public static BossAttributes GetReplacedBoss(Level level, int vanillaBossId) { if (!level.GameSave.GetSettings().BossRando.Value) { return(GetBossAttributes(level, vanillaBossId)); } int[] validBosses = GetValidBosses(level); Random random = new Random((int)level.GameSave.GetSeed().Value.Id); int[] replacedBosses = validBosses.OrderBy(x => random.Next()).ToArray(); int bossIndex = Array.IndexOf(validBosses, vanillaBossId, 0); if (bossIndex == -1) { return(GetBossAttributes(level, vanillaBossId)); } int replacedBossId = replacedBosses[bossIndex]; BossAttributes replacedBossInfo = GetBossAttributes(level, replacedBossId); return(replacedBossInfo); }
public static void SetBossKillSave(Level level, int vanillaBossId) { BossAttributes vanillaBossInfo = GetBossAttributes(level, vanillaBossId); level.GameSave.SetValue($"TSRando_{vanillaBossInfo.SaveName}", true); level.GameSave.SetValue("IsFightingBoss", false); RefreshBossSaveFlags(level); }
public static void ClearBossSaveFlags(Level level, bool valueToSet) { int[] validBosses = GetValidBosses(level); foreach (int bossIndex in validBosses) { BossAttributes bossInfo = GetBossAttributes(level, bossIndex); level.GameSave.SetValue(bossInfo.SaveName, valueToSet); } level.GameSave.SetValue("IsVileteSaved", false); level.GameSave.SetCutsceneTriggered("LakeSerene0_Seykis", true); level.GameSave.SetValue("IsCantoranActive", true); level.GameSave.SetValue("IsEndingABCleared", false); level.GameSave.SetValue("IsLabTSReady", false); }
public static void RefreshBossSaveFlags(Level level) { // Iterate through all bosses and set their kill flag to reflect boss location, not actual boss int[] validBosses = GetValidBosses(level); int pastBossesKilled = 0; bool labTSUsed = false; foreach (int bossIndex in validBosses) { BossAttributes bossInfo = GetBossAttributes(level, bossIndex); bool isBossDead = level.GameSave.GetSaveBool($"TSRando_{bossInfo.SaveName}"); level.GameSave.SetValue(bossInfo.SaveName, isBossDead); int[] pastBosses = new int[] { (int)EBossID.GoldenIdol, (int)EBossID.Aelana, (int)EBossID.Maw }; if (isBossDead && Array.Exists(pastBosses, index => index == bossIndex)) { pastBossesKilled++; } if (isBossDead && (bossIndex == (int)EBossID.Vol || bossIndex == (int)EBossID.Prince)) { labTSUsed = true; } } level.GameSave.SetValue("IsPastCleared", pastBossesKilled == 3); level.GameSave.SetValue("IsVileteSaved", level.GameSave.GetSaveBool("TSRando_IsVileteSaved")); bool isPinkBirdDead = level.GameSave.GetSaveBool("TSRando_IsPinkBirdDead"); bool isCantoranDead = level.GameSave.GetSaveBool("TSRando_IsBossDead_Cantoran") || !level.GameSave.GetSeed().Value.Options.Cantoran; level.GameSave.SetCutsceneTriggered("LakeSerene0_Seykis", isPinkBirdDead); level.GameSave.SetValue("IsCantoranActive", isPinkBirdDead && !isCantoranDead); level.GameSave.SetValue("IsEndingABCleared", level.GameSave.GetSaveBool("TSRando_IsBossDead_Emperor")); level.GameSave.SetValue("IsLabTSReady", !labTSUsed && level.GameSave.GetSaveBool("TSRando_IsLabTSReady")); // Clear the following save flags for vanilla boss seeds if (!level.GameSave.GetSettings().BossRando.Value) { level.GameSave.SetValue("IsBossDead_Emperor", false); level.GameSave.SetValue("IsBossDead_Sandman", false); level.GameSave.SetValue("IsBossDead_Nightmare", false); } }
public static void UpdateBestiary(Level level, SettingCollection gameSettings) { TimeSpinnerGame.Localizer.OverrideKey("inv_use_PlaceHolderItem1", "Nothing"); TimeSpinnerGame.Localizer.OverrideKey("inv_use_PlaceHolderItem1_desc", "You thought you picked something up, but it turned out to be nothing."); level.GCM.AsDynamic()._bestiary = BestiarySpecification.FromCompressedFile("./Content/Bestiary.dat"); var bestiary = level.GCM.Bestiary; Random random = new Random((int)level.GameSave.GetSeed().Value.Id); int[] validBosses = GetValidBosses(level); foreach (var bestiaryEntry in bestiary.BestiaryEntries) { if (gameSettings.ShowBestiary.Value) { level.GameSave.SetValue(string.Format(bestiaryEntry.Key.Replace("Enemy_", "KILL_")), 1); } if (gameSettings.BossRando.Value && validBosses.Contains(bestiaryEntry.Index)) { BossAttributes replacedBossInfo = GetBossAttributes(level, bestiaryEntry.Index); BossAttributes vanillaBossInfo = GetVanillaBoss(level, bestiaryEntry.Index); bestiaryEntry.VisibleName = $"{replacedBossInfo.VisibleName} as {vanillaBossInfo.VisibleName}"; if (gameSettings.BossScaling.Value) { bestiaryEntry.HP = vanillaBossInfo.HP; bestiaryEntry.TouchDamage = vanillaBossInfo.TouchDamage; bestiaryEntry.Exp = vanillaBossInfo.XP; if (replacedBossInfo.Minions.Length > 0) { foreach (int minionId in replacedBossInfo.Minions) { MinionAttributes minionInfo = GetMinionAttributes(level, minionId); var minionEntry = bestiary.BestiaryEntries[minionId]; minionEntry.VisibleName = minionInfo.VisibleName; minionEntry.HP = (int)((float)vanillaBossInfo.HP / replacedBossInfo.HP * minionInfo.HP); minionEntry.TouchDamage = (int)((float)vanillaBossInfo.TouchDamage / replacedBossInfo.TouchDamage * minionInfo.TouchDamage); } } } } bestiaryEntry.VisibleDescription = $"ATK - {bestiaryEntry.TouchDamage}"; int dropSlot = 0; foreach (var loot in bestiaryEntry.LootTable) { var item = Helper.GetAllLoot().SelectRandom(random); switch (gameSettings.DropRateCategory.Value) { case "Fixed": loot.DropRate = (int)gameSettings.DropRate.Value; break; case "Tiered": if (item.LootType == LootType.Equipment) { loot.DropRate = (int)Helper.LookupEquipmentRarity((EInventoryEquipmentType)item.ItemId); } else { loot.DropRate = (int)Helper.LookupUseItemRarity((EInventoryUseItemType)item.ItemId); } break; case "Random": Array lootTiers = Enum.GetValues(typeof(ELootTier)); if (gameSettings.LootTierDistro.Value == "Full Random") { loot.DropRate = (int)lootTiers.GetValue(random.Next(lootTiers.Length)); } else { int offset = 0; if (gameSettings.LootTierDistro.Value == "Inverted Weight") { offset = 4; } int rarityRoll = random.Next(21); switch (rarityRoll) { case int roll when(roll >= 20): loot.DropRate = (int)lootTiers.GetValue(Math.Abs(4 - offset)); break; case int roll when(roll >= 16): loot.DropRate = (int)lootTiers.GetValue(Math.Abs(3 - offset)); break; case int roll when(roll >= 13): loot.DropRate = (int)lootTiers.GetValue(Math.Abs(2 - offset)); break; case int roll when(roll >= 8): loot.DropRate = (int)lootTiers.GetValue(Math.Abs(1 - offset)); break; case int roll when(roll >= 0): loot.DropRate = (int)lootTiers.GetValue(Math.Abs(0 - offset)); break; default: loot.DropRate = (int)ELootTier.Uncommon; break; } } break; case "Vanilla": default: break; } bestiaryEntry.VisibleDescription += $"\nItem {dropSlot + 1} base drop rate: {loot.DropRate}%"; if (gameSettings.ShowDrops.Value) { level.GameSave.SetValue(string.Format(bestiaryEntry.Key.Replace("Enemy_", "DROP_" + dropSlot + "_")), true); } if (gameSettings.LootPool.Value == "Random") { loot.Item = item.ItemId; if (item.LootType == LootType.Equipment) { loot.Category = (int)EInventoryCategoryType.Equipment; } else { loot.Category = (int)EInventoryCategoryType.UseItem; } } else if (gameSettings.LootPool.Value == "Empty") { loot.DropRate = 0; loot.Item = (int)EInventoryUseItemType.PlaceHolderItem1; loot.Category = (int)EInventoryCategoryType.UseItem; } dropSlot++; } } }