Cuberite
A lightweight, fast and extensible game server for Minecraft
Prefab.cpp
Go to the documentation of this file.
1 
2 // Prefab.cpp
3 
4 /*
5 Implements the cPrefab class, representing a cPiece descendant for the cPieceGenerator that
6 uses a prefabricate in a cBlockArea for drawing itself.
7 */
8 
9 #include "Globals.h"
10 #include "Prefab.h"
11 #include "../WorldStorage/SchematicFileSerializer.h"
12 #include "ChunkDesc.h"
13 #include "../BlockInfo.h"
14 
15 
16 
17 
18 
20  m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ),
21  m_HitBox(
22  {a_Def.m_HitboxMinX, a_Def.m_HitboxMinY, a_Def.m_HitboxMinZ},
23  {a_Def.m_HitboxMaxX, a_Def.m_HitboxMaxY, a_Def.m_HitboxMaxZ}
24  ),
25  m_AllowedRotations(a_Def.m_AllowedRotations),
26  m_MergeStrategy(a_Def.m_MergeStrategy),
27  m_ExtendFloorStrategy(a_Def.m_ExtendFloorStrategy),
28  m_DefaultWeight(a_Def.m_DefaultWeight),
29  m_AddWeightIfSame(a_Def.m_AddWeightIfSame),
30  m_MoveToGround(a_Def.m_MoveToGround)
31 {
32  m_BlockArea[0].Create(m_Size);
33  CharMap cm;
34  ParseCharMap(cm, a_Def.m_CharMap);
35  ParseBlockImage(cm, a_Def.m_Image);
36  ParseConnectors(a_Def.m_Connectors);
37  ParseDepthWeight(a_Def.m_DepthWeight);
38 
39  AddRotatedBlockAreas();
40 }
41 
42 
43 
44 
45 
46 cPrefab::cPrefab(const cBlockArea & a_Image, int a_AllowedRotations) :
47  m_Size(a_Image.GetSize()),
48  m_AllowedRotations(a_AllowedRotations),
49  m_MergeStrategy(cBlockArea::msOverwrite),
50  m_ExtendFloorStrategy(efsNone),
51  m_DefaultWeight(1),
52  m_AddWeightIfSame(0),
53  m_MoveToGround(false)
54 {
55  m_HitBox.p1.Set(0, 0, 0);
56  m_HitBox.p2.Set(m_Size.x - 1, m_Size.y - 1, m_Size.z - 1);
57  m_BlockArea[0].CopyFrom(a_Image);
59 }
60 
61 
62 
63 
64 
65 cPrefab::cPrefab(const cBlockArea & a_Image) :
66  m_Size(a_Image.GetSize()),
67  m_AllowedRotations(0),
68  m_MergeStrategy(cBlockArea::msOverwrite),
69  m_ExtendFloorStrategy(efsNone),
70  m_DefaultWeight(1),
71  m_AddWeightIfSame(0),
72  m_MoveToGround(false)
73 {
74  m_HitBox.p1.Set(0, 0, 0);
75  m_HitBox.p2.Set(m_Size.x - 1, m_Size.y - 1, m_Size.z - 1);
76  m_BlockArea[0].CopyFrom(a_Image);
77 }
78 
79 
80 
81 
82 
83 cPrefab::cPrefab(const AString & a_BlockDefinitions, const AString & a_BlockData, int a_SizeX, int a_SizeY, int a_SizeZ) :
84  m_Size(a_SizeX, a_SizeY, a_SizeZ),
85  m_AllowedRotations(0),
86  m_MergeStrategy(cBlockArea::msOverwrite),
87  m_ExtendFloorStrategy(efsNone),
88  m_DefaultWeight(1),
89  m_AddWeightIfSame(0),
90  m_MoveToGround(false)
91 {
92  m_HitBox.p1.Set(0, 0, 0);
93  m_HitBox.p2.Set(m_Size.x - 1, m_Size.y - 1, m_Size.z - 1);
95  CharMap cm;
96  ParseCharMap(cm, a_BlockDefinitions.c_str());
97  ParseBlockImage(cm, a_BlockData.c_str());
98 }
99 
100 
101 
102 
103 
105 {
106  // 1 CCW rotation:
107  if ((m_AllowedRotations & 0x01) != 0)
108  {
110  m_BlockArea[1].RotateCCW();
111  }
112 
113  // 2 rotations are the same as mirroring twice; mirroring is faster because it has no reallocations
114  if ((m_AllowedRotations & 0x02) != 0)
115  {
117  m_BlockArea[2].MirrorXY();
118  m_BlockArea[2].MirrorYZ();
119  }
120 
121  // 3 CCW rotations = 1 CW rotation:
122  if ((m_AllowedRotations & 0x04) != 0)
123  {
125  m_BlockArea[3].RotateCW();
126  }
127 }
128 
129 
130 
131 
132 
133 void cPrefab::Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const
134 {
135  Draw(a_Dest, a_Placement->GetCoords(), a_Placement->GetNumCCWRotations());
136 }
137 
138 
139 
140 
141 
142 void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumRotations) const
143 {
144  // Draw the basic image:
145  Vector3i Placement(a_Placement);
146  int ChunkStartX = a_Dest.GetChunkX() * cChunkDef::Width;
147  int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width;
148  Placement.Move(-ChunkStartX, 0, -ChunkStartZ);
149  const cBlockArea & Image = m_BlockArea[a_NumRotations];
150 
151  // If the placement is outside this chunk, bail out:
152  if (
153  (Placement.x > cChunkDef::Width) || (Placement.x + Image.GetSizeX() < 0) ||
154  (Placement.z > cChunkDef::Width) || (Placement.z + Image.GetSizeZ() < 0)
155  )
156  {
157  return;
158  }
159 
160  if (m_Modifiers.size() == 0)
161  {
162  // Write the image:
163  a_Dest.WriteBlockArea(Image, Placement.x, Placement.y, Placement.z, m_MergeStrategy);
164  }
165  else
166  {
167  cBlockArea RandomizedImage;
168  Image.CopyTo(RandomizedImage);
169 
170  for (size_t i = 0; i < m_Modifiers.size(); i++)
171  {
172  m_Modifiers[i]->Modify(RandomizedImage, a_Placement, a_NumRotations);
173  }
174 
175  // Write the modified image:
176  a_Dest.WriteBlockArea(RandomizedImage, Placement.x, Placement.y, Placement.z, m_MergeStrategy);
177  }
178 
179  // If requested, draw the floor (from the bottom of the prefab down to the nearest non-air)
180  switch (m_ExtendFloorStrategy)
181  {
182  case efsNone: break; // Nothing needed
184  {
185  int MaxX = Image.GetSizeX();
186  int MaxZ = Image.GetSizeZ();
187  for (int z = 0; z < MaxZ; z++)
188  {
189  int RelZ = Placement.z + z;
190  if ((RelZ < 0) || (RelZ >= cChunkDef::Width))
191  {
192  // Z coord outside the chunk
193  continue;
194  }
195  for (int x = 0; x < MaxX; x++)
196  {
197  int RelX = Placement.x + x;
198  if ((RelX < 0) || (RelX >= cChunkDef::Width))
199  {
200  // X coord outside the chunk
201  continue;
202  }
204  NIBBLETYPE BlockMeta;
205  Image.GetRelBlockTypeMeta(x, 0, z, BlockType, BlockMeta);
207  {
208  // Do not expand air nor sponge blocks
209  continue;
210  }
211  for (int y = Placement.y - 1; y >= 0; y--)
212  {
213  BLOCKTYPE ExistingBlock = a_Dest.GetBlockType(RelX, y, RelZ);
214  if (ExistingBlock != E_BLOCK_AIR)
215  {
216  // End the expansion for this column, reached the end
217  break;
218  }
219  a_Dest.SetBlockTypeMeta(RelX, y, RelZ, BlockType, BlockMeta);
220  } // for y
221  } // for x
222  } // for z
223  break;
224  } // efsRepeatBottomTillNonAir
225 
227  {
228  int MaxX = Image.GetSizeX();
229  int MaxZ = Image.GetSizeZ();
230  for (int z = 0; z < MaxZ; z++)
231  {
232  int RelZ = Placement.z + z;
233  if ((RelZ < 0) || (RelZ >= cChunkDef::Width))
234  {
235  // Z coord outside the chunk
236  continue;
237  }
238  for (int x = 0; x < MaxX; x++)
239  {
240  int RelX = Placement.x + x;
241  if ((RelX < 0) || (RelX >= cChunkDef::Width))
242  {
243  // X coord outside the chunk
244  continue;
245  }
247  NIBBLETYPE BlockMeta;
248  Image.GetRelBlockTypeMeta(x, 0, z, BlockType, BlockMeta);
250  {
251  // Do not expand air nor sponge blocks
252  continue;
253  }
254  for (int y = Placement.y - 1; y >= 0; y--)
255  {
256  BLOCKTYPE ExistingBlock = a_Dest.GetBlockType(RelX, y, RelZ);
257  if (cBlockInfo::IsSolid(ExistingBlock))
258  {
259  // End the expansion for this column, reached the end
260  break;
261  }
262  a_Dest.SetBlockTypeMeta(RelX, y, RelZ, BlockType, BlockMeta);
263  } // for y
264  } // for x
265  } // for z
266  break;
267  } // efsRepeatBottomTillSolid
268  }
269 }
270 
271 
272 
273 
274 
275 bool cPrefab::HasConnectorType(int a_ConnectorType) const
276 {
277  for (cConnectors::const_iterator itr = m_Connectors.begin(), end = m_Connectors.end(); itr != end; ++itr)
278  {
279  if (itr->m_Type == a_ConnectorType)
280  {
281  return true;
282  }
283  } // for itr - m_Connectors[]
284  return false;
285 }
286 
287 
288 
289 
290 
291 int cPrefab::GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector) const
292 {
293  // Use the default or per-depth weight:
294  cDepthWeight::const_iterator itr = m_DepthWeight.find(a_PlacedPiece.GetDepth() + 1);
295  int res = (itr == m_DepthWeight.end()) ? m_DefaultWeight : itr->second;
296 
297  // If the piece is the same as the parent, apply the m_AddWeightIfSame modifier:
298  const cPiece * ParentPiece = &a_PlacedPiece.GetPiece();
299  const cPiece * ThisPiece = this;
300  if (ThisPiece == ParentPiece)
301  {
302  res += m_AddWeightIfSame;
303  }
304  return res;
305 }
306 
307 
308 
309 
310 
311 void cPrefab::SetDefaultWeight(int a_DefaultWeight)
312 {
313  m_DefaultWeight = a_DefaultWeight;
314 }
315 
316 
317 
318 
319 
320 void cPrefab::AddConnector(int a_RelX, int a_RelY, int a_RelZ, cPiece::cConnector::eDirection a_Direction, int a_Type)
321 {
322  m_Connectors.emplace_back(a_RelX, a_RelY, a_RelZ, a_Type, a_Direction);
323 }
324 
325 
326 
327 
328 
329 void cPrefab::SetAllowedRotations(int a_AllowedRotations)
330 {
331  m_AllowedRotations = a_AllowedRotations;
333 }
334 
335 
336 
337 
338 
339 void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef)
340 {
341  ASSERT(a_CharMapDef != nullptr);
342 
343  // Initialize the charmap to all-invalid values:
344  for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++)
345  {
346  a_CharMapOut[i].m_BlockType = 0;
347  a_CharMapOut[i].m_BlockMeta = 16; // Mark unassigned entries with a meta that is impossible otherwise
348  }
349 
350  // Process the lines in the definition:
351  AStringVector Lines = StringSplitAndTrim(a_CharMapDef, "\n");
352  for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr)
353  {
354  AStringVector CharDef = StringSplitAndTrim(*itr, ":");
355  size_t NumElements = CharDef.size();
356  if ((NumElements < 2) || CharDef[0].empty() || CharDef[1].empty())
357  {
358  LOGWARNING("Bad prefab CharMap definition line: \"%s\", skipping.", itr->c_str());
359  continue;
360  }
361  unsigned char Src = static_cast<unsigned char>(CharDef[0][0]);
362  ASSERT(a_CharMapOut[Src].m_BlockMeta == 16); // This letter has not been assigned yet?
363  a_CharMapOut[Src].m_BlockType = static_cast<BLOCKTYPE>(atoi(CharDef[1].c_str()));
364  NIBBLETYPE BlockMeta = 0;
365  if ((NumElements >= 3) && !CharDef[2].empty())
366  {
367  BlockMeta = static_cast<NIBBLETYPE>(atoi(CharDef[2].c_str()));
368  ASSERT((BlockMeta <= 15));
369  }
370  a_CharMapOut[Src].m_BlockMeta = BlockMeta;
371  } // for itr - Lines[]
372 }
373 
374 
375 
376 
377 
378 void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage)
379 {
380  // Map each letter in the a_BlockImage (from the in-source definition) to real blocktype / blockmeta:
381  for (int y = 0; y < m_Size.y; y++)
382  {
383  for (int z = 0; z < m_Size.z; z++)
384  {
385  const unsigned char * BlockImage = reinterpret_cast<const unsigned char *>(a_BlockImage + y * m_Size.x * m_Size.z + z * m_Size.x);
386  for (int x = 0; x < m_Size.x; x++)
387  {
388  const sBlockTypeDef & MappedValue = a_CharMap[BlockImage[x]];
389  ASSERT(MappedValue.m_BlockMeta != 16); // Using a letter not defined in the CharMap?
390  m_BlockArea[0].SetRelBlockTypeMeta(x, y, z, MappedValue.m_BlockType, MappedValue.m_BlockMeta);
391  }
392  }
393  }
394 }
395 
396 
397 
398 
399 
400 void cPrefab::ParseConnectors(const char * a_ConnectorsDef)
401 {
402  ASSERT(a_ConnectorsDef != nullptr);
403 
404  AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n");
405  for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr)
406  {
407  if (itr->empty())
408  {
409  continue;
410  }
411  // Split into components: "Type: X, Y, Z: Direction":
412  AStringVector Defs = StringSplitAndTrim(*itr, ":");
413  if (Defs.size() != 3)
414  {
415  LOGWARNING("Bad prefab Connector definition line: \"%s\", skipping.", itr->c_str());
416  continue;
417  }
418  AStringVector Coords = StringSplitAndTrim(Defs[1], ",");
419  if (Coords.size() != 3)
420  {
421  LOGWARNING("Bad prefab Connector coords definition: \"%s\", skipping.", Defs[1].c_str());
422  continue;
423  }
424 
425  // Check that the Direction is valid:
428  {
429  LOGWARNING("Bad prefab Connector direction: \"%s\", skipping.", Defs[2].c_str());
430  continue;
431  }
432 
433  // Add the connector:
435  atoi(Coords[0].c_str()), atoi(Coords[1].c_str()), atoi(Coords[2].c_str()), // Connector pos
436  atoi(Defs[0].c_str()), // Connector type
437  Direction
438  ));
439  } // for itr - Lines[]
440 }
441 
442 
443 
444 
445 
446 void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef)
447 {
448  // The member needn't be defined at all, if so, skip:
449  if (a_DepthWeightDef == nullptr)
450  {
451  return;
452  }
453 
454  // Split into individual records: "Record | Record | Record"
455  AStringVector Defs = StringSplitAndTrim(a_DepthWeightDef, "|");
456 
457  // Add each record's contents:
458  for (AStringVector::const_iterator itr = Defs.begin(), end = Defs.end(); itr != end; ++itr)
459  {
460  // Split into components: "Depth : Weight"
461  AStringVector Components = StringSplitAndTrim(*itr, ":");
462  if (Components.size() != 2)
463  {
464  LOGWARNING("Bad prefab DepthWeight record: \"%s\", skipping.", itr->c_str());
465  continue;
466  }
467 
468  // Parse depth:
469  int Depth = atoi(Components[0].c_str());
470  if ((Depth == 0) && (Components[0] != "0"))
471  {
472  LOGWARNING("Bad prefab DepthWeight record, cannot parse depth \"%s\", skipping.", Components[0].c_str());
473  continue;
474  }
475 
476  // Parse weight:
477  int Weight = atoi(Components[1].c_str());
478  if ((Weight == 0) && (Components[1] != "0"))
479  {
480  LOGWARNING("Bad prefab DepthWeight record, cannot parse weight \"%s\", skipping.", Components[1].c_str());
481  continue;
482  }
483 
484  // Save to map:
485  ASSERT(m_DepthWeight.find(Depth) == m_DepthWeight.end()); // Not a duplicate
486  m_DepthWeight[Depth] = Weight;
487  } // for itr - Defs[]
488 }
489 
490 
491 
492 
493 
495 {
496  return m_Connectors;
497 }
498 
499 
500 
501 
502 
504 {
505  return m_Size;
506 }
507 
508 
509 
510 
511 
513 {
514  return m_HitBox;
515 }
516 
517 
518 
519 
520 
521 bool cPrefab::CanRotateCCW(int a_NumRotations) const
522 {
523  // Either zero rotations
524  // Or the proper bit in m_AllowedRotations is set
525  return (a_NumRotations == 0) || ((m_AllowedRotations & (1 << ((a_NumRotations + 3) % 4))) != 0);
526 }
527 
528 
529 
530 
@ E_BLOCK_SPONGE
Definition: BlockType.h:29
@ E_BLOCK_AIR
Definition: BlockType.h:10
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
Definition: ChunkDef.h:44
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:41
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Definition: Globals.h:231
#define ASSERT(x)
Definition: Globals.h:276
void LOGWARNING(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:67
BlockType
Definition: BlockTypes.h:4
Direction
AStringVector StringSplitAndTrim(const AString &str, const AString &delim)
Split the string at any of the listed delimiters and trim each value.
std::vector< AString > AStringVector
Definition: StringUtils.h:12
std::string AString
Definition: StringUtils.h:11
void Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes=baTypes|baMetas|baBlockEntities)
Creates a new area of the specified size and contents.
Definition: BlockArea.cpp:338
void GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
Definition: BlockArea.cpp:1849
void SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Definition: BlockArea.cpp:1796
void MirrorYZ(void)
Mirrors the entire area around the YZ plane.
Definition: BlockArea.cpp:1275
void MirrorXY(void)
Mirrors the entire area around the XY plane.
Definition: BlockArea.cpp:1161
void CopyFrom(const cBlockArea &a_From)
Copies the contents from the specified BlockArea into this object.
Definition: BlockArea.cpp:587
void RotateCW(void)
Rotates the entire area clockwise around the Y axis.
Definition: BlockArea.cpp:1101
void RotateCCW(void)
Rotates the entire area counter-clockwise around the Y axis.
Definition: BlockArea.cpp:1041
int GetSizeZ(void) const
Definition: BlockArea.h:349
int GetSizeX(void) const
Definition: BlockArea.h:347
void CopyTo(cBlockArea &a_Into) const
Copies this object's contents into the specified BlockArea.
Definition: BlockArea.cpp:544
static bool IsSolid(BLOCKTYPE Block)
Is this block solid (player cannot walk through)?
Definition: BlockInfo.cpp:892
static const int Width
Definition: ChunkDef.h:124
Definition: Cuboid.h:10
Vector3i p2
Definition: Cuboid.h:13
Vector3i p1
Definition: Cuboid.h:13
int GetChunkX() const
Definition: ChunkDesc.h:49
void SetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Definition: ChunkDesc.cpp:63
BLOCKTYPE GetBlockType(int a_RelX, int a_RelY, int a_RelZ) const
Definition: ChunkDesc.cpp:90
void WriteBlockArea(const cBlockArea &a_BlockArea, int a_RelX, int a_RelY, int a_RelZ, cBlockArea::eMergeStrategy a_MergeStrategy=cBlockArea::msOverwrite)
Writes the block area into the chunk, with its origin set at the specified relative coords.
Definition: ChunkDesc.cpp:271
int GetChunkZ() const
Definition: ChunkDesc.h:50
Represents a single piece.
Definition: PiecePool.h:21
cPieceModifiers m_Modifiers
The modifiers which are modifying piece's blocks.
Definition: PiecePool.h:185
std::vector< cConnector > cConnectors
Definition: PiecePool.h:95
static bool StringToDirection(const AString &a_Value, eDirection &a_Out)
Converts the string representation of a direction into the eDirection enum value.
Definition: PiecePool.cpp:401
Represents a single piece that has been placed to specific coords in the world.
Definition: PiecePool.h:328
int GetDepth(void) const
Definition: PiecePool.h:337
const Vector3i & GetCoords(void) const
Definition: PiecePool.h:334
int GetNumCCWRotations(void) const
Definition: PiecePool.h:335
const cPiece & GetPiece(void) const
Definition: PiecePool.h:333
sBlockTypeDef CharMap[256]
Maps letters in the sDef::m_Image onto a sBlockTypeDef block type definition.
Definition: Prefab.h:168
virtual Vector3i GetSize(void) const override
Returns the dimensions of this piece.
Definition: Prefab.cpp:503
cDepthWeight m_DepthWeight
Chances of this piece being used, per depth of the generated piece tree.
Definition: Prefab.h:205
void ParseCharMap(CharMap &a_CharMapOut, const char *a_CharMapDef)
Parses the CharMap in the definition into a CharMap binary data used for translating the definition i...
Definition: Prefab.cpp:339
int m_AllowedRotations
Bitmask, bit N set -> N rotations CCW supported.
Definition: Prefab.h:188
void ParseConnectors(const char *a_ConnectorsDef)
Parses the connectors definition text into m_Connectors member.
Definition: Prefab.cpp:400
void ParseDepthWeight(const char *a_DepthWeightDef)
Parses the per-depth weight into m_DepthWeight member.
Definition: Prefab.cpp:446
void AddConnector(int a_RelX, int a_RelY, int a_RelZ, cPiece::cConnector::eDirection a_Direction, int a_Type)
Adds the specified connector to the list of connectors this piece supports.
Definition: Prefab.cpp:320
cCuboid m_HitBox
The hitbox used for collision-checking between prefabs.
Definition: Prefab.h:182
int m_DefaultWeight
Chance of this piece being used, if no other modifier is active.
Definition: Prefab.h:198
void SetAllowedRotations(int a_AllowedRotations)
Sets the m_AllowedRotations bitmask and fills the m_BlockArea[] with rotated versions of m_BlockArea[...
Definition: Prefab.cpp:329
Vector3i m_Size
The size of the prefab.
Definition: Prefab.h:179
virtual bool CanRotateCCW(int a_NumRotations) const override
Returns true if the piece can be rotated CCW the specific number of 90-degree turns.
Definition: Prefab.cpp:521
void Draw(cChunkDesc &a_Dest, const cPlacedPiece *a_Placement) const
Draws the prefab into the specified chunk, according to the placement stored in the PlacedPiece.
Definition: Prefab.cpp:133
cBlockArea m_BlockArea[4]
The cBlockArea that contains the block definitions for the prefab.
Definition: Prefab.h:176
cConnectors m_Connectors
The connectors through which the piece connects to other pieces.
Definition: Prefab.h:185
virtual cConnectors GetConnectors(void) const override
Returns all of the available connectors that the piece has.
Definition: Prefab.cpp:494
cPrefab(const sDef &a_Def)
Creates a prefab from the provided definition.
Definition: Prefab.cpp:19
void AddRotatedBlockAreas(void)
Based on the m_AllowedRotations, adds rotated cBlockAreas to the m_BlockArea array.
Definition: Prefab.cpp:104
@ efsRepeatBottomTillSolid
Repeat the bottom-most block down until the first solid block; non-solids are overwritten.
Definition: Prefab.h:40
@ efsRepeatBottomTillNonAir
Repeat the bottom-most block down until the first non-air block.
Definition: Prefab.h:39
@ efsNone
No processing, the prefab is left "floating in the air".
Definition: Prefab.h:38
void SetDefaultWeight(int a_DefaultWeight)
Sets the (unmodified) DefaultWeight property for this piece.
Definition: Prefab.cpp:311
int m_AddWeightIfSame
The weight to add to this piece's base per-depth chance if the previous piece is the same.
Definition: Prefab.h:210
cBlockArea::eMergeStrategy m_MergeStrategy
The merge strategy to use when drawing the prefab into a block area.
Definition: Prefab.h:191
eExtendFloorStrategy m_ExtendFloorStrategy
How the prefab should handle not being on top of the ground.
Definition: Prefab.h:195
virtual cCuboid GetHitBox(void) const override
Returns the "hitbox" of this piece.
Definition: Prefab.cpp:512
void ParseBlockImage(const CharMap &a_CharMap, const char *a_BlockImage)
Parses the Image in the definition into m_BlockArea[0]'s block types and metas, using the specified C...
Definition: Prefab.cpp:378
int GetPieceWeight(const cPlacedPiece &a_PlacedPiece, const cPiece::cConnector &a_ExistingConnector) const
Returns the weight (chance) of this prefab generating as the next piece after the specified placed pi...
Definition: Prefab.cpp:291
bool HasConnectorType(int a_ConnectorType) const
Returns true if the prefab has any connector of the specified type.
Definition: Prefab.cpp:275
int m_HitboxMinZ
Definition: Prefab.h:50
int m_HitboxMinY
Definition: Prefab.h:50
int m_HitboxMinX
The hitbox used for collision-checking between prefabs.
Definition: Prefab.h:50
Packs complete definition of a single block, for per-letter assignment.
Definition: Prefab.h:162
NIBBLETYPE m_BlockMeta
Definition: Prefab.h:164
BLOCKTYPE m_BlockType
Definition: Prefab.h:163
T x
Definition: Vector3.h:17
void Move(T a_X, T a_Y, T a_Z)
Definition: Vector3.h:162
T y
Definition: Vector3.h:17
void Set(T a_x, T a_y, T a_z)
Definition: Vector3.h:42
T z
Definition: Vector3.h:17