Пример #1
0
        public TerrainAlphaMap FindTerrainAlpha(uint pcode, uint tcode, out LandDefs.Rotation rot, out int alphaIdx)
        {
            List <TerrainAlphaMap> terrainMaps = null;
            var baseIdx = 0;

            // corner tcodes - sw / se / ne / nw
            if (tcode != 1 && tcode != 2 && tcode != 4 && tcode != 8)
            {
                baseIdx     = 4;
                terrainMaps = SideTerrainMaps;   // common tcode: 9
            }
            else
            {
                terrainMaps = CornerTerrainMaps; // common tcode: 8
            }
            var numTerrains = terrainMaps.Count;

            var prng = (int)Math.Floor((1379576222 * pcode - 1372186442) * 2.3283064e-10 * numTerrains);

            if (prng >= numTerrains)
            {
                prng = 0;
            }

            var alpha = terrainMaps[prng];

            alphaIdx = baseIdx + prng;

            rot = LandDefs.Rotation.Rot0;

            var i         = 0;
            var alphaCode = alpha.TCode;

            while (alphaCode != tcode)
            {
                // corners: 8 -> 1 -> 2 -> 4
                // sides: 9 -> 3 -> 6 -> 12
                // west / south / east / north?
                alphaCode *= 2;
                if (alphaCode >= 16)
                {
                    alphaCode -= 15;
                }
                if (++i >= 4)
                {
                    return(null);
                }
            }
            rot = (LandDefs.Rotation)i;

            if (alpha.Texture == null && alpha.TexGID != 0)
            {
                var qdid = new QualifiedDataID(11, alpha.TexGID);
                alpha.Texture = new ImgTex(DBObj.GetSurfaceTexture(alpha.TexGID));
            }
            return(alpha);
        }
Пример #2
0
        public uint SelectRot(int x, int y, ref LandDefs.Rotation rot, List <uint> palCode, int size, uint palID, ref int rIndex, bool minimizePal)
        {
            var first_tnum = (ulong)(1813693831 * y - x * (1647165151 * y + 1109124029) - 2031889191)
                             * 2.3283064e-10 * LandTex.Count;
            var tnum     = first_tnum;
            var cur_tnum = first_tnum;

            LandDefs.Rotation curRot;

            var jmp = false;

            do
            {
                while (true)
                {
                    CurTex = (int)first_tnum;
                    if (CheckTerrain(palCode, ref palID))
                    {
                        break;
                    }

                    if (cur_tnum == first_tnum)
                    {
                        CurTex = 0;
                        rot    = LandDefs.Rotation.Rot0;
                        return(palCode[0]);
                    }
                }
                var beginRot = GetBeginRotation(x, y, palCode, minimizePal);
                curRot = beginRot;
                jmp    = false;
                while (!CheckRot(palCode[(int)curRot], ref rIndex))
                {
                    curRot = (LandDefs.Rotation)(((int)curRot + 1) & 3);
                    if (curRot == beginRot)
                    {
                        // y
                        tnum     = (tnum + 1) % (ulong)LandTex.Count;
                        cur_tnum = tnum;
                        if (cur_tnum == first_tnum)
                        {
                            CurTex = 0;
                            rot    = LandDefs.Rotation.Rot0;
                            return(palCode[0]);
                        }
                        jmp = true;
                        break;
                    }
                }
            }while (jmp);

            rot = curRot;
            return(palCode[(int)curRot]);
        }
