Compare commits

..

No commits in common. "0658960b70aeeff62143e58115dc07248e7cddaa" and "6aedb96342b528f16fd8bfd2aee9c4aa81d9ff34" have entirely different histories.

11 changed files with 172 additions and 375 deletions

File diff suppressed because one or more lines are too long

View File

@ -209,33 +209,33 @@ class ItemDisplay
*/
public static function renderListItem(array $item, bool $showType = true, bool $showQuantity = true): string
{
$parts = [];
// 名称(带品质颜色和强化)
$parts[] = self::formatName($item);
// 数量
$quantity = $item['quantity'] ?? 1;
if ($showQuantity && $quantity > 1) {
$parts[] = self::$gray . "x{$quantity}" . self::$reset;
}
// 类型
if ($showType) {
$type = $item['type'] ?? '';
$typeName = self::getTypeName($type);
$parts[] = self::$gray . "[{$typeName}]" . self::$reset;
}
// 主属性(简洁版)或法术信息
$type = $item['type'] ?? '';
if ($type === 'spell') {
// 法术显示由 SpellDisplay 处理(计算方式和基础数值)
// 需要导入 SpellDisplay 后使用
$statsStr = SpellDisplay::renderListItem($item);
$statsStr = SpellDisplay::formatSpellCompact($item);
// 为了向后兼容,使用内联逻辑(调用处应该使用 SpellDisplay
} else {
// 显示装备的属性
$parts = [];
// 名称(带品质颜色和强化)
$parts[] = self::formatName($item);
// 数量
$quantity = $item['quantity'] ?? 1;
if ($showQuantity && $quantity > 1) {
$parts[] = self::$gray . "x{$quantity}" . self::$reset;
}
// 类型
if ($showType) {
$type = $item['type'] ?? '';
$typeName = self::getTypeName($type);
$parts[] = self::$gray . "[{$typeName}]" . self::$reset;
}
$statsStr = self::formatStatsCompact($item);
}

View File

@ -87,8 +87,6 @@ class SpellCalculator
$baseDamage = (int)($attackerStats['matk'] * $actualMultiplier);
}
$baseDamage += ($spellInfo['base'] ?? 0) * $spellInfo['enhanceLevel'];
// 计算防御减免
$resistance = $defenderStats['mdef'] ?? 0;
$damage = max(1, $baseDamage - $resistance);

View File

