操作优化
This commit is contained in:
parent
b4ec385827
commit
bacc28acce
|
|
@ -11,6 +11,7 @@ use Game\Modules\NpcPanel;
|
||||||
use Game\Modules\PartnerPanel;
|
use Game\Modules\PartnerPanel;
|
||||||
use Game\Modules\TalentPanel;
|
use Game\Modules\TalentPanel;
|
||||||
use Game\Modules\DungeonSelectPanel;
|
use Game\Modules\DungeonSelectPanel;
|
||||||
|
use Game\Modules\EquipmentEnhancePanel;
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
|
|
@ -22,7 +23,8 @@ class Game
|
||||||
const PARTNER = 6;
|
const PARTNER = 6;
|
||||||
const TALENT = 7;
|
const TALENT = 7;
|
||||||
const DUNGEON_SELECT = 8;
|
const DUNGEON_SELECT = 8;
|
||||||
const EXIT = 99;
|
const EQUIPMENT_ENHANCE = 9;
|
||||||
|
const EXIT = 0;
|
||||||
|
|
||||||
public Player $player;
|
public Player $player;
|
||||||
public int $state = self::MENU;
|
public int $state = self::MENU;
|
||||||
|
|
@ -175,6 +177,9 @@ class Game
|
||||||
case self::TALENT:
|
case self::TALENT:
|
||||||
(new TalentPanel($this))->show();
|
(new TalentPanel($this))->show();
|
||||||
break;
|
break;
|
||||||
|
case self::EQUIPMENT_ENHANCE:
|
||||||
|
(new EquipmentEnhancePanel($this))->show();
|
||||||
|
break;
|
||||||
case self::EXIT:
|
case self::EXIT:
|
||||||
$this->output->writeln("再见!");
|
$this->output->writeln("再见!");
|
||||||
$this->saveState();
|
$this->saveState();
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class ItemDisplay
|
||||||
{
|
{
|
||||||
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
|
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
|
||||||
$color = self::getQualityColor($quality);
|
$color = self::getQualityColor($quality);
|
||||||
$name = $item['name'] ?? '未知物品';
|
$name = ($item['name'] ?? '未知物品') . 'lv.' . $item['level'];
|
||||||
|
|
||||||
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
||||||
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
|
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
|
||||||
|
|
@ -291,7 +291,7 @@ class ItemDisplay
|
||||||
{
|
{
|
||||||
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
|
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
|
||||||
$color = self::getQualityColor($quality);
|
$color = self::getQualityColor($quality);
|
||||||
$name = $item['name'] ?? '未知物品';
|
$name = ($item['name'] ?? '未知物品') . 'lv.' . $item['level'];
|
||||||
|
|
||||||
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
||||||
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
|
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
|
||||||
|
|
|
||||||
|
|
@ -35,13 +35,13 @@ class Player
|
||||||
|
|
||||||
// 天赋每点提供的属性
|
// 天赋每点提供的属性
|
||||||
public static array $talentBonus = [
|
public static array $talentBonus = [
|
||||||
'hp' => 20,
|
'hp' => 10,
|
||||||
'patk' => 5,
|
'patk' => 5,
|
||||||
'matk' => 4,
|
'matk' => 4,
|
||||||
'pdef' => 3,
|
'pdef' => 3,
|
||||||
'mdef' => 3,
|
'mdef' => 3,
|
||||||
'crit' => 2,
|
'crit' => 1,
|
||||||
'critdmg' => 10,
|
'critdmg' => 5,
|
||||||
];
|
];
|
||||||
|
|
||||||
// 天赋名称
|
// 天赋名称
|
||||||
|
|
|
||||||
464
src/Modules/EquipmentEnhancePanel.php
Normal file
464
src/Modules/EquipmentEnhancePanel.php
Normal file
|
|
@ -0,0 +1,464 @@
|
||||||
|
<?php
|
||||||
|
namespace Game\Modules;
|
||||||
|
|
||||||
|
use Game\Core\Game;
|
||||||
|
use Game\Core\ItemDisplay;
|
||||||
|
use Game\Core\Screen;
|
||||||
|
use Game\Services\EquipmentEnhancer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 装备强化面板
|
||||||
|
* 允许玩家快速强化库存或装备栏中的任何装备
|
||||||
|
*/
|
||||||
|
class EquipmentEnhancePanel
|
||||||
|
{
|
||||||
|
private string $cyan = "\033[36m";
|
||||||
|
private string $yellow = "\033[33m";
|
||||||
|
private string $green = "\033[32m";
|
||||||
|
private string $red = "\033[31m";
|
||||||
|
private string $white = "\033[37m";
|
||||||
|
private string $bold = "\033[1m";
|
||||||
|
private string $reset = "\033[0m";
|
||||||
|
|
||||||
|
public function __construct(public Game $game) {}
|
||||||
|
|
||||||
|
public function show()
|
||||||
|
{
|
||||||
|
while (true) {
|
||||||
|
Screen::clear($this->game->output);
|
||||||
|
|
||||||
|
$out = $this->game->output;
|
||||||
|
$player = $this->game->player;
|
||||||
|
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->bold}装 备 强 化 中 心{$this->reset} {$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->white}灵石: {$this->yellow}{$player->spiritStones}{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}");
|
||||||
|
|
||||||
|
// 显示已装备物品
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->bold}当前装备:{$this->reset}");
|
||||||
|
|
||||||
|
$slots = ['weapon' => '武器', 'armor' => '护甲', 'boots' => '靴子', 'ring' => '戒指', 'necklace' => '项链'];
|
||||||
|
$equipped = [];
|
||||||
|
$slotIndex = 1;
|
||||||
|
|
||||||
|
foreach ($slots as $slot => $slotName) {
|
||||||
|
$item = $player->equip[$slot] ?? null;
|
||||||
|
|
||||||
|
if ($item) {
|
||||||
|
$str = ItemDisplay::renderListItem($item);
|
||||||
|
$out->writeln("{$this->cyan}║[$slotIndex]$str");
|
||||||
|
$equipped[$slotIndex] = ['slot' => $slot, 'item' => $item];
|
||||||
|
} else {
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} [{$slotIndex}] {$slotName}: {$this->red}未装备{$this->reset}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$slotIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->bold}库存物品:{$this->reset}");
|
||||||
|
|
||||||
|
// 显示库存中可强化的物品
|
||||||
|
$inventoryStart = $slotIndex;
|
||||||
|
$inventoryItems = [];
|
||||||
|
|
||||||
|
foreach ($player->inventory as $invIndex => $item) {
|
||||||
|
if (in_array($item['type'] ?? '', ['weapon', 'armor', 'boots', 'ring', 'necklace'])) {
|
||||||
|
$str = ItemDisplay::renderListItem($item);
|
||||||
|
$out->writeln("{$this->cyan}║[$slotIndex]$str");
|
||||||
|
$inventoryItems[$slotIndex] = ['invIndex' => $invIndex, 'item' => $item];
|
||||||
|
$slotIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($inventoryItems) === 0 && count($equipped) < 5) {
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->red}(无可强化物品){$this->reset}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 选择要强化的装备编号或 [0] 返回");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 输入 [info 编号] 查看强化信息");
|
||||||
|
$out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}");
|
||||||
|
|
||||||
|
$choice = Screen::input($out, "选择: ");
|
||||||
|
|
||||||
|
// 处理返回
|
||||||
|
if ($choice === '0') {
|
||||||
|
$this->game->state = Game::MENU;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理查看信息
|
||||||
|
if (strpos($choice, 'info') === 0) {
|
||||||
|
$parts = explode(' ', $choice);
|
||||||
|
if (isset($parts[1])) {
|
||||||
|
$itemIndex = (int)$parts[1];
|
||||||
|
$this->showEnhanceInfo($equipped, $inventoryItems, $itemIndex);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$itemIndex = (int)$choice;
|
||||||
|
|
||||||
|
// 从已装备物品中强化
|
||||||
|
if (isset($equipped[$itemIndex])) {
|
||||||
|
$this->selectTargetLevelAndEnhance(
|
||||||
|
$equipped[$itemIndex]['slot'],
|
||||||
|
$equipped[$itemIndex]['item'],
|
||||||
|
true
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从库存中强化
|
||||||
|
if (isset($inventoryItems[$itemIndex])) {
|
||||||
|
$invIndex = $inventoryItems[$itemIndex]['invIndex'];
|
||||||
|
$this->selectTargetLevelAndEnhance(
|
||||||
|
null,
|
||||||
|
$inventoryItems[$itemIndex]['item'],
|
||||||
|
false,
|
||||||
|
$invIndex
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$out->writeln("{$this->red}无效选择{$this->reset}");
|
||||||
|
Screen::sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择目标强化等级并进行强化
|
||||||
|
*/
|
||||||
|
private function selectTargetLevelAndEnhance(
|
||||||
|
?string $slot,
|
||||||
|
array &$item,
|
||||||
|
bool $fromEquipped,
|
||||||
|
?int $invIndex = null
|
||||||
|
) {
|
||||||
|
$out = $this->game->output;
|
||||||
|
$player = $this->game->player;
|
||||||
|
$currentLevel = $item['enhanceLevel'] ?? 0;
|
||||||
|
|
||||||
|
Screen::clear($out);
|
||||||
|
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->bold}强 化 等 级 选 择{$this->reset} {$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}");
|
||||||
|
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 装备: {$item['name']}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 当前等级: {$this->yellow}+{$currentLevel}{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 可选等级:");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
|
||||||
|
// 显示可选择的目标等级
|
||||||
|
for ($target = $currentLevel + 1; $target <= EquipmentEnhancer::MAX_ENHANCE_LEVEL; $target++) {
|
||||||
|
$cost = EquipmentEnhancer::getTotalCost($currentLevel, $target);
|
||||||
|
$canAfford = $player->spiritStones >= $cost ? "{$this->green}✓{$this->reset}" : "{$this->red}✗{$this->reset}";
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} [{$target}] +{$target} (需要: {$cost} 灵石) {$canAfford}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} [0] 手动强化 (一次一级)");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 当前灵石: {$this->yellow}{$player->spiritStones}{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}");
|
||||||
|
|
||||||
|
$choice = Screen::input($out, "选择目标等级: ");
|
||||||
|
|
||||||
|
if ($choice === '0') {
|
||||||
|
// 手动强化一次
|
||||||
|
if ($fromEquipped && $slot) {
|
||||||
|
$this->enhanceEquipment($slot, $item, true);
|
||||||
|
} else {
|
||||||
|
$this->enhanceInventoryItem($invIndex, $item);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$targetLevel = (int)$choice;
|
||||||
|
|
||||||
|
// 验证选择有效性
|
||||||
|
if ($targetLevel <= $currentLevel || $targetLevel > EquipmentEnhancer::MAX_ENHANCE_LEVEL) {
|
||||||
|
$out->writeln("{$this->red}无效的目标等级{$this->reset}");
|
||||||
|
Screen::sleep(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查灵石是否足够
|
||||||
|
$totalCost = EquipmentEnhancer::getTotalCost($currentLevel, $targetLevel);
|
||||||
|
if ($player->spiritStones < $totalCost) {
|
||||||
|
$lack = $totalCost - $player->spiritStones;
|
||||||
|
$out->writeln("{$this->red}灵石不足!还需要 {$lack} 灵石{$this->reset}");
|
||||||
|
Screen::sleep(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行自动强化
|
||||||
|
if ($fromEquipped && $slot) {
|
||||||
|
$this->enhanceToLevel($slot, $item, $targetLevel, true);
|
||||||
|
} else {
|
||||||
|
$this->enhanceToLevel(null, $item, $targetLevel, false, $invIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动强化装备到目标等级
|
||||||
|
*/
|
||||||
|
private function enhanceToLevel(
|
||||||
|
?string $slot,
|
||||||
|
array &$item,
|
||||||
|
int $targetLevel,
|
||||||
|
bool $fromEquipped,
|
||||||
|
?int $invIndex = null
|
||||||
|
) {
|
||||||
|
$out = $this->game->output;
|
||||||
|
$player = $this->game->player;
|
||||||
|
$currentLevel = $item['enhanceLevel'] ?? 0;
|
||||||
|
$item['enhanceLevel'] = $item['enhanceLevel'] ?? 0;
|
||||||
|
Screen::clear($out);
|
||||||
|
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->bold}自 动 强 化 中{$this->reset} {$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}");
|
||||||
|
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 装备: {$item['name']}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 目标: +{$targetLevel}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
|
||||||
|
$totalAttempts = 0;
|
||||||
|
$successCount = 0;
|
||||||
|
$failureCount = 0;
|
||||||
|
$downgrades = 0;
|
||||||
|
$startingSpirits = $player->spiritStones;
|
||||||
|
|
||||||
|
// 循环强化直到达到目标等级或灵石用完
|
||||||
|
while ($item['enhanceLevel'] < $targetLevel && $player->spiritStones > 0) {
|
||||||
|
// 检查下一级是否可以强化(灵石足够)
|
||||||
|
$config = EquipmentEnhancer::getConfig($item['enhanceLevel']);
|
||||||
|
if (!$config || $player->spiritStones < $config['cost']) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalAttempts++;
|
||||||
|
$oldLevel = $item['enhanceLevel'];
|
||||||
|
|
||||||
|
// 执行强化
|
||||||
|
$result = EquipmentEnhancer::enhance($item, $player);
|
||||||
|
|
||||||
|
if ($result['success']) {
|
||||||
|
$successCount++;
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 第 {$totalAttempts} 次: {$this->green}✓ 成功{$this->reset} +{$oldLevel} → +{$result['newLevel']}");
|
||||||
|
} else {
|
||||||
|
$failureCount++;
|
||||||
|
if ($result['downgraded']) {
|
||||||
|
$downgrades++;
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 第 {$totalAttempts} 次: {$this->red}✗ 失败并降级{$this->reset} +{$oldLevel} → +{$result['newLevel']}");
|
||||||
|
} else {
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 第 {$totalAttempts} 次: {$this->yellow}✗ 失败{$this->reset} 等级保持 +{$oldLevel}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新显示信息
|
||||||
|
if ($fromEquipped && $slot) {
|
||||||
|
$player->equip[$slot]['enhanceLevel'] = $item['enhanceLevel'];
|
||||||
|
} elseif ($invIndex !== null) {
|
||||||
|
$player->inventory[$invIndex] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示最终结果
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->bold}强 化 完 成{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}");
|
||||||
|
|
||||||
|
$finalLevel = $item['enhanceLevel'];
|
||||||
|
$spiritUsed = $startingSpirits - $player->spiritStones;
|
||||||
|
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 装备等级: {$this->yellow}+{$currentLevel}{$this->reset} → {$this->yellow}+{$finalLevel}{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 强化尝试: {$this->yellow}{$totalAttempts}{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 成功次数: {$this->green}{$successCount}{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 失败次数: {$this->red}{$failureCount}{$this->reset}");
|
||||||
|
if ($downgrades > 0) {
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 降级次数: {$this->red}{$downgrades}{$this->reset}");
|
||||||
|
}
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 灵石消耗: {$this->yellow}{$spiritUsed}{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 剩余灵石: {$this->yellow}{$player->spiritStones}{$this->reset}");
|
||||||
|
|
||||||
|
if ($finalLevel >= $targetLevel) {
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->green}✓ 已达到目标等级!{$this->reset}");
|
||||||
|
} elseif ($player->spiritStones <= 0) {
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->yellow}灵石已用完{$this->reset}");
|
||||||
|
} else {
|
||||||
|
$lack = EquipmentEnhancer::getTotalCost($finalLevel, $targetLevel);
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->yellow}灵石不足,还需 {$lack} 灵石{$this->reset}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}");
|
||||||
|
|
||||||
|
$this->game->saveState();
|
||||||
|
Screen::pause($out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 强化已装备的物品(手动一次一级)
|
||||||
|
*/
|
||||||
|
private function enhanceEquipment(string $slot, array &$item, bool $fromEquipped = true)
|
||||||
|
{
|
||||||
|
$out = $this->game->output;
|
||||||
|
$player = $this->game->player;
|
||||||
|
|
||||||
|
// 使用 EquipmentEnhancer 执行强化
|
||||||
|
$result = EquipmentEnhancer::enhance($item, $player);
|
||||||
|
|
||||||
|
Screen::clear($out);
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->bold}强 化 结 果{$this->reset} {$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}");
|
||||||
|
$out->writeln("");
|
||||||
|
|
||||||
|
if ($result['success']) {
|
||||||
|
$out->writeln("{$this->green}★ 强化成功!{$this->reset}");
|
||||||
|
$out->writeln("{$item['name']} 强化等级提升至 {$this->yellow}+{$result['newLevel']}{$this->reset}");
|
||||||
|
|
||||||
|
// 更新已装备物品
|
||||||
|
if ($fromEquipped) {
|
||||||
|
$player->equip[$slot]['enhanceLevel'] = $result['newLevel'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($result['cost'] === 0) {
|
||||||
|
$out->writeln("{$this->red}✗ {$result['message']}{$this->reset}");
|
||||||
|
} else {
|
||||||
|
$out->writeln("{$this->red}✗ 强化失败!{$this->reset}");
|
||||||
|
if ($result['downgraded']) {
|
||||||
|
$out->writeln("{$this->red}{$item['name']} 强化等级下降至 +{$result['newLevel']}{$this->reset}");
|
||||||
|
|
||||||
|
// 更新已装备物品
|
||||||
|
if ($fromEquipped) {
|
||||||
|
$player->equip[$slot]['enhanceLevel'] = $result['newLevel'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$out->writeln("强化等级保持不变");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("花费灵石: {$result['cost']}");
|
||||||
|
$out->writeln("当前灵石: {$player->spiritStones}");
|
||||||
|
|
||||||
|
$this->game->saveState();
|
||||||
|
Screen::pause($out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 强化库存中的物品
|
||||||
|
*/
|
||||||
|
private function enhanceInventoryItem(int $invIndex, array &$item)
|
||||||
|
{
|
||||||
|
$out = $this->game->output;
|
||||||
|
$player = $this->game->player;
|
||||||
|
|
||||||
|
// 使用 EquipmentEnhancer 执行强化
|
||||||
|
$result = EquipmentEnhancer::enhance($item, $player);
|
||||||
|
|
||||||
|
// 更新库存中的物品
|
||||||
|
$player->inventory[$invIndex] = $item;
|
||||||
|
|
||||||
|
Screen::clear($out);
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->bold}强 化 结 果{$this->reset} {$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}");
|
||||||
|
$out->writeln("");
|
||||||
|
|
||||||
|
if ($result['success']) {
|
||||||
|
$out->writeln("{$this->green}★ 强化成功!{$this->reset}");
|
||||||
|
$out->writeln("{$item['name']} 强化等级提升至 {$this->yellow}+{$result['newLevel']}{$this->reset}");
|
||||||
|
} else {
|
||||||
|
if ($result['cost'] === 0) {
|
||||||
|
$out->writeln("{$this->red}✗ {$result['message']}{$this->reset}");
|
||||||
|
} else {
|
||||||
|
$out->writeln("{$this->red}✗ 强化失败!{$this->reset}");
|
||||||
|
if ($result['downgraded']) {
|
||||||
|
$out->writeln("{$this->red}{$item['name']} 强化等级下降至 +{$result['newLevel']}{$this->reset}");
|
||||||
|
} else {
|
||||||
|
$out->writeln("强化等级保持不变");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("花费灵石: {$result['cost']}");
|
||||||
|
$out->writeln("当前灵石: {$player->spiritStones}");
|
||||||
|
|
||||||
|
$this->game->saveState();
|
||||||
|
Screen::pause($out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示装备强化信息
|
||||||
|
*/
|
||||||
|
private function showEnhanceInfo(array $equipped, array $inventoryItems, int $itemIndex)
|
||||||
|
{
|
||||||
|
$out = $this->game->output;
|
||||||
|
$player = $this->game->player;
|
||||||
|
|
||||||
|
$item = null;
|
||||||
|
if (isset($equipped[$itemIndex])) {
|
||||||
|
$item = $equipped[$itemIndex]['item'];
|
||||||
|
} elseif (isset($inventoryItems[$itemIndex])) {
|
||||||
|
$item = $inventoryItems[$itemIndex]['item'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Screen::clear($out);
|
||||||
|
|
||||||
|
$currentLevel = $item['enhanceLevel'] ?? 0;
|
||||||
|
$config = EquipmentEnhancer::getConfig($currentLevel);
|
||||||
|
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("{$this->cyan}╔════════════════════════════════════╗{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->bold}强化信息{$this->reset} {$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}");
|
||||||
|
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 装备: {$item['name']}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 当前强化: {$this->yellow}+{$currentLevel}{$this->reset}");
|
||||||
|
|
||||||
|
if ($config) {
|
||||||
|
$nextBonus = EquipmentEnhancer::getEnhanceBonusPercent($currentLevel + 1);
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 下一级信息:");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 成功率: {$this->yellow}{$config['rate']}%{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 花费: {$config['cost']} 灵石");
|
||||||
|
if ($config['downgrade'] > 0) {
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 降级率: {$this->red}{$config['downgrade']}%{$this->reset}");
|
||||||
|
}
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 属性加成: {$nextBonus}%");
|
||||||
|
} else {
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->green}✓ 已达最大强化等级{$this->reset}");
|
||||||
|
}
|
||||||
|
|
||||||
|
$out->writeln("{$this->cyan}╠════════════════════════════════════╣{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} 当前灵石: {$this->yellow}{$player->spiritStones}{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset}");
|
||||||
|
$out->writeln("{$this->cyan}╚════════════════════════════════════╝{$this->reset}");
|
||||||
|
|
||||||
|
Screen::pause($out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -32,7 +32,7 @@ class InventoryPanel
|
||||||
|
|
||||||
public function __construct(public Game $game) {}
|
public function __construct(public Game $game) {}
|
||||||
|
|
||||||
public function show(int $page = 1, string $category = 'all')
|
public function show(int $page = 1, string $category = 'equipment')
|
||||||
{
|
{
|
||||||
$out = $this->game->output;
|
$out = $this->game->output;
|
||||||
Screen::clear($out);
|
Screen::clear($out);
|
||||||
|
|
@ -340,19 +340,35 @@ class InventoryPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一键使用消耗品回复生命值至满
|
* 一键使用消耗品回复生命值至满(包括队友)
|
||||||
*/
|
*/
|
||||||
private function autoHeal()
|
private function autoHeal()
|
||||||
{
|
{
|
||||||
$out = $this->game->output;
|
$out = $this->game->output;
|
||||||
$player = $this->game->player;
|
$player = $this->game->player;
|
||||||
|
|
||||||
$stats = $player->getStats();
|
// 检查玩家和队友谁需要治疗
|
||||||
$maxHp = $stats['maxHp'];
|
$playerStats = $player->getStats();
|
||||||
|
$playerMaxHp = $playerStats['maxHp'];
|
||||||
|
$playerNeedsHeal = $player->hp < $playerMaxHp;
|
||||||
|
|
||||||
// 检查是否已满血
|
// 收集需要治疗的队友
|
||||||
if ($player->hp >= $maxHp) {
|
$partnersNeedHeal = [];
|
||||||
$out->writeln("你的生命值已满!");
|
foreach ($player->partners as $partner) {
|
||||||
|
$partnerStats = $partner->getStats();
|
||||||
|
$partnerMaxHp = $partnerStats['maxHp'];
|
||||||
|
if ($partner->hp < $partnerMaxHp) {
|
||||||
|
$partnersNeedHeal[] = [
|
||||||
|
'partner' => $partner,
|
||||||
|
'maxHp' => $partnerMaxHp,
|
||||||
|
'needHeal' => $partnerMaxHp - $partner->hp,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果都不需要治疗
|
||||||
|
if (!$playerNeedsHeal && empty($partnersNeedHeal)) {
|
||||||
|
$out->writeln("你和队友的生命值都已满!");
|
||||||
Screen::sleep(1);
|
Screen::sleep(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -376,10 +392,12 @@ class InventoryPanel
|
||||||
|
|
||||||
$totalHealed = 0;
|
$totalHealed = 0;
|
||||||
$itemsUsed = 0;
|
$itemsUsed = 0;
|
||||||
|
$healLog = [];
|
||||||
|
|
||||||
while ($player->hp < $maxHp && !empty($consumables)) {
|
// 回复玩家
|
||||||
|
while ($playerNeedsHeal && $player->hp < $playerMaxHp && !empty($consumables)) {
|
||||||
// 计算需要恢复的量
|
// 计算需要恢复的量
|
||||||
$needHeal = $maxHp - $player->hp;
|
$needHeal = $playerMaxHp - $player->hp;
|
||||||
|
|
||||||
// 找到最合适的药品(不浪费或浪费最少的)
|
// 找到最合适的药品(不浪费或浪费最少的)
|
||||||
$bestIndex = null;
|
$bestIndex = null;
|
||||||
|
|
@ -408,15 +426,14 @@ class InventoryPanel
|
||||||
$actualHeal = $player->heal($item['heal']);
|
$actualHeal = $player->heal($item['heal']);
|
||||||
$totalHealed += $actualHeal;
|
$totalHealed += $actualHeal;
|
||||||
$itemsUsed++;
|
$itemsUsed++;
|
||||||
|
$healLog[] = "玩家: +{$actualHeal} HP";
|
||||||
|
|
||||||
// 减少数量或移除物品
|
// 减少数量或移除物品
|
||||||
if (($player->inventory[$inventoryIndex]['quantity'] ?? 1) > 1) {
|
if (($player->inventory[$inventoryIndex]['quantity'] ?? 1) > 1) {
|
||||||
$player->inventory[$inventoryIndex]['quantity']--;
|
$player->inventory[$inventoryIndex]['quantity']--;
|
||||||
// 更新 consumables 中的数量
|
|
||||||
$consumables[$bestIndex]['item']['quantity']--;
|
$consumables[$bestIndex]['item']['quantity']--;
|
||||||
} else {
|
} else {
|
||||||
unset($player->inventory[$inventoryIndex]);
|
unset($player->inventory[$inventoryIndex]);
|
||||||
// 从 consumables 中移除
|
|
||||||
unset($consumables[$bestIndex]);
|
unset($consumables[$bestIndex]);
|
||||||
$consumables = array_values($consumables);
|
$consumables = array_values($consumables);
|
||||||
}
|
}
|
||||||
|
|
@ -434,16 +451,97 @@ class InventoryPanel
|
||||||
usort($consumables, fn($a, $b) => ($a['item']['heal'] ?? 0) <=> ($b['item']['heal'] ?? 0));
|
usort($consumables, fn($a, $b) => ($a['item']['heal'] ?? 0) <=> ($b['item']['heal'] ?? 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 回复队友(按需要程度优先恢复)
|
||||||
|
if (!empty($partnersNeedHeal) && !empty($consumables)) {
|
||||||
|
// 按需要治疗量从大到小排序(优先治疗伤势最重的)
|
||||||
|
usort($partnersNeedHeal, fn($a, $b) => $b['needHeal'] <=> $a['needHeal']);
|
||||||
|
|
||||||
|
foreach ($partnersNeedHeal as $healData) {
|
||||||
|
$partner = $healData['partner'];
|
||||||
|
$partnerMaxHp = $healData['maxHp'];
|
||||||
|
|
||||||
|
while ($partner->hp < $partnerMaxHp && !empty($consumables)) {
|
||||||
|
// 计算需要恢复的量
|
||||||
|
$needHeal = $partnerMaxHp - $partner->hp;
|
||||||
|
|
||||||
|
// 找到最合适的药品
|
||||||
|
$bestIndex = null;
|
||||||
|
$bestWaste = PHP_INT_MAX;
|
||||||
|
|
||||||
|
foreach ($consumables as $i => $c) {
|
||||||
|
$healAmount = $c['item']['heal'] ?? 0;
|
||||||
|
$waste = max(0, $healAmount - $needHeal);
|
||||||
|
|
||||||
|
if ($waste < $bestWaste) {
|
||||||
|
$bestWaste = $waste;
|
||||||
|
$bestIndex = $i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($waste === 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($bestIndex === null) break;
|
||||||
|
|
||||||
|
$selected = $consumables[$bestIndex];
|
||||||
|
$inventoryIndex = $selected['index'];
|
||||||
|
$item = $selected['item'];
|
||||||
|
|
||||||
|
// 使用药品回复队友
|
||||||
|
$actualHeal = $partner->heal($item['heal']);
|
||||||
|
$totalHealed += $actualHeal;
|
||||||
|
$itemsUsed++;
|
||||||
|
$healLog[] = "{$partner->name}: +{$actualHeal} HP";
|
||||||
|
|
||||||
|
// 减少数量或移除物品
|
||||||
|
if (($player->inventory[$inventoryIndex]['quantity'] ?? 1) > 1) {
|
||||||
|
$player->inventory[$inventoryIndex]['quantity']--;
|
||||||
|
$consumables[$bestIndex]['item']['quantity']--;
|
||||||
|
} else {
|
||||||
|
unset($player->inventory[$inventoryIndex]);
|
||||||
|
unset($consumables[$bestIndex]);
|
||||||
|
$consumables = array_values($consumables);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新整理背包索引
|
||||||
|
$player->inventory = array_values($player->inventory);
|
||||||
|
|
||||||
|
// 更新 consumables 的索引引用
|
||||||
|
$consumables = [];
|
||||||
|
foreach ($player->inventory as $index => $invItem) {
|
||||||
|
if (($invItem['type'] ?? '') === 'consume' && ($invItem['heal'] ?? 0) > 0) {
|
||||||
|
$consumables[] = ['index' => $index, 'item' => $invItem];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usort($consumables, fn($a, $b) => ($a['item']['heal'] ?? 0) <=> ($b['item']['heal'] ?? 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->game->saveState();
|
$this->game->saveState();
|
||||||
|
|
||||||
if ($totalHealed > 0) {
|
if ($totalHealed > 0) {
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("╔════════════════════════════════════╗");
|
||||||
|
$out->writeln("║ 一键回血结果 ║");
|
||||||
|
$out->writeln("╚════════════════════════════════════╝");
|
||||||
$out->writeln("使用了 {$itemsUsed} 个药品,共恢复 {$totalHealed} HP!");
|
$out->writeln("使用了 {$itemsUsed} 个药品,共恢复 {$totalHealed} HP!");
|
||||||
$out->writeln("当前生命值: {$player->hp}/{$maxHp}");
|
$out->writeln("");
|
||||||
|
$out->writeln("治疗详情:");
|
||||||
|
foreach ($healLog as $log) {
|
||||||
|
$out->writeln(" " . $log);
|
||||||
|
}
|
||||||
|
$out->writeln("");
|
||||||
|
$out->writeln("当前状态:");
|
||||||
|
$out->writeln(" 玩家: {$player->hp}/{$playerMaxHp}");
|
||||||
|
foreach ($player->partners as $partner) {
|
||||||
|
$partnerStats = $partner->getStats();
|
||||||
|
$out->writeln(" {$partner->name}: {$partner->hp}/{$partnerStats['maxHp']}");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$out->writeln("没有使用任何药品。");
|
$out->writeln("没有使用任何药品。");
|
||||||
}
|
}
|
||||||
|
|
||||||
Screen::sleep(1);
|
Screen::pause($out);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function batchSell()
|
private function batchSell()
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ class Menu
|
||||||
$out->writeln("[4] 拜访故人");
|
$out->writeln("[4] 拜访故人");
|
||||||
$out->writeln("[5] 同伴管理");
|
$out->writeln("[5] 同伴管理");
|
||||||
$out->writeln("[6] 天赋系统");
|
$out->writeln("[6] 天赋系统");
|
||||||
$out->writeln("[99] 退出");
|
$out->writeln("[7] 装备强化");
|
||||||
|
$out->writeln("[0] 退出");
|
||||||
$out->writeln("=========================");
|
$out->writeln("=========================");
|
||||||
|
|
||||||
$choice = Input::ask($out, "请选择: ");
|
$choice = Input::ask($out, "请选择: ");
|
||||||
|
|
@ -30,7 +31,7 @@ class Menu
|
||||||
$this->game->state = Game::DUNGEON_SELECT;
|
$this->game->state = Game::DUNGEON_SELECT;
|
||||||
|
|
||||||
} elseif ($choice == 2) {
|
} elseif ($choice == 2) {
|
||||||
$this->game->state = Game::STATS; // ← 新增
|
$this->game->state = Game::STATS;
|
||||||
|
|
||||||
} elseif ($choice == 3) {
|
} elseif ($choice == 3) {
|
||||||
$this->game->state = Game::INVENTORY;
|
$this->game->state = Game::INVENTORY;
|
||||||
|
|
@ -44,7 +45,10 @@ class Menu
|
||||||
} elseif ($choice == 6) {
|
} elseif ($choice == 6) {
|
||||||
$this->game->state = Game::TALENT;
|
$this->game->state = Game::TALENT;
|
||||||
|
|
||||||
} elseif ($choice == 99) {
|
} elseif ($choice == 7) {
|
||||||
|
$this->game->state = Game::EQUIPMENT_ENHANCE;
|
||||||
|
|
||||||
|
} elseif ($choice == 0) {
|
||||||
$this->game->state = Game::EXIT;
|
$this->game->state = Game::EXIT;
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
|
|
|
||||||
|
|
@ -34,22 +34,23 @@ class NpcPanel
|
||||||
$this->game->output->writeln("目前没有故人可以拜访。");
|
$this->game->output->writeln("目前没有故人可以拜访。");
|
||||||
} else {
|
} else {
|
||||||
foreach ($availableNpcs as $index => $npc) {
|
foreach ($availableNpcs as $index => $npc) {
|
||||||
$this->game->output->writeln("[{$index}] {$npc['name']} <{$npc['title']}>");
|
$idx = $index+1;
|
||||||
|
$this->game->output->writeln("[{$idx}] {$npc['name']} <{$npc['title']}>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->game->output->writeln("==============================");
|
$this->game->output->writeln("==============================");
|
||||||
$this->game->output->writeln("[99] 返回");
|
$this->game->output->writeln("[0] 返回");
|
||||||
|
|
||||||
$choice = Input::ask($this->game->output, "请选择故人: ");
|
$choice = Input::ask($this->game->output, "请选择故人: ");
|
||||||
|
|
||||||
if ($choice == 99) {
|
if ($choice == 0) {
|
||||||
$this->game->state = Game::MENU;
|
$this->game->state = Game::MENU;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($availableNpcs[$choice])) {
|
if (isset($availableNpcs[$choice-1])) {
|
||||||
$this->interact($availableNpcs[$choice]);
|
$this->interact($availableNpcs[$choice-1]);
|
||||||
} else {
|
} else {
|
||||||
$this->game->output->writeln("无效选择");
|
$this->game->output->writeln("无效选择");
|
||||||
Screen::sleep(1);
|
Screen::sleep(1);
|
||||||
|
|
@ -86,12 +87,12 @@ class NpcPanel
|
||||||
|
|
||||||
$this->game->output->writeln("[{$idx}] {$label}");
|
$this->game->output->writeln("[{$idx}] {$label}");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->game->output->writeln("[99] 离开");
|
$this->game->output->writeln("[0] 离开");
|
||||||
|
|
||||||
$choice = Input::ask($this->game->output, "请选择: ");
|
$choice = Input::ask($this->game->output, "请选择: ");
|
||||||
|
|
||||||
if ($choice == 99) return;
|
if ($choice == 0) return;
|
||||||
|
|
||||||
if (isset($actionKeys[$choice])) {
|
if (isset($actionKeys[$choice])) {
|
||||||
$actionType = $actionKeys[$choice];
|
$actionType = $actionKeys[$choice];
|
||||||
|
|
@ -156,13 +157,15 @@ class NpcPanel
|
||||||
private function trade(array $items)
|
private function trade(array $items)
|
||||||
{
|
{
|
||||||
// Simple trade implementation
|
// Simple trade implementation
|
||||||
|
$index = 1;
|
||||||
foreach ($items as $idx => $itemInfo) {
|
foreach ($items as $idx => $itemInfo) {
|
||||||
$this->game->output->writeln("[{$idx}] {$itemInfo['name']} - {$itemInfo['price']} 灵石");
|
$index++;
|
||||||
|
$this->game->output->writeln("[{$index}] {$itemInfo['name']} - {$itemInfo['price']} 灵石");
|
||||||
}
|
}
|
||||||
$this->game->output->writeln("[99] 取消");
|
$this->game->output->writeln("[0] 取消");
|
||||||
|
|
||||||
$choice = Input::ask($this->game->output, "购买: ");
|
$choice = Input::ask($this->game->output, "购买: ");
|
||||||
if (isset($items[$choice])) {
|
if (isset($items[$choice-1])) {
|
||||||
$itemInfo = $items[$choice];
|
$itemInfo = $items[$choice];
|
||||||
if ($this->game->player->spiritStones >= $itemInfo['price']) {
|
if ($this->game->player->spiritStones >= $itemInfo['price']) {
|
||||||
$this->game->player->spiritStones -= $itemInfo['price'];
|
$this->game->player->spiritStones -= $itemInfo['price'];
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class PartnerPanel
|
||||||
if (empty($partners)) {
|
if (empty($partners)) {
|
||||||
$this->game->output->writeln("{$this->white}暂无同伴,可通过拜访故人招募。{$this->reset}");
|
$this->game->output->writeln("{$this->white}暂无同伴,可通过拜访故人招募。{$this->reset}");
|
||||||
} else {
|
} else {
|
||||||
$idx = 0;
|
$idx = 1;
|
||||||
foreach ($partners as $partner) {
|
foreach ($partners as $partner) {
|
||||||
$stats = $partner->getStats();
|
$stats = $partner->getStats();
|
||||||
$this->game->output->writeln("[{$idx}] {$this->magenta}{$partner->name}{$this->reset} Lv.{$partner->level}");
|
$this->game->output->writeln("[{$idx}] {$this->magenta}{$partner->name}{$this->reset} Lv.{$partner->level}");
|
||||||
|
|
@ -45,18 +45,18 @@ class PartnerPanel
|
||||||
$this->game->output->writeln("");
|
$this->game->output->writeln("");
|
||||||
$this->game->output->writeln("{$this->cyan}=============================={$this->reset}");
|
$this->game->output->writeln("{$this->cyan}=============================={$this->reset}");
|
||||||
$this->game->output->writeln("输入编号查看详情");
|
$this->game->output->writeln("输入编号查看详情");
|
||||||
$this->game->output->writeln("[99] 返回");
|
$this->game->output->writeln("[0] 返回");
|
||||||
|
|
||||||
$choice = Input::ask($this->game->output, "请选择: ");
|
$choice = Input::ask($this->game->output, "请选择: ");
|
||||||
|
|
||||||
if ($choice == 99) {
|
if ($choice == 0) {
|
||||||
$this->game->state = Game::MENU;
|
$this->game->state = Game::MENU;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$partnerList = array_values($partners);
|
$partnerList = array_values($partners);
|
||||||
if (isset($partnerList[$choice])) {
|
if (isset($partnerList[$choice-1])) {
|
||||||
$this->showPartnerDetail($partnerList[$choice]);
|
$this->showPartnerDetail($partnerList[$choice-1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +115,7 @@ class PartnerPanel
|
||||||
$this->game->output->writeln("[1] 装备物品");
|
$this->game->output->writeln("[1] 装备物品");
|
||||||
$this->game->output->writeln("[2] 卸下装备");
|
$this->game->output->writeln("[2] 卸下装备");
|
||||||
$this->game->output->writeln("[3] {$this->red}解散同伴{$this->reset}");
|
$this->game->output->writeln("[3] {$this->red}解散同伴{$this->reset}");
|
||||||
$this->game->output->writeln("[99] 返回");
|
$this->game->output->writeln("[0] 返回");
|
||||||
|
|
||||||
$choice = Input::ask($this->game->output, "请选择: ");
|
$choice = Input::ask($this->game->output, "请选择: ");
|
||||||
|
|
||||||
|
|
@ -131,7 +131,7 @@ class PartnerPanel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '99':
|
case '0':
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +157,7 @@ class PartnerPanel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$displayIdx = 0;
|
$displayIdx = 1;
|
||||||
$idxMap = [];
|
$idxMap = [];
|
||||||
foreach ($equipableItems as $realIdx => $item) {
|
foreach ($equipableItems as $realIdx => $item) {
|
||||||
$displayStr = ItemDisplay::renderListItem($item, true, false);
|
$displayStr = ItemDisplay::renderListItem($item, true, false);
|
||||||
|
|
@ -166,11 +166,11 @@ class PartnerPanel
|
||||||
$displayIdx++;
|
$displayIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->game->output->writeln("[99] 取消");
|
$this->game->output->writeln("[0] 取消");
|
||||||
|
|
||||||
$choice = Input::ask($this->game->output, "选择装备: ");
|
$choice = Input::ask($this->game->output, "选择装备: ");
|
||||||
|
|
||||||
if ($choice == 99) return;
|
if ($choice == 0) return;
|
||||||
|
|
||||||
if (!isset($idxMap[$choice])) {
|
if (!isset($idxMap[$choice])) {
|
||||||
$this->game->output->writeln("无效选择");
|
$this->game->output->writeln("无效选择");
|
||||||
|
|
@ -224,11 +224,11 @@ class PartnerPanel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->game->output->writeln("[99] 取消");
|
$this->game->output->writeln("[0] 取消");
|
||||||
|
|
||||||
$choice = Input::ask($this->game->output, "选择卸下: ");
|
$choice = Input::ask($this->game->output, "选择卸下: ");
|
||||||
|
|
||||||
if ($choice == 99) return;
|
if ($choice == 0) return;
|
||||||
|
|
||||||
if (!isset($equipped[$choice])) {
|
if (!isset($equipped[$choice])) {
|
||||||
$this->game->output->writeln("无效选择");
|
$this->game->output->writeln("无效选择");
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ namespace Game\Modules;
|
||||||
use Game\Core\Game;
|
use Game\Core\Game;
|
||||||
use Game\Core\Screen;
|
use Game\Core\Screen;
|
||||||
use Game\Core\ItemDisplay;
|
use Game\Core\ItemDisplay;
|
||||||
|
use Game\Services\EquipmentEnhancer;
|
||||||
|
|
||||||
class StatsPanel
|
class StatsPanel
|
||||||
{
|
{
|
||||||
|
|
@ -255,41 +256,26 @@ class StatsPanel
|
||||||
$item = &$player->equip[$slot];
|
$item = &$player->equip[$slot];
|
||||||
if (!$item) return;
|
if (!$item) return;
|
||||||
|
|
||||||
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
// 使用 EquipmentEnhancer 模块执行强化
|
||||||
$config = $this->enhanceConfig[$enhanceLevel] ?? $this->enhanceConfig[14];
|
$result = EquipmentEnhancer::enhance($item, $player);
|
||||||
$cost = $config['cost'];
|
|
||||||
$successRate = $config['rate'];
|
|
||||||
$downgradeChance = $config['downgrade'];
|
|
||||||
|
|
||||||
// 检查灵石
|
// 显示强化结果
|
||||||
if ($player->spiritStones < $cost) {
|
|
||||||
$out->writeln("{$this->red}灵石不足!{$this->reset}");
|
|
||||||
Screen::sleep(1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 扣除灵石
|
|
||||||
$player->spendSpiritStones($cost);
|
|
||||||
|
|
||||||
// 判断成功
|
|
||||||
$roll = rand(1, 100);
|
|
||||||
$out->writeln("");
|
$out->writeln("");
|
||||||
|
|
||||||
if ($roll <= $successRate) {
|
if ($result['success']) {
|
||||||
// 成功
|
// 强化成功
|
||||||
$item['enhanceLevel'] = $enhanceLevel + 1;
|
|
||||||
$out->writeln("{$this->green}★ 强化成功!{$this->reset}");
|
$out->writeln("{$this->green}★ 强化成功!{$this->reset}");
|
||||||
$out->writeln("装备强化等级提升至 {$this->yellow}+{$item['enhanceLevel']}{$this->reset}");
|
$out->writeln("装备强化等级提升至 {$this->yellow}+{$result['newLevel']}{$this->reset}");
|
||||||
} else {
|
} else {
|
||||||
// 失败
|
// 强化失败或其他原因
|
||||||
$out->writeln("{$this->red}✗ 强化失败!{$this->reset}");
|
if ($result['cost'] === 0) {
|
||||||
|
// 灵石不足或已达最大等级
|
||||||
// 判断是否掉级
|
$out->writeln("{$this->red}✗ {$result['message']}{$this->reset}");
|
||||||
if ($enhanceLevel > 0 && $downgradeChance > 0) {
|
} else {
|
||||||
$downgradeRoll = rand(1, 100);
|
// 强化失败
|
||||||
if ($downgradeRoll <= $downgradeChance) {
|
$out->writeln("{$this->red}✗ 强化失败!{$this->reset}");
|
||||||
$item['enhanceLevel'] = max(0, $enhanceLevel - 1);
|
if ($result['downgraded']) {
|
||||||
$out->writeln("{$this->red}装备强化等级下降至 +{$item['enhanceLevel']}{$this->reset}");
|
$out->writeln("{$this->red}装备强化等级下降至 +{$result['newLevel']}{$this->reset}");
|
||||||
} else {
|
} else {
|
||||||
$out->writeln("强化等级保持不变");
|
$out->writeln("强化等级保持不变");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ class TalentPanel
|
||||||
$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->yellow}{$stats['crit']}%{$this->reset} 暴伤: {$this->yellow}{$stats['critdmg']}%{$this->reset}");
|
||||||
$this->game->output->writeln("{$this->cyan}╚════════════════════════════════════════╝{$this->reset}");
|
$this->game->output->writeln("{$this->cyan}╚════════════════════════════════════════╝{$this->reset}");
|
||||||
$this->game->output->writeln("");
|
$this->game->output->writeln("");
|
||||||
$this->game->output->writeln("[1-5] 加点 | [r] 重置天赋 | [0] 返回");
|
$this->game->output->writeln("[1-7] 加点 | [r] 重置天赋 | [0] 返回");
|
||||||
|
|
||||||
$choice = Input::ask($this->game->output, "请选择: ");
|
$choice = Input::ask($this->game->output, "请选择: ");
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ class TalentPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
$choiceInt = intval($choice);
|
$choiceInt = intval($choice);
|
||||||
if ($choiceInt >= 1 && $choiceInt <= 5) {
|
if ($choiceInt >= 1 && $choiceInt <= 7) {
|
||||||
$talents = array_keys(Player::$talentNames);
|
$talents = array_keys(Player::$talentNames);
|
||||||
$selectedTalent = $talents[$choiceInt - 1];
|
$selectedTalent = $talents[$choiceInt - 1];
|
||||||
$this->allocateTalent($selectedTalent);
|
$this->allocateTalent($selectedTalent);
|
||||||
|
|
|
||||||
234
src/Services/EquipmentEnhancer.php
Normal file
234
src/Services/EquipmentEnhancer.php
Normal file
|
|
@ -0,0 +1,234 @@
|
||||||
|
<?php
|
||||||
|
namespace Game\Services;
|
||||||
|
|
||||||
|
use Game\Entities\Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 装备强化服务模块
|
||||||
|
* 提供独立的、可复用的装备强化功能
|
||||||
|
* 可以强化任何装备(库存、装备栏等)
|
||||||
|
*/
|
||||||
|
class EquipmentEnhancer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 强化配置表
|
||||||
|
* 等级 => [成功率%, 花费, 降级概率%]
|
||||||
|
*/
|
||||||
|
private static array $enhanceConfig = [
|
||||||
|
0 => ['rate' => 100, 'cost' => 50, 'downgrade' => 0],
|
||||||
|
1 => ['rate' => 95, 'cost' => 100, 'downgrade' => 0],
|
||||||
|
2 => ['rate' => 90, 'cost' => 150, 'downgrade' => 0],
|
||||||
|
3 => ['rate' => 85, 'cost' => 200, 'downgrade' => 0],
|
||||||
|
4 => ['rate' => 80, 'cost' => 300, 'downgrade' => 10],
|
||||||
|
5 => ['rate' => 70, 'cost' => 400, 'downgrade' => 20],
|
||||||
|
6 => ['rate' => 60, 'cost' => 500, 'downgrade' => 30],
|
||||||
|
7 => ['rate' => 50, 'cost' => 650, 'downgrade' => 40],
|
||||||
|
8 => ['rate' => 40, 'cost' => 800, 'downgrade' => 50],
|
||||||
|
9 => ['rate' => 30, 'cost' => 1000, 'downgrade' => 60],
|
||||||
|
10 => ['rate' => 20, 'cost' => 1500, 'downgrade' => 70],
|
||||||
|
11 => ['rate' => 15, 'cost' => 2000, 'downgrade' => 80],
|
||||||
|
12 => ['rate' => 10, 'cost' => 3000, 'downgrade' => 90],
|
||||||
|
13 => ['rate' => 7, 'cost' => 4000, 'downgrade' => 95],
|
||||||
|
14 => ['rate' => 5, 'cost' => 5000, 'downgrade' => 100],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大强化等级
|
||||||
|
*/
|
||||||
|
public const MAX_ENHANCE_LEVEL = 14;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每个强化等级的属性加成百分比
|
||||||
|
*/
|
||||||
|
public const ENHANCE_BONUS_PER_LEVEL = 0.05; // 5%
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行装备强化
|
||||||
|
*
|
||||||
|
* @param array &$item 装备数组引用(会直接修改)
|
||||||
|
* @param Player $player 玩家对象(需要扣费)
|
||||||
|
* @return array 强化结果数组
|
||||||
|
* [
|
||||||
|
* 'success' => bool, // 是否强化成功
|
||||||
|
* 'message' => string, // 结果消息
|
||||||
|
* 'oldLevel' => int, // 强化前等级
|
||||||
|
* 'newLevel' => int, // 强化后等级
|
||||||
|
* 'cost' => int, // 花费的灵石
|
||||||
|
* 'downgraded' => bool, // 是否发生了降级
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
public static function enhance(array &$item, Player $player): array
|
||||||
|
{
|
||||||
|
$itemName = $item['name'] ?? '未知装备';
|
||||||
|
$currentLevel = $item['enhanceLevel'] ?? 0;
|
||||||
|
|
||||||
|
// 检查是否已达最大强化等级
|
||||||
|
if ($currentLevel >= self::MAX_ENHANCE_LEVEL) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => "{$itemName} 已达最大强化等级!",
|
||||||
|
'oldLevel' => $currentLevel,
|
||||||
|
'newLevel' => $currentLevel,
|
||||||
|
'cost' => 0,
|
||||||
|
'downgraded' => false,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前等级的强化配置
|
||||||
|
$config = self::$enhanceConfig[$currentLevel];
|
||||||
|
$cost = $config['cost'];
|
||||||
|
$successRate = $config['rate'];
|
||||||
|
$downgradeChance = $config['downgrade'];
|
||||||
|
|
||||||
|
// 检查灵石是否足够
|
||||||
|
if ($player->spiritStones < $cost) {
|
||||||
|
$lack = $cost - $player->spiritStones;
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => "灵石不足!还需要 {$lack} 灵石",
|
||||||
|
'oldLevel' => $currentLevel,
|
||||||
|
'newLevel' => $currentLevel,
|
||||||
|
'cost' => 0,
|
||||||
|
'downgraded' => false,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 扣费
|
||||||
|
$player->spendSpiritStones($cost);
|
||||||
|
|
||||||
|
// 掷骰子检定成功
|
||||||
|
$roll = rand(1, 100);
|
||||||
|
$success = $roll <= $successRate;
|
||||||
|
|
||||||
|
if ($success) {
|
||||||
|
// 强化成功
|
||||||
|
$item['enhanceLevel'] = $currentLevel + 1;
|
||||||
|
$newLevel = $currentLevel + 1;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'message' => "{$itemName} 强化成功! +{$currentLevel} → +{$newLevel}",
|
||||||
|
'oldLevel' => $currentLevel,
|
||||||
|
'newLevel' => $newLevel,
|
||||||
|
'cost' => $cost,
|
||||||
|
'downgraded' => false,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// 强化失败
|
||||||
|
$result = [
|
||||||
|
'success' => false,
|
||||||
|
'message' => "{$itemName} 强化失败...",
|
||||||
|
'oldLevel' => $currentLevel,
|
||||||
|
'newLevel' => $currentLevel,
|
||||||
|
'cost' => $cost,
|
||||||
|
'downgraded' => false,
|
||||||
|
];
|
||||||
|
|
||||||
|
// 检查是否触发降级
|
||||||
|
if ($currentLevel > 0 && $downgradeChance > 0) {
|
||||||
|
$downgradeRoll = rand(1, 100);
|
||||||
|
if ($downgradeRoll <= $downgradeChance) {
|
||||||
|
// 发生降级
|
||||||
|
$item['enhanceLevel'] = $currentLevel - 1;
|
||||||
|
$downgradedLevel = $currentLevel - 1;
|
||||||
|
$result['downgraded'] = true;
|
||||||
|
$result['newLevel'] = $downgradedLevel;
|
||||||
|
$result['message'] = "{$itemName} 强化失败并降级了... +{$currentLevel} → +{$downgradedLevel}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取强化配置
|
||||||
|
*
|
||||||
|
* @param int $level 强化等级
|
||||||
|
* @return array|null 配置数组或null
|
||||||
|
*/
|
||||||
|
public static function getConfig(int $level): ?array
|
||||||
|
{
|
||||||
|
return self::$enhanceConfig[$level] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有强化配置
|
||||||
|
*
|
||||||
|
* @return array 完整的配置表
|
||||||
|
*/
|
||||||
|
public static function getAllConfig(): array
|
||||||
|
{
|
||||||
|
return self::$enhanceConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算强化后的属性值
|
||||||
|
*
|
||||||
|
* @param int $baseValue 基础属性值
|
||||||
|
* @param int $enhanceLevel 强化等级
|
||||||
|
* @return int 强化后的属性值
|
||||||
|
*/
|
||||||
|
public static function calculateEnhancedValue(int $baseValue, int $enhanceLevel): int
|
||||||
|
{
|
||||||
|
$multiplier = 1 + ($enhanceLevel * self::ENHANCE_BONUS_PER_LEVEL);
|
||||||
|
return (int)($baseValue * $multiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取强化加成百分比
|
||||||
|
*
|
||||||
|
* @param int $enhanceLevel 强化等级
|
||||||
|
* @return float 加成百分比 (例: 0.25 表示 25%)
|
||||||
|
*/
|
||||||
|
public static function getEnhanceBonus(int $enhanceLevel): float
|
||||||
|
{
|
||||||
|
return $enhanceLevel * self::ENHANCE_BONUS_PER_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取强化加成百分比(百分数形式)
|
||||||
|
*
|
||||||
|
* @param int $enhanceLevel 强化等级
|
||||||
|
* @return int 加成百分数 (例: 25 表示 25%)
|
||||||
|
*/
|
||||||
|
public static function getEnhanceBonusPercent(int $enhanceLevel): int
|
||||||
|
{
|
||||||
|
return (int)($enhanceLevel * self::ENHANCE_BONUS_PER_LEVEL * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查装备是否已达最大强化等级
|
||||||
|
*
|
||||||
|
* @param array $item 装备数组
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isMaxLevel(array $item): bool
|
||||||
|
{
|
||||||
|
$level = $item['enhanceLevel'] ?? 0;
|
||||||
|
return $level >= self::MAX_ENHANCE_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取强化所需的总花费(从当前等级到目标等级)
|
||||||
|
*
|
||||||
|
* @param int $fromLevel 起始强化等级
|
||||||
|
* @param int $toLevel 目标强化等级
|
||||||
|
* @return int 总花费灵石数
|
||||||
|
*/
|
||||||
|
public static function getTotalCost(int $fromLevel, int $toLevel): int
|
||||||
|
{
|
||||||
|
if ($fromLevel >= $toLevel || $toLevel > self::MAX_ENHANCE_LEVEL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$total = 0;
|
||||||
|
for ($level = $fromLevel; $level < $toLevel; $level++) {
|
||||||
|
if (isset(self::$enhanceConfig[$level])) {
|
||||||
|
$total += self::$enhanceConfig[$level]['cost'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $total;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user