1
0
Fork 0

Merge branch 'master' into chunksparsing/structs

Conflicts:
	src/Chunk.h
This commit is contained in:
Tycho 2014-05-10 05:05:44 -07:00
commit d478e3cfb1
105 changed files with 2020 additions and 958 deletions

@ -1 +1 @@
Subproject commit 013a32a7fb3c8a6cfe0aef892d4c7394d4e1be59
Subproject commit 5c8557d4fdfa580c100510cde07a1a778ea2e244

View File

@ -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

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -23,6 +23,13 @@ public:
{
a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta >> 2));
}
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(

View File

@ -39,6 +39,13 @@ public:
}
virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
{
return true;
}
// Bed specific helper functions
static NIBBLETYPE RotationToMetaData(double a_Rotation)
{

View File

@ -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))
{

View File

@ -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) ||

View File

@ -68,7 +68,6 @@ public:
{
return 0;
}
for (int newY = Y + 1; newY < cChunkDef::Height; newY++)
{
@ -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);
}
};

View File

@ -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;
}
} ;

View File

@ -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;

View File

@ -85,6 +85,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(...)

View File

@ -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;
}

View File

@ -97,6 +97,12 @@ public:
return "";
}
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)

View File

@ -77,6 +77,11 @@ public:
// Reset meta to 0
a_Pickups.push_back(cItem(m_BlockType, 1, 0));
}
virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
{
return true;
}
static NIBBLETYPE RotationToMetaData(double a_Rotation)
{

View File

@ -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)
{

View File

@ -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);
}
}

View File

@ -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",

View File

@ -385,6 +385,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

View File

@ -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
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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))
{

View File

@ -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,9 +1017,9 @@ 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;
return;
@ -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();
}
// Have to process position related packets this every two ticks
if (m_World->GetWorldAge() % 2 == 0)
{
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)))
double SpeedSqr = GetSpeed().SqrLength();
if (SpeedSqr == 0.0)
{
//
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;
// 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
{
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)
// Movin'
m_World->BroadcastEntityVelocity(*this, a_Exclude);
m_bHasSentNoSpeed = false;
}
// 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?
{
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);
m_bDirtyOrientation = false;
}
}
// 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;
}
@ -1472,8 +1477,7 @@ 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;
m_Speed.z += a_AddSpeedZ;
WrapSpeed();
}
@ -1483,8 +1487,7 @@ 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;
m_Speed.x += a_AddSpeedX;
WrapSpeed();
}
@ -1494,8 +1497,7 @@ void cEntity::AddSpeedX(double a_AddSpeedX)
void cEntity::AddSpeedY(double a_AddSpeedY)
{
m_Speed.y += a_AddSpeedY;
m_bDirtySpeed = true;
m_Speed.y += a_AddSpeedY;
WrapSpeed();
}
@ -1505,8 +1507,7 @@ void cEntity::AddSpeedY(double a_AddSpeedY)
void cEntity::AddSpeedZ(double a_AddSpeedZ)
{
m_Speed.z += a_AddSpeedZ;
m_bDirtySpeed = true;
m_Speed.z += a_AddSpeedZ;
WrapSpeed();
}
@ -1561,8 +1562,7 @@ Vector3d cEntity::GetLookVector(void) const
// Set position
void cEntity::SetPosition(double a_PosX, double a_PosY, double a_PosZ)
{
m_Pos.Set(a_PosX, a_PosY, a_PosZ);
m_bDirtyPosition = true;
m_Pos.Set(a_PosX, a_PosY, a_PosZ);
}
@ -1571,8 +1571,7 @@ 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;
m_Pos.x = a_PosX;
}
@ -1581,8 +1580,7 @@ void cEntity::SetPosX(double a_PosX)
void cEntity::SetPosY(double a_PosY)
{
m_Pos.y = a_PosY;
m_bDirtyPosition = true;
m_Pos.y = a_PosY;
}
@ -1592,7 +1590,6 @@ void cEntity::SetPosY(double a_PosY)
void cEntity::SetPosZ(double a_PosZ)
{
m_Pos.z = a_PosZ;
m_bDirtyPosition = true;
}

View File

@ -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.
bool m_bDirtyHead;
bool m_bDirtyOrientation;
bool m_bDirtyPosition;
bool m_bDirtySpeed;
bool m_bOnGround;
float m_Gravity;
/** Stores whether head yaw has been set manually */
bool m_bDirtyHead;
// Last Position.
double m_LastPosX, m_LastPosY, m_LastPosZ;
/** 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;
// This variables keep track of the last time a packet was sent
Int64 m_TimeLastTeleportPacket, m_TimeLastMoveReltPacket, m_TimeLastSpeedPacket; // In ticks
/** 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 sent to client via the Relative Move or Teleport packets (not Velocity)
Only updated if cEntity::BroadcastMovementUpdate() is called! */
Vector3d m_LastPos;
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);

View File

