1
0

Merge branch 'master' into Bow

This commit is contained in:
Howaner 2014-06-26 15:49:53 +02:00
commit eaf36766f6
82 changed files with 5336 additions and 3499 deletions

View File

@ -1,5 +1,6 @@
Many people have contributed to MCServer, and this list attempts to broadcast at least some of them. Many people have contributed to MCServer, and this list attempts to broadcast at least some of them.
BasedDoge (Donated AlchemistVillage prefabs)
bearbin (Alexander Harkness) bearbin (Alexander Harkness)
derouinw derouinw
Diusrex Diusrex
@ -26,5 +27,6 @@ tonibm19
UltraCoderRU UltraCoderRU
worktycho worktycho
xoft xoft
Yeeeeezus (Donated AlchemistVillage prefabs)
Please add yourself to this list if you contribute to MCServer. Please add yourself to this list if you contribute to MCServer.

View File

@ -523,13 +523,16 @@ end
Functions = Functions =
{ {
GenerateOfflineUUID = { Params = "Username", Return = "string", Notes = "(STATIC) Generates an UUID based on the player name provided. This is used for the offline (non-auth) mode, when there's no UUID source. Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. Returns a 36-char UUID (with dashes)." },
GetLocale = { Params = "", Return = "Locale", Notes = "Returns the locale string that the client sends as part of the protocol handshake. Can be used to provide localized strings." }, GetLocale = { Params = "", Return = "Locale", Notes = "Returns the locale string that the client sends as part of the protocol handshake. Can be used to provide localized strings." },
GetPing = { Params = "", Return = "number", Notes = "Returns the ping time, in ms" }, GetPing = { Params = "", Return = "number", Notes = "Returns the ping time, in ms" },
GetPlayer = { Params = "", Return = "{{cPlayer|cPlayer}}", Notes = "Returns the player object connected to this client. Note that this may be nil, for example if the player object is not yet spawned." }, GetPlayer = { Params = "", Return = "{{cPlayer|cPlayer}}", Notes = "Returns the player object connected to this client. Note that this may be nil, for example if the player object is not yet spawned." },
GetUniqueID = { Params = "", Return = "number", Notes = "Returns the UniqueID of the client used to identify the client in the server" }, GetUniqueID = { Params = "", Return = "number", Notes = "Returns the UniqueID of the client used to identify the client in the server" },
GetUUID = { Params = "", Return = "string", Notes = "Returns the authentication-based UUID of the client. This UUID should be used to identify the player when persisting any player-related data." },
GetUsername = { Params = "", Return = "string", Notes = "Returns the username that the client has provided" }, GetUsername = { Params = "", Return = "string", Notes = "Returns the username that the client has provided" },
GetViewDistance = { Params = "", Return = "number", Notes = "Returns the viewdistance (number of chunks loaded for the player in each direction)" }, GetViewDistance = { Params = "", Return = "number", Notes = "Returns the viewdistance (number of chunks loaded for the player in each direction)" },
HasPluginChannel = { Params = "ChannelName", Return = "bool", Notes = "Returns true if the client has registered to receive messages on the specified plugin channel." }, HasPluginChannel = { Params = "ChannelName", Return = "bool", Notes = "Returns true if the client has registered to receive messages on the specified plugin channel." },
IsUUIDOnline = { Params = "UUID", Return = "bool", Notes = "(STATIC) Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes). If the string given is not a valid UUID, returns false."},
Kick = { Params = "Reason", Return = "", Notes = "Kicks the user with the specified reason" }, Kick = { Params = "Reason", Return = "", Notes = "Kicks the user with the specified reason" },
SendPluginMessage = { Params = "Channel, Message", Return = "", Notes = "Sends the plugin message on the specified channel." }, SendPluginMessage = { Params = "Channel, Message", Return = "", Notes = "Sends the plugin message on the specified channel." },
SetLocale = { Params = "Locale", Return = "", Notes = "Sets the locale that MCServer keeps on record. Initially the locale is initialized in protocol handshake, this function allows plugins to override the stored value (but only server-side and only until the user disconnects)." }, SetLocale = { Params = "Locale", Return = "", Notes = "Sets the locale that MCServer keeps on record. Initially the locale is initialized in protocol handshake, this function allows plugins to override the stored value (but only server-side and only until the user disconnects)." },

View File

@ -346,7 +346,7 @@ end
function OnUsingBlazeRod(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, CursorY, CursorZ) function OnUsingBlazeRod(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, CursorY, CursorZ)
-- Magic rod of query: show block types and metas for both neighbors of the pointed face -- Magic rod of query: show block types and metas for both neighbors of the pointed face
local Type, Meta, Valid = Player:GetWorld():GetBlockTypeMeta(BlockX, BlockY, BlockZ, Type, Meta); local Valid, Type, Meta = Player:GetWorld():GetBlockTypeMeta(BlockX, BlockY, BlockZ);
if (Type == E_BLOCK_AIR) then if (Type == E_BLOCK_AIR) then
Player:SendMessage(cChatColor.LightGray .. "Block {" .. BlockX .. ", " .. BlockY .. ", " .. BlockZ .. "}: air:" .. Meta); Player:SendMessage(cChatColor.LightGray .. "Block {" .. BlockX .. ", " .. BlockY .. ", " .. BlockZ .. "}: air:" .. Meta);
@ -356,7 +356,7 @@ function OnUsingBlazeRod(Player, BlockX, BlockY, BlockZ, BlockFace, CursorX, Cur
end end
local X, Y, Z = AddFaceDirection(BlockX, BlockY, BlockZ, BlockFace); local X, Y, Z = AddFaceDirection(BlockX, BlockY, BlockZ, BlockFace);
Valid, Type, Meta = Player:GetWorld():GetBlockTypeMeta(X, Y, Z, Type, Meta); Valid, Type, Meta = Player:GetWorld():GetBlockTypeMeta(X, Y, Z);
if (Type == E_BLOCK_AIR) then if (Type == E_BLOCK_AIR) then
Player:SendMessage(cChatColor.LightGray .. "Block {" .. X .. ", " .. Y .. ", " .. Z .. "}: air:" .. Meta); Player:SendMessage(cChatColor.LightGray .. "Block {" .. X .. ", " .. Y .. ", " .. Z .. "}: air:" .. Meta);
else else

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="windows-1250"?> <?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="9.00" Version="9,00"
Name="BiomeVisualiser" Name="BiomeVisualiser"
ProjectGUID="{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}" ProjectGUID="{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
RootNamespace="BiomeVisualiser" RootNamespace="BiomeVisualiser"
@ -327,6 +327,14 @@
<Filter <Filter
Name="Shared" Name="Shared"
> >
<File
RelativePath="..\..\src\BiomeDef.cpp"
>
</File>
<File
RelativePath="..\..\src\BiomeDef.h"
>
</File>
<File <File
RelativePath="..\..\src\BlockID.cpp" RelativePath="..\..\src\BlockID.cpp"
> >
@ -355,6 +363,14 @@
RelativePath="..\..\src\WorldStorage\FastNBT.h" RelativePath="..\..\src\WorldStorage\FastNBT.h"
> >
</File> </File>
<File
RelativePath="..\..\src\FastRandom.cpp"
>
</File>
<File
RelativePath="..\..\src\FastRandom.h"
>
</File>
<File <File
RelativePath="..\..\src\Globals.cpp" RelativePath="..\..\src\Globals.cpp"
> >

View File

@ -1765,6 +1765,7 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S)
if (!ChunkStay->AddChunks(2)) if (!ChunkStay->AddChunks(2))
{ {
delete ChunkStay; delete ChunkStay;
ChunkStay = NULL;
return 0; return 0;
} }

View File

@ -1571,6 +1571,7 @@ bool cPluginLua::AddHookRef(int a_HookType, int a_FnRefIdx)
LOGWARNING("Plugin %s tried to add a hook %d with bad handler function.", GetName().c_str(), a_HookType); LOGWARNING("Plugin %s tried to add a hook %d with bad handler function.", GetName().c_str(), a_HookType);
m_LuaState.LogStackTrace(); m_LuaState.LogStackTrace();
delete Ref; delete Ref;
Ref = NULL;
return false; return false;
} }

View File

@ -1467,6 +1467,7 @@ void cPluginManager::RemovePlugin(cPlugin * a_Plugin)
a_Plugin->OnDisable(); a_Plugin->OnDisable();
} }
delete a_Plugin; delete a_Plugin;
a_Plugin = NULL;
} }

View File

@ -295,9 +295,9 @@ cBlockArea::~cBlockArea()
void cBlockArea::Clear(void) void cBlockArea::Clear(void)
{ {
delete[] m_BlockTypes; m_BlockTypes = NULL; delete[] m_BlockTypes; m_BlockTypes = NULL;
delete[] m_BlockMetas; m_BlockMetas = NULL; delete[] m_BlockMetas; m_BlockMetas = NULL;
delete[] m_BlockLight; m_BlockLight = NULL; delete[] m_BlockLight; m_BlockLight = NULL;
delete[] m_BlockSkyLight; m_BlockSkyLight = NULL; delete[] m_BlockSkyLight; m_BlockSkyLight = NULL;
m_Origin.Set(0, 0, 0); m_Origin.Set(0, 0, 0);
m_Size.Set(0, 0, 0); m_Size.Set(0, 0, 0);
@ -1013,8 +1013,8 @@ void cBlockArea::RotateCCW(void)
} // for x } // for x
std::swap(m_BlockTypes, NewTypes); std::swap(m_BlockTypes, NewTypes);
std::swap(m_BlockMetas, NewMetas); std::swap(m_BlockMetas, NewMetas);
delete[] NewTypes; delete[] NewTypes; NewTypes = NULL;
delete[] NewMetas; delete[] NewMetas; NewMetas = NULL;
std::swap(m_Size.x, m_Size.z); std::swap(m_Size.x, m_Size.z);
} }
@ -1058,8 +1058,8 @@ void cBlockArea::RotateCW(void)
} // for x } // for x
std::swap(m_BlockTypes, NewTypes); std::swap(m_BlockTypes, NewTypes);
std::swap(m_BlockMetas, NewMetas); std::swap(m_BlockMetas, NewMetas);
delete[] NewTypes; delete[] NewTypes; NewTypes = NULL;
delete[] NewMetas; delete[] NewMetas; NewMetas = NULL;
std::swap(m_Size.x, m_Size.z); std::swap(m_Size.x, m_Size.z);
} }
@ -1206,7 +1206,7 @@ void cBlockArea::RotateCCWNoMeta(void)
} // for z } // for z
} // for x } // for x
std::swap(m_BlockTypes, NewTypes); std::swap(m_BlockTypes, NewTypes);
delete[] NewTypes; delete[] NewTypes; NewTypes = NULL;
} }
if (HasBlockMetas()) if (HasBlockMetas())
{ {
@ -1224,7 +1224,7 @@ void cBlockArea::RotateCCWNoMeta(void)
} // for z } // for z
} // for x } // for x
std::swap(m_BlockMetas, NewMetas); std::swap(m_BlockMetas, NewMetas);
delete[] NewMetas; delete[] NewMetas; NewMetas = NULL;
} }
std::swap(m_Size.x, m_Size.z); std::swap(m_Size.x, m_Size.z);
} }
@ -1251,7 +1251,7 @@ void cBlockArea::RotateCWNoMeta(void)
} // for x } // for x
} // for z } // for z
std::swap(m_BlockTypes, NewTypes); std::swap(m_BlockTypes, NewTypes);
delete[] NewTypes; delete[] NewTypes; NewTypes = NULL;
} }
if (HasBlockMetas()) if (HasBlockMetas())
{ {
@ -1269,7 +1269,7 @@ void cBlockArea::RotateCWNoMeta(void)
} // for x } // for x
} // for z } // for z
std::swap(m_BlockMetas, NewMetas); std::swap(m_BlockMetas, NewMetas);
delete[] NewMetas; delete[] NewMetas; NewMetas = NULL;
} }
std::swap(m_Size.x, m_Size.z); std::swap(m_Size.x, m_Size.z);
} }
@ -1658,6 +1658,7 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
if (m_BlockMetas == NULL) if (m_BlockMetas == NULL)
{ {
delete[] m_BlockTypes; delete[] m_BlockTypes;
m_BlockTypes = NULL;
return false; return false;
} }
} }
@ -1667,7 +1668,9 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
if (m_BlockLight == NULL) if (m_BlockLight == NULL)
{ {
delete[] m_BlockMetas; delete[] m_BlockMetas;
m_BlockMetas = NULL;
delete[] m_BlockTypes; delete[] m_BlockTypes;
m_BlockTypes = NULL;
return false; return false;
} }
} }
@ -1677,8 +1680,11 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes)
if (m_BlockSkyLight == NULL) if (m_BlockSkyLight == NULL)
{ {
delete[] m_BlockLight; delete[] m_BlockLight;
m_BlockLight = NULL;
delete[] m_BlockMetas; delete[] m_BlockMetas;
m_BlockMetas = NULL;
delete[] m_BlockTypes; delete[] m_BlockTypes;
m_BlockTypes = NULL;
return false; return false;
} }
} }

View File

@ -122,6 +122,13 @@ void cChestEntity::UsedBy(cPlayer * a_Player)
void cChestEntity::OpenNewWindow(void) void cChestEntity::OpenNewWindow(void)
{ {
// TODO: cats are an obstruction
if ((GetPosY() + 1 < cChunkDef::Height) && cBlockInfo::IsSolid(GetWorld()->GetBlock(GetPosX(), GetPosY() + 1, GetPosZ())))
{
// Obstruction, don't open
return;
}
// Callback for opening together with neighbor chest: // Callback for opening together with neighbor chest:
class cOpenDouble : class cOpenDouble :
public cChestCallback public cChestCallback
@ -135,6 +142,12 @@ void cChestEntity::OpenNewWindow(void)
virtual bool Item(cChestEntity * a_Chest) override virtual bool Item(cChestEntity * a_Chest) override
{ {
if ((a_Chest->GetPosY() + 1 < cChunkDef::Height) && cBlockInfo::IsSolid(a_Chest->GetWorld()->GetBlock(a_Chest->GetPosX(), a_Chest->GetPosY() + 1, a_Chest->GetPosZ())))
{
// Obstruction, don't open
return false;
}
// The primary chest should eb the one with lesser X or Z coord: // The primary chest should eb the one with lesser X or Z coord:
cChestEntity * Primary = a_Chest; cChestEntity * Primary = a_Chest;
cChestEntity * Secondary = m_ThisChest; cChestEntity * Secondary = m_ThisChest;

View File

@ -294,23 +294,24 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
return false; return false;
} }
int bx, by, bz; // Get the coords of the block where to output items:
int OutX, OutY, OutZ;
NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ);
if (!GetOutputBlockPos(Meta, bx, by, bz)) if (!GetOutputBlockPos(Meta, OutX, OutY, OutZ))
{ {
// Not attached to another container // Not attached to another container
return false; return false;
} }
if (by < 0) if (OutY < 0)
{ {
// Cannot output below the zero-th block level // Cannot output below the zero-th block level
return false; return false;
} }
// Convert coords to relative: // Convert coords to relative:
int rx = bx - a_Chunk.GetPosX() * cChunkDef::Width; int OutRelX = OutX - a_Chunk.GetPosX() * cChunkDef::Width;
int rz = bz - a_Chunk.GetPosZ() * cChunkDef::Width; int OutRelZ = OutZ - a_Chunk.GetPosZ() * cChunkDef::Width;
cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(rx, rz); cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(OutRelX, OutRelZ);
if (DestChunk == NULL) if (DestChunk == NULL)
{ {
// The destination chunk has been unloaded, don't tick // The destination chunk has been unloaded, don't tick
@ -319,26 +320,32 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
// Call proper moving function, based on the blocktype present at the coords: // Call proper moving function, based on the blocktype present at the coords:
bool res = false; bool res = false;
switch (DestChunk->GetBlock(rx, by, rz)) switch (DestChunk->GetBlock(OutRelX, OutY, OutRelZ))
{ {
case E_BLOCK_CHEST: case E_BLOCK_CHEST:
{ {
// Chests have special handling because of double-chests // Chests have special handling because of double-chests
res = MoveItemsToChest(*DestChunk, bx, by, bz); res = MoveItemsToChest(*DestChunk, OutX, OutY, OutZ);
break; break;
} }
case E_BLOCK_LIT_FURNACE: case E_BLOCK_LIT_FURNACE:
case E_BLOCK_FURNACE: case E_BLOCK_FURNACE:
{ {
// Furnaces have special handling because of the direction-to-slot relation // Furnaces have special handling because of the direction-to-slot relation
res = MoveItemsToFurnace(*DestChunk, bx, by, bz, Meta); res = MoveItemsToFurnace(*DestChunk, OutX, OutY, OutZ, Meta);
break; break;
} }
case E_BLOCK_DISPENSER: case E_BLOCK_DISPENSER:
case E_BLOCK_DROPPER: case E_BLOCK_DROPPER:
case E_BLOCK_HOPPER: case E_BLOCK_HOPPER:
{ {
res = MoveItemsToGrid(*(cBlockEntityWithItems *)DestChunk->GetBlockEntity(bx, by, bz)); cBlockEntityWithItems * BlockEntity = (cBlockEntityWithItems *)DestChunk->GetBlockEntity(OutX, OutY, OutZ);
if (BlockEntity == NULL)
{
LOGWARNING("%s: A block entity was not found where expected at {%d, %d, %d}", __FUNCTION__, OutX, OutY, OutZ);
return false;
}
res = MoveItemsToGrid(*BlockEntity);
break; break;
} }
} }
@ -359,7 +366,13 @@ bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick)
/// Moves items from a chest (dblchest) above the hopper into this hopper. Returns true if contents have changed. /// Moves items from a chest (dblchest) above the hopper into this hopper. Returns true if contents have changed.
bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
{ {
if (MoveItemsFromGrid(*(cChestEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ))) cChestEntity * Chest = (cChestEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ);
if (Chest == NULL)
{
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ);
return false;
}
if (MoveItemsFromGrid(*Chest))
{ {
// Moved the item from the chest directly above the hopper // Moved the item from the chest directly above the hopper
return true; return true;
@ -389,9 +402,17 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
{ {
continue; continue;
} }
if (MoveItemsFromGrid(*(cChestEntity *)Neighbor->GetBlockEntity(x, m_PosY, z))) Chest = (cChestEntity *)Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z);
if (Chest == NULL)
{ {
return true; LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z);
}
else
{
if (MoveItemsFromGrid(*Chest))
{
return true;
}
} }
return false; return false;
} }
@ -408,7 +429,11 @@ bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk)
bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk) bool cHopperEntity::MoveItemsFromFurnace(cChunk & a_Chunk)
{ {
cFurnaceEntity * Furnace = (cFurnaceEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ); cFurnaceEntity * Furnace = (cFurnaceEntity *)a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ);
ASSERT(Furnace != NULL); if (Furnace == NULL)
{
LOGWARNING("%s: A furnace entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ);
return false;
}
// Try move from the output slot: // Try move from the output slot:
if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput, true)) if (MoveItemsFromSlot(*Furnace, cFurnaceEntity::fsOutput, true))
@ -517,7 +542,13 @@ bool cHopperEntity::MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_Sl
bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ) bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
// Try the chest directly connected to the hopper: // Try the chest directly connected to the hopper:
if (MoveItemsToGrid(*(cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ))) cChestEntity * Chest = (cChestEntity *)a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ);
if (Chest == NULL)
{
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, a_BlockX, a_BlockY, a_BlockZ);
return false;
}
if (MoveItemsToGrid(*Chest))
{ {
return true; return true;
} }
@ -534,19 +565,27 @@ bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_Block
{0, 1}, {0, 1},
{0, -1}, {0, -1},
} ; } ;
int RelX = a_BlockX - a_Chunk.GetPosX() * cChunkDef::Width;
int RelZ = a_BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width;
for (size_t i = 0; i < ARRAYCOUNT(Coords); i++) for (size_t i = 0; i < ARRAYCOUNT(Coords); i++)
{ {
int x = m_RelX + Coords[i].x; int x = RelX + Coords[i].x;
int z = m_RelZ + Coords[i].z; int z = RelZ + Coords[i].z;
cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z); cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z);
if ( if (
(Neighbor == NULL) || (Neighbor == NULL) ||
(Neighbor->GetBlock(x, m_PosY + 1, z) != E_BLOCK_CHEST) (Neighbor->GetBlock(x, a_BlockY, z) != E_BLOCK_CHEST)
) )
{ {
continue; continue;
} }
if (MoveItemsToGrid(*(cChestEntity *)Neighbor->GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ))) Chest = (cChestEntity *)Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z);
if (Chest == NULL)
{
LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d} (%d, %d)", __FUNCTION__, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z, x, z);
continue;
}
if (MoveItemsToGrid(*Chest))
{ {
return true; return true;
} }

View File

@ -70,6 +70,8 @@ void cMobHeadEntity::SetOwner(const AString & a_Owner)
void cMobHeadEntity::SendTo(cClientHandle & a_Client) void cMobHeadEntity::SendTo(cClientHandle & a_Client)
{ {
cWorld * World = a_Client.GetPlayer()->GetWorld();
a_Client.SendBlockChange(m_PosX, m_PosY, m_PosZ, m_BlockType, World->GetBlockMeta(m_PosX, m_PosY, m_PosZ));
a_Client.SendUpdateBlockEntity(*this); a_Client.SendUpdateBlockEntity(*this);
} }

View File

