1.VirtualKeyboard Mod

2.Dll Rewrite improve
3.Mod hook solution
4.Mod code rewrite
This commit is contained in:
yangzhi 2019-04-24 02:18:25 +08:00
parent fa62d719d5
commit b62fdf88e6
125 changed files with 3947 additions and 342 deletions

View File

@ -27,13 +27,14 @@ namespace DllRewrite
this.StardewValley = this.resolver.Resolve(new AssemblyNameReference("StardewValley", new Version("1.3.0.0")));
this.StardewModdingAPI = this.resolver.Resolve(new AssemblyNameReference("StardewModdingAPI", new Version("0.0.0.0")));
}
public void InsertModHook(string name, TypeReference[] paraTypes, TypeReference returnType)
public void InsertModHook(string name, TypeReference[] paraTypes, string[] paraNames, TypeReference returnType)
{
TypeDefinition typeModHooksObject = this.StardewValley.MainModule.GetType("StardewValley.ModHooks");
var hook = new MethodDefinition(name, MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.NewSlot | MethodAttributes.HideBySig, returnType);
foreach (TypeReference typeReference in paraTypes)
for(int i = 0; i< paraTypes.Length; i++)
{
hook.Parameters.Add(new ParameterDefinition(typeReference));
ParameterDefinition define = new ParameterDefinition(paraNames[i], ParameterAttributes.None, paraTypes[i]);
hook.Parameters.Add(define);
}
switch (returnType.FullName)
{
@ -111,6 +112,56 @@ namespace DllRewrite
instructions.Add(processor.Create(OpCodes.Stsfld, this.GetFieldReference("hooks", "StardewValley.Game1", this.StardewValley)));
this.InsertInstructions(processor, jointPoint, instructions);
// isRaining and isDebrisWeather
PropertyDefinition propertyDefinition = new PropertyDefinition("isRaining", PropertyAttributes.None, this.GetTypeReference("System.Boolean"));
propertyDefinition.GetMethod = new MethodDefinition("get_isRaining", MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.SpecialName | MethodAttributes.Static | MethodAttributes.HideBySig, this.GetTypeReference("System.Boolean"));
propertyDefinition.GetMethod.SemanticsAttributes = MethodSemanticsAttributes.Getter;
processor = propertyDefinition.GetMethod.Body.GetILProcessor();
TypeDefinition typeRainManager = this.StardewValley.MainModule.GetType("StardewValley.RainManager");
MethodDefinition getMethod = typeRainManager.Methods.FirstOrDefault(m => m.Name == "get_Instance");
processor.Emit(OpCodes.Callvirt, getMethod);
FieldReference isRainingField = this.GetFieldReference("isRaining", "StardewValley.RainManager", this.StardewValley);
processor.Emit(OpCodes.Ldfld, isRainingField);
processor.Emit(OpCodes.Ret);
typeGame1.Methods.Add(propertyDefinition.GetMethod);
typeGame1.Properties.Add(propertyDefinition);
propertyDefinition = new PropertyDefinition("isDebrisWeather", PropertyAttributes.None, this.GetTypeReference("System.Boolean"));
propertyDefinition.GetMethod = new MethodDefinition("get_isDebrisWeather", MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.SpecialName | MethodAttributes.Static | MethodAttributes.HideBySig, this.GetTypeReference("System.Boolean"));
propertyDefinition.GetMethod.SemanticsAttributes = MethodSemanticsAttributes.Getter;
processor = propertyDefinition.GetMethod.Body.GetILProcessor();
TypeDefinition typeWeatherDebrisManager = this.StardewValley.MainModule.GetType("StardewValley.WeatherDebrisManager");
getMethod = typeWeatherDebrisManager.Methods.FirstOrDefault(m => m.Name == "get_Instance");
processor.Emit(OpCodes.Callvirt, getMethod);
FieldReference isDebrisWeatherField = this.GetFieldReference("isDebrisWeather", "StardewValley.WeatherDebrisManager", this.StardewValley);
processor.Emit(OpCodes.Ldfld, isDebrisWeatherField);
processor.Emit(OpCodes.Ret);
typeGame1.Methods.Add(propertyDefinition.GetMethod);
typeGame1.Properties.Add(propertyDefinition);
//HUDMessage..ctor
TypeDefinition typeHUDMessage = this.StardewValley.MainModule.GetType("StardewValley.HUDMessage");
MethodDefinition hudConstructor = new MethodDefinition(".ctor", MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.HideBySig, this.GetTypeReference("System.Void"));
hudConstructor.Parameters.Add(new ParameterDefinition(this.GetTypeReference("System.String")));
hudConstructor.Parameters.Add(new ParameterDefinition(this.GetTypeReference("System.Int32")));
processor = hudConstructor.Body.GetILProcessor();
processor.Emit(OpCodes.Ldarg_0);
processor.Emit(OpCodes.Ldarg_1);
processor.Emit(OpCodes.Ldarg_2);
processor.Emit(OpCodes.Ldc_I4_M1);
MethodDefinition targetConstructor = typeHUDMessage.Methods.FirstOrDefault(item => {
if(item.Parameters.Count == 3 && item.Parameters[0].ParameterType.FullName == "System.String"
&& item.Parameters[1].ParameterType.FullName == "System.Int32" && item.Parameters[1].ParameterType.FullName == "System.Int32")
{
return true;
}
return false;
});
processor.Emit(OpCodes.Call, targetConstructor);
processor.Emit(OpCodes.Ret);
typeHUDMessage.Methods.Add(hudConstructor);
// Back Button Fix
MethodDefinition method = typeGame1.Methods.FirstOrDefault(m => m.Name == "_updateAndroidMenus");
processor = method.Body.GetILProcessor();
@ -120,6 +171,153 @@ namespace DllRewrite
var GetGamePadState = typeInputState.Methods.FirstOrDefault(m => m.Name == "GetGamePadState");
processor.Replace(method.Body.Instructions[1], processor.Create(OpCodes.Callvirt, GetGamePadState));
}
public void ApplyCommonHookEntry(TypeDefinition targetType, string methodname, string hookname, bool patchPrefix = true, bool patchPostfix = true, Func<MethodDefinition, bool> methodFilter = null)
{
string qualifyName = $"{targetType.FullName}.{methodname}";
TypeDefinition typeModHooksObject = this.StardewValley.MainModule.GetType("StardewValley.ModHooks");
var targetMethod = targetType.Methods.FirstOrDefault(method => (!method.IsConstructor && method.HasBody && method.Name == methodname && (methodFilter == null || methodFilter(method))));
var prefixHook = typeModHooksObject.Methods.FirstOrDefault(m => m.Name == hookname + "_Prefix");
var postfixHook = typeModHooksObject.Methods.FirstOrDefault(m => m.Name == hookname + "_Postfix");
var processor = targetMethod.Body.GetILProcessor();
FieldReference hooksField = this.GetFieldReference("hooks", "StardewValley.Game1", this.StardewValley);
Instruction jointPoint;
List<Instruction> instructions;
byte i, j;
// state
byte returnIndex = 0;
byte parameterIndexBegin = 0, parameterIndexEnd = 0;
byte parameterOffset = (targetMethod.IsStatic ? (byte)0 : (byte)1);
byte stateIndex = (byte)targetMethod.Body.Variables.Count;
targetMethod.Body.Variables.Add(new VariableDefinition(this.GetTypeReference("System.Boolean")));
if (targetMethod.ReturnType.FullName != "System.Void")
{
// return
returnIndex = (byte)targetMethod.Body.Variables.Count;
targetMethod.Body.Variables.Add(new VariableDefinition(this.GetTypeReference("System.Object")));
}
parameterIndexBegin = (byte)targetMethod.Body.Variables.Count;
for (i = 0; i < targetMethod.Parameters.Count; i++)
{
targetMethod.Body.Variables.Add(new VariableDefinition(this.GetTypeReference("System.Object")));
parameterIndexEnd = (byte)targetMethod.Body.Variables.Count;
}
if (patchPrefix && prefixHook != null)
{
instructions = new List<Instruction>();
jointPoint = targetMethod.Body.Instructions[0];
for (i = parameterOffset, j = parameterIndexBegin; i < targetMethod.Parameters.Count + parameterOffset; i++, j++)
{
instructions.Add(this._createLdargsInstruction(processor, i));
if(targetMethod.Parameters[i - parameterOffset].ParameterType.IsValueType)
{
instructions.Add(processor.Create(OpCodes.Box, targetMethod.Parameters[i - parameterOffset].ParameterType));
}
instructions.Add(this._createStlocInstruction(processor, j));
}
instructions.Add(processor.Create(OpCodes.Ldsfld, hooksField));
instructions.Add(processor.Create(OpCodes.Ldstr, qualifyName));
if (!targetMethod.IsStatic)
{
instructions.Add(processor.Create(OpCodes.Ldarg_0));
if (targetType.IsValueType)
instructions.Add(processor.Create(OpCodes.Box, targetType));
}
for (i = parameterOffset, j = parameterIndexBegin; i < targetMethod.Parameters.Count + parameterOffset; i++, j++)
{
instructions.Add(processor.Create(OpCodes.Ldloca_S, j));
}
for (; i < prefixHook.Parameters.Count - 2; i++)
{
instructions.Add(processor.Create(OpCodes.Ldloca_S, (byte)0));
}
instructions.Add(processor.Create(OpCodes.Ldloca_S, returnIndex));
instructions.Add(processor.Create(OpCodes.Callvirt, prefixHook));
instructions.Add(this._createStlocInstruction(processor, stateIndex));
for (i = parameterOffset, j = parameterIndexBegin; i < targetMethod.Parameters.Count + parameterOffset; i++, j++)
{
instructions.Add(this._createLdlocInstruction(processor, j));
if (targetMethod.Parameters[i - parameterOffset].ParameterType.IsValueType)
{
instructions.Add(processor.Create(OpCodes.Unbox_Any, targetMethod.Parameters[i - parameterOffset].ParameterType));
}
else
{
instructions.Add(processor.Create(OpCodes.Castclass, targetMethod.Parameters[i - parameterOffset].ParameterType));
}
instructions.Add(processor.Create(OpCodes.Starg_S, i));
}
instructions.Add(this._createLdlocInstruction(processor, stateIndex));
instructions.Add(processor.Create(OpCodes.Brtrue, jointPoint));
if (targetMethod.ReturnType.FullName != "System.Void") {
instructions.Add(this._createLdlocInstruction(processor, returnIndex));
if (targetMethod.ReturnType.IsValueType)
instructions.Add(processor.Create(OpCodes.Unbox_Any, targetMethod.ReturnType));
else
instructions.Add(processor.Create(OpCodes.Castclass, targetMethod.ReturnType));
}
instructions.Add(processor.Create(OpCodes.Ret));
this.InsertInstructions(processor, jointPoint, instructions);
}
if (patchPostfix && postfixHook != null)
{
instructions = new List<Instruction>();
jointPoint = targetMethod.Body.Instructions[targetMethod.Body.Instructions.Count - 1];
if (targetMethod.ReturnType.FullName != "System.Void")
{
instructions.Add(processor.Create(OpCodes.Box, targetMethod.ReturnType));
instructions.Add(this._createStlocInstruction(processor, returnIndex));
}
for (i = parameterOffset, j = parameterIndexBegin; i < targetMethod.Parameters.Count + parameterOffset; i++, j++)
{
instructions.Add(this._createLdargsInstruction(processor, i));
if (targetMethod.Parameters[i - parameterOffset].ParameterType.IsValueType)
{
instructions.Add(processor.Create(OpCodes.Box, targetMethod.Parameters[i - parameterOffset].ParameterType));
}
instructions.Add(this._createStlocInstruction(processor, j));
}
instructions.Add(processor.Create(OpCodes.Ldsfld, hooksField));
instructions.Add(processor.Create(OpCodes.Ldstr, qualifyName));
if (!targetMethod.IsStatic)
{
instructions.Add(processor.Create(OpCodes.Ldarg_0));
if (targetType.IsValueType)
instructions.Add(processor.Create(OpCodes.Box, targetType));
}
for (i = parameterOffset, j = parameterIndexBegin; i < targetMethod.Parameters.Count + parameterOffset; i++, j++)
{
instructions.Add(processor.Create(OpCodes.Ldloca_S, j));
}
for (; i < postfixHook.Parameters.Count - 3; i++)
{
instructions.Add(processor.Create(OpCodes.Ldloca_S, (byte)0));
}
if (targetMethod.ReturnType.FullName != "System.Void")
{
instructions.Add(processor.Create(OpCodes.Ldloca_S, stateIndex));
instructions.Add(processor.Create(OpCodes.Ldloca_S, returnIndex));
instructions.Add(processor.Create(OpCodes.Callvirt, postfixHook));
instructions.Add(this._createLdlocInstruction(processor, returnIndex));
if (targetMethod.ReturnType.IsValueType)
instructions.Add(processor.Create(OpCodes.Unbox_Any, targetMethod.ReturnType));
else
instructions.Add(processor.Create(OpCodes.Castclass, targetMethod.ReturnType));
}
else
{
instructions.Add(processor.Create(OpCodes.Ldloca_S, stateIndex));
instructions.Add(processor.Create(OpCodes.Ldloca_S, returnIndex));
instructions.Add(processor.Create(OpCodes.Callvirt, postfixHook));
}
this.InsertInstructions(processor, jointPoint, instructions);
for (int x = 0; x < targetMethod.Body.Instructions.Count - 1; x++)
{
Instruction origin = targetMethod.Body.Instructions[x];
_patchPostfixReturn(processor, instructions, origin);
}
}
}
public void ApplyHookEntry(TypeDefinition targetType, string methodname, string hookname, bool isPrefix)
{
TypeDefinition typeModHooksObject = this.StardewValley.MainModule.GetType("StardewValley.ModHooks");
@ -162,10 +360,7 @@ namespace DllRewrite
for(int i = 0; i < method.Body.Instructions.Count - 1; i++)
{
Instruction origin = method.Body.Instructions[i];
if (origin.OpCode == OpCodes.Ret)
{
processor.Replace(origin, processor.Create(OpCodes.Br, instructions[0]));
}
_patchPostfixReturn(processor, instructions, origin);
}
}
else
@ -204,6 +399,102 @@ namespace DllRewrite
}
}
private static void _patchPostfixReturn(ILProcessor processor, List<Instruction> instructions, Instruction origin)
{
if (origin.OpCode == OpCodes.Ret)
{
processor.Replace(origin, processor.Create(OpCodes.Br, instructions[0]));
}
else
{
if ((origin.OpCode == OpCodes.Br && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Br_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Br;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Brfalse && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Brfalse_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Brfalse;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Brtrue && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Brtrue_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Brtrue;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Beq && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Beq_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Beq;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Bge && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Bge_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Bge;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Bge_Un && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Bge_Un_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Bge_Un;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Bgt && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Bgt_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Bgt;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Bgt_Un && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Bgt_Un_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Bgt_Un;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Ble && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Ble_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Ble;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Ble_Un && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Ble_Un_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Ble_Un;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Blt && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Blt_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Blt;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Blt_Un && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Blt_Un_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Blt_Un;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Bne_Un && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Bne_Un_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Bne_Un;
origin.Operand = instructions[0];
}
else if ((origin.OpCode == OpCodes.Leave && ((Instruction)origin.Operand).OpCode == OpCodes.Ret)
|| (origin.OpCode == OpCodes.Leave_S && ((Instruction)origin.Operand).OpCode == OpCodes.Ret))
{
origin.OpCode = OpCodes.Leave;
origin.Operand = instructions[0];
}
}
}
private Instruction _createStlocInstruction(ILProcessor processor, byte index)
{
switch (index)
@ -262,55 +553,340 @@ namespace DllRewrite
public AssemblyDefinition InsertModHooks()
{
this.ApplyGamePatch();
TypeDefinition typeGame1 = this.StardewValley.MainModule.GetType("StardewValley.Game1");
this.InsertModHook("OnGame1_Update_Prefix", new TypeReference[] {
this.GetTypeReference("StardewValley.Game1", this.StardewValley),
this.GetTypeReference("Microsoft.Xna.Framework.GameTime", this.MonoGame_Framework)},
this.InsertModHook("OnCommonHook_Prefix", new TypeReference[] {
this.GetTypeReference("System.String"),
this.GetTypeReference("System.Object"),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object"))},
new string[] {
"hookName", "__instance",
"param1", "param2", "param3",
"param4", "__result"},
this.GetTypeReference("System.Boolean"));
this.ApplyHookEntry(typeGame1, "Update", "OnGame1_Update_Prefix", true);
this.InsertModHook("OnGame1_Update_Postfix", new TypeReference[] {
this.GetTypeReference("StardewValley.Game1", this.StardewValley),
this.GetTypeReference("Microsoft.Xna.Framework.GameTime", this.MonoGame_Framework)},
this.InsertModHook("OnCommonStaticHook_Prefix", new TypeReference[] {
this.GetTypeReference("System.String"),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object"))},
new string[] {
"hookName", "param1",
"param2", "param3", "param4",
"param5", "__result"},
this.GetTypeReference("System.Boolean"));
this.InsertModHook("OnCommonHook_Postfix", new TypeReference[] {
this.GetTypeReference("System.String"),
this.GetTypeReference("System.Object"),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Boolean")),
new ByReferenceType(this.GetTypeReference("System.Object"))},
new string[] {
"hookName", "__instance",
"param1", "param2", "param3",
"param4", "__state", "__result"},
this.GetTypeReference("System.Void"));
this.ApplyHookEntry(typeGame1, "Update", "OnGame1_Update_Postfix", false);
this.InsertModHook("OnCommonStaticHook_Postfix", new TypeReference[] {
this.GetTypeReference("System.String"),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Boolean")),
new ByReferenceType(this.GetTypeReference("System.Object"))},
new string[] {
"hookName", "param1",
"param2", "param3", "param4",
"param5", "__state", "__result"},
this.GetTypeReference("System.Void"));
this.InsertModHook("OnCommonHook10_Prefix", new TypeReference[] {
this.GetTypeReference("System.String"),
this.GetTypeReference("System.Object"),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object"))},
new string[] {
"hookName", "__instance",
"param1", "param2", "param3",
"param4", "param5", "param6",
"param7", "param8", "param9",
"__result"},
this.GetTypeReference("System.Boolean"));
this.InsertModHook("OnCommonStaticHook10_Prefix", new TypeReference[] {
this.GetTypeReference("System.String"),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object"))},
new string[] {
"hookName", "param1",
"param2", "param3", "param4",
"param5", "param6", "param7",
"param8", "param9", "param10",
"__result"},
this.GetTypeReference("System.Boolean"));
this.InsertModHook("OnCommonHook10_Postfix", new TypeReference[] {
this.GetTypeReference("System.String"),
this.GetTypeReference("System.Object"),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Boolean")),
new ByReferenceType(this.GetTypeReference("System.Object"))},
new string[] {
"hookName", "__instance",
"param1", "param2", "param3",
"param4", "param5", "param6",
"param7", "param8", "param9",
"__state", "__result"},
this.GetTypeReference("System.Void"));
this.InsertModHook("OnCommonStaticHook10_Postfix", new TypeReference[] {
this.GetTypeReference("System.String"),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Object")),
new ByReferenceType(this.GetTypeReference("System.Boolean")),
new ByReferenceType(this.GetTypeReference("System.Object"))},
new string[] {
"hookName", "param1",
"param2", "param3", "param4",
"param5", "param6", "param7",
"param8", "param9", "param10",
"__state", "__result"},
this.GetTypeReference("System.Void"));
// On Game1 hooks
TypeDefinition typeGame1 = this.StardewValley.MainModule.GetType("StardewValley.Game1");
this.ApplyCommonHookEntry(typeGame1, "Update", "OnCommonHook");
this.ApplyCommonHookEntry(typeGame1, "_draw", "OnCommonHook");
this.ApplyCommonHookEntry(typeGame1, "getSourceRectForStandardTileSheet", "OnCommonStaticHook");
this.ApplyCommonHookEntry(typeGame1, "tryToCheckAt", "OnCommonStaticHook");
this.ApplyCommonHookEntry(typeGame1, "getLocationRequest", "OnCommonStaticHook");
// On Object hooks
TypeDefinition typeObject = this.StardewValley.MainModule.GetType("StardewValley.Object");
this.ApplyCommonHookEntry(typeObject, "canBePlacedHere", "OnCommonHook", true, false);
this.ApplyCommonHookEntry(typeObject, "checkForAction", "OnCommonHook", true, false);
this.ApplyCommonHookEntry(typeObject, "isIndexOkForBasicShippedCategory", "OnCommonStaticHook");
// On ReadyCheckDialog hooks
TypeDefinition typeReadyCheckDialog = this.StardewValley.MainModule.GetType("StardewValley.Menus.ReadyCheckDialog");
this.ApplyCommonHookEntry(typeReadyCheckDialog, "update", "OnCommonHook");
// On Building hooks
TypeDefinition typeBuilding = this.StardewValley.MainModule.GetType("StardewValley.Buildings.Building");
this.ApplyCommonHookEntry(typeBuilding, "load", "OnCommonHook");
// On GameLocation hooks
TypeDefinition typeGameLocation = this.StardewValley.MainModule.GetType("StardewValley.GameLocation");
this.ApplyCommonHookEntry(typeGameLocation, "performTouchAction", "OnCommonHook");
this.ApplyCommonHookEntry(typeGameLocation, "isActionableTile", "OnCommonHook");
this.ApplyCommonHookEntry(typeGameLocation, "tryToAddCritters", "OnCommonHook");
this.ApplyCommonHookEntry(typeGameLocation, "getSourceRectForObject", "OnCommonStaticHook");
this.ApplyCommonHookEntry(typeGameLocation, "answerDialogue", "OnCommonHook");
this.ApplyCommonHookEntry(typeGameLocation, "Equals", "OnCommonHook", true, false, (method)=> method.Parameters[0].ParameterType == this.GetTypeReference("StardewValley.GameLocation", this.StardewValley));
// On Objects.TV hooks
TypeDefinition typeObjectsTV = this.StardewValley.MainModule.GetType("StardewValley.Objects.TV");
this.ApplyCommonHookEntry(typeObjectsTV, "checkForAction", "OnCommonHook");
//this.InsertModHook("OnGame1_Update_Prefix", new TypeReference[] {
// this.GetTypeReference("StardewValley.Game1", this.StardewValley),
// this.GetTypeReference("Microsoft.Xna.Framework.GameTime", this.MonoGame_Framework)},
// this.GetTypeReference("System.Boolean"));
//this.ApplyHookEntry(typeGame1, "Update", "OnGame1_Update_Prefix", true);
//this.InsertModHook("OnGame1_Update_Postfix", new TypeReference[] {
// this.GetTypeReference("StardewValley.Game1", this.StardewValley),
// this.GetTypeReference("Microsoft.Xna.Framework.GameTime", this.MonoGame_Framework)},
// this.GetTypeReference("System.Void"));
//this.ApplyHookEntry(typeGame1, "Update", "OnGame1_Update_Postfix", false);
this.InsertModHook("OnGame1_CreateContentManager_Prefix", new TypeReference[] {
this.GetTypeReference("StardewValley.Game1", this.StardewValley),
this.GetTypeReference("System.IServiceProvider"),
this.GetTypeReference("System.String"),
new ByReferenceType(this.GetTypeReference("StardewValley.LocalizedContentManager", this.StardewValley)) },
new string[] { "game1", "serviceProvider", "rootDirectory", "__result"},
this.GetTypeReference("System.Boolean"));
this.ApplyHookEntry(typeGame1, "CreateContentManager", "OnGame1_CreateContentManager_Prefix", true);
this.InsertModHook("OnGame1_Draw_Prefix", new TypeReference[] {
this.GetTypeReference("StardewValley.Game1", this.StardewValley),
this.GetTypeReference("Microsoft.Xna.Framework.GameTime", this.MonoGame_Framework)},
this.GetTypeReference("System.Boolean"));
this.ApplyHookEntry(typeGame1, "Draw", "OnGame1_Draw_Prefix", true);
//this.InsertModHook("OnGame1__draw_Prefix", new TypeReference[] {
// this.GetTypeReference("StardewValley.Game1", this.StardewValley),
// this.GetTypeReference("Microsoft.Xna.Framework.GameTime", this.MonoGame_Framework),
// this.GetTypeReference("Microsoft.Xna.Framework.Graphics.RenderTarget2D", this.MonoGame_Framework)},
// this.GetTypeReference("System.Boolean"));
//this.ApplyHookEntry(typeGame1, "_draw", "OnGame1__draw_Prefix", true);
//this.InsertModHook("OnGame1_getSourceRectForStandardTileSheet_Prefix", new TypeReference[] {
// this.GetTypeReference("Microsoft.Xna.Framework.Graphics.Texture2D", this.MonoGame_Framework),
// this.GetTypeReference("System.Int32"),
// this.GetTypeReference("System.Int32"),
// this.GetTypeReference("System.Int32"),
// new ByReferenceType(this.GetTypeReference("Microsoft.Xna.Framework.Rectangle", this.MonoGame_Framework)) },
// this.GetTypeReference("System.Boolean"));
//this.ApplyHookEntry(typeGame1, "getSourceRectForStandardTileSheet", "OnGame1_getSourceRectForStandardTileSheet_Prefix", true);
this.InsertModHook("OnObject_canBePlacedHere_Prefix", new TypeReference[] {
this.GetTypeReference("StardewValley.Object", this.StardewValley),
this.GetTypeReference("StardewValley.GameLocation", this.StardewValley),
this.GetTypeReference("Microsoft.Xna.Framework.Vector2", this.MonoGame_Framework),
new ByReferenceType(this.GetTypeReference("System.Boolean")) },
this.GetTypeReference("System.Boolean"));
TypeDefinition typeObject = this.StardewValley.MainModule.GetType("StardewValley.Object");
this.ApplyHookEntry(typeObject, "canBePlacedHere", "OnObject_canBePlacedHere_Prefix", true);
//this.InsertModHook("OnGame1_getSourceRectForStandardTileSheet_Postfix", new TypeReference[] {
// this.GetTypeReference("Microsoft.Xna.Framework.Graphics.Texture2D", this.MonoGame_Framework),
// this.GetTypeReference("System.Int32"),
// this.GetTypeReference("System.Int32"),
// this.GetTypeReference("System.Int32"),
// new ByReferenceType(this.GetTypeReference("Microsoft.Xna.Framework.Rectangle", this.MonoGame_Framework)) },
// this.GetTypeReference("System.Void"));
//this.ApplyHookEntry(typeGame1, "getSourceRectForStandardTileSheet", "OnGame1_getSourceRectForStandardTileSheet_Postfix", false);
this.InsertModHook("OnObject_checkForAction_Prefix", new TypeReference[] {
this.GetTypeReference("StardewValley.Object", this.StardewValley),
this.GetTypeReference("StardewValley.Farmer", this.StardewValley),
this.GetTypeReference("System.Boolean"),
new ByReferenceType(this.GetTypeReference("System.Boolean"))},
this.GetTypeReference("System.Boolean"));
this.ApplyHookEntry(typeObject, "checkForAction", "OnObject_checkForAction_Prefix", true);
//this.InsertModHook("OnGame1_tryToCheckAt_Postfix", new TypeReference[] {
// this.GetTypeReference("Microsoft.Xna.Framework.Vector2", this.MonoGame_Framework),
// this.GetTypeReference("StardewValley.Farmer", this.StardewValley),
// new ByReferenceType(this.GetTypeReference("System.Boolean")) },
// this.GetTypeReference("System.Void"));
//this.ApplyHookEntry(typeGame1, "tryToCheckAt", "OnGame1_tryToCheckAt_Postfix", false);
//this.InsertModHook("OnGame1_getLocationRequest_Prefix", new TypeReference[] {
// this.GetTypeReference("System.String"),
// this.GetTypeReference("System.Boolean"),
// new ByReferenceType(this.GetTypeReference("StardewValley.LocationRequest", this.StardewValley)) },
// this.GetTypeReference("System.Boolean"));
//this.ApplyHookEntry(typeGame1, "getLocationRequest", "OnGame1_getLocationRequest_Prefix", true);
//// On Object hooks
//this.InsertModHook("OnObject_canBePlacedHere_Prefix", new TypeReference[] {
// this.GetTypeReference("StardewValley.Object", this.StardewValley),
// this.GetTypeReference("StardewValley.GameLocation", this.StardewValley),
// this.GetTypeReference("Microsoft.Xna.Framework.Vector2", this.MonoGame_Framework),
// new ByReferenceType(this.GetTypeReference("System.Boolean")) },
// this.GetTypeReference("System.Boolean"));
//TypeDefinition typeObject = this.StardewValley.MainModule.GetType("StardewValley.Object");
//this.ApplyHookEntry(typeObject, "canBePlacedHere", "OnObject_canBePlacedHere_Prefix", true);
//this.InsertModHook("OnObject_checkForAction_Prefix", new TypeReference[] {
// this.GetTypeReference("StardewValley.Object", this.StardewValley),
// this.GetTypeReference("StardewValley.Farmer", this.StardewValley),
// this.GetTypeReference("System.Boolean"),
// new ByReferenceType(this.GetTypeReference("System.Boolean"))},
// this.GetTypeReference("System.Boolean"));
//this.ApplyHookEntry(typeObject, "checkForAction", "OnObject_checkForAction_Prefix", true);
//this.InsertModHook("OnObject_isIndexOkForBasicShippedCategory_Postfix", new TypeReference[] {
// this.GetTypeReference("System.Int32"),
// new ByReferenceType(this.GetTypeReference("System.Boolean")) },
// this.GetTypeReference("System.Void"));
//this.ApplyHookEntry(typeObject, "isIndexOkForBasicShippedCategory", "OnObject_isIndexOkForBasicShippedCategory_Postfix", false);
//// On ReadyCheckDialog hooks
//this.InsertModHook("OnReadyCheckDialog_update_Postfix", new TypeReference[] {
// this.GetTypeReference("StardewValley.Menus.ReadyCheckDialog", this.StardewValley),
// this.GetTypeReference("Microsoft.Xna.Framework.GameTime", this.MonoGame_Framework)},
// this.GetTypeReference("System.Void"));
//TypeDefinition typeReadyCheckDialog = this.StardewValley.MainModule.GetType("StardewValley.Menus.ReadyCheckDialog");
//this.ApplyHookEntry(typeReadyCheckDialog, "update", "OnReadyCheckDialog_update_Postfix", false);
//// On Building hooks
//this.InsertModHook("OnBuilding_load_Prefix", new TypeReference[] {
// this.GetTypeReference("StardewValley.Buildings.Building", this.StardewValley)},
// this.GetTypeReference("System.Boolean"));
//TypeDefinition typeBuilding = this.StardewValley.MainModule.GetType("StardewValley.Buildings.Building");
//this.ApplyHookEntry(typeBuilding, "load", "OnBuilding_load_Prefix", true);
//// On GameLocation hooks
//this.InsertModHook("OnGameLocation_performTouchAction_Postfix", new TypeReference[] {
// this.GetTypeReference("StardewValley.GameLocation", this.StardewValley),
// this.GetTypeReference("System.String"),
// this.GetTypeReference("Microsoft.Xna.Framework.Vector2", this.MonoGame_Framework)},
// this.GetTypeReference("System.Void"));
//TypeDefinition typeGameLocation = this.StardewValley.MainModule.GetType("StardewValley.GameLocation");
//this.ApplyHookEntry(typeGameLocation, "performTouchAction", "OnGameLocation_performTouchAction_Postfix", false);
//this.InsertModHook("OnGameLocation_isActionableTile_Postfix", new TypeReference[] {
// this.GetTypeReference("StardewValley.GameLocation", this.StardewValley),
// this.GetTypeReference("System.Int32"),
// this.GetTypeReference("System.Int32"),
// this.GetTypeReference("StardewValley.Farmer", this.StardewValley),
// new ByReferenceType(this.GetTypeReference("System.Boolean"))},
// this.GetTypeReference("System.Void"));
//this.ApplyHookEntry(typeGameLocation, "isActionableTile", "OnGameLocation_isActionableTile_Postfix", false);
//this.InsertModHook("OnGameLocation_tryToAddCritters_Prefix", new TypeReference[] {
// this.GetTypeReference("StardewValley.GameLocation", this.StardewValley),
// this.GetTypeReference("System.Boolean")},
// this.GetTypeReference("System.Boolean"));
//this.ApplyHookEntry(typeGameLocation, "tryToAddCritters", "OnGameLocation_tryToAddCritters_Prefix", true);
//this.InsertModHook("OnGameLocation_getSourceRectForObject_Prefix", new TypeReference[] {
// this.GetTypeReference("System.Int32"),
// new ByReferenceType(this.GetTypeReference("Microsoft.Xna.Framework.Rectangle", this.MonoGame_Framework)) },
// this.GetTypeReference("System.Boolean"));
//this.ApplyHookEntry(typeGameLocation, "getSourceRectForObject", "OnGameLocation_getSourceRectForObject_Prefix", true);
//this.InsertModHook("OnGameLocation_getSourceRectForObject_Postfix", new TypeReference[] {
// this.GetTypeReference("System.Int32"),
// new ByReferenceType(this.GetTypeReference("Microsoft.Xna.Framework.Rectangle", this.MonoGame_Framework)) },
// this.GetTypeReference("System.Void"));
//this.ApplyHookEntry(typeGameLocation, "getSourceRectForObject", "OnGameLocation_getSourceRectForObject_Postfix", false);
//this.InsertModHook("OnGameLocation_answerDialogue_Prefix", new TypeReference[] {
// this.GetTypeReference("StardewValley.GameLocation", this.StardewValley),
// this.GetTypeReference("StardewValley.Response", this.StardewValley),
// new ByReferenceType(this.GetTypeReference("System.Boolean"))},
// this.GetTypeReference("System.Boolean"));
//this.ApplyHookEntry(typeGameLocation, "answerDialogue", "OnGameLocation_answerDialogue_Prefix", true);
//// On Objects.TV hooks
//this.InsertModHook("OnObjectsTV_checkForAction_Prefix", new TypeReference[] {
// this.GetTypeReference("StardewValley.Objects.TV", this.StardewValley),
// this.GetTypeReference("StardewValley.Farmer", this.StardewValley),
// this.GetTypeReference("System.Boolean"),
// new ByReferenceType(this.GetTypeReference("System.Boolean"))},
// this.GetTypeReference("System.Boolean"));
//TypeDefinition typeObjectsTV = this.StardewValley.MainModule.GetType("StardewValley.Objects.TV");
//this.ApplyHookEntry(typeObjectsTV, "checkForAction", "OnObjectsTV_checkForAction_Prefix", true);
//this.InsertModHook("OnObjectsTV_checkForAction_Postfix", new TypeReference[] {
// this.GetTypeReference("StardewValley.Objects.TV", this.StardewValley),
// this.GetTypeReference("StardewValley.Farmer", this.StardewValley),
// this.GetTypeReference("System.Boolean"),
// new ByReferenceType(this.GetTypeReference("System.Boolean"))},
// this.GetTypeReference("System.Void"));
//this.ApplyHookEntry(typeObjectsTV, "checkForAction", "OnObjectsTV_checkForAction_Postfix", false);
this.InsertModHook("OnObject_isIndexOkForBasicShippedCategory_Postfix", new TypeReference[] {
this.GetTypeReference("System.Int32"),
new ByReferenceType(this.GetTypeReference("System.Boolean")) },
this.GetTypeReference("System.Void"));
this.ApplyHookEntry(typeObject, "isIndexOkForBasicShippedCategory", "OnObject_isIndexOkForBasicShippedCategory_Postfix", false);
return this.StardewValley;
}

View File

@ -0,0 +1,144 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
using StardewValley.Menus;
using static VirtualKeyboad.ModConfig;
namespace VirtualKeyboad
{
class KeyButton
{
private readonly IModHelper helper;
private readonly Rectangle buttonRectangle;
private readonly int padding;
private readonly IReflectedMethod RaiseButtonPressed;
private readonly IReflectedMethod RaiseButtonReleased;
private readonly IReflectedMethod Legacy_KeyPressed;
private readonly IReflectedMethod Legacy_KeyReleased;
private readonly SButton button;
private readonly float transparency;
private readonly bool autoHidden;
private bool raisingPressed = false;
private bool raisingReleased = false;
public KeyButton(IModHelper helper, Button buttonDefine)
{
this.helper = helper;
this.buttonRectangle = new Rectangle(buttonDefine.rectangle.X, buttonDefine.rectangle.Y, buttonDefine.rectangle.Width, buttonDefine.rectangle.Height);
this.padding = buttonDefine.rectangle.Padding;
this.button = buttonDefine.key;
this.autoHidden = buttonDefine.autoHidden;
if (buttonDefine.transparency <= 0.01f || buttonDefine.transparency > 1f)
{
buttonDefine.transparency = 0.5f;
}
this.transparency = buttonDefine.transparency;
helper.Events.Display.RenderingHud += this.OnRenderingHud;
helper.Events.Input.ButtonReleased += this.Input_ButtonReleased;
helper.Events.Input.ButtonPressed += this.Input_ButtonPressed;
SMDroid.ModEntry entry = helper.Reflection.GetField<SMDroid.ModEntry>(typeof(Game1), "hooks").GetValue();
object score = helper.Reflection.GetField<object>(entry, "core").GetValue();
object eventManager = helper.Reflection.GetField<object>(score, "EventManager").GetValue();
object buttonPressed = helper.Reflection.GetField<object>(eventManager, "ButtonPressed").GetValue();
object buttonReleased = helper.Reflection.GetField<object>(eventManager, "ButtonReleased").GetValue();
this.RaiseButtonPressed = helper.Reflection.GetMethod(buttonPressed, "Raise");
this.RaiseButtonReleased = helper.Reflection.GetMethod(buttonReleased, "Raise");
object legacyButtonPressed = helper.Reflection.GetField<object>(eventManager, "Legacy_KeyPressed").GetValue();
object legacyButtonReleased = helper.Reflection.GetField<object>(eventManager, "Legacy_KeyReleased").GetValue();
this.Legacy_KeyPressed = helper.Reflection.GetMethod(legacyButtonPressed, "Raise");
this.Legacy_KeyReleased = helper.Reflection.GetMethod(legacyButtonReleased, "Raise");
}
private bool shouldTrigger(Vector2 point)
{
if (this.autoHidden && Game1.activeClickableMenu != null)
{
return false;
}
if (!this.buttonRectangle.Contains(point.X * Game1.options.zoomLevel, point.Y * Game1.options.zoomLevel))
{
return false;
}
//if (Game1.activeClickableMenu != null && !this.buttonRectangle.Contains(point.X, point.Y))
//{
// return false;
//}
return true;
}
private void Input_ButtonPressed(object sender, ButtonPressedEventArgs e)
{
if (this.raisingPressed)
{
return;
}
Vector2 point = e.Cursor.ScreenPixels;
if (this.shouldTrigger(point)){
object inputState = this.helper.Reflection.GetField<object>(e, "InputState").GetValue();
object buttonPressedEventArgs = Activator.CreateInstance(typeof(ButtonPressedEventArgs), BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { this.button, e.Cursor, inputState }, null);
EventArgsKeyPressed eventArgsKeyPressed = new EventArgsKeyPressed((Keys)this.button);
try
{
this.raisingPressed = true;
this.RaiseButtonPressed.Invoke(new object[] { buttonPressedEventArgs });
this.Legacy_KeyPressed.Invoke(new object[] { eventArgsKeyPressed });
}
finally
{
this.raisingPressed = false;
}
}
}
private void Input_ButtonReleased(object sender, ButtonReleasedEventArgs e)
{
if (this.raisingReleased)
{
return;
}
Vector2 point = e.Cursor.ScreenPixels;
if (this.shouldTrigger(point))
{
object inputState = this.helper.Reflection.GetField<object>(e, "InputState").GetValue();
object buttonReleasedEventArgs = Activator.CreateInstance(typeof(ButtonReleasedEventArgs), BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { this.button, e.Cursor, inputState }, null);
EventArgsKeyPressed eventArgsKeyReleased = new EventArgsKeyPressed((Keys)this.button);
try
{
this.raisingReleased = true;
this.RaiseButtonReleased.Invoke(new object[] { buttonReleasedEventArgs });
this.Legacy_KeyReleased.Invoke(new object[] { eventArgsKeyReleased });
}
finally
{
this.raisingReleased = false;
}
}
}
/// <summary>Raised before drawing the HUD (item toolbar, clock, etc) to the screen.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
private void OnRenderingHud(object sender, EventArgs e)
{
if (!Game1.eventUp && (!this.autoHidden || (this.autoHidden && Game1.activeClickableMenu == null)))
{
Game1.spriteBatch.Draw(Game1.staminaRect, this.buttonRectangle, Color.LightGray * this.transparency);
Rectangle shrinkRectangle = new Rectangle(this.buttonRectangle.X + this.padding, this.buttonRectangle.Y + this.padding, this.buttonRectangle.Width - 2 * this.padding, this.buttonRectangle.Height - 2 * this.padding);
Game1.spriteBatch.Draw(Game1.staminaRect, shrinkRectangle, Color.DarkGray * this.transparency * 0.5f);
Game1.spriteBatch.DrawString(Game1.dialogueFont, this.button.ToString(), new Vector2(this.buttonRectangle.X + 8, this.buttonRectangle.Y + 8), Color.White * this.transparency);
}
}
}
}

View File

@ -0,0 +1,45 @@
using Microsoft.Xna.Framework;
using StardewModdingAPI;
namespace VirtualKeyboad
{
class ModConfig
{
public Button[] buttons { get; set;} = new Button[] {
new Button(SButton.Q, new Rect(192, 64, 90, 90, 6), 0.5f, true),
new Button(SButton.I, new Rect(288, 64, 90, 90, 6), 0.5f, true),
new Button(SButton.O, new Rect(384, 64, 90, 90, 6), 0.5f, true),
new Button(SButton.P, new Rect(480, 64, 90, 90, 6), 0.5f, true)
};
internal class Button {
public SButton key;
public Rect rectangle;
public bool autoHidden;
public float transparency;
public Button(SButton key, Rect rectangle, float transparency, bool autoHidden)
{
this.key = key;
this.rectangle = rectangle;
this.transparency = transparency;
this.autoHidden = autoHidden;
}
}
internal class Rect
{
public int X;
public int Y;
public int Width;
public int Height;
public int Padding;
public Rect(int x, int y, int width, int height, int padding)
{
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
this.Padding = padding;
}
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StardewModdingAPI;
namespace VirtualKeyboad
{
class ModEntry : Mod
{
private List<KeyButton> keyboard = new List<KeyButton>();
private ModConfig modConfig;
public override void Entry(IModHelper helper)
{
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]));
}
helper.WriteConfig(this.modConfig);
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("VirtualKeyboad")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VirtualKeyboad")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("7a7bdd05-433a-4297-afec-131e35123026")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,163 @@
<?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')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7A7BDD05-433A-4297-AFEC-131E35123026}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VirtualKeyboad</RootNamespace>
<AssemblyName>VirtualKeyboad</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="StardewModdingAPI">
<HintPath>..\assemblies\StardewModdingAPI.dll</HintPath>
</Reference>
<Reference Include="StardewValley">
<HintPath>..\assemblies\StardewValley.dll</HintPath>
</Reference>
<Reference Include="BmFont, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\BmFont.dll</HintPath>
</Reference>
<Reference Include="Google.Android.Vending.Expansion.Downloader, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Google.Android.Vending.Expansion.Downloader.dll</HintPath>
</Reference>
<Reference Include="Google.Android.Vending.Expansion.ZipFile, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Google.Android.Vending.Expansion.ZipFile.dll</HintPath>
</Reference>
<Reference Include="Google.Android.Vending.Licensing, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Google.Android.Vending.Licensing.dll</HintPath>
</Reference>
<Reference Include="Java.Interop, Version=0.1.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Java.Interop.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AppCenter, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Microsoft.AppCenter.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AppCenter.Analytics, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Microsoft.AppCenter.Analytics.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AppCenter.Analytics.Android.Bindings, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Microsoft.AppCenter.Analytics.Android.Bindings.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AppCenter.Android.Bindings, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Microsoft.AppCenter.Android.Bindings.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AppCenter.Crashes, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Microsoft.AppCenter.Crashes.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AppCenter.Crashes.Android.Bindings, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Microsoft.AppCenter.Crashes.Android.Bindings.dll</HintPath>
</Reference>
<Reference Include="Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Mono.Android.dll</HintPath>
</Reference>
<Reference Include="Mono.Security, Version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Mono.Security.dll</HintPath>
</Reference>
<Reference Include="MonoGame.Framework, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\MonoGame.Framework.dll</HintPath>
</Reference>
<Reference Include="mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
<HintPath>..\assemblies\mscorlib.dll</HintPath>
</Reference>
<Reference Include="System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
<HintPath>..\assemblies\System.dll</HintPath>
</Reference>
<Reference Include="System.Xml, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
<HintPath>..\assemblies\System.Xml.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<HintPath>..\assemblies\System.Net.Http.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
<HintPath>..\assemblies\System.Runtime.Serialization.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Android.Arch.Core.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Xamarin.Android.Arch.Core.Common.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Android.Arch.Lifecycle.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Xamarin.Android.Arch.Lifecycle.Common.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Android.Arch.Lifecycle.Runtime, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Xamarin.Android.Arch.Lifecycle.Runtime.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Android.Support.Annotations, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Xamarin.Android.Support.Annotations.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Android.Support.Compat, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Xamarin.Android.Support.Compat.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Android.Support.Core.UI, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Xamarin.Android.Support.Core.UI.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Android.Support.Core.Utils, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Xamarin.Android.Support.Core.Utils.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Android.Support.Fragment, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Xamarin.Android.Support.Fragment.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Android.Support.Media.Compat, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Xamarin.Android.Support.Media.Compat.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Android.Support.v4, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\Xamarin.Android.Support.v4.dll</HintPath>
</Reference>
<Reference Include="xTile, Version=1.0.7033.16602, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\assemblies\xTile.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="KeyButton.cs" />
<Compile Include="ModConfig.cs" />
<Compile Include="ModEntry.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,10 @@
{
"Name": "VirtualKeyboard",
"Author": "ZaneYork",
"Version": "1.0.1",
"MinimumApiVersion": "2.10.1",
"Description": "Virtual keyboard for mods",
"UniqueID": "VirtualKeyboad",
"EntryDll": "VirtualKeyboad.dll",
"UpdateKeys": [ "Nexus: null" ]
}

View File

@ -5,6 +5,9 @@ using StardewModdingAPI.Framework;
using System.Threading;
using Microsoft.Xna.Framework.Graphics;
using System.IO;
using StardewValley.Menus;
using StardewValley.Buildings;
using StardewValley.Objects;
namespace SMDroid
{
@ -22,7 +25,7 @@ namespace SMDroid
{
this.core = new SCore(Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, "SMDroid/Mods"), false);
}
public override bool OnGame1_CreateContentManager_Prefix(Game1 _, IServiceProvider serviceProvider, string rootDirectory, ref LocalizedContentManager __result)
public override bool OnGame1_CreateContentManager_Prefix(Game1 game1, IServiceProvider serviceProvider, string rootDirectory, ref LocalizedContentManager __result)
{
// Game1._temporaryContent initialising from SGame constructor
// NOTE: this method is called before the SGame constructor runs. Don't depend on anything being initialised at this point.
@ -30,48 +33,58 @@ namespace SMDroid
{
this.ContentCore = new ContentCoordinator(serviceProvider, rootDirectory, Thread.CurrentThread.CurrentUICulture, SGame.ConstructorHack.Monitor, SGame.ConstructorHack.Reflection, SGame.ConstructorHack.JsonHelper, SGame.OnLoadingFirstAsset ?? SGame.ConstructorHack?.OnLoadingFirstAsset);
this.NextContentManagerIsMain = true;
this.core.RunInteractively(this.ContentCore);
__result = this.ContentCore.CreateGameContentManager("Game1._temporaryContent");
this.core.RunInteractively(this.ContentCore);
return false;
}
// Game1.content initialising from LoadContent
if (this.NextContentManagerIsMain)
{
this.NextContentManagerIsMain = false;
__result = this.ContentCore.MainContentManager;
return false;
}
// any other content manager
__result = this.ContentCore.CreateGameContentManager("(generated)");
return false;
}
public override bool OnGame1_Update_Prefix(Game1 _, GameTime time)
public override bool OnCommonHook_Prefix(string hookName, object __instance, ref object param1, ref object param2, ref object param3, ref object param4, ref object __result)
{
return this.core.GameInstance.Update(time);
switch (hookName)
{
case "StardewValley.Game1.Update":
return this.core.GameInstance.Update(param1 as GameTime);
case "StardewValley.Game1._draw":
return this.core.GameInstance.Draw(param1 as GameTime, param2 as RenderTarget2D);
default:
return this.core.GameInstance.OnCommonHook_Prefix(hookName, __instance, ref param1, ref param2, ref param3, ref param4, ref __result);
}
}
public override void OnGame1_Update_Postfix(Game1 _, GameTime time)
public override void OnCommonHook_Postfix(string hookName, object __instance, ref object param1, ref object param2, ref object param3, ref object param4, ref bool __state, ref object __result)
{
this.core.GameInstance.Update_Postfix(time);
switch (hookName)
{
case "StardewValley.Game1.Update":
this.core.GameInstance.Update_Postfix(param1 as GameTime);
return;
default:
this.core.GameInstance.OnCommonHook_Postfix(hookName, __instance, ref param1, ref param2, ref param3, ref param4, ref __state, ref __result);
return;
}
}
public override bool OnGame1_Draw_Prefix(Game1 _, GameTime time)
public override bool OnCommonStaticHook_Prefix(string hookName, ref object param1, ref object param2, ref object param3, ref object param4, ref object param5, ref object __result)
{
return this.core.GameInstance.Draw(time);
return this.core.GameInstance.OnCommonStaticHook_Prefix(hookName, ref param1, ref param2, ref param3, ref param4, ref param5, ref __result);
}
public override void OnCommonStaticHook_Postfix(string hookName, ref object param1, ref object param2, ref object param3, ref object param4, ref object param5, ref bool __state, ref object __result)
{
this.core.GameInstance.OnCommonStaticHook_Postfix(hookName, ref param1, ref param2, ref param3, ref param4, ref param5, ref __state, ref __result);
}
public override void OnGame1_NewDayAfterFade(Action action)
{
this.core.GameInstance.OnNewDayAfterFade();
base.OnGame1_NewDayAfterFade(action);
}
public override bool OnObject_canBePlacedHere_Prefix(StardewValley.Object __instance, GameLocation location, Vector2 tile, ref bool __result)
{
return this.core.GameInstance.OnObjectCanBePlacedHere(__instance, location, tile, ref __result);
}
public override void OnObject_isIndexOkForBasicShippedCategory_Postfix(int index, ref bool __result)
{
this.core.GameInstance.OnObjectIsIndexOkForBasicShippedCategory(index, ref __result);
}
public override bool OnObject_checkForAction_Prefix(StardewValley.Object __instance, Farmer value, bool justCheckingForActivity, ref bool __result)
{
return this.core.GameInstance.OnObjectCheckForAction(__instance);
}
}
}

View File

@ -166,17 +166,23 @@ namespace StardewModdingAPI
case Platform.Android:
removeAssemblyReferences = new[]
{
"Netcode",
"StardewValley",
"Stardew Valley",
"Microsoft.Xna.Framework",
"Microsoft.Xna.Framework.Game",
"Microsoft.Xna.Framework.Graphics",
"Microsoft.Xna.Framework.Xact"
"Microsoft.Xna.Framework.Xact",
"Newtonsoft.Json",
"StardewModdingAPI.Toolkit.CoreInterfaces"
};
targetAssemblies = new[]
{
typeof(StardewValley.Game1).Assembly,
typeof(Microsoft.Xna.Framework.Vector2).Assembly
typeof(Constants).Assembly,
typeof(Microsoft.Xna.Framework.Vector2).Assembly,
typeof(System.Xml.XmlWriter).Assembly,
typeof(System.Xml.Linq.XElement).Assembly
};
break;
default:

View File

@ -0,0 +1,120 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised during the game's draw loop, when the game is rendering content to the window.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class GraphicsEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after the game window is resized.</summary>
public static event EventHandler Resize
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_Resize.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_Resize.Remove(value);
}
/****
** Main render events
****/
/// <summary>Raised before drawing the world to the screen.</summary>
public static event EventHandler OnPreRenderEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPreRenderEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPreRenderEvent.Remove(value);
}
/// <summary>Raised after drawing the world to the screen.</summary>
public static event EventHandler OnPostRenderEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPostRenderEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPostRenderEvent.Remove(value);
}
/****
** HUD events
****/
/// <summary>Raised before drawing the HUD (item toolbar, clock, etc) to the screen. The HUD is available at this point, but not necessarily visible. (For example, the event is raised even if a menu is open.)</summary>
public static event EventHandler OnPreRenderHudEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPreRenderHudEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPreRenderHudEvent.Remove(value);
}
/// <summary>Raised after drawing the HUD (item toolbar, clock, etc) to the screen. The HUD is available at this point, but not necessarily visible. (For example, the event is raised even if a menu is open.)</summary>
public static event EventHandler OnPostRenderHudEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPostRenderHudEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPostRenderHudEvent.Remove(value);
}
/****
** GUI events
****/
/// <summary>Raised before drawing a menu to the screen during a draw loop. This includes the game's internal menus like the title screen.</summary>
public static event EventHandler OnPreRenderGuiEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPreRenderGuiEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPreRenderGuiEvent.Remove(value);
}
/// <summary>Raised after drawing a menu to the screen during a draw loop. This includes the game's internal menus like the title screen.</summary>
public static event EventHandler OnPostRenderGuiEvent
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GraphicsEvents.EventManager.Legacy_OnPostRenderGuiEvent.Add(value);
}
remove => GraphicsEvents.EventManager.Legacy_OnPostRenderGuiEvent.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
GraphicsEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -0,0 +1,122 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the game changes state.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class GameEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised when the game updates its state (≈60 times per second).</summary>
public static event EventHandler UpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_UpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_UpdateTick.Remove(value);
}
/// <summary>Raised every other tick (≈30 times per second).</summary>
public static event EventHandler SecondUpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_SecondUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_SecondUpdateTick.Remove(value);
}
/// <summary>Raised every fourth tick (≈15 times per second).</summary>
public static event EventHandler FourthUpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_FourthUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_FourthUpdateTick.Remove(value);
}
/// <summary>Raised every eighth tick (≈8 times per second).</summary>
public static event EventHandler EighthUpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_EighthUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_EighthUpdateTick.Remove(value);
}
/// <summary>Raised every 15th tick (≈4 times per second).</summary>
public static event EventHandler QuarterSecondTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_QuarterSecondTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_QuarterSecondTick.Remove(value);
}
/// <summary>Raised every 30th tick (≈twice per second).</summary>
public static event EventHandler HalfSecondTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_HalfSecondTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_HalfSecondTick.Remove(value);
}
/// <summary>Raised every 60th tick (≈once per second).</summary>
public static event EventHandler OneSecondTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_OneSecondTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_OneSecondTick.Remove(value);
}
/// <summary>Raised once after the game initialises and all <see cref="IMod.Entry"/> methods have been called.</summary>
public static event EventHandler FirstUpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
GameEvents.EventManager.Legacy_FirstUpdateTick.Add(value);
}
remove => GameEvents.EventManager.Legacy_FirstUpdateTick.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
GameEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -0,0 +1,100 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised before and after the player saves/loads the game.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class SaveEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised before the game creates the save file.</summary>
public static event EventHandler BeforeCreate
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_BeforeCreateSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_BeforeCreateSave.Remove(value);
}
/// <summary>Raised after the game finishes creating the save file.</summary>
public static event EventHandler AfterCreate
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterCreateSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterCreateSave.Remove(value);
}
/// <summary>Raised before the game begins writes data to the save file.</summary>
public static event EventHandler BeforeSave
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_BeforeSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_BeforeSave.Remove(value);
}
/// <summary>Raised after the game finishes writing data to the save file.</summary>
public static event EventHandler AfterSave
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterSave.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterSave.Remove(value);
}
/// <summary>Raised after the player loads a save slot.</summary>
public static event EventHandler AfterLoad
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterLoad.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterLoad.Remove(value);
}
/// <summary>Raised after the game returns to the title screen.</summary>
public static event EventHandler AfterReturnToTitle
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SaveEvents.EventManager.Legacy_AfterReturnToTitle.Add(value);
}
remove => SaveEvents.EventManager.Legacy_AfterReturnToTitle.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
SaveEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -0,0 +1,56 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the in-game date or time changes.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class TimeEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after the game begins a new day, including when loading a save.</summary>
public static event EventHandler AfterDayStarted
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
TimeEvents.EventManager.Legacy_AfterDayStarted.Add(value);
}
remove => TimeEvents.EventManager.Legacy_AfterDayStarted.Remove(value);
}
/// <summary>Raised after the in-game clock changes.</summary>
public static event EventHandler<EventArgsIntChanged> TimeOfDayChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
TimeEvents.EventManager.Legacy_TimeOfDayChanged.Add(value);
}
remove => TimeEvents.EventManager.Legacy_TimeOfDayChanged.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
TimeEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,18 +0,0 @@
using System;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Events related to UI and drawing to the screen.</summary>
public interface IHookEvents
{
/// <summary>Object.canBePlacedHere hook.</summary>
event Func<ObjectCanBePlacedHereEventArgs, bool> ObjectCanBePlacedHere;
/// <summary>Object.checkForAction hook.</summary>
event Func<ObjectCheckForActionEventArgs, bool> ObjectCheckForAction;
/// <summary>Object.isIndexOkForBasicShippedCategory hook.</summary>
event Func<ObjectIsIndexOkForBasicShippedCategoryEventArgs, bool> ObjectIsIndexOkForBasicShippedCategory;
}
}

