Jump to content

idok2

Member
  • Posts

    4
  • Joined

  • Last visited

  • Feedback

    0%

Posts posted by idok2

  1. On 2/7/2023 at 9:09 PM, Anohros said:

    A wild guess..

    does the map width and height match with your map?

    I refer to this part from the source:

    var mapWidth = 4;
    var mapHeight = 5;

    Width is the number of tiles in the x axis and height in y axis.

    Yes, its correct. Jinno map1 so C1, it is 4, 5.

  2. On 2/4/2023 at 11:03 PM, .InyaProduction said:
    using System;
    using System.IO;
    using Unity.Collections;
    using Unity.Jobs;
    using UnityEngine;
    
    public class MapLoaderView : MonoBehaviour
    {
        public Terrain Terrain;
    
        private const int TerrainTileSize = 131;
        private const int TerrainTileSquare = TerrainTileSize * TerrainTileSize;
        private const int SplatSize = TerrainTileSize - 2;
        private const int SplatSquare = SplatSize * SplatSize;
        // Start is called before the first frame update
        void Start()
        {
            var mapWidth = 4;
            var mapHeight = 5;
            
            float[,] data = new float[Terrain.terrainData.heightmapResolution, Terrain.terrainData.heightmapResolution];
            Terrain.terrainData.SetHeights(0, 0, data);
            
            NativeArray<int> xOffset = new NativeArray<int>(mapWidth * mapHeight, Allocator.TempJob);
            NativeArray<int> yOffset = new NativeArray<int>(mapWidth * mapHeight, Allocator.TempJob);
            NativeArray<float> jobData = new NativeArray<float>(SplatSquare * mapHeight * mapWidth, Allocator.TempJob);
            NativeArray<UInt16> mapData = new NativeArray<UInt16>(TerrainTileSquare * mapHeight * mapWidth, Allocator.TempJob);
            
            for (int tileX = 0; tileX < mapWidth; tileX++)
            for (int tileY = 0; tileY < mapHeight; tileY++)
            {
                var file = File.ReadAllBytes($"Assets/_M2/Features/Maps/Original/metin2_map_c1/00{tileX}00{tileY}/height.raw");
                var tileOffset = ((tileX * TerrainTileSquare * mapHeight) + (tileY * TerrainTileSquare));
                for (var offset = 0; offset < file.Length / 2; offset++)
                {
                    var mapDataOffset = tileOffset + offset;
                    mapData[mapDataOffset] = BitConverter.ToUInt16(file, offset * 2);
                }
                
                xOffset[tileX * mapHeight + tileY] = tileX;
                yOffset[tileX * mapHeight + tileY] = tileY;
            }
            
            TerrainJob terrainJob = new TerrainJob
            {
                xOffsetData = xOffset,
                yOffsetData = yOffset,
                data = jobData,
                mapWidth = mapWidth,
                mapHeight = mapHeight,
                mapData = mapData,
            };
            JobHandle handle = terrainJob.Schedule(mapWidth * mapHeight, 1);
            handle.Complete();
    
            for (int tileX = 0; tileX < mapWidth; tileX++)
            for (int tileY = 0; tileY < mapHeight; tileY++)
            {
                for (var pixelX = 0; pixelX < SplatSize; pixelX++)
                for (var pixelY = 0; pixelY < SplatSize; pixelY++)
                {
                    var dataOffset = ((tileX * SplatSquare * mapHeight) + (((mapHeight - 1) - tileY) * SplatSquare));
                    data[tileY * SplatSize + pixelY, tileX * SplatSize + pixelX] = terrainJob.data[dataOffset + pixelX * SplatSize + pixelY];
                }
            }
    
            Terrain.terrainData.SetHeights(0, 0, data);
    
            xOffset.Dispose();
            yOffset.Dispose();
            jobData.Dispose();
            mapData.Dispose();
    
            int size = 258;
            int[,] texData = new int[size * mapWidth, size * mapHeight];
            
            for (int tileX = 0; tileX < mapWidth; tileX++)
            for (int tileY = 0; tileY < mapHeight; tileY++)
            {
                LoadTextures($"Assets/_M2/Features/Maps/Original/metin2_map_c1/00{tileX}00{tileY}/tile.raw", tileX, (mapHeight - 1) - tileY, ref texData);
            }
            
            LoadFullTextures(texData, Terrain.terrainData, size * mapWidth, size * mapHeight);
            bool[,] holes = new bool[Terrain.terrainData.holesResolution, Terrain.terrainData.holesResolution];
            for (var pixelX = 0; pixelX < Terrain.terrainData.holesResolution; pixelX++)
            for (var pixelY = 0; pixelY < Terrain.terrainData.holesResolution; pixelY++)
            {
                var solid = pixelX + 1 < mapHeight * SplatSize && pixelY + 1 < mapWidth * SplatSize;
                holes[pixelX, pixelY] = solid;
            }
            Terrain.terrainData.SetHoles(0, 0, holes);
        }
    
        public struct TerrainJob : IJobParallelFor
        {
            [NativeDisableParallelForRestriction]
            public NativeArray<float> data;
            [ReadOnly]
            public NativeArray<int> xOffsetData;
            [ReadOnly]
            public NativeArray<int> yOffsetData;
            [ReadOnly] 
            public NativeArray<UInt16> mapData;
            [ReadOnly]
            public int mapWidth;
            [ReadOnly]
            public int mapHeight;
            
            public void Execute(int i)
            {
                var xShift = xOffsetData[i];
                var yShift = yOffsetData[i];
    
                var dataOffset = ((xShift * TerrainTileSquare * mapHeight) + (yShift * TerrainTileSquare));
    
                var targetDataOffset = ((xShift * SplatSquare * mapHeight) + (yShift * SplatSquare));
                
                for (int pixelY = 0; pixelY < TerrainTileSize; pixelY++)
                {
                    for (int pixelX = 0; pixelX < TerrainTileSize; pixelX++)
                    {
                        float v = (float)mapData[dataOffset + (pixelX * TerrainTileSize) + pixelY] / 0xFFFF;
                        if (pixelX >= 1 && pixelY >= 1 && pixelX <= SplatSize && pixelY <= SplatSize)
                        {
                            var realY = pixelY - 1;
                            var realX = pixelX - 1;
                            data[targetDataOffset + realY * SplatSize + ((SplatSize - 1) - realX)] = v;
                        }
                    }
                }
            }
        }
        
        public struct Native2DArray<T> : System.IDisposable where T: struct
        {
            private int sizeX;
            private int sizeY;
            private NativeArray<T> flatArray;
            
            public Native2DArray(int sizeX, int sizeY, Allocator allocator)
            {
                this.sizeX = sizeX;
                this.sizeY = sizeY;
                flatArray = new NativeArray<T>(sizeX * sizeY, allocator);
            }
     
            public T this[int x, int y]
            {
                get { return flatArray[x + y * sizeX]; }
                set { flatArray[x + y * sizeX] = value; }
            }
     
            public void Dispose()
            {
                flatArray.Dispose();
            }
    
            public int Length => this.sizeX * this.sizeY;
        }
    
        void LoadTerrain(string aFileName, TerrainData aTerrain, int shiftX, int shiftY)
        {
            int size = 131;
            
            float[,] data = new float[size - 2, size - 2];
            using (var file = System.IO.File.OpenRead(aFileName))
            using (var reader = new System.IO.BinaryReader(file))
            {
                for (int y = size - 1; y >= 0; y--)
                {
                    for (int x = 0; x < size; x++)
                    {
                        float v = (float)reader.ReadUInt16() / 0xFFFF;
                        if (x >= 1 && y >= 1 && x <= size - 2 && y <= size - 2)
                        {
                            data[y - 1, x - 1] = v;
                        }
                    }
                }
            }
        }
    
        void LoadTextures(string tileFileName, int shiftX, int shiftY, ref int[,] fullTexData)
        {
            int size = 258;
    
            using (var texFile = System.IO.File.OpenRead(tileFileName))
            using (var texReader = new System.IO.BinaryReader(texFile))
            {
                for (int y = size - 1; y >= 0; y--)
                {
                    for (int x = 0; x < size; x++)
                    {
                        int tex = texReader.ReadByte();
                        fullTexData[size * shiftX + x, size * shiftY + y] = tex - 1;
                    }
                }
            }
        }
        
        void LoadFullTextures(int[,] fullTexData, TerrainData aTerrain, int width, int height)
        {
            float[,,] texData = aTerrain.GetAlphamaps(0, 0, width, height);
            {
                for (int y = height - 1; y >= 0; y--)
                {
                    for (int x = 0; x < width; x++)
                    {
                        {
                            var count = 0;
                            float[] texWeights = new float[aTerrain.terrainLayers.Length];
                            // BOTTOM
                            if (x - 1 >= 0 && y - 1 >= 0)
                            {
                                count++;
                                texWeights[fullTexData[x - 1, y - 1]] += 1 / 9f;
                            }
    
                            if (y - 1 >= 0)
                            {
                                count++;
                                texWeights[fullTexData[x, y - 1]] += 1;
                            }
    
                            if (x + 1 < width && y - 1 >= 0)
                            {
                                count++;
                                texWeights[fullTexData[x + 1, y - 1]] += 1;
                            }
                            
                            // CENTER
                            if (x - 1 >= 0)
                            {
                                count++;
                                texWeights[fullTexData[x - 1, y]] += 1;
                            }
    
                            if (true)
                            {
                                count++;
                                texWeights[fullTexData[x, y]] += 1;
                            }
    
                            if (x + 1 < width)
                            {
                                count++;
                                texWeights[fullTexData[x + 1, y]] += 1;
                            }
                            
                            // TOP
                            if (x - 1 >= 0 && y + 1 < height)
                            {
                                count++;
                                texWeights[fullTexData[x - 1, y]] += 1;
                            }
    
                            if (y + 1 < height)
                            {
                                count++;
                                texWeights[fullTexData[x, y]] += 1;
                            }
    
                            if (x + 1 < width && y + 1 < height)
                            {
                                count++;
                                texWeights[fullTexData[x + 1, y]] += 1;
                            }
    
                            for (var iTex = 0; iTex < aTerrain.terrainLayers.Length; iTex++)
                            {
                                texData[y, x, iTex] = texWeights[iTex] / (float)count;
                            }
                        }
                    }
                }
            }
    
            aTerrain.SetAlphamaps(0, 0, texData);
        }
    
        bool IsBitSet(byte b, int pos)
        {
            return (b & (1 << pos)) != 0;
        }
    
        // Update is called once per frame
        void Update()
        {
        }
    }
    using Unity.Collections;
    using Unity.Collections.LowLevel.Unsafe;
    
    public static class NativeArrayExtension
    {
        public static byte[] ToRawBytes<T>(this NativeArray<T> arr) where T : struct
        {
            var slice = new NativeSlice<T>(arr).SliceConvert<byte>();
            var bytes = new byte[slice.Length];
            slice.CopyTo(bytes);
            return bytes;
        }
    
        public static void CopyFromRawBytes<T>(this NativeArray<T> arr, byte[] bytes) where T : struct
        {
            var byteArr = new NativeArray<byte>(bytes, Allocator.Temp);
            var slice = new NativeSlice<byte>(byteArr).SliceConvert<T>();
    
            UnityEngine.Debug.Assert(arr.Length == slice.Length);
            slice.CopyTo(arr);
        }
    
        public static NativeArray<T> FromRawBytes<T>(byte[] bytes, Allocator allocator) where T : struct
        {
            int structSize = UnsafeUtility.SizeOf<T>();
    
            UnityEngine.Debug.Assert(bytes.Length % structSize == 0);
    
            int length = bytes.Length / UnsafeUtility.SizeOf<T>();
            var arr = new NativeArray<T>(length, allocator);
            arr.CopyFromRawBytes(bytes);
            return arr;
        }
    }

    This would be the map loader I have used

    OMG! Thank you a lot. I am just getting started so i sorry, but i have 2 errors. 

    https://metin2.download/picture/RgYGUN28Xh9l3QoY12ysqxyRlG6uVigA/.png

    Before you asking, no i don't want to develop a game like metin 2 without knowledge. I just want to learn Unity this way. I just want to play around with things 😄 . And i like messing around with Metin2 things.

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.