1
0

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
This commit is contained in:
madmaxoft@gmail.com 2013-05-08 09:45:07 +00:00
parent a3717ba324
commit 7cbf36bf17
12 changed files with 513 additions and 132 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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);
}

View File

@ -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,

View File

@ -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 <math.h>
#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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
} ;

View File

@ -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 (DraggingItem.m_ItemType <= 0) // Empty-handed?
{
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();
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()))
{
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();
}
}
else if (!DraggingItem.IsEqual(Slot))
{
// Swap contents
cItem tmp(DraggingItem);
DraggingItem = Slot;
Slot = tmp;
}
break;
}
else if ((Slot.m_ItemType <= 0) || DraggingItem.IsEqual(Slot))
case caLeftClick:
{
// Drop one item in slot
cItemHandler * Handler = ItemHandler(Slot.m_ItemType);
if ((DraggingItem.m_ItemCount > 0) && (Slot.m_ItemCount < Handler->GetMaxStackSize()))
// Left-clicked
if (!DraggingItem.IsEqual(Slot))
{
Slot.m_ItemType = DraggingItem.m_ItemType;
Slot.m_ItemCount++;
Slot.m_ItemDamage = DraggingItem.m_ItemDamage;
DraggingItem.m_ItemCount--;
// Switch contents
cItem tmp(DraggingItem);
DraggingItem = Slot;
Slot = tmp;
}
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;
}
else if (!DraggingItem.IsEqual(Slot))
default:
{
// Swap contents
cItem tmp(DraggingItem);
DraggingItem = Slot;
Slot = tmp;
LOGWARNING("SlotArea: Unhandled click action: %d (%s)", a_ClickAction, ClickActionToString(a_ClickAction));
m_ParentWindow.BroadcastWholeWindow();
return;
}
}
else
{
// Left-clicked
if (!DraggingItem.IsEqual(Slot))
{
// Switch contents
cItem tmp(DraggingItem);
DraggingItem = Slot;
Slot = tmp;
}
else
{
// 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();
}
}
}
} // 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;
}

View File

@ -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;

View File

@ -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();

View File

@ -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
);