188 lines
6.5 KiB
PHP
188 lines
6.5 KiB
PHP
<?php
|
||
namespace Game\Model;
|
||
|
||
// 继承 Character 基类
|
||
class Player extends Character {
|
||
protected int $level = 1;
|
||
protected int $currentXp = 0;
|
||
protected int $xpToNextLevel = 100;
|
||
|
||
// ⭐ 新增:已学习的技能列表
|
||
protected array $abilities = []; // 存储 Ability 实例
|
||
// ⭐ 新增:装备槽位,键是槽位名,值是 Item 对象
|
||
protected array $equipment = [
|
||
'weapon' => null,
|
||
'armor' => null,
|
||
'helmet' => null,
|
||
// 可根据需要添加 'ring', 'amulet' 等
|
||
];
|
||
public function __construct(string $name, int $maxHealth, int $attack, int $defense,int $maxMana = 50) {
|
||
// 调用父类 (Character) 的构造函数来初始化核心属性
|
||
parent::__construct($name, $maxHealth, $attack, $defense,$maxMana);
|
||
}
|
||
|
||
// ⭐ 新增:获取装备
|
||
public function getEquipment(): array {
|
||
return $this->equipment;
|
||
}
|
||
|
||
// ⭐ 新增:设置装备 (由 EquipmentService 调用)
|
||
public function setEquipment(string $slot, ?Item $item): void {
|
||
$this->equipment[$slot] = $item;
|
||
}
|
||
|
||
// ⭐ 新增方法:提升等级
|
||
public function incrementLevel(): void {
|
||
$this->level++;
|
||
}
|
||
|
||
// ⭐ 新增方法:扣除升级所需的经验值并计算新的经验值目标
|
||
public function subtractXpToNextLevel(): void {
|
||
// 计算溢出的经验值(如果有)
|
||
$excessXp = $this->currentXp - $this->xpToNextLevel;
|
||
|
||
// 设置新的经验值
|
||
$this->currentXp = $excessXp;
|
||
|
||
// 计算下一次升级所需的经验值 (简化公式:增加 50% 难度)
|
||
$this->xpToNextLevel = (int)($this->xpToNextLevel * 1.5);
|
||
}
|
||
|
||
// ⭐ 新增方法:设置经验值 (用于存档加载)
|
||
public function setXpToNextLevel(int $xp): void {
|
||
$this->xpToNextLevel = $xp;
|
||
}
|
||
|
||
// ⭐ 确保 setLevel 存在 (用于存档加载)
|
||
public function setLevel(int $level): void {
|
||
$this->level = $level;
|
||
}
|
||
|
||
// ⭐ 新增方法:学习技能
|
||
public function learnAbility(Ability $ability): void {
|
||
$this->abilities[$ability->id] = $ability;
|
||
}
|
||
|
||
// ⭐ 新增方法:获取所有技能
|
||
public function getAbilities(): array {
|
||
return $this->abilities;
|
||
}
|
||
|
||
// ⭐ 新增:货币属性
|
||
protected int $gold = 0;
|
||
|
||
// ... 现有构造函数和 Getter ...
|
||
|
||
// ⭐ 新增 Getter
|
||
public function getGold(): int { return $this->gold; }
|
||
|
||
// ⭐ 新增 Setter/Modifier
|
||
public function gainGold(int $amount): void {
|
||
$this->gold += $amount;
|
||
}
|
||
|
||
protected array $completedQuests = []; // 存储已完成的任务 ID
|
||
// ⭐ 新增方法:添加/接受任务
|
||
/**
|
||
* @var Quest[] 当前活跃任务列表 (键为 Quest ID)
|
||
*/
|
||
protected array $activeQuests = [];
|
||
// ...
|
||
|
||
// ⭐ 修正方法:接受 Quest 对象
|
||
public function addActiveQuest(Quest $quest): void {
|
||
// 使用任务 ID 作为键,存储整个 Quest 对象
|
||
$this->activeQuests[$quest->getId()] = $quest;
|
||
}
|
||
|
||
// ⭐ 确保 setInventory 存在 (用于存档加载)
|
||
// 如果存档时将 Quest 对象序列化了,这里可能需要反序列化逻辑,
|
||
// 但现在我们只确保它可以接受数组。
|
||
public function setActiveQuests(array $quests): void {
|
||
$this->activeQuests = $quests;
|
||
}
|
||
|
||
public function getActiveQuests(): array {
|
||
return $this->activeQuests;
|
||
}
|
||
|
||
// ⭐ 新增方法:更新任务进度
|
||
public function updateQuestProgress(string $questId, int $count = 1): void {
|
||
if (isset($this->activeQuests[$questId])) {
|
||
$progress = &$this->activeQuests[$questId]; // 使用引用
|
||
if (!$progress['isCompleted']) {
|
||
$progress['currentCount'] += $count;
|
||
if ($progress['currentCount'] >= $progress['targetCount']) {
|
||
$progress['currentCount'] = $progress['targetCount'];
|
||
$progress['isCompleted'] = true;
|
||
// 触发 QuestCompletedEventRequest
|
||
// 注意:实际的奖励和标记完成应在 QuestService 确认后进行
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// ⭐ 新增方法:标记任务完成
|
||
public function markQuestCompleted(string $questId): void {
|
||
unset($this->activeQuests[$questId]);
|
||
$this->completedQuests[] = $questId;
|
||
}
|
||
|
||
// ⭐ 新增方法:检查任务是否已完成
|
||
public function isQuestCompleted(string $questId): bool {
|
||
return in_array($questId, $this->completedQuests);
|
||
}
|
||
|
||
// ⭐ 新增:玩家背包 (存储 Item 实例)
|
||
protected array $inventory = [];
|
||
|
||
// ... 现有构造函数和 Getter ...
|
||
|
||
// ⭐ 新增方法:添加物品到背包
|
||
public function addItem(Item $item): void {
|
||
$this->inventory[] = $item;
|
||
}
|
||
|
||
// ⭐ 新增方法:获取背包
|
||
public function getInventory(): array {
|
||
return $this->inventory;
|
||
}
|
||
|
||
// Player 特有的 Getter 方法
|
||
public function getLevel(): int { return $this->level; }
|
||
public function getCurrentXp(): int { return $this->currentXp; }
|
||
public function getXpToNextLevel(): int { return $this->xpToNextLevel; }
|
||
|
||
// Player 特有的 Setter/Modifier 方法
|
||
public function gainXp(int $amount): void {
|
||
$this->currentXp += $amount;
|
||
// TODO: 未来在这里实现升级逻辑 (LevelUpEvent)
|
||
}
|
||
|
||
public function removeItemByIndex(int $index): bool {
|
||
if (isset($this->inventory[$index])) {
|
||
unset($this->inventory[$index]);
|
||
// 重新索引数组,确保背包索引连续
|
||
$this->inventory = array_values($this->inventory);
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
// ⭐ 新增 Player 特有的 Setter:
|
||
|
||
public function setCurrentXp(int $xp): void { $this->currentXp = $xp; }
|
||
public function setGold(int $gold): void { $this->gold = $gold; }
|
||
public function setInventory(array $inventory): void {
|
||
// WARNING: 这里的 inventory 数组可能只包含序列化数据,需要确保 Item 实例化
|
||
// 在我们当前简化的JSON方案中,暂且直接赋值原始数据。
|
||
$this->inventory = $inventory;
|
||
}
|
||
public function getCompletedQuests(): array { return $this->completedQuests; } // 确保这个 Getter 存在
|
||
public function setCompletedQuests(array $quests): void { $this->completedQuests = $quests; }
|
||
|
||
public function setHealth(mixed $health)
|
||
{
|
||
$this->health = $health;
|
||
}
|
||
} |