示例#1
0
        private void ValidateDefinitionList(List <TR2Entities> modelEntities)
        {
            Dictionary <TR2Entities, List <TR2Entities> > detectedAliases = new Dictionary <TR2Entities, List <TR2Entities> >();

            foreach (TR2Entities entity in modelEntities)
            {
                if (_entityAliases.ContainsKey(entity))
                {
                    TR2Entities masterEntity = _entityAliases[entity];
                    if (!detectedAliases.ContainsKey(masterEntity))
                    {
                        detectedAliases[masterEntity] = new List <TR2Entities>();
                    }
                    detectedAliases[_entityAliases[entity]].Add(entity);
                }
            }

            foreach (TR2Entities masterEntity in detectedAliases.Keys)
            {
                if (detectedAliases[masterEntity].Count > 1 && !_permittedAliasDuplicates.Contains(masterEntity))
                {
                    throw new TransportException(string.Format
                                                 (
                                                     "Only one alias per entity can exist in the same level. [{0}] were found as aliases for {1}.",
                                                     string.Join(", ", detectedAliases[masterEntity]),
                                                     masterEntity.ToString()
                                                 ));
                }
            }
        }
示例#2
0
            protected override void StartImpl()
            {
                // Make the outfit selection outwith the processing thread to ensure consistent RNG.
                // We select all potential Laras including the default for the level as there are
                // only 4 to choose from (there is also Assault Course Lara, but when holstering pistols
                // her trousers disappear, so she is excluded for the time being...).
                List <TR2Entities>      allLaras = TR2EntityUtilities.GetLaraTypes();
                List <TR2CombinedLevel> levels   = new List <TR2CombinedLevel>(_outfitAllocations.Keys);

                foreach (TR2CombinedLevel level in levels)
                {
                    // Add the persistent outfit first, but we will populate the candidate
                    // list regardless in case a level cannot support this choice.
                    if (_outer.PersistOutfits)
                    {
                        _outfitAllocations[level].Add(_outer._persistentOutfit);
                    }

                    while (_outfitAllocations[level].Count < allLaras.Count)
                    {
                        TR2Entities nextLara = allLaras[_outer._generator.Next(0, allLaras.Count)];
                        if (!_outfitAllocations[level].Contains(nextLara))
                        {
                            _outfitAllocations[level].Add(nextLara);
                        }
                    }
                }
            }
示例#3
0
        private void DisguiseEntity(TR2CombinedLevel level, TR2Entities guiser, TR2Entities targetEntity)
        {
            List <TRModel> models        = level.Data.Models.ToList();
            int            existingIndex = models.FindIndex(m => m.ID == (short)guiser);

            if (existingIndex != -1)
            {
                models.RemoveAt(existingIndex);
            }

            TRModel disguiseAsModel = models[models.FindIndex(m => m.ID == (short)targetEntity)];

            if (targetEntity == TR2Entities.BirdMonster && level.Is(LevelNames.CHICKEN))
            {
                // We have to keep the original model for the boss, so in
                // this instance we just clone the model for the guiser
                models.Add(new TRModel
                {
                    Animation    = disguiseAsModel.Animation,
                    FrameOffset  = disguiseAsModel.FrameOffset,
                    ID           = (uint)guiser,
                    MeshTree     = disguiseAsModel.MeshTree,
                    NumMeshes    = disguiseAsModel.NumMeshes,
                    StartingMesh = disguiseAsModel.StartingMesh
                });
            }
            else
            {
                disguiseAsModel.ID = (uint)guiser;
            }

            level.Data.Models    = models.ToArray();
            level.Data.NumModels = (uint)models.Count;
        }
示例#4
0
 public void AddEntity(TR2Entities entity)
 {
     if (!Entities.Contains(entity))
     {
         Entities.Add(entity);
     }
 }
示例#5
0
        private TR2Entities GetWeaponAmmo(TR2Entities weapon)
        {
            switch (weapon)
            {
            case TR2Entities.Shotgun_S_P:
                return(TR2Entities.ShotgunAmmo_S_P);

            case TR2Entities.Automags_S_P:
                return(TR2Entities.AutoAmmo_S_P);

            case TR2Entities.Uzi_S_P:
                return(TR2Entities.UziAmmo_S_P);

            case TR2Entities.Harpoon_S_P:
                return(TR2Entities.HarpoonAmmo_S_P);

            case TR2Entities.M16_S_P:
                return(TR2Entities.M16Ammo_S_P);

            case TR2Entities.GrenadeLauncher_S_P:
                return(TR2Entities.Grenades_S_P);

            default:
                return(TR2Entities.PistolAmmo_S_P);
            }
        }
