public Bio2DA(ExportEntry export) { //Console.WriteLine("Loading " + export.ObjectName); Export = export; RowNames = new List<string>(); if (export.ClassName == "Bio2DA") { const string rowLabelsVar = "m_sRowLabel"; var props = export.GetProperty<ArrayProperty<NameProperty>>(rowLabelsVar); if (props != null) { foreach (NameProperty n in props) { RowNames.Add(n.ToString()); } } else { Console.WriteLine("Unable to find row names property!"); return; } } else { var props = export.GetProperty<ArrayProperty<IntProperty>>("m_lstRowNumbers");//Bio2DANumberedRows if (props != null) { foreach (IntProperty n in props) { RowNames.Add(n.Value.ToString()); } } else { Debug.WriteLine("Unable to find row names property (m_lstRowNumbers)!"); return; } } var binary = export.GetBinaryData<Bio2DABinary>(); ColumnNames = new List<string>(binary.ColumnNames.Select(n => n.Name)); Cells = new Bio2DACell[RowCount, ColumnCount]; foreach ((int index, Bio2DABinary.Cell cell) in binary.Cells) { int row = index / ColumnCount; int col = index % ColumnCount; this[row, col] = cell.Type switch { Bio2DABinary.DataType.INT => new Bio2DACell(cell.IntValue), Bio2DABinary.DataType.NAME => new Bio2DACell(cell.NameValue, export.FileRef), Bio2DABinary.DataType.FLOAT => new Bio2DACell(cell.FloatValue), _ => throw new ArgumentOutOfRangeException() }; } IsIndexed = binary.IsIndexed; }
private static void SetupChildrenBlend(ExportEntry export) { // Drill to children var childrenX = export.GetProperty <ArrayProperty <StructProperty> >("Children"); if (childrenX != null) { foreach (var c in childrenX) { var anim = c.GetProp <ObjectProperty>("Anim").ResolveToEntry(export.FileRef) as ExportEntry; if (anim != null) { SetupChildrenBlend(anim); } } } // Update blends var randInfo = export.GetProperty <ArrayProperty <StructProperty> >("RandomInfo"); if (randInfo != null) { foreach (var ri in randInfo) { ri.Properties.AddOrReplaceProp(new FloatProperty(3, "BlendInTime")); } export.WriteProperty(randInfo); } }
private static bool CanRandomize(ExportEntry export, bool isArchetypeCheck, out ExportEntry hairMeshExp) { hairMeshExp = null; if (export.IsDefaultObject) { return(false); } if (export.ClassName == "BioPawn" && export.GetProperty <ObjectProperty>("m_oHairMesh") is ObjectProperty op && op.ResolveToEntry(export.FileRef) is ExportEntry hairExp) { hairMeshExp = hairExp; return(true); } if (export.ClassName == "SFXSkeletalMeshActorMAT") { if (export.GetProperty <ObjectProperty>("HairMesh") is ObjectProperty opSKM && opSKM.ResolveToEntry(export.FileRef) is ExportEntry hairExpSKM) { // Check if skeletal mesh is set locally or if it's done in the archetype // if set to zero we should not add hair cause it will look bad var skeletalMesh = hairExpSKM.GetProperty <ObjectProperty>("SkeletalMesh"); if (skeletalMesh == null) { // Look in archetype if (export.Archetype != null) { ExportEntry arch = export.Archetype as ExportEntry; if (export.Archetype is ImportEntry imp) { // oof arch = EntryImporter.ResolveImport(imp, MERFileSystem.GetGlobalCache()); } hairMeshExp = hairExpSKM; var result = export.ObjectFlags.Has(UnrealFlags.EObjectFlags.ArchetypeObject) == isArchetypeCheck && CanRandomize(arch, true, out _); // look at archetype if (result && !isArchetypeCheck) { Debug.WriteLine($"Running on {export.ObjectName.Instanced}"); } return(result); } } else { hairMeshExp = hairExpSKM; var result = export.ObjectFlags.Has(UnrealFlags.EObjectFlags.ArchetypeObject) == isArchetypeCheck && skeletalMesh.Value != 0; if (result && !isArchetypeCheck) { Debug.WriteLine($"Running on {export.ObjectName.Instanced}"); } return(result); } } } return(false); }
public static void SetUpAnimStreamFile(string animSourceFilePath, int animSequenceUIndex, string saveAsName) { string animViewerAnimStreamFilePath = Path.Combine(App.ExecFolder, "ME3AnimViewer_StreamAnim.pcc"); using IMEPackage pcc = MEPackageHandler.OpenMEPackage(animViewerAnimStreamFilePath); if (animSourceFilePath != null) { try { const int InterpDataUIndex = 8; const int InterpTrackAnimControlUIndex = 10; const int KIS_DYN_AnimsetUIndex = 6; #if DEBUG Debug.WriteLine($"AnimViewer Loading: {animSourceFilePath} #{animSequenceUIndex}"); #endif using IMEPackage animSourceFile = MEPackageHandler.OpenMEPackage(animSourceFilePath); ExportEntry sourceAnimSeq = animSourceFile.GetUExport(animSequenceUIndex); IEntry parent = EntryImporter.GetOrAddCrossImportOrPackage(sourceAnimSeq.ParentFullPath, animSourceFile, pcc); EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.CloneAllDependencies, sourceAnimSeq, pcc, parent, true, out IEntry ent); ExportEntry importedAnimSeq = (ExportEntry)ent; NameReference seqName = importedAnimSeq.GetProperty <NameProperty>("SequenceName").Value; float seqLength = importedAnimSeq.GetProperty <FloatProperty>("SequenceLength"); IEntry bioAnimSet = pcc.GetEntry(importedAnimSeq.GetProperty <ObjectProperty>("m_pBioAnimSetData").Value); string setName = importedAnimSeq.ObjectName.Name.RemoveRight(seqName.Name.Length + 1); ExportEntry animInterpData = pcc.GetUExport(InterpDataUIndex); animInterpData.WriteProperty(new FloatProperty(seqLength, "InterpLength")); ExportEntry animTrack = pcc.GetUExport(InterpTrackAnimControlUIndex); var animSeqKeys = animTrack.GetProperty <ArrayProperty <StructProperty> >("AnimSeqs"); animSeqKeys[0].Properties.AddOrReplaceProp(new NameProperty(seqName, "AnimSeqName")); animTrack.WriteProperty(animSeqKeys); ExportEntry dynamicAnimSet = pcc.GetUExport(KIS_DYN_AnimsetUIndex); dynamicAnimSet.WriteProperty(new ObjectProperty(bioAnimSet.UIndex, "m_pBioAnimSetData")); dynamicAnimSet.WriteProperty(new NameProperty(setName, "m_nmOrigSetName")); dynamicAnimSet.WriteProperty(new ArrayProperty <ObjectProperty>("Sequences") { new ObjectProperty(importedAnimSeq.UIndex) }); } catch (Exception e) { MessageBox.Show($"Error Loading {animSourceFilePath} #{animSequenceUIndex}"); } } string tempFilePath = Path.Combine(ME3Directory.CookedPCPath, $"{saveAsName}.pcc"); pcc.Save(tempFilePath); InteropHelper.TryPadFile(tempFilePath, 10_485_760); }
private static void RandomizeDancer(ExportEntry skeletalMeshActorMatArchetype) { // Install new head and body assets var newInfo = IlliumHub.DancerOptions.RandomElement(); while (newInfo.Location != null || newInfo.Rotation != null || (newInfo.BodyAsset != null && !newInfo.BodyAsset.IsAssetFileAvailable()) || (newInfo.HeadAsset != null && !newInfo.HeadAsset.IsAssetFileAvailable())) { // Make sure assets are available, if not, repick // I don't want anything that requires specific positioning data newInfo = IlliumHub.DancerOptions.RandomElement(); } var newBody = PackageTools.PortExportIntoPackage(skeletalMeshActorMatArchetype.FileRef, newInfo.BodyAsset.GetAsset()); var bodySM = skeletalMeshActorMatArchetype.GetProperty <ObjectProperty>("SkeletalMeshComponent").ResolveToEntry(skeletalMeshActorMatArchetype.FileRef) as ExportEntry; var headSM = skeletalMeshActorMatArchetype.GetProperty <ObjectProperty>("HeadMesh").ResolveToEntry(skeletalMeshActorMatArchetype.FileRef) as ExportEntry; bodySM.WriteProperty(new ObjectProperty(newBody.UIndex, "SkeletalMesh")); if (newInfo.HeadAsset != null) { var newHead = PackageTools.PortExportIntoPackage(skeletalMeshActorMatArchetype.FileRef, newInfo.HeadAsset.GetAsset()); headSM.WriteProperty(new ObjectProperty(newHead.UIndex, "SkeletalMesh")); } else if (!newInfo.KeepHead) { headSM.RemoveProperty("SkeletalMesh"); } if (newInfo.DrawScale != 1) { // Install DS3D on the archetype. It works. Not gonna question it var ds = new CFVector3() { X = newInfo.DrawScale, Y = newInfo.DrawScale, Z = newInfo.DrawScale, }; skeletalMeshActorMatArchetype.WriteProperty(ds.ToLocationStructProperty("DrawScale3D")); //hack } if (newInfo.MorphFace != null) { var newHead = PackageTools.PortExportIntoPackage(skeletalMeshActorMatArchetype.FileRef, newInfo.MorphFace.GetAsset()); headSM.WriteProperty(new ObjectProperty(newHead.UIndex, "MorphHead")); } }
public static bool RandomizeExport(ExportEntry export, RandomizationOption option) { if (!CanRandomize(export)) { return(false); } var boneDefinitions = export.GetProperty <ArrayProperty <StructProperty> >(export.ClassName == @"BioLookAtDefinition" ? "BoneDefinitions" : "m_aLookBoneDefs"); if (boneDefinitions != null) { //Log.Information($"Randomizing BioLookAtDefinition {export.UIndex}"); foreach (var item in boneDefinitions) { //if (item.GetProp<NameProperty>("m_nBoneName").Value.Name.StartsWith("Eye")) //{ // item.GetProp<FloatProperty>("m_fLimit").Value = ThreadSafeRandom.Next(1, 5); // item.GetProp<FloatProperty>("m_fUpDownLimit").Value = ThreadSafeRandom.Next(1, 5); //} //else //{ item.GetProp <FloatProperty>(@"m_fDelay").Value = ThreadSafeRandom.NextFloat(0, 5); item.GetProp <FloatProperty>("m_fLimit").Value = ThreadSafeRandom.NextFloat(1, 170); item.GetProp <FloatProperty>("m_fUpDownLimit").Value = ThreadSafeRandom.NextFloat(70, 170); //} } export.WriteProperty(boneDefinitions); return(true); } return(false); }
public static List <ExportEntry> GetCollectionItems(ExportEntry smac) { var collectionItems = new List <ExportEntry>(); var smacItems = smac.GetProperty <ArrayProperty <ObjectProperty> >(smac.ClassName == "StaticMeshCollectionActor" ? "StaticMeshComponents" : "LightComponents"); if (smacItems != null) { //Read exports... foreach (ObjectProperty obj in smacItems) { if (obj.Value > 0) { ExportEntry item = smac.FileRef.GetUExport(obj.Value); collectionItems.Add(item); } else { //this is a blank entry, or an import, somehow. collectionItems.Add(null); } } return(collectionItems); } return(null); }
/// <summary> /// Builds a list of OutputLinkIdx => [List of nodes pointed to] /// </summary> /// <param name="node"></param> /// <returns></returns> public static List <List <SeqTools.OutboundLink> > GetOutboundLinksOfNode(ExportEntry node) { var outputLinksMapping = new List <List <SeqTools.OutboundLink> >(); var outlinksProp = node.GetProperty <ArrayProperty <StructProperty> >("OutputLinks"); if (outlinksProp != null) { int i = 0; foreach (var ol in outlinksProp) { var oLinks = new List <SeqTools.OutboundLink>(); outputLinksMapping.Add(oLinks); var links = ol.GetProp <ArrayProperty <StructProperty> >("Links"); if (links != null) { foreach (var l in links) { oLinks.Add(SeqTools.OutboundLink.FromStruct(l, node.FileRef)); } } i++; } } return(outputLinksMapping); }
public static void SetLocation(ExportEntry export, float x, float y, float z) { StructProperty prop = export.GetProperty <StructProperty>("location"); SetLocation(prop, x, y, z); export.WriteProperty(prop); }
/// <summary> /// When gun randomizer is active, we must also update weapon animations /// unfortunately due to the complexity there's no way this could be done on the fly /// so we're just gonna update all of them /// </summary> /// <param name="export"></param> /// <param name="wrtype"></param> /// <returns></returns> private static bool CanRandomize(ExportEntry export, out EWRType wrtype) { wrtype = EWRType.Invalid; if (export.IsDefaultObject) { return(false); } if (export.ClassName == "Bio_Appr_Character_Body") { var fname = Path.GetFileName(export.FileRef.FilePath); if ((!fname.StartsWith("BioD") && !fname.StartsWith("BioP")) || fname == "BioP_Global.pcc") { return(false); // Only modify design files } wrtype = EWRType.ApprBody; return(true); } else if (export.ClassName == "SFXLoadoutData" //&& !export.ObjectName.Name.Contains("HeavyWeaponMech") // Not actually sure we can't randomize this one && !export.ObjectName.Name.Contains("BOS_Reaper") && // Don't randomize the final boss cause it'd really make him stupid export.GetProperty <ArrayProperty <ObjectProperty> >("Weapons") != null) { wrtype = EWRType.Loadout; return(true); } else if (export.ClassName == "BioSeqAct_SetWeapon") { wrtype = EWRType.SetWeapon; return(true); } return(false); }
public InterpGroup(ExportEntry export) { Export = export; GroupName = export.GetProperty <NameProperty>("GroupName")?.Value ?? "Group"; if (export.GetProperty <StructProperty>("GroupColor") is StructProperty colorStruct) { var a = colorStruct.GetProp <ByteProperty>("A").Value; var r = colorStruct.GetProp <ByteProperty>("R").Value; var g = colorStruct.GetProp <ByteProperty>("G").Value; var b = colorStruct.GetProp <ByteProperty>("B").Value; GroupColor = Color.FromArgb(a, r, g, b); } RefreshTracks(); }
public static bool RandomizeExport(ExportEntry export, RandomizationOption option) { if (!CanRandomize(export)) { return(false); } //Log.Information($@"Randomizing light {export.UIndex}"); var lc = export.GetProperty <StructProperty>("LightColor"); if (lc == null) { // create var pc = new PropertyCollection(); pc.Add(new ByteProperty(255, "B")); pc.Add(new ByteProperty(255, "G")); pc.Add(new ByteProperty(255, "R")); pc.Add(new ByteProperty(0, "A")); lc = new StructProperty("Color", pc, "LightColor", true); } RStructs.RandomizeColor(lc, false); export.WriteProperty(lc); return(true); }
public static void SetLocation(ExportEntry export, CFVector3 location) { StructProperty prop = export.GetProperty <StructProperty>("location"); SetLocation(prop, location); export.WriteProperty(prop); }
public static Point3D GetLocation(ExportEntry export) { float x = 0, y = 0, z = int.MinValue; var prop = export.GetProperty <StructProperty>("location"); if (prop != null) { foreach (var locprop in prop.Properties) { switch (locprop) { case FloatProperty fltProp when fltProp.Name == "X": x = fltProp; break; case FloatProperty fltProp when fltProp.Name == "Y": y = fltProp; break; case FloatProperty fltProp when fltProp.Name == "Z": z = fltProp; break; } } return(new Point3D(x, y, z)); } return(null); }
public static bool RandomizeExport(ExportEntry export, RandomizationOption option) { if (!CanRandomize(export)) { return(false); } var settings = export.GetProperty <StructProperty>("Settings"); if (settings != null) { MERLog.Information($@"Randomizing PostProcessingVolume settings {export.UIndex}"); // randomize the options RProperty.RandBool(settings.Properties, "bEnableDOF", ThreadSafeRandom.Next(3) == 0); RProperty.RandBool(settings.Properties, "bEnableFilmic", ThreadSafeRandom.Next(3) == 0); RProperty.RandBool(settings.Properties, "bEnableBloom", ThreadSafeRandom.Next(3) == 0); RProperty.RandFloat(settings.Properties, "Bloom_Scale", 0, 0.4f, ThreadSafeRandom.Next(5) == 0); RProperty.RandFloat(settings.Properties, "DOF_BlurKernelSize", 0, 20f, ThreadSafeRandom.Next(5) == 0); RProperty.RandFloat(settings.Properties, "DOF_MaxNearBlurAmount", 0, 0.2f, ThreadSafeRandom.Next(5) == 0); RProperty.RandFloat(settings.Properties, "DOF_MaxFarBlurAmount", 0.1f, 0.5f, ThreadSafeRandom.Next(5) == 0); RProperty.RandFloat(settings.Properties, "DOF_InnerFocusRadius", 0, 2000f, ThreadSafeRandom.Next(5) == 0); RProperty.RandFloat(settings.Properties, "DOF_FocusDistance", 0, 400f, ThreadSafeRandom.Next(5) == 0); RProperty.RandFloat(settings.Properties, "Scene_Desaturation", 0, 0.5f, ThreadSafeRandom.Next(5) == 0); RProperty.RandFloat(settings.Properties, "Scene_InterpolationDuration", 0, 2f, ThreadSafeRandom.Next(5) == 0); RProperty.RandVector(settings.Properties, "Scene_Highlights", 0, 2, ThreadSafeRandom.Next(8) == 0); RProperty.RandVector(settings.Properties, "Scene_Midtones", 0, 6f, ThreadSafeRandom.Next(5) == 0); RProperty.RandVector(settings.Properties, "Scene_Shadows", 0, .4f, ThreadSafeRandom.Next(8) == 0); export.WriteProperty(settings); return(true); } return(false); }
/// <summary> /// ME2 SPECIFIC<para/> /// Repoint a WwiseStream to play the data from another, typically across banks. /// </summary> /// <param name="originalExport">The audio you want to play (e.g. this is the audio that will be 'installed')</param> /// <param name="targetAudioStream">The audio stream that you want to replace.</param> public static void RepointWwiseStream(ExportEntry originalExport, ExportEntry targetAudioStream) { var props = originalExport.GetProperties(); var bin = ObjectBinary.From <WwiseStream>(originalExport); var targetId = targetAudioStream.GetProperty <IntProperty>("Id"); props.AddOrReplaceProp(targetId); targetAudioStream.WritePropertiesAndBinary(props, bin); }
public static void GenerateNewNavGUID(ExportEntry export) { StructProperty guidProp = export.GetProperty <StructProperty>("NavGuid"); if (guidProp != null) { export.WriteProperty(CommonStructs.GuidProp(Guid.NewGuid(), "NavGuid")); } }
public StructProperty GetCollisionMeshProperty(IMEPackage pcc) { if (pcc.isUExport(BodySetup)) { ExportEntry rb_BodySetup = pcc.getUExport(BodySetup); return(rb_BodySetup.GetProperty <StructProperty>("AggGeom")); } return(null); }
private static bool CanRandomize(ExportEntry export, out string cutsceneName) { cutsceneName = null; if (!export.IsDefaultObject && export.ClassName == "SeqAct_Interp" && export.GetProperty <StrProperty>("ObjName") is { } strp&& strp.Value.StartsWith("ANIMCUTSCENE_")) { cutsceneName = strp; return(true); } return(false); }
//me3 pcc to augment must be a map, and must have at least one BioTriggerStream and LevelStreamingKismet static void AugmentMapToLoadLiveEditor(IMEPackage pcc) { const string stateName = "SS_LIVEEDITOR"; var mainSequence = pcc.Exports.First(exp => exp.ObjectName == "Main_Sequence" && exp.ClassName == "Sequence"); var bioWorldInfo = pcc.Exports.First(exp => exp.ClassName == "BioWorldInfo"); #region Sequencing var consoleEvent = SequenceObjectCreator.CreateSequenceObject(pcc, "SeqEvent_Console", MEGame.ME3); consoleEvent.WriteProperty(new NameProperty("LoadLiveEditor", "ConsoleEventName")); KismetHelper.AddObjectToSequence(consoleEvent, mainSequence); var setStreamingState = SequenceObjectCreator.CreateSequenceObject(pcc, "BioSeqAct_SetStreamingState", MEGame.ME3); setStreamingState.WriteProperty(new NameProperty(stateName, "StateName")); setStreamingState.WriteProperty(new BoolProperty(true, "NewValue")); KismetHelper.AddObjectToSequence(setStreamingState, mainSequence); KismetHelper.CreateOutputLink(consoleEvent, "Out", setStreamingState); var levelLoaded = SequenceObjectCreator.CreateSequenceObject(pcc, "SeqEvent_LevelLoaded", MEGame.ME3); KismetHelper.AddObjectToSequence(levelLoaded, mainSequence); var sendMessageToME3Exp = SequenceObjectCreator.CreateSequenceObject(pcc, "SeqAct_SendMessageToME3Explorer", MEGame.ME3); KismetHelper.AddObjectToSequence(sendMessageToME3Exp, mainSequence); KismetHelper.CreateOutputLink(levelLoaded, "Loaded and Visible", sendMessageToME3Exp); var stringVar = SequenceObjectCreator.CreateSequenceObject(pcc, "SeqVar_String", MEGame.ME3); stringVar.WriteProperty(new StrProperty(LoaderLoadedMessage, "StrValue")); KismetHelper.AddObjectToSequence(stringVar, mainSequence); KismetHelper.CreateVariableLink(sendMessageToME3Exp, "MessageName", stringVar); #endregion ExportEntry lsk = EntryCloner.CloneEntry(pcc.Exports.First(exp => exp.ClassName == "LevelStreamingKismet")); lsk.WriteProperty(new NameProperty(liveEditorFileName, "PackageName")); var streamingLevels = bioWorldInfo.GetProperty <ArrayProperty <ObjectProperty> >("StreamingLevels"); streamingLevels.Add(new ObjectProperty(lsk)); bioWorldInfo.WriteProperty(streamingLevels); ExportEntry bts = EntryCloner.CloneTree(pcc.Exports.First(exp => exp.ClassName == "BioTriggerStream")); var streamingStates = bts.GetProperty <ArrayProperty <StructProperty> >("StreamingStates"); while (streamingStates.Count > 1) { streamingStates.RemoveAt(streamingStates.Count - 1); } streamingStates.Add(new StructProperty("BioStreamingState", new PropertyCollection { new NameProperty(stateName, "StateName"), new ArrayProperty <NameProperty>("VisibleChunkNames") { new NameProperty(liveEditorFileName) } })); bts.WriteProperty(streamingStates); pcc.AddToLevelActorsIfNotThere(bts); }
private static void SetBaseColorInterpGroup(ExportEntry yellowToGreen, Vector3 color1, Vector3 color2) { var tracks = yellowToGreen.GetProperty <ArrayProperty <ObjectProperty> >("InterpTracks"); foreach (var t in tracks) { var itvmp = t.ResolveToEntry(yellowToGreen.FileRef) as ExportEntry; var ittProps = itvmp.GetProperties(); var parmName = ittProps.GetProp <NameProperty>("ParamName").Value.Name; var vStartPoint = ittProps.GetProp <StructProperty>("VectorTrack").GetProp <ArrayProperty <StructProperty> >("Points")[0]; var vEndPoint = ittProps.GetProp <StructProperty>("VectorTrack").GetProp <ArrayProperty <StructProperty> >("Points")[1]; Vector3 color1Used = color1; Vector3 color2Used = color2; switch (parmName) { case "Reflection_Color": color1Used = BoostColor(color1, .1f); color2Used = BoostColor(color2, 0.1f); break; case "Wire_Color": color1Used = BoostColor(color1, .2f); color2Used = BoostColor(color2, .2f); break; case "FloorTileColor": color1Used = BoostColor(color1, -.1f); color2Used = BoostColor(color2, -.1f); break; case "WireColor": color1Used = BoostColor(color1, .15f); color2Used = BoostColor(color2, .15f); break; case "MainColor": color1Used = BoostColor(color1, 0); color2Used = BoostColor(color2, 0); break; case "GlowColor": color1Used = BoostColor(color1, -.2f); color2Used = BoostColor(color2, -.2f); break; } vStartPoint.Properties.AddOrReplaceProp(color1Used.ToVectorStructProperty("OutVal")); vEndPoint.Properties.AddOrReplaceProp(color2Used.ToVectorStructProperty("OutVal")); itvmp.WriteProperties(ittProps); } }
/// <summary> /// Gets the containing sequence of the specified export. Performed by looking for ParentSequence object property. Pass true to continue up the chain. /// </summary> /// <param name="export"></param> /// <returns></returns> public static ExportEntry GetParentSequence(ExportEntry export, bool lookup = false) { var result = export?.GetProperty <ObjectProperty>("ParentSequence")?.ResolveToEntry(export.FileRef) as ExportEntry; while (lookup && result != null && result.ClassName != "Sequence") { result = result.GetProperty <ObjectProperty>("ParentSequence")?.ResolveToEntry(export.FileRef) as ExportEntry; } return(result); }
public InterpTrackDirector(ExportEntry export) : base(export) { var trackKeys = export.GetProperty <ArrayProperty <StructProperty> >("CutTrack"); if (trackKeys != null) { foreach (var trackKey in trackKeys) { Keys.Add(new Key(trackKey.GetProp <FloatProperty>("Time"))); } } }
public InterpTrackAnimControl(ExportEntry export) : base(export) { var trackKeys = export.GetProperty <ArrayProperty <StructProperty> >("AnimSeqs"); if (trackKeys != null) { foreach (var trackKey in trackKeys) { Keys.Add(new Key(trackKey.GetProp <FloatProperty>("StartTime"))); } } }
public static BioParticleModuleSound Parse(ExportEntry export) { var wwiseEvent = export.GetProperty <ObjectProperty>("oWwiseEvent")?.Value; var wwiseEventObj = (IEntry)null; export.FileRef.TryGetEntry(wwiseEvent ?? 0, out wwiseEventObj); return(new BioParticleModuleSound() { Export = export, WwiseEventEntry = wwiseEventObj }); }
public InterpTrackVectorBase(ExportEntry export) : base(export) { var vectorTrackProp = export.GetProperty <StructProperty>("VectorTrack"); if (vectorTrackProp != null) { foreach (var curvePoint in vectorTrackProp.GetPropOrDefault <ArrayProperty <StructProperty> >("Points")) { Keys.Add(new Key(curvePoint.GetProp <FloatProperty>("InVal"))); } } }
private static void InstallDynamicAnimSetRefForSkeletalMesh(ExportEntry export, RBioEvtSysTrackGesture.Gesture gesture) { // We have parent sequence data var skmDynamicAnimSets = export.GetProperty <ArrayProperty <ObjectProperty> >("AnimSets") ?? new ArrayProperty <ObjectProperty>("AnimSets"); // Check to see if there is any item that uses our bioanimset var bioAnimSet = gesture.GetBioAnimSet(export.FileRef); if (bioAnimSet != null) { ExportEntry skmBioDynamicAnimSet = null; foreach (var skmDynAnimSet in skmDynamicAnimSets) { var kEntry = skmDynAnimSet.ResolveToEntry(export.FileRef) as ExportEntry; // I don't think these can be imports as they're part of the seq var associatedset = kEntry.GetProperty <ObjectProperty>("m_pBioAnimSetData").ResolveToEntry(export.FileRef); if (associatedset == bioAnimSet) { // It's this one skmBioDynamicAnimSet = kEntry; break; } } if (skmBioDynamicAnimSet == null) { // We need to generate a new one PropertyCollection props = new PropertyCollection(); props.Add(new NameProperty(gesture.GestureSet, "m_nmOrigSetName")); props.Add(new ArrayProperty <ObjectProperty>("Sequences")); props.Add(new ObjectProperty(bioAnimSet, "m_pBioAnimSetData")); skmBioDynamicAnimSet = ExportCreator.CreateExport(export.FileRef, $"BioDynamicAnimSet", "BioDynamicAnimSet", export); // Write a blank count of 0 - we will update this in subsequent call // This must be here to ensure parser can read it skmBioDynamicAnimSet.WritePropertiesAndBinary(props, new byte[4]); skmDynamicAnimSets.Add(new ObjectProperty(skmBioDynamicAnimSet)); // Add new export to sequence's list of biodynamicanimsets export.WriteProperty(skmDynamicAnimSets); } var currentObjs = skmBioDynamicAnimSet.GetProperty <ArrayProperty <ObjectProperty> >("Sequences"); if (currentObjs.All(x => x.Value != gesture.Entry.UIndex)) { // We need to add our item to it currentObjs.Add(new ObjectProperty(gesture.Entry)); var bin = ObjectBinary.From <BioDynamicAnimSet>(skmBioDynamicAnimSet); bin.SequenceNamesToUnkMap[gesture.GestureAnim] = 1; // Not sure what the value should be, or if game actually reads this // FIX IT IF WE EVER FIGURE IT OUT! skmBioDynamicAnimSet.WriteProperty(currentObjs); skmBioDynamicAnimSet.WriteBinary(bin); } } }
public BioInterpTrack(ExportEntry exp) : base(exp) { var trackKeys = exp.GetProperty <ArrayProperty <StructProperty> >("m_aTrackKeys"); if (trackKeys != null) { foreach (StructProperty bioTrackKey in trackKeys) { var fTime = bioTrackKey.GetProp <FloatProperty>("fTime"); Keys.Add(new Key(fTime)); } } }
/// <summary> /// Gets a list of all entries that are referenced by this sequence. If the passed in object is not a Sequence, the parent sequence is used. Returns null if there is no parent sequence. /// </summary> /// <param name="export"></param> /// <returns></returns> public static List <IEntry> GetAllSequenceElements(ExportEntry export) { if (export.ClassName == "Sequence") { var seqObjs = export.GetProperty <ArrayProperty <ObjectProperty> >("SequenceObjects"); if (seqObjs != null) { return(seqObjs.Where(x => export.FileRef.IsEntry(x.Value)).Select(x => x.ResolveToEntry(export.FileRef)).ToList()); } } else { // Pull from parent sequence. var pSeqObj = export.GetProperty <ObjectProperty>("ParentSequence"); if (pSeqObj != null && pSeqObj.ResolveToEntry(export.FileRef) is ExportEntry pSeq && pSeq.ClassName == "Sequence") { return(GetAllSequenceElements(pSeq)); } } return(null); }
/// <summary> /// Fetches the NavGuid object as a UnrealGUID /// </summary> /// <param name="export"></param> /// <returns></returns> public static UnrealGUID GetNavGUID(ExportEntry export) { StructProperty navGuid = export.GetProperty <StructProperty>("NavGuid"); if (navGuid != null) { return(new UnrealGUID(navGuid) { export = export }); } return(null); }