From dabc1f1cd44ea51ebdf88723d220ab6312c3886b Mon Sep 17 00:00:00 2001 From: hant Date: Sat, 6 Dec 2025 22:50:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=A3=85=E5=A4=87=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=B9=B6=E5=AE=9E=E7=8E=B0=E8=87=AA=E5=8A=A8=E9=98=B2?= =?UTF-8?q?=E6=8A=A4=E7=8A=B6=E6=80=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复装备配置中硬编码属性值的问题 * 5处直接指定patk/matk/pdef/mdef的装备改为使用模板 * 现在装备会正确生成词条和动态属性 * 装备品质与属性值完全匹配 - 实现战斗中的自动防护状态切换 * 当自身血量健康(>50%)且队友血量低(<30%)时 * 自动进入防护状态为队友抗伤 * 仅在有需要时自动切换,提高战斗智能性 * 显示战斗信息提示玩家防护状态的激活 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/Data/maps.php | 16 ++-- src/Modules/Battle.php | 161 +++++++++++++++++++++++++++++++++++------ 2 files changed, 146 insertions(+), 31 deletions(-) diff --git a/src/Data/maps.php b/src/Data/maps.php index f401d28..d8142ae 100644 --- a/src/Data/maps.php +++ b/src/Data/maps.php @@ -193,7 +193,7 @@ return [ 'exp' => 100, 'spirit_stones' => 20, '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' => 'armor', 'name' => '疗愈大衣', 'quality' => 'rare', 'rate' => 12] + $armorTemplate, ['type' => 'ring', 'name' => '医道戒', 'rate' => 10] + $ringTemplate, @@ -426,7 +426,7 @@ return [ 'exp' => 400, 'spirit_stones' => 150, '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' => 'armor', 'name' => '烈焰战甲', 'quality' => 'rare', 'rate' => 12] + $armorTemplate, ['type' => 'boots', 'name' => '云游靴', 'quality' => 'rare', 'rate' => 10] + $bootsTemplate, @@ -582,7 +582,7 @@ return [ 'exp' => 1000, 'spirit_stones' => 400, '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' => 'ring', 'name' => '黑煞戒', 'rate' => 15] + $ringTemplate, ['type' => 'boots', 'name' => '黑煞靴', 'quality' => 'rare', 'rate' => 12] + $bootsTemplate, @@ -817,8 +817,8 @@ return [ 'exp' => 4000, 'spirit_stones' => 1500, 'drops' => [ - ['type' => 'weapon', 'name' => '金蛟剪', 'quality' => 'legendary', 'patk' => 300, 'matk' => 200, 'rate' => 20], - ['type' => 'armor', 'name' => '金蛟鳞甲', 'quality' => 'legendary', 'pdef' => 180, 'mdef' => 120, 'rate' => 20], + ['type' => 'weapon', 'name' => '金蛟剪', 'quality' => 'legendary', 'rate' => 20] + $weaponTemplate, + ['type' => 'armor', 'name' => '金蛟鳞甲', 'quality' => 'legendary', 'rate' => 20] + $armorTemplate, ['type' => 'necklace', 'name' => '金蛟珠', 'quality' => 'epic', 'rate' => 15] + $necklaceTemplate, ['type' => 'boots', 'name' => '金蛟靴', 'quality' => 'rare', 'rate' => 12] + $bootsTemplate, ['type' => 'consume', 'name' => '九曲灵参', 'rate' => 25, 'heal' => 5000], @@ -898,7 +898,7 @@ return [ 'exp' => 5000, 'spirit_stones' => 2000, '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' => 'armor', 'name' => '云中甲', 'quality' => 'rare', 'rate' => 12] + $armorTemplate, ['type' => 'boots', 'name' => '飘云靴', 'quality' => 'rare', 'rate' => 10] + $bootsTemplate, @@ -1135,8 +1135,8 @@ return [ 'exp' => 30000, 'spirit_stones' => 15000, 'drops' => [ - ['type' => 'weapon', 'name' => '青竹蜂云剑', 'quality' => 'legendary', 'patk' => 1500, 'matk' => 1000, 'rate' => 15], - ['type' => 'armor', 'name' => '五行甲', 'quality' => 'legendary', 'pdef' => 1000, 'mdef' => 1000, 'rate' => 15], + ['type' => 'weapon', 'name' => '青竹蜂云剑', 'quality' => 'legendary', 'rate' => 15] + $weaponTemplate, + ['type' => 'armor', 'name' => '五行甲', 'quality' => 'legendary', 'rate' => 15] + $armorTemplate, ['type' => 'necklace', 'name' => '凤凰链', 'quality' => 'legendary', 'rate' => 12] + $necklaceTemplate, ['type' => 'boots', 'name' => '凤凰靴', 'quality' => 'epic', 'rate' => 10] + $bootsTemplate, ['type' => 'consume', 'name' => '飞升令', 'rate' => 25, 'heal' => 99999], diff --git a/src/Modules/Battle.php b/src/Modules/Battle.php index 723acc2..6fd4d31 100644 --- a/src/Modules/Battle.php +++ b/src/Modules/Battle.php @@ -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 { - // 自动选择目标 + // 自动选择目标(使用威胁值系统) if (!$target) { - $opponents = $this->getOpponents($caster); - foreach ($opponents as $enemy) { - if ($enemy->hp > 0) { - $target = $enemy; - break; - } - } + $target = $this->selectTargetWithThreat($caster); } if (!$target) return true; @@ -518,7 +565,7 @@ class Battle // 显示法术施放信息 $casterName = ($caster instanceof Player) ? "你" : $caster->name; $actionVerb = ($caster instanceof Player) ? "施放" : "施放了"; - + $out->writeln("{$this->cyan}║{$this->reset} {$this->magenta}✦{$this->reset} {$casterName} {$actionVerb} {$qualityColor}{$name}{$this->reset}"); if ($isCrit) { @@ -527,19 +574,28 @@ class Battle $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) { $target->hp = 0; $out->writeln("{$this->cyan}║{$this->reset} {$this->red}💀 {$target->name} 被击败了!{$this->reset}"); - + // 如果是玩家击败了所有敌人 if (($caster instanceof Player || $caster instanceof Partner) && empty($this->getAliveEnemies())) { Screen::delay(500000); - $this->showVictory($out, $stats); + $this->showVictory($out, $stats); return true; } - + // 如果是敌人击败了玩家 if ($target instanceof Player) { Screen::delay(500000); @@ -730,6 +786,59 @@ class Battle 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){ return false; } + + // 检查是否应该自动进入防护状态 + $this->checkAutoEnterProtectMode($actor, $out); + // 1. 尝试使用法术 $selectedSpell = $this->smartSelectSpell($actor); @@ -773,15 +886,8 @@ class Battle } // 2. 如果没有使用法术,执行普通攻击 - // 寻找目标 - $target = null; - $opponents = $this->getOpponents($actor); - foreach ($opponents as $enemy) { - if ($enemy->hp > 0) { - $target = $enemy; - break; - } - } + // 寻找目标(使用威胁值系统) + $target = $this->selectTargetWithThreat($actor); if (!$target) return true; // 无目标,回合结束 @@ -815,7 +921,16 @@ class Battle $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 点