summaryrefslogtreecommitdiffstats
path: root/src/BlockEntities/BrewingstandEntity.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/BlockEntities/BrewingstandEntity.cpp')
-rw-r--r--src/BlockEntities/BrewingstandEntity.cpp309
1 files changed, 309 insertions, 0 deletions
diff --git a/src/BlockEntities/BrewingstandEntity.cpp b/src/BlockEntities/BrewingstandEntity.cpp
new file mode 100644
index 000000000..e34297393
--- /dev/null
+++ b/src/BlockEntities/BrewingstandEntity.cpp
@@ -0,0 +1,309 @@
+
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
+
+#include "BrewingstandEntity.h"
+#include "../Bindings/PluginManager.h"
+#include "../UI/BrewingstandWindow.h"
+#include "../Entities/Player.h"
+#include "../Root.h"
+#include "../Chunk.h"
+
+
+
+
+
+
+
+
+
+
+
+
+cBrewingstandEntity::cBrewingstandEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World) :
+ super(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, ContentsWidth, ContentsHeight, a_World),
+ m_BlockMeta(a_BlockMeta),
+ m_IsDestroyed(false),
+ m_IsBrewing(false),
+ m_TimeBrewed(0)
+{
+ m_Contents.AddListener(*this);
+ for (int i = 0; i < 3; i++)
+ {
+ m_Results[i] = *(new cItem());
+ }
+}
+
+
+
+
+
+cBrewingstandEntity::~cBrewingstandEntity()
+{
+ // Tell window its owner is destroyed
+ cWindow * Window = GetWindow();
+ if (Window != nullptr)
+ {
+ Window->OwnerDestroyed();
+ }
+}
+
+
+
+
+
+void cBrewingstandEntity::UsedBy(cPlayer * a_Player)
+{
+ cWindow * Window = GetWindow();
+ if (Window == nullptr)
+ {
+ OpenWindow(new cBrewingstandWindow(m_PosX, m_PosY, m_PosZ, this));
+ Window = GetWindow();
+ }
+
+ if (Window != nullptr)
+ {
+ if (a_Player->GetWindow() != Window)
+ {
+ a_Player->OpenWindow(Window);
+ }
+ }
+
+ if (m_IsBrewing)
+ {
+ BroadcastProgress(0, m_NeedBrewingTime - m_TimeBrewed);
+ }
+ else
+ {
+ BroadcastProgress(0, 0);
+ }
+}
+
+
+
+
+
+bool cBrewingstandEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
+{
+ UNUSED(a_Dt);
+
+ if (!m_IsBrewing)
+ {
+ return false;
+ }
+
+ const cBrewingRecipes::cRecipe * Recipe = nullptr;
+ // The necessary brewing time, has been reached
+ if (m_TimeBrewed >= m_NeedBrewingTime)
+ {
+ BroadcastProgress(0, 0);
+ m_IsBrewing = false;
+ m_TimeBrewed = 0;
+
+ // Return if the hook has been canceled
+ if (cPluginManager::Get()->CallHookBrewingCompleting(*m_World, *this))
+ {
+ return false;
+ }
+
+ // Decrease item count, full stacks are allowed in the ingredient slot
+ cItem Ingredient = m_Contents.GetSlot(bsIngredient);
+ Ingredient.m_ItemCount -= 1;
+ m_Contents.SetSlot(bsIngredient, Ingredient);
+
+ // Loop over all bottle slots and update available bottles
+ for (int i = 0; i < 3; i++)
+ {
+ if (m_Contents.GetSlot(i).IsEmpty() || (m_CurrentBrewingRecipes[i] == nullptr))
+ {
+ continue;
+ }
+
+ Recipe = m_CurrentBrewingRecipes[i];
+ m_Contents.SetSlot(i, Recipe->Output->CopyOne());
+ }
+
+ // Brewing process completed
+ cPluginManager::Get()->CallHookBrewingCompleted(*m_World, *this);
+
+ return true;
+ }
+
+ m_TimeBrewed++;
+ UpdateProgressBars(false);
+ return false;
+}
+
+
+
+
+
+
+void cBrewingstandEntity::SendTo(cClientHandle & a_Client)
+{
+ // Nothing needs to be sent
+ UNUSED(a_Client);
+}
+
+
+
+
+
+void cBrewingstandEntity::BroadcastProgress(short a_ProgressbarID, short a_Value)
+{
+ cWindow * Window = GetWindow();
+ if (Window != nullptr)
+ {
+ Window->SetProperty(a_ProgressbarID, a_Value);
+ }
+}
+
+
+
+
+
+
+void cBrewingstandEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
+{
+ super::OnSlotChanged(a_ItemGrid, a_SlotNum);
+
+ if (m_IsDestroyed)
+ {
+ return;
+ }
+
+ ASSERT(a_ItemGrid == &m_Contents);
+
+ // Check if still a item is in the ingredient slot
+ if (GetSlot(bsIngredient).IsEmpty())
+ {
+ if (m_IsBrewing)
+ {
+ // Cancel brewing
+ BroadcastProgress(0, 0);
+ m_IsBrewing = false;
+ m_TimeBrewed = 0;
+ }
+ return;
+ }
+
+ // Recheck the bottles
+ cBrewingRecipes * BR = cRoot::Get()->GetBrewingRecipes();
+ const cBrewingRecipes::cRecipe * Recipe = nullptr;
+ bool Stop = true;
+ for (int i = 0; i < 3; i++)
+ {
+ if (GetSlot(i).IsEmpty())
+ {
+ m_CurrentBrewingRecipes[i] = nullptr;
+ m_Results[i].Clear();
+ continue;
+ }
+
+ if (m_CurrentBrewingRecipes[i] != nullptr)
+ {
+ Recipe = m_CurrentBrewingRecipes[i];
+ if (Recipe->Ingredient->IsEqual(GetSlot(bsIngredient)) && Recipe->Input->IsEqual(GetSlot(i)))
+ {
+ Stop = false;
+ continue;
+ }
+ }
+
+ Recipe = BR->GetRecipeFrom(m_Contents.GetSlot(i), m_Contents.GetSlot(bsIngredient));
+ if (Recipe != nullptr)
+ {
+ // Found a brewing recipe for the items
+ m_CurrentBrewingRecipes[i] = Recipe;
+ m_Results[i] = Recipe->Output->CopyOne();
+ Stop = false;
+ }
+ }
+
+ if (Stop)
+ {
+ if (m_IsBrewing)
+ {
+ // Cancel brewing
+ BroadcastProgress(0, 0);
+ m_IsBrewing = false;
+ m_TimeBrewed = 0;
+ }
+ return;
+ }
+
+ // Start brewing process, if not running
+ if (!m_IsBrewing)
+ {
+ m_IsBrewing = true;
+ }
+}
+
+
+
+
+
+void cBrewingstandEntity::UpdateProgressBars(bool a_ForceUpdate)
+{
+ /** Sending an update every 3th tick, using a higher value lets look the progressbar ugly */
+ if (!a_ForceUpdate && (m_World->GetWorldAge() % 3 != 0))
+ {
+ return;
+ }
+
+ BroadcastProgress(0, m_NeedBrewingTime - m_TimeBrewed);
+}
+
+
+
+
+
+void cBrewingstandEntity::setTimeBrewed(short a_TimeBrewed)
+{
+ m_TimeBrewed = a_TimeBrewed;
+}
+
+
+
+
+
+void cBrewingstandEntity::ContinueBrewing(void)
+{
+ // Continue brewing if number is greater than 0
+ if (m_TimeBrewed > 0)
+ {
+ m_IsBrewing = true;
+ }
+}
+
+
+
+
+
+void cBrewingstandEntity::GetRecipes(void)
+{
+ if (GetSlot(3).IsEmpty())
+ {
+ return;
+ }
+
+ cBrewingRecipes * BR = cRoot::Get()->GetBrewingRecipes();
+ const cBrewingRecipes::cRecipe * Recipe = nullptr;
+ for (int i = 0; i < 3; i++)
+ {
+ if (GetSlot(i).IsEmpty())
+ {
+ continue;
+ }
+ Recipe = BR->GetRecipeFrom(GetSlot(i), GetSlot(bsIngredient));
+ if (Recipe != nullptr)
+ {
+ m_CurrentBrewingRecipes[i] = Recipe;
+ m_Results[i] = Recipe->Output->CopyOne();
+ }
+ }
+}
+
+
+
+
+