diff --git a/OpenDiablo2.Common/Enums/eLevelSubType.cs b/OpenDiablo2.Common/Enums/eLevelSubType.cs new file mode 100644 index 00000000..6e8b75d4 --- /dev/null +++ b/OpenDiablo2.Common/Enums/eLevelSubType.cs @@ -0,0 +1,17 @@ +namespace OpenDiablo2.Common.Enums +{ + public enum eLevelSubType + { + Act1BorderCliff = 1, + Act1BorderMiddle = 2, + Act1BorderCorner = 2, + Act1BorderBorder = 3, + Act1Waypoint = 4, + Act1Shrine = 5, + Act1Wilderness = 6, + Act2Waypoint = 7, + Act2Shrine = 8, + Act2Desert = 9, + + } +} diff --git a/OpenDiablo2.Common/Enums/eWildBorder.cs b/OpenDiablo2.Common/Enums/eWildBorder.cs new file mode 100644 index 00000000..855e4012 --- /dev/null +++ b/OpenDiablo2.Common/Enums/eWildBorder.cs @@ -0,0 +1,18 @@ +namespace OpenDiablo2.Common.Enums +{ + public enum eWildBorder + { + South, + West, + North, + East, + SouthWest, + NorthWest, + NorthEast, + SouthEast, + ClosedBoxTopRight, + ClosedBoxBottomRight, + ClosedBoxBottomLeft, + ClosedBoxTopLeft + } +} diff --git a/OpenDiablo2.Common/Interfaces/IGameState.cs b/OpenDiablo2.Common/Interfaces/IGameState.cs index 6ff95853..d2e903ff 100644 --- a/OpenDiablo2.Common/Interfaces/IGameState.cs +++ b/OpenDiablo2.Common/Interfaces/IGameState.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Drawing; using OpenDiablo2.Common.Enums; using OpenDiablo2.Common.Models; @@ -15,5 +16,7 @@ namespace OpenDiablo2.Common.Interfaces void Update(long ms); IEnumerable GetMapCellInfo(int cellX, int cellY, eRenderCellType renderCellType); void UpdateMapCellInfo(int cellX, int cellY, eRenderCellType renderCellType, IEnumerable mapCellInfo); + MapInfo LoadMap(eLevelId levelId, Point origin); + MapInfo LoadSubMap(int levelDefId, Point origin); } } diff --git a/OpenDiablo2.Common/Interfaces/IMapEngine.cs b/OpenDiablo2.Common/Interfaces/IMapEngine.cs index 58a9e364..d8ccf182 100644 --- a/OpenDiablo2.Common/Interfaces/IMapEngine.cs +++ b/OpenDiablo2.Common/Interfaces/IMapEngine.cs @@ -9,6 +9,5 @@ namespace OpenDiablo2.Common.Interfaces PointF CameraLocation { get; set; } void Update(long ms); void Render(); - void NotifyMapChanged(); } } diff --git a/OpenDiablo2.Common/Models/MPQDS1.cs b/OpenDiablo2.Common/Models/MPQDS1.cs index 382c4d27..dae54170 100644 --- a/OpenDiablo2.Common/Models/MPQDS1.cs +++ b/OpenDiablo2.Common/Models/MPQDS1.cs @@ -73,6 +73,8 @@ namespace OpenDiablo2.Common.Models { static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + public string MapFile { get; set; } + public Int32 Version { get; internal set; } public Int32 Width { get; internal set; } public Int32 Height { get; internal set; } diff --git a/OpenDiablo2.Common/Models/MapInfo.cs b/OpenDiablo2.Common/Models/MapInfo.cs index 67383500..80c680c8 100644 --- a/OpenDiablo2.Common/Models/MapInfo.cs +++ b/OpenDiablo2.Common/Models/MapInfo.cs @@ -7,6 +7,7 @@ namespace OpenDiablo2.Common.Models public sealed class MapInfo { public eLevelId LevelId { get; set; } = eLevelId.None; + public MapInfo PrimaryMap { get; set; } = null; public MPQDS1 FileData { get; set; } public LevelPreset LevelPreset { get; set; } public LevelDetail LevelDetail { get; set; } diff --git a/OpenDiablo2.Common/OpenDiablo2.Common.csproj b/OpenDiablo2.Common/OpenDiablo2.Common.csproj index 0b9b7bfd..aeb2f4c2 100644 --- a/OpenDiablo2.Common/OpenDiablo2.Common.csproj +++ b/OpenDiablo2.Common/OpenDiablo2.Common.csproj @@ -74,8 +74,10 @@ + + diff --git a/OpenDiablo2.Core/GameState/GameState.cs b/OpenDiablo2.Core/GameState/GameState.cs index 13cae74d..c361233a 100644 --- a/OpenDiablo2.Core/GameState/GameState.cs +++ b/OpenDiablo2.Core/GameState/GameState.cs @@ -64,8 +64,71 @@ namespace OpenDiablo2.Core.GameState_ // TODO: Loading may make this 'fun'.. mapInfo = new List(); - LoadMap(eLevelId.Act1_Town1, new Point(0, 0)); + (new MapGenerator(this)).Generate(); + // TODO: We need a map generator here... + /* + { + // TODO: TEMP CODE AHEAD! + var transId = nw ? 3 : 2; + var level = engineDataManager.LevelPresets.First(x => x.Def == (int)transId); + var levelDetails = engineDataManager.LevelDetails.First(x => x.Id == level.LevelId); + var levelType = engineDataManager.LevelTypes.First(x => x.Id == levelDetails.LevelType); + + // Some maps have variations, so lets pick a random one + var mapNames = new List(); + if (level.File1 != "0") mapNames.Add(level.File1); + if (level.File2 != "0") mapNames.Add(level.File2); + if (level.File3 != "0") mapNames.Add(level.File3); + if (level.File4 != "0") mapNames.Add(level.File4); + if (level.File5 != "0") mapNames.Add(level.File5); + if (level.File6 != "0") mapNames.Add(level.File6); + + + var random = new Random(Seed); + var mapName = "data\\global\\tiles\\" + mapNames[random.Next(mapNames.Count())].Replace("/", "\\"); + _mapDataTemp2 = resourceManager.GetMPQDS1(mapName, level, levelDetails, levelType); + + } + */ + + } + + + public MapInfo LoadSubMap(int levelDefId, Point origin) + { + var level = engineDataManager.LevelPresets.First(x => x.Def == levelDefId); + var levelDetails = engineDataManager.LevelDetails.First(x => x.Id == level.LevelId); + var levelType = engineDataManager.LevelTypes.First(x => x.Id == levelDetails.LevelType); + + // Some maps have variations, so lets pick a random one + var mapNames = new List(); + if (level.File1 != "0") mapNames.Add(level.File1); + if (level.File2 != "0") mapNames.Add(level.File2); + if (level.File3 != "0") mapNames.Add(level.File3); + if (level.File4 != "0") mapNames.Add(level.File4); + if (level.File5 != "0") mapNames.Add(level.File5); + if (level.File6 != "0") mapNames.Add(level.File6); + + + var random = new Random(Seed); + var mapName = "data\\global\\tiles\\" + mapNames[random.Next(mapNames.Count())].Replace("/", "\\"); + var fileData = resourceManager.GetMPQDS1(mapName, level, levelDetails, levelType); + + var result = new MapInfo + { + LevelId = eLevelId.None, + LevelPreset = level, + LevelDetail = levelDetails, + LevelType = levelType, + FileData = fileData, + CellInfo = new Dictionary(), + TileLocation = new Rectangle(origin, new Size(fileData.Width, fileData.Height)) + }; + + mapInfo.Add(result); + + return result; } public MapInfo LoadMap(eLevelId levelId, Point origin) @@ -108,32 +171,8 @@ namespace OpenDiablo2.Core.GameState_ }; mapInfo.Add(result); + return result; - /* - { - // TODO: TEMP CODE AHEAD! - var transId = nw ? 3 : 2; - var level = engineDataManager.LevelPresets.First(x => x.Def == (int)transId); - var levelDetails = engineDataManager.LevelDetails.First(x => x.Id == level.LevelId); - var levelType = engineDataManager.LevelTypes.First(x => x.Id == levelDetails.LevelType); - - // Some maps have variations, so lets pick a random one - var mapNames = new List(); - if (level.File1 != "0") mapNames.Add(level.File1); - if (level.File2 != "0") mapNames.Add(level.File2); - if (level.File3 != "0") mapNames.Add(level.File3); - if (level.File4 != "0") mapNames.Add(level.File4); - if (level.File5 != "0") mapNames.Add(level.File5); - if (level.File6 != "0") mapNames.Add(level.File6); - - - var random = new Random(Seed); - var mapName = "data\\global\\tiles\\" + mapNames[random.Next(mapNames.Count())].Replace("/", "\\"); - _mapDataTemp2 = resourceManager.GetMPQDS1(mapName, level, levelDetails, levelType); - - } - */ - getMapEngine().NotifyMapChanged(); } public IEnumerable GetMapCellInfo(int cellX, int cellY, eRenderCellType renderCellType) @@ -174,7 +213,6 @@ namespace OpenDiablo2.Core.GameState_ var map = mapInfo.FirstOrDefault(z => z.TileLocation.Contains(x, y)); if (map == null) { - // TODO: Generate map here return null; } @@ -283,7 +321,7 @@ namespace OpenDiablo2.Core.GameState_ } int frame = 0; - var tiles = map.FileData.LookupTable + var tiles = (map.PrimaryMap ?? map).FileData.LookupTable .Where(x => x.MainIndex == main_index && x.SubIndex == sub_index && x.Orientation == orientation) .Select(x => x.TileRef); diff --git a/OpenDiablo2.Core/Map Engine/MapEngine.cs b/OpenDiablo2.Core/Map Engine/MapEngine.cs index f5ee444d..d7443f72 100644 --- a/OpenDiablo2.Core/Map Engine/MapEngine.cs +++ b/OpenDiablo2.Core/Map Engine/MapEngine.cs @@ -50,17 +50,6 @@ namespace OpenDiablo2.Core.Map_Engine loadingSprite = renderWindow.LoadSprite(ResourcePaths.LoadingScreen, Palettes.Loading, new Point(300, 400)); } - public void NotifyMapChanged() - { - LoadNewMapData(); - CameraLocation = new PointF(0, 0); - } - - private void LoadNewMapData() - { - - } - public void Render() { var cx = -(cameraLocation.X - Math.Truncate(cameraLocation.X)); diff --git a/OpenDiablo2.Core/MapGenerator.cs b/OpenDiablo2.Core/MapGenerator.cs new file mode 100644 index 00000000..40c17812 --- /dev/null +++ b/OpenDiablo2.Core/MapGenerator.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenDiablo2.Common.Enums; +using OpenDiablo2.Common.Interfaces; +using OpenDiablo2.Common.Models; + +namespace OpenDiablo2.Core +{ + public sealed class MapGenerator + { + private readonly IGameState gameState; + + public MapGenerator(IGameState gameState) + { + this.gameState = gameState; + } + + public void Generate() + { + var wildBorder = 5; // (4-15) + // TODO: Is there no data file that explicitly defines this?? + var townMap = gameState.LoadMap(eLevelId.Act1_Town1, new Point(0, 0)); + if (townMap.FileData.MapFile.Contains("S1")) + { + var defId = 3; // Act 1 - Town 1 Transition S + var borderMap = gameState.LoadSubMap(defId, new Point(0, townMap.FileData.Height)); + borderMap.PrimaryMap = townMap; + + var wilderness = gameState.LoadSubMap(wildBorder, new Point(26, townMap.FileData.Height + borderMap.FileData.Height)); + wilderness.PrimaryMap = townMap; + } + else if (townMap.FileData.MapFile.Contains("E1")) + { + var defId = 2; // Act 1 - Town 1 Transition E + var borderMap = gameState.LoadSubMap(defId, new Point(townMap.FileData.Width, 0)); + borderMap.PrimaryMap = townMap; + + for (int i = 4; i <= 15; i++) + { + var wilderness = gameState.LoadSubMap(i, new Point(townMap.FileData.Width + borderMap.FileData.Width + ((i-4) * 10), 26)); + wilderness.PrimaryMap = townMap; + } + } + + } + + + } +} diff --git a/OpenDiablo2.Core/OpenDiablo2.Core.csproj b/OpenDiablo2.Core/OpenDiablo2.Core.csproj index 9e549e01..4a9fccb7 100644 --- a/OpenDiablo2.Core/OpenDiablo2.Core.csproj +++ b/OpenDiablo2.Core/OpenDiablo2.Core.csproj @@ -77,6 +77,7 @@ + diff --git a/OpenDiablo2.Core/ResourceManager.cs b/OpenDiablo2.Core/ResourceManager.cs index 1eb650d9..141f6052 100644 --- a/OpenDiablo2.Core/ResourceManager.cs +++ b/OpenDiablo2.Core/ResourceManager.cs @@ -43,7 +43,10 @@ namespace OpenDiablo2.Core public MPQDS1 GetMPQDS1(string resourcePath, LevelPreset level, LevelDetail levelDetail, LevelType levelType) { var mapName = resourcePath.Replace("data\\global\\tiles\\", "").Replace("\\", "/"); - return new MPQDS1(mpqProvider.GetStream(resourcePath), level, levelDetail, levelType, engineDataManager, this); + return new MPQDS1(mpqProvider.GetStream(resourcePath), level, levelDetail, levelType, engineDataManager, this) + { + MapFile = resourcePath + }; } public Palette GetPalette(string paletteFile)