This commit is contained in:
hant 2025-12-06 20:52:40 +08:00
parent cd020e1240
commit 6aedb96342
8 changed files with 525 additions and 323 deletions

File diff suppressed because one or more lines are too long

View File

@ -25,11 +25,14 @@ class SpellDisplay
'crit_damage' => '暴击伤害系数影响伤害', 'crit_damage' => '暴击伤害系数影响伤害',
'crit_aoe' => '暴击率影响范围伤害', 'crit_aoe' => '暴击率影响范围伤害',
'defense' => '基于防御属性', 'defense' => '基于防御属性',
'low_def_bonus' => '对低防御敌人伤害加成', 'def_pierce' => '防御穿透伤害',
'matk_scaled' => '随敌人数量加成', 'status_bonus' => '目标状态加成伤害',
'enemy_count_bonus' => '敌人数量加成伤害',
'dispersed_damage' => '伤害分散到所有敌人', 'dispersed_damage' => '伤害分散到所有敌人',
'smart_heal' => '智能治疗(优先低血量)', 'smart_heal' => '智能治疗(优先低血量)',
'hp_missing' => '基于缺失生命值', 'hp_missing' => '基于缺失生命值',
'low_def_bonus' => '对低防御敌人伤害加成',
'matk_scaled' => '随敌人数量加成',
'team_sync' => '基于队伍规模', 'team_sync' => '基于队伍规模',
]; ];
@ -122,9 +125,33 @@ class SpellDisplay
$typeName = self::getTypeName($spellType); $typeName = self::getTypeName($spellType);
$parts[] = self::$gray . "[{$typeName}]" . self::$reset; $parts[] = self::$gray . "[{$typeName}]" . self::$reset;
// 消耗和基本描述 // 计算方式
$calcType = $spell['calc_type'] ?? 'matk';
$calcDesc = self::getCalcTypeDescription($calcType);
$parts[] = self::$cyan . "{$calcDesc}" . self::$reset;
// 基础值
if ($spellType === 'damage_single' || $spellType === 'damage_aoe') {
$base = $spell['base'] ?? [5, 12, 25, 45];
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
$baseValue = $base[$qualityIndex] ?? 5;
$parts[] = self::$yellow . "基础:{$baseValue}" . self::$reset;
} elseif ($spellType === 'heal_single' || $spellType === 'heal_aoe') {
$base = $spell['base'] ?? [8, 18, 38, 65];
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
$baseValue = $base[$qualityIndex] ?? 8;
$parts[] = self::$yellow . "基础:{$baseValue}" . self::$reset;
}
// 消耗
$cost = $spell['cost'] ?? 0; $cost = $spell['cost'] ?? 0;
$parts[] = self::$cyan . "消耗:{$cost}" . self::$reset; $enhanceLevel = $spell['enhanceLevel'] ?? 0;
$actualCost = max(1, $cost - ($enhanceLevel * 2));
if ($enhanceLevel > 0) {
$parts[] = self::$cyan . "消耗:{$actualCost}(原:{$cost})" . self::$reset;
} else {
$parts[] = self::$cyan . "消耗:{$cost}" . self::$reset;
}
return implode(" ", $parts); return implode(" ", $parts);
} }
@ -424,9 +451,10 @@ class SpellDisplay
// 第一行:槽位名 + 法术名 // 第一行:槽位名 + 法术名
$lines[] = $linePrefix . self::$cyan . $slotName . self::$reset . ": " . self::formatName($spell); $lines[] = $linePrefix . self::$cyan . $slotName . self::$reset . ": " . self::formatName($spell);
// 计算方式 // 计算方式和法术类型
$calcType = $spell['calc_type'] ?? 'matk'; $calcType = $spell['calc_type'] ?? 'matk';
$spellType = $spell['spellType'] ?? $spell['type'] ?? 'unknown'; $spellType = $spell['spellType'] ?? $spell['type'] ?? 'unknown';
$typeName = self::getTypeName($spellType);
// 计算方式的完整描述 // 计算方式的完整描述
$calcTypeDescMap = [ $calcTypeDescMap = [
@ -437,6 +465,9 @@ class SpellDisplay
'crit_heal' => '暴击治疗', 'crit_heal' => '暴击治疗',
'crit_damage' => '暴击伤害', 'crit_damage' => '暴击伤害',
'defense' => '基于防御', 'defense' => '基于防御',
'def_pierce' => '防御穿透',
'status_bonus' => '状态加成',
'enemy_count_bonus' => '敌人加成',
'low_def_bonus' => '克低防', 'low_def_bonus' => '克低防',
'matk_scaled' => '群体伤害', 'matk_scaled' => '群体伤害',
'dispersed_damage' => '分散伤害', 'dispersed_damage' => '分散伤害',
@ -447,16 +478,33 @@ class SpellDisplay
]; ];
$calcDesc = $calcTypeDescMap[$calcType] ?? $calcType; $calcDesc = $calcTypeDescMap[$calcType] ?? $calcType;
$lines[] = $linePrefix . " " . self::$white . "计算: " . self::$green . $calcDesc . self::$reset; $lines[] = $linePrefix . " " . self::$white . "类型: " . self::$magenta . $typeName . self::$reset .
self::$white . " | 计算: " . self::$green . $calcDesc . self::$reset;
// 显示基础数值 // 显示基础数值和倍数
if ($spellType === 'damage_single' || $spellType === 'damage_aoe') { if ($spellType === 'damage_single' || $spellType === 'damage_aoe') {
$ratio = $spell['damage_ratio']; $ratio = $spell['damage_ratio'];
$lines[] = $linePrefix . " " . self::$white . "倍数: " . self::$yellow . "x{$ratio}" . self::$reset; $base = $spell['base'] ?? [5, 12, 25, 45];
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
$baseValue = $base[$qualityIndex] ?? 5;
$lines[] = $linePrefix . " " . self::$white . "倍数: " . self::$yellow . "x{$ratio}" . self::$reset .
self::$white . " | 基础值: " . self::$yellow . "{$baseValue}" . self::$reset;
} elseif ($spellType === 'heal_single' || $spellType === 'heal_aoe') { } elseif ($spellType === 'heal_single' || $spellType === 'heal_aoe') {
$ratio = $spell['heal_ratio']; $ratio = $spell['heal_ratio'];
$base = $spell['heal_base']; $healBase = $spell['heal_base'] ?? null;
$lines[] = $linePrefix . " " . self::$white . "治疗: " . self::$yellow . "x{$ratio} + {$base}" . self::$reset; $base = $spell['base'] ?? [8, 18, 38, 65];
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
$baseValue = $base[$qualityIndex] ?? 8;
if ($healBase) {
$healBaseValue = $healBase[$qualityIndex] ?? 20;
$lines[] = $linePrefix . " " . self::$white . "倍数: " . self::$yellow . "x{$ratio}" . self::$reset .
self::$white . " | 基数: " . self::$yellow . "{$healBaseValue}" . self::$reset .
self::$white . " | 基础: " . self::$yellow . "{$baseValue}" . self::$reset;
} else {
$lines[] = $linePrefix . " " . self::$white . "倍数: " . self::$yellow . "x{$ratio}" . self::$reset .
self::$white . " | 基础值: " . self::$yellow . "{$baseValue}" . self::$reset;
}
} }
// 显示消耗 // 显示消耗
@ -464,7 +512,9 @@ class SpellDisplay
$enhanceLevel = $spell['enhanceLevel'] ?? 0; $enhanceLevel = $spell['enhanceLevel'] ?? 0;
$actualCost = max(1, $cost - ($enhanceLevel * 2)); $actualCost = max(1, $cost - ($enhanceLevel * 2));
if ($enhanceLevel > 0) { if ($enhanceLevel > 0) {
$lines[] = $linePrefix . " " . self::$white . "消耗: " . self::$yellow . "{$cost}" . self::$reset . "" . self::$green . "{$actualCost}" . self::$reset; $lines[] = $linePrefix . " " . self::$white . "消耗: " . self::$yellow . "{$cost}" . self::$reset .
"" . self::$green . "{$actualCost}" . self::$reset .
self::$yellow . " +{$enhanceLevel}" . self::$reset;
} else { } else {
$lines[] = $linePrefix . " " . self::$white . "消耗: " . self::$green . "{$actualCost}" . self::$reset; $lines[] = $linePrefix . " " . self::$white . "消耗: " . self::$green . "{$actualCost}" . self::$reset;
} }

