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(); }
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); } } }
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")); } } }
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); }