BlockArea: Finished rotation and mirroring with meta. Implemented example meta handling for vines, stairs and torches.
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1319 0a769ca7-a7f5-676a-18bf-c427514a06d6master
parent
b0397f7273
commit
8dc54301a4
|
@ -105,6 +105,37 @@ function Initialize(Plugin)
|
|||
BA1:SaveToSchematicFile("schematics/rot4.schematic");
|
||||
end
|
||||
|
||||
-- Debug block area rotation:
|
||||
if (BA1:LoadFromSchematicFile("schematics/rotm.schematic")) then
|
||||
BA1:RotateCCW();
|
||||
BA1:SaveToSchematicFile("schematics/rotm1.schematic");
|
||||
BA1:RotateCCW();
|
||||
BA1:SaveToSchematicFile("schematics/rotm2.schematic");
|
||||
BA1:RotateCCW();
|
||||
BA1:SaveToSchematicFile("schematics/rotm3.schematic");
|
||||
BA1:RotateCCW();
|
||||
BA1:SaveToSchematicFile("schematics/rotm4.schematic");
|
||||
end
|
||||
|
||||
-- Debug block area mirroring:
|
||||
if (BA1:LoadFromSchematicFile("schematics/ltm.schematic")) then
|
||||
BA1:MirrorXY();
|
||||
BA1:SaveToSchematicFile("schematics/ltm_XY.schematic");
|
||||
BA1:MirrorXY();
|
||||
BA1:SaveToSchematicFile("schematics/ltm_XY2.schematic");
|
||||
|
||||
BA1:MirrorXZ();
|
||||
BA1:SaveToSchematicFile("schematics/ltm_XZ.schematic");
|
||||
BA1:MirrorXZ();
|
||||
BA1:SaveToSchematicFile("schematics/ltm_XZ2.schematic");
|
||||
|
||||
BA1:MirrorYZ();
|
||||
BA1:SaveToSchematicFile("schematics/ltm_YZ.schematic");
|
||||
BA1:MirrorYZ();
|
||||
BA1:SaveToSchematicFile("schematics/ltm_YZ2.schematic");
|
||||
end
|
||||
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "World.h"
|
||||
#include "OSSupport/GZipFile.h"
|
||||
#include "WorldStorage/FastNBT.h"
|
||||
#include "Blocks/BlockHandler.h"
|
||||
|
||||
|
||||
|
||||
|
@ -923,12 +924,41 @@ void cBlockArea::RotateCCW(void)
|
|||
{
|
||||
if (!HasBlockTypes())
|
||||
{
|
||||
LOGWARNING("cBlockArea: Cannot rotate meta without blocktypes!");
|
||||
LOGWARNING("cBlockArea: Cannot rotate blockmeta without blocktypes!");
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(!"Not implemented yet");
|
||||
// TODO
|
||||
if (!HasBlockMetas())
|
||||
{
|
||||
// There are no blockmetas to rotate, just use the NoMeta function
|
||||
RotateCCWNoMeta();
|
||||
return;
|
||||
}
|
||||
|
||||
// We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time:
|
||||
BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ];
|
||||
NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ];
|
||||
for (int x = 0; x < m_SizeX; x++)
|
||||
{
|
||||
int NewZ = m_SizeX - x - 1;
|
||||
for (int z = 0; z < m_SizeZ; z++)
|
||||
{
|
||||
int NewX = z;
|
||||
for (int y = 0; y < m_SizeY; y++)
|
||||
{
|
||||
int NewIdx = NewX + NewZ * m_SizeX + y * m_SizeX * m_SizeZ;
|
||||
int OldIdx = MakeIndex(x, y, z);
|
||||
NewTypes[NewIdx] = m_BlockTypes[OldIdx];
|
||||
NewMetas[NewIdx] = BlockHandler(m_BlockTypes[OldIdx])->MetaRotateCCW(m_BlockMetas[OldIdx]);
|
||||
} // for y
|
||||
} // for z
|
||||
} // for x
|
||||
std::swap(m_BlockTypes, NewTypes);
|
||||
std::swap(m_BlockMetas, NewMetas);
|
||||
delete[] NewTypes;
|
||||
delete[] NewMetas;
|
||||
|
||||
std::swap(m_SizeX, m_SizeZ);
|
||||
}
|
||||
|
||||
|
||||
|
@ -939,12 +969,41 @@ void cBlockArea::RotateCW(void)
|
|||
{
|
||||
if (!HasBlockTypes())
|
||||
{
|
||||
LOGWARNING("cBlockArea: Cannot rotate meta without blocktypes!");
|
||||
LOGWARNING("cBlockArea: Cannot rotate blockmeta without blocktypes!");
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(!"Not implemented yet");
|
||||
// TODO
|
||||
if (!HasBlockMetas())
|
||||
{
|
||||
// There are no blockmetas to rotate, just use the NoMeta function
|
||||
RotateCWNoMeta();
|
||||
return;
|
||||
}
|
||||
|
||||
// We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time:
|
||||
BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ];
|
||||
NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ];
|
||||
for (int x = 0; x < m_SizeX; x++)
|
||||
{
|
||||
int NewZ = x;
|
||||
for (int z = 0; z < m_SizeZ; z++)
|
||||
{
|
||||
int NewX = m_SizeZ - z - 1;
|
||||
for (int y = 0; y < m_SizeY; y++)
|
||||
{
|
||||
int NewIdx = NewX + NewZ * m_SizeX + y * m_SizeX * m_SizeZ;
|
||||
int OldIdx = MakeIndex(x, y, z);
|
||||
NewTypes[NewIdx] = m_BlockTypes[OldIdx];
|
||||
NewMetas[NewIdx] = BlockHandler(m_BlockTypes[OldIdx])->MetaRotateCW(m_BlockMetas[OldIdx]);
|
||||
} // for y
|
||||
} // for z
|
||||
} // for x
|
||||
std::swap(m_BlockTypes, NewTypes);
|
||||
std::swap(m_BlockMetas, NewMetas);
|
||||
delete[] NewTypes;
|
||||
delete[] NewMetas;
|
||||
|
||||
std::swap(m_SizeX, m_SizeZ);
|
||||
}
|
||||
|
||||
|
||||
|
@ -958,9 +1017,33 @@ void cBlockArea::MirrorXY(void)
|
|||
LOGWARNING("cBlockArea: Cannot mirror meta without blocktypes!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasBlockMetas())
|
||||
{
|
||||
// There are no blockmetas to mirror, just use the NoMeta function
|
||||
MirrorXYNoMeta();
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(!"Not implemented yet");
|
||||
// TODO
|
||||
// We are guaranteed that both blocktypes and blockmetas exist; mirror both at the same time:
|
||||
int HalfZ = m_SizeZ / 2;
|
||||
int MaxZ = m_SizeZ - 1;
|
||||
for (int y = 0; y < m_SizeY; y++)
|
||||
{
|
||||
for (int z = 0; z < HalfZ; z++)
|
||||
{
|
||||
for (int x = 0; x < m_SizeX; x++)
|
||||
{
|
||||
int Idx1 = MakeIndex(x, y, z);
|
||||
int Idx2 = MakeIndex(x, y, MaxZ - z);
|
||||
std::swap(m_BlockTypes[Idx1], m_BlockTypes[Idx2]);
|
||||
NIBBLETYPE Meta1 = BlockHandler(m_BlockTypes[Idx2])->MetaMirrorXY(m_BlockMetas[Idx1]);
|
||||
NIBBLETYPE Meta2 = BlockHandler(m_BlockTypes[Idx1])->MetaMirrorXY(m_BlockMetas[Idx2]);
|
||||
m_BlockMetas[Idx1] = Meta2;
|
||||
m_BlockMetas[Idx2] = Meta1;
|
||||
} // for x
|
||||
} // for z
|
||||
} // for y
|
||||
}
|
||||
|
||||
|
||||
|
@ -975,8 +1058,32 @@ void cBlockArea::MirrorXZ(void)
|
|||
return;
|
||||
}
|
||||
|
||||
ASSERT(!"Not implemented yet");
|
||||
// TODO
|
||||
if (!HasBlockMetas())
|
||||
{
|
||||
// There are no blockmetas to mirror, just use the NoMeta function
|
||||
MirrorXZNoMeta();
|
||||
return;
|
||||
}
|
||||
|
||||
// We are guaranteed that both blocktypes and blockmetas exist; mirror both at the same time:
|
||||
int HalfY = m_SizeY / 2;
|
||||
int MaxY = m_SizeY - 1;
|
||||
for (int y = 0; y < HalfY; y++)
|
||||
{
|
||||
for (int z = 0; z < m_SizeZ; z++)
|
||||
{
|
||||
for (int x = 0; x < m_SizeX; x++)
|
||||
{
|
||||
int Idx1 = MakeIndex(x, y, z);
|
||||
int Idx2 = MakeIndex(x, MaxY - y, z);
|
||||
std::swap(m_BlockTypes[Idx1], m_BlockTypes[Idx2]);
|
||||
NIBBLETYPE Meta1 = BlockHandler(m_BlockTypes[Idx2])->MetaMirrorXZ(m_BlockMetas[Idx1]);
|
||||
NIBBLETYPE Meta2 = BlockHandler(m_BlockTypes[Idx1])->MetaMirrorXZ(m_BlockMetas[Idx2]);
|
||||
m_BlockMetas[Idx1] = Meta2;
|
||||
m_BlockMetas[Idx2] = Meta1;
|
||||
} // for x
|
||||
} // for z
|
||||
} // for y
|
||||
}
|
||||
|
||||
|
||||
|
@ -991,8 +1098,32 @@ void cBlockArea::MirrorYZ(void)
|
|||
return;
|
||||
}
|
||||
|
||||
ASSERT(!"Not implemented yet");
|
||||
// TODO
|
||||
if (!HasBlockMetas())
|
||||
{
|
||||
// There are no blockmetas to mirror, just use the NoMeta function
|
||||
MirrorYZNoMeta();
|
||||
return;
|
||||
}
|
||||
|
||||
// We are guaranteed that both blocktypes and blockmetas exist; mirror both at the same time:
|
||||
int HalfX = m_SizeX / 2;
|
||||
int MaxX = m_SizeX - 1;
|
||||
for (int y = 0; y < m_SizeY; y++)
|
||||
{
|
||||
for (int z = 0; z < m_SizeZ; z++)
|
||||
{
|
||||
for (int x = 0; x < HalfX; x++)
|
||||
{
|
||||
int Idx1 = MakeIndex(x, y, z);
|
||||
int Idx2 = MakeIndex(MaxX - x, y, z);
|
||||
std::swap(m_BlockTypes[Idx1], m_BlockTypes[Idx2]);
|
||||
NIBBLETYPE Meta1 = BlockHandler(m_BlockTypes[Idx2])->MetaMirrorYZ(m_BlockMetas[Idx1]);
|
||||
NIBBLETYPE Meta2 = BlockHandler(m_BlockTypes[Idx1])->MetaMirrorYZ(m_BlockMetas[Idx2]);
|
||||
m_BlockMetas[Idx1] = Meta2;
|
||||
m_BlockMetas[Idx2] = Meta1;
|
||||
} // for x
|
||||
} // for z
|
||||
} // for y
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -112,6 +112,21 @@ public:
|
|||
*/
|
||||
virtual void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk);
|
||||
|
||||
/// Returns the meta for a block after rotating it counter-clockwise from the specified meta. Default: no change
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) { return a_Meta; }
|
||||
|
||||
/// Returns the meta for a block after rotating it clockwise from the specified meta. Default: no change
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) { return a_Meta; }
|
||||
|
||||
/// Returns the meta for a block after mirroring it around the XY plane. Default: no change
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) { return a_Meta; }
|
||||
|
||||
/// Returns the meta for a block after mirroring it around the XZ plane. Default: no change
|
||||
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) { return a_Meta; }
|
||||
|
||||
/// Returns the meta for a block after mirroring it around the YZ plane. Default: no change
|
||||
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; }
|
||||
|
||||
|
||||
/// Get the blockhandler for a specific block id
|
||||
static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockType);
|
||||
|
|
|
@ -49,6 +49,77 @@ public:
|
|||
}
|
||||
|
||||
// TODO: step sound
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 3 and 4 stay, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x0c);
|
||||
switch (a_Meta & 0x03)
|
||||
{
|
||||
case 0x00: return TopBits | 0x03; // East -> North
|
||||
case 0x01: return TopBits | 0x02; // West -> South
|
||||
case 0x02: return TopBits | 0x00; // South -> East
|
||||
case 0x03: return TopBits | 0x01; // North -> West
|
||||
}
|
||||
// Not reachable, but to avoid a compiler warning:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 3 and 4 stay, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x0c);
|
||||
switch (a_Meta & 0x03)
|
||||
{
|
||||
case 0x00: return TopBits | 0x02; // East -> South
|
||||
case 0x01: return TopBits | 0x03; // West -> North
|
||||
case 0x02: return TopBits | 0x01; // South -> West
|
||||
case 0x03: return TopBits | 0x00; // North -> East
|
||||
}
|
||||
// Not reachable, but to avoid a compiler warning:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 3 and 4 stay, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x0c);
|
||||
switch (a_Meta & 0x03)
|
||||
{
|
||||
case 0x00: return TopBits | 0x00; // East -> East
|
||||
case 0x01: return TopBits | 0x01; // West -> West
|
||||
case 0x02: return TopBits | 0x03; // South -> North
|
||||
case 0x03: return TopBits | 0x02; // North -> South
|
||||
}
|
||||
// Not reachable, but to avoid a compiler warning:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Toggle bit 3:
|
||||
return (a_Meta & 0x0b) | ((~a_Meta) & 0x04);
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 3 and 4 stay, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x0c);
|
||||
switch (a_Meta & 0x03)
|
||||
{
|
||||
case 0x00: return TopBits | 0x01; // East -> West
|
||||
case 0x01: return TopBits | 0x00; // West -> East
|
||||
case 0x02: return TopBits | 0x02; // South -> South
|
||||
case 0x03: return TopBits | 0x03; // North -> North
|
||||
}
|
||||
// Not reachable, but to avoid a compiler warning:
|
||||
return 0;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
|
|
@ -132,6 +132,67 @@ public:
|
|||
{
|
||||
return "step.wood";
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bit 4 stays, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x08);
|
||||
switch (a_Meta & 0x07)
|
||||
{
|
||||
case 0x01: return TopBits | 0x04; // East -> North
|
||||
case 0x02: return TopBits | 0x03; // West -> South
|
||||
case 0x03: return TopBits | 0x01; // South -> East
|
||||
case 0x04: return TopBits | 0x02; // North -> West
|
||||
default: return a_Meta; // Floor -> Floor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bit 4 stays, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x08);
|
||||
switch (a_Meta & 0x07)
|
||||
{
|
||||
case 0x01: return TopBits | 0x03; // East -> South
|
||||
case 0x02: return TopBits | 0x04; // West -> North
|
||||
case 0x03: return TopBits | 0x02; // South -> West
|
||||
case 0x04: return TopBits | 0x01; // North -> East
|
||||
default: return a_Meta; // Floor -> Floor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bit 4 stays, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x08);
|
||||
switch (a_Meta & 0x07)
|
||||
{
|
||||
case 0x03: return TopBits | 0x04; // South -> North
|
||||
case 0x04: return TopBits | 0x03; // North -> South
|
||||
default: return a_Meta; // Keep the rest
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mirroring around the XZ plane doesn't make sense for floor torches,
|
||||
// the others stay the same, so let's keep all the metas the same.
|
||||
// The base class does tht for us, no need to override MetaMirrorXZ()
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bit 4 stays, the rest is swapped around according to a table:
|
||||
NIBBLETYPE TopBits = (a_Meta & 0x08);
|
||||
switch (a_Meta & 0x07)
|
||||
{
|
||||
case 0x01: return TopBits | 0x02; // East -> West
|
||||
case 0x02: return TopBits | 0x01; // West -> East
|
||||
default: return a_Meta; // Keep the rest
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
|
|
@ -138,10 +138,36 @@ public:
|
|||
}
|
||||
|
||||
|
||||
bool DoesDropOnUnsuitable(void)
|
||||
virtual bool DoesDropOnUnsuitable(void) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
return ((a_Meta << 1) | (a_Meta >> 3)) & 0x0f; // Rotate bits to the left
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 2 and 4 stay, bits 1 and 3 swap
|
||||
return ((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2));
|
||||
}
|
||||
|
||||
|
||||
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
// Bits 1 and 3 stay, bits 2 and 4 swap
|
||||
return ((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2));
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue