diff --git a/project/SPT.Custom/Patches/ResetTraderServicesPatch.cs b/project/SPT.Custom/Patches/ResetTraderServicesPatch.cs deleted file mode 100644 index c8aa536..0000000 --- a/project/SPT.Custom/Patches/ResetTraderServicesPatch.cs +++ /dev/null @@ -1,22 +0,0 @@ -using SPT.Reflection.Patching; -using SPT.SinglePlayer.Utils.TraderServices; -using EFT; -using HarmonyLib; -using System.Reflection; - -namespace SPT.Custom.Patches -{ - public class ResetTraderServicesPatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return AccessTools.Method(typeof(BaseLocalGame), nameof(BaseLocalGame.Stop)); - } - - [PatchPrefix] - private static void PatchPrefix() - { - TraderServicesManager.Instance.Clear(); - } - } -} diff --git a/project/SPT.Custom/SPTCustomPlugin.cs b/project/SPT.Custom/SPTCustomPlugin.cs index 0398151..65ccf5c 100644 --- a/project/SPT.Custom/SPTCustomPlugin.cs +++ b/project/SPT.Custom/SPTCustomPlugin.cs @@ -35,7 +35,6 @@ namespace SPT.Custom new SetLocationIdOnRaidStartPatch().Enable(); new RagfairFeePatch().Enable(); new ScavQuestPatch().Enable(); - new ResetTraderServicesPatch().Enable(); new ScavItemCheckmarkPatch().Enable(); new CultistAmuletRemovalPatch().Enable(); new HalloweenExtractPatch().Enable(); diff --git a/project/SPT.SinglePlayer/Models/Progression/LighthouseProgressionClass.cs b/project/SPT.SinglePlayer/Models/Progression/LighthouseProgressionClass.cs deleted file mode 100644 index 6021931..0000000 --- a/project/SPT.SinglePlayer/Models/Progression/LighthouseProgressionClass.cs +++ /dev/null @@ -1,192 +0,0 @@ -using Comfort.Common; -using EFT; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -namespace SPT.SinglePlayer.Models.Progression -{ - public class LighthouseProgressionClass : MonoBehaviour - { - private GameWorld _gameWorld; - private Player _player; - private float _timer; - private List _bridgeMines; - private RecodableItemClass _transmitter; - private readonly List _zryachiyAndFollowers = new List(); - private bool _aggressor; - private bool _isDoorDisabled; - private readonly string _transmitterId = "62e910aaf957f2915e0a5e36"; - private readonly string _lightKeeperTid = "638f541a29ffd1183d187f57"; - - public void Start() - { - _gameWorld = Singleton.Instance; - _player = _gameWorld?.MainPlayer; - - if (_gameWorld == null || _player == null) - { - Destroy(this); - - return; - } - - - // Get transmitter from players inventory - _transmitter = GetTransmitterFromInventory(); - - // Exit if transmitter does not exist and isnt green - if (!PlayerHasActiveTransmitterInInventory()) - { - Destroy(this); - - return; - } - - var places = Singleton.Instance.BotsController.CoversData.AIPlaceInfoHolder.Places; - - places.First(x => x.name == "Attack").gameObject.SetActive(false); - - // Zone was added in a newer version and the gameObject actually has a \ - places.First(y => y.name == "CloseZone\\").gameObject.SetActive(false); - - // Give access to Lightkeepers door - _gameWorld.BufferZoneController.SetPlayerAccessStatus(_player.ProfileId, true); - - _bridgeMines = _gameWorld.MineManager.Mines; - - // Set mines to be non-active - SetBridgeMinesStatus(false); - } - - public void Update() - { - IncrementLastUpdateTimer(); - - // Exit early if last update() run time was < 10 secs ago - if (_timer < 10f) - { - return; - } - - // Skip if: - // GameWorld missing - // Player not an enemy to Zryachiy - // Lk door not accessible - // Player has no transmitter on thier person - if (_gameWorld == null || _isDoorDisabled || _transmitter == null) - { - return; - } - - // Find Zryachiy and prep him - if (_zryachiyAndFollowers.Count == 0) - { - SetupZryachiyAndFollowerHostility(); - } - - // If player becomes aggressor, block access to LK - if (_aggressor) - { - DisableAccessToLightKeeper(); - } - } - - /// - /// Gets transmitter from players inventory - /// - private RecodableItemClass GetTransmitterFromInventory() - { - return (RecodableItemClass) _player.Profile.Inventory.AllRealPlayerItems.FirstOrDefault(x => x.TemplateId == _transmitterId); - } - - /// - /// Checks for transmitter status and exists in players inventory - /// - private bool PlayerHasActiveTransmitterInInventory() - { - return _transmitter != null && - _transmitter?.RecodableComponent?.Status == RadioTransmitterStatus.Green; - } - - /// - /// Update _time to diff from last run of update() - /// - private void IncrementLastUpdateTimer() - { - _timer += Time.deltaTime; - } - - /// - /// Set all brdige mines to desire state - /// - /// What state should bridge mines be set to - private void SetBridgeMinesStatus(bool desiredMineState) - { - // Find mines with opposite state of what we want - var mines = _bridgeMines.Where(mine => mine.gameObject.activeSelf == !desiredMineState && mine.transform.parent.gameObject.name == "Directional_mines_LHZONE"); - foreach (var mine in mines) - { - mine.gameObject.SetActive(desiredMineState); - } - } - - /// - /// Put Zryachiy and followers into a list and sub to their death event - /// Make player agressor if player kills them. - /// - private void SetupZryachiyAndFollowerHostility() - { - // Only process non-players (ai) - foreach (var aiBot in _gameWorld.AllAlivePlayersList.Where(x => !x.IsYourPlayer)) - { - // Bots that die on mounted guns get stuck in AllAlivePlayersList, need to check health - if (!aiBot.HealthController.IsAlive) - { - continue; - } - - // Edge case of bossZryachiy not being hostile to player - if (aiBot.AIData.BotOwner.IsRole(WildSpawnType.bossZryachiy) || aiBot.AIData.BotOwner.IsRole(WildSpawnType.followerZryachiy)) - { - // Subscribe to bots OnDeath event - aiBot.OnPlayerDeadOrUnspawn += OnZryachiyOrFollowerDeath; - - // Save bot to list for later access - if (!_zryachiyAndFollowers.Contains(aiBot)) - { - _zryachiyAndFollowers.Add(aiBot); - } - } - } - } - - /// - /// Set aggression + standing loss when Zryachiy/follower is killed by player - /// - /// The player who killed Zryachiy/follower. - private void OnZryachiyOrFollowerDeath(Player player) - { - // Check if zryachiy/follower was killed by player - if (player?.KillerId == _player?.ProfileId) - { - // If player kills zryachiy or follower, force aggressor state - // Also set players Lk standing to negative (allows access to quest chain (Making Amends)) - _aggressor = true; - _player?.Profile.TradersInfo[_lightKeeperTid].SetStanding(-0.01); - } - } - - /// - /// Disable door + set transmitter to 'red' - /// - private void DisableAccessToLightKeeper() - { - // Disable access to Lightkeepers door for the player - _gameWorld.BufferZoneController.SetPlayerAccessStatus(_gameWorld.MainPlayer.ProfileId, false); - _transmitter?.RecodableComponent?.SetStatus(RadioTransmitterStatus.Yellow); - _transmitter?.RecodableComponent?.SetEncoded(false); - _isDoorDisabled = true; - } - } -} diff --git a/project/SPT.SinglePlayer/Patches/Progression/LighthouseBridgePatch.cs b/project/SPT.SinglePlayer/Patches/Progression/LighthouseBridgePatch.cs deleted file mode 100644 index 4db3ebc..0000000 --- a/project/SPT.SinglePlayer/Patches/Progression/LighthouseBridgePatch.cs +++ /dev/null @@ -1,35 +0,0 @@ -using SPT.Reflection.Patching; -using SPT.SinglePlayer.Models.Progression; -using Comfort.Common; -using EFT; -using System.Reflection; -using HarmonyLib; - -namespace SPT.SinglePlayer.Patches.Progression -{ - public class LighthouseBridgePatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return AccessTools.Method(typeof(GameWorld), nameof(GameWorld.OnGameStarted)); - } - - [PatchPostfix] - private static void PatchPostfix() - { - var gameWorld = Singleton.Instance; - - if (gameWorld == null) - { - return; - } - - if (gameWorld.MainPlayer.Location.ToLower() != "lighthouse" || gameWorld.MainPlayer.Side == EPlayerSide.Savage) - { - return; - } - - gameWorld.GetOrAddComponent(); - } - } -} \ No newline at end of file diff --git a/project/SPT.SinglePlayer/Patches/Progression/LighthouseTransmitterPatch.cs b/project/SPT.SinglePlayer/Patches/Progression/LighthouseTransmitterPatch.cs deleted file mode 100644 index 626cbce..0000000 --- a/project/SPT.SinglePlayer/Patches/Progression/LighthouseTransmitterPatch.cs +++ /dev/null @@ -1,42 +0,0 @@ -using SPT.Reflection.Patching; -using Comfort.Common; -using EFT; -using System.Reflection; -using HarmonyLib; - -namespace SPT.SinglePlayer.Patches.Progression -{ - public class LighthouseTransmitterPatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return AccessTools.Method(typeof(RadioTransmitterHandlerClass), nameof(RadioTransmitterHandlerClass.method_4)); - } - - [PatchPrefix] - private static bool PatchPrefix(RadioTransmitterHandlerClass __instance) - { - var gameWorld = Singleton.Instance; - - if (gameWorld == null) return false; - - var transmitter = __instance.RecodableComponent; - - if (transmitter.IsEncoded) - { - transmitter.SetStatus(RadioTransmitterStatus.Green); - } - else if (gameWorld.MainPlayer.IsAgressorInLighthouseTraderZone) - { - // this might need to be tested and changed as I don't think this currently is affect upon killing bosses - transmitter.SetStatus(RadioTransmitterStatus.Yellow); - } - else - { - transmitter.SetStatus(RadioTransmitterStatus.Red); - } - - return false; - } - } -} \ No newline at end of file diff --git a/project/SPT.SinglePlayer/Patches/TraderServices/GetTraderServicesPatch.cs b/project/SPT.SinglePlayer/Patches/TraderServices/GetTraderServicesPatch.cs deleted file mode 100644 index 4b52e2b..0000000 --- a/project/SPT.SinglePlayer/Patches/TraderServices/GetTraderServicesPatch.cs +++ /dev/null @@ -1,25 +0,0 @@ -using SPT.Reflection.Patching; -using SPT.SinglePlayer.Utils.TraderServices; -using HarmonyLib; -using System.Reflection; - -namespace SPT.SinglePlayer.Patches.TraderServices -{ - public class GetTraderServicesPatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return AccessTools.Method(typeof(InventoryControllerClass), nameof(InventoryControllerClass.GetTraderServicesDataFromServer)); - } - - [PatchPrefix] - public static bool PatchPrefix(string traderId) - { - Logger.LogInfo($"Loading {traderId} services from servers"); - TraderServicesManager.Instance.GetTraderServicesDataFromServer(traderId); - - // Skip original - return false; - } - } -} diff --git a/project/SPT.SinglePlayer/Patches/TraderServices/LightKeeperServicesPatch.cs b/project/SPT.SinglePlayer/Patches/TraderServices/LightKeeperServicesPatch.cs deleted file mode 100644 index eb0f33f..0000000 --- a/project/SPT.SinglePlayer/Patches/TraderServices/LightKeeperServicesPatch.cs +++ /dev/null @@ -1,27 +0,0 @@ -using SPT.Reflection.Patching; -using SPT.SinglePlayer.Utils.TraderServices; -using Comfort.Common; -using EFT; -using System.Reflection; - -namespace SPT.SinglePlayer.Patches.TraderServices -{ - public class LightKeeperServicesPatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return typeof(GameWorld).GetMethod(nameof(GameWorld.OnGameStarted)); - } - - [PatchPostfix] - public static void PatchPostFix() - { - var gameWorld = Singleton.Instance; - - if (gameWorld != null) - { - gameWorld.gameObject.AddComponent(); - } - } - } -} diff --git a/project/SPT.SinglePlayer/Patches/TraderServices/PurchaseTraderServicePatch.cs b/project/SPT.SinglePlayer/Patches/TraderServices/PurchaseTraderServicePatch.cs deleted file mode 100644 index 9a14797..0000000 --- a/project/SPT.SinglePlayer/Patches/TraderServices/PurchaseTraderServicePatch.cs +++ /dev/null @@ -1,36 +0,0 @@ -using SPT.Reflection.Patching; -using SPT.SinglePlayer.Utils.TraderServices; -using EFT; -using HarmonyLib; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace SPT.SinglePlayer.Patches.TraderServices -{ - public class PurchaseTraderServicePatch : ModulePatch - { - protected override MethodBase GetTargetMethod() - { - return AccessTools.Method(typeof(InventoryControllerClass), nameof(InventoryControllerClass.TryPurchaseTraderService)); - } - - [PatchPostfix] - public static async void PatchPostFix(Task __result, ETraderServiceType serviceType, AbstractQuestControllerClass questController, string subServiceId) - { - bool purchased = await __result; - if (purchased) - { - Logger.LogInfo($"Player purchased service {serviceType}"); - TraderServicesManager.Instance.AfterPurchaseTraderService(serviceType, questController, subServiceId); - } - else - { - Logger.LogInfo($"Player failed to purchase service {serviceType}"); - } - } - } -} diff --git a/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs b/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs index 15b5150..ccc652b 100644 --- a/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs +++ b/project/SPT.SinglePlayer/SPTSingleplayerPlugin.cs @@ -6,7 +6,6 @@ using SPT.SinglePlayer.Patches.Progression; using SPT.SinglePlayer.Patches.Quests; using SPT.SinglePlayer.Patches.RaidFix; using SPT.SinglePlayer.Patches.ScavMode; -using SPT.SinglePlayer.Patches.TraderServices; using BepInEx; namespace SPT.SinglePlayer @@ -41,11 +40,6 @@ namespace SPT.SinglePlayer new ScavProfileLoadPatch().Enable(); new ScavPrefabLoadPatch().Enable(); new ScavExfilPatch().Enable(); - new LighthouseBridgePatch().Enable(); - new LighthouseTransmitterPatch().Enable(); - new GetTraderServicesPatch().Enable(); - new PurchaseTraderServicePatch().Enable(); - new LightKeeperServicesPatch().Enable(); // Still need new DisableReadyLocationReadyPatch().Enable(); diff --git a/project/SPT.SinglePlayer/Utils/TraderServices/LightKeeperServicesManager.cs b/project/SPT.SinglePlayer/Utils/TraderServices/LightKeeperServicesManager.cs deleted file mode 100644 index f1f025f..0000000 --- a/project/SPT.SinglePlayer/Utils/TraderServices/LightKeeperServicesManager.cs +++ /dev/null @@ -1,64 +0,0 @@ -using BepInEx.Logging; -using Comfort.Common; -using EFT; -using HarmonyLib.Tools; -using UnityEngine; - -namespace SPT.SinglePlayer.Utils.TraderServices -{ - internal class LightKeeperServicesManager : MonoBehaviour - { - private static ManualLogSource logger; - GameWorld gameWorld; - BotsController botsController; - - private void Awake() - { - logger = BepInEx.Logging.Logger.CreateLogSource(nameof(LightKeeperServicesManager)); - - gameWorld = Singleton.Instance; - if (gameWorld == null || TraderServicesManager.Instance == null) - { - logger.LogError("[SPT-LKS] GameWorld or TraderServices null"); - Destroy(this); - return; - } - - botsController = Singleton.Instance.BotsController; - if (botsController == null) - { - logger.LogError("[SPT-LKS] BotsController null"); - Destroy(this); - return; - } - - TraderServicesManager.Instance.OnTraderServicePurchased += OnTraderServicePurchased; - } - - private void OnTraderServicePurchased(ETraderServiceType serviceType, string subserviceId) - { - switch (serviceType) - { - case ETraderServiceType.ExUsecLoyalty: - botsController.BotTradersServices.LighthouseKeeperServices.OnFriendlyExUsecPurchased(gameWorld.MainPlayer); - break; - case ETraderServiceType.ZryachiyAid: - botsController.BotTradersServices.LighthouseKeeperServices.OnFriendlyZryachiyPurchased(gameWorld.MainPlayer); - break; - } - } - - private void OnDestroy() - { - if (gameWorld == null || botsController == null) - { - return; - } - - if (TraderServicesManager.Instance != null) - { - TraderServicesManager.Instance.OnTraderServicePurchased -= OnTraderServicePurchased; - } - } - } -} diff --git a/project/SPT.SinglePlayer/Utils/TraderServices/TraderServiceModel.cs b/project/SPT.SinglePlayer/Utils/TraderServices/TraderServiceModel.cs deleted file mode 100644 index c0afe62..0000000 --- a/project/SPT.SinglePlayer/Utils/TraderServices/TraderServiceModel.cs +++ /dev/null @@ -1,36 +0,0 @@ -using EFT; -using Newtonsoft.Json; -using System.Collections.Generic; - -namespace SPT.SinglePlayer.Utils.TraderServices -{ - public class TraderServiceModel - { - [JsonProperty("serviceType")] - public ETraderServiceType ServiceType { get; set; } - - [JsonProperty("itemsToPay")] - public Dictionary ItemsToPay { get; set; } - - [JsonProperty("subServices")] - public Dictionary SubServices { get; set; } - - [JsonProperty("itemsToReceive")] - public MongoID[] ItemsToReceive { get; set; } - - [JsonProperty("requirements")] - public TraderServiceRequirementsModel Requirements { get; set; } - } - - public class TraderServiceRequirementsModel - { - [JsonProperty("completedQuests")] - public string[] CompletedQuests { get; set; } - - [JsonProperty("standings")] - public Dictionary Standings { get; set; } - - [JsonProperty("side")] - public ESideType Side { get; set; } - } -} \ No newline at end of file diff --git a/project/SPT.SinglePlayer/Utils/TraderServices/TraderServicesManager.cs b/project/SPT.SinglePlayer/Utils/TraderServices/TraderServicesManager.cs deleted file mode 100644 index e4956db..0000000 --- a/project/SPT.SinglePlayer/Utils/TraderServices/TraderServicesManager.cs +++ /dev/null @@ -1,237 +0,0 @@ -using SPT.Common.Http; -using Comfort.Common; -using EFT; -using EFT.Quests; -using HarmonyLib; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEngine; -using static BackendConfigSettingsClass; -using StandingListClass = GClass2188; - -namespace SPT.SinglePlayer.Utils.TraderServices -{ - public class TraderServicesManager - { - /// - /// Subscribe to this event to trigger trader service logic. - /// - public event Action OnTraderServicePurchased; - - private static TraderServicesManager _instance; - - public static TraderServicesManager Instance - { - get - { - if (_instance == null) - { - _instance = new TraderServicesManager(); - } - - return _instance; - } - } - - private Dictionary> _servicePurchased { get; set; } - private HashSet _cachedTraders = new HashSet(); - private FieldInfo _playerQuestControllerField; - - public TraderServicesManager() - { - _servicePurchased = new Dictionary>(); - _playerQuestControllerField = AccessTools.Field(typeof(Player), "_questController"); - } - - public void Clear() - { - _servicePurchased.Clear(); - _cachedTraders.Clear(); - } - - public void GetTraderServicesDataFromServer(string traderId) - { - Dictionary servicesData = Singleton.Instance.ServicesData; - var gameWorld = Singleton.Instance; - var player = gameWorld?.MainPlayer; - - if (gameWorld == null || player == null) - { - Debug.LogError("GetTraderServicesDataFromServer - Error fetching game objects"); - return; - } - - if (!player.Profile.TradersInfo.TryGetValue(traderId, out Profile.TraderInfo traderInfo)) - { - Debug.LogError("GetTraderServicesDataFromServer - Error fetching profile trader info"); - return; - } - - // Only request data from the server if it's not already cached - if (!_cachedTraders.Contains(traderId)) - { - var json = RequestHandler.GetJson($"/singleplayer/traderServices/getTraderServices/{traderId}"); - var traderServiceModels = JsonConvert.DeserializeObject>(json); - - foreach (var traderServiceModel in traderServiceModels) - { - ETraderServiceType serviceType = traderServiceModel.ServiceType; - ServiceData serviceData; - - // Only populate trader services that don't exist yet - if (!servicesData.ContainsKey(traderServiceModel.ServiceType)) - { - TraderServicesClass traderService = new TraderServicesClass - { - TraderId = traderId, - ServiceType = serviceType, - UniqueItems = traderServiceModel.ItemsToReceive ?? new MongoID[0], - ItemsToPay = traderServiceModel.ItemsToPay ?? new Dictionary(), - - // SubServices seem to be populated dynamically in the client (For BTR taxi atleast), so we can just ignore it - // NOTE: For future reference, this is a dict of `point id` to `price` for the BTR taxi - SubServices = new Dictionary() - }; - - // Convert our format to the backend settings format - serviceData = new ServiceData(traderService); - - // Populate requirements if provided - if (traderServiceModel.Requirements != null) - { - if (traderServiceModel.Requirements.Standings != null) - { - serviceData.TraderServiceRequirements.Standings = new StandingListClass(); - serviceData.TraderServiceRequirements.Standings.AddRange(traderServiceModel.Requirements.Standings); - - // BSG has a bug in their code, we _need_ to initialize this if Standings isn't null - serviceData.TraderServiceRequirements.CompletedQuests = new QuestDictionaryClass(); - } - - if (traderServiceModel.Requirements.CompletedQuests != null) - { - serviceData.TraderServiceRequirements.CompletedQuests = new QuestDictionaryClass(); - serviceData.TraderServiceRequirements.CompletedQuests.Concat(traderServiceModel.Requirements.CompletedQuests); - } - } - - servicesData[serviceData.ServiceType] = serviceData; - } - } - - _cachedTraders.Add(traderId); - } - - // Update service availability - foreach (var servicesDataPair in servicesData) - { - // Only update this trader's services - if (servicesDataPair.Value.TraderId != traderId) - { - continue; - } - - var IsServiceAvailable = this.IsServiceAvailable(player, servicesDataPair.Value.TraderServiceRequirements); - - // Check whether we've purchased this service yet - var traderService = servicesDataPair.Key; - var WasPurchasedInThisRaid = IsServicePurchased(traderService, traderId); - traderInfo.SetServiceAvailability(traderService, IsServiceAvailable, WasPurchasedInThisRaid); - } - } - - private bool IsServiceAvailable(Player player, ServiceRequirements requirements) - { - // Handle standing requirements - if (requirements.Standings != null) - { - foreach (var entry in requirements.Standings) - { - if (!player.Profile.TradersInfo.ContainsKey(entry.Key) || - player.Profile.TradersInfo[entry.Key].Standing < entry.Value) - { - return false; - } - } - } - - // Handle quest requirements - if (requirements.CompletedQuests != null) - { - AbstractQuestControllerClass questController = _playerQuestControllerField.GetValue(player) as AbstractQuestControllerClass; - foreach (string questId in requirements.CompletedQuests) - { - var conditional = questController.Quests.GetConditional(questId); - if (conditional == null || conditional.QuestStatus != EQuestStatus.Success) - { - return false; - } - } - } - - return true; - } - - public void AfterPurchaseTraderService(ETraderServiceType serviceType, AbstractQuestControllerClass questController, string subServiceId = null) - { - GameWorld gameWorld = Singleton.Instance; - Player player = gameWorld?.MainPlayer; - - if (gameWorld == null || player == null) - { - Debug.LogError("TryPurchaseTraderService - Error fetching game objects"); - return; - } - - // Service doesn't exist - if (!Singleton.Instance.ServicesData.TryGetValue(serviceType, out var serviceData)) - { - return; - } - - SetServicePurchased(serviceType, subServiceId, serviceData.TraderId); - } - - public void SetServicePurchased(ETraderServiceType serviceType, string subserviceId, string traderId) - { - if (_servicePurchased.TryGetValue(serviceType, out var traderDict)) - { - traderDict[traderId] = true; - } - else - { - _servicePurchased[serviceType] = new Dictionary(); - _servicePurchased[serviceType][traderId] = true; - } - - if (OnTraderServicePurchased != null) - { - OnTraderServicePurchased.Invoke(serviceType, subserviceId); - } - } - - public void RemovePurchasedService(ETraderServiceType serviceType, string traderId) - { - if (_servicePurchased.TryGetValue(serviceType, out var traderDict)) - { - traderDict[traderId] = false; - } - } - - public bool IsServicePurchased(ETraderServiceType serviceType, string traderId) - { - if (_servicePurchased.TryGetValue(serviceType, out var traderDict)) - { - if (traderDict.TryGetValue(traderId, out var result)) - { - return result; - } - } - - return false; - } - } -}