PetDtoFactory.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. namespace App\Module\Pet\Factories;
  3. use App\Module\Pet\Dtos\PetDataDto;
  4. use App\Module\Pet\Dtos\PetLifeSkillDto;
  5. use App\Module\Pet\Models\PetUser;
  6. use App\Module\Pet\Models\PetSkill;
  7. use App\Module\Pet\Models\PetLevelConfig;
  8. use App\Module\Pet\Logic\PetLogic;
  9. /**
  10. * 宠物DTO工厂类
  11. *
  12. * 负责创建宠物相关的DTO对象
  13. */
  14. class PetDtoFactory
  15. {
  16. /**
  17. * 创建宠物数据DTO
  18. *
  19. * @param PetUser $pet 宠物模型
  20. * @param int|null $fightingCapacity 战力值,如果为null则会计算
  21. * @return PetDataDto 宠物数据DTO
  22. */
  23. public static function createPetDataDto(PetUser $pet, ?int $fightingCapacity = null): PetDataDto
  24. {
  25. // 创建宠物DTO
  26. $petDto = new PetDataDto();
  27. $petDto->id = $pet->id;
  28. $petDto->type_id = $pet->type_id ?? 0; // 如果模型中没有type_id字段,默认为0
  29. $petDto->name = $pet->name;
  30. $petDto->level = $pet->level;
  31. $petDto->exp = $pet->experience;
  32. $petDto->power = $pet->stamina;
  33. // 获取宠物等级配置
  34. $levelConfig = PetLevelConfig::where('level', $pet->level)->first();
  35. $petDto->maxpower = $levelConfig ? $levelConfig->stamina_max : 100;
  36. // 计算战力
  37. if ($fightingCapacity === null) {
  38. $petLogic = new PetLogic();
  39. $fightingCapacity = $petLogic->calculatePower($pet->id);
  40. }
  41. $petDto->fighting_capacity = $fightingCapacity;
  42. $petDto->score = $fightingCapacity; // 暂时使用战力作为评分
  43. // 设置品阶和状态
  44. $petDto->grade = $pet->grade->value;
  45. $petDto->status = $pet->status->value;
  46. // 获取宠物生活技能
  47. $petDto->life_skills = self::createPetLifeSkillDtos($pet);
  48. return $petDto;
  49. }
  50. /**
  51. * 创建宠物生活技能DTO数组
  52. *
  53. * @param PetUser $pet 宠物模型
  54. * @return array 生活技能DTO数组
  55. */
  56. public static function createPetLifeSkillDtos(PetUser $pet): array
  57. {
  58. // 获取所有技能
  59. $allSkills = PetSkill::all();
  60. // 筛选出宠物等级可用的技能
  61. $availableSkills = $allSkills->filter(function ($skill) use ($pet) {
  62. return $pet->level >= $skill->min_level;
  63. });
  64. // 获取技能使用记录,计算冷却时间
  65. $skillLogs = $pet->skillLogs()
  66. ->orderBy('used_at', 'desc')
  67. ->get()
  68. ->groupBy('skill_id');
  69. $skillDtos = [];
  70. foreach ($availableSkills as $skill) {
  71. $lastUsed = null;
  72. $cooldownRemaining = 0;
  73. $canUse = true;
  74. if (isset($skillLogs[$skill->id]) && $skillLogs[$skill->id]->count() > 0) {
  75. $lastUsed = $skillLogs[$skill->id][0]->used_at;
  76. $cooldownSeconds = $skill->cool_down;
  77. $secondsSinceLastUse = now()->diffInSeconds($lastUsed);
  78. $cooldownRemaining = max(0, $cooldownSeconds - $secondsSinceLastUse);
  79. $canUse = $cooldownRemaining === 0;
  80. }
  81. // 检查体力是否足够
  82. if ($pet->stamina < $skill->stamina_cost) {
  83. $canUse = false;
  84. }
  85. $skillDto = new PetLifeSkillDto();
  86. $skillDto->skill_id = $skill->id;
  87. $skillDto->canuse = $canUse;
  88. $skillDto->curnum = $cooldownRemaining;
  89. $skillDto->maxnum = $skill->cool_down;
  90. $skillDtos[] = $skillDto;
  91. }
  92. return $skillDtos;
  93. }
  94. }