@ -128,15 +128,19 @@ class SpellDisplay
// 计算方式
$calcType = $spell['calc_type'] ?? 'matk';
$calcDesc = self::getCalcTypeDescription($calcType);
$ratio = $spell['damage_ratio'];
$parts[] = self::$cyan . "{$calcDesc} x $ratio" . self::$reset;
$parts[] = self::$cyan . "{$calcDesc}" . self::$reset;
// 基础值
if ($spellType === 'damage_single' || $spellType === 'damage_aoe') {
$base = $spell['base'] ?? 0;
$parts[] = self::$yellow . "基础:{$base}" . self::$reset;
$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'] ?? 0;
$parts[] = self::$yellow . "基础:{$base}" . self::$reset;
$base = $spell['base'] ?? [8, 18, 38, 65];
$qualityIndex = self::getQualityIndex($spell['quality'] ?? 'common');
$baseValue = $base[$qualityIndex] ?? 8;
$parts[] = self::$yellow . "基础:{$baseValue}" . self::$reset;
}
// 消耗
@ -443,8 +447,77 @@ class SpellDisplay
public static function renderSlot(string $slotName, array $spell, string $linePrefix = ""): array
{
$lines = [];
// 第一行:槽位名 + 法术名
$lines[] = $linePrefix . self::$cyan . $slotName . self::$reset . ": " . self::renderListItem($spell);
$lines[] = $linePrefix . self::$cyan . $slotName . self::$reset . ": " . self::formatName($spell);
// 计算方式和法术类型
$calcType = $spell['calc_type'] ?? 'matk';
$spellType = $spell['spellType'] ?? $spell['type'] ?? 'unknown';
$typeName = self::getTypeName($spellType);
// 计算方式的完整描述
$calcTypeDescMap = [
'matk' => '基于魔攻',
'patk' => '基于物攻',
'hybrid' => '混合伤害',
'hp_percent' => '基于HP%',
'crit_heal' => '暴击治疗',
'crit_damage' => '暴击伤害',
'defense' => '基于防御',
'def_pierce' => '防御穿透',
'status_bonus' => '状态加成',
'enemy_count_bonus' => '敌人加成',
'low_def_bonus' => '克低防',
'matk_scaled' => '群体伤害',
'dispersed_damage' => '分散伤害',
'crit_aoe' => '暴击范围',
'smart_heal' => '智能治疗',
'hp_missing' => '缺血治疗',
'team_sync' => '队伍同步',
];
$calcDesc = $calcTypeDescMap[$calcType] ?? $calcType;
$lines[] = $linePrefix . " " . self::$white . "类型: " . self::$magenta . $typeName . self::$reset .
self::$white . " | 计算: " . self::$green . $calcDesc . self::$reset;
// 显示基础数值和倍数
if ($spellType === 'damage_single' || $spellType === 'damage_aoe') {
$ratio = $spell['damage_ratio'];
$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') {
$ratio = $spell['heal_ratio'];
$healBase = $spell['heal_base'] ?? null;
$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;
}
}
// 显示消耗
$cost = $spell['cost'] ?? 0;
$enhanceLevel = $spell['enhanceLevel'] ?? 0;
$actualCost = max(1, $cost - ($enhanceLevel * 2));
if ($enhanceLevel > 0) {
$lines[] = $linePrefix . " " . self::$white . "消耗: " . self::$yellow . "{$cost}" . self::$reset .
"" . self::$green . "{$actualCost}" . self::$reset .
self::$yellow . " +{$enhanceLevel}" . self::$reset;
} else {
$lines[] = $linePrefix . " " . self::$white . "消耗: " . self::$green . "{$actualCost}" . self::$reset;
}
return $lines;
}

View File

@ -193,7 +193,7 @@ return [
'exp' => 100,
'spirit_stones' => 20,
'drops' => [
['type' => 'weapon', 'name' => '眨眼剑法', 'quality' => 'rare', 'rate' => 15] + $weaponTemplate,
['type' => 'weapon', 'name' => '眨眼剑法', 'quality' => 'rare', 'patk' => 15, 'rate' => 15],
['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', 'rate' => 15] + $weaponTemplate,
['type' => 'weapon', 'name' => '烈焰刀', 'quality' => 'epic', 'patk' => 50, 'matk' => 30, 'rate' => 15],
['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', 'rate' => 20] + $weaponTemplate,
['type' => 'weapon', 'name' => '青元剑', 'quality' => 'legendary', 'patk' => 100, 'matk' => 80, 'rate' => 20],
['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', 'rate' => 20] + $weaponTemplate,
['type' => 'armor', 'name' => '金蛟鳞甲', 'quality' => 'legendary', 'rate' => 20] + $armorTemplate,
['type' => 'weapon', 'name' => '金蛟剪', 'quality' => 'legendary', 'patk' => 300, 'matk' => 200, 'rate' => 20],
['type' => 'armor', 'name' => '金蛟鳞甲', 'quality' => 'legendary', 'pdef' => 180, 'mdef' => 120, 'rate' => 20],
['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', 'rate' => 15] + $weaponTemplate,
['type' => 'weapon', 'name' => '落云剑', 'quality' => 'epic', 'patk' => 350, 'matk' => 250, 'rate' => 15],
['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', 'rate' => 15] + $weaponTemplate,
['type' => 'armor', 'name' => '五行甲', 'quality' => 'legendary', 'rate' => 15] + $armorTemplate,
['type' => 'weapon', 'name' => '青竹蜂云剑', 'quality' => 'legendary', 'patk' => 1500, 'matk' => 1000, 'rate' => 15],
['type' => 'armor', 'name' => '五行甲', 'quality' => 'legendary', 'pdef' => 1000, 'mdef' => 1000, 'rate' => 15],
['type' => 'necklace', 'name' => '凤凰链', 'quality' => 'legendary', 'rate' => 12] + $necklaceTemplate,
['type' => 'boots', 'name' => '凤凰靴', 'quality' => 'epic', 'rate' => 10] + $bootsTemplate,
['type' => 'consume', 'name' => '飞升令', 'rate' => 25, 'heal' => 99999],

View File

@ -21,12 +21,6 @@ class Actor
public int $mana = 100;
public int $maxMana = 100;
// 防护系统
public bool $isProtecting = false; // 是否处于防护状态
public float $protectDamageReduction = 0.2; // 防护角色伤害减免 20%
public float $protectDamageTakenBonus = 0.3; // 防护角色承受伤害增加 30%
public int $protectThreatBonus = 50; // 防护角色的威胁值加成
// 技能槽位系统 (新法术系统)
public array $skillSlots = [
'skill1' => null,
@ -291,52 +285,4 @@ class Actor
}
}
}
/**
* 进入防护状态
*/
public function enterProtectMode(): bool
{
if ($this->isProtecting) {
return false; // 已经在防护状态
}
$this->isProtecting = true;
return true;
}
/**
* 退出防护状态
*/
public function exitProtectMode(): bool
{
if (!$this->isProtecting) {
return false; // 未在防护状态
}
$this->isProtecting = false;
return true;
}
/**
* 获取防护状态下的伤害减免(用于保护队友)
*/
public function getProtectDamageReduction(): float
{
return $this->isProtecting ? $this->protectDamageReduction : 0;
}
/**
* 获取防护状态下的伤害增加(防护者承受更多伤害)
*/
public function getProtectDamageTakenBonus(): float
{
return $this->isProtecting ? $this->protectDamageTakenBonus : 0;
}
/**
* 获取威胁值加成
*/
public function getThreatBonus(): int
{
return $this->isProtecting ? $this->protectThreatBonus : 0;
}
}

