| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- <?php
- namespace App\Module\Farm\Logics;
- use App\Module\Farm\Enums\DISASTER_TYPE;
- use App\Module\GameItems\Services\ItemService;
- use Illuminate\Support\Facades\Log;
- use UCore\Db\Helper;
- use UCore\Exception\LogicException;
- /**
- * 灾害去除逻辑类
- *
- * 处理各种类型的灾害去除操作,包括概率计算、状态验证和物品消耗
- */
- class DisasterRemovalLogic
- {
- /**
- * 灾害类型与物品属性的映射关系
- */
- private const DISASTER_ITEM_ATTRIBUTES = [
- DISASTER_TYPE::DROUGHT->value => 'fram_drought_rate', // 干旱 -> 浇水概率
- DISASTER_TYPE::PEST->value => 'fram_pesticide_rate', // 虫害 -> 除虫概率
- DISASTER_TYPE::WEED->value => 'fram_weedicide_rate', // 杂草 -> 除草概率
- ];
- /**
- * 灾害类型与操作名称的映射关系
- */
- private const DISASTER_ACTION_NAMES = [
- DISASTER_TYPE::DROUGHT->value => '浇水',
- DISASTER_TYPE::PEST->value => '除虫',
- DISASTER_TYPE::WEED->value => '除草',
- ];
- /**
- * 尝试去除指定类型的灾害
- *
- * 注意:此方法假设所有验证已经通过,专注于业务逻辑处理
- *
- * @param int $userId 用户ID
- * @param int $landId 土地ID
- * @param int $itemId 物品ID
- * @param int $disasterType 灾害类型
- * @param string $sourceType 消耗来源类型
- * @return array 操作结果
- * @throws LogicException
- */
- public function removeDisaster(int $userId, int $landId, int $itemId, int $disasterType, string $sourceType): array
- {
- // 检查事务状态
- Helper::check_tr();
- // 获取物品成功率
- $successRate = $this->getItemSuccessRate($itemId, $disasterType);
- // 进行概率判断
- if (!$this->rollSuccess($successRate)) {
- // 失败时仍然消耗物品
- $this->consumeItem($userId, $itemId, $landId, $sourceType);
- $actionName = self::DISASTER_ACTION_NAMES[$disasterType];
- throw new LogicException("{$actionName}失败,请再次尝试");
- }
- // 执行灾害清理
- $result = $this->clearDisasterFromCrop($userId, $landId, $disasterType);
- if (!$result) {
- throw new LogicException("灾害清理失败,请检查土地状态或作物生长阶段");
- }
- // 消耗物品
- $this->consumeItem($userId, $itemId, $landId, $sourceType);
- $actionName = self::DISASTER_ACTION_NAMES[$disasterType];
- Log::info("用户{$actionName}成功", [
- 'user_id' => $userId,
- 'land_id' => $landId,
- 'item_id' => $itemId,
- 'disaster_type' => $disasterType,
- 'success_rate' => $successRate
- ]);
- return [
- 'success' => true,
- 'message' => "{$actionName}成功",
- 'disaster_type' => $disasterType,
- 'success_rate' => $successRate
- ];
- }
- /**
- * 获取物品的成功率
- *
- * @param int $itemId 物品ID
- * @param int $disasterType 灾害类型
- * @return int 成功率(百分比)
- */
- private function getItemSuccessRate(int $itemId, int $disasterType): int
- {
- $attributeName = self::DISASTER_ITEM_ATTRIBUTES[$disasterType];
- return ItemService::getItemNumericAttribute($itemId, $attributeName, 0);
- }
- /**
- * 进行概率判断
- *
- * @param int $successRate 成功率(百分比,100=100%)
- * @return bool 是否成功
- */
- private function rollSuccess(int $successRate): bool
- {
- if ($successRate <= 0) {
- return false;
- }
- if ($successRate >= 100) {
- return true;
- }
- $randomNumber = mt_rand(1, 100);
- return $randomNumber <= $successRate;
- }
- /**
- * 从作物中清理指定类型的灾害
- *
- * @param int $userId 用户ID
- * @param int $landId 土地ID
- * @param int $disasterType 灾害类型
- * @return bool 是否成功
- */
- private function clearDisasterFromCrop(int $userId, int $landId, int $disasterType): bool
- {
- try {
- $cropLogic = new CropLogic();
- return $cropLogic->clearDisaster($userId, $landId, $disasterType);
- } catch (\Exception $e) {
- Log::error('清理灾害失败', [
- 'user_id' => $userId,
- 'land_id' => $landId,
- 'disaster_type' => $disasterType,
- 'error' => $e->getMessage(),
- 'trace' => $e->getTraceAsString()
- ]);
- return false;
- }
- }
- /**
- * 消耗物品
- *
- * @param int $userId 用户ID
- * @param int $itemId 物品ID
- * @param int $landId 土地ID
- * @param string $sourceType 消耗来源类型
- * @throws LogicException
- */
- private function consumeItem(int $userId, int $itemId, int $landId, string $sourceType): void
- {
- ItemService::consumeItem($userId, $itemId, null, 1, [
- 'source_type' => $sourceType,
- 'source_id' => $landId,
- 'details' => ['land_id' => $landId]
- ]);
- }
- }
|