public override void Import() { List <TRColour4> palette16 = Level.Palette16.ToList(); Dictionary <int, int> indexMap = new Dictionary <int, int>(); foreach (int paletteIndex in Definition.Colours.Keys) { TRColour4 newColour = Definition.Colours[paletteIndex]; int existingIndex = palette16.FindIndex ( e => e.Red == newColour.Red && e.Green == newColour.Green && e.Blue == newColour.Blue// && e.Unused == newColour.Unused ); if (existingIndex != -1) { indexMap[paletteIndex] = existingIndex; } else { indexMap[paletteIndex] = P16Importer.Import(Level, newColour); } } foreach (TRMesh mesh in Definition.Meshes) { foreach (TRFace4 rect in mesh.ColouredRectangles) { rect.Texture = ReindexTexture(rect.Texture, indexMap); } foreach (TRFace3 tri in mesh.ColouredTriangles) { tri.Texture = ReindexTexture(tri.Texture, indexMap); } } P16Importer.ResetPaletteTracking(Level); }
public void RedrawStaticTargets(StaticTextureSource source, string variant, Dictionary <TextureCategory, bool> options) { if (source.Categories != null) { // Exclude it if any of its categories are in the options and switched off foreach (TextureCategory category in source.Categories) { if (options.ContainsKey(category) && !options[category]) { return; } } } // For sprite sequence sources, the targets are mapped dynamically. if (source.IsSpriteSequence && (!StaticMapping.ContainsKey(source) || StaticMapping[source].Count == 0)) { GenerateSpriteSequenceTargets(source); } // This can happen if we have a source grouped for this level, // but the source is actually only in place on certain conditions // - an example is the flame in Venice, which is only added if // the Flamethrower has been imported. if (!StaticMapping.ContainsKey(source)) { return; } List <Rectangle> segments = source.VariantMap[variant]; foreach (StaticTextureTarget target in StaticMapping[source]) { if (target.Segment < 0 || target.Segment >= segments.Count) { throw new IndexOutOfRangeException(string.Format("Segment {0} is invalid for texture source {1}.", target.Segment, source.PNGPath)); } GetBitmapGraphics(target.Tile).ImportSegment(source, target, segments[target.Segment]); } if (source.EntityColourMap != null) { foreach (TR2Entities entity in source.EntityColourMap.Keys) { TRMesh[] meshes = TR2LevelUtilities.GetModelMeshes(_level, entity); ISet <int> colourIndices = new HashSet <int>(); foreach (TRMesh mesh in meshes) { foreach (TRFace4 t in mesh.ColouredRectangles) { colourIndices.Add(BitConverter.GetBytes(t.Texture)[1]); } foreach (TRFace3 t in mesh.ColouredTriangles) { colourIndices.Add(BitConverter.GetBytes(t.Texture)[1]); } } Dictionary <int, int> remapIndices = new Dictionary <int, int>(); foreach (Color targetColour in source.EntityColourMap[entity].Keys) { int matchedIndex = -1; foreach (int currentIndex in colourIndices) { TRColour4 currentColour = _level.Palette16[currentIndex]; if (currentColour.Red == targetColour.R && currentColour.Green == targetColour.G && currentColour.Blue == targetColour.B) { matchedIndex = currentIndex; } } if (matchedIndex == -1) { continue; } // Extract the colour from the top-left of the rectangle specified in the source, and import that into the level int sourceRectangle = source.EntityColourMap[entity][targetColour]; int newColourIndex = P16Importer.Import(_level, source.Bitmap.GetPixel(segments[sourceRectangle].X, segments[sourceRectangle].Y)); remapIndices.Add(matchedIndex, newColourIndex); } // Remap the affected mesh textures to the newly inserted colours foreach (TRMesh mesh in meshes) { foreach (TRFace4 t in mesh.ColouredRectangles) { t.Texture = ConvertMeshTexture(t.Texture, remapIndices); } foreach (TRFace3 t in mesh.ColouredTriangles) { t.Texture = ConvertMeshTexture(t.Texture, remapIndices); } } } // Reset the palette tracking P16Importer.ResetPaletteTracking(_level); } }