private Texture2D GetWeaponTextureAtlas(
            string filename,
            MetalTypes metalType,
            out Rect[] rectsOut,
            out RecordIndex[] indicesOut,
            int padding,
            int border,
            bool dilate = false)
        {
            // Load texture file
            cifFile.Load(Path.Combine(dfUnity.Arena2Path, filename), FileUsage.UseMemory, true);

            // Read every image in archive
            Rect               rect;
            List <Texture2D>   textures = new List <Texture2D>();
            List <RecordIndex> indices  = new List <RecordIndex>();

            for (int record = 0; record < cifFile.RecordCount; record++)
            {
                int         frames = cifFile.GetFrameCount(record);
                DFSize      size   = cifFile.GetSize(record);
                RecordIndex ri     = new RecordIndex()
                {
                    startIndex = textures.Count,
                    frameCount = frames,
                    width      = size.Width,
                    height     = size.Height,
                };
                indices.Add(ri);
                for (int frame = 0; frame < frames; frame++)
                {
                    textures.Add(GetWeaponTexture2D(filename, record, frame, metalType, out rect, border, dilate));
                }
            }

            // Pack textures into atlas
            Texture2D atlas = new Texture2D(2048, 2048, TextureFormat.RGBA32, false);

            rectsOut   = atlas.PackTextures(textures.ToArray(), padding, 2048);
            indicesOut = indices.ToArray();

            // Shrink UV rect to compensate for internal border
            float ru = 1f / atlas.width;
            float rv = 1f / atlas.height;

            for (int i = 0; i < rectsOut.Length; i++)
            {
                Rect rct = rectsOut[i];
                rct.xMin   += border * ru;
                rct.xMax   -= border * ru;
                rct.yMin   += border * rv;
                rct.yMax   -= border * rv;
                rectsOut[i] = rct;
            }

            return(atlas);
        }
        /// <summary>
        /// Get name for a CifRci image with a metal type.
        /// </summary>
        /// <param name="filename">Name of CIF/RCI file.</param>
        /// <param name="record">Record index.</param>
        /// <param name="frame">Frame index. It's different than zero only for animations.</param>
        /// <param name="metalType">Metal type of weapon.</param>
        static public string GetNameCifRci(string filename, int record, int frame, MetalTypes metalType)
        {
            if (metalType == MetalTypes.None)
            {
                return(GetNameCifRci(filename, record, frame));
            }

            return(string.Format("{0}_{1}", GetNameCifRci(filename, record, frame), metalType));
        }
示例#3
0
 /// <summary>
 /// Convert (filename, record, frame) to string name.
 /// </summary>
 /// <param name="filename">Name of CIF/RCI file.</param>
 /// <param name="record">Record index.</param>
 /// <param name="frame">Frame index. It's different than zero only for animations.</param>
 /// <param name="metalType">Metal type of weapon.</param>
 static public string GetNameCifRci(string filename, int record, int frame, MetalTypes metalType)
 {
     if (metalType == MetalTypes.None)
     {
         return(GetNameCifRci(filename, record, frame));
     }
     else
     {
         return(GetNameCifRci(filename, record, frame) + "_" + metalType);
     }
 }
        // Gets colour indices based on metal type
        public static byte[] GetMetalColors(MetalTypes metalType)
        {
            byte[] indices;
            switch (metalType)
            {
            case MetalTypes.Iron:
                indices = new byte[] { 0x77, 0x78, 0x57, 0x79, 0x58, 0x59, 0x7A, 0x5A, 0x7B, 0x5B, 0x7C, 0x5C, 0x7D, 0x5D, 0x5E, 0x5F };
                break;

            case MetalTypes.Steel:
                indices = new byte[] { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F };
                break;

            case MetalTypes.Silver:
                indices = new byte[] { 0xE0, 0x70, 0x50, 0x71, 0x51, 0x72, 0x73, 0x52, 0x74, 0x53, 0x75, 0x54, 0x55, 0x56, 0x57, 0x58 };
                break;

            case MetalTypes.Elven:
                indices = new byte[] { 0xE0, 0x70, 0x50, 0x71, 0x51, 0x72, 0x73, 0x52, 0x74, 0x53, 0x75, 0x54, 0x55, 0x56, 0x57, 0x58 };
                break;

            case MetalTypes.Dwarven:
                indices = new byte[] { 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F };
                break;

            case MetalTypes.Mithril:
                indices = new byte[] { 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE };
                break;

            case MetalTypes.Adamantium:
                indices = new byte[] { 0x5A, 0x5B, 0x7C, 0x5C, 0x7D, 0x5D, 0x7E, 0x5E, 0x7F, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE };
                break;

            case MetalTypes.Ebony:
                indices = new byte[] { 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE };
                break;

            case MetalTypes.Orcish:
                indices = new byte[] { 0xA2, 0xA3, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD };
                break;

            case MetalTypes.Daedric:
                indices = new byte[] { 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE };
                break;

            default:
                indices = new byte[] { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F };
                break;
            }

            return(indices);
        }
