重构:Partner 继承 Actor 类
- Partner 现在继承 Actor,获得统一的天赋、法术和属性系统
- Partner 覆盖 talentBonus 为自己的特殊值(hp 20, critdmg 10)
- Partner 覆盖 getStats() 以支持自定义的 baseStats 和 growth 系数
- Partner 保留特有的 autoAllocateTalent() 方法(私有,确保 HP 至少加1点)
- Partner 覆盖 gainExp() 以调用自己的 autoAllocateTalent()
- 删除重复的方法:heal(), recoverMana(), spendMana(), learnSpell()
- 保留特有方法:getTotalTalentPoints(), hasSpell(), getSpellLevel()
- 简化 Partner 构造函数,使用 Actor 的属性
统一体系:所有 Actor 子类(Player, Partner, Monster, NPC)都继承同一套天赋和属性系统
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e593d81942
commit
1cff247906
|
|
@ -141,18 +141,6 @@ class Actor
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置所有天赋
|
||||
*/
|
||||
public function resetTalents(): void
|
||||
{
|
||||
$spent = array_sum($this->talents);
|
||||
foreach ($this->talents as $key => $_) {
|
||||
$this->talents[$key] = 0;
|
||||
}
|
||||
$this->talentPoints += $spent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动分配天赋(根据权重)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,40 +1,12 @@
|
|||
<?php
|
||||
namespace Game\Entities;
|
||||
|
||||
class Partner
|
||||
class Partner extends Actor
|
||||
{
|
||||
public string $id;
|
||||
public string $name;
|
||||
// Partner特有的基础属性配置
|
||||
public array $baseStats = [];
|
||||
public array $equip = []; // weapon, armor, ring, boots, necklace
|
||||
|
||||
// 法术系统
|
||||
public array $spells = []; // 已学习的法术ID列表
|
||||
public array $spellBooks = []; // 拥有的法术资源书
|
||||
|
||||
// 天赋系统
|
||||
public array $talents = [
|
||||
'hp' => 0,
|
||||
'patk' => 0,
|
||||
'matk' => 0,
|
||||
'pdef' => 0,
|
||||
'mdef' => 0,
|
||||
'crit' => 0,
|
||||
'critdmg' => 0,
|
||||
];
|
||||
|
||||
// 天赋权重(决定升级时自动加点的倾向)
|
||||
public array $talentWeights = [
|
||||
'hp' => 1,
|
||||
'patk' => 1,
|
||||
'matk' => 1,
|
||||
'pdef' => 1,
|
||||
'mdef' => 1,
|
||||
'crit' => 1,
|
||||
'critdmg' => 1,
|
||||
];
|
||||
|
||||
// 天赋每点提供的属性(与Player相同)
|
||||
// Partner特有的天赋加成(与 Actor 不同)
|
||||
public static array $talentBonus = [
|
||||
'hp' => 20,
|
||||
'patk' => 5,
|
||||
|
|
@ -69,21 +41,8 @@ class Partner
|
|||
}
|
||||
|
||||
/**
|
||||
* 获取天赋提供的属性加成
|
||||
* Partner特有的属性计算(基于baseStats和growth)
|
||||
*/
|
||||
public function getTalentStats(): array
|
||||
{
|
||||
return [
|
||||
'maxHp' => $this->talents['hp'] * self::$talentBonus['hp'],
|
||||
'patk' => $this->talents['patk'] * self::$talentBonus['patk'],
|
||||
'matk' => $this->talents['matk'] * self::$talentBonus['matk'],
|
||||
'pdef' => $this->talents['pdef'] * self::$talentBonus['pdef'],
|
||||
'mdef' => $this->talents['mdef'] * self::$talentBonus['mdef'],
|
||||
'crit' => $this->talents['crit'] * self::$talentBonus['crit'],
|
||||
'critdmg' => $this->talents['critdmg'] * self::$talentBonus['critdmg'],
|
||||
];
|
||||
}
|
||||
|
||||
public function getStats(): array
|
||||
{
|
||||
// Calculate base stats based on level and growth
|
||||
|
|
@ -217,6 +176,9 @@ class Partner
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Partner特有的升级逻辑,自动分配天赋点
|
||||
*/
|
||||
public function gainExp(int $amount): bool
|
||||
{
|
||||
$this->exp += $amount;
|
||||
|
|
@ -225,7 +187,7 @@ class Partner
|
|||
$this->exp -= $this->maxExp;
|
||||
$this->maxExp = (int)($this->maxExp * 1.5);
|
||||
|
||||
// 升级时自动分配3点天赋(根据权重)
|
||||
// 升级时自动分配3点天赋(根据权重,且 HP 至少加1点)
|
||||
$this->autoAllocateTalent(3);
|
||||
|
||||
return true;
|
||||
|
|
@ -241,54 +203,6 @@ class Partner
|
|||
return array_sum($this->talents);
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复队友血量
|
||||
*/
|
||||
public function heal(int $amount): int
|
||||
{
|
||||
$stats = $this->getStats();
|
||||
$maxHp = $stats['maxHp'];
|
||||
|
||||
$oldHp = $this->hp;
|
||||
$this->hp = min($this->hp + $amount, $maxHp);
|
||||
|
||||
return $this->hp - $oldHp; // 返回实际恢复的血量
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复魔法值,不超过上限
|
||||
*/
|
||||
public function recoverMana(int $amount): int
|
||||
{
|
||||
$oldMana = $this->mana;
|
||||
$this->mana = min($this->mana + $amount, $this->maxMana);
|
||||
return $this->mana - $oldMana;
|
||||
}
|
||||
|
||||
/**
|
||||
* 消耗魔法值(返回是否成功)
|
||||
*/
|
||||
public function spendMana(int $amount): bool
|
||||
{
|
||||
if ($this->mana >= $amount) {
|
||||
$this->mana -= $amount;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 学习法术
|
||||
*/
|
||||
public function learnSpell(int $spellId): bool
|
||||
{
|
||||
if (!isset($this->spells[$spellId])) {
|
||||
$this->spells[$spellId] = ['level' => 1];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已学习法术
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -60,47 +60,6 @@ class Player extends Actor
|
|||
return $this->hp - $oldHp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完全恢复生命值
|
||||
*/
|
||||
public function fullHeal(): void
|
||||
{
|
||||
$stats = $this->getStats();
|
||||
$this->hp = $stats['maxHp'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复魔法值,不超过上限
|
||||
* @param int $amount 恢复量
|
||||
* @return int 实际恢复量
|
||||
*/
|
||||
public function recoverMana(int $amount): int
|
||||
{
|
||||
$oldMana = $this->mana;
|
||||
$this->mana = min($this->mana + $amount, $this->maxMana);
|
||||
return $this->mana - $oldMana;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完全恢复魔法值
|
||||
*/
|
||||
public function fullRecoverMana(): void
|
||||
{
|
||||
$this->mana = $this->maxMana;
|
||||
}
|
||||
|
||||
/**
|
||||
* 消耗魔法值(返回是否成功)
|
||||
*/
|
||||
public function spendMana(int $amount): bool
|
||||
{
|
||||
if ($this->mana >= $amount) {
|
||||
$this->mana -= $amount;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 学习法术
|
||||
*/
|
||||
|
|
@ -284,99 +243,4 @@ class Player extends Actor
|
|||
{
|
||||
return $this->partners[$partnerId] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate total stats including base, talents, equipment, and affixes.
|
||||
* @return array ['maxHp' => int, 'patk' => int, 'matk' => int, 'pdef' => int, 'mdef' => int, 'crit' => int, 'critdmg' => float]
|
||||
*/
|
||||
public function getStats(): array
|
||||
{
|
||||
// 获取天赋加成
|
||||
$talentStats = $this->getTalentStats();
|
||||
|
||||
$stats = [
|
||||
'maxHp' => $this->maxHp + $talentStats['maxHp'],
|
||||
'patk' => $this->patk + $talentStats['patk'],
|
||||
'matk' => $this->matk + $talentStats['matk'],
|
||||
'pdef' => $this->pdef + $talentStats['pdef'],
|
||||
'mdef' => $this->mdef + $talentStats['mdef'],
|
||||
'crit' => $this->crit + $talentStats['crit'],
|
||||
'critdmg' => $this->critdmg + $talentStats['critdmg'],
|
||||
];
|
||||
|
||||
$percentBonuses = [
|
||||
'maxHp' => 0,
|
||||
'patk' => 0,
|
||||
'matk' => 0,
|
||||
'pdef' => 0,
|
||||
'mdef' => 0,
|
||||
'crit' => 0,
|
||||
'critdmg' => 0,
|
||||
];
|
||||
|
||||
// 1. Add Equipment Base Stats & Parse Affixes
|
||||
foreach ($this->equip as $item) {
|
||||
if (empty($item)) continue;
|
||||
|
||||
// 计算强化加成(每级+5%)
|
||||
$enhanceLevel = $item['enhanceLevel'] ?? 0;
|
||||
$enhanceMultiplier = 1 + ($enhanceLevel * 0.05);
|
||||
|
||||
// Base Stats (主属性) - 应用强化加成
|
||||
$stats['maxHp'] += (int)(($item['hp'] ?? 0) * $enhanceMultiplier);
|
||||
$stats['patk'] += (int)(($item['patk'] ?? 0) * $enhanceMultiplier);
|
||||
$stats['matk'] += (int)(($item['matk'] ?? 0) * $enhanceMultiplier);
|
||||
$stats['pdef'] += (int)(($item['pdef'] ?? 0) * $enhanceMultiplier);
|
||||
$stats['mdef'] += (int)(($item['mdef'] ?? 0) * $enhanceMultiplier);
|
||||
$stats['crit'] += (int)(($item['crit'] ?? 0) * $enhanceMultiplier);
|
||||
$stats['critdmg'] += (int)(($item['critdmg'] ?? 0) * $enhanceMultiplier);
|
||||
|
||||
// Affixes (副属性)
|
||||
if (!empty($item['affixes'])) {
|
||||
foreach ($item['affixes'] as $affix) {
|
||||
$this->parseAffix($affix, $stats, $percentBonuses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Apply Percentage Bonuses
|
||||
foreach ($stats as $key => $val) {
|
||||
if (isset($percentBonuses[$key]) && $percentBonuses[$key] > 0) {
|
||||
$stats[$key] = (int)($val * (1 + $percentBonuses[$key] / 100));
|
||||
}
|
||||
}
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
private function parseAffix(string $affix, array &$flatStats, array &$percentStats)
|
||||
{
|
||||
// Example: "物攻 +5% (T1)" or "生命值 +20 (T1)"
|
||||
if (preg_match('/(物攻|魔攻|物防|魔防|生命值|暴击率|暴击伤害)\s+\+(\d+)(%?)/', $affix, $matches)) {
|
||||
$name = $matches[1];
|
||||
$value = (int)$matches[2];
|
||||
$isPercent = $matches[3] === '%';
|
||||
|
||||
$key = match ($name) {
|
||||
'物攻' => 'patk',
|
||||
'魔攻' => 'matk',
|
||||
'物防' => 'pdef',
|
||||
'魔防' => 'mdef',
|
||||
'生命值' => 'maxHp',
|
||||
'暴击' => 'crit',
|
||||
'暴击率' => 'crit',
|
||||
'暴击伤害' => 'critdmg',
|
||||
default => null
|
||||
};
|
||||
|
||||
if ($key) {
|
||||
// Crit and CritDmg are always treated as flat additions (even if they have %)
|
||||
if ($isPercent && !in_array($key, ['crit', 'critdmg'])) {
|
||||
$percentStats[$key] += $value;
|
||||
} else {
|
||||
$flatStats[$key] += $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user