示例#6
0
        // roomNumber is specified if ONLY that room is to be populated
        private void PlaceAllItems(List <Location> locations, int roomNumber = -1, TR2Entities entityToAdd = TR2Entities.LargeMed_S_P, bool transformToLevelSpace = true)
        {
            List <TR2Entity> ents = _levelInstance.Data.Entities.ToList();

            foreach (Location loc in locations)
            {
                Location copy = transformToLevelSpace ? SpatialConverters.TransformToLevelSpace(loc, _levelInstance.Data.Rooms[loc.Room].Info) : loc;

                if (roomNumber == -1 || roomNumber == copy.Room)
                {
                    ents.Add(new TR2Entity
                    {
                        TypeID     = (short)entityToAdd,
                        Room       = Convert.ToInt16(copy.Room),
                        X          = copy.X,
                        Y          = copy.Y,
                        Z          = copy.Z,
                        Angle      = 0,
                        Intensity1 = -1,
                        Intensity2 = -1,
                        Flags      = 0
                    });
                }
            }

            _levelInstance.Data.NumEntities = (uint)ents.Count;
            _levelInstance.Data.Entities    = ents.ToArray();
        }
示例#7
0
        private void AdjustEntities()
        {
            // If an entity is marked to be removed but is also in the list
            // to import, don't remove it in the first place.
            List <TR2Entities> cleanedEntities = new List <TR2Entities>();

            foreach (TR2Entities entity in EntitiesToRemove)
            {
                if (_aliasMap.ContainsKey(entity))
                {
                    // Check if we have another alias in the import list different from any
                    // in the current level
                    TR2Entities alias       = TR2EntityUtilities.GetAliasForLevel(LevelName, entity);
                    TR2Entities importAlias = TR2Entities.Lara;
                    foreach (TR2Entities a in _aliasMap[entity])
                    {
                        if (EntitiesToImport.Contains(a))
                        {
                            importAlias = a;
                            break;
                        }
                    }

                    if (alias != importAlias)
                    {
                        cleanedEntities.Add(entity);
                    }
                }
                else if (!EntitiesToImport.Contains(entity))
                {
                    cleanedEntities.Add(entity);
                }
            }
            EntitiesToRemove = cleanedEntities;
        }
示例#8
0
        public TRModelDefinition CreateModelDefinition(TR2Entities modelEntity)
        {
            Definition = new TRModelDefinition
            {
                Alias = modelEntity
            };

            if (_entityAliases.ContainsKey(modelEntity))
            {
                modelEntity = _entityAliases[modelEntity];
            }
            _modelHandler.ModelEntity = modelEntity;

            _textureHandler.ExportIndividualSegments = ExportIndividualSegments;
            _textureHandler.SegmentsFolder           = _segmentsFolder;
            _textureHandler.TextureClassifier        = TextureClassifier;

            _modelHandler.Export();
            _meshHandler.Export();
            _colourHandler.Export();
            _textureHandler.Export();
            _animationHandler.Export();
            _cinematicHandler.Export();
            _soundHandler.Export();

            ExportDependencies();

            return(_definition);
        }
示例#9
0
 public static int GetRestrictedEnemyLevelCount(TR2Entities entity)
 {
     if (_restrictedEnemyLevelCounts.ContainsKey(entity))
     {
         return(_restrictedEnemyLevelCounts[entity]);
     }
     return(-1);
 }
示例#10
0
 private void SetPersistentOutfit()
 {
     if (PersistOutfits)
     {
         List <TR2Entities> allLaras = TR2EntityUtilities.GetLaraTypes();
         _persistentOutfit = allLaras[_generator.Next(0, allLaras.Count)];
     }
 }
示例#11
0
 public static bool IsAmmoType(TR2Entities entity)
 {
     return(entity == TR2Entities.ShotgunAmmo_S_P ||
            entity == TR2Entities.AutoAmmo_S_P ||
            entity == TR2Entities.UziAmmo_S_P ||
            entity == TR2Entities.HarpoonAmmo_S_P ||
            entity == TR2Entities.M16Ammo_S_P ||
            entity == TR2Entities.Grenades_S_P);
 }
示例#12
0
        private void PopulateVehicleLocation(TR2Entities entity, Dictionary <TR2Entities, Location> locationMap)
        {
            Location location = VehicleUtilities.GetRandomLocation(_levelInstance.Name, entity, _generator);

            if (location != null)
            {
                locationMap[entity] = location;
            }
        }
