private void RandomizeFloorTracks(TR2Level level, FDControl floorData) { // Try to keep triggers that are beside each other and setup for the same // thing using the same track, otherwise the result is just a bit too random. // This relies on tr2audio.json having PrimaryCategory properly defined for // each track. foreach (TR2Room room in level.Rooms) { Dictionary <TRAudioCategory, TRAudioTrack> roomTracks = new Dictionary <TRAudioCategory, TRAudioTrack>(); List <FDActionListItem> triggerItems = new List <FDActionListItem>(); foreach (TRRoomSector sector in room.SectorList) { if (sector.FDIndex > 0) { triggerItems.AddRange(FDUtilities.GetActionListItems(floorData, FDTrigAction.PlaySoundtrack, sector.FDIndex)); } } // Generate a random track for the first in each category for this room, then others // in the same category will follow suit. foreach (FDActionListItem item in triggerItems) { TRAudioCategory category = FindTrackCategory(item.Parameter); if (!roomTracks.ContainsKey(category)) { List <TRAudioTrack> tracks = _tracks[category]; roomTracks[category] = tracks[_generator.Next(0, tracks.Count)]; } item.Parameter = roomTracks[category].ID; } } }
public static void SetEntityTriggers(TR2Level level, TR2Entity entity) { if (_oneShotEnemies.Contains((TR2Entities)entity.TypeID)) { int entityID = level.Entities.ToList().IndexOf(entity); FDControl fdControl = new FDControl(); fdControl.ParseFromLevel(level); List <FDTriggerEntry> triggers = FDUtilities.GetEntityTriggers(fdControl, entityID); foreach (FDTriggerEntry trigger in triggers) { trigger.TrigSetup.SetOneShot(); } fdControl.WriteToLevel(level); } }
public void FloorData_ReadWriteOneShotTest() { //Read GW data TR2LevelReader reader = new TR2LevelReader(); TR2Level lvl = reader.ReadLevel("wall.tr2"); //Parse the floordata using FDControl FDControl fdataReader = new FDControl(); fdataReader.ParseFromLevel(lvl); //Get all triggers for entity ID 18 List <FDTriggerEntry> triggers = FDUtilities.GetEntityTriggers(fdataReader, 18); //There should be 3 Assert.AreEqual(triggers.Count, 3); //Verify none of the triggers has OneShot set foreach (FDTriggerEntry trigger in triggers) { Assert.IsFalse(trigger.TrigSetup.OneShot); } //Set OneShot on each trigger foreach (FDTriggerEntry trigger in triggers) { trigger.TrigSetup.SetOneShot(); } fdataReader.WriteToLevel(lvl); //Save it and read it back in TR2LevelWriter writer = new TR2LevelWriter(); writer.WriteLevelToFile(lvl, "TEST.tr2"); lvl = reader.ReadLevel("TEST.tr2"); fdataReader = new FDControl(); fdataReader.ParseFromLevel(lvl); //Get the triggers again afresh triggers = FDUtilities.GetEntityTriggers(fdataReader, 18); //Verify that they now have OneShot set foreach (FDTriggerEntry trigger in triggers) { Assert.IsTrue(trigger.TrigSetup.OneShot); } //Switch it off again foreach (FDTriggerEntry trigger in triggers) { trigger.TrigSetup.ClearOneShot(); } fdataReader.WriteToLevel(lvl); //Save it and read it back in writer.WriteLevelToFile(lvl, "TEST.tr2"); lvl = reader.ReadLevel("TEST.tr2"); fdataReader = new FDControl(); fdataReader.ParseFromLevel(lvl); //Get the triggers again afresh triggers = FDUtilities.GetEntityTriggers(fdataReader, 18); //Verify that they now once again do not have OneShot set foreach (FDTriggerEntry trigger in triggers) { Assert.IsFalse(trigger.TrigSetup.OneShot); } }
private void RandomizeSecretTracks(TR2Level level, FDControl floorData) { // Generate new triggers for secrets to allow different sounds for each one List <TRAudioTrack> secretTracks = _tracks[TRAudioCategory.Secret]; Dictionary <int, TR2Entity> secrets = GetSecretItems(level); foreach (int entityIndex in secrets.Keys) { TR2Entity secret = secrets[entityIndex]; TRRoomSector sector = FDUtilities.GetRoomSector(secret.X, secret.Y, secret.Z, secret.Room, level, floorData); if (sector.FDIndex == 0) { // The secret is positioned on a tile that currently has no FD, so create it floorData.CreateFloorData(sector); } List <FDEntry> entries = floorData.Entries[sector.FDIndex]; FDTriggerEntry existingTriggerEntry = entries.Find(e => e is FDTriggerEntry) as FDTriggerEntry; bool existingEntityPickup = false; if (existingTriggerEntry != null) { if (existingTriggerEntry.TrigType == FDTrigType.Pickup && existingTriggerEntry.TrigActionList[0].Parameter == entityIndex) { // GW gold secret (default location) already has a pickup trigger to spawn the // TRex (or whatever enemy) so we'll just append to that item list here existingEntityPickup = true; } else { // There is already a non-pickup trigger for this sector so while nothing is wrong with // adding a pickup trigger, the game ignores it. So in this instance, the sound that // plays will just be whatever is set in the script. continue; } } // Generate a new music action FDActionListItem musicAction = new FDActionListItem { TrigAction = FDTrigAction.PlaySoundtrack, Parameter = secretTracks[_generator.Next(0, secretTracks.Count)].ID }; // For GW default gold, just append it if (existingEntityPickup) { existingTriggerEntry.TrigActionList.Add(musicAction); } else { entries.Add(new FDTriggerEntry { // The values here are replicated from Trigger#112 (in trview) in GW. // The first action list must be the entity being picked up and so // remaining action list items are actioned on pick up. Setup = new FDSetup { Value = 1028 }, TrigSetup = new FDTrigSetup { Value = 15872 }, TrigActionList = new List <FDActionListItem> { new FDActionListItem { TrigAction = FDTrigAction.Object, Parameter = (ushort)entityIndex }, musicAction } }); } } }