private void AddPlayerChatMessage(object sender, ChatMessageEventArgs e) { int messageHash = messagesField.GetValue().Last().GetHashCode(); RemoveExcedentMessages(messageHash); string message = formatMessageMethod.Invoke <string>(e.SourcePlayer.UniqueMultiplayerID, e.ChatKind, e.Message); int witdh = Game1.chatBox.chatBox.Width; if (e.ChatKind == Constants.ChatMessageKind.Normal) { witdh -= 8; } message = Game1.parseText(message, Game1.chatBox.chatBox.Font, witdh - 8); PlayerMessageList.Add(new PlayerMessage(e.SourcePlayer, e.Language, message, messageHash)); foreach (ChatSnippet item in messagesField.GetValue().Last().message) { if (item.emojiIndex >= NumberVanillaEmoji) { item.emojiIndex = -1; } } }
/// <summary>Patches the load menu</summary> /// <param name="menu">The menu to patch</param> private void PatchLoadMenu(LoadGameMenu menu) { //Don't want to patch the coop menu if (menu is CoopMenu) { return; } //Relfedt into the task that is running IReflectedField <Task <List <SFarmer> > > task = Entry.Helper.Reflection.GetField <Task <List <SFarmer> > >(menu, "_initTask"); if (!TaskStarted) { if (task == null || task.GetValue() == null) { return; } if (!task.GetValue().IsCompleted) { TaskStarted = true; return; } } else { if (task != null && task.GetValue() != null && !task.GetValue().IsCompleted) { return; } } TaskStarted = false; PreviousLoadMenu = menu; //Find the saved games if (!Farmers.Any()) { Farmers = Entry.Helper.Reflection.GetMethod(typeof(LoadGameMenu), "FindSaveGames").Invoke <List <SFarmer> >(); } //Create a new instance of the list Type elementType = Type.GetType("StardewValley.Menus.LoadGameMenu+MenuSlot, Stardew Valley"); Type listType = typeof(List <>).MakeGenericType(new Type[] { elementType }); object list = Activator.CreateInstance(listType); //Set value of the menu slots and invoke addSaveFiles method Entry.Helper.Reflection.GetField <object>(menu, "menuSlots").SetValue(list); Entry.Helper.Reflection.GetMethod(menu, "addSaveFiles").Invoke(Farmers); //Add the Patch Farmer event Entry.Helper.Events.GameLoop.UpdateTicked += OnUpdateTickedPatchLoadMenuFarmer; }
public override void receiveLeftClick(int x, int y, bool playSound = true) { if (showingResultScreen.GetValue() && playAgain.containsPoint(x, y) && ( toBet == 0 || Game1.player.clubCoins >= toBet || !M.Config.checkQiCoin )) { Game1.currentMinigame = new CalicoJackExitable(toBet, highStakes); Game1.playSound("smallSelect"); return; } base.receiveLeftClick(x, y, playSound); }
/// <summary>Get the locale codes (like <c>ja-JP</c>) used in asset keys.</summary> /// <param name="reflection">Simplifies access to private game code.</param> private IDictionary <string, LanguageCode> GetKeyLocales(Reflector reflection) { // get the private code field directly to avoid changed-code logic IReflectedField <LanguageCode> codeField = reflection.GetField <LanguageCode>(typeof(LocalizedContentManager), "_currentLangCode"); // remember previous settings LanguageCode previousCode = codeField.GetValue(); string previousOverride = this.LanguageCodeOverride; // create locale => code map IDictionary <string, LanguageCode> map = new Dictionary <string, LanguageCode>(StringComparer.InvariantCultureIgnoreCase); this.LanguageCodeOverride = null; foreach (LanguageCode code in Enum.GetValues(typeof(LanguageCode))) { codeField.SetValue(code); map[this.GetKeyLocale.Invoke <string>()] = code; } // restore previous settings codeField.SetValue(previousCode); this.LanguageCodeOverride = previousOverride; return(map); }
private void Junimo_Lives(object sender, EventArgs args) { if (!Context.IsWorldReady) { return; } if (Game1.currentMinigame is MineCart game) { IReflectedField <int> livesLeft = this.Helper.Reflection.GetField <int>(game, "livesLeft"); if (livesLeft != null) { if (livesLeft.GetValue() < 3) { livesLeft.SetValue(3); //this.Monitor.Log("Set Cart Lives to 3"); } else { return; } } } else { return; } }
/// <summary> /// Adds in a junimo actor at the current location. Allows for multiple. /// </summary> /// <param name="EventManager"></param> /// <param name="EventData"></param> public static void AddInJumimoActorForEvent(EventManager EventManager, string EventData) { string[] splits = EventData.Split(' '); string name = splits[0]; string actorName = splits[1]; int xPos = Convert.ToInt32(splits[2]); int yPos = Convert.ToInt32(splits[3]); Color color = new Color(Convert.ToInt32(splits[4]), Convert.ToInt32(splits[5]), Convert.ToInt32(splits[6])); bool flipped = Convert.ToBoolean(splits[7]); List <NPC> actors = Game1.CurrentEvent.actors; Junimo junimo = new Junimo(new Vector2(xPos * 64, yPos * 64), -1, false); junimo.Name = actorName; junimo.EventActor = true; junimo.flip = flipped; IReflectedField <NetColor> colorF = StardustCore.ModCore.ModHelper.Reflection.GetField <NetColor>(junimo, "color", true); NetColor c = colorF.GetValue(); c.R = color.R; c.G = color.G; c.B = color.B; colorF.SetValue(c); actors.Add((NPC)junimo); ++Game1.CurrentEvent.CurrentCommand; //I've been told ++<int> is more efficient than <int>++; }
public void MenuEvents_MenuChanged(object sender, EventArgsClickableMenuChanged e) { System.Console.Write($"Type of new menu is {e.NewMenu.GetType().ToString()}"); if (e.NewMenu is CraftingPage page && !(e.NewMenu is ListenerCraftingPage)) { ListenerCraftingPage replacement = new ListenerCraftingPage(page, this.replacer); Game1.activeClickableMenu = replacement; } if (e.NewMenu is GameMenu) { IReflectedField <List <IClickableMenu> > pages = this.Helper.Reflection.GetField <List <IClickableMenu> >(e.NewMenu, "pages"); var menuPages = pages.GetValue(); for (int i = 0; i < menuPages.Count; i++) { if (menuPages[i] is CraftingPage craftingPage) { menuPages[i] = new ListenerCraftingPage(craftingPage, this.replacer); break; } } pages.SetValue(menuPages); } }
private static bool ShouldDrawButton() { return(Game1.gameMode == 0 && TitleMenu.subMenu == null && !_isTransitioningButtons.GetValue() && _titleInPosition.GetValue() && !_transitioningCharacterCreationMenu.GetValue()); }
/// <summary>Render the UI.</summary> /// <param name="spriteBatch">The sprite batch being drawn.</param> public override void draw(SpriteBatch spriteBatch) { // disable when game is using immediate sprite sorting if (!ValidatedDrawMode) { IReflectedField <SpriteSortMode> sortModeField = ClimatesOfFerngill.Reflection.GetField <SpriteSortMode>(Game1.spriteBatch, "spriteSortMode", required: false) // XNA ?? ClimatesOfFerngill.Reflection.GetField <SpriteSortMode>(Game1.spriteBatch, "_sortMode"); // MonoGame if (sortModeField.GetValue() == SpriteSortMode.Immediate) { ClimatesOfFerngill.Logger.Log("Aborted the weather draw because the game's current rendering mode isn't compatible with the mod's UI. This only happens in rare cases (e.g. the Stardew Valley Fair).", LogLevel.Warn); exitThisMenu(playSound: false); return; } ValidatedDrawMode = true; } // calculate dimensions int x = xPositionOnScreen; int y = yPositionOnScreen; const int gutter = 15; float leftOffset = gutter; float topOffset = gutter; float contentWidth = width - gutter * 2; float contentHeight = height - gutter * 2; // get font SpriteFont font = Game1.smallFont; float lineHeight = font.MeasureString("ABC").Y; //at this point I'm going to manually put this in as I don't need in many places, // and I kinda want to have this where I can understand what it's for float spaceWidth = DrawHelper.GetSpaceWidth(font); // draw background // (This uses a separate sprite batch because it needs to be drawn before the // foreground batch, and we can't use the foreground batch because the background is // outside the clipping area.) spriteBatch.DrawSprite(Sprites.Letter.Sheet, Sprites.Letter.Sprite, x, y, scale: width / (float)Sprites.Letter.Sprite.Width); // begin draw // draw weather icon spriteBatch.Draw(IconSheet.WeatherSource, new Vector2(x + leftOffset, y + topOffset), Sprites.Icons.GetWeatherSprite(CurrentWeather.GetCurrentConditions()), Color.White); leftOffset += 72; // draw text as sent from outside the menu float wrapWidth = width - leftOffset - gutter; { Vector2 textSize = spriteBatch.DrawTextBlock(font, MenuText, new Vector2(x + leftOffset, y + topOffset), wrapWidth); topOffset += textSize.Y + lineHeight; } drawMouse(Game1.spriteBatch); }
public static void CaskMachine(object __instance) { IReflectedField <Dictionary <int, float> > agingRates = CustomCaskModEntry.Helper.Reflection.GetField <Dictionary <int, float> >(__instance, "AgingRates"); foreach (var keyValuePair in DataLoader.CaskDataId) { agingRates.GetValue()[keyValuePair.Key] = keyValuePair.Value; } }
private void MenuChanged(object sender, MenuChangedEventArgs e) { var shop = e.NewMenu as StardewValley.Menus.ShopMenu; if (shop == null || Game1.currentLocation.Name != "Forest" || !shop.potraitPersonDialogue.Contains("hats")) { return; } // no bundles for Joja members if (Game1.player.hasOrWillReceiveMail("JojaMember")) { return; } CommunityCenter communityCenter = Game1.locations.OfType <CommunityCenter>().First(); if (communityCenter.areAllAreasComplete()) { return; } IReflectedField <Dictionary <Item, int[]> > inventoryInformation = this.Helper.Reflection.GetField <Dictionary <Item, int[]> >(shop, "itemPriceAndStock"); Dictionary <Item, int[]> itemPriceAndStock = inventoryInformation.GetValue(); IReflectedField <List <Item> > forSaleInformation = this.Helper.Reflection.GetField <List <Item> >(shop, "forSale"); List <Item> forSale = forSaleInformation.GetValue(); foreach (var bundle in GetBundles()) { if (communityCenter.isBundleComplete(bundle.ID)) { continue; } foreach (var ing in bundle.Ingredients) { if (communityCenter.bundles[bundle.ID][ing.Index]) { continue; } int itemId = ing.ItemID; var objectToAdd = new StardewValley.Object(Vector2.Zero, itemId, ing.Stack); objectToAdd.Quality = ing.Quality; if (objectToAdd.Name.Contains("rror")) { continue; } itemPriceAndStock.Add(objectToAdd, new int[2] { 5000, ing.Stack }); forSale.Add(objectToAdd); } } inventoryInformation.SetValue(itemPriceAndStock); forSaleInformation.SetValue(forSale); }
public static void AutoFishing(BobberBar bar) { AutoFishingCounter = (AutoFishingCounter + 1) % 3; if (AutoFishingCounter > 0) { return; } IReflectedField <float> bobberSpeed = Reflection.GetField <float>(bar, "bobberBarSpeed"); float barPos = Reflection.GetField <float>(bar, "bobberBarPos").GetValue(); int barHeight = Reflection.GetField <int>(bar, "bobberBarHeight").GetValue(); float fishPos = Reflection.GetField <float>(bar, "bobberPosition").GetValue(); float treasurePos = Reflection.GetField <float>(bar, "treasurePosition").GetValue(); float distanceFromCatching = Reflection.GetField <float>(bar, "distanceFromCatching").GetValue(); bool treasureCaught = Reflection.GetField <bool>(bar, "treasureCaught").GetValue(); bool treasure = Reflection.GetField <bool>(bar, "treasure").GetValue(); float treasureApeearTimer = Reflection.GetField <float>(bar, "treasureAppearTimer").GetValue(); float bobberBarSpeed = bobberSpeed.GetValue(); float top = barPos; if (treasure && treasureApeearTimer <= 0 && !treasureCaught) { if (!CatchingTreasure && distanceFromCatching > 0.7f) { CatchingTreasure = true; } if (CatchingTreasure && distanceFromCatching < 0.3f) { CatchingTreasure = false; } if (CatchingTreasure) { fishPos = treasurePos; } } if (fishPos > barPos + (barHeight / 2f)) { return; } float strength = (fishPos - (barPos + barHeight / 2f)) / 18f; float distance = fishPos - top; float threshold = Util.Cap(InstanceHolder.Config.CpuThresholdFishing, 0, 0.5f); if (distance < threshold * barHeight || distance > (1 - threshold) * barHeight) { bobberBarSpeed = strength; } bobberSpeed.SetValue(bobberBarSpeed); }
/// <summary>Perform any logic needed on update while the animation is active.</summary> /// <param name="playerAnimationID">The player's current animation ID.</param> public override void Update(int playerAnimationID) { LoadGameMenu menu = (LoadGameMenu)this.Reflection.GetField <IClickableMenu>(typeof(TitleMenu), "_subMenu").GetValue(); IReflectedField <int> timerToLoad = this.GetTimerToLoad(menu); this.ApplySkips( run: () => menu.update(Game1.currentGameTime), until: () => timerToLoad.GetValue() <= 0 ); }
/// <summary>Perform any logic needed on update while the animation is active.</summary> /// <param name="playerAnimationID">The player's current animation ID.</param> public override void Update(int playerAnimationID) { LoadGameMenu menu = (LoadGameMenu)this.Reflection.GetField <IClickableMenu>(typeof(TitleMenu), "_subMenu").GetValue(); IReflectedField <int> timerToLoad = this.GetTimerToLoad(menu); for (int i = 1; i < this.Multiplier && timerToLoad.GetValue() > 0; i++) { menu.update(Game1.currentGameTime); } }
/// <summary>Raised once after game is saved.</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event data.</param> private void OnSaved(object sender, SavedEventArgs e) { messagesField = Helper.Reflection.GetField <List <ChatMessage> >(Game1.chatBox, "messages"); msgCount = messagesField.GetValue().Count; if (msgCount == 0) { return; } int count = 1; ChatMessage message = messagesField.GetValue()[msgCount - count]; while (message.GetHashCode() != lastMsg) { messages.Add(message); message = messagesField.GetValue()[msgCount - ++count]; } lastMsg = messagesField.GetValue()[msgCount - 1].GetHashCode(); messages.Reverse(); }
/// <summary>Raised once every tick.</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event data.</param> private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { if (!Context.IsWorldReady) { return; } messagesField = Helper.Reflection.GetField <List <ChatMessage> >(Game1.chatBox, "messages"); msgCount = messagesField.GetValue().Count; if (msgCount == 0) { return; } ChatMessage message = messagesField.GetValue()[msgCount - 1]; if (message.GetHashCode() != lastMsg) { lastMsg = message.GetHashCode(); messages.Add(message); } }
/// <summary> /// Reverts the mushroom stump back into a tree exactly like its done in StardewValley.TerrainFeatures.Tree.dayUpdate, but only if it's not a chopped down tree /// </summary> /// <param name="tree">current mushroom tree</param> private void FixMushroomStump(Tree tree) { if (tree.treeType.Value == (int)TreeType.mushroomTree) { IReflectedField <float> shakeRotation = Helper.Reflection.GetField <float>(tree, "shakeRotation"); // if the value is higher than this the game considers the tree as falling or having fallen if (Math.Abs(shakeRotation.GetValue()) < 1.5707963267948966) { tree.stump.Set(false); tree.health.Set(10f); shakeRotation.SetValue(0f); } } }
private void GameEvents_UpdateTick(object sender, EventArgs e) { if (Game1.activeClickableMenu is CarpenterMenu carpenter) { if (carpenter.CurrentBlueprint.name == "Aquaponics") { IReflectedField <Building> cBuilding = Helper.Reflection.GetField <Building>(carpenter, "currentBuilding"); if (!(cBuilding.GetValue() is Aquaponics)) { cBuilding.SetValue(new Aquaponics(Vector2.Zero, Game1.getFarm())); } } } }
public static bool Prefix(Wand __instance) { Vector2 frontDoor = FarmState.frontDoorLocation + new Vector2(0, 1); Game1.warpFarmer("Farm", (int)frontDoor.X, (int)frontDoor.Y, false); if (!Game1.isStartingToGetDarkOut()) { Game1.playMorningSong(); } else { Game1.changeMusicTrack("none", false, Game1.MusicContext.Default); } Game1.fadeToBlackAlpha = 0.99f; Game1.screenGlow = false; IReflectedField <Farmer> lastUser = FarmHouseStates.reflector.GetField <Farmer>(__instance, "lastUser"); lastUser.GetValue().temporarilyInvincible = false; lastUser.GetValue().temporaryInvincibilityTimer = 0; Game1.displayFarmer = true; return(false); }
private void Events_Rendering(object sender, EventArgs e) { if (Game1.activeClickableMenu is Billboard) { #region accessing Billboard Billboard menu = (Billboard)Game1.activeClickableMenu; FieldInfo calendarField = menu.GetType().GetField("calendarDays", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (calendarField == null) { this.Monitor.Log("Could not find field 'calendarDays' in Billboard!", LogLevel.Error); return; } List <ClickableTextureComponent> calendarDays = (List <ClickableTextureComponent>)calendarField.GetValue(menu); IReflectedField <string> privateField = this.Helper.Reflection.GetField <string>(menu, "hoverText"); string hoverText = privateField.GetValue(); #endregion if (calendarDays != null && !(hoverText.Contains("Moon") || hoverText.Contains("moon"))) { for (int day = 1; day <= 28; day++) { ClickableTextureComponent component = calendarDays[day - 1]; // 0 - 27 if (component.bounds.Contains(Game1.getMouseX(), Game1.getMouseY())) { if (moon.LunarCalendar[day] >= 0 && moon.LunarCalendar[day] <= 3) { if (hoverText.Length > 0) { hoverText += "\n"; } hoverText += $"{moon.CalculatePhaseName(moon.LunarCalendar[day])} moon"; } else { hoverText += ""; break; } } } privateField.SetValue(hoverText); } } }
private void Junimo_Lives(object sender, UpdateTickedEventArgs args) { if (!Context.IsWorldReady) { return; } if (Game1.currentMinigame is MineCart game && args.IsMultipleOf(30)) { IReflectedField <int> livesLeft = Helper.Reflection.GetField <int>(game, "livesLeft"); if (livesLeft?.GetValue() < 3) { livesLeft.SetValue(3); //this.Monitor.Log("Set Cart Lives to 3"); } } }
public void Shake(Vector2 tileLocation, bool doEvenIfStillShaking) { if (!((double)_maxShake.GetValue() == 0.0 | doEvenIfStillShaking)) { return; } _shakeLeft.SetValue((double)Game1.player.getTileLocation().X > (double)tileLocation.X || (double)Game1.player.getTileLocation().X == (double)tileLocation.X && Game1.random.NextDouble() < 0.5); _maxShake.SetValue((float)Math.PI / 128f); if (!townBush && tileSheetOffset == 1 && inBloom(Game1.currentSeason, Game1.dayOfMonth)) { int parentSheetIndex = -1; string currentSeason = Game1.currentSeason; if (currentSeason != "spring") { if (currentSeason == "fall") { parentSheetIndex = 410; } } else { parentSheetIndex = 296; } if (parentSheetIndex == -1) { return; } tileSheetOffset.Value = 0; setUpSourceRect(); int num = new Random((int)tileLocation.X + (int)tileLocation.Y * 5000 + (int)Game1.uniqueIDForThisGame + (int)Game1.stats.DaysPlayed).Next(1, 2) + Game1.player.ForagingLevel / 4; for (int index = 0; index < num; ++index) { Game1.createItemDebris((Item) new StardewValley.Object(parentSheetIndex, 1, false, -1, Game1.player.professions.Contains(16) ? 4 : 0), Utility.PointToVector2(getBoundingBox().Center), Game1.random.Next(1, 4), (GameLocation)null); } DelayedAction.playSoundAfterDelay("leafrustle", 100); } else { if ((double)tileLocation.X != 20.0f || (double)tileLocation.Y != 8.0f || (Game1.dayOfMonth != 28 || Game1.timeOfDay != 1200) || Game1.player.mailReceived.Contains("junimoPlush")) { return; } Game1.player.addItemByMenuIfNecessaryElseHoldUp((Item) new Furniture(1733, Vector2.Zero), new ItemGrabMenu.behaviorOnItemSelect(junimoPlushCallback)); } }
public static void Activate() { HatService.OnUpdateTicked = (e) => { if (Game1.currentLocation.isOutdoors || Game1.player.hasMenuOpen || !Game1.player.canMove || !Game1.game1.IsActive) { return; } if (e.Ticks % 480 == 0) { multiplayer.GetValue().broadcastSprites(Game1.currentLocation, Utility.sparkleWithinArea(new Rectangle(Convert.ToInt32(Game1.player.position.X), Convert.ToInt32(Game1.player.position.Y) - 128, 32, 32), 2, Color.DeepPink)); foreach (var npc in Game1.currentLocation.getCharacters()) { Game1.player.changeFriendship(5, npc); } } }; }
public static void AutoReelRod() { Farmer player = Game1.player; if (!(player.CurrentTool is FishingRod rod) || Game1.activeClickableMenu != null) { return; } IReflectedField <int> whichFish = Reflection.GetField <int>(rod, "whichFish"); if (!rod.isNibbling || !rod.isFishing || whichFish.GetValue() != -1 || rod.isReeling || rod.hit || rod.isTimingCast || rod.pullingOutOfWater || rod.fishCaught) { return; } rod.DoFunction(player.currentLocation, 1, 1, 1, player); }
public void selectChannel(StardewValley.Farmer who, string answer) { string a = answer.Split(' ')[0]; CustomTVMod.monitor.Log("Select Channel:" + a, LogLevel.Trace); if (a == "more") { showChannels(currentpage + 1); } if (actions.ContainsKey(a)) { actions[a].Invoke(tv, tvScreen.GetValue(), who, a); } return; }
/// <summary>Temporarily dismount and set up the player to interact with a tile, then return it to the previous state afterwards.</summary> /// <param name="action">The action to perform.</param> private void TemporarilyFakeInteraction(Action action) { // get references SFarmer player = Game1.player; IReflectedField <Horse> mountField = this.Reflection.GetField <Horse>(Game1.player, "mount"); // save current state Horse mount = mountField.GetValue(); Vector2 mountPosition = this.Position; WateringCan wateringCan = player.CurrentTool as WateringCan; int waterInCan = wateringCan?.WaterLeft ?? 0; float stamina = player.stamina; Vector2 position = player.Position; int facingDirection = player.FacingDirection; int currentToolIndex = player.CurrentToolIndex; bool canMove = Game1.player.canMove; // fix player frozen due to animations when performing an action // move mount out of the way mountField.SetValue(null); this.Position = new Vector2(-5, -5); // perform action try { action(); } finally { // move mount back this.Position = mountPosition; mountField.SetValue(mount); // restore previous state if (wateringCan != null) { wateringCan.WaterLeft = waterInCan; } player.stamina = stamina; player.Position = position; player.FacingDirection = facingDirection; player.CurrentToolIndex = currentToolIndex; Game1.player.canMove = canMove; } }
public override void draw(SpriteBatch spriteBatch, Vector2 tileLocation) { Vector2 screenPosition = Game1.GlobalToLocal(Game1.viewport, new Vector2( tileLocation.X * 64f + 64f / 2, (tileLocation.Y + 1f) * 64f)); spriteBatch.Draw( texture: CustomTexture, position: screenPosition, sourceRectangle: SourceRectangle, color: Color.White * AlphaField.GetValue(), rotation: ShakeField.GetValue(), origin: new Vector2( SourceRectangle.Width / 2, SourceRectangle.Height), scale: Game1.pixelZoom, effects: flipped ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth: (this.getBoundingBox(tileLocation).Center.Y + 48) / 10000f - tileLocation.X / 1000000f); }
private void StartMinigameEndFunction(FishingRod rod, Farmer user, int fish) { rod.isReeling = true; rod.hit = false; // Animation switch (user.FacingDirection) { case 1: user.FarmerSprite.setCurrentSingleFrame(48); break; case 3: user.FarmerSprite.setCurrentSingleFrame(48, 32000, false, true); break; default: break; } user.FarmerSprite.PauseForSingleAnimation = true; // Distance from bobber to land IReflectedField <int> clearWaterDistanceField = ModFishing.Instance.Helper.Reflection.GetField <int>(rod, "clearWaterDistance"); clearWaterDistanceField.SetValue(FishingRod.distanceToLand((int)(rod.bobber.X / 64.0 - 1.0), (int)(rod.bobber.Y / 64.0 - 1.0), user.currentLocation)); // Calculate size of fish float num = 1f * (clearWaterDistanceField.GetValue() / 5f) * (Game1.random.Next(1 + Math.Min(10, user.FishingLevel) / 2, 6) / 5f); if (rod.favBait) { num *= 1.2f; } float fishSize = Math.Max(0.0f, Math.Min(1f, num * (float)(1.0 + Game1.random.Next(-10, 10) / 100.0))); // Check if there should be treasure bool treasure = !Game1.isFestival(); treasure &= user.fishCaught != null && user.fishCaught.Count > 1; treasure &= Game1.random.NextDouble() < ModFishing.Instance.Api.GetTreasureChance(user, rod); Game1.activeClickableMenu = new CustomBobberBar(user, fish, fishSize, treasure, rod.attachments[1]?.ParentSheetIndex ?? -1); }
private void OnMenuChanged(object sender, MenuChangedEventArgs eventArgs) { if (!(eventArgs.NewMenu is ShopMenu shopMenu) || !shopMenu.portraitPerson.Equals(Game1.getCharacterFromName("Robin"))) { return; } Item hardwoodItem = new Object(Vector2.Zero, HardwoodItemId, ShopMenu.infiniteStock); IReflectedField <List <ISalable> > forSaleInformation = Helper.Reflection.GetField <List <ISalable> >(shopMenu, "forSale"); List <ISalable> forSale = forSaleInformation.GetValue(); int woodItemPosition = forSale.FindIndex(salable => salable is Item item && item.parentSheetIndex.Equals(WoodItemId)); forSale.Insert(woodItemPosition + 1, hardwoodItem); IReflectedField <Dictionary <ISalable, int[]> > inventoryInformation = Helper.Reflection.GetField <Dictionary <ISalable, int[]> >(shopMenu, "itemPriceAndStock"); Dictionary <ISalable, int[]> itemPriceAndStock = inventoryInformation.GetValue(); itemPriceAndStock.Add(hardwoodItem, new[] { HardwoodPrice, ShopMenu.infiniteStock }); }
/// <summary>Process the answer in front of Wizard Shrine.</summary> private void Answer_WizardShrine(Farmer farmer, string ans) { if (ans != "Yes") { return; } if (Game1.player.Money >= 500) { OpenMenu(); Game1.player.Money -= 500; try { IReflectedField <Multiplayer> multiplayer = Helper.Reflection.GetField <Multiplayer>(typeof(Game1), "multiplayer"); multiplayer.GetValue()?.globalChatInfoMessage("Makeover", Game1.player.Name); } catch { } } else { Game1.drawObjectDialogue(Game1.content.LoadString("Strings\\UI:NotEnoughMoney2")); } }