Jump to content

.InyaProduction

Former Staff
  • Posts

    511
  • Joined

  • Last visited

  • Days Won

    10
  • Feedback

    0%

Everything posted by .InyaProduction

  1. This code has some bugs if I remember correctly but it is a good baseline You can see the result here: [Hidden Content]
  2. 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
  3. By the way, one thing I changed: you should change the DeviL convert from PNG to PNGA so it also converts the alpha channel of the DDS files
  4. Was that gr2 file from metin2? Does not sound like it
  5. Download Metin2 Download Hey, I will keep this short and simple. I had been playing around in the last days with exporting GR2 to a format that you can use in other software. Everything I found did not include skeleton / animation export. You can do stuff like this with it: [Hidden Content] Usage: Just drag and drop all gr2 files you want to export as an fbx file. Keep follwing in mind: Animations need a skeleton, always include one, if you are after the animation just put the lvl 1 armor of the class or the base model of the monster into it If you are selecting multiple files to drag on it select them with CTRL and select the file with the skeleton last This was basically created as POC, no fancy quality of life here Trees and collision files are not supported If you put the Textures to the correct D:\ymir work path they will be converted to PNG and put into the working folder too Credit for the base library that does most of the heavy lifting goes to: [Hidden Content] Download [Hidden Content]
  6. Just a warning to those who really value their discord Account, this is seen as a User Bot, which is forbidden by discord and you will get you banned if you are out of luck (unless you are using a bot, which needs to be invited by the server owner)
  7. It was asked for the file from this post, so I delivered it
  8. Which link is dead in here? Edit: [Hidden Content] here is 3ds max + the importer of which the link is missing
  9. If you're interested, i sell this system The first Version of it was created 18 days after source release (so far before Metin2 announced the system) and has improved a lot since then
  10. I dont know if you can push maps to python, but i did it this way when i needed it: 1: Say python a new map is incoming, i named that one startListener 2: Give datasets one by one to python by Py_* commands and fill a new array you created / flushed in startListener with the data 3: Say python your have no more data, i named that one stopListener and execute whatever you want with the array I don't have access to my source code right now. Sorry for just discribing it without code examples
  11. That case sounds like the auth core is started but the game core is not up. You will get connection to the auth (saying wrong pw) and if you enter the right password it tries to connect you to the gamecore.. which (if its not up) will return no connection
  12. i have the same error Edit the plugins.ini. It contains a path you need to adjust
  13. You should be carefull with the pivot when you dont have a test client. It will require to be a little bit up right when you view from a top view. Else the weapon will be on the hands back
  14. High level players have 15k hp.. 3% is 450 which is more than enough. And i really dont think it will be only 3%
  15. The granny viewer does not support this. You will only see that ingame. For transparency you need the opacity map in 3ds max
  16. First of all.. you try to define a function in a function? Is that even working? Secondly: your function call doesnt contain a parameter you need to call "return f(VAR)" here I would be much easier to understand what that means if you would explain us what you try to do
  17. here you can get 3ds max 7 with all exporters you need
  18. ​admin page ip and password are can block everything that can affect the server except the player count api and some log related stuff. But i think youre right with the db cache port. If this ones open one of the worst "hacks" (not further discribed here cause of possible chaos) is possible
  19. adminpage_ip: your ip-address adminpage_password: your password Put this to the config of all your game core (not db, not auth) (your ip = the ip of your website, password = you choose what you want)
  20. What do you expect from this server? Do you want us to adjust drops, gold and so on? Or just something to play on?
  21. There is no gr2 plugin for 3ds max 2016. Use 2012
×
×
  • 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.