重构:将天赋系统统一移到 Actor 基类
- 将天赋系统 (talents, talentWeights, talentBonus, getTalentStats) 集中在 Actor 基类
- 添加 allocateTalent(), resetTalents(), autoAllocateTalents(), gainExp() 到 Actor
- Monster 保留特有的基础属性、奖励和掉落表
- NPC 保留特有的标识和配置相关属性
- Player 保留特有的名称映射、NPC 标记、同伴系统和升级治疗逻辑
- 删除所有重复代码,提高代码复用性和可维护性
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
05bff41e35
commit
e593d81942
|
|
@ -3,7 +3,7 @@ namespace Game\Entities;
|
||||||
|
|
||||||
class Actor
|
class Actor
|
||||||
{
|
{
|
||||||
// Common properties shared by Player, Partner, Monster
|
// Common properties shared by Player, Partner, Monster, NPC
|
||||||
public string $name = '';
|
public string $name = '';
|
||||||
public int $level = 1;
|
public int $level = 1;
|
||||||
public int $exp = 0;
|
public int $exp = 0;
|
||||||
|
|
@ -29,6 +29,40 @@ class Actor
|
||||||
|
|
||||||
public int $spiritStones = 0;
|
public int $spiritStones = 0;
|
||||||
|
|
||||||
|
// 天赋系统(所有Actor都支持)
|
||||||
|
public int $talentPoints = 0;
|
||||||
|
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,
|
||||||
|
];
|
||||||
|
|
||||||
|
// 天赋每点提供的属性
|
||||||
|
public static array $talentBonus = [
|
||||||
|
'hp' => 10,
|
||||||
|
'patk' => 5,
|
||||||
|
'matk' => 4,
|
||||||
|
'pdef' => 3,
|
||||||
|
'mdef' => 3,
|
||||||
|
'crit' => 1,
|
||||||
|
'critdmg' => 5,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Heal by amount, not exceeding max HP. Returns actual healed amount.
|
* Heal by amount, not exceeding max HP. Returns actual healed amount.
|
||||||
*/
|
*/
|
||||||
|
|
@ -74,7 +108,103 @@ class Actor
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unified getStats used by Player, Partner, Monster.
|
* 获取天赋属性加成
|
||||||
|
*/
|
||||||
|
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 allocateTalent(string $talent, int $points): bool
|
||||||
|
{
|
||||||
|
if ($points < 0 || $points > $this->talentPoints) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($this->talents[$talent])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->talents[$talent] += $points;
|
||||||
|
$this->talentPoints -= $points;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置所有天赋
|
||||||
|
*/
|
||||||
|
public function resetTalents(): void
|
||||||
|
{
|
||||||
|
$spent = array_sum($this->talents);
|
||||||
|
foreach ($this->talents as $key => $_) {
|
||||||
|
$this->talents[$key] = 0;
|
||||||
|
}
|
||||||
|
$this->talentPoints += $spent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动分配天赋(根据权重)
|
||||||
|
*/
|
||||||
|
public function autoAllocateTalents(int $points): void
|
||||||
|
{
|
||||||
|
if ($points <= 0 || empty($this->talentWeights)) {
|
||||||
|
$this->talentPoints += $points;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalWeight = array_sum($this->talentWeights);
|
||||||
|
if ($totalWeight <= 0) {
|
||||||
|
$this->talentPoints += $points;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按照权重比例分配天赋点
|
||||||
|
foreach ($this->talents as $talent => &$value) {
|
||||||
|
if (isset($this->talentWeights[$talent])) {
|
||||||
|
$weight = $this->talentWeights[$talent];
|
||||||
|
$allocation = (int)($points * ($weight / $totalWeight));
|
||||||
|
$value += $allocation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得经验并检查升级
|
||||||
|
*/
|
||||||
|
public function gainExp(int $amount): bool
|
||||||
|
{
|
||||||
|
$this->exp += $amount;
|
||||||
|
|
||||||
|
$leveled = false;
|
||||||
|
while ($this->exp >= $this->maxExp) {
|
||||||
|
$this->exp -= $this->maxExp;
|
||||||
|
$this->level++;
|
||||||
|
|
||||||
|
// 分配天赋点(每级3点)
|
||||||
|
$this->autoAllocateTalents(3);
|
||||||
|
|
||||||
|
// 增加下一级所需的经验
|
||||||
|
$this->maxExp = (int)($this->maxExp * 1.2);
|
||||||
|
|
||||||
|
$leveled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $leveled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unified getStats used by Player, Partner, Monster, NPC.
|
||||||
* Merges base stats, equipment bonuses, affixes, and optional talent modifiers provided by subclasses.
|
* Merges base stats, equipment bonuses, affixes, and optional talent modifiers provided by subclasses.
|
||||||
*/
|
*/
|
||||||
public function getStats(): array
|
public function getStats(): array
|
||||||
|
|
@ -92,13 +222,11 @@ class Actor
|
||||||
|
|
||||||
$percentBonuses = array_fill_keys(array_keys($base), 0);
|
$percentBonuses = array_fill_keys(array_keys($base), 0);
|
||||||
|
|
||||||
// 1. If subclass provides talent-like stats, merge them
|
// 1. Apply talent bonuses
|
||||||
if (method_exists($this, 'getTalentStats')) {
|
|
||||||
$talent = $this->getTalentStats();
|
$talent = $this->getTalentStats();
|
||||||
foreach ($talent as $k => $v) {
|
foreach ($talent as $k => $v) {
|
||||||
if (isset($base[$k])) $base[$k] += $v;
|
if (isset($base[$k])) $base[$k] += $v;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Apply equipment base stats and collect affix percent bonuses
|
// 2. Apply equipment base stats and collect affix percent bonuses
|
||||||
foreach ($this->equip as $item) {
|
foreach ($this->equip as $item) {
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,19 @@ namespace Game\Entities;
|
||||||
|
|
||||||
class Monster extends Actor
|
class Monster extends Actor
|
||||||
{
|
{
|
||||||
public string $name = '普通怪物';
|
// Monster特有的基础属性(不含装备加成)
|
||||||
public int $level = 1;
|
public int $baseHp = 20;
|
||||||
public int $baseHp = 20; // 基础HP(不含装备加成)
|
public int $basePatk = 4;
|
||||||
public int $basePatk = 4; // 基础物理攻击(不含装备加成)
|
public int $baseMatk = 2;
|
||||||
public int $baseMatk = 2; // 基础魔法攻击(不含装备加成)
|
public int $basePdef = 0;
|
||||||
public int $basePdef = 0; // 基础物理防御(不含装备加成)
|
public int $baseMdef = 0;
|
||||||
public int $baseMdef = 0; // 基础魔法防御(不含装备加成)
|
|
||||||
|
// Monster特有的奖励属性
|
||||||
public int $expReward = 10;
|
public int $expReward = 10;
|
||||||
public int $spiritStoneReward = 0; // 灵石奖励
|
public int $spiritStoneReward = 0;
|
||||||
public array $dropTable = []; // 消耗品掉落表 ['item' => [...], 'rate' => 0.5]
|
|
||||||
|
// Monster特有的掉落表
|
||||||
|
public array $dropTable = [];
|
||||||
|
|
||||||
public static function create(int $dungeonId): self
|
public static function create(int $dungeonId): self
|
||||||
{
|
{
|
||||||
|
|
@ -231,6 +234,7 @@ class Monster extends Actor
|
||||||
$this->critdmg += $item['critdmg'] ?? 0;
|
$this->critdmg += $item['critdmg'] ?? 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取怪物装备的物品列表(用于战斗胜利时掉落)
|
* 获取怪物装备的物品列表(用于战斗胜利时掉落)
|
||||||
* @return array
|
* @return array
|
||||||
|
|
@ -245,4 +249,23 @@ class Monster extends Actor
|
||||||
}
|
}
|
||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 随机掉落装备物品(从穿着的装备随机掉落)
|
||||||
|
* @param int $dropRate 掉落概率(0-100)
|
||||||
|
* @return array 掉落的物品列表
|
||||||
|
*/
|
||||||
|
public function getRandomEquipmentDrops(int $dropRate = 50): array
|
||||||
|
{
|
||||||
|
$drops = [];
|
||||||
|
foreach ($this->equip as $item) {
|
||||||
|
if (!empty($item)) {
|
||||||
|
// 每件装备有独立的掉落概率
|
||||||
|
if (rand(1, 100) <= $dropRate) {
|
||||||
|
$drops[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $drops;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
111
src/Entities/NPC.php
Normal file
111
src/Entities/NPC.php
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
<?php
|
||||||
|
namespace Game\Entities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NPC Class - Represents non-player characters
|
||||||
|
* NPCs can be treated like other players/actors in terms of stat calculation
|
||||||
|
* They support equipment, talents, and can participate in battles like partners
|
||||||
|
*/
|
||||||
|
class NPC extends Actor
|
||||||
|
{
|
||||||
|
// NPC特有属性
|
||||||
|
public string $id = '';
|
||||||
|
public string $title = '';
|
||||||
|
public string $desc = '';
|
||||||
|
public int $minLevel = 1;
|
||||||
|
|
||||||
|
// NPC特有的基础属性(不含装备加成)
|
||||||
|
public int $baseHp = 20;
|
||||||
|
public int $basePatk = 4;
|
||||||
|
public int $baseMatk = 2;
|
||||||
|
public int $basePdef = 0;
|
||||||
|
public int $baseMdef = 0;
|
||||||
|
|
||||||
|
// NPC特有的奖励属性
|
||||||
|
public int $expReward = 10;
|
||||||
|
public int $spiritStoneReward = 0;
|
||||||
|
|
||||||
|
// NPC特有的掉落表
|
||||||
|
public array $dropTable = [];
|
||||||
|
|
||||||
|
// NPC特有的成长系数
|
||||||
|
public float $growth = 1.1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从配置创建NPC实例
|
||||||
|
*/
|
||||||
|
public static function createFromConfig(array $config): self
|
||||||
|
{
|
||||||
|
$npc = new self();
|
||||||
|
|
||||||
|
$npc->id = $config['id'] ?? '';
|
||||||
|
$npc->name = $config['name'] ?? 'Unknown NPC';
|
||||||
|
$npc->title = $config['title'] ?? '';
|
||||||
|
$npc->desc = $config['desc'] ?? '';
|
||||||
|
$npc->minLevel = $config['min_level'] ?? 1;
|
||||||
|
|
||||||
|
// Base stats
|
||||||
|
if (isset($config['base_stats'])) {
|
||||||
|
$npc->baseHp = $config['base_stats']['hp'] ?? 20;
|
||||||
|
$npc->basePatk = $config['base_stats']['patk'] ?? 4;
|
||||||
|
$npc->baseMatk = $config['base_stats']['matk'] ?? 2;
|
||||||
|
$npc->basePdef = $config['base_stats']['pdef'] ?? 0;
|
||||||
|
$npc->baseMdef = $config['base_stats']['mdef'] ?? 0;
|
||||||
|
$npc->crit = $config['base_stats']['crit'] ?? 5;
|
||||||
|
$npc->critdmg = $config['base_stats']['critdmg'] ?? 130;
|
||||||
|
$npc->growth = $config['base_stats']['growth'] ?? 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Talent weights
|
||||||
|
if (isset($config['talent_weights'])) {
|
||||||
|
$npc->talentWeights = $config['talent_weights'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default level 1
|
||||||
|
$npc->level = 1;
|
||||||
|
$npc->hp = $npc->baseHp;
|
||||||
|
$npc->patk = $npc->basePatk;
|
||||||
|
$npc->matk = $npc->baseMatk;
|
||||||
|
$npc->pdef = $npc->basePdef;
|
||||||
|
$npc->mdef = $npc->baseMdef;
|
||||||
|
|
||||||
|
// Initialize mana
|
||||||
|
$npc->maxMana = 100;
|
||||||
|
$npc->mana = 100;
|
||||||
|
|
||||||
|
return $npc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化法力值(基于等级)
|
||||||
|
*/
|
||||||
|
public function initializeMana(): void
|
||||||
|
{
|
||||||
|
$this->maxMana = 100 + ($this->level * 10);
|
||||||
|
$this->mana = $this->maxMana;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加已装备物品
|
||||||
|
*/
|
||||||
|
public function equipItem(string $type, array $item): void
|
||||||
|
{
|
||||||
|
if (in_array($type, ['weapon', 'armor', 'boots', 'ring', 'necklace'])) {
|
||||||
|
$this->equip[$type] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有已装备物品(用于掉落,如同怪物)
|
||||||
|
*/
|
||||||
|
public function getEquippedItems(): array
|
||||||
|
{
|
||||||
|
$items = [];
|
||||||
|
foreach ($this->equip as $item) {
|
||||||
|
if (!empty($item)) {
|
||||||
|
$items[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,30 +6,7 @@ use Game\Entities\Partner;
|
||||||
class Player extends Actor
|
class Player extends Actor
|
||||||
{
|
{
|
||||||
|
|
||||||
// 天赋系统
|
// Player特有的天赋名称
|
||||||
public int $talentPoints = 0; // 可用天赋点
|
|
||||||
public array $talents = [ // 已分配的天赋点
|
|
||||||
'hp' => 0, // 每点 +20 生命
|
|
||||||
'patk' => 0, // 每点 +5 物攻
|
|
||||||
'matk' => 0, // 每点 +4 魔攻
|
|
||||||
'pdef' => 0, // 每点 +3 物防
|
|
||||||
'mdef' => 0, // 每点 +3 魔防
|
|
||||||
'crit' => 0, // 每点 +2% 暴击
|
|
||||||
'critdmg' => 0, // 每点 +10% 暴伤
|
|
||||||
];
|
|
||||||
|
|
||||||
// 天赋每点提供的属性
|
|
||||||
public static array $talentBonus = [
|
|
||||||
'hp' => 10,
|
|
||||||
'patk' => 5,
|
|
||||||
'matk' => 4,
|
|
||||||
'pdef' => 3,
|
|
||||||
'mdef' => 3,
|
|
||||||
'crit' => 1,
|
|
||||||
'critdmg' => 5,
|
|
||||||
];
|
|
||||||
|
|
||||||
// 天赋名称
|
|
||||||
public static array $talentNames = [
|
public static array $talentNames = [
|
||||||
'hp' => '生命',
|
'hp' => '生命',
|
||||||
'patk' => '物攻',
|
'patk' => '物攻',
|
||||||
|
|
@ -40,6 +17,13 @@ class Player extends Actor
|
||||||
'critdmg' => '暴伤',
|
'critdmg' => '暴伤',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Player特有的NPC交互标记
|
||||||
|
public array $npcFlags = [];
|
||||||
|
|
||||||
|
// Player特有的同伴系统
|
||||||
|
public int $maxPartners = 2; // 最多可携带同伴数
|
||||||
|
public array $partners = []; // 已招募的同伴
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加灵石
|
* 增加灵石
|
||||||
*/
|
*/
|
||||||
|
|
@ -188,6 +172,9 @@ class Player extends Actor
|
||||||
return $this->spellBooks[$spellId] ?? 0;
|
return $this->spellBooks[$spellId] ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Player特有的经验获取,升级时会恢复生命值
|
||||||
|
*/
|
||||||
public function gainExp(int $amount): bool
|
public function gainExp(int $amount): bool
|
||||||
{
|
{
|
||||||
$this->exp += $amount;
|
$this->exp += $amount;
|
||||||
|
|
@ -196,8 +183,8 @@ class Player extends Actor
|
||||||
$this->exp -= $this->maxExp;
|
$this->exp -= $this->maxExp;
|
||||||
$this->maxExp = (int)($this->maxExp * 1.5);
|
$this->maxExp = (int)($this->maxExp * 1.5);
|
||||||
|
|
||||||
// 升级获得天赋点(每级3点)
|
// 升级获得天赋点(每级3点)并通过 autoAllocateTalents 自动分配
|
||||||
$this->talentPoints += 3;
|
$this->autoAllocateTalents(3);
|
||||||
|
|
||||||
// 升级时恢复全部生命值
|
// 升级时恢复全部生命值
|
||||||
$this->fullHeal();
|
$this->fullHeal();
|
||||||
|
|
@ -208,7 +195,7 @@ class Player extends Actor
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分配天赋点
|
* Player特有的分配天赋点(返回布尔值)
|
||||||
*/
|
*/
|
||||||
public function allocateTalent(string $talent, int $points = 1): bool
|
public function allocateTalent(string $talent, int $points = 1): bool
|
||||||
{
|
{
|
||||||
|
|
@ -226,7 +213,7 @@ class Player extends Actor
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置天赋(返还所有点数)
|
* Player特有的重置天赋(返还所有点数)
|
||||||
*/
|
*/
|
||||||
public function resetTalents(): int
|
public function resetTalents(): int
|
||||||
{
|
{
|
||||||
|
|
@ -240,23 +227,6 @@ class Player extends Actor
|
||||||
return $total;
|
return $total;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取天赋提供的属性加成
|
|
||||||
*/
|
|
||||||
public function getTalentStats(): array
|
|
||||||
{
|
|
||||||
$stats = [
|
|
||||||
'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'],
|
|
||||||
];
|
|
||||||
return $stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addItem(array $item)
|
public function addItem(array $item)
|
||||||
{
|
{
|
||||||
// Handle stacking for consumables
|
// Handle stacking for consumables
|
||||||
|
|
@ -283,20 +253,6 @@ class Player extends Actor
|
||||||
$this->inventory[] = $item;
|
$this->inventory[] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var array<int, array> */
|
|
||||||
public array $inventory = [];
|
|
||||||
|
|
||||||
public array $equip = [];
|
|
||||||
|
|
||||||
/** @var array<string, bool> */
|
|
||||||
public array $npcFlags = [];
|
|
||||||
|
|
||||||
/** @var array<string, Partner> 同伴列表 */
|
|
||||||
public array $partners = [];
|
|
||||||
|
|
||||||
/** @var int 最大同伴数量 */
|
|
||||||
public int $maxPartners = 2;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 招募同伴
|
* 招募同伴
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -868,8 +868,8 @@ class Battle
|
||||||
$totalExp += $enemy->expReward;
|
$totalExp += $enemy->expReward;
|
||||||
$totalStones += $enemy->spiritStoneReward;
|
$totalStones += $enemy->spiritStoneReward;
|
||||||
|
|
||||||
// 掉落
|
// 掉落 - 从怪物穿着的装备随机掉落
|
||||||
foreach ($enemy->getEquippedItems() as $item) {
|
foreach ($enemy->getRandomEquipmentDrops(50) as $item) {
|
||||||
$this->player->addItem($item);
|
$this->player->addItem($item);
|
||||||
$allDrops[] = $item;
|
$allDrops[] = $item;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use Game\Core\Screen;
|
||||||
use Game\Core\Input;
|
use Game\Core\Input;
|
||||||
use Game\Entities\Item;
|
use Game\Entities\Item;
|
||||||
use Game\Entities\Partner;
|
use Game\Entities\Partner;
|
||||||
|
use Game\Entities\NPC;
|
||||||
|
|
||||||
class NpcPanel
|
class NpcPanel
|
||||||
{
|
{
|
||||||
|
|
@ -58,6 +59,27 @@ class NpcPanel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从配置创建NPC实例
|
||||||
|
*/
|
||||||
|
public function createNPCInstance(array $npcConfig): NPC
|
||||||
|
{
|
||||||
|
return NPC::createFromConfig($npcConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取NPC实例(从配置ID)
|
||||||
|
*/
|
||||||
|
public function getNPCById(string $id): ?NPC
|
||||||
|
{
|
||||||
|
foreach ($this->npcs as $npcConfig) {
|
||||||
|
if ($npcConfig['id'] === $id) {
|
||||||
|
return $this->createNPCInstance($npcConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private function interact(array $npc)
|
private function interact(array $npc)
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user