Пример #3
0
        public bool SelectTerrain(int x, int y, ref uint surfNum, ref LandDefs.Rotation rot, List <uint> palCodes, int size, bool minimizePal)
        {
            var palIDs = new List <uint>();   // ??

            if (PalShift == null && TexMerge == null)
            {
                return(false);
            }

            if (PalShift != null)
            {
                var rotIdx          = (int)rot;
                var selectRotResult = PalShift.SelectRot(x, y, ref rot, palCodes, size, palIDs[0] /* fixme */, ref rotIdx /* verify */, minimizePal);
                if (SurfInfo.TryGetValue(selectRotResult, out var surfInfo))
                {
                    surfInfo.LCellCount++;
                    surfNum = surfInfo.SurfNum;
                    return(true);
                }
                else
                {
                    // PalShift.MakeNewSurface()
                    // return AddNewSurface()
                    return(false);
                }
            }

            if (TexMerge != null)
            {
                var palCode = palCodes[0];
                rot = LandDefs.Rotation.Rot0;

                if (SurfInfo.TryGetValue(palCode, out var surfInfo))
                {
                    surfInfo.LCellCount++;
                    surfNum = surfInfo.SurfNum;
                    return(true);
                }
                else
                {
                    var surface = TexMerge.MakeNewSurface(palCode, size);
                    return(AddNewSurface(surface, palCode, ref surfNum));
                }
            }

            return(false);
        }
Пример #4
0
        public RoadAlphaMap FindRoadAlpha(uint pcode, uint rcode, out LandDefs.Rotation rot, out int alphaIdx)
        {
            rot      = LandDefs.Rotation.Rot0;
            alphaIdx = -1;

            var numRoadMaps = RoadMaps.Count;

            if (numRoadMaps == 0)
            {
                return(null);
            }

            var prng = (int)Math.Floor((1379576222 * pcode - 1372186442) * 2.3283064e-10 * numRoadMaps);

            for (var i = 0; i < numRoadMaps; i++)
            {
                var idx   = (i + prng) % numRoadMaps;
                var alpha = RoadMaps[idx];
                rot = LandDefs.Rotation.Rot0;
                var alphaCode = alpha.RCode;
                alphaIdx = 5 + idx;

                for (var j = 0; j < 4; j++)
                {
                    if (alphaCode == rcode)
                    {
                        rot = (LandDefs.Rotation)j;
                        if (alpha.Texture == null && alpha.RoadTexGID != 0)
                        {
                            alpha.Texture = new ImgTex(DBObj.GetSurfaceTexture(alpha.RoadTexGID));
                        }

                        return(alpha);
                    }
                    alphaCode *= 2;
                    if (alphaCode >= 16)
                    {
                        alphaCode -= 15;
                    }
                }
            }
            alphaIdx = -1;
            return(null);
        }
Пример #5
0
        public static bool Merge(byte[] data, uint texSize, ImgTex texture, LandDefs.Rotation rot, TerrainTex terrainTex)
        {
            if (texture == null)
            {
                return(false);
            }

            var baseTexture = terrainTex.BaseTexture;

            if (baseTexture != null)
            {
                ImgTex.MergeTexture(data, texSize, texSize, baseTexture, terrainTex.TexTiling, texture, rot);
                return(true);
            }
            else if (terrainTex.InitEnd())
            {
                ImgTex.MergeTexture(data, texSize, texSize, terrainTex.BaseTexture, terrainTex.TexTiling, texture, rot);
                return(true);
            }
            return(false);
        }
