static void Postfix(ref CardFrameUI __instance, CardState cardState, List <AbstractSpriteSelector> ___spriteSelectors)
            {
                try
                {
                    if (cardState.GetLinkedClassID() == null)
                    {
                        return;
                    }
                    List <Sprite> cardFrame;
                    if (CustomClassManager.CustomClassFrame.TryGetValue(cardState.GetLinkedClassID(), out cardFrame))
                    {
                        foreach (AbstractSpriteSelector spriteSelector in ___spriteSelectors)
                        {
                            switch (spriteSelector)
                            {
                            case ClassSpriteSelector classSpriteSelector:

                                foreach (var image in classSpriteSelector.gameObject.GetComponents <Image>())
                                {
                                    image.sprite = cardState.GetCardType() == CardType.Monster ? cardFrame[0] : cardFrame[1];
                                }
                                continue;
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    Trainworks.Log(BepInEx.Logging.LogLevel.Error, "TryGetValue is a dumb function.");
                }
            }
        /// <summary>
        /// Imports new data to the English Localization from a CSV string with separators ';'.
        /// Required columns are 'Keys', 'Type', 'Plural', 'Group', 'Desc', 'Descriptions'
        /// </summary>
        public static void ImportCSV(string path, char Separator = ',')
        {
            string CSVstring = "";

            var localPath = Path.GetDirectoryName(new Uri(Assembly.GetCallingAssembly().CodeBase).LocalPath);

            Trainworks.Log(BepInEx.Logging.LogLevel.All, "File: " + Path.Combine(localPath, path));

            try
            {   // Open the text file using a stream reader.
                using (StreamReader sr = new StreamReader(Path.Combine(localPath, path)))
                {
                    // Read the stream to a string, and write the string to the console.
                    CSVstring = sr.ReadToEnd();
                }
            }
            catch (IOException e)
            {
                Trainworks.Log(LogLevel.Error, "We couldn't read the file at " + Path.Combine(localPath, path));
                Trainworks.Log(LogLevel.Error, e.Message);
            }

            List <string> categories = LocalizationManager.Sources[0].GetCategories(true, (List <string>)null);

            foreach (string Category in categories)
            {
                LocalizationManager.Sources[0].Import_CSV(Category, CSVstring, eSpreadsheetUpdateMode.AddNewTerms, Separator);
            }
        }
        /// <summary>
        /// Builds the CardData represented by this builder's parameters recursively
        /// and registers it and its components with the appropriate managers.
        /// </summary>
        /// <returns>The newly registered CardData</returns>
        public CardData BuildAndRegister(int ChampionIndex = 0)
        {
            var cardData = this.Build();

            Trainworks.Log(LogLevel.Debug, "Adding custom card: " + cardData.GetName());
            CustomCardManager.RegisterCustomCard(cardData, this.CardPoolIDs);

            var Clan = cardData.GetLinkedClass();

            ChampionData ClanChamp = Clan.GetChampionData(ChampionIndex);

            ClanChamp.championCardData = cardData;
            if (this.ChampionIconPath != null)
            {
                Sprite championIconSprite = CustomAssetManager.LoadSpriteFromPath(this.BaseAssetPath + "/" + this.ChampionIconPath);
                ClanChamp.championIcon = championIconSprite;
            }
            ClanChamp.starterCardData = StarterCardData;
            if (this.UpgradeTree != null)
            {
                ClanChamp.upgradeTree = UpgradeTree.Build();
            }
            ClanChamp.championSelectedCue = ChampionSelectedCue;

            return(cardData);
        }
        public GameObject Construct(AssetReference assetRef, BundleAssetLoadingInfo bundleInfo)
        {
            var asset = BundleManager.LoadAssetFromBundle(bundleInfo, bundleInfo.SpriteName);

            if (asset.GetType() == typeof(Texture2D))
            {
                // "Type checking ew"
                // You're thinking it, I can tell.
                // Through all the horrible things we've done with this project,
                // type checking is where you draw the line?
                var tex = asset as Texture2D;
                if (tex != null)
                {
                    Sprite sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f), 128f);
                    return(CreateCardGameObject(assetRef, sprite));
                }
                return(null);
            }
            else
            {
                var gameObject = asset as GameObject;
                if (gameObject != null)
                {
                    GameObject.DontDestroyOnLoad(gameObject);
                    return(gameObject);
                }
            }
            Trainworks.Log(BepInEx.Logging.LogLevel.Warning, "Invalid asset type " + asset.GetType() + " when loading asset: " + bundleInfo.SpriteName);
            return(null);
        }
        public static string GenerateDeterministicGUID(string key)
        {
            if (key == null)
            {
                Trainworks.Log(BepInEx.Logging.LogLevel.Warning, "GUIDGenerator cannot generate determinstic GUID for null key");
                return(key);
            }

            //Generate a byte array from a string using default encoding
            byte[] inputBytes = Encoding.Default.GetBytes(key);

            //Use bytes to generate a byte array of length 16 using MD5CryptoServiceProvider
            byte[] hashBytes = provider.ComputeHash(inputBytes);

            //Set the first nibble of the byte to be 0100
            hashBytes[7] = (byte)(0x40 | ((int)hashBytes[7] & 0xf));

            //Set the first crumb of the byte to be 10
            hashBytes[8] = (byte)(0x80 | ((int)hashBytes[8] & 0x3f));

            //Resize the array to get the first 16 bytes
            Array.Resize <byte>(ref hashBytes, 16);

            Guid guid = new Guid(hashBytes);

            return(guid.ToString());
        }
 private static void TemplateCharacterLoadingComplete(IAsyncOperation <GameObject> asyncOperation)
 {
     TemplateCharacter = asyncOperation.Result;
     if (TemplateCharacter == null)
     {
         Trainworks.Log(LogLevel.Warning, "Failed to load character template");
     }
 }
 public static Sprite LoadSpriteFromRuntimeKey(Hash128 runtimeKey)
 {
     if (RuntimeKeyToAssetInfo.ContainsKey(runtimeKey))
     {
         return(LoadSpriteFromPath(RuntimeKeyToAssetInfo[runtimeKey].FullPath));
     }
     Trainworks.Log(BepInEx.Logging.LogLevel.Warning, "Custom asset failed to load from runtime key: " + runtimeKey);
     return(null);
 }
Exemple #8
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="cardPoolID"></param>
 /// <returns></returns>
 public static CardPool GetCustomCardPoolByID(string cardPoolID)
 {
     if (CustomCardPools.ContainsKey(cardPoolID))
     {
         return(CustomCardPools[cardPoolID]);
     }
     Trainworks.Log(LogLevel.Warning, "Could not find card pool: " + cardPoolID);
     return(null);
 }
Exemple #9
0
        /// <summary>
        /// Builds the CardData represented by this builder's parameters recursively
        /// and registers it and its components with the appropriate managers.
        /// </summary>
        /// <returns>The newly registered CardData</returns>
        public CardData BuildAndRegister()
        {
            var cardData = this.Build();

            Trainworks.Log(LogLevel.Debug, "Adding custom card: " + cardData.GetName());
            CustomCardManager.RegisterCustomCard(cardData, this.CardPoolIDs);

            return(cardData);
        }
Exemple #10
0
 public static void RegisterCustomCardPool(CardPool cardPool)
 {
     if (!CustomCardPools.ContainsKey(cardPool.name))
     {
         CustomCardPools.Add(cardPool.name, cardPool);
     }
     else
     {
         Trainworks.Log(LogLevel.Warning, "Attempted to register duplicate card pool with name: " + cardPool.name);
     }
 }
        static void Postfix(ref CombatManager __instance)
        {
            Queue <CombatManager.TriggerQueueData> triggerQueue = (Queue <CombatManager.TriggerQueueData>)AccessTools.PropertyGetter(typeof(CombatManager), "TriggerQueue").Invoke(__instance, null);

            if (!__instance.IsRunningTriggerQueue)
            {
                foreach (CombatManager.TriggerQueueData data in triggerQueue.ToList())
                {
                    Trainworks.Log(BepInEx.Logging.LogLevel.Error, $"Trigger Not Enqued, will be cleared: {data.trigger}");
                }
            }
        }
 /// <summary>
 /// Register a custom card with the manager, allowing it to show up in game
 /// both in the logbook and whenever cards are chosen from the specified pools.
 /// </summary>
 /// <param name="cardData">The custom card data to register</param>
 /// <param name="cardPoolData">The card pools the custom card should be a part of</param>
 public static void RegisterCustomCard(CardData cardData, List <string> cardPoolData)
 {
     if (!CustomCardData.ContainsKey(cardData.GetID()))
     {
         CustomCardData.Add(cardData.GetID(), cardData);
         CustomCardPoolManager.AddCardToPools(cardData, cardPoolData);
         ProviderManager.SaveManager.GetAllGameData().GetAllCardData().Add(cardData);
     }
     else
     {
         Trainworks.Log(LogLevel.Warning, "Attempted to register duplicate card data with name: " + cardData.name);
     }
 }
 /// <summary>
 /// Register a custom relic with the manager, allowing it to show up in game.
 /// </summary>
 /// <param name="relicData">The custom relic data to register</param>
 /// <param name="relicPoolData">The pools to insert the custom relic data into</param>
 public static void RegisterCustomRelic(CollectableRelicData relicData, List <string> relicPoolData)
 {
     if (!CustomRelicData.ContainsKey(relicData.GetID()))
     {
         CustomRelicData.Add(relicData.GetID(), relicData);
         CustomRelicPoolManager.AddRelicToPools(relicData, relicPoolData);
         ProviderManager.SaveManager.GetAllGameData().GetAllCollectableRelicData().Add(relicData);
     }
     else
     {
         Trainworks.Log(LogLevel.Warning, "Attempted to register duplicate relic data with name: " + relicData.name);
     }
 }
Exemple #14
0
 /// <summary>
 /// Register a custom class with the manager, allowing it to show up in game.
 /// </summary>
 /// <param name="classData">The custom class data to register</param>
 public static void RegisterCustomClass(ClassData classData)
 {
     if (!CustomClassData.ContainsKey(classData.GetID()))
     {
         CustomClassData.Add(classData.GetID(), classData);
         ProviderManager.SaveManager.GetAllGameData().GetAllClassDatas().Add(classData);
         ProviderManager.SaveManager.GetAllGameData().GetBalanceData().GetClassDatas().Add(classData);
     }
     else
     {
         Trainworks.Log(LogLevel.Warning, "Attempted to register duplicate class data with name: " + classData.name);
     }
 }
 /// <summary>
 /// Register a custom character with the manager, allowing it to show up in game.
 /// </summary>
 /// <param name="data">The custom character data to register</param>
 public static bool RegisterCustomCharacter(CharacterData data)
 {
     if (!CustomCharacterData.ContainsKey(data.GetID()))
     {
         CustomCharacterData.Add(data.GetID(), data);
         ProviderManager.SaveManager.GetAllGameData().GetAllCharacterData().Add(data);
         return(true);
     }
     else
     {
         Trainworks.Log(LogLevel.Warning, "Attempted to register duplicate character data with name: " + data.name);
         return(false);
     }
 }
 /// <summary>
 /// Create a sprite from texture at provided path.
 /// </summary>
 /// <param name="path">Absolute path of the texture</param>
 /// <returns>The sprite, or null if there is no texture at the given path</returns>
 public static Sprite LoadSpriteFromPath(string path)
 {
     if (File.Exists(path))
     {
         // Create the card sprite
         byte[]    fileData = File.ReadAllBytes(path);
         Texture2D tex      = new Texture2D(1, 1);
         UnityEngine.ImageConversion.LoadImage(tex, fileData);
         Sprite sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f), 128f);
         sprite.name = Path.GetFileNameWithoutExtension(path);
         return(sprite);
     }
     Trainworks.Log(BepInEx.Logging.LogLevel.Warning, "No asset found at: " + path);
     return(null);
 }