示例#5
0
        private void LoadWeaponAtlas()
        {
            // Get weapon filename
            string filename = WeaponBasics.GetWeaponFilename(WeaponType);

            // Load the weapon texture atlas
            // Texture is dilated into a transparent coloured border to remove dark edges when filtered
            // Important to use returned UV rects when drawing to get right dimensions
            weaponAtlas            = GetWeaponTextureAtlas(filename, MetalType, out weaponRects, out weaponIndices, 2, 2, true);
            weaponAtlas.filterMode = dfUnity.MaterialReader.MainFilterMode;

            // Get weapon anims
            weaponAnims = (WeaponAnimation[])WeaponBasics.GetWeaponAnims(WeaponType).Clone();

            // Store current weapon
            currentWeaponType = WeaponType;
            currentMetalType  = MetalType;
        }
示例#6
0
        private Texture2D GetWeaponTexture2D(
            string filename,
            int record,
            int frame,
            MetalTypes metalType,
            out Rect rectOut,
            int border  = 0,
            bool dilate = false)
        {
            // Get source bitmap
            DFBitmap dfBitmap = cifFile.GetDFBitmap(record, frame);

            // Tint based on metal type
            // But not for steel as that is default colour in files
            if (metalType != MetalTypes.Steel && metalType != MetalTypes.None)
            {
                dfBitmap = ImageProcessing.ChangeDye(dfBitmap, ImageProcessing.GetMetalDyeColor(metalType), DyeTargets.WeaponsAndArmor);
            }

            // Get Color32 array
            DFSize sz;

            Color32[] colors = cifFile.GetColor32(dfBitmap, 0, border, out sz);

            // Dilate edges
            if (border > 0 && dilate)
            {
                ImageProcessing.DilateColors(ref colors, sz);
            }

            // Create Texture2D
            Texture2D texture = new Texture2D(sz.Width, sz.Height, TextureFormat.ARGB32, false);

            texture.SetPixels32(colors);
            texture.Apply(true);

            // Shrink UV rect to compensate for internal border
            float ru = 1f / sz.Width;
            float rv = 1f / sz.Height;

            rectOut = new Rect(border * ru, border * rv, (sz.Width - border * 2) * ru, (sz.Height - border * 2) * rv);

            return(texture);
        }
        /// <summary>
        /// Tint a weapon image based on metal type.
        /// </summary>
        /// <param name="srcBitmap">Source weapon image.</param>
        /// <param name="size">Image size.</param>
        /// <param name="metalType">Metal type for tint.</param>
        public static void TintWeaponImage(ref DFBitmap srcBitmap, MetalTypes metalType)
        {
            byte[] swaps = GetMetalColors(metalType);

            int rowPos;

            for (int y = 0; y < srcBitmap.Height; y++)
            {
                rowPos = y * srcBitmap.Width;
                for (int x = 0; x < srcBitmap.Width; x++)
                {
                    byte index = srcBitmap.Data[rowPos + x];
                    if (index >= 0x70 && index <= 0x7f)
                    {
                        int offset = index - 0x70;
                        srcBitmap.Data[rowPos + x] = swaps[offset];
                    }
                }
            }
        }
        /// <summary>
        /// Converts a DaggerfallUnity metal type to dye colour.
        /// </summary>
        public static DyeColors GetMetalDyeColor(MetalTypes metalType)
        {
            switch (metalType)
            {
            case MetalTypes.Iron:
                return(DyeColors.Iron);

            case MetalTypes.Steel:
                return(DyeColors.Steel);

            case MetalTypes.Silver:
                return(DyeColors.Silver);

            case MetalTypes.Elven:
                return(DyeColors.Elven);

            case MetalTypes.Dwarven:
                return(DyeColors.Dwarven);

            case MetalTypes.Mithril:
                return(DyeColors.Mithril);

            case MetalTypes.Adamantium:
                return(DyeColors.Adamantium);

            case MetalTypes.Ebony:
                return(DyeColors.Ebony);

            case MetalTypes.Orcish:
                return(DyeColors.Orcish);

            case MetalTypes.Daedric:
                return(DyeColors.Daedric);

            default:
                return(DyeColors.Unchanged);
            }
        }
