using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using CIG; using CIG.Translation; using CIG3.ExtensionMethods; using CIGEnums; using SUISS.Core; using SUISS.Scheduling; using SUISS.Storage; using SUISSEngine; using UnityEngine; public class CIGGameState : GameState { protected override StorageLifecycle GetLifecycle() { return StorageLifecycle.Game; } protected override string GetStorageKey() { return this.storageKey; } protected override void Start() { base.Start(); if (SingletonMonobehaviour.Instance != null) { SingletonMonobehaviour.Instance.StartLeaderboards(); SingletonMonobehaviour.Instance.StartRoutine(this._syncGameScoresRoutine = this.SyncGameScores()); } this.CheckGlobalValues(); this.GiveLevelUpReward(); } private IEnumerator SyncGameScores() { for (;;) { CIGSparkSocServices sparksoc = SingletonMonobehaviour.Instance; if (sparksoc != null) { this.PostNewHighscores(sparksoc); } yield return Timing.time + 300.0; } yield break; } private void PostNewHighscores(CIGSparkSocServices sparksoc) { sparksoc.PostNewHighScores(this.Level, this.GlobalPopulation, this.GetIslandsUnlockedCount(), (int)Mathf.Round(this.LevelProgress * 100f)); } protected override void OnNewGameState() { base.OnNewGameState(); for (int i = 0; i < this.initialIslandUnlocks.Length; i++) { this.SetIslandUnlocked(this.initialIslandUnlocks[i]); } this.RecalculateRequiredXP(1); this.Level = 1; this.Balance = this.InitialBalance; this.GiftedBalance = Currencies.Zero; this.CurrenciesEarned = Currencies.Zero; this.CurrenciesSpent = Currencies.Zero; this.GlobalHappiness = this.BaseHappiness; this.GlobalPopulation = 0; this.GlobalHousing = 0; this.GlobalEmployees = 0; this.GlobalJobs = 0; this.UnprocessedChestGold = 0m; this.SpeedupWithCashEnabled = false; this.MaxBuildingLevel10 = true; } protected override void Awake() { base.Awake(); for (int i = 0; i < this.Levels.Length; i++) { LevelDefinition levelDefinition = this.Levels[i]; decimal value = 30000.0m + (i + 1) * 10000.0m; levelDefinition.Reward = new Currencies("Cash", value); } object[] array = this.GetValue("RequiredXPValues", new object[0]); int num = -1; for (int j = 0; j < array.Length; j++) { this.Levels[j].XP = (int)array[j]; if (j > 0 && this.Levels[j].XP < this.Levels[j - 1].XP) { if (num < 0) { num = this.Levels[j - 1].XP; } this.Levels[j].XP += num; } } if (array.Length != this.Levels.Length) { object[] array2 = new object[this.Levels.Length]; int num2 = 0; while (num2 < array.Length && num2 < array2.Length) { array2[num2] = array[num2]; num2++; } for (int k = array.Length; k < array2.Length; k++) { array2[k] = 0; } int level = this.Level; int num3 = array.Length; while (num3 <= level && num3 < array2.Length) { this.RecalculateRequiredXP(num3); array2[num3] = this.Levels[num3].XP; num3++; } array = array2; this.SetValue("RequiredXPValues", array); for (int l = 0; l < array.Length; l++) { this.Levels[l].XP = (int)array[l]; } } if (!this.GetValue("CloudStorageMigrationCompleted", false) && InstallVersion.InstallVersionName != "?" && new Version(InstallVersion.InstallVersionName) < new Version(2, 3, 0)) { if (StorageController.HasLoadedCloudSave) { Singleton.Instance.CloudStorageState = CloudStorageState.Activated; } this.SetValue("CloudStorageMigrationCompleted", true); UnityEngine.Debug.Log("Performed cloud storage activation migration"); } bool flag = false; if (this.UnprocessedChestGold > 0m) { this.Balance += new Currencies("Gold", this.UnprocessedChestGold); this.UnprocessedChestGold = 0m; flag = true; } object obj; if (Storage.Get(StorageLifecycle.Forever).Root.TryGetValue("UnprocessedPurchase", out obj)) { if (obj is Currencies) { this.GiveCurrencies(obj as Currencies); this.CountBoughtGoldPackageIfApplicable(obj as Currencies); } Storage.Get(StorageLifecycle.Forever).Root.Remove("UnprocessedPurchase"); flag = true; } if (this.Level <= this.Levels.Length) { Currencies earnedBalance = this.EarnedBalance; decimal value2 = earnedBalance.GetValue("XP"); if (value2 < this.Levels[this.Level - 1].XP) { this.SetValue("EarnedBalance", earnedBalance.WithoutXPCurrency() + new Currencies("XP", this.Levels[this.Level - 1].XP)); flag = true; } } if (flag) { StorageController.SaveAll(); } } protected override void OnDestroy() { if (this._syncGameScoresRoutine != null && SingletonMonobehaviour.IsAvailable) { SingletonMonobehaviour.Instance.StopRoutine(this._syncGameScoresRoutine); this._syncGameScoresRoutine = null; } base.OnDestroy(); } //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event Action LevelledUp; protected virtual void OnLevelledUp(int arg) { Action levelledUp = this.LevelledUp; if (levelledUp != null) { levelledUp(arg); } } //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event CIGGameState.BalanceChangedEventHandler BalanceChangedEvent; private void FireBalanceChangedEvent(Currencies oldBalance, Currencies newBalance, object earnSource) { if (this.BalanceChangedEvent != null) { this.BalanceChangedEvent(oldBalance, newBalance, earnSource); } } public int MaxLevel { get { return this.Levels.Length - 1; } } public int Level { get { return this.GetValue("Level", 1); } private set { this.SetValue("Level", value); } } public bool ReachedMaxLevel { get { return this.Level >= this.MaxLevel; } } public float LevelProgress { get { float num = (float)this.Balance.GetValue("XP"); float num4; if (this.Level >= this.Levels.Length) { float num2; if (this.Level == this.MaxLevel + 1) { num2 = (float)this.Levels[this.Level - 1].XP; } else { num2 = (float)this.XPNeededForGeneratedLevel(this.Level - 1); } float num3 = (float)this.XPNeededForGeneratedLevel(this.Level); num4 = (num - num2) / (num3 - num2); } else { float num5 = (float)this.Levels[this.Level - 1].XP; float num6 = (float)this.Levels[this.Level].XP; num4 = (num - num5) / (num6 - num5); } if (num4 < 0f) { num4 = 0f; } else if (num4 > 1f) { num4 = 1f; } return num4; } } public Currencies GiftedBalance { get { return this.GetValue("GiftedBalance", new Currencies()); } private set { if (value.ContainsPositive("XP")) { this.EarnedBalance += new Currencies("XP", value.GetValue("XP")); } this.SetValue("GiftedBalance", value.WithoutXPCurrency()); } } public Currencies EarnedBalance { get { return this.GetValue("EarnedBalance", new Currencies()); } private set { decimal value2 = this.ProcessXPGain(value.GetValue("XP")); Currencies value3 = value.WithoutXPCurrency() + new Currencies("XP", value2); this.SetValue("EarnedBalance", value3); } } public Currencies Balance { get { return this.EarnedBalance + this.GiftedBalance; } private set { this.EarnedBalance = Currencies.NonNegative(value - this.GiftedBalance); this.GiftedBalance = this.GiftedBalance.Cap(value - this.EarnedBalance, true); } } public Currencies CurrenciesEarned { get { return this.GetValue("CurrenciesEarned", new Currencies()); } private set { this.SetValue("CurrenciesEarned", value); } } public Currencies CurrenciesSpent { get { return this.GetValue("CurrenciesSpent", new Currencies()); } private set { this.SetValue("CurrenciesSpent", value); } } public decimal UnprocessedChestGold { get { return this.GetValue("UnprocessedChestGold", 0m); } set { this.SetValue("UnprocessedChestGold", (!(value > 0m)) ? 0m : value); } } public int GlobalHappiness { get { return this.GetValue("GlobalHappiness", 0); } private set { this.SetValue("GlobalHappiness", value); } } public int GlobalPopulation { get { return this.GetValue("GlobalPopulation", 0); } private set { this.SetValue("GlobalPopulation", value); } } public int GlobalHousing { get { return this.GetValue("GlobalHousing", 0); } private set { this.SetValue("GlobalHousing", value); } } public int GlobalEmployees { get { return this.GetValue("GlobalEmployees", 0); } private set { this.SetValue("GlobalEmployees", value); } } public int GlobalJobs { get { return this.GetValue("GlobalJobs", 0); } private set { this.SetValue("GlobalJobs", value); } } public Currencies LevelUpReward { get { return this.GetValue("LevelUpReward", new Currencies()); } private set { this.SetValue("LevelUpReward", value); } } public bool SpeedupWithCashEnabled { get { return this.GetValue("SpeedupWithCashEnabled", true); } private set { this.SetValue("SpeedupWithCashEnabled", value); } } public bool MaxBuildingLevel10 { get { return this.GetValue("MaxBuildingLevel10", false); } private set { this.SetValue("MaxBuildingLevel10", value); } } public bool IsConnectionUnlocked(Island island1, Island island2) { if (island1.IsValid() && island2.IsValid()) { return this.GetValue("IslandConnections", string.Empty).Contains(this.GetConnectionString(island1, island2)); } UnityEngine.Debug.LogWarning(string.Concat(new string[] { "Invalid islands (", island1.ToString(), ", ", island2.ToString(), ") passed to IsConnectionUnlocked()" })); return false; } public void SetConnectionUnlocked(Island island1, Island island2) { if (island1.IsValid() && island2.IsValid()) { if (!this.IsConnectionUnlocked(island1, island2)) { this.SetValue("IslandConnections", this.GetValue("IslandConnections", string.Empty) + this.GetConnectionString(island1, island2)); } } else { UnityEngine.Debug.LogWarning(string.Concat(new string[] { "Invalid islands (", island1.ToString(), ", ", island2.ToString(), ") passed to SetConnectionUnlocked()" })); } } public bool IsIslandUnlocked(Island island) { if (island.IsValid()) { return this.GetValue("UnlockedIsland" + island.GetIndex().ToString(), false); } UnityEngine.Debug.LogWarning("Invalid island (" + island.ToString() + ") passed to IsIslandUnlocked()"); return false; } public int GetIslandsUnlockedCount() { int num = 0; foreach (Island island in IslandExtensions.GetIslands()) { if (island.IsValid() && this.IsIslandUnlocked(island)) { num++; } } return num; } public void SetIslandUnlocked(Island island) { if (island.IsValid()) { bool flag = this.IsIslandUnlocked(island); this.SetValue("UnlockedIsland" + island.GetIndex().ToString(), true); if (!flag) { this.stats.AddIslandUnlocked(); } } else { UnityEngine.Debug.LogWarning("Invalid island (" + island.ToString() + ") passed to SetIslandUnlocked()"); } } public decimal GetXpForLevelsUp(decimal levelsUp) { int i = this.Level - 1; int num = this.Level + (int)Math.Ceiling(levelsUp) + 1; while (i < num) { this.RecalculateRequiredXP(i); i++; } decimal d = Math.Min(1m - (decimal)this.LevelProgress, levelsUp); levelsUp -= d; int num2 = (int)Math.Floor(levelsUp); decimal d2 = levelsUp - num2; decimal d3 = (this.GetXpForLevel(this.Level) - this.GetXpForLevel(this.Level - 1)) * d; decimal d4 = this.GetXpForLevel(this.Level + num2) - this.GetXpForLevel(this.Level); decimal d5 = (this.GetXpForLevel(this.Level + num2 + 1) - this.GetXpForLevel(this.Level + num2)) * d2; return d3 + d4 + d5; } public void EarnCurrencies(Currencies c, object earnSource = null) { Currencies balance = this.Balance; this.Balance += c; this.CurrenciesEarned += c; this.FireBalanceChangedEvent(balance, this.Balance, earnSource); } public void GiveCurrencies(Currencies c) { Currencies balance = this.Balance; this.GiftedBalance += c; this.FireBalanceChangedEvent(balance, this.Balance, null); } public void CountBoughtGoldPackageIfApplicable(Currencies bought) { if (bought.Contains("Gold")) { this.stats.AddNumberOfGoldPackagesBought(1); } } public bool SpendCurrencies(Currencies c, bool enableGoldAsAlternativeForCash, Action purchaseCallback) { Currencies currencies = this.Balance.MissingCurrencies(c); if (!currencies.IsEmpty()) { SingletonMonobehaviour.Instance.OpenYouNeedMore(c, enableGoldAsAlternativeForCash, purchaseCallback); return false; } ServiceLocator.Find().Invoke>(new InterestingRatingTriggerEvent(CIGInterestingRatingTriggerEventType.SpendCurrencies)); Currencies balance = this.Balance; this.Balance -= c; this.CurrenciesSpent += c; if (purchaseCallback != null) { purchaseCallback(true, c); } this.FireBalanceChangedEvent(balance, this.Balance, null); return true; } public void AddGlobalPopulation(int pop) { this.GlobalPopulation += pop; } public void AddGlobalHousing(int room) { this.GlobalHousing += room; } public void AddGlobalHappiness(int smiles) { this.GlobalHappiness += smiles; } public void AddGlobalEmployees(int emp) { this.GlobalEmployees += emp; } public void AddGlobalJobs(int jobs) { this.GlobalJobs += jobs; } public void GiveLevelUpReward() { Currencies levelUpReward = this.LevelUpReward; if (levelUpReward.IsEmpty()) { return; } if (levelUpReward.ContainsPositive("Gold")) { } this.GiveCurrencies(levelUpReward); this.LevelUpReward = new Currencies(); } public int XPNeededForGeneratedLevel(int level) { return this.Levels[this.MaxLevel].XP + (level - this.MaxLevel) * 50000; } protected void CheckGlobalValues() { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; IEnumerator enumerator = Enum.GetValues(typeof(Island)).GetEnumerator(); try { while (enumerator.MoveNext()) { object obj = enumerator.Current; Island island = (Island)obj; if (island.IsValid()) { Dictionary dictionary = CIGIslandState.GetDictionary(island); num += dictionary.GetInt("Happiness", 0); num2 += dictionary.GetInt("Housing", 0); num3 += dictionary.GetInt("Population", 0); num4 += dictionary.GetInt("Jobs", 0); num5 += dictionary.GetInt("Employees", 0); } } } finally { IDisposable disposable; if ((disposable = (enumerator as IDisposable)) != null) { disposable.Dispose(); } } if (num != this.GlobalHappiness) { UnityEngine.Debug.LogWarning(string.Format("GlobalHappiness {0} does not match sum of (island) happiness {1}.", this.GlobalHappiness, num)); this.GlobalHappiness = num; } if (num2 != this.GlobalHousing) { UnityEngine.Debug.LogWarning(string.Format("GlobalHousing {0} does not match sum of (island) housing {1}.", this.GlobalHousing, num2)); this.GlobalHousing = num2; } if (num3 != this.GlobalPopulation) { UnityEngine.Debug.LogWarning(string.Format("GlobalPopulation {0} does not match sum of (island) population {1}.", this.GlobalPopulation, num3)); this.GlobalPopulation = num3; } if (num4 != this.GlobalJobs) { UnityEngine.Debug.LogWarning(string.Format("GlobalJobs {0} does not match sum of (island) jobs {1}.", this.GlobalJobs, num4)); this.GlobalJobs = num4; } if (num5 != this.GlobalEmployees) { UnityEngine.Debug.LogWarning(string.Format("GlobalEmployees {0} does not match sum of (island) employees {1}.", this.GlobalEmployees, num5)); this.GlobalEmployees = num5; } } private decimal ProcessXPGain(decimal newXp) { if (!this.ReachedMaxLevel) { return this.ProcessXPGainManual(newXp); } return this.ProcessXPGainGenerated(newXp); } private decimal ProcessXPGainManual(decimal newXp) { if (this.Level >= this.Levels.Length) { UnityEngine.Debug.LogWarning("What is there to process? Player is max level already"); return 0m; } decimal d = this.Levels[this.Level].XP; while (this.Level < this.Levels.Length && newXp >= d) { this.LevelUpManual(); if (this.Level == this.Levels.Length) { return this.ProcessXPGainGenerated(newXp); } d = this.Levels[this.Level].XP; } return newXp; } private decimal ProcessXPGainGenerated(decimal newXp) { if (this.Level == 150) { UnityEngine.Debug.LogWarning("What is there to process? Player is max generated level already"); return 0m; } int value = this.XPNeededForGeneratedLevel(this.Level); while (newXp >= value) { this.LevelUpGenerated(); if (this.Level == 150) { return value; } value = this.XPNeededForGeneratedLevel(this.Level); } return newXp; } private void LevelUpManual() { if (this.Level >= this.Levels.Length) { UnityEngine.Debug.LogWarning("Can't level up because the maximum level has been reached already."); return; } this.RecalculateRequiredXP(this.Level + 1); this.IncreaseLevel(); Currencies reward = this.Levels[this.Level - 1].Reward; this.LevelUpReward += reward; this.LevelledUpPopups(reward); this.OnLevelledUp(this.Level); } private void LevelUpGenerated() { this.IncreaseLevel(); Currencies currencies = new Currencies("Gold", 2m); this.LevelUpReward += currencies; this.LevelledUpPopups(currencies); this.OnLevelledUp(this.Level); } private void IncreaseLevel() { int level = this.Level; this.Level++; int level2 = this.Level; int numberOfTimesPlayed = SingletonMonobehaviour.Instance.NumberOfTimesPlayed; if (numberOfTimesPlayed != 1) { if (numberOfTimesPlayed == 2) { } } else { } } protected void LevelledUpPopups(Currencies reward) { ServiceLocator.Find().Invoke>(new InterestingRatingTriggerEvent(CIGInterestingRatingTriggerEventType.LevelUp)); SingletonMonobehaviour.Instance.PlayClip(Clip.Applause); int popupLevel = this.Level; PopupManager instance = SingletonMonobehaviour.Instance; instance.RequestPopup(delegate(State state) { SingletonMonobehaviour.Instance.AddScreenViewed("level_up"); ((LevelUpPopupState)state).UpdateElements(popupLevel, reward); }); if (this.Level == Mathf.Max(this.MaxLevel, 150)) { instance.RequestGenericPopup(UISpriteType.Star, Localization.Key("maxed_out_header"), Localization.Key("max_level_reached"), Localization.Key("ok"), null, null, null, null, true); } } private string GetConnectionString(Island island1, Island island2) { int num = island1.GetIndex(); int num2 = island2.GetIndex(); if (num > num2) { int num3 = num; num = num2; num2 = num3; } return string.Format(":{0}-{1}:", num, num2); } private void RecalculateRequiredXP(int level) { if (level < 0 || level >= this.Levels.Length) { return; } decimal num; if (level <= 0) { num = 0.0m; } else if (level == 1) { num = 200.0m; } else { if (level < CIGGameState.BASE_XP_PER_LEVEL.Length) { num = CIGGameState.BASE_XP_PER_LEVEL[level]; } else { num = CIGGameState.BASE_XP_PER_LEVEL[CIGGameState.BASE_XP_PER_LEVEL.Length - 1]; } if (level > 12 || (int)Math.Round(num) == 0) { decimal d = (decimal)(this.FactorMinutesPerLevel + (float)level * this.FactorMinutesPerLevelPerLevel); num += this.stats.GlobalProfitPerHour.GetValue("XP") / 60.0m * level * d; } } num *= (decimal)base.GetComponent().FactorForUpLevellingSpeed; int num2; if (level == 0) { num2 = (int)num; } else { num2 = this.Levels[level - 1].XP + (int)num; } this.Levels[level].XP = num2; object[] value = this.GetValue("RequiredXPValues", new object[0]); if (value != null && level < value.Length) { value[level] = num2; } } private int GetXpForLevel(int level) { return (level <= this.MaxLevel) ? this.Levels[level].XP : this.XPNeededForGeneratedLevel(level); } public const string LevelKey = "Level"; public const string EarnedBalanceKey = "EarnedBalance"; public const string GiftedBalanceKey = "GiftedBalance"; public const string CurrenciesEarnedKey = "CurrenciesEarned"; public const string CurrenciesSpentKey = "CurrenciesSpent"; public const string GlobalHappinessKey = "GlobalHappiness"; public const string GlobalPopulationKey = "GlobalPopulation"; public const string GlobalHousingKey = "GlobalHousing"; public const string GlobalEmployeesKey = "GlobalEmployees"; public const string GlobalJobsKey = "GlobalJobs"; public const string RequiredXPValuesKey = "RequiredXPValues"; public const string CashCurrency = "Cash"; public const string GoldCurrency = "Gold"; public const string XPCurrency = "XP"; public const string LevelUpCurrency = "LevelUp"; public const string UnprocessedPurchaseKey = "UnprocessedPurchase"; public const string UnprocessedChestGoldKey = "UnprocessedChestGold"; public const string IslandUnlockedKeyPrefix = "UnlockedIsland"; public const string CraneCountKeyPrefix = "CraneCount"; public const string IslandConnectionsKey = "IslandConnections"; public const string LevelUpRewardKey = "LevelUpReward"; public const int GeneratedLevelXPIncrements = 50000; public const int MaxGeneratedLevel = 150; private const string SpeedupWithCashEnabledKey = "SpeedupWithCashEnabled"; private const string MaxBuildingLevel10Key = "MaxBuildingLevel10"; private const string CloudStorageMigrationCompletedKey = "CloudStorageMigrationCompleted"; public string storageKey = "GameState"; [SelfReference] public GameObjectManager prefabManager; [SelfReference] public CIGGameStats stats; public Currencies InitialBalance = new Currencies(); public LevelDefinition[] Levels = new LevelDefinition[0]; public int BaseHappiness; public Island[] initialIslandUnlocks; [Tooltip("een level duurt zo lang als de waarde van het level maal dit getal, in minuten")] public float FactorMinutesPerLevel = 0.1f; [Tooltip("PER LEVEL gaat de factor hierboven omhoog")] public float FactorMinutesPerLevelPerLevel = 0.175f; private IEnumerator _syncGameScoresRoutine; private static readonly long[] BASE_XP_PER_LEVEL = new long[] { 132L, 212L, 292L, 372L, 452L, 532L, 612L, 692L, 772L, 935L, 965L, 1335L, 1705L, 2075L, 2445L, 2815L, 3185L, 3555L, 3925L, 4661L, 4990L, 5377L, 5764L, 6151L, 6538L, 6925L, 7312L, 7699L, 8086L, 8858L, 10108L, 10604L, 11100L, 11596L, 12092L, 12588L, 13084L, 13580L, 14076L, 15063L, 17595L, 17760L, 17925L, 18090L, 18255L, 18420L, 18585L, 18750L, 18915L, 19241L, 23644L, 23644L, 23644L, 23644L, 23644L, 23644L, 23644L, 23644L, 23644L, 23644L, 28165L, 28165L, 28165L, 28165L, 28165L, 28165L, 28165L, 28165L, 28165L, 28165L, 31986L, 31986L, 31986L, 31986L, 31986L, 31986L, 31986L, 31986L, 31986L, 31986L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L, 39723L }; public delegate void BalanceChangedEventHandler(Currencies oldBalance, Currencies newBalance, object earnSource); }