From 27dece2cf445147c5e2848f9ec26f38a101f50fc Mon Sep 17 00:00:00 2001 From: Gormogon Date: Sun, 29 May 2016 18:23:01 -0400 Subject: Attempt to migrate to new directory structure. --- .../Inheritance/ItemStackChange.cs | 18 + .../Inheritance/Menus/SBobberBar.cs | 288 ++++ .../Inheritance/Menus/SGameMenu.cs | 48 + .../Inheritance/Menus/SInventoryPage.cs | 19 + .../Inheritance/Minigames/SMinigameBase.cs | 34 + src/StardewModdingAPI/Inheritance/SBareObject.cs | 20 + src/StardewModdingAPI/Inheritance/SGame.cs | 1726 ++++++++++++++++++++ src/StardewModdingAPI/Inheritance/SObject.cs | 277 ++++ 8 files changed, 2430 insertions(+) create mode 100644 src/StardewModdingAPI/Inheritance/ItemStackChange.cs create mode 100644 src/StardewModdingAPI/Inheritance/Menus/SBobberBar.cs create mode 100644 src/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs create mode 100644 src/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs create mode 100644 src/StardewModdingAPI/Inheritance/Minigames/SMinigameBase.cs create mode 100644 src/StardewModdingAPI/Inheritance/SBareObject.cs create mode 100644 src/StardewModdingAPI/Inheritance/SGame.cs create mode 100644 src/StardewModdingAPI/Inheritance/SObject.cs (limited to 'src/StardewModdingAPI/Inheritance') diff --git a/src/StardewModdingAPI/Inheritance/ItemStackChange.cs b/src/StardewModdingAPI/Inheritance/ItemStackChange.cs new file mode 100644 index 00000000..88fc002e --- /dev/null +++ b/src/StardewModdingAPI/Inheritance/ItemStackChange.cs @@ -0,0 +1,18 @@ +using StardewValley; + +namespace StardewModdingAPI.Inheritance +{ + public enum ChangeType + { + Removed, + Added, + StackChange + } + + public class ItemStackChange + { + public Item Item { get; set; } + public int StackChange { get; set; } + public ChangeType ChangeType { get; set; } + } +} \ No newline at end of file diff --git a/src/StardewModdingAPI/Inheritance/Menus/SBobberBar.cs b/src/StardewModdingAPI/Inheritance/Menus/SBobberBar.cs new file mode 100644 index 00000000..1e424f73 --- /dev/null +++ b/src/StardewModdingAPI/Inheritance/Menus/SBobberBar.cs @@ -0,0 +1,288 @@ +using System.Reflection; +using Microsoft.Xna.Framework; +using StardewValley.BellsAndWhistles; +using StardewValley.Menus; + +namespace StardewModdingAPI.Inheritance.Menus +{ + public class SBobberBar : BobberBar + { + /// + /// DO NOT CONSTRUCT THIS CLASS + /// To retrieve an instance of SBobberBar, use SBobberBar.ConstructFromBaseClass() + /// + public SBobberBar(int whichFish, float fishSize, bool treasure, int bobber) : base(whichFish, fishSize, treasure, bobber) + { + } + + public BobberBar BaseBobberBar { get; private set; } + + /// + /// The green rectangle bar that moves up and down + /// + public float bobberPosition + { + get { return (float) GetBaseFieldInfo("bobberPosition").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bobberPosition").SetValue(BaseBobberBar, value); } + } + + /// + /// The green bar on the right. How close to catching the fish you are + /// Range: 0 - 1 | 1 = catch, 0 = fail + /// + public float distanceFromCatching + { + get { return (float) GetBaseFieldInfo("distanceFromCatching").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("distanceFromCatching").SetValue(BaseBobberBar, value); } + } + + public float difficulty + { + get { return (float) GetBaseFieldInfo("difficulty").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("difficulty").SetValue(BaseBobberBar, value); } + } + + public int motionType + { + get { return (int) GetBaseFieldInfo("motionType").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("motionType").SetValue(BaseBobberBar, value); } + } + + public int whichFish + { + get { return (int) GetBaseFieldInfo("whichFish").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("whichFish").SetValue(BaseBobberBar, value); } + } + + public float bobberSpeed + { + get { return (float) GetBaseFieldInfo("bobberSpeed").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bobberSpeed").SetValue(BaseBobberBar, value); } + } + + public float bobberAcceleration + { + get { return (float) GetBaseFieldInfo("bobberAcceleration").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bobberAcceleration").SetValue(BaseBobberBar, value); } + } + + public float bobberTargetPosition + { + get { return (float) GetBaseFieldInfo("bobberTargetPosition").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bobberTargetPosition").SetValue(BaseBobberBar, value); } + } + + public float scale + { + get { return (float) GetBaseFieldInfo("scale").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("scale").SetValue(BaseBobberBar, value); } + } + + public float everythingShakeTimer + { + get { return (float) GetBaseFieldInfo("everythingShakeTimer").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("everythingShakeTimer").SetValue(BaseBobberBar, value); } + } + + public float floaterSinkerAcceleration + { + get { return (float) GetBaseFieldInfo("floaterSinkerAcceleration").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("floaterSinkerAcceleration").SetValue(BaseBobberBar, value); } + } + + public float treasurePosition + { + get { return (float) GetBaseFieldInfo("treasurePosition").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("treasurePosition").SetValue(BaseBobberBar, value); } + } + + public float treasureCatchLevel + { + get { return (float) GetBaseFieldInfo("treasureCatchLevel").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("treasureCatchLevel").SetValue(BaseBobberBar, value); } + } + + public float treasureAppearTimer + { + get { return (float) GetBaseFieldInfo("treasureAppearTimer").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("treasureAppearTimer").SetValue(BaseBobberBar, value); } + } + + public float treasureScale + { + get { return (float) GetBaseFieldInfo("treasureScale").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("treasureScale").SetValue(BaseBobberBar, value); } + } + + public bool bobberInBar + { + get { return (bool) GetBaseFieldInfo("bobberInBar").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bobberInBar").SetValue(BaseBobberBar, value); } + } + + public bool buttonPressed + { + get { return (bool) GetBaseFieldInfo("buttonPressed").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("buttonPressed").SetValue(BaseBobberBar, value); } + } + + public bool flipBubble + { + get { return (bool) GetBaseFieldInfo("flipBubble").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("flipBubble").SetValue(BaseBobberBar, value); } + } + + public bool fadeIn + { + get { return (bool) GetBaseFieldInfo("fadeIn").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("fadeIn").SetValue(BaseBobberBar, value); } + } + + public bool fadeOut + { + get { return (bool) GetBaseFieldInfo("fadeOut").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bobberPfadeOutosition").SetValue(BaseBobberBar, value); } + } + + /// + /// Whether or not a treasure chest appears + /// + public bool treasure + { + get { return (bool) GetBaseFieldInfo("treasure").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("treasure").SetValue(BaseBobberBar, value); } + } + + public bool treasureCaught + { + get { return (bool) GetBaseFieldInfo("treasureCaught").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("treasureCaught").SetValue(BaseBobberBar, value); } + } + + public bool perfect + { + get { return (bool) GetBaseFieldInfo("perfect").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("perfect").SetValue(BaseBobberBar, value); } + } + + public bool bossFish + { + get { return (bool) GetBaseFieldInfo("bossFish").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bossFish").SetValue(BaseBobberBar, value); } + } + + public int bobberBarHeight + { + get { return (int) GetBaseFieldInfo("bobberBarHeight").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bobberBarHeight").SetValue(BaseBobberBar, value); } + } + + public int fishSize + { + get { return (int) GetBaseFieldInfo("fishSize").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("fishSize").SetValue(BaseBobberBar, value); } + } + + public int fishQuality + { + get { return (int) GetBaseFieldInfo("fishQuality").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("fishQuality").SetValue(BaseBobberBar, value); } + } + + public int minFishSize + { + get { return (int) GetBaseFieldInfo("minFishSize").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("minFishSize").SetValue(BaseBobberBar, value); } + } + + public int maxFishSize + { + get { return (int) GetBaseFieldInfo("maxFishSize").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("maxFishSize").SetValue(BaseBobberBar, value); } + } + + public int fishSizeReductionTimer + { + get { return (int) GetBaseFieldInfo("fishSizeReductionTimer").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("fishSizeReductionTimer").SetValue(BaseBobberBar, value); } + } + + public int whichBobber + { + get { return (int) GetBaseFieldInfo("whichBobber").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("whichBobber").SetValue(BaseBobberBar, value); } + } + + public Vector2 barShake + { + get { return (Vector2) GetBaseFieldInfo("barShake").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("barShake").SetValue(BaseBobberBar, value); } + } + + public Vector2 fishShake + { + get { return (Vector2) GetBaseFieldInfo("fishShake").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("fishShake").SetValue(BaseBobberBar, value); } + } + + public Vector2 everythingShake + { + get { return (Vector2) GetBaseFieldInfo("everythingShake").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("everythingShake").SetValue(BaseBobberBar, value); } + } + + public Vector2 treasureShake + { + get { return (Vector2) GetBaseFieldInfo("treasureShake").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("treasureShake").SetValue(BaseBobberBar, value); } + } + + public float reelRotation + { + get { return (float) GetBaseFieldInfo("reelRotation").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("reelRotation").SetValue(BaseBobberBar, value); } + } + + public SparklingText sparkleText + { + get { return (SparklingText) GetBaseFieldInfo("sparkleText").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("sparkleText").SetValue(BaseBobberBar, value); } + } + + public float bobberBarPos + { + get { return (float) GetBaseFieldInfo("bobberBarPos").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bobberBarPos").SetValue(BaseBobberBar, value); } + } + + public float bobberBarSpeed + { + get { return (float) GetBaseFieldInfo("bobberBarSpeed").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bobberBarSpeed").SetValue(BaseBobberBar, value); } + } + + public float bobberBarAcceleration + { + get { return (float) GetBaseFieldInfo("bobberBarAcceleration").GetValue(BaseBobberBar); } + set { GetBaseFieldInfo("bobberBarAcceleration").SetValue(BaseBobberBar, value); } + } + + public static FieldInfo[] PrivateFields => GetPrivateFields(); + + public static SBobberBar ConstructFromBaseClass(BobberBar baseClass) + { + var b = new SBobberBar(0, 0, false, 0) {BaseBobberBar = baseClass}; + return b; + } + + public static FieldInfo[] GetPrivateFields() + { + return typeof(BobberBar).GetFields(BindingFlags.Instance | BindingFlags.NonPublic); + } + + public static FieldInfo GetBaseFieldInfo(string name) + { + return typeof(BobberBar).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic); + } + } +} \ No newline at end of file diff --git a/src/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs b/src/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs new file mode 100644 index 00000000..a4d3d8d0 --- /dev/null +++ b/src/StardewModdingAPI/Inheritance/Menus/SGameMenu.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using System.Reflection; +using StardewValley.Menus; + +namespace StardewModdingAPI.Inheritance.Menus +{ + public class SGameMenu : GameMenu + { + public GameMenu BaseGameMenu { get; private set; } + + public List tabs + { + get { return (List) GetBaseFieldInfo("tabs").GetValue(BaseGameMenu); } + set { GetBaseFieldInfo("tabs").SetValue(BaseGameMenu, value); } + } + + public List pages + { + get { return (List) GetBaseFieldInfo("pages").GetValue(BaseGameMenu); } + set { GetBaseFieldInfo("pages").SetValue(BaseGameMenu, value); } + } + + public static SGameMenu ConstructFromBaseClass(GameMenu baseClass) + { + var s = new SGameMenu {BaseGameMenu = baseClass}; + return s; + } + + public override void receiveRightClick(int x, int y, bool playSound = true) + { + if (pages[currentTab] is InventoryPage) + { + Log.AsyncY("INV SCREEN"); + } + base.receiveRightClick(x, y, playSound); + } + + public static FieldInfo[] GetPrivateFields() + { + return typeof(GameMenu).GetFields(BindingFlags.Instance | BindingFlags.NonPublic); + } + + public static FieldInfo GetBaseFieldInfo(string name) + { + return typeof(GameMenu).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic); + } + } +} \ No newline at end of file diff --git a/src/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs b/src/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs new file mode 100644 index 00000000..436b834d --- /dev/null +++ b/src/StardewModdingAPI/Inheritance/Menus/SInventoryPage.cs @@ -0,0 +1,19 @@ +using StardewValley.Menus; + +namespace StardewModdingAPI.Inheritance.Menus +{ + public class SInventoryPage : InventoryPage + { + public SInventoryPage(int x, int y, int width, int height) : base(x, y, width, height) + { + } + + public InventoryPage BaseInventoryPage { get; private set; } + + public static SInventoryPage ConstructFromBaseClass(InventoryPage baseClass) + { + var s = new SInventoryPage(0, 0, 0, 0) {BaseInventoryPage = baseClass}; + return s; + } + } +} \ No newline at end of file diff --git a/src/StardewModdingAPI/Inheritance/Minigames/SMinigameBase.cs b/src/StardewModdingAPI/Inheritance/Minigames/SMinigameBase.cs new file mode 100644 index 00000000..f30021de --- /dev/null +++ b/src/StardewModdingAPI/Inheritance/Minigames/SMinigameBase.cs @@ -0,0 +1,34 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using StardewValley.Minigames; + +namespace StardewModdingAPI.Inheritance.Minigames +{ + internal abstract class SMinigameBase : IMinigame + { + public abstract bool tick(GameTime time); + + public abstract void receiveLeftClick(int x, int y, bool playSound = true); + + public abstract void leftClickHeld(int x, int y); + + public abstract void receiveRightClick(int x, int y, bool playSound = true); + + public abstract void releaseLeftClick(int x, int y); + + public abstract void releaseRightClick(int x, int y); + + public abstract void receiveKeyPress(Keys k); + + public abstract void receiveKeyRelease(Keys k); + + public abstract void draw(SpriteBatch b); + + public abstract void changeScreenSize(); + + public abstract void unload(); + + public abstract void receiveEventPoke(int data); + } +} \ No newline at end of file diff --git a/src/StardewModdingAPI/Inheritance/SBareObject.cs b/src/StardewModdingAPI/Inheritance/SBareObject.cs new file mode 100644 index 00000000..5bef7b3e --- /dev/null +++ b/src/StardewModdingAPI/Inheritance/SBareObject.cs @@ -0,0 +1,20 @@ +namespace StardewModdingAPI.Inheritance +{ + public struct SBareObject + { + public int parentSheetIndex { get; set; } + public int stack { get; set; } + public bool isRecipe { get; set; } + public int price { get; set; } + public int quality { get; set; } + + public SBareObject(int psi, int sta, bool ir, int pri, int qua) + { + parentSheetIndex = psi; + stack = sta; + isRecipe = ir; + price = pri; + quality = qua; + } + } +} \ No newline at end of file diff --git a/src/StardewModdingAPI/Inheritance/SGame.cs b/src/StardewModdingAPI/Inheritance/SGame.cs new file mode 100644 index 00000000..9b69434a --- /dev/null +++ b/src/StardewModdingAPI/Inheritance/SGame.cs @@ -0,0 +1,1726 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using StardewModdingAPI.Events; +using StardewValley; +using StardewValley.BellsAndWhistles; +using StardewValley.Locations; +using StardewValley.Menus; +using StardewValley.Tools; +using xTile.Dimensions; +using Rectangle = Microsoft.Xna.Framework.Rectangle; + +namespace StardewModdingAPI.Inheritance +{ + /// + /// The 'SGame' class. + /// This summary, and many others, only exists because XML doc tags. + /// + public class SGame : Game1 + { + /// + /// Useless right now. + /// + public const int LowestModItemID = 1000; + + private bool FireLoadedGameEvent; + + /// + /// Gets a jagged array of all buttons pressed on the gamepad the prior frame. + /// + public Buttons[][] PreviouslyPressedButtons; + + internal SGame() + { + Instance = this; + FirstUpdate = true; + } + + /// + /// Useless at this time. + /// + [Obsolete] + // ReSharper disable once UnusedAutoPropertyAccessor.Local + public static Dictionary ModItems { get; private set; } + + /// + /// The current KeyboardState + /// + public KeyboardState KStateNow { get; private set; } + + /// + /// The prior KeyboardState + /// + public KeyboardState KStatePrior { get; private set; } + + /// + /// The current MouseState + /// + public MouseState MStateNow { get; private set; } + + /// + /// The prior MouseState + /// + public MouseState MStatePrior { get; private set; } + + /// + /// All keys pressed on the current frame + /// + public Keys[] CurrentlyPressedKeys => KStateNow.GetPressedKeys(); + + /// + /// All keys pressed on the prior frame + /// + public Keys[] PreviouslyPressedKeys => KStatePrior.GetPressedKeys(); + + /// + /// All keys pressed on this frame except for the ones pressed on the prior frame + /// + public Keys[] FramePressedKeys => CurrentlyPressedKeys.Except(PreviouslyPressedKeys).ToArray(); + + /// + /// All keys pressed on the prior frame except for the ones pressed on the current frame + /// + public Keys[] FrameReleasedKeys => PreviouslyPressedKeys.Except(CurrentlyPressedKeys).ToArray(); + + /// + /// Whether or not a save was tagged as 'Loaded' the prior frame. + /// + public bool PreviouslyLoadedGame { get; private set; } + + /// + /// The list of GameLocations on the prior frame + /// + public int PreviousGameLocations { get; private set; } + + /// + /// The list of GameObjects on the prior frame + /// + public int PreviousLocationObjects { get; private set; } + + /// + /// The list of Items in the player's inventory on the prior frame + /// + public Dictionary PreviousItems { get; private set; } + + /// + /// The player's Combat level on the prior frame + /// + public int PreviousCombatLevel { get; private set; } + + /// + /// The player's Farming level on the prior frame + /// + public int PreviousFarmingLevel { get; private set; } + + /// + /// The player's Fishing level on the prior frame + /// + public int PreviousFishingLevel { get; private set; } + + /// + /// The player's Foraging level on the prior frame + /// + public int PreviousForagingLevel { get; private set; } + + /// + /// The player's Mining level on the prior frame + /// + public int PreviousMiningLevel { get; private set; } + + /// + /// The player's Luck level on the prior frame + /// + public int PreviousLuckLevel { get; private set; } + + //Kill me now comments are so boring + + /// + /// The player's previous game location + /// + public GameLocation PreviousGameLocation { get; private set; } + + /// + /// The previous ActiveGameMenu in Game1 + /// + public IClickableMenu PreviousActiveMenu { get; private set; } + + /// + /// Indicates if the MenuClosed event was fired to prevent it from re-firing. + /// + internal bool WasMenuClosedInvoked = false; + + /// + /// The previous mine level + /// + public int PreviousMineLevel { get; private set; } + + /// + /// The previous TimeOfDay (Int32 between 600 and 2400?) + /// + public int PreviousTimeOfDay { get; private set; } + + /// + /// The previous DayOfMonth (Int32 between 1 and 28?) + /// + public int PreviousDayOfMonth { get; private set; } + + /// + /// The previous Season (String as follows: "winter", "spring", "summer", "fall") + /// + public string PreviousSeasonOfYear { get; private set; } + + /// + /// The previous Year + /// + public int PreviousYearOfGame { get; private set; } + + /// + /// The previous result of Game1.newDay + /// + public bool PreviousIsNewDay { get; private set; } + + /// + /// The previous 'Farmer' (Player) + /// + public Farmer PreviousFarmer { get; private set; } + + /// + /// The current index of the update tick. Recycles every 60th tick to 0. (Int32 between 0 and 59) + /// + public int CurrentUpdateTick { get; private set; } + + /// + /// Whether or not this update frame is the very first of the entire game + /// + public bool FirstUpdate { get; private set; } + + /// + /// The current RenderTarget in Game1 (Private field, uses reflection) + /// + public RenderTarget2D Screen + { + get { return typeof(Game1).GetBaseFieldValue(Program.gamePtr, "screen"); } + set { typeof(Game1).SetBaseFieldValue(this, "screen", value); } + } + + /// + /// The current Colour in Game1 (Private field, uses reflection) + /// + public Color BgColour + { + get { return (Color) typeof(Game1).GetBaseFieldValue(Program.gamePtr, "bgColor"); } + set { typeof(Game1).SetBaseFieldValue(this, "bgColor", value); } + } + + /// + /// Static accessor for an Instance of the class SGame + /// + public static SGame Instance { get; private set; } + + /// + /// The game's FPS. Re-determined every Draw update. + /// + public static float FramesPerSecond { get; private set; } + + /// + /// Whether or not we're in a pseudo 'debug' mode. Mostly for displaying information like FPS. + /// + public static bool Debug { get; private set; } + + internal static Queue DebugMessageQueue { get; private set; } + + /// + /// The current player (equal to Farmer.Player) + /// + [Obsolete("Use Farmer.Player instead")] + public Farmer CurrentFarmer => player; + + /// + /// Gets ALL static fields that belong to 'Game1' + /// + public static FieldInfo[] GetStaticFields => typeof(Game1).GetFields(); + + /// + /// Whether or not a button was just pressed on the controller + /// + /// + /// + /// + /// + private bool WasButtonJustPressed(Buttons button, ButtonState buttonState, PlayerIndex stateIndex) + { + return buttonState == ButtonState.Pressed && !PreviouslyPressedButtons[(int) stateIndex].Contains(button); + } + + /// + /// Whether or not a button was just released on the controller + /// + /// + /// + /// + /// + private bool WasButtonJustReleased(Buttons button, ButtonState buttonState, PlayerIndex stateIndex) + { + return buttonState == ButtonState.Released && PreviouslyPressedButtons[(int) stateIndex].Contains(button); + } + + /// + /// Whether or not an analog button was just pressed on the controller + /// + /// + /// + /// + /// + private bool WasButtonJustPressed(Buttons button, float value, PlayerIndex stateIndex) + { + return WasButtonJustPressed(button, value > 0.2f ? ButtonState.Pressed : ButtonState.Released, stateIndex); + } + + /// + /// Whether or not an analog button was just released on the controller + /// + /// + /// + /// + /// + private bool WasButtonJustReleased(Buttons button, float value, PlayerIndex stateIndex) + { + return WasButtonJustReleased(button, value > 0.2f ? ButtonState.Pressed : ButtonState.Released, stateIndex); + } + + /// + /// Gets an array of all Buttons pressed on a joystick + /// + /// + /// + public Buttons[] GetButtonsDown(PlayerIndex index) + { + var state = GamePad.GetState(index); + var buttons = new List(); + if (state.IsConnected) + { + if (state.Buttons.A == ButtonState.Pressed) buttons.Add(Buttons.A); + if (state.Buttons.B == ButtonState.Pressed) buttons.Add(Buttons.B); + if (state.Buttons.Back == ButtonState.Pressed) buttons.Add(Buttons.Back); + if (state.Buttons.BigButton == ButtonState.Pressed) buttons.Add(Buttons.BigButton); + if (state.Buttons.LeftShoulder == ButtonState.Pressed) buttons.Add(Buttons.LeftShoulder); + if (state.Buttons.LeftStick == ButtonState.Pressed) buttons.Add(Buttons.LeftStick); + if (state.Buttons.RightShoulder == ButtonState.Pressed) buttons.Add(Buttons.RightShoulder); + if (state.Buttons.RightStick == ButtonState.Pressed) buttons.Add(Buttons.RightStick); + if (state.Buttons.Start == ButtonState.Pressed) buttons.Add(Buttons.Start); + if (state.Buttons.X == ButtonState.Pressed) buttons.Add(Buttons.X); + if (state.Buttons.Y == ButtonState.Pressed) buttons.Add(Buttons.Y); + if (state.DPad.Up == ButtonState.Pressed) buttons.Add(Buttons.DPadUp); + if (state.DPad.Down == ButtonState.Pressed) buttons.Add(Buttons.DPadDown); + if (state.DPad.Left == ButtonState.Pressed) buttons.Add(Buttons.DPadLeft); + if (state.DPad.Right == ButtonState.Pressed) buttons.Add(Buttons.DPadRight); + if (state.Triggers.Left > 0.2f) buttons.Add(Buttons.LeftTrigger); + if (state.Triggers.Right > 0.2f) buttons.Add(Buttons.RightTrigger); + } + return buttons.ToArray(); + } + + /// + /// Gets all buttons that were pressed on the current frame of a joystick + /// + /// + /// + public Buttons[] GetFramePressedButtons(PlayerIndex index) + { + var state = GamePad.GetState(index); + var buttons = new List(); + if (state.IsConnected) + { + if (WasButtonJustPressed(Buttons.A, state.Buttons.A, index)) buttons.Add(Buttons.A); + if (WasButtonJustPressed(Buttons.B, state.Buttons.B, index)) buttons.Add(Buttons.B); + if (WasButtonJustPressed(Buttons.Back, state.Buttons.Back, index)) buttons.Add(Buttons.Back); + if (WasButtonJustPressed(Buttons.BigButton, state.Buttons.BigButton, index)) buttons.Add(Buttons.BigButton); + if (WasButtonJustPressed(Buttons.LeftShoulder, state.Buttons.LeftShoulder, index)) buttons.Add(Buttons.LeftShoulder); + if (WasButtonJustPressed(Buttons.LeftStick, state.Buttons.LeftStick, index)) buttons.Add(Buttons.LeftStick); + if (WasButtonJustPressed(Buttons.RightShoulder, state.Buttons.RightShoulder, index)) buttons.Add(Buttons.RightShoulder); + if (WasButtonJustPressed(Buttons.RightStick, state.Buttons.RightStick, index)) buttons.Add(Buttons.RightStick); + if (WasButtonJustPressed(Buttons.Start, state.Buttons.Start, index)) buttons.Add(Buttons.Start); + if (WasButtonJustPressed(Buttons.X, state.Buttons.X, index)) buttons.Add(Buttons.X); + if (WasButtonJustPressed(Buttons.Y, state.Buttons.Y, index)) buttons.Add(Buttons.Y); + if (WasButtonJustPressed(Buttons.DPadUp, state.DPad.Up, index)) buttons.Add(Buttons.DPadUp); + if (WasButtonJustPressed(Buttons.DPadDown, state.DPad.Down, index)) buttons.Add(Buttons.DPadDown); + if (WasButtonJustPressed(Buttons.DPadLeft, state.DPad.Left, index)) buttons.Add(Buttons.DPadLeft); + if (WasButtonJustPressed(Buttons.DPadRight, state.DPad.Right, index)) buttons.Add(Buttons.DPadRight); + if (WasButtonJustPressed(Buttons.LeftTrigger, state.Triggers.Left, index)) buttons.Add(Buttons.LeftTrigger); + if (WasButtonJustPressed(Buttons.RightTrigger, state.Triggers.Right, index)) buttons.Add(Buttons.RightTrigger); + } + return buttons.ToArray(); + } + + /// + /// Gets all buttons that were released on the current frame of a joystick + /// + /// + /// + public Buttons[] GetFrameReleasedButtons(PlayerIndex index) + { + var state = GamePad.GetState(index); + var buttons = new List(); + if (state.IsConnected) + { + if (WasButtonJustReleased(Buttons.A, state.Buttons.A, index)) buttons.Add(Buttons.A); + if (WasButtonJustReleased(Buttons.B, state.Buttons.B, index)) buttons.Add(Buttons.B); + if (WasButtonJustReleased(Buttons.Back, state.Buttons.Back, index)) buttons.Add(Buttons.Back); + if (WasButtonJustReleased(Buttons.BigButton, state.Buttons.BigButton, index)) buttons.Add(Buttons.BigButton); + if (WasButtonJustReleased(Buttons.LeftShoulder, state.Buttons.LeftShoulder, index)) buttons.Add(Buttons.LeftShoulder); + if (WasButtonJustReleased(Buttons.LeftStick, state.Buttons.LeftStick, index)) buttons.Add(Buttons.LeftStick); + if (WasButtonJustReleased(Buttons.RightShoulder, state.Buttons.RightShoulder, index)) buttons.Add(Buttons.RightShoulder); + if (WasButtonJustReleased(Buttons.RightStick, state.Buttons.RightStick, index)) buttons.Add(Buttons.RightStick); + if (WasButtonJustReleased(Buttons.Start, state.Buttons.Start, index)) buttons.Add(Buttons.Start); + if (WasButtonJustReleased(Buttons.X, state.Buttons.X, index)) buttons.Add(Buttons.X); + if (WasButtonJustReleased(Buttons.Y, state.Buttons.Y, index)) buttons.Add(Buttons.Y); + if (WasButtonJustReleased(Buttons.DPadUp, state.DPad.Up, index)) buttons.Add(Buttons.DPadUp); + if (WasButtonJustReleased(Buttons.DPadDown, state.DPad.Down, index)) buttons.Add(Buttons.DPadDown); + if (WasButtonJustReleased(Buttons.DPadLeft, state.DPad.Left, index)) buttons.Add(Buttons.DPadLeft); + if (WasButtonJustReleased(Buttons.DPadRight, state.DPad.Right, index)) buttons.Add(Buttons.DPadRight); + if (WasButtonJustReleased(Buttons.LeftTrigger, state.Triggers.Left, index)) buttons.Add(Buttons.LeftTrigger); + if (WasButtonJustReleased(Buttons.RightTrigger, state.Triggers.Right, index)) buttons.Add(Buttons.RightTrigger); + } + return buttons.ToArray(); + } + + /// + /// + /// + public static MethodInfo DrawFarmBuildings = typeof(Game1).GetMethod("drawFarmBuildings", BindingFlags.NonPublic | BindingFlags.Instance); + + /// + /// + /// + public static MethodInfo DrawHUD = typeof(Game1).GetMethod("drawHUD", BindingFlags.NonPublic | BindingFlags.Instance); + + /// + /// + /// + public static MethodInfo DrawDialogueBox = typeof(Game1).GetMethod("drawDialogueBox", BindingFlags.NonPublic | BindingFlags.Instance); + + public static MethodInfo CheckForEscapeKeys = typeof(Game1).GetMethod("checkForEscapeKeys", BindingFlags.NonPublic | BindingFlags.Instance); + + public static MethodInfo UpdateControlInput = typeof(Game1).GetMethod("UpdateControlInput", BindingFlags.NonPublic | BindingFlags.Instance); + + public static MethodInfo UpdateCharacters = typeof(Game1).GetMethod("UpdateCharacters", BindingFlags.NonPublic | BindingFlags.Instance); + + public static MethodInfo UpdateLocations = typeof(Game1).GetMethod("UpdateLocations", BindingFlags.NonPublic | BindingFlags.Instance); + + public static MethodInfo getViewportCenter = typeof(Game1).GetMethod("getViewportCenter", BindingFlags.NonPublic | BindingFlags.Instance); + + public static MethodInfo UpdateTitleScreen = typeof(Game1).GetMethod("UpdateTitleScreen", BindingFlags.NonPublic | BindingFlags.Instance); + + public delegate void BaseBaseDraw(); + + /// + /// Whether or not the game's zoom level is 1.0f + /// + public bool ZoomLevelIsOne => options.zoomLevel.Equals(1.0f); + + /// + /// XNA Init Method + /// + protected override void Initialize() + { + Log.AsyncY("XNA Initialize"); + //ModItems = new Dictionary(); + DebugMessageQueue = new Queue(); + PreviouslyPressedButtons = new Buttons[4][]; + for (var i = 0; i < 4; ++i) PreviouslyPressedButtons[i] = new Buttons[0]; + + base.Initialize(); + GameEvents.InvokeInitialize(); + } + + /// + /// XNA LC Method + /// + protected override void LoadContent() + { + Log.AsyncY("XNA LoadContent"); + base.LoadContent(); + GameEvents.InvokeLoadContent(); + } + + /// + /// XNA Update Method + /// + /// + protected override void Update(GameTime gameTime) + { + QueueDebugMessage("FPS: " + FramesPerSecond); + UpdateEventCalls(); + + /* + if (ZoomLevelIsOne) + { + options.zoomLevel = 0.99f; + InvokeBasePrivateInstancedMethod("Window_ClientSizeChanged", null, null); + } + */ + + if (FramePressedKeys.Contains(Keys.F3)) + { + Debug = !Debug; + } + + if (FramePressedKeys.Contains(Keys.F2)) + { + //Built-in debug mode + debugMode = !debugMode; + } + + if (Constants.EnableCompletelyOverridingBaseCalls) + { + #region Overridden Update Call + + try + { + if (Program.BuildType == 0) + SteamHelper.update(); + if ((paused /*|| !this.IsActive*/) && (options == null || options.pauseWhenOutOfFocus || paused)) + return; + if (quit) + Exit(); + currentGameTime = gameTime; + if (gameMode != 11) + { + if (IsMultiplayer && gameMode == 3) + { + if (multiplayerMode == 2) + server.receiveMessages(); + else + client.receiveMessages(); + } + if (IsActive) + InvokeMethodInfo(CheckForEscapeKeys); + //InvokeBasePrivateInstancedMethod("checkForEscapeKeys"); + + //this.checkForEscapeKeys(); + updateMusic(); + updateRaindropPosition(); + bloom?.tick(gameTime); + if (globalFade) + { + if (!dialogueUp) + { + if (fadeIn) + { + fadeToBlackAlpha = Math.Max(0.0f, fadeToBlackAlpha - globalFadeSpeed); + if (fadeToBlackAlpha <= 0.0) + { + globalFade = false; + if (afterFade != null) + { + afterFadeFunction afterFadeFunction = afterFade; + afterFade(); + if (afterFade != null && afterFade.Equals(afterFadeFunction)) + afterFade = null; + if (nonWarpFade) + fadeToBlack = false; + } + } + } + else + { + fadeToBlackAlpha = Math.Min(1f, fadeToBlackAlpha + globalFadeSpeed); + if (fadeToBlackAlpha >= 1.0) + { + globalFade = false; + if (afterFade != null) + { + afterFadeFunction afterFadeFunction = afterFade; + afterFade(); + if (afterFade != null && afterFade.Equals(afterFadeFunction)) + afterFade = null; + if (nonWarpFade) + fadeToBlack = false; + } + } + } + } + else + InvokeMethodInfo(UpdateControlInput, gameTime); + //InvokeBasePrivateInstancedMethod("UpdateControlInput", gameTime); + //this.UpdateControlInput(gameTime); + } + else if (pauseThenDoFunctionTimer > 0) + { + freezeControls = true; + pauseThenDoFunctionTimer -= gameTime.ElapsedGameTime.Milliseconds; + if (pauseThenDoFunctionTimer <= 0) + { + freezeControls = false; + afterPause?.Invoke(); + } + } + if (gameMode == 3 || gameMode == 2) + { + player.millisecondsPlayed += (uint) gameTime.ElapsedGameTime.Milliseconds; + bool flag = true; + if (currentMinigame != null) + { + if (pauseTime > 0.0) + updatePause(gameTime); + if (fadeToBlack) + { + updateScreenFade(gameTime); + if (fadeToBlackAlpha >= 1.0) + fadeToBlack = false; + } + else + { + if (thumbstickMotionMargin > 0) + thumbstickMotionMargin -= gameTime.ElapsedGameTime.Milliseconds; + if (IsActive) + { + KeyboardState state1 = Keyboard.GetState(); + MouseState state2 = Mouse.GetState(); + GamePadState state3 = GamePad.GetState(PlayerIndex.One); + foreach (Keys keys in state1.GetPressedKeys()) + { + if (!oldKBState.IsKeyDown(keys)) + currentMinigame.receiveKeyPress(keys); + } + if (options.gamepadControls) + { + if (currentMinigame == null) + { + oldMouseState = state2; + oldKBState = state1; + oldPadState = state3; + return; + } + foreach (Buttons b in Utility.getPressedButtons(state3, oldPadState)) + currentMinigame.receiveKeyPress(Utility.mapGamePadButtonToKey(b)); + if (currentMinigame == null) + { + oldMouseState = state2; + oldKBState = state1; + oldPadState = state3; + return; + } + if (state3.ThumbSticks.Right.Y < -0.200000002980232 && oldPadState.ThumbSticks.Right.Y >= -0.200000002980232) + currentMinigame.receiveKeyPress(Keys.Down); + if (state3.ThumbSticks.Right.Y > 0.200000002980232 && oldPadState.ThumbSticks.Right.Y <= 0.200000002980232) + currentMinigame.receiveKeyPress(Keys.Up); + if (state3.ThumbSticks.Right.X < -0.200000002980232 && oldPadState.ThumbSticks.Right.X >= -0.200000002980232) + currentMinigame.receiveKeyPress(Keys.Left); + if (state3.ThumbSticks.Right.X > 0.200000002980232 && oldPadState.ThumbSticks.Right.X <= 0.200000002980232) + currentMinigame.receiveKeyPress(Keys.Right); + if (oldPadState.ThumbSticks.Right.Y < -0.200000002980232 && state3.ThumbSticks.Right.Y >= -0.200000002980232) + currentMinigame.receiveKeyRelease(Keys.Down); + if (oldPadState.ThumbSticks.Right.Y > 0.200000002980232 && state3.ThumbSticks.Right.Y <= 0.200000002980232) + currentMinigame.receiveKeyRelease(Keys.Up); + if (oldPadState.ThumbSticks.Right.X < -0.200000002980232 && state3.ThumbSticks.Right.X >= -0.200000002980232) + currentMinigame.receiveKeyRelease(Keys.Left); + if (oldPadState.ThumbSticks.Right.X > 0.200000002980232 && state3.ThumbSticks.Right.X <= 0.200000002980232) + currentMinigame.receiveKeyRelease(Keys.Right); + if (isGamePadThumbstickInMotion()) + { + setMousePosition(getMouseX() + (int) (state3.ThumbSticks.Left.X * 16.0), getMouseY() - (int) (state3.ThumbSticks.Left.Y * 16.0)); + lastCursorMotionWasMouse = false; + } + else if (getMousePosition().X != getOldMouseX() || getMousePosition().Y != getOldMouseY()) + lastCursorMotionWasMouse = true; + } + foreach (Keys keys in oldKBState.GetPressedKeys()) + { + if (!state1.IsKeyDown(keys)) + currentMinigame.receiveKeyRelease(keys); + } + if (options.gamepadControls) + { + if (currentMinigame == null) + { + oldMouseState = state2; + oldKBState = state1; + oldPadState = state3; + return; + } + if (state3.IsConnected && state3.IsButtonDown(Buttons.X) && !oldPadState.IsButtonDown(Buttons.X)) + currentMinigame.receiveRightClick(getMouseX(), getMouseY(), true); + else if (state3.IsConnected && state3.IsButtonDown(Buttons.A) && !oldPadState.IsButtonDown(Buttons.A)) + currentMinigame.receiveLeftClick(getMouseX(), getMouseY(), true); + else if (state3.IsConnected && !state3.IsButtonDown(Buttons.X) && oldPadState.IsButtonDown(Buttons.X)) + currentMinigame.releaseRightClick(getMouseX(), getMouseY()); + else if (state3.IsConnected && !state3.IsButtonDown(Buttons.A) && oldPadState.IsButtonDown(Buttons.A)) + currentMinigame.releaseLeftClick(getMouseX(), getMouseY()); + foreach (Buttons b in Utility.getPressedButtons(oldPadState, state3)) + currentMinigame.receiveKeyRelease(Utility.mapGamePadButtonToKey(b)); + if (state3.IsConnected && state3.IsButtonDown(Buttons.A)) + currentMinigame?.leftClickHeld(0, 0); + } + if (currentMinigame == null) + { + oldMouseState = state2; + oldKBState = state1; + oldPadState = state3; + return; + } + if (state2.LeftButton == ButtonState.Pressed && oldMouseState.LeftButton != ButtonState.Pressed) + currentMinigame.receiveLeftClick(getMouseX(), getMouseY(), true); + if (state2.RightButton == ButtonState.Pressed && oldMouseState.RightButton != ButtonState.Pressed) + currentMinigame.receiveRightClick(getMouseX(), getMouseY(), true); + if (state2.LeftButton == ButtonState.Released && oldMouseState.LeftButton == ButtonState.Pressed) + currentMinigame.releaseLeftClick(getMouseX(), getMouseY()); + if (state2.RightButton == ButtonState.Released && oldMouseState.RightButton == ButtonState.Pressed) + currentMinigame.releaseLeftClick(getMouseX(), getMouseY()); + if (state2.LeftButton == ButtonState.Pressed && oldMouseState.LeftButton == ButtonState.Pressed) + currentMinigame.leftClickHeld(getMouseX(), getMouseY()); + oldMouseState = state2; + oldKBState = state1; + oldPadState = state3; + } + if (currentMinigame != null && currentMinigame.tick(gameTime)) + { + currentMinigame.unload(); + currentMinigame = null; + fadeIn = true; + fadeToBlackAlpha = 1f; + return; + } + } + flag = IsMultiplayer; + } + else if (farmEvent != null && farmEvent.tickUpdate(gameTime)) + { + farmEvent.makeChangesToLocation(); + timeOfDay = 600; + UpdateOther(gameTime); + displayHUD = true; + farmEvent = null; + currentLocation = getLocationFromName("FarmHouse"); + player.position = Utility.PointToVector2(Utility.getHomeOfFarmer(player).getBedSpot()) * tileSize; + player.position.X -= tileSize; + changeMusicTrack("none"); + currentLocation.resetForPlayerEntry(); + player.forceCanMove(); + freezeControls = false; + displayFarmer = true; + outdoorLight = Color.White; + viewportFreeze = false; + fadeToBlackAlpha = 0.0f; + fadeToBlack = false; + globalFadeToClear(null, 0.02f); + player.mailForTomorrow.Clear(); + showEndOfNightStuff(); + } + if (flag) + { + if (endOfNightMenus.Count() > 0 && activeClickableMenu == null) + activeClickableMenu = endOfNightMenus.Pop(); + if (activeClickableMenu != null) + { + updateActiveMenu(gameTime); + } + else + { + if (pauseTime > 0.0) + updatePause(gameTime); + if (!globalFade && !freezeControls && (activeClickableMenu == null && IsActive)) + InvokeMethodInfo(UpdateControlInput, gameTime); + //InvokeBasePrivateInstancedMethod("UpdateControlInput", gameTime); + //this.UpdateControlInput(gameTime); + } + if (showingEndOfNightStuff && endOfNightMenus.Count() == 0 && activeClickableMenu == null) + { + showingEndOfNightStuff = false; + globalFadeToClear(playMorningSong, 0.02f); + } + if (!showingEndOfNightStuff) + { + if (IsMultiplayer || activeClickableMenu == null && currentMinigame == null) + UpdateGameClock(gameTime); + //this.UpdateCharacters(gameTime); + //this.UpdateLocations(gameTime); + //InvokeBasePrivateInstancedMethod("UpdateCharacters", gameTime); + //InvokeBasePrivateInstancedMethod("UpdateLocations", gameTime); + //UpdateViewPort(false, (Point)InvokeBasePrivateInstancedMethod("getViewportCenter")); + + InvokeMethodInfo(UpdateCharacters, gameTime); + InvokeMethodInfo(UpdateLocations, gameTime); + UpdateViewPort(false, (Point) InvokeMethodInfo(getViewportCenter)); + } + UpdateOther(gameTime); + if (messagePause) + { + KeyboardState state1 = Keyboard.GetState(); + MouseState state2 = Mouse.GetState(); + GamePadState state3 = GamePad.GetState(PlayerIndex.One); + if (isOneOfTheseKeysDown(state1, options.actionButton) && !isOneOfTheseKeysDown(oldKBState, options.actionButton)) + pressActionButton(state1, state2, state3); + oldKBState = state1; + oldPadState = state3; + } + } + } + else + { + //InvokeBasePrivateInstancedMethod("UpdateTitleScreen", gameTime); + InvokeMethodInfo(UpdateTitleScreen, gameTime); + //this.UpdateTitleScreen(gameTime); + if (activeClickableMenu != null) + updateActiveMenu(gameTime); + if (gameMode == 10) + UpdateOther(gameTime); + } + audioEngine?.Update(); + if (multiplayerMode == 2 && gameMode == 3) + server.sendMessages(gameTime); + } + } + catch (Exception ex) + { + Log.Error("An error occurred in the overridden update loop: " + ex); + } + + //typeof (Game).GetMethod("Update", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(this, new object[] {gameTime}); + //base.Update(gameTime); + + #endregion + } + else + { + try + { + base.Update(gameTime); + } + catch (Exception ex) + { + Log.AsyncR("An error occured in the base update loop: " + ex); + Console.ReadKey(); + } + } + + GameEvents.InvokeUpdateTick(); + if (FirstUpdate) + { + GameEvents.InvokeFirstUpdateTick(); + FirstUpdate = false; + } + + if (CurrentUpdateTick % 2 == 0) + GameEvents.InvokeSecondUpdateTick(); + + if (CurrentUpdateTick % 4 == 0) + GameEvents.InvokeFourthUpdateTick(); + + if (CurrentUpdateTick % 8 == 0) + GameEvents.InvokeEighthUpdateTick(); + + if (CurrentUpdateTick % 15 == 0) + GameEvents.InvokeQuarterSecondTick(); + + if (CurrentUpdateTick % 30 == 0) + GameEvents.InvokeHalfSecondTick(); + + if (CurrentUpdateTick % 60 == 0) + GameEvents.InvokeOneSecondTick(); + + CurrentUpdateTick += 1; + if (CurrentUpdateTick >= 60) + CurrentUpdateTick = 0; + + if (KStatePrior != KStateNow) + KStatePrior = KStateNow; + + for (var i = PlayerIndex.One; i <= PlayerIndex.Four; i++) + { + PreviouslyPressedButtons[(int) i] = GetButtonsDown(i); + } + } + + /// + /// XNA Draw Method + /// + /// + protected override void Draw(GameTime gameTime) + { + FramesPerSecond = 1 / (float) gameTime.ElapsedGameTime.TotalSeconds; + + if (Constants.EnableCompletelyOverridingBaseCalls) + { + #region Overridden Draw + + try + { + if (!ZoomLevelIsOne) + { + GraphicsDevice.SetRenderTarget(Screen); + } + + GraphicsDevice.Clear(BgColour); + if (options.showMenuBackground && activeClickableMenu != null && activeClickableMenu.showWithoutTransparencyIfOptionIsSet()) + { + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + activeClickableMenu.drawBackground(spriteBatch); + GraphicsEvents.InvokeOnPreRenderGuiEvent(null, EventArgs.Empty); + activeClickableMenu.draw(spriteBatch); + GraphicsEvents.InvokeOnPostRenderGuiEvent(null, EventArgs.Empty); + spriteBatch.End(); + if (!ZoomLevelIsOne) + { + GraphicsDevice.SetRenderTarget(null); + GraphicsDevice.Clear(BgColour); + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone); + spriteBatch.Draw(Screen, Vector2.Zero, Screen.Bounds, Color.White, 0f, Vector2.Zero, options.zoomLevel, SpriteEffects.None, 1f); + spriteBatch.End(); + } + return; + } + if (gameMode == 11) + { + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + spriteBatch.DrawString(smoothFont, "Stardew Valley has crashed...", new Vector2(16f, 16f), Color.HotPink); + spriteBatch.DrawString(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)); + spriteBatch.DrawString(smoothFont, parseText(errorMessage, smoothFont, graphics.GraphicsDevice.Viewport.Width), new Vector2(16f, 48f), Color.White); + spriteBatch.End(); + return; + } + if (currentMinigame != null) + { + currentMinigame.draw(spriteBatch); + if (globalFade && !menuUp && (!nameSelectUp || messagePause)) + { + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + spriteBatch.Draw(fadeToBlackRect, graphics.GraphicsDevice.Viewport.Bounds, Color.Black * ((gameMode == 0) ? (1f - fadeToBlackAlpha) : fadeToBlackAlpha)); + spriteBatch.End(); + } + if (!ZoomLevelIsOne) + { + GraphicsDevice.SetRenderTarget(null); + GraphicsDevice.Clear(BgColour); + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone); + spriteBatch.Draw(Screen, Vector2.Zero, Screen.Bounds, Color.White, 0f, Vector2.Zero, options.zoomLevel, SpriteEffects.None, 1f); + spriteBatch.End(); + } + return; + } + if (showingEndOfNightStuff) + { + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + activeClickableMenu?.draw(spriteBatch); + spriteBatch.End(); + if (!ZoomLevelIsOne) + { + GraphicsDevice.SetRenderTarget(null); + GraphicsDevice.Clear(BgColour); + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone); + spriteBatch.Draw(Screen, Vector2.Zero, Screen.Bounds, Color.White, 0f, Vector2.Zero, options.zoomLevel, SpriteEffects.None, 1f); + spriteBatch.End(); + } + return; + } + if (gameMode == 6) + { + 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(spriteBatch, "Loading" + text, 64, graphics.GraphicsDevice.Viewport.Height - 64, 999, -1, 999, 1f, 1f, false, 0, "Loading..."); + spriteBatch.End(); + if (!ZoomLevelIsOne) + { + GraphicsDevice.SetRenderTarget(null); + GraphicsDevice.Clear(BgColour); + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone); + spriteBatch.Draw(Screen, Vector2.Zero, Screen.Bounds, Color.White, 0f, Vector2.Zero, options.zoomLevel, SpriteEffects.None, 1f); + spriteBatch.End(); + } + return; + } + if (gameMode == 0) + { + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + } + else + { + if (drawLighting) + { + GraphicsDevice.SetRenderTarget(lightmap); + GraphicsDevice.Clear(Color.White * 0f); + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, null, null); + spriteBatch.Draw(staminaRect, lightmap.Bounds, currentLocation.name.Equals("UndergroundMine") ? mine.getLightingColor(gameTime) : ((!ambientLight.Equals(Color.White) && (!isRaining || !currentLocation.isOutdoors)) ? ambientLight : outdoorLight)); + for (int i = 0; i < currentLightSources.Count; i++) + { + if (Utility.isOnScreen(currentLightSources.ElementAt(i).position, (int) (currentLightSources.ElementAt(i).radius * tileSize * 4f))) + { + spriteBatch.Draw(currentLightSources.ElementAt(i).lightTexture, GlobalToLocal(viewport, currentLightSources.ElementAt(i).position) / options.lightingQuality, currentLightSources.ElementAt(i).lightTexture.Bounds, currentLightSources.ElementAt(i).color, 0f, new Vector2(currentLightSources.ElementAt(i).lightTexture.Bounds.Center.X, currentLightSources.ElementAt(i).lightTexture.Bounds.Center.Y), currentLightSources.ElementAt(i).radius / options.lightingQuality, SpriteEffects.None, 0.9f); + } + } + spriteBatch.End(); + GraphicsDevice.SetRenderTarget(ZoomLevelIsOne ? null : Screen); + } + if (bloomDay) + { + bloom?.BeginDraw(); + } + GraphicsDevice.Clear(BgColour); + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + GraphicsEvents.InvokeOnPreRenderEvent(null, EventArgs.Empty); + background?.draw(spriteBatch); + mapDisplayDevice.BeginScene(spriteBatch); + currentLocation.Map.GetLayer("Back").Draw(mapDisplayDevice, viewport, Location.Origin, false, pixelZoom); + currentLocation.drawWater(spriteBatch); + if (CurrentEvent == null) + { + using (List.Enumerator enumerator = currentLocation.characters.GetEnumerator()) + { + while (enumerator.MoveNext()) + { + NPC current = enumerator.Current; + if (current != null && !current.swimming && !current.hideShadow && !current.IsMonster && !currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(current.getTileLocation())) + { + spriteBatch.Draw(shadowTexture, GlobalToLocal(viewport, current.position + new Vector2(current.sprite.spriteWidth * pixelZoom / 2f, current.GetBoundingBox().Height + (current.IsMonster ? 0 : (pixelZoom * 3)))), shadowTexture.Bounds, Color.White, 0f, new Vector2(shadowTexture.Bounds.Center.X, shadowTexture.Bounds.Center.Y), (pixelZoom + current.yJumpOffset / 40f) * current.scale, SpriteEffects.None, Math.Max(0f, current.getStandingY() / 10000f) - 1E-06f); + } + } + goto IL_B30; + } + } + foreach (NPC current2 in CurrentEvent.actors) + { + if (!current2.swimming && !current2.hideShadow && !currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(current2.getTileLocation())) + { + spriteBatch.Draw(shadowTexture, GlobalToLocal(viewport, current2.position + new Vector2(current2.sprite.spriteWidth * pixelZoom / 2f, current2.GetBoundingBox().Height + (current2.IsMonster ? 0 : (pixelZoom * 3)))), shadowTexture.Bounds, Color.White, 0f, new Vector2(shadowTexture.Bounds.Center.X, shadowTexture.Bounds.Center.Y), (pixelZoom + current2.yJumpOffset / 40f) * current2.scale, SpriteEffects.None, Math.Max(0f, current2.getStandingY() / 10000f) - 1E-06f); + } + } + IL_B30: + if (!player.swimming && !player.isRidingHorse() && !currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(player.getTileLocation())) + { + spriteBatch.Draw(shadowTexture, GlobalToLocal(player.position + new Vector2(32f, 24f)), shadowTexture.Bounds, Color.White, 0f, new Vector2(shadowTexture.Bounds.Center.X, shadowTexture.Bounds.Center.Y), 4f - (((player.running || player.usingTool) && player.FarmerSprite.indexInCurrentAnimation > 1) ? (Math.Abs(FarmerRenderer.featureYOffsetPerFrame[player.FarmerSprite.CurrentFrame]) * 0.5f) : 0f), SpriteEffects.None, 0f); + } + currentLocation.Map.GetLayer("Buildings").Draw(mapDisplayDevice, viewport, Location.Origin, false, pixelZoom); + mapDisplayDevice.EndScene(); + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + if (CurrentEvent == null) + { + using (List.Enumerator enumerator3 = currentLocation.characters.GetEnumerator()) + { + while (enumerator3.MoveNext()) + { + NPC current3 = enumerator3.Current; + if (current3 != null && !current3.swimming && !current3.hideShadow && currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(current3.getTileLocation())) + { + spriteBatch.Draw(shadowTexture, GlobalToLocal(viewport, current3.position + new Vector2(current3.sprite.spriteWidth * pixelZoom / 2f, current3.GetBoundingBox().Height + (current3.IsMonster ? 0 : (pixelZoom * 3)))), shadowTexture.Bounds, Color.White, 0f, new Vector2(shadowTexture.Bounds.Center.X, shadowTexture.Bounds.Center.Y), (pixelZoom + current3.yJumpOffset / 40f) * current3.scale, SpriteEffects.None, Math.Max(0f, current3.getStandingY() / 10000f) - 1E-06f); + } + } + goto IL_F5F; + } + } + foreach (NPC current4 in CurrentEvent.actors) + { + if (!current4.swimming && !current4.hideShadow && currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(current4.getTileLocation())) + { + spriteBatch.Draw(shadowTexture, GlobalToLocal(viewport, current4.position + new Vector2(current4.sprite.spriteWidth * pixelZoom / 2f, current4.GetBoundingBox().Height + (current4.IsMonster ? 0 : (pixelZoom * 3)))), shadowTexture.Bounds, Color.White, 0f, new Vector2(shadowTexture.Bounds.Center.X, shadowTexture.Bounds.Center.Y), (pixelZoom + current4.yJumpOffset / 40f) * current4.scale, SpriteEffects.None, Math.Max(0f, current4.getStandingY() / 10000f) - 1E-06f); + } + } + IL_F5F: + if (!player.swimming && !player.isRidingHorse() && currentLocation.shouldShadowBeDrawnAboveBuildingsLayer(player.getTileLocation())) + { + spriteBatch.Draw(shadowTexture, GlobalToLocal(player.position + new Vector2(32f, 24f)), shadowTexture.Bounds, Color.White, 0f, new Vector2(shadowTexture.Bounds.Center.X, shadowTexture.Bounds.Center.Y), 4f - (((player.running || player.usingTool) && player.FarmerSprite.indexInCurrentAnimation > 1) ? (Math.Abs(FarmerRenderer.featureYOffsetPerFrame[player.FarmerSprite.CurrentFrame]) * 0.5f) : 0f), SpriteEffects.None, Math.Max(0.0001f, player.getStandingY() / 10000f + 0.00011f) - 0.0001f); + } + if (displayFarmer) + { + player.draw(spriteBatch); + } + if ((eventUp || killScreen) && !killScreen) + { + currentLocation.currentEvent?.draw(spriteBatch); + } + if (player.currentUpgrade != null && player.currentUpgrade.daysLeftTillUpgradeDone <= 3 && currentLocation.Name.Equals("Farm")) + { + spriteBatch.Draw(player.currentUpgrade.workerTexture, GlobalToLocal(viewport, player.currentUpgrade.positionOfCarpenter), player.currentUpgrade.getSourceRectangle(), Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, (player.currentUpgrade.positionOfCarpenter.Y + tileSize * 3 / 4) / 10000f); + } + currentLocation.draw(spriteBatch); + if (eventUp && currentLocation.currentEvent?.messageToScreen != null) + { + drawWithBorder(currentLocation.currentEvent.messageToScreen, Color.Black, Color.White, new Vector2(graphics.GraphicsDevice.Viewport.TitleSafeArea.Width / 2 - borderFont.MeasureString(currentLocation.currentEvent.messageToScreen).X / 2f, graphics.GraphicsDevice.Viewport.TitleSafeArea.Height - tileSize), 0f, 1f, 0.999f); + } + if (player.ActiveObject == null && (player.UsingTool || pickingTool) && player.CurrentTool != null && (!player.CurrentTool.Name.Equals("Seeds") || pickingTool)) + { + drawTool(player); + } + if (currentLocation.Name.Equals("Farm")) + { + //typeof (Game1).GetMethod("drawFarmBuildings", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Program.gamePtr, null); + DrawFarmBuildings.Invoke(Program.gamePtr, null); + //this.drawFarmBuildings(); + } + if (tvStation >= 0) + { + spriteBatch.Draw(tvStationTexture, GlobalToLocal(viewport, new Vector2(6 * tileSize + tileSize / 4, 2 * tileSize + tileSize / 2)), new Rectangle(tvStation * 24, 0, 24, 15), Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, 1E-08f); + } + if (panMode) + { + spriteBatch.Draw(fadeToBlackRect, new Rectangle((int) Math.Floor((getOldMouseX() + viewport.X) / (double) tileSize) * tileSize - viewport.X, (int) Math.Floor((getOldMouseY() + viewport.Y) / (double) tileSize) * tileSize - viewport.Y, tileSize, tileSize), Color.Lime * 0.75f); + foreach (Warp current5 in currentLocation.warps) + { + spriteBatch.Draw(fadeToBlackRect, new Rectangle(current5.X * tileSize - viewport.X, current5.Y * tileSize - viewport.Y, tileSize, tileSize), Color.Red * 0.75f); + } + } + mapDisplayDevice.BeginScene(spriteBatch); + currentLocation.Map.GetLayer("Front").Draw(mapDisplayDevice, viewport, Location.Origin, false, pixelZoom); + mapDisplayDevice.EndScene(); + currentLocation.drawAboveFrontLayer(spriteBatch); + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + if (currentLocation.Name.Equals("Farm") && stats.SeedsSown >= 200u) + { + spriteBatch.Draw(debrisSpriteSheet, GlobalToLocal(viewport, new Vector2(3 * tileSize + tileSize / 4, tileSize + tileSize / 3)), getSourceRectForStandardTileSheet(debrisSpriteSheet, 16), Color.White); + spriteBatch.Draw(debrisSpriteSheet, GlobalToLocal(viewport, new Vector2(4 * tileSize + tileSize, 2 * tileSize + tileSize)), getSourceRectForStandardTileSheet(debrisSpriteSheet, 16), Color.White); + spriteBatch.Draw(debrisSpriteSheet, GlobalToLocal(viewport, new Vector2(5 * tileSize, 2 * tileSize)), getSourceRectForStandardTileSheet(debrisSpriteSheet, 16), Color.White); + spriteBatch.Draw(debrisSpriteSheet, GlobalToLocal(viewport, new Vector2(3 * tileSize + tileSize / 2, 3 * tileSize)), getSourceRectForStandardTileSheet(debrisSpriteSheet, 16), Color.White); + spriteBatch.Draw(debrisSpriteSheet, GlobalToLocal(viewport, new Vector2(5 * tileSize - tileSize / 4, tileSize)), getSourceRectForStandardTileSheet(debrisSpriteSheet, 16), Color.White); + spriteBatch.Draw(debrisSpriteSheet, GlobalToLocal(viewport, new Vector2(4 * tileSize, 3 * tileSize + tileSize / 6)), getSourceRectForStandardTileSheet(debrisSpriteSheet, 16), Color.White); + spriteBatch.Draw(debrisSpriteSheet, GlobalToLocal(viewport, new Vector2(4 * tileSize + tileSize / 5, 2 * tileSize + tileSize / 3)), getSourceRectForStandardTileSheet(debrisSpriteSheet, 16), Color.White); + } + if (displayFarmer && player.ActiveObject != null && player.ActiveObject.bigCraftable && checkBigCraftableBoundariesForFrontLayer() && currentLocation.Map.GetLayer("Front").PickTile(new Location(player.getStandingX(), player.getStandingY()), viewport.Size) == null) + { + drawPlayerHeldObject(player); + } + else if (displayFarmer && player.ActiveObject != null && ((currentLocation.Map.GetLayer("Front").PickTile(new Location((int) player.position.X, (int) player.position.Y - tileSize * 3 / 5), viewport.Size) != null && !currentLocation.Map.GetLayer("Front").PickTile(new Location((int) player.position.X, (int) player.position.Y - tileSize * 3 / 5), viewport.Size).TileIndexProperties.ContainsKey("FrontAlways")) || (currentLocation.Map.GetLayer("Front").PickTile(new Location(player.GetBoundingBox().Right, (int) player.position.Y - tileSize * 3 / 5), viewport.Size) != null && !currentLocation.Map.GetLayer("Front").PickTile(new Location(player.GetBoundingBox().Right, (int) player.position.Y - tileSize * 3 / 5), viewport.Size).TileIndexProperties.ContainsKey("FrontAlways")))) + { + drawPlayerHeldObject(player); + } + if ((player.UsingTool || pickingTool) && player.CurrentTool != null && (!player.CurrentTool.Name.Equals("Seeds") || pickingTool) && currentLocation.Map.GetLayer("Front").PickTile(new Location(player.getStandingX(), (int) player.position.Y - tileSize * 3 / 5), viewport.Size) != null && currentLocation.Map.GetLayer("Front").PickTile(new Location(player.getStandingX(), player.getStandingY()), viewport.Size) == null) + { + drawTool(player); + } + if (currentLocation.Map.GetLayer("AlwaysFront") != null) + { + mapDisplayDevice.BeginScene(spriteBatch); + currentLocation.Map.GetLayer("AlwaysFront").Draw(mapDisplayDevice, viewport, Location.Origin, false, pixelZoom); + mapDisplayDevice.EndScene(); + } + if (toolHold > 400f && player.CurrentTool.UpgradeLevel >= 1 && player.canReleaseTool) + { + Color color = Color.White; + switch ((int) (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; + } + spriteBatch.Draw(littleEffect, new Rectangle((int) player.getLocalPosition(viewport).X - 2, (int) player.getLocalPosition(viewport).Y - (player.CurrentTool.Name.Equals("Watering Can") ? 0 : tileSize) - 2, (int) (toolHold % 600f * 0.08f) + 4, tileSize / 8 + 4), Color.Black); + spriteBatch.Draw(littleEffect, new Rectangle((int) player.getLocalPosition(viewport).X, (int) player.getLocalPosition(viewport).Y - (player.CurrentTool.Name.Equals("Watering Can") ? 0 : tileSize), (int) (toolHold % 600f * 0.08f), tileSize / 8), color); + } + if (isDebrisWeather && currentLocation.IsOutdoors && !currentLocation.ignoreDebrisWeather && !currentLocation.Name.Equals("Desert") && viewport.X > -10) + { + foreach (WeatherDebris current6 in debrisWeather) + { + current6.draw(spriteBatch); + } + } + farmEvent?.draw(spriteBatch); + if (currentLocation.LightLevel > 0f && timeOfDay < 2000) + { + spriteBatch.Draw(fadeToBlackRect, graphics.GraphicsDevice.Viewport.Bounds, Color.Black * currentLocation.LightLevel); + } + if (screenGlow) + { + spriteBatch.Draw(fadeToBlackRect, graphics.GraphicsDevice.Viewport.Bounds, screenGlowColor * screenGlowAlpha); + } + currentLocation.drawAboveAlwaysFrontLayer(spriteBatch); + if (player.CurrentTool is FishingRod && ((player.CurrentTool as FishingRod).isTimingCast || (player.CurrentTool as FishingRod).castingChosenCountdown > 0f || (player.CurrentTool as FishingRod).fishCaught || (player.CurrentTool as FishingRod).showingTreasure)) + { + player.CurrentTool.draw(spriteBatch); + } + if (isRaining && currentLocation.IsOutdoors && !currentLocation.Name.Equals("Desert") && !(currentLocation is Summit) && (!eventUp || currentLocation.isTileOnMap(new Vector2(viewport.X / tileSize, viewport.Y / tileSize)))) + { + for (int j = 0; j < rainDrops.Length; j++) + { + spriteBatch.Draw(rainTexture, rainDrops[j].position, getSourceRectForStandardTileSheet(rainTexture, rainDrops[j].frame), Color.White); + } + } + + spriteBatch.End(); + + //base.Draw(gameTime); + + spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + if (eventUp && currentLocation.currentEvent != null) + { + foreach (NPC current7 in currentLocation.currentEvent.actors) + { + if (current7.isEmoting) + { + Vector2 localPosition = current7.getLocalPosition(viewport); + localPosition.Y -= tileSize * 2 + pixelZoom * 3; + if (current7.age == 2) + { + localPosition.Y += tileSize / 2; + } + else if (current7.gender == 1) + { + localPosition.Y += tileSize / 6; + } + spriteBatch.Draw(emoteSpriteSheet, localPosition, new Rectangle(current7.CurrentEmoteIndex * (tileSize / 4) % emoteSpriteSheet.Width, current7.CurrentEmoteIndex * (tileSize / 4) / emoteSpriteSheet.Width * (tileSize / 4), tileSize / 4, tileSize / 4), Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, current7.getStandingY() / 10000f); + } + } + } + spriteBatch.End(); + if (drawLighting) + { + spriteBatch.Begin(SpriteSortMode.Deferred, new BlendState + { + ColorBlendFunction = BlendFunction.ReverseSubtract, + ColorDestinationBlend = Blend.One, + ColorSourceBlend = Blend.SourceColor + }, SamplerState.LinearClamp, null, null); + spriteBatch.Draw(lightmap, Vector2.Zero, lightmap.Bounds, Color.White, 0f, Vector2.Zero, options.lightingQuality, SpriteEffects.None, 1f); + if (isRaining && currentLocation.isOutdoors && !(currentLocation is Desert)) + { + spriteBatch.Draw(staminaRect, graphics.GraphicsDevice.Viewport.Bounds, Color.OrangeRed * 0.45f); + } + spriteBatch.End(); + } + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + if (drawGrid) + { + int num2 = -viewport.X % tileSize; + float num3 = -(float) viewport.Y % tileSize; + for (int k = num2; k < graphics.GraphicsDevice.Viewport.Width; k += tileSize) + { + spriteBatch.Draw(staminaRect, new Rectangle(k, (int) num3, 1, graphics.GraphicsDevice.Viewport.Height), Color.Red * 0.5f); + } + for (float num4 = num3; num4 < (float) graphics.GraphicsDevice.Viewport.Height; num4 += (float) tileSize) + { + spriteBatch.Draw(staminaRect, new Rectangle(num2, (int) num4, graphics.GraphicsDevice.Viewport.Width, 1), Color.Red * 0.5f); + } + } + if (currentBillboard != 0) + { + drawBillboard(); + } + + GraphicsEvents.InvokeOnPreRenderHudEventNoCheck(null, EventArgs.Empty); + if ((displayHUD || eventUp) && currentBillboard == 0 && gameMode == 3 && !freezeControls && !panMode) + { + GraphicsEvents.InvokeOnPreRenderHudEvent(null, EventArgs.Empty); + //typeof (Game1).GetMethod("drawHUD", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Program.gamePtr, null); + DrawHUD.Invoke(Program.gamePtr, null); + GraphicsEvents.InvokeOnPostRenderHudEvent(null, EventArgs.Empty); + //this.drawHUD(); + } + else if (activeClickableMenu == null && farmEvent == null) + { + spriteBatch.Draw(mouseCursors, new Vector2(getOldMouseX(), getOldMouseY()), getSourceRectForStandardTileSheet(mouseCursors, 0, 16, 16), Color.White, 0f, Vector2.Zero, 4f + dialogueButtonScale / 150f, SpriteEffects.None, 1f); + } + GraphicsEvents.InvokeOnPostRenderHudEventNoCheck(null, EventArgs.Empty); + + if (hudMessages.Any() && (!eventUp || isFestival())) + { + for (int l = hudMessages.Count - 1; l >= 0; l--) + { + hudMessages[l].draw(spriteBatch, l); + } + } + } + farmEvent?.draw(spriteBatch); + if (dialogueUp && !nameSelectUp && !messagePause && !(activeClickableMenu is DialogueBox)) + { + //typeof (Game1).GetMethod("drawDialogueBox", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Program.gamePtr, null); + DrawDialogueBox.Invoke(Program.gamePtr, null); + //this.drawDialogueBox(); + } + if (progressBar) + { + spriteBatch.Draw(fadeToBlackRect, new Rectangle((graphics.GraphicsDevice.Viewport.TitleSafeArea.Width - dialogueWidth) / 2, graphics.GraphicsDevice.Viewport.TitleSafeArea.Bottom - tileSize * 2, dialogueWidth, tileSize / 2), Color.LightGray); + spriteBatch.Draw(staminaRect, new Rectangle((graphics.GraphicsDevice.Viewport.TitleSafeArea.Width - dialogueWidth) / 2, graphics.GraphicsDevice.Viewport.TitleSafeArea.Bottom - tileSize * 2, (int) (pauseAccumulator / pauseTime * dialogueWidth), tileSize / 2), Color.DimGray); + } + if (eventUp) + { + currentLocation.currentEvent?.drawAfterMap(spriteBatch); + } + if (isRaining && currentLocation.isOutdoors && !(currentLocation is Desert)) + { + spriteBatch.Draw(staminaRect, graphics.GraphicsDevice.Viewport.Bounds, Color.Blue * 0.2f); + } + if ((fadeToBlack || globalFade) && !menuUp && (!nameSelectUp || messagePause)) + { + spriteBatch.Draw(fadeToBlackRect, graphics.GraphicsDevice.Viewport.Bounds, Color.Black * ((gameMode == 0) ? (1f - fadeToBlackAlpha) : fadeToBlackAlpha)); + } + else if (flashAlpha > 0f) + { + if (options.screenFlash) + { + spriteBatch.Draw(fadeToBlackRect, graphics.GraphicsDevice.Viewport.Bounds, Color.White * Math.Min(1f, flashAlpha)); + } + flashAlpha -= 0.1f; + } + if ((messagePause || globalFade) && dialogueUp) + { + //typeof (Game1).GetMethod("drawDialogueBox", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Program.gamePtr, null); + DrawDialogueBox.Invoke(Program.gamePtr, null); + //this.drawDialogueBox(); + } + foreach (TemporaryAnimatedSprite current8 in screenOverlayTempSprites) + { + current8.draw(spriteBatch, true); + } + if (debugMode) + { + spriteBatch.DrawString(smallFont, string.Concat(new object[] + { + panMode ? ((getOldMouseX() + viewport.X) / tileSize + "," + (getOldMouseY() + viewport.Y) / tileSize) : string.Concat("aplayer: ", player.getStandingX() / tileSize, ", ", player.getStandingY() / tileSize), + Environment.NewLine, + "debugOutput: ", + debugOutput + }), new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, 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 (showKeyHelp) + { + spriteBatch.DrawString(smallFont, keyHelpString, new Vector2(tileSize, viewport.Height - tileSize - (dialogueUp ? (tileSize * 3 + (isQuestion ? (questionChoices.Count * tileSize) : 0)) : 0) - smallFont.MeasureString(keyHelpString).Y), Color.LightGray, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0.9999999f); + } + + GraphicsEvents.InvokeOnPreRenderGuiEventNoCheck(null, EventArgs.Empty); + if (activeClickableMenu != null) + { + GraphicsEvents.InvokeOnPreRenderGuiEvent(null, EventArgs.Empty); + activeClickableMenu.draw(spriteBatch); + GraphicsEvents.InvokeOnPostRenderGuiEvent(null, EventArgs.Empty); + } + else + { + farmEvent?.drawAboveEverything(spriteBatch); + } + GraphicsEvents.InvokeOnPostRenderGuiEventNoCheck(null, EventArgs.Empty); + + GraphicsEvents.InvokeOnPostRenderEvent(null, EventArgs.Empty); + spriteBatch.End(); + + GraphicsEvents.InvokeDrawInRenderTargetTick(); + + if (!ZoomLevelIsOne) + { + GraphicsDevice.SetRenderTarget(null); + GraphicsDevice.Clear(BgColour); + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone); + spriteBatch.Draw(Screen, Vector2.Zero, Screen.Bounds, Color.White, 0f, Vector2.Zero, options.zoomLevel, SpriteEffects.None, 1f); + spriteBatch.End(); + } + + GraphicsEvents.InvokeDrawTick(); + } + catch (Exception ex) + { + Log.Error("An error occured in the overridden draw loop: " + ex); + } + + #endregion + } + else + { + #region Base Draw Call + + try + { + base.Draw(gameTime); + } + catch (Exception ex) + { + Log.AsyncR("An error occured in the base draw loop: " + ex); + Console.ReadKey(); + } + + GraphicsEvents.InvokeDrawTick(); + + if (Constants.EnableDrawingIntoRenderTarget) + { + if (!options.zoomLevel.Equals(1.0f)) + { + if (Screen.RenderTargetUsage == RenderTargetUsage.DiscardContents) + { + Screen = new RenderTarget2D(graphics.GraphicsDevice, Math.Min(4096, (int) (Window.ClientBounds.Width * (1.0 / options.zoomLevel))), + Math.Min(4096, (int) (Window.ClientBounds.Height * (1.0 / options.zoomLevel))), + false, SurfaceFormat.Color, DepthFormat.Depth16, 1, RenderTargetUsage.PreserveContents); + } + GraphicsDevice.SetRenderTarget(Screen); + } + + // Not beginning the batch due to inconsistancies with the standard draw tick... + //spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + + GraphicsEvents.InvokeDrawInRenderTargetTick(); + + //spriteBatch.End(); + + //Re-draw the HUD + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, null, null); + activeClickableMenu?.draw(spriteBatch); + /* + if ((displayHUD || eventUp) && currentBillboard == 0 && gameMode == 3 && !freezeControls && !panMode) + typeof (Game1).GetMethod("drawHUD", BindingFlags.NonPublic | BindingFlags.Instance)?.Invoke(Program.gamePtr, null); + */ + spriteBatch.Draw(mouseCursors, new Vector2(getOldMouseX(), getOldMouseY()), getSourceRectForStandardTileSheet(mouseCursors, options.gamepadControls ? 44 : 0, 16, 16), Color.White, 0.0f, Vector2.Zero, pixelZoom + dialogueButtonScale / 150f, SpriteEffects.None, 1f); + + spriteBatch.End(); + + if (!options.zoomLevel.Equals(1.0f)) + { + GraphicsDevice.SetRenderTarget(null); + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullNone); + spriteBatch.Draw(Screen, Vector2.Zero, Screen.Bounds, Color.White, 0.0f, Vector2.Zero, options.zoomLevel, SpriteEffects.None, 1f); + spriteBatch.End(); + } + } + + #endregion + } + + if (Debug) + { + spriteBatch.Begin(); + + int i = 0; + while (DebugMessageQueue.Any()) + { + string s = DebugMessageQueue.Dequeue(); + spriteBatch.DrawString(smoothFont, s, new Vector2(0, i * 14), Color.CornflowerBlue); + i++; + } + GraphicsEvents.InvokeDrawDebug(null, EventArgs.Empty); + + spriteBatch.End(); + } + else + { + DebugMessageQueue.Clear(); + } + } + + [Obsolete("Do not use at this time.")] + // ReSharper disable once UnusedMember.Local + private static int RegisterModItem(SObject modItem) + { + if (modItem.HasBeenRegistered) + { + Log.AsyncR($"The item {modItem.Name} has already been registered with ID {modItem.RegisteredId}"); + return modItem.RegisteredId; + } + var newId = LowestModItemID; + if (ModItems.Count > 0) + newId = Math.Max(LowestModItemID, ModItems.OrderBy(x => x.Key).First().Key + 1); + ModItems.Add(newId, modItem); + modItem.HasBeenRegistered = true; + modItem.RegisteredId = newId; + return newId; + } + + [Obsolete("Do not use at this time.")] + // ReSharper disable once UnusedMember.Local + private static SObject PullModItemFromDict(int id, bool isIndex) + { + if (isIndex) + { + if (ModItems.ElementAtOrDefault(id).Value != null) + { + return ModItems.ElementAt(id).Value.Clone(); + } + Log.AsyncR("ModItem Dictionary does not contain index: " + id); + return null; + } + if (ModItems.ContainsKey(id)) + { + return ModItems[id].Clone(); + } + Log.AsyncR("ModItem Dictionary does not contain ID: " + id); + return null; + } + + private void UpdateEventCalls() + { + KStateNow = Keyboard.GetState(); + + MStateNow = Mouse.GetState(); + + foreach (var k in FramePressedKeys) + ControlEvents.InvokeKeyPressed(k); + + foreach (var k in FrameReleasedKeys) + ControlEvents.InvokeKeyReleased(k); + + for (var i = PlayerIndex.One; i <= PlayerIndex.Four; i++) + { + var buttons = GetFramePressedButtons(i); + foreach (var b in buttons) + { + if (b == Buttons.LeftTrigger || b == Buttons.RightTrigger) + { + ControlEvents.InvokeTriggerPressed(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right); + } + else + { + ControlEvents.InvokeButtonPressed(i, b); + } + } + } + + for (var i = PlayerIndex.One; i <= PlayerIndex.Four; i++) + { + foreach (var b in GetFrameReleasedButtons(i)) + { + if (b == Buttons.LeftTrigger || b == Buttons.RightTrigger) + { + ControlEvents.InvokeTriggerReleased(i, b, b == Buttons.LeftTrigger ? GamePad.GetState(i).Triggers.Left : GamePad.GetState(i).Triggers.Right); + } + else + { + ControlEvents.InvokeButtonReleased(i, b); + } + } + } + + + if (KStateNow != KStatePrior) + { + ControlEvents.InvokeKeyboardChanged(KStatePrior, KStateNow); + } + + if (MStateNow != MStatePrior) + { + ControlEvents.InvokeMouseChanged(MStatePrior, MStateNow); + MStatePrior = MStateNow; + } + + if (activeClickableMenu != null && activeClickableMenu != PreviousActiveMenu) + { + MenuEvents.InvokeMenuChanged(PreviousActiveMenu, activeClickableMenu); + PreviousActiveMenu = activeClickableMenu; + WasMenuClosedInvoked = false; + } + + if (!WasMenuClosedInvoked && PreviousActiveMenu != null && activeClickableMenu == null) + { + MenuEvents.InvokeMenuClosed(PreviousActiveMenu); + WasMenuClosedInvoked = true; + } + + if (locations.GetHash() != PreviousGameLocations) + { + LocationEvents.InvokeLocationsChanged(locations); + PreviousGameLocations = locations.GetHash(); + } + + if (currentLocation != PreviousGameLocation) + { + LocationEvents.InvokeCurrentLocationChanged(PreviousGameLocation, currentLocation); + PreviousGameLocation = currentLocation; + } + + if (player != null && player != PreviousFarmer) + { + PlayerEvents.InvokeFarmerChanged(PreviousFarmer, player); + PreviousFarmer = player; + } + + if (player != null && player.combatLevel != PreviousCombatLevel) + { + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Combat, player.combatLevel); + PreviousCombatLevel = player.combatLevel; + } + + if (player != null && player.farmingLevel != PreviousFarmingLevel) + { + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Farming, player.farmingLevel); + PreviousFarmingLevel = player.farmingLevel; + } + + if (player != null && player.fishingLevel != PreviousFishingLevel) + { + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Fishing, player.fishingLevel); + PreviousFishingLevel = player.fishingLevel; + } + + if (player != null && player.foragingLevel != PreviousForagingLevel) + { + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Foraging, player.foragingLevel); + PreviousForagingLevel = player.foragingLevel; + } + + if (player != null && player.miningLevel != PreviousMiningLevel) + { + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Mining, player.miningLevel); + PreviousMiningLevel = player.miningLevel; + } + + if (player != null && player.luckLevel != PreviousLuckLevel) + { + PlayerEvents.InvokeLeveledUp(EventArgsLevelUp.LevelType.Luck, player.luckLevel); + PreviousLuckLevel = player.luckLevel; + } + + List changedItems; + if (player != null && HasInventoryChanged(player.items, out changedItems)) + { + PlayerEvents.InvokeInventoryChanged(player.items, changedItems); + PreviousItems = player.items.Where(n => n != null).ToDictionary(n => n, n => n.Stack); + } + + var objectHash = currentLocation?.objects?.GetHash(); + if (objectHash != null && PreviousLocationObjects != objectHash) + { + LocationEvents.InvokeOnNewLocationObject(currentLocation.objects); + PreviousLocationObjects = objectHash ?? -1; + } + + if (timeOfDay != PreviousTimeOfDay) + { + TimeEvents.InvokeTimeOfDayChanged(PreviousTimeOfDay, timeOfDay); + PreviousTimeOfDay = timeOfDay; + } + + if (dayOfMonth != PreviousDayOfMonth) + { + TimeEvents.InvokeDayOfMonthChanged(PreviousDayOfMonth, dayOfMonth); + PreviousDayOfMonth = dayOfMonth; + } + + if (currentSeason != PreviousSeasonOfYear) + { + TimeEvents.InvokeSeasonOfYearChanged(PreviousSeasonOfYear, currentSeason); + PreviousSeasonOfYear = currentSeason; + } + + if (year != PreviousYearOfGame) + { + TimeEvents.InvokeYearOfGameChanged(PreviousYearOfGame, year); + PreviousYearOfGame = year; + } + + //NOTE THAT THIS MUST CHECK BEFORE SETTING IT TO TRUE BECAUSE OF SOME SILLY ISSUES + if (FireLoadedGameEvent) + { + PlayerEvents.InvokeLoadedGame(new EventArgsLoadedGameChanged(hasLoadedGame)); + FireLoadedGameEvent = false; + } + + if (hasLoadedGame != PreviouslyLoadedGame) + { + FireLoadedGameEvent = true; + PreviouslyLoadedGame = hasLoadedGame; + } + + if (mine != null && PreviousMineLevel != mine.mineLevel) + { + MineEvents.InvokeMineLevelChanged(PreviousMineLevel, mine.mineLevel); + PreviousMineLevel = mine.mineLevel; + } + + if (PreviousIsNewDay != newDay) + { + TimeEvents.InvokeOnNewDay(PreviousDayOfMonth, dayOfMonth, newDay); + PreviousIsNewDay = newDay; + } + } + + private bool HasInventoryChanged(List items, out List changedItems) + { + changedItems = new List(); + IEnumerable actualItems = items.Where(n => n != null).ToArray(); + foreach (var item in actualItems) + { + if (PreviousItems != null && PreviousItems.ContainsKey(item)) + { + if (PreviousItems[item] != item.Stack) + { + changedItems.Add(new ItemStackChange {Item = item, StackChange = item.Stack - PreviousItems[item], ChangeType = ChangeType.StackChange}); + } + } + else + { + changedItems.Add(new ItemStackChange {Item = item, StackChange = item.Stack, ChangeType = ChangeType.Added}); + } + } + + if (PreviousItems != null) + { + changedItems.AddRange(PreviousItems.Where(n => actualItems.All(i => i != n.Key)).Select(n => + new ItemStackChange {Item = n.Key, StackChange = -n.Key.Stack, ChangeType = ChangeType.Removed})); + } + + return changedItems.Any(); + } + + /// + /// Invokes a private, non-static method in Game1 via Reflection + /// + /// The name of the method + /// Any parameters needed + /// Whatever the method normally returns. Null if void. + [Obsolete("This is very slow. Cache the method info and then invoke it with InvokeMethodInfo().")] + public static object InvokeBasePrivateInstancedMethod(string name, params object[] parameters) + { + try + { + return typeof(Game1).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance).Invoke(Program.gamePtr, parameters); + } + catch + { + Log.AsyncR("Failed to call base method: " + name); + return null; + } + } + + /// + /// Invokes a given method info with the supplied parameters + /// + /// + /// + /// + public static object InvokeMethodInfo(MethodInfo mi, params object[] parameters) + { + try + { + return mi.Invoke(Program.gamePtr, parameters); + } + catch + { + Log.AsyncR("Failed to call base method: " + mi.Name); + return null; + } + } + + /// + /// Queue's a message to be drawn in Debug mode (F3) + /// + /// + public static bool QueueDebugMessage(string message) + { + if (!Debug) + return false; + + if (DebugMessageQueue.Count > 32) + return false; + + DebugMessageQueue.Enqueue(message); + return true; + } + } +} \ No newline at end of file diff --git a/src/StardewModdingAPI/Inheritance/SObject.cs b/src/StardewModdingAPI/Inheritance/SObject.cs new file mode 100644 index 00000000..639b85b1 --- /dev/null +++ b/src/StardewModdingAPI/Inheritance/SObject.cs @@ -0,0 +1,277 @@ +using System; +using System.Xml.Serialization; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewValley; +using Object = StardewValley.Object; + +#pragma warning disable 1591 + +namespace StardewModdingAPI.Inheritance +{ + [Obsolete("Do not use at this time.")] + public class SObject : Object + { + public SObject() + { + name = "Modded Item Name"; + Description = "Modded Item Description"; + CategoryName = "Modded Item Category"; + Category = 4163; + CategoryColour = Color.White; + IsPassable = false; + IsPlaceable = false; + boundingBox = new Rectangle(0, 0, 64, 64); + MaxStackSize = 999; + + type = "interactive"; + } + + public override string Name + { + get { return name; } + set { name = value; } + } + + public string Description { get; set; } + public Texture2D Texture { get; set; } + public string CategoryName { get; set; } + public Color CategoryColour { get; set; } + public bool IsPassable { get; set; } + public bool IsPlaceable { get; set; } + public bool HasBeenRegistered { get; set; } + public int RegisteredId { get; set; } + + public int MaxStackSize { get; set; } + + public bool WallMounted { get; set; } + public Vector2 DrawPosition { get; set; } + + public bool FlaggedForPickup { get; set; } + + [XmlIgnore] + public Vector2 CurrentMouse { get; protected set; } + + [XmlIgnore] + public Vector2 PlacedAt { get; protected set; } + + public override int Stack + { + get { return stack; } + set { stack = value; } + } + + public override string getDescription() + { + return Description; + } + + public override void draw(SpriteBatch spriteBatch, int x, int y, float alpha = 1) + { + if (Texture != null) + { + spriteBatch.Draw(Texture, Game1.GlobalToLocal(Game1.viewport, new Vector2(x * Game1.tileSize + Game1.tileSize / 2 + (shakeTimer > 0 ? Game1.random.Next(-1, 2) : 0), y * Game1.tileSize + Game1.tileSize / 2 + (shakeTimer > 0 ? Game1.random.Next(-1, 2) : 0))), Game1.currentLocation.getSourceRectForObject(ParentSheetIndex), Color.White * alpha, 0f, new Vector2(8f, 8f), scale.Y > 1f ? getScale().Y : Game1.pixelZoom, flipped ? SpriteEffects.FlipHorizontally : SpriteEffects.None, (isPassable() ? getBoundingBox(new Vector2(x, y)).Top : getBoundingBox(new Vector2(x, y)).Bottom) / 10000f); + } + } + + public new void drawAsProp(SpriteBatch b) + { + } + + public override void draw(SpriteBatch spriteBatch, int xNonTile, int yNonTile, float layerDepth, float alpha = 1) + { + Log.Debug("THIS DRAW FUNCTION IS NOT IMPLEMENTED I WANT TO KNOW WHERE IT IS CALLED"); + //try + //{ + // if (Texture != null) + // { + // int targSize = Game1.tileSize; + // int midX = (xNonTile) + 32; + // int midY = (yNonTile) + 32; + + // int targX = midX - targSize / 2; + // int targY = midY - targSize / 2; + + // Rectangle targ = new Rectangle(targX, targY, targSize, targSize); + // spriteBatch.Draw(Texture, targ, null, new Color(255, 255, 255, 255f * alpha), 0, Vector2.Zero, SpriteEffects.None, layerDepth); + // //spriteBatch.Draw(Program.DebugPixel, targ, null, Color.Red, 0, Vector2.Zero, SpriteEffects.None, layerDepth); + // /* + // spriteBatch.DrawString(Game1.dialogueFont, "TARG: " + targ, new Vector2(128, 0), Color.Red); + // spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX * 0.5f, targY), Color.Orange); + // spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX, targY), Color.Red); + // spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX * 1.5f, targY), Color.Yellow); + // spriteBatch.DrawString(Game1.dialogueFont, ".", new Vector2(targX * 2f, targY), Color.Green); + // */ + // } + //} + //catch (Exception ex) + //{ + // Log.AsyncR(ex.ToString()); + // Console.ReadKey(); + //} + } + + public override void drawInMenu(SpriteBatch spriteBatch, Vector2 location, float scaleSize, float transparency, float layerDepth, bool drawStackNumber) + { + if (isRecipe) + { + transparency = 0.5f; + scaleSize *= 0.75f; + } + + if (Texture != null) + { + var targSize = (int) (64 * scaleSize * 0.9f); + var midX = (int) (location.X + 32); + var midY = (int) (location.Y + 32); + + var targX = midX - targSize / 2; + var targY = midY - targSize / 2; + + spriteBatch.Draw(Texture, new Rectangle(targX, targY, targSize, targSize), null, new Color(255, 255, 255, transparency), 0, Vector2.Zero, SpriteEffects.None, layerDepth); + } + if (drawStackNumber) + { + var _scale = 0.5f + scaleSize; + Game1.drawWithBorder(stack.ToString(), Color.Black, Color.White, location + new Vector2(Game1.tileSize - Game1.tinyFont.MeasureString(string.Concat(stack.ToString())).X * _scale, Game1.tileSize - (float) ((double) Game1.tinyFont.MeasureString(string.Concat(stack.ToString())).Y * 3.0f / 4.0f) * _scale), 0.0f, _scale, 1f, true); + } + } + + public override void drawWhenHeld(SpriteBatch spriteBatch, Vector2 objectPosition, Farmer f) + { + if (Texture != null) + { + var targSize = 64; + var midX = (int) (objectPosition.X + 32); + var midY = (int) (objectPosition.Y + 32); + + var targX = midX - targSize / 2; + var targY = midY - targSize / 2; + + spriteBatch.Draw(Texture, new Rectangle(targX, targY, targSize, targSize), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, (f.getStandingY() + 2) / 10000f); + } + } + + public override Color getCategoryColor() + { + return CategoryColour; + } + + public override string getCategoryName() + { + if (string.IsNullOrEmpty(CategoryName)) + return "Modded Item"; + return CategoryName; + } + + public override bool isPassable() + { + return IsPassable; + } + + public override bool isPlaceable() + { + return IsPlaceable; + } + + public override int maximumStackSize() + { + return MaxStackSize; + } + + public SObject Clone() + { + var toRet = new SObject + { + Name = Name, + CategoryName = CategoryName, + Description = Description, + Texture = Texture, + IsPassable = IsPassable, + IsPlaceable = IsPlaceable, + quality = quality, + scale = scale, + isSpawnedObject = isSpawnedObject, + isRecipe = isRecipe, + questItem = questItem, + stack = 1, + HasBeenRegistered = HasBeenRegistered, + RegisteredId = RegisteredId + }; + + + return toRet; + } + + public override Item getOne() + { + return Clone(); + } + + public override void actionWhenBeingHeld(Farmer who) + { + var x = Game1.oldMouseState.X + Game1.viewport.X; + var y = Game1.oldMouseState.Y + Game1.viewport.Y; + + x = x / Game1.tileSize; + y = y / Game1.tileSize; + + CurrentMouse = new Vector2(x, y); + //Program.LogDebug(canBePlacedHere(Game1.currentLocation, CurrentMouse)); + base.actionWhenBeingHeld(who); + } + + public override bool canBePlacedHere(GameLocation l, Vector2 tile) + { + //Program.LogDebug(CurrentMouse.ToString().Replace("{", "").Replace("}", "")); + if (!l.objects.ContainsKey(tile)) + return true; + + return false; + } + + public override bool placementAction(GameLocation location, int x, int y, Farmer who = null) + { + if (Game1.didPlayerJustRightClick()) + return false; + + x = x / Game1.tileSize; + y = y / Game1.tileSize; + + //Program.LogDebug(x + " - " + y); + //Console.ReadKey(); + + var key = new Vector2(x, y); + + if (!canBePlacedHere(location, key)) + return false; + + var s = Clone(); + + s.PlacedAt = key; + s.boundingBox = new Rectangle(x / Game1.tileSize * Game1.tileSize, y / Game1.tileSize * Game1.tileSize, boundingBox.Width, boundingBox.Height); + + location.objects.Add(key, s); + Log.Async($"{GetHashCode()} - {s.GetHashCode()}"); + + return true; + } + + public override void actionOnPlayerEntry() + { + //base.actionOnPlayerEntry(); + } + + public override void drawPlacementBounds(SpriteBatch spriteBatch, GameLocation location) + { + if (canBePlacedHere(location, CurrentMouse)) + { + var targSize = Game1.tileSize; + + var x = Game1.oldMouseState.X + Game1.viewport.X; + var y = Game1.oldMouseState.Y + Game1.viewport.Y; + spriteBatch.Draw(Game1.mouseCursors, new Vector2(x / Game1.tileSize * Game1.tileSize - Game1.viewport.X, y / Game1.tileSize * Game1.tileSize - Game1.viewport.Y), new Rectangle(Utility.playerCanPlaceItemHere(location, this, x, y, Game1.player) ? 194 : 210, 388, 16, 16), Color.White, 0.0f, Vector2.Zero, Game1.pixelZoom, SpriteEffects.None, 0.01f); + } + } + } +} \ No newline at end of file -- cgit