@ -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;
}

View File

@ -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();
}

View File

@ -76,11 +76,8 @@ 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);
}
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"];
@ -1860,17 +1851,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();

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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.

View File

@ -174,44 +174,47 @@ 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)
int MaxX = Image.GetSizeX();
int MaxZ = Image.GetSizeZ();
for (int z = 0; z < MaxZ; z++)
if (m_ShouldExtendFloor)
{
int RelZ = Placement.z + z;
if ((RelZ < 0) || (RelZ >= cChunkDef::Width))
int MaxX = Image.GetSizeX();
int MaxZ = Image.GetSizeZ();
for (int z = 0; z < MaxZ; z++)
{
// Z coord outside the chunk
continue;
}
for (int x = 0; x < MaxX; x++)
{
int RelX = Placement.x + x;
if ((RelX < 0) || (RelX >= cChunkDef::Width))
int RelZ = Placement.z + z;
if ((RelZ < 0) || (RelZ >= cChunkDef::Width))
{
// X coord outside the chunk
// Z coord outside the chunk
continue;
}
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
Image.GetRelBlockTypeMeta(x, 0, z, BlockType, BlockMeta);
if ((BlockType == E_BLOCK_AIR) || (BlockType == E_BLOCK_SPONGE))
for (int x = 0; x < MaxX; x++)
{
// Do not expand air nor sponge blocks
continue;
}
for (int y = Placement.y - 1; y >= 0; y--)
{
BLOCKTYPE ExistingBlock = a_Dest.GetBlockType(RelX, y, RelZ);
if (ExistingBlock != E_BLOCK_AIR)
int RelX = Placement.x + x;
if ((RelX < 0) || (RelX >= cChunkDef::Width))
{
// End the expansion for this column, reached the end
break;
// X coord outside the chunk
continue;
}
a_Dest.SetBlockTypeMeta(RelX, y, RelZ, BlockType, BlockMeta);
} // for y
} // for x
} // for z
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
Image.GetRelBlockTypeMeta(x, 0, z, BlockType, BlockMeta);
if ((BlockType == E_BLOCK_AIR) || (BlockType == E_BLOCK_SPONGE))
{
// Do not expand air nor sponge blocks
continue;
}
for (int y = Placement.y - 1; y >= 0; y--)
{
BLOCKTYPE ExistingBlock = a_Dest.GetBlockType(RelX, y, RelZ);
if (ExistingBlock != E_BLOCK_AIR)
{
// End the expansion for this column, reached the end
break;
}
a_Dest.SetBlockTypeMeta(RelX, y, RelZ, BlockType, BlockMeta);
} // for y
} // for x
} // for z
}
}

View File

@ -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,

View File

@ -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;

View File

@ -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++)
{

View File

@ -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++ )
{
if (!ExistsGroup(Split[i]))
{
LOGWARNING("The group %s for player %s was not found!", Split[i].c_str(), Player.c_str());
}
}
continue;
}
}
AStringVector Split = StringSplitAndTrim(Groups, ",");
for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr)
{
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", "-");

View File

@ -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)

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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;
}
@ -190,14 +195,15 @@ public:
// tolua_begin
short m_ItemType;
char m_ItemCount;
short m_ItemDamage;
cEnchantments m_Enchantments;
AString m_CustomName;
AString m_Lore;
short m_ItemType;
char m_ItemCount;
short m_ItemDamage;
cEnchantments m_Enchantments;
AString m_CustomName;
AString m_Lore;
cFireworkItem m_FireworkItem;
int m_RepairCost;
cFireworkItem m_FireworkItem;
};
// tolua_end

View File

@ -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;
}
} ;

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -78,7 +78,7 @@ public:
}
return true;
}
} ;

View File

@ -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;
}
} ;

View File

@ -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;
}
};

View File

@ -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;
}
} ;

View File

@ -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())
{

View File

@ -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();

View File

@ -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();
}

View File

@ -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; }

View File

@ -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())
{

View File

@ -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);

View File

@ -64,7 +64,7 @@ void cMobCensus::CollectSpawnableChunk(cChunk & a_Chunk)
int cMobCensus::GetNumChunks(void)
{
return m_EligibleForSpawnChunks.size();
return (int)m_EligibleForSpawnChunks.size();
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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));
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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)
{

View File

@ -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";

View File

@ -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());
}

View File

@ -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;

View File

@ -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:

View File

@ -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;
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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];
}

View File

@ -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:

View File

@ -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
{

View File

@ -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:

View File

@ -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;

View File

@ -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,8 +174,16 @@ public:
z *= a_v;
}
// tolua_begin
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
{
return Vector3<T>(
@ -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;
}
@ -262,7 +279,15 @@ 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

View File

@ -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;

View File

@ -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! */

View File

@ -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);

View File

@ -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
{

View File

@ -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));
}

View File

@ -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;
}

Some files were not shown because too many files have changed in this diff Show More