Beispiel #1
0
 void ResetRunData()
 {
     MapsAvailable.Clear();
     MapsAvailable.AddRange(Maps.MapList.Where(map => - 2 <= map.Rating && map.Rating <= 2));
     MapsVisited.Clear();
     MapLabels.Clear();
 }
        public void ActivateFirstMap()
        {
#if DEBUG
            Console.WriteLine($"Requesting first map with level: {MapLevel}");
#endif
            Console.WriteLine("Travelling to Lordran...");

            MapLevel = 1;                // should already be done in EMEVD cleanup

            Map firstMap = GetNextMap(); // Any map rated from -1 to 1.

            // Get random start point.
            Connection startPoint = GetStartPoint(firstMap, 0, ignoreDepth: true);
#if DEBUG
            Console.WriteLine($"Activating first map: {firstMap.Name}");
            Console.WriteLine($"    Labels: {string.Join(", ", MapLabels[firstMap])}");
            Console.WriteLine($"    Start point index: {startPoint.IndexInLevel}");
#endif
            foreach (int startFlag in startPoint.AllStartFlags)
            {
#if DEBUG
                Console.WriteLine($"    Enabling start flag: {startFlag}");
#endif
                EnableFlag(startFlag);  // "disable end" flag and other miscellaneous flags to enable (e.g. boss dead).
            }

            DisableFlag(GameFlag.DisableAbyssPortal);  // Reset Abyss portal for new map.

            // Disable map's "dead enemies" flags.
            for (int i = 0; i < 100; i++)
            {
                DisableFlag(firstMap.DeadEnemyFlagBase + i);
            }

            // Reset shop stocks of Motes/Tomes.
            for (int i = 0; i < 100; i++)
            {
                DisableFlag(11027000 + i);  // Includes "bonfire shop" (11027090).
            }
            MapGenerator.GenerateMapData(firstMap, redPhantomOdds: GetFlag(GameFlag.MornsteinRingFlag) ? 0.2 : 0.1);

            CurrentMap = firstMap;
            foreach (var map in Maps.MapList)
            {
                DisableFlag(map.InMapFlag);
            }
            EnableFlag(CurrentMap.InMapFlag);

            MapsAvailable.Remove(firstMap);
            MapsVisited.Add(firstMap);
            EnableFlag(firstMap.IsVisitedFlag);

            DisableFlag(GameFlag.OneBonfireCreated);
            DisableFlag(GameFlag.TwoBonfiresCreated);

            EnableFlag(GameFlag.RunSetupCompleteFlag);
            EnableFlag(GameFlag.RequestLevelMessageBase + MapLevel - 1);
            EnableFlag(startPoint.WarpRequestFlag);
        }
 void ResetRunData()
 {
     InvadersAvailable.Clear();
     InvadersAvailable.AddRange(Enumerable.Range(0, 30));
     InvadersUsed.Clear();
     BossCategoriesUsed.Clear();
     MapsAvailable.Clear();
     MapsAvailable.AddRange(Maps.MapList.Where(map => - 2 <= map.Rating && map.Rating <= 2));
     MapsVisited.Clear();
     MapLabels.Clear();
 }
