Cuberite
A lightweight, fast and extensible game server for Minecraft
BrewingstandEntity.cpp
Go to the documentation of this file.
1 
2 #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
3 
4 #include "BrewingstandEntity.h"
5 #include "../Bindings/PluginManager.h"
6 #include "../UI/BrewingstandWindow.h"
7 #include "../Entities/Player.h"
8 #include "../Chunk.h"
9 
10 
11 
12 
13 
14 cBrewingstandEntity::cBrewingstandEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World):
15  super(a_BlockType, a_BlockMeta, a_Pos, ContentsWidth, ContentsHeight, a_World),
16  m_IsDestroyed(false),
17  m_IsBrewing(false),
18  m_TimeBrewed(0),
19  m_RemainingFuel(0)
20 {
21  m_Contents.AddListener(*this);
22 }
23 
24 
25 
26 
27 
29 {
30  // Tell window its owner is destroyed
31  cWindow * Window = GetWindow();
32  if (Window != nullptr)
33  {
34  Window->OwnerDestroyed();
35  }
36 }
37 
38 
39 
40 
41 
43 {
44  m_IsDestroyed = true;
46 }
47 
48 
49 
50 
51 
53 {
54  super::CopyFrom(a_Src);
55  auto & src = static_cast<const cBrewingstandEntity &>(a_Src);
56  m_IsBrewing = src.m_IsBrewing;
57  for (size_t i = 0; i < ARRAYCOUNT(m_CurrentBrewingRecipes); ++i)
58  {
59  m_CurrentBrewingRecipes[i] = src.m_CurrentBrewingRecipes[i];
60  }
61  for (size_t i = 0; i < ARRAYCOUNT(m_Results); ++i)
62  {
63  m_Results[i] = src.m_Results[i];
64  }
65  m_TimeBrewed = src.m_TimeBrewed;
66  m_RemainingFuel = src.m_RemainingFuel;
67 }
68 
69 
70 
71 
72 
74 {
75  // Nothing needs to be sent
76  UNUSED(a_Client);
77 }
78 
79 
80 
81 
82 
83 bool cBrewingstandEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
84 {
85  UNUSED(a_Dt);
86 
87  if (!m_IsBrewing)
88  {
89  return false;
90  }
91 
92  // The necessary brewing time, has been reached
94  {
95  BroadcastProgress(0, 0);
96  m_IsBrewing = false;
97  m_TimeBrewed = 0;
98 
99  // Return if the hook has been cancelled
100  if (cPluginManager::Get()->CallHookBrewingCompleting(*m_World, *this))
101  {
102  return false;
103  }
104 
105  // Decrease item count, full stacks are allowed in the ingredient slot
106  cItem Ingredient = m_Contents.GetSlot(bsIngredient);
107  Ingredient.m_ItemCount -= 1;
108  m_Contents.SetSlot(bsIngredient, Ingredient);
109 
110  // Fuel slot
111  m_RemainingFuel--;
112  if (m_RemainingFuel <= 0)
113  {
115  {
116  cItem Fuel = m_Contents.GetSlot(bsFuel);
117  Fuel.m_ItemCount -= 1;
118  m_Contents.SetSlot(bsFuel, Fuel);
119  m_RemainingFuel = 20;
121  }
122  }
123  else
124  {
126  }
127 
128 
129  // Loop over all bottle slots and update available bottles
130  const cBrewingRecipes::cRecipe * Recipe = nullptr;
131  for (int i = 0; i < 3; i++)
132  {
133  if (m_Contents.GetSlot(i).IsEmpty() || (m_CurrentBrewingRecipes[i] == nullptr))
134  {
135  continue;
136  }
137 
138  Recipe = m_CurrentBrewingRecipes[i];
139  m_Contents.SetSlot(i, Recipe->Output.CopyOne());
140  }
141 
142  // Brewing process completed
144  return true;
145  }
146 
147  m_TimeBrewed++;
148  UpdateProgressBars(false);
149  return false;
150 }
151 
152 
153 
154 
155 
157 {
158  cWindow * Window = GetWindow();
159  if (Window == nullptr)
160  {
161  OpenWindow(new cBrewingstandWindow(this));
162  Window = GetWindow();
163  }
164 
165  if (Window != nullptr)
166  {
167  if (a_Player->GetWindow() != Window)
168  {
169  a_Player->OpenWindow(*Window);
170  }
171  }
172 
173  if (m_IsBrewing)
174  {
176  }
177  else
178  {
179  BroadcastProgress(0, 0);
180  }
182  return true;
183 }
184 
185 
186 
187 
188 
189 void cBrewingstandEntity::BroadcastProgress(short a_ProgressbarID, short a_Value)
190 {
191  cWindow * Window = GetWindow();
192  if (Window != nullptr)
193  {
194  Window->SetProperty(a_ProgressbarID, a_Value);
195  }
196 }
197 
198 
199 
200 
201 
202 void cBrewingstandEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
203 {
204  super::OnSlotChanged(a_ItemGrid, a_SlotNum);
205 
206  if (m_IsDestroyed)
207  {
208  return;
209  }
210 
211  ASSERT(a_ItemGrid == &m_Contents);
212 
213  // Check for fuel
214  if (m_RemainingFuel <= 0)
215  {
216  if (GetSlot(bsFuel).IsEmpty())
217  {
218  // No remaining fuel stop brewing and bail out
219  m_IsBrewing = false;
220  return;
221  }
222  else
223  {
224  // Fuel is available, refill
225  m_RemainingFuel = 20;
227  cItem Fuel = m_Contents.GetSlot(bsFuel);
228  Fuel.m_ItemCount -= 1;
229  m_Contents.SetSlot(bsFuel, Fuel);
230  }
231  }
232 
233  // Check if still a item is in the ingredient slot
234  if (GetSlot(bsIngredient).IsEmpty())
235  {
236  if (m_IsBrewing)
237  {
238  // Cancel brewing
239  BroadcastProgress(0, 0);
240  m_IsBrewing = false;
241  m_TimeBrewed = 0;
242  }
243  return;
244  }
245 
246  // Recheck the bottles
248  const cBrewingRecipes::cRecipe * Recipe = nullptr;
249  bool Stop = true;
250  for (int i = 0; i < 3; i++)
251  {
252  if (GetSlot(i).IsEmpty())
253  {
254  m_CurrentBrewingRecipes[i] = nullptr;
255  m_Results[i].Clear();
256  continue;
257  }
258 
259  if (m_CurrentBrewingRecipes[i] != nullptr)
260  {
261  Recipe = m_CurrentBrewingRecipes[i];
262  if (Recipe->Ingredient.IsEqual(GetSlot(bsIngredient)) && Recipe->Input.IsEqual(GetSlot(i)))
263  {
264  Stop = false;
265  continue;
266  }
267  }
268 
270  if (Recipe != nullptr)
271  {
272  // Found a brewing recipe for the items
273  m_CurrentBrewingRecipes[i] = Recipe;
274  m_Results[i] = Recipe->Output.CopyOne();
275  Stop = false;
276  }
277  }
278 
279  if (Stop)
280  {
281  if (m_IsBrewing)
282  {
283  // Cancel brewing
284  BroadcastProgress(0, 0);
285  m_IsBrewing = false;
286  m_TimeBrewed = 0;
287  }
288  return;
289  }
290 
291  // Start brewing process, if not running
292  if (!m_IsBrewing)
293  {
294  m_IsBrewing = true;
295  }
296 }
297 
298 
299 
300 
301 
303 {
305  if (!a_ForceUpdate && (m_World->GetWorldAge() % 3 != 0))
306  {
307  return;
308  }
309 
311 }
312 
313 
314 
315 
316 
318 {
319  // Continue brewing if number is greater than 0
320  if ((m_TimeBrewed > 0) && (m_RemainingFuel > 0))
321  {
322  m_IsBrewing = true;
323  }
324 }
325 
326 
327 
328 
329 
331 {
332  if (GetSlot(bsIngredient).IsEmpty())
333  {
334  return;
335  }
336 
338  const cBrewingRecipes::cRecipe * Recipe = nullptr;
339  for (int i = 0; i < 3; i++)
340  {
341  if (GetSlot(i).IsEmpty())
342  {
343  continue;
344  }
345  Recipe = BR->GetRecipeFrom(GetSlot(i), GetSlot(bsIngredient));
346  if (Recipe != nullptr)
347  {
348  m_CurrentBrewingRecipes[i] = Recipe;
349  m_Results[i] = Recipe->Output.CopyOne();
350  }
351  }
352 }
353 
354 
355 
356 
357 
cItem m_Results[3]
Result items for the bottle inputs.
virtual bool UsedBy(cPlayer *a_Player) override
Called when a player uses this entity; should open the UI window.
void UpdateProgressBars(bool a_ForceUpdate=false)
Broadcasts progressbar updates, if needed.
bool m_IsBrewing
Set to true if the brewing stand is brewing an item.
short m_TimeBrewed
Amount of ticks that the current item has been brewed.
cBrewingstandEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld *a_World)
Constructor used for normal operation.
virtual ~cBrewingstandEntity() override
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:42
const cItem & GetSlot(int a_SlotNum) const
void Clear(void)
Definition: Item.h:106
void LoadRecipes(void)
Gets the recipes.
cWindow * GetWindow(void)
Definition: Player.h:239
short m_RemainingFuel
The remaining fuel for the brewing stand.
Definition: Player.h:27
virtual void CopyFrom(const cBlockEntity &a_Src) override
Copies all properties of a_Src into this entity, except for its m_World and location.
bool IsEmpty(void) const
Definition: Item.h:116
void OpenWindow(cWindow *a_Window)
Definition: WindowOwner.h:34
void OwnerDestroyed(void)
Definition: Window.cpp:352
virtual void Destroy() override
bool IsEqual(const cItem &a_Item) const
Definition: Item.h:123
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:45
virtual void Destroy(void) override
static cPluginManager * Get(void)
Returns the instance of the Plugin Manager (there is only ever one)
Definition: Chunk.h:49
cItem CopyOne(void) const
Returns a copy of this item with m_ItemCount set to 1.
Definition: Item.cpp:15
const cRecipe * GetRecipeFrom(const cItem &a_Input, const cItem &a_Ingredient) const
Returns a recipe for the specified input, nullptr if no recipe found.
cWorld * m_World
Definition: BlockEntity.h:155
void AddListener(cListener &a_Listener)
Adds a callback that gets called whenever a slot changes.
Definition: ItemGrid.cpp:785
cBrewingRecipes * GetBrewingRecipes(void)
Definition: Root.h:92
virtual void SendTo(cClientHandle &a_Client) override
Sends the packet defining the block entity to the client specified.
cWindow * GetWindow(void) const
Definition: WindowOwner.h:40
Definition: World.h:65
char m_ItemCount
Definition: Item.h:210
virtual Int64 GetWorldAge(void) const override
Definition: World.h:109
#define ASSERT(x)
Definition: Globals.h:335
bool m_IsDestroyed
Set to true when the brewing stand entity has been destroyed to prevent the block being set again...
const cBrewingRecipes::cRecipe * m_CurrentBrewingRecipes[3]
Store the current brewing recipes.
#define UNUSED
Definition: Globals.h:152
virtual void CopyFrom(const cBlockEntity &a_Src) override
Copies all properties of a_Src into this entity, except for its m_World and location.
virtual void SetProperty(short a_Property, short a_Value)
Updates a numerical property associated with the window.
Definition: Window.cpp:751
void ContinueBrewing(void)
Starts the brewing proccess.
virtual void OnSlotChanged(cItemGrid *a_ItemGrid, int a_SlotNum) override
Called whenever a slot changes.
static cRoot * Get()
Definition: Root.h:51
bool CallHookBrewingCompleted(cWorld &a_World, cBrewingstandEntity &a_Brewingstand)
Represents a UI window.
Definition: Window.h:53
void BroadcastProgress(short a_ProgressbarID, short a_Value)
Sends the specified progressbar value to all clients of the window.
virtual void OnSlotChanged(cItemGrid *a_Grid, int a_SlotNum) override
Called whenever a slot changes.
const short m_NeedBrewingTime
Brewing time is 400 ticks.
const cItem & GetSlot(int a_X, int a_Y) const
Definition: ItemGrid.cpp:96
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Definition: Globals.h:290
Definition: Item.h:36
void OpenWindow(cWindow &a_Window)
Opens the specified window; closes the current one first using CloseWindow()
Definition: Player.cpp:1349
virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
Ticks the entity; returns true if the chunk should be marked as dirty as a result of this ticking...
void SetSlot(int a_X, int a_Y, const cItem &a_Item)
Definition: ItemGrid.cpp:121