mirror of
https://github.com/setube/ogame-vue-ts.git
synced 2026-05-11 23:45:11 +08:00
1.6.0更新
This commit is contained in:
@@ -4,25 +4,15 @@ const config: CapacitorConfig = {
|
||||
appId: 'games.wenzi.ogame',
|
||||
appName: 'OGame Vue Ts',
|
||||
webDir: 'docs',
|
||||
server: {
|
||||
androidScheme: 'https',
|
||||
cacheControl: 'max-age=31536000'
|
||||
},
|
||||
server: { androidScheme: 'https', cacheControl: 'max-age=31536000' },
|
||||
android: {
|
||||
buildOptions: {
|
||||
keystorePath: undefined,
|
||||
keystoreAlias: undefined
|
||||
},
|
||||
buildOptions: { keystorePath: undefined, keystoreAlias: undefined },
|
||||
webContentsDebuggingEnabled: false,
|
||||
allowMixedContent: false,
|
||||
hardwareAcceleration: true
|
||||
},
|
||||
plugins: {
|
||||
// 禁用键盘自动调整视口
|
||||
Keyboard: {
|
||||
resize: 'none'
|
||||
}
|
||||
}
|
||||
// 禁用键盘自动调整视口
|
||||
plugins: { Keyboard: { resize: 'none' } }
|
||||
}
|
||||
|
||||
export default config
|
||||
|
||||
75
main.go
75
main.go
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"embed"
|
||||
"flag"
|
||||
"fmt"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -20,10 +22,16 @@ var content embed.FS
|
||||
|
||||
func main() {
|
||||
// --- 1. 命令行参数配置 ---
|
||||
// 定义 -port 参数,默认为 0(自动分配)
|
||||
portPtr := flag.Int("port", 0, "指定运行端口 (例如: 8080),不指定则自动分配可用端口")
|
||||
// 定义 -port 参数,默认为 -1(表示未指定,需要交互选择)
|
||||
portPtr := flag.Int("port", -1, "指定运行端口 (例如: 8080),不指定则显示交互菜单")
|
||||
flag.Parse()
|
||||
|
||||
// 如果没有通过命令行指定端口,显示交互式菜单
|
||||
port := *portPtr
|
||||
if port == -1 {
|
||||
port = showPortMenu()
|
||||
}
|
||||
|
||||
// --- 2. 静态资源处理 ---
|
||||
// 获取 docs 子目录的文件系统句柄
|
||||
distFS, err := fs.Sub(content, "docs")
|
||||
@@ -60,10 +68,10 @@ func main() {
|
||||
})
|
||||
|
||||
// --- 3. 端口监听逻辑 ---
|
||||
addr := fmt.Sprintf("0.0.0.0:%d", *portPtr)
|
||||
addr := fmt.Sprintf("0.0.0.0:%d", port)
|
||||
listener, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
fmt.Printf("错误: 端口 %d 已被占用或监听失败: %v\n", *portPtr, err)
|
||||
fmt.Printf("错误: 端口 %d 已被占用或监听失败: %v\n", port, err)
|
||||
// 停留 5 秒让用户看到错误信息
|
||||
time.Sleep(5 * time.Second)
|
||||
os.Exit(1)
|
||||
@@ -79,8 +87,8 @@ func main() {
|
||||
fmt.Printf("启动时间: %s\n", time.Now().Format("2006-01-02 15:04:05"))
|
||||
fmt.Printf("本地访问: %s\n", localUrl)
|
||||
fmt.Printf("局域网访问: %s\n", lanUrl)
|
||||
if *portPtr != 0 {
|
||||
fmt.Printf("运行模式: 固定端口 (%d)\n", *portPtr)
|
||||
if port != 0 {
|
||||
fmt.Printf("运行模式: 固定端口 (%d)\n", port)
|
||||
} else {
|
||||
fmt.Printf("运行模式: 自动分配端口\n")
|
||||
}
|
||||
@@ -132,3 +140,58 @@ func openBrowser(url string) {
|
||||
|
||||
_ = exec.Command(cmd, args...).Start()
|
||||
}
|
||||
|
||||
// 显示端口选择菜单
|
||||
func showPortMenu() int {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
fmt.Println("=======================================")
|
||||
fmt.Println(" OGame Vue Ts 服务器启动")
|
||||
fmt.Println("=======================================")
|
||||
fmt.Println()
|
||||
fmt.Println("请选择端口模式:")
|
||||
fmt.Println(" [1] 随机端口 (自动分配可用端口)")
|
||||
fmt.Println(" [2] 自定义端口 (指定固定端口)")
|
||||
fmt.Println()
|
||||
fmt.Print("请输入选项 (1/2): ")
|
||||
|
||||
for {
|
||||
input, _ := reader.ReadString('\n')
|
||||
input = strings.TrimSpace(input)
|
||||
|
||||
switch input {
|
||||
case "1", "":
|
||||
fmt.Println("\n已选择: 随机端口模式")
|
||||
return 0
|
||||
case "2":
|
||||
return inputCustomPort(reader)
|
||||
default:
|
||||
fmt.Print("无效输入,请输入 1 或 2: ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 输入自定义端口
|
||||
func inputCustomPort(reader *bufio.Reader) int {
|
||||
fmt.Print("请输入端口号 (1-65535,推荐: 8080): ")
|
||||
|
||||
for {
|
||||
input, _ := reader.ReadString('\n')
|
||||
input = strings.TrimSpace(input)
|
||||
|
||||
// 如果直接回车,使用默认端口 8080
|
||||
if input == "" {
|
||||
fmt.Println("\n已选择: 固定端口 8080")
|
||||
return 8080
|
||||
}
|
||||
|
||||
port, err := strconv.Atoi(input)
|
||||
if err != nil || port < 1 || port > 65535 {
|
||||
fmt.Print("无效端口号,请输入 1-65535 之间的数字: ")
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("\n已选择: 固定端口 %d\n", port)
|
||||
return port
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,8 @@
|
||||
"email": "1962257451@qq.com"
|
||||
},
|
||||
"private": true,
|
||||
"version": "1.5.6",
|
||||
"buildDate": "2025/12/27 03:58:44",
|
||||
"version": "1.6.0",
|
||||
"buildDate": "2026/1/6 02:54:44",
|
||||
"main": "dist-electron/main.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -34,6 +34,7 @@
|
||||
"crypto-js": "^4.2.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"finalhandler": "^2.1.1",
|
||||
"lightningcss": "^1.30.2",
|
||||
"lucide-vue-next": "^0.556.0",
|
||||
"marked": "^17.0.1",
|
||||
"motion-v": "^1.7.4",
|
||||
@@ -44,10 +45,10 @@
|
||||
"tailwindcss": "^4.1.17",
|
||||
"vue": "^3.5.24",
|
||||
"vue-router": "4",
|
||||
"vue-sonner": "^2.0.9",
|
||||
"lightningcss": "^1.30.2"
|
||||
"vue-sonner": "^2.0.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@csstools/postcss-cascade-layers": "^5.0.2",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@types/node": "^24.10.2",
|
||||
|
||||
41
pnpm-lock.yaml
generated
41
pnpm-lock.yaml
generated
@@ -81,6 +81,9 @@ importers:
|
||||
specifier: ^2.0.9
|
||||
version: 2.0.9
|
||||
devDependencies:
|
||||
'@csstools/postcss-cascade-layers':
|
||||
specifier: ^5.0.2
|
||||
version: 5.0.2(postcss@8.5.6)
|
||||
'@types/crypto-js':
|
||||
specifier: ^4.2.2
|
||||
version: 4.2.2
|
||||
@@ -674,6 +677,18 @@ packages:
|
||||
'@capacitor/synapse@1.0.4':
|
||||
resolution: {integrity: sha512-/C1FUo8/OkKuAT4nCIu/34ny9siNHr9qtFezu4kxm6GY1wNFxrCFWjfYx5C1tUhVGz3fxBABegupkpjXvjCHrw==}
|
||||
|
||||
'@csstools/postcss-cascade-layers@5.0.2':
|
||||
resolution: {integrity: sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
postcss: ^8.4
|
||||
|
||||
'@csstools/selector-specificity@5.0.0':
|
||||
resolution: {integrity: sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
postcss-selector-parser: ^7.0.0
|
||||
|
||||
'@develar/schema-utils@2.6.5':
|
||||
resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==}
|
||||
engines: {node: '>= 8.9.0'}
|
||||
@@ -1915,6 +1930,11 @@ packages:
|
||||
resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
cssesc@3.0.0:
|
||||
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
|
||||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
|
||||
csstype@3.2.3:
|
||||
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||
|
||||
@@ -3104,6 +3124,10 @@ packages:
|
||||
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
postcss-selector-parser@7.1.1:
|
||||
resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
postcss@8.5.6:
|
||||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
@@ -4646,6 +4670,16 @@ snapshots:
|
||||
|
||||
'@capacitor/synapse@1.0.4': {}
|
||||
|
||||
'@csstools/postcss-cascade-layers@5.0.2(postcss@8.5.6)':
|
||||
dependencies:
|
||||
'@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.1)
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
'@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.1)':
|
||||
dependencies:
|
||||
postcss-selector-parser: 7.1.1
|
||||
|
||||
'@develar/schema-utils@2.6.5':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
@@ -5955,6 +5989,8 @@ snapshots:
|
||||
|
||||
crypto-random-string@2.0.0: {}
|
||||
|
||||
cssesc@3.0.0: {}
|
||||
|
||||
csstype@3.2.3: {}
|
||||
|
||||
data-view-buffer@1.0.2:
|
||||
@@ -7243,6 +7279,11 @@ snapshots:
|
||||
|
||||
possible-typed-array-names@1.1.0: {}
|
||||
|
||||
postcss-selector-parser@7.1.1:
|
||||
dependencies:
|
||||
cssesc: 3.0.0
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
postcss@8.5.6:
|
||||
dependencies:
|
||||
nanoid: 3.3.11
|
||||
|
||||
87
src/App.vue
87
src/App.vue
@@ -45,7 +45,7 @@
|
||||
<ChevronsUpDown class="h-4 w-4 shrink-0 text-muted-foreground ml-2" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-72 p-0" side="bottom" align="start">
|
||||
<PopoverContent class="w-70 p-0" side="bottom" align="start">
|
||||
<div class="p-2">
|
||||
<div class="px-2 py-1.5 mb-1 text-xs font-semibold text-muted-foreground">
|
||||
{{ t('planet.switchPlanet') }}
|
||||
@@ -378,7 +378,7 @@
|
||||
</SidebarInset>
|
||||
|
||||
<!-- 右下角固定通知按钮 -->
|
||||
<div class="fixed bottom-4 right-4 z-50 flex flex-col gap-2">
|
||||
<div class="fixed bottom-4 right-4 z-50 flex flex-col gap-2" :class="{ 'bottom-15': Capacitor.isNativePlatform() }">
|
||||
<!-- 返回顶部 -->
|
||||
<BackToTop />
|
||||
<!-- 队列通知 -->
|
||||
@@ -518,7 +518,7 @@
|
||||
import HintToast from '@/components/notifications/HintToast.vue'
|
||||
import BackToTop from '@/components/common/BackToTop.vue'
|
||||
import Sonner from '@/components/ui/sonner/Sonner.vue'
|
||||
import { MissionType, BuildingType, TechnologyType, DiplomaticEventType } from '@/types/game'
|
||||
import { MissionType, BuildingType, TechnologyType, DiplomaticEventType, ShipType } from '@/types/game'
|
||||
import type { FleetMission, NPC, MissileAttack } from '@/types/game'
|
||||
import { DIPLOMATIC_CONFIG } from '@/config/gameConfig'
|
||||
import type { VersionInfo } from '@/utils/versionCheck'
|
||||
@@ -838,8 +838,14 @@
|
||||
|
||||
// 计算离线收益(直接同步计算,应用游戏速度)
|
||||
const bonuses = officerLogic.calculateActiveBonuses(gameStore.player.officers, now)
|
||||
const miningTechLevel = gameStore.player.technologies[TechnologyType.MiningTechnology] || 0
|
||||
const techBonuses = {
|
||||
mineralResearchLevel: gameStore.player.technologies[TechnologyType.MineralResearch] || 0,
|
||||
crystalResearchLevel: gameStore.player.technologies[TechnologyType.CrystalResearch] || 0,
|
||||
fuelResearchLevel: gameStore.player.technologies[TechnologyType.FuelResearch] || 0
|
||||
}
|
||||
gameStore.player.planets.forEach(planet => {
|
||||
resourceLogic.updatePlanetResources(planet, now, bonuses, gameStore.gameSpeed)
|
||||
resourceLogic.updatePlanetResources(planet, now, bonuses, gameStore.gameSpeed, miningTechLevel, techBonuses)
|
||||
})
|
||||
|
||||
// 只在没有NPC星球时才生成(首次加载已有玩家数据时)
|
||||
@@ -1065,6 +1071,19 @@
|
||||
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, gameStore.locale)
|
||||
|
||||
// 同步战斗损失到NPC的实际星球数据
|
||||
const npcPlanet = targetNpc.planets.find(p => p.id === targetPlanet.id)
|
||||
if (npcPlanet) {
|
||||
// 同步舰队损失
|
||||
Object.entries(attackResult.battleResult.defenderLosses.fleet).forEach(([shipType, lost]) => {
|
||||
npcPlanet.fleet[shipType as ShipType] = Math.max(0, (npcPlanet.fleet[shipType as ShipType] || 0) - lost)
|
||||
})
|
||||
// 同步防御损失(修复后的数据已在targetPlanet中)
|
||||
npcPlanet.defense = { ...targetPlanet.defense }
|
||||
// 同步资源(被掠夺后的)
|
||||
npcPlanet.resources = { ...targetPlanet.resources }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1262,8 +1281,41 @@
|
||||
}
|
||||
}
|
||||
} else if (mission.missionType === MissionType.Destroy) {
|
||||
// 处理行星毁灭任务
|
||||
const destroyResult = fleetLogic.processDestroyArrival(mission, targetPlanet, gameStore.player)
|
||||
// 处理行星毁灭任务(需要先战斗,再计算毁灭概率)
|
||||
const destroyResult = await fleetLogic.processDestroyArrival(mission, targetPlanet, gameStore.player, null, gameStore.player.planets)
|
||||
|
||||
// 处理战斗报告(如果发生了战斗)
|
||||
if (destroyResult.battleResult) {
|
||||
gameStore.player.battleReports.push(destroyResult.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, destroyResult.battleResult, npcStore.npcs, gameStore.locale)
|
||||
|
||||
// 同步战斗损失到NPC的实际星球数据
|
||||
const npcPlanet = targetNpc.planets.find(p => p.id === targetPlanet.id)
|
||||
if (npcPlanet) {
|
||||
Object.entries(destroyResult.battleResult.defenderLosses.fleet).forEach(([shipType, lost]) => {
|
||||
npcPlanet.fleet[shipType as ShipType] = Math.max(0, (npcPlanet.fleet[shipType as ShipType] || 0) - lost)
|
||||
})
|
||||
npcPlanet.defense = { ...targetPlanet.defense }
|
||||
npcPlanet.resources = { ...targetPlanet.resources }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理新生成的月球
|
||||
if (destroyResult.moon) {
|
||||
gameStore.player.planets.push(destroyResult.moon)
|
||||
}
|
||||
|
||||
// 处理残骸场
|
||||
if (destroyResult.debrisField) {
|
||||
universeStore.debrisFields[destroyResult.debrisField.id] = destroyResult.debrisField
|
||||
}
|
||||
|
||||
// 更新成就统计 - 行星毁灭
|
||||
if (destroyResult.success) {
|
||||
@@ -1303,12 +1355,14 @@
|
||||
? {
|
||||
destroyedPlanetName:
|
||||
targetPlanet?.name ||
|
||||
`[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`
|
||||
`[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`,
|
||||
hadBattle: !!destroyResult.battleResult
|
||||
}
|
||||
: {
|
||||
failReason: destroyResult.failReason,
|
||||
destructionChance: destroyResult.destructionChance,
|
||||
deathstarsLost: destroyResult.deathstarsLost
|
||||
deathstarsLost: destroyResult.deathstarsLost,
|
||||
hadBattle: !!destroyResult.battleResult
|
||||
},
|
||||
read: false
|
||||
})
|
||||
@@ -1387,7 +1441,7 @@
|
||||
delete universeStore.debrisFields[destroyedDebrisId]
|
||||
}
|
||||
} else if (mission.missionType === MissionType.Expedition) {
|
||||
// 处理远征任务
|
||||
// 处理探险任务
|
||||
const expeditionResult = fleetLogic.processExpeditionArrival(mission)
|
||||
|
||||
// 确保返回时间正确设置(兼容旧版本任务数据)
|
||||
@@ -1399,12 +1453,12 @@
|
||||
mission.returnTime = now + flightDuration
|
||||
}
|
||||
|
||||
// 更新成就统计 - 远征
|
||||
// 更新成就统计 - 探险
|
||||
const isSuccessful =
|
||||
expeditionResult.eventType === 'resources' || expeditionResult.eventType === 'darkMatter' || expeditionResult.eventType === 'fleet'
|
||||
gameLogic.trackMissionStats(gameStore.player, 'expedition', { successful: isSuccessful })
|
||||
|
||||
// 生成远征任务报告
|
||||
// 生成探险任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
@@ -1676,10 +1730,16 @@
|
||||
// 应用损失到目标星球
|
||||
missileLogic.applyMissileAttackResult(targetPlanet, impactResult.defenseLosses)
|
||||
|
||||
// 如果目标是NPC的星球,扣除外交好感度
|
||||
// 如果目标是NPC的星球,同步损失到NPC实际数据并扣除外交好感度
|
||||
if (targetPlanet.ownerId && targetPlanet.ownerId !== gameStore.player.id) {
|
||||
const targetNpc = npcStore.npcs.find(npc => npc.id === targetPlanet.ownerId)
|
||||
if (targetNpc) {
|
||||
// 同步防御损失到NPC的实际星球数据
|
||||
const npcPlanet = targetNpc.planets.find(p => p.id === targetPlanet.id)
|
||||
if (npcPlanet) {
|
||||
missileLogic.applyMissileAttackResult(npcPlanet, impactResult.defenseLosses)
|
||||
}
|
||||
|
||||
// 导弹攻击扣除好感度
|
||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||
const reputationLoss = REPUTATION_CHANGES.ATTACK / 2 // 导弹攻击的好感度惩罚是普通攻击的一半
|
||||
@@ -2220,6 +2280,7 @@
|
||||
const switchToMoon = () => {
|
||||
if (moon.value) {
|
||||
gameStore.currentPlanetId = moon.value.id
|
||||
router.push('/')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2227,12 +2288,14 @@
|
||||
const switchToParentPlanet = () => {
|
||||
if (planet.value?.parentPlanetId) {
|
||||
gameStore.currentPlanetId = planet.value.parentPlanetId
|
||||
router.push('/')
|
||||
}
|
||||
}
|
||||
|
||||
// 切换到指定星球
|
||||
const switchToPlanet = (planetId: string) => {
|
||||
gameStore.currentPlanetId = planetId
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
// 切换侧边栏
|
||||
|
||||
@@ -72,15 +72,15 @@ html.light {
|
||||
/* 队列添加动画 - 脉冲效果 */
|
||||
@keyframes queue-pulse-animation {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.7);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
transform: scale3d(1.1, 1.1, 1);
|
||||
box-shadow: 0 0 0 8px rgba(34, 197, 94, 0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
transform: scale3d(1, 1, 1);
|
||||
box-shadow: 0 0 0 0 rgba(34, 197, 94, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<!-- 可缩放内容包装器 -->
|
||||
<div
|
||||
class="map-content origin-top-left transition-transform duration-200"
|
||||
:style="{ transform: `scale(${zoomLevel})`, minWidth: calculatedMapWidth + 'px', minHeight: calculatedMapHeight + 'px' }"
|
||||
:style="{ transform: `scale3d(${zoomLevel}, ${zoomLevel}, 1)`, minWidth: calculatedMapWidth + 'px', minHeight: calculatedMapHeight + 'px' }"
|
||||
>
|
||||
<!-- SVG连接线 - 位置与节点容器对齐 -->
|
||||
<svg
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
}
|
||||
|
||||
.quest-available .quest-node:hover {
|
||||
transform: scale(1.05);
|
||||
transform: scale3d(1.05, 1.05, 1);
|
||||
}
|
||||
|
||||
@keyframes pulse-glow {
|
||||
|
||||
@@ -491,9 +491,20 @@
|
||||
return currentPlanet.value.buildings['naniteFactory'] || 0
|
||||
})
|
||||
|
||||
// 获取研究所等级(用于研究时间计算)
|
||||
// 获取有效研究所等级(考虑星际研究网络)
|
||||
const researchLabLevel = computed(() => {
|
||||
if (!currentPlanet.value) return 0
|
||||
const intergalacticResearchNetworkLevel = gameStore.player.technologies[TechnologyType.IntergalacticResearchNetwork] || 0
|
||||
|
||||
// 如果有星际研究网络,计算有效实验室等级
|
||||
if (intergalacticResearchNetworkLevel > 0) {
|
||||
return researchLogic.calculateEffectiveLabLevel(
|
||||
gameStore.player.planets,
|
||||
currentPlanet.value.id,
|
||||
intergalacticResearchNetworkLevel
|
||||
)
|
||||
}
|
||||
|
||||
return currentPlanet.value.buildings['researchLab'] || 0
|
||||
})
|
||||
|
||||
@@ -502,6 +513,12 @@
|
||||
return gameStore.player.technologies['energyTechnology'] || 0
|
||||
})
|
||||
|
||||
// 获取大学等级(用于研究时间计算)
|
||||
const universityLevel = computed(() => {
|
||||
if (!currentPlanet.value) return 0
|
||||
return currentPlanet.value.buildings['university'] || 0
|
||||
})
|
||||
|
||||
// 翻译键(转换为复数形式)
|
||||
const typeKey = computed(() => {
|
||||
const typeMap = {
|
||||
@@ -931,7 +948,9 @@
|
||||
level - 1,
|
||||
activeBonuses.value.researchSpeedBonus,
|
||||
researchLabLevel.value,
|
||||
energyTechLevel.value
|
||||
energyTechLevel.value,
|
||||
1,
|
||||
universityLevel.value
|
||||
)
|
||||
|
||||
let researchSpeedBonus = 0
|
||||
|
||||
@@ -178,6 +178,16 @@
|
||||
type: 'attacker-loss' | 'defender-loss' | 'info'
|
||||
}
|
||||
const battleLogs = ref<BattleLog[]>([])
|
||||
const MAX_LOGS = 100 // 限制日志数量,防止100回合战斗导致性能问题
|
||||
|
||||
// 添加日志的辅助函数,自动限制数量
|
||||
const addBattleLog = (log: BattleLog) => {
|
||||
battleLogs.value.push(log)
|
||||
// 如果超过最大数量,删除最旧的日志
|
||||
if (battleLogs.value.length > MAX_LOGS) {
|
||||
battleLogs.value = battleLogs.value.slice(-MAX_LOGS)
|
||||
}
|
||||
}
|
||||
|
||||
// 计算属性
|
||||
const totalRounds = computed(() => props.report.roundDetails?.length || props.report.rounds || 1)
|
||||
@@ -367,97 +377,101 @@
|
||||
if (currentRoundIndex.value >= totalRounds.value) return
|
||||
|
||||
isPlayingRound = true
|
||||
const speed = parseFloat(speedMultiplier.value)
|
||||
const roundIndex = currentRoundIndex.value
|
||||
const roundData = props.report.roundDetails?.[roundIndex]
|
||||
try {
|
||||
const speed = parseFloat(speedMultiplier.value) || 1
|
||||
const roundIndex = currentRoundIndex.value
|
||||
const roundData = props.report.roundDetails?.[roundIndex]
|
||||
|
||||
// 攻击动画阶段
|
||||
attackAnimationPhase.value = 'attack'
|
||||
// 攻击动画阶段
|
||||
attackAnimationPhase.value = 'attack'
|
||||
|
||||
// 添加日志
|
||||
battleLogs.value.push({
|
||||
round: roundIndex + 1,
|
||||
message: t('messagesView.roundStarted').replace('{round}', String(roundIndex + 1)),
|
||||
type: 'info'
|
||||
})
|
||||
// 添加日志
|
||||
addBattleLog({
|
||||
round: roundIndex + 1,
|
||||
message: t('messagesView.roundStarted').replace('{round}', String(roundIndex + 1)),
|
||||
type: 'info'
|
||||
})
|
||||
|
||||
// 等待攻击动画
|
||||
await sleep(400 / speed)
|
||||
// 等待攻击动画
|
||||
await sleep(400 / speed)
|
||||
|
||||
// 伤害阶段
|
||||
attackAnimationPhase.value = 'damage'
|
||||
// 伤害阶段
|
||||
attackAnimationPhase.value = 'damage'
|
||||
|
||||
// 计算当前回合的损失数字
|
||||
if (roundData) {
|
||||
const attackerLoss = Object.values(roundData.attackerLosses).reduce((sum, count) => sum + count, 0)
|
||||
const defenderLoss =
|
||||
Object.values(roundData.defenderLosses.fleet || {}).reduce((sum, count) => sum + count, 0) +
|
||||
Object.values(roundData.defenderLosses.defense || {}).reduce((sum, count) => sum + count, 0)
|
||||
displayedLosses.value = { attacker: attackerLoss, defender: defenderLoss }
|
||||
} else {
|
||||
displayedLosses.value = { attacker: 0, defender: 0 }
|
||||
// 计算当前回合的损失数字
|
||||
if (roundData) {
|
||||
const attackerLoss = Object.values(roundData.attackerLosses || {}).reduce((sum, count) => sum + count, 0)
|
||||
const defenderLoss =
|
||||
Object.values(roundData.defenderLosses?.fleet || {}).reduce((sum, count) => sum + count, 0) +
|
||||
Object.values(roundData.defenderLosses?.defense || {}).reduce((sum, count) => sum + count, 0)
|
||||
displayedLosses.value = { attacker: attackerLoss, defender: defenderLoss }
|
||||
} else {
|
||||
displayedLosses.value = { attacker: 0, defender: 0 }
|
||||
}
|
||||
showDamageNumbers.value = true
|
||||
|
||||
if (roundData) {
|
||||
// 记录攻击方损失
|
||||
for (const [shipType, count] of Object.entries(roundData.attackerLosses || {})) {
|
||||
if (count > 0) {
|
||||
explodingShips.value.push({ side: 'attacker', type: shipType })
|
||||
addBattleLog({
|
||||
round: roundIndex + 1,
|
||||
message: t('messagesView.shipDestroyed')
|
||||
.replace('{count}', String(count))
|
||||
.replace('{ship}', SHIPS.value[shipType as ShipType]?.name || shipType),
|
||||
type: 'attacker-loss'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 记录防守方损失
|
||||
for (const [shipType, count] of Object.entries(roundData.defenderLosses?.fleet || {})) {
|
||||
if (count > 0) {
|
||||
explodingShips.value.push({ side: 'defender', type: shipType })
|
||||
addBattleLog({
|
||||
round: roundIndex + 1,
|
||||
message: t('messagesView.shipDestroyed')
|
||||
.replace('{count}', String(count))
|
||||
.replace('{ship}', SHIPS.value[shipType as ShipType]?.name || shipType),
|
||||
type: 'defender-loss'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for (const [defType, count] of Object.entries(roundData.defenderLosses?.defense || {})) {
|
||||
if (count > 0) {
|
||||
explodingShips.value.push({ side: 'defender', type: defType })
|
||||
addBattleLog({
|
||||
round: roundIndex + 1,
|
||||
message: t('messagesView.defenseDestroyed')
|
||||
.replace('{count}', String(count))
|
||||
.replace('{defense}', DEFENSES.value[defType as DefenseType]?.name || defType),
|
||||
type: 'defender-loss'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 等待伤害显示
|
||||
await sleep(600 / speed)
|
||||
|
||||
// 清理状态
|
||||
attackAnimationPhase.value = 'idle'
|
||||
showDamageNumbers.value = false
|
||||
explodingShips.value = []
|
||||
|
||||
currentRoundIndex.value++
|
||||
} finally {
|
||||
// 确保锁始终被释放,即使发生错误
|
||||
isPlayingRound = false
|
||||
}
|
||||
showDamageNumbers.value = true
|
||||
|
||||
if (roundData) {
|
||||
// 记录攻击方损失
|
||||
for (const [shipType, count] of Object.entries(roundData.attackerLosses)) {
|
||||
if (count > 0) {
|
||||
explodingShips.value.push({ side: 'attacker', type: shipType })
|
||||
battleLogs.value.push({
|
||||
round: roundIndex + 1,
|
||||
message: t('messagesView.shipDestroyed')
|
||||
.replace('{count}', String(count))
|
||||
.replace('{ship}', SHIPS.value[shipType as ShipType]?.name || shipType),
|
||||
type: 'attacker-loss'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 记录防守方损失
|
||||
for (const [shipType, count] of Object.entries(roundData.defenderLosses.fleet || {})) {
|
||||
if (count > 0) {
|
||||
explodingShips.value.push({ side: 'defender', type: shipType })
|
||||
battleLogs.value.push({
|
||||
round: roundIndex + 1,
|
||||
message: t('messagesView.shipDestroyed')
|
||||
.replace('{count}', String(count))
|
||||
.replace('{ship}', SHIPS.value[shipType as ShipType]?.name || shipType),
|
||||
type: 'defender-loss'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for (const [defType, count] of Object.entries(roundData.defenderLosses.defense || {})) {
|
||||
if (count > 0) {
|
||||
explodingShips.value.push({ side: 'defender', type: defType })
|
||||
battleLogs.value.push({
|
||||
round: roundIndex + 1,
|
||||
message: t('messagesView.defenseDestroyed')
|
||||
.replace('{count}', String(count))
|
||||
.replace('{defense}', DEFENSES.value[defType as DefenseType]?.name || defType),
|
||||
type: 'defender-loss'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 等待伤害显示
|
||||
await sleep(600 / speed)
|
||||
|
||||
// 清理状态
|
||||
attackAnimationPhase.value = 'idle'
|
||||
showDamageNumbers.value = false
|
||||
explodingShips.value = []
|
||||
|
||||
currentRoundIndex.value++
|
||||
isPlayingRound = false
|
||||
}
|
||||
|
||||
const nextRound = () => {
|
||||
const nextRound = async () => {
|
||||
if (currentRoundIndex.value < totalRounds.value) {
|
||||
pause()
|
||||
playRound()
|
||||
await playRound()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<ProgressIndicator
|
||||
data-slot="progress-indicator"
|
||||
class="bg-primary h-full w-full flex-1 transition-all"
|
||||
:style="`transform: translateX(-${100 - (props.modelValue ?? 0)}%);`"
|
||||
:style="`transform: translate3d(-${100 - (props.modelValue ?? 0)}%, 0, 0);`"
|
||||
/>
|
||||
</ProgressRoot>
|
||||
</template>
|
||||
|
||||
@@ -43,7 +43,8 @@ export const useGameConfig = () => {
|
||||
[BuildingType.JumpGate]: 'jumpGate',
|
||||
[BuildingType.PlanetDestroyerFactory]: 'planetDestroyerFactory',
|
||||
[BuildingType.GeoResearchStation]: 'geoResearchStation',
|
||||
[BuildingType.DeepDrillingFacility]: 'deepDrillingFacility'
|
||||
[BuildingType.DeepDrillingFacility]: 'deepDrillingFacility',
|
||||
[BuildingType.University]: 'university'
|
||||
}
|
||||
|
||||
// 舰船类型枚举值到翻译键的映射
|
||||
@@ -100,7 +101,11 @@ export const useGameConfig = () => {
|
||||
[TechnologyType.DarkMatterTechnology]: 'darkMatterTechnology',
|
||||
[TechnologyType.TerraformingTechnology]: 'terraformingTechnology',
|
||||
[TechnologyType.PlanetDestructionTech]: 'planetDestructionTech',
|
||||
[TechnologyType.MiningTechnology]: 'miningTechnology'
|
||||
[TechnologyType.MiningTechnology]: 'miningTechnology',
|
||||
[TechnologyType.IntergalacticResearchNetwork]: 'intergalacticResearchNetwork',
|
||||
[TechnologyType.MineralResearch]: 'mineralResearch',
|
||||
[TechnologyType.CrystalResearch]: 'crystalResearch',
|
||||
[TechnologyType.FuelResearch]: 'fuelResearch'
|
||||
}
|
||||
|
||||
// 军官类型枚举值到翻译键的映射
|
||||
|
||||
@@ -110,7 +110,7 @@ export const triggerQueueAnimation = (event: MouseEvent, type: 'building' | 'tec
|
||||
|
||||
el.style.left = `${x}px`
|
||||
el.style.top = `${y}px`
|
||||
el.style.transform = `translate(-50%, -50%) scale(${scale})`
|
||||
el.style.transform = `translate3d(-50%, -50%, 0) scale3d(${scale}, ${scale}, 1)`
|
||||
el.style.opacity = `${opacity}`
|
||||
|
||||
if (progress < 1) {
|
||||
|
||||
@@ -284,7 +284,7 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
||||
id: BuildingType.LunarBase,
|
||||
name: '月球基地',
|
||||
description: '增加月球可用空间',
|
||||
baseCost: { metal: 20000, crystal: 40000, deuterium: 20000, darkMatter: 0, energy: 0 },
|
||||
baseCost: { metal: 8000, crystal: 8000, deuterium: 4000, darkMatter: 0, energy: 0 },
|
||||
baseTime: 45, // 减少建造时间:60→45秒
|
||||
costMultiplier: 2,
|
||||
spaceUsage: 0, // 月球基地本身不占用空间,反而增加空间
|
||||
@@ -357,7 +357,7 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
||||
[BuildingType.GeoResearchStation]: {
|
||||
id: BuildingType.GeoResearchStation,
|
||||
name: '地质研究站',
|
||||
description: '研究地质结构,提高矿脉自然恢复速度。每级增加50%恢复速率',
|
||||
description: '研究地质结构,提高矿脉自然恢复速度。每级增加10%恢复速率',
|
||||
baseCost: { metal: 50000, crystal: 30000, deuterium: 20000, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 1.8,
|
||||
@@ -416,6 +416,34 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
||||
[TechnologyType.PlasmaTechnology]: 5
|
||||
}
|
||||
}
|
||||
},
|
||||
// 2moons新增建筑
|
||||
[BuildingType.University]: {
|
||||
id: BuildingType.University,
|
||||
name: '大学',
|
||||
description: '培养科研人员,加快研究速度。每级减少研究时间8%(与星际研究网络叠加)',
|
||||
baseCost: { metal: 200000, crystal: 100000, deuterium: 50000, darkMatter: 0, energy: 0 },
|
||||
baseTime: 120,
|
||||
costMultiplier: 2,
|
||||
spaceUsage: 8,
|
||||
planetOnly: true,
|
||||
maxLevel: 10, // 最多10级(最高约57%研究时间减少)
|
||||
requirements: {
|
||||
[BuildingType.ResearchLab]: 8,
|
||||
[BuildingType.RoboticsFactory]: 6
|
||||
},
|
||||
levelRequirements: {
|
||||
5: {
|
||||
[BuildingType.ResearchLab]: 10,
|
||||
[BuildingType.RoboticsFactory]: 8,
|
||||
[TechnologyType.EnergyTechnology]: 8
|
||||
},
|
||||
8: {
|
||||
[BuildingType.ResearchLab]: 12,
|
||||
[BuildingType.NaniteFactory]: 2,
|
||||
[TechnologyType.ComputerTechnology]: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,6 +754,111 @@ export const TECHNOLOGIES: Record<TechnologyType, TechnologyConfig> = {
|
||||
[TechnologyType.PlasmaTechnology]: 3
|
||||
}
|
||||
}
|
||||
},
|
||||
// 2moons新增科技
|
||||
[TechnologyType.IntergalacticResearchNetwork]: {
|
||||
id: TechnologyType.IntergalacticResearchNetwork,
|
||||
name: '星际研究网络',
|
||||
description: '连接多个星球的研究实验室,共享研究资源。每级可连接1个额外的研究实验室(取等级最高的N个实验室)',
|
||||
baseCost: { metal: 240000, crystal: 400000, deuterium: 160000, darkMatter: 0, energy: 0 },
|
||||
baseTime: 180,
|
||||
costMultiplier: 2,
|
||||
maxLevel: 10,
|
||||
requirements: {
|
||||
[BuildingType.ResearchLab]: 10,
|
||||
[TechnologyType.ComputerTechnology]: 8,
|
||||
[TechnologyType.HyperspaceTechnology]: 8
|
||||
},
|
||||
levelRequirements: {
|
||||
5: {
|
||||
[BuildingType.ResearchLab]: 12,
|
||||
[TechnologyType.ComputerTechnology]: 10,
|
||||
[TechnologyType.HyperspaceTechnology]: 10
|
||||
},
|
||||
8: {
|
||||
[BuildingType.ResearchLab]: 14,
|
||||
[TechnologyType.ComputerTechnology]: 12,
|
||||
[BuildingType.NaniteFactory]: 5
|
||||
}
|
||||
}
|
||||
},
|
||||
[TechnologyType.MineralResearch]: {
|
||||
id: TechnologyType.MineralResearch,
|
||||
name: '矿物研究',
|
||||
description: '研究更高效的金属提取技术,提升金属矿产量。每级增加金属产量2%',
|
||||
baseCost: { metal: 60000, crystal: 30000, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 1.75,
|
||||
maxLevel: 20,
|
||||
requirements: {
|
||||
[BuildingType.ResearchLab]: 5,
|
||||
[BuildingType.MetalMine]: 10,
|
||||
[TechnologyType.EnergyTechnology]: 3
|
||||
},
|
||||
levelRequirements: {
|
||||
10: {
|
||||
[BuildingType.ResearchLab]: 8,
|
||||
[BuildingType.MetalMine]: 20,
|
||||
[TechnologyType.EnergyTechnology]: 8
|
||||
},
|
||||
15: {
|
||||
[BuildingType.ResearchLab]: 12,
|
||||
[BuildingType.NaniteFactory]: 2,
|
||||
[TechnologyType.PlasmaTechnology]: 5
|
||||
}
|
||||
}
|
||||
},
|
||||
[TechnologyType.CrystalResearch]: {
|
||||
id: TechnologyType.CrystalResearch,
|
||||
name: '晶体研究',
|
||||
description: '研究更高效的晶体提炼技术,提升晶体矿产量。每级增加晶体产量2%',
|
||||
baseCost: { metal: 40000, crystal: 60000, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 1.75,
|
||||
maxLevel: 20,
|
||||
requirements: {
|
||||
[BuildingType.ResearchLab]: 5,
|
||||
[BuildingType.CrystalMine]: 10,
|
||||
[TechnologyType.EnergyTechnology]: 3
|
||||
},
|
||||
levelRequirements: {
|
||||
10: {
|
||||
[BuildingType.ResearchLab]: 8,
|
||||
[BuildingType.CrystalMine]: 20,
|
||||
[TechnologyType.EnergyTechnology]: 8
|
||||
},
|
||||
15: {
|
||||
[BuildingType.ResearchLab]: 12,
|
||||
[BuildingType.NaniteFactory]: 2,
|
||||
[TechnologyType.PlasmaTechnology]: 5
|
||||
}
|
||||
}
|
||||
},
|
||||
[TechnologyType.FuelResearch]: {
|
||||
id: TechnologyType.FuelResearch,
|
||||
name: '燃料研究',
|
||||
description: '研究更高效的重氢合成技术,提升重氢产量。每级增加重氢产量2%',
|
||||
baseCost: { metal: 0, crystal: 50000, deuterium: 50000, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 1.75,
|
||||
maxLevel: 20,
|
||||
requirements: {
|
||||
[BuildingType.ResearchLab]: 5,
|
||||
[BuildingType.DeuteriumSynthesizer]: 10,
|
||||
[TechnologyType.EnergyTechnology]: 3
|
||||
},
|
||||
levelRequirements: {
|
||||
10: {
|
||||
[BuildingType.ResearchLab]: 8,
|
||||
[BuildingType.DeuteriumSynthesizer]: 20,
|
||||
[TechnologyType.EnergyTechnology]: 8
|
||||
},
|
||||
15: {
|
||||
[BuildingType.ResearchLab]: 12,
|
||||
[BuildingType.NaniteFactory]: 2,
|
||||
[TechnologyType.PlasmaTechnology]: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1007,7 +1140,7 @@ export const SHIPS: Record<ShipType, ShipConfig> = {
|
||||
id: ShipType.Deathstar,
|
||||
name: '死星',
|
||||
description: '终极武器,能够摧毁整个行星',
|
||||
cost: { metal: 5000000, crystal: 4000000, deuterium: 1000000, darkMatter: 20000, energy: 0 },
|
||||
cost: { metal: 50000000, crystal: 40000000, deuterium: 10000000, darkMatter: 20000, energy: 0 },
|
||||
buildTime: 600,
|
||||
cargoCapacity: 1000000,
|
||||
attack: 200000,
|
||||
@@ -1467,9 +1600,9 @@ export const DIPLOMATIC_CONFIG = {
|
||||
// 贸易检查间隔(秒)
|
||||
CHECK_INTERVAL: 1800, // 30分钟
|
||||
// 贸易概率
|
||||
PROBABILITY: 0.1,
|
||||
PROBABILITY: 0.05,
|
||||
// 玩家最多同时保留的贸易提议数量
|
||||
MAX_PENDING_OFFERS: 30,
|
||||
MAX_PENDING_OFFERS: 5,
|
||||
// 汇率配置:NPC出售资源的汇率
|
||||
EXCHANGE_RATES: {
|
||||
// 金属:晶体:重氢 基准比例 3:2:1
|
||||
@@ -1658,9 +1791,9 @@ export const ORE_DEPOSIT_CONFIG = {
|
||||
// 矿脉恢复配置
|
||||
REGENERATION: {
|
||||
ENABLED: true,
|
||||
// 每小时恢复初始储量的百分比(0.1% = 每小时恢复0.1%,约42天完全恢复)
|
||||
RATE_PER_HOUR: 0.001,
|
||||
// 最大恢复到初始储量的百分比(100%表示可以完全恢复)
|
||||
// 每小时恢复初始储量的百分比(1% = 每小时恢复1%,约4.2天完全恢复)
|
||||
RATE_PER_HOUR: 0.01,
|
||||
// 最大恢复到初始储量的百分比(100表示可以完全恢复)%
|
||||
MAX_PERCENTAGE: 1.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +153,7 @@ export default {
|
||||
planetDestroyerFactory: 'Planetenzerstörer-Fabrik',
|
||||
geoResearchStation: 'Geologische Forschungsstation',
|
||||
deepDrillingFacility: 'Tiefbohranlage',
|
||||
university: 'Universität',
|
||||
buildTime: 'Bauzeit',
|
||||
build: 'Bauen',
|
||||
production: 'Produktion',
|
||||
@@ -204,8 +205,9 @@ export default {
|
||||
jumpGate: 'Überträgt Flotten sofort zu anderen Monden',
|
||||
planetDestroyerFactory: 'Konstruiert ultimative Waffen zur Zerstörung von Planeten',
|
||||
geoResearchStation:
|
||||
'Erforscht geologische Strukturen und erhöht die natürliche Erzvorkommen-Regenerationsrate. +50% Regeneration pro Stufe',
|
||||
deepDrillingFacility: ''
|
||||
'Erforscht geologische Strukturen und erhöht die natürliche Erzvorkommen-Regenerationsrate. +10% Regeneration pro Stufe',
|
||||
deepDrillingFacility: '',
|
||||
university: 'Bildet Forscher aus, um die Forschungsgeschwindigkeit zu beschleunigen. -8% Forschungszeit pro Stufe'
|
||||
},
|
||||
ships: {
|
||||
lightFighter: 'Leichter Jäger',
|
||||
@@ -287,7 +289,11 @@ export default {
|
||||
researchQueueBonus: 'Forschungswarteschlange',
|
||||
colonySlots: 'Kolonieplätze',
|
||||
forAllPlanets: '(Global)',
|
||||
speedBonus: 'Geschwindigkeitsbonus'
|
||||
speedBonus: 'Geschwindigkeitsbonus',
|
||||
// Ressourcenproduktionsbonus-Anzeige
|
||||
mineralResearch: 'Mineralforschung',
|
||||
crystalResearch: 'Kristallforschung',
|
||||
fuelResearch: 'Brennstoffforschung'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: 'Energietechnik',
|
||||
@@ -308,7 +314,11 @@ export default {
|
||||
darkMatterTechnology: 'Dunkle-Materie-Technologie',
|
||||
terraformingTechnology: 'Terraforming-Technologie',
|
||||
planetDestructionTech: 'Planetenzerstörungstechnologie',
|
||||
miningTechnology: ''
|
||||
miningTechnology: '',
|
||||
intergalacticResearchNetwork: 'Intergalaktisches Forschungsnetzwerk',
|
||||
mineralResearch: 'Mineralforschung',
|
||||
crystalResearch: 'Kristallforschung',
|
||||
fuelResearch: 'Treibstoffforschung'
|
||||
},
|
||||
technologyDescriptions: {
|
||||
energyTechnology: 'Verbessert Energieeffizienz',
|
||||
@@ -330,7 +340,11 @@ export default {
|
||||
darkMatterTechnology: 'Forschung zu Eigenschaften und Anwendungen von Dunkler Materie',
|
||||
terraformingTechnology: 'Forschung zur Planeten-Terraforming-Technologie, erhöht verfügbaren Platz aller Planeten um 30 pro Stufe',
|
||||
planetDestructionTech: 'Schreckliche Technologie zur Zerstörung ganzer Planeten',
|
||||
miningTechnology: ''
|
||||
miningTechnology: '',
|
||||
intergalacticResearchNetwork: 'Verbindet mehrere Forschungslabore über Planeten hinweg. Jede Stufe verbindet 1 zusätzliches Labor',
|
||||
mineralResearch: 'Erforscht effizientere Metallextraktionstechniken. +2% Metallproduktion pro Stufe',
|
||||
crystalResearch: 'Erforscht effizientere Kristallveredelungstechniken. +2% Kristallproduktion pro Stufe',
|
||||
fuelResearch: 'Erforscht effizientere Deuterium-Synthesetechniken. +2% Deuteriumproduktion pro Stufe'
|
||||
},
|
||||
officers: {
|
||||
commander: 'Kommandant',
|
||||
@@ -932,7 +946,10 @@ export default {
|
||||
hideRoundDetails: 'Rundendetails ausblenden',
|
||||
round: 'Runde {round}',
|
||||
attackerRemainingPower: 'Verbleibende Angreiferkraft',
|
||||
defenderRemainingPower: 'Verbleibende Verteidigerkraft'
|
||||
defenderRemainingPower: 'Verbleibende Verteidigerkraft',
|
||||
importFromSpyReport: 'Aus Spionagebericht importieren',
|
||||
selectSpyReport: 'Spionagebericht auswählen',
|
||||
noSpyReports: 'Keine Spionageberichte verfügbar'
|
||||
},
|
||||
settings: {
|
||||
dataManagement: 'Datenverwaltung',
|
||||
@@ -943,6 +960,7 @@ export default {
|
||||
exporting: 'Exportieren...',
|
||||
exportSuccess: 'Export erfolgreich',
|
||||
exportSuccessWithPath: 'Export erfolgreich, Datei gespeichert unter: {path}',
|
||||
storagePermissionDenied: 'Speicherberechtigung verweigert, Datei kann nicht exportiert werden',
|
||||
exportFailed: 'Export fehlgeschlagen, bitte erneut versuchen',
|
||||
importData: 'Daten importieren',
|
||||
importDataDesc: 'Spielfortschritt aus JSON-Datei wiederherstellen',
|
||||
@@ -962,6 +980,8 @@ export default {
|
||||
gameSettingsDesc: 'Spielparameter und Einstellungen anpassen',
|
||||
gamePause: 'Spielpause',
|
||||
gamePauseDesc: 'Spielzeit und Ressourcenproduktion pausieren oder fortsetzen',
|
||||
battleMode: 'Bis zum Ende kämpfen',
|
||||
battleModeDesc: 'Wenn aktiviert, dauern Kämpfe bis zu 100 Runden bis ein Sieger feststeht. Wenn deaktiviert, wird der klassische 6-Runden-Modus verwendet',
|
||||
pause: 'Pausieren',
|
||||
resume: 'Fortsetzen',
|
||||
gamePaused: 'Spiel pausiert',
|
||||
@@ -1400,19 +1420,23 @@ export default {
|
||||
skip: 'Anleitung überspringen',
|
||||
welcome: {
|
||||
title: 'Willkommen bei OGame',
|
||||
content: 'Willkommen, Kommandant! Diese Anleitung führt Sie durch die Grundlagen des Imperiumsaufbaus. Klicken Sie auf "Weiter", um Ihre Reise zu beginnen.'
|
||||
content:
|
||||
'Willkommen, Kommandant! Diese Anleitung führt Sie durch die Grundlagen des Imperiumsaufbaus. Klicken Sie auf "Weiter", um Ihre Reise zu beginnen.'
|
||||
},
|
||||
resources: {
|
||||
title: 'Ressourcenübersicht',
|
||||
content: 'Dies sind Ihre Ressourcen: Metall, Kristall und Deuterium. Sie sind für den Bau von Gebäuden und die Erforschung von Technologien unerlässlich. Energie ist ebenfalls wichtig, um Ihre Infrastruktur zu betreiben.'
|
||||
content:
|
||||
'Dies sind Ihre Ressourcen: Metall, Kristall und Deuterium. Sie sind für den Bau von Gebäuden und die Erforschung von Technologien unerlässlich. Energie ist ebenfalls wichtig, um Ihre Infrastruktur zu betreiben.'
|
||||
},
|
||||
planet: {
|
||||
title: 'Ihr Planet',
|
||||
content: 'Dies ist Ihr Heimatplanet. Hier sehen Sie den Planetennamen, die Koordinaten und können zwischen Planeten wechseln, wenn Sie Ihr Imperium erweitern.'
|
||||
content:
|
||||
'Dies ist Ihr Heimatplanet. Hier sehen Sie den Planetennamen, die Koordinaten und können zwischen Planeten wechseln, wenn Sie Ihr Imperium erweitern.'
|
||||
},
|
||||
navigation: {
|
||||
title: 'Navigationsmenü',
|
||||
content: 'Verwenden Sie dieses Menü, um zwischen verschiedenen Bereichen zu navigieren: Gebäude, Forschung, Flotte, Galaxie usw. Jeder Bereich bietet einzigartige Spielfunktionen.'
|
||||
content:
|
||||
'Verwenden Sie dieses Menü, um zwischen verschiedenen Bereichen zu navigieren: Gebäude, Forschung, Flotte, Galaxie usw. Jeder Bereich bietet einzigartige Spielfunktionen.'
|
||||
},
|
||||
gotoBuildings: {
|
||||
title: 'Zu Gebäuden gehen',
|
||||
@@ -1420,39 +1444,48 @@ export default {
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: 'Solarkraftwerk bauen',
|
||||
content: 'Bauen Sie zuerst ein Solarkraftwerk! Es versorgt Ihren Planeten mit Energie. Ohne Energie können andere Ressourcengebäude nicht funktionieren. Dies ist der wichtigste erste Schritt.'
|
||||
content:
|
||||
'Bauen Sie zuerst ein Solarkraftwerk! Es versorgt Ihren Planeten mit Energie. Ohne Energie können andere Ressourcengebäude nicht funktionieren. Dies ist der wichtigste erste Schritt.'
|
||||
},
|
||||
waitBuild: {
|
||||
title: 'Bauauftrag',
|
||||
content: 'Ihr Gebäude befindet sich jetzt im Bauauftrag. Klicken Sie auf das Warteschlangensymbol oben rechts, um alle laufenden Bau- und Forschungsaufgaben anzuzeigen. Gebäude brauchen Zeit zur Fertigstellung, aber Sie können während des Wartens weitermachen.'
|
||||
content:
|
||||
'Ihr Gebäude befindet sich jetzt im Bauauftrag. Klicken Sie auf das Warteschlangensymbol oben rechts, um alle laufenden Bau- und Forschungsaufgaben anzuzeigen. Gebäude brauchen Zeit zur Fertigstellung, aber Sie können während des Wartens weitermachen.'
|
||||
},
|
||||
buildMetalMine: {
|
||||
title: 'Metallmine bauen',
|
||||
content: 'Jetzt, da Sie Energie haben, bauen Sie eine Metallmine. Die Metallmine ist Ihre Hauptmetallquelle, und Metall wird für fast jedes Gebäude und Schiff benötigt.'
|
||||
content:
|
||||
'Jetzt, da Sie Energie haben, bauen Sie eine Metallmine. Die Metallmine ist Ihre Hauptmetallquelle, und Metall wird für fast jedes Gebäude und Schiff benötigt.'
|
||||
},
|
||||
buildCrystalMine: {
|
||||
title: 'Kristallmine bauen',
|
||||
content: 'Kristall ist seltener, aber für fortgeschrittene Technologien entscheidend. Bauen Sie eine Kristallmine, um diese wertvolle Ressource zu sammeln.'
|
||||
content:
|
||||
'Kristall ist seltener, aber für fortgeschrittene Technologien entscheidend. Bauen Sie eine Kristallmine, um diese wertvolle Ressource zu sammeln.'
|
||||
},
|
||||
buildDeuterium: {
|
||||
title: 'Deuteriumsynthesizer bauen',
|
||||
content: 'Deuterium ist für Schiffstreibstoff und fortgeschrittene Forschung unerlässlich. Bauen Sie einen Deuteriumsynthesizer, um diese wichtige Ressource zu produzieren.'
|
||||
content:
|
||||
'Deuterium ist für Schiffstreibstoff und fortgeschrittene Forschung unerlässlich. Bauen Sie einen Deuteriumsynthesizer, um diese wichtige Ressource zu produzieren.'
|
||||
},
|
||||
upgradeMines: {
|
||||
title: 'Ressourcenminen upgraden',
|
||||
content: 'Als Nächstes müssen Sie die drei Ressourcenminen (Metall, Kristall, Deuterium) auf Level 2 upgraden, um die Anforderungen für den Bau der Roboterfabrik zu erfüllen. Upgraden Sie sie weiter, wenn Sie genügend Ressourcen haben.'
|
||||
content:
|
||||
'Als Nächstes müssen Sie die drei Ressourcenminen (Metall, Kristall, Deuterium) auf Level 2 upgraden, um die Anforderungen für den Bau der Roboterfabrik zu erfüllen. Upgraden Sie sie weiter, wenn Sie genügend Ressourcen haben.'
|
||||
},
|
||||
buildRobotics: {
|
||||
title: 'Roboterfabrik bauen',
|
||||
content: 'Die Roboterfabrik kann die Baugeschwindigkeit erheblich erhöhen. Sie benötigt Metallmine, Kristallmine und Deuteriumsynthesizer jeweils auf Level 2. Bauen Sie sie, um die Baueffizienz zu steigern!'
|
||||
content:
|
||||
'Die Roboterfabrik kann die Baugeschwindigkeit erheblich erhöhen. Sie benötigt Metallmine, Kristallmine und Deuteriumsynthesizer jeweils auf Level 2. Bauen Sie sie, um die Baueffizienz zu steigern!'
|
||||
},
|
||||
upgradeMinesForLab: {
|
||||
title: 'Ressourcenminen weiter upgraden',
|
||||
content: 'Jetzt müssen Sie die drei Ressourcenminen auf Level 3 upgraden, um die Bauanforderungen des Forschungslabors zu erfüllen. Entwickeln Sie Ihre Ressourcenproduktion weiter.'
|
||||
content:
|
||||
'Jetzt müssen Sie die drei Ressourcenminen auf Level 3 upgraden, um die Bauanforderungen des Forschungslabors zu erfüllen. Entwickeln Sie Ihre Ressourcenproduktion weiter.'
|
||||
},
|
||||
buildResearchLab: {
|
||||
title: 'Forschungslabor bauen',
|
||||
content: 'Das Forschungslabor ist die Grundlage für technologischen Fortschritt. Es benötigt alle drei Ressourcenminen auf Level 3. Bauen Sie es, um Technologieforschung freizuschalten!'
|
||||
content:
|
||||
'Das Forschungslabor ist die Grundlage für technologischen Fortschritt. Es benötigt alle drei Ressourcenminen auf Level 3. Bauen Sie es, um Technologieforschung freizuschalten!'
|
||||
},
|
||||
gotoResearch: {
|
||||
title: 'Zur Forschung gehen',
|
||||
@@ -1460,11 +1493,13 @@ export default {
|
||||
},
|
||||
researchEnergy: {
|
||||
title: 'Energietechnik erforschen',
|
||||
content: 'Die Energietechnik kann Ihre Energieproduktion verbessern und fortgeschrittene Gebäude freischalten. Dies ist eine der grundlegendsten und wichtigsten Technologien.'
|
||||
content:
|
||||
'Die Energietechnik kann Ihre Energieproduktion verbessern und fortgeschrittene Gebäude freischalten. Dies ist eine der grundlegendsten und wichtigsten Technologien.'
|
||||
},
|
||||
shipyardIntro: {
|
||||
title: 'Flotte & Werft',
|
||||
content: 'Schiffe ermöglichen es Ihnen, die Galaxie zu erkunden, Ressourcen zu transportieren und Ihr Imperium zu verteidigen. Um Schiffe zu bauen, benötigen Sie eine Raumschiffwerft (benötigt Roboterfabrik Level 2).'
|
||||
content:
|
||||
'Schiffe ermöglichen es Ihnen, die Galaxie zu erkunden, Ressourcen zu transportieren und Ihr Imperium zu verteidigen. Um Schiffe zu bauen, benötigen Sie eine Raumschiffwerft (benötigt Roboterfabrik Level 2).'
|
||||
},
|
||||
gotoBuildingsForShipyard: {
|
||||
title: 'Zurück zur Gebäudeseite',
|
||||
@@ -1472,32 +1507,39 @@ export default {
|
||||
},
|
||||
buildShipyard: {
|
||||
title: 'Raumschiffwerft bauen',
|
||||
content: 'Die Raumschiffwerft ermöglicht es Ihnen, Schiffe und Verteidigungssysteme zu bauen. Dies ist für Flottenoperationen unerlässlich.'
|
||||
content:
|
||||
'Die Raumschiffwerft ermöglicht es Ihnen, Schiffe und Verteidigungssysteme zu bauen. Dies ist für Flottenoperationen unerlässlich.'
|
||||
},
|
||||
fleetIntro: {
|
||||
title: 'Flottenoperationen',
|
||||
content: 'Sobald Sie Schiffe haben, können Sie sie auf Missionen schicken: Ressourcen transportieren, Planeten kolonisieren, Feinde angreifen oder Trümmerfelder erkunden.'
|
||||
content:
|
||||
'Sobald Sie Schiffe haben, können Sie sie auf Missionen schicken: Ressourcen transportieren, Planeten kolonisieren, Feinde angreifen oder Trümmerfelder erkunden.'
|
||||
},
|
||||
galaxyIntro: {
|
||||
title: 'Galaxie erkunden',
|
||||
content: 'Die Galaxieansicht zeigt andere Planeten, Trümmerfelder und Expansionsmöglichkeiten. Verwenden Sie sie, um Ziele auszukundschaften und Ihre Strategie zu planen.'
|
||||
content:
|
||||
'Die Galaxieansicht zeigt andere Planeten, Trümmerfelder und Expansionsmöglichkeiten. Verwenden Sie sie, um Ziele auszukundschaften und Ihre Strategie zu planen.'
|
||||
},
|
||||
complete: {
|
||||
title: 'Anleitung abgeschlossen!',
|
||||
content: 'Glückwunsch, Kommandant! Sie kennen jetzt die Grundlagen. Bauen Sie Ihr Imperium weiter auf, erforschen Sie Technologien und erkunden Sie die Galaxie. Denken Sie daran: Zuerst Energie entwickeln, dann Ressourcen, dann Fabriken und Forschung! Viel Glück!'
|
||||
content:
|
||||
'Glückwunsch, Kommandant! Sie kennen jetzt die Grundlagen. Bauen Sie Ihr Imperium weiter auf, erforschen Sie Technologien und erkunden Sie die Galaxie. Denken Sie daran: Zuerst Energie entwickeln, dann Ressourcen, dann Fabriken und Forschung! Viel Glück!'
|
||||
},
|
||||
mobile: {
|
||||
welcome: {
|
||||
title: 'Willkommen bei OGame (Mobil)',
|
||||
content: 'Willkommen, Kommandant! Dies ist eine vereinfachte Anleitung für Touchscreens. Wir werden schnell die Kernfunktionen durchgehen, damit Sie mit dem Aufbau Ihres Imperiums beginnen können.'
|
||||
content:
|
||||
'Willkommen, Kommandant! Dies ist eine vereinfachte Anleitung für Touchscreens. Wir werden schnell die Kernfunktionen durchgehen, damit Sie mit dem Aufbau Ihres Imperiums beginnen können.'
|
||||
},
|
||||
resources: {
|
||||
title: 'Obere Ressourcenleiste',
|
||||
content: 'Oben werden Ihre Ressourcen angezeigt: Metall, Kristall und Deuterium. Tippen Sie, um detaillierte Produktionsinformationen anzuzeigen.'
|
||||
content:
|
||||
'Oben werden Ihre Ressourcen angezeigt: Metall, Kristall und Deuterium. Tippen Sie, um detaillierte Produktionsinformationen anzuzeigen.'
|
||||
},
|
||||
menu: {
|
||||
title: 'Navigationsmenü öffnen',
|
||||
content: 'Tippen Sie auf dieses Menüsymbol, um die Navigationsleiste zu öffnen. Sie können auf alle Funktionen zugreifen: Gebäude, Forschung, Flotte usw.'
|
||||
content:
|
||||
'Tippen Sie auf dieses Menüsymbol, um die Navigationsleiste zu öffnen. Sie können auf alle Funktionen zugreifen: Gebäude, Forschung, Flotte usw.'
|
||||
},
|
||||
gotoBuildings: {
|
||||
title: 'Zur Gebäudeseite gehen',
|
||||
@@ -1505,19 +1547,23 @@ export default {
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: 'Solarkraftwerk bauen',
|
||||
content: 'Bauen Sie zuerst ein Solarkraftwerk! Scrollen Sie nach unten, um es zu finden, und tippen Sie auf die Karte zum Bauen. Energie ist die Grundlage für alles.'
|
||||
content:
|
||||
'Bauen Sie zuerst ein Solarkraftwerk! Scrollen Sie nach unten, um es zu finden, und tippen Sie auf die Karte zum Bauen. Energie ist die Grundlage für alles.'
|
||||
},
|
||||
waitBuild: {
|
||||
title: 'Bauauftrag',
|
||||
content: 'Tippen Sie auf das Warteschlangensymbol oben rechts, um den Baufortschritt anzuzeigen. Sie können weiter andere Seiten durchsuchen - der Bau läuft im Hintergrund.'
|
||||
content:
|
||||
'Tippen Sie auf das Warteschlangensymbol oben rechts, um den Baufortschritt anzuzeigen. Sie können weiter andere Seiten durchsuchen - der Bau läuft im Hintergrund.'
|
||||
},
|
||||
buildMetalMine: {
|
||||
title: 'Metallmine bauen',
|
||||
content: 'Nachdem Sie Energie haben, bauen Sie eine Metallmine. Scrollen Sie nach unten, um die Metallmine zu finden, und tippen Sie zum Bauen.'
|
||||
content:
|
||||
'Nachdem Sie Energie haben, bauen Sie eine Metallmine. Scrollen Sie nach unten, um die Metallmine zu finden, und tippen Sie zum Bauen.'
|
||||
},
|
||||
complete: {
|
||||
title: 'Schnellanleitung abgeschlossen!',
|
||||
content: 'Sehr gut! Sie haben die Grundlagen gemeistert. Bauen Sie weiter die Kristallmine und den Deuteriumsynthesizer und erkunden Sie andere Funktionen. Denken Sie daran: Zuerst Energie, dann Ressourcen!'
|
||||
content:
|
||||
'Sehr gut! Sie haben die Grundlagen gemeistert. Bauen Sie weiter die Kristallmine und den Deuteriumsynthesizer und erkunden Sie andere Funktionen. Denken Sie daran: Zuerst Energie, dann Ressourcen!'
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1586,7 +1632,8 @@ export default {
|
||||
},
|
||||
campaign: {
|
||||
title: 'Kampagnenmodus',
|
||||
message: 'Erkunden Sie die Galaxie-Story-Kampagne! Schließen Sie Missionen ab, um Ressourcenbelohnungen zu erhalten und neue Herausforderungen freizuschalten. Jeder Knoten hat einzigartige Ziele und Feinde.'
|
||||
message:
|
||||
'Erkunden Sie die Galaxie-Story-Kampagne! Schließen Sie Missionen ab, um Ressourcenbelohnungen zu erhalten und neue Herausforderungen freizuschalten. Jeder Knoten hat einzigartige Ziele und Feinde.'
|
||||
},
|
||||
achievements: {
|
||||
title: 'Erfolgssystem',
|
||||
@@ -1964,13 +2011,19 @@ export default {
|
||||
questNotActive: 'Quest nicht aktiv',
|
||||
questNotCompleted: 'Quest nicht abgeschlossen',
|
||||
rewardsAlreadyClaimed: 'Belohnungen bereits erhalten',
|
||||
prerequisiteNotMet: 'Voraussetzungs-Quest nicht abgeschlossen'
|
||||
prerequisiteNotMet: 'Voraussetzungs-Quest nicht abgeschlossen',
|
||||
questLocked: 'Quest ist gesperrt',
|
||||
notInitialized: 'Kampagne nicht initialisiert',
|
||||
questAlreadyCompleted: 'Quest bereits abgeschlossen'
|
||||
},
|
||||
speakers: {
|
||||
ancientVoice: 'Antike Stimme',
|
||||
neighborNPC: 'Nachbar-Fraktion',
|
||||
mysteriousSignal: 'Mysteriöses Signal',
|
||||
enemyCommander: 'Feindlicher Kommandant'
|
||||
enemyCommander: 'Feindlicher Kommandant',
|
||||
shadowVoice: 'Schattenstimme',
|
||||
allyNPC: 'Verbündete Fraktion',
|
||||
ancientGuardian: 'Antiker Wächter'
|
||||
},
|
||||
objectiveDescriptions: {
|
||||
buildMetalMine: 'Baue Metallmine auf Stufe 2',
|
||||
@@ -2060,13 +2113,19 @@ export default {
|
||||
'2_3': {
|
||||
prologue_1:
|
||||
'Deine Expedition entdeckte anomale Signale. Diese Signale scheinen von einer antiken Zivilisation zu stammen... Untersuche ihre Quelle.',
|
||||
prologue_2:
|
||||
'Diese Signale... Sie tragen Echos einer längst verlorenen Zivilisation. Ihre Geheimnisse warten darauf, entdeckt zu werden...',
|
||||
epilogue_1: 'Diese Symbole... Sie sind Ruinen einer antiken Zivilisation! Untersuche weiter, um ihre Geheimnisse zu enthüllen.'
|
||||
},
|
||||
'2_4': {
|
||||
prologue_1: 'Du hast den Standort antiker Ruinen gefunden. Sende deine Flotte zur Erkundung und sieh, was du entdecken kannst.'
|
||||
prologue_1: 'Du hast den Standort antiker Ruinen gefunden. Sende deine Flotte zur Erkundung und sieh, was du entdecken kannst.',
|
||||
prologue_2: 'Die Ruinen bergen viele Geheimnisse... Wähle deinen Weg weise...',
|
||||
choice_1: 'Vorsichtig erkunden - Sicherheit priorisieren',
|
||||
choice_2: 'Aggressiv erkunden - Entdeckung priorisieren'
|
||||
},
|
||||
'2_5': {
|
||||
prologue_1: 'Datenarchive wurden in den Ruinen gefunden. Studiere diese Daten, vielleicht kannst du neue Technologie freischalten.'
|
||||
prologue_1: 'Datenarchive wurden in den Ruinen gefunden. Studiere diese Daten, vielleicht kannst du neue Technologie freischalten.',
|
||||
epilogue_1: 'Die antiken Daten wurden entschlüsselt! Neue technologische Erkenntnisse wurden gewonnen.'
|
||||
},
|
||||
'3_1': { prologue_1: 'Beim Erkunden vergiss nicht die Diplomatie. Gute Beziehungen zu umliegenden Fraktionen zu pflegen nützt dir.' },
|
||||
'3_2': {
|
||||
@@ -2075,14 +2134,19 @@ export default {
|
||||
},
|
||||
'3_3': {
|
||||
prologue_1:
|
||||
'Geheimdienstberichte deuten darauf hin, dass feindliche Kräfte dich aus den Schatten beobachten. Bleibe wachsam und erkunde ihre Bewegungen.'
|
||||
'Geheimdienstberichte deuten darauf hin, dass feindliche Kräfte dich aus den Schatten beobachten. Bleibe wachsam und erkunde ihre Bewegungen.',
|
||||
prologue_2: 'Dunkle Mächte regen sich in der Leere... Sie haben deine wachsende Macht bemerkt...'
|
||||
},
|
||||
'3_4': {
|
||||
prologue_1: 'Schließe eine formelle Allianz mit freundlichen Fraktionen, um euch gegenseitig gegen Bedrohungen zu unterstützen.'
|
||||
},
|
||||
'3_5': { prologue_1: 'Bedrohungen nähern sich. Baue Verteidigungsanlagen und bereite dich auf mögliche Konflikte vor.' },
|
||||
'3_5': {
|
||||
prologue_1: 'Bedrohungen nähern sich. Baue Verteidigungsanlagen und bereite dich auf mögliche Konflikte vor.',
|
||||
epilogue_1: 'Deine Verteidigung ist bereit. Der Sturm naht, aber du bist vorbereitet.'
|
||||
},
|
||||
'4_1': {
|
||||
prologue_1: 'Der Feind hat einen Angriff gestartet! Verteidige deinen Planeten!',
|
||||
prologue_2: 'Die Schattenflotte nähert sich... Deine Stunde der Prüfung ist gekommen...',
|
||||
epilogue_1: 'Du hast die erste Welle des Feindes erfolgreich abgewehrt. Aber das ist erst der Anfang...'
|
||||
},
|
||||
'4_2': {
|
||||
@@ -2092,20 +2156,28 @@ export default {
|
||||
'4_4': {
|
||||
prologue_1: 'Viele Trümmer bleiben auf dem Schlachtfeld. Recycel diese Ressourcen, um dich auf die nächste Schlacht vorzubereiten.'
|
||||
},
|
||||
'4_5': { prologue_1: 'Die letzte Schlacht naht. Baue eine mächtige Flotte und bereite dich auf die ultimative Herausforderung vor.' },
|
||||
'4_5': {
|
||||
prologue_1: 'Die letzte Schlacht naht. Baue eine mächtige Flotte und bereite dich auf die ultimative Herausforderung vor.',
|
||||
epilogue_1: 'Deine Flotte ist versammelt. Der entscheidende Moment naht...'
|
||||
},
|
||||
'5_1': {
|
||||
prologue_1: 'Alle Hinweise deuten auf den tiefsten Teil der Ruinen. Die Kerngeheimnisse der antiken Zivilisation liegen dort.',
|
||||
prologue_2: 'Du bist endlich angekommen... Die Wahrheit wird bald enthüllt...'
|
||||
},
|
||||
'5_2': { prologue_1: 'In den Tiefen der Ruinen entdecktest du verlorene antike Technologie. Erforsche und schalte ihre Macht frei.' },
|
||||
'5_2': {
|
||||
prologue_1: 'In den Tiefen der Ruinen entdecktest du verlorene antike Technologie. Erforsche und schalte ihre Macht frei.',
|
||||
prologue_2: 'Diese Technologie... Sie ist älter als alle bekannten Zivilisationen. Gehe vorsichtig damit um...'
|
||||
},
|
||||
'5_3': {
|
||||
prologue_1: 'Ein mysteriöser Feind ist aufgetaucht. Dies ist die letzte Herausforderung. Besiege ihn!',
|
||||
prologue_2: 'Ich bin der Wächter dieser Geheimnisse. Beweise deinen Wert oder werde vernichtet!',
|
||||
epilogue_1: 'Du hast es geschafft! Der antike Wächter wurde besiegt. Die Geheimnisse der Galaxie stehen dir nun offen.'
|
||||
},
|
||||
'5_4': { prologue_1: 'Frieden ist endlich eingekehrt. In dieser neuen Ära gründe neue Kolonien und erweitere dein Imperium.' },
|
||||
'5_5': {
|
||||
prologue_1: 'Deine Legende hat gerade erst begonnen. Erkunde weiter und erobere mehr Sternensysteme!',
|
||||
epilogue_1: 'Die Galaxie ist weit und grenzenlos, mit zahllosen Geheimnissen, die auf dich warten...'
|
||||
epilogue_1: 'Die Galaxie ist weit und grenzenlos, mit zahllosen Geheimnissen, die auf dich warten...',
|
||||
epilogue_2: 'Deine Reise geht weiter... Neue Abenteuer warten jenseits der Sterne...'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ export default {
|
||||
cannotAttackOwnPlanet: 'Cannot attack your own planet',
|
||||
fleetMissionsFull: 'Fleet mission slots full',
|
||||
insufficientFleet: 'Insufficient fleet',
|
||||
insufficientShips: 'Insufficient ships',
|
||||
invalidQuantity: 'Invalid quantity',
|
||||
insufficientFuel: 'Insufficient fuel',
|
||||
planetOnly: 'This building can only be built on planets',
|
||||
moonOnly: 'This building can only be built on moons',
|
||||
@@ -55,7 +57,12 @@ export default {
|
||||
researchQueueFull: 'Research queue full',
|
||||
moonExists: 'Moon already exists',
|
||||
insufficientDebris: 'Insufficient debris field',
|
||||
launchFailed: 'Launch failed'
|
||||
launchFailed: 'Launch failed',
|
||||
planetNotFound: 'Planet not found',
|
||||
cannotAbandonHomePlanet: 'Cannot abandon home planet',
|
||||
hasBuildQueue: 'Please wait for build queue to complete',
|
||||
hasFleetOnPlanet: 'Please transfer or scrap all fleet first',
|
||||
hasDefenseOnPlanet: 'Please demolish all defense first'
|
||||
},
|
||||
nav: {
|
||||
overview: 'Overview',
|
||||
@@ -123,7 +130,12 @@ export default {
|
||||
renamePlanet: 'Rename Planet',
|
||||
renamePlanetTitle: 'Rename Planet',
|
||||
planetNamePlaceholder: 'Enter new planet name',
|
||||
rename: 'Rename'
|
||||
rename: 'Rename',
|
||||
abandonColony: 'Abandon Colony',
|
||||
confirmAbandon: 'Confirm Abandon Colony',
|
||||
abandonWarning: 'Are you sure you want to abandon "{name}"?\n\nThis action cannot be undone!\nAll buildings, resources and the moon (if any) will be lost.',
|
||||
confirmAbandonButton: 'Abandon',
|
||||
abandonFailed: 'Abandon Failed'
|
||||
},
|
||||
player: {
|
||||
points: 'Total Points'
|
||||
@@ -152,6 +164,7 @@ export default {
|
||||
planetDestroyerFactory: 'Planet Destroyer Factory',
|
||||
geoResearchStation: 'Geological Research Station',
|
||||
deepDrillingFacility: 'Deep Drilling Facility',
|
||||
university: 'University',
|
||||
buildTime: 'Build Time',
|
||||
production: 'Production',
|
||||
consumption: 'Consumption',
|
||||
@@ -199,8 +212,9 @@ export default {
|
||||
sensorPhalanx: 'Detects fleet activities in surrounding systems',
|
||||
jumpGate: 'Instantly transfers fleets to other moons',
|
||||
planetDestroyerFactory: 'Constructs ultimate weapons capable of destroying planets',
|
||||
geoResearchStation: 'Researches geological structures and increases ore deposit regeneration rate. +50% regeneration per level',
|
||||
deepDrillingFacility: 'Drills deep into the crust to access deeper ore veins. +20% ore deposit capacity per level'
|
||||
geoResearchStation: 'Researches geological structures and increases ore deposit regeneration rate. +10% regeneration per level',
|
||||
deepDrillingFacility: 'Drills deep into the crust to access deeper ore veins. +20% ore deposit capacity per level',
|
||||
university: 'Trains researchers to accelerate research speed. -8% research time per level (stacks with Intergalactic Research Network)'
|
||||
},
|
||||
ships: {
|
||||
lightFighter: 'Light Fighter',
|
||||
@@ -275,7 +289,11 @@ export default {
|
||||
researchQueueBonus: 'Research Queue',
|
||||
colonySlots: 'Colony Slots',
|
||||
forAllPlanets: '(Global)',
|
||||
speedBonus: 'Speed Bonus'
|
||||
speedBonus: 'Speed Bonus',
|
||||
// 资源产量加成显示
|
||||
mineralResearch: 'Mineral Research',
|
||||
crystalResearch: 'Crystal Research',
|
||||
fuelResearch: 'Fuel Research'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: 'Energy Technology',
|
||||
@@ -296,7 +314,11 @@ export default {
|
||||
darkMatterTechnology: 'Dark Matter Technology',
|
||||
terraformingTechnology: 'Terraforming Technology',
|
||||
planetDestructionTech: 'Planet Destruction Technology',
|
||||
miningTechnology: 'Mining Technology'
|
||||
miningTechnology: 'Mining Technology',
|
||||
intergalacticResearchNetwork: 'Intergalactic Research Network',
|
||||
mineralResearch: 'Mineral Research',
|
||||
crystalResearch: 'Crystal Research',
|
||||
fuelResearch: 'Fuel Research'
|
||||
},
|
||||
technologyDescriptions: {
|
||||
energyTechnology: 'Improves energy efficiency',
|
||||
@@ -318,7 +340,11 @@ export default {
|
||||
darkMatterTechnology: 'Research into dark matter properties and applications',
|
||||
terraformingTechnology: 'Research planet terraforming technology, adds 30 available space to all planets per level',
|
||||
planetDestructionTech: 'Terrifying technology for destroying entire planets',
|
||||
miningTechnology: 'Improves mining methods and equipment, increases ore deposit capacity on all planets. +15% capacity per level'
|
||||
miningTechnology: 'Improves mining methods and equipment, increases ore deposit capacity on all planets. +15% capacity per level',
|
||||
intergalacticResearchNetwork: 'Links multiple research labs across planets. Each level connects 1 additional lab (highest level labs are used)',
|
||||
mineralResearch: 'Research more efficient metal extraction techniques. +2% metal production per level',
|
||||
crystalResearch: 'Research more efficient crystal refinement techniques. +2% crystal production per level',
|
||||
fuelResearch: 'Research more efficient deuterium synthesis techniques. +2% deuterium production per level'
|
||||
},
|
||||
officers: {
|
||||
commander: 'Commander',
|
||||
@@ -440,7 +466,12 @@ export default {
|
||||
inputError: 'Input Error',
|
||||
inputErrorMessage: 'Please enter build quantity!',
|
||||
buildFailed: 'Build Failed',
|
||||
buildFailedMessage: 'Please check if you have enough resources or if prerequisites are met.'
|
||||
buildFailedMessage: 'Please check if you have enough resources or if prerequisites are met.',
|
||||
scrapQuantity: 'Scrap Quantity',
|
||||
scrapRefund: 'Scrap Refund (50%)',
|
||||
scrap: 'Scrap',
|
||||
scrapFailed: 'Scrap Failed',
|
||||
scrapFailedMessage: 'Please check if you have enough ships.'
|
||||
},
|
||||
defense: {
|
||||
attack: 'Attack',
|
||||
@@ -917,6 +948,9 @@ export default {
|
||||
round: 'Round {round}',
|
||||
attackerRemainingPower: 'Attacker remaining power',
|
||||
defenderRemainingPower: 'Defender remaining power',
|
||||
importFromSpyReport: 'Import from Spy Report',
|
||||
selectSpyReport: 'Select Spy Report',
|
||||
noSpyReports: 'No spy reports available',
|
||||
// Battle animation
|
||||
playAnimation: 'Play Animation',
|
||||
showDetails: 'Show Details',
|
||||
@@ -944,6 +978,7 @@ export default {
|
||||
exporting: 'Exporting...',
|
||||
exportSuccess: 'Export successful',
|
||||
exportSuccessWithPath: 'Export successful, file saved to: {path}',
|
||||
storagePermissionDenied: 'Storage permission denied, cannot export file',
|
||||
exportFailed: 'Export failed, please try again',
|
||||
importData: 'Import Data',
|
||||
importDataDesc: 'Restore game progress from JSON file',
|
||||
@@ -961,6 +996,8 @@ export default {
|
||||
gameSettingsDesc: 'Adjust game parameters and preferences',
|
||||
gamePause: 'Game Pause',
|
||||
gamePauseDesc: 'Pause or resume game time and resource production',
|
||||
battleMode: 'Fight to Finish Mode',
|
||||
battleModeDesc: 'When enabled, battles last up to 100 rounds until a winner is decided. When disabled, uses classic 6-round mode',
|
||||
pause: 'Pause',
|
||||
resume: 'Resume',
|
||||
gamePaused: 'Game paused',
|
||||
@@ -1950,13 +1987,19 @@ export default {
|
||||
questNotActive: 'Quest not active',
|
||||
questNotCompleted: 'Quest not completed',
|
||||
rewardsAlreadyClaimed: 'Rewards already claimed',
|
||||
prerequisiteNotMet: 'Prerequisite quest not completed'
|
||||
prerequisiteNotMet: 'Prerequisite quest not completed',
|
||||
questLocked: 'Quest is locked',
|
||||
notInitialized: 'Campaign not initialized',
|
||||
questAlreadyCompleted: 'Quest already completed'
|
||||
},
|
||||
speakers: {
|
||||
ancientVoice: 'Ancient Voice',
|
||||
neighborNPC: 'Neighbor Faction',
|
||||
mysteriousSignal: 'Mysterious Signal',
|
||||
enemyCommander: 'Enemy Commander'
|
||||
enemyCommander: 'Enemy Commander',
|
||||
shadowVoice: 'Shadow Voice',
|
||||
allyNPC: 'Allied Faction',
|
||||
ancientGuardian: 'Ancient Guardian'
|
||||
},
|
||||
objectiveDescriptions: {
|
||||
buildMetalMine: 'Build Metal Mine to level 2',
|
||||
@@ -2044,13 +2087,18 @@ export default {
|
||||
'2_3': {
|
||||
prologue_1:
|
||||
'Your expedition discovered anomalous signals. These signals seem to come from an ancient civilization... Investigate their source.',
|
||||
prologue_2: 'These signals... they carry echoes of a long-lost civilization. Their secrets await discovery...',
|
||||
epilogue_1: 'These symbols... They are ruins of an ancient civilization! Continue investigating to uncover their secrets.'
|
||||
},
|
||||
'2_4': {
|
||||
prologue_1: 'You have found the location of ancient ruins. Send your fleet to explore and see what you can discover.'
|
||||
prologue_1: 'You have found the location of ancient ruins. Send your fleet to explore and see what you can discover.',
|
||||
prologue_2: 'The ruins hold many secrets... Choose your path wisely...',
|
||||
choice_1: 'Explore cautiously - prioritize safety',
|
||||
choice_2: 'Explore aggressively - prioritize discovery'
|
||||
},
|
||||
'2_5': {
|
||||
prologue_1: 'Data archives were found in the ruins. Study this data, perhaps you can unlock new technology.'
|
||||
prologue_1: 'Data archives were found in the ruins. Study this data, perhaps you can unlock new technology.',
|
||||
epilogue_1: 'The ancient data has been decrypted! New technological insights have been gained.'
|
||||
},
|
||||
'3_1': {
|
||||
prologue_1: 'While exploring, do not forget about diplomacy. Maintaining good relations with surrounding factions benefits you.'
|
||||
@@ -2059,16 +2107,19 @@ export default {
|
||||
prologue_1: 'Some factions have shown friendliness. Continue deepening relations, perhaps you can gain more support.'
|
||||
},
|
||||
'3_3': {
|
||||
prologue_1: 'Intelligence indicates hostile forces are watching you from the shadows. Stay vigilant and scout their movements.'
|
||||
prologue_1: 'Intelligence indicates hostile forces are watching you from the shadows. Stay vigilant and scout their movements.',
|
||||
prologue_2: 'Dark forces stir in the void... They have noticed your growing power...'
|
||||
},
|
||||
'3_4': {
|
||||
prologue_1: 'Establish a formal alliance with friendly factions to support each other against threats.'
|
||||
},
|
||||
'3_5': {
|
||||
prologue_1: 'Threats are approaching. Build defense facilities and prepare for possible conflict.'
|
||||
prologue_1: 'Threats are approaching. Build defense facilities and prepare for possible conflict.',
|
||||
epilogue_1: 'Your defenses are ready. The storm is coming, but you are prepared.'
|
||||
},
|
||||
'4_1': {
|
||||
prologue_1: 'The enemy has launched an attack! Defend your planet!',
|
||||
prologue_2: 'The shadow fleet approaches... Your moment of trial has come...',
|
||||
epilogue_1: "You successfully repelled the enemy's first wave. But this is just the beginning..."
|
||||
},
|
||||
'4_2': {
|
||||
@@ -2081,17 +2132,20 @@ export default {
|
||||
prologue_1: 'Much debris remains on the battlefield. Recycle these resources to prepare for the next battle.'
|
||||
},
|
||||
'4_5': {
|
||||
prologue_1: 'The final battle approaches. Build a powerful fleet and prepare for the ultimate challenge.'
|
||||
prologue_1: 'The final battle approaches. Build a powerful fleet and prepare for the ultimate challenge.',
|
||||
epilogue_1: 'Your fleet is assembled. The decisive moment draws near...'
|
||||
},
|
||||
'5_1': {
|
||||
prologue_1: 'All clues point to the deepest part of the ruins. The core secrets of the ancient civilization lie there.',
|
||||
prologue_2: 'You have finally arrived... The truth will soon be revealed...'
|
||||
},
|
||||
'5_2': {
|
||||
prologue_1: 'In the depths of the ruins, you discovered lost ancient technology. Research and unlock their power.'
|
||||
prologue_1: 'In the depths of the ruins, you discovered lost ancient technology. Research and unlock their power.',
|
||||
prologue_2: 'This technology... it predates all known civilizations. Handle it with care...'
|
||||
},
|
||||
'5_3': {
|
||||
prologue_1: 'A mysterious enemy has appeared. This is the final challenge. Defeat it!',
|
||||
prologue_2: 'I am the guardian of these secrets. Prove your worth, or be destroyed!',
|
||||
epilogue_1: 'You did it! The ancient guardian has been defeated. The secrets of the galaxy are now open to you.'
|
||||
},
|
||||
'5_4': {
|
||||
@@ -2099,7 +2153,8 @@ export default {
|
||||
},
|
||||
'5_5': {
|
||||
prologue_1: 'Your legend has just begun. Continue exploring and conquering more star systems!',
|
||||
epilogue_1: 'The galaxy is vast and boundless, with countless secrets waiting for you to discover...'
|
||||
epilogue_1: 'The galaxy is vast and boundless, with countless secrets waiting for you to discover...',
|
||||
epilogue_2: 'Your journey continues... New adventures await beyond the stars...'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -152,6 +152,7 @@ export default {
|
||||
planetDestroyerFactory: 'Fábrica de Destructores de Planetas',
|
||||
geoResearchStation: 'Estación de Investigación Geológica',
|
||||
deepDrillingFacility: 'Instalación de Perforación Profunda',
|
||||
university: 'Universidad',
|
||||
buildTime: 'Tiempo de Construcción',
|
||||
production: 'Producción',
|
||||
consumption: 'Consumo',
|
||||
@@ -200,9 +201,10 @@ export default {
|
||||
jumpGate: 'Transfiere flotas instantáneamente a otras lunas',
|
||||
planetDestroyerFactory: 'Construye armas definitivas capaces de destruir planetas',
|
||||
geoResearchStation:
|
||||
'Investiga estructuras geológicas y aumenta la tasa de regeneración de depósitos de mineral. +50% de regeneración por nivel',
|
||||
'Investiga estructuras geológicas y aumenta la tasa de regeneración de depósitos de mineral. +10% de regeneración por nivel',
|
||||
deepDrillingFacility:
|
||||
'Perfora profundamente en la corteza para acceder a vetas de mineral más profundas. +20% de capacidad de depósito de mineral por nivel'
|
||||
'Perfora profundamente en la corteza para acceder a vetas de mineral más profundas. +20% de capacidad de depósito de mineral por nivel',
|
||||
university: 'Entrena investigadores para acelerar la velocidad de investigación. -8% de tiempo de investigación por nivel'
|
||||
},
|
||||
ships: {
|
||||
lightFighter: 'Caza Ligero',
|
||||
@@ -278,7 +280,11 @@ export default {
|
||||
colonySlots: 'Espacios de Colonia',
|
||||
forAllPlanets: '(Global)',
|
||||
speedBonus: 'Bono de Velocidad',
|
||||
researchSpeedBonus: 'Bono de Velocidad de Investigación'
|
||||
researchSpeedBonus: 'Bono de Velocidad de Investigación',
|
||||
// Visualización de bono de producción de recursos
|
||||
mineralResearch: 'Investigación Mineral',
|
||||
crystalResearch: 'Investigación de Cristal',
|
||||
fuelResearch: 'Investigación de Combustible'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: 'Tecnología de Energía',
|
||||
@@ -299,7 +305,11 @@ export default {
|
||||
darkMatterTechnology: 'Tecnología de Materia Oscura',
|
||||
terraformingTechnology: 'Tecnología de Terraformación',
|
||||
planetDestructionTech: 'Tecnología de Destrucción Planetaria',
|
||||
miningTechnology: 'Tecnología de Minería'
|
||||
miningTechnology: 'Tecnología de Minería',
|
||||
intergalacticResearchNetwork: 'Red de Investigación Intergaláctica',
|
||||
mineralResearch: 'Investigación Mineral',
|
||||
crystalResearch: 'Investigación de Cristal',
|
||||
fuelResearch: 'Investigación de Combustible'
|
||||
},
|
||||
technologyDescriptions: {
|
||||
energyTechnology: 'Mejora la eficiencia energética',
|
||||
@@ -323,7 +333,11 @@ export default {
|
||||
'Investigación de tecnología de terraformación planetaria, añade 30 espacios disponibles a todos los planetas por nivel',
|
||||
planetDestructionTech: 'Tecnología aterradora para destruir planetas enteros',
|
||||
miningTechnology:
|
||||
'Mejora los métodos y equipos de minería, aumenta la capacidad de depósito de mineral en todos los planetas. +15% de capacidad por nivel'
|
||||
'Mejora los métodos y equipos de minería, aumenta la capacidad de depósito de mineral en todos los planetas. +15% de capacidad por nivel',
|
||||
intergalacticResearchNetwork: 'Conecta múltiples laboratorios de investigación entre planetas. Cada nivel conecta 1 laboratorio adicional',
|
||||
mineralResearch: 'Investiga técnicas más eficientes de extracción de metal. +2% de producción de metal por nivel',
|
||||
crystalResearch: 'Investiga técnicas más eficientes de refinamiento de cristal. +2% de producción de cristal por nivel',
|
||||
fuelResearch: 'Investiga técnicas más eficientes de síntesis de deuterio. +2% de producción de deuterio por nivel'
|
||||
},
|
||||
officers: {
|
||||
commander: 'Comandante',
|
||||
@@ -925,6 +939,9 @@ export default {
|
||||
round: 'Ronda {round}',
|
||||
attackerRemainingPower: 'Poder restante del atacante',
|
||||
defenderRemainingPower: 'Poder restante del defensor',
|
||||
importFromSpyReport: 'Importar desde informe de espionaje',
|
||||
selectSpyReport: 'Seleccionar informe de espionaje',
|
||||
noSpyReports: 'No hay informes de espionaje disponibles',
|
||||
// Battle animation
|
||||
playAnimation: 'Reproducir Animación',
|
||||
showDetails: 'Mostrar Detalles',
|
||||
@@ -952,6 +969,7 @@ export default {
|
||||
exporting: 'Exportando...',
|
||||
exportSuccess: 'Exportación exitosa',
|
||||
exportSuccessWithPath: 'Exportación exitosa, archivo guardado en: {path}',
|
||||
storagePermissionDenied: 'Permiso de almacenamiento denegado, no se puede exportar el archivo',
|
||||
exportFailed: 'Exportación fallida, por favor intenta de nuevo',
|
||||
importData: 'Importar Datos',
|
||||
importDataDesc: 'Restaurar progreso del juego desde archivo JSON',
|
||||
@@ -969,6 +987,8 @@ export default {
|
||||
gameSettingsDesc: 'Ajustar parámetros y preferencias del juego',
|
||||
gamePause: 'Pausa del Juego',
|
||||
gamePauseDesc: 'Pausar o reanudar el tiempo del juego y la producción de recursos',
|
||||
battleMode: 'Modo de combate hasta el final',
|
||||
battleModeDesc: 'Cuando está activado, las batallas duran hasta 100 rondas hasta que se decide un ganador. Cuando está desactivado, se usa el modo clásico de 6 rondas',
|
||||
pause: 'Pausar',
|
||||
resume: 'Reanudar',
|
||||
gamePaused: 'Juego pausado',
|
||||
@@ -1954,13 +1974,19 @@ export default {
|
||||
questNotActive: 'Misión no activa',
|
||||
questNotCompleted: 'Misión no completada',
|
||||
rewardsAlreadyClaimed: 'Recompensas ya reclamadas',
|
||||
prerequisiteNotMet: 'Misión prerequisito no completada'
|
||||
prerequisiteNotMet: 'Misión prerequisito no completada',
|
||||
questLocked: 'Misión bloqueada',
|
||||
notInitialized: 'Campaña no inicializada',
|
||||
questAlreadyCompleted: 'Misión ya completada'
|
||||
},
|
||||
speakers: {
|
||||
ancientVoice: 'Voz Antigua',
|
||||
neighborNPC: 'Facción Vecina',
|
||||
mysteriousSignal: 'Señal Misteriosa',
|
||||
enemyCommander: 'Comandante Enemigo'
|
||||
enemyCommander: 'Comandante Enemigo',
|
||||
shadowVoice: 'Voz de la Sombra',
|
||||
allyNPC: 'Facción Aliada',
|
||||
ancientGuardian: 'Guardián Antiguo'
|
||||
},
|
||||
objectiveDescriptions: {
|
||||
buildMetalMine: 'Construir Mina de Metal al nivel 2',
|
||||
@@ -2050,13 +2076,18 @@ export default {
|
||||
'2_3': {
|
||||
prologue_1:
|
||||
'Tu expedición descubrió señales anómalas. Estas señales parecen venir de una civilización antigua... Investiga su origen.',
|
||||
prologue_2: 'Estas señales... llevan ecos de una civilización perdida hace tiempo. Sus secretos esperan ser descubiertos...',
|
||||
epilogue_1: 'Estos símbolos... ¡Son ruinas de una civilización antigua! Continúa investigando para descubrir sus secretos.'
|
||||
},
|
||||
'2_4': {
|
||||
prologue_1: 'Has encontrado la ubicación de ruinas antiguas. Envía tu flota a explorar y ver qué puedes descubrir.'
|
||||
prologue_1: 'Has encontrado la ubicación de ruinas antiguas. Envía tu flota a explorar y ver qué puedes descubrir.',
|
||||
prologue_2: 'Las ruinas guardan muchos secretos... Elige tu camino sabiamente...',
|
||||
choice_1: 'Explorar con cautela - priorizar seguridad',
|
||||
choice_2: 'Explorar agresivamente - priorizar descubrimiento'
|
||||
},
|
||||
'2_5': {
|
||||
prologue_1: 'Se encontraron archivos de datos en las ruinas. Estudia estos datos, quizás puedas desbloquear nueva tecnología.'
|
||||
prologue_1: 'Se encontraron archivos de datos en las ruinas. Estudia estos datos, quizás puedas desbloquear nueva tecnología.',
|
||||
epilogue_1: '¡Los datos antiguos han sido descifrados! Se han obtenido nuevos conocimientos tecnológicos.'
|
||||
},
|
||||
'3_1': {
|
||||
prologue_1: 'Mientras exploras, no olvides la diplomacia. Mantener buenas relaciones con las facciones circundantes te beneficia.'
|
||||
@@ -2066,16 +2097,19 @@ export default {
|
||||
},
|
||||
'3_3': {
|
||||
prologue_1:
|
||||
'La inteligencia indica que fuerzas hostiles te están vigilando desde las sombras. Mantente alerta y explora sus movimientos.'
|
||||
'La inteligencia indica que fuerzas hostiles te están vigilando desde las sombras. Mantente alerta y explora sus movimientos.',
|
||||
prologue_2: 'Fuerzas oscuras se agitan en el vacío... Han notado tu poder creciente...'
|
||||
},
|
||||
'3_4': {
|
||||
prologue_1: 'Establece una alianza formal con facciones amigables para apoyarse mutuamente contra las amenazas.'
|
||||
},
|
||||
'3_5': {
|
||||
prologue_1: 'Las amenazas se acercan. Construye instalaciones de defensa y prepárate para posibles conflictos.'
|
||||
prologue_1: 'Las amenazas se acercan. Construye instalaciones de defensa y prepárate para posibles conflictos.',
|
||||
epilogue_1: 'Tus defensas están listas. La tormenta se acerca, pero estás preparado.'
|
||||
},
|
||||
'4_1': {
|
||||
prologue_1: '¡El enemigo ha lanzado un ataque! ¡Defiende tu planeta!',
|
||||
prologue_2: 'La flota de las sombras se acerca... Ha llegado tu momento de prueba...',
|
||||
epilogue_1: 'Repeliste exitosamente la primera ola del enemigo. Pero esto es solo el comienzo...'
|
||||
},
|
||||
'4_2': {
|
||||
@@ -2088,7 +2122,8 @@ export default {
|
||||
prologue_1: 'Muchos escombros permanecen en el campo de batalla. Recicla estos recursos para prepararte para la próxima batalla.'
|
||||
},
|
||||
'4_5': {
|
||||
prologue_1: 'La batalla final se acerca. Construye una flota poderosa y prepárate para el desafío definitivo.'
|
||||
prologue_1: 'La batalla final se acerca. Construye una flota poderosa y prepárate para el desafío definitivo.',
|
||||
epilogue_1: 'Tu flota está reunida. El momento decisivo se acerca...'
|
||||
},
|
||||
'5_1': {
|
||||
prologue_1:
|
||||
@@ -2096,10 +2131,12 @@ export default {
|
||||
prologue_2: 'Finalmente has llegado... La verdad pronto será revelada...'
|
||||
},
|
||||
'5_2': {
|
||||
prologue_1: 'En las profundidades de las ruinas, descubriste tecnología antigua perdida. Investiga y desbloquea su poder.'
|
||||
prologue_1: 'En las profundidades de las ruinas, descubriste tecnología antigua perdida. Investiga y desbloquea su poder.',
|
||||
prologue_2: 'Esta tecnología... es más antigua que todas las civilizaciones conocidas. Manéjala con cuidado...'
|
||||
},
|
||||
'5_3': {
|
||||
prologue_1: 'Ha aparecido un enemigo misterioso. Este es el desafío final. ¡Derrótalo!',
|
||||
prologue_2: '¡Soy el guardián de estos secretos. Demuestra tu valor o serás destruido!',
|
||||
epilogue_1: '¡Lo lograste! El guardián antiguo ha sido derrotado. Los secretos de la galaxia ahora están abiertos para ti.'
|
||||
},
|
||||
'5_4': {
|
||||
@@ -2107,7 +2144,8 @@ export default {
|
||||
},
|
||||
'5_5': {
|
||||
prologue_1: 'Tu leyenda acaba de comenzar. ¡Continúa explorando y conquistando más sistemas estelares!',
|
||||
epilogue_1: 'La galaxia es vasta e infinita, con innumerables secretos esperando que los descubras...'
|
||||
epilogue_1: 'La galaxia es vasta e infinita, con innumerables secretos esperando que los descubras...',
|
||||
epilogue_2: 'Tu viaje continúa... Nuevas aventuras esperan más allá de las estrellas...'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -165,6 +165,7 @@ export default {
|
||||
planetDestroyerFactory: '惑星破壊工場',
|
||||
geoResearchStation: '地質研究所',
|
||||
deepDrillingFacility: '深部掘削施設',
|
||||
university: '大学',
|
||||
buildTime: '建設時間',
|
||||
build: '建設',
|
||||
production: '生産量',
|
||||
@@ -215,8 +216,9 @@ export default {
|
||||
sensorPhalanx: '周辺星系の艦隊活動を探知',
|
||||
jumpGate: '他の月へ艦隊を瞬間移動',
|
||||
planetDestroyerFactory: '惑星を破壊できる究極兵器を建造',
|
||||
geoResearchStation: '地質構造を研究し、鉱脈の自然回復速度を向上。レベル毎に回復速度50%増加',
|
||||
deepDrillingFacility: ''
|
||||
geoResearchStation: '地質構造を研究し、鉱脈の自然回復速度を向上。レベル毎に回復速度10%増加',
|
||||
deepDrillingFacility: '',
|
||||
university: '研究者を育成し、研究速度を加速。レベル毎に研究時間-8%'
|
||||
},
|
||||
ships: {
|
||||
lightFighter: '軽戦闘機',
|
||||
@@ -299,7 +301,11 @@ export default {
|
||||
colonySlots: '植民地スロット',
|
||||
forAllPlanets: '(全惑星)',
|
||||
speedBonus: '速度ボーナス',
|
||||
researchSpeedBonus: '研究速度ボーナス'
|
||||
researchSpeedBonus: '研究速度ボーナス',
|
||||
// 資源生産ボーナス表示
|
||||
mineralResearch: '鉱物研究',
|
||||
crystalResearch: 'クリスタル研究',
|
||||
fuelResearch: '燃料研究'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: 'エネルギー技術',
|
||||
@@ -320,7 +326,11 @@ export default {
|
||||
darkMatterTechnology: 'ダークマター技術',
|
||||
terraformingTechnology: 'テラフォーミング技術',
|
||||
planetDestructionTech: '惑星破壊技術',
|
||||
miningTechnology: ''
|
||||
miningTechnology: '',
|
||||
intergalacticResearchNetwork: '銀河間研究ネットワーク',
|
||||
mineralResearch: '鉱物研究',
|
||||
crystalResearch: 'クリスタル研究',
|
||||
fuelResearch: '燃料研究'
|
||||
},
|
||||
technologyDescriptions: {
|
||||
energyTechnology: 'エネルギー利用効率を向上',
|
||||
@@ -342,7 +352,11 @@ export default {
|
||||
darkMatterTechnology: 'ダークマターの性質と応用を研究',
|
||||
terraformingTechnology: '惑星地形改造技術を研究、レベル毎に全惑星の利用可能スペース30増加',
|
||||
planetDestructionTech: '惑星全体を破壊する恐怖の技術を研究',
|
||||
miningTechnology: ''
|
||||
miningTechnology: '',
|
||||
intergalacticResearchNetwork: '複数の惑星の研究所を連結。レベル毎に追加1研究所を接続',
|
||||
mineralResearch: 'より効率的な金属抽出技術を研究。レベル毎に金属生産+2%',
|
||||
crystalResearch: 'より効率的なクリスタル精製技術を研究。レベル毎にクリスタル生産+2%',
|
||||
fuelResearch: 'より効率的な重水素合成技術を研究。レベル毎に重水素生産+2%'
|
||||
},
|
||||
officers: {
|
||||
commander: '司令官',
|
||||
@@ -955,7 +969,10 @@ export default {
|
||||
hideRoundDetails: 'ラウンド詳細非表示',
|
||||
round: '第{round}ラウンド',
|
||||
attackerRemainingPower: '攻撃側残存火力',
|
||||
defenderRemainingPower: '防御側残存火力'
|
||||
defenderRemainingPower: '防御側残存火力',
|
||||
importFromSpyReport: 'スパイレポートからインポート',
|
||||
selectSpyReport: 'スパイレポートを選択',
|
||||
noSpyReports: 'スパイレポートがありません'
|
||||
},
|
||||
settings: {
|
||||
dataManagement: 'データ管理',
|
||||
@@ -966,6 +983,7 @@ export default {
|
||||
exporting: 'エクスポート中...',
|
||||
exportSuccess: 'エクスポート成功',
|
||||
exportSuccessWithPath: 'エクスポート成功、ファイルの保存先:{path}',
|
||||
storagePermissionDenied: 'ストレージ権限が拒否されました。ファイルをエクスポートできません',
|
||||
exportFailed: 'エクスポートに失敗しました。もう一度お試しください',
|
||||
importData: 'データインポート',
|
||||
importDataDesc: 'JSONファイルからゲームの進行状況を復元',
|
||||
@@ -983,6 +1001,8 @@ export default {
|
||||
gameSettingsDesc: 'ゲームパラメータと設定を調整',
|
||||
gamePause: 'ゲーム一時停止',
|
||||
gamePauseDesc: 'ゲーム時間と資源生産を一時停止または再開',
|
||||
battleMode: '最後まで戦うモード',
|
||||
battleModeDesc: '有効にすると、勝者が決まるまで最大100ラウンドの戦闘が行われます。無効の場合は、クラシックな6ラウンドモードが使用されます',
|
||||
pause: '一時停止',
|
||||
resume: '再開',
|
||||
gamePaused: 'ゲームを一時停止しました',
|
||||
@@ -1996,13 +2016,19 @@ export default {
|
||||
questNotActive: 'クエストはアクティブではありません',
|
||||
questNotCompleted: 'クエスト未完了',
|
||||
rewardsAlreadyClaimed: '報酬は既に受け取り済み',
|
||||
prerequisiteNotMet: '前提クエスト未完了'
|
||||
prerequisiteNotMet: '前提クエスト未完了',
|
||||
questLocked: 'クエストはロックされています',
|
||||
notInitialized: 'キャンペーンが初期化されていません',
|
||||
questAlreadyCompleted: 'クエストは既に完了しています'
|
||||
},
|
||||
speakers: {
|
||||
ancientVoice: '古代の声',
|
||||
neighborNPC: '隣接勢力',
|
||||
mysteriousSignal: '謎の信号',
|
||||
enemyCommander: '敵司令官'
|
||||
enemyCommander: '敵司令官',
|
||||
shadowVoice: '影の声',
|
||||
allyNPC: '同盟勢力',
|
||||
ancientGuardian: '古代の守護者'
|
||||
},
|
||||
objectiveDescriptions: {
|
||||
buildMetalMine: '金属鉱山をレベル2に建設',
|
||||
@@ -2082,36 +2108,60 @@ export default {
|
||||
},
|
||||
'2_3': {
|
||||
prologue_1: '遠征で異常な信号を発見しました。これらの信号は古代文明からのようです...発信源を調査してください。',
|
||||
prologue_2: 'これらの信号...失われた文明の残響を運んでいる。その秘密が発見を待っている...',
|
||||
epilogue_1: 'これらの記号は...古代文明の遺跡だ!さらに調査して秘密を解き明かそう。'
|
||||
},
|
||||
'2_4': { prologue_1: '古代遺跡の場所を発見しました。艦隊を送り、何が見つかるか探索してください。' },
|
||||
'2_5': { prologue_1: '遺跡でデータアーカイブが見つかりました。このデータを研究すれば、新しい技術が解放できるかもしれません。' },
|
||||
'2_4': {
|
||||
prologue_1: '古代遺跡の場所を発見しました。艦隊を送り、何が見つかるか探索してください。',
|
||||
prologue_2: '遺跡には多くの秘密がある...賢く道を選べ...',
|
||||
choice_1: '慎重に探索する - 安全を優先',
|
||||
choice_2: '積極的に探索する - 発見を優先'
|
||||
},
|
||||
'2_5': {
|
||||
prologue_1: '遺跡でデータアーカイブが見つかりました。このデータを研究すれば、新しい技術が解放できるかもしれません。',
|
||||
epilogue_1: '古代のデータが解読されました!新しい技術的洞察を得ました。'
|
||||
},
|
||||
'3_1': { prologue_1: '探索中も外交を忘れないでください。周囲の勢力と良好な関係を維持することは有益です。' },
|
||||
'3_2': { prologue_1: 'いくつかの勢力が友好を示しています。関係を深め続ければ、より多くのサポートを得られるかもしれません。' },
|
||||
'3_3': { prologue_1: '情報によると敵対勢力が影からあなたを監視しています。警戒を怠らず、彼らの動きを偵察してください。' },
|
||||
'3_3': {
|
||||
prologue_1: '情報によると敵対勢力が影からあなたを監視しています。警戒を怠らず、彼らの動きを偵察してください。',
|
||||
prologue_2: '闇の力が虚空で蠢いている...彼らはあなたの成長する力に気づいた...'
|
||||
},
|
||||
'3_4': { prologue_1: '友好勢力と正式な同盟を結び、脅威に対してお互いをサポートしましょう。' },
|
||||
'3_5': { prologue_1: '脅威が迫っています。防衛施設を建設し、可能な紛争に備えてください。' },
|
||||
'3_5': {
|
||||
prologue_1: '脅威が迫っています。防衛施設を建設し、可能な紛争に備えてください。',
|
||||
epilogue_1: '防衛準備が整いました。嵐が来るが、あなたは準備ができている。'
|
||||
},
|
||||
'4_1': {
|
||||
prologue_1: '敵が攻撃を開始しました!惑星を守ってください!',
|
||||
prologue_2: '影の艦隊が迫っている...あなたの試練の時が来た...',
|
||||
epilogue_1: '敵の第一波を撃退しました。しかしこれは始まりに過ぎません...'
|
||||
},
|
||||
'4_2': { prologue_1: '敵は撤退しましたが、戻ってくるでしょう。彼らの惑星を偵察して戦力を把握してください。' },
|
||||
'4_3': { prologue_1: '反撃の時です。敵の惑星を攻撃し、彼らの戦力を弱めてください。' },
|
||||
'4_4': { prologue_1: '戦場に多くのデブリが残っています。これらの資源をリサイクルして次の戦闘に備えてください。' },
|
||||
'4_5': { prologue_1: '最終決戦が近づいています。強力な艦隊を建造し、究極の挑戦に備えてください。' },
|
||||
'4_5': {
|
||||
prologue_1: '最終決戦が近づいています。強力な艦隊を建造し、究極の挑戦に備えてください。',
|
||||
epilogue_1: '艦隊が集結しました。決戦の時が近づいている...'
|
||||
},
|
||||
'5_1': {
|
||||
prologue_1: 'すべての手がかりは遺跡の最深部を指しています。古代文明の核心的な秘密がそこにあります。',
|
||||
prologue_2: 'ついに到着した...真実がまもなく明かされる...'
|
||||
},
|
||||
'5_2': { prologue_1: '遺跡の深部で失われた古代技術を発見しました。研究してその力を解放してください。' },
|
||||
'5_2': {
|
||||
prologue_1: '遺跡の深部で失われた古代技術を発見しました。研究してその力を解放してください。',
|
||||
prologue_2: 'この技術は...既知のすべての文明より古い。慎重に扱え...'
|
||||
},
|
||||
'5_3': {
|
||||
prologue_1: '謎の敵が現れました。これが最後の挑戦です。撃破してください!',
|
||||
prologue_2: '私はこれらの秘密の守護者だ。お前の価値を証明せよ、さもなくば滅びよ!',
|
||||
epilogue_1: 'やりました!古代の守護者は倒されました。銀河の秘密は今やあなたに開かれています。'
|
||||
},
|
||||
'5_4': { prologue_1: 'ついに平和が訪れました。この新時代に新しい植民地を築き、帝国を拡大してください。' },
|
||||
'5_5': {
|
||||
prologue_1: 'あなたの伝説は始まったばかりです。さらに探索を続け、より多くの星系を征服してください!',
|
||||
epilogue_1: '銀河は広大で果てしなく、数え切れない秘密があなたを待っています...'
|
||||
epilogue_1: '銀河は広大で果てしなく、数え切れない秘密があなたを待っています...',
|
||||
epilogue_2: 'あなたの旅は続く...新たな冒険が星の彼方で待っている...'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +153,7 @@ export default {
|
||||
planetDestroyerFactory: '행성 파괴 공장',
|
||||
geoResearchStation: '지질 연구소',
|
||||
deepDrillingFacility: '심층 시추 시설',
|
||||
university: '대학',
|
||||
buildTime: '건설 시간',
|
||||
build: '건설',
|
||||
production: '생산량',
|
||||
@@ -199,8 +200,9 @@ export default {
|
||||
sensorPhalanx: '주변 행성계의 함대 활동 감지',
|
||||
jumpGate: '다른 위성으로 함대 순간 이동',
|
||||
planetDestroyerFactory: '행성을 파괴할 수 있는 궁극 병기 건조',
|
||||
geoResearchStation: '지질 구조를 연구하여 광맥 자연 회복 속도를 높입니다. 레벨당 회복 속도 50% 증가',
|
||||
deepDrillingFacility: ''
|
||||
geoResearchStation: '지질 구조를 연구하여 광맥 자연 회복 속도를 높입니다. 레벨당 회복 속도 10% 증가',
|
||||
deepDrillingFacility: '',
|
||||
university: '연구원을 양성하여 연구 속도를 가속합니다. 레벨당 연구 시간 -8%'
|
||||
},
|
||||
ships: {
|
||||
lightFighter: '경전투기',
|
||||
@@ -276,7 +278,11 @@ export default {
|
||||
colonySlots: '식민지 슬롯',
|
||||
forAllPlanets: '(전역)',
|
||||
speedBonus: '속도 보너스',
|
||||
researchSpeedBonus: '연구 속도 보너스'
|
||||
researchSpeedBonus: '연구 속도 보너스',
|
||||
// 자원 생산 보너스 표시
|
||||
mineralResearch: '광물 연구',
|
||||
crystalResearch: '크리스탈 연구',
|
||||
fuelResearch: '연료 연구'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: '에너지 기술',
|
||||
@@ -297,7 +303,11 @@ export default {
|
||||
darkMatterTechnology: '암흑 물질 기술',
|
||||
terraformingTechnology: '지형 변환 기술',
|
||||
planetDestructionTech: '행성 파괴 기술',
|
||||
miningTechnology: ''
|
||||
miningTechnology: '',
|
||||
intergalacticResearchNetwork: '은하간 연구 네트워크',
|
||||
mineralResearch: '광물 연구',
|
||||
crystalResearch: '크리스탈 연구',
|
||||
fuelResearch: '연료 연구'
|
||||
},
|
||||
technologyDescriptions: {
|
||||
energyTechnology: '에너지 이용 효율 향상',
|
||||
@@ -319,7 +329,11 @@ export default {
|
||||
darkMatterTechnology: '암흑 물질의 성질과 응용 연구',
|
||||
terraformingTechnology: '행성 지형 개조 기술 연구, 레벨당 모든 행성의 가용 공간 30 증가',
|
||||
planetDestructionTech: '행성 전체를 파괴하는 공포의 기술 연구',
|
||||
miningTechnology: ''
|
||||
miningTechnology: '',
|
||||
intergalacticResearchNetwork: '여러 행성의 연구소를 연결합니다. 레벨당 1개 추가 연구소 연결',
|
||||
mineralResearch: '더 효율적인 금속 추출 기술 연구. 레벨당 금속 생산 +2%',
|
||||
crystalResearch: '더 효율적인 크리스탈 정제 기술 연구. 레벨당 크리스탈 생산 +2%',
|
||||
fuelResearch: '더 효율적인 중수소 합성 기술 연구. 레벨당 중수소 생산 +2%'
|
||||
},
|
||||
officers: {
|
||||
commander: '사령관',
|
||||
@@ -910,7 +924,10 @@ export default {
|
||||
hideRoundDetails: '라운드 상세 숨기기',
|
||||
round: '제 {round} 라운드',
|
||||
attackerRemainingPower: '공격자 잔여 화력',
|
||||
defenderRemainingPower: '방어자 잔여 화력'
|
||||
defenderRemainingPower: '방어자 잔여 화력',
|
||||
importFromSpyReport: '정찰 보고서에서 가져오기',
|
||||
selectSpyReport: '정찰 보고서 선택',
|
||||
noSpyReports: '정찰 보고서가 없습니다'
|
||||
},
|
||||
settings: {
|
||||
dataManagement: '데이터 관리',
|
||||
@@ -921,6 +938,7 @@ export default {
|
||||
exporting: '내보내는 중...',
|
||||
exportSuccess: '내보내기 성공',
|
||||
exportSuccessWithPath: '내보내기 성공, 파일 저장 위치: {path}',
|
||||
storagePermissionDenied: '저장소 권한이 거부되어 파일을 내보낼 수 없습니다',
|
||||
exportFailed: '내보내기 실패, 다시 시도해주세요',
|
||||
importData: '데이터 가져오기',
|
||||
importDataDesc: 'JSON 파일에서 게임 진행 상황 복원',
|
||||
@@ -938,6 +956,8 @@ export default {
|
||||
gameSettingsDesc: '게임 매개변수 및 설정 조정',
|
||||
gamePause: '게임 일시정지',
|
||||
gamePauseDesc: '게임 시간 및 자원 생산 일시정지 또는 재개',
|
||||
battleMode: '끝까지 싸우기 모드',
|
||||
battleModeDesc: '활성화하면 승자가 결정될 때까지 최대 100라운드까지 전투가 진행됩니다. 비활성화하면 클래식 6라운드 모드가 사용됩니다',
|
||||
pause: '일시정지',
|
||||
resume: '재개',
|
||||
gamePaused: '게임이 일시정지되었습니다',
|
||||
@@ -1936,13 +1956,19 @@ export default {
|
||||
questNotActive: '퀘스트가 활성화되지 않았습니다',
|
||||
questNotCompleted: '퀘스트 미완료',
|
||||
rewardsAlreadyClaimed: '이미 보상을 받았습니다',
|
||||
prerequisiteNotMet: '선행 퀘스트 미완료'
|
||||
prerequisiteNotMet: '선행 퀘스트 미완료',
|
||||
questLocked: '퀘스트가 잠겨 있습니다',
|
||||
notInitialized: '캠페인이 초기화되지 않았습니다',
|
||||
questAlreadyCompleted: '퀘스트가 이미 완료되었습니다'
|
||||
},
|
||||
speakers: {
|
||||
ancientVoice: '고대의 목소리',
|
||||
neighborNPC: '인접 세력',
|
||||
mysteriousSignal: '신비한 신호',
|
||||
enemyCommander: '적 사령관'
|
||||
enemyCommander: '적 사령관',
|
||||
shadowVoice: '그림자의 목소리',
|
||||
allyNPC: '동맹 세력',
|
||||
ancientGuardian: '고대의 수호자'
|
||||
},
|
||||
objectiveDescriptions: {
|
||||
buildMetalMine: '금속 광산을 레벨 2로 건설',
|
||||
@@ -2023,38 +2049,60 @@ export default {
|
||||
},
|
||||
'2_3': {
|
||||
prologue_1: '탐험에서 이상한 신호를 발견했습니다. 이 신호들은 고대 문명에서 온 것 같습니다... 출처를 조사하세요.',
|
||||
prologue_2: '이 신호들... 잃어버린 문명의 메아리를 담고 있다. 그들의 비밀이 발견을 기다리고 있다...',
|
||||
epilogue_1: '이 기호들은... 고대 문명의 유적이다! 계속 조사하여 비밀을 밝히세요.'
|
||||
},
|
||||
'2_4': { prologue_1: '고대 유적의 위치를 발견했습니다. 함대를 보내 무엇을 발견할 수 있는지 탐험하세요.' },
|
||||
'2_5': { prologue_1: '유적에서 데이터 아카이브가 발견되었습니다. 이 데이터를 연구하면 새 기술을 해금할 수 있을지도 모릅니다.' },
|
||||
'2_4': {
|
||||
prologue_1: '고대 유적의 위치를 발견했습니다. 함대를 보내 무엇을 발견할 수 있는지 탐험하세요.',
|
||||
prologue_2: '유적에는 많은 비밀이 있다... 현명하게 길을 선택하라...',
|
||||
choice_1: '신중하게 탐험 - 안전 우선',
|
||||
choice_2: '적극적으로 탐험 - 발견 우선'
|
||||
},
|
||||
'2_5': {
|
||||
prologue_1: '유적에서 데이터 아카이브가 발견되었습니다. 이 데이터를 연구하면 새 기술을 해금할 수 있을지도 모릅니다.',
|
||||
epilogue_1: '고대 데이터가 해독되었습니다! 새로운 기술적 통찰을 얻었습니다.'
|
||||
},
|
||||
'3_1': { prologue_1: '탐험 중에도 외교를 잊지 마세요. 주변 세력과 좋은 관계를 유지하는 것이 유익합니다.' },
|
||||
'3_2': { prologue_1: '일부 세력이 우호를 보이고 있습니다. 관계를 계속 깊게 하면 더 많은 지원을 받을 수 있을지도 모릅니다.' },
|
||||
'3_3': {
|
||||
prologue_1: '정보에 따르면 적대 세력이 그림자에서 당신을 감시하고 있습니다. 경계를 늦추지 말고 그들의 움직임을 정찰하세요.'
|
||||
prologue_1: '정보에 따르면 적대 세력이 그림자에서 당신을 감시하고 있습니다. 경계를 늦추지 말고 그들의 움직임을 정찰하세요.',
|
||||
prologue_2: '어둠의 힘이 허공에서 움직이고 있다... 그들은 당신의 성장하는 힘을 알아챘다...'
|
||||
},
|
||||
'3_4': { prologue_1: '우호 세력과 공식 동맹을 맺어 위협에 대해 서로를 지원하세요.' },
|
||||
'3_5': { prologue_1: '위협이 다가오고 있습니다. 방어 시설을 건설하고 가능한 충돌에 대비하세요.' },
|
||||
'3_5': {
|
||||
prologue_1: '위협이 다가오고 있습니다. 방어 시설을 건설하고 가능한 충돌에 대비하세요.',
|
||||
epilogue_1: '방어 준비가 완료되었습니다. 폭풍이 오지만, 당신은 준비가 되어 있습니다.'
|
||||
},
|
||||
'4_1': {
|
||||
prologue_1: '적이 공격을 시작했습니다! 행성을 방어하세요!',
|
||||
prologue_2: '그림자 함대가 다가온다... 당신의 시련의 시간이 왔다...',
|
||||
epilogue_1: '적의 첫 번째 파도를 성공적으로 격퇴했습니다. 하지만 이것은 시작에 불과합니다...'
|
||||
},
|
||||
'4_2': { prologue_1: '적이 후퇴했지만 돌아올 것입니다. 그들의 행성을 정찰하여 전력을 파악하세요.' },
|
||||
'4_3': { prologue_1: '반격할 시간입니다. 적 행성을 공격하여 그들의 전력을 약화시키세요.' },
|
||||
'4_4': { prologue_1: '전장에 많은 잔해가 남아 있습니다. 이 자원을 재활용하여 다음 전투에 대비하세요.' },
|
||||
'4_5': { prologue_1: '최종 전투가 다가오고 있습니다. 강력한 함대를 건조하고 궁극의 도전에 대비하세요.' },
|
||||
'4_5': {
|
||||
prologue_1: '최종 전투가 다가오고 있습니다. 강력한 함대를 건조하고 궁극의 도전에 대비하세요.',
|
||||
epilogue_1: '함대가 집결했습니다. 결전의 시간이 다가온다...'
|
||||
},
|
||||
'5_1': {
|
||||
prologue_1: '모든 단서가 유적의 가장 깊은 곳을 가리킵니다. 고대 문명의 핵심 비밀이 그곳에 있습니다.',
|
||||
prologue_2: '드디어 도착했다... 진실이 곧 밝혀질 것이다...'
|
||||
},
|
||||
'5_2': { prologue_1: '유적 깊은 곳에서 잃어버린 고대 기술을 발견했습니다. 연구하여 그 힘을 해방하세요.' },
|
||||
'5_2': {
|
||||
prologue_1: '유적 깊은 곳에서 잃어버린 고대 기술을 발견했습니다. 연구하여 그 힘을 해방하세요.',
|
||||
prologue_2: '이 기술은... 알려진 모든 문명보다 오래되었다. 신중하게 다루어라...'
|
||||
},
|
||||
'5_3': {
|
||||
prologue_1: '신비한 적이 나타났습니다. 이것이 마지막 도전입니다. 격파하세요!',
|
||||
prologue_2: '나는 이 비밀들의 수호자다. 네 가치를 증명하라, 그렇지 않으면 멸망하라!',
|
||||
epilogue_1: '해냈습니다! 고대의 수호자가 쓰러졌습니다. 은하의 비밀이 이제 당신에게 열려 있습니다.'
|
||||
},
|
||||
'5_4': { prologue_1: '마침내 평화가 찾아왔습니다. 이 새 시대에 새 식민지를 세우고 제국을 확장하세요.' },
|
||||
'5_5': {
|
||||
prologue_1: '당신의 전설은 이제 막 시작되었습니다. 계속 탐험하고 더 많은 성계를 정복하세요!',
|
||||
epilogue_1: '은하는 광대하고 끝이 없으며, 셀 수 없는 비밀이 당신을 기다리고 있습니다...'
|
||||
epilogue_1: '은하는 광대하고 끝이 없으며, 셀 수 없는 비밀이 당신을 기다리고 있습니다...',
|
||||
epilogue_2: '당신의 여정은 계속된다... 새로운 모험이 별 너머에서 기다리고 있다...'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,6 +154,7 @@ export default {
|
||||
planetDestroyerFactory: 'Фабрика разрушителей планет',
|
||||
geoResearchStation: 'Геологическая станция',
|
||||
deepDrillingFacility: 'Глубинная буровая установка',
|
||||
university: 'Университет',
|
||||
buildTime: 'Время строительства',
|
||||
build: 'Построить',
|
||||
production: 'Производство',
|
||||
@@ -205,8 +206,9 @@ export default {
|
||||
jumpGate: 'Мгновенно переносит флоты на другие луны',
|
||||
planetDestroyerFactory: 'Производит абсолютное оружие, способное уничтожать планеты',
|
||||
geoResearchStation:
|
||||
'Исследует геологическую структуру и повышает скорость восстановления рудных месторождений. +50% скорости восстановления за уровень',
|
||||
deepDrillingFacility: ''
|
||||
'Исследует геологическую структуру и повышает скорость восстановления рудных месторождений. +10% скорости восстановления за уровень',
|
||||
deepDrillingFacility: '',
|
||||
university: 'Обучает исследователей для ускорения исследований. -8% времени исследования за уровень'
|
||||
},
|
||||
ships: {
|
||||
lightFighter: 'Лёгкий истребитель',
|
||||
@@ -288,7 +290,11 @@ export default {
|
||||
researchQueueBonus: 'Очередь исследований',
|
||||
colonySlots: 'Слоты колоний',
|
||||
forAllPlanets: '(Глобально)',
|
||||
speedBonus: 'Бонус скорости'
|
||||
speedBonus: 'Бонус скорости',
|
||||
// Отображение бонуса производства ресурсов
|
||||
mineralResearch: 'Минеральные исследования',
|
||||
crystalResearch: 'Кристаллические исследования',
|
||||
fuelResearch: 'Топливные исследования'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: 'Энергетическая технология',
|
||||
@@ -309,7 +315,11 @@ export default {
|
||||
darkMatterTechnology: 'Технология тёмной материи',
|
||||
terraformingTechnology: 'Технология терраформирования',
|
||||
planetDestructionTech: 'Технология уничтожения планет',
|
||||
miningTechnology: ''
|
||||
miningTechnology: '',
|
||||
intergalacticResearchNetwork: 'Межгалактическая исследовательская сеть',
|
||||
mineralResearch: 'Исследование минералов',
|
||||
crystalResearch: 'Исследование кристаллов',
|
||||
fuelResearch: 'Исследование топлива'
|
||||
},
|
||||
technologyDescriptions: {
|
||||
energyTechnology: 'Улучшает энергоэффективность',
|
||||
@@ -332,7 +342,11 @@ export default {
|
||||
terraformingTechnology:
|
||||
'Исследование технологии терраформирования планет, увеличивает доступное пространство всех планет на 30 за уровень',
|
||||
planetDestructionTech: 'Исследование ужасающей технологии уничтожения целых планет',
|
||||
miningTechnology: ''
|
||||
miningTechnology: '',
|
||||
intergalacticResearchNetwork: 'Связывает несколько исследовательских лабораторий на разных планетах. Каждый уровень подключает 1 дополнительную лабораторию',
|
||||
mineralResearch: 'Исследование более эффективных методов добычи металла. +2% производства металла за уровень',
|
||||
crystalResearch: 'Исследование более эффективных методов обработки кристаллов. +2% производства кристаллов за уровень',
|
||||
fuelResearch: 'Исследование более эффективных методов синтеза дейтерия. +2% производства дейтерия за уровень'
|
||||
},
|
||||
officers: {
|
||||
commander: 'Командир',
|
||||
@@ -933,7 +947,10 @@ export default {
|
||||
hideRoundDetails: 'Скрыть детали раундов',
|
||||
round: 'Раунд {round}',
|
||||
attackerRemainingPower: 'Оставшаяся мощь нападающего',
|
||||
defenderRemainingPower: 'Оставшаяся мощь защитника'
|
||||
defenderRemainingPower: 'Оставшаяся мощь защитника',
|
||||
importFromSpyReport: 'Импорт из шпионского отчета',
|
||||
selectSpyReport: 'Выбрать шпионский отчет',
|
||||
noSpyReports: 'Нет шпионских отчетов'
|
||||
},
|
||||
settings: {
|
||||
dataManagement: 'Управление данными',
|
||||
@@ -944,6 +961,7 @@ export default {
|
||||
exporting: 'Экспорт...',
|
||||
exportSuccess: 'Экспорт успешен',
|
||||
exportSuccessWithPath: 'Экспорт успешен, файл сохранен в: {path}',
|
||||
storagePermissionDenied: 'Разрешение на хранение отклонено, невозможно экспортировать файл',
|
||||
exportFailed: 'Экспорт не удался, попробуйте еще раз',
|
||||
importData: 'Импорт данных',
|
||||
importDataDesc: 'Восстановить прогресс игры из JSON файла',
|
||||
@@ -961,6 +979,8 @@ export default {
|
||||
gameSettingsDesc: 'Настроить параметры и предпочтения игры',
|
||||
gamePause: 'Пауза игры',
|
||||
gamePauseDesc: 'Приостановить или возобновить игровое время и производство ресурсов',
|
||||
battleMode: 'Режим боя до конца',
|
||||
battleModeDesc: 'При включении бои длятся до 100 раундов до определения победителя. При выключении используется классический режим 6 раундов',
|
||||
pause: 'Пауза',
|
||||
resume: 'Возобновить',
|
||||
gamePaused: 'Игра приостановлена',
|
||||
@@ -1993,13 +2013,19 @@ export default {
|
||||
questNotActive: 'Квест не активен',
|
||||
questNotCompleted: 'Квест не завершён',
|
||||
rewardsAlreadyClaimed: 'Награды уже получены',
|
||||
prerequisiteNotMet: 'Предварительный квест не завершён'
|
||||
prerequisiteNotMet: 'Предварительный квест не завершён',
|
||||
questLocked: 'Квест заблокирован',
|
||||
notInitialized: 'Кампания не инициализирована',
|
||||
questAlreadyCompleted: 'Квест уже завершён'
|
||||
},
|
||||
speakers: {
|
||||
ancientVoice: 'Древний голос',
|
||||
neighborNPC: 'Соседняя фракция',
|
||||
mysteriousSignal: 'Загадочный сигнал',
|
||||
enemyCommander: 'Вражеский командир'
|
||||
enemyCommander: 'Вражеский командир',
|
||||
shadowVoice: 'Голос тени',
|
||||
allyNPC: 'Союзная фракция',
|
||||
ancientGuardian: 'Древний страж'
|
||||
},
|
||||
objectiveDescriptions: {
|
||||
buildMetalMine: 'Построить Металлургический завод до уровня 2',
|
||||
@@ -2089,12 +2115,19 @@ export default {
|
||||
'2_3': {
|
||||
prologue_1:
|
||||
'Ваша экспедиция обнаружила аномальные сигналы. Эти сигналы, похоже, исходят от древней цивилизации... Исследуйте их источник.',
|
||||
prologue_2: 'Эти сигналы... Они несут отголоски исчезнувшей цивилизации. Их тайны ждут открытия...',
|
||||
epilogue_1: 'Эти символы... Это руины древней цивилизации! Продолжайте исследование, чтобы раскрыть их тайны.'
|
||||
},
|
||||
'2_4': {
|
||||
prologue_1: 'Вы нашли местоположение древних руин. Отправьте свой флот на исследование и посмотрите, что вы можете обнаружить.'
|
||||
prologue_1: 'Вы нашли местоположение древних руин. Отправьте свой флот на исследование и посмотрите, что вы можете обнаружить.',
|
||||
prologue_2: 'В руинах скрыто много тайн... Выбирайте путь мудро...',
|
||||
choice_1: 'Исследовать осторожно - приоритет безопасности',
|
||||
choice_2: 'Исследовать агрессивно - приоритет открытий'
|
||||
},
|
||||
'2_5': {
|
||||
prologue_1: 'В руинах найдены архивы данных. Изучите эти данные, возможно, вы сможете разблокировать новую технологию.',
|
||||
epilogue_1: 'Древние данные расшифрованы! Получены новые технологические знания.'
|
||||
},
|
||||
'2_5': { prologue_1: 'В руинах найдены архивы данных. Изучите эти данные, возможно, вы сможете разблокировать новую технологию.' },
|
||||
'3_1': {
|
||||
prologue_1: 'Во время исследований не забывайте о дипломатии. Поддержание хороших отношений с окружающими фракциями выгодно.'
|
||||
},
|
||||
@@ -2103,31 +2136,44 @@ export default {
|
||||
},
|
||||
'3_3': {
|
||||
prologue_1:
|
||||
'Разведка показывает, что враждебные силы наблюдают за вами из тени. Оставайтесь бдительными и разведайте их перемещения.'
|
||||
'Разведка показывает, что враждебные силы наблюдают за вами из тени. Оставайтесь бдительными и разведайте их перемещения.',
|
||||
prologue_2: 'Тёмные силы шевелятся в пустоте... Они заметили вашу растущую мощь...'
|
||||
},
|
||||
'3_4': { prologue_1: 'Заключите официальный альянс с дружественными фракциями для взаимной поддержки против угроз.' },
|
||||
'3_5': { prologue_1: 'Угрозы приближаются. Постройте оборонительные сооружения и подготовьтесь к возможному конфликту.' },
|
||||
'3_5': {
|
||||
prologue_1: 'Угрозы приближаются. Постройте оборонительные сооружения и подготовьтесь к возможному конфликту.',
|
||||
epilogue_1: 'Ваша оборона готова. Буря надвигается, но вы подготовлены.'
|
||||
},
|
||||
'4_1': {
|
||||
prologue_1: 'Враг начал атаку! Защитите свою планету!',
|
||||
prologue_2: 'Теневой флот приближается... Час твоего испытания настал...',
|
||||
epilogue_1: 'Вы успешно отбили первую волну врага. Но это только начало...'
|
||||
},
|
||||
'4_2': { prologue_1: 'Враг отступил, но он вернётся. Разведайте их планеты, чтобы понять их силу.' },
|
||||
'4_3': { prologue_1: 'Пора контратаковать. Атакуйте вражеские планеты и ослабьте их силы.' },
|
||||
'4_4': { prologue_1: 'На поле боя осталось много обломков. Переработайте эти ресурсы для подготовки к следующей битве.' },
|
||||
'4_5': { prologue_1: 'Финальная битва приближается. Постройте мощный флот и приготовьтесь к конечному испытанию.' },
|
||||
'4_5': {
|
||||
prologue_1: 'Финальная битва приближается. Постройте мощный флот и приготовьтесь к конечному испытанию.',
|
||||
epilogue_1: 'Ваш флот собран. Решающий момент приближается...'
|
||||
},
|
||||
'5_1': {
|
||||
prologue_1: 'Все улики указывают на самую глубокую часть руин. Ключевые тайны древней цивилизации находятся там.',
|
||||
prologue_2: 'Ты наконец прибыл... Истина скоро откроется...'
|
||||
},
|
||||
'5_2': { prologue_1: 'В глубинах руин вы обнаружили утерянные древние технологии. Исследуйте и разблокируйте их мощь.' },
|
||||
'5_2': {
|
||||
prologue_1: 'В глубинах руин вы обнаружили утерянные древние технологии. Исследуйте и разблокируйте их мощь.',
|
||||
prologue_2: 'Эта технология... Она древнее всех известных цивилизаций. Обращайтесь с ней осторожно...'
|
||||
},
|
||||
'5_3': {
|
||||
prologue_1: 'Появился загадочный враг. Это финальное испытание. Победите его!',
|
||||
prologue_2: 'Я — страж этих тайн. Докажи свою ценность или будешь уничтожен!',
|
||||
epilogue_1: 'Вы справились! Древний страж повержен. Тайны галактики теперь открыты для вас.'
|
||||
},
|
||||
'5_4': { prologue_1: 'Мир наконец наступил. В эту новую эру основывайте новые колонии и расширяйте свою империю.' },
|
||||
'5_5': {
|
||||
prologue_1: 'Ваша легенда только началась. Продолжайте исследовать и завоёвывать больше звёздных систем!',
|
||||
epilogue_1: 'Галактика необъятна и бесконечна, бесчисленные тайны ждут вас...'
|
||||
epilogue_1: 'Галактика необъятна и бесконечна, бесчисленные тайны ждут вас...',
|
||||
epilogue_2: 'Ваше путешествие продолжается... Новые приключения ждут за звёздами...'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ export default {
|
||||
launchFailed: '发射失败',
|
||||
fleetMissionsFull: '舰队任务槽位已满',
|
||||
insufficientFleet: '舰队数量不足',
|
||||
insufficientShips: '舰船数量不足',
|
||||
invalidQuantity: '无效数量',
|
||||
insufficientFuel: '燃料不足',
|
||||
planetOnly: '该建筑只能在行星上建造',
|
||||
moonOnly: '该建筑只能在月球上建造',
|
||||
@@ -56,7 +58,12 @@ export default {
|
||||
buildingLevelZero: '建筑等级为0,无法拆除',
|
||||
researchQueueFull: '研究队列已满',
|
||||
moonExists: '已存在月球',
|
||||
insufficientDebris: '残骸场不足'
|
||||
insufficientDebris: '残骸场不足',
|
||||
planetNotFound: '找不到星球',
|
||||
cannotAbandonHomePlanet: '不能放弃母星',
|
||||
hasBuildQueue: '请等待建造队列完成',
|
||||
hasFleetOnPlanet: '请先转移或拆除所有舰船',
|
||||
hasDefenseOnPlanet: '请先拆除所有防御设施'
|
||||
},
|
||||
nav: {
|
||||
overview: '总览',
|
||||
@@ -124,7 +131,12 @@ export default {
|
||||
renamePlanet: '重命名星球',
|
||||
renamePlanetTitle: '重命名星球',
|
||||
planetNamePlaceholder: '输入新的星球名称',
|
||||
rename: '重命名'
|
||||
rename: '重命名',
|
||||
abandonColony: '放弃殖民地',
|
||||
confirmAbandon: '确认放弃殖民地',
|
||||
abandonWarning: '确定要放弃 "{name}" 吗?\n\n此操作无法撤销!\n所有建筑、资源和月球(如有)都将丢失。',
|
||||
confirmAbandonButton: '放弃',
|
||||
abandonFailed: '放弃失败'
|
||||
},
|
||||
player: {
|
||||
points: '总积分'
|
||||
@@ -153,6 +165,7 @@ export default {
|
||||
planetDestroyerFactory: '行星毁灭者工厂',
|
||||
geoResearchStation: '地质研究站',
|
||||
deepDrillingFacility: '深层钻探设施',
|
||||
university: '大学',
|
||||
buildTime: '建造时间',
|
||||
production: '产量',
|
||||
consumption: '消耗',
|
||||
@@ -200,8 +213,9 @@ export default {
|
||||
sensorPhalanx: '侦测周围星系的舰队活动',
|
||||
jumpGate: '瞬间传送舰队到其他月球',
|
||||
planetDestroyerFactory: '建造能够摧毁行星的终极武器',
|
||||
geoResearchStation: '研究地质结构,提高矿脉自然恢复速度。每级增加50%恢复速率',
|
||||
deepDrillingFacility: '深入地壳钻探,解锁更深层的矿脉储量。每级增加20%矿脉上限'
|
||||
geoResearchStation: '研究地质结构,提高矿脉自然恢复速度。每级增加10%恢复速率',
|
||||
deepDrillingFacility: '深入地壳钻探,解锁更深层的矿脉储量。每级增加20%矿脉上限',
|
||||
university: '培养科研人员,加快研究速度。每级减少研究时间8%(与星际研究网络叠加)'
|
||||
},
|
||||
ships: {
|
||||
lightFighter: '轻型战斗机',
|
||||
@@ -276,7 +290,11 @@ export default {
|
||||
researchQueueBonus: '研究队列',
|
||||
colonySlots: '殖民地槽位',
|
||||
forAllPlanets: '(全局)',
|
||||
speedBonus: '速度加成'
|
||||
speedBonus: '速度加成',
|
||||
// 资源产量加成显示
|
||||
mineralResearch: '矿物研究',
|
||||
crystalResearch: '晶体研究',
|
||||
fuelResearch: '燃料研究'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: '能源技术',
|
||||
@@ -297,7 +315,11 @@ export default {
|
||||
darkMatterTechnology: '暗物质技术',
|
||||
terraformingTechnology: '地形改造技术',
|
||||
planetDestructionTech: '行星毁灭技术',
|
||||
miningTechnology: '采矿技术'
|
||||
miningTechnology: '采矿技术',
|
||||
intergalacticResearchNetwork: '星际研究网络',
|
||||
mineralResearch: '矿物研究',
|
||||
crystalResearch: '晶体研究',
|
||||
fuelResearch: '燃料研究'
|
||||
},
|
||||
technologyDescriptions: {
|
||||
energyTechnology: '提高能源利用效率',
|
||||
@@ -319,7 +341,11 @@ export default {
|
||||
darkMatterTechnology: '研究暗物质的性质和应用',
|
||||
terraformingTechnology: '研究行星地形改造技术,每级为所有行星增加30个可用空间',
|
||||
planetDestructionTech: '研究如何摧毁整个行星的恐怖技术',
|
||||
miningTechnology: '改进采矿方法和设备,提升所有星球矿脉储量上限。每级增加15%矿脉上限'
|
||||
miningTechnology: '改进采矿方法和设备,提升所有星球矿脉储量上限。每级增加15%矿脉上限',
|
||||
intergalacticResearchNetwork: '连接多个星球的研究实验室,共享研究资源。每级可连接1个额外的研究实验室(取等级最高的N个实验室)',
|
||||
mineralResearch: '研究更高效的金属提取技术,提升金属矿产量。每级增加金属产量2%',
|
||||
crystalResearch: '研究更高效的晶体提炼技术,提升晶体矿产量。每级增加晶体产量2%',
|
||||
fuelResearch: '研究更高效的重氢合成技术,提升重氢产量。每级增加重氢产量2%'
|
||||
},
|
||||
officers: {
|
||||
commander: '指挥官',
|
||||
@@ -437,7 +463,12 @@ export default {
|
||||
inputError: '输入错误',
|
||||
inputErrorMessage: '请输入建造数量!',
|
||||
buildFailed: '建造失败',
|
||||
buildFailedMessage: '请检查资源是否足够或前置条件是否满足。'
|
||||
buildFailedMessage: '请检查资源是否足够或前置条件是否满足。',
|
||||
scrapQuantity: '拆除数量',
|
||||
scrapRefund: '拆除返还 (50%)',
|
||||
scrap: '拆除',
|
||||
scrapFailed: '拆除失败',
|
||||
scrapFailedMessage: '请检查舰船数量是否足够。'
|
||||
},
|
||||
defense: {
|
||||
attack: '攻击力',
|
||||
@@ -859,14 +890,14 @@ export default {
|
||||
missileAttackFailed: '导弹攻击失败,目标星球不存在',
|
||||
missileAttackIntercepted: '所有导弹被拦截',
|
||||
hits: '枚命中',
|
||||
expeditionResources: '远征队发现了资源!',
|
||||
expeditionDarkMatter: '远征队发现了暗物质!',
|
||||
expeditionFleet: '远征队发现了废弃的舰船!',
|
||||
expeditionPiratesAttack: '远征队遭遇海盗袭击,损失了部分舰船',
|
||||
expeditionPiratesEscaped: '远征队遭遇海盗,但成功逃脱',
|
||||
expeditionAliensAttack: '远征队遭遇外星人袭击,损失了部分舰船',
|
||||
expeditionAliensEscaped: '远征队遭遇外星人,但成功逃脱',
|
||||
expeditionNothing: '远征队什么也没有发现'
|
||||
expeditionResources: '探险队发现了资源!',
|
||||
expeditionDarkMatter: '探险队发现了暗物质!',
|
||||
expeditionFleet: '探险队发现了废弃的舰船!',
|
||||
expeditionPiratesAttack: '探险队遭遇海盗袭击,损失了部分舰船',
|
||||
expeditionPiratesEscaped: '探险队遭遇海盗,但成功逃脱',
|
||||
expeditionAliensAttack: '探险队遭遇外星人袭击,损失了部分舰船',
|
||||
expeditionAliensEscaped: '探险队遭遇外星人,但成功逃脱',
|
||||
expeditionNothing: '探险队什么也没有发现'
|
||||
},
|
||||
simulatorView: {
|
||||
title: '战斗模拟器',
|
||||
@@ -903,7 +934,10 @@ export default {
|
||||
hideRoundDetails: '隐藏回合详情',
|
||||
round: '第 {round} 回合',
|
||||
attackerRemainingPower: '攻击方剩余火力',
|
||||
defenderRemainingPower: '防守方剩余火力'
|
||||
defenderRemainingPower: '防守方剩余火力',
|
||||
importFromSpyReport: '从侦查报告导入',
|
||||
selectSpyReport: '选择侦查报告',
|
||||
noSpyReports: '没有侦查报告'
|
||||
},
|
||||
settings: {
|
||||
dataManagement: '数据管理',
|
||||
@@ -914,6 +948,7 @@ export default {
|
||||
exporting: '导出中...',
|
||||
exportSuccess: '导出成功',
|
||||
exportSuccessWithPath: '导出成功,文件已保存到:{path}',
|
||||
storagePermissionDenied: '存储权限被拒绝,无法导出文件',
|
||||
exportFailed: '导出失败,请重试',
|
||||
importData: '导入数据',
|
||||
importDataDesc: '从JSON文件恢复游戏进度',
|
||||
@@ -931,6 +966,8 @@ export default {
|
||||
gameSettingsDesc: '调整游戏参数和偏好设置',
|
||||
gamePause: '游戏暂停',
|
||||
gamePauseDesc: '暂停或恢复游戏时间和资源生产',
|
||||
battleMode: '战斗到底模式',
|
||||
battleModeDesc: '启用后战斗最多进行100回合直到分出胜负,关闭则使用经典6回合模式',
|
||||
pause: '暂停',
|
||||
resume: '恢复',
|
||||
gamePaused: '游戏已暂停',
|
||||
@@ -1738,8 +1775,8 @@ export default {
|
||||
colonizer: '成功殖民星球次数',
|
||||
spy: '执行侦查任务次数',
|
||||
deployer: '执行部署任务次数',
|
||||
explorer: '远征总次数',
|
||||
luckyExplorer: '远征成功次数',
|
||||
explorer: '探险总次数',
|
||||
luckyExplorer: '探险成功次数',
|
||||
recycler: '回收任务次数',
|
||||
scavenger: '回收资源总量',
|
||||
destroyer: '摧毁星球次数',
|
||||
@@ -1867,7 +1904,7 @@ export default {
|
||||
},
|
||||
'2_2': {
|
||||
title: '深空探险',
|
||||
description: '派遣舰队进行远征探险'
|
||||
description: '派遣舰队进行探险探险'
|
||||
},
|
||||
'2_3': {
|
||||
title: '神秘信号',
|
||||
@@ -1963,13 +2000,19 @@ export default {
|
||||
questNotActive: '任务未激活',
|
||||
questNotCompleted: '任务未完成',
|
||||
rewardsAlreadyClaimed: '奖励已领取',
|
||||
prerequisiteNotMet: '前置任务未完成'
|
||||
prerequisiteNotMet: '前置任务未完成',
|
||||
questLocked: '任务已锁定',
|
||||
notInitialized: '战役未初始化',
|
||||
questAlreadyCompleted: '任务已完成'
|
||||
},
|
||||
speakers: {
|
||||
ancientVoice: '古代之声',
|
||||
neighborNPC: '邻近势力',
|
||||
mysteriousSignal: '神秘信号',
|
||||
enemyCommander: '敌方指挥官'
|
||||
enemyCommander: '敌方指挥官',
|
||||
shadowVoice: '暗影之声',
|
||||
allyNPC: '盟友势力',
|
||||
ancientGuardian: '远古守护者'
|
||||
},
|
||||
objectiveDescriptions: {
|
||||
buildMetalMine: '建造金属矿到2级',
|
||||
@@ -1989,10 +2032,10 @@ export default {
|
||||
buildColonyShip: '建造殖民船',
|
||||
colonizeNewPlanet: '殖民新星球',
|
||||
colonizeMultiple: '殖民5个星球',
|
||||
completeExpedition: '完成3次远征任务',
|
||||
expeditionDeepSpace: '完成2次深空远征',
|
||||
completeExpedition: '完成3次探险任务',
|
||||
expeditionDeepSpace: '完成2次深空探险',
|
||||
expeditionUncharted: '探索1次未知区域',
|
||||
expeditionDangerous: '完成3次危险星云远征',
|
||||
expeditionDangerous: '完成3次危险星云探险',
|
||||
discoverRuins: '发现古代遗迹',
|
||||
researchComputer: '研究电脑技术到4级',
|
||||
researchImpulse: '研究脉冲驱动到3级',
|
||||
@@ -2048,18 +2091,23 @@ export default {
|
||||
prologue_2: '宇宙是无限的...更多的星球意味着更多的可能性...'
|
||||
},
|
||||
'2_2': {
|
||||
prologue_1: '殖民成功!但宇宙深处还有更多秘密等待发现。派遣舰队进行远征探险吧。',
|
||||
prologue_1: '殖民成功!但宇宙深处还有更多秘密等待发现。派遣舰队进行探险探险吧。',
|
||||
prologue_2: '远方传来微弱的信号...那里有什么在等待着你...'
|
||||
},
|
||||
'2_3': {
|
||||
prologue_1: '你的探险队发现了异常信号。这些信号似乎来自一个古老的文明...调查它们的来源。',
|
||||
prologue_2: '这些信号...承载着一个早已消逝的文明的回响。它们的秘密等待被发现...',
|
||||
epilogue_1: '这些符号...是古代文明的遗迹!继续调查,揭开它们的秘密。'
|
||||
},
|
||||
'2_4': {
|
||||
prologue_1: '你发现了古代遗迹的位置。派遣舰队前去探索,看看能发现什么。'
|
||||
prologue_1: '你发现了古代遗迹的位置。派遣舰队前去探索,看看能发现什么。',
|
||||
prologue_2: '遗迹中隐藏着许多秘密...明智地选择你的道路...',
|
||||
choice_1: '谨慎探索 - 优先安全',
|
||||
choice_2: '激进探索 - 优先发现'
|
||||
},
|
||||
'2_5': {
|
||||
prologue_1: '遗迹中发现了大量数据档案。研究这些数据,也许能解锁新的科技。'
|
||||
prologue_1: '遗迹中发现了大量数据档案。研究这些数据,也许能解锁新的科技。',
|
||||
epilogue_1: '古代数据已被解密!获得了新的科技洞见。'
|
||||
},
|
||||
'3_1': {
|
||||
prologue_1: '在探索的同时,也不要忘记外交。与周围的势力保持良好关系对你有益。'
|
||||
@@ -2068,16 +2116,19 @@ export default {
|
||||
prologue_1: '有些势力对你表示了友好。继续加深关系,也许能获得更多支持。'
|
||||
},
|
||||
'3_3': {
|
||||
prologue_1: '情报显示,有敌对势力正在暗中观察你。保持警惕,侦查他们的动向。'
|
||||
prologue_1: '情报显示,有敌对势力正在暗中观察你。保持警惕,侦查他们的动向。',
|
||||
prologue_2: '黑暗势力在虚空中蠢蠢欲动...他们已经注意到你日益增长的力量...'
|
||||
},
|
||||
'3_4': {
|
||||
prologue_1: '与友好势力建立正式同盟,在面对威胁时互相支持。'
|
||||
},
|
||||
'3_5': {
|
||||
prologue_1: '威胁正在逼近。建设防御设施,准备迎接可能的冲突。'
|
||||
prologue_1: '威胁正在逼近。建设防御设施,准备迎接可能的冲突。',
|
||||
epilogue_1: '你的防线已经准备就绪。风暴即将来临,但你已经做好了准备。'
|
||||
},
|
||||
'4_1': {
|
||||
prologue_1: '敌人发动了进攻!保卫你的星球!',
|
||||
prologue_2: '暗影舰队正在逼近...你的考验时刻已经到来...',
|
||||
epilogue_1: '你成功击退了敌人的第一波进攻。但这只是开始...'
|
||||
},
|
||||
'4_2': {
|
||||
@@ -2090,17 +2141,20 @@ export default {
|
||||
prologue_1: '战场上留下了大量残骸。回收这些资源,为下一场战斗做准备。'
|
||||
},
|
||||
'4_5': {
|
||||
prologue_1: '最终决战即将来临。建造强大的舰队,准备迎接最后的挑战。'
|
||||
prologue_1: '最终决战即将来临。建造强大的舰队,准备迎接最后的挑战。',
|
||||
epilogue_1: '你的舰队已经集结完毕。决定性的时刻即将到来...'
|
||||
},
|
||||
'5_1': {
|
||||
prologue_1: '所有线索都指向遗迹的最深处。那里隐藏着古代文明最核心的秘密。',
|
||||
prologue_2: '你终于来到了这里...真相即将揭晓...'
|
||||
},
|
||||
'5_2': {
|
||||
prologue_1: '在遗迹深处,你发现了失落的古代科技。研究并解锁它们的力量。'
|
||||
prologue_1: '在遗迹深处,你发现了失落的古代科技。研究并解锁它们的力量。',
|
||||
prologue_2: '这项科技...比所有已知文明都要古老。小心处理...'
|
||||
},
|
||||
'5_3': {
|
||||
prologue_1: '一个神秘的敌人出现了。这是最后的挑战,击败它!',
|
||||
prologue_2: '我是这些秘密的守护者。证明你的价值,否则将被毁灭!',
|
||||
epilogue_1: '你做到了!古代的守护者已被击败。银河系的秘密向你敞开。'
|
||||
},
|
||||
'5_4': {
|
||||
@@ -2108,7 +2162,8 @@ export default {
|
||||
},
|
||||
'5_5': {
|
||||
prologue_1: '你的传奇才刚刚开始。继续探索,征服更多的星系!',
|
||||
epilogue_1: '银河系广阔无垠,还有无数秘密等待你去发现...'
|
||||
epilogue_1: '银河系广阔无垠,还有无数秘密等待你去发现...',
|
||||
epilogue_2: '你的旅程仍在继续...新的冒险在群星之外等待着你...'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -155,6 +155,7 @@ export default {
|
||||
planetDestroyerFactory: '行星毀滅者工廠',
|
||||
geoResearchStation: '地質研究站',
|
||||
deepDrillingFacility: '深層鑽探設施',
|
||||
university: '大學',
|
||||
buildTime: '建造時間',
|
||||
build: '建造',
|
||||
production: '產量',
|
||||
@@ -206,7 +207,8 @@ export default {
|
||||
jumpGate: '瞬間傳送艦隊到其他月球',
|
||||
planetDestroyerFactory: '建造能夠摧毀行星的終極武器',
|
||||
geoResearchStation: '研究地質結構,提高礦脈自然恢復速度。每級增加50%恢復速率',
|
||||
deepDrillingFacility: ''
|
||||
deepDrillingFacility: '',
|
||||
university: '培養科研人員,加快研究速度。每級減少研究時間8%'
|
||||
},
|
||||
ships: {
|
||||
lightFighter: '輕型戰鬥機',
|
||||
@@ -281,7 +283,11 @@ export default {
|
||||
researchQueueBonus: '研究隊列',
|
||||
colonySlots: '殖民地槽位',
|
||||
forAllPlanets: '(全局)',
|
||||
speedBonus: '速度加成'
|
||||
speedBonus: '速度加成',
|
||||
// 資源產量加成顯示
|
||||
mineralResearch: '礦物研究',
|
||||
crystalResearch: '晶體研究',
|
||||
fuelResearch: '燃料研究'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: '能源技術',
|
||||
@@ -302,7 +308,11 @@ export default {
|
||||
darkMatterTechnology: '暗物質技術',
|
||||
terraformingTechnology: '地形改造技術',
|
||||
planetDestructionTech: '行星毀滅技術',
|
||||
miningTechnology: ''
|
||||
miningTechnology: '',
|
||||
intergalacticResearchNetwork: '星際研究網絡',
|
||||
mineralResearch: '礦物研究',
|
||||
crystalResearch: '晶體研究',
|
||||
fuelResearch: '燃料研究'
|
||||
},
|
||||
technologyDescriptions: {
|
||||
energyTechnology: '提高能源利用效率',
|
||||
@@ -324,7 +334,11 @@ export default {
|
||||
darkMatterTechnology: '研究暗物質的性質和應用',
|
||||
terraformingTechnology: '研究行星地形改造技術,每級為所有行星增加30個可用空間',
|
||||
planetDestructionTech: '研究如何摧毀整個行星的恐怖技術',
|
||||
miningTechnology: ''
|
||||
miningTechnology: '',
|
||||
intergalacticResearchNetwork: '連接多個星球的研究實驗室,共享研究資源。每級可連接1個額外的研究實驗室',
|
||||
mineralResearch: '研究更高效的金屬提取技術,提升金屬礦產量。每級增加金屬產量2%',
|
||||
crystalResearch: '研究更高效的晶體提煉技術,提升晶體礦產量。每級增加晶體產量2%',
|
||||
fuelResearch: '研究更高效的重氫合成技術,提升重氫產量。每級增加重氫產量2%'
|
||||
},
|
||||
officers: {
|
||||
commander: '指揮官',
|
||||
@@ -924,7 +938,10 @@ export default {
|
||||
hideRoundDetails: '隱藏回合詳情',
|
||||
round: '第 {round} 回合',
|
||||
attackerRemainingPower: '攻擊方剩餘火力',
|
||||
defenderRemainingPower: '防守方剩餘火力'
|
||||
defenderRemainingPower: '防守方剩餘火力',
|
||||
importFromSpyReport: '從偵查報告匯入',
|
||||
selectSpyReport: '選擇偵查報告',
|
||||
noSpyReports: '沒有偵查報告'
|
||||
},
|
||||
settings: {
|
||||
dataManagement: '資料管理',
|
||||
@@ -935,6 +952,7 @@ export default {
|
||||
exporting: '匯出中...',
|
||||
exportSuccess: '匯出成功',
|
||||
exportSuccessWithPath: '匯出成功,檔案已儲存到:{path}',
|
||||
storagePermissionDenied: '儲存權限被拒絕,無法匯出檔案',
|
||||
exportFailed: '匯出失敗,請重試',
|
||||
importData: '匯入資料',
|
||||
importDataDesc: '從JSON檔案恢復遊戲進度',
|
||||
@@ -952,6 +970,8 @@ export default {
|
||||
gameSettingsDesc: '調整遊戲參數和偏好設定',
|
||||
gamePause: '遊戲暫停',
|
||||
gamePauseDesc: '暫停或恢復遊戲時間和資源生產',
|
||||
battleMode: '戰鬥到底模式',
|
||||
battleModeDesc: '啟用後戰鬥最多進行100回合直到分出勝負,關閉則使用經典6回合模式',
|
||||
pause: '暫停',
|
||||
resume: '恢復',
|
||||
gamePaused: '遊戲已暫停',
|
||||
@@ -2159,13 +2179,19 @@ export default {
|
||||
questNotActive: '任務未激活',
|
||||
questNotCompleted: '任務未完成',
|
||||
rewardsAlreadyClaimed: '獎勵已領取',
|
||||
prerequisiteNotMet: '前置任務未完成'
|
||||
prerequisiteNotMet: '前置任務未完成',
|
||||
questLocked: '任務已鎖定',
|
||||
notInitialized: '戰役未初始化',
|
||||
questAlreadyCompleted: '任務已完成'
|
||||
},
|
||||
speakers: {
|
||||
ancientVoice: '古代之聲',
|
||||
neighborNPC: '鄰近勢力',
|
||||
mysteriousSignal: '神秘信號',
|
||||
enemyCommander: '敵方指揮官'
|
||||
enemyCommander: '敵方指揮官',
|
||||
shadowVoice: '暗影之聲',
|
||||
allyNPC: '盟友勢力',
|
||||
ancientGuardian: '遠古守護者'
|
||||
},
|
||||
objectiveDescriptions: {
|
||||
buildMetalMine: '建造金屬礦到2級',
|
||||
@@ -2249,13 +2275,18 @@ export default {
|
||||
},
|
||||
'2_3': {
|
||||
prologue_1: '你的探險隊發現了異常信號。這些信號似乎來自一個古老的文明...調查它們的來源。',
|
||||
prologue_2: '這些信號...承載著失落文明的回響。它們的秘密等待被發現...',
|
||||
epilogue_1: '這些符號...是古代文明的遺跡!繼續調查,揭開它們的秘密。'
|
||||
},
|
||||
'2_4': {
|
||||
prologue_1: '你發現了古代遺跡的位置。派遣艦隊前去探索,看看能發現什麼。'
|
||||
prologue_1: '你發現了古代遺跡的位置。派遣艦隊前去探索,看看能發現什麼。',
|
||||
prologue_2: '遺跡中藏有許多秘密...明智地選擇你的道路...',
|
||||
choice_1: '謹慎探索 - 優先安全',
|
||||
choice_2: '積極探索 - 優先發現'
|
||||
},
|
||||
'2_5': {
|
||||
prologue_1: '遺跡中發現了大量數據檔案。研究這些數據,也許能解鎖新的科技。'
|
||||
prologue_1: '遺跡中發現了大量數據檔案。研究這些數據,也許能解鎖新的科技。',
|
||||
epilogue_1: '古代數據已被解密!獲得了新的技術見解。'
|
||||
},
|
||||
'3_1': {
|
||||
prologue_1: '在探索的同時,也不要忘記外交。與周圍的勢力保持良好關係對你有益。'
|
||||
@@ -2264,16 +2295,19 @@ export default {
|
||||
prologue_1: '有些勢力對你表示了友好。繼續加深關係,也許能獲得更多支持。'
|
||||
},
|
||||
'3_3': {
|
||||
prologue_1: '情報顯示,有敵對勢力正在暗中觀察你。保持警惕,偵查他們的動向。'
|
||||
prologue_1: '情報顯示,有敵對勢力正在暗中觀察你。保持警惕,偵查他們的動向。',
|
||||
prologue_2: '黑暗勢力在虛空中蠢蠢欲動...他們已經注意到你日益增長的力量...'
|
||||
},
|
||||
'3_4': {
|
||||
prologue_1: '與友好勢力建立正式同盟,在面對威脅時互相支持。'
|
||||
},
|
||||
'3_5': {
|
||||
prologue_1: '威脅正在逼近。建設防禦設施,準備迎接可能的衝突。'
|
||||
prologue_1: '威脅正在逼近。建設防禦設施,準備迎接可能的衝突。',
|
||||
epilogue_1: '你的防禦已經就緒。風暴即將來臨,但你已準備好了。'
|
||||
},
|
||||
'4_1': {
|
||||
prologue_1: '敵人發動了進攻!保衛你的星球!',
|
||||
prologue_2: '暗影艦隊正在逼近...你的考驗時刻已經到來...',
|
||||
epilogue_1: '你成功擊退了敵人的第一波進攻。但這只是開始...'
|
||||
},
|
||||
'4_2': {
|
||||
@@ -2286,17 +2320,20 @@ export default {
|
||||
prologue_1: '戰場上留下了大量殘骸。回收這些資源,為下一場戰鬥做準備。'
|
||||
},
|
||||
'4_5': {
|
||||
prologue_1: '最終決戰即將來臨。建造強大的艦隊,準備迎接最後的挑戰。'
|
||||
prologue_1: '最終決戰即將來臨。建造強大的艦隊,準備迎接最後的挑戰。',
|
||||
epilogue_1: '你的艦隊已經集結完畢。決戰時刻即將來臨...'
|
||||
},
|
||||
'5_1': {
|
||||
prologue_1: '所有線索都指向遺跡的最深處。那裡隱藏著古代文明最核心的秘密。',
|
||||
prologue_2: '你終於來到了這裡...真相即將揭曉...'
|
||||
},
|
||||
'5_2': {
|
||||
prologue_1: '在遺跡深處,你發現了失落的古代科技。研究並解鎖它們的力量。'
|
||||
prologue_1: '在遺跡深處,你發現了失落的古代科技。研究並解鎖它們的力量。',
|
||||
prologue_2: '這項科技...比所有已知文明都要古老。小心處理它...'
|
||||
},
|
||||
'5_3': {
|
||||
prologue_1: '一個神秘的敵人出現了。這是最後的挑戰,擊敗它!',
|
||||
prologue_2: '我是這些秘密的守護者。證明你的價值,否則將被毀滅!',
|
||||
epilogue_1: '你做到了!古代的守護者已被擊敗。銀河系的秘密向你敞開。'
|
||||
},
|
||||
'5_4': {
|
||||
@@ -2304,7 +2341,8 @@ export default {
|
||||
},
|
||||
'5_5': {
|
||||
prologue_1: '你的傳奇才剛剛開始。繼續探索,征服更多的星系!',
|
||||
epilogue_1: '銀河系廣闘無垠,還有無數秘密等待你去發現...'
|
||||
epilogue_1: '銀河系廣闘無垠,還有無數秘密等待你去發現...',
|
||||
epilogue_2: '你的旅程還在繼續...新的冒險在星海彼岸等待著你...'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ export const simulateBattle = async (
|
||||
_attackerOfficers: Record<OfficerType, Officer>,
|
||||
_defenderOfficers: Record<OfficerType, Officer>,
|
||||
attackerTechnologies: Record<TechnologyType, number>,
|
||||
defenderTechnologies: Record<TechnologyType, number>
|
||||
defenderTechnologies: Record<TechnologyType, number>,
|
||||
battleToFinish: boolean = false // 战斗到底模式
|
||||
): Promise<BattleResult> => {
|
||||
// 从科技系统读取实际科技等级
|
||||
const attackerWeaponTech = attackerTechnologies['weaponsTechnology'] || 0
|
||||
@@ -41,7 +42,7 @@ export const simulateBattle = async (
|
||||
shieldTech: defenderShieldTech,
|
||||
armorTech: defenderArmorTech
|
||||
},
|
||||
maxRounds: 6 // 最多6回合
|
||||
maxRounds: battleToFinish ? 100 : 6 // 战斗到底模式最多100回合,经典模式6回合
|
||||
})
|
||||
|
||||
// 计算掠夺(仅攻击方胜利时)
|
||||
|
||||
@@ -23,30 +23,44 @@ export const calculateBuildingCost = (buildingType: BuildingType, targetLevel: n
|
||||
|
||||
/**
|
||||
* 计算建筑升级时间
|
||||
* 使用 2moons 公式(调整版):
|
||||
* 1. 成本系数 = Σ (资源^0.3 / 0.003)
|
||||
* 2. 时间(秒) = 成本系数 / ((1 + 机器人工厂) × 2^纳米工厂 × 游戏速度)
|
||||
* @param buildingType 建筑类型
|
||||
* @param targetLevel 目标等级
|
||||
* @param buildingSpeedBonus 指挥官等提供的速度加成百分比
|
||||
* @param roboticsFactoryLevel 机器人工厂等级
|
||||
* @param naniteFactoryLevel 纳米工厂等级
|
||||
* @param gameSpeed 游戏速度(默认1)
|
||||
*/
|
||||
export const calculateBuildingTime = (
|
||||
buildingType: BuildingType,
|
||||
targetLevel: number,
|
||||
buildingSpeedBonus: number = 0,
|
||||
roboticsFactoryLevel: number = 0,
|
||||
naniteFactoryLevel: number = 0
|
||||
naniteFactoryLevel: number = 0,
|
||||
gameSpeed: number = 1
|
||||
): number => {
|
||||
const config = BUILDINGS[buildingType]
|
||||
const multiplier = Math.pow(config.costMultiplier, targetLevel - 1)
|
||||
const baseTime = config.baseTime * multiplier
|
||||
// 计算该等级的成本
|
||||
const cost = calculateBuildingCost(buildingType, targetLevel)
|
||||
|
||||
// 机器人工厂和纳米工厂的加速:建造时间 / (1 + 机器人工厂等级 + 纳米工厂等级 × 2)
|
||||
const factorySpeedDivisor = 1 + roboticsFactoryLevel + naniteFactoryLevel * 2
|
||||
// 2moons 公式:成本系数 = Σ (资源^0.3 / 0.003)
|
||||
let elementCost = 0
|
||||
if (cost.metal > 0) elementCost += Math.pow(cost.metal, 0.3) / 0.003
|
||||
if (cost.crystal > 0) elementCost += Math.pow(cost.crystal, 0.3) / 0.003
|
||||
if (cost.deuterium > 0) elementCost += Math.pow(cost.deuterium, 0.3) / 0.003
|
||||
|
||||
// 机器人工厂和纳米工厂的加速
|
||||
const factoryBonus = (1 + roboticsFactoryLevel) * Math.pow(2, naniteFactoryLevel)
|
||||
|
||||
// 简化公式:时间(秒) = 成本系数 / (工厂加成 × 游戏速度)
|
||||
const timeInSeconds = elementCost / (factoryBonus * gameSpeed)
|
||||
|
||||
// 指挥官等的百分比加成
|
||||
const speedMultiplier = 1 - buildingSpeedBonus / 100
|
||||
|
||||
return Math.floor((baseTime / factorySpeedDivisor) * speedMultiplier)
|
||||
// 确保最小时间为5秒
|
||||
return Math.max(5, Math.floor(timeInSeconds * speedMultiplier))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +92,16 @@ export const checkBuildingRequirements = (
|
||||
for (const [key, level] of Object.entries(requirements)) {
|
||||
const requiredLevel = level as number
|
||||
if (Object.values(BuildingType).includes(key as BuildingType)) {
|
||||
if ((planet.buildings[key as BuildingType] || 0) < requiredLevel) {
|
||||
const requiredBuildingType = key as BuildingType
|
||||
const requiredBuildingConfig = BUILDINGS[requiredBuildingType]
|
||||
|
||||
// 如果当前是月球,且所需建筑是星球专属建筑(planetOnly),则跳过此前置条件
|
||||
// 这允许在月球上建造机器人工厂等建筑,即使它们的前置条件是无法在月球建造的矿场
|
||||
if (planet.isMoon && requiredBuildingConfig?.planetOnly) {
|
||||
continue
|
||||
}
|
||||
|
||||
if ((planet.buildings[requiredBuildingType] || 0) < requiredLevel) {
|
||||
return false
|
||||
}
|
||||
} else if (Object.values(TechnologyType).includes(key as TechnologyType)) {
|
||||
@@ -168,6 +191,12 @@ export const completeBuildQueue = (
|
||||
const buildingType = item.itemType as BuildingType
|
||||
const currentLevel = planet.buildings[buildingType] || 0
|
||||
planet.buildings[buildingType] = Math.max(0, currentLevel - 1)
|
||||
} else if (item.type === 'scrap_ship') {
|
||||
// 舰船拆除完成,减少舰船数量(舰船已在开始拆除时扣除)
|
||||
// 资源返还也在开始拆除时完成,这里不需要额外操作
|
||||
if (onCompleted) {
|
||||
onCompleted('ship', item.itemType, undefined, item.quantity)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { FleetMission, Planet, Resources, Fleet, BattleResult, SpyReport, P
|
||||
import type { Locale } from '@/locales'
|
||||
import { ShipType, DefenseType, MissionType, BuildingType, OfficerType, TechnologyType, ExpeditionZone } from '@/types/game'
|
||||
import { FLEET_STORAGE_CONFIG, EXPEDITION_ZONES } from '@/config/gameConfig'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import * as battleLogic from './battleLogic'
|
||||
import * as moonLogic from './moonLogic'
|
||||
import * as moonValidation from './moonValidation'
|
||||
@@ -156,6 +157,7 @@ export const processAttackArrival = async (
|
||||
}
|
||||
|
||||
// 执行战斗(使用 Worker 进行异步计算)
|
||||
const gameStore = useGameStore()
|
||||
const battleResult = await battleLogic.simulateBattle(
|
||||
mission.fleet,
|
||||
targetPlanet.fleet,
|
||||
@@ -164,7 +166,8 @@ export const processAttackArrival = async (
|
||||
attacker.officers,
|
||||
defender?.officers || ({} as Record<OfficerType, Officer>),
|
||||
attacker.technologies,
|
||||
defender?.technologies || ({} as Record<TechnologyType, number>)
|
||||
defender?.technologies || ({} as Record<TechnologyType, number>),
|
||||
gameStore.battleToFinish
|
||||
)
|
||||
|
||||
// 更新战斗报告ID
|
||||
@@ -250,6 +253,7 @@ export const processNPCAttackArrival = async (
|
||||
allPlanets: Planet[]
|
||||
): Promise<{ battleResult: BattleResult; moon: Planet | null; debrisField: DebrisField | null } | null> => {
|
||||
// 执行战斗(使用 Worker 进行异步计算)
|
||||
const gameStore = useGameStore()
|
||||
const battleResult = await battleLogic.simulateBattle(
|
||||
mission.fleet, // NPC舰队
|
||||
targetPlanet.fleet, // 玩家舰队
|
||||
@@ -258,7 +262,8 @@ export const processNPCAttackArrival = async (
|
||||
{} as Record<OfficerType, Officer>, // NPC没有军官系统
|
||||
defender.officers || ({} as Record<OfficerType, Officer>), // 玩家军官
|
||||
npc.technologies, // NPC科技等级
|
||||
defender.technologies // 玩家科技等级
|
||||
defender.technologies, // 玩家科技等级
|
||||
gameStore.battleToFinish
|
||||
)
|
||||
|
||||
// 更新战斗报告ID和参与者信息
|
||||
@@ -721,12 +726,12 @@ export const processRecycleArrival = (
|
||||
}
|
||||
|
||||
/**
|
||||
* 远征事件类型
|
||||
* 探险事件类型
|
||||
*/
|
||||
export type ExpeditionEventType = 'resources' | 'darkMatter' | 'fleet' | 'nothing' | 'pirates' | 'aliens'
|
||||
|
||||
/**
|
||||
* 远征结果
|
||||
* 探险结果
|
||||
*/
|
||||
export interface ExpeditionResult {
|
||||
eventType: ExpeditionEventType
|
||||
@@ -737,8 +742,8 @@ export interface ExpeditionResult {
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理远征任务到达
|
||||
* 远征任务会随机触发各种事件,基于探险区域配置
|
||||
* 处理探险任务到达
|
||||
* 探险任务会随机触发各种事件,基于探险区域配置
|
||||
*/
|
||||
export const processExpeditionArrival = (mission: FleetMission): ExpeditionResult => {
|
||||
// 获取探险区域配置,默认为近空区域
|
||||
@@ -968,9 +973,18 @@ export interface DestroyResult {
|
||||
deathstarDestructionChance: number // 死星反向销毁概率
|
||||
isMoon: boolean // 目标是否为月球
|
||||
failReason?: DestroyFailReason // 失败原因
|
||||
battleResult?: BattleResult // 战斗结果(如果发生了战斗)
|
||||
debrisField?: DebrisField // 战斗产生的残骸场
|
||||
moon?: Planet // 战斗产生的月球
|
||||
}
|
||||
|
||||
export const processDestroyArrival = (mission: FleetMission, targetPlanet: Planet | undefined, attacker: Player): DestroyResult => {
|
||||
export const processDestroyArrival = async (
|
||||
mission: FleetMission,
|
||||
targetPlanet: Planet | undefined,
|
||||
attacker: Player,
|
||||
defender: Player | null,
|
||||
allPlanets: Planet[]
|
||||
): Promise<DestroyResult> => {
|
||||
if (!targetPlanet) {
|
||||
mission.status = 'returning'
|
||||
return {
|
||||
@@ -995,8 +1009,8 @@ export const processDestroyArrival = (mission: FleetMission, targetPlanet: Plane
|
||||
}
|
||||
|
||||
// 检查是否有死星
|
||||
const deathstarCount = mission.fleet[ShipType.Deathstar] || 0
|
||||
if (deathstarCount === 0) {
|
||||
const initialDeathstarCount = mission.fleet[ShipType.Deathstar] || 0
|
||||
if (initialDeathstarCount === 0) {
|
||||
mission.status = 'returning'
|
||||
return {
|
||||
success: false,
|
||||
@@ -1008,10 +1022,113 @@ export const processDestroyArrival = (mission: FleetMission, targetPlanet: Plane
|
||||
}
|
||||
}
|
||||
|
||||
// 检查目标是否有防御力量(舰队或防御设施)
|
||||
const hasDefenderFleet = Object.values(targetPlanet.fleet || {}).some(count => count > 0)
|
||||
const hasDefense = Object.values(targetPlanet.defense || {}).some(count => count > 0)
|
||||
const needsBattle = hasDefenderFleet || hasDefense
|
||||
|
||||
let battleResult: BattleResult | undefined
|
||||
let debrisField: DebrisField | undefined
|
||||
let newMoon: Planet | undefined
|
||||
let survivingDeathstars = initialDeathstarCount
|
||||
|
||||
// 如果目标有防御力量,先进行战斗
|
||||
if (needsBattle) {
|
||||
const gameStore = useGameStore()
|
||||
|
||||
// 执行战斗
|
||||
battleResult = await battleLogic.simulateBattle(
|
||||
mission.fleet,
|
||||
targetPlanet.fleet,
|
||||
targetPlanet.defense,
|
||||
targetPlanet.resources,
|
||||
attacker.officers,
|
||||
defender?.officers || ({} as Record<OfficerType, Officer>),
|
||||
attacker.technologies,
|
||||
defender?.technologies || ({} as Record<TechnologyType, number>),
|
||||
gameStore.battleToFinish
|
||||
)
|
||||
|
||||
// 更新战斗报告
|
||||
battleResult.id = `battle_${Date.now()}`
|
||||
battleResult.attackerId = attacker.id
|
||||
battleResult.defenderId = targetPlanet.ownerId || 'unknown'
|
||||
battleResult.attackerPlanetId = mission.originPlanetId
|
||||
battleResult.defenderPlanetId = targetPlanet.id
|
||||
|
||||
// 更新舰队 - 计算幸存舰船
|
||||
const survivingFleet: Partial<Fleet> = {}
|
||||
Object.entries(mission.fleet).forEach(([shipType, initialCount]) => {
|
||||
const lost = battleResult!.attackerLosses[shipType as ShipType] || 0
|
||||
const surviving = initialCount - lost
|
||||
if (surviving > 0) {
|
||||
survivingFleet[shipType as ShipType] = surviving
|
||||
}
|
||||
})
|
||||
mission.fleet = survivingFleet
|
||||
|
||||
// 计算存活的死星数量
|
||||
survivingDeathstars = survivingFleet[ShipType.Deathstar] || 0
|
||||
|
||||
// 更新目标星球舰队和防御
|
||||
Object.entries(battleResult.defenderLosses.fleet).forEach(([shipType, lost]) => {
|
||||
const current = targetPlanet.fleet[shipType as ShipType] || 0
|
||||
targetPlanet.fleet[shipType as ShipType] = Math.max(0, current - lost)
|
||||
})
|
||||
Object.entries(battleResult.defenderLosses.defense).forEach(([defenseType, lost]) => {
|
||||
const current = targetPlanet.defense[defenseType as DefenseType] || 0
|
||||
targetPlanet.defense[defenseType as DefenseType] = Math.max(0, current - lost)
|
||||
})
|
||||
|
||||
// 计算残骸场
|
||||
const debrisResources = battleResult.debrisField
|
||||
if (debrisResources.metal > 0 || debrisResources.crystal > 0) {
|
||||
debrisField = {
|
||||
id: `debris_${targetPlanet.position.galaxy}_${targetPlanet.position.system}_${targetPlanet.position.position}`,
|
||||
position: { ...targetPlanet.position },
|
||||
resources: {
|
||||
metal: debrisResources.metal,
|
||||
crystal: debrisResources.crystal
|
||||
},
|
||||
createdAt: Date.now()
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否生成月球(只有非月球位置才能生成月球)
|
||||
if (!targetPlanet.isMoon && debrisField) {
|
||||
const moonExists = moonLogic.hasMoonAtPosition(allPlanets, targetPlanet.position)
|
||||
if (!moonExists) {
|
||||
newMoon =
|
||||
moonLogic.tryGenerateMoon(
|
||||
{ ...debrisResources, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
targetPlanet.position,
|
||||
targetPlanet.id,
|
||||
targetPlanet.ownerId || attacker.id
|
||||
) || undefined
|
||||
}
|
||||
}
|
||||
|
||||
// 如果攻击方失败或没有存活的死星,直接返回
|
||||
if (battleResult.winner === 'defender' || survivingDeathstars === 0) {
|
||||
mission.status = 'returning'
|
||||
return {
|
||||
success: false,
|
||||
destructionChance: 0,
|
||||
deathstarsLost: initialDeathstarCount > 0 && survivingDeathstars === 0,
|
||||
deathstarDestructionChance: 0,
|
||||
isMoon: targetPlanet.isMoon || false,
|
||||
failReason: survivingDeathstars === 0 ? 'noDeathstar' : 'chanceFailed',
|
||||
battleResult,
|
||||
debrisField,
|
||||
moon: newMoon
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据目标类型使用不同的销毁逻辑
|
||||
if (targetPlanet.isMoon) {
|
||||
// 月球销毁使用 OGame 公式
|
||||
const result = moonLogic.tryDestroyMoon(targetPlanet, deathstarCount)
|
||||
const result = moonLogic.tryDestroyMoon(targetPlanet, survivingDeathstars)
|
||||
|
||||
// 如果死星被反向销毁,从任务舰队中移除
|
||||
if (result.deathstarsDestroyed) {
|
||||
@@ -1027,13 +1144,16 @@ export const processDestroyArrival = (mission: FleetMission, targetPlanet: Plane
|
||||
deathstarsLost: result.deathstarsDestroyed,
|
||||
deathstarDestructionChance: result.deathstarDestructionChance,
|
||||
isMoon: true,
|
||||
failReason: result.moonDestroyed ? undefined : 'chanceFailed'
|
||||
failReason: result.moonDestroyed ? undefined : 'chanceFailed',
|
||||
battleResult,
|
||||
debrisField,
|
||||
moon: newMoon
|
||||
}
|
||||
} else {
|
||||
// 行星销毁使用原有逻辑
|
||||
// 行星销毁使用原有逻辑(基于存活的死星数量)
|
||||
const planetaryShieldCount = targetPlanet.defense[DefenseType.PlanetaryShield] || 0
|
||||
const defensePower = calculatePlanetDefensePower(targetPlanet.fleet, targetPlanet.defense)
|
||||
const destructionChance = calculateDestructionChance(deathstarCount, planetaryShieldCount, defensePower)
|
||||
const destructionChance = calculateDestructionChance(survivingDeathstars, planetaryShieldCount, defensePower)
|
||||
|
||||
const randomValue = Math.random() * 100
|
||||
const success = randomValue < destructionChance
|
||||
@@ -1047,7 +1167,10 @@ export const processDestroyArrival = (mission: FleetMission, targetPlanet: Plane
|
||||
deathstarsLost: false,
|
||||
deathstarDestructionChance: 0,
|
||||
isMoon: false,
|
||||
failReason: success ? undefined : 'chanceFailed'
|
||||
failReason: success ? undefined : 'chanceFailed',
|
||||
battleResult,
|
||||
debrisField,
|
||||
moon: newMoon
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1200,8 +1323,40 @@ export const updateFleetMissions = async (
|
||||
}
|
||||
break
|
||||
|
||||
case MissionType.Destroy:
|
||||
const destroyResult = processDestroyArrival(mission, targetPlanet, attacker)
|
||||
case MissionType.Destroy: {
|
||||
const destroyResult = await processDestroyArrival(mission, targetPlanet, attacker, defender, allPlanets)
|
||||
|
||||
// 处理战斗报告
|
||||
if (destroyResult.battleResult) {
|
||||
battleReports.push(destroyResult.battleResult)
|
||||
}
|
||||
|
||||
// 处理新生成的月球
|
||||
if (destroyResult.moon) {
|
||||
newMoons.push(destroyResult.moon)
|
||||
const moonKey = `${destroyResult.moon.position.galaxy}:${destroyResult.moon.position.system}:${destroyResult.moon.position.position}`
|
||||
planets.set(moonKey, destroyResult.moon)
|
||||
}
|
||||
|
||||
// 处理残骸场
|
||||
if (destroyResult.debrisField) {
|
||||
const existingDebris = debrisFields.get(destroyResult.debrisField.id)
|
||||
if (existingDebris) {
|
||||
const updatedDebris: DebrisField = {
|
||||
...existingDebris,
|
||||
resources: {
|
||||
metal: existingDebris.resources.metal + destroyResult.debrisField.resources.metal,
|
||||
crystal: existingDebris.resources.crystal + destroyResult.debrisField.resources.crystal
|
||||
}
|
||||
}
|
||||
debrisFields.set(destroyResult.debrisField.id, updatedDebris)
|
||||
updatedDebrisFields.push(updatedDebris)
|
||||
} else {
|
||||
debrisFields.set(destroyResult.debrisField.id, destroyResult.debrisField)
|
||||
newDebrisFields.push(destroyResult.debrisField)
|
||||
}
|
||||
}
|
||||
|
||||
if (destroyResult.success && destroyResult.planetId) {
|
||||
// 星球被摧毁
|
||||
destroyedPlanetIds.push(destroyResult.planetId)
|
||||
@@ -1217,6 +1372,7 @@ export const updateFleetMissions = async (
|
||||
planets.delete(targetKey)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,11 +150,20 @@ export const processGameUpdate = (
|
||||
}
|
||||
|
||||
// 更新所有星球资源(直接同步计算,避免 Worker 通信开销)
|
||||
// 获取采矿技术等级(用于矿脉恢复上限计算)
|
||||
const miningTechLevel = player.technologies[TechnologyType.MiningTechnology] || 0
|
||||
// 获取资源研究科技等级
|
||||
const techBonuses = {
|
||||
mineralResearchLevel: player.technologies[TechnologyType.MineralResearch] || 0,
|
||||
crystalResearchLevel: player.technologies[TechnologyType.CrystalResearch] || 0,
|
||||
fuelResearchLevel: player.technologies[TechnologyType.FuelResearch] || 0
|
||||
}
|
||||
|
||||
player.planets.forEach(planet => {
|
||||
// 计算更新前的资源(用于计算生产量)
|
||||
const resourcesBefore = { ...planet.resources }
|
||||
|
||||
resourceLogic.updatePlanetResources(planet, now, bonuses, gameSpeed)
|
||||
resourceLogic.updatePlanetResources(planet, now, bonuses, gameSpeed, miningTechLevel, techBonuses)
|
||||
|
||||
// 追踪资源生产统计
|
||||
if (player.achievementStats) {
|
||||
@@ -209,6 +218,10 @@ export const processGameUpdate = (
|
||||
onCompleted
|
||||
)
|
||||
|
||||
// 重要:先更新 player.researchQueue,再处理等待队列
|
||||
// 这样等待队列处理时可以正确 push 新项目到队列中
|
||||
player.researchQueue = updatedResearchQueue
|
||||
|
||||
// 处理等待队列自动执行
|
||||
const waitingResult = waitingQueueLogic.processAllWaitingQueues(player, now)
|
||||
// 如果有等待队列项被执行,可以在这里添加通知(可选)
|
||||
@@ -244,8 +257,9 @@ export const processGameUpdate = (
|
||||
onUnlock(allUnlockedItems)
|
||||
}
|
||||
|
||||
// 返回当前的研究队列(包含等待队列处理后添加的新项)
|
||||
return {
|
||||
updatedResearchQueue
|
||||
updatedResearchQueue: player.researchQueue
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@ import type {
|
||||
AllyDefenseNotification,
|
||||
AttitudeChangeNotification
|
||||
} from '@/types/game'
|
||||
import { MissionType, ShipType, TechnologyType, RelationStatus, NPCAIType } from '@/types/game'
|
||||
import { MissionType, ShipType, DefenseType, TechnologyType, RelationStatus, NPCAIType } from '@/types/game'
|
||||
|
||||
// 重新导出类型供外部使用
|
||||
export type { TradeOffer, IntelReport, JointAttackInvite, IntelType, AidNotification, AllyDefenseNotification, AttitudeChangeNotification }
|
||||
import * as fleetLogic from './fleetLogic'
|
||||
import * as diplomaticLogic from './diplomaticLogic'
|
||||
import * as resourceLogic from './resourceLogic'
|
||||
import { DIPLOMATIC_CONFIG, SHIPS } from '@/config/gameConfig'
|
||||
import { DIPLOMATIC_CONFIG, SHIPS, DEFENSES } from '@/config/gameConfig'
|
||||
|
||||
// ========== 敌对NPC增强行为类型定义 ==========
|
||||
|
||||
@@ -908,11 +908,69 @@ export const processNPCSpyArrival = (
|
||||
}
|
||||
|
||||
/**
|
||||
* 决定NPC攻击舰队组成
|
||||
* 基于侦查报告和NPC实力
|
||||
* 计算舰队的战斗力
|
||||
* 使用 attack + shield + armor 作为单位战斗力
|
||||
*/
|
||||
const decideAttackFleet = (_npc: NPC, npcPlanet: Planet, _spyReport: SpyReport, config: DynamicBehaviorConfig): Partial<Fleet> | null => {
|
||||
// 简单策略:派出一定比例的可用舰队
|
||||
const calculateFleetCombatPower = (fleet: Partial<Fleet> | undefined): number => {
|
||||
if (!fleet) return 0
|
||||
let power = 0
|
||||
for (const [shipType, count] of Object.entries(fleet)) {
|
||||
if (count && count > 0) {
|
||||
const config = SHIPS[shipType as ShipType]
|
||||
if (config) {
|
||||
// 战斗力 = (攻击力 + 护盾 + 装甲) * 数量
|
||||
power += (config.attack + config.shield + config.armor) * count
|
||||
}
|
||||
}
|
||||
}
|
||||
return power
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算防御设施的战斗力
|
||||
*/
|
||||
const calculateDefenseCombatPower = (defense: Partial<Record<DefenseType, number>> | undefined): number => {
|
||||
if (!defense) return 0
|
||||
let power = 0
|
||||
for (const [defenseType, count] of Object.entries(defense)) {
|
||||
if (count && count > 0) {
|
||||
const config = DEFENSES[defenseType as DefenseType]
|
||||
if (config) {
|
||||
// 战斗力 = (攻击力 + 护盾 + 装甲) * 数量
|
||||
power += (config.attack + config.shield + config.armor) * count
|
||||
}
|
||||
}
|
||||
}
|
||||
return power
|
||||
}
|
||||
|
||||
/**
|
||||
* 评估NPC是否能赢得战斗
|
||||
* 返回NPC战斗力与敌方战斗力的比值
|
||||
*/
|
||||
export const evaluateWinProbability = (npcFleet: Partial<Fleet>, spyReport: SpyReport): number => {
|
||||
const npcPower = calculateFleetCombatPower(npcFleet)
|
||||
const enemyFleetPower = calculateFleetCombatPower(spyReport.fleet)
|
||||
const enemyDefensePower = calculateDefenseCombatPower(spyReport.defense)
|
||||
const totalEnemyPower = enemyFleetPower + enemyDefensePower
|
||||
|
||||
// 如果敌方没有防御力,返回无限大(可以攻击)
|
||||
if (totalEnemyPower === 0) return Infinity
|
||||
|
||||
return npcPower / totalEnemyPower
|
||||
}
|
||||
|
||||
/**
|
||||
* 决定NPC攻击舰队组成
|
||||
* 基于侦查报告和NPC实力,只有当有合理胜算时才攻击
|
||||
*/
|
||||
const decideAttackFleet = (_npc: NPC, npcPlanet: Planet, spyReport: SpyReport, config: DynamicBehaviorConfig): Partial<Fleet> | null => {
|
||||
// 计算敌方总战斗力
|
||||
const enemyFleetPower = calculateFleetCombatPower(spyReport.fleet)
|
||||
const enemyDefensePower = calculateDefenseCombatPower(spyReport.defense)
|
||||
const totalEnemyPower = enemyFleetPower + enemyDefensePower
|
||||
|
||||
// 先计算可用的攻击舰队
|
||||
const attackFleet: Partial<Fleet> = {}
|
||||
let hasShips = false
|
||||
|
||||
@@ -939,7 +997,22 @@ const decideAttackFleet = (_npc: NPC, npcPlanet: Planet, _spyReport: SpyReport,
|
||||
}
|
||||
}
|
||||
|
||||
return hasShips ? attackFleet : null
|
||||
if (!hasShips) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 计算NPC舰队战斗力
|
||||
const npcPower = calculateFleetCombatPower(attackFleet)
|
||||
|
||||
// 如果敌方有防御力,检查是否有足够的胜算
|
||||
// 要求NPC战斗力至少是敌方的1.2倍才会发动攻击(确保有较大胜算)
|
||||
const MIN_WIN_RATIO = 1.2
|
||||
if (totalEnemyPower > 0 && npcPower < totalEnemyPower * MIN_WIN_RATIO) {
|
||||
// NPC战斗力不足,不发动攻击
|
||||
return null
|
||||
}
|
||||
|
||||
return attackFleet
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1520,6 +1593,25 @@ export const createNPCRecycleMission = (npc: NPC, debris: DebrisField, player: P
|
||||
return null
|
||||
}
|
||||
|
||||
// 检查残骸位置是否有玩家星球
|
||||
const playerPlanetAtDebris = allPlanets.find(
|
||||
p =>
|
||||
p.ownerId === player.id &&
|
||||
p.position.galaxy === debris.position.galaxy &&
|
||||
p.position.system === debris.position.system &&
|
||||
p.position.position === debris.position.position
|
||||
)
|
||||
|
||||
// 如果残骸在玩家星球位置,检查玩家是否有防御
|
||||
// 如果玩家有防御,NPC不应该只派回收船去送死(会被击毁产生更多残骸,形成恶性循环)
|
||||
if (playerPlanetAtDebris) {
|
||||
// 计算玩家星球的总防御数量
|
||||
const totalDefense = Object.values(playerPlanetAtDebris.defense || {}).reduce((sum, count) => sum + (count || 0), 0)
|
||||
if (totalDefense > 0) {
|
||||
return null // 玩家有防御,不派纯回收船去送死
|
||||
}
|
||||
}
|
||||
|
||||
// 检查NPC是否有回收船
|
||||
const recyclers = closestPlanet.fleet[ShipType.Recycler] || 0
|
||||
if (recyclers === 0) {
|
||||
@@ -1566,15 +1658,7 @@ export const createNPCRecycleMission = (npc: NPC, debris: DebrisField, player: P
|
||||
}
|
||||
npc.fleetMissions.push(mission)
|
||||
|
||||
// 检查残骸位置是否有玩家星球,如果有则发送警告
|
||||
const playerPlanetAtDebris = allPlanets.find(
|
||||
p =>
|
||||
p.ownerId === player.id &&
|
||||
p.position.galaxy === debris.position.galaxy &&
|
||||
p.position.system === debris.position.system &&
|
||||
p.position.position === debris.position.position
|
||||
)
|
||||
|
||||
// 如果残骸在玩家星球位置,发送警告(非敌对NPC才会执行到这里)
|
||||
if (playerPlanetAtDebris) {
|
||||
// 创建即将到来的舰队警告(非敌对)
|
||||
const alert = createIncomingFleetAlert(mission, npc, playerPlanetAtDebris)
|
||||
|
||||
@@ -266,12 +266,12 @@ export const formatDepletionTime = (hours: number): string => {
|
||||
/**
|
||||
* 计算地质研究站带来的恢复速率加成
|
||||
* @param geoStationLevel 地质研究站等级
|
||||
* @returns 恢复速率倍数(1 + 等级 * 0.5)
|
||||
* @returns 恢复速率倍数(1 + 等级 * 0.1)
|
||||
*/
|
||||
export const calculateGeoStationBonus = (geoStationLevel: number): number => {
|
||||
// 每级地质研究站增加50%恢复速度
|
||||
// 0级 = 1倍, 1级 = 1.5倍, 2级 = 2倍, ..., 10级 = 6倍
|
||||
return 1 + geoStationLevel * 0.5
|
||||
return 1 + geoStationLevel * 0.1
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,8 +280,16 @@ export const calculateGeoStationBonus = (geoStationLevel: number): number => {
|
||||
* @param deposits 矿脉储量对象
|
||||
* @param hoursElapsed 经过的小时数
|
||||
* @param geoStationLevel 地质研究站等级(可选,影响恢复速度)
|
||||
* @param deepDrillingLevel 深层钻探设施等级(可选,影响恢复上限)
|
||||
* @param miningTechLevel 采矿技术等级(可选,影响恢复上限)
|
||||
*/
|
||||
export const regenerateDeposits = (deposits: OreDeposits, hoursElapsed: number, geoStationLevel: number = 0): void => {
|
||||
export const regenerateDeposits = (
|
||||
deposits: OreDeposits,
|
||||
hoursElapsed: number,
|
||||
geoStationLevel: number = 0,
|
||||
deepDrillingLevel: number = 0,
|
||||
miningTechLevel: number = 0
|
||||
): void => {
|
||||
const { REGENERATION } = ORE_DEPOSIT_CONFIG
|
||||
|
||||
if (!REGENERATION.ENABLED || hoursElapsed <= 0) return
|
||||
@@ -289,32 +297,36 @@ export const regenerateDeposits = (deposits: OreDeposits, hoursElapsed: number,
|
||||
// 计算地质研究站加成
|
||||
const geoBonus = calculateGeoStationBonus(geoStationLevel)
|
||||
|
||||
// 动态计算初始储量上限
|
||||
const initialDeposits = calculateInitialDeposits(deposits.position)
|
||||
// 计算带有建筑和科技加成的储量上限
|
||||
const enhancedDeposits = calculateEnhancedDeposits(deposits.position, deepDrillingLevel, miningTechLevel)
|
||||
|
||||
// 计算恢复量(基于初始储量的百分比,乘以地质研究站加成)
|
||||
// 计算恢复量(基于增强后储量的百分比,乘以地质研究站加成)
|
||||
const regenRate = REGENERATION.RATE_PER_HOUR * hoursElapsed * geoBonus
|
||||
const maxPercentage = REGENERATION.MAX_PERCENTAGE
|
||||
|
||||
// 恢复每种资源
|
||||
const metalRegen = initialDeposits.metal * regenRate
|
||||
const crystalRegen = initialDeposits.crystal * regenRate
|
||||
const deuteriumRegen = initialDeposits.deuterium * regenRate
|
||||
const metalRegen = enhancedDeposits.metal * regenRate
|
||||
const crystalRegen = enhancedDeposits.crystal * regenRate
|
||||
const deuteriumRegen = enhancedDeposits.deuterium * regenRate
|
||||
|
||||
// 添加恢复量,但不超过初始储量的最大百分比
|
||||
deposits.metal = Math.min(initialDeposits.metal * maxPercentage, deposits.metal + metalRegen)
|
||||
deposits.crystal = Math.min(initialDeposits.crystal * maxPercentage, deposits.crystal + crystalRegen)
|
||||
deposits.deuterium = Math.min(initialDeposits.deuterium * maxPercentage, deposits.deuterium + deuteriumRegen)
|
||||
// 添加恢复量,但不超过增强后储量的最大百分比
|
||||
deposits.metal = Math.min(enhancedDeposits.metal * maxPercentage, deposits.metal + metalRegen)
|
||||
deposits.crystal = Math.min(enhancedDeposits.crystal * maxPercentage, deposits.crystal + crystalRegen)
|
||||
deposits.deuterium = Math.min(enhancedDeposits.deuterium * maxPercentage, deposits.deuterium + deuteriumRegen)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取矿脉恢复状态信息
|
||||
* @param deposits 矿脉储量
|
||||
* @param geoStationLevel 地质研究站等级(可选,影响恢复时间计算)
|
||||
* @param deepDrillingLevel 深层钻探设施等级(可选,影响恢复上限)
|
||||
* @param miningTechLevel 采矿技术等级(可选,影响恢复上限)
|
||||
*/
|
||||
export const getRegenerationInfo = (
|
||||
deposits: OreDeposits | undefined,
|
||||
geoStationLevel: number = 0
|
||||
geoStationLevel: number = 0,
|
||||
deepDrillingLevel: number = 0,
|
||||
miningTechLevel: number = 0
|
||||
): {
|
||||
metalRecovering: boolean
|
||||
crystalRecovering: boolean
|
||||
@@ -338,26 +350,26 @@ export const getRegenerationInfo = (
|
||||
}
|
||||
}
|
||||
|
||||
// 动态计算初始储量上限
|
||||
const initialDeposits = calculateInitialDeposits(deposits.position)
|
||||
// 计算带有建筑和科技加成的储量上限
|
||||
const enhancedDeposits = calculateEnhancedDeposits(deposits.position, deepDrillingLevel, miningTechLevel)
|
||||
|
||||
const { REGENERATION } = ORE_DEPOSIT_CONFIG
|
||||
const maxPercentage = REGENERATION.MAX_PERCENTAGE
|
||||
// 实际恢复速率 = 基础速率 * 地质研究站加成
|
||||
const ratePerHour = REGENERATION.RATE_PER_HOUR * geoBonus
|
||||
|
||||
const metalMax = initialDeposits.metal * maxPercentage
|
||||
const crystalMax = initialDeposits.crystal * maxPercentage
|
||||
const deuteriumMax = initialDeposits.deuterium * maxPercentage
|
||||
const metalMax = enhancedDeposits.metal * maxPercentage
|
||||
const crystalMax = enhancedDeposits.crystal * maxPercentage
|
||||
const deuteriumMax = enhancedDeposits.deuterium * maxPercentage
|
||||
|
||||
const metalRecovering = deposits.metal < metalMax
|
||||
const crystalRecovering = deposits.crystal < crystalMax
|
||||
const deuteriumRecovering = deposits.deuterium < deuteriumMax
|
||||
|
||||
// 计算恢复到满需要的小时数(考虑地质研究站加成)
|
||||
const hoursToFullMetal = metalRecovering ? (metalMax - deposits.metal) / (initialDeposits.metal * ratePerHour) : 0
|
||||
const hoursToFullCrystal = crystalRecovering ? (crystalMax - deposits.crystal) / (initialDeposits.crystal * ratePerHour) : 0
|
||||
const hoursToFullDeuterium = deuteriumRecovering ? (deuteriumMax - deposits.deuterium) / (initialDeposits.deuterium * ratePerHour) : 0
|
||||
const hoursToFullMetal = metalRecovering ? (metalMax - deposits.metal) / (enhancedDeposits.metal * ratePerHour) : 0
|
||||
const hoursToFullCrystal = crystalRecovering ? (crystalMax - deposits.crystal) / (enhancedDeposits.crystal * ratePerHour) : 0
|
||||
const hoursToFullDeuterium = deuteriumRecovering ? (deuteriumMax - deposits.deuterium) / (enhancedDeposits.deuterium * ratePerHour) : 0
|
||||
|
||||
return {
|
||||
metalRecovering,
|
||||
|
||||
@@ -320,3 +320,63 @@ export const calculateDeuteriumTemperatureBonus = (maxTemperature: number): numb
|
||||
// 返回乘数,例如:-40°C时返回1.52,+100°C时返回0.96
|
||||
return 1.36 - 0.004 * maxTemperature
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否可以放弃殖民地
|
||||
* @param planets 玩家所有星球
|
||||
* @param planetId 要放弃的星球ID
|
||||
* @returns 是否可以放弃及原因
|
||||
*/
|
||||
export const canAbandonColony = (
|
||||
planets: Planet[],
|
||||
planetId: string
|
||||
): { canAbandon: boolean; reason?: string } => {
|
||||
const planet = planets.find(p => p.id === planetId)
|
||||
if (!planet) {
|
||||
return { canAbandon: false, reason: 'errors.planetNotFound' }
|
||||
}
|
||||
|
||||
// 主星(第一个非月球星球)不能放弃
|
||||
const mainPlanet = planets.find(p => !p.isMoon)
|
||||
if (mainPlanet && mainPlanet.id === planetId) {
|
||||
return { canAbandon: false, reason: 'errors.cannotAbandonHomePlanet' }
|
||||
}
|
||||
|
||||
// 检查是否有正在进行的建造队列
|
||||
if (planet.buildQueue.length > 0) {
|
||||
return { canAbandon: false, reason: 'errors.hasBuildQueue' }
|
||||
}
|
||||
|
||||
// 检查是否有舰队在该星球
|
||||
const hasFleet = Object.values(planet.fleet).some(count => count > 0)
|
||||
if (hasFleet) {
|
||||
return { canAbandon: false, reason: 'errors.hasFleetOnPlanet' }
|
||||
}
|
||||
|
||||
// 检查是否有防御在该星球
|
||||
const hasDefense = Object.values(planet.defense).some(count => count > 0)
|
||||
if (hasDefense) {
|
||||
return { canAbandon: false, reason: 'errors.hasDefenseOnPlanet' }
|
||||
}
|
||||
|
||||
return { canAbandon: true }
|
||||
}
|
||||
|
||||
/**
|
||||
* 放弃殖民地
|
||||
* @param planets 玩家所有星球
|
||||
* @param planetId 要放弃的星球ID
|
||||
* @returns 放弃后的星球列表
|
||||
*/
|
||||
export const abandonColony = (planets: Planet[], planetId: string): Planet[] => {
|
||||
const planet = planets.find(p => p.id === planetId)
|
||||
if (!planet) return planets
|
||||
|
||||
// 如果放弃的是行星,同时删除其月球
|
||||
if (!planet.isMoon) {
|
||||
return planets.filter(p => p.id !== planetId && p.parentPlanetId !== planetId)
|
||||
}
|
||||
|
||||
// 如果放弃的是月球,只删除月球
|
||||
return planets.filter(p => p.id !== planetId)
|
||||
}
|
||||
|
||||
@@ -90,16 +90,27 @@ export const checkRequirements = (
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算星球的资源产量(包含军官加成)
|
||||
* 计算星球的资源产量(包含军官加成和科技加成)
|
||||
* @param planet 星球对象
|
||||
* @param officers 玩家的军官对象
|
||||
* @param resourceSpeed 游戏速度
|
||||
* @param techBonuses 科技加成(可选,矿物研究/晶体研究/燃料研究)
|
||||
* @returns 每小时各类资源的产量
|
||||
*/
|
||||
export const getResourceProduction = (planet: Planet, officers: Record<OfficerType, Officer>, resourceSpeed: number = 1): Resources => {
|
||||
export const getResourceProduction = (
|
||||
planet: Planet,
|
||||
officers: Record<OfficerType, Officer>,
|
||||
resourceSpeed: number = 1,
|
||||
techBonuses?: {
|
||||
mineralResearchLevel?: number
|
||||
crystalResearchLevel?: number
|
||||
fuelResearchLevel?: number
|
||||
}
|
||||
): Resources => {
|
||||
// 计算当前激活的军官加成
|
||||
const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now())
|
||||
// 根据建筑等级和军官加成计算资源产量
|
||||
const base = resourceLogic.calculateResourceProduction(planet, bonuses)
|
||||
const base = resourceLogic.calculateResourceProduction(planet, bonuses, techBonuses)
|
||||
return scaleResources(base, resourceSpeed)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,57 @@
|
||||
import type { Resources, BuildQueueItem } from '@/types/game'
|
||||
import type { Resources, BuildQueueItem, Planet } from '@/types/game'
|
||||
import { TechnologyType, BuildingType } from '@/types/game'
|
||||
import { TECHNOLOGIES } from '@/config/gameConfig'
|
||||
import * as pointsLogic from './pointsLogic'
|
||||
|
||||
/**
|
||||
* 计算有效研究实验室等级(考虑星际研究网络)
|
||||
* 星际研究网络允许连接多个星球的研究实验室,取等级最高的N个实验室等级之和
|
||||
* @param planets 玩家的所有星球
|
||||
* @param currentPlanetId 当前星球ID(研究所在的星球)
|
||||
* @param intergalacticResearchNetworkLevel 星际研究网络等级
|
||||
* @returns 有效的研究实验室等级总和
|
||||
*/
|
||||
export const calculateEffectiveLabLevel = (
|
||||
planets: Planet[],
|
||||
currentPlanetId: string,
|
||||
intergalacticResearchNetworkLevel: number
|
||||
): number => {
|
||||
// 收集所有星球的研究实验室等级
|
||||
const labLevels: { planetId: string; level: number }[] = []
|
||||
|
||||
for (const planet of planets) {
|
||||
const labLevel = planet.buildings[BuildingType.ResearchLab] || 0
|
||||
if (labLevel > 0) {
|
||||
labLevels.push({ planetId: planet.id, level: labLevel })
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有星际研究网络,只返回当前星球的实验室等级
|
||||
if (intergalacticResearchNetworkLevel === 0) {
|
||||
const currentPlanet = planets.find(p => p.id === currentPlanetId)
|
||||
return currentPlanet?.buildings[BuildingType.ResearchLab] || 0
|
||||
}
|
||||
|
||||
// 按等级降序排序
|
||||
labLevels.sort((a, b) => b.level - a.level)
|
||||
|
||||
// 可连接的实验室数量 = 1 + 星际研究网络等级
|
||||
// 等级1可连接2个实验室,等级2可连接3个,以此类推
|
||||
const maxLabs = 1 + intergalacticResearchNetworkLevel
|
||||
|
||||
// 取前N个实验室的等级之和
|
||||
let totalLevel = 0
|
||||
const count = Math.min(maxLabs, labLevels.length)
|
||||
for (let i = 0; i < count; i++) {
|
||||
const lab = labLevels[i]
|
||||
if (lab) {
|
||||
totalLevel += lab.level
|
||||
}
|
||||
}
|
||||
|
||||
return totalLevel
|
||||
}
|
||||
|
||||
// 用于生成唯一ID的计数器
|
||||
let researchQueueIdCounter = 0
|
||||
|
||||
@@ -23,31 +72,56 @@ export const calculateTechnologyCost = (techType: TechnologyType, targetLevel: n
|
||||
|
||||
/**
|
||||
* 计算科技研究时间
|
||||
* 使用 2moons 公式(调整版):
|
||||
* 1. 成本系数 = Σ (资源^0.3 / 0.003)
|
||||
* 2. 时间(秒) = 成本系数 / ((1 + 研究实验室等级) × 能源加成 × 游戏速度)
|
||||
* @param techType 科技类型
|
||||
* @param currentLevel 当前等级
|
||||
* @param currentLevel 当前等级(要研究的目标等级 = currentLevel + 1)
|
||||
* @param researchSpeedBonus 军官等提供的研究速度加成百分比
|
||||
* @param researchLabLevel 研究实验室等级
|
||||
* @param energyTechLevel 能源技术等级
|
||||
* @param energyTechLevel 能源技术等级(提供额外加速)
|
||||
* @param gameSpeed 游戏速度(默认1)
|
||||
* @param universityLevel 大学等级(每级减少研究时间8%)
|
||||
*/
|
||||
export const calculateTechnologyTime = (
|
||||
techType: TechnologyType,
|
||||
currentLevel: number,
|
||||
researchSpeedBonus: number = 0,
|
||||
researchLabLevel: number = 1,
|
||||
energyTechLevel: number = 0
|
||||
energyTechLevel: number = 0,
|
||||
gameSpeed: number = 1,
|
||||
universityLevel: number = 0
|
||||
): number => {
|
||||
const config = TECHNOLOGIES[techType]
|
||||
const baseTime = config.baseTime * Math.pow(config.costMultiplier, currentLevel)
|
||||
// 目标等级 = 当前等级 + 1
|
||||
const targetLevel = currentLevel + 1
|
||||
|
||||
// 计算该等级的成本
|
||||
const cost = calculateTechnologyCost(techType, targetLevel)
|
||||
|
||||
// 2moons 公式:成本系数 = Σ (资源^0.3 / 0.003)
|
||||
let elementCost = 0
|
||||
if (cost.metal > 0) elementCost += Math.pow(cost.metal, 0.3) / 0.003
|
||||
if (cost.crystal > 0) elementCost += Math.pow(cost.crystal, 0.3) / 0.003
|
||||
if (cost.deuterium > 0) elementCost += Math.pow(cost.deuterium, 0.3) / 0.003
|
||||
|
||||
// 研究实验室和能源技术的加速:研究时间 / (研究实验室等级 × (1 + 能源技术等级))
|
||||
// 研究实验室等级至少为1,防止除以0
|
||||
const labLevel = Math.max(1, researchLabLevel)
|
||||
const techSpeedDivisor = labLevel * (1 + energyTechLevel)
|
||||
|
||||
// 能源技术提供额外加速(每级5%)
|
||||
const energyBonus = 1 + energyTechLevel * 0.05
|
||||
|
||||
// 简化公式:时间(秒) = 成本系数 / (实验室加成 × 能源加成 × 游戏速度)
|
||||
const timeInSeconds = elementCost / ((1 + labLevel) * energyBonus * gameSpeed)
|
||||
|
||||
// 军官等的百分比加成
|
||||
const speedMultiplier = 1 - researchSpeedBonus / 100
|
||||
|
||||
return Math.floor((baseTime / techSpeedDivisor) * speedMultiplier)
|
||||
// 大学加成:每级减少研究时间8%(最高10级=57%减少,因为是乘法叠加)
|
||||
// 使用乘法叠加:(1 - 0.08)^level
|
||||
const universityMultiplier = Math.pow(0.92, universityLevel)
|
||||
|
||||
// 确保最小时间为5秒
|
||||
return Math.max(5, Math.floor(timeInSeconds * speedMultiplier * universityMultiplier))
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,7 +54,8 @@ export const executeTechnologyResearch = (
|
||||
techType: TechnologyType,
|
||||
currentLevel: number,
|
||||
officers: Record<OfficerType, Officer>,
|
||||
technologies: Partial<Record<TechnologyType, number>>
|
||||
technologies: Partial<Record<TechnologyType, number>>,
|
||||
allPlanets?: Planet[]
|
||||
): { queueItem: BuildQueueItem } => {
|
||||
const targetLevel = currentLevel + 1
|
||||
const cost = researchLogic.calculateTechnologyCost(techType, targetLevel)
|
||||
@@ -62,11 +63,30 @@ export const executeTechnologyResearch = (
|
||||
// 计算军官加成
|
||||
const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now())
|
||||
|
||||
// 获取研究实验室等级和能源技术等级
|
||||
const researchLabLevel = planet.buildings[BuildingType.ResearchLab] || 1
|
||||
const energyTechLevel = technologies[TechnologyType.EnergyTechnology] || 0
|
||||
// 获取星际研究网络等级
|
||||
const intergalacticResearchNetworkLevel = technologies[TechnologyType.IntergalacticResearchNetwork] || 0
|
||||
|
||||
const time = researchLogic.calculateTechnologyTime(techType, currentLevel, bonuses.researchSpeedBonus, researchLabLevel, energyTechLevel)
|
||||
// 计算有效研究实验室等级(考虑星际研究网络)
|
||||
let researchLabLevel: number
|
||||
if (allPlanets && intergalacticResearchNetworkLevel > 0) {
|
||||
researchLabLevel = researchLogic.calculateEffectiveLabLevel(allPlanets, planet.id, intergalacticResearchNetworkLevel)
|
||||
} else {
|
||||
researchLabLevel = planet.buildings[BuildingType.ResearchLab] || 1
|
||||
}
|
||||
|
||||
const energyTechLevel = technologies[TechnologyType.EnergyTechnology] || 0
|
||||
// 获取大学等级(加速研究)
|
||||
const universityLevel = planet.buildings[BuildingType.University] || 0
|
||||
|
||||
const time = researchLogic.calculateTechnologyTime(
|
||||
techType,
|
||||
currentLevel,
|
||||
bonuses.researchSpeedBonus,
|
||||
researchLabLevel,
|
||||
energyTechLevel,
|
||||
1,
|
||||
universityLevel
|
||||
)
|
||||
|
||||
// 扣除资源
|
||||
resourceLogic.deductResources(planet.resources, cost)
|
||||
|
||||
@@ -5,6 +5,24 @@ import { OFFICERS } from '@/config/gameConfig'
|
||||
import * as oreDepositLogic from './oreDepositLogic'
|
||||
import * as planetLogic from './planetLogic'
|
||||
|
||||
/**
|
||||
* 计算资源研究科技加成
|
||||
* @param mineralResearchLevel 矿物研究等级(每级+2%金属产量)
|
||||
* @param crystalResearchLevel 晶体研究等级(每级+2%晶体产量)
|
||||
* @param fuelResearchLevel 燃料研究等级(每级+2%重氢产量)
|
||||
*/
|
||||
export const calculateResearchProductionBonus = (
|
||||
mineralResearchLevel: number = 0,
|
||||
crystalResearchLevel: number = 0,
|
||||
fuelResearchLevel: number = 0
|
||||
): { metalBonus: number; crystalBonus: number; deuteriumBonus: number } => {
|
||||
return {
|
||||
metalBonus: mineralResearchLevel * 2, // 每级2%
|
||||
crystalBonus: crystalResearchLevel * 2,
|
||||
deuteriumBonus: fuelResearchLevel * 2
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算电量产出
|
||||
*/
|
||||
@@ -93,6 +111,9 @@ export const calculateEnergyConsumption = (planet: Planet): number => {
|
||||
|
||||
/**
|
||||
* 计算资源产量(每小时)
|
||||
* @param planet 星球
|
||||
* @param bonuses 军官等加成
|
||||
* @param techBonuses 科技加成(可选,矿物研究/晶体研究/燃料研究)
|
||||
*/
|
||||
export const calculateResourceProduction = (
|
||||
planet: Planet,
|
||||
@@ -100,6 +121,11 @@ export const calculateResourceProduction = (
|
||||
resourceProductionBonus: number
|
||||
darkMatterProductionBonus: number
|
||||
energyProductionBonus: number
|
||||
},
|
||||
techBonuses?: {
|
||||
mineralResearchLevel?: number
|
||||
crystalResearchLevel?: number
|
||||
fuelResearchLevel?: number
|
||||
}
|
||||
): Resources => {
|
||||
const metalMineLevel = planet.buildings[BuildingType.MetalMine] || 0
|
||||
@@ -110,6 +136,16 @@ export const calculateResourceProduction = (
|
||||
const resourceBonus = 1 + (bonuses.resourceProductionBonus || 0) / 100
|
||||
const darkMatterBonus = 1 + (bonuses.darkMatterProductionBonus || 0) / 100
|
||||
|
||||
// 计算科技加成
|
||||
const researchBonus = calculateResearchProductionBonus(
|
||||
techBonuses?.mineralResearchLevel || 0,
|
||||
techBonuses?.crystalResearchLevel || 0,
|
||||
techBonuses?.fuelResearchLevel || 0
|
||||
)
|
||||
const metalTechBonus = 1 + researchBonus.metalBonus / 100
|
||||
const crystalTechBonus = 1 + researchBonus.crystalBonus / 100
|
||||
const deuteriumTechBonus = 1 + researchBonus.deuteriumBonus / 100
|
||||
|
||||
// 计算能量产出(每小时)
|
||||
const energyProduction = calculateEnergyProduction(planet, { energyProductionBonus: bonuses.energyProductionBonus })
|
||||
|
||||
@@ -131,13 +167,28 @@ export const calculateResourceProduction = (
|
||||
const deuteriumTempBonus = planetLogic.calculateDeuteriumTemperatureBonus(planet.temperature?.max ?? 0)
|
||||
|
||||
return {
|
||||
metal: metalMineLevel * 1500 * Math.pow(1.5, metalMineLevel) * resourceBonus * productionEfficiency * metalDepositEfficiency,
|
||||
crystal: crystalMineLevel * 1000 * Math.pow(1.5, crystalMineLevel) * resourceBonus * productionEfficiency * crystalDepositEfficiency,
|
||||
metal:
|
||||
metalMineLevel *
|
||||
1500 *
|
||||
Math.pow(1.5, metalMineLevel) *
|
||||
resourceBonus *
|
||||
metalTechBonus *
|
||||
productionEfficiency *
|
||||
metalDepositEfficiency,
|
||||
crystal:
|
||||
crystalMineLevel *
|
||||
1000 *
|
||||
Math.pow(1.5, crystalMineLevel) *
|
||||
resourceBonus *
|
||||
crystalTechBonus *
|
||||
productionEfficiency *
|
||||
crystalDepositEfficiency,
|
||||
deuterium:
|
||||
deuteriumSynthesizerLevel *
|
||||
500 *
|
||||
Math.pow(1.5, deuteriumSynthesizerLevel) *
|
||||
resourceBonus *
|
||||
deuteriumTechBonus *
|
||||
productionEfficiency *
|
||||
deuteriumDepositEfficiency *
|
||||
deuteriumTempBonus,
|
||||
@@ -183,7 +234,13 @@ export const updatePlanetResources = (
|
||||
energyProductionBonus: number
|
||||
storageCapacityBonus: number
|
||||
},
|
||||
gameSpeed: number = 1
|
||||
gameSpeed: number = 1,
|
||||
miningTechLevel: number = 0,
|
||||
techBonuses?: {
|
||||
mineralResearchLevel?: number
|
||||
crystalResearchLevel?: number
|
||||
fuelResearchLevel?: number
|
||||
}
|
||||
): void => {
|
||||
const timeDiff = (now - planet.lastUpdate) / 1000 // 转换为秒
|
||||
|
||||
@@ -214,11 +271,15 @@ export const updatePlanetResources = (
|
||||
planet.resources.energy = Math.max(0, planet.resources.energy)
|
||||
|
||||
// 计算资源产量(会检查能量是否充足,以及矿脉储量效率)
|
||||
const production = calculateResourceProduction(planet, {
|
||||
resourceProductionBonus: bonuses.resourceProductionBonus,
|
||||
darkMatterProductionBonus: bonuses.darkMatterProductionBonus,
|
||||
energyProductionBonus: bonuses.energyProductionBonus
|
||||
})
|
||||
const production = calculateResourceProduction(
|
||||
planet,
|
||||
{
|
||||
resourceProductionBonus: bonuses.resourceProductionBonus,
|
||||
darkMatterProductionBonus: bonuses.darkMatterProductionBonus,
|
||||
energyProductionBonus: bonuses.energyProductionBonus
|
||||
},
|
||||
techBonuses
|
||||
)
|
||||
|
||||
// 计算实际产出量(用于消耗矿脉储量)
|
||||
const metalProduced = (production.metal * effectiveTimeDiff) / 3600
|
||||
@@ -232,10 +293,11 @@ export const updatePlanetResources = (
|
||||
oreDepositLogic.consumeDeposit(planet.oreDeposits, 'deuterium', deuteriumProduced)
|
||||
|
||||
// 矿脉缓慢恢复(每次更新时恢复一小部分)
|
||||
// 地质研究站等级影响恢复速度
|
||||
// 地质研究站等级影响恢复速度,深层钻探设施和采矿技术影响恢复上限
|
||||
const hoursElapsed = effectiveTimeDiff / 3600
|
||||
const geoStationLevel = planet.buildings[BuildingType.GeoResearchStation] || 0
|
||||
oreDepositLogic.regenerateDeposits(planet.oreDeposits, hoursElapsed, geoStationLevel)
|
||||
const deepDrillingLevel = planet.buildings[BuildingType.DeepDrillingFacility] || 0
|
||||
oreDepositLogic.regenerateDeposits(planet.oreDeposits, hoursElapsed, geoStationLevel, deepDrillingLevel, miningTechLevel)
|
||||
}
|
||||
|
||||
// 更新资源(转换为每秒产量,应用游戏速度)
|
||||
@@ -386,12 +448,22 @@ export interface ConsumptionDetail {
|
||||
|
||||
/**
|
||||
* 计算资源产量详细breakdown
|
||||
* @param planet 星球
|
||||
* @param officers 军官
|
||||
* @param currentTime 当前时间
|
||||
* @param resourceSpeed 游戏速度
|
||||
* @param techBonuses 科技加成(可选,矿物研究/晶体研究/燃料研究)
|
||||
*/
|
||||
export const calculateProductionBreakdown = (
|
||||
planet: Planet,
|
||||
officers: Record<OfficerType, Officer>,
|
||||
currentTime: number,
|
||||
resourceSpeed: number = 1
|
||||
resourceSpeed: number = 1,
|
||||
techBonuses?: {
|
||||
mineralResearchLevel?: number
|
||||
crystalResearchLevel?: number
|
||||
fuelResearchLevel?: number
|
||||
}
|
||||
): ProductionBreakdown => {
|
||||
const metalMineLevel = planet.buildings[BuildingType.MetalMine] || 0
|
||||
const crystalMineLevel = planet.buildings[BuildingType.CrystalMine] || 0
|
||||
@@ -432,6 +504,13 @@ export const calculateProductionBreakdown = (
|
||||
const totalDarkMatterBonus = activeOfficerBonuses.reduce((sum, officer) => sum + officer.darkMatterBonus, 0)
|
||||
const totalEnergyBonus = activeOfficerBonuses.reduce((sum, officer) => sum + officer.energyBonus, 0)
|
||||
|
||||
// 计算科技加成
|
||||
const researchBonus = calculateResearchProductionBonus(
|
||||
techBonuses?.mineralResearchLevel || 0,
|
||||
techBonuses?.crystalResearchLevel || 0,
|
||||
techBonuses?.fuelResearchLevel || 0
|
||||
)
|
||||
|
||||
// 金属矿产量
|
||||
const metalBase = metalMineLevel * 1500 * Math.pow(1.5, metalMineLevel)
|
||||
const metalBonuses: ProductionBonus[] = []
|
||||
@@ -449,16 +528,27 @@ export const calculateProductionBreakdown = (
|
||||
}
|
||||
})
|
||||
|
||||
// 添加矿物研究科技加成
|
||||
if (researchBonus.metalBonus > 0) {
|
||||
const techBonusValue = metalBase * (1 + totalResourceBonus / 100) * (researchBonus.metalBonus / 100)
|
||||
metalBonuses.push({
|
||||
name: 'research.mineralResearch',
|
||||
percentage: researchBonus.metalBonus,
|
||||
value: techBonusValue,
|
||||
source: 'technology'
|
||||
})
|
||||
}
|
||||
|
||||
if (!hasPositiveEnergyBalance) {
|
||||
metalBonuses.push({
|
||||
name: 'resources.noEnergy',
|
||||
percentage: -100,
|
||||
value: -metalBase * (1 + totalResourceBonus / 100),
|
||||
value: -metalBase * (1 + totalResourceBonus / 100) * (1 + researchBonus.metalBonus / 100),
|
||||
source: 'other'
|
||||
})
|
||||
}
|
||||
|
||||
const metalFinal = metalBase * (1 + totalResourceBonus / 100) * productionEfficiency
|
||||
const metalFinal = metalBase * (1 + totalResourceBonus / 100) * (1 + researchBonus.metalBonus / 100) * productionEfficiency
|
||||
|
||||
// 晶体矿产量
|
||||
const crystalBase = crystalMineLevel * 1000 * Math.pow(1.5, crystalMineLevel)
|
||||
@@ -476,16 +566,27 @@ export const calculateProductionBreakdown = (
|
||||
}
|
||||
})
|
||||
|
||||
// 添加晶体研究科技加成
|
||||
if (researchBonus.crystalBonus > 0) {
|
||||
const techBonusValue = crystalBase * (1 + totalResourceBonus / 100) * (researchBonus.crystalBonus / 100)
|
||||
crystalBonuses.push({
|
||||
name: 'research.crystalResearch',
|
||||
percentage: researchBonus.crystalBonus,
|
||||
value: techBonusValue,
|
||||
source: 'technology'
|
||||
})
|
||||
}
|
||||
|
||||
if (!hasPositiveEnergyBalance) {
|
||||
crystalBonuses.push({
|
||||
name: 'resources.noEnergy',
|
||||
percentage: -100,
|
||||
value: -crystalBase * (1 + totalResourceBonus / 100),
|
||||
value: -crystalBase * (1 + totalResourceBonus / 100) * (1 + researchBonus.crystalBonus / 100),
|
||||
source: 'other'
|
||||
})
|
||||
}
|
||||
|
||||
const crystalFinal = crystalBase * (1 + totalResourceBonus / 100) * productionEfficiency
|
||||
const crystalFinal = crystalBase * (1 + totalResourceBonus / 100) * (1 + researchBonus.crystalBonus / 100) * productionEfficiency
|
||||
|
||||
// 重氢合成器产量(受温度影响)
|
||||
// OGame 原版规则:温度越低,重氢产量越高
|
||||
@@ -518,16 +619,27 @@ export const calculateProductionBreakdown = (
|
||||
}
|
||||
})
|
||||
|
||||
// 添加燃料研究科技加成
|
||||
if (researchBonus.deuteriumBonus > 0) {
|
||||
const techBonusValue = deuteriumBase * (1 + totalResourceBonus / 100) * (researchBonus.deuteriumBonus / 100)
|
||||
deuteriumBonuses.push({
|
||||
name: 'research.fuelResearch',
|
||||
percentage: researchBonus.deuteriumBonus,
|
||||
value: techBonusValue,
|
||||
source: 'technology'
|
||||
})
|
||||
}
|
||||
|
||||
if (!hasPositiveEnergyBalance) {
|
||||
deuteriumBonuses.push({
|
||||
name: 'resources.noEnergy',
|
||||
percentage: -100,
|
||||
value: -deuteriumBase * (1 + totalResourceBonus / 100),
|
||||
value: -deuteriumBase * (1 + totalResourceBonus / 100) * (1 + researchBonus.deuteriumBonus / 100),
|
||||
source: 'other'
|
||||
})
|
||||
}
|
||||
|
||||
const deuteriumFinal = deuteriumBase * (1 + totalResourceBonus / 100) * productionEfficiency
|
||||
const deuteriumFinal = deuteriumBase * (1 + totalResourceBonus / 100) * (1 + researchBonus.deuteriumBonus / 100) * productionEfficiency
|
||||
|
||||
// 暗物质收集器产量
|
||||
const darkMatterBase = darkMatterCollectorLevel * 25 * Math.pow(1.5, darkMatterCollectorLevel)
|
||||
|
||||
@@ -322,3 +322,49 @@ export const addFleet = (currentFleet: Fleet, fleet: Partial<Fleet>): void => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算舰船拆除返还资源
|
||||
* 返还50%的建造成本
|
||||
*/
|
||||
export const calculateShipScrapRefund = (shipType: ShipType, quantity: number): Resources => {
|
||||
const cost = calculateShipCost(shipType, quantity)
|
||||
return {
|
||||
metal: Math.floor(cost.metal * 0.5),
|
||||
crystal: Math.floor(cost.crystal * 0.5),
|
||||
deuterium: Math.floor(cost.deuterium * 0.5),
|
||||
darkMatter: Math.floor(cost.darkMatter * 0.5),
|
||||
energy: 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算舰船拆除时间
|
||||
* 拆除时间为建造时间的50%
|
||||
*/
|
||||
export const calculateShipScrapTime = (
|
||||
shipType: ShipType,
|
||||
quantity: number,
|
||||
buildingSpeedBonus: number = 0,
|
||||
roboticsFactoryLevel: number = 0,
|
||||
naniteFactoryLevel: number = 0
|
||||
): number => {
|
||||
const buildTime = calculateShipBuildTime(shipType, quantity, buildingSpeedBonus, roboticsFactoryLevel, naniteFactoryLevel)
|
||||
return Math.floor(buildTime * 0.5)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建舰船拆除队列项
|
||||
*/
|
||||
export const createShipScrapQueueItem = (shipType: ShipType, quantity: number, scrapTime: number): BuildQueueItem => {
|
||||
const now = Date.now()
|
||||
shipQueueIdCounter++
|
||||
return {
|
||||
id: `scrap_ship_${now}_${shipQueueIdCounter}`,
|
||||
type: 'scrap_ship',
|
||||
itemType: shipType,
|
||||
quantity,
|
||||
startTime: now,
|
||||
endTime: now + scrapTime * 1000
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,3 +201,66 @@ export const executeFleetDispatch = (
|
||||
resourceLogic.deductResources(planet.resources, cargo)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证舰船拆除的所有条件
|
||||
*/
|
||||
export const validateShipScrap = (
|
||||
planet: Planet,
|
||||
shipType: ShipType,
|
||||
quantity: number
|
||||
): {
|
||||
valid: boolean
|
||||
reason?: string
|
||||
} => {
|
||||
// 检查数量是否有效
|
||||
if (quantity <= 0) {
|
||||
return { valid: false, reason: 'errors.invalidQuantity' }
|
||||
}
|
||||
|
||||
// 检查舰船数量是否足够
|
||||
const available = planet.fleet[shipType] || 0
|
||||
if (available < quantity) {
|
||||
return { valid: false, reason: 'errors.insufficientShips' }
|
||||
}
|
||||
|
||||
return { valid: true }
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行舰船拆除
|
||||
*/
|
||||
export const executeShipScrap = (
|
||||
planet: Planet,
|
||||
shipType: ShipType,
|
||||
quantity: number,
|
||||
officers: Record<OfficerType, Officer>
|
||||
): BuildQueueItem => {
|
||||
// 计算军官加成
|
||||
const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now())
|
||||
|
||||
// 获取机器人工厂和纳米工厂等级
|
||||
const roboticsFactoryLevel = planet.buildings[BuildingType.RoboticsFactory] || 0
|
||||
const naniteFactoryLevel = planet.buildings[BuildingType.NaniteFactory] || 0
|
||||
|
||||
// 计算拆除时间
|
||||
const scrapTime = shipLogic.calculateShipScrapTime(
|
||||
shipType,
|
||||
quantity,
|
||||
bonuses.buildingSpeedBonus,
|
||||
roboticsFactoryLevel,
|
||||
naniteFactoryLevel
|
||||
)
|
||||
|
||||
// 计算返还资源
|
||||
const refund = shipLogic.calculateShipScrapRefund(shipType, quantity)
|
||||
|
||||
// 扣除舰船(立即扣除,避免拆除过程中派遣)
|
||||
planet.fleet[shipType] = (planet.fleet[shipType] || 0) - quantity
|
||||
|
||||
// 返还资源
|
||||
resourceLogic.addResources(planet.resources, refund)
|
||||
|
||||
// 创建队列项
|
||||
return shipLogic.createShipScrapQueueItem(shipType, quantity, scrapTime)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ export const useGameStore = defineStore('game', {
|
||||
gameTime: Date.now(),
|
||||
isPaused: false,
|
||||
gameSpeed: 1,
|
||||
battleToFinish: true, // 战斗到底模式:false=经典模式(6回合平局),true=战斗到底(最多100回合)
|
||||
player: {
|
||||
id: 'player1',
|
||||
name: '',
|
||||
|
||||
@@ -160,12 +160,12 @@
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
transform: translate3d(0, 10px, 0);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ aside nav a {
|
||||
}
|
||||
|
||||
aside nav a:hover button {
|
||||
transform: translateX(4px);
|
||||
transform: translate3d(4px, 0, 0);
|
||||
}
|
||||
|
||||
/* 资源数字更新动画 */
|
||||
|
||||
@@ -50,7 +50,9 @@ export const BuildingType = {
|
||||
// 特殊建筑
|
||||
PlanetDestroyerFactory: 'planetDestroyerFactory', // 行星毁灭者工厂
|
||||
GeoResearchStation: 'geoResearchStation', // 地质研究站(影响矿脉恢复速度)
|
||||
DeepDrillingFacility: 'deepDrillingFacility' // 深层钻探设施(提升矿脉上限)
|
||||
DeepDrillingFacility: 'deepDrillingFacility', // 深层钻探设施(提升矿脉上限)
|
||||
// 2moons新增建筑
|
||||
University: 'university' // 大学(加速研究)
|
||||
} as const
|
||||
|
||||
export type BuildingType = (typeof BuildingType)[keyof typeof BuildingType]
|
||||
@@ -98,7 +100,12 @@ export const TechnologyType = {
|
||||
DarkMatterTechnology: 'darkMatterTechnology', // 暗物质技术
|
||||
TerraformingTechnology: 'terraformingTechnology', // 地形改造技术
|
||||
PlanetDestructionTech: 'planetDestructionTech', // 行星毁灭技术
|
||||
MiningTechnology: 'miningTechnology' // 采矿技术(提升矿脉上限)
|
||||
MiningTechnology: 'miningTechnology', // 采矿技术(提升矿脉上限)
|
||||
// 2moons新增科技
|
||||
IntergalacticResearchNetwork: 'intergalacticResearchNetwork', // 星际研究网络(连接多个研究实验室)
|
||||
MineralResearch: 'mineralResearch', // 矿物研究(提升金属产量)
|
||||
CrystalResearch: 'crystalResearch', // 晶体研究(提升晶体产量)
|
||||
FuelResearch: 'fuelResearch' // 燃料研究(提升重氢产量)
|
||||
} as const
|
||||
|
||||
export type TechnologyType = (typeof TechnologyType)[keyof typeof TechnologyType]
|
||||
@@ -496,6 +503,8 @@ export interface MissionReport {
|
||||
// 毁灭任务:概率和死星损失
|
||||
destructionChance?: number
|
||||
deathstarsLost?: boolean
|
||||
// 毁灭任务:是否发生了战斗
|
||||
hadBattle?: boolean
|
||||
// 部署任务:部署的舰队
|
||||
deployedFleet?: Partial<Fleet>
|
||||
// 导弹攻击任务:导弹信息
|
||||
@@ -656,7 +665,7 @@ export interface DebrisField {
|
||||
// 建造队列项
|
||||
export interface BuildQueueItem {
|
||||
id: string
|
||||
type: 'building' | 'technology' | 'ship' | 'defense' | 'demolish'
|
||||
type: 'building' | 'technology' | 'ship' | 'defense' | 'demolish' | 'scrap_ship'
|
||||
itemType: BuildingType | TechnologyType | ShipType | DefenseType
|
||||
targetLevel?: number // 用于建筑和科技
|
||||
quantity?: number // 用于舰船和防御
|
||||
@@ -667,7 +676,7 @@ export interface BuildQueueItem {
|
||||
// 等待队列项(尚未开始执行,不需要 startTime/endTime)
|
||||
export interface WaitingQueueItem {
|
||||
id: string
|
||||
type: 'building' | 'technology' | 'ship' | 'defense' | 'demolish'
|
||||
type: 'building' | 'technology' | 'ship' | 'defense' | 'demolish' | 'scrap_ship'
|
||||
itemType: BuildingType | TechnologyType | ShipType | DefenseType
|
||||
targetLevel?: number // 用于建筑和科技
|
||||
quantity?: number // 用于舰船和防御
|
||||
|
||||
@@ -109,7 +109,10 @@ const COMBAT_EFFECTS = {
|
||||
* 计算一个单位对另一个单位造成的伤害
|
||||
* 增强版:包含护盾弹回、重型武器穿透、装甲损坏累积
|
||||
*/
|
||||
const calculateDamage = (attacker: CombatUnit, defender: CombatUnit): { destroyed: number; damagedShield: number; armorDamageDealt: number } => {
|
||||
const calculateDamage = (
|
||||
attacker: CombatUnit,
|
||||
defender: CombatUnit
|
||||
): { destroyed: number; damagedShield: number; armorDamageDealt: number } => {
|
||||
const attackPower = attacker.attack
|
||||
// 使用当前护盾值(如果有),否则使用最大护盾
|
||||
const defenderCurrentShield = defender.currentShield ?? defender.shield
|
||||
@@ -157,14 +160,8 @@ const calculateDamage = (attacker: CombatUnit, defender: CombatUnit): { destroye
|
||||
|
||||
// 穿透护盾后对装甲造成损坏累积
|
||||
if (remainingDamage > 0) {
|
||||
armorDamageDealt = Math.min(
|
||||
COMBAT_EFFECTS.ARMOR_DAMAGE_RATE,
|
||||
COMBAT_EFFECTS.MAX_ARMOR_DAMAGE - (defender.armorDamage ?? 0)
|
||||
)
|
||||
defender.armorDamage = Math.min(
|
||||
COMBAT_EFFECTS.MAX_ARMOR_DAMAGE,
|
||||
(defender.armorDamage ?? 0) + armorDamageDealt
|
||||
)
|
||||
armorDamageDealt = Math.min(COMBAT_EFFECTS.ARMOR_DAMAGE_RATE, COMBAT_EFFECTS.MAX_ARMOR_DAMAGE - (defender.armorDamage ?? 0))
|
||||
defender.armorDamage = Math.min(COMBAT_EFFECTS.MAX_ARMOR_DAMAGE, (defender.armorDamage ?? 0) + armorDamageDealt)
|
||||
}
|
||||
|
||||
// 再消耗装甲
|
||||
@@ -453,8 +450,24 @@ export const simulateBattle = (
|
||||
} else if (defenderUnits.length === 0) {
|
||||
winner = 'attacker'
|
||||
} else {
|
||||
// OGame原版规则:6回合后双方都有剩余单位时判定为平局
|
||||
winner = 'draw'
|
||||
// 达到最大回合数后双方都有剩余单位
|
||||
// 如果是战斗到底模式(maxRounds > 6),根据剩余战力判定胜负
|
||||
if (maxRounds > 6) {
|
||||
// 计算剩余战力
|
||||
const attackerPower = attackerUnits.reduce((sum, u) => sum + u.count * u.armor, 0)
|
||||
const defenderPower = defenderUnits.reduce((sum, u) => sum + u.count * u.armor, 0)
|
||||
// 战力差距超过20%判定胜负,否则平局
|
||||
if (attackerPower > defenderPower * 1.2) {
|
||||
winner = 'attacker'
|
||||
} else if (defenderPower > attackerPower * 1.2) {
|
||||
winner = 'defender'
|
||||
} else {
|
||||
winner = 'draw'
|
||||
}
|
||||
} else {
|
||||
// OGame原版规则:6回合后双方都有剩余单位时判定为平局
|
||||
winner = 'draw'
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -57,9 +57,15 @@
|
||||
<!-- 防守方配置 -->
|
||||
<TabsContent value="defender" class="mt-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>{{ t('simulatorView.defenderConfig') }}</CardTitle>
|
||||
<CardDescription>{{ t('simulatorView.defenderConfigDesc') }}</CardDescription>
|
||||
<CardHeader class="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<div class="space-y-1">
|
||||
<CardTitle>{{ t('simulatorView.defenderConfig') }}</CardTitle>
|
||||
<CardDescription>{{ t('simulatorView.defenderConfigDesc') }}</CardDescription>
|
||||
</div>
|
||||
<Button variant="outline" size="sm" @click="showSpyReportSelector = true" :disabled="!gameStore.player?.spyReports?.length">
|
||||
<FileDown class="h-4 w-4 mr-2" />
|
||||
{{ t('simulatorView.importFromSpyReport') }}
|
||||
</Button>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-4">
|
||||
<!-- 舰队配置 -->
|
||||
@@ -147,28 +153,80 @@
|
||||
|
||||
<!-- 战斗结果对话框 -->
|
||||
<BattleReportDialog v-model:open="showResultDialog" :report="simulationResult" />
|
||||
|
||||
<!-- 侦查报告选择对话框 -->
|
||||
<Dialog v-model:open="showSpyReportSelector">
|
||||
<DialogContent class="max-w-2xl max-h-[80vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{{ t('simulatorView.selectSpyReport') }}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div class="space-y-2">
|
||||
<div v-if="!sortedSpyReports.length" class="text-center py-8 text-muted-foreground">
|
||||
{{ t('simulatorView.noSpyReports') }}
|
||||
</div>
|
||||
<div
|
||||
v-for="report in sortedSpyReports"
|
||||
:key="report.id"
|
||||
@click="importFromSpyReport(report)"
|
||||
class="p-3 border rounded-lg cursor-pointer hover:bg-accent transition-colors"
|
||||
>
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<div class="font-medium">{{ report.targetPlanetName }}</div>
|
||||
<div class="text-sm text-muted-foreground">
|
||||
[{{ report.targetPosition.galaxy }}:{{ report.targetPosition.system }}:{{ report.targetPosition.position }}]
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm text-muted-foreground">
|
||||
{{ formatTime(report.timestamp) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 flex gap-4 text-xs">
|
||||
<span class="flex items-center gap-1">
|
||||
<ResourceIcon type="metal" size="sm" />
|
||||
{{ formatNumber(report.resources.metal) }}
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<ResourceIcon type="crystal" size="sm" />
|
||||
{{ formatNumber(report.resources.crystal) }}
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<ResourceIcon type="deuterium" size="sm" />
|
||||
{{ formatNumber(report.resources.deuterium) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, toRaw } from 'vue'
|
||||
import { ref, toRaw, computed } from 'vue'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { useGameConfig } from '@/composables/useGameConfig'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { ShipType, DefenseType } from '@/types/game'
|
||||
import type { Fleet, BattleResult } from '@/types/game'
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import { ShipType, DefenseType, TechnologyType } from '@/types/game'
|
||||
import type { Fleet, BattleResult, SpyReport } from '@/types/game'
|
||||
import { workerManager } from '@/workers/workerManager'
|
||||
import ResourceIcon from '@/components/common/ResourceIcon.vue'
|
||||
import BattleReportDialog from '@/components/dialogs/BattleReportDialog.vue'
|
||||
import { Sword, Shield, Zap, RotateCcw } from 'lucide-vue-next'
|
||||
import { Sword, Shield, Zap, RotateCcw, FileDown } from 'lucide-vue-next'
|
||||
import * as planetLogic from '@/logic/planetLogic'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { SHIPS, DEFENSES } = useGameConfig()
|
||||
const gameStore = useGameStore()
|
||||
|
||||
// 侦查报告选择对话框状态
|
||||
const showSpyReportSelector = ref(false)
|
||||
|
||||
// 科技类型配置
|
||||
const techTypes = ['weapon', 'shield', 'armor'] as const
|
||||
@@ -249,7 +307,8 @@
|
||||
// 使用 Worker 执行战斗模拟
|
||||
const result = await workerManager.simulateBattle({
|
||||
attacker: attackerSide,
|
||||
defender: defenderSide
|
||||
defender: defenderSide,
|
||||
maxRounds: gameStore.battleToFinish ? 100 : 6
|
||||
})
|
||||
|
||||
// 计算掠夺和残骸场
|
||||
@@ -302,4 +361,65 @@
|
||||
simulationResult.value = null
|
||||
showResultDialog.value = false
|
||||
}
|
||||
|
||||
// 按时间排序的侦查报告
|
||||
const sortedSpyReports = computed(() => {
|
||||
return [...(gameStore.player?.spyReports || [])].sort((a, b) => b.timestamp - a.timestamp)
|
||||
})
|
||||
|
||||
// 格式化时间
|
||||
const formatTime = (timestamp: number) => {
|
||||
return new Date(timestamp).toLocaleString()
|
||||
}
|
||||
|
||||
// 格式化数字
|
||||
const formatNumber = (num: number) => {
|
||||
if (num >= 1e9) return (num / 1e9).toFixed(1) + 'B'
|
||||
if (num >= 1e6) return (num / 1e6).toFixed(1) + 'M'
|
||||
if (num >= 1e3) return (num / 1e3).toFixed(1) + 'K'
|
||||
return num.toString()
|
||||
}
|
||||
|
||||
// 从侦查报告导入数据
|
||||
const importFromSpyReport = (report: SpyReport) => {
|
||||
// 先重置防守方数据
|
||||
defenderFleet.value = initializeFleet()
|
||||
defenderDefense.value = initializeDefense()
|
||||
|
||||
// 填入资源
|
||||
if (report.resources) {
|
||||
defenderResources.value = {
|
||||
metal: report.resources.metal || 0,
|
||||
crystal: report.resources.crystal || 0,
|
||||
deuterium: report.resources.deuterium || 0,
|
||||
darkMatter: report.resources.darkMatter || 0,
|
||||
energy: 0
|
||||
}
|
||||
}
|
||||
|
||||
// 填入舰队
|
||||
if (report.fleet) {
|
||||
Object.entries(report.fleet).forEach(([key, value]) => {
|
||||
defenderFleet.value[key as keyof Fleet] = value || 0
|
||||
})
|
||||
}
|
||||
|
||||
// 填入防御
|
||||
if (report.defense) {
|
||||
Object.entries(report.defense).forEach(([key, value]) => {
|
||||
defenderDefense.value[key as DefenseType] = value || 0
|
||||
})
|
||||
}
|
||||
|
||||
// 填入科技
|
||||
if (report.technologies) {
|
||||
defenderTech.value.weapon = report.technologies[TechnologyType.WeaponsTechnology] || 0
|
||||
defenderTech.value.shield = report.technologies[TechnologyType.ShieldingTechnology] || 0
|
||||
defenderTech.value.armor = report.technologies[TechnologyType.ArmourTechnology] || 0
|
||||
}
|
||||
|
||||
// 关闭对话框并切换到防守方标签
|
||||
showSpyReportSelector.value = false
|
||||
activeTab.value = 'defender'
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
<TabsList :class="['grid', 'w-full', showJumpGateTab ? 'grid-cols-3' : 'grid-cols-2']">
|
||||
<TabsTrigger v-for="tab in visibleTabs" :key="tab.value" :value="tab.value">
|
||||
{{ t(`fleetView.${tab.labelKey}`) }}
|
||||
<Badge v-if="tab.value === 'missions' && gameStore.player.fleetMissions.length > 0" variant="destructive" class="ml-1">
|
||||
{{ gameStore.player.fleetMissions.length }}
|
||||
<Badge v-if="tab.value === 'missions' && totalMissionsCount > 0" variant="destructive" class="ml-1">
|
||||
{{ totalMissionsCount }}
|
||||
</Badge>
|
||||
<Badge v-if="tab.value === 'jumpGate' && jumpGateReady" variant="default" class="ml-1">✓</Badge>
|
||||
</TabsTrigger>
|
||||
@@ -294,13 +294,14 @@
|
||||
|
||||
<!-- 飞行任务 -->
|
||||
<TabsContent value="missions" class="mt-4 space-y-4">
|
||||
<Empty v-if="gameStore.player.fleetMissions.length === 0" class="border rounded-lg">
|
||||
<Empty v-if="totalMissionsCount === 0" class="border rounded-lg">
|
||||
<EmptyContent>
|
||||
<RocketIcon class="h-10 w-10 text-muted-foreground" />
|
||||
<EmptyDescription>{{ t('fleetView.noFlightMissions') }}</EmptyDescription>
|
||||
</EmptyContent>
|
||||
</Empty>
|
||||
|
||||
<!-- 舰队任务 -->
|
||||
<Card v-for="mission in gameStore.player.fleetMissions" :key="mission.id">
|
||||
<CardHeader>
|
||||
<div class="flex justify-between items-start">
|
||||
@@ -378,6 +379,44 @@
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<!-- 导弹攻击任务 -->
|
||||
<Card v-for="missileAttack in flyingMissileAttacks" :key="missileAttack.id">
|
||||
<CardHeader>
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<CardTitle class="text-base sm:text-lg flex items-center gap-2">
|
||||
<Crosshair class="h-4 w-4 text-destructive" />
|
||||
{{ t('galaxyView.missileAttackTitle') }}
|
||||
</CardTitle>
|
||||
<CardDescription class="text-xs sm:text-sm">
|
||||
{{ getPlanetName(missileAttack.originPlanetId) }} → [{{ missileAttack.targetPosition.galaxy }}:{{ missileAttack.targetPosition.system }}:{{
|
||||
missileAttack.targetPosition.position
|
||||
}}]
|
||||
</CardDescription>
|
||||
</div>
|
||||
<Badge variant="destructive">
|
||||
{{ t('fleetView.outbound') }}
|
||||
</Badge>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-3">
|
||||
<!-- 导弹数量 -->
|
||||
<div>
|
||||
<p class="text-xs sm:text-sm font-medium mb-2">{{ t('galaxyView.missileCount') }}:</p>
|
||||
<Badge variant="outline">{{ missileAttack.missileCount }}</Badge>
|
||||
</div>
|
||||
|
||||
<!-- 进度条 -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between text-xs sm:text-sm">
|
||||
<span>{{ t('fleetView.arrivalTime') }}:</span>
|
||||
<span>{{ formatTime(getMissileRemainingTime(missileAttack)) }}</span>
|
||||
</div>
|
||||
<Progress :model-value="getMissileProgress(missileAttack)" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
<!-- 跳跃门 -->
|
||||
@@ -591,7 +630,8 @@
|
||||
Clock,
|
||||
Check,
|
||||
Globe,
|
||||
Moon
|
||||
Moon,
|
||||
Crosshair
|
||||
} from 'lucide-vue-next'
|
||||
import { formatNumber, formatTime } from '@/utils/format'
|
||||
import * as shipValidation from '@/logic/shipValidation'
|
||||
@@ -628,6 +668,16 @@
|
||||
return publicLogic.getMaxFleetMissions(bonuses.additionalFleetSlots, computerTechLevel)
|
||||
})
|
||||
|
||||
// 飞行中的导弹攻击
|
||||
const flyingMissileAttacks = computed(() => {
|
||||
return gameStore.player.missileAttacks?.filter(m => m.status === 'flying') || []
|
||||
})
|
||||
|
||||
// 总任务数量(舰队任务 + 导弹攻击)
|
||||
const totalMissionsCount = computed(() => {
|
||||
return gameStore.player.fleetMissions.length + flyingMissileAttacks.value.length
|
||||
})
|
||||
|
||||
const activeTab = ref<'send' | 'missions' | 'jumpGate'>('send')
|
||||
|
||||
// Tab 配置
|
||||
@@ -837,6 +887,8 @@
|
||||
selectedMission.value = MissionType.Attack
|
||||
} else if (mission === 'colonize') {
|
||||
selectedMission.value = MissionType.Colonize
|
||||
} else if (mission === 'recycle') {
|
||||
selectedMission.value = MissionType.Recycle
|
||||
} else if (gift === '1') {
|
||||
// 如果有gift参数,设置为运输任务并启用赠送模式
|
||||
selectedMission.value = MissionType.Transport
|
||||
@@ -1413,4 +1465,18 @@
|
||||
return Math.max(0, Math.min(100, (elapsed / total) * 100))
|
||||
}
|
||||
}
|
||||
|
||||
// 获取导弹任务剩余时间
|
||||
const getMissileRemainingTime = (missileAttack: any): number => {
|
||||
const now = currentTime.value
|
||||
return Math.max(0, (missileAttack.arrivalTime - now) / 1000)
|
||||
}
|
||||
|
||||
// 获取导弹任务进度
|
||||
const getMissileProgress = (missileAttack: any): number => {
|
||||
const now = currentTime.value
|
||||
const total = missileAttack.arrivalTime - missileAttack.launchTime
|
||||
const elapsed = now - missileAttack.launchTime
|
||||
return Math.max(0, Math.min(100, (elapsed / total) * 100))
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
{{ t('galaxyView.myPlanets') }}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-72 p-2" align="start">
|
||||
<PopoverContent class="w-87 p-2 max-h-80 overflow-y-auto" align="start">
|
||||
<div class="space-y-1">
|
||||
<div class="px-2 py-1.5 text-xs font-semibold text-muted-foreground">
|
||||
{{ t('galaxyView.selectPlanetToView') }}
|
||||
@@ -114,7 +114,7 @@
|
||||
{{ highlightedNpc.name }} ({{ highlightedNpc.planets.length }})
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-72 p-2" align="start">
|
||||
<PopoverContent class="w-72 p-2 max-h-96 overflow-y-auto" align="start">
|
||||
<div class="space-y-1">
|
||||
<div class="px-2 py-1.5 text-xs font-semibold text-muted-foreground">
|
||||
{{ t('galaxyView.selectPlanetToView') }}
|
||||
|
||||
@@ -149,11 +149,11 @@
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
transform: translate3d(0, -10px, 0);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -22,8 +22,47 @@
|
||||
<div v-if="planet.isMoon" class="mt-2">
|
||||
<Button @click="switchToParentPlanet" variant="outline" size="sm">{{ t('planet.backToPlanet') }}</Button>
|
||||
</div>
|
||||
<!-- 放弃殖民地按钮 -->
|
||||
<div v-if="canShowAbandonButton" class="mt-4">
|
||||
<Button @click="showAbandonDialog = true" variant="destructive" size="sm">
|
||||
{{ t('planet.abandonColony') }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 放弃殖民地确认对话框 -->
|
||||
<AlertDialog :open="showAbandonDialog" @update:open="showAbandonDialog = $event">
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{{ t('planet.confirmAbandon') }}</AlertDialogTitle>
|
||||
<AlertDialogDescription class="whitespace-pre-line">
|
||||
{{ t('planet.abandonWarning', { name: planet.name }) }}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>{{ t('common.cancel') }}</AlertDialogCancel>
|
||||
<AlertDialogAction @click="handleAbandonColony" class="bg-destructive text-destructive-foreground hover:bg-destructive/90">
|
||||
{{ t('planet.confirmAbandonButton') }}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
<!-- 错误提示对话框 -->
|
||||
<AlertDialog :open="showErrorDialog" @update:open="showErrorDialog = $event">
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{{ t('planet.abandonFailed') }}</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{{ errorMessage }}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogAction>{{ t('common.confirm') }}</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
<!-- 资源管理 -->
|
||||
<Card>
|
||||
<CardHeader>
|
||||
@@ -195,25 +234,45 @@
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { useGameConfig } from '@/composables/useGameConfig'
|
||||
import { computed } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle
|
||||
} from '@/components/ui/alert-dialog'
|
||||
import ResourceIcon from '@/components/common/ResourceIcon.vue'
|
||||
import { formatNumber, getResourceColor } from '@/utils/format'
|
||||
import { scaleNumber } from '@/utils/speed'
|
||||
import type { Planet } from '@/types/game'
|
||||
import { TechnologyType } from '@/types/game'
|
||||
import * as publicLogic from '@/logic/publicLogic'
|
||||
import * as resourceLogic from '@/logic/resourceLogic'
|
||||
import * as planetLogic from '@/logic/planetLogic'
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const { t } = useI18n()
|
||||
const { SHIPS } = useGameConfig()
|
||||
const planet = computed(() => gameStore.currentPlanet)
|
||||
|
||||
// 获取科技加成
|
||||
const techBonuses = computed(() => ({
|
||||
mineralResearchLevel: gameStore.player.technologies[TechnologyType.MineralResearch] || 0,
|
||||
crystalResearchLevel: gameStore.player.technologies[TechnologyType.CrystalResearch] || 0,
|
||||
fuelResearchLevel: gameStore.player.technologies[TechnologyType.FuelResearch] || 0
|
||||
}))
|
||||
|
||||
const production = computed(() =>
|
||||
planet.value ? publicLogic.getResourceProduction(planet.value, gameStore.player.officers, gameStore.gameSpeed) : null
|
||||
planet.value ? publicLogic.getResourceProduction(planet.value, gameStore.player.officers, gameStore.gameSpeed, techBonuses.value) : null
|
||||
)
|
||||
const capacity = computed(() => (planet.value ? publicLogic.getResourceCapacity(planet.value, gameStore.player.officers) : null))
|
||||
|
||||
@@ -226,7 +285,7 @@
|
||||
// 资源产量详细breakdown
|
||||
const productionBreakdown = computed(() => {
|
||||
if (!planet.value) return null
|
||||
return resourceLogic.calculateProductionBreakdown(planet.value, gameStore.player.officers, Date.now(), gameStore.gameSpeed)
|
||||
return resourceLogic.calculateProductionBreakdown(planet.value, gameStore.player.officers, Date.now(), gameStore.gameSpeed, techBonuses.value)
|
||||
})
|
||||
|
||||
// 资源消耗详细breakdown
|
||||
@@ -286,4 +345,45 @@
|
||||
gameStore.currentPlanetId = planet.value.parentPlanetId
|
||||
}
|
||||
}
|
||||
|
||||
// 放弃殖民地相关
|
||||
const showAbandonDialog = ref(false)
|
||||
const showErrorDialog = ref(false)
|
||||
const errorMessage = ref('')
|
||||
|
||||
// 是否显示放弃按钮(非主星才显示)
|
||||
const canShowAbandonButton = computed(() => {
|
||||
if (!planet.value) return false
|
||||
// 找到主星(第一个非月球星球)
|
||||
const mainPlanet = gameStore.player.planets.find(p => !p.isMoon)
|
||||
// 当前星球不是主星时才显示放弃按钮
|
||||
return mainPlanet && mainPlanet.id !== planet.value.id
|
||||
})
|
||||
|
||||
// 处理放弃殖民地
|
||||
const handleAbandonColony = () => {
|
||||
if (!planet.value) return
|
||||
|
||||
const check = planetLogic.canAbandonColony(gameStore.player.planets, planet.value.id)
|
||||
if (!check.canAbandon) {
|
||||
showAbandonDialog.value = false
|
||||
errorMessage.value = check.reason ? t(check.reason) : t('planet.abandonFailed')
|
||||
showErrorDialog.value = true
|
||||
return
|
||||
}
|
||||
|
||||
// 记录当前星球ID用于后续切换
|
||||
const abandonedPlanetId = planet.value.id
|
||||
|
||||
// 执行放弃
|
||||
gameStore.player.planets = planetLogic.abandonColony(gameStore.player.planets, abandonedPlanetId)
|
||||
|
||||
// 切换到主星
|
||||
const mainPlanet = gameStore.player.planets.find(p => !p.isMoon)
|
||||
if (mainPlanet) {
|
||||
gameStore.currentPlanetId = mainPlanet.id
|
||||
}
|
||||
|
||||
showAbandonDialog.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -175,7 +175,8 @@
|
||||
techType,
|
||||
currentLevel,
|
||||
gameStore.player.officers,
|
||||
gameStore.player.technologies
|
||||
gameStore.player.technologies,
|
||||
gameStore.player.planets
|
||||
)
|
||||
gameStore.player.researchQueue.push(queueItem)
|
||||
return true
|
||||
@@ -333,11 +334,33 @@
|
||||
const getResearchTime = (techType: TechnologyType): number => {
|
||||
if (!planet.value) return 0
|
||||
const currentLevel = getTechLevel(techType)
|
||||
const researchLabLevel = planet.value.buildings['researchLab'] || 0
|
||||
const intergalacticResearchNetworkLevel = player.value.technologies[TechnologyType.IntergalacticResearchNetwork] || 0
|
||||
|
||||
// 计算有效研究实验室等级(考虑星际研究网络)
|
||||
let researchLabLevel: number
|
||||
if (intergalacticResearchNetworkLevel > 0) {
|
||||
researchLabLevel = researchLogic.calculateEffectiveLabLevel(
|
||||
gameStore.player.planets,
|
||||
planet.value.id,
|
||||
intergalacticResearchNetworkLevel
|
||||
)
|
||||
} else {
|
||||
researchLabLevel = planet.value.buildings['researchLab'] || 0
|
||||
}
|
||||
|
||||
const energyTechLevel = player.value.technologies['energyTechnology'] || 0
|
||||
const universityLevel = planet.value.buildings['university'] || 0
|
||||
const bonuses = officerLogic.calculateActiveBonuses(player.value.officers, gameStore.gameTime)
|
||||
|
||||
return researchLogic.calculateTechnologyTime(techType, currentLevel, bonuses.researchSpeedBonus, researchLabLevel, energyTechLevel)
|
||||
return researchLogic.calculateTechnologyTime(
|
||||
techType,
|
||||
currentLevel,
|
||||
bonuses.researchSpeedBonus,
|
||||
researchLabLevel,
|
||||
energyTechLevel,
|
||||
1,
|
||||
universityLevel
|
||||
)
|
||||
}
|
||||
|
||||
// 检查是否可以添加到等待队列
|
||||
|
||||
@@ -114,6 +114,15 @@
|
||||
{{ gameStore.isPaused ? t('settings.resume') : t('settings.pause') }}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<!-- 战斗模式 -->
|
||||
<div class="flex items-center justify-between p-4 border rounded-lg">
|
||||
<div class="space-y-1">
|
||||
<h3 class="font-medium">{{ t('settings.battleMode') }}</h3>
|
||||
<p class="text-sm text-muted-foreground">{{ t('settings.battleModeDesc') }}</p>
|
||||
</div>
|
||||
<Switch :checked="gameStore.battleToFinish" @update:checked="(val: boolean) => (gameStore.battleToFinish = val)" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -581,12 +590,22 @@
|
||||
const fileName = `${pkg.name}-${new Date().toISOString().slice(0, 10)}-${Date.now()}.json`
|
||||
const jsonString = JSON.stringify(exportData, null, 2)
|
||||
|
||||
// Android 保存到 Documents 目录
|
||||
// Android 保存到公共 Downloads 目录
|
||||
if (Capacitor.isNativePlatform()) {
|
||||
// 检查并请求存储权限
|
||||
const permStatus = await Filesystem.checkPermissions()
|
||||
if (permStatus.publicStorage !== 'granted') {
|
||||
const reqResult = await Filesystem.requestPermissions()
|
||||
if (reqResult.publicStorage !== 'granted') {
|
||||
toast.error(t('settings.storagePermissionDenied'))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const result = await Filesystem.writeFile({
|
||||
path: fileName,
|
||||
path: `Download/${fileName}`,
|
||||
data: jsonString,
|
||||
directory: Directory.Documents,
|
||||
directory: Directory.ExternalStorage,
|
||||
encoding: Encoding.UTF8
|
||||
})
|
||||
toast.success(t('settings.exportSuccessWithPath', { path: result.uri }))
|
||||
|
||||
@@ -101,6 +101,20 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 拆除数量输入 -->
|
||||
<div v-if="(planet.fleet[shipType] || 0) > 0" class="space-y-2">
|
||||
<Label :for="`scrap-quantity-${shipType}`" class="text-xs sm:text-sm text-destructive">{{ t('shipyardView.scrapQuantity') }}</Label>
|
||||
<Input
|
||||
:id="`scrap-quantity-${shipType}`"
|
||||
v-model.number="scrapQuantities[shipType]"
|
||||
type="number"
|
||||
min="0"
|
||||
:max="planet.fleet[shipType] || 0"
|
||||
placeholder="0"
|
||||
class="text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="quantities[shipType] > 0" class="text-xs sm:text-sm space-y-1.5 sm:space-y-2 p-2.5 sm:p-3 bg-muted rounded-lg">
|
||||
<p class="font-medium text-muted-foreground">{{ t('shipyardView.totalCost') }}:</p>
|
||||
<div class="space-y-1 sm:space-y-1.5">
|
||||
@@ -133,6 +147,36 @@
|
||||
>
|
||||
{{ t('queue.addToWaiting') }}
|
||||
</Button>
|
||||
|
||||
<!-- 拆除返还资源显示 -->
|
||||
<div v-if="scrapQuantities[shipType] > 0" class="text-xs sm:text-sm space-y-1.5 sm:space-y-2 p-2.5 sm:p-3 bg-destructive/10 rounded-lg border border-destructive/30">
|
||||
<p class="font-medium text-destructive">{{ t('shipyardView.scrapRefund') }}:</p>
|
||||
<div class="space-y-1 sm:space-y-1.5">
|
||||
<div
|
||||
v-for="resourceType in costResourceTypes"
|
||||
:key="resourceType.key"
|
||||
v-show="resourceType.key !== 'darkMatter' || getScrapRefund(shipType).darkMatter > 0"
|
||||
class="flex items-center gap-1.5 sm:gap-2"
|
||||
>
|
||||
<ResourceIcon :type="resourceType.key" size="sm" />
|
||||
<span class="text-xs">{{ t(`resources.${resourceType.key}`) }}:</span>
|
||||
<span class="font-medium text-xs sm:text-sm text-green-500">
|
||||
+{{ formatNumber(getScrapRefund(shipType)[resourceType.key]) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 拆除按钮 -->
|
||||
<Button
|
||||
v-if="(planet.fleet[shipType] || 0) > 0"
|
||||
@click="handleScrap(shipType, $event)"
|
||||
:disabled="!canScrap(shipType)"
|
||||
variant="destructive"
|
||||
class="w-full"
|
||||
>
|
||||
{{ t('shipyardView.scrap') }}
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -243,6 +287,25 @@
|
||||
[ShipType.Deathstar]: 0
|
||||
})
|
||||
|
||||
// 每种舰船的拆除数量
|
||||
const scrapQuantities = ref<Record<ShipType, number>>({
|
||||
[ShipType.LightFighter]: 0,
|
||||
[ShipType.HeavyFighter]: 0,
|
||||
[ShipType.Cruiser]: 0,
|
||||
[ShipType.Battleship]: 0,
|
||||
[ShipType.Battlecruiser]: 0,
|
||||
[ShipType.Bomber]: 0,
|
||||
[ShipType.Destroyer]: 0,
|
||||
[ShipType.SmallCargo]: 0,
|
||||
[ShipType.LargeCargo]: 0,
|
||||
[ShipType.ColonyShip]: 0,
|
||||
[ShipType.Recycler]: 0,
|
||||
[ShipType.EspionageProbe]: 0,
|
||||
[ShipType.SolarSatellite]: 0,
|
||||
[ShipType.DarkMatterHarvester]: 0,
|
||||
[ShipType.Deathstar]: 0
|
||||
})
|
||||
|
||||
const buildShip = (shipType: ShipType, quantity: number): { success: boolean; reason?: string } => {
|
||||
if (!gameStore.currentPlanet) return { success: false }
|
||||
const validation = shipValidation.validateShipBuild(gameStore.currentPlanet, shipType, quantity, gameStore.player.technologies)
|
||||
@@ -380,4 +443,54 @@
|
||||
waitingQueueLogic.addToBuildWaitingQueue(planet.value, item)
|
||||
quantities.value[shipType] = 0
|
||||
}
|
||||
|
||||
// 计算拆除返还资源
|
||||
const getScrapRefund = (shipType: ShipType) => {
|
||||
const quantity = scrapQuantities.value[shipType]
|
||||
return shipLogic.calculateShipScrapRefund(shipType, quantity)
|
||||
}
|
||||
|
||||
// 检查是否可以拆除
|
||||
const canScrap = (shipType: ShipType): boolean => {
|
||||
if (!planet.value) return false
|
||||
|
||||
const quantity = scrapQuantities.value[shipType]
|
||||
if (quantity <= 0) return false
|
||||
|
||||
const available = planet.value.fleet[shipType] || 0
|
||||
return available >= quantity
|
||||
}
|
||||
|
||||
// 拆除舰船
|
||||
const handleScrap = (shipType: ShipType, _event: MouseEvent) => {
|
||||
// 防抖:防止快速点击
|
||||
if (isProcessing.value) return
|
||||
isProcessing.value = true
|
||||
setTimeout(() => {
|
||||
isProcessing.value = false
|
||||
}, DEBOUNCE_DELAY)
|
||||
|
||||
const quantity = scrapQuantities.value[shipType]
|
||||
if (quantity <= 0) {
|
||||
alertDialogTitle.value = t('shipyardView.inputError')
|
||||
alertDialogMessage.value = t('shipyardView.inputErrorMessage')
|
||||
alertDialogOpen.value = true
|
||||
return
|
||||
}
|
||||
|
||||
if (!gameStore.currentPlanet) return
|
||||
|
||||
const validation = shipValidation.validateShipScrap(gameStore.currentPlanet, shipType, quantity)
|
||||
if (!validation.valid) {
|
||||
alertDialogTitle.value = t('shipyardView.scrapFailed')
|
||||
alertDialogMessage.value = validation.reason ? t(validation.reason) : t('shipyardView.scrapFailedMessage')
|
||||
alertDialogOpen.value = true
|
||||
return
|
||||
}
|
||||
|
||||
// 执行拆除
|
||||
const queueItem = shipValidation.executeShipScrap(gameStore.currentPlanet, shipType, quantity, gameStore.player.officers)
|
||||
gameStore.currentPlanet.buildQueue.push(queueItem)
|
||||
scrapQuantities.value[shipType] = 0
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -304,8 +304,24 @@ const simulateBattle = (attacker: BattleSideData, defender: BattleSideData, maxR
|
||||
} else if (defenderUnits.length === 0) {
|
||||
winner = 'attacker'
|
||||
} else {
|
||||
// OGame原版规则:6回合后双方都有剩余单位时判定为平局
|
||||
winner = 'draw'
|
||||
// 达到最大回合数后双方都有剩余单位
|
||||
// 如果是战斗到底模式(maxRounds > 6),根据剩余战力判定胜负
|
||||
if (maxRounds > 6) {
|
||||
// 计算剩余战力
|
||||
const attackerPower = attackerUnits.reduce((sum, u) => sum + u.count * u.armor, 0)
|
||||
const defenderPower = defenderUnits.reduce((sum, u) => sum + u.count * u.armor, 0)
|
||||
// 战力差距超过20%判定胜负,否则平局
|
||||
if (attackerPower > defenderPower * 1.2) {
|
||||
winner = 'attacker'
|
||||
} else if (defenderPower > attackerPower * 1.2) {
|
||||
winner = 'defender'
|
||||
} else {
|
||||
winner = 'draw'
|
||||
}
|
||||
} else {
|
||||
// OGame原版规则:6回合后双方都有剩余单位时判定为平局
|
||||
winner = 'draw'
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -23,14 +23,7 @@ export default defineConfig(async () => {
|
||||
background_color: '#000000',
|
||||
display: 'fullscreen',
|
||||
orientation: 'any',
|
||||
icons: [
|
||||
{
|
||||
src: 'logo.svg',
|
||||
sizes: 'any',
|
||||
type: 'image/svg+xml',
|
||||
purpose: 'any'
|
||||
}
|
||||
]
|
||||
icons: [{ src: 'logo.svg', sizes: 'any', type: 'image/svg+xml', purpose: 'any' }]
|
||||
},
|
||||
workbox: {
|
||||
globPatterns: ['**/*.{js,css,html,ico,png,svg,mp3,wav,json}'],
|
||||
@@ -39,13 +32,7 @@ export default defineConfig(async () => {
|
||||
{
|
||||
urlPattern: ({ request }) => request.destination === 'image' || request.destination === 'audio',
|
||||
handler: 'CacheFirst', // 优先使用缓存
|
||||
options: {
|
||||
cacheName: 'game-assets',
|
||||
expiration: {
|
||||
maxEntries: 100,
|
||||
maxAgeSeconds: 30 * 24 * 60 * 60 // 缓存 30 天
|
||||
}
|
||||
}
|
||||
options: { cacheName: 'game-assets', expiration: { maxEntries: 100, maxAgeSeconds: 30 * 24 * 60 * 60 } }
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -113,16 +100,14 @@ export default defineConfig(async () => {
|
||||
// 使用 lightningcss 处理 CSS,自动转换 oklch 等新语法为兼容格式
|
||||
transformer: 'lightningcss',
|
||||
lightningcss: {
|
||||
// 目标浏览器:Android 5+, iOS 10+, Chrome 60+
|
||||
// 目标浏览器:降低到更保守的版本以支持华为等国产手机 WebView
|
||||
targets: {
|
||||
android: 5 << 16, // Android 5.0
|
||||
chrome: 60 << 16, // Chrome 60
|
||||
ios_saf: 10 << 16 // iOS Safari 10
|
||||
android: (4 << 16) | (4 << 8), // Android 4.4
|
||||
chrome: 49 << 16, // Chrome 49 (Android 4.4 WebView)
|
||||
ios_saf: (9 << 16) | (3 << 8) // iOS Safari 9.3
|
||||
},
|
||||
// 禁用现代 CSS 特性,确保兼容旧版浏览器
|
||||
drafts: {
|
||||
customMedia: false
|
||||
}
|
||||
drafts: { customMedia: false }
|
||||
}
|
||||
},
|
||||
// 优化依赖预构建
|
||||
|
||||
28
调整基础矿脉恢复速度.ini
Normal file
28
调整基础矿脉恢复速度.ini
Normal file
@@ -0,0 +1,28 @@
|
||||
OGame-Vue-Ts v1.6.0 更新说明
|
||||
|
||||
调整基础矿脉恢复速度
|
||||
调整地质研究站每级恢复速率
|
||||
调整建造死星所需资源
|
||||
修复研究等待队列资源扣除但等级不增加的问题
|
||||
修复攻击NPC后NPC拥有资源不减少的问题
|
||||
修复导弹攻击后反弹道导弹不减少的问题
|
||||
修复矿脉上限加成计算错误问题
|
||||
为战斗模拟器新增加从侦查报告一键填入的功能
|
||||
调整建筑与研究升级时间
|
||||
修复文本丢失问题
|
||||
调整月球基地初始建造成本
|
||||
修复无法派遣舰队到自己星球位置的问题
|
||||
修复敌对NPC会无脑派遣舰队回收残骸导致产生更多残骸的恶性循环问题
|
||||
修复敌对NPC反复派回收船到玩家星球的问题
|
||||
修复NPC无脑进攻问题
|
||||
修复贸易邮件大量生成导致淹没其他邮件问题
|
||||
添加舰船拆除功能
|
||||
添加放弃殖民地功能
|
||||
修复从月球切换回母星会触发白屏问题
|
||||
修复死星毁灭任务跳过战斗的问题
|
||||
修复对战动画偶现卡顿导致弹窗无响应问题
|
||||
增加战斗到底模式, 开启后支持最多战斗100回合
|
||||
|
||||
添加建筑: 大学
|
||||
添加科技: 星际研究网络, 矿物研究, 晶体研究, 燃料研究
|
||||
|
||||
Reference in New Issue
Block a user