From c3555c74f558cae5041c882fba0377d9fa2894be Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 29 Mar 2018 20:27:43 -0400 Subject: update for Stardew Valley 1.2.0.20 (#453) --- src/SMAPI/Constants.cs | 2 +- src/SMAPI/Framework/ContentCore.cs | 20 +++++- src/SMAPI/Framework/SGame.cs | 138 ++++++++++++++++++++++--------------- 3 files changed, 101 insertions(+), 59 deletions(-) (limited to 'src/SMAPI') diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 6270186a..72b9c78e 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -186,7 +186,7 @@ namespace StardewModdingAPI { string prefix = #if STARDEW_VALLEY_1_3 - new string(Game1.player.name.Value.Where(char.IsLetterOrDigit).ToArray()); + new string(Game1.player.Name.Where(char.IsLetterOrDigit).ToArray()); #else new string(Game1.player.name.Where(char.IsLetterOrDigit).ToArray()); #endif diff --git a/src/SMAPI/Framework/ContentCore.cs b/src/SMAPI/Framework/ContentCore.cs index 3c7e7b5a..43357553 100644 --- a/src/SMAPI/Framework/ContentCore.cs +++ b/src/SMAPI/Framework/ContentCore.cs @@ -44,6 +44,11 @@ namespace StardewModdingAPI.Framework /// The underlying asset cache. private readonly ContentCache Cache; +#if STARDEW_VALLEY_1_3 + /// A lookup which indicates whether the asset is localisable (i.e. the filename contains the locale), if previously loaded. + private readonly IDictionary IsLocalisableLookup; +#endif + /// The locale codes used in asset keys indexed by enum value. private readonly IDictionary Locales; @@ -106,6 +111,9 @@ namespace StardewModdingAPI.Framework this.CoreAssets = new CoreAssetPropagator(this.NormaliseAssetName, reflection); this.Locales = this.GetKeyLocales(reflection); this.LanguageCodes = this.Locales.ToDictionary(p => p.Value, p => p.Key, StringComparer.InvariantCultureIgnoreCase); +#if STARDEW_VALLEY_1_3 + this.IsLocalisableLookup = reflection.GetField>(this.Content, "_localizedAsset").GetValue(); +#endif } /// Get a new content manager which defers loading to the content core. @@ -512,8 +520,18 @@ namespace StardewModdingAPI.Framework /// The normalised asset name. private bool IsNormalisedKeyLoaded(string normalisedAssetName) { - return this.Cache.ContainsKey(normalisedAssetName) +#if STARDEW_VALLEY_1_3 + if (!this.IsLocalisableLookup.TryGetValue(normalisedAssetName, out bool localisable)) + return false; + + return localisable + ? this.Cache.ContainsKey($"{normalisedAssetName}.{this.Locales[this.Content.GetCurrentLanguage()]}") + : this.Cache.ContainsKey(normalisedAssetName); +#else + return + this.Cache.ContainsKey(normalisedAssetName) || this.Cache.ContainsKey($"{normalisedAssetName}.{this.Locales[this.Content.GetCurrentLanguage()]}"); // translated asset +#endif } /// Track that a content manager loaded an asset. diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs index 47bc40e6..ae702711 100644 --- a/src/SMAPI/Framework/SGame.cs +++ b/src/SMAPI/Framework/SGame.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Xna.Framework; @@ -25,6 +26,8 @@ using StardewValley.Tools; using xTile.Dimensions; #if !STARDEW_VALLEY_1_3 using xTile.Layers; +#else +using SFarmer = StardewValley.Farmer; #endif namespace StardewModdingAPI.Framework @@ -162,6 +165,7 @@ namespace StardewModdingAPI.Framework private readonly Action drawDialogueBox = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(drawDialogueBox)).Invoke(); #if STARDEW_VALLEY_1_3 private readonly Action drawOverlays = spriteBatch => SGame.Reflection.GetMethod(SGame.Instance, nameof(SGame.drawOverlays)).Invoke(spriteBatch); + private static StringBuilder _debugStringBuilder => SGame.Reflection.GetField(typeof(Game1), nameof(_debugStringBuilder)).GetValue(); #endif private readonly Action renderScreenBuffer = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(renderScreenBuffer)).Invoke(); // ReSharper restore ArrangeStaticMemberQualifier, ArrangeThisQualifier, InconsistentNaming @@ -727,6 +731,12 @@ namespace StardewModdingAPI.Framework this.RaisePostRender(); Game1.spriteBatch.End(); } + if (Game1.overlayMenu != null) + { + Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); + Game1.overlayMenu.draw(Game1.spriteBatch); + Game1.spriteBatch.End(); + } //base.Draw(gameTime); this.renderScreenBuffer(); } @@ -845,7 +855,7 @@ namespace StardewModdingAPI.Framework int widthOfString = SpriteText.getWidthOfString(str3); int height = 64; int x = 64; - int y = Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Bottom - height; + int y = Game1.graphics.GraphicsDevice.Viewport.GetTitleSafeArea().Bottom - height; SpriteText.drawString(Game1.spriteBatch, s, x, y, 999999, widthOfString, height, 1f, 0.88f, false, 0, str3, -1); Game1.spriteBatch.End(); if ((double)Game1.options.zoomLevel != 1.0) @@ -857,6 +867,7 @@ namespace StardewModdingAPI.Framework Game1.spriteBatch.End(); } this.drawOverlays(Game1.spriteBatch); + //base.Draw(gameTime); } else { @@ -956,6 +967,27 @@ namespace StardewModdingAPI.Framework } } } + foreach (SFarmer farmer in Game1.currentLocation.getFarmers()) + { + if (!(bool)((NetFieldBase)farmer.swimming) && !farmer.isRidingHorse() && (Game1.currentLocation == null || !Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(farmer.getTileLocation()))) + { + SpriteBatch spriteBatch = Game1.spriteBatch; + Texture2D shadowTexture = Game1.shadowTexture; + Vector2 local = Game1.GlobalToLocal(farmer.Position + new Vector2(32f, 24f)); + Microsoft.Xna.Framework.Rectangle? sourceRectangle = new Microsoft.Xna.Framework.Rectangle?(Game1.shadowTexture.Bounds); + Color white = Color.White; + double num2 = 0.0; + Microsoft.Xna.Framework.Rectangle bounds2 = Game1.shadowTexture.Bounds; + double x = (double)bounds2.Center.X; + bounds2 = Game1.shadowTexture.Bounds; + double y = (double)bounds2.Center.Y; + Vector2 origin = new Vector2((float)x, (float)y); + double num3 = 4.0 - (!farmer.running && !farmer.UsingTool || farmer.FarmerSprite.currentAnimationIndex <= 1 ? 0.0 : (double)Math.Abs(FarmerRenderer.featureYOffsetPerFrame[farmer.FarmerSprite.CurrentFrame]) * 0.5); + int num4 = 0; + double num5 = 0.0; + spriteBatch.Draw(shadowTexture, local, sourceRectangle, white, (float)num2, origin, (float)num3, (SpriteEffects)num4, (float)num5); + } + } Game1.currentLocation.Map.GetLayer("Buildings").Draw(Game1.mapDisplayDevice, Game1.viewport, Location.Origin, false, 4); Game1.mapDisplayDevice.EndScene(); Game1.spriteBatch.End(); @@ -976,6 +1008,27 @@ namespace StardewModdingAPI.Framework Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, actor.Position + new Vector2((float)(actor.Sprite.SpriteWidth * 4) / 2f, (float)(actor.GetBoundingBox().Height + (actor.IsMonster ? 0 : 12)))), new Microsoft.Xna.Framework.Rectangle?(Game1.shadowTexture.Bounds), Color.White, 0.0f, new Vector2((float)Game1.shadowTexture.Bounds.Center.X, (float)Game1.shadowTexture.Bounds.Center.Y), (float)(4.0 + (double)actor.yJumpOffset / 40.0) * (float)((NetFieldBase)actor.scale), SpriteEffects.None, Math.Max(0.0f, (float)actor.getStandingY() / 10000f) - 1E-06f); } } + foreach (SFarmer farmer in Game1.currentLocation.getFarmers()) + { + if (!(bool)((NetFieldBase)farmer.swimming) && !farmer.isRidingHorse() && (Game1.currentLocation != null && Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(farmer.getTileLocation()))) + { + SpriteBatch spriteBatch = Game1.spriteBatch; + Texture2D shadowTexture = Game1.shadowTexture; + Vector2 local = Game1.GlobalToLocal(farmer.Position + new Vector2(32f, 24f)); + Microsoft.Xna.Framework.Rectangle? sourceRectangle = new Microsoft.Xna.Framework.Rectangle?(Game1.shadowTexture.Bounds); + Color white = Color.White; + double num2 = 0.0; + Microsoft.Xna.Framework.Rectangle bounds2 = Game1.shadowTexture.Bounds; + double x = (double)bounds2.Center.X; + bounds2 = Game1.shadowTexture.Bounds; + double y = (double)bounds2.Center.Y; + Vector2 origin = new Vector2((float)x, (float)y); + double num3 = 4.0 - (!farmer.running && !farmer.UsingTool || farmer.FarmerSprite.currentAnimationIndex <= 1 ? 0.0 : (double)Math.Abs(FarmerRenderer.featureYOffsetPerFrame[farmer.FarmerSprite.CurrentFrame]) * 0.5); + int num4 = 0; + double num5 = 0.0; + spriteBatch.Draw(shadowTexture, local, sourceRectangle, white, (float)num2, origin, (float)num3, (SpriteEffects)num4, (float)num5); + } + } if ((Game1.eventUp || Game1.killScreen) && (!Game1.killScreen && Game1.currentLocation.currentEvent != null)) Game1.currentLocation.currentEvent.draw(Game1.spriteBatch); if (Game1.player.currentUpgrade != null && Game1.player.currentUpgrade.daysLeftTillUpgradeDone <= 3 && Game1.currentLocation.Name.Equals("Farm")) @@ -1054,7 +1107,6 @@ namespace StardewModdingAPI.Framework Game1.spriteBatch.Draw(Game1.rainTexture, Game1.rainDrops[index].position, new Microsoft.Xna.Framework.Rectangle?(Game1.getSourceRectForStandardTileSheet(Game1.rainTexture, Game1.rainDrops[index].frame, -1, -1)), Color.White); } Game1.spriteBatch.End(); - //base.Draw(gameTime); Game1.spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); if (Game1.eventUp && Game1.currentLocation.currentEvent != null) { @@ -1155,30 +1207,8 @@ namespace StardewModdingAPI.Framework this.drawDialogueBox(); if (Game1.progressBar) { - SpriteBatch spriteBatch1 = Game1.spriteBatch; - Texture2D fadeToBlackRect = Game1.fadeToBlackRect; - viewport1 = Game1.graphics.GraphicsDevice.Viewport; - int x1 = (viewport1.TitleSafeArea.Width - Game1.dialogueWidth) / 2; - viewport1 = Game1.graphics.GraphicsDevice.Viewport; - Microsoft.Xna.Framework.Rectangle titleSafeArea = viewport1.TitleSafeArea; - int y1 = titleSafeArea.Bottom - 128; - int dialogueWidth = Game1.dialogueWidth; - int height1 = 32; - Microsoft.Xna.Framework.Rectangle destinationRectangle1 = new Microsoft.Xna.Framework.Rectangle(x1, y1, dialogueWidth, height1); - Color lightGray = Color.LightGray; - spriteBatch1.Draw(fadeToBlackRect, destinationRectangle1, lightGray); - SpriteBatch spriteBatch2 = Game1.spriteBatch; - Texture2D staminaRect = Game1.staminaRect; - viewport1 = Game1.graphics.GraphicsDevice.Viewport; - int x2 = (viewport1.TitleSafeArea.Width - Game1.dialogueWidth) / 2; - viewport1 = Game1.graphics.GraphicsDevice.Viewport; - titleSafeArea = viewport1.TitleSafeArea; - int y2 = titleSafeArea.Bottom - 128; - int width = (int)((double)Game1.pauseAccumulator / (double)Game1.pauseTime * (double)Game1.dialogueWidth); - int height2 = 32; - Microsoft.Xna.Framework.Rectangle destinationRectangle2 = new Microsoft.Xna.Framework.Rectangle(x2, y2, width, height2); - Color dimGray = Color.DimGray; - spriteBatch2.Draw(staminaRect, destinationRectangle2, dimGray); + Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Microsoft.Xna.Framework.Rectangle((Game1.graphics.GraphicsDevice.Viewport.GetTitleSafeArea().Width - Game1.dialogueWidth) / 2, Game1.graphics.GraphicsDevice.Viewport.GetTitleSafeArea().Bottom - 128, Game1.dialogueWidth, 32), Color.LightGray); + Game1.spriteBatch.Draw(Game1.staminaRect, new Microsoft.Xna.Framework.Rectangle((Game1.graphics.GraphicsDevice.Viewport.GetTitleSafeArea().Width - Game1.dialogueWidth) / 2, Game1.graphics.GraphicsDevice.Viewport.GetTitleSafeArea().Bottom - 128, (int)((double)Game1.pauseAccumulator / (double)Game1.pauseTime * (double)Game1.dialogueWidth), 32), Color.DimGray); } if (Game1.eventUp && (Game1.currentLocation != null && Game1.currentLocation.currentEvent != null)) Game1.currentLocation.currentEvent.drawAfterMap(Game1.spriteBatch); @@ -1219,38 +1249,31 @@ namespace StardewModdingAPI.Framework overlayTempSprite.draw(Game1.spriteBatch, true, 0, 0, 1f); if (Game1.debugMode) { - SpriteBatch spriteBatch = Game1.spriteBatch; - SpriteFont smallFont = Game1.smallFont; - object[] objArray = new object[10]; - int index = 0; - string str; - if (!Game1.panMode) - str = "player: " + (object)(Game1.player.getStandingX() / 64) + ", " + (object)(Game1.player.getStandingY() / 64); + StringBuilder debugStringBuilder = SGame._debugStringBuilder; + debugStringBuilder.Clear(); + if (Game1.panMode) + { + debugStringBuilder.Append((Game1.getOldMouseX() + Game1.viewport.X) / 64); + debugStringBuilder.Append(","); + debugStringBuilder.Append((Game1.getOldMouseY() + Game1.viewport.Y) / 64); + } else - str = ((Game1.getOldMouseX() + Game1.viewport.X) / 64).ToString() + "," + (object)((Game1.getOldMouseY() + Game1.viewport.Y) / 64); - objArray[index] = (object)str; - objArray[1] = (object)" mouseTransparency: "; - objArray[2] = (object)Game1.mouseCursorTransparency; - objArray[3] = (object)" mousePosition: "; - objArray[4] = (object)Game1.getMouseX(); - objArray[5] = (object)","; - objArray[6] = (object)Game1.getMouseY(); - objArray[7] = (object)Environment.NewLine; - objArray[8] = (object)"debugOutput: "; - objArray[9] = (object)Game1.debugOutput; - string text = string.Concat(objArray); - Viewport viewport2 = this.GraphicsDevice.Viewport; - double x = (double)viewport2.TitleSafeArea.X; - viewport2 = this.GraphicsDevice.Viewport; - double y = (double)viewport2.TitleSafeArea.Y; - Vector2 position = new Vector2((float)x, (float)y); - Color red = Color.Red; - double num2 = 0.0; - Vector2 zero = Vector2.Zero; - double num3 = 1.0; - int num4 = 0; - double num5 = 0.99999988079071; - spriteBatch.DrawString(smallFont, text, position, red, (float)num2, zero, (float)num3, (SpriteEffects)num4, (float)num5); + { + debugStringBuilder.Append("player: "); + debugStringBuilder.Append(Game1.player.getStandingX() / 64); + debugStringBuilder.Append(", "); + debugStringBuilder.Append(Game1.player.getStandingY() / 64); + } + debugStringBuilder.Append(" mouseTransparency: "); + debugStringBuilder.Append(Game1.mouseCursorTransparency); + debugStringBuilder.Append(" mousePosition: "); + debugStringBuilder.Append(Game1.getMouseX()); + debugStringBuilder.Append(","); + debugStringBuilder.Append(Game1.getMouseY()); + debugStringBuilder.Append(Environment.NewLine); + debugStringBuilder.Append("debugOutput: "); + debugStringBuilder.Append(Game1.debugOutput); + Game1.spriteBatch.DrawString(Game1.smallFont, debugStringBuilder, new Vector2((float)this.GraphicsDevice.Viewport.GetTitleSafeArea().X, (float)(this.GraphicsDevice.Viewport.GetTitleSafeArea().Y + Game1.smallFont.LineSpacing * 8)), Color.Red, 0.0f, Vector2.Zero, 1f, SpriteEffects.None, 0.9999999f); } if (Game1.showKeyHelp) Game1.spriteBatch.DrawString(Game1.smallFont, Game1.keyHelpString, new Vector2(64f, (float)(Game1.viewport.Height - 64 - (Game1.dialogueUp ? 192 + (Game1.isQuestion ? Game1.questionChoices.Count * 64 : 0) : 0)) - Game1.smallFont.MeasureString(Game1.keyHelpString).Y), Color.LightGray, 0.0f, Vector2.Zero, 1f, SpriteEffects.None, 0.9999999f); @@ -1279,6 +1302,7 @@ namespace StardewModdingAPI.Framework Game1.spriteBatch.End(); this.drawOverlays(Game1.spriteBatch); this.renderScreenBuffer(); + //base.Draw(gameTime); } } } -- cgit From 30e89b3a3373d3a73f62e7297ac27db8de70246b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 30 Mar 2018 22:51:34 -0400 Subject: fix mods not being loaded if an optional dependency is installed but skipped --- docs/release-notes.md | 5 ++++- src/SMAPI/Framework/ModLoading/ModResolver.cs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/SMAPI') diff --git a/docs/release-notes.md b/docs/release-notes.md index a3e1abbd..3406e735 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -15,7 +15,10 @@ * Added support for beta releases on the home page. --> -## vNext +## 2.5.5 +* For players: + * Fixed mods not being loaded if an optional dependency is installed but skipped. + * For the [log parser][]: * Tweaked UI. diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index f878a1b9..a9896278 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -352,6 +352,7 @@ namespace StardewModdingAPI.Framework.ModLoading { // sorted successfully case ModDependencyStatus.Sorted: + case ModDependencyStatus.Failed when !dependency.IsRequired: // ignore failed optional dependency break; // failed, which means this mod can't be loaded either -- cgit From f41896041dcdc9ab5ac014f2b185d86e2f21ebf9 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 10 Apr 2018 18:05:21 -0400 Subject: fix typo in config file --- src/SMAPI/StardewModdingAPI.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SMAPI') diff --git a/src/SMAPI/StardewModdingAPI.config.json b/src/SMAPI/StardewModdingAPI.config.json index 5b6bae12..f7082e96 100644 --- a/src/SMAPI/StardewModdingAPI.config.json +++ b/src/SMAPI/StardewModdingAPI.config.json @@ -59,7 +59,7 @@ This file contains advanced configuration for SMAPI. You generally shouldn't cha * - A JSON structure containing any of four manifest fields (ID, Name, Author, and * EntryDll) to match. * - * - MapLocalVersions and MapRemoteVersions crrect local manifest versions and remote versions + * - MapLocalVersions and MapRemoteVersions correct local manifest versions and remote versions * during update checks. For example, if the API returns version '1.1-1078' where '1078' is * intended to be a build number, MapRemoteVersions can map it to '1.1' when comparing to the * mod's current version. This is only meant to support legacy mods with injected update keys. -- cgit From 9fba3c12667555958e2eb6ecf1d2ebe47fd77c58 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 10 Apr 2018 18:20:49 -0400 Subject: add context properties for multiplayer, update release notes (#453) --- docs/release-notes.md | 4 +++- src/SMAPI/Context.cs | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/SMAPI') diff --git a/docs/release-notes.md b/docs/release-notes.md index 3406e735..c04b6bdf 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,12 +3,14 @@ ## 2.6 alpha * For players: * Added support for Stardew Valley 1.3+; no longer compatible with earlier versions. + * Added `Context.IsMultiplayer` and `Context.IsMainPlayer` flags. * Fixed SMAPI update alerts linking to the GitHub repository instead of [smapi.io](https://smapi.io). * Fixed SMAPI update checks not showing newer beta versions when using a beta version. * For modders: * Dropped some deprecated APIs. - * Fixed some assets not being editable. + * Fixed assets loaded by temporary content managers not being editable. + * Fixed issue where assets didn't reload correctly when the player switches language. * For SMAPI developers: * Added prerelease versions to the mod update-check API response where available (GitHub only). diff --git a/src/SMAPI/Context.cs b/src/SMAPI/Context.cs index 119e14c8..7ed9b052 100644 --- a/src/SMAPI/Context.cs +++ b/src/SMAPI/Context.cs @@ -1,4 +1,4 @@ -using StardewModdingAPI.Events; +using StardewModdingAPI.Events; using StardewValley; using StardewValley.Menus; @@ -25,6 +25,12 @@ namespace StardewModdingAPI /// Whether the game is currently running the draw loop. This isn't relevant to most mods, since you should use to draw to the screen. public static bool IsInDrawLoop { get; internal set; } + /// Whether and the player loaded the save in multiplayer mode (regardless of whether any other players are connected). + public static bool IsMultiplayer => Context.IsWorldReady && Game1.multiplayerMode != Game1.singlePlayer; + + /// Whether and the current player is the main player. This is always true in single-player, and true when hosting in multiplayer. + public static bool IsMainPlayer => Context.IsWorldReady && Game1.IsMasterGame; + /**** ** Internal ****/ -- cgit From fa335f80beee17f17ecedcfa7bcb6f9967a39776 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 11 Apr 2018 15:41:32 -0400 Subject: fix crash when player has duplicate item references --- docs/release-notes.md | 3 ++- src/SMAPI/Framework/SGame.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/SMAPI') diff --git a/docs/release-notes.md b/docs/release-notes.md index c65d6e0d..66d911b7 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -4,7 +4,6 @@ * For players: * Added support for Stardew Valley 1.3+; no longer compatible with earlier versions. * Added `Context.IsMultiplayer` and `Context.IsMainPlayer` flags. - * Fixed SMAPI update alerts linking to the GitHub repository instead of [smapi.io](https://smapi.io). * Fixed SMAPI update checks not showing newer beta versions when using a beta version. * For modders: @@ -21,6 +20,8 @@ ## 2.5.5 * For players: * Fixed mods not being loaded if an optional dependency is installed but skipped. + * Fixed rare crash when the game duplicates an item. + * Fixed SMAPI update alerts linking to the GitHub repository instead of [smapi.io](https://smapi.io). * For the [log parser][]: * Tweaked UI. diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs index ae702711..9af02dd4 100644 --- a/src/SMAPI/Framework/SGame.cs +++ b/src/SMAPI/Framework/SGame.cs @@ -569,7 +569,7 @@ namespace StardewModdingAPI.Framework this.PreviousForagingLevel = Game1.player.foragingLevel; this.PreviousMiningLevel = Game1.player.miningLevel; this.PreviousLuckLevel = Game1.player.luckLevel; - this.PreviousItems = Game1.player.items.Where(n => n != null).ToDictionary(n => n, n => n.Stack); + this.PreviousItems = Game1.player.items.Where(n => n != null).Distinct().ToDictionary(n => n, n => n.Stack); this.PreviousLocationObjects = this.GetHash(Game1.currentLocation.objects); this.PreviousTime = Game1.timeOfDay; this.PreviousMineLevel = Game1.mine?.mineLevel ?? 0; -- cgit From b425bff1e992efbab154e3ef289e8cc4c41ab714 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 11 Apr 2018 15:43:11 -0400 Subject: update for Stardew Valley 1.3.0.26 (#453) --- src/SMAPI/Framework/SGame.cs | 52 ++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 23 deletions(-) (limited to 'src/SMAPI') diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs index 9af02dd4..0c31b98e 100644 --- a/src/SMAPI/Framework/SGame.cs +++ b/src/SMAPI/Framework/SGame.cs @@ -136,8 +136,10 @@ namespace StardewModdingAPI.Framework /// Whether this is the very first update tick since the game started. private bool FirstUpdate; +#if !STARDEW_VALLEY_1_3 /// The current game instance. private static SGame Instance; +#endif /// A callback to invoke after the game finishes initialising. private readonly Action OnGameInitialised; @@ -148,6 +150,7 @@ namespace StardewModdingAPI.Framework /// Simplifies access to private game code. private static Reflector Reflection; +#if !STARDEW_VALLEY_1_3 // ReSharper disable ArrangeStaticMemberQualifier, ArrangeThisQualifier, InconsistentNaming /// Used to access private fields and methods. private static List _fpsList => SGame.Reflection.GetField>(typeof(Game1), nameof(_fpsList)).GetValue(); @@ -163,12 +166,13 @@ namespace StardewModdingAPI.Framework private readonly Action drawFarmBuildings = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(drawFarmBuildings)).Invoke(); private readonly Action drawHUD = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(drawHUD)).Invoke(); private readonly Action drawDialogueBox = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(drawDialogueBox)).Invoke(); + private readonly Action renderScreenBuffer = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(renderScreenBuffer)).Invoke(); + // ReSharper restore ArrangeStaticMemberQualifier, ArrangeThisQualifier, InconsistentNaming +#endif + #if STARDEW_VALLEY_1_3 - private readonly Action drawOverlays = spriteBatch => SGame.Reflection.GetMethod(SGame.Instance, nameof(SGame.drawOverlays)).Invoke(spriteBatch); private static StringBuilder _debugStringBuilder => SGame.Reflection.GetField(typeof(Game1), nameof(_debugStringBuilder)).GetValue(); #endif - private readonly Action renderScreenBuffer = () => SGame.Reflection.GetMethod(SGame.Instance, nameof(renderScreenBuffer)).Invoke(); - // ReSharper restore ArrangeStaticMemberQualifier, ArrangeThisQualifier, InconsistentNaming /********* @@ -195,7 +199,9 @@ namespace StardewModdingAPI.Framework this.Monitor = monitor; this.Events = eventManager; this.FirstUpdate = true; +#if !STARDEW_VALLEY_1_3 SGame.Instance = this; +#endif SGame.Reflection = reflection; this.OnGameInitialised = onGameInitialised; if (this.ContentCore == null) // shouldn't happen since CreateContentManager is called first, but let's init here just in case @@ -256,7 +262,7 @@ namespace StardewModdingAPI.Framework // a small chance that the task will finish after we defer but before the game checks, // which means technically events should be raised, but the effects of missing one // update tick are neglible and not worth the complications of bypassing Game1.Update. - if (SGame._newDayTask != null) + if (Game1._newDayTask != null) { base.Update(gameTime); this.Events.Specialised_UnvalidatedUpdateTick.Raise(); @@ -681,27 +687,27 @@ namespace StardewModdingAPI.Framework { if (Game1.debugMode) { - if (SGame._fpsStopwatch.IsRunning) + if (Game1._fpsStopwatch.IsRunning) { - float totalSeconds = (float)SGame._fpsStopwatch.Elapsed.TotalSeconds; - SGame._fpsList.Add(totalSeconds); - while (SGame._fpsList.Count >= 120) - SGame._fpsList.RemoveAt(0); + float totalSeconds = (float)Game1._fpsStopwatch.Elapsed.TotalSeconds; + Game1._fpsList.Add(totalSeconds); + while (Game1._fpsList.Count >= 120) + Game1._fpsList.RemoveAt(0); float num = 0.0f; - foreach (float fps in SGame._fpsList) + foreach (float fps in Game1._fpsList) num += fps; - SGame._fps = (float)(1.0 / ((double)num / (double)SGame._fpsList.Count)); + Game1._fps = (float)(1.0 / ((double)num / (double)Game1._fpsList.Count)); } - SGame._fpsStopwatch.Restart(); + Game1._fpsStopwatch.Restart(); } else { - if (SGame._fpsStopwatch.IsRunning) - SGame._fpsStopwatch.Reset(); - SGame._fps = 0.0f; - SGame._fpsList.Clear(); + if (Game1._fpsStopwatch.IsRunning) + Game1._fpsStopwatch.Reset(); + Game1._fps = 0.0f; + Game1._fpsList.Clear(); } - if (SGame._newDayTask != null) + if (Game1._newDayTask != null) { this.GraphicsDevice.Clear(this.bgColor); //base.Draw(gameTime); @@ -709,7 +715,7 @@ namespace StardewModdingAPI.Framework else { if ((double)Game1.options.zoomLevel != 1.0) - this.GraphicsDevice.SetRenderTarget(this.screenWrapper); + this.GraphicsDevice.SetRenderTarget(this.screen); if (this.IsSaving) { this.GraphicsDevice.Clear(this.bgColor); @@ -765,7 +771,7 @@ namespace StardewModdingAPI.Framework this.GraphicsDevice.SetRenderTarget((RenderTarget2D)null); this.GraphicsDevice.Clear(this.bgColor); Game1.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone); - Game1.spriteBatch.Draw((Texture2D)this.screenWrapper, Vector2.Zero, new Microsoft.Xna.Framework.Rectangle?(this.screenWrapper.Bounds), Color.White, 0.0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f); + Game1.spriteBatch.Draw((Texture2D)this.screen, Vector2.Zero, new Microsoft.Xna.Framework.Rectangle?(this.screen.Bounds), Color.White, 0.0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f); Game1.spriteBatch.End(); } this.drawOverlays(Game1.spriteBatch); @@ -794,7 +800,7 @@ namespace StardewModdingAPI.Framework this.GraphicsDevice.SetRenderTarget((RenderTarget2D)null); this.GraphicsDevice.Clear(this.bgColor); Game1.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone); - Game1.spriteBatch.Draw((Texture2D)this.screenWrapper, Vector2.Zero, new Microsoft.Xna.Framework.Rectangle?(this.screenWrapper.Bounds), Color.White, 0.0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f); + Game1.spriteBatch.Draw((Texture2D)this.screen, Vector2.Zero, new Microsoft.Xna.Framework.Rectangle?(this.screen.Bounds), Color.White, 0.0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f); Game1.spriteBatch.End(); } this.drawOverlays(Game1.spriteBatch); @@ -823,7 +829,7 @@ namespace StardewModdingAPI.Framework this.GraphicsDevice.SetRenderTarget((RenderTarget2D)null); this.GraphicsDevice.Clear(this.bgColor); Game1.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone); - Game1.spriteBatch.Draw((Texture2D)this.screenWrapper, Vector2.Zero, new Microsoft.Xna.Framework.Rectangle?(this.screenWrapper.Bounds), Color.White, 0.0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f); + Game1.spriteBatch.Draw((Texture2D)this.screen, Vector2.Zero, new Microsoft.Xna.Framework.Rectangle?(this.screen.Bounds), Color.White, 0.0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f); Game1.spriteBatch.End(); } this.drawOverlays(Game1.spriteBatch); @@ -863,7 +869,7 @@ namespace StardewModdingAPI.Framework this.GraphicsDevice.SetRenderTarget((RenderTarget2D)null); this.GraphicsDevice.Clear(this.bgColor); Game1.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone); - Game1.spriteBatch.Draw((Texture2D)this.screenWrapper, Vector2.Zero, new Microsoft.Xna.Framework.Rectangle?(this.screenWrapper.Bounds), Color.White, 0.0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f); + Game1.spriteBatch.Draw((Texture2D)this.screen, Vector2.Zero, new Microsoft.Xna.Framework.Rectangle?(this.screen.Bounds), Color.White, 0.0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f); Game1.spriteBatch.End(); } this.drawOverlays(Game1.spriteBatch); @@ -907,7 +913,7 @@ namespace StardewModdingAPI.Framework } } Game1.spriteBatch.End(); - this.GraphicsDevice.SetRenderTarget((double)Game1.options.zoomLevel == 1.0 ? (RenderTarget2D)null : this.screenWrapper); + this.GraphicsDevice.SetRenderTarget((double)Game1.options.zoomLevel == 1.0 ? (RenderTarget2D)null : this.screen); } if (Game1.bloomDay && Game1.bloom != null) Game1.bloom.BeginDraw(); -- cgit From e0488fa5b2a0a5236a7a034d6712392eb8ed1918 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 11 Apr 2018 16:08:58 -0400 Subject: fix error when a remote mod version is invalid (#462) --- docs/release-notes.md | 5 +++-- src/SMAPI/Program.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/SMAPI') diff --git a/docs/release-notes.md b/docs/release-notes.md index 66d911b7..1a28af70 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -19,9 +19,10 @@ ## 2.5.5 * For players: - * Fixed mods not being loaded if an optional dependency is installed but skipped. - * Fixed rare crash when the game duplicates an item. + * Fixed mod not loaded if it has an optional dependency that's loaded but skipped. + * Fixed mod update alerts not shown if one mod has an invalid remote version. * Fixed SMAPI update alerts linking to the GitHub repository instead of [smapi.io](https://smapi.io). + * Fixed rare crash if the game duplicates an item. * For the [log parser][]: * Tweaked UI. diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 1b8cb2ba..5a1f7409 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -629,7 +629,7 @@ namespace StardewModdingAPI // compare versions bool isUpdate = remoteVersion.IsNewerThan(localVersion); - this.VerboseLog($" {mod.DisplayName} ({result.Key}): {(isUpdate ? $"{mod.Manifest.Version}{(!localVersion.Equals(mod.Manifest.Version) ? $" [{localVersion}]" : "")} => {remoteInfo.Version}{(!remoteVersion.Equals(new SemanticVersion(remoteInfo.Version)) ? $" [{remoteVersion}]" : "")}" : "okay")}."); + this.VerboseLog($" {mod.DisplayName} ({result.Key}): {(isUpdate ? $"{mod.Manifest.Version}{(!localVersion.Equals(mod.Manifest.Version) ? $" [{localVersion}]" : "")} => {remoteInfo.Version}" : "okay")}."); if (isUpdate) { if (!updatesByMod.TryGetValue(mod, out ModInfoModel other) || remoteVersion.IsNewerThan(other.Version)) -- cgit From e4222ad1fd5b32ca81ee55e025b4e421582cb2d3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 11 Apr 2018 16:17:23 -0400 Subject: fix error when two content packs use different capitalisation for the same required mod ID (#469) --- docs/release-notes.md | 1 + src/SMAPI/Program.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/SMAPI') diff --git a/docs/release-notes.md b/docs/release-notes.md index 1a28af70..a5bd205f 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -22,6 +22,7 @@ * Fixed mod not loaded if it has an optional dependency that's loaded but skipped. * Fixed mod update alerts not shown if one mod has an invalid remote version. * Fixed SMAPI update alerts linking to the GitHub repository instead of [smapi.io](https://smapi.io). + * Fixed error when two content packs use different capitalisation for the same required mod ID. * Fixed rare crash if the game duplicates an item. * For the [log parser][]: diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 5a1f7409..ff4e9a50 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -736,7 +736,7 @@ namespace StardewModdingAPI // get content packs by mod ID IDictionary contentPacksByModID = loadedContentPacks - .GroupBy(p => p.Manifest.ContentPackFor.UniqueID) + .GroupBy(p => p.Manifest.ContentPackFor.UniqueID, StringComparer.InvariantCultureIgnoreCase) .ToDictionary( group => group.Key, group => group.Select(metadata => metadata.ContentPack).ToArray(), -- cgit From 4fa46fd741c90695a02e564fe4c55715ec86463f Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 11 Apr 2018 18:36:58 -0400 Subject: fix error in Stardew Valley 1.2 build mode (#453) --- src/SMAPI/Framework/SGame.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/SMAPI') diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs index 0c31b98e..c6e9aa92 100644 --- a/src/SMAPI/Framework/SGame.cs +++ b/src/SMAPI/Framework/SGame.cs @@ -262,7 +262,11 @@ namespace StardewModdingAPI.Framework // a small chance that the task will finish after we defer but before the game checks, // which means technically events should be raised, but the effects of missing one // update tick are neglible and not worth the complications of bypassing Game1.Update. +#if STARDEW_VALLEY_1_3 if (Game1._newDayTask != null) +#else + if (SGame._newDayTask != null) +#endif { base.Update(gameTime); this.Events.Specialised_UnvalidatedUpdateTick.Raise(); -- cgit From 15a80ab2442c18a478dbaec9d5120ec0cf25770b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 11 Apr 2018 18:47:32 -0400 Subject: update for 2.5.5 release --- build/GlobalAssemblyInfo.cs | 4 ++-- src/SMAPI.Mods.ConsoleCommands/manifest.json | 2 +- src/SMAPI/Constants.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/SMAPI') diff --git a/build/GlobalAssemblyInfo.cs b/build/GlobalAssemblyInfo.cs index d2cf8fe7..f2477486 100644 --- a/build/GlobalAssemblyInfo.cs +++ b/build/GlobalAssemblyInfo.cs @@ -1,5 +1,5 @@ using System.Reflection; [assembly: AssemblyProduct("SMAPI")] -[assembly: AssemblyVersion("2.5.4")] -[assembly: AssemblyFileVersion("2.5.4")] +[assembly: AssemblyVersion("2.5.5")] +[assembly: AssemblyFileVersion("2.5.5")] diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json index a56cf66d..b6f9b81c 100644 --- a/src/SMAPI.Mods.ConsoleCommands/manifest.json +++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json @@ -1,7 +1,7 @@ { "Name": "Console Commands", "Author": "SMAPI", - "Version": "2.5.4", + "Version": "2.5.5", "Description": "Adds SMAPI console commands that let you manipulate the game.", "UniqueID": "SMAPI.ConsoleCommands", "EntryDll": "ConsoleCommands.dll" diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 72b9c78e..1e35c030 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -41,7 +41,7 @@ namespace StardewModdingAPI #if STARDEW_VALLEY_1_3 new SemanticVersion($"2.6-alpha.{DateTime.UtcNow:yyyyMMddHHmm}"); #else - new SemanticVersion("2.5.4"); + new SemanticVersion("2.5.5"); #endif /// The minimum supported version of Stardew Valley. -- cgit