summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Generating/Prefab.cpp139
-rw-r--r--src/Generating/Prefab.h83
2 files changed, 222 insertions, 0 deletions
diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp
new file mode 100644
index 000000000..824800119
--- /dev/null
+++ b/src/Generating/Prefab.cpp
@@ -0,0 +1,139 @@
+
+// Prefab.cpp
+
+/*
+Implements the cPrefab class, representing a cPiece descendant for the cPieceGenerator that
+uses a prefabricate in a cBlockArea for drawing itself.
+*/
+
+#include "Globals.h"
+#include "Prefab.h"
+#include "../WorldStorage/SchematicFileSerializer.h"
+
+
+
+
+
+cPrefab::cPrefab(const cPrefab::sDef & a_Def) :
+ m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ),
+ m_HitBox(0, 0, 0, a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ),
+ m_AllowedRotations(7), // TODO: All rotations allowed (not in the definition yet)
+ m_MergeStrategy(cBlockArea::msImprint)
+{
+ m_BlockArea.Create(m_Size);
+ CharMap cm;
+ ParseCharMap(cm, a_Def.m_CharMap);
+ ParseBlockImage(cm, a_Def.m_Image);
+}
+
+
+
+
+
+void cPrefab::Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement)
+{
+ Vector3i Placement = a_Placement->GetCoords();
+ Placement.Move(a_Dest.GetOrigin() * (-1));
+ a_Dest.Merge(m_BlockArea, Placement, m_MergeStrategy);
+
+}
+
+
+
+
+
+void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef)
+{
+ // Initialize the charmap to all-invalid values:
+ for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++)
+ {
+ a_CharMapOut[i] = -1;
+ }
+
+ // Process the lines in the definition:
+ AStringVector Lines = StringSplitAndTrim(a_CharMapDef, "\n");
+ for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr)
+ {
+ AStringVector CharDef = StringSplitAndTrim(*itr, ":");
+ size_t NumElements = CharDef.size();
+ if ((NumElements < 2) || CharDef[0].empty() || CharDef[1].empty())
+ {
+ LOGWARNING("Bad prefab CharMap definition line: \"%s\", skipping.", itr->c_str());
+ continue;
+ }
+ unsigned char Src = (unsigned char)CharDef[0][0];
+ BLOCKTYPE BlockType = (BLOCKTYPE)atoi(CharDef[1].c_str());
+ NIBBLETYPE BlockMeta = 0;
+ if ((NumElements >= 3) && !CharDef[2].empty())
+ {
+ BlockMeta = (NIBBLETYPE)atoi(CharDef[2].c_str());
+ ASSERT((BlockMeta >= 0) && (BlockMeta <= 15));
+ }
+ ASSERT(a_CharMapOut[Src] == -1); // Any duplicates letter-wise?
+ a_CharMapOut[Src] = (BlockType << 4) | BlockMeta;
+ } // for itr - Lines[]
+}
+
+
+
+
+
+void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage)
+{
+ // Map each letter in the a_BlockImage (from the in-source definition) to real blocktype / blockmeta:
+ for (int y = 0; y < m_Size.y; y++)
+ {
+ for (int z = 0; z < m_Size.z; z++)
+ {
+ const unsigned char * BlockImage = (const unsigned char *)a_BlockImage + y * m_Size.x * m_Size.z + z * m_Size.x;
+ for (int x = 0; x < m_Size.x; x++)
+ {
+ int MappedValue = a_CharMap[BlockImage[x]];
+ ASSERT(MappedValue != -1); // Using a letter not defined in the CharMap?
+ BLOCKTYPE BlockType = MappedValue >> 4;
+ NIBBLETYPE BlockMeta = MappedValue & 0x0f;
+ m_BlockArea.SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta);
+ }
+ }
+ }
+}
+
+
+
+
+
+cPiece::cConnectors cPrefab::GetConnectors(void) const
+{
+ return m_Connectors;
+}
+
+
+
+
+
+Vector3i cPrefab::GetSize(void) const
+{
+ return m_Size;
+}
+
+
+
+
+
+cCuboid cPrefab::GetHitBox(void) const
+{
+ return m_HitBox;
+}
+
+
+
+
+
+bool cPrefab::CanRotateCCW(int a_NumRotations) const
+{
+ return ((m_AllowedRotations & (1 << (a_NumRotations % 4))) != 0);
+}
+
+
+
+
diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h
new file mode 100644
index 000000000..6596b906b
--- /dev/null
+++ b/src/Generating/Prefab.h
@@ -0,0 +1,83 @@
+
+// Prefab.h
+
+/*
+Declares the cPrefab class, representing a cPiece descendant for the cPieceGenerator that
+uses a prefabricate in a cBlockArea for drawing itself.
+The class can be constructed from data that is stored directly in the executable, in a sPrefabDef structure
+declared in this file as well; the Gallery server exports areas in this format.
+*/
+
+
+
+
+
+#pragma once
+
+#include "PieceGenerator.h"
+#include "../BlockArea.h"
+
+
+
+
+
+
+class cPrefab :
+ public cPiece
+{
+public:
+ struct sDef
+ {
+ int m_SizeX;
+ int m_SizeY;
+ int m_SizeZ;
+ const char * m_CharMap;
+ const char * m_Image;
+ // TODO: Connectors
+ };
+
+ cPrefab(const sDef & a_Def);
+
+ /** Draws the prefab into the specified block area, according to the placement stored in the PlacedPiece. */
+ void Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement);
+
+protected:
+ /** Maps letters in the sDef::m_Image onto a number, BlockType * 16 | BlockMeta */
+ typedef int CharMap[256];
+
+
+ /** The cBlockArea that contains the block definitions for the prefab */
+ cBlockArea m_BlockArea;
+
+ /** The size of the prefab */
+ Vector3i m_Size;
+
+ /** The hitbox of the prefab. In first version is the same as the m_BlockArea dimensions */
+ cCuboid m_HitBox;
+
+ /** The connectors through which the piece connects to other pieces */
+ cConnectors m_Connectors;
+
+ /** Bitmask, bit N set -> N rotations CCW supported */
+ int m_AllowedRotations;
+
+ /** The merge strategy to use when drawing the prefab into a block area */
+ cBlockArea::eMergeStrategy m_MergeStrategy;
+
+
+ // cPiece overrides:
+ virtual cConnectors GetConnectors(void) const override;
+ virtual Vector3i GetSize(void) const override;
+ virtual cCuboid GetHitBox(void) const override;
+ virtual bool CanRotateCCW(int a_NumRotations) const override;
+
+ /** Parses the CharMap in the definition into a CharMap binary data used for translating the definition into BlockArea. */
+ void ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef);
+
+ /** Parses the Image in the definition into m_BlockArea's block types and metas, using the specified CharMap. */
+ void ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage);
+};
+
+
+
+