Working shift-click support in crafting areas; window update working in 1.3.2
git-svn-id: http://mc-server.googlecode.com/svn/trunk@869 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
fdf8387092
commit
50c6a66092
@ -13,6 +13,7 @@
|
|||||||
#include "ChunkDataSerializer.h"
|
#include "ChunkDataSerializer.h"
|
||||||
#include "cPlayer.h"
|
#include "cPlayer.h"
|
||||||
#include "cMonster.h"
|
#include "cMonster.h"
|
||||||
|
#include "UI/cWindow.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -360,6 +361,26 @@ void cProtocol132::SendUnloadChunk(int a_ChunkX, int a_ChunkZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol132::SendWholeInventory(const cWindow & a_Window)
|
||||||
|
{
|
||||||
|
// 1.3.2 requires player inventory slots to be sent as SetSlot packets,
|
||||||
|
// otherwise it sometimes fails to update the window
|
||||||
|
super::SendWholeInventory(a_Window);
|
||||||
|
const cItem * Slots = m_Client->GetPlayer()->GetInventory().GetSlots();
|
||||||
|
int BaseOffset = a_Window.GetNumSlots() - cInventory::c_NumSlots + cInventory::c_MainOffset; // the number of non-inventory slots the window has; inventory follows
|
||||||
|
char WindowID = a_Window.GetWindowID();
|
||||||
|
for (int i = 0; i < cInventory::c_NumSlots - cInventory::c_MainOffset; i++)
|
||||||
|
{
|
||||||
|
SendInventorySlot(WindowID, BaseOffset + i, Slots[i + cInventory::c_MainOffset]);
|
||||||
|
} // for i - Slots[]
|
||||||
|
// Send even the item being dragged:
|
||||||
|
SendInventorySlot(-1, -1, m_Client->GetPlayer()->GetDraggingItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AString cProtocol132::GetAuthServerID(void)
|
AString cProtocol132::GetAuthServerID(void)
|
||||||
{
|
{
|
||||||
// http://wiki.vg/wiki/index.php?title=Session&oldid=2615
|
// http://wiki.vg/wiki/index.php?title=Session&oldid=2615
|
||||||
|
@ -32,15 +32,16 @@ public:
|
|||||||
virtual void DataReceived(const char * a_Data, int a_Size) override;
|
virtual void DataReceived(const char * a_Data, int a_Size) override;
|
||||||
|
|
||||||
// Sending commands:
|
// Sending commands:
|
||||||
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
|
virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
|
||||||
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||||
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
|
||||||
virtual void SendDestroyEntity(const cEntity & a_Entity) override;
|
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
|
||||||
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
|
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
|
||||||
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
|
||||||
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8
|
virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8
|
||||||
virtual void SendSpawnMob (const cMonster & a_Mob) override;
|
virtual void SendSpawnMob (const cMonster & a_Mob) override;
|
||||||
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
|
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
|
||||||
|
virtual void SendWholeInventory(const cWindow & a_Window) override;
|
||||||
|
|
||||||
virtual AString GetAuthServerID(void) override;
|
virtual AString GetAuthServerID(void) override;
|
||||||
|
|
||||||
|
@ -257,7 +257,14 @@ void cSlotAreaCrafting::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRigh
|
|||||||
// Override for craft result slot
|
// Override for craft result slot
|
||||||
if (a_SlotNum == 0)
|
if (a_SlotNum == 0)
|
||||||
{
|
{
|
||||||
ClickedResult(a_Player, a_IsShiftPressed);
|
if (a_IsShiftPressed)
|
||||||
|
{
|
||||||
|
ShiftClickedResult(a_Player);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClickedResult(a_Player);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
super::Clicked(a_Player, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_ClickedItem);
|
super::Clicked(a_Player, a_SlotNum, a_IsRightClick, a_IsShiftPressed, a_ClickedItem);
|
||||||
@ -290,12 +297,9 @@ void cSlotAreaCrafting::OnPlayerRemoved(cPlayer & a_Player)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSlotAreaCrafting::ClickedResult(cPlayer & a_Player, bool a_IsShiftPressed)
|
void cSlotAreaCrafting::ClickedResult(cPlayer & a_Player)
|
||||||
{
|
{
|
||||||
const cItem * ResultSlot = GetSlot(0, a_Player);
|
const cItem * ResultSlot = GetSlot(0, a_Player);
|
||||||
LOGD("Clicked in craft result slot, item there: %d:%d (%d times)",
|
|
||||||
ResultSlot->m_ItemID, ResultSlot->m_ItemHealth, ResultSlot->m_ItemCount
|
|
||||||
);
|
|
||||||
cItem & DraggingItem = a_Player.GetDraggingItem();
|
cItem & DraggingItem = a_Player.GetDraggingItem();
|
||||||
|
|
||||||
// Get the current recipe:
|
// Get the current recipe:
|
||||||
@ -333,11 +337,54 @@ void cSlotAreaCrafting::ClickedResult(cPlayer & a_Player, bool a_IsShiftPressed)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cSlotAreaCrafting::ShiftClickedResult(cPlayer & a_Player)
|
||||||
|
{
|
||||||
|
cItem Result(*GetSlot(0, a_Player));
|
||||||
|
if (Result.IsEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cItem * PlayerSlots = GetPlayerSlots(a_Player) + 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Try distributing the result. If it fails, bail out:
|
||||||
|
cItem ResultCopy(Result);
|
||||||
|
m_ParentWindow.DistributeStack(ResultCopy, a_Player, this, false);
|
||||||
|
if (!ResultCopy.IsEmpty())
|
||||||
|
{
|
||||||
|
// Couldn't distribute all of it. Bail out
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Distribute the result, this time for real:
|
||||||
|
ResultCopy = Result;
|
||||||
|
m_ParentWindow.DistributeStack(ResultCopy, a_Player, this, true);
|
||||||
|
|
||||||
|
// Remove the ingredients from the crafting grid and update the recipe:
|
||||||
|
cCraftingRecipe & Recipe = GetRecipeForPlayer(a_Player);
|
||||||
|
cCraftingGrid Grid(PlayerSlots, m_GridSize, m_GridSize);
|
||||||
|
Recipe.ConsumeIngredients(Grid);
|
||||||
|
Grid.CopyToItems(PlayerSlots);
|
||||||
|
UpdateRecipe(a_Player);
|
||||||
|
if (!Recipe.GetResult().IsEqual(Result))
|
||||||
|
{
|
||||||
|
// The recipe has changed, bail out
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cSlotAreaCrafting::UpdateRecipe(cPlayer & a_Player)
|
void cSlotAreaCrafting::UpdateRecipe(cPlayer & a_Player)
|
||||||
{
|
{
|
||||||
cCraftingGrid Grid(GetPlayerSlots(a_Player) + 1, m_GridSize, m_GridSize);
|
cCraftingGrid Grid(GetPlayerSlots(a_Player) + 1, m_GridSize, m_GridSize);
|
||||||
cCraftingRecipe & Recipe = GetRecipeForPlayer(a_Player);
|
cCraftingRecipe & Recipe = GetRecipeForPlayer(a_Player);
|
||||||
cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe);
|
cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe);
|
||||||
|
SetSlot(0, a_Player, Recipe.GetResult());
|
||||||
|
m_ParentWindow.SendSlot(a_Player, this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,7 +197,10 @@ protected:
|
|||||||
cRecipeMap m_Recipes;
|
cRecipeMap m_Recipes;
|
||||||
|
|
||||||
/// Handles a click in the result slot. Crafts using the current recipe, if possible
|
/// Handles a click in the result slot. Crafts using the current recipe, if possible
|
||||||
void ClickedResult(cPlayer & a_Player, bool a_IsShiftPressed);
|
void ClickedResult(cPlayer & a_Player);
|
||||||
|
|
||||||
|
/// Handles a shift-click in the result slot. Crafts using the current recipe until it changes or no more space for result.
|
||||||
|
void ShiftClickedResult(cPlayer & a_Player);
|
||||||
|
|
||||||
/// Updates the current recipe and result slot based on the ingredients currently in the crafting grid of the specified player
|
/// Updates the current recipe and result slot based on the ingredients currently in the crafting grid of the specified player
|
||||||
void UpdateRecipe(cPlayer & a_Player);
|
void UpdateRecipe(cPlayer & a_Player);
|
||||||
|
@ -294,6 +294,35 @@ void cWindow::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, cSlotArea
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cWindow::SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_RelativeSlotNum)
|
||||||
|
{
|
||||||
|
int SlotBase = 0;
|
||||||
|
bool Found = false;
|
||||||
|
for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
if (*itr == a_SlotArea)
|
||||||
|
{
|
||||||
|
Found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SlotBase += (*itr)->GetNumSlots();
|
||||||
|
} // for itr - m_SlotAreas[]
|
||||||
|
if (!Found)
|
||||||
|
{
|
||||||
|
LOGERROR("cWindow::SendSlot(): unknown a_SlotArea");
|
||||||
|
ASSERT(!"cWindow::SendSlot(): unknown a_SlotArea");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_Player.GetClientHandle()->SendInventorySlot(
|
||||||
|
m_WindowID, a_RelativeSlotNum + SlotBase, *(a_SlotArea->GetSlot(a_RelativeSlotNum, a_Player))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWindow::Destroy(void)
|
void cWindow::Destroy(void)
|
||||||
{
|
{
|
||||||
LOGD("Destroying window %p (type %d)", this, m_WindowType);
|
LOGD("Destroying window %p (type %d)", this, m_WindowType);
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
cWindow(WindowType a_WindowType, const AString & a_WindowTitle);
|
cWindow(WindowType a_WindowType, const AString & a_WindowTitle);
|
||||||
virtual ~cWindow();
|
virtual ~cWindow();
|
||||||
|
|
||||||
int GetWindowID(void) const { return m_WindowID; }
|
char GetWindowID(void) const { return m_WindowID; }
|
||||||
int GetWindowType(void) const { return m_WindowType; }
|
int GetWindowType(void) const { return m_WindowType; }
|
||||||
|
|
||||||
cWindowOwner * GetOwner() { return m_Owner; }
|
cWindowOwner * GetOwner() { return m_Owner; }
|
||||||
@ -99,6 +99,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, cSlotArea * a_ExcludeArea, bool a_ShouldApply);
|
void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, cSlotArea * a_ExcludeArea, bool a_ShouldApply);
|
||||||
|
|
||||||
|
/// Used by cSlotAreas to send individual slots to clients, a_RelativeSlotNum is the slot number relative to a_SlotArea
|
||||||
|
void SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_RelativeSlotNum);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
cSlotAreas m_SlotAreas;
|
cSlotAreas m_SlotAreas;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user