View File

@ -277,7 +277,7 @@ return [
'spells' => [ 'spells' => [
['id' => 10, 'name' => '炎火术', 'rate' => 20, 'quality' => 'common', 'base' => 5, 'growth' => 0.6] + $fireSpellTemplate, ['id' => 10, 'name' => '炎火术', 'rate' => 20, 'quality' => 'common', 'base' => 5, 'growth' => 0.6] + $fireSpellTemplate,
['id' => 11, 'name' => '冰魄术', 'rate' => 25, 'quality' => 'rare', 'base' => 10, 'growth' => 0.7] + $iceSpellTemplate, ['id' => 11, 'name' => '冰魄术', 'rate' => 25, 'quality' => 'rare', 'base' => 10, 'growth' => 0.7] + $iceSpellTemplate,
['id' => 12, 'name' => '雷刹术', 'rate' => 15, 'quality' => 'rare', 'base' => 14, 'growth' => 0.9] + $thunderSpellTemplate, ['id' => 12, 'name' => '雷刹术', 'rate' => 25, 'quality' => 'rare', 'base' => 14, 'growth' => 0.9] + $thunderSpellTemplate,
['id' => 20, 'name' => '冰暴术', 'rate' => 20, 'quality' => 'rare', 'base' => 10, 'growth' => 0.7] + $iceSpellTemplate, ['id' => 20, 'name' => '冰暴术', 'rate' => 20, 'quality' => 'rare', 'base' => 10, 'growth' => 0.7] + $iceSpellTemplate,
], ],
'weight' => 15, 'weight' => 15,

View File

@ -25,15 +25,16 @@ return [
'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数 'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数
], ],
// 2. 及时救难 - 生命值百分比型 (恢复 = 自己最大生命值 × 百分比) // 2. 强击疗法 - 物攻型 (恢复 = 物攻 × 倍数 + 基础值)
2 => [ 2 => [
'name' => '及时救难', 'name' => '强击疗法',
'type' => 'heal_single', 'type' => 'heal_single',
'calc_type' => 'hp_percent', // 计算方式:最大生命值百分比 'calc_type' => 'patk', // 计算方式:纯物攻
'cost' => 20, 'cost' => 18,
'level_req' => 5, 'level_req' => 3,
'desc' => '将自己的部分生命值转移给队友', 'desc' => '通过强劲的气血运行来治疗,效果与物攻相关',
'heal_ratio' => [0.3, 0.4, 0.5, 0.6], // 最大生命值百分比 'heal_ratio' => [0.4, 0.65, 0.95, 1.4], // 物攻倍数
'heal_base' => [15, 30, 55, 90], // 基础治疗值
'base' => [8, 18, 38, 65], // 基础伤害值 'base' => [8, 18, 38, 65], // 基础伤害值
'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数 'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数
], ],
@ -52,35 +53,21 @@ return [
'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数 'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数
], ],
// 4. 生命之泉 - 基于当前生命值缺口 (恢复 = 缺失血量 × 百分比) // 4. 及时救难 - 生命值百分比型 (恢复 = 自己最大生命值 × 百分比)
4 => [ 4 => [
'name' => '生命之泉', 'name' => '及时救难',
'type' => 'heal_single', 'type' => 'heal_single',
'calc_type' => 'hp_missing', // 计算方式:缺失生命值百分比 'calc_type' => 'hp_percent', // 计算方式:最大生命值百分比
'cost' => 30, 'cost' => 20,
'level_req' => 18, 'level_req' => 5,
'desc' => '根据队友缺失的生命值比例进行治疗', 'desc' => '将自己的部分生命值转移给队友',
'heal_ratio' => [0.4, 0.55, 0.7, 0.85], // 缺失生命值百分比 'heal_ratio' => [0.3, 0.4, 0.5, 0.6], // 最大生命值百分比
'base' => [8, 18, 38, 65], // 基础伤害值 'base' => [8, 18, 38, 65], // 基础伤害值
'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数 'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数
], ],
// 5. 暴击治疗 - 与暴击率相关 (恢复 = 魔攻 × 倍数 × (1 + 暴击率×特殊系数)) // 5. 援护术 - 基于防御属性 (恢复 = (物防+魔防) × 倍数 + 固定值)
5 => [ 5 => [
'name' => '暴击治疗',
'type' => 'heal_single',
'calc_type' => 'crit_heal', // 计算方式:与暴击率相关
'cost' => 28,
'level_req' => 22,
'desc' => '暴击率越高,治疗效果越强',
'heal_ratio' => [0.4, 0.65, 0.95, 1.4], // 基础魔攻倍数
'crit_bonus' => [0.5, 0.7, 1.0, 1.5], // 暴击率加成系数
'base' => [8, 18, 38, 65], // 基础伤害值
'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数
],
// 6. 援护术 - 基于防御属性 (恢复 = (物防+魔防) × 倍数 + 固定值)
6 => [
'name' => '援护术', 'name' => '援护术',
'type' => 'heal_single', 'type' => 'heal_single',
'calc_type' => 'defense', // 计算方式:基于防御属性 'calc_type' => 'defense', // 计算方式:基于防御属性
@ -92,6 +79,20 @@ return [
'base' => [8, 18, 38, 65], // 基础伤害值 'base' => [8, 18, 38, 65], // 基础伤害值
'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数 'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数
], ],
// 6. 暴击治疗 - 与暴击率相关 (恢复 = 魔攻 × 倍数 × (1 + 暴击率×特殊系数))
6 => [
'name' => '暴击治疗',
'type' => 'heal_single',
'calc_type' => 'crit_heal', // 计算方式:与暴击率相关
'cost' => 28,
'level_req' => 22,
'desc' => '暴击率越高,治疗效果越强',
'heal_ratio' => [0.4, 0.65, 0.95, 1.4], // 基础魔攻倍数
'crit_bonus' => [0.5, 0.7, 1.0, 1.5], // 暴击率加成系数
'base' => [8, 18, 38, 65], // 基础伤害值
'growth' => [0.8, 1.0, 1.2, 1.5], // 等级成长系数
],
], ],
// ============ 单体伤害法术 (damage_single) ============ // ============ 单体伤害法术 (damage_single) ============
@ -109,34 +110,21 @@ return [
'growth' => [0.6, 0.8, 1.0, 1.2], // 等级成长系数 'growth' => [0.6, 0.8, 1.0, 1.2], // 等级成长系数
], ],
// 11. 冰锥术 - 魔攻型 // 11. 剑刃风暴 - 物攻型 (伤害 = 物攻 × 倍数)
11 => [ 11 => [
'name' => '冰锥术', 'name' => '剑刃风暴',
'type' => 'damage_single',
'calc_type' => 'matk',
'cost' => 22,
'level_req' => 6,
'desc' => '凝聚寒冰之力,发出锐利冰锥',
'damage_ratio' => [1.3, 1.8, 2.2, 3.0],
'base' => [4, 10, 22, 42], // 基础伤害值
'growth' => [0.5, 0.7, 0.95, 1.15], // 等级成长系数
],
// 12. 雷击术 - 物攻型 (伤害 = 物攻 × 倍数)
12 => [
'name' => '雷击术',
'type' => 'damage_single', 'type' => 'damage_single',
'calc_type' => 'patk', 'calc_type' => 'patk',
'cost' => 24, 'cost' => 20,
'level_req' => 10, 'level_req' => 2,
'desc' => '召唤雷电直击单个敌人,与物攻相关', 'desc' => '旋转剑刃造成锋利的伤害',
'damage_ratio' => [1.4, 1.9, 2.3, 3.2], 'damage_ratio' => [1.1, 1.5, 1.9, 2.5],
'base' => [6, 14, 28, 48], // 基础伤害值 'base' => [6, 14, 28, 48], // 基础伤害值
'growth' => [0.7, 0.9, 1.1, 1.3], // 等级成长系数 'growth' => [0.7, 0.9, 1.1, 1.3], // 等级成长系数
], ],
// 13. 烈焰焚天 - 混合型 (伤害 = (魔攻 + 物攻) × 倍数) // 12. 烈焰焚天 - 混合型 (伤害 = (魔攻 + 物攻) × 倍数)
13 => [ 12 => [
'name' => '烈焰焚天', 'name' => '烈焰焚天',
'type' => 'damage_single', 'type' => 'damage_single',
'calc_type' => 'hybrid', 'calc_type' => 'hybrid',
@ -148,7 +136,21 @@ return [
'growth' => [0.6, 0.8, 1.0, 1.2], // 等级成长系数 'growth' => [0.6, 0.8, 1.0, 1.2], // 等级成长系数
], ],
// 14. 诛仙剑气 - 物攻 + 暴击型 (伤害 = 物攻 × 倍数 × (1 + 暴击伤害系数)) // 13. 冰锥术 - 防御穿透型 (伤害 = 魔攻 × 倍数 × (1 + 敌人防御缺陷系数))
13 => [
'name' => '冰锥术',
'type' => 'damage_single',
'calc_type' => 'def_pierce',
'cost' => 22,
'level_req' => 6,
'desc' => '凝聚寒冰之力穿透敌人防御',
'damage_ratio' => [1.3, 1.8, 2.2, 3.0],
'pierce_bonus' => [0.2, 0.3, 0.45, 0.6], // 防御穿透系数
'base' => [4, 10, 22, 42], // 基础伤害值
'growth' => [0.5, 0.7, 0.95, 1.15], // 等级成长系数
],
// 14. 诛仙剑气 - 暴击伤害型 (伤害 = 物攻 × 倍数 × (1 + 暴击伤害系数))
14 => [ 14 => [
'name' => '诛仙剑气', 'name' => '诛仙剑气',
'type' => 'damage_single', 'type' => 'damage_single',
@ -162,17 +164,18 @@ return [
'growth' => [0.6, 0.8, 1.0, 1.2], // 等级成长系数 'growth' => [0.6, 0.8, 1.0, 1.2], // 等级成长系数
], ],
// 15. 狂暴斩 - 低防御有加成 (伤害 = 物攻 × 倍数 × (1 + (100-敌人防御百分比)×系数)) // 15. 雷击术 - 特殊型(基于目标状态) (伤害 = 物攻 × 倍数 × (1 + 特殊加成))
15 => [ 15 => [
'name' => '狂暴斩', 'name' => '雷击术',
'type' => 'damage_single', 'type' => 'damage_single',
'calc_type' => 'low_def_bonus', 'calc_type' => 'status_bonus',
'cost' => 32, 'cost' => 24,
'level_req' => 20, 'level_req' => 10,
'desc' => '攻击防御低的敌人伤害更高', 'desc' => '召唤雷电直击单个敌人,若敌人被异常状态影响伤害更高',
'damage_ratio' => [1.1, 1.5, 2.0, 2.7], 'damage_ratio' => [1.4, 1.9, 2.3, 3.2],
'base' => [5, 12, 25, 45], // 基础伤害值 'status_bonus' => [0.3, 0.45, 0.6, 0.8], // 敌人异常状态加成系数
'growth' => [0.6, 0.8, 1.0, 1.2], // 等级成长系数 'base' => [6, 14, 28, 48], // 基础伤害值
'growth' => [0.7, 0.9, 1.1, 1.3], // 等级成长系数
], ],
], ],
@ -191,18 +194,17 @@ return [
'growth' => [0.5, 0.7, 0.95, 1.15], 'growth' => [0.5, 0.7, 0.95, 1.15],
], ],
// 21. 炎爆术 - 魔攻型,随敌人数量加成 // 21. 狂风斩 - 物攻型 (每敌伤害 = 物攻 × 倍数)
21 => [ 21 => [
'name' => '炎爆术', 'name' => '狂风斩',
'type' => 'damage_aoe', 'type' => 'damage_aoe',
'calc_type' => 'matk_scaled', 'calc_type' => 'patk',
'cost' => 40, 'cost' => 45,
'level_req' => 12, 'level_req' => 16,
'desc' => '引发连锁爆炸,敌人越多伤害加成越高', 'desc' => '挥出狂暴的风刃,基于物攻伤害',
'damage_ratio' => [0.8, 1.1, 1.4, 1.9], 'damage_ratio' => [0.9, 1.2, 1.6, 2.1],
'enemy_count_bonus' => [0.1, 0.15, 0.2, 0.3], // 每增加一个敌人增加的伤害百分比 'base' => [6, 14, 28, 48],
'base' => [4, 10, 22, 42], // 基础伤害值 'growth' => [0.7, 0.9, 1.1, 1.3],
'growth' => [0.5, 0.7, 0.95, 1.15], // 等级成长系数
], ],
// 22. 流星雨 - 混合型 (每敌伤害 = (魔攻 + 物攻) × 倍数) // 22. 流星雨 - 混合型 (每敌伤害 = (魔攻 + 物攻) × 倍数)
@ -218,7 +220,7 @@ return [
'growth' => [0.6, 0.8, 1, 1.2], 'growth' => [0.6, 0.8, 1, 1.2],
], ],
// 23. 灭世风暴 - 基于暴击率 (每敌伤害 = 魔攻 × 倍数 × (1 + 暴击率×系数)) // 23. 灭世风暴 - 暴击加成型 (每敌伤害 = 魔攻 × 倍数 × (1 + 暴击率×系数))
23 => [ 23 => [
'name' => '灭世风暴', 'name' => '灭世风暴',
'type' => 'damage_aoe', 'type' => 'damage_aoe',
@ -232,8 +234,22 @@ return [
'growth' => [0.6, 0.8, 1, 1.2], 'growth' => [0.6, 0.8, 1, 1.2],
], ],
// 24. 末日火雨 - 敌人越多伤害越低,但每个敌人都会受伤 // 24. 炎爆术 - 敌人数量加成型 (每敌伤害 = 魔攻 × 倍数 × (1 + 敌人数-1 × 加成系数))
24 => [ 24 => [
'name' => '炎爆术',
'type' => 'damage_aoe',
'calc_type' => 'enemy_count_bonus',
'cost' => 40,
'level_req' => 12,
'desc' => '引发连锁爆炸,敌人越多伤害加成越高',
'damage_ratio' => [0.8, 1.1, 1.4, 1.9],
'enemy_count_bonus' => [0.1, 0.15, 0.2, 0.3], // 每增加一个敌人增加的伤害百分比
'base' => [4, 10, 22, 42], // 基础伤害值
'growth' => [0.5, 0.7, 0.95, 1.15], // 等级成长系数
],
// 25. 末日火雨 - 伤害分散型 (总伤害 = 魔攻 × 倍数,按敌人数分散,敌人越多每个敌人伤害越低)
25 => [
'name' => '末日火雨', 'name' => '末日火雨',
'type' => 'damage_aoe', 'type' => 'damage_aoe',
'calc_type' => 'dispersed_damage', 'calc_type' => 'dispersed_damage',
@ -245,19 +261,6 @@ return [
'base' => [5, 12, 25, 45], // 基础伤害值 'base' => [5, 12, 25, 45], // 基础伤害值
'growth' => [0.6, 0.8, 1.0, 1.2], // 等级成长系数 'growth' => [0.6, 0.8, 1.0, 1.2], // 等级成长系数
], ],
// 25. 狂风斩 - 基于物攻 (每敌伤害 = 物攻 × 倍数)
25 => [
'name' => '狂风斩',
'type' => 'damage_aoe',
'calc_type' => 'patk',
'cost' => 45,
'level_req' => 16,
'desc' => '挥出狂暴的风刃,基于物攻伤害',
'damage_ratio' => [0.9, 1.2, 1.6, 2.1],
'base' => [6, 14, 28, 48],
'growth' => [0.7, 0.9, 1.1, 1.3],
],
], ],
// ============ 群体治疗法术 (heal_aoe) ============ // ============ 群体治疗法术 (heal_aoe) ============
@ -276,15 +279,16 @@ return [
'growth' => [0.8, 1, 1.2, 1.5], 'growth' => [0.8, 1, 1.2, 1.5],
], ],
// 31. 恢复光环 - 生命值百分比型 (每人恢复 = 自己最大生命值 × 百分比) // 31. 强势守护 - 物攻型 (每人恢复 = 物攻 × 倍数 + 基础值)
31 => [ 31 => [
'name' => '恢复光环', 'name' => '强势守护',
'type' => 'heal_aoe', 'type' => 'heal_aoe',
'calc_type' => 'hp_percent', 'calc_type' => 'patk',
'cost' => 35, 'cost' => 32,
'level_req' => 14, 'level_req' => 10,
'desc' => '释放温暖的光芒,基于自己的最大生命值恢复队员', 'desc' => '以强大的力量保护队友,基于物攻进行治疗',
'heal_ratio' => [0.2, 0.3, 0.4, 0.5], 'heal_ratio' => [0.25, 0.4, 0.6, 0.85],
'heal_base' => [12, 25, 42, 65],
'base' => [8, 18, 38, 65], 'base' => [8, 18, 38, 65],
'growth' => [0.8, 1, 1.2, 1.5], 'growth' => [0.8, 1, 1.2, 1.5],
], ],
@ -303,17 +307,15 @@ return [
'growth' => [0.8, 1, 1.2, 1.5], 'growth' => [0.8, 1, 1.2, 1.5],
], ],
// 33. 仙界救赎 - 智能治疗(优先治疗血量少的队员) // 33. 恢复光环 - 生命值百分比型 (每人恢复 = 自己最大生命值 × 百分比)
33 => [ 33 => [
'name' => '仙界救赎', 'name' => '恢复光环',
'type' => 'heal_aoe', 'type' => 'heal_aoe',
'calc_type' => 'smart_heal', 'calc_type' => 'hp_percent',
'cost' => 55, 'cost' => 35,
'level_req' => 32, 'level_req' => 14,
'desc' => '至高的救赎之力,优先治疗血量较低的队员', 'desc' => '释放温暖的光芒,基于自己的最大生命值恢复队员',
'heal_ratio' => [0.4, 0.6, 0.9, 1.3], 'heal_ratio' => [0.2, 0.3, 0.4, 0.5],
'heal_base' => [25, 45, 70, 110],
'priority_bonus' => [0.2, 0.3, 0.4, 0.5], // 血量越少加成越多
'base' => [8, 18, 38, 65], 'base' => [8, 18, 38, 65],
'growth' => [0.8, 1, 1.2, 1.5], 'growth' => [0.8, 1, 1.2, 1.5],
], ],
@ -332,16 +334,17 @@ return [
'growth' => [0.8, 1, 1.2, 1.5], 'growth' => [0.8, 1, 1.2, 1.5],
], ],
// 35. 团队共鸣 - 基于队伍状态 (每人恢复 = 魔攻 × 倍数 × (队员数量系数)) // 35. 仙界救赎 - 智能治疗(优先治疗血量少的队员)
35 => [ 35 => [
'name' => '团队共鸣', 'name' => '仙界救赎',
'type' => 'heal_aoe', 'type' => 'heal_aoe',
'calc_type' => 'team_sync', 'calc_type' => 'smart_heal',
'cost' => 38, 'cost' => 55,
'level_req' => 20, 'level_req' => 32,
'desc' => '队员越多,治疗效果越强', 'desc' => '至高的救赎之力,优先治疗血量较低的队员',
'heal_ratio' => [0.35, 0.55, 0.8, 1.1], 'heal_ratio' => [0.4, 0.6, 0.9, 1.3],
'team_bonus' => [0.2, 0.3, 0.45, 0.6], // 每增加一个队员增加的治疗百分比 'heal_base' => [25, 45, 70, 110],
'priority_bonus' => [0.2, 0.3, 0.4, 0.5], // 血量越少加成越多
'base' => [8, 18, 38, 65], 'base' => [8, 18, 38, 65],
'growth' => [0.8, 1, 1.2, 1.5], 'growth' => [0.8, 1, 1.2, 1.5],
], ],
@ -376,46 +379,5 @@ return [
8 => ['cost' => 10, 'bonus' => 70, 'cost_reduction' => 14], 8 => ['cost' => 10, 'bonus' => 70, 'cost_reduction' => 14],
9 => ['cost' => 12, 'bonus' => 80, 'cost_reduction' => 16], 9 => ['cost' => 12, 'bonus' => 80, 'cost_reduction' => 16],
10 => ['cost' => 15, 'bonus' => 100, 'cost_reduction' => 20], 10 => ['cost' => 15, 'bonus' => 100, 'cost_reduction' => 20],
], ]
// ============ 地牢法术掉落映射 ============
'dungeon_spell_drops' => [
1 => ['heal_single', 'damage_single', 'damage_aoe'], // 七玄门 (Lv.1-5)
2 => ['damage_single', 'damage_aoe', 'heal_aoe'], // 太南谷 (Lv.5-10)
3 => ['heal_single', 'heal_aoe'], // 血色禁地 (Lv.10-15)
4 => ['damage_single', 'damage_aoe'], // 黄枫谷 (Lv.15-20)
5 => ['damage_single', 'heal_aoe'], // 燕翎堡 (Lv.20-30)
6 => ['damage_single', 'heal_aoe'], // 越京皇宫 (Lv.30-40)
7 => ['damage_aoe'], // 乱星海-魁星岛 (Lv.40-50)
8 => ['damage_aoe', 'heal_single', 'heal_aoe'], // 虚天殿 (Lv.50-60)
9 => ['damage_single', 'damage_aoe', 'heal_single'], // 外星海 (Lv.60+)
],
// ============ 按法术类型和品质分类 ============
'spells_by_quality' => [
'common' => [
'heal_single' => [1],
'damage_single' => [10],
'damage_aoe' => [20],
'heal_aoe' => [30],
],
'rare' => [
'heal_single' => [2, 3],
'damage_single' => [11, 12],
'damage_aoe' => [21, 22],
'heal_aoe' => [31, 32],
],
'epic' => [
'heal_single' => [4, 5],
'damage_single' => [13, 14],
'damage_aoe' => [23, 24],
'heal_aoe' => [33, 34],
],
'legendary' => [
'heal_single' => [6],
'damage_single' => [15],
'damage_aoe' => [25],
'heal_aoe' => [35],
],
],
]; ];

