static void LoadFxLookup(bool forceReload = false)
        {
            var filepath = $"{Main.ModEntry.Path}/fxlookup.txt";

            if (File.Exists(filepath) && !forceReload)
            {
                FXIds = File
                        .ReadAllLines($"{Main.ModEntry.Path}/fxlookup.txt")
                        .Where(id => LibraryThing.GetResourceGuidMap().ContainsKey(id))
                        .ToArray();
            }
            else
            {
                var idList = new List <string>();
                foreach (var kv in LibraryThing.GetResourceGuidMap())
                {
                    var obj = ResourcesLibrary.TryGetResource <UnityEngine.Object>(kv.Key);
                    var go  = obj as GameObject;
                    if (go != null && go.GetComponent <PooledFx>() != null)
                    {
                        idList.Add(kv.Key);
                    }
                    ResourcesLibrary.CleanupLoadedCache();
                }
                FXIds = idList
                        .OrderBy(id => LibraryThing.GetResourceGuidMap()[id])
                        .ToArray();
                File.WriteAllLines(filepath, FXIds);
            }
        }
Exemple #2
0
        public void HandleProjectileLaunched(Projectile projectile)
        {
            var cubePrefab = ResourcesLibrary.TryGetResource <GameObject>(TestCubeGuid);
            var cube       = GameObject.Instantiate(cubePrefab, projectile.View.transform);

            cube.transform.localPosition = Vector3.zero;
        }
 static UnitEntityView GetView(string id)
 {
     if (string.IsNullOrEmpty(id))
     {
         return(null);
     }
     return(ResourcesLibrary.TryGetResource <UnitEntityView>(id));
 }
Exemple #4
0
        public static void DumpList()
        {
            var resourceTypes = new Type[]
            {
                typeof(EquipmentEntity),
                typeof(Familiar),
                typeof(UnitEntityView),
                typeof(ProjectileView)
                //Note: PrefabLink : WeakResourceLink<GameObject> exists
            };

            Directory.CreateDirectory($"Blueprints/");
            var blueprints          = ResourcesLibrary.GetBlueprints <BlueprintScriptableObject>().ToList();
            var blueprintsByAssetId = ResourcesLibrary.LibraryObject.BlueprintsByAssetId;

            Main.DebugLog($"BlueprintsByAssetId contains  {blueprintsByAssetId.Count} blueprints");
            Main.DebugLog($"Dumping {blueprints.Count} blueprints");
            using (var file = new StreamWriter("Blueprints/Blueprints.txt"))
            {
                file.WriteLine($"name\tAssetId\tType");
                foreach (var blueprint in blueprints)
                {
                    file.WriteLine($"{blueprint.name}\t{blueprint.AssetGuid}\t{blueprint.GetType()}");
                }
            }
            var resourcePathsByAssetId = ResourcesLibrary.LibraryObject.ResourceNamesByAssetId;

            Main.DebugLog($"ResourcePathsByAssetId contains  {blueprintsByAssetId.Count} resources");
            using (var file = new StreamWriter("Blueprints/Resources.txt"))
            {
                file.WriteLine($"Name\tAssetId\tType\tBaseType\tInstanceId");
                foreach (var kv in ResourcesLibrary.LibraryObject.ResourceNamesByAssetId)
                {
                    var resource = ResourcesLibrary.TryGetResource <UnityEngine.Object>(kv.Key);
                    if (resource != null)
                    {
                        var baseType = resource.GetType().IsAssignableFrom(typeof(UnityEngine.GameObject)) ? "GameObject" :
                                       resource.GetType().IsAssignableFrom(typeof(UnityEngine.ScriptableObject)) ? "ScriptableObject" :
                                       resource.GetType().IsAssignableFrom(typeof(UnityEngine.Component)) ? "Component" :
                                       "Object";
                        var go       = resource as GameObject;
                        var typeName = resource?.GetType().Name ?? "NULL";
                        if (go != null)
                        {
                            foreach (var type in resourceTypes)
                            {
                                if (go.GetComponent(type) != null)
                                {
                                    typeName = type.Name;
                                }
                            }
                        }
                        file.WriteLine($"{kv.Value}\t{kv.Key}\t{typeName}\t{baseType}\t{resource?.GetInstanceID()}");
                        ResourcesLibrary.CleanupLoadedCache();
                    }
                }
            }
        }
 public static void DumpUnitViews()
 {
     foreach (var kv in ResourcesLibrary.LibraryObject.ResourcePathsByAssetId)
     {
         var resource = ResourcesLibrary.TryGetResource <UnitEntityView>(kv.Key);
         if (resource == null)
         {
             continue;
         }
         JsonBlueprints.Dump(resource, kv.Key);
     }
 }
Exemple #6
0
 public static void DumpUnitViews()
 {
     foreach (var kv in ResourcesLibrary.LibraryObject.ResourceNamesByAssetId)
     {
         var resource = ResourcesLibrary.TryGetResource <UnitEntityView>(kv.Key);
         if (resource == null)
         {
             continue;
         }
         DumpResource(resource, kv.Key);
         ResourcesLibrary.CleanupLoadedCache();
     }
 }
