Added a basic cPrefab class.
Can be defined in the source by GalExport's cpp output.
This commit is contained in:
parent
87de596078
commit
37778e5f82
139
src/Generating/Prefab.cpp
Normal file
139
src/Generating/Prefab.cpp
Normal file
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
83
src/Generating/Prefab.h
Normal file
83
src/Generating/Prefab.h
Normal file
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user