diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/BlockArea.cpp | 2 | ||||
-rw-r--r-- | src/ChunkMap.cpp | 4 | ||||
-rw-r--r-- | src/ChunkMap.h | 6 | ||||
-rw-r--r-- | src/ClientHandle.cpp | 31 | ||||
-rw-r--r-- | src/ClientHandle.h | 4 | ||||
-rw-r--r-- | src/Mobs/Monster.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Sheep.cpp | 49 | ||||
-rw-r--r-- | src/Mobs/Sheep.h | 19 | ||||
-rw-r--r-- | src/Server.cpp | 2 | ||||
-rw-r--r-- | src/WorldStorage/WSSAnvil.cpp | 15 |
10 files changed, 85 insertions, 49 deletions
diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 185582ba3..0e4c42f0f 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -59,7 +59,7 @@ void InternalMergeBlocks( } else { - BLOCKTYPE FakeDestMeta = 0; + NIBBLETYPE FakeDestMeta = 0; Combinator(a_DstTypes[DstIdx], a_SrcTypes[SrcIdx], FakeDestMeta, (NIBBLETYPE)0); } ++DstIdx; diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 35d55d396..4040fff9f 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1278,7 +1278,7 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP -void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients) +void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients) { cChunkInterface ChunkInterface(this); if (a_BlockType == E_BLOCK_AIR) @@ -1303,7 +1303,7 @@ void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a -void cChunkMap::QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType) +void cChunkMap::QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType) { int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 4daa85ebd..973d0d219 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -154,9 +154,9 @@ public: NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ); NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ); NIBBLETYPE GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ); - void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockMeta); - void SetBlock (cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); - void QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType = E_BLOCK_AIR); + void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockMeta); + void SetBlock (cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true); + void QueueSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Int64 a_Tick, BLOCKTYPE a_PreviousBlockType = E_BLOCK_AIR); bool GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); bool GetBlockInfo (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index efa734b44..56275a9b2 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -40,9 +40,6 @@ /** Maximum number of block change interactions a player can perform per tick - exceeding this causes a kick */ #define MAX_BLOCK_CHANGE_INTERACTIONS 20 -/** How many ticks before the socket is closed after the client is destroyed (#31) */ -static const int TICKS_BEFORE_CLOSE = 20; - @@ -79,7 +76,6 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_PingID(1), m_BlockDigAnimStage(-1), m_HasStartedDigging(false), - m_TicksSinceDestruction(0), m_State(csConnected), m_ShouldCheckDownloaded(false), m_NumExplosionsThisTick(0), @@ -104,7 +100,7 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : cClientHandle::~cClientHandle() { - ASSERT(m_State >= csDestroyedWaiting); // Has Destroy() been called? + ASSERT(m_State == csDestroyed); // Has Destroy() been called? LOGD("Deleting client \"%s\" at %p", GetUsername().c_str(), this); @@ -169,7 +165,7 @@ void cClientHandle::Destroy(void) RemoveFromAllChunks(); m_Player->GetWorld()->RemoveClientFromChunkSender(this); } - m_State = csDestroyedWaiting; + m_State = csDestroyed; } @@ -1823,18 +1819,7 @@ bool cClientHandle::CheckBlockInteractionsRate(void) void cClientHandle::Tick(float a_Dt) -{ - // Handle clients that are waiting for final close while destroyed: - if (m_State == csDestroyedWaiting) - { - m_TicksSinceDestruction += 1; // This field is misused for the timeout counting - if (m_TicksSinceDestruction > TICKS_BEFORE_CLOSE) - { - m_State = csDestroyed; - } - return; - } - +{ // Process received network data: AString IncomingData; { @@ -1900,15 +1885,7 @@ void cClientHandle::Tick(float a_Dt) void cClientHandle::ServerTick(float a_Dt) -{ - // Handle clients that are waiting for final close while destroyed: - if (m_State == csDestroyedWaiting) - { - // Do not wait while the client is not in the world, simply cut them off. - m_State = csDestroyed; - return; - } - +{ // Process received network data: AString IncomingData; { diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 6f2c86b27..b0bbda19e 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -325,9 +325,6 @@ private: int m_LastDigBlockX; int m_LastDigBlockY; int m_LastDigBlockZ; - - /** Used while csDestroyedWaiting for counting the ticks until the connection is closed */ - int m_TicksSinceDestruction; enum eState { @@ -338,7 +335,6 @@ private: csConfirmingPos, ///< The client has been sent the position packet, waiting for them to repeat the position back csPlaying, ///< Normal gameplay csDestroying, ///< The client is being destroyed, don't queue any more packets / don't add to chunks - csDestroyedWaiting, ///< The client has been destroyed, but is still kept so that the Kick packet is delivered (#31) csDestroyed, ///< The client has been destroyed, the destructor is to be called from the owner thread // TODO: Add Kicking here as well diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index aaef7580d..6acebde87 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -900,7 +900,7 @@ cMonster * cMonster::NewMonsterFromType(cMonster::eType a_MobType) case mtMooshroom: toReturn = new cMooshroom(); break; case mtOcelot: toReturn = new cOcelot(); break; case mtPig: toReturn = new cPig(); break; - case mtSheep: toReturn = new cSheep (Random.NextInt(15)); break; // Colour parameter + case mtSheep: toReturn = new cSheep(); break; case mtSilverfish: toReturn = new cSilverfish(); break; case mtSnowGolem: toReturn = new cSnowGolem(); break; case mtSpider: toReturn = new cSpider(); break; diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 5a6b760af..e208aa891 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -5,6 +5,7 @@ #include "../BlockID.h" #include "../Entities/Player.h" #include "../World.h" +#include "FastRandom.h" @@ -16,6 +17,16 @@ cSheep::cSheep(int a_Color) : m_WoolColor(a_Color), m_TimeToStopEating(-1) { + // Generate random wool color. + if (m_WoolColor == -1) + { + m_WoolColor = GenerateNaturalRandomColor(); + } + + if ((m_WoolColor < 0) || (m_WoolColor > 15)) + { + m_WoolColor = 0; + } } @@ -37,7 +48,7 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cSheep::OnRightClicked(cPlayer & a_Player) { const cItem & EquippedItem = a_Player.GetEquippedItem(); - if ((EquippedItem.m_ItemType == E_ITEM_SHEARS) && (!m_IsSheared)) + if ((EquippedItem.m_ItemType == E_ITEM_SHEARS) && !IsSheared() && !IsBaby()) { m_IsSheared = true; m_World->BroadcastEntityMetadata(*this); @@ -51,6 +62,7 @@ void cSheep::OnRightClicked(cPlayer & a_Player) int NumDrops = m_World->GetTickRandomNumber(2) + 1; Drops.push_back(cItem(E_BLOCK_WOOL, NumDrops, m_WoolColor)); m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); + m_World->BroadcastSoundEffect("mob.sheep.shear", POSX_TOINT * 8, POSY_TOINT * 8, POSZ_TOINT * 8, 1.0f, 1.0f); } else if ((EquippedItem.m_ItemType == E_ITEM_DYE) && (m_WoolColor != 15 - EquippedItem.m_ItemDamage)) { @@ -109,3 +121,38 @@ void cSheep::Tick(float a_Dt, cChunk & a_Chunk) } } + + + + +NIBBLETYPE cSheep::GenerateNaturalRandomColor(void) +{ + cFastRandom Random; + int Chance = Random.NextInt(101); + + if (Chance <= 81) + { + return E_META_WOOL_WHITE; + } + else if (Chance <= 86) + { + return E_META_WOOL_BLACK; + } + else if (Chance <= 91) + { + return E_META_WOOL_GRAY; + } + else if (Chance <= 96) + { + return E_META_WOOL_LIGHTGRAY; + } + else if (Chance <= 99) + { + return E_META_WOOL_BROWN; + } + else + { + return E_META_WOOL_PINK; + } +} + diff --git a/src/Mobs/Sheep.h b/src/Mobs/Sheep.h index 402e8e61c..5ffd3e4fe 100644 --- a/src/Mobs/Sheep.h +++ b/src/Mobs/Sheep.h @@ -13,21 +13,32 @@ class cSheep : typedef cPassiveMonster super; public: - cSheep(int a_Color); - + + /** The number is the color of the sheep. + Use E_META_WOOL_* constants for the wool color. + If you type -1, the server will generate a random color + with the GenerateNaturalRandomColor() function. */ + cSheep(int a_Color = -1); + CLASS_PROTODEF(cSheep); - + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void OnRightClicked(cPlayer & a_Player) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_WHEAT); } + /** Generates a random color for the sheep like the vanilla server. + The percent's where used are from the wiki: http://minecraft.gamepedia.com/Sheep#Breeding */ + static NIBBLETYPE GenerateNaturalRandomColor(void); + bool IsSheared(void) const { return m_IsSheared; } + void SetSheared(bool a_IsSheared) { m_IsSheared = a_IsSheared; } + int GetFurColor(void) const { return m_WoolColor; } + void SetFurColor(int a_WoolColor) { m_WoolColor = a_WoolColor; } private: - bool m_IsSheared; int m_WoolColor; int m_TimeToStopEating; diff --git a/src/Server.cpp b/src/Server.cpp index 5d1e51036..9220731eb 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -221,14 +221,12 @@ bool cServer::InitServer(cIniFile & a_SettingsIni) bool HasAnyPorts = false; AString Ports = a_SettingsIni.GetValueSet("Server", "Port", "25565"); - m_ListenThreadIPv4.SetReuseAddr(true); if (m_ListenThreadIPv4.Initialize(Ports)) { HasAnyPorts = true; } Ports = a_SettingsIni.GetValueSet("Server", "PortsIPv6", "25565"); - m_ListenThreadIPv6.SetReuseAddr(true); if (m_ListenThreadIPv6.Initialize(Ports)) { HasAnyPorts = true; diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index fb2aebbf5..0b2a4c053 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -2086,10 +2086,11 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { int ColorIdx = a_NBT.FindChildByName(a_TagIdx, "Color"); - - if (ColorIdx < 0) { return; } - - int Color = (int)a_NBT.GetByte(ColorIdx); + int Color = -1; + if (ColorIdx > 0) + { + Color = (int)a_NBT.GetByte(ColorIdx); + } std::auto_ptr<cSheep> Monster(new cSheep(Color)); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) @@ -2102,6 +2103,12 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ return; } + int ShearedIdx = a_NBT.FindChildByName(a_TagIdx, "Sheared"); + if (ShearedIdx > 0) + { + Monster->SetSheared(a_NBT.GetByte(ShearedIdx) != 0); + } + a_Entities.push_back(Monster.release()); } |