/// <summary> /// Get a FacetSector given an ID. FacetSector contains tile information about current block. /// UOPs related. /// </summary> /// <param name="sector"></param> /// <returns></returns> public static FacetSector getSector(int sector) { //Fast search if (facetSectors.ContainsKey(sector)) { return(facetSectors[sector]); } int currentFacet = 0; //Look for the file in facet hashes string toHash = string.Format("build/sectors/facet_{0:D2}/{1:D8}.bin", currentFacet, sector); ulong hash = HashDictionary.HashFileName(toHash); if (!UOResourceManager.uopHashes.facet0Hashes.ContainsKey(hash)) { UOConsole.Fatal("Cannot find {0} in facet0Hashes", toHash); return(null); } UOResourceManager.uopMapping_t map = UOResourceManager.uopHashes.facet0Hashes[hash]; MythicPackage _uop = new MythicPackage(fileDirectory + "facet0.uop"); byte[] raw = _uop.Blocks[map.block].Files[map.file].Unpack(_uop.FileInfo.FullName); FacetSector fs; using (MemoryStream ms = new MemoryStream(raw)){ using (BinaryReader r = new BinaryReader(ms)) { fs = FacetSector.readSector(r); } } facetSectors[sector] = fs; return(fs); }
//Get a resource given an id // the id is coming from TILEART -> TEXTURES // or TERRAINDEF -> TEXTURES public static UOResource getResource(Tileart tileart) { UOResource resource = null; //WorldArt Texture if (tileart.textures[0].texturePresent == 1) { resource = getResource(tileart.textures[0].texturesArray[0], ShaderTypes.Sprite); } //LegacyTexture if (resource == null && tileart.textures[1].texturePresent == 1) { resource = getLegacyResource(tileart.textures[1].texturesArray[0]); } //EnhancedTexture //Is this really necessary? //Light Texture if (resource != null && tileart.textures[3].texturePresent == 1) { //TODO: light texture load } // if (resource == null) { UOConsole.Fatal("texture is not present {0}", tileart.id); tileart = UOResourceManager.getTileart(1); resource = getResource(tileart.textures[0].texturesArray[0], ShaderTypes.Sprite); } return(resource); }
public static UOResource getLegacyResource(TextureImageInfo tileartTextureInfo) { //FAST search if (legacyTextures.ContainsKey(tileartTextureInfo.textureIDX)) { //TODO: references++ return(legacyTextures[tileartTextureInfo.textureIDX]); } //Get the string from stringDictionary if (tileartTextureInfo.textureIDX >= stringDictionary.count) { UOConsole.Fatal("String {0} not found in dictionary.", tileartTextureInfo.textureIDX); return(null); } string tga = stringDictionary.values[tileartTextureInfo.textureIDX]; //Replace extension int start = (tga.LastIndexOf("\\") == -1) ? 0 : (tga.LastIndexOf("\\") + 1); int end = tga.IndexOf("_"); if (end == -1) { UOConsole.Fatal("no descr in: {0} .. trying with extension", tga); tga = tga.Replace(".tga", ""); end = tga.Length; } //UOConsole.Fatal("{0} {1} {2}", tga, start, end); string toHash = tga.Substring(start, end - start); while (toHash.Length < 8) //Filling the missing zeros { toHash = "0" + toHash; } toHash += ".dds"; toHash = toHash.ToLower(); toHash = "build/tileartlegacy/" + toHash; //Get the file from Texture.uop ulong tehHash = HashDictionary.HashFileName(toHash); if (!uopHashes.legacyTexturesHashes.ContainsKey(tehHash)) { UOConsole.Fatal("string {0} not found in legacyTextureHashes - tga: {1}", toHash, tga); return(null); } uopMapping_t map = uopHashes.legacyTexturesHashes[tehHash]; MythicPackage tex = new MythicPackage(fileDirectory + "LegacyTexture.uop"); byte[] raw = tex.Blocks[map.block].Files[map.file].Unpack(tex.FileInfo.FullName); UOResource res = new UOResource(raw, ShaderTypes.Sprite, true); legacyTextures.Add(tileartTextureInfo.textureIDX, res); return(res); }
//Land tiles does not have tileart TEXTURES section.. we need to extract them from terrain definition public static TextureImageInfo getLandtileTextureID(uint legacyLandtileID) { //Fast search if (landtiles.ContainsKey(legacyLandtileID)) { return(landtiles[legacyLandtileID]); } //Translate the legacy ID to the new pair newID-subtype using legacyterrainMap if (!legacyTerrainMap.ContainsKey(legacyLandtileID)) { UOConsole.Fatal("Cannot find {0} in legacyTerrainMap", legacyLandtileID); return(null); } legacyTerrainMap_t landtileID = legacyTerrainMap[legacyLandtileID]; //Get the file from terrain definition using the newID ulong hash = HashDictionary.HashFileName(string.Format("build/terraindefinition/{0}.bin", landtileID.newID)); if (!uopHashes.terrainHashes.ContainsKey(hash)) { UOConsole.Fatal("Cannot find {0} in terrainHashes", landtileID.newID); return(null); } uopMapping_t pos = uopHashes.terrainHashes[hash]; MythicPackage _uop = new MythicPackage(fileDirectory + "TerrainDefinition.uop"); byte[] raw = _uop.Blocks[pos.block].Files[pos.file].Unpack(_uop.FileInfo.FullName); //Read the loaded terrainDefinition file. TerrainDefinition td; using (MemoryStream ms = new MemoryStream(raw)) { using (BinaryReader r = new BinaryReader(ms)) { td = TerrainDefinition.readTerrainDefinition(r); } } if (td == null) { UOConsole.Fatal("Cannot read terrainDefinition file"); return(null); } landtiles[legacyLandtileID] = td.textures.texturesArray[landtileID.newSubtype]; //Returns the texture according to subtype return(td.textures.texturesArray[landtileID.newSubtype]); }
//Get a tileart given a graphic id public static Tileart getTileart(uint graphic) { //Fast search if (tileartCollection.ContainsKey(graphic)) { return(tileartCollection[graphic]); } //Get the file from tileart using the id ulong hash = HashDictionary.HashFileName(string.Format("build/tileart/{0:D8}.bin", graphic)); if (!uopHashes.tileartHashes.ContainsKey(hash)) { UOConsole.Fatal("Cannot find {0} in tileartHashes", graphic); return(null); } uopMapping_t pos = uopHashes.tileartHashes[hash]; MythicPackage _uop = new MythicPackage(fileDirectory + "tileart.uop"); byte[] raw = _uop.Blocks[pos.block].Files[pos.file].Unpack(_uop.FileInfo.FullName); //Read the loaded tileart file. Tileart t; using (MemoryStream ms = new MemoryStream(raw)) { using (BinaryReader r = new BinaryReader(ms)) { t = Tileart.readTileart(r); } } if (t == null) { UOConsole.Fatal("Cannot read tileart file"); return(t); } tileartCollection[graphic] = t; //Returns the texture according to subtype return(t); }
/// <summary> /// MAIN THREAD /// This function loads a sector and puts the resulting terrain mesh into a GameObject /// </summary> /// <param name="sectorID"></param> /// <returns></returns> public static GameObject buildTerrain(int sectorID) { GameObject terrain = new GameObject("terrain" + sectorID); MeshFilter mf = (MeshFilter)terrain.AddComponent(typeof(MeshFilter)); MeshRenderer mr = (MeshRenderer)terrain.AddComponent(typeof(MeshRenderer)); //MeshCollider mc = (MeshCollider)terrain.AddComponent(typeof(MeshCollider)); //Load a facet sector UOReader.FacetSector sec = UOFacetManager.getSector(sectorID); //Set the data to a mesh Mesh mesh = new Mesh(); UOFacetManager.facetSectorMesh m = UOFacetManager.buildTerrainMesh(sec); //Copy values from the specific class.... i tried using directly a mesh but didn't worked.. mesh.vertices = m.vertices; mesh.triangles = m.triangles; mesh.normals = m.normals; mesh.uv = m.uvs; int i = 0; mesh.subMeshCount = m.subMeshes.Values.Count; UOConsole.Fatal("terrain: {0} subMeshes", mesh.subMeshCount); foreach (uint k in m.subMeshes.Keys) { //UOConsole.Fatal(string.Format("idx {0} texture {1} count: {2}", i, k, m.subMeshes[k].Count)); mesh.SetTriangles(m.subMeshes[k].ToArray(), i++); } mf.mesh = mesh; mr.materials = m.materials.ToArray(); float sq = Mathf.Sqrt(2.0f); terrain.transform.Rotate(0, 0, -45.0f); terrain.transform.localScale *= 1 / sq; terrain.transform.localScale /= 1.6525f; //Moving from 100pixel based to 64pixel based return(terrain); }
/// <summary> /// MAIN THREAD /// load the already cached sprites into GameObjects. /// This function ignores not-yet loaded sprites. /// </summary> public void loadObjects(Position p) { UOReader.FacetSector fs = UOFacetManager.getSector(sectorID); int worldY = (fs.sectorID % 64) * 64; int worldX = (fs.sectorID / 64) * 64; //Check if the block does not exit yet if (statics[fs.sectorID] == null) { statics[fs.sectorID] = new GameObject(fs.sectorID.ToString() + " statics"); statics[fs.sectorID].transform.parent = theMap.transform; terrains[fs.sectorID] = buildTerrain(fs.sectorID); terrains[fs.sectorID].transform.parent = theMap.transform; } bool needsAnotherRun = false; //Wheter the SectorLoader thread has not finished yet. for (int x = 0; x < fs.tiles.Length; ++x) { for (int y = 0; y < fs.tiles[x].Length; ++y) { if (Mathf.Abs(worldX + x - p.x) > UPDATE_RANGE || Mathf.Abs(worldY + y - p.y) > UPDATE_RANGE) { needsAnotherRun = true; continue; } if (fs.tiles[x][y].staticsCount <= 0) { continue; } if (goArray[x, y] == null) { goArray[x, y] = new GameObject[fs.tiles[x][y].statics.Length]; } for (int i = 0; i < fs.tiles[x][y].statics.Length; ++i) { facetStatic_t st = fs.tiles[x][y].statics[i]; if (facetSprites.ContainsKey(st.graphic)) { if (goArray[x, y][i] == null) { UOStatic si = facetSprites[st.graphic] as UOStatic; if (si == null) { facetSprites.Remove(st.graphic); UOConsole.Fatal("UPDATE: Removing {0} cause it's null", st.graphic); } goArray[x, y][i] = si.getDrawItem(x, y, st.z, worldX, worldY); goArray[x, y][i].transform.parent = statics[fs.sectorID].transform; } //Else we already have the tile loaded! } else { //We need another run needsAnotherRun = true; } } //End statics } //End y } //End x if (!needsAnotherRun) { fullLoaded = true; UOConsole.Debug("UPDATE: Finished loading {0}", sectorID); } return; }
//Preload all hashes public static bool loadUOPs() { //Load the string dictionary data MythicPackage sd = new MythicPackage(fileDirectory + "string_dictionary.uop"); byte[] data = sd.Blocks[0].Files[0].Unpack(sd.FileInfo.FullName); using (MemoryStream fs = new MemoryStream(data)) { using (BinaryReader r = new BinaryReader(fs)) { stringDictionary.unk64 = r.ReadUInt64(); stringDictionary.count = r.ReadUInt32(); stringDictionary.unk16 = r.ReadInt16(); stringDictionary.values = new string[stringDictionary.count]; for (int i = 0; i < stringDictionary.count; ++i) { ushort len = r.ReadUInt16(); byte[] datas = r.ReadBytes(len); stringDictionary.values[i] = UTF8Encoding.ASCII.GetString(datas); } } } //Load the map conversion between new ids and legacy ones using (FileStream fs = new FileStream(fileDirectory + "legacyterrainmap.csv", FileMode.Open)) { using (StreamReader r = new StreamReader(fs)) { string line = r.ReadLine(); //legacy newid newsub while (true) { line = r.ReadLine(); if (line == null) { break; } string[] values = line.Split(','); if (values.Length != 3) { UOConsole.Fatal("cannot read legacyterrainmap.csv"); return(false); } legacyTerrainMap[uint.Parse(values[0])] = new legacyTerrainMap_t(uint.Parse(values[0]), uint.Parse(values[1]), uint.Parse(values[2])); } } } //Now build files dictionaries for fast searching uopHashes.tileartHashes = new Dictionary <ulong, uopMapping_t>(); uopHashes.textureHashes = new Dictionary <ulong, uopMapping_t>(); uopHashes.terrainHashes = new Dictionary <ulong, uopMapping_t>(); uopHashes.facet0Hashes = new Dictionary <ulong, uopMapping_t>(); uopHashes.legacyTexturesHashes = new Dictionary <ulong, uopMapping_t>(); MythicPackage _uop = new MythicPackage(fileDirectory + "tileart.uop"); for (int i = 0; i < _uop.Blocks.Count; ++i) { for (int j = 0; j < _uop.Blocks[i].Files.Count; ++j) { uopHashes.tileartHashes.Add(_uop.Blocks[i].Files[j].FileHash, new uopMapping_t(i, j)); } } _uop = new MythicPackage(fileDirectory + "Texture.uop"); for (int i = 0; i < _uop.Blocks.Count; ++i) { for (int j = 0; j < _uop.Blocks[i].Files.Count; ++j) { uopHashes.textureHashes.Add(_uop.Blocks[i].Files[j].FileHash, new uopMapping_t(i, j)); } } _uop = new MythicPackage(fileDirectory + "TerrainDefinition.uop"); for (int i = 0; i < _uop.Blocks.Count; ++i) { for (int j = 0; j < _uop.Blocks[i].Files.Count; ++j) { uopHashes.terrainHashes.Add(_uop.Blocks[i].Files[j].FileHash, new uopMapping_t(i, j)); } } _uop = new MythicPackage(fileDirectory + "facet0.uop"); for (int i = 0; i < _uop.Blocks.Count; ++i) { for (int j = 0; j < _uop.Blocks[i].Files.Count; ++j) { uopHashes.facet0Hashes.Add(_uop.Blocks[i].Files[j].FileHash, new uopMapping_t(i, j)); } } _uop = new MythicPackage(fileDirectory + "LegacyTexture.uop"); for (int i = 0; i < _uop.Blocks.Count; ++i) { for (int j = 0; j < _uop.Blocks[i].Files.Count; ++j) { uopHashes.legacyTexturesHashes.Add(_uop.Blocks[i].Files[j].FileHash, new uopMapping_t(i, j)); } } return(true); }