1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-10-05 09:44:05 -04:00
OpenDiablo2/OpenDiablo2.Common/Models/MPQDS1.cs

341 lines
11 KiB
C#
Raw Normal View History

2018-11-24 03:07:41 -05:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenDiablo2.Common.Interfaces;
namespace OpenDiablo2.Common.Models
{
public sealed class MPQDS1TileProps
{
public byte Prop1 { get; internal set; }
public byte Prop2 { get; internal set; }
public byte Prop3 { get; internal set; }
public byte Prop4 { get; internal set; }
}
public sealed class MPQDS1WallOrientationTileProps
{
public byte Orientation1 { get; internal set; }
public byte Orientation2 { get; internal set; }
public byte Orientation3 { get; internal set; }
public byte Orientation4 { get; internal set; }
}
public sealed class MPQDS1WallLayer
{
public MPQDS1TileProps[] Props { get; internal set; }
public MPQDS1WallOrientationTileProps[] Orientations { get; internal set; }
}
public sealed class MPQDS1FloorLayer
{
public MPQDS1TileProps[] Props { get; internal set; }
}
public sealed class MPQDS1ShadowLayer
{
public MPQDS1TileProps[] Props { get; internal set; }
}
public sealed class MPQDS1Object
{
public Int32 Type { get; internal set; }
public Int32 Id { get; internal set; }
public Int32 X { get; internal set; }
public Int32 Y { get; internal set; }
public Int32 DS1Flags { get; internal set; }
2018-11-24 03:07:41 -05:00
}
2018-11-24 17:54:15 -05:00
public sealed class MPQDS1Group
{
public Int32 TileX { get; internal set; }
public Int32 TileY { get; internal set; }
public Int32 Width { get; internal set; }
public Int32 Height { get; internal set; }
}
2018-11-24 03:07:41 -05:00
public sealed class MPQDS1
{
static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public Int32 Version { get; internal set; }
public Int32 Width { get; internal set; }
public Int32 Height { get; internal set; }
public Int32 Act { get; internal set; } // ???
public Int32 TagType { get; internal set; } // ???
public Int32 FileCount { get; internal set; }
public Int32 NumberOfWalls { get; internal set; }
public Int32 NumberOfFloors { get; internal set; }
public Int32 NumberOfObjects { get; internal set; }
public Int32 NumberOfNPCs { get; internal set; }
2018-11-24 17:54:15 -05:00
public Int32 NumberOfTags { get; internal set; }
public Int32 NumberOfGroups { get; internal set; }
public MPQDT1[] DT1s = new MPQDT1[33];
2018-11-24 03:07:41 -05:00
public List<string> FileNames { get; internal set; } = new List<string>();
2018-11-24 17:54:15 -05:00
public MPQDS1WallLayer[] WallLayers { get; internal set; }
public MPQDS1FloorLayer[] FloorLayers { get; internal set; }
public MPQDS1ShadowLayer[] ShadowLayers { get; internal set; }
public MPQDS1Object[] Objects { get; internal set; }
public MPQDS1Group[] Groups { get; internal set; }
2018-11-24 03:07:41 -05:00
// TODO: DI magic please
public MPQDS1(Stream stream, LevelPreset level, LevelDetail levelDetail, LevelType levelType, IEngineDataManager engineDataManager, IResourceManager resourceManager)
2018-11-24 03:07:41 -05:00
{
log.Debug($"Loading {level.Name} (Act {levelDetail.Act})...");
2018-11-24 03:07:41 -05:00
var br = new BinaryReader(stream);
Version = br.ReadInt32();
Width = br.ReadInt32() + 1;
Height = br.ReadInt32() + 1;
2018-11-24 17:54:15 -05:00
Act = br.ReadInt32() + 1;
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
if (Version >= 10)
{
TagType = br.ReadInt32();
if (TagType == 1 || TagType == 2)
NumberOfTags = 1;
}
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
FileCount = 0;
if (Version >= 3)
{
FileCount = br.ReadInt32();
for (int i = 0; i < FileCount; i++)
{
var fn = "";
while (true)
{
var b = br.ReadByte();
if (b == 0)
break;
fn += (char)b;
}
if (fn.StartsWith("\\d2\\"))
fn = fn.Substring(4);
FileNames.Add(fn);
}
}
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
if (Version >= 9 && Version <= 13)
{
br.ReadBytes(8);
}
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
if (Version >= 4)
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
NumberOfWalls = br.ReadInt32();
if (Version >= 16)
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
NumberOfFloors = br.ReadInt32();
2018-11-24 03:07:41 -05:00
}
2018-11-24 17:54:15 -05:00
else NumberOfFloors = 1;
}
else
{
NumberOfFloors = 1;
NumberOfWalls = 1;
NumberOfTags = 1;
2018-11-24 03:07:41 -05:00
}
2018-11-24 17:54:15 -05:00
var layoutStream = new List<int>();
if (Version < 4)
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
layoutStream.AddRange(new int[] { 1, 9, 5, 12, 11 });
}
else
{
for (var x = 0; x < NumberOfWalls; x++)
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
layoutStream.Add(1 + x);
layoutStream.Add(5 + x);
}
for (var x = 0; x < NumberOfFloors; x++)
layoutStream.Add(9 + x);
layoutStream.Add(11);
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
if (NumberOfTags > 0)
layoutStream.Add(12);
}
WallLayers = new MPQDS1WallLayer[NumberOfWalls];
for (var l = 0; l < NumberOfWalls; l++)
{
WallLayers[l] = new MPQDS1WallLayer
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
Orientations = new MPQDS1WallOrientationTileProps[Width * Height],
Props = new MPQDS1TileProps[Width * Height]
};
}
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
FloorLayers = new MPQDS1FloorLayer[NumberOfFloors];
for (var l = 0; l < NumberOfFloors; l++)
{
FloorLayers[l] = new MPQDS1FloorLayer
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
Props = new MPQDS1TileProps[Width * Height]
};
2018-11-24 03:07:41 -05:00
}
2018-11-24 17:54:15 -05:00
ShadowLayers = new MPQDS1ShadowLayer[1];
for (var l = 0; l < 1; l++)
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
ShadowLayers[l] = new MPQDS1ShadowLayer
2018-11-24 03:07:41 -05:00
{
Props = new MPQDS1TileProps[Width * Height]
};
2018-11-24 17:54:15 -05:00
}
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
for (int n = 0; n < layoutStream.Count(); n++)
{
for (var y = 0; y < Height; y++)
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
for (var x = 0; x < Width; x++)
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
switch (layoutStream[n])
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
// Walls
case 1:
case 2:
case 3:
case 4:
WallLayers[layoutStream[n] - 1].Props[x + (y * Width)] = new MPQDS1TileProps
{
Prop1 = br.ReadByte(),
Prop2 = br.ReadByte(),
Prop3 = br.ReadByte(),
Prop4 = br.ReadByte()
};
break;
// Orientations
case 5:
case 6:
case 7:
case 8:
// TODO: Orientations
if (Version < 7)
{
br.ReadBytes(4);
}
else
{
br.ReadBytes(4);
}
break;
// Floors
case 9:
case 10:
FloorLayers[layoutStream[n] - 9].Props[x + (y * Width)] = new MPQDS1TileProps
{
Prop1 = br.ReadByte(),
Prop2 = br.ReadByte(),
Prop3 = br.ReadByte(),
Prop4 = br.ReadByte()
};
break;
// Shadow
case 11:
ShadowLayers[layoutStream[n] - 11].Props[x + (y * Width)] = new MPQDS1TileProps
{
Prop1 = br.ReadByte(),
Prop2 = br.ReadByte(),
Prop3 = br.ReadByte(),
Prop4 = br.ReadByte()
};
break;
// Tags
case 12:
// TODO: Tags
br.ReadBytes(4);
break;
}
2018-11-24 03:07:41 -05:00
}
}
}
2018-11-24 17:54:15 -05:00
/*
NumberOfObjects = 0;
if (Version >= 2)
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
NumberOfObjects = br.ReadInt32();
Objects = new MPQDS1Object[NumberOfObjects];
for (int i = 0; i < NumberOfObjects; i++)
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
Objects[i] = new MPQDS1Object
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
Type = br.ReadInt32(),
Id = br.ReadInt32(),
X = br.ReadInt32(),
Y = br.ReadInt32()
2018-11-24 03:07:41 -05:00
};
2018-11-24 17:54:15 -05:00
if (Version > 5)
Objects[i].DS1Flags = br.ReadInt32();
2018-11-24 03:07:41 -05:00
}
}
2018-11-24 17:54:15 -05:00
if (Version >= 12 && TagType == 1 || TagType == 2)
2018-11-24 03:07:41 -05:00
{
2018-11-24 17:54:15 -05:00
if (Version >= 18)
br.ReadBytes(4);
NumberOfGroups = br.ReadInt32();
2018-11-24 03:07:41 -05:00
}
2018-11-24 17:54:15 -05:00
else NumberOfGroups = 0;
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
Groups = new MPQDS1Group[NumberOfGroups];
for (var x = 0; x < NumberOfGroups; x++)
{
Groups[x] = new MPQDS1Group
{
TileX = br.ReadInt32(),
TileY = br.ReadInt32(),
Width = br.ReadInt32(),
Height = br.ReadInt32(),
};
if (Version >= 13)
br.ReadBytes(4);
}
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
if (Version >= 14)
{
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
NumberOfNPCs = br.ReadInt32();
}*/
2018-11-24 03:07:41 -05:00
2018-11-24 18:54:32 -05:00
2018-11-24 03:07:41 -05:00
2018-11-24 17:54:15 -05:00
var dt1Mask = level.Dt1Mask;
2018-11-24 03:07:41 -05:00
for (int i = 0; i < 32; i++)
{
var tilePath = levelType.File[i];
var isMasked = ((dt1Mask >> i) & 1) == 1;
if (!isMasked)
continue;
log.Debug($"Loading DT resource {levelType.File[i]}");
DT1s[i] = resourceManager.GetMPQDT1("data\\global\\tiles\\" + levelType.File[i].Replace("/", "\\"));
2018-11-24 18:54:32 -05:00
2018-11-24 03:07:41 -05:00
}
}
}
}