@ -8,12 +8,6 @@
cBlockInfo cBlockInfo::ms_Info[256];
cBlockInfo::cBlockInfo() cBlockInfo::cBlockInfo()
: m_LightValue(0x00) : m_LightValue(0x00)
, m_SpreadLightFalloff(0x0f) , m_SpreadLightFalloff(0x0f)
@ -34,14 +28,25 @@ cBlockInfo::cBlockInfo()
cBlockInfo::~cBlockInfo() cBlockInfo::~cBlockInfo()
{ {
delete m_Handler; delete m_Handler;
m_Handler = NULL;
} }
/** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once.
It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable.
It works only if it is called for the first time before the app spawns other threads. */
cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type) cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
{ {
static cBlockInfo ms_Info[256];
static bool IsBlockInfoInitialized = false;
if (!IsBlockInfoInitialized)
{
cBlockInfo::Initialize(ms_Info);
IsBlockInfoInitialized = true;
}
return ms_Info[a_Type]; return ms_Info[a_Type];
} }
@ -49,414 +54,401 @@ cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type)
void cBlockInfo::Initialize(void) void cBlockInfo::Initialize(cBlockInfoArray & a_Info)
{ {
for (unsigned int i = 0; i < 256; ++i) for (unsigned int i = 0; i < 256; ++i)
{ {
if (ms_Info[i].m_Handler == NULL) if (a_Info[i].m_Handler == NULL)
{ {
ms_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i); a_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i);
} }
} }
// Emissive blocks // Emissive blocks
ms_Info[E_BLOCK_FIRE ].m_LightValue = 15; a_Info[E_BLOCK_FIRE ].m_LightValue = 15;
ms_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15; a_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15;
ms_Info[E_BLOCK_JACK_O_LANTERN ].m_LightValue = 15; a_Info[E_BLOCK_JACK_O_LANTERN ].m_LightValue = 15;
ms_Info[E_BLOCK_LAVA ].m_LightValue = 15; a_Info[E_BLOCK_LAVA ].m_LightValue = 15;
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15; a_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15;
ms_Info[E_BLOCK_END_PORTAL ].m_LightValue = 15; a_Info[E_BLOCK_END_PORTAL ].m_LightValue = 15;
ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_LightValue = 15; a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_LightValue = 15;
ms_Info[E_BLOCK_TORCH ].m_LightValue = 14; a_Info[E_BLOCK_TORCH ].m_LightValue = 14;
ms_Info[E_BLOCK_BURNING_FURNACE ].m_LightValue = 13; a_Info[E_BLOCK_BURNING_FURNACE ].m_LightValue = 13;
ms_Info[E_BLOCK_NETHER_PORTAL ].m_LightValue = 11; a_Info[E_BLOCK_NETHER_PORTAL ].m_LightValue = 11;
ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9; a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9;
ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9; a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9;
ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7; a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7;
ms_Info[E_BLOCK_BREWING_STAND ].m_LightValue = 1; a_Info[E_BLOCK_BREWING_STAND ].m_LightValue = 1;
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_LightValue = 1; a_Info[E_BLOCK_BROWN_MUSHROOM ].m_LightValue = 1;
ms_Info[E_BLOCK_DRAGON_EGG ].m_LightValue = 1; a_Info[E_BLOCK_DRAGON_EGG ].m_LightValue = 1;
// Spread blocks // Spread blocks
ms_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_CAKE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_CAKE ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_CHEST ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_CHEST ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_FENCE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_FENCE ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_FENCE_GATE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_FENCE_GATE ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_FIRE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_FIRE ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_GLASS ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_GLASS ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_GLASS_PANE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_GLASS_PANE ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_GLOWSTONE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_GLOWSTONE ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1;
ms_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1;
// Light in water and lava dissapears faster: // Light in water and lava dissapears faster:
ms_Info[E_BLOCK_LAVA ].m_SpreadLightFalloff = 3; a_Info[E_BLOCK_LAVA ].m_SpreadLightFalloff = 3;
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_SpreadLightFalloff = 3; a_Info[E_BLOCK_STATIONARY_LAVA ].m_SpreadLightFalloff = 3;
ms_Info[E_BLOCK_STATIONARY_WATER ].m_SpreadLightFalloff = 3; a_Info[E_BLOCK_STATIONARY_WATER ].m_SpreadLightFalloff = 3;
ms_Info[E_BLOCK_WATER ].m_SpreadLightFalloff = 3; a_Info[E_BLOCK_WATER ].m_SpreadLightFalloff = 3;
// Transparent blocks // Transparent blocks
ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true; a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true;
ms_Info[E_BLOCK_AIR ].m_Transparent = true; a_Info[E_BLOCK_AIR ].m_Transparent = true;
ms_Info[E_BLOCK_ANVIL ].m_Transparent = true; a_Info[E_BLOCK_ANVIL ].m_Transparent = true;
ms_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true; a_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true;
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true; a_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true;
ms_Info[E_BLOCK_CAKE ].m_Transparent = true; a_Info[E_BLOCK_CAKE ].m_Transparent = true;
ms_Info[E_BLOCK_CARROTS ].m_Transparent = true; a_Info[E_BLOCK_CARROTS ].m_Transparent = true;
ms_Info[E_BLOCK_CHEST ].m_Transparent = true; a_Info[E_BLOCK_CHEST ].m_Transparent = true;
ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_Transparent = true; a_Info[E_BLOCK_COBBLESTONE_WALL ].m_Transparent = true;
ms_Info[E_BLOCK_COBWEB ].m_Transparent = true; a_Info[E_BLOCK_COBWEB ].m_Transparent = true;
ms_Info[E_BLOCK_CROPS ].m_Transparent = true; a_Info[E_BLOCK_CROPS ].m_Transparent = true;
ms_Info[E_BLOCK_DANDELION ].m_Transparent = true; a_Info[E_BLOCK_DANDELION ].m_Transparent = true;
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true; a_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true;
ms_Info[E_BLOCK_ENDER_CHEST ].m_Transparent = true; a_Info[E_BLOCK_ENDER_CHEST ].m_Transparent = true;
ms_Info[E_BLOCK_FENCE ].m_Transparent = true; a_Info[E_BLOCK_FENCE ].m_Transparent = true;
ms_Info[E_BLOCK_FENCE_GATE ].m_Transparent = true; a_Info[E_BLOCK_FENCE_GATE ].m_Transparent = true;
ms_Info[E_BLOCK_FIRE ].m_Transparent = true; a_Info[E_BLOCK_FIRE ].m_Transparent = true;
ms_Info[E_BLOCK_FLOWER ].m_Transparent = true; a_Info[E_BLOCK_FLOWER ].m_Transparent = true;
ms_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true; a_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true;
ms_Info[E_BLOCK_GLASS ].m_Transparent = true; a_Info[E_BLOCK_GLASS ].m_Transparent = true;
ms_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true; a_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true;
ms_Info[E_BLOCK_HEAD ].m_Transparent = true; a_Info[E_BLOCK_HEAD ].m_Transparent = true;
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true; a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
ms_Info[E_BLOCK_ICE ].m_Transparent = true; a_Info[E_BLOCK_ICE ].m_Transparent = true;
ms_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true; a_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true;
ms_Info[E_BLOCK_LADDER ].m_Transparent = true; a_Info[E_BLOCK_LADDER ].m_Transparent = true;
ms_Info[E_BLOCK_LAVA ].m_Transparent = true; a_Info[E_BLOCK_LAVA ].m_Transparent = true;
ms_Info[E_BLOCK_LEAVES ].m_Transparent = true; a_Info[E_BLOCK_LEAVES ].m_Transparent = true;
ms_Info[E_BLOCK_LEVER ].m_Transparent = true; a_Info[E_BLOCK_LEVER ].m_Transparent = true;
ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Transparent = true; a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
ms_Info[E_BLOCK_MELON_STEM ].m_Transparent = true; a_Info[E_BLOCK_MELON_STEM ].m_Transparent = true;
ms_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Transparent = true; a_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Transparent = true;
ms_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true; a_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true;
ms_Info[E_BLOCK_POTATOES ].m_Transparent = true; a_Info[E_BLOCK_POTATOES ].m_Transparent = true;
ms_Info[E_BLOCK_POWERED_RAIL ].m_Transparent = true; a_Info[E_BLOCK_POWERED_RAIL ].m_Transparent = true;
ms_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true; a_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true;
ms_Info[E_BLOCK_PUMPKIN_STEM ].m_Transparent = true; a_Info[E_BLOCK_PUMPKIN_STEM ].m_Transparent = true;
ms_Info[E_BLOCK_RAIL ].m_Transparent = true; a_Info[E_BLOCK_RAIL ].m_Transparent = true;
ms_Info[E_BLOCK_RED_MUSHROOM ].m_Transparent = true; a_Info[E_BLOCK_RED_MUSHROOM ].m_Transparent = true;
ms_Info[E_BLOCK_SIGN_POST ].m_Transparent = true; a_Info[E_BLOCK_SIGN_POST ].m_Transparent = true;
ms_Info[E_BLOCK_SNOW ].m_Transparent = true; a_Info[E_BLOCK_SNOW ].m_Transparent = true;
ms_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true; a_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true;
ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true; a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true;
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true; a_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true;
ms_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true; a_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true;
ms_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true; a_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true;
ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true;
ms_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true; a_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true;
ms_Info[E_BLOCK_TORCH ].m_Transparent = true; a_Info[E_BLOCK_TORCH ].m_Transparent = true;
ms_Info[E_BLOCK_VINES ].m_Transparent = true; a_Info[E_BLOCK_VINES ].m_Transparent = true;
ms_Info[E_BLOCK_WALLSIGN ].m_Transparent = true; a_Info[E_BLOCK_WALLSIGN ].m_Transparent = true;
ms_Info[E_BLOCK_WATER ].m_Transparent = true; a_Info[E_BLOCK_WATER ].m_Transparent = true;
ms_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true; a_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true;
ms_Info[E_BLOCK_WOODEN_DOOR ].m_Transparent = true; a_Info[E_BLOCK_WOODEN_DOOR ].m_Transparent = true;
ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Transparent = true; a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Transparent = true;
// TODO: Any other transparent blocks? // TODO: Any other transparent blocks?
// One hit break blocks: // One hit break blocks:
ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_OneHitDig = true; a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_OneHitDig = true;
ms_Info[E_BLOCK_BIG_FLOWER ].m_OneHitDig = true; a_Info[E_BLOCK_BIG_FLOWER ].m_OneHitDig = true;
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_OneHitDig = true; a_Info[E_BLOCK_BROWN_MUSHROOM ].m_OneHitDig = true;
ms_Info[E_BLOCK_CARROTS ].m_OneHitDig = true; a_Info[E_BLOCK_CARROTS ].m_OneHitDig = true;
ms_Info[E_BLOCK_CROPS ].m_OneHitDig = true; a_Info[E_BLOCK_CROPS ].m_OneHitDig = true;
ms_Info[E_BLOCK_DANDELION ].m_OneHitDig = true; a_Info[E_BLOCK_DANDELION ].m_OneHitDig = true;
ms_Info[E_BLOCK_FIRE ].m_OneHitDig = true; a_Info[E_BLOCK_FIRE ].m_OneHitDig = true;
ms_Info[E_BLOCK_FLOWER ].m_OneHitDig = true; a_Info[E_BLOCK_FLOWER ].m_OneHitDig = true;
ms_Info[E_BLOCK_FLOWER_POT ].m_OneHitDig = true; a_Info[E_BLOCK_FLOWER_POT ].m_OneHitDig = true;
ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true; a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true;
ms_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true; a_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true;
ms_Info[E_BLOCK_POTATOES ].m_OneHitDig = true; a_Info[E_BLOCK_POTATOES ].m_OneHitDig = true;
ms_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true; a_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true;
ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true; a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true;
ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_OneHitDig = true; a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_OneHitDig = true;
ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_OneHitDig = true; a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_OneHitDig = true;
ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_OneHitDig = true; a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_OneHitDig = true;
ms_Info[E_BLOCK_REDSTONE_WIRE ].m_OneHitDig = true; a_Info[E_BLOCK_REDSTONE_WIRE ].m_OneHitDig = true;
ms_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true; a_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true;
ms_Info[E_BLOCK_REEDS ].m_OneHitDig = true; a_Info[E_BLOCK_REEDS ].m_OneHitDig = true;
ms_Info[E_BLOCK_SAPLING ].m_OneHitDig = true; a_Info[E_BLOCK_SAPLING ].m_OneHitDig = true;
ms_Info[E_BLOCK_TNT ].m_OneHitDig = true; a_Info[E_BLOCK_TNT ].m_OneHitDig = true;
ms_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true; a_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true;
ms_Info[E_BLOCK_TORCH ].m_OneHitDig = true; a_Info[E_BLOCK_TORCH ].m_OneHitDig = true;
// Blocks that break when pushed by piston: // Blocks that break when pushed by piston:
ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PistonBreakable = true; a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PistonBreakable = true;
ms_Info[E_BLOCK_AIR ].m_PistonBreakable = true; a_Info[E_BLOCK_AIR ].m_PistonBreakable = true;
ms_Info[E_BLOCK_BED ].m_PistonBreakable = true; a_Info[E_BLOCK_BED ].m_PistonBreakable = true;
ms_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true; a_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true;
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true; a_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true;
ms_Info[E_BLOCK_CAKE ].m_PistonBreakable = true; a_Info[E_BLOCK_CAKE ].m_PistonBreakable = true;
ms_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true; a_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true;
ms_Info[E_BLOCK_CROPS ].m_PistonBreakable = true; a_Info[E_BLOCK_CROPS ].m_PistonBreakable = true;
ms_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true; a_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true;
ms_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true; a_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true;
ms_Info[E_BLOCK_FIRE ].m_PistonBreakable = true; a_Info[E_BLOCK_FIRE ].m_PistonBreakable = true;
ms_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true; a_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true;
ms_Info[E_BLOCK_HEAD ].m_PistonBreakable = true; a_Info[E_BLOCK_HEAD ].m_PistonBreakable = true;
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true; a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true;
ms_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true; a_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true;
ms_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true; a_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true;
ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
ms_Info[E_BLOCK_LADDER ].m_PistonBreakable = true; a_Info[E_BLOCK_LADDER ].m_PistonBreakable = true;
ms_Info[E_BLOCK_LAVA ].m_PistonBreakable = true; a_Info[E_BLOCK_LAVA ].m_PistonBreakable = true;
ms_Info[E_BLOCK_LEVER ].m_PistonBreakable = true; a_Info[E_BLOCK_LEVER ].m_PistonBreakable = true;
ms_Info[E_BLOCK_MELON ].m_PistonBreakable = true; a_Info[E_BLOCK_MELON ].m_PistonBreakable = true;
ms_Info[E_BLOCK_MELON_STEM ].m_PistonBreakable = true; a_Info[E_BLOCK_MELON_STEM ].m_PistonBreakable = true;
ms_Info[E_BLOCK_PUMPKIN ].m_PistonBreakable = true; a_Info[E_BLOCK_PUMPKIN ].m_PistonBreakable = true;
ms_Info[E_BLOCK_PUMPKIN_STEM ].m_PistonBreakable = true; a_Info[E_BLOCK_PUMPKIN_STEM ].m_PistonBreakable = true;
ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_PistonBreakable = true; a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_PistonBreakable = true;
ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_PistonBreakable = true; a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_PistonBreakable = true;
ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PistonBreakable = true; a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PistonBreakable = true;
ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PistonBreakable = true; a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PistonBreakable = true;
ms_Info[E_BLOCK_REDSTONE_WIRE ].m_PistonBreakable = true; a_Info[E_BLOCK_REDSTONE_WIRE ].m_PistonBreakable = true;
ms_Info[E_BLOCK_RED_MUSHROOM ].m_PistonBreakable = true; a_Info[E_BLOCK_RED_MUSHROOM ].m_PistonBreakable = true;
ms_Info[E_BLOCK_REEDS ].m_PistonBreakable = true; a_Info[E_BLOCK_REEDS ].m_PistonBreakable = true;
ms_Info[E_BLOCK_SNOW ].m_PistonBreakable = true; a_Info[E_BLOCK_SNOW ].m_PistonBreakable = true;
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_PistonBreakable = true; a_Info[E_BLOCK_STATIONARY_LAVA ].m_PistonBreakable = true;
ms_Info[E_BLOCK_STATIONARY_WATER ].m_PistonBreakable = true; a_Info[E_BLOCK_STATIONARY_WATER ].m_PistonBreakable = true;
ms_Info[E_BLOCK_STONE_BUTTON ].m_PistonBreakable = true; a_Info[E_BLOCK_STONE_BUTTON ].m_PistonBreakable = true;
ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true;
ms_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true; a_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true;
ms_Info[E_BLOCK_TORCH ].m_PistonBreakable = true; a_Info[E_BLOCK_TORCH ].m_PistonBreakable = true;
ms_Info[E_BLOCK_VINES ].m_PistonBreakable = true; a_Info[E_BLOCK_VINES ].m_PistonBreakable = true;
ms_Info[E_BLOCK_WATER ].m_PistonBreakable = true; a_Info[E_BLOCK_WATER ].m_PistonBreakable = true;
ms_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true; a_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true;
ms_Info[E_BLOCK_WOODEN_DOOR ].m_PistonBreakable = true; a_Info[E_BLOCK_WOODEN_DOOR ].m_PistonBreakable = true;
ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_PistonBreakable = true; a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_PistonBreakable = true;
// Blocks that cannot be snowed over: // Blocks that cannot be snowed over:
ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_IsSnowable = false; a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_IsSnowable = false;
ms_Info[E_BLOCK_AIR ].m_IsSnowable = false; a_Info[E_BLOCK_AIR ].m_IsSnowable = false;
ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSnowable = false; a_Info[E_BLOCK_BIG_FLOWER ].m_IsSnowable = false;
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSnowable = false; a_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSnowable = false;
ms_Info[E_BLOCK_CACTUS ].m_IsSnowable = false; a_Info[E_BLOCK_CACTUS ].m_IsSnowable = false;
ms_Info[E_BLOCK_CHEST ].m_IsSnowable = false; a_Info[E_BLOCK_CHEST ].m_IsSnowable = false;
ms_Info[E_BLOCK_CROPS ].m_IsSnowable = false; a_Info[E_BLOCK_CROPS ].m_IsSnowable = false;
ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_IsSnowable = false; a_Info[E_BLOCK_COBBLESTONE_WALL ].m_IsSnowable = false;
ms_Info[E_BLOCK_DANDELION ].m_IsSnowable = false; a_Info[E_BLOCK_DANDELION ].m_IsSnowable = false;
ms_Info[E_BLOCK_FIRE ].m_IsSnowable = false; a_Info[E_BLOCK_FIRE ].m_IsSnowable = false;
ms_Info[E_BLOCK_FLOWER ].m_IsSnowable = false; a_Info[E_BLOCK_FLOWER ].m_IsSnowable = false;
ms_Info[E_BLOCK_GLASS ].m_IsSnowable = false; a_Info[E_BLOCK_GLASS ].m_IsSnowable = false;
ms_Info[E_BLOCK_ICE ].m_IsSnowable = false; a_Info[E_BLOCK_ICE ].m_IsSnowable = false;
ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_IsSnowable = false; a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_IsSnowable = false;
ms_Info[E_BLOCK_LAVA ].m_IsSnowable = false; a_Info[E_BLOCK_LAVA ].m_IsSnowable = false;
ms_Info[E_BLOCK_LILY_PAD ].m_IsSnowable = false; a_Info[E_BLOCK_LILY_PAD ].m_IsSnowable = false;
ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_IsSnowable = false; a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_IsSnowable = false;
ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_IsSnowable = false; a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_IsSnowable = false;
ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSnowable = false; a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSnowable = false;
ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSnowable = false; a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSnowable = false;
ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSnowable = false; a_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSnowable = false;
ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSnowable = false; a_Info[E_BLOCK_RED_MUSHROOM ].m_IsSnowable = false;
ms_Info[E_BLOCK_REEDS ].m_IsSnowable = false; a_Info[E_BLOCK_REEDS ].m_IsSnowable = false;
ms_Info[E_BLOCK_SAPLING ].m_IsSnowable = false; a_Info[E_BLOCK_SAPLING ].m_IsSnowable = false;
ms_Info[E_BLOCK_SIGN_POST ].m_IsSnowable = false; a_Info[E_BLOCK_SIGN_POST ].m_IsSnowable = false;
ms_Info[E_BLOCK_SNOW ].m_IsSnowable = false; a_Info[E_BLOCK_SNOW ].m_IsSnowable = false;
ms_Info[E_BLOCK_STAINED_GLASS ].m_IsSnowable = false; a_Info[E_BLOCK_STAINED_GLASS ].m_IsSnowable = false;
ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_IsSnowable = false; a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_IsSnowable = false;
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSnowable = false; a_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSnowable = false;
ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSnowable = false; a_Info[E_BLOCK_STATIONARY_WATER ].m_IsSnowable = false;
ms_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false; a_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false;
ms_Info[E_BLOCK_TNT ].m_IsSnowable = false; a_Info[E_BLOCK_TNT ].m_IsSnowable = false;
ms_Info[E_BLOCK_TORCH ].m_IsSnowable = false; a_Info[E_BLOCK_TORCH ].m_IsSnowable = false;
ms_Info[E_BLOCK_VINES ].m_IsSnowable = false; a_Info[E_BLOCK_VINES ].m_IsSnowable = false;
ms_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false; a_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false;
ms_Info[E_BLOCK_WATER ].m_IsSnowable = false; a_Info[E_BLOCK_WATER ].m_IsSnowable = false;
ms_Info[E_BLOCK_RAIL ].m_IsSnowable = false; a_Info[E_BLOCK_RAIL ].m_IsSnowable = false;
ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSnowable = false; a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSnowable = false;
ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false; a_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false;
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false; a_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false;
ms_Info[E_BLOCK_COBWEB ].m_IsSnowable = false; a_Info[E_BLOCK_COBWEB ].m_IsSnowable = false;
ms_Info[E_BLOCK_HEAD ].m_IsSnowable = false; a_Info[E_BLOCK_HEAD ].m_IsSnowable = false;
// Blocks that don't drop without a special tool: // Blocks that don't drop without a special tool:
ms_Info[E_BLOCK_BRICK ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_BRICK ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_COBBLESTONE_WALL ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_DIAMOND_ORE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_DIAMOND_ORE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_EMERALD_ORE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_EMERALD_ORE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_END_STONE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_END_STONE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_GOLD_BLOCK ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_GOLD_BLOCK ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_GOLD_ORE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_GOLD_ORE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true; a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_IRON_BLOCK ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_IRON_BLOCK ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_IRON_ORE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_IRON_ORE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_LAPIS_BLOCK ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_LAPIS_BLOCK ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_LAPIS_ORE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_LAPIS_ORE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true; a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_NETHERRACK ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_NETHERRACK ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_NETHER_BRICK ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_NETHER_BRICK ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_OBSIDIAN ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_OBSIDIAN ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_REDSTONE_ORE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_REDSTONE_ORE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_RequiresSpecialTool = true; a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_SANDSTONE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_SANDSTONE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_SANDSTONE_STAIRS ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_SANDSTONE_STAIRS ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_SNOW ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_SNOW ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_STONE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_STONE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_STONE_BRICKS ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_STONE_BRICKS ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_FURNACE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_FURNACE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_LIT_FURNACE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_LIT_FURNACE ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_ANVIL ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_ANVIL ].m_RequiresSpecialTool = true;
ms_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_RequiresSpecialTool = true; a_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_RequiresSpecialTool = true;
// Nonsolid blocks: // Nonsolid blocks:
ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSolid = false; a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSolid = false;
ms_Info[E_BLOCK_AIR ].m_IsSolid = false; a_Info[E_BLOCK_AIR ].m_IsSolid = false;
ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false; a_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false;
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false; a_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false;
ms_Info[E_BLOCK_CAKE ].m_IsSolid = false; a_Info[E_BLOCK_CAKE ].m_IsSolid = false;
ms_Info[E_BLOCK_CARROTS ].m_IsSolid = false; a_Info[E_BLOCK_CARROTS ].m_IsSolid = false;
ms_Info[E_BLOCK_COBWEB ].m_IsSolid = false; a_Info[E_BLOCK_COBWEB ].m_IsSolid = false;
ms_Info[E_BLOCK_CROPS ].m_IsSolid = false; a_Info[E_BLOCK_CROPS ].m_IsSolid = false;
ms_Info[E_BLOCK_DANDELION ].m_IsSolid = false; a_Info[E_BLOCK_DANDELION ].m_IsSolid = false;
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false; a_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false;
ms_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false; a_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false;
ms_Info[E_BLOCK_FIRE ].m_IsSolid = false; a_Info[E_BLOCK_FENCE ].m_IsSolid = false;
ms_Info[E_BLOCK_FLOWER ].m_IsSolid = false; a_Info[E_BLOCK_FENCE_GATE ].m_IsSolid = false;
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false; a_Info[E_BLOCK_FIRE ].m_IsSolid = false;
ms_Info[E_BLOCK_LAVA ].m_IsSolid = false; a_Info[E_BLOCK_FLOWER ].m_IsSolid = false;
ms_Info[E_BLOCK_LEVER ].m_IsSolid = false; a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false; a_Info[E_BLOCK_LAVA ].m_IsSolid = false;
ms_Info[E_BLOCK_MELON_STEM ].m_IsSolid = false; a_Info[E_BLOCK_LEVER ].m_IsSolid = false;
ms_Info[E_BLOCK_NETHER_PORTAL ].m_IsSolid = false; a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false;
ms_Info[E_BLOCK_PISTON_EXTENSION ].m_IsSolid = false; a_Info[E_BLOCK_MELON_STEM ].m_IsSolid = false;
ms_Info[E_BLOCK_POTATOES ].m_IsSolid = false; a_Info[E_BLOCK_NETHER_PORTAL ].m_IsSolid = false;
ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false; a_Info[E_BLOCK_PISTON_EXTENSION ].m_IsSolid = false;
ms_Info[E_BLOCK_RAIL ].m_IsSolid = false; a_Info[E_BLOCK_POTATOES ].m_IsSolid = false;
ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false; a_Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false;
ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false; a_Info[E_BLOCK_RAIL ].m_IsSolid = false;
ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false; a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false;
ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false; a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false;
ms_Info[E_BLOCK_REEDS ].m_IsSolid = false; a_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false;
ms_Info[E_BLOCK_SAPLING ].m_IsSolid = false; a_Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false;
ms_Info[E_BLOCK_SIGN_POST ].m_IsSolid = false; a_Info[E_BLOCK_REEDS ].m_IsSolid = false;
ms_Info[E_BLOCK_SNOW ].m_IsSolid = false; a_Info[E_BLOCK_SAPLING ].m_IsSolid = false;
ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false; a_Info[E_BLOCK_SIGN_POST ].m_IsSolid = false;
ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false; a_Info[E_BLOCK_SNOW ].m_IsSolid = false;
ms_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false; a_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false;
ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false; a_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false;
ms_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false; a_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false;
ms_Info[E_BLOCK_TORCH ].m_IsSolid = false; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false;
ms_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false; a_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false;
ms_Info[E_BLOCK_VINES ].m_IsSolid = false; a_Info[E_BLOCK_TORCH ].m_IsSolid = false;
ms_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false; a_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false;
ms_Info[E_BLOCK_WATER ].m_IsSolid = false; a_Info[E_BLOCK_VINES ].m_IsSolid = false;
ms_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false; a_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false;
ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_IsSolid = false; a_Info[E_BLOCK_WATER ].m_IsSolid = false;
ms_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false; a_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false;
a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_IsSolid = false;
a_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false;
// Blocks that fully occupy their voxel - used as a guide for torch placeable blocks, amongst other things: // Blocks that fully occupy their voxel - used as a guide for torch placeable blocks, amongst other things:
ms_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_BOOKCASE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_BOOKCASE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_BRICK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_BRICK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_CLAY ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_CLAY ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_COAL_ORE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_COAL_ORE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_COBBLESTONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_COBBLESTONE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_COMMAND_BLOCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_COMMAND_BLOCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_CRAFTING_TABLE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_CRAFTING_TABLE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_DIAMOND_BLOCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_DIAMOND_ORE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_DIAMOND_ORE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_DIRT ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_DIRT ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_DISPENSER ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_DISPENSER ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_DROPPER ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_DROPPER ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_EMERALD_BLOCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_EMERALD_BLOCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_EMERALD_ORE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_EMERALD_ORE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_END_STONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_END_STONE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_FURNACE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_FURNACE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_GLOWSTONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_GLOWSTONE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_GOLD_BLOCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_GOLD_BLOCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_GOLD_ORE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_GOLD_ORE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_GRASS ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_GRASS ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_GRAVEL ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_GRAVEL ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_HARDENED_CLAY ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_HARDENED_CLAY ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_ICE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_ICE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_JUKEBOX ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_JUKEBOX ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_LAPIS_BLOCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_LAPIS_BLOCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_SANDSTONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_SANDSTONE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_SAND ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_SAND ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_SILVERFISH_EGG ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_SILVERFISH_EGG ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_SPONGE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_SPONGE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_STAINED_CLAY ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_STAINED_CLAY ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true;
ms_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true; a_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true;
} }
// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor:
class cBlockInfoInitializer
{
public:
cBlockInfoInitializer(void)
{
cBlockInfo::Initialize();
}
} BlockInfoInitializer;

