/// <summary>Runs once after all mods are loaded by SMAPI. Initializes file data, events, and Harmony patches.</summary> public override void Entry(IModHelper helper) { //initialize utilities AssetHelper.Initialize(helper); TileData.Monitor = Monitor; //load config.json ModConfig.Initialize(helper, Monitor); //initialize mod interactions helper.Events.GameLoop.GameLaunched += GameLoop_GameLaunched_InitializeModInteractions; //initialize Harmony and mod features Harmony harmony = new Harmony(ModManifest.UniqueID); //fish locations HarmonyPatch_FishLocations.ApplyPatch(harmony, Monitor); //custom order boards HarmonyPatch_CustomOrderBoards.ApplyPatch(harmony, Monitor); DisplayNewOrderExclamationPoint.Enable(helper, Monitor); Command_CustomBoard.Enable(helper, Monitor); //destroyable bushes HarmonyPatch_DestroyableBushes.ApplyPatch(harmony, Monitor); //bed placement HarmonyPatch_BedPlacement.ApplyPatch(harmony, Monitor); HarmonyPatch_PassOutSafely.ApplyPatch(harmony, Monitor); //kitchen features HarmonyPatch_ActionKitchen.ApplyPatch(harmony, Monitor); HarmonyPatch_AllowMiniFridges.ApplyPatch(harmony, Monitor); //water color WaterColor.Enable(helper, Monitor); }
/// <summary>Applies this Harmony patch to the game.</summary> /// <param name="harmony">The <see cref="Harmony"/> created with this mod's ID.</param> /// <param name="monitor">The <see cref="IMonitor"/> provided by SMAPI. Used for log messages.</param> public static void ApplyPatch(Harmony harmony, IMonitor monitor) { if (Applied) { return; } //store args Monitor = monitor; //initialize assets/properties AssetName = ModEntry.AssetPrefix + "FishLocations"; //create asset name TilePropertyName = ModEntry.PropertyPrefix + "FishLocations"; //create tile property name AssetHelper.SetDefault(AssetName, new Dictionary <string, FishLocationsData>()); //create a default instance for the asset //get methods to patch dynamically HashSet <Type> getFishingLocationMethods = new HashSet <Type>(); //every type with a unique GameLocation.getFishingLocation(Vector2) HashSet <Type> oceanCrabPotMethods = new HashSet <Type>(); //every type with a unique GameLocation.catchOceanCrabPotFishFromThisSpot(int, int) foreach (Type type in AccessTools.AllTypes()) //for every type { if (typeof(GameLocation).IsAssignableFrom(type)) //if this is a type of GameLocation { if (AccessTools.Method(type, nameof(GameLocation.getFishingLocation), new[] { typeof(Vector2) }) is MethodInfo fishing) //if this type has a fishing method { getFishingLocationMethods.Add(fishing.DeclaringType); //add the method's declaring type to the set } if (AccessTools.Method(type, nameof(GameLocation.catchOceanCrabPotFishFromThisSpot), new[] { typeof(int), typeof(int) }) is MethodInfo ocean) //if this type has a crab pot method { oceanCrabPotMethods.Add(ocean.DeclaringType); //add the method's declaring type to the set } } } //apply patches Monitor.Log($"Applying Harmony patch \"{nameof(HarmonyPatch_FishLocations)}\": postfixing every implementation of method \"GameLocation.getFishingLocation(Vector2)\".", LogLevel.Trace); foreach (var type in getFishingLocationMethods) //for each unique version of the fishing method { Monitor.VerboseLog($"Applying Harmony patch \"{nameof(HarmonyPatch_FishLocations)}\": postfixing method \"{type.Name}.getFishingLocation(Vector2)\"."); harmony.Patch( original: AccessTools.Method(type, nameof(GameLocation.getFishingLocation), new[] { typeof(Vector2) }), postfix: new HarmonyMethod(typeof(HarmonyPatch_FishLocations), nameof(Postfix_getFishingLocation)) ); } Monitor.Log($"Applying Harmony patch \"{nameof(HarmonyPatch_FishLocations)}\": postfixing every implementation of method \"GameLocation.catchOceanCrabPotFishFromThisSpot(int, int)\".", LogLevel.Trace); foreach (var type in oceanCrabPotMethods) //for each unique version of the crab pot method { Monitor.VerboseLog($"Applying Harmony patch \"{nameof(HarmonyPatch_FishLocations)}\": postfixing method \"{type.Name}.catchOceanCrabPotFishFromThisSpot(int, int)\"."); harmony.Patch( original: AccessTools.Method(type, nameof(GameLocation.catchOceanCrabPotFishFromThisSpot), new[] { typeof(int), typeof(int) }), postfix: new HarmonyMethod(typeof(HarmonyPatch_FishLocations), nameof(Postfix_catchOceanCrabPotFishFromThisSpot)) ); } Monitor.Log($"Applying Harmony patch \"{nameof(HarmonyPatch_FishLocations)}\": transpiling method \"CrabPot.DayUpdate(GameLocation)\".", LogLevel.Trace); harmony.Patch( original: AccessTools.Method(typeof(CrabPot), nameof(CrabPot.DayUpdate)), transpiler: new HarmonyMethod(typeof(HarmonyPatch_FishLocations), nameof(Transpiler_CrabPot_DayUpdate)) ); Monitor.Log($"Applying Harmony patch \"{nameof(HarmonyPatch_FishLocations)}\": prefixing method \"GameLocation.getFish(float, int, int, Farmer, double, Vector2, string)\".", LogLevel.Trace); harmony.Patch( original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.getFish)), prefix: new HarmonyMethod(typeof(HarmonyPatch_FishLocations), nameof(Prefix_getFish)) ); Applied = true; }