hanli/src/Core/ItemDisplay.php
2025-12-07 22:01:41 +08:00

416 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Game\Core;
/**
* 统一的装备显示工具类
*/
class ItemDisplay
{
// 品质颜色
private static array $qualityColors = [
'common' => Colors::WHITE,
'rare' => Colors::BLUE,
'epic' => Colors::MAGENTA,
'legendary' => Colors::YELLOW,
];
// 品质名称
private static array $qualityNames = [
'common' => '普通',
'rare' => '稀有',
'epic' => '史诗',
'legendary' => '传说',
];
// 类型名称
private static array $typeNames = [
'weapon' => '武器',
'armor' => '护甲',
'boots' => '靴子',
'ring' => '戒指',
'necklace' => '项链',
'consume' => '消耗品',
'spell' => '法术',
];
// 属性名称
private static array $statNames = [
'patk' => '物攻',
'matk' => '魔攻',
'pdef' => '物防',
'mdef' => '魔防',
'hp' => '生命',
'crit' => '暴击',
'critdmg' => '暴伤',
'heal' => '治疗',
'cost' => '消耗',
'damage' => '伤害倍率',
];
// 颜色常量
private static string $reset = Colors::RESET;
private static string $yellow = Colors::YELLOW;
private static string $green = Colors::GREEN;
private static string $cyan = Colors::CYAN;
private static string $white = Colors::WHITE;
private static string $gray = Colors::GRAY;
/**
* 获取品质颜色
*/
public static function getQualityColor(string $quality): string
{
return self::$qualityColors[$quality] ?? self::$white;
}
/**
* 获取品质名称
*/
public static function getQualityName(string $quality): string
{
return self::$qualityNames[$quality] ?? '普通';
}
/**
* 获取类型名称
*/
public static function getTypeName(string $type): string
{
return self::$typeNames[$type] ?? ucfirst($type);
}
/**
* 格式化装备名称(带品质颜色和强化等级)
*/
public static function formatName(array $item): string
{
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
$color = self::getQualityColor($quality);
$name = ($item['name'] ?? '未知物品') . 'lv.' . $item['level'];
$enhanceLevel = $item['enhanceLevel'] ?? 0;
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
return $color . $name . self::$reset . $enhanceStr;
}
/**
* 格式化主属性(单行简洁版)
*/
public static function formatStatsCompact(array $item): string
{
$stats = [];
foreach (self::$statNames as $key => $name) {
$value = $item[$key] ?? 0;
if ($value > 0) {
if ($key === 'damage') {
$stats[] = "{$name}:{$value}x";
} else {
$stats[] = "{$name}+{$value}";
}
}
}
return $stats ? self::$green . "(" . implode(" ", $stats) . ")" . self::$reset : "";
}
/**
* 格式化主属性(多行详细版)
*/
public static function formatStatsDetailed(array $item, string $prefix = " "): array
{
$lines = [];
$enhanceLevel = $item['enhanceLevel'] ?? 0;
// 法术强化逻辑不同
$isSpell = ($item['type'] ?? '') === 'spell';
if ($isSpell) {
// 法术强化: 伤害+5%, 消耗-2
$damageMultiplier = 1 + ($enhanceLevel * 0.05);
$costReduction = $enhanceLevel * 2;
foreach (self::$statNames as $key => $name) {
$baseValue = $item[$key] ?? 0;
if ($baseValue > 0) {
if ($key === 'damage') {
$finalValue = number_format($baseValue * $damageMultiplier, 2);
if ($enhanceLevel > 0) {
$lines[] = $prefix . self::$cyan . $name . self::$reset . ": " .
self::$white . $baseValue . "x" . self::$reset . "" .
self::$green . $finalValue . "x" . self::$reset;
} else {
$lines[] = $prefix . self::$cyan . $name . self::$reset . ": " .
self::$green . $baseValue . "x" . self::$reset;
}
} elseif ($key === 'cost') {
$finalValue = max(1, $baseValue - $costReduction);
if ($enhanceLevel > 0) {
$lines[] = $prefix . self::$cyan . $name . self::$reset . ": " .
self::$white . $baseValue . self::$reset . "" .
self::$green . $finalValue . self::$reset;
} else {
$lines[] = $prefix . self::$cyan . $name . self::$reset . ": " .
self::$green . $baseValue . self::$reset;
}
} else {
// For other stats on spells, just display the base value
$lines[] = $prefix . self::$cyan . $name . self::$reset . ": " .
self::$green . $baseValue . self::$reset;
}
}
}
} else {
// 装备强化逻辑
$enhanceMultiplier = 1 + ($enhanceLevel * 0.05);
foreach (self::$statNames as $key => $name) {
$baseValue = $item[$key] ?? 0;
if ($baseValue > 0) {
$finalValue = (int)($baseValue * $enhanceMultiplier);
if ($enhanceLevel > 0 && $key !== 'heal') {
$lines[] = $prefix . self::$cyan . $name . self::$reset . ": " .
self::$white . $baseValue . self::$reset . "" .
self::$green . $finalValue . self::$reset;
} else {
$lines[] = $prefix . self::$cyan . $name . self::$reset . ": " .
self::$green . $baseValue . self::$reset;
}
}
}
}
return $lines;
}
/**
* 格式化词条
*/
public static function formatAffixes(array $item, string $prefix = " "): array
{
$lines = [];
$affixes = $item['affixes'] ?? [];
if (!empty($affixes)) {
foreach ($affixes as $affix) {
$lines[] = $prefix . self::$yellow . "" . self::$reset . $affix;
}
}
return $lines;
}
/**
* 渲染物品简略信息(用于列表)
* 格式: [品质色]名称[/品质色]+强化 (类型) 主属性 <词条数>
* 注:法术显示由 SpellDisplay::formatSpellCompact() 处理
*/
public static function renderListItem(array $item, bool $showType = true, bool $showQuantity = true): string
{
// 主属性(简洁版)或法术信息
$type = $item['type'] ?? '';
if ($type === 'spell') {
// 法术显示由 SpellDisplay 处理(计算方式和基础数值)
// 需要导入 SpellDisplay 后使用
$statsStr = SpellDisplay::renderListItem($item);
// 为了向后兼容,使用内联逻辑(调用处应该使用 SpellDisplay
} else {
// 显示装备的属性
$parts = [];
// 名称(带品质颜色和强化)
$parts[] = self::formatName($item);
// 数量
$quantity = $item['quantity'] ?? 1;
if ($showQuantity && $quantity > 1) {
$parts[] = self::$gray . "x{$quantity}" . self::$reset;
}
// 类型
if ($showType) {
$type = $item['type'] ?? '';
$typeName = self::getTypeName($type);
$parts[] = self::$gray . "[{$typeName}]" . self::$reset;
}
$statsStr = self::formatStatsCompact($item);
}
if ($statsStr) {
$parts[] = $statsStr;
}
// 词条数量提示(仅限装备)
if ($type !== 'spell') {
$affixes = $item['affixes'] ?? [];
if (!empty($affixes)) {
$count = count($affixes);
$parts[] = self::$cyan . implode(',',$affixes);
}
}
return implode(" ", $parts);
}
/**
* 渲染物品详细信息(用于详情面板)
* 返回多行数组
*/
public static function renderDetail(array $item, string $linePrefix = ""): array
{
$lines = [];
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
$qualityColor = self::getQualityColor($quality);
$qualityName = self::getQualityName($quality);
$type = $item['type'] ?? '';
$typeName = self::getTypeName($type);
$enhanceLevel = $item['enhanceLevel'] ?? 0;
// 名称行
$lines[] = $linePrefix . self::formatName($item);
$lines[] = $linePrefix;
// 品质和类型
$lines[] = $linePrefix . "品质: " . $qualityColor . $qualityName . self::$reset;
$lines[] = $linePrefix . "类型: " . self::$white . $typeName . self::$reset;
// 强化等级
if ($enhanceLevel > 0) {
$bonus = $enhanceLevel * 5;
$lines[] = $linePrefix . "强化: " . self::$yellow . "+{$enhanceLevel}" . self::$reset .
self::$gray . " (属性+{$bonus}%)" . self::$reset;
}
$lines[] = $linePrefix;
// 法术特殊显示
if ($type === 'spell') {
$lines[] = $linePrefix . self::$white . "--- 法术信息 ---" . self::$reset;
$lines += SpellDisplay::renderDetail($item);
$lines[] = $linePrefix;
}else{
// 主属性
$lines[] = $linePrefix . self::$white . "--- 主属性 ---" . self::$reset;
$statLines = self::formatStatsDetailed($item, $linePrefix . " ");
if (!empty($statLines)) {
$lines = array_merge($lines, $statLines);
} else {
$lines[] = $linePrefix . " " . self::$gray . "(无)" . self::$reset;
}
// 词条
$affixes = $item['affixes'] ?? [];
if (!empty($affixes)) {
$lines[] = $linePrefix;
$lines[] = $linePrefix . self::$white . "--- 词条 ---" . self::$reset;
$affixLines = self::formatAffixes($item, $linePrefix . " ");
$lines = array_merge($lines, $affixLines);
}
// 描述
$desc = $item['desc'] ?? '';
if ($desc) {
$lines[] = $linePrefix;
$lines[] = $linePrefix . self::$gray . $desc . self::$reset;
}
}
return $lines;
}
/**
* 渲染装备槽位信息(用于属性面板)
* 注:法术显示由 SpellDisplay::renderSlot() 处理
*/
public static function renderSlot(string $slotName, ?array $item, string $linePrefix = ""): array
{
// 委托给 SpellDisplay 处理法术,其他类型则在此处理
if ($item && ($item['type'] ?? '') === 'spell') {
// 法术显示由 SpellDisplay 完全处理
// 调用处应该直接使用 SpellDisplay::renderSlot()
// 这里为了向后兼容保留了基本支持
}
$lines = [];
if ($item) {
$type = $item['type'] ?? '';
// 第一行:槽位名 + 装备/法术名
$lines[] = $linePrefix . self::$cyan . $slotName . self::$reset . ": " . self::formatName($item);
if ($type !== 'spell') {
// 装备显示:属性和词条
$statsStr = self::formatStatsCompact($item);
if ($statsStr) {
$lines[] = $linePrefix . " " . $statsStr;
}
// 词条
$affixes = $item['affixes'] ?? [];
foreach ($affixes as $affix) {
$lines[] = $linePrefix . " " . self::$yellow . "" . self::$reset . " " . $affix;
}
}
} else {
$lines[] = $linePrefix . self::$cyan . $slotName . self::$reset . ": " .
self::$gray . "(空)" . self::$reset;
}
return $lines;
}
/**
* 渲染战斗掉落物品(简洁版)
*/
public static function renderDrop(array $item, string $prefix = " "): string
{
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
$color = self::getQualityColor($quality);
if ($item['type'] == 'potion_pool'){
return self::$green .$item['name'] . '+' .$item['heal'];
}
$name = ($item['name'] ?? '未知物品') . 'lv.' . ($item['level'] ?? '');
$enhanceLevel = $item['enhanceLevel'] ?? 0;
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
// 简要属性
$stats = [];
foreach (['patk', 'matk', 'pdef', 'mdef', 'hp'] as $key) {
$value = $item[$key] ?? 0;
if ($value > 0) {
$statName = self::$statNames[$key] ?? $key;
$stats[] = "{$statName}+{$value}";
}
}
$statsStr = $stats ? self::$gray . " (" . implode(" ", $stats) . ")" . self::$reset : "";
// 词条数量
$affixCount = count($item['affixes'] ?? []);
$affixStr = $affixCount > 0 ? self::$cyan . " <{$affixCount}词条>" . self::$reset : "";
return $prefix . "" . $color . $name . self::$reset . $enhanceStr . $statsStr . $affixStr;
}
/**
* 根据品质获取数组索引
*/
private static function getQualityIndex(string $quality): int
{
return match($quality) {
'common' => 0,
'rare' => 1,
'epic' => 2,
'legendary' => 3,
default => 0,
};
}
}