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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        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));
        }
Example #6
0
 public override bool CanParse(ExportEntry exportEntry) => exportEntry.IsA("ParticleModule");
Example #7
0
        //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));
        }