private bool Enter(SCOwArea area, SCOwArea linked) { if ((linked.Tile & SCBitFlags.Chime) > 0 && (changes & MapChange.Chime) == 0) { return(false); } if ((linked.Tile & SCBitFlags.River) > 0 && (changes & MapChange.Canoe) > 0) { if (!processedAreas.Contains(linked.Index)) { immediateAreas.Add(linked.Index); } return(true); } else if ((linked.Tile & SCBitFlags.Land) > 0) { if (!processedAreas.Contains(linked.Index)) { immediateAreas.Add(linked.Index); } return(true); } else if ((linked.Tile & SCBitFlags.Ocean) > 0 && (changes & MapChange.Ship) > 0 && area.Index == shipDockAreaIndex) { if (!processedAreas.Contains(linked.Index)) { immediateAreas.Add(linked.Index); } return(true); } return(false); }
private void ProcessEnterTele(SCOwArea area, SCPointOfInterest poi) { if (processedDungeons.Contains(poi.Teleport.OverworldTeleport)) { return; } processedDungeons.Add(poi.Teleport.OverworldTeleport); var dungeon = Main.Dungeons.First(d => d.OverworldTeleport == poi.Teleport.OverworldTeleport); dungeon.Done = true; foreach (var dpoi in dungeon.PointsOfInterest) { if (dpoi.BitFlagSet.IsAccessible(requirements, changes)) { ProcessSmPointOfInterest(dpoi, (byte)poi.Teleport.OverworldTeleport); } else if (dpoi.Type == SCPointOfInterestType.Treasure || dpoi.Type == SCPointOfInterestType.Shop || dpoi.Type == SCPointOfInterestType.Orb || dpoi.Type == SCPointOfInterestType.QuestNpc || dpoi.Type == SCPointOfInterestType.Exit) { dpoi.DungeonIndex = (byte)poi.Teleport.OverworldTeleport; deferredPointOfInterests.Enqueue(dpoi); } } }
private bool Cross(SCOwArea area, SCOwArea linked, bool swim, bool walk) { if ((area.Tile & SCBitFlags.Ocean) > 0 && swim) { foreach (var nextLink in linked.Links) { var nextArea = Main.Overworld.Areas[nextLink]; if (nextArea.Index != area.Index && (nextArea.Tile & SCBitFlags.Ocean) > 0) { if (!processedAreas.Contains(nextArea.Index)) { immediateAreas.Add(nextArea.Index); } return(true); } } } else if ((area.Tile & SCBitFlags.Land) > 0 && walk) { foreach (var nextLink in linked.Links) { var nextArea = Main.Overworld.Areas[nextLink]; if (nextArea.Index != area.Index && (nextArea.Tile & SCBitFlags.Land) > 0) { if (!processedAreas.Contains(nextArea.Index)) { immediateAreas.Add(nextArea.Index); } return(true); } } } return(false); }
public (bool complete, IEnumerable <IRewardSource> rewardSources, AccessRequirement requirements, MapChange changes) Crawl(IVictoryConditionFlags victoryConditions) { Stopwatch w = Stopwatch.StartNew(); immediateAreas = new HashSet <short>(256); processedAreas = new HashSet <short>(2048); processedDungeons = new HashSet <OverworldTeleportIndex>(32); deferredAreas = new HashSet <SCDeferredAreaQueueEntry>(64, new SCDeferredAreaQueueEntryEqualityComparer()); deferredPointOfInterests = new Queue <SCPointOfInterest>(); rewardSources = new HashSet <IRewardSource>(256, new RewardSourceEqualityComparer()); shipDockAreaIndex = -1; slabTranslated = false; herbCheckedIn = false; princessRescued = false; vampireAccessible = false; airShipLiftOff = false; BuildInitialRequirements(victoryConditions); SetAirShipPoi(); short areaIndex = Main.Overworld.Tiles[locations.StartingLocation.X, locations.StartingLocation.Y].Area; SCOwArea area = Main.Overworld.Areas[areaIndex]; CrawlOwArea(area); ProcessImmediateAreas(); while (ProcessDeferredAreas()) { ProcessImmediateAreas(); } //that for just means, that there's a fault in the function. Actually the mere existence of the call is a fault in the above functions for (int i = 0; i < 10; i++) { ProcessDeferredPointsOfInterest(); } w.Stop(); var requiredAccess = AccessRequirement.All; var requiredMapChanges = MapChange.All; if ((bool)victoryConditions.IsFloaterRemoved) { requiredMapChanges &= ~MapChange.Airship; } bool complete = changes.HasFlag(requiredMapChanges) && requirements.HasFlag(requiredAccess); return(complete, rewardSources, requirements, changes); }
private void ProcessOwPointOfInterest(SCOwArea area, SCPointOfInterest poi) { if (poi.Type == SCPointOfInterestType.Shop) { ProcessShop(poi, 255); } else if (poi.Type == SCPointOfInterestType.Tele) { ProcessEnterTele(area, poi); } else if (poi.Type == SCPointOfInterestType.AirShip) { airShipLocationAccessible = true; } }
private bool CheckLink(SCOwArea area, short link) { if (processedAreas.Contains(link)) { return(true); } SCOwArea linked = Main.Overworld.Areas[link]; if (linked.Tile == SCBitFlags.Bridge) { return(Cross(area, linked, true, (changes & MapChange.Bridge) > 0)); } else if (linked.Tile == SCBitFlags.Canal) { return(Cross(area, linked, (changes & MapChange.Canal) > 0, true)); } else { return(Enter(area, linked)); } }
private void CrawlOwArea(SCOwArea area) { processedAreas.Add(area.Index); foreach (var poi in area.PointsOfInterest) { ProcessOwPointOfInterest(area, poi); } foreach (var link in area.Links) { if (!CheckLink(area, link)) { deferredAreas.Add(new SCDeferredAreaQueueEntry(area.Index, link)); } } if (airShipLocationAccessible && (changes & MapChange.Airship) > 0 && !airShipLiftOff) { LiftOff(); } }
private void ProcessImmediateAreas() { while (immediateAreas.Count > 0) { maxqueue = Math.Max(maxqueue, immediateAreas.Count); var entry = immediateAreas.First(); immediateAreas.Remove(entry); if (!processedAreas.Contains(entry)) { SCOwArea nextArea = Main.Overworld.Areas[entry]; CrawlOwArea(nextArea); } } //not sure, but helps if (airShipLocationAccessible && (changes & MapChange.Airship) > 0 && !airShipLiftOff) { LiftOff(); } }
public SCLogicArea(short areaId, SCOwArea area, SCRequirementsSet newFlags) { AreaId = areaId; Area = area; Requirements = newFlags; }