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; } }