private static void Restore(string path) { WorldMapGenerateMap.Restore(path); Avatar.Restore(path); Title.Restore(path); Talk.Restore(path); Dungeons.Restore(path); }
private static void Randomize(int seed, string path, Flags flags, string encoded) { //Console.WriteLine("Seed: " + seed); string json = JsonConvert.SerializeObject(flags); if (string.IsNullOrWhiteSpace(encoded)) { encoded = flags.GetEncoded(); } else { flags.DecodeAndSet(encoded); json = JsonConvert.SerializeObject(flags); } Console.WriteLine("Flags JSON : " + json); Console.WriteLine("Flags Base64: " + encoded); StreamWriter spoilerWriter = new StreamWriter("spoiler.txt"); SpoilerLog spoilerLog = new SpoilerLog(spoilerWriter, flags.SpoilerLog); System.IO.File.AppendAllText(@"seed.txt", seed.ToString() + " " + encoded + Environment.NewLine); spoilerLog.WriteFlags(flags); var random = new Random(seed); var randomValues = new List <int>(); for (int i = 0; i < 50; i++) { randomValues.Add(random.Next()); } var ultimaData = new UltimaData(); IWorldMap worldMap = null; //WorldMapGenerateMap.PrintWorldMapInfo(path); if (flags.Overworld == 5) { worldMap = new WorldMapGenerateMap(spoilerLog); } else if (flags.Overworld == 1) { worldMap = new WorldMapUnchanged(spoilerLog); } else if (flags.Overworld == 2) { worldMap = new WorldMapShuffleLocations(spoilerLog); } worldMap.Load(path, randomValues[0], randomValues[1], randomValues[2], ultimaData); var avatar = new Avatar(spoilerLog); avatar.Load(path, ultimaData, worldMap, flags); var title = new Title(spoilerLog); title.Load(path, ultimaData); var talk = new Talk(spoilerLog); talk.Load(path); var dungeons = new Dungeons(spoilerLog); dungeons.Load(path, ultimaData, flags); var party = new Party(spoilerLog); party.Load(path, ultimaData); var towns = new Towns(spoilerLog); towns.Load(path, ultimaData); if (flags.Fixes) { spoilerLog.Add(SpoilerCategory.Fix, "Serpent Hold's Healer"); ultimaData.ShopLocations[ultimaData.LOC_SERPENT - 1][5] = 0x12; } worldMap.Randomize(ultimaData, new Random(randomValues[3]), new Random(randomValues[4])); dungeons.Randomize(new Random(randomValues[6]), flags); if (flags.ClothMap) { var clothMap = worldMap.ToClothMap(ultimaData, new Random(randomValues[5])); clothMap.SaveAsPng($"clothMap-{seed}.png"); new Process { StartInfo = new ProcessStartInfo($"clothMap-{seed}.png") { UseShellExecute = true } }.Start(); } if (flags.RandomizeSpells) { var recipes = new byte[2]; ultimaData.SpellsRecipes['r' - 'a'].Byte = 0; ultimaData.SpellsRecipes['g' - 'a'].Byte = 0; while (ultimaData.SpellsRecipes['r' - 'a'].Byte == 0) { random.NextBytes(recipes); ultimaData.SpellsRecipes['r' - 'a'].Byte = (byte)(recipes[0] | recipes[1]); } while (ultimaData.SpellsRecipes['g' - 'a'].Byte == 0) { random.NextBytes(recipes); ultimaData.SpellsRecipes['g' - 'a'].Byte = (byte)(recipes[0] | recipes[1]); } } if (!String.IsNullOrWhiteSpace(flags.SpellRemove)) { var arr = flags.SpellRemove.ToLower().ToArray(); for (int i = 0; i < arr.Length; i++) { if (arr[i] > 'z' || arr[i] < 'a') { throw new ArgumentException("spellRemove can only contain letters."); } ultimaData.SpellsRecipes[arr[i] - 'a'].Byte = 0; } } if (flags.StartingWeapons) { for (int charIdx = 0; charIdx < 8; charIdx++) { var selected = false; while (!selected) { // -1 so Mystic weapons and armors aren't included var weapon = random.Next(1, Party.AllowedWeaponsMask.Length - 1); //If weapon is allowed if ((Party.AllowedWeaponsMask[weapon] & (0x80 >> ultimaData.StartingCharacters[charIdx].Class)) != 0) { ultimaData.StartingCharacters[charIdx].Weapon = (ushort)weapon; selected = true; } } selected = false; while (!selected) { var armor = random.Next(1, Party.AllowedArmorMask.Length); //If weapon is allowed if ((Party.AllowedArmorMask[armor] & (0x80 >> ultimaData.StartingCharacters[charIdx].Class)) != 0) { ultimaData.StartingCharacters[charIdx].Armor = (ushort)armor; selected = true; } } } } //worldMap.TestAbyssEjection(); //Console.WriteLine(Talk.GetSextantText(ultimaData.LCB[0])); //for (int i = 0; i < 8; i++) //{ // ultimaData.StartingArmor[i] = Convert.ToUInt16(i + 10); //} //for (int i = 0; i < 16; i++) //{ // ultimaData.StartingWeapons[i] = Convert.ToUInt16(i + 10); //} //ultimaData.StartingFood = 2345 * 100 + 99; //ultimaData.StartingGold = 1337; //for (int i = 0; i < 4; i++) //{ // ultimaData.StartingEquipment[i] = Convert.ToUInt16(i + 10); //} //for (int i = 0; i < 8; i++) //{ // ultimaData.StartingReagents[i] = Convert.ToUInt16(i + 10); //} //for (int i = 0; i < 26; i++) //{ // ultimaData.StartingMixtures[i] = Convert.ToUInt16(i + 10); //} //ultimaData.StartingItems = 0XFFFF; if (flags.QuestItemPercentage > 0) { ushort ushortone = 1; ultimaData.StartingItems = 0; for (ushort i = 0; i < 16; i++) { if (random.Next(0, 100) < flags.QuestItemPercentage) { ultimaData.StartingItems |= (ushort)(ushortone << i); } } // Never have the skull destroyed ultimaData.StartingItems &= (ushort)(~(ushortone << 1)); // Don' pre-use bell, book and candle ultimaData.StartingItems &= (ushort)(~(ushortone << 10)); ultimaData.StartingItems &= (ushort)(~(ushortone << 11)); ultimaData.StartingItems &= (ushort)(~(ushortone << 12)); ultimaData.StartingRunes = 0; for (ushort i = 0; i < 8; i++) { if (random.Next(0, 100) < flags.QuestItemPercentage) { ultimaData.StartingRunes |= (byte)(1 << i); } } ultimaData.StartingStones = 0; for (ushort i = 0; i < 8; i++) { if (random.Next(0, 100) < flags.QuestItemPercentage) { ultimaData.StartingStones |= (byte)(1 << i); } } LogQuestItems(spoilerLog, ultimaData); } else { spoilerLog.Add(SpoilerCategory.Start, "No change to starting quest items."); } if (flags.Sextant) { ultimaData.StartingEquipment[3] = 0x01; } if (flags.KarmaSetPercentage > 0) { for (int virtue = 0; virtue < 8; virtue++) { if (random.Next(0, 100) < flags.KarmaSetPercentage) { ultimaData.StartingKarma[virtue] = (flags.KarmaValue.HasValue ? (byte)flags.KarmaValue.Value : (byte)random.Next(0, 100)); spoilerLog.Add(SpoilerCategory.Start, $"{ultimaData.ItemNames[virtue + 15]} karma at {ultimaData.StartingKarma[virtue]}"); } else { spoilerLog.Add(SpoilerCategory.Start, $"{ultimaData.ItemNames[virtue + 15]} karma unchanged."); } } } if (flags.Runes) { spoilerLog.Add(SpoilerCategory.Feature, $"Rune locations randomized"); var usedLocations = new List <byte>(); for (int i = UltimaData.ITEM_RUNE_HONESTY; i < 8 + UltimaData.ITEM_RUNE_HONESTY; i++) { var possibleOptions = ItemOptions.ItemToItemOptions[i].Where(x => !usedLocations.Contains(x.Item.Location)).ToList(); var selectedItemOption = possibleOptions[random.Next(0, possibleOptions.Count)]; ultimaData.Items[i].X = selectedItemOption.Item.X; ultimaData.Items[i].Y = selectedItemOption.Item.Y; ultimaData.Items[i].Location = selectedItemOption.Item.Location; ultimaData.ItemOptions.Add(i, selectedItemOption); usedLocations.Add(selectedItemOption.Item.Location); } } if (flags.Mantras) { int numberOfTwos = 3; int numberOfThrees = 4; int numberOfFours = 1; // Grab Sacrifice first since it is special var mantrasWithLimericks = talk.Mantras.Where(x => x.Limerick.Length > 0).ToList(); var sacrificeMantra = mantrasWithLimericks[random.Next(0, mantrasWithLimericks.Count)]; talk.Mantras.Remove(sacrificeMantra); if (sacrificeMantra.Text.Length == 2) { numberOfTwos--; } else if (sacrificeMantra.Text.Length == 3) { numberOfThrees--; } else if (sacrificeMantra.Text.Length == 4) { numberOfFours--; } var possibleTwos = talk.Mantras.Where(x => x.Text.Length == 2).ToList(); var possibleThrees = talk.Mantras.Where(x => x.Text.Length == 3).ToList(); var possibleFours = talk.Mantras.Where(x => x.Text.Length == 4).ToList(); var possibleMantras = new List <Mantra>(); for (int i = 0; i < numberOfTwos; i++) { var nextIdx = random.Next(0, possibleTwos.Count); possibleMantras.Add(possibleTwos[nextIdx]); possibleTwos.RemoveAt(nextIdx); } for (int i = 0; i < numberOfThrees; i++) { var nextIdx = random.Next(0, possibleThrees.Count); possibleMantras.Add(possibleThrees[nextIdx]); possibleThrees.RemoveAt(nextIdx); } for (int i = 0; i < numberOfFours; i++) { var nextIdx = random.Next(0, possibleFours.Count); possibleMantras.Add(possibleFours[nextIdx]); possibleFours.RemoveAt(nextIdx); } possibleMantras.Shuffle(random); possibleMantras.Insert(4, sacrificeMantra); talk.Mantras = possibleMantras; for (int i = 0; i < 8; i++) { ultimaData.Mantras[i] = talk.Mantras[i].Text.ToLower(); } } if (flags.WordOfPassage) { var selection = talk.WordsOfPassage[random.Next(0, talk.WordsOfPassage.Count)]; ultimaData.WordTruth = selection.Item1; ultimaData.WordLove = selection.Item2; ultimaData.WordCourage = selection.Item3; ultimaData.WordOfPassage = selection.Item1 + selection.Item2 + selection.Item3; } //ultimaData.StartingStones = 0XFF; //ultimaData.StartingRunes = 0XFF; title.Update(ultimaData, flags, encoded); talk.Update(ultimaData, avatar, flags, worldMap); avatar.Update(ultimaData, flags); dungeons.Update(ultimaData, flags); party.Update(ultimaData); towns.Update(ultimaData, flags); towns.Save(path); party.Save(path); dungeons.Save(path); title.Save(path); talk.Save(path); avatar.Save(path); worldMap.Save(path); if (flags.MiniMap) { var image = worldMap.ToImage(); image.SaveAsPng($"worldMap-{seed}.png"); //image = worldMap.ToHeightMapImage(); //if (image != null) //{ // image.SaveAsPng($"worldMap-hm-{seed}.png"); //} } spoilerWriter.Close(); //PrintWorldMapInfo(); }