mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2025-01-10 14:53:00 +08:00
Added parsing of distantlights dat files
This commit is contained in:
parent
c45f170de4
commit
2bd5cacaf1
326
CodeWalker.Core/GameFiles/FileTypes/DistantLightsFile.cs
Normal file
326
CodeWalker.Core/GameFiles/FileTypes/DistantLightsFile.cs
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
using SharpDX;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using TC = System.ComponentModel.TypeConverterAttribute;
|
||||||
|
using EXP = System.ComponentModel.ExpandableObjectConverter;
|
||||||
|
|
||||||
|
namespace CodeWalker.GameFiles
|
||||||
|
{
|
||||||
|
[TC(typeof(EXP))] public class DistantLightsFile : GameFile, PackedFile
|
||||||
|
{
|
||||||
|
public bool HD { get; set; } = true;
|
||||||
|
public uint GridSize { get; set; } = 32;
|
||||||
|
public uint CellSize { get; set; } = 512;
|
||||||
|
public uint CellCount { get; set; } = 1024;
|
||||||
|
public uint NodeCount { get; set; }
|
||||||
|
public uint PathCount { get; set; }
|
||||||
|
public uint[] PathIndices { get; set; } //CellCount
|
||||||
|
public uint[] PathCounts1 { get; set; } //CellCount
|
||||||
|
public uint[] PathCounts2 { get; set; } //CellCount
|
||||||
|
public DistantLightsNode[] Nodes { get; set; } //NodeCount
|
||||||
|
public DistantLightsPath[] Paths { get; set; } //PathCount
|
||||||
|
public DistantLightsCell[] Cells { get; set; } //CellCount (built from loaded data)
|
||||||
|
|
||||||
|
|
||||||
|
public DistantLightsFile() : base(null, GameFileType.DistantLights)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public DistantLightsFile(RpfFileEntry entry) : base(entry, GameFileType.DistantLights)
|
||||||
|
{
|
||||||
|
RpfFileEntry = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Load(byte[] data, RpfFileEntry entry)
|
||||||
|
{
|
||||||
|
if (entry != null)
|
||||||
|
{
|
||||||
|
RpfFileEntry = entry;
|
||||||
|
Name = entry.Name;
|
||||||
|
|
||||||
|
if (!entry.NameLower.EndsWith("_hd.dat"))
|
||||||
|
{
|
||||||
|
HD = false;
|
||||||
|
GridSize = 16;
|
||||||
|
CellSize = 1024;
|
||||||
|
CellCount = 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (MemoryStream ms = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
DataReader r = new DataReader(ms, Endianess.BigEndian);
|
||||||
|
|
||||||
|
Read(r);
|
||||||
|
};
|
||||||
|
|
||||||
|
Loaded = true;
|
||||||
|
}
|
||||||
|
public byte[] Save()
|
||||||
|
{
|
||||||
|
MemoryStream s = new MemoryStream();
|
||||||
|
DataWriter w = new DataWriter(s);
|
||||||
|
|
||||||
|
Write(w);
|
||||||
|
|
||||||
|
var buf = new byte[s.Length];
|
||||||
|
s.Position = 0;
|
||||||
|
s.Read(buf, 0, buf.Length);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void Read(DataReader r)
|
||||||
|
{
|
||||||
|
NodeCount = r.ReadUInt32();
|
||||||
|
PathCount = r.ReadUInt32();
|
||||||
|
PathIndices = new uint[CellCount];
|
||||||
|
PathCounts1 = new uint[CellCount];
|
||||||
|
PathCounts2 = new uint[CellCount];
|
||||||
|
Nodes = new DistantLightsNode[NodeCount];
|
||||||
|
Paths = new DistantLightsPath[PathCount];
|
||||||
|
for (uint i = 0; i < CellCount; i++)
|
||||||
|
{
|
||||||
|
PathIndices[i] = r.ReadUInt32();
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < CellCount; i++)
|
||||||
|
{
|
||||||
|
PathCounts1[i] = r.ReadUInt32();
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < CellCount; i++)
|
||||||
|
{
|
||||||
|
PathCounts2[i] = r.ReadUInt32();
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < NodeCount; i++)
|
||||||
|
{
|
||||||
|
Nodes[i] = new DistantLightsNode(r);
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < PathCount; i++)
|
||||||
|
{
|
||||||
|
Paths[i] = new DistantLightsPath(r, HD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BuildCells();
|
||||||
|
|
||||||
|
}
|
||||||
|
private void Write(DataWriter w)
|
||||||
|
{
|
||||||
|
w.Write(NodeCount);
|
||||||
|
w.Write(PathCount);
|
||||||
|
|
||||||
|
for (uint i = 0; i < CellCount; i++)
|
||||||
|
{
|
||||||
|
w.Write(PathIndices[i]);
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < CellCount; i++)
|
||||||
|
{
|
||||||
|
w.Write(PathCounts1[i]);
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < CellCount; i++)
|
||||||
|
{
|
||||||
|
w.Write(PathCounts2[i]);
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < NodeCount; i++)
|
||||||
|
{
|
||||||
|
Nodes[i].Write(w);
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < PathCount; i++)
|
||||||
|
{
|
||||||
|
Paths[i].Write(w, HD);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void BuildCells()
|
||||||
|
{
|
||||||
|
for (uint i = 0; i < PathCount; i++)
|
||||||
|
{
|
||||||
|
var path = Paths[i];
|
||||||
|
path.Nodes = new DistantLightsNode[path.NodeCount];
|
||||||
|
for (uint n = 0; n < path.NodeCount; n++)
|
||||||
|
{
|
||||||
|
path.Nodes[n] = Nodes[path.NodeIndex + n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cells = new DistantLightsCell[CellCount];
|
||||||
|
for (uint x = 0; x < GridSize; x++)
|
||||||
|
{
|
||||||
|
for (uint y = 0; y < GridSize; y++)
|
||||||
|
{
|
||||||
|
var i = x * GridSize + y;
|
||||||
|
var cell = new DistantLightsCell();
|
||||||
|
cell.Index = i;
|
||||||
|
cell.CellX = x;
|
||||||
|
cell.CellY = y;
|
||||||
|
cell.CellMin = new Vector2(x, y) * CellSize - 8192.0f;
|
||||||
|
cell.CellMax = cell.CellMin + CellSize;
|
||||||
|
var pc1 = PathCounts1[i];
|
||||||
|
if (pc1 > 0)
|
||||||
|
{
|
||||||
|
cell.Paths1 = new DistantLightsPath[pc1];
|
||||||
|
for (uint l = 0; l < pc1; l++)
|
||||||
|
{
|
||||||
|
cell.Paths1[l] = Paths[PathIndices[i] + l];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var pc2 = PathCounts2[i];
|
||||||
|
if (pc2 > 0)
|
||||||
|
{
|
||||||
|
cell.Paths2 = new DistantLightsPath[pc2];
|
||||||
|
for (uint l = 0; l < pc2; l++)
|
||||||
|
{
|
||||||
|
cell.Paths2[l] = Paths[PathIndices[i] + l + pc1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Cells[i] = cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[TC(typeof(EXP))] public class DistantLightsNode
|
||||||
|
{
|
||||||
|
public short X { get; set; }
|
||||||
|
public short Y { get; set; }
|
||||||
|
public short Z { get; set; }
|
||||||
|
|
||||||
|
public DistantLightsNode()
|
||||||
|
{ }
|
||||||
|
public DistantLightsNode(DataReader r)
|
||||||
|
{
|
||||||
|
Read(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Read(DataReader r)
|
||||||
|
{
|
||||||
|
X = r.ReadInt16();
|
||||||
|
Y = r.ReadInt16();
|
||||||
|
Z = r.ReadInt16();
|
||||||
|
}
|
||||||
|
public void Write(DataWriter w)
|
||||||
|
{
|
||||||
|
w.Write(X);
|
||||||
|
w.Write(Y);
|
||||||
|
w.Write(Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 Vector
|
||||||
|
{
|
||||||
|
get { return new Vector3(X, Y, Z); }
|
||||||
|
set { X = (short)Math.Round(value.X); Y = (short)Math.Round(value.Y); Z = (short)Math.Round(value.Z); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Vector.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TC(typeof(EXP))] public class DistantLightsPath
|
||||||
|
{
|
||||||
|
public short CenterX { get; set; }
|
||||||
|
public short CenterY { get; set; }
|
||||||
|
public ushort SizeX { get; set; }
|
||||||
|
public ushort SizeY { get; set; }
|
||||||
|
public ushort NodeIndex { get; set; }
|
||||||
|
public ushort NodeCount { get; set; }
|
||||||
|
public ushort Short7 { get; set; }
|
||||||
|
public ushort Short8 { get; set; }
|
||||||
|
public float Float1 { get; set; }
|
||||||
|
public byte Byte1 { get; set; }
|
||||||
|
public byte Byte2 { get; set; }
|
||||||
|
public byte Byte3 { get; set; }
|
||||||
|
public byte Byte4 { get; set; }
|
||||||
|
|
||||||
|
public DistantLightsNode[] Nodes { get; set; }
|
||||||
|
|
||||||
|
public DistantLightsPath()
|
||||||
|
{ }
|
||||||
|
public DistantLightsPath(DataReader r, bool hd)
|
||||||
|
{
|
||||||
|
Read(r, hd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Read(DataReader r, bool hd)
|
||||||
|
{
|
||||||
|
CenterX = r.ReadInt16();
|
||||||
|
CenterY = r.ReadInt16();
|
||||||
|
SizeX = r.ReadUInt16();
|
||||||
|
SizeY = r.ReadUInt16();
|
||||||
|
NodeIndex = r.ReadUInt16();
|
||||||
|
NodeCount = r.ReadUInt16();
|
||||||
|
if (hd)
|
||||||
|
{
|
||||||
|
Short7 = r.ReadUInt16();
|
||||||
|
Short8 = r.ReadUInt16();
|
||||||
|
Float1 = r.ReadSingle();
|
||||||
|
Byte1 = r.ReadByte();
|
||||||
|
Byte2 = r.ReadByte();
|
||||||
|
Byte3 = r.ReadByte();
|
||||||
|
Byte4 = r.ReadByte();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Byte1 = r.ReadByte();
|
||||||
|
Byte2 = r.ReadByte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Write(DataWriter w, bool hd)
|
||||||
|
{
|
||||||
|
w.Write(CenterX);
|
||||||
|
w.Write(CenterY);
|
||||||
|
w.Write(SizeX);
|
||||||
|
w.Write(SizeY);
|
||||||
|
w.Write(NodeIndex);
|
||||||
|
w.Write(NodeCount);
|
||||||
|
if (hd)
|
||||||
|
{
|
||||||
|
w.Write(Short7);
|
||||||
|
w.Write(Short8);
|
||||||
|
w.Write(Float1);
|
||||||
|
w.Write(Byte1);
|
||||||
|
w.Write(Byte2);
|
||||||
|
w.Write(Byte3);
|
||||||
|
w.Write(Byte4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
w.Write(Byte1);
|
||||||
|
w.Write(Byte2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return CenterX.ToString() + ", " + CenterY.ToString() + ", " + SizeX.ToString() + ", " + SizeY.ToString() + ", " +
|
||||||
|
NodeIndex.ToString() + ", " + NodeCount.ToString() + ", " + Short7.ToString() + ", " + Short8.ToString() + ", " +
|
||||||
|
FloatUtil.ToString(Float1) + ", " + Byte1.ToString() + ", " + Byte2.ToString() + ", " + Byte3.ToString() + ", " + Byte4.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TC(typeof(EXP))] public class DistantLightsCell
|
||||||
|
{
|
||||||
|
public uint Index { get; set; }
|
||||||
|
public uint CellX { get; set; }
|
||||||
|
public uint CellY { get; set; }
|
||||||
|
public Vector2 CellMin { get; set; }
|
||||||
|
public Vector2 CellMax { get; set; }
|
||||||
|
public DistantLightsPath[] Paths1 { get; set; }
|
||||||
|
public DistantLightsPath[] Paths2 { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Index.ToString() + " (" + CellX.ToString() + ", " + CellY.ToString() + ") - " +
|
||||||
|
(Paths1?.Length ?? 0).ToString() + ", " + (Paths2?.Length ?? 0).ToString() + " - (" +
|
||||||
|
CellMin.ToString() + " - " + CellMax.ToString() + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -83,6 +83,7 @@ namespace CodeWalker.GameFiles
|
|||||||
Heightmap = 27,
|
Heightmap = 27,
|
||||||
Watermap = 28,
|
Watermap = 28,
|
||||||
Mrf = 29,
|
Mrf = 29,
|
||||||
|
DistantLights = 30,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -313,6 +313,8 @@ namespace CodeWalker
|
|||||||
InitSubFileType(".dat", "cache_y.dat", "Cache File", 6, FileTypeAction.ViewCacheDat, true);
|
InitSubFileType(".dat", "cache_y.dat", "Cache File", 6, FileTypeAction.ViewCacheDat, true);
|
||||||
InitSubFileType(".dat", "heightmap.dat", "Heightmap", 6, FileTypeAction.ViewHeightmap, true);
|
InitSubFileType(".dat", "heightmap.dat", "Heightmap", 6, FileTypeAction.ViewHeightmap, true);
|
||||||
InitSubFileType(".dat", "heightmapheistisland.dat", "Heightmap", 6, FileTypeAction.ViewHeightmap, true);
|
InitSubFileType(".dat", "heightmapheistisland.dat", "Heightmap", 6, FileTypeAction.ViewHeightmap, true);
|
||||||
|
InitSubFileType(".dat", "distantlights.dat", "Distant Lights", 6, FileTypeAction.ViewDistantLights);
|
||||||
|
InitSubFileType(".dat", "distantlights_hd.dat", "Distant Lights", 6, FileTypeAction.ViewDistantLights);
|
||||||
}
|
}
|
||||||
private void InitFileType(string ext, string name, int imgidx, FileTypeAction defaultAction = FileTypeAction.ViewHex, bool xmlConvertible = false)
|
private void InitFileType(string ext, string name, int imgidx, FileTypeAction defaultAction = FileTypeAction.ViewHex, bool xmlConvertible = false)
|
||||||
{
|
{
|
||||||
@ -1404,6 +1406,7 @@ namespace CodeWalker
|
|||||||
case FileTypeAction.ViewYfd:
|
case FileTypeAction.ViewYfd:
|
||||||
case FileTypeAction.ViewHeightmap:
|
case FileTypeAction.ViewHeightmap:
|
||||||
case FileTypeAction.ViewMrf:
|
case FileTypeAction.ViewMrf:
|
||||||
|
case FileTypeAction.ViewDistantLights:
|
||||||
return true;
|
return true;
|
||||||
case FileTypeAction.ViewHex:
|
case FileTypeAction.ViewHex:
|
||||||
default:
|
default:
|
||||||
@ -1539,6 +1542,9 @@ namespace CodeWalker
|
|||||||
case FileTypeAction.ViewNametable:
|
case FileTypeAction.ViewNametable:
|
||||||
ViewNametable(name, path, data, fe);
|
ViewNametable(name, path, data, fe);
|
||||||
break;
|
break;
|
||||||
|
case FileTypeAction.ViewDistantLights:
|
||||||
|
ViewDistantLights(name, path, data, fe);
|
||||||
|
break;
|
||||||
case FileTypeAction.ViewHex:
|
case FileTypeAction.ViewHex:
|
||||||
default:
|
default:
|
||||||
ViewHex(name, path, data);
|
ViewHex(name, path, data);
|
||||||
@ -1793,6 +1799,13 @@ namespace CodeWalker
|
|||||||
f.Show();
|
f.Show();
|
||||||
f.LoadNametable(name, path, data, e);
|
f.LoadNametable(name, path, data, e);
|
||||||
}
|
}
|
||||||
|
private void ViewDistantLights(string name, string path, byte[] data, RpfFileEntry e)
|
||||||
|
{
|
||||||
|
var dlf = RpfFile.GetFile<DistantLightsFile>(e, data);
|
||||||
|
GenericForm f = new GenericForm(this);
|
||||||
|
f.Show();
|
||||||
|
f.LoadFile(dlf, dlf.RpfFileEntry);
|
||||||
|
}
|
||||||
|
|
||||||
private RpfFileEntry CreateFileEntry(string name, string path, ref byte[] data)
|
private RpfFileEntry CreateFileEntry(string name, string path, ref byte[] data)
|
||||||
{
|
{
|
||||||
@ -4864,6 +4877,7 @@ namespace CodeWalker
|
|||||||
ViewHeightmap = 23,
|
ViewHeightmap = 23,
|
||||||
ViewMrf = 24,
|
ViewMrf = 24,
|
||||||
ViewNametable = 25,
|
ViewNametable = 25,
|
||||||
|
ViewDistantLights = 26,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user