addError('宠物不存在'); return false; } // 获取技能信息 $skill = PetSkill::find($skillId); if (!$skill) { $this->addError('技能(' . $skillId . ')不存在'); return false; } // 检查宠物状态 if ($pet->status !== PetStatus::NORMAL) { $this->addError('宠物当前状态(' . $pet->status->name . ')不允许使用技能'); return false; } // 检查宠物当前等级是否可以使用该技能(基于等级配置表) if (!$this->checkPetSkillAvailable($pet, $skillId)) { $this->addError('该技能在当前等级(' . $pet->level . ')不可用'); return false; } // 检查宠物体力是否足够 if ($pet->stamina < $skill->stamina_cost) { $this->addError('宠物体力(' . $pet->stamina . ')不足,需要体力(' . $skill->stamina_cost . ')才能使用该技能'); return false; } // 检查技能冷却时间 $lastUsed = $pet->skillLogs() ->where('skill_id', $skillId) ->orderBy('used_at', 'desc') ->first(); if ($lastUsed) { $cooldownSeconds = $skill->cool_down; $now = now(); $lastUsedTime = $lastUsed->used_at; // 确保时间计算的正确性 if ($lastUsedTime instanceof \Carbon\Carbon) { $secondsSinceLastUse = $now->diffInSeconds($lastUsedTime, false); } else { // 如果不是Carbon对象,尝试解析 $lastUsedTime = \Carbon\Carbon::parse($lastUsedTime); $secondsSinceLastUse = $now->diffInSeconds($lastUsedTime, false); } // 如果secondsSinceLastUse为负数,说明lastUsed时间在未来,这是异常情况 if ($secondsSinceLastUse < 0) { // 异常情况下,重置为0,允许技能使用 $secondsSinceLastUse = 0; } if ($secondsSinceLastUse < $cooldownSeconds) { $remainingCooldown = $cooldownSeconds - $secondsSinceLastUse; $this->addError('技能冷却中,还需等待' . $remainingCooldown . '秒'); return false; } } return true; } catch (\Exception $e) { $this->addError('验证过程发生错误: ' . $e->getMessage()); return false; } } /** * 检查宠物当前等级是否可以使用指定技能 * * 基于宠物等级配置表中的 skills 字段进行检查 * * @param PetUser $pet 宠物对象 * @param int $skillId 技能ID * @return bool 是否可以使用该技能 */ private 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; } } }