示例#9
0
 /// <summary>
 /// Search for image on disk to replace .CIFs and .RCIs. for a specific metalType
 /// (filename_record-frame_metalType.png, for example 'WEAPON04.CIF_0-0_Iron.Png').
 /// </summary>
 /// <param name="filename">Name of image.</param>
 /// <param name="record">Record index.</param>
 /// <param name="frame">Frame index. It's different than zero only for weapon animations (WEAPONXX.CIF) </param>
 /// <returns>True if generic or specific image exists.</returns>
 static public bool CustomCifExist(string filename, int record, int frame, MetalTypes metalType)
 {
     return(TextureFileExist(cifRciPath, GetNameCifRci(filename, record, frame, metalType)));
 }
示例#10
0
 /// <summary>
 /// Seek CifRci with a specific metaltype from modding locations.
 /// </summary>
 /// <param name="name">Image name.</param>
 /// <param name="record">Record index.</param>
 /// <param name="frame">Animation frame index</param>
 /// <param name="metalType">Metal type.</param>
 /// <param name="tex">Imported image as texture.</param>
 /// <returns>True if CifRci imported.</returns>
 public static bool TryImportCifRci(string name, int record, int frame, MetalTypes metalType, out Texture2D tex)
 {
     return(TryImportTexture(cifRciPath, GetNameCifRci(name, record, frame, metalType), out tex));
 }
示例#11
0
 /// <summary>
 /// Import image from disk to replace .CIFs and .RCIs. for a specific metalType
 /// (filename_record-frame_metalType.png', for example 'WEAPON04.CIF_0-0_Iron.Png').
 /// </summary>
 /// <param name="filename">Name of image.</param>
 /// <param name="record">Record index.</param>
 /// <param name="frame">Frame index. It's different than zero only for weapon animations (WEAPONXX.CIF) </param>
 /// <returns>Image for this metalType or generic image if metalType is None.</returns>
 static public Texture2D LoadCustomCif(string filename, int record, int frame, MetalTypes metalType)
 {
     return(ImportTextureFile(cifRciPath, GetNameCifRci(filename, record, frame, metalType)));
 }
示例#12
0
        private Texture2D GetWeaponTextureAtlas(
            string filename,
            MetalTypes metalType,
            out Rect[] rectsOut,
            out RecordIndex[] indicesOut,
            int padding,
            int border,
            bool dilate = false)
        {
            // Load texture file
            cifFile.Load(Path.Combine(dfUnity.Arena2Path, filename), FileUsage.UseMemory, true);

            // Read every image in archive
            Rect rect;
            List<Texture2D> textures = new List<Texture2D>();
            List<RecordIndex> indices = new List<RecordIndex>();
            for (int record = 0; record < cifFile.RecordCount; record++)
            {
                int frames = cifFile.GetFrameCount(record);
                DFSize size = cifFile.GetSize(record);
                RecordIndex ri = new RecordIndex()
                {
                    startIndex = textures.Count,
                    frameCount = frames,
                    width = size.Width,
                    height = size.Height,
                };
                indices.Add(ri);
                for (int frame = 0; frame < frames; frame++)
                {
                    textures.Add(GetWeaponTexture2D(filename, record, frame, metalType, out rect, border, dilate));
                }
            }

            // Pack textures into atlas
            Texture2D atlas = new Texture2D(2048, 2048, TextureFormat.RGBA32, false);
            rectsOut = atlas.PackTextures(textures.ToArray(), padding, 2048);
            indicesOut = indices.ToArray();

            // Shrink UV rect to compensate for internal border
            float ru = 1f / atlas.width;
            float rv = 1f / atlas.height;
            for (int i = 0; i < rectsOut.Length; i++)
            {
                Rect rct = rectsOut[i];
                rct.xMin += border * ru;
                rct.xMax -= border * ru;
                rct.yMin += border * rv;
                rct.yMax -= border * rv;
                rectsOut[i] = rct;
            }

            return atlas;
        }