View File

@ -16,18 +16,8 @@ class cBlockHandler;
class cBlockInfo class cBlockInfo
{ {
public: public:
// tolua_end
cBlockInfo(); /** Returns the associated BlockInfo structure for the specified block type. */
~cBlockInfo();
/** (Re-)Initializes the internal BlockInfo structures. */
static void Initialize(void);
// tolua_begin
/** Returns the associated BlockInfo structure. */
static cBlockInfo & Get(BLOCKTYPE a_Type); static cBlockInfo & Get(BLOCKTYPE a_Type);
@ -79,13 +69,18 @@ public:
inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler; } inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler; }
protected: protected:
/** Storage for all the BlockInfo structures. */
typedef cBlockInfo cBlockInfoArray[256];
// TODO xdot: Change to std::vector to support dynamic block IDs /** Creates a default BlockInfo structure, initializes all values to their defaults */
static cBlockInfo ms_Info[256]; cBlockInfo();
/** Cleans up the stored values */
~cBlockInfo();
/** Initializes the specified BlockInfo structures with block-specific values. */
static void Initialize(cBlockInfoArray & a_BlockInfos);
}; // tolua_export }; // tolua_export

View File

@ -45,9 +45,16 @@ void cBlockDoorHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldIn
void cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) void cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ)
{ {
UNUSED(a_WorldInterface);
UNUSED(a_BlockFace);
UNUSED(a_CursorX);
UNUSED(a_CursorY);
UNUSED(a_CursorZ);
if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR) if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR)
{ {
ChangeDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); ChangeDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle());
} }
} }

View File

@ -45,6 +45,7 @@ public:
// Standing aside - use last direction // Standing aside - use last direction
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, OldMetaData);
} }
a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle());
} }

View File

@ -36,8 +36,8 @@ public:
- Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir - Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir
*/ */
a_BlockY--; // Because we want the block below the fire // a_BlockY - 1: Because we want the block below the fire
FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_ChunkInterface, a_WorldInterface); FindAndSetPortalFrame(a_BlockX, a_BlockY - 1, a_BlockZ, a_ChunkInterface, a_WorldInterface);
} }
virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override

View File

@ -38,6 +38,7 @@
#include "BlockGlass.h" #include "BlockGlass.h"
#include "BlockGlowstone.h" #include "BlockGlowstone.h"
#include "BlockGravel.h" #include "BlockGravel.h"
#include "BlockHayBale.h"
#include "BlockMobHead.h" #include "BlockMobHead.h"
#include "BlockHopper.h" #include "BlockHopper.h"
#include "BlockIce.h" #include "BlockIce.h"
@ -56,6 +57,7 @@
#include "BlockPlanks.h" #include "BlockPlanks.h"
#include "BlockPortal.h" #include "BlockPortal.h"
#include "BlockPumpkin.h" #include "BlockPumpkin.h"
#include "BlockPressurePlate.h"
#include "BlockQuartz.h" #include "BlockQuartz.h"
#include "BlockRail.h" #include "BlockRail.h"
#include "BlockRedstone.h" #include "BlockRedstone.h"
@ -83,6 +85,91 @@
/*
// Tests the meta rotation and mirroring.
// Note that the cMetaRotator needs to have its assert paths disabled for this test to work!
static class cBlockHandlerRotationTester
{
public:
cBlockHandlerRotationTester(void)
{
printf("Performing block handlers test...\n");
for (BLOCKTYPE Type = 0; Type < E_BLOCK_MAX_TYPE_ID; Type++)
{
cBlockHandler * Handler = cBlockInfo::GetHandler(Type);
if (Handler == NULL)
{
printf("NULL handler for block type %d!\n", Type);
continue;
}
AString BlockName = ItemTypeToString(Type);
for (NIBBLETYPE Meta = 0; Meta < 16; Meta++)
{
// Test the CW / CCW rotations:
NIBBLETYPE TestMeta;
TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaRotateCW(Meta))));
if (TestMeta != Meta)
{
// 4 CW rotations should produce no change in the meta
printf("Handler for blocktype %d (%s) fails CW 4-rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
}
TestMeta = Handler->MetaRotateCCW(Handler->MetaRotateCCW(Handler->MetaRotateCCW(Handler->MetaRotateCCW(Meta))));
if (TestMeta != Meta)
{
// 4 CCW rotations should produce no change in the meta
printf("Handler for blocktype %d (%s) fails CCW 4-rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
}
TestMeta = Handler->MetaRotateCCW(Handler->MetaRotateCW(Meta));
if (TestMeta != Meta)
{
// CCW rotation of a CW rotation should produce no change in the meta
printf("Handler for blocktype %d (%s) fails CCW(CW) rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
}
TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCCW(Meta));
if (TestMeta != Meta)
{
// CW rotation of a CCW rotation should produce no change in the meta
printf("Handler for blocktype %d (%s) fails CW(CCW) rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
}
// Test the mirroring:
TestMeta = Handler->MetaMirrorXY(Handler->MetaMirrorXY(Meta));
if (TestMeta != Meta)
{
// Double-mirroring should produce the same meta:
printf("Handler for blocktype %d (%s) fails XY mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
}
TestMeta = Handler->MetaMirrorXZ(Handler->MetaMirrorXZ(Meta));
if (TestMeta != Meta)
{
// Double-mirroring should produce the same meta:
printf("Handler for blocktype %d (%s) fails XZ mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
}
TestMeta = Handler->MetaMirrorYZ(Handler->MetaMirrorYZ(Meta));
if (TestMeta != Meta)
{
// Double-mirroring should produce the same meta:
printf("Handler for blocktype %d (%s) fails YZ mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
}
// Test mirror-rotating:
TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaMirrorXY(Handler->MetaMirrorYZ(Meta))));
if (TestMeta != Meta)
{
// 2 CW rotations should be the same as XY, YZ mirroring:
printf("Handler for blocktype %d (%s) fails rotation-mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta);
}
}
} // for Type
printf("Block handlers test complete.\n");
}
} g_BlockHandlerRotationTester;
//*/
cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
{ {
switch(a_BlockType) switch(a_BlockType)
@ -130,10 +217,12 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_GLOWSTONE: return new cBlockGlowstoneHandler (a_BlockType); case E_BLOCK_GLOWSTONE: return new cBlockGlowstoneHandler (a_BlockType);
case E_BLOCK_GOLD_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_GOLD_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_GLASS: return new cBlockGlassHandler (a_BlockType); case E_BLOCK_GLASS: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType); case E_BLOCK_GRASS: return new cBlockDirtHandler (a_BlockType);
case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType); case E_BLOCK_GRAVEL: return new cBlockGravelHandler (a_BlockType);
case E_BLOCK_HAY_BALE: return new cBlockSidewaysHandler (a_BlockType); case E_BLOCK_HAY_BALE: return new cBlockHayBaleHandler (a_BlockType);
case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType); case E_BLOCK_HEAD: return new cBlockMobHeadHandler (a_BlockType);
case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType); case E_BLOCK_HOPPER: return new cBlockHopperHandler (a_BlockType);
case E_BLOCK_ICE: return new cBlockIceHandler (a_BlockType); case E_BLOCK_ICE: return new cBlockIceHandler (a_BlockType);
case E_BLOCK_INACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType); case E_BLOCK_INACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType);
@ -149,6 +238,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType); case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType);
case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType); case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType);
case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType); case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType);
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: return new cBlockPressurePlateHandler(a_BlockType);
case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType); case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType);
case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType); case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType);
case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType); case E_BLOCK_MELON_STEM: return new cBlockStemsHandler (a_BlockType);
@ -170,7 +260,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_QUARTZ_BLOCK: return new cBlockQuartzHandler (a_BlockType); case E_BLOCK_QUARTZ_BLOCK: return new cBlockQuartzHandler (a_BlockType);
case E_BLOCK_QUARTZ_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_QUARTZ_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType); case E_BLOCK_RAIL: return new cBlockRailHandler (a_BlockType);
case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType); // We need this to change pickups to an off lamp; else 1.7+ clients crash case E_BLOCK_REDSTONE_LAMP_ON: return new cBlockRedstoneLampHandler (a_BlockType);
case E_BLOCK_REDSTONE_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_REDSTONE_ORE: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_REDSTONE_ORE_GLOWING: return new cBlockOreHandler (a_BlockType); case E_BLOCK_REDSTONE_ORE_GLOWING: return new cBlockOreHandler (a_BlockType);
case E_BLOCK_REDSTONE_REPEATER_OFF: return new cBlockRedstoneRepeaterHandler(a_BlockType); case E_BLOCK_REDSTONE_REPEATER_OFF: return new cBlockRedstoneRepeaterHandler(a_BlockType);
@ -186,12 +276,15 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_SIGN_POST: return new cBlockSignHandler (a_BlockType); case E_BLOCK_SIGN_POST: return new cBlockSignHandler (a_BlockType);
case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType); case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType);
case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_STAINED_GLASS: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_STAINED_GLASS_PANE: return new cBlockGlassHandler (a_BlockType);
case E_BLOCK_STATIONARY_LAVA: return new cBlockLavaHandler (a_BlockType); case E_BLOCK_STATIONARY_LAVA: return new cBlockLavaHandler (a_BlockType);
case E_BLOCK_STATIONARY_WATER: return new cBlockFluidHandler (a_BlockType); case E_BLOCK_STATIONARY_WATER: return new cBlockFluidHandler (a_BlockType);
case E_BLOCK_STICKY_PISTON: return new cBlockPistonHandler (a_BlockType); case E_BLOCK_STICKY_PISTON: return new cBlockPistonHandler (a_BlockType);
case E_BLOCK_STONE: return new cBlockStoneHandler (a_BlockType); case E_BLOCK_STONE: return new cBlockStoneHandler (a_BlockType);
case E_BLOCK_STONE_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_STONE_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_STONE_BUTTON: return new cBlockButtonHandler (a_BlockType); case E_BLOCK_STONE_BUTTON: return new cBlockButtonHandler (a_BlockType);
case E_BLOCK_STONE_PRESSURE_PLATE: return new cBlockPressurePlateHandler (a_BlockType);
case E_BLOCK_STONE_SLAB: return new cBlockSlabHandler (a_BlockType); case E_BLOCK_STONE_SLAB: return new cBlockSlabHandler (a_BlockType);
case E_BLOCK_SUGARCANE: return new cBlockSugarcaneHandler (a_BlockType); case E_BLOCK_SUGARCANE: return new cBlockSugarcaneHandler (a_BlockType);
case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType); case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType);
@ -199,10 +292,11 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType); case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType);
case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType); case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType);
case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType); case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType);
case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType); case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType); // TODO: This needs a special handler
case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType); case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType);
case E_BLOCK_WOODEN_BUTTON: return new cBlockButtonHandler (a_BlockType); case E_BLOCK_WOODEN_BUTTON: return new cBlockButtonHandler (a_BlockType);
case E_BLOCK_WOODEN_DOOR: return new cBlockDoorHandler (a_BlockType); case E_BLOCK_WOODEN_DOOR: return new cBlockDoorHandler (a_BlockType);
case E_BLOCK_WOODEN_PRESSURE_PLATE: return new cBlockPressurePlateHandler (a_BlockType);
case E_BLOCK_WOODEN_SLAB: return new cBlockSlabHandler (a_BlockType); case E_BLOCK_WOODEN_SLAB: return new cBlockSlabHandler (a_BlockType);
case E_BLOCK_WOODEN_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_WOODEN_STAIRS: return new cBlockStairsHandler (a_BlockType);
case E_BLOCK_WOOL: return new cBlockClothHandler (a_BlockType); case E_BLOCK_WOOL: return new cBlockClothHandler (a_BlockType);

29
src/Blocks/BlockHayBale.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#include "BlockHandler.h"
#include "BlockSideways.h"
class cBlockHayBaleHandler :
public cBlockSidewaysHandler
{
public:
cBlockHayBaleHandler(BLOCKTYPE a_BlockType)
: cBlockSidewaysHandler(a_BlockType)
{
}
virtual const char * GetStepSound(void) override
{
return "step.grass";
}
} ;

View File

@ -7,12 +7,13 @@
class cBlockLeverHandler : class cBlockLeverHandler :
public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false> public cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false>
{ {
typedef cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false> super; typedef cMetaRotator<cBlockHandler, 0x07, 0x04, 0x01, 0x03, 0x02, false> super;
public: public:
cBlockLeverHandler(BLOCKTYPE a_BlockType) cBlockLeverHandler(BLOCKTYPE a_BlockType) :
: cMetaRotator<cBlockHandler, 0x07, 0x04, 0x02, 0x03, 0x01, false>(a_BlockType) super(a_BlockType)
{ {
} }
@ -132,7 +133,7 @@ public:
case 0x05: return 0x06; // Ground rotation case 0x05: return 0x06; // Ground rotation
case 0x06: return 0x05; case 0x06: return 0x05;
default: return super::MetaRotateCCW(a_Meta); // Wall Rotation default: return super::MetaRotateCW(a_Meta); // Wall Rotation
} }
} }
} ; } ;

View File

@ -19,24 +19,69 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0)); // The drop spawn is in OnDestroyed method
}
virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
if (a_Player->IsGameModeCreative())
{
// No drops in creative mode
return;
}
class cCallback : public cBlockEntityCallback
{
virtual bool Item(cBlockEntity * a_BlockEntity)
{
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
{
return false;
}
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
cItems Pickups;
Pickups.Add(E_ITEM_HEAD, 1, (short) MobHeadEntity->GetType());
MTRand r1;
// Mid-block position first
double MicroX, MicroY, MicroZ;
MicroX = MobHeadEntity->GetPosX() + 0.5;
MicroY = MobHeadEntity->GetPosY() + 0.5;
MicroZ = MobHeadEntity->GetPosZ() + 0.5;
// Add random offset second
MicroX += r1.rand(1) - 0.5;
MicroZ += r1.rand(1) - 0.5;
MobHeadEntity->GetWorld()->SpawnItemPickups(Pickups, MicroX, MicroY, MicroZ);
return false;
}
} Callback;
a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
} }
bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
if (a_BlockY < 2) if (a_BlockY < 2)
{ {
return false; return false;
} }
class cCallback : public cMobHeadCallback class cCallback : public cBlockEntityCallback
{ {
bool m_IsWither; bool m_IsWither;
virtual bool Item (cMobHeadEntity * a_MobHeadEntity) virtual bool Item(cBlockEntity * a_BlockEntity)
{ {
m_IsWither = (a_MobHeadEntity->GetType() == SKULL_TYPE_WITHER); if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
{
return false;
}
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
m_IsWither = (MobHeadEntity->GetType() == SKULL_TYPE_WITHER);
return false; return false;
} }
@ -70,7 +115,7 @@ public:
} PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ)); } PlayerCallback(Vector3f((float)a_BlockX, (float)a_BlockY, (float)a_BlockZ));
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA); a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA);
if (!CallbackA.IsWither()) if (!CallbackA.IsWither())
{ {
@ -87,8 +132,8 @@ public:
return false; return false;
} }
a_World->DoWithMobHeadAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA); a_WorldInterface.DoWithBlockEntityAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA);
a_World->DoWithMobHeadAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB); a_WorldInterface.DoWithBlockEntityAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB);
BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ); BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ);
BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ); BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ);
@ -101,15 +146,15 @@ public:
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
// Block entities // Block entities
a_World->SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_World->SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
// Spawn the wither: // Spawn the wither:
a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
// Award Achievement // Award Achievement
a_World->ForEachPlayer(PlayerCallback); a_WorldInterface.ForEachPlayer(PlayerCallback);
return true; return true;
} }
@ -117,8 +162,8 @@ public:
CallbackA.Reset(); CallbackA.Reset();
CallbackB.Reset(); CallbackB.Reset();
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA); a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA);
a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB); a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB);
Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1); Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1);
Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1); Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1);
@ -131,15 +176,15 @@ public:
a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0);
// Block entities // Block entities
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0); a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0); a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0);
// Spawn the wither: // Spawn the wither:
a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); a_WorldInterface.SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither);
// Award Achievement // Award Achievement
a_World->ForEachPlayer(PlayerCallback); a_WorldInterface.ForEachPlayer(PlayerCallback);
return true; return true;
} }
@ -154,23 +199,29 @@ public:
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta
) override ) override
{ {
class cCallback : public cMobHeadCallback class cCallback : public cBlockEntityCallback
{ {
cPlayer * m_Player; cPlayer * m_Player;
NIBBLETYPE m_OldBlockMeta; NIBBLETYPE m_OldBlockMeta;
NIBBLETYPE m_NewBlockMeta; NIBBLETYPE m_NewBlockMeta;
virtual bool Item (cMobHeadEntity * a_MobHeadEntity) virtual bool Item(cBlockEntity * a_BlockEntity)
{ {
if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD)
{
return false;
}
cMobHeadEntity * MobHeadEntity = static_cast<cMobHeadEntity*>(a_BlockEntity);
int Rotation = 0; int Rotation = 0;
if (m_NewBlockMeta == 1) if (m_NewBlockMeta == 1)
{ {
Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF; Rotation = (int) floor(m_Player->GetYaw() * 16.0F / 360.0F + 0.5) & 0xF;
} }
a_MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta)); MobHeadEntity->SetType(static_cast<eMobHeadType>(m_OldBlockMeta));
a_MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation)); MobHeadEntity->SetRotation(static_cast<eMobHeadRotation>(Rotation));
a_MobHeadEntity->GetWorld()->BroadcastBlockEntity(a_MobHeadEntity->GetPosX(), a_MobHeadEntity->GetPosY(), a_MobHeadEntity->GetPosZ(), m_Player->GetClientHandle()); MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ());
return false; return false;
} }
@ -184,8 +235,7 @@ public:
cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace)); cCallback Callback(a_Player, a_BlockMeta, static_cast<NIBBLETYPE>(a_BlockFace));
a_BlockMeta = (NIBBLETYPE)a_BlockFace; a_BlockMeta = (NIBBLETYPE)a_BlockFace;
cWorld * World = (cWorld *) &a_WorldInterface; a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback);
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
if (a_BlockMeta == SKULL_TYPE_WITHER) if (a_BlockMeta == SKULL_TYPE_WITHER)
@ -200,7 +250,7 @@ public:
}; };
for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i) for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i)
{ {
if (TrySpawnWither(a_ChunkInterface, World, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z)) if (TrySpawnWither(a_ChunkInterface, a_WorldInterface, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z))
{ {
break; break;
} }

View File

@ -0,0 +1,38 @@
#pragma once
#include "BlockHandler.h"
class cBlockPressurePlateHandler :
public cBlockHandler
{
public:
cBlockPressurePlateHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
// Reset meta to 0
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
{
if (a_RelY <= 0)
{
return false;
}
BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ);
return ((BlockBelow == E_BLOCK_FENCE_GATE) || (BlockBelow == E_BLOCK_FENCE) || cBlockInfo::IsSolid(BlockBelow));
}
} ;

View File

@ -75,13 +75,13 @@ public:
virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override
{ {
return (++a_Meta) & 0x0F; return (a_Meta + 4) & 0x0f;
} }
virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override
{ {
return (--a_Meta) & 0x0F; return (a_Meta + 12) & 0x0f;
} }
virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override
@ -90,7 +90,7 @@ public:
// There are 16 meta values which correspond to different directions. // There are 16 meta values which correspond to different directions.
// These values are equated to angles on a circle; 0x08 = 180 degrees. // These values are equated to angles on a circle; 0x08 = 180 degrees.
return (a_Meta < 0x08) ? 0x08 + a_Meta : 0x08 - a_Meta; return (a_Meta < 0x08) ? (0x08 + a_Meta) : (0x08 - a_Meta);
} }

View File

@ -80,6 +80,7 @@ public:
if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))) if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)))
{ {
a_BlockType = GetDoubleSlabType(m_BlockType); a_BlockType = GetDoubleSlabType(m_BlockType);
a_BlockMeta = a_BlockMeta & 0x7;
} }
return true; return true;
@ -123,6 +124,12 @@ public:
return E_BLOCK_AIR; return E_BLOCK_AIR;
} }
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
{
// Toggle the 4th bit - up / down:
return (a_Meta ^ 0x08);
}
} ; } ;
@ -166,15 +173,6 @@ public:
ASSERT(!"Unhandled double slab type!"); ASSERT(!"Unhandled double slab type!");
return ""; return "";
} }
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
{
NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelated meta data.
// 8th bit is up/down. 1 right-side-up, 0 is up-side-down.
return (a_Meta & 0x08) ? 0x00 + OtherMeta : 0x01 + OtherMeta;
}
} ; } ;

View File

