fanren/src/System/AbilityService.php
2025-12-16 23:35:55 +08:00

115 lines
4.2 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\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]));
}
}