Exemple #7
0
        static public void maybeAddCharacter(UnitEntityView original)
        {
            var character = original.GetComponent <Character>();

            if (character == null)
            {
                character = original.gameObject.AddComponent <Character>();
                //BlueprintRoot.Instance.CharGen.FemaleDoll
                var drow = ResourcesLibrary.TryGetResource <UnitEntityView>("a65d9da806faa8f4ca078dfe942bf458", true);
                CloneMonobehaviour(drow.GetComponentInChildren <Character>(), character);
                character.BakedCharacter = CreateBakedCharacter(original.gameObject);
            }
        }
        public object ReadResource(JsonReader reader, Type objectType, object existingValue, JsonSerializer szr)
        {
            JObject jObject = JObject.Load(reader);
            var     name    = (string)jObject["name"];

            Main.DebugLog($"Deserializing {name} of {objectType.Name} with {GetType().Name}");
            var typeName            = (string)jObject["$type"];
            var realType            = Type.GetType(typeName);
            ScriptableObject result = null;

            if (jObject["$append"] != null)
            {
                var settings = JsonBlueprints.CreateSettings(null);
                szr = JsonSerializer.Create(settings);
                szr.ObjectCreationHandling = ObjectCreationHandling.Reuse;
                var copy = (string)jObject["$append"];
                jObject.Remove("$append");
                var parts = copy.Split(':');
                result = ResourcesLibrary.TryGetResource <ScriptableObject>(parts[1]);
                name   = result.name;
                Main.DebugLog($"Appending to {result.name}");
            }
            if (jObject["$replace"] != null)
            {
                var copy = (string)jObject["$replace"];
                jObject.Remove("$replace");
                var parts = copy.Split(':');
                result = ResourcesLibrary.TryGetBlueprint(parts[1]);
                name   = result.name;
            }
            if (jObject["$copy"] != null)
            {
                var copy = (string)jObject["$copy"];
                jObject.Remove("$copy");
                var parts    = copy.Split(':');
                var resource = ResourcesLibrary.TryGetResource <ScriptableObject>(parts[1]);
                result = (ScriptableObject)BlueprintUtil.ShallowClone(resource);
                Main.DebugLog($"Copying {resource.name}");
            }
            if (result == null)
            {
                result = ScriptableObject.CreateInstance(realType);
            }
            szr.Populate(jObject.CreateReader(), result);
            return(result);
        }
        public static void DumpList()
        {
            var typemap = new Dictionary <Type, string>();

            Directory.CreateDirectory($"Blueprints/");
            var blueprints          = ResourcesLibrary.GetBlueprints <BlueprintScriptableObject>().ToList();
            var blueprintsByAssetID = ResourcesLibrary.LibraryObject.BlueprintsByAssetId;

            Main.DebugLog($"BlueprintsByAssetId contains  {blueprintsByAssetID.Count} blueprints");
            Main.DebugLog($"Dumping {blueprints.Count} blueprints");
            using (var file = new StreamWriter("Blueprints/Blueprints.txt"))
            {
                foreach (var blueprint in blueprints)
                {
                    typemap[blueprint.GetType()] = "Blueprint";
                    file.WriteLine($"{blueprint.name}\t{blueprint.AssetGuid}\t{blueprint.GetType()}");
                }
            }
            var resourcePathsByAssetId = ResourcesLibrary.LibraryObject.ResourcePathsByAssetId;

            Main.DebugLog($"ResourcePathsByAssetId contains  {blueprintsByAssetID.Count} resources");
            using (var file = new StreamWriter("Blueprints/Resources.txt"))
            {
                foreach (var kv in ResourcesLibrary.LibraryObject.ResourcePathsByAssetId)
                {
                    var resource = ResourcesLibrary.TryGetResource <UnityEngine.Object>(kv.Key);
                    if (resource != null)
                    {
                        var baseType = resource.GetType().IsAssignableFrom(typeof(UnityEngine.GameObject)) ? "GameObject" :
                                       resource.GetType().IsAssignableFrom(typeof(UnityEngine.ScriptableObject)) ? "ScriptableObject" :
                                       resource.GetType().IsAssignableFrom(typeof(UnityEngine.Component)) ? "Component" :
                                       "Object";
                        typemap[resource.GetType()] = $"Resource:{baseType}";
                    }
                    file.WriteLine($"{resource?.name ?? "NULL"}\t{kv.Key}\t{resource?.GetType()?.Name ?? "NULL"}\t{kv.Value}");
                }
            }
            using (var file = new StreamWriter("Blueprints/Types.txt"))
            {
                foreach (var kv in typemap.OrderBy(kv => kv.Value))
                {
                    file.WriteLine($"{kv.Key}\t{kv.Value}");
                }
            }
        }
        /*
         * Based on DollData.CreateUnitView, DollRoom.CreateAvatar and
         * UnitEntityData.CreateView
         */
        public static void RebuildCharacter(UnitEntityData unitEntityData)
        {
            var character = unitEntityData.View.CharacterAvatar;

            if (character == null)
            {
                return;                    // Happens when overriding view
            }
            if (unitEntityData.Descriptor.Doll != null)
            {
                var doll           = unitEntityData.Descriptor.Doll;
                var savedEquipment = true;
                character.RemoveAllEquipmentEntities(savedEquipment);
                if (doll.RacePreset != null)
                {
                    character.Skeleton = (doll.Gender != Gender.Male) ? doll.RacePreset.FemaleSkeleton : doll.RacePreset.MaleSkeleton;
                    character.AddEquipmentEntities(doll.RacePreset.Skin.Load(doll.Gender, doll.RacePreset.RaceId), savedEquipment);
                }
                ///character.m_Mirror = doll.LeftHanded;
                foreach (string assetID in doll.EquipmentEntityIds)
                {
                    EquipmentEntity ee = ResourcesLibrary.TryGetResource <EquipmentEntity>(assetID);
                    character.AddEquipmentEntity(ee, savedEquipment);
                }
                doll.ApplyRampIndices(character);
                Traverse.Create(unitEntityData.View).Field("m_EquipmentClass").SetValue(null); //UpdateClassEquipment won't update if the class doesn't change
                //Adds Armor
                unitEntityData.View.UpdateBodyEquipmentModel();
                unitEntityData.View.UpdateClassEquipment();
            }
            else
            {
                character.RemoveAllEquipmentEntities();
                character.RestoreSavedEquipment();
                IEnumerable <EquipmentEntity> bodyEquipment = unitEntityData.Body.AllSlots.SelectMany(
                    new Func <ItemSlot, IEnumerable <EquipmentEntity> >(unitEntityData.View.ExtractEquipmentEntities));
                character.AddEquipmentEntities(bodyEquipment, false);
            }
            //Add Kineticist Tattoos
            EventBus.RaiseEvent <IUnitViewAttachedHandler>(unitEntityData, delegate(IUnitViewAttachedHandler h)
            {
                h.HandleUnitViewAttached();
            });
        }