Beispiel #4
0
 void LoadExistingRun()
 {
     // Load data from game flags about a run that is already underway.
     ResetRunData();
     List <Label> allLabels = new List <Label>(Enum.GetValues(typeof(Label)).Cast <Label>());
     {
         foreach (MapInfo map in Maps.MapList)
         {
             if (GetFlag(map.IsVisitedFlag))
             {
                 MapsAvailable.Remove(map);
                 MapsVisited.Add(map);
             }
             MapLabels[map] = new List <Label>(allLabels.Where(label => GetFlag(map.HasLabelFlagBase + (int)label)));
             if (GetFlag(map.InMapFlag))
             {
                 CurrentMap = map;
             }
         }
     }
 }
        void LoadExistingRun()
        {
            // Load data from game flags about a run that is already underway.
            ResetRunData();
            List <Label> allLabels = new List <Label>(Enum.GetValues(typeof(Label)).Cast <Label>());

            {
                foreach (Map map in Maps.MapList)
                {
                    if (GetFlag(map.IsVisitedFlag))
                    {
                        MapsAvailable.Remove(map);
                        MapsVisited.Add(map);
                    }
                    MapLabels[map] = new List <Label>(allLabels.Where(label => GetFlag(map.HasLabelFlagBase + (int)label)));
                    if (GetFlag(map.InMapFlag))
                    {
                        CurrentMap = map;
                    }
                }
                int maxBossCategory = EnemyGenerator.LastBossCategory;
                for (int category = 0; category <= maxBossCategory; category++)
                {
                    if (GetFlag(GameFlag.BossCategoryUsedBaseFlag + category))
                    {
                        BossCategoriesUsed.Add(category);
                    }
                }
            }

            foreach (int invader in InvadersAvailable.ToArray())
            {
                if (GetFlag(GameFlag.InvaderUsedBaseFlag + invader))
                {
                    InvadersAvailable.Remove(invader);
                    InvadersUsed.Add(invader);
                }
            }
        }
Beispiel #6
0
        MapInfo GetNextMap()
        {
            // First maps are completely random (sans endpoint maps), with random start points.
            // Last map is an endpoint: Anor Londo, Duke's Archives, New Londo Ruins, Lost Izalith, or Tomb of the Giants.
            // It's Anor Londo if you don't have the Lordvessel (and the others will never appear).
            // Otherwise, it's a random map from among the endpoints you haven't beaten.
            // If you've beaten them all, it's any endpoint.
            if (DEBUG_MAP != "")
            {
                return(Maps.GetMap(DEBUG_MAP));
            }

            int mapLevel    = MapLevel; // Note that map level is incremented just before this is called, so it's the level of THIS upcoming map.
            int endMapLevel = GetFlag(GameFlag.LobosJrRingFlag) ? 9 : 6;

            if (mapLevel < endMapLevel)
            {
                List <MapInfo> options = new List <MapInfo>(Maps.MapList.Where(map => - 1 <= map.Rating && map.Rating <= 1 && MapsAvailable.Contains(map)));
                // 80% chance to remove Great Hollow and Ash Lake from options.
                if (options.Count > 2 && Rand.Roll(0.8))
                {
                    if (options.Contains(Maps.GetMap("AshLake")))
                    {
                        options.Remove(Maps.GetMap("AshLake"));
                    }
                    if (options.Contains(Maps.GetMap("GreatHollow")))
                    {
                        options.Remove(Maps.GetMap("GreatHollow"));
                    }
                }
                return(options.GetRandomElement(Rand));
            }
            else if (mapLevel == endMapLevel)
            {
                if (!GetFlag(GameFlag.LordvesselObtained))
                {
                    // If you don't have the Lordvessel, the final level is always Anor Londo,
                    // with the only possible exit being Gwynevere's bonfire.
                    EnableFlag(11512000);  // Disable Batwing exit.
                    EnableFlag(11512010);  // Disable Archives exit.
                    return(Maps.GetMap("AnorLondo"));
                }
                else
                {
                    // If you have the Lordvessel, the final level is one of the four Lord Soul areas
                    // whose boss you have not yet defeated.
                    List <MapInfo> options = new List <MapInfo>(Maps.MapList.Where(
                                                                    map => (Math.Abs(map.Rating) == 2 || map.Name == "NewLondoRuins") && map.Name != "AnorLondo" && MapsAvailable.Contains(map)));
                    if (GetFlag(GameFlag.ArchivesBossDefeated))
                    {
                        options.Remove(Maps.GetMap("DukesArchives"));
                    }
                    if (GetFlag(GameFlag.TombBossDefeated))
                    {
                        options.Remove(Maps.GetMap("TombOfTheGiants"));
                    }
                    if (GetFlag(GameFlag.IzalithBossDefeated))
                    {
                        options.Remove(Maps.GetMap("LostIzalith"));
                    }
                    if (GetFlag(GameFlag.NewLondoBossDefeated))
                    {
                        options.Remove(Maps.GetMap("NewLondoRuins"));
                    }
                    if (!options.Any())
                    {
                        // All Lord Souls have been obtained. Go to any rating 2 map instead.
                        options = new List <MapInfo>(Maps.MapList.Where(map => Math.Abs(map.Rating) == 2 && MapsAvailable.Contains(map)));
                    }
                    MapInfo chosen = options.GetRandomElement(Rand);
                    if (chosen.Name == "NewLondoRuins")
                    {
                        // No way out of New Londo except into the Abyss at this point.
                        EnableFlag(chosen.Connections[0].DisableEndFlag);
                        EnableFlag(chosen.Connections[1].DisableEndFlag);
                        EnableFlag(chosen.Connections[2].DisableEndFlag);
                        // Seal gate is automatically opened if it's an endpoint.
                        EnableFlag(61600110);
                        EnableFlag(11600110);
                    }
                    return(chosen);
                }
            }
            else  // Only requested from EMEVD if the game KNOWS you're allowed to one of these true-ending maps.
            {
                if (GetFlag(GameFlag.AbyssBattleVictoryCountBase + 3))
                {
                    return(Maps.GetMap("ChasmOfTheAbyss"));
                }
                else
                {
                    return(Maps.GetMap("KilnOfTheFirstFlame"));
                }
            }
        }
