/********* ** Public 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) { // Read config ModConfig config = helper.ReadConfig <ModConfig>(); HEART_LEVEL_1 = config.heartLevel1; HEART_LEVEL_2 = config.heartLevel2; HEART_LEVEL_3 = config.heartLevel3; DISC_1 = config.disc1; DISC_2 = config.disc2; DISC_3 = config.disc3; BONUS_DISC = config.bonusDisc; CUSTOM_NPCS = config.customNPCs; // Security checks // Make sure that hearts are between 0 and 10, if not, assume standard values if (HEART_LEVEL_1 < 0 || HEART_LEVEL_1 > 10) { HEART_LEVEL_1 = 3; } if (HEART_LEVEL_2 < 0 || HEART_LEVEL_2 > 10) { HEART_LEVEL_2 = 7; } if (HEART_LEVEL_3 < 0 || HEART_LEVEL_3 > 10) { HEART_LEVEL_3 = 10; } // If relations between hearts are funky if (HEART_LEVEL_2 < HEART_LEVEL_1 || HEART_LEVEL_3 < HEART_LEVEL_2 || HEART_LEVEL_3 < HEART_LEVEL_1) { HEART_LEVEL_1 = 3; HEART_LEVEL_2 = 7; HEART_LEVEL_3 = 10; } // if discounts exceed 99% (100% crashes calculations for Krobus) if (DISC_1 > 99) { DISC_1 = 10; } if (DISC_2 > 99) { DISC_2 = 25; } if (DISC_3 > 99) { DISC_3 = 50; } if (BONUS_DISC > 99) { BONUS_DISC = 5; } // Asset editors for Robin's prices and mail helper.Content.AssetEditors.Add(new robinEditor()); helper.Content.AssetEditors.Add(new mailEditor(helper.Translation)); // When menus change (ie. a shop window is opened), go do the magic helper.Events.Display.MenuChanged += this.OnMenuChanged; // TODO: Find better time to do this helper.Events.GameLoop.DayStarted += this.OnDayStarted; helper.Events.GameLoop.Saving += this.OnSaving; }
public override void Entry(IModHelper helper) { TimeEvents.AfterDayStarted += Events_NewDay; treeOverhaulConfig = helper.ReadConfig <TreeOverhaulConfig>(); this.Monitor.Log(GetType().Name + " has loaded", LogLevel.Trace); }
/// <summary> /// Sets up the mod and adds commands to the console /// </summary> /// <param name="helper"></param> public override void Entry(IModHelper helper) { Config = helper.ReadConfig <ModConfig>(); challengeHelper = new ConfigChallengeHelper(Helper, Config, Monitor); CustomGuildChallengeMod.Instance = this; helper.Events.GameLoop.GameLaunched += OnGameLaunched; helper.ConsoleCommands.Add("player_setkills", "Update kill count for a monster type", (command, arguments) => { if (arguments.Length != 2) { Monitor.Log("Usage: player_setkills \"Monster Name\" integerKillCount ", LogLevel.Warn); } else if (!int.TryParse(arguments[1], out int killCount)) { Monitor.Log("Invalid kill count. Use an integer, like 50 or 100. Example: player_setkills \"Green Slime\" 100 ", LogLevel.Warn); } else { int before = Game1.player.stats.getMonstersKilled(arguments[0]); Game1.player.stats.specificMonstersKilled[arguments[0]] = killCount; Monitor.Log(arguments[0] + " kills changed from " + before + " to " + killCount, LogLevel.Info); } }); helper.ConsoleCommands.Add("player_getkills", "Get kill count for monster type", (command, arguments) => { if (arguments.Length == 0) { Monitor.Log("Usage: player_getkills \"Monster Name\"", LogLevel.Warn); } else { Monitor.Log(arguments[0] + "'s killed: " + Game1.player.stats.getMonstersKilled(arguments[0]), LogLevel.Info); } }); helper.ConsoleCommands.Add("player_giveitem", "See mod README for item number info", (command, arguments) => { int itemStack = 1; if (arguments.Length < 2) { Monitor.Log("Usage: player_giveitem itemType itemNumber [itemStackCount - optional]", LogLevel.Warn); } else if (!int.TryParse(arguments[0], out int itemType) || !int.TryParse(arguments[1], out int itemNumber) || (arguments.Length == 3 && !int.TryParse(arguments[2], out itemStack))) { Monitor.Log("Invalid item number. Use an integer, like 50 or 100. Example: player_giveitem 0 100 5", LogLevel.Warn); } else { var item = challengeHelper.customAdventureGuild.CreateReward(itemType, itemNumber, itemStack); if (item == null) { Monitor.Log("Invalid item numbers: " + itemType + " " + itemNumber + ". No item was spawned.", LogLevel.Warn); } else { Game1.player.addItemsByMenuIfNecessary(new Item[] { item }.ToList()); Monitor.Log("Item " + item.DisplayName + " given to player.", LogLevel.Info); } } }); helper.ConsoleCommands.Add("player_getallkills", "Display all kills for all monsters", (command, arguments) => { foreach (var item in Game1.player.stats.specificMonstersKilled) { Monitor.Log(item.Key + "'s killed: " + item.Value); } }); helper.ConsoleCommands.Add("toggle_monsterskilledinfo", "Turn debug statement of monster kill on or off", (command, arguments) => { Config.DebugMonsterKills = !Config.DebugMonsterKills; string status = Config.DebugMonsterKills ? "Enabled" : "Disabled"; Monitor.Log("Monsters killed debug info " + status); }); string log = Config.CustomChallengesEnabled ? "Initialized (" + Config.Challenges.Count + " custom challenges loaded)" : "Initialized (Vanilla challenges loaded)"; Monitor.Log(log, LogLevel.Debug); }
/********* ** Public 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) { Config = helper.ReadConfig <OmniFarmConfig>(); helper.Events.GameLoop.DayStarted += OnDayStarted; }
/********* ** Public 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) { this.Config = helper.ReadConfig <ModConfig>(); helper.Events.GameLoop.GameLaunched += this.OnGameLaunched; }
/// <summary> /// mod entry point /// </summary> /// <param name="helper"></param> public override void Entry(IModHelper helper) { Helper = helper; Console = Monitor; I18N = helper.Translation; Helper.Events.Display.MenuChanged += MenuChanged; ModData.Api.GetMod("GilarF.ModSettingsTab").OptionsChanged += (o, eventArgs) => ModData.Config = Helper.ReadConfig <TabConfig>(); Helper.Events.GameLoop.GameLaunched += (sender, args) => ModData.Init(); Helper.Events.GameLoop.GameLaunched += (sender, args) => LocalizedContentManager.OnLanguageChange += code => ModData.Init(); }
public override void Entry(IModHelper helper) { Events = helper.Events; if (AntiCheat.HasIllegalMods()) { Game1.quit = true; Console.Clear(); Monitor.Log("You have an illegal mod installed. Please uninstall it before using this mod.", LogLevel.Warn); if (AntiCheat.IllegalMod != null) { Monitor.Log($"- '{AntiCheat.IllegalMod}'", LogLevel.Warn); } Monitor.Log("Press any key to continue...", LogLevel.Warn); Console.ReadKey(); return; } var config = helper.ReadConfig <ModConfig>(); if (config == null) { config = new ModConfig(); helper.WriteConfig(config); } Config = config; BRGame = new Game(helper, config); Patch.PatchAll("ilyaki.battleroyale"); try { //Remove player limit var multiplayer = helper.Reflection.GetField <Multiplayer>(typeof(Game1), "multiplayer").GetValue(); multiplayer.playerLimit = config.PlayerLimit;//250 is the Galaxy limit (it's multiplied by two for some reason, so set 125) }catch (Exception) { Monitor.Log("Error setting player limit. The max is 125", LogLevel.Error); } helper.ConsoleCommands.Add("br_start", "Start the game. Alternative to pressing Right control", (c, a) => { if (Game1.IsServer) { BRGame.ServerStartGame(); } }); Events.Input.ButtonPressed += (o, e) => { if (Game1.IsServer && e.Button.TryGetKeyboard(out Keys key) && key == Keys.RightControl) { BRGame.ServerStartGame(); } if (e.Button.TryGetKeyboard(out Keys key2) && key2 == Keys.RightAlt) { var loc = Game1.player.currentLocation; int x = Game1.player.getTileX(); int y = Game1.player.getTileY(); Monitor.Log($"tile location={loc.Name}, pos=({x},{y})", LogLevel.Info); Monitor.Log($"my id : {Game1.player.UniqueMultiplayerID}", LogLevel.Info); Monitor.Log($"precise position = {Game1.player.Position}", LogLevel.Info); /*Game1.player.addItemToInventory(new StardewValley.Tools.Slingshot()); * Game1.player.addItemToInventory(new StardewValley.Tools.Slingshot(33)); * * var xd = new int[] { 388, 390, 378, 380, 384, 382, 386, 441 }; * foreach(int asdf in xd) * { * Game1.player.addItemToInventory(new StardewValley.Object(asdf, 100)); * }*/ } }; Events.GameLoop.UpdateTicked += (o, e) => BRGame?.Update(Game1.currentGameTime); Events.GameLoop.UpdateTicked += (o, e) => HitShaker.Update(Game1.currentGameTime); Events.GameLoop.UpdateTicked += (o, e) => SpectatorMode.Update(); //https://github.com/funny-snek/Always-On-Server-for-Multiplayer/blob/master/Always%20On%20Server/ModEntry.cs string currentSavedInviteCode = ""; Events.GameLoop.UpdateTicked += (o, e) => { if (e.IsMultipleOf(60 * 5) && Game1.server != null && Game1.options.enableServer == true && !string.Equals(currentSavedInviteCode, Game1.server.getInviteCode())) { currentSavedInviteCode = Game1.server.getInviteCode(); try { //helper.DirectoryPath StreamWriter sw = new StreamWriter("InviteCode.txt"); //Should be in the same folder as StardewModdingAPI.exe sw.WriteLine(currentSavedInviteCode); sw.Close(); } catch (Exception b) { Console.WriteLine("Exception writing InviteCode: " + b.Message); } } }; Events.Player.Warped += (o, e) => { if (e.NewLocation != null && (e.NewLocation is StardewValley.Locations.Woods || e.NewLocation.Name == "BugLand")) { e.NewLocation.characters.Clear(); } }; Events.Display.RenderingHud += (o, e) => { if (!SpectatorMode.InSpectatorMode) { Storm.Draw(Game1.spriteBatch); } }; Events.Display.Rendered += (o, e) => { if (SpectatorMode.InSpectatorMode) //Spectator mode can only see the storm when it is drawn above everything { Storm.Draw(Game1.spriteBatch); if (Game1.activeClickableMenu == null) { string message = "Spectating"; SpriteText.drawStringWithScrollBackground(Game1.spriteBatch, message, Game1.viewport.Width / 2 - SpriteText.getWidthOfString(message) / 2, 16, "", 1f, -1); } } }; helper.ConsoleCommands.Add("br_kick", "Kick a player. Usage: br_kick <player ID>", (a, b) => { if (!Game1.IsServer) { Monitor.Log("Need to be the server host", LogLevel.Info); } else if (b.Length != 1) { Monitor.Log("Need 1 argument", LogLevel.Info); } else if (!long.TryParse(b[0], out long x)) { Monitor.Log("Not a valid number", LogLevel.Info); } else { try { var f = Game1.getOnlineFarmers().First(p => p != Game1.player && p.UniqueMultiplayerID == x); NetworkUtility.KickPlayer(f, "You have been kicked by the host."); } catch (Exception) { Monitor.Log($"Could not find player with id {x}", LogLevel.Info); } } }); helper.ConsoleCommands.Add("br_setNumberOfPlayerSlots", "Sets the number of player slots. Usage: br_setNumberOfPlayerSlots <number of slots>", (a, b) => { if (!Game1.IsServer) { Monitor.Log("Need to be the server host", LogLevel.Info); } else if (b.Length != 1) { Monitor.Log("Need 1 argument", LogLevel.Info); } else if (!int.TryParse(b[0], out int n)) { Monitor.Log("Not a valid number", LogLevel.Info); } else { n = Math.Abs(n); var emptyCabins = Game1.getFarm().buildings.Where(z => z.daysOfConstructionLeft.Value <= 0 && z.indoors.Value is Cabin).ToArray(); if (n > emptyCabins.Length) { for (int i = 0; i < n - emptyCabins.Length; i++) { var blueprint = new BluePrint("Log Cabin"); var building = new Building(blueprint, new Vector2(-10000, 0)); Game1.getFarm().buildings.Add(building); try { foreach (var warp in building.indoors.Value.warps) { //warp.TargetName = "Forest"; Helper.Reflection.GetField <NetString>(warp, "targetName", true).SetValue(new NetString("Forest")); warp.TargetX = 100; warp.TargetY = 20; } } catch (Exception) { } } Monitor.Log($"Added {n - emptyCabins.Length} player slots", LogLevel.Info); } else if (n < emptyCabins.Length) { for (int i = 0; i < emptyCabins.Length - n; i++) { Game1.getFarm().buildings.Remove(emptyCabins[i]); } Monitor.Log($"Removed {emptyCabins.Length - n} player slots", LogLevel.Info); } else { Monitor.Log($"There are already {n} player slots", LogLevel.Info); } } }); }
public override void Entry(IModHelper helper) { Logger.monitor = Monitor; config = helper.ReadConfig <Config>(); Logger.debugMode = config.debug; var harmony = HarmonyInstance.Create("mabelsyrup.farmhouse"); FarmHouseStates.harmony = harmony; FarmHouseStates.modPath = helper.DirectoryPath; FarmHouseStates.spouseRooms = new Dictionary <string, int>(); FarmHouseStates.reflector = helper.Reflection; Image.Renderer.testRender = Image.Renderer.render(32, 32, 8).render(); //FarmHouse patches harmony.Patch( original: AccessTools.Method(typeof(FarmHouse), nameof(FarmHouse.getFloors)), postfix: new HarmonyMethod(AccessTools.Method(typeof(FarmHouse_getFloors_Patch), nameof(FarmHouse_getFloors_Patch.Postfix))) ); harmony.Patch( original: AccessTools.Method(typeof(FarmHouse), nameof(FarmHouse.getWalls)), postfix: new HarmonyMethod(AccessTools.Method(typeof(FarmHouse_getWalls_Patch), nameof(FarmHouse_getWalls_Patch.Postfix))) ); harmony.Patch( original: AccessTools.Method(typeof(FarmHouse), nameof(FarmHouse.setMapForUpgradeLevel)), prefix: new HarmonyMethod(AccessTools.Method(typeof(FarmHouse_setMapForUpgradeLevel_patch), nameof(FarmHouse_setMapForUpgradeLevel_patch.Prefix))) ); harmony.Patch( original: AccessTools.Method(typeof(FarmHouse), nameof(FarmHouse.loadSpouseRoom)), prefix: new HarmonyMethod(AccessTools.Method(typeof(FarmHouse_loadSpouseRoom_Patch), nameof(FarmHouse_loadSpouseRoom_Patch.Prefix))) ); harmony.Patch( original: AccessTools.Method(typeof(FarmHouse), nameof(FarmHouse.performTenMinuteUpdate)), prefix: new HarmonyMethod(AccessTools.Method(typeof(FarmHouse_performTenMinuteUpdate_patch), nameof(FarmHouse_performTenMinuteUpdate_patch.Prefix))) ); harmony.Patch( original: AccessTools.Method(typeof(FarmHouse), nameof(FarmHouse.showSpouseRoom)), prefix: new HarmonyMethod(AccessTools.Method(typeof(FarmHouse_showSpouseRoom_Patch), nameof(FarmHouse_showSpouseRoom_Patch.Prefix))) ); //harmony.Patch( // original: AccessTools.Method(typeof(FarmHouse), nameof(FarmHouse.getBedSpot)), // transpiler: new HarmonyMethod(AccessTools.Method(typeof(FarmHouse_showSpouseRoom_Patch), nameof(FarmHouse_getBedSpot_patch.Transpiler))) //); //harmony.Patch( // original: AccessTools.Method(typeof(FarmHouse), nameof(FarmHouse.getKitchenStandingSpot)), // prefix: new HarmonyMethod(AccessTools.Method(typeof(FarmHouse_getKitchenStandingSpot_Patch), nameof(FarmHouse_getKitchenStandingSpot_Patch.Prefix))) //); //DecoratableLocation patches harmony.Patch( original: helper.Reflection.GetMethod(new DecoratableLocation(), "doSetVisibleWallpaper").MethodInfo, prefix: new HarmonyMethod(AccessTools.Method(typeof(DecoratableLocation_doSetVisibleWallpaper_Patch), nameof(DecoratableLocation_doSetVisibleWallpaper_Patch.Prefix))) ); harmony.Patch( original: AccessTools.Method(typeof(DecoratableLocation), nameof(DecoratableLocation.setFloor)), prefix: new HarmonyMethod(AccessTools.Method(typeof(DecoratableLocation_setFloor_Patch), nameof(DecoratableLocation_setFloor_Patch.Prefix))) ); harmony.Patch( original: AccessTools.Method(typeof(DecoratableLocation), nameof(DecoratableLocation.setWallpaper)), prefix: new HarmonyMethod(AccessTools.Method(typeof(DecoratableLocation_setWallpaper_Patch), nameof(DecoratableLocation_setWallpaper_Patch.Prefix))) ); //harmony.Patch( // original: AccessTools.Method(typeof(DecoratableLocation), nameof(DecoratableLocation.resetForPlayerEntry)), // prefix: new HarmonyMethod(AccessTools.Method(typeof(DecoratableLocation_resetForPlayerEntry_Patch), nameof(DecoratableLocation_resetForPlayerEntry_Patch.Prefix))) //); harmony.Patch( original: AccessTools.Method(typeof(DecoratableLocation), nameof(DecoratableLocation.getFloors)), postfix: new HarmonyMethod(AccessTools.Method(typeof(DecoratableLocation_getFloors_Patch), nameof(DecoratableLocation_getFloors_Patch.Postfix))) ); harmony.Patch( original: AccessTools.Method(typeof(DecoratableLocation), nameof(DecoratableLocation.getWalls)), postfix: new HarmonyMethod(AccessTools.Method(typeof(DecoratableLocation_getWalls_Patch), nameof(DecoratableLocation_getWalls_Patch.Postfix))) ); harmony.Patch( original: helper.Reflection.GetMethod(new DecoratableLocation(), "doSetVisibleFloor").MethodInfo, prefix: new HarmonyMethod(AccessTools.Method(typeof(DecoratableLocation_doSetVisibleFloor_Patch), nameof(DecoratableLocation_doSetVisibleFloor_Patch.Prefix))) ); //Game1 Patches harmony.Patch( original: AccessTools.Method(typeof(Game1), nameof(Game1.getLocationRequest)), prefix: new HarmonyMethod(AccessTools.Method(typeof(Game1_getLocationRequest_PrePatch), nameof(Game1_getLocationRequest_PrePatch.Prefix))) ); harmony.Patch( original: AccessTools.Method(typeof(Game1), nameof(Game1.warpFarmer), new Type[] { typeof(LocationRequest), typeof(int), typeof(int), typeof(int) }), prefix: new HarmonyMethod(AccessTools.Method(typeof(Game1_warpFarmer_Patch), nameof(Game1_warpFarmer_Patch.Prefix))) ); harmony.Patch( original: helper.Reflection.GetMethod(typeof(Game1), "_newDayAfterFade").MethodInfo, transpiler: new HarmonyMethod(AccessTools.Method(typeof(Game1_newDayAfterFade_Patch), nameof(Game1_newDayAfterFade_Patch.Transpiler))) ); //Farm Patches harmony.Patch( original: helper.Reflection.GetMethod(new Farm(), "resetSharedState").MethodInfo, postfix: new HarmonyMethod(AccessTools.Method(typeof(Farm_resetSharedState_Patch), nameof(Farm_resetSharedState_Patch.Postfix))) ); harmony.Patch( original: helper.Reflection.GetMethod(new Farm(), "resetLocalState").MethodInfo, postfix: new HarmonyMethod(AccessTools.Method(typeof(Farm_resetLocalState_Patch), nameof(Farm_resetLocalState_Patch.Postfix))) ); harmony.Patch( original: AccessTools.Method(typeof(Farm), nameof(Farm.showShipment)), prefix: new HarmonyMethod(AccessTools.Method(typeof(Farm_showShipment_Patch), nameof(Farm_showShipment_Patch.Prefix))) ); harmony.Patch( original: AccessTools.Method(typeof(Farm), nameof(Farm.UpdateWhenCurrentLocation)), transpiler: new HarmonyMethod(AccessTools.Method(typeof(Farm_UpdateWhenCurrentLocation_Patch), nameof(Farm_UpdateWhenCurrentLocation_Patch.Transpiler))) ); harmony.Patch( original: AccessTools.Method(typeof(Farm), nameof(Farm.addSpouseOutdoorArea)), prefix: new HarmonyMethod(AccessTools.Method(typeof(Farm_addSpouseOutdoorArea_Patch), nameof(Farm_addSpouseOutdoorArea_Patch.Prefix))) ); //Shed Patches harmony.Patch( original: AccessTools.Method(typeof(Shed), nameof(Shed.getFloors)), postfix: new HarmonyMethod(AccessTools.Method(typeof(Shed_getFloors_Patch), nameof(Shed_getFloors_Patch.Postfix))) ); harmony.Patch( original: AccessTools.Method(typeof(Shed), nameof(Shed.getWalls)), postfix: new HarmonyMethod(AccessTools.Method(typeof(Shed_getWalls_Patch), nameof(Shed_getWalls_Patch.Postfix))) ); //GameLocation Patches harmony.Patch( original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.performAction)), prefix: new HarmonyMethod(AccessTools.Method(typeof(GameLocation_performAction_Patch), nameof(GameLocation_performAction_Patch.Prefix))) ); harmony.Patch( original: helper.Reflection.GetMethod(new GameLocation(), "_updateAmbientLighting").MethodInfo, prefix: new HarmonyMethod(AccessTools.Method(typeof(GameLocation__updateAmbientLighting_Patch), nameof(GameLocation__updateAmbientLighting_Patch.Prefix))) ); //harmony.Patch( // original: helper.Reflection.GetMethod(new GameLocation(), "carpenters").MethodInfo, // transpiler: new HarmonyMethod(AccessTools.Method(typeof(GameLocation_carpenters_Patch), nameof(GameLocation_carpenters_Patch.Transpiler))) //); //harmony.Patch( // original: helper.Reflection.GetMethod(new GameLocation(), "houseUpgradeAccept").MethodInfo, // prefix: new HarmonyMethod(AccessTools.Method(typeof(GameLocation_houseUpgradeAccept_Patch), nameof(GameLocation_houseUpgradeAccept_Patch.Prefix))) //); //harmony.Patch( // original: helper.Reflection.GetMethod(new GameLocation(), "houseUpgradeOffer").MethodInfo, // prefix: new HarmonyMethod(AccessTools.Method(typeof(GameLocation_houseUpgradeOffer_Patch), nameof(GameLocation_houseUpgradeOffer_Patch.Prefix))) //); //NPC patches harmony.Patch( original: AccessTools.Method(typeof(NPC), nameof(NPC.marriageDuties)), transpiler: new HarmonyMethod(AccessTools.Method(typeof(NPC_marriageDuties_Patch), nameof(NPC_marriageDuties_Patch.Transpiler))) ); harmony.Patch( original: AccessTools.Method(typeof(NPC), nameof(NPC.setUpForOutdoorPatioActivity)), prefix: new HarmonyMethod(AccessTools.Method(typeof(NPC_setUpForOutdoorPatioActivity_Patch), nameof(NPC_setUpForOutdoorPatioActivity_Patch.Prefix))) ); harmony.Patch( original: helper.Reflection.GetMethod(new NPC(), "doPlaySpousePatioAnimation").MethodInfo, prefix: new HarmonyMethod(AccessTools.Method(typeof(NPC_doPlaySpousePatioAnimation_Patch), nameof(NPC_doPlaySpousePatioAnimation_Patch.Prefix))) ); //Wand patches harmony.Patch( original: helper.Reflection.GetMethod(new StardewValley.Tools.Wand(), "wandWarpForReal").MethodInfo, prefix: new HarmonyMethod(AccessTools.Method(typeof(Wand_wandWarpForReal_Patch), nameof(Wand_wandWarpForReal_Patch.Prefix))) ); //Object patches harmony.Patch( original: helper.Reflection.GetMethod(new StardewValley.Object(), "totemWarpForReal").MethodInfo, prefix: new HarmonyMethod(AccessTools.Method(typeof(Object_totemWarpForReal_Patch), nameof(Object_totemWarpForReal_Patch.Prefix))) ); //Wallpaper patches harmony.Patch( original: AccessTools.Method(typeof(StardewValley.Objects.Wallpaper), nameof(StardewValley.Objects.Wallpaper.placementAction)), prefix: new HarmonyMethod(AccessTools.Method(typeof(Wallpaper_placementAction_Patch), nameof(Wallpaper_placementAction_Patch.Prefix))) ); //Event patches harmony.Patch( original: helper.Reflection.GetMethod(new StardewValley.Event(), "setUpCharacters").MethodInfo, prefix: new HarmonyMethod(AccessTools.Method(typeof(Event_setUpCharacters_Patch), nameof(Event_setUpCharacters_Patch.Prefix))), transpiler: new HarmonyMethod(AccessTools.Method(typeof(Event_setUpCharacters_Patch), nameof(Event_setUpCharacters_Patch.Transpiler))) ); //Pet patches harmony.Patch( original: AccessTools.Method(typeof(Pet), nameof(Pet.warpToFarmHouse)), postfix: new HarmonyMethod(AccessTools.Method(typeof(Pet_warpToFarmHouse_Patch), nameof(Pet_warpToFarmHouse_Patch.Postfix))) ); helper.Events.GameLoop.DayStarted += newDay; helper.Events.World.NpcListChanged += npcListChanged; helper.Events.Player.Warped += fixPlayerWarps; helper.Events.GameLoop.GameLaunched += GameLoop_GameLaunched; helper.Events.GameLoop.SaveLoaded += saveLoaded; helper.Events.Input.ButtonPressed += buttonPressed; helper.Events.Display.RenderedWorld += Display_RenderedWorld; FarmHouseStates.loader = helper.Content; //helper.Events.Display.RenderedHud += drawStuff; }
/// <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) { ModMonitor = Monitor; #if DEBUG //Logger.InitLogger(helper.DirectoryPath + "\\logfile.txt", false, Monitor); #endif #region Harmony Patches ModPatchControl patchControl = new ModPatchControl(helper); patchControl.PatchList.Add(new MultiplayerPatch.ProcessIncomingMessagePatch()); patchControl.PatchList.Add(new MultiplayerPatch.AddPlayerPatch()); patchControl.PatchList.Add(new MultiplayerPatch.PlayerDisconnectedPatch()); //PatchControl.PatchList.Add(new MultiplayerPatch.SendChatMessagePatch()); //PatchControl.PatchList.Add(new MultiplayerPatch.ReceiveChatMessagePatch()); patchControl.PatchList.Add(new Game1Patch.DrawOverlaysPatch()); /* * PatchControl.PatchList.Add(new MultiplayerPatch.ReceivePlayerIntroductionPatch()); */ IClassPatch receiveChatMessage = null; IClassPatch addMessagePatch = null; if (helper.ModRegistry.IsLoaded("cat.chatcommands")) { receiveChatMessage = new ModSupportPatch.ChatCommands_ReceiveChatMessage(); addMessagePatch = new ModSupportPatch.ChatCommands_AddMessagePatch(); patchControl.PatchList.Add(new ModSupportPatch.ChatCommands_AddConsoleMessagePatch(helper.Reflection)); } patchControl.PatchList.Add(receiveChatMessage ?? new ChatBoxPatch.ReceiveChatMessagePatch()); patchControl.PatchList.Add(addMessagePatch ?? new ChatBoxPatch.AddMessagePatch()); patchControl.ApplyPatch(); #endregion this.Monitor.Log("Loading mod config...", LogLevel.Trace); this.config = helper.ReadConfig <ModConfig>(); #if !DEBUG || TRUE #if DEBUG ModLogger = new Logger(Path.Combine(helper.DirectoryPath, "logfile.txt"), false, Monitor); #endif this.Monitor.Log("Loading mod data...", LogLevel.Trace); this.modData = this.Helper.Data.ReadJsonFile <ModData>(ModPaths.Data.Path); if (this.modData == null) { this.Monitor.Log("Mod data file not found. (harmless info)", LogLevel.Trace); this.modData = new ModData(helper, config.ImageExtensions) { WatchedPaths = new List <string>() { ModPaths.Assets.InputFolder } }; } else { modData.FileExtensionsFilter = config.ImageExtensions; modData.ModHelper = helper; } emojiAssetsLoader = new EmojiAssetsLoader(helper, modData, config, EmojiMenu.EMOJI_SIZE); #else this.Monitor.Log("Loading debug data file...", LogLevel.Trace); this.modDebugData = this.Helper.Data.ReadJsonFile <ModDebugData>("debugData.json") ?? new ModDebugData(); //string configPath = Path.Combine(Constants.ExecutionPath, "Mods", "SkipIntro", "config.json"); //string json = File.ReadAllText(configPath); //dynamic jsonObj = JsonConvert.DeserializeObject(json); //if((string)(jsonObj["SkipTo"]) == "HostCoop") { // jsonObj["SkipTo"] = "JoinCoop"; // modDebugData.IsHost = true; //} else { // jsonObj["SkipTo"] = "HostCoop"; // modDebugData.IsHost = false; //} //string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Formatting.Indented); //File.WriteAllText(configPath, output); if (modDebugData.ActAsHost()) { this.Helper.Data.WriteJsonFile("debugData.json", modDebugData); Monitor.Log($"====> HOST <===="); ModLogger = new Logger(Path.Combine(helper.DirectoryPath, "logfile.txt"), false, Monitor); this.Monitor.Log("Loading mod data...", LogLevel.Trace); this.modData = this.Helper.Data.ReadJsonFile <ModData>(ModPaths.Data.Path); if (this.modData == null) { this.Monitor.Log("Mod data file not found. (harmless info)", LogLevel.Trace); this.modData = new ModData(helper, config.ImageExtensions) { WatchedPaths = new List <string>() { ModPaths.Assets.InputFolder } }; } else { modData.FileExtensionsFilter = config.ImageExtensions; modData.ModHelper = helper; } emojiAssetsLoader = new EmojiAssetsLoader(helper, modData, config, EmojiMenu.EMOJI_SIZE); } else { this.Helper.Data.WriteJsonFile("debugData.json", modDebugData); Monitor.Log($"====> CLIENT <===="); ModLogger = new Logger(Path.Combine(helper.DirectoryPath, "logfileClient.txt"), false, Monitor); ModPaths.Assets.InputFolder = ModPaths.Assets.InputFolder + "CLIENT"; ModPaths.Assets.Folder = ModPaths.Assets.Folder + "CLIENT"; ModPaths.Data.Path = "dataCLIENT.json"; this.Monitor.Log("Loading mod data...", LogLevel.Trace); this.modData = this.Helper.Data.ReadJsonFile <ModData>(ModPaths.Data.Path); if (this.modData == null) { this.Monitor.Log("Mod data file not found. (harmless info)", LogLevel.Trace); this.modData = new ModData(helper, config.ImageExtensions) { WatchedPaths = new List <string>() { ModPaths.Assets.InputFolder } }; } else { modData.FileExtensionsFilter = config.ImageExtensions; modData.ModHelper = helper; } emojiAssetsLoader = new EmojiAssetsLoader(helper, modData, config, EmojiMenu.EMOJI_SIZE); } #endif helper.Content.AssetLoaders.Add(emojiAssetsLoader); //helper.ConsoleCommands.Add("reload_emojis", "Reload the game emojis with the new ones found in the mod folder.", this.ReloadEmojis); helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; }
public static T ReadConfig <T>() where T : class, new() { return(_helper.ReadConfig <T>()); }
public ModOptionsPageHandler(IModHelper helper, IDictionary <String, String> options) { _options = options; helper.Events.Display.MenuChanged += ToggleModOptions; _helper = helper; ModConfig modConfig = _helper.ReadConfig <ModConfig>(); _luckOfDay = new LuckOfDay(helper); _showBirthdayIcon = new ShowBirthdayIcon(helper); _showAccurateHearts = new ShowAccurateHearts(helper.Events); _locationOfTownsfolk = new LocationOfTownsfolk(helper, _options); _showWhenAnimalNeedsPet = new ShowWhenAnimalNeedsPet(helper); _showCalendarAndBillboardOnGameMenuButton = new ShowCalendarAndBillboardOnGameMenuButton(helper); _showScarecrowAndSprinklerRange = new ShowItemEffectRanges(modConfig, helper.Events); _experienceBar = new ExperienceBar(helper); _showItemHoverInformation = new ShowItemHoverInformation(helper.Events); _shopHarvestPrices = new ShopHarvestPrices(helper); _showQueenOfSauceIcon = new ShowQueenOfSauceIcon(helper); _showTravelingMerchant = new ShowTravelingMerchant(helper); _showCropAndBarrelTime = new ShowCropAndBarrelTime(helper); _showToolUpgradeStatus = new ShowToolUpgradeStatus(helper); _elementsToDispose = new List <IDisposable>() { _luckOfDay, _showBirthdayIcon, _showAccurateHearts, _locationOfTownsfolk, _showWhenAnimalNeedsPet, _showCalendarAndBillboardOnGameMenuButton, _showCropAndBarrelTime, _experienceBar, _showItemHoverInformation, _showTravelingMerchant, _shopHarvestPrices, _showQueenOfSauceIcon, _showToolUpgradeStatus }; int whichOption = 1; Version thisVersion = Assembly.GetAssembly(this.GetType()).GetName().Version; _optionsElements.Add(new ModOptionsElement("UI Info Suite v" + thisVersion.Major + "." + thisVersion.Minor + "." + thisVersion.Build)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowLuckIcon), whichOption++, _luckOfDay.Toggle, _options, OptionKeys.ShowLuckIcon)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowLevelUpAnimation), whichOption++, _experienceBar.ToggleLevelUpAnimation, _options, OptionKeys.ShowLevelUpAnimation)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowExperienceBar), whichOption++, _experienceBar.ToggleShowExperienceBar, _options, OptionKeys.ShowExperienceBar)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.AllowExperienceBarToFadeOut), whichOption++, _experienceBar.ToggleExperienceBarFade, _options, OptionKeys.AllowExperienceBarToFadeOut)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowExperienceGain), whichOption++, _experienceBar.ToggleShowExperienceGain, _options, OptionKeys.ShowExperienceGain)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowLocationOfTownsPeople), whichOption++, _locationOfTownsfolk.ToggleShowNPCLocationsOnMap, _options, OptionKeys.ShowLocationOfTownsPeople)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowBirthdayIcon), whichOption++, _showBirthdayIcon.ToggleOption, _options, OptionKeys.ShowBirthdayIcon)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowHeartFills), whichOption++, _showAccurateHearts.ToggleOption, _options, OptionKeys.ShowHeartFills)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowAnimalsNeedPets), whichOption++, _showWhenAnimalNeedsPet.ToggleOption, _options, OptionKeys.ShowAnimalsNeedPets)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.DisplayCalendarAndBillboard), whichOption++, _showCalendarAndBillboardOnGameMenuButton.ToggleOption, _options, OptionKeys.DisplayCalendarAndBillboard)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowCropAndBarrelTooltip), whichOption++, _showCropAndBarrelTime.ToggleOption, _options, OptionKeys.ShowCropAndBarrelTooltip)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowItemEffectRanges), whichOption++, _showScarecrowAndSprinklerRange.ToggleOption, _options, OptionKeys.ShowItemEffectRanges)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowExtraItemInformation), whichOption++, _showItemHoverInformation.ToggleOption, _options, OptionKeys.ShowExtraItemInformation)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowTravelingMerchant), whichOption++, _showTravelingMerchant.ToggleOption, _options, OptionKeys.ShowTravelingMerchant)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowHarvestPricesInShop), whichOption++, _shopHarvestPrices.ToggleOption, _options, OptionKeys.ShowHarvestPricesInShop)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowWhenNewRecipesAreAvailable), whichOption++, _showQueenOfSauceIcon.ToggleOption, _options, OptionKeys.ShowWhenNewRecipesAreAvailable)); _optionsElements.Add(new ModOptionsCheckbox(_helper.SafeGetString(OptionKeys.ShowToolUpgradeStatus), whichOption++, _showToolUpgradeStatus.ToggleOption, _options, OptionKeys.ShowToolUpgradeStatus)); }
public override void Entry(IModHelper helper) { _config = helper.ReadConfig <Config>(); helper.Events.Input.ButtonPressed += OnButtonPress; }
public override void Entry(IModHelper helper) { _config = helper.ReadConfig <CmoConfig>(); //Events helper.Events.Input.ButtonPressed += ButtonPressed; //Make sure Customized Crystalarium mod isn't installed. if (helper.ModRegistry.IsLoaded("DIGUS.CustomCrystalariumMod")) { Monitor.Log("Due to incompatability issues with Customizable Crystalarium, the Crystalarium has been turned off for this mod. This way you can use both at the same time.", LogLevel.Info); _config.Machines.Crystalarium.CustomCrystalariumEnabled = false; } //Harmony Original Code credit goes to Cat from the SDV Modding Discord, I modified his Harmony code. try { HarmonyInstance Harmony = HarmonyInstance.Create("mizzion.configuremachineOutputs"); //Now we set up the patches, will use a dictionary, just in case I need to expand later. Idea of using Harmony this way came from Cat#2506's mod from the SDV discord IDictionary <string, Type> replacements = new Dictionary <string, Type> { [nameof(SObject.performObjectDropInAction)] = typeof(PerformObjectDropInActionPatch), [nameof(SObject.checkForAction)] = typeof(CheckForActionPatch) }; IList <Type> typesToPatch = new List <Type>(); typesToPatch.Add(typeof(SObject)); //Let's try to get CFR Machines working. //Still not sure how I want to do the input/Outputs...... if (helper.ModRegistry.IsLoaded("Platonymous.CustomFarming")) { try { //typesToPatch.Add(Type.GetType("CustomFarmingRedux.CustomMachine, CustomFarmingRedux")); Monitor.Log("CFR Support should be active(Soon).", LogLevel.Trace); } catch (Exception e) { this.Monitor.Log("Failed to add support for CFR Machines.", LogLevel.Trace); this.Monitor.Log(e.ToString(), LogLevel.Debug); } } //Go through and set up the patching foreach (Type t in typesToPatch) { foreach (KeyValuePair <string, Type> replacement in replacements) { MethodInfo original = t.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(m => m.Name == replacement.Key); MethodInfo prefix = replacement.Value .GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(item => item.Name == "Prefix"); MethodInfo postfix = replacement.Value .GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(item => item.Name == "Postfix"); //this.Monitor.Log($"Patching {original} with {prefix} {postfix}", LogLevel.Trace); this.Monitor.Log($"Patching {original} with {prefix} {postfix}", LogLevel.Trace); Harmony.Patch(original, prefix == null ? null : new HarmonyMethod(prefix), postfix == null ? null : new HarmonyMethod(postfix)); } } } catch (Exception ex) { Monitor.Log($"There was an error setting up harmony.\n {ex}", LogLevel.Trace); } //Initialize so we can get the configs. podia = new PerformObjectDropInActionPatch(Monitor, _config); cfa = new CheckForActionPatch(Monitor, _config); //pfp = new PerformLightningPatch(Monitor, _config); }
public override void Entry(IModHelper helper) { _config = helper.ReadConfig <ModConfig>(); InputEvents.ButtonPressed += InputEvents_ButtonPressed; }
/********* ** Public 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) { this.Config = helper.ReadConfig <ModConfig>(); ControlEvents.KeyPressed += this.ControlEvents_KeyPressed; }
public override void Entry(IModHelper helper) { config = helper.ReadConfig <C>(); base.Entry(helper); }
/********* ** Public methods *********/ /// <summary>The mod entry point, called after the mod is first loaded.</summary> /// <param name="helper">Provides methods for interacting with the mod directory, such as read/writing a config file or custom JSON files.</param> public override void Entry(IModHelper helper) { this.Config = helper.ReadConfig <ModConfig>(); MenuEvents.MenuChanged += this.MenuEvents_MenuChanged; }
public override void Entry(IModHelper helper) { ModHelper = helper; Util.Helper = helper; Util.Monitor = Monitor; Util.ModInstance = this; Conf = helper.ReadConfig <Config>(); IModEvents Events = Helper.Events; Events.Input.ButtonPressed += OnButtonPressed; Events.GameLoop.UpdateTicked += OnGameUpdateEvent; Events.Display.RenderedHud += OnPostRenderHud; Events.Display.RenderedActiveMenu += OnPostRenderGui; Events.Display.MenuChanged += OnMenuChanged; Events.GameLoop.Saving += OnBeforeSave; Events.GameLoop.DayStarted += OnDayStarted; Conf.CpuThresholdFishing = Util.Cap(Conf.CpuThresholdFishing, 0, 0.5f); Conf.HealthToEatRatio = Util.Cap(Conf.HealthToEatRatio, 0.1f, 0.8f); Conf.StaminaToEatRatio = Util.Cap(Conf.StaminaToEatRatio, 0.1f, 0.8f); Conf.AutoCollectRadius = (int)Util.Cap(Conf.AutoCollectRadius, 1, 3); Conf.AutoHarvestRadius = (int)Util.Cap(Conf.AutoHarvestRadius, 1, 3); Conf.AutoPetRadius = (int)Util.Cap(Conf.AutoPetRadius, 1, 3); Conf.AutoWaterRadius = (int)Util.Cap(Conf.AutoWaterRadius, 1, 3); Conf.AutoDigRadius = (int)Util.Cap(Conf.AutoDigRadius, 1, 3); Conf.AutoShakeRadius = (int)Util.Cap(Conf.AutoShakeRadius, 1, 3); Conf.MachineRadius = (int)Util.Cap(Conf.MachineRadius, 1, 3); Conf.RadiusCraftingFromChests = (int)Util.Cap(Conf.RadiusCraftingFromChests, 1, 5); Conf.IdleTimeout = (int)Util.Cap(Conf.IdleTimeout, 1, 300); Conf.ScavengingRadius = (int)Util.Cap(Conf.ScavengingRadius, 1, 3); Conf.AnimalHarvestRadius = (int)Util.Cap(Conf.AnimalHarvestRadius, 1, 3); if (ModChecker.IsCoGLoaded(helper)) { Monitor.Log("CasksOnGround detected."); IsCoGOn = true; } if (ModChecker.IsCALoaded(helper)) { Monitor.Log("CasksAnywhere detected."); IsCAOn = true; } if (ModChecker.IsCCLoaded(helper)) { Monitor.Log("Convenient Chests detected. JOE's CraftingFromChests feature will be disabled and won't patch the game."); Conf.CraftingFromChests = false; IsCCOn = true; } else { HarmonyPatcher.Init(); } helper.WriteConfig(Conf); MineIcons.Init(helper); }
public override void Entry(IModHelper helper) { this._config = helper.ReadConfig <ModConfig>(); Helper.Events.Input.ButtonPressed += new EventHandler <ButtonPressedEventArgs>(this.Input_ButtonPressed); }
/// <summary> /// The mod entry point, called after the mod is first loaded. /// Loads config file and adds method to the event of starting a new day. /// </summary> /// <param name="helper">Provides simplified APIs for writing mods.</param> public override void Entry(IModHelper helper) { helper.Events.GameLoop.DayStarted += OnDayStarted; treeOverhaulConfig = helper.ReadConfig <TreeOverhaulConfig>(); }
public DataLoader(IModHelper helper) { Helper = helper; I18N = helper.Translation; ModConfig = helper.ReadConfig <ModConfig>(); CraftingData = DataLoader.Helper.Data.ReadJsonFile <CraftingData>("data\\CraftingRecipes.json") ?? new CraftingData(); DataLoader.Helper.Data.WriteJsonFile("data\\CraftingRecipes.json", CraftingData); var editors = Helper.Content.AssetEditors; editors.Add(this); if (!ModConfig.DisableIridiumQualityFish) { MailDao.SaveLetter ( new Letter ( "IridiumQualityFishWithWildBait" , I18N.Get("IridiumQualityFishWithWildBait.Letter") , (l) => !Game1.player.mailReceived.Contains(l.Id) && Game1.player.craftingRecipes.ContainsKey("Wild Bait") && Game1.player.FishingLevel >= 4 , (l) => Game1.player.mailReceived.Add(l.Id) ) ); } AddLetter(BaitTackle.EverlastingBait, (l) => Game1.player.FishingLevel >= 10 && GetNpcFriendship("Willy") >= 10 * 250 && !Game1.player.craftingRecipes.ContainsKey(BaitTackle.EverlastingBait.GetDescription())); AddLetter(BaitTackle.EverlastingWildBait, (l) => Game1.player.craftingRecipes.ContainsKey("Wild Bait") && Game1.player.craftingRecipes.ContainsKey(BaitTackle.EverlastingBait.GetDescription()) && Game1.player.craftingRecipes[BaitTackle.EverlastingBait.GetDescription()] > 0 && GetNpcFriendship("Linus") >= 10 * 250 && !Game1.player.craftingRecipes.ContainsKey(BaitTackle.EverlastingWildBait.GetDescription())); AddLetter(BaitTackle.EverlastingMagnet, (l) => Game1.player.FishingLevel >= 10 && GetNpcFriendship("Wizard") >= 10 * 250 && !Game1.player.craftingRecipes.ContainsKey(BaitTackle.EverlastingMagnet.GetDescription()), null, 2); MailDao.SaveLetter ( new Letter ( "UnbreakableTackleIntroduction" , I18N.Get("UnbreakableTackleIntroduction.Letter") , (l) => !Game1.player.mailReceived.Contains(l.Id) && Game1.player.achievements.Contains(21) && Game1.player.FishingLevel >= 8 && GetNpcFriendship("Willy") >= 6 * 250 && GetNpcFriendship("Clint") >= 6 * 250 , (l) => Game1.player.mailReceived.Add(l.Id) ) ); AddLetter ( BaitTackle.UnbreakableSpinner , (l) => Game1.player.achievements.Contains(21) && Game1.player.FishingLevel >= 8 && GetNpcFriendship("Willy") >= 6 * 250 && GetNpcFriendship("Clint") >= 6 * 250 && !Game1.player.craftingRecipes.ContainsKey(BaitTackle.UnbreakableSpinner.GetDescription()) , (l) => LoadTackleQuest(BaitTackle.UnbreakableSpinner) ); AddLetter ( BaitTackle.UnbreakableLeadBobber , (l) => Game1.player.mailReceived.Contains(BaitTackle.UnbreakableSpinner.GetQuestName()) && !Game1.player.craftingRecipes.ContainsKey(BaitTackle.UnbreakableLeadBobber.GetDescription()) , (l) => LoadTackleQuest(BaitTackle.UnbreakableLeadBobber) ); AddLetter ( BaitTackle.UnbreakableTrapBobber , (l) => Game1.player.mailReceived.Contains(BaitTackle.UnbreakableLeadBobber.GetQuestName()) && !Game1.player.craftingRecipes.ContainsKey(BaitTackle.UnbreakableTrapBobber.GetDescription()) , (l) => LoadTackleQuest(BaitTackle.UnbreakableTrapBobber) ); AddLetter ( BaitTackle.UnbreakableCorkBobber , (l) => Game1.player.mailReceived.Contains(BaitTackle.UnbreakableTrapBobber.GetQuestName()) && !Game1.player.craftingRecipes.ContainsKey(BaitTackle.UnbreakableCorkBobber.GetDescription()) , (l) => LoadTackleQuest(BaitTackle.UnbreakableCorkBobber) ); AddLetter ( BaitTackle.UnbreakableTreasureHunter , (l) => Game1.player.mailReceived.Contains(BaitTackle.UnbreakableCorkBobber.GetQuestName()) && !Game1.player.craftingRecipes.ContainsKey(BaitTackle.UnbreakableTreasureHunter.GetDescription()) , (l) => LoadTackleQuest(BaitTackle.UnbreakableTreasureHunter) ); AddLetter ( BaitTackle.UnbreakableBarbedHook , (l) => Game1.player.mailReceived.Contains(BaitTackle.UnbreakableTreasureHunter.GetQuestName()) && !Game1.player.craftingRecipes.ContainsKey(BaitTackle.UnbreakableBarbedHook.GetDescription()) , (l) => LoadTackleQuest(BaitTackle.UnbreakableBarbedHook) ); AddLetter ( BaitTackle.UnbreakableDressedSpinner , (l) => Game1.player.mailReceived.Contains(BaitTackle.UnbreakableBarbedHook.GetQuestName()) && !Game1.player.craftingRecipes.ContainsKey(BaitTackle.UnbreakableDressedSpinner.GetDescription()) , (l) => LoadTackleQuest(BaitTackle.UnbreakableDressedSpinner) ); MailDao.SaveLetter ( new Letter ( "UnbreakableTackleReward" , I18N.Get("UnbreakableTackleReward.Letter") , new List <Item> { new StardewValley.Object(74, 1) } , (l) => Game1.player.mailReceived.Contains(BaitTackle.UnbreakableDressedSpinner.GetQuestName()) && !Game1.player.mailReceived.Contains(l.Id) , (l) => { Game1.player.mailReceived.Add(l.Id); } ) ); }
public override void Entry(IModHelper helper) { config = helper.ReadConfig <Config>(); helper.Content.AssetEditors.Add(new Ghostify(helper)); }
public override void Entry(IModHelper helper) { GameEvents.UpdateTick += this.GameEvents_UpdateTick; this.Config = helper.ReadConfig <Config>(); }
public override void Entry(IModHelper helper) { Utils.Reflection = helper.Reflection; if (helper.ModRegistry.IsLoaded("cat.fruittreesanywhere")) { this.Monitor.Log("You have both this mod, and the old version ('Fruit Trees Anywhere') installed!", LogLevel.Error); this.Monitor.Log( "In order for this mod to work properly, you need to delete the FruitTreesAnywhere folder!", LogLevel.Error); this.Monitor.Log( "This mod does everything the old version does and fruit tree junimo harvesting, so please delete FruitTreesAnywhere!", LogLevel.Error); SaveEvents.AfterLoad += this.ShowErrorMessage; return; } BetterFruitTreesConfig config = helper.ReadConfig <BetterFruitTreesConfig>(); IInitializable pHelper = new PlacementHelper(config); pHelper.Init(); if (config.Disable_Fruit_Tree_Junimo_Harvesting) { return; } Utils.HarvestThreeAtOnce = config.Wait_To_Harvest_Fruit_Trees_Until_They_Have_Three_Fruits__Then_Harvest_All_Three_At_Once; HarmonyInstance harmony = HarmonyInstance.Create("cat.betterfruittrees"); Type junimoHarvesterType = Utils.GetSDVType("Characters.JunimoHarvester"); IList <Tuple <string, Type, Type> > replacements = new List <Tuple <string, Type, Type> > { { "foundCropEndFunction", junimoHarvesterType, typeof(FoundCropEndFunctionPatch) }, { "tryToHarvestHere", junimoHarvesterType, typeof(TryToHarvestHerePatch) }, { "update", junimoHarvesterType, typeof(UpdatePatch) }, { "areThereMatureCropsWithinRadius", Utils.GetSDVType("Buildings.JunimoHut"), typeof(AreThereMatureCropsWithinRadiusPatch) } }; foreach (Tuple <string, Type, Type> replacement in replacements) { MethodInfo original = replacement.Item2 .GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public).ToList() .Find(m => m.Name == replacement.Item1); MethodInfo prefix = replacement.Item3.GetMethods(BindingFlags.Static | BindingFlags.Public) .FirstOrDefault(item => item.Name == "Prefix"); MethodInfo postfix = replacement.Item3.GetMethods(BindingFlags.Static | BindingFlags.Public) .FirstOrDefault(item => item.Name == "Postfix"); harmony.Patch(original, prefix == null ? null : new HarmonyMethod(prefix), postfix == null ? null : new HarmonyMethod(postfix)); } }
/// <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) { Instance = this; this.Config = helper.ReadConfig <Config>(); this.Bridge = new Bridge(helper.ModRegistry, this.Config.DebugMode); this.EventManager = new EventManager(this.Monitor); this.QuestManager = new QuestManager(this.Monitor); this.QuestStateStore = new QuestStateStore(helper.Data, this.Monitor); this.StatsManager = new StatsManager(helper.Multiplayer, helper.Data); this.ConditionManager = new ConditionManager(this.Monitor); this.QuestOfferManager = new QuestOfferManager(this.ConditionManager, this.QuestManager); this.ContentPackLoader = new Loader(this.Monitor, this.QuestManager, this.QuestOfferManager); this.QuestController = new QuestController(this.QuestManager, this.QuestOfferManager, this.Monitor); this.MailController = new MailController(this.QuestManager, this.QuestOfferManager, this.Monitor); this.QuestLogWatchdog = new QuestLogWatchdog(helper.Events, this.EventManager, this.StatsManager, this.Monitor); this.NetworkOperator = new NetworkOperator( helper: helper.Multiplayer, events: helper.Events.Multiplayer, questStateStore: this.QuestStateStore, statsManager: this.StatsManager, questController: this.QuestController, modManifest: this.ModManifest, monitor: this.Monitor); helper.Content.AssetEditors.Add(this.QuestController); helper.Content.AssetEditors.Add(this.MailController); helper.Events.GameLoop.GameLaunched += this.OnGameStarted; helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked; helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; helper.Events.GameLoop.Saving += this.OnSaving; helper.Events.GameLoop.DayStarted += this.OnDayStarted; helper.Events.GameLoop.DayEnding += this.OnDayEnding; helper.Events.GameLoop.ReturnedToTitle += this.OnReturnToTitle; helper.Events.Display.MenuChanged += this.OnQuestLogMenuChanged; this.NetworkOperator.InitReceived += this.OnNetworkInitMessageReceived; this.Patcher = new GamePatcher(this.ModManifest.UniqueID, this.Monitor, false); this.Patcher.Apply( new Patches.QuestPatch(this.QuestManager, this.EventManager), new Patches.LocationPatch(this.ConditionManager), new Patches.Game1Patch(this.QuestManager, this.QuestOfferManager), new Patches.DialoguePatch(this.QuestManager), new Patches.NPCPatch(this.QuestManager, this.QuestOfferManager), new Patches.BillboardPatch()); helper.ConsoleCommands.Add("quests_list", "List all managed quests", Commands.ListQuests); helper.ConsoleCommands.Add("quests_log", "List all managed quests which are in player's quest log", Commands.ListLog); helper.ConsoleCommands.Add("quests_stats", "Show quest statistics", Commands.QuestStats); helper.ConsoleCommands.Add("quests_invalidate", "Invalidate quest assets cache", Commands.InvalidateCache); helper.ConsoleCommands.Add("quests_accept", "Accept managed quest and add it to questlog", Commands.AcceptQuest); helper.ConsoleCommands.Add("quests_complete", "Complete managed quest in questlog", Commands.CompleteQuest); helper.ConsoleCommands.Add("quests_remove", "Remove managed quest from questlog", Commands.RemoveQuest); helper.ConsoleCommands.Add("quests_customtypes", "List of exposed custom quest types", Commands.ListTypeFactories); var packs = helper.ContentPacks.GetOwned(); if (packs.Any()) { this.ContentPackLoader.LoadPacks(packs); } }
public override void Entry(IModHelper helper) { GameEvents.HalfSecondTick += this.GameEvents_HalfSecondTick; config = helper.ReadConfig <Config>(); }
public override void Entry(IModHelper helper) { Instance = this; Config = helper.ReadConfig <PondPainterConfig>(); helper.Events.GameLoop.DayStarted += GameLoop_DayStarted; if (Config.Enable_Animations) { helper.Events.GameLoop.UpdateTicked += GameLoop_UpdateTicked; } foreach (IContentPack contentPack in this.Helper.ContentPacks.GetOwned()) { this.Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}", LogLevel.Trace); // We are assuming that we will receive the packs in proper dependency order. // However, dependencies are traditionally "whoever updates last wins" but tag matching is usually the opposite. // So we will try to do the following. If we get pack A, B, C we save the data as C entries, B entries, A entries. int entryIndex = 0; if (contentPack.HasFile(ContentPackFile)) { PondPainterPackData packData = contentPack.ReadJsonFile <PondPainterPackData>(ContentPackFile); if (packData.EmptyPondColor != null) { Data.EmptyPondColor = ColorLookup.FromName(packData.EmptyPondColor); } int index = 0; foreach (PondPainterPackEntry entry in packData.Entries) { index++; string LogName = String.Format("Entry {0}", index); if (entry.LogName != null && !entry.LogName.Equals("")) { LogName = entry.LogName; } //this.Monitor.Log($"Found an entry called \"{LogName}\" and will now try to parse it.", LogLevel.Debug); if (entry.Tags.Count == 0) { this.Monitor.Log($"Entry \"{LogName}\" has an empty Tags list and will be skipped.", LogLevel.Warn); continue; } int cindex = 0; PondPainterDataEntry DataEntry = new PondPainterDataEntry(contentPack.Manifest.UniqueID, LogName, entry.Tags); foreach (PondPainterPackColor c in entry.Colors) { cindex++; Color?theColor = null; if (c.ColorName != null) { theColor = ColorLookup.FromName(c.ColorName); } if (theColor == null) { this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} does not have a ColorName defined and will be skipped.", LogLevel.Warn); continue; } // We've passed the null check so it is time to get rid of the damned nullable type Color theRealColor = (Color)theColor; bool HasAnimation = false; // Some defaults; note the range is a double even though the content pack only takes ints // This is because the internal ColorMine properties are all doubles int AnimationFrameDelay = 10; double AnimationRange = 20.0f; // Of course I had to make this configurable too, which means I have to sanity-check it. // For other options I could delay the sanity checks until I was certain we actually had a properly defined type, but this one // needs to be checked before I try to construct the animations. This means some meaningless error messages will be logged if // there is an animation type of "none" and something wrong with this value. // The total amount of steps is really twice this variable +1 since we go from base + steps to base - steps int AnimationSteps = 30; if (c.AnimationTotalFrames != null) { AnimationSteps = Math.Abs((int)c.AnimationTotalFrames); if (c.AnimationTotalFrames > -2 && c.AnimationTotalFrames < 2) { this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} has animation total frames set to ({c.AnimationTotalFrames}). The minimum useful value is 2 and that will be used instead.", LogLevel.Warn); AnimationSteps = 2; } else if (c.AnimationTotalFrames < 0) { this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} has animation total frames set to ({c.AnimationTotalFrames}). This value should be positive and will be changed to {AnimationSteps}.", LogLevel.Warn); } } List <Color> AnimationColors = new List <Color>(); if (c.AnimationType != null && !c.AnimationType.Equals("none")) { // An AnimationType was given, and each type is processed a bit differently. // The range will be interpreted differently for various types, but it should // never be 0 since that represents an animation that does nothing. // Note that null right now is still ok; it is only an explicit 0 being excluded if (c.AnimationRange == null || c.AnimationRange != 0) { if (c.AnimationType.Equals("hue")) { if (c.AnimationRange != null) { // restrict range to (0, 180] if (c.AnimationRange < 0 || c.AnimationRange > 180) { AnimationRange = Math.Min(180.0f, Math.Abs((int)c.AnimationRange)); this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} has an animation range of ({c.AnimationRange}). Hue animations must have a positive range <= 180 so this will be interpreted as {AnimationRange}.", LogLevel.Warn); } else { AnimationRange = (double)c.AnimationRange; } } else { AnimationRange = 20.0f; this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} had no animation range listed; the default of {AnimationRange} will be used.", LogLevel.Debug); } HasAnimation = true; // Calculating the animation frames, in HSV via ColorMine // We use a sine model with the animation "range" as amplitude and a period of the number of steps. SimpleRGB BaseRGB = new SimpleRGB(theRealColor.R, theRealColor.G, theRealColor.B); SimpleHSV BaseHSV = BaseRGB.ToHSV(); this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} Tracing HUE animation with base of {BaseHSV.H} and a range of {AnimationRange} in {AnimationSteps} steps.", LogLevel.Trace); for (int i = 0; i <= AnimationSteps; i++) { // We can't do the simpler NewHSV = BaseHSV because that is not a true copy SimpleHSV NewHSV = BaseRGB.ToHSV(); double hue = (360 + BaseHSV.H + AnimationRange * Math.Sin(2 * i * Math.PI / AnimationSteps)) % 360; NewHSV.H = hue; //this.Monitor.Log($"** Animation trace step {i}: hue {hue}. Base {BaseHSV.H}", LogLevel.Trace); SimpleRGB NewRGB = NewHSV.ToRGB(); AnimationColors.Add(new Color((int)NewRGB.R, (int)NewRGB.G, (int)NewRGB.B)); } } else if (c.AnimationType.Equals("value")) { if (c.AnimationRange != null) { // restrict range to (0, 100] (will be converted to (0, 1] later) if (c.AnimationRange < 0 || c.AnimationRange > 100) { AnimationRange = Math.Min(100, Math.Abs((int)c.AnimationRange)); this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} has an animation range of {c.AnimationRange}. Value animations must have a positive range <= 100 so this will be interpreted as {AnimationRange}.", LogLevel.Warn); } else { AnimationRange = (double)c.AnimationRange; } } else { AnimationRange = 20.0f; this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} had no animation range listed; the default of {AnimationRange} will be used.", LogLevel.Info); } AnimationRange /= 100.0f; HasAnimation = true; // Calculating the animation frames, in HSV via ColorMine // We use a sine model with the animation "range" as amplitude and a period of the number of steps. SimpleRGB BaseRGB = new SimpleRGB(theRealColor.R, theRealColor.G, theRealColor.B); SimpleHSV BaseHSV = BaseRGB.ToHSV(); //this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} Tracing VALUE animation with base of {BaseHSV.V} and a range of {AnimationRange} in {AnimationSteps} steps.", LogLevel.Trace); for (int i = 0; i <= AnimationSteps; i++) { // We can't do the simpler NewHSV = BaseHSV because that is not a true copy SimpleHSV NewHSV = BaseRGB.ToHSV(); double val = Math.Min(Math.Max(BaseHSV.V + AnimationRange * Math.Sin(2 * i * Math.PI / AnimationSteps), 0), 1); NewHSV.V = val; this.Monitor.Log($"** Animation trace step {i}: value {val}. Base {BaseHSV.V}", LogLevel.Trace); SimpleRGB NewRGB = NewHSV.ToRGB(); AnimationColors.Add(new Color((int)NewRGB.R, (int)NewRGB.G, (int)NewRGB.B)); } } else { this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} has an unknown animation type ({c.AnimationType}). A static color will be used instead.", LogLevel.Warn); } } else // AnimationRange was 0 { this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} has an animation range of zero. A static color will be used instead.", LogLevel.Warn); } } if (HasAnimation) { // To get here, we had a valid animation type with an appropriate range. // One final sanity check is on the timing. if (c.AnimationFrameDelay == null || c.AnimationFrameDelay == 0) { this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} had no animation frame delay listed; the default of {AnimationFrameDelay} frames will be used.", LogLevel.Info); } else { AnimationFrameDelay = Math.Abs((int)c.AnimationFrameDelay); if (c.AnimationFrameDelay < 0) { this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} had an animation frame delay of {c.AnimationFrameDelay}; timings must be positive so this will be interpreted as {AnimationFrameDelay}.", LogLevel.Warn); } } DataEntry.Colors.Add(c.MinPopulationForColor, new PondPainterDataColorDef(AnimationColors, AnimationFrameDelay)); this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} successfully added as a new animation.", LogLevel.Trace); } else { DataEntry.Colors.Add(c.MinPopulationForColor, new PondPainterDataColorDef((Color)theColor)); this.Monitor.Log($"Entry \"{LogName}\" color definition {cindex} successfully added as a new static color.", LogLevel.Trace); } } Data.Entries.Insert(entryIndex++, DataEntry); //this.Monitor.Log($"Entry \"{LogName}\" complete entry added to internal data.", LogLevel.Trace); } } else { this.Monitor.Log($"Unable to load content pack {contentPack.Manifest.Name} {contentPack.Manifest.Version} because no {ContentPackFile} file was found.", LogLevel.Warn); } } this.Monitor.Log($"Finished loading content packs. Data has {Data.Entries.Count} entries.", LogLevel.Trace); }
/// <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) { this.config = helper.ReadConfig <AutoStackerConfig>(); helper.Events.Input.ButtonPressed += this.OnButtonPressed; }
public ConfigurationService(IModHelper modHelper) { _modHelper = modHelper; _modConfig = _modHelper.ReadConfig <ModConfig>(); }
/* * Mod Entry & Config Validation */ public override void Entry(IModHelper helper) { this.Config = processConfig(helper.ReadConfig <ModConfig>()); helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded; helper.Events.GameLoop.UpdateTicking += this.OnUpdateTicking; }