@ -6,6 +6,12 @@
class cItems; class cItems;
typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
class cWorldInterface class cWorldInterface
{ {
public: public:
@ -29,6 +35,9 @@ public:
/** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0; virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0;
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) = 0;
/** Sends the block on those coords to the player */ /** Sends the block on those coords to the player */
virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0; virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0;

View File

@ -165,6 +165,7 @@ cByteBuffer::~cByteBuffer()
{ {
CheckValid(); CheckValid();
delete[] m_Buffer; delete[] m_Buffer;
m_Buffer = NULL;
} }

View File

@ -152,7 +152,9 @@ cChunk::~cChunk()
m_NeighborZP->m_NeighborZM = NULL; m_NeighborZP->m_NeighborZM = NULL;
} }
delete m_WaterSimulatorData; delete m_WaterSimulatorData;
m_WaterSimulatorData = NULL;
delete m_LavaSimulatorData; delete m_LavaSimulatorData;
m_LavaSimulatorData = NULL;
} }
@ -596,6 +598,7 @@ void cChunk::Tick(float a_Dt)
cEntity * ToDelete = *itr; cEntity * ToDelete = *itr;
itr = m_Entities.erase(itr); itr = m_Entities.erase(itr);
delete ToDelete; delete ToDelete;
ToDelete = NULL;
continue; continue;
} }
++itr; ++itr;
@ -1417,6 +1420,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType,
BlockEntity->Destroy(); BlockEntity->Destroy();
RemoveBlockEntity(BlockEntity); RemoveBlockEntity(BlockEntity);
delete BlockEntity; delete BlockEntity;
BlockEntity = NULL;
} }
// If the new block is a block entity, create the entity object: // If the new block is a block entity, create the entity object:
@ -1612,6 +1616,12 @@ void cChunk::AddBlockEntity(cBlockEntity * a_BlockEntity)
cBlockEntity * cChunk::GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ) cBlockEntity * cChunk::GetBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
// Check that the query coords are within chunk bounds:
ASSERT(a_BlockX >= m_PosX * cChunkDef::Width);
ASSERT(a_BlockX < m_PosX * cChunkDef::Width + cChunkDef::Width);
ASSERT(a_BlockZ >= m_PosZ * cChunkDef::Width);
ASSERT(a_BlockZ < m_PosZ * cChunkDef::Width + cChunkDef::Width);
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
{ {
if ( if (

View File

@ -1,9 +0,0 @@
#include "Globals.h"
#include "ChunkDef.h"
// It appears that failing to have this definition causes link errors as cChunkDef::Height is not
// defined. It also appears that we can have the initalizer in the declaration so it can be inlined
// if the declaration is in a class????
const int cChunkDef::Height;

View File

@ -35,8 +35,8 @@ class cBlockArea;
class cMobCensus; class cMobCensus;
class cMobSpawner; class cMobSpawner;
typedef std::list<cClientHandle *> cClientHandleList; typedef std::list<cClientHandle *> cClientHandleList;
typedef cChunk * cChunkPtr; typedef cChunk * cChunkPtr;
typedef cItemCallback<cEntity> cEntityCallback; typedef cItemCallback<cEntity> cEntityCallback;
typedef cItemCallback<cBlockEntity> cBlockEntityCallback; typedef cItemCallback<cBlockEntity> cBlockEntityCallback;
typedef cItemCallback<cChestEntity> cChestCallback; typedef cItemCallback<cChestEntity> cChestCallback;

View File

@ -232,6 +232,9 @@ AString cClientHandle::FormatMessageType(bool ShouldAppendChatPrefixes, eMessage
AString cClientHandle::GenerateOfflineUUID(const AString & a_Username) AString cClientHandle::GenerateOfflineUUID(const AString & a_Username)
{ {
// Online UUIDs are always version 4 (random)
// We use Version 3 (MD5 hash) UUIDs for the offline UUIDs
// This guarantees that they will never collide with an online UUID and can be distinguished.
// Proper format for a version 3 UUID is: // Proper format for a version 3 UUID is:
// xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B // xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B
@ -254,6 +257,32 @@ AString cClientHandle::GenerateOfflineUUID(const AString & a_Username)
bool cClientHandle::IsUUIDOnline(const AString & a_UUID)
{
// Online UUIDs are always version 4 (random)
// We use Version 3 (MD5 hash) UUIDs for the offline UUIDs
// This guarantees that they will never collide with an online UUID and can be distinguished.
// The version-specifying char is at pos #12 of raw UUID, pos #14 in dashed-UUID.
switch (a_UUID.size())
{
case 32:
{
// This is the UUID format without dashes, the version char is at pos #12:
return (a_UUID[12] == '4');
}
case 36:
{
// This is the UUID format with dashes, the version char is at pos #14:
return (a_UUID[14] == '4');
}
}
return false;
}
void cClientHandle::Kick(const AString & a_Reason) void cClientHandle::Kick(const AString & a_Reason)
{ {
if (m_State >= csAuthenticating) // Don't log pings if (m_State >= csAuthenticating) // Don't log pings
@ -953,6 +982,26 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
m_LastDigBlockY = a_BlockY; m_LastDigBlockY = a_BlockY;
m_LastDigBlockZ = a_BlockZ; m_LastDigBlockZ = a_BlockZ;
// Check for clickthrough-blocks:
/* When the user breaks a fire block, the client send the wrong block location.
We must find the right block with the face direction. */
if (a_BlockFace != BLOCK_FACE_NONE)
{
int pX = a_BlockX;
int pY = a_BlockY;
int pZ = a_BlockZ;
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
cBlockHandler * Handler = cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(pX, pY, pZ));
if (Handler->IsClickedThrough())
{
cChunkInterface ChunkInterface(m_Player->GetWorld()->GetChunkMap());
Handler->OnDigging(ChunkInterface, *m_Player->GetWorld(), m_Player, pX, pY, pZ);
return;
}
}
if ( if (
(m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately (m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately
cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too
@ -979,22 +1028,6 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
ItemHandler->OnDiggingBlock(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); ItemHandler->OnDiggingBlock(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
// Check for clickthrough-blocks:
if (a_BlockFace != BLOCK_FACE_NONE)
{
int pX = a_BlockX;
int pY = a_BlockY;
int pZ = a_BlockZ;
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
Handler = cBlockInfo::GetHandler(World->GetBlock(pX, pY, pZ));
if (Handler->IsClickedThrough())
{
Handler->OnDigging(ChunkInterface, *World, m_Player, pX, pY, pZ);
}
}
} }

View File

@ -63,7 +63,7 @@ public:
const AString & GetIPString(void) const { return m_IPString; } const AString & GetIPString(void) const { return m_IPString; }
cPlayer* GetPlayer() { return m_Player; } // tolua_export cPlayer * GetPlayer(void) { return m_Player; } // tolua_export
const AString & GetUUID(void) const { return m_UUID; } // tolua_export const AString & GetUUID(void) const { return m_UUID; } // tolua_export
void SetUUID(const AString & a_UUID) { m_UUID = a_UUID; } void SetUUID(const AString & a_UUID) { m_UUID = a_UUID; }
@ -76,9 +76,16 @@ public:
/** Generates an UUID based on the player name provided. /** Generates an UUID based on the player name provided.
This is used for the offline (non-auth) mode, when there's no UUID source. This is used for the offline (non-auth) mode, when there's no UUID source.
Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. */ Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same.
Returns a 36-char UUID (with dashes). */
static AString GenerateOfflineUUID(const AString & a_Username); // tolua_export static AString GenerateOfflineUUID(const AString & a_Username); // tolua_export
/** Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID.
We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart.
Accepts both 32-char and 36-char UUIDs (with and without dashes).
If the string given is not a valid UUID, returns false. */
static bool IsUUIDOnline(const AString & a_UUID); // tolua_export
/** Formats the type of message with the proper color and prefix for sending to the client. **/ /** Formats the type of message with the proper color and prefix for sending to the client. **/
static AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString & a_AdditionalData); static AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString & a_AdditionalData);

View File

@ -59,6 +59,7 @@ cCraftingGrid::cCraftingGrid(const cCraftingGrid & a_Original) :
cCraftingGrid::~cCraftingGrid() cCraftingGrid::~cCraftingGrid()
{ {
delete[] m_Items; delete[] m_Items;
m_Items = NULL;
} }

View File

@ -274,8 +274,19 @@ inline eBlockFace RotateBlockFaceCW(eBlockFace a_BlockFace)
} }
} }
inline eBlockFace ReverseBlockFace(eBlockFace a_BlockFace)
{
switch (a_BlockFace)
{
case BLOCK_FACE_YP: return BLOCK_FACE_YM;
case BLOCK_FACE_XP: return BLOCK_FACE_XM;
case BLOCK_FACE_ZP: return BLOCK_FACE_ZM;
case BLOCK_FACE_YM: return BLOCK_FACE_YP;
case BLOCK_FACE_XM: return BLOCK_FACE_XP;
case BLOCK_FACE_ZM: return BLOCK_FACE_ZP;
default: return a_BlockFace;
}
}
/** Returns the textual representation of the BlockFace constant. */ /** Returns the textual representation of the BlockFace constant. */

View File

@ -146,6 +146,7 @@ cPlayer::~cPlayer(void)
m_ClientHandle = NULL; m_ClientHandle = NULL;
delete m_InventoryWindow; delete m_InventoryWindow;
m_InventoryWindow = NULL;
LOGD("Player %p deleted", this); LOGD("Player %p deleted", this);
} }

View File

@ -36,10 +36,6 @@ void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d &
{ {
TotalDamage = 3; TotalDamage = 3;
} }
else if (MobType == cMonster::mtEnderDragon)
{
TotalDamage = 1;
}
} }
// TODO: If entity is Ender Crystal, destroy it // TODO: If entity is Ender Crystal, destroy it
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1); a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);

View File

@ -42,6 +42,7 @@ cFurnaceRecipe::~cFurnaceRecipe()
{ {
ClearRecipes(); ClearRecipes();
delete m_pState; delete m_pState;
m_pState = NULL;
} }
@ -187,7 +188,9 @@ void cFurnaceRecipe::ClearRecipes(void)
{ {
Recipe R = *itr; Recipe R = *itr;
delete R.In; delete R.In;
R.In = NULL;
delete R.Out; delete R.Out;
R.Out = NULL;
} }
m_pState->Recipes.clear(); m_pState->Recipes.clear();
@ -195,6 +198,7 @@ void cFurnaceRecipe::ClearRecipes(void)
{ {
Fuel F = *itr; Fuel F = *itr;
delete F.In; delete F.In;
F.In = NULL;
} }
m_pState->Fuel.clear(); m_pState->Fuel.clear();
} }

View File

@ -135,7 +135,9 @@ cBioGenCache::cBioGenCache(cBiomeGen * a_BioGenToCache, int a_CacheSize) :
cBioGenCache::~cBioGenCache() cBioGenCache::~cBioGenCache()
{ {
delete[] m_CacheData; delete[] m_CacheData;
m_CacheData = NULL;
delete[] m_CacheOrder; delete[] m_CacheOrder;
m_CacheOrder = NULL;
} }
@ -745,7 +747,12 @@ cBioGenTwoLevel::cBioGenTwoLevel(int a_Seed) :
m_VoronoiSmall(a_Seed + 2000), m_VoronoiSmall(a_Seed + 2000),
m_DistortX(a_Seed + 3000), m_DistortX(a_Seed + 3000),
m_DistortZ(a_Seed + 4000), m_DistortZ(a_Seed + 4000),
m_Noise(a_Seed + 5000) m_Noise1(a_Seed + 5001),
m_Noise2(a_Seed + 5002),
m_Noise3(a_Seed + 5003),
m_Noise4(a_Seed + 5004),
m_Noise5(a_Seed + 5005),
m_Noise6(a_Seed + 5006)
{ {
} }
@ -767,12 +774,12 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
int BlockZ = BaseZ + z * 4; int BlockZ = BaseZ + z * 4;
float BlockXF = (float)(16 * BlockX) / 128; float BlockXF = (float)(16 * BlockX) / 128;
float BlockZF = (float)(16 * BlockZ) / 128; float BlockZF = (float)(16 * BlockZ) / 128;
double NoiseX = m_Noise.CubicNoise3D(BlockXF / 16, BlockZF / 16, 1000); double NoiseX = m_Noise1.CubicNoise2D(BlockXF / 16, BlockZF / 16);
NoiseX += 0.5 * m_Noise.CubicNoise3D(BlockXF / 8, BlockZF / 8, 2000); NoiseX += 0.5 * m_Noise2.CubicNoise2D(BlockXF / 8, BlockZF / 8);
NoiseX += 0.08 * m_Noise.CubicNoise3D(BlockXF, BlockZF, 3000); NoiseX += 0.08 * m_Noise3.CubicNoise2D(BlockXF, BlockZF);
double NoiseZ = m_Noise.CubicNoise3D(BlockXF / 16, BlockZF / 16, 4000); double NoiseZ = m_Noise4.CubicNoise2D(BlockXF / 16, BlockZF / 16);
NoiseZ += 0.5 * m_Noise.CubicNoise3D(BlockXF / 8, BlockZF / 8, 5000); NoiseZ += 0.5 * m_Noise5.CubicNoise2D(BlockXF / 8, BlockZF / 8);
NoiseZ += 0.08 * m_Noise.CubicNoise3D(BlockXF, BlockZF, 6000); NoiseZ += 0.08 * m_Noise6.CubicNoise2D(BlockXF, BlockZF);
DistortX[4 * x][4 * z] = BlockX + (int)(64 * NoiseX); DistortX[4 * x][4 * z] = BlockX + (int)(64 * NoiseX);
DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ); DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ);
@ -786,8 +793,8 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
{ {
for (int x = 0; x < cChunkDef::Width; x++) for (int x = 0; x < cChunkDef::Width; x++)
{ {
int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z]) / 7;
int MinDist1, MinDist2; int MinDist1, MinDist2;
int BiomeGroup = m_VoronoiLarge.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 7;
int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 11; int BiomeIdx = m_VoronoiSmall.GetValueAt(DistortX[x][z], DistortZ[x][z], MinDist1, MinDist2) / 11;
cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1)); cChunkDef::SetBiome(a_BiomeMap, x, z, SelectBiome(BiomeGroup, BiomeIdx, (MinDist1 < MinDist2 / 4) ? 0 : 1));
} }

View File

@ -261,7 +261,12 @@ protected:
/// The noise used to distort the inupt Z coord /// The noise used to distort the inupt Z coord
cPerlinNoise m_DistortZ; cPerlinNoise m_DistortZ;
cNoise m_Noise; cNoise m_Noise1;
cNoise m_Noise2;
cNoise m_Noise3;
cNoise m_Noise4;
cNoise m_Noise5;
cNoise m_Noise6;
// cBiomeGen overrides: // cBiomeGen overrides:

View File

@ -672,7 +672,9 @@ cCompoGenCache::cCompoGenCache(cTerrainCompositionGen & a_Underlying, int a_Cach
cCompoGenCache::~cCompoGenCache() cCompoGenCache::~cCompoGenCache()
{ {
delete[] m_CacheData; delete[] m_CacheData;
m_CacheData = NULL;
delete[] m_CacheOrder; delete[] m_CacheOrder;
m_CacheOrder = NULL;
} }

View File

@ -26,6 +26,7 @@
#include "POCPieceGenerator.h" #include "POCPieceGenerator.h"
#include "RainbowRoadsGen.h" #include "RainbowRoadsGen.h"
#include "Ravines.h" #include "Ravines.h"
#include "TestRailsGen.h"
#include "UnderwaterBaseGen.h" #include "UnderwaterBaseGen.h"
#include "VillageGen.h" #include "VillageGen.h"
@ -414,6 +415,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{ {
m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed)); m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed));
} }
else if (NoCaseCompare(*itr, "TestRails") == 0)
{
m_FinishGens.push_back(new cTestRailsGen(Seed, 100, 1, 7, 50));
}
else if (NoCaseCompare(*itr, "Trees") == 0) else if (NoCaseCompare(*itr, "Trees") == 0)
{ {
m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen));

View File

@ -88,8 +88,8 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur
for (cStructurePtrs::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;) for (cStructurePtrs::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;)
{ {
if ( if (
((*itr)->m_OriginX >= MinX) && ((*itr)->m_OriginX < MaxX) && ((*itr)->m_GridX >= MinX) && ((*itr)->m_GridX < MaxX) &&
((*itr)->m_OriginZ >= MinZ) && ((*itr)->m_OriginZ < MaxZ) ((*itr)->m_GridZ >= MinZ) && ((*itr)->m_GridZ < MaxZ)
) )
{ {
// want // want

View File

@ -142,7 +142,9 @@ cHeiGenCache::cHeiGenCache(cTerrainHeightGen & a_HeiGenToCache, int a_CacheSize)
cHeiGenCache::~cHeiGenCache() cHeiGenCache::~cHeiGenCache()
{ {
delete[] m_CacheData; delete[] m_CacheData;
m_CacheData = NULL;
delete[] m_CacheOrder; delete[] m_CacheOrder;
m_CacheOrder = NULL;
} }

View File

@ -211,6 +211,17 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumR
int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width; int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width;
Placement.Move(-ChunkStartX, 0, -ChunkStartZ); Placement.Move(-ChunkStartX, 0, -ChunkStartZ);
const cBlockArea & Image = m_BlockArea[a_NumRotations]; const cBlockArea & Image = m_BlockArea[a_NumRotations];
// If the placement is outside this chunk, bail out:
if (
(Placement.x > cChunkDef::Width) || (Placement.x + Image.GetSizeX() < 0) ||
(Placement.z > cChunkDef::Width) || (Placement.z + Image.GetSizeZ() < 0)
)
{
return;
}
// Write the image:
a_Dest.WriteBlockArea(Image, Placement.x, Placement.y, Placement.z, m_MergeStrategy); a_Dest.WriteBlockArea(Image, Placement.x, Placement.y, Placement.z, m_MergeStrategy);
// If requested, draw the floor (from the bottom of the prefab down to the nearest non-air) // If requested, draw the floor (from the bottom of the prefab down to the nearest non-air)

File diff suppressed because it is too large Load Diff

View File

@ -129,6 +129,176 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] =
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Farm:
// The data has been exported from the gallery Plains, area index 166, ID 554, created by Aloe_vera
{
// Size:
11, 7, 13, // SizeX = 11, SizeY = 7, SizeZ = 13
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
10, 6, 12, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 3: 0\n" /* dirt */
"b: 60: 7\n" /* tilleddirt */
"c: 8: 0\n" /* water */
"d: 43: 0\n" /* doubleslab */
"e: 44: 0\n" /* step */
"f: 59: 7\n" /* crops */
"g: 83: 0\n" /* reedblock */
"h:113: 0\n" /* netherbrickfence */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "mmmmmmmmmmm"
/* 1 */ "maaaaaaaaam"
/* 2 */ "maaaaaaaaam"
/* 3 */ "maaaaaaaaam"
/* 4 */ "maaaaaaaaam"
/* 5 */ "maaaaaaaaam"
/* 6 */ "maaaaaaaaam"
/* 7 */ "maaaaaaaaam"
/* 8 */ "maaaaaaaaam"
/* 9 */ "maaaaaaaaam"
/* 10 */ "maaaaaaaaam"
/* 11 */ "maaaaaaaaam"
/* 12 */ "mmmmmmmmmmm"
// Level 1
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "mmmmmmmmmmm"
/* 1 */ "maaaaaaaaam"
/* 2 */ "mabbbbbbbam"
/* 3 */ "mabbbbbbbam"
/* 4 */ "mabbbbbbbam"
/* 5 */ "mabbbbbbbam"
/* 6 */ "mabcccccaam"
/* 7 */ "mabbbbbbbam"
/* 8 */ "mabbbbbbbam"
/* 9 */ "mabbbbbbbam"
/* 10 */ "mabbbbbbbam"
/* 11 */ "maaaaaaaaam"
/* 12 */ "mmmmmmmmmmm"
// Level 2
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ ".deeeeeeed."
/* 2 */ ".efffffffe."
/* 3 */ ".efffffffe."
/* 4 */ ".efffffffe."
/* 5 */ ".efgggggfe."
/* 6 */ ".eg.....ge."
/* 7 */ ".efgggggfe."
/* 8 */ ".efffffffe."
/* 9 */ ".efffffffe."
/* 10 */ ".efffffffe."
/* 11 */ ".deeeeeeed."
/* 12 */ "..........."
// Level 3
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ ".h.......h."
/* 2 */ "..........."
/* 3 */ "..........."
/* 4 */ "..........."
/* 5 */ "...ggggg..."
/* 6 */ "..g.....g.."
/* 7 */ "...ggggg..."
/* 8 */ "..........."
/* 9 */ "..........."
/* 10 */ "..........."
/* 11 */ ".h.......h."
/* 12 */ "..........."
// Level 4
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ ".h.......h."
/* 2 */ "..........."
/* 3 */ "..........."
/* 4 */ "..........."
/* 5 */ "...ggggg..."
/* 6 */ "..g.....g.."
/* 7 */ "...ggggg..."
/* 8 */ "..........."
/* 9 */ "..........."
/* 10 */ "..........."
/* 11 */ ".h.......h."
/* 12 */ "..........."
// Level 5
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ "..........."
/* 1 */ ".h.......h."
/* 2 */ "..........."
/* 3 */ "..........."
/* 4 */ "..........."
/* 5 */ "..........."
/* 6 */ "..........."
/* 7 */ "..........."
/* 8 */ "..........."
/* 9 */ "..........."
/* 10 */ "..........."
/* 11 */ ".h.......h."
/* 12 */ "..........."
// Level 6
/* z\x* 1 */
/* * 01234567890 */
/* 0 */ ".h.......h."
/* 1 */ "hhh.....hhh"
/* 2 */ ".h.......h."
/* 3 */ "..........."
/* 4 */ "..........."
/* 5 */ "..........."
/* 6 */ "..........."
/* 7 */ "..........."
/* 8 */ "..........."
/* 9 */ "..........."
/* 10 */ ".h.......h."
/* 11 */ "hhh.....hhh"
/* 12 */ ".h.......h.",
// Connectors:
"-1: 10, 2, 6: 5\n" /* Type -1, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
true,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // Farm
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Forge: // Forge:
// The data has been exported from the gallery Plains, area index 79, ID 145, created by Aloe_vera // The data has been exported from the gallery Plains, area index 79, ID 145, created by Aloe_vera
@ -2025,12 +2195,12 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] =
// Level 1 // Level 1
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "bbbbbbb" /* 0 */ "bmmmmmm"
/* 1 */ "bbbbbbb" /* 1 */ "bmmmmmm"
/* 2 */ "bbbbbbb" /* 2 */ "bmmmmmm"
/* 3 */ "bbbabbb" /* 3 */ "bmmmmmm"
/* 4 */ "bbbbbbb" /* 4 */ "bmmmmmm"
/* 5 */ "bbbbbbb" /* 5 */ "bmmmmmm"
/* 6 */ "bbbbbbb" /* 6 */ "bbbbbbb"
// Level 2 // Level 2
@ -3005,159 +3175,157 @@ const cPrefab::sDef g_JapaneseVillageStartingPrefabs[] =
"a: 1: 0\n" /* stone */ "a: 1: 0\n" /* stone */
"b: 4: 0\n" /* cobblestone */ "b: 4: 0\n" /* cobblestone */
"c: 8: 0\n" /* water */ "c: 8: 0\n" /* water */
"d: 3: 0\n" /* dirt */ "d: 13: 0\n" /* gravel */
"e: 2: 0\n" /* grass */ "e: 67: 1\n" /* stairs */
"f: 13: 0\n" /* gravel */ "f: 67: 2\n" /* stairs */
"g: 67: 1\n" /* stairs */ "g: 67: 0\n" /* stairs */
"h: 67: 2\n" /* stairs */ "h: 67: 3\n" /* stairs */
"i: 67: 0\n" /* stairs */ "i: 85: 0\n" /* fence */
"j: 67: 3\n" /* stairs */ "j: 44: 8\n" /* step */
"k: 85: 0\n" /* fence */ "k: 44: 0\n" /* step */
"l: 44: 8\n" /* step */ "l: 43: 0\n" /* doubleslab */
"m: 19: 0\n" /* sponge */ "m: 19: 0\n" /* sponge */,
"n: 44: 0\n" /* step */
"o: 43: 0\n" /* doubleslab */,
// Block data: // Block data:
// Level 0 // Level 0
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "aaaaaaa" /* 0 */ "mmmmmmm"
/* 1 */ "aaaaaaa" /* 1 */ "maaaaam"
/* 2 */ "aaaaaaa" /* 2 */ "maaaaam"
/* 3 */ "aaaaaaa" /* 3 */ "maaaaam"
/* 4 */ "aaaaaaa" /* 4 */ "maaaaam"
/* 5 */ "aaaaaaa" /* 5 */ "maaaaam"
/* 6 */ "aaaaaaa" /* 6 */ "mmmmmmm"
// Level 1 // Level 1
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "aaaaaaa" /* 0 */ "mmmmmmm"
/* 1 */ "abbbbba" /* 1 */ "mbbbbbm"
/* 2 */ "abcc.ba" /* 2 */ "mbcc.bm"
/* 3 */ "abcccba" /* 3 */ "mbcccbm"
/* 4 */ "abcccba" /* 4 */ "mbcccbm"
/* 5 */ "abbbbba" /* 5 */ "mbbbbbm"
/* 6 */ "aaaaaaa" /* 6 */ "mmmmmmm"
// Level 2 // Level 2
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "aaaaaaa" /* 0 */ "mmmmmmm"
/* 1 */ "abbbbba" /* 1 */ "mbbbbbm"
/* 2 */ "abcccba" /* 2 */ "mbcccbm"
/* 3 */ "abcccba" /* 3 */ "mbcccbm"
/* 4 */ "abcccba" /* 4 */ "mbcccbm"
/* 5 */ "abbbbba" /* 5 */ "mbbbbbm"
/* 6 */ "aaaaaaa" /* 6 */ "mmmmmmm"
// Level 3 // Level 3
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "aaaaaaa" /* 0 */ "mmmmmmm"
/* 1 */ "abbbbba" /* 1 */ "mbbbbbm"
/* 2 */ "abcccba" /* 2 */ "mbcccbm"
/* 3 */ "abcccba" /* 3 */ "mbcccbm"
/* 4 */ "abcccba" /* 4 */ "mbcccbm"
/* 5 */ "abbbbba" /* 5 */ "mbbbbbm"
/* 6 */ "aaaaaaa" /* 6 */ "mmmmmmm"
// Level 4 // Level 4
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "aaaaaaa" /* 0 */ "mmmmmmm"
/* 1 */ "abbbbba" /* 1 */ "mbbbbbm"
/* 2 */ "abcccba" /* 2 */ "mbcccbm"
/* 3 */ "abcccba" /* 3 */ "mbcccbm"
/* 4 */ "abcccba" /* 4 */ "mbcccbm"
/* 5 */ "abbbbba" /* 5 */ "mbbbbbm"
/* 6 */ "aaaaaaa" /* 6 */ "mmmmmmm"
// Level 5 // Level 5
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "ddddddd" /* 0 */ "mmmmmmm"
/* 1 */ "dbbbbbd" /* 1 */ "mbbbbbm"
/* 2 */ "dbcccbd" /* 2 */ "mbcccbm"
/* 3 */ "dbcccbd" /* 3 */ "mbcccbm"
/* 4 */ "dbcccbd" /* 4 */ "mbcccbm"
/* 5 */ "dbbbbbd" /* 5 */ "mbbbbbm"
/* 6 */ "ddddddd" /* 6 */ "mmmmmmm"
// Level 6 // Level 6
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "ddddddd" /* 0 */ "mmmmmmm"
/* 1 */ "dbbbbbd" /* 1 */ "mbbbbbm"
/* 2 */ "dbcccbd" /* 2 */ "mbcccbm"
/* 3 */ "dbcccbd" /* 3 */ "mbcccbm"
/* 4 */ "dbcccbd" /* 4 */ "mbcccbm"
/* 5 */ "dbbbbbd" /* 5 */ "mbbbbbm"
/* 6 */ "ddddddd" /* 6 */ "mmmmmmm"
// Level 7 // Level 7
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "ddddddd" /* 0 */ "mmbbbmm"
/* 1 */ "dbbbbbd" /* 1 */ "mbbbbbm"
/* 2 */ "dbcccbd" /* 2 */ "bbcccbb"
/* 3 */ "dbcccbd" /* 3 */ "bbcccbb"
/* 4 */ "dbcccbd" /* 4 */ "bbcccbb"
/* 5 */ "dbbbbbd" /* 5 */ "mbbbbbm"
/* 6 */ "ddddddd" /* 6 */ "mmbbbmm"
// Level 8 // Level 8
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "eefffee" /* 0 */ "mmdddmm"
/* 1 */ "ebbbbbe" /* 1 */ "mbbbbbm"
/* 2 */ "fbcccbf" /* 2 */ "dbcccbd"
/* 3 */ "fbcccbf" /* 3 */ "dbcccbd"
/* 4 */ "fbcccbf" /* 4 */ "dbcccbd"
/* 5 */ "ebbbbbe" /* 5 */ "mbbbbbm"
/* 6 */ "eefffee" /* 6 */ "mmdddmm"
// Level 9 // Level 9
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "......." /* 0 */ "mm...mm"
/* 1 */ ".bghib." /* 1 */ "mbefgbm"
/* 2 */ ".j...j." /* 2 */ ".h...h."
/* 3 */ ".i...g." /* 3 */ ".g...e."
/* 4 */ ".h...h." /* 4 */ ".f...f."
/* 5 */ ".bgjib." /* 5 */ "mbehgbm"
/* 6 */ "......." /* 6 */ "mm...mm"
// Level 10 // Level 10
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "......." /* 0 */ "mm...mm"
/* 1 */ ".k...k." /* 1 */ "mi...im"
/* 2 */ "......." /* 2 */ "......."
/* 3 */ "......." /* 3 */ "......."
/* 4 */ "......." /* 4 */ "......."
/* 5 */ ".k...k." /* 5 */ "mi...im"
/* 6 */ "......." /* 6 */ "mm...mm"
// Level 11 // Level 11
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "......." /* 0 */ "mm...mm"
/* 1 */ ".k...k." /* 1 */ "mi...im"
/* 2 */ "......." /* 2 */ "......."
/* 3 */ "......." /* 3 */ "......."
/* 4 */ "......." /* 4 */ "......."
/* 5 */ ".k...k." /* 5 */ "mi...im"
/* 6 */ "......." /* 6 */ "mm...mm"
// Level 12 // Level 12
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ ".lnnnl." /* 0 */ "mjkkkjm"
/* 1 */ "loooool" /* 1 */ "jlllllj"
/* 2 */ "nooooon" /* 2 */ "klllllk"
/* 3 */ "nooooon" /* 3 */ "klllllk"
/* 4 */ "nooooon" /* 4 */ "klllllk"
/* 5 */ "loooool" /* 5 */ "jlllllj"
/* 6 */ ".lnnnl." /* 6 */ "mjkkkjm"
// Level 13 // Level 13
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "n.....n" /* 0 */ "k.....k"
/* 1 */ "......." /* 1 */ "......."
/* 2 */ "..nnn.." /* 2 */ "..kkk.."
/* 3 */ "..non.." /* 3 */ "..klk.."
/* 4 */ "..nnn.." /* 4 */ "..kkk.."
/* 5 */ "......." /* 5 */ "......."
/* 6 */ "n.....n", /* 6 */ "k.....k",
// Connectors: // Connectors:
"2: 0, 9, 3: 4\n" /* Type 2, direction X- */ "2: 0, 9, 3: 4\n" /* Type 2, direction X- */

View File

@ -362,29 +362,29 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 0 // Level 0
/* z\x* 11111 */ /* z\x* 11111 */
/* * 012345678901234 */ /* * 012345678901234 */
/* 0 */ "aaaaaaaaaaaaaaa" /* 0 */ "aaaaaaabaaaaaaa"
/* 1 */ "aaaaaaaaaaaaaaa" /* 1 */ "aaaaaaaaaaaaaaa"
/* 2 */ "aaaaaaaaaaaaaaa" /* 2 */ "aaaaaaaaaaaaaaa"
/* 3 */ "aaaaaaaaaaaaaaa" /* 3 */ "aaaaaaaaaaaaaaa"
/* 4 */ "aaaaaaaaaaaaaaa" /* 4 */ "aaaaaaaaaaaaaaa"
/* 5 */ "aaaaaaaaaaaaaaa"
/* 6 */ "aaaaaaaaaaaaaaa"
/* 7 */ "aaaaaaaaaaaaaaa"
/* 8 */ "aaaaaaaaaaaaaaa"
// Level 1
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "aaaaaaabaaaaaaa"
/* 1 */ "aaaaaaabaaaaaaa"
/* 2 */ "aaaaaaabaaaaaaa"
/* 3 */ "aaaaaaabaaaaaaa"
/* 4 */ "aaaaaaabaaaaaaa"
/* 5 */ "aaaaaaabaaaaaaa" /* 5 */ "aaaaaaabaaaaaaa"
/* 6 */ "aaaaaaabaaaaaaa" /* 6 */ "aaaaaaabaaaaaaa"
/* 7 */ "aaaaaaabaaaaaaa" /* 7 */ "aaaaaaabaaaaaaa"
/* 8 */ "aaaaaaabaaaaaaa" /* 8 */ "aaaaaaabaaaaaaa"
// Level 1
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "aaaaaaamaaaaaaa"
/* 1 */ "aaaaaaamaaaaaaa"
/* 2 */ "aaaaaaamaaaaaaa"
/* 3 */ "aaaaaaamaaaaaaa"
/* 4 */ "aaaaaaamaaaaaaa"
/* 5 */ "aaaaaaamaaaaaaa"
/* 6 */ "aaaaaaamaaaaaaa"
/* 7 */ "aaaaaaamaaaaaaa"
/* 8 */ "aaaaaaamaaaaaaa"
// Level 2 // Level 2
/* z\x* 11111 */ /* z\x* 11111 */
/* * 012345678901234 */ /* * 012345678901234 */
@ -509,12 +509,12 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"d: 67: 1\n" /* stairs */ "d: 67: 1\n" /* stairs */
"e: 17: 0\n" /* tree */ "e: 17: 0\n" /* tree */
"f: 5: 0\n" /* wood */ "f: 5: 0\n" /* wood */
"g: 64: 6\n" /* wooddoorblock */ "g: 64: 2\n" /* wooddoorblock */
"h: 10: 0\n" /* lava */ "h: 10: 0\n" /* lava */
"i: 54: 2\n" /* chest */ "i: 54: 2\n" /* chest */
"j: 61: 2\n" /* furnace */ "j: 61: 2\n" /* furnace */
"k:102: 0\n" /* glasspane */ "k:102: 0\n" /* glasspane */
"l: 64:12\n" /* wooddoorblock */ "l: 64: 8\n" /* wooddoorblock */
"m: 19: 0\n" /* sponge */ "m: 19: 0\n" /* sponge */
"n:139: 0\n" /* cobblestonewall */ "n:139: 0\n" /* cobblestonewall */
"o:101: 0\n" /* ironbars */ "o:101: 0\n" /* ironbars */
@ -2544,7 +2544,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
true, true,
// DefaultWeight: // DefaultWeight:
100, 20,
// DepthWeight: // DepthWeight:
"", "",
@ -2746,8 +2746,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"d: 67: 1\n" /* stairs */ "d: 67: 1\n" /* stairs */
"e: 17: 0\n" /* tree */ "e: 17: 0\n" /* tree */
"f: 5: 0\n" /* wood */ "f: 5: 0\n" /* wood */
"g: 64: 7\n" /* wooddoorblock */ "g: 64: 3\n" /* wooddoorblock */
"h: 64:12\n" /* wooddoorblock */ "h: 64: 8\n" /* wooddoorblock */
"i:102: 0\n" /* glasspane */ "i:102: 0\n" /* glasspane */
"j: 53: 2\n" /* woodstairs */ "j: 53: 2\n" /* woodstairs */
"k: 53: 7\n" /* woodstairs */ "k: 53: 7\n" /* woodstairs */
@ -3000,9 +3000,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"d: 67: 1\n" /* stairs */ "d: 67: 1\n" /* stairs */
"e: 17: 0\n" /* tree */ "e: 17: 0\n" /* tree */
"f: 5: 0\n" /* wood */ "f: 5: 0\n" /* wood */
"g: 64: 7\n" /* wooddoorblock */ "g: 64: 3\n" /* wooddoorblock */
"h:102: 0\n" /* glasspane */ "h:102: 0\n" /* glasspane */
"i: 64:12\n" /* wooddoorblock */ "i: 64: 8\n" /* wooddoorblock */
"j: 53: 2\n" /* woodstairs */ "j: 53: 2\n" /* woodstairs */
"k: 53: 7\n" /* woodstairs */ "k: 53: 7\n" /* woodstairs */
"l: 50: 3\n" /* torch */ "l: 50: 3\n" /* torch */
@ -3141,31 +3141,32 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
"k: 85: 0\n" /* fence */ "k: 85: 0\n" /* fence */
"l: 53: 0\n" /* woodstairs */ "l: 53: 0\n" /* woodstairs */
"m: 19: 0\n" /* sponge */ "m: 19: 0\n" /* sponge */
"n: 64: 6\n" /* wooddoorblock */ "n: 64: 2\n" /* wooddoorblock */
"o: 64: 4\n" /* wooddoorblock */ "o: 64: 4\n" /* wooddoorblock */
"p:102: 0\n" /* glasspane */ "p:102: 0\n" /* glasspane */
"q: 72: 0\n" /* woodplate */ "q: 72: 0\n" /* woodplate */
"r: 64:12\n" /* wooddoorblock */ "r: 64: 8\n" /* wooddoorblock */
"s: 53: 5\n" /* woodstairs */ "s: 64:12\n" /* wooddoorblock */
"t: 53: 4\n" /* woodstairs */ "t: 53: 5\n" /* woodstairs */
"u: 50: 1\n" /* torch */ "u: 53: 4\n" /* woodstairs */
"v: 50: 2\n" /* torch */, "v: 50: 1\n" /* torch */
"w: 50: 2\n" /* torch */,
// Block data: // Block data:
// Level 0 // Level 0
/* z\x* */ /* z\x* */
/* * 0123456789 */ /* * 0123456789 */
/* 0 */ ".........." /* 0 */ "mmmmmmmmmm"
/* 1 */ ".aaaaa...." /* 1 */ "maaaaammmm"
/* 2 */ ".aaaaa...." /* 2 */ "maaaaammmm"
/* 3 */ ".aaaaabbbb" /* 3 */ "maaaaabbbb"
/* 4 */ "aaaaaabbbb" /* 4 */ "aaaaaabbbb"
/* 5 */ "aaaaaabbbb" /* 5 */ "aaaaaabbbb"
/* 6 */ "aaaaaabbbb" /* 6 */ "aaaaaabbbb"
/* 7 */ ".aaaaabbbb" /* 7 */ "maaaaabbbb"
/* 8 */ ".aaaaabbbb" /* 8 */ "maaaaabbbb"
/* 9 */ ".aaaaa...." /* 9 */ "maaaaammmm"
/* 10 */ ".........." /* 10 */ "mmmmmmmmmm"
// Level 1 // Level 1
/* z\x* */ /* z\x* */
@ -3205,7 +3206,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 2 */ ".p.q.pmmmm" /* 2 */ ".p.q.pmmmm"
/* 3 */ ".p...p...." /* 3 */ ".p...p...."
/* 4 */ ".c...c...." /* 4 */ ".c...c...."
/* 5 */ ".r...r...." /* 5 */ ".r...s...."
/* 6 */ ".c...c...." /* 6 */ ".c...c...."
/* 7 */ ".p...p...." /* 7 */ ".p...p...."
/* 8 */ ".p...p...." /* 8 */ ".p...p...."
@ -3215,47 +3216,47 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 4 // Level 4
/* z\x* */ /* z\x* */
/* * 0123456789 */ /* * 0123456789 */
/* 0 */ "ls...tjmmm" /* 0 */ "lt...ujmmm"
/* 1 */ "licccijmmm" /* 1 */ "licccijmmm"
/* 2 */ "lc...cjmmm" /* 2 */ "lc...cjmmm"
/* 3 */ "lc...cj..." /* 3 */ "lc...cj..."
/* 4 */ "lcu.vcj..." /* 4 */ "lcv.wcj..."
/* 5 */ "lc...cj..." /* 5 */ "lc...cj..."
/* 6 */ "lcu.vcj..." /* 6 */ "lcv.wcj..."
/* 7 */ "lc...cj..." /* 7 */ "lc...cj..."
/* 8 */ "lc...cj..." /* 8 */ "lc...cj..."
/* 9 */ "licccijmmm" /* 9 */ "licccijmmm"
/* 10 */ "ls...tjmmm" /* 10 */ "lt...ujmmm"
// Level 5 // Level 5
/* z\x* */ /* z\x* */
/* * 0123456789 */ /* * 0123456789 */
/* 0 */ "mls.tjmmmm" /* 0 */ ".lt.uj.mmm"
/* 1 */ "mlcccjmmmm" /* 1 */ ".lcccj.mmm"
/* 2 */ "mlc.cjmmmm" /* 2 */ ".lc.cj.mmm"
/* 3 */ "mlc.cjm..." /* 3 */ ".lc.cj...."
/* 4 */ "mlc.cjm..." /* 4 */ ".lc.cj...."
/* 5 */ "mlc.cjm..." /* 5 */ ".lc.cj...."
/* 6 */ "mlc.cjm..." /* 6 */ ".lc.cj...."
/* 7 */ "mlc.cjm..." /* 7 */ ".lc.cj...."
/* 8 */ "mlc.cjm..." /* 8 */ ".lc.cj...."
/* 9 */ "mlcccjmmmm" /* 9 */ ".lcccj.mmm"
/* 10 */ "mls.tjmmmm" /* 10 */ ".lt.uj.mmm"
// Level 6 // Level 6
/* z\x* */ /* z\x* */
/* * 0123456789 */ /* * 0123456789 */
/* 0 */ "mmlcjmmmmm" /* 0 */ "..lcj..mmm"
/* 1 */ "mmlcjmmmmm" /* 1 */ "..lcj..mmm"
/* 2 */ "mmlcjmmmmm" /* 2 */ "..lcj..mmm"
/* 3 */ "mmlcjmm..." /* 3 */ "..lcj....."
/* 4 */ "mmlcjmm..." /* 4 */ "..lcj....."
/* 5 */ "mmlcjmm..." /* 5 */ "..lcj....."
/* 6 */ "mmlcjmm..." /* 6 */ "..lcj....."
/* 7 */ "mmlcjmm..." /* 7 */ "..lcj....."
/* 8 */ "mmlcjmm..." /* 8 */ "..lcj....."
/* 9 */ "mmlcjmmmmm" /* 9 */ "..lcj..mmm"
/* 10 */ "mmlcjmmmmm", /* 10 */ "..lcj..mmm",
// Connectors: // Connectors:
"-1: 0, 1, 5: 4\n" /* Type -1, direction X- */, "-1: 0, 1, 5: 4\n" /* Type -1, direction X- */,
@ -3626,7 +3627,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 0 // Level 0
/* z\x* 1 */ /* z\x* 1 */
/* * 01234567890 */ /* * 01234567890 */
/* 0 */ "aaabbbbaaaa" /* 0 */ "aaaabbbaaaa"
/* 1 */ "abbbbbbbbba" /* 1 */ "abbbbbbbbba"
/* 2 */ "abbbbbbbbba" /* 2 */ "abbbbbbbbba"
/* 3 */ "abbbbbbbbba" /* 3 */ "abbbbbbbbba"
@ -4509,10 +4510,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".aaaaaaaaa." /* 4 */ ".aaaaaaaaa."
/* 5 */ ".aaaaaaaaa." /* 5 */ ".aaaaaaaaa."
/* 6 */ ".....aaaaa." /* 6 */ ".....aaaaa."
/* 7 */ ".....aaaaa." /* 7 */ "mmmm.aaaaa."
/* 8 */ ".....aaaaa." /* 8 */ "mmmm.aaaaa."
/* 9 */ ".....aaaaa." /* 9 */ "mmmm.aaaaa."
/* 10 */ "..........." /* 10 */ "mmmm......."
// Level 2 // Level 2
/* z\x* 1 */ /* z\x* 1 */
@ -4524,10 +4525,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".f.......f." /* 4 */ ".f.......f."
/* 5 */ ".efffe...f." /* 5 */ ".efffe...f."
/* 6 */ ".....f...f." /* 6 */ ".....f...f."
/* 7 */ ".....f...f." /* 7 */ "mmmm.f...f."
/* 8 */ ".....f...f." /* 8 */ "mmmm.f...f."
/* 9 */ ".....efffe." /* 9 */ "mmmm.efffe."
/* 10 */ "..........." /* 10 */ "mmmm......."
// Level 3 // Level 3
/* z\x* 1 */ /* z\x* 1 */
@ -4539,10 +4540,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".h.......h." /* 4 */ ".h.......h."
/* 5 */ ".ehhhe...f." /* 5 */ ".ehhhe...f."
/* 6 */ ".....h...h." /* 6 */ ".....h...h."
/* 7 */ ".....h...h." /* 7 */ "mmmm.h...h."
/* 8 */ ".....h...h." /* 8 */ "mmmm.h...h."
/* 9 */ ".....ehhhe." /* 9 */ "mmmm.ehhhe."
/* 10 */ "..........." /* 10 */ "mmmm......."
// Level 4 // Level 4
/* z\x* 1 */ /* z\x* 1 */
@ -4554,10 +4555,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ ".f...o...fl" /* 4 */ ".f...o...fl"
/* 5 */ "pfffffq.rfl" /* 5 */ "pfffffq.rfl"
/* 6 */ "sssssf...fl" /* 6 */ "sssssf...fl"
/* 7 */ "....tf...fl" /* 7 */ "mmmmtf...fl"
/* 8 */ "....tf...fl" /* 8 */ "mmmmtf...fl"
/* 9 */ "....tfffffl" /* 9 */ "mmmmtfffffl"
/* 10 */ "....tu...vl" /* 10 */ "mmmmtu...vl"
// Level 5 // Level 5
/* z\x* 1 */ /* z\x* 1 */
@ -4569,10 +4570,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ "pffffff.fl." /* 4 */ "pffffff.fl."
/* 5 */ "ssssssf.fl." /* 5 */ "ssssssf.fl."
/* 6 */ ".....tf.fl." /* 6 */ ".....tf.fl."
/* 7 */ ".....tf.fl." /* 7 */ "mmmm.tf.fl."
/* 8 */ ".....tf.fl." /* 8 */ "mmmm.tf.fl."
/* 9 */ ".....tfffl." /* 9 */ "mmmm.tfffl."
/* 10 */ ".....tu.vl." /* 10 */ "mmmm.tu.vl."
// Level 6 // Level 6
/* z\x* 1 */ /* z\x* 1 */
@ -4584,10 +4585,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 4 */ "sssssstfl.." /* 4 */ "sssssstfl.."
/* 5 */ "......tfl.." /* 5 */ "......tfl.."
/* 6 */ "......tfl.." /* 6 */ "......tfl.."
/* 7 */ "......tfl.." /* 7 */ "mmmm..tfl.."
/* 8 */ "......tfl.." /* 8 */ "mmmm..tfl.."
/* 9 */ "......tfl.." /* 9 */ "mmmm..tfl.."
/* 10 */ "......tfl..", /* 10 */ "mmmm..tfl..",
// Connectors: // Connectors:
"-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */, "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */,
@ -4837,9 +4838,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
// Level 1 // Level 1
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ ".aaaaa..." /* 4 */ ".aaaaa..."
/* 5 */ ".aaaaab.." /* 5 */ ".aaaaab.."
@ -4847,15 +4848,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".aaaaad.." /* 7 */ ".aaaaad.."
/* 8 */ ".aaaaa..." /* 8 */ ".aaaaa..."
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 2 // Level 2
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ ".efffe..." /* 4 */ ".efffe..."
/* 5 */ ".f...f..." /* 5 */ ".f...f..."
@ -4863,15 +4864,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..." /* 7 */ ".f...f..."
/* 8 */ ".efffe..." /* 8 */ ".efffe..."
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 3 // Level 3
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ ".ejjje..." /* 4 */ ".ejjje..."
/* 5 */ ".j...f..." /* 5 */ ".j...f..."
@ -4879,15 +4880,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".j...f..." /* 7 */ ".j...f..."
/* 8 */ ".ejjje..." /* 8 */ ".ejjje..."
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 4 // Level 4
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ ".efffe..." /* 4 */ ".efffe..."
/* 5 */ ".f..nf..." /* 5 */ ".f..nf..."
@ -4895,15 +4896,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f..nf..k" /* 7 */ ".f..nf..k"
/* 8 */ ".efffe..o" /* 8 */ ".efffe..o"
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 5 // Level 5
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ ".epppe..." /* 4 */ ".epppe..."
/* 5 */ ".q...q..." /* 5 */ ".q...q..."
@ -4911,15 +4912,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".q...q..k" /* 7 */ ".q...q..k"
/* 8 */ ".epppe..o" /* 8 */ ".epppe..o"
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 6 // Level 6
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ ".efffe..." /* 4 */ ".efffe..."
/* 5 */ ".f...f..." /* 5 */ ".f...f..."
@ -4927,15 +4928,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..o" /* 7 */ ".f...f..o"
/* 8 */ ".efffe..o" /* 8 */ ".efffe..o"
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 7 // Level 7
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ ".ejjje..." /* 4 */ ".ejjje..."
/* 5 */ ".j...j..." /* 5 */ ".j...j..."
@ -4943,15 +4944,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".j...j..o" /* 7 */ ".j...j..o"
/* 8 */ ".ejjje..." /* 8 */ ".ejjje..."
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 8 // Level 8
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........o" /* 0 */ "mmmmmmm.o"
/* 1 */ "........o" /* 1 */ "mmmmmmm.o"
/* 2 */ "........o" /* 2 */ "mmmmmmm.o"
/* 3 */ "........." /* 3 */ "........."
/* 4 */ ".efffe..." /* 4 */ ".efffe..."
/* 5 */ ".f...f..k" /* 5 */ ".f...f..k"
@ -4959,15 +4960,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..o" /* 7 */ ".f...f..o"
/* 8 */ ".efffe..." /* 8 */ ".efffe..."
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 9 // Level 9
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........k" /* 0 */ "mmmmmmm.k"
/* 1 */ "........k" /* 1 */ "mmmmmmm.k"
/* 2 */ "........o" /* 2 */ "mmmmmmm.o"
/* 3 */ "........o" /* 3 */ "........o"
/* 4 */ ".epppe..o" /* 4 */ ".epppe..o"
/* 5 */ ".q...q..k" /* 5 */ ".q...q..k"
@ -4975,15 +4976,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".q...q..k" /* 7 */ ".q...q..k"
/* 8 */ ".epppe..k" /* 8 */ ".epppe..k"
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 10 // Level 10
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........k" /* 2 */ "mmmmmmm.k"
/* 3 */ "rrrrrrr.k" /* 3 */ "rrrrrrr.k"
/* 4 */ "sfffffs.o" /* 4 */ "sfffffs.o"
/* 5 */ ".f...f..o" /* 5 */ ".f...f..o"
@ -4991,15 +4992,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ ".f...f..o" /* 7 */ ".f...f..o"
/* 8 */ "tffffft.o" /* 8 */ "tffffft.o"
/* 9 */ "uuuuuuu.k" /* 9 */ "uuuuuuu.k"
/* 10 */ "........k" /* 10 */ "mmmmmmm.k"
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 11 // Level 11
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ "rrrrrrr.k" /* 4 */ "rrrrrrr.k"
/* 5 */ "sfffffs.k" /* 5 */ "sfffffs.k"
@ -5007,15 +5008,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "tffffft.k" /* 7 */ "tffffft.k"
/* 8 */ "uuuuuuu.o" /* 8 */ "uuuuuuu.o"
/* 9 */ "........o" /* 9 */ "........o"
/* 10 */ "........o" /* 10 */ "mmmmmmm.o"
/* 11 */ "........k" /* 11 */ "mmmmmmm.k"
/* 12 */ "........k" /* 12 */ "mmmmmmm.k"
// Level 12 // Level 12
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ "........." /* 4 */ "........."
/* 5 */ "rrrrrrr.o" /* 5 */ "rrrrrrr.o"
@ -5023,15 +5024,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "uuuuuuu.k" /* 7 */ "uuuuuuu.k"
/* 8 */ "........." /* 8 */ "........."
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........o" /* 10 */ "mmmmmmm.o"
/* 11 */ "........o" /* 11 */ "mmmmmmm.o"
/* 12 */ "........o" /* 12 */ "mmmmmmm.o"
// Level 13 // Level 13
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ "........." /* 4 */ "........."
/* 5 */ "........o" /* 5 */ "........o"
@ -5039,15 +5040,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........." /* 7 */ "........."
/* 8 */ "........." /* 8 */ "........."
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 14 // Level 14
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ "........o" /* 4 */ "........o"
/* 5 */ "........o" /* 5 */ "........o"
@ -5055,15 +5056,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........." /* 7 */ "........."
/* 8 */ "........." /* 8 */ "........."
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 15 // Level 15
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ "........o" /* 4 */ "........o"
/* 5 */ "........k" /* 5 */ "........k"
@ -5071,15 +5072,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........." /* 7 */ "........."
/* 8 */ "........." /* 8 */ "........."
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ "........." /* 12 */ "mmmmmmm.."
// Level 16 // Level 16
/* z\x* 012345678 */ /* z\x* 012345678 */
/* 0 */ "........." /* 0 */ "mmmmmmm.."
/* 1 */ "........." /* 1 */ "mmmmmmm.."
/* 2 */ "........." /* 2 */ "mmmmmmm.."
/* 3 */ "........." /* 3 */ "........."
/* 4 */ "........o" /* 4 */ "........o"
/* 5 */ "........k" /* 5 */ "........k"
@ -5087,9 +5088,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] =
/* 7 */ "........." /* 7 */ "........."
/* 8 */ "........." /* 8 */ "........."
/* 9 */ "........." /* 9 */ "........."
/* 10 */ "........." /* 10 */ "mmmmmmm.."
/* 11 */ "........." /* 11 */ "mmmmmmm.."
/* 12 */ ".........", /* 12 */ "mmmmmmm..",
// Connectors: // Connectors:
"-1: 8, 1, 6: 5\n" /* Type -1, direction X+ */, "-1: 8, 1, 6: 5\n" /* Type -1, direction X+ */,
@ -5472,13 +5473,15 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
"l: 66: 7\n" /* tracks */ "l: 66: 7\n" /* tracks */
"m: 19: 0\n" /* sponge */ "m: 19: 0\n" /* sponge */
"n: 50: 2\n" /* torch */ "n: 50: 2\n" /* torch */
"o: 2: 0\n" /* grass */ "o: 4: 0\n" /* cobblestone */
"p: 53: 2\n" /* woodstairs */ "p: 2: 0\n" /* grass */
"q: 77: 1\n" /* stonebutton */ "q: 13: 0\n" /* gravel */
"r: 27: 0\n" /* poweredrail */ "r: 53: 2\n" /* woodstairs */
"s: 53: 7\n" /* woodstairs */ "s: 77: 1\n" /* stonebutton */
"t: 53: 6\n" /* woodstairs */ "t: 27: 0\n" /* poweredrail */
"u: 53: 3\n" /* woodstairs */, "u: 53: 7\n" /* woodstairs */
"v: 53: 6\n" /* woodstairs */
"w: 53: 3\n" /* woodstairs */,
// Block data: // Block data:
// Level 0 // Level 0
@ -5783,28 +5786,28 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
// Level 30 // Level 30
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "mmmmmmm" /* 0 */ "mmooomm"
/* 1 */ "mmmammm" /* 1 */ "mmmammm"
/* 2 */ "mm...mm" /* 2 */ "om...mo"
/* 3 */ "ma..aam" /* 3 */ "oa..aao"
/* 4 */ "mmfgamm" /* 4 */ "omfgamo"
/* 5 */ "mmmammm" /* 5 */ "mmmammm"
/* 6 */ "mmmmmmm" /* 6 */ "mmooomm"
// Level 31 // Level 31
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "ooomooo" /* 0 */ "ppqqqpp"
/* 1 */ "oaaaaao" /* 1 */ "paaaaap"
/* 2 */ "oa.aaao" /* 2 */ "qa.aaaq"
/* 3 */ "oa..iao" /* 3 */ "qa..iaq"
/* 4 */ "oa..jao" /* 4 */ "qa..jaq"
/* 5 */ "oaaaaao" /* 5 */ "paaaaap"
/* 6 */ "ooooooo" /* 6 */ "ppqqqpp"
// Level 32 // Level 32
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "...p..." /* 0 */ "...r..."
/* 1 */ ".aqrba." /* 1 */ ".astba."
/* 2 */ "...fl.." /* 2 */ "...fl.."
/* 3 */ "......." /* 3 */ "......."
/* 4 */ "......." /* 4 */ "......."
@ -5833,31 +5836,31 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] =
// Level 35 // Level 35
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "ppppppp" /* 0 */ "rrrrrrr"
/* 1 */ "saaaaas" /* 1 */ "uaaaaau"
/* 2 */ ".a...a." /* 2 */ ".a...a."
/* 3 */ ".a...a." /* 3 */ ".a...a."
/* 4 */ ".a...a." /* 4 */ ".a...a."
/* 5 */ "taaaaat" /* 5 */ "vaaaaav"
/* 6 */ "uuuuuuu" /* 6 */ "wwwwwww"
// Level 36 // Level 36
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "......." /* 0 */ "......."
/* 1 */ "ppppppp" /* 1 */ "rrrrrrr"
/* 2 */ "saaaaas" /* 2 */ "uaaaaau"
/* 3 */ ".aaaaa." /* 3 */ ".aaaaa."
/* 4 */ "taaaaat" /* 4 */ "vaaaaav"
/* 5 */ "uuuuuuu" /* 5 */ "wwwwwww"
/* 6 */ "......." /* 6 */ "......."
// Level 37 // Level 37
/* z\x* 0123456 */ /* z\x* 0123456 */
/* 0 */ "......." /* 0 */ "......."
/* 1 */ "......." /* 1 */ "......."
/* 2 */ "ppppppp" /* 2 */ "rrrrrrr"
/* 3 */ "aaaaaaa" /* 3 */ "aaaaaaa"
/* 4 */ "uuuuuuu" /* 4 */ "wwwwwww"
/* 5 */ "......." /* 5 */ "......."
/* 6 */ ".......", /* 6 */ ".......",

View File

@ -23,8 +23,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
12, 6, 10, // SizeX = 12, SizeY = 6, SizeZ = 10 12, 6, 10, // SizeX = 12, SizeY = 6, SizeZ = 10
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
11, 5, 9, // MaxX, MaxY, MaxZ 12, 5, 10, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */
@ -170,8 +170,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
13, 6, 9, // SizeX = 13, SizeY = 6, SizeZ = 9 13, 6, 9, // SizeX = 13, SizeY = 6, SizeZ = 9
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
12, 5, 8, // MaxX, MaxY, MaxZ 13, 5, 9, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */
@ -309,8 +309,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
7, 6, 6, // SizeX = 7, SizeY = 6, SizeZ = 6 7, 6, 6, // SizeX = 7, SizeY = 6, SizeZ = 6
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
6, 5, 5, // MaxX, MaxY, MaxZ 7, 5, 6, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */
@ -420,8 +420,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
6, 5, 6, // MaxX, MaxY, MaxZ 7, 5, 7, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */
@ -538,8 +538,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
9, 6, 7, // SizeX = 9, SizeY = 6, SizeZ = 7 9, 6, 7, // SizeX = 9, SizeY = 6, SizeZ = 7
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
8, 5, 6, // MaxX, MaxY, MaxZ 9, 5, 7, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */
@ -656,8 +656,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
10, 6, 7, // SizeX = 10, SizeY = 6, SizeZ = 7 10, 6, 7, // SizeX = 10, SizeY = 6, SizeZ = 7
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
9, 5, 6, // MaxX, MaxY, MaxZ 10, 5, 7, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */
@ -780,8 +780,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
10, 6, 9, // SizeX = 10, SizeY = 6, SizeZ = 9 10, 6, 9, // SizeX = 10, SizeY = 6, SizeZ = 9
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
9, 5, 8, // MaxX, MaxY, MaxZ 10, 5, 9, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */
@ -918,8 +918,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
11, 6, 9, // SizeX = 11, SizeY = 6, SizeZ = 9 11, 6, 9, // SizeX = 11, SizeY = 6, SizeZ = 9
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
10, 5, 8, // MaxX, MaxY, MaxZ 11, 5, 9, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */
@ -1054,18 +1054,18 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
// The data has been exported from the gallery Desert, area index 53, ID 345, created by jakibaki // The data has been exported from the gallery Desert, area index 53, ID 345, created by jakibaki
{ {
// Size: // Size:
15, 5, 14, // SizeX = 15, SizeY = 5, SizeZ = 14 15, 6, 14, // SizeX = 15, SizeY = 6, SizeZ = 14
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
14, 4, 13, // MaxX, MaxY, MaxZ 15, 5, 14, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */
"a:128: 0\n" /* sandstonestairs */ "a: 24: 0\n" /* sandstone */
"b:128: 2\n" /* sandstonestairs */ "b:128: 0\n" /* sandstonestairs */
"c:128: 1\n" /* sandstonestairs */ "c:128: 2\n" /* sandstonestairs */
"d: 24: 0\n" /* sandstone */ "d:128: 1\n" /* sandstonestairs */
"e: 43: 1\n" /* doubleslab */ "e: 43: 1\n" /* doubleslab */
"f: 64: 7\n" /* wooddoorblock */ "f: 64: 7\n" /* wooddoorblock */
"g:171: 0\n" /* carpet */ "g:171: 0\n" /* carpet */
@ -1088,43 +1088,61 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
// Level 0 // Level 0
/* z\x* 11111 */ /* z\x* 11111 */
/* * 012345678901234 */ /* * 012345678901234 */
/* 0 */ "...abc........." /* 0 */ "mmmaaammmmmmmmm"
/* 1 */ ".ddddddddddddd." /* 1 */ "maaaaaaaaaaaaam"
/* 2 */ ".ddddddddddddd." /* 2 */ "maaaaaaaaaaaaam"
/* 3 */ ".ddddddddddddd." /* 3 */ "maaaaaaaaaaaaam"
/* 4 */ ".ddddddddddddd." /* 4 */ "maaaaaaaaaaaaam"
/* 5 */ ".ddddddddddded." /* 5 */ "maaaaaaaaaaaaam"
/* 6 */ ".ddddddddddddd." /* 6 */ "maaaaaaaaaaaaam"
/* 7 */ ".ddddddddddddd." /* 7 */ "maaaaaaaaaaaaam"
/* 8 */ ".......deddddd." /* 8 */ "mmmmmmmaaaaaaam"
/* 9 */ "mmmmmm.ddddddd." /* 9 */ "mmmmmmmaaaaaaam"
/* 10 */ "mmmmmm.ddddddd." /* 10 */ "mmmmmmmaaaaaaam"
/* 11 */ "mmmmmm.ddddddd." /* 11 */ "mmmmmmmaaaaaaam"
/* 12 */ "mmmmmm.ddddddd." /* 12 */ "mmmmmmmaaaaaaam"
/* 13 */ "..............." /* 13 */ "mmmmmmmmmmmmmmm"
// Level 1 // Level 1
/* z\x* 11111 */ /* z\x* 11111 */
/* * 012345678901234 */ /* * 012345678901234 */
/* 0 */ "..............." /* 0 */ "...bcd........."
/* 1 */ ".dddfddddddddd." /* 1 */ ".aaaaaaaaaaaaa."
/* 2 */ ".dgghhhhhhhhgd." /* 2 */ ".aaaaaaaaaaaaa."
/* 3 */ ".dghiiiiiiiihd." /* 3 */ ".aaaaaaaaaaaaa."
/* 4 */ ".dghiggggggihd." /* 4 */ ".aaaaaaaaaaaaa."
/* 5 */ ".dghiiiiiigihd." /* 5 */ ".aaaaaaaaaaaea."
/* 6 */ ".dgghhhhhigihd." /* 6 */ ".aaaaaaaaaaaaa."
/* 7 */ ".dddddddhigihd." /* 7 */ ".aaaaaaaaaaaaa."
/* 8 */ ".......dhigihd." /* 8 */ ".......aeaaaaa."
/* 9 */ "mmmmmm.dhiiihd." /* 9 */ "mmmmmm.aaaaaaa."
/* 10 */ "mmmmmm.dghhhgd." /* 10 */ "mmmmmm.aaaaaaa."
/* 11 */ "mmmmmm.dggggjd." /* 11 */ "mmmmmm.aaaaaaa."
/* 12 */ "mmmmmm.ddddddd." /* 12 */ "mmmmmm.aaaaaaa."
/* 13 */ "..............." /* 13 */ "..............."
// Level 2 // Level 2
/* z\x* 11111 */ /* z\x* 11111 */
/* * 012345678901234 */ /* * 012345678901234 */
/* 0 */ "..............." /* 0 */ "..............."
/* 1 */ ".aaafaaaaaaaaa."
/* 2 */ ".agghhhhhhhhga."
/* 3 */ ".aghiiiiiiiiha."
/* 4 */ ".aghiggggggiha."
/* 5 */ ".aghiiiiiigiha."
/* 6 */ ".agghhhhhigiha."
/* 7 */ ".aaaaaaahigiha."
/* 8 */ ".......ahigiha."
/* 9 */ "mmmmmm.ahiiiha."
/* 10 */ "mmmmmm.aghhhga."
/* 11 */ "mmmmmm.aggggja."
/* 12 */ "mmmmmm.aaaaaaa."
/* 13 */ "..............."
// Level 3
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ ".kkklkkkk.kkkk." /* 1 */ ".kkklkkkk.kkkk."
/* 2 */ ".k...........k." /* 2 */ ".k...........k."
/* 3 */ ".k...........k." /* 3 */ ".k...........k."
@ -1139,44 +1157,44 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
/* 12 */ "mmmmmm.kkk.kkk." /* 12 */ "mmmmmm.kkk.kkk."
/* 13 */ "..............." /* 13 */ "..............."
// Level 3
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ ".ddddddddddddd."
/* 2 */ ".d......n....d."
/* 3 */ ".d...........d."
/* 4 */ ".do..........d."
/* 5 */ ".d...........d."
/* 6 */ ".d..........pd."
/* 7 */ ".ddddddd.....d."
/* 8 */ ".......d.....d."
/* 9 */ "mmmmmm.d.....d."
/* 10 */ "mmmmmm.d.....d."
/* 11 */ "mmmmmm.d..q..d."
/* 12 */ "mmmmmm.ddddddd."
/* 13 */ "..............."
// Level 4 // Level 4
/* z\x* 11111 */ /* z\x* 11111 */
/* * 012345678901234 */ /* * 012345678901234 */
/* 0 */ "..............."
/* 1 */ ".aaaaaaaaaaaaa."
/* 2 */ ".a......n....a."
/* 3 */ ".a...........a."
/* 4 */ ".ao..........a."
/* 5 */ ".a...........a."
/* 6 */ ".a..........pa."
/* 7 */ ".aaaaaaa.....a."
/* 8 */ ".......a.....a."
/* 9 */ "mmmmmm.a.....a."
/* 10 */ "mmmmmm.a.....a."
/* 11 */ "mmmmmm.a..q..a."
/* 12 */ "mmmmmm.aaaaaaa."
/* 13 */ "..............."
// Level 5
/* z\x* 11111 */
/* * 012345678901234 */
/* 0 */ "rrrrrrrrrrrrrrs" /* 0 */ "rrrrrrrrrrrrrrs"
/* 1 */ "tddddddddddddds" /* 1 */ "taaaaaaaaaaaaas"
/* 2 */ "tddddddddddddds" /* 2 */ "taaaaaaaaaaaaas"
/* 3 */ "tddddddddddddds" /* 3 */ "taaaaaaaaaaaaas"
/* 4 */ "tddddddddddddds" /* 4 */ "taaaaaaaaaaaaas"
/* 5 */ "tddddddddddddds" /* 5 */ "taaaaaaaaaaaaas"
/* 6 */ "tddddddddddddds" /* 6 */ "taaaaaaaaaaaaas"
/* 7 */ "tddddddddddddds" /* 7 */ "taaaaaaaaaaaaas"
/* 8 */ "tuuuuutddddddds" /* 8 */ "tuuuuutaaaaaaas"
/* 9 */ "mmmmmmtddddddds" /* 9 */ "mmmmmmtaaaaaaas"
/* 10 */ "mmmmmmtddddddds" /* 10 */ "mmmmmmtaaaaaaas"
/* 11 */ "mmmmmmtddddddds" /* 11 */ "mmmmmmtaaaaaaas"
/* 12 */ "mmmmmmtddddddds" /* 12 */ "mmmmmmtaaaaaaas"
/* 13 */ "......tuuuuuuuu", /* 13 */ "......tuuuuuuuu",
// Connectors: // Connectors:
"-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */, "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations: // AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */ 7, /* 1, 2, 3 CCW rotation allowed */
@ -1210,8 +1228,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
6, 5, 6, // MaxX, MaxY, MaxZ 7, 5, 7, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */
@ -1320,8 +1338,8 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] =
14, 4, 16, // SizeX = 14, SizeY = 4, SizeZ = 16 14, 4, 16, // SizeX = 14, SizeY = 4, SizeZ = 16
// Hitbox (relative to bounding box): // Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ -1, 0, 0, // MinX, MinY, MinZ
13, 3, 15, // MaxX, MaxY, MaxZ 14, 3, 16, // MaxX, MaxY, MaxZ
// Block definitions: // Block definitions:
".: 0: 0\n" /* air */ ".: 0: 0\n" /* air */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,484 @@
// TestRailsPrefabs.cpp
// Defines the prefabs in the group TestRails
// NOTE: This file has been generated automatically by GalExport!
// Any manual changes will be overwritten by the next automatic export!
#include "Globals.h"
#include "TestRailsPrefabs.h"
const cPrefab::sDef g_TestRailsPrefabs[] =
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ActivatorRail:
// The data has been exported from the gallery Plains, area index 251, ID 746, created by Aloe_vera
{
// Size:
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
6, 2, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
"b: 5: 0\n" /* wood */
"c:157: 0\n" /* activatorrail */
"d:157: 2\n" /* activatorrail */
"e:157: 3\n" /* activatorrail */
"f:157: 5\n" /* activatorrail */
"g: 50: 5\n" /* torch */
"h:157: 4\n" /* activatorrail */
"i:157: 1\n" /* activatorrail */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 0123456 */
/* 0 */ "aaab..."
/* 1 */ "abbbbb."
/* 2 */ "abbb.b."
/* 3 */ "bbbb.bb"
/* 4 */ ".b...b."
/* 5 */ ".bbbbb."
/* 6 */ "...b..."
// Level 1
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".cdbec."
/* 2 */ ".fg..f."
/* 3 */ ".b.g.b."
/* 4 */ ".h...h."
/* 5 */ ".cdbec."
/* 6 */ "......."
// Level 2
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "...i..."
/* 2 */ "......."
/* 3 */ ".c...c."
/* 4 */ "......."
/* 5 */ "...i..."
/* 6 */ ".......",
// Connectors:
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
false,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // ActivatorRail
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DetectorRail:
// The data has been exported from the gallery Plains, area index 250, ID 745, created by Aloe_vera
{
// Size:
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
6, 2, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
"b: 5: 0\n" /* wood */
"c: 28: 0\n" /* detectorrail */
"d: 28: 2\n" /* detectorrail */
"e: 28: 3\n" /* detectorrail */
"f: 28: 5\n" /* detectorrail */
"g: 50: 5\n" /* torch */
"h: 28: 4\n" /* detectorrail */
"i: 28: 1\n" /* detectorrail */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 0123456 */
/* 0 */ "aaab..."
/* 1 */ "abbbbb."
/* 2 */ "abbb.b."
/* 3 */ "bbbb.bb"
/* 4 */ ".b...b."
/* 5 */ ".bbbbb."
/* 6 */ "...b..."
// Level 1
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".cdbec."
/* 2 */ ".fg..f."
/* 3 */ ".b.g.b."
/* 4 */ ".h...h."
/* 5 */ ".cdbec."
/* 6 */ "......."
// Level 2
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "...i..."
/* 2 */ "......."
/* 3 */ ".c...c."
/* 4 */ "......."
/* 5 */ "...i..."
/* 6 */ ".......",
// Connectors:
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
false,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // DetectorRail
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PowerRail:
// The data has been exported from the gallery Plains, area index 248, ID 743, created by Aloe_vera
{
// Size:
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
6, 2, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
"b: 5: 0\n" /* wood */
"c: 27: 0\n" /* poweredrail */
"d: 27: 2\n" /* poweredrail */
"e: 27: 3\n" /* poweredrail */
"f: 27: 5\n" /* poweredrail */
"g: 50: 5\n" /* torch */
"h: 27: 4\n" /* poweredrail */
"i: 27: 1\n" /* poweredrail */
"m: 19: 0\n" /* sponge */,
// Block data:
// Level 0
/* z\x* 0123456 */
/* 0 */ "aaab..."
/* 1 */ "abbbbb."
/* 2 */ "abbb.b."
/* 3 */ "bbbb.bb"
/* 4 */ ".b...b."
/* 5 */ ".bbbbb."
/* 6 */ "...b..."
// Level 1
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".cdbec."
/* 2 */ ".fg..f."
/* 3 */ ".b.g.b."
/* 4 */ ".h...h."
/* 5 */ ".cdbec."
/* 6 */ "......."
// Level 2
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "...i..."
/* 2 */ "......."
/* 3 */ ".c...c."
/* 4 */ "......."
/* 5 */ "...i..."
/* 6 */ ".......",
// Connectors:
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
false,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // PowerRail
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RegularRail:
// The data has been exported from the gallery Plains, area index 247, ID 742, created by Aloe_vera
{
// Size:
7, 3, 7, // SizeX = 7, SizeY = 3, SizeZ = 7
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
6, 2, 6, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
"b: 5: 0\n" /* wood */
"c: 66: 6\n" /* tracks */
"d: 66: 2\n" /* tracks */
"e: 66: 3\n" /* tracks */
"f: 66: 7\n" /* tracks */
"g: 66: 5\n" /* tracks */
"h: 50: 5\n" /* torch */
"i: 66: 4\n" /* tracks */
"j: 66: 9\n" /* tracks */
"k: 66: 8\n" /* tracks */
"l: 66: 1\n" /* tracks */
"m: 19: 0\n" /* sponge */
"n: 66: 0\n" /* tracks */,
// Block data:
// Level 0
/* z\x* 0123456 */
/* 0 */ "aaab..."
/* 1 */ "abbbbb."
/* 2 */ "abbb.b."
/* 3 */ "bbbb.bb"
/* 4 */ ".b...b."
/* 5 */ ".bbbbb."
/* 6 */ "...b..."
// Level 1
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ ".cdbef."
/* 2 */ ".gh..g."
/* 3 */ ".b.h.b."
/* 4 */ ".i...i."
/* 5 */ ".jdbek."
/* 6 */ "......."
// Level 2
/* z\x* 0123456 */
/* 0 */ "......."
/* 1 */ "...l..."
/* 2 */ "......."
/* 3 */ ".n...n."
/* 4 */ "......."
/* 5 */ "...l..."
/* 6 */ ".......",
// Connectors:
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
false,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // RegularRail
}; // g_TestRailsPrefabs
const cPrefab::sDef g_TestRailsStartingPrefabs[] =
{
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CentralPiece:
// The data has been exported from the gallery Plains, area index 249, ID 744, created by Aloe_vera
{
// Size:
6, 3, 6, // SizeX = 6, SizeY = 3, SizeZ = 6
// Hitbox (relative to bounding box):
0, 0, 0, // MinX, MinY, MinZ
5, 2, 5, // MaxX, MaxY, MaxZ
// Block definitions:
".: 0: 0\n" /* air */
"a: 1: 0\n" /* stone */
"b: 5: 0\n" /* wood */
"c: 66: 6\n" /* tracks */
"d: 66: 2\n" /* tracks */
"e: 66: 3\n" /* tracks */
"f: 66: 7\n" /* tracks */
"g: 66: 5\n" /* tracks */
"h: 50: 5\n" /* torch */
"i: 66: 4\n" /* tracks */
"j: 66: 9\n" /* tracks */
"k: 66: 8\n" /* tracks */
"l: 66: 1\n" /* tracks */
"m: 19: 0\n" /* sponge */
"n: 66: 0\n" /* tracks */,
// Block data:
// Level 0
/* z\x* 012345 */
/* 0 */ "aaab.."
/* 1 */ "abbbbb"
/* 2 */ "abbb.b"
/* 3 */ "bbbb.b"
/* 4 */ ".b...b"
/* 5 */ ".bbbbb"
// Level 1
/* z\x* 012345 */
/* 0 */ "......"
/* 1 */ ".cdbef"
/* 2 */ ".gh..g"
/* 3 */ ".b.h.b"
/* 4 */ ".i...i"
/* 5 */ ".jdbek"
// Level 2
/* z\x* 012345 */
/* 0 */ "......"
/* 1 */ "...l.."
/* 2 */ "......"
/* 3 */ ".n...n"
/* 4 */ "......"
/* 5 */ "...l..",
// Connectors:
"1: 3, 1, 6: 3\n" /* Type 1, direction Z+ */
"1: 0, 1, 3: 4\n" /* Type 1, direction X- */
"-1: 0, 1, 3: 4\n" /* Type -1, direction X- */
"-1: 3, 1, 6: 3\n" /* Type -1, direction Z+ */
"1: 6, 1, 3: 5\n" /* Type 1, direction X+ */
"-1: 6, 1, 3: 5\n" /* Type -1, direction X+ */
"1: 3, 1, 0: 2\n" /* Type 1, direction Z- */
"-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */,
// AllowedRotations:
7, /* 1, 2, 3 CCW rotation allowed */
// Merge strategy:
cBlockArea::msSpongePrint,
// ShouldExtendFloor:
true,
// DefaultWeight:
100,
// DepthWeight:
"",
// AddWeightIfSame:
0,
// MoveToGround:
false,
}, // CentralPiece
};
// The prefab counts:
const size_t g_TestRailsPrefabsCount = ARRAYCOUNT(g_TestRailsPrefabs);
const size_t g_TestRailsStartingPrefabsCount = ARRAYCOUNT(g_TestRailsStartingPrefabs);

View File

@ -0,0 +1,15 @@
// TestRailsPrefabs.h
// Declares the prefabs in the group TestRails
#include "../Prefab.h"
extern const cPrefab::sDef g_TestRailsPrefabs[];
extern const cPrefab::sDef g_TestRailsStartingPrefabs[];
extern const size_t g_TestRailsPrefabsCount;
extern const size_t g_TestRailsStartingPrefabsCount;

View File

@ -366,7 +366,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] =
true, true,
// DefaultWeight: // DefaultWeight:
100, 200,
// DepthWeight: // DepthWeight:
"", "",

View File

@ -0,0 +1,116 @@
// TestRailsGen.cpp
// Implements the cTestRailsGen class representing the testing rails generator
#include "Globals.h"
#include "TestRailsGen.h"
#include "Prefabs/TestRailsPrefabs.h"
#include "PieceGenerator.h"
static cPrefabPiecePool g_TestRails(g_TestRailsPrefabs, g_TestRailsPrefabsCount, g_TestRailsStartingPrefabs, g_TestRailsStartingPrefabsCount);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cTestRailsGen::cTestRails:
class cTestRailsGen::cTestRails :
public cGridStructGen::cStructure
{
typedef cGridStructGen::cStructure super;
public:
cTestRails(
int a_Seed,
int a_GridX, int a_GridZ,
int a_OriginX, int a_OriginZ,
int a_MaxDepth,
int a_MaxSize
) :
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Seed(a_Seed),
m_Noise(a_Seed),
m_MaxSize(a_MaxSize),
m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, 255, a_OriginZ + a_MaxSize)
{
// Generate the pieces for this test:
cBFSPieceGenerator pg(g_TestRails, a_Seed);
pg.PlacePieces(a_OriginX, 150, a_OriginZ, a_MaxDepth, m_Pieces);
if (m_Pieces.empty())
{
return;
}
}
~cTestRails()
{
cPieceGenerator::FreePieces(m_Pieces);
}
protected:
/** Seed for the random functions */
int m_Seed;
/** The noise used as a pseudo-random generator */
cNoise m_Noise;
/** Maximum size, in X/Z blocks, of the structure (radius from the origin) */
int m_MaxSize;
/** Borders of the structure - no item may reach out of this cuboid. */
cCuboid m_Borders;
/** The rails pieces, placed by the generator. */
cPlacedPieces m_Pieces;
// cGridStructGen::cStructure overrides:
virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override
{
for (cPlacedPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr)
{
cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece());
Prefab.Draw(a_Chunk, *itr);
} // for itr - m_PlacedPieces[]
}
} ;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cTestRailsGen:
cTestRailsGen::cTestRailsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
m_Noise(a_Seed + 1000),
m_MaxDepth(a_MaxDepth),
m_MaxSize(a_MaxSize)
{
}
cGridStructGen::cStructurePtr cTestRailsGen::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
// Create a base based on the chosen prefabs:
return cStructurePtr(new cTestRails(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize));
}

View File

@ -0,0 +1,47 @@
// TestRailsGen.h
// Declares the cTestRailsGen class representing the testing rails generator
#pragma once
#include "GridStructGen.h"
#include "PrefabPiecePool.h"
class cTestRailsGen :
public cGridStructGen
{
typedef cGridStructGen super;
public:
cTestRailsGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize);
protected:
class cTestRails; // fwd: TestRailsGen.cpp
/** The noise used for generating random numbers */
cNoise m_Noise;
/** Maximum depth of the generator tree*/
int m_MaxDepth;
/** Maximum size, in X/Z blocks, of the base (radius from the origin) */
int m_MaxSize;
// cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;
} ;

View File

@ -30,10 +30,12 @@ cGroupManager::~cGroupManager()
for( GroupMap::iterator itr = m_pState->Groups.begin(); itr != m_pState->Groups.end(); ++itr ) for( GroupMap::iterator itr = m_pState->Groups.begin(); itr != m_pState->Groups.end(); ++itr )
{ {
delete itr->second; delete itr->second;
itr->second = NULL;
} }
m_pState->Groups.clear(); m_pState->Groups.clear();
delete m_pState; delete m_pState;
m_pState = NULL;
} }

