diff options
Diffstat (limited to '')
-rw-r--r-- | source/UI/SlotArea.cpp | 57 | ||||
-rw-r--r-- | source/UI/SlotArea.h | 5 | ||||
-rw-r--r-- | source/UI/cWindow.cpp | 29 | ||||
-rw-r--r-- | source/UI/cWindow.h | 5 |
4 files changed, 89 insertions, 7 deletions
diff --git a/source/UI/SlotArea.cpp b/source/UI/SlotArea.cpp index 60929be2f..6bc90b78e 100644 --- a/source/UI/SlotArea.cpp +++ b/source/UI/SlotArea.cpp @@ -257,7 +257,14 @@ void cSlotAreaCrafting::Clicked(cPlayer & a_Player, int a_SlotNum, bool a_IsRigh // Override for craft result slot
if (a_SlotNum == 0)
{
- ClickedResult(a_Player, a_IsShiftPressed);
+ if (a_IsShiftPressed)
+ {
+ ShiftClickedResult(a_Player);
+ }
+ else
+ {
+ ClickedResult(a_Player);
+ }
return;
}
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);
- 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();
// 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)
{
cCraftingGrid Grid(GetPlayerSlots(a_Player) + 1, m_GridSize, m_GridSize);
cCraftingRecipe & Recipe = GetRecipeForPlayer(a_Player);
cRoot::Get()->GetCraftingRecipes()->GetRecipe(&a_Player, Grid, Recipe);
+ SetSlot(0, a_Player, Recipe.GetResult());
+ m_ParentWindow.SendSlot(a_Player, this, 0);
}
diff --git a/source/UI/SlotArea.h b/source/UI/SlotArea.h index 0f3182036..79f95c5d5 100644 --- a/source/UI/SlotArea.h +++ b/source/UI/SlotArea.h @@ -197,7 +197,10 @@ protected: cRecipeMap m_Recipes;
/// 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
void UpdateRecipe(cPlayer & a_Player);
diff --git a/source/UI/cWindow.cpp b/source/UI/cWindow.cpp index 71d2a1200..7efbfaa5e 100644 --- a/source/UI/cWindow.cpp +++ b/source/UI/cWindow.cpp @@ -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) { LOGD("Destroying window %p (type %d)", this, m_WindowType); diff --git a/source/UI/cWindow.h b/source/UI/cWindow.h index 980a1e711..0fc368c9c 100644 --- a/source/UI/cWindow.h +++ b/source/UI/cWindow.h @@ -58,7 +58,7 @@ public: cWindow(WindowType a_WindowType, const AString & a_WindowTitle); virtual ~cWindow(); - int GetWindowID(void) const { return m_WindowID; } + char GetWindowID(void) const { return m_WindowID; } int GetWindowType(void) const { return m_WindowType; } cWindowOwner * GetOwner() { return m_Owner; } @@ -99,6 +99,9 @@ public: */ 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: cSlotAreas m_SlotAreas; |