View File

@ -23,6 +23,5 @@ namespace StardewModdingAPI.Events
/// <summary>Events serving specialised edge cases that shouldn't be used by most mods.</summary>
ISpecialisedEvents Specialised { get; }
IHookEvents Hook { get; }
}
}

View File

@ -0,0 +1,123 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework.Input;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the player uses a controller, keyboard, or mouse.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class ControlEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised when the <see cref="KeyboardState"/> changes. That happens when the player presses or releases a key.</summary>
public static event EventHandler<EventArgsKeyboardStateChanged> KeyboardChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_KeyboardChanged.Add(value);
}
remove => ControlEvents.EventManager.Legacy_KeyboardChanged.Remove(value);
}
/// <summary>Raised after the player presses a keyboard key.</summary>
public static event EventHandler<EventArgsKeyPressed> KeyPressed
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_KeyPressed.Add(value);
}
remove => ControlEvents.EventManager.Legacy_KeyPressed.Remove(value);
}
/// <summary>Raised after the player releases a keyboard key.</summary>
public static event EventHandler<EventArgsKeyPressed> KeyReleased
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_KeyReleased.Add(value);
}
remove => ControlEvents.EventManager.Legacy_KeyReleased.Remove(value);
}
/// <summary>Raised when the <see cref="MouseState"/> changes. That happens when the player moves the mouse, scrolls the mouse wheel, or presses/releases a button.</summary>
public static event EventHandler<EventArgsMouseStateChanged> MouseChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_MouseChanged.Add(value);
}
remove => ControlEvents.EventManager.Legacy_MouseChanged.Remove(value);
}
/// <summary>The player pressed a controller button. This event isn't raised for trigger buttons.</summary>
public static event EventHandler<EventArgsControllerButtonPressed> ControllerButtonPressed
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerButtonPressed.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerButtonPressed.Remove(value);
}
/// <summary>The player released a controller button. This event isn't raised for trigger buttons.</summary>
public static event EventHandler<EventArgsControllerButtonReleased> ControllerButtonReleased
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerButtonReleased.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerButtonReleased.Remove(value);
}
/// <summary>The player pressed a controller trigger button.</summary>
public static event EventHandler<EventArgsControllerTriggerPressed> ControllerTriggerPressed
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerTriggerPressed.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerTriggerPressed.Remove(value);
}
/// <summary>The player released a controller trigger button.</summary>
public static event EventHandler<EventArgsControllerTriggerReleased> ControllerTriggerReleased
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ControlEvents.EventManager.Legacy_ControllerTriggerReleased.Add(value);
}
remove => ControlEvents.EventManager.Legacy_ControllerTriggerReleased.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
ControlEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -0,0 +1,34 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.ControllerButtonPressed"/> event.</summary>
public class EventArgsControllerButtonPressed : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player who pressed the button.</summary>
public PlayerIndex PlayerIndex { get; }
/// <summary>The controller button that was pressed.</summary>
public Buttons ButtonPressed { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="playerIndex">The player who pressed the button.</param>
/// <param name="button">The controller button that was pressed.</param>
public EventArgsControllerButtonPressed(PlayerIndex playerIndex, Buttons button)
{
this.PlayerIndex = playerIndex;
this.ButtonPressed = button;
}
}
}
#endif

