From 7cbf36bf17df70d325d03e4cd40859ac31b4c2e2 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Wed, 8 May 2013 09:45:07 +0000 Subject: Refactored window clicking code to use different click actions First part of solving FS #371; should fix #370. git-svn-id: http://mc-server.googlecode.com/svn/trunk@1459 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Bindings.cpp | 149 ++++++++++++++++++++++++++++++++-- source/Bindings.h | 2 +- source/ClientHandle.cpp | 10 +-- source/ClientHandle.h | 2 +- source/Defines.h | 172 ++++++++++++++++++++++++++++++++-------- source/Protocol/Protocol125.cpp | 42 +++++++++- source/Protocol/Protocol15x.cpp | 78 ++++++++++++++++++ source/Protocol/Protocol15x.h | 2 + source/UI/SlotArea.cpp | 147 ++++++++++++++++++---------------- source/UI/SlotArea.h | 10 +-- source/UI/Window.cpp | 25 ++++-- source/UI/Window.h | 2 +- 12 files changed, 511 insertions(+), 130 deletions(-) (limited to 'source') diff --git a/source/Bindings.cpp b/source/Bindings.cpp index eec033c85..fb9e6e265 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 04/28/13 20:39:37. +** Generated automatically by tolua++-1.0.92 on 05/08/13 11:35:08. */ #ifndef __cplusplus @@ -2858,6 +2858,35 @@ static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* function: ClickActionToString */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ClickActionToString00 +static int tolua_AllToLua_ClickActionToString00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + eClickAction a_ClickAction = ((eClickAction) (int) tolua_tonumber(tolua_S,1,0)); + { + const char* tolua_ret = (const char*) ClickActionToString(a_ClickAction); + tolua_pushstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ClickActionToString'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* function: IsValidBlock */ #ifndef TOLUA_DISABLE_tolua_AllToLua_IsValidBlock00 static int tolua_AllToLua_IsValidBlock00(lua_State* tolua_S) @@ -4259,6 +4288,38 @@ static int tolua_AllToLua_cEntity_GetHeadYaw00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: GetMass of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetMass00 +static int tolua_AllToLua_cEntity_GetMass00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetMass'", NULL); +#endif + { + double tolua_ret = (double) self->GetMass(); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetMass'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetPosition of class cEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetPosition00 static int tolua_AllToLua_cEntity_GetPosition00(lua_State* tolua_S) @@ -4782,6 +4843,39 @@ static int tolua_AllToLua_cEntity_SetHeadYaw00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: SetMass of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetMass00 +static int tolua_AllToLua_cEntity_SetMass00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + double a_Mass = ((double) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetMass'", NULL); +#endif + { + self->SetMass(a_Mass); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetMass'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: SetPosX of class cEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetPosX00 static int tolua_AllToLua_cEntity_SetPosX00(lua_State* tolua_S) @@ -24323,6 +24417,50 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"DIG_STATUS_FINISHED",DIG_STATUS_FINISHED); tolua_constant(tolua_S,"DIG_STATUS_DROP_HELD",DIG_STATUS_DROP_HELD); tolua_constant(tolua_S,"DIG_STATUS_SHOOT_EAT",DIG_STATUS_SHOOT_EAT); + tolua_constant(tolua_S,"caLeftClick",caLeftClick); + tolua_constant(tolua_S,"caRightClick",caRightClick); + tolua_constant(tolua_S,"caShiftLeftClick",caShiftLeftClick); + tolua_constant(tolua_S,"caShiftRightClick",caShiftRightClick); + tolua_constant(tolua_S,"caNumber1",caNumber1); + tolua_constant(tolua_S,"caNumber2",caNumber2); + tolua_constant(tolua_S,"caNumber3",caNumber3); + tolua_constant(tolua_S,"caNumber4",caNumber4); + tolua_constant(tolua_S,"caNumber5",caNumber5); + tolua_constant(tolua_S,"caNumber6",caNumber6); + tolua_constant(tolua_S,"caNumber7",caNumber7); + tolua_constant(tolua_S,"caNumber8",caNumber8); + tolua_constant(tolua_S,"caNumber9",caNumber9); + tolua_constant(tolua_S,"caMiddleClick",caMiddleClick); + tolua_constant(tolua_S,"caDropKey",caDropKey); + tolua_constant(tolua_S,"caCtrlDropKey",caCtrlDropKey); + tolua_constant(tolua_S,"caLeftClickOutside",caLeftClickOutside); + tolua_constant(tolua_S,"caRightClickOutside",caRightClickOutside); + tolua_constant(tolua_S,"caLeftClickOutsideHoldNothing",caLeftClickOutsideHoldNothing); + tolua_constant(tolua_S,"caRightClickOutsideHoldNothing",caRightClickOutsideHoldNothing); + tolua_constant(tolua_S,"caLeftPaintBegin",caLeftPaintBegin); + tolua_constant(tolua_S,"caRightPaintBegin",caRightPaintBegin); + tolua_constant(tolua_S,"caLeftPaintProgress",caLeftPaintProgress); + tolua_constant(tolua_S,"caRightPaintProgress",caRightPaintProgress); + tolua_constant(tolua_S,"caLeftPaintEnd",caLeftPaintEnd); + tolua_constant(tolua_S,"caRightPaintEnd",caRightPaintEnd); + tolua_constant(tolua_S,"caDblClick",caDblClick); + tolua_constant(tolua_S,"caUnknown",caUnknown); + tolua_constant(tolua_S,"eGameMode_NotSet",eGameMode_NotSet); + tolua_constant(tolua_S,"eGameMode_Survival",eGameMode_Survival); + tolua_constant(tolua_S,"eGameMode_Creative",eGameMode_Creative); + tolua_constant(tolua_S,"eGameMode_Adventure",eGameMode_Adventure); + tolua_constant(tolua_S,"gmNotSet",gmNotSet); + tolua_constant(tolua_S,"gmSurvival",gmSurvival); + tolua_constant(tolua_S,"gmCreative",gmCreative); + tolua_constant(tolua_S,"gmAdventure",gmAdventure); + tolua_constant(tolua_S,"eWeather_Sunny",eWeather_Sunny); + tolua_constant(tolua_S,"eWeather_Rain",eWeather_Rain); + tolua_constant(tolua_S,"eWeather_ThunderStorm",eWeather_ThunderStorm); + tolua_constant(tolua_S,"wSunny",wSunny); + tolua_constant(tolua_S,"wRain",wRain); + tolua_constant(tolua_S,"wThunderstorm",wThunderstorm); + tolua_constant(tolua_S,"wStorm",wStorm); + tolua_function(tolua_S,"ClickActionToString",tolua_AllToLua_ClickActionToString00); tolua_function(tolua_S,"IsValidBlock",tolua_AllToLua_IsValidBlock00); tolua_function(tolua_S,"IsValidItem",tolua_AllToLua_IsValidItem00); tolua_function(tolua_S,"AddFaceDirection",tolua_AllToLua_AddFaceDirection00); @@ -24339,13 +24477,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsLeggings",tolua_AllToLua_ItemCategory_IsLeggings00); tolua_function(tolua_S,"IsBoots",tolua_AllToLua_ItemCategory_IsBoots00); tolua_endmodule(tolua_S); - tolua_constant(tolua_S,"eGameMode_NotSet",eGameMode_NotSet); - tolua_constant(tolua_S,"eGameMode_Survival",eGameMode_Survival); - tolua_constant(tolua_S,"eGameMode_Creative",eGameMode_Creative); - tolua_constant(tolua_S,"eGameMode_Adventure",eGameMode_Adventure); - tolua_constant(tolua_S,"eWeather_Sunny",eWeather_Sunny); - tolua_constant(tolua_S,"eWeather_Rain",eWeather_Rain); - tolua_constant(tolua_S,"eWeather_ThunderStorm",eWeather_ThunderStorm); tolua_function(tolua_S,"GetTime",tolua_AllToLua_GetTime00); tolua_function(tolua_S,"GetChar",tolua_AllToLua_GetChar00); tolua_cclass(tolua_S,"cStringMap","cStringMap","",NULL); @@ -24425,6 +24556,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetParentClass",tolua_AllToLua_cEntity_GetParentClass00); tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cEntity_GetWorld00); tolua_function(tolua_S,"GetHeadYaw",tolua_AllToLua_cEntity_GetHeadYaw00); + tolua_function(tolua_S,"GetMass",tolua_AllToLua_cEntity_GetMass00); tolua_function(tolua_S,"GetPosition",tolua_AllToLua_cEntity_GetPosition00); tolua_function(tolua_S,"GetPosX",tolua_AllToLua_cEntity_GetPosX00); tolua_function(tolua_S,"GetPosY",tolua_AllToLua_cEntity_GetPosY00); @@ -24441,6 +24573,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetChunkX",tolua_AllToLua_cEntity_GetChunkX00); tolua_function(tolua_S,"GetChunkZ",tolua_AllToLua_cEntity_GetChunkZ00); tolua_function(tolua_S,"SetHeadYaw",tolua_AllToLua_cEntity_SetHeadYaw00); + tolua_function(tolua_S,"SetMass",tolua_AllToLua_cEntity_SetMass00); tolua_function(tolua_S,"SetPosX",tolua_AllToLua_cEntity_SetPosX00); tolua_function(tolua_S,"SetPosY",tolua_AllToLua_cEntity_SetPosY00); tolua_function(tolua_S,"SetPosZ",tolua_AllToLua_cEntity_SetPosZ00); diff --git a/source/Bindings.h b/source/Bindings.h index c9f311193..e80650e8b 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 04/28/13 20:39:38. +** Generated automatically by tolua++-1.0.92 on 05/08/13 11:35:08. */ /* Exported function */ diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index ab7e3e2d9..e52f521f9 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -462,7 +462,7 @@ void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_Hel return; } - m_Player->GetWindow()->Clicked(*m_Player, 0, a_SlotNum, false, false, a_HeldItem); + m_Player->GetWindow()->Clicked(*m_Player, 0, a_SlotNum, (a_SlotNum >= 0) ? caLeftClick : caLeftClickOutside, a_HeldItem); } @@ -1010,10 +1010,10 @@ void cClientHandle::HandleWindowClose(char a_WindowID) -void cClientHandle::HandleWindowClick(char a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem) +void cClientHandle::HandleWindowClick(char a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_HeldItem) { - LOGD("WindowClick: WinID %d, SlotNum %d, IsRclk %d, IsShift %d, Item %s x %d", - a_WindowID, a_SlotNum, a_IsRightClick, a_IsShiftPressed, + LOGD("WindowClick: WinID %d, SlotNum %d, action: %s, Item %s x %d", + a_WindowID, a_SlotNum, ClickActionToString(a_ClickAction), ItemToString(a_HeldItem).c_str(), a_HeldItem.m_ItemCount ); @@ -1024,7 +1024,7 @@ void cClientHandle::HandleWindowClick(char a_WindowID, short a_SlotNum, bool a_I return; } - Window->Clicked(*m_Player, a_WindowID, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_HeldItem); + Window->Clicked(*m_Player, a_WindowID, a_SlotNum, a_ClickAction, a_HeldItem); } diff --git a/source/ClientHandle.h b/source/ClientHandle.h index 269022b55..50389584b 100644 --- a/source/ClientHandle.h +++ b/source/ClientHandle.h @@ -163,7 +163,7 @@ public: void HandleAnimation (char a_Animation); void HandleSlotSelected (short a_SlotNum); void HandleWindowClose (char a_WindowID); - void HandleWindowClick (char a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem); + void HandleWindowClick (char a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_HeldItem); void HandleUpdateSign ( int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, diff --git a/source/Defines.h b/source/Defines.h index c90416003..e92568d78 100644 --- a/source/Defines.h +++ b/source/Defines.h @@ -5,6 +5,10 @@ typedef unsigned char Byte; + + + + // tolua_begin /// How much light do the blocks emit on their own? @@ -23,7 +27,7 @@ extern bool g_BlockOneHitDig[]; -// Block face constants, used in PlayerDigging and PlayerBlockPlacement packets +/// Block face constants, used in PlayerDigging and PlayerBlockPlacement packets enum { BLOCK_FACE_NONE = -1, // Interacting with no block face - swinging the item in the air @@ -35,7 +39,11 @@ enum BLOCK_FACE_EAST = 5, // Interacting with the eastern face of the block } ; -// PlayerDigging status constants: + + + + +/// PlayerDigging status constants enum { DIG_STATUS_STARTED = 0, @@ -44,14 +52,131 @@ enum DIG_STATUS_DROP_HELD = 4, DIG_STATUS_SHOOT_EAT = 5, } ; -// tolua_end -inline bool IsValidBlock(int a_BlockType) // tolua_export -{ // tolua_export +/// Individual actions sent in the WindowClick packet +enum eClickAction +{ + // Sorted by occurrence in the 1.5 protocol + caLeftClick, + caRightClick, + caShiftLeftClick, + caShiftRightClick, + caNumber1, + caNumber2, + caNumber3, + caNumber4, + caNumber5, + caNumber6, + caNumber7, + caNumber8, + caNumber9, + caMiddleClick, + caDropKey, + caCtrlDropKey, + caLeftClickOutside, + caRightClickOutside, + caLeftClickOutsideHoldNothing, + caRightClickOutsideHoldNothing, + caLeftPaintBegin, + caRightPaintBegin, + caLeftPaintProgress, + caRightPaintProgress, + caLeftPaintEnd, + caRightPaintEnd, + caDblClick, + // Add new actions here + caUnknown = 255, + + // Keep this list in sync with ClickActionToString() function below! +} ; + + + + + +enum eGameMode +{ + eGameMode_NotSet = -1, + eGameMode_Survival = 0, + eGameMode_Creative = 1, + eGameMode_Adventure = 2, + + // Easier-to-use synonyms: + gmNotSet = eGameMode_NotSet, + gmSurvival = eGameMode_Survival, + gmCreative = eGameMode_Creative, + gmAdventure = eGameMode_Adventure, +} ; + + + + + +enum eWeather +{ + eWeather_Sunny = 0, + eWeather_Rain = 1, + eWeather_ThunderStorm = 2, + + // Easier-to-use synonyms: + wSunny = eWeather_Sunny, + wRain = eWeather_Rain, + wThunderstorm = eWeather_ThunderStorm, + wStorm = wThunderstorm, +} ; + + + + + +inline const char * ClickActionToString(eClickAction a_ClickAction) +{ + switch (a_ClickAction) + { + case caLeftClick: return "caLeftClick"; + case caRightClick: return "caRightClick"; + case caShiftLeftClick: return "caShiftLeftClick"; + case caShiftRightClick: return "caShiftRightClick"; + case caNumber1: return "caNumber1"; + case caNumber2: return "caNumber2"; + case caNumber3: return "caNumber3"; + case caNumber4: return "caNumber4"; + case caNumber5: return "caNumber5"; + case caNumber6: return "caNumber6"; + case caNumber7: return "caNumber7"; + case caNumber8: return "caNumber8"; + case caNumber9: return "caNumber9"; + case caMiddleClick: return "caMiddleClick"; + case caDropKey: return "caDropKey"; + case caCtrlDropKey: return "caCtrlDropKey"; + case caLeftClickOutside: return "caLeftClickOutside"; + case caRightClickOutside: return "caRightClickOutside"; + case caLeftClickOutsideHoldNothing: return "caLeftClickOutsideHoldNothing"; + case caRightClickOutsideHoldNothing: return "caRightClickOutsideHoldNothing"; + case caLeftPaintBegin: return "caLeftPaintBegin"; + case caRightPaintBegin: return "caRightPaintBegin"; + case caLeftPaintProgress: return "caLeftPaintProgress"; + case caRightPaintProgress: return "caRightPaintProgress"; + case caLeftPaintEnd: return "caLeftPaintEnd"; + case caRightPaintEnd: return "caRightPaintEnd"; + case caDblClick: return "caDblClick"; + + case caUnknown: return "caUnknown"; + } + ASSERT(!"Unknown click action"); + return "caUnknown"; +} + + + + + +inline bool IsValidBlock(int a_BlockType) +{ if ( (a_BlockType > -1) && (a_BlockType <= E_BLOCK_MAX_TYPE_ID) && @@ -62,14 +187,14 @@ inline bool IsValidBlock(int a_BlockType) // tolua_export return true; } return false; -} // tolua_export +} -inline bool IsValidItem(int a_ItemType) // tolua_export -{ // tolua_export +inline bool IsValidItem(int a_ItemType) +{ if ( ((a_ItemType >= E_ITEM_FIRST) && (a_ItemType <= E_ITEM_MAX_CONSECUTIVE_TYPE_ID)) || // Basic items range ((a_ItemType >= E_ITEM_FIRST_DISC) && (a_ItemType <= E_ITEM_LAST_DISC)) // Music discs' special range @@ -84,7 +209,9 @@ inline bool IsValidItem(int a_ItemType) // tolua_export } return IsValidBlock(a_ItemType); -} // tolua_export +} + +// tolua_end @@ -202,8 +329,7 @@ inline void AddFaceDirection(int & a_BlockX, unsigned char & a_BlockY, int & a_B #include #define PI 3.14159265358979323846264338327950288419716939937510582097494459072381640628620899862803482534211706798f -#define MIN(a,b) (((a)>(b))?(b):(a)) -#define MAX(a,b) (((a)>(b))?(a):(b)) + inline void EulerToVector(double a_Pan, double a_Pitch, double & a_X, double & a_Y, double & a_Z) { // a_X = sinf ( a_Pan / 180 * PI ) * cosf ( a_Pitch / 180 * PI ); @@ -381,30 +507,6 @@ inline bool BlockRequiresSpecialTool(BLOCKTYPE a_BlockType) } -// tolua_begin -enum eGameMode -{ - eGameMode_NotSet = -1, - eGameMode_Survival = 0, - eGameMode_Creative = 1, - eGameMode_Adventure = 2 -}; - - - - - -enum eWeather -{ - eWeather_Sunny = 0, - eWeather_Rain = 1, - eWeather_ThunderStorm = 2 -}; - - - - -// tolua_end diff --git a/source/Protocol/Protocol125.cpp b/source/Protocol/Protocol125.cpp index 4be4cb033..17def7c8a 100644 --- a/source/Protocol/Protocol125.cpp +++ b/source/Protocol/Protocol125.cpp @@ -1381,7 +1381,47 @@ int cProtocol125::ParseWindowClick(void) { return res; } - m_Client->HandleWindowClick(WindowID, SlotNum, IsRightClick, IsShiftPressed, HeldItem); + + // Convert IsShiftPressed, IsRightClick, SlotNum and HeldItem into eClickAction used in the newer protocols: + eClickAction Action; + if (IsRightClick) + { + if (IsShiftPressed) + { + Action = caShiftRightClick; + } + else + { + if (SlotNum == -999) + { + Action = (HeldItem.IsEmpty()) ? caRightClickOutsideHoldNothing : caRightClickOutside; + } + else + { + Action = caRightClick; + } + } + } + else + { + // IsLeftClick + if (IsShiftPressed) + { + Action = caShiftLeftClick; + } + else + { + if (SlotNum == -999) + { + Action = (HeldItem.IsEmpty()) ? caLeftClickOutsideHoldNothing : caRightClickOutside; + } + else + { + Action = caLeftClick; + } + } + } + m_Client->HandleWindowClick(WindowID, SlotNum, Action, HeldItem); return PARSE_OK; } diff --git a/source/Protocol/Protocol15x.cpp b/source/Protocol/Protocol15x.cpp index 61358fcdb..78792af19 100644 --- a/source/Protocol/Protocol15x.cpp +++ b/source/Protocol/Protocol15x.cpp @@ -10,6 +10,23 @@ Implements the 1.5.x protocol classes: #include "Globals.h" #include "Protocol15x.h" +#include "../ClientHandle.h" +#include "../Item.h" + + + + + +#define HANDLE_PACKET_READ(Proc, Type, Var) \ + Type Var; \ + { \ + if (!m_ReceivedData.Proc(Var)) \ + { \ + m_ReceivedData.CheckValid(); \ + return PARSE_INCOMPLETE; \ + } \ + m_ReceivedData.CheckValid(); \ + } @@ -57,3 +74,64 @@ void cProtocol150::SendWindowOpen(char a_WindowID, char a_WindowType, const AStr + +int cProtocol150::ParseWindowClick(void) +{ + HANDLE_PACKET_READ(ReadChar, char, WindowID); + HANDLE_PACKET_READ(ReadBEShort, short, SlotNum); + HANDLE_PACKET_READ(ReadByte, Byte, Button); + HANDLE_PACKET_READ(ReadBEShort, short, TransactionID); + HANDLE_PACKET_READ(ReadByte, Byte, Mode); + cItem HeldItem; + int res = ParseItem(HeldItem); + if (res < 0) + { + return res; + } + + // Convert Button, Mode, SlotNum and HeldItem into eClickAction: + eClickAction Action; + switch ((Mode << 8) | Button) + { + case 0x0000: Action = (SlotNum != -999) ? caLeftClick : caLeftClickOutside; break; + case 0x0001: Action = (SlotNum != -999) ? caRightClick : caRightClickOutside; break; + case 0x0100: Action = caShiftLeftClick; break; + case 0x0101: Action = caShiftRightClick; break; + case 0x0200: Action = caNumber1; break; + case 0x0201: Action = caNumber2; break; + case 0x0202: Action = caNumber3; break; + case 0x0203: Action = caNumber4; break; + case 0x0204: Action = caNumber5; break; + case 0x0205: Action = caNumber6; break; + case 0x0206: Action = caNumber7; break; + case 0x0207: Action = caNumber8; break; + case 0x0208: Action = caNumber9; break; + case 0x0300: Action = caMiddleClick; break; + case 0x0400: Action = (SlotNum == -999) ? caLeftClickOutsideHoldNothing : caDropKey; break; + case 0x0401: Action = (SlotNum == -999) ? caRightClickOutsideHoldNothing : caCtrlDropKey; break; + case 0x0500: Action = (SlotNum == -999) ? caLeftPaintBegin : caUnknown; break; + case 0x0501: Action = (SlotNum != -999) ? caLeftPaintProgress : caUnknown; break; + case 0x0502: Action = (SlotNum == -999) ? caLeftPaintEnd : caUnknown; break; + case 0x0504: Action = (SlotNum == -999) ? caRightPaintBegin : caUnknown; break; + case 0x0505: Action = (SlotNum != -999) ? caRightPaintProgress : caUnknown; break; + case 0x0506: Action = (SlotNum == -999) ? caRightPaintEnd : caUnknown; break; + case 0x0600: Action = caDblClick; break; + } + + if (Action == caUnknown) + { + LOGWARNING("Received an unknown click action combination: Mode = %d, Button = %d, Slot = %d, HeldItem = %s. Ignoring packet.", + Mode, Button, SlotNum, ItemToFullString(HeldItem).c_str() + ); + ASSERT(!"Unknown click action"); + return PARSE_OK; + } + + m_Client->HandleWindowClick(WindowID, SlotNum, Action, HeldItem); + return PARSE_OK; +} + + + + + diff --git a/source/Protocol/Protocol15x.h b/source/Protocol/Protocol15x.h index f09ba09d7..a1c665ab4 100644 --- a/source/Protocol/Protocol15x.h +++ b/source/Protocol/Protocol15x.h @@ -29,6 +29,8 @@ public: cProtocol150(cClientHandle * a_Client); virtual void SendWindowOpen(char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots) override; + + virtual int ParseWindowClick(void); } ; diff --git a/source/UI/SlotArea.cpp b/source/UI/SlotArea.cpp index 00698acda..f78e23e99 100644 --- a/source/UI/SlotArea.cpp +++ b/source/UI/SlotArea.cpp @@ -31,7 +31,7 @@ cSlotArea::cSlotArea(int a_NumSlots, cWindow & a_ParentWindow) : -void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem) +void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) { /* LOGD("Slot area with %d slots clicked at slot number %d, clicked item %s, slot item %s", @@ -50,94 +50,105 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, return; } - if (a_IsShiftPressed) + if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick)) { if (!a_Player.IsDraggingItem()) { ShiftClicked(a_Player, a_SlotNum, a_ClickedItem); return; } - LOGD("Shift clicked, but the player is draggint an item: %s", ItemToFullString(a_Player.GetDraggingItem()).c_str()); + LOGD("Shift clicked, but the player is dragging an item: %s", ItemToFullString(a_Player.GetDraggingItem()).c_str()); return; } cItem Slot(*GetSlot(a_SlotNum, a_Player)); if (!Slot.IsSameType(a_ClickedItem)) { - LOGD("*** Window lost sync at item %d in SlotArea with %d items ***", a_SlotNum, m_NumSlots); - LOGD("My item: %s", ItemToFullString(Slot).c_str()); - LOGD("Their item: %s", ItemToFullString(a_ClickedItem).c_str()); + LOGWARNING("*** Window lost sync at item %d in SlotArea with %d items ***", a_SlotNum, m_NumSlots); + LOGWARNING("My item: %s", ItemToFullString(Slot).c_str()); + LOGWARNING("Their item: %s", ItemToFullString(a_ClickedItem).c_str()); bAsync = true; } cItem & DraggingItem = a_Player.GetDraggingItem(); - if (a_IsRightClick) + switch (a_ClickAction) { - // Right clicked - if (DraggingItem.m_ItemType <= 0) // Empty-handed? + case caRightClick: { - DraggingItem.m_ItemCount = (char)(((float)Slot.m_ItemCount) / 2.f + 0.5f); - Slot.m_ItemCount -= DraggingItem.m_ItemCount; - DraggingItem.m_ItemType = Slot.m_ItemType; - DraggingItem.m_ItemDamage = Slot.m_ItemDamage; - - if (Slot.m_ItemCount <= 0) + if (DraggingItem.m_ItemType <= 0) // Empty-handed? { - Slot.Empty(); + DraggingItem.m_ItemCount = (char)(((float)Slot.m_ItemCount) / 2.f + 0.5f); + Slot.m_ItemCount -= DraggingItem.m_ItemCount; + DraggingItem.m_ItemType = Slot.m_ItemType; + DraggingItem.m_ItemDamage = Slot.m_ItemDamage; + + if (Slot.m_ItemCount <= 0) + { + Slot.Empty(); + } } - } - else if ((Slot.m_ItemType <= 0) || DraggingItem.IsEqual(Slot)) - { - // Drop one item in slot - cItemHandler * Handler = ItemHandler(Slot.m_ItemType); - if ((DraggingItem.m_ItemCount > 0) && (Slot.m_ItemCount < Handler->GetMaxStackSize())) + else if ((Slot.m_ItemType <= 0) || DraggingItem.IsEqual(Slot)) { - Slot.m_ItemType = DraggingItem.m_ItemType; - Slot.m_ItemCount++; - Slot.m_ItemDamage = DraggingItem.m_ItemDamage; - DraggingItem.m_ItemCount--; + // Drop one item in slot + cItemHandler * Handler = ItemHandler(Slot.m_ItemType); + if ((DraggingItem.m_ItemCount > 0) && (Slot.m_ItemCount < Handler->GetMaxStackSize())) + { + Slot.m_ItemType = DraggingItem.m_ItemType; + Slot.m_ItemCount++; + Slot.m_ItemDamage = DraggingItem.m_ItemDamage; + DraggingItem.m_ItemCount--; + } + if (DraggingItem.m_ItemCount <= 0) + { + DraggingItem.Empty(); + } } - if (DraggingItem.m_ItemCount <= 0) + else if (!DraggingItem.IsEqual(Slot)) { - DraggingItem.Empty(); + // Swap contents + cItem tmp(DraggingItem); + DraggingItem = Slot; + Slot = tmp; } + break; } - else if (!DraggingItem.IsEqual(Slot)) - { - // Swap contents - cItem tmp(DraggingItem); - DraggingItem = Slot; - Slot = tmp; - } - } - else - { - // Left-clicked - if (!DraggingItem.IsEqual(Slot)) - { - // Switch contents - cItem tmp(DraggingItem); - DraggingItem = Slot; - Slot = tmp; - } - else + + case caLeftClick: { - // Same type, add items: - cItemHandler * Handler = ItemHandler(DraggingItem.m_ItemType); - int FreeSlots = Handler->GetMaxStackSize() - Slot.m_ItemCount; - if (FreeSlots < 0) + // Left-clicked + if (!DraggingItem.IsEqual(Slot)) { - ASSERT(!"Bad item stack size - where did we get more items in a slot than allowed?"); - FreeSlots = 0; + // Switch contents + cItem tmp(DraggingItem); + DraggingItem = Slot; + Slot = tmp; } - int Filling = (FreeSlots > DraggingItem.m_ItemCount) ? DraggingItem.m_ItemCount : FreeSlots; - Slot.m_ItemCount += (char)Filling; - DraggingItem.m_ItemCount -= (char)Filling; - if (DraggingItem.m_ItemCount <= 0) + else { - DraggingItem.Empty(); + // Same type, add items: + cItemHandler * Handler = ItemHandler(DraggingItem.m_ItemType); + int FreeSlots = Handler->GetMaxStackSize() - Slot.m_ItemCount; + if (FreeSlots < 0) + { + ASSERT(!"Bad item stack size - where did we get more items in a slot than allowed?"); + FreeSlots = 0; + } + int Filling = (FreeSlots > DraggingItem.m_ItemCount) ? DraggingItem.m_ItemCount : FreeSlots; + Slot.m_ItemCount += (char)Filling; + DraggingItem.m_ItemCount -= (char)Filling; + if (DraggingItem.m_ItemCount <= 0) + { + DraggingItem.Empty(); + } } + break; } - } + default: + { + LOGWARNING("SlotArea: Unhandled click action: %d (%s)", a_ClickAction, ClickActionToString(a_ClickAction)); + m_ParentWindow.BroadcastWholeWindow(); + return; + } + } // switch (a_ClickAction SetSlot(a_SlotNum, a_Player, Slot); if (bAsync) @@ -301,12 +312,12 @@ cSlotAreaCrafting::cSlotAreaCrafting(int a_GridSize, cWindow & a_ParentWindow) : -void cSlotAreaCrafting::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem) +void cSlotAreaCrafting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) { // Override for craft result slot if (a_SlotNum == 0) { - if (a_IsShiftPressed) + if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick)) { ShiftClickedResult(a_Player); } @@ -316,7 +327,7 @@ void cSlotAreaCrafting::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRigh } return; } - super::Clicked(a_Player, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_ClickedItem); + super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem); UpdateRecipe(a_Player); } @@ -475,9 +486,9 @@ cSlotAreaDispenser::cSlotAreaDispenser(cDispenserEntity * a_Dispenser, cWindow & -void cSlotAreaDispenser::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem) +void cSlotAreaDispenser::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) { - super::Clicked(a_Player, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_ClickedItem); + super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem); if (m_Dispenser == NULL) { @@ -522,11 +533,11 @@ cSlotAreaFurnace::cSlotAreaFurnace(cFurnaceEntity * a_Furnace, cWindow & a_Paren -void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem) +void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) { cItem Fuel = *GetSlot(0, a_Player); - super::Clicked(a_Player, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_ClickedItem); + super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem); if (m_Furnace == NULL) { @@ -582,7 +593,7 @@ cSlotAreaInventoryBase::cSlotAreaInventoryBase(int a_NumSlots, int a_SlotOffset, -void cSlotAreaInventoryBase::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem) +void cSlotAreaInventoryBase::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) { if ((a_Player.GetGameMode() == eGameMode_Creative) && (m_ParentWindow.GetWindowType() == cWindow::Inventory)) { @@ -592,7 +603,7 @@ void cSlotAreaInventoryBase::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_I } // Survival inventory and all other windows' inventory has the same handling as normal slot areas - super::Clicked(a_Player, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_ClickedItem); + super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem); return; } diff --git a/source/UI/SlotArea.h b/source/UI/SlotArea.h index fff9f46cc..2738e08e9 100644 --- a/source/UI/SlotArea.h +++ b/source/UI/SlotArea.h @@ -38,7 +38,7 @@ public: virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) = 0; /// Called when a player clicks in the window. Parameters taken from the click packet. - virtual void Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem); + virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem); /// Called from Clicked if it is a valid shiftclick virtual void ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem); @@ -76,7 +76,7 @@ public: cSlotAreaInventoryBase(int a_NumSlots, int a_SlotOffset, cWindow & a_ParentWindow); // Creative inventory's click handling is somewhat different from survival inventory's, handle that here: - virtual void Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem) override; + virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override; virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) override; virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; @@ -185,7 +185,7 @@ public: cSlotAreaCrafting(int a_GridSize, cWindow & a_ParentWindow); // cSlotAreaTemporary overrides: - virtual void Clicked (cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem) override; + virtual void Clicked (cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override; virtual void OnPlayerRemoved(cPlayer & a_Player) override; // Distributing items into this area is completely disabled @@ -258,7 +258,7 @@ class cSlotAreaDispenser : public: cSlotAreaDispenser(cDispenserEntity * a_Dispenser, cWindow & a_ParentWindow); - virtual void Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem) override; + virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override; virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) override; virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; @@ -278,7 +278,7 @@ class cSlotAreaFurnace : public: cSlotAreaFurnace(cFurnaceEntity * a_Furnace, cWindow & a_ParentWindow); - virtual void Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_ClickedItem) override; + virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override; virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) override; virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; diff --git a/source/UI/Window.cpp b/source/UI/Window.cpp index 12c3e7350..bb80a7ce7 100644 --- a/source/UI/Window.cpp +++ b/source/UI/Window.cpp @@ -96,7 +96,7 @@ void cWindow::GetSlots(cPlayer & a_Player, cItems & a_Slots) const void cWindow::Clicked( cPlayer & a_Player, - int a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, + int a_WindowID, short a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem ) { @@ -106,16 +106,31 @@ void cWindow::Clicked( return; } - if (a_SlotNum < 0) // Outside window click + switch (a_ClickAction) { - if (a_IsRightClick) + case caRightClickOutside: { + // Toss one of the dragged items: a_Player.TossItem(true); + return; } - else + case caLeftClickOutside: { + // Toss all dragged items: a_Player.TossItem(true, a_Player.GetDraggingItem().m_ItemCount); + return; + } + case caLeftClickOutsideHoldNothing: + case caRightClickOutsideHoldNothing: + { + // Nothing needed + return; } + } + + if (a_SlotNum < 0) + { + // TODO: Other click actions with irrelevant slot number (FS #371) return; } @@ -125,7 +140,7 @@ void cWindow::Clicked( { if (LocalSlotNum < (*itr)->GetNumSlots()) { - (*itr)->Clicked(a_Player, LocalSlotNum, a_IsRightClick, a_IsShiftPressed, a_ClickedItem); + (*itr)->Clicked(a_Player, LocalSlotNum, a_ClickAction, a_ClickedItem); return; } LocalSlotNum -= (*itr)->GetNumSlots(); diff --git a/source/UI/Window.h b/source/UI/Window.h index c119d79ab..7bd87a2ce 100644 --- a/source/UI/Window.h +++ b/source/UI/Window.h @@ -72,7 +72,7 @@ public: void Clicked( cPlayer & a_Player, int a_WindowID, - short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, + short a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem ); -- cgit v1.2.3