cyan = Colors::CYAN; $this->white = Colors::WHITE; $this->reset = Colors::RESET; $this->bold = Colors::BOLD; $this->green = Colors::GREEN; $this->yellow = Colors::YELLOW; $this->magenta = Colors::MAGENTA; $this->red = Colors::RED; } public function show() { static $spellsData = null; if ($spellsData === null) { $spellsData = require __DIR__ . '/../../src/Data/spells.php'; } $out = $this->game->output; $in = $this->game->input; $player = $this->game->player; while (true) { // 清屏显示菜单 Screen::clear($out); $out->writeln("{$this->bold}{$this->cyan}=== 法术系统 ==={$this->reset}"); $out->writeln(""); // 显示魔法值状态 $manaPercent = ($player->mana / $player->maxMana) * 100; $manaBar = $this->getManaBar($player->mana, $player->maxMana); $out->writeln("魔法值: {$manaBar} {$player->mana}/{$player->maxMana}"); $out->writeln(""); // 显示已学习的法术 $out->writeln("{$this->bold}{$this->yellow}已学习的法术:{$this->reset}"); if (empty($player->spells)) { $out->writeln(" {$this->white}暂无法术{$this->reset}"); } else { $spellIndex = 0; foreach ($player->spells as $spellId => $spellData) { $spellIndex++; // 获取法术信息 $spellInfo = $this->getSpellInfo($spellId, $spellsData); $level = $spellData['level'] ?? 1; $name = $spellInfo['name'] ?? '未知法术'; $quality = $spellInfo['quality'] ?? 'common'; $qualityColor = $this->getQualityColor($quality); $out->writeln(" [{$spellIndex}] {$qualityColor}{$name}{$this->reset} (Lv.{$level})"); } } $out->writeln(""); // 显示拥有的资源书 $out->writeln("{$this->bold}{$this->magenta}拥有的法术资源书:{$this->reset}"); if (empty($player->spellBooks)) { $out->writeln(" {$this->white}暂无资源书{$this->reset}"); } else { $bookIndex = 0; foreach ($player->spellBooks as $spellId => $count) { $bookIndex++; $spellInfo = $this->getSpellInfo($spellId, $spellsData); $name = $spellInfo['name'] ?? '未知法术'; $quality = $spellInfo['quality'] ?? 'common'; $qualityColor = $this->getQualityColor($quality); $out->writeln(" [{$bookIndex}] {$qualityColor}{$name}的法术书{$this->reset} x{$count}"); } } $out->writeln(""); // 菜单选项 $out->writeln("{$this->bold}选择操作:{$this->reset}"); $out->writeln("[1] 查看法术详情"); $out->writeln("[2] 学习法术"); $out->writeln("[3] 升级法术"); $out->writeln("[0] 返回"); $choice = Input::ask($this->game->output, "请选择: ");; switch ($choice) { case '1': $this->viewSpellDetails($spellsData); break; case '2': $this->learnSpell($spellsData); break; case '3': $this->upgradeSpell($spellsData); break; case '0': $this->game->state = Game::MENU; return; default: $out->writeln("{$this->red}无效选择{$this->reset}"); Screen::delay(500000); } } } /** * 查看法术详情 */ private function viewSpellDetails(array $spellsData) { $out = $this->game->output; $player = $this->game->player; while (true) { Screen::clear($out); $out->writeln("{$this->bold}{$this->cyan}=== 法术详情 ==={$this->reset}"); $out->writeln(""); if (empty($player->spells)) { $out->writeln("{$this->red}还未学习任何法术{$this->reset}"); Screen::delay(1000000); return; } // 列出已学习的法术 $spellArray = []; $spellIndex = 0; foreach ($player->spells as $spellId => $spellData) { $spellIndex++; $spellInfo = $this->getSpellInfo($spellId, $spellsData); $name = $spellInfo['name'] ?? '未知法术'; $quality = $spellInfo['quality'] ?? 'common'; $qualityColor = $this->getQualityColor($quality); $level = $spellData['level'] ?? 1; $out->writeln("[{$spellIndex}] {$qualityColor}{$name}{$this->reset} (Lv.{$level})"); $spellArray[$spellIndex] = ['spellId' => $spellId, 'spellInfo' => $spellInfo]; } $out->writeln("[0] 返回"); $choice = Input::ask($this->game->output, "请选择: ");; if ($choice == '0') { return; } if (isset($spellArray[$choice])) { $selected = $spellArray[$choice]; $this->displaySpellDetail($selected['spellId'], $selected['spellInfo'], $spellsData); } else { $out->writeln("{$this->red}无效选择{$this->reset}"); Screen::delay(500000); } } } /** * 显示单个法术的详细信息 */ private function displaySpellDetail(int $spellId, array $spellInfo, array $spellsData) { $out = $this->game->output; $player = $this->game->player; Screen::clear($out); $out->writeln("{$this->bold}{$this->cyan}=== {$spellInfo['name']} ==={$this->reset}"); $out->writeln(""); $quality = $spellInfo['quality'] ?? 'common'; $qualityColor = $this->getQualityColor($quality); $level = $player->getSpellLevel($spellId); $out->writeln("品质: {$qualityColor}{$this->getQualityName($quality)}{$this->reset}"); $out->writeln("等级: {$this->yellow}Lv.{$level}{$this->reset}"); $out->writeln("描述: {$spellInfo['desc']}"); $out->writeln(""); // 显示法术效果信息 $type = $spellInfo['type'] ?? ''; $baseCost = $spellInfo['cost'] ?? 0; $upgrades = $spellsData['upgrades'] ?? []; $upgradeInfo = $upgrades[$level] ?? []; $costReduction = $upgradeInfo['cost_reduction'] ?? 0; $actualCost = max(1, $baseCost - $costReduction); $out->writeln("{$this->green}基础消耗: {$baseCost} → 当前消耗: {$actualCost}{$this->reset}"); if ($type === 'damage_single') { $damage = $spellInfo['damage'] ?? 1.0; $damageBonus = $upgradeInfo['damage_bonus'] ?? 0; $actualDamage = $damage * (1 + $damageBonus / 100); $out->writeln("伤害倍数: {$this->yellow}" . number_format($damage, 2) . "{$this->reset} → {$this->green}" . number_format($actualDamage, 2) . "x{$this->reset}"); $out->writeln("效果: {$this->magenta}对单个敌人造成魔法伤害{$this->reset}"); } elseif ($type === 'damage_aoe') { $damage = $spellInfo['damage'] ?? 1.0; $damageBonus = $upgradeInfo['damage_bonus'] ?? 0; $actualDamage = $damage * (1 + $damageBonus / 100); $out->writeln("伤害倍数: {$this->yellow}" . number_format($damage, 2) . "{$this->reset} → {$this->green}" . number_format($actualDamage, 2) . "x{$this->reset}"); $out->writeln("效果: {$this->magenta}对所有敌人造成魔法伤害{$this->reset}"); } elseif ($type === 'support') { $subtype = $spellInfo['subtype'] ?? ''; if ($subtype === 'heal' || $subtype === 'heal_all') { $heal = $spellInfo['heal'] ?? 0.5; $healBase = $spellInfo['heal_base'] ?? 20; $out->writeln("恢复效果: {$this->green}魔攻 x {$heal} + {$healBase}{$this->reset}"); $out->writeln("效果: {$this->magenta}恢复生命值{$this->reset}"); } elseif ($subtype === 'defend') { $defenseBoos = $spellInfo['defense_boost'] ?? 0; $out->writeln("防御增加: {$this->green}+{$defenseBoos}{$this->reset}"); $out->writeln("效果: {$this->magenta}增加防御力{$this->reset}"); } } $out->writeln(""); Screen::pause($out); } /** * 学习法术 */ private function learnSpell(array $spellsData) { $out = $this->game->output; $player = $this->game->player; Screen::clear($out); $out->writeln("{$this->bold}{$this->cyan}=== 学习法术 ==={$this->reset}"); $out->writeln(""); // 获取所有可学习的法术(按品质分类) $allSpells = []; foreach ($spellsData as $category => $spells) { if (is_array($spells) && $category !== 'quality_levels' && $category !== 'upgrades') { foreach ($spells as $spellId => $spellInfo) { if (is_numeric($spellId)) { $allSpells[$spellId] = $spellInfo; } } } } // 显示可以学习的法术 $learnableIndex = 0; $learnableSpells = []; foreach ($allSpells as $spellId => $spellInfo) { // 检查是否已学习 if ($player->hasSpell($spellId)) { continue; } // 检查等级要求 $levelReq = $spellInfo['level_req'] ?? 1; if ($player->level < $levelReq) { continue; } // 检查是否有资源书 $bookCount = $player->getSpellBookCount($spellId); if ($bookCount < 1) { continue; } $learnableIndex++; $quality = $spellInfo['quality'] ?? 'common'; $qualityColor = $this->getQualityColor($quality); $name = $spellInfo['name'] ?? '未知法术'; $out->writeln("[{$learnableIndex}] {$qualityColor}{$name}{$this->reset} (需求等级: {$levelReq})"); $learnableSpells[$learnableIndex] = ['spellId' => $spellId, 'spellInfo' => $spellInfo]; } if (empty($learnableSpells)) { $out->writeln("{$this->yellow}暂无可学习的法术(需要有资源书并满足等级要求){$this->reset}"); Screen::delay(1000000); return; } $out->writeln("[0] 返回"); $choice = Input::ask($this->game->output, "请选择: ");; if ($choice == '0') { return; } if (isset($learnableSpells[$choice])) { $selected = $learnableSpells[$choice]; $spellId = $selected['spellId']; // 消耗资源书 $player->spendSpellBooks($spellId, 1); // 学习法术 if ($player->learnSpell($spellId)) { $out->writeln("{$this->green}✓ 成功学习 {$selected['spellInfo']['name']}{$this->reset}"); } else { $out->writeln("{$this->red}✗ 学习失败{$this->reset}"); } Screen::delay(1000000); } else { $out->writeln("{$this->red}无效选择{$this->reset}"); Screen::delay(500000); } } /** * 升级法术 */ private function upgradeSpell(array $spellsData) { $out = $this->game->output; $in = $this->game->input; $player = $this->game->player; Screen::clear($out); $out->writeln("{$this->bold}{$this->cyan}=== 升级法术 ==={$this->reset}"); $out->writeln(""); if (empty($player->spells)) { $out->writeln("{$this->red}还未学习任何法术{$this->reset}"); Screen::delay(1000000); return; } // 列出已学习但未满级的法术 $upgradableIndex = 0; $upgradableSpells = []; $upgrades = $spellsData['upgrades'] ?? []; foreach ($player->spells as $spellId => $spellData) { $level = $spellData['level'] ?? 1; // 检查是否已满级 if ($level >= 10) { continue; } $spellInfo = $this->getSpellInfo($spellId, $spellsData); $quality = $spellInfo['quality'] ?? 'common'; $qualityColor = $this->getQualityColor($quality); $name = $spellInfo['name'] ?? '未知法术'; // 获取升级所需资源书数量 $nextLevel = $level + 1; $upgradeInfo = $upgrades[$nextLevel] ?? ['cost' => 0]; $booksNeeded = $upgradeInfo['cost'] ?? 0; $booksOwned = $player->getSpellBookCount($spellId); $upgradableIndex++; $canUpgrade = $booksOwned >= $booksNeeded; $statusColor = $canUpgrade ? $this->green : $this->red; $out->writeln("[{$upgradableIndex}] {$qualityColor}{$name}{$this->reset} Lv.{$level}"); $out->writeln(" 升级所需: {$statusColor}{$booksNeeded}{$this->reset} 本资源书 (拥有: {$booksOwned})"); $upgradableSpells[$upgradableIndex] = ['spellId' => $spellId, 'spellInfo' => $spellInfo]; } if (empty($upgradableSpells)) { $out->writeln("{$this->yellow}暂无可升级的法术{$this->reset}"); Screen::delay(1000000); return; } $out->writeln("[0] 返回"); $choice = Input::ask($out,"请选择要升级的法术"); if ($choice == '0') { return; } if (isset($upgradableSpells[$choice])) { $selected = $upgradableSpells[$choice]; $spellId = $selected['spellId']; $level = $player->getSpellLevel($spellId); $nextLevel = $level + 1; $upgradeInfo = $upgrades[$nextLevel] ?? ['cost' => 0]; $booksNeeded = $upgradeInfo['cost'] ?? 0; // 检查是否有足够的资源书 if (!$player->spendSpellBooks($spellId, $booksNeeded)) { $out->writeln("{$this->red}✗ 资源书不足!{$this->reset}"); Screen::delay(1000000); return; } // 升级法术 if ($player->upgradeSpell($spellId)) { $out->writeln("{$this->green}✓ 成功升级 {$selected['spellInfo']['name']} 至 Lv.{$nextLevel}{$this->reset}"); } else { $out->writeln("{$this->red}✗ 升级失败{$this->reset}"); } Screen::delay(1000000); } else { $out->writeln("{$this->red}无效选择{$this->reset}"); Screen::delay(500000); } } /** * 获取魔法值进度条 */ private function getManaBar(int $current, int $max): string { $percent = ($current / $max) * 100; $filled = (int)(20 * ($current / $max)); $empty = 20 - $filled; $color = $percent >= 50 ? $this->green : ($percent >= 25 ? $this->yellow : $this->red); return "{$color}[" . str_repeat('█', $filled) . str_repeat('░', $empty) . "]{$this->reset} " . number_format($percent, 0) . "%"; } /** * 获取法术的品质颜色 */ private function getQualityColor(string $quality): string { $map = [ 'common' => Colors::WHITE, 'rare' => Colors::BLUE, 'epic' => Colors::MAGENTA, 'legendary' => Colors::YELLOW, ]; return $map[$quality] ?? $this->white; } /** * 获取品质名称 */ private function getQualityName(string $quality): string { $map = [ 'common' => '普通', 'rare' => '稀有', 'epic' => '史诗', 'legendary' => '传奇', ]; return $map[$quality] ?? '未知'; } /** * 获取法术信息 */ private function getSpellInfo(int $spellId, array $spellsData): ?array { foreach ($spellsData as $category => $spells) { if (is_array($spells) && $category !== 'quality_levels' && $category !== 'upgrades') { if (isset($spells[$spellId])) { return $spells[$spellId]; } } } return null; } }