/*************************** ** Mod Injection Methods ** ***************************/ /// <summary>The mod entry point, called after the mod is first loaded.</summary> /// <param name="helper">Provides simplified APIs for writing mods.</param> public override void Entry(IModHelper helper) { try { myMonitor = this.Monitor; myInput = this.Helper.Input; str = this.Helper.Translation; Config = this.Helper.ReadConfig <ModConfig>(); helper.Events.GameLoop.GameLaunched += this.OnGameLaunched; helper.Events.Input.ButtonPressed += this.OnButtonPressed; helper.Events.Input.CursorMoved += this.OnCursorMoved; Harmony harmonyInstance = new Harmony(this.ModManifest.UniqueID); patchPrefix(harmonyInstance, typeof(Farmer), nameof(Farmer.useTool), typeof(ModEntry), nameof(ModEntry.Prefix_useTool)); patchPostfix(harmonyInstance, typeof(Farmer), nameof(Farmer.useTool), typeof(ModEntry), nameof(ModEntry.Postfix_useTool)); patchPrefix(harmonyInstance, typeof(Character), nameof(Character.GetToolLocation), typeof(ModEntry), nameof(ModEntry.Prefix_GetToolLocation), new Type[] { typeof(Vector2), typeof(bool) }); patchPrefix(harmonyInstance, typeof(Utility), nameof(Utility.isWithinTileWithLeeway), typeof(ModEntry), nameof(ModEntry.Prefix_isWithinTileWithLeeway)); patchPrefix(harmonyInstance, typeof(Game1), nameof(Game1.pressUseToolButton), typeof(ModEntry), nameof(ModEntry.Prefix_pressUseToolButton)); patchPrefix(harmonyInstance, typeof(Farmer), nameof(Farmer.draw), typeof(ModEntry), nameof(ModEntry.Prefix_Farmer_draw), new Type[] { typeof(SpriteBatch) }); patchPostfix(harmonyInstance, typeof(Farmer), nameof(Farmer.draw), typeof(ModEntry), nameof(ModEntry.Postfix_Farmer_draw), new Type[] { typeof(SpriteBatch) }); patchPrefix(harmonyInstance, typeof(SpriteBatch), nameof(SpriteBatch.Draw), typeof(ModEntry), nameof(ModEntry.Prefix_SpriteBatch_Draw), new Type[] { typeof(Texture2D), typeof(Vector2), typeof(Rectangle?), typeof(Color), typeof(float), typeof(Vector2), typeof(Vector2), typeof(SpriteEffects), typeof(float) }); patchPrefix(harmonyInstance, typeof(Utility), nameof(Utility.playerCanPlaceItemHere), typeof(ModEntry), nameof(ModEntry.Prefix_playerCanPlaceItemHere)); patchPostfix(harmonyInstance, typeof(Utility), nameof(Utility.playerCanPlaceItemHere), typeof(ModEntry), nameof(ModEntry.Postfix_playerCanPlaceItemHere)); patchPrefix(harmonyInstance, typeof(Utility), nameof(Utility.withinRadiusOfPlayer), typeof(ModEntry), nameof(ModEntry.Prefix_withinRadiusOfPlayer)); if (helper.ModRegistry.IsLoaded("Thor.HoeWaterDirection")) { patchPostfix(harmonyInstance, null, "", typeof(ModEntry), nameof(ModEntry.Postfix_HandleChangeDirectoryImpl), null, "Thor.Stardew.Mods.HoeWaterDirection.ModEntry:HandleChangeDirectoryImpl"); } } catch (Exception e) { Log("Error in mod setup: " + e.Message + Environment.NewLine + e.StackTrace); } }
/******************************** ** Config Menu Initialization ** ********************************/ /// <summary>Initializes menu for Generic Mod Config Menu on game launch.</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event data.</param> private void OnGameLaunched(object sender, GameLaunchedEventArgs e) { try { // Get Generic Mod Config Menu's API (if it's installed). var configMenu = Helper.ModRegistry.GetApi <IGenericModConfigMenuApi>("spacechase0.GenericModConfigMenu"); if (configMenu is null) { return; } // Register mod. configMenu.Register(mod: ModManifest, reset: () => Config = new ModConfig(), save: () => Helper.WriteConfig(Config)); // Add options. configMenu.AddSectionTitle(mod: ModManifest, text: () => str.Get("headerRanges")); List <string> rangeList = new List <string>(); rangeList.Add("1"); rangeList.Add("-1"); for (int i = 2; i <= 20; i++) { rangeList.Add(i.ToString()); } foreach (string subject in new string[] { "axe", "pickaxe", "hoe", "wateringCan", "seeds", "objects" }) { configMenu.AddTextOption( mod: ModManifest, name: () => str.Get("optionRangeName", new { subject = str.Get(subject + "ForRangeName") }), tooltip: () => str.Get("optionRangeTooltip", new { subject = str.Get(subject + "ForRangeTooltip") }), getValue: () => { int value = 1; switch (subject) { case "axe": value = Config.AxeRange; break; case "pickaxe": value = Config.PickaxeRange; break; case "hoe": value = Config.HoeRange; break; case "wateringCan": value = Config.WateringCanRange; break; case "seeds": value = Config.SeedRange; break; case "objects": value = Config.ObjectPlaceRange; break; } return(rangeList[value == 1? 0 // Default : value < 0? 1 // Unlimited : value]); // Extended }, setValue: strValue => { int value = 1; if (strValue.Equals(rangeList[0])) { value = 1; } else if (strValue.Equals(rangeList[1])) { value = -1; } else { for (int i = 2; i <= 20; i++) { if (strValue.Equals(rangeList[i])) { value = i; break; } } } switch (subject) { case "axe": Config.AxeRange = value; break; case "pickaxe": Config.PickaxeRange = value; break; case "hoe": Config.HoeRange = value; break; case "wateringCan": Config.WateringCanRange = value; break; case "seeds": Config.SeedRange = value; break; case "objects": Config.ObjectPlaceRange = value; break; } }, allowedValues: rangeList.ToArray(), formatAllowedValue: value => { if (value.Equals("1")) { return(str.Get("rangeDefault")); } else if (value.Equals("-1")) { return(str.Get("rangeUnlimited")); } else { return(str.Get("rangeExtended", new { tiles = value })); } } ); } configMenu.AddSectionTitle(mod: ModManifest, text: () => str.Get("headerUseOnTile")); foreach (string tool in new string[] { "axe", "pickaxe", "hoe" }) { configMenu.AddBoolOption( mod: ModManifest, name: () => str.Get("optionSelfUsabilityName", new { tool = str.Get(tool + "ForUsabilityName") }), tooltip: () => str.Get("optionSelfUsabilityTooltip", new { tool = str.Get(tool + "ForUsabilityTooltip") }), getValue: () => { switch (tool) { case "axe": return(Config.AxeUsableOnPlayerTile); case "pickaxe": return(Config.PickaxeUsableOnPlayerTile); case "hoe": return(Config.HoeUsableOnPlayerTile); } return(true); }, setValue: value => { switch (tool) { case "axe": Config.AxeUsableOnPlayerTile = value; break; case "pickaxe": Config.PickaxeUsableOnPlayerTile = value; break; case "hoe": Config.HoeUsableOnPlayerTile = value; break; } } ); } configMenu.AddSectionTitle(mod: ModManifest, text: () => str.Get("headerFaceClick")); configMenu.AddBoolOption( mod: ModManifest, name: () => str.Get("optionToolFaceClickName"), tooltip: () => str.Get("optionToolFaceClickTooltip"), getValue: () => Config.ToolAlwaysFaceClick, setValue: value => Config.ToolAlwaysFaceClick = value ); configMenu.AddBoolOption( mod: ModManifest, name: () => str.Get("optionWeaponFaceClickName"), tooltip: () => str.Get("optionWeaponFaceClickTooltip"), getValue: () => Config.WeaponAlwaysFaceClick, setValue: value => Config.WeaponAlwaysFaceClick = value ); configMenu.AddSectionTitle(mod: ModManifest, text: () => str.Get("headerMisc")); configMenu.AddTextOption( mod: ModManifest, name: () => str.Get("optionToolHitLocationName"), tooltip: () => str.Get("optionToolHitLocationTooltip"), getValue: () => Config.ToolHitLocationDisplay.ToString(), setValue: value => Config.ToolHitLocationDisplay = int.Parse(value), allowedValues: new string[] { "0", "1", "2" }, formatAllowedValue: value => { switch (value) { case "0": return(str.Get("locationLogicOriginal")); case "1": default: return(str.Get("locationLogicNew")); case "2": return(str.Get("locationLogicCombined")); } } ); configMenu.AddBoolOption( mod: ModManifest, name: () => str.Get("optionAllowRangedChargeName"), tooltip: () => str.Get("optionAllowRangedChargeTooltip"), getValue: () => Config.AllowRangedChargeEffects, setValue: value => Config.AllowRangedChargeEffects = value ); configMenu.AddBoolOption( mod: ModManifest, name: () => str.Get("optionOnClickOnlyName"), tooltip: () => str.Get("optionOnClickOnlyTooltip"), getValue: () => Config.CustomRangeOnClickOnly, setValue: value => Config.CustomRangeOnClickOnly = value ); } catch (Exception exception) { Log("Error setting up mod config menu (menu may not appear): " + exception.InnerException + Environment.NewLine + exception.StackTrace); } }