1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2025-02-09 10:06:35 -05:00

Minor cleanup. Added object and object type data dictionaries. Map loader now includes object and tag data

This commit is contained in:
Tim Sarbin 2018-12-14 14:48:36 -05:00
parent f56273a4a2
commit c85b2bc605
12 changed files with 277 additions and 171 deletions

View File

@ -1,8 +1,7 @@
using System.Collections.Generic; using OpenDiablo2.Common.Enums;
using System.Collections.Immutable;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces.Mobs; using OpenDiablo2.Common.Interfaces.Mobs;
using OpenDiablo2.Common.Models; using OpenDiablo2.Common.Models;
using System.Collections.Immutable;
namespace OpenDiablo2.Common.Interfaces namespace OpenDiablo2.Common.Interfaces
{ {
@ -16,5 +15,6 @@ namespace OpenDiablo2.Common.Interfaces
ImmutableDictionary<eHero, IHeroTypeConfig> HeroTypeConfigs { get; } ImmutableDictionary<eHero, IHeroTypeConfig> HeroTypeConfigs { get; }
ImmutableList<IEnemyTypeConfig> EnemyTypeConfigs { get; } ImmutableList<IEnemyTypeConfig> EnemyTypeConfigs { get; }
ImmutableList<ObjectInfo> Objects { get; } ImmutableList<ObjectInfo> Objects { get; }
ImmutableList<ObjectTypeInfo> ObjectTypes { get; }
} }
} }

View File