示例#13
0
        private void BuildDefinitionList(List <TRModelDefinition> standardModelDefinitions, List <TRModelDefinition> soundModelDefinitions, List <TR2Entities> modelEntities, TR2Entities nextEntity, bool isDependency)
        {
            if (modelEntities.Contains(nextEntity))
            {
                // If the model already in the list is a dependency only, but the new one to add isn't, switch it
                TRModelDefinition definition = standardModelDefinitions.Find(m => m.Alias == nextEntity);
                if (definition != null && definition.IsDependencyOnly && !isDependency)
                {
                    definition.IsDependencyOnly = false;
                }
                return;
            }

            TRModelDefinition nextDefinition = LoadDefinition(nextEntity);

            nextDefinition.IsDependencyOnly = isDependency;
            modelEntities.Add(nextEntity);

            // Add dependencies first
            foreach (TR2Entities dependency in nextDefinition.Dependencies)
            {
                // If it's a non-graphics dependency, but we are importing another alias
                // for it, or the level already contains the dependency, we don't need it.
                bool        nonGraphics = _noGraphicsEntityDependencies.Contains(dependency);
                TR2Entities aliasFor    = TR2EntityUtilities.TranslateEntityAlias(dependency);
                if (aliasFor != dependency && nonGraphics)
                {
                    bool required = true;
                    // #139 check entire model list for instances where alias and dependencies cause clashes
                    foreach (TR2Entities entity in modelEntities)
                    {
                        // If this entity and the dependency are in the same family
                        if (aliasFor == TR2EntityUtilities.TranslateEntityAlias(entity))
                        {
                            // Skip it
                            required = false;
                            break;
                        }
                    }

                    if (!required)
                    {
                        // We don't need the graphics, but do we need hardcoded sound?
                        if (_soundOnlyDependencies.Contains(dependency) && standardModelDefinitions.Find(m => m.Alias == dependency) == null)
                        {
                            soundModelDefinitions.Add(LoadDefinition(dependency));
                        }

                        continue;
                    }
                }

                BuildDefinitionList(standardModelDefinitions, soundModelDefinitions, modelEntities, dependency, nonGraphics);
            }

            standardModelDefinitions.Add(nextDefinition);
        }
示例#14
0
        public static bool IsEnemySupported(string lvlName, TR2Entities entity)
        {
            if (_unsupportedEnemies.ContainsKey(lvlName))
            {
                return(!_unsupportedEnemies[lvlName].Contains(TR2EntityUtilities.TranslateEntityAlias(entity)));
            }

            return(true);
        }
示例#15
0
 public static bool IsGunType(TR2Entities entity)
 {
     return(entity == TR2Entities.Shotgun_S_P ||
            entity == TR2Entities.Automags_S_P ||
            entity == TR2Entities.Uzi_S_P ||
            entity == TR2Entities.Harpoon_S_P ||
            entity == TR2Entities.M16_S_P ||
            entity == TR2Entities.GrenadeLauncher_S_P);
 }
示例#16
0
        public static List <TR2Entities> GetEnemyGuisers(TR2Entities entity)
        {
            List <TR2Entities> entities = new List <TR2Entities>();

            if (_enemyGuisers.ContainsKey(entity))
            {
                entities.AddRange(_enemyGuisers[entity]);
            }
            return(entities);
        }
示例#17
0
        public static TRModel GetModel(TR2Level level, TR2Entities entity)
        {
            int i = level.Models.ToList().FindIndex(e => e.ID == (uint)entity);

            if (i != -1)
            {
                return(level.Models[i]);
            }
            return(null);
        }
示例#18
0
        public static TRMesh[] GetModelMeshes(TR2Level level, TR2Entities entity)
        {
            TRModel model = GetModel(level, entity);

            if (model != null)
            {
                return(GetModelMeshes(level, model));
            }
            return(null);
        }