Exemple #17
0
 /// <summary>
 /// Load an asset from an asset bundle
 /// </summary>
 /// <param name="info">Loading info for the asset</param>
 /// <param name="assetName">Name of the asset to load from the bundle</param>
 /// <returns>The asset specified by the given info as a UnityEngine object</returns>
 public static UnityEngine.Object LoadAssetFromBundle(BundleAssetLoadingInfo info, string assetName)
 {
     if (LoadedAssetBundles.ContainsKey(info.FullPath))
     {
         var asset = LoadedAssetBundles[info.FullPath].LoadAsset(assetName);
         if (asset == null)
         {
             Trainworks.Log(BepInEx.Logging.LogLevel.Warning, "Custom asset: " + assetName + " failed to load from bundle: " + info.FullPath);
         }
         ApplyImportSettings(info, ref asset);
         return(asset);
     }
     Trainworks.Log(BepInEx.Logging.LogLevel.Warning, "Attempting to load asset from non-existent bundle: " + info.FullPath);
     return(null);
 }
 /// <summary>
 /// A general function used to Apply a Card Trigger in different ways, dependant on parameters
 /// </summary>
 /// <param name="cardTrigger">CardTrigger to be Applied</param>
 /// <param name="playedCard">Card to apply triggers to</param>
 /// <param name="fireAllMonsterTriggersInRoom">Whether Apply Card Triggers should fire on monster's Instead, requires Trigger to have an associated character trigger</param>
 /// <param name="roomIndex">Room to fire triggers in, -1 defaults to selected room</param>
 /// <param name="ignoreDeadInTargeting">Whether effects applied by the trigger should ignore dead in targetting</param>
 /// <param name="triggeredCharacter">Character used to determine how many times Card Trigger should be applied</param>
 /// <param name="cardTriggerFiredCallback">Action to take after applying trigger</param>
 /// <returns></returns>
 public static void ApplyCardTriggers(CardTrigger cardTrigger, CardState playedCard, bool fireAllMonsterTriggersInRoom = false, int roomIndex = -1, bool ignoreDeadInTargeting = true, CharacterState triggeredCharacter = null, Action cardTriggerFiredCallback = null)
 {
     Trainworks.Log(BepInEx.Logging.LogLevel.Info, $"Applying {cardTrigger.Name}");
     if (ProviderManager.TryGetProvider <CombatManager>(out CombatManager combatManager))
     {
         combatManager.StartCoroutine(
             combatManager.ApplyCardTriggers(
                 cardTrigger.GetEnum(),
                 playedCard,
                 fireAllMonsterTriggersInRoom,
                 roomIndex,
                 ignoreDeadInTargeting,
                 triggeredCharacter,
                 cardTriggerFiredCallback
                 )
             );
     }
 }
        /// <summary>
        /// Get the card data corresponding to the given ID
        /// </summary>
        /// <param name="cardID">ID of the card to get</param>
        /// <returns>The card data for the given ID</returns>
        public static CardData GetCardDataByID(string cardID)
        {
            // Search for custom card matching ID
            var guid = GUIDGenerator.GenerateDeterministicGUID(cardID);

            if (CustomCardData.ContainsKey(guid))
            {
                return(CustomCardData[guid]);
            }

            // No custom card found; search for vanilla card matching ID
            var vanillaCard = ProviderManager.SaveManager.GetAllGameData().FindCardData(cardID);

            if (vanillaCard == null)
            {
                Trainworks.Log(LogLevel.All, "Couldn't find card: " + cardID + " - This will cause crashes.");
            }
            return(vanillaCard);
        }
        /// <summary>
        /// Get the relic data corresponding to the given ID
        /// </summary>
        /// <param name="relicID">ID of the relic to get</param>
        /// <returns>The relic data for the given ID</returns>
        public static CollectableRelicData GetRelicDataByID(string relicID)
        {
            // Search for custom relic matching ID
            var guid = GUIDGenerator.GenerateDeterministicGUID(relicID);

            if (CustomRelicData.ContainsKey(guid))
            {
                return(CustomRelicData[guid]);
            }

            // No custom relic found; search for vanilla relic matching ID
            var vanillaRelic = ProviderManager.SaveManager.GetAllGameData().FindCollectableRelicData(relicID);

            if (vanillaRelic == null)
            {
                Trainworks.Log(LogLevel.All, "Couldn't find relic: " + relicID + " - This will cause crashes.");
            }
            return(vanillaRelic);
        }
