public static LogicObjects.ItemUnlockData FindRequirements(LogicObjects.LogicEntry Item, List <LogicObjects.LogicEntry> logic) { List <int> ImportantItems = new List <int>(); List <LogicObjects.PlaythroughItem> playthrough = new List <LogicObjects.PlaythroughItem>(); var LogicCopy = Utility.CloneLogicList(logic); foreach (var i in LogicCopy) { if (i.Unrandomized()) { i.IsFake = true; } } var ItemCopy = LogicCopy[Item.ID]; LogicEditing.ForceFreshCalculation(LogicCopy); foreach (var i in LogicCopy) { ImportantItems.Add(i.ID); if (i.IsFake) { i.SpoilerRandom = i.ID; } } PlaythroughGenerator.UnlockAllFake(LogicCopy, ImportantItems, 0, playthrough); List <int> UsedItems = new List <int>(); bool isAvailable = (LogicEditing.RequirementsMet(ItemCopy.Required, LogicCopy, UsedItems) && LogicEditing.CondtionalsMet(ItemCopy.Conditionals, LogicCopy, UsedItems)); if (!isAvailable) { return(new LogicObjects.ItemUnlockData()); } List <int> NeededItems = Tools.ResolveFakeToRealItems(new LogicObjects.PlaythroughItem { SphereNumber = 0, Check = ItemCopy, ItemsUsed = UsedItems }, playthrough, LogicCopy); List <int> FakeItems = Tools.FindAllFakeItems(new LogicObjects.PlaythroughItem { SphereNumber = 0, Check = ItemCopy, ItemsUsed = UsedItems }, playthrough, LogicCopy); NeededItems = NeededItems.Distinct().ToList(); return(new LogicObjects.ItemUnlockData { playthrough = playthrough, FakeItems = FakeItems, ResolvedRealItems = NeededItems, UsedItems = UsedItems }); }
public static PlaythroughContainer GeneratePlaythrough(LogicObjects.TrackerInstance Instance, int GameClear, bool fullplaythrough = false) { var container = new PlaythroughContainer(); List <LogicObjects.PlaythroughItem> Playthrough = new List <LogicObjects.PlaythroughItem>(); Dictionary <int, int> SpoilerToID = new Dictionary <int, int>(); container.PlaythroughInstance = Utility.CloneTrackerInstance(Instance); if (GameClear < 0) { container.ErrorMessage = ("Could not find game clear requirements. Playthrough can not be generated."); return(container); } if (!Utility.CheckforSpoilerLog(container.PlaythroughInstance.Logic)) { var file = Utility.FileSelect("Select A Spoiler Log", "Spoiler Log (*.txt;*html)|*.txt;*html"); if (file == "") { return(null); } LogicEditing.WriteSpoilerLogToLogic(container.PlaythroughInstance, file); } if (!Utility.CheckforSpoilerLog(container.PlaythroughInstance.Logic, true)) { MessageBox.Show("Not all items have spoiler data. Results may be inconsistant. Ensure you are using the same version of logic used to generate your selected spoiler log"); } List <int> importantItems = new List <int>(); foreach (var i in container.PlaythroughInstance.Logic) { i.Available = false; i.Checked = false; i.Aquired = false; if (!i.IsFake && i.Unrandomized() && i.SpoilerRandom < 0) { i.SpoilerRandom = i.ID; } if (i.IsFake) { i.SpoilerRandom = i.ID; i.RandomizedItem = i.ID; i.LocationName = i.DictionaryName; i.ItemName = i.DictionaryName; } if (i.Unrandomized() && i.ID == i.SpoilerRandom) { i.IsFake = true; } //If the item is unrandomized treat it as a fake item if (i.SpoilerRandom > -1) { i.RandomizedItem = i.SpoilerRandom; } //Make the items randomized item its spoiler item, just for consitancy sake else if (i.RandomizedItem > -1) { i.SpoilerRandom = i.RandomizedItem; } //If the item doesn't have spoiler data, but does have a randomized item. set it's spoiler data to the randomized item else if (i.Unrandomized(1)) { i.SpoilerRandom = i.ID; i.RandomizedItem = i.ID; } //If the item doesn't have spoiler data or a randomized item and is unrandomized (manual), set it's spoiler item to it's self if (SpoilerToID.ContainsKey(i.SpoilerRandom) || i.SpoilerRandom < 0) { continue; } SpoilerToID.Add(i.SpoilerRandom, i.ID); //Check for all items mentioned in the logic file if (i.Required != null) { foreach (var k in i.Required) { if (!importantItems.Contains(k)) { importantItems.Add(k); } } } if (i.Conditionals != null) { foreach (var j in i.Conditionals) { foreach (var k in j) { if (!importantItems.Contains(k)) { importantItems.Add(k); } } } } if (i.ID == GameClear) { importantItems.Add(i.ID); } if (!importantItems.Contains(i.ID) && fullplaythrough) { importantItems.Add(i.ID); } } SwapAreaClearLogic(container.PlaythroughInstance); MarkAreaClearAsEntry(container.PlaythroughInstance); CalculatePlaythrough(container.PlaythroughInstance, Playthrough, 0, importantItems); importantItems = new List <int>(); var GameClearPlaythroughItem = Playthrough.Find(x => x.Check.ID == GameClear); if (GameClearPlaythroughItem == null) { container.Playthrough = Playthrough.OrderBy(x => x.SphereNumber).ThenBy(x => x.Check.ItemSubType).ThenBy(x => x.Check.LocationArea).ThenBy(x => x.Check.LocationName).ToList(); return(container); } container.GameClearItem = GameClearPlaythroughItem; importantItems.Add(GameClearPlaythroughItem.Check.ID); FindImportantItems(GameClearPlaythroughItem, importantItems, Playthrough, SpoilerToID); container.Playthrough = Playthrough.OrderBy(x => x.SphereNumber).ThenBy(x => x.Check.ItemSubType).ThenBy(x => x.Check.LocationArea).ThenBy(x => x.Check.LocationName).ToList(); container.RealItemPlaythrough = JsonConvert.DeserializeObject <List <LogicObjects.PlaythroughItem> >(JsonConvert.SerializeObject(container.Playthrough)); //Replace all fake items with the real items used to unlock those fake items foreach (var i in container.RealItemPlaythrough) { i.ItemsUsed = Tools.ResolveFakeToRealItems(i, Playthrough, container.PlaythroughInstance.Logic).Distinct().ToList(); } container.ImportantPlaythrough = container.RealItemPlaythrough.Where(i => (importantItems.Contains(i.Check.ID) && !i.Check.IsFake) || i.Check.ID == GameClear).ToList(); //Convert Progressive Items Back to real items ConvertProgressiveItems(container.Playthrough, container.PlaythroughInstance); ConvertProgressiveItems(container.RealItemPlaythrough, container.PlaythroughInstance); ConvertProgressiveItems(container.ImportantPlaythrough, container.PlaythroughInstance); return(container); }
public static void GeneratePlaythrough(LogicObjects.TrackerInstance Instance) { List <LogicObjects.PlaythroughItem> Playthrough = new List <LogicObjects.PlaythroughItem>(); Dictionary <int, int> SpoilerToID = new Dictionary <int, int>(); var playLogic = Utility.CloneTrackerInstance(Instance); var GameClear = GetGameClearEntry(playLogic.Logic, Instance.EntranceRando); if (GameClear < 0) { MessageBox.Show("Could not find game clear requirements. Playthrough can not be generated."); return; } if (!Utility.CheckforSpoilerLog(playLogic.Logic)) { var file = Utility.FileSelect("Select A Spoiler Log", "Spoiler Log (*.txt;*html)|*.txt;*html"); if (file == "") { return; } LogicEditing.WriteSpoilerLogToLogic(playLogic, file); } if (!Utility.CheckforSpoilerLog(playLogic.Logic, true)) { MessageBox.Show("Not all items have spoiler data. Playthrough may not generate correctly. Ensure you are using the same version of logic used to generate your selected spoiler log"); } List <int> importantItems = new List <int>(); foreach (var i in playLogic.Logic) { i.Available = false; i.Checked = false; i.Aquired = false; if (i.IsFake) { i.SpoilerRandom = i.ID; i.RandomizedItem = i.ID; i.LocationName = i.DictionaryName; i.ItemName = i.DictionaryName; } if (i.Unrandomized() && i.ID == i.SpoilerRandom) { i.IsFake = true; } if (i.SpoilerRandom > -1) { i.RandomizedItem = i.SpoilerRandom; } SpoilerToID.Add(i.SpoilerRandom, i.ID); //Check for all items mentioned in the logic file if (i.Required != null) { foreach (var k in i.Required) { if (!importantItems.Contains(k)) { importantItems.Add(k); } } } if (i.Conditionals != null) { foreach (var j in i.Conditionals) { foreach (var k in j) { if (!importantItems.Contains(k)) { importantItems.Add(k); } } } } if (i.ID == GameClear) { importantItems.Add(i.ID); } } SwapAreaClearLogic(playLogic); MarkAreaClearAsEntry(playLogic); CalculatePlaythrough(playLogic.Logic, Playthrough, 0, importantItems); importantItems = new List <int>(); bool MajoraReachable = false; var GameClearPlaythroughItem = new LogicObjects.PlaythroughItem(); foreach (var i in Playthrough) { if (i.Check.ID == GameClear) { GameClearPlaythroughItem = i; importantItems.Add(i.Check.ID); FindImportantItems(i, importantItems, Playthrough, SpoilerToID); MajoraReachable = true; break; } } if (!MajoraReachable) { MessageBox.Show("This seed is not beatable using this logic! Playthrough could not be generated!"); return; } Playthrough = Playthrough.OrderBy(x => x.SphereNumber).ThenBy(x => x.Check.ItemSubType).ThenBy(x => x.Check.LocationArea).ThenBy(x => x.Check.LocationName).ToList(); //Replace all fake items with the real items used to unlock those fake items foreach (var i in Playthrough) { i.ItemsUsed = Tools.ResolveFakeToRealItems(i, Playthrough, playLogic.Logic).Distinct().ToList(); } List <string> PlaythroughString = new List <string>(); int lastSphere = -1; foreach (var i in Playthrough) { if (!importantItems.Contains(i.Check.ID) || i.Check.IsFake) { continue; } if (i.SphereNumber != lastSphere) { PlaythroughString.Add("Sphere: " + i.SphereNumber + " ====================================="); lastSphere = i.SphereNumber; } PlaythroughString.Add("Check \"" + i.Check.LocationName + "\" to obtain \"" + playLogic.Logic[i.Check.RandomizedItem].ItemName + "\""); string items = " Using Items: "; foreach (var j in i.ItemsUsed) { items = items + playLogic.Logic[j].ItemName + ", "; } if (items != " Using Items: ") { PlaythroughString.Add(items); } } var h = GameClearPlaythroughItem; PlaythroughString.Add("Sphere: " + h.SphereNumber + " ====================================="); lastSphere = h.SphereNumber; PlaythroughString.Add("Defeat Majora"); string items2 = " Using Items: "; foreach (var j in h.ItemsUsed) { items2 = items2 + playLogic.Logic[j].ItemName + ", "; } if (items2 != " Using Items: ") { PlaythroughString.Add(items2); } InformationDisplay DisplayPlaythrough = new InformationDisplay(); InformationDisplay.Playthrough = PlaythroughString; DisplayPlaythrough.DebugFunction = 3; DisplayPlaythrough.Show(); InformationDisplay.Playthrough = new List <string>(); }