@ -2,7 +2,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using OpenDiablo2.Common.Exceptions;
using OpenDiablo2.Common.Interfaces; using OpenDiablo2.Common.Interfaces;
namespace OpenDiablo2.Common.Models namespace OpenDiablo2.Common.Models
@ -40,6 +42,11 @@ namespace OpenDiablo2.Common.Models
public MPQDS1TileProps[] Props { get; internal set; } public MPQDS1TileProps[] Props { get; internal set; }
} }
public sealed class MPQDS1TagLayer
{
public Int32 Number { get; internal set; }
}
public sealed class MPQDS1Object public sealed class MPQDS1Object
{ {
public Int32 Type { get; internal set; } public Int32 Type { get; internal set; }
@ -47,6 +54,7 @@ namespace OpenDiablo2.Common.Models
public Int32 X { get; internal set; } public Int32 X { get; internal set; }
public Int32 Y { get; internal set; } public Int32 Y { get; internal set; }
public Int32 DS1Flags { get; internal set; } public Int32 DS1Flags { get; internal set; }
public ObjectInfo Info { get; internal set; }
} }
public sealed class MPQDS1Group public sealed class MPQDS1Group
@ -92,6 +100,7 @@ namespace OpenDiablo2.Common.Models
public MPQDS1WallLayer[] WallLayers { get; internal set; } public MPQDS1WallLayer[] WallLayers { get; internal set; }
public MPQDS1FloorLayer[] FloorLayers { get; internal set; } public MPQDS1FloorLayer[] FloorLayers { get; internal set; }
public MPQDS1ShadowLayer[] ShadowLayers { get; internal set; } public MPQDS1ShadowLayer[] ShadowLayers { get; internal set; }
public MPQDS1TagLayer[] TagLayers { get; internal set; }
public MPQDS1Object[] Objects { get; internal set; } public MPQDS1Object[] Objects { get; internal set; }
public MPQDS1Group[] Groups { get; internal set; } public MPQDS1Group[] Groups { get; internal set; }
@ -125,7 +134,7 @@ namespace OpenDiablo2.Common.Models
fn.Append((char)b); fn.Append((char)b);
} }
var fnStr = fn.ToString(); var fnStr = fn.ToString();
if (fnStr.StartsWith("\\d2\\")) if (fnStr.StartsWith(@"\d2\"))
fnStr = fnStr.Substring(4); fnStr = fnStr.Substring(4);
FileNames.Add(fnStr); FileNames.Add(fnStr);
} }
@ -139,12 +148,7 @@ namespace OpenDiablo2.Common.Models
if (Version >= 4) if (Version >= 4)
{ {
NumberOfWalls = br.ReadInt32(); NumberOfWalls = br.ReadInt32();
NumberOfFloors = Version >= 16 ? br.ReadInt32() : 1;
if (Version >= 16)
{
NumberOfFloors = br.ReadInt32();
}
else NumberOfFloors = 1;
} }
else else
{ {
@ -159,7 +163,7 @@ namespace OpenDiablo2.Common.Models
if (Version < 4) if (Version < 4)
{ {
layoutStream.AddRange(new int[] { 1, 9, 5, 12, 11 }); layoutStream.AddRange(new[] { 1, 9, 5, 12, 11 });
} }
else else
{ {
@ -205,21 +209,27 @@ namespace OpenDiablo2.Common.Models
}; };
} }
TagLayers = new MPQDS1TagLayer[NumberOfTags];
for (var l = 0; l < NumberOfTags; l++)
{
TagLayers[l] = new MPQDS1TagLayer { Number = -1 };
}
for (int n = 0; n < layoutStream.Count; n++)
foreach (var idx in layoutStream)
{ {
for (var y = 0; y < Height; y++) for (var y = 0; y < Height; y++)
{ {
for (var x = 0; x < Width; x++) for (var x = 0; x < Width; x++)
{ {
switch (layoutStream[n]) switch (idx)
{ {
// Walls // Walls
case 1: case 1:
case 2: case 2:
case 3: case 3:
case 4: case 4:
WallLayers[layoutStream[n] - 1].Props[x + (y * Width)] = new MPQDS1TileProps WallLayers[idx - 1].Props[x + (y * Width)] = new MPQDS1TileProps
{ {
Prop1 = br.ReadByte(), Prop1 = br.ReadByte(),
Prop2 = br.ReadByte(), Prop2 = br.ReadByte(),
@ -240,7 +250,7 @@ namespace OpenDiablo2.Common.Models
} }
else else
{ {
WallLayers[layoutStream[n] - 5].Orientations[x + (y * Width)] = new MPQDS1WallOrientationTileProps WallLayers[idx - 5].Orientations[x + (y * Width)] = new MPQDS1WallOrientationTileProps
{ {
Orientation1 = br.ReadByte(), Orientation1 = br.ReadByte(),
Orientation2 = br.ReadByte(), Orientation2 = br.ReadByte(),
@ -253,7 +263,7 @@ namespace OpenDiablo2.Common.Models
// Floors // Floors
case 9: case 9:
case 10: case 10:
FloorLayers[layoutStream[n] - 9].Props[x + (y * Width)] = new MPQDS1TileProps FloorLayers[idx - 9].Props[x + (y * Width)] = new MPQDS1TileProps
{ {
Prop1 = br.ReadByte(), Prop1 = br.ReadByte(),
Prop2 = br.ReadByte(), Prop2 = br.ReadByte(),
@ -263,7 +273,7 @@ namespace OpenDiablo2.Common.Models
break; break;
// Shadow // Shadow
case 11: case 11:
ShadowLayers[layoutStream[n] - 11].Props[x + (y * Width)] = new MPQDS1TileProps ShadowLayers[idx - 11].Props[x + (y * Width)] = new MPQDS1TileProps
{ {
Prop1 = br.ReadByte(), Prop1 = br.ReadByte(),
Prop2 = br.ReadByte(), Prop2 = br.ReadByte(),
@ -273,25 +283,73 @@ namespace OpenDiablo2.Common.Models
break; break;
// Tags // Tags
case 12: case 12:
// TODO: Tags TagLayers[idx - 12].Number = br.ReadInt32();
br.ReadBytes(4);
break; break;
default:
throw new OpenDiablo2Exception($"Unknown layer {idx} encountered.");
} }
} }
} }
} }
// Load the objects
NumberOfObjects = br.ReadInt32();
Objects = new MPQDS1Object[NumberOfObjects];
for (var i = 0; i < NumberOfObjects; i++)
{
Objects[i] = new MPQDS1Object
{
Type = br.ReadInt32(),
Id = br.ReadInt32(),
X = br.ReadInt32(),
Y = br.ReadInt32(),
};
if (Version > 5)
Objects[i].DS1Flags = br.ReadInt32();
Objects[i].Info = engineDataManager.Objects.First(x => x.Id == Objects[i].Id);
}
if (Version >= 12 && (TagType == 1 || TagType == 2))
{
if (Version >= 18)
br.ReadInt32(); // Skip a byte (but why?)
NumberOfGroups = br.ReadInt32();
Groups = new MPQDS1Group[NumberOfGroups];
for (var i = 0; i < NumberOfGroups; i++)
{
Groups[i] = new MPQDS1Group
{
TileX = br.ReadInt32(),
TileY = br.ReadInt32(),
Width = br.ReadInt32(),
Height = br.ReadInt32()
};
if (Version >= 13)
br.ReadInt32(); // Unknown group property value (what is this???)
}
}
else
Groups = new MPQDS1Group[0];
if (Version >= 14)
{
// TODO: NPC Paths
}
var dt1Mask = level.Dt1Mask; var dt1Mask = level.Dt1Mask;
for (int i = 0; i < 32; i++) for (var i = 0; i < 32; i++)
{ {
var isMasked = ((dt1Mask >> i) & 1) == 1; var isMasked = ((dt1Mask >> i) & 1) == 1;
if (!isMasked || levelType.File[i] == "0") if (!isMasked || levelType.File[i] == "0")
continue; continue;
DT1s[i] = resourceManager.GetMPQDT1("data\\global\\tiles\\" + levelType.File[i].Replace("/", "\\")); DT1s[i] = resourceManager.GetMPQDT1(@"data\global\tiles\" + levelType.File[i].Replace("/", "\\"));
} }
@ -312,6 +370,7 @@ namespace OpenDiablo2.Common.Models
} }
} }
} }
} }

View File

@ -46,7 +46,7 @@ namespace OpenDiablo2.Common.Models
public Int32 X2 { get; private set; } public Int32 X2 { get; private set; }
public Int32 NumberOfTiles { get; private set; } public Int32 NumberOfTiles { get; private set; }
public MPQDT1Tile[] Tiles { get; private set; } public MPQDT1Tile[] Tiles { get; private set; }
private readonly Int32 tileHeaderOffset; private readonly Int32 _tileHeaderOffset;
public MPQDT1(Stream stream) public MPQDT1(Stream stream)
{ {
@ -58,7 +58,7 @@ namespace OpenDiablo2.Common.Models
stream.Seek(268, SeekOrigin.Begin); // Skip useless header info stream.Seek(268, SeekOrigin.Begin); // Skip useless header info
NumberOfTiles = br.ReadInt32(); NumberOfTiles = br.ReadInt32();
tileHeaderOffset = br.ReadInt32(); _tileHeaderOffset = br.ReadInt32();
ReadTiles(br); ReadTiles(br);
ReadBlockHeaders(br); ReadBlockHeaders(br);
@ -68,9 +68,9 @@ namespace OpenDiablo2.Common.Models
private void ReadTiles(BinaryReader br) private void ReadTiles(BinaryReader br)
{ {
Tiles = new MPQDT1Tile[NumberOfTiles]; Tiles = new MPQDT1Tile[NumberOfTiles];
for (int tileIndex = 0; tileIndex < NumberOfTiles; tileIndex++) for (var tileIndex = 0; tileIndex < NumberOfTiles; tileIndex++)
{ {
br.BaseStream.Seek(tileHeaderOffset + (tileIndex * 96), SeekOrigin.Begin); br.BaseStream.Seek(_tileHeaderOffset + (tileIndex * 96), SeekOrigin.Begin);
Tiles[tileIndex] = new MPQDT1Tile(); Tiles[tileIndex] = new MPQDT1Tile();
var tile = Tiles[tileIndex]; var tile = Tiles[tileIndex];
@ -86,7 +86,7 @@ namespace OpenDiablo2.Common.Models
tile.SubIndex = br.ReadInt32(); tile.SubIndex = br.ReadInt32();
tile.RarityOrFrameIndex = br.ReadInt32(); tile.RarityOrFrameIndex = br.ReadInt32();
br.ReadBytes(4); br.ReadBytes(4);
for (int i = 0; i < 25; i++) for (var i = 0; i < 25; i++)
tile.SubTileFlags[i] = br.ReadByte(); tile.SubTileFlags[i] = br.ReadByte();
br.ReadBytes(7); br.ReadBytes(7);
tile.BlockHeadersPointer = br.ReadInt32(); tile.BlockHeadersPointer = br.ReadInt32();
@ -99,12 +99,12 @@ namespace OpenDiablo2.Common.Models
private void ReadBlockHeaders(BinaryReader br) private void ReadBlockHeaders(BinaryReader br)
{ {
for (int tileIndex = 0; tileIndex < NumberOfTiles; tileIndex++) for (var tileIndex = 0; tileIndex < NumberOfTiles; tileIndex++)
{ {
var tile = Tiles[tileIndex]; var tile = Tiles[tileIndex];
tile.Blocks = new MPQDT1Block[tile.NumberOfBlocks]; tile.Blocks = new MPQDT1Block[tile.NumberOfBlocks];
for (int blockIndex = 0; blockIndex < tile.NumberOfBlocks; blockIndex++) for (var blockIndex = 0; blockIndex < tile.NumberOfBlocks; blockIndex++)
{ {
br.BaseStream.Seek(tile.BlockHeadersPointer + (blockIndex * 20), SeekOrigin.Begin); br.BaseStream.Seek(tile.BlockHeadersPointer + (blockIndex * 20), SeekOrigin.Begin);
@ -126,9 +126,9 @@ namespace OpenDiablo2.Common.Models
private void ReadBlockGraphics(BinaryReader br) private void ReadBlockGraphics(BinaryReader br)
{ {
for (int tileIndex = 0; tileIndex < NumberOfTiles; tileIndex++) for (var tileIndex = 0; tileIndex < NumberOfTiles; tileIndex++)
{ {
for (int blockIndex = 0; blockIndex < Tiles[tileIndex].NumberOfBlocks; blockIndex++) for (var blockIndex = 0; blockIndex < Tiles[tileIndex].NumberOfBlocks; blockIndex++)
{ {
var block = Tiles[tileIndex].Blocks[blockIndex]; var block = Tiles[tileIndex].Blocks[blockIndex];
br.BaseStream.Seek(Tiles[tileIndex].BlockHeadersPointer + block.FileOffset, SeekOrigin.Begin); br.BaseStream.Seek(Tiles[tileIndex].BlockHeadersPointer + block.FileOffset, SeekOrigin.Begin);
@ -139,17 +139,13 @@ namespace OpenDiablo2.Common.Models
if (block.Length != 256) if (block.Length != 256)
throw new OpenDiablo2Exception($"Expected exactly 256 bytes of data, but got {block.Length} instead!"); throw new OpenDiablo2Exception($"Expected exactly 256 bytes of data, but got {block.Length} instead!");
int x = 0; var y = 0;
int y = 0;
int n = 0;
int[] xjump = { 14, 12, 10, 8, 6, 4, 2, 0, 2, 4, 6, 8, 10, 12, 14 };
int[] nbpix = { 4, 8, 12, 16, 20, 24, 28, 32, 28, 24, 20, 16, 12, 8, 4 };
var length = 256; var length = 256;
block.PixelData = new Int16[32 * 32]; block.PixelData = new Int16[32 * 32];
while (length > 0) while (length > 0)
{ {
x = xjump[y]; var x = new[] { 14, 12, 10, 8, 6, 4, 2, 0, 2, 4, 6, 8, 10, 12, 14 }[y];
n = nbpix[y]; var n = new[] { 4, 8, 12, 16, 20, 24, 28, 32, 28, 24, 20, 16, 12, 8, 4 }[y];
length -= n; length -= n;
while (n > 0) while (n > 0)
{ {
@ -165,15 +161,13 @@ namespace OpenDiablo2.Common.Models
{ {
// RLE block // RLE block
var length = block.Length; var length = block.Length;
byte b1; var x = 0;
byte b2; var y = 0;
int x = 0;
int y = 0;
block.PixelData = new Int16[32 * 32]; block.PixelData = new Int16[32 * 32];
while (length > 0) while (length > 0)
{ {
b1 = br.ReadByte(); var b1 = br.ReadByte();
b2 = br.ReadByte(); var b2 = br.ReadByte();
length -= 2; length -= 2;
if (b1 + b2 == 0) if (b1 + b2 == 0)
{ {

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OpenDiablo2.Common.Models
{
public sealed class ObjectTypeInfo
{
public string Name { get; internal set; }
public string Token { get; internal set; }
public bool Beta { get; internal set; }
}
public static class ObjectTypeInfoHelper
{
public static ObjectTypeInfo ToObjectTypeInfo(this string[] row)
=> new ObjectTypeInfo { Name = row[0], Token = row[1], Beta = Convert.ToInt32(row[2]) == 1 };
}
}

View File

@ -121,6 +121,7 @@
<Compile Include="Models\MPQDCC.cs" /> <Compile Include="Models\MPQDCC.cs" />
<Compile Include="Models\ItemContainerLayout.cs" /> <Compile Include="Models\ItemContainerLayout.cs" />
<Compile Include="Models\ObjectInfo.cs" /> <Compile Include="Models\ObjectInfo.cs" />
<Compile Include="Models\ObjectTypeInfo.cs" />
<Compile Include="Models\PlayerInfo.cs" /> <Compile Include="Models\PlayerInfo.cs" />
<Compile Include="Models\PlayerLocationDetails.cs" /> <Compile Include="Models\PlayerLocationDetails.cs" />
<Compile Include="Interfaces\UI\IButton.cs" /> <Compile Include="Interfaces\UI\IButton.cs" />

View File

@ -45,7 +45,7 @@ namespace OpenDiablo2.Core
builder.RegisterType<InventoryPanel>().AsImplementedInterfaces().InstancePerDependency(); builder.RegisterType<InventoryPanel>().AsImplementedInterfaces().InstancePerDependency();
builder.RegisterType<SkillsPanel>().AsImplementedInterfaces().InstancePerDependency(); builder.RegisterType<SkillsPanel>().AsImplementedInterfaces().InstancePerDependency();
builder.RegisterType<ItemContainer>().As<IItemContainer>().InstancePerDependency(); builder.RegisterType<ItemContainer>().As<IItemContainer>().InstancePerDependency();
builder.RegisterType<MPQProvider>().As<IMPQProvider>().SingleInstance(); builder.RegisterType<MpqProvider>().As<IMPQProvider>().SingleInstance();
builder.RegisterType<ResourceManager>().As<IResourceManager>().SingleInstance(); builder.RegisterType<ResourceManager>().As<IResourceManager>().SingleInstance();
builder.RegisterType<TextDictionary>().As<ITextDictionary>().SingleInstance(); builder.RegisterType<TextDictionary>().As<ITextDictionary>().SingleInstance();
builder.RegisterType<TextBox>().As<ITextBox>().InstancePerDependency(); builder.RegisterType<TextBox>().As<ITextBox>().InstancePerDependency();

View File

@ -23,6 +23,7 @@ namespace OpenDiablo2.Core
public ImmutableList<LevelPreset> LevelPresets { get; internal set; } public ImmutableList<LevelPreset> LevelPresets { get; internal set; }
public ImmutableList<LevelType> LevelTypes { get; internal set; } public ImmutableList<LevelType> LevelTypes { get; internal set; }
public ImmutableList<ObjectInfo> Objects { get; internal set; } public ImmutableList<ObjectInfo> Objects { get; internal set; }
public ImmutableList<ObjectTypeInfo> ObjectTypes { get; internal set; }
public ImmutableList<Item> Items { get; internal set; } public ImmutableList<Item> Items { get; internal set; }
public ImmutableDictionary<eHero, ILevelExperienceConfig> ExperienceConfigs { get; internal set; } public ImmutableDictionary<eHero, ILevelExperienceConfig> ExperienceConfigs { get; internal set; }
@ -83,6 +84,18 @@ namespace OpenDiablo2.Core
.Where(x => x.Count() > 150 && x[0] != "Expansion") .Where(x => x.Count() > 150 && x[0] != "Expansion")
.Select(x => x.ToObjectInfo()) .Select(x => x.ToObjectInfo())
.ToImmutableList(); .ToImmutableList();
log.Info("Loading object types");
ObjectTypes = mpqProvider
.GetTextFile(ResourcePaths.ObjectDetails)
.Skip(1)
.Where(x => !String.IsNullOrWhiteSpace(x))
.Select(x => x.Split('\t'))
.Where(x => x.Count() == 3 && x[0] != "Expansion")
.Select(x => x.ToObjectTypeInfo())
.ToImmutableList();
} }
private ImmutableList<Item> LoadItemData() private ImmutableList<Item> LoadItemData()

View File

@ -26,15 +26,15 @@ namespace OpenDiablo2.Core.GameState_
private readonly Func<eSessionType, ISessionManager> getSessionManager; private readonly Func<eSessionType, ISessionManager> getSessionManager;
private readonly Func<string, IRandomizedMapGenerator> getRandomizedMapGenerator; private readonly Func<string, IRandomizedMapGenerator> getRandomizedMapGenerator;
private float animationTime = 0f; private float animationTime;
private List<IMapInfo> mapInfo; private List<IMapInfo> mapInfo;
private readonly List<MapCellInfo> mapDataLookup = new List<MapCellInfo>(); private readonly List<MapCellInfo> mapDataLookup;
private ISessionManager sessionManager; private ISessionManager sessionManager;
public int Act { get; private set; } public int Act { get; private set; }
public string MapName { get; private set; } public string MapName { get; private set; }
public Palette CurrentPalette => paletteProvider.PaletteTable[$"ACT{Act}"]; public Palette CurrentPalette => paletteProvider.PaletteTable[$"ACT{Act}"];
public List<PlayerInfo> PlayerInfos { get; private set; } = new List<PlayerInfo>(); public List<PlayerInfo> PlayerInfos { get; private set; }
readonly private IMouseCursor originalMouseCursor; readonly private IMouseCursor originalMouseCursor;
@ -74,7 +74,8 @@ namespace OpenDiablo2.Core.GameState_
this.getRandomizedMapGenerator = getRandomizedMapGenerator; this.getRandomizedMapGenerator = getRandomizedMapGenerator;
originalMouseCursor = renderWindow.MouseCursor; originalMouseCursor = renderWindow.MouseCursor;
PlayerInfos = new List<PlayerInfo>();
mapDataLookup = new List<MapCellInfo>();
} }
public void Initialize(string characterName, eHero hero, eSessionType sessionType) public void Initialize(string characterName, eHero hero, eSessionType sessionType)
@ -88,8 +89,8 @@ namespace OpenDiablo2.Core.GameState_
sessionManager.OnFocusOnPlayer += OnFocusOnPlayer; sessionManager.OnFocusOnPlayer += OnFocusOnPlayer;
mapInfo = new List<IMapInfo>(); mapInfo = new List<IMapInfo>();
sceneManager.ChangeScene(eSceneType.Game);
sceneManager.ChangeScene(eSceneType.Game);
sessionManager.JoinGame(characterName, hero); sessionManager.JoinGame(characterName, hero);
} }
@ -97,7 +98,7 @@ namespace OpenDiablo2.Core.GameState_
=> getMapEngine().FocusedPlayerId = playerId; => getMapEngine().FocusedPlayerId = playerId;
private void OnPlayerInfo(int clientHash, IEnumerable<PlayerInfo> playerInfo) private void OnPlayerInfo(int clientHash, IEnumerable<PlayerInfo> playerInfo)
=> this.PlayerInfos = playerInfo.ToList(); => PlayerInfos = playerInfo.ToList();
private void OnLocatePlayers(int clientHash, IEnumerable<PlayerLocationDetails> playerLocationDetails) private void OnLocatePlayers(int clientHash, IEnumerable<PlayerLocationDetails> playerLocationDetails)
{ {
@ -203,9 +204,12 @@ namespace OpenDiablo2.Core.GameState_
var random = new Random(Seed); var random = new Random(Seed);
// -------------------------------------------------------------------------------------
// var mapName = "data\\global\\tiles\\" + mapNames[random.Next(mapNames.Count)].Replace("/", "\\"); // var mapName = "data\\global\\tiles\\" + mapNames[random.Next(mapNames.Count)].Replace("/", "\\");
// -------------------------------------------------------------------------------------
// TODO: ***TEMP FOR TESTING // TODO: ***TEMP FOR TESTING
var mapName = "data\\global\\tiles\\" + mapNames[0].Replace("/", "\\"); var mapName = "data\\global\\tiles\\" + mapNames[0].Replace("/", "\\");
// -------------------------------------------------------------------------------------
MapName = levelDetails.LevelPreset.Name; MapName = levelDetails.LevelPreset.Name;
Act = levelDetails.LevelType.Act; Act = levelDetails.LevelType.Act;
@ -270,15 +274,23 @@ namespace OpenDiablo2.Core.GameState_
private IMapInfo GetMap(ref int cellX, ref int cellY) private IMapInfo GetMap(ref int cellX, ref int cellY)
{ {
var p = new Point(cellX, cellY); var p = new Point(cellX, cellY);
var map = mapInfo.LastOrDefault(z => z.TileLocation.Contains(p));
if (map == null) IMapInfo mi = null;
for (var i = mapInfo.Count - 1; i >= 0; i--)
{ {
return null; if (mapInfo[i].TileLocation.Contains(p))
{
mi = mapInfo[i];
break;
} }
cellX -= map.TileLocation.X; }
cellY -= map.TileLocation.Y; if (mi == null)
return map; return null;
cellX -= mi.TileLocation.X;
cellY -= mi.TileLocation.Y;
return mi;
} }
public void UpdateMapCellInfo(int cellX, int cellY, eRenderCellType renderCellType, IEnumerable<MapCellInfo> mapCellInfo) public void UpdateMapCellInfo(int cellX, int cellY, eRenderCellType renderCellType, IEnumerable<MapCellInfo> mapCellInfo)
@ -294,9 +306,8 @@ namespace OpenDiablo2.Core.GameState_
} }
else else
{ {
var cursorsprite = renderWindow.LoadSprite(ResourcePaths.GeneratePathForItem(item.Item.InvFile), Palettes.Units); var cursorSprite = renderWindow.LoadSprite(ResourcePaths.GeneratePathForItem(item.Item.InvFile), Palettes.Units);
renderWindow.MouseCursor = renderWindow.LoadCursor(cursorSprite, 0, new Point(cursorSprite.FrameSize.Width / 2, cursorSprite.FrameSize.Height / 2));
renderWindow.MouseCursor = renderWindow.LoadCursor(cursorsprite, 0, new Point(cursorsprite.FrameSize.Width / 2, cursorsprite.FrameSize.Height / 2));
} }
this.SelectedItem = item; this.SelectedItem = item;
@ -317,8 +328,8 @@ namespace OpenDiablo2.Core.GameState_
if (cellInfo != null && (cellInfo.Ignore || !cellInfo.Tile.Animated)) if (cellInfo != null && (cellInfo.Ignore || !cellInfo.Tile.Animated))
return cellInfo.Ignore ? null : cellInfo; return cellInfo.Ignore ? null : cellInfo;
var main_index = (props.Prop3 >> 4) + ((props.Prop4 & 0x03) << 4); var mainIndex = (props.Prop3 >> 4) + ((props.Prop4 & 0x03) << 4);
var sub_index = props.Prop2; var subIndex = props.Prop2;
if (orientation == 0) if (orientation == 0)
{ {
@ -375,15 +386,14 @@ namespace OpenDiablo2.Core.GameState_
} }
} }
int frame = 0;
IEnumerable<MPQDT1Tile> tiles = Enumerable.Empty<MPQDT1Tile>(); IEnumerable<MPQDT1Tile> tiles = Enumerable.Empty<MPQDT1Tile>();
tiles = map.FileData.LookupTable tiles = map.FileData.LookupTable
.Where(x => x.MainIndex == main_index && x.SubIndex == sub_index && x.Orientation == orientation) .Where(x => x.MainIndex == mainIndex && x.SubIndex == subIndex && x.Orientation == orientation)
.Select(x => x.TileRef); .Select(x => x.TileRef);
if (tiles == null || !tiles.Any()) if (tiles == null || !tiles.Any())
{ {
log.Error($"Could not find tile [{main_index}:{sub_index}:{orientation}]!"); log.Error($"Could not find tile [{mainIndex}:{subIndex}:{orientation}]!");
map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo { Ignore = true }; map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo { Ignore = true };
return null; return null;
} }
@ -438,7 +448,7 @@ namespace OpenDiablo2.Core.GameState_
} }
var mapCellInfo = mapDataLookup.FirstOrDefault(x => x.Tile.Id == tile.Id && x.AnimationId == frame); var mapCellInfo = mapDataLookup.FirstOrDefault(x => x.Tile.Id == tile.Id);
if (mapCellInfo == null) if (mapCellInfo == null)
{ {
mapCellInfo = renderWindow.CacheMapCell(tile, cellType); mapCellInfo = renderWindow.CacheMapCell(tile, cellType);

View File

@ -27,45 +27,52 @@ using System.Linq;
namespace OpenDiablo2.Core namespace OpenDiablo2.Core
{ {
public sealed class MPQProvider : IMPQProvider public sealed class MpqProvider : IMPQProvider
{ {
private readonly IList<MPQ> mpqs; private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private readonly Dictionary<string, int> mpqLookup = new Dictionary<string, int>();
public MPQProvider(GlobalConfiguration globalConfiguration) private readonly IList<MPQ> _mpqs;
private readonly Dictionary<string, int> _mpqLookup = new Dictionary<string, int>();
public MpqProvider(GlobalConfiguration globalConfiguration)
{ {
// TODO: Make this less dumb. We need to an external file to configure mpq load order. // TODO: Make this less dumb. We need to an external file to configure mpq load order.
this.mpqs = Directory _mpqs = Directory
.EnumerateFiles(globalConfiguration.BaseDataPath, "*.mpq") .EnumerateFiles(globalConfiguration.BaseDataPath, "*.mpq")
.Where(x => !Path.GetFileName(x).StartsWith("patch")) .Where(x => !(Path.GetFileName(x)?.StartsWith("patch") ?? false))
.Select(file => new MPQ(file)) .Select(file => new MPQ(file))
.ToArray(); .ToArray();
if (!_mpqs.Any())
{
_log.Fatal("No data files were found! Are you specifying the correct data path?");
throw new OpenDiablo2Exception("No data files were found.");
}
// Load the base game files // Load the base game files
for(var i = 0; i < mpqs.Count(); i++) for(var i = 0; i < _mpqs.Count; i++)
{ {
if (Path.GetFileName(mpqs[i].Path).StartsWith("d2exp") || Path.GetFileName(mpqs[i].Path).StartsWith("d2x")) var path = Path.GetFileName(_mpqs[i].Path) ?? string.Empty;
if (path.StartsWith("d2exp") || path.StartsWith("d2x"))
continue; continue;
foreach(var file in mpqs[i].Files) foreach(var file in _mpqs[i].Files)
{ _mpqLookup[file.ToLower()] = i;
mpqLookup[file.ToLower()] = i;
}
} }
// Load the expansion game files // Load the expansion game files
for (var i = 0; i < mpqs.Count(); i++) for (var i = 0; i < _mpqs.Count; i++)
{ {
if (!Path.GetFileName(mpqs[i].Path).StartsWith("d2exp") && !Path.GetFileName(mpqs[i].Path).StartsWith("d2x")) var path = Path.GetFileName(_mpqs[i].Path) ?? string.Empty;
if (!path.StartsWith("d2exp") && !path.StartsWith("d2x"))
continue; continue;
foreach (var file in mpqs[i].Files) foreach (var file in _mpqs[i].Files)
{ _mpqLookup[file.ToLower()] = i;
mpqLookup[file.ToLower()] = i;
}
} }
} }
@ -77,36 +84,26 @@ namespace OpenDiablo2.Core
return result; return result;
} }
public IEnumerator<MPQ> GetEnumerator() public IEnumerator<MPQ> GetEnumerator() => _mpqs.GetEnumerator();
{
return mpqs.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
{
return GetEnumerator();
}
public Stream GetStream(string fileName) public Stream GetStream(string fileName) => !_mpqLookup.ContainsKey(fileName.ToLower())
{ ? null
if (!mpqLookup.ContainsKey(fileName.ToLower())) : _mpqs[_mpqLookup[fileName.ToLower()]].OpenFile(fileName);
return null;
return mpqs[mpqLookup[fileName.ToLower()]].OpenFile(fileName);
}
public IEnumerable<string> GetTextFile(string fileName) public IEnumerable<string> GetTextFile(string fileName)
=> new StreamReader(mpqs[mpqLookup[fileName.ToLower()]].OpenFile(fileName)).ReadToEnd().Split('\n'); => new StreamReader(_mpqs[_mpqLookup[fileName.ToLower()]].OpenFile(fileName)).ReadToEnd().Split('\n');
public string GetCharacterDccPath(eHero hero, eMobMode mobMode, eCompositType compositType, PlayerEquipment equipment) public string GetCharacterDccPath(eHero hero, eMobMode mobMode, eCompositType compositType, PlayerEquipment equipment)
{ {
var fileName = ($@"{ResourcePaths.PlayerAnimationBase}\{hero.ToToken()}\{compositType.ToToken()}\{hero.ToToken()}{compositType.ToToken()}").ToLower(); var fileName = $@"{ResourcePaths.PlayerAnimationBase}\{hero.ToToken()}\{compositType.ToToken()}\{hero.ToToken()}{compositType.ToToken()}".ToLower();
switch (compositType) switch (compositType)
{ {
case eCompositType.Head: case eCompositType.Head:
fileName += $"{equipment.Head?.Item.Code ?? eArmorType.Lite.ToToken()}{mobMode.ToToken()}"; fileName += $"{equipment.Head?.Item.Code ?? eArmorType.Lite.ToToken()}{mobMode.ToToken()}";
return mpqLookup.ContainsKey($"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower()) return _mpqLookup.ContainsKey($"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower())
? $"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower() ? $"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower()
: $"{fileName}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower(); : $"{fileName}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower();
case eCompositType.Torso: case eCompositType.Torso:
@ -114,7 +111,7 @@ namespace OpenDiablo2.Core
case eCompositType.RightArm: case eCompositType.RightArm:
case eCompositType.LeftArm: case eCompositType.LeftArm:
fileName += $"{equipment.ArmorType.ToToken()}{mobMode.ToToken()}"; fileName += $"{equipment.ArmorType.ToToken()}{mobMode.ToToken()}";
return mpqLookup.ContainsKey($"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower()) return _mpqLookup.ContainsKey($"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower())
? $"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower() ? $"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower()
: $"{fileName}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower(); : $"{fileName}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower();
case eCompositType.RightHand: case eCompositType.RightHand:
@ -131,14 +128,14 @@ namespace OpenDiablo2.Core
if (!(equipment.LeftArm?.Item is Armor)) if (!(equipment.LeftArm?.Item is Armor))
return null; return null;
fileName += $"{equipment.LeftArm.Item.Code}{mobMode.ToToken()}"; fileName += $"{equipment.LeftArm.Item.Code}{mobMode.ToToken()}";
return mpqLookup.ContainsKey($"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower()) return _mpqLookup.ContainsKey($"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower())
? $"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower() ? $"{fileName}{equipment.WeaponClass.ToToken()}.dcc".ToLower()
: $"{fileName}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower(); : $"{fileName}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower();
// TODO: Figure these out... // TODO: Figure these out...
case eCompositType.Special1: case eCompositType.Special1:
case eCompositType.Special2: case eCompositType.Special2:
fileName += $"{equipment.ArmorType.ToToken()}{mobMode.ToToken()}{equipment.WeaponClass}.dcc".ToLower(); fileName += $"{equipment.ArmorType.ToToken()}{mobMode.ToToken()}{equipment.WeaponClass}.dcc".ToLower();
return mpqLookup.ContainsKey(fileName) return _mpqLookup.ContainsKey(fileName)
? fileName ? fileName
: null; // TODO: Should we silence this? : null; // TODO: Should we silence this?
case eCompositType.Special3: case eCompositType.Special3:

View File

@ -11,29 +11,32 @@ namespace OpenDiablo2.Core.Map_Engine
{ {
public sealed class MapEngine : IMapEngine public sealed class MapEngine : IMapEngine
{ {
private readonly IGameState gameState; private readonly IGameState _gameState;
private readonly IRenderWindow renderWindow; private readonly IRenderWindow _renderWindow;
private readonly List<ICharacterRenderer> characterRenderers = new List<ICharacterRenderer>(); private readonly List<ICharacterRenderer> _characterRenderers = new List<ICharacterRenderer>();
public int FocusedPlayerId { get; set; } = 0; public int FocusedPlayerId { get; set; } = 0;
private PointF cameraLocation = new PointF(); private PointF _cameraLocation = new PointF();
public PointF CameraLocation public PointF CameraLocation
{ {
get => cameraLocation; get => _cameraLocation;
set set
{ {
if (cameraLocation == value) // ReSharper disable once RedundantCheckBeforeAssignment (This is a false positive)
if (_cameraLocation == value)
return; return;
cameraLocation = value; _cameraLocation = value;
} }
} }
private const int private const int
cellSizeX = 160, CellSizeX = 160,
cellSizeY = 80; CellSizeY = 80,
CellSizeXHalf = 80,
CellSizeYHalf = 40;
public MapEngine( public MapEngine(
IGameState gameState, IGameState gameState,
@ -41,8 +44,8 @@ namespace OpenDiablo2.Core.Map_Engine
ISessionManager sessionManager ISessionManager sessionManager
) )
{ {
this.gameState = gameState; _gameState = gameState;
this.renderWindow = renderWindow; _renderWindow = renderWindow;
sessionManager.OnPlayerInfo += OnPlayerInfo; sessionManager.OnPlayerInfo += OnPlayerInfo;
sessionManager.OnLocatePlayers += OnLocatePlayers; sessionManager.OnLocatePlayers += OnLocatePlayers;
@ -52,7 +55,12 @@ namespace OpenDiablo2.Core.Map_Engine
{ {
foreach (var loc in playerLocationDetails) foreach (var loc in playerLocationDetails)
{ {
var cr = characterRenderers.FirstOrDefault(x => x.LocationDetails.PlayerId == loc.PlayerId); var cr = _characterRenderers.FirstOrDefault(x => x.LocationDetails.PlayerId == loc.PlayerId);
if (cr == null)
{
// TODO: Should we log this?
continue;
}
var newDirection = loc.MovementDirection != cr.LocationDetails.MovementDirection; var newDirection = loc.MovementDirection != cr.LocationDetails.MovementDirection;
var stanceChanged = loc.MovementType != cr.LocationDetails.MovementType; var stanceChanged = loc.MovementType != cr.LocationDetails.MovementType;
cr.LocationDetails = loc; cr.LocationDetails = loc;
@ -64,10 +72,10 @@ namespace OpenDiablo2.Core.Map_Engine
private void OnPlayerInfo(int clientHash, IEnumerable<PlayerInfo> playerInfo) private void OnPlayerInfo(int clientHash, IEnumerable<PlayerInfo> playerInfo)
{ {
// Remove character renderers for players that no longer exist... // Remove character renderers for players that no longer exist...
characterRenderers.RemoveAll(x => playerInfo.Any(z => z.UID == x.UID)); _characterRenderers.RemoveAll(x => playerInfo.Any(z => z.UID == x.UID));
// Update existing character renderers // Update existing character renderers
foreach (var cr in characterRenderers) foreach (var cr in _characterRenderers)
{ {
var info = playerInfo.FirstOrDefault(x => x.UID == cr.UID); var info = playerInfo.FirstOrDefault(x => x.UID == cr.UID);
if (info == null) if (info == null)
@ -82,67 +90,70 @@ namespace OpenDiablo2.Core.Map_Engine
} }
// Add character renderers for characters that now exist // Add character renderers for characters that now exist
foreach (var info in playerInfo.Where(x => !characterRenderers.Any(z => x.UID == z.UID))) foreach (var info in playerInfo.Where(x => _characterRenderers.All(z => x.UID != z.UID)).ToArray())
{ {
var cr = renderWindow.CreateCharacterRenderer(); var cr = _renderWindow.CreateCharacterRenderer();
cr.UID = info.UID; cr.UID = info.UID;
cr.LocationDetails = info.LocationDetails; cr.LocationDetails = info.LocationDetails;
cr.MobMode = info.MobMode; cr.MobMode = info.MobMode;
cr.Equipment = info.Equipment; cr.Equipment = info.Equipment;
cr.Hero = info.Hero; cr.Hero = info.Hero;
characterRenderers.Add(cr); _characterRenderers.Add(cr);
cr.ResetAnimationData(); cr.ResetAnimationData();
} }
} }
const int skewX = 400; private const int SkewX = 400;
const int skewY = 300; private const int SkewY = 300;
public void Render() public void Render()
{ {
var xOffset = gameState.CameraOffset; var xOffset = _gameState.CameraOffset;
var cx = -(cameraLocation.X - Math.Truncate(cameraLocation.X)); var cx = -(_cameraLocation.X - Math.Truncate(_cameraLocation.X));
var cy = -(cameraLocation.Y - Math.Truncate(cameraLocation.Y)); var cy = -(_cameraLocation.Y - Math.Truncate(_cameraLocation.Y));
for (int ty = -7; ty <= 9; ty++) for (var ty = -7; ty <= 9; ty++)
{ {
for (int tx = -8; tx <= 8; tx++) for (var tx = -8; tx <= 8; tx++)
{ {
var ax = tx + Math.Truncate(cameraLocation.X); var ax = (int)(tx + Math.Truncate(_cameraLocation.X));
var ay = ty + Math.Truncate(cameraLocation.Y); var ay = (int)(ty + Math.Truncate(_cameraLocation.Y));
var px = (tx - ty) * (cellSizeX / 2); var px = (tx - ty) * CellSizeXHalf;
var py = (tx + ty) * (cellSizeY / 2); var py = (tx + ty) * CellSizeYHalf;
var ox = (cx - cy) * (cellSizeX / 2); var ox = (cx - cy) * CellSizeXHalf;
var oy = (cx + cy) * (cellSizeY / 2); var oy = (cx + cy) * CellSizeYHalf;
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallLower)) foreach (var cellInfo in _gameState.GetMapCellInfo(ax, ay, eRenderCellType.WallLower))
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy + 80); _renderWindow.DrawMapCell(cellInfo, SkewX + px + (int)ox + xOffset, SkewY + py + (int)oy + 80);
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.Floor)) foreach (var cellInfo in _gameState.GetMapCellInfo(ax, ay, eRenderCellType.Floor))
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy); _renderWindow.DrawMapCell(cellInfo, SkewX + px + (int)ox + xOffset, SkewY + py + (int)oy);
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallNormal)) foreach (var cellInfo in _gameState.GetMapCellInfo(ax, ay, eRenderCellType.WallNormal))
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy + 80); _renderWindow.DrawMapCell(cellInfo, SkewX + px + (int)ox + xOffset, SkewY + py + (int)oy + 80);
foreach (var character in characterRenderers.Where(x => Math.Truncate(x.LocationDetails.PlayerX) == ax && Math.Truncate(x.LocationDetails.PlayerY) == ay)) foreach (var character in _characterRenderers.Where(x =>
(int)Math.Truncate(x.LocationDetails.PlayerX) == ax &&
(int)Math.Truncate(x.LocationDetails.PlayerY) == ay)
)
{ {
var ptx = character.LocationDetails.PlayerX - Math.Truncate(cameraLocation.X); var ptx = character.LocationDetails.PlayerX - Math.Truncate(_cameraLocation.X);
var pty = character.LocationDetails.PlayerY - Math.Truncate(cameraLocation.Y); var pty = character.LocationDetails.PlayerY - Math.Truncate(_cameraLocation.Y);
var ppx = (ptx - pty) * (cellSizeX / 2); var ppx = (int)((ptx - pty) * CellSizeXHalf);
var ppy = (ptx + pty) * (cellSizeY / 2); var ppy = (int)((ptx + pty) * CellSizeYHalf);
character.Render(skewX + (int)ppx + (int)ox + xOffset, skewY + (int)ppy + (int)oy); character.Render(SkewX + (int)ppx + (int)ox + xOffset, SkewY + (int)ppy + (int)oy);
} }
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.Roof)) foreach (var cellInfo in _gameState.GetMapCellInfo(ax, ay, eRenderCellType.Roof))
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy - 80); _renderWindow.DrawMapCell(cellInfo, SkewX + px + (int)ox + xOffset, SkewY + py + (int)oy - 80);
} }
} }
@ -154,18 +165,18 @@ namespace OpenDiablo2.Core.Map_Engine
public void Update(long ms) public void Update(long ms)
{ {
foreach (var character in characterRenderers) foreach (var character in _characterRenderers)
character.Update(ms); character.Update(ms);
if (FocusedPlayerId != 0) if (FocusedPlayerId == 0)
{ return;
var player = gameState.PlayerInfos.FirstOrDefault(x => x.LocationDetails.PlayerId == FocusedPlayerId);
if (player != null) var player = _gameState.PlayerInfos.FirstOrDefault(x => x.LocationDetails.PlayerId == FocusedPlayerId);
{ if (player == null)
// TODO: Maybe smooth movement? Maybe not? return;
CameraLocation = new PointF(player.LocationDetails.PlayerX, player.LocationDetails.PlayerY); CameraLocation = new PointF(player.LocationDetails.PlayerX, player.LocationDetails.PlayerY);
}
}
} }

View File

@ -189,8 +189,8 @@ namespace OpenDiablo2.SDL2_
{ {
var texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, frameW, frameH); var texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, frameW, frameH);
SDL.SDL_LockTexture(texture, IntPtr.Zero, out IntPtr pixels, out int pitch); SDL.SDL_LockTexture(texture, IntPtr.Zero, out var pixels, out var pitch);
UInt32* data = (UInt32*)pixels; var data = (UInt32*)pixels;
var priorityBase = (directionConversion[LocationDetails.MovementDirection] * animationData.FramesPerDirection * animationData.NumberOfLayers) var priorityBase = (directionConversion[LocationDetails.MovementDirection] * animationData.FramesPerDirection * animationData.NumberOfLayers)
+ (frameIndex * animationData.NumberOfLayers); + (frameIndex * animationData.NumberOfLayers);

View File

@ -11,7 +11,7 @@ namespace OpenDiablo2.TestConsole
static class Program static class Program
{ {
private static GlobalConfiguration GlobalConfig = null; private static GlobalConfiguration GlobalConfig = null;
private static MPQProvider MPQProv = null; private static MpqProvider MPQProv = null;
private static EngineDataManager EngineDataMan = null; private static EngineDataManager EngineDataMan = null;
static void Main(string[] args) static void Main(string[] args)
@ -126,7 +126,7 @@ namespace OpenDiablo2.TestConsole
BaseDataPath = Path.GetFullPath(path) BaseDataPath = Path.GetFullPath(path)
}; };
MPQProv = new MPQProvider(GlobalConfig); MPQProv = new MpqProvider(GlobalConfig);
EngineDataMan = new EngineDataManager(MPQProv); EngineDataMan = new EngineDataManager(MPQProv);
} }