Exemple #21
0
 /// <summary>
 /// Base Constructor for creating an Extended Enumerator
 /// </summary>
 /// <param name="Name">Name of new Enum Value</param>
 /// <param name="ID">ID of new Enum Value</param>
 public ExtendedEnum(string Name, int ID)
 {
     this.ID   = ID;
     this.Name = Name;
     if (NameToExtendedEnumMap.ContainsKey(this.Name))
     {
         Trainworks.Log(BepInEx.Logging.LogLevel.Warning, $"Name: {this.Name} Conflict in domain, {typeof(TExtendedEnum).Name}");
     }
     if (IntToExtendedEnumMap.ContainsKey(this.ID))
     {
         Trainworks.Log(BepInEx.Logging.LogLevel.Warning, $"ID#{this.ID} Conflict between {Name} and {IntToExtendedEnumMap[this.ID].Name} in domain, {typeof(TExtendedEnum).Name}");
     }
     if (ReservedIDs.Contains(this.ID))
     {
         Trainworks.Log(BepInEx.Logging.LogLevel.Warning, $"ID#{this.ID} is Reserved and can't be set for {Name}");
     }
     NameToExtendedEnumMap[Name] = (TExtendedEnum)this;
     IntToExtendedEnumMap[ID]    = (TExtendedEnum)this;
 }