View File

@ -144,7 +144,7 @@ class Battle
$this->round = 0; $this->round = 0;
// 显示遭遇界面 // 显示遭遇界面
$this->showEncounter($out); // $this->showEncounter($out);
$playerFirst = $this->determineFirstStrike(); $playerFirst = $this->determineFirstStrike();
@ -408,12 +408,12 @@ class Battle
$lowHpAllies = []; $lowHpAllies = [];
foreach ($allies as $ally) { foreach ($allies as $ally) {
if ($ally->hp < $ally->maxHp * 0.5) { $status = $ally->getStats();
if ($status['hp'] < $status['maxHp'] * 0.5) {
$lowHpAllies[] = $ally; $lowHpAllies[] = $ally;
} }
} }
$lowHpCount = count($lowHpAllies); $lowHpCount = count($lowHpAllies);
// 2. 筛选可用法术并分类 // 2. 筛选可用法术并分类
$availableSpells = [ $availableSpells = [
'heal_aoe' => [], 'heal_aoe' => [],
@ -505,9 +505,8 @@ class Battle
if (!$target) return true; if (!$target) return true;
// 显示法术基础信息 // 显示法术基础信息
$calcType = $spellInfo['calc_type'] ?? 'matk';
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
$actualCost = SpellCalculator::calculateCost($spellInfo);
$quality = $spellInfo['quality'] ?? 'common'; $quality = $spellInfo['quality'] ?? 'common';
$qualityColor = SpellDisplay::getQualityColor($quality); $qualityColor = SpellDisplay::getQualityColor($quality);
@ -515,16 +514,12 @@ class Battle
$damageResult = SpellCalculator::calculateDamage($spellInfo, $stats, $target->getStats(), $damageBonus); $damageResult = SpellCalculator::calculateDamage($spellInfo, $stats, $target->getStats(), $damageBonus);
$damage = $damageResult['damage']; $damage = $damageResult['damage'];
$isCrit = $damageResult['isCrit']; $isCrit = $damageResult['isCrit'];
$baseDamageMultiplier = $damageResult['multiplier'];
// 显示法术施放信息 // 显示法术施放信息
$casterName = ($caster instanceof Player) ? "" : $caster->name; $casterName = ($caster instanceof Player) ? "" : $caster->name;
$actionVerb = ($caster instanceof Player) ? "施放" : "施放了"; $actionVerb = ($caster instanceof Player) ? "施放" : "施放了";
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}"); $out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}");
if ($caster instanceof Player) {
$out->writeln("{$this->cyan}{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost} | 倍数: {$baseDamageMultiplier}x{$this->reset}");
}
if ($isCrit) { if ($isCrit) {
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->red}{$this->bold}暴击!{$this->reset}{$target->name} 造成 {$this->red}{$damage}{$this->reset} 点魔法伤害!"); $out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->red}{$this->bold}暴击!{$this->reset}{$target->name} 造成 {$this->red}{$damage}{$this->reset} 点魔法伤害!");
@ -562,9 +557,6 @@ class Battle
private function castDamageAoeSpell($out, Actor $caster, ?Actor $target, array $spellInfo, array $stats, int $damageBonus, string $name): bool private function castDamageAoeSpell($out, Actor $caster, ?Actor $target, array $spellInfo, array $stats, int $damageBonus, string $name): bool
{ {
// 显示法术基础信息 // 显示法术基础信息
$calcType = $spellInfo['calc_type'] ?? 'matk';
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
$actualCost = SpellCalculator::calculateCost($spellInfo);
$quality = $spellInfo['quality'] ?? 'common'; $quality = $spellInfo['quality'] ?? 'common';
$qualityColor = SpellDisplay::getQualityColor($quality); $qualityColor = SpellDisplay::getQualityColor($quality);
@ -572,9 +564,7 @@ class Battle
$actionVerb = ($caster instanceof Player) ? "施放" : "施放了"; $actionVerb = ($caster instanceof Player) ? "施放" : "施放了";
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}"); $out->writeln("{$this->cyan}{$this->reset} {$this->magenta}{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}");
if ($caster instanceof Player) {
$out->writeln("{$this->cyan}{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost}{$this->reset}");
}
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}✨ 魔法在整个战场爆炸!{$this->reset}"); $out->writeln("{$this->cyan}{$this->reset} {$this->magenta}✨ 魔法在整个战场爆炸!{$this->reset}");
$opponents = $this->getOpponents($caster); $opponents = $this->getOpponents($caster);
@ -642,9 +632,6 @@ class Battle
} }
// 显示法术基础信息 // 显示法术基础信息
$calcType = $spellInfo['calc_type'] ?? 'matk';
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
$actualCost = SpellCalculator::calculateCost($spellInfo);
$quality = $spellInfo['quality'] ?? 'common'; $quality = $spellInfo['quality'] ?? 'common';
$qualityColor = SpellDisplay::getQualityColor($quality); $qualityColor = SpellDisplay::getQualityColor($quality);
@ -652,9 +639,7 @@ class Battle
$actionVerb = ($caster instanceof Player) ? "施放" : "施放了"; $actionVerb = ($caster instanceof Player) ? "施放" : "施放了";
$out->writeln("{$this->cyan}{$this->reset} {$this->green}{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}"); $out->writeln("{$this->cyan}{$this->reset} {$this->green}{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}");
if ($caster instanceof Player) {
$out->writeln("{$this->cyan}{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost}{$this->reset}");
}
$healAmount = SpellCalculator::calculateHeal($spellInfo, $stats, $healBonus); $healAmount = SpellCalculator::calculateHeal($spellInfo, $stats, $healBonus);
@ -677,9 +662,6 @@ class Battle
private function castHealAoeSpell($out, Actor $caster, ?Actor $target, array $spellInfo, array $stats, int $healBonus, string $name): bool private function castHealAoeSpell($out, Actor $caster, ?Actor $target, array $spellInfo, array $stats, int $healBonus, string $name): bool
{ {
// 显示法术基础信息 // 显示法术基础信息
$calcType = $spellInfo['calc_type'] ?? 'matk';
$calcDesc = SpellDisplay::getCalcTypeDescription($calcType);
$actualCost = SpellCalculator::calculateCost($spellInfo);
$quality = $spellInfo['quality'] ?? 'common'; $quality = $spellInfo['quality'] ?? 'common';
$qualityColor = SpellDisplay::getQualityColor($quality); $qualityColor = SpellDisplay::getQualityColor($quality);
@ -687,9 +669,7 @@ class Battle
$actionVerb = ($caster instanceof Player) ? "施放" : "施放了"; $actionVerb = ($caster instanceof Player) ? "施放" : "施放了";
$out->writeln("{$this->cyan}{$this->reset} {$this->green}{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}"); $out->writeln("{$this->cyan}{$this->reset} {$this->green}{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}");
if ($caster instanceof Player) {
$out->writeln("{$this->cyan}{$this->reset} {$this->white}计算方式: {$calcDesc} | 消耗: {$actualCost}{$this->reset}");
}
$healAmount = SpellCalculator::calculateHeal($spellInfo, $stats, $healBonus); $healAmount = SpellCalculator::calculateHeal($spellInfo, $stats, $healBonus);
@ -726,15 +706,11 @@ class Battle
// 显示法术基础信息 // 显示法术基础信息
$quality = $spellInfo['quality'] ?? 'common'; $quality = $spellInfo['quality'] ?? 'common';
$qualityColor = SpellDisplay::getQualityColor($quality); $qualityColor = SpellDisplay::getQualityColor($quality);
$actualCost = SpellCalculator::calculateCost($spellInfo);
$casterName = ($caster instanceof Player) ? "" : $caster->name; $casterName = ($caster instanceof Player) ? "" : $caster->name;
$actionVerb = ($caster instanceof Player) ? "施放" : "施放了"; $actionVerb = ($caster instanceof Player) ? "施放" : "施放了";
$out->writeln("{$this->cyan}{$this->reset} {$this->cyan}{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}"); $out->writeln("{$this->cyan}{$this->reset} {$this->cyan}{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}");
if ($caster instanceof Player) {
$out->writeln("{$this->cyan}{$this->reset} {$this->white}消耗: {$actualCost}{$this->reset}");
}
$subtype = $spellInfo['subtype'] ?? ''; $subtype = $spellInfo['subtype'] ?? '';

View File

@ -264,7 +264,9 @@ class InventoryPanel
$slot = $item['type']; $slot = $item['type'];
// 获取新装备原有的强化等级 // 获取新装备原有的强化等级
$newItemEnhanceLevel = $item['enhanceLevel'] ?? 0; // $newItemEnhanceLevel = $item['enhanceLevel'] ?? 0;
// 调整为不能继承强化等级
$newItemEnhanceLevel = 0;
// If there's already an item in the slot, swap enhance levels // If there's already an item in the slot, swap enhance levels
if (isset($player->equip[$slot]) && !empty($player->equip[$slot])) { if (isset($player->equip[$slot]) && !empty($player->equip[$slot])) {

View File

@ -277,6 +277,7 @@ class NpcPanel
'exp' => 0, 'exp' => 0,
'baseStats' => $npc['base_stats'], 'baseStats' => $npc['base_stats'],
'equip' => [], 'equip' => [],
'talentWeights' => $npc['talent_weights'] ?? null, // 从 NPC 配置加载天赋权重
...$npc['base_stats'] ...$npc['base_stats']
]); ]);

