| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- <?php
- namespace App\Module\Pet\Factories;
- use App\Module\Pet\Dtos\PetDataDto;
- use App\Module\Pet\Dtos\PetLifeSkillDto;
- use App\Module\Pet\Models\PetUser;
- use App\Module\Pet\Models\PetSkill;
- use App\Module\Pet\Models\PetLevelConfig;
- use App\Module\Pet\Logic\PetLogic;
- use Illuminate\Support\Facades\Log;
- /**
- * 宠物DTO工厂类
- *
- * 负责创建宠物相关的DTO对象
- */
- class PetDtoFactory
- {
- /**
- * 创建宠物数据DTO
- *
- * @param PetUser $pet 宠物模型
- * @param int|null $fightingCapacity 战力值,如果为null则会计算
- * @return PetDataDto 宠物数据DTO
- */
- public static function createPetDataDto(PetUser $pet, ?int $fightingCapacity = null): PetDataDto
- {
- // 创建宠物DTO
- $petDto = new PetDataDto();
- $petDto->id = $pet->id;
- $petDto->typeId = $pet->type_id ?? 0; // 如果模型中没有type_id字段,默认为0
- $petDto->name = $pet->name;
- $petDto->level = $pet->level;
- $petDto->exp = $pet->experience;
- $petDto->power = $pet->stamina;
- // 获取宠物等级配置
- /**
- * @var PetLevelConfig $levelConfig
- */
- $levelConfig = PetLevelConfig::where('level', $pet->level)->first();
- $petDto->maxpower = $levelConfig ? ($levelConfig->numeric_attributes->stamina_max ?? 100) : 100;
- // 计算战力
- if ($fightingCapacity === null) {
- $petLogic = new PetLogic();
- $fightingCapacity = $petLogic->calculatePower($pet->id);
- }
- $petDto->fightingCapacity = $fightingCapacity;
- $petDto->score = $fightingCapacity; // 暂时使用战力作为评分
- // 设置品阶和状态
- // grade字段在数据库中是integer,直接使用
- $petDto->grade = $pet->grade;
- // status字段被转换为PetStatus枚举,需要获取value
- $petDto->status = $pet->status->value;
- // 获取宠物生活技能
- $petDto->lifeSkills = self::createPetLifeSkillDtos($pet);
- return $petDto;
- }
- /**
- * 创建宠物生活技能DTO数组
- *
- * @param PetUser $pet 宠物模型
- * @return array 生活技能DTO数组
- */
- public static function createPetLifeSkillDtos(PetUser $pet): array
- {
- // 获取所有技能
- $allSkills = PetSkill::all();
- // 筛选出宠物等级可用的技能(基于等级配置表)
- $availableSkills = $allSkills->filter(function ($skill) use ($pet) {
- return self::checkPetSkillAvailable($pet, $skill->id);
- });
- // 获取宠物当前激活的技能
- $activeSkills = \App\Module\Pet\Models\PetActiveSkill::where('pet_id', $pet->id)
- ->where('status', 'active')
- ->where('end_time', '>', now())
- ->get()
- ->keyBy('skill_id');
- // 获取技能使用记录,计算冷却时间
- $skillLogs = $pet->skillLogs()
- ->orderBy('used_at', 'desc')
- ->get()
- ->groupBy('skill_id');
- $skillDtos = [];
- foreach ($availableSkills as $skill) {
- $skillDto = new PetLifeSkillDto();
- $curnum = 0; // 当前剩余时间(激活技能的剩余时间)
- $maxnum = 0; // 最大时间(激活技能的持续时间)
- // 检查是否有激活的技能
- if (isset($activeSkills[$skill->id])) {
- /**
- * @var \App\Module\Pet\Models\PetActiveSkill $activeSkill
- */
- $activeSkill = $activeSkills[$skill->id];
- $now = now();
- // 计算激活技能的剩余时间
- $remainingSeconds = $now->diffInSeconds($activeSkill->end_time, false);
- if ($remainingSeconds > 0) {
- $curnum = $remainingSeconds; // 剩余激活时间
- $maxnum = $skill->duration_time; // 技能持续时间
- }
- $skillDto->end_times = $activeSkill->end_time->getTimestamp();
- }
- $skillDto->skillId = $skill->id;
- // $skillDto->canuse = $canUse; // 不再处理
- $skillDto->curnum = $curnum; // 激活技能的剩余时间
- $skillDto->maxnum = $maxnum; // 激活技能的持续时间
- // $
- $skillDtos[] = $skillDto;
- }
- return $skillDtos;
- }
- /**
- * 检查宠物当前等级是否可以使用指定技能
- *
- * 基于宠物等级配置表中的 skills 字段进行检查
- *
- * @param PetUser $pet 宠物对象
- * @param int $skillId 技能ID
- * @return bool 是否可以使用该技能
- */
- private static function checkPetSkillAvailable(PetUser $pet, int $skillId): bool
- {
- try {
- // 获取宠物当前等级的配置
- // 注意:这里假设所有宠物都使用 pet_id=1 的配置,如果有多种宠物类型,需要修改
- $levelConfig = PetLevelConfig::where('pet_id', 1)
- ->where('level', $pet->level)
- ->first();
- if (!$levelConfig) {
- Log::warning('宠物等级配置不存在', [
- 'pet_id' => $pet->id,
- 'pet_level' => $pet->level,
- 'skill_id' => $skillId
- ]);
- // 如果没有配置,默认允许使用(向后兼容)
- return true;
- }
- // 检查技能是否在可用技能列表中
- $availableSkills = $levelConfig->skills ?? [];
- $isAvailable = in_array($skillId, $availableSkills);
- Log::info('宠物技能可用性检查', [
- 'pet_id' => $pet->id,
- 'pet_level' => $pet->level,
- 'skill_id' => $skillId,
- 'available_skills' => $availableSkills,
- 'is_available' => $isAvailable
- ]);
- return $isAvailable;
- } catch (\Exception $e) {
- Log::error('检查宠物技能可用性时发生错误', [
- 'pet_id' => $pet->id,
- 'pet_level' => $pet->level,
- 'skill_id' => $skillId,
- 'error' => $e->getMessage()
- ]);
- // 发生错误时默认允许使用(向后兼容)
- return true;
- }
- }
- }
|