/// <summary> /// Load existing map /// </summary> /// <param name="buffer"></param> public void Load(byte[] buffer) { try { using (BinaryReader b = new BinaryReader(new MemoryStream(buffer))) { Sign = Encoding.Default.GetString(b.ReadBytes(16)); Version = b.ReadInt32(); #if DEBUG == false if (!SupportedVersion.Contains(Version)) { XLog.WriteLine(Levels.Error, $"Failed"); XLog.WriteLine(Levels.Error, "Incompatible version {0} is not supported or not implemented.", Version); return; } #endif var dwMapPropertiesOffset = b.ReadInt32(); var dwTerrainSegmentOffset = b.ReadInt32(); var dwPropOffset = b.ReadInt32(); var dwVectorAttrOffset = b.ReadInt32(); var dwWaterOffset = b.ReadInt32(); var dwGrassColonyOffset = (Version >= 17) ? b.ReadInt32() : 0; var dwEventAreaOffset = (Version >= 22) ? b.ReadInt32() : 0; TileCountPerSegment = b.ReadInt32(); SegmentCountPerMap = b.ReadInt32(); TileLenght = b.ReadSingle(); #region Properties MapProperties.Primary.Diffuse = new KColor(b.ReadByte(), b.ReadByte(), b.ReadByte(), 255); MapProperties.Primary.Specular = new KColor(b.ReadByte(), b.ReadByte(), b.ReadByte(), 255); MapProperties.Primary.Attenuation0 = b.ReadSingle(); MapProperties.Primary.Attenuation1 = b.ReadSingle(); MapProperties.Primary.Attenuation2 = b.ReadSingle(); MapProperties.Secondary.Diffuse = new KColor(b.ReadByte(), b.ReadByte(), b.ReadByte(), 255); MapProperties.Secondary.Specular = new KColor(b.ReadByte(), b.ReadByte(), b.ReadByte(), 255); MapProperties.Secondary.Attenuation0 = b.ReadSingle(); MapProperties.Secondary.Attenuation1 = b.ReadSingle(); MapProperties.Secondary.Attenuation2 = b.ReadSingle(); MapProperties.Sky = new KColor(b.ReadByte(), b.ReadByte(), b.ReadByte(), 255); MapProperties.Fog = new KColor(b.ReadByte(), b.ReadByte(), b.ReadByte(), 255); MapProperties.FogNear = b.ReadSingle(); MapProperties.FogFar = b.ReadSingle(); MapProperties.SkyType = b.ReadUInt32(); MapProperties.ShowTerrainInGame = b.ReadBoolean(); #endregion #region Terrain segment for (int segmentY = 0; segmentY < SegmentCountPerMap; segmentY++) { for (int segmentX = 0; segmentX < SegmentCountPerMap; segmentX++) { DwTerrainSegment[segmentX, segmentY] = new KSegment(); DwTerrainSegment[segmentX, segmentY].Version = (Version >= 16) ? b.ReadUInt32() : 0; for (int tile = 0; tile < 3; tile++) { DwTerrainSegment[segmentX, segmentY].Tile[tile] = (Version >= 16) ? b.ReadUInt16() : (ushort)0; } DwTerrainSegment[segmentX, segmentY].HsVector = new KVertex[TileCountPerSegment, TileCountPerSegment]; for (int tileY = 0; tileY < TileCountPerSegment; tileY++) { for (int tileX = 0; tileX < TileCountPerSegment; tileX++) { DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY] = new KVertex(); DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY].Height = b.ReadSingle(); for (int f = 0; f < 2; f++) { if (Version >= 16) { DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY].FillBits[f] = b.ReadUInt32(); } if (Version == 15 && f == 0) { DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY].FillBits[f] = b.ReadUInt32(); } } DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY].Attribute = (Version >= 16) ? b.ReadInt64() : 0; DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY].Color = new KTripleColor(b.ReadByte(), b.ReadByte(), b.ReadByte()); } } } } #endregion #region Prop //Escape offset prop table for (int i = 0; i < SegmentCountPerMap * SegmentCountPerMap; i++) { b.ReadInt32(); } // PROP var segment = 0; for (int segmentY = 0; segmentY < SegmentCountPerMap; segmentY++) { for (int segmentX = 0; segmentX < SegmentCountPerMap; segmentX++) { var propcount = b.ReadInt32(); for (int p = 0; p < propcount; p++) { var prop = new KProp(); /* index */ b.ReadInt32(); prop.SegmentId = segment; prop.X = b.ReadSingle(); prop.Y = b.ReadSingle(); prop.Z = b.ReadSingle(); prop.RotateX = b.ReadSingle(); prop.RotateY = b.ReadSingle(); prop.RotateZ = b.ReadSingle(); prop.ScaleX = b.ReadSingle(); prop.ScaleY = (Version >= 21) ? b.ReadSingle() : prop.ScaleX; prop.ScaleZ = (Version >= 21) ? b.ReadSingle() : prop.ScaleX; prop.PropNum = b.ReadUInt16(); prop.HeightLocked = (Version >= 21) ? b.ReadBoolean() : false; prop.LockHeight = (Version >= 21) ? b.ReadSingle() : 0.0f; prop.TextureGroup = (Version >= 21) ? b.ReadInt16() : (short)-1; DwProps.Add(prop); } if (Version >= 19) { var grassCount = b.ReadInt32(); for (int n = 0; n < grassCount; n++) { var grass = new KGrass(); grass.SegmentId = segment; grass.GrassId = b.ReadInt32(); var propCount = b.ReadInt32(); for (int i = 0; i < propCount; i++) { var prop = new KGrassProp(); prop.X = b.ReadSingle(); prop.Y = b.ReadSingle(); prop.RotateX = b.ReadSingle(); prop.RotateY = b.ReadSingle(); prop.RotateZ = b.ReadSingle(); grass.Props.Add(prop); } DwGrass.Add(grass); } } segment++; } } #endregion #region Vector attribute var polygonCount = b.ReadInt32(); for (int i = 0; i < polygonCount; i++) { var polygon = new Polygon2(); var pointNum = b.ReadInt32(); for (int p = 0; p < pointNum; p++) { var point = new K2DPosition(); point.X = b.ReadInt32(); point.Y = b.ReadInt32(); polygon.Points.Add(point); } DwVectorAttr.Add(polygon); } #endregion #region Water var waterCount = b.ReadInt32(); for (int i = 0; i < waterCount; i++) { var water = new Water(); water.PointA.X = b.ReadSingle(); water.PointA.Y = b.ReadSingle(); water.PointA.Z = b.ReadSingle(); water.PointB.X = b.ReadSingle(); water.PointB.Y = b.ReadSingle(); water.PointB.Z = b.ReadSingle(); water.Center.X = b.ReadSingle(); water.Center.Y = b.ReadSingle(); water.Center.Z = b.ReadSingle(); water.UseReflect = b.ReadInt32(); water.WaterId = b.ReadInt32(); DwWater.Add(water); } #endregion if (Version >= 17) { #region Speed grass var speedGrassCount = b.ReadInt32(); for (int i = 0; i < speedGrassCount; i++) { var speedGrass = new SpeedGrassColony(); speedGrass.GrassId = b.ReadInt32(); speedGrass.Density = b.ReadSingle(); speedGrass.Distribution = b.ReadSingle(); speedGrass.Size = b.ReadSingle(); speedGrass.HeightP = b.ReadSingle(); speedGrass.HeightM = b.ReadSingle(); speedGrass.Color = new KColor(b.ReadByte(), b.ReadByte(), b.ReadByte(), b.ReadByte()); speedGrass.ColorRatio = b.ReadSingle(); speedGrass.ColorTone = b.ReadSingle(); speedGrass.Chroma = b.ReadSingle(); speedGrass.Brightness = b.ReadSingle(); speedGrass.CombinationRatio = b.ReadSingle(); speedGrass.WindReaction = b.ReadSingle(); speedGrass.Filename = Encoding.Default.GetString(b.ReadBytes(b.ReadInt32())); var polyshCount = b.ReadInt32(); for (int p = 0; p < polyshCount; p++) { var polygon = new Polygon2(); var pointCount = b.ReadInt32(); for (int n = 0; n < pointCount; n++) { var point = new K2DPosition(); point.X = b.ReadInt32(); point.Y = b.ReadInt32(); polygon.Points.Add(point); } speedGrass.Polygons.Add(polygon); } DwGrassColony.Add(speedGrass); } #endregion } if (Version >= 22) { #region Event area var eventAreaCount = b.ReadInt32(); for (int i = 0; i < eventAreaCount; i++) { var area = new EventAreaScript(); area.AreaId = b.ReadInt32(); var count = b.ReadInt32(); for (int p = 0; p < count; p++) { var polygon = new Polygon2(); var pointNum = b.ReadInt32(); for (int n = 0; n < pointNum; n++) { var point = new K2DPosition(); point.X = b.ReadInt32(); point.Y = b.ReadInt32(); polygon.Points.Add(point); } area.Polygons.Add(polygon); } DwEventArea.Add(area); } #endregion } } XLog.WriteLine(Levels.Good, "Ok"); } catch (Exception exception) { Blank(); XLog.WriteLine(Levels.Error, "Failed"); XLog.WriteLine(Levels.Fatal, "NfmManager::Load<Exception> -> {0}", exception); } }
/// <summary> /// Load existing map /// </summary> /// <param name="buffer"></param> public void Load(byte[] buffer) { try { using (MemoryReader mem = new MemoryReader(buffer)) { /*Terrain.Sign = Encoding.Default.GetString()*/ mem.ReadBytes(16); Terrain.Version = mem.ReadInt32(); #if DEBUG == false if (!SupportedVersion.Contains(Terrain.Version)) { Parent.Log(Levels.Error, $"Failed\n"); Parent.Log(Levels.Error, $"Incompatible version {Terrain.Version} is not supported or not implemented.\n"); return; } #endif var dwMapPropertiesOffset = mem.ReadInt32(); var dwTerrainSegmentOffset = mem.ReadInt32(); var dwPropOffset = mem.ReadInt32(); var dwVectorAttrOffset = mem.ReadInt32(); var dwWaterOffset = mem.ReadInt32(); var dwGrassColonyOffset = (Terrain.Version >= 17) ? mem.ReadInt32() : 0; var dwEventAreaOffset = (Terrain.Version >= 22) ? mem.ReadInt32() : 0; Global.TileCountPerSegment = mem.ReadInt32(); Global.SegmentCountPerMap = mem.ReadInt32(); Global.TileLenght = mem.ReadSingle(); #region Properties Terrain.MapProperties.Primary.Diffuse = new KColor(mem.ReadByte(), mem.ReadByte(), mem.ReadByte(), 255); Terrain.MapProperties.Primary.Specular = new KColor(mem.ReadByte(), mem.ReadByte(), mem.ReadByte(), 255); Terrain.MapProperties.Primary.Attenuation0 = mem.ReadSingle(); Terrain.MapProperties.Primary.Attenuation1 = mem.ReadSingle(); Terrain.MapProperties.Primary.Attenuation2 = mem.ReadSingle(); Terrain.MapProperties.Secondary.Diffuse = new KColor(mem.ReadByte(), mem.ReadByte(), mem.ReadByte(), 255); Terrain.MapProperties.Secondary.Specular = new KColor(mem.ReadByte(), mem.ReadByte(), mem.ReadByte(), 255); Terrain.MapProperties.Secondary.Attenuation0 = mem.ReadSingle(); Terrain.MapProperties.Secondary.Attenuation1 = mem.ReadSingle(); Terrain.MapProperties.Secondary.Attenuation2 = mem.ReadSingle(); Terrain.MapProperties.Sky = new KColor(mem.ReadByte(), mem.ReadByte(), mem.ReadByte(), 255); Terrain.MapProperties.Fog = new KColor(mem.ReadByte(), mem.ReadByte(), mem.ReadByte(), 255); Terrain.MapProperties.FogNear = mem.ReadSingle(); Terrain.MapProperties.FogFar = mem.ReadSingle(); Terrain.MapProperties.SkyType = mem.ReadUInt32(); Terrain.MapProperties.ShowTerrainInGame = mem.ReadBoolean(); #endregion #region Terrain segment for (int segmentY = 0; segmentY < Global.SegmentCountPerMap; segmentY++) { for (int segmentX = 0; segmentX < Global.SegmentCountPerMap; segmentX++) { Terrain.DwTerrainSegment[segmentX, segmentY] = new TerrainSegment(); Terrain.DwTerrainSegment[segmentX, segmentY].Version = (Terrain.Version >= 16) ? mem.ReadUInt32() : 0; for (int tile = 0; tile < 3; tile++) { Terrain.DwTerrainSegment[segmentX, segmentY].Tile[tile] = (Terrain.Version >= 16) ? mem.ReadUInt16() : (ushort)0; } Terrain.DwTerrainSegment[segmentX, segmentY].HsVector = new TerrainVertex[Global.TileCountPerSegment, Global.TileCountPerSegment]; for (int tileY = 0; tileY < Global.TileCountPerSegment; tileY++) { for (int tileX = 0; tileX < Global.TileCountPerSegment; tileX++) { Terrain.DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY] = new TerrainVertex(); Terrain.DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY].Height = mem.ReadSingle(); for (int f = 0; f < 2; f++) { if (Terrain.Version >= 16) { Terrain.DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY].FillBits[f] = mem.ReadUInt32(); } if (Terrain.Version == 15 && f == 0) { Terrain.DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY].FillBits[f] = mem.ReadUInt32(); } } Terrain.DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY].Attribute = (Terrain.Version >= 16) ? mem.ReadInt64() : 0; Terrain.DwTerrainSegment[segmentX, segmentY].HsVector[tileX, tileY].Color = new KColor(mem.ReadByte(), mem.ReadByte(), mem.ReadByte()); } } } } #endregion #region Prop //Escape offset prop table for (int i = 0; i < Global.SegmentCountPerMap * Global.SegmentCountPerMap; i++) { mem.ReadInt32(); } // PROP var segment = 0; for (int segmentY = 0; segmentY < Global.SegmentCountPerMap; segmentY++) { for (int segmentX = 0; segmentX < Global.SegmentCountPerMap; segmentX++) { var propcount = mem.ReadInt32(); for (int p = 0; p < propcount; p++) { var prop = new TerrainProp(); /* index */ mem.ReadInt32(); var vector = new Vector { X = mem.ReadSingle() + (segmentX * Global.TileLenght * Global.TileCountPerSegment), Y = mem.ReadSingle() + (segmentY * Global.TileLenght * Global.TileCountPerSegment), Z = mem.ReadSingle() }; prop.Position = vector; prop.RotateX = mem.ReadSingle(); prop.RotateY = mem.ReadSingle(); prop.RotateZ = mem.ReadSingle(); prop.ScaleX = mem.ReadSingle(); prop.ScaleY = (Terrain.Version >= 21) ? mem.ReadSingle() : prop.ScaleX; prop.ScaleZ = (Terrain.Version >= 21) ? mem.ReadSingle() : prop.ScaleX; prop.PropNum = mem.ReadUInt16(); prop.HeightLocked = (Terrain.Version >= 21) ? mem.ReadBoolean() : false; prop.LockHeight = (Terrain.Version >= 21) ? mem.ReadSingle() : 0.0f; prop.TextureGroup = (Terrain.Version >= 21) ? mem.ReadInt16() : (short)-1; Terrain.DwProps.Add(prop); } if (Terrain.Version >= 19) { var grassCount = mem.ReadInt32(); for (int n = 0; n < grassCount; n++) { var grass = new GrassProp(); var grassId = mem.ReadInt32(); var propCount = mem.ReadInt32(); for (int i = 0; i < propCount; i++) { var prop = new GrassProp(); var vector = new Vector(mem.ReadSingle(), mem.ReadSingle()); prop.GrassId = grassId; prop.Position = vector; prop.RotateX = mem.ReadSingle(); prop.RotateY = mem.ReadSingle(); prop.RotateZ = mem.ReadSingle(); Terrain.DwGrass.Add(grass); } } } segment++; } } #endregion #region Vector attribute var polygonCount = mem.ReadInt32(); for (int i = 0; i < polygonCount; i++) { var polygon = new Polygon(); var pointNum = mem.ReadInt32(); for (int p = 0; p < pointNum; p++) { var point = new Vector(mem.ReadInt32(), mem.ReadInt32()); polygon.Add(point); } Terrain.DwVectorAttr.Add(polygon); } #endregion #region Water var waterCount = mem.ReadInt32(); for (int i = 0; i < waterCount; i++) { var water = new Water(); water.Rectangle.LeftTop = new Vector { X = mem.ReadSingle() / Global.ScaleRatio, Y = mem.ReadSingle() / Global.ScaleRatio, Z = mem.ReadSingle() } .Rotate180FlipY(); water.Rectangle.RightBottom = new Vector { X = mem.ReadSingle() / Global.ScaleRatio, Y = mem.ReadSingle() / Global.ScaleRatio, Z = mem.ReadSingle() } .Rotate180FlipY(); water.Rectangle.Center = new Vector { X = mem.ReadSingle() / Global.ScaleRatio, Y = mem.ReadSingle() / Global.ScaleRatio, Z = mem.ReadSingle() } .Rotate180FlipY(); water.UseReflect = mem.ReadInt32(); water.WaterId = mem.ReadInt32(); Terrain.DwWater.Add(water); } #endregion if (Terrain.Version >= 17) { #region Speed grass var speedGrassCount = mem.ReadInt32(); for (int i = 0; i < speedGrassCount; i++) { var speedGrass = new SpeedGrassColony(); speedGrass.GrassId = mem.ReadInt32(); speedGrass.Density = mem.ReadSingle(); speedGrass.Distribution = mem.ReadSingle(); speedGrass.Size = mem.ReadSingle(); speedGrass.HeightP = mem.ReadSingle(); speedGrass.HeightM = mem.ReadSingle(); speedGrass.Color = new KColor(mem.ReadByte(), mem.ReadByte(), mem.ReadByte(), mem.ReadByte()); speedGrass.ColorRatio = mem.ReadSingle(); speedGrass.ColorTone = mem.ReadSingle(); speedGrass.Chroma = mem.ReadSingle(); speedGrass.Brightness = mem.ReadSingle(); speedGrass.CombinationRatio = mem.ReadSingle(); speedGrass.WindReaction = mem.ReadSingle(); speedGrass.Filename = Encoding.Default.GetString(mem.ReadBytes(mem.ReadInt32())); var polyshCount = mem.ReadInt32(); for (int p = 0; p < polyshCount; p++) { var polygon = new Polygon(); var pointCount = mem.ReadInt32(); for (int n = 0; n < pointCount; n++) { var point = new Vector(mem.ReadInt32(), mem.ReadInt32()); polygon.Add(point); } speedGrass.Polygons.Add(polygon); } Terrain.DwGrassColony.Add(speedGrass); } #endregion } if (Terrain.Version >= 22) { #region Event area var eventAreaCount = mem.ReadInt32(); for (int i = 0; i < eventAreaCount; i++) { var area = new EventArea(); area.AreaId = mem.ReadInt32(); var count = mem.ReadInt32(); for (int p = 0; p < count; p++) { var polygon = new Polygon(); var pointNum = mem.ReadInt32(); for (int n = 0; n < pointNum; n++) { var vector = new Vector { X = mem.ReadInt32() * Global.TileLenght / PointRatio / Global.ScaleRatio, Y = mem.ReadInt32() * Global.TileLenght / PointRatio / Global.ScaleRatio }; polygon.Add(vector.Rotate180FlipY()); } area.Polygons.Add(polygon); } Terrain.DwEventArea.Add(area); } #endregion } } Parent.Log(Levels.Success, "Ok\n"); } catch (Exception exception) { Dispose(); Parent.Log(Levels.Error, "Failed\n"); Parent.Log(Levels.Fatal, $"Nfm::Load<Exception> -> {exception}\n"); } }