unify SMAPI versions for SDV 1.11 and 1.2 using compile switches where needed (#264)
This commit is contained in:
parent
ceabb05a84
commit
6f43a3dae5
|
@ -12,11 +12,10 @@ For mod developers:
|
||||||
|
|
||||||
## 1.10
|
## 1.10
|
||||||
See [log](https://github.com/Pathoschild/SMAPI/compare/1.9...1.10).
|
See [log](https://github.com/Pathoschild/SMAPI/compare/1.9...1.10).
|
||||||
* Updated for Stardew Valley 1.2.
|
|
||||||
* SMAPI now rewrites many mods for compatibility with game updates, but some mods may still need an update.
|
|
||||||
|
|
||||||
## 1.10
|
For players:
|
||||||
See [log](https://github.com/Pathoschild/SMAPI/compare/1.9...1.9.1).
|
* Added support for Stardew Valley 1.2 beta.
|
||||||
|
* SMAPI now rewrites many mods for compatibility with game updates, but some mods may still need an update.
|
||||||
|
|
||||||
For mod developers:
|
For mod developers:
|
||||||
* Fixed mouse-changed event never updating prior mouse position.
|
* Fixed mouse-changed event never updating prior mouse position.
|
||||||
|
|
|
@ -36,10 +36,20 @@ namespace StardewModdingAPI
|
||||||
public static ISemanticVersion ApiVersion { get; } = new SemanticVersion(1, 10, 0);
|
public static ISemanticVersion ApiVersion { get; } = new SemanticVersion(1, 10, 0);
|
||||||
|
|
||||||
/// <summary>The minimum supported version of Stardew Valley.</summary>
|
/// <summary>The minimum supported version of Stardew Valley.</summary>
|
||||||
public static ISemanticVersion MinimumGameVersion { get; } = new SemanticVersion("1.2.15");
|
public static ISemanticVersion MinimumGameVersion { get; } =
|
||||||
|
#if SDV_1_2
|
||||||
|
new SemanticVersion("1.2.15");
|
||||||
|
#else
|
||||||
|
new SemanticVersion("1.1");
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>The maximum supported version of Stardew Valley.</summary>
|
/// <summary>The maximum supported version of Stardew Valley.</summary>
|
||||||
public static ISemanticVersion MaximumGameVersion { get; } = null;
|
public static ISemanticVersion MaximumGameVersion { get; } =
|
||||||
|
#if SDV_1_2
|
||||||
|
null;
|
||||||
|
#else
|
||||||
|
new SemanticVersion("1.1.1");
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>The path to the game folder.</summary>
|
/// <summary>The path to the game folder.</summary>
|
||||||
public static string ExecutionPath { get; } = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
public static string ExecutionPath { get; } = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
|
@ -146,8 +156,10 @@ namespace StardewModdingAPI
|
||||||
/****
|
/****
|
||||||
** Finders throw an exception when incompatible code is found.
|
** Finders throw an exception when incompatible code is found.
|
||||||
****/
|
****/
|
||||||
|
#if SDV_1_2
|
||||||
// changes in Stardew Valley 1.2 (with no rewriters)
|
// changes in Stardew Valley 1.2 (with no rewriters)
|
||||||
new FieldFinder("StardewValley.Item", "set_Name"),
|
new FieldFinder("StardewValley.Item", "set_Name"),
|
||||||
|
#endif
|
||||||
|
|
||||||
// APIs removed in SMAPI 1.9
|
// APIs removed in SMAPI 1.9
|
||||||
new TypeFinder("StardewModdingAPI.Advanced.ConfigFile"),
|
new TypeFinder("StardewModdingAPI.Advanced.ConfigFile"),
|
||||||
|
@ -172,6 +184,7 @@ namespace StardewModdingAPI
|
||||||
// crossplatform
|
// crossplatform
|
||||||
new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchWrapper), onlyIfPlatformChanged: true),
|
new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchWrapper), onlyIfPlatformChanged: true),
|
||||||
|
|
||||||
|
#if SDV_1_2
|
||||||
// Stardew Valley 1.2
|
// Stardew Valley 1.2
|
||||||
new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.activeClickableMenu)),
|
new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.activeClickableMenu)),
|
||||||
new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.currentMinigame)),
|
new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.currentMinigame)),
|
||||||
|
@ -179,6 +192,7 @@ namespace StardewModdingAPI
|
||||||
new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.player)),
|
new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.player)),
|
||||||
new FieldReplaceRewriter(typeof(Game1), "borderFont", nameof(Game1.smallFont)),
|
new FieldReplaceRewriter(typeof(Game1), "borderFont", nameof(Game1.smallFont)),
|
||||||
new FieldReplaceRewriter(typeof(Game1), "smoothFont", nameof(Game1.smallFont)),
|
new FieldReplaceRewriter(typeof(Game1), "smoothFont", nameof(Game1.smallFont)),
|
||||||
|
#endif
|
||||||
|
|
||||||
// SMAPI 1.9
|
// SMAPI 1.9
|
||||||
new TypeReferenceRewriter("StardewModdingAPI.Inheritance.ItemStackChange", typeof(ItemStackChange))
|
new TypeReferenceRewriter("StardewModdingAPI.Inheritance.ItemStackChange", typeof(ItemStackChange))
|
||||||
|
|
|
@ -138,6 +138,9 @@ namespace StardewModdingAPI.Framework
|
||||||
mod.ID == key
|
mod.ID == key
|
||||||
&& (mod.LowerSemanticVersion == null || !manifest.Version.IsOlderThan(mod.LowerSemanticVersion))
|
&& (mod.LowerSemanticVersion == null || !manifest.Version.IsOlderThan(mod.LowerSemanticVersion))
|
||||||
&& !manifest.Version.IsNewerThan(mod.UpperSemanticVersion)
|
&& !manifest.Version.IsNewerThan(mod.UpperSemanticVersion)
|
||||||
|
#if !SDV_1_2
|
||||||
|
&& !mod.OnlyStardewValleyBeta
|
||||||
|
#endif
|
||||||
select mod
|
select mod
|
||||||
).FirstOrDefault();
|
).FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,9 @@ namespace StardewModdingAPI.Framework.Models
|
||||||
/// <summary>Indicates how SMAPI should consider the mod.</summary>
|
/// <summary>Indicates how SMAPI should consider the mod.</summary>
|
||||||
public ModCompatibilityType Compatibility { get; set; }
|
public ModCompatibilityType Compatibility { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Whether this record only applies to the Stardew Valley 1.2 beta.</summary>
|
||||||
|
public bool OnlyStardewValleyBeta { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/****
|
/****
|
||||||
** Injected
|
** Injected
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
@ -16,8 +14,14 @@ using StardewValley.Locations;
|
||||||
using StardewValley.Menus;
|
using StardewValley.Menus;
|
||||||
using StardewValley.Tools;
|
using StardewValley.Tools;
|
||||||
using xTile.Dimensions;
|
using xTile.Dimensions;
|
||||||
using xTile.Layers;
|
|
||||||
using SFarmer = StardewValley.Farmer;
|
using SFarmer = StardewValley.Farmer;
|
||||||
|
#if SDV_1_2
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using xTile.Layers;
|
||||||
|
#else
|
||||||
|
using Rectangle = Microsoft.Xna.Framework.Rectangle;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace StardewModdingAPI.Framework
|
namespace StardewModdingAPI.Framework
|
||||||
{
|
{
|
||||||
|
@ -136,8 +140,10 @@ namespace StardewModdingAPI.Framework
|
||||||
/// <summary>The player character at last check.</summary>
|
/// <summary>The player character at last check.</summary>
|
||||||
private SFarmer PreviousFarmer;
|
private SFarmer PreviousFarmer;
|
||||||
|
|
||||||
|
#if SDV_1_2
|
||||||
/// <summary>The previous content locale.</summary>
|
/// <summary>The previous content locale.</summary>
|
||||||
private LocalizedContentManager.LanguageCode? PreviousLocale;
|
private LocalizedContentManager.LanguageCode? PreviousLocale;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>An index incremented on every tick and reset every 60th tick (0–59).</summary>
|
/// <summary>An index incremented on every tick and reset every 60th tick (0–59).</summary>
|
||||||
private int CurrentUpdateTick;
|
private int CurrentUpdateTick;
|
||||||
|
@ -154,6 +160,7 @@ namespace StardewModdingAPI.Framework
|
||||||
// ReSharper disable ArrangeStaticMemberQualifier, ArrangeThisQualifier, InconsistentNaming
|
// ReSharper disable ArrangeStaticMemberQualifier, ArrangeThisQualifier, InconsistentNaming
|
||||||
/// <summary>Used to access private fields and methods.</summary>
|
/// <summary>Used to access private fields and methods.</summary>
|
||||||
private static readonly IReflectionHelper Reflection = new ReflectionHelper();
|
private static readonly IReflectionHelper Reflection = new ReflectionHelper();
|
||||||
|
#if SDV_1_2
|
||||||
private static List<float> _fpsList => SGame.Reflection.GetPrivateField<List<float>>(typeof(Game1), nameof(_fpsList)).GetValue();
|
private static List<float> _fpsList => SGame.Reflection.GetPrivateField<List<float>>(typeof(Game1), nameof(_fpsList)).GetValue();
|
||||||
private static Stopwatch _fpsStopwatch => SGame.Reflection.GetPrivateField<Stopwatch>(typeof(Game1), nameof(SGame._fpsStopwatch)).GetValue();
|
private static Stopwatch _fpsStopwatch => SGame.Reflection.GetPrivateField<Stopwatch>(typeof(Game1), nameof(SGame._fpsStopwatch)).GetValue();
|
||||||
private static float _fps
|
private static float _fps
|
||||||
|
@ -161,13 +168,21 @@ namespace StardewModdingAPI.Framework
|
||||||
set { SGame.Reflection.GetPrivateField<float>(typeof(Game1), nameof(_fps)).SetValue(value); }
|
set { SGame.Reflection.GetPrivateField<float>(typeof(Game1), nameof(_fps)).SetValue(value); }
|
||||||
}
|
}
|
||||||
private static Task _newDayTask => SGame.Reflection.GetPrivateField<Task>(typeof(Game1), nameof(_newDayTask)).GetValue();
|
private static Task _newDayTask => SGame.Reflection.GetPrivateField<Task>(typeof(Game1), nameof(_newDayTask)).GetValue();
|
||||||
|
#endif
|
||||||
private Color bgColor => SGame.Reflection.GetPrivateField<Color>(this, nameof(bgColor)).GetValue();
|
private Color bgColor => SGame.Reflection.GetPrivateField<Color>(this, nameof(bgColor)).GetValue();
|
||||||
public RenderTarget2D screenWrapper => SGame.Reflection.GetPrivateProperty<RenderTarget2D>(this, "screen").GetValue(); // deliberately renamed to avoid an infinite loop
|
public RenderTarget2D screenWrapper =>
|
||||||
|
#if SDV_1_2
|
||||||
|
SGame.Reflection.GetPrivateProperty<RenderTarget2D>(this, "screen").GetValue(); // deliberately renamed to avoid an infinite loop
|
||||||
|
#else
|
||||||
|
SGame.Reflection.GetPrivateField<RenderTarget2D>(this, "screen").GetValue(); // deliberately renamed to avoid an infinite loop
|
||||||
|
#endif
|
||||||
public BlendState lightingBlend => SGame.Reflection.GetPrivateField<BlendState>(this, nameof(lightingBlend)).GetValue();
|
public BlendState lightingBlend => SGame.Reflection.GetPrivateField<BlendState>(this, nameof(lightingBlend)).GetValue();
|
||||||
private readonly Action drawFarmBuildings = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(drawFarmBuildings)).Invoke(new object[0]);
|
private readonly Action drawFarmBuildings = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(drawFarmBuildings)).Invoke(new object[0]);
|
||||||
private readonly Action drawHUD = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(drawHUD)).Invoke(new object[0]);
|
private readonly Action drawHUD = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(drawHUD)).Invoke(new object[0]);
|
||||||
private readonly Action drawDialogueBox = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(drawDialogueBox)).Invoke(new object[0]);
|
private readonly Action drawDialogueBox = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(drawDialogueBox)).Invoke(new object[0]);
|
||||||
|
#if SDV_1_2
|
||||||
private readonly Action renderScreenBuffer = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(renderScreenBuffer)).Invoke(new object[0]);
|
private readonly Action renderScreenBuffer = () => SGame.Reflection.GetPrivateMethod(SGame.Instance, nameof(renderScreenBuffer)).Invoke(new object[0]);
|
||||||
|
#endif
|
||||||
// ReSharper restore ArrangeStaticMemberQualifier, ArrangeThisQualifier, InconsistentNaming
|
// ReSharper restore ArrangeStaticMemberQualifier, ArrangeThisQualifier, InconsistentNaming
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,6 +201,7 @@ namespace StardewModdingAPI.Framework
|
||||||
/****
|
/****
|
||||||
** Intercepted methods & events
|
** Intercepted methods & events
|
||||||
****/
|
****/
|
||||||
|
#if SDV_1_2
|
||||||
/// <summary>Constructor a content manager to read XNB files.</summary>
|
/// <summary>Constructor a content manager to read XNB files.</summary>
|
||||||
/// <param name="serviceProvider">The service provider to use to locate services.</param>
|
/// <param name="serviceProvider">The service provider to use to locate services.</param>
|
||||||
/// <param name="rootDirectory">The root directory to search for content.</param>
|
/// <param name="rootDirectory">The root directory to search for content.</param>
|
||||||
|
@ -193,11 +209,13 @@ namespace StardewModdingAPI.Framework
|
||||||
{
|
{
|
||||||
return new SContentManager(this.Content.ServiceProvider, this.Content.RootDirectory, this.Monitor);
|
return new SContentManager(this.Content.ServiceProvider, this.Content.RootDirectory, this.Monitor);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// <summary>The method called when the game is updating its state. This happens roughly 60 times per second.</summary>
|
/// <summary>The method called when the game is updating its state. This happens roughly 60 times per second.</summary>
|
||||||
/// <param name="gameTime">A snapshot of the game timing state.</param>
|
/// <param name="gameTime">A snapshot of the game timing state.</param>
|
||||||
protected override void Update(GameTime gameTime)
|
protected override void Update(GameTime gameTime)
|
||||||
{
|
{
|
||||||
|
#if SDV_1_2
|
||||||
// While a background new-day task is in progress, the game skips its own update logic
|
// While a background new-day task is in progress, the game skips its own update logic
|
||||||
// and defers to the XNA Update method. Running mod code in parallel to the background
|
// and defers to the XNA Update method. Running mod code in parallel to the background
|
||||||
// update is risky, because data changes can conflict (e.g. collection changed during
|
// update is risky, because data changes can conflict (e.g. collection changed during
|
||||||
|
@ -213,6 +231,7 @@ namespace StardewModdingAPI.Framework
|
||||||
base.Update(gameTime);
|
base.Update(gameTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// raise game loaded
|
// raise game loaded
|
||||||
if (this.FirstUpdate)
|
if (this.FirstUpdate)
|
||||||
|
@ -277,6 +296,7 @@ namespace StardewModdingAPI.Framework
|
||||||
[SuppressMessage("ReSharper", "RedundantCast", Justification = "copied from game code as-is")]
|
[SuppressMessage("ReSharper", "RedundantCast", Justification = "copied from game code as-is")]
|
||||||
[SuppressMessage("ReSharper", "RedundantExplicitNullableCreation", Justification = "copied from game code as-is")]
|
[SuppressMessage("ReSharper", "RedundantExplicitNullableCreation", Justification = "copied from game code as-is")]
|
||||||
[SuppressMessage("ReSharper", "RedundantTypeArgumentsOfMethod", Justification = "copied from game code as-is")]
|
[SuppressMessage("ReSharper", "RedundantTypeArgumentsOfMethod", Justification = "copied from game code as-is")]
|
||||||
|
#if SDV_1_2
|
||||||
protected override void Draw(GameTime gameTime)
|
protected override void Draw(GameTime gameTime)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -931,6 +951,425 @@ namespace StardewModdingAPI.Framework
|
||||||
this.Monitor.Log($"An error occured in the overridden draw loop: {ex.GetLogSummary()}", LogLevel.Error);
|
this.Monitor.Log($"An error occured in the overridden draw loop: {ex.GetLogSummary()}", LogLevel.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
protected override void Draw(GameTime gameTime)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!this.ZoomLevelIsOne)
|
||||||
|
this.GraphicsDevice.SetRenderTarget(this.screenWrapper);
|
||||||
|
|
||||||
|
this.GraphicsDevice.Clear(this.bgColor);
|
||||||
|
if (Game1.options.showMenuBackground && Game1.activeClickableMenu != null && Game1.activeClickableMenu.showWithoutTransparencyIfOptionIsSet())
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Game1.activeClickableMenu.drawBackground(Game1.spriteBatch);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
this.Monitor.Log($"The {Game1.activeClickableMenu.GetType().FullName} menu crashed while drawing its background. SMAPI will force it to exit to avoid crashing the game.\n{ex.GetLogSummary()}", LogLevel.Error);
|
||||||
|
Game1.activeClickableMenu.exitThisMenu();
|
||||||
|
}
|
||||||
|
GraphicsEvents.InvokeOnPreRenderGuiEvent(this.Monitor);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Game1.activeClickableMenu.draw(Game1.spriteBatch);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
this.Monitor.Log($"The {Game1.activeClickableMenu.GetType().FullName} menu crashed while drawing itself. SMAPI will force it to exit to avoid crashing the game.\n{ex.GetLogSummary()}", LogLevel.Error);
|
||||||
|
Game1.activeClickableMenu.exitThisMenu();
|
||||||
|
}
|
||||||
|
GraphicsEvents.InvokeOnPostRenderGuiEvent(this.Monitor);
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
if (!this.ZoomLevelIsOne)
|
||||||
|
{
|
||||||
|
this.GraphicsDevice.SetRenderTarget(null);
|
||||||
|
this.GraphicsDevice.Clear(this.bgColor);
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone);
|
||||||
|
Game1.spriteBatch.Draw(this.screenWrapper, Vector2.Zero, this.screenWrapper.Bounds, Color.White, 0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f);
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Game1.gameMode == 11)
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
Game1.spriteBatch.DrawString(Game1.smoothFont, "Stardew Valley has crashed...", new Vector2(16f, 16f), Color.HotPink);
|
||||||
|
Game1.spriteBatch.DrawString(Game1.smoothFont, "Please send the error report or a screenshot of this message to @ConcernedApe. (http://stardewvalley.net/contact/)", new Vector2(16f, 32f), new Color(0, 255, 0));
|
||||||
|
Game1.spriteBatch.DrawString(Game1.smoothFont, Game1.parseText(Game1.errorMessage, Game1.smoothFont, Game1.graphics.GraphicsDevice.Viewport.Width), new Vector2(16f, 48f), Color.White);
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Game1.currentMinigame != null)
|
||||||
|
{
|
||||||
|
Game1.currentMinigame.draw(Game1.spriteBatch);
|
||||||
|
if (Game1.globalFade && !Game1.menuUp && (!Game1.nameSelectUp || Game1.messagePause))
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, Game1.graphics.GraphicsDevice.Viewport.Bounds, Color.Black * ((Game1.gameMode == 0) ? (1f - Game1.fadeToBlackAlpha) : Game1.fadeToBlackAlpha));
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
}
|
||||||
|
if (!this.ZoomLevelIsOne)
|
||||||
|
{
|
||||||
|
this.GraphicsDevice.SetRenderTarget(null);
|
||||||
|
this.GraphicsDevice.Clear(this.bgColor);
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone);
|
||||||
|
Game1.spriteBatch.Draw(this.screenWrapper, Vector2.Zero, this.screenWrapper.Bounds, Color.White, 0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f);
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Game1.showingEndOfNightStuff)
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Game1.activeClickableMenu?.draw(Game1.spriteBatch);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
this.Monitor.Log($"The {Game1.activeClickableMenu.GetType().FullName} menu crashed while drawing itself. SMAPI will force it to exit to avoid crashing the game.\n{ex.GetLogSummary()}", LogLevel.Error);
|
||||||
|
Game1.activeClickableMenu.exitThisMenu();
|
||||||
|
}
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
if (!this.ZoomLevelIsOne)
|
||||||
|
{
|
||||||
|
this.GraphicsDevice.SetRenderTarget(null);
|
||||||
|
this.GraphicsDevice.Clear(this.bgColor);
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone);
|
||||||
|
Game1.spriteBatch.Draw(this.screenWrapper, Vector2.Zero, this.screenWrapper.Bounds, Color.White, 0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f);
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Game1.gameMode == 6)
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
string text = "";
|
||||||
|
int num = 0;
|
||||||
|
while (num < gameTime.TotalGameTime.TotalMilliseconds % 999.0 / 333.0)
|
||||||
|
{
|
||||||
|
text += ".";
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
SpriteText.drawString(Game1.spriteBatch, "Loading" + text, 64, Game1.graphics.GraphicsDevice.Viewport.Height - 64, 999, -1, 999, 1f, 1f, false, 0, "Loading...");
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
if (!this.ZoomLevelIsOne)
|
||||||
|
{
|
||||||
|
this.GraphicsDevice.SetRenderTarget(null);
|
||||||
|
this.GraphicsDevice.Clear(this.bgColor);
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone);
|
||||||
|
Game1.spriteBatch.Draw(this.screenWrapper, Vector2.Zero, this.screenWrapper.Bounds, Color.White, 0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f);
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Game1.gameMode == 0)
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Game1.drawLighting)
|
||||||
|
{
|
||||||
|
this.GraphicsDevice.SetRenderTarget(Game1.lightmap);
|
||||||
|
this.GraphicsDevice.Clear(Color.White * 0f);
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, null, null);
|
||||||
|
Game1.spriteBatch.Draw(Game1.staminaRect, Game1.lightmap.Bounds, Game1.currentLocation.name.Equals("UndergroundMine") ? Game1.mine.getLightingColor(gameTime) : ((!Game1.ambientLight.Equals(Color.White) && (!Game1.isRaining || !Game1.currentLocation.isOutdoors)) ? Game1.ambientLight : Game1.outdoorLight));
|
||||||
|
for (int i = 0; i < Game1.currentLightSources.Count; i++)
|
||||||
|
{
|
||||||
|
if (Utility.isOnScreen(Game1.currentLightSources.ElementAt(i).position, (int)(Game1.currentLightSources.ElementAt(i).radius * Game1.tileSize * 4f)))
|
||||||
|
Game1.spriteBatch.Draw(Game1.currentLightSources.ElementAt(i).lightTexture, Game1.GlobalToLocal(Game1.viewport, Game1.currentLightSources.ElementAt(i).position) / Game1.options.lightingQuality, Game1.currentLightSources.ElementAt(i).lightTexture.Bounds, Game1.currentLightSources.ElementAt(i).color, 0f, new Vector2(Game1.currentLightSources.ElementAt(i).lightTexture.Bounds.Center.X, Game1.currentLightSources.ElementAt(i).lightTexture.Bounds.Center.Y), Game1.currentLightSources.ElementAt(i).radius / Game1.options.lightingQuality, SpriteEffects.None, 0.9f);
|
||||||
|
}
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
this.GraphicsDevice.SetRenderTarget(this.ZoomLevelIsOne ? null : this.screenWrapper);
|
||||||
|
}
|
||||||
|
if (Game1.bloomDay)
|
||||||
|
Game1.bloom?.BeginDraw();
|
||||||
|
this.GraphicsDevice.Clear(this.bgColor);
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
GraphicsEvents.InvokeOnPreRenderEvent(this.Monitor);
|
||||||
|
Game1.background?.draw(Game1.spriteBatch);
|
||||||
|
Game1.mapDisplayDevice.BeginScene(Game1.spriteBatch);
|
||||||
|
Game1.currentLocation.Map.GetLayer("Back").Draw(Game1.mapDisplayDevice, Game1.viewport, Location.Origin, false, Game1.pixelZoom);
|
||||||
|
Game1.currentLocation.drawWater(Game1.spriteBatch);
|
||||||
|
if (Game1.CurrentEvent == null)
|
||||||
|
{
|
||||||
|
using (List<NPC>.Enumerator enumerator = Game1.currentLocation.characters.GetEnumerator())
|
||||||
|
{
|
||||||
|
while (enumerator.MoveNext())
|
||||||
|
{
|
||||||
|
NPC current = enumerator.Current;
|
||||||
|
if (current != null && !current.swimming && !current.hideShadow && !current.IsMonster && !Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(current.getTileLocation()))
|
||||||
|
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, current.position + new Vector2(current.sprite.spriteWidth * Game1.pixelZoom / 2f, current.GetBoundingBox().Height + (current.IsMonster ? 0 : (Game1.pixelZoom * 3)))), Game1.shadowTexture.Bounds, Color.White, 0f, new Vector2(Game1.shadowTexture.Bounds.Center.X, Game1.shadowTexture.Bounds.Center.Y), (Game1.pixelZoom + current.yJumpOffset / 40f) * current.scale, SpriteEffects.None, Math.Max(0f, current.getStandingY() / 10000f) - 1E-06f);
|
||||||
|
}
|
||||||
|
goto IL_B30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (NPC current2 in Game1.CurrentEvent.actors)
|
||||||
|
{
|
||||||
|
if (!current2.swimming && !current2.hideShadow && !Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(current2.getTileLocation()))
|
||||||
|
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, current2.position + new Vector2(current2.sprite.spriteWidth * Game1.pixelZoom / 2f, current2.GetBoundingBox().Height + (current2.IsMonster ? 0 : (Game1.pixelZoom * 3)))), Game1.shadowTexture.Bounds, Color.White, 0f, new Vector2(Game1.shadowTexture.Bounds.Center.X, Game1.shadowTexture.Bounds.Center.Y), (Game1.pixelZoom + current2.yJumpOffset / 40f) * current2.scale, SpriteEffects.None, Math.Max(0f, current2.getStandingY() / 10000f) - 1E-06f);
|
||||||
|
}
|
||||||
|
IL_B30:
|
||||||
|
if (!Game1.player.swimming && !Game1.player.isRidingHorse() && !Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(Game1.player.getTileLocation()))
|
||||||
|
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.player.position + new Vector2(32f, 24f)), Game1.shadowTexture.Bounds, Color.White, 0f, new Vector2(Game1.shadowTexture.Bounds.Center.X, Game1.shadowTexture.Bounds.Center.Y), 4f - (((Game1.player.running || Game1.player.usingTool) && Game1.player.FarmerSprite.indexInCurrentAnimation > 1) ? (Math.Abs(FarmerRenderer.featureYOffsetPerFrame[Game1.player.FarmerSprite.CurrentFrame]) * 0.5f) : 0f), SpriteEffects.None, 0f);
|
||||||
|
Game1.currentLocation.Map.GetLayer("Buildings").Draw(Game1.mapDisplayDevice, Game1.viewport, Location.Origin, false, Game1.pixelZoom);
|
||||||
|
Game1.mapDisplayDevice.EndScene();
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
if (Game1.CurrentEvent == null)
|
||||||
|
{
|
||||||
|
using (List<NPC>.Enumerator enumerator3 = Game1.currentLocation.characters.GetEnumerator())
|
||||||
|
{
|
||||||
|
while (enumerator3.MoveNext())
|
||||||
|
{
|
||||||
|
NPC current3 = enumerator3.Current;
|
||||||
|
if (current3 != null && !current3.swimming && !current3.hideShadow && Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(current3.getTileLocation()))
|
||||||
|
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, current3.position + new Vector2(current3.sprite.spriteWidth * Game1.pixelZoom / 2f, current3.GetBoundingBox().Height + (current3.IsMonster ? 0 : (Game1.pixelZoom * 3)))), Game1.shadowTexture.Bounds, Color.White, 0f, new Vector2(Game1.shadowTexture.Bounds.Center.X, Game1.shadowTexture.Bounds.Center.Y), (Game1.pixelZoom + current3.yJumpOffset / 40f) * current3.scale, SpriteEffects.None, Math.Max(0f, current3.getStandingY() / 10000f) - 1E-06f);
|
||||||
|
}
|
||||||
|
goto IL_F5F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (NPC current4 in Game1.CurrentEvent.actors)
|
||||||
|
{
|
||||||
|
if (!current4.swimming && !current4.hideShadow && Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(current4.getTileLocation()))
|
||||||
|
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.viewport, current4.position + new Vector2(current4.sprite.spriteWidth * Game1.pixelZoom / 2f, current4.GetBoundingBox().Height + (current4.IsMonster ? 0 : (Game1.pixelZoom * 3)))), Game1.shadowTexture.Bounds, Color.White, 0f, new Vector2(Game1.shadowTexture.Bounds.Center.X, Game1.shadowTexture.Bounds.Center.Y), (Game1.pixelZoom + current4.yJumpOffset / 40f) * current4.scale, SpriteEffects.None, Math.Max(0f, current4.getStandingY() / 10000f) - 1E-06f);
|
||||||
|
}
|
||||||
|
IL_F5F:
|
||||||
|
if (!Game1.player.swimming && !Game1.player.isRidingHorse() && Game1.currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(Game1.player.getTileLocation()))
|
||||||
|
Game1.spriteBatch.Draw(Game1.shadowTexture, Game1.GlobalToLocal(Game1.player.position + new Vector2(32f, 24f)), Game1.shadowTexture.Bounds, Color.White, 0f, new Vector2(Game1.shadowTexture.Bounds.Center.X, Game1.shadowTexture.Bounds.Center.Y), 4f - (((Game1.player.running || Game1.player.usingTool) && Game1.player.FarmerSprite.indexInCurrentAnimation > 1) ? (Math.Abs(FarmerRenderer.featureYOffsetPerFrame[Game1.player.FarmerSprite.CurrentFrame]) * 0.5f) : 0f), SpriteEffects.None, Math.Max(0.0001f, Game1.player.getStandingY() / 10000f + 0.00011f) - 0.0001f);
|
||||||
|
if (Game1.displayFarmer)
|
||||||
|
Game1.player.draw(Game1.spriteBatch);
|
||||||
|
if ((Game1.eventUp || Game1.killScreen) && !Game1.killScreen)
|
||||||
|
Game1.currentLocation.currentEvent?.draw(Game1.spriteBatch);
|
||||||
|
if (Game1.player.currentUpgrade != null && Game1.player.currentUpgrade.daysLeftTillUpgradeDone <= 3 && Game1.currentLocation.Name.Equals("Farm"))
|
||||||
|
Game1.spriteBatch.Draw(Game1.player.currentUpgrade.workerTexture, Game1.GlobalToLocal(Game1.viewport, Game1.player.currentUpgrade.positionOfCarpenter), Game1.player.currentUpgrade.getSourceRectangle(), Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, (Game1.player.currentUpgrade.positionOfCarpenter.Y + Game1.tileSize * 3 / 4) / 10000f);
|
||||||
|
Game1.currentLocation.draw(Game1.spriteBatch);
|
||||||
|
if (Game1.eventUp && Game1.currentLocation.currentEvent?.messageToScreen != null)
|
||||||
|
Game1.drawWithBorder(Game1.currentLocation.currentEvent.messageToScreen, Color.Black, Color.White, new Vector2(Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Width / 2 - Game1.borderFont.MeasureString(Game1.currentLocation.currentEvent.messageToScreen).X / 2f, Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Height - Game1.tileSize), 0f, 1f, 0.999f);
|
||||||
|
if (Game1.player.ActiveObject == null && (Game1.player.UsingTool || Game1.pickingTool) && Game1.player.CurrentTool != null && (!Game1.player.CurrentTool.Name.Equals("Seeds") || Game1.pickingTool))
|
||||||
|
Game1.drawTool(Game1.player);
|
||||||
|
if (Game1.currentLocation.Name.Equals("Farm"))
|
||||||
|
this.drawFarmBuildings();
|
||||||
|
if (Game1.tvStation >= 0)
|
||||||
|
Game1.spriteBatch.Draw(Game1.tvStationTexture, Game1.GlobalToLocal(Game1.viewport, new Vector2(6 * Game1.tileSize + Game1.tileSize / 4, 2 * Game1.tileSize + Game1.tileSize / 2)), new Rectangle(Game1.tvStation * 24, 0, 24, 15), Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, 1E-08f);
|
||||||
|
if (Game1.panMode)
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Rectangle((int)Math.Floor((Game1.getOldMouseX() + Game1.viewport.X) / (double)Game1.tileSize) * Game1.tileSize - Game1.viewport.X, (int)Math.Floor((Game1.getOldMouseY() + Game1.viewport.Y) / (double)Game1.tileSize) * Game1.tileSize - Game1.viewport.Y, Game1.tileSize, Game1.tileSize), Color.Lime * 0.75f);
|
||||||
|
foreach (Warp current5 in Game1.currentLocation.warps)
|
||||||
|
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Rectangle(current5.X * Game1.tileSize - Game1.viewport.X, current5.Y * Game1.tileSize - Game1.viewport.Y, Game1.tileSize, Game1.tileSize), Color.Red * 0.75f);
|
||||||
|
}
|
||||||
|
Game1.mapDisplayDevice.BeginScene(Game1.spriteBatch);
|
||||||
|
Game1.currentLocation.Map.GetLayer("Front").Draw(Game1.mapDisplayDevice, Game1.viewport, Location.Origin, false, Game1.pixelZoom);
|
||||||
|
Game1.mapDisplayDevice.EndScene();
|
||||||
|
Game1.currentLocation.drawAboveFrontLayer(Game1.spriteBatch);
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
if (Game1.currentLocation.Name.Equals("Farm") && Game1.stats.SeedsSown >= 200u)
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.Draw(Game1.debrisSpriteSheet, Game1.GlobalToLocal(Game1.viewport, new Vector2(3 * Game1.tileSize + Game1.tileSize / 4, Game1.tileSize + Game1.tileSize / 3)), Game1.getSourceRectForStandardTileSheet(Game1.debrisSpriteSheet, 16), Color.White);
|
||||||
|
Game1.spriteBatch.Draw(Game1.debrisSpriteSheet, Game1.GlobalToLocal(Game1.viewport, new Vector2(4 * Game1.tileSize + Game1.tileSize, 2 * Game1.tileSize + Game1.tileSize)), Game1.getSourceRectForStandardTileSheet(Game1.debrisSpriteSheet, 16), Color.White);
|
||||||
|
Game1.spriteBatch.Draw(Game1.debrisSpriteSheet, Game1.GlobalToLocal(Game1.viewport, new Vector2(5 * Game1.tileSize, 2 * Game1.tileSize)), Game1.getSourceRectForStandardTileSheet(Game1.debrisSpriteSheet, 16), Color.White);
|
||||||
|
Game1.spriteBatch.Draw(Game1.debrisSpriteSheet, Game1.GlobalToLocal(Game1.viewport, new Vector2(3 * Game1.tileSize + Game1.tileSize / 2, 3 * Game1.tileSize)), Game1.getSourceRectForStandardTileSheet(Game1.debrisSpriteSheet, 16), Color.White);
|
||||||
|
Game1.spriteBatch.Draw(Game1.debrisSpriteSheet, Game1.GlobalToLocal(Game1.viewport, new Vector2(5 * Game1.tileSize - Game1.tileSize / 4, Game1.tileSize)), Game1.getSourceRectForStandardTileSheet(Game1.debrisSpriteSheet, 16), Color.White);
|
||||||
|
Game1.spriteBatch.Draw(Game1.debrisSpriteSheet, Game1.GlobalToLocal(Game1.viewport, new Vector2(4 * Game1.tileSize, 3 * Game1.tileSize + Game1.tileSize / 6)), Game1.getSourceRectForStandardTileSheet(Game1.debrisSpriteSheet, 16), Color.White);
|
||||||
|
Game1.spriteBatch.Draw(Game1.debrisSpriteSheet, Game1.GlobalToLocal(Game1.viewport, new Vector2(4 * Game1.tileSize + Game1.tileSize / 5, 2 * Game1.tileSize + Game1.tileSize / 3)), Game1.getSourceRectForStandardTileSheet(Game1.debrisSpriteSheet, 16), Color.White);
|
||||||
|
}
|
||||||
|
if (Game1.displayFarmer && Game1.player.ActiveObject != null && Game1.player.ActiveObject.bigCraftable && this.checkBigCraftableBoundariesForFrontLayer() && Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location(Game1.player.getStandingX(), Game1.player.getStandingY()), Game1.viewport.Size) == null)
|
||||||
|
Game1.drawPlayerHeldObject(Game1.player);
|
||||||
|
else if (Game1.displayFarmer && Game1.player.ActiveObject != null && ((Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location((int)Game1.player.position.X, (int)Game1.player.position.Y - Game1.tileSize * 3 / 5), Game1.viewport.Size) != null && !Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location((int)Game1.player.position.X, (int)Game1.player.position.Y - Game1.tileSize * 3 / 5), Game1.viewport.Size).TileIndexProperties.ContainsKey("FrontAlways")) || (Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location(Game1.player.GetBoundingBox().Right, (int)Game1.player.position.Y - Game1.tileSize * 3 / 5), Game1.viewport.Size) != null && !Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location(Game1.player.GetBoundingBox().Right, (int)Game1.player.position.Y - Game1.tileSize * 3 / 5), Game1.viewport.Size).TileIndexProperties.ContainsKey("FrontAlways"))))
|
||||||
|
Game1.drawPlayerHeldObject(Game1.player);
|
||||||
|
if ((Game1.player.UsingTool || Game1.pickingTool) && Game1.player.CurrentTool != null && (!Game1.player.CurrentTool.Name.Equals("Seeds") || Game1.pickingTool) && Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location(Game1.player.getStandingX(), (int)Game1.player.position.Y - Game1.tileSize * 3 / 5), Game1.viewport.Size) != null && Game1.currentLocation.Map.GetLayer("Front").PickTile(new Location(Game1.player.getStandingX(), Game1.player.getStandingY()), Game1.viewport.Size) == null)
|
||||||
|
Game1.drawTool(Game1.player);
|
||||||
|
if (Game1.currentLocation.Map.GetLayer("AlwaysFront") != null)
|
||||||
|
{
|
||||||
|
Game1.mapDisplayDevice.BeginScene(Game1.spriteBatch);
|
||||||
|
Game1.currentLocation.Map.GetLayer("AlwaysFront").Draw(Game1.mapDisplayDevice, Game1.viewport, Location.Origin, false, Game1.pixelZoom);
|
||||||
|
Game1.mapDisplayDevice.EndScene();
|
||||||
|
}
|
||||||
|
if (Game1.toolHold > 400f && Game1.player.CurrentTool.UpgradeLevel >= 1 && Game1.player.canReleaseTool)
|
||||||
|
{
|
||||||
|
Color color = Color.White;
|
||||||
|
switch ((int)(Game1.toolHold / 600f) + 2)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
color = Tool.copperColor;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
color = Tool.steelColor;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
color = Tool.goldColor;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
color = Tool.iridiumColor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Game1.spriteBatch.Draw(Game1.littleEffect, new Rectangle((int)Game1.player.getLocalPosition(Game1.viewport).X - 2, (int)Game1.player.getLocalPosition(Game1.viewport).Y - (Game1.player.CurrentTool.Name.Equals("Watering Can") ? 0 : Game1.tileSize) - 2, (int)(Game1.toolHold % 600f * 0.08f) + 4, Game1.tileSize / 8 + 4), Color.Black);
|
||||||
|
Game1.spriteBatch.Draw(Game1.littleEffect, new Rectangle((int)Game1.player.getLocalPosition(Game1.viewport).X, (int)Game1.player.getLocalPosition(Game1.viewport).Y - (Game1.player.CurrentTool.Name.Equals("Watering Can") ? 0 : Game1.tileSize), (int)(Game1.toolHold % 600f * 0.08f), Game1.tileSize / 8), color);
|
||||||
|
}
|
||||||
|
if (Game1.isDebrisWeather && Game1.currentLocation.IsOutdoors && !Game1.currentLocation.ignoreDebrisWeather && !Game1.currentLocation.Name.Equals("Desert") && Game1.viewport.X > -10)
|
||||||
|
{
|
||||||
|
foreach (WeatherDebris current6 in Game1.debrisWeather)
|
||||||
|
current6.draw(Game1.spriteBatch);
|
||||||
|
}
|
||||||
|
Game1.farmEvent?.draw(Game1.spriteBatch);
|
||||||
|
if (Game1.currentLocation.LightLevel > 0f && Game1.timeOfDay < 2000)
|
||||||
|
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, Game1.graphics.GraphicsDevice.Viewport.Bounds, Color.Black * Game1.currentLocation.LightLevel);
|
||||||
|
if (Game1.screenGlow)
|
||||||
|
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, Game1.graphics.GraphicsDevice.Viewport.Bounds, Game1.screenGlowColor * Game1.screenGlowAlpha);
|
||||||
|
Game1.currentLocation.drawAboveAlwaysFrontLayer(Game1.spriteBatch);
|
||||||
|
if (Game1.player.CurrentTool is FishingRod && ((Game1.player.CurrentTool as FishingRod).isTimingCast || (Game1.player.CurrentTool as FishingRod).castingChosenCountdown > 0f || (Game1.player.CurrentTool as FishingRod).fishCaught || (Game1.player.CurrentTool as FishingRod).showingTreasure))
|
||||||
|
Game1.player.CurrentTool.draw(Game1.spriteBatch);
|
||||||
|
if (Game1.isRaining && Game1.currentLocation.IsOutdoors && !Game1.currentLocation.Name.Equals("Desert") && !(Game1.currentLocation is Summit) && (!Game1.eventUp || Game1.currentLocation.isTileOnMap(new Vector2(Game1.viewport.X / Game1.tileSize, Game1.viewport.Y / Game1.tileSize))))
|
||||||
|
{
|
||||||
|
for (int j = 0; j < Game1.rainDrops.Length; j++)
|
||||||
|
Game1.spriteBatch.Draw(Game1.rainTexture, Game1.rainDrops[j].position, Game1.getSourceRectForStandardTileSheet(Game1.rainTexture, Game1.rainDrops[j].frame), Color.White);
|
||||||
|
}
|
||||||
|
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
|
||||||
|
//base.Draw(gameTime);
|
||||||
|
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
if (Game1.eventUp && Game1.currentLocation.currentEvent != null)
|
||||||
|
{
|
||||||
|
foreach (NPC current7 in Game1.currentLocation.currentEvent.actors)
|
||||||
|
{
|
||||||
|
if (current7.isEmoting)
|
||||||
|
{
|
||||||
|
Vector2 localPosition = current7.getLocalPosition(Game1.viewport);
|
||||||
|
localPosition.Y -= Game1.tileSize * 2 + Game1.pixelZoom * 3;
|
||||||
|
if (current7.age == 2)
|
||||||
|
localPosition.Y += Game1.tileSize / 2;
|
||||||
|
else if (current7.gender == 1)
|
||||||
|
localPosition.Y += Game1.tileSize / 6;
|
||||||
|
Game1.spriteBatch.Draw(Game1.emoteSpriteSheet, localPosition, new Rectangle(current7.CurrentEmoteIndex * (Game1.tileSize / 4) % Game1.emoteSpriteSheet.Width, current7.CurrentEmoteIndex * (Game1.tileSize / 4) / Game1.emoteSpriteSheet.Width * (Game1.tileSize / 4), Game1.tileSize / 4, Game1.tileSize / 4), Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, current7.getStandingY() / 10000f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
if (Game1.drawLighting)
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, new BlendState
|
||||||
|
{
|
||||||
|
ColorBlendFunction = BlendFunction.ReverseSubtract,
|
||||||
|
ColorDestinationBlend = Blend.One,
|
||||||
|
ColorSourceBlend = Blend.SourceColor
|
||||||
|
}, SamplerState.LinearClamp, null, null);
|
||||||
|
Game1.spriteBatch.Draw(Game1.lightmap, Vector2.Zero, Game1.lightmap.Bounds, Color.White, 0f, Vector2.Zero, Game1.options.lightingQuality, SpriteEffects.None, 1f);
|
||||||
|
if (Game1.isRaining && Game1.currentLocation.isOutdoors && !(Game1.currentLocation is Desert))
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.Draw(Game1.staminaRect, Game1.graphics.GraphicsDevice.Viewport.Bounds, Color.OrangeRed * 0.45f);
|
||||||
|
}
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
}
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null);
|
||||||
|
if (Game1.drawGrid)
|
||||||
|
{
|
||||||
|
int num2 = -Game1.viewport.X % Game1.tileSize;
|
||||||
|
float num3 = -(float)Game1.viewport.Y % Game1.tileSize;
|
||||||
|
for (int k = num2; k < Game1.graphics.GraphicsDevice.Viewport.Width; k += Game1.tileSize)
|
||||||
|
Game1.spriteBatch.Draw(Game1.staminaRect, new Rectangle(k, (int)num3, 1, Game1.graphics.GraphicsDevice.Viewport.Height), Color.Red * 0.5f);
|
||||||
|
for (float num4 = num3; num4 < (float)Game1.graphics.GraphicsDevice.Viewport.Height; num4 += (float)Game1.tileSize)
|
||||||
|
Game1.spriteBatch.Draw(Game1.staminaRect, new Rectangle(num2, (int)num4, Game1.graphics.GraphicsDevice.Viewport.Width, 1), Color.Red * 0.5f);
|
||||||
|
}
|
||||||
|
if (Game1.currentBillboard != 0)
|
||||||
|
this.drawBillboard();
|
||||||
|
|
||||||
|
if ((Game1.displayHUD || Game1.eventUp) && Game1.currentBillboard == 0 && Game1.gameMode == 3 && !Game1.freezeControls && !Game1.panMode)
|
||||||
|
{
|
||||||
|
GraphicsEvents.InvokeOnPreRenderHudEvent(this.Monitor);
|
||||||
|
this.drawHUD();
|
||||||
|
GraphicsEvents.InvokeOnPostRenderHudEvent(this.Monitor);
|
||||||
|
}
|
||||||
|
else if (Game1.activeClickableMenu == null && Game1.farmEvent == null)
|
||||||
|
Game1.spriteBatch.Draw(Game1.mouseCursors, new Vector2(Game1.getOldMouseX(), Game1.getOldMouseY()), Game1.getSourceRectForStandardTileSheet(Game1.mouseCursors, 0, 16, 16), Color.White, 0f, Vector2.Zero, 4f + Game1.dialogueButtonScale / 150f, SpriteEffects.None, 1f);
|
||||||
|
|
||||||
|
if (Game1.hudMessages.Any() && (!Game1.eventUp || Game1.isFestival()))
|
||||||
|
{
|
||||||
|
for (int l = Game1.hudMessages.Count - 1; l >= 0; l--)
|
||||||
|
Game1.hudMessages[l].draw(Game1.spriteBatch, l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Game1.farmEvent?.draw(Game1.spriteBatch);
|
||||||
|
if (Game1.dialogueUp && !Game1.nameSelectUp && !Game1.messagePause && !(Game1.activeClickableMenu is DialogueBox))
|
||||||
|
this.drawDialogueBox();
|
||||||
|
if (Game1.progressBar)
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, new Rectangle((Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Width - Game1.dialogueWidth) / 2, Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Bottom - Game1.tileSize * 2, Game1.dialogueWidth, Game1.tileSize / 2), Color.LightGray);
|
||||||
|
Game1.spriteBatch.Draw(Game1.staminaRect, new Rectangle((Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Width - Game1.dialogueWidth) / 2, Game1.graphics.GraphicsDevice.Viewport.TitleSafeArea.Bottom - Game1.tileSize * 2, (int)(Game1.pauseAccumulator / Game1.pauseTime * Game1.dialogueWidth), Game1.tileSize / 2), Color.DimGray);
|
||||||
|
}
|
||||||
|
if (Game1.eventUp)
|
||||||
|
Game1.currentLocation.currentEvent?.drawAfterMap(Game1.spriteBatch);
|
||||||
|
if (Game1.isRaining && Game1.currentLocation.isOutdoors && !(Game1.currentLocation is Desert))
|
||||||
|
Game1.spriteBatch.Draw(Game1.staminaRect, Game1.graphics.GraphicsDevice.Viewport.Bounds, Color.Blue * 0.2f);
|
||||||
|
if ((Game1.fadeToBlack || Game1.globalFade) && !Game1.menuUp && (!Game1.nameSelectUp || Game1.messagePause))
|
||||||
|
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, Game1.graphics.GraphicsDevice.Viewport.Bounds, Color.Black * ((Game1.gameMode == 0) ? (1f - Game1.fadeToBlackAlpha) : Game1.fadeToBlackAlpha));
|
||||||
|
else if (Game1.flashAlpha > 0f)
|
||||||
|
{
|
||||||
|
if (Game1.options.screenFlash)
|
||||||
|
Game1.spriteBatch.Draw(Game1.fadeToBlackRect, Game1.graphics.GraphicsDevice.Viewport.Bounds, Color.White * Math.Min(1f, Game1.flashAlpha));
|
||||||
|
Game1.flashAlpha -= 0.1f;
|
||||||
|
}
|
||||||
|
if ((Game1.messagePause || Game1.globalFade) && Game1.dialogueUp)
|
||||||
|
this.drawDialogueBox();
|
||||||
|
foreach (TemporaryAnimatedSprite current8 in Game1.screenOverlayTempSprites)
|
||||||
|
current8.draw(Game1.spriteBatch, true);
|
||||||
|
if (Game1.debugMode)
|
||||||
|
{
|
||||||
|
Game1.spriteBatch.DrawString(Game1.smallFont, string.Concat(new object[]
|
||||||
|
{
|
||||||
|
Game1.panMode ? ((Game1.getOldMouseX() + Game1.viewport.X) / Game1.tileSize + "," + (Game1.getOldMouseY() + Game1.viewport.Y) / Game1.tileSize) : string.Concat("aplayer: ", Game1.player.getStandingX() / Game1.tileSize, ", ", Game1.player.getStandingY() / Game1.tileSize),
|
||||||
|
Environment.NewLine,
|
||||||
|
"debugOutput: ",
|
||||||
|
Game1.debugOutput
|
||||||
|
}), new Vector2(this.GraphicsDevice.Viewport.TitleSafeArea.X, this.GraphicsDevice.Viewport.TitleSafeArea.Y), Color.Red, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0.9999999f);
|
||||||
|
}
|
||||||
|
/*if (inputMode)
|
||||||
|
{
|
||||||
|
spriteBatch.DrawString(smallFont, "Input: " + debugInput, new Vector2(tileSize, tileSize * 3), Color.Purple);
|
||||||
|
}*/
|
||||||
|
if (Game1.showKeyHelp)
|
||||||
|
Game1.spriteBatch.DrawString(Game1.smallFont, Game1.keyHelpString, new Vector2(Game1.tileSize, Game1.viewport.Height - Game1.tileSize - (Game1.dialogueUp ? (Game1.tileSize * 3 + (Game1.isQuestion ? (Game1.questionChoices.Count * Game1.tileSize) : 0)) : 0) - Game1.smallFont.MeasureString(Game1.keyHelpString).Y), Color.LightGray, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0.9999999f);
|
||||||
|
|
||||||
|
if (Game1.activeClickableMenu != null)
|
||||||
|
{
|
||||||
|
GraphicsEvents.InvokeOnPreRenderGuiEvent(this.Monitor);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Game1.activeClickableMenu.draw(Game1.spriteBatch);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
this.Monitor.Log($"The {Game1.activeClickableMenu.GetType().FullName} menu crashed while drawing itself. SMAPI will force it to exit to avoid crashing the game.\n{ex.GetLogSummary()}", LogLevel.Error);
|
||||||
|
Game1.activeClickableMenu.exitThisMenu();
|
||||||
|
}
|
||||||
|
GraphicsEvents.InvokeOnPostRenderGuiEvent(this.Monitor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Game1.farmEvent?.drawAboveEverything(Game1.spriteBatch);
|
||||||
|
|
||||||
|
GraphicsEvents.InvokeOnPostRenderEvent(this.Monitor);
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
|
||||||
|
if (!this.ZoomLevelIsOne)
|
||||||
|
{
|
||||||
|
this.GraphicsDevice.SetRenderTarget(null);
|
||||||
|
this.GraphicsDevice.Clear(this.bgColor);
|
||||||
|
Game1.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone);
|
||||||
|
Game1.spriteBatch.Draw(this.screenWrapper, Vector2.Zero, this.screenWrapper.Bounds, Color.White, 0f, Vector2.Zero, Game1.options.zoomLevel, SpriteEffects.None, 1f);
|
||||||
|
Game1.spriteBatch.End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
this.Monitor.Log($"An error occured in the overridden draw loop: {ex.GetLogSummary()}", LogLevel.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****
|
/****
|
||||||
** Methods
|
** Methods
|
||||||
|
@ -1061,6 +1500,7 @@ namespace StardewModdingAPI.Framework
|
||||||
/// <summary>Detect changes since the last update ticket and trigger mod events.</summary>
|
/// <summary>Detect changes since the last update ticket and trigger mod events.</summary>
|
||||||
private void UpdateEventCalls()
|
private void UpdateEventCalls()
|
||||||
{
|
{
|
||||||
|
#if SDV_1_2
|
||||||
// content locale changed event
|
// content locale changed event
|
||||||
if (this.PreviousLocale != LocalizedContentManager.CurrentLanguageCode)
|
if (this.PreviousLocale != LocalizedContentManager.CurrentLanguageCode)
|
||||||
{
|
{
|
||||||
|
@ -1071,9 +1511,14 @@ namespace StardewModdingAPI.Framework
|
||||||
ContentEvents.InvokeAfterLocaleChanged(this.Monitor, oldValue.ToString(), newValue.ToString());
|
ContentEvents.InvokeAfterLocaleChanged(this.Monitor, oldValue.ToString(), newValue.ToString());
|
||||||
this.PreviousLocale = newValue;
|
this.PreviousLocale = newValue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// save loaded event
|
// save loaded event
|
||||||
if (Constants.IsSaveLoaded && !SaveGame.IsProcessing/*still loading save*/ && this.AfterLoadTimer >= 0)
|
if (Constants.IsSaveLoaded
|
||||||
|
#if SDV_1_2
|
||||||
|
&& !SaveGame.IsProcessing/*still loading save*/
|
||||||
|
#endif
|
||||||
|
&& this.AfterLoadTimer >= 0)
|
||||||
{
|
{
|
||||||
if (this.AfterLoadTimer == 0)
|
if (this.AfterLoadTimer == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -247,7 +247,14 @@ namespace StardewModdingAPI
|
||||||
this.GameInstance.Exiting += (sender, e) => this.IsGameRunning = false;
|
this.GameInstance.Exiting += (sender, e) => this.IsGameRunning = false;
|
||||||
this.GameInstance.Window.ClientSizeChanged += (sender, e) => GraphicsEvents.InvokeResize(this.Monitor, sender, e);
|
this.GameInstance.Window.ClientSizeChanged += (sender, e) => GraphicsEvents.InvokeResize(this.Monitor, sender, e);
|
||||||
this.GameInstance.Window.Title = $"Stardew Valley {Constants.GameVersion} with SMAPI {Constants.ApiVersion}";
|
this.GameInstance.Window.Title = $"Stardew Valley {Constants.GameVersion} with SMAPI {Constants.ApiVersion}";
|
||||||
|
#if SDV_1_2
|
||||||
StardewValley.Program.gamePtr = this.GameInstance;
|
StardewValley.Program.gamePtr = this.GameInstance;
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
Type type = typeof(Game1).Assembly.GetType("StardewValley.Program", true);
|
||||||
|
type.GetField("gamePtr").SetValue(null, this.GameInstance);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// configure
|
// configure
|
||||||
Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef;
|
Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef;
|
||||||
|
|
|
@ -27,6 +27,10 @@ This file contains advanced configuration for SMAPI. You generally shouldn't cha
|
||||||
* Changing this field is not recommended and may destabilise your game.
|
* Changing this field is not recommended and may destabilise your game.
|
||||||
*/
|
*/
|
||||||
"ModCompatibility": [
|
"ModCompatibility": [
|
||||||
|
|
||||||
|
/****
|
||||||
|
** Stardew Valley 1.2+ only
|
||||||
|
****/
|
||||||
{
|
{
|
||||||
"Name": "AccessChestAnywhere",
|
"Name": "AccessChestAnywhere",
|
||||||
"ID": "AccessChestAnywhere",
|
"ID": "AccessChestAnywhere",
|
||||||
|
@ -34,9 +38,94 @@ This file contains advanced configuration for SMAPI. You generally shouldn't cha
|
||||||
"Compatibility": "AssumeBroken",
|
"Compatibility": "AssumeBroken",
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/257",
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/257",
|
||||||
"UnofficialUpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/518",
|
"UnofficialUpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/518",
|
||||||
"Notes": "Crashes with 'Method not found: Void StardewValley.Item.set_Name(System.String)'."
|
"Notes": "Crashes with 'Method not found: Void StardewValley.Item.set_Name(System.String)'.",
|
||||||
|
"OnlyStardewValleyBeta": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"Name": "Chests Anywhere",
|
||||||
|
"ID": "ChestsAnywhere",
|
||||||
|
"UpperVersion": "1.8.2",
|
||||||
|
"Compatibility": "AssumeBroken",
|
||||||
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/518",
|
||||||
|
"Notes": "Crashes with 'Method not found: Void StardewValley.Menus.TextBox.set_Highlighted(Boolean)'.",
|
||||||
|
"OnlyStardewValleyBeta": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Chests Anywhere",
|
||||||
|
"ID": "Pathoschild.ChestsAnywhere",
|
||||||
|
"UpperVersion": "1.9-beta",
|
||||||
|
"Compatibility": "AssumeBroken",
|
||||||
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/518",
|
||||||
|
"Notes": "ID changed in 1.9. Crashes with InvalidOperationException: 'The menu doesn't seem to have a player inventory'.",
|
||||||
|
"OnlyStardewValleyBeta": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "CJB Automation",
|
||||||
|
"ID": "CJBAutomation",
|
||||||
|
"UpperVersion": "1.4",
|
||||||
|
"Compatibility": "AssumeBroken",
|
||||||
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/211",
|
||||||
|
"Notes": "Crashes with 'Method not found: Void StardewValley.Item.set_Name(System.String)'.",
|
||||||
|
"OnlyStardewValleyBeta": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Cooking Skill",
|
||||||
|
"ID": "CookingSkill",
|
||||||
|
"UpperVersion": "1.0.3",
|
||||||
|
"Compatibility": "AssumeBroken",
|
||||||
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/522",
|
||||||
|
"Notes": "Crashes with 'Method not found: Void StardewValley.Buff..ctor(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, System.String)'.",
|
||||||
|
"OnlyStardewValleyBeta": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Extended Fridge",
|
||||||
|
"ID": "Mystra007ExtendedFridge",
|
||||||
|
"UpperVersion": "1.0",
|
||||||
|
"Compatibility": "AssumeBroken",
|
||||||
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/485",
|
||||||
|
"Notes": "Actual upper version is 0.94, but mod incorrectly sets it to 1.0 in the manifest. Crashes with 'Field not found: StardewValley.Game1.mouseCursorTransparency'.",
|
||||||
|
"OnlyStardewValleyBeta": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Get Dressed",
|
||||||
|
"ID": "GetDressed.dll",
|
||||||
|
"UpperVersion": "3.2",
|
||||||
|
"Compatibility": "AssumeBroken",
|
||||||
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/331",
|
||||||
|
"Notes": "Crashes with NullReferenceException in GameEvents.UpdateTick.",
|
||||||
|
"OnlyStardewValleyBeta": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Lookup Anything",
|
||||||
|
"ID": "LookupAnything",
|
||||||
|
"UpperVersion": "1.10",
|
||||||
|
"Compatibility": "AssumeBroken",
|
||||||
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/541",
|
||||||
|
"Notes": "Crashes with FormatException when looking up NPCs.",
|
||||||
|
"OnlyStardewValleyBeta": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Lookup Anything",
|
||||||
|
"ID": "Pathoschild.LookupAnything",
|
||||||
|
"UpperVersion": "1.10.1",
|
||||||
|
"Compatibility": "AssumeBroken",
|
||||||
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/541",
|
||||||
|
"Notes": "ID changed in 1.10.1. Crashes with FormatException when looking up NPCs.",
|
||||||
|
"OnlyStardewValleyBeta": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Teleporter",
|
||||||
|
"ID": "Teleporter",
|
||||||
|
"UpperVersion": "1.0.2",
|
||||||
|
"Compatibility": "AssumeBroken",
|
||||||
|
"UpdateUrl": "http://community.playstarbound.com/resources/4374",
|
||||||
|
"Notes": "Crashes with 'InvalidOperationException: The StardewValley.Menus.MapPage object doesn't have a private 'points' instance field'.",
|
||||||
|
"OnlyStardewValleyBeta": true
|
||||||
|
},
|
||||||
|
|
||||||
|
/****
|
||||||
|
** Any version of Stardew Valley
|
||||||
|
****/ {
|
||||||
"Name": "Almighty Tool",
|
"Name": "Almighty Tool",
|
||||||
"ID": "AlmightyTool.dll",
|
"ID": "AlmightyTool.dll",
|
||||||
"UpperVersion": "1.1.1",
|
"UpperVersion": "1.1.1",
|
||||||
|
@ -68,30 +157,6 @@ This file contains advanced configuration for SMAPI. You generally shouldn't cha
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/242",
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/242",
|
||||||
"Notes": "Not compatible with Stardew Valley 1.1+"
|
"Notes": "Not compatible with Stardew Valley 1.1+"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Name": "Chests Anywhere",
|
|
||||||
"ID": "ChestsAnywhere",
|
|
||||||
"UpperVersion": "1.8.2",
|
|
||||||
"Compatibility": "AssumeBroken",
|
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/518",
|
|
||||||
"Notes": "Crashes with 'Method not found: Void StardewValley.Menus.TextBox.set_Highlighted(Boolean)'."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "Chests Anywhere",
|
|
||||||
"ID": "Pathoschild.ChestsAnywhere",
|
|
||||||
"UpperVersion": "1.9-beta",
|
|
||||||
"Compatibility": "AssumeBroken",
|
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/518",
|
|
||||||
"Notes": "ID changed in 1.9. Crashes with InvalidOperationException: 'The menu doesn't seem to have a player inventory'."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "CJB Automation",
|
|
||||||
"ID": "CJBAutomation",
|
|
||||||
"UpperVersion": "1.4",
|
|
||||||
"Compatibility": "AssumeBroken",
|
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/211",
|
|
||||||
"Notes": "Crashes with 'Method not found: Void StardewValley.Item.set_Name(System.String)'."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Name": "CJB Cheats Menu",
|
"Name": "CJB Cheats Menu",
|
||||||
"ID": "CJBCheatsMenu",
|
"ID": "CJBCheatsMenu",
|
||||||
|
@ -114,14 +179,6 @@ This file contains advanced configuration for SMAPI. You generally shouldn't cha
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/93",
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/93",
|
||||||
"Notes": "Uses SMAPI's internal SGame class."
|
"Notes": "Uses SMAPI's internal SGame class."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Name": "Cooking Skill",
|
|
||||||
"ID": "CookingSkill",
|
|
||||||
"UpperVersion": "1.0.3",
|
|
||||||
"Compatibility": "AssumeBroken",
|
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/522",
|
|
||||||
"Notes": "Crashes with 'Method not found: Void StardewValley.Buff..ctor(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32, System.String)'."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Name": "Enemy Health Bars",
|
"Name": "Enemy Health Bars",
|
||||||
"ID": "SPDHealthBar",
|
"ID": "SPDHealthBar",
|
||||||
|
@ -138,38 +195,6 @@ This file contains advanced configuration for SMAPI. You generally shouldn't cha
|
||||||
"UpdateUrl": "http://community.playstarbound.com/resources/4228",
|
"UpdateUrl": "http://community.playstarbound.com/resources/4228",
|
||||||
"Notes": "Uses obsolete StardewModdingAPI.Inheritance.SObject until 1.6.1; then crashes until 1.6.4 ('Entoarox Framework requested an immediate game shutdown: Fatal error attempting to update player tick properties System.NullReferenceException: Object reference not set to an instance of an object. at Entoarox.Framework.PlayerHelper.Update(Object s, EventArgs e)')."
|
"Notes": "Uses obsolete StardewModdingAPI.Inheritance.SObject until 1.6.1; then crashes until 1.6.4 ('Entoarox Framework requested an immediate game shutdown: Fatal error attempting to update player tick properties System.NullReferenceException: Object reference not set to an instance of an object. at Entoarox.Framework.PlayerHelper.Update(Object s, EventArgs e)')."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Name": "Extended Fridge",
|
|
||||||
"ID": "Mystra007ExtendedFridge",
|
|
||||||
"UpperVersion": "1.0",
|
|
||||||
"Compatibility": "AssumeBroken",
|
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/485",
|
|
||||||
"Notes": "Actual upper version is 0.94, but mod incorrectly sets it to 1.0 in the manifest. Crashes with 'Field not found: StardewValley.Game1.mouseCursorTransparency'."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "Get Dressed",
|
|
||||||
"ID": "GetDressed.dll",
|
|
||||||
"UpperVersion": "3.2",
|
|
||||||
"Compatibility": "AssumeBroken",
|
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/331",
|
|
||||||
"Notes": "Crashes with NullReferenceException in GameEvents.UpdateTick."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "Lookup Anything",
|
|
||||||
"ID": "LookupAnything",
|
|
||||||
"UpperVersion": "1.10",
|
|
||||||
"Compatibility": "AssumeBroken",
|
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/541",
|
|
||||||
"Notes": "Crashes with FormatException when looking up NPCs."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "Lookup Anything",
|
|
||||||
"ID": "Pathoschild.LookupAnything",
|
|
||||||
"UpperVersion": "1.10.1",
|
|
||||||
"Compatibility": "AssumeBroken",
|
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/541",
|
|
||||||
"Notes": "ID changed in 1.10.1. Crashes with FormatException when looking up NPCs."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Name": "Makeshift Multiplayer",
|
"Name": "Makeshift Multiplayer",
|
||||||
"ID": "StardewValleyMP",
|
"ID": "StardewValleyMP",
|
||||||
|
@ -227,14 +252,6 @@ This file contains advanced configuration for SMAPI. You generally shouldn't cha
|
||||||
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/683",
|
"UpdateUrl": "http://www.nexusmods.com/stardewvalley/mods/683",
|
||||||
"Notes": "Crashes with 'Method not found: Void StardewModdingAPI.Command.CallCommand(System.String)'."
|
"Notes": "Crashes with 'Method not found: Void StardewModdingAPI.Command.CallCommand(System.String)'."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Name": "Teleporter",
|
|
||||||
"ID": "Teleporter",
|
|
||||||
"UpperVersion": "1.0.2",
|
|
||||||
"Compatibility": "AssumeBroken",
|
|
||||||
"UpdateUrl": "http://community.playstarbound.com/resources/4374",
|
|
||||||
"Notes": "Crashes with 'InvalidOperationException: The StardewValley.Menus.MapPage object doesn't have a private 'points' instance field'."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Name": "Zoryn's Better RNG",
|
"Name": "Zoryn's Better RNG",
|
||||||
"ID": "76b6d1e1-f7ba-4d72-8c32-5a1e6d2716f6",
|
"ID": "76b6d1e1-f7ba-4d72-8c32-5a1e6d2716f6",
|
||||||
|
|
Loading…
Reference in New Issue