View File

@ -28,6 +28,7 @@ cHTTPConnection::~cHTTPConnection()
{ {
// LOGD("HTTP: Connection deleting: %p", this); // LOGD("HTTP: Connection deleting: %p", this);
delete m_CurrentRequest; delete m_CurrentRequest;
m_CurrentRequest = NULL;
} }

View File

@ -28,6 +28,7 @@ cItemGrid::cItemGrid(int a_Width, int a_Height) :
cItemGrid::~cItemGrid() cItemGrid::~cItemGrid()
{ {
delete[] m_Slots; delete[] m_Slots;
m_Slots = NULL;
} }

View File

@ -66,6 +66,7 @@ public:
if (!Arrow->Initialize(*a_Player->GetWorld())) if (!Arrow->Initialize(*a_Player->GetWorld()))
{ {
delete Arrow; delete Arrow;
Arrow = NULL;
return; return;
} }

View File

@ -260,6 +260,7 @@ void cItemHandler::Deinit()
for(int i = 0; i < 2267; i++) for(int i = 0; i < 2267; i++)
{ {
delete m_ItemHandler[i]; delete m_ItemHandler[i];
m_ItemHandler[i] = NULL;
} }
memset(m_ItemHandler, 0, sizeof(m_ItemHandler)); // Don't leave any dangling pointers around, just in case memset(m_ItemHandler, 0, sizeof(m_ItemHandler)); // Don't leave any dangling pointers around, just in case
m_HandlerInitialized = false; m_HandlerInitialized = false;

