|
|
@@ -230,31 +230,38 @@ class CropLogic
|
|
|
throw new \Exception('种子信息不存在');
|
|
|
}
|
|
|
|
|
|
- // 使用发芽期确定的最终产出果实ID,如果没有则随机选择
|
|
|
- if ($crop->final_output_item_id) {
|
|
|
- $outputItemId = $crop->final_output_item_id;
|
|
|
- // 获取对应的产出配置来确定数量范围
|
|
|
- $outputInfo = $this->getOutputInfoByItemId($seed->id, $outputItemId);
|
|
|
- $outputAmount = mt_rand($outputInfo['min_amount'], $outputInfo['max_amount']);
|
|
|
-
|
|
|
- Log::info('使用发芽期确定的最终产出果实', [
|
|
|
+ // 严格验证:收获时必须有完整的产出数据
|
|
|
+ if (!$crop->final_output_item_id) {
|
|
|
+ Log::error('收获失败:作物没有确定的产出物品ID', [
|
|
|
'crop_id' => $crop->id,
|
|
|
- 'final_output_item_id' => $outputItemId,
|
|
|
- 'output_amount' => $outputAmount
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'seed_id' => $seed->id,
|
|
|
+ 'growth_stage' => $crop->growth_stage->value
|
|
|
]);
|
|
|
- } else {
|
|
|
- // 兼容旧数据:如果没有预设的最终产出果实ID,则随机选择
|
|
|
- $outputInfo = $this->getRandomOutput($seed->id);
|
|
|
- $outputItemId = $outputInfo['item_id'];
|
|
|
- $outputAmount = mt_rand($outputInfo['min_amount'], $outputInfo['max_amount']);
|
|
|
+ throw new \Exception("作物ID {$crop->id} 没有确定的产出物品ID,无法收获");
|
|
|
+ }
|
|
|
|
|
|
- Log::warning('作物没有预设最终产出果实ID,使用随机选择', [
|
|
|
+ if (!$crop->final_output_amount) {
|
|
|
+ Log::error('收获失败:作物没有确定的产量', [
|
|
|
'crop_id' => $crop->id,
|
|
|
+ 'user_id' => $userId,
|
|
|
'seed_id' => $seed->id,
|
|
|
- 'random_output_item_id' => $outputItemId
|
|
|
+ 'growth_stage' => $crop->growth_stage->value,
|
|
|
+ 'final_output_item_id' => $crop->final_output_item_id
|
|
|
]);
|
|
|
+ throw new \Exception("作物ID {$crop->id} 没有确定的产量,无法收获");
|
|
|
}
|
|
|
|
|
|
+ // 使用成熟期确定的产量和产出物品
|
|
|
+ $outputItemId = $crop->final_output_item_id;
|
|
|
+ $outputAmount = $crop->final_output_amount;
|
|
|
+
|
|
|
+ Log::info('使用成熟期确定的最终产量', [
|
|
|
+ 'crop_id' => $crop->id,
|
|
|
+ 'final_output_item_id' => $outputItemId,
|
|
|
+ 'final_output_amount' => $outputAmount
|
|
|
+ ]);
|
|
|
+
|
|
|
// 创建收获记录
|
|
|
$harvestLog = new FarmHarvestLog();
|
|
|
$harvestLog->user_id = $userId;
|
|
|
@@ -794,6 +801,20 @@ class CropLogic
|
|
|
throw new \Exception("作物ID {$crop->id} 进入成熟期但没有确定最终产出果实ID,这是系统错误");
|
|
|
}
|
|
|
|
|
|
+ // 如果进入成熟期,计算并确定最终产量
|
|
|
+ if ($newStage === GROWTH_STAGE::MATURE->value && !$crop->final_output_amount) {
|
|
|
+ $finalAmount = $this->calculateMatureOutput($crop);
|
|
|
+ $crop->final_output_amount = $finalAmount;
|
|
|
+
|
|
|
+ Log::info('作物进入成熟期,确定最终产量', [
|
|
|
+ 'crop_id' => $crop->id,
|
|
|
+ 'user_id' => $crop->user_id,
|
|
|
+ 'seed_id' => $crop->seed_id,
|
|
|
+ 'final_output_amount' => $finalAmount,
|
|
|
+ 'final_output_item_id' => $crop->final_output_item_id
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
$crop->save();
|
|
|
|
|
|
// 如果进入枯萎期,需要更新土地状态
|
|
|
@@ -984,27 +1005,174 @@ class CropLogic
|
|
|
*/
|
|
|
private function getOutputInfoByItemId(int $seedId, int $itemId): array
|
|
|
{
|
|
|
- // 获取种子的所有产出配置
|
|
|
- $outputs = FarmSeedOutput::where('seed_id', $seedId)->get();
|
|
|
+ try {
|
|
|
+ // 获取种子的所有产出配置
|
|
|
+ $outputs = FarmSeedOutput::where('seed_id', $seedId)->get();
|
|
|
|
|
|
- // 查找匹配的产出配置
|
|
|
- $targetOutput = $outputs->firstWhere('item_id', $itemId);
|
|
|
+ // 查找匹配的产出配置
|
|
|
+ $targetOutput = $outputs->firstWhere('item_id', $itemId);
|
|
|
+
|
|
|
+ if ($targetOutput) {
|
|
|
+ return [
|
|
|
+ 'item_id' => $targetOutput->item_id,
|
|
|
+ 'min_amount' => $targetOutput->min_amount,
|
|
|
+ 'max_amount' => $targetOutput->max_amount,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果没有找到匹配的产出配置,使用种子的默认产出
|
|
|
+ $seed = FarmSeed::find($seedId);
|
|
|
+
|
|
|
+ if ($seed) {
|
|
|
+ return [
|
|
|
+ 'item_id' => $itemId, // 使用传入的物品ID
|
|
|
+ 'min_amount' => $seed->min_output,
|
|
|
+ 'max_amount' => $seed->max_output,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果种子也不存在,返回默认值
|
|
|
+ Log::warning('种子不存在,使用默认产出配置', [
|
|
|
+ 'seed_id' => $seedId,
|
|
|
+ 'item_id' => $itemId
|
|
|
+ ]);
|
|
|
|
|
|
- if ($targetOutput) {
|
|
|
return [
|
|
|
- 'item_id' => $targetOutput->item_id,
|
|
|
- 'min_amount' => $targetOutput->min_amount,
|
|
|
- 'max_amount' => $targetOutput->max_amount,
|
|
|
+ 'item_id' => $itemId,
|
|
|
+ 'min_amount' => 1,
|
|
|
+ 'max_amount' => 10,
|
|
|
+ ];
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error('获取产出配置信息失败', [
|
|
|
+ 'seed_id' => $seedId,
|
|
|
+ 'item_id' => $itemId,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 发生错误时返回安全的默认值
|
|
|
+ return [
|
|
|
+ 'item_id' => $itemId,
|
|
|
+ 'min_amount' => 1,
|
|
|
+ 'max_amount' => 10,
|
|
|
];
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算成熟期产量
|
|
|
+ *
|
|
|
+ * 在作物进入成熟期时调用,计算并确定最终产量
|
|
|
+ *
|
|
|
+ * @param FarmCrop $crop 作物对象
|
|
|
+ * @return int 最终产量
|
|
|
+ */
|
|
|
+ public function calculateMatureOutput(FarmCrop $crop): int
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $land = $crop->land;
|
|
|
+ $seed = $crop->seed;
|
|
|
+ $farmUser = $crop->user;
|
|
|
|
|
|
- // 如果没有找到匹配的产出配置,使用种子的默认产出
|
|
|
- $seed = FarmSeed::find($seedId);
|
|
|
+ // 1. 验证必须有产出物品ID
|
|
|
+ if (!$crop->final_output_item_id) {
|
|
|
+ Log::error('成熟期产量计算失败:作物没有确定的产出物品ID', [
|
|
|
+ 'crop_id' => $crop->id,
|
|
|
+ 'user_id' => $crop->user_id,
|
|
|
+ 'seed_id' => $seed->id,
|
|
|
+ 'growth_stage' => $crop->growth_stage->value
|
|
|
+ ]);
|
|
|
+ throw new \Exception("作物ID {$crop->id} 没有确定的产出物品ID,无法计算产量");
|
|
|
+ }
|
|
|
|
|
|
- return [
|
|
|
- 'item_id' => $itemId, // 使用传入的物品ID
|
|
|
- 'min_amount' => $seed->min_output,
|
|
|
- 'max_amount' => $seed->max_output,
|
|
|
- ];
|
|
|
+ // 2. 获取基础产量(使用发芽期确定的产出配置)
|
|
|
+ $outputInfo = $this->getOutputInfoByItemId($seed->id, $crop->final_output_item_id);
|
|
|
+ $baseAmount = mt_rand($outputInfo['min_amount'], $outputInfo['max_amount']);
|
|
|
+
|
|
|
+ // 3. 获取土地的产量加成
|
|
|
+ $landOutputBonus = $land->landType->output_bonus ?? 0;
|
|
|
+
|
|
|
+ // 4. 获取房屋的产量加成
|
|
|
+ $houseConfig = $farmUser->houseConfig;
|
|
|
+ $houseOutputBonus = ($houseConfig->output_bonus ?? 0) / 100; // 将百分比值转换为小数
|
|
|
+
|
|
|
+ // 5. 检查是否有丰收之神加持
|
|
|
+ $hasHarvestBuff = $farmUser->buffs()
|
|
|
+ ->where('buff_type', \App\Module\Farm\Enums\BUFF_TYPE::HARVEST_GOD)
|
|
|
+ ->where('expire_time', '>', now())
|
|
|
+ ->exists();
|
|
|
+
|
|
|
+ // 6. 计算灾害减产
|
|
|
+ $disasterPenalty = 0;
|
|
|
+ if (!empty($crop->disasters)) {
|
|
|
+ $dJian = \App\Module\Farm\Services\DisasterService::getAllDisasters();
|
|
|
+ foreach ($crop->disasters as $disaster) {
|
|
|
+ if (($disaster['status'] ?? '') === 'active') {
|
|
|
+ // 递加减产比例
|
|
|
+ $disasterPenalty += $dJian[$disaster] ?? 0.05; // 默认5%减产
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7. 计算最终产量
|
|
|
+ $finalAmount = $baseAmount;
|
|
|
+
|
|
|
+ // 应用土地加成
|
|
|
+ $finalAmount = (int)($finalAmount * (1 + $landOutputBonus));
|
|
|
+
|
|
|
+ // 应用房屋加成
|
|
|
+ $finalAmount = (int)($finalAmount * (1 + $houseOutputBonus));
|
|
|
+
|
|
|
+ // 应用灾害减产
|
|
|
+ $finalAmount = (int)($finalAmount * (1 - $disasterPenalty));
|
|
|
+
|
|
|
+ // 如果有丰收之神加持,使用最大可能产量
|
|
|
+ if ($hasHarvestBuff) {
|
|
|
+ $maxPossibleAmount = $seed->max_output;
|
|
|
+ $maxPossibleAmount = (int)($maxPossibleAmount * (1 + $landOutputBonus));
|
|
|
+ $maxPossibleAmount = (int)($maxPossibleAmount * (1 + $houseOutputBonus));
|
|
|
+ $finalAmount = max($finalAmount, $maxPossibleAmount);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 8. 应用产量限制
|
|
|
+ // 确保产量不超过全局最高产量
|
|
|
+ $globalMaxOutput = 3000;
|
|
|
+ $finalAmount = min($finalAmount, $globalMaxOutput);
|
|
|
+
|
|
|
+ // 如果有灾害,确保产量不超过灾害时最高产量
|
|
|
+ if ($disasterPenalty > 0) {
|
|
|
+ $disasterMaxOutput = 2000;
|
|
|
+ $finalAmount = min($finalAmount, $disasterMaxOutput);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保最小产量为1
|
|
|
+ $finalAmount = max(1, $finalAmount);
|
|
|
+
|
|
|
+ Log::info('成熟期产量计算完成', [
|
|
|
+ 'crop_id' => $crop->id,
|
|
|
+ 'user_id' => $crop->user_id,
|
|
|
+ 'seed_id' => $seed->id,
|
|
|
+ 'base_amount' => $baseAmount,
|
|
|
+ 'final_amount' => $finalAmount,
|
|
|
+ 'land_bonus' => $landOutputBonus,
|
|
|
+ 'house_bonus' => $houseOutputBonus,
|
|
|
+ 'disaster_penalty' => $disasterPenalty,
|
|
|
+ 'has_harvest_buff' => $hasHarvestBuff,
|
|
|
+ 'final_output_item_id' => $crop->final_output_item_id
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return $finalAmount;
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error('成熟期产量计算失败', [
|
|
|
+ 'crop_id' => $crop->id,
|
|
|
+ 'user_id' => $crop->user_id,
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ 'trace' => $e->getTraceAsString()
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 发生错误时返回种子的最小产量
|
|
|
+ return $crop->seed->min_output ?? 1;
|
|
|
+ }
|
|
|
}
|
|
|
}
|