Fix Virtual Keyboard mod
This commit is contained in:
parent
0f94f4609d
commit
a406411a04
|
@ -1,74 +1,58 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using StardewModdingAPI.Events;
|
||||
using StardewModdingAPI.Framework;
|
||||
using StardewModdingAPI.Framework.Input;
|
||||
using StardewValley;
|
||||
using StardewValley.Menus;
|
||||
using System.Reflection;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using static StardewModdingAPI.Mods.VirtualKeyboard.ModConfig;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace StardewModdingAPI.Mods.VirtualKeyboard
|
||||
{
|
||||
class KeyButton
|
||||
{
|
||||
private readonly IModHelper helper;
|
||||
private readonly IMonitor Monitor;
|
||||
private readonly Rectangle buttonRectangle;
|
||||
private readonly Rectangle ButtonRectangle;
|
||||
|
||||
private object buttonPressed;
|
||||
private object buttonReleased;
|
||||
|
||||
private readonly MethodBase RaiseButtonPressed;
|
||||
private readonly MethodBase RaiseButtonReleased;
|
||||
|
||||
private readonly SButton buttonKey;
|
||||
private readonly float transparency;
|
||||
private readonly string alias;
|
||||
private readonly string command;
|
||||
public bool hidden;
|
||||
private bool raisingPressed = false;
|
||||
private bool raisingReleased = false;
|
||||
private readonly SButton ButtonKey;
|
||||
private readonly float Transparency;
|
||||
private readonly string Alias;
|
||||
private readonly string Command;
|
||||
public bool Hidden;
|
||||
private bool RaisingPressed;
|
||||
private bool RaisingReleased;
|
||||
|
||||
public KeyButton(IModHelper helper, VirtualButton buttonDefine, IMonitor monitor)
|
||||
{
|
||||
this.Monitor = monitor;
|
||||
this.helper = helper;
|
||||
this.hidden = true;
|
||||
this.buttonRectangle = new Rectangle(buttonDefine.rectangle.X, buttonDefine.rectangle.Y, buttonDefine.rectangle.Width, buttonDefine.rectangle.Height);
|
||||
this.buttonKey = buttonDefine.key;
|
||||
this.Hidden = true;
|
||||
this.ButtonRectangle = new Rectangle(buttonDefine.rectangle.X, buttonDefine.rectangle.Y, buttonDefine.rectangle.Width, buttonDefine.rectangle.Height);
|
||||
this.ButtonKey = buttonDefine.key;
|
||||
|
||||
if (buttonDefine.alias == null)
|
||||
this.alias = this.buttonKey.ToString();
|
||||
this.Alias = this.ButtonKey.ToString();
|
||||
else
|
||||
this.alias = buttonDefine.alias;
|
||||
this.command = buttonDefine.command;
|
||||
this.Alias = buttonDefine.alias;
|
||||
this.Command = buttonDefine.command;
|
||||
|
||||
if (buttonDefine.transparency <= 0.01f || buttonDefine.transparency > 1f)
|
||||
{
|
||||
buttonDefine.transparency = 0.5f;
|
||||
}
|
||||
this.transparency = buttonDefine.transparency;
|
||||
this.Transparency = buttonDefine.transparency;
|
||||
|
||||
helper.Events.Display.Rendered += this.OnRendered;
|
||||
helper.Events.Input.ButtonReleased += this.EventInputButtonReleased;
|
||||
helper.Events.Input.ButtonPressed += this.EventInputButtonPressed;
|
||||
}
|
||||
|
||||
private object GetSCore(IModHelper helper)
|
||||
private bool ShouldTrigger(Vector2 screenPixels, SButton button)
|
||||
{
|
||||
MainActivity activity = this.helper.Reflection.GetField<MainActivity>(typeof(MainActivity), "instance").GetValue();
|
||||
object score = activity.GetType().GetField("core", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(activity);
|
||||
return score;
|
||||
}
|
||||
|
||||
private bool shouldTrigger(Vector2 screenPixels, SButton button)
|
||||
if (this.ButtonRectangle.Contains(screenPixels.X * Game1.options.zoomLevel, screenPixels.Y * Game1.options.zoomLevel) && !this.Hidden && button == SButton.MouseLeft)
|
||||
{
|
||||
if (this.buttonRectangle.Contains(screenPixels.X * Game1.options.zoomLevel, screenPixels.Y * Game1.options.zoomLevel) && !this.hidden && button == SButton.MouseLeft)
|
||||
{
|
||||
if (!this.hidden)
|
||||
if (!this.Hidden)
|
||||
Toolbar.toolbarPressed = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -77,34 +61,34 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard
|
|||
|
||||
private void EventInputButtonPressed(object sender, ButtonPressedEventArgs e)
|
||||
{
|
||||
if (this.raisingPressed)
|
||||
if (this.RaisingPressed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 screenPixels = e.Cursor.ScreenPixels;
|
||||
if (this.buttonKey != SButton.None && this.shouldTrigger(screenPixels, e.Button))
|
||||
if (this.ButtonKey != SButton.None && this.ShouldTrigger(screenPixels, e.Button))
|
||||
{
|
||||
object input = this.helper.Reflection.GetField<object>(typeof(Game1), "input").GetValue();
|
||||
this.raisingPressed = true;
|
||||
input.GetType().GetMethod("OverrideButton").Invoke(input, new object[] { this.buttonKey, true });
|
||||
this.raisingPressed = false;
|
||||
this.RaisingPressed = true;
|
||||
SInputState input = Game1.input as SInputState;
|
||||
input?.OverrideButton(this.ButtonKey, true);
|
||||
this.RaisingPressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void EventInputButtonReleased(object sender, ButtonReleasedEventArgs e)
|
||||
{
|
||||
if (this.raisingReleased)
|
||||
if (this.RaisingReleased)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 screenPixels = e.Cursor.ScreenPixels;
|
||||
if (this.shouldTrigger(screenPixels, e.Button))
|
||||
if (this.ShouldTrigger(screenPixels, e.Button))
|
||||
{
|
||||
if (this.buttonKey == SButton.RightWindows)
|
||||
if (this.ButtonKey == SButton.RightWindows)
|
||||
{
|
||||
KeyboardInput.Show("Command", "", "", false).ContinueWith<string>(delegate (Task<string> s) {
|
||||
KeyboardInput.Show("Command", "").ContinueWith(delegate (Task<string> s) {
|
||||
string command;
|
||||
command = s.Result;
|
||||
if (command.Length > 0)
|
||||
|
@ -115,36 +99,31 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard
|
|||
});
|
||||
return;
|
||||
}
|
||||
if (this.buttonKey == SButton.RightControl)
|
||||
if (this.ButtonKey == SButton.RightControl)
|
||||
{
|
||||
SGameConsole.Instance.Show();
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(this.command))
|
||||
if (!string.IsNullOrEmpty(this.Command))
|
||||
{
|
||||
this.SendCommand(this.command);
|
||||
this.SendCommand(this.Command);
|
||||
return;
|
||||
}
|
||||
object input = this.helper.Reflection.GetField<object>(typeof(Game1), "input").GetValue();
|
||||
this.raisingReleased = true;
|
||||
input.GetType().GetMethod("OverrideButton").Invoke(input, new object[] { this.buttonKey, false });
|
||||
this.raisingReleased = false;
|
||||
this.RaisingReleased = true;
|
||||
SInputState input = Game1.input as SInputState;
|
||||
input?.OverrideButton(this.ButtonKey, false);
|
||||
this.RaisingReleased = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SendCommand(string command)
|
||||
{
|
||||
object score = this.GetSCore(this.helper);
|
||||
ConcurrentQueue<string> commandQueue = score.GetType().GetProperty("CommandQueue", BindingFlags.Public | BindingFlags.Instance)?.GetValue(score) as ConcurrentQueue<string>;
|
||||
SCore score = SMainActivity.Instance.core;
|
||||
CommandQueue commandQueue = score.RawCommandQueue;
|
||||
if (commandQueue != null)
|
||||
{
|
||||
commandQueue.Enqueue(command);
|
||||
return;
|
||||
commandQueue.Add(command);
|
||||
}
|
||||
|
||||
object sgame = score.GetType().GetField("Game", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(score);
|
||||
commandQueue = sgame.GetType().GetProperty("CommandQueue", BindingFlags.Public | BindingFlags.Instance)?.GetValue(sgame) as ConcurrentQueue<string>;
|
||||
commandQueue?.Enqueue(command);
|
||||
}
|
||||
|
||||
/// <summary>Raised before drawing the HUD (item toolbar, clock, etc) to the screen.</summary>
|
||||
|
@ -152,19 +131,20 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard
|
|||
/// <param name="e">The event arguments.</param>
|
||||
private void OnRendered(object sender, EventArgs e)
|
||||
{
|
||||
if (!this.hidden)
|
||||
if (!this.Hidden)
|
||||
{
|
||||
float scale = this.transparency;
|
||||
float scale = this.Transparency;
|
||||
if (!Game1.eventUp && Game1.activeClickableMenu is GameMenu == false && Game1.activeClickableMenu is ShopMenu == false && Game1.activeClickableMenu is IClickableMenu == false)
|
||||
{
|
||||
scale *= 0.5f;
|
||||
}
|
||||
System.Reflection.FieldInfo matrixField = Game1.spriteBatch.GetType().GetField("_matrix", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
object originMatrix = matrixField.GetValue(Game1.spriteBatch);
|
||||
System.Reflection.FieldInfo spriteEffectField = Game1.spriteBatch.GetType().GetField("_spriteEffect", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
SpriteEffect originSpriteEffect = spriteEffectField?.GetValue(Game1.spriteBatch) as SpriteEffect;
|
||||
var originMatrix = originSpriteEffect?.TransformMatrix;
|
||||
Game1.spriteBatch.End();
|
||||
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, null, Microsoft.Xna.Framework.Matrix.CreateScale(1f));
|
||||
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, null, Matrix.CreateScale(1f));
|
||||
IClickableMenu.drawTextureBoxWithIconAndText(Game1.spriteBatch, Game1.smallFont, Game1.mouseCursors, new Rectangle(0x100, 0x100, 10, 10), null, new Rectangle(0, 0, 1, 1),
|
||||
this.alias, this.buttonRectangle.X, this.buttonRectangle.Y, this.buttonRectangle.Width, this.buttonRectangle.Height, Color.BurlyWood * scale, 4f,
|
||||
this.Alias, this.ButtonRectangle.X, this.ButtonRectangle.Y, this.ButtonRectangle.Width, this.ButtonRectangle.Height, Color.BurlyWood * scale, 4f,
|
||||
true, false, true, false, false, false, false); // Remove bold to fix the text position issue
|
||||
Game1.spriteBatch.End();
|
||||
if(originMatrix != null)
|
||||
|
|
|
@ -2,18 +2,18 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard
|
|||
{
|
||||
class ModConfig
|
||||
{
|
||||
public Toggle vToggle { get; set; } = new Toggle(new Rect(36, 12, 64, 64), true, SButton.None);
|
||||
public Toggle vToggle { get; set; } = new(new Rect(36, 12, 64, 64), true, SButton.None);
|
||||
public VirtualButton[] buttons { get; set;} = new VirtualButton[] {
|
||||
new VirtualButton(SButton.Q, new Rect(190, 80, 90, 90), 0.5f),
|
||||
new VirtualButton(SButton.I, new Rect(290, 80, 90, 90), 0.5f),
|
||||
new VirtualButton(SButton.O, new Rect(390, 80, 90, 90), 0.5f),
|
||||
new VirtualButton(SButton.P, new Rect(490, 80, 90, 90), 0.5f)
|
||||
new(SButton.Q, new Rect(190, 80, 90, 90), 0.5f),
|
||||
new(SButton.I, new Rect(290, 80, 90, 90), 0.5f),
|
||||
new(SButton.O, new Rect(390, 80, 90, 90), 0.5f),
|
||||
new(SButton.P, new Rect(490, 80, 90, 90), 0.5f)
|
||||
};
|
||||
public VirtualButton[] buttonsExtend { get; set; } = new VirtualButton[] {
|
||||
new VirtualButton(SButton.MouseRight, new Rect(190, 170, 162, 90), 0.5f, "RightMouse"),
|
||||
new VirtualButton(SButton.None, new Rect(360, 170, 92, 90), 0.5f, "Zoom", "zoom 1.0"),
|
||||
new VirtualButton(SButton.RightWindows, new Rect(460, 170, 162, 90), 0.5f, "Command"),
|
||||
new VirtualButton(SButton.RightControl, new Rect(630, 170, 162, 90), 0.5f, "Console")
|
||||
new(SButton.MouseRight, new Rect(190, 170, 162, 90), 0.5f, "RightMouse"),
|
||||
new(SButton.None, new Rect(360, 170, 92, 90), 0.5f, "Zoom", "zoom 1.0"),
|
||||
new(SButton.RightWindows, new Rect(460, 170, 162, 90), 0.5f, "Command"),
|
||||
new(SButton.RightControl, new Rect(630, 170, 162, 90), 0.5f, "Console")
|
||||
};
|
||||
internal class VirtualButton {
|
||||
public SButton key { get;set; }
|
||||
|
|
|
@ -1,36 +1 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("StardewModdingAPI.Mods.VirtualKeyboard")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("StardewModdingAPI.Mods.VirtualKeyboard")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("29cce9c9-6811-415d-a681-a6d47073924d")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
|
@ -1,18 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{29CCE9C9-6811-415D-A681-A6D47073924D}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>StardewModdingAPI.Mods.VirtualKeyboard</RootNamespace>
|
||||
<AssemblyName>VirtualKeyboard</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -32,54 +28,16 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Android">
|
||||
<HintPath>..\..\..\..\..\Downloads\StardewValleyAndroidStuff\base_1.4.5.145\assemblies\Mono.Android.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MonoGame.Framework, Version=3.7.1.189, Culture=neutral, processorArchitecture=MSIL">
|
||||
<Reference Include="MonoGame.Framework">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\Downloads\StardewValleyAndroidStuff\base_1.4.5.145\assemblies\MonoGame.Framework.dll</HintPath>
|
||||
<HintPath>..\..\..\Downloads\StardewValleyAndroidStuff\base_1.5.6.31\assemblies\MonoGame.Framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="StardewModdingAPI">
|
||||
<HintPath>..\SMAPI\bin\Release\StardewModdingAPI.dll</HintPath>
|
||||
<HintPath>..\SMAPI\bin\Debug\StardewModdingAPI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="StardewValley">
|
||||
<HintPath>..\..\..\..\..\Downloads\StardewValleyAndroidStuff\base_1.4.5.145\assemblies\StardewValley.dll</HintPath>
|
||||
<HintPath>..\..\..\Downloads\StardewValleyAndroidStuff\base_1.5.6.31\assemblies\StardewValley.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Core">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows.Forms">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="KeyButton.cs" />
|
||||
<Compile Include="ModConfig.cs" />
|
||||
<Compile Include="ModEntry.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="VirtualToggle.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="manifest.json" />
|
||||
|
@ -93,5 +51,4 @@
|
|||
<Name>SMAPI.Toolkit</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -10,105 +10,105 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard
|
|||
{
|
||||
class VirtualToggle
|
||||
{
|
||||
private readonly IModHelper helper;
|
||||
private readonly IModHelper Helper;
|
||||
private readonly IMonitor Monitor;
|
||||
|
||||
private int enabledStage = 0;
|
||||
private bool autoHidden = true;
|
||||
private bool isDefault = true;
|
||||
private ClickableTextureComponent virtualToggleButton;
|
||||
private int EnabledStage = 0;
|
||||
private bool AutoHidden = true;
|
||||
private bool IsDefault = true;
|
||||
private ClickableTextureComponent VirtualToggleButton;
|
||||
|
||||
private List<KeyButton> keyboard = new List<KeyButton>();
|
||||
private List<KeyButton> keyboardExtend = new List<KeyButton>();
|
||||
private ModConfig modConfig;
|
||||
private Texture2D texture;
|
||||
private int lastPressTick = 0;
|
||||
private List<KeyButton> Keyboard = new();
|
||||
private List<KeyButton> KeyboardExtend = new();
|
||||
private ModConfig ModConfig;
|
||||
private Texture2D Texture;
|
||||
private int LastPressTick = 0;
|
||||
|
||||
public VirtualToggle(IModHelper helper, IMonitor monitor)
|
||||
{
|
||||
this.Monitor = monitor;
|
||||
this.helper = helper;
|
||||
this.texture = this.helper.Content.Load<Texture2D>("assets/togglebutton.png", ContentSource.ModFolder);
|
||||
this.Helper = helper;
|
||||
this.Texture = this.Helper.ModContent.Load<Texture2D>("assets/togglebutton.png");
|
||||
|
||||
this.modConfig = helper.ReadConfig<ModConfig>();
|
||||
for (int i = 0; i < this.modConfig.buttons.Length; i++)
|
||||
this.keyboard.Add(new KeyButton(helper, this.modConfig.buttons[i], this.Monitor));
|
||||
for (int i = 0; i < this.modConfig.buttonsExtend.Length; i++)
|
||||
this.keyboardExtend.Add(new KeyButton(helper, this.modConfig.buttonsExtend[i], this.Monitor));
|
||||
this.ModConfig = helper.ReadConfig<ModConfig>();
|
||||
for (int i = 0; i < this.ModConfig.buttons.Length; i++)
|
||||
this.Keyboard.Add(new KeyButton(helper, this.ModConfig.buttons[i], this.Monitor));
|
||||
for (int i = 0; i < this.ModConfig.buttonsExtend.Length; i++)
|
||||
this.KeyboardExtend.Add(new KeyButton(helper, this.ModConfig.buttonsExtend[i], this.Monitor));
|
||||
|
||||
if (this.modConfig.vToggle.rectangle.X != 36 || this.modConfig.vToggle.rectangle.Y != 12)
|
||||
this.isDefault = false;
|
||||
this.autoHidden = this.modConfig.vToggle.autoHidden;
|
||||
if (this.ModConfig.vToggle.rectangle.X != 36 || this.ModConfig.vToggle.rectangle.Y != 12)
|
||||
this.IsDefault = false;
|
||||
this.AutoHidden = this.ModConfig.vToggle.autoHidden;
|
||||
|
||||
this.virtualToggleButton = new ClickableTextureComponent(new Rectangle(Game1.toolbarPaddingX + 64, 12, 128, 128), this.texture, new Rectangle(0, 0, 16, 16), 5.75f, false);
|
||||
helper.WriteConfig(this.modConfig);
|
||||
this.VirtualToggleButton = new ClickableTextureComponent(new Rectangle(Game1.toolbarPaddingX + 64, 12, 128, 128), this.Texture, new Rectangle(0, 0, 16, 16), 5.75f, false);
|
||||
helper.WriteConfig(this.ModConfig);
|
||||
|
||||
this.helper.Events.Display.Rendered += this.OnRendered;
|
||||
this.helper.Events.Display.MenuChanged += this.OnMenuChanged;
|
||||
this.helper.Events.Input.ButtonPressed += this.VirtualToggleButtonPressed;
|
||||
this.Helper.Events.Display.Rendered += this.OnRendered;
|
||||
this.Helper.Events.Display.MenuChanged += this.OnMenuChanged;
|
||||
this.Helper.Events.Input.ButtonPressed += this.VirtualToggleButtonPressed;
|
||||
}
|
||||
|
||||
private void OnMenuChanged(object sender, MenuChangedEventArgs e)
|
||||
{
|
||||
if(this.autoHidden && e.NewMenu != null) {
|
||||
foreach (var keys in this.keyboard)
|
||||
if(this.AutoHidden && e.NewMenu != null) {
|
||||
foreach (var keys in this.Keyboard)
|
||||
{
|
||||
keys.hidden = true;
|
||||
keys.Hidden = true;
|
||||
}
|
||||
foreach (var keys in this.keyboardExtend)
|
||||
foreach (var keys in this.KeyboardExtend)
|
||||
{
|
||||
keys.hidden = true;
|
||||
keys.Hidden = true;
|
||||
}
|
||||
this.enabledStage = 0;
|
||||
this.EnabledStage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void VirtualToggleButtonPressed(object sender, ButtonPressedEventArgs e)
|
||||
{
|
||||
Vector2 screenPixels = e.Cursor.ScreenPixels;
|
||||
if (this.modConfig.vToggle.key != SButton.None && e.Button == this.modConfig.vToggle.key)
|
||||
this.toggleLogic();
|
||||
else if (e.Button == SButton.MouseLeft && this.shouldTrigger(screenPixels))
|
||||
this.toggleLogic();
|
||||
if (this.ModConfig.vToggle.key != SButton.None && e.Button == this.ModConfig.vToggle.key)
|
||||
this.ToggleLogic();
|
||||
else if (e.Button == SButton.MouseLeft && this.ShouldTrigger(screenPixels))
|
||||
this.ToggleLogic();
|
||||
}
|
||||
|
||||
private void toggleLogic()
|
||||
private void ToggleLogic()
|
||||
{
|
||||
switch (this.enabledStage)
|
||||
switch (this.EnabledStage)
|
||||
{
|
||||
case 0:
|
||||
foreach (var keys in this.keyboard)
|
||||
foreach (var keys in this.Keyboard)
|
||||
{
|
||||
keys.hidden = false;
|
||||
keys.Hidden = false;
|
||||
}
|
||||
|
||||
foreach (var keys in this.keyboardExtend)
|
||||
foreach (var keys in this.KeyboardExtend)
|
||||
{
|
||||
keys.hidden = true;
|
||||
keys.Hidden = true;
|
||||
}
|
||||
|
||||
this.enabledStage = 1;
|
||||
this.EnabledStage = 1;
|
||||
break;
|
||||
case 1 when this.keyboardExtend.Count > 0:
|
||||
foreach (var keys in this.keyboardExtend)
|
||||
case 1 when this.KeyboardExtend.Count > 0:
|
||||
foreach (var keys in this.KeyboardExtend)
|
||||
{
|
||||
keys.hidden = false;
|
||||
keys.Hidden = false;
|
||||
}
|
||||
|
||||
this.enabledStage = 2;
|
||||
this.EnabledStage = 2;
|
||||
break;
|
||||
default:
|
||||
foreach (var keys in this.keyboard)
|
||||
foreach (var keys in this.Keyboard)
|
||||
{
|
||||
keys.hidden = true;
|
||||
keys.Hidden = true;
|
||||
}
|
||||
|
||||
foreach (var keys in this.keyboardExtend)
|
||||
foreach (var keys in this.KeyboardExtend)
|
||||
{
|
||||
keys.hidden = true;
|
||||
keys.Hidden = true;
|
||||
}
|
||||
|
||||
this.enabledStage = 0;
|
||||
this.EnabledStage = 0;
|
||||
if (Game1.activeClickableMenu is IClickableMenu menu && !(Game1.activeClickableMenu is DialogueBox))
|
||||
{
|
||||
menu.exitThisMenu();
|
||||
|
@ -119,16 +119,16 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard
|
|||
}
|
||||
}
|
||||
|
||||
private bool shouldTrigger(Vector2 screenPixels)
|
||||
private bool ShouldTrigger(Vector2 screenPixels)
|
||||
{
|
||||
int tick = Game1.ticks;
|
||||
if(tick - this.lastPressTick <= 6)
|
||||
if(tick - this.LastPressTick <= 6)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.virtualToggleButton.containsPoint((int)(screenPixels.X * Game1.options.zoomLevel), (int)(screenPixels.Y * Game1.options.zoomLevel)))
|
||||
if (this.VirtualToggleButton.containsPoint((int)(screenPixels.X * Game1.options.zoomLevel), (int)(screenPixels.Y * Game1.options.zoomLevel)))
|
||||
{
|
||||
this.lastPressTick = tick;
|
||||
this.LastPressTick = tick;
|
||||
Toolbar.toolbarPressed = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -137,42 +137,43 @@ namespace StardewModdingAPI.Mods.VirtualKeyboard
|
|||
|
||||
private void OnRendered(object sender, EventArgs e)
|
||||
{
|
||||
if (this.isDefault)
|
||||
if (this.IsDefault)
|
||||
{
|
||||
if (Game1.options.verticalToolbar)
|
||||
this.virtualToggleButton.bounds.X = Game1.toolbarPaddingX + Game1.toolbar.itemSlotSize + 200;
|
||||
this.VirtualToggleButton.bounds.X = Game1.toolbarPaddingX + Game1.toolbar.itemSlotSize + 200;
|
||||
else
|
||||
this.virtualToggleButton.bounds.X = Game1.toolbarPaddingX + Game1.toolbar.itemSlotSize + 50;
|
||||
this.VirtualToggleButton.bounds.X = Game1.toolbarPaddingX + Game1.toolbar.itemSlotSize + 50;
|
||||
|
||||
if (Game1.toolbar.alignTop == true && !Game1.options.verticalToolbar)
|
||||
{
|
||||
object toolbarHeight = this.helper.Reflection.GetField<int>(Game1.toolbar, "toolbarHeight").GetValue();
|
||||
this.virtualToggleButton.bounds.Y = (int)toolbarHeight + 50;
|
||||
object toolbarHeight = this.Helper.Reflection.GetField<int>(Game1.toolbar, "toolbarHeight").GetValue();
|
||||
this.VirtualToggleButton.bounds.Y = (int)toolbarHeight + 50;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.virtualToggleButton.bounds.Y = 12;
|
||||
this.VirtualToggleButton.bounds.Y = 12;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.virtualToggleButton.bounds.X = this.modConfig.vToggle.rectangle.X;
|
||||
this.virtualToggleButton.bounds.Y = this.modConfig.vToggle.rectangle.Y;
|
||||
this.VirtualToggleButton.bounds.X = this.ModConfig.vToggle.rectangle.X;
|
||||
this.VirtualToggleButton.bounds.Y = this.ModConfig.vToggle.rectangle.Y;
|
||||
}
|
||||
|
||||
float scale = 1f;
|
||||
if (this.enabledStage == 0)
|
||||
if (this.EnabledStage == 0)
|
||||
{
|
||||
scale = 0.5f;
|
||||
}
|
||||
if (!Game1.eventUp && Game1.activeClickableMenu is GameMenu == false && Game1.activeClickableMenu is ShopMenu == false)
|
||||
scale = 0.25f;
|
||||
|
||||
System.Reflection.FieldInfo matrixField = Game1.spriteBatch.GetType().GetField("_matrix", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
object originMatrix = matrixField.GetValue(Game1.spriteBatch);
|
||||
System.Reflection.FieldInfo spriteEffectField = Game1.spriteBatch.GetType().GetField("_spriteEffect", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
SpriteEffect originSpriteEffect = spriteEffectField?.GetValue(Game1.spriteBatch) as SpriteEffect;
|
||||
var originMatrix = originSpriteEffect?.TransformMatrix;
|
||||
Game1.spriteBatch.End();
|
||||
Game1.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, null, Microsoft.Xna.Framework.Matrix.CreateScale(1f));
|
||||
this.virtualToggleButton.draw(Game1.spriteBatch, Color.White * scale, 0.000001f);
|
||||
this.VirtualToggleButton.draw(Game1.spriteBatch, Color.White * scale, 0.000001f);
|
||||
Game1.spriteBatch.End();
|
||||
if (originMatrix != null)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"Name": "VirtualKeyboard",
|
||||
"Author": "SMAPI",
|
||||
"Version": "3.3.1",
|
||||
"MinimumApiVersion": "3.4.0",
|
||||
"Version": "4.0.1",
|
||||
"MinimumApiVersion": "3.18.2",
|
||||
"Description": "A much needed Virtual Keyboard for SMAPI Android.",
|
||||
"UniqueID": "VirtualKeyboard",
|
||||
"EntryDll": "VirtualKeyboard.dll",
|
||||
|
|
|
@ -16,11 +16,7 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
|
|||
HarmonyMethod finalizer = null)
|
||||
{
|
||||
if (Constants.HarmonyEnabled)
|
||||
#if HARMONY_2
|
||||
return instance.Patch(original, prefix, postfix, transpiler, finalizer);
|
||||
#else
|
||||
return instance.Patch(original, prefix, postfix, transpiler);
|
||||
#endif
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
|
||||
namespace StardewModdingAPI.Framework.ModLoading.Rewriters
|
||||
{
|
||||
/// <summary>Rewrites all references to a type.</summary>
|
||||
internal class ModuleReferenceRewriter : IInstructionHandler
|
||||
{
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <inheritdoc />
|
||||
public string DefaultPhrase { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ISet<InstructionHandleResult> Flags { get; } = new HashSet<InstructionHandleResult>();
|
||||
|
||||
/// <inheritdoc />
|
||||
public ISet<string> Phrases { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private readonly string AssemblyName;
|
||||
|
||||
private readonly AssemblyNameReference Target;
|
||||
|
||||
|
||||
public ModuleReferenceRewriter(string phrase, string assemblyName, Assembly target)
|
||||
{
|
||||
this.DefaultPhrase = $"{phrase} assembly ref";
|
||||
this.AssemblyName = assemblyName;
|
||||
this.Target = AssemblyNameReference.Parse(target.FullName);
|
||||
}
|
||||
|
||||
public bool Handle(ModuleDefinition module)
|
||||
{
|
||||
if (!module.AssemblyReferences.Any(assembly => assembly.Name.Equals(this.AssemblyName)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// add target assembly references
|
||||
module.AssemblyReferences.Add(this.Target);
|
||||
|
||||
// rewrite type scopes to use target assemblies
|
||||
IEnumerable<TypeReference> typeReferences = module.GetTypeReferences()
|
||||
.Where(p => p.Scope.Name.Equals(this.AssemblyName))
|
||||
.OrderBy(p => p.FullName);
|
||||
foreach (TypeReference type in typeReferences)
|
||||
type.Scope = this.Target;
|
||||
|
||||
// rewrite types using custom attributes
|
||||
foreach (TypeDefinition type in module.GetTypes())
|
||||
{
|
||||
foreach (CustomAttribute attr in type.CustomAttributes)
|
||||
{
|
||||
foreach (CustomAttributeArgument conField in attr.ConstructorArguments)
|
||||
{
|
||||
if (conField.Value is TypeReference typeRef)
|
||||
typeRef.Scope = this.Target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = module.AssemblyReferences.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if(module.AssemblyReferences[i].Name.Equals(this.AssemblyName))
|
||||
{
|
||||
module.AssemblyReferences.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
this.Flags.Add(InstructionHandleResult.Rewritten);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Handle(ModuleDefinition module, TypeReference type, Action<TypeReference> replaceWith)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Handle(ModuleDefinition module, ILProcessor cil, Instruction instruction)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,26 +53,14 @@ namespace StardewModdingAPI.Metadata
|
|||
yield return new FieldReplaceRewriter()
|
||||
.AddField(typeof(DecoratableLocation), "furniture", typeof(GameLocation), nameof(GameLocation.furniture))
|
||||
.AddField(typeof(Farm), "resourceClumps", typeof(GameLocation), nameof(GameLocation.resourceClumps))
|
||||
#if SMAPI_FOR_MOBILE
|
||||
.AddField(typeof(ItemGrabMenu), "context", typeof(ItemGrabMenu), "specialObject")
|
||||
#endif
|
||||
.AddField(typeof(MineShaft), "resourceClumps", typeof(GameLocation), nameof(GameLocation.resourceClumps));
|
||||
|
||||
#if SMAPI_FOR_MOBILE
|
||||
#if SMAPI_LEGACY_PATCH
|
||||
// Redirect reference
|
||||
yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(Game1), typeof(Game1Methods), "isRaining", nameof(Game1Methods.IsRainingProp));
|
||||
#if !ANDROID_TARGET_MOBILE_LEGACY
|
||||
yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(Game1), typeof(Game1Methods), "isSnowing", nameof(Game1Methods.IsSnowingProp));
|
||||
#endif
|
||||
yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(Game1), typeof(Game1Methods), "isDebrisWeather", nameof(Game1Methods.IsDebrisWeatherProp));
|
||||
yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(Game1), typeof(Game1Methods), "rainDrops", nameof(Game1Methods.RainDropsProp));
|
||||
// module rewrite for .Net 5 runtime assemblies
|
||||
yield return new ModuleReferenceRewriter("System.Collections", "System.Collections", typeof(System.Collections.CollectionBase).Assembly);
|
||||
yield return new ModuleReferenceRewriter("System.Runtime", "System.Runtime", typeof(System.Collections.CollectionBase).Assembly);
|
||||
|
||||
// yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(Game1), typeof(WeatherDebrisManager), "debrisWeather","weatherDebrisList", "Instance");
|
||||
#endif
|
||||
yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(Game1), typeof(Game1Methods), "onScreenMenus", "onScreenMenus");
|
||||
yield return new PropertyToFieldRewriter(typeof(Game1), "toolSpriteSheet", "toolSpriteSheet");
|
||||
// yield return new TypeFieldToAnotherTypeFieldRewriter(typeof(GameLocation), typeof(DebrisManager), "debris", this.Monitor, "debrisNetCollection");
|
||||
|
||||
// Menu fix
|
||||
yield return new TypeFieldToAnotherTypePropertyRewriter(typeof(MenuWithInventory), typeof(MenuWithInventoryMethods), "trashCan", nameof(MenuWithInventoryMethods.TrashCanProp));
|
||||
|
|
|
@ -4,3 +4,7 @@ using System.Runtime.CompilerServices;
|
|||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // Moq for unit testing
|
||||
[assembly: InternalsVisibleTo("ContentPatcher")]
|
||||
[assembly: InternalsVisibleTo("ErrorHandler")]
|
||||
#if SMAPI_FOR_MOBILE
|
||||
[assembly: InternalsVisibleTo("VirtualKeyboard")]
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue