mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2025-01-09 23:15:09 +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,
|
||||
Watermap = 28,
|
||||
Mrf = 29,
|
||||
DistantLights = 30,
|
||||
}
|
||||
|
||||
|
||||
|
@ -313,6 +313,8 @@ namespace CodeWalker
|
||||
InitSubFileType(".dat", "cache_y.dat", "Cache File", 6, FileTypeAction.ViewCacheDat, true);
|
||||
InitSubFileType(".dat", "heightmap.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)
|
||||
{
|
||||
@ -1404,6 +1406,7 @@ namespace CodeWalker
|
||||
case FileTypeAction.ViewYfd:
|
||||
case FileTypeAction.ViewHeightmap:
|
||||
case FileTypeAction.ViewMrf:
|
||||
case FileTypeAction.ViewDistantLights:
|
||||
return true;
|
||||
case FileTypeAction.ViewHex:
|
||||
default:
|
||||
@ -1539,6 +1542,9 @@ namespace CodeWalker
|
||||
case FileTypeAction.ViewNametable:
|
||||
ViewNametable(name, path, data, fe);
|
||||
break;
|
||||
case FileTypeAction.ViewDistantLights:
|
||||
ViewDistantLights(name, path, data, fe);
|
||||
break;
|
||||
case FileTypeAction.ViewHex:
|
||||
default:
|
||||
ViewHex(name, path, data);
|
||||
@ -1793,6 +1799,13 @@ namespace CodeWalker
|
||||
f.Show();
|
||||
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)
|
||||
{
|
||||
@ -4864,6 +4877,7 @@ namespace CodeWalker
|
||||
ViewHeightmap = 23,
|
||||
ViewMrf = 24,
|
||||
ViewNametable = 25,
|
||||
ViewDistantLights = 26,
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user