View File

@ -44,7 +44,6 @@ class Item
// 随机品质
$roll = rand(1, 100);
// $roll = 100;
if ($roll <= 70) $quality = 'common';
elseif ($roll <= 90) $quality = 'rare';
elseif ($roll <= 98) $quality = 'epic';
@ -90,7 +89,6 @@ class Item
$item->desc = "Lv.{$level} {$quality}品质的药剂";
} else {
// 检查是否有特定物品配置
// dd($typeConfig);
$specificConfig = $typeConfig['specific_config'][$item->name] ?? [];
// 合并配置:优先使用特定配置,否则使用默认配置
@ -210,12 +208,15 @@ class Item
public static function createFromSpec(array $spec, int $baseLevel): array
{
$type = $spec['type'] ?? 'weapon';
$quality = $spec['quality'] ?? null;
$itemLevel = $spec['level'] ?? $baseLevel;
$affixes = $spec['affixes'] ?? [];
$specificName = $spec['name'] ?? null;
$item = self::randomItem($type, $itemLevel, $specificName);
if ($quality) $item['quality'] = $quality;
if (!empty($affixes)) $item['affixes'] = $affixes;
// Allow overriding specific stats if provided in spec (e.g. from maps.php drops)
foreach (['patk', 'matk', 'pdef', 'mdef', 'hp', 'crit', 'critdmg'] as $stat) {
@ -299,7 +300,6 @@ class Item
$growth = 0;
if (isset($spellInfo['base']) && isset($spellInfo['growth'])) {
$baseArray = $spellInfo['base'];
$growthArray = $spellInfo['growth'];
// 确保索引在范围内
@ -308,8 +308,8 @@ class Item
$growth = $growthArray[$qualityIndex] ?? ($growthArray[0] ?? 0);
// 应用计算公式finalValue = baseValue + (level * growth) + randomBonus
$randomBonus = rand(0, max(1, (int)($baseValue * 3)));
$finalBaseValue = (int)($baseValue + ($level * $growth * 10) + $randomBonus);
$randomBonus = rand(0, max(1, (int)($baseValue * 0.15)));
$finalBaseValue = (int)($baseValue + ($level * $growth) + $randomBonus);
} else {
$finalBaseValue = 0;
}

View File

@ -297,7 +297,7 @@ class Battle
private function renderHpBar(float $percent, int $width): string
{
$filled = (int)($percent * $width);
$empty = max($width - $filled,1);
$empty = max($width - $filled,0);
// 根据血量百分比选择颜色
if ($percent > 0.6) {
@ -308,7 +308,7 @@ class Battle
$color = $this->red;
}
$bar = $color . str_repeat("", $filled) . $this->white . str_repeat("", $empty?:1) . $this->reset;
$bar = $color . str_repeat("", $filled) . $this->white . str_repeat("", $empty) . $this->reset;
return "[" . $bar . "]";
}
@ -395,59 +395,6 @@ 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);
}
/**
* 智能选择法术 (通用)
*/
@ -544,9 +491,15 @@ class Battle
*/
private function castDamageSingleSpell($out, Actor $caster, ?Actor $target, array $spellInfo, array $stats, int $damageBonus, string $name): bool
{
// 自动选择目标(使用威胁值系统)
// 自动选择目标
if (!$target) {
$target = $this->selectTargetWithThreat($caster);
$opponents = $this->getOpponents($caster);
foreach ($opponents as $enemy) {
if ($enemy->hp > 0) {
$target = $enemy;
break;
}
}
}
if (!$target) return true;
@ -574,16 +527,7 @@ class Battle
$out->writeln("{$this->cyan}{$this->reset} {$this->magenta}✨ 对 {$target->name} 造成 {$this->green}{$damage}{$this->reset} 点魔法伤害");
}
// 应用防护机制:防护角色承受更多伤害
$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}");
}
$target->hp -= $damage;
if ($target->hp <= 0) {
$target->hp = 0;
@ -786,59 +730,6 @@ 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.5) {
$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}");
}
}
/**
* 执行角色的回合行动 (通用)
*/
@ -847,10 +738,6 @@ class Battle
if ($actor->hp <= 0){
return false;
}
// 检查是否应该自动进入防护状态
$this->checkAutoEnterProtectMode($actor, $out);
// 1. 尝试使用法术
$selectedSpell = $this->smartSelectSpell($actor);
@ -886,8 +773,15 @@ class Battle
}
// 2. 如果没有使用法术,执行普通攻击
// 寻找目标(使用威胁值系统)
$target = $this->selectTargetWithThreat($actor);
// 寻找目标
$target = null;
$opponents = $this->getOpponents($actor);
foreach ($opponents as $enemy) {
if ($enemy->hp > 0) {
$target = $enemy;
break;
}
}
if (!$target) return true; // 无目标,回合结束
@ -921,16 +815,7 @@ class Battle
$out->writeln("{$this->cyan}{$this->reset} {$this->white}⚔️ 造成 {$damage} 点伤害{$this->reset}");
}
// 应用防护机制:防护角色承受更多伤害
$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}");
}
$target->hp -= $damage;
// 蓝量恢复机制
// 攻击者恢复 15 点