View File

@ -319,17 +319,50 @@ class StatsPanel
Screen::clear($this->game->output); Screen::clear($this->game->output);
$this->game->output->writeln("{$this->cyan}========== 装备物品 =========={$this->reset}"); $this->game->output->writeln("{$this->cyan}========== 装备物品 =========={$this->reset}");
// 筛选可装备物品 // Step 1: 选择装备部位
$slots = ['weapon' => '武器', 'armor' => '护甲', 'boots' => '鞋子', 'ring' => '戒指', 'necklace' => '项链'];
$slotIdx = 1;
$slotMap = [];
$this->game->output->writeln("{$this->white}请先选择装备部位:{$this->reset}");
foreach ($slots as $slotKey => $slotName) {
$currentItem = $actor->equip[$slotKey] ?? null;
if ($currentItem) {
$this->game->output->writeln("[{$slotIdx}] {$slotName}: " . ItemDisplay::formatName($currentItem));
} else {
$this->game->output->writeln("[{$slotIdx}] {$slotName}: (空)");
}
$slotMap[$slotIdx] = $slotKey;
$slotIdx++;
}
$this->game->output->writeln("[0] 取消");
$slotChoice = Input::ask($this->game->output, "选择部位: ");
if ($slotChoice == 0) return;
if (!isset($slotMap[$slotChoice])) {
$this->game->output->writeln("无效选择");
Screen::sleep(1);
return;
}
$selectedSlot = $slotMap[$slotChoice];
// Step 2: 显示该部位的可装备物品
Screen::clear($this->game->output);
$this->game->output->writeln("{$this->cyan}========== 选择物品 =========={$this->reset}");
$equipableItems = []; $equipableItems = [];
foreach ($this->game->player->inventory as $idx => $item) { foreach ($this->game->player->inventory as $idx => $item) {
$type = $item['type'] ?? ''; if (($item['type'] ?? '') === $selectedSlot) {
if (in_array($type, ['weapon', 'armor', 'ring', 'boots', 'necklace'])) {
$equipableItems[$idx] = $item; $equipableItems[$idx] = $item;
} }
} }
if (empty($equipableItems)) { if (empty($equipableItems)) {
$this->game->output->writeln("{$this->white}没有可装备的物品{$this->reset}"); $this->game->output->writeln("{$this->white}背包中没有此类型的物品{$this->reset}");
Screen::pause($this->game->output); Screen::pause($this->game->output);
return; return;
} }
@ -345,28 +378,27 @@ class StatsPanel
$this->game->output->writeln("[0] 取消"); $this->game->output->writeln("[0] 取消");
$choice = Input::ask($this->game->output, "选择装备: "); $itemChoice = Input::ask($this->game->output, "选择装备: ");
if ($choice == 0) return; if ($itemChoice == 0) return;
if (!isset($idxMap[$choice])) { if (!isset($idxMap[$itemChoice])) {
$this->game->output->writeln("无效选择"); $this->game->output->writeln("无效选择");
Screen::sleep(1); Screen::sleep(1);
return; return;
} }
$realIdx = $idxMap[$choice]; $realIdx = $idxMap[$itemChoice];
$item = $this->game->player->inventory[$realIdx]; $item = $this->game->player->inventory[$realIdx];
$slot = $item['type'];
// 如果该槽位已有装备,先卸下 // 如果该槽位已有装备,先卸下
if (!empty($actor->equip[$slot])) { if (!empty($actor->equip[$selectedSlot])) {
$oldItem = $actor->equip[$slot]; $oldItem = $actor->equip[$selectedSlot];
$this->game->player->addItem($oldItem); $this->game->player->addItem($oldItem);
} }
// 装备新物品 // 装备新物品
$actor->equip[$slot] = $item; $actor->equip[$selectedSlot] = $item;
// 从背包移除 // 从背包移除
unset($this->game->player->inventory[$realIdx]); unset($this->game->player->inventory[$realIdx]);
@ -508,6 +540,7 @@ class StatsPanel
private function showEnhancePanel(string $slot, Actor $actor) private function showEnhancePanel(string $slot, Actor $actor)
{ {
$out = $this->game->output; $out = $this->game->output;
$player = $this->game->player;
$item = $actor->equip[$slot] ?? null; $item = $actor->equip[$slot] ?? null;
@ -519,17 +552,8 @@ class StatsPanel
Screen::clear($out); Screen::clear($out);
$slotName = match ($slot) {
"weapon" => "武器",
"armor" => "护甲",
"boots" => "鞋子",
"ring" => "戒指",
"necklace" => "项链",
default => ucfirst($slot)
};
$enhanceLevel = $item['enhanceLevel'] ?? 0; $enhanceLevel = $item['enhanceLevel'] ?? 0;
$maxLevel = 15; $maxLevel = 14;
if ($enhanceLevel >= $maxLevel) { if ($enhanceLevel >= $maxLevel) {
$out->writeln("该装备已达到最高强化等级!"); $out->writeln("该装备已达到最高强化等级!");
@ -537,72 +561,58 @@ class StatsPanel
return; return;
} }
$config = $this->enhanceConfig[$enhanceLevel] ?? $this->enhanceConfig[14]; // 显示目标等级选择
$successRate = $config['rate']; $out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$cost = $config['cost']; $out->writeln("{$this->cyan} 装 备 强 化 等 级 选 择{$this->reset}");
$downgradeChance = $config['downgrade']; $out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("");
// 计算强化后的属性预览 $out->writeln("装备: " . ItemDisplay::formatName($item));
$currentBonus = $this->calculateEnhanceBonus($enhanceLevel); $out->writeln("当前等级: {$this->yellow}+{$enhanceLevel}{$this->reset}");
$nextBonus = $this->calculateEnhanceBonus($enhanceLevel + 1); $out->writeln("");
$out->writeln("可选等级:");
// 获取品质
$quality = $item['quality'] ?? $item['rarity'] ?? 'common';
$out->writeln("╔════════════════════════════════════╗");
$out->writeln("{$this->cyan}装备强化{$this->reset}");
$out->writeln("╠════════════════════════════════════╣");
// 使用统一的装备显示
$out->writeln("║ 位置: {$slotName}");
$out->writeln("║ 装备: " . ItemDisplay::formatName($item));
$out->writeln("║ 品质: " . ItemDisplay::getQualityColor($quality) .
ItemDisplay::getQualityName($quality) . $this->reset);
$out->writeln("");
// 显示主属性
$out->writeln("{$this->white}--- 主属性 ---{$this->reset}");
$statLines = ItemDisplay::formatStatsDetailed($item, "");
foreach ($statLines as $line) {
$out->writeln($line);
}
// 显示词条
$affixes = $item['affixes'] ?? [];
if (!empty($affixes)) {
$out->writeln("");
$out->writeln("{$this->white}--- 词条 ---{$this->reset}");
$affixLines = ItemDisplay::formatAffixes($item, "");
foreach ($affixLines as $line) {
$out->writeln($line);
}
}
$out->writeln("");
$out->writeln("╠════════════════════════════════════╣");
$out->writeln("");
$out->writeln("║ 当前强化等级: {$this->green}+{$enhanceLevel}{$this->reset}");
$out->writeln("║ 当前属性加成: {$this->green}+{$currentBonus}%{$this->reset}");
$out->writeln("");
$out->writeln("║ ➜ 强化至 {$this->yellow}+".($enhanceLevel + 1)."{$this->reset}");
$out->writeln("║ 属性加成: {$this->yellow}+{$nextBonus}%{$this->reset}");
$out->writeln("");
$out->writeln("║ 成功率: {$this->green}{$successRate}%{$this->reset}");
if ($downgradeChance > 0) {
$out->writeln("║ 失败掉级概率: {$this->red}{$downgradeChance}%{$this->reset}");
}
$out->writeln("║ 费用: {$this->yellow}{$cost}{$this->reset} 灵石");
$out->writeln("");
$out->writeln("║ 你的灵石: {$this->green}{$this->game->player->spiritStones}{$this->reset}");
$out->writeln("╚════════════════════════════════════╝");
$out->writeln(""); $out->writeln("");
$out->writeln("[1] 强化 | [0] 返回");
$choice = Screen::input($out, "选择操作:"); // 显示所有可选的目标等级
for ($target = $enhanceLevel + 1; $target <= $maxLevel; $target++) {
if ($choice == 1) { $totalCost = EquipmentEnhancer::getTotalCost($enhanceLevel, $target);
$this->doEnhance($slot, $actor); $canAfford = $player->spiritStones >= $totalCost ? "{$this->green}{$this->reset}" : "{$this->red}{$this->reset}";
$out->writeln(" [{$target}] +{$target} (需要: {$totalCost} 灵石) {$canAfford}");
} }
$out->writeln("");
$out->writeln(" [0] 手动强化 (一次一级)");
$out->writeln("");
$out->writeln("当前灵石: {$this->yellow}{$player->spiritStones}{$this->reset}");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$choice = Screen::input($out, "选择目标等级:");
if ($choice == 0) {
// 手动强化一次
$this->doEnhance($slot, $actor);
return;
}
$targetLevel = (int)$choice;
// 验证选择有效性
if ($targetLevel <= $enhanceLevel || $targetLevel > $maxLevel) {
$out->writeln("{$this->red}无效的目标等级{$this->reset}");
Screen::sleep(1);
return;
}
// 检查灵石是否足够
$totalCost = EquipmentEnhancer::getTotalCost($enhanceLevel, $targetLevel);
if ($player->spiritStones < $totalCost) {
$lack = $totalCost - $player->spiritStones;
$out->writeln("{$this->red}灵石不足!还需要 {$lack} 灵石{$this->reset}");
Screen::sleep(1);
return;
}
// 执行自动强化
$this->doEnhanceToLevel($slot, $actor, $targetLevel);
} }
private function doEnhance(string $slot, Actor $actor) private function doEnhance(string $slot, Actor $actor)
@ -642,6 +652,101 @@ class StatsPanel
Screen::sleep(1); Screen::sleep(1);
} }
/**
* 自动强化装备到目标等级
*/
private function doEnhanceToLevel(string $slot, Actor $actor, int $targetLevel)
{
$out = $this->game->output;
$player = $this->game->player;
$item = &$actor->equip[$slot];
if (!$item) return;
$currentLevel = $item['enhanceLevel'] ?? 0;
$item['enhanceLevel'] = $item['enhanceLevel'] ?? 0;
Screen::clear($out);
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("{$this->cyan} 自 动 强 化 中{$this->reset}");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("");
$out->writeln("装备: " . ItemDisplay::formatName($item));
$out->writeln("目标: +{$targetLevel}");
$out->writeln("");
$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("{$totalAttempts} 次: {$this->green}✓ 成功{$this->reset} +{$oldLevel} → +{$result['newLevel']}");
} else {
$failureCount++;
if ($result['downgraded']) {
$downgrades++;
$out->writeln("{$totalAttempts} 次: {$this->red}✗ 失败并降级{$this->reset} +{$oldLevel} → +{$result['newLevel']}");
} else {
$out->writeln("{$totalAttempts} 次: {$this->yellow}✗ 失败{$this->reset} 等级保持 +{$oldLevel}");
}
}
}
// 显示最终结果
$out->writeln("");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("{$this->cyan} 强 化 完 成{$this->reset}");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$finalLevel = $item['enhanceLevel'];
$spiritUsed = $startingSpirits - $player->spiritStones;
$out->writeln("装备等级: {$this->yellow}+{$currentLevel}{$this->reset}{$this->yellow}+{$finalLevel}{$this->reset}");
$out->writeln("强化尝试: {$this->yellow}{$totalAttempts}{$this->reset}");
$out->writeln("成功次数: {$this->green}{$successCount}{$this->reset}");
$out->writeln("失败次数: {$this->red}{$failureCount}{$this->reset}");
if ($downgrades > 0) {
$out->writeln("降级次数: {$this->red}{$downgrades}{$this->reset}");
}
$out->writeln("灵石消耗: {$this->yellow}{$spiritUsed}{$this->reset}");
$out->writeln("剩余灵石: {$this->yellow}{$player->spiritStones}{$this->reset}");
if ($finalLevel >= $targetLevel) {
$out->writeln("");
$out->writeln("{$this->green}✓ 已达到目标等级!{$this->reset}");
} elseif ($player->spiritStones <= 0) {
$out->writeln("");
$out->writeln("{$this->yellow}灵石已用完{$this->reset}");
} else {
$lack = EquipmentEnhancer::getTotalCost($finalLevel, $targetLevel);
$out->writeln("");
$out->writeln("{$this->yellow}灵石不足,还需 {$lack} 灵石{$this->reset}");
}
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$this->game->saveState();
Screen::pause($out);
}
/** /**
* 计算强化等级对应的属性加成百分比 * 计算强化等级对应的属性加成百分比
*/ */
@ -825,6 +930,7 @@ class StatsPanel
private function showSkillEnhancePanel(string $slot, Actor $actor) private function showSkillEnhancePanel(string $slot, Actor $actor)
{ {
$out = $this->game->output; $out = $this->game->output;
$player = $this->game->player;
$item = $actor->skillSlots[$slot] ?? null; $item = $actor->skillSlots[$slot] ?? null;
if (!$item) return; if (!$item) return;
@ -832,7 +938,7 @@ class StatsPanel
Screen::clear($out); Screen::clear($out);
$enhanceLevel = $item['enhanceLevel'] ?? 0; $enhanceLevel = $item['enhanceLevel'] ?? 0;
$maxLevel = 15; $maxLevel = 14;
if ($enhanceLevel >= $maxLevel) { if ($enhanceLevel >= $maxLevel) {
$out->writeln("该技能已达到最高强化等级!"); $out->writeln("该技能已达到最高强化等级!");
@ -840,48 +946,58 @@ class StatsPanel
return; return;
} }
// 使用与装备相同的强化配置 // 显示目标等级选择
$config = $this->enhanceConfig[$enhanceLevel] ?? $this->enhanceConfig[14]; $out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$successRate = $config['rate']; $out->writeln("{$this->cyan} 技 能 强 化 等 级 选 择{$this->reset}");
$cost = $config['cost']; $out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$downgradeChance = $config['downgrade']; $out->writeln("");
$out->writeln("技能: " . ItemDisplay::formatName($item));
$out->writeln("╔════════════════════════════════════╗"); $out->writeln("当前等级: {$this->yellow}+{$enhanceLevel}{$this->reset}");
$out->writeln("{$this->cyan}技能强化{$this->reset}"); $out->writeln("");
$out->writeln("╠════════════════════════════════════╣"); $out->writeln("可选等级:");
$out->writeln("║ 技能: " . ItemDisplay::formatName($item));
$out->writeln("");
// 显示属性变化
$out->writeln("{$this->white}--- 属性预览 ---{$this->reset}");
$statLines = ItemDisplay::formatStatsDetailed($item, "");
foreach ($statLines as $line) {
$out->writeln($line);
}
$out->writeln("");
$out->writeln("╠════════════════════════════════════╣");
$out->writeln("");
$out->writeln("║ 当前等级: {$this->green}+{$enhanceLevel}{$this->reset}");
$out->writeln("");
$out->writeln("║ ➜ 强化至 {$this->yellow}+".($enhanceLevel + 1)."{$this->reset}");
$out->writeln("");
$out->writeln("║ 成功率: {$this->green}{$successRate}%{$this->reset}");
if ($downgradeChance > 0) {
$out->writeln("║ 失败掉级概率: {$this->red}{$downgradeChance}%{$this->reset}");
}
$out->writeln("║ 费用: {$this->yellow}{$cost}{$this->reset} 灵石");
$out->writeln("");
$out->writeln("║ 你的灵石: {$this->green}{$this->game->player->spiritStones}{$this->reset}");
$out->writeln("╚════════════════════════════════════╝");
$out->writeln(""); $out->writeln("");
$out->writeln("[1] 强化 | [0] 返回");
$choice = Screen::input($out, "选择操作:"); // 显示所有可选的目标等级
for ($target = $enhanceLevel + 1; $target <= $maxLevel; $target++) {
if ($choice == 1) { $totalCost = EquipmentEnhancer::getTotalCost($enhanceLevel, $target);
$this->doEnhanceSkill($slot, $actor); $canAfford = $player->spiritStones >= $totalCost ? "{$this->green}{$this->reset}" : "{$this->red}{$this->reset}";
$out->writeln(" [{$target}] +{$target} (需要: {$totalCost} 灵石) {$canAfford}");
} }
$out->writeln("");
$out->writeln(" [0] 手动强化 (一次一级)");
$out->writeln("");
$out->writeln("当前灵石: {$this->yellow}{$player->spiritStones}{$this->reset}");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$choice = Screen::input($out, "选择目标等级:");
if ($choice == 0) {
// 手动强化一次
$this->doEnhanceSkill($slot, $actor);
return;
}
$targetLevel = (int)$choice;
// 验证选择有效性
if ($targetLevel <= $enhanceLevel || $targetLevel > $maxLevel) {
$out->writeln("{$this->red}无效的目标等级{$this->reset}");
Screen::sleep(1);
return;
}
// 检查灵石是否足够
$totalCost = EquipmentEnhancer::getTotalCost($enhanceLevel, $targetLevel);
if ($player->spiritStones < $totalCost) {
$lack = $totalCost - $player->spiritStones;
$out->writeln("{$this->red}灵石不足!还需要 {$lack} 灵石{$this->reset}");
Screen::sleep(1);
return;
}
// 执行自动强化
$this->doEnhanceSkillToLevel($slot, $actor, $targetLevel);
} }
private function doEnhanceSkill(string $slot, Actor $actor) private function doEnhanceSkill(string $slot, Actor $actor)
@ -916,4 +1032,99 @@ class StatsPanel
$this->game->saveState(); $this->game->saveState();
Screen::sleep(1); Screen::sleep(1);
} }
/**
* 自动强化技能到目标等级
*/
private function doEnhanceSkillToLevel(string $slot, Actor $actor, int $targetLevel)
{
$out = $this->game->output;
$player = $this->game->player;
$item = &$actor->skillSlots[$slot];
if (!$item) return;
$currentLevel = $item['enhanceLevel'] ?? 0;
$item['enhanceLevel'] = $item['enhanceLevel'] ?? 0;
Screen::clear($out);
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("{$this->cyan} 自 动 强 化 中{$this->reset}");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("");
$out->writeln("技能: " . ItemDisplay::formatName($item));
$out->writeln("目标: +{$targetLevel}");
$out->writeln("");
$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("{$totalAttempts} 次: {$this->green}✓ 成功{$this->reset} +{$oldLevel} → +{$result['newLevel']}");
} else {
$failureCount++;
if ($result['downgraded']) {
$downgrades++;
$out->writeln("{$totalAttempts} 次: {$this->red}✗ 失败并降级{$this->reset} +{$oldLevel} → +{$result['newLevel']}");
} else {
$out->writeln("{$totalAttempts} 次: {$this->yellow}✗ 失败{$this->reset} 等级保持 +{$oldLevel}");
}
}
}
// 显示最终结果
$out->writeln("");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("{$this->cyan} 强 化 完 成{$this->reset}");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$finalLevel = $item['enhanceLevel'];
$spiritUsed = $startingSpirits - $player->spiritStones;
$out->writeln("技能等级: {$this->yellow}+{$currentLevel}{$this->reset}{$this->yellow}+{$finalLevel}{$this->reset}");
$out->writeln("强化尝试: {$this->yellow}{$totalAttempts}{$this->reset}");
$out->writeln("成功次数: {$this->green}{$successCount}{$this->reset}");
$out->writeln("失败次数: {$this->red}{$failureCount}{$this->reset}");
if ($downgrades > 0) {
$out->writeln("降级次数: {$this->red}{$downgrades}{$this->reset}");
}
$out->writeln("灵石消耗: {$this->yellow}{$spiritUsed}{$this->reset}");
$out->writeln("剩余灵石: {$this->yellow}{$player->spiritStones}{$this->reset}");
if ($finalLevel >= $targetLevel) {
$out->writeln("");
$out->writeln("{$this->green}✓ 已达到目标等级!{$this->reset}");
} elseif ($player->spiritStones <= 0) {
$out->writeln("");
$out->writeln("{$this->yellow}灵石已用完{$this->reset}");
} else {
$lack = EquipmentEnhancer::getTotalCost($finalLevel, $targetLevel);
$out->writeln("");
$out->writeln("{$this->yellow}灵石不足,还需 {$lack} 灵石{$this->reset}");
}
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$this->game->saveState();
Screen::pause($out);
}
} }