Merge pull request #170 from alexguirre/mrf-research

MRF/XML conversion
This commit is contained in:
dexyfex 2022-09-08 10:23:33 +10:00 committed by GitHub
commit 983ab5a977
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 4689 additions and 1218 deletions

File diff suppressed because it is too large Load Diff

View File

@ -4543,6 +4543,39 @@ namespace CodeWalker.GameFiles
}
else
{ }
var xml = MrfXml.GetXml(mrffile);
var mrf2 = XmlMrf.GetMrf(xml);
var ndata2 = mrf2.Save();
if (ndata2.Length == odata.Length)
{
for (int i = 0; i < ndata2.Length; i++)
{
if (ndata2[i] != odata[i] && !mrfDiffCanBeIgnored(i, mrffile))
{ break; }
}
}
else
{ }
bool mrfDiffCanBeIgnored(int fileOffset, MrfFile originalMrf)
{
foreach (var n in originalMrf.AllNodes)
{
if (n is MrfNodeStateBase state)
{
// If TransitionCount is 0, the TransitionsOffset value can be ignored.
// TransitionsOffset in original MRFs isn't always set to 0 in this case,
// XML-imported MRFs always set it to 0
if (state.TransitionCount == 0 && fileOffset == (state.FileOffset + 0x1C))
{
return true;
}
}
}
return false;
}
}
else
{ }
@ -4554,6 +4587,103 @@ namespace CodeWalker.GameFiles
}
}
}
// create and save a custom MRF
{
// Usage example:
// RequestAnimDict("move_m@alien")
// TaskMoveNetworkByName(PlayerPedId(), "mymrf", 0.0, true, 0, 0)
// SetTaskMoveNetworkSignalFloat(PlayerPedId(), "sprintrate", 2.0)
var mymrf = new MrfFile();
var clip1 = new MrfNodeClip
{
NodeIndex = 0,
Name = JenkHash.GenHash("clip1"),
ClipType = MrfValueType.Literal,
ClipContainerType = MrfClipContainerType.ClipDictionary,
ClipContainerName = JenkHash.GenHash("move_m@alien"),
ClipName = JenkHash.GenHash("alien_run"),
LoopedType = MrfValueType.Literal,
Looped = true,
};
var clip2 = new MrfNodeClip
{
NodeIndex = 0,
Name = JenkHash.GenHash("clip2"),
ClipType = MrfValueType.Literal,
ClipContainerType = MrfClipContainerType.ClipDictionary,
ClipContainerName = JenkHash.GenHash("move_m@alien"),
ClipName = JenkHash.GenHash("alien_sprint"),
LoopedType = MrfValueType.Literal,
Looped = true,
RateType = MrfValueType.Parameter,
RateParameterName = JenkHash.GenHash("sprintrate"),
};
var clipstate1 = new MrfNodeState
{
NodeIndex = 0,
Name = JenkHash.GenHash("clipstate1"),
InitialNode = clip1,
Transitions = new[]
{
new MrfStateTransition
{
Duration = 2.5f,
HasDurationParameter = false,
//TargetState = clipstate2,
Conditions = new[]
{
new MrfConditionTimeGreaterThan { Value = 4.0f },
},
}
},
};
var clipstate2 = new MrfNodeState
{
NodeIndex = 1,
Name = JenkHash.GenHash("clipstate2"),
InitialNode = clip2,
Transitions = new[]
{
new MrfStateTransition
{
Duration = 2.5f,
HasDurationParameter = false,
//TargetState = clipstate1,
Conditions = new[]
{
new MrfConditionTimeGreaterThan { Value = 4.0f },
},
}
},
};
clipstate1.Transitions[0].TargetState = clipstate2;
clipstate2.Transitions[0].TargetState = clipstate1;
var rootsm = new MrfNodeStateMachine
{
NodeIndex = 0,
Name = JenkHash.GenHash("statemachine"),
States = new[]
{
new MrfStateRef { StateName = clipstate1.Name, State = clipstate1 },
new MrfStateRef { StateName = clipstate2.Name, State = clipstate2 },
},
InitialNode = clipstate1,
};
mymrf.AllNodes = new MrfNode[]
{
rootsm,
clipstate1,
clip1,
clipstate2,
clip2,
};
mymrf.RootState = rootsm;
var mymrfData = mymrf.Save();
//File.WriteAllBytes("mymrf.mrf", mymrfData);
//File.WriteAllText("mymrf.dot", mymrf.DumpStateGraph());
}
}
public void TestFxcs()
{

View File

@ -147,6 +147,11 @@ namespace CodeWalker.GameFiles
HeightmapFile hmf = RpfFile.GetFile<HeightmapFile>(e, data);
return GetXml(hmf, out filename, outputfolder);
}
else if (fnl.EndsWith(".mrf"))
{
MrfFile mrf = RpfFile.GetFile<MrfFile>(e, data);
return GetXml(mrf, out filename, outputfolder);
}
filename = fn;
return string.Empty;
}
@ -314,6 +319,12 @@ namespace CodeWalker.GameFiles
filename = fn + ".xml";
return HmapXml.GetXml(hmf);
}
public static string GetXml(MrfFile mrf, out string filename, string outputfolder)
{
var fn = (mrf?.Name) ?? "";
filename = fn + ".xml";
return MrfXml.GetXml(mrf);
}
@ -2231,6 +2242,7 @@ namespace CodeWalker.GameFiles
Fxc = 20,
Heightmap = 21,
Ypdb = 22,
Mrf = 23,
}
}

