Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
                }
            }
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
 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;
     }
 }
Exemplo n.º 6
0
        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));
            }
        }
Exemplo n.º 7
0
        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();
            }
        }
Exemplo n.º 8
0
        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();
            }
        }
Exemplo n.º 9
0
 public SCLogicArea(short areaId, SCOwArea area, SCRequirementsSet newFlags)
 {
     AreaId       = areaId;
     Area         = area;
     Requirements = newFlags;
 }