View File

@ -0,0 +1,34 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.ControllerButtonReleased"/> event.</summary>
public class EventArgsControllerButtonReleased : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player who pressed the button.</summary>
public PlayerIndex PlayerIndex { get; }
/// <summary>The controller button that was pressed.</summary>
public Buttons ButtonReleased { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="playerIndex">The player who pressed the button.</param>
/// <param name="button">The controller button that was released.</param>
public EventArgsControllerButtonReleased(PlayerIndex playerIndex, Buttons button)
{
this.PlayerIndex = playerIndex;
this.ButtonReleased = button;
}
}
}
#endif

View File

@ -0,0 +1,39 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.ControllerTriggerPressed"/> event.</summary>
public class EventArgsControllerTriggerPressed : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player who pressed the button.</summary>
public PlayerIndex PlayerIndex { get; }
/// <summary>The controller button that was pressed.</summary>
public Buttons ButtonPressed { get; }
/// <summary>The current trigger value.</summary>
public float Value { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="playerIndex">The player who pressed the trigger button.</param>
/// <param name="button">The trigger button that was pressed.</param>
/// <param name="value">The current trigger value.</param>
public EventArgsControllerTriggerPressed(PlayerIndex playerIndex, Buttons button, float value)
{
this.PlayerIndex = playerIndex;
this.ButtonPressed = button;
this.Value = value;
}
}
}
#endif

