192 lines
8.5 KiB
PHP
192 lines
8.5 KiB
PHP
<?php
|
||
namespace Game\Modules;
|
||
|
||
use Game\Core\Game;
|
||
use Game\Core\Screen;
|
||
use Game\Core\Input;
|
||
use Game\Entities\Player;
|
||
|
||
class TalentPanel
|
||
{
|
||
private string $reset = "\033[0m";
|
||
private string $cyan = "\033[36m";
|
||
private string $green = "\033[32m";
|
||
private string $yellow = "\033[33m";
|
||
private string $red = "\033[31m";
|
||
private string $magenta = "\033[35m";
|
||
private string $white = "\033[37m";
|
||
private string $gray = "\033[90m";
|
||
|
||
public function __construct(public Game $game)
|
||
{
|
||
}
|
||
|
||
public function show()
|
||
{
|
||
while (true) {
|
||
Screen::clear($this->game->output);
|
||
$player = $this->game->player;
|
||
$stats = $player->getStats();
|
||
|
||
$this->game->output->writeln("{$this->cyan}╔════════════════════════════════════════╗{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset} {$this->yellow}天 赋 系 统{$this->reset} {$this->cyan}║{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}╠════════════════════════════════════════╣{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset} 可用天赋点: {$this->yellow}{$player->talentPoints}{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}╠════════════════════════════════════════╣{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset} {$this->white}--- 天赋分配 ---{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset}");
|
||
|
||
// 显示各天赋
|
||
$idx = 1;
|
||
foreach (Player::$talentNames as $key => $name) {
|
||
$points = $player->talents[$key];
|
||
$bonus = Player::$talentBonus[$key];
|
||
$totalBonus = $points * $bonus;
|
||
|
||
// 根据天赋类型显示不同的单位
|
||
$unit = in_array($key, ['crit', 'critdmg']) ? '%' : '';
|
||
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset} [{$idx}] {$this->green}{$name}{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset} 已分配: {$this->yellow}{$points}{$this->reset} 点");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset} 加成: {$this->green}+{$totalBonus}{$unit}{$this->reset} {$this->gray}(每点+{$bonus}{$unit}){$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset}");
|
||
|
||
$idx++;
|
||
}
|
||
|
||
$this->game->output->writeln("{$this->cyan}╠════════════════════════════════════════╣{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset} {$this->white}--- 当前属性 ---{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset} 生命: {$this->green}{$stats['maxHp']}{$this->reset} 物攻: {$this->red}{$stats['patk']}{$this->reset} 魔攻: {$this->cyan}{$stats['matk']}{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset} 物防: {$this->red}{$stats['pdef']}{$this->reset} 魔防: {$this->cyan}{$stats['mdef']}{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}║{$this->reset} 暴击: {$this->yellow}{$stats['crit']}%{$this->reset} 暴伤: {$this->yellow}{$stats['critdmg']}%{$this->reset}");
|
||
$this->game->output->writeln("{$this->cyan}╚════════════════════════════════════════╝{$this->reset}");
|
||
$this->game->output->writeln("");
|
||
$this->game->output->writeln("[1-7] 加点 | [r] 重置天赋 | [0] 返回");
|
||
|
||
$choice = Input::ask($this->game->output, "请选择: ");
|
||
|
||
if ($choice == 0) {
|
||
$this->game->state = Game::MENU;
|
||
return;
|
||
}
|
||
|
||
if (strtolower($choice) === 'r') {
|
||
$this->resetTalents();
|
||
continue;
|
||
}
|
||
|
||
$choiceInt = intval($choice);
|
||
if ($choiceInt >= 1 && $choiceInt <= 7) {
|
||
$talents = array_keys(Player::$talentNames);
|
||
$selectedTalent = $talents[$choiceInt - 1];
|
||
$this->allocateTalent($selectedTalent);
|
||
}
|
||
}
|
||
}
|
||
|
||
private function allocateTalent(string $talent)
|
||
{
|
||
$player = $this->game->player;
|
||
$name = Player::$talentNames[$talent];
|
||
|
||
if ($player->talentPoints <= 0) {
|
||
$this->game->output->writeln("{$this->red}没有可用的天赋点!{$this->reset}");
|
||
Screen::sleep(1);
|
||
return;
|
||
}
|
||
|
||
Screen::clear($this->game->output);
|
||
$this->game->output->writeln("{$this->cyan}========== 分配天赋: {$name} =========={$this->reset}");
|
||
$this->game->output->writeln("");
|
||
$this->game->output->writeln("可用天赋点: {$this->yellow}{$player->talentPoints}{$this->reset}");
|
||
$this->game->output->writeln("当前 {$name}: {$this->green}{$player->talents[$talent]}{$this->reset} 点");
|
||
$this->game->output->writeln("");
|
||
$this->game->output->writeln("[1] 加 1 点");
|
||
$this->game->output->writeln("[5] 加 5 点");
|
||
$this->game->output->writeln("[10] 加 10 点");
|
||
$this->game->output->writeln("[a] 全部加到此天赋");
|
||
$this->game->output->writeln("[0] 取消");
|
||
|
||
$choice = Input::ask($this->game->output, "请选择: ");
|
||
|
||
$points = 0;
|
||
switch (strtolower($choice)) {
|
||
case '1':
|
||
$points = 1;
|
||
break;
|
||
case '5':
|
||
$points = 5;
|
||
break;
|
||
case '10':
|
||
$points = 10;
|
||
break;
|
||
case 'a':
|
||
$points = $player->talentPoints;
|
||
break;
|
||
case '0':
|
||
return;
|
||
default:
|
||
$points = intval($choice);
|
||
}
|
||
|
||
if ($points <= 0) {
|
||
return;
|
||
}
|
||
|
||
// 限制不超过可用点数
|
||
$points = min($points, $player->talentPoints);
|
||
|
||
if ($player->allocateTalent($talent, $points)) {
|
||
$this->game->saveState();
|
||
$bonus = $points * Player::$talentBonus[$talent];
|
||
$unit = in_array($talent, ['crit', 'critdmg']) ? '%' : '';
|
||
$this->game->output->writeln("{$this->green}成功分配 {$points} 点到 {$name}!{$this->reset}");
|
||
$this->game->output->writeln("{$this->yellow}+{$bonus}{$unit} {$name}{$this->reset}");
|
||
Screen::sleep(1);
|
||
}
|
||
}
|
||
|
||
private function resetTalents()
|
||
{
|
||
$player = $this->game->player;
|
||
$totalPoints = array_sum($player->talents);
|
||
|
||
if ($totalPoints <= 0) {
|
||
$this->game->output->writeln("{$this->yellow}没有已分配的天赋点。{$this->reset}");
|
||
Screen::sleep(1);
|
||
return;
|
||
}
|
||
|
||
// 重置费用:每点10灵石
|
||
$cost = $totalPoints * 10;
|
||
|
||
$this->game->output->writeln("");
|
||
$this->game->output->writeln("{$this->yellow}重置天赋将返还 {$totalPoints} 点天赋点{$this->reset}");
|
||
$this->game->output->writeln("{$this->red}费用: {$cost} 灵石{$this->reset}");
|
||
$this->game->output->writeln("你的灵石: {$this->green}{$player->spiritStones}{$this->reset}");
|
||
|
||
if ($player->spiritStones < $cost) {
|
||
$this->game->output->writeln("{$this->red}灵石不足!{$this->reset}");
|
||
Screen::sleep(1);
|
||
return;
|
||
}
|
||
|
||
$confirm = Input::ask($this->game->output, "确认重置?[y/n]: ");
|
||
|
||
if (strtolower($confirm) !== 'y') {
|
||
$this->game->output->writeln("取消重置。");
|
||
Screen::sleep(1);
|
||
return;
|
||
}
|
||
|
||
$player->spendSpiritStones($cost);
|
||
$returned = $player->resetTalents();
|
||
$this->game->saveState();
|
||
|
||
$this->game->output->writeln("{$this->green}天赋已重置!返还 {$returned} 点天赋点。{$this->reset}");
|
||
Screen::sleep(1);
|
||
}
|
||
}
|