View File

@ -37,6 +37,7 @@ public:
if (!ItemFrame->Initialize(*a_World)) if (!ItemFrame->Initialize(*a_World))
{ {
delete ItemFrame; delete ItemFrame;
ItemFrame = NULL;
return false; return false;
} }

View File

@ -31,6 +31,17 @@ public:
Vector3d Pos = a_Player->GetThrowStartPos(); Vector3d Pos = a_Player->GetThrowStartPos();
Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff; Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff;
// Play sound
cFastRandom Random;
a_World->BroadcastSoundEffect(
"random.bow",
(int)std::floor(a_Player->GetPosX() * 8.0),
(int)std::floor((a_Player->GetPosY() - a_Player->GetHeight()) * 8.0),
(int)std::floor(a_Player->GetPosZ() * 8.0),
0.5F,
0.4F / (Random.NextFloat(1.0F) * 0.4F + 0.8F)
);
if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed) < 0) if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed) < 0)
{ {
return false; return false;

View File

@ -23,7 +23,7 @@ class cReader :
BLOCKTYPE * OutputRows = m_BlockTypes; BLOCKTYPE * OutputRows = m_BlockTypes;
int InputIdx = 0; int InputIdx = 0;
int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3; int OutputIdx = m_ReadingChunkX + m_ReadingChunkZ * cChunkDef::Width * 3;
int MaxHeight = std::min(cChunkDef::Height, m_MaxHeight + 16); // Need 16 blocks above the highest int MaxHeight = std::min(+cChunkDef::Height, m_MaxHeight + 16); // Need 16 blocks above the highest
for (int y = 0; y < MaxHeight; y++) for (int y = 0; y < MaxHeight; y++)
{ {
for (int z = 0; z < cChunkDef::Width; z++) for (int z = 0; z < cChunkDef::Width; z++)

View File

@ -57,6 +57,7 @@ cMCLogger::~cMCLogger()
{ {
m_Log->Log("--- Stopped Log ---\n"); m_Log->Log("--- Stopped Log ---\n");
delete m_Log; delete m_Log;
m_Log = NULL;
if (this == s_MCLogger) if (this == s_MCLogger)
{ {
s_MCLogger = NULL; s_MCLogger = NULL;

View File

@ -47,6 +47,7 @@ void cBlaze::Attack(float a_Dt)
if (!FireCharge->Initialize(*m_World)) if (!FireCharge->Initialize(*m_World))
{ {
delete FireCharge; delete FireCharge;
FireCharge = NULL;
return; return;
} }
m_World->BroadcastSpawnEntity(*FireCharge); m_World->BroadcastSpawnEntity(*FireCharge);

View File

@ -49,6 +49,7 @@ void cGhast::Attack(float a_Dt)
if (!GhastBall->Initialize(*m_World)) if (!GhastBall->Initialize(*m_World))
{ {
delete GhastBall; delete GhastBall;
GhastBall = NULL;
return; return;
} }
m_World->BroadcastSpawnEntity(*GhastBall); m_World->BroadcastSpawnEntity(*GhastBall);

View File

@ -84,6 +84,7 @@ void cSkeleton::Attack(float a_Dt)
if (!Arrow->Initialize(*m_World)) if (!Arrow->Initialize(*m_World))
{ {
delete Arrow; delete Arrow;
Arrow = NULL;
return; return;
} }
m_World->BroadcastSpawnEntity(*Arrow); m_World->BroadcastSpawnEntity(*Arrow);

View File

@ -47,6 +47,7 @@ cMonsterConfig::cMonsterConfig(void)
cMonsterConfig::~cMonsterConfig() cMonsterConfig::~cMonsterConfig()
{ {
delete m_pState; delete m_pState;
m_pState = NULL;
} }

View File

@ -877,6 +877,7 @@ void cPerlinNoise::Generate2D(
if (ShouldFreeWorkspace) if (ShouldFreeWorkspace)
{ {
delete[] a_Workspace; delete[] a_Workspace;
a_Workspace = NULL;
} }
} }
@ -943,6 +944,7 @@ void cPerlinNoise::Generate3D(
if (ShouldFreeWorkspace) if (ShouldFreeWorkspace)
{ {
delete[] a_Workspace; delete[] a_Workspace;
a_Workspace = NULL;
} }
} }
@ -1045,6 +1047,7 @@ void cRidgedMultiNoise::Generate2D(
if (ShouldFreeWorkspace) if (ShouldFreeWorkspace)
{ {
delete[] a_Workspace; delete[] a_Workspace;
a_Workspace = NULL;
} }
} }
@ -1111,6 +1114,7 @@ void cRidgedMultiNoise::Generate3D(
if (ShouldFreeWorkspace) if (ShouldFreeWorkspace)
{ {
delete[] a_Workspace; delete[] a_Workspace;
a_Workspace = NULL;
} }
} }

View File

@ -71,6 +71,7 @@ cEvent::~cEvent()
{ {
sem_destroy(m_Event); sem_destroy(m_Event);
delete m_Event; delete m_Event;
m_Event = NULL;
} }
#endif #endif
} }

View File

@ -61,6 +61,7 @@ bool cSocketThreads::AddClient(const cSocket & a_Socket, cCallback * a_Client)
// There was an error launching the thread (but it was already logged along with the reason) // There was an error launching the thread (but it was already logged along with the reason)
LOGERROR("A new cSocketThread failed to start"); LOGERROR("A new cSocketThread failed to start");
delete Thread; delete Thread;
Thread = NULL;
return false; return false;
} }
Thread->AddClient(a_Socket, a_Client); Thread->AddClient(a_Socket, a_Client);

View File

@ -66,11 +66,13 @@ cThread::cThread( ThreadFunc a_ThreadFunction, void* a_Param, const char* a_Thre
cThread::~cThread() cThread::~cThread()
{ {
delete m_Event; delete m_Event;
m_Event = NULL;
if( m_StopEvent ) if( m_StopEvent )
{ {
m_StopEvent->Wait(); m_StopEvent->Wait();
delete m_StopEvent; delete m_StopEvent;
m_StopEvent = NULL;
} }
} }

View File

@ -37,6 +37,7 @@ cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) :
cProtocolRecognizer::~cProtocolRecognizer() cProtocolRecognizer::~cProtocolRecognizer()
{ {
delete m_Protocol; delete m_Protocol;
m_Protocol = NULL;
} }

View File

@ -326,6 +326,7 @@ void cServer::OnConnectionAccepted(cSocket & a_Socket)
LOGERROR("Client \"%s\" cannot be handled, server probably unstable", ClientIP.c_str()); LOGERROR("Client \"%s\" cannot be handled, server probably unstable", ClientIP.c_str());
a_Socket.CloseSocket(); a_Socket.CloseSocket();
delete NewHandle; delete NewHandle;
NewHandle = NULL;
return; return;
} }

View File

@ -169,7 +169,8 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a
X = Pos->x; X = Pos->x;
Z = Pos->z; Z = Pos->z;
} }
}else if(BlockID == E_BLOCK_AIR) }
else if(BlockID == E_BLOCK_AIR)
{ {
LowestPoint = 9; //This always dominates LowestPoint = 9; //This always dominates
X = Pos->x; X = Pos->x;
@ -177,6 +178,7 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a
} }
delete Pos; delete Pos;
Pos = NULL;
} }
if (LowestPoint == m_World.GetBlockMeta(a_X, a_Y, a_Z)) if (LowestPoint == m_World.GetBlockMeta(a_X, a_Y, a_Z))

View File

