Merge branch 'master' into chunksparsing/structs
Conflicts: src/Chunk.h
This commit is contained in:
commit
d478e3cfb1
@ -1 +1 @@
|
||||
Subproject commit 013a32a7fb3c8a6cfe0aef892d4c7394d4e1be59
|
||||
Subproject commit 5c8557d4fdfa580c100510cde07a1a778ea2e244
|
@ -221,7 +221,7 @@ typedef unsigned char Byte;
|
||||
#if (defined(_MSC_VER) && (_MSC_VER < 1600))
|
||||
// MSVC before 2010 doesn't have std::shared_ptr, but has std::tr1::shared_ptr, defined in <memory> included earlier
|
||||
#define SharedPtr std::tr1::shared_ptr
|
||||
#elif (__cplusplus >= 201103L)
|
||||
#elif (defined(_MSC_VER) || (__cplusplus >= 201103L))
|
||||
// C++11 has std::shared_ptr in <memory>, included earlier
|
||||
#define SharedPtr std::shared_ptr
|
||||
#else
|
||||
|
@ -243,7 +243,7 @@ int cIniFile::FindKey(const AString & a_KeyName) const
|
||||
{
|
||||
if (CheckCase(names[keyID]) == CaseKeyName)
|
||||
{
|
||||
return keyID;
|
||||
return (int)keyID;
|
||||
}
|
||||
}
|
||||
return noID;
|
||||
@ -279,7 +279,7 @@ int cIniFile::AddKeyName(const AString & keyname)
|
||||
{
|
||||
names.resize(names.size() + 1, keyname);
|
||||
keys.resize(keys.size() + 1);
|
||||
return names.size() - 1;
|
||||
return (int)names.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
@ -683,7 +683,7 @@ int cIniFile::GetNumKeyComments(const int keyID) const
|
||||
{
|
||||
if (keyID < (int)keys.size())
|
||||
{
|
||||
return keys[keyID].comments.size();
|
||||
return (int)keys[keyID].comments.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -143,13 +143,14 @@ void cPluginManager::ReloadPluginsNow(cIniFile & a_SettingsIni)
|
||||
}
|
||||
}
|
||||
|
||||
if (GetNumPlugins() == 0)
|
||||
size_t NumLoadedPlugins = GetNumPlugins();
|
||||
if (NumLoadedPlugins)
|
||||
{
|
||||
LOG("-- No Plugins Loaded --");
|
||||
}
|
||||
else if (GetNumPlugins() > 1)
|
||||
else if (NumLoadedPlugins > 1)
|
||||
{
|
||||
LOG("-- Loaded %i Plugins --", GetNumPlugins());
|
||||
LOG("-- Loaded %i Plugins --", (int)NumLoadedPlugins);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1869,7 +1870,7 @@ void cPluginManager::AddHook(cPlugin * a_Plugin, int a_Hook)
|
||||
|
||||
|
||||
|
||||
unsigned int cPluginManager::GetNumPlugins() const
|
||||
size_t cPluginManager::GetNumPlugins() const
|
||||
{
|
||||
return m_Plugins.size();
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ public: // tolua_export
|
||||
/** Adds the plugin to the list of plugins called for the specified hook type. Handles multiple adds as a single add */
|
||||
void AddHook(cPlugin * a_Plugin, int a_HookType);
|
||||
|
||||
unsigned int GetNumPlugins() const; // tolua_export
|
||||
size_t GetNumPlugins() const; // tolua_export
|
||||
|
||||
// Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort
|
||||
bool CallHookBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source);
|
||||
|
@ -707,11 +707,11 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R
|
||||
|
||||
if (IsDummyMetas)
|
||||
{
|
||||
MergeByStrategy<true>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
|
||||
MergeByStrategy<false>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
|
||||
}
|
||||
else
|
||||
{
|
||||
MergeByStrategy<false>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
|
||||
MergeByStrategy<true>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
|
||||
}
|
||||
}
|
||||
|
||||
@ -738,31 +738,31 @@ void cBlockArea::Fill(int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_Block
|
||||
a_DataTypes = a_DataTypes & GetDataTypes();
|
||||
}
|
||||
|
||||
int BlockCount = GetBlockCount();
|
||||
size_t BlockCount = GetBlockCount();
|
||||
if ((a_DataTypes & baTypes) != 0)
|
||||
{
|
||||
for (int i = 0; i < BlockCount; i++)
|
||||
for (size_t i = 0; i < BlockCount; i++)
|
||||
{
|
||||
m_BlockTypes[i] = a_BlockType;
|
||||
}
|
||||
}
|
||||
if ((a_DataTypes & baMetas) != 0)
|
||||
{
|
||||
for (int i = 0; i < BlockCount; i++)
|
||||
for (size_t i = 0; i < BlockCount; i++)
|
||||
{
|
||||
m_BlockMetas[i] = a_BlockMeta;
|
||||
}
|
||||
}
|
||||
if ((a_DataTypes & baLight) != 0)
|
||||
{
|
||||
for (int i = 0; i < BlockCount; i++)
|
||||
for (size_t i = 0; i < BlockCount; i++)
|
||||
{
|
||||
m_BlockLight[i] = a_BlockLight;
|
||||
}
|
||||
}
|
||||
if ((a_DataTypes & baSkyLight) != 0)
|
||||
{
|
||||
for (int i = 0; i < BlockCount; i++)
|
||||
for (size_t i = 0; i < BlockCount; i++)
|
||||
{
|
||||
m_BlockSkyLight[i] = a_BlockSkyLight;
|
||||
}
|
||||
|
@ -110,10 +110,13 @@ void cBlockInfo::Initialize(void)
|
||||
// Transparent blocks
|
||||
ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_AIR ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_ANVIL ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_CAKE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_CARROTS ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_CHEST ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_CROPS ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_DANDELION ].m_Transparent = true;
|
||||
@ -126,6 +129,7 @@ void cBlockInfo::Initialize(void)
|
||||
ms_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_GLASS ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_HEAD ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_ICE ].m_Transparent = true;
|
||||
ms_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true;
|
||||
@ -196,12 +200,14 @@ void cBlockInfo::Initialize(void)
|
||||
ms_Info[E_BLOCK_BED ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_CAKE ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_CROPS ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_FIRE ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_HEAD ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true;
|
||||
ms_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true;
|
||||
@ -243,6 +249,7 @@ void cBlockInfo::Initialize(void)
|
||||
ms_Info[E_BLOCK_CACTUS ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_CHEST ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_CROPS ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_DANDELION ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_FIRE ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_FLOWER ].m_IsSnowable = false;
|
||||
@ -276,6 +283,7 @@ void cBlockInfo::Initialize(void)
|
||||
ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_IsSnowable = false;
|
||||
ms_Info[E_BLOCK_HEAD ].m_IsSnowable = false;
|
||||
|
||||
|
||||
// Blocks that don't drop without a special tool:
|
||||
@ -283,6 +291,7 @@ void cBlockInfo::Initialize(void)
|
||||
ms_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true;
|
||||
ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true;
|
||||
@ -325,6 +334,7 @@ void cBlockInfo::Initialize(void)
|
||||
ms_Info[E_BLOCK_AIR ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_CAKE ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_CARROTS ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_COBWEB ].m_IsSolid = false;
|
||||
ms_Info[E_BLOCK_CROPS ].m_IsSolid = false;
|
||||
|
@ -25,6 +25,13 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual void 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) override
|
||||
{
|
||||
cWindow * Window = new cAnvilWindow(a_BlockX, a_BlockY, a_BlockZ);
|
||||
a_Player->OpenWindow(Window);
|
||||
}
|
||||
|
||||
|
||||
virtual bool GetPlacementBlockTypeMeta(
|
||||
cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
|
||||
|
@ -39,6 +39,13 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Bed specific helper functions
|
||||
static NIBBLETYPE RotationToMetaData(double a_Rotation)
|
||||
{
|
||||
|
@ -35,8 +35,10 @@ public:
|
||||
// Grass becomes dirt if there is something on top of it:
|
||||
if (a_RelY < cChunkDef::Height - 1)
|
||||
{
|
||||
BLOCKTYPE Above = a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ);
|
||||
if ((!cBlockInfo::IsTransparent(Above) && !cBlockInfo::IsOneHitDig(Above)) || IsBlockWater(Above))
|
||||
BLOCKTYPE Above;
|
||||
NIBBLETYPE AboveMeta;
|
||||
a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY + 1, a_RelZ, Above, AboveMeta);
|
||||
if (!cBlockInfo::GetHandler(Above)->CanDirtGrowGrass(AboveMeta))
|
||||
{
|
||||
a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, E_META_DIRT_NORMAL);
|
||||
return;
|
||||
@ -77,7 +79,7 @@ public:
|
||||
BLOCKTYPE AboveDest;
|
||||
NIBBLETYPE AboveMeta;
|
||||
Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta);
|
||||
if ((cBlockInfo::IsOneHitDig(AboveDest) || cBlockInfo::IsTransparent(AboveDest)) && !IsBlockWater(AboveDest))
|
||||
if (cBlockInfo::GetHandler(AboveDest)->CanDirtGrowGrass(AboveMeta))
|
||||
{
|
||||
if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, ssGrassSpread))
|
||||
{
|
||||
|
@ -52,9 +52,9 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
int NumBlocks = Area.GetBlockCount();
|
||||
size_t NumBlocks = Area.GetBlockCount();
|
||||
BLOCKTYPE * BlockTypes = Area.GetBlockTypes();
|
||||
for (int i = 0; i < NumBlocks; i++)
|
||||
for (size_t i = 0; i < NumBlocks; i++)
|
||||
{
|
||||
if (
|
||||
(BlockTypes[i] == E_BLOCK_WATER) ||
|
||||
|
@ -69,7 +69,6 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
for (int newY = Y + 1; newY < cChunkDef::Height; newY++)
|
||||
{
|
||||
BLOCKTYPE Block = a_ChunkInterface.GetBlock(X, newY, Z);
|
||||
@ -84,7 +83,7 @@ public:
|
||||
// This is because the frame is a solid obsidian pillar
|
||||
if ((MaxY != 0) && (newY == Y + 1))
|
||||
{
|
||||
return EvaluatePortalBorder(X, newY, Z, MaxY, a_ChunkInterface);
|
||||
return EvaluatePortalBorder(X, newY, Z, MaxY, a_ChunkInterface) ? -1 /* -1 = found a frame */ : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -99,18 +98,18 @@ public:
|
||||
}
|
||||
|
||||
/// Evaluates if coords have a valid border on top, based on MaxY
|
||||
int EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cChunkInterface & a_ChunkInterface)
|
||||
bool EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cChunkInterface & a_ChunkInterface)
|
||||
{
|
||||
for (int checkBorder = FoundObsidianY + 1; checkBorder <= MaxY - 1; checkBorder++) // FoundObsidianY + 1: FoundObsidianY has already been checked in FindObsidianCeiling; MaxY - 1: portal doesn't need corners
|
||||
{
|
||||
if (a_ChunkInterface.GetBlock(X, checkBorder, Z) != E_BLOCK_OBSIDIAN)
|
||||
{
|
||||
// Base obsidian, base + 1 obsidian, base + x NOT obsidian -> not complete portal
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Everything was obsidian, found a border!
|
||||
return -1; // Return -1 for a frame border
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Finds entire frame in any direction with the coordinates of a base block and fills hole with nether portal (START HERE)
|
||||
@ -169,7 +168,7 @@ public:
|
||||
{
|
||||
return false; // Not valid slice, no portal can be formed
|
||||
}
|
||||
} XZP = X1 - 1; // Set boundary of frame interior, note that for some reason, the loop of X and the loop of Z go to different numbers, hence -1 here and -2 there
|
||||
} XZP = X1 - 1; // Set boundary of frame interior
|
||||
for (; ((a_ChunkInterface.GetBlock(X2, Y, Z) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X2, Y + 1, Z) == E_BLOCK_OBSIDIAN)); X2--) // Go the other direction (XM)
|
||||
{
|
||||
int Value = FindObsidianCeiling(X2, Y, Z, a_ChunkInterface, MaxY);
|
||||
@ -199,13 +198,13 @@ public:
|
||||
if ((Value == -1) || (ValueTwo == -1))
|
||||
{
|
||||
FoundFrameZP = true;
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
else if ((Value != MaxY) && (ValueTwo != MaxY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} XZP = Z1 - 2;
|
||||
} XZP = Z1 - 1;
|
||||
for (; ((a_ChunkInterface.GetBlock(X, Y, Z2) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X, Y + 1, Z2) == E_BLOCK_OBSIDIAN)); Z2--)
|
||||
{
|
||||
int Value = FindObsidianCeiling(X, Y, Z2, a_ChunkInterface, MaxY);
|
||||
@ -213,13 +212,13 @@ public:
|
||||
if ((Value == -1) || (ValueTwo == -1))
|
||||
{
|
||||
FoundFrameZM = true;
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
else if ((Value != MaxY) && (ValueTwo != MaxY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} XZM = Z2 + 2;
|
||||
} XZM = Z2 + 1;
|
||||
return (FoundFrameZP && FoundFrameZM);
|
||||
}
|
||||
};
|
||||
|
@ -49,6 +49,12 @@ public:
|
||||
}
|
||||
super::Check(a_ChunkInterface, a_PluginInterface, a_RelX, a_RelY, a_RelZ, a_Chunk);
|
||||
}
|
||||
|
||||
|
||||
virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -400,6 +400,15 @@ bool cBlockHandler::CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, in
|
||||
|
||||
|
||||
|
||||
bool cBlockHandler::CanDirtGrowGrass(NIBBLETYPE a_Meta)
|
||||
{
|
||||
return ((cBlockInfo::IsTransparent(m_BlockType)) || (cBlockInfo::IsOneHitDig(m_BlockType)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockHandler::IsUseable()
|
||||
{
|
||||
return false;
|
||||
|
@ -86,6 +86,9 @@ public:
|
||||
/// Checks if the block can stay at the specified relative coords in the chunk
|
||||
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk);
|
||||
|
||||
/** Can the dirt under this block grow to grass? */
|
||||
virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta);
|
||||
|
||||
/** Checks if the block can be placed at this point.
|
||||
Default: CanBeAt(...)
|
||||
NOTE: This call doesn't actually place the block
|
||||
|
@ -138,14 +138,14 @@ bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
// Filter the blocks into a {leaves, log, other (air)} set:
|
||||
BLOCKTYPE * Types = a_Area.GetBlockTypes();
|
||||
for (int i = a_Area.GetBlockCount() - 1; i > 0; i--)
|
||||
for (size_t i = a_Area.GetBlockCount() - 1; i > 0; i--)
|
||||
{
|
||||
switch (Types[i])
|
||||
{
|
||||
case E_BLOCK_NEW_LEAVES:
|
||||
case E_BLOCK_NEW_LOG:
|
||||
case E_BLOCK_LEAVES:
|
||||
case E_BLOCK_LOG:
|
||||
case E_BLOCK_NEW_LEAVES:
|
||||
case E_BLOCK_NEW_LOG:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -98,6 +98,12 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
return ((a_Meta & 0x8) != 0);
|
||||
}
|
||||
|
||||
|
||||
/// Returns true if the specified blocktype is one of the slabs handled by this handler
|
||||
static bool IsAnySlabType(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
|
@ -78,6 +78,11 @@ public:
|
||||
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
|
||||
}
|
||||
|
||||
virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static NIBBLETYPE RotationToMetaData(double a_Rotation)
|
||||
{
|
||||
a_Rotation += 90 + 45; // So its not aligned with axis
|
||||
|
@ -689,7 +689,7 @@ void cChunk::ProcessQueuedSetBlocks(void)
|
||||
{
|
||||
if (itr->m_Tick <= CurrTick)
|
||||
{
|
||||
if (itr->m_PreviousType != E_BLOCK_AIR) // PreviousType defaults to -1 if not specified
|
||||
if (itr->m_PreviousType != E_BLOCK_AIR) // PreviousType defaults to 0 if not specified
|
||||
{
|
||||
if (GetBlock(itr->m_RelX, itr->m_RelY, itr->m_RelZ) == itr->m_PreviousType)
|
||||
{
|
||||
@ -1568,6 +1568,24 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT
|
||||
|
||||
|
||||
|
||||
void cChunk::SetMeta(int a_BlockIdx, NIBBLETYPE a_Meta)
|
||||
{
|
||||
if (GetNibble(m_BlockMeta, a_BlockIdx) == a_Meta)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MarkDirty();
|
||||
SetNibble(m_BlockMeta, a_BlockIdx, a_Meta);
|
||||
Vector3i Coords(IndexToCoordinate(a_BlockIdx));
|
||||
|
||||
m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, Coords.x, Coords.y, Coords.z, GetBlock(a_BlockIdx), a_Meta));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cChunk::SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle * a_Client)
|
||||
{
|
||||
|
||||
|
@ -1245,8 +1245,6 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP
|
||||
if ((Chunk != NULL) && Chunk->IsValid())
|
||||
{
|
||||
Chunk->SetMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta);
|
||||
Chunk->MarkDirty();
|
||||
Chunk->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ AString cClientHandle::FormatMessageType(bool ShouldAppendChatPrefixes, eMessage
|
||||
{
|
||||
switch (a_ChatPrefix)
|
||||
{
|
||||
case mtCustom: return AString();
|
||||
case mtCustom: return "";
|
||||
case mtFailure: return FormatChatPrefix(ShouldAppendChatPrefixes, "INFO", cChatColor::Rose, cChatColor::White);
|
||||
case mtInformation: return FormatChatPrefix(ShouldAppendChatPrefixes, "INFO", cChatColor::Yellow, cChatColor::White);
|
||||
case mtSuccess: return FormatChatPrefix(ShouldAppendChatPrefixes, "INFO", cChatColor::Green, cChatColor::White);
|
||||
@ -224,7 +224,7 @@ AString cClientHandle::FormatMessageType(bool ShouldAppendChatPrefixes, eMessage
|
||||
}
|
||||
}
|
||||
ASSERT(!"Unhandled chat prefix type!");
|
||||
return AString();
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@ -633,6 +633,10 @@ void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString
|
||||
// Client <-> Server branding exchange
|
||||
SendPluginMessage("MC|Brand", "MCServer");
|
||||
}
|
||||
else if (a_Channel == "MC|ItemName")
|
||||
{
|
||||
HandleAnvilItemName(a_Message.c_str(), a_Message.size());
|
||||
}
|
||||
else if (a_Channel == "REGISTER")
|
||||
{
|
||||
if (HasPluginChannel(a_Channel))
|
||||
@ -774,6 +778,29 @@ void cClientHandle::HandleCommandBlockMessage(const char * a_Data, size_t a_Leng
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleAnvilItemName(const char * a_Data, size_t a_Length)
|
||||
{
|
||||
if (a_Length < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m_Player->GetWindow() == NULL) || (m_Player->GetWindow()->GetWindowType() != cWindow::wtAnvil))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AString Name(a_Data, a_Length);
|
||||
if (Name.length() <= 30)
|
||||
{
|
||||
((cAnvilWindow *)m_Player->GetWindow())->SetRepairedItemName(Name, m_Player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, char a_Status)
|
||||
{
|
||||
LOGD("HandleLeftClick: {%i, %i, %i}; Face: %i; Stat: %i",
|
||||
|
@ -386,6 +386,9 @@ private:
|
||||
/** Handles the "MC|AdvCdm" plugin message */
|
||||
void HandleCommandBlockMessage(const char * a_Data, size_t a_Length);
|
||||
|
||||
/** Handles the "MC|ItemName" plugin message */
|
||||
void HandleAnvilItemName(const char * a_Data, size_t a_Length);
|
||||
|
||||
// cSocketThreads::cCallback overrides:
|
||||
virtual void DataReceived (const char * a_Data, size_t a_Size) override; // Data is received from the client
|
||||
virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client
|
||||
|
@ -802,7 +802,7 @@ void cCraftingRecipes::HandleFireworks(const cItem * a_CraftingGrid, cCraftingRe
|
||||
break;
|
||||
}
|
||||
case E_ITEM_PAPER: break;
|
||||
default: LOG("Unexpected item in firework rocket a_Recipe, was the crafting file fireworks section changed?"); break;
|
||||
default: LOG("Unexpected item in firework rocket recipe, was the crafting file's fireworks section changed?"); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -837,7 +837,7 @@ void cCraftingRecipes::HandleFireworks(const cItem * a_CraftingGrid, cCraftingRe
|
||||
case E_ITEM_GOLD_NUGGET: a_Recipe->m_Result.m_FireworkItem.m_Type = 2; break;
|
||||
case E_ITEM_FEATHER: a_Recipe->m_Result.m_FireworkItem.m_Type = 4; break;
|
||||
case E_ITEM_HEAD: a_Recipe->m_Result.m_FireworkItem.m_Type = 3; break;
|
||||
default: LOG("Unexpected item in firework star a_Recipe, was the crafting file fireworks section changed?"); break; // ermahgerd BARD ardmins
|
||||
default: LOG("Unexpected item in firework star recipe, was the crafting file's fireworks section changed?"); break; // ermahgerd BARD ardmins
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age)
|
||||
WorldAges::iterator itr = m_WorldAges.find(a_WorldName);
|
||||
if (itr == m_WorldAges.end())
|
||||
{
|
||||
ASSERT(!"Unknown world in cDeadlockDetect");
|
||||
SetWorldAge(a_WorldName, a_Age);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,15 @@ void cEnchantments::AddFromString(const AString & a_StringSpec)
|
||||
|
||||
|
||||
|
||||
size_t cEnchantments::Count(void)
|
||||
{
|
||||
return m_Enchantments.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cEnchantments::ToString(void) const
|
||||
{
|
||||
// Serialize all the enchantments into a string
|
||||
|
@ -84,6 +84,9 @@ public:
|
||||
/** Adds enchantments in the stringspec; if a specified enchantment already exists, overwrites it */
|
||||
void AddFromString(const AString & a_StringSpec);
|
||||
|
||||
/** Get the count of enchantments */
|
||||
size_t Count(void);
|
||||
|
||||
/** Serializes all the enchantments into a string */
|
||||
AString ToString(void) const;
|
||||
|
||||
|
@ -15,6 +15,7 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a
|
||||
m_IsCritical(false),
|
||||
m_Timer(0),
|
||||
m_HitGroundTimer(0),
|
||||
m_HasTeleported(false),
|
||||
m_bIsCollected(false),
|
||||
m_HitBlockPos(Vector3i(0, 0, 0))
|
||||
{
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "Entity.h"
|
||||
@ -10,7 +11,6 @@
|
||||
#include "../Simulator/FluidSimulator.h"
|
||||
#include "../Bindings/PluginManager.h"
|
||||
#include "../Tracer.h"
|
||||
#include "Minecart.h"
|
||||
#include "Player.h"
|
||||
|
||||
|
||||
@ -32,16 +32,10 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
|
||||
, m_Attachee(NULL)
|
||||
, m_bDirtyHead(true)
|
||||
, m_bDirtyOrientation(true)
|
||||
, m_bDirtyPosition(true)
|
||||
, m_bDirtySpeed(true)
|
||||
, m_bOnGround( false )
|
||||
, m_Gravity( -9.81f )
|
||||
, m_LastPosX( 0.0 )
|
||||
, m_LastPosY( 0.0 )
|
||||
, m_LastPosZ( 0.0 )
|
||||
, m_TimeLastTeleportPacket(0)
|
||||
, m_TimeLastMoveReltPacket(0)
|
||||
, m_TimeLastSpeedPacket(0)
|
||||
, m_bHasSentNoSpeed(true)
|
||||
, m_bOnGround(false)
|
||||
, m_Gravity(-9.81f)
|
||||
, m_LastPos(a_X, a_Y, a_Z)
|
||||
, m_IsInitialized(false)
|
||||
, m_EntityType(a_EntityType)
|
||||
, m_World(NULL)
|
||||
@ -55,7 +49,7 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, d
|
||||
, m_IsSubmerged(false)
|
||||
, m_AirLevel(0)
|
||||
, m_AirTickTimer(0)
|
||||
, m_HeadYaw( 0.0 )
|
||||
, m_HeadYaw(0.0)
|
||||
, m_Rot(0.0, 0.0, 0.0)
|
||||
, m_Pos(a_X, a_Y, a_Z)
|
||||
, m_WaterSpeed(0, 0, 0)
|
||||
@ -794,30 +788,43 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
NextSpeed += m_WaterSpeed;
|
||||
|
||||
if( NextSpeed.SqrLength() > 0.f )
|
||||
if (NextSpeed.SqrLength() > 0.f)
|
||||
{
|
||||
cTracer Tracer( GetWorld() );
|
||||
bool HasHit = Tracer.Trace( NextPos, NextSpeed, 2 );
|
||||
if (HasHit) // Oh noez! we hit something
|
||||
cTracer Tracer(GetWorld());
|
||||
// Distance traced is an integer, so we round up from the distance we should go (Speed * Delta), else we will encounter collision detection failurse
|
||||
int DistanceToTrace = (int)(ceil((NextSpeed * a_Dt).SqrLength()) * 2);
|
||||
bool HasHit = Tracer.Trace(NextPos, NextSpeed, DistanceToTrace);
|
||||
|
||||
if (HasHit)
|
||||
{
|
||||
// Set to hit position
|
||||
// Oh noez! We hit something: verify that the (hit position - current) was smaller or equal to the (position that we should travel without obstacles - current)
|
||||
// This is because previously, we traced with a length that was rounded up (due to integer limitations), and in the case that something was hit, we don't want to overshoot our projected movement
|
||||
if ((Tracer.RealHit - NextPos).SqrLength() <= (NextSpeed * a_Dt).SqrLength())
|
||||
{
|
||||
// Block hit was within our projected path
|
||||
// Begin by stopping movement in the direction that we hit something. The Normal is the line perpendicular to a 2D face and in this case, stores what block face was hit through either -1 or 1.
|
||||
// For example: HitNormal.y = -1 : BLOCK_FACE_YM; HitNormal.y = 1 : BLOCK_FACE_YP
|
||||
if (Tracer.HitNormal.x != 0.f) NextSpeed.x = 0.f;
|
||||
if (Tracer.HitNormal.y != 0.f) NextSpeed.y = 0.f;
|
||||
if (Tracer.HitNormal.z != 0.f) NextSpeed.z = 0.f;
|
||||
|
||||
if (Tracer.HitNormal.y > 0) // means on ground
|
||||
if (Tracer.HitNormal.y == 1) // Hit BLOCK_FACE_YP, we are on the ground
|
||||
{
|
||||
m_bOnGround = true;
|
||||
}
|
||||
NextPos.Set(Tracer.RealHit.x,Tracer.RealHit.y,Tracer.RealHit.z);
|
||||
NextPos.x += Tracer.HitNormal.x * 0.3f;
|
||||
NextPos.y += Tracer.HitNormal.y * 0.05f; // Any larger produces entity vibration-upon-the-spot
|
||||
NextPos.z += Tracer.HitNormal.z * 0.3f;
|
||||
|
||||
// Now, set our position to the hit block (i.e. move part way along our intended trajectory)
|
||||
NextPos.Set(Tracer.RealHit.x, Tracer.RealHit.y, Tracer.RealHit.z);
|
||||
NextPos.x += Tracer.HitNormal.x * 0.1;
|
||||
NextPos.y += Tracer.HitNormal.y * 0.05;
|
||||
NextPos.z += Tracer.HitNormal.z * 0.1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have hit a block but overshot our intended trajectory, move normally, safe in the warm cocoon of knowledge that we won't appear to teleport forwards on clients,
|
||||
// and that this piece of software will come to be hailed as the epitome of performance and functionality in C++, never before seen, and of such a like that will never
|
||||
// be henceforth seen again in the time of programmers and man alike
|
||||
// </&sensationalist>
|
||||
NextPos += (NextSpeed * a_Dt);
|
||||
}
|
||||
}
|
||||
@ -1010,8 +1017,8 @@ void cEntity::SetSwimState(cChunk & a_Chunk)
|
||||
{
|
||||
// This sometimes happens on Linux machines
|
||||
// Ref.: http://forum.mc-server.org/showthread.php?tid=1244
|
||||
LOGD("SetSwimState failure: RelX = %d, RelZ = %d, LastPos = {%.02f, %.02f}, Pos = %.02f, %.02f}",
|
||||
RelX, RelY, m_LastPosX, m_LastPosZ, GetPosX(), GetPosZ()
|
||||
LOGD("SetSwimState failure: RelX = %d, RelZ = %d, Pos = %.02f, %.02f}",
|
||||
RelX, RelY, GetPosX(), GetPosZ()
|
||||
);
|
||||
m_IsSwimming = false;
|
||||
m_IsSubmerged = false;
|
||||
@ -1178,72 +1185,70 @@ void cEntity::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
|
||||
|
||||
void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
|
||||
{
|
||||
// Send velocity packet every two ticks if: speed is not negligible or speed was set (as indicated by the DirtySpeed flag)
|
||||
if (((m_Speed.SqrLength() > 0.0004f) || m_bDirtySpeed) && ((m_World->GetWorldAge() - m_TimeLastSpeedPacket) >= 2))
|
||||
// Process packet sending every two ticks
|
||||
if (GetWorld()->GetWorldAge() % 2 == 0)
|
||||
{
|
||||
m_World->BroadcastEntityVelocity(*this,a_Exclude);
|
||||
m_bDirtySpeed = false;
|
||||
m_TimeLastSpeedPacket = m_World->GetWorldAge();
|
||||
double SpeedSqr = GetSpeed().SqrLength();
|
||||
if (SpeedSqr == 0.0)
|
||||
{
|
||||
// Speed is zero, send this to clients once only as well as an absolute position
|
||||
if (!m_bHasSentNoSpeed)
|
||||
{
|
||||
m_World->BroadcastEntityVelocity(*this, a_Exclude);
|
||||
m_World->BroadcastTeleportEntity(*this, a_Exclude);
|
||||
m_bHasSentNoSpeed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Movin'
|
||||
m_World->BroadcastEntityVelocity(*this, a_Exclude);
|
||||
m_bHasSentNoSpeed = false;
|
||||
}
|
||||
|
||||
// Have to process position related packets this every two ticks
|
||||
if (m_World->GetWorldAge() % 2 == 0)
|
||||
// TODO: Pickups move disgracefully if relative move packets are sent as opposed to just velocity. Have a system to send relmove only when SetPosXXX() is called with a large difference in position
|
||||
int DiffX = (int)(floor(GetPosX() * 32.0) - floor(m_LastPos.x * 32.0));
|
||||
int DiffY = (int)(floor(GetPosY() * 32.0) - floor(m_LastPos.y * 32.0));
|
||||
int DiffZ = (int)(floor(GetPosZ() * 32.0) - floor(m_LastPos.z * 32.0));
|
||||
|
||||
if ((DiffX != 0) || (DiffY != 0) || (DiffZ != 0)) // Have we moved?
|
||||
{
|
||||
int DiffX = (int) (floor(GetPosX() * 32.0) - floor(m_LastPosX * 32.0));
|
||||
int DiffY = (int) (floor(GetPosY() * 32.0) - floor(m_LastPosY * 32.0));
|
||||
int DiffZ = (int) (floor(GetPosZ() * 32.0) - floor(m_LastPosZ * 32.0));
|
||||
Int64 DiffTeleportPacket = m_World->GetWorldAge() - m_TimeLastTeleportPacket;
|
||||
// 4 blocks is max Relative So if the Diff is greater than 127 or. Send an absolute position every 20 seconds
|
||||
if (DiffTeleportPacket >= 400 ||
|
||||
((DiffX > 127) || (DiffX < -128) ||
|
||||
(DiffY > 127) || (DiffY < -128) ||
|
||||
(DiffZ > 127) || (DiffZ < -128)))
|
||||
{
|
||||
//
|
||||
m_World->BroadcastTeleportEntity(*this,a_Exclude);
|
||||
m_TimeLastTeleportPacket = m_World->GetWorldAge();
|
||||
m_TimeLastMoveReltPacket = m_TimeLastTeleportPacket; //Must synchronize.
|
||||
m_LastPosX = GetPosX();
|
||||
m_LastPosY = GetPosY();
|
||||
m_LastPosZ = GetPosZ();
|
||||
m_bDirtyPosition = false;
|
||||
m_bDirtyOrientation = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Int64 DiffMoveRelPacket = m_World->GetWorldAge() - m_TimeLastMoveReltPacket;
|
||||
//if the change is big enough.
|
||||
if ((abs(DiffX) >= 4 || abs(DiffY) >= 4 || abs(DiffZ) >= 4 || DiffMoveRelPacket >= 60) && m_bDirtyPosition)
|
||||
if ((abs(DiffX) <= 127) && (abs(DiffY) <= 127) && (abs(DiffZ) <= 127)) // Limitations of a Byte
|
||||
{
|
||||
// Difference within Byte limitations, use a relative move packet
|
||||
if (m_bDirtyOrientation)
|
||||
{
|
||||
m_World->BroadcastEntityRelMoveLook(*this, (char)DiffX, (char)DiffY, (char)DiffZ,a_Exclude);
|
||||
m_World->BroadcastEntityRelMoveLook(*this, (char)DiffX, (char)DiffY, (char)DiffZ, a_Exclude);
|
||||
m_bDirtyOrientation = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_World->BroadcastEntityRelMove(*this, (char)DiffX, (char)DiffY, (char)DiffZ,a_Exclude);
|
||||
m_World->BroadcastEntityRelMove(*this, (char)DiffX, (char)DiffY, (char)DiffZ, a_Exclude);
|
||||
}
|
||||
m_LastPosX = GetPosX();
|
||||
m_LastPosY = GetPosY();
|
||||
m_LastPosZ = GetPosZ();
|
||||
m_bDirtyPosition = false;
|
||||
m_TimeLastMoveReltPacket = m_World->GetWorldAge();
|
||||
// Clients seem to store two positions, one for the velocity packet and one for the teleport/relmove packet
|
||||
// The latter is only changed with a relmove/teleport, and m_LastPos stores this position
|
||||
m_LastPos = GetPosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bDirtyOrientation)
|
||||
{
|
||||
m_World->BroadcastEntityLook(*this,a_Exclude);
|
||||
// Too big a movement, do a teleport
|
||||
m_World->BroadcastTeleportEntity(*this, a_Exclude);
|
||||
m_LastPos = GetPosition(); // See above
|
||||
m_bDirtyOrientation = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bDirtyHead)
|
||||
{
|
||||
m_World->BroadcastEntityHeadLook(*this,a_Exclude);
|
||||
m_World->BroadcastEntityHeadLook(*this, a_Exclude);
|
||||
m_bDirtyHead = false;
|
||||
}
|
||||
if (m_bDirtyOrientation)
|
||||
{
|
||||
// Send individual update in case above (sending with rel-move packet) wasn't done
|
||||
GetWorld()->BroadcastEntityLook(*this, a_Exclude);
|
||||
m_bDirtyOrientation = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1383,7 +1388,7 @@ void cEntity::SetRoll(double a_Roll)
|
||||
void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
|
||||
{
|
||||
m_Speed.Set(a_SpeedX, a_SpeedY, a_SpeedZ);
|
||||
m_bDirtySpeed = true;
|
||||
|
||||
WrapSpeed();
|
||||
}
|
||||
|
||||
@ -1393,7 +1398,7 @@ void cEntity::SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
|
||||
void cEntity::SetSpeedX(double a_SpeedX)
|
||||
{
|
||||
m_Speed.x = a_SpeedX;
|
||||
m_bDirtySpeed = true;
|
||||
|
||||
WrapSpeed();
|
||||
}
|
||||
|
||||
@ -1403,7 +1408,7 @@ void cEntity::SetSpeedX(double a_SpeedX)
|
||||
void cEntity::SetSpeedY(double a_SpeedY)
|
||||
{
|
||||
m_Speed.y = a_SpeedY;
|
||||
m_bDirtySpeed = true;
|
||||
|
||||
WrapSpeed();
|
||||
}
|
||||
|
||||
@ -1413,7 +1418,7 @@ void cEntity::SetSpeedY(double a_SpeedY)
|
||||
void cEntity::SetSpeedZ(double a_SpeedZ)
|
||||
{
|
||||
m_Speed.z = a_SpeedZ;
|
||||
m_bDirtySpeed = true;
|
||||
|
||||
WrapSpeed();
|
||||
}
|
||||
|
||||
@ -1433,7 +1438,7 @@ void cEntity::SetWidth(double a_Width)
|
||||
void cEntity::AddPosX(double a_AddPosX)
|
||||
{
|
||||
m_Pos.x += a_AddPosX;
|
||||
m_bDirtyPosition = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1442,7 +1447,7 @@ void cEntity::AddPosX(double a_AddPosX)
|
||||
void cEntity::AddPosY(double a_AddPosY)
|
||||
{
|
||||
m_Pos.y += a_AddPosY;
|
||||
m_bDirtyPosition = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1451,7 +1456,7 @@ void cEntity::AddPosY(double a_AddPosY)
|
||||
void cEntity::AddPosZ(double a_AddPosZ)
|
||||
{
|
||||
m_Pos.z += a_AddPosZ;
|
||||
m_bDirtyPosition = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1462,7 +1467,7 @@ void cEntity::AddPosition(double a_AddPosX, double a_AddPosY, double a_AddPosZ)
|
||||
m_Pos.x += a_AddPosX;
|
||||
m_Pos.y += a_AddPosY;
|
||||
m_Pos.z += a_AddPosZ;
|
||||
m_bDirtyPosition = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1473,7 +1478,6 @@ void cEntity::AddSpeed(double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeed
|
||||
m_Speed.x += a_AddSpeedX;
|
||||
m_Speed.y += a_AddSpeedY;
|
||||
m_Speed.z += a_AddSpeedZ;
|
||||
m_bDirtySpeed = true;
|
||||
WrapSpeed();
|
||||
}
|
||||
|
||||
@ -1484,7 +1488,6 @@ void cEntity::AddSpeed(double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeed
|
||||
void cEntity::AddSpeedX(double a_AddSpeedX)
|
||||
{
|
||||
m_Speed.x += a_AddSpeedX;
|
||||
m_bDirtySpeed = true;
|
||||
WrapSpeed();
|
||||
}
|
||||
|
||||
@ -1495,7 +1498,6 @@ void cEntity::AddSpeedX(double a_AddSpeedX)
|
||||
void cEntity::AddSpeedY(double a_AddSpeedY)
|
||||
{
|
||||
m_Speed.y += a_AddSpeedY;
|
||||
m_bDirtySpeed = true;
|
||||
WrapSpeed();
|
||||
}
|
||||
|
||||
@ -1506,7 +1508,6 @@ void cEntity::AddSpeedY(double a_AddSpeedY)
|
||||
void cEntity::AddSpeedZ(double a_AddSpeedZ)
|
||||
{
|
||||
m_Speed.z += a_AddSpeedZ;
|
||||
m_bDirtySpeed = true;
|
||||
WrapSpeed();
|
||||
}
|
||||
|
||||
@ -1562,7 +1563,6 @@ Vector3d cEntity::GetLookVector(void) const
|
||||
void cEntity::SetPosition(double a_PosX, double a_PosY, double a_PosZ)
|
||||
{
|
||||
m_Pos.Set(a_PosX, a_PosY, a_PosZ);
|
||||
m_bDirtyPosition = true;
|
||||
}
|
||||
|
||||
|
||||
@ -1572,7 +1572,6 @@ void cEntity::SetPosition(double a_PosX, double a_PosY, double a_PosZ)
|
||||
void cEntity::SetPosX(double a_PosX)
|
||||
{
|
||||
m_Pos.x = a_PosX;
|
||||
m_bDirtyPosition = true;
|
||||
}
|
||||
|
||||
|
||||
@ -1582,7 +1581,6 @@ void cEntity::SetPosX(double a_PosX)
|
||||
void cEntity::SetPosY(double a_PosY)
|
||||
{
|
||||
m_Pos.y = a_PosY;
|
||||
m_bDirtyPosition = true;
|
||||
}
|
||||
|
||||
|
||||
@ -1592,7 +1590,6 @@ void cEntity::SetPosY(double a_PosY)
|
||||
void cEntity::SetPosZ(double a_PosZ)
|
||||
{
|
||||
m_Pos.z = a_PosZ;
|
||||
m_bDirtyPosition = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -430,22 +430,29 @@ protected:
|
||||
/// The entity which is attached to this entity (rider), NULL if none
|
||||
cEntity * m_Attachee;
|
||||
|
||||
// Flags that signal that we haven't updated the clients with the latest.
|
||||
/** Stores whether head yaw has been set manually */
|
||||
bool m_bDirtyHead;
|
||||
bool m_bDirtyOrientation;
|
||||
bool m_bDirtyPosition;
|
||||
bool m_bDirtySpeed;
|
||||
|
||||
/** Stores whether our yaw/pitch/roll (body orientation) has been set manually */
|
||||
bool m_bDirtyOrientation;
|
||||
|
||||
/** Stores whether we have sent a Velocity packet with a speed of zero (no speed) to the client
|
||||
Ensures that said packet is sent only once */
|
||||
bool m_bHasSentNoSpeed;
|
||||
|
||||
/** Stores if the entity is on the ground */
|
||||
bool m_bOnGround;
|
||||
|
||||
/** Stores gravity that is applied to an entity every tick
|
||||
For realistic effects, this should be negative. For spaaaaaaace, this can be zero or even positive */
|
||||
float m_Gravity;
|
||||
|
||||
// Last Position.
|
||||
double m_LastPosX, m_LastPosY, m_LastPosZ;
|
||||
/** Last position sent to client via the Relative Move or Teleport packets (not Velocity)
|
||||
Only updated if cEntity::BroadcastMovementUpdate() is called! */
|
||||
Vector3d m_LastPos;
|
||||
|
||||
// This variables keep track of the last time a packet was sent
|
||||
Int64 m_TimeLastTeleportPacket, m_TimeLastMoveReltPacket, m_TimeLastSpeedPacket; // In ticks
|
||||
|
||||
bool m_IsInitialized; // Is set to true when it's initialized, until it's destroyed (Initialize() till Destroy() )
|
||||
/** True when entity is initialised (Initialize()) and false when destroyed pending deletion (Destroy()) */
|
||||
bool m_IsInitialized;
|
||||
|
||||
eEntityType m_EntityType;
|
||||
|
||||
@ -469,12 +476,14 @@ protected:
|
||||
/// Time, in ticks, since the last damage dealt by the void. Reset to zero when moving out of the void.
|
||||
int m_TicksSinceLastVoidDamage;
|
||||
|
||||
|
||||
virtual void Destroyed(void) {} // Called after the entity has been destroyed
|
||||
|
||||
void SetWorld(cWorld * a_World) { m_World = a_World; }
|
||||
|
||||
/** Called in each tick to handle air-related processing i.e. drowning */
|
||||
virtual void HandleAir();
|
||||
|
||||
/** Called once per tick to set IsSwimming and IsSubmerged */
|
||||
virtual void SetSwimState(cChunk & a_Chunk);
|
||||
|
||||
|
@ -34,8 +34,6 @@ cExpOrb::cExpOrb(const Vector3d & a_Pos, int a_Reward)
|
||||
void cExpOrb::SpawnOn(cClientHandle & a_Client)
|
||||
{
|
||||
a_Client.SendExperienceOrb(*this);
|
||||
m_bDirtyPosition = false;
|
||||
m_bDirtySpeed = false;
|
||||
m_bDirtyOrientation = false;
|
||||
m_bDirtyHead = false;
|
||||
}
|
||||
|
@ -86,9 +86,8 @@ void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
AddSpeedY(MilliDt * -9.8f);
|
||||
AddPosition(GetSpeed() * MilliDt);
|
||||
|
||||
// If not static (One billionth precision) broadcast movement.
|
||||
static const float epsilon = 0.000000001f;
|
||||
if ((fabs(GetSpeedX()) > epsilon) || (fabs(GetSpeedZ()) > epsilon))
|
||||
// If not static (one billionth precision) broadcast movement
|
||||
if ((fabs(GetSpeedX()) > std::numeric_limits<double>::epsilon()) || (fabs(GetSpeedZ()) > std::numeric_limits<double>::epsilon()))
|
||||
{
|
||||
BroadcastMovementUpdate();
|
||||
}
|
||||
|
@ -77,10 +77,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
|
||||
cTimer t1;
|
||||
m_LastPlayerListTime = t1.GetNowTime();
|
||||
|
||||
m_TimeLastTeleportPacket = 0;
|
||||
|
||||
m_PlayerName = a_PlayerName;
|
||||
m_bDirtyPosition = true; // So chunks are streamed to player at spawn
|
||||
|
||||
if (!LoadFromDisk())
|
||||
{
|
||||
@ -209,25 +206,22 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
m_BowCharge += 1;
|
||||
}
|
||||
|
||||
//handle updating experience
|
||||
// Handle updating experience
|
||||
if (m_bDirtyExperience)
|
||||
{
|
||||
SendExperience();
|
||||
}
|
||||
|
||||
if (m_bDirtyPosition)
|
||||
if (GetPosition() != m_LastPos) // Change in position from last tick?
|
||||
{
|
||||
// Apply food exhaustion from movement:
|
||||
ApplyFoodExhaustionFromMovement();
|
||||
|
||||
cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this);
|
||||
BroadcastMovementUpdate(m_ClientHandle);
|
||||
m_ClientHandle->StreamChunks();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
BroadcastMovementUpdate(m_ClientHandle);
|
||||
}
|
||||
|
||||
if (m_Health > 0) // make sure player is alive
|
||||
{
|
||||
@ -1596,10 +1590,7 @@ bool cPlayer::LoadFromDisk()
|
||||
SetPosX(JSON_PlayerPosition[(unsigned int)0].asDouble());
|
||||
SetPosY(JSON_PlayerPosition[(unsigned int)1].asDouble());
|
||||
SetPosZ(JSON_PlayerPosition[(unsigned int)2].asDouble());
|
||||
m_LastPosX = GetPosX();
|
||||
m_LastPosY = GetPosY();
|
||||
m_LastPosZ = GetPosZ();
|
||||
m_LastFoodPos = GetPosition();
|
||||
m_LastPos = GetPosition();
|
||||
}
|
||||
|
||||
Json::Value & JSON_PlayerRotation = root["rotation"];
|
||||
@ -1861,17 +1852,16 @@ void cPlayer::ApplyFoodExhaustionFromMovement()
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the distance travelled, update the last pos:
|
||||
Vector3d Movement(GetPosition() - m_LastFoodPos);
|
||||
Movement.y = 0; // Only take XZ movement into account
|
||||
m_LastFoodPos = GetPosition();
|
||||
|
||||
// If riding anything, apply no food exhaustion
|
||||
if (m_AttachedTo != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the distance travelled, update the last pos:
|
||||
Vector3d Movement(GetPosition() - m_LastPos);
|
||||
Movement.y = 0; // Only take XZ movement into account
|
||||
|
||||
// Apply the exhaustion based on distance travelled:
|
||||
double BaseExhaustion = Movement.Length();
|
||||
if (IsSprinting())
|
||||
|
@ -423,9 +423,6 @@ protected:
|
||||
/** Number of ticks remaining for the foodpoisoning effect; zero if not foodpoisoned */
|
||||
int m_FoodPoisonedTicksRemaining;
|
||||
|
||||
/** Last position that has been recorded for food-related processing: */
|
||||
Vector3d m_LastFoodPos;
|
||||
|
||||
float m_LastJumpHeight;
|
||||
float m_LastGroundHeight;
|
||||
bool m_bTouchGround;
|
||||
|
@ -30,8 +30,6 @@ cTNTEntity::cTNTEntity(const Vector3d & a_Pos, int a_FuseTicks) :
|
||||
void cTNTEntity::SpawnOn(cClientHandle & a_ClientHandle)
|
||||
{
|
||||
a_ClientHandle.SendSpawnObject(*this, 50, 1, 0, 0); // 50 means TNT
|
||||
m_bDirtyPosition = false;
|
||||
m_bDirtySpeed = false;
|
||||
m_bDirtyOrientation = false;
|
||||
m_bDirtyHead = false;
|
||||
}
|
||||
|
@ -239,9 +239,15 @@ void cCaveTunnel::Randomize(cNoise & a_Noise)
|
||||
|
||||
bool cCaveTunnel::RefineDefPoints(const cCaveDefPoints & a_Src, cCaveDefPoints & a_Dst)
|
||||
{
|
||||
if (a_Src.size() < 2)
|
||||
{
|
||||
// There are no midpoints, nothing to smooth
|
||||
return true;
|
||||
}
|
||||
|
||||
// Smoothing: for each line segment, add points on its 1/4 lengths
|
||||
bool res = false;
|
||||
int Num = a_Src.size() - 2; // this many intermediary points
|
||||
size_t Num = a_Src.size() - 2; // this many intermediary points
|
||||
a_Dst.clear();
|
||||
a_Dst.reserve(Num * 2 + 2);
|
||||
cCaveDefPoints::const_iterator itr = a_Src.begin() + 1;
|
||||
@ -251,7 +257,7 @@ bool cCaveTunnel::RefineDefPoints(const cCaveDefPoints & a_Src, cCaveDefPoints &
|
||||
int PrevY = Source.m_BlockY;
|
||||
int PrevZ = Source.m_BlockZ;
|
||||
int PrevR = Source.m_Radius;
|
||||
for (int i = 0; i <= Num; ++i, ++itr)
|
||||
for (size_t i = 0; i <= Num; ++i, ++itr)
|
||||
{
|
||||
int dx = itr->m_BlockX - PrevX;
|
||||
int dy = itr->m_BlockY - PrevY;
|
||||
|
@ -543,7 +543,7 @@ cMineShaft * cMineShaftCorridor::CreateAndFit(
|
||||
{
|
||||
cCuboid BoundingBox(a_PivotX, a_PivotY - 1, a_PivotZ);
|
||||
BoundingBox.p2.y += 3;
|
||||
int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
|
||||
int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + (int)a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
|
||||
int NumSegments = 2 + (rnd) % (MAX_SEGMENTS - 1); // 2 .. MAX_SEGMENTS
|
||||
switch (a_Direction)
|
||||
{
|
||||
@ -985,7 +985,7 @@ cMineShaft * cMineShaftCrossing::CreateAndFit(
|
||||
)
|
||||
{
|
||||
cCuboid BoundingBox(a_PivotX, a_PivotY - 1, a_PivotZ);
|
||||
int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
|
||||
int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + (int)a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
|
||||
BoundingBox.p2.y += 3;
|
||||
if ((rnd % 4) < 2)
|
||||
{
|
||||
@ -1127,7 +1127,7 @@ cMineShaft * cMineShaftStaircase::CreateAndFit(
|
||||
cNoise & a_Noise
|
||||
)
|
||||
{
|
||||
int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
|
||||
int rnd = a_Noise.IntNoise3DInt(a_PivotX, a_PivotY + (int)a_ParentSystem.m_MineShafts.size(), a_PivotZ) / 7;
|
||||
cCuboid Box;
|
||||
switch (a_Direction)
|
||||
{
|
||||
|
@ -339,9 +339,9 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, i
|
||||
int NumRotations = 1;
|
||||
for (size_t i = 1; i < ARRAYCOUNT(Rotations); i++)
|
||||
{
|
||||
if (StartingPiece->CanRotateCCW(i))
|
||||
if (StartingPiece->CanRotateCCW((int)i))
|
||||
{
|
||||
Rotations[NumRotations] = i;
|
||||
Rotations[NumRotations] = (int)i;
|
||||
NumRotations += 1;
|
||||
}
|
||||
}
|
||||
@ -388,7 +388,8 @@ bool cPieceGenerator::TryPlacePieceAtConnector(
|
||||
// Get a list of available connections:
|
||||
const int * RotTable = DirectionRotationTable[a_Connector.m_Direction];
|
||||
cConnections Connections;
|
||||
cPieces AvailablePieces = m_PiecePool.GetPiecesWithConnector(a_Connector.m_Type);
|
||||
int WantedConnectorType = -a_Connector.m_Type;
|
||||
cPieces AvailablePieces = m_PiecePool.GetPiecesWithConnector(WantedConnectorType);
|
||||
Connections.reserve(AvailablePieces.size());
|
||||
Vector3i ConnPos = a_Connector.m_Pos; // The position at which the new connector should be placed - 1 block away from the connector
|
||||
AddFaceDirection(ConnPos.x, ConnPos.y, ConnPos.z, a_Connector.m_Direction);
|
||||
@ -406,7 +407,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector(
|
||||
cPiece::cConnectors Connectors = (*itrP)->GetConnectors();
|
||||
for (cPiece::cConnectors::iterator itrC = Connectors.begin(), endC = Connectors.end(); itrC != endC; ++itrC)
|
||||
{
|
||||
if (itrC->m_Type != a_Connector.m_Type)
|
||||
if (itrC->m_Type != WantedConnectorType)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -38,7 +38,8 @@ public:
|
||||
/** Position relative to the piece */
|
||||
Vector3i m_Pos;
|
||||
|
||||
/** Type of the connector. Any arbitrary number; the generator connects only connectors of the same type. */
|
||||
/** Type of the connector. Any arbitrary number; the generator connects only connectors of opposite
|
||||
(negative) types. */
|
||||
int m_Type;
|
||||
|
||||
/** Direction in which the connector is facing.
|
||||
|
@ -174,6 +174,8 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const
|
||||
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 (m_ShouldExtendFloor)
|
||||
{
|
||||
int MaxX = Image.GetSizeX();
|
||||
int MaxZ = Image.GetSizeZ();
|
||||
for (int z = 0; z < MaxZ; z++)
|
||||
@ -212,6 +214,7 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const
|
||||
} // for y
|
||||
} // for x
|
||||
} // for z
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -134,7 +134,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 12, 2, 2: 5\n" /* Type 1, direction X+ */
|
||||
"1: 0, 2, 2: 4\n" /* Type 1, direction X- */,
|
||||
"1: 0, 2, 2: 4\n" /* Type 1, direction X- */
|
||||
"-1: 12, 2, 2: 5\n" /* Type -1, direction X+ */
|
||||
"-1: 0, 2, 2: 4\n" /* Type -1, direction X- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -143,7 +145,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
20,
|
||||
@ -291,7 +293,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
// Connectors:
|
||||
"1: 12, 2, 4: 5\n" /* Type 1, direction X+ */
|
||||
"1: 6, 2, 0: 2\n" /* Type 1, direction Z- */
|
||||
"1: 0, 2, 4: 4\n" /* Type 1, direction X- */,
|
||||
"1: 0, 2, 4: 4\n" /* Type 1, direction X- */
|
||||
"-1: 12, 2, 4: 5\n" /* Type -1, direction X+ */
|
||||
"-1: 6, 2, 0: 2\n" /* Type -1, direction Z- */
|
||||
"-1: 0, 2, 4: 4\n" /* Type -1, direction X- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -300,7 +305,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
20,
|
||||
@ -420,7 +425,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -590,7 +595,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -790,7 +795,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
5,
|
||||
@ -991,7 +996,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
10,
|
||||
@ -1085,7 +1090,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -1185,7 +1190,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -1208,7 +1213,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Hitbox (relative to bounding box):
|
||||
0, 0, 0, // MinX, MinY, MinZ
|
||||
4, 6, 15, // MaxX, MaxY, MaxZ
|
||||
4, 16, 15, // MaxX, MaxY, MaxZ
|
||||
|
||||
// Block definitions:
|
||||
".: 0: 0\n" /* air */
|
||||
@ -1364,7 +1369,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
10,
|
||||
@ -1604,7 +1609,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
5,
|
||||
@ -1933,7 +1938,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
20,
|
||||
@ -2052,7 +2057,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
500,
|
||||
@ -2212,7 +2217,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
10,
|
||||
@ -2302,7 +2307,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 10, 1, 2: 5\n" /* Type 1, direction X+ */
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
|
||||
"-1: 10, 1, 2: 5\n" /* Type -1, direction X+ */
|
||||
"-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -2311,7 +2318,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
300,
|
||||
@ -2401,7 +2408,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 12, 1, 2: 5\n" /* Type 1, direction X+ */
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
|
||||
"-1: 12, 1, 2: 5\n" /* Type -1, direction X+ */
|
||||
"-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -2410,7 +2419,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
300,
|
||||
@ -2494,7 +2503,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 4, 1, 2: 5\n" /* Type 1, direction X+ */
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
|
||||
"-1: 4, 1, 2: 5\n" /* Type -1, direction X+ */
|
||||
"-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -2503,7 +2514,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
500,
|
||||
@ -2631,7 +2642,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 2, 1, 10: 3\n" /* Type 1, direction Z+ */
|
||||
"1: 10, 1, 2: 5\n" /* Type 1, direction X+ */,
|
||||
"1: 10, 1, 2: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 2, 1, 10: 3\n" /* Type -1, direction Z+ */
|
||||
"-1: 10, 1, 2: 5\n" /* Type -1, direction X+ */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -2640,7 +2653,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -2769,7 +2782,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 10, 1, 2: 5\n" /* Type 1, direction X+ */
|
||||
"1: 2, 1, 10: 3\n" /* Type 1, direction Z+ */,
|
||||
"1: 2, 1, 10: 3\n" /* Type 1, direction Z+ */
|
||||
"-1: 2, 1, 10: 3\n" /* Type -1, direction Z+ */
|
||||
"-1: 10, 1, 2: 5\n" /* Type -1, direction X+ */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -2778,7 +2793,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -2890,7 +2905,11 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
"1: 8, 1, 4: 5\n" /* Type 1, direction X+ */
|
||||
"1: 4, 1, 0: 2\n" /* Type 1, direction Z- */
|
||||
"1: 4, 1, 8: 3\n" /* Type 1, direction Z+ */
|
||||
"1: 0, 1, 4: 4\n" /* Type 1, direction X- */,
|
||||
"1: 0, 1, 4: 4\n" /* Type 1, direction X- */
|
||||
"-1: 8, 1, 4: 5\n" /* Type -1, direction X+ */
|
||||
"-1: 4, 1, 8: 3\n" /* Type -1, direction Z+ */
|
||||
"-1: 0, 1, 4: 4\n" /* Type -1, direction X- */
|
||||
"-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -2899,7 +2918,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -3040,7 +3059,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
|
||||
"1: 8, 8, 2: 5\n" /* Type 1, direction X+ */,
|
||||
"1: 8, 8, 2: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 0, 1, 2: 4\n" /* Type -1, direction X- */
|
||||
"-1: 8, 8, 2: 5\n" /* Type -1, direction X+ */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -3049,7 +3070,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
1000,
|
||||
@ -3139,7 +3160,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
|
||||
"1: 13, 1, 2: 5\n" /* Type 1, direction X+ */,
|
||||
"1: 13, 1, 2: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 0, 1, 2: 4\n" /* Type -1, direction X- */
|
||||
"-1: 13, 1, 2: 5\n" /* Type -1, direction X+ */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -3148,7 +3171,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -3393,7 +3416,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
// Connectors:
|
||||
"1: 0, 6, 7: 4\n" /* Type 1, direction X- */
|
||||
"1: 9, 1, 14: 3\n" /* Type 1, direction Z+ */
|
||||
"1: 9, 1, 0: 2\n" /* Type 1, direction Z- */,
|
||||
"1: 9, 1, 0: 2\n" /* Type 1, direction Z- */
|
||||
"-1: 0, 6, 7: 4\n" /* Type -1, direction X- */
|
||||
"-1: 9, 1, 14: 3\n" /* Type -1, direction Z+ */
|
||||
"-1: 9, 1, 0: 2\n" /* Type -1, direction Z- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -3402,7 +3428,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
10,
|
||||
@ -3722,7 +3748,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 11, 1, 7: 5\n" /* Type 1, direction X+ */
|
||||
"1: 0, 9, 7: 4\n" /* Type 1, direction X- */,
|
||||
"1: 0, 9, 7: 4\n" /* Type 1, direction X- */
|
||||
"-1: 11, 1, 7: 5\n" /* Type -1, direction X+ */
|
||||
"-1: 0, 9, 7: 4\n" /* Type -1, direction X- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -3731,7 +3759,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
10,
|
||||
@ -4009,7 +4037,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
10,
|
||||
@ -4186,7 +4214,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 12, 1, 6: 5\n" /* Type 1, direction X+ */
|
||||
"1: 0, 1, 6: 4\n" /* Type 1, direction X- */,
|
||||
"1: 0, 1, 6: 4\n" /* Type 1, direction X- */
|
||||
"-1: 12, 1, 6: 5\n" /* Type -1, direction X+ */
|
||||
"-1: 0, 1, 6: 4\n" /* Type -1, direction X- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -4195,7 +4225,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -4338,7 +4368,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -4481,7 +4511,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -4586,7 +4616,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
// Connectors:
|
||||
"1: 0, 1, 4: 4\n" /* Type 1, direction X- */
|
||||
"1: 6, 1, 0: 2\n" /* Type 1, direction Z- */
|
||||
"1: 12, 1, 4: 5\n" /* Type 1, direction X+ */,
|
||||
"1: 12, 1, 4: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 0, 1, 4: 4\n" /* Type -1, direction X- */
|
||||
"-1: 12, 1, 4: 5\n" /* Type -1, direction X+ */
|
||||
"-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -4595,7 +4628,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -4712,7 +4745,10 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
// Connectors:
|
||||
"1: 0, 1, 6: 4\n" /* Type 1, direction X- */
|
||||
"1: 6, 1, 0: 2\n" /* Type 1, direction Z- */
|
||||
"1: 12, 1, 6: 5\n" /* Type 1, direction X+ */,
|
||||
"1: 12, 1, 6: 5\n" /* Type 1, direction X+ */
|
||||
"-1: 0, 1, 6: 4\n" /* Type -1, direction X- */
|
||||
"-1: 6, 1, 0: 2\n" /* Type -1, direction Z- */
|
||||
"-1: 12, 1, 6: 5\n" /* Type -1, direction X+ */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -4721,7 +4757,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -4806,7 +4842,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 2, 1, 4: 3\n" /* Type 1, direction Z+ */
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
|
||||
"-1: 2, 1, 4: 3\n" /* Type -1, direction Z+ */
|
||||
"-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -4815,7 +4853,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -4901,7 +4939,9 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"1: 2, 1, 4: 3\n" /* Type 1, direction Z+ */
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */,
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
|
||||
"-1: 2, 1, 4: 3\n" /* Type -1, direction Z+ */
|
||||
"-1: 0, 1, 2: 4\n" /* Type -1, direction X- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -4910,7 +4950,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -4996,7 +5036,11 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
"1: 4, 1, 2: 5\n" /* Type 1, direction X+ */
|
||||
"1: 2, 1, 4: 3\n" /* Type 1, direction Z+ */
|
||||
"1: 0, 1, 2: 4\n" /* Type 1, direction X- */
|
||||
"1: 2, 1, 0: 2\n" /* Type 1, direction Z- */,
|
||||
"1: 2, 1, 0: 2\n" /* Type 1, direction Z- */
|
||||
"-1: 4, 1, 2: 5\n" /* Type -1, direction X+ */
|
||||
"-1: 2, 1, 4: 3\n" /* Type -1, direction Z+ */
|
||||
"-1: 0, 1, 2: 4\n" /* Type -1, direction X- */
|
||||
"-1: 2, 1, 0: 2\n" /* Type -1, direction Z- */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -5005,7 +5049,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -5120,7 +5164,7 @@ const cPrefab::sDef g_NetherFortPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
@ -5314,7 +5358,8 @@ const cPrefab::sDef g_NetherFortStartingPrefabs[] =
|
||||
|
||||
// Connectors:
|
||||
"0: 6, 1, 0: 2\n" /* Type 0, direction Z- */
|
||||
"1: 6, 1, 12: 3\n" /* Type 1, direction Z+ */,
|
||||
"1: 6, 1, 12: 3\n" /* Type 1, direction Z+ */
|
||||
"-1: 6, 1, 12: 3\n" /* Type -1, direction Z+ */,
|
||||
|
||||
// AllowedRotations:
|
||||
7, /* 1, 2, 3 CCW rotation allowed */
|
||||
@ -5323,7 +5368,7 @@ const cPrefab::sDef g_NetherFortStartingPrefabs[] =
|
||||
cBlockArea::msSpongePrint,
|
||||
|
||||
// ShouldExtendFloor:
|
||||
false,
|
||||
true,
|
||||
|
||||
// DefaultWeight:
|
||||
100,
|
||||
|
@ -306,8 +306,14 @@ void cStructGenRavines::cRavine::GenerateBaseDefPoints(int a_BlockX, int a_Block
|
||||
|
||||
void cStructGenRavines::cRavine::RefineDefPoints(const cRavDefPoints & a_Src, cRavDefPoints & a_Dst)
|
||||
{
|
||||
if (a_Src.size() < 2)
|
||||
{
|
||||
// No midpoints, nothing to refine
|
||||
return;
|
||||
}
|
||||
|
||||
// Smoothing: for each line segment, add points on its 1/4 lengths
|
||||
int Num = a_Src.size() - 2; // this many intermediary points
|
||||
size_t Num = a_Src.size() - 2; // this many intermediary points
|
||||
a_Dst.clear();
|
||||
a_Dst.reserve(Num * 2 + 2);
|
||||
cRavDefPoints::const_iterator itr = a_Src.begin() + 1;
|
||||
@ -318,7 +324,7 @@ void cStructGenRavines::cRavine::RefineDefPoints(const cRavDefPoints & a_Src, cR
|
||||
int PrevR = Source.m_Radius;
|
||||
int PrevT = Source.m_Top;
|
||||
int PrevB = Source.m_Bottom;
|
||||
for (int i = 0; i <= Num; ++i, ++itr)
|
||||
for (size_t i = 0; i <= Num; ++i, ++itr)
|
||||
{
|
||||
int dx = itr->m_BlockX - PrevX;
|
||||
int dz = itr->m_BlockZ - PrevZ;
|
||||
|
@ -136,7 +136,7 @@ inline void PushSomeColumns(int a_BlockX, int a_Height, int a_BlockZ, int a_Colu
|
||||
{
|
||||
int x = a_BlockX + a_Coords[i].x;
|
||||
int z = a_BlockZ + a_Coords[i].z;
|
||||
if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + i, z + 64 * a_Seq) <= a_Chance)
|
||||
if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + (int)i, z + 64 * a_Seq) <= a_Chance)
|
||||
{
|
||||
for (int j = 0; j < a_ColumnHeight; j++)
|
||||
{
|
||||
|
@ -79,23 +79,24 @@ void cGroupManager::CheckUsers(void)
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int NumKeys = IniFile.GetNumKeys();
|
||||
for (size_t i = 0; i < NumKeys; i++)
|
||||
int NumKeys = IniFile.GetNumKeys();
|
||||
for (int i = 0; i < NumKeys; i++)
|
||||
{
|
||||
AString Player = IniFile.GetKeyName( i );
|
||||
AString Player = IniFile.GetKeyName(i);
|
||||
AString Groups = IniFile.GetValue(Player, "Groups", "");
|
||||
if (!Groups.empty())
|
||||
if (Groups.empty())
|
||||
{
|
||||
AStringVector Split = StringSplit( Groups, "," );
|
||||
for( unsigned int i = 0; i < Split.size(); i++ )
|
||||
continue;
|
||||
}
|
||||
AStringVector Split = StringSplitAndTrim(Groups, ",");
|
||||
for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr)
|
||||
{
|
||||
if (!ExistsGroup(Split[i]))
|
||||
if (!ExistsGroup(*itr))
|
||||
{
|
||||
LOGWARNING("The group %s for player %s was not found!", Split[i].c_str(), Player.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for itr - Split[]
|
||||
} // for i - ini file keys
|
||||
}
|
||||
|
||||
|
||||
@ -128,15 +129,15 @@ void cGroupManager::LoadGroups()
|
||||
IniFile.WriteFile("groups.ini");
|
||||
}
|
||||
|
||||
unsigned int NumKeys = IniFile.GetNumKeys();
|
||||
for (size_t i = 0; i < NumKeys; i++)
|
||||
int NumKeys = IniFile.GetNumKeys();
|
||||
for (int i = 0; i < NumKeys; i++)
|
||||
{
|
||||
AString KeyName = IniFile.GetKeyName( i );
|
||||
cGroup* Group = GetGroup( KeyName.c_str() );
|
||||
AString KeyName = IniFile.GetKeyName(i);
|
||||
cGroup * Group = GetGroup(KeyName.c_str());
|
||||
|
||||
Group->ClearPermission(); // Needed in case the groups are reloaded.
|
||||
|
||||
LOGD("Loading group: %s", KeyName.c_str() );
|
||||
LOGD("Loading group %s", KeyName.c_str());
|
||||
|
||||
Group->SetName(KeyName);
|
||||
AString Color = IniFile.GetValue(KeyName, "Color", "-");
|
||||
|
@ -97,7 +97,7 @@ void cNameValueParser::Parse(const char * a_Data, size_t a_Size)
|
||||
{
|
||||
ASSERT(m_State != psFinished); // Calling Parse() after Finish() is wrong!
|
||||
|
||||
int Last = 0;
|
||||
size_t Last = 0;
|
||||
for (size_t i = 0; i < a_Size;)
|
||||
{
|
||||
switch (m_State)
|
||||
|
@ -376,6 +376,7 @@ bool cInventory::DamageItem(int a_SlotNum, short a_Amount)
|
||||
if (!Grid->DamageItem(GridSlotNum, a_Amount))
|
||||
{
|
||||
// The item has been damaged, but did not break yet
|
||||
SendSlot(a_SlotNum);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -151,6 +151,8 @@ void cItem::GetJson(Json::Value & a_OutValue) const
|
||||
a_OutValue["Colours"] = m_FireworkItem.ColoursToString(m_FireworkItem);
|
||||
a_OutValue["FadeColours"] = m_FireworkItem.FadeColoursToString(m_FireworkItem);
|
||||
}
|
||||
|
||||
a_OutValue["RepairCost"] = m_RepairCost;
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,6 +181,8 @@ void cItem::FromJson(const Json::Value & a_Value)
|
||||
m_FireworkItem.ColoursFromString(a_Value.get("Colours", "").asString(), m_FireworkItem);
|
||||
m_FireworkItem.FadeColoursFromString(a_Value.get("FadeColours", "").asString(), m_FireworkItem);
|
||||
}
|
||||
|
||||
m_RepairCost = a_Value.get("RepairCost", 0).asInt();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
m_ItemDamage(0),
|
||||
m_CustomName(""),
|
||||
m_Lore(""),
|
||||
m_RepairCost(0),
|
||||
m_FireworkItem()
|
||||
{
|
||||
}
|
||||
@ -60,6 +61,7 @@ public:
|
||||
m_Enchantments(a_Enchantments),
|
||||
m_CustomName (a_CustomName),
|
||||
m_Lore (a_Lore),
|
||||
m_RepairCost (0),
|
||||
m_FireworkItem()
|
||||
{
|
||||
if (!IsValidItem(m_ItemType))
|
||||
@ -85,6 +87,7 @@ public:
|
||||
m_Enchantments(a_CopyFrom.m_Enchantments),
|
||||
m_CustomName (a_CopyFrom.m_CustomName),
|
||||
m_Lore (a_CopyFrom.m_Lore),
|
||||
m_RepairCost (a_CopyFrom.m_RepairCost),
|
||||
m_FireworkItem(a_CopyFrom.m_FireworkItem)
|
||||
{
|
||||
}
|
||||
@ -100,6 +103,7 @@ public:
|
||||
m_Enchantments.Clear();
|
||||
m_CustomName = "";
|
||||
m_Lore = "";
|
||||
m_RepairCost = 0;
|
||||
m_FireworkItem.EmptyData();
|
||||
}
|
||||
|
||||
@ -109,6 +113,7 @@ public:
|
||||
m_ItemType = E_ITEM_EMPTY;
|
||||
m_ItemCount = 0;
|
||||
m_ItemDamage = 0;
|
||||
m_RepairCost = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -197,6 +202,7 @@ public:
|
||||
AString m_CustomName;
|
||||
AString m_Lore;
|
||||
|
||||
int m_RepairCost;
|
||||
cFireworkItem m_FireworkItem;
|
||||
};
|
||||
// tolua_end
|
||||
|
@ -60,6 +60,49 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool CanRepairWithRawMaterial(short a_ItemType) override
|
||||
{
|
||||
switch (m_ItemType)
|
||||
{
|
||||
case E_ITEM_CHAIN_BOOTS:
|
||||
case E_ITEM_CHAIN_CHESTPLATE:
|
||||
case E_ITEM_CHAIN_HELMET:
|
||||
case E_ITEM_CHAIN_LEGGINGS:
|
||||
{
|
||||
return (a_ItemType == E_ITEM_IRON);
|
||||
}
|
||||
case E_ITEM_DIAMOND_BOOTS:
|
||||
case E_ITEM_DIAMOND_CHESTPLATE:
|
||||
case E_ITEM_DIAMOND_HELMET:
|
||||
case E_ITEM_DIAMOND_LEGGINGS:
|
||||
{
|
||||
return (a_ItemType == E_ITEM_DIAMOND);
|
||||
}
|
||||
case E_ITEM_IRON_BOOTS:
|
||||
case E_ITEM_IRON_CHESTPLATE:
|
||||
case E_ITEM_IRON_HELMET:
|
||||
case E_ITEM_IRON_LEGGINGS:
|
||||
{
|
||||
return (a_ItemType == E_ITEM_IRON);
|
||||
}
|
||||
case E_ITEM_GOLD_BOOTS:
|
||||
case E_ITEM_GOLD_CHESTPLATE:
|
||||
case E_ITEM_GOLD_HELMET:
|
||||
case E_ITEM_GOLD_LEGGINGS:
|
||||
{
|
||||
return (a_ItemType == E_ITEM_GOLD);
|
||||
}
|
||||
case E_ITEM_LEATHER_BOOTS:
|
||||
case E_ITEM_LEATHER_CAP:
|
||||
case E_ITEM_LEATHER_PANTS:
|
||||
case E_ITEM_LEATHER_TUNIC:
|
||||
{
|
||||
return (a_ItemType == E_ITEM_LEATHER);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -511,6 +511,16 @@ bool cItemHandler::IsPlaceable(void)
|
||||
|
||||
|
||||
|
||||
|
||||
bool cItemHandler::CanRepairWithRawMaterial(short a_ItemType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
UNUSED(a_BlockType);
|
||||
|
@ -85,6 +85,9 @@ public:
|
||||
/** Blocks simply get placed */
|
||||
virtual bool IsPlaceable(void);
|
||||
|
||||
/** Can the anvil repair this item, when a_Item is the second input? */
|
||||
virtual bool CanRepairWithRawMaterial(short a_ItemType);
|
||||
|
||||
/** Called before a block is placed into a world.
|
||||
The handler should return true to allow placement, false to refuse.
|
||||
Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block.
|
||||
|
@ -47,9 +47,9 @@ public:
|
||||
public cBlockTracer::cCallbacks
|
||||
{
|
||||
public:
|
||||
cCallbacks(cWorld * a_CBWorld) :
|
||||
m_HasHitFluid(false),
|
||||
m_World(a_CBWorld)
|
||||
|
||||
cCallbacks(void) :
|
||||
m_HasHitFluid(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -62,10 +62,9 @@ public:
|
||||
return false;
|
||||
}
|
||||
AddFaceDirection(a_CBBlockX, a_CBBlockY, a_CBBlockZ, BLOCK_FACE_YP); // Always place pad at top of water block
|
||||
BLOCKTYPE Block = m_World->GetBlock(a_CBBlockX, a_CBBlockY, a_CBBlockZ);
|
||||
if (
|
||||
!IsBlockWater(Block) &&
|
||||
cBlockInfo::FullyOccupiesVoxel(Block)
|
||||
!IsBlockWater(a_CBBlockType) &&
|
||||
cBlockInfo::FullyOccupiesVoxel(a_CBBlockType)
|
||||
)
|
||||
{
|
||||
// Can't place lilypad on air/in another block!
|
||||
@ -80,11 +79,10 @@ public:
|
||||
|
||||
Vector3i m_Pos;
|
||||
bool m_HasHitFluid;
|
||||
cWorld * m_World;
|
||||
|
||||
};
|
||||
|
||||
cCallbacks Callbacks(a_World);
|
||||
cCallbacks Callbacks;
|
||||
cLineBlockTracer Tracer(*a_Player->GetWorld(), Callbacks);
|
||||
Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector());
|
||||
Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5);
|
||||
|
@ -76,6 +76,7 @@ public:
|
||||
case E_BLOCK_STONE_PRESSURE_PLATE:
|
||||
case E_BLOCK_BRICK:
|
||||
case E_BLOCK_COBBLESTONE_STAIRS:
|
||||
case E_BLOCK_COBBLESTONE_WALL:
|
||||
case E_BLOCK_STONE_BRICK_STAIRS:
|
||||
case E_BLOCK_NETHER_BRICK_STAIRS:
|
||||
case E_BLOCK_CAULDRON:
|
||||
@ -85,6 +86,19 @@ public:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool CanRepairWithRawMaterial(short a_ItemType) override
|
||||
{
|
||||
switch (m_ItemType)
|
||||
{
|
||||
case E_ITEM_WOODEN_PICKAXE: return (a_ItemType == E_BLOCK_PLANKS);
|
||||
case E_ITEM_STONE_PICKAXE: return (a_ItemType == E_BLOCK_COBBLESTONE);
|
||||
case E_ITEM_IRON_PICKAXE: return (a_ItemType == E_ITEM_IRON);
|
||||
case E_ITEM_GOLD_PICKAXE: return (a_ItemType == E_ITEM_GOLD);
|
||||
case E_ITEM_DIAMOND_PICKAXE: return (a_ItemType == E_ITEM_DIAMOND);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -41,4 +41,18 @@ public:
|
||||
{
|
||||
return (a_BlockType == E_BLOCK_SNOW);
|
||||
}
|
||||
|
||||
virtual bool CanRepairWithRawMaterial(short a_ItemType) override
|
||||
{
|
||||
switch (m_ItemType)
|
||||
{
|
||||
case E_ITEM_WOODEN_SHOVEL: return (a_ItemType == E_BLOCK_PLANKS);
|
||||
case E_ITEM_STONE_SHOVEL: return (a_ItemType == E_BLOCK_COBBLESTONE);
|
||||
case E_ITEM_IRON_SHOVEL: return (a_ItemType == E_ITEM_IRON);
|
||||
case E_ITEM_GOLD_SHOVEL: return (a_ItemType == E_ITEM_GOLD);
|
||||
case E_ITEM_DIAMOND_SHOVEL: return (a_ItemType == E_ITEM_DIAMOND);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -23,6 +23,19 @@ public:
|
||||
{
|
||||
return (a_BlockType == E_BLOCK_COBWEB);
|
||||
}
|
||||
|
||||
virtual bool CanRepairWithRawMaterial(short a_ItemType) override
|
||||
{
|
||||
switch (m_ItemType)
|
||||
{
|
||||
case E_ITEM_WOODEN_SWORD: return (a_ItemType == E_BLOCK_PLANKS);
|
||||
case E_ITEM_STONE_SWORD: return (a_ItemType == E_BLOCK_COBBLESTONE);
|
||||
case E_ITEM_IRON_SWORD: return (a_ItemType == E_ITEM_IRON);
|
||||
case E_ITEM_GOLD_SWORD: return (a_ItemType == E_ITEM_GOLD);
|
||||
case E_ITEM_DIAMOND_SWORD: return (a_ItemType == E_ITEM_DIAMOND);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -28,15 +28,19 @@ public:
|
||||
|
||||
virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override
|
||||
{
|
||||
Vector3d Pos = a_Player->GetThrowStartPos();
|
||||
Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff;
|
||||
|
||||
if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||
}
|
||||
|
||||
Vector3d Pos = a_Player->GetThrowStartPos();
|
||||
Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff;
|
||||
a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -127,7 +131,10 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
a_World->CreateProjectile(a_BlockX + 0.5, a_BlockY + 1, a_BlockZ + 0.5, m_ProjectileKind, a_Player, a_Player->GetEquippedItem());
|
||||
if (a_World->CreateProjectile(a_BlockX + 0.5, a_BlockY + 1, a_BlockZ + 0.5, m_ProjectileKind, a_Player, a_Player->GetEquippedItem()) < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a_Player->IsGameModeCreative())
|
||||
{
|
||||
|
@ -103,11 +103,13 @@ void cLightingThread::Stop(void)
|
||||
cCSLock Lock(m_CS);
|
||||
for (cChunkStays::iterator itr = m_PendingQueue.begin(), end = m_PendingQueue.end(); itr != end; ++itr)
|
||||
{
|
||||
(*itr)->Disable();
|
||||
delete *itr;
|
||||
}
|
||||
m_PendingQueue.clear();
|
||||
for (cChunkStays::iterator itr = m_Queue.begin(), end = m_Queue.end(); itr != end; ++itr)
|
||||
{
|
||||
(*itr)->Disable();
|
||||
delete *itr;
|
||||
}
|
||||
m_Queue.clear();
|
||||
|
@ -614,7 +614,7 @@ unsigned int cMap::GetNumPixels(void) const
|
||||
|
||||
|
||||
|
||||
unsigned int cMap::GetNumDecorators(void) const
|
||||
size_t cMap::GetNumDecorators(void) const
|
||||
{
|
||||
return m_Decorators.size();
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
unsigned int GetNumDecorators(void) const;
|
||||
size_t GetNumDecorators(void) const;
|
||||
|
||||
const cColorList & GetData(void) const { return m_Data; }
|
||||
|
||||
|
@ -86,7 +86,7 @@ cMap * cMapManager::CreateMap(int a_CenterX, int a_CenterY, int a_Scale)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cMap Map(m_MapData.size(), a_CenterX, a_CenterY, m_World, a_Scale);
|
||||
cMap Map((unsigned)m_MapData.size(), a_CenterX, a_CenterY, m_World, a_Scale);
|
||||
|
||||
m_MapData.push_back(Map);
|
||||
|
||||
@ -97,7 +97,7 @@ cMap * cMapManager::CreateMap(int a_CenterX, int a_CenterY, int a_Scale)
|
||||
|
||||
|
||||
|
||||
unsigned int cMapManager::GetNumMaps(void) const
|
||||
size_t cMapManager::GetNumMaps(void) const
|
||||
{
|
||||
return m_MapData.size();
|
||||
}
|
||||
@ -151,7 +151,7 @@ void cMapManager::SaveMapData(void)
|
||||
|
||||
cIDCountSerializer IDSerializer(m_World->GetName());
|
||||
|
||||
IDSerializer.SetMapCount(m_MapData.size());
|
||||
IDSerializer.SetMapCount((unsigned)m_MapData.size());
|
||||
|
||||
if (!IDSerializer.Save())
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
*/
|
||||
bool ForEachMap(cMapCallback & a_Callback);
|
||||
|
||||
unsigned int GetNumMaps(void) const; // tolua_export
|
||||
size_t GetNumMaps(void) const; // tolua_export
|
||||
|
||||
/** Loads the map data from the disk */
|
||||
void LoadMapData(void);
|
||||
|
@ -64,7 +64,7 @@ void cMobCensus::CollectSpawnableChunk(cChunk & a_Chunk)
|
||||
|
||||
int cMobCensus::GetNumChunks(void)
|
||||
{
|
||||
return m_EligibleForSpawnChunks.size();
|
||||
return (int)m_EligibleForSpawnChunks.size();
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ void cMobFamilyCollecter::CollectMob(cMonster & a_Monster)
|
||||
|
||||
int cMobFamilyCollecter::GetNumberOfCollectedMobs(cMonster::eFamily a_Family)
|
||||
{
|
||||
return m_Mobs[a_Family].size();
|
||||
return (int)m_Mobs[a_Family].size();
|
||||
}
|
||||
|
||||
|
||||
|
@ -104,13 +104,13 @@ cMonster::eType cMobSpawner::ChooseMobType(EMCSBiome a_Biome)
|
||||
}
|
||||
}
|
||||
|
||||
int allowedMobsSize = allowedMobs.size();
|
||||
size_t allowedMobsSize = allowedMobs.size();
|
||||
if (allowedMobsSize > 0)
|
||||
{
|
||||
std::set<cMonster::eType>::iterator itr = allowedMobs.begin();
|
||||
int iRandom = m_Random.NextInt(allowedMobsSize,a_Biome);
|
||||
int iRandom = m_Random.NextInt((int)allowedMobsSize, a_Biome);
|
||||
|
||||
for(int i = 0; i < iRandom; i++)
|
||||
for (int i = 0; i < iRandom; i++)
|
||||
{
|
||||
++itr;
|
||||
}
|
||||
|
@ -108,14 +108,13 @@ void cAggressiveMonster::Attack(float a_Dt)
|
||||
|
||||
bool cAggressiveMonster::IsMovingToTargetPosition()
|
||||
{
|
||||
static const float epsilon = 0.000000000001f;
|
||||
// Difference between destination x and target x is negligible (to 10^-12 precision)
|
||||
if (fabsf((float)m_FinalDestination.x - (float)m_Target->GetPosX()) < epsilon)
|
||||
if (fabsf((float)m_FinalDestination.x - (float)m_Target->GetPosX()) < std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Difference between destination z and target z is negligible (to 10^-12 precision)
|
||||
else if (fabsf((float)m_FinalDestination.z - (float)m_Target->GetPosZ()) > epsilon)
|
||||
else if (fabsf((float)m_FinalDestination.z - (float)m_Target->GetPosZ()) > std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -814,7 +814,7 @@ void cPerlinNoise::SetSeed(int a_Seed)
|
||||
|
||||
void cPerlinNoise::AddOctave(float a_Frequency, float a_Amplitude)
|
||||
{
|
||||
m_Octaves.push_back(cOctave(m_Seed * (m_Octaves.size() + 4) * 4 + 1024, a_Frequency, a_Amplitude));
|
||||
m_Octaves.push_back(cOctave(m_Seed * ((int)m_Octaves.size() + 4) * 4 + 1024, a_Frequency, a_Amplitude));
|
||||
}
|
||||
|
||||
|
||||
|
@ -214,7 +214,7 @@ void cListenThread::Execute(void)
|
||||
timeval tv; // On Linux select() doesn't seem to wake up when socket is closed, so let's kinda busy-wait:
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
if (select(Highest + 1, &fdRead, NULL, NULL, &tv) == -1)
|
||||
if (select((int)Highest + 1, &fdRead, NULL, NULL, &tv) == -1)
|
||||
{
|
||||
LOG("select(R) call failed in cListenThread: \"%s\"", cSocket::GetLastErrorString().c_str());
|
||||
continue;
|
||||
|
@ -328,18 +328,18 @@ bool cSocket::ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Por
|
||||
|
||||
|
||||
|
||||
int cSocket::Receive(char * a_Buffer, unsigned int a_Length, unsigned int a_Flags)
|
||||
int cSocket::Receive(char * a_Buffer, size_t a_Length, unsigned int a_Flags)
|
||||
{
|
||||
return recv(m_Socket, a_Buffer, a_Length, a_Flags);
|
||||
return recv(m_Socket, a_Buffer, (int)a_Length, a_Flags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cSocket::Send(const char * a_Buffer, unsigned int a_Length)
|
||||
int cSocket::Send(const char * a_Buffer, size_t a_Length)
|
||||
{
|
||||
return send(m_Socket, a_Buffer, a_Length, MSG_NOSIGNAL);
|
||||
return send(m_Socket, a_Buffer, (int)a_Length, MSG_NOSIGNAL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,8 +110,8 @@ public:
|
||||
/// Connects to the specified host or string IP address and port, using IPv4. Returns true if successful.
|
||||
bool ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Port);
|
||||
|
||||
int Receive(char * a_Buffer, unsigned int a_Length, unsigned int a_Flags);
|
||||
int Send (const char * a_Buffer, unsigned int a_Length);
|
||||
int Receive(char * a_Buffer, size_t a_Length, unsigned int a_Flags);
|
||||
int Send (const char * a_Buffer, size_t a_Length);
|
||||
|
||||
unsigned short GetPort(void) const; // Returns 0 on failure
|
||||
|
||||
|
@ -406,7 +406,7 @@ void cSocketThreads::cSocketThread::Execute(void)
|
||||
timeval Timeout;
|
||||
Timeout.tv_sec = 5;
|
||||
Timeout.tv_usec = 0;
|
||||
if (select(Highest + 1, &fdRead, &fdWrite, NULL, &Timeout) == -1)
|
||||
if (select((int)Highest + 1, &fdRead, &fdWrite, NULL, &Timeout) == -1)
|
||||
{
|
||||
LOG("select() call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str());
|
||||
continue;
|
||||
|
@ -118,7 +118,7 @@ int cProbabDistrib::MapValue(int a_OrigValue) const
|
||||
size_t Hi = m_Cumulative.size() - 1;
|
||||
while (Hi - Lo > 1)
|
||||
{
|
||||
int Mid = (Lo + Hi) / 2;
|
||||
size_t Mid = (Lo + Hi) / 2;
|
||||
int MidProbab = m_Cumulative[Mid].m_Probability;
|
||||
if (MidProbab < a_OrigValue)
|
||||
{
|
||||
|
@ -214,7 +214,7 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S
|
||||
ReplaceString(ActualAddress, "%SERVERID%", a_ServerId);
|
||||
|
||||
AString Request;
|
||||
Request += "GET " + ActualAddress + " HTTP/1.1\r\n";
|
||||
Request += "GET " + ActualAddress + " HTTP/1.0\r\n";
|
||||
Request += "Host: " + m_Server + "\r\n";
|
||||
Request += "User-Agent: MCServer\r\n";
|
||||
Request += "Connection: close\r\n";
|
||||
|
@ -197,7 +197,7 @@ void cProtocol172::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
|
||||
Pkt.WriteInt(a_ChunkX);
|
||||
Pkt.WriteInt(a_ChunkZ);
|
||||
Pkt.WriteShort((short)a_Changes.size());
|
||||
Pkt.WriteInt(a_Changes.size() * 4);
|
||||
Pkt.WriteInt((int)a_Changes.size() * 4);
|
||||
for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr)
|
||||
{
|
||||
unsigned int Coords = itr->y | (itr->z << 8) | (itr->x << 12);
|
||||
@ -532,7 +532,7 @@ void cProtocol172::SendExplosion(double a_BlockX, double a_BlockY, double a_Bloc
|
||||
Pkt.WriteFloat((float)a_BlockY);
|
||||
Pkt.WriteFloat((float)a_BlockZ);
|
||||
Pkt.WriteFloat((float)a_Radius);
|
||||
Pkt.WriteInt(a_BlocksAffected.size());
|
||||
Pkt.WriteInt((int)a_BlocksAffected.size());
|
||||
for (cVector3iArray::const_iterator itr = a_BlocksAffected.begin(), end = a_BlocksAffected.end(); itr != end; ++itr)
|
||||
{
|
||||
Pkt.WriteChar((char)itr->x);
|
||||
@ -698,7 +698,7 @@ void cProtocol172::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decor
|
||||
|
||||
cPacketizer Pkt(*this, 0x34);
|
||||
Pkt.WriteVarInt(a_ID);
|
||||
Pkt.WriteShort (1 + (3 * a_Decorators.size()));
|
||||
Pkt.WriteShort ((short)(1 + (3 * a_Decorators.size())));
|
||||
|
||||
Pkt.WriteByte(1);
|
||||
|
||||
@ -1174,7 +1174,7 @@ void cProtocol172::SendTabCompletionResults(const AStringVector & a_Results)
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, 0x3a); // Tab-Complete packet
|
||||
Pkt.WriteVarInt(a_Results.size());
|
||||
Pkt.WriteVarInt((int)a_Results.size());
|
||||
|
||||
for (AStringVector::const_iterator itr = a_Results.begin(), end = a_Results.end(); itr != end; ++itr)
|
||||
{
|
||||
@ -1743,7 +1743,7 @@ void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer)
|
||||
cPacketizer Pkt(*this, 0x01);
|
||||
Pkt.WriteString(Server->GetServerID());
|
||||
const AString & PubKeyDer = Server->GetPublicKeyDER();
|
||||
Pkt.WriteShort(PubKeyDer.size());
|
||||
Pkt.WriteShort((short)PubKeyDer.size());
|
||||
Pkt.WriteBuf(PubKeyDer.data(), PubKeyDer.size());
|
||||
Pkt.WriteShort(4);
|
||||
Pkt.WriteInt((int)(intptr_t)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :)
|
||||
@ -2138,7 +2138,7 @@ void cProtocol172::WritePacket(cByteBuffer & a_Packet)
|
||||
cCSLock Lock(m_CSPacket);
|
||||
AString Pkt;
|
||||
a_Packet.ReadAll(Pkt);
|
||||
WriteVarInt(Pkt.size());
|
||||
WriteVarInt((UInt32)Pkt.size());
|
||||
SendData(Pkt.data(), Pkt.size());
|
||||
Flush();
|
||||
}
|
||||
@ -2278,6 +2278,13 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TAG_Int:
|
||||
{
|
||||
if (TagName == "RepairCost")
|
||||
{
|
||||
a_Item.m_RepairCost = NBT.GetInt(tag);
|
||||
}
|
||||
}
|
||||
default: LOGD("Unimplemented NBT data when parsing!"); break;
|
||||
}
|
||||
}
|
||||
@ -2396,7 +2403,7 @@ cProtocol172::cPacketizer::~cPacketizer()
|
||||
AString DataToSend;
|
||||
|
||||
// Send the packet length
|
||||
UInt32 PacketLen = m_Out.GetUsedSpace();
|
||||
UInt32 PacketLen = (UInt32)m_Out.GetUsedSpace();
|
||||
m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen);
|
||||
m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend);
|
||||
m_Protocol.SendData(DataToSend.data(), DataToSend.size());
|
||||
@ -2451,6 +2458,10 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
|
||||
|
||||
// Send the enchantments and custom names:
|
||||
cFastNBTWriter Writer;
|
||||
if (a_Item.m_RepairCost != 0)
|
||||
{
|
||||
Writer.AddInt("RepairCost", a_Item.m_RepairCost);
|
||||
}
|
||||
if (!a_Item.m_Enchantments.IsEmpty())
|
||||
{
|
||||
const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
|
||||
@ -2489,7 +2500,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
|
||||
Writer.Finish();
|
||||
AString Compressed;
|
||||
CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
|
||||
WriteShort(Compressed.size());
|
||||
WriteShort((short)Compressed.size());
|
||||
WriteBuf(Compressed.data(), Compressed.size());
|
||||
}
|
||||
|
||||
@ -2559,7 +2570,7 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt
|
||||
|
||||
AString Compressed;
|
||||
CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
|
||||
WriteShort(Compressed.size());
|
||||
WriteShort((short)Compressed.size());
|
||||
WriteBuf(Compressed.data(), Compressed.size());
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ protected:
|
||||
bool m_IsEncrypted;
|
||||
|
||||
cAesCfb128Decryptor m_Decryptor;
|
||||
cAesCfb128Decryptor m_Encryptor;
|
||||
cAesCfb128Encryptor m_Encryptor;
|
||||
|
||||
/** The logfile where the comm is logged, when g_ShouldLogComm is true */
|
||||
cFile m_CommLogFile;
|
||||
|
@ -871,7 +871,7 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void)
|
||||
// Not enough bytes for the packet length, keep waiting
|
||||
return false;
|
||||
}
|
||||
ReadSoFar -= m_Buffer.GetReadableSpace();
|
||||
ReadSoFar -= (UInt32)m_Buffer.GetReadableSpace();
|
||||
if (!m_Buffer.CanReadBytes(PacketLen))
|
||||
{
|
||||
// Not enough bytes for the packet, keep waiting
|
||||
@ -961,7 +961,7 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
|
||||
{
|
||||
return false;
|
||||
}
|
||||
NumBytesRead -= m_Buffer.GetReadableSpace();
|
||||
NumBytesRead -= (UInt32)m_Buffer.GetReadableSpace();
|
||||
switch (ProtocolVersion)
|
||||
{
|
||||
case PROTO_VERSION_1_7_2:
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
|
||||
virtual void Finished(void) override
|
||||
{
|
||||
m_Connection.SendResponse(m_RequestID, RCON_PACKET_RESPONSE, m_Buffer.size(), m_Buffer.c_str());
|
||||
m_Connection.SendResponse(m_RequestID, RCON_PACKET_RESPONSE, (int)m_Buffer.size(), m_Buffer.c_str());
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
14
src/Root.cpp
14
src/Root.cpp
@ -590,13 +590,13 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac
|
||||
{
|
||||
class cCallback : public cPlayerListCallback
|
||||
{
|
||||
unsigned m_BestRating;
|
||||
unsigned m_NameLength;
|
||||
size_t m_BestRating;
|
||||
size_t m_NameLength;
|
||||
const AString m_PlayerName;
|
||||
|
||||
virtual bool Item (cPlayer * a_pPlayer)
|
||||
{
|
||||
unsigned int Rating = RateCompareString (m_PlayerName, a_pPlayer->GetName());
|
||||
size_t Rating = RateCompareString (m_PlayerName, a_pPlayer->GetName());
|
||||
if ((Rating > 0) && (Rating >= m_BestRating))
|
||||
{
|
||||
m_BestMatch = a_pPlayer;
|
||||
@ -626,7 +626,7 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac
|
||||
cPlayer * m_BestMatch;
|
||||
unsigned m_NumMatches;
|
||||
} Callback (a_PlayerName);
|
||||
ForEachPlayer( Callback );
|
||||
ForEachPlayer(Callback);
|
||||
|
||||
if (Callback.m_NumMatches == 1)
|
||||
{
|
||||
@ -763,8 +763,8 @@ void cRoot::LogChunkStats(cCommandOutputCallback & a_Output)
|
||||
{
|
||||
cWorld * World = itr->second;
|
||||
int NumInGenerator = World->GetGeneratorQueueLength();
|
||||
int NumInSaveQueue = World->GetStorageSaveQueueLength();
|
||||
int NumInLoadQueue = World->GetStorageLoadQueueLength();
|
||||
int NumInSaveQueue = (int)World->GetStorageSaveQueueLength();
|
||||
int NumInLoadQueue = (int)World->GetStorageLoadQueueLength();
|
||||
int NumValid = 0;
|
||||
int NumDirty = 0;
|
||||
int NumInLighting = 0;
|
||||
@ -784,8 +784,6 @@ void cRoot::LogChunkStats(cCommandOutputCallback & a_Output)
|
||||
a_Output.Out(" block lighting: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024);
|
||||
a_Output.Out(" heightmap: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024);
|
||||
a_Output.Out(" biomemap: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024);
|
||||
int Rest = sizeof(cChunk) - sizeof(cChunkDef::BlockTypes) - 3 * sizeof(cChunkDef::BlockNibbles) - sizeof(cChunkDef::HeightMap) - sizeof(cChunkDef::BiomeMap);
|
||||
a_Output.Out(" other: %6d bytes (%3d KiB)", Rest, (Rest + 1023) / 1024);
|
||||
SumNumValid += NumValid;
|
||||
SumNumDirty += NumDirty;
|
||||
SumNumInLighting += NumInLighting;
|
||||
|
@ -261,7 +261,7 @@ void cTeam::SetDisplayName(const AString & a_Name)
|
||||
|
||||
|
||||
|
||||
unsigned int cTeam::GetNumPlayers(void) const
|
||||
size_t cTeam::GetNumPlayers(void) const
|
||||
{
|
||||
return m_Players.size();
|
||||
}
|
||||
@ -569,7 +569,7 @@ void cScoreboard::SendTo(cClientHandle & a_Client)
|
||||
|
||||
|
||||
|
||||
unsigned int cScoreboard::GetNumObjectives(void) const
|
||||
size_t cScoreboard::GetNumObjectives(void) const
|
||||
{
|
||||
return m_Objectives.size();
|
||||
}
|
||||
@ -578,7 +578,7 @@ unsigned int cScoreboard::GetNumObjectives(void) const
|
||||
|
||||
|
||||
|
||||
unsigned int cScoreboard::GetNumTeams(void) const
|
||||
size_t cScoreboard::GetNumTeams(void) const
|
||||
{
|
||||
return m_Teams.size();
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ public:
|
||||
// tolua_begin
|
||||
|
||||
/** Returns the number of registered players */
|
||||
unsigned int GetNumPlayers(void) const;
|
||||
size_t GetNumPlayers(void) const;
|
||||
|
||||
bool AllowsFriendlyFire(void) const { return m_AllowsFriendlyFire; }
|
||||
bool CanSeeFriendlyInvisible(void) const { return m_CanSeeFriendlyInvisible; }
|
||||
@ -248,9 +248,9 @@ public:
|
||||
|
||||
cObjective * GetObjectiveIn(eDisplaySlot a_Slot);
|
||||
|
||||
unsigned int GetNumObjectives(void) const;
|
||||
size_t GetNumObjectives(void) const;
|
||||
|
||||
unsigned int GetNumTeams(void) const;
|
||||
size_t GetNumTeams(void) const;
|
||||
|
||||
void AddPlayerScore(const AString & a_Name, cObjective::eType a_Type, cObjective::Score a_Value = 1);
|
||||
|
||||
|
@ -148,7 +148,7 @@ void cDelayedFluidSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_Chunk
|
||||
{
|
||||
SimulateBlock(a_Chunk, itr->x, itr->y, itr->z);
|
||||
}
|
||||
m_TotalBlocks -= Blocks.size();
|
||||
m_TotalBlocks -= (int)Blocks.size();
|
||||
Blocks.clear();
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -55,13 +55,13 @@ private:
|
||||
|
||||
struct sSimulatedPlayerToggleableList // Define structure of the list containing simulate-on-update blocks (such as trapdoors that respond once to a block update, and can be toggled by a player)
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
Vector3i a_RelBlockPos;
|
||||
bool WasLastStatePowered; // Was the last state powered or not? Determines whether a source update has happened and if I should resimulate
|
||||
};
|
||||
|
||||
struct sRepeatersDelayList // Define structure of list containing repeaters' delay states
|
||||
{
|
||||
Vector3i a_BlockPos;
|
||||
Vector3i a_RelBlockPos;
|
||||
unsigned char a_DelayTicks; // For how many ticks should the repeater delay
|
||||
unsigned char a_ElapsedTicks; // How much of the previous has been elapsed?
|
||||
bool ShouldPowerOn; // What happens when the delay time is fulfilled?
|
||||
@ -91,80 +91,80 @@ private:
|
||||
|
||||
/* ====== SOURCES ====== */
|
||||
/** Handles the redstone torch */
|
||||
void HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
void HandleRedstoneTorch(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
||||
/** Handles the redstone block */
|
||||
void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleRedstoneBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles levers */
|
||||
void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleRedstoneLever(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles buttons */
|
||||
void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType);
|
||||
void HandleRedstoneButton(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles daylight sensors */
|
||||
void HandleDaylightSensor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles pressure plates */
|
||||
void HandlePressurePlate(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
|
||||
void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
|
||||
/* ==================== */
|
||||
|
||||
/* ====== CARRIERS ====== */
|
||||
/** Handles redstone wire */
|
||||
void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleRedstoneWire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles repeaters */
|
||||
void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
void HandleRedstoneRepeater(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
||||
/* ====================== */
|
||||
|
||||
/* ====== DEVICES ====== */
|
||||
/** Handles pistons */
|
||||
void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandlePiston(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles dispensers and droppers */
|
||||
void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleDropSpenser(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles TNT (exploding) */
|
||||
void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleTNT(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles redstone lamps */
|
||||
void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState);
|
||||
void HandleRedstoneLamp(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyState);
|
||||
/** Handles doords */
|
||||
void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleDoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles command blocks */
|
||||
void HandleCommandBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleCommandBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles activator, detector, and powered rails */
|
||||
void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType);
|
||||
void HandleRail(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType);
|
||||
/** Handles trapdoors */
|
||||
void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleTrapdoor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles fence gates */
|
||||
void HandleFenceGate(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Handles noteblocks */
|
||||
void HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/* ===================== */
|
||||
|
||||
/* ====== Helper functions ====== */
|
||||
/** Marks a block as powered */
|
||||
void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
void SetBlockPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Marks a block as being powered through another block */
|
||||
void SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MiddleX, int a_MiddleY, int a_MiddleZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddeBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
void SetBlockLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, int a_RelMiddleX, int a_RelMiddleY, int a_RelMiddleZ, int a_RelSourceX, int a_RelSourceY, int a_RelSourceZ, BLOCKTYPE a_MiddeBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back */
|
||||
void SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool WasLastStatePowered);
|
||||
void SetPlayerToggleableBlockAsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool WasLastStatePowered);
|
||||
/** Marks the second block in a direction as linked powered */
|
||||
void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
void SetDirectionLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, char a_Direction, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Marks all blocks immediately surrounding a coordinate as powered */
|
||||
void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
void SetAllDirsAsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char a_PowerLevel = MAX_POWER_LEVEL);
|
||||
/** Queues a repeater to be powered or unpowered */
|
||||
void QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
|
||||
void QueueRepeaterPowerChange(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta, bool ShouldPowerOn);
|
||||
|
||||
/** Returns if a coordinate is powered or linked powered */
|
||||
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { return AreCoordsDirectlyPowered(a_BlockX, a_BlockY, a_BlockZ) || AreCoordsLinkedPowered(a_BlockX, a_BlockY, a_BlockZ); }
|
||||
bool AreCoordsPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { return AreCoordsDirectlyPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ) || AreCoordsLinkedPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); }
|
||||
/** Returns if a coordinate is in the directly powered blocks list */
|
||||
bool AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
bool AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Returns if a coordinate is in the indirectly powered blocks list */
|
||||
bool AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
bool AreCoordsLinkedPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ);
|
||||
/** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */
|
||||
bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered);
|
||||
bool AreCoordsSimulated(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, bool IsCurrentStatePowered);
|
||||
/** Returns if a repeater is powered */
|
||||
bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
bool IsRepeaterPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a repeater is locked */
|
||||
bool IsRepeaterLocked(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
bool IsRepeaterLocked(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a piston is powered */
|
||||
bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
|
||||
bool IsPistonPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, NIBBLETYPE a_Meta);
|
||||
/** Returns if a wire is powered
|
||||
The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire */
|
||||
bool IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ, unsigned char & a_PowerLevel);
|
||||
bool IsWirePowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, unsigned char & a_PowerLevel);
|
||||
|
||||
|
||||
/** Returns if lever metadata marks it as emitting power */
|
||||
|
@ -64,7 +64,7 @@ void cSandSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChun
|
||||
a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0);
|
||||
}
|
||||
}
|
||||
m_TotalBlocks -= ChunkData.size();
|
||||
m_TotalBlocks -= (int)ChunkData.size();
|
||||
ChunkData.clear();
|
||||
}
|
||||
|
||||
@ -254,6 +254,10 @@ void cSandSimulator::FinishFalling(
|
||||
{
|
||||
// Rematerialize the material here:
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_FallingBlockType, a_FallingBlockMeta);
|
||||
if (a_FallingBlockType == E_BLOCK_ANVIL)
|
||||
{
|
||||
a_World->BroadcastSoundParticleEffect(1022, a_BlockX, a_BlockY, a_BlockZ, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -102,10 +102,7 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int
|
||||
{
|
||||
return Cost;
|
||||
}
|
||||
if (
|
||||
IsPassableForFluid(BlockType) || // The block can be passed by the liquid ...
|
||||
(IsBlockLiquid(BlockType) && (BlockMeta != 0)) // ... or it is a liquid and not a source block
|
||||
)
|
||||
if (IsPassableForFluid(BlockType) || IsBlockLiquid(BlockType))
|
||||
{
|
||||
// Path found, exit
|
||||
return a_Iteration;
|
||||
|
@ -11,15 +11,15 @@
|
||||
|
||||
|
||||
/// Compresses a_Data into a_Compressed; returns Z_XXX error constants same as zlib's compress2()
|
||||
int CompressString(const char * a_Data, int a_Length, AString & a_Compressed, int a_Factor)
|
||||
int CompressString(const char * a_Data, size_t a_Length, AString & a_Compressed, int a_Factor)
|
||||
{
|
||||
uLongf CompressedSize = compressBound(a_Length);
|
||||
uLongf CompressedSize = compressBound((uLong)a_Length);
|
||||
|
||||
// HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer!
|
||||
// It saves us one allocation and one memcpy of the entire compressed data
|
||||
// It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010)
|
||||
a_Compressed.resize(CompressedSize);
|
||||
int errorcode = compress2( (Bytef*)a_Compressed.data(), &CompressedSize, (const Bytef*)a_Data, a_Length, a_Factor);
|
||||
int errorcode = compress2((Bytef*)a_Compressed.data(), &CompressedSize, (const Bytef *)a_Data, (uLong)a_Length, a_Factor);
|
||||
if (errorcode != Z_OK)
|
||||
{
|
||||
return errorcode;
|
||||
@ -33,14 +33,14 @@ int CompressString(const char * a_Data, int a_Length, AString & a_Compressed, in
|
||||
|
||||
|
||||
/// Uncompresses a_Data into a_Decompressed; returns Z_XXX error constants same as zlib's uncompress()
|
||||
int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize)
|
||||
int UncompressString(const char * a_Data, size_t a_Length, AString & a_Uncompressed, size_t a_UncompressedSize)
|
||||
{
|
||||
// HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer!
|
||||
// It saves us one allocation and one memcpy of the entire compressed data
|
||||
// It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010)
|
||||
a_Uncompressed.resize(a_UncompressedSize);
|
||||
uLongf UncompressedSize = (uLongf)a_UncompressedSize; // On some architectures the uLongf is different in size to int, that may be the cause of the -5 error
|
||||
int errorcode = uncompress((Bytef*)a_Uncompressed.data(), &UncompressedSize, (const Bytef*)a_Data, a_Length);
|
||||
int errorcode = uncompress((Bytef*)a_Uncompressed.data(), &UncompressedSize, (const Bytef*)a_Data, (uLong)a_Length);
|
||||
if (errorcode != Z_OK)
|
||||
{
|
||||
return errorcode;
|
||||
@ -63,7 +63,7 @@ int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compres
|
||||
z_stream strm;
|
||||
memset(&strm, 0, sizeof(strm));
|
||||
strm.next_in = (Bytef *)a_Data;
|
||||
strm.avail_in = a_Length;
|
||||
strm.avail_in = (uInt)a_Length;
|
||||
strm.next_out = (Bytef *)Buffer;
|
||||
strm.avail_out = sizeof(Buffer);
|
||||
|
||||
@ -127,7 +127,7 @@ extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString &
|
||||
z_stream strm;
|
||||
memset(&strm, 0, sizeof(strm));
|
||||
strm.next_in = (Bytef *)a_Data;
|
||||
strm.avail_in = a_Length;
|
||||
strm.avail_in = (uInt)a_Length;
|
||||
strm.next_out = (Bytef *)Buffer;
|
||||
strm.avail_out = sizeof(Buffer);
|
||||
|
||||
|
@ -10,10 +10,10 @@
|
||||
|
||||
|
||||
/// Compresses a_Data into a_Compressed using ZLIB; returns Z_XXX error constants same as zlib's compress2()
|
||||
extern int CompressString(const char * a_Data, int a_Length, AString & a_Compressed, int a_Factor);
|
||||
extern int CompressString(const char * a_Data, size_t a_Length, AString & a_Compressed, int a_Factor);
|
||||
|
||||
/// Uncompresses a_Data into a_Uncompressed; returns Z_XXX error constants same as zlib's decompress()
|
||||
extern int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize);
|
||||
extern int UncompressString(const char * a_Data, size_t a_Length, AString & a_Uncompressed, size_t a_UncompressedSize);
|
||||
|
||||
/// Compresses a_Data into a_Compressed using GZIP; returns Z_OK for success or Z_XXX error constants same as zlib
|
||||
extern int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compressed);
|
||||
|
@ -247,18 +247,22 @@ int NoCaseCompare(const AString & s1, const AString & s2)
|
||||
|
||||
|
||||
|
||||
unsigned int RateCompareString(const AString & s1, const AString & s2 )
|
||||
size_t RateCompareString(const AString & s1, const AString & s2)
|
||||
{
|
||||
unsigned int MatchedLetters = 0;
|
||||
unsigned int s1Length = s1.length();
|
||||
size_t MatchedLetters = 0;
|
||||
size_t s1Length = s1.length();
|
||||
|
||||
if( s1Length > s2.length() ) return 0; // Definitely not a match
|
||||
|
||||
for (unsigned int i = 0; i < s1Length; i++)
|
||||
if (s1Length > s2.length())
|
||||
{
|
||||
char c1 = (char)toupper( s1[i] );
|
||||
char c2 = (char)toupper( s2[i] );
|
||||
if( c1 == c2 )
|
||||
// Definitely not a match
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < s1Length; i++)
|
||||
{
|
||||
char c1 = (char)toupper(s1[i]);
|
||||
char c2 = (char)toupper(s2[i]);
|
||||
if (c1 == c2)
|
||||
{
|
||||
++MatchedLetters;
|
||||
}
|
||||
@ -288,11 +292,11 @@ void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString &
|
||||
|
||||
|
||||
// Converts a stream of BE shorts into UTF-8 string; returns a ref to a_UTF8
|
||||
AString & RawBEToUTF8(const char * a_RawData, int a_NumShorts, AString & a_UTF8)
|
||||
AString & RawBEToUTF8(const char * a_RawData, size_t a_NumShorts, AString & a_UTF8)
|
||||
{
|
||||
a_UTF8.clear();
|
||||
a_UTF8.reserve(3 * a_NumShorts / 2); // a quick guess of the resulting size
|
||||
for (int i = 0; i < a_NumShorts; i++)
|
||||
for (size_t i = 0; i < a_NumShorts; i++)
|
||||
{
|
||||
int c = GetBEShort(&a_RawData[i * 2]);
|
||||
if (c < 0x80)
|
||||
|
@ -55,13 +55,13 @@ extern AString & StrToLower(AString & s);
|
||||
extern int NoCaseCompare(const AString & s1, const AString & s2); // tolua_export
|
||||
|
||||
/// Case-insensitive string comparison that returns a rating of equal-ness between [0 - s1.length()]
|
||||
extern unsigned int RateCompareString(const AString & s1, const AString & s2 );
|
||||
extern size_t RateCompareString(const AString & s1, const AString & s2);
|
||||
|
||||
/// Replaces *each* occurence of iNeedle in iHayStack with iReplaceWith
|
||||
extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith); // tolua_export
|
||||
|
||||
/// Converts a stream of BE shorts into UTF-8 string; returns a ref to a_UTF8
|
||||
extern AString & RawBEToUTF8(const char * a_RawData, int a_NumShorts, AString & a_UTF8);
|
||||
extern AString & RawBEToUTF8(const char * a_RawData, size_t a_NumShorts, AString & a_UTF8);
|
||||
|
||||
/// Converts a UTF-8 string into a UTF-16 BE string, packing that back into AString; return a ref to a_UTF16
|
||||
extern AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a_UTF16);
|
||||
|
@ -219,6 +219,10 @@ bool cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pos.y < 0) || (pos.y >= cChunkDef::Height))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BLOCKTYPE BlockID = m_World->GetBlock(pos.x, pos.y, pos.z);
|
||||
// Block is counted as a collision if we are not doing a line of sight and it is solid,
|
||||
// or if the block is not air and not water. That way mobs can still see underwater.
|
||||
@ -226,7 +230,7 @@ bool cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int
|
||||
{
|
||||
BlockHitPosition = pos;
|
||||
int Normal = GetHitNormal(a_Start, End, pos );
|
||||
if(Normal > 0)
|
||||
if (Normal > 0)
|
||||
{
|
||||
HitNormal = m_NormalTable[Normal-1];
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ void cSlotArea::OnPlayerRemoved(cPlayer & a_Player)
|
||||
|
||||
|
||||
|
||||
void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_Apply, bool a_KeepEmptySlots)
|
||||
void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots)
|
||||
{
|
||||
for (int i = 0; i < m_NumSlots; i++)
|
||||
{
|
||||
@ -264,7 +264,7 @@ void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_
|
||||
{
|
||||
NumFit = a_ItemStack.m_ItemCount;
|
||||
}
|
||||
if (a_Apply)
|
||||
if (a_ShouldApply)
|
||||
{
|
||||
cItem NewSlot(a_ItemStack);
|
||||
NewSlot.m_ItemCount = Slot->m_ItemCount + NumFit;
|
||||
@ -595,6 +595,409 @@ cCraftingRecipe & cSlotAreaCrafting::GetRecipeForPlayer(cPlayer & a_Player)
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cSlotAreaAnvil:
|
||||
|
||||
cSlotAreaAnvil::cSlotAreaAnvil(cAnvilWindow & a_ParentWindow) :
|
||||
cSlotAreaTemporary(3, a_ParentWindow),
|
||||
m_MaximumCost(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSlotAreaAnvil::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem)
|
||||
{
|
||||
ASSERT((a_SlotNum >= 0) && (a_SlotNum < GetNumSlots()));
|
||||
if (a_SlotNum != 2)
|
||||
{
|
||||
super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem);
|
||||
UpdateResult(a_Player);
|
||||
return;
|
||||
}
|
||||
|
||||
bool bAsync = false;
|
||||
if (GetSlot(a_SlotNum, a_Player) == NULL)
|
||||
{
|
||||
LOGWARNING("GetSlot(%d) returned NULL! Ignoring click", a_SlotNum);
|
||||
return;
|
||||
}
|
||||
|
||||
if (a_ClickAction == caDblClick)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick))
|
||||
{
|
||||
ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
|
||||
return;
|
||||
}
|
||||
|
||||
cItem Slot(*GetSlot(a_SlotNum, a_Player));
|
||||
if (!Slot.IsSameType(a_ClickedItem))
|
||||
{
|
||||
LOGWARNING("*** Window lost sync at item %d in SlotArea with %d items ***", a_SlotNum, m_NumSlots);
|
||||
LOGWARNING("My item: %s", ItemToFullString(Slot).c_str());
|
||||
LOGWARNING("Their item: %s", ItemToFullString(a_ClickedItem).c_str());
|
||||
bAsync = true;
|
||||
}
|
||||
cItem & DraggingItem = a_Player.GetDraggingItem();
|
||||
|
||||
if (Slot.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!DraggingItem.IsEmpty())
|
||||
{
|
||||
if (!(DraggingItem.IsEqual(Slot) && ((DraggingItem.m_ItemCount + Slot.m_ItemCount) <= cItemHandler::GetItemHandler(Slot)->GetMaxStackSize())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CanTakeResultItem(a_Player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cItem NewItem = cItem(Slot);
|
||||
NewItem.m_ItemCount += DraggingItem.m_ItemCount;
|
||||
|
||||
Slot.Empty();
|
||||
DraggingItem.Empty();
|
||||
SetSlot(a_SlotNum, a_Player, Slot);
|
||||
|
||||
DraggingItem = NewItem;
|
||||
OnTakeResult(a_Player);
|
||||
|
||||
if (bAsync)
|
||||
{
|
||||
m_ParentWindow.BroadcastWholeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSlotAreaAnvil::ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem)
|
||||
{
|
||||
if (a_SlotNum != 2)
|
||||
{
|
||||
super::ShiftClicked(a_Player, a_SlotNum, a_ClickedItem);
|
||||
UpdateResult(a_Player);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a copy of the slot, distribute it among the other areas, then update the slot to contain the leftover:
|
||||
cItem Slot(*GetSlot(a_SlotNum, a_Player));
|
||||
|
||||
if (Slot.IsEmpty() || !CanTakeResultItem(a_Player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_ParentWindow.DistributeStack(Slot, a_Player, this, true);
|
||||
if (Slot.IsEmpty())
|
||||
{
|
||||
Slot.Empty();
|
||||
OnTakeResult(a_Player);
|
||||
}
|
||||
SetSlot(a_SlotNum, a_Player, Slot);
|
||||
|
||||
// Some clients try to guess our actions and not always right (armor slots in 1.2.5), so we fix them:
|
||||
m_ParentWindow.BroadcastWholeWindow();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSlotAreaAnvil::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
const cItem * Slot = GetSlot(i, a_Player);
|
||||
if (!Slot->IsEqual(a_ItemStack) && (!Slot->IsEmpty() || a_KeepEmptySlots))
|
||||
{
|
||||
// Different items
|
||||
continue;
|
||||
}
|
||||
int NumFit = ItemHandler(Slot->m_ItemType)->GetMaxStackSize() - Slot->m_ItemCount;
|
||||
if (NumFit <= 0)
|
||||
{
|
||||
// Full stack already
|
||||
continue;
|
||||
}
|
||||
if (NumFit > a_ItemStack.m_ItemCount)
|
||||
{
|
||||
NumFit = a_ItemStack.m_ItemCount;
|
||||
}
|
||||
if (a_ShouldApply)
|
||||
{
|
||||
cItem NewSlot(a_ItemStack);
|
||||
NewSlot.m_ItemCount = Slot->m_ItemCount + NumFit;
|
||||
SetSlot(i, a_Player, NewSlot);
|
||||
}
|
||||
a_ItemStack.m_ItemCount -= NumFit;
|
||||
if (a_ItemStack.IsEmpty())
|
||||
{
|
||||
UpdateResult(a_Player);
|
||||
return;
|
||||
}
|
||||
} // for i - Slots
|
||||
UpdateResult(a_Player);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSlotAreaAnvil::OnTakeResult(cPlayer & a_Player)
|
||||
{
|
||||
if (!a_Player.IsGameModeCreative())
|
||||
{
|
||||
a_Player.DeltaExperience(cPlayer::XpForLevel(m_MaximumCost));
|
||||
}
|
||||
SetSlot(0, a_Player, cItem());
|
||||
|
||||
if (m_StackSizeToBeUsedInRepair > 0)
|
||||
{
|
||||
const cItem * Item = GetSlot(1, a_Player);
|
||||
if (!Item->IsEmpty() && (Item->m_ItemCount > m_StackSizeToBeUsedInRepair))
|
||||
{
|
||||
cItem NewSecondItem(*Item);
|
||||
NewSecondItem.m_ItemCount -= m_StackSizeToBeUsedInRepair;
|
||||
SetSlot(1, a_Player, NewSecondItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSlot(1, a_Player, cItem());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSlot(1, a_Player, cItem());
|
||||
}
|
||||
m_ParentWindow.SetProperty(0, m_MaximumCost, a_Player);
|
||||
|
||||
m_MaximumCost = 0;
|
||||
((cAnvilWindow*)&m_ParentWindow)->SetRepairedItemName("", NULL);
|
||||
|
||||
int PosX, PosY, PosZ;
|
||||
((cAnvilWindow*)&m_ParentWindow)->GetBlockPos(PosX, PosY, PosZ);
|
||||
|
||||
BLOCKTYPE Block;
|
||||
NIBBLETYPE BlockMeta;
|
||||
a_Player.GetWorld()->GetBlockTypeMeta(PosX, PosY, PosZ, Block, BlockMeta);
|
||||
|
||||
cFastRandom Random;
|
||||
if (!a_Player.IsGameModeCreative() && (Block == E_BLOCK_ANVIL) && (Random.NextFloat(1.0F) < 0.12F))
|
||||
{
|
||||
NIBBLETYPE Orientation = BlockMeta & 0x3;
|
||||
NIBBLETYPE AnvilDamage = BlockMeta >> 2;
|
||||
++AnvilDamage;
|
||||
|
||||
if (AnvilDamage > 2)
|
||||
{
|
||||
// Anvil will break
|
||||
a_Player.GetWorld()->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, (NIBBLETYPE)0);
|
||||
a_Player.GetWorld()->BroadcastSoundParticleEffect(1020, PosX, PosY, PosZ, 0);
|
||||
a_Player.CloseWindow(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Player.GetWorld()->SetBlockMeta(PosX, PosY, PosZ, Orientation | (AnvilDamage << 2));
|
||||
a_Player.GetWorld()->BroadcastSoundParticleEffect(1021, PosX, PosY, PosZ, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a_Player.GetWorld()->BroadcastSoundParticleEffect(1021, PosX, PosY, PosZ, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cSlotAreaAnvil::CanTakeResultItem(cPlayer & a_Player)
|
||||
{
|
||||
return (
|
||||
(
|
||||
a_Player.IsGameModeCreative() || // Is the player in gamemode?
|
||||
(a_Player.GetXpLevel() >= m_MaximumCost) // or the player have enough exp?
|
||||
) &&
|
||||
(!GetSlot(2, a_Player)->IsEmpty()) && // Is a item in the result slot?
|
||||
(m_MaximumCost > 0) // When no maximum cost is set, the item isn't set from the UpdateResult() method and can't be a valid enchanting result.
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSlotAreaAnvil::OnPlayerRemoved(cPlayer & a_Player)
|
||||
{
|
||||
TossItems(a_Player, 0, 2);
|
||||
super::OnPlayerRemoved(a_Player);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player)
|
||||
{
|
||||
cItem Input(*GetSlot(0, a_Player));
|
||||
cItem SecondInput(*GetSlot(1, a_Player));
|
||||
cItem Output(*GetSlot(2, a_Player));
|
||||
|
||||
if (Input.IsEmpty() && !Output.IsEmpty())
|
||||
{
|
||||
Output.Empty();
|
||||
SetSlot(2, a_Player, Output);
|
||||
m_ParentWindow.SetProperty(0, 0, a_Player);
|
||||
return;
|
||||
}
|
||||
|
||||
m_MaximumCost = 0;
|
||||
m_StackSizeToBeUsedInRepair = 0;
|
||||
int RepairCost = Input.m_RepairCost;
|
||||
int NeedExp = 0;
|
||||
bool IsEnchantBook = false;
|
||||
if (!SecondInput.IsEmpty())
|
||||
{
|
||||
IsEnchantBook = (SecondInput.m_ItemType == E_ITEM_ENCHANTED_BOOK);
|
||||
|
||||
RepairCost += SecondInput.m_RepairCost;
|
||||
if (Input.IsDamageable() && cItemHandler::GetItemHandler(Input)->CanRepairWithRawMaterial(SecondInput.m_ItemType))
|
||||
{
|
||||
// Tool and armor repair with special item (iron / gold / diamond / ...)
|
||||
int DamageDiff = std::min((int)Input.m_ItemDamage, (int)Input.GetMaxDamage() / 4);
|
||||
if (DamageDiff <= 0)
|
||||
{
|
||||
// No enchantment
|
||||
Output.Empty();
|
||||
SetSlot(2, a_Player, Output);
|
||||
m_ParentWindow.SetProperty(0, 0, a_Player);
|
||||
return;
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
while ((DamageDiff > 0) && (x < SecondInput.m_ItemCount))
|
||||
{
|
||||
Input.m_ItemDamage -= DamageDiff;
|
||||
NeedExp += std::max(1, DamageDiff / 100) + (int)Input.m_Enchantments.Count();
|
||||
DamageDiff = std::min((int)Input.m_ItemDamage, (int)Input.GetMaxDamage() / 4);
|
||||
|
||||
++x;
|
||||
}
|
||||
m_StackSizeToBeUsedInRepair = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Tool and armor repair with two tools / armors
|
||||
if (!IsEnchantBook && (!Input.IsSameType(SecondInput) || !Input.IsDamageable()))
|
||||
{
|
||||
// No enchantment
|
||||
Output.Empty();
|
||||
SetSlot(2, a_Player, Output);
|
||||
m_ParentWindow.SetProperty(0, 0, a_Player);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Input.GetMaxDamage() > 0) && !IsEnchantBook)
|
||||
{
|
||||
int FirstDamageDiff = Input.GetMaxDamage() - Input.m_ItemDamage;
|
||||
int SecondDamageDiff = SecondInput.GetMaxDamage() - SecondInput.m_ItemDamage;
|
||||
int Damage = SecondDamageDiff + Input.GetMaxDamage() * 12 / 100;
|
||||
|
||||
int NewItemDamage = Input.GetMaxDamage() - (FirstDamageDiff + Damage);
|
||||
if (NewItemDamage > 0)
|
||||
{
|
||||
NewItemDamage = 0;
|
||||
}
|
||||
|
||||
if (NewItemDamage < Input.m_ItemDamage)
|
||||
{
|
||||
Input.m_ItemDamage = NewItemDamage;
|
||||
NeedExp += std::max(1, Damage / 100);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add enchantments.
|
||||
}
|
||||
}
|
||||
|
||||
int NameChangeExp = 0;
|
||||
const AString & RepairedItemName = ((cAnvilWindow*)&m_ParentWindow)->GetRepairedItemName();
|
||||
if (RepairedItemName.empty())
|
||||
{
|
||||
// Remove custom name
|
||||
if (!Input.m_CustomName.empty())
|
||||
{
|
||||
NameChangeExp = (Input.IsDamageable()) ? 7 : (Input.m_ItemCount * 5);
|
||||
NeedExp += NameChangeExp;
|
||||
Input.m_CustomName = "";
|
||||
}
|
||||
}
|
||||
else if (RepairedItemName != Input.m_CustomName)
|
||||
{
|
||||
// Change custom name
|
||||
NameChangeExp = (Input.IsDamageable()) ? 7 : (Input.m_ItemCount * 5);
|
||||
NeedExp += NameChangeExp;
|
||||
|
||||
if (!Input.m_CustomName.empty())
|
||||
{
|
||||
RepairCost += NameChangeExp / 2;
|
||||
}
|
||||
|
||||
Input.m_CustomName = RepairedItemName;
|
||||
}
|
||||
|
||||
// TODO: Add enchantment exp cost.
|
||||
|
||||
m_MaximumCost = RepairCost + NeedExp;
|
||||
|
||||
if (NeedExp < 0)
|
||||
{
|
||||
Input.Empty();
|
||||
}
|
||||
|
||||
if ((NameChangeExp == NeedExp) && (NameChangeExp > 0) && (m_MaximumCost >= 40))
|
||||
{
|
||||
m_MaximumCost = 39;
|
||||
}
|
||||
if (m_MaximumCost >= 40 && !a_Player.IsGameModeCreative())
|
||||
{
|
||||
Input.Empty();
|
||||
}
|
||||
|
||||
if (!Input.IsEmpty())
|
||||
{
|
||||
RepairCost = std::max(Input.m_RepairCost, SecondInput.m_RepairCost);
|
||||
if (!Input.m_CustomName.empty())
|
||||
{
|
||||
RepairCost -= 9;
|
||||
}
|
||||
RepairCost = std::max(RepairCost, 0);
|
||||
RepairCost += 2;
|
||||
Input.m_RepairCost = RepairCost;
|
||||
}
|
||||
|
||||
SetSlot(2, a_Player, Input);
|
||||
m_ParentWindow.SetProperty(0, m_MaximumCost, a_Player);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cSlotAreaEnchanting:
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Inventory.h"
|
||||
#include "Window.h"
|
||||
|
||||
|
||||
|
||||
@ -259,6 +260,43 @@ protected:
|
||||
|
||||
|
||||
|
||||
class cSlotAreaAnvil :
|
||||
public cSlotAreaTemporary
|
||||
{
|
||||
typedef cSlotAreaTemporary super;
|
||||
|
||||
public:
|
||||
cSlotAreaAnvil(cAnvilWindow & a_ParentWindow);
|
||||
|
||||
// cSlotArea overrides:
|
||||
virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
|
||||
virtual void ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem) override;
|
||||
virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override;
|
||||
|
||||
// cSlotAreaTemporary overrides:
|
||||
virtual void OnPlayerRemoved(cPlayer & a_Player) override;
|
||||
|
||||
/** Can the player take the item from the slot? */
|
||||
bool CanTakeResultItem(cPlayer & a_Player);
|
||||
|
||||
/** This function will call, when the player take the item from the slot. */
|
||||
void OnTakeResult(cPlayer & a_Player);
|
||||
|
||||
/** Handles a click in the item slot. */
|
||||
void UpdateResult(cPlayer & a_Player);
|
||||
|
||||
protected:
|
||||
/** The maximum cost of repairing/renaming in the anvil. */
|
||||
int m_MaximumCost;
|
||||
|
||||
/** The stack size of the second item where was used for repair */
|
||||
char m_StackSizeToBeUsedInRepair;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cSlotAreaEnchanting :
|
||||
public cSlotAreaTemporary
|
||||
{
|
||||
|
@ -591,7 +591,7 @@ void cWindow::OnLeftPaintEnd(cPlayer & a_Player)
|
||||
|
||||
const cSlotNums & SlotNums = a_Player.GetInventoryPaintSlots();
|
||||
cItem ToDistribute(a_Player.GetDraggingItem());
|
||||
int ToEachSlot = (int)ToDistribute.m_ItemCount / SlotNums.size();
|
||||
int ToEachSlot = (int)ToDistribute.m_ItemCount / (int)SlotNums.size();
|
||||
|
||||
int NumDistributed = DistributeItemToSlots(a_Player, ToDistribute, ToEachSlot, SlotNums);
|
||||
|
||||
@ -804,6 +804,51 @@ cCraftingWindow::cCraftingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) :
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cAnvilWindow:
|
||||
|
||||
cAnvilWindow::cAnvilWindow(int a_BlockX, int a_BlockY, int a_BlockZ) :
|
||||
cWindow(wtAnvil, "Repair"),
|
||||
m_RepairedItemName(""),
|
||||
m_BlockX(a_BlockX),
|
||||
m_BlockY(a_BlockY),
|
||||
m_BlockZ(a_BlockZ)
|
||||
{
|
||||
m_AnvilSlotArea = new cSlotAreaAnvil(*this);
|
||||
m_SlotAreas.push_back(m_AnvilSlotArea);
|
||||
m_SlotAreas.push_back(new cSlotAreaInventory(*this));
|
||||
m_SlotAreas.push_back(new cSlotAreaHotBar(*this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cAnvilWindow::SetRepairedItemName(const AString & a_Name, cPlayer * a_Player)
|
||||
{
|
||||
m_RepairedItemName = a_Name;
|
||||
|
||||
if (a_Player != NULL)
|
||||
{
|
||||
m_AnvilSlotArea->UpdateResult(*a_Player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cAnvilWindow::GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ)
|
||||
{
|
||||
a_PosX = m_BlockX;
|
||||
a_PosY = m_BlockY;
|
||||
a_PosZ = m_BlockZ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cEnchantingWindow:
|
||||
|
||||
|
@ -24,6 +24,7 @@ class cEnderChestEntity;
|
||||
class cFurnaceEntity;
|
||||
class cHopperEntity;
|
||||
class cSlotArea;
|
||||
class cSlotAreaAnvil;
|
||||
class cWorld;
|
||||
|
||||
typedef std::list<cPlayer *> cPlayerList;
|
||||
@ -231,6 +232,32 @@ public:
|
||||
|
||||
|
||||
|
||||
class cAnvilWindow :
|
||||
public cWindow
|
||||
{
|
||||
typedef cWindow super;
|
||||
public:
|
||||
cAnvilWindow(int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||
|
||||
/** Gets the repaired item name. */
|
||||
AString GetRepairedItemName(void) const { return m_RepairedItemName; }
|
||||
|
||||
/** Set the repaired item name. */
|
||||
void SetRepairedItemName(const AString & a_Name, cPlayer * a_Player);
|
||||
|
||||
/** Gets the Position from the Anvil */
|
||||
void GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ);
|
||||
|
||||
protected:
|
||||
cSlotAreaAnvil * m_AnvilSlotArea;
|
||||
AString m_RepairedItemName;
|
||||
int m_BlockX, m_BlockY, m_BlockZ;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cEnchantingWindow :
|
||||
public cWindow
|
||||
{
|
||||
@ -243,7 +270,7 @@ public:
|
||||
/** Return the Value of a Property */
|
||||
int GetPropertyValue(int a_Property);
|
||||
|
||||
/** Set the Position Values to the Position of the Enchantment Table */
|
||||
/** Get the Position from the Enchantment Table */
|
||||
void GetBlockPos(int & a_PosX, int & a_PosY, int & a_PosZ);
|
||||
|
||||
cSlotArea * m_SlotArea;
|
||||
|
@ -42,7 +42,6 @@ public:
|
||||
Vector3(const Vector3<_T> * a_Rhs) : x(a_Rhs->x), y(a_Rhs->y), z(a_Rhs->z) {}
|
||||
// tolua_begin
|
||||
|
||||
|
||||
inline void Set(T a_x, T a_y, T a_z)
|
||||
{
|
||||
x = a_x;
|
||||
@ -107,18 +106,18 @@ public:
|
||||
|
||||
inline bool Equals(const Vector3<T> & a_Rhs) const
|
||||
{
|
||||
return x == a_Rhs.x && y == a_Rhs.y && z == a_Rhs.z;
|
||||
// Perform a bitwise comparison of the contents - we want to know whether this object is exactly equal
|
||||
// To perform EPS-based comparison, use the EqualsEps() function
|
||||
return (
|
||||
(memcmp(&x, &a_Rhs.x, sizeof(x)) == 0) &&
|
||||
(memcmp(&y, &a_Rhs.y, sizeof(y)) == 0) &&
|
||||
(memcmp(&z, &a_Rhs.z, sizeof(z)) == 0)
|
||||
);
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector3<T> & a_Rhs) const
|
||||
inline bool EqualsEps(const Vector3<T> & a_Rhs, T a_Eps) const
|
||||
{
|
||||
return Equals(a_Rhs);
|
||||
}
|
||||
|
||||
inline bool operator < (const Vector3<T> & a_Rhs)
|
||||
{
|
||||
// return (x < a_Rhs.x) && (y < a_Rhs.y) && (z < a_Rhs.z); ?
|
||||
return (x < a_Rhs.x) || (x == a_Rhs.x && y < a_Rhs.y) || (x == a_Rhs.x && y == a_Rhs.y && z < a_Rhs.z);
|
||||
return (Abs(x - a_Rhs.x) < a_Eps) && (Abs(y - a_Rhs.y) < a_Eps) && (Abs(z - a_Rhs.z) < a_Eps);
|
||||
}
|
||||
|
||||
inline void Move(T a_X, T a_Y, T a_Z)
|
||||
@ -137,6 +136,16 @@ public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
inline bool operator != (const Vector3<T> & a_Rhs) const
|
||||
{
|
||||
return !Equals(a_Rhs);
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector3<T> & a_Rhs) const
|
||||
{
|
||||
return Equals(a_Rhs);
|
||||
}
|
||||
|
||||
inline void operator += (const Vector3<T> & a_Rhs)
|
||||
{
|
||||
x += a_Rhs.x;
|
||||
@ -165,6 +174,14 @@ public:
|
||||
z *= a_v;
|
||||
}
|
||||
|
||||
inline Vector3<T> & operator = (const Vector3<T> & a_Rhs)
|
||||
{
|
||||
x = a_Rhs.x;
|
||||
y = a_Rhs.y;
|
||||
z = a_Rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// tolua_begin
|
||||
|
||||
inline Vector3<T> operator + (const Vector3<T>& a_Rhs) const
|
||||
@ -219,7 +236,7 @@ public:
|
||||
*/
|
||||
inline double LineCoeffToXYPlane(const Vector3<T> & a_OtherEnd, T a_Z) const
|
||||
{
|
||||
if (abs(z - a_OtherEnd.z) < EPS)
|
||||
if (Abs(z - a_OtherEnd.z) < EPS)
|
||||
{
|
||||
return NO_INTERSECTION;
|
||||
}
|
||||
@ -234,7 +251,7 @@ public:
|
||||
*/
|
||||
inline double LineCoeffToXZPlane(const Vector3<T> & a_OtherEnd, T a_Y) const
|
||||
{
|
||||
if (abs(y - a_OtherEnd.y) < EPS)
|
||||
if (Abs(y - a_OtherEnd.y) < EPS)
|
||||
{
|
||||
return NO_INTERSECTION;
|
||||
}
|
||||
@ -249,7 +266,7 @@ public:
|
||||
*/
|
||||
inline double LineCoeffToYZPlane(const Vector3<T> & a_OtherEnd, T a_X) const
|
||||
{
|
||||
if (abs(x - a_OtherEnd.x) < EPS)
|
||||
if (Abs(x - a_OtherEnd.x) < EPS)
|
||||
{
|
||||
return NO_INTERSECTION;
|
||||
}
|
||||
@ -263,6 +280,14 @@ public:
|
||||
/** Return value of LineCoeffToPlane() if the line is parallel to the plane. */
|
||||
static const double NO_INTERSECTION;
|
||||
|
||||
protected:
|
||||
|
||||
/** Returns the absolute value of the given argument.
|
||||
Templatized because the standard library differentiates between abs() and fabs(). */
|
||||
static T Abs(T a_Value)
|
||||
{
|
||||
return (a_Value < 0) ? -a_Value : a_Value;
|
||||
}
|
||||
};
|
||||
// tolua_end
|
||||
|
||||
|
@ -394,10 +394,14 @@ void cWorld::InitializeSpawn(void)
|
||||
|
||||
// For the debugging builds, don't make the server build too much world upon start:
|
||||
#if defined(_DEBUG) || defined(ANDROID_NDK)
|
||||
int ViewDist = 9;
|
||||
const int DefaultViewDist = 9;
|
||||
#else
|
||||
int ViewDist = 20; // Always prepare an area 20 chunks across, no matter what the actual cClientHandle::VIEWDISTANCE is
|
||||
const int DefaultViewDist = 20; // Always prepare an area 20 chunks across, no matter what the actual cClientHandle::VIEWDISTANCE is
|
||||
#endif // _DEBUG
|
||||
cIniFile IniFile;
|
||||
IniFile.ReadFile(m_IniFileName);
|
||||
int ViewDist = IniFile.GetValueSetI("SpawnPosition", "PregenerateDistance", DefaultViewDist);
|
||||
IniFile.WriteFile(m_IniFileName);
|
||||
|
||||
LOG("Preparing spawn area in world \"%s\"...", m_WorldName.c_str());
|
||||
for (int x = 0; x < ViewDist; x++)
|
||||
@ -2402,13 +2406,13 @@ bool cWorld::DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_
|
||||
bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCallback & a_Callback)
|
||||
{
|
||||
cPlayer * BestMatch = NULL;
|
||||
unsigned int BestRating = 0;
|
||||
unsigned int NameLength = a_PlayerNameHint.length();
|
||||
size_t BestRating = 0;
|
||||
size_t NameLength = a_PlayerNameHint.length();
|
||||
|
||||
cCSLock Lock(m_CSPlayers);
|
||||
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
unsigned int Rating = RateCompareString (a_PlayerNameHint, (*itr)->GetName());
|
||||
size_t Rating = RateCompareString (a_PlayerNameHint, (*itr)->GetName());
|
||||
if (Rating >= BestRating)
|
||||
{
|
||||
BestMatch = *itr;
|
||||
@ -2422,7 +2426,6 @@ bool cWorld::FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCa
|
||||
|
||||
if (BestMatch != NULL)
|
||||
{
|
||||
LOG("Compared %s and %s with rating %i", a_PlayerNameHint.c_str(), BestMatch->GetName().c_str(), BestRating);
|
||||
return a_Callback.Item (BestMatch);
|
||||
}
|
||||
return false;
|
||||
|
@ -351,7 +351,7 @@ public:
|
||||
/** Is the trapdoor open? Returns false if there is no trapdoor at the specified coords. */
|
||||
bool IsTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export
|
||||
|
||||
/** Set the state of a trapdoor. Returns true if the trapdoor was update, false if there was no trapdoor at those coords. */
|
||||
/** Set the state of a trapdoor. Returns true if the trapdoor was updated, false if there was no trapdoor at those coords. */
|
||||
bool SetTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open); // tolua_export
|
||||
|
||||
/** Regenerate the given chunk: */
|
||||
@ -710,7 +710,9 @@ public:
|
||||
virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) override; // tolua_export
|
||||
int SpawnMobFinalize(cMonster* a_Monster);
|
||||
|
||||
/** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise */
|
||||
/** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise
|
||||
Item parameter used currently for Fireworks to correctly set entity metadata based on item metadata
|
||||
*/
|
||||
int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem & a_Item, const Vector3d * a_Speed = NULL); // tolua_export
|
||||
|
||||
/** Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread! */
|
||||
|
@ -29,7 +29,7 @@
|
||||
// cParsedNBT:
|
||||
|
||||
#define NEEDBYTES(N) \
|
||||
if (m_Length - m_Pos < N) \
|
||||
if (m_Length - m_Pos < (size_t)N) \
|
||||
{ \
|
||||
return false; \
|
||||
}
|
||||
@ -38,7 +38,7 @@
|
||||
|
||||
|
||||
|
||||
cParsedNBT::cParsedNBT(const char * a_Data, int a_Length) :
|
||||
cParsedNBT::cParsedNBT(const char * a_Data, size_t a_Length) :
|
||||
m_Data(a_Data),
|
||||
m_Length(a_Length),
|
||||
m_Pos(0)
|
||||
@ -79,14 +79,14 @@ bool cParsedNBT::Parse(void)
|
||||
|
||||
|
||||
|
||||
bool cParsedNBT::ReadString(int & a_StringStart, int & a_StringLen)
|
||||
bool cParsedNBT::ReadString(size_t & a_StringStart, size_t & a_StringLen)
|
||||
{
|
||||
NEEDBYTES(2);
|
||||
a_StringStart = m_Pos + 2;
|
||||
a_StringLen = GetBEShort(m_Data + m_Pos);
|
||||
if (a_StringLen < 0)
|
||||
a_StringLen = (size_t)GetBEShort(m_Data + m_Pos);
|
||||
if (a_StringLen > 0xffff)
|
||||
{
|
||||
// Invalid string length
|
||||
// Suspicious string length
|
||||
return false;
|
||||
}
|
||||
m_Pos += 2 + a_StringLen;
|
||||
@ -99,8 +99,10 @@ bool cParsedNBT::ReadString(int & a_StringStart, int & a_StringLen)
|
||||
|
||||
bool cParsedNBT::ReadCompound(void)
|
||||
{
|
||||
ASSERT(m_Tags.size() > 0);
|
||||
|
||||
// Reads the latest tag as a compound
|
||||
int ParentIdx = m_Tags.size() - 1;
|
||||
int ParentIdx = (int)m_Tags.size() - 1;
|
||||
int PrevSibling = -1;
|
||||
for (;;)
|
||||
{
|
||||
@ -114,13 +116,13 @@ bool cParsedNBT::ReadCompound(void)
|
||||
m_Tags.push_back(cFastNBTTag(TagType, ParentIdx, PrevSibling));
|
||||
if (PrevSibling >= 0)
|
||||
{
|
||||
m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1;
|
||||
m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1;
|
||||
m_Tags[ParentIdx].m_FirstChild = (int)m_Tags.size() - 1;
|
||||
}
|
||||
PrevSibling = m_Tags.size() - 1;
|
||||
PrevSibling = (int)m_Tags.size() - 1;
|
||||
RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength));
|
||||
RETURN_FALSE_IF_FALSE(ReadTag());
|
||||
} // while (true)
|
||||
@ -146,20 +148,20 @@ bool cParsedNBT::ReadList(eTagType a_ChildrenType)
|
||||
}
|
||||
|
||||
// Read items:
|
||||
int ParentIdx = m_Tags.size() - 1;
|
||||
int ParentIdx = (int)m_Tags.size() - 1;
|
||||
int PrevSibling = -1;
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
m_Tags.push_back(cFastNBTTag(a_ChildrenType, ParentIdx, PrevSibling));
|
||||
if (PrevSibling >= 0)
|
||||
{
|
||||
m_Tags[PrevSibling].m_NextSibling = m_Tags.size() - 1;
|
||||
m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Tags[ParentIdx].m_FirstChild = m_Tags.size() - 1;
|
||||
m_Tags[ParentIdx].m_FirstChild = (int)m_Tags.size() - 1;
|
||||
}
|
||||
PrevSibling = m_Tags.size() - 1;
|
||||
PrevSibling = (int)m_Tags.size() - 1;
|
||||
RETURN_FALSE_IF_FALSE(ReadTag());
|
||||
} // for (i)
|
||||
m_Tags[ParentIdx].m_LastChild = PrevSibling;
|
||||
@ -279,7 +281,7 @@ int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLen
|
||||
for (int Child = m_Tags[a_Tag].m_FirstChild; Child != -1; Child = m_Tags[Child].m_NextSibling)
|
||||
{
|
||||
if (
|
||||
(m_Tags[Child].m_NameLength == (int)a_NameLength) &&
|
||||
(m_Tags[Child].m_NameLength == a_NameLength) &&
|
||||
(memcmp(m_Data + m_Tags[Child].m_NameStart, a_Name, a_NameLength) == 0)
|
||||
)
|
||||
{
|
||||
@ -336,7 +338,7 @@ cFastNBTWriter::cFastNBTWriter(const AString & a_RootTagName) :
|
||||
m_Stack[0].m_Type = TAG_Compound;
|
||||
m_Result.reserve(100 * 1024);
|
||||
m_Result.push_back(TAG_Compound);
|
||||
WriteString(a_RootTagName.data(), a_RootTagName.size());
|
||||
WriteString(a_RootTagName.data(), (UInt16)a_RootTagName.size());
|
||||
}
|
||||
|
||||
|
||||
@ -389,7 +391,7 @@ void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType)
|
||||
|
||||
++m_CurrentStack;
|
||||
m_Stack[m_CurrentStack].m_Type = TAG_List;
|
||||
m_Stack[m_CurrentStack].m_Pos = m_Result.size() - 4;
|
||||
m_Stack[m_CurrentStack].m_Pos = (int)m_Result.size() - 4;
|
||||
m_Stack[m_CurrentStack].m_Count = 0;
|
||||
m_Stack[m_CurrentStack].m_ItemType = a_ChildrenType;
|
||||
}
|
||||
@ -493,7 +495,7 @@ void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value)
|
||||
void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements)
|
||||
{
|
||||
TagCommon(a_Name, TAG_ByteArray);
|
||||
Int32 len = htonl(a_NumElements);
|
||||
u_long len = htonl((u_long)a_NumElements);
|
||||
m_Result.append((const char *)&len, 4);
|
||||
m_Result.append(a_Value, a_NumElements);
|
||||
}
|
||||
@ -505,7 +507,7 @@ void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value,
|
||||
void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, size_t a_NumElements)
|
||||
{
|
||||
TagCommon(a_Name, TAG_IntArray);
|
||||
Int32 len = htonl(a_NumElements);
|
||||
u_long len = htonl((u_long)a_NumElements);
|
||||
size_t cap = m_Result.capacity();
|
||||
size_t size = m_Result.length();
|
||||
if ((cap - size) < (4 + a_NumElements * 4))
|
||||
@ -534,7 +536,7 @@ void cFastNBTWriter::Finish(void)
|
||||
|
||||
|
||||
|
||||
void cFastNBTWriter::WriteString(const char * a_Data, short a_Length)
|
||||
void cFastNBTWriter::WriteString(const char * a_Data, UInt16 a_Length)
|
||||
{
|
||||
Int16 Len = htons(a_Length);
|
||||
m_Result.append((const char *)&Len, 2);
|
||||
|
@ -61,10 +61,10 @@ public:
|
||||
|
||||
// The following members are indices into the data stream. m_DataLength == 0 if no data available
|
||||
// They must not be pointers, because the datastream may be copied into another AString object in the meantime.
|
||||
int m_NameStart;
|
||||
int m_NameLength;
|
||||
int m_DataStart;
|
||||
int m_DataLength;
|
||||
size_t m_NameStart;
|
||||
size_t m_NameLength;
|
||||
size_t m_DataStart;
|
||||
size_t m_DataLength;
|
||||
|
||||
// The following members are indices into the array returned; -1 if not valid
|
||||
// They must not be pointers, because pointers would not survive std::vector reallocation
|
||||
@ -114,7 +114,7 @@ Each primitive tag also stores the length of the contained data, in bytes.
|
||||
class cParsedNBT
|
||||
{
|
||||
public:
|
||||
cParsedNBT(const char * a_Data, int a_Length);
|
||||
cParsedNBT(const char * a_Data, size_t a_Length);
|
||||
|
||||
bool IsValid(void) const {return m_IsValid; }
|
||||
|
||||
@ -135,7 +135,7 @@ public:
|
||||
|
||||
/** Returns the length of the tag's data, in bytes.
|
||||
Not valid for Compound or List tags! */
|
||||
int GetDataLength (int a_Tag) const
|
||||
size_t GetDataLength (int a_Tag) const
|
||||
{
|
||||
ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_List);
|
||||
ASSERT(m_Tags[(size_t)a_Tag].m_Type != TAG_Compound);
|
||||
@ -251,15 +251,15 @@ public:
|
||||
|
||||
protected:
|
||||
const char * m_Data;
|
||||
int m_Length;
|
||||
size_t m_Length;
|
||||
std::vector<cFastNBTTag> m_Tags;
|
||||
bool m_IsValid; // True if parsing succeeded
|
||||
|
||||
// Used while parsing:
|
||||
int m_Pos;
|
||||
size_t m_Pos;
|
||||
|
||||
bool Parse(void);
|
||||
bool ReadString(int & a_StringStart, int & a_StringLen); // Reads a simple string (2 bytes length + data), sets the string descriptors
|
||||
bool ReadString(size_t & a_StringStart, size_t & a_StringLen); // Reads a simple string (2 bytes length + data), sets the string descriptors
|
||||
bool ReadCompound(void); // Reads the latest tag as a compound
|
||||
bool ReadList(eTagType a_ChildrenType); // Reads the latest tag as a list of items of type a_ChildrenType
|
||||
bool ReadTag(void); // Reads the latest tag, depending on its m_Type setting
|
||||
@ -319,7 +319,7 @@ protected:
|
||||
|
||||
bool IsStackTopCompound(void) const { return (m_Stack[m_CurrentStack].m_Type == TAG_Compound); }
|
||||
|
||||
void WriteString(const char * a_Data, short a_Length);
|
||||
void WriteString(const char * a_Data, UInt16 a_Length);
|
||||
|
||||
inline void TagCommon(const AString & a_Name, eTagType a_Type)
|
||||
{
|
||||
@ -330,7 +330,7 @@ protected:
|
||||
{
|
||||
// Compound: add the type and name:
|
||||
m_Result.push_back((char)a_Type);
|
||||
WriteString(a_Name.c_str(), (short)a_Name.length());
|
||||
WriteString(a_Name.c_str(), (UInt16)a_Name.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -96,7 +96,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB
|
||||
if (ExplosionName == "Colors")
|
||||
{
|
||||
// Divide by four as data length returned in bytes
|
||||
int DataLength = a_NBT.GetDataLength(explosiontag);
|
||||
size_t DataLength = a_NBT.GetDataLength(explosiontag);
|
||||
// round to the next highest multiple of four
|
||||
DataLength -= DataLength % 4;
|
||||
if (DataLength == 0)
|
||||
@ -105,14 +105,14 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB
|
||||
}
|
||||
|
||||
const char * ColourData = (a_NBT.GetData(explosiontag));
|
||||
for (int i = 0; i < DataLength; i += 4 /* Size of network int*/)
|
||||
for (size_t i = 0; i < DataLength; i += 4)
|
||||
{
|
||||
a_FireworkItem.m_Colours.push_back(GetBEInt(ColourData + i));
|
||||
}
|
||||
}
|
||||
else if (ExplosionName == "FadeColors")
|
||||
{
|
||||
int DataLength = a_NBT.GetDataLength(explosiontag) / 4;
|
||||
size_t DataLength = a_NBT.GetDataLength(explosiontag) / 4;
|
||||
// round to the next highest multiple of four
|
||||
DataLength -= DataLength % 4;
|
||||
if (DataLength == 0)
|
||||
@ -121,7 +121,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB
|
||||
}
|
||||
|
||||
const char * FadeColourData = (a_NBT.GetData(explosiontag));
|
||||
for (int i = 0; i < DataLength; i += 4 /* Size of network int*/)
|
||||
for (size_t i = 0; i < DataLength; i += 4)
|
||||
{
|
||||
a_FireworkItem.m_FadeColours.push_back(GetBEInt(FadeColourData + i));
|
||||
}
|
||||
|
@ -152,6 +152,10 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT)
|
||||
if (CurrLine >= 0)
|
||||
{
|
||||
unsigned int Width = a_NBT.GetShort(CurrLine);
|
||||
if (Width != 128)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_Map->m_Width = Width;
|
||||
}
|
||||
|
||||
@ -159,6 +163,10 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT)
|
||||
if (CurrLine >= 0)
|
||||
{
|
||||
unsigned int Height = a_NBT.GetShort(CurrLine);
|
||||
if (Height >= 256)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_Map->m_Height = Height;
|
||||
}
|
||||
|
||||
|
@ -96,10 +96,35 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin
|
||||
m_Writer.AddByte ("Slot", (unsigned char)a_Slot);
|
||||
}
|
||||
|
||||
// Write the enchantments:
|
||||
if (!a_Item.m_Enchantments.IsEmpty() || ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)))
|
||||
// Write the tag compound (for enchantment, firework, custom name and repair cost):
|
||||
if (
|
||||
(!a_Item.m_Enchantments.IsEmpty()) ||
|
||||
((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) ||
|
||||
(a_Item.m_RepairCost > 0) ||
|
||||
(a_Item.m_CustomName != "") ||
|
||||
(a_Item.m_Lore != "")
|
||||
)
|
||||
{
|
||||
m_Writer.BeginCompound("tag");
|
||||
if (a_Item.m_RepairCost > 0)
|
||||
{
|
||||
m_Writer.AddInt("RepairCost", a_Item.m_RepairCost);
|
||||
}
|
||||
|
||||
if ((a_Item.m_CustomName != "") || (a_Item.m_Lore != ""))
|
||||
{
|
||||
m_Writer.BeginCompound("display");
|
||||
if (a_Item.m_CustomName != "")
|
||||
{
|
||||
m_Writer.AddString("Name", a_Item.m_CustomName);
|
||||
}
|
||||
if (a_Item.m_Lore != "")
|
||||
{
|
||||
m_Writer.AddString("Lore", a_Item.m_Lore);
|
||||
}
|
||||
m_Writer.EndCompound();
|
||||
}
|
||||
|
||||
if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR))
|
||||
{
|
||||
cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, m_Writer, (ENUM_ITEM_ID)a_Item.m_ItemType);
|
||||
@ -490,7 +515,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
|
||||
}
|
||||
case cMonster::mtMagmaCube:
|
||||
{
|
||||
m_Writer.AddByte("Size", ((const cMagmaCube *)a_Monster)->GetSize());
|
||||
m_Writer.AddInt("Size", ((const cMagmaCube *)a_Monster)->GetSize());
|
||||
break;
|
||||
}
|
||||
case cMonster::mtSheep:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user