示例#13
0
        private void LoadWeaponAtlas()
        {
            // Get weapon filename
            string filename = WeaponBasics.GetWeaponFilename(WeaponType);

            // Load the weapon texture atlas
            // Texture is dilated into a transparent coloured border to remove dark edges when filtered
            // Important to use returned UV rects when drawing to get right dimensions
            weaponAtlas = GetWeaponTextureAtlas(filename, MetalType, out weaponRects, out weaponIndices, 2, 2, true);
            weaponAtlas.filterMode = dfUnity.MaterialReader.MainFilterMode;

            // Get weapon anims
            weaponAnims = (WeaponAnimation[])WeaponBasics.GetWeaponAnims(WeaponType).Clone();

            // Store current weapon
            lastWeaponType = WeaponType;
            lastMetalType = MetalType;
        }
示例#14
0
        private Texture2D GetWeaponTexture2D(
            string filename,
            int record,
            int frame,
            MetalTypes metalType,
            out Rect rectOut,
            int border = 0,
            bool dilate = false)
        {
            // Get source bitmap
            DFBitmap dfBitmap = cifFile.GetDFBitmap(record, frame);

            // Tint based on metal type
            // But not for steel as that is default colour in files
            if (metalType != MetalTypes.Steel)
                ImageProcessing.TintWeaponImage(dfBitmap, metalType);

            // Get Color32 array
            DFSize sz;
            Color32[] colors = cifFile.GetColor32(dfBitmap, 0, border, out sz);

            // Dilate edges
            if (border > 0 && dilate)
                ImageProcessing.DilateColors(ref colors, sz);

            // Create Texture2D
            Texture2D texture = new Texture2D(sz.Width, sz.Height, TextureFormat.RGBA32, false);
            texture.SetPixels32(colors);
            texture.Apply(true);

            // Shrink UV rect to compensate for internal border
            float ru = 1f / sz.Width;
            float rv = 1f / sz.Height;
            rectOut = new Rect(border * ru, border * rv, (sz.Width - border * 2) * ru, (sz.Height - border * 2) * rv);

            return texture;
        }
 /// <summary>
 /// Converts a DaggerfallUnity metal type to dye colour.
 /// </summary>
 public static DyeColors GetMetalDyeColor(MetalTypes metalType)
 {
     switch(metalType)
     {
         case MetalTypes.Iron:
             return DyeColors.Iron;
         case MetalTypes.Steel:
             return DyeColors.Steel;
         case MetalTypes.Chain:
         case MetalTypes.Silver:
         case MetalTypes.Elven:
             return DyeColors.SilverOrElven;
         case MetalTypes.Dwarven:
             return DyeColors.Dwarven;
         case MetalTypes.Mithril:
             return DyeColors.Mithril;
         case MetalTypes.Adamantium:
             return DyeColors.Adamantium;
         case MetalTypes.Ebony:
             return DyeColors.Ebony;
         case MetalTypes.Orcish:
             return DyeColors.Orcish;
         case MetalTypes.Daedric:
             return DyeColors.Daedric;
         default:
             return DyeColors.Unchanged;
     }
 }
        /// <summary>
        /// Tint a weapon image based on metal type.
        /// </summary>
        /// <param name="srcBitmap">Source weapon image.</param>
        /// <param name="size">Image size.</param>
        /// <param name="metalType">Metal type for tint.</param>
        public static void TintWeaponImage(DFBitmap srcBitmap, MetalTypes metalType)
        {
            // Must be indexed format
            if (srcBitmap.Format != DFBitmap.Formats.Indexed)
                return;

            byte[] swaps = GetMetalColors(metalType);

            int rowPos;
            for (int y = 0; y < srcBitmap.Height; y++)
            {
                rowPos = y * srcBitmap.Width;
                for (int x = 0; x < srcBitmap.Width; x++)
                {
                    byte index = srcBitmap.Data[rowPos + x];
                    if (index >= 0x70 && index <= 0x7f)
                    {
                        int offset = index - 0x70;
                        srcBitmap.Data[rowPos + x] = swaps[offset];
                    }
                }
            }
        }
        // Gets colour indices based on metal type
        public static byte[] GetMetalColors(MetalTypes metalType)
        {
            byte[] indices;
            switch (metalType)
            {
                case MetalTypes.Iron:
                    indices = new byte[] { 0x77, 0x78, 0x57, 0x79, 0x58, 0x59, 0x7A, 0x5A, 0x7B, 0x5B, 0x7C, 0x5C, 0x7D, 0x5D, 0x5E, 0x5F };
                    break;
                case MetalTypes.Steel:
                    indices = new byte[] { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F };
                    break;
                case MetalTypes.Silver:
                    indices = new byte[] { 0xE0, 0x70, 0x50, 0x71, 0x51, 0x72, 0x73, 0x52, 0x74, 0x53, 0x75, 0x54, 0x55, 0x56, 0x57, 0x58 };
                    break;
                case MetalTypes.Elven:
                    indices = new byte[] { 0xE0, 0x70, 0x50, 0x71, 0x51, 0x72, 0x73, 0x52, 0x74, 0x53, 0x75, 0x54, 0x55, 0x56, 0x57, 0x58 };
                    break;
                case MetalTypes.Dwarven:
                    indices = new byte[] { 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F };
                    break;
                case MetalTypes.Mithril:
                    indices = new byte[] { 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE };
                    break;
                case MetalTypes.Adamantium:
                    indices = new byte[] { 0x5A, 0x5B, 0x7C, 0x5C, 0x7D, 0x5D, 0x7E, 0x5E, 0x7F, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE };
                    break;
                case MetalTypes.Ebony:
                    indices = new byte[] { 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE };
                    break;
                case MetalTypes.Orcish:
                    indices = new byte[] { 0xA2, 0xA3, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD };
                    break;
                case MetalTypes.Daedric:
                    indices = new byte[] { 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE };
                    break;
                default:
                    indices = new byte[] { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F };
                    break;
            }

            return indices;
        }