View File

@ -0,0 +1,39 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.ControllerTriggerReleased"/> event.</summary>
public class EventArgsControllerTriggerReleased : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player who pressed the button.</summary>
public PlayerIndex PlayerIndex { get; }
/// <summary>The controller button that was released.</summary>
public Buttons ButtonReleased { get; }
/// <summary>The current trigger value.</summary>
public float Value { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="playerIndex">The player who pressed the trigger button.</param>
/// <param name="button">The trigger button that was released.</param>
/// <param name="value">The current trigger value.</param>
public EventArgsControllerTriggerReleased(PlayerIndex playerIndex, Buttons button, float value)
{
this.PlayerIndex = playerIndex;
this.ButtonReleased = button;
this.Value = value;
}
}
}
#endif

View File

@ -0,0 +1,64 @@
#if !SMAPI_3_0_STRICT
using System;
using System.Collections.Generic;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments when a button is pressed or released.</summary>
public class EventArgsInput : EventArgs
{
/*********
** Fields
*********/
/// <summary>The buttons to suppress.</summary>
private readonly HashSet<SButton> SuppressButtons;
/*********
** Accessors
*********/
/// <summary>The button on the controller, keyboard, or mouse.</summary>
public SButton Button { get; }
/// <summary>The current cursor position.</summary>
public ICursorPosition Cursor { get; }
/// <summary>Whether the input should trigger actions on the affected tile.</summary>
public bool IsActionButton => this.Button.IsActionButton();
/// <summary>Whether the input should use tools on the affected tile.</summary>
public bool IsUseToolButton => this.Button.IsUseToolButton();
/// <summary>Whether a mod has indicated the key was already handled.</summary>
public bool IsSuppressed => this.SuppressButtons.Contains(this.Button);
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="button">The button on the controller, keyboard, or mouse.</param>
/// <param name="cursor">The cursor position.</param>
/// <param name="suppressButtons">The buttons to suppress.</param>
public EventArgsInput(SButton button, ICursorPosition cursor, HashSet<SButton> suppressButtons)
{
this.Button = button;
this.Cursor = cursor;
this.SuppressButtons = suppressButtons;
}
/// <summary>Prevent the game from handling the current button press. This doesn't prevent other mods from receiving the event.</summary>
public void SuppressButton()
{
this.SuppressButton(this.Button);
}
/// <summary>Prevent the game from handling a button press. This doesn't prevent other mods from receiving the event.</summary>
/// <param name="button">The button to suppress.</param>
public void SuppressButton(SButton button)
{
this.SuppressButtons.Add(button);
}
}
}
#endif

