2024-01-07 02:41:10 +08:00
|
|
|
|
using CodeWalker.Core.Utils;
|
|
|
|
|
using CodeWalker.GameFiles;
|
|
|
|
|
using Collections.Pooled;
|
2017-09-21 18:33:05 +08:00
|
|
|
|
using SharpDX;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2024-01-07 02:41:10 +08:00
|
|
|
|
using System.Runtime.CompilerServices;
|
2017-09-21 18:33:05 +08:00
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace CodeWalker.World
|
|
|
|
|
{
|
|
|
|
|
public class PopZones : BasePathData
|
|
|
|
|
{
|
|
|
|
|
public volatile bool Inited = false;
|
|
|
|
|
public GameFileCache GameFileCache;
|
|
|
|
|
|
|
|
|
|
public Dictionary<string, PopZone> Groups = new Dictionary<string, PopZone>();
|
|
|
|
|
|
2017-12-14 19:45:43 +08:00
|
|
|
|
public EditorVertex[] GetTriangleVertices()
|
2017-09-21 18:33:05 +08:00
|
|
|
|
{
|
|
|
|
|
return TriangleVerts;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-07 02:41:10 +08:00
|
|
|
|
public EditorVertex[] TriangleVerts = Array.Empty<EditorVertex>();
|
2017-09-21 18:33:05 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Init(GameFileCache gameFileCache, Action<string> updateStatus)
|
|
|
|
|
{
|
2024-01-07 02:41:10 +08:00
|
|
|
|
using var _ = new DisposableTimer("PopZones Init");
|
2017-09-21 18:33:05 +08:00
|
|
|
|
Inited = false;
|
|
|
|
|
|
|
|
|
|
GameFileCache = gameFileCache;
|
|
|
|
|
|
|
|
|
|
var rpfman = gameFileCache.RpfMan;
|
|
|
|
|
|
|
|
|
|
string filename = "common.rpf\\data\\levels\\gta5\\popzone.ipl";
|
|
|
|
|
if (gameFileCache.EnableDlc)
|
|
|
|
|
{
|
|
|
|
|
filename = "update\\update.rpf\\common\\data\\levels\\gta5\\popzone.ipl";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string ipltext = rpfman.GetFileUTF8Text(filename);
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(ipltext))
|
|
|
|
|
{
|
|
|
|
|
ipltext = "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Groups.Clear();
|
|
|
|
|
|
2024-01-07 02:41:10 +08:00
|
|
|
|
//var ipllines = ipltext.Split('\n');
|
2017-09-21 18:33:05 +08:00
|
|
|
|
bool inzone = false;
|
2024-01-07 02:41:10 +08:00
|
|
|
|
foreach (var iplline in ipltext.EnumerateSplit('\n'))
|
2017-09-21 18:33:05 +08:00
|
|
|
|
{
|
|
|
|
|
var linet = iplline.Trim();
|
|
|
|
|
if (linet == "zone")
|
|
|
|
|
{
|
|
|
|
|
inzone = true;
|
|
|
|
|
}
|
|
|
|
|
else if (linet == "end")
|
|
|
|
|
{
|
|
|
|
|
inzone = false;
|
|
|
|
|
}
|
|
|
|
|
else if (inzone)
|
|
|
|
|
{
|
|
|
|
|
PopZoneBox box = new PopZoneBox();
|
|
|
|
|
box.Init(linet);
|
|
|
|
|
|
2024-01-07 02:41:10 +08:00
|
|
|
|
if (!Groups.TryGetValue(box.NameLabel, out var group))
|
2017-09-21 18:33:05 +08:00
|
|
|
|
{
|
|
|
|
|
group = new PopZone();
|
|
|
|
|
group.NameLabel = box.NameLabel;
|
|
|
|
|
Groups[box.NameLabel] = group;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
group.Boxes.Add(box);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var group in Groups.Values)
|
|
|
|
|
{
|
2024-01-07 02:41:10 +08:00
|
|
|
|
var hash = JenkHash.GenHashLower(group.NameLabel);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
group.Name = GlobalText.TryGetString(hash);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BuildVertices();
|
|
|
|
|
|
|
|
|
|
Inited = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void BuildVertices()
|
|
|
|
|
{
|
|
|
|
|
|
2024-01-07 02:41:10 +08:00
|
|
|
|
using var vlist = new PooledList<EditorVertex>();
|
2017-09-22 15:31:02 +08:00
|
|
|
|
|
2017-09-21 18:33:05 +08:00
|
|
|
|
foreach (var group in Groups.Values)
|
|
|
|
|
{
|
2024-01-07 02:41:10 +08:00
|
|
|
|
var hash = JenkHash.GenHashLower(group.NameLabel);
|
2017-09-22 15:31:02 +08:00
|
|
|
|
byte cr = (byte)((hash >> 8) & 0xFF);
|
|
|
|
|
byte cg = (byte)((hash >> 16) & 0xFF);
|
|
|
|
|
byte cb = (byte)((hash >> 24) & 0xFF);
|
|
|
|
|
byte ca = 60;
|
|
|
|
|
uint cv = (uint)new Color(cr, cg, cb, ca).ToRgba();
|
|
|
|
|
|
|
|
|
|
foreach (var box in group.Boxes)
|
|
|
|
|
{
|
|
|
|
|
var min = box.Box.Minimum;
|
|
|
|
|
var max = box.Box.Maximum;
|
|
|
|
|
|
2024-01-07 02:41:10 +08:00
|
|
|
|
var v1 = new EditorVertex(new Vector3(min.X, min.Y, 0), cv);
|
|
|
|
|
var v2 = new EditorVertex(new Vector3(max.X, min.Y, 0), cv);
|
|
|
|
|
var v3 = new EditorVertex(new Vector3(min.X, max.Y, 0), cv);
|
|
|
|
|
var v4 = new EditorVertex(new Vector3(max.X, max.Y, 0), cv);
|
2017-09-22 15:31:02 +08:00
|
|
|
|
|
|
|
|
|
vlist.Add(v1);
|
|
|
|
|
vlist.Add(v2);
|
|
|
|
|
vlist.Add(v3);
|
|
|
|
|
vlist.Add(v3);
|
|
|
|
|
vlist.Add(v2);
|
|
|
|
|
vlist.Add(v4);
|
|
|
|
|
}
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
2017-09-22 15:31:02 +08:00
|
|
|
|
if (vlist.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
TriangleVerts = vlist.ToArray();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-01-07 02:41:10 +08:00
|
|
|
|
TriangleVerts = [];
|
2017-09-22 15:31:02 +08:00
|
|
|
|
}
|
2017-09-21 18:33:05 +08:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class PopZone
|
|
|
|
|
{
|
|
|
|
|
public string NameLabel { get; set; }
|
|
|
|
|
public string Name { get; set; } //lookup from gxt2 with label..?
|
|
|
|
|
public List<PopZoneBox> Boxes { get; set; } = new List<PopZoneBox>();
|
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
2024-01-07 02:41:10 +08:00
|
|
|
|
return $"{NameLabel}: {Name}";
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class PopZoneBox
|
|
|
|
|
{
|
|
|
|
|
public string ID { get; set; }
|
|
|
|
|
public BoundingBox Box { get; set; }
|
|
|
|
|
public string NameLabel { get; set; }
|
|
|
|
|
public float UnkVal { get; set; }
|
|
|
|
|
|
2024-01-07 02:41:10 +08:00
|
|
|
|
[SkipLocalsInit]
|
|
|
|
|
public void Init(ReadOnlySpan<char> iplline)
|
2017-09-21 18:33:05 +08:00
|
|
|
|
{
|
2024-01-07 02:41:10 +08:00
|
|
|
|
Span<Range> parts = stackalloc Range[10];
|
|
|
|
|
var numParts = iplline.Split(parts, ',', StringSplitOptions.TrimEntries);
|
|
|
|
|
//var parts = iplline.Split(',');
|
|
|
|
|
if (numParts >= 9)
|
2017-09-21 18:33:05 +08:00
|
|
|
|
{
|
2024-01-07 02:41:10 +08:00
|
|
|
|
ID = iplline[parts[0]].ToString();
|
2017-09-21 18:33:05 +08:00
|
|
|
|
BoundingBox b = new BoundingBox();
|
2024-01-07 02:41:10 +08:00
|
|
|
|
b.Minimum.X = FloatUtil.Parse(iplline[parts[1]]);
|
|
|
|
|
b.Minimum.Y = FloatUtil.Parse(iplline[parts[2]]);
|
|
|
|
|
b.Minimum.Z = FloatUtil.Parse(iplline[parts[3]]);
|
|
|
|
|
b.Maximum.X = FloatUtil.Parse(iplline[parts[4]]);
|
|
|
|
|
b.Maximum.Y = FloatUtil.Parse(iplline[parts[5]]);
|
|
|
|
|
b.Maximum.Z = FloatUtil.Parse(iplline[parts[6]]);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
Box = b;
|
2024-01-07 02:41:10 +08:00
|
|
|
|
NameLabel = iplline[parts[7]].ToString();
|
|
|
|
|
UnkVal = FloatUtil.Parse(iplline[parts[8]]);
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
|
{
|
2024-01-07 02:41:10 +08:00
|
|
|
|
return $"{ID}: {NameLabel}: {Box}";
|
2017-09-21 18:33:05 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|