public LevelViewModel(LocalizedString levelName, Action <LevelViewModel> onChangedIsUnlocked, bool branched = false, int link = -1, bool canIsUnlockedBeModified = true, FinBossLevel bossFlag = FinBossLevel.None, bool hasCages = true) { LevelName = levelName; OnChangedIsUnlocked = onChangedIsUnlocked; Branched = branched; Link = link; CanIsUnlockedBeModified = canIsUnlockedBeModified && link == -1; BossFlag = bossFlag; HasCages = hasCages; }
// The game calls this when generating and loading a password to make sure it's valid (0x801a1b14). We re-implement it here to make sure generated passwords will be accepted by the game. public string Validate() { // Get the level index byte level = LevelIndex; // Make sure the level is not above the allowed range or set to any of the branched levels if (level >= 18 || 1 >= (byte)(level - 2) || 1 >= (byte)(level - 6)) { return($"Invalid level index of {level}"); } // Lives have a range of 0-99 if (LivesCount >= 100) { return($"Invalid lives count of {LivesCount}"); } // Continues have a range of 0-9 if (Continues >= 10) { return($"Invalid continues count of {Continues}"); } // Make sure bosses haven't been marked as complete if the level hasn't been reached if (FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.Moskito)) { if (!WorldInfo[3].IsUnlocked || level <= 3) { return($"Moskito has been beaten under invalid circumstances"); } } else { if (level >= 9) { return($"Moskito has to be beaten before Twilight Gulch"); } } if (FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.MrSax) && (!WorldInfo[7].IsUnlocked || level <= 7)) { return($"Mr Sax has been beaten under invalid circumstances"); } if (FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.HelpedMusician)) { if (level <= 9) { return($"Helped The Musician under invalid circumstances"); } } else { if (level >= 11 || WorldInfo[11].HasAllCages) { return($"Hasn't helped The Musician"); } } if (FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.MrSkops)) { if (level <= 15 || !FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.HelpedMusician) || !FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.Moskito)) { return($"Mr Skops has been beaten under invalid circumstances"); } } else { if (level >= 17 || FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.MrDark)) { return($"Mr Skops has to be beaten before Mr Dark"); } } // Jungle branch if (WorldInfo[3].IsUnlocked) { if (level <= 3) { return($"Jungle branch should not be unlocked"); } } else { if (WorldInfo[3].HasAllCages || FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.Moskito)) { return($"Jungle branch should be unlocked"); } } // Music branch if (WorldInfo[7].IsUnlocked) { if (level <= 7) { return($"Music branch should not be unlocked"); } } else { if (WorldInfo[7].HasAllCages || FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.MrSax)) { return($"Music branch should be unlocked"); } } for (int i = level + 1; i <= 17; i++) { if (WorldInfo[i].HasAllCages) { return($"Cages found in locked level {i}"); } } if (level > 8 && (!FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.Moskito) || !WorldInfo[3].IsUnlocked)) { return($"Moskito has to be beaten and unlocked before Twilight Gulch"); } if ((level == 17) || WorldInfo[17].HasAllCages) { var cages = WorldInfo.Take(17).Count(x => x.HasAllCages); if (cages != 17 || !FinBossLevel.HasFlag(Rayman1FinBossLevelFlags.MrSkops) || !WorldInfo[3].IsUnlocked || !WorldInfo[7].IsUnlocked) { return($"Last level has been unlocked under invalid circumstances"); } } return(null); }