示例#19
0
        public void RemoveModelSegmentsChecked(IEnumerable <TR2Entities> modelEntitiesToRemove)
        {
            // Perform an exhaustive check against every other model in the level to find shared textures.

            Dictionary <TR2Entities, Dictionary <TexturedTile, List <TexturedTileSegment> > > candidateSegments = new Dictionary <TR2Entities, Dictionary <TexturedTile, List <TexturedTileSegment> > >();

            // First cache each segment for the models we wish to remove
            foreach (TR2Entities modelEntity in modelEntitiesToRemove)
            {
                candidateSegments[modelEntity] = GetModelSegments(modelEntity);
            }

            // Load the segments for every other model in the level. For each, scan the segments of
            // the removal candidates. If any is used by any other model, the segment is no longer
            // a candidate. If the other model that shares it is in the list to remove, it will
            // remain a candidate.
            foreach (TRModel model in Level.Models)
            {
                TR2Entities otherEntity = (TR2Entities)model.ID;
                if (modelEntitiesToRemove.Contains(otherEntity))
                {
                    continue;
                }

                Dictionary <TexturedTile, List <TexturedTileSegment> > modelSegments = GetModelSegments(otherEntity);
                foreach (TR2Entities entityToRemove in modelEntitiesToRemove)
                {
                    Dictionary <TexturedTile, List <TexturedTileSegment> > entityMap = candidateSegments[entityToRemove];
                    foreach (TexturedTile tile in entityMap.Keys)
                    {
                        if (modelSegments.ContainsKey(tile))
                        {
                            int match = entityMap[tile].FindIndex(s1 => modelSegments[tile].Any(s2 => s1 == s2));
                            if (match != -1)
                            {
                                //System.Diagnostics.Debug.WriteLine("\t\t" + otherEntity + ", " + tile.Index + ": " + entityMap[tile][match].Bounds);
                                entityMap[tile].RemoveAt(match);
                            }
                        }
                    }
                }
            }

            // Tell each tile to remove the candidate segments
            foreach (Dictionary <TexturedTile, List <TexturedTileSegment> > segmentMap in candidateSegments.Values)
            {
                foreach (TexturedTile tile in segmentMap.Keys)
                {
                    foreach (TexturedTileSegment segment in segmentMap[tile])
                    {
                        tile.Remove(segment);
                    }
                }
            }
        }
示例#20
0
        public static TR2Entities TranslateEntityAlias(TR2Entities entity)
        {
            foreach (TR2Entities parentEntity in EntityFamilies.Keys)
            {
                if (EntityFamilies[parentEntity].Contains(entity))
                {
                    return(parentEntity);
                }
            }

            return(entity);
        }
示例#21
0
 private void AdjustOutfit(TR2CombinedLevel level, TR2Entities lara)
 {
     if (level.Is(LevelNames.HOME) && lara != TR2Entities.LaraHome)
     {
         // This ensures that Lara's hips match the new outfit for the starting animation and shower cutscene,
         // otherwise the dressing gown hips are rendered, but the mesh is completely different for this, plus
         // its textures will have been removed.
         TRMesh laraMiscMesh = TR2LevelUtilities.GetModelFirstMesh(level.Data, TR2Entities.LaraMiscAnim_H);
         TRMesh laraHipsMesh = TR2LevelUtilities.GetModelFirstMesh(level.Data, TR2Entities.Lara);
         TR2LevelUtilities.DuplicateMesh(level.Data, laraMiscMesh, laraHipsMesh);
     }
 }
示例#22
0
        private void CleanAliases()
        {
            List <TR2Entities> cleanedEntities = new List <TR2Entities>();

            // Do we have any aliases?
            foreach (TR2Entities importEntity in EntitiesToImport)
            {
                if (_aliasMap.ContainsKey(importEntity))
                {
                    throw new TransportException(string.Format
                                                 (
                                                     "Cannot import ambiguous entity {0} - choose an alias from [{1}].",
                                                     importEntity.ToString(),
                                                     string.Join(", ", _aliasMap[importEntity])
                                                 ));
                }

                bool entityIsValid = true;
                if (_entityAliases.ContainsKey(importEntity))
                {
                    TR2Entities existingEntity = TR2EntityUtilities.GetAliasForLevel(LevelName, _entityAliases[importEntity]);
                    // This entity is only valid if the alias it's for is not already there
                    entityIsValid = importEntity != existingEntity;
                }

                if (entityIsValid)
                {
                    cleanedEntities.Add(importEntity);
                }
            }

            // #139 Ensure that aliases are added last so to avoid dependency issues
            cleanedEntities.Sort(delegate(TR2Entities e1, TR2Entities e2)
            {
                return(((short)TR2EntityUtilities.TranslateEntityAlias(e1)).CompareTo((short)TR2EntityUtilities.TranslateEntityAlias(e2)));
            });

            // For some reason, if the Barracuda is added before the shark, there is a slight animation
            // corruption on the shark's mouth. I can't find the reason. The patch is to ensure the
            // Barracuda is added last.
            // #137 Reason found - animated textures were not being reindexed following deduplication. See
            // TRModelExtensions.ReindexTextures and #137.

            /*int barracudaIndex = cleanedEntities.FindIndex(e => _aliasMap[TR2Entities.Barracuda].Contains(e));
             * if (barracudaIndex != -1)
             * {
             *  TR2Entities barracuda = cleanedEntities[barracudaIndex];
             *  cleanedEntities.RemoveAt(barracudaIndex);
             *  cleanedEntities.Add(barracuda);
             * }*/

            EntitiesToImport = cleanedEntities;
        }