Exemple #22
0
        public static void RegisterBundle(string assetGUID, BundleAssetLoadingInfo bundleInfo)
        {
            string path = bundleInfo.FullPath;

            if (!LoadedAssetBundles.ContainsKey(path))
            {
                if (File.Exists(path))
                {
                    LoadedAssetBundles[path] = AssetBundle.LoadFromFile(path);
                }
                else
                {
                    Trainworks.Log(BepInEx.Logging.LogLevel.Warning, "Custom asset bundle failed to load from path: " + path);
                }
            }
            var runtimeKey = Hash128.Parse(assetGUID);

            RuntimeKeyToBundleInfo[runtimeKey] = bundleInfo;
        }
        public static GameObject LoadGameObjectFromAssetRef(AssetReference assetRef)
        {
            var runtimeKey = assetRef.RuntimeKey;

            if (BundleManager.RuntimeKeyToBundleInfo.ContainsKey(runtimeKey))
            {
                var bundleInfo       = BundleManager.RuntimeKeyToBundleInfo[runtimeKey];
                var assetType        = RuntimeKeyToAssetInfo[runtimeKey].AssetType;
                var assetConstructor = AssetTypeToAssetConstructor[assetType];
                return(assetConstructor.Construct(assetRef, bundleInfo));
            }
            else if (RuntimeKeyToAssetInfo.ContainsKey(runtimeKey))
            {
                var assetType        = RuntimeKeyToAssetInfo[runtimeKey].AssetType;
                var assetConstructor = AssetTypeToAssetConstructor[assetType];
                return(assetConstructor.Construct(assetRef));
            }
            Trainworks.Log(BepInEx.Logging.LogLevel.Warning, "Runtime key is not registered with CustomAssetManager: " + runtimeKey);
            return(null);
        }
        /// <summary>
        /// Get the character data corresponding to the given ID
        /// </summary>
        /// <param name="characterID">ID of the character to get</param>
        /// <returns>The character data for the given ID</returns>
        public static CharacterData GetCharacterDataByID(string characterID)
        {
            // Search for custom character matching ID
            var guid = GUIDGenerator.GenerateDeterministicGUID(characterID);

            if (CustomCharacterData.ContainsKey(guid))
            {
                return(CustomCharacterData[guid]);
            }

            // No custom card found; search for vanilla character matching ID
            var vanillaChar = ProviderManager.SaveManager.GetAllGameData().GetAllCharacterData().Find((chara) => {
                return(chara.GetID() == characterID);
            });

            if (vanillaChar == null)
            {
                Trainworks.Log(LogLevel.All, "Couldn't find character: " + characterID + " - This will cause crashes.");
            }
            return(vanillaChar);
        }
