hanli/src/Entities/Partner.php
hant 52e465177c Fix event loop initialization and handle pipe errors
- Modified startup script to instantiate GameProcessServer separately
  before wrapping in WsServer/HttpServer, allowing direct access to
  set event loop after IoServer creation
- Implemented setLoop() method to set event loop after construction
- Added error handling for fwrite() to gracefully handle broken pipes
  when process closes
- Suppressed fread() warnings with @ operator to avoid noise
- Simplified startOutputReader() since event loop polling is now
  handled directly in onOpen()
- Added null checks for event loop before using in timers
- Server now properly starts with continuous 100ms output polling

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 14:17:28 +08:00

131 lines
3.6 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;
class Partner extends Actor
{
public $id;
// Partner特有的天赋加成与 Actor 不同)
public static array $talentBonus = [
'hp' => 20,
'patk' => 5,
'matk' => 4,
'pdef' => 3,
'mdef' => 3,
'crit' => 2,
'critdmg' => 10,
];
public function __construct(array $data)
{
$this->id = $data['id'];
$this->name = $data['name'];
$this->level = $data['level'] ?? 1;
$this->exp = $data['exp'] ?? 0;
$this->maxExp = $data['maxExp'] ?? (int)(100 * pow(1.5, $this->level - 1));
$this->patk = $data['patk'] ;
$this->matk = $data['matk'] ;
$this->pdef = $data['pdef'] ;
$this->mdef = $data['mdef'] ;
$this->crit = $data['crit'] ;
$this->critdmg = $data['critdmg'] ?? 130;
$this->maxHp = $data['maxHp'];
$this->hp = $data['hp'] ?? $data['maxHp'];
// 装备和天赋系统
$this->equip = $data['equip'] ?? [];
$this->talents = $data['talents'] ?? $this->talents;
$this->talentWeights = $data['talentWeights'] ?? $this->talentWeights;
// 加载技能槽位数据 (新法术系统)
$this->mana = $data['mana'] ?? $this->mana;
$this->maxMana = $data['maxMana'] ?? 100;
$this->skillSlots = $data['skillSlots'] ?? $this->skillSlots;
}
/**
* 根据权重自动分配天赋点
* 重要: HP生命值总是必须至少加1点
*/
private function autoAllocateTalent(int $points): void
{
$totalWeight = array_sum($this->talentWeights);
if ($totalWeight <= 0) {
$totalWeight = 7; // 默认平均分配
}
// 按权重分配点数
$remaining = $points;
$allocated = [];
foreach ($this->talentWeights as $talent => $weight) {
$share = (int)floor($points * $weight / $totalWeight);
$allocated[$talent] = $share;
$remaining -= $share;
}
// 关键: 确保 HP 至少获得1点HP是必须的
if ($allocated['hp'] < 1) {
$allocated['hp'] = 1;
$remaining--;
}
// 剩余点数按权重优先分配
$sortedTalents = $this->talentWeights;
arsort($sortedTalents);
foreach ($sortedTalents as $talent => $weight) {
if ($remaining <= 0) break;
$allocated[$talent]++;
$remaining--;
}
// 应用分配
foreach ($allocated as $talent => $addPoints) {
$this->talents[$talent] += $addPoints;
}
}
/**
* Partner特有的升级逻辑自动分配天赋点
*/
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点天赋根据权重且 HP 至少加1点
$this->autoAllocateTalent(3);
return true;
}
return false;
}
/**
* 获取总天赋点数
*/
public function getTotalTalentPoints(): int
{
return array_sum($this->talents);
}
/**
* 检查是否已学习法术
*/
public function hasSpell(int $spellId): bool
{
return isset($this->spells[$spellId]);
}
/**
* 获取法术等级
*/
public function getSpellLevel(int $spellId): int
{
return $this->spells[$spellId]['level'] ?? 0;
}
}