diff --git a/README-DE.md b/README-DE.md new file mode 100644 index 0000000..9999d06 --- /dev/null +++ b/README-DE.md @@ -0,0 +1,184 @@ +
+ OGame Vue TS Logo + + # OGame Vue TS + + Ein modernes Weltraum-Strategiespiel basierend auf dem klassischen OGame, entwickelt mit Vue 3 und TypeScript. + + [![GitHub Release](https://img.shields.io/github/v/release/setube/ogame-vue-ts?style=flat&logo=github&label=Release)](https://github.com/setube/ogame-vue-ts/releases/latest) + [![License: CC BY-NC 4.0](https://img.shields.io/badge/License-CC%20BY--NC%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc/4.0/) + [![Vue 3](https://img.shields.io/badge/Vue-3.5-brightgreen.svg)](https://vuejs.org/) + [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue.svg)](https://www.typescriptlang.org/) + [![Vite](https://img.shields.io/badge/Vite-7.2-646CFF.svg)](https://vitejs.dev/) + [![Go](https://img.shields.io/badge/Go-1.23-79D4FD.svg)](https://golang.org/) + + **Downloads:** + [![Android x86_64](https://img.shields.io/badge/Android-x86__64-3DDC84?logo=android&logoColor=white)](https://github.com/setube/ogame-vue-ts/releases/latest/download/OGame-x86_64.APK) + [![Android arm64](https://img.shields.io/badge/Android-arm64--v8a-3DDC84?logo=android&logoColor=white)](https://github.com/setube/ogame-vue-ts/releases/latest/download/OGame-arm64-v8a.APK) + [![Android armv7](https://img.shields.io/badge/Android-armeabi--v7a-3DDC84?logo=android&logoColor=white)](https://github.com/setube/ogame-vue-ts/releases/latest/download/OGame-armeabi-v7a.APK) + + [![Windows Server](https://img.shields.io/badge/Server-Windows-0078D6?logo=windows&logoColor=white)](https://github.com/setube/ogame-vue-ts/releases/latest/download/ogame-server-win.exe) + [![Linux](https://img.shields.io/badge/Server-Linux%20amd64-FCC624?logo=linux&logoColor=black)](https://github.com/setube/ogame-vue-ts/releases/latest/download/ogame-server-linux) + [![Linux arm64](https://img.shields.io/badge/Server-Linux%20amd64-FCC624?logo=linux&logoColor=black)](https://github.com/setube/ogame-vue-ts/releases/latest/download/ogame-server-linux-arm64) + [![macOS](https://img.shields.io/badge/Server-macOS%20ARM-000000?logo=apple&logoColor=white)](https://github.com/setube/ogame-vue-ts/releases/latest/download/OGame-mac.dmg) + + [![Windows Desktop](https://img.shields.io/badge/Desktop-Windows-0078D6?logo=windows&logoColor=white)](https://github.com/setube/ogame-vue-ts/releases/latest/download/OGame-Setup.exe) + [![Ubuntu Desktop](https://img.shields.io/badge/Desktop-Ubuntu-E95420?logo=ubuntu&logoColor=white)](https://github.com/setube/ogame-vue-ts/releases/latest/download/OGame-linux.AppImage) + [![macOS Desktop](https://img.shields.io/badge/Desktop-macOS-000000?logo=apple&logoColor=white)](https://github.com/setube/ogame-vue-ts/releases/latest/download/OGame-mac.dmg) + + [简体中文](README.md) | [English](README-EN.md) | [繁體中文](README-zh-TW.md) | Deutsch | [Русский](README-RU.md) | [한국어](README-KO.md) + +
+ +## Über das Projekt + +OGame Vue TS ist ein Einzelspieler-Weltraum-Strategiespiel im Browser, inspiriert vom klassischen OGame. Baue dein Imperium in der Galaxie auf, erforsche Technologien, konstruiere Raumschiffe und nimm an epischen Weltraumschlachten teil. Dieses Projekt wurde mit modernen Webtechnologien entwickelt und läuft vollständig im Browser mit lokaler Datenspeicherung. + +## Hauptfunktionen + +- **Mehrsprachige Unterstützung** - Verfügbar in 6 Sprachen: Englisch, Chinesisch (vereinfacht & traditionell), Deutsch, Russisch und Koreanisch +- **Gebäudeverwaltung** - Baue und verbessere verschiedene Gebäude auf Planeten und Monden +- **Technologieforschung** - Schalte fortschrittliche Technologien frei, um dein Imperium zu stärken +- **Flottenverwaltung** - Baue Schiffe, sende Missionen und nimm an taktischen Weltraumkämpfen teil +- **Verteidigungssysteme** - Errichte Verteidigungsanlagen zum Schutz deiner Kolonien +- **Offiziersystem** - Rekrutiere Offiziere für strategische Vorteile +- **Kampfsimulator** - Teste Kampfszenarien, bevor du Ressourcen einsetzt +- **Galaxieansicht** - Erkunde das Universum und interagiere mit anderen Planeten +- **Lokale Datenspeicherung** - Alle Spieldaten werden verschlüsselt im Browser gespeichert +- **Dunkler/Heller Modus** - Wähle dein bevorzugtes visuelles Thema +- **Warteschlangenverwaltung** - Verwalte mehrere Bau- und Forschungswarteschlangen +- **Mondgenerierung** - Wahrscheinlichkeitsbasierte Monderzeugung aus Trümmerfeldern + +## Technologie-Stack + +- **Frontend-Framework:** [Vue 3](https://vuejs.org/) + Composition API (` diff --git a/src/components/campaign/QuestNode.vue b/src/components/campaign/QuestNode.vue new file mode 100644 index 0000000..9ef16b0 --- /dev/null +++ b/src/components/campaign/QuestNode.vue @@ -0,0 +1,195 @@ + + + + + diff --git a/src/components/campaign/StoryDialog.vue b/src/components/campaign/StoryDialog.vue new file mode 100644 index 0000000..fa8bb52 --- /dev/null +++ b/src/components/campaign/StoryDialog.vue @@ -0,0 +1,271 @@ + + + + + diff --git a/src/components/BackToTop.vue b/src/components/common/BackToTop.vue similarity index 100% rename from src/components/BackToTop.vue rename to src/components/common/BackToTop.vue diff --git a/src/components/CardUnlockOverlay.vue b/src/components/common/CardUnlockOverlay.vue similarity index 93% rename from src/components/CardUnlockOverlay.vue rename to src/components/common/CardUnlockOverlay.vue index 883dfe9..92f2cc4 100644 --- a/src/components/CardUnlockOverlay.vue +++ b/src/components/common/CardUnlockOverlay.vue @@ -1,5 +1,9 @@ @@ -662,19 +352,20 @@ import { useGameStore } from '@/stores/gameStore' import { useI18n } from '@/composables/useI18n' import { computed, ref } from 'vue' - import { useRouter } from 'vue-router' 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 { Badge } from '@/components/ui/badge' - import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog' import { FixedPagination } from '@/components/ui/pagination' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' import { Checkbox } from '@/components/ui/checkbox' - import BattleReportDialog from '@/components/BattleReportDialog.vue' - import SpyReportDialog from '@/components/SpyReportDialog.vue' + import BattleReportDialog from '@/components/dialogs/BattleReportDialog.vue' + import SpyReportDialog from '@/components/dialogs/SpyReportDialog.vue' + import SpiedNotificationDialog from '@/components/dialogs/SpiedNotificationDialog.vue' + import MissionReportDialog from '@/components/dialogs/MissionReportDialog.vue' + import NPCActivityDialog from '@/components/dialogs/NPCActivityDialog.vue' import { formatDate } from '@/utils/format' - import { X, Sword, Eye, AlertTriangle, Package, Recycle, Gift, Ban, Check, Users, Skull, Globe, Compass, Trash2 } from 'lucide-vue-next' + import { X, Sword, Eye, AlertTriangle, Package, Recycle, Gift, Ban, Check, Users, Trash2 } from 'lucide-vue-next' import { Empty, EmptyContent, EmptyDescription } from '@/components/ui/empty' import type { BattleResult, @@ -690,7 +381,6 @@ import * as diplomaticLogic from '@/logic/diplomaticLogic' import { toast } from 'vue-sonner' - const router = useRouter() const gameStore = useGameStore() const npcStore = useNPCStore() const { t } = useI18n() @@ -739,13 +429,45 @@ type BasicResourceKey = 'metal' | 'crystal' | 'deuterium' const basicResourceFields: { key: BasicResourceKey }[] = [{ key: 'metal' }, { key: 'crystal' }, { key: 'deuterium' }] - // 残骸资源字段配置(只有金属和晶体) - type DebrisResourceKey = 'metal' | 'crystal' - const debrisResourceFields: { key: DebrisResourceKey }[] = [{ key: 'metal' }, { key: 'crystal' }] + /** + * 获取NPC当前名称 + * 优先使用当前NPC的实际名称,如果NPC不存在则使用通知中保存的旧名称 + * 支持通过ID查找,也支持通过旧名称中的ID模式匹配 + */ + const getNpcName = (npcId: string | undefined, fallbackName: string): string => { + if (!npcStore.npcs?.length) return fallbackName - // 全部资源字段配置(包含暗物质,用于探险任务) - type AllResourceKey = 'metal' | 'crystal' | 'deuterium' | 'darkMatter' - const allResourceFields: { key: AllResourceKey }[] = [{ key: 'metal' }, { key: 'crystal' }, { key: 'deuterium' }, { key: 'darkMatter' }] + // 1. 先通过 npcId 查找 + if (npcId) { + const npc = npcStore.npcs.find(n => n.id === npcId) + if (npc) return npc.name + } + + // 2. 尝试从旧名称中提取ID并查找 + // 旧格式如 "NPC-npc_182",新ID格式为 "npc_182" + const idMatch = fallbackName.match(/npc_\d+/) + if (idMatch) { + const extractedId = idMatch[0] + const npc = npcStore.npcs.find(n => n.id === extractedId) + if (npc) return npc.name + } + + return fallbackName + } + + /** + * 获取侦查报告的目标名称 + * 显示 NPC 名称(如果是 NPC 星球)或星球名称 + */ + const getSpyReportTargetName = (report: SpyReport): string => { + // 尝试通过 targetPlayerId 获取 NPC 名称 + if (report.targetPlayerId && report.targetPlayerId !== 'unknown') { + const npc = npcStore.npcs.find(n => n.id === report.targetPlayerId) + if (npc) return npc.name + } + // 回退到星球名称 + return report.targetPlanetName || report.targetPlanetId + } const hasSelectedAny = computed(() => { return Object.values(clearOptions.value).some(v => v) @@ -1237,58 +959,4 @@ gameStore.player.giftRejectedNotifications.splice(index, 1) } } - - // 查看NPC在星系中的位置 - const viewNPCInGalaxy = (npcId?: string) => { - if (!npcId) return - const npc = npcStore.npcs.find(n => n.id === npcId) - if (!npc || npc.planets.length === 0) return - - const targetPlanet = npc.planets[0] - if (!targetPlanet) return - - showSpiedDialog.value = false - router.push({ - path: '/galaxy', - query: { - galaxy: targetPlanet.position.galaxy, - system: targetPlanet.position.system, - highlightNpc: npcId - } - }) - } - - // 查看位置在星系中 - const viewLocationInGalaxy = (position?: { galaxy: number; system: number; position: number }) => { - if (!position) return - - showNPCActivityDialog.value = false - router.push({ - path: '/galaxy', - query: { - galaxy: position.galaxy, - system: position.system - } - }) - } - - // 获取任务类型图标 - const getMissionIcon = (missionType?: MissionType) => { - if (!missionType) return Package - - switch (missionType) { - case MissionType.Transport: - return Package - case MissionType.Recycle: - return Recycle - case MissionType.Colonize: - return Globe - case MissionType.Expedition: - return Compass - case MissionType.Destroy: - return Skull - default: - return Package - } - } diff --git a/src/views/OfficersView.vue b/src/views/OfficersView.vue index a2bd7e6..617e796 100644 --- a/src/views/OfficersView.vue +++ b/src/views/OfficersView.vue @@ -162,7 +162,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' - import ResourceIcon from '@/components/ResourceIcon.vue' + import ResourceIcon from '@/components/common/ResourceIcon.vue' import { AlertDialog, AlertDialogAction, diff --git a/src/views/OverviewView.vue b/src/views/OverviewView.vue index f6ad777..1cca6d2 100644 --- a/src/views/OverviewView.vue +++ b/src/views/OverviewView.vue @@ -9,6 +9,10 @@

{{ t('planet.position') }}: [{{ planet.position.galaxy }}:{{ planet.position.system }}:{{ planet.position.position }}]

+ +

+ {{ t('planet.temperature') }}: {{ planet.temperature.min }}°C {{ t('common.to') }} {{ planet.temperature.max }}°C +