操作优化
This commit is contained in:
parent
b4ec385827
commit
bacc28acce
|
|
@ -11,6 +11,7 @@ use Game\Modules\NpcPanel;
|
|||
use Game\Modules\PartnerPanel;
|
||||
use Game\Modules\TalentPanel;
|
||||
use Game\Modules\DungeonSelectPanel;
|
||||
use Game\Modules\EquipmentEnhancePanel;
|
||||
|
||||
class Game
|
||||
{
|
||||
|
|
@ -22,7 +23,8 @@ class Game
|
|||
const PARTNER = 6;
|
||||
const TALENT = 7;
|
||||
const DUNGEON_SELECT = 8;
|
||||
const EXIT = 99;
|
||||
const EQUIPMENT_ENHANCE = 9;
|
||||
const EXIT = 0;
|
||||
|
||||
public Player $player;
|
||||
public int $state = self::MENU;
|
||||
|
|
@ -175,6 +177,9 @@ class Game
|
|||
case self::TALENT:
|
||||
(new TalentPanel($this))->show();
|
||||
break;
|
||||
case self::EQUIPMENT_ENHANCE:
|
||||
(new EquipmentEnhancePanel($this))->show();
|
||||
break;
|
||||
case self::EXIT:
|
||||
$this->output->writeln("再见!");
|
||||
$this->saveState();
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class ItemDisplay
|
|||
{
|
||||
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
|
||||
$color = self::getQualityColor($quality);
|
||||
$name = $item['name'] ?? '未知物品';
|
||||
$name = ($item['name'] ?? '未知物品') . 'lv.' . $item['level'];
|
||||
|
||||
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
||||
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
|
||||
|
|
@ -291,7 +291,7 @@ class ItemDisplay
|
|||
{
|
||||
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
|
||||
$color = self::getQualityColor($quality);
|
||||
$name = $item['name'] ?? '未知物品';
|
||||
$name = ($item['name'] ?? '未知物品') . 'lv.' . $item['level'];
|
||||
|
||||
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
||||
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@ class Player
|
|||
|
||||
// 天赋每点提供的属性
|
||||
public static array $talentBonus = [
|
||||
'hp' => 20,
|
||||
'hp' => 10,
|
||||
'patk' => 5,
|
||||
'matk' => 4,
|
||||
'pdef' => 3,
|
||||
'mdef' => 3,
|
||||
'crit' => 2,
|
||||
'critdmg' => 10,
|
||||
'crit' => 1,
|
||||
'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 show(int $page = 1, string $category = 'all')
|
||||
public function show(int $page = 1, string $category = 'equipment')
|
||||
{
|
||||
$out = $this->game->output;
|
||||
Screen::clear($out);
|
||||
|
|
@ -340,19 +340,35 @@ class InventoryPanel
|
|||
}
|
||||
|
||||
/**
|
||||
* 一键使用消耗品回复生命值至满
|
||||
* 一键使用消耗品回复生命值至满(包括队友)
|
||||
*/
|
||||
private function autoHeal()
|
||||
{
|
||||
$out = $this->game->output;
|
||||
$player = $this->game->player;
|
||||
|
||||
$stats = $player->getStats();
|
||||
$maxHp = $stats['maxHp'];
|
||||
// 检查玩家和队友谁需要治疗
|
||||
$playerStats = $player->getStats();
|
||||
$playerMaxHp = $playerStats['maxHp'];
|
||||
$playerNeedsHeal = $player->hp < $playerMaxHp;
|
||||
|
||||
// 检查是否已满血
|
||||
if ($player->hp >= $maxHp) {
|
||||
$out->writeln("你的生命值已满!");
|
||||
// 收集需要治疗的队友
|
||||
$partnersNeedHeal = [];
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
|
@ -376,10 +392,12 @@ class InventoryPanel
|
|||
|
||||
$totalHealed = 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;
|
||||
|
|
@ -408,15 +426,14 @@ class InventoryPanel
|
|||
$actualHeal = $player->heal($item['heal']);
|
||||
$totalHealed += $actualHeal;
|
||||
$itemsUsed++;
|
||||
$healLog[] = "玩家: +{$actualHeal} HP";
|
||||
|
||||
// 减少数量或移除物品
|
||||
if (($player->inventory[$inventoryIndex]['quantity'] ?? 1) > 1) {
|
||||
$player->inventory[$inventoryIndex]['quantity']--;
|
||||
// 更新 consumables 中的数量
|
||||
$consumables[$bestIndex]['item']['quantity']--;
|
||||
} else {
|
||||
unset($player->inventory[$inventoryIndex]);
|
||||
// 从 consumables 中移除
|
||||
unset($consumables[$bestIndex]);
|
||||
$consumables = array_values($consumables);
|
||||
}
|
||||
|
|
@ -434,16 +451,97 @@ class InventoryPanel
|
|||
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();
|
||||
|
||||
if ($totalHealed > 0) {
|
||||
$out->writeln("");
|
||||
$out->writeln("╔════════════════════════════════════╗");
|
||||
$out->writeln("║ 一键回血结果 ║");
|
||||
$out->writeln("╚════════════════════════════════════╝");
|
||||
$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 {
|
||||
$out->writeln("没有使用任何药品。");
|
||||
}
|
||||
|
||||
Screen::sleep(1);
|
||||
Screen::pause($out);
|
||||
}
|
||||
|
||||
private function batchSell()
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ class Menu
|
|||
$out->writeln("[4] 拜访故人");
|
||||
$out->writeln("[5] 同伴管理");
|
||||
$out->writeln("[6] 天赋系统");
|
||||
$out->writeln("[99] 退出");
|
||||
$out->writeln("[7] 装备强化");
|
||||
$out->writeln("[0] 退出");
|
||||
$out->writeln("=========================");
|
||||
|
||||
$choice = Input::ask($out, "请选择: ");
|
||||
|
|
@ -30,7 +31,7 @@ class Menu
|
|||
$this->game->state = Game::DUNGEON_SELECT;
|
||||
|
||||
} elseif ($choice == 2) {
|
||||
$this->game->state = Game::STATS; // ← 新增
|
||||
$this->game->state = Game::STATS;
|
||||
|
||||
} elseif ($choice == 3) {
|
||||
$this->game->state = Game::INVENTORY;
|
||||
|
|
@ -44,7 +45,10 @@ class Menu
|
|||
} elseif ($choice == 6) {
|
||||
$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;
|
||||
|
||||
}else {
|
||||
|
|
|
|||
|
|
@ -34,22 +34,23 @@ class NpcPanel
|
|||
$this->game->output->writeln("目前没有故人可以拜访。");
|
||||
} else {
|
||||
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("[99] 返回");
|
||||
$this->game->output->writeln("[0] 返回");
|
||||
|
||||
$choice = Input::ask($this->game->output, "请选择故人: ");
|
||||
|
||||
if ($choice == 99) {
|
||||
if ($choice == 0) {
|
||||
$this->game->state = Game::MENU;
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($availableNpcs[$choice])) {
|
||||
$this->interact($availableNpcs[$choice]);
|
||||
if (isset($availableNpcs[$choice-1])) {
|
||||
$this->interact($availableNpcs[$choice-1]);
|
||||
} else {
|
||||
$this->game->output->writeln("无效选择");
|
||||
Screen::sleep(1);
|
||||
|
|
@ -86,12 +87,12 @@ class NpcPanel
|
|||
|
||||
$this->game->output->writeln("[{$idx}] {$label}");
|
||||
}
|
||||
|
||||
$this->game->output->writeln("[99] 离开");
|
||||
|
||||
|
||||
$this->game->output->writeln("[0] 离开");
|
||||
|
||||
$choice = Input::ask($this->game->output, "请选择: ");
|
||||
|
||||
if ($choice == 99) return;
|
||||
|
||||
if ($choice == 0) return;
|
||||
|
||||
if (isset($actionKeys[$choice])) {
|
||||
$actionType = $actionKeys[$choice];
|
||||
|
|
@ -156,13 +157,15 @@ class NpcPanel
|
|||
private function trade(array $items)
|
||||
{
|
||||
// Simple trade implementation
|
||||
$index = 1;
|
||||
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, "购买: ");
|
||||
if (isset($items[$choice])) {
|
||||
if (isset($items[$choice-1])) {
|
||||
$itemInfo = $items[$choice];
|
||||
if ($this->game->player->spiritStones >= $itemInfo['price']) {
|
||||
$this->game->player->spiritStones -= $itemInfo['price'];
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class PartnerPanel
|
|||
if (empty($partners)) {
|
||||
$this->game->output->writeln("{$this->white}暂无同伴,可通过拜访故人招募。{$this->reset}");
|
||||
} else {
|
||||
$idx = 0;
|
||||
$idx = 1;
|
||||
foreach ($partners as $partner) {
|
||||
$stats = $partner->getStats();
|
||||
$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->cyan}=============================={$this->reset}");
|
||||
$this->game->output->writeln("输入编号查看详情");
|
||||
$this->game->output->writeln("[99] 返回");
|
||||
$this->game->output->writeln("[0] 返回");
|
||||
|
||||
$choice = Input::ask($this->game->output, "请选择: ");
|
||||
|
||||
if ($choice == 99) {
|
||||
if ($choice == 0) {
|
||||
$this->game->state = Game::MENU;
|
||||
return;
|
||||
}
|
||||
|
||||
$partnerList = array_values($partners);
|
||||
if (isset($partnerList[$choice])) {
|
||||
$this->showPartnerDetail($partnerList[$choice]);
|
||||
if (isset($partnerList[$choice-1])) {
|
||||
$this->showPartnerDetail($partnerList[$choice-1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ class PartnerPanel
|
|||
$this->game->output->writeln("[1] 装备物品");
|
||||
$this->game->output->writeln("[2] 卸下装备");
|
||||
$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, "请选择: ");
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ class PartnerPanel
|
|||
return;
|
||||
}
|
||||
break;
|
||||
case '99':
|
||||
case '0':
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ class PartnerPanel
|
|||
return;
|
||||
}
|
||||
|
||||
$displayIdx = 0;
|
||||
$displayIdx = 1;
|
||||
$idxMap = [];
|
||||
foreach ($equipableItems as $realIdx => $item) {
|
||||
$displayStr = ItemDisplay::renderListItem($item, true, false);
|
||||
|
|
@ -166,11 +166,11 @@ class PartnerPanel
|
|||
$displayIdx++;
|
||||
}
|
||||
|
||||
$this->game->output->writeln("[99] 取消");
|
||||
$this->game->output->writeln("[0] 取消");
|
||||
|
||||
$choice = Input::ask($this->game->output, "选择装备: ");
|
||||
|
||||
if ($choice == 99) return;
|
||||
if ($choice == 0) return;
|
||||
|
||||
if (!isset($idxMap[$choice])) {
|
||||
$this->game->output->writeln("无效选择");
|
||||
|
|
@ -224,11 +224,11 @@ class PartnerPanel
|
|||
return;
|
||||
}
|
||||
|
||||
$this->game->output->writeln("[99] 取消");
|
||||
$this->game->output->writeln("[0] 取消");
|
||||
|
||||
$choice = Input::ask($this->game->output, "选择卸下: ");
|
||||
|
||||
if ($choice == 99) return;
|
||||
if ($choice == 0) return;
|
||||
|
||||
if (!isset($equipped[$choice])) {
|
||||
$this->game->output->writeln("无效选择");
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace Game\Modules;
|
|||
use Game\Core\Game;
|
||||
use Game\Core\Screen;
|
||||
use Game\Core\ItemDisplay;
|
||||
use Game\Services\EquipmentEnhancer;
|
||||
|
||||
class StatsPanel
|
||||
{
|
||||
|
|
@ -255,41 +256,26 @@ class StatsPanel
|
|||
$item = &$player->equip[$slot];
|
||||
if (!$item) return;
|
||||
|
||||
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
||||
$config = $this->enhanceConfig[$enhanceLevel] ?? $this->enhanceConfig[14];
|
||||
$cost = $config['cost'];
|
||||
$successRate = $config['rate'];
|
||||
$downgradeChance = $config['downgrade'];
|
||||
// 使用 EquipmentEnhancer 模块执行强化
|
||||
$result = EquipmentEnhancer::enhance($item, $player);
|
||||
|
||||
// 检查灵石
|
||||
if ($player->spiritStones < $cost) {
|
||||
$out->writeln("{$this->red}灵石不足!{$this->reset}");
|
||||
Screen::sleep(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// 扣除灵石
|
||||
$player->spendSpiritStones($cost);
|
||||
|
||||
// 判断成功
|
||||
$roll = rand(1, 100);
|
||||
// 显示强化结果
|
||||
$out->writeln("");
|
||||
|
||||
if ($roll <= $successRate) {
|
||||
// 成功
|
||||
$item['enhanceLevel'] = $enhanceLevel + 1;
|
||||
if ($result['success']) {
|
||||
// 强化成功
|
||||
$out->writeln("{$this->green}★ 强化成功!{$this->reset}");
|
||||
$out->writeln("装备强化等级提升至 {$this->yellow}+{$item['enhanceLevel']}{$this->reset}");
|
||||
$out->writeln("装备强化等级提升至 {$this->yellow}+{$result['newLevel']}{$this->reset}");
|
||||
} else {
|
||||
// 失败
|
||||
$out->writeln("{$this->red}✗ 强化失败!{$this->reset}");
|
||||
|
||||
// 判断是否掉级
|
||||
if ($enhanceLevel > 0 && $downgradeChance > 0) {
|
||||
$downgradeRoll = rand(1, 100);
|
||||
if ($downgradeRoll <= $downgradeChance) {
|
||||
$item['enhanceLevel'] = max(0, $enhanceLevel - 1);
|
||||
$out->writeln("{$this->red}装备强化等级下降至 +{$item['enhanceLevel']}{$this->reset}");
|
||||
// 强化失败或其他原因
|
||||
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}装备强化等级下降至 +{$result['newLevel']}{$this->reset}");
|
||||
} else {
|
||||
$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->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, "请选择: ");
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ class TalentPanel
|
|||
}
|
||||
|
||||
$choiceInt = intval($choice);
|
||||
if ($choiceInt >= 1 && $choiceInt <= 5) {
|
||||
if ($choiceInt >= 1 && $choiceInt <= 7) {
|
||||
$talents = array_keys(Player::$talentNames);
|
||||
$selectedTalent = $talents[$choiceInt - 1];
|
||||
$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