View File

@ -0,0 +1,28 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.KeyboardChanged"/> event.</summary>
public class EventArgsKeyPressed : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The keyboard button that was pressed.</summary>
public Keys KeyPressed { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="key">The keyboard button that was pressed.</param>
public EventArgsKeyPressed(Keys key)
{
this.KeyPressed = key;
}
}
}
#endif

View File

@ -0,0 +1,33 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.KeyboardChanged"/> event.</summary>
public class EventArgsKeyboardStateChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous keyboard state.</summary>
public KeyboardState NewState { get; }
/// <summary>The current keyboard state.</summary>
public KeyboardState PriorState { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorState">The previous keyboard state.</param>
/// <param name="newState">The current keyboard state.</param>
public EventArgsKeyboardStateChanged(KeyboardState priorState, KeyboardState newState)
{
this.PriorState = priorState;
this.NewState = newState;
}
}
}
#endif

View File

@ -0,0 +1,44 @@
#if !SMAPI_3_0_STRICT
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="ControlEvents.MouseChanged"/> event.</summary>
public class EventArgsMouseStateChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous mouse state.</summary>
public MouseState PriorState { get; }
/// <summary>The current mouse state.</summary>
public MouseState NewState { get; }
/// <summary>The previous mouse position on the screen adjusted for the zoom level.</summary>
public Point PriorPosition { get; }
/// <summary>The current mouse position on the screen adjusted for the zoom level.</summary>
public Point NewPosition { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorState">The previous mouse state.</param>
/// <param name="newState">The current mouse state.</param>
/// <param name="priorPosition">The previous mouse position on the screen adjusted for the zoom level.</param>
/// <param name="newPosition">The current mouse position on the screen adjusted for the zoom level.</param>
public EventArgsMouseStateChanged(MouseState priorState, MouseState newState, Point priorPosition, Point newPosition)
{
this.PriorState = priorState;
this.NewState = newState;
this.PriorPosition = priorPosition;
this.NewPosition = newPosition;
}
}
}
#endif

