private void ChooseNightLevels() { _nightLevels = new List <string>(); while (_nightLevels.Count < NumLevels) { TR23ScriptedLevel level = Levels[_generator.Next(0, Levels.Count)]; if (level.Is(LevelNames.ASSAULT)) { continue; } string id = level.LevelFileBaseName.ToUpper(); if (!_nightLevels.Contains(id)) { _nightLevels.Add(id); } } }
private void FindAndCleanUnarmedPistolLocation(TR23ScriptedLevel lvl) { string lvlFile = lvl.LevelFileBaseName.ToUpper(); Location levelPistolLocation = null; if (_pistolLocations.ContainsKey(lvlFile)) { levelPistolLocation = _pistolLocations[lvlFile]; CleanUnarmedPistolLocation(levelPistolLocation); } if (lvl.RemovesWeapons && levelPistolLocation != null) { _unarmedLevelPistolIndex = FindUnarmedPistolIndex(levelPistolLocation); } else { _unarmedLevelPistolIndex = -1; } }
private void ChooseHaircutLevels() { _haircutLevels = new List <string>(); if (RandomlyCutHair) { // One, some, or all. We don't use Levels.Count+1 here as the Assault Course // doesn't work for now (missing gunflare texture used for transparency). int numLevels = _generator.Next(1, Levels.Count); while (_haircutLevels.Count < numLevels) { TR23ScriptedLevel level = Levels[_generator.Next(0, Levels.Count)]; if (level.Is(LevelNames.ASSAULT)) { continue; } string id = level.LevelFileBaseName.ToUpper(); if (!_haircutLevels.Contains(id)) { _haircutLevels.Add(id); } } } }
public static string GetDecodedName(this TR23ScriptedLevel level) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < level.Name.Length; i++) { char c = level.Name[i]; char d; if (i == level.Name.Length - 1) { d = c; } else { d = level.Name[i + 1]; } switch (c) { case '$': switch (d) { case 'A': sb.Append('À'); break; case 'E': sb.Append('È'); break; case 'I': sb.Append('Ì'); break; case 'O': sb.Append('Ò'); break; case 'U': sb.Append('Ù'); break; case 'a': sb.Append('à'); break; case 'e': sb.Append('è'); break; case 'i': sb.Append('ì'); break; case 'o': sb.Append('ò'); break; case 'u': sb.Append('ù'); break; } i++; break; case ')': switch (d) { case 'A': sb.Append('Á'); break; case 'C': sb.Append('Ć'); break; case 'E': sb.Append('É'); break; case 'I': sb.Append('Í'); break; case 'N': sb.Append('Ń'); break; case 'S': sb.Append('Ś'); break; case 'O': sb.Append('Ó'); break; case 'U': sb.Append('Ú'); break; case 'Y': sb.Append('Ý'); break; case 'Z': sb.Append('Ź'); break; case 'a': sb.Append('á'); break; case 'c': sb.Append('ć'); break; case 'e': sb.Append('é'); break; case 'i': sb.Append('í'); break; case 'n': sb.Append('ń'); break; case 's': sb.Append('ś'); break; case 'o': sb.Append('ó'); break; case 'u': sb.Append('ú'); break; case 'y': sb.Append('ý'); break; case 'z': sb.Append('ź'); break; } i++; break; case '(': switch (d) { case 'A': sb.Append('Â'); break; case 'E': sb.Append('Ê'); break; case 'I': sb.Append('Î'); break; case 'O': sb.Append('Ô'); break; case 'U': sb.Append('Û'); break; case 'a': sb.Append('â'); break; case 'e': sb.Append('ê'); break; case 'i': sb.Append('î'); break; case 'o': sb.Append('ô'); break; case 'u': sb.Append('û'); break; } i++; break; case '~': switch (d) { case 'A': sb.Append('Ä'); break; case 'E': sb.Append('Ë'); break; case 'I': sb.Append('Ï'); break; case 'O': sb.Append('Ö'); break; case 'U': sb.Append('Ü'); break; case 'Y': sb.Append('Ÿ'); break; case 'a': sb.Append('ä'); break; case 'e': sb.Append('ë'); break; case 'i': sb.Append('ï'); break; case 'o': sb.Append('ö'); break; case 'u': sb.Append('ü'); break; case 'y': sb.Append('ÿ'); break; } i++; break; default: sb.Append(ConvertChar(c)); break; } } return(sb.ToString()); }
public LevelView(TR23ScriptedLevel level) { _level = level; LevelName = _level.GetDecodedName(); }
private void RandomizeSecrets(List <Location> LevelLocations, TR23ScriptedLevel lvl) { if (LevelLocations.Count > 2) { if (IsDevelopmentModeOn) { PlaceAllSecrets(lvl, LevelLocations); return; } //Apply zoning to the locations to ensure they are spread out. ZonedLocationCollection ZonedLocations = new ZonedLocationCollection(); ZonedLocations.PopulateZones(lvl.LevelFileBaseName.ToUpper(), LevelLocations, ZonePopulationMethod.SecretsOnly); Location GoldSecret; Location JadeSecret; Location StoneSecret; //Find suitable locations, ensuring they are zoned, do not share a room and difficulty. //Location = ZoneLocations[ZoneGroup][LocationInZoneGroup] do { GoldSecret = ZonedLocations.GoldZone[_generator.Next(0, ZonedLocations.GoldZone.Count)]; } while (GoldSecret.Difficulty == Difficulty.Hard && AllowHard == false); do { JadeSecret = ZonedLocations.JadeZone[_generator.Next(0, ZonedLocations.JadeZone.Count)]; } while ((JadeSecret.Room == GoldSecret.Room) || (JadeSecret.Difficulty == Difficulty.Hard && AllowHard == false)); do { StoneSecret = ZonedLocations.StoneZone[_generator.Next(0, ZonedLocations.StoneZone.Count)]; } while ((StoneSecret.Room == GoldSecret.Room) || (StoneSecret.Room == JadeSecret.Room) || (StoneSecret.Difficulty == Difficulty.Hard && AllowHard == false)); //Due to TRMod only accepting room space coords entities are actually stored in level space. So include some //calls to support a transformation of any locations that are specified in room space to maintain backwards compatbility //with older locations and support locations that are specified in both level or room space. GoldSecret = SpatialConverters.TransformToLevelSpace(GoldSecret, _levelInstance.Rooms[GoldSecret.Room].Info); JadeSecret = SpatialConverters.TransformToLevelSpace(JadeSecret, _levelInstance.Rooms[JadeSecret.Room].Info); StoneSecret = SpatialConverters.TransformToLevelSpace(StoneSecret, _levelInstance.Rooms[StoneSecret.Room].Info); //Does the level contain the entities? int GoldIndex = Array.FindIndex(_levelInstance.Entities, ent => (ent.TypeID == (short)TR2Entities.GoldSecret_S_P)); int JadeIndex = Array.FindIndex(_levelInstance.Entities, ent => (ent.TypeID == (short)TR2Entities.JadeSecret_S_P)); int StoneIndex = Array.FindIndex(_levelInstance.Entities, ent => (ent.TypeID == (short)TR2Entities.StoneSecret_S_P)); //Check if we could find instances of the secret entities, if not, we need to add not edit. if (GoldIndex != -1) { _levelInstance.Entities[GoldIndex].Room = Convert.ToInt16(GoldSecret.Room); _levelInstance.Entities[GoldIndex].X = GoldSecret.X; _levelInstance.Entities[GoldIndex].Y = GoldSecret.Y; _levelInstance.Entities[GoldIndex].Z = GoldSecret.Z; } else { TR2Entity GoldEntity = new TR2Entity { TypeID = (int)TR2Entities.GoldSecret_S_P, Room = Convert.ToInt16(GoldSecret.Room), X = GoldSecret.X, Y = GoldSecret.Y, Z = GoldSecret.Z, Angle = 0, Intensity1 = -1, Intensity2 = -1, Flags = 0 }; List <TR2Entity> ents = _levelInstance.Entities.ToList(); ents.Add(GoldEntity); _levelInstance.Entities = ents.ToArray(); _levelInstance.NumEntities++; } if (JadeIndex != -1) { _levelInstance.Entities[JadeIndex].Room = Convert.ToInt16(JadeSecret.Room); _levelInstance.Entities[JadeIndex].X = JadeSecret.X; _levelInstance.Entities[JadeIndex].Y = JadeSecret.Y; _levelInstance.Entities[JadeIndex].Z = JadeSecret.Z; } else { TR2Entity JadeEntity = new TR2Entity { TypeID = (int)TR2Entities.JadeSecret_S_P, Room = Convert.ToInt16(JadeSecret.Room), X = JadeSecret.X, Y = JadeSecret.Y, Z = JadeSecret.Z, Angle = 0, Intensity1 = -1, Intensity2 = -1, Flags = 0 }; List <TR2Entity> ents = _levelInstance.Entities.ToList(); ents.Add(JadeEntity); _levelInstance.Entities = ents.ToArray(); _levelInstance.NumEntities++; } if (StoneIndex != -1) { _levelInstance.Entities[StoneIndex].Room = Convert.ToInt16(StoneSecret.Room); _levelInstance.Entities[StoneIndex].X = StoneSecret.X; _levelInstance.Entities[StoneIndex].Y = StoneSecret.Y; _levelInstance.Entities[StoneIndex].Z = StoneSecret.Z; } else { TR2Entity StoneEntity = new TR2Entity { TypeID = (int)TR2Entities.StoneSecret_S_P, Room = Convert.ToInt16(StoneSecret.Room), X = StoneSecret.X, Y = StoneSecret.Y, Z = StoneSecret.Z, Angle = 0, Intensity1 = -1, Intensity2 = -1, Flags = 0 }; List <TR2Entity> ents = _levelInstance.Entities.ToList(); ents.Add(StoneEntity); _levelInstance.Entities = ents.ToArray(); _levelInstance.NumEntities++; } } }
private void PlaceAllSecrets(TR23ScriptedLevel lvl, List <Location> LevelLocations) { ZonedLocationCollection ZonedLocations = new ZonedLocationCollection(); ZonedLocations.PopulateZones(lvl.LevelFileBaseName.ToUpper(), LevelLocations, ZonePopulationMethod.SecretsOnly); List <TR2Entity> ents = _levelInstance.Entities.ToList(); bool SecretsRemain = true; while (SecretsRemain) { int i; //Remove any existing secrets for (i = 0; i < ents.Count; i++) { if (ents[i].TypeID == (int)TR2Entities.StoneSecret_S_P || ents[i].TypeID == (int)TR2Entities.JadeSecret_S_P || ents[i].TypeID == (int)TR2Entities.GoldSecret_S_P) { ents.RemoveAt(i); i--; break; } } ; //We have exhausted the list and found nothing, if we exited early try again if (i == ents.Count) { SecretsRemain = false; } } //Add new entities foreach (Location loc in ZonedLocations.StoneZone) { Location copy = SpatialConverters.TransformToLevelSpace(loc, _levelInstance.Rooms[loc.Room].Info); ents.Add(new TR2Entity { TypeID = (int)TR2Entities.StoneSecret_S_P, Room = Convert.ToInt16(copy.Room), X = copy.X, Y = copy.Y, Z = copy.Z, Angle = 0, Intensity1 = -1, Intensity2 = -1, Flags = 0 }); } foreach (Location loc in ZonedLocations.JadeZone) { Location copy = SpatialConverters.TransformToLevelSpace(loc, _levelInstance.Rooms[loc.Room].Info); ents.Add(new TR2Entity { TypeID = (int)TR2Entities.JadeSecret_S_P, Room = Convert.ToInt16(copy.Room), X = copy.X, Y = copy.Y, Z = copy.Z, Angle = 0, Intensity1 = -1, Intensity2 = -1, Flags = 0 }); } foreach (Location loc in ZonedLocations.GoldZone) { Location copy = SpatialConverters.TransformToLevelSpace(loc, _levelInstance.Rooms[loc.Room].Info); ents.Add(new TR2Entity { TypeID = (int)TR2Entities.GoldSecret_S_P, Room = Convert.ToInt16(copy.Room), X = copy.X, Y = copy.Y, Z = copy.Z, Angle = 0, Intensity1 = -1, Intensity2 = -1, Flags = 0 }); } _levelInstance.NumEntities = (uint)ents.Count; _levelInstance.Entities = ents.ToArray(); }
protected void LoadLevelInstance(TR23ScriptedLevel scriptedLevel) { _scriptedLevelInstance = scriptedLevel; _levelInstance = LoadLevel(scriptedLevel.LevelFileBaseName); }
private void RandomizeEnemyTypes(TR23ScriptedLevel lvl) { string lvlName = lvl.LevelFileBaseName.ToUpper(); List <TR2Entities> EnemyTypes = TR2EntityUtilities.GetEnemyTypeDictionary()[lvlName]; for (int i = 0; i < _levelInstance.Entities.Count(); i++) { if (lvl.Is(LevelNames.CHICKEN) && _levelInstance.Entities[i].Room == 143 && _levelInstance.Entities[i].TypeID == (int)TR2Entities.BirdMonster) { //#60 - Ice Palace - Room 143 chicken man must remain to avoid softlock. continue; } else if (lvl.Is(LevelNames.HOME) && _levelInstance.Entities[i].TypeID == (int)TR2Entities.ShotgunGoon) { //#62 - Avoid randomizing shotgun goon in HSH continue; } //#45 - Check to see if any items are at the same location as the enemy. //If there are we need to ensure that the new random enemy type is one that can drop items. List <TR2Entity> SharedItems = new List <TR2Entity>(Array.FindAll(_levelInstance.Entities, e => ((e.X == _levelInstance.Entities[i].X) && (e.Y == _levelInstance.Entities[i].Y) && (e.Z == _levelInstance.Entities[i].Z)))); List <TR2Entities> DroppableEnemies = TR2EntityUtilities.DroppableEnemyTypes()[lvlName]; //Is it an entity we are keen on replacing? if (EnemyTypes.Contains((TR2Entities)_levelInstance.Entities[i].TypeID)) { //Do multiple entities share one location? if ((SharedItems.Count > 1) && (DroppableEnemies.Count != 0)) { //Are any entities sharing a location a droppable pickup? bool IsPickupItem = false; foreach (TR2Entity ent in SharedItems) { TR2Entities EntType = (TR2Entities)ent.TypeID; IsPickupItem = (TR2EntityUtilities.IsUtilityType(EntType)) || (TR2EntityUtilities.IsGunType(EntType)) || (TR2EntityUtilities.IsKeyItemType(EntType)); if (IsPickupItem) { break; } } //Generate a location _levelInstance.Entities[i].TypeID = (short)EnemyTypes[_generator.Next(0, EnemyTypes.Count)]; //Do we need to ensure the enemy can drop the item on the same tile? if (!TR2EntityUtilities.CanDropPickups((TR2Entities)_levelInstance.Entities[i].TypeID) && IsPickupItem) { //Ensure the new random entity can drop pickups _levelInstance.Entities[i].TypeID = (short)DroppableEnemies[_generator.Next(0, DroppableEnemies.Count)]; } } else { _levelInstance.Entities[i].TypeID = (short)EnemyTypes[_generator.Next(0, EnemyTypes.Count)]; } short room = _levelInstance.Entities[i].Room; if (!TR2EntityUtilities.IsWaterCreature((TR2Entities)_levelInstance.Entities[i].TypeID) && _levelInstance.Rooms[room].ContainsWater) { if (!PerformDraining(lvlName, room)) { //Draining cannot be performed so make the entity a water creature. TR2Entities ent; //Make sure water creature can appear on level do { ent = TR2EntityUtilities.WaterCreatures()[_generator.Next(0, TR2EntityUtilities.WaterCreatures().Count)]; } while (!EnemyTypes.Contains(ent)); _levelInstance.Entities[i].TypeID = (short)ent; } } } } }