修复装备配置并实现自动防护状态功能
- 修复装备配置中硬编码属性值的问题 * 5处直接指定patk/matk/pdef/mdef的装备改为使用模板 * 现在装备会正确生成词条和动态属性 * 装备品质与属性值完全匹配 - 实现战斗中的自动防护状态切换 * 当自身血量健康(>50%)且队友血量低(<30%)时 * 自动进入防护状态为队友抗伤 * 仅在有需要时自动切换,提高战斗智能性 * 显示战斗信息提示玩家防护状态的激活 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
6aedb96342
commit
dabc1f1cd4
|
|
@ -193,7 +193,7 @@ return [
|
||||||
'exp' => 100,
|
'exp' => 100,
|
||||||
'spirit_stones' => 20,
|
'spirit_stones' => 20,
|
||||||
'drops' => [
|
'drops' => [
|
||||||
['type' => 'weapon', 'name' => '眨眼剑法', 'quality' => 'rare', 'patk' => 15, 'rate' => 15],
|
['type' => 'weapon', 'name' => '眨眼剑法', 'quality' => 'rare', 'rate' => 15] + $weaponTemplate,
|
||||||
['type' => 'necklace', 'name' => '长生锁', 'rate' => 20] + $necklaceTemplate,
|
['type' => 'necklace', 'name' => '长生锁', 'rate' => 20] + $necklaceTemplate,
|
||||||
['type' => 'armor', 'name' => '疗愈大衣', 'quality' => 'rare', 'rate' => 12] + $armorTemplate,
|
['type' => 'armor', 'name' => '疗愈大衣', 'quality' => 'rare', 'rate' => 12] + $armorTemplate,
|
||||||
['type' => 'ring', 'name' => '医道戒', 'rate' => 10] + $ringTemplate,
|
['type' => 'ring', 'name' => '医道戒', 'rate' => 10] + $ringTemplate,
|
||||||
|
|
@ -426,7 +426,7 @@ return [
|
||||||
'exp' => 400,
|
'exp' => 400,
|
||||||
'spirit_stones' => 150,
|
'spirit_stones' => 150,
|
||||||
'drops' => [
|
'drops' => [
|
||||||
['type' => 'weapon', 'name' => '烈焰刀', 'quality' => 'epic', 'patk' => 50, 'matk' => 30, 'rate' => 15],
|
['type' => 'weapon', 'name' => '烈焰刀', 'quality' => 'epic', 'rate' => 15] + $weaponTemplate,
|
||||||
['type' => 'ring', 'name' => '传音符', 'rate' => 15] + $ringTemplate,
|
['type' => 'ring', 'name' => '传音符', 'rate' => 15] + $ringTemplate,
|
||||||
['type' => 'armor', 'name' => '烈焰战甲', 'quality' => 'rare', 'rate' => 12] + $armorTemplate,
|
['type' => 'armor', 'name' => '烈焰战甲', 'quality' => 'rare', 'rate' => 12] + $armorTemplate,
|
||||||
['type' => 'boots', 'name' => '云游靴', 'quality' => 'rare', 'rate' => 10] + $bootsTemplate,
|
['type' => 'boots', 'name' => '云游靴', 'quality' => 'rare', 'rate' => 10] + $bootsTemplate,
|
||||||
|
|
@ -582,7 +582,7 @@ return [
|
||||||
'exp' => 1000,
|
'exp' => 1000,
|
||||||
'spirit_stones' => 400,
|
'spirit_stones' => 400,
|
||||||
'drops' => [
|
'drops' => [
|
||||||
['type' => 'weapon', 'name' => '青元剑', 'quality' => 'legendary', 'patk' => 100, 'matk' => 80, 'rate' => 20],
|
['type' => 'weapon', 'name' => '青元剑', 'quality' => 'legendary', 'rate' => 20] + $weaponTemplate,
|
||||||
['type' => 'armor', 'name' => '黑煞甲', 'quality' => 'legendary', 'rate' => 18] + $armorTemplate,
|
['type' => 'armor', 'name' => '黑煞甲', 'quality' => 'legendary', 'rate' => 18] + $armorTemplate,
|
||||||
['type' => 'ring', 'name' => '黑煞戒', 'rate' => 15] + $ringTemplate,
|
['type' => 'ring', 'name' => '黑煞戒', 'rate' => 15] + $ringTemplate,
|
||||||
['type' => 'boots', 'name' => '黑煞靴', 'quality' => 'rare', 'rate' => 12] + $bootsTemplate,
|
['type' => 'boots', 'name' => '黑煞靴', 'quality' => 'rare', 'rate' => 12] + $bootsTemplate,
|
||||||
|
|
@ -817,8 +817,8 @@ return [
|
||||||
'exp' => 4000,
|
'exp' => 4000,
|
||||||
'spirit_stones' => 1500,
|
'spirit_stones' => 1500,
|
||||||
'drops' => [
|
'drops' => [
|
||||||
['type' => 'weapon', 'name' => '金蛟剪', 'quality' => 'legendary', 'patk' => 300, 'matk' => 200, 'rate' => 20],
|
['type' => 'weapon', 'name' => '金蛟剪', 'quality' => 'legendary', 'rate' => 20] + $weaponTemplate,
|
||||||
['type' => 'armor', 'name' => '金蛟鳞甲', 'quality' => 'legendary', 'pdef' => 180, 'mdef' => 120, 'rate' => 20],
|
['type' => 'armor', 'name' => '金蛟鳞甲', 'quality' => 'legendary', 'rate' => 20] + $armorTemplate,
|
||||||
['type' => 'necklace', 'name' => '金蛟珠', 'quality' => 'epic', 'rate' => 15] + $necklaceTemplate,
|
['type' => 'necklace', 'name' => '金蛟珠', 'quality' => 'epic', 'rate' => 15] + $necklaceTemplate,
|
||||||
['type' => 'boots', 'name' => '金蛟靴', 'quality' => 'rare', 'rate' => 12] + $bootsTemplate,
|
['type' => 'boots', 'name' => '金蛟靴', 'quality' => 'rare', 'rate' => 12] + $bootsTemplate,
|
||||||
['type' => 'consume', 'name' => '九曲灵参', 'rate' => 25, 'heal' => 5000],
|
['type' => 'consume', 'name' => '九曲灵参', 'rate' => 25, 'heal' => 5000],
|
||||||
|
|
@ -898,7 +898,7 @@ return [
|
||||||
'exp' => 5000,
|
'exp' => 5000,
|
||||||
'spirit_stones' => 2000,
|
'spirit_stones' => 2000,
|
||||||
'drops' => [
|
'drops' => [
|
||||||
['type' => 'weapon', 'name' => '落云剑', 'quality' => 'epic', 'patk' => 350, 'matk' => 250, 'rate' => 15],
|
['type' => 'weapon', 'name' => '落云剑', 'quality' => 'epic', 'rate' => 15] + $weaponTemplate,
|
||||||
['type' => 'necklace', 'name' => '定魂珠', 'rate' => 20] + $necklaceTemplate,
|
['type' => 'necklace', 'name' => '定魂珠', 'rate' => 20] + $necklaceTemplate,
|
||||||
['type' => 'armor', 'name' => '云中甲', 'quality' => 'rare', 'rate' => 12] + $armorTemplate,
|
['type' => 'armor', 'name' => '云中甲', 'quality' => 'rare', 'rate' => 12] + $armorTemplate,
|
||||||
['type' => 'boots', 'name' => '飘云靴', 'quality' => 'rare', 'rate' => 10] + $bootsTemplate,
|
['type' => 'boots', 'name' => '飘云靴', 'quality' => 'rare', 'rate' => 10] + $bootsTemplate,
|
||||||
|
|
@ -1135,8 +1135,8 @@ return [
|
||||||
'exp' => 30000,
|
'exp' => 30000,
|
||||||
'spirit_stones' => 15000,
|
'spirit_stones' => 15000,
|
||||||
'drops' => [
|
'drops' => [
|
||||||
['type' => 'weapon', 'name' => '青竹蜂云剑', 'quality' => 'legendary', 'patk' => 1500, 'matk' => 1000, 'rate' => 15],
|
['type' => 'weapon', 'name' => '青竹蜂云剑', 'quality' => 'legendary', 'rate' => 15] + $weaponTemplate,
|
||||||
['type' => 'armor', 'name' => '五行甲', 'quality' => 'legendary', 'pdef' => 1000, 'mdef' => 1000, 'rate' => 15],
|
['type' => 'armor', 'name' => '五行甲', 'quality' => 'legendary', 'rate' => 15] + $armorTemplate,
|
||||||
['type' => 'necklace', 'name' => '凤凰链', 'quality' => 'legendary', 'rate' => 12] + $necklaceTemplate,
|
['type' => 'necklace', 'name' => '凤凰链', 'quality' => 'legendary', 'rate' => 12] + $necklaceTemplate,
|
||||||
['type' => 'boots', 'name' => '凤凰靴', 'quality' => 'epic', 'rate' => 10] + $bootsTemplate,
|
['type' => 'boots', 'name' => '凤凰靴', 'quality' => 'epic', 'rate' => 10] + $bootsTemplate,
|
||||||
['type' => 'consume', 'name' => '飞升令', 'rate' => 25, 'heal' => 99999],
|
['type' => 'consume', 'name' => '飞升令', 'rate' => 25, 'heal' => 99999],
|
||||||
|
|
|
||||||
|
|
@ -395,6 +395,59 @@ class Battle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算目标的威胁值(用于敌人选择目标)
|
||||||
|
* 威胁值 = 输出能力 + 防御能力 + 防护状态加成
|
||||||
|
*/
|
||||||
|
private function calculateThreat(Actor $target): int
|
||||||
|
{
|
||||||
|
$stats = $target->getStats();
|
||||||
|
|
||||||
|
// 基础威胁值 = (物攻 + 魔攻) / 2
|
||||||
|
$threat = (int)(($stats['patk'] + $stats['matk']) / 2);
|
||||||
|
|
||||||
|
// 防御角色威胁值大幅上升
|
||||||
|
$threat += $target->getThreatBonus();
|
||||||
|
|
||||||
|
// 血量比例也会影响威胁值(血量越多越有威胁)
|
||||||
|
$threat += (int)($stats['hp'] / $stats['maxHp'] * 10);
|
||||||
|
|
||||||
|
return $threat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 智能选择单体目标(考虑防护角色机制)
|
||||||
|
*/
|
||||||
|
private function selectTargetWithThreat(Actor $actor): ?Actor
|
||||||
|
{
|
||||||
|
$opponents = $this->getOpponents($actor);
|
||||||
|
$aliveOpponents = array_filter($opponents, fn($e) => $e->hp > 0);
|
||||||
|
|
||||||
|
if (empty($aliveOpponents)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 优先级1:选择处于防护状态的目标(防御者)
|
||||||
|
$protectingTargets = array_filter($aliveOpponents, fn($e) => $e->isProtecting);
|
||||||
|
if (!empty($protectingTargets)) {
|
||||||
|
return current($protectingTargets);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 优先级2:选择威胁值最高的目标
|
||||||
|
$maxThreat = -1;
|
||||||
|
$bestTarget = null;
|
||||||
|
|
||||||
|
foreach ($aliveOpponents as $target) {
|
||||||
|
$threat = $this->calculateThreat($target);
|
||||||
|
if ($threat > $maxThreat) {
|
||||||
|
$maxThreat = $threat;
|
||||||
|
$bestTarget = $target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $bestTarget ?? current($aliveOpponents);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 智能选择法术 (通用)
|
* 智能选择法术 (通用)
|
||||||
*/
|
*/
|
||||||
|
|
@ -491,15 +544,9 @@ class Battle
|
||||||
*/
|
*/
|
||||||
private function castDamageSingleSpell($out, Actor $caster, ?Actor $target, array $spellInfo, array $stats, int $damageBonus, string $name): bool
|
private function castDamageSingleSpell($out, Actor $caster, ?Actor $target, array $spellInfo, array $stats, int $damageBonus, string $name): bool
|
||||||
{
|
{
|
||||||
// 自动选择目标
|
// 自动选择目标(使用威胁值系统)
|
||||||
if (!$target) {
|
if (!$target) {
|
||||||
$opponents = $this->getOpponents($caster);
|
$target = $this->selectTargetWithThreat($caster);
|
||||||
foreach ($opponents as $enemy) {
|
|
||||||
if ($enemy->hp > 0) {
|
|
||||||
$target = $enemy;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$target) return true;
|
if (!$target) return true;
|
||||||
|
|
@ -518,7 +565,7 @@ class Battle
|
||||||
// 显示法术施放信息
|
// 显示法术施放信息
|
||||||
$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 ($isCrit) {
|
if ($isCrit) {
|
||||||
|
|
@ -527,19 +574,28 @@ class Battle
|
||||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✨ 对 {$target->name} 造成 {$this->green}{$damage}{$this->reset} 点魔法伤害");
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✨ 对 {$target->name} 造成 {$this->green}{$damage}{$this->reset} 点魔法伤害");
|
||||||
}
|
}
|
||||||
|
|
||||||
$target->hp -= $damage;
|
// 应用防护机制:防护角色承受更多伤害
|
||||||
|
$actualDamage = (int)($damage * (1 + $target->getProtectDamageTakenBonus()));
|
||||||
|
|
||||||
|
$target->hp -= $actualDamage;
|
||||||
|
|
||||||
|
// 如果防护角色正在保护队友,需要显示保护效果
|
||||||
|
if ($target->isProtecting && $actualDamage > $damage) {
|
||||||
|
$extraDamage = $actualDamage - $damage;
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->yellow}🛡️ 防护状态:额外承受 {$extraDamage} 伤害!{$this->reset}");
|
||||||
|
}
|
||||||
|
|
||||||
if ($target->hp <= 0) {
|
if ($target->hp <= 0) {
|
||||||
$target->hp = 0;
|
$target->hp = 0;
|
||||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->red}💀 {$target->name} 被击败了!{$this->reset}");
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->red}💀 {$target->name} 被击败了!{$this->reset}");
|
||||||
|
|
||||||
// 如果是玩家击败了所有敌人
|
// 如果是玩家击败了所有敌人
|
||||||
if (($caster instanceof Player || $caster instanceof Partner) && empty($this->getAliveEnemies())) {
|
if (($caster instanceof Player || $caster instanceof Partner) && empty($this->getAliveEnemies())) {
|
||||||
Screen::delay(500000);
|
Screen::delay(500000);
|
||||||
$this->showVictory($out, $stats);
|
$this->showVictory($out, $stats);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果是敌人击败了玩家
|
// 如果是敌人击败了玩家
|
||||||
if ($target instanceof Player) {
|
if ($target instanceof Player) {
|
||||||
Screen::delay(500000);
|
Screen::delay(500000);
|
||||||
|
|
@ -730,6 +786,59 @@ class Battle
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否应该自动进入防护状态来保护低血量队友
|
||||||
|
* 条件:自身血量健康 (>50%) 且有队友血量低 (<30%)
|
||||||
|
*/
|
||||||
|
private function checkAutoEnterProtectMode(Actor $actor, $out): void
|
||||||
|
{
|
||||||
|
// 仅玩家和队友可以进入防护状态,敌人不需要
|
||||||
|
if (!($actor instanceof Player) && !($actor instanceof Partner)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已经在防护状态,不需要再进入
|
||||||
|
if ($actor->isProtecting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stats = $actor->getStats();
|
||||||
|
$healthRatio = $stats['hp'] / $stats['maxHp'];
|
||||||
|
|
||||||
|
// 自身血量需要健康(>50%)
|
||||||
|
if ($healthRatio <= 0.5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有队友血量低
|
||||||
|
$allies = $this->getAllies($actor);
|
||||||
|
$hasLowHpAlly = false;
|
||||||
|
|
||||||
|
foreach ($allies as $ally) {
|
||||||
|
// 跳过自己和倒下的队友
|
||||||
|
if ($ally === $actor || $ally->hp <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$allyStats = $ally->getStats();
|
||||||
|
$allyHealthRatio = $allyStats['hp'] / $allyStats['maxHp'];
|
||||||
|
|
||||||
|
// 如果有队友血量低于30%,进入防护状态
|
||||||
|
if ($allyHealthRatio < 0.3) {
|
||||||
|
$hasLowHpAlly = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动进入防护状态
|
||||||
|
if ($hasLowHpAlly) {
|
||||||
|
$actor->enterProtectMode();
|
||||||
|
|
||||||
|
$actorName = ($actor instanceof Player) ? "你" : $actor->name;
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->yellow}🛡️{$this->reset} {$actorName} 主动进入防护状态,为队友抗伤!{$this->reset}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行角色的回合行动 (通用)
|
* 执行角色的回合行动 (通用)
|
||||||
*/
|
*/
|
||||||
|
|
@ -738,6 +847,10 @@ class Battle
|
||||||
if ($actor->hp <= 0){
|
if ($actor->hp <= 0){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查是否应该自动进入防护状态
|
||||||
|
$this->checkAutoEnterProtectMode($actor, $out);
|
||||||
|
|
||||||
// 1. 尝试使用法术
|
// 1. 尝试使用法术
|
||||||
$selectedSpell = $this->smartSelectSpell($actor);
|
$selectedSpell = $this->smartSelectSpell($actor);
|
||||||
|
|
||||||
|
|
@ -773,15 +886,8 @@ class Battle
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 如果没有使用法术,执行普通攻击
|
// 2. 如果没有使用法术,执行普通攻击
|
||||||
// 寻找目标
|
// 寻找目标(使用威胁值系统)
|
||||||
$target = null;
|
$target = $this->selectTargetWithThreat($actor);
|
||||||
$opponents = $this->getOpponents($actor);
|
|
||||||
foreach ($opponents as $enemy) {
|
|
||||||
if ($enemy->hp > 0) {
|
|
||||||
$target = $enemy;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$target) return true; // 无目标,回合结束
|
if (!$target) return true; // 无目标,回合结束
|
||||||
|
|
||||||
|
|
@ -815,7 +921,16 @@ class Battle
|
||||||
$out->writeln("{$this->cyan}║{$this->reset} {$this->white}⚔️ 造成 {$damage} 点伤害{$this->reset}");
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->white}⚔️ 造成 {$damage} 点伤害{$this->reset}");
|
||||||
}
|
}
|
||||||
|
|
||||||
$target->hp -= $damage;
|
// 应用防护机制:防护角色承受更多伤害
|
||||||
|
$actualDamage = (int)($damage * (1 + $target->getProtectDamageTakenBonus()));
|
||||||
|
|
||||||
|
$target->hp -= $actualDamage;
|
||||||
|
|
||||||
|
// 如果防护角色正在保护队友,需要显示保护效果
|
||||||
|
if ($target->isProtecting && $actualDamage > $damage) {
|
||||||
|
$extraDamage = $actualDamage - $damage;
|
||||||
|
$out->writeln("{$this->cyan}║{$this->reset} {$this->yellow}🛡️ 防护状态:额外承受 {$extraDamage} 伤害!{$this->reset}");
|
||||||
|
}
|
||||||
|
|
||||||
// 蓝量恢复机制
|
// 蓝量恢复机制
|
||||||
// 攻击者恢复 15 点
|
// 攻击者恢复 15 点
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user