hanli/src/Entities/Player.php
hant 1cff247906 重构: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>
2025-12-03 22:09:34 +08:00

247 lines
6.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Game\Entities;
use Game\Entities\Partner;
class Player extends Actor
{
// Player特有的天赋名称
public static array $talentNames = [
'hp' => '生命',
'patk' => '物攻',
'matk' => '魔攻',
'pdef' => '物防',
'mdef' => '魔防',
'crit' => '暴击',
'critdmg' => '暴伤',
];
// Player特有的NPC交互标记
public array $npcFlags = [];
// Player特有的同伴系统
public int $maxPartners = 2; // 最多可携带同伴数
public array $partners = []; // 已招募的同伴
/**
* 增加灵石
*/
public function addSpiritStones(int $amount): void
{
$this->spiritStones += $amount;
}
/**
* 扣除灵石(返回是否成功)
*/
public function spendSpiritStones(int $amount): bool
{
if ($this->spiritStones >= $amount) {
$this->spiritStones -= $amount;
return true;
}
return false;
}
/**
* 恢复生命值,不超过上限
* @param int $amount 恢复量
* @return int 实际恢复量
*/
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 learnSpell(int $spellId): bool
{
if (!isset($this->spells[$spellId])) {
$this->spells[$spellId] = ['level' => 1];
return true;
}
return false;
}
/**
* 升级法术等级
*/
public function upgradeSpell(int $spellId): bool
{
if (!isset($this->spells[$spellId])) {
return false;
}
$this->spells[$spellId]['level'] = min($this->spells[$spellId]['level'] + 1, 10);
return true;
}
/**
* 检查是否已学习法术
*/
public function hasSpell(int $spellId): bool
{
return isset($this->spells[$spellId]);
}
/**
* 获取法术等级
*/
public function getSpellLevel(int $spellId): int
{
return $this->spells[$spellId]['level'] ?? 0;
}
/**
* 添加法术资源书
*/
public function addSpellBook(int $spellId, int $quantity = 1): void
{
if (!isset($this->spellBooks[$spellId])) {
$this->spellBooks[$spellId] = 0;
}
$this->spellBooks[$spellId] += $quantity;
}
/**
* 消耗法术资源书
*/
public function spendSpellBooks(int $spellId, int $quantity = 1): bool
{
if (($this->spellBooks[$spellId] ?? 0) >= $quantity) {
$this->spellBooks[$spellId] -= $quantity;
return true;
}
return false;
}
/**
* 获取法术资源书数量
*/
public function getSpellBookCount(int $spellId): int
{
return $this->spellBooks[$spellId] ?? 0;
}
/**
* Player特有的经验获取升级时会恢复生命值
*/
public function gainExp(int $amount): bool
{
$this->exp += $amount;
if ($this->exp >= $this->maxExp) {
$this->level++;
$this->exp -= $this->maxExp;
$this->maxExp = (int)($this->maxExp * 1.5);
// 升级获得天赋点每级3点并通过 autoAllocateTalents 自动分配
$this->autoAllocateTalents(3);
// 升级时恢复全部生命值
$this->fullHeal();
return true; // Leveled up
}
return false;
}
/**
* Player特有的分配天赋点返回布尔值
*/
public function allocateTalent(string $talent, int $points = 1): bool
{
if ($points <= 0 || $this->talentPoints < $points) {
return false;
}
if (!isset($this->talents[$talent])) {
return false;
}
$this->talents[$talent] += $points;
$this->talentPoints -= $points;
return true;
}
/**
* Player特有的重置天赋返还所有点数
*/
public function resetTalents(): int
{
$total = array_sum($this->talents);
$this->talentPoints += $total;
foreach ($this->talents as $key => $value) {
$this->talents[$key] = 0;
}
return $total;
}
public function addItem(array $item)
{
// Handle stacking for consumables
if (($item['type'] ?? '') === 'consume') {
foreach ($this->inventory as &$existingItem) {
// Check if it's the same item (compare name, heal, quality, level)
// We exclude 'id' and 'quantity' from comparison
$isSame = ($existingItem['name'] === $item['name']) &&
(($existingItem['heal'] ?? 0) === ($item['heal'] ?? 0)) &&
(($existingItem['quality'] ?? '') === ($item['quality'] ?? '')) &&
(($existingItem['level'] ?? 1) === ($item['level'] ?? 1));
if ($isSame) {
$existingItem['quantity'] = ($existingItem['quantity'] ?? 1) + 1;
return;
}
}
}
// Assign a unique ID to the item to handle duplicates
$item['id'] = uniqid();
// Initialize quantity for new items
$item['quantity'] = 1;
$this->inventory[] = $item;
}
/**
* 招募同伴
*/
public function recruitPartner(Partner $partner): bool
{
if (count($this->partners) >= $this->maxPartners) {
return false;
}
$this->partners[$partner->id] = $partner;
return true;
}
/**
* 解散同伴
*/
public function dismissPartner(string $partnerId): bool
{
if (isset($this->partners[$partnerId])) {
unset($this->partners[$partnerId]);
return true;
}
return false;
}
/**
* 获取同伴
*/
public function getPartner(string $partnerId): ?Partner
{
return $this->partners[$partnerId] ?? null;
}
}