using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using CIG; using CIG.Translation; using CIGEnums; using SUISS.Core; using SUISS.Core.Utilities; using SUISSEngine; using UnityEngine; [RequireComponent(typeof(Serializing))] public sealed class CIGBuyOneBuildingGetOneFreeManager : SingletonMonobehaviour { //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event CIGBuyOneBuildingGetOneFreeManager.StateChangedEventHandler StateChangedEvent; private void FireStateChangedEvent() { if (this.StateChangedEvent != null) { this.StateChangedEvent(); } } protected override void OnDestroy() { this.StopSaleIntervalRoutine(); this.StopTimeOutRoutine(); base.OnDestroy(); } public void Buy() { if (this.State == CIGBuyOneBuildingGetOneFreeManager.BuyOneBuildingGetOneFreeState.Active) { SingletonMonobehaviour.Instance.CloseRecursive(true); if (SingletonMonobehaviour.Instance.SpendCurrencies(this.PaidBuilding.PurchasePrice, false, null)) { int num = (int)this.PaidBuilding.PurchasePrice.GetValue("Gold"); CIGGameStats instance = SingletonMonobehaviour.Instance; instance.AddGoldSpent_DiscountedGoldBuildings(num); instance.AddVirtualCurrencySpent(); SingletonMonobehaviour.Instance.AddBuilding(this.PaidBuilding); SingletonMonobehaviour.Instance.AddBuilding(this.FreeBuilding); CIGBuilding cigbuilding = null; this.FreeBuilding = cigbuilding; this.PaidBuilding = cigbuilding; this.StopTimeOutRoutine(); this.SetStateInactive(); this.StartSaleIntervalRoutine(); SingletonMonobehaviour.Instance.RequestGenericPopup(UISpriteType.ShopIcon, Localization.Key("reward_congratulations"), Localization.Key("purchased_buildings_in_menu"), Localization.Key("thank_you"), null, null, null, null, true); } } } public CIGBuyOneBuildingGetOneFreeManager.BuyOneBuildingGetOneFreeState State { get; private set; } public TimeSpan SaleTimeLeft { get { DateTime utcNow = DateTime.UtcNow; if (this._saleEndsAt < utcNow) { return TimeSpan.Zero; } return this._saleEndsAt - utcNow; } } public CIGBuilding FreeBuilding { get; private set; } public CIGBuilding PaidBuilding { get; private set; } private bool FindGoldBuildings(out CIGBuilding paidBuilding, out CIGBuilding freeBuilding) { CIGBuilding cigbuilding; freeBuilding = (cigbuilding = null); paidBuilding = cigbuilding; List list = new List(); foreach (CIGBuilding cigbuilding2 in SingletonMonobehaviour.Instance.AllBuildings) { if (cigbuilding2.IsUnlocked && !cigbuilding2.activatable && !this.HasReachedBuiltLimit(cigbuilding2) && cigbuilding2.PurchasePrice.ContainsPositive("Gold")) { list.Add(cigbuilding2); } } int num = list.Count; if (num > 1) { paidBuilding = list.PickRandom(); list.Remove(paidBuilding); num--; list.Sort((CIGBuilding a, CIGBuilding b) => this.GetGoldPrice(a).CompareTo(this.GetGoldPrice(b))); if (this.GetGoldPrice(list[0]) > this.GetGoldPrice(paidBuilding)) { freeBuilding = list[0]; } else { for (int j = 0; j < num; j++) { if (!(this.GetGoldPrice(list[j]) <= this.GetGoldPrice(paidBuilding))) { decimal freeBuildingPurchasePrice = this.GetGoldPrice(freeBuilding); freeBuilding = list.FindAll((CIGBuilding b) => this.GetGoldPrice(b) == freeBuildingPurchasePrice).PickRandom(); break; } freeBuilding = list[j]; } } return true; } UnityEngine.Debug.LogWarningFormat("Found only {0} available gold buildings which is not enough. Skipping Buy One Building Get One Free sale.", new object[] { num }); return false; } private IEnumerator SaleIntervalRoutine() { yield return new WaitForSecondsRealtime(480f); CIGBuilding paid; CIGBuilding free; if (UnityEngine.Random.value < 0.25f && this.FindGoldBuildings(out paid, out free)) { this.PaidBuilding = paid; this.FreeBuilding = free; this._saleEndsAt = DateTime.UtcNow.AddSeconds(600.0); this.SetStateActive(); this._startSaleRoutine = null; } yield break; } private void StartSaleIntervalRoutine() { this.StopSaleIntervalRoutine(); base.StartCoroutine(this._startSaleRoutine = this.SaleIntervalRoutine()); } private void StopSaleIntervalRoutine() { if (this._startSaleRoutine != null) { base.StopCoroutine(this._startSaleRoutine); this._startSaleRoutine = null; } } private IEnumerator SaleTimeout() { yield return new WaitForSecondsRealtime((float)(this._saleEndsAt - DateTime.UtcNow).TotalSeconds); if (this.State == CIGBuyOneBuildingGetOneFreeManager.BuyOneBuildingGetOneFreeState.Active) { this.SetStateInactive(); } this._saleTimeoutRoutine = null; this.StartSaleIntervalRoutine(); yield break; } private void StartTimeoutRoutine() { this.StopTimeOutRoutine(); base.StartCoroutine(this._saleTimeoutRoutine = this.SaleTimeout()); } private void StopTimeOutRoutine() { if (this._saleTimeoutRoutine != null) { base.StopCoroutine(this._saleTimeoutRoutine); this._saleTimeoutRoutine = null; } } private void SetStateActive() { this.State = CIGBuyOneBuildingGetOneFreeManager.BuyOneBuildingGetOneFreeState.Active; this.StartTimeoutRoutine(); this.FireStateChangedEvent(); this._serializing.Serialize(); } private void SetStateInactive() { this.State = CIGBuyOneBuildingGetOneFreeManager.BuyOneBuildingGetOneFreeState.Inactive; this._saleEndsAt = DateTime.UtcNow; this.StopTimeOutRoutine(); this.FireStateChangedEvent(); this._serializing.Serialize(); } private decimal GetGoldPrice(CIGBuilding building) { if (building.PurchasePrice.ContainsPositive("Gold")) { return building.PurchasePrice.GetValue("Gold"); } return 0m; } private bool HasReachedBuiltLimit(CIGBuilding building) { int strictMax = building.strictMax; return strictMax >= 0 && SingletonMonobehaviour.Instance.NumberOf(building.CachedName) >= strictMax; } private void OnSerialize(Dictionary values) { values["BOBGOFState"] = (int)this.State; values["BOBGOFEndsAt"] = this._saleEndsAt.ToBinary(); this.SetOrRemove("BOBGOFPaidBuilding", this.PaidBuilding, values); this.SetOrRemove("BOBGOFFreeBuilding", this.FreeBuilding, values); } private void OnDeserialize(Dictionary values) { this.State = (CIGBuyOneBuildingGetOneFreeManager.BuyOneBuildingGetOneFreeState)values.GetInt("BOBGOFState", 0); this._saleEndsAt = DateTime.FromBinary(values.GetLong("BOBGOFEndsAt", 0L)); string @string = values.GetString("BOBGOFPaidBuilding", string.Empty); this.PaidBuilding = SingletonMonobehaviour.Instance.GetBuilding(@string); string string2 = values.GetString("BOBGOFFreeBuilding", string.Empty); this.FreeBuilding = SingletonMonobehaviour.Instance.GetBuilding(string2); if (this.PaidBuilding == null || this.FreeBuilding == null) { this.State = CIGBuyOneBuildingGetOneFreeManager.BuyOneBuildingGetOneFreeState.Inactive; this._saleEndsAt = DateTime.UtcNow; values.Remove("BOBGOFPaidBuilding"); values.Remove("BOBGOFFreeBuilding"); } if (this.State == CIGBuyOneBuildingGetOneFreeManager.BuyOneBuildingGetOneFreeState.Inactive) { this.StartSaleIntervalRoutine(); } else { this.StartTimeoutRoutine(); } } private void SetOrRemove(string key, CIGBuilding building, Dictionary storage) { if (building == null) { storage.Remove(key); } else { storage[key] = building.CachedName; } } public const string TrackingName = "BOBGOF"; private const int SaleDurationInSeconds = 600; private const int TryStartingSaleIntervalInSeconds = 480; private const float NormalisedChanceSaleStarts = 0.25f; private const string StateKey = "BOBGOFState"; private const string SaleEndAtKey = "BOBGOFEndsAt"; private const string PaidBuildingKey = "BOBGOFPaidBuilding"; private const string FreeBuildingKey = "BOBGOFFreeBuilding"; [SerializeField] private Serializing _serializing; private IEnumerator _startSaleRoutine; private DateTime _saleEndsAt; private IEnumerator _saleTimeoutRoutine; public enum BuyOneBuildingGetOneFreeState { Inactive, Active } public delegate void StateChangedEventHandler(); }