Exemple #25
0
        public GameObject Construct(AssetReference assetRef, BundleAssetLoadingInfo bundleInfo)
        {
            // Don't recreate
            if (CharacterPrefabDictionary.ContainsKey(bundleInfo.SpriteName))
            {
                return(CharacterPrefabDictionary[bundleInfo.SpriteName]);
            }

            if (CharacterPrefabDictionary.ContainsKey(bundleInfo.ObjectName))
            {
                return(CharacterPrefabDictionary[bundleInfo.ObjectName]);
            }

            // Create a new one if one doesn't exist already
            var tex = BundleManager.LoadAssetFromBundle(bundleInfo, bundleInfo.SpriteName) as Texture2D;

            if (tex != null)
            {
                Sprite sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f), 128f);
                sprite.name = "Sprite_" + bundleInfo.SpriteName.Replace("assets/", "").Replace(".png", "");
                if (bundleInfo.ObjectName != null)
                {
                    GameObject gameObject = BundleManager.LoadAssetFromBundle(bundleInfo, bundleInfo.ObjectName) as GameObject;
                    if (gameObject != null)
                    {
                        var spineObj = CreateCharacterGameObject(assetRef, sprite, gameObject);
                        GameObject.DontDestroyOnLoad(spineObj);
                        CharacterPrefabDictionary.Add(bundleInfo.ObjectName, spineObj);
                        return(spineObj);
                    }
                }
                var charObj = CreateCharacterGameObject(assetRef, sprite);
                GameObject.DontDestroyOnLoad(charObj);
                CharacterPrefabDictionary.Add(bundleInfo.SpriteName, charObj);
                return(charObj);
            }
            Trainworks.Log(BepInEx.Logging.LogLevel.Warning, "Invalid sprite name when loading asset: " + bundleInfo.SpriteName);
            return(null);
        }