View File

@ -0,0 +1,56 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the player uses a controller, keyboard, or mouse button.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class InputEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised when the player presses a button on the keyboard, controller, or mouse.</summary>
public static event EventHandler<EventArgsInput> ButtonPressed
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
InputEvents.EventManager.Legacy_ButtonPressed.Add(value);
}
remove => InputEvents.EventManager.Legacy_ButtonPressed.Remove(value);
}
/// <summary>Raised when the player releases a keyboard key on the keyboard, controller, or mouse.</summary>
public static event EventHandler<EventArgsInput> ButtonReleased
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
InputEvents.EventManager.Legacy_ButtonReleased.Add(value);
}
remove => InputEvents.EventManager.Legacy_ButtonReleased.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
InputEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -0,0 +1,33 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewValley.Menus;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="MenuEvents.MenuChanged"/> event.</summary>
public class EventArgsClickableMenuChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous menu.</summary>
public IClickableMenu NewMenu { get; }
/// <summary>The current menu.</summary>
public IClickableMenu PriorMenu { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorMenu">The previous menu.</param>
/// <param name="newMenu">The current menu.</param>
public EventArgsClickableMenuChanged(IClickableMenu priorMenu, IClickableMenu newMenu)
{
this.NewMenu = newMenu;
this.PriorMenu = priorMenu;
}
}
}
#endif