View File

@ -264,27 +264,26 @@ class InventoryPanel
$slot = $item['type'];
// 获取新装备原有的强化等级
$newItemEnhanceLevel = $item['enhanceLevel'] ?? 0;
// $newItemEnhanceLevel = 0;
// $newItemEnhanceLevel = $item['enhanceLevel'] ?? 0;
// 调整为不能继承强化等级
$newItemEnhanceLevel = 0;
// If there's already an item in the slot, swap enhance levels
// 调整为不能继承强化等级
// if (isset($player->equip[$slot]) && !empty($player->equip[$slot])) {
// $oldItem = $player->equip[$slot];
// $oldEnhanceLevel = $oldItem['enhanceLevel'] ?? 0;
//
// // 旧装备继承新装备的强化等级
// $oldItem['enhanceLevel'] = $newItemEnhanceLevel;
// $player->addItem($oldItem);
//
// $oldEnhanceStr = $oldEnhanceLevel > 0 ? "+{$oldEnhanceLevel}" : "";
// $newEnhanceStr = $newItemEnhanceLevel > 0 ? "+{$newItemEnhanceLevel}" : "";
// $out->writeln("已取下 {$oldItem['name']}{$newEnhanceStr} 并放入背包");
//
// // 新装备继承旧装备的强化等级
// $item['enhanceLevel'] = $oldEnhanceLevel;
// }
if (isset($player->equip[$slot]) && !empty($player->equip[$slot])) {
$oldItem = $player->equip[$slot];
$oldEnhanceLevel = $oldItem['enhanceLevel'] ?? 0;
// 旧装备继承新装备的强化等级
$oldItem['enhanceLevel'] = $newItemEnhanceLevel;
$player->addItem($oldItem);
$oldEnhanceStr = $oldEnhanceLevel > 0 ? "+{$oldEnhanceLevel}" : "";
$newEnhanceStr = $newItemEnhanceLevel > 0 ? "+{$newItemEnhanceLevel}" : "";
$out->writeln("已取下 {$oldItem['name']}{$newEnhanceStr} 并放入背包");
// 新装备继承旧装备的强化等级
$item['enhanceLevel'] = $oldEnhanceLevel;
}
$player->equip[$slot] = $item;

