Пример #1
0
        /// <summary>Loads an animal sub type's assets and validates.</summary>
        /// <param name="subType">The sub type to load assets for and to validate.</param>
        /// <returns>Whether the sub type was valid.</returns>
        private bool LoadAnimalSubType(AnimalSubType subType, IContentPack contentPack, string animalName)
        {
            // get sprites
            var sprites = new AnimalSprites(
                adultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", $"{subType.Name}.png"), contentPack),
                babySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", $"Baby {subType.Name}.png"), contentPack),
                harvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", $"Harvested {subType.Name}.png"), contentPack),
                springAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "spring", $"{subType.Name}.png"), contentPack),
                springHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "spring", $"Harvested {subType.Name}.png"), contentPack),
                springBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "spring", $"Baby {subType.Name}.png"), contentPack),
                summerAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "summer", $"{subType.Name}.png"), contentPack),
                summerHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "summer", $"Harvested {subType.Name}.png"), contentPack),
                summerBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "summer", $"Baby {subType.Name}.png"), contentPack),
                fallAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "fall", $"{subType.Name}.png"), contentPack),
                fallHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "fall", $"Harvested {subType.Name}.png"), contentPack),
                fallBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "fall", $"Baby {subType.Name}.png"), contentPack),
                winterAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "winter", $"{subType.Name}.png"), contentPack),
                winterHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "winter", $"Harvested {subType.Name}.png"), contentPack),
                winterBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "winter", $"Baby {subType.Name}.png"), contentPack)
                );

            // ensure sprites are valid
            if (!sprites.IsValid())
            {
                this.Monitor.Log($"Sprites are not valid for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName} >> Subtype: {subType.Name}", LogLevel.Error);
                return(false);
            }
            subType.Sprites = sprites;

            // resolve API tokens in data and validate it
            subType.ResolveTokens();
            if (!subType.IsValid())
            {
                this.Monitor.Log($"Data is not valid for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName} >> Subtype: {subType.Name}", LogLevel.Error);
                return(false);
            }

            return(true);
        }
