mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-03 07:07:25 -05:00
Minor cleanup. Added object and object type data dictionaries. Map loader now includes object and tag data
This commit is contained in:
parent
f56273a4a2
commit
c85b2bc605
@ -1,8 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces.Mobs;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace OpenDiablo2.Common.Interfaces
|
||||
{
|
||||
@ -16,5 +15,6 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
ImmutableDictionary<eHero, IHeroTypeConfig> HeroTypeConfigs { get; }
|
||||
ImmutableList<IEnemyTypeConfig> EnemyTypeConfigs { get; }
|
||||
ImmutableList<ObjectInfo> Objects { get; }
|
||||
ImmutableList<ObjectTypeInfo> ObjectTypes { get; }
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using OpenDiablo2.Common.Exceptions;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
|
||||
namespace OpenDiablo2.Common.Models
|
||||
@ -40,6 +42,11 @@ namespace OpenDiablo2.Common.Models
|
||||
public MPQDS1TileProps[] Props { get; internal set; }
|
||||
}
|
||||
|
||||
public sealed class MPQDS1TagLayer
|
||||
{
|
||||
public Int32 Number { get; internal set; }
|
||||
}
|
||||
|
||||
public sealed class MPQDS1Object
|
||||
{
|
||||
public Int32 Type { get; internal set; }
|
||||
@ -47,6 +54,7 @@ namespace OpenDiablo2.Common.Models
|
||||
public Int32 X { get; internal set; }
|
||||
public Int32 Y { get; internal set; }
|
||||
public Int32 DS1Flags { get; internal set; }
|
||||
public ObjectInfo Info { get; internal set; }
|
||||
}
|
||||
|
||||
public sealed class MPQDS1Group
|
||||
@ -92,6 +100,7 @@ namespace OpenDiablo2.Common.Models
|
||||
public MPQDS1WallLayer[] WallLayers { get; internal set; }
|
||||
public MPQDS1FloorLayer[] FloorLayers { get; internal set; }
|
||||
public MPQDS1ShadowLayer[] ShadowLayers { get; internal set; }
|
||||
public MPQDS1TagLayer[] TagLayers { get; internal set; }
|
||||
public MPQDS1Object[] Objects { get; internal set; }
|
||||
public MPQDS1Group[] Groups { get; internal set; }
|
||||
|
||||
@ -125,7 +134,7 @@ namespace OpenDiablo2.Common.Models
|
||||
fn.Append((char)b);
|
||||
}
|
||||
var fnStr = fn.ToString();
|
||||
if (fnStr.StartsWith("\\d2\\"))
|
||||
if (fnStr.StartsWith(@"\d2\"))
|
||||
fnStr = fnStr.Substring(4);
|
||||
FileNames.Add(fnStr);
|
||||
}
|
||||
@ -139,12 +148,7 @@ namespace OpenDiablo2.Common.Models
|
||||
if (Version >= 4)
|
||||
{
|
||||
NumberOfWalls = br.ReadInt32();
|
||||
|
||||
if (Version >= 16)
|
||||
{
|
||||
NumberOfFloors = br.ReadInt32();
|
||||
}
|
||||
else NumberOfFloors = 1;
|
||||
NumberOfFloors = Version >= 16 ? br.ReadInt32() : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -159,7 +163,7 @@ namespace OpenDiablo2.Common.Models
|
||||
|
||||
if (Version < 4)
|
||||
{
|
||||
layoutStream.AddRange(new int[] { 1, 9, 5, 12, 11 });
|
||||
layoutStream.AddRange(new[] { 1, 9, 5, 12, 11 });
|
||||
}
|
||||
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 x = 0; x < Width; x++)
|
||||
{
|
||||
switch (layoutStream[n])
|
||||
switch (idx)
|
||||
{
|
||||
// Walls
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
WallLayers[layoutStream[n] - 1].Props[x + (y * Width)] = new MPQDS1TileProps
|
||||
WallLayers[idx - 1].Props[x + (y * Width)] = new MPQDS1TileProps
|
||||
{
|
||||
Prop1 = br.ReadByte(),
|
||||
Prop2 = br.ReadByte(),
|
||||
@ -240,7 +250,7 @@ namespace OpenDiablo2.Common.Models
|
||||
}
|
||||
else
|
||||
{
|
||||
WallLayers[layoutStream[n] - 5].Orientations[x + (y * Width)] = new MPQDS1WallOrientationTileProps
|
||||
WallLayers[idx - 5].Orientations[x + (y * Width)] = new MPQDS1WallOrientationTileProps
|
||||
{
|
||||
Orientation1 = br.ReadByte(),
|
||||
Orientation2 = br.ReadByte(),
|
||||
@ -253,7 +263,7 @@ namespace OpenDiablo2.Common.Models
|
||||
// Floors
|
||||
case 9:
|
||||
case 10:
|
||||
FloorLayers[layoutStream[n] - 9].Props[x + (y * Width)] = new MPQDS1TileProps
|
||||
FloorLayers[idx - 9].Props[x + (y * Width)] = new MPQDS1TileProps
|
||||
{
|
||||
Prop1 = br.ReadByte(),
|
||||
Prop2 = br.ReadByte(),
|
||||
@ -263,7 +273,7 @@ namespace OpenDiablo2.Common.Models
|
||||
break;
|
||||
// Shadow
|
||||
case 11:
|
||||
ShadowLayers[layoutStream[n] - 11].Props[x + (y * Width)] = new MPQDS1TileProps
|
||||
ShadowLayers[idx - 11].Props[x + (y * Width)] = new MPQDS1TileProps
|
||||
{
|
||||
Prop1 = br.ReadByte(),
|
||||
Prop2 = br.ReadByte(),
|
||||
@ -273,32 +283,80 @@ namespace OpenDiablo2.Common.Models
|
||||
break;
|
||||
// Tags
|
||||
case 12:
|
||||
// TODO: Tags
|
||||
br.ReadBytes(4);
|
||||
TagLayers[idx - 12].Number = br.ReadInt32();
|
||||
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;
|
||||
for (int i = 0; i < 32; i++)
|
||||
for (var i = 0; i < 32; i++)
|
||||
{
|
||||
var isMasked = ((dt1Mask >> i) & 1) == 1;
|
||||
if (!isMasked || levelType.File[i] == "0")
|
||||
continue;
|
||||
|
||||
DT1s[i] = resourceManager.GetMPQDT1("data\\global\\tiles\\" + levelType.File[i].Replace("/", "\\"));
|
||||
DT1s[i] = resourceManager.GetMPQDT1(@"data\global\tiles\" + levelType.File[i].Replace("/", "\\"));
|
||||
}
|
||||
|
||||
|
||||
LookupTable = new List<DS1LookupTable>();
|
||||
foreach(var dt1 in DT1s.Where(x => x != null))
|
||||
foreach (var dt1 in DT1s.Where(x => x != null))
|
||||
{
|
||||
foreach(var tile in dt1.Tiles)
|
||||
foreach (var tile in dt1.Tiles)
|
||||
{
|
||||
LookupTable.Add(new DS1LookupTable
|
||||
{
|
||||
@ -311,7 +369,8 @@ namespace OpenDiablo2.Common.Models
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ namespace OpenDiablo2.Common.Models
|
||||
public Int32 X2 { get; private set; }
|
||||
public Int32 NumberOfTiles { get; private set; }
|
||||
public MPQDT1Tile[] Tiles { get; private set; }
|
||||
private readonly Int32 tileHeaderOffset;
|
||||
private readonly Int32 _tileHeaderOffset;
|
||||
|
||||
public MPQDT1(Stream stream)
|
||||
{
|
||||
@ -58,19 +58,19 @@ namespace OpenDiablo2.Common.Models
|
||||
stream.Seek(268, SeekOrigin.Begin); // Skip useless header info
|
||||
|
||||
NumberOfTiles = br.ReadInt32();
|
||||
tileHeaderOffset = br.ReadInt32();
|
||||
|
||||
_tileHeaderOffset = br.ReadInt32();
|
||||
|
||||
ReadTiles(br);
|
||||
ReadBlockHeaders(br);
|
||||
ReadBlockGraphics(br);
|
||||
|
||||
|
||||
}
|
||||
private void ReadTiles(BinaryReader br)
|
||||
{
|
||||
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();
|
||||
var tile = Tiles[tileIndex];
|
||||
|
||||
@ -86,7 +86,7 @@ namespace OpenDiablo2.Common.Models
|
||||
tile.SubIndex = br.ReadInt32();
|
||||
tile.RarityOrFrameIndex = br.ReadInt32();
|
||||
br.ReadBytes(4);
|
||||
for (int i = 0; i < 25; i++)
|
||||
for (var i = 0; i < 25; i++)
|
||||
tile.SubTileFlags[i] = br.ReadByte();
|
||||
br.ReadBytes(7);
|
||||
tile.BlockHeadersPointer = br.ReadInt32();
|
||||
@ -99,12 +99,12 @@ namespace OpenDiablo2.Common.Models
|
||||
|
||||
private void ReadBlockHeaders(BinaryReader br)
|
||||
{
|
||||
for (int tileIndex = 0; tileIndex < NumberOfTiles; tileIndex++)
|
||||
for (var tileIndex = 0; tileIndex < NumberOfTiles; tileIndex++)
|
||||
{
|
||||
var tile = Tiles[tileIndex];
|
||||
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);
|
||||
|
||||
@ -126,9 +126,9 @@ namespace OpenDiablo2.Common.Models
|
||||
|
||||
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];
|
||||
br.BaseStream.Seek(Tiles[tileIndex].BlockHeadersPointer + block.FileOffset, SeekOrigin.Begin);
|
||||
@ -139,17 +139,13 @@ namespace OpenDiablo2.Common.Models
|
||||
if (block.Length != 256)
|
||||
throw new OpenDiablo2Exception($"Expected exactly 256 bytes of data, but got {block.Length} instead!");
|
||||
|
||||
int x = 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 y = 0;
|
||||
var length = 256;
|
||||
block.PixelData = new Int16[32 * 32];
|
||||
while (length > 0)
|
||||
{
|
||||
x = xjump[y];
|
||||
n = nbpix[y];
|
||||
var x = new[] { 14, 12, 10, 8, 6, 4, 2, 0, 2, 4, 6, 8, 10, 12, 14 }[y];
|
||||
var n = new[] { 4, 8, 12, 16, 20, 24, 28, 32, 28, 24, 20, 16, 12, 8, 4 }[y];
|
||||
length -= n;
|
||||
while (n > 0)
|
||||
{
|
||||
@ -165,15 +161,13 @@ namespace OpenDiablo2.Common.Models
|
||||
{
|
||||
// RLE block
|
||||
var length = block.Length;
|
||||
byte b1;
|
||||
byte b2;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
block.PixelData = new Int16[32 * 32];
|
||||
while (length > 0)
|
||||
{
|
||||
b1 = br.ReadByte();
|
||||
b2 = br.ReadByte();
|
||||
var b1 = br.ReadByte();
|
||||
var b2 = br.ReadByte();
|
||||
length -= 2;
|
||||
if (b1 + b2 == 0)
|
||||
{
|
||||
|
21
OpenDiablo2.Common/Models/ObjectTypeInfo.cs
Normal file
21
OpenDiablo2.Common/Models/ObjectTypeInfo.cs
Normal 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 };
|
||||
}
|
||||
}
|
@ -121,6 +121,7 @@
|
||||
<Compile Include="Models\MPQDCC.cs" />
|
||||
<Compile Include="Models\ItemContainerLayout.cs" />
|
||||
<Compile Include="Models\ObjectInfo.cs" />
|
||||
<Compile Include="Models\ObjectTypeInfo.cs" />
|
||||
<Compile Include="Models\PlayerInfo.cs" />
|
||||
<Compile Include="Models\PlayerLocationDetails.cs" />
|
||||
<Compile Include="Interfaces\UI\IButton.cs" />
|
||||
|
@ -45,7 +45,7 @@ namespace OpenDiablo2.Core
|
||||
builder.RegisterType<InventoryPanel>().AsImplementedInterfaces().InstancePerDependency();
|
||||
builder.RegisterType<SkillsPanel>().AsImplementedInterfaces().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<TextDictionary>().As<ITextDictionary>().SingleInstance();
|
||||
builder.RegisterType<TextBox>().As<ITextBox>().InstancePerDependency();
|
||||
|
@ -23,6 +23,7 @@ namespace OpenDiablo2.Core
|
||||
public ImmutableList<LevelPreset> LevelPresets { get; internal set; }
|
||||
public ImmutableList<LevelType> LevelTypes { 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 ImmutableDictionary<eHero, ILevelExperienceConfig> ExperienceConfigs { get; internal set; }
|
||||
@ -83,6 +84,18 @@ namespace OpenDiablo2.Core
|
||||
.Where(x => x.Count() > 150 && x[0] != "Expansion")
|
||||
.Select(x => x.ToObjectInfo())
|
||||
.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()
|
||||
|
@ -26,15 +26,15 @@ namespace OpenDiablo2.Core.GameState_
|
||||
private readonly Func<eSessionType, ISessionManager> getSessionManager;
|
||||
private readonly Func<string, IRandomizedMapGenerator> getRandomizedMapGenerator;
|
||||
|
||||
private float animationTime = 0f;
|
||||
private float animationTime;
|
||||
private List<IMapInfo> mapInfo;
|
||||
private readonly List<MapCellInfo> mapDataLookup = new List<MapCellInfo>();
|
||||
private readonly List<MapCellInfo> mapDataLookup;
|
||||
private ISessionManager sessionManager;
|
||||
|
||||
public int Act { get; private set; }
|
||||
public string MapName { get; private set; }
|
||||
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;
|
||||
|
||||
@ -74,7 +74,8 @@ namespace OpenDiablo2.Core.GameState_
|
||||
this.getRandomizedMapGenerator = getRandomizedMapGenerator;
|
||||
|
||||
originalMouseCursor = renderWindow.MouseCursor;
|
||||
|
||||
PlayerInfos = new List<PlayerInfo>();
|
||||
mapDataLookup = new List<MapCellInfo>();
|
||||
}
|
||||
|
||||
public void Initialize(string characterName, eHero hero, eSessionType sessionType)
|
||||
@ -88,8 +89,8 @@ namespace OpenDiablo2.Core.GameState_
|
||||
sessionManager.OnFocusOnPlayer += OnFocusOnPlayer;
|
||||
|
||||
mapInfo = new List<IMapInfo>();
|
||||
|
||||
sceneManager.ChangeScene(eSceneType.Game);
|
||||
|
||||
sessionManager.JoinGame(characterName, hero);
|
||||
}
|
||||
|
||||
@ -97,7 +98,7 @@ namespace OpenDiablo2.Core.GameState_
|
||||
=> getMapEngine().FocusedPlayerId = playerId;
|
||||
|
||||
private void OnPlayerInfo(int clientHash, IEnumerable<PlayerInfo> playerInfo)
|
||||
=> this.PlayerInfos = playerInfo.ToList();
|
||||
=> PlayerInfos = playerInfo.ToList();
|
||||
|
||||
private void OnLocatePlayers(int clientHash, IEnumerable<PlayerLocationDetails> playerLocationDetails)
|
||||
{
|
||||
@ -203,9 +204,12 @@ namespace OpenDiablo2.Core.GameState_
|
||||
|
||||
|
||||
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
|
||||
var mapName = "data\\global\\tiles\\" + mapNames[0].Replace("/", "\\");
|
||||
// -------------------------------------------------------------------------------------
|
||||
MapName = levelDetails.LevelPreset.Name;
|
||||
Act = levelDetails.LevelType.Act;
|
||||
|
||||
@ -270,15 +274,23 @@ namespace OpenDiablo2.Core.GameState_
|
||||
private IMapInfo GetMap(ref int cellX, ref int cellY)
|
||||
{
|
||||
var p = new Point(cellX, cellY);
|
||||
var map = mapInfo.LastOrDefault(z => z.TileLocation.Contains(p));
|
||||
if (map == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
cellX -= map.TileLocation.X;
|
||||
cellY -= map.TileLocation.Y;
|
||||
return map;
|
||||
IMapInfo mi = null;
|
||||
for (var i = mapInfo.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (mapInfo[i].TileLocation.Contains(p))
|
||||
{
|
||||
mi = mapInfo[i];
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (mi == null)
|
||||
return null;
|
||||
|
||||
cellX -= mi.TileLocation.X;
|
||||
cellY -= mi.TileLocation.Y;
|
||||
return mi;
|
||||
}
|
||||
|
||||
public void UpdateMapCellInfo(int cellX, int cellY, eRenderCellType renderCellType, IEnumerable<MapCellInfo> mapCellInfo)
|
||||
@ -294,9 +306,8 @@ namespace OpenDiablo2.Core.GameState_
|
||||
}
|
||||
else
|
||||
{
|
||||
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));
|
||||
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));
|
||||
}
|
||||
|
||||
this.SelectedItem = item;
|
||||
@ -317,8 +328,8 @@ namespace OpenDiablo2.Core.GameState_
|
||||
if (cellInfo != null && (cellInfo.Ignore || !cellInfo.Tile.Animated))
|
||||
return cellInfo.Ignore ? null : cellInfo;
|
||||
|
||||
var main_index = (props.Prop3 >> 4) + ((props.Prop4 & 0x03) << 4);
|
||||
var sub_index = props.Prop2;
|
||||
var mainIndex = (props.Prop3 >> 4) + ((props.Prop4 & 0x03) << 4);
|
||||
var subIndex = props.Prop2;
|
||||
|
||||
if (orientation == 0)
|
||||
{
|
||||
@ -375,15 +386,14 @@ namespace OpenDiablo2.Core.GameState_
|
||||
}
|
||||
}
|
||||
|
||||
int frame = 0;
|
||||
IEnumerable<MPQDT1Tile> tiles = Enumerable.Empty<MPQDT1Tile>();
|
||||
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);
|
||||
|
||||
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 };
|
||||
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)
|
||||
{
|
||||
mapCellInfo = renderWindow.CacheMapCell(tile, cellType);
|
||||
|
@ -27,45 +27,52 @@ using System.Linq;
|
||||
|
||||
namespace OpenDiablo2.Core
|
||||
{
|
||||
public sealed class MPQProvider : IMPQProvider
|
||||
public sealed class MpqProvider : IMPQProvider
|
||||
{
|
||||
private readonly IList<MPQ> mpqs;
|
||||
private readonly Dictionary<string, int> mpqLookup = new Dictionary<string, int>();
|
||||
private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private readonly IList<MPQ> _mpqs;
|
||||
private readonly Dictionary<string, int> _mpqLookup = new Dictionary<string, int>();
|
||||
|
||||
public MPQProvider(GlobalConfiguration globalConfiguration)
|
||||
public MpqProvider(GlobalConfiguration globalConfiguration)
|
||||
{
|
||||
// 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")
|
||||
.Where(x => !Path.GetFileName(x).StartsWith("patch"))
|
||||
.Where(x => !(Path.GetFileName(x)?.StartsWith("patch") ?? false))
|
||||
.Select(file => new MPQ(file))
|
||||
.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
|
||||
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;
|
||||
|
||||
foreach(var file in mpqs[i].Files)
|
||||
{
|
||||
mpqLookup[file.ToLower()] = i;
|
||||
}
|
||||
foreach(var file in _mpqs[i].Files)
|
||||
_mpqLookup[file.ToLower()] = i;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
foreach (var file in mpqs[i].Files)
|
||||
{
|
||||
mpqLookup[file.ToLower()] = i;
|
||||
}
|
||||
foreach (var file in _mpqs[i].Files)
|
||||
_mpqLookup[file.ToLower()] = i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,36 +84,26 @@ namespace OpenDiablo2.Core
|
||||
return result;
|
||||
}
|
||||
|
||||
public IEnumerator<MPQ> GetEnumerator()
|
||||
{
|
||||
return mpqs.GetEnumerator();
|
||||
}
|
||||
public IEnumerator<MPQ> GetEnumerator() => _mpqs.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
public Stream GetStream(string fileName)
|
||||
{
|
||||
if (!mpqLookup.ContainsKey(fileName.ToLower()))
|
||||
return null;
|
||||
public Stream GetStream(string fileName) => !_mpqLookup.ContainsKey(fileName.ToLower())
|
||||
? null
|
||||
: _mpqs[_mpqLookup[fileName.ToLower()]].OpenFile(fileName);
|
||||
|
||||
return mpqs[mpqLookup[fileName.ToLower()]].OpenFile(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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
case eCompositType.Head:
|
||||
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}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower();
|
||||
case eCompositType.Torso:
|
||||
@ -114,7 +111,7 @@ namespace OpenDiablo2.Core
|
||||
case eCompositType.RightArm:
|
||||
case eCompositType.LeftArm:
|
||||
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}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower();
|
||||
case eCompositType.RightHand:
|
||||
@ -131,14 +128,14 @@ namespace OpenDiablo2.Core
|
||||
if (!(equipment.LeftArm?.Item is Armor))
|
||||
return null;
|
||||
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}{eWeaponClass.HandToHand.ToToken()}.dcc".ToLower();
|
||||
// TODO: Figure these out...
|
||||
case eCompositType.Special1:
|
||||
case eCompositType.Special2:
|
||||
fileName += $"{equipment.ArmorType.ToToken()}{mobMode.ToToken()}{equipment.WeaponClass}.dcc".ToLower();
|
||||
return mpqLookup.ContainsKey(fileName)
|
||||
return _mpqLookup.ContainsKey(fileName)
|
||||
? fileName
|
||||
: null; // TODO: Should we silence this?
|
||||
case eCompositType.Special3:
|
||||
|
@ -11,29 +11,32 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
{
|
||||
public sealed class MapEngine : IMapEngine
|
||||
{
|
||||
private readonly IGameState gameState;
|
||||
private readonly IRenderWindow renderWindow;
|
||||
private readonly IGameState _gameState;
|
||||
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;
|
||||
|
||||
private PointF cameraLocation = new PointF();
|
||||
private PointF _cameraLocation = new PointF();
|
||||
public PointF CameraLocation
|
||||
{
|
||||
get => cameraLocation;
|
||||
get => _cameraLocation;
|
||||
set
|
||||
{
|
||||
if (cameraLocation == value)
|
||||
// ReSharper disable once RedundantCheckBeforeAssignment (This is a false positive)
|
||||
if (_cameraLocation == value)
|
||||
return;
|
||||
|
||||
cameraLocation = value;
|
||||
_cameraLocation = value;
|
||||
}
|
||||
}
|
||||
|
||||
private const int
|
||||
cellSizeX = 160,
|
||||
cellSizeY = 80;
|
||||
CellSizeX = 160,
|
||||
CellSizeY = 80,
|
||||
CellSizeXHalf = 80,
|
||||
CellSizeYHalf = 40;
|
||||
|
||||
public MapEngine(
|
||||
IGameState gameState,
|
||||
@ -41,8 +44,8 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
ISessionManager sessionManager
|
||||
)
|
||||
{
|
||||
this.gameState = gameState;
|
||||
this.renderWindow = renderWindow;
|
||||
_gameState = gameState;
|
||||
_renderWindow = renderWindow;
|
||||
|
||||
sessionManager.OnPlayerInfo += OnPlayerInfo;
|
||||
sessionManager.OnLocatePlayers += OnLocatePlayers;
|
||||
@ -52,7 +55,12 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
{
|
||||
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 stanceChanged = loc.MovementType != cr.LocationDetails.MovementType;
|
||||
cr.LocationDetails = loc;
|
||||
@ -64,10 +72,10 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
private void OnPlayerInfo(int clientHash, IEnumerable<PlayerInfo> playerInfo)
|
||||
{
|
||||
// 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
|
||||
foreach (var cr in characterRenderers)
|
||||
foreach (var cr in _characterRenderers)
|
||||
{
|
||||
var info = playerInfo.FirstOrDefault(x => x.UID == cr.UID);
|
||||
if (info == null)
|
||||
@ -82,67 +90,70 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
}
|
||||
|
||||
// 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.LocationDetails = info.LocationDetails;
|
||||
cr.MobMode = info.MobMode;
|
||||
cr.Equipment = info.Equipment;
|
||||
cr.Hero = info.Hero;
|
||||
characterRenderers.Add(cr);
|
||||
_characterRenderers.Add(cr);
|
||||
cr.ResetAnimationData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const int skewX = 400;
|
||||
const int skewY = 300;
|
||||
private const int SkewX = 400;
|
||||
private const int SkewY = 300;
|
||||
|
||||
public void Render()
|
||||
{
|
||||
var xOffset = gameState.CameraOffset;
|
||||
var xOffset = _gameState.CameraOffset;
|
||||
|
||||
var cx = -(cameraLocation.X - Math.Truncate(cameraLocation.X));
|
||||
var cy = -(cameraLocation.Y - Math.Truncate(cameraLocation.Y));
|
||||
var cx = -(_cameraLocation.X - Math.Truncate(_cameraLocation.X));
|
||||
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 ay = ty + Math.Truncate(cameraLocation.Y);
|
||||
var ax = (int)(tx + Math.Truncate(_cameraLocation.X));
|
||||
var ay = (int)(ty + Math.Truncate(_cameraLocation.Y));
|
||||
|
||||
var px = (tx - ty) * (cellSizeX / 2);
|
||||
var py = (tx + ty) * (cellSizeY / 2);
|
||||
var px = (tx - ty) * CellSizeXHalf;
|
||||
var py = (tx + ty) * CellSizeYHalf;
|
||||
|
||||
var ox = (cx - cy) * (cellSizeX / 2);
|
||||
var oy = (cx + cy) * (cellSizeY / 2);
|
||||
var ox = (cx - cy) * CellSizeXHalf;
|
||||
var oy = (cx + cy) * CellSizeYHalf;
|
||||
|
||||
|
||||
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallLower))
|
||||
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy + 80);
|
||||
foreach (var cellInfo in _gameState.GetMapCellInfo(ax, ay, eRenderCellType.WallLower))
|
||||
_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))
|
||||
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy);
|
||||
foreach (var cellInfo in _gameState.GetMapCellInfo(ax, ay, eRenderCellType.Floor))
|
||||
_renderWindow.DrawMapCell(cellInfo, SkewX + px + (int)ox + xOffset, SkewY + py + (int)oy);
|
||||
|
||||
|
||||
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallNormal))
|
||||
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy + 80);
|
||||
foreach (var cellInfo in _gameState.GetMapCellInfo(ax, ay, eRenderCellType.WallNormal))
|
||||
_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 pty = character.LocationDetails.PlayerY - Math.Truncate(cameraLocation.Y);
|
||||
var ptx = character.LocationDetails.PlayerX - Math.Truncate(_cameraLocation.X);
|
||||
var pty = character.LocationDetails.PlayerY - Math.Truncate(_cameraLocation.Y);
|
||||
|
||||
var ppx = (ptx - pty) * (cellSizeX / 2);
|
||||
var ppy = (ptx + pty) * (cellSizeY / 2);
|
||||
var ppx = (int)((ptx - pty) * CellSizeXHalf);
|
||||
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))
|
||||
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy - 80);
|
||||
foreach (var cellInfo in _gameState.GetMapCellInfo(ax, ay, eRenderCellType.Roof))
|
||||
_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)
|
||||
{
|
||||
foreach (var character in characterRenderers)
|
||||
foreach (var character in _characterRenderers)
|
||||
character.Update(ms);
|
||||
|
||||
if (FocusedPlayerId != 0)
|
||||
{
|
||||
var player = gameState.PlayerInfos.FirstOrDefault(x => x.LocationDetails.PlayerId == FocusedPlayerId);
|
||||
if (player != null)
|
||||
{
|
||||
// TODO: Maybe smooth movement? Maybe not?
|
||||
CameraLocation = new PointF(player.LocationDetails.PlayerX, player.LocationDetails.PlayerY);
|
||||
}
|
||||
}
|
||||
if (FocusedPlayerId == 0)
|
||||
return;
|
||||
|
||||
var player = _gameState.PlayerInfos.FirstOrDefault(x => x.LocationDetails.PlayerId == FocusedPlayerId);
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
CameraLocation = new PointF(player.LocationDetails.PlayerX, player.LocationDetails.PlayerY);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
SDL.SDL_LockTexture(texture, IntPtr.Zero, out IntPtr pixels, out int pitch);
|
||||
UInt32* data = (UInt32*)pixels;
|
||||
SDL.SDL_LockTexture(texture, IntPtr.Zero, out var pixels, out var pitch);
|
||||
var data = (UInt32*)pixels;
|
||||
|
||||
var priorityBase = (directionConversion[LocationDetails.MovementDirection] * animationData.FramesPerDirection * animationData.NumberOfLayers)
|
||||
+ (frameIndex * animationData.NumberOfLayers);
|
||||
|
@ -11,7 +11,7 @@ namespace OpenDiablo2.TestConsole
|
||||
static class Program
|
||||
{
|
||||
private static GlobalConfiguration GlobalConfig = null;
|
||||
private static MPQProvider MPQProv = null;
|
||||
private static MpqProvider MPQProv = null;
|
||||
private static EngineDataManager EngineDataMan = null;
|
||||
|
||||
static void Main(string[] args)
|
||||
@ -126,7 +126,7 @@ namespace OpenDiablo2.TestConsole
|
||||
BaseDataPath = Path.GetFullPath(path)
|
||||
};
|
||||
|
||||
MPQProv = new MPQProvider(GlobalConfig);
|
||||
MPQProv = new MpqProvider(GlobalConfig);
|
||||
|
||||
EngineDataMan = new EngineDataManager(MPQProv);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user