diff --git a/CodeWalker.Core/CodeWalker.Core.csproj b/CodeWalker.Core/CodeWalker.Core.csproj
index 5b267aa..440993b 100644
--- a/CodeWalker.Core/CodeWalker.Core.csproj
+++ b/CodeWalker.Core/CodeWalker.Core.csproj
@@ -61,6 +61,7 @@
+
diff --git a/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs
index 7625e29..09dc80b 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs
@@ -44,7 +44,7 @@ namespace CodeWalker.GameFiles
}
else
{
- Xml = Encoding.UTF8.GetString(data);
+ Xml = TextUtil.GetUTF8Text(data);
}
XmlDocument xdoc = new XmlDocument();
diff --git a/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs
index 6002c24..b092b39 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs
@@ -43,7 +43,7 @@ namespace CodeWalker.GameFiles
}
else
{
- Xml = Encoding.UTF8.GetString(data);
+ Xml = TextUtil.GetUTF8Text(data);
}
XmlDocument xdoc = new XmlDocument();
diff --git a/CodeWalker.Core/GameFiles/FileTypes/GtxdFile.cs b/CodeWalker.Core/GameFiles/FileTypes/GtxdFile.cs
index 4c47102..1d7932e 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/GtxdFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/GtxdFile.cs
@@ -60,13 +60,7 @@ namespace CodeWalker.GameFiles
else if (entry.NameLower.EndsWith(".meta"))
{
//required for update\x64\dlcpacks\mpheist\dlc.rpf\common\data\gtxd.meta and update\x64\dlcpacks\mpluxe\dlc.rpf\common\data\gtxd.meta
- string bom = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
- string xml = Encoding.UTF8.GetString(data);
-
- if (xml.StartsWith(bom, StringComparison.Ordinal))
- {
- xml = xml.Remove(0, bom.Length);
- }
+ string xml = TextUtil.GetUTF8Text(data);
LoadTxdRelationships(xml);
Loaded = true;
diff --git a/CodeWalker.Core/GameFiles/FileTypes/PedsFile.cs b/CodeWalker.Core/GameFiles/FileTypes/PedsFile.cs
new file mode 100644
index 0000000..439134f
--- /dev/null
+++ b/CodeWalker.Core/GameFiles/FileTypes/PedsFile.cs
@@ -0,0 +1,348 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SharpDX;
+using System.IO;
+using System.Xml;
+
+using TC = System.ComponentModel.TypeConverterAttribute;
+using EXP = System.ComponentModel.ExpandableObjectConverter;
+
+
+namespace CodeWalker.GameFiles
+{
+ [TC(typeof(EXP))] public class PedsFile : GameFile, PackedFile
+ {
+ public PsoFile Pso { get; set; }
+ public string Xml { get; set; }
+
+ public CPedModelInfo__InitDataList InitDataList { get; set; }
+
+ public PedsFile() : base(null, GameFileType.Peds)
+ { }
+ public PedsFile(RpfFileEntry entry) : base(entry, GameFileType.Peds)
+ {
+ }
+
+ public void Load(byte[] data, RpfFileEntry entry)
+ {
+ RpfFileEntry = entry;
+ Name = entry.Name;
+ FilePath = Name;
+
+
+
+ //can be PSO .ymt or XML .meta
+ MemoryStream ms = new MemoryStream(data);
+ if (PsoFile.IsPSO(ms))
+ {
+ Pso = new PsoFile();
+ Pso.Load(data);
+ Xml = PsoXml.GetXml(Pso); //yep let's just convert that to XML :P
+ }
+ else
+ {
+ Xml = TextUtil.GetUTF8Text(data);
+ }
+
+ XmlDocument xdoc = new XmlDocument();
+ if (!string.IsNullOrEmpty(Xml))
+ {
+ try
+ {
+ xdoc.LoadXml(Xml);
+ }
+ catch (Exception ex)
+ {
+ var msg = ex.Message;
+ }
+ }
+ else
+ { }
+
+
+ if (xdoc.DocumentElement != null)
+ {
+ InitDataList = new CPedModelInfo__InitDataList(xdoc.DocumentElement);
+ }
+
+
+
+
+ Loaded = true;
+ }
+ }
+
+
+
+ [TC(typeof(EXP))] public class CPedModelInfo__InitDataList
+ {
+ public string residentTxd { get; set; }
+ public string[] residentAnims { get; set; }
+ public CPedModelInfo__InitData[] InitDatas { get; set; }
+ public CTxdRelationship[] txdRelationships { get; set; }
+ public CMultiTxdRelationship[] multiTxdRelationships { get; set; }
+
+ public CPedModelInfo__InitDataList(XmlNode node)
+ {
+ XmlNodeList items;
+
+ residentTxd = Xml.GetChildInnerText(node, "residentTxd");
+
+ items = node.SelectSingleNode("residentAnims")?.SelectNodes("Item");
+ if (items?.Count > 0)
+ {
+ residentAnims = new string[items.Count];
+ for (int i = 0; i < items.Count; i++)
+ {
+ residentAnims[i] = items[i].InnerText;
+ }
+ }
+ items = node.SelectSingleNode("InitDatas")?.SelectNodes("Item");
+ if (items?.Count > 0)
+ {
+ InitDatas = new CPedModelInfo__InitData[items.Count];
+ for (int i = 0; i < items.Count; i++)
+ {
+ InitDatas[i] = new CPedModelInfo__InitData(items[i]);
+ }
+ }
+ items = node.SelectSingleNode("txdRelationships")?.SelectNodes("Item");
+ if (items?.Count > 0)
+ {
+ txdRelationships = new CTxdRelationship[items.Count];
+ for (int i = 0; i < items.Count; i++)
+ {
+ txdRelationships[i] = new CTxdRelationship(items[i]);
+ }
+ }
+ items = node.SelectSingleNode("multiTxdRelationships")?.SelectNodes("Item");
+ if (items?.Count > 0)
+ {
+ multiTxdRelationships = new CMultiTxdRelationship[items.Count];
+ for (int i = 0; i < items.Count; i++)
+ {
+ multiTxdRelationships[i] = new CMultiTxdRelationship(items[i]);
+ }
+ }
+
+ }
+ }
+
+ [TC(typeof(EXP))] public class CPedModelInfo__InitData
+ {
+ public string Name { get; set; }
+ public string PropsName { get; set; }
+ public string ClipDictionaryName { get; set; }
+ public string BlendShapeFileName { get; set; }
+ public string ExpressionSetName { get; set; }
+ public string ExpressionDictionaryName { get; set; }
+ public string ExpressionName { get; set; }
+ public string Pedtype { get; set; }
+ public string MovementClipSet { get; set; }
+ public string[] MovementClipSets { get; set; }
+ public string StrafeClipSet { get; set; }
+ public string MovementToStrafeClipSet { get; set; }
+ public string InjuredStrafeClipSet { get; set; }
+ public string FullBodyDamageClipSet { get; set; }
+ public string AdditiveDamageClipSet { get; set; }
+ public string DefaultGestureClipSet { get; set; }
+ public string FacialClipsetGroupName { get; set; }
+ public string DefaultVisemeClipSet { get; set; }
+ public string SidestepClipSet { get; set; }
+ public string PoseMatcherName { get; set; }
+ public string PoseMatcherProneName { get; set; }
+ public string GetupSetHash { get; set; }
+ public string CreatureMetadataName { get; set; }
+ public string DecisionMakerName { get; set; }
+ public string MotionTaskDataSetName { get; set; }
+ public string DefaultTaskDataSetName { get; set; }
+ public string PedCapsuleName { get; set; }
+ public string PedLayoutName { get; set; }
+ public string PedComponentSetName { get; set; }
+ public string PedComponentClothName { get; set; }
+ public string PedIKSettingsName { get; set; }
+ public string TaskDataName { get; set; }
+ public bool IsStreamedGfx { get; set; }
+ public bool AmbulanceShouldRespondTo { get; set; }
+ public bool CanRideBikeWithNoHelmet { get; set; }
+ public bool CanSpawnInCar { get; set; }
+ public bool IsHeadBlendPed { get; set; }
+ public bool bOnlyBulkyItemVariations { get; set; }
+ public string RelationshipGroup { get; set; }
+ public string NavCapabilitiesName { get; set; }
+ public string PerceptionInfo { get; set; }
+ public string DefaultBrawlingStyle { get; set; }
+ public string DefaultUnarmedWeapon { get; set; }
+ public string Personality { get; set; }
+ public string CombatInfo { get; set; }
+ public string VfxInfoName { get; set; }
+ public string AmbientClipsForFlee { get; set; }
+ public string Radio1 { get; set; } // MetaName.ePedRadioGenre
+ public string Radio2 { get; set; } // MetaName.ePedRadioGenre
+ public float FUpOffset { get; set; }
+ public float RUpOffset { get; set; }
+ public float FFrontOffset { get; set; }
+ public float RFrontOffset { get; set; }
+ public float MinActivationImpulse { get; set; }
+ public float Stubble { get; set; }
+ public float HDDist { get; set; }
+ public float TargetingThreatModifier { get; set; }
+ public float KilledPerceptionRangeModifer { get; set; }
+ public string Sexiness { get; set; } // MetaTypeName.ARRAYINFO MetaName.eSexinessFlags
+ public byte Age { get; set; }
+ public byte MaxPassengersInCar { get; set; }
+ public string ExternallyDrivenDOFs { get; set; } // MetaTypeName.ARRAYINFO MetaName.eExternallyDrivenDOFs
+ public string PedVoiceGroup { get; set; }
+ public string AnimalAudioObject { get; set; }
+ public string AbilityType { get; set; } // MetaName.SpecialAbilityType
+ public string ThermalBehaviour { get; set; } // MetaName.ThermalBehaviour
+ public string SuperlodType { get; set; } // MetaName.eSuperlodType
+ public string ScenarioPopStreamingSlot { get; set; } // MetaName.eScenarioPopStreamingSlot
+ public string DefaultSpawningPreference { get; set; } // MetaName.DefaultSpawnPreference
+ public float DefaultRemoveRangeMultiplier { get; set; }
+ public bool AllowCloseSpawning { get; set; }
+
+
+ public CPedModelInfo__InitData(XmlNode node)
+ {
+ Name = Xml.GetChildInnerText(node, "Name");
+ PropsName = Xml.GetChildInnerText(node, "PropsName");
+ ClipDictionaryName = Xml.GetChildInnerText(node, "ClipDictionaryName");
+ BlendShapeFileName = Xml.GetChildInnerText(node, "BlendShapeFileName");
+ ExpressionSetName = Xml.GetChildInnerText(node, "ExpressionSetName");
+ ExpressionDictionaryName = Xml.GetChildInnerText(node, "ExpressionDictionaryName");
+ ExpressionName = Xml.GetChildInnerText(node, "ExpressionName");
+ Pedtype = Xml.GetChildInnerText(node, "Pedtype");
+ MovementClipSet = Xml.GetChildInnerText(node, "MovementClipSet");
+ var items = node.SelectSingleNode("MovementClipSets")?.SelectNodes("Item");
+ if (items?.Count > 0)
+ {
+ MovementClipSets = new string[items.Count];
+ for (int i = 0; i < items.Count; i++)
+ {
+ MovementClipSets[i] = items[i].InnerText;
+ }
+ }
+ StrafeClipSet = Xml.GetChildInnerText(node, "StrafeClipSet");
+ MovementToStrafeClipSet = Xml.GetChildInnerText(node, "MovementToStrafeClipSet");
+ InjuredStrafeClipSet = Xml.GetChildInnerText(node, "InjuredStrafeClipSet");
+ FullBodyDamageClipSet = Xml.GetChildInnerText(node, "FullBodyDamageClipSet");
+ AdditiveDamageClipSet = Xml.GetChildInnerText(node, "AdditiveDamageClipSet");
+ DefaultGestureClipSet = Xml.GetChildInnerText(node, "DefaultGestureClipSet");
+ FacialClipsetGroupName = Xml.GetChildInnerText(node, "FacialClipsetGroupName");
+ DefaultVisemeClipSet = Xml.GetChildInnerText(node, "DefaultVisemeClipSet");
+ SidestepClipSet = Xml.GetChildInnerText(node, "SidestepClipSet");
+ PoseMatcherName = Xml.GetChildInnerText(node, "PoseMatcherName");
+ PoseMatcherProneName = Xml.GetChildInnerText(node, "PoseMatcherProneName");
+ GetupSetHash = Xml.GetChildInnerText(node, "GetupSetHash");
+ CreatureMetadataName = Xml.GetChildInnerText(node, "CreatureMetadataName");
+ DecisionMakerName = Xml.GetChildInnerText(node, "DecisionMakerName");
+ MotionTaskDataSetName = Xml.GetChildInnerText(node, "MotionTaskDataSetName");
+ DefaultTaskDataSetName = Xml.GetChildInnerText(node, "DefaultTaskDataSetName");
+ PedCapsuleName = Xml.GetChildInnerText(node, "PedCapsuleName");
+ PedLayoutName = Xml.GetChildInnerText(node, "PedLayoutName");
+ PedComponentSetName = Xml.GetChildInnerText(node, "PedComponentSetName");
+ PedComponentClothName = Xml.GetChildInnerText(node, "PedComponentClothName");
+ PedIKSettingsName = Xml.GetChildInnerText(node, "PedIKSettingsName");
+ TaskDataName = Xml.GetChildInnerText(node, "TaskDataName");
+ IsStreamedGfx = Xml.GetChildBoolAttribute(node, "IsStreamedGfx", "value");
+ AmbulanceShouldRespondTo = Xml.GetChildBoolAttribute(node, "AmbulanceShouldRespondTo", "value");
+ CanRideBikeWithNoHelmet = Xml.GetChildBoolAttribute(node, "CanRideBikeWithNoHelmet", "value");
+ CanSpawnInCar = Xml.GetChildBoolAttribute(node, "CanSpawnInCar", "value");
+ IsHeadBlendPed = Xml.GetChildBoolAttribute(node, "IsHeadBlendPed", "value");
+ bOnlyBulkyItemVariations = Xml.GetChildBoolAttribute(node, "bOnlyBulkyItemVariations", "value");
+ RelationshipGroup = Xml.GetChildInnerText(node, "RelationshipGroup");
+ NavCapabilitiesName = Xml.GetChildInnerText(node, "NavCapabilitiesName");
+ PerceptionInfo = Xml.GetChildInnerText(node, "PerceptionInfo");
+ DefaultBrawlingStyle = Xml.GetChildInnerText(node, "DefaultBrawlingStyle");
+ DefaultUnarmedWeapon = Xml.GetChildInnerText(node, "DefaultUnarmedWeapon");
+ Personality = Xml.GetChildInnerText(node, "Personality");
+ CombatInfo = Xml.GetChildInnerText(node, "CombatInfo");
+ VfxInfoName = Xml.GetChildInnerText(node, "VfxInfoName");
+ AmbientClipsForFlee = Xml.GetChildInnerText(node, "AmbientClipsForFlee");
+ Radio1 = Xml.GetChildInnerText(node, "Radio1"); // MetaName.ePedRadioGenre
+ Radio2 = Xml.GetChildInnerText(node, "Radio2"); // MetaName.ePedRadioGenre
+ FUpOffset = Xml.GetChildFloatAttribute(node, "FUpOffset", "value");
+ RUpOffset = Xml.GetChildFloatAttribute(node, "RUpOffset", "value");
+ FFrontOffset = Xml.GetChildFloatAttribute(node, "FFrontOffset", "value");
+ RFrontOffset = Xml.GetChildFloatAttribute(node, "RFrontOffset", "value");
+ MinActivationImpulse = Xml.GetChildFloatAttribute(node, "MinActivationImpulse", "value");
+ Stubble = Xml.GetChildFloatAttribute(node, "Stubble", "value");
+ HDDist = Xml.GetChildFloatAttribute(node, "HDDist", "value");
+ TargetingThreatModifier = Xml.GetChildFloatAttribute(node, "TargetingThreatModifier", "value");
+ KilledPerceptionRangeModifer = Xml.GetChildFloatAttribute(node, "KilledPerceptionRangeModifer", "value");
+ Sexiness = Xml.GetChildInnerText(node, "Sexiness"); // MetaTypeName.ARRAYINFO MetaName.eSexinessFlags
+ Age = (byte)Xml.GetChildUIntAttribute(node, "Age", "value");
+ MaxPassengersInCar = (byte)Xml.GetChildUIntAttribute(node, "MaxPassengersInCar", "value");
+ ExternallyDrivenDOFs = Xml.GetChildInnerText(node, "ExternallyDrivenDOFs"); // MetaTypeName.ARRAYINFO MetaName.eExternallyDrivenDOFs
+ PedVoiceGroup = Xml.GetChildInnerText(node, "PedVoiceGroup");
+ AnimalAudioObject = Xml.GetChildInnerText(node, "AnimalAudioObject");
+ AbilityType = Xml.GetChildInnerText(node, "AbilityType"); // MetaName.SpecialAbilityType
+ ThermalBehaviour = Xml.GetChildInnerText(node, "ThermalBehaviour"); // MetaName.ThermalBehaviour
+ SuperlodType = Xml.GetChildInnerText(node, "SuperlodType"); // MetaName.eSuperlodType
+ ScenarioPopStreamingSlot = Xml.GetChildInnerText(node, "ScenarioPopStreamingSlot"); // MetaName.eScenarioPopStreamingSlot
+ DefaultSpawningPreference = Xml.GetChildInnerText(node, "DefaultSpawningPreference"); // MetaName.DefaultSpawnPreference
+ DefaultRemoveRangeMultiplier = Xml.GetChildFloatAttribute(node, "DefaultRemoveRangeMultiplier", "value");
+ AllowCloseSpawning = Xml.GetChildBoolAttribute(node, "AllowCloseSpawning", "value");
+ }
+
+
+ public override string ToString()
+ {
+ return Name;
+ }
+ }
+
+ [TC(typeof(EXP))] public class CTxdRelationship
+ {
+ public string parent { get; set; }
+ public string child { get; set; }
+
+ public CTxdRelationship(XmlNode node)
+ {
+ parent = Xml.GetChildInnerText(node, "parent");
+ child = Xml.GetChildInnerText(node, "child");
+ }
+
+ public override string ToString()
+ {
+ return parent + ": " + child;
+ }
+ }
+
+ [TC(typeof(EXP))] public class CMultiTxdRelationship
+ {
+ public string parent { get; set; }
+ public string[] children { get; set; }
+
+ public CMultiTxdRelationship(XmlNode node)
+ {
+ parent = Xml.GetChildInnerText(node, "parent");
+ var items = node.SelectSingleNode("children")?.SelectNodes("Item");
+ if (items?.Count > 0)
+ {
+ children = new string[items.Count];
+ for (int i = 0; i < items.Count; i++)
+ {
+ children[i] = items[i].InnerText;
+ }
+ }
+ }
+
+ public override string ToString()
+ {
+ return parent + ": " + (children?.Length ?? 0).ToString() + " children";
+ }
+ }
+
+
+
+
+
+
+}
+
+
diff --git a/CodeWalker.Core/GameFiles/FileTypes/VehicleLayoutsFile.cs b/CodeWalker.Core/GameFiles/FileTypes/VehicleLayoutsFile.cs
index d5dcf8c..f6b4f3e 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/VehicleLayoutsFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/VehicleLayoutsFile.cs
@@ -26,7 +26,7 @@ namespace CodeWalker.GameFiles
//always XML .meta
- Xml = Encoding.UTF8.GetString(data);
+ Xml = TextUtil.GetUTF8Text(data);
//TODO: parse CVehicleMetadataMgr XML
diff --git a/CodeWalker.Core/GameFiles/FileTypes/VehiclesFile.cs b/CodeWalker.Core/GameFiles/FileTypes/VehiclesFile.cs
index bcd18db..d80485c 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/VehiclesFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/VehiclesFile.cs
@@ -37,14 +37,7 @@ namespace CodeWalker.GameFiles
if (entry.NameLower.EndsWith(".meta"))
{
- //required for update\x64\dlcpacks\mpheist\dlc.rpf\common\data\gtxd.meta and update\x64\dlcpacks\mpluxe\dlc.rpf\common\data\gtxd.meta
- string bom = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
- string xml = Encoding.UTF8.GetString(data);
-
- if (xml.StartsWith(bom, StringComparison.Ordinal))
- {
- xml = xml.Remove(0, bom.Length);
- }
+ string xml = TextUtil.GetUTF8Text(data);
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(xml);
diff --git a/CodeWalker.Core/GameFiles/GameFile.cs b/CodeWalker.Core/GameFiles/GameFile.cs
index e941522..025f192 100644
--- a/CodeWalker.Core/GameFiles/GameFile.cs
+++ b/CodeWalker.Core/GameFiles/GameFile.cs
@@ -75,6 +75,7 @@ namespace CodeWalker.GameFiles
CarModCols = 19,
CarVariations = 20,
VehicleLayouts = 21,
+ Peds = 22,
}
diff --git a/CodeWalker.Core/GameFiles/GameFileCache.cs b/CodeWalker.Core/GameFiles/GameFileCache.cs
index 5051392..c286025 100644
--- a/CodeWalker.Core/GameFiles/GameFileCache.cs
+++ b/CodeWalker.Core/GameFiles/GameFileCache.cs
@@ -79,7 +79,7 @@ namespace CodeWalker.GameFiles
public Dictionary TimeCycleModsDict = new Dictionary();
public Dictionary VehiclesInitDict { get; set; }
-
+ public Dictionary PedsInitDict { get; set; }
public List BaseRpfs { get; private set; }
public List AllRpfs { get; private set; }
@@ -89,6 +89,7 @@ namespace CodeWalker.GameFiles
public bool BuildExtendedJenkIndex = true;
public bool LoadArchetypes = true;
public bool LoadVehicles = false;
+ public bool LoadPeds = false;
private bool PreloadedMode = false;
private string GTAFolder;
@@ -273,6 +274,10 @@ namespace CodeWalker.GameFiles
UpdateStatus("Loading vehicles...");
InitVehicles();
+
+ UpdateStatus("Loading peds...");
+ InitPeds();
+
}
private void InitDlcList()
@@ -1592,6 +1597,69 @@ namespace CodeWalker.GameFiles
}
+ public void InitPeds()
+ {
+ if (!LoadPeds) return;
+
+ IEnumerable rpfs = PreloadedMode ? AllRpfs : (IEnumerable)ActiveMapRpfFiles.Values;
+
+ var allPeds = new Dictionary();
+ var allPedsFiles = new List();
+
+ var addPedsFiles = new Action>((from) =>
+ {
+ foreach (RpfFile file in from)
+ {
+ if (file.AllEntries == null) continue;
+ foreach (RpfEntry entry in file.AllEntries)
+ {
+#if !DEBUG
+ try
+#endif
+ {
+ if ((entry.NameLower == "peds.ymt") || (entry.NameLower == "peds.meta"))
+ {
+ var pf = RpfMan.GetFile(entry);
+ if (pf.InitDataList?.InitDatas != null)
+ {
+ foreach (var initData in pf.InitDataList.InitDatas)
+ {
+ var name = initData.Name.ToLowerInvariant();
+ var hash = JenkHash.GenHash(name);
+ if (allPeds.ContainsKey(hash))
+ { }
+ allPeds[hash] = initData;
+ }
+ }
+ allPedsFiles.Add(pf);
+ }
+ }
+#if !DEBUG
+ catch (Exception ex)
+ {
+ string errstr = entry.Path + "\n" + ex.ToString();
+ ErrorLog(errstr);
+ }
+#endif
+ }
+ }
+
+ });
+
+
+ addPedsFiles(rpfs);
+
+ if (EnableDlc)
+ {
+ addPedsFiles(DlcActiveRpfs);
+ }
+
+
+ PedsInitDict = allPeds;
+
+
+ }
+
public bool SetDlcLevel(string dlc, bool enable)
{
diff --git a/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs b/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs
index 4d378c1..5c7cf49 100644
--- a/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs
+++ b/CodeWalker.Core/GameFiles/MetaTypes/Meta.cs
@@ -1110,10 +1110,7 @@ namespace CodeWalker.GameFiles
{
var str = JenkIndex.TryGetString(Hash);
if (!string.IsNullOrEmpty(str)) return str;
- if (Enum.IsDefined(typeof(MetaName), Hash))
- {
- return ((MetaName)Hash).ToString();
- }
+ if (MetaNames.TryGetString(Hash, out str)) return str;
return GlobalText.GetString(Hash);
}
diff --git a/CodeWalker.Core/GameFiles/MetaTypes/MetaNames.cs b/CodeWalker.Core/GameFiles/MetaTypes/MetaNames.cs
index b68dd72..8dc8524 100644
--- a/CodeWalker.Core/GameFiles/MetaTypes/MetaNames.cs
+++ b/CodeWalker.Core/GameFiles/MetaTypes/MetaNames.cs
@@ -8,6 +8,21 @@ using System.Threading.Tasks;
namespace CodeWalker.GameFiles
{
+ public static class MetaNames
+ {
+ public static bool TryGetString(uint h, out string str)
+ {
+ if (Enum.IsDefined(typeof(MetaName), h))
+ {
+ str = ((MetaName)h).ToString();
+ if (str.StartsWith("@")) str = str.Substring(1); //mainly to handle the @null entry
+ return true;
+ }
+ str = null;
+ return false;
+ }
+ }
+
public class MetaNamesUtil
{
@@ -3468,11 +3483,60 @@ namespace CodeWalker.GameFiles
ePedVarComp = 884254308,
ePropRenderFlags = 4212977111,
CPedPropTexData = 254518642,
+ eScenarioPopStreamingSlot = 3029795674,
+ eFadeCurveType = 3057039286,
+ eSuperlodType = 4015041481,
+ ePedRadioGenre = 2942646938,
+ eSexinessFlags = 374769227,
+ eExternallyDrivenDOFs = 637184392,
+ SpecialAbilityType = 2011786168,
+ DefaultSpawnPreference = 888587604,
CScenarioChainingEdge__eAction = 3609807418,
CScenarioChainingEdge__eNavMode = 3971773454,
CScenarioChainingEdge__eNavSpeed = 941086046,
+ standard_ped = 2703423328, //in peds.ymt
+ standard_male = 1860494962, //in peds.ymt PedCapsuleName
+ standard_female = 3778684510, //in peds.ymt PedCapsuleName
+ facial_clipset_group_gen_male = 2968316036, //in peds.ymt FacialClipsetGroupName
+ facial_clipset_group_gen_female = 984918963, //in peds.ymt FacialClipsetGroupName
+ facial_clipset_group_p_m_zero = 3839850645, //in peds.ymt FacialClipsetGroupName
+ facial_clipset_group_p_m_one = 3697506179, //in peds.ymt FacialClipsetGroupName
+ facial_clipset_group_p_m_two = 3958944905, //in peds.ymt FacialClipsetGroupName
+ anim_group_gesture_m_generic = 4080627616, //in peds.ymt DefaultGestureClipSet
+ anim_group_gesture_f_generic = 1375166916, //in peds.ymt DefaultGestureClipSet
+ anim_group_visemes_m_lo = 3326036851, //in peds.ymt DefaultVisemeClipSet
+ anim_group_visemes_f_lo = 2783456433, //in peds.ymt DefaultVisemeClipSet
+ nmbs_slow_getups = 69709351, //peds.ymt GetupSetHash
+ clip_set_id_invalid = 2106583169, //in peds.ymt
+ move_strafe_injured = 1434752434, //in peds.ymt InjuredStrafeClipSet
+ move_ped_to_strafe = 3943634031, //in peds.ymt MovementToStrafeClipSet
+ move_ped_strafing = 2464962150, //in peds.ymt StrafeClipSet
+ civmale = 45677184, //in peds.ymt Pedtype
+ civfemale = 1191392768, //in peds.ymt Pedtype
+ vfxpedinfo_human_generic = 1167185222, //in peds.ymt VfxInfoName
+ expr_set_ambient_male = 2495275024, //in peds.ymt ExpressionSetName
+ expr_set_ambient_female = 3793172393, //in peds.ymt ExpressionSetName
+ default_perception = 3537703288, //in peds.ymt PerceptionInfo
+ streamed_male = 4014297412, //in peds.ymt Personality
+ streamed_female = 991949850, //in peds.ymt Personality
+ fitnessmale = 921466782, //in peds.ymt Personality
+ fitnessfemale = 419688606, //in peds.ymt Personality
+ youngrichman = 3818603935, //in peds.ymt Personality
+ youngrichwoman = 367809573, //in peds.ymt Personality
+ youngaverageweakman = 3971800366, //in peds.ymt Personality
+ youngaverageweakwoman = 806694113, //in peds.ymt Personality
+ bs_ai = 2150391885, //in peds.ymt DefaultBrawlingStyle
+ bs_franklin = 1037948029, //in peds.ymt DefaultBrawlingStyle
+ bs_michael = 2057220685, //in peds.ymt DefaultBrawlingStyle
+ bs_trevor = 1249954968, //in peds.ymt DefaultBrawlingStyle
+ weapon_unarmed = 2725352035, //in peds.ymt DefaultUnarmedWeapon
+ silent_pvg = 423993118, //in peds.ymt PedVoiceGroup
+ silent_cutscene_pvg = 1896822940, //in peds.ymt PedVoiceGroup
+
+ @null = 987444055, // how best to handle this? C# doesn't like it
+
diff --git a/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs b/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs
index a39a167..869dc32 100644
--- a/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs
+++ b/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs
@@ -1827,12 +1827,10 @@ namespace CodeWalker.GameFiles
uint uh = (uint)h;
if (uh == 0) return "";
- if (Enum.IsDefined(typeof(MetaName), h))
- {
- return h.ToString();
- }
+ string str;
+ if (MetaNames.TryGetString(uh, out str)) return str;
- var str = JenkIndex.TryGetString(uh);
+ str = JenkIndex.TryGetString(uh);
if (!string.IsNullOrEmpty(str)) return str;
//TODO: do extra hash lookup here
@@ -1849,11 +1847,7 @@ namespace CodeWalker.GameFiles
if (string.IsNullOrEmpty(str))
{
- var nh = (MetaName)(uint)h;
- if (Enum.IsDefined(typeof(MetaName), nh))
- {
- return nh.ToString();
- }
+ if (MetaNames.TryGetString(h, out str)) return str;
}
//todo: make sure JenkIndex is built!
@@ -1880,12 +1874,10 @@ namespace CodeWalker.GameFiles
public static string UintString(uint h)
{
- if (Enum.IsDefined(typeof(MetaName), h))
- {
- return ((MetaName)h).ToString();
- }
+ string str;
+ if (MetaNames.TryGetString(h, out str)) return str;
- var str = JenkIndex.TryGetString(h);
+ str = JenkIndex.TryGetString(h);
if (!string.IsNullOrEmpty(str)) return str;
//TODO: do extra hash lookup here
diff --git a/CodeWalker.Core/GameFiles/MetaTypes/PsoTypes.cs b/CodeWalker.Core/GameFiles/MetaTypes/PsoTypes.cs
index ba432f3..419e2cf 100644
--- a/CodeWalker.Core/GameFiles/MetaTypes/PsoTypes.cs
+++ b/CodeWalker.Core/GameFiles/MetaTypes/PsoTypes.cs
@@ -800,8 +800,8 @@ namespace CodeWalker.GameFiles
new PsoStructureEntryInfo(MetaName.CombatInfo, PsoDataType.String, 192, 7, 0),
new PsoStructureEntryInfo(MetaName.VfxInfoName, PsoDataType.String, 196, 7, 0),
new PsoStructureEntryInfo(MetaName.AmbientClipsForFlee, PsoDataType.String, 200, 7, 0),
- new PsoStructureEntryInfo(MetaName.Radio1, PsoDataType.Enum, 204, 0, (MetaName)2942646938),
- new PsoStructureEntryInfo(MetaName.Radio2, PsoDataType.Enum, 208, 0, (MetaName)2942646938),
+ new PsoStructureEntryInfo(MetaName.Radio1, PsoDataType.Enum, 204, 0, MetaName.ePedRadioGenre),
+ new PsoStructureEntryInfo(MetaName.Radio2, PsoDataType.Enum, 208, 0, MetaName.ePedRadioGenre),
new PsoStructureEntryInfo(MetaName.FUpOffset, PsoDataType.Float, 212, 0, 0),
new PsoStructureEntryInfo(MetaName.RUpOffset, PsoDataType.Float, 216, 0, 0),
new PsoStructureEntryInfo(MetaName.FFrontOffset, PsoDataType.Float, 220, 0, 0),
@@ -811,19 +811,19 @@ namespace CodeWalker.GameFiles
new PsoStructureEntryInfo(MetaName.HDDist, PsoDataType.Float, 236, 0, 0),
new PsoStructureEntryInfo(MetaName.TargetingThreatModifier, PsoDataType.Float, 240, 0, 0),
new PsoStructureEntryInfo(MetaName.KilledPerceptionRangeModifer, PsoDataType.Float, 244, 0, 0),
- new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.Enum, 0, 0, (MetaName)374769227),
+ new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.Enum, 0, 0, MetaName.eSexinessFlags),
new PsoStructureEntryInfo(MetaName.Sexiness, PsoDataType.Flags, 248, 0, (MetaName)2097211),
new PsoStructureEntryInfo(MetaName.Age, PsoDataType.UByte, 252, 0, 0),
new PsoStructureEntryInfo(MetaName.MaxPassengersInCar, PsoDataType.UByte, 253, 0, 0),
- new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.Enum, 0, 0, (MetaName)637184392),
+ new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.Enum, 0, 0, MetaName.eExternallyDrivenDOFs),
new PsoStructureEntryInfo(MetaName.ExternallyDrivenDOFs, PsoDataType.Flags, 254, 2, (MetaName)327743),
new PsoStructureEntryInfo(MetaName.PedVoiceGroup, PsoDataType.String, 256, 7, 0),
new PsoStructureEntryInfo(MetaName.AnimalAudioObject, PsoDataType.String, 260, 7, 0),
- new PsoStructureEntryInfo(MetaName.AbilityType, PsoDataType.Enum, 264, 0, (MetaName)2011786168),
+ new PsoStructureEntryInfo(MetaName.AbilityType, PsoDataType.Enum, 264, 0, MetaName.SpecialAbilityType),
new PsoStructureEntryInfo(MetaName.ThermalBehaviour, PsoDataType.Enum, 268, 0, MetaName.ThermalBehaviour),
- new PsoStructureEntryInfo(MetaName.SuperlodType, PsoDataType.Enum, 272, 0, (MetaName)4015041481),
- new PsoStructureEntryInfo(MetaName.ScenarioPopStreamingSlot, PsoDataType.Enum, 276, 0, (MetaName)3029795674),
- new PsoStructureEntryInfo(MetaName.DefaultSpawningPreference, PsoDataType.Enum, 280, 0, (MetaName)888587604),
+ new PsoStructureEntryInfo(MetaName.SuperlodType, PsoDataType.Enum, 272, 0, MetaName.eSuperlodType),
+ new PsoStructureEntryInfo(MetaName.ScenarioPopStreamingSlot, PsoDataType.Enum, 276, 0, MetaName.eScenarioPopStreamingSlot),
+ new PsoStructureEntryInfo(MetaName.DefaultSpawningPreference, PsoDataType.Enum, 280, 0, MetaName.DefaultSpawnPreference),
new PsoStructureEntryInfo(MetaName.DefaultRemoveRangeMultiplier, PsoDataType.Float, 284, 0, 0),
new PsoStructureEntryInfo(MetaName.AllowCloseSpawning, PsoDataType.Bool, 288, 0, 0)
);
@@ -841,7 +841,7 @@ namespace CodeWalker.GameFiles
new PsoStructureEntryInfo(MetaName.mediumCharge, PsoDataType.SInt, 28, 0, 0),
new PsoStructureEntryInfo(MetaName.largeCharge, PsoDataType.SInt, 32, 0, 0),
new PsoStructureEntryInfo(MetaName.continuousCharge, PsoDataType.SInt, 36, 0, 0),
- new PsoStructureEntryInfo(MetaName.fadeCurveType, PsoDataType.Enum, 40, 0, (MetaName)3057039286),
+ new PsoStructureEntryInfo(MetaName.fadeCurveType, PsoDataType.Enum, 40, 0, MetaName.eFadeCurveType),
new PsoStructureEntryInfo(MetaName.halfSigmoidConstant, PsoDataType.Float, 44, 0, 0),
new PsoStructureEntryInfo(MetaName.sigmoidConstant, PsoDataType.Float, 48, 0, 0),
new PsoStructureEntryInfo(MetaName.fadeInTime, PsoDataType.Float, 52, 0, 0),
@@ -14849,8 +14849,8 @@ namespace CodeWalker.GameFiles
new PsoEnumEntryInfo(MetaName.PARTITION_2, 2),
new PsoEnumEntryInfo(MetaName.PARTITION_MAX, 3)
);
- case (MetaName)2942646938:
- return new PsoEnumInfo((MetaName)2942646938, 1,
+ case MetaName.ePedRadioGenre:
+ return new PsoEnumInfo(MetaName.ePedRadioGenre, 1,
new PsoEnumEntryInfo(MetaName.RADIO_GENRE_OFF, 0),
new PsoEnumEntryInfo(MetaName.RADIO_GENRE_MODERN_ROCK, 1),
new PsoEnumEntryInfo(MetaName.RADIO_GENRE_CLASSIC_ROCK, 2),
@@ -14869,20 +14869,20 @@ namespace CodeWalker.GameFiles
new PsoEnumEntryInfo(MetaName.RADIO_GENRE_SURF, 15),
new PsoEnumEntryInfo(MetaName.RADIO_GENRE_UNSPECIFIED, 16)
);
- case (MetaName)374769227:
- return new PsoEnumInfo((MetaName)374769227, 1,
+ case MetaName.eSexinessFlags:
+ return new PsoEnumInfo(MetaName.eSexinessFlags, 1,
new PsoEnumEntryInfo(MetaName.SF_JEER_AT_HOT_PED, 0),
new PsoEnumEntryInfo((MetaName)296569367, 1),
new PsoEnumEntryInfo(MetaName.SF_HOT_PERSON, 2)
);
- case (MetaName)637184392:
- return new PsoEnumInfo((MetaName)637184392, 1,
+ case MetaName.eExternallyDrivenDOFs:
+ return new PsoEnumInfo(MetaName.eExternallyDrivenDOFs, 1,
new PsoEnumEntryInfo(MetaName.EMPTY, 0),
new PsoEnumEntryInfo(MetaName.HIGH_HEELS, 1),
new PsoEnumEntryInfo(MetaName.COLLAR, 2)
);
- case (MetaName)2011786168:
- return new PsoEnumInfo((MetaName)2011786168, 1,
+ case MetaName.SpecialAbilityType: //CPedModelInfo__InitData AbilityType
+ return new PsoEnumInfo(MetaName.SpecialAbilityType, 1,
new PsoEnumEntryInfo(MetaName.SAT_NONE, -1),
new PsoEnumEntryInfo(MetaName.SAT_CAR_SLOWDOWN, 0),
new PsoEnumEntryInfo(MetaName.SAT_RAGE, 1),
@@ -14897,28 +14897,28 @@ namespace CodeWalker.GameFiles
new PsoEnumEntryInfo(MetaName.TB_WARM, 2),
new PsoEnumEntryInfo(MetaName.TB_HOT, 3)
);
- case (MetaName)4015041481:
- return new PsoEnumInfo((MetaName)4015041481, 1,
+ case MetaName.eSuperlodType:
+ return new PsoEnumInfo(MetaName.eSuperlodType, 1,
new PsoEnumEntryInfo(MetaName.SLOD_HUMAN, 0),
new PsoEnumEntryInfo(MetaName.SLOD_SMALL_QUADPED, 1),
new PsoEnumEntryInfo(MetaName.SLOD_LARGE_QUADPED, 2),
new PsoEnumEntryInfo(MetaName.SLOD_NULL, 3),
new PsoEnumEntryInfo(MetaName.SLOD_KEEP_LOWEST, 4)
);
- case (MetaName)3029795674: //CPedModelInfo__InitData ScenarioPopStreamingSlot
- return new PsoEnumInfo((MetaName)3029795674, 1,
+ case MetaName.eScenarioPopStreamingSlot: //CPedModelInfo__InitData ScenarioPopStreamingSlot
+ return new PsoEnumInfo(MetaName.eScenarioPopStreamingSlot, 1,
new PsoEnumEntryInfo(MetaName.SCENARIO_POP_STREAMING_NORMAL, 0),
new PsoEnumEntryInfo(MetaName.SCENARIO_POP_STREAMING_SMALL, 1)
);
- case (MetaName)888587604:
- return new PsoEnumInfo((MetaName)888587604, 1,
+ case MetaName.DefaultSpawnPreference: //CPedModelInfo__InitData DefaultSpawningPreference
+ return new PsoEnumInfo(MetaName.DefaultSpawnPreference, 1,
new PsoEnumEntryInfo(MetaName.DSP_AERIAL, 0),
new PsoEnumEntryInfo(MetaName.DSP_AQUATIC, 1),
new PsoEnumEntryInfo(MetaName.DSP_GROUND_WILDLIFE, 2),
new PsoEnumEntryInfo(MetaName.DSP_NORMAL, 3)
);
- case (MetaName)3057039286:
- return new PsoEnumInfo((MetaName)3057039286, 1,
+ case MetaName.eFadeCurveType:
+ return new PsoEnumInfo(MetaName.eFadeCurveType, 1,
new PsoEnumEntryInfo(MetaName.FCT_NONE, 0),
new PsoEnumEntryInfo(MetaName.FCT_LINEAR, 1),
new PsoEnumEntryInfo(MetaName.FCT_HALF_SIGMOID, 2),
diff --git a/CodeWalker.Core/GameFiles/Resources/Drawable.cs b/CodeWalker.Core/GameFiles/Resources/Drawable.cs
index afd034b..ad44539 100644
--- a/CodeWalker.Core/GameFiles/Resources/Drawable.cs
+++ b/CodeWalker.Core/GameFiles/Resources/Drawable.cs
@@ -541,13 +541,13 @@ namespace CodeWalker.GameFiles
public Matrix[] TransformationsInverted { get; set; }
public Matrix[] Transformations { get; set; }
- public ushort[] ParentIndices { get; set; }
- public ushort[] ChildIndices { get; set; }//mapping child->parent indices, first child index, then parent
+ public short[] ParentIndices { get; set; }
+ public short[] ChildIndices { get; set; }//mapping child->parent indices, first child index, then parent
private ResourceSystemStructBlock TransformationsInvertedBlock = null;//for saving only
private ResourceSystemStructBlock TransformationsBlock = null;
- private ResourceSystemStructBlock ParentIndicesBlock = null;
- private ResourceSystemStructBlock ChildIndicesBlock = null;
+ private ResourceSystemStructBlock ParentIndicesBlock = null;
+ private ResourceSystemStructBlock ChildIndicesBlock = null;
public Dictionary BonesMap { get; set; }//for convienience finding bones by tag
@@ -597,8 +597,8 @@ namespace CodeWalker.GameFiles
);
this.TransformationsInverted = reader.ReadStructsAt(this.TransformationsInvertedPointer, this.BonesCount);
this.Transformations = reader.ReadStructsAt(this.TransformationsPointer, this.BonesCount);
- this.ParentIndices = reader.ReadUshortsAt(this.ParentIndicesPointer, this.BonesCount);
- this.ChildIndices = reader.ReadUshortsAt(this.ChildIndicesPointer, this.ChildIndicesCount);
+ this.ParentIndices = reader.ReadShortsAt(this.ParentIndicesPointer, this.BonesCount);
+ this.ChildIndices = reader.ReadShortsAt(this.ChildIndicesPointer, this.ChildIndicesCount);
if ((Bones != null) && (ParentIndices != null))
@@ -608,7 +608,7 @@ namespace CodeWalker.GameFiles
{
var bone = Bones[i];
var pind = ParentIndices[i];
- if (pind < Bones.Count)
+ if ((pind >= 0) && (pind < Bones.Count))
{
bone.Parent = Bones[pind];
}
@@ -698,12 +698,12 @@ namespace CodeWalker.GameFiles
}
if (ParentIndices != null)
{
- ParentIndicesBlock = new ResourceSystemStructBlock(ParentIndices);
+ ParentIndicesBlock = new ResourceSystemStructBlock(ParentIndices);
list.Add(ParentIndicesBlock);
}
if (ChildIndices != null)
{
- ChildIndicesBlock = new ResourceSystemStructBlock(ChildIndices);
+ ChildIndicesBlock = new ResourceSystemStructBlock(ChildIndices);
list.Add(ChildIndicesBlock);
}
return list.ToArray();
@@ -771,6 +771,27 @@ namespace CodeWalker.GameFiles
}
}
+ [Flags] public enum EBoneFlags : ushort
+ {
+ None = 0,
+ RotX = 0x1,
+ RotY = 0x2,
+ RotZ = 0x4,
+ LimitRotation = 0x8,
+ TransX = 0x10,
+ TransY = 0x20,
+ TransZ = 0x40,
+ LimitTranslation = 0x80,
+ ScaleX = 0x100,
+ ScaleY = 0x200,
+ ScaleZ = 0x400,
+ LimitScale = 0x800,
+ Unk0 = 0x1000,
+ Unk1 = 0x2000,
+ Unk2 = 0x4000,
+ Unk3 = 0x8000,
+ }
+
[TypeConverter(typeof(ExpandableObjectConverter))] public class Bone : ResourceSystemBlock
{
public override long BlockLength
@@ -788,14 +809,14 @@ namespace CodeWalker.GameFiles
public uint Unknown_1Ch { get; set; } // 0x00000000 RHW?
public Vector3 Scale { get; set; }
public float Unknown_2Ch { get; set; } // 1.0 RHW?
- public ushort NextSiblingIndex { get; set; } //limb end index? IK chain?
+ public short NextSiblingIndex { get; set; } //limb end index? IK chain?
public short ParentIndex { get; set; }
public uint Unknown_34h { get; set; } // 0x00000000
public ulong NamePointer { get; set; }
- public ushort Flags { get; set; }
- public ushort Index { get; set; }
+ public EBoneFlags Flags { get; set; }
+ public short Index { get; set; }
public ushort Tag { get; set; }
- public ushort Index2 { get; set; }//same as Index?
+ public short Index2 { get; set; }//same as Index?
public uint Unknown_48h { get; set; } // 0x00000000
public uint Unknown_4Ch { get; set; } // 0x00000000
@@ -826,14 +847,14 @@ namespace CodeWalker.GameFiles
this.Unknown_1Ch = reader.ReadUInt32();
this.Scale = reader.ReadVector3();
this.Unknown_2Ch = reader.ReadSingle();
- this.NextSiblingIndex = reader.ReadUInt16();
+ this.NextSiblingIndex = reader.ReadInt16();
this.ParentIndex = reader.ReadInt16();
this.Unknown_34h = reader.ReadUInt32();
this.NamePointer = reader.ReadUInt64();
- this.Flags = reader.ReadUInt16();
- this.Index = reader.ReadUInt16();
+ this.Flags = (EBoneFlags)reader.ReadUInt16();
+ this.Index = reader.ReadInt16();
this.Tag = reader.ReadUInt16();
- this.Index2 = reader.ReadUInt16();
+ this.Index2 = reader.ReadInt16();
this.Unknown_48h = reader.ReadUInt32();
this.Unknown_4Ch = reader.ReadUInt32();
@@ -866,7 +887,7 @@ namespace CodeWalker.GameFiles
writer.Write(this.ParentIndex);
writer.Write(this.Unknown_34h);
writer.Write(this.NamePointer);
- writer.Write(this.Flags);
+ writer.Write((ushort)this.Flags);
writer.Write(this.Index);
writer.Write(this.Tag);
writer.Write(this.Index2);
diff --git a/CodeWalker.Core/GameFiles/Resources/ResourceData.cs b/CodeWalker.Core/GameFiles/Resources/ResourceData.cs
index c34bc44..2a92f68 100644
--- a/CodeWalker.Core/GameFiles/Resources/ResourceData.cs
+++ b/CodeWalker.Core/GameFiles/Resources/ResourceData.cs
@@ -266,6 +266,15 @@ namespace CodeWalker.GameFiles
//Position = posbackup;
return result;
}
+ public short[] ReadShortsAt(ulong position, uint count)
+ {
+ if ((position <= 0) || (count == 0)) return null;
+ var result = new short[count];
+ var length = count * 2;
+ byte[] data = ReadBytesAt(position, length);
+ Buffer.BlockCopy(data, 0, result, 0, (int)length);
+ return result;
+ }
public uint[] ReadUintsAt(ulong position, uint count)
{
if ((position <= 0) || (count == 0)) return null;
diff --git a/CodeWalker.Core/GameFiles/RpfManager.cs b/CodeWalker.Core/GameFiles/RpfManager.cs
index 3f7d8fc..78075c6 100644
--- a/CodeWalker.Core/GameFiles/RpfManager.cs
+++ b/CodeWalker.Core/GameFiles/RpfManager.cs
@@ -283,18 +283,7 @@ namespace CodeWalker.GameFiles
public string GetFileUTF8Text(string path)
{
byte[] bytes = GetFileData(path);
- if (bytes == null)
- { return string.Empty; } //file not found..
- if ((bytes.Length > 3) && (bytes[0] == 0xEF) && (bytes[1] == 0xBB) && (bytes[2] == 0xBF))
- {
- byte[] newb = new byte[bytes.Length - 3];
- for (int i = 3; i < bytes.Length; i++)
- {
- newb[i - 3] = bytes[i];
- }
- bytes = newb; //trim starting 3 "magic" bytes?
- }
- return Encoding.UTF8.GetString(bytes);
+ return TextUtil.GetUTF8Text(bytes);
}
public XmlDocument GetFileXml(string path)
{
diff --git a/CodeWalker.Core/Utils/Utils.cs b/CodeWalker.Core/Utils/Utils.cs
index 2f0ef16..2138fbe 100644
--- a/CodeWalker.Core/Utils/Utils.cs
+++ b/CodeWalker.Core/Utils/Utils.cs
@@ -81,6 +81,25 @@ namespace CodeWalker
// Return formatted number with suffix
return readable.ToString(fmt) + suffix;
}
+
+
+
+ public static string GetUTF8Text(byte[] bytes)
+ {
+ if (bytes == null)
+ { return string.Empty; } //file not found..
+ if ((bytes.Length > 3) && (bytes[0] == 0xEF) && (bytes[1] == 0xBB) && (bytes[2] == 0xBF))
+ {
+ byte[] newb = new byte[bytes.Length - 3];
+ for (int i = 3; i < bytes.Length; i++)
+ {
+ newb[i - 3] = bytes[i];
+ }
+ bytes = newb; //trim starting byte order mark
+ }
+ return Encoding.UTF8.GetString(bytes);
+ }
+
}
diff --git a/CodeWalker.csproj b/CodeWalker.csproj
index de19481..9758a4c 100644
--- a/CodeWalker.csproj
+++ b/CodeWalker.csproj
@@ -149,6 +149,12 @@
ModelMatForm.cs
+
+ Form
+
+
+ PedsForm.cs
+
Form
@@ -592,6 +598,9 @@
ModelMatForm.cs
+
+ PedsForm.cs
+
GenerateLODLightsPanel.cs
diff --git a/Peds/PedsForm.Designer.cs b/Peds/PedsForm.Designer.cs
new file mode 100644
index 0000000..a82d4f5
--- /dev/null
+++ b/Peds/PedsForm.Designer.cs
@@ -0,0 +1,758 @@
+namespace CodeWalker.Peds
+{
+ partial class PedsForm
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PedsForm));
+ this.ConsoleTextBox = new CodeWalker.WinForms.TextBoxFix();
+ this.ToolsPanelShowButton = new System.Windows.Forms.Button();
+ this.ToolsPanelHideButton = new System.Windows.Forms.Button();
+ this.ToolsDragPanel = new System.Windows.Forms.Panel();
+ this.ConsolePanel = new System.Windows.Forms.Panel();
+ this.HDTexturesCheckBox = new System.Windows.Forms.CheckBox();
+ this.SkeletonsCheckBox = new System.Windows.Forms.CheckBox();
+ this.TimeOfDayLabel = new System.Windows.Forms.Label();
+ this.ToolsOptionsTabPage = new System.Windows.Forms.TabPage();
+ this.label19 = new System.Windows.Forms.Label();
+ this.TimeOfDayTrackBar = new System.Windows.Forms.TrackBar();
+ this.ControlLightDirCheckBox = new System.Windows.Forms.CheckBox();
+ this.ShowCollisionMeshesCheckBox = new System.Windows.Forms.CheckBox();
+ this.GridCheckBox = new System.Windows.Forms.CheckBox();
+ this.GridCountComboBox = new System.Windows.Forms.ComboBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.GridSizeComboBox = new System.Windows.Forms.ComboBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.StatusBarCheckBox = new System.Windows.Forms.CheckBox();
+ this.ErrorConsoleCheckBox = new System.Windows.Forms.CheckBox();
+ this.HDRRenderingCheckBox = new System.Windows.Forms.CheckBox();
+ this.SkydomeCheckBox = new System.Windows.Forms.CheckBox();
+ this.ShadowsCheckBox = new System.Windows.Forms.CheckBox();
+ this.WireframeCheckBox = new System.Windows.Forms.CheckBox();
+ this.RenderModeComboBox = new System.Windows.Forms.ComboBox();
+ this.label11 = new System.Windows.Forms.Label();
+ this.TextureSamplerComboBox = new System.Windows.Forms.ComboBox();
+ this.TextureCoordsComboBox = new System.Windows.Forms.ComboBox();
+ this.label10 = new System.Windows.Forms.Label();
+ this.AnisotropicFilteringCheckBox = new System.Windows.Forms.CheckBox();
+ this.label14 = new System.Windows.Forms.Label();
+ this.DetailsPropertyGrid = new CodeWalker.WinForms.ReadOnlyPropertyGrid();
+ this.ToolsDetailsTabPage = new System.Windows.Forms.TabPage();
+ this.TextureViewerButton = new System.Windows.Forms.Button();
+ this.TexturesTreeView = new CodeWalker.WinForms.TreeViewFix();
+ this.ToolsTexturesTabPage = new System.Windows.Forms.TabPage();
+ this.ModelsTreeView = new CodeWalker.WinForms.TreeViewFix();
+ this.StatusStrip = new System.Windows.Forms.StatusStrip();
+ this.StatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
+ this.MousedLabel = new System.Windows.Forms.ToolStripStatusLabel();
+ this.StatsLabel = new System.Windows.Forms.ToolStripStatusLabel();
+ this.ToolsModelsTabPage = new System.Windows.Forms.TabPage();
+ this.label3 = new System.Windows.Forms.Label();
+ this.PedNameComboBox = new System.Windows.Forms.ComboBox();
+ this.StatsUpdateTimer = new System.Windows.Forms.Timer(this.components);
+ this.ToolsPedTabPage = new System.Windows.Forms.TabPage();
+ this.ToolsTabControl = new System.Windows.Forms.TabControl();
+ this.ToolsPanel = new System.Windows.Forms.Panel();
+ this.ConsolePanel.SuspendLayout();
+ this.ToolsOptionsTabPage.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.TimeOfDayTrackBar)).BeginInit();
+ this.ToolsDetailsTabPage.SuspendLayout();
+ this.ToolsTexturesTabPage.SuspendLayout();
+ this.StatusStrip.SuspendLayout();
+ this.ToolsModelsTabPage.SuspendLayout();
+ this.ToolsPedTabPage.SuspendLayout();
+ this.ToolsTabControl.SuspendLayout();
+ this.ToolsPanel.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // ConsoleTextBox
+ //
+ this.ConsoleTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ConsoleTextBox.Location = new System.Drawing.Point(3, 3);
+ this.ConsoleTextBox.Multiline = true;
+ this.ConsoleTextBox.Name = "ConsoleTextBox";
+ this.ConsoleTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+ this.ConsoleTextBox.Size = new System.Drawing.Size(695, 95);
+ this.ConsoleTextBox.TabIndex = 0;
+ //
+ // ToolsPanelShowButton
+ //
+ this.ToolsPanelShowButton.Location = new System.Drawing.Point(15, 15);
+ this.ToolsPanelShowButton.Name = "ToolsPanelShowButton";
+ this.ToolsPanelShowButton.Size = new System.Drawing.Size(30, 23);
+ this.ToolsPanelShowButton.TabIndex = 8;
+ this.ToolsPanelShowButton.Text = ">>";
+ this.ToolsPanelShowButton.UseVisualStyleBackColor = true;
+ this.ToolsPanelShowButton.Click += new System.EventHandler(this.ToolsPanelShowButton_Click);
+ //
+ // ToolsPanelHideButton
+ //
+ this.ToolsPanelHideButton.Location = new System.Drawing.Point(3, 3);
+ this.ToolsPanelHideButton.Name = "ToolsPanelHideButton";
+ this.ToolsPanelHideButton.Size = new System.Drawing.Size(30, 23);
+ this.ToolsPanelHideButton.TabIndex = 0;
+ this.ToolsPanelHideButton.Text = "<<";
+ this.ToolsPanelHideButton.UseVisualStyleBackColor = true;
+ this.ToolsPanelHideButton.Click += new System.EventHandler(this.ToolsPanelHideButton_Click);
+ //
+ // ToolsDragPanel
+ //
+ this.ToolsDragPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ToolsDragPanel.Cursor = System.Windows.Forms.Cursors.VSplit;
+ this.ToolsDragPanel.Location = new System.Drawing.Point(249, 0);
+ this.ToolsDragPanel.Name = "ToolsDragPanel";
+ this.ToolsDragPanel.Size = new System.Drawing.Size(4, 666);
+ this.ToolsDragPanel.TabIndex = 17;
+ this.ToolsDragPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ToolsDragPanel_MouseDown);
+ this.ToolsDragPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ToolsDragPanel_MouseMove);
+ this.ToolsDragPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ToolsDragPanel_MouseUp);
+ //
+ // ConsolePanel
+ //
+ this.ConsolePanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ConsolePanel.BackColor = System.Drawing.SystemColors.Control;
+ this.ConsolePanel.Controls.Add(this.ConsoleTextBox);
+ this.ConsolePanel.Location = new System.Drawing.Point(271, 577);
+ this.ConsolePanel.Name = "ConsolePanel";
+ this.ConsolePanel.Size = new System.Drawing.Size(701, 101);
+ this.ConsolePanel.TabIndex = 9;
+ this.ConsolePanel.Visible = false;
+ //
+ // HDTexturesCheckBox
+ //
+ this.HDTexturesCheckBox.AutoSize = true;
+ this.HDTexturesCheckBox.Checked = true;
+ this.HDTexturesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.HDTexturesCheckBox.Location = new System.Drawing.Point(19, 242);
+ this.HDTexturesCheckBox.Name = "HDTexturesCheckBox";
+ this.HDTexturesCheckBox.Size = new System.Drawing.Size(82, 17);
+ this.HDTexturesCheckBox.TabIndex = 10;
+ this.HDTexturesCheckBox.Text = "HD textures";
+ this.HDTexturesCheckBox.UseVisualStyleBackColor = true;
+ this.HDTexturesCheckBox.CheckedChanged += new System.EventHandler(this.HDTexturesCheckBox_CheckedChanged);
+ //
+ // SkeletonsCheckBox
+ //
+ this.SkeletonsCheckBox.AutoSize = true;
+ this.SkeletonsCheckBox.Location = new System.Drawing.Point(19, 444);
+ this.SkeletonsCheckBox.Name = "SkeletonsCheckBox";
+ this.SkeletonsCheckBox.Size = new System.Drawing.Size(103, 17);
+ this.SkeletonsCheckBox.TabIndex = 22;
+ this.SkeletonsCheckBox.Text = "Show Skeletons";
+ this.SkeletonsCheckBox.UseVisualStyleBackColor = true;
+ this.SkeletonsCheckBox.CheckedChanged += new System.EventHandler(this.SkeletonsCheckBox_CheckedChanged);
+ //
+ // TimeOfDayLabel
+ //
+ this.TimeOfDayLabel.AutoSize = true;
+ this.TimeOfDayLabel.Location = new System.Drawing.Point(78, 109);
+ this.TimeOfDayLabel.Name = "TimeOfDayLabel";
+ this.TimeOfDayLabel.Size = new System.Drawing.Size(34, 13);
+ this.TimeOfDayLabel.TabIndex = 5;
+ this.TimeOfDayLabel.Text = "12:00";
+ //
+ // ToolsOptionsTabPage
+ //
+ this.ToolsOptionsTabPage.Controls.Add(this.HDTexturesCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.SkeletonsCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.TimeOfDayLabel);
+ this.ToolsOptionsTabPage.Controls.Add(this.label19);
+ this.ToolsOptionsTabPage.Controls.Add(this.TimeOfDayTrackBar);
+ this.ToolsOptionsTabPage.Controls.Add(this.ControlLightDirCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.ShowCollisionMeshesCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.GridCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.GridCountComboBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.label2);
+ this.ToolsOptionsTabPage.Controls.Add(this.GridSizeComboBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.label1);
+ this.ToolsOptionsTabPage.Controls.Add(this.StatusBarCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.ErrorConsoleCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.HDRRenderingCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.SkydomeCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.ShadowsCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.WireframeCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.RenderModeComboBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.label11);
+ this.ToolsOptionsTabPage.Controls.Add(this.TextureSamplerComboBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.TextureCoordsComboBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.label10);
+ this.ToolsOptionsTabPage.Controls.Add(this.AnisotropicFilteringCheckBox);
+ this.ToolsOptionsTabPage.Controls.Add(this.label14);
+ this.ToolsOptionsTabPage.Location = new System.Drawing.Point(4, 22);
+ this.ToolsOptionsTabPage.Name = "ToolsOptionsTabPage";
+ this.ToolsOptionsTabPage.Size = new System.Drawing.Size(239, 607);
+ this.ToolsOptionsTabPage.TabIndex = 3;
+ this.ToolsOptionsTabPage.Text = "Options";
+ this.ToolsOptionsTabPage.UseVisualStyleBackColor = true;
+ //
+ // label19
+ //
+ this.label19.AutoSize = true;
+ this.label19.Location = new System.Drawing.Point(7, 109);
+ this.label19.Name = "label19";
+ this.label19.Size = new System.Drawing.Size(65, 13);
+ this.label19.TabIndex = 4;
+ this.label19.Text = "Time of day:";
+ //
+ // TimeOfDayTrackBar
+ //
+ this.TimeOfDayTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.TimeOfDayTrackBar.BackColor = System.Drawing.SystemColors.ControlLightLight;
+ this.TimeOfDayTrackBar.LargeChange = 60;
+ this.TimeOfDayTrackBar.Location = new System.Drawing.Point(9, 125);
+ this.TimeOfDayTrackBar.Maximum = 1440;
+ this.TimeOfDayTrackBar.Name = "TimeOfDayTrackBar";
+ this.TimeOfDayTrackBar.Size = new System.Drawing.Size(222, 45);
+ this.TimeOfDayTrackBar.TabIndex = 6;
+ this.TimeOfDayTrackBar.TickFrequency = 60;
+ this.TimeOfDayTrackBar.Value = 720;
+ this.TimeOfDayTrackBar.Scroll += new System.EventHandler(this.TimeOfDayTrackBar_Scroll);
+ //
+ // ControlLightDirCheckBox
+ //
+ this.ControlLightDirCheckBox.AutoSize = true;
+ this.ControlLightDirCheckBox.Location = new System.Drawing.Point(19, 83);
+ this.ControlLightDirCheckBox.Name = "ControlLightDirCheckBox";
+ this.ControlLightDirCheckBox.Size = new System.Drawing.Size(124, 17);
+ this.ControlLightDirCheckBox.TabIndex = 3;
+ this.ControlLightDirCheckBox.Text = "Control light direction";
+ this.ControlLightDirCheckBox.UseVisualStyleBackColor = true;
+ this.ControlLightDirCheckBox.CheckedChanged += new System.EventHandler(this.ControlLightDirCheckBox_CheckedChanged);
+ //
+ // ShowCollisionMeshesCheckBox
+ //
+ this.ShowCollisionMeshesCheckBox.AutoSize = true;
+ this.ShowCollisionMeshesCheckBox.Location = new System.Drawing.Point(19, 173);
+ this.ShowCollisionMeshesCheckBox.Name = "ShowCollisionMeshesCheckBox";
+ this.ShowCollisionMeshesCheckBox.Size = new System.Drawing.Size(132, 17);
+ this.ShowCollisionMeshesCheckBox.TabIndex = 7;
+ this.ShowCollisionMeshesCheckBox.Text = "Show collision meshes";
+ this.ShowCollisionMeshesCheckBox.UseVisualStyleBackColor = true;
+ this.ShowCollisionMeshesCheckBox.CheckedChanged += new System.EventHandler(this.ShowCollisionMeshesCheckBox_CheckedChanged);
+ //
+ // GridCheckBox
+ //
+ this.GridCheckBox.AutoSize = true;
+ this.GridCheckBox.Location = new System.Drawing.Point(19, 364);
+ this.GridCheckBox.Name = "GridCheckBox";
+ this.GridCheckBox.Size = new System.Drawing.Size(45, 17);
+ this.GridCheckBox.TabIndex = 17;
+ this.GridCheckBox.Text = "Grid";
+ this.GridCheckBox.UseVisualStyleBackColor = true;
+ this.GridCheckBox.CheckedChanged += new System.EventHandler(this.GridCheckBox_CheckedChanged);
+ //
+ // GridCountComboBox
+ //
+ this.GridCountComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.GridCountComboBox.FormattingEnabled = true;
+ this.GridCountComboBox.Items.AddRange(new object[] {
+ "20",
+ "40",
+ "60",
+ "100"});
+ this.GridCountComboBox.Location = new System.Drawing.Point(83, 411);
+ this.GridCountComboBox.Name = "GridCountComboBox";
+ this.GridCountComboBox.Size = new System.Drawing.Size(114, 21);
+ this.GridCountComboBox.TabIndex = 21;
+ this.GridCountComboBox.SelectedIndexChanged += new System.EventHandler(this.GridCountComboBox_SelectedIndexChanged);
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(7, 414);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(59, 13);
+ this.label2.TabIndex = 20;
+ this.label2.Text = "Grid count:";
+ //
+ // GridSizeComboBox
+ //
+ this.GridSizeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.GridSizeComboBox.FormattingEnabled = true;
+ this.GridSizeComboBox.Items.AddRange(new object[] {
+ "0.1",
+ "1.0",
+ "10",
+ "100"});
+ this.GridSizeComboBox.Location = new System.Drawing.Point(83, 384);
+ this.GridSizeComboBox.Name = "GridSizeComboBox";
+ this.GridSizeComboBox.Size = new System.Drawing.Size(114, 21);
+ this.GridSizeComboBox.TabIndex = 19;
+ this.GridSizeComboBox.SelectedIndexChanged += new System.EventHandler(this.GridSizeComboBox_SelectedIndexChanged);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(7, 387);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(70, 13);
+ this.label1.TabIndex = 18;
+ this.label1.Text = "Grid unit size:";
+ //
+ // StatusBarCheckBox
+ //
+ this.StatusBarCheckBox.AutoSize = true;
+ this.StatusBarCheckBox.Checked = true;
+ this.StatusBarCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.StatusBarCheckBox.Location = new System.Drawing.Point(19, 480);
+ this.StatusBarCheckBox.Name = "StatusBarCheckBox";
+ this.StatusBarCheckBox.Size = new System.Drawing.Size(74, 17);
+ this.StatusBarCheckBox.TabIndex = 23;
+ this.StatusBarCheckBox.Text = "Status bar";
+ this.StatusBarCheckBox.UseVisualStyleBackColor = true;
+ this.StatusBarCheckBox.CheckedChanged += new System.EventHandler(this.StatusBarCheckBox_CheckedChanged);
+ //
+ // ErrorConsoleCheckBox
+ //
+ this.ErrorConsoleCheckBox.AutoSize = true;
+ this.ErrorConsoleCheckBox.Location = new System.Drawing.Point(105, 480);
+ this.ErrorConsoleCheckBox.Name = "ErrorConsoleCheckBox";
+ this.ErrorConsoleCheckBox.Size = new System.Drawing.Size(88, 17);
+ this.ErrorConsoleCheckBox.TabIndex = 24;
+ this.ErrorConsoleCheckBox.Text = "Error console";
+ this.ErrorConsoleCheckBox.UseVisualStyleBackColor = true;
+ this.ErrorConsoleCheckBox.CheckedChanged += new System.EventHandler(this.ErrorConsoleCheckBox_CheckedChanged);
+ //
+ // HDRRenderingCheckBox
+ //
+ this.HDRRenderingCheckBox.AutoSize = true;
+ this.HDRRenderingCheckBox.Checked = true;
+ this.HDRRenderingCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.HDRRenderingCheckBox.Location = new System.Drawing.Point(19, 14);
+ this.HDRRenderingCheckBox.Name = "HDRRenderingCheckBox";
+ this.HDRRenderingCheckBox.Size = new System.Drawing.Size(97, 17);
+ this.HDRRenderingCheckBox.TabIndex = 0;
+ this.HDRRenderingCheckBox.Text = "HDR rendering";
+ this.HDRRenderingCheckBox.UseVisualStyleBackColor = true;
+ this.HDRRenderingCheckBox.CheckedChanged += new System.EventHandler(this.HDRRenderingCheckBox_CheckedChanged);
+ //
+ // SkydomeCheckBox
+ //
+ this.SkydomeCheckBox.AutoSize = true;
+ this.SkydomeCheckBox.Location = new System.Drawing.Point(19, 60);
+ this.SkydomeCheckBox.Name = "SkydomeCheckBox";
+ this.SkydomeCheckBox.Size = new System.Drawing.Size(70, 17);
+ this.SkydomeCheckBox.TabIndex = 2;
+ this.SkydomeCheckBox.Text = "Skydome";
+ this.SkydomeCheckBox.UseVisualStyleBackColor = true;
+ this.SkydomeCheckBox.CheckedChanged += new System.EventHandler(this.SkydomeCheckBox_CheckedChanged);
+ //
+ // ShadowsCheckBox
+ //
+ this.ShadowsCheckBox.AutoSize = true;
+ this.ShadowsCheckBox.Checked = true;
+ this.ShadowsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.ShadowsCheckBox.Location = new System.Drawing.Point(19, 37);
+ this.ShadowsCheckBox.Name = "ShadowsCheckBox";
+ this.ShadowsCheckBox.Size = new System.Drawing.Size(70, 17);
+ this.ShadowsCheckBox.TabIndex = 1;
+ this.ShadowsCheckBox.Text = "Shadows";
+ this.ShadowsCheckBox.UseVisualStyleBackColor = true;
+ this.ShadowsCheckBox.CheckedChanged += new System.EventHandler(this.ShadowsCheckBox_CheckedChanged);
+ //
+ // WireframeCheckBox
+ //
+ this.WireframeCheckBox.AutoSize = true;
+ this.WireframeCheckBox.Location = new System.Drawing.Point(19, 196);
+ this.WireframeCheckBox.Name = "WireframeCheckBox";
+ this.WireframeCheckBox.Size = new System.Drawing.Size(74, 17);
+ this.WireframeCheckBox.TabIndex = 8;
+ this.WireframeCheckBox.Text = "Wireframe";
+ this.WireframeCheckBox.UseVisualStyleBackColor = true;
+ this.WireframeCheckBox.CheckedChanged += new System.EventHandler(this.WireframeCheckBox_CheckedChanged);
+ //
+ // RenderModeComboBox
+ //
+ this.RenderModeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.RenderModeComboBox.FormattingEnabled = true;
+ this.RenderModeComboBox.Items.AddRange(new object[] {
+ "Default",
+ "Single texture",
+ "Vertex normals",
+ "Vertex tangents",
+ "Vertex colour 1",
+ "Vertex colour 2",
+ "Texture coord 1",
+ "Texture coord 2",
+ "Texture coord 3"});
+ this.RenderModeComboBox.Location = new System.Drawing.Point(83, 274);
+ this.RenderModeComboBox.Name = "RenderModeComboBox";
+ this.RenderModeComboBox.Size = new System.Drawing.Size(114, 21);
+ this.RenderModeComboBox.TabIndex = 12;
+ this.RenderModeComboBox.SelectedIndexChanged += new System.EventHandler(this.RenderModeComboBox_SelectedIndexChanged);
+ //
+ // label11
+ //
+ this.label11.AutoSize = true;
+ this.label11.Location = new System.Drawing.Point(7, 304);
+ this.label11.Name = "label11";
+ this.label11.Size = new System.Drawing.Size(67, 13);
+ this.label11.TabIndex = 13;
+ this.label11.Text = "Tex sampler:";
+ //
+ // TextureSamplerComboBox
+ //
+ this.TextureSamplerComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.TextureSamplerComboBox.Enabled = false;
+ this.TextureSamplerComboBox.FormattingEnabled = true;
+ this.TextureSamplerComboBox.Location = new System.Drawing.Point(83, 301);
+ this.TextureSamplerComboBox.Name = "TextureSamplerComboBox";
+ this.TextureSamplerComboBox.Size = new System.Drawing.Size(114, 21);
+ this.TextureSamplerComboBox.TabIndex = 14;
+ this.TextureSamplerComboBox.SelectedIndexChanged += new System.EventHandler(this.TextureSamplerComboBox_SelectedIndexChanged);
+ //
+ // TextureCoordsComboBox
+ //
+ this.TextureCoordsComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.TextureCoordsComboBox.Enabled = false;
+ this.TextureCoordsComboBox.FormattingEnabled = true;
+ this.TextureCoordsComboBox.Items.AddRange(new object[] {
+ "Texture coord 1",
+ "Texture coord 2",
+ "Texture coord 3"});
+ this.TextureCoordsComboBox.Location = new System.Drawing.Point(83, 328);
+ this.TextureCoordsComboBox.Name = "TextureCoordsComboBox";
+ this.TextureCoordsComboBox.Size = new System.Drawing.Size(114, 21);
+ this.TextureCoordsComboBox.TabIndex = 16;
+ this.TextureCoordsComboBox.SelectedIndexChanged += new System.EventHandler(this.TextureCoordsComboBox_SelectedIndexChanged);
+ //
+ // label10
+ //
+ this.label10.AutoSize = true;
+ this.label10.Location = new System.Drawing.Point(7, 277);
+ this.label10.Name = "label10";
+ this.label10.Size = new System.Drawing.Size(74, 13);
+ this.label10.TabIndex = 11;
+ this.label10.Text = "Render mode:";
+ //
+ // AnisotropicFilteringCheckBox
+ //
+ this.AnisotropicFilteringCheckBox.AutoSize = true;
+ this.AnisotropicFilteringCheckBox.Checked = true;
+ this.AnisotropicFilteringCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.AnisotropicFilteringCheckBox.Location = new System.Drawing.Point(19, 219);
+ this.AnisotropicFilteringCheckBox.Name = "AnisotropicFilteringCheckBox";
+ this.AnisotropicFilteringCheckBox.Size = new System.Drawing.Size(114, 17);
+ this.AnisotropicFilteringCheckBox.TabIndex = 9;
+ this.AnisotropicFilteringCheckBox.Text = "Anisotropic filtering";
+ this.AnisotropicFilteringCheckBox.UseVisualStyleBackColor = true;
+ this.AnisotropicFilteringCheckBox.CheckedChanged += new System.EventHandler(this.AnisotropicFilteringCheckBox_CheckedChanged);
+ //
+ // label14
+ //
+ this.label14.AutoSize = true;
+ this.label14.Location = new System.Drawing.Point(7, 331);
+ this.label14.Name = "label14";
+ this.label14.Size = new System.Drawing.Size(63, 13);
+ this.label14.TabIndex = 15;
+ this.label14.Text = "Tex coords:";
+ //
+ // DetailsPropertyGrid
+ //
+ this.DetailsPropertyGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.DetailsPropertyGrid.HelpVisible = false;
+ this.DetailsPropertyGrid.Location = new System.Drawing.Point(0, 3);
+ this.DetailsPropertyGrid.Name = "DetailsPropertyGrid";
+ this.DetailsPropertyGrid.PropertySort = System.Windows.Forms.PropertySort.NoSort;
+ this.DetailsPropertyGrid.ReadOnly = true;
+ this.DetailsPropertyGrid.Size = new System.Drawing.Size(239, 604);
+ this.DetailsPropertyGrid.TabIndex = 1;
+ this.DetailsPropertyGrid.ToolbarVisible = false;
+ //
+ // ToolsDetailsTabPage
+ //
+ this.ToolsDetailsTabPage.Controls.Add(this.DetailsPropertyGrid);
+ this.ToolsDetailsTabPage.Location = new System.Drawing.Point(4, 22);
+ this.ToolsDetailsTabPage.Name = "ToolsDetailsTabPage";
+ this.ToolsDetailsTabPage.Size = new System.Drawing.Size(239, 607);
+ this.ToolsDetailsTabPage.TabIndex = 2;
+ this.ToolsDetailsTabPage.Text = "Details";
+ this.ToolsDetailsTabPage.UseVisualStyleBackColor = true;
+ //
+ // TextureViewerButton
+ //
+ this.TextureViewerButton.Location = new System.Drawing.Point(6, 6);
+ this.TextureViewerButton.Name = "TextureViewerButton";
+ this.TextureViewerButton.Size = new System.Drawing.Size(113, 23);
+ this.TextureViewerButton.TabIndex = 2;
+ this.TextureViewerButton.Text = "Open texture viewer";
+ this.TextureViewerButton.UseVisualStyleBackColor = true;
+ this.TextureViewerButton.Click += new System.EventHandler(this.TextureViewerButton_Click);
+ //
+ // TexturesTreeView
+ //
+ this.TexturesTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.TexturesTreeView.Location = new System.Drawing.Point(0, 34);
+ this.TexturesTreeView.Name = "TexturesTreeView";
+ this.TexturesTreeView.ShowRootLines = false;
+ this.TexturesTreeView.Size = new System.Drawing.Size(239, 573);
+ this.TexturesTreeView.TabIndex = 1;
+ //
+ // ToolsTexturesTabPage
+ //
+ this.ToolsTexturesTabPage.Controls.Add(this.TextureViewerButton);
+ this.ToolsTexturesTabPage.Controls.Add(this.TexturesTreeView);
+ this.ToolsTexturesTabPage.Location = new System.Drawing.Point(4, 22);
+ this.ToolsTexturesTabPage.Name = "ToolsTexturesTabPage";
+ this.ToolsTexturesTabPage.Padding = new System.Windows.Forms.Padding(3);
+ this.ToolsTexturesTabPage.Size = new System.Drawing.Size(239, 607);
+ this.ToolsTexturesTabPage.TabIndex = 1;
+ this.ToolsTexturesTabPage.Text = "Textures";
+ this.ToolsTexturesTabPage.UseVisualStyleBackColor = true;
+ //
+ // ModelsTreeView
+ //
+ this.ModelsTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ModelsTreeView.CheckBoxes = true;
+ this.ModelsTreeView.Location = new System.Drawing.Point(0, 3);
+ this.ModelsTreeView.Name = "ModelsTreeView";
+ this.ModelsTreeView.ShowRootLines = false;
+ this.ModelsTreeView.Size = new System.Drawing.Size(239, 604);
+ this.ModelsTreeView.TabIndex = 2;
+ this.ModelsTreeView.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.ModelsTreeView_AfterCheck);
+ this.ModelsTreeView.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.ModelsTreeView_NodeMouseDoubleClick);
+ this.ModelsTreeView.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.ModelsTreeView_KeyPress);
+ //
+ // StatusStrip
+ //
+ this.StatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.StatusLabel,
+ this.MousedLabel,
+ this.StatsLabel});
+ this.StatusStrip.Location = new System.Drawing.Point(0, 689);
+ this.StatusStrip.Name = "StatusStrip";
+ this.StatusStrip.Size = new System.Drawing.Size(984, 22);
+ this.StatusStrip.TabIndex = 6;
+ this.StatusStrip.Text = "statusStrip1";
+ //
+ // StatusLabel
+ //
+ this.StatusLabel.BackColor = System.Drawing.SystemColors.Control;
+ this.StatusLabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.StatusLabel.Name = "StatusLabel";
+ this.StatusLabel.Size = new System.Drawing.Size(878, 17);
+ this.StatusLabel.Spring = true;
+ this.StatusLabel.Text = "Initialising";
+ this.StatusLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // MousedLabel
+ //
+ this.MousedLabel.BackColor = System.Drawing.SystemColors.Control;
+ this.MousedLabel.Name = "MousedLabel";
+ this.MousedLabel.Size = new System.Drawing.Size(16, 17);
+ this.MousedLabel.Text = " ";
+ //
+ // StatsLabel
+ //
+ this.StatsLabel.BackColor = System.Drawing.SystemColors.Control;
+ this.StatsLabel.Name = "StatsLabel";
+ this.StatsLabel.Size = new System.Drawing.Size(75, 17);
+ this.StatsLabel.Text = "0 geometries";
+ //
+ // ToolsModelsTabPage
+ //
+ this.ToolsModelsTabPage.Controls.Add(this.ModelsTreeView);
+ this.ToolsModelsTabPage.Location = new System.Drawing.Point(4, 22);
+ this.ToolsModelsTabPage.Name = "ToolsModelsTabPage";
+ this.ToolsModelsTabPage.Padding = new System.Windows.Forms.Padding(3);
+ this.ToolsModelsTabPage.Size = new System.Drawing.Size(239, 607);
+ this.ToolsModelsTabPage.TabIndex = 0;
+ this.ToolsModelsTabPage.Text = "Models";
+ this.ToolsModelsTabPage.UseVisualStyleBackColor = true;
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(3, 11);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(38, 13);
+ this.label3.TabIndex = 1;
+ this.label3.Text = "Name:";
+ //
+ // PedNameComboBox
+ //
+ this.PedNameComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.PedNameComboBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
+ this.PedNameComboBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
+ this.PedNameComboBox.FormattingEnabled = true;
+ this.PedNameComboBox.Location = new System.Drawing.Point(54, 8);
+ this.PedNameComboBox.Name = "PedNameComboBox";
+ this.PedNameComboBox.Size = new System.Drawing.Size(182, 21);
+ this.PedNameComboBox.TabIndex = 0;
+ //
+ // StatsUpdateTimer
+ //
+ this.StatsUpdateTimer.Enabled = true;
+ this.StatsUpdateTimer.Interval = 500;
+ this.StatsUpdateTimer.Tick += new System.EventHandler(this.StatsUpdateTimer_Tick);
+ //
+ // ToolsPedTabPage
+ //
+ this.ToolsPedTabPage.Controls.Add(this.label3);
+ this.ToolsPedTabPage.Controls.Add(this.PedNameComboBox);
+ this.ToolsPedTabPage.Location = new System.Drawing.Point(4, 22);
+ this.ToolsPedTabPage.Name = "ToolsPedTabPage";
+ this.ToolsPedTabPage.Size = new System.Drawing.Size(239, 607);
+ this.ToolsPedTabPage.TabIndex = 4;
+ this.ToolsPedTabPage.Text = "Ped";
+ this.ToolsPedTabPage.UseVisualStyleBackColor = true;
+ //
+ // ToolsTabControl
+ //
+ this.ToolsTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ToolsTabControl.Controls.Add(this.ToolsPedTabPage);
+ this.ToolsTabControl.Controls.Add(this.ToolsModelsTabPage);
+ this.ToolsTabControl.Controls.Add(this.ToolsTexturesTabPage);
+ this.ToolsTabControl.Controls.Add(this.ToolsDetailsTabPage);
+ this.ToolsTabControl.Controls.Add(this.ToolsOptionsTabPage);
+ this.ToolsTabControl.Location = new System.Drawing.Point(2, 30);
+ this.ToolsTabControl.Name = "ToolsTabControl";
+ this.ToolsTabControl.SelectedIndex = 0;
+ this.ToolsTabControl.Size = new System.Drawing.Size(247, 633);
+ this.ToolsTabControl.TabIndex = 1;
+ //
+ // ToolsPanel
+ //
+ this.ToolsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)));
+ this.ToolsPanel.BackColor = System.Drawing.SystemColors.ControlDark;
+ this.ToolsPanel.Controls.Add(this.ToolsTabControl);
+ this.ToolsPanel.Controls.Add(this.ToolsPanelHideButton);
+ this.ToolsPanel.Controls.Add(this.ToolsDragPanel);
+ this.ToolsPanel.Location = new System.Drawing.Point(12, 12);
+ this.ToolsPanel.Name = "ToolsPanel";
+ this.ToolsPanel.Size = new System.Drawing.Size(252, 666);
+ this.ToolsPanel.TabIndex = 7;
+ this.ToolsPanel.Visible = false;
+ //
+ // PedsForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.Color.MidnightBlue;
+ this.ClientSize = new System.Drawing.Size(984, 711);
+ this.Controls.Add(this.ConsolePanel);
+ this.Controls.Add(this.StatusStrip);
+ this.Controls.Add(this.ToolsPanel);
+ this.Controls.Add(this.ToolsPanelShowButton);
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.KeyPreview = true;
+ this.Name = "PedsForm";
+ this.Text = "Ped Viewer - CodeWalker by dexyfex";
+ this.Deactivate += new System.EventHandler(this.PedsForm_Deactivate);
+ this.Load += new System.EventHandler(this.PedsForm_Load);
+ this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.PedsForm_KeyDown);
+ this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.PedsForm_KeyUp);
+ this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PedsForm_MouseDown);
+ this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PedsForm_MouseMove);
+ this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PedsForm_MouseUp);
+ this.ConsolePanel.ResumeLayout(false);
+ this.ConsolePanel.PerformLayout();
+ this.ToolsOptionsTabPage.ResumeLayout(false);
+ this.ToolsOptionsTabPage.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.TimeOfDayTrackBar)).EndInit();
+ this.ToolsDetailsTabPage.ResumeLayout(false);
+ this.ToolsTexturesTabPage.ResumeLayout(false);
+ this.StatusStrip.ResumeLayout(false);
+ this.StatusStrip.PerformLayout();
+ this.ToolsModelsTabPage.ResumeLayout(false);
+ this.ToolsPedTabPage.ResumeLayout(false);
+ this.ToolsPedTabPage.PerformLayout();
+ this.ToolsTabControl.ResumeLayout(false);
+ this.ToolsPanel.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private WinForms.TextBoxFix ConsoleTextBox;
+ private System.Windows.Forms.Button ToolsPanelShowButton;
+ private System.Windows.Forms.Button ToolsPanelHideButton;
+ private System.Windows.Forms.Panel ToolsDragPanel;
+ private System.Windows.Forms.Panel ConsolePanel;
+ private System.Windows.Forms.CheckBox HDTexturesCheckBox;
+ private System.Windows.Forms.CheckBox SkeletonsCheckBox;
+ private System.Windows.Forms.Label TimeOfDayLabel;
+ private System.Windows.Forms.TabPage ToolsOptionsTabPage;
+ private System.Windows.Forms.Label label19;
+ private System.Windows.Forms.TrackBar TimeOfDayTrackBar;
+ private System.Windows.Forms.CheckBox ControlLightDirCheckBox;
+ private System.Windows.Forms.CheckBox ShowCollisionMeshesCheckBox;
+ private System.Windows.Forms.CheckBox GridCheckBox;
+ private System.Windows.Forms.ComboBox GridCountComboBox;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.ComboBox GridSizeComboBox;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.CheckBox StatusBarCheckBox;
+ private System.Windows.Forms.CheckBox ErrorConsoleCheckBox;
+ private System.Windows.Forms.CheckBox HDRRenderingCheckBox;
+ private System.Windows.Forms.CheckBox SkydomeCheckBox;
+ private System.Windows.Forms.CheckBox ShadowsCheckBox;
+ private System.Windows.Forms.CheckBox WireframeCheckBox;
+ private System.Windows.Forms.ComboBox RenderModeComboBox;
+ private System.Windows.Forms.Label label11;
+ private System.Windows.Forms.ComboBox TextureSamplerComboBox;
+ private System.Windows.Forms.ComboBox TextureCoordsComboBox;
+ private System.Windows.Forms.Label label10;
+ private System.Windows.Forms.CheckBox AnisotropicFilteringCheckBox;
+ private System.Windows.Forms.Label label14;
+ private WinForms.ReadOnlyPropertyGrid DetailsPropertyGrid;
+ private System.Windows.Forms.TabPage ToolsDetailsTabPage;
+ private System.Windows.Forms.Button TextureViewerButton;
+ private WinForms.TreeViewFix TexturesTreeView;
+ private System.Windows.Forms.TabPage ToolsTexturesTabPage;
+ private WinForms.TreeViewFix ModelsTreeView;
+ private System.Windows.Forms.StatusStrip StatusStrip;
+ private System.Windows.Forms.ToolStripStatusLabel StatusLabel;
+ private System.Windows.Forms.ToolStripStatusLabel MousedLabel;
+ private System.Windows.Forms.ToolStripStatusLabel StatsLabel;
+ private System.Windows.Forms.TabPage ToolsModelsTabPage;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.ComboBox PedNameComboBox;
+ private System.Windows.Forms.Timer StatsUpdateTimer;
+ private System.Windows.Forms.TabPage ToolsPedTabPage;
+ private System.Windows.Forms.TabControl ToolsTabControl;
+ private System.Windows.Forms.Panel ToolsPanel;
+ }
+}
\ No newline at end of file
diff --git a/Peds/PedsForm.cs b/Peds/PedsForm.cs
new file mode 100644
index 0000000..34af71f
--- /dev/null
+++ b/Peds/PedsForm.cs
@@ -0,0 +1,1417 @@
+using CodeWalker.GameFiles;
+using CodeWalker.Properties;
+using CodeWalker.Rendering;
+using CodeWalker.World;
+using SharpDX;
+using SharpDX.Direct3D11;
+using SharpDX.XInput;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Color = SharpDX.Color;
+
+namespace CodeWalker.Peds
+{
+ public partial class PedsForm : Form, DXForm
+ {
+ public Form Form { get { return this; } } //for DXForm/DXManager use
+
+ public Renderer Renderer = null;
+ public object RenderSyncRoot { get { return Renderer.RenderSyncRoot; } }
+
+ volatile bool formopen = false;
+ volatile bool running = false;
+ volatile bool pauserendering = false;
+ //volatile bool initialised = false;
+
+ Stopwatch frametimer = new Stopwatch();
+ Camera camera;
+ Timecycle timecycle;
+ Weather weather;
+ Clouds clouds;
+
+ Entity camEntity = new Entity();
+
+
+ bool MouseLButtonDown = false;
+ bool MouseRButtonDown = false;
+ int MouseX;
+ int MouseY;
+ System.Drawing.Point MouseDownPoint;
+ System.Drawing.Point MouseLastPoint;
+
+
+ public GameFileCache GameFileCache { get; } = GameFileCacheFactory.Create();
+
+
+ InputManager Input = new InputManager();
+
+
+ bool initedOk = false;
+
+
+
+ bool toolsPanelResizing = false;
+ int toolsPanelResizeStartX = 0;
+ int toolsPanelResizeStartLeft = 0;
+ int toolsPanelResizeStartRight = 0;
+
+ Dictionary DrawableDrawFlags = new Dictionary();
+
+ bool enableGrid = false;
+ float gridSize = 1.0f;
+ int gridCount = 40;
+ List gridVerts = new List();
+ object gridSyncRoot = new object();
+
+
+
+ public PedsForm()
+ {
+ InitializeComponent();
+
+ Renderer = new Renderer(this, GameFileCache);
+ camera = Renderer.camera;
+ timecycle = Renderer.timecycle;
+ weather = Renderer.weather;
+ clouds = Renderer.clouds;
+
+ initedOk = Renderer.Init();
+
+ Renderer.controllightdir = !Settings.Default.Skydome;
+ Renderer.rendercollisionmeshes = false;
+ Renderer.renderclouds = false;
+ //Renderer.renderclouds = true;
+ //Renderer.individualcloudfrag = "Contrails";
+ Renderer.rendermoon = false;
+ Renderer.renderskeletons = false;
+ Renderer.SelectionFlagsTestAll = true;
+
+ }
+
+ public void InitScene(Device device)
+ {
+ int width = ClientSize.Width;
+ int height = ClientSize.Height;
+
+ try
+ {
+ Renderer.DeviceCreated(device, width, height);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Error loading shaders!\n" + ex.ToString());
+ return;
+ }
+
+
+ camera.FollowEntity = camEntity;
+ camera.FollowEntity.Position = Vector3.Zero;// prevworldpos;
+ camera.FollowEntity.Orientation = Quaternion.LookAtLH(Vector3.Zero, Vector3.Up, Vector3.ForwardLH);
+ camera.TargetDistance = 2.0f;
+ camera.CurrentDistance = 2.0f;
+ camera.TargetRotation.Y = 0.2f;
+ camera.CurrentRotation.Y = 0.2f;
+ camera.TargetRotation.X = 0.5f * (float)Math.PI;
+ camera.CurrentRotation.X = 0.5f * (float)Math.PI;
+
+
+ LoadSettings();
+
+
+ formopen = true;
+ new Thread(new ThreadStart(ContentThread)).Start();
+
+ frametimer.Start();
+
+ }
+ public void CleanupScene()
+ {
+ formopen = false;
+
+ Renderer.DeviceDestroyed();
+
+ int count = 0;
+ while (running && (count < 5000)) //wait for the content thread to exit gracefully
+ {
+ Thread.Sleep(1);
+ count++;
+ }
+ }
+ public void RenderScene(DeviceContext context)
+ {
+ float elapsed = (float)frametimer.Elapsed.TotalSeconds;
+ frametimer.Restart();
+
+ if (pauserendering) return;
+
+ if (!Monitor.TryEnter(Renderer.RenderSyncRoot, 50))
+ { return; } //couldn't get a lock, try again next time
+
+ UpdateControlInputs(elapsed);
+ //space.Update(elapsed);
+
+
+ Renderer.Update(elapsed, MouseLastPoint.X, MouseLastPoint.Y);
+
+
+
+ //UpdateWidgets();
+ //BeginMouseHitTest();
+
+
+
+
+ Renderer.BeginRender(context);
+
+ Renderer.RenderSkyAndClouds();
+
+ Renderer.SelectedDrawable = null;// SelectedItem.Drawable;
+
+
+ RenderPed();
+
+ //UpdateMouseHitsFromRenderer();
+ //RenderSelection();
+
+
+ RenderGrid(context);
+
+
+ Renderer.RenderQueued();
+
+ //Renderer.RenderBounds(MapSelectionMode.Entity);
+
+ //Renderer.RenderSelectionGeometry(MapSelectionMode.Entity);
+
+ //RenderMoused();
+
+ Renderer.RenderFinalPass();
+
+ //RenderMarkers();
+ //RenderWidgets();
+
+ Renderer.EndRender();
+
+ Monitor.Exit(Renderer.RenderSyncRoot);
+
+ //UpdateMarkerSelectionPanelInvoke();
+ }
+ public void BuffersResized(int w, int h)
+ {
+ Renderer.BuffersResized(w, h);
+ }
+
+
+
+
+
+ private void Init()
+ {
+ //called from PedForm_Load
+
+ if (!initedOk)
+ {
+ Close();
+ return;
+ }
+
+
+ MouseWheel += PedsForm_MouseWheel;
+
+ if (!GTAFolder.UpdateGTAFolder(true))
+ {
+ Close();
+ return;
+ }
+
+
+
+ ShaderParamNames[] texsamplers = RenderableGeometry.GetTextureSamplerList();
+ foreach (var texsampler in texsamplers)
+ {
+ TextureSamplerComboBox.Items.Add(texsampler);
+ }
+ //TextureSamplerComboBox.SelectedIndex = 0;//LoadSettings will do this..
+
+
+ UpdateGridVerts();
+ GridSizeComboBox.SelectedIndex = 1;
+ GridCountComboBox.SelectedIndex = 1;
+
+
+
+ Input.Init();
+
+
+ Renderer.Start();
+ }
+
+
+ private void ContentThread()
+ {
+ //main content loading thread.
+ running = true;
+
+ UpdateStatus("Scanning...");
+
+ try
+ {
+ GTA5Keys.LoadFromPath(GTAFolder.CurrentGTAFolder, Settings.Default.Key);
+ }
+ catch
+ {
+ MessageBox.Show("Keys not found! This shouldn't happen.");
+ Close();
+ return;
+ }
+
+ GameFileCache.EnableDlc = true;
+ GameFileCache.LoadPeds = true;
+ 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...
+ GameFileCache.Init(UpdateStatus, LogError);
+
+ //UpdateDlcListComboBox(gameFileCache.DlcNameList);
+
+ //EnableCacheDependentUI();
+
+ UpdateGlobalPedsUI();
+
+
+ LoadWorld();
+
+
+
+ //initialised = true;
+
+ //EnableDLCModsUI();
+
+ //UpdateStatus("Ready");
+
+
+ Task.Run(() => {
+ while (formopen && !IsDisposed) //renderer content loop
+ {
+ bool rcItemsPending = Renderer.ContentThreadProc();
+
+ if (!rcItemsPending)
+ {
+ Thread.Sleep(1); //sleep if there's nothing to do
+ }
+ }
+ });
+
+ while (formopen && !IsDisposed) //main asset loop
+ {
+ bool fcItemsPending = GameFileCache.ContentThreadProc();
+
+ if (!fcItemsPending)
+ {
+ Thread.Sleep(1); //sleep if there's nothing to do
+ }
+ }
+
+ GameFileCache.Clear();
+
+ running = false;
+ }
+
+
+
+
+ private void LoadSettings()
+ {
+ var s = Settings.Default;
+ //WindowState = s.WindowMaximized ? FormWindowState.Maximized : WindowState;
+ //FullScreenCheckBox.Checked = s.FullScreen;
+ WireframeCheckBox.Checked = s.Wireframe;
+ HDRRenderingCheckBox.Checked = s.HDR;
+ ShadowsCheckBox.Checked = s.Shadows;
+ SkydomeCheckBox.Checked = s.Skydome;
+ RenderModeComboBox.SelectedIndex = Math.Max(RenderModeComboBox.FindString(s.RenderMode), 0);
+ TextureSamplerComboBox.SelectedIndex = Math.Max(TextureSamplerComboBox.FindString(s.RenderTextureSampler), 0);
+ TextureCoordsComboBox.SelectedIndex = Math.Max(TextureCoordsComboBox.FindString(s.RenderTextureSamplerCoord), 0);
+ AnisotropicFilteringCheckBox.Checked = s.AnisotropicFiltering;
+ //ErrorConsoleCheckBox.Checked = s.ShowErrorConsole;
+ //StatusBarCheckBox.Checked = s.ShowStatusBar;
+ }
+
+
+
+ private void LoadWorld()
+ {
+ UpdateStatus("Loading timecycles...");
+ timecycle.Init(GameFileCache, UpdateStatus);
+ timecycle.SetTime(Renderer.timeofday);
+
+ UpdateStatus("Loading materials...");
+ BoundsMaterialTypes.Init(GameFileCache);
+
+ UpdateStatus("Loading weather...");
+ weather.Init(GameFileCache, UpdateStatus, timecycle);
+ //UpdateWeatherTypesComboBox(weather);
+
+ UpdateStatus("Loading clouds...");
+ clouds.Init(GameFileCache, UpdateStatus, weather);
+ //UpdateCloudTypesComboBox(clouds);
+
+ }
+
+
+
+
+
+
+ private void UpdateStatus(string text)
+ {
+ try
+ {
+ if (InvokeRequired)
+ {
+ BeginInvoke(new Action(() => { UpdateStatus(text); }));
+ }
+ else
+ {
+ StatusLabel.Text = text;
+ }
+ }
+ catch { }
+ }
+ private void LogError(string text)
+ {
+ try
+ {
+ if (InvokeRequired)
+ {
+ Invoke(new Action(() => { LogError(text); }));
+ }
+ else
+ {
+ //TODO: error logging..
+ ConsoleTextBox.AppendText(text + "\r\n");
+ //StatusLabel.Text = text;
+ //MessageBox.Show(text);
+ }
+ }
+ catch { }
+ }
+
+
+
+
+ private void UpdateMousePosition(MouseEventArgs e)
+ {
+ MouseX = e.X;
+ MouseY = e.Y;
+ MouseLastPoint = e.Location;
+ }
+
+ private void RotateCam(int dx, int dy)
+ {
+ camera.MouseRotate(dx, dy);
+ }
+
+ private void MoveCameraToView(Vector3 pos, float rad)
+ {
+ //move the camera to a default place where the given sphere is fully visible.
+
+ rad = Math.Max(0.01f, rad);
+
+ camera.FollowEntity.Position = pos;
+ camera.TargetDistance = rad * 1.6f;
+ camera.CurrentDistance = rad * 1.6f;
+
+ camera.ZFar = Math.Min(rad * 200.0f, 12000.0f);
+ camera.ZNear = Math.Min(camera.ZFar * 5e-5f, 0.5f);
+ camera.UpdateProj = true;
+
+ }
+
+
+
+
+
+
+
+ private void AddDrawableTreeNode(DrawableBase drawable, uint hash, bool check)
+ {
+ MetaHash mhash = new MetaHash(hash);
+
+ var dnode = ModelsTreeView.Nodes.Add(mhash.ToString());
+ dnode.Tag = drawable;
+ dnode.Checked = check;
+
+ AddDrawableModelsTreeNodes(drawable.DrawableModelsHigh, "High Detail", true, dnode);
+ AddDrawableModelsTreeNodes(drawable.DrawableModelsMedium, "Medium Detail", false, dnode);
+ AddDrawableModelsTreeNodes(drawable.DrawableModelsLow, "Low Detail", false, dnode);
+ AddDrawableModelsTreeNodes(drawable.DrawableModelsVeryLow, "Very Low Detail", false, dnode);
+ //AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false, dnode);
+
+ }
+ private void AddDrawableModelsTreeNodes(ResourcePointerList64 models, string prefix, bool check, TreeNode parentDrawableNode = null)
+ {
+ if (models == null) return;
+ if (models.data_items == null) return;
+
+ for (int mi = 0; mi < models.data_items.Length; mi++)
+ {
+ var tnc = (parentDrawableNode != null) ? parentDrawableNode.Nodes : ModelsTreeView.Nodes;
+
+ var model = models.data_items[mi];
+ string mprefix = prefix + " " + (mi + 1).ToString();
+ var mnode = tnc.Add(mprefix + " " + model.ToString());
+ mnode.Tag = model;
+ mnode.Checked = check;
+
+ var tmnode = TexturesTreeView.Nodes.Add(mprefix + " " + model.ToString());
+ tmnode.Tag = model;
+
+ if (!check)
+ {
+ Renderer.SelectionModelDrawFlags[model] = false;
+ }
+
+ if ((model.Geometries == null) || (model.Geometries.data_items == null)) continue;
+
+ foreach (var geom in model.Geometries.data_items)
+ {
+ var gname = geom.ToString();
+ var gnode = mnode.Nodes.Add(gname);
+ gnode.Tag = geom;
+ gnode.Checked = true;// check;
+
+ var tgnode = tmnode.Nodes.Add(gname);
+ tgnode.Tag = geom;
+
+ if ((geom.Shader != null) && (geom.Shader.ParametersList != null) && (geom.Shader.ParametersList.Hashes != null))
+ {
+ var pl = geom.Shader.ParametersList;
+ var h = pl.Hashes;
+ var p = pl.Parameters;
+ for (int ip = 0; ip < h.Length; ip++)
+ {
+ var hash = pl.Hashes[ip];
+ var parm = pl.Parameters[ip];
+ var tex = parm.Data as TextureBase;
+ if (tex != null)
+ {
+ var t = tex as Texture;
+ var tstr = tex.Name.Trim();
+ if (t != null)
+ {
+ tstr = string.Format("{0} ({1}x{2}, embedded)", tex.Name, t.Width, t.Height);
+ }
+ var tnode = tgnode.Nodes.Add(hash.ToString().Trim() + ": " + tstr);
+ tnode.Tag = tex;
+ }
+ }
+ tgnode.Expand();
+ }
+
+ }
+
+ mnode.Expand();
+ tmnode.Expand();
+ }
+ }
+ private void UpdateSelectionDrawFlags(TreeNode node)
+ {
+ //update the selection draw flags depending on tag and checked/unchecked
+ var drwbl = node.Tag as DrawableBase;
+ var model = node.Tag as DrawableModel;
+ var geom = node.Tag as DrawableGeometry;
+ bool rem = node.Checked;
+ lock (Renderer.RenderSyncRoot)
+ {
+ if (drwbl != null)
+ {
+ if (rem)
+ {
+ if (DrawableDrawFlags.ContainsKey(drwbl))
+ {
+ DrawableDrawFlags.Remove(drwbl);
+ }
+ }
+ else
+ {
+ DrawableDrawFlags[drwbl] = false;
+ }
+ }
+ if (model != null)
+ {
+ if (rem)
+ {
+ if (Renderer.SelectionModelDrawFlags.ContainsKey(model))
+ {
+ Renderer.SelectionModelDrawFlags.Remove(model);
+ }
+ }
+ else
+ {
+ Renderer.SelectionModelDrawFlags[model] = false;
+ }
+ }
+ if (geom != null)
+ {
+ if (rem)
+ {
+ if (Renderer.SelectionGeometryDrawFlags.ContainsKey(geom))
+ {
+ Renderer.SelectionGeometryDrawFlags.Remove(geom);
+ }
+ }
+ else
+ {
+ Renderer.SelectionGeometryDrawFlags[geom] = false;
+ }
+ }
+ //updateArchetypeStatus = true;
+ }
+ }
+
+
+ private void UpdateGlobalPedsUI()
+ {
+ if (InvokeRequired)
+ {
+ BeginInvoke(new Action(() => { UpdateGlobalPedsUI(); }));
+ }
+ else
+ {
+ PedNameComboBox.Items.Clear();
+
+ var peds = GameFileCache.PedsInitDict.Values.ToList();
+ peds.Sort((a, b) => { return a.Name.CompareTo(b.Name); });
+ foreach (var ped in peds)
+ {
+ PedNameComboBox.Items.Add(ped.Name);
+ }
+ if (peds.Count > 0)
+ {
+ PedNameComboBox.SelectedIndex = 0;
+ }
+
+ }
+
+ }
+
+
+
+
+
+ private void UpdateModelsUI(DrawableBase drawable)
+ {
+ DetailsPropertyGrid.SelectedObject = drawable;
+
+ DrawableDrawFlags.Clear();
+ Renderer.SelectionModelDrawFlags.Clear();
+ Renderer.SelectionGeometryDrawFlags.Clear();
+ ModelsTreeView.Nodes.Clear();
+ ModelsTreeView.ShowRootLines = false;
+ TexturesTreeView.Nodes.Clear();
+ if (drawable != null)
+ {
+ AddDrawableModelsTreeNodes(drawable.DrawableModelsHigh, "High Detail", true);
+ AddDrawableModelsTreeNodes(drawable.DrawableModelsMedium, "Medium Detail", false);
+ AddDrawableModelsTreeNodes(drawable.DrawableModelsLow, "Low Detail", false);
+ AddDrawableModelsTreeNodes(drawable.DrawableModelsVeryLow, "Very Low Detail", false);
+ //AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false);
+
+
+ var fdrawable = drawable as FragDrawable;
+ if (fdrawable != null)
+ {
+ var plod1 = fdrawable.OwnerFragment?.PhysicsLODGroup?.PhysicsLOD1;
+ if ((plod1 != null) && (plod1.Children?.data_items != null))
+ {
+ foreach (var child in plod1.Children.data_items)
+ {
+ var cdrwbl = child.Drawable1;
+ if ((cdrwbl != null) && (cdrwbl.AllModels?.Length > 0))
+ {
+ if (cdrwbl.Owner is FragDrawable) continue; //it's a copied drawable... eg a wheel
+
+ var dname = child.GroupNameHash.ToString();
+ AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsHigh, dname + " - High Detail", true);
+ AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsMedium, dname + " - Medium Detail", false);
+ AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsLow, dname + " - Low Detail", false);
+ AddDrawableModelsTreeNodes(cdrwbl.DrawableModelsVeryLow, dname + " - Very Low Detail", false);
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+
+
+ public void LoadPed()
+ {
+ var pedname = PedNameComboBox.Text;
+ var pednamel = pedname.ToLowerInvariant();
+ MetaHash pedhash = JenkHash.GenHash(pednamel);
+
+
+ //MetaHash modelhashhi = JenkHash.GenHash(pednamel + "_hi");
+ //bool hidet = VehicleHighDetailCheckBox.Checked;
+ //var yfthash = hidet ? modelhashhi : pedhash;
+ //VehicleInitData vid = null;
+ //if (GameFileCache.VehiclesInitDict.TryGetValue(pedhash, out vid))
+ //{
+ // bool vehiclechange = SelectedVehicleHash != pedhash;
+ // SelectedModelHash = yfthash;
+ // SelectedVehicleHash = pedhash;
+ // SelectedVehicleInit = vid;
+ // SelectedVehicleYft = GameFileCache.GetYft(SelectedModelHash);
+ // while (!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()));
+ //}
+ //else
+ //{
+ // SelectedModelHash = 0;
+ // SelectedVehicleHash = 0;
+ // SelectedVehicleInit = null;
+ // SelectedVehicleYft = null;
+ // VehicleMakeLabel.Text = "-";
+ // VehicleNameLabel.Text = "-";
+ //}
+ }
+
+ public void LoadModel(YftFile yft, bool movecamera = true)
+ {
+ if (yft == null) return;
+
+ //FileName = yft.Name;
+ //Yft = yft;
+
+ var dr = yft.Fragment?.Drawable;
+ if (movecamera && (dr != null))
+ {
+ MoveCameraToView(dr.BoundingCenter, dr.BoundingSphereRadius);
+ }
+
+ UpdateModelsUI(yft.Fragment.Drawable);
+ }
+
+
+
+ private void UpdateTimeOfDayLabel()
+ {
+ int v = TimeOfDayTrackBar.Value;
+ float fh = v / 60.0f;
+ int ih = (int)fh;
+ int im = v - (ih * 60);
+ if (ih == 24) ih = 0;
+ TimeOfDayLabel.Text = string.Format("{0:00}:{1:00}", ih, im);
+ }
+
+
+ private void UpdateControlInputs(float elapsed)
+ {
+ if (elapsed > 0.1f) elapsed = 0.1f;
+
+ var s = Settings.Default;
+
+ float moveSpeed = 2.0f;
+
+
+ Input.Update(elapsed);
+
+ if (Input.xbenable)
+ {
+ //if (ControllerButtonJustPressed(GamepadButtonFlags.Start))
+ //{
+ // SetControlMode(ControlMode == WorldControlMode.Free ? WorldControlMode.Ped : WorldControlMode.Free);
+ //}
+ }
+
+
+
+ if (Input.ShiftPressed)
+ {
+ moveSpeed *= 5.0f;
+ }
+ if (Input.CtrlPressed)
+ {
+ moveSpeed *= 0.2f;
+ }
+
+ Vector3 movevec = Input.KeyboardMoveVec(false);
+
+
+ //if (MapViewEnabled == true)
+ //{
+ // movevec *= elapsed * 100.0f * Math.Min(camera.OrthographicTargetSize * 0.01f, 30.0f);
+ // float mapviewscale = 1.0f / camera.Height;
+ // float fdx = MapViewDragX * mapviewscale;
+ // float fdy = MapViewDragY * mapviewscale;
+ // movevec.X -= fdx * camera.OrthographicSize;
+ // movevec.Y += fdy * camera.OrthographicSize;
+ //}
+ //else
+ {
+ //normal movement
+ movevec *= elapsed * moveSpeed * Math.Min(camera.TargetDistance, 50.0f);
+ }
+
+
+ Vector3 movewvec = camera.ViewInvQuaternion.Multiply(movevec);
+ camEntity.Position += movewvec;
+
+ //MapViewDragX = 0;
+ //MapViewDragY = 0;
+
+
+
+
+ if (Input.xbenable)
+ {
+ camera.ControllerRotate(Input.xblx + Input.xbrx, Input.xbly + Input.xbry);
+
+ float zoom = 0.0f;
+ float zoomspd = s.XInputZoomSpeed;
+ float zoomamt = zoomspd * elapsed;
+ if (Input.ControllerButtonPressed(GamepadButtonFlags.DPadUp)) zoom += zoomamt;
+ if (Input.ControllerButtonPressed(GamepadButtonFlags.DPadDown)) zoom -= zoomamt;
+
+ camera.ControllerZoom(zoom);
+
+ float acc = 0.0f;
+ float accspd = s.XInputMoveSpeed;//actually accel speed...
+ acc += Input.xbrt * accspd;
+ acc -= Input.xblt * accspd;
+
+ Vector3 newdir = camera.ViewDirection; //maybe use the "vehicle" direction...?
+ Input.xbcontrolvelocity += (acc * elapsed);
+
+ if (Input.ControllerButtonPressed(GamepadButtonFlags.A | GamepadButtonFlags.RightShoulder)) //handbrake...
+ {
+ Input.xbcontrolvelocity *= Math.Max(0.75f - elapsed, 0);//not ideal for low fps...
+ //xbcontrolvelocity = 0.0f;
+ if (Math.Abs(Input.xbcontrolvelocity) < 0.001f) Input.xbcontrolvelocity = 0.0f;
+ }
+
+ camEntity.Velocity = newdir * Input.xbcontrolvelocity;
+ camEntity.Position += camEntity.Velocity * elapsed;
+
+
+ //fire!
+ //if (ControllerButtonJustPressed(GamepadButtonFlags.LeftShoulder))
+ //{
+ // SpawnTestEntity(true);
+ //}
+
+ }
+
+
+
+ }
+
+
+
+ private void UpdateGridVerts()
+ {
+ lock (gridSyncRoot)
+ {
+ gridVerts.Clear();
+
+ float s = gridSize * gridCount * 0.5f;
+ uint cblack = (uint)Color.Black.ToRgba();
+ uint cgray = (uint)Color.DimGray.ToRgba();
+ uint cred = (uint)Color.DarkRed.ToRgba();
+ uint cgrn = (uint)Color.DarkGreen.ToRgba();
+ int interval = 10;
+
+ for (int i = 0; i <= gridCount; i++)
+ {
+ float o = (gridSize * i) - s;
+ if ((i % interval) != 0)
+ {
+ gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, -s, 0), Colour = cgray });
+ gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, s, 0), Colour = cgray });
+ gridVerts.Add(new VertexTypePC() { Position = new Vector3(-s, o, 0), Colour = cgray });
+ gridVerts.Add(new VertexTypePC() { Position = new Vector3(s, o, 0), Colour = cgray });
+ }
+ }
+ for (int i = 0; i <= gridCount; i++) //draw main lines last, so they are on top
+ {
+ float o = (gridSize * i) - s;
+ if ((i % interval) == 0)
+ {
+ var cx = (o == 0) ? cred : cblack;
+ var cy = (o == 0) ? cgrn : cblack;
+ gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, -s, 0), Colour = cy });
+ gridVerts.Add(new VertexTypePC() { Position = new Vector3(o, s, 0), Colour = cy });
+ gridVerts.Add(new VertexTypePC() { Position = new Vector3(-s, o, 0), Colour = cx });
+ gridVerts.Add(new VertexTypePC() { Position = new Vector3(s, o, 0), Colour = cx });
+ }
+ }
+
+ }
+ }
+
+ private void RenderGrid(DeviceContext context)
+ {
+ if (!enableGrid) return;
+
+ lock (gridSyncRoot)
+ {
+ if (gridVerts.Count > 0)
+ {
+ Renderer.RenderLines(gridVerts);
+ }
+ }
+ }
+
+
+
+
+
+
+
+ private void RenderPed()
+ {
+
+ //YftFile yft = GameFileCache.GetYft(SelectedModelHash);
+ //if (yft != null)
+ //{
+ // 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);
+
+ // Renderer.RenderFragment(arch, null, f, txdhash);
+
+ // //seldrwbl = f.Drawable;
+ // }
+ // }
+ //}
+
+ }
+
+
+
+
+
+
+
+
+
+
+ private void PedsForm_Load(object sender, EventArgs e)
+ {
+ Init();
+ }
+
+ private void PedsForm_MouseDown(object sender, MouseEventArgs e)
+ {
+ switch (e.Button)
+ {
+ case MouseButtons.Left: MouseLButtonDown = true; break;
+ case MouseButtons.Right: MouseRButtonDown = true; break;
+ }
+
+ if (!ToolsPanelShowButton.Focused)
+ {
+ ToolsPanelShowButton.Focus(); //make sure no textboxes etc are focused!
+ }
+
+ MouseDownPoint = e.Location;
+ MouseLastPoint = MouseDownPoint;
+
+ if (MouseLButtonDown)
+ {
+ }
+
+ if (MouseRButtonDown)
+ {
+ //SelectMousedItem();
+ }
+
+ MouseX = e.X; //to stop jumps happening on mousedown, sometimes the last MouseMove event was somewhere else... (eg after clicked a menu)
+ MouseY = e.Y;
+ }
+
+ private void PedsForm_MouseUp(object sender, MouseEventArgs e)
+ {
+ switch (e.Button)
+ {
+ case MouseButtons.Left: MouseLButtonDown = false; break;
+ case MouseButtons.Right: MouseRButtonDown = false; break;
+ }
+
+
+
+ if (e.Button == MouseButtons.Left)
+ {
+ }
+ }
+
+ private void PedsForm_MouseMove(object sender, MouseEventArgs e)
+ {
+ int dx = e.X - MouseX;
+ int dy = e.Y - MouseY;
+
+ //if (MouseInvert)
+ //{
+ // dy = -dy;
+ //}
+
+ //if (ControlMode == WorldControlMode.Free && !ControlBrushEnabled)
+ {
+ if (MouseLButtonDown)
+ {
+ RotateCam(dx, dy);
+ }
+ if (MouseRButtonDown)
+ {
+ if (Renderer.controllightdir)
+ {
+ Renderer.lightdirx += (dx * camera.Sensitivity);
+ Renderer.lightdiry += (dy * camera.Sensitivity);
+ }
+ else if (Renderer.controltimeofday)
+ {
+ float tod = Renderer.timeofday;
+ tod += (dx - dy) / 30.0f;
+ while (tod >= 24.0f) tod -= 24.0f;
+ while (tod < 0.0f) tod += 24.0f;
+ timecycle.SetTime(tod);
+ Renderer.timeofday = tod;
+
+ float fv = tod * 60.0f;
+ TimeOfDayTrackBar.Value = (int)fv;
+ UpdateTimeOfDayLabel();
+ }
+ }
+
+ UpdateMousePosition(e);
+
+ }
+
+
+
+ }
+
+ private void PedsForm_MouseWheel(object sender, MouseEventArgs e)
+ {
+ if (e.Delta != 0)
+ {
+ camera.MouseZoom(e.Delta);
+ }
+ }
+
+ private void PedsForm_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (ActiveControl is TextBox)
+ {
+ var tb = ActiveControl as TextBox;
+ if (!tb.ReadOnly) return; //don't move the camera when typing!
+ }
+ if (ActiveControl is ComboBox)
+ {
+ var cb = ActiveControl as ComboBox;
+ if (cb.DropDownStyle != ComboBoxStyle.DropDownList) return; //nontypable combobox
+ }
+
+ bool enablemove = true;// (!iseditmode) || (MouseLButtonDown && (GrabbedMarker == null) && (GrabbedWidget == null));
+
+ Input.KeyDown(e, enablemove);
+
+ var k = e.KeyCode;
+ var kb = Input.keyBindings;
+ bool ctrl = Input.CtrlPressed;
+ bool shift = Input.ShiftPressed;
+
+
+ if (!ctrl)
+ {
+ if (k == kb.MoveSlowerZoomIn)
+ {
+ camera.MouseZoom(1);
+ }
+ if (k == kb.MoveFasterZoomOut)
+ {
+ camera.MouseZoom(-1);
+ }
+ }
+
+
+ if (!Input.kbmoving) //don't trigger further actions if moving.
+ {
+ if (!ctrl)
+ {
+
+ }
+ else
+ {
+ //switch (k)
+ //{
+ // //case Keys.N:
+ // // New();
+ // // break;
+ // //case Keys.O:
+ // // Open();
+ // // break;
+ // //case Keys.S:
+ // // if (shift) SaveAll();
+ // // else Save();
+ // // break;
+ // //case Keys.Z:
+ // // Undo();
+ // // break;
+ // //case Keys.Y:
+ // // Redo();
+ // // break;
+ // //case Keys.C:
+ // // CopyItem();
+ // // break;
+ // //case Keys.V:
+ // // PasteItem();
+ // // break;
+ // //case Keys.U:
+ // // ToolsPanelShowButton.Visible = !ToolsPanelShowButton.Visible;
+ // // break;
+ //}
+ }
+ }
+
+ //if (ControlMode != WorldControlMode.Free || ControlBrushEnabled)
+ //{
+ // e.Handled = true;
+ //}
+ }
+
+ private void PedsForm_KeyUp(object sender, KeyEventArgs e)
+ {
+ Input.KeyUp(e);
+
+ if (ActiveControl is TextBox)
+ {
+ var tb = ActiveControl as TextBox;
+ if (!tb.ReadOnly) return; //don't move the camera when typing!
+ }
+ if (ActiveControl is ComboBox)
+ {
+ var cb = ActiveControl as ComboBox;
+ if (cb.DropDownStyle != ComboBoxStyle.DropDownList) return; //non-typable combobox
+ }
+
+ //if (ControlMode != WorldControlMode.Free)
+ //{
+ // e.Handled = true;
+ //}
+ }
+
+ private void PedsForm_Deactivate(object sender, EventArgs e)
+ {
+ //try not to lock keyboard movement if the form loses focus.
+ Input.KeyboardStop();
+ }
+
+ private void StatsUpdateTimer_Tick(object sender, EventArgs e)
+ {
+ StatsLabel.Text = Renderer.GetStatusText();
+
+ if (Renderer.timerunning)
+ {
+ float fv = Renderer.timeofday * 60.0f;
+ //TimeOfDayTrackBar.Value = (int)fv;
+ UpdateTimeOfDayLabel();
+ }
+
+ //CameraPositionTextBox.Text = FloatUtil.GetVector3String(camera.Position, "0.##");
+ }
+
+ private void ToolsPanelShowButton_Click(object sender, EventArgs e)
+ {
+ ToolsPanel.Visible = true;
+ }
+
+ private void ToolsPanelHideButton_Click(object sender, EventArgs e)
+ {
+ ToolsPanel.Visible = false;
+ }
+
+ private void ToolsDragPanel_MouseDown(object sender, MouseEventArgs e)
+ {
+ if (e.Button == MouseButtons.Left)
+ {
+ toolsPanelResizing = true;
+ toolsPanelResizeStartX = e.X + ToolsPanel.Left + ToolsDragPanel.Left;
+ toolsPanelResizeStartLeft = ToolsPanel.Left;
+ toolsPanelResizeStartRight = ToolsPanel.Right;
+ }
+ }
+
+ private void ToolsDragPanel_MouseUp(object sender, MouseEventArgs e)
+ {
+ toolsPanelResizing = false;
+ }
+
+ private void ToolsDragPanel_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (toolsPanelResizing)
+ {
+ int rx = e.X + ToolsPanel.Left + ToolsDragPanel.Left;
+ int dx = rx - toolsPanelResizeStartX;
+ ToolsPanel.Width = toolsPanelResizeStartRight - toolsPanelResizeStartLeft + dx;
+ }
+ }
+
+ private void ModelsTreeView_AfterCheck(object sender, TreeViewEventArgs e)
+ {
+ if (e.Node != null)
+ {
+ UpdateSelectionDrawFlags(e.Node);
+ }
+ }
+
+ private void ModelsTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
+ {
+ if (e.Node != null)
+ {
+ e.Node.Checked = !e.Node.Checked;
+ //UpdateSelectionDrawFlags(e.Node);
+ }
+ }
+
+ private void ModelsTreeView_KeyPress(object sender, KeyPressEventArgs e)
+ {
+ e.Handled = true; //stops annoying ding sound...
+ }
+
+ private void HDRRenderingCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ lock (Renderer.RenderSyncRoot)
+ {
+ Renderer.shaders.hdr = HDRRenderingCheckBox.Checked;
+ }
+ }
+
+ private void ShadowsCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ lock (Renderer.RenderSyncRoot)
+ {
+ Renderer.shaders.shadows = ShadowsCheckBox.Checked;
+ }
+ }
+
+ private void SkydomeCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ Renderer.renderskydome = SkydomeCheckBox.Checked;
+ //Renderer.controllightdir = !Renderer.renderskydome;
+ }
+
+ private void ControlLightDirCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ Renderer.controllightdir = ControlLightDirCheckBox.Checked;
+ }
+
+ private void TimeOfDayTrackBar_Scroll(object sender, EventArgs e)
+ {
+ int v = TimeOfDayTrackBar.Value;
+ float fh = v / 60.0f;
+ UpdateTimeOfDayLabel();
+ lock (Renderer.RenderSyncRoot)
+ {
+ Renderer.timeofday = fh;
+ timecycle.SetTime(Renderer.timeofday);
+ }
+ }
+
+ private void ShowCollisionMeshesCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ Renderer.rendercollisionmeshes = ShowCollisionMeshesCheckBox.Checked;
+ Renderer.rendercollisionmeshlayerdrawable = ShowCollisionMeshesCheckBox.Checked;
+ }
+
+ private void WireframeCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ Renderer.shaders.wireframe = WireframeCheckBox.Checked;
+ }
+
+ private void AnisotropicFilteringCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ Renderer.shaders.AnisotropicFiltering = AnisotropicFilteringCheckBox.Checked;
+ }
+
+ private void HDTexturesCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ Renderer.renderhdtextures = HDTexturesCheckBox.Checked;
+ }
+
+ private void RenderModeComboBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ TextureSamplerComboBox.Enabled = false;
+ TextureCoordsComboBox.Enabled = false;
+ switch (RenderModeComboBox.Text)
+ {
+ default:
+ case "Default":
+ Renderer.shaders.RenderMode = WorldRenderMode.Default;
+ break;
+ case "Single texture":
+ Renderer.shaders.RenderMode = WorldRenderMode.SingleTexture;
+ TextureSamplerComboBox.Enabled = true;
+ TextureCoordsComboBox.Enabled = true;
+ break;
+ case "Vertex normals":
+ Renderer.shaders.RenderMode = WorldRenderMode.VertexNormals;
+ break;
+ case "Vertex tangents":
+ Renderer.shaders.RenderMode = WorldRenderMode.VertexTangents;
+ break;
+ case "Vertex colour 1":
+ Renderer.shaders.RenderMode = WorldRenderMode.VertexColour;
+ Renderer.shaders.RenderVertexColourIndex = 1;
+ break;
+ case "Vertex colour 2":
+ Renderer.shaders.RenderMode = WorldRenderMode.VertexColour;
+ Renderer.shaders.RenderVertexColourIndex = 2;
+ break;
+ case "Vertex colour 3":
+ Renderer.shaders.RenderMode = WorldRenderMode.VertexColour;
+ Renderer.shaders.RenderVertexColourIndex = 3;
+ break;
+ case "Texture coord 1":
+ Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord;
+ Renderer.shaders.RenderTextureCoordIndex = 1;
+ break;
+ case "Texture coord 2":
+ Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord;
+ Renderer.shaders.RenderTextureCoordIndex = 2;
+ break;
+ case "Texture coord 3":
+ Renderer.shaders.RenderMode = WorldRenderMode.TextureCoord;
+ Renderer.shaders.RenderTextureCoordIndex = 3;
+ break;
+ }
+ }
+
+ private void TextureSamplerComboBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (TextureSamplerComboBox.SelectedItem is ShaderParamNames)
+ {
+ Renderer.shaders.RenderTextureSampler = (ShaderParamNames)TextureSamplerComboBox.SelectedItem;
+ }
+ }
+
+ private void TextureCoordsComboBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ switch (TextureCoordsComboBox.Text)
+ {
+ default:
+ case "Texture coord 1":
+ Renderer.shaders.RenderTextureSamplerCoord = 1;
+ break;
+ case "Texture coord 2":
+ Renderer.shaders.RenderTextureSamplerCoord = 2;
+ break;
+ case "Texture coord 3":
+ Renderer.shaders.RenderTextureSamplerCoord = 3;
+ break;
+ }
+ }
+
+ private void GridCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ enableGrid = GridCheckBox.Checked;
+ }
+
+ private void GridSizeComboBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ float newgs;
+ float.TryParse(GridSizeComboBox.Text, out newgs);
+ if (newgs != gridSize)
+ {
+ gridSize = newgs;
+ UpdateGridVerts();
+ }
+ }
+
+ private void GridCountComboBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ int newgc;
+ int.TryParse(GridCountComboBox.Text, out newgc);
+ if (newgc != gridCount)
+ {
+ gridCount = newgc;
+ UpdateGridVerts();
+ }
+ }
+
+ private void SkeletonsCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ Renderer.renderskeletons = SkeletonsCheckBox.Checked;
+ }
+
+ private void StatusBarCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ StatusStrip.Visible = StatusBarCheckBox.Checked;
+ }
+
+ private void ErrorConsoleCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ ConsolePanel.Visible = ErrorConsoleCheckBox.Checked;
+ }
+
+ private void TextureViewerButton_Click(object sender, EventArgs e)
+ {
+ //TextureDictionary td = null;
+
+ //if ((Ydr != null) && (Ydr.Loaded))
+ //{
+ // td = Ydr.Drawable?.ShaderGroup?.TextureDictionary;
+ //}
+ //else if ((Yft != null) && (Yft.Loaded))
+ //{
+ // td = Yft.Fragment?.Drawable?.ShaderGroup?.TextureDictionary;
+ //}
+
+ //if (td != null)
+ //{
+ // YtdForm f = new YtdForm();
+ // f.Show();
+ // f.LoadTexDict(td, fileName);
+ // //f.LoadYtd(ytd);
+ //}
+ //else
+ //{
+ // MessageBox.Show("Couldn't find embedded texture dict.");
+ //}
+ }
+
+
+
+
+ }
+}
diff --git a/Peds/PedsForm.resx b/Peds/PedsForm.resx
new file mode 100644
index 0000000..36d72f5
--- /dev/null
+++ b/Peds/PedsForm.resx
@@ -0,0 +1,415 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+ 127, 17
+
+
+
+
+ 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
+ 6P///ysvjWVqtP///////wAAAAAAAAAAAP////D0/0hPpsDG6////////6y02d7k8////3qAx+/z/f//
+ /wAAAAAAAAAAAAAAAAAAAP///////////////8zT8V5ns1Rcrdzh9f///////////wAAAAAAAAAAAAAA
+ AAAAAP////////7+/6ix3nmBxFthtmdwu09WqbC54/v9//r8//j6//39/wAAAAAAAAAAAOjt/H6I0FJc
+ skpSqHF+wRMahFZhs4iT1AsNc1pgrm52v2RsuO/z/gAAAP////////L2/cLJ7rrD64+V4DY+ozU+mYmU
+ 0X2Hy1hfss7V8urv/PP2/v///wAAAP///+Pp+d/k9////////+Pp/4uR3ysymW14xYOM0fD0/P///+Xq
+ +ri/6Pj6/wAAAOrv/j5DnbS75P////////////X4/+/0/ubr+/r7/////////9rh+hgZhKGo2QAAAPDz
+ /eLn+f////j6/2Nqttrg9////+Hn+P3+//3+/1hescLJ6/////L2/eru/AAAAAAAAAAAAP///8rR70tR
+ p/3+//v8/zY6jNPY7////09WqWpwu////wAAAAAAAAAAAAAAAAAAAAAAAPb4/vr7//////v8/5Wd1eHm
+ +P////v8//T3/wAAAAAAAAAAAAAAAP//AAD8PwAA/D8AAPwDAACAAwAAgAMAAIAHAADABwAAwAEAAMAB
+ AAAAAQAAAAEAAAABAAAAAQAAwAcAAOAPAAAoAAAAQAAAAIAAAAABABgAAAAAAAAwAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3//P3//P3/
+ /f7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/
+ +fv/+fv/+Pr/+fv/+vv//P3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAA/f7/+fr/8/b/7PL/5+3/6e/+9Pf/+vv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAA/P3/9/r/6O7/cXe1UVaet7z17fL/+Pr//f3/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+/z/9Pj/4Oj/NzyCUlOd2dz/6O//9Pf//P3/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/2+P9X2OmREGLnqPd
+ 4+v/8vb/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/
+ 1N35bXK1JSRtbHGz5O7/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAA+vv/8PX/3Ob/U1eaDwtXjZLT4+z/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2eP+MjR6AAA+c3i34Or/8fX/+/z/AAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/1d/7MS91AAA1UFSS4On/8vb/+/z/AAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ 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
+ /v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+vz/+fv/+Pr/+Pr/+vv//f3//v//AAAAAAAAAAAAAAAA
+ /v//+fv/9Pf/2+L/SVGtAABsLTaZytL58fX/9/n//f7/AAAAAAAAAAAAAAAA/v7/+/z/9/n/9fj/9vn/
+ 9fj/9vj/+vz//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//f3//f3//f3//v7//v//AAAA
+ AAAAAAAAAAAAAAAAAAAA+/z/9vn/6e//mZ7gTVarr7bp6/H/9fj/+vv//v7/AAAAAAAAAAAAAAAAAAAA
+ /v7//f7/+/z/+/z/+/z//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/+Pr/9fj/6e7/4+n/8fb/9Pf/+Pr//f3/AAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+fv/+fv/+vv/+Pr/+vv/
+ /P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7/
+ /f3//P3//f7//v7//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////
+ ///////4D/////////AH////////8Af////////wB/////////AH////////8Af////////wB///////
+ //AH////////8Af////////wB/////////AH////////8AfwP//////wB8Af//+Af/AHgB///wA/8AcA
+ H///AB/wBgAf//8AD/AGAB///wAH8AYAH///AAPwBAAf//8AA/AEAD///wAD8AQAP///AAPwBAB///+A
+ A/AEAP///8AD4AAA////4AcAAAH////wDgAAAf/////8AAAH//////gAAAf/////4AAAAf/////gAAAA
+ /f//+AAAAAAAD//AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+A
+ AAAAAAAP/4AAAAAAAB//wAAAAABAf/4HwAAAAYAf8APAAAADgA/gA+AAAAMAA8AD8AAABwADgAP8AAAf
+ AAOAA/4AAB8AA4ADAAAAAQADgAIAcA4AgAOABgBwDgBAA4AMAGAMADADwDwAYAwAOAfg+ABgBAAeH//4
+ AEAEAB////gAwAYAH///+ADABgAf///4AcAGAB////gBwAcAH///+APAB4A////8B+AHwH//////4A//
+ ///////gD/////////Af//////////////8=
+
+
+
\ No newline at end of file
diff --git a/Program.cs b/Program.cs
index 6bb6187..a064e7b 100644
--- a/Program.cs
+++ b/Program.cs
@@ -19,6 +19,7 @@ namespace CodeWalker
bool explorermode = false;
bool projectmode = false;
bool vehiclesmode = false;
+ bool pedsmode = false;
if ((args != null) && (args.Length > 0))
{
foreach (string arg in args)
@@ -40,6 +41,10 @@ namespace CodeWalker
{
vehiclesmode = true;
}
+ if (argl == "peds")
+ {
+ pedsmode = true;
+ }
}
}
@@ -73,6 +78,10 @@ namespace CodeWalker
{
Application.Run(new Vehicles.VehicleForm());
}
+ else if (pedsmode)
+ {
+ Application.Run(new Peds.PedsForm());
+ }
else
{
Application.Run(new WorldForm());
diff --git a/Project/Panels/GenerateLODLightsPanel.cs b/Project/Panels/GenerateLODLightsPanel.cs
index ece3fb9..7e27c42 100644
--- a/Project/Panels/GenerateLODLightsPanel.cs
+++ b/Project/Panels/GenerateLODLightsPanel.cs
@@ -180,14 +180,14 @@ namespace CodeWalker.Project.Panels
xform = modeltransforms[boneidx];
xform.Column4 = Vector4.UnitW;
//xform = Matrix.Identity;
- ushort[] pinds = skeleton.ParentIndices;
- ushort parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (ushort)65535;
- while (parentind < pinds.Length)
+ short[] pinds = skeleton.ParentIndices;
+ short parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (short)-1;
+ while ((parentind >= 0) && (parentind < pinds.Length))
{
Matrix ptrans = (parentind < modeltransforms.Length) ? modeltransforms[parentind] : Matrix.Identity;
ptrans.Column4 = Vector4.UnitW;
xform = Matrix.Multiply(ptrans, xform);
- parentind = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (ushort)65535;
+ parentind = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (short)-1;
}
}
}
diff --git a/Rendering/Renderable.cs b/Rendering/Renderable.cs
index 1f9e3f3..e7e07eb 100644
--- a/Rendering/Renderable.cs
+++ b/Rendering/Renderable.cs
@@ -279,14 +279,14 @@ namespace CodeWalker.Rendering
else if (!usepose) //when using the skeleton's matrices, they need to be transformed by parent
{
trans.Column4 = Vector4.UnitW;
- ushort[] pinds = skeleton.ParentIndices;
- ushort parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (ushort)65535;
- while (parentind < pinds.Length)
+ short[] pinds = skeleton.ParentIndices;
+ short parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (short)-1;
+ while ((parentind >= 0) && (parentind < pinds.Length))
{
Matrix ptrans = (parentind < modeltransforms.Length) ? modeltransforms[parentind] : Matrix.Identity;
ptrans.Column4 = Vector4.UnitW;
trans = Matrix.Multiply(ptrans, trans);
- parentind = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (ushort)65535;
+ parentind = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (short)-1;
}
}
diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs
index 3c8b4e1..30924c5 100644
--- a/Rendering/Renderer.cs
+++ b/Rendering/Renderer.cs
@@ -1136,7 +1136,7 @@ namespace CodeWalker.Rendering
if (xforms != null)//how to use xforms? bind pose?
{
var xform = (i < xforms.Length) ? xforms[i] : Matrix.Identity;
- var pxform = (pind < xforms.Length) ? xforms[pind] : Matrix.Identity;
+ var pxform = ((pind >= 0) && (pind < xforms.Length)) ? xforms[pind] : Matrix.Identity;
}
else
{