View File

@ -0,0 +1,28 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewValley.Menus;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="MenuEvents.MenuClosed"/> event.</summary>
public class EventArgsClickableMenuClosed : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The menu that was closed.</summary>
public IClickableMenu PriorMenu { get; }
/*********
** Accessors
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorMenu">The menu that was closed.</param>
public EventArgsClickableMenuClosed(IClickableMenu priorMenu)
{
this.PriorMenu = priorMenu;
}
}
}
#endif

View File

@ -0,0 +1,56 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when a game menu is opened or closed (including internal menus like the title screen).</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class MenuEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after a game menu is opened or replaced with another menu. This event is not invoked when a menu is closed.</summary>
public static event EventHandler<EventArgsClickableMenuChanged> MenuChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MenuEvents.EventManager.Legacy_MenuChanged.Add(value);
}
remove => MenuEvents.EventManager.Legacy_MenuChanged.Remove(value);
}
/// <summary>Raised after a game menu is closed.</summary>
public static event EventHandler<EventArgsClickableMenuClosed> MenuClosed
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MenuEvents.EventManager.Legacy_MenuClosed.Add(value);
}
remove => MenuEvents.EventManager.Legacy_MenuClosed.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
MenuEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -0,0 +1,32 @@
#if !SMAPI_3_0_STRICT
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="MineEvents.MineLevelChanged"/> event.</summary>
public class EventArgsMineLevelChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous mine level.</summary>
public int PreviousMineLevel { get; }
/// <summary>The current mine level.</summary>
public int CurrentMineLevel { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="previousMineLevel">The previous mine level.</param>
/// <param name="currentMineLevel">The current mine level.</param>
public EventArgsMineLevelChanged(int previousMineLevel, int currentMineLevel)
{
this.PreviousMineLevel = previousMineLevel;
this.CurrentMineLevel = currentMineLevel;
}
}
}
#endif

View File

@ -0,0 +1,45 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when something happens in the mines.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class MineEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after the player warps to a new level of the mine.</summary>
public static event EventHandler<EventArgsMineLevelChanged> MineLevelChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MineEvents.EventManager.Legacy_MineLevelChanged.Add(value);
}
remove => MineEvents.EventManager.Legacy_MineLevelChanged.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
MineEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -0,0 +1,78 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised during the multiplayer sync process.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class MultiplayerEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised before the game syncs changes from other players.</summary>
public static event EventHandler BeforeMainSync
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_BeforeMainSync.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_BeforeMainSync.Remove(value);
}
/// <summary>Raised after the game syncs changes from other players.</summary>
public static event EventHandler AfterMainSync
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_AfterMainSync.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_AfterMainSync.Remove(value);
}
/// <summary>Raised before the game broadcasts changes to other players.</summary>
public static event EventHandler BeforeMainBroadcast
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_BeforeMainBroadcast.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_BeforeMainBroadcast.Remove(value);
}
/// <summary>Raised after the game broadcasts changes to other players.</summary>
public static event EventHandler AfterMainBroadcast
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
MultiplayerEvents.EventManager.Legacy_AfterMainBroadcast.Add(value);
}
remove => MultiplayerEvents.EventManager.Legacy_AfterMainBroadcast.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
MultiplayerEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -1,34 +0,0 @@
using StardewValley;
using Microsoft.Xna.Framework;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IHookEvents.ObjectCanBePlacedHere"/> event.</summary>
public class ObjectCanBePlacedHereEventArgs : System.EventArgs
{
/*********
** Accessors
*********/
public Object __instance { get; }
public GameLocation location { get; }
public Vector2 tile { get; }
public bool __result;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="oldSize">The previous window size.</param>
/// <param name="newSize">The current window size.</param>
internal ObjectCanBePlacedHereEventArgs(Object __instance, GameLocation location, Vector2 tile, bool __result)
{
this.__instance = __instance;
this.location = location;
this.tile = tile;
this.__result = __result;
}
}
}

View File

@ -1,24 +0,0 @@
using StardewValley;
using Microsoft.Xna.Framework;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IHookEvents.ObjectCheckForAction"/> event.</summary>
public class ObjectCheckForActionEventArgs : System.EventArgs
{
/*********
** Accessors
*********/
public Object __instance { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
internal ObjectCheckForActionEventArgs(Object __instance)
{
this.__instance = __instance;
}
}
}

View File

@ -1,29 +0,0 @@
using System;
using Microsoft.Xna.Framework;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an <see cref="IHookEvents.ObjectIsIndexOkForBasicShippedCategoryEventArgs"/> event.</summary>
public class ObjectIsIndexOkForBasicShippedCategoryEventArgs : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The index</summary>
public int index { get; }
public bool __result;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="oldSize">The previous window size.</param>
/// <param name="newSize">The current window size.</param>
internal ObjectIsIndexOkForBasicShippedCategoryEventArgs(int index, bool __result)
{
this.index = index;
this.__result = __result;
}
}
}

