public static bool RandomizeExport(ExportEntry export, RandomizationOption option) { if (!CanRandomize(export)) { return(false); } var properties = export.GetProperties(); var lightColor = properties.GetProp <StructProperty>("LightColor"); if (lightColor != null) { lightColor.GetProp <ByteProperty>("R").Value = (byte)ThreadSafeRandom.Next(256); lightColor.GetProp <ByteProperty>("G").Value = (byte)ThreadSafeRandom.Next(256); lightColor.GetProp <ByteProperty>("B").Value = (byte)ThreadSafeRandom.Next(256); var density = properties.GetProp <FloatProperty>("Density"); if (density != null) { var thicknessRandomizer = ThreadSafeRandom.NextFloat(-density * .03, density * 1.15); density.Value = density + thicknessRandomizer; } //Debug.WriteLine($"Updating fog {export.InstancedFullPath} in {export.FileRef.FilePath}"); export.WriteProperties(properties); return(true); } return(false); }
public static void RemoveAllLinks(ExportEntry export) { var props = export.GetProperties(); var outLinksProp = props.GetProp <ArrayProperty <StructProperty> >("OutputLinks"); if (outLinksProp != null) { foreach (var prop in outLinksProp) { prop.GetProp <ArrayProperty <StructProperty> >("Links").Clear(); } } var varLinksProp = props.GetProp <ArrayProperty <StructProperty> >("VariableLinks"); if (varLinksProp != null) { foreach (var prop in varLinksProp) { prop.GetProp <ArrayProperty <ObjectProperty> >("LinkedVariables").Clear(); } } var eventLinksProp = props.GetProp <ArrayProperty <StructProperty> >("EventLinks"); if (eventLinksProp != null) { foreach (var prop in eventLinksProp) { prop.GetProp <ArrayProperty <ObjectProperty> >("LinkedEvents").Clear(); } } export.WriteProperties(props); }
public InterpTrack(ExportEntry export) { Export = export; var props = export.GetProperties(); TrackTitle = props.GetProp <StrProperty>("TrackTitle")?.Value; }
public AnimTree(ExportEntry export) { pcc = export.FileRef; Export = export; data = export.Data; PropertyCollection props = export.GetProperties(); NodeTotalWeight = props.GetPropOrDefault <FloatProperty>("NodeTotalWeight").Value; ComposePrePassBoneNames = props.GetPropOrDefault <ArrayProperty <NameProperty> >("ComposePrePassBoneNames").Select(n => n.Value.Instanced).ToList(); AnimGroups = props.GetPropOrDefault <ArrayProperty <StructProperty> >("AnimGroups").Select(prop => new AnimGroupEntry { GroupName = prop.GetPropOrDefault <NameProperty>("GroupName").Value.Instanced, RateScale = prop.GetPropOrDefault <FloatProperty>("RateScale").Value, SynchPctPosition = prop.GetPropOrDefault <FloatProperty>("SynchPctPosition").Value }).ToList(); SkelControlLists = props.GetPropOrDefault <ArrayProperty <StructProperty> >("SkelControlLists").Select(prop => new SkelControlListEntry { BoneName = prop.GetPropOrDefault <NameProperty>("BoneName").Value.Instanced, ControlHead = prop.GetPropOrDefault <ObjectProperty>("ControlHead").Value }).ToList(); Children = props.GetPropOrDefault <ArrayProperty <StructProperty> >("Children").Select(prop => new ChildrenEntry { Name = prop.GetPropOrDefault <NameProperty>("Name").Value.Instanced, Weight = prop.GetPropOrDefault <FloatProperty>("Weight").Value, Anim = prop.GetPropOrDefault <ObjectProperty>("Anim").Value, bIsAdditive = prop.GetPropOrDefault <BoolProperty>("bIsAdditive").Value, bMirrorSkeleton = prop.GetPropOrDefault <BoolProperty>("bMirrorSkeleton").Value }).ToList(); }
public static bool RandomizeExport(ExportEntry exp, RandomizationOption option) { if (!CanRandomize(exp)) { return(false); } var props = exp.GetProperties(); var navs = props.GetProp <ArrayProperty <StructProperty> >("NavList").Select(x => x.Properties.GetProp <ObjectProperty>("Nav")).ToList(); var destNavs = exp.FileRef.Exports.Where(x => x.IsA("NavigationPoint")).ToList(); destNavs.Shuffle(); foreach (var n in navs) { n.Value = destNavs[0].UIndex; destNavs.RemoveAt(0); } //foreach (var nav in navs) //{ // var entry = nav.ResolveToEntry(exp.FileRef) as ExportEntry; //} exp.WriteProperties(props); return(true); }
/// <summary> /// Installs the specified r2d to the specified export. Specify an asset name if you wish to use a specific asset in the RTexture2D object. /// </summary> /// <param name="r2d"></param> /// <param name="export"></param> /// <param name="asset"></param> public static void InstallTexture(RTexture2D r2d, ExportEntry export, string asset = null) { // If no asset was specified pick a random asset asset ??= r2d.FetchRandomTextureAsset(); // 2. Is this asset already parsed? if (r2d.InstantiatedItems.TryGetValue(asset, out var instantiated)) { // It's already been instantiated. Just use this data instead MERLog.Information($@"Writing out cached asset {asset} for {export.InstancedFullPath}"); export.WritePropertiesAndBinary(instantiated.props, instantiated.texData); } else { MERLog.Information($@"Installing texture asset {asset} for {export.InstancedFullPath}"); // 3. Asset has not been setup yet. Write out the precomputed data. export.WriteBinary(GetTextureAssetBinary(asset)); // 4. Read in the data so it's in the correct context. var ut2d = ObjectBinary.From <UTexture2D>(export); // 5. Move compressed mips to TFC foreach (var mip in ut2d.Mips) { if (mip.IsCompressed) { mip.DataOffset = TFCBuilder.WriteMip(r2d, mip.Mip); // If it's compressed it needs to be stored externally. if (mip.StorageType == StorageTypes.pccLZO) { mip.StorageType = StorageTypes.extLZO; } if (mip.StorageType == StorageTypes.pccZlib) { mip.StorageType = StorageTypes.extZlib; } } } // 6. Setup the properties var props = export.GetProperties(); props.AddOrReplaceProp(new IntProperty(ut2d.Mips.Count - 1, @"MipTailBaseIdx")); props.AddOrReplaceProp(new IntProperty(ut2d.Mips[0].SizeX, @"SizeX")); props.AddOrReplaceProp(new IntProperty(ut2d.Mips[0].SizeY, @"SizeY")); props.AddOrReplaceProp(r2d.PreMountTexture ? ActiveBuilder.BGTFCNameProp : ActiveBuilder.DLCTFCNameProp); props.AddOrReplaceProp(r2d.PreMountTexture ? ActiveBuilder.BGTFCGuidProp : ActiveBuilder.DLCTFCGuidProp); if (r2d.LODGroup != null) { // Write a new LOD property props.AddOrReplaceProp(r2d.LODGroup); } // 7. Commit the export export.WritePropertiesAndBinary(props, ut2d); // 8. Cache the work that's been done so we don't need to it again. r2d.InstantiatedItems[asset] = (props, ut2d); } }
public static bool PerformRandomization(ExportEntry export, RandomizationOption option) { if (!CanRandomize(export)) { return(false); } MERLog.Information($"{export.FileRef.FilePath}\t{export.FullPath}"); var props = export.GetProperties(); if (export.ClassName == "BioSunFlareComponent" || export.ClassName == "BioSunFlareStreakComponent") { var tint = props.GetProp <StructProperty>("FlareTint"); if (tint != null) { RStructs.RandomizeTint(tint, false); } RProperty.RandFloat(props, "Intensity", 0.0001f, 100f, false); RProperty.RandFloat(props, "BrightPercent", 0.0001f, 0.1f, false); RProperty.RandFloat(props, "Scale", 0.05f, 3f, false); } else if (export.ClassName == "BioSunActor") { var tint = props.GetProp <StructProperty>("SunTint"); if (tint != null) { RStructs.RandomizeTint(tint, false); } } export.WriteProperties(props); return(true); }
/// <summary> /// Builds a map of position => allowable values (as a string) /// </summary> /// <param name="frontEndData"></param> /// <returns></returns> private static Dictionary <int, char[]> CalculateCodeMap(ExportEntry frontEndData) { Dictionary <int, char[]> map = new(); var props = frontEndData.GetProperties(); var categories = props.GetProp <ArrayProperty <StructProperty> >("MorphCategories"); int position = 0; foreach (var category in categories) { foreach (var slider in category.GetProp <ArrayProperty <StructProperty> >("m_aoSliders")) { if (!slider.GetProp <BoolProperty>("m_bNotched")) { map[position] = unnotchedSliderCodeChars.ToCharArray(); } else { // It's notched map[position] = unnotchedSliderCodeChars.Substring(0, slider.GetProp <IntProperty>("m_iSteps")).ToCharArray(); } position++; } } return(map); }
/// <summary> /// Changes a single output link to a new target and commits the properties. /// </summary> /// <param name="export">Export to operate on</param> /// <param name="outputLinkIndex">The index of the item in 'OutputLinks'</param> /// <param name="linksIndex">The index of the item in the Links array</param> /// <param name="newTarget">The UIndex of the new target</param> public static void ChangeOutlink(ExportEntry export, int outputLinkIndex, int linksIndex, int newTarget) { var props = export.GetProperties(); ChangeOutlink(props, outputLinkIndex, linksIndex, newTarget); export.WriteProperties(props); }
/// <summary> /// Sets the reach spec size and commits the results back to the export /// </summary> /// <param name="spec"></param> /// <param name="radius"></param> /// <param name="height"></param> public static void SetReachSpecSize(ExportEntry spec, int radius, int height) { PropertyCollection specProperties = spec.GetProperties(); SetReachSpecSize(specProperties, radius, height); spec.WriteProperties(specProperties); //write it back. }
public void Deserialize(IMEPackage pcc) { PropertyCollection properties = export.GetProperties(); int off; switch (pcc.Game) { case MEGame.ME3: off = export.propsEnd() + 8; break; case MEGame.ME2: off = export.propsEnd() + 0x28; break; default: throw new Exception("Can oly read WwiseStreams for ME3 and ME2!"); } ValueOffset = off; DataSize = BitConverter.ToInt32(memory, off); DataOffset = BitConverter.ToInt32(memory, off + 4); NameProperty nameProp = properties.GetProp <NameProperty>("Filename"); FileName = nameProp?.Value; Id = properties.GetProp <IntProperty>("Id"); }
/// <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 uint GetTextureCRC(ExportEntry export) { PropertyCollection properties = export.GetProperties(); var format = properties.GetProp <EnumProperty>("Format"); var cache = properties.GetProp <NameProperty>("TextureFileCacheName"); List <Texture2DMipInfo> mips = Texture2D.GetTexture2DMipInfos(export, cache != null ? cache.Value : null); var topmip = mips.FirstOrDefault(x => x.storageType != StorageTypes.empty); return(Texture2D.GetMipCRC(topmip, format.Value)); }
public static Gesture GetDefaultPose(ExportEntry export) { var props = export.GetProperties(); return(new Gesture() { GestureAnim = props.GetProp <NameProperty>("nmStartingPoseSet").Value, GestureSet = props.GetProp <NameProperty>("nmStartingPoseSet").Value, }); }
public static BioParticleModuleColorOverLife Parse(ExportEntry export) { var props = export.GetProperties(); var bpmcol = new BioParticleModuleColorOverLife(); bpmcol.Export = export; bpmcol.ColorOverLife = DistributionVector.FromStruct(props.GetProp <StructProperty>("ColorOverLife")); bpmcol.AlphaOverLife = DistributionFloat.FromStruct(props.GetProp <StructProperty>("AlphaOverLife")); return(bpmcol); }
public BioAnimSetData(ExportEntry export) { pcc = export.FileRef; Export = export; data = export.Data; PropertyCollection props = export.GetProperties(); bAnimRotationOnly = props.GetPropOrDefault <BoolProperty>("bAnimRotationOnly").Value; TrackBoneNames = props.GetPropOrDefault <ArrayProperty <NameProperty> >("TrackBoneNames").Select(n => n.Value.Instanced).ToList(); UseTranslationBoneNames = props.GetPropOrDefault <ArrayProperty <NameProperty> >("UseTranslationBoneNames").Select(n => n.Value.Instanced).ToList(); }
public static void WriteDefaultPose(ExportEntry export, Gesture newPose) { var props = export.GetProperties(); props.AddOrReplaceProp(new NameProperty(newPose.GestureSet, "nmStartingPoseSet")); props.AddOrReplaceProp(new NameProperty(newPose.GestureAnim, "nmStartingPoseAnim")); export.WriteProperties(props); ExportEntry owningSeq = null; InstallDynamicAnimSetRefForSeq(ref owningSeq, export, newPose); }
public InterpGroup(ExportEntry export) { Export = export; var props = export.GetProperties(); GroupName = props.GetProp <NameProperty>("GroupName")?.Value; var tracks = props.GetProp <ArrayProperty <ObjectProperty> >("InterpTracks"); if (tracks != null) { Tracks.AddRange(tracks.Select(x => new InterpTrack(x.ResolveToEntry(export.FileRef) as ExportEntry))); } }
public InterpData(ExportEntry export) { Export = export; var props = export.GetProperties(); InterpLength = props.GetProp <FloatProperty>("InterpLength"); var groups = props.GetProp <ArrayProperty <ObjectProperty> >("InterpGroups"); if (groups != null) { InterpGroups.AddRange(groups.Select(x => new InterpGroup(x.ResolveToEntry(export.FileRef) as ExportEntry))); } }
public static bool RandomizeExport(ExportEntry material, RandomizationOption option) { if (!CanRandomize(material)) { return(false); } var props = material.GetProperties(); { var vectors = props.GetProp <ArrayProperty <StructProperty> >("VectorParameterValues"); if (vectors != null) { foreach (var vector in vectors) { var pc = vector.GetProp <StructProperty>("ParameterValue"); if (pc != null) { RStructs.RandomizeTint(pc, false); } } } var scalars = props.GetProp <ArrayProperty <StructProperty> >("ScalarParameterValues"); if (scalars != null) { for (int i = 0; i < scalars.Count; i++) { var scalar = scalars[i]; var parameter = scalar.GetProp <NameProperty>("ParameterName"); var currentValue = scalar.GetProp <FloatProperty>("ParameterValue"); if (currentValue > 1) { scalar.GetProp <FloatProperty>("ParameterValue").Value = ThreadSafeRandom.NextFloat(0, currentValue * 1.3); } else { //Debug.WriteLine("Randomizing parameter " + scalar.GetProp<NameProperty>("ParameterName")); scalar.GetProp <FloatProperty>("ParameterValue").Value = ThreadSafeRandom.NextFloat(0, 1); } } //foreach (var scalar in vectors) //{ // var paramValue = vector.GetProp<StructProperty>("ParameterValue"); // RandomizeTint( paramValue, false); //} } } material.WriteProperties(props); return(true); }
private static void SlightlyRandomizeMovementData(ExportEntry export) { var props = export.GetProperties(); foreach (var prop in props) { if (prop is FloatProperty fp) { // We try to make sure it weights more towards faster not slower fp.Value = ThreadSafeRandom.NextFloat(fp.Value - (fp * .35), fp.Value + (fp * .75)); } } export.WriteProperties(props); }
public override bool CanParse(ExportEntry exportEntry) { var props = exportEntry.GetProperties(); foreach (var prop in props) { if (prop is StructProperty structProp && Enum.TryParse(structProp.StructType, out CurveType _)) { return(true); } } return(false); }
public static bool RandomizeExport(ExportEntry export, RandomizationOption option) { if (!CanRandomize(export)) { return(false); } PropertyCollection props = export.GetProperties(); var colorOverrides = props.GetProp <ArrayProperty <StructProperty> >("m_aColorOverrides"); if (colorOverrides != null) { foreach (StructProperty colorParameter in colorOverrides) { //Debug.WriteLine("Randomizing Color Parameter"); RStructs.RandomizeTint(colorParameter.GetProp <StructProperty>("cValue"), false); } } var scalarOverrides = props.GetProp <ArrayProperty <StructProperty> >("m_aScalarOverrides"); if (scalarOverrides != null) { foreach (StructProperty scalarParameter in scalarOverrides) { var name = scalarParameter.GetProp <NameProperty>("nName"); if (name != null) { if (name.Value.Name.Contains("_Frek_") || name.Value.Name.StartsWith("HAIR") || name.Value.Name.StartsWith("HED_Scar")) { var currentValue = scalarParameter.GetProp <FloatProperty>("sValue"); if (currentValue != null) { //Debug.WriteLine("Randomizing FREK HAIR HEDSCAR"); if (currentValue > 1) { scalarParameter.GetProp <FloatProperty>("sValue").Value = ThreadSafeRandom.NextFloat(0, currentValue * 1.3); } else { scalarParameter.GetProp <FloatProperty>("sValue").Value = ThreadSafeRandom.NextFloat(0, 1); } } } } } } export.WriteProperties(props); return(true); }
public Texture2D(ExportEntry export) { Export = export; PropertyCollection properties = export.GetProperties(); TextureFormat = properties.GetProp <EnumProperty>("Format").Value.Name; var cache = properties.GetProp <NameProperty>("TextureFileCacheName"); NeverStream = properties.GetProp <BoolProperty>("NeverStream") ?? false; Mips = GetTexture2DMipInfos(export, cache?.Value); if (Export.Game != Mod.MEGame.ME1) { TextureGuid = new Guid(Export.Data.Skip(Export.Data.Length - 16).Take(16).ToArray()); } }
public static bool RandomizeNPCExport2(ExportEntry export, RandomizationOption randOption) { if (!CanRandomizeNPCExport2(export)) { return(false); } var props = export.GetProperties(); var isIconic = props.GetProp <BoolProperty>("bIconicAppearance"); if (isIconic != null && isIconic) { return(false); // Don't modify an iconic look as it has a bunch fo stuff in it that can totally break it like scalp seams. } Dictionary <string, CFVector4> vectorValues = new(); Dictionary <string, float> scalarValues = new(); if (export.IsA("BioPawn")) { ChangeColorsInSubObjects(export, vectorValues, scalarValues, props); } else { // It's a SFXSkeletalMeshActorMAT, a basic type of NPC. var parms = VectorParameter.GetVectorParameters(export); if (parms != null) { foreach (var parm in parms) { vectorValues[parm.ParameterName] = parm.ParameterValue; RStructs.RandomizeTint(parm.ParameterValue, false); } VectorParameter.WriteVectorParameters(export, parms, "VectorParameters"); // Get submaterials and write out their properties too ChangeColorsInSubObjects(export, vectorValues, scalarValues, props); } // Should we try to randomize things that don't have a skin tone...? if (export.ObjectFlags.Has(UnrealFlags.EObjectFlags.ArchetypeObject) && PackageTools.IsLevelSubfile(Path.GetFileName(export.FileRef.FilePath))) { export.indexValue = ThreadSafeRandom.Next(); } } return(true); }
public AnimSet(ExportEntry export) { pcc = export.FileRef; Export = export; data = export.Data; PropertyCollection props = export.GetProperties(); m_pBioAnimSetData = props.GetPropOrDefault <ObjectProperty>("m_pBioAnimSetData").Value; if (pcc.IsUExport(m_pBioAnimSetData)) { SetData = new BioAnimSetData(pcc.GetUExport(m_pBioAnimSetData)); } PreviewSkelMeshName = props.GetPropOrDefault <NameProperty>("PreviewSkelMeshName").Value.Instanced; Sequences = props.GetPropOrDefault <ArrayProperty <ObjectProperty> >("Sequences").Select(prop => prop.Value).ToList(); }
internal static ExportEntry GetReachSpecEndExport(ExportEntry reachSpec, PropertyCollection props = null) { if (props == null) { props = reachSpec.GetProperties(); } if (props.GetProp <StructProperty>("End") is StructProperty endProperty && endProperty.GetProp <ObjectProperty>(SharedPathfinding.GetReachSpecEndName(reachSpec)) is ObjectProperty otherNodeValue && reachSpec.FileRef.isUExport(otherNodeValue.Value)) { return(reachSpec.FileRef.getUExport(otherNodeValue.Value)); } return(null); //can't get end, or is external }
public static BioParticleSpriteEmitter Parse(ExportEntry export) { BioParticleSpriteEmitter bpse = new BioParticleSpriteEmitter() { Export = export }; var props = export.GetProperties(); bpse.SpawnRate = DistributionFloat.FromStruct(props.GetProp <StructProperty>("SpawnRate")); bpse.EmitterName = props.GetProp <NameProperty>("EmitterName")?.Value; var lods = props.GetProp <ArrayProperty <ObjectProperty> >("LODLevels").Select(x => BioParticleLODLevel.Parse(x.ResolveToEntry(export.FileRef) as ExportEntry)); bpse.LODLevels = new ObservableCollectionExtended <BioParticleLODLevel>(lods); return(bpse); }
public static bool RandomizeExport(ExportEntry export, RandomizationOption option) { if (!CanRandomize(export)) { return(false); } var props = export.GetProperties(); if (export.ObjectName.Name.Contains("SFXPower")) { props.AddOrReplaceProp(new BoolProperty(true, "bCustomDroneColor")); props.AddOrReplaceProp(new BoolProperty(true, "bCustomDroneColor2")); } else { //sfxpawn props.AddOrReplaceProp(new BoolProperty(true, "bCustomColor")); props.AddOrReplaceProp(new BoolProperty(true, "bCustomColor2")); } PropertyCollection randColors = new PropertyCollection(); randColors.AddOrReplaceProp(new FloatProperty(ThreadSafeRandom.NextFloat(0, 60), "X")); randColors.AddOrReplaceProp(new FloatProperty(ThreadSafeRandom.NextFloat(0, 60), "Y")); randColors.AddOrReplaceProp(new FloatProperty(ThreadSafeRandom.NextFloat(0, 60), "Z")); PropertyCollection randColors2 = new PropertyCollection(); randColors2.AddOrReplaceProp(new FloatProperty(ThreadSafeRandom.NextFloat(0, 128), "X")); randColors2.AddOrReplaceProp(new FloatProperty(ThreadSafeRandom.NextFloat(0, 128), "Y")); randColors2.AddOrReplaceProp(new FloatProperty(ThreadSafeRandom.NextFloat(0, 128), "Z")); if (export.ObjectName.Name.Contains("SFXPower")) { props.AddOrReplaceProp(new StructProperty("Vector", randColors, "CustomDroneColor", true)); props.AddOrReplaceProp(new StructProperty("Vector", randColors2, "CustomDroneColor2", true)); } else { //sfxpawn props.AddOrReplaceProp(new StructProperty("Vector", randColors, "DroneColor", true)); props.AddOrReplaceProp(new StructProperty("Vector", randColors2, "DroneColor2", true)); } export.WriteProperties(props); return(true); }
/// <summary> /// Constructs musicstreaminfo from a WwiseStream export /// </summary> /// <param name="export"></param> /// <param name="files"></param> public MusicStreamInfo(ExportEntry export, List <string> loadedFiles) { StreamFullPath = export.InstancedFullPath; if (export.ObjectName.Name.Contains("silence") || !export.ObjectName.Name.StartsWith("mus_") || export.ObjectName.Name.Contains("gui")) { IsUsable = false; return; } var bin = ObjectBinary.From <WwiseStream>(export); if (bin.IsPCCStored) { IsUsable = false; return; // We aren't going to support this } // Props var props = export.GetProperties(); Filename = props.GetProp <NameProperty>("Filename").Value; BankName = props.GetProp <NameProperty>("BankName").Value; // Bin DataOffset = bin.DataOffset; DataSize = bin.DataSize; UnkGuid = bin.UnkGuid; // Get the duration var fname = Filename + ".afc"; var afcFile = loadedFiles.FirstOrDefault(x => Path.GetFileName(x).Equals(fname, StringComparison.InvariantCultureIgnoreCase)); if (afcFile != null) { var ai = GetAudioInfo(afcFile); var len = ai.GetLength(); DurationMs = (float)len.TotalMilliseconds; } else { Debug.WriteLine($"Could not find AFC file {Filename}!"); IsUsable = false; } }