From 1c207568a530b23c28084a4b626ba6a81959e839 Mon Sep 17 00:00:00 2001 From: Chomp Date: Sat, 21 Jun 2025 15:16:01 +0100 Subject: [PATCH] Moved loot generation logic from `LocationLifecycleService` into `LocationLootGenerator` --- .../Generators/LocationLootGenerator.cs | 71 +++++++++++++++++-- .../Services/LocationLifecycleService.cs | 70 ++++-------------- 2 files changed, 77 insertions(+), 64 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs index eafb49ac..1064863b 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs @@ -37,18 +37,75 @@ public class LocationLootGenerator( protected readonly SeasonalEventConfig _seasonalEventConfig = _configServer.GetConfig(); + + /// + /// Generate Loot for provided location () + /// + /// Id of location (e.g. bigmap/factory4_day) + /// Collection of spawn points with loot + public List GenerateLocationLoot(string locationId) + { + var result = new List(); + + // Get generation details for location from db + var locationDetails = _databaseService.GetLocation(locationId); + if (locationDetails is null) + { + _logger.Error($"Location: {locationId} not found in database, generated 0 loot items"); + return result; + } + + // Clone ammo data to ensure any changes don't affect the db values + var staticAmmoDist = _cloner.Clone(locationDetails.StaticAmmo); + + // Pull location-specific spawn limits from db + var itemsWithSpawnCountLimitsClone = _cloner.Clone(_locationConfig.LootMaxSpawnLimits.GetValueOrDefault(locationId.ToLower())); + + // Store items with spawn count limits inside so they can be accessed later inside static/dynamic loot spawn methods + counterTrackerHelper.AddDataToTrack(itemsWithSpawnCountLimitsClone); + + // Create containers with loot + result.AddRange(GenerateStaticContainers( + locationId.ToLower(), + staticAmmoDist + )); + + // Add dynamic loot to output loot + var dynamicSpawnPoints = GenerateDynamicLoot( + _cloner.Clone(locationDetails.LooseLoot.Value), + staticAmmoDist, + locationId.ToLower(), + itemsWithSpawnCountLimitsClone + ); + + // Merge dynamic spawns into result + result.AddRange(dynamicSpawnPoints); + + _logger.Success( + _localisationService.GetText( + "location-dynamic_items_spawned_success", + dynamicSpawnPoints.Count + ) + ); + _logger.Success(_localisationService.GetText("location-generated_success", locationId)); + + // Clean up tracker + counterTrackerHelper.Clear(); + + return result; + } + /// Create a list of container objects with randomised loot - /// Map base to generate containers for + /// Location to generate for /// Static ammo distribution /// List of container objects public List GenerateStaticContainers( - LocationBase locationBase, + string locationId, Dictionary> staticAmmoDist ) { var staticLootItemCount = 0; var result = new List(); - var locationId = locationBase.Id.ToLower(); var mapData = _databaseService.GetLocation(locationId); @@ -58,7 +115,7 @@ public class LocationLootGenerator( _logger.Error( _localisationService.GetText( "location-unable_to_find_static_weapon_for_map", - locationBase.Name + locationId ) ); } @@ -74,7 +131,7 @@ public class LocationLootGenerator( _logger.Error( _localisationService.GetText( "location-unable_to_find_static_container_for_map", - locationBase.Name + locationId ) ); } @@ -86,7 +143,7 @@ public class LocationLootGenerator( _logger.Error( _localisationService.GetText( "location-unable_to_find_forced_static_data_for_map", - locationBase.Name + locationId ) ); } @@ -145,7 +202,7 @@ public class LocationLootGenerator( if (_logger.IsLogEnabled(LogLevel.Debug)) { _logger.Debug( - $"Container randomisation disabled, Adding {staticRandomisableContainersOnMap.Count} containers to {locationBase.Name}" + $"Container randomisation disabled, Adding {staticRandomisableContainersOnMap.Count} containers to: {locationId}" ); } diff --git a/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs b/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs index ebd297ed..2b6e2fbe 100644 --- a/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs @@ -357,18 +357,14 @@ public class LocationLifecycleService } } + /// /// Generate a maps base location (cloned) and loot /// + /// Session/Player id /// Map name /// OPTIONAL - Should loot be generated for the map before being returned - /// LocationBase - /// LocationBase - /// OPTIONAL - Should loot be generated for the map before being returned - /// Map name - /// - /// Generate a maps base location (cloned) and loot - /// + /// LocationBase with loot public virtual LocationBase GenerateLocationAndLoot( string sessionId, string name, @@ -393,59 +389,22 @@ public class LocationLifecycleService return locationBaseClone; } - // Add custom pmcs to map every time its run + // Add custom PMCs to map every time its run _pmcWaveGenerator.ApplyWaveChangesToMap(locationBaseClone); - // Adjust raid based on whether this is a scav run + // Adjust raid values based raid type (e.g. Scav or PMC) LocationConfig? locationConfigClone = null; var raidAdjustments = _profileActivityService - .GetProfileActivityRaidData(sessionId) - ?.RaidAdjustments; + .GetProfileActivityRaidData(sessionId)? + .RaidAdjustments; if (raidAdjustments is not null) { locationConfigClone = _cloner.Clone(_locationConfig); // Clone values so they can be used to reset originals later _raidTimeAdjustmentService.MakeAdjustmentsToMap(raidAdjustments, locationBaseClone); } - var staticAmmoDist = _cloner.Clone(location.StaticAmmo); - - var itemsWithSpawnCountLimits = _cloner.Clone( - _locationConfig.LootMaxSpawnLimits.GetValueOrDefault(name.ToLower()) - ); - - // Store items with spawn count limits inside so they can be accessed later inside static/dynamic loot spawn methods - _counterTrackerHelper.AddDataToTrack(itemsWithSpawnCountLimits); - - // Create containers and add loot to them - var staticLoot = _locationLootGenerator.GenerateStaticContainers( - locationBaseClone, - staticAmmoDist - ); - locationBaseClone.Loot.AddRange(staticLoot); - - // Add dynamic loot to output loot - var dynamicLootDistClone = _cloner.Clone(location.LooseLoot.Value); - var dynamicSpawnPoints = _locationLootGenerator.GenerateDynamicLoot( - dynamicLootDistClone, - staticAmmoDist, - name.ToLower(), - itemsWithSpawnCountLimits - ); - - // Push chosen spawn points into returned object - foreach (var spawnPoint in dynamicSpawnPoints) - { - locationBaseClone.Loot.Add(spawnPoint); - } - - // Done generating, log results - _logger.Success( - _localisationService.GetText( - "location-dynamic_items_spawned_success", - dynamicSpawnPoints.Count - ) - ); - _logger.Success(_localisationService.GetText("location-generated_success", name)); + // Generate loot for location + locationBaseClone.Loot = _locationLootGenerator.GenerateLocationLoot(name); // Reset loot multipliers back to original values if (raidAdjustments is not null && locationConfigClone is not null) @@ -457,9 +416,6 @@ public class LocationLifecycleService _profileActivityService.GetProfileActivityRaidData(sessionId).RaidAdjustments = null; } - // Clean up tracker - _counterTrackerHelper.Clear(); - return locationBaseClone; } @@ -628,7 +584,7 @@ public class LocationLifecycleService // Check if new standing has leveled up trader _traderHelper.LevelUp(fenceId, pmcData); pmcData.TradersInfo[fenceId].LoyaltyLevel = Math.Max( - (int)pmcData.TradersInfo[fenceId].LoyaltyLevel, + (int) pmcData.TradersInfo[fenceId].LoyaltyLevel, 1 ); @@ -666,7 +622,7 @@ public class LocationLifecycleService // Check if new standing has leveled up trader _traderHelper.LevelUp(fenceId, pmcData); pmcData.TradersInfo[fenceId].LoyaltyLevel = Math.Max( - (int)pmcData.TradersInfo[fenceId].LoyaltyLevel, + (int) pmcData.TradersInfo[fenceId].LoyaltyLevel, 1 ); @@ -698,7 +654,7 @@ public class LocationLifecycleService fenceStanding += Math.Max(baseGain / extractCount, 0.01); // Ensure fence loyalty level is not above/below the range -7 to 15 - var newFenceStanding = Math.Min(Math.Max((double)fenceStanding, -7), 15); + var newFenceStanding = Math.Min(Math.Max((double) fenceStanding, -7), 15); _logger.Debug( $"Old vs new fence standing: {pmcData.TradersInfo[fenceId].Standing}, {newFenceStanding}" ); @@ -1002,7 +958,7 @@ public class LocationLifecycleService // Clamp fence standing var currentFenceStanding = postRaidProfile.TradersInfo[fenceId].Standing; pmcProfile.TradersInfo[fenceId].Standing = Math.Min( - Math.Max((double)currentFenceStanding, -7), + Math.Max((double) currentFenceStanding, -7), 15 ); // Ensure it stays between -7 and 15