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 formatSpellCompact(array $spell): string { $calcType = $spell['calc_type'] ?? 'matk'; $spellType = $spell['spellType'] ?? $spell['type'] ?? 'unknown'; $calcTypeMap = [ 'matk' => '魔攻', 'patk' => '物攻', 'hybrid' => '混合', 'hp_percent' => 'HP%', 'crit_heal' => '暴治', 'crit_damage' => '暴伤', 'defense' => '防御', 'low_def_bonus' => '克低防', 'matk_scaled' => '群伤', 'dispersed_damage' => '分散伤', 'crit_aoe' => '暴范', 'smart_heal' => '智能治', 'hp_missing' => '缺血治', 'team_sync' => '队伍同步', ]; $calcDesc = $calcTypeMap[$calcType] ?? $calcType; // 根据法术类型显示基础数值 $valueStr = ''; if ($spellType === 'damage_single' || $spellType === 'damage_aoe') { $damageRatio = $spell['damage_ratio'] ?? [1.2, 1.6, 2.0, 2.6]; $qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common'); $ratio = $damageRatio[$qualityIndex] ?? 1.0; $valueStr = self::$green . "{$ratio}x" . self::$reset; } elseif ($spellType === 'heal_single' || $spellType === 'heal_aoe') { $healRatio = $spell['heal_ratio'] ?? [0.5, 0.8, 1.2, 1.8]; $qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common'); $ratio = $healRatio[$qualityIndex] ?? 0.5; $valueStr = self::$green . "{$ratio}x" . self::$reset; } return self::$cyan . "[{$calcDesc}]" . self::$reset . ($valueStr ? " " . $valueStr : ""); } /** * 格式化主属性(多行详细版) */ 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; } /** * 渲染物品简略信息(用于列表) * 格式: [品质色]名称[/品质色]+强化 (类型) 主属性 <词条数> */ public static function renderListItem(array $item, bool $showType = true, bool $showQuantity = true): string { $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; } // 主属性(简洁版)或法术信息 $type = $item['type'] ?? ''; if ($type === 'spell') { // 显示法术的计算方式和基础数值 $spellInfo = self::formatSpellCompact($item); if ($spellInfo) { $parts[] = $spellInfo; } } else { // 显示装备的属性 $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; $spellType = $item['spellType'] ?? $item['type'] ?? 'unknown'; $calcType = $item['calc_type'] ?? 'unknown'; // 计算方式映射 $calcTypeMap = [ 'matk' => '基于魔攻', 'patk' => '基于物攻', 'hp_percent' => '基于最大生命值百分比', 'hybrid' => '基于(魔攻+物攻)混合', 'crit_heal' => '暴击率影响治疗效果', 'crit_damage' => '暴击伤害系数影响伤害', 'crit_aoe' => '暴击率影响范围伤害', 'defense' => '基于防御属性', 'low_def_bonus' => '对低防御敌人伤害加成', 'matk_scaled' => '随敌人数量加成', 'dispersed_damage' => '伤害分散到所有敌人', 'smart_heal' => '智能治疗(优先低血量)', 'hp_missing' => '基于缺失生命值', 'team_sync' => '基于队伍规模', ]; $calcDesc = $calcTypeMap[$calcType] ?? $calcType; $lines[] = $linePrefix . " 计算方式: " . self::$cyan . $calcDesc . self::$reset; // 基础数值 if ($spellType === 'damage_single' || $spellType === 'damage_aoe') { $damageRatio = $item['damage_ratio'] ?? [1.2, 1.6, 2.0, 2.6]; $qualityIndex = self::getQualityIndex($quality); $ratio = $damageRatio[$qualityIndex] ?? 1.0; $lines[] = $linePrefix . " 伤害倍数: " . self::$green . $ratio . "x" . self::$reset; } elseif ($spellType === 'heal_single' || $spellType === 'heal_aoe') { $healRatio = $item['heal_ratio'] ?? [0.5, 0.8, 1.2, 1.8]; $healBase = $item['heal_base'] ?? [20, 40, 70, 120]; $qualityIndex = self::getQualityIndex($quality); $ratio = $healRatio[$qualityIndex] ?? 0.5; $base = $healBase[$qualityIndex] ?? 20; $lines[] = $linePrefix . " 治疗系数: " . self::$green . $ratio . "x + " . $base . self::$reset; } $lines[] = $linePrefix; } // 主属性 $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; } /** * 渲染装备槽位信息(用于属性面板) */ public static function renderSlot(string $slotName, ?array $item, string $linePrefix = "║ "): array { $lines = []; if ($item) { $type = $item['type'] ?? ''; // 第一行:槽位名 + 装备/法术名 $lines[] = $linePrefix . self::$cyan . $slotName . self::$reset . ": " . self::formatName($item); if ($type === 'spell') { // 法术显示:计算方式和基础数值 $calcType = $item['calc_type'] ?? 'matk'; $spellType = $item['spellType'] ?? $item['type'] ?? 'unknown'; // 计算方式的完整描述 $calcTypeDescMap = [ 'matk' => '基于魔攻', 'patk' => '基于物攻', 'hybrid' => '混合伤害', 'hp_percent' => '基于HP%', 'crit_heal' => '暴击治疗', 'crit_damage' => '暴击伤害', 'defense' => '基于防御', 'low_def_bonus' => '克低防', 'matk_scaled' => '群体伤害', 'dispersed_damage' => '分散伤害', 'crit_aoe' => '暴击范围', 'smart_heal' => '智能治疗', 'hp_missing' => '缺血治疗', 'team_sync' => '队伍同步', ]; $calcDesc = $calcTypeDescMap[$calcType] ?? $calcType; $lines[] = $linePrefix . " " . self::$white . "计算: " . self::$green . $calcDesc . self::$reset; // 显示基础数值 if ($spellType === 'damage_single' || $spellType === 'damage_aoe') { $damageRatio = $item['damage_ratio'] ?? [1.2, 1.6, 2.0, 2.6]; $qualityIndex = self::getQualityIndex($item['quality'] ?? 'common'); $ratio = $damageRatio[$qualityIndex] ?? 1.0; $lines[] = $linePrefix . " " . self::$white . "倍数: " . self::$yellow . "{$ratio}x" . self::$reset; } elseif ($spellType === 'heal_single' || $spellType === 'heal_aoe') { $healRatio = $item['heal_ratio'] ?? [0.5, 0.8, 1.2, 1.8]; $healBase = $item['heal_base'] ?? [20, 40, 70, 120]; $qualityIndex = self::getQualityIndex($item['quality'] ?? 'common'); $ratio = $healRatio[$qualityIndex] ?? 0.5; $base = $healBase[$qualityIndex] ?? 20; $lines[] = $linePrefix . " " . self::$white . "治疗: " . self::$yellow . "{$ratio}x + {$base}" . self::$reset; } // 显示消耗 $cost = $item['cost'] ?? 0; $enhanceLevel = $item['enhanceLevel'] ?? 0; $actualCost = max(1, $cost - ($enhanceLevel * 2)); if ($enhanceLevel > 0) { $lines[] = $linePrefix . " " . self::$white . "消耗: " . self::$yellow . "{$cost}" . self::$reset . " → " . self::$green . "{$actualCost}" . self::$reset; } else { $lines[] = $linePrefix . " " . self::$white . "消耗: " . self::$green . "{$actualCost}" . self::$reset; } } else { // 装备显示:属性和词条 $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); $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, }; } }