Пример #6
0
        public void GetCellRotation(uint landblockID, uint x, uint y, ref bool singleTextureCell, ref uint surfNum, ref LandDefs.Rotation rotation)
        {
            var lcoord = LandDefs.blockid_to_lcoord(landblockID);

            var globalCellX = (int)(lcoord.Value.X + x);
            var globalCellY = (int)(lcoord.Value.Y + y);

            // no palette shift

            // SW / SE / NE / NW
            var i        = (int)(LandDefs.VertexDim * x + y);
            var terrain  = Terrain[i];
            var t1       = (terrain & 0x7F) >> 2;
            var r1       = terrain & 3;
            var j        = (int)(LandDefs.VertexDim * (x + 1) + y);
            var terrain2 = Terrain[j];
            var t2       = (terrain2 & 0x7F) >> 2;
            var r2       = terrain2 & 3;
            var terrain3 = Terrain[j + 1];
            var t3       = (terrain3 & 0x7F) >> 2;
            var r3       = terrain3 & 3;
            var terrain4 = Terrain[i + 1];
            var t4       = (terrain4 & 0x7F) >> 2;
            var r4       = terrain4 & 3;

            /*Console.WriteLine($"LandblockStruct.GetCellRotation({landblockID:X8}, x:{x}, y:{y})");
             * Console.WriteLine($"I1: {i}, I2: {j}, I3: {j+1}, I4: {i+1}");
             * if (r1 != 0 || r2 != 0 || r3 != 0 || r4 != 0)
             *  Console.WriteLine($"R1: {r1}, R2: {r2}, R3: {r3}, R4: {r4}");
             * Console.WriteLine($"T1: {(LandDefs.TerrainType)t1}, T2: {(LandDefs.TerrainType)t2}, T3: {(LandDefs.TerrainType)t3}, T4: {(LandDefs.TerrainType)t4}");*/

            var palCodes = new List <uint>();

            palCodes.Add(GetPalCode(r1, r2, r3, r4, t1, t2, t3, t4));   // 0
            //palCodes.Add(GetPalCode(r2, r3, r4, r1, t2, t3, t4, t1));   // 270
            //palCodes.Add(GetPalCode(r3, r4, r1, r2, t3, t4, t1, t2));   // 180
            //palCodes.Add(GetPalCode(r4, r1, r2, r3, t4, t1, t2, t3));   // 90

            var singleRoadCell = r1 == r2 && r1 == r3 && r1 == r4;
            var singleTypeCell = t1 == t2 && t1 == t3 && t1 == t4;

            singleTextureCell = r1 != 0 ? singleRoadCell : singleRoadCell && singleTypeCell;

            var regionDesc  = DatManager.PortalDat.RegionDesc;
            var minimizePal = true;

            LandSurf.Instance.SelectTerrain(globalCellX, globalCellY, ref surfNum, ref rotation, palCodes, 1, minimizePal);
        }
Пример #7
0
        public static void MergeTexture(byte[] data, uint dest_height, uint dest_width, ImgTex csi_merge_tex, uint tiling, ImgTex alphaMap, LandDefs.Rotation rot)
        {
            var imageData = csi_merge_tex.ImageData;

            var src_height = imageData != null ? imageData.Height : 0;
            var src_width  = imageData != null ? imageData.Width : 0;

            var alphaData    = alphaMap.ImageData;
            var alpha_width  = alphaData != null ? alphaData.Width : 0;
            var alpha_height = alphaData != null ? alphaData.Height : 0;

            var alpha_scale = (float)dest_width / alpha_width;

            var pixelIdx = 0;
            var stepX    = 0;
            var stepY    = 0;

            switch (rot)
            {
            case LandDefs.Rotation.Rot0:
                pixelIdx = 0;
                stepX    = 1;
                stepY    = src_width;
                break;

            case LandDefs.Rotation.Rot90:
                pixelIdx = src_width - 1;
                stepX    = src_width;
                stepY    = -1;
                break;

            case LandDefs.Rotation.Rot180:
                pixelIdx = src_width * src_height - 1;
                stepX    = -1;
                stepY    = -src_width;
                break;

            case LandDefs.Rotation.Rot270:
                pixelIdx = src_width * (src_height - 1);
                stepX    = -src_width;
                stepY    = -1;
                break;
            }

            // alphaStep handles upscaling / downscaling
            var alphaStep = 1.0f / alpha_scale;

            // copy csi_merge_tex into dest buffer (data)
            Array.Copy(imageData.Data, data, imageData.Data.Length);

            // start walking the alpha map
            for (var _alphaY = 0.0f; _alphaY < alpha_height; _alphaY += alphaStep)
            {
                var alphaY = (int)Math.Round(_alphaY);

                for (var _alphaX = 0.0f; _alphaX < alpha_width; _alphaX += alphaStep)
                {
                    // TODO: handle rotation
                    var alphaX = (int)Math.Round(_alphaX);

                    var idx = (alphaY * alpha_width + alphaX) * 4;
                    var a   = alphaData.Data[idx];
                    data[idx] = a;
                }
            }
        }