示例#23
0
 public static bool IsUtilityType(TR2Entities entity)
 {
     return(entity == TR2Entities.ShotgunAmmo_S_P ||
            entity == TR2Entities.AutoAmmo_S_P ||
            entity == TR2Entities.UziAmmo_S_P ||
            entity == TR2Entities.HarpoonAmmo_S_P ||
            entity == TR2Entities.M16Ammo_S_P ||
            entity == TR2Entities.Grenades_S_P ||
            entity == TR2Entities.SmallMed_S_P ||
            entity == TR2Entities.LargeMed_S_P ||
            entity == TR2Entities.Flares_S_P);
 }
示例#24
0
        public StaticTextureSource[] GetStaticSource(TR2Entities entity)
        {
            List <StaticTextureSource> sources = new List <StaticTextureSource>();

            if (_entityMap.ContainsKey(entity))
            {
                foreach (string src in _entityMap[entity])
                {
                    sources.Add(GetStaticSource(src));
                }
            }
            return(sources.ToArray());
        }
示例#25
0
        private void CopyEntity(TR2Entity entity, TR2Entities newType)
        {
            List <TR2Entity> ents = _levelInstance.Data.Entities.ToList();

            if (ents.Count < _levelInstance.GetMaximumEntityLimit())
            {
                TR2Entity copy = entity.Clone();
                copy.TypeID = (short)newType;
                ents.Add(copy);
                _levelInstance.Data.NumEntities++;
                _levelInstance.Data.Entities = ents.ToArray();
            }
        }
示例#26
0
        private StaticTextureSource[] GetSources(TR2Entities entity)
        {
            List <StaticTextureSource> sources = new List <StaticTextureSource>();

            foreach (StaticTextureSource source in _entitySources)
            {
                if (source.EntityTextureMap.ContainsKey(entity))
                {
                    sources.Add(source);
                }
            }
            return(sources.ToArray());
        }
示例#27
0
 public static bool IsKeyItemType(TR2Entities entity)
 {
     return(entity == TR2Entities.Key1_S_P ||
            entity == TR2Entities.Key2_S_P ||
            entity == TR2Entities.Key3_S_P ||
            entity == TR2Entities.Key4_S_P ||
            entity == TR2Entities.Puzzle1_S_P ||
            entity == TR2Entities.Puzzle2_S_P ||
            entity == TR2Entities.Puzzle3_S_P ||
            entity == TR2Entities.Puzzle4_S_P ||
            entity == TR2Entities.Quest1_S_P ||
            entity == TR2Entities.Quest2_S_P);
 }
示例#28
0
 public static TR2Entities GetAliasForLevel(string lvl, TR2Entities entity)
 {
     if (LevelEntityAliases.ContainsKey(entity))
     {
         foreach (TR2Entities alias in LevelEntityAliases[entity].Keys)
         {
             if (LevelEntityAliases[entity][alias].Contains(lvl))
             {
                 return(alias);
             }
         }
     }
     return(entity);
 }
示例#29
0
        public static List <TR2Entities> GetEntityFamily(TR2Entities entity)
        {
            foreach (TR2Entities parentEntity in EntityFamilies.Keys)
            {
                if (EntityFamilies[parentEntity].Contains(entity))
                {
                    return(EntityFamilies[parentEntity]);
                }
            }

            return(new List <TR2Entities> {
                entity
            });
        }
示例#30
0
 public static bool IsWaterEnemyRequired(TR2CombinedLevel level)
 {
     foreach (TR2Entity entityInstance in level.Data.Entities)
     {
         TR2Entities entity = (TR2Entities)entityInstance.TypeID;
         if (TR2EntityUtilities.IsWaterCreature(entity))
         {
             if (!level.CanPerformDraining(entityInstance.Room))
             {
                 // Draining cannot be performed so we need to ensure we get at least one water enemy
                 return(true);
             }
         }
     }
     return(false);
 }