115 lines
4.2 KiB
PHP
115 lines
4.2 KiB
PHP
<?php
|
||
namespace Game\System;
|
||
|
||
use Game\Database\AbilityRepository;
|
||
use Game\Event\Event;
|
||
use Game\Event\EventListenerInterface;
|
||
use Game\Event\EventDispatcher;
|
||
use Game\Model\Ability;
|
||
use Game\Model\Player;
|
||
use Game\Model\Enemy; // 假设战斗逻辑中需要 Enemy
|
||
|
||
/**
|
||
* AbilityService: 负责技能的加载、管理和效果计算。
|
||
*/
|
||
class AbilityService implements EventListenerInterface {
|
||
|
||
private EventDispatcher $dispatcher;
|
||
private StateManager $stateManager;
|
||
|
||
// ... 现有属性 ...
|
||
private AbilityRepository $abilityRepository;
|
||
|
||
// ⭐ 修正构造函数:注入 AbilityRepository
|
||
public function __construct(EventDispatcher $dispatcher, StateManager $stateManager, AbilityRepository $abilityRepository) {
|
||
$this->dispatcher = $dispatcher;
|
||
$this->stateManager = $stateManager;
|
||
$this->abilityRepository = $abilityRepository;
|
||
}
|
||
|
||
|
||
public function learnInitialAbilities(Player $player): void {
|
||
$initialAbilities = ['FIREBALL', 'HEAL']; // 仍然可以硬编码初始技能的ID
|
||
|
||
foreach ($initialAbilities as $id) {
|
||
// ⭐ 使用 Repository 获取数据
|
||
$data = $this->abilityRepository->find($id);
|
||
if ($data) {
|
||
$player->learnAbility(new Ability(
|
||
$data['id'],
|
||
$data['name'],
|
||
$data['type'],
|
||
$data['mana_cost'],
|
||
$data['power'],
|
||
$data['scaling']
|
||
));
|
||
}
|
||
}
|
||
}
|
||
|
||
public function handleEvent(Event $event): void {
|
||
switch ($event->getType()) {
|
||
case 'GameStartEvent':
|
||
// 确保在游戏开始时玩家获得技能
|
||
$this->learnInitialAbilities($this->stateManager->getPlayer());
|
||
break;
|
||
case 'CastAbilityEvent': // 响应 BattleService 的请求
|
||
$this->handleCastAbility($event->getPayload()['abilityId'], $event->getPayload()['target']);
|
||
break;
|
||
// TODO: 未来监听 LevelUpEvent 来学习新技能
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理技能施放的核心逻辑
|
||
*/
|
||
private function handleCastAbility(string $abilityId, Enemy $target): void {
|
||
$player = $this->stateManager->getPlayer();
|
||
$ability = $player->getAbilities()[$abilityId] ?? null;
|
||
|
||
if (!$ability) {
|
||
$this->dispatcher->dispatch(new Event('SystemMessage', ['message' => '❌ 未知的技能。']));
|
||
return;
|
||
}
|
||
|
||
// 1. 检查资源消耗
|
||
if (!$player->spendMana($ability->manaCost)) {
|
||
$this->dispatcher->dispatch(new Event('SystemMessage', ['message' => '❌ MP不足,无法施放 ' . $ability->name . '。']));
|
||
return;
|
||
}
|
||
|
||
$this->dispatcher->dispatch(new Event('SystemMessage', ['message' => "✨ {$player->getName()} 施放了 <fg=blue>{$ability->name}</>!(-{$ability->manaCost} MP)"]));
|
||
|
||
// 2. 计算效果
|
||
$damage = 0;
|
||
$heal = 0;
|
||
|
||
$scalingValue = match ($ability->scaling) {
|
||
'attack' => $player->getAttack(),
|
||
'mana' => $player->getMaxMana(), // 魔法值越高,技能越强
|
||
default => 0,
|
||
};
|
||
|
||
// 基础伤害计算:威力 + (加成属性 * 0.5)
|
||
$rawEffect = $ability->power + (int)($scalingValue * 0.5);
|
||
|
||
// 3. 应用效果
|
||
switch ($ability->type) {
|
||
case 'damage':
|
||
$damage = $target->takeDamage($rawEffect);
|
||
$this->dispatcher->dispatch(new Event('SystemMessage', [
|
||
'message' => "💥 {$ability->name} 对 {$target->getName()} 造成了 <fg=red>{$damage}</> 点伤害!"
|
||
]));
|
||
break;
|
||
case 'heal':
|
||
$heal = $player->heal($rawEffect);
|
||
$this->dispatcher->dispatch(new Event('SystemMessage', [
|
||
'message' => "💖 恢复了 <fg=green>{$heal}</> 点生命值!"
|
||
]));
|
||
break;
|
||
}
|
||
|
||
// 4. 触发 BattleService 的事件,让其检查战斗是否结束
|
||
$this->dispatcher->dispatch(new Event('AbilityEffectApplied', ['target' => $target]));
|
||
}
|
||
} |