Пример #2
0
        /// <summary>Load all the sprites for the new animals from the loaded content packs.</summary>
        private void LoadContentPacks()
        {
            foreach (IContentPack contentPack in this.Helper.ContentPacks.GetOwned())
            {
                Monitor.Log($"Loading {contentPack.Manifest.Name}");

                // loop through each animal folder in the current content pack
                foreach (var animalFolder in Directory.GetDirectories(contentPack.DirectoryPath))
                {
                    var animalFolderSplit = animalFolder.Split(Path.DirectorySeparatorChar);
                    var animalName        = animalFolderSplit[animalFolderSplit.Length - 1];

                    // ensure content.json file exists
                    if (!File.Exists(Path.Combine(animalFolder, "content.json")))
                    {
                        this.Monitor.Log($"Content pack: {contentPack.Manifest.Name} >> Animal: {animalName} doesn't contain a content.json file.", LogLevel.Error);
                        continue;
                    }

                    // serialize and validate content.json file
                    AnimalData animalData    = contentPack.LoadAsset <AnimalData>(Path.Combine(animalName, "content.json"));
                    bool       isAnimalValid = animalData.IsValid(animalName);
                    if (!isAnimalValid)
                    {
                        this.Monitor.Log($"Content.json is not valid for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName}", LogLevel.Error);
                        continue;
                    }

                    // loop through each sub type and add them (such as colour varients etc)
                    List <AnimalSubType> animalSubTypes = new List <AnimalSubType>();
                    foreach (var type in animalData.Types)
                    {
                        // get sprites
                        var sprites = new AnimalSprites(
                            adultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", $"{type}.png"), contentPack),
                            babySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", $"Baby {type}.png"), contentPack),
                            harvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", $"Harvested {type}.png"), contentPack),
                            springAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "spring", $"{type}.png"), contentPack),
                            springHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "spring", $"Harvested {type}.png"), contentPack),
                            springBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "spring", $"Baby {type}.png"), contentPack),
                            summerAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "summer", $"{type}.png"), contentPack),
                            summerHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "summer", $"Harvested {type}.png"), contentPack),
                            summerBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "summer", $"Baby {type}.png"), contentPack),
                            fallAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "fall", $"{type}.png"), contentPack),
                            fallHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "fall", $"Harvested {type}.png"), contentPack),
                            fallBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "fall", $"Baby {type}.png"), contentPack),
                            winterAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "winter", $"{type}.png"), contentPack),
                            winterHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "winter", $"Harvested {type}.png"), contentPack),
                            winterBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "winter", $"Baby {type}.png"), contentPack)
                            );

                        // ensure sprites are valid
                        if (!sprites.IsValid())
                        {
                            this.Monitor.Log($"Sprites are not valid for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName} >> Subtype: {type}", LogLevel.Error);
                            continue;
                        }

                        // get data
                        AnimalSubTypeData data;
                        if (File.Exists(Path.Combine(animalFolder, "assets", $"{type} content.json")))
                        {
                            data = contentPack.LoadAsset <AnimalSubTypeData>(Path.Combine(animalName, "assets", $"{type} content.json"));
                        }
                        else if (File.Exists(Path.Combine(animalFolder, "assets", "content.json")))
                        {
                            data = contentPack.LoadAsset <AnimalSubTypeData>(Path.Combine(animalName, "assets", "content.json"));
                        }
                        else
                        {
                            this.Monitor.Log($"Content pack: {contentPack.Manifest.Name} >> Animal: {animalName} >> Type: {type} doesn't have a content.json file.", LogLevel.Error);
                            continue;
                        }

                        // resolve API tokens in data and validate it
                        data.ResolveTokens();
                        if (!data.IsValid(type))
                        {
                            this.Monitor.Log($"Data is not valid for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName} >> Subtype: {type}", LogLevel.Error);
                            continue;
                        }

                        // create subtype and add to animal
                        var animalSubType = new AnimalSubType(
                            name: type,
                            data: data,
                            sprites: sprites
                            );

                        animalSubTypes.Add(animalSubType);
                    }

                    // ensure there were valid sub types
                    if (animalSubTypes.Count == 0)
                    {
                        this.Monitor.Log($"No valid sub types for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName}.\n Animal will not be added.", LogLevel.Error);
                        continue;
                    }

                    // create, validate, and add the animal
                    var animal = new Animal(
                        name: animalName,
                        data: animalData,
                        shopIcon: GetSpriteByPath(Path.Combine(animalName, $"shopdisplay.png"), contentPack),
                        subTypes: animalSubTypes
                        );

                    if (!animal.IsValid())
                    {
                        this.Monitor.Log($"Animal is not valid at Content pack: {contentPack.Manifest.Name} >> Animal: {animalName}", LogLevel.Error);
                        continue;
                    }

                    Animals.Add(animal);
                }
            }
        }
        /*********
        ** Internal Methods
        *********/
        /// <summary>The prefix for the LoadTexture method.</summary>
        /// <param name="textureName">The name of the texture to load.</param>
        /// <param name="__instance">The <see cref="AnimatedSprite"/> instance being patched.</param>
        /// <returns>False meaning the original method won't get ran.</returns>
        internal static bool LoadTexturePrefix(AnimatedSprite __instance)
        {
            var loadedTexture = (string)typeof(AnimatedSprite).GetField("loadedTexture", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance);

            if (loadedTexture == __instance.textureName.Value)
            {
                return(false);
            }

            var spriteTexture  = (Texture2D)typeof(AnimatedSprite).GetField("spriteTexture", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance);
            var contentManager = (ContentManager)typeof(AnimatedSprite).GetField("contentManager", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance);

            // check if the texture to load is an animal
            if (__instance.textureName.Value != null && __instance.textureName.Value.Contains("Animals\\"))
            {
                var           animalName          = __instance.textureName.Value.Split('\\')[1];
                var           isCustomAnimal      = false;
                AnimalSubType customAnimalSubType = null;

                // check if it's a custom animal
                var subType = ModEntry.Instance.Api.GetAnimalSubTypeByName(animalName);
                if (subType != null)
                {
                    var currentSeason = Season.Spring;
                    switch (Game1.currentSeason)
                    {
                    case "spring":
                        currentSeason = Season.Spring;
                        break;

                    case "summer":
                        currentSeason = Season.Summer;
                        break;

                    case "fall":
                        currentSeason = Season.Fall;
                        break;

                    case "winter":
                        currentSeason = Season.Winter;
                        break;
                    }

                    // load the texture through FAVR, not the content pipeline
                    spriteTexture = customAnimalSubType.Sprites.GetSpriteSheet(
                        isBaby: animalName.Contains("Baby"),
                        isHarvested: animalName.Contains("Sheared"),
                        season: currentSeason
                        );
                }
                else
                {
                    spriteTexture = contentManager.Load <Texture2D>(__instance.textureName.Value);
                }
            }
            else
            {
                spriteTexture = __instance.textureName.Value != null?contentManager.Load <Texture2D>(__instance.textureName.Value) : null;
            }

            loadedTexture = __instance.textureName.Value;

            typeof(AnimatedSprite).GetField("spriteTexture", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, spriteTexture);
            typeof(AnimatedSprite).GetField("loadedTexture", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, loadedTexture);

            if (spriteTexture == null)
            {
                return(false);
            }

            __instance.UpdateSourceRect();
            return(false);
        }