优化技能显示系统:增强战斗中的法术信息显示
新增功能:
- 创建 SpellDisplay 工具类,统一管理法术显示逻辑
- 支持 14 种计算方式的中文说明显示
- 显示品质特定的基础伤害/治疗倍数
- 增强 Battle.php 中所有法术施放方法的信息显示
改进内容:
- castDamageSingleSpell: 显示计算方式、消耗、伤害倍数
- castDamageAoeSpell: 显示计算方式、消耗
- castHealSingleSpell: 显示计算方式、消耗
- castHealAoeSpell: 显示计算方式、消耗
- castSupportSpell: 显示品质颜色和消耗
技术细节:
- ItemDisplay.php 添加 getQualityIndex() 辅助方法
- SpellDisplay.php 修复 match 表达式语法(改用 if-elseif)
- 使用质量索引访问品质相关数组
- 显示强化后的实际消耗
🧙 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
9d9af5f96c
commit
c065e19113
|
|
@ -275,6 +275,51 @@ class ItemDisplay
|
|||
|
||||
$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 . " ");
|
||||
|
|
@ -362,4 +407,18 @@ class ItemDisplay
|
|||
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
380
src/Core/SpellDisplay.php
Normal file
380
src/Core/SpellDisplay.php
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
<?php
|
||||
namespace Game\Core;
|
||||
|
||||
/**
|
||||
* 法术显示工具类 - 统一管理法术信息的展示
|
||||
*/
|
||||
class SpellDisplay
|
||||
{
|
||||
// 法术类型名称
|
||||
private static array $typeNames = [
|
||||
'heal_single' => '单体治疗',
|
||||
'damage_single' => '单体伤害',
|
||||
'damage_aoe' => '群体伤害',
|
||||
'heal_aoe' => '群体治疗',
|
||||
'support' => '辅助',
|
||||
];
|
||||
|
||||
// 计算方式说明
|
||||
private static array $calcTypeDescriptions = [
|
||||
'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' => '基于队伍规模',
|
||||
];
|
||||
|
||||
// 品质颜色
|
||||
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 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;
|
||||
private static string $magenta = Colors::MAGENTA;
|
||||
private static string $blue = Colors::BLUE;
|
||||
|
||||
/**
|
||||
* 获取法术品质颜色
|
||||
*/
|
||||
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] ?? $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取计算方式描述
|
||||
*/
|
||||
public static function getCalcTypeDescription(string $calcType): string
|
||||
{
|
||||
return self::$calcTypeDescriptions[$calcType] ?? $calcType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化法术名称(带品质颜色和等级)
|
||||
*/
|
||||
public static function formatName(array $spell): string
|
||||
{
|
||||
$quality = $spell['quality'] ?? 'common';
|
||||
$color = self::getQualityColor($quality);
|
||||
$name = $spell['name'] ?? '未知法术';
|
||||
$level = $spell['level'] ?? 1;
|
||||
|
||||
$enhanceLevel = $spell['enhanceLevel'] ?? 0;
|
||||
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
|
||||
|
||||
return $color . $name . self::$reset . " Lv.{$level}" . $enhanceStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化法术简要信息(用于列表)
|
||||
*/
|
||||
public static function renderListItem(array $spell): string
|
||||
{
|
||||
$parts = [];
|
||||
|
||||
// 名称(带品质颜色和强化)
|
||||
$parts[] = self::formatName($spell);
|
||||
|
||||
// 法术类型
|
||||
$spellType = $spell['spellType'] ?? $spell['type'] ?? 'unknown';
|
||||
$typeName = self::getTypeName($spellType);
|
||||
$parts[] = self::$gray . "[{$typeName}]" . self::$reset;
|
||||
|
||||
// 消耗和基本描述
|
||||
$cost = $spell['cost'] ?? 0;
|
||||
$parts[] = self::$cyan . "消耗:{$cost}" . self::$reset;
|
||||
|
||||
return implode(" ", $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化法术详细信息(用于详情面板)
|
||||
* 返回多行数组
|
||||
*/
|
||||
public static function renderDetail(array $spell, string $linePrefix = "║ "): array
|
||||
{
|
||||
$lines = [];
|
||||
|
||||
$quality = $spell['quality'] ?? 'common';
|
||||
$qualityColor = self::getQualityColor($quality);
|
||||
$qualityName = self::getQualityName($quality);
|
||||
|
||||
$spellType = $spell['spellType'] ?? $spell['type'] ?? 'unknown';
|
||||
$typeName = self::getTypeName($spellType);
|
||||
|
||||
$calcType = $spell['calc_type'] ?? 'unknown';
|
||||
$calcTypeDesc = self::getCalcTypeDescription($calcType);
|
||||
|
||||
$enhanceLevel = $spell['enhanceLevel'] ?? 0;
|
||||
$spellId = $spell['spellId'] ?? 'unknown';
|
||||
|
||||
// 名称行
|
||||
$lines[] = $linePrefix . self::formatName($spell);
|
||||
$lines[] = $linePrefix;
|
||||
|
||||
// 基本信息
|
||||
$lines[] = $linePrefix . "品质: " . $qualityColor . $qualityName . self::$reset;
|
||||
$lines[] = $linePrefix . "类型: " . self::$white . $typeName . self::$reset;
|
||||
$lines[] = $linePrefix . "法术ID: " . self::$gray . $spellId . self::$reset;
|
||||
$lines[] = $linePrefix;
|
||||
|
||||
// 强化信息
|
||||
if ($enhanceLevel > 0) {
|
||||
$damageBonus = $enhanceLevel * 5;
|
||||
$costReduction = $enhanceLevel * 2;
|
||||
$lines[] = $linePrefix . "强化: " . self::$yellow . "+{$enhanceLevel}" . self::$reset .
|
||||
self::$gray . " (伤害+{$damageBonus}% 消耗-{$costReduction})" . self::$reset;
|
||||
$lines[] = $linePrefix;
|
||||
}
|
||||
|
||||
// 计算方式
|
||||
$lines[] = $linePrefix . self::$cyan . "━━ 基础数值 ━━" . self::$reset;
|
||||
$lines[] = $linePrefix . "计算方式: " . self::$green . $calcTypeDesc . self::$reset;
|
||||
|
||||
// 根据法术类型显示不同的基础数值
|
||||
if ($spellType === 'heal_single' || $spellType === 'heal_aoe') {
|
||||
$lines[] = self::formatHealValues($spell, $linePrefix, $enhanceLevel);
|
||||
} elseif ($spellType === 'damage_single' || $spellType === 'damage_aoe') {
|
||||
$lines[] = self::formatDamageValues($spell, $linePrefix, $enhanceLevel);
|
||||
}
|
||||
|
||||
$lines[] = $linePrefix;
|
||||
|
||||
// 消耗信息
|
||||
$baseCost = $spell['cost'] ?? 20;
|
||||
$actualCost = max(1, $baseCost - ($enhanceLevel * 2));
|
||||
if ($enhanceLevel > 0) {
|
||||
$lines[] = $linePrefix . "魔法消耗: " . self::$white . $baseCost . self::$reset .
|
||||
" → " . self::$green . $actualCost . self::$reset;
|
||||
} else {
|
||||
$lines[] = $linePrefix . "魔法消耗: " . self::$green . $baseCost . self::$reset;
|
||||
}
|
||||
$lines[] = $linePrefix;
|
||||
|
||||
// 描述
|
||||
$desc = $spell['desc'] ?? '';
|
||||
if ($desc) {
|
||||
$lines[] = $linePrefix . self::$gray . $desc . self::$reset;
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化治疗法术的基础数值
|
||||
*/
|
||||
private static function formatHealValues(array $spell, string $linePrefix, int $enhanceLevel): string
|
||||
{
|
||||
$calcType = $spell['calc_type'] ?? 'matk';
|
||||
$healRatio = $spell['heal_ratio'] ?? [0.5, 0.8, 1.2, 1.8];
|
||||
$healBase = $spell['heal_base'] ?? [20, 40, 70, 120];
|
||||
|
||||
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
|
||||
$ratio = $healRatio[$qualityIndex] ?? 0.5;
|
||||
$base = $healBase[$qualityIndex] ?? 20;
|
||||
|
||||
$lines = "";
|
||||
|
||||
match($calcType) {
|
||||
'matk' => $lines = self::formatMatkHeal($ratio, $base, $linePrefix, $enhanceLevel),
|
||||
'hp_percent' => $lines = self::formatHpPercentHeal($ratio, $linePrefix),
|
||||
'hybrid' => $lines = self::formatHybridHeal($ratio, $base, $linePrefix, $enhanceLevel),
|
||||
'hp_missing' => $lines = self::formatHpMissingHeal($ratio, $linePrefix),
|
||||
'crit_heal' => $lines = self::formatCritHeal($ratio, $base, $spell['crit_bonus'] ?? [0.5, 0.7, 1.0, 1.5], $linePrefix, $enhanceLevel),
|
||||
'defense' => $lines = self::formatDefenseHeal($ratio, $base, $linePrefix, $enhanceLevel),
|
||||
default => $lines = $linePrefix . "基础治疗: " . self::$green . "{$ratio}x魔攻 + {$base}" . self::$reset,
|
||||
};
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化伤害法术的基础数值
|
||||
*/
|
||||
private static function formatDamageValues(array $spell, string $linePrefix, int $enhanceLevel): string
|
||||
{
|
||||
$calcType = $spell['calc_type'] ?? 'matk';
|
||||
$damageRatio = $spell['damage_ratio'] ?? [1.2, 1.6, 2.0, 2.6];
|
||||
|
||||
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
|
||||
$ratio = $damageRatio[$qualityIndex] ?? 1.2;
|
||||
|
||||
if ($calcType === 'matk') {
|
||||
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x魔攻" . self::$reset;
|
||||
} elseif ($calcType === 'patk') {
|
||||
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x物攻" . self::$reset;
|
||||
} elseif ($calcType === 'hybrid') {
|
||||
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x(魔攻+物攻)" . self::$reset;
|
||||
} elseif ($calcType === 'crit_damage') {
|
||||
$critBonus = $spell['crit_dmg_bonus'] ?? [0.3, 0.5, 0.8, 1.2];
|
||||
$bonus = $critBonus[$qualityIndex] ?? 0.3;
|
||||
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x物攻" . self::$reset . "\n" .
|
||||
$linePrefix . "暴击加成: " . self::$yellow . "{$bonus}x暴伤系数" . self::$reset;
|
||||
} elseif ($calcType === 'low_def_bonus') {
|
||||
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x物攻(低防御加成)" . self::$reset;
|
||||
} elseif ($calcType === 'matk_scaled') {
|
||||
$enemyBonus = $spell['enemy_count_bonus'] ?? [0.1, 0.15, 0.2, 0.3];
|
||||
$bonus = $enemyBonus[$qualityIndex] ?? 0.1;
|
||||
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x魔攻" . self::$reset . "\n" .
|
||||
$linePrefix . "敌人数加成: " . self::$yellow . "+" . ($bonus*100) . "%/敌人" . self::$reset;
|
||||
} elseif ($calcType === 'dispersed_damage') {
|
||||
$dispersion = $spell['dispersion'] ?? [0.8, 0.75, 0.7, 0.65];
|
||||
$disp = $dispersion[$qualityIndex] ?? 0.8;
|
||||
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x魔攻" . self::$reset . "\n" .
|
||||
$linePrefix . "分散系数: " . self::$yellow . "{$disp}(敌人越多衰减越严重)" . self::$reset;
|
||||
} elseif ($calcType === 'crit_aoe') {
|
||||
$critBonus = $spell['crit_bonus'] ?? [0.4, 0.6, 0.9, 1.3];
|
||||
$bonus = $critBonus[$qualityIndex] ?? 0.4;
|
||||
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x魔攻" . self::$reset . "\n" .
|
||||
$linePrefix . "暴击影响: " . self::$yellow . "{$bonus}x暴击率" . self::$reset;
|
||||
}
|
||||
|
||||
return $linePrefix . "伤害倍数: " . self::$green . "{$ratio}x" . self::$reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化魔攻治疗
|
||||
*/
|
||||
private static function formatMatkHeal(float $ratio, float $base, string $linePrefix, int $enhanceLevel): string
|
||||
{
|
||||
$healBonus = $enhanceLevel * 5;
|
||||
if ($enhanceLevel > 0) {
|
||||
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x魔攻 + {$base}" . self::$reset .
|
||||
" " . self::$yellow . "(+{$healBonus}%)" . self::$reset;
|
||||
}
|
||||
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x魔攻 + {$base}" . self::$reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化生命值百分比治疗
|
||||
*/
|
||||
private static function formatHpPercentHeal(float $ratio, string $linePrefix): string
|
||||
{
|
||||
return $linePrefix . "恢复量: " . self::$green . ($ratio * 100) . "% 最大生命值" . self::$reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化混合治疗
|
||||
*/
|
||||
private static function formatHybridHeal(float $ratio, float $base, string $linePrefix, int $enhanceLevel): string
|
||||
{
|
||||
$healBonus = $enhanceLevel * 5;
|
||||
if ($enhanceLevel > 0) {
|
||||
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x(魔攻+物攻) + {$base}" . self::$reset .
|
||||
" " . self::$yellow . "(+{$healBonus}%)" . self::$reset;
|
||||
}
|
||||
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x(魔攻+物攻) + {$base}" . self::$reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化缺失生命值治疗
|
||||
*/
|
||||
private static function formatHpMissingHeal(float $ratio, string $linePrefix): string
|
||||
{
|
||||
return $linePrefix . "恢复量: " . self::$green . ($ratio * 100) . "% 缺失生命值" . self::$reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化暴击治疗
|
||||
*/
|
||||
private static function formatCritHeal(float $ratio, float $base, array $critBonus, string $linePrefix, int $enhanceLevel): string
|
||||
{
|
||||
$qualityIndex = self::getQualityIndex(0);
|
||||
$bonus = $critBonus[$qualityIndex] ?? 0.5;
|
||||
$healBonus = $enhanceLevel * 5;
|
||||
$result = $linePrefix . "恢复量: " . self::$green . "{$ratio}x魔攻 + {$base}" . self::$reset;
|
||||
$result .= "\n" . $linePrefix . "暴击系数: " . self::$yellow . "{$bonus}x暴击率加成" . self::$reset;
|
||||
if ($enhanceLevel > 0) {
|
||||
$result .= "\n" . $linePrefix . "强化加成: " . self::$yellow . "+{$healBonus}%" . self::$reset;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化防御治疗
|
||||
*/
|
||||
private static function formatDefenseHeal(float $ratio, float $base, string $linePrefix, int $enhanceLevel): string
|
||||
{
|
||||
$healBonus = $enhanceLevel * 5;
|
||||
if ($enhanceLevel > 0) {
|
||||
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x(物防+魔防) + {$base}" . self::$reset .
|
||||
" " . self::$yellow . "(+{$healBonus}%)" . self::$reset;
|
||||
}
|
||||
return $linePrefix . "恢复量: " . self::$green . "{$ratio}x(物防+魔防) + {$base}" . self::$reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据品质获取数组索引
|
||||
*/
|
||||
private static function getQualityIndex(string $quality): int
|
||||
{
|
||||
return match($quality) {
|
||||
'common' => 0,
|
||||
'rare' => 1,
|
||||
'epic' => 2,
|
||||
'legendary' => 3,
|
||||
default => 0,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染战斗中的法术简洁信息
|
||||
*/
|
||||
public static function renderBattleInfo(array $spell, string $prefix = " "): string
|
||||
{
|
||||
$quality = $spell['quality'] ?? 'common';
|
||||
$color = self::getQualityColor($quality);
|
||||
$name = $spell['name'] ?? '未知法术';
|
||||
$cost = $spell['cost'] ?? 20;
|
||||
$enhanceLevel = $spell['enhanceLevel'] ?? 0;
|
||||
$calcType = $spell['calc_type'] ?? 'unknown';
|
||||
$calcDesc = self::getCalcTypeDescription($calcType);
|
||||
|
||||
$enhanceStr = $enhanceLevel > 0 ? self::$yellow . "+{$enhanceLevel}" . self::$reset : "";
|
||||
|
||||
return $prefix . $color . $name . self::$reset . $enhanceStr .
|
||||
" [消耗:{$cost} {$calcDesc}]";
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ use Game\Core\Game;
|
|||
use Game\Core\Input;
|
||||
use Game\Core\Screen;
|
||||
use Game\Core\ItemDisplay;
|
||||
use Game\Core\SpellDisplay;
|
||||
use Game\Core\Colors;
|
||||
use Game\Entities\Player;
|
||||
use Game\Entities\Actor;
|
||||
|
|
@ -387,7 +388,7 @@ class Battle
|
|||
// 消耗魔法值
|
||||
$this->player->spendMana($actualCost);
|
||||
|
||||
// 计算强化加成: 每级 +5% 伤害
|
||||
// 计算强化加成: 每级 +5% 伤害或治疗
|
||||
$damageBonus = $enhanceLevel * 5;
|
||||
|
||||
$type = $spellItem['spellType'] ?? 'damage_single';
|
||||
|
|
@ -401,7 +402,12 @@ class Battle
|
|||
return $this->castDamageSingleSpell($out, 0, $spellInfo, $stats, $damageBonus, $name);
|
||||
} elseif ($type === 'damage_aoe') {
|
||||
return $this->castDamageAoeSpell($out, 0, $spellInfo, $stats, $damageBonus, $name);
|
||||
} elseif ($type === 'heal_single') {
|
||||
return $this->castHealSingleSpell($out, $spellInfo, $stats, $damageBonus, $name);
|
||||
} elseif ($type === 'heal_aoe') {
|
||||
return $this->castHealAoeSpell($out, $spellInfo, $stats, $damageBonus, $name);
|
||||
} elseif ($type === 'support') {
|
||||
// 兼容旧版本的 support 类型
|
||||
return $this->castSupportSpell($out, $spellInfo, $stats, $name);
|
||||
}
|
||||
|
||||
|
|
@ -424,8 +430,16 @@ class Battle
|
|||
|
||||
if (!$target) return true;
|
||||
|
||||
// 显示法术基础信息
|
||||
$calcType = $spellInfo['calc_type'] ?? 'matk';
|
||||
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
|
||||
$cost = $spellInfo['cost'] ?? 20;
|
||||
$actualCost = max(1, $cost - (($spellInfo['enhanceLevel'] ?? 0) * 2));
|
||||
$quality = $spellInfo['quality'] ?? 'common';
|
||||
$qualityColor = SpellDisplay::getQualityColor($quality);
|
||||
|
||||
// 计算法术伤害
|
||||
$baseDamageMultiplier = $spellInfo['damage'] ?? 1.0;
|
||||
$baseDamageMultiplier = $spellInfo['damage_ratio'][$this->getQualityIndex($quality)] ?? ($spellInfo['damage'] ?? 1.0);
|
||||
$actualDamageMultiplier = $baseDamageMultiplier * (1 + $damageBonus / 100);
|
||||
$baseDamage = (int)($stats['matk'] * $actualDamageMultiplier);
|
||||
|
||||
|
|
@ -437,14 +451,16 @@ class Battle
|
|||
$critRate = $stats['crit'];
|
||||
$isCrit = rand(1, 100) <= $critRate;
|
||||
|
||||
// 显示法术施放信息
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✦{$this->reset} 你施放 {$qualityColor}{$name}{$this->reset}");
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost} | 倍数: {$baseDamageMultiplier}x{$this->reset}");
|
||||
|
||||
if ($isCrit) {
|
||||
$critDmg = $stats['critdmg'];
|
||||
$damage = (int)($damage * ($critDmg / 100));
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✦{$this->reset} 你施放 {$name}... {$this->red}{$this->bold}暴击!{$this->reset}");
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✨ 造成 {$damage} 点魔法伤害!{$this->reset}");
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✨ {$this->red}{$this->bold}暴击!{$this->reset} 造成 {$this->red}{$damage}{$this->reset} 点魔法伤害!");
|
||||
} else {
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✦{$this->reset} 你施放 {$name}...");
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✨ 造成 {$damage} 点魔法伤害{$this->reset}");
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✨ 造成 {$this->green}{$damage}{$this->reset} 点魔法伤害");
|
||||
}
|
||||
|
||||
$target->hp -= $damage;
|
||||
|
|
@ -468,11 +484,20 @@ class Battle
|
|||
*/
|
||||
private function castDamageAoeSpell($out, int $spellId, array $spellInfo, array $stats, int $damageBonus, string $name): bool
|
||||
{
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✦{$this->reset} 你施放 {$name}...");
|
||||
// 显示法术基础信息
|
||||
$calcType = $spellInfo['calc_type'] ?? 'matk';
|
||||
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
|
||||
$cost = $spellInfo['cost'] ?? 20;
|
||||
$actualCost = max(1, $cost - (($spellInfo['enhanceLevel'] ?? 0) * 2));
|
||||
$quality = $spellInfo['quality'] ?? 'common';
|
||||
$qualityColor = SpellDisplay::getQualityColor($quality);
|
||||
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✦{$this->reset} 你施放 {$qualityColor}{$name}{$this->reset}");
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost}{$this->reset}");
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✨ 魔法在整个战场爆炸!{$this->reset}");
|
||||
|
||||
// 计算法术伤害
|
||||
$baseDamageMultiplier = $spellInfo['damage'] ?? 0.8;
|
||||
$baseDamageMultiplier = $spellInfo['damage_ratio'][$this->getQualityIndex($quality)] ?? ($spellInfo['damage'] ?? 0.8);
|
||||
$actualDamageMultiplier = $baseDamageMultiplier * (1 + $damageBonus / 100);
|
||||
|
||||
$allEnemiesDefeated = true;
|
||||
|
|
@ -511,13 +536,90 @@ class Battle
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 施放单体治疗法术
|
||||
*/
|
||||
private function castHealSingleSpell($out, array $spellInfo, array $stats, int $healBonus, string $name): bool
|
||||
{
|
||||
// 显示法术基础信息
|
||||
$calcType = $spellInfo['calc_type'] ?? 'matk';
|
||||
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
|
||||
$cost = $spellInfo['cost'] ?? 20;
|
||||
$quality = $spellInfo['quality'] ?? 'common';
|
||||
$qualityColor = SpellDisplay::getQualityColor($quality);
|
||||
$actualCost = max(1, $cost - (($spellInfo['enhanceLevel'] ?? 0) * 2));
|
||||
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->green}✦{$this->reset} 你施放 {$qualityColor}{$name}{$this->reset}");
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost}{$this->reset}");
|
||||
|
||||
$heal = $spellInfo['heal'] ?? 0.5;
|
||||
$healBase = $spellInfo['heal_base'] ?? 20;
|
||||
$healAmount = (int)($stats['matk'] * $heal + $healBase);
|
||||
|
||||
// 应用治疗加成
|
||||
$healAmount = (int)($healAmount * (1 + $healBonus / 100));
|
||||
|
||||
$actualHeal = $this->player->heal($healAmount);
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->green}💚 恢复了 {$actualHeal} 点生命值{$this->reset}");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 施放群体治疗法术
|
||||
*/
|
||||
private function castHealAoeSpell($out, array $spellInfo, array $stats, int $healBonus, string $name): bool
|
||||
{
|
||||
// 显示法术基础信息
|
||||
$calcType = $spellInfo['calc_type'] ?? 'matk';
|
||||
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
|
||||
$cost = $spellInfo['cost'] ?? 20;
|
||||
$quality = $spellInfo['quality'] ?? 'common';
|
||||
$qualityColor = SpellDisplay::getQualityColor($quality);
|
||||
$actualCost = max(1, $cost - (($spellInfo['enhanceLevel'] ?? 0) * 2));
|
||||
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->green}✦{$this->reset} 你施放 {$qualityColor}{$name}{$this->reset}");
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost}{$this->reset}");
|
||||
|
||||
$heal = $spellInfo['heal'] ?? 0.5;
|
||||
$healBase = $spellInfo['heal_base'] ?? 20;
|
||||
$healAmount = (int)($stats['matk'] * $heal + $healBase);
|
||||
|
||||
// 应用治疗加成
|
||||
$healAmount = (int)($healAmount * (1 + $healBonus / 100));
|
||||
|
||||
$actualHeal = $this->player->heal($healAmount);
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->green}💚 你恢复了 {$actualHeal} 点生命值{$this->reset}");
|
||||
|
||||
// 同伴也恢复
|
||||
$alivePartners = $this->getAlivePartners();
|
||||
foreach ($alivePartners as $partner) {
|
||||
$partnerHeal = (int)($healAmount * 0.8); // 同伴恢复量为玩家的80%
|
||||
$actualPartnerHeal = $partner->heal($partnerHeal);
|
||||
$this->partnerHp[$partner->id] = $partner->hp;
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->green}💚 {$partner->name} 恢复了 {$actualPartnerHeal} 点生命值{$this->reset}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 施放辅助法术
|
||||
*/
|
||||
private function castSupportSpell($out, array $spellInfo, array $stats, string $name): bool
|
||||
{
|
||||
// 显示法术基础信息
|
||||
$quality = $spellInfo['quality'] ?? 'common';
|
||||
$qualityColor = SpellDisplay::getQualityColor($quality);
|
||||
$cost = $spellInfo['cost'] ?? 20;
|
||||
$actualCost = max(1, $cost - (($spellInfo['enhanceLevel'] ?? 0) * 2));
|
||||
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->cyan}✦{$this->reset} 你施放 {$qualityColor}{$name}{$this->reset}");
|
||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->white}消耗: {$actualCost}{$this->reset}");
|
||||
|
||||
$subtype = $spellInfo['subtype'] ?? '';
|
||||
|
||||
|
||||
if ($subtype === 'heal' || $subtype === 'heal_all') {
|
||||
if ($subtype === 'heal') {
|
||||
// 恢复自己
|
||||
|
|
@ -624,35 +726,17 @@ class Battle
|
|||
}
|
||||
|
||||
/**
|
||||
* 生成法术物品掉落 (新法术系统)
|
||||
* 根据品质获取数组索引
|
||||
*/
|
||||
private function generateSpellDrop(Actor $enemy): ?array
|
||||
private function getQualityIndex(string $quality): int
|
||||
{
|
||||
// 尝试从独立的副本法术映射文件获取(每个副本有自己的法术池)
|
||||
$dungeonId = $this->game->dungeonId;
|
||||
$spellIds = null;
|
||||
|
||||
$dungeonSpellFile = __DIR__ . '/../../src/Data/dungeon_spells.php';
|
||||
if (file_exists($dungeonSpellFile)) {
|
||||
$dungeonMap = require $dungeonSpellFile;
|
||||
$spellIds = $dungeonMap[$dungeonId] ?? null;
|
||||
}
|
||||
|
||||
// 回退到全局配置里的 dungeon_spell_drops
|
||||
if (empty($spellIds)) {
|
||||
$dungeonSpellDrops = $this->spellsData['dungeon_spell_drops'] ?? [];
|
||||
$spellIds = $dungeonSpellDrops[$dungeonId] ?? null;
|
||||
}
|
||||
|
||||
if (empty($spellIds) || !is_array($spellIds)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 从法术池中随机选择一个法术ID
|
||||
$spellId = $spellIds[array_rand($spellIds)];
|
||||
|
||||
// 使用 Item::createSpell 创建法术物品
|
||||
return \Game\Entities\Item::createSpell($spellId, $enemy->level);
|
||||
return match($quality) {
|
||||
'common' => 0,
|
||||
'rare' => 1,
|
||||
'epic' => 2,
|
||||
'legendary' => 3,
|
||||
default => 0,
|
||||
};
|
||||
}
|
||||
|
||||
private function playerAttack($out): bool
|
||||
|
|
@ -856,27 +940,25 @@ class Battle
|
|||
$totalExp += $enemy->expReward;
|
||||
$totalStones += $enemy->spiritStoneReward;
|
||||
|
||||
// 掉落 - 从怪物穿着的装备随机掉落
|
||||
// 掉落 - 从怪物穿着的装备随机掉落(50%概率)
|
||||
foreach ($enemy->getRandomEquipmentDrops(50) as $item) {
|
||||
$this->player->addItem($item);
|
||||
$allDrops[] = $item;
|
||||
}
|
||||
|
||||
// 掉落 - 从怪物穿着的法术随机掉落(50%概率)
|
||||
foreach ($enemy->getRandomSpellDrops(50) as $spell) {
|
||||
$this->player->addItem($spell);
|
||||
$allDrops[] = $spell;
|
||||
}
|
||||
|
||||
// 掉落 - 从掉落表中随机掉落物品
|
||||
foreach ($enemy->dropTable as $drop) {
|
||||
if (rand(1, 100) <= $drop['rate']) {
|
||||
$this->player->addItem($drop['item']);
|
||||
$allDrops[] = $drop['item'];
|
||||
}
|
||||
}
|
||||
|
||||
// 掉落法术物品 (新法术系统)
|
||||
$spellDropChance = 15; // 15% 概率掉落法术
|
||||
if (rand(1, 100) <= $spellDropChance && !empty($this->spellsData)) {
|
||||
$spellItem = $this->generateSpellDrop($enemy);
|
||||
if ($spellItem) {
|
||||
$this->player->addItem($spellItem);
|
||||
$allDrops[] = $spellItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 经验
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user