View File

@ -177,15 +177,6 @@ class StatsPanel
}
$out->writeln("║ HP: {$this->red}{$stats['hp']}{$this->reset}/{$stats['maxHp']}");
// 显示防护状态
$protectStatus = $actor->isProtecting ? "{$this->green}✓ 防护中{$this->reset}" : "{$this->red}✗ 未防护{$this->reset}";
$out->writeln("║ 状态: {$protectStatus}");
if ($actor->isProtecting) {
$out->writeln("║ 伤害减免: {$this->green}20%{$this->reset} | 伤害增加: {$this->red}30%{$this->reset}");
}
$out->writeln("║ 物攻: {$this->yellow}{$stats['patk']}{$this->reset}");
$out->writeln("║ 魔攻: {$this->blue}{$stats['matk']}{$this->reset}");
$out->writeln("║ 物防: {$this->yellow}{$stats['pdef']}{$this->reset}");
@ -278,10 +269,6 @@ class StatsPanel
$out->writeln("[1] 装备物品 | [2] 卸下装备 | [3] 强化装备");
$out->writeln("[5] 装备技能 | [6] 卸下技能 | [7] 强化技能");
// 防护状态切换
$protectToggle = $actor->isProtecting ? "p] 退出防护" : "[p] 进入防护";
$out->writeln("[{$protectToggle}");
if ($this->isPlayer) {
$out->writeln("[s] 切换角色 | [0] 返回");
} else {
@ -294,20 +281,6 @@ class StatsPanel
return $this->showCharacterSelect();
}
// 处理防护状态切换
if (strtolower($choice) === 'p') {
if ($actor->isProtecting) {
$actor->exitProtectMode();
$out->writeln("{$this->green}已退出防护状态{$this->reset}");
} else {
$actor->enterProtectMode();
$out->writeln("{$this->green}已进入防护状态{$this->reset}");
}
$this->game->saveState();
Screen::pause($out);
continue;
}
// 统一处理操作
switch ($choice) {
case '1':
@ -355,7 +328,7 @@ class StatsPanel
foreach ($slots as $slotKey => $slotName) {
$currentItem = $actor->equip[$slotKey] ?? null;
if ($currentItem) {
$this->game->output->writeln("[{$slotIdx}] {$slotName}: " . ItemDisplay::renderListItem($currentItem));
$this->game->output->writeln("[{$slotIdx}] {$slotName}: " . ItemDisplay::formatName($currentItem));
} else {
$this->game->output->writeln("[{$slotIdx}] {$slotName}: (空)");
}
@ -451,7 +424,7 @@ class StatsPanel
foreach ($slots as $slot => $name) {
if (!empty($actor->equip[$slot])) {
$item = $actor->equip[$slot];
$this->game->output->writeln("[{$idx}] {$name}: " . ItemDisplay::renderListItem($item));
$this->game->output->writeln("[{$idx}] {$name}: " . ItemDisplay::formatName($item));
$equipped[$idx] = $slot;
$idx++;
}
@ -536,7 +509,7 @@ class StatsPanel
if (!empty($actor->equip[$slot])) {
$item = $actor->equip[$slot];
$enhanceLevel = $item['enhanceLevel'] ?? 0;
$this->game->output->writeln("[{$idx}] {$name}: " . ItemDisplay::renderListItem($item) . " {$this->yellow}+{$enhanceLevel}{$this->reset}");
$this->game->output->writeln("[{$idx}] {$name}: " . ItemDisplay::formatName($item) . " {$this->yellow}+{$enhanceLevel}{$this->reset}");
$equipped[$idx] = $slot;
$idx++;
}
@ -593,7 +566,7 @@ class StatsPanel
$out->writeln("{$this->cyan} 装 备 强 化 等 级 选 择{$this->reset}");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("");
$out->writeln("装备: " . ItemDisplay::renderListItem($item));
$out->writeln("装备: " . ItemDisplay::formatName($item));
$out->writeln("当前等级: {$this->yellow}+{$enhanceLevel}{$this->reset}");
$out->writeln("");
$out->writeln("可选等级:");
@ -699,7 +672,7 @@ class StatsPanel
$out->writeln("{$this->cyan} 自 动 强 化 中{$this->reset}");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("");
$out->writeln("装备: " . ItemDisplay::renderListItem($item));
$out->writeln("装备: " . ItemDisplay::formatName($item));
$out->writeln("目标: +{$targetLevel}");
$out->writeln("");
@ -830,7 +803,7 @@ class StatsPanel
foreach ($skillSlots as $slot) {
$currentSpell = $actor->skillSlots[$slot] ?? null;
if ($currentSpell) {
$out->writeln("[{$i}] 技能{$i}: " . ItemDisplay::renderListItem($currentSpell));
$out->writeln("[{$i}] 技能{$i}: " . ItemDisplay::formatName($currentSpell));
} else {
$out->writeln("[{$i}] 技能{$i}: (空)");
}
@ -876,7 +849,7 @@ class StatsPanel
foreach ($skillSlots as $slot) {
$currentSpell = $actor->skillSlots[$slot] ?? null;
if ($currentSpell) {
$out->writeln("[{$i}] 技能{$i}: " . ItemDisplay::renderListItem($currentSpell));
$out->writeln("[{$i}] 技能{$i}: " . ItemDisplay::formatName($currentSpell));
$hasSkill = true;
} else {
$out->writeln("[{$i}] 技能{$i}: (空)");
@ -928,7 +901,7 @@ class StatsPanel
foreach ($skillSlots as $slot) {
$spell = $actor->skillSlots[$slot] ?? null;
if ($spell) {
$out->writeln("[{$i}] 技能{$i}: " . ItemDisplay::renderListItem($spell));
$out->writeln("[{$i}] 技能{$i}: " . ItemDisplay::formatName($spell));
$equipped[$i] = $slot;
$hasSkill = true;
} else {
@ -978,7 +951,7 @@ class StatsPanel
$out->writeln("{$this->cyan} 技 能 强 化 等 级 选 择{$this->reset}");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("");
$out->writeln("技能: " . ItemDisplay::renderListItem($item));
$out->writeln("技能: " . ItemDisplay::formatName($item));
$out->writeln("当前等级: {$this->yellow}+{$enhanceLevel}{$this->reset}");
$out->writeln("");
$out->writeln("可选等级:");
@ -1080,7 +1053,7 @@ class StatsPanel
$out->writeln("{$this->cyan} 自 动 强 化 中{$this->reset}");
$out->writeln("{$this->cyan}════════════════════════════════════{$this->reset}");
$out->writeln("");
$out->writeln("技能: " . ItemDisplay::renderListItem($item));
$out->writeln("技能: " . ItemDisplay::formatName($item));
$out->writeln("目标: +{$targetLevel}");
$out->writeln("");

View File

@ -4,86 +4,9 @@ use Game\Entities\Item;
require __DIR__ . '/../vendor/autoload.php';
$monster = \Game\Entities\Monster::create(6);
dd($monster->getRandomEquipmentDrops(100));
//$player = new \Game\Entities\Player();
$monster = \Game\Entities\Monster::create(1);
$weaponTemplate = [
'fixed_primary' => [
'patk' => ['base' => [4, 10, 18, 30], 'growth' => 1.5],
'matk' => ['base' => [2, 5, 10, 18], 'growth' => 0.8],
],
'random_primary_pool' => [
'crit' => ['weight' => 40, 'base' => [1, 3, 5, 10], 'growth' => 0.3],
'critdmg' => ['weight' => 40, 'base' => [3, 8, 14, 24], 'growth' => 0.7],
'matk' => ['weight' => 20, 'base' => [2, 5, 10, 18], 'growth' => 0.8],
],
'random_primary_count' => [
'common' => [0, 0], 'rare' => [0, 1], 'epic' => [1, 1], 'legendary' => [1, 2]
],
'affix_weights' => ['patk' => 30, 'matk' => 20, 'crit' => 25, 'critdmg' => 25, 'hp' => 10],
];
$armorTemplate = [
'fixed_primary' => [
'pdef' => ['base' => [2, 6, 12, 20], 'growth' => 0.6],
'mdef' => ['base' => [1, 4, 8, 15], 'growth' => 0.5],
],
'random_primary_pool' => [
'hp' => ['weight' => 100, 'base' => [10, 25, 45, 75], 'growth' => 3.5],
],
'random_primary_count' => [
'common' => [0, 0], 'rare' => [0, 1], 'epic' => [1, 1], 'legendary' => [1, 1],
],
'affix_weights' => ['pdef' => 30, 'mdef' => 30, 'hp' => 40, 'patk' => 5, 'matk' => 5],
];
$ringTemplate = [
'fixed_primary' => [
'crit' => ['base' => [2, 5, 8, 12], 'growth' => 0.4],
],
'random_primary_pool' => [
'critdmg' => ['weight' => 40, 'base' => [5, 12, 20, 35], 'growth' => 0.8],
'patk' => ['weight' => 30, 'base' => [2, 6, 12, 20], 'growth' => 0.8],
'matk' => ['weight' => 30, 'base' => [2, 6, 12, 20], 'growth' => 0.8],
],
'random_primary_count' => [
'common' => [0, 0], 'rare' => [0, 1], 'epic' => [1, 1], 'legendary' => [1, 2],
],
'affix_weights' => ['crit' => 30, 'critdmg' => 30, 'patk' => 20, 'matk' => 20],
];
$necklaceTemplate = [
'fixed_primary' => [
'hp' => ['base' => [15, 35, 60, 100], 'growth' => 4.0],
],
'random_primary_pool' => [
'pdef' => ['weight' => 25, 'base' => [1, 5, 10, 18], 'growth' => 0.5],
'mdef' => ['weight' => 25, 'base' => [1, 5, 10, 18], 'growth' => 0.5],
'critdmg' => ['weight' => 50, 'base' => [3, 8, 15, 25], 'growth' => 0.5],
],
'random_primary_count' => [
'common' => [0, 0], 'rare' => [0, 1], 'epic' => [1, 1], 'legendary' => [1, 2],
],
'affix_weights' => ['hp' => 30, 'pdef' => 20, 'mdef' => 20, 'crit' => 15, 'critdmg' => 15],
];
$bootsTemplate = [
'fixed_primary' => [
'pdef' => ['base' => [1, 4, 8, 15], 'growth' => 0.4],
'mdef' => ['base' => [1, 3, 6, 12], 'growth' => 0.3],
],
'random_primary_pool' => [
'hp' => ['weight' => 60, 'base' => [8, 20, 35, 60], 'growth' => 2.5],
'crit' => ['weight' => 40, 'base' => [1, 3, 5, 8], 'growth' => 0.2],
],
'random_primary_count' => [
'common' => [0, 0], 'rare' => [0, 1], 'epic' => [1, 1], 'legendary' => [1, 2],
],
'affix_weights' => ['pdef' => 25, 'mdef' => 25, 'hp' => 30, 'crit' => 20],
];
$player = new \Game\Entities\Player();
$res = Item::createSpell(1, 'common', 10);
// dd($monster->getRandomEquipmentDrops(100));
dd(Item::randomItem('armor', 30));
dd($monster->equip,$monster->getStats(),$monster->name,$monster->skillSlots);