Exemple #26
0
        /// <summary>
        /// Create a GameObject for the custom character with the AssetReference and Sprite
        /// </summary>
        /// <param name="assetRef">Reference containing the asset information</param>
        /// <param name="sprite">Sprite to create character with</param>
        /// <returns>The GameObject for the character</returns>
        private static GameObject CreateCharacterGameObject(AssetReference assetRef, Sprite sprite)
        {
            /*
             * // This code attempts to construct a Spine Object with no animations to match the imported PNG file. This gives us better outlining, draw order, and highlighting.
             *
             * GameObject skeletonData = new GameObject();
             * skeletonData.name = sprite.name;
             * var s = skeletonData.AddComponent<SkeletonAnimation>();
             *
             * // All we need is a complete and valid SkeletonDataAsset... does that include the atlas primarymaterial, atlas data, skeletonjson, state, and skeleton?
             * s.skeletonDataAsset = new SkeletonDataAsset();
             * s.skeletonDataAsset.skeletonJSON = new TextAsset("{\"skeleton\":{\"spine\":\"3.6.0.7-beta\",\"width\":" + sprite.rect.width + ",\"height\":" + sprite.rect.height + ",\"fps\":24,\"hash\":\" \",\"name\":\"Armature\"},\"bones\":[{\"name\":\"root\"}],\"slots\":[{\"name\":\"Unit\",\"bone\":\"root\",\"attachment\":\"Unit\"}],\"skins\":{\"default\":{\"Unit\":{\"Unit\":{\"name\":\"Unit\",\"width\":" + sprite.rect.width + ",\"height\":" + sprite.rect.height + ",\"y\":" + sprite.rect.width + "}}}}}");
             * s.skeletonDataAsset.atlasAssets.AddToArray<AtlasAssetBase>(new SpineAtlasAsset());
             * s.skeletonDataAsset.atlasAssets[0].
             */

            /*
             * Trainworks.Log(BepInEx.Logging.LogLevel.All, "We're doing the code!");
             * var skeletonData = TrainworksBundle.LoadAsset("assets/PNGTemplate.prefab") as GameObject;
             *
             * return CreateCharacterGameObject(assetRef, sprite, skeletonData);
             */

            Trainworks.Log(BepInEx.Logging.LogLevel.All, "Character Template: " + CustomCharacterManager.TemplateCharacter);

            // Create a new character GameObject by cloning an existing, working character
            var characterGameObject = GameObject.Instantiate(CustomCharacterManager.TemplateCharacter);

            // Set aside its CharacterState and CharacterUI components for later use
            var characterState = characterGameObject.GetComponentInChildren <CharacterState>();
            var characterUI    = characterGameObject.GetComponentInChildren <CharacterUI>();

            // Set the name, and hide the UI
            characterUI.HideDetails();
            characterGameObject.name = "Character_" + sprite.name;

            // Make its MeshRenderer active; this is what enables the sprite we're about to attach to show up
            characterGameObject.GetComponentInChildren <MeshRenderer>(true).gameObject.SetActive(true);

            // Delete all the spine anims
            var spine = characterGameObject.GetComponentInChildren <ShinyShoe.CharacterUIMeshSpine>(true);

            foreach (Transform child in spine.transform)
            {
                GameObject.Destroy(child.gameObject);
            }
            spine.gameObject.SetActive(false);

            // Set states in the CharacterState and CharacterUI to the sprite to show it ingame
            Traverse.Create(characterState).Field <Sprite>("sprite").Value = sprite;
            characterUI.GetSpriteRenderer().sprite = sprite;

            // Set up the outline Sprite - well, seems like there will be problems here
            var outlineMesh = characterGameObject.GetComponentInChildren <CharacterUIOutlineMesh>(true);

            //Traverse.Create(outlineMesh).Field("outlineData").Field<Texture2D>("characterTexture").Value = sprite.texture;
            //Traverse.Create(outlineMesh).Field("outlineData").Field<Texture2D>("outlineTexture").Value = sprite.texture;
            Traverse.Create(outlineMesh).Field <CharacterOutlineData>("outlineData").Value = null; //CharacterOutlineData.Create(sprite.texture);
            //Traverse.Create(outlineMesh).Field("outlineData").Field<Texture2D>("outlineTexture").Value = sprite.texture;

            return(characterGameObject);
        }