@ -59,21 +59,20 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
int RelZ = 0; int RelZ = 0;
BLOCKTYPE Block; BLOCKTYPE Block;
NIBBLETYPE Meta; NIBBLETYPE Meta;
cChunk * Chunk; cChunk * OtherChunk = a_Chunk;
if (a_OtherChunk != NULL) if (a_OtherChunk != NULL)
{ {
RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width; RelX = a_BlockX - a_OtherChunk->GetPosX() * cChunkDef::Width;
RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width; RelZ = a_BlockZ - a_OtherChunk->GetPosZ() * cChunkDef::Width;
a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); a_OtherChunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
Chunk = a_OtherChunk; OtherChunk = a_OtherChunk;
} }
else else
{ {
RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width;
RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width;
a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta);
Chunk = a_Chunk;
} }
// Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid // Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid
@ -92,7 +91,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{ {
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = PoweredBlocks->erase(itr); itr = PoweredBlocks->erase(itr);
Chunk->SetIsRedstoneDirty(true); a_Chunk->SetIsRedstoneDirty(true);
OtherChunk->SetIsRedstoneDirty(true);
continue; continue;
} }
else if ( else if (
@ -107,21 +107,23 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{ {
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = PoweredBlocks->erase(itr); itr = PoweredBlocks->erase(itr);
Chunk->SetIsRedstoneDirty(true); a_Chunk->SetIsRedstoneDirty(true);
OtherChunk->SetIsRedstoneDirty(true);
continue; continue;
} }
else if (Block == E_BLOCK_DAYLIGHT_SENSOR) else if (Block == E_BLOCK_DAYLIGHT_SENSOR)
{ {
if (!m_World.IsChunkLighted(Chunk->GetPosX(), Chunk->GetPosZ())) if (!m_World.IsChunkLighted(OtherChunk->GetPosX(), OtherChunk->GetPosZ()))
{ {
m_World.QueueLightChunk(Chunk->GetPosX(), Chunk->GetPosZ()); m_World.QueueLightChunk(OtherChunk->GetPosX(), OtherChunk->GetPosZ());
} }
else else
{ {
if (Chunk->GetTimeAlteredLight(Chunk->GetSkyLight(RelX, a_BlockY + 1, RelZ)) <= 7) if (OtherChunk->GetTimeAlteredLight(OtherChunk->GetSkyLight(RelX, a_BlockY + 1, RelZ)) <= 7)
{ {
itr = PoweredBlocks->erase(itr); itr = PoweredBlocks->erase(itr);
Chunk->SetIsRedstoneDirty(true); a_Chunk->SetIsRedstoneDirty(true);
OtherChunk->SetIsRedstoneDirty(true);
continue; continue;
} }
} }
@ -139,7 +141,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{ {
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr); itr = LinkedPoweredBlocks->erase(itr);
Chunk->SetIsRedstoneDirty(true); a_Chunk->SetIsRedstoneDirty(true);
OtherChunk->SetIsRedstoneDirty(true);
continue; continue;
} }
else if ( else if (
@ -153,7 +156,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{ {
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr); itr = LinkedPoweredBlocks->erase(itr);
Chunk->SetIsRedstoneDirty(true); a_Chunk->SetIsRedstoneDirty(true);
OtherChunk->SetIsRedstoneDirty(true);
continue; continue;
} }
} }
@ -163,7 +167,8 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY,
{ {
LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z);
itr = LinkedPoweredBlocks->erase(itr); itr = LinkedPoweredBlocks->erase(itr);
Chunk->SetIsRedstoneDirty(true); a_Chunk->SetIsRedstoneDirty(true);
OtherChunk->SetIsRedstoneDirty(true);
continue; continue;
} }
} }
@ -271,6 +276,8 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
ShouldUpdateSimulateOnceBlocks = true; ShouldUpdateSimulateOnceBlocks = true;
} }
HandleRedstoneRepeaterDelays();
for (cRedstoneSimulatorChunkData::iterator dataitr = m_RedstoneSimulatorChunkData->begin(); dataitr != m_RedstoneSimulatorChunkData->end();) for (cRedstoneSimulatorChunkData::iterator dataitr = m_RedstoneSimulatorChunkData->begin(); dataitr != m_RedstoneSimulatorChunkData->end();)
{ {
if (dataitr->DataTwo) if (dataitr->DataTwo)
@ -282,26 +289,6 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
switch (dataitr->Data) switch (dataitr->Data)
{ {
case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break; case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break;
case E_BLOCK_REDSTONE_REPEATER_OFF:
case E_BLOCK_REDSTONE_REPEATER_ON:
{
bool FoundItem = false;
for (RepeatersDelayList::iterator repeateritr = m_RepeatersDelayList->begin(); repeateritr != m_RepeatersDelayList->end(); ++repeateritr)
{
if (repeateritr->a_RelBlockPos == Vector3i(dataitr->x, dataitr->y, dataitr->z))
{
HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data, repeateritr);
FoundItem = true;
break;
}
}
if (!FoundItem && ShouldUpdateSimulateOnceBlocks)
{
HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data, m_RepeatersDelayList->end());
}
break;
}
case E_BLOCK_WOODEN_PRESSURE_PLATE: case E_BLOCK_WOODEN_PRESSURE_PLATE:
case E_BLOCK_STONE_PRESSURE_PLATE: case E_BLOCK_STONE_PRESSURE_PLATE:
case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE:
@ -357,6 +344,12 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int
HandlePiston(dataitr->x, dataitr->y, dataitr->z); HandlePiston(dataitr->x, dataitr->y, dataitr->z);
break; break;
} }
case E_BLOCK_REDSTONE_REPEATER_OFF:
case E_BLOCK_REDSTONE_REPEATER_ON:
{
HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data);
break;
}
case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_OFF:
case E_BLOCK_REDSTONE_TORCH_ON: case E_BLOCK_REDSTONE_TORCH_ON:
{ {
@ -511,29 +504,10 @@ void cIncrementalRedstoneSimulator::HandleRedstoneLever(int a_RelBlockX, int a_R
{ {
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
NIBBLETYPE Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta); eBlockFace Dir = cBlockLeverHandler::BlockMetaDataToBlockFace(Meta);
switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered()
{ Dir = ReverseBlockFace(Dir);
case BLOCK_FACE_YP:
case BLOCK_FACE_XP:
case BLOCK_FACE_ZP:
{
Dir--;
break;
}
case BLOCK_FACE_XM:
case BLOCK_FACE_ZM:
case BLOCK_FACE_YM:
{
Dir++;
break;
}
default:
{
ASSERT(!"Unhandled lever metadata!");
return;
}
}
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir); SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir);
} }
} }
@ -546,15 +520,17 @@ void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBl
{ {
int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX;
int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
cChunkInterface ChunkInterface(m_World.GetChunkMap()); NIBBLETYPE MetaData = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
NIBBLETYPE MetaData = ChunkInterface.GetBlockMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) if (AreCoordsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ))
{ {
if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true)) if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true))
{ {
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData | 0x4); if ((MetaData & 0x4) == 0)
m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); {
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData | 0x4);
m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
}
SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true); SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, true);
} }
} }
@ -562,8 +538,11 @@ void cIncrementalRedstoneSimulator::HandleFenceGate(int a_RelBlockX, int a_RelBl
{ {
if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false)) if (!AreCoordsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false))
{ {
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & 0xFFFFFFFB); if ((MetaData & 0x4) != 0)
m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0); {
m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, MetaData & ~0x04);
m_Chunk->BroadcastSoundParticleEffect(1003, BlockX, a_RelBlockY, BlockZ, 0);
}
SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false); SetPlayerToggleableBlockAsSimulated(a_RelBlockX, a_RelBlockY, a_RelBlockZ, false);
} }
} }
@ -580,27 +559,8 @@ void cIncrementalRedstoneSimulator::HandleRedstoneButton(int a_RelBlockX, int a_
{ {
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
NIBBLETYPE Dir = cBlockButtonHandler::BlockMetaDataToBlockFace(Meta); eBlockFace Dir = cBlockButtonHandler::BlockMetaDataToBlockFace(Meta);
switch (Dir) // Now, flip the direction into the type used by SetBlockLinkedPowered() Dir = ReverseBlockFace(Dir);
{
case BLOCK_FACE_XP:
case BLOCK_FACE_ZP:
{
Dir--;
break;
}
case BLOCK_FACE_XM:
case BLOCK_FACE_ZM:
{
Dir++;
break;
}
default:
{
ASSERT(!"Unhandled button metadata!");
return;
}
}
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir); SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Dir);
} }
} }
@ -767,7 +727,7 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_RelBlockX, int a_Re
void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState, RepeatersDelayList::iterator a_Itr) void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState)
{ {
/* Repeater Orientation Mini Guide: /* Repeater Orientation Mini Guide:
=================================== ===================================
@ -794,102 +754,80 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int
NIBBLETYPE a_Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); NIBBLETYPE a_Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON); bool IsOn = (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON);
bool WereItrsChanged = false;
if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta)) // If we're locked, change nothing. Otherwise: if (!IsRepeaterLocked(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta)) // If we're locked, change nothing. Otherwise:
{ {
bool IsSelfPowered = IsRepeaterPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta); bool IsSelfPowered = IsRepeaterPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta);
if (IsSelfPowered && !IsOn) // Queue a power change if powered, but not on and not locked. if (IsSelfPowered && !IsOn) // Queue a power change if powered, but not on and not locked.
{ {
WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true); QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, true);
} }
else if (!IsSelfPowered && IsOn) // Queue a power change if unpowered, on, and not locked. else if (!IsSelfPowered && IsOn) // Queue a power change if unpowered, on, and not locked.
{ {
WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false); QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false);
}
else if (a_Itr == m_RepeatersDelayList->end())
{
return;
} }
} }
else if (a_Itr == m_RepeatersDelayList->end()) }
{
return;
}
if (WereItrsChanged) void cIncrementalRedstoneSimulator::HandleRedstoneRepeaterDelays()
{
for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end();)
{ {
for (a_Itr = m_RepeatersDelayList->begin(); a_Itr != m_RepeatersDelayList->end(); ++a_Itr)
if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
{ {
if (a_Itr->a_RelBlockPos == Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) int RelBlockX = itr->a_RelBlockPos.x;
int RelBlockY = itr->a_RelBlockPos.y;
int RelBlockZ = itr->a_RelBlockPos.z;
NIBBLETYPE Meta = m_Chunk->GetMeta(RelBlockX, RelBlockY, RelBlockZ);
if (itr->ShouldPowerOn)
{ {
// Leave a_Itr at where we found the entry
break; m_Chunk->SetBlock(itr->a_RelBlockPos, E_BLOCK_REDSTONE_REPEATER_ON, Meta); // For performance
}
}
}
// a_Itr may be passed with m_RepeatersDelayList::end, however, we can guarantee this iterator is always valid because... switch (Meta & 0x3) // We only want the direction (bottom) bits
// ...QueueRepeaterPowerChange is called to add an entry (and the above code updates iterator). However, if the repeater was locked or something similar...
// ...we will never get here because of the returns.
if (a_Itr->a_ElapsedTicks >= a_Itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks?
{
if (a_Itr->ShouldPowerOn)
{
if (!IsOn)
{
m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // For performance
}
switch (a_Meta & 0x3) // We only want the direction (bottom) bits
{
case 0x0:
{ {
SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ - 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ); case 0x0:
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZM); {
break; SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ - 1, RelBlockX, RelBlockY, RelBlockZ);
} SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZM);
case 0x1: break;
{ }
SetBlockPowered(a_RelBlockX + 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ); case 0x1:
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XP); {
break; SetBlockPowered(RelBlockX + 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ);
} SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XP);
case 0x2: break;
{ }
SetBlockPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ + 1, a_RelBlockX, a_RelBlockY, a_RelBlockZ); case 0x2:
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_ZP); {
break; SetBlockPowered(RelBlockX, RelBlockY, RelBlockZ + 1, RelBlockX, RelBlockY, RelBlockZ);
} SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_ZP);
case 0x3: break;
{ }
SetBlockPowered(a_RelBlockX - 1, a_RelBlockY, a_RelBlockZ, a_RelBlockX, a_RelBlockY, a_RelBlockZ); case 0x3:
SetDirectionLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, BLOCK_FACE_XM); {
break; SetBlockPowered(RelBlockX - 1, RelBlockY, RelBlockZ, RelBlockX, RelBlockY, RelBlockZ);
SetDirectionLinkedPowered(RelBlockX, RelBlockY, RelBlockZ, BLOCK_FACE_XM);
break;
}
} }
} }
else
// Removal of the data entry will be handled in SimChunk - we still want to continue trying to power blocks, even if our delay time has reached {
// Otherwise, the power state of blocks in front won't update after we have powered on m_Chunk->SetBlock(RelBlockX, RelBlockY, RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, Meta);
return; }
itr = m_RepeatersDelayList->erase(itr);
} }
else else
{ {
if (IsOn) // Apparently, incrementing ticks only works reliably here, and not in SimChunk;
{ // With a world with lots of redstone, the repeaters simply do not delay
m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); // I am confounded to say why. Perhaps optimisation failure.
} LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_RelBlockPos.x, itr->a_RelBlockPos.y, itr->a_RelBlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks);
m_RepeatersDelayList->erase(a_Itr); // We can remove off repeaters which don't need further updating itr->a_ElapsedTicks++;
return; itr++;
} }
} }
else
{
// Apparently, incrementing ticks only works reliably here, and not in SimChunk;
// With a world with lots of redstone, the repeaters simply do not delay
// I am confounded to say why. Perhaps optimisation failure.
LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", a_Itr->a_RelBlockPos.x, a_Itr->a_RelBlockPos.y, a_Itr->a_RelBlockPos.z, a_Itr->a_ElapsedTicks, a_Itr->a_DelayTicks);
a_Itr->a_ElapsedTicks++;
}
} }
@ -1147,19 +1085,17 @@ void cIncrementalRedstoneSimulator::HandleNoteBlock(int a_RelBlockX, int a_RelBl
void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) void cIncrementalRedstoneSimulator::HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ)
{ {
int a_ChunkX, a_ChunkZ; int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX, BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
cChunkDef::BlockToChunk(a_RelBlockX, a_RelBlockZ, a_ChunkX, a_ChunkZ); int ChunkX, ChunkZ;
cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ);
if (!m_World.IsChunkLighted(a_ChunkX, a_ChunkZ)) if (!m_World.IsChunkLighted(ChunkX, ChunkZ))
{ {
m_World.QueueLightChunk(a_ChunkX, a_ChunkZ); m_World.QueueLightChunk(ChunkX, ChunkZ);
} }
else else
{ {
int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; if (m_Chunk->GetTimeAlteredLight(m_World.GetBlockSkyLight(BlockX, a_RelBlockY + 1, BlockZ)) > 8)
int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ;
NIBBLETYPE SkyLight = m_Chunk->GetTimeAlteredLight(m_World.GetBlockSkyLight(BlockX, a_RelBlockY + 1, BlockZ));
if (SkyLight > 8)
{ {
SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ);
} }

View File

@ -108,7 +108,9 @@ private:
/** Handles redstone wire */ /** Handles redstone wire */
void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
/** Handles repeaters */ /** Handles repeaters */
void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState, RepeatersDelayList::iterator a_Itr); void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
/** Handles delayed updates to Repeaters **/
void HandleRedstoneRepeaterDelays();
/* ====================== */ /* ====================== */
/* ====== DEVICES ====== */ /* ====== DEVICES ====== */

View File

@ -11,8 +11,12 @@
cVoronoiMap::cVoronoiMap(int a_Seed, int a_CellSize) : cVoronoiMap::cVoronoiMap(int a_Seed, int a_CellSize) :
m_Noise(a_Seed), m_Noise1(a_Seed + 1),
m_CellSize(a_CellSize) m_Noise2(a_Seed + 2),
m_Noise3(a_Seed + 3),
m_CellSize(a_CellSize),
m_CurrentCellX(9999999), // Cell coords that are definitely out of the range for normal generator, so that the first query will overwrite them
m_CurrentCellZ(9999999)
{ {
} }
@ -57,26 +61,25 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2
int CellX = a_X / m_CellSize; int CellX = a_X / m_CellSize;
int CellZ = a_Y / m_CellSize; int CellZ = a_Y / m_CellSize;
UpdateCell(CellX, CellZ);
// Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell // Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell
int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this
int MinDist2 = MinDist; int MinDist2 = MinDist;
int res = 0; // Will be overriden int res = 0; // Will be overriden
for (int x = CellX - 2; x <= CellX + 2; x++) for (int x = 0; x < 5; x++)
{ {
int BaseX = x * m_CellSize; for (int z = 0; z < 5; z++)
for (int z = CellZ - 2; z < CellZ + 2; z++)
{ {
int OffsetX = (m_Noise.IntNoise3DInt(x, 16 * x + 32 * z, z) / 8) % m_CellSize; int SeedX = m_SeedX[x][z];
int OffsetZ = (m_Noise.IntNoise3DInt(x, 32 * x - 16 * z, z) / 8) % m_CellSize; int SeedZ = m_SeedZ[x][z];
int SeedX = BaseX + OffsetX;
int SeedZ = z * m_CellSize + OffsetZ;
int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedZ - a_Y) * (SeedZ - a_Y); int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedZ - a_Y) * (SeedZ - a_Y);
if (Dist < MinDist) if (Dist < MinDist)
{ {
MinDist2 = MinDist; MinDist2 = MinDist;
MinDist = Dist; MinDist = Dist;
res = m_Noise.IntNoise3DInt(x, x - z + 1000, z); res = m_Noise3.IntNoise2DInt(x + CellX - 2, z + CellZ - 2);
} }
else if (Dist < MinDist2) else if (Dist < MinDist2)
{ {
@ -93,3 +96,33 @@ int cVoronoiMap::GetValueAt(int a_X, int a_Y, int & a_MinDist1, int & a_MinDist2
void cVoronoiMap::UpdateCell(int a_CellX, int a_CellZ)
{
// If the specified cell is currently cached, bail out:
if ((a_CellX == m_CurrentCellX) && (a_CellZ == m_CurrentCellZ))
{
return;
}
// Update the cell cache for the new cell position:
int NoiseBaseX = a_CellX - 2;
int NoiseBaseZ = a_CellZ - 2;
for (int x = 0; x < 5; x++)
{
int BaseX = (NoiseBaseX + x) * m_CellSize;
for (int z = 0; z < 5; z++)
{
int OffsetX = (m_Noise1.IntNoise2DInt(NoiseBaseX + x, NoiseBaseZ + z) / 8) % m_CellSize;
int OffsetZ = (m_Noise2.IntNoise2DInt(NoiseBaseX + x, NoiseBaseZ + z) / 8) % m_CellSize;
m_SeedX[x][z] = BaseX + OffsetX;
m_SeedZ[x][z] = (NoiseBaseZ + z) * m_CellSize + OffsetZ;
} // for z
} // for x
m_CurrentCellX = a_CellX;
m_CurrentCellZ = a_CellZ;
}

View File

@ -29,15 +29,34 @@ public:
/// Returns the value in the cell into which the specified point lies, and the distance to the nearest Voronoi seed /// Returns the value in the cell into which the specified point lies, and the distance to the nearest Voronoi seed
int GetValueAt(int a_X, int a_Y, int & a_MinDistance); int GetValueAt(int a_X, int a_Y, int & a_MinDistance);
/// Returns the value in the cell into which the specified point lies, and the distances to the 2 nearest Voronoi seeds /// Returns the value in the cell into which the specified point lies, and the distances to the 2 nearest Voronoi seeds. Uses a cache
int GetValueAt(int a_X, int a_Y, int & a_MinDistance1, int & a_MinDistance2); int GetValueAt(int a_X, int a_Y, int & a_MinDistance1, int & a_MinDistance2);
protected: protected:
/// The noise used for generating Voronoi seeds /// The noise used for generating Voronoi seeds
cNoise m_Noise; cNoise m_Noise1;
cNoise m_Noise2;
cNoise m_Noise3;
/// Size of the Voronoi cells (avg X/Y distance between the seeds) /// Size of the Voronoi cells (avg X/Y distance between the seeds)
int m_CellSize; int m_CellSize;
/** The X coordinate of the currently cached cell neighborhood */
int m_CurrentCellX;
/** The Z coordinate of the currently cached cell neighborhood */
int m_CurrentCellZ;
/** The seeds of cells around m_CurrentCellX, m_CurrentCellZ, X-coords */
int m_SeedX[5][5];
/** The seeds of cells around m_CurrentCellX, m_CurrentCellZ, X-coords */
int m_SeedZ[5][5];
/** Updates the cached cell seeds to match the specified cell. Noop if cell pos already matches.
Updates m_SeedX and m_SeedZ. */
void UpdateCell(int a_CellX, int a_CellZ);
} ; } ;

View File

@ -524,6 +524,7 @@ void cWebAdmin::OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest &
// Delete any request data assigned to the request: // Delete any request data assigned to the request:
cRequestData * Data = (cRequestData *)(a_Request.GetUserData()); cRequestData * Data = (cRequestData *)(a_Request.GetUserData());
delete Data; delete Data;
Data = NULL;
} }

View File

@ -267,12 +267,12 @@ cWorld::cWorld(const AString & a_WorldName) :
cWorld::~cWorld() cWorld::~cWorld()
{ {
delete m_SimulatorManager; delete m_SimulatorManager; m_SimulatorManager = NULL;
delete m_SandSimulator; delete m_SandSimulator; m_SandSimulator = NULL;
delete m_WaterSimulator; delete m_WaterSimulator; m_WaterSimulator = NULL;
delete m_LavaSimulator; delete m_LavaSimulator; m_LavaSimulator = NULL;
delete m_FireSimulator; delete m_FireSimulator; m_FireSimulator = NULL;
delete m_RedstoneSimulator; delete m_RedstoneSimulator; m_RedstoneSimulator = NULL;
UnloadUnusedChunks(); UnloadUnusedChunks();
@ -2972,11 +2972,13 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster)
if (cPluginManager::Get()->CallHookSpawningMonster(*this, *a_Monster)) if (cPluginManager::Get()->CallHookSpawningMonster(*this, *a_Monster))
{ {
delete a_Monster; delete a_Monster;
a_Monster = NULL;
return -1; return -1;
} }
if (!a_Monster->Initialize(*this)) if (!a_Monster->Initialize(*this))
{ {
delete a_Monster; delete a_Monster;
a_Monster = NULL;
return -1; return -1;
} }
BroadcastSpawnEntity(*a_Monster); BroadcastSpawnEntity(*a_Monster);
@ -2999,6 +3001,7 @@ int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProje
if (!Projectile->Initialize(*this)) if (!Projectile->Initialize(*this))
{ {
delete Projectile; delete Projectile;
Projectile = NULL;
return -1; return -1;
} }
return Projectile->GetUniqueID(); return Projectile->GetUniqueID();

View File

@ -532,7 +532,7 @@ public:
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) override; // tolua_export virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) override; // tolua_export
/** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */ /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp virtual bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback) override; // Exported in ManualBindings.cpp
/** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */ /** Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found */
bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp bool DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp
@ -830,6 +830,7 @@ private:
virtual ~cScheduledTask() virtual ~cScheduledTask()
{ {
delete m_Task; delete m_Task;
m_Task = NULL;
} }
}; };

View File

@ -345,6 +345,7 @@ void cNBTChunkSerializer::AddBasicEntity(cEntity * a_Entity, const AString & a_C
m_Writer.AddDouble("", a_Entity->GetYaw()); m_Writer.AddDouble("", a_Entity->GetYaw());
m_Writer.AddDouble("", a_Entity->GetPitch()); m_Writer.AddDouble("", a_Entity->GetPitch());
m_Writer.EndList(); m_Writer.EndList();
m_Writer.AddShort("Health", a_Entity->GetHealth());
} }
@ -575,7 +576,6 @@ void cNBTChunkSerializer::AddPickupEntity(cPickup * a_Pickup)
m_Writer.BeginCompound(""); m_Writer.BeginCompound("");
AddBasicEntity(a_Pickup, "Item"); AddBasicEntity(a_Pickup, "Item");
AddItem(a_Pickup->GetItem(), -1, "Item"); AddItem(a_Pickup->GetItem(), -1, "Item");
m_Writer.AddShort("Health", (Int16)(unsigned char)a_Pickup->GetHealth());
m_Writer.AddShort("Age", (Int16)a_Pickup->GetAge()); m_Writer.AddShort("Age", (Int16)a_Pickup->GetAge());
m_Writer.EndCompound(); m_Writer.EndCompound();
} }
@ -608,17 +608,12 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile)
case cProjectileEntity::pkGhastFireball: case cProjectileEntity::pkGhastFireball:
{ {
m_Writer.AddInt("ExplosionPower", 1); m_Writer.AddInt("ExplosionPower", 1);
// fall-through: break;
} }
case cProjectileEntity::pkFireCharge: case cProjectileEntity::pkFireCharge:
case cProjectileEntity::pkWitherSkull: case cProjectileEntity::pkWitherSkull:
case cProjectileEntity::pkEnderPearl: case cProjectileEntity::pkEnderPearl:
{ {
m_Writer.BeginList("Motion", TAG_Double);
m_Writer.AddDouble("", a_Projectile->GetSpeedX());
m_Writer.AddDouble("", a_Projectile->GetSpeedY());
m_Writer.AddDouble("", a_Projectile->GetSpeedZ());
m_Writer.EndList();
break; break;
} }
default: default:
@ -683,7 +678,6 @@ void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb * a_ExpOrb)
{ {
m_Writer.BeginCompound(""); m_Writer.BeginCompound("");
AddBasicEntity(a_ExpOrb, "XPOrb"); AddBasicEntity(a_ExpOrb, "XPOrb");
m_Writer.AddShort("Health", (Int16)(unsigned char)a_ExpOrb->GetHealth());
m_Writer.AddShort("Age", (Int16)a_ExpOrb->GetAge()); m_Writer.AddShort("Age", (Int16)a_ExpOrb->GetAge());
m_Writer.AddShort("Value", (Int16)a_ExpOrb->GetReward()); m_Writer.AddShort("Value", (Int16)a_ExpOrb->GetReward());
m_Writer.EndCompound(); m_Writer.EndCompound();

View File

@ -469,6 +469,9 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_
a_Writer.AddByte("MCSIsLightValid", 1); a_Writer.AddByte("MCSIsLightValid", 1);
} }
// Store the flag that the chunk has all the ores, trees, dungeons etc. MCS chunks are always complete.
a_Writer.AddByte("TerrainPopulated", 1);
a_Writer.EndCompound(); // "Level" a_Writer.EndCompound(); // "Level"
return true; return true;
} }
@ -1458,13 +1461,6 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a
{ {
return; return;
} }
// Load health:
int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
if (Health > 0)
{
Pickup->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF));
}
// Load age: // Load age:
int Age = a_NBT.FindChildByName(a_TagIdx, "Age"); int Age = a_NBT.FindChildByName(a_TagIdx, "Age");
@ -1510,13 +1506,6 @@ void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a
return; return;
} }
// Load Health:
int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
if (Health > 0)
{
ExpOrb->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF));
}
// Load Age: // Load Age:
int Age = a_NBT.FindChildByName(a_TagIdx, "Age"); int Age = a_NBT.FindChildByName(a_TagIdx, "Age");
if (Age > 0) if (Age > 0)
@ -2434,6 +2423,13 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N
} }
a_Entity.SetYaw(Rotation[0]); a_Entity.SetYaw(Rotation[0]);
a_Entity.SetRoll(Rotation[1]); a_Entity.SetRoll(Rotation[1]);
// Load health:
int Health = a_NBT.FindChildByName(a_TagIdx, "Health");
if (Health > 0)
{
a_Entity.SetHealth(a_NBT.GetShort(Health));
}
return true; return true;
} }

View File

@ -473,6 +473,7 @@ cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_
{ {
LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", "Header", m_FileName.c_str(), __LINE__, f.Tell()); LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", "Header", m_FileName.c_str(), __LINE__, f.Tell());
delete Header; delete Header;
Header = NULL;
return; return;
} }
m_ChunkHeaders.push_back(Header); m_ChunkHeaders.push_back(Header);