View File

@ -0,0 +1,43 @@
#if !SMAPI_3_0_STRICT
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="PlayerEvents.InventoryChanged"/> event.</summary>
public class EventArgsInventoryChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player's inventory.</summary>
public IList<Item> Inventory { get; }
/// <summary>The added items.</summary>
public List<ItemStackChange> Added { get; }
/// <summary>The removed items.</summary>
public List<ItemStackChange> Removed { get; }
/// <summary>The items whose stack sizes changed.</summary>
public List<ItemStackChange> QuantityChanged { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="inventory">The player's inventory.</param>
/// <param name="changedItems">The inventory changes.</param>
public EventArgsInventoryChanged(IList<Item> inventory, ItemStackChange[] changedItems)
{
this.Inventory = inventory;
this.Added = changedItems.Where(n => n.ChangeType == ChangeType.Added).ToList();
this.Removed = changedItems.Where(n => n.ChangeType == ChangeType.Removed).ToList();
this.QuantityChanged = changedItems.Where(n => n.ChangeType == ChangeType.StackChange).ToList();
}
}
}
#endif

View File

@ -0,0 +1,55 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Enums;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="PlayerEvents.LeveledUp"/> event.</summary>
public class EventArgsLevelUp : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player skill that leveled up.</summary>
public LevelType Type { get; }
/// <summary>The new skill level.</summary>
public int NewLevel { get; }
/// <summary>The player skill types.</summary>
public enum LevelType
{
/// <summary>The combat skill.</summary>
Combat = SkillType.Combat,
/// <summary>The farming skill.</summary>
Farming = SkillType.Farming,
/// <summary>The fishing skill.</summary>
Fishing = SkillType.Fishing,
/// <summary>The foraging skill.</summary>
Foraging = SkillType.Foraging,
/// <summary>The mining skill.</summary>
Mining = SkillType.Mining,
/// <summary>The luck skill.</summary>
Luck = SkillType.Luck
}
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="type">The player skill that leveled up.</param>
/// <param name="newLevel">The new skill level.</param>
public EventArgsLevelUp(LevelType type, int newLevel)
{
this.Type = type;
this.NewLevel = newLevel;
}
}
}
#endif

View File

@ -0,0 +1,34 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="PlayerEvents.Warped"/> event.</summary>
public class EventArgsPlayerWarped : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The player's previous location.</summary>
public GameLocation PriorLocation { get; }
/// <summary>The player's current location.</summary>
public GameLocation NewLocation { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorLocation">The player's previous location.</param>
/// <param name="newLocation">The player's current location.</param>
public EventArgsPlayerWarped(GameLocation priorLocation, GameLocation newLocation)
{
this.NewLocation = newLocation;
this.PriorLocation = priorLocation;
}
}
}
#endif

View File

@ -0,0 +1,68 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the player data changes.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class PlayerEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after the player's inventory changes in any way (added or removed item, sorted, etc).</summary>
public static event EventHandler<EventArgsInventoryChanged> InventoryChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
PlayerEvents.EventManager.Legacy_InventoryChanged.Add(value);
}
remove => PlayerEvents.EventManager.Legacy_InventoryChanged.Remove(value);
}
/// <summary>Raised after the player levels up a skill. This happens as soon as they level up, not when the game notifies the player after their character goes to bed.</summary>
public static event EventHandler<EventArgsLevelUp> LeveledUp
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
PlayerEvents.EventManager.Legacy_LeveledUp.Add(value);
}
remove => PlayerEvents.EventManager.Legacy_LeveledUp.Remove(value);
}
/// <summary>Raised after the player warps to a new location.</summary>
public static event EventHandler<EventArgsPlayerWarped> Warped
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
PlayerEvents.EventManager.Legacy_PlayerWarped.Add(value);
}
remove => PlayerEvents.EventManager.Legacy_PlayerWarped.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
PlayerEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -0,0 +1,45 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the game loads content.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class ContentEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after the content language changes.</summary>
public static event EventHandler<EventArgsValueChanged<string>> AfterLocaleChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
ContentEvents.EventManager.Legacy_LocaleChanged.Add(value);
}
remove => ContentEvents.EventManager.Legacy_LocaleChanged.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
ContentEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -0,0 +1,32 @@
#if !SMAPI_3_0_STRICT
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for an integer field that changed value.</summary>
public class EventArgsIntChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous value.</summary>
public int PriorInt { get; }
/// <summary>The current value.</summary>
public int NewInt { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorInt">The previous value.</param>
/// <param name="newInt">The current value.</param>
public EventArgsIntChanged(int priorInt, int newInt)
{
this.PriorInt = priorInt;
this.NewInt = newInt;
}
}
}
#endif

View File

@ -0,0 +1,33 @@
#if !SMAPI_3_0_STRICT
using System;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a field that changed value.</summary>
/// <typeparam name="T">The value type.</typeparam>
public class EventArgsValueChanged<T> : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The previous value.</summary>
public T PriorValue { get; }
/// <summary>The current value.</summary>
public T NewValue { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="priorValue">The previous value.</param>
/// <param name="newValue">The current value.</param>
public EventArgsValueChanged(T priorValue, T newValue)
{
this.PriorValue = priorValue;
this.NewValue = newValue;
}
}
}
#endif

View File

@ -0,0 +1,45 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events serving specialised edge cases that shouldn't be used by most mods.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class SpecialisedEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised when the game updates its state (≈60 times per second), regardless of normal SMAPI validation. This event is not thread-safe and may be invoked while game logic is running asynchronously. Changes to game state in this method may crash the game or corrupt an in-progress save. Do not use this event unless you're fully aware of the context in which your code will be run. Mods using this method will trigger a stability warning in the SMAPI console.</summary>
public static event EventHandler UnvalidatedUpdateTick
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
SpecialisedEvents.EventManager.Legacy_UnvalidatedUpdateTick.Add(value);
}
remove => SpecialisedEvents.EventManager.Legacy_UnvalidatedUpdateTick.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
SpecialisedEvents.EventManager = eventManager;
}
}
}
#endif

View File

@ -0,0 +1,41 @@
#if !SMAPI_3_0_STRICT
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
using StardewValley.Buildings;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="LocationEvents.BuildingsChanged"/> event.</summary>
public class EventArgsLocationBuildingsChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The location which changed.</summary>
public GameLocation Location { get; }
/// <summary>The buildings added to the location.</summary>
public IEnumerable<Building> Added { get; }
/// <summary>The buildings removed from the location.</summary>
public IEnumerable<Building> Removed { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="location">The location which changed.</param>
/// <param name="added">The buildings added to the location.</param>
/// <param name="removed">The buildings removed from the location.</param>
public EventArgsLocationBuildingsChanged(GameLocation location, IEnumerable<Building> added, IEnumerable<Building> removed)
{
this.Location = location;
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}
#endif

View File

@ -0,0 +1,42 @@
#if !SMAPI_3_0_STRICT
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using StardewValley;
using SObject = StardewValley.Object;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="LocationEvents.ObjectsChanged"/> event.</summary>
public class EventArgsLocationObjectsChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The location which changed.</summary>
public GameLocation Location { get; }
/// <summary>The objects added to the location.</summary>
public IEnumerable<KeyValuePair<Vector2, SObject>> Added { get; }
/// <summary>The objects removed from the location.</summary>
public IEnumerable<KeyValuePair<Vector2, SObject>> Removed { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="location">The location which changed.</param>
/// <param name="added">The objects added to the location.</param>
/// <param name="removed">The objects removed from the location.</param>
public EventArgsLocationObjectsChanged(GameLocation location, IEnumerable<KeyValuePair<Vector2, SObject>> added, IEnumerable<KeyValuePair<Vector2, SObject>> removed)
{
this.Location = location;
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}
#endif

View File

@ -0,0 +1,35 @@
#if !SMAPI_3_0_STRICT
using System;
using System.Collections.Generic;
using System.Linq;
using StardewValley;
namespace StardewModdingAPI.Events
{
/// <summary>Event arguments for a <see cref="LocationEvents.LocationsChanged"/> event.</summary>
public class EventArgsLocationsChanged : EventArgs
{
/*********
** Accessors
*********/
/// <summary>The added locations.</summary>
public IEnumerable<GameLocation> Added { get; }
/// <summary>The removed locations.</summary>
public IEnumerable<GameLocation> Removed { get; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="added">The added locations.</param>
/// <param name="removed">The removed locations.</param>
public EventArgsLocationsChanged(IEnumerable<GameLocation> added, IEnumerable<GameLocation> removed)
{
this.Added = added.ToArray();
this.Removed = removed.ToArray();
}
}
}
#endif

View File

@ -0,0 +1,67 @@
#if !SMAPI_3_0_STRICT
using System;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
namespace StardewModdingAPI.Events
{
/// <summary>Events raised when the player transitions between game locations, a location is added or removed, or the objects in the current location change.</summary>
[Obsolete("Use " + nameof(Mod.Helper) + "." + nameof(IModHelper.Events) + " instead. See https://smapi.io/3.0 for more info.")]
public static class LocationEvents
{
/*********
** Fields
*********/
/// <summary>The core event manager.</summary>
private static EventManager EventManager;
/*********
** Events
*********/
/// <summary>Raised after a game location is added or removed.</summary>
public static event EventHandler<EventArgsLocationsChanged> LocationsChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
LocationEvents.EventManager.Legacy_LocationsChanged.Add(value);
}
remove => LocationEvents.EventManager.Legacy_LocationsChanged.Remove(value);
}
/// <summary>Raised after buildings are added or removed in a location.</summary>
public static event EventHandler<EventArgsLocationBuildingsChanged> BuildingsChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
LocationEvents.EventManager.Legacy_BuildingsChanged.Add(value);
}
remove => LocationEvents.EventManager.Legacy_BuildingsChanged.Remove(value);
}
/// <summary>Raised after objects are added or removed in a location.</summary>
public static event EventHandler<EventArgsLocationObjectsChanged> ObjectsChanged
{
add
{
SCore.DeprecationManager.WarnForOldEvents();
LocationEvents.EventManager.Legacy_ObjectsChanged.Add(value);
}
remove => LocationEvents.EventManager.Legacy_ObjectsChanged.Remove(value);
}
/*********
** Public methods
*********/
/// <summary>Initialise the events.</summary>
/// <param name="eventManager">The core event manager.</param>
internal static void Init(EventManager eventManager)
{
LocationEvents.EventManager = eventManager;
}
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More