View File

@ -59,6 +59,8 @@ namespace CodeWalker.GameFiles
return GetHeightmapData(doc);
case MetaFormat.Ypdb:
return GetYpdbData(doc);
case MetaFormat.Mrf:
return GetMrfData(doc);
}
return null;
}
@ -194,6 +196,12 @@ namespace CodeWalker.GameFiles
if (ypdb.WeightSet == null) return null;
return ypdb.Save();
}
public static byte[] GetMrfData(XmlDocument doc)
{
var mrf = XmlMrf.GetMrf(doc);
if (mrf == null) return null;
return mrf.Save();
}
public static string GetXMLFormatName(MetaFormat mformat)
@ -222,6 +230,7 @@ namespace CodeWalker.GameFiles
case MetaFormat.CacheFile: return "CacheFile XML";
case MetaFormat.Heightmap: return "Heightmap XML";
case MetaFormat.Ypdb: return "YPDB XML";
case MetaFormat.Mrf: return "MRF XML";
default: return "XML";
}
}
@ -320,6 +329,10 @@ namespace CodeWalker.GameFiles
{
mformat = MetaFormat.Ypdb;
}
if (fnamel.EndsWith(".mrf.xml"))
{
mformat = MetaFormat.Mrf;
}
return mformat;
}

View File

@ -298,7 +298,7 @@ namespace CodeWalker
InitFileType(".png", "Portable Network Graphics", 16);
InitFileType(".dds", "DirectDraw Surface", 16);
InitFileType(".ytd", "Texture Dictionary", 16, FileTypeAction.ViewYtd, true);
InitFileType(".mrf", "Move Network File", 18, FileTypeAction.ViewMrf);
InitFileType(".mrf", "Move Network File", 18, FileTypeAction.ViewMrf, true);
InitFileType(".ycd", "Clip Dictionary", 18, FileTypeAction.ViewYcd, true);
InitFileType(".ypt", "Particle Effect", 18, FileTypeAction.ViewModel, true);
InitFileType(".ybn", "Static Collisions", 19, FileTypeAction.ViewModel, true);
@ -1793,9 +1793,9 @@ namespace CodeWalker
private void ViewMrf(string name, string path, byte[] data, RpfFileEntry e)
{
var mrf = RpfFile.GetFile<MrfFile>(e, data);
GenericForm f = new GenericForm(this);
MetaForm f = new MetaForm(this);
f.Show();
f.LoadFile(mrf, mrf.RpfFileEntry);
f.LoadMeta(mrf);
}
private void ViewNametable(string name, string path, byte[] data, RpfFileEntry e)
{

View File

@ -388,6 +388,20 @@ namespace CodeWalker.Forms
metaFormat = MetaFormat.Ypdb;
}
}
public void LoadMeta(MrfFile mrf)
{
var fn = ((mrf?.RpfFileEntry?.Name) ?? "") + ".xml";
Xml = MrfXml.GetXml(mrf);
FileName = fn;
RawPropertyGrid.SelectedObject = mrf;
rpfFileEntry = mrf?.RpfFileEntry;
modified = false;
metaFormat = MetaFormat.XML;
if (mrf?.RpfFileEntry != null)
{
metaFormat = MetaFormat.Mrf;
}
}