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); }
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); }
/// <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 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 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> /// 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); }
public void SaveChanges() { Export.WriteProperties(Props); MemoryStream m = new MemoryStream(); m.WriteInt32(CompressedBlob.Length); m.WriteFromBuffer(CompressedBlob); Export.setBinaryData(m.ToArray()); }
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 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 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 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); }
public static void AddObjectToSequence(ExportEntry newObject, ExportEntry sequenceExport, bool removeLinks = false) { ArrayProperty <ObjectProperty> seqObjs = sequenceExport.GetProperty <ArrayProperty <ObjectProperty> >("SequenceObjects") ?? new ArrayProperty <ObjectProperty>("SequenceObjects"); seqObjs.Add(new ObjectProperty(newObject)); sequenceExport.WriteProperty(seqObjs); PropertyCollection newObjectProps = newObject.GetProperties(); newObjectProps.AddOrReplaceProp(new ObjectProperty(sequenceExport, "ParentSequence")); newObject.WriteProperties(newObjectProps); if (removeLinks) { RemoveAllLinks(newObject); } newObject.Parent = sequenceExport; }
public static bool RandomizeExport(ExportEntry exp, RandomizationOption option) { if (!CanRandomize(exp)) { return(false); } MERLog.Information($"Randomizing illusive eye color in {exp.FileRef.FilePath}"); var props = exp.GetProperties(); //eye color var emisVector = props.GetProp <ArrayProperty <StructProperty> >("VectorParameterValues").First(x => x.GetProp <NameProperty>("ParameterName").Value.Name == "Emis_Color").GetProp <StructProperty>("ParameterValue"); //tint is float based RStructs.RandomizeTint(emisVector, false); var emisScalar = props.GetProp <ArrayProperty <StructProperty> >("ScalarParameterValues").First(x => x.GetProp <NameProperty>("ParameterName").Value.Name == "Emis_Scalar").GetProp <FloatProperty>("ParameterValue"); emisScalar.Value = 3; //very vibrant exp.WriteProperties(props); return(true); }
/// <summary> /// Randomizes the export. Does not check CanRandomize() /// </summary> /// <param name="export"></param> /// <param name="option"></param> private static void RandomizeInternal(ExportEntry export, RandomizationOption option) { var props = export.GetProperties(); ArrayProperty <StructProperty> m_aMorphFeatures = props.GetProp <ArrayProperty <StructProperty> >("m_aMorphFeatures"); if (m_aMorphFeatures != null) { foreach (StructProperty morphFeature in m_aMorphFeatures) { FloatProperty offset = morphFeature.GetProp <FloatProperty>("Offset"); if (offset != null) { //Debug.WriteLine("Randomizing morph face " + Path.GetFilePath(export.FileRef.FilePath) + " " + export.UIndex + " " + export.FullPath + " offset"); offset.Value = offset.Value * ThreadSafeRandom.NextFloat(1 - (option.SliderValue / 3), 1 + (option.SliderValue / 3)); } } } ArrayProperty <StructProperty> m_aFinalSkeleton = props.GetProp <ArrayProperty <StructProperty> >("m_aFinalSkeleton"); if (m_aFinalSkeleton != null) { foreach (StructProperty offsetBonePos in m_aFinalSkeleton) { StructProperty vPos = offsetBonePos.GetProp <StructProperty>("vPos"); if (vPos != null) { //Debug.WriteLine("Randomizing morph face " + Path.GetFilePath(export.FileRef.FilePath) + " " + export.UIndex + " " + export.FullPath + " vPos"); FloatProperty x = vPos.GetProp <FloatProperty>("X"); FloatProperty y = vPos.GetProp <FloatProperty>("Y"); FloatProperty z = vPos.GetProp <FloatProperty>("Z"); x.Value = x.Value * ThreadSafeRandom.NextFloat(1 - option.SliderValue, 1 + option.SliderValue); y.Value = y.Value * ThreadSafeRandom.NextFloat(1 - option.SliderValue, 1 + option.SliderValue); z.Value = z.Value * ThreadSafeRandom.NextFloat(1 - (option.SliderValue / .85), 1 + (option.SliderValue / .85)); } } } export.WriteProperties(props); }
private static void randomizeFrontEnd(ExportEntry frontEnd) { var props = frontEnd.GetProperties(); //read categories var morphCategories = props.GetProp <ArrayProperty <StructProperty> >("MorphCategories"); var sliders = new Dictionary <string, StructProperty>(); foreach (var cat in morphCategories) { var catSliders = cat.GetProp <ArrayProperty <StructProperty> >("m_aoSliders"); foreach (var cSlider in catSliders) { var name = cSlider.GetProp <StrProperty>("m_sName"); sliders[name.Value] = cSlider; } } //Default Settings var defaultSettings = props.GetProp <ArrayProperty <StructProperty> >("m_aDefaultSettings"); foreach (var basehead in defaultSettings) { randomizeBaseHead(basehead, frontEnd, sliders); } //randomize base heads ? var baseHeads = props.GetProp <ArrayProperty <StructProperty> >("m_aBaseHeads"); foreach (var basehead in baseHeads) { randomizeBaseHead(basehead, frontEnd, sliders); } frontEnd.WriteProperties(props); }
public static void CreateCurveFromSavedCams(ExportEntry export) { POV[] cams = ReadSavedCamsFile(); var props = export.GetProperties(); var posTrack = props.GetProp <StructProperty>("PosTrack").GetProp <ArrayProperty <StructProperty> >("Points"); var rotTrack = props.GetProp <StructProperty>("EulerTrack").GetProp <ArrayProperty <StructProperty> >("Points"); var lookupTrack = props.GetProp <StructProperty>("LookupTrack").GetProp <ArrayProperty <StructProperty> >("Points"); posTrack.Clear(); rotTrack.Clear(); for (int i = 0; i < cams.Length; i++) { POV cam = cams[i]; if (cam.IsZero) { break; } posTrack.Add(new InterpCurvePoint <Vector3> { InVal = i * 2, OutVal = cam.Position, InterpMode = EInterpCurveMode.CIM_CurveUser }.ToStructProperty(MEGame.ME3)); rotTrack.Add(new InterpCurvePoint <Vector3> { InVal = i * 2, OutVal = cam.Rotation, InterpMode = EInterpCurveMode.CIM_CurveUser }.ToStructProperty(MEGame.ME3)); lookupTrack.Add(new StructProperty("InterpLookupPoint", false, new NameProperty("None", "GroupName"), new FloatProperty(0, "Time"))); } export.WriteProperties(props); }
public static List <string> Relink(ExportEntry sourceExport, ExportEntry relinkingExport, OrderedMultiValueDictionary <IEntry, IEntry> crossPCCObjectMappingList, bool importExportDependencies = false) { var relinkFailedReport = new List <string>(); IMEPackage sourcePcc = sourceExport.FileRef; //Relink stack if (relinkingExport.HasStack) { byte[] stack = relinkingExport.GetStack(); int uIndex = BitConverter.ToInt32(stack, 0); string relinkResult = relinkUIndex(sourceExport.FileRef, relinkingExport, ref uIndex, "Stack: Node", crossPCCObjectMappingList, "", importExportDependencies); if (relinkResult is null) { stack.OverwriteRange(0, BitConverter.GetBytes(uIndex)); } else { relinkFailedReport.Add(relinkResult); } uIndex = BitConverter.ToInt32(stack, 4); relinkResult = relinkUIndex(sourceExport.FileRef, relinkingExport, ref uIndex, "Stack: StateNode", crossPCCObjectMappingList, "", importExportDependencies); if (relinkResult is null) { stack.OverwriteRange(4, BitConverter.GetBytes(uIndex)); } else { relinkFailedReport.Add(relinkResult); } relinkingExport.SetStack(stack); } //Relink Properties PropertyCollection transplantProps = sourceExport.GetProperties(); relinkFailedReport.AddRange(relinkPropertiesRecursive(sourcePcc, relinkingExport, transplantProps, crossPCCObjectMappingList, "", importExportDependencies)); relinkingExport.WriteProperties(transplantProps); //Relink Binary try { if (relinkingExport.Game != sourcePcc.Game && (relinkingExport.IsClass || relinkingExport.ClassName == "State" || relinkingExport.ClassName == "Function")) { relinkFailedReport.Add($"{relinkingExport.UIndex} {relinkingExport.FullPath} binary relinking failed. Cannot port {relinkingExport.ClassName} between games!"); return(relinkFailedReport); } if (ObjectBinary.From(relinkingExport) is ObjectBinary objBin) { List <(UIndex, string)> indices = objBin.GetUIndexes(relinkingExport.FileRef.Game); foreach ((UIndex uIndex, string propName) in indices) { string result = relinkUIndex(sourcePcc, relinkingExport, ref uIndex.value, $"(Binary Property: {propName})", crossPCCObjectMappingList, "", importExportDependencies); if (result != null) { relinkFailedReport.Add(result); } } //UStruct is abstract baseclass for Class, State, and Function, and can have script in it if (objBin is UStruct uStructBinary && uStructBinary.ScriptBytes.Length > 0) { if (relinkingExport.Game == MEGame.ME3) { (List <Token> tokens, _) = Bytecode.ParseBytecode(uStructBinary.ScriptBytes, sourceExport); foreach (Token token in tokens) { relinkFailedReport.AddRange(RelinkToken(token, uStructBinary.ScriptBytes, sourceExport, relinkingExport, crossPCCObjectMappingList, importExportDependencies)); } } else { relinkFailedReport.Add($"{relinkingExport.UIndex} {relinkingExport.FullPath} binary relinking failed. {relinkingExport.ClassName} contains script, " + $"which cannot be relinked for {relinkingExport.Game}"); } } relinkingExport.setBinaryData(objBin.ToBytes(relinkingExport.FileRef, relinkingExport.DataOffset + relinkingExport.propsEnd())); return(relinkFailedReport); } byte[] binarydata = relinkingExport.getBinaryData(); if (binarydata.Length > 0) { switch (relinkingExport.ClassName) { //todo: make a WwiseEvent ObjectBinary class case "WwiseEvent": { void relinkAtPosition(int binaryPosition, string propertyName) { int uIndex = BitConverter.ToInt32(binarydata, binaryPosition); string relinkResult = relinkUIndex(sourcePcc, relinkingExport, ref uIndex, propertyName, crossPCCObjectMappingList, "", importExportDependencies); if (relinkResult is null) { binarydata.OverwriteRange(binaryPosition, BitConverter.GetBytes(uIndex)); } else { relinkFailedReport.Add(relinkResult); } } if (relinkingExport.FileRef.Game == MEGame.ME3) { int count = BitConverter.ToInt32(binarydata, 0); for (int j = 0; j < count; j++) { relinkAtPosition(4 + (j * 4), $"(Binary Property: WwiseStreams[{j}])"); } relinkingExport.setBinaryData(binarydata); } else if (relinkingExport.FileRef.Game == MEGame.ME2) { int parsingPos = 4; int linkCount = BitConverter.ToInt32(binarydata, parsingPos); parsingPos += 4; for (int j = 0; j < linkCount; j++) { int bankcount = BitConverter.ToInt32(binarydata, parsingPos); parsingPos += 4; for (int k = 0; k < bankcount; k++) { relinkAtPosition(parsingPos, $"(Binary Property: link[{j}].WwiseBanks[{k}])"); parsingPos += 4; } int wwisestreamcount = BitConverter.ToInt32(binarydata, parsingPos); parsingPos += 4; for (int k = 0; k < wwisestreamcount; k++) { relinkAtPosition(parsingPos, $"(Binary Property: link[{j}].WwiseStreams[{k}])"); parsingPos += 4; } } relinkingExport.setBinaryData(binarydata); } } break; case "DominantDirectionalLightComponent": case "SphericalHarmonicLightComponent": case "DominantPointLightComponent": case "StaticLightCollectionActor": case "DominantSpotLightComponent": case "DirectionalLightComponent": case "StaticMeshCollectionActor": case "TerrainWeightMapTexture": case "PhysicsAssetInstance": case "PointLightComponent": case "ShadowMapTexture2D": case "SpotLightComponent": case "LightMapTexture2D": case "SkyLightComponent": case "TextureFlipBook": case "BrushComponent": case "FaceFXAnimSet": case "TextureMovie": case "AnimSequence": case "RB_BodySetup": case "MorphTarget": case "ShadowMap1D": case "WwiseStream": case "WwiseBank": case "Texture2D": //these classes have binary but do not need relinking break; default: if (binarydata.Any(b => b != 0)) { relinkFailedReport.Add($"{relinkingExport.UIndex} {relinkingExport.FullPath} has unparsed binary. " + $"This binary may contain items that need to be relinked. Come to the Discord server " + $"(click ME3Tweaks logo in main window for invite) and ask devs to parse this class."); } break; } } } catch (Exception e) when(!App.IsDebug) { relinkFailedReport.Add($"{relinkingExport.UIndex} {relinkingExport.FullPath} binary relinking failed due to exception: {e.Message}"); } return(relinkFailedReport); }
public static bool RandomizeExport(ExportEntry export, RandomizationOption option) { if (!CanRandomize(export)) { return(false); } MERLog.Information($"[{Path.GetFileNameWithoutExtension(export.FileRef.FilePath)}] Randomizing movement interpolations for " + export.UIndex + ": " + export.InstancedFullPath); var props = export.GetProperties(); var posTrack = props.GetProp <StructProperty>("PosTrack"); if (posTrack != null) { var points = posTrack.GetProp <ArrayProperty <StructProperty> >("Points"); if (points != null) { foreach (StructProperty s in points) { var outVal = s.GetProp <StructProperty>("OutVal"); if (outVal != null) { FloatProperty x = outVal.GetProp <FloatProperty>("X"); FloatProperty y = outVal.GetProp <FloatProperty>("Y"); FloatProperty z = outVal.GetProp <FloatProperty>("Z"); x.Value = x.Value * ThreadSafeRandom.NextFloat(1 - option.SliderValue, 1 + option.SliderValue); y.Value = y.Value * ThreadSafeRandom.NextFloat(1 - option.SliderValue, 1 + option.SliderValue); z.Value = z.Value * ThreadSafeRandom.NextFloat(1 - option.SliderValue, 1 + option.SliderValue); } } } } var eulerTrack = props.GetProp <StructProperty>("EulerTrack"); if (eulerTrack != null) { var points = eulerTrack.GetProp <ArrayProperty <StructProperty> >("Points"); if (points != null) { foreach (StructProperty s in points) { var outVal = s.GetProp <StructProperty>("OutVal"); if (outVal != null) { FloatProperty x = outVal.GetProp <FloatProperty>("X"); FloatProperty y = outVal.GetProp <FloatProperty>("Y"); FloatProperty z = outVal.GetProp <FloatProperty>("Z"); if (x.Value != 0) { x.Value = x.Value * ThreadSafeRandom.NextFloat(1 - option.SliderValue, 1 + option.SliderValue); } else { x.Value = ThreadSafeRandom.NextFloat(0, ThreadSafeRandom.NextFloat(-1000 * option.SliderValue, 1000 * option.SliderValue)); } if (y.Value != 0) { y.Value = y.Value * ThreadSafeRandom.NextFloat(1 - option.SliderValue, 1 + option.SliderValue); } else { y.Value = ThreadSafeRandom.NextFloat(0, ThreadSafeRandom.NextFloat(-1000 * option.SliderValue, 1000 * option.SliderValue)); } if (z.Value != 0) { z.Value = z.Value * ThreadSafeRandom.NextFloat(1 - option.SliderValue, 1 + option.SliderValue); } else { z.Value = ThreadSafeRandom.NextFloat(0, ThreadSafeRandom.NextFloat(-1000 * option.SliderValue, 1000 * option.SliderValue)); } } } } } export.WriteProperties(props); return(true); }
public static void CreateReachSpec(ExportEntry startNode, bool createTwoWay, ExportEntry destinationNode, string reachSpecClass, ReachSpecSize size, PropertyCollection externalGUIDProperties = null) { IMEPackage Pcc = startNode.FileRef; ExportEntry reachSpectoClone = Pcc.Exports.FirstOrDefault(x => x.ClassName == "ReachSpec"); if (externalGUIDProperties != null) //EXTERNAL { //external node //Debug.WriteLine("Num Exports: " + pcc.Exports.Count); if (reachSpectoClone != null) { ExportEntry outgoingSpec = reachSpectoClone.Clone(); Pcc.addExport(outgoingSpec); IEntry reachSpecClassImp = GetEntryOrAddImport(Pcc, reachSpecClass); //new class type. outgoingSpec.idxClass = reachSpecClassImp.UIndex; outgoingSpec.idxObjectName = reachSpecClassImp.idxObjectName; var properties = outgoingSpec.GetProperties(); ObjectProperty outgoingSpecStartProp = properties.GetProp <ObjectProperty>("Start"); //START StructProperty outgoingEndStructProp = properties.GetProp <StructProperty>("End"); //Embeds END ObjectProperty outgoingSpecEndProp = outgoingEndStructProp.Properties.GetProp <ObjectProperty>(SharedPathfinding.GetReachSpecEndName(outgoingSpec)); //END outgoingSpecStartProp.Value = startNode.UIndex; outgoingSpecEndProp.Value = 0; var endGuid = outgoingEndStructProp.GetProp <StructProperty>("Guid"); endGuid.Properties = externalGUIDProperties; //set the other guid values to our guid values //Add to source node prop ArrayProperty <ObjectProperty> PathList = startNode.GetProperty <ArrayProperty <ObjectProperty> >("PathList"); PathList.Add(new ObjectProperty(outgoingSpec.UIndex)); startNode.WriteProperty(PathList); outgoingSpec.WriteProperties(properties); //Write Spec Size SharedPathfinding.SetReachSpecSize(outgoingSpec, size.SpecRadius, size.SpecHeight); //Reindex reachspecs. SharedPathfinding.ReindexMatchingObjects(outgoingSpec); } } else { //Debug.WriteLine("Source Node: " + startNode.Index); //Debug.WriteLine("Num Exports: " + pcc.Exports.Count); //int outgoingSpec = pcc.ExportCount; //int incomingSpec = pcc.ExportCount + 1; if (reachSpectoClone != null) { ExportEntry outgoingSpec = reachSpectoClone.Clone(); Pcc.addExport(outgoingSpec); ExportEntry incomingSpec = null; if (createTwoWay) { incomingSpec = reachSpectoClone.Clone(); Pcc.addExport(incomingSpec); } IEntry reachSpecClassImp = GetEntryOrAddImport(Pcc, reachSpecClass); //new class type. outgoingSpec.idxClass = reachSpecClassImp.UIndex; outgoingSpec.idxObjectName = reachSpecClassImp.idxObjectName; var outgoingSpecProperties = outgoingSpec.GetProperties(); if (reachSpecClass == "Engine.SlotToSlotReachSpec") { outgoingSpecProperties.Add(new ByteProperty(1, "SpecDirection")); //We might need to find a way to support this edit } //Debug.WriteLine("Outgoing UIndex: " + outgoingSpecExp.UIndex); ObjectProperty outgoingSpecStartProp = outgoingSpecProperties.GetProp <ObjectProperty>("Start"); //START StructProperty outgoingEndStructProp = outgoingSpecProperties.GetProp <StructProperty>("End"); //Embeds END ObjectProperty outgoingSpecEndProp = outgoingEndStructProp.Properties.GetProp <ObjectProperty>(SharedPathfinding.GetReachSpecEndName(outgoingSpec)); //END outgoingSpecStartProp.Value = startNode.UIndex; outgoingSpecEndProp.Value = destinationNode.UIndex; //Add to source node prop var PathList = startNode.GetProperty <ArrayProperty <ObjectProperty> >("PathList"); PathList.Add(new ObjectProperty(outgoingSpec.UIndex)); startNode.WriteProperty(PathList); //Write Spec Size SetReachSpecSize(outgoingSpecProperties, size.SpecRadius, size.SpecHeight); outgoingSpec.WriteProperties(outgoingSpecProperties); if (createTwoWay) { incomingSpec.idxClass = reachSpecClassImp.UIndex; incomingSpec.idxObjectName = reachSpecClassImp.idxObjectName; var incomingSpecProperties = incomingSpec.GetProperties(); if (reachSpecClass == "Engine.SlotToSlotReachSpec") { incomingSpecProperties.Add(new ByteProperty(2, "SpecDirection")); } ObjectProperty incomingSpecStartProp = incomingSpecProperties.GetProp <ObjectProperty>("Start"); //START StructProperty incomingEndStructProp = incomingSpecProperties.GetProp <StructProperty>("End"); //Embeds END ObjectProperty incomingSpecEndProp = incomingEndStructProp.Properties.GetProp <ObjectProperty>(SharedPathfinding.GetReachSpecEndName(incomingSpec)); //END incomingSpecStartProp.Value = destinationNode.UIndex; //Uindex incomingSpecEndProp.Value = startNode.UIndex; //Add reachspec to destination node's path list (returning) var DestPathList = destinationNode.GetProperty <ArrayProperty <ObjectProperty> >("PathList"); DestPathList.Add(new ObjectProperty(incomingSpec.UIndex)); destinationNode.WriteProperty(DestPathList); //destNode.WriteProperty(DestPathList); SetReachSpecSize(incomingSpecProperties, size.SpecRadius, size.SpecHeight); incomingSpec.WriteProperties(incomingSpecProperties); } //Reindex reachspecs. SharedPathfinding.ReindexMatchingObjects(outgoingSpec); } } }
public static string GenerateUDKFileForLevel(string udkPath, IMEPackage pcc) { #region AssetPackage string meshPackageName = $"{Path.GetFileNameWithoutExtension(pcc.FilePath)}Meshes"; string meshFile = Path.Combine(udkPath, @"UDKGame\Content\Shared\", $"{meshPackageName}.upk"); MEPackageHandler.CreateAndSavePackage(meshFile, MEGame.UDK); using IMEPackage meshPackage = MEPackageHandler.OpenUDKPackage(meshFile); meshPackage.getEntryOrAddImport("Core.Package"); IEntry defMat = meshPackage.getEntryOrAddImport("EngineMaterials.DefaultMaterial", "Material", "Engine"); var allMats = new HashSet <int>(); var relinkMap = new Dictionary <IEntry, IEntry>(); #region StaticMeshes List <ExportEntry> staticMeshes = pcc.Exports.Where(exp => exp.ClassName == "StaticMesh").ToList(); foreach (ExportEntry mesh in staticMeshes) { var mats = new Queue <int>(); StaticMesh stm = ObjectBinary.From <StaticMesh>(mesh); foreach (StaticMeshRenderData lodModel in stm.LODModels) { foreach (StaticMeshElement meshElement in lodModel.Elements) { mats.Enqueue(meshElement.Material); allMats.Add(meshElement.Material); meshElement.Material = 0; } } if (pcc.GetEntry(stm.BodySetup) is ExportEntry rbBodySetup) { rbBodySetup.RemoveProperty("PhysMaterial"); } mesh.WriteBinary(stm); IEntry newParent = EntryImporter.GetOrAddCrossImportOrPackage(mesh.ParentFullPath, pcc, meshPackage); EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.CloneTreeAsChild, mesh, meshPackage, newParent, false, out IEntry ent, relinkMap); ExportEntry portedMesh = (ExportEntry)ent; stm = ObjectBinary.From <StaticMesh>(portedMesh); foreach (StaticMeshRenderData lodModel in stm.LODModels) { foreach (StaticMeshElement meshElement in lodModel.Elements) { meshElement.Material = mats.Dequeue(); } } portedMesh.WriteBinary(stm); } #endregion #region Materials using (IMEPackage udkResources = MEPackageHandler.OpenMEPackageFromStream(Utilities.GetCustomAppResourceStream(MEGame.UDK))) { ExportEntry normDiffMat = udkResources.Exports.First(exp => exp.ObjectName == "NormDiffMat"); foreach (int matUIndex in allMats) { if (pcc.GetEntry(matUIndex) is ExportEntry matExp) { List <IEntry> textures = new MaterialInstanceConstant(matExp).Textures; ExportEntry diff = null; ExportEntry norm = null; foreach (IEntry texEntry in textures) { if (texEntry is ExportEntry texport) { if (texport.ObjectName.Name.ToLower().Contains("diff")) { diff = texport; } else if (texport.ObjectName.Name.ToLower().Contains("norm")) { norm = texport; } } } if (diff == null) { relinkMap[matExp] = defMat; continue; } else { EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.AddSingularAsChild, diff, meshPackage, null, false, out IEntry ent); diff = (ExportEntry)ent; diff.RemoveProperty("TextureFileCacheName"); diff.RemoveProperty("TFCFileGuid"); diff.RemoveProperty("LODGroup"); } if (norm != null) { EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.AddSingularAsChild, norm, meshPackage, null, false, out IEntry ent); norm = (ExportEntry)ent; norm.RemoveProperty("TextureFileCacheName"); norm.RemoveProperty("TFCFileGuid"); norm.RemoveProperty("LODGroup"); } EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.CloneTreeAsChild, normDiffMat, meshPackage, null, true, out IEntry matEnt); ExportEntry newMat = (ExportEntry)matEnt; newMat.ObjectName = matExp.ObjectName; Material matBin = ObjectBinary.From <Material>(newMat); matBin.SM3MaterialResource.UniformExpressionTextures = new UIndex[] { norm?.UIndex ?? 0, diff.UIndex }; newMat.WriteBinary(matBin); relinkMap[matExp] = newMat; if (newMat.GetProperty <ArrayProperty <ObjectProperty> >("Expressions") is {} expressionsProp&& expressionsProp.Count >= 2) { ExportEntry diffExpression = meshPackage.GetUExport(expressionsProp[0].Value); ExportEntry normExpression = meshPackage.GetUExport(expressionsProp[1].Value); diffExpression.WriteProperty(new ObjectProperty(diff.UIndex, "Texture")); normExpression.WriteProperty(new ObjectProperty(norm?.UIndex ?? 0, "Texture")); } } else if (pcc.GetEntry(matUIndex) is ImportEntry matImp) { relinkMap[matImp] = defMat; } } var relinkMapping = new OrderedMultiValueDictionary <IEntry, IEntry>(relinkMap); foreach (ExportEntry stmExport in staticMeshes) { if (relinkMap.TryGetValue(stmExport, out IEntry destEnt) && destEnt is ExportEntry destExp) { Relinker.Relink(stmExport, destExp, relinkMapping); } } } #endregion meshPackage.Save(); #endregion var staticMeshActors = new List <ExportEntry>(); var lightActors = new List <ExportEntry>(); string tempPackagePath = Path.Combine(App.ExecFolder, $"{Path.GetFileNameWithoutExtension(pcc.FilePath)}.udk"); File.Copy(Path.Combine(App.ExecFolder, "empty.udk"), tempPackagePath, true); using IMEPackage udkPackage = MEPackageHandler.OpenUDKPackage(tempPackagePath); { var topLevelMeshPackages = new List <IEntry>(); foreach (ExportEntry exportEntry in staticMeshes) { IEntry imp = udkPackage.getEntryOrAddImport($"{exportEntry.FullPath}", "StaticMesh", "Engine", exportEntry.ObjectName.Number); while (imp.Parent != null) { imp = imp.Parent; } if (!topLevelMeshPackages.Contains(imp)) { topLevelMeshPackages.Add(imp); } } ExportEntry levelExport = udkPackage.Exports.First(exp => exp.ClassName == "Level"); List <int> actorsInLevel = ObjectBinary.From <Level>(pcc.Exports.First(exp => exp.ClassName == "Level")).Actors.Select(u => u.value).ToList(); var componentToMatrixMap = new Dictionary <int, Matrix>(); foreach (int uIndex in actorsInLevel) { if (pcc.GetEntry(uIndex) is ExportEntry stcExp) { if (stcExp.ClassName == "StaticMeshCollectionActor") { StaticMeshCollectionActor stmc = ObjectBinary.From <StaticMeshCollectionActor>(stcExp); var components = stcExp.GetProperty <ArrayProperty <ObjectProperty> >("StaticMeshComponents"); for (int i = 0; i < components.Count; i++) { componentToMatrixMap[components[i].Value] = stmc.LocalToWorldTransforms[i]; } } else if (stcExp.ClassName == "StaticLightCollectionActor") { StaticLightCollectionActor stlc = ObjectBinary.From <StaticLightCollectionActor>(stcExp); var components = stcExp.GetProperty <ArrayProperty <ObjectProperty> >("LightComponents"); for (int i = 0; i < components.Count; i++) { componentToMatrixMap[components[i].Value] = stlc.LocalToWorldTransforms[i]; } } } } #region StaticMeshActors { var emptySMCBin = new StaticMeshComponent(); IEntry staticMeshActorClass = udkPackage.getEntryOrAddImport("Engine.StaticMeshActor"); udkPackage.getEntryOrAddImport("Engine.Default__StaticMeshActor", "StaticMeshActor", "Engine"); IEntry staticMeshComponentArchetype = udkPackage.getEntryOrAddImport("Engine.Default__StaticMeshActor.StaticMeshComponent0", "StaticMeshComponent", "Engine"); int smaIndex = 2; int smcIndex = 2; foreach (ExportEntry smc in pcc.Exports.Where(exp => exp.ClassName == "StaticMeshComponent")) { if (smc.Parent is ExportEntry parent && actorsInLevel.Contains(parent.UIndex) && parent.IsA("StaticMeshActorBase")) { StructProperty locationProp; StructProperty rotationProp; StructProperty scaleProp = null; smc.CondenseArchetypes(); if (!(smc.GetProperty <ObjectProperty>("StaticMesh") is { } meshProp) || !pcc.IsUExport(meshProp.Value)) { continue; } smc.WriteBinary(emptySMCBin); smc.RemoveProperty("bBioIsReceivingDecals"); smc.RemoveProperty("bBioForcePrecomputedShadows"); //smc.RemoveProperty("bUsePreComputedShadows"); smc.RemoveProperty("bAcceptsLights"); smc.RemoveProperty("IrrelevantLights"); smc.RemoveProperty("Materials"); //should make use of this? smc.ObjectName = new NameReference("StaticMeshComponent", smcIndex++); if (parent.ClassName == "StaticMeshCollectionActor") { if (!componentToMatrixMap.TryGetValue(smc.UIndex, out Matrix m)) { continue; } (Vector3 posVec, Vector3 scaleVec, Rotator rotator) = m.UnrealDecompose(); locationProp = CommonStructs.Vector3Prop(posVec, "Location"); rotationProp = CommonStructs.RotatorProp(rotator, "Rotation"); scaleProp = CommonStructs.Vector3Prop(scaleVec, "DrawScale3D"); //smc.WriteProperty(CommonStructs.Matrix(m, "CachedParentToWorld")); } else { locationProp = parent.GetProperty <StructProperty>("Location"); rotationProp = parent.GetProperty <StructProperty>("Rotation"); scaleProp = parent.GetProperty <StructProperty>("DrawScale3D"); if (parent.GetProperty <FloatProperty>("DrawScale")?.Value is float scale) { Vector3 scaleVec = Vector3.One; if (scaleProp != null) { scaleVec = CommonStructs.GetVector3(scaleProp); } scaleProp = CommonStructs.Vector3Prop(scaleVec * scale, "DrawScale3D"); } } ExportEntry sma = new ExportEntry(udkPackage, EntryImporter.CreateStack(MEGame.UDK, staticMeshActorClass.UIndex)) { ObjectName = new NameReference("StaticMeshActor", smaIndex++), Class = staticMeshActorClass, Parent = levelExport }; sma.ObjectFlags |= UnrealFlags.EObjectFlags.HasStack; udkPackage.AddExport(sma); EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.AddSingularAsChild, smc, udkPackage, sma, true, out IEntry result); var props = new PropertyCollection { new ObjectProperty(result.UIndex, "StaticMeshComponent"), new NameProperty(new NameReference(Path.GetFileNameWithoutExtension(smc.FileRef.FilePath), smc.UIndex), "Tag"), new ObjectProperty(result.UIndex, "CollisionComponent") }; if (locationProp != null) { props.Add(locationProp); } if (rotationProp != null) { props.Add(rotationProp); } if (scaleProp != null) { props.Add(scaleProp); } sma.WriteProperties(props); staticMeshActors.Add(sma); } } IEntry topMeshPackageImport = udkPackage.getEntryOrAddImport(meshPackageName, "Package"); foreach (IEntry mp in topLevelMeshPackages) { mp.Parent = topMeshPackageImport; } } #endregion #region LightActors { IEntry pointLightClass = udkPackage.getEntryOrAddImport("Engine.PointLight"); IEntry spotLightClass = udkPackage.getEntryOrAddImport("Engine.SpotLight"); IEntry directionalLightClass = udkPackage.getEntryOrAddImport("Engine.DirectionalLight"); int plaIndex = 1; int plcIndex = 1; int slaIndex = 1; int slcIndex = 1; int dlaIndex = 1; int dlcIndex = 1; foreach (ExportEntry lightComponent in pcc.Exports) { if (!(lightComponent.Parent is ExportEntry parent && actorsInLevel.Contains(parent.UIndex))) { continue; } StructProperty locationProp; StructProperty rotationProp; StructProperty scaleProp; switch (lightComponent.ClassName) { case "PointLightComponent": lightComponent.CondenseArchetypes(); lightComponent.ObjectName = new NameReference("PointLightComponent", plcIndex++); if (parent.ClassName == "StaticLightCollectionActor") { if (!componentToMatrixMap.TryGetValue(lightComponent.UIndex, out Matrix m)) { continue; } (Vector3 posVec, Vector3 scaleVec, Rotator rotator) = m.UnrealDecompose(); locationProp = CommonStructs.Vector3Prop(posVec, "Location"); rotationProp = CommonStructs.RotatorProp(rotator, "Rotation"); scaleProp = CommonStructs.Vector3Prop(scaleVec, "DrawScale3D"); } else { locationProp = parent.GetProperty <StructProperty>("Location"); rotationProp = parent.GetProperty <StructProperty>("Rotation"); scaleProp = parent.GetProperty <StructProperty>("DrawScale3D"); if (parent.GetProperty <FloatProperty>("DrawScale")?.Value is float scale) { Vector3 scaleVec = Vector3.One; if (scaleProp != null) { scaleVec = CommonStructs.GetVector3(scaleProp); } scaleProp = CommonStructs.Vector3Prop(scaleVec * scale, "DrawScale3D"); } } ExportEntry pla = new ExportEntry(udkPackage, EntryImporter.CreateStack(MEGame.UDK, pointLightClass.UIndex)) { ObjectName = new NameReference("PointLight", plaIndex++), Class = pointLightClass, Parent = levelExport }; pla.ObjectFlags |= UnrealFlags.EObjectFlags.HasStack; udkPackage.AddExport(pla); EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.AddSingularAsChild, lightComponent, udkPackage, pla, true, out IEntry portedPLC); var plsProps = new PropertyCollection { new ObjectProperty(portedPLC.UIndex, "LightComponent"), new NameProperty("PointLight", "Tag"), }; if (locationProp != null) { plsProps.Add(locationProp); } if (rotationProp != null) { plsProps.Add(rotationProp); } if (scaleProp != null) { plsProps.Add(scaleProp); } pla.WriteProperties(plsProps); lightActors.Add(pla); break; case "SpotLightComponent": lightComponent.CondenseArchetypes(); lightComponent.ObjectName = new NameReference("SpotLightComponent", slcIndex++); if (parent.ClassName == "StaticLightCollectionActor") { if (!componentToMatrixMap.TryGetValue(lightComponent.UIndex, out Matrix m)) { continue; } (Vector3 posVec, Vector3 scaleVec, Rotator rotator) = m.UnrealDecompose(); locationProp = CommonStructs.Vector3Prop(posVec, "Location"); rotationProp = CommonStructs.RotatorProp(rotator, "Rotation"); scaleProp = CommonStructs.Vector3Prop(scaleVec, "DrawScale3D"); } else { locationProp = parent.GetProperty <StructProperty>("Location"); rotationProp = parent.GetProperty <StructProperty>("Rotation"); scaleProp = parent.GetProperty <StructProperty>("DrawScale3D"); if (parent.GetProperty <FloatProperty>("DrawScale")?.Value is float scale) { Vector3 scaleVec = Vector3.One; if (scaleProp != null) { scaleVec = CommonStructs.GetVector3(scaleProp); } scaleProp = CommonStructs.Vector3Prop(scaleVec * scale, "DrawScale3D"); } } ExportEntry sla = new ExportEntry(udkPackage, EntryImporter.CreateStack(MEGame.UDK, spotLightClass.UIndex)) { ObjectName = new NameReference("SpotLight", slaIndex++), Class = spotLightClass, Parent = levelExport }; sla.ObjectFlags |= UnrealFlags.EObjectFlags.HasStack; udkPackage.AddExport(sla); EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.AddSingularAsChild, lightComponent, udkPackage, sla, true, out IEntry portedSLC); var slaProps = new PropertyCollection { new ObjectProperty(portedSLC.UIndex, "LightComponent"), new NameProperty("SpotLight", "Tag"), }; if (locationProp != null) { slaProps.Add(locationProp); } if (rotationProp != null) { slaProps.Add(rotationProp); } if (scaleProp != null) { slaProps.Add(scaleProp); } sla.WriteProperties(slaProps); lightActors.Add(sla); break; case "DirectionalLightComponent": lightComponent.CondenseArchetypes(); lightComponent.ObjectName = new NameReference("DirectionalLightComponent", dlcIndex++); if (parent.ClassName == "StaticLightCollectionActor") { if (!componentToMatrixMap.TryGetValue(lightComponent.UIndex, out Matrix m)) { continue; } (Vector3 posVec, Vector3 scaleVec, Rotator rotator) = m.UnrealDecompose(); locationProp = CommonStructs.Vector3Prop(posVec, "Location"); rotationProp = CommonStructs.RotatorProp(rotator, "Rotation"); scaleProp = CommonStructs.Vector3Prop(scaleVec, "DrawScale3D"); } else { locationProp = parent.GetProperty <StructProperty>("Location"); rotationProp = parent.GetProperty <StructProperty>("Rotation"); scaleProp = parent.GetProperty <StructProperty>("DrawScale3D"); if (parent.GetProperty <FloatProperty>("DrawScale")?.Value is float scale) { Vector3 scaleVec = Vector3.One; if (scaleProp != null) { scaleVec = CommonStructs.GetVector3(scaleProp); } scaleProp = CommonStructs.Vector3Prop(scaleVec * scale, "DrawScale3D"); } } ExportEntry dla = new ExportEntry(udkPackage, EntryImporter.CreateStack(MEGame.UDK, directionalLightClass.UIndex)) { ObjectName = new NameReference("DirectionalLight", dlaIndex++), Class = directionalLightClass, Parent = levelExport }; dla.ObjectFlags |= UnrealFlags.EObjectFlags.HasStack; udkPackage.AddExport(dla); EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.AddSingularAsChild, lightComponent, udkPackage, dla, true, out IEntry portedDLC); var dlaProps = new PropertyCollection { new ObjectProperty(portedDLC.UIndex, "LightComponent"), new NameProperty("DirectionalLight", "Tag"), }; if (locationProp != null) { dlaProps.Add(locationProp); } if (rotationProp != null) { dlaProps.Add(rotationProp); } if (scaleProp != null) { dlaProps.Add(scaleProp); } dla.WriteProperties(dlaProps); lightActors.Add(dla); break; } } } UDKifyLights(udkPackage); #endregion Level level = ObjectBinary.From <Level>(levelExport); level.Actors = levelExport.GetChildren().Where(ent => ent.IsA("Actor")).Select(ent => new UIndex(ent.UIndex)).ToList(); levelExport.WriteBinary(level); udkPackage.Save(); } string resultFilePath = Path.Combine(udkPath, @"UDKGame\Content\Maps\", $"{Path.GetFileNameWithoutExtension(pcc.FilePath)}.udk"); using (IMEPackage udkPackage2 = MEPackageHandler.OpenUDKPackage(Path.Combine(App.ExecFolder, "empty.udk"))) { ExportEntry levelExport = udkPackage2.Exports.First(exp => exp.ClassName == "Level"); Level levelBin = ObjectBinary.From <Level>(levelExport); foreach (ExportEntry actor in staticMeshActors) { EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.CloneTreeAsChild, actor, udkPackage2, levelExport, true, out IEntry result); levelBin.Actors.Add(result.UIndex); } foreach (ExportEntry actor in lightActors) { EntryImporter.ImportAndRelinkEntries(EntryImporter.PortingOption.CloneTreeAsChild, actor, udkPackage2, levelExport, true, out IEntry result); levelBin.Actors.Add(result.UIndex); } levelExport.WriteBinary(levelBin); udkPackage2.Save(resultFilePath); } File.Delete(tempPackagePath); return(resultFilePath); }
public static bool RandomizeExportSkin(ExportEntry material, RandomizationOption option, ref StructProperty skinColorPV) { 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 pn = vector.GetProp <NameProperty>("ParameterName"); var pv = vector.GetProp <StructProperty>("ParameterValue"); if (pn != null && pn.Value == "SkinTone" && skinColorPV != null && pv != null) { vector.Properties.AddOrReplaceProp(skinColorPV); } else if (pv != null) { RStructs.RandomizeTint(pv, false); if (pn.Value == "SkinTone") { skinColorPV = pv; // Below method will assign data to this structproperty. } } } } 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(.1, 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); }