示例#18
0
        private Texture2D GetWeaponTextureAtlas(
            string filename,
            MetalTypes metalType,
            out Rect[] rectsOut,
            out RecordIndex[] indicesOut,
            int padding,
            int border,
            bool dilate = false)
        {
            // Load texture file
            cifFile.Load(Path.Combine(dfUnity.Arena2Path, filename), FileUsage.UseMemory, true);

            // Read every image in archive
            Rect               rect;
            List <Texture2D>   textures = new List <Texture2D>();
            List <RecordIndex> indices  = new List <RecordIndex>();

            CustomTextures = new Dictionary <string, Texture2D>();
            for (int record = 0; record < cifFile.RecordCount; record++)
            {
                int         frames = cifFile.GetFrameCount(record);
                DFSize      size   = cifFile.GetSize(record);
                RecordIndex ri     = new RecordIndex()
                {
                    startIndex = textures.Count,
                    frameCount = frames,
                    width      = size.Width,
                    height     = size.Height,
                };
                indices.Add(ri);
                for (int frame = 0; frame < frames; frame++)
                {
                    textures.Add(GetWeaponTexture2D(filename, record, frame, metalType, out rect, border, dilate));

                    Texture2D tex;
                    if (TextureReplacement.TryImportCifRci(filename, record, frame, metalType, out tex))
                    {
                        tex.filterMode = (FilterMode)DaggerfallUnity.Settings.MainFilterMode;
                        CustomTextures.Add(record + "-" + frame, tex);
                    }

                    //// Import custom texture
                    //if (TextureReplacement.CustomCifExist(filename, record, frame, metalType))
                    //{
                    //    Texture2D tex = TextureReplacement.LoadCustomCif(filename, record, frame, metalType);
                    //    tex.filterMode = (FilterMode)DaggerfallUnity.Settings.MainFilterMode;
                    //    CustomTextures.Add(record + "-" + frame, tex);
                    //}
                }
            }

            // Pack textures into atlas
            Texture2D atlas = new Texture2D(2048, 2048, TextureFormat.ARGB32, false);

            rectsOut   = atlas.PackTextures(textures.ToArray(), padding, 2048);
            indicesOut = indices.ToArray();

            // Shrink UV rect to compensate for internal border
            float ru = 1f / atlas.width;
            float rv = 1f / atlas.height;

            for (int i = 0; i < rectsOut.Length; i++)
            {
                Rect rct = rectsOut[i];
                rct.xMin   += border * ru;
                rct.xMax   -= border * ru;
                rct.yMin   += border * rv;
                rct.yMax   -= border * rv;
                rectsOut[i] = rct;
            }

            return(atlas);
        }