/// <summary>Apply the mod textures to the given menu, if applicable.</summary> /// <param name="menu">The menu to change.</param> /// <param name="isFarmExpansion">Whether the menu is the Farm Expansion build menu.</param> /// <param name="isPelicanFiber">Whether the menu is the Pelican Fiber build menu.</param> /// <param name="isGarage">Whether a blueprint is for a tractor garage.</param> /// <param name="reflection">The SMAPI API for accessing internal code.</param> public void ApplyTextures(IClickableMenu menu, bool isFarmExpansion, bool isPelicanFiber, Func <BluePrint, bool> isGarage, IReflectionHelper reflection) { // vanilla menu if (menu is CarpenterMenu carpenterMenu) { if (isGarage(carpenterMenu.CurrentBlueprint)) { Building building = reflection.GetField <Building>(carpenterMenu, "currentBuilding").GetValue(); if (building.texture.Value != this.GarageTexture && this.GarageTexture != null) { building.texture = new Lazy <Texture2D>(() => this.GarageTexture); } } return; } // Farm Expansion & Pelican Fiber menus if (isFarmExpansion || isPelicanFiber) { BluePrint currentBlueprint = reflection.GetProperty <BluePrint>(menu, isFarmExpansion ? "CurrentBlueprint" : "currentBlueprint").GetValue(); if (isGarage(currentBlueprint)) { Building building = reflection.GetField <Building>(menu, "currentBuilding").GetValue(); if (building.texture.Value != this.GarageTexture && this.GarageTexture != null) { building.texture = new Lazy <Texture2D>(() => this.GarageTexture); } } } }
/********* ** Public methods *********/ /// <summary>Construct an instance.</summary> /// <param name="contentPack">The content pack from which the patch was loaded.</param> /// <param name="name">The raw patch name to display in error messages.</param> /// <param name="patch">The patch instance from Content Patcher.</param> /// <param name="reflection">Simplifies access to private code.</param> /// <param name="reflection">Simplifies access to game content.</param> public PatchData(IContentPack contentPack, string name, object patch, IReflectionHelper reflection) { this.ContentPack = contentPack; this.Name = name; this.Reflection = reflection; this.LastChangedTickProperty = reflection.GetProperty <int>(patch, "LastChangedTick"); this.IsReadyProperty = reflection.GetProperty <bool>(patch, "IsReady"); this.IsAppliedProperty = reflection.GetProperty <bool>(patch, "IsApplied"); this.FromAssetProperty = reflection.GetProperty <string>(patch, "FromAsset"); this.TargetAssetProperty = reflection.GetProperty <IAssetName>(patch, "TargetAsset"); this.FromAreaProperty = reflection.GetField <object>(patch, "FromArea"); this.ToAreaProperty = reflection.GetField <object>(patch, "ToArea"); this.RefreshIfNeeded(); }
/********* ** Methods *********/ /// <summary>Get the key for a list asset entry.</summary> /// <typeparam name="TValue">The list value type.</typeparam> /// <param name="entity">The entity whose ID to fetch.</param> /// <param name="reflection">Simplifies dynamic access to game code.</param> public static string GetListAssetKey <TValue>(TValue entity, IReflectionHelper reflection) { switch (entity) { case ConcessionItemData entry: return(entry.ID.ToString()); case ConcessionTaste entry: return(entry.Name); case FishPondData entry: return(string.Join(",", entry.RequiredTags)); case MovieCharacterReaction entry: return(entry.NPCName); case RandomBundleData entry: return(entry.AreaName); case TailorItemRecipe entry: return(string.Join(",", entry.FirstItemTags) + "|" + string.Join(",", entry.SecondItemTags)); default: { var property = reflection.GetProperty <object>(entity, "ID", required: false); if (property != null) { return(property.GetValue()?.ToString()); } var field = reflection.GetField <object>(entity, "ID", required: false); if (field != null) { return(field.GetValue()?.ToString()); } throw new NotSupportedException($"No ID implementation for list asset value type {typeof(TValue).FullName}."); } } }