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); }
/// <summary> /// Is this a non-player biopawn /// </summary> /// <param name="export"></param> /// <returns></returns> private static bool CanRandomize(ExportEntry export) { if (!export.IsDefaultObject && !export.IsClass && export.IsA("BioPawn")) { // BioPawn instance var props = export.GetProperties(); var aic = props.GetProp <ObjectProperty>("AIController"); if (aic == null || (aic.ResolveToEntry(export.FileRef) is IEntry e && (e.ObjectName == "SFXAI_Ambient" || e.ObjectName == "SFXAI_None"))) { return(true); } var ambient = export.GetProperty <BoolProperty>("bAmbientCreature"); if (ambient != null && ambient) { return(true); // Combat pawns cannot be modified } } return(false); }
public static ObjectBinary From(ExportEntry export) { if (export.IsDefaultObject) { //DefaultObjects don't have binary return(null); } string className = export.ClassName; if (export.IsA("BioPawn")) { //way, waaay too many subclasses of BioPawn to put in the switch statement, so we take care of it here className = "BioPawn"; } switch (className) { case "AnimSequence": return(From <AnimSequence>(export)); case "BioStage": return(From <BioStage>(export)); case "Level": return(From <Level>(export)); case "World": return(From <World>(export)); case "Model": return(From <Model>(export)); case "Polys": return(From <Polys>(export)); case "DecalMaterial": case "Material": return(From <Material>(export)); case "MaterialInstanceConstant": case "MaterialInstanceTimeVarying": if (export.GetProperty <BoolProperty>("bHasStaticPermutationResource")?.Value == true) { return(From <MaterialInstance>(export)); } return(Array.Empty <byte>()); case "FracturedStaticMesh": return(From <FracturedStaticMesh>(export)); case "StaticMesh": return(From <StaticMesh>(export)); case "SkeletalMesh": case "BioSocketSupermodel": return(From <SkeletalMesh>(export)); case "CoverMeshComponent": case "InteractiveFoliageComponent": case "SplineMeshComponent": case "FracturedStaticMeshComponent": case "StaticMeshComponent": return(From <StaticMeshComponent>(export)); case "DecalComponent": return(From <DecalComponent>(export)); case "Terrain": return(From <Terrain>(export)); case "TerrainComponent": return(From <TerrainComponent>(export)); case "FluidSurfaceComponent": return(From <FluidSurfaceComponent>(export)); case "ModelComponent": return(From <ModelComponent>(export)); case "BioDynamicAnimSet": return(From <BioDynamicAnimSet>(export)); case "BioPawn": return(From <BioPawn>(export)); case "PrefabInstance": return(From <PrefabInstance>(export)); case "Class": return(From <UClass>(export)); case "State": return(From <UState>(export)); case "Function": return(From <UFunction>(export)); case "Enum": return(From <UEnum>(export)); case "Const": return(From <UConst>(export)); case "ScriptStruct": return(From <UScriptStruct>(export)); case "IntProperty": return(From <UIntProperty>(export)); case "BoolProperty": return(From <UBoolProperty>(export)); case "FloatProperty": return(From <UFloatProperty>(export)); case "NameProperty": return(From <UNameProperty>(export)); case "StrProperty": return(From <UStrProperty>(export)); case "StringRefProperty": return(From <UStringRefProperty>(export)); case "ByteProperty": return(From <UByteProperty>(export)); case "ObjectProperty": return(From <UObjectProperty>(export)); case "ComponentProperty": return(From <UComponentProperty>(export)); case "InterfaceProperty": return(From <UInterfaceProperty>(export)); case "ArrayProperty": return(From <UArrayProperty>(export)); case "StructProperty": return(From <UStructProperty>(export)); case "BioMask4Property": return(From <UBioMask4Property>(export)); case "MapProperty": return(From <UMapProperty>(export)); case "ClassProperty": return(From <UClassProperty>(export)); case "DelegateProperty": return(From <UDelegateProperty>(export)); case "ShaderCache": return(From <ShaderCache>(export)); case "StaticMeshCollectionActor": return(From <StaticMeshCollectionActor>(export)); case "StaticLightCollectionActor": return(From <StaticLightCollectionActor>(export)); case "WwiseEvent": return(From <WwiseEvent>(export)); case "WwiseStream": return(From <WwiseStream>(export)); case "WwiseBank": return(From <WwiseBank>(export)); case "BioGestureRuntimeData": return(From <BioGestureRuntimeData>(export)); case "LightMapTexture2D": return(From <LightMapTexture2D>(export)); case "Texture2D": case "ShadowMapTexture2D": case "TerrainWeightMapTexture": case "TextureFlipBook": return(From <UTexture2D>(export)); case "GuidCache": return(From <GuidCache>(export)); case "FaceFXAnimSet": return(From <FaceFXAnimSet>(export)); case "Bio2DA": case "Bio2DANumberedRows": return(From <Bio2DABinary>(export)); case "BioMorphFace": return(From <BioMorphFace>(export)); case "MorphTarget": return(From <MorphTarget>(export)); case "SFXMorphFaceFrontEndDataSource": return(From <SFXMorphFaceFrontEndDataSource>(export)); case "PhysicsAssetInstance": return(From <PhysicsAssetInstance>(export)); case "DirectionalLightComponent": case "PointLightComponent": case "SkyLightComponent": case "SphericalHarmonicLightComponent": case "SpotLightComponent": case "DominantSpotLightComponent": case "DominantPointLightComponent": case "DominantDirectionalLightComponent": return(From <LightComponent>(export)); case "ShadowMap1D": return(From <ShadowMap1D>(export)); case "BioTlkFileSet": return(From <BioTlkFileSet>(export)); case "RB_BodySetup": return(From <RB_BodySetup>(export)); case "BrushComponent": return(From <BrushComponent>(export)); case "ForceFeedbackWaveform": return(From <ForceFeedbackWaveform>(export)); case "SoundCue": return(From <SoundCue>(export)); case "SoundNodeWave": return(From <SoundNodeWave>(export)); case "ObjectRedirector": return(From <ObjectRedirector>(export)); case "TextureMovie": return(From <TextureMovie>(export)); default: return(null); } }
// Jacob is not listed as an iconic appearance. // If we run skin randomizer it will look weird // private static bool CanRandomizeNPCExport(ExportEntry export) => !export.IsDefaultObject && (export.IsA("BioPawn") || (export.ObjectFlags.Has(UnrealFlags.EObjectFlags.ArchetypeObject) && export.IsA("SFXSkeletalMeshActorMAT"))); private static bool CanRandomizeNPCExport2(ExportEntry export) => !export.IsDefaultObject && (export.IsA("BioPawn") || export.IsA("SFXSkeletalMeshActorMAT"));
//call this method to regenerate ME2ObjectInfo.json //Takes a long time (10 minutes maybe?). Application will be completely unresponsive during that time. public static void generateInfo(string outpath) { var NewClasses = new Dictionary <string, ClassInfo>(); var NewStructs = new Dictionary <string, ClassInfo>(); var NewEnums = new Dictionary <string, List <NameReference> >(); var NewSequenceObjects = new Dictionary <string, SequenceObjectInfo>(); foreach (string filePath in MELoadedFiles.GetOfficialFiles(MEGame.ME2)) { if (Path.GetExtension(filePath) == ".pcc") { using IMEPackage pcc = MEPackageHandler.OpenME2Package(filePath); for (int j = 1; j <= pcc.ExportCount; j++) { ExportEntry exportEntry = pcc.GetUExport(j); string className = exportEntry.ClassName; if (className == "Enum") { generateEnumValues(exportEntry, NewEnums); } else if (className == "Class") { string objectName = exportEntry.ObjectName; if (!NewClasses.ContainsKey(objectName)) { NewClasses.Add(objectName, generateClassInfo(exportEntry)); } } else if (className == "ScriptStruct") { string objectName = exportEntry.ObjectName; if (!NewStructs.ContainsKey(objectName)) { NewStructs.Add(objectName, generateClassInfo(exportEntry, isStruct: true)); } } else if (exportEntry.IsA("SequenceObject")) { if (!NewSequenceObjects.TryGetValue(className, out SequenceObjectInfo seqObjInfo)) { seqObjInfo = new SequenceObjectInfo(); NewSequenceObjects.Add(className, seqObjInfo); } int objInstanceVersion = exportEntry.GetProperty <IntProperty>("ObjInstanceVersion"); if (objInstanceVersion > seqObjInfo.ObjInstanceVersion) { seqObjInfo.ObjInstanceVersion = objInstanceVersion; } } } //Debug.WriteLine("Releasing " + pcc.FileName); } } //CUSTOM ADDITIONS try { NewClasses.Add("LightMapTexture2D", new ClassInfo { baseClass = "Texture2D", exportIndex = 0, pccPath = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName }); NewClasses["StaticMesh"] = new ClassInfo { baseClass = "Object", exportIndex = 0, pccPath = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName, properties = { new KeyValuePair <string, PropertyInfo>("UseSimpleRigidBodyCollision", new PropertyInfo(PropertyType.BoolProperty)), new KeyValuePair <string, PropertyInfo>("UseSimpleLineCollision", new PropertyInfo(PropertyType.BoolProperty)), new KeyValuePair <string, PropertyInfo>("UseSimpleBoxCollision", new PropertyInfo(PropertyType.BoolProperty)), new KeyValuePair <string, PropertyInfo>("UseFullPrecisionUVs", new PropertyInfo(PropertyType.BoolProperty)), new KeyValuePair <string, PropertyInfo>("BodySetup", new PropertyInfo(PropertyType.ObjectProperty, "RB_BodySetup")), new KeyValuePair <string, PropertyInfo>("LODDistanceRatio", new PropertyInfo(PropertyType.FloatProperty)), new KeyValuePair <string, PropertyInfo>("LightMapCoordinateIndex", new PropertyInfo(PropertyType.IntProperty)), new KeyValuePair <string, PropertyInfo>("LightMapResolution", new PropertyInfo(PropertyType.IntProperty)), } }; } catch (Exception) { } //SFXPhysicalMaterialDecals missing items ClassInfo sfxpmd = NewClasses["SFXPhysicalMaterialDecals"]; string[] decalComponentArrays = { "HeavyPistol", "AutoPistol", "HandCannon", "SMG", "Shotgun", "HeavyShotgun", "FlakGun", "AssaultRifle", "Needler", "Machinegun", "SniperRifle", "AntiMatRifle", "MassCannon", "ParticleBeam" }; foreach (string decal in decalComponentArrays) { sfxpmd.properties.Add(decal, new PropertyInfo(PropertyType.ArrayProperty, "DecalComponent")); } NewClasses["SFXWeapon"].properties.Add("InstantHitDamageTypes", new PropertyInfo(PropertyType.ArrayProperty, "Class")); File.WriteAllText("ME2ObjectInfo.json", JsonConvert.SerializeObject(new { SequenceObjects = NewSequenceObjects, Classes = NewClasses, Structs = NewStructs, Enums = NewEnums }, Formatting.Indented)); }
public override bool CanParse(ExportEntry exportEntry) => exportEntry.IsA("ParticleModule");
//call this method to regenerate ME1ObjectInfo.json //Takes a long time (10 to 20 minutes maybe?). Application will be completely unresponsive during that time. public static void generateInfo(string outpath) { Classes = new Dictionary <string, ClassInfo>(); Structs = new Dictionary <string, ClassInfo>(); Enums = new Dictionary <string, List <NameReference> >(); SequenceObjects = new Dictionary <string, SequenceObjectInfo>(); foreach (string file in MELoadedFiles.GetOfficialFiles(MEGame.ME1)) { if (Path.GetExtension(file) == ".upk" || Path.GetExtension(file) == ".sfm" || Path.GetExtension(file) == ".u") { Debug.WriteLine($"File: {file}"); using IMEPackage pcc = MEPackageHandler.OpenME1Package(file); for (int j = 1; j <= pcc.ExportCount; j++) { ExportEntry exportEntry = pcc.GetUExport(j); string className = exportEntry.ClassName; if (className == "Enum") { generateEnumValues(exportEntry); } else if (className == "Class") { string objectName = exportEntry.ObjectName; Debug.WriteLine($"Generating information for {objectName}"); if (!Classes.ContainsKey(objectName)) { Classes.Add(objectName, generateClassInfo(exportEntry)); } } else if (className == "ScriptStruct") { string objectName = exportEntry.ObjectName; if (!Structs.ContainsKey(exportEntry.ObjectName)) { Structs.Add(objectName, generateClassInfo(exportEntry, isStruct: true)); } } else if (exportEntry.IsA("SequenceObject")) { if (!SequenceObjects.TryGetValue(className, out SequenceObjectInfo seqObjInfo)) { seqObjInfo = new SequenceObjectInfo(); SequenceObjects.Add(className, seqObjInfo); } int objInstanceVersion = exportEntry.GetProperty <IntProperty>("ObjInstanceVersion"); if (objInstanceVersion > seqObjInfo.ObjInstanceVersion) { seqObjInfo.ObjInstanceVersion = objInstanceVersion; } } } } } //CUSTOM ADDITIONS Classes["LightMapTexture2D"] = new ClassInfo { baseClass = "Texture2D", exportIndex = 0, pccPath = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName }; Classes["StaticMesh"] = new ClassInfo { baseClass = "Object", exportIndex = 0, pccPath = UnrealObjectInfo.Me3ExplorerCustomNativeAdditionsName, properties = { new KeyValuePair <string, PropertyInfo>("UseSimpleRigidBodyCollision", new PropertyInfo(PropertyType.BoolProperty)), new KeyValuePair <string, PropertyInfo>("UseSimpleLineCollision", new PropertyInfo(PropertyType.BoolProperty)), new KeyValuePair <string, PropertyInfo>("UseSimpleBoxCollision", new PropertyInfo(PropertyType.BoolProperty)), new KeyValuePair <string, PropertyInfo>("ForceDoubleSidedShadowVolumes", new PropertyInfo(PropertyType.BoolProperty)), new KeyValuePair <string, PropertyInfo>("BodySetup", new PropertyInfo(PropertyType.ObjectProperty, "RB_BodySetup")), new KeyValuePair <string, PropertyInfo>("LODDistanceRatio", new PropertyInfo(PropertyType.FloatProperty)), new KeyValuePair <string, PropertyInfo>("LightMapCoordinateIndex", new PropertyInfo(PropertyType.IntProperty)), new KeyValuePair <string, PropertyInfo>("LightMapResolution", new PropertyInfo(PropertyType.IntProperty)), new KeyValuePair <string, PropertyInfo>("SoundCue", new PropertyInfo(PropertyType.ObjectProperty, "SoundCue")), } }; File.WriteAllText(outpath, JsonConvert.SerializeObject(new { SequenceObjects, Classes, Structs, Enums }, Formatting.Indented)); }