Exemple #11
0
        public static void DumpList()
        {
            Directory.CreateDirectory($"Blueprints/");
            var blueprints          = ResourcesLibrary.GetBlueprints <BlueprintScriptableObject>().ToList();
            var blueprintsByAssetId = ResourcesLibrary.LibraryObject.BlueprintsByAssetId;

            Main.DebugLog($"BlueprintsByAssetId contains  {blueprintsByAssetId.Count} blueprints");
            Main.DebugLog($"Dumping {blueprints.Count} blueprints");
            using (var file = new StreamWriter("Blueprints/Blueprints.txt"))
            {
                file.WriteLine($"name\tAssetId\tType");
                foreach (var blueprint in blueprints)
                {
                    file.WriteLine($"{blueprint.name}\t{blueprint.AssetGuid}\t{blueprint.GetType()}");
                }
            }
            var resourcePathsByAssetId = ResourcesLibrary.LibraryObject.ResourceNamesByAssetId;

            Main.DebugLog($"ResourcePathsByAssetId contains  {blueprintsByAssetId.Count} resources");
            using (var file = new StreamWriter("Blueprints/Resources.txt"))
            {
                file.WriteLine($"name\tResourcenName\tAssetId\tType\tBaseType\tInstanceId");
                foreach (var kv in ResourcesLibrary.LibraryObject.ResourceNamesByAssetId)
                {
                    var resource = ResourcesLibrary.TryGetResource <UnityEngine.Object>(kv.Key);
                    if (resource != null)
                    {
                        var baseType = resource.GetType().IsAssignableFrom(typeof(UnityEngine.GameObject)) ? "GameObject" :
                                       resource.GetType().IsAssignableFrom(typeof(UnityEngine.ScriptableObject)) ? "ScriptableObject" :
                                       resource.GetType().IsAssignableFrom(typeof(UnityEngine.Component)) ? "Component" :
                                       "Object";
                        var go       = resource as GameObject;
                        var typeName = resource?.GetType().Name ?? "NULL";
                        if (go != null)
                        {
                            typeName = go.GetComponents <MonoBehaviour>().Join(c => c.GetType().Name);
                        }
                        file.WriteLine($"{resource?.name ?? "NULL"}\t{kv.Key}\t{kv.Value}\t{typeName}\t{baseType}\t{resource?.GetInstanceID()}");
                        ResourcesLibrary.CleanupLoadedCache();
                    }
                }
            }
        }
        static void ShowDollInfo(UnitEntityData unitEntityData)
        {
            var doll = unitEntityData.Descriptor.Doll;

            if (doll == null)
            {
                GUILayout.Label("No Doll", GUILayout.Width(200f));
                return;
            }
            GUILayout.Label("Indices", GUILayout.Width(200f));
            foreach (var kv in doll.EntityRampIdices)
            {
                var ee = ResourcesLibrary.TryGetResource <EquipmentEntity>(kv.Key);
                GUILayout.Label($"{kv.Key} - {ee?.name} - {kv.Value}");
            }
            GUILayout.Label("EquipmentEntities", GUILayout.Width(200f));
            foreach (var id in doll.EquipmentEntityIds)
            {
                var ee = ResourcesLibrary.TryGetResource <EquipmentEntity>(id);
                GUILayout.Label($"{id} - {ee?.name}");
            }
        }
        public static void UpdateModel(UnitEntityView view)
        {
            if (view.CharacterAvatar == null || view.EntityData == null)
            {
                return;
            }
            if (!view.EntityData.IsPlayerFaction)
            {
                return;
            }
            Settings.CharacterSettings characterSettings = Main.settings.GetCharacterSettings(view.EntityData);
            if (characterSettings == null)
            {
                return;
            }
            bool dirty = view.CharacterAvatar.IsDirty;

            if (view.EntityData.Descriptor.Doll == null && characterSettings.classOutfit.Name != "Default")
            {
                ChangeCompanionOutfit(view, characterSettings);
            }
            if (characterSettings.classOutfit.Name == "None")
            {
                NoClassOutfit(view);
            }
            if (characterSettings.hideHelmet)
            {
                HideSlot(view, view.EntityData.Body.Head, ref dirty);
            }

            /* if (characterSettings.hideItemCloak)
             * {
             *   HideSlot(view, view.EntityData.Body.Shoulders, ref dirty);
             * }*/
            if (characterSettings.hideArmor)
            {
                HideSlot(view, view.EntityData.Body.Armor, ref dirty);
            }
            if (characterSettings.hideGloves)
            {
                HideSlot(view, view.EntityData.Body.Gloves, ref dirty);
            }
            if (characterSettings.hideBracers)
            {
                HideSlot(view, view.EntityData.Body.Wrist, ref dirty);
            }
            if (characterSettings.hideBoots)
            {
                HideSlot(view, view.EntityData.Body.Feet, ref dirty);
            }
            if (characterSettings.hideHorns)
            {
                foreach (var ee in view.CharacterAvatar.EquipmentEntities.ToArray())
                {
                    if (ee.BodyParts.Exists((bodypart) => bodypart.Type == BodyPartType.Horns))
                    {
                        view.CharacterAvatar.EquipmentEntities.Remove(ee);
                        dirty = true;
                    }
                }
            }
            if (characterSettings.hideTail)
            {
                foreach (var ee in view.CharacterAvatar.EquipmentEntities.ToArray())
                {
                    if (ee.name.StartsWith("Tail"))
                    {
                        view.CharacterAvatar.EquipmentEntities.Remove(ee);
                        dirty = true;
                    }
                }
            }
            if (characterSettings.hideClassCloak)
            {
                foreach (var ee in view.CharacterAvatar.EquipmentEntities.ToArray())
                {
                    if (ee.OutfitParts.Exists((outfit) => {
                        return(outfit.Special == EquipmentEntity.OutfitPartSpecialType.Backpack ||
                               outfit.Special == EquipmentEntity.OutfitPartSpecialType.Backpack);
                    }) && !view.ExtractEquipmentEntities(view.EntityData.Body.Shoulders).Contains(ee))
                    {
                        view.CharacterAvatar.EquipmentEntities.Remove(ee);
                        dirty = true;
                    }
                }
            }
            if (characterSettings.hideCap)
            {
                foreach (var ee in view.CharacterAvatar.EquipmentEntities.ToArray())
                {
                    if (ee.BodyParts.Exists((bodypart) => bodypart.Type == BodyPartType.Helmet) &&
                        !view.ExtractEquipmentEntities(view.EntityData.Body.Head).Contains(ee))
                    {
                        view.CharacterAvatar.EquipmentEntities.Remove(ee);
                        dirty = true;
                    }
                }
            }
            if (characterSettings.overrideHelm != null && !characterSettings.hideHelmet)
            {
                if (!OverrideEquipment(view, view.EntityData.Body.Head, characterSettings.overrideHelm, ref dirty))
                {
                    characterSettings.overrideHelm = null;
                }
            }

            /*            if (characterSettings.overrideCloak
             *            != null && !characterSettings.hideItemCloak)
             *          {
             *              if (!OverrideEquipment(view, view.EntityData.Body.Shoulders, characterSettings.overrideCloak, ref dirty))
             *              {
             *                  characterSettings.overrideCloak = null;
             *              }
             *          }*/
            if (characterSettings.overrideArmor != null && !characterSettings.hideArmor)
            {
                if (!OverrideEquipment(view, view.EntityData.Body.Armor, characterSettings.overrideArmor, ref dirty))
                {
                    characterSettings.overrideArmor = null;
                }
            }
            if (characterSettings.overrideBracers != null && !characterSettings.hideBracers)
            {
                if (!OverrideEquipment(view, view.EntityData.Body.Wrist, characterSettings.overrideBracers, ref dirty))
                {
                    characterSettings.overrideBracers = null;
                }
            }
            if (characterSettings.overrideGloves != null && !characterSettings.hideGloves)
            {
                if (!OverrideEquipment(view, view.EntityData.Body.Gloves, characterSettings.overrideGloves, ref dirty))
                {
                    characterSettings.overrideGloves = null;
                }
            }
            if (characterSettings.overrideBoots != null && !characterSettings.hideBoots)
            {
                if (!OverrideEquipment(view, view.EntityData.Body.Feet, characterSettings.overrideBoots, ref dirty))
                {
                    characterSettings.overrideBoots = null;
                }
            }
            if (characterSettings.overrideGlasses != null && !characterSettings.hideGlasses)
            {
                if (!OverrideEquipment(view, view.EntityData.Body.Glasses, characterSettings.overrideGlasses, ref dirty))
                {
                    characterSettings.overrideGlasses = null;
                }
            }
            if (characterSettings.overrideShirt != null && !characterSettings.hideShirt)
            {
                if (!OverrideEquipment(view, view.EntityData.Body.Shirt, characterSettings.overrideShirt, ref dirty))
                {
                    characterSettings.overrideShirt = null;
                }
            }
            if (characterSettings.overrideTattoo != null)
            {
                foreach (var assetId in EquipmentResourcesManager.Tattoos.Keys)
                {
                    var ee = ResourcesLibrary.TryGetResource <EquipmentEntity>(assetId);
                    if (ee != null)
                    {
                        view.CharacterAvatar.RemoveEquipmentEntity(ee);
                    }
                }
                var tattoo = ResourcesLibrary.TryGetResource <EquipmentEntity>(characterSettings.overrideTattoo);
                if (tattoo != null)
                {
                    view.CharacterAvatar.AddEquipmentEntity(tattoo);
                }
            }

            /*if (view.EntityData.Descriptor.Progression?.GetEquipmentClass().Name == "Ranger")
             * {
             *  FixRangerCloak(view);
             * }*/
            view.CharacterAvatar.IsDirty = dirty;
        }
        //Refer FxHelper.SpawnFxOnGameObject
        static void ShowFxInfo(UnitEntityData unitEntityData)
        {
            //Choose FX
            GUILayout.Label($"Choose FX {FXIds.Length} available", GUILayout.Width(200f));
            if (FXIds.Length == 0)
            {
                LoadFxLookup();
            }
            GUILayout.BeginHorizontal();
            fxIndex = (int)GUILayout.HorizontalSlider(fxIndex, 0, FXIds.Length - 1, GUILayout.Width(300));
            if (GUILayout.Button("Prev", GUILayout.Width(45)))
            {
                fxIndex = fxIndex == 0 ? 0 : fxIndex - 1;
            }
            if (GUILayout.Button("Next", GUILayout.Width(45)))
            {
                fxIndex = fxIndex >= FXIds.Length - 1 ? FXIds.Length - 1 : fxIndex + 1;
            }
            var fxId = FXIds[fxIndex];

            GUILayout.Label($"{LibraryThing.GetResourceGuidMap()[fxId]} {FXIds[fxIndex]}");
            if (GUILayout.Button("Apply", GUILayout.Width(200)))
            {
                var prefab = ResourcesLibrary.TryGetResource <GameObject>(fxId);
                FxHelper.SpawnFxOnUnit(prefab, unitEntityData.View);
            }
            if (GUILayout.Button("Clear FX Cache", GUILayout.Width(200)))
            {
                LoadFxLookup(forceReload: true);
            }
            GUILayout.EndHorizontal();
            //List of SpawnFxOnStart
            var spawnOnStart = unitEntityData.View.GetComponent <SpawnFxOnStart>();

            if (spawnOnStart)
            {
                GUILayout.Label("Spawn on Start", GUILayout.Width(200f));
                GUILayout.Label("FxOnStart " + spawnOnStart.FxOnStart?.Load()?.name, GUILayout.Width(400));
                GUILayout.Label("FXFxOnDeath " + spawnOnStart.FxOnStart?.Load()?.name, GUILayout.Width(400));
            }
            GUILayout.Label("Decals");
            var decals = Traverse.Create(unitEntityData.View).Field("m_Decals").GetValue <List <FxDecal> >();

            for (int i = decals.Count - 1; i >= 0; i--)
            {
                var decal = decals[i];
                GUILayout.Label("Decal: " + decal.name, GUILayout.Width(400));
                if (GUILayout.Button("Destroy", GUILayout.Width(200f)))
                {
                    GameObject.Destroy(decal.gameObject);
                    decals.RemoveAt(i);
                }
            }
            GUILayout.Label("CustomWeaponEffects", GUILayout.Width(200f));
            var dollroom = Game.Instance.UI.Common.DollRoom;

            foreach (var kv in EffectsManager.WeaponEnchantments)
            {
                GUILayout.Label($"{kv.Key.Name} - {kv.Value.Count}");
                foreach (var go in kv.Value)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Label($"  {go?.name ?? "NULL"}");
                    if (dollroom != null && GUILayout.Button("UnscaleFXTimes", GUILayout.ExpandWidth(false)))
                    {
                        Traverse.Create(dollroom).Method("UnscaleFxTimes", new object[] { go }).GetValue();
                    }
                    GUILayout.EndHorizontal();
                }
            }
            GUILayout.Label("FXRoot", GUILayout.Width(200f));
            foreach (Transform t in FxHelper.FxRoot.transform)
            {
                var            pooledFX       = t.gameObject.GetComponent <PooledFx>();
                var            snapToLocaters = (List <SnapToLocator>)AccessTools.Field(typeof(PooledFx), "m_SnapToLocators").GetValue(pooledFX);
                var            fxBone         = snapToLocaters.Select(s => s.Locator).FirstOrDefault();
                UnitEntityView unit           = null;
                if (fxBone != null)
                {
                    var viewTransform = fxBone.Transform;
                    while (viewTransform != null && unit == null)
                    {
                        unit = viewTransform.GetComponent <UnitEntityView>();
                        if (unit == null)
                        {
                            viewTransform = viewTransform.parent;
                        }
                    }
                }
                GUILayout.BeginHorizontal();
                if (unit != null)
                {
                    GUILayout.Label($"{pooledFX.name} - {unit.EntityData.CharacterName} - {unit.name}", GUILayout.Width(200f));
                }
                else
                {
                    GUILayout.Label($"{pooledFX.name}", GUILayout.Width(200f));
                }
                if (GUILayout.Button("DestroyFX", GUILayout.Width(200)))
                {
                    FxHelper.Destroy(t.gameObject);
                }
                GUILayout.EndHorizontal();
            }
        }
        static void ShowCharacterInfo(UnitEntityData unitEntityData)
        {
            var character = unitEntityData.View.CharacterAvatar;

            if (character == null)
            {
                return;
            }
            GUILayout.Label($"View: {unitEntityData.View.name}", GUILayout.Width(200f));
            GUILayout.Label($"BakedCharacter: {character.BakedCharacter?.name ?? "NULL"}", GUILayout.Width(200f));

            if (m_OrphanedKingmakerEquipment == null)
            {
                BuildOrphenedKingmakerEquipment();
            }
            if (m_OrphanedMaleEquipment == null || m_OrphanedFemaleEquipment == null)
            {
                BuildOrphanedEquipment();
            }
            void onEquipment()
            {
                unitEntityData.View.CharacterAvatar.RemoveAllEquipmentEntities();
                var preset = unitEntityData.Descriptor.Progression.Race.Presets.First();
                var skin   = preset.Skin.Load(unitEntityData.Gender, preset.RaceId);

                unitEntityData.View.CharacterAvatar.AddEquipmentEntities(skin);
                var kee = ResourcesLibrary.TryGetBlueprint <KingmakerEquipmentEntity>(selectedKingmakerOrphanedEquipment);

                if (kee != null)
                {
                    var ees = kee.Load(unitEntityData.Gender, unitEntityData.Descriptor.Progression.Race.RaceId);
                    unitEntityData.View.CharacterAvatar.AddEquipmentEntities(ees);
                    unitEntityData.View.CharacterAvatar.IsDirty = true;
                }
                var ee = ResourcesLibrary.TryGetResource <EquipmentEntity>(selectedOrphanedEquipment);

                if (ee != null)
                {
                    unitEntityData.View.CharacterAvatar.AddEquipmentEntity(ee);
                    unitEntityData.View.CharacterAvatar.IsDirty = true;
                }
            }

            var equipmentList = unitEntityData.Gender == Gender.Male ? m_OrphanedMaleEquipment : m_OrphanedFemaleEquipment;

            Util.ChooseSlider($"OrphanedKingmakerEquipment", m_OrphanedKingmakerEquipment, ref selectedKingmakerOrphanedEquipment, onEquipment);
            Util.ChooseSlider($"OrphanedEquipment", equipmentList, ref selectedOrphanedEquipment, onEquipment);

            GUILayout.Label("Equipment", GUILayout.Width(200f));
            foreach (var ee in character.EquipmentEntities.ToArray())
            {
                GUILayout.BeginHorizontal();
                if (ee == null)
                {
                    GUILayout.Label("Null");
                }
                else
                {
                    GUILayout.Label(
                        String.Format("{0}:{1}:{2}:P{3}:S{4}", ee.name, ee.BodyParts.Count, ee.OutfitParts.Count,
                                      character.GetPrimaryRampIndex(ee), character.GetSecondaryRampIndex(ee)),
                        GUILayout.ExpandWidth(false));
                }
                if (GUILayout.Button("Remove", GUILayout.ExpandWidth(false)))
                {
                    character.RemoveEquipmentEntity(ee);
                }
                if (ee == null)
                {
                    GUILayout.EndHorizontal();
                    continue;
                }
                bool expanded = ee.name == expandedEE;
                if (expanded && GUILayout.Button("Shrink ", GUILayout.ExpandWidth(false)))
                {
                    expandedEE = null;
                }
                if (!expanded && GUILayout.Button("Expand", GUILayout.ExpandWidth(false)))
                {
                    expandedEE = ee.name;
                }
                GUILayout.EndHorizontal();
                if (expanded)
                {
                    EquipmentEntityInfo settings = lookup.ContainsKey(ee.name) ? lookup[ee.name] : new EquipmentEntityInfo();
                    GUILayout.Label($" HideFlags: {ee.HideBodyParts}", GUILayout.Width(200f));
                    var       primaryIndex = character.GetPrimaryRampIndex(ee);
                    Texture2D primaryRamp  = null;
                    if (primaryIndex < 0 || primaryIndex > ee.PrimaryRamps.Count - 1)
                    {
                        primaryRamp = ee.PrimaryRamps.FirstOrDefault();
                    }
                    else
                    {
                        primaryRamp = ee.PrimaryRamps[primaryIndex];
                    }
                    GUILayout.Label($"PrimaryRamp: {primaryRamp?.name ?? "NULL"}", GUILayout.Width(200f));

                    var       secondaryIndex = character.GetSecondaryRampIndex(ee);
                    Texture2D secondaryRamp  = null;
                    if (secondaryIndex < 0 || secondaryIndex > ee.SecondaryRamps.Count - 1)
                    {
                        secondaryRamp = ee.SecondaryRamps.FirstOrDefault();
                    }
                    else
                    {
                        secondaryRamp = ee.SecondaryRamps[secondaryIndex];
                    }
                    GUILayout.Label($"SecondaryRamp: {secondaryRamp?.name ?? "NULL"}", GUILayout.Width(200f));

                    foreach (var bodypart in ee.BodyParts.ToArray())
                    {
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(String.Format(" BP {0}:{1}", bodypart?.RendererPrefab?.name ?? "NULL", bodypart?.Type), GUILayout.ExpandWidth(false));
                        if (GUILayout.Button("Remove", GUILayout.ExpandWidth(false)))
                        {
                            ee.BodyParts.Remove(bodypart);
                        }
                        GUILayout.EndHorizontal();
                    }
                    foreach (var outfitpart in ee.OutfitParts.ToArray())
                    {
                        GUILayout.BeginHorizontal();
                        var prefab = Traverse.Create(outfitpart).Field("m_Prefab").GetValue <GameObject>();
                        GUILayout.Label(String.Format(" OP {0}:{1}", prefab?.name ?? "NULL", outfitpart?.Special), GUILayout.ExpandWidth(false));
                        if (GUILayout.Button("Remove", GUILayout.ExpandWidth(false)))
                        {
                            ee.OutfitParts.Remove(outfitpart);
                        }
                        GUILayout.EndHorizontal();
                    }
                }
            }
            GUILayout.Label("Character", GUILayout.Width(300));
            GUILayout.Label("RampIndices", GUILayout.Width(200f));
            foreach (var index in Traverse.Create(character).Field("m_RampIndices").GetValue <List <Character.SelectedRampIndices> >())
            {
                var name = index.EquipmentEntity != null ? index.EquipmentEntity.name : "NULL";
                GUILayout.Label($"  {name} - {index.PrimaryIndex}, {index.SecondaryIndex}");
            }
            GUILayout.Label("SavedRampIndices", GUILayout.Width(200f));
            foreach (var index in Traverse.Create(character).Field("m_SavedRampIndices").GetValue <List <Character.SavedSelectedRampIndices> >())
            {
                GUILayout.Label($"  {GetName(index.EquipmentEntityLink)} - {index.PrimaryIndex}, {index.SecondaryIndex}");
            }
            GUILayout.Label("SavedEquipmentEntities", GUILayout.Width(200f));
            foreach (var link in Traverse.Create(character).Field("m_SavedEquipmentEntities").GetValue <List <EquipmentEntityLink> >())
            {
                var name = GetName(link);
                GUILayout.Label($"  {name}");
            }
        }
        static void BuildOrphanedEquipment()
        {
            string maleFilepath = "Mods/VisualAdjustments/MaleOrphanedEquipment.json";

            if (File.Exists(maleFilepath))
            {
                JsonSerializer serializer = new JsonSerializer();
                using (StreamReader sr = new StreamReader(maleFilepath))
                    using (JsonTextReader reader = new JsonTextReader(sr))
                    {
                        var result = serializer.Deserialize <Dictionary <string, string> >(reader);
                        m_OrphanedMaleEquipment = result;
                        if (m_OrphanedMaleEquipment == null)
                        {
                            Main.Log($"Error loading {maleFilepath}");
                        }
                    }
            }
            var femaleFilepath = "Mods/VisualAdjustments/FemaleOrphanedEquipment.json";

            if (File.Exists(femaleFilepath))
            {
                JsonSerializer serializer = new JsonSerializer();
                using (StreamReader sr = new StreamReader(femaleFilepath))
                    using (JsonTextReader reader = new JsonTextReader(sr))
                    {
                        var result = serializer.Deserialize <Dictionary <string, string> >(reader);
                        m_OrphanedFemaleEquipment = result;
                        if (m_OrphanedFemaleEquipment == null)
                        {
                            Main.Log($"Error loading {femaleFilepath}");
                        }
                    }
            }
            if (m_OrphanedMaleEquipment == null || m_OrphanedFemaleEquipment == null)
            {
                Main.Log("Rebuilding Orphaned Equipment Lookup");
                var eeBlacklist = new HashSet <string>();
                foreach (var gender in new Gender[] { Gender.Male, Gender.Female })
                {
                    foreach (var race in BlueprintRoot.Instance.Progression.CharacterRaces)
                    {
                        var armorLinks = BluePrintThing.GetBlueprints <KingmakerEquipmentEntity>()
                                         .SelectMany(kee => kee.GetLinks(gender, race.RaceId));
                        var options = gender == Gender.Male ? race.MaleOptions : race.FemaleOptions;
                        var links   = race.Presets
                                      .SelectMany(preset => preset.Skin.GetLinks(gender, race.RaceId))
                                      .Concat(armorLinks)
                                      .Concat(options.Beards)
                                      .Concat(options.Eyebrows)
                                      .Concat(options.Hair)
                                      .Concat(options.Heads)
                                      .Concat(options.Horns);
                        foreach (var link in links)
                        {
                            eeBlacklist.Add(link.AssetId);
                        }
                    }
                }

                m_OrphanedMaleEquipment   = new Dictionary <string, string>();
                m_OrphanedFemaleEquipment = new Dictionary <string, string>();
                foreach (var kv in LibraryThing.GetResourceGuidMap().OrderBy(kv => kv.Value))
                {
                    if (eeBlacklist.Contains(kv.Key))
                    {
                        continue;
                    }
                    var ee = ResourcesLibrary.TryGetResource <EquipmentEntity>(kv.Key);
                    if (ee == null)
                    {
                        continue;
                    }
                    var  nameParts = ee.name.Split('_');
                    bool isMale    = nameParts.Contains("M");
                    bool isFemale  = nameParts.Contains("F");
                    if (!isMale && !isFemale)
                    {
                        isMale   = true;
                        isFemale = true;
                    }
                    if (isMale)
                    {
                        m_OrphanedMaleEquipment[kv.Key] = kv.Value;
                    }
                    if (isFemale)
                    {
                        m_OrphanedFemaleEquipment[kv.Key] = kv.Value;
                    }
                }
                JsonSerializer serializer = new JsonSerializer();
                serializer.Formatting = Formatting.Indented;
                using (StreamWriter sw = new StreamWriter(maleFilepath))
                    using (JsonWriter writer = new JsonTextWriter(sw))
                    {
                        serializer.Serialize(writer, m_OrphanedMaleEquipment);
                    }
                using (StreamWriter sw = new StreamWriter(femaleFilepath))
                    using (JsonWriter writer = new JsonTextWriter(sw))
                    {
                        serializer.Serialize(writer, m_OrphanedFemaleEquipment);
                    }
                ResourcesLibrary.CleanupLoadedCache();
            }
        }
        // Token: 0x06000003 RID: 3 RVA: 0x000027B4 File Offset: 0x000009B4
        private static bool Prefix(UnitEntityData __instance, ref UnitEntityView __result)
        {
            if (!Main.modEnabled)
            {
                return(true);
            }

            if (Main.customPrefabUnits == null || Main.customPrefabUnits.Count() == 0)
            {
                Main.Init();
            }


            Main.DebugLog("NEW CreateView() -  " + __instance.Blueprint.CharacterName + " - " + __instance.Blueprint.name + " - " + __instance.Blueprint.AssetGuid);
            Polymorph activePolymorph = __instance.GetActivePolymorph();

            if (activePolymorph != null)
            {
                UnitEntityView unitEntityView = activePolymorph.Prefab.Load(false);
                if (unitEntityView)
                {
                    Quaternion rotation = (!unitEntityView.ForbidRotation) ? Quaternion.Euler(0f, __instance.Orientation, 0f) : Quaternion.identity;



                    bool isprefab2 = false;
                    if (unitEntityView.GetComponentsInChildren <Component>().Count() > 0)
                    {
                        isprefab2 = true;

                        Tuple <string, string> result2 = new Tuple <string, string>("", "");
                        // if (__instance.Blueprint.CustomizationPreset != null || Main.customPrefabUnits.ContainsKey(__instance.Blueprint.name))
                        // {

                        result2 = Main.randomPool(__instance.Blueprint, unitEntityView);
                        //   }

                        unitEntityView = Main.unitEntityViewTexReplacer(unitEntityView, result2.Item1, result2.Item2);
                    }


                    UnitEntityView unitEntityView2 = UnityEngine.Object.Instantiate <UnitEntityView>(unitEntityView, __instance.Position, rotation);



                    if (!isprefab2)
                    {
                        Tuple <string, string> result = new Tuple <string, string>("", "");


                        //  if (__instance.Blueprint.CustomizationPreset != null || Main.customPrefabUnits.ContainsKey(__instance.Blueprint.name))
                        // {

                        result = Main.randomPool(__instance.Blueprint, unitEntityView2);
                        // }

                        unitEntityView2 = Main.unitEntityViewTexReplacer(unitEntityView2, result.Item1, result.Item2);
                    }

                    /*
                     *
                     * string texfullpath = "";
                     * if (!string.IsNullOrEmpty(__instance.Descriptor.CustomPrefabGuid)&& __instance.Blueprint != null)
                     * {
                     *  //texfullpath = Main.randomPool(__instance.Blueprint, __instance.Descriptor.CustomPrefabGuid);
                     *
                     *  unitEntityView2
                     * }
                     *
                     * unitEntityView2 = Main.unitEntityViewTexReplacer(unitEntityView2, texfullpath);
                     */
                    activePolymorph.SetReplacementViewOnLoad(unitEntityView2);
                    unitEntityView2.DisableSizeScaling = true;
                    //                  Main.DebugLog("1 " + unitEntityView2.name);
                    __result = unitEntityView2;

                    // Main.OrigTexName = null;
                    // Main.ReadableText = null;


                    Main.preset    = null;
                    Main.notRandom = false;
                    return(false);
                }
            }
            if (__instance.Descriptor.Doll != null)
            {
                UnitEntityView unitEntityView3 = __instance.Descriptor.Doll.CreateUnitView(false);
                unitEntityView3.transform.position = __instance.Position;
                unitEntityView3.transform.rotation = Quaternion.Euler(0f, __instance.Orientation, 0f);

                /*
                 * string texfullpath = "";
                 * if (!string.IsNullOrEmpty(__instance.Descriptor.CustomPrefabGuid) && __instance.Blueprint != null)
                 * {
                 *  texfullpath = Main.randomPool(__instance.Blueprint, __instance.Descriptor.CustomPrefabGuid);
                 * }
                 *
                 * unitEntityView3 = Main.unitEntityViewTexReplacer(unitEntityView3, texfullpath);
                 * //                Main.DebugLog("2 " + unitEntityView3.name);
                 */


                Tuple <string, string> result = new Tuple <string, string>("", "");
                //if (!string.IsNullOrEmpty(__instance.Descriptor.CustomPrefabGuid))
                // if (__instance.Blueprint.CustomizationPreset != null || Main.customPrefabUnits.ContainsKey(__instance.Blueprint.name))
                // {

                result = Main.randomPool(__instance.Blueprint, unitEntityView3);
                // }

                unitEntityView3 = Main.unitEntityViewTexReplacer(unitEntityView3, result.Item1, result.Item2);



                __result = unitEntityView3;
                // Main.OrigTexName = null;
                // Main.ReadableText = null;


                Main.preset    = null;
                Main.notRandom = false;
                return(false);
            }
            UnitEntityView unitEntityView4 = (!string.IsNullOrEmpty(__instance.Descriptor.CustomPrefabGuid)) ? ResourcesLibrary.TryGetResource <UnitEntityView>(__instance.Descriptor.CustomPrefabGuid, false) : __instance.Blueprint.Prefab.Load(false);


            if (unitEntityView4 == null)
            {
                UberDebug.LogError(__instance.Blueprint, "Cannot find prefab for unit", Array.Empty <object>());

                __result = null;
                // Main.OrigTexName = null;
                //  Main.ReadableText = null;


                Main.preset    = null;
                Main.notRandom = false;
                return(false);
            }



            bool isprefab = false;

            if (unitEntityView4.GetComponentsInChildren <Component>().Count() > 0)
            {
                isprefab = true;

                Tuple <string, string> result2 = new Tuple <string, string>("", "");
                // if (__instance.Blueprint.CustomizationPreset != null || Main.customPrefabUnits.ContainsKey(__instance.Blueprint.name))
                // {

                result2 = Main.randomPool(__instance.Blueprint, unitEntityView4);
                // }

                unitEntityView4 = Main.unitEntityViewTexReplacer(unitEntityView4, result2.Item1, result2.Item2);
            }



            Quaternion rotation2 = (!unitEntityView4.ForbidRotation) ? Quaternion.Euler(0f, __instance.Orientation, 0f) : Quaternion.identity;


            UnitEntityView resultView = UnityEngine.Object.Instantiate <UnitEntityView>(unitEntityView4, __instance.Position, rotation2);


            if (!isprefab)
            {
                Tuple <string, string> result = new Tuple <string, string>("", "");


                // if (__instance.Blueprint.CustomizationPreset != null || Main.customPrefabUnits.ContainsKey(__instance.Blueprint.name))
                // {

                result = Main.randomPool(__instance.Blueprint, resultView);
                // }

                resultView = Main.unitEntityViewTexReplacer(resultView, result.Item1, result.Item2);
            }


            __result = resultView;
            //   Main.OrigTexName = null;
            // Main.ReadableText = null;


            Main.preset    = null;
            Main.notRandom = false;

            return(false);
        }
        static void OnGUI(UnityModManager.ModEntry modEntry)
        {
            try
            {
                if (!enabled)
                {
                    return;
                }
#if (DEBUG)
                if (GUILayout.Button("DumpClassRaceBlueprints"))
                {
                    AssetsDump.DumpQuick();
                }
                if (GUILayout.Button("DumpSampleOfBlueprints"))
                {
                    AssetsDump.DumpBlueprints();
                }
                if (GUILayout.Button("DumpAllBlueprints"))
                {
                    AssetsDump.DumpAllBlueprints();
                }
                if (GUILayout.Button("DumpEquipmentEntities"))
                {
                    AssetsDump.DumpEquipmentEntities();
                }
                if (GUILayout.Button("DumpUnitViews"))
                {
                    AssetsDump.DumpUnitViews();
                }
                if (GUILayout.Button("DumpList"))
                {
                    AssetsDump.DumpList();
                }
                if (GUILayout.Button("TestLoad"))
                {
                    //var bp = JsonBlueprints.Load<BlueprintCharacterClass>("mods/customraces/data/slayerclass.json");
                    //DebugLog("Loaded " + (bp?.name ?? "NULL"));
                    //var info = BlueprintInfo.Load();
                    //DebugLog("Loaded " + info.Classes[0].name);
                    var vp = JsonBlueprints.Load <BlueprintRaceVisualPreset>("mods/customraces/data/TestPreset.json");
                    DebugLog("Loaded " + vp.name);
                }

                /*
                 * UnityEngine.Networking.NetworkTransport.GetAssetId(go) //returns ""
                 * internal static extern bool Object.DoesObjectWithInstanceIDExist(int instanceID); //returns true
                 * internal static extern Object Object.FindObjectFromInstanceID(int instanceID); // returns CR_Hair_VioletDark_U_HM
                 * Resources.FindObjectsOfTypeAll<Texture2D>() // returns CR_Hair_VioletDark_U_HM after it has been loaded with Resource.Load
                 */
                if (GUILayout.Button("FindObject"))
                {
                    var go = BlueprintUtil.FindObjectByInstanceId <GameObject>(270194);
                    DebugLog("FindByID " + go == null ? "NULL" : go.name); //OH_LongswordThieves

                    var sprite = BlueprintUtil.FindObjectByInstanceId <Sprite>(45820);
                    DebugLog(sprite == null ? "NULL" : sprite.name); //OH_LongswordThieves

                    var texture1 = BlueprintUtil.FindObjectByInstanceId <Texture2D>(552466);
                    DebugLog(texture1 == null ? "NULL" : texture1.name);                                                   //CR_Hair_VioletDark_U_HM

                    var humanHair = ResourcesLibrary.TryGetResource <EquipmentEntity>("a9558cfc0705d4e48af7ecd2ebd75411"); //EE_Hair_HairLongWavy_M_HM

                    var texture2 = BlueprintUtil.FindObjectByInstanceId <Texture2D>(552466);
                    DebugLog(texture2 == null ? "NULL" : texture2.name); //CR_Hair_VioletDark_U_HM
                }
                if (GUILayout.Button("FindObject2"))
                {
                    var doesExist = Traverse.Create <UnityEngine.Object>().Method("DoesObjectWithInstanceIDExist", new object[] { 552466 }).GetValue <bool>();
                    DebugLog($"Does resource exist first {doesExist}");
                    var tex1 = Traverse.Create <UnityEngine.Object>().Method("FindObjectFromInstanceID", new object[] { 552466 }).GetValue <UnityEngine.Object>();
                    DebugLog(tex1 == null ? "NULL" : tex1.name);                                                           //CR_Hair_VioletDark_U_HM

                    var humanHair = ResourcesLibrary.TryGetResource <EquipmentEntity>("a9558cfc0705d4e48af7ecd2ebd75411"); //EE_Hair_HairLongWavy_M_HM

                    doesExist = Traverse.Create <UnityEngine.Object>().Method("DoesObjectWithInstanceIDExist", new object[] { 552466 }).GetValue <bool>();
                    DebugLog($"Does resource exist second {doesExist}");
                    var tex2 = Traverse.Create <UnityEngine.Object>().Method("FindObjectFromInstanceID", new object[] { 552466 }).GetValue <UnityEngine.Object>();
                    DebugLog(tex2 == null ? "NULL" : tex2.name); //CR_Hair_VioletDark_U_HM


                    var go = (GameObject)BlueprintUtil.FindObjectByInstanceId <GameObject>(270194);
                    DebugLog("FindByID " + go == null ? "NULL" : go.name); //OH_LongswordThieves

                    var assetId = UnityEngine.Networking.NetworkTransport.GetAssetId(go);
                    if (assetId == null)
                    {
                        assetId = "NULL";
                    }
                    if (assetId == "")
                    {
                        assetId = "Empty";
                    }
                    DebugLog($"AssetId: {assetId}");
                }

                if (GUILayout.Button("Reload"))
                {
                    BlueprintManager.Reload();
                }
                int newTorso = (int)GUILayout.HorizontalSlider(torso, -1, MeshTestRace.testAssets.Length - 1, GUILayout.Width(300));
                GUILayout.Label("Torso: " + newTorso);
                if (torso != newTorso)
                {
                    torso = newTorso;
                    MeshTestRace.ChooseTorso(torso);
                }
#endif
            } catch (Exception e)
            {
                DebugLog(e.ToString() + " " + e.StackTrace);
            }
        }
        static void OnGUI(UnityModManager.ModEntry modEntry)
        {
            try
            {
                if (!enabled)
                {
                    return;
                }
#if (DEBUG)
                GUILayout.Label($"Game Version: {GameVersion.GetVersion()}");
                if (GUILayout.Button("DumpAssets"))
                {
                    AssetsDump.DumpAssets();
                }
                if (GUILayout.Button("DumpClassRaceBlueprints"))
                {
                    AssetsDump.DumpQuick();
                }
                if (GUILayout.Button("DumpSampleOfBlueprints"))
                {
                    AssetsDump.DumpBlueprints();
                }
                if (GUILayout.Button("DumpAllBlueprints"))
                {
                    AssetsDump.DumpAllBlueprints();
                }
                if (GUILayout.Button("DumpAllBlueprintsVerbose"))
                {
                    AssetsDump.DumpAllBlueprintsVerbose();
                }
                if (GUILayout.Button("DumpFlags"))
                {
                    var blueprints = ResourcesLibrary.GetBlueprints <BlueprintUnlockableFlag>();
                    Directory.CreateDirectory("Blueprints");
                    using (var file = new StreamWriter("Blueprints/log.txt"))
                    {
                        foreach (var blueprint in blueprints)
                        {
                            if (blueprint.AssetGuid.Length != 32)
                            {
                                continue;
                            }
                            Main.DebugLog($"Dumping {blueprint.name} - {blueprint.AssetGuid}");
                            try
                            {
                                AssetsDump.DumpBlueprint(blueprint);
                            }
                            catch (Exception ex)
                            {
                                file.WriteLine($"Error dumping {blueprint.name}:{blueprint.AssetGuid}:{blueprint.GetType().FullName}, {ex.ToString()}");
                            }
                        }
                    }
                }
                if (GUILayout.Button("DumpEquipmentEntities"))
                {
                    AssetsDump.DumpEquipmentEntities();
                }
                if (GUILayout.Button("DumpUnitViews"))
                {
                    AssetsDump.DumpUnitViews();
                }
                if (GUILayout.Button("DumpList"))
                {
                    AssetsDump.DumpList();
                }
                if (GUILayout.Button("DumpScriptableObjects"))
                {
                    AssetsDump.DumpScriptableObjects();
                }
                if (GUILayout.Button("DumpAssetBundles"))
                {
                    AssetsDump.DumpAssetBundles();
                }
                if (GUILayout.Button("DumpUI"))
                {
                    AssetsDump.DumpUI();
                }
                if (GUILayout.Button("DumpSceneList"))
                {
                    AssetsDump.DumpSceneList();
                }
                if (GUILayout.Button("DumpKingdom"))
                {
                    AssetsDump.DumpKingdom();
                }
                if (GUILayout.Button("DumpView"))
                {
                    var view      = ResourcesLibrary.TryGetResource <GameObject>("adf003833b2463543a065d5160c7e8f1");
                    var character = view.GetComponent <Character>();
                    JsonBlueprints.Dump(character, "adf003833b2463543a065d5160c7e8f1");
                }
                if (GUILayout.Button("TestLoad"))
                {
                    var vp = JsonBlueprints.Load <BlueprintRaceVisualPreset>("mods/customraces/data/TestPreset.json");
                    DebugLog("Loaded " + vp.name);
                }
#endif
            } catch (Exception e)
            {
                DebugLog(e.ToString() + " " + e.StackTrace);
            }
        }
        static void SetupClassApperance(BlueprintCharacterClass newClass, BlueprintCharacterClass rogue, BlueprintCharacterClass ranger)
        {
            newClass.PrimaryColor   = 31;
            newClass.SecondaryColor = 7;

            /*
             * Shoulder stuff, Belts and straps, keytools
             * "b1c62eff2287d9a4fbbf76c345d58840" EE_RogueAccesories_M
             * "345af8eabd450524ab364e7a7c6f1044" EE_RogueAccesories_F
             *
             * Base Outfit
             * "d019e95d4a8a8474aa4e03489449d6ee" EE_Rogue_M_Any_Colorize
             * "c6757746d62b78f46a92020110dfe088" EE_Rogue_F_Any_Colorize
             *
             * Nice Cape
             * "bba6c03b44e5a1c4dbfacf7eec6123dd" EE_Rogue_M_Cape
             * "b7613075291c79947a0cde8c7aec5926" EE_Rogue_F_Cape
             *
             * Backpack
             * "e249678d823d00f4cb30d4d5c8ca1219" Ranger_M_Accessories
             * "e09cf61a567f2a84ea9a3b505f390a32" Ranger_F_Accessories
             *
             * Belts and Straps
             * "0809ab3735b54874b965a09311f0c898" EE_RangerAccesories_M_Any_Colorize
             * "b6bca728c4ced324da7e8d0d01ad34bb" EE_RangerAccesories_F_Any_Colorize
             *
             * Base Outfit
             * "ca71ad9178ecf6a4d942ce55d0c7857b" EE_Ranger_M_Any_Colorize
             * "bc6fb7e5c91de08418b81a397b20bb18" EE_Ranger_F_Any_Colorize
             *
             * Ratty Cape
             * "fb0037ec1d96c8d418bc08d3e0bbf063" EE_Ranger_M_Cape
             * "52a0a0c7183957a4ea02301ce40b3e83" EE_Ranger_F_Cape
             */

            /*
             * Ranger contains: Boots, Forearms, Faulds, Hands, Torso, Upperarms, Upperlegs
             * Roue Contains: Boots, forearms, Faulds, Torso, Upperarms, Upperlegs
             */
            var rogueMaleOutfit  = ResourcesLibrary.TryGetResource <EquipmentEntity>("d019e95d4a8a8474aa4e03489449d6ee");
            var rangerMaleOutfit = ResourcesLibrary.TryGetResource <EquipmentEntity>("ca71ad9178ecf6a4d942ce55d0c7857b");
            var maleOutfit       = BlueprintUtil.CopyEquipmentEntity(rogueMaleOutfit);

            maleOutfit.BodyParts.Clear();
            var rangerBodyPartTypes = BodyPartType.Boots | BodyPartType.Hands | BodyPartType.Upperarms | BodyPartType.Forearms;
            var rogueBodyPartTypes  = BodyPartType.Faulds | BodyPartType.Upperlegs | BodyPartType.Torso;

            maleOutfit.BodyParts.AddRange(rogueMaleOutfit.BodyParts.Where(
                                              (bp) => (bp.Type & rogueBodyPartTypes) != 0));
            maleOutfit.BodyParts.AddRange(rangerMaleOutfit.BodyParts.Where(
                                              (bp) => (bp.Type & rangerBodyPartTypes) != 0));
            var maleOutfitLink     = BlueprintUtil.MakeEquipmentEntityLink(maleOutfit, "7b8429914e404455b270835c20486322");
            var rogueFemaleOutfit  = ResourcesLibrary.TryGetResource <EquipmentEntity>("c6757746d62b78f46a92020110dfe088");
            var rangerFemaleOutfit = ResourcesLibrary.TryGetResource <EquipmentEntity>("bc6fb7e5c91de08418b81a397b20bb18");
            var femaleOutfit       = BlueprintUtil.CopyEquipmentEntity(rogueFemaleOutfit);

            femaleOutfit.BodyParts.Clear();
            femaleOutfit.BodyParts.AddRange(rogueFemaleOutfit.BodyParts.Where(
                                                (bp) => bp.Type == BodyPartType.Faulds || bp.Type == BodyPartType.Torso || bp.Type == BodyPartType.Upperarms || bp.Type == BodyPartType.Upperlegs));
            femaleOutfit.BodyParts.AddRange(rangerFemaleOutfit.BodyParts.Where(
                                                (bp) => bp.Type == BodyPartType.Boots || bp.Type == BodyPartType.Hands || bp.Type == BodyPartType.Forearms));

            var femaleOutfitLink = BlueprintUtil.MakeEquipmentEntityLink(femaleOutfit, "b23db2bf48b340b79e25039deb0c86dd");

            //EquipmentEntities contains race dependent equipment entities, specificly hoods because races have different heads
            newClass.EquipmentEntities     = rogue.EquipmentEntities;
            newClass.MaleEquipmentEntities = new EquipmentEntityLink[] {
                new EquipmentEntityLink()
                {
                    AssetId = "0809ab3735b54874b965a09311f0c898"
                },              //EE_RangerAccesories_M_Any_Colorize
                maleOutfitLink, //CustomOutfit
                new EquipmentEntityLink()
                {
                    AssetId = "fb0037ec1d96c8d418bc08d3e0bbf063"
                },                                                                         //EE_Ranger_M_Cape
            };
            newClass.FemaleEquipmentEntities = new EquipmentEntityLink[] {
                new EquipmentEntityLink()
                {
                    AssetId = "b6bca728c4ced324da7e8d0d01ad34bb"
                },                //EE_RangerAccesories_F_Any_Colorize
                femaleOutfitLink, //CustomOutfit
                new EquipmentEntityLink()
                {
                    AssetId = "52a0a0c7183957a4ea02301ce40b3e83"
                },                                                                         //EE_Ranger_F_Cape
            };
        }