Beispiel #7
0
        public MapInfo ActivateMap(int triggerFlag)
        {
            // Enemies get harder (unless at max).
            if (MapLevel < 10)
            {
                MapLevel += 1;
            }

#if DEBUG
            Console.WriteLine($"Requesting map with level: {MapLevel}");
#endif

            MapInfo    newMap     = GetNextMap();
            Connection startPoint = GetStartPoint(newMap, 0, ignoreDepth: true);

#if DEBUG
            Console.WriteLine($"Activating map: {newMap.Name}");
            Console.WriteLine($"    Labels: {string.Join(", ", MapLabels[newMap])}");
            Console.WriteLine($"    Start point index: {startPoint.IndexInLevel}");
#endif
            // Disable map's "dead enemies" flags.
            for (int i = 0; i < 100; i++)
            {
                DisableFlag(newMap.DeadEnemyFlagBase + i);
            }

            // Reset shop stocks of Motes/Tomes.
            for (int i = 0; i < 100; i++)
            {
                DisableFlag(11027000 + i);  // Includes "bonfire shop" (11027090).
            }
            // Generate MSB, LUABND, FFXBND, and tweaked EMEVD for new map.
            double       redPhantomOdds = GetFlag(GameFlag.MornsteinRingFlag) ? 0.2 : 0.1;
            MapGenerator mapGen         = new MapGenerator(Mod, this, newMap, Rand, redPhantomOdds, startPoint);
            mapGen.Generate();

            foreach (int startFlag in startPoint.AllStartFlags)
            {
#if DEBUG
                Console.WriteLine($"    Enabling start flag: {startFlag}");
#endif
                EnableFlag(startFlag);                // "disable end" flag and other miscellaneous flags to enable (e.g. boss dead).
            }
            DisableFlag(GameFlag.DisableAbyssPortal); // Reset Abyss portal for new map.
            DisableFlag(GameFlag.AbyssBattleActive);
            if (newMap.Name != "Painted World")       // Current map is not updated when you're in the Painted World, which is only temporary.
            {
                CurrentMap = newMap;
                foreach (var map in Maps.MapList)
                {
                    DisableFlag(map.InMapFlag);
                }
                EnableFlag(CurrentMap.InMapFlag);
            }
            MapsAvailable.Remove(newMap);
            MapsVisited.Add(newMap);
            EnableFlag(newMap.IsVisitedFlag);  // Painted World also marked as visited here.

            DisableFlag(GameFlag.OneBonfireCreated);
            DisableFlag(GameFlag.TwoBonfiresCreated);

            Hook.LastBonfire = startPoint.SpawnPointID;

            EnableFlag(GameFlag.RequestLevelMessageBase + MapLevel - 1);
            EnableFlag(startPoint.WarpRequestFlag);
            return(newMap);
        }