Format Style Fixes
This commit is contained in:
@@ -9,11 +9,7 @@ using SPTarkov.Server.Core.Services;
|
||||
namespace SPTarkov.Server.Core.Controllers;
|
||||
|
||||
[Injectable]
|
||||
public class AchievementController(
|
||||
ProfileHelper profileHelper,
|
||||
DatabaseService databaseService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
public class AchievementController(ProfileHelper profileHelper, DatabaseService databaseService, ConfigServer configServer)
|
||||
{
|
||||
protected readonly CoreConfig coreConfig = configServer.GetConfig<CoreConfig>();
|
||||
|
||||
@@ -37,11 +33,7 @@ public class AchievementController(
|
||||
var stats = new Dictionary<string, int>();
|
||||
var profiles = profileHelper
|
||||
.GetProfiles()
|
||||
.Where(kvp =>
|
||||
!coreConfig.Features.AchievementProfileIdBlacklist.Contains(
|
||||
kvp.Value.ProfileInfo.ProfileId
|
||||
)
|
||||
)
|
||||
.Where(kvp => !coreConfig.Features.AchievementProfileIdBlacklist.Contains(kvp.Value.ProfileInfo.ProfileId))
|
||||
.ToDictionary();
|
||||
|
||||
var achievements = databaseService.GetAchievements();
|
||||
@@ -70,8 +62,7 @@ public class AchievementController(
|
||||
var percentage = 0;
|
||||
if (profiles.Count > 0)
|
||||
{
|
||||
percentage = (int)
|
||||
Math.Round((double)profilesHaveAchievement / profiles.Count * 100);
|
||||
percentage = (int)Math.Round((double)profilesHaveAchievement / profiles.Count * 100);
|
||||
}
|
||||
|
||||
stats.Add(achievementId, percentage);
|
||||
|
||||
@@ -51,9 +51,7 @@ public class BotController(
|
||||
{
|
||||
if (!_botConfig.PresetBatch.TryGetValue(type, out var limit))
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText("bot-bot_preset_count_value_missing", type)
|
||||
);
|
||||
_logger.Warning(_serverLocalisationService.GetText("bot-bot_preset_count_value_missing", type));
|
||||
|
||||
return 10;
|
||||
}
|
||||
@@ -80,38 +78,23 @@ public class BotController(
|
||||
/// <param name="diffLevel">difficulty level server requested settings for</param>
|
||||
/// <param name="ignoreRaidSettings">OPTIONAL - should raid settings chosen pre-raid be ignored</param>
|
||||
/// <returns>Difficulty object</returns>
|
||||
public DifficultyCategories GetBotDifficulty(
|
||||
MongoId sessionId,
|
||||
string type,
|
||||
string diffLevel,
|
||||
bool ignoreRaidSettings = false
|
||||
)
|
||||
public DifficultyCategories GetBotDifficulty(MongoId sessionId, string type, string diffLevel, bool ignoreRaidSettings = false)
|
||||
{
|
||||
var difficulty = diffLevel.ToLowerInvariant();
|
||||
|
||||
var raidConfig = _profileActivityService
|
||||
.GetProfileActivityRaidData(sessionId)
|
||||
.RaidConfiguration;
|
||||
var raidConfig = _profileActivityService.GetProfileActivityRaidData(sessionId).RaidConfiguration;
|
||||
|
||||
if (!(raidConfig != null || ignoreRaidSettings))
|
||||
{
|
||||
_logger.Error(
|
||||
_serverLocalisationService.GetText(
|
||||
"bot-missing_application_context",
|
||||
"RAID_CONFIGURATION"
|
||||
)
|
||||
);
|
||||
_logger.Error(_serverLocalisationService.GetText("bot-missing_application_context", "RAID_CONFIGURATION"));
|
||||
}
|
||||
|
||||
// Check value chosen in pre-raid difficulty dropdown
|
||||
// If value is not 'asonline', change requested difficulty to be what was chosen in dropdown
|
||||
var botDifficultyDropDownValue =
|
||||
raidConfig?.WavesSettings?.BotDifficulty?.ToString().ToLowerInvariant() ?? "asonline";
|
||||
var botDifficultyDropDownValue = raidConfig?.WavesSettings?.BotDifficulty?.ToString().ToLowerInvariant() ?? "asonline";
|
||||
if (botDifficultyDropDownValue != "asonline")
|
||||
{
|
||||
difficulty = _botDifficultyHelper.ConvertBotDifficultyDropdownToBotDifficulty(
|
||||
botDifficultyDropDownValue
|
||||
);
|
||||
difficulty = _botDifficultyHelper.ConvertBotDifficultyDropdownToBotDifficulty(botDifficultyDropDownValue);
|
||||
}
|
||||
|
||||
var botDb = _databaseService.GetBots();
|
||||
@@ -147,9 +130,7 @@ public class BotController(
|
||||
result[botTypeLower] = result[Roles.Assault];
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
$"Unable to find bot: {botTypeLower} in db, copying: '{Roles.Assault}'"
|
||||
);
|
||||
_logger.Debug($"Unable to find bot: {botTypeLower} in db, copying: '{Roles.Assault}'");
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -158,9 +139,7 @@ public class BotController(
|
||||
if (botDetails?.BotDifficulty is null)
|
||||
{
|
||||
// Bot has no difficulty values, skip
|
||||
_logger.Warning(
|
||||
$"Unable to find bot: {botTypeLower} difficulty values in db, skipping"
|
||||
);
|
||||
_logger.Warning($"Unable to find bot: {botTypeLower} difficulty values in db, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -174,11 +153,7 @@ public class BotController(
|
||||
}
|
||||
|
||||
// Store all difficulty values in dict keyed by difficulty type e.g. easy/normal/hard/impossible
|
||||
result[botNameKey]
|
||||
.TryAdd(
|
||||
difficultyName,
|
||||
GetBotDifficulty(string.Empty, botNameKey, difficultyName, true)
|
||||
);
|
||||
result[botNameKey].TryAdd(difficultyName, GetBotDifficulty(string.Empty, botNameKey, difficultyName, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,17 +180,11 @@ public class BotController(
|
||||
/// <param name="pmcProfile">Player generating bots</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>List of generated bots</returns>
|
||||
protected List<BotBase> GenerateBotWaves(
|
||||
GenerateBotsRequestData request,
|
||||
PmcData? pmcProfile,
|
||||
MongoId sessionId
|
||||
)
|
||||
protected List<BotBase> GenerateBotWaves(GenerateBotsRequestData request, PmcData? pmcProfile, MongoId sessionId)
|
||||
{
|
||||
var generatedBotList = new List<BotBase>();
|
||||
var raidSettings = GetMostRecentRaidSettings(sessionId);
|
||||
var allPmcsHaveSameNameAsPlayer = _randomUtil.GetChance100(
|
||||
_pmcConfig.AllPMCsHavePlayerNameWithRandomPrefixChance
|
||||
);
|
||||
var allPmcsHaveSameNameAsPlayer = _randomUtil.GetChance100(_pmcConfig.AllPMCsHavePlayerNameWithRandomPrefixChance);
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
// Map conditions to promises for bot generation
|
||||
@@ -232,12 +201,7 @@ public class BotController(
|
||||
raidSettings
|
||||
);
|
||||
|
||||
GenerateBotWave(
|
||||
condition,
|
||||
botWaveGenerationDetails,
|
||||
generatedBotList,
|
||||
sessionId
|
||||
);
|
||||
GenerateBotWave(condition, botWaveGenerationDetails, generatedBotList, sessionId);
|
||||
})
|
||||
)
|
||||
.ToArray()
|
||||
@@ -247,9 +211,7 @@ public class BotController(
|
||||
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.Debug(
|
||||
$"Took {stopwatch.ElapsedMilliseconds}ms to GenerateMultipleBotsAndCache()"
|
||||
);
|
||||
_logger.Debug($"Took {stopwatch.ElapsedMilliseconds}ms to GenerateMultipleBotsAndCache()");
|
||||
}
|
||||
|
||||
return generatedBotList;
|
||||
@@ -270,17 +232,12 @@ public class BotController(
|
||||
MongoId sessionId
|
||||
)
|
||||
{
|
||||
var isEventBot = generateRequest.Role?.Contains(
|
||||
"event",
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
);
|
||||
var isEventBot = generateRequest.Role?.Contains("event", StringComparison.OrdinalIgnoreCase);
|
||||
if (isEventBot.GetValueOrDefault(false))
|
||||
{
|
||||
// Add eventRole data + reassign role property to be base type
|
||||
botGenerationDetails.EventRole = generateRequest.Role;
|
||||
botGenerationDetails.Role = _seasonalEventService.GetBaseRoleForEventBot(
|
||||
botGenerationDetails.EventRole
|
||||
);
|
||||
botGenerationDetails.Role = _seasonalEventService.GetBaseRoleForEventBot(botGenerationDetails.EventRole);
|
||||
}
|
||||
|
||||
var role = botGenerationDetails.EventRole ?? botGenerationDetails.Role;
|
||||
@@ -308,16 +265,11 @@ public class BotController(
|
||||
|
||||
try
|
||||
{
|
||||
bot = _botGenerator.PrepareAndGenerateBot(
|
||||
sessionId,
|
||||
_cloner.Clone(botGenerationDetails)
|
||||
);
|
||||
bot = _botGenerator.PrepareAndGenerateBot(sessionId, _cloner.Clone(botGenerationDetails));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(
|
||||
$"Failed to generate bot: {botGenerationDetails.Role} #{i + 1}: {e.Message} {e.StackTrace}"
|
||||
);
|
||||
_logger.Error($"Failed to generate bot: {botGenerationDetails.Role} #{i + 1}: {e.Message} {e.StackTrace}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -353,17 +305,11 @@ public class BotController(
|
||||
/// <returns>GetRaidConfigurationRequestData if it exists</returns>
|
||||
protected GetRaidConfigurationRequestData? GetMostRecentRaidSettings(MongoId sessionId)
|
||||
{
|
||||
var raidConfiguration = _profileActivityService
|
||||
.GetProfileActivityRaidData(sessionId)
|
||||
?.RaidConfiguration;
|
||||
var raidConfiguration = _profileActivityService.GetProfileActivityRaidData(sessionId)?.RaidConfiguration;
|
||||
|
||||
if (raidConfiguration is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
"bot-unable_to_load_raid_settings_from_appcontext"
|
||||
)
|
||||
);
|
||||
_logger.Warning(_serverLocalisationService.GetText("bot-unable_to_load_raid_settings_from_appcontext"));
|
||||
}
|
||||
|
||||
return raidConfiguration;
|
||||
@@ -376,10 +322,7 @@ public class BotController(
|
||||
/// <returns>MinMax values</returns>
|
||||
protected MinMax<int> GetPmcLevelRangeForMap(string? location)
|
||||
{
|
||||
return _pmcConfig.LocationSpecificPmcLevelOverride!.GetValueOrDefault(
|
||||
location?.ToLowerInvariant() ?? "",
|
||||
null
|
||||
);
|
||||
return _pmcConfig.LocationSpecificPmcLevelOverride!.GetValueOrDefault(location?.ToLowerInvariant() ?? "", null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -402,18 +345,13 @@ public class BotController(
|
||||
return new BotGenerationDetails
|
||||
{
|
||||
IsPmc = generateAsPmc,
|
||||
Side = generateAsPmc
|
||||
? _botHelper.GetPmcSideByRole(condition.Role ?? string.Empty)
|
||||
: "Savage",
|
||||
Side = generateAsPmc ? _botHelper.GetPmcSideByRole(condition.Role ?? string.Empty) : "Savage",
|
||||
Role = condition.Role,
|
||||
PlayerLevel = pmcProfile?.Info?.Level ?? 1,
|
||||
PlayerName = pmcProfile?.Info?.Nickname,
|
||||
BotRelativeLevelDeltaMax = _pmcConfig.BotRelativeLevelDeltaMax,
|
||||
BotRelativeLevelDeltaMin = _pmcConfig.BotRelativeLevelDeltaMin,
|
||||
BotCountToGenerate = Math.Max(
|
||||
GetBotPresetGenerationLimit(condition.Role),
|
||||
condition.Limit
|
||||
), // Choose largest between value passed in from request vs what's in bot.config
|
||||
BotCountToGenerate = Math.Max(GetBotPresetGenerationLimit(condition.Role), condition.Limit), // Choose largest between value passed in from request vs what's in bot.config
|
||||
BotDifficulty = condition.Difficulty,
|
||||
LocationSpecificPmcLevelOverride = GetPmcLevelRangeForMap(raidSettings?.Location), // Min/max levels for PMCs to generate within
|
||||
IsPlayerScav = false,
|
||||
@@ -437,12 +375,7 @@ public class BotController(
|
||||
|
||||
if (location == "default")
|
||||
{
|
||||
_logger.Warning(
|
||||
_serverLocalisationService.GetText(
|
||||
"bot-no_bot_cap_found_for_location",
|
||||
location.ToLowerInvariant()
|
||||
)
|
||||
);
|
||||
_logger.Warning(_serverLocalisationService.GetText("bot-no_bot_cap_found_for_location", location.ToLowerInvariant()));
|
||||
}
|
||||
|
||||
return maxCap;
|
||||
|
||||
@@ -41,32 +41,24 @@ public class BuildController(
|
||||
};
|
||||
|
||||
// Ensure the secure container in the default presets match what the player has equipped
|
||||
var defaultEquipmentPresetsClone = cloner
|
||||
.Clone(databaseService.GetTemplates().DefaultEquipmentPresets)
|
||||
.ToList();
|
||||
var defaultEquipmentPresetsClone = cloner.Clone(databaseService.GetTemplates().DefaultEquipmentPresets).ToList();
|
||||
|
||||
// Get players secure container
|
||||
var playerSecureContainer =
|
||||
profile.CharacterData?.PmcData?.Inventory?.Items?.FirstOrDefault(x =>
|
||||
x.SlotId == secureContainerSlotId
|
||||
);
|
||||
var playerSecureContainer = profile.CharacterData?.PmcData?.Inventory?.Items?.FirstOrDefault(x =>
|
||||
x.SlotId == secureContainerSlotId
|
||||
);
|
||||
|
||||
var firstDefaultItemsSecureContainer = defaultEquipmentPresetsClone
|
||||
.FirstOrDefault()
|
||||
?.Items?.FirstOrDefault(x => x.SlotId == secureContainerSlotId);
|
||||
|
||||
if (
|
||||
playerSecureContainer is not null
|
||||
&& playerSecureContainer.Template != firstDefaultItemsSecureContainer?.Template
|
||||
)
|
||||
if (playerSecureContainer is not null && playerSecureContainer.Template != firstDefaultItemsSecureContainer?.Template)
|
||||
// Default equipment presets' secure container tpl doesn't match players secure container tpl
|
||||
{
|
||||
foreach (var defaultPreset in defaultEquipmentPresetsClone)
|
||||
{
|
||||
// Find presets secure container
|
||||
var secureContainer = defaultPreset.Items?.FirstOrDefault(item =>
|
||||
item.SlotId == secureContainerSlotId
|
||||
);
|
||||
var secureContainer = defaultPreset.Items?.FirstOrDefault(item => item.SlotId == secureContainerSlotId);
|
||||
if (secureContainer is not null)
|
||||
{
|
||||
secureContainer.Template = playerSecureContainer.Template;
|
||||
@@ -133,9 +125,7 @@ public class BuildController(
|
||||
var profile = profileHelper.GetFullProfile(sessionID);
|
||||
var pmcData = profile.CharacterData.PmcData;
|
||||
|
||||
var existingSavedEquipmentBuilds = saveServer
|
||||
.GetProfile(sessionID)
|
||||
.UserBuildData.EquipmentBuilds;
|
||||
var existingSavedEquipmentBuilds = saveServer.GetProfile(sessionID).UserBuildData.EquipmentBuilds;
|
||||
|
||||
// Replace duplicate ID's. The first item is the base item.
|
||||
// Root ID and the base item ID need to match.
|
||||
@@ -150,9 +140,7 @@ public class BuildController(
|
||||
Items = request.Items.ToList(),
|
||||
};
|
||||
|
||||
var existingBuild = existingSavedEquipmentBuilds?.FirstOrDefault(build =>
|
||||
build.Name == request.Name || build.Id == request.Id
|
||||
);
|
||||
var existingBuild = existingSavedEquipmentBuilds?.FirstOrDefault(build => build.Name == request.Name || build.Id == request.Id);
|
||||
if (existingBuild is not null)
|
||||
{
|
||||
// Already exists, replace
|
||||
@@ -198,9 +186,7 @@ public class BuildController(
|
||||
profile.UserBuildData.MagazineBuilds ??= [];
|
||||
|
||||
// Check if template with desired name already exists and remove it
|
||||
var magazineBuildToRemove = profile.UserBuildData.MagazineBuilds.FirstOrDefault(item =>
|
||||
item.Name == request.Name
|
||||
);
|
||||
var magazineBuildToRemove = profile.UserBuildData.MagazineBuilds.FirstOrDefault(item => item.Name == request.Name);
|
||||
if (magazineBuildToRemove is not null)
|
||||
{
|
||||
profile.UserBuildData.MagazineBuilds.Remove(magazineBuildToRemove);
|
||||
@@ -224,9 +210,7 @@ public class BuildController(
|
||||
var magazineBuilds = profile.UserBuildData.MagazineBuilds;
|
||||
|
||||
// Check for id in weapon array first
|
||||
var matchingWeaponBuild = weaponBuilds.FirstOrDefault(weaponBuild =>
|
||||
weaponBuild.Id == idToRemove
|
||||
);
|
||||
var matchingWeaponBuild = weaponBuilds.FirstOrDefault(weaponBuild => weaponBuild.Id == idToRemove);
|
||||
if (matchingWeaponBuild is not null)
|
||||
{
|
||||
weaponBuilds.Remove(matchingWeaponBuild);
|
||||
@@ -235,9 +219,7 @@ public class BuildController(
|
||||
}
|
||||
|
||||
// Id not found in weapons, try equipment
|
||||
var matchingEquipmentBuild = equipmentBuilds.FirstOrDefault(equipmentBuild =>
|
||||
equipmentBuild.Id == idToRemove
|
||||
);
|
||||
var matchingEquipmentBuild = equipmentBuilds.FirstOrDefault(equipmentBuild => equipmentBuild.Id == idToRemove);
|
||||
if (matchingEquipmentBuild is not null)
|
||||
{
|
||||
equipmentBuilds.Remove(matchingEquipmentBuild);
|
||||
@@ -246,9 +228,7 @@ public class BuildController(
|
||||
}
|
||||
|
||||
// Id not found in weapons/equipment, try mags
|
||||
var matchingMagazineBuild = magazineBuilds.FirstOrDefault(magBuild =>
|
||||
magBuild.Id == idToRemove
|
||||
);
|
||||
var matchingMagazineBuild = magazineBuilds.FirstOrDefault(magBuild => magBuild.Id == idToRemove);
|
||||
if (matchingMagazineBuild is not null)
|
||||
{
|
||||
magazineBuilds.Remove(matchingMagazineBuild);
|
||||
@@ -257,8 +237,6 @@ public class BuildController(
|
||||
}
|
||||
|
||||
// Not found in weapons,equipment or magazines, not good
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("build-unable_to_delete_preset", idToRemove)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("build-unable_to_delete_preset", idToRemove));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,18 +42,12 @@ public class CustomizationController(
|
||||
|
||||
var matchingSuits = suits?.Where(s => clothing.ContainsKey(s.SuiteId));
|
||||
matchingSuits = matchingSuits?.Where(s =>
|
||||
clothing[s.SuiteId]?.Properties?.Side?.Contains(pmcData?.Info?.Side ?? string.Empty)
|
||||
?? false
|
||||
clothing[s.SuiteId]?.Properties?.Side?.Contains(pmcData?.Info?.Side ?? string.Empty) ?? false
|
||||
);
|
||||
|
||||
if (matchingSuits == null)
|
||||
{
|
||||
throw new Exception(
|
||||
serverLocalisationService.GetText(
|
||||
"customisation-unable_to_get_trader_suits",
|
||||
traderId
|
||||
)
|
||||
);
|
||||
throw new Exception(serverLocalisationService.GetText("customisation-unable_to_get_trader_suits", traderId));
|
||||
}
|
||||
|
||||
return matchingSuits.ToList();
|
||||
@@ -67,23 +61,14 @@ public class CustomizationController(
|
||||
/// <param name="buyClothingRequest">Request object</param>
|
||||
/// <param name="sessionId">Session id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse BuyCustomisation(
|
||||
PmcData pmcData,
|
||||
BuyClothingRequestData buyClothingRequest,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse BuyCustomisation(PmcData pmcData, BuyClothingRequestData buyClothingRequest, MongoId sessionId)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionId);
|
||||
|
||||
var traderOffer = GetTraderClothingOffer(sessionId, buyClothingRequest.Offer);
|
||||
if (traderOffer is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"customisation-unable_to_find_suit_by_id",
|
||||
buyClothingRequest.Offer
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("customisation-unable_to_find_suit_by_id", buyClothingRequest.Offer));
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -130,9 +115,7 @@ public class CustomizationController(
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionId);
|
||||
|
||||
// Check if clothing can be found by id
|
||||
return fullProfile.CustomisationUnlocks.Exists(customisation =>
|
||||
Equals(customisation.Id, suitId)
|
||||
);
|
||||
return fullProfile.CustomisationUnlocks.Exists(customisation => Equals(customisation.Id, suitId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -146,12 +129,7 @@ public class CustomizationController(
|
||||
var foundSuit = GetAllTraderSuits(sessionId).FirstOrDefault(s => s.Id == offerId);
|
||||
if (foundSuit is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"customisation-unable_to_find_suit_with_id",
|
||||
offerId
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("customisation-unable_to_find_suit_with_id", offerId));
|
||||
}
|
||||
|
||||
return foundSuit;
|
||||
@@ -180,14 +158,7 @@ public class CustomizationController(
|
||||
{
|
||||
var options = new ProcessBuyTradeRequestData
|
||||
{
|
||||
SchemeItems =
|
||||
[
|
||||
new IdWithCount
|
||||
{
|
||||
Count = inventoryItemToProcess.Count.Value,
|
||||
Id = inventoryItemToProcess.Id,
|
||||
},
|
||||
],
|
||||
SchemeItems = [new IdWithCount { Count = inventoryItemToProcess.Count.Value, Id = inventoryItemToProcess.Id }],
|
||||
TransactionId = Traders.RAGMAN,
|
||||
Action = "BuyCustomization",
|
||||
Type = "",
|
||||
@@ -212,10 +183,7 @@ public class CustomizationController(
|
||||
|
||||
foreach (var (traderId, trader) in traders)
|
||||
{
|
||||
if (
|
||||
trader.Base?.CustomizationSeller is not null
|
||||
&& trader.Base.CustomizationSeller.Value
|
||||
)
|
||||
if (trader.Base?.CustomizationSeller is not null && trader.Base.CustomizationSeller.Value)
|
||||
{
|
||||
result.AddRange(GetTraderSuits(traderId, sessionId));
|
||||
}
|
||||
@@ -241,9 +209,7 @@ public class CustomizationController(
|
||||
/// <returns></returns>
|
||||
public List<CustomisationStorage> GetCustomisationStorage(MongoId sessionId)
|
||||
{
|
||||
var customisationResultsClone = cloner.Clone(
|
||||
databaseService.GetTemplates().CustomisationStorage
|
||||
);
|
||||
var customisationResultsClone = cloner.Clone(databaseService.GetTemplates().CustomisationStorage);
|
||||
|
||||
var profile = profileHelper.GetFullProfile(sessionId);
|
||||
if (profile is null)
|
||||
@@ -263,11 +229,7 @@ public class CustomizationController(
|
||||
/// <param name="request"></param>
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse SetCustomisation(
|
||||
MongoId sessionId,
|
||||
CustomizationSetRequest request,
|
||||
PmcData pmcData
|
||||
)
|
||||
public ItemEventRouterResponse SetCustomisation(MongoId sessionId, CustomizationSetRequest request, PmcData pmcData)
|
||||
{
|
||||
foreach (var customisation in request.Customizations)
|
||||
{
|
||||
|
||||
@@ -38,12 +38,7 @@ public class DialogueController(
|
||||
{
|
||||
if (_dialogueChatBots.Any(cb => cb.GetChatBot().Id == chatBot.GetChatBot().Id))
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"dialog-chatbot_id_already_exists",
|
||||
chatBot.GetChatBot().Id
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("dialog-chatbot_id_already_exists", chatBot.GetChatBot().Id));
|
||||
}
|
||||
|
||||
_dialogueChatBots.Add(chatBot);
|
||||
@@ -190,11 +185,7 @@ public class DialogueController(
|
||||
/// <param name="messageType">What type of message is being sent</param>
|
||||
/// <param name="sessionId">Player id</param>
|
||||
/// <returns>UserDialogInfo list</returns>
|
||||
public virtual List<UserDialogInfo> GetDialogueUsers(
|
||||
Dialogue? dialog,
|
||||
MessageType? messageType,
|
||||
MongoId sessionId
|
||||
)
|
||||
public virtual List<UserDialogInfo> GetDialogueUsers(Dialogue? dialog, MessageType? messageType, MongoId sessionId)
|
||||
{
|
||||
var profile = saveServer.GetProfile(sessionId);
|
||||
|
||||
@@ -202,9 +193,7 @@ public class DialogueController(
|
||||
if (
|
||||
messageType == MessageType.UserMessage
|
||||
&& dialog?.Users is not null
|
||||
&& dialog.Users.All(userDialog =>
|
||||
userDialog.Id != profile.CharacterData?.PmcData?.SessionId
|
||||
)
|
||||
&& dialog.Users.All(userDialog => userDialog.Id != profile.CharacterData?.PmcData?.SessionId)
|
||||
)
|
||||
{
|
||||
dialog.Users.Add(
|
||||
@@ -218,11 +207,7 @@ public class DialogueController(
|
||||
Nickname = profile.CharacterData?.PmcData?.Info?.Nickname,
|
||||
Side = profile.CharacterData?.PmcData?.Info?.Side,
|
||||
MemberCategory = profile.CharacterData?.PmcData?.Info?.MemberCategory,
|
||||
SelectedMemberCategory = profile
|
||||
.CharacterData
|
||||
?.PmcData
|
||||
?.Info
|
||||
?.SelectedMemberCategory,
|
||||
SelectedMemberCategory = profile.CharacterData?.PmcData?.Info?.SelectedMemberCategory,
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -240,10 +225,7 @@ public class DialogueController(
|
||||
/// <param name="request">Get dialog request</param>
|
||||
/// <param name="sessionId">Session id</param>
|
||||
/// <returns>GetMailDialogViewResponseData object</returns>
|
||||
public virtual GetMailDialogViewResponseData GenerateDialogueView(
|
||||
GetMailDialogViewRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public virtual GetMailDialogViewResponseData GenerateDialogueView(GetMailDialogViewRequestData request, MongoId sessionId)
|
||||
{
|
||||
var dialogueId = request.DialogId;
|
||||
var fullProfile = saveServer.GetProfile(sessionId);
|
||||
@@ -279,18 +261,11 @@ public class DialogueController(
|
||||
/// <param name="profile">Player profile</param>
|
||||
/// <param name="request">get dialog request</param>
|
||||
/// <returns>Dialogue</returns>
|
||||
protected Dialogue GetDialogByIdFromProfile(
|
||||
SptProfile profile,
|
||||
GetMailDialogViewRequestData request
|
||||
)
|
||||
protected Dialogue GetDialogByIdFromProfile(SptProfile profile, GetMailDialogViewRequestData request)
|
||||
{
|
||||
if (
|
||||
profile.DialogueRecords is null
|
||||
|| profile.DialogueRecords.ContainsKey(request.DialogId!)
|
||||
)
|
||||
if (profile.DialogueRecords is null || profile.DialogueRecords.ContainsKey(request.DialogId!))
|
||||
{
|
||||
return profile.DialogueRecords?[request.DialogId!]
|
||||
?? throw new NullReferenceException();
|
||||
return profile.DialogueRecords?[request.DialogId!] ?? throw new NullReferenceException();
|
||||
}
|
||||
|
||||
profile.DialogueRecords[request.DialogId!] = new Dialogue
|
||||
@@ -310,9 +285,7 @@ public class DialogueController(
|
||||
|
||||
var dialogue = profile.DialogueRecords[request.DialogId!];
|
||||
dialogue.Users = [];
|
||||
var chatBot = _dialogueChatBots.FirstOrDefault(cb =>
|
||||
cb.GetChatBot().Id == request.DialogId
|
||||
);
|
||||
var chatBot = _dialogueChatBots.FirstOrDefault(cb => cb.GetChatBot().Id == request.DialogId);
|
||||
|
||||
if (chatBot is null)
|
||||
{
|
||||
@@ -331,10 +304,7 @@ public class DialogueController(
|
||||
/// <param name="fullProfile">Player profile</param>
|
||||
/// <param name="userDialogs">The participants of the mail</param>
|
||||
/// <returns>UserDialogInfo list</returns>
|
||||
protected List<UserDialogInfo> GetProfilesForMail(
|
||||
SptProfile fullProfile,
|
||||
List<UserDialogInfo>? userDialogs
|
||||
)
|
||||
protected List<UserDialogInfo> GetProfilesForMail(SptProfile fullProfile, List<UserDialogInfo>? userDialogs)
|
||||
{
|
||||
List<UserDialogInfo> result = [];
|
||||
if (userDialogs is null)
|
||||
@@ -383,10 +353,7 @@ public class DialogueController(
|
||||
var activeMessages = GetActiveMessagesFromDialog(sessionId, dialogueId);
|
||||
foreach (var message in activeMessages)
|
||||
{
|
||||
if (
|
||||
message.HasRewards.GetValueOrDefault(false)
|
||||
&& !message.RewardCollected.GetValueOrDefault(false)
|
||||
)
|
||||
if (message.HasRewards.GetValueOrDefault(false) && !message.RewardCollected.GetValueOrDefault(false))
|
||||
{
|
||||
newAttachmentCount++;
|
||||
}
|
||||
@@ -436,12 +403,7 @@ public class DialogueController(
|
||||
var profile = saveServer.GetProfile(sessionId);
|
||||
if (!profile.DialogueRecords.Remove(dialogueId))
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"dialogue-unable_to_find_in_profile",
|
||||
new { sessionId, dialogueId }
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("dialogue-unable_to_find_in_profile", new { sessionId, dialogueId }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,12 +418,7 @@ public class DialogueController(
|
||||
var dialog = dialogueHelper.GetDialogsForProfile(sessionId).GetValueOrDefault(dialogueId);
|
||||
if (dialog is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"dialogue-unable_to_find_in_profile",
|
||||
new { sessionId, dialogueId }
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("dialogue-unable_to_find_in_profile", new { sessionId, dialogueId }));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -480,12 +437,7 @@ public class DialogueController(
|
||||
var dialogs = dialogueHelper.GetDialogsForProfile(sessionId);
|
||||
if (dialogs.Any() != true)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"dialogue-unable_to_find_dialogs_in_profile",
|
||||
new { sessionId }
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("dialogue-unable_to_find_dialogs_in_profile", new { sessionId }));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -504,10 +456,7 @@ public class DialogueController(
|
||||
/// <param name="dialogueId">Dialog to get mail attachments from</param>
|
||||
/// <param name="sessionId">Session id</param>
|
||||
/// <returns>GetAllAttachmentsResponse or null if dialogue doesn't exist</returns>
|
||||
public virtual GetAllAttachmentsResponse? GetAllAttachments(
|
||||
string dialogueId,
|
||||
MongoId sessionId
|
||||
)
|
||||
public virtual GetAllAttachmentsResponse? GetAllAttachments(string dialogueId, MongoId sessionId)
|
||||
{
|
||||
var dialogs = dialogueHelper.GetDialogsForProfile(sessionId);
|
||||
var dialog = dialogs.TryGetValue(dialogueId, out var dialogInfo);
|
||||
@@ -538,16 +487,11 @@ public class DialogueController(
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async ValueTask<string> SendMessage(
|
||||
MongoId sessionId,
|
||||
SendMessageRequest request
|
||||
)
|
||||
public virtual async ValueTask<string> SendMessage(MongoId sessionId, SendMessageRequest request)
|
||||
{
|
||||
mailSendService.SendPlayerMessageToNpc(sessionId, request.DialogId, request.Text);
|
||||
|
||||
var chatBot = _dialogueChatBots.FirstOrDefault(cb =>
|
||||
cb.GetChatBot().Id == request.DialogId
|
||||
);
|
||||
var chatBot = _dialogueChatBots.FirstOrDefault(cb => cb.GetChatBot().Id == request.DialogId);
|
||||
|
||||
if (chatBot is not null)
|
||||
{
|
||||
@@ -619,10 +563,7 @@ public class DialogueController(
|
||||
/// <param name="sessionID">Session/player id</param>
|
||||
/// <param name="request">Sent friend request</param>
|
||||
/// <returns></returns>
|
||||
public virtual FriendRequestSendResponse SendFriendRequest(
|
||||
MongoId sessionID,
|
||||
FriendRequestData request
|
||||
)
|
||||
public virtual FriendRequestSendResponse SendFriendRequest(MongoId sessionID, FriendRequestData request)
|
||||
{
|
||||
// To avoid needing to jump between profiles, auto-accept all friend requests
|
||||
var friendProfile = profileHelper.GetFullProfile(request.To.Value);
|
||||
@@ -647,9 +588,7 @@ public class DialogueController(
|
||||
var notification = new WsFriendsListAccept
|
||||
{
|
||||
EventType = NotificationEventType.friendListRequestAccept,
|
||||
Profile = profileHelper.GetChatRoomMemberFromPmcProfile(
|
||||
friendProfile.CharacterData.PmcData
|
||||
),
|
||||
Profile = profileHelper.GetChatRoomMemberFromPmcProfile(friendProfile.CharacterData.PmcData),
|
||||
};
|
||||
notificationSendHelper.SendMessage(sessionID, notification);
|
||||
},
|
||||
@@ -687,9 +626,7 @@ public class DialogueController(
|
||||
var profile = saveServer.GetProfile(sessionId);
|
||||
if (!profile.DialogueRecords.TryGetValue(request.DialogId, out var dialogToClear))
|
||||
{
|
||||
logger.Warning(
|
||||
$"unable to clear messages from dialog: {request.DialogId} as it cannot be found in profile: {sessionId}"
|
||||
);
|
||||
logger.Warning($"unable to clear messages from dialog: {request.DialogId} as it cannot be found in profile: {sessionId}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -77,14 +77,8 @@ public class GameController(
|
||||
return;
|
||||
}
|
||||
|
||||
fullProfile.CharacterData!.PmcData!.WishList ??= new DictionaryOrList<MongoId, int>(
|
||||
new Dictionary<MongoId, int>(),
|
||||
[]
|
||||
);
|
||||
fullProfile.CharacterData.ScavData!.WishList ??= new DictionaryOrList<MongoId, int>(
|
||||
new Dictionary<MongoId, int>(),
|
||||
[]
|
||||
);
|
||||
fullProfile.CharacterData!.PmcData!.WishList ??= new DictionaryOrList<MongoId, int>(new Dictionary<MongoId, int>(), []);
|
||||
fullProfile.CharacterData.ScavData!.WishList ??= new DictionaryOrList<MongoId, int>(new Dictionary<MongoId, int>(), []);
|
||||
|
||||
if (fullProfile.DialogueRecords is not null)
|
||||
{
|
||||
@@ -93,9 +87,7 @@ public class GameController(
|
||||
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug(
|
||||
$"Started game with session {sessionId} {fullProfile.ProfileInfo?.Username}"
|
||||
);
|
||||
logger.Debug($"Started game with session {sessionId} {fullProfile.ProfileInfo?.Username}");
|
||||
}
|
||||
|
||||
var pmcProfile = fullProfile.CharacterData.PmcData;
|
||||
@@ -122,20 +114,12 @@ public class GameController(
|
||||
|
||||
if (pmcProfile.Hideout is not null)
|
||||
{
|
||||
profileFixerService.AddMissingHideoutBonusesToProfile(
|
||||
pmcProfile,
|
||||
databaseService.GetHideout().Areas
|
||||
);
|
||||
profileFixerService.AddMissingHideoutBonusesToProfile(pmcProfile, databaseService.GetHideout().Areas);
|
||||
hideoutHelper.SetHideoutImprovementsToCompleted(pmcProfile);
|
||||
pmcProfile.UnlockHideoutWallInProfile();
|
||||
|
||||
// Handle if player has been inactive for a long time, catch up on hideout update before the user goes to his hideout
|
||||
if (
|
||||
!profileActivityService.ActiveWithinLastMinutes(
|
||||
sessionId,
|
||||
_hideoutConfig.UpdateProfileHideoutWhenActiveWithinMinutes
|
||||
)
|
||||
)
|
||||
if (!profileActivityService.ActiveWithinLastMinutes(sessionId, _hideoutConfig.UpdateProfileHideoutWhenActiveWithinMinutes))
|
||||
{
|
||||
hideoutHelper.UpdatePlayerHideout(sessionId);
|
||||
}
|
||||
@@ -170,11 +154,8 @@ public class GameController(
|
||||
{
|
||||
var profile = profileHelper.GetPmcProfile(sessionId);
|
||||
var gameTime =
|
||||
profile
|
||||
?.Stats?.Eft?.OverallCounters?.Items?.FirstOrDefault(c =>
|
||||
c.Key!.Contains("LifeTime") && c.Key.Contains("Pmc")
|
||||
)
|
||||
?.Value ?? 0D;
|
||||
profile?.Stats?.Eft?.OverallCounters?.Items?.FirstOrDefault(c => c.Key!.Contains("LifeTime") && c.Key.Contains("Pmc"))?.Value
|
||||
?? 0D;
|
||||
|
||||
var config = new GameConfigResponse
|
||||
{
|
||||
@@ -213,11 +194,7 @@ public class GameController(
|
||||
/// <returns></returns>
|
||||
public GameModeResponse GetGameMode(MongoId sessionId, GameModeRequestData requestData)
|
||||
{
|
||||
return new GameModeResponse
|
||||
{
|
||||
GameMode = "pve",
|
||||
BackendUrl = httpServerHelper.GetBackendUrl(),
|
||||
};
|
||||
return new GameModeResponse { GameMode = "pve", BackendUrl = httpServerHelper.GetBackendUrl() };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -247,11 +224,7 @@ public class GameController(
|
||||
/// <returns></returns>
|
||||
public CheckVersionResponse GetValidGameVersion(MongoId sessionId)
|
||||
{
|
||||
return new CheckVersionResponse
|
||||
{
|
||||
IsValid = true,
|
||||
LatestVersion = _coreConfig.CompatibleTarkovVersion,
|
||||
};
|
||||
return new CheckVersionResponse { IsValid = true, LatestVersion = _coreConfig.CompatibleTarkovVersion };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -294,9 +267,7 @@ public class GameController(
|
||||
var botReloadSkill = pmcProfile.GetSkillFromProfile(SkillTypes.BotReload);
|
||||
if (botReloadSkill?.Progress > 0)
|
||||
{
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("server_start_player_active_botreload_skill")
|
||||
);
|
||||
logger.Warning(serverLocalisationService.GetText("server_start_player_active_botreload_skill"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,9 +309,7 @@ public class GameController(
|
||||
if (pmcProfile.Health?.Energy?.Current - pmcProfile.Health?.Energy?.Maximum <= _deviation)
|
||||
{
|
||||
// Set new value, whatever is smallest
|
||||
pmcProfile.Health!.Energy!.Current += Math.Round(
|
||||
energyRegenPerHour * (diffSeconds!.Value / 3600)
|
||||
);
|
||||
pmcProfile.Health!.Energy!.Current += Math.Round(energyRegenPerHour * (diffSeconds!.Value / 3600));
|
||||
if (pmcProfile.Health.Energy.Current > pmcProfile.Health.Energy.Maximum)
|
||||
{
|
||||
pmcProfile.Health.Energy.Current = pmcProfile.Health.Energy.Maximum;
|
||||
@@ -348,14 +317,9 @@ public class GameController(
|
||||
}
|
||||
|
||||
// Player has hydration deficit
|
||||
if (
|
||||
pmcProfile.Health?.Hydration?.Current - pmcProfile.Health?.Hydration?.Maximum
|
||||
<= _deviation
|
||||
)
|
||||
if (pmcProfile.Health?.Hydration?.Current - pmcProfile.Health?.Hydration?.Maximum <= _deviation)
|
||||
{
|
||||
pmcProfile.Health!.Hydration!.Current += Math.Round(
|
||||
hydrationRegenPerHour * (diffSeconds!.Value / 3600)
|
||||
);
|
||||
pmcProfile.Health!.Hydration!.Current += Math.Round(hydrationRegenPerHour * (diffSeconds!.Value / 3600));
|
||||
if (pmcProfile.Health.Hydration.Current > pmcProfile.Health.Hydration.Maximum)
|
||||
{
|
||||
pmcProfile.Health.Hydration.Current = pmcProfile.Health.Hydration.Maximum;
|
||||
@@ -375,15 +339,9 @@ public class GameController(
|
||||
/// <param name="pmcProfile">Player</param>
|
||||
/// <param name="hpRegenPerHour"></param>
|
||||
/// <param name="diffSeconds"></param>
|
||||
protected void DecreaseBodyPartEffectTimes(
|
||||
PmcData pmcProfile,
|
||||
double hpRegenPerHour,
|
||||
double diffSeconds
|
||||
)
|
||||
protected void DecreaseBodyPartEffectTimes(PmcData pmcProfile, double hpRegenPerHour, double diffSeconds)
|
||||
{
|
||||
foreach (
|
||||
var bodyPart in pmcProfile.Health!.BodyParts!.Select(bodyPartKvP => bodyPartKvP.Value)
|
||||
)
|
||||
foreach (var bodyPart in pmcProfile.Health!.BodyParts!.Select(bodyPartKvP => bodyPartKvP.Value))
|
||||
{
|
||||
// Check part hp
|
||||
if (bodyPart.Health!.Current < bodyPart.Health.Maximum)
|
||||
@@ -456,11 +414,7 @@ public class GameController(
|
||||
/// <param name="pmcProfile"></param>
|
||||
protected void SendMechanicGiftsToNewProfile(PmcData pmcProfile)
|
||||
{
|
||||
giftService.SendGiftWithSilentReceivedCheck(
|
||||
"MechanicGiftDay1",
|
||||
pmcProfile.SessionId.Value,
|
||||
1
|
||||
);
|
||||
giftService.SendGiftWithSilentReceivedCheck("MechanicGiftDay1", pmcProfile.SessionId.Value, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -475,9 +429,7 @@ public class GameController(
|
||||
{
|
||||
if (
|
||||
fullProfile.SptData.Mods.Any(m =>
|
||||
m.Author == mod.ModMetadata.Author
|
||||
&& m.Version == mod.ModMetadata.Version
|
||||
&& m.Name == mod.ModMetadata.Name
|
||||
m.Author == mod.ModMetadata.Author && m.Version == mod.ModMetadata.Version && m.Name == mod.ModMetadata.Name
|
||||
)
|
||||
)
|
||||
{
|
||||
@@ -554,9 +506,7 @@ public class GameController(
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug($"Profile made with: {fullProfile.SptData?.Version}");
|
||||
logger.Debug(
|
||||
$"Server version: {ProgramStatics.SPT_VERSION() ?? _coreConfig.SptVersion} {ProgramStatics.COMMIT()}"
|
||||
);
|
||||
logger.Debug($"Server version: {ProgramStatics.SPT_VERSION() ?? _coreConfig.SptVersion} {ProgramStatics.COMMIT()}");
|
||||
logger.Debug($"Debug enabled: {ProgramStatics.DEBUG()}");
|
||||
logger.Debug($"Mods enabled: {ProgramStatics.MODS()}");
|
||||
}
|
||||
|
||||
@@ -34,24 +34,15 @@ public class HealthController(
|
||||
/// <param name="request">Healing request</param>
|
||||
/// <param name="sessionID">Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse OffRaidHeal(
|
||||
PmcData pmcData,
|
||||
OffraidHealRequestData request,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse OffRaidHeal(PmcData pmcData, OffraidHealRequestData request, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
|
||||
// Update medkit used (hpresource)
|
||||
var healingItemToUse = pmcData.Inventory.Items.FirstOrDefault(item =>
|
||||
item.Id == request.Item
|
||||
);
|
||||
var healingItemToUse = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == request.Item);
|
||||
if (healingItemToUse is null)
|
||||
{
|
||||
var errorMessage = serverLocalisationService.GetText(
|
||||
"health-healing_item_not_found",
|
||||
request.Item
|
||||
);
|
||||
var errorMessage = serverLocalisationService.GetText("health-healing_item_not_found", request.Item);
|
||||
logger.Error(errorMessage);
|
||||
|
||||
return httpResponseUtil.AppendErrorToOutput(output, errorMessage);
|
||||
@@ -67,9 +58,7 @@ public class HealthController(
|
||||
else
|
||||
{
|
||||
// Get max healing from db
|
||||
var maxHp = itemHelper
|
||||
.GetItem(healingItemToUse.Template)
|
||||
.Value.Properties.MaxHpResource;
|
||||
var maxHp = itemHelper.GetItem(healingItemToUse.Template).Value.Properties.MaxHpResource;
|
||||
healingItemToUse.Upd.MedKit = new UpdMedKit { HpResource = maxHp - request.Count }; // Subtract amout used from max
|
||||
// request.count appears to take into account healing effects removed, e.g. bleeds
|
||||
// Salewa heals limb for 20 and fixes light bleed = (20+45 = 65)
|
||||
@@ -87,9 +76,7 @@ public class HealthController(
|
||||
var bodyPartToHeal = pmcData.Health.BodyParts.GetValueOrDefault(request.Part);
|
||||
if (bodyPartToHeal is null)
|
||||
{
|
||||
logger.Warning(
|
||||
$"Player: {sessionID} Tried to heal a non-existent body part: {request.Part}"
|
||||
);
|
||||
logger.Warning($"Player: {sessionID} Tried to heal a non-existent body part: {request.Part}");
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -112,12 +99,7 @@ public class HealthController(
|
||||
}
|
||||
|
||||
// Check if healing item removes the effect on limb
|
||||
if (
|
||||
!healItemEffectDetails.TryGetValue(
|
||||
effect,
|
||||
out var matchingEffectFromHealingItem
|
||||
)
|
||||
)
|
||||
if (!healItemEffectDetails.TryGetValue(effect, out var matchingEffectFromHealingItem))
|
||||
// Healing item doesn't have matching effect, it doesn't remove the effect
|
||||
{
|
||||
continue;
|
||||
@@ -149,11 +131,7 @@ public class HealthController(
|
||||
/// <param name="request">Eat request</param>
|
||||
/// <param name="sessionID">Session id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse OffRaidEat(
|
||||
PmcData pmcData,
|
||||
OffraidEatRequestData request,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse OffRaidEat(PmcData pmcData, OffraidEatRequestData request, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
var resourceLeft = 0d;
|
||||
@@ -164,16 +142,11 @@ public class HealthController(
|
||||
{
|
||||
return httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
serverLocalisationService.GetText(
|
||||
"health-unable_to_find_item_to_consume",
|
||||
request.Item
|
||||
)
|
||||
serverLocalisationService.GetText("health-unable_to_find_item_to_consume", request.Item)
|
||||
);
|
||||
}
|
||||
|
||||
var consumedItemMaxResource = itemHelper
|
||||
.GetItem(itemToConsume.Template)
|
||||
.Value.Properties.MaxResource;
|
||||
var consumedItemMaxResource = itemHelper.GetItem(itemToConsume.Template).Value.Properties.MaxResource;
|
||||
if (consumedItemMaxResource > 1)
|
||||
{
|
||||
// Ensure item has a upd object
|
||||
@@ -181,10 +154,7 @@ public class HealthController(
|
||||
|
||||
if (itemToConsume.Upd.FoodDrink is null)
|
||||
{
|
||||
itemToConsume.Upd.FoodDrink = new UpdFoodDrink
|
||||
{
|
||||
HpPercent = consumedItemMaxResource - request.Count,
|
||||
};
|
||||
itemToConsume.Upd.FoodDrink = new UpdFoodDrink { HpPercent = consumedItemMaxResource - request.Count };
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -210,21 +180,14 @@ public class HealthController(
|
||||
switch (key)
|
||||
{
|
||||
case HealthFactor.Hydration:
|
||||
ApplyEdibleEffect(
|
||||
pmcData.Health.Hydration,
|
||||
effectProps,
|
||||
foodIsSingleUse,
|
||||
request
|
||||
);
|
||||
ApplyEdibleEffect(pmcData.Health.Hydration, effectProps, foodIsSingleUse, request);
|
||||
break;
|
||||
case HealthFactor.Energy:
|
||||
ApplyEdibleEffect(pmcData.Health.Energy, effectProps, foodIsSingleUse, request);
|
||||
break;
|
||||
|
||||
default:
|
||||
logger.Warning(
|
||||
$"Unhandled effect after consuming: {itemToConsume.Template}, {key}"
|
||||
);
|
||||
logger.Warning($"Unhandled effect after consuming: {itemToConsume.Template}, {key}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -279,11 +242,7 @@ public class HealthController(
|
||||
/// <param name="healthTreatmentRequest">Request data from client</param>
|
||||
/// <param name="sessionID">Session id</param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse HealthTreatment(
|
||||
PmcData pmcData,
|
||||
HealthTreatmentRequestData healthTreatmentRequest,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse HealthTreatment(PmcData pmcData, HealthTreatmentRequestData healthTreatmentRequest, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
var payMoneyRequest = new ProcessBuyTradeRequestData
|
||||
|
||||
@@ -44,9 +44,7 @@ public class HideoutController(
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
public static readonly MongoId NameTaskConditionCountersCraftingId = new(
|
||||
"673f5d6fdd6ed700c703afdc"
|
||||
);
|
||||
public static readonly MongoId NameTaskConditionCountersCraftingId = new("673f5d6fdd6ed700c703afdc");
|
||||
|
||||
protected readonly FrozenSet<HideoutAreas> _areasWithResources =
|
||||
[
|
||||
@@ -66,19 +64,12 @@ public class HideoutController(
|
||||
/// <param name="request">Start upgrade request</param>
|
||||
/// <param name="sessionID">Session/player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void StartUpgrade(
|
||||
PmcData pmcData,
|
||||
HideoutUpgradeRequestData request,
|
||||
MongoId sessionID,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void StartUpgrade(PmcData pmcData, HideoutUpgradeRequestData request, MongoId sessionID, ItemEventRouterResponse output)
|
||||
{
|
||||
var items = request
|
||||
.Items.Select(reqItem =>
|
||||
{
|
||||
var item = pmcData.Inventory.Items.FirstOrDefault(invItem =>
|
||||
invItem.Id == reqItem.Id
|
||||
);
|
||||
var item = pmcData.Inventory.Items.FirstOrDefault(invItem => invItem.Id == reqItem.Id);
|
||||
return new { inventoryItem = item, requestedItem = reqItem };
|
||||
})
|
||||
.ToList();
|
||||
@@ -88,12 +79,7 @@ public class HideoutController(
|
||||
{
|
||||
if (item.inventoryItem is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_item_in_inventory",
|
||||
item.requestedItem.Id
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_item_in_inventory", item.requestedItem.Id));
|
||||
httpResponseUtil.AppendErrorToOutput(output);
|
||||
|
||||
return;
|
||||
@@ -115,38 +101,25 @@ public class HideoutController(
|
||||
}
|
||||
|
||||
// Construction time management
|
||||
var profileHideoutArea = pmcData.Hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == request.AreaType
|
||||
);
|
||||
var profileHideoutArea = pmcData.Hideout.Areas.FirstOrDefault(area => area.Type == request.AreaType);
|
||||
if (profileHideoutArea is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("hideout-unable_to_find_area", request.AreaType)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_area", request.AreaType));
|
||||
httpResponseUtil.AppendErrorToOutput(output);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var hideoutDataDb = databaseService
|
||||
.GetTables()
|
||||
.Hideout.Areas.FirstOrDefault(area => area.Type == request.AreaType);
|
||||
var hideoutDataDb = databaseService.GetTables().Hideout.Areas.FirstOrDefault(area => area.Type == request.AreaType);
|
||||
if (hideoutDataDb is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_area_in_database",
|
||||
request.AreaType
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_area_in_database", request.AreaType));
|
||||
httpResponseUtil.AppendErrorToOutput(output);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var ctime = hideoutDataDb
|
||||
.Stages[(profileHideoutArea.Level + 1).ToString()]
|
||||
.ConstructionTime;
|
||||
var ctime = hideoutDataDb.Stages[(profileHideoutArea.Level + 1).ToString()].ConstructionTime;
|
||||
if (ctime > 0)
|
||||
{
|
||||
if (profileHelper.IsDeveloperAccount(sessionID))
|
||||
@@ -179,14 +152,10 @@ public class HideoutController(
|
||||
var hideout = databaseService.GetHideout();
|
||||
var globals = databaseService.GetGlobals();
|
||||
|
||||
var profileHideoutArea = pmcData.Hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == request.AreaType
|
||||
);
|
||||
var profileHideoutArea = pmcData.Hideout.Areas.FirstOrDefault(area => area.Type == request.AreaType);
|
||||
if (profileHideoutArea is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("hideout-unable_to_find_area", request.AreaType)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_area", request.AreaType));
|
||||
httpResponseUtil.AppendErrorToOutput(output);
|
||||
|
||||
return;
|
||||
@@ -197,33 +166,19 @@ public class HideoutController(
|
||||
profileHideoutArea.CompleteTime = 0;
|
||||
profileHideoutArea.Constructing = false;
|
||||
|
||||
var hideoutData = hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == profileHideoutArea.Type
|
||||
);
|
||||
var hideoutData = hideout.Areas.FirstOrDefault(area => area.Type == profileHideoutArea.Type);
|
||||
if (hideoutData is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_area_in_database",
|
||||
request.AreaType
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_area_in_database", request.AreaType));
|
||||
httpResponseUtil.AppendErrorToOutput(output);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply bonuses
|
||||
if (
|
||||
!hideoutData.Stages.TryGetValue(
|
||||
profileHideoutArea.Level.ToString(),
|
||||
out var hideoutStage
|
||||
)
|
||||
)
|
||||
if (!hideoutData.Stages.TryGetValue(profileHideoutArea.Level.ToString(), out var hideoutStage))
|
||||
{
|
||||
logger.Error(
|
||||
$"Stage level: {profileHideoutArea.Level} not found for area: {request.AreaType}"
|
||||
);
|
||||
logger.Error($"Stage level: {profileHideoutArea.Level} not found for area: {request.AreaType}");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -239,21 +194,11 @@ public class HideoutController(
|
||||
// Upgrade includes a container improvement/addition
|
||||
if (!string.IsNullOrEmpty(hideoutStage.Container))
|
||||
{
|
||||
AddContainerImprovementToProfile(
|
||||
output,
|
||||
sessionID,
|
||||
pmcData,
|
||||
profileHideoutArea,
|
||||
hideoutData,
|
||||
hideoutStage
|
||||
);
|
||||
AddContainerImprovementToProfile(output, sessionID, pmcData, profileHideoutArea, hideoutData, hideoutStage);
|
||||
}
|
||||
|
||||
// Upgrading water collector / med station
|
||||
if (
|
||||
profileHideoutArea.Type == HideoutAreas.WaterCollector
|
||||
|| profileHideoutArea.Type == HideoutAreas.MedStation
|
||||
)
|
||||
if (profileHideoutArea.Type == HideoutAreas.WaterCollector || profileHideoutArea.Type == HideoutAreas.MedStation)
|
||||
{
|
||||
SetWallVisibleIfPrereqsMet(pmcData);
|
||||
}
|
||||
@@ -278,17 +223,11 @@ public class HideoutController(
|
||||
/// <param name="pmcData">Player profile</param>
|
||||
protected void SetWallVisibleIfPrereqsMet(PmcData pmcData)
|
||||
{
|
||||
var medStation = pmcData.Hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == HideoutAreas.MedStation
|
||||
);
|
||||
var waterCollector = pmcData.Hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == HideoutAreas.WaterCollector
|
||||
);
|
||||
var medStation = pmcData.Hideout.Areas.FirstOrDefault(area => area.Type == HideoutAreas.MedStation);
|
||||
var waterCollector = pmcData.Hideout.Areas.FirstOrDefault(area => area.Type == HideoutAreas.WaterCollector);
|
||||
if (medStation?.Level >= 1 && waterCollector?.Level >= 1)
|
||||
{
|
||||
var wall = pmcData.Hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == HideoutAreas.EmergencyWall
|
||||
);
|
||||
var wall = pmcData.Hideout.Areas.FirstOrDefault(area => area.Type == HideoutAreas.EmergencyWall);
|
||||
if (wall?.Level == 0)
|
||||
{
|
||||
wall.Level = 3;
|
||||
@@ -319,12 +258,7 @@ public class HideoutController(
|
||||
var keyForHideoutAreaStash = ((int)dbHideoutArea.Type).ToString();
|
||||
if (!pmcData.Inventory.HideoutAreaStashes.ContainsKey(keyForHideoutAreaStash))
|
||||
{
|
||||
if (
|
||||
!pmcData.Inventory.HideoutAreaStashes.TryAdd(
|
||||
keyForHideoutAreaStash,
|
||||
dbHideoutArea.Id
|
||||
)
|
||||
)
|
||||
if (!pmcData.Inventory.HideoutAreaStashes.TryAdd(keyForHideoutAreaStash, dbHideoutArea.Id))
|
||||
{
|
||||
logger.Error($"Unable to add key: {dbHideoutArea.Type} to HideoutAreaStashes");
|
||||
}
|
||||
@@ -337,27 +271,13 @@ public class HideoutController(
|
||||
if (dbHideoutArea.Type == HideoutAreas.EquipmentPresetsStand)
|
||||
// Can have multiple 'standx' children depending on upgrade level
|
||||
{
|
||||
AddMissingPresetStandItemsToProfile(
|
||||
sessionId,
|
||||
hideoutStage,
|
||||
pmcData,
|
||||
dbHideoutArea,
|
||||
output
|
||||
);
|
||||
AddMissingPresetStandItemsToProfile(sessionId, hideoutStage, pmcData, dbHideoutArea, output);
|
||||
}
|
||||
|
||||
AddContainerUpgradeToClientOutput(
|
||||
sessionId,
|
||||
keyForHideoutAreaStash,
|
||||
dbHideoutArea,
|
||||
hideoutStage,
|
||||
output
|
||||
);
|
||||
AddContainerUpgradeToClientOutput(sessionId, keyForHideoutAreaStash, dbHideoutArea, hideoutStage, output);
|
||||
|
||||
// Some hideout areas (Gun stand) have child areas linked to it
|
||||
var childDbArea = databaseService
|
||||
.GetHideout()
|
||||
.Areas.FirstOrDefault(area => area.ParentArea == dbHideoutArea.Id);
|
||||
var childDbArea = databaseService.GetHideout().Areas.FirstOrDefault(area => area.ParentArea == dbHideoutArea.Id);
|
||||
if (childDbArea is null)
|
||||
{
|
||||
// No child db area, we're complete
|
||||
@@ -372,23 +292,14 @@ public class HideoutController(
|
||||
}
|
||||
|
||||
// Set child area level to same as parent area
|
||||
pmcData
|
||||
.Hideout.Areas.FirstOrDefault(hideoutArea => hideoutArea.Type == childDbArea.Type)
|
||||
.Level = pmcData
|
||||
pmcData.Hideout.Areas.FirstOrDefault(hideoutArea => hideoutArea.Type == childDbArea.Type).Level = pmcData
|
||||
.Hideout.Areas.FirstOrDefault(area => area.Type == profileParentHideoutArea.Type)
|
||||
.Level;
|
||||
|
||||
// Add/upgrade stash item in player inventory
|
||||
if (
|
||||
!childDbArea.Stages.TryGetValue(
|
||||
profileParentHideoutArea.Level.ToString(),
|
||||
out var childDbAreaStage
|
||||
)
|
||||
)
|
||||
if (!childDbArea.Stages.TryGetValue(profileParentHideoutArea.Level.ToString(), out var childDbAreaStage))
|
||||
{
|
||||
logger.Error(
|
||||
$"Unable to find stage: {profileParentHideoutArea.Level} of area: {dbHideoutArea.Id}"
|
||||
);
|
||||
logger.Error($"Unable to find stage: {profileParentHideoutArea.Level} of area: {dbHideoutArea.Id}");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -396,13 +307,7 @@ public class HideoutController(
|
||||
AddUpdateInventoryItemToProfile(sessionId, pmcData, childDbArea, childDbAreaStage);
|
||||
|
||||
// Inform client of the changes
|
||||
AddContainerUpgradeToClientOutput(
|
||||
sessionId,
|
||||
childAreaTypeKey,
|
||||
childDbArea,
|
||||
childDbAreaStage,
|
||||
output
|
||||
);
|
||||
AddContainerUpgradeToClientOutput(sessionId, childAreaTypeKey, childDbArea, childDbAreaStage, output);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -412,16 +317,9 @@ public class HideoutController(
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <param name="dbHideoutArea">Hideout area from db being upgraded</param>
|
||||
/// <param name="hideoutStage">Stage area upgraded to</param>
|
||||
protected void AddUpdateInventoryItemToProfile(
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
HideoutArea dbHideoutArea,
|
||||
Stage hideoutStage
|
||||
)
|
||||
protected void AddUpdateInventoryItemToProfile(MongoId sessionId, PmcData pmcData, HideoutArea dbHideoutArea, Stage hideoutStage)
|
||||
{
|
||||
var existingInventoryItem = pmcData.Inventory.Items.FirstOrDefault(item =>
|
||||
item.Id == dbHideoutArea.Id
|
||||
);
|
||||
var existingInventoryItem = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == dbHideoutArea.Id);
|
||||
if (existingInventoryItem is not null)
|
||||
{
|
||||
// Update existing items container tpl to point to new id (tpl)
|
||||
@@ -431,11 +329,7 @@ public class HideoutController(
|
||||
}
|
||||
|
||||
// Add new item as none exists (don't inform client of newContainerItem, will be done in `profileChanges.changedHideoutStashes`)
|
||||
var newContainerItem = new Item
|
||||
{
|
||||
Id = dbHideoutArea.Id,
|
||||
Template = hideoutStage.Container.Value,
|
||||
};
|
||||
var newContainerItem = new Item { Id = dbHideoutArea.Id, Template = hideoutStage.Container.Value };
|
||||
pmcData.Inventory.Items.Add(newContainerItem);
|
||||
}
|
||||
|
||||
@@ -456,12 +350,14 @@ public class HideoutController(
|
||||
)
|
||||
{
|
||||
// Ensure ChangedHideoutStashes isn't null
|
||||
output.ProfileChanges[sessionId].ChangedHideoutStashes ??=
|
||||
new Dictionary<string, HideoutStashItem>();
|
||||
output.ProfileChanges[sessionId].ChangedHideoutStashes ??= new Dictionary<string, HideoutStashItem>();
|
||||
|
||||
// Inform client of changes
|
||||
output.ProfileChanges[sessionId].ChangedHideoutStashes[changedHideoutStashesKey] =
|
||||
new HideoutStashItem { Id = hideoutDbData.Id, Template = hideoutStage.Container };
|
||||
output.ProfileChanges[sessionId].ChangedHideoutStashes[changedHideoutStashesKey] = new HideoutStashItem
|
||||
{
|
||||
Id = hideoutDbData.Id,
|
||||
Template = hideoutStage.Container,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -482,9 +378,7 @@ public class HideoutController(
|
||||
|
||||
var itemsToAdd = addItemToHideoutRequest.Items.Select(kvp =>
|
||||
{
|
||||
var item = pmcData.Inventory.Items.FirstOrDefault(invItem =>
|
||||
invItem.Id == kvp.Value.Id
|
||||
);
|
||||
var item = pmcData.Inventory.Items.FirstOrDefault(invItem => invItem.Id == kvp.Value.Id);
|
||||
return new
|
||||
{
|
||||
inventoryItem = item,
|
||||
@@ -493,17 +387,10 @@ public class HideoutController(
|
||||
};
|
||||
});
|
||||
|
||||
var hideoutArea = pmcData.Hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == addItemToHideoutRequest.AreaType
|
||||
);
|
||||
var hideoutArea = pmcData.Hideout.Areas.FirstOrDefault(area => area.Type == addItemToHideoutRequest.AreaType);
|
||||
if (hideoutArea is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_area_in_database",
|
||||
addItemToHideoutRequest.AreaType
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_area_in_database", addItemToHideoutRequest.AreaType));
|
||||
return httpResponseUtil.AppendErrorToOutput(output);
|
||||
}
|
||||
|
||||
@@ -522,9 +409,7 @@ public class HideoutController(
|
||||
|
||||
// Add item to area.slots
|
||||
var destinationLocationIndex = int.Parse(item.slot);
|
||||
var hideoutSlotIndex = hideoutArea.Slots.FindIndex(slot =>
|
||||
slot.LocationIndex == destinationLocationIndex
|
||||
);
|
||||
var hideoutSlotIndex = hideoutArea.Slots.FindIndex(slot => slot.LocationIndex == destinationLocationIndex);
|
||||
if (hideoutSlotIndex == -1)
|
||||
{
|
||||
logger.Error(
|
||||
@@ -560,33 +445,20 @@ public class HideoutController(
|
||||
/// <param name="request">Take item out of area request</param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse TakeItemsFromAreaSlots(
|
||||
PmcData pmcData,
|
||||
HideoutTakeItemOutRequestData request,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse TakeItemsFromAreaSlots(PmcData pmcData, HideoutTakeItemOutRequestData request, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
|
||||
var hideoutArea = pmcData.Hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == request.AreaType
|
||||
);
|
||||
var hideoutArea = pmcData.Hideout.Areas.FirstOrDefault(area => area.Type == request.AreaType);
|
||||
if (hideoutArea is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("hideout-unable_to_find_area", request.AreaType)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_area", request.AreaType));
|
||||
return httpResponseUtil.AppendErrorToOutput(output);
|
||||
}
|
||||
|
||||
if (hideoutArea.Slots is null || hideoutArea.Slots.Count == 0)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_item_to_remove_from_area",
|
||||
hideoutArea.Type
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_item_to_remove_from_area", hideoutArea.Type));
|
||||
return httpResponseUtil.AppendErrorToOutput(output);
|
||||
}
|
||||
|
||||
@@ -600,12 +472,7 @@ public class HideoutController(
|
||||
return response;
|
||||
}
|
||||
|
||||
throw new Exception(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unhandled_remove_item_from_area_request",
|
||||
hideoutArea.Type
|
||||
)
|
||||
);
|
||||
throw new Exception(serverLocalisationService.GetText("hideout-unhandled_remove_item_from_area_request", hideoutArea.Type));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -636,9 +503,7 @@ public class HideoutController(
|
||||
}
|
||||
|
||||
// Assume only one item in slot
|
||||
var itemToReturn = hideoutArea
|
||||
.Slots?.FirstOrDefault(slot => slot.LocationIndex == slotIndexToRemove)
|
||||
?.Items?.FirstOrDefault();
|
||||
var itemToReturn = hideoutArea.Slots?.FirstOrDefault(slot => slot.LocationIndex == slotIndexToRemove)?.Items?.FirstOrDefault();
|
||||
if (itemToReturn is null)
|
||||
{
|
||||
logger.Error(
|
||||
@@ -665,9 +530,7 @@ public class HideoutController(
|
||||
}
|
||||
|
||||
// Remove items from slot, keep locationIndex object
|
||||
var hideoutSlotIndex = hideoutArea.Slots.FindIndex(slot =>
|
||||
slot.LocationIndex == slotIndexToRemove
|
||||
);
|
||||
var hideoutSlotIndex = hideoutArea.Slots.FindIndex(slot => slot.LocationIndex == slotIndexToRemove);
|
||||
hideoutArea.Slots[hideoutSlotIndex].Items = null;
|
||||
|
||||
return output;
|
||||
@@ -681,25 +544,17 @@ public class HideoutController(
|
||||
/// <param name="request">Toggle area request</param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse ToggleArea(
|
||||
PmcData pmcData,
|
||||
HideoutToggleAreaRequestData request,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse ToggleArea(PmcData pmcData, HideoutToggleAreaRequestData request, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
|
||||
// Force a production update (occur before area is toggled as it could be generator and doing it after generator enabled would cause incorrect calculaton of production progress)
|
||||
hideoutHelper.UpdatePlayerHideout(sessionID);
|
||||
|
||||
var hideoutArea = pmcData.Hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == request.AreaType
|
||||
);
|
||||
var hideoutArea = pmcData.Hideout.Areas.FirstOrDefault(area => area.Type == request.AreaType);
|
||||
if (hideoutArea is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("hideout-unable_to_find_area", request.AreaType)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_area", request.AreaType));
|
||||
return httpResponseUtil.AppendErrorToOutput(output);
|
||||
}
|
||||
|
||||
@@ -725,14 +580,10 @@ public class HideoutController(
|
||||
hideoutHelper.RegisterProduction(pmcData, request, sessionID);
|
||||
|
||||
// Find the recipe of the production
|
||||
var recipe = databaseService
|
||||
.GetHideout()
|
||||
.Production.Recipes.FirstOrDefault(production => production.Id == request.RecipeId);
|
||||
var recipe = databaseService.GetHideout().Production.Recipes.FirstOrDefault(production => production.Id == request.RecipeId);
|
||||
|
||||
// Find the actual amount of items we need to remove because body can send weird data
|
||||
var recipeRequirementsClone = cloner.Clone(
|
||||
recipe.Requirements.Where(r => r.Type == "Item" || r.Type == "Tool")
|
||||
);
|
||||
var recipeRequirementsClone = cloner.Clone(recipe.Requirements.Where(r => r.Type == "Item" || r.Type == "Tool"));
|
||||
|
||||
List<IdWithCount> itemsToDelete = [];
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
@@ -742,9 +593,7 @@ public class HideoutController(
|
||||
foreach (var itemToDelete in itemsToDelete)
|
||||
{
|
||||
var itemToCheck = pmcData.Inventory.Items.FirstOrDefault(i => i.Id == itemToDelete.Id);
|
||||
var requirement = recipeRequirementsClone.FirstOrDefault(requirement =>
|
||||
requirement.TemplateId == itemToCheck.Template
|
||||
);
|
||||
var requirement = recipeRequirementsClone.FirstOrDefault(requirement => requirement.TemplateId == itemToCheck.Template);
|
||||
|
||||
// Handle tools not having a `count`, but always only requiring 1
|
||||
var requiredCount = requirement.Count ?? 1;
|
||||
@@ -753,13 +602,7 @@ public class HideoutController(
|
||||
continue;
|
||||
}
|
||||
|
||||
inventoryHelper.RemoveItemByCount(
|
||||
pmcData,
|
||||
itemToDelete.Id,
|
||||
requiredCount,
|
||||
sessionID,
|
||||
output
|
||||
);
|
||||
inventoryHelper.RemoveItemByCount(pmcData, itemToDelete.Id, requiredCount, sessionID, output);
|
||||
|
||||
// Tools don't have a count
|
||||
if (requirement.Type != "Tool")
|
||||
@@ -779,19 +622,13 @@ public class HideoutController(
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse ScavCaseProductionStart(
|
||||
PmcData pmcData,
|
||||
HideoutScavCaseStartRequestData request,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse ScavCaseProductionStart(PmcData pmcData, HideoutScavCaseStartRequestData request, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
|
||||
foreach (var requestedItem in request.Items)
|
||||
{
|
||||
var inventoryItem = pmcData.Inventory.Items.FirstOrDefault(item =>
|
||||
item.Id == requestedItem.Id
|
||||
);
|
||||
var inventoryItem = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == requestedItem.Id);
|
||||
if (inventoryItem is null)
|
||||
{
|
||||
logger.Error(
|
||||
@@ -803,10 +640,7 @@ public class HideoutController(
|
||||
return httpResponseUtil.AppendErrorToOutput(output);
|
||||
}
|
||||
|
||||
if (
|
||||
inventoryItem.Upd?.StackObjectsCount is not null
|
||||
&& inventoryItem.Upd.StackObjectsCount > requestedItem.Count
|
||||
)
|
||||
if (inventoryItem.Upd?.StackObjectsCount is not null && inventoryItem.Upd.StackObjectsCount > requestedItem.Count)
|
||||
{
|
||||
inventoryItem.Upd.StackObjectsCount -= requestedItem.Count;
|
||||
}
|
||||
@@ -816,17 +650,10 @@ public class HideoutController(
|
||||
}
|
||||
}
|
||||
|
||||
var recipe = databaseService
|
||||
.GetHideout()
|
||||
.Production?.ScavRecipes?.FirstOrDefault(r => r.Id == request.RecipeId);
|
||||
var recipe = databaseService.GetHideout().Production?.ScavRecipes?.FirstOrDefault(r => r.Id == request.RecipeId);
|
||||
if (recipe is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_scav_case_recipie_in_database",
|
||||
request.RecipeId
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_scav_case_recipie_in_database", request.RecipeId));
|
||||
|
||||
return httpResponseUtil.AppendErrorToOutput(output);
|
||||
}
|
||||
@@ -840,9 +667,7 @@ public class HideoutController(
|
||||
pmcData,
|
||||
recipe.ProductionTime ?? 0,
|
||||
SkillTypes.Crafting,
|
||||
databaseService
|
||||
.GetGlobals()
|
||||
.Configuration.SkillsSettings.Crafting.CraftTimeReductionPerLevel
|
||||
databaseService.GetGlobals().Configuration.SkillsSettings.Crafting.CraftTimeReductionPerLevel
|
||||
);
|
||||
|
||||
var modifiedScavCaseTime = GetScavCaseTime(pmcData, adjustedCraftTime);
|
||||
@@ -900,11 +725,7 @@ public class HideoutController(
|
||||
/// <param name="request">Remove production from area request</param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse TakeProduction(
|
||||
PmcData pmcData,
|
||||
HideoutTakeProductionRequestData request,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse TakeProduction(PmcData pmcData, HideoutTakeProductionRequestData request, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
var hideoutDb = databaseService.GetHideout();
|
||||
@@ -926,9 +747,7 @@ public class HideoutController(
|
||||
return output;
|
||||
}
|
||||
|
||||
var scavCase = hideoutDb.Production.ScavRecipes.FirstOrDefault(r =>
|
||||
r.Id == request.RecipeId
|
||||
);
|
||||
var scavCase = hideoutDb.Production.ScavRecipes.FirstOrDefault(r => r.Id == request.RecipeId);
|
||||
if (scavCase is not null)
|
||||
{
|
||||
HandleScavCase(sessionID, pmcData, request, output);
|
||||
@@ -936,12 +755,7 @@ public class HideoutController(
|
||||
return output;
|
||||
}
|
||||
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_production_in_profile_by_recipie_id",
|
||||
request.RecipeId
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_production_in_profile_by_recipie_id", request.RecipeId));
|
||||
|
||||
return httpResponseUtil.AppendErrorToOutput(output);
|
||||
}
|
||||
@@ -986,19 +800,11 @@ public class HideoutController(
|
||||
// If we're unable to find the production, send an error to the client
|
||||
if (prodId is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_production_in_profile_by_recipie_id",
|
||||
request.RecipeId
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_production_in_profile_by_recipie_id", request.RecipeId));
|
||||
|
||||
httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_production_in_profile_by_recipie_id",
|
||||
request.RecipeId
|
||||
)
|
||||
serverLocalisationService.GetText("hideout-unable_to_find_production_in_profile_by_recipie_id", request.RecipeId)
|
||||
);
|
||||
|
||||
return;
|
||||
@@ -1029,10 +835,7 @@ public class HideoutController(
|
||||
{
|
||||
itemHelper.AddUpdObjectToItem(reward.FirstOrDefault());
|
||||
|
||||
reward.FirstOrDefault().Upd.RecodableComponent = new UpdRecodableComponent
|
||||
{
|
||||
IsEncoded = true,
|
||||
};
|
||||
reward.FirstOrDefault().Upd.RecodableComponent = new UpdRecodableComponent { IsEncoded = true };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1061,9 +864,7 @@ public class HideoutController(
|
||||
if (totalCraftingHours / _hideoutConfig.HoursForSkillCrafting >= 1)
|
||||
{
|
||||
// Spent enough time crafting to get a bonus xp multiplier
|
||||
var multiplierCrafting = Math.Floor(
|
||||
totalCraftingHours.Value / _hideoutConfig.HoursForSkillCrafting
|
||||
);
|
||||
var multiplierCrafting = Math.Floor(totalCraftingHours.Value / _hideoutConfig.HoursForSkillCrafting);
|
||||
craftingExpAmount += (int)(1 * multiplierCrafting);
|
||||
totalCraftingHours -= _hideoutConfig.HoursForSkillCrafting * multiplierCrafting;
|
||||
}
|
||||
@@ -1136,11 +937,7 @@ public class HideoutController(
|
||||
var intellectAmountToGive = 0.5 * Math.Round((double)(craftingExpAmount / 15));
|
||||
if (intellectAmountToGive > 0)
|
||||
{
|
||||
profileHelper.AddSkillPointsToPlayer(
|
||||
pmcData,
|
||||
SkillTypes.Intellect,
|
||||
intellectAmountToGive
|
||||
);
|
||||
profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.Intellect, intellectAmountToGive);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1157,11 +954,7 @@ public class HideoutController(
|
||||
// production.json is set to
|
||||
if (recipe.Continuous.GetValueOrDefault(false))
|
||||
{
|
||||
hideoutProduction.ProductionTime = hideoutHelper.GetAdjustedCraftTimeWithSkills(
|
||||
pmcData,
|
||||
recipe.Id,
|
||||
true
|
||||
);
|
||||
hideoutProduction.ProductionTime = hideoutHelper.GetAdjustedCraftTimeWithSkills(pmcData, recipe.Id, true);
|
||||
}
|
||||
|
||||
// Flag normal (not continuous) crafts as complete
|
||||
@@ -1177,11 +970,7 @@ public class HideoutController(
|
||||
/// <param name="recipe"></param>
|
||||
/// <param name="itemAndChildrenToSendToPlayer"></param>
|
||||
/// <param name="rewardIsPreset">Reward is a preset</param>
|
||||
protected void HandleStackableState(
|
||||
HideoutProduction recipe,
|
||||
List<List<Item>> itemAndChildrenToSendToPlayer,
|
||||
bool rewardIsPreset
|
||||
)
|
||||
protected void HandleStackableState(HideoutProduction recipe, List<List<Item>> itemAndChildrenToSendToPlayer, bool rewardIsPreset)
|
||||
{
|
||||
var rewardIsStackable = itemHelper.IsItemTplStackable(recipe.EndProduct);
|
||||
if (rewardIsStackable.GetValueOrDefault(false))
|
||||
@@ -1206,9 +995,7 @@ public class HideoutController(
|
||||
// Add the first reward item to array when not a preset (first preset added above earlier)
|
||||
if (!rewardIsPreset)
|
||||
{
|
||||
itemAndChildrenToSendToPlayer.Add(
|
||||
[new Item { Id = new MongoId(), Template = recipe.EndProduct }]
|
||||
);
|
||||
itemAndChildrenToSendToPlayer.Add([new Item { Id = new MongoId(), Template = recipe.EndProduct }]);
|
||||
}
|
||||
|
||||
// Add multiple of item if recipe requests it
|
||||
@@ -1216,10 +1003,7 @@ public class HideoutController(
|
||||
var countOfItemsToReward = recipe.Count;
|
||||
for (var index = 1; index < countOfItemsToReward; index++)
|
||||
{
|
||||
var firstItemWithChildrenClone = cloner
|
||||
.Clone(itemAndChildrenToSendToPlayer.FirstOrDefault())
|
||||
.ReplaceIDs()
|
||||
.ToList();
|
||||
var firstItemWithChildrenClone = cloner.Clone(itemAndChildrenToSendToPlayer.FirstOrDefault()).ReplaceIDs().ToList();
|
||||
|
||||
itemAndChildrenToSendToPlayer.AddRange([firstItemWithChildrenClone]);
|
||||
}
|
||||
@@ -1249,10 +1033,7 @@ public class HideoutController(
|
||||
/// <param name="pmcData">Profile to get counter from</param>
|
||||
/// <param name="recipe">Recipe being crafted</param>
|
||||
/// <returns>TaskConditionCounter</returns>
|
||||
protected TaskConditionCounter GetCustomSptHoursCraftingTaskConditionCounter(
|
||||
PmcData pmcData,
|
||||
HideoutProduction recipe
|
||||
)
|
||||
protected TaskConditionCounter GetCustomSptHoursCraftingTaskConditionCounter(PmcData pmcData, HideoutProduction recipe)
|
||||
{
|
||||
// Add if doesn't exist
|
||||
pmcData.TaskConditionCounters.TryAdd(
|
||||
@@ -1297,12 +1078,7 @@ public class HideoutController(
|
||||
|
||||
if (prodId == null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_production_in_profile_by_recipie_id",
|
||||
request.RecipeId
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_production_in_profile_by_recipie_id", request.RecipeId));
|
||||
|
||||
httpResponseUtil.AppendErrorToOutput(output);
|
||||
|
||||
@@ -1344,12 +1120,7 @@ public class HideoutController(
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <param name="request">QTE result object</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void HandleQTEEventOutcome(
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
HandleQTEEventRequestData request,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void HandleQTEEventOutcome(MongoId sessionId, PmcData pmcData, HandleQTEEventRequestData request, ItemEventRouterResponse output)
|
||||
{
|
||||
// {
|
||||
// "Action": "HideoutQuickTimeEvent",
|
||||
@@ -1368,22 +1139,14 @@ public class HideoutController(
|
||||
if (outcome)
|
||||
{
|
||||
// Success
|
||||
pmcData.Health.Energy.Current += relevantQte
|
||||
.Results[QteEffectType.singleSuccessEffect]
|
||||
.Energy;
|
||||
pmcData.Health.Hydration.Current += relevantQte
|
||||
.Results[QteEffectType.singleSuccessEffect]
|
||||
.Hydration;
|
||||
pmcData.Health.Energy.Current += relevantQte.Results[QteEffectType.singleSuccessEffect].Energy;
|
||||
pmcData.Health.Hydration.Current += relevantQte.Results[QteEffectType.singleSuccessEffect].Hydration;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed
|
||||
pmcData.Health.Energy.Current += relevantQte
|
||||
.Results[QteEffectType.singleFailEffect]
|
||||
.Energy;
|
||||
pmcData.Health.Hydration.Current += relevantQte
|
||||
.Results[QteEffectType.singleFailEffect]
|
||||
.Hydration;
|
||||
pmcData.Health.Energy.Current += relevantQte.Results[QteEffectType.singleFailEffect].Energy;
|
||||
pmcData.Health.Hydration.Current += relevantQte.Results[QteEffectType.singleFailEffect].Hydration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1408,21 +1171,17 @@ public class HideoutController(
|
||||
protected void HandleMusclePain(PmcData pmcData, QteResult finishEffect)
|
||||
{
|
||||
var hasMildPain = pmcData.Health.BodyParts["Chest"].Effects?.ContainsKey("MildMusclePain");
|
||||
var hasSeverePain = pmcData
|
||||
.Health.BodyParts["Chest"]
|
||||
.Effects?.ContainsKey("SevereMusclePain");
|
||||
var hasSeverePain = pmcData.Health.BodyParts["Chest"].Effects?.ContainsKey("SevereMusclePain");
|
||||
|
||||
// Has no muscle pain at all, add mild
|
||||
if (!hasMildPain.GetValueOrDefault(false) && !hasSeverePain.GetValueOrDefault(false))
|
||||
{
|
||||
// Nullguard
|
||||
pmcData.Health.BodyParts["Chest"].Effects ??=
|
||||
new Dictionary<string, BodyPartEffectProperties>();
|
||||
pmcData.Health.BodyParts["Chest"].Effects["MildMusclePain"] =
|
||||
new BodyPartEffectProperties
|
||||
{
|
||||
Time = finishEffect.RewardEffects.FirstOrDefault().Time, // TODO - remove hard coded access, get value properly
|
||||
};
|
||||
pmcData.Health.BodyParts["Chest"].Effects ??= new Dictionary<string, BodyPartEffectProperties>();
|
||||
pmcData.Health.BodyParts["Chest"].Effects["MildMusclePain"] = new BodyPartEffectProperties
|
||||
{
|
||||
Time = finishEffect.RewardEffects.FirstOrDefault().Time, // TODO - remove hard coded access, get value properly
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1432,11 +1191,10 @@ public class HideoutController(
|
||||
// Already has mild pain, remove mild and add severe
|
||||
pmcData.Health.BodyParts["Chest"].Effects.Remove("MildMusclePain");
|
||||
|
||||
pmcData.Health.BodyParts["Chest"].Effects["SevereMusclePain"] =
|
||||
new BodyPartEffectProperties
|
||||
{
|
||||
Time = finishEffect.RewardEffects.FirstOrDefault().Time,
|
||||
};
|
||||
pmcData.Health.BodyParts["Chest"].Effects["SevereMusclePain"] = new BodyPartEffectProperties
|
||||
{
|
||||
Time = finishEffect.RewardEffects.FirstOrDefault().Time,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1446,26 +1204,18 @@ public class HideoutController(
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <param name="request">shooting range score request></param>
|
||||
public void RecordShootingRangePoints(
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
RecordShootingRangePoints request
|
||||
)
|
||||
public void RecordShootingRangePoints(MongoId sessionId, PmcData pmcData, RecordShootingRangePoints request)
|
||||
{
|
||||
const string shootingRangeKey = "ShootingRangePoints";
|
||||
var overallCounterItems = pmcData.Stats.Eft.OverallCounters.Items;
|
||||
|
||||
// Find counter by key
|
||||
var shootingRangeHighScore = overallCounterItems.FirstOrDefault(counter =>
|
||||
counter.Key.Contains(shootingRangeKey)
|
||||
);
|
||||
var shootingRangeHighScore = overallCounterItems.FirstOrDefault(counter => counter.Key.Contains(shootingRangeKey));
|
||||
if (shootingRangeHighScore is null)
|
||||
{
|
||||
// Counter not found, add blank one
|
||||
overallCounterItems.Add(new CounterKeyValue { Key = [shootingRangeKey], Value = 0 });
|
||||
shootingRangeHighScore = overallCounterItems.FirstOrDefault(counter =>
|
||||
counter.Key.Contains(shootingRangeKey)
|
||||
);
|
||||
shootingRangeHighScore = overallCounterItems.FirstOrDefault(counter => counter.Key.Contains(shootingRangeKey));
|
||||
}
|
||||
|
||||
shootingRangeHighScore.Value = request.Points;
|
||||
@@ -1478,11 +1228,7 @@ public class HideoutController(
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <param name="request">Improve area request</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse ImproveArea(
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
HideoutImproveAreaRequestData request
|
||||
)
|
||||
public ItemEventRouterResponse ImproveArea(MongoId sessionId, PmcData pmcData, HideoutImproveAreaRequestData request)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionId);
|
||||
|
||||
@@ -1498,12 +1244,7 @@ public class HideoutController(
|
||||
{
|
||||
if (item.inventoryItem is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_item_in_inventory",
|
||||
item.requestedItem.Id
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_item_in_inventory", item.requestedItem.Id));
|
||||
return httpResponseUtil.AppendErrorToOutput(output);
|
||||
}
|
||||
|
||||
@@ -1522,28 +1263,17 @@ public class HideoutController(
|
||||
}
|
||||
}
|
||||
|
||||
var profileHideoutArea = pmcData.Hideout.Areas.FirstOrDefault(x =>
|
||||
x.Type == request.AreaType
|
||||
);
|
||||
var profileHideoutArea = pmcData.Hideout.Areas.FirstOrDefault(x => x.Type == request.AreaType);
|
||||
if (profileHideoutArea is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("hideout-unable_to_find_area", request.AreaType)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_area", request.AreaType));
|
||||
return httpResponseUtil.AppendErrorToOutput(output);
|
||||
}
|
||||
|
||||
var hideoutDbData = databaseService
|
||||
.GetHideout()
|
||||
.Areas.FirstOrDefault(area => area.Type == request.AreaType);
|
||||
var hideoutDbData = databaseService.GetHideout().Areas.FirstOrDefault(area => area.Type == request.AreaType);
|
||||
if (hideoutDbData is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"hideout-unable_to_find_area_in_database",
|
||||
request.AreaType
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("hideout-unable_to_find_area_in_database", request.AreaType));
|
||||
return httpResponseUtil.AppendErrorToOutput(output);
|
||||
}
|
||||
|
||||
@@ -1577,11 +1307,7 @@ public class HideoutController(
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <param name="request">Cancel production request data</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse CancelProduction(
|
||||
MongoId sessionId,
|
||||
PmcData pmcData,
|
||||
HideoutCancelProductionRequestData request
|
||||
)
|
||||
public ItemEventRouterResponse CancelProduction(MongoId sessionId, PmcData pmcData, HideoutCancelProductionRequestData request)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionId);
|
||||
|
||||
@@ -1647,21 +1373,15 @@ public class HideoutController(
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionId);
|
||||
|
||||
var itemDetails = databaseService
|
||||
.GetHideout()
|
||||
.Customisation.Globals.FirstOrDefault(cust => cust.Id == request.OfferId);
|
||||
var itemDetails = databaseService.GetHideout().Customisation.Globals.FirstOrDefault(cust => cust.Id == request.OfferId);
|
||||
if (itemDetails is null)
|
||||
{
|
||||
logger.Error(
|
||||
$"Unable to find customisation: {request.OfferId} in db, cannot apply to hideout"
|
||||
);
|
||||
logger.Error($"Unable to find customisation: {request.OfferId} in db, cannot apply to hideout");
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
pmcData.Hideout.Customization[GetHideoutCustomisationType(itemDetails.Type)] = itemDetails
|
||||
.ItemId
|
||||
.Value;
|
||||
pmcData.Hideout.Customization[GetHideoutCustomisationType(itemDetails.Type)] = itemDetails.ItemId.Value;
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -1734,9 +1454,7 @@ public class HideoutController(
|
||||
{
|
||||
Id = new MongoId(),
|
||||
Template = pmcData
|
||||
.Inventory.Items.FirstOrDefault(item =>
|
||||
item.SlotId == "Pockets" && item.ParentId == pmcData.Inventory.Equipment
|
||||
)
|
||||
.Inventory.Items.FirstOrDefault(item => item.SlotId == "Pockets" && item.ParentId == pmcData.Inventory.Equipment)
|
||||
.Template, // Same pocket tpl as players profile (unheard get bigger, matching pockets etc)
|
||||
ParentId = standId,
|
||||
SlotId = "Pockets",
|
||||
@@ -1763,9 +1481,7 @@ public class HideoutController(
|
||||
{
|
||||
if (request.Poses is null)
|
||||
{
|
||||
logger.Warning(
|
||||
"this really shouldnt be possible, but a request has come in with a pose change without poses"
|
||||
);
|
||||
logger.Warning("this really shouldnt be possible, but a request has come in with a pose change without poses");
|
||||
return eventOutputHolder.GetOutput(sessionId);
|
||||
}
|
||||
|
||||
@@ -1800,10 +1516,7 @@ public class HideoutController(
|
||||
{
|
||||
if (
|
||||
profile.CharacterData.PmcData.Hideout is not null
|
||||
&& profileActivityService.ActiveWithinLastMinutes(
|
||||
sessionId,
|
||||
_hideoutConfig.UpdateProfileHideoutWhenActiveWithinMinutes
|
||||
)
|
||||
&& profileActivityService.ActiveWithinLastMinutes(sessionId, _hideoutConfig.UpdateProfileHideoutWhenActiveWithinMinutes)
|
||||
)
|
||||
{
|
||||
hideoutHelper.UpdatePlayerHideout(sessionId);
|
||||
|
||||
@@ -36,10 +36,7 @@ public class InRaidController(
|
||||
/// </summary>
|
||||
/// <param name="offRaidProfileData"></param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
public void SavePostRaidProfileForScav(
|
||||
ScavSaveRequestData offRaidProfileData,
|
||||
MongoId sessionId
|
||||
)
|
||||
public void SavePostRaidProfileForScav(ScavSaveRequestData offRaidProfileData, MongoId sessionId)
|
||||
{
|
||||
var serverScavProfile = profileHelper.GetScavProfile(sessionId);
|
||||
|
||||
|
||||
@@ -90,9 +90,7 @@ public class InsuranceController(
|
||||
{
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug(
|
||||
$"Found {profileInsuranceDetails.Count} insurance packages in profile {sessionId}"
|
||||
);
|
||||
logger.Debug($"Found {profileInsuranceDetails.Count} insurance packages in profile {sessionId}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,9 +169,7 @@ public class InsuranceController(
|
||||
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug(
|
||||
$"Removed processed insurance package. Remaining packages: {profile.InsuranceList.Count}"
|
||||
);
|
||||
logger.Debug($"Removed processed insurance package. Remaining packages: {profile.InsuranceList.Count}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,11 +186,7 @@ public class InsuranceController(
|
||||
// Populate a Map object of items for quick lookup by their ID and use it to populate a Map of main-parent items
|
||||
// and each of their attachments. For example, a gun mapped to each of its attachments.
|
||||
var itemsMap = insured.Items.GenerateItemsMap();
|
||||
var parentAttachmentsMap = PopulateParentAttachmentsMap(
|
||||
rootItemParentId,
|
||||
insured,
|
||||
itemsMap
|
||||
);
|
||||
var parentAttachmentsMap = PopulateParentAttachmentsMap(rootItemParentId, insured, itemsMap);
|
||||
|
||||
// Check to see if any regular items are present.
|
||||
var hasRegularItems = itemsMap.Values.Any(item => !itemHelper.IsAttachmentAttached(item));
|
||||
@@ -278,11 +270,7 @@ public class InsuranceController(
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"insurance-unable_to_find_attachment_in_db",
|
||||
new
|
||||
{
|
||||
insuredItemId = insuredItem.Id,
|
||||
insuredItemTpl = insuredItem.Template,
|
||||
}
|
||||
new { insuredItemId = insuredItem.Id, insuredItemTpl = insuredItem.Template }
|
||||
)
|
||||
);
|
||||
|
||||
@@ -384,11 +372,7 @@ public class InsuranceController(
|
||||
/// <param name="insured">Insurance object containing the items to evaluate</param>
|
||||
/// <param name="toDelete">Hashset to keep track of items marked for deletion</param>
|
||||
/// <param name="parentAttachmentsMap">Dictionary containing parent item IDs to arrays of their attachment items</param>
|
||||
protected void ProcessRegularItems(
|
||||
Insurance insured,
|
||||
HashSet<MongoId> toDelete,
|
||||
Dictionary<MongoId, List<Item>> parentAttachmentsMap
|
||||
)
|
||||
protected void ProcessRegularItems(Insurance insured, HashSet<MongoId> toDelete, Dictionary<MongoId, List<Item>> parentAttachmentsMap)
|
||||
{
|
||||
foreach (var insuredItem in insured.Items)
|
||||
{
|
||||
@@ -471,35 +455,23 @@ public class InsuranceController(
|
||||
/// <param name="attachments">Array of attachment items to sort, filter, and roll</param>
|
||||
/// <param name="traderId">ID of the trader to that has ensured these items</param>
|
||||
/// <param name="toDelete">array that accumulates the IDs of the items to be deleted</param>
|
||||
protected void ProcessAttachmentByParent(
|
||||
IEnumerable<Item> attachments,
|
||||
MongoId traderId,
|
||||
HashSet<MongoId> toDelete
|
||||
)
|
||||
protected void ProcessAttachmentByParent(IEnumerable<Item> attachments, MongoId traderId, HashSet<MongoId> toDelete)
|
||||
{
|
||||
// Create dict of item ids + their flea/handbook price (highest is chosen)
|
||||
var weightedAttachmentByPrice = WeightAttachmentsByPrice(attachments);
|
||||
|
||||
// Get how many attachments we want to pull off parent
|
||||
var countOfAttachmentsToRemove = GetAttachmentCountToRemove(
|
||||
weightedAttachmentByPrice,
|
||||
traderId
|
||||
);
|
||||
var countOfAttachmentsToRemove = GetAttachmentCountToRemove(weightedAttachmentByPrice, traderId);
|
||||
|
||||
// Create prob array and add all attachments with rouble price as the weight
|
||||
var attachmentsProbabilityArray = new ProbabilityObjectArray<MongoId, double?>(cloner);
|
||||
foreach (var (itemTpl, price) in weightedAttachmentByPrice)
|
||||
{
|
||||
attachmentsProbabilityArray.Add(
|
||||
new ProbabilityObject<MongoId, double?>(itemTpl, price, null)
|
||||
);
|
||||
attachmentsProbabilityArray.Add(new ProbabilityObject<MongoId, double?>(itemTpl, price, null));
|
||||
}
|
||||
|
||||
// Draw x attachments from weighted array to remove from parent, remove from pool after being picked
|
||||
var attachmentIdsToRemove = attachmentsProbabilityArray.Draw(
|
||||
(int)countOfAttachmentsToRemove,
|
||||
false
|
||||
);
|
||||
var attachmentIdsToRemove = attachmentsProbabilityArray.Draw((int)countOfAttachmentsToRemove, false);
|
||||
foreach (var attachmentId in attachmentIdsToRemove)
|
||||
{
|
||||
toDelete.Add(attachmentId);
|
||||
@@ -570,10 +542,7 @@ public class InsuranceController(
|
||||
/// <param name="weightedAttachmentByPrice">Dict of item Tpls and their rouble price</param>
|
||||
/// <param name="traderId">Trader the attachment is insured against</param>
|
||||
/// <returns>Attachment count to remove</returns>
|
||||
protected double GetAttachmentCountToRemove(
|
||||
Dictionary<MongoId, double> weightedAttachmentByPrice,
|
||||
MongoId traderId
|
||||
)
|
||||
protected double GetAttachmentCountToRemove(Dictionary<MongoId, double> weightedAttachmentByPrice, MongoId traderId)
|
||||
{
|
||||
const int removeCount = 0;
|
||||
|
||||
@@ -584,9 +553,7 @@ public class InsuranceController(
|
||||
|
||||
// Get attachments count above or equal to price set in config
|
||||
return weightedAttachmentByPrice
|
||||
.Where(attachment =>
|
||||
attachment.Value >= _insuranceConfig.MinAttachmentRoublePriceToBeTaken
|
||||
)
|
||||
.Where(attachment => attachment.Value >= _insuranceConfig.MinAttachmentRoublePriceToBeTaken)
|
||||
.Count(_ => RollForDelete(traderId) ?? false);
|
||||
}
|
||||
|
||||
@@ -625,12 +592,7 @@ public class InsuranceController(
|
||||
else if (insurance.Items?.Count == 0)
|
||||
// Not labs and no items to return
|
||||
{
|
||||
if (
|
||||
traderDialogMessages.TryGetValue(
|
||||
"insuranceFailed",
|
||||
out var insuranceFailedTemplates
|
||||
)
|
||||
)
|
||||
if (traderDialogMessages.TryGetValue("insuranceFailed", out var insuranceFailedTemplates))
|
||||
{
|
||||
insurance.MessageTemplateId = randomUtil.GetArrayValue(insuranceFailedTemplates);
|
||||
}
|
||||
@@ -656,11 +618,8 @@ public class InsuranceController(
|
||||
/// <returns></returns>
|
||||
protected bool IsMapLabsAndInsuranceDisabled(Insurance insurance, string labsId = "laboratory")
|
||||
{
|
||||
return string.Equals(
|
||||
insurance.SystemData?.Location,
|
||||
labsId,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
) && !(databaseService.GetLocation(labsId)?.Base?.Insurance ?? false);
|
||||
return string.Equals(insurance.SystemData?.Location, labsId, StringComparison.OrdinalIgnoreCase)
|
||||
&& !(databaseService.GetLocation(labsId)?.Base?.Insurance ?? false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -669,16 +628,10 @@ public class InsuranceController(
|
||||
/// <param name="insurance">The insured items to process</param>
|
||||
/// <param name="labyrinthId">OPTIONAL - id of labyrinth location</param>
|
||||
/// <returns></returns>
|
||||
protected bool IsMapLabyrinthAndInsuranceDisabled(
|
||||
Insurance insurance,
|
||||
string labyrinthId = "labyrinth"
|
||||
)
|
||||
protected bool IsMapLabyrinthAndInsuranceDisabled(Insurance insurance, string labyrinthId = "labyrinth")
|
||||
{
|
||||
return string.Equals(
|
||||
insurance.SystemData?.Location,
|
||||
labyrinthId,
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
) && !(databaseService.GetLocation(labyrinthId)?.Base?.Insurance ?? false);
|
||||
return string.Equals(insurance.SystemData?.Location, labyrinthId, StringComparison.OrdinalIgnoreCase)
|
||||
&& !(databaseService.GetLocation(labyrinthId)?.Base?.Insurance ?? false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -686,10 +639,7 @@ public class InsuranceController(
|
||||
/// </summary>
|
||||
/// <param name="traderDialogMessages"></param>
|
||||
/// <param name="insurance"></param>
|
||||
protected void HandleLabsInsurance(
|
||||
Dictionary<string, List<string>?> traderDialogMessages,
|
||||
Insurance insurance
|
||||
)
|
||||
protected void HandleLabsInsurance(Dictionary<string, List<string>?> traderDialogMessages, Insurance insurance)
|
||||
{
|
||||
// Use labs specific messages if available, otherwise use default
|
||||
if (!traderDialogMessages.TryGetValue("insuranceFailedLabs", out var responseMessageIds))
|
||||
@@ -708,17 +658,9 @@ public class InsuranceController(
|
||||
/// </summary>
|
||||
/// <param name="traderDialogMessages"></param>
|
||||
/// <param name="insurance"></param>
|
||||
protected void HandleLabyrinthInsurance(
|
||||
Dictionary<string, List<string>?> traderDialogMessages,
|
||||
Insurance insurance
|
||||
)
|
||||
protected void HandleLabyrinthInsurance(Dictionary<string, List<string>?> traderDialogMessages, Insurance insurance)
|
||||
{
|
||||
if (
|
||||
!traderDialogMessages.TryGetValue(
|
||||
"insuranceFailedLabyrinth",
|
||||
out var responseMessageIds
|
||||
)
|
||||
)
|
||||
if (!traderDialogMessages.TryGetValue("insuranceFailedLabyrinth", out var responseMessageIds))
|
||||
{
|
||||
traderDialogMessages.TryGetValue("insuranceFailed", out responseMessageIds);
|
||||
}
|
||||
@@ -751,15 +693,11 @@ public class InsuranceController(
|
||||
var roll = returnChance >= traderReturnChance;
|
||||
|
||||
// Log the roll with as much detail as possible.
|
||||
var itemName = insuredItem is not null
|
||||
? $"{itemHelper.GetItemName(insuredItem.Template)}"
|
||||
: "";
|
||||
var itemName = insuredItem is not null ? $"{itemHelper.GetItemName(insuredItem.Template)}" : "";
|
||||
var status = roll ? "Delete" : "Keep";
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug(
|
||||
$"Rolling {itemName} with {trader} - Return {traderReturnChance}% - Roll: {returnChance} - Status: {status}"
|
||||
);
|
||||
logger.Debug($"Rolling {itemName} with {trader} - Return {traderReturnChance}% - Roll: {returnChance} - Status: {status}");
|
||||
}
|
||||
|
||||
return roll;
|
||||
@@ -772,11 +710,7 @@ public class InsuranceController(
|
||||
/// <param name="request">Insurance request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse object to send to client</returns>
|
||||
public ItemEventRouterResponse Insure(
|
||||
PmcData pmcData,
|
||||
InsureRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse Insure(PmcData pmcData, InsureRequestData request, MongoId sessionId)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionId);
|
||||
var itemsToInsureCount = request.Items.Count;
|
||||
@@ -792,11 +726,7 @@ public class InsuranceController(
|
||||
new IdWithCount
|
||||
{
|
||||
Id = Money.ROUBLES, // TODO: update to handle different currencies
|
||||
Count = insuranceService.GetRoublePriceToInsureItemWithTrader(
|
||||
pmcData,
|
||||
inventoryItemsHash[key],
|
||||
request.TransactionId
|
||||
),
|
||||
Count = insuranceService.GetRoublePriceToInsureItemWithTrader(pmcData, inventoryItemsHash[key], request.TransactionId),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -824,9 +754,7 @@ public class InsuranceController(
|
||||
foreach (var key in request.Items)
|
||||
{
|
||||
var inventoryItem = inventoryItemsHash.GetValueOrDefault(key);
|
||||
pmcData.InsuredItems.Add(
|
||||
new InsuredItem { TId = request.TransactionId, ItemId = inventoryItem.Id }
|
||||
);
|
||||
pmcData.InsuredItems.Add(new InsuredItem { TId = request.TransactionId, ItemId = inventoryItem.Id });
|
||||
// If Item is Helmet or Body Armour -> Handle insurance of soft inserts
|
||||
if (itemHelper.ArmorItemHasRemovableOrSoftInsertSlots(inventoryItem.Template))
|
||||
{
|
||||
@@ -834,11 +762,7 @@ public class InsuranceController(
|
||||
}
|
||||
}
|
||||
|
||||
profileHelper.AddSkillPointsToPlayer(
|
||||
pmcData,
|
||||
SkillTypes.Charisma,
|
||||
itemsToInsureCount * 0.01
|
||||
);
|
||||
profileHelper.AddSkillPointsToPlayer(pmcData, SkillTypes.Charisma, itemsToInsureCount * 0.01);
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -849,15 +773,10 @@ public class InsuranceController(
|
||||
/// <param name="itemWithSoftInserts">Armor item to be insured</param>
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <param name="request">Insurance request data</param>
|
||||
public void InsureSoftInserts(
|
||||
Item itemWithSoftInserts,
|
||||
PmcData pmcData,
|
||||
InsureRequestData request
|
||||
)
|
||||
public void InsureSoftInserts(Item itemWithSoftInserts, PmcData pmcData, InsureRequestData request)
|
||||
{
|
||||
var softInsertSlots = pmcData.Inventory.Items.Where(item =>
|
||||
item.ParentId == itemWithSoftInserts.Id
|
||||
&& itemHelper.IsSoftInsertId(item.SlotId.ToLowerInvariant())
|
||||
item.ParentId == itemWithSoftInserts.Id && itemHelper.IsSoftInsertId(item.SlotId.ToLowerInvariant())
|
||||
);
|
||||
|
||||
foreach (var softInsertSlot in softInsertSlots)
|
||||
@@ -867,9 +786,7 @@ public class InsuranceController(
|
||||
logger.Debug($"SoftInsertSlots: {softInsertSlot.SlotId}");
|
||||
}
|
||||
|
||||
pmcData.InsuredItems.Add(
|
||||
new InsuredItem { TId = request.TransactionId, ItemId = softInsertSlot.Id }
|
||||
);
|
||||
pmcData.InsuredItems.Add(new InsuredItem { TId = request.TransactionId, ItemId = softInsertSlot.Id });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -900,9 +817,7 @@ public class InsuranceController(
|
||||
{
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug(
|
||||
$"Item with id: {itemId} missing from player inventory, skipping"
|
||||
);
|
||||
logger.Debug($"Item with id: {itemId} missing from player inventory, skipping");
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -911,11 +826,7 @@ public class InsuranceController(
|
||||
if (
|
||||
!traderItems.TryAdd(
|
||||
inventoryItem.Template,
|
||||
insuranceService.GetRoublePriceToInsureItemWithTrader(
|
||||
pmcData,
|
||||
inventoryItem,
|
||||
traderId
|
||||
)
|
||||
insuranceService.GetRoublePriceToInsureItemWithTrader(pmcData, inventoryItem, traderId)
|
||||
)
|
||||
)
|
||||
{
|
||||
|
||||
@@ -44,12 +44,7 @@ public class InventoryController(
|
||||
/// <param name="moveRequest">Move request data</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void MoveItem(
|
||||
PmcData pmcData,
|
||||
InventoryMoveRequestData moveRequest,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void MoveItem(PmcData pmcData, InventoryMoveRequestData moveRequest, MongoId sessionId, ItemEventRouterResponse output)
|
||||
{
|
||||
if (output.Warnings?.Count > 0)
|
||||
{
|
||||
@@ -57,27 +52,18 @@ public class InventoryController(
|
||||
}
|
||||
|
||||
// Changes made to result apply to character inventory
|
||||
var ownerInventoryItems = inventoryHelper.GetOwnerInventoryItems(
|
||||
moveRequest,
|
||||
moveRequest.Item.Value,
|
||||
sessionId
|
||||
);
|
||||
var ownerInventoryItems = inventoryHelper.GetOwnerInventoryItems(moveRequest, moveRequest.Item.Value, sessionId);
|
||||
if (ownerInventoryItems.SameInventory.GetValueOrDefault(false))
|
||||
{
|
||||
// Don't move items from trader to profile, this can happen when editing a traders preset weapons
|
||||
if (
|
||||
moveRequest.FromOwner?.Type == "Trader"
|
||||
&& !ownerInventoryItems.IsMail.GetValueOrDefault(false)
|
||||
)
|
||||
if (moveRequest.FromOwner?.Type == "Trader" && !ownerInventoryItems.IsMail.GetValueOrDefault(false))
|
||||
{
|
||||
AppendTraderExploitErrorResponse(output);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for item in inventory before allowing internal transfer
|
||||
var originalItemLocation = ownerInventoryItems.From?.FirstOrDefault(item =>
|
||||
item.Id == moveRequest.Item
|
||||
);
|
||||
var originalItemLocation = ownerInventoryItems.From?.FirstOrDefault(item => item.Id == moveRequest.Item);
|
||||
if (originalItemLocation is null)
|
||||
{
|
||||
// Internal item move but item never existed, possible dupe glitch
|
||||
@@ -87,12 +73,7 @@ public class InventoryController(
|
||||
|
||||
var originalLocationSlotId = originalItemLocation.SlotId;
|
||||
|
||||
var moveResult = inventoryHelper.MoveItemInternal(
|
||||
pmcData,
|
||||
ownerInventoryItems.From ?? [],
|
||||
moveRequest,
|
||||
out var errorMessage
|
||||
);
|
||||
var moveResult = inventoryHelper.MoveItemInternal(pmcData, ownerInventoryItems.From ?? [], moveRequest, out var errorMessage);
|
||||
if (!moveResult)
|
||||
{
|
||||
httpResponseUtil.AppendErrorToOutput(output, errorMessage);
|
||||
@@ -103,14 +84,8 @@ public class InventoryController(
|
||||
if (
|
||||
moveRequest.To?.Container != null
|
||||
&& (
|
||||
moveRequest.To.Container.StartsWith(
|
||||
"dogtag",
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
)
|
||||
|| originalLocationSlotId.StartsWith(
|
||||
"dogtag",
|
||||
StringComparison.OrdinalIgnoreCase
|
||||
)
|
||||
moveRequest.To.Container.StartsWith("dogtag", StringComparison.OrdinalIgnoreCase)
|
||||
|| originalLocationSlotId.StartsWith("dogtag", StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
)
|
||||
{
|
||||
@@ -119,11 +94,7 @@ public class InventoryController(
|
||||
}
|
||||
else
|
||||
{
|
||||
inventoryHelper.MoveItemToProfile(
|
||||
ownerInventoryItems.From ?? [],
|
||||
ownerInventoryItems.To ?? [],
|
||||
moveRequest
|
||||
);
|
||||
inventoryHelper.MoveItemToProfile(ownerInventoryItems.From ?? [], ownerInventoryItems.To ?? [], moveRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,21 +119,12 @@ public class InventoryController(
|
||||
/// <param name="request">Pin/Lock request data</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void PinOrLock(
|
||||
PmcData pmcData,
|
||||
PinOrLockItemRequest request,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void PinOrLock(PmcData pmcData, PinOrLockItemRequest request, MongoId sessionId, ItemEventRouterResponse output)
|
||||
{
|
||||
var itemToAdjust = pmcData.Inventory!.Items!.FirstOrDefault(item =>
|
||||
item.Id == request.Item
|
||||
);
|
||||
var itemToAdjust = pmcData.Inventory!.Items!.FirstOrDefault(item => item.Id == request.Item);
|
||||
if (itemToAdjust is null)
|
||||
{
|
||||
logger.Error(
|
||||
$"Unable find item: {request.Item.Value.ToString()} to: {request.State} on player: {sessionId} to: "
|
||||
);
|
||||
logger.Error($"Unable find item: {request.Item.Value.ToString()} to: {request.State} on player: {sessionId} to: ");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -192,11 +154,7 @@ public class InventoryController(
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
public void RedeemProfileReward(
|
||||
PmcData pmcData,
|
||||
RedeemProfileRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public void RedeemProfileReward(PmcData pmcData, RedeemProfileRequestData request, MongoId sessionId)
|
||||
{
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionId);
|
||||
foreach (var rewardEvent in request.Events)
|
||||
@@ -204,28 +162,20 @@ public class InventoryController(
|
||||
// Hard coded to `SYSTEM` for now
|
||||
// TODO: make this dynamic
|
||||
var dialog = fullProfile.DialogueRecords["59e7125688a45068a6249071"];
|
||||
var mail = dialog.Messages.FirstOrDefault(message =>
|
||||
message.Id == rewardEvent.MessageId
|
||||
);
|
||||
var mailEvent = mail.ProfileChangeEvents.FirstOrDefault(changeEvent =>
|
||||
changeEvent.Id == rewardEvent.EventId
|
||||
);
|
||||
var mail = dialog.Messages.FirstOrDefault(message => message.Id == rewardEvent.MessageId);
|
||||
var mailEvent = mail.ProfileChangeEvents.FirstOrDefault(changeEvent => changeEvent.Id == rewardEvent.EventId);
|
||||
|
||||
switch (mailEvent.Type)
|
||||
{
|
||||
case "TraderSalesSum":
|
||||
pmcData.TradersInfo[mailEvent.Entity].SalesSum = mailEvent.Value;
|
||||
traderHelper.LevelUp(mailEvent.Entity, pmcData);
|
||||
logger.Success(
|
||||
$"Set trader {mailEvent.Entity}: Sales Sum to: {mailEvent.Value}"
|
||||
);
|
||||
logger.Success($"Set trader {mailEvent.Entity}: Sales Sum to: {mailEvent.Value}");
|
||||
break;
|
||||
case "TraderStanding":
|
||||
pmcData.TradersInfo[mailEvent.Entity].Standing = mailEvent.Value;
|
||||
traderHelper.LevelUp(mailEvent.Entity, pmcData);
|
||||
logger.Success(
|
||||
$"Set trader {mailEvent.Entity}: Standing to: {mailEvent.Value}"
|
||||
);
|
||||
logger.Success($"Set trader {mailEvent.Entity}: Standing to: {mailEvent.Value}");
|
||||
break;
|
||||
case "ProfileLevel":
|
||||
pmcData.Info.Experience = (int)mailEvent.Value.Value;
|
||||
@@ -235,9 +185,7 @@ public class InventoryController(
|
||||
break;
|
||||
case "SkillPoints":
|
||||
{
|
||||
var profileSkill = pmcData.Skills.Common.FirstOrDefault(x =>
|
||||
x.Id == Enum.Parse<SkillTypes>(mailEvent.Entity)
|
||||
);
|
||||
var profileSkill = pmcData.Skills.Common.FirstOrDefault(x => x.Id == Enum.Parse<SkillTypes>(mailEvent.Entity));
|
||||
if (profileSkill is null)
|
||||
{
|
||||
logger.Warning($"Unable to find skill with name: {mailEvent.Entity}");
|
||||
@@ -250,10 +198,7 @@ public class InventoryController(
|
||||
}
|
||||
case "ExamineAllItems":
|
||||
{
|
||||
var itemIds = databaseService
|
||||
.GetItems()
|
||||
.Where(x => x.Value.Type != "Node")
|
||||
.Select(x => x.Key);
|
||||
var itemIds = databaseService.GetItems().Where(x => x.Value.Type != "Node").Select(x => x.Key);
|
||||
FlagItemsAsInspectedAndRewardXp(itemIds, fullProfile);
|
||||
logger.Success($"Flagged {itemIds.Count()} items as examined");
|
||||
|
||||
@@ -276,9 +221,7 @@ public class InventoryController(
|
||||
var newValue = mailEvent.Value;
|
||||
var hideoutAreaType = Enum.Parse<HideoutAreas>(areaName ?? "NotSet");
|
||||
|
||||
var desiredArea = pmcData.Hideout.Areas.FirstOrDefault(area =>
|
||||
area.Type == hideoutAreaType
|
||||
);
|
||||
var desiredArea = pmcData.Hideout.Areas.FirstOrDefault(area => area.Type == hideoutAreaType);
|
||||
if (desiredArea is not null)
|
||||
{
|
||||
desiredArea.Level = (int?)newValue;
|
||||
@@ -299,43 +242,27 @@ public class InventoryController(
|
||||
/// </summary>
|
||||
/// <param name="itemTpls">Inspected item tpls</param>
|
||||
/// <param name="fullProfile">Profile to add xp to</param>
|
||||
protected void FlagItemsAsInspectedAndRewardXp(
|
||||
IEnumerable<MongoId> itemTpls,
|
||||
SptProfile fullProfile
|
||||
)
|
||||
protected void FlagItemsAsInspectedAndRewardXp(IEnumerable<MongoId> itemTpls, SptProfile fullProfile)
|
||||
{
|
||||
foreach (var itemTpl in itemTpls)
|
||||
{
|
||||
var item = itemHelper.GetItem(itemTpl);
|
||||
if (!item.Key)
|
||||
{
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-unable_to_inspect_item_not_in_db",
|
||||
itemTpl
|
||||
)
|
||||
);
|
||||
logger.Warning(serverLocalisationService.GetText("inventory-unable_to_inspect_item_not_in_db", itemTpl));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
fullProfile.CharacterData.PmcData.Info.Experience += item.Value
|
||||
.Properties
|
||||
.ExamineExperience;
|
||||
fullProfile.CharacterData.PmcData.Info.Experience += item.Value.Properties.ExamineExperience;
|
||||
fullProfile.CharacterData.PmcData.Encyclopedia[itemTpl] = false;
|
||||
|
||||
fullProfile.CharacterData.ScavData.Info.Experience += item.Value
|
||||
.Properties
|
||||
.ExamineExperience;
|
||||
fullProfile.CharacterData.ScavData.Info.Experience += item.Value.Properties.ExamineExperience;
|
||||
fullProfile.CharacterData.ScavData.Encyclopedia[itemTpl] = false;
|
||||
}
|
||||
|
||||
// TODO: update this with correct calculation using values from globals json
|
||||
profileHelper.AddSkillPointsToPlayer(
|
||||
fullProfile.CharacterData.PmcData,
|
||||
SkillTypes.Intellect,
|
||||
0.05 * itemTpls.Count()
|
||||
);
|
||||
profileHelper.AddSkillPointsToPlayer(fullProfile.CharacterData.PmcData, SkillTypes.Intellect, 0.05 * itemTpls.Count());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -379,14 +306,10 @@ public class InventoryController(
|
||||
}
|
||||
else
|
||||
{
|
||||
var rewardContainerDetails = inventoryHelper.GetRandomLootContainerRewardDetails(
|
||||
openedItem.Template
|
||||
);
|
||||
var rewardContainerDetails = inventoryHelper.GetRandomLootContainerRewardDetails(openedItem.Template);
|
||||
if (rewardContainerDetails?.RewardCount == null)
|
||||
{
|
||||
logger.Error(
|
||||
$"Unable to add loot to container: {openedItem.Template}, no rewards found"
|
||||
);
|
||||
logger.Error($"Unable to add loot to container: {openedItem.Template}, no rewards found");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -427,12 +350,7 @@ public class InventoryController(
|
||||
/// <param name="request">Edit marker request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void EditMapMarker(
|
||||
PmcData pmcData,
|
||||
InventoryEditMarkerRequestData request,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void EditMapMarker(PmcData pmcData, InventoryEditMarkerRequestData request, MongoId sessionId, ItemEventRouterResponse output)
|
||||
{
|
||||
var mapItem = mapMarkerService.EditMarkerOnMap(pmcData, request);
|
||||
|
||||
@@ -480,26 +398,14 @@ public class InventoryController(
|
||||
/// <param name="request">Add marker request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void SortInventory(
|
||||
PmcData pmcData,
|
||||
InventorySortRequestData request,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void SortInventory(PmcData pmcData, InventorySortRequestData request, MongoId sessionId, ItemEventRouterResponse output)
|
||||
{
|
||||
foreach (var change in request.ChangedItems)
|
||||
{
|
||||
var inventoryItem = pmcData.Inventory.Items.FirstOrDefault(item =>
|
||||
item.Id == change.Id
|
||||
);
|
||||
var inventoryItem = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == change.Id);
|
||||
if (inventoryItem is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-unable_to_sort_inventory_restart_game",
|
||||
change.Id
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("inventory-unable_to_sort_inventory_restart_game", change.Id));
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -517,11 +423,7 @@ public class InventoryController(
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse ReadEncyclopedia(
|
||||
PmcData pmcData,
|
||||
InventoryReadEncyclopediaRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse ReadEncyclopedia(PmcData pmcData, InventoryReadEncyclopediaRequestData request, MongoId sessionId)
|
||||
{
|
||||
foreach (var id in request.Ids)
|
||||
{
|
||||
@@ -538,12 +440,7 @@ public class InventoryController(
|
||||
/// <param name="request">Examine item request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void ExamineItem(
|
||||
PmcData pmcData,
|
||||
InventoryExamineRequestData request,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void ExamineItem(PmcData pmcData, InventoryExamineRequestData request, MongoId sessionId, ItemEventRouterResponse output)
|
||||
{
|
||||
MongoId? itemId = null;
|
||||
if (request.FromOwner is not null)
|
||||
@@ -554,12 +451,7 @@ public class InventoryController(
|
||||
}
|
||||
catch
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-examine_item_does_not_exist",
|
||||
request.ItemId
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("inventory-examine_item_does_not_exist", request.ItemId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,10 +497,7 @@ public class InventoryController(
|
||||
if (request.FromOwner.Id == Traders.FENCE)
|
||||
// Get tpl from fence assorts
|
||||
{
|
||||
return fenceService
|
||||
.GetRawFenceAssorts()
|
||||
.Items.FirstOrDefault(x => x.Id == request.ItemId)
|
||||
?.Template;
|
||||
return fenceService.GetRawFenceAssorts().Items.FirstOrDefault(x => x.Id == request.ItemId)?.Template;
|
||||
}
|
||||
|
||||
if (request.FromOwner.Type == "Trader")
|
||||
@@ -632,22 +521,17 @@ public class InventoryController(
|
||||
|
||||
// Try alternate way of getting offer if first approach fails
|
||||
var offer =
|
||||
ragfairOfferService.GetOfferByOfferId(request.ItemId)
|
||||
?? ragfairOfferService.GetOfferByOfferId(request.FromOwner.Id.Value);
|
||||
ragfairOfferService.GetOfferByOfferId(request.ItemId) ?? ragfairOfferService.GetOfferByOfferId(request.FromOwner.Id.Value);
|
||||
|
||||
// Try find examine item inside offer items array
|
||||
var matchingItem = offer.Items.FirstOrDefault(offerItem =>
|
||||
offerItem.Id == request.ItemId
|
||||
);
|
||||
var matchingItem = offer.Items.FirstOrDefault(offerItem => offerItem.Id == request.ItemId);
|
||||
if (matchingItem is not null)
|
||||
{
|
||||
return matchingItem.Template;
|
||||
}
|
||||
|
||||
// Unable to find item in database or ragfair
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText("inventory-unable_to_find_item", request.ItemId)
|
||||
);
|
||||
logger.Warning(serverLocalisationService.GetText("inventory-unable_to_find_item", request.ItemId));
|
||||
}
|
||||
|
||||
// get hideout item
|
||||
@@ -662,9 +546,7 @@ public class InventoryController(
|
||||
// all mail the player has
|
||||
var mail = profileHelper.GetFullProfile(sessionId).DialogueRecords;
|
||||
// per trader/person mail
|
||||
var dialogue = mail.FirstOrDefault(x =>
|
||||
x.Value.Messages.Any(m => m.Id == request.FromOwner.Id)
|
||||
);
|
||||
var dialogue = mail.FirstOrDefault(x => x.Value.Messages.Any(m => m.Id == request.FromOwner.Id));
|
||||
// check each message from that trader/person for messages that match the ID we got
|
||||
var message = dialogue.Value.Messages.FirstOrDefault(m => m.Id == request.FromOwner.Id);
|
||||
// get the Id given and get the Template ID from that
|
||||
@@ -689,12 +571,7 @@ public class InventoryController(
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void UnBindItem(
|
||||
PmcData pmcData,
|
||||
InventoryBindRequestData request,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void UnBindItem(PmcData pmcData, InventoryBindRequestData request, MongoId sessionId, ItemEventRouterResponse output)
|
||||
{
|
||||
// Remove kvp from requested fast panel index
|
||||
|
||||
@@ -710,12 +587,7 @@ public class InventoryController(
|
||||
/// <param name="bindRequest"></param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void BindItem(
|
||||
PmcData pmcData,
|
||||
InventoryBindRequestData bindRequest,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void BindItem(PmcData pmcData, InventoryBindRequestData bindRequest, MongoId sessionId, ItemEventRouterResponse output)
|
||||
{
|
||||
// Remove link
|
||||
pmcData.Inventory.FastPanel.Remove(bindRequest.Index);
|
||||
@@ -731,18 +603,12 @@ public class InventoryController(
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse TagItem(
|
||||
PmcData pmcData,
|
||||
InventoryTagRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse TagItem(PmcData pmcData, InventoryTagRequestData request, MongoId sessionId)
|
||||
{
|
||||
var itemToTag = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == request.Item);
|
||||
if (itemToTag is null)
|
||||
{
|
||||
logger.Warning(
|
||||
$"Unable to tag item: {request.Item} as it cannot be found in player {sessionId} inventory"
|
||||
);
|
||||
logger.Warning($"Unable to tag item: {request.Item} as it cannot be found in player {sessionId} inventory");
|
||||
|
||||
return new ItemEventRouterResponse { Warnings = [] };
|
||||
}
|
||||
@@ -762,11 +628,7 @@ public class InventoryController(
|
||||
/// <param name="request">Toggle request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse ToggleItem(
|
||||
PmcData pmcData,
|
||||
InventoryToggleRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse ToggleItem(PmcData pmcData, InventoryToggleRequestData request, MongoId sessionId)
|
||||
{
|
||||
// May need to reassign to scav profile
|
||||
var playerData = pmcData;
|
||||
@@ -782,10 +644,7 @@ public class InventoryController(
|
||||
{
|
||||
itemHelper.AddUpdObjectToItem(
|
||||
itemToToggle,
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-item_to_toggle_missing_upd",
|
||||
itemToToggle.Id
|
||||
)
|
||||
serverLocalisationService.GetText("inventory-item_to_toggle_missing_upd", itemToToggle.Id)
|
||||
);
|
||||
|
||||
itemToToggle.Upd.Togglable = new UpdTogglable { On = request.Value };
|
||||
@@ -793,12 +652,7 @@ public class InventoryController(
|
||||
return eventOutputHolder.GetOutput(sessionId);
|
||||
}
|
||||
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-unable_to_toggle_item_not_found",
|
||||
request.Item
|
||||
)
|
||||
);
|
||||
logger.Warning(serverLocalisationService.GetText("inventory-unable_to_toggle_item_not_found", request.Item));
|
||||
|
||||
return new ItemEventRouterResponse { Warnings = [] };
|
||||
}
|
||||
@@ -810,11 +664,7 @@ public class InventoryController(
|
||||
/// <param name="request">Fold item request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse FoldItem(
|
||||
PmcData pmcData,
|
||||
InventoryFoldRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse FoldItem(PmcData pmcData, InventoryFoldRequestData request, MongoId sessionId)
|
||||
{
|
||||
// May need to reassign to scav profile
|
||||
var playerData = pmcData;
|
||||
@@ -829,12 +679,7 @@ public class InventoryController(
|
||||
if (itemToFold is null)
|
||||
{
|
||||
// Item not found
|
||||
logger.Warning(
|
||||
serverLocalisationService.GetText(
|
||||
"inventory-unable_to_fold_item_not_found_in_inventory",
|
||||
request.Item
|
||||
)
|
||||
);
|
||||
logger.Warning(serverLocalisationService.GetText("inventory-unable_to_fold_item_not_found_in_inventory", request.Item));
|
||||
|
||||
return new ItemEventRouterResponse { Warnings = [] };
|
||||
}
|
||||
@@ -856,11 +701,7 @@ public class InventoryController(
|
||||
/// <param name="request">Swap item request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse SwapItem(
|
||||
PmcData pmcData,
|
||||
InventorySwapRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse SwapItem(PmcData pmcData, InventorySwapRequestData request, MongoId sessionId)
|
||||
{
|
||||
// During post-raid scav transfer, the swap may be in the scav inventory
|
||||
var playerData = pmcData;
|
||||
@@ -917,19 +758,10 @@ public class InventoryController(
|
||||
/// <param name="request">Transfer item request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void TransferItem(
|
||||
PmcData pmcData,
|
||||
InventoryTransferRequestData request,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void TransferItem(PmcData pmcData, InventoryTransferRequestData request, MongoId sessionId, ItemEventRouterResponse output)
|
||||
{
|
||||
// TODO - check GetOwnerInventoryItems() call still works
|
||||
var inventoryItems = inventoryHelper.GetOwnerInventoryItems(
|
||||
request,
|
||||
request.Item,
|
||||
sessionId
|
||||
);
|
||||
var inventoryItems = inventoryHelper.GetOwnerInventoryItems(request, request.Item, sessionId);
|
||||
var sourceItem = inventoryItems.From.FirstOrDefault(item => item.Id == request.Item);
|
||||
var destinationItem = inventoryItems.To.FirstOrDefault(item => item.Id == request.With);
|
||||
|
||||
@@ -981,26 +813,16 @@ public class InventoryController(
|
||||
/// <param name="request">Merge stacks request</param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void MergeItem(
|
||||
PmcData pmcData,
|
||||
InventoryMergeRequestData request,
|
||||
MongoId sessionID,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void MergeItem(PmcData pmcData, InventoryMergeRequestData request, MongoId sessionID, ItemEventRouterResponse output)
|
||||
{
|
||||
// Changes made to result apply to character inventory
|
||||
var inventoryItems = inventoryHelper.GetOwnerInventoryItems(
|
||||
request,
|
||||
request.Item,
|
||||
sessionID
|
||||
);
|
||||
var inventoryItems = inventoryHelper.GetOwnerInventoryItems(request, request.Item, sessionID);
|
||||
|
||||
// Get source item (can be from player or trader or mail)
|
||||
var sourceItem = inventoryItems.From.FirstOrDefault(x => x.Id == request.Item);
|
||||
if (sourceItem is null)
|
||||
{
|
||||
var errorMessage =
|
||||
$"Unable to merge stacks as source item: {request.With} cannot be found";
|
||||
var errorMessage = $"Unable to merge stacks as source item: {request.With} cannot be found";
|
||||
logger.Error(errorMessage);
|
||||
|
||||
httpResponseUtil.AppendErrorToOutput(output, errorMessage);
|
||||
@@ -1012,8 +834,7 @@ public class InventoryController(
|
||||
var destinationItem = inventoryItems.To.FirstOrDefault(x => x.Id == request.With);
|
||||
if (destinationItem is null)
|
||||
{
|
||||
var errorMessage =
|
||||
$"Unable to merge stacks as destination item: {request.With} cannot be found";
|
||||
var errorMessage = $"Unable to merge stacks as destination item: {request.With} cannot be found";
|
||||
logger.Error(errorMessage);
|
||||
|
||||
httpResponseUtil.AppendErrorToOutput(output, errorMessage);
|
||||
@@ -1038,24 +859,18 @@ public class InventoryController(
|
||||
}
|
||||
|
||||
// Remove FiR status from destination stack when source stack has no FiR but destination does
|
||||
if (
|
||||
!sourceItem.Upd.SpawnedInSession.GetValueOrDefault(false)
|
||||
&& destinationItem.Upd.SpawnedInSession.GetValueOrDefault(false)
|
||||
)
|
||||
if (!sourceItem.Upd.SpawnedInSession.GetValueOrDefault(false) && destinationItem.Upd.SpawnedInSession.GetValueOrDefault(false))
|
||||
{
|
||||
destinationItem.Upd.SpawnedInSession = false;
|
||||
}
|
||||
|
||||
destinationItem.Upd.StackObjectsCount += sourceItem.Upd.StackObjectsCount; // Add source stackcount to destination
|
||||
output
|
||||
.ProfileChanges[sessionID]
|
||||
.Items.DeletedItems.Add(new DeletedItem { Id = sourceItem.Id }); // Inform client source item being deleted
|
||||
output.ProfileChanges[sessionID].Items.DeletedItems.Add(new DeletedItem { Id = sourceItem.Id }); // Inform client source item being deleted
|
||||
|
||||
var indexOfItemToRemove = inventoryItems.From.FindIndex(x => x.Id == sourceItem.Id);
|
||||
if (indexOfItemToRemove == -1)
|
||||
{
|
||||
var errorMessage =
|
||||
$"Unable to find item: {sourceItem.Id} to remove from sender inventory";
|
||||
var errorMessage = $"Unable to find item: {sourceItem.Id} to remove from sender inventory";
|
||||
logger.Error(errorMessage);
|
||||
|
||||
httpResponseUtil.AppendErrorToOutput(output, errorMessage);
|
||||
@@ -1073,19 +888,10 @@ public class InventoryController(
|
||||
/// <param name="request">Split stack request</param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void SplitItem(
|
||||
PmcData pmcData,
|
||||
InventorySplitRequestData request,
|
||||
MongoId sessionID,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void SplitItem(PmcData pmcData, InventorySplitRequestData request, MongoId sessionID, ItemEventRouterResponse output)
|
||||
{
|
||||
// Changes made to result apply to character inventory
|
||||
var inventoryItems = inventoryHelper.GetOwnerInventoryItems(
|
||||
request,
|
||||
request.NewItem.Value,
|
||||
sessionID
|
||||
);
|
||||
var inventoryItems = inventoryHelper.GetOwnerInventoryItems(request, request.NewItem.Value, sessionID);
|
||||
|
||||
// Handle cartridge edge-case
|
||||
if (request.Container.Location is null && request.Container.ContainerName == "cartridges")
|
||||
@@ -1098,8 +904,7 @@ public class InventoryController(
|
||||
var itemToSplit = inventoryItems.From.FirstOrDefault(x => x.Id == request.SplitItem);
|
||||
if (itemToSplit is null)
|
||||
{
|
||||
var errorMessage =
|
||||
$"Unable to split stack as source item: {request.SplitItem} cannot be found";
|
||||
var errorMessage = $"Unable to split stack as source item: {request.SplitItem} cannot be found";
|
||||
logger.Error(errorMessage);
|
||||
|
||||
httpResponseUtil.AppendErrorToOutput(output, errorMessage);
|
||||
@@ -1148,12 +953,7 @@ public class InventoryController(
|
||||
/// <param name="request">Discard item request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="output">Client response</param>
|
||||
public void DiscardItem(
|
||||
PmcData pmcData,
|
||||
InventoryRemoveRequestData request,
|
||||
MongoId sessionId,
|
||||
ItemEventRouterResponse output
|
||||
)
|
||||
public void DiscardItem(PmcData pmcData, InventoryRemoveRequestData request, MongoId sessionId, ItemEventRouterResponse output)
|
||||
{
|
||||
if (request.FromOwner?.Type == "Mail")
|
||||
{
|
||||
|
||||
@@ -38,9 +38,7 @@ public class LauncherController(
|
||||
// Get all possible profile types + filter out any that are blacklisted
|
||||
var profileTemplates = databaseService
|
||||
.GetProfileTemplates()
|
||||
.Where(profile =>
|
||||
!_coreConfig.Features.CreateNewProfileTypesBlacklist.Contains(profile.Key)
|
||||
)
|
||||
.Where(profile => !_coreConfig.Features.CreateNewProfileTypesBlacklist.Contains(profile.Key))
|
||||
.ToDictionary();
|
||||
|
||||
return new ConnectResponse
|
||||
@@ -57,17 +55,12 @@ public class LauncherController(
|
||||
/// </summary>
|
||||
/// <param name="profileTemplates">Profiles to get descriptions of</param>
|
||||
/// <returns>Dictionary of profile types with related descriptive text</returns>
|
||||
protected Dictionary<string, string> GetProfileDescriptions(
|
||||
Dictionary<string, ProfileSides> profileTemplates
|
||||
)
|
||||
protected Dictionary<string, string> GetProfileDescriptions(Dictionary<string, ProfileSides> profileTemplates)
|
||||
{
|
||||
var result = new Dictionary<string, string>();
|
||||
foreach (var (profileKey, profile) in profileTemplates)
|
||||
{
|
||||
result.TryAdd(
|
||||
profileKey,
|
||||
serverLocalisationService.GetText(profile.DescriptionLocaleKey)
|
||||
);
|
||||
result.TryAdd(profileKey, serverLocalisationService.GetText(profile.DescriptionLocaleKey));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -79,9 +72,7 @@ public class LauncherController(
|
||||
/// <returns></returns>
|
||||
public Info? Find(MongoId sessionId)
|
||||
{
|
||||
return saveServer.GetProfiles().TryGetValue(sessionId, out var profile)
|
||||
? profile.ProfileInfo
|
||||
: null;
|
||||
return saveServer.GetProfiles().TryGetValue(sessionId, out var profile) ? profile.ProfileInfo : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -215,10 +206,7 @@ public class LauncherController(
|
||||
/// <returns>Dictionary of mod name and mod details</returns>
|
||||
public Dictionary<string, AbstractModMetadata> GetLoadedServerMods()
|
||||
{
|
||||
return loadedMods.ToDictionary(
|
||||
sptMod => sptMod.ModMetadata?.Name ?? "UNKNOWN MOD",
|
||||
sptMod => sptMod.ModMetadata
|
||||
);
|
||||
return loadedMods.ToDictionary(sptMod => sptMod.ModMetadata?.Name ?? "UNKNOWN MOD", sptMod => sptMod.ModMetadata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -47,10 +47,7 @@ public class LauncherV2Controller(
|
||||
|
||||
foreach (var (templateName, template) in dbProfiles)
|
||||
{
|
||||
result.TryAdd(
|
||||
templateName,
|
||||
serverLocalisationService.GetText(template.DescriptionLocaleKey)
|
||||
);
|
||||
result.TryAdd(templateName, serverLocalisationService.GetText(template.DescriptionLocaleKey));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -149,10 +146,7 @@ public class LauncherV2Controller(
|
||||
/// <returns></returns>
|
||||
public Dictionary<string, AbstractModMetadata> LoadedMods()
|
||||
{
|
||||
return loadedMods.ToDictionary(
|
||||
sptMod => sptMod.ModMetadata.Name,
|
||||
sptMod => sptMod.ModMetadata
|
||||
);
|
||||
return loadedMods.ToDictionary(sptMod => sptMod.ModMetadata.Name, sptMod => sptMod.ModMetadata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -187,10 +181,7 @@ public class LauncherV2Controller(
|
||||
{
|
||||
foreach (var (sessionId, profile) in saveServer.GetProfiles())
|
||||
{
|
||||
if (
|
||||
info.Username == profile.ProfileInfo!.Username
|
||||
&& info.Password == profile.ProfileInfo.Password
|
||||
)
|
||||
if (info.Username == profile.ProfileInfo!.Username && info.Password == profile.ProfileInfo.Password)
|
||||
{
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
@@ -10,11 +10,7 @@ using LogLevel = SPTarkov.Server.Core.Models.Spt.Logging.LogLevel;
|
||||
namespace SPTarkov.Server.Core.Controllers;
|
||||
|
||||
[Injectable]
|
||||
public class LocationController(
|
||||
ISptLogger<LocationController> logger,
|
||||
DatabaseService databaseService,
|
||||
AirdropService airdropService
|
||||
)
|
||||
public class LocationController(ISptLogger<LocationController> logger, DatabaseService databaseService, AirdropService airdropService)
|
||||
{
|
||||
/// <summary>
|
||||
/// Handle client/locations
|
||||
@@ -49,11 +45,7 @@ public class LocationController(
|
||||
locationResult.Add(mapBase.IdField, mapBase);
|
||||
}
|
||||
|
||||
return new LocationsGenerateAllResponse
|
||||
{
|
||||
Locations = locationResult,
|
||||
Paths = locationsFromDb.Base!.Paths,
|
||||
};
|
||||
return new LocationsGenerateAllResponse { Locations = locationResult, Paths = locationsFromDb.Base!.Paths };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -104,9 +104,7 @@ public class MatchController(
|
||||
// Set pmcs to difficulty set in pre-raid screen if override in bot config isnt enabled
|
||||
if (!_pmcConfig.UseDifficultyOverride)
|
||||
{
|
||||
_pmcConfig.Difficulty = ConvertDifficultyDropdownIntoBotDifficulty(
|
||||
request.WavesSettings.BotDifficulty.ToString()
|
||||
);
|
||||
_pmcConfig.Difficulty = ConvertDifficultyDropdownIntoBotDifficulty(request.WavesSettings.BotDifficulty.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,10 +130,7 @@ public class MatchController(
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="request">Start raid request</param>
|
||||
/// <returns>StartLocalRaidResponseData</returns>
|
||||
public StartLocalRaidResponseData StartLocalRaid(
|
||||
MongoId sessionId,
|
||||
StartLocalRaidRequestData request
|
||||
)
|
||||
public StartLocalRaidResponseData StartLocalRaid(MongoId sessionId, StartLocalRaidRequestData request)
|
||||
{
|
||||
return locationLifecycleService.StartLocalRaid(sessionId, request);
|
||||
}
|
||||
|
||||
@@ -16,11 +16,7 @@ public class NoteController(EventOutputHolder eventOutputHolder)
|
||||
/// <param name="request">Add note request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse AddNote(
|
||||
PmcData pmcData,
|
||||
NoteActionRequest request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse AddNote(PmcData pmcData, NoteActionRequest request, MongoId sessionId)
|
||||
{
|
||||
var newNote = new Note { Time = request.Note.Time, Text = request.Note.Text };
|
||||
pmcData.Notes.DataNotes.Add(newNote);
|
||||
@@ -34,11 +30,7 @@ public class NoteController(EventOutputHolder eventOutputHolder)
|
||||
/// <param name="request">Edit note request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse EditNote(
|
||||
PmcData pmcData,
|
||||
NoteActionRequest request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse EditNote(PmcData pmcData, NoteActionRequest request, MongoId sessionId)
|
||||
{
|
||||
var noteToEdit = pmcData.Notes.DataNotes[request.Index!.Value];
|
||||
noteToEdit.Time = request.Note.Time;
|
||||
@@ -53,11 +45,7 @@ public class NoteController(EventOutputHolder eventOutputHolder)
|
||||
/// <param name="request">Delete note request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse DeleteNote(
|
||||
PmcData pmcData,
|
||||
NoteActionRequest request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse DeleteNote(PmcData pmcData, NoteActionRequest request, MongoId sessionId)
|
||||
{
|
||||
pmcData.Notes?.DataNotes?.RemoveAt(request.Index!.Value);
|
||||
|
||||
|
||||
@@ -8,11 +8,7 @@ using SPTarkov.Server.Core.Services;
|
||||
namespace SPTarkov.Server.Core.Controllers;
|
||||
|
||||
[Injectable]
|
||||
public class NotifierController(
|
||||
HttpServerHelper httpServerHelper,
|
||||
NotifierHelper notifierHelper,
|
||||
NotificationService notificationService
|
||||
)
|
||||
public class NotifierController(HttpServerHelper httpServerHelper, NotifierHelper notifierHelper, NotificationService notificationService)
|
||||
{
|
||||
protected const int PollInterval = 300;
|
||||
protected const int Timeout = 15000;
|
||||
|
||||
@@ -8,11 +8,7 @@ using SPTarkov.Server.Core.Services;
|
||||
namespace SPTarkov.Server.Core.Controllers;
|
||||
|
||||
[Injectable]
|
||||
public class PresetController(
|
||||
ISptLogger<PresetController> logger,
|
||||
PresetHelper presetHelper,
|
||||
DatabaseService databaseService
|
||||
)
|
||||
public class PresetController(ISptLogger<PresetController> logger, PresetHelper presetHelper, DatabaseService databaseService)
|
||||
{
|
||||
/// <summary>
|
||||
/// Keyed by item tpl, value = collection of preset ids
|
||||
|
||||
@@ -44,9 +44,7 @@ public class ProfileController(
|
||||
var profile = saveServer.GetProfile(sessionId);
|
||||
if (profile?.CharacterData == null)
|
||||
{
|
||||
throw new Exception(
|
||||
$"Unable to find character data for id: {sessionId}. Profile may be corrupt"
|
||||
);
|
||||
throw new Exception($"Unable to find character data for id: {sessionId}. Profile may be corrupt");
|
||||
}
|
||||
|
||||
var pmc = profile.CharacterData.PmcData;
|
||||
@@ -82,8 +80,7 @@ public class ProfileController(
|
||||
Side = pmc.Info.Side,
|
||||
CurrentLevel = pmc.Info.Level,
|
||||
CurrentExperience = pmc.Info.Experience ?? 0,
|
||||
PreviousExperience =
|
||||
currentLevel == 0 ? 0 : profileHelper.GetExperience(currentLevel.Value),
|
||||
PreviousExperience = currentLevel == 0 ? 0 : profileHelper.GetExperience(currentLevel.Value),
|
||||
NextLevel = xpToNextLevel,
|
||||
MaxLevel = maxLvl,
|
||||
Edition = profile.ProfileInfo?.Edition ?? "",
|
||||
@@ -127,10 +124,7 @@ public class ProfileController(
|
||||
/// <param name="request">Create profile request</param>
|
||||
/// <param name="sessionId">Player id</param>
|
||||
/// <returns>Player id</returns>
|
||||
public virtual async ValueTask<string> CreateProfile(
|
||||
ProfileCreateRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public virtual async ValueTask<string> CreateProfile(ProfileCreateRequestData request, MongoId sessionId)
|
||||
{
|
||||
return await createProfileService.CreateProfile(sessionId, request);
|
||||
}
|
||||
@@ -152,10 +146,7 @@ public class ProfileController(
|
||||
/// <param name="request">Validate nickname request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
public virtual NicknameValidationResult ValidateNickname(
|
||||
ValidateNicknameRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public virtual NicknameValidationResult ValidateNickname(ValidateNicknameRequestData request, MongoId sessionId)
|
||||
{
|
||||
if (request.Nickname?.Length < 3)
|
||||
{
|
||||
@@ -177,15 +168,9 @@ public class ProfileController(
|
||||
/// <param name="request">Change nickname request</param>
|
||||
/// <param name="sessionId">Player id</param>
|
||||
/// <returns></returns>
|
||||
public virtual NicknameValidationResult ChangeNickname(
|
||||
ProfileChangeNicknameRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public virtual NicknameValidationResult ChangeNickname(ProfileChangeNicknameRequestData request, MongoId sessionId)
|
||||
{
|
||||
var output = ValidateNickname(
|
||||
new ValidateNicknameRequestData { Nickname = request.Nickname },
|
||||
sessionId
|
||||
);
|
||||
var output = ValidateNickname(new ValidateNicknameRequestData { Nickname = request.Nickname }, sessionId);
|
||||
|
||||
if (output == NicknameValidationResult.Valid)
|
||||
{
|
||||
@@ -215,10 +200,7 @@ public class ProfileController(
|
||||
/// <param name="request">Search profiles request</param>
|
||||
/// <param name="sessionID">Player id</param>
|
||||
/// <returns>Found profiles</returns>
|
||||
public virtual List<SearchFriendResponse> SearchProfiles(
|
||||
SearchProfilesRequestData request,
|
||||
MongoId sessionID
|
||||
)
|
||||
public virtual List<SearchFriendResponse> SearchProfiles(SearchProfilesRequestData request, MongoId sessionID)
|
||||
{
|
||||
var result = new List<SearchFriendResponse>();
|
||||
|
||||
@@ -228,10 +210,7 @@ public class ProfileController(
|
||||
foreach (var profile in allProfiles)
|
||||
{
|
||||
var pmcProfile = profile?.CharacterData?.PmcData;
|
||||
if (
|
||||
!pmcProfile?.Info?.LowerNickname?.Contains(request.Nickname.ToLowerInvariant())
|
||||
?? false
|
||||
)
|
||||
if (!pmcProfile?.Info?.LowerNickname?.Contains(request.Nickname.ToLowerInvariant()) ?? false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -285,21 +264,13 @@ public class ProfileController(
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <param name="request">Get other profile request</param>
|
||||
/// <returns>GetOtherProfileResponse</returns>
|
||||
public virtual GetOtherProfileResponse GetOtherProfile(
|
||||
MongoId sessionId,
|
||||
GetOtherProfileRequest request
|
||||
)
|
||||
public virtual GetOtherProfileResponse GetOtherProfile(MongoId sessionId, GetOtherProfileRequest request)
|
||||
{
|
||||
// Find the profile by the account ID, fall back to the current player if we can't find the account
|
||||
var profileToView = profileHelper.GetFullProfileByAccountId(request.AccountId);
|
||||
if (
|
||||
profileToView?.CharacterData?.PmcData is null
|
||||
|| profileToView.CharacterData.ScavData is null
|
||||
)
|
||||
if (profileToView?.CharacterData?.PmcData is null || profileToView.CharacterData.ScavData is null)
|
||||
{
|
||||
logger.Warning(
|
||||
$"Unable to get profile: {request.AccountId} to show, falling back to own profile"
|
||||
);
|
||||
logger.Warning($"Unable to get profile: {request.AccountId} to show, falling back to own profile");
|
||||
profileToView = profileHelper.GetFullProfile(sessionId);
|
||||
}
|
||||
|
||||
@@ -312,16 +283,12 @@ public class ProfileController(
|
||||
hideoutKeys.Add(profileToViewPmc.Inventory.HideoutCustomizationStashId);
|
||||
|
||||
// Find hideout items e.g. posters
|
||||
var hideoutRootItems = profileToViewPmc.Inventory.Items.Where(x =>
|
||||
hideoutKeys.Contains(x.Id)
|
||||
);
|
||||
var hideoutRootItems = profileToViewPmc.Inventory.Items.Where(x => hideoutKeys.Contains(x.Id));
|
||||
var itemsToReturn = new List<Item>();
|
||||
foreach (var rootItems in hideoutRootItems)
|
||||
{
|
||||
// Check each root items for children and add
|
||||
var itemWithChildren = profileToViewPmc.Inventory.Items.GetItemWithChildren(
|
||||
rootItems.Id
|
||||
);
|
||||
var itemWithChildren = profileToViewPmc.Inventory.Items.GetItemWithChildren(rootItems.Id);
|
||||
itemsToReturn.AddRange(itemWithChildren);
|
||||
}
|
||||
|
||||
@@ -334,9 +301,7 @@ public class ProfileController(
|
||||
Nickname = profileToViewPmc.Info.Nickname,
|
||||
Side = profileToViewPmc.Info.Side,
|
||||
Experience = profileToViewPmc.Info.Experience,
|
||||
MemberCategory = (int)(
|
||||
profileToViewPmc.Info.MemberCategory ?? MemberCategory.Default
|
||||
),
|
||||
MemberCategory = (int)(profileToViewPmc.Info.MemberCategory ?? MemberCategory.Default),
|
||||
BannedState = profileToViewPmc.Info.BannedState,
|
||||
BannedUntil = profileToViewPmc.Info.BannedUntil,
|
||||
RegistrationDate = profileToViewPmc.Info.RegistrationDate,
|
||||
@@ -351,11 +316,7 @@ public class ProfileController(
|
||||
Voice = profileToViewPmc.Customization.Voice,
|
||||
},
|
||||
Skills = profileToViewPmc.Skills,
|
||||
Equipment = new OtherProfileEquipment
|
||||
{
|
||||
Id = profileToViewPmc.Inventory.Equipment,
|
||||
Items = profileToViewPmc.Inventory.Items,
|
||||
},
|
||||
Equipment = new OtherProfileEquipment { Id = profileToViewPmc.Inventory.Equipment, Items = profileToViewPmc.Inventory.Items },
|
||||
Achievements = profileToViewPmc.Achievements,
|
||||
FavoriteItems = profileHelper.GetOtherProfileFavorites(profileToViewPmc),
|
||||
PmcStats = new OtherProfileStats
|
||||
|
||||
@@ -50,19 +50,13 @@ public class QuestController(
|
||||
/// <param name="acceptedQuest">Quest accepted</param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse AcceptQuest(
|
||||
PmcData pmcData,
|
||||
AcceptQuestRequestData acceptedQuest,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse AcceptQuest(PmcData pmcData, AcceptQuestRequestData acceptedQuest, MongoId sessionID)
|
||||
{
|
||||
var acceptQuestResponse = eventOutputHolder.GetOutput(sessionID);
|
||||
|
||||
// Does quest exist in profile
|
||||
// Restarting a failed quest can mean quest exists in profile
|
||||
var existingQuestStatus = pmcData.Quests.FirstOrDefault(x =>
|
||||
x.QId == acceptedQuest.QuestId
|
||||
);
|
||||
var existingQuestStatus = pmcData.Quests.FirstOrDefault(x => x.QId == acceptedQuest.QuestId);
|
||||
if (existingQuestStatus is not null)
|
||||
{
|
||||
// Update existing
|
||||
@@ -74,11 +68,7 @@ public class QuestController(
|
||||
else
|
||||
{
|
||||
// Add new quest to server profile
|
||||
var newQuest = questHelper.GetQuestReadyForProfile(
|
||||
pmcData,
|
||||
QuestStatusEnum.Started,
|
||||
acceptedQuest
|
||||
);
|
||||
var newQuest = questHelper.GetQuestReadyForProfile(pmcData, QuestStatusEnum.Started, acceptedQuest);
|
||||
pmcData.Quests.Add(newQuest);
|
||||
}
|
||||
|
||||
@@ -88,18 +78,11 @@ public class QuestController(
|
||||
|
||||
if (questFromDb.Conditions?.AvailableForFinish is not null)
|
||||
{
|
||||
AddTaskConditionCountersToProfile(
|
||||
questFromDb.Conditions.AvailableForFinish,
|
||||
pmcData,
|
||||
acceptedQuest.QuestId
|
||||
);
|
||||
AddTaskConditionCountersToProfile(questFromDb.Conditions.AvailableForFinish, pmcData, acceptedQuest.QuestId);
|
||||
}
|
||||
|
||||
// Get messageId of text to send to player as text message in game
|
||||
var messageId = questHelper.GetMessageIdForQuestStart(
|
||||
questFromDb.StartedMessageText,
|
||||
questFromDb.Description
|
||||
);
|
||||
var messageId = questHelper.GetMessageIdForQuestStart(questFromDb.StartedMessageText, questFromDb.Description);
|
||||
|
||||
// Apply non-item rewards to profile + return item rewards
|
||||
var startedQuestRewardItems = questRewardHelper.ApplyQuestReward(
|
||||
@@ -117,16 +100,11 @@ public class QuestController(
|
||||
MessageType.QuestStart,
|
||||
messageId,
|
||||
startedQuestRewardItems.ToList(),
|
||||
timeUtil.GetHoursAsSeconds(
|
||||
(int)questHelper.GetMailItemRedeemTimeHoursForProfile(pmcData)
|
||||
)
|
||||
timeUtil.GetHoursAsSeconds((int)questHelper.GetMailItemRedeemTimeHoursForProfile(pmcData))
|
||||
);
|
||||
|
||||
// Having accepted new quest, look for newly unlocked quests and inform client of them
|
||||
var newlyAccessibleQuests = questHelper.GetNewlyAccessibleQuestsWhenStartingQuest(
|
||||
acceptedQuest.QuestId,
|
||||
sessionID
|
||||
);
|
||||
var newlyAccessibleQuests = questHelper.GetNewlyAccessibleQuestsWhenStartingQuest(acceptedQuest.QuestId, sessionID);
|
||||
if (newlyAccessibleQuests.Count > 0)
|
||||
{
|
||||
acceptQuestResponse.ProfileChanges[sessionID].Quests.AddRange(newlyAccessibleQuests);
|
||||
@@ -142,17 +120,9 @@ public class QuestController(
|
||||
/// <param name="questConditionsToAdd">Conditions to iterate over and possibly add to profile</param>
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <param name="questId">Quest where conditions originated</param>
|
||||
protected void AddTaskConditionCountersToProfile(
|
||||
IEnumerable<QuestCondition> questConditionsToAdd,
|
||||
PmcData pmcData,
|
||||
MongoId questId
|
||||
)
|
||||
protected void AddTaskConditionCountersToProfile(IEnumerable<QuestCondition> questConditionsToAdd, PmcData pmcData, MongoId questId)
|
||||
{
|
||||
foreach (
|
||||
var condition in questConditionsToAdd.Where(condition =>
|
||||
condition.ConditionType == "SellItemToTrader"
|
||||
)
|
||||
)
|
||||
foreach (var condition in questConditionsToAdd.Where(condition => condition.ConditionType == "SellItemToTrader"))
|
||||
{
|
||||
if (pmcData.TaskConditionCounters.TryGetValue(condition.Id, out _))
|
||||
{
|
||||
@@ -185,11 +155,7 @@ public class QuestController(
|
||||
/// <param name="request">Complete quest request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse CompleteQuest(
|
||||
PmcData pmcData,
|
||||
CompleteQuestRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse CompleteQuest(PmcData pmcData, CompleteQuestRequestData request, MongoId sessionId)
|
||||
{
|
||||
return questHelper.CompleteQuest(pmcData, request, sessionId);
|
||||
}
|
||||
@@ -202,11 +168,7 @@ public class QuestController(
|
||||
/// <param name="request">Handover request</param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse HandoverQuest(
|
||||
PmcData pmcData,
|
||||
HandoverQuestRequestData request,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse HandoverQuest(PmcData pmcData, HandoverQuestRequestData request, MongoId sessionID)
|
||||
{
|
||||
var quest = questHelper.GetQuestFromDb(request.QuestId, pmcData);
|
||||
HashSet<string> handoverQuestTypes = ["HandoverItem", "WeaponAssembly"];
|
||||
@@ -217,11 +179,7 @@ public class QuestController(
|
||||
|
||||
// Decrement number of items handed in
|
||||
QuestCondition? handoverRequirements = null;
|
||||
foreach (
|
||||
var condition in quest.Conditions.AvailableForFinish.Where(condition =>
|
||||
condition.Id == request.ConditionId
|
||||
)
|
||||
)
|
||||
foreach (var condition in quest.Conditions.AvailableForFinish.Where(condition => condition.Id == request.ConditionId))
|
||||
{
|
||||
// Not a handover quest type, skip
|
||||
if (!handoverQuestTypes.Contains(condition.ConditionType))
|
||||
@@ -261,51 +219,26 @@ public class QuestController(
|
||||
|
||||
if (isItemHandoverQuest && handedInCount == 0)
|
||||
{
|
||||
return ShowRepeatableQuestInvalidConditionError(
|
||||
request.QuestId,
|
||||
request.ConditionId,
|
||||
output
|
||||
);
|
||||
return ShowRepeatableQuestInvalidConditionError(request.QuestId, request.ConditionId, output);
|
||||
}
|
||||
|
||||
var totalItemCountToRemove = 0d;
|
||||
foreach (var itemHandover in request.Items)
|
||||
{
|
||||
var matchingItemInProfile = pmcData.Inventory.Items.FirstOrDefault(item =>
|
||||
item.Id == itemHandover.Id
|
||||
);
|
||||
if (
|
||||
!(
|
||||
matchingItemInProfile is not null
|
||||
&& handoverRequirements.Target.List.Contains(matchingItemInProfile.Template)
|
||||
)
|
||||
)
|
||||
var matchingItemInProfile = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == itemHandover.Id);
|
||||
if (!(matchingItemInProfile is not null && handoverRequirements.Target.List.Contains(matchingItemInProfile.Template)))
|
||||
// Item handed in by player doesn't match what was requested
|
||||
{
|
||||
return ShowQuestItemHandoverMatchError(
|
||||
request,
|
||||
matchingItemInProfile,
|
||||
handoverRequirements,
|
||||
output
|
||||
);
|
||||
return ShowQuestItemHandoverMatchError(request, matchingItemInProfile, handoverRequirements, output);
|
||||
}
|
||||
|
||||
// Remove the right quantity of given items
|
||||
var itemCountToRemove = Math.Min(
|
||||
itemHandover.Count ?? 0,
|
||||
handedInCount - totalItemCountToRemove
|
||||
);
|
||||
var itemCountToRemove = Math.Min(itemHandover.Count ?? 0, handedInCount - totalItemCountToRemove);
|
||||
totalItemCountToRemove += itemCountToRemove;
|
||||
if (itemHandover.Count - itemCountToRemove > 0)
|
||||
{
|
||||
// Remove single item with no children
|
||||
questHelper.ChangeItemStack(
|
||||
pmcData,
|
||||
itemHandover.Id,
|
||||
(int)(itemHandover.Count - itemCountToRemove),
|
||||
sessionID,
|
||||
output
|
||||
);
|
||||
questHelper.ChangeItemStack(pmcData, itemHandover.Id, (int)(itemHandover.Count - itemCountToRemove), sessionID, output);
|
||||
|
||||
// Complete - handedInCount == totalItemCountToRemove
|
||||
if (Math.Abs(totalItemCountToRemove - handedInCount) < 0.01)
|
||||
@@ -316,15 +249,11 @@ public class QuestController(
|
||||
else
|
||||
{
|
||||
// Remove item with children
|
||||
var toRemove = pmcData
|
||||
.Inventory.Items.GetItemWithChildrenTpls(itemHandover.Id)
|
||||
.ToHashSet();
|
||||
var toRemove = pmcData.Inventory.Items.GetItemWithChildrenTpls(itemHandover.Id).ToHashSet();
|
||||
var index = pmcData.Inventory.Items.Count;
|
||||
|
||||
// Important: don't tell the client to remove the attachments, it will handle it
|
||||
output
|
||||
.ProfileChanges[sessionID]
|
||||
.Items.DeletedItems.Add(new DeletedItem { Id = itemHandover.Id });
|
||||
output.ProfileChanges[sessionID].Items.DeletedItems.Add(new DeletedItem { Id = itemHandover.Id });
|
||||
|
||||
// Important: loop backward when removing items from the array we're looping on
|
||||
while (index-- > 0)
|
||||
@@ -339,9 +268,7 @@ public class QuestController(
|
||||
// element `location` properties of the parent so they are sequential, while retaining order
|
||||
if (removedItem.Location?.GetType() == typeof(int))
|
||||
{
|
||||
var childItems = pmcData.Inventory.Items.GetItemWithChildren(
|
||||
removedItem.ParentId
|
||||
);
|
||||
var childItems = pmcData.Inventory.Items.GetItemWithChildren(removedItem.ParentId);
|
||||
childItems.RemoveAt(0); // Remove the parent
|
||||
|
||||
// Sort by the current `location` and update
|
||||
@@ -357,12 +284,7 @@ public class QuestController(
|
||||
}
|
||||
}
|
||||
|
||||
UpdateProfileTaskConditionCounterValue(
|
||||
pmcData,
|
||||
request.ConditionId,
|
||||
request.QuestId,
|
||||
totalItemCountToRemove
|
||||
);
|
||||
UpdateProfileTaskConditionCounterValue(pmcData, request.ConditionId, request.QuestId, totalItemCountToRemove);
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -426,12 +348,7 @@ public class QuestController(
|
||||
/// <param name="conditionId">Backend counter id to update</param>
|
||||
/// <param name="questId">Quest id counter is associated with</param>
|
||||
/// <param name="counterValue">Value to increment the backend counter with</param>
|
||||
protected void UpdateProfileTaskConditionCounterValue(
|
||||
PmcData pmcData,
|
||||
MongoId conditionId,
|
||||
MongoId questId,
|
||||
double counterValue
|
||||
)
|
||||
protected void UpdateProfileTaskConditionCounterValue(PmcData pmcData, MongoId conditionId, MongoId questId, double counterValue)
|
||||
{
|
||||
if (pmcData.TaskConditionCounters.GetValueOrDefault(conditionId) != null)
|
||||
{
|
||||
|
||||
@@ -62,8 +62,7 @@ public class RagfairController(
|
||||
var pmcProfile = profile.CharacterData.PmcData;
|
||||
if (
|
||||
pmcProfile.RagfairInfo is not null
|
||||
&& pmcProfile.Info.Level
|
||||
>= databaseService.GetGlobals().Configuration.RagFair.MinUserLevel
|
||||
&& pmcProfile.Info.Level >= databaseService.GetGlobals().Configuration.RagFair.MinUserLevel
|
||||
)
|
||||
{
|
||||
ragfairOfferHelper.ProcessOffersOnProfile(sessionId);
|
||||
@@ -91,21 +90,12 @@ public class RagfairController(
|
||||
};
|
||||
|
||||
// Get all offers ready for sorting/filtering below
|
||||
result.Offers = GetOffersForSearchType(
|
||||
searchRequest,
|
||||
itemsToAdd,
|
||||
traderAssorts,
|
||||
profile.CharacterData.PmcData
|
||||
);
|
||||
result.Offers = GetOffersForSearchType(searchRequest, itemsToAdd, traderAssorts, profile.CharacterData.PmcData);
|
||||
|
||||
// Client requested a category refresh
|
||||
if (searchRequest.UpdateOfferCount.GetValueOrDefault(false))
|
||||
{
|
||||
result.Categories = GetSpecificCategories(
|
||||
profile.CharacterData.PmcData,
|
||||
searchRequest,
|
||||
result.Offers
|
||||
);
|
||||
result.Categories = GetSpecificCategories(profile.CharacterData.PmcData, searchRequest, result.Offers);
|
||||
}
|
||||
|
||||
// Adjust index value of offers found to start at 0
|
||||
@@ -217,10 +207,7 @@ public class RagfairController(
|
||||
var assortId = offerRootItem.Id;
|
||||
|
||||
// No trader found in profile, create a blank record for them
|
||||
var existsInProfile = !fullProfile.TraderPurchases.TryAdd(
|
||||
offer.User.Id,
|
||||
new Dictionary<MongoId, TraderPurchaseData>()
|
||||
);
|
||||
var existsInProfile = !fullProfile.TraderPurchases.TryAdd(offer.User.Id, new Dictionary<MongoId, TraderPurchaseData>());
|
||||
if (!existsInProfile)
|
||||
{
|
||||
// Not purchased by player before, use value from assort data
|
||||
@@ -266,16 +253,10 @@ public class RagfairController(
|
||||
/// <param name="searchRequest">Client search request data</param>
|
||||
/// <param name="offers">Ragfair offers to get categories for</param>
|
||||
/// <returns>Record with templates + counts</returns>
|
||||
protected Dictionary<MongoId, int> GetSpecificCategories(
|
||||
PmcData pmcProfile,
|
||||
SearchRequestData searchRequest,
|
||||
List<RagfairOffer> offers
|
||||
)
|
||||
protected Dictionary<MongoId, int> GetSpecificCategories(PmcData pmcProfile, SearchRequestData searchRequest, List<RagfairOffer> offers)
|
||||
{
|
||||
// Linked/required search categories
|
||||
var playerHasFleaUnlocked =
|
||||
pmcProfile.Info.Level
|
||||
>= databaseService.GetGlobals().Configuration.RagFair.MinUserLevel;
|
||||
var playerHasFleaUnlocked = pmcProfile.Info.Level >= databaseService.GetGlobals().Configuration.RagFair.MinUserLevel;
|
||||
List<RagfairOffer> offerPool;
|
||||
if (IsLinkedSearch(searchRequest) || IsRequiredSearch(searchRequest))
|
||||
{
|
||||
@@ -297,11 +278,7 @@ public class RagfairController(
|
||||
return [];
|
||||
}
|
||||
|
||||
return ragfairServer.GetAllActiveCategories(
|
||||
playerHasFleaUnlocked,
|
||||
searchRequest,
|
||||
offerPool
|
||||
);
|
||||
return ragfairServer.GetAllActiveCategories(playerHasFleaUnlocked, searchRequest, offerPool);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -342,12 +319,7 @@ public class RagfairController(
|
||||
// Searching for items in preset menu
|
||||
if (searchRequest.BuildCount > 0)
|
||||
{
|
||||
return ragfairOfferHelper.GetOffersForBuild(
|
||||
searchRequest,
|
||||
itemsToAdd,
|
||||
traderAssorts,
|
||||
pmcProfile
|
||||
);
|
||||
return ragfairOfferHelper.GetOffersForBuild(searchRequest, itemsToAdd, traderAssorts, pmcProfile);
|
||||
}
|
||||
|
||||
if (searchRequest.NeededSearchId != null && !searchRequest.NeededSearchId.Value.IsEmpty())
|
||||
@@ -356,12 +328,7 @@ public class RagfairController(
|
||||
}
|
||||
|
||||
// Searching for general items
|
||||
return ragfairOfferHelper.GetValidOffers(
|
||||
searchRequest,
|
||||
itemsToAdd,
|
||||
traderAssorts,
|
||||
pmcProfile
|
||||
);
|
||||
return ragfairOfferHelper.GetValidOffers(searchRequest, itemsToAdd, traderAssorts, pmcProfile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -370,10 +337,7 @@ public class RagfairController(
|
||||
/// <param name="getPriceRequest">Client request object</param>
|
||||
/// <param name="ignoreTraderOffers">OPTIONAL - Should trader offers be ignored in the calculation</param>
|
||||
/// <returns>min/avg/max values for an item based on flea offers available</returns>
|
||||
public GetItemPriceResult GetItemMinAvgMaxFleaPriceValues(
|
||||
GetMarketPriceRequestData getPriceRequest,
|
||||
bool ignoreTraderOffers = true
|
||||
)
|
||||
public GetItemPriceResult GetItemMinAvgMaxFleaPriceValues(GetMarketPriceRequestData getPriceRequest, bool ignoreTraderOffers = true)
|
||||
{
|
||||
// Get all items of tpl
|
||||
var offers = ragfairOfferService.GetOffersOfType(getPriceRequest.TemplateId);
|
||||
@@ -411,11 +375,7 @@ public class RagfairController(
|
||||
};
|
||||
}
|
||||
|
||||
protected double GetAveragePriceFromOffers(
|
||||
IEnumerable<RagfairOffer> offers,
|
||||
MinMax<double> minMax,
|
||||
bool ignoreTraderOffers
|
||||
)
|
||||
protected double GetAveragePriceFromOffers(IEnumerable<RagfairOffer> offers, MinMax<double> minMax, bool ignoreTraderOffers)
|
||||
{
|
||||
var sum = 0d;
|
||||
var totalOfferCount = 0;
|
||||
@@ -434,9 +394,7 @@ public class RagfairController(
|
||||
}
|
||||
|
||||
// Figure out how many items the requirementsCost is applying to, and what the per-item price is
|
||||
var offerItemCount = offer.SellInOnePiece.GetValueOrDefault(false)
|
||||
? offer.Items.First().Upd?.StackObjectsCount ?? 1
|
||||
: 1;
|
||||
var offerItemCount = offer.SellInOnePiece.GetValueOrDefault(false) ? offer.Items.First().Upd?.StackObjectsCount ?? 1 : 1;
|
||||
var perItemPrice = offer.RequirementsCost / offerItemCount;
|
||||
|
||||
// Handle min/max calculations based on the per-item price
|
||||
@@ -468,30 +426,20 @@ public class RagfairController(
|
||||
/// <param name="offerRequest">Flea list creation offer</param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse AddPlayerOffer(
|
||||
PmcData pmcData,
|
||||
AddOfferRequestData offerRequest,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse AddPlayerOffer(PmcData pmcData, AddOfferRequestData offerRequest, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionID);
|
||||
|
||||
if (!IsValidPlayerOfferRequest(offerRequest))
|
||||
{
|
||||
return httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
"Unable to add offer, check server for error"
|
||||
);
|
||||
return httpResponseUtil.AppendErrorToOutput(output, "Unable to add offer, check server for error");
|
||||
}
|
||||
|
||||
var typeOfOffer = GetOfferType(offerRequest);
|
||||
if (typeOfOffer == FleaOfferType.UNKNOWN)
|
||||
{
|
||||
return httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
$"Unknown offer type: {typeOfOffer}, cannot list item on flea"
|
||||
);
|
||||
return httpResponseUtil.AppendErrorToOutput(output, $"Unknown offer type: {typeOfOffer}, cannot list item on flea");
|
||||
}
|
||||
|
||||
switch (typeOfOffer)
|
||||
@@ -504,10 +452,7 @@ public class RagfairController(
|
||||
return CreatePackOffer(sessionID, offerRequest, fullProfile, output);
|
||||
case FleaOfferType.UNKNOWN:
|
||||
default:
|
||||
return httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
$"Unknown offer type: {typeOfOffer}, cannot list item on flea"
|
||||
);
|
||||
return httpResponseUtil.AppendErrorToOutput(output, $"Unknown offer type: {typeOfOffer}, cannot list item on flea");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,9 +472,7 @@ public class RagfairController(
|
||||
|
||||
if (offerRequest.Requirements is null)
|
||||
{
|
||||
logger.Error(
|
||||
localisationService.GetText("ragfair-unable_to_place_offer_with_no_requirements")
|
||||
);
|
||||
logger.Error(localisationService.GetText("ragfair-unable_to_place_offer_with_no_requirements"));
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -613,9 +556,7 @@ public class RagfairController(
|
||||
|
||||
// Average offer price for single item (or whole weapon)
|
||||
// MUST occur prior to CreatePlayerOffer(), otherwise offer ends up in averages calculation
|
||||
var averages = GetItemMinAvgMaxFleaPriceValues(
|
||||
new GetMarketPriceRequestData { TemplateId = firstInventoryItem.Template }
|
||||
);
|
||||
var averages = GetItemMinAvgMaxFleaPriceValues(new GetMarketPriceRequestData { TemplateId = firstInventoryItem.Template });
|
||||
|
||||
// Create flea object
|
||||
var offer = CreatePlayerOffer(sessionID, offerRequest.Requirements, inventoryItems, false);
|
||||
@@ -625,12 +566,7 @@ public class RagfairController(
|
||||
|
||||
// Check for and apply item price modifer if it exists in config
|
||||
var averageOfferPrice = averages.Avg;
|
||||
if (
|
||||
_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(
|
||||
rootOfferItem.Template,
|
||||
out var itemPriceModifer
|
||||
)
|
||||
)
|
||||
if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(rootOfferItem.Template, out var itemPriceModifer))
|
||||
{
|
||||
averageOfferPrice *= itemPriceModifer;
|
||||
}
|
||||
@@ -645,11 +581,7 @@ public class RagfairController(
|
||||
var playerListedPriceInRub = CalculateRequirementsPriceInRub(offerRequest.Requirements);
|
||||
|
||||
// Roll sale chance
|
||||
var sellChancePercent = ragfairSellHelper.CalculateSellChance(
|
||||
averageOfferPrice.Value,
|
||||
playerListedPriceInRub,
|
||||
qualityMultiplier
|
||||
);
|
||||
var sellChancePercent = ragfairSellHelper.CalculateSellChance(averageOfferPrice.Value, playerListedPriceInRub, qualityMultiplier);
|
||||
|
||||
// Create array of sell times for items listed
|
||||
offer.SellResults = ragfairSellHelper.RollForSale(sellChancePercent, (int)stackCountTotal);
|
||||
@@ -707,9 +639,7 @@ public class RagfairController(
|
||||
|
||||
// multi-offers are all the same item,
|
||||
// Get first item and its children and use as template
|
||||
var firstInventoryItemAndChildren = pmcData.Inventory.Items.GetItemWithChildren(
|
||||
offerRequest.Items.FirstOrDefault()
|
||||
);
|
||||
var firstInventoryItemAndChildren = pmcData.Inventory.Items.GetItemWithChildren(offerRequest.Items.FirstOrDefault());
|
||||
|
||||
// Find items to be listed on flea (+ children) from player inventory
|
||||
var result = GetItemsToListOnFleaFromInventory(pmcData, offerRequest.Items);
|
||||
@@ -729,29 +659,17 @@ public class RagfairController(
|
||||
|
||||
// Single price for an item
|
||||
// MUST occur prior to CreatePlayerOffer(), otherwise offer ends up in averages calculation
|
||||
var averages = GetItemMinAvgMaxFleaPriceValues(
|
||||
new GetMarketPriceRequestData { TemplateId = firstInventoryItem.Template }
|
||||
);
|
||||
var averages = GetItemMinAvgMaxFleaPriceValues(new GetMarketPriceRequestData { TemplateId = firstInventoryItem.Template });
|
||||
var singleItemPrice = averages.Avg;
|
||||
|
||||
// Create flea object
|
||||
var offer = CreatePlayerOffer(
|
||||
sessionID,
|
||||
offerRequest.Requirements,
|
||||
firstInventoryItemAndChildren,
|
||||
true
|
||||
);
|
||||
var offer = CreatePlayerOffer(sessionID, offerRequest.Requirements, firstInventoryItemAndChildren, true);
|
||||
|
||||
// This is the item that will be listed on flea, has merged stackObjectCount
|
||||
var newRootOfferItem = offer.Items[0]; // TODO: add logic like single/multi offers to find root item
|
||||
|
||||
// Check for and apply item price modifer if it exists in config
|
||||
if (
|
||||
_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(
|
||||
newRootOfferItem.Template,
|
||||
out var itemPriceModifer
|
||||
)
|
||||
)
|
||||
if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(newRootOfferItem.Template, out var itemPriceModifer))
|
||||
{
|
||||
singleItemPrice *= itemPriceModifer;
|
||||
}
|
||||
@@ -773,11 +691,7 @@ public class RagfairController(
|
||||
);
|
||||
|
||||
// Create array of sell times for items listed + sell all at once as it's a pack
|
||||
offer.SellResults = ragfairSellHelper.RollForSale(
|
||||
sellChancePercent,
|
||||
(int)stackCountTotal,
|
||||
true
|
||||
);
|
||||
offer.SellResults = ragfairSellHelper.RollForSale(sellChancePercent, (int)stackCountTotal, true);
|
||||
|
||||
// Subtract flea market fee from stash
|
||||
if (_ragfairConfig.Sell.Fees)
|
||||
@@ -831,10 +745,7 @@ public class RagfairController(
|
||||
|
||||
// Find items to be listed on flea from player inventory
|
||||
var inventoryItemsToSell = GetItemsToListOnFleaFromInventory(pmcData, offerRequest.Items);
|
||||
if (
|
||||
inventoryItemsToSell.Items is null
|
||||
|| !string.IsNullOrEmpty(inventoryItemsToSell.ErrorMessage)
|
||||
)
|
||||
if (inventoryItemsToSell.Items is null || !string.IsNullOrEmpty(inventoryItemsToSell.ErrorMessage))
|
||||
{
|
||||
httpResponseUtil.AppendErrorToOutput(output, inventoryItemsToSell.ErrorMessage);
|
||||
}
|
||||
@@ -846,9 +757,7 @@ public class RagfairController(
|
||||
|
||||
// Average offer price for single item (or whole weapon)
|
||||
// MUST occur prior to CreatePlayerOffer(), otherwise offer ends up in averages calculation
|
||||
var averages = GetItemMinAvgMaxFleaPriceValues(
|
||||
new GetMarketPriceRequestData { TemplateId = firstItemToSell.Template }
|
||||
);
|
||||
var averages = GetItemMinAvgMaxFleaPriceValues(new GetMarketPriceRequestData { TemplateId = firstItemToSell.Template });
|
||||
var averageOfferPriceSingleItem = averages.Avg;
|
||||
|
||||
// Checks are done, create offer
|
||||
@@ -866,12 +775,7 @@ public class RagfairController(
|
||||
var qualityMultiplier = itemHelper.GetItemQualityModifierForItems(offer.Items, true);
|
||||
|
||||
// Check for and apply item price modifer if it exists in config
|
||||
if (
|
||||
_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(
|
||||
offerRootItem.Template,
|
||||
out var itemPriceModifer
|
||||
)
|
||||
)
|
||||
if (_ragfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(offerRootItem.Template, out var itemPriceModifer))
|
||||
{
|
||||
averageOfferPriceSingleItem *= itemPriceModifer;
|
||||
}
|
||||
@@ -941,9 +845,7 @@ public class RagfairController(
|
||||
{
|
||||
// Get tax from cache hydrated earlier by client, if that's missing fall back to server calculation (inaccurate)
|
||||
var requestRootItemId = offerRequest.Items.FirstOrDefault();
|
||||
var storedClientTaxValue = ragfairTaxService.GetStoredClientOfferTaxValueById(
|
||||
requestRootItemId
|
||||
);
|
||||
var storedClientTaxValue = ragfairTaxService.GetStoredClientOfferTaxValueById(requestRootItemId);
|
||||
var tax = storedClientTaxValue is not null
|
||||
? storedClientTaxValue.Fee
|
||||
: ragfairTaxService.CalculateTax(
|
||||
@@ -956,9 +858,7 @@ public class RagfairController(
|
||||
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug(
|
||||
$"Offer tax to charge: {tax}, pulled from client: {storedClientTaxValue.Count is not null}"
|
||||
);
|
||||
logger.Debug($"Offer tax to charge: {tax}, pulled from client: {storedClientTaxValue.Count is not null}");
|
||||
}
|
||||
|
||||
// Cleanup of cache now we've used the tax value from it
|
||||
@@ -968,10 +868,7 @@ public class RagfairController(
|
||||
paymentService.PayMoney(pmcData, buyTradeRequest, sessionId, output);
|
||||
if (output.Warnings.Count > 0)
|
||||
{
|
||||
httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
localisationService.GetText("ragfair-unable_to_pay_commission_fee", tax)
|
||||
);
|
||||
httpResponseUtil.AppendErrorToOutput(output, localisationService.GetText("ragfair-unable_to_pay_commission_fee", tax));
|
||||
return true; // Fee failed
|
||||
}
|
||||
|
||||
@@ -986,12 +883,7 @@ public class RagfairController(
|
||||
/// <param name="items">Item(s) to list on flea (with children)</param>
|
||||
/// <param name="sellInOnePiece">Is this a pack offer</param>
|
||||
/// <returns>RagfairOffer</returns>
|
||||
protected RagfairOffer CreatePlayerOffer(
|
||||
MongoId sessionId,
|
||||
List<Requirement> requirements,
|
||||
List<Item> items,
|
||||
bool sellInOnePiece
|
||||
)
|
||||
protected RagfairOffer CreatePlayerOffer(MongoId sessionId, List<Requirement> requirements, List<Item> items, bool sellInOnePiece)
|
||||
{
|
||||
const int loyalLevel = 1;
|
||||
var formattedItems = items.Select(item =>
|
||||
@@ -1039,19 +931,14 @@ public class RagfairController(
|
||||
{
|
||||
return requirements.Sum(requirement =>
|
||||
{
|
||||
if (
|
||||
requirement.Template.IsEmpty()
|
||||
|| !requirement.Count.HasValue
|
||||
|| requirement.Count == 0
|
||||
)
|
||||
if (requirement.Template.IsEmpty() || !requirement.Count.HasValue || requirement.Count == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return paymentHelper.IsMoneyTpl(requirement.Template)
|
||||
? handbookHelper.InRUB(requirement.Count.Value, requirement.Template)
|
||||
: itemHelper.GetDynamicItemPrice(requirement.Template).Value
|
||||
* requirement.Count.Value;
|
||||
: itemHelper.GetDynamicItemPrice(requirement.Template).Value * requirement.Count.Value;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1075,17 +962,10 @@ public class RagfairController(
|
||||
var rootItem = pmcData.Inventory?.Items?.FirstOrDefault(i => i.Id == itemId);
|
||||
if (rootItem is null)
|
||||
{
|
||||
errorMessage = localisationService.GetText(
|
||||
"ragfair-unable_to_find_item_in_inventory",
|
||||
new { id = itemId.ToString() }
|
||||
);
|
||||
errorMessage = localisationService.GetText("ragfair-unable_to_find_item_in_inventory", new { id = itemId.ToString() });
|
||||
logger.Error(errorMessage);
|
||||
|
||||
return new GetItemsToListOnFleaFromInventoryResult
|
||||
{
|
||||
Items = itemsToReturn,
|
||||
ErrorMessage = errorMessage,
|
||||
};
|
||||
return new GetItemsToListOnFleaFromInventoryResult { Items = itemsToReturn, ErrorMessage = errorMessage };
|
||||
}
|
||||
|
||||
rootItem.FixItemStackCount();
|
||||
@@ -1095,19 +975,13 @@ public class RagfairController(
|
||||
|
||||
if (itemsToReturn.Count == 0)
|
||||
{
|
||||
errorMessage = localisationService.GetText(
|
||||
"ragfair-unable_to_find_requested_items_in_inventory"
|
||||
);
|
||||
errorMessage = localisationService.GetText("ragfair-unable_to_find_requested_items_in_inventory");
|
||||
logger.Error(errorMessage);
|
||||
|
||||
return new GetItemsToListOnFleaFromInventoryResult { ErrorMessage = errorMessage };
|
||||
}
|
||||
|
||||
return new GetItemsToListOnFleaFromInventoryResult
|
||||
{
|
||||
Items = itemsToReturn,
|
||||
ErrorMessage = errorMessage,
|
||||
};
|
||||
return new GetItemsToListOnFleaFromInventoryResult { Items = itemsToReturn, ErrorMessage = errorMessage };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1126,10 +1000,7 @@ public class RagfairController(
|
||||
if (playerProfileOffers is null)
|
||||
{
|
||||
logger.Warning(
|
||||
localisationService.GetText(
|
||||
"ragfair-unable_to_remove_offer_not_found_in_profile",
|
||||
new { profileId = sessionId, offerId }
|
||||
)
|
||||
localisationService.GetText("ragfair-unable_to_remove_offer_not_found_in_profile", new { profileId = sessionId, offerId })
|
||||
);
|
||||
|
||||
pmcData.RagfairInfo.Offers = [];
|
||||
@@ -1138,14 +1009,9 @@ public class RagfairController(
|
||||
var playerOffer = playerProfileOffers?.FirstOrDefault(x => x.Id == offerId);
|
||||
if (playerOffer is null)
|
||||
{
|
||||
logger.Error(
|
||||
localisationService.GetText("ragfair-offer_not_found_in_profile", new { offerId })
|
||||
);
|
||||
logger.Error(localisationService.GetText("ragfair-offer_not_found_in_profile", new { offerId }));
|
||||
|
||||
return httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
localisationService.GetText("ragfair-offer_not_found_in_profile_short")
|
||||
);
|
||||
return httpResponseUtil.AppendErrorToOutput(output, localisationService.GetText("ragfair-offer_not_found_in_profile_short"));
|
||||
}
|
||||
|
||||
// Only reduce time to end if time remaining is greater than what we would set it to
|
||||
@@ -1157,9 +1023,7 @@ public class RagfairController(
|
||||
playerOffer.EndTime = (long?)Math.Round((double)newEndTime);
|
||||
}
|
||||
|
||||
logger.Debug(
|
||||
$"Flagged player offer: {offerId} for expiry in: {TimeSpan.FromTicks(playerOffer.EndTime.Value).ToString()}"
|
||||
);
|
||||
logger.Debug($"Flagged player offer: {offerId} for expiry in: {TimeSpan.FromTicks(playerOffer.EndTime.Value).ToString()}");
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -1170,10 +1034,7 @@ public class RagfairController(
|
||||
/// <param name="extendRequest">Extend time request</param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse ExtendOffer(
|
||||
ExtendOfferRequestData extendRequest,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse ExtendOffer(ExtendOfferRequestData extendRequest, MongoId sessionId)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionId);
|
||||
|
||||
@@ -1184,16 +1045,8 @@ public class RagfairController(
|
||||
|
||||
if (playerOfferIndex == -1)
|
||||
{
|
||||
logger.Warning(
|
||||
localisationService.GetText(
|
||||
"ragfair-offer_not_found_in_profile",
|
||||
new { offerId = extendRequest.OfferId }
|
||||
)
|
||||
);
|
||||
return httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
localisationService.GetText("ragfair-offer_not_found_in_profile_short")
|
||||
);
|
||||
logger.Warning(localisationService.GetText("ragfair-offer_not_found_in_profile", new { offerId = extendRequest.OfferId }));
|
||||
return httpResponseUtil.AppendErrorToOutput(output, localisationService.GetText("ragfair-offer_not_found_in_profile_short"));
|
||||
}
|
||||
|
||||
var playerOffer = playerOffers[playerOfferIndex];
|
||||
@@ -1205,8 +1058,7 @@ public class RagfairController(
|
||||
var sellInOncePiece = playerOffer.SellInOnePiece.GetValueOrDefault(false);
|
||||
if (!sellInOncePiece)
|
||||
{
|
||||
count = (int)
|
||||
playerOffer.Items.Sum(offerItem => offerItem.Upd?.StackObjectsCount ?? 0);
|
||||
count = (int)playerOffer.Items.Sum(offerItem => offerItem.Upd?.StackObjectsCount ?? 0);
|
||||
}
|
||||
|
||||
var tax = ragfairTaxService.CalculateTax(
|
||||
@@ -1221,10 +1073,7 @@ public class RagfairController(
|
||||
paymentService.PayMoney(pmcData, request, sessionId, output);
|
||||
if (output.Warnings.Count > 0)
|
||||
{
|
||||
return httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
localisationService.GetText("ragfair-unable_to_pay_commission_fee")
|
||||
);
|
||||
return httpResponseUtil.AppendErrorToOutput(output, localisationService.GetText("ragfair-unable_to_pay_commission_fee"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1240,19 +1089,13 @@ public class RagfairController(
|
||||
/// <param name="currency">What currency: RUB, EURO, USD</param>
|
||||
/// <param name="value">Amount of currency</param>
|
||||
/// <returns>ProcessBuyTradeRequestData</returns>
|
||||
protected ProcessBuyTradeRequestData CreateBuyTradeRequestObject(
|
||||
CurrencyType currency,
|
||||
double value
|
||||
)
|
||||
protected ProcessBuyTradeRequestData CreateBuyTradeRequestObject(CurrencyType currency, double value)
|
||||
{
|
||||
return new ProcessBuyTradeRequestData
|
||||
{
|
||||
TransactionId = "ragfair",
|
||||
Action = "TradingConfirm",
|
||||
SchemeItems =
|
||||
[
|
||||
new IdWithCount { Id = currency.GetCurrencyTpl(), Count = Math.Round(value) },
|
||||
],
|
||||
SchemeItems = [new IdWithCount { Id = currency.GetCurrencyTpl(), Count = Math.Round(value) }],
|
||||
Type = "",
|
||||
ItemId = MongoId.Empty(),
|
||||
Count = 0,
|
||||
|
||||
@@ -19,32 +19,16 @@ public class RepairController(EventOutputHolder eventOutputHolder, RepairService
|
||||
/// <param name="request">endpoint request data</param>
|
||||
/// <param name="pmcData">player profile</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse TraderRepair(
|
||||
MongoId sessionID,
|
||||
TraderRepairActionDataRequest request,
|
||||
PmcData pmcData
|
||||
)
|
||||
public ItemEventRouterResponse TraderRepair(MongoId sessionID, TraderRepairActionDataRequest request, PmcData pmcData)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
|
||||
// find the item to repair
|
||||
foreach (var repairItem in request.RepairItems)
|
||||
{
|
||||
var repairDetails = repairService.RepairItemByTrader(
|
||||
sessionID,
|
||||
pmcData,
|
||||
repairItem,
|
||||
request.TraderId
|
||||
);
|
||||
var repairDetails = repairService.RepairItemByTrader(sessionID, pmcData, repairItem, request.TraderId);
|
||||
|
||||
repairService.PayForRepair(
|
||||
sessionID,
|
||||
pmcData,
|
||||
repairItem.Id,
|
||||
repairDetails.RepairCost.Value,
|
||||
request.TraderId,
|
||||
output
|
||||
);
|
||||
repairService.PayForRepair(sessionID, pmcData, repairItem.Id, repairDetails.RepairCost.Value, request.TraderId, output);
|
||||
|
||||
if (output.Warnings?.Count > 0)
|
||||
{
|
||||
@@ -69,22 +53,12 @@ public class RepairController(EventOutputHolder eventOutputHolder, RepairService
|
||||
/// <param name="body">endpoint request data</param>
|
||||
/// <param name="pmcData">player profile</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse RepairWithKit(
|
||||
MongoId sessionId,
|
||||
RepairActionDataRequest body,
|
||||
PmcData pmcData
|
||||
)
|
||||
public ItemEventRouterResponse RepairWithKit(MongoId sessionId, RepairActionDataRequest body, PmcData pmcData)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionId);
|
||||
|
||||
// repair item
|
||||
var repairDetails = repairService.RepairItemByKit(
|
||||
sessionId,
|
||||
pmcData,
|
||||
body.RepairKitsInfo,
|
||||
body.Target.Value,
|
||||
output
|
||||
);
|
||||
var repairDetails = repairService.RepairItemByKit(sessionId, pmcData, body.RepairKitsInfo, body.Target.Value, output);
|
||||
|
||||
repairService.AddBuffToItem(repairDetails, pmcData);
|
||||
|
||||
|
||||
@@ -46,12 +46,7 @@ public class RepeatableQuestController(
|
||||
ICloner cloner
|
||||
)
|
||||
{
|
||||
protected static readonly FrozenSet<string> _questTypes =
|
||||
[
|
||||
"PickUp",
|
||||
"Exploration",
|
||||
"Elimination",
|
||||
];
|
||||
protected static readonly FrozenSet<string> _questTypes = ["PickUp", "Exploration", "Elimination"];
|
||||
protected readonly QuestConfig QuestConfig = configServer.GetConfig<QuestConfig>();
|
||||
|
||||
/// <summary>
|
||||
@@ -63,18 +58,10 @@ public class RepeatableQuestController(
|
||||
/// <param name="acceptedQuest">Repeatable quest accepted</param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns>ItemEventRouterResponse</returns>
|
||||
public ItemEventRouterResponse AcceptRepeatableQuest(
|
||||
PmcData pmcData,
|
||||
AcceptQuestRequestData acceptedQuest,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse AcceptRepeatableQuest(PmcData pmcData, AcceptQuestRequestData acceptedQuest, MongoId sessionID)
|
||||
{
|
||||
// Create and store quest status object inside player profile
|
||||
var newRepeatableQuest = questHelper.GetQuestReadyForProfile(
|
||||
pmcData,
|
||||
QuestStatusEnum.Started,
|
||||
acceptedQuest
|
||||
);
|
||||
var newRepeatableQuest = questHelper.GetQuestReadyForProfile(pmcData, QuestStatusEnum.Started, acceptedQuest);
|
||||
pmcData.Quests.Add(newRepeatableQuest);
|
||||
|
||||
// Look for the generated quest cache in profile.RepeatableQuests
|
||||
@@ -82,22 +69,14 @@ public class RepeatableQuestController(
|
||||
if (repeatableQuestProfile is null)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"repeatable-accepted_repeatable_quest_not_found_in_active_quests",
|
||||
acceptedQuest.QuestId
|
||||
)
|
||||
serverLocalisationService.GetText("repeatable-accepted_repeatable_quest_not_found_in_active_quests", acceptedQuest.QuestId)
|
||||
);
|
||||
|
||||
throw new Exception(
|
||||
serverLocalisationService.GetText("repeatable-unable_to_accept_quest_see_log")
|
||||
);
|
||||
throw new Exception(serverLocalisationService.GetText("repeatable-unable_to_accept_quest_see_log"));
|
||||
}
|
||||
|
||||
// Some scav quests need to be added to scav profile for them to show up in-raid
|
||||
if (
|
||||
repeatableQuestProfile.Side == "Scav"
|
||||
&& _questTypes.Contains(repeatableQuestProfile.Type.ToString())
|
||||
)
|
||||
if (repeatableQuestProfile.Side == "Scav" && _questTypes.Contains(repeatableQuestProfile.Type.ToString()))
|
||||
{
|
||||
var fullProfile = profileHelper.GetFullProfile(sessionID);
|
||||
|
||||
@@ -117,11 +96,7 @@ public class RepeatableQuestController(
|
||||
/// <param name="changeRequest">Change quest request</param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse ChangeRepeatableQuest(
|
||||
PmcData pmcData,
|
||||
RepeatableQuestChangeRequest changeRequest,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse ChangeRepeatableQuest(PmcData pmcData, RepeatableQuestChangeRequest changeRequest, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
|
||||
@@ -134,9 +109,7 @@ public class RepeatableQuestController(
|
||||
if (repeatables.RepeatableType is null || repeatables.Quest is null)
|
||||
{
|
||||
// Unable to find quest being replaced
|
||||
var message = serverLocalisationService.GetText(
|
||||
"quest-unable_to_find_repeatable_to_replace"
|
||||
);
|
||||
var message = serverLocalisationService.GetText("quest-unable_to_find_repeatable_to_replace");
|
||||
logger.Error(message);
|
||||
|
||||
return httpResponseUtil.AppendErrorToOutput(output, message);
|
||||
@@ -154,17 +127,13 @@ public class RepeatableQuestController(
|
||||
.ToList();
|
||||
|
||||
// Save for later cost calculations
|
||||
var previousChangeRequirement = cloner.Clone(
|
||||
repeatablesOfTypeInProfile.ChangeRequirement[changeRequest.QuestId]
|
||||
);
|
||||
var previousChangeRequirement = cloner.Clone(repeatablesOfTypeInProfile.ChangeRequirement[changeRequest.QuestId]);
|
||||
|
||||
// Delete the replaced quest change requirement data as we're going to add new data below
|
||||
repeatablesOfTypeInProfile.ChangeRequirement.Remove(changeRequest.QuestId);
|
||||
|
||||
// Get config for this repeatable subtype (daily/weekly/scav)
|
||||
var repeatableConfig = QuestConfig.RepeatableQuests.FirstOrDefault(config =>
|
||||
config.Name == repeatablesOfTypeInProfile.Name
|
||||
);
|
||||
var repeatableConfig = QuestConfig.RepeatableQuests.FirstOrDefault(config => config.Name == repeatablesOfTypeInProfile.Name);
|
||||
|
||||
// If the configuration dictates to replace with the same quest type, adjust the available quest types
|
||||
if (repeatableConfig?.KeepDailyQuestTypeOnReplacement is not null)
|
||||
@@ -173,16 +142,8 @@ public class RepeatableQuestController(
|
||||
}
|
||||
|
||||
// Generate meta-data for what type/level range of quests can be generated for player
|
||||
var allowedQuestTypes = GenerateQuestPool(
|
||||
repeatableConfig,
|
||||
pmcData.Info.Level.GetValueOrDefault(1)
|
||||
);
|
||||
var newRepeatableQuest = AttemptToGenerateRepeatableQuest(
|
||||
sessionID,
|
||||
pmcData,
|
||||
allowedQuestTypes,
|
||||
repeatableConfig
|
||||
);
|
||||
var allowedQuestTypes = GenerateQuestPool(repeatableConfig, pmcData.Info.Level.GetValueOrDefault(1));
|
||||
var newRepeatableQuest = AttemptToGenerateRepeatableQuest(sessionID, pmcData, allowedQuestTypes, repeatableConfig);
|
||||
if (newRepeatableQuest is null)
|
||||
{
|
||||
// Unable to find quest being replaced
|
||||
@@ -218,11 +179,7 @@ public class RepeatableQuestController(
|
||||
};
|
||||
|
||||
// Check if we should charge player for replacing quest
|
||||
var isFreeToReplace = UseFreeRefreshIfAvailable(
|
||||
fullProfile,
|
||||
repeatablesOfTypeInProfile,
|
||||
repeatableTypeLower
|
||||
);
|
||||
var isFreeToReplace = UseFreeRefreshIfAvailable(fullProfile, repeatablesOfTypeInProfile, repeatableTypeLower);
|
||||
if (!isFreeToReplace)
|
||||
{
|
||||
// Reduce standing with trader for not doing their quest
|
||||
@@ -233,17 +190,8 @@ public class RepeatableQuestController(
|
||||
foreach (var cost in previousChangeRequirement.ChangeCost)
|
||||
{
|
||||
// Not free, Charge player + apply charisma bonus to cost of replacement
|
||||
cost.Count = (int)
|
||||
Math.Truncate(
|
||||
cost.Count.Value * (1 - (Math.Truncate(charismaBonus / 100) * 0.001))
|
||||
);
|
||||
paymentService.AddPaymentToOutput(
|
||||
pmcData,
|
||||
cost.TemplateId,
|
||||
cost.Count.Value,
|
||||
sessionID,
|
||||
output
|
||||
);
|
||||
cost.Count = (int)Math.Truncate(cost.Count.Value * (1 - (Math.Truncate(charismaBonus / 100) * 0.001)));
|
||||
paymentService.AddPaymentToOutput(pmcData, cost.TemplateId, cost.Count.Value, sessionID, output);
|
||||
if (output.Warnings.Count > 0)
|
||||
{
|
||||
return output;
|
||||
@@ -302,11 +250,7 @@ public class RepeatableQuestController(
|
||||
/// <param name="repeatableSubType">Can be daily / weekly / scav repeatable</param>
|
||||
/// <param name="repeatableTypeName">Subtype of repeatable quest: daily / weekly / scav</param>
|
||||
/// <returns>Is the repeatable being replaced for free</returns>
|
||||
protected bool UseFreeRefreshIfAvailable(
|
||||
SptProfile? fullProfile,
|
||||
PmcDataRepeatableQuest repeatableSubType,
|
||||
string repeatableTypeName
|
||||
)
|
||||
protected bool UseFreeRefreshIfAvailable(SptProfile? fullProfile, PmcDataRepeatableQuest repeatableSubType, string repeatableTypeName)
|
||||
{
|
||||
// No free refreshes, exit early
|
||||
if (repeatableSubType.FreeChangesAvailable <= 0)
|
||||
@@ -318,9 +262,7 @@ public class RepeatableQuestController(
|
||||
}
|
||||
|
||||
// Only certain game versions have access to free refreshes
|
||||
var hasAccessToFreeRefreshSystem = profileHelper.HasAccessToRepeatableFreeRefreshSystem(
|
||||
fullProfile.CharacterData.PmcData
|
||||
);
|
||||
var hasAccessToFreeRefreshSystem = profileHelper.HasAccessToRepeatableFreeRefreshSystem(fullProfile.CharacterData.PmcData);
|
||||
|
||||
// If the player has access and available refreshes:
|
||||
if (hasAccessToFreeRefreshSystem)
|
||||
@@ -345,10 +287,7 @@ public class RepeatableQuestController(
|
||||
/// </summary>
|
||||
/// <param name="repeatablesOfTypeInProfile">repeatables that have the replaced and new quest</param>
|
||||
/// <param name="replacedQuestId">Id of the replaced quest</param>
|
||||
protected void CleanUpRepeatableChangeRequirements(
|
||||
PmcDataRepeatableQuest repeatablesOfTypeInProfile,
|
||||
string replacedQuestId
|
||||
)
|
||||
protected void CleanUpRepeatableChangeRequirements(PmcDataRepeatableQuest repeatablesOfTypeInProfile, string replacedQuestId)
|
||||
{
|
||||
if (repeatablesOfTypeInProfile.ActiveQuests.Count == 1)
|
||||
// Only one repeatable quest being replaced (e.g. scav_daily), remove everything ready for new quest requirement to be added
|
||||
@@ -402,12 +341,7 @@ public class RepeatableQuestController(
|
||||
|
||||
if (attempts > maxAttempts)
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText(
|
||||
"quest-repeatable_generation_failed_please_report",
|
||||
attempts
|
||||
)
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("quest-repeatable_generation_failed_please_report", attempts));
|
||||
}
|
||||
|
||||
return newRepeatableQuest;
|
||||
@@ -446,9 +380,7 @@ public class RepeatableQuestController(
|
||||
var traderId = randomUtil.DrawRandomFromList(traders).FirstOrDefault();
|
||||
if (traderId.IsEmpty())
|
||||
{
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("repeatable-unable_to_find_trader_in_pool")
|
||||
);
|
||||
logger.Error(serverLocalisationService.GetText("repeatable-unable_to_find_trader_in_pool"));
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -460,34 +392,10 @@ public class RepeatableQuestController(
|
||||
|
||||
return questType switch
|
||||
{
|
||||
"Elimination" => eliminationQuestGenerator.Generate(
|
||||
sessionId,
|
||||
pmcLevel,
|
||||
traderId,
|
||||
questTypePool,
|
||||
repeatableConfig
|
||||
),
|
||||
"Completion" => completionQuestGenerator.Generate(
|
||||
sessionId,
|
||||
pmcLevel,
|
||||
traderId,
|
||||
questTypePool,
|
||||
repeatableConfig
|
||||
),
|
||||
"Exploration" => explorationQuestGenerator.Generate(
|
||||
sessionId,
|
||||
pmcLevel,
|
||||
traderId,
|
||||
questTypePool,
|
||||
repeatableConfig
|
||||
),
|
||||
"Pickup" => pickupQuestGenerator.Generate(
|
||||
sessionId,
|
||||
pmcLevel,
|
||||
traderId,
|
||||
questTypePool,
|
||||
repeatableConfig
|
||||
),
|
||||
"Elimination" => eliminationQuestGenerator.Generate(sessionId, pmcLevel, traderId, questTypePool, repeatableConfig),
|
||||
"Completion" => completionQuestGenerator.Generate(sessionId, pmcLevel, traderId, questTypePool, repeatableConfig),
|
||||
"Exploration" => explorationQuestGenerator.Generate(sessionId, pmcLevel, traderId, questTypePool, repeatableConfig),
|
||||
"Pickup" => pickupQuestGenerator.Generate(sessionId, pmcLevel, traderId, questTypePool, repeatableConfig),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
@@ -500,18 +408,12 @@ public class RepeatableQuestController(
|
||||
protected void RemoveQuestFromProfile(SptProfile fullProfile, MongoId questToReplaceId)
|
||||
{
|
||||
// Find quest we're replacing in pmc profile quests array and remove it
|
||||
questHelper.FindAndRemoveQuestFromArrayIfExists(
|
||||
questToReplaceId,
|
||||
fullProfile.CharacterData.PmcData.Quests
|
||||
);
|
||||
questHelper.FindAndRemoveQuestFromArrayIfExists(questToReplaceId, fullProfile.CharacterData.PmcData.Quests);
|
||||
|
||||
// Look for and remove quest we're replacing in scav profile too
|
||||
if (fullProfile.CharacterData.ScavData is not null)
|
||||
{
|
||||
questHelper.FindAndRemoveQuestFromArrayIfExists(
|
||||
questToReplaceId,
|
||||
fullProfile.CharacterData.ScavData.Quests
|
||||
);
|
||||
questHelper.FindAndRemoveQuestFromArrayIfExists(questToReplaceId, fullProfile.CharacterData.ScavData.Quests);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -526,20 +428,14 @@ public class RepeatableQuestController(
|
||||
foreach (var repeatablesInProfile in pmcData.RepeatableQuests)
|
||||
{
|
||||
// Check for existing quest in (daily/weekly/scav arrays)
|
||||
var questToReplace = repeatablesInProfile.ActiveQuests?.FirstOrDefault(repeatable =>
|
||||
repeatable.Id == questId
|
||||
);
|
||||
var questToReplace = repeatablesInProfile.ActiveQuests?.FirstOrDefault(repeatable => repeatable.Id == questId);
|
||||
if (questToReplace is null)
|
||||
// Not found, skip to next repeatable subtype
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return new GetRepeatableByIdResult
|
||||
{
|
||||
Quest = questToReplace,
|
||||
RepeatableType = repeatablesInProfile,
|
||||
};
|
||||
return new GetRepeatableByIdResult { Quest = questToReplace, RepeatableType = repeatablesInProfile };
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -577,10 +473,7 @@ public class RepeatableQuestController(
|
||||
foreach (var repeatableConfig in QuestConfig.RepeatableQuests)
|
||||
{
|
||||
// Get daily/weekly data from profile, add empty object if missing
|
||||
var generatedRepeatables = GetRepeatableQuestSubTypeFromProfile(
|
||||
repeatableConfig,
|
||||
pmcData
|
||||
);
|
||||
var generatedRepeatables = GetRepeatableQuestSubTypeFromProfile(repeatableConfig, pmcData);
|
||||
var repeatableTypeLower = repeatableConfig.Name.ToLowerInvariant();
|
||||
|
||||
var canAccessRepeatables = CanProfileAccessRepeatableQuests(repeatableConfig, pmcData);
|
||||
@@ -620,10 +513,7 @@ public class RepeatableQuestController(
|
||||
ProcessExpiredQuests(generatedRepeatables, pmcData);
|
||||
|
||||
// Create dynamic quest pool to avoid generating duplicates
|
||||
var questTypePool = GenerateQuestPool(
|
||||
repeatableConfig,
|
||||
pmcData.Info.Level.GetValueOrDefault(1)
|
||||
);
|
||||
var questTypePool = GenerateQuestPool(repeatableConfig, pmcData.Info.Level.GetValueOrDefault(1));
|
||||
|
||||
// Add repeatable quests of this loops sub-type (daily/weekly)
|
||||
for (var i = 0; i < GetQuestCount(repeatableConfig, fullProfile); i++)
|
||||
@@ -642,9 +532,7 @@ public class RepeatableQuestController(
|
||||
lifeline++;
|
||||
if (lifeline > 10)
|
||||
{
|
||||
logger.Error(
|
||||
"We were stuck in repeatable quest generation. This should never happen. Please report"
|
||||
);
|
||||
logger.Error("We were stuck in repeatable quest generation. This should never happen. Please report");
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -675,9 +563,7 @@ public class RepeatableQuestController(
|
||||
new ChangeRequirement
|
||||
{
|
||||
ChangeCost = quest.ChangeCost,
|
||||
ChangeStandingCost = randomUtil.GetArrayValue(
|
||||
repeatableConfig.StandingChangeCost
|
||||
), // Randomise standing loss to replace
|
||||
ChangeStandingCost = randomUtil.GetArrayValue(repeatableConfig.StandingChangeCost), // Randomise standing loss to replace
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -709,15 +595,10 @@ public class RepeatableQuestController(
|
||||
/// <param name="repeatableConfig">daily/weekly config</param>
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <returns>PmcDataRepeatableQuest</returns>
|
||||
protected PmcDataRepeatableQuest GetRepeatableQuestSubTypeFromProfile(
|
||||
RepeatableQuestConfig repeatableConfig,
|
||||
PmcData pmcData
|
||||
)
|
||||
protected PmcDataRepeatableQuest GetRepeatableQuestSubTypeFromProfile(RepeatableQuestConfig repeatableConfig, PmcData pmcData)
|
||||
{
|
||||
// Get from profile, add if missing
|
||||
var repeatableQuestDetails = pmcData.RepeatableQuests.FirstOrDefault(repeatable =>
|
||||
repeatable.Name == repeatableConfig.Name
|
||||
);
|
||||
var repeatableQuestDetails = pmcData.RepeatableQuests.FirstOrDefault(repeatable => repeatable.Name == repeatableConfig.Name);
|
||||
var hasAccess = profileHelper.HasAccessToRepeatableFreeRefreshSystem(pmcData);
|
||||
|
||||
if (repeatableQuestDetails is null)
|
||||
@@ -755,16 +636,10 @@ public class RepeatableQuestController(
|
||||
/// <param name="repeatableConfig">Repeatable quest config</param>
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <returns>True if profile has access to repeatables</returns>
|
||||
protected bool CanProfileAccessRepeatableQuests(
|
||||
RepeatableQuestConfig repeatableConfig,
|
||||
PmcData pmcData
|
||||
)
|
||||
protected bool CanProfileAccessRepeatableQuests(RepeatableQuestConfig repeatableConfig, PmcData pmcData)
|
||||
{
|
||||
// PMC and daily quests not unlocked yet
|
||||
if (
|
||||
repeatableConfig.Side == PlayerGroup.Pmc
|
||||
&& !PlayerHasDailyPmcQuestsUnlocked(pmcData, repeatableConfig)
|
||||
)
|
||||
if (repeatableConfig.Side == PlayerGroup.Pmc && !PlayerHasDailyPmcQuestsUnlocked(pmcData, repeatableConfig))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -789,10 +664,7 @@ public class RepeatableQuestController(
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
/// <param name="repeatableConfig">Config of daily type to check</param>
|
||||
/// <returns>True if unlocked</returns>
|
||||
protected static bool PlayerHasDailyPmcQuestsUnlocked(
|
||||
PmcData pmcData,
|
||||
RepeatableQuestConfig repeatableConfig
|
||||
)
|
||||
protected static bool PlayerHasDailyPmcQuestsUnlocked(PmcData pmcData, RepeatableQuestConfig repeatableConfig)
|
||||
{
|
||||
return pmcData.Info.Level >= repeatableConfig.MinPlayerLevel;
|
||||
}
|
||||
@@ -804,11 +676,7 @@ public class RepeatableQuestController(
|
||||
/// <returns>True if unlocked</returns>
|
||||
protected bool PlayerHasDailyScavQuestsUnlocked(PmcData pmcData)
|
||||
{
|
||||
return pmcData
|
||||
.Hideout?.Areas?.FirstOrDefault(hideoutArea =>
|
||||
hideoutArea.Type == HideoutAreas.IntelligenceCenter
|
||||
)
|
||||
?.Level >= 1;
|
||||
return pmcData.Hideout?.Areas?.FirstOrDefault(hideoutArea => hideoutArea.Type == HideoutAreas.IntelligenceCenter)?.Level >= 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -816,17 +684,12 @@ public class RepeatableQuestController(
|
||||
/// </summary>
|
||||
/// <param name="generatedRepeatables">Repeatables to process (daily/weekly)</param>
|
||||
/// <param name="pmcData">Players PMC profile</param>
|
||||
protected void ProcessExpiredQuests(
|
||||
PmcDataRepeatableQuest generatedRepeatables,
|
||||
PmcData pmcData
|
||||
)
|
||||
protected void ProcessExpiredQuests(PmcDataRepeatableQuest generatedRepeatables, PmcData pmcData)
|
||||
{
|
||||
var questsToKeep = new List<RepeatableQuest>();
|
||||
foreach (var activeQuest in generatedRepeatables.ActiveQuests)
|
||||
{
|
||||
var questStatusInProfile = pmcData.Quests.FirstOrDefault(quest =>
|
||||
quest.QId == activeQuest.Id
|
||||
);
|
||||
var questStatusInProfile = pmcData.Quests.FirstOrDefault(quest => quest.QId == activeQuest.Id);
|
||||
if (questStatusInProfile is null)
|
||||
{
|
||||
continue;
|
||||
@@ -884,14 +747,8 @@ public class RepeatableQuestController(
|
||||
// Add "any" to pickup quest pool
|
||||
questPool.Pool.Pickup.Locations[ELocationName.any] = ["any"];
|
||||
|
||||
var eliminationConfig = repeatableQuestHelper.GetEliminationConfigByPmcLevel(
|
||||
pmcLevel,
|
||||
repeatableConfig
|
||||
);
|
||||
var targetsConfig = new ProbabilityObjectArray<string, BossInfo>(
|
||||
cloner,
|
||||
eliminationConfig.Targets
|
||||
);
|
||||
var eliminationConfig = repeatableQuestHelper.GetEliminationConfigByPmcLevel(pmcLevel, repeatableConfig);
|
||||
var targetsConfig = new ProbabilityObjectArray<string, BossInfo>(cloner, eliminationConfig.Targets);
|
||||
|
||||
// Populate Elimination quest targets and their locations
|
||||
foreach (var target in targetsConfig)
|
||||
@@ -899,10 +756,7 @@ public class RepeatableQuestController(
|
||||
// Target is boss
|
||||
if (target.Data?.IsBoss ?? false)
|
||||
{
|
||||
questPool.Pool.Elimination.Targets.Add(
|
||||
target.Key,
|
||||
new TargetLocation { Locations = ["any"] }
|
||||
);
|
||||
questPool.Pool.Elimination.Targets.Add(target.Key, new TargetLocation { Locations = ["any"] });
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -916,10 +770,7 @@ public class RepeatableQuestController(
|
||||
|
||||
questPool.Pool.Elimination.Targets.Add(
|
||||
target.Key,
|
||||
new TargetLocation
|
||||
{
|
||||
Locations = allowedLocations.Select(x => x.ToString()).ToList(),
|
||||
}
|
||||
new TargetLocation { Locations = allowedLocations.Select(x => x.ToString()).ToList() }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -938,18 +789,9 @@ public class RepeatableQuestController(
|
||||
Types = cloner.Clone(repeatableConfig.Types)!,
|
||||
Pool = new QuestPool
|
||||
{
|
||||
Exploration = new ExplorationPool
|
||||
{
|
||||
Locations = new Dictionary<ELocationName, List<string>>(),
|
||||
},
|
||||
Elimination = new EliminationPool
|
||||
{
|
||||
Targets = new Dictionary<string, TargetLocation>(),
|
||||
},
|
||||
Pickup = new ExplorationPool
|
||||
{
|
||||
Locations = new Dictionary<ELocationName, List<string>>(),
|
||||
},
|
||||
Exploration = new ExplorationPool { Locations = new Dictionary<ELocationName, List<string>>() },
|
||||
Elimination = new EliminationPool { Targets = new Dictionary<string, TargetLocation>() },
|
||||
Pickup = new ExplorationPool { Locations = new Dictionary<ELocationName, List<string>>() },
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -971,10 +813,7 @@ public class RepeatableQuestController(
|
||||
// Add elite bonus to daily quests
|
||||
if (
|
||||
string.Equals(repeatableConfig.Name, "daily", StringComparison.OrdinalIgnoreCase)
|
||||
&& profileHelper.HasEliteSkillLevel(
|
||||
SkillTypes.Charisma,
|
||||
fullProfile.CharacterData.PmcData
|
||||
)
|
||||
&& profileHelper.HasEliteSkillLevel(SkillTypes.Charisma, fullProfile.CharacterData.PmcData)
|
||||
)
|
||||
// Elite charisma skill gives extra daily quest(s)
|
||||
{
|
||||
@@ -984,8 +823,7 @@ public class RepeatableQuestController(
|
||||
}
|
||||
|
||||
// Add any extra repeatable quests the profile has unlocked
|
||||
questCount += (int)
|
||||
fullProfile.SptData.ExtraRepeatableQuests.GetValueOrDefault(repeatableConfig.Id, 0);
|
||||
questCount += (int)fullProfile.SptData.ExtraRepeatableQuests.GetValueOrDefault(repeatableConfig.Id, 0);
|
||||
|
||||
return questCount;
|
||||
}
|
||||
|
||||
@@ -46,11 +46,7 @@ public class TradeController(
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse ConfirmTrading(
|
||||
PmcData pmcData,
|
||||
ProcessBaseTradeRequestData request,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse ConfirmTrading(PmcData pmcData, ProcessBaseTradeRequestData request, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
|
||||
@@ -76,11 +72,7 @@ public class TradeController(
|
||||
var errorMessage = $"Unhandled trade event: {request.Type}";
|
||||
logger.Error(errorMessage);
|
||||
|
||||
return httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
errorMessage,
|
||||
BackendErrorCodes.RagfairUnavailable
|
||||
);
|
||||
return httpResponseUtil.AppendErrorToOutput(output, errorMessage, BackendErrorCodes.RagfairUnavailable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -90,11 +82,7 @@ public class TradeController(
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionID">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse ConfirmRagfairTrading(
|
||||
PmcData pmcData,
|
||||
ProcessRagfairTradeRequestData request,
|
||||
MongoId sessionID
|
||||
)
|
||||
public ItemEventRouterResponse ConfirmRagfairTrading(PmcData pmcData, ProcessRagfairTradeRequestData request, MongoId sessionID)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionID);
|
||||
|
||||
@@ -103,11 +91,7 @@ public class TradeController(
|
||||
var fleaOffer = ragfairServer.GetOffer(offer.Id);
|
||||
if (fleaOffer is null)
|
||||
{
|
||||
return httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
$"Offer with ID {offer.Id} not found",
|
||||
BackendErrorCodes.OfferNotFound
|
||||
);
|
||||
return httpResponseUtil.AppendErrorToOutput(output, $"Offer with ID {offer.Id} not found", BackendErrorCodes.OfferNotFound);
|
||||
}
|
||||
|
||||
if (offer.Count == 0)
|
||||
@@ -116,11 +100,7 @@ public class TradeController(
|
||||
"ragfair-unable_to_purchase_0_count_item",
|
||||
itemHelper.GetItem(fleaOffer.Items[0].Template).Value.Name
|
||||
);
|
||||
return httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
errorMessage,
|
||||
BackendErrorCodes.OfferOutOfStock
|
||||
);
|
||||
return httpResponseUtil.AppendErrorToOutput(output, errorMessage, BackendErrorCodes.OfferOutOfStock);
|
||||
}
|
||||
|
||||
if (fleaOffer.IsTraderOffer())
|
||||
@@ -168,11 +148,7 @@ public class TradeController(
|
||||
logger.Debug(errorMessage);
|
||||
}
|
||||
|
||||
httpResponseUtil.AppendErrorToOutput(
|
||||
output,
|
||||
errorMessage,
|
||||
BackendErrorCodes.RagfairUnavailable
|
||||
);
|
||||
httpResponseUtil.AppendErrorToOutput(output, errorMessage, BackendErrorCodes.RagfairUnavailable);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -188,13 +164,7 @@ public class TradeController(
|
||||
SchemeId = 0,
|
||||
SchemeItems = requestOffer.Items,
|
||||
};
|
||||
tradeHelper.BuyItem(
|
||||
pmcData,
|
||||
buyData,
|
||||
sessionId,
|
||||
_traderConfig.PurchasesAreFoundInRaid,
|
||||
output
|
||||
);
|
||||
tradeHelper.BuyItem(pmcData, buyData, sessionId, _traderConfig.PurchasesAreFoundInRaid, output);
|
||||
|
||||
// Remove/lower offer quantity of item purchased from trader flea offer
|
||||
ragfairServer.ReduceOfferQuantity(fleaOffer.Id, requestOffer.Count ?? 0);
|
||||
@@ -228,13 +198,7 @@ public class TradeController(
|
||||
};
|
||||
|
||||
// buyItem() must occur prior to removing the offer stack, otherwise item inside offer doesn't exist for confirmTrading() to use
|
||||
tradeHelper.BuyItem(
|
||||
pmcData,
|
||||
buyData,
|
||||
sessionId,
|
||||
_ragfairConfig.Dynamic.PurchasesAreFoundInRaid,
|
||||
output
|
||||
);
|
||||
tradeHelper.BuyItem(pmcData, buyData, sessionId, _ragfairConfig.Dynamic.PurchasesAreFoundInRaid, output);
|
||||
if (output.Warnings?.Count > 0)
|
||||
{
|
||||
return;
|
||||
@@ -274,11 +238,7 @@ public class TradeController(
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse SellScavItemsToFence(
|
||||
PmcData pmcData,
|
||||
SellScavItemsToFenceRequestData request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse SellScavItemsToFence(PmcData pmcData, SellScavItemsToFenceRequestData request, MongoId sessionId)
|
||||
{
|
||||
var output = eventOutputHolder.GetOutput(sessionId);
|
||||
|
||||
@@ -316,11 +276,7 @@ public class TradeController(
|
||||
sessionId,
|
||||
trader,
|
||||
MessageType.MessageWithItems,
|
||||
randomUtil.GetArrayValue(
|
||||
databaseService.GetTrader(trader).Dialogue.TryGetValue("soldItems", out var items)
|
||||
? items
|
||||
: []
|
||||
),
|
||||
randomUtil.GetArrayValue(databaseService.GetTrader(trader).Dialogue.TryGetValue("soldItems", out var items) ? items : []),
|
||||
currencyReward.SelectMany(x => x).ToList(),
|
||||
timeUtil.GetHoursAsSeconds(72)
|
||||
);
|
||||
@@ -347,25 +303,14 @@ public class TradeController(
|
||||
foreach (var itemToSell in itemWithChildren)
|
||||
{
|
||||
var itemDetails = itemHelper.GetItem(itemToSell.Template);
|
||||
if (
|
||||
!(
|
||||
itemDetails.Key
|
||||
&& itemHelper.IsOfBaseclasses(
|
||||
itemDetails.Value.Id,
|
||||
traderDetails.ItemsBuy.Category
|
||||
)
|
||||
)
|
||||
)
|
||||
if (!(itemDetails.Key && itemHelper.IsOfBaseclasses(itemDetails.Value.Id, traderDetails.ItemsBuy.Category)))
|
||||
// Skip if tpl isn't item OR item doesn't fulfil match traders buy categories
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get price of item multiplied by how many are in stack
|
||||
totalPrice += (int)(
|
||||
(handbookPrices[itemToSell.Template] ?? 0)
|
||||
* (itemToSell.Upd?.StackObjectsCount ?? 1)
|
||||
);
|
||||
totalPrice += (int)((handbookPrices[itemToSell.Template] ?? 0) * (itemToSell.Upd?.StackObjectsCount ?? 1));
|
||||
}
|
||||
|
||||
return totalPrice;
|
||||
|
||||
@@ -83,10 +83,7 @@ public class TraderController(
|
||||
foreach (var kvp in trader.Assort?.BarterScheme)
|
||||
{
|
||||
var barterSchemeItem = kvp.Value.FirstOrDefault()?.FirstOrDefault();
|
||||
if (
|
||||
barterSchemeItem?.Template != null
|
||||
&& paymentHelper.IsMoneyTpl(barterSchemeItem.Template)
|
||||
)
|
||||
if (barterSchemeItem?.Template != null && paymentHelper.IsMoneyTpl(barterSchemeItem.Template))
|
||||
{
|
||||
barterSchemeItem.Count += Math.Round(barterSchemeItem?.Count * multiplier ?? 0D, 2);
|
||||
}
|
||||
|
||||
@@ -50,11 +50,7 @@ public class WeatherController(
|
||||
/// <returns>GetLocalWeatherResponseData</returns>
|
||||
public GetLocalWeatherResponseData GenerateLocal(MongoId sessionId)
|
||||
{
|
||||
var result = new GetLocalWeatherResponseData
|
||||
{
|
||||
Season = seasonalEventService.GetActiveWeatherSeason(),
|
||||
Weather = [],
|
||||
};
|
||||
var result = new GetLocalWeatherResponseData { Season = seasonalEventService.GetActiveWeatherSeason(), Weather = [] };
|
||||
|
||||
result.Weather.AddRange(raidWeatherService.GetUpcomingWeather());
|
||||
|
||||
|
||||
@@ -18,11 +18,7 @@ public class WishlistController(EventOutputHolder eventOutputHolder)
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse AddToWishList(
|
||||
PmcData pmcData,
|
||||
AddToWishlistRequest request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse AddToWishList(PmcData pmcData, AddToWishlistRequest request, MongoId sessionId)
|
||||
{
|
||||
pmcData.WishList ??= new DictionaryOrList<MongoId, int>(new Dictionary<MongoId, int>(), []);
|
||||
foreach (var item in request.Items)
|
||||
@@ -40,11 +36,7 @@ public class WishlistController(EventOutputHolder eventOutputHolder)
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse RemoveFromWishList(
|
||||
PmcData pmcData,
|
||||
RemoveFromWishlistRequest request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse RemoveFromWishList(PmcData pmcData, RemoveFromWishlistRequest request, MongoId sessionId)
|
||||
{
|
||||
foreach (var itemId in request.Items)
|
||||
{
|
||||
@@ -61,11 +53,7 @@ public class WishlistController(EventOutputHolder eventOutputHolder)
|
||||
/// <param name="request"></param>
|
||||
/// <param name="sessionId">Session/Player id</param>
|
||||
/// <returns></returns>
|
||||
public ItemEventRouterResponse ChangeWishListItemCategory(
|
||||
PmcData pmcData,
|
||||
ChangeWishlistItemCategoryRequest request,
|
||||
MongoId sessionId
|
||||
)
|
||||
public ItemEventRouterResponse ChangeWishListItemCategory(PmcData pmcData, ChangeWishlistItemCategoryRequest request, MongoId sessionId)
|
||||
{
|
||||
pmcData.WishList.Dictionary[request.Item] = request.Category.Value;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user