完整实现自动收菜、自动播种、灾害防护三个宠物技能的具体效果
在之前的任务中,我们已经建立了宠物自动技能的基础架构:
但是三个核心技能的具体效果还没有完整实现,需要:
/**
* 获取用户所有可收获的土地
*/
public static function getHarvestableLands(int $userId): Collection
/**
* 获取用户所有空闲的土地
*/
public static function getIdleLands(int $userId): Collection
/**
* 获取用户所有有作物的土地
*/
public static function getLandsWithCrops(int $userId): Collection
public function getHarvestableLands(int $userId): Collection
{
// 查询状态为可收获的土地
$lands = FarmLand::where('user_id', $userId)
->where('status', LAND_STATUS::HARVESTABLE->value)
->orderBy('position')
->get();
return $lands->map(function ($land) {
return LandInfoDto::fromModel($land);
});
}
/**
* 获取用户拥有的种子物品
*/
public static function getUserSeedItems(int $userId, bool $includeExpired = false): array
{
// 获取所有种子的物品ID
$seedItemIds = FarmSeed::pluck('item_id')->toArray();
// 查询用户拥有的种子物品
$userItems = ItemUser::where('user_id', $userId)
->whereIn('item_id', $seedItemIds)
->where('quantity', '>', 0)
->get();
// 按物品ID分组并汇总数量
$seedItems = [];
foreach ($userItems as $userItem) {
$itemId = $userItem->item_id;
$seedItems[$itemId] = ($seedItems[$itemId] ?? 0) + $userItem->quantity;
}
return $seedItems;
}
public function processAutoHarvest(PetActiveSkill $activeSkill): void
{
$pet = $activeSkill->pet;
$userId = $pet->user_id;
// 获取用户所有可收获的土地
$harvestableLands = LandService::getHarvestableLands($userId);
$harvestCount = 0;
foreach ($harvestableLands as $land) {
try {
DB::beginTransaction();
// 调用收获服务
$result = CropService::harvestCrop($userId, $land->id);
if ($result && !$result->error) {
$harvestCount++;
Log::info('自动收菜成功', [
'user_id' => $userId,
'pet_id' => $pet->id,
'land_id' => $land->id
]);
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
Log::warning('自动收菜失败', [
'user_id' => $userId,
'pet_id' => $pet->id,
'land_id' => $land->id,
'error' => $e->getMessage()
]);
}
}
// 记录统计信息
$this->recordSkillStatistics($activeSkill, 'auto_harvest', [
'harvest_count' => $harvestCount,
'total_lands_checked' => $harvestableLands->count()
]);
}
public function processAutoPlant(PetActiveSkill $activeSkill): void
{
$pet = $activeSkill->pet;
$userId = $pet->user_id;
// 获取用户所有空闲的土地
$idleLands = LandService::getIdleLands($userId);
// 获取优先使用的种子列表
$preferredSeeds = $activeSkill->getConfigValue('preferred_seeds', []);
// 获取用户拥有的种子物品
$availableSeeds = $this->getAvailableSeeds($userId, $preferredSeeds);
$plantCount = 0;
foreach ($idleLands as $land) {
if (empty($availableSeeds)) {
break; // 种子用完了
}
try {
DB::beginTransaction();
// 选择种子(优先使用配置的种子)
$seedItemId = array_shift($availableSeeds);
// 先消耗种子物品
ItemService::consumeItem($userId, $seedItemId, null, 1, [
'source' => 'pet_auto_plant'
]);
// 调用种植服务
$result = CropService::plantCrop($userId, $land->id, $seedItemId);
if ($result) {
$plantCount++;
Log::info('自动播种成功', [
'user_id' => $userId,
'pet_id' => $pet->id,
'land_id' => $land->id,
'seed_item_id' => $seedItemId
]);
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
Log::warning('自动播种失败', [
'user_id' => $userId,
'pet_id' => $pet->id,
'land_id' => $land->id,
'error' => $e->getMessage()
]);
}
}
// 记录统计信息
$this->recordSkillStatistics($activeSkill, 'auto_plant', [
'plant_count' => $plantCount,
'total_lands_checked' => $idleLands->count()
]);
}
public function processDisasterProtection(PetActiveSkill $activeSkill): void
{
$pet = $activeSkill->pet;
$userId = $pet->user_id;
// 获取防护的灾害类型
$protectedTypes = $activeSkill->getConfigValue('protected_types', ['all']);
// 获取用户所有有作物的土地
$landsWithCrops = LandService::getLandsWithCrops($userId);
$protectionCount = 0;
foreach ($landsWithCrops as $land) {
try {
// 检查土地是否有灾害
$hasDisaster = $this->checkLandDisaster($land, $protectedTypes);
if ($hasDisaster) {
// 自动清除灾害(需要消耗相应道具)
$cleared = $this->autoClearDisaster($userId, $land, $protectedTypes);
if ($cleared) {
$protectionCount++;
Log::info('自动清除灾害成功', [
'user_id' => $userId,
'pet_id' => $pet->id,
'land_id' => $land->id
]);
}
}
} catch (\Exception $e) {
Log::warning('灾害防护处理失败', [
'user_id' => $userId,
'pet_id' => $pet->id,
'land_id' => $land->id,
'error' => $e->getMessage()
]);
}
}
// 记录统计信息
$this->recordSkillStatistics($activeSkill, 'disaster_protection', [
'protection_count' => $protectionCount,
'total_lands_checked' => $landsWithCrops->count(),
'protected_types' => $protectedTypes
]);
}
protected function checkLandDisaster($land, array $protectedTypes): bool
{
// 检查土地状态是否为灾害状态
if ($land->status !== LAND_STATUS::DISASTER->value) {
return false;
}
// 获取土地上的作物
$crop = $land->crop;
if (!$crop) {
return false;
}
// 检查作物是否有活跃的灾害
$disasters = $crop->disasters ?? [];
foreach ($disasters as $disaster) {
if (($disaster['status'] ?? '') === 'active') {
$disasterType = $disaster['type'] ?? 0;
// 如果防护类型包含'all'或包含特定灾害类型
if (in_array('all', $protectedTypes) || in_array($disasterType, $protectedTypes)) {
return true;
}
}
}
return false;
}
protected function autoClearDisaster(int $userId, $land, array $protectedTypes): bool
{
$crop = $land->crop;
if (!$crop) {
return false;
}
$disasters = $crop->disasters ?? [];
$clearedCount = 0;
foreach ($disasters as $disaster) {
if (($disaster['status'] ?? '') === 'active') {
$disasterType = $disaster['type'] ?? 0;
// 检查是否需要清除这种类型的灾害
if (in_array('all', $protectedTypes) || in_array($disasterType, $protectedTypes)) {
try {
// 获取对应的清除道具
$clearItem = $this->getDisasterClearItem($userId, $disasterType);
if ($clearItem) {
// 调用农场服务清除灾害
$result = CropService::clearDisaster($userId, $land->id, $disasterType);
if ($result) {
// 消耗道具
ItemService::consumeItem(
$userId,
$clearItem['item_id'],
null,
1,
['source' => 'pet_auto_disaster_protection']
);
$clearedCount++;
}
}
} catch (\Exception $e) {
Log::warning('宠物自动清除灾害失败', [
'user_id' => $userId,
'land_id' => $land->id,
'disaster_type' => $disasterType,
'error' => $e->getMessage()
]);
}
}
}
}
return $clearedCount > 0;
}
app/Module/Farm/Services/LandService.php - 新增土地查询方法app/Module/Farm/Logics/LandLogic.php - 实现土地查询逻辑app/Module/GameItems/Services/ItemService.php - 新增种子物品查询方法app/Module/Pet/Logic/PetAutoSkillLogic.php - 完善三个技能的具体实现✅ 已完成
app/Module/Farm/Services/LandService.php - 土地服务扩展app/Module/Farm/Logics/LandLogic.php - 土地逻辑实现app/Module/GameItems/Services/ItemService.php - 物品服务扩展app/Module/Pet/Logic/PetAutoSkillLogic.php - 自动技能逻辑实现