-
Posts
511 -
Joined
-
Last visited
-
Days Won
10 -
Feedback
0%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by .InyaProduction
-
-
On 1/26/2023 at 1:55 PM, idok2 said:
My question is, how did u import the map? I want it too sooo soo badly
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
- 1
- 1
-
On 2/13/2022 at 8:00 PM, Anohros said:
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
- 2
- 1
- 2
- 3
-
On 2/8/2022 at 4:03 PM, ranvids said:
Gr2 file contain a uv mapped mesh, group of vertices, materials, animations, skeletons, custom normals, multiple uv channels mesh and such.
I ended up using Noesis exporter along with a python plugin ( fmt_GR2reader135.py ) and granny.dll , which export everything, included skeletons. I just hoped for the same features but packaged in an handy .exe file .... like your software
Was that gr2 file from metin2? Does not sound like it
-
3 hours ago, ranvids said:
Hey thank you for your efforts. I dont know why , but it doesnt work on my side. I dragged on it a gr2 file and from cmd i clearly see it says exported successfully but i dont have any fbx file in the same folder. What could be happening? Thank you!
What contents are in the gr2 file?
-
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: https://metin2.download/video/i9E288Uehmx50MyL4qkT9fzWzAbpDxJX/.mp4
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:
Download
- 219
- 14
- 3
- 2
- 1
- 3
- 1
- 5
- 3
- 2
- 94
- 19
- 155
-
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)
- 2
-
59 minutes ago, ToXiC4000 said:
It was asked for the file from this post, so I delivered it
- 4
-
-
Whats your GPU?
-
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
-
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 startListener2: 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
-
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
-
Help.
i have the same error
Edit the plugins.ini. It contains a path you need to adjust
-
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
-
They are adding some, hmm, i dont know how to name it decently
I think it is good to do this, because now a no-IS players could have a pet (Wepen-boxes spend so much Yangs^^) so now you can drop your own pet. But questions are -#1 - How it will work?
#2 - Drop chances? (I think there will be something in IS wich could make your chances to drop it higher, and not only thief gloves..)
#3 - Abilities which will pets give you (their values), if they are useful or not... like +3% HP, who cares about 3%?!!!
And more....
High level players have 15k hp.. 3% is 450 which is more than enough. And i really dont think it will be only 3%
-
The granny viewer does not support this. You will only see that ingame.
For transparency you need the opacity map in 3ds max
-
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
-
here you can get 3ds max 7 with all exporters you need
-
Show us your localeInfo.py line 120 - 150
-
Guys it's a p2p command. He didn't set up a firewall and that's the point behind that.
Set up a firewall and block those p2p ports (and db cache port) and you'll be safe from this attack
adminpage_ip: 127.0.0.1
This should also work for you.
Note:
The attack can be from p2p ports and from normal ports. Against normal ports, you can use adminpage_ip to bind your API to localhost, so it'll only accept connections from localhost!
Against p2p ports it's more difficult. You need to shut down access to them via firewall. That's gonna fix your problem and the attack you're getting there is through the p2p ports. So you may look at that
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
-
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)
-
What budget do you have? 10-20€ per month?
-
What do you expect from this server?
Do you want us to adjust drops, gold and so on? Or just something to play on?
-
There is no gr2 plugin for 3ds max 2016. Use 2012
- 1
Metin2 map to unity3d
in Community Support - Questions & Answers
Posted
This code has some bugs if I remember correctly but it is a good baseline
You can see the result here: https://metin2.download/video/i9E288Uehmx50MyL4qkT9fzWzAbpDxJX/.mp4