diff --git a/CodeWalker.Core/CodeWalker.Core.csproj b/CodeWalker.Core/CodeWalker.Core.csproj
index 757b713..8e9c9ae 100644
--- a/CodeWalker.Core/CodeWalker.Core.csproj
+++ b/CodeWalker.Core/CodeWalker.Core.csproj
@@ -150,6 +150,7 @@
+
diff --git a/CodeWalker.Core/GameFiles/GameFileCache.cs b/CodeWalker.Core/GameFiles/GameFileCache.cs
index e22a0f4..955db7f 100644
--- a/CodeWalker.Core/GameFiles/GameFileCache.cs
+++ b/CodeWalker.Core/GameFiles/GameFileCache.cs
@@ -92,7 +92,7 @@ namespace CodeWalker.GameFiles
public bool DoFullStringIndex = false;
public bool BuildExtendedJenkIndex = true;
public bool LoadArchetypes = true;
- public bool LoadVehicles = false;
+ public bool LoadVehicles = true;
public bool LoadPeds = true;
private bool PreloadedMode = false;
@@ -1404,6 +1404,7 @@ namespace CodeWalker.GameFiles
string langstr3 = "american.rpf";
Gxt2Dict = new Dictionary();
+ var gxt2files = new List();
foreach (var rpf in AllRpfs)
{
foreach (var entry in rpf.AllEntries)
@@ -1414,13 +1415,25 @@ namespace CodeWalker.GameFiles
if (entry.NameLower.EndsWith(".gxt2") && (p.Contains(langstr) || p.Contains(langstr2) || p.Contains(langstr3)))
{
Gxt2Dict[entry.ShortNameHash] = fentry;
+
+ if (DoFullStringIndex)
+ {
+ var gxt2 = RpfMan.GetFile(entry);
+ if (gxt2 != null)
+ {
+ for (int i = 0; i < gxt2.TextEntries.Length; i++)
+ {
+ var e = gxt2.TextEntries[i];
+ GlobalText.Ensure(e.Text, e.Hash);
+ }
+ gxt2files.Add(gxt2);
+ }
+ }
}
}
}
}
-
-
if (!DoFullStringIndex)
{
string globalgxt2path = "x64b.rpf\\data\\lang\\" + langstr + ".rpf\\global.gxt2";
@@ -1437,21 +1450,6 @@ namespace CodeWalker.GameFiles
}
- List gxt2files = new List();
- foreach (var entry in Gxt2Dict.Values)
- {
- var gxt2 = RpfMan.GetFile(entry);
- if (gxt2 != null)
- {
- for (int i = 0; i < gxt2.TextEntries.Length; i++)
- {
- var e = gxt2.TextEntries[i];
- GlobalText.Ensure(e.Text, e.Hash);
- }
- gxt2files.Add(gxt2);
- }
- }
-
GlobalText.FullIndexBuilt = true;
diff --git a/CodeWalker.Core/World/Vehicle.cs b/CodeWalker.Core/World/Vehicle.cs
new file mode 100644
index 0000000..4428f73
--- /dev/null
+++ b/CodeWalker.Core/World/Vehicle.cs
@@ -0,0 +1,102 @@
+using CodeWalker.GameFiles;
+using SharpDX;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace CodeWalker.World
+{
+ [TypeConverter(typeof(ExpandableObjectConverter))] public class Vehicle
+ {
+ public string Name { get; set; } = string.Empty;
+ public MetaHash NameHash { get; set; } = 0;//base vehicle name hash
+ public MetaHash ModelHash { get; set; } = 0;//vehicle model name hash, can be _hi
+
+ public VehicleInitData InitData { get; set; } = null;
+ public YftFile Yft { get; set; } = null;
+
+ public YcdFile ConvRoofDict { get; set; } = null;
+ public ClipMapEntry ConvRoofClip { get; set; } = null;
+
+ public string DisplayMake { get; set; } = string.Empty;//make display name
+ public string DisplayName { get; set; } = string.Empty;//model display name
+
+ public YmapEntityDef RenderEntity = new YmapEntityDef(); //placeholder entity object for rendering
+
+ public Vector3 Position { get; set; } = Vector3.Zero;
+ public Quaternion Rotation { get; set; } = Quaternion.Identity;
+
+
+ public void Init(string name, GameFileCache gfc, bool hidef = true)
+ {
+ Name = name;
+ var modelnamel = name.ToLowerInvariant();
+ MetaHash modelhash = JenkHash.GenHash(modelnamel);
+ MetaHash modelhashhi = JenkHash.GenHash(modelnamel + "_hi");
+ var yfthash = hidef ? modelhashhi : modelhash;
+
+ VehicleInitData vid = null;
+ if (gfc.VehiclesInitDict.TryGetValue(modelhash, out vid))
+ {
+ bool vehiclechange = NameHash != modelhash;
+ ConvRoofDict = null;
+ ConvRoofClip = null;
+ ModelHash = yfthash;
+ NameHash = modelhash;
+ InitData = vid;
+ Yft = gfc.GetYft(ModelHash);
+ while ((Yft != null) && (!Yft.Loaded))
+ {
+ Thread.Sleep(20);//kinda hacky
+ Yft = gfc.GetYft(ModelHash);
+ }
+
+ DisplayMake = GlobalText.TryGetString(JenkHash.GenHash(vid.vehicleMakeName.ToLowerInvariant()));
+ DisplayName = GlobalText.TryGetString(JenkHash.GenHash(vid.gameName.ToLowerInvariant()));
+
+ if (!string.IsNullOrEmpty(vid.animConvRoofDictName) && (vid.animConvRoofDictName.ToLowerInvariant() != "null"))
+ {
+ var ycdhash = JenkHash.GenHash(vid.animConvRoofDictName.ToLowerInvariant());
+ var cliphash = JenkHash.GenHash(vid.animConvRoofName?.ToLowerInvariant());
+ ConvRoofDict = gfc.GetYcd(ycdhash);
+ while ((ConvRoofDict != null) && (!ConvRoofDict.Loaded))
+ {
+ Thread.Sleep(20);//kinda hacky
+ ConvRoofDict = gfc.GetYcd(ycdhash);
+ }
+ ClipMapEntry cme = null;
+ ConvRoofDict?.ClipMap?.TryGetValue(cliphash, out cme);
+ ConvRoofClip = cme;
+ }
+ }
+ else
+ {
+ ModelHash = 0;
+ NameHash = 0;
+ InitData = null;
+ Yft = null;
+ DisplayMake = "-";
+ DisplayName = "-";
+ ConvRoofDict = null;
+ ConvRoofClip = null;
+ }
+
+
+ UpdateEntity();
+ }
+
+
+
+ public void UpdateEntity()
+ {
+ RenderEntity.SetPosition(Position);
+ RenderEntity.SetOrientation(Rotation);
+ }
+
+
+ }
+}
diff --git a/PedsForm.cs b/PedsForm.cs
index a5dd93d..e2d4709 100644
--- a/PedsForm.cs
+++ b/PedsForm.cs
@@ -335,6 +335,7 @@ namespace CodeWalker.Peds
GameFileCache.EnableDlc = true;
GameFileCache.EnableMods = true;
GameFileCache.LoadPeds = true;
+ GameFileCache.LoadVehicles = false;
GameFileCache.LoadArchetypes = false;//to speed things up a little
GameFileCache.BuildExtendedJenkIndex = false;//to speed things up a little
GameFileCache.DoFullStringIndex = true;//to get all global text from DLC...
diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs
index b221527..523644d 100644
--- a/Rendering/Renderer.cs
+++ b/Rendering/Renderer.cs
@@ -2734,6 +2734,22 @@ namespace CodeWalker.Rendering
}
}
+ public void RenderVehicle(Vehicle vehicle, ClipMapEntry animClip = null)
+ {
+
+ YftFile yft = vehicle.Yft;
+ if ((yft != null) && (yft.Loaded) && (yft.Fragment != null))
+ {
+ var f = yft.Fragment;
+ var txdhash = vehicle.NameHash;
+
+ RenderFragment(null, vehicle.RenderEntity, f, txdhash, animClip);
+
+ }
+
+ }
+
+
public void RenderPed(Ped ped)
diff --git a/VehicleForm.cs b/VehicleForm.cs
index ff5bf16..4068a08 100644
--- a/VehicleForm.cs
+++ b/VehicleForm.cs
@@ -75,13 +75,8 @@ namespace CodeWalker.Vehicles
- MetaHash SelectedVehicleHash = 0;//base vehicle name hash
- MetaHash SelectedModelHash = 0;//yft name hash, can be _hi
- VehicleInitData SelectedVehicleInit = null;
- YftFile SelectedVehicleYft = null;
+ Vehicle SelectedVehicle = new Vehicle();
- YcdFile ConvRoofDict = null;
- ClipMapEntry ConvRoofClip = null;
bool PlayConvRoofAnim = false;
@@ -289,6 +284,7 @@ namespace CodeWalker.Vehicles
}
GameFileCache.EnableDlc = true;
+ GameFileCache.LoadPeds = false;
GameFileCache.LoadVehicles = true;
GameFileCache.LoadArchetypes = false;//to speed things up a little
GameFileCache.BuildExtendedJenkIndex = false;//to speed things up a little
@@ -668,68 +664,22 @@ namespace CodeWalker.Vehicles
public void LoadVehicle()
{
- var modelname = VehicleModelComboBox.Text;
- var modelnamel = modelname.ToLowerInvariant();
- MetaHash modelhash = JenkHash.GenHash(modelnamel);
- MetaHash modelhashhi = JenkHash.GenHash(modelnamel + "_hi");
+ var name = VehicleModelComboBox.Text;
bool hidet = VehicleHighDetailCheckBox.Checked;
- var yfthash = hidet ? modelhashhi : modelhash;
+ bool vehiclechange = SelectedVehicle.Name != name;
- VehicleInitData vid = null;
- if (GameFileCache.VehiclesInitDict.TryGetValue(modelhash, out vid))
+ SelectedVehicle.Init(name, GameFileCache, hidet);
+
+ if (SelectedVehicle.InitData != null)
{
- bool vehiclechange = SelectedVehicleHash != modelhash;
- ConvRoofDict = null;
- ConvRoofClip = null;
- SelectedModelHash = yfthash;
- SelectedVehicleHash = modelhash;
- SelectedVehicleInit = vid;
- SelectedVehicleYft = GameFileCache.GetYft(SelectedModelHash);
- while ((SelectedVehicleYft != null) && (!SelectedVehicleYft.Loaded))
- {
- Thread.Sleep(20);//kinda hacky
- SelectedVehicleYft = GameFileCache.GetYft(SelectedModelHash);
- }
- LoadModel(SelectedVehicleYft, vehiclechange);
- VehicleMakeLabel.Text = GlobalText.TryGetString(JenkHash.GenHash(vid.vehicleMakeName.ToLower()));
- VehicleNameLabel.Text = GlobalText.TryGetString(JenkHash.GenHash(vid.gameName.ToLower()));
-
- if (!string.IsNullOrEmpty(vid.animConvRoofDictName) && (vid.animConvRoofDictName.ToLowerInvariant() != "null"))
- {
- ConvRoofDictNameLabel.Text = vid.animConvRoofDictName;
- ConvRoofNameLabel.Text = vid.animConvRoofName;
-
- var ycdhash = JenkHash.GenHash(vid.animConvRoofDictName.ToLowerInvariant());
- var cliphash = JenkHash.GenHash(vid.animConvRoofName?.ToLowerInvariant());
- ConvRoofDict = GameFileCache.GetYcd(ycdhash);
- while ((ConvRoofDict != null) && (!ConvRoofDict.Loaded))
- {
- Thread.Sleep(20);//kinda hacky
- ConvRoofDict = GameFileCache.GetYcd(ycdhash);
- }
- ClipMapEntry cme = null;
- ConvRoofDict?.ClipMap?.TryGetValue(cliphash, out cme);
- ConvRoofClip = cme;
-
- ConvRoofPanel.Visible = true;
- }
- else
- {
- ConvRoofPanel.Visible = false;
- }
- }
- else
- {
- SelectedModelHash = 0;
- SelectedVehicleHash = 0;
- SelectedVehicleInit = null;
- SelectedVehicleYft = null;
- VehicleMakeLabel.Text = "-";
- VehicleNameLabel.Text = "-";
- ConvRoofPanel.Visible = false;
- ConvRoofDict = null;
- ConvRoofClip = null;
+ LoadModel(SelectedVehicle.Yft, vehiclechange);
+ ConvRoofDictNameLabel.Text = SelectedVehicle.InitData.animConvRoofDictName;
+ ConvRoofNameLabel.Text = SelectedVehicle.InitData.animConvRoofName;
}
+ VehicleMakeLabel.Text = SelectedVehicle.DisplayMake;
+ VehicleNameLabel.Text = SelectedVehicle.DisplayName;
+ ConvRoofPanel.Visible = SelectedVehicle.ConvRoofClip != null;
+
}
public void LoadModel(YftFile yft, bool movecamera = true)
@@ -926,39 +876,14 @@ namespace CodeWalker.Vehicles
private void RenderVehicle()
{
-
- YftFile yft = GameFileCache.GetYft(SelectedModelHash);
- if (yft != null)
+ ClipMapEntry clip = null;
+ if (PlayConvRoofAnim)
{
- if (yft.Loaded)
- {
- if (yft.Fragment != null)
- {
- var f = yft.Fragment;
-
- var txdhash = SelectedVehicleHash;// yft.RpfFileEntry?.ShortNameHash ?? 0;
-
- var namelower = yft.RpfFileEntry?.GetShortNameLower();
- if (namelower?.EndsWith("_hi") ?? false)
- {
- txdhash = JenkHash.GenHash(namelower.Substring(0, namelower.Length - 3));
- }
-
- Archetype arch = null;// TryGetArchetype(hash);
-
- ClipMapEntry clip = null;
- if (PlayConvRoofAnim)
- {
- clip = ConvRoofClip;
- }
-
- Renderer.RenderFragment(arch, null, f, txdhash, clip);
-
- //seldrwbl = f.Drawable;
- }
- }
+ clip = SelectedVehicle.ConvRoofClip;
}
+ Renderer.RenderVehicle(SelectedVehicle, clip);
+
}
diff --git a/World/CutsceneForm.cs b/World/CutsceneForm.cs
index 99c7ac1..e9540a4 100644
--- a/World/CutsceneForm.cs
+++ b/World/CutsceneForm.cs
@@ -467,44 +467,40 @@ namespace CodeWalker.World
{
foreach (var obj in SceneObjects.Values)
{
- if (obj.Ped != null)
+ var pos = Position;
+ var rot = Rotation;
+ var animate = (obj.Ped != null) || (obj.Prop != null) || (obj.Vehicle != null);
+ if (animate)
{
ycd.CutsceneMap.TryGetValue(obj.AnimHash, out cme);
- var pos = Position;
- var rot = Rotation;
if (cme != null)
{
cme.OverridePlayTime = true;
cme.PlayTime = cutOffset;
-
- updateObjectTransform(obj, cme, 0, 5, 6);
-
+ updateObjectTransform(obj, cme, 0, 5, 6); //using root animation bone ids
pos = pos + rot.Multiply(obj.Position);
rot = rot * obj.Rotation;
}
+ }
+ if (obj.Ped != null)
+ {
obj.Ped.Position = pos;
obj.Ped.Rotation = rot;
obj.Ped.AnimClip = cme;
}
if (obj.Prop != null)
{
- ycd.CutsceneMap.TryGetValue(obj.AnimHash, out cme);
- var pos = Position;
- var rot = Rotation;
- if (cme != null)
- {
- cme.OverridePlayTime = true;
- cme.PlayTime = cutOffset;
-
- updateObjectTransform(obj, cme, 0, 5, 6);
-
- pos = pos + rot.Multiply(obj.Position);
- rot = rot * obj.Rotation;
- }
obj.Prop.Position = pos;
obj.Prop.Orientation = rot;
obj.AnimClip = cme;
}
+ if (obj.Vehicle != null)
+ {
+ obj.Vehicle.Position = pos;
+ obj.Vehicle.Rotation = rot;
+ obj.Vehicle.UpdateEntity();
+ obj.AnimClip = cme;
+ }
}
}
@@ -533,6 +529,10 @@ namespace CodeWalker.World
{
renderer.RenderArchetype(obj.Prop.Archetype, obj.Prop, null, true, obj.AnimClip);
}
+ if (obj.Vehicle != null)
+ {
+ renderer.RenderVehicle(obj.Vehicle, obj.AnimClip);
+ }
}
}
@@ -1026,12 +1026,14 @@ namespace CodeWalker.World
public Quaternion Rotation { get; set; }
public Ped Ped { get; set; }
-
public YmapEntityDef Prop { get; set; }
+ public Vehicle Vehicle { get; set; }
public MetaHash AnimHash { get; set; }
public ClipMapEntry AnimClip { get; set; }
+
+
public void Init(CutObject obj, GameFileCache gfc)
{
@@ -1141,7 +1143,12 @@ namespace CodeWalker.World
private void InitVehicle(CutVehicleModelObject veh, GameFileCache gfc)
{
+ var name = veh.StreamingName.ToString();
+ Vehicle = new Vehicle();
+ Vehicle.Init(name, gfc);
+
+ AnimHash = veh.StreamingName;
}
private void InitWeapon(CutWeaponModelObject weap, GameFileCache gfc)