From 95be80cdb5322720e7c9fbd13ec2692288afd931 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 14 Dec 2013 16:52:22 +0000 Subject: [PATCH 01/51] Implemented note block playing and fixed wire Game of Thrones music in Minecraft, here I come! --- src/Bindings/ManualBindings.cpp | 2 ++ src/Chunk.cpp | 32 ++++++++++++++++++ src/Chunk.h | 6 +++- src/ChunkMap.cpp | 17 ++++++++++ src/ChunkMap.h | 5 +++ src/Simulator/RedstoneSimulator.cpp | 52 ++++++++++++++++++++++++++--- src/Simulator/RedstoneSimulator.h | 2 ++ src/World.cpp | 9 +++++ src/World.h | 5 +++ 9 files changed, 125 insertions(+), 5 deletions(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 4f7e1470a..2e19c2581 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -18,6 +18,7 @@ #include "../BlockEntities/DropperEntity.h" #include "../BlockEntities/FurnaceEntity.h" #include "../BlockEntities/HopperEntity.h" +#include "../BlockEntities/NoteEntity.h" #include "md5/md5.h" #include "../LineBlockTracer.h" @@ -2217,6 +2218,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "DoWithDropperAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithEntityByID", tolua_DoWithID< cWorld, cEntity, &cWorld::DoWithEntityByID>); tolua_function(tolua_S, "DoWithFurnaceAt", tolua_DoWithXYZ); + tolua_function(tolua_S, "DoWithNoteBlockAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>); tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk); diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 42969bf6d..b3c1896dc 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2225,6 +2225,38 @@ bool cChunk::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceC +bool cChunk::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback) +{ + // The blockentity list is locked by the parent chunkmap's CS + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2) + { + ++itr2; + if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ)) + { + continue; + } + if ((*itr)->GetBlockType() != E_BLOCK_NOTE_BLOCK) + { + // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out + return false; + } + + // The correct block entity is here, + if (a_Callback.Item((cNoteEntity *)*itr)) + { + return false; + } + return true; + } // for itr - m_BlockEntitites[] + + // Not found: + return false; +} + + + + + bool cChunk::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) { // The blockentity list is locked by the parent chunkmap's CS diff --git a/src/Chunk.h b/src/Chunk.h index 9e5d117c5..a5bc9863b 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -35,7 +35,6 @@ namespace Json class cWorld; -class cFurnaceEntity; class cClientHandle; class cServer; class MTRand; @@ -44,6 +43,7 @@ class cChunkMap; class cChestEntity; class cDispenserEntity; class cFurnaceEntity; +class cNoteEntity; class cBlockArea; class cPawn; class cPickup; @@ -58,6 +58,7 @@ typedef cItemCallback cEntityCallback; typedef cItemCallback cChestCallback; typedef cItemCallback cDispenserCallback; typedef cItemCallback cFurnaceCallback; +typedef cItemCallback cNoteBlockCallback; @@ -246,6 +247,9 @@ public: /// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible + /// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found + bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); + /// Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index cb722af3b..f2195741d 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1899,6 +1899,23 @@ bool cChunkMap::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurna +bool cChunkMap::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback) +{ + int ChunkX, ChunkZ; + int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; + cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk == NULL) && !Chunk->IsValid()) + { + return false; + } + return Chunk->DoWithNoteBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); +} + + + + bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) { diff --git a/src/ChunkMap.h b/src/ChunkMap.h index ef070194b..f079c9a1b 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -22,6 +22,7 @@ class cDispenserEntity; class cDropperEntity; class cDropSpenserEntity; class cFurnaceEntity; +class cNoteEntity; class cPawn; class cPickup; class cChunkDataSerializer; @@ -38,6 +39,7 @@ typedef cItemCallback cDispenserCallback; typedef cItemCallback cDropperCallback; typedef cItemCallback cDropSpenserCallback; typedef cItemCallback cFurnaceCallback; +typedef cItemCallback cNoteBlockCallback; typedef cItemCallback cChunkCallback; @@ -228,6 +230,9 @@ public: /// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Lua-accessible + /// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found + bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Lua-accessible + /// Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index f61e1c63b..e1ffaf30f 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -3,6 +3,7 @@ #include "RedstoneSimulator.h" #include "../BlockEntities/DropSpenserEntity.h" +#include "../BlockEntities/NoteEntity.h" #include "../Entities/TNTEntity.h" #include "../Blocks/BlockTorch.h" #include "../Blocks/BlockDoor.h" @@ -196,6 +197,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c case E_BLOCK_TNT: HandleTNT(a_X, dataitr->y, a_Z); break; case E_BLOCK_TRAPDOOR: HandleTrapdoor(a_X, dataitr->y, a_Z); break; case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(a_X, dataitr->y, a_Z); break; + case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(a_X, dataitr->y, a_Z); break; case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_ON: @@ -459,12 +461,12 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl } } - // Wire still powered, power blocks beneath - SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE); - if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire { + // Wire still powered, power blocks beneath + SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE); + switch (GetWireDirection(a_BlockX, a_BlockY, a_BlockZ)) { case REDSTONE_NONE: @@ -821,6 +823,48 @@ void cRedstoneSimulator::HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ +void cRedstoneSimulator::HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + bool m_bAreCoordsPowered = AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ); + + if (m_bAreCoordsPowered) + { + if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, true)) + { + class cSetPowerToNoteBlock : + public cNoteBlockCallback + { + bool m_IsPowered; + public: + cSetPowerToNoteBlock(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} + + virtual bool Item(cNoteEntity * a_NoteBlock) override + { + if (m_IsPowered) + { + a_NoteBlock->MakeSound(); + } + return false; + } + } NoteBlockSP(m_bAreCoordsPowered); + + m_World.DoWithNoteBlockAt(a_BlockX, a_BlockY, a_BlockZ, NoteBlockSP); + SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, true); + } + } + else + { + if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, false)) + { + SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, false); + } + } +} + + + + + bool cRedstoneSimulator::AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index 23ac510fc..9bdeb8f32 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -112,6 +112,8 @@ private: void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType); /// Handles trapdoors void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ); + /// Handles noteblocks + void HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ); /* ===================== */ /* ====== Helper functions ====== */ diff --git a/src/World.cpp b/src/World.cpp index 564905d33..9ec389be9 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1129,6 +1129,15 @@ bool cWorld::DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceC +bool cWorld::DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback) +{ + return m_ChunkMap->DoWithNoteBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); +} + + + + + bool cWorld::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) { return m_ChunkMap->GetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4); diff --git a/src/World.h b/src/World.h index fc821a68a..5cd8b41b6 100644 --- a/src/World.h +++ b/src/World.h @@ -42,6 +42,7 @@ class cChunkGenerator; // The thread responsible for generating chunks class cChestEntity; class cDispenserEntity; class cFurnaceEntity; +class cNoteEntity; class cMobCensus; typedef std::list< cPlayer * > cPlayerList; @@ -51,6 +52,7 @@ typedef cItemCallback cEntityCallback; typedef cItemCallback cChestCallback; typedef cItemCallback cDispenserCallback; typedef cItemCallback cFurnaceCallback; +typedef cItemCallback cNoteBlockCallback; @@ -444,6 +446,9 @@ public: /// Calls the callback for the furnace at the specified coords; returns false if there's no furnace at those coords or callback returns true, returns true if found bool DoWithFurnaceAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFurnaceCallback & a_Callback); // Exported in ManualBindings.cpp + + /// Calls the callback for the noteblock at the specified coords; returns false if there's no noteblock at those coords or callback returns true, returns true if found + bool DoWithNoteBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cNoteBlockCallback & a_Callback); // Exported in ManualBindings.cpp /// Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Exported in ManualBindings.cpp From 37069288d5801acce0ad34878a78aa0daf004135 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 14 Dec 2013 18:03:00 +0100 Subject: [PATCH 02/51] Added SendEntityEffect and SendRemoveEntityEffect. Also a Player now gets the hunger effect when he has food poison. --- src/Entities/Player.cpp | 10 +++++++++- src/Protocol/Protocol.h | 2 ++ src/Protocol/Protocol125.cpp | 30 +++++++++++++++++++++++++++++ src/Protocol/Protocol125.h | 2 ++ src/Protocol/Protocol17x.cpp | 24 +++++++++++++++++++++++ src/Protocol/Protocol17x.h | 2 ++ src/Protocol/ProtocolRecognizer.cpp | 20 +++++++++++++++++++ src/Protocol/ProtocolRecognizer.h | 2 ++ 8 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 85833f31d..20c4818b2 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -557,9 +557,13 @@ void cPlayer::FoodPoison(int a_NumTicks) m_FoodPoisonedTicksRemaining = std::max(m_FoodPoisonedTicksRemaining, a_NumTicks); if (!HasBeenFoodPoisoned) { - // TODO: Send the poisoning indication to the client - how? + m_ClientHandle->SendRemoveEntityEffect(*this, 17); SendHealth(); } + else + { + m_ClientHandle->SendEntityEffect(*this, 17, 0, 20); + } } @@ -1704,6 +1708,10 @@ void cPlayer::HandleFood(void) m_FoodPoisonedTicksRemaining--; m_FoodExhaustionLevel += 0.025; // 0.5 per second = 0.025 per tick } + else + { + m_ClientHandle->SendRemoveEntityEffect(*this, 17); // remove the "Hunger" effect. + } // Apply food exhaustion that has accumulated: if (m_FoodExhaustionLevel >= 4) diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index ff6541aeb..d90ece2b0 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -62,6 +62,7 @@ public: virtual void SendDestroyEntity (const cEntity & a_Entity) = 0; virtual void SendDisconnect (const AString & a_Reason) = 0; virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) = 0; virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) = 0; virtual void SendEntityHeadLook (const cEntity & a_Entity) = 0; virtual void SendEntityLook (const cEntity & a_Entity) = 0; @@ -85,6 +86,7 @@ public: virtual void SendPlayerMoveLook (void) = 0; virtual void SendPlayerPosition (void) = 0; virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0; + virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0; virtual void SendRespawn (void) = 0; virtual void SendExperience (void) = 0; virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 9334e6f2d..d4c1f0dd5 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -43,6 +43,8 @@ enum PACKET_HANDSHAKE = 0x02, PACKET_CHAT = 0x03, PACKET_UPDATE_TIME = 0x04, + PACKET_ENTITY_EFFECT = 0x1D, + PACKET_REMOVE_ENTITY_EFFECT = 0x1E, PACKET_ENTITY_EQUIPMENT = 0x05, PACKET_USE_ENTITY = 0x07, PACKET_UPDATE_HEALTH = 0x08, @@ -300,6 +302,21 @@ void cProtocol125::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) +void cProtocol125::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) +{ + cCSLock Lock(m_CSPacket); + WriteByte (PACKET_ENTITY_EFFECT); + WriteInt (a_Entity.GetUniqueID()); + WriteByte (a_EffectID); + WriteByte (a_Amplifier); + WriteShort(a_Duration); + Flush(); +} + + + + + void cProtocol125::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) { cCSLock Lock(m_CSPacket); @@ -678,6 +695,19 @@ void cProtocol125::SendPlayerSpawn(const cPlayer & a_Player) +void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) +{ + cCSLock Lock(m_CSPacket); + WriteByte (PACKET_REMOVE_ENTITY_EFFECT); + WriteInt (a_Entity.GetUniqueID()); + WriteByte (a_EffectID); + Flush(); +} + + + + + void cProtocol125::SendRespawn(void) { cCSLock Lock(m_CSPacket); diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 32efef4e8..ebbcd762a 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -38,6 +38,7 @@ public: virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendDisconnect (const AString & a_Reason) override; virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; virtual void SendEntityHeadLook (const cEntity & a_Entity) override; virtual void SendEntityLook (const cEntity & a_Entity) override; @@ -61,6 +62,7 @@ public: virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; virtual void SendPlayerSpawn (const cPlayer & a_Player) override; + virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; virtual void SendRespawn (void) override; virtual void SendExperience (void) override; virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index bfb38904c..a05efb562 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -236,6 +236,19 @@ void cProtocol172::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) +void cProtocol172::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) +{ + cPacketizer Pkt(*this, 0x1D); // Entity Effect packet + Pkt.WriteInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_EffectID); + Pkt.WriteByte(a_Amplifier); + Pkt.WriteShort(a_Duration); +} + + + + + void cProtocol172::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) { cPacketizer Pkt(*this, 0x04); // Entity Equipment packet @@ -585,6 +598,17 @@ void cProtocol172::SendPlayerSpawn(const cPlayer & a_Player) +void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) +{ + cPacketizer Pkt(*this, 0x1E); + Pkt.WriteInt(a_Entity.GetUniqueID()); + Pkt.WriteByte(a_EffectID); +} + + + + + void cProtocol172::SendRespawn(void) { cPacketizer Pkt(*this, 0x07); // Respawn packet diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index b8c91fbeb..4a91f0e56 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -47,6 +47,7 @@ public: virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendDisconnect (const AString & a_Reason) override; virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; virtual void SendEntityHeadLook (const cEntity & a_Entity) override; virtual void SendEntityLook (const cEntity & a_Entity) override; @@ -70,6 +71,7 @@ public: virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; virtual void SendPlayerSpawn (const cPlayer & a_Player) override; + virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; virtual void SendRespawn (void) override; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8 virtual void SendExperience (void) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 683700d37..30b48a92f 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -216,6 +216,16 @@ void cProtocolRecognizer::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) +void cProtocolRecognizer::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration); +} + + + + + void cProtocolRecognizer::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) { ASSERT(m_Protocol != NULL); @@ -456,6 +466,16 @@ void cProtocolRecognizer::SendPlayerSpawn(const cPlayer & a_Player) +void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendRemoveEntityEffect(a_Entity, a_EffectID); +} + + + + + void cProtocolRecognizer::SendRespawn(void) { ASSERT(m_Protocol != NULL); diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 83fc23c22..0d69e9406 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -73,6 +73,7 @@ public: virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendDisconnect (const AString & a_Reason) override; virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override; virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; virtual void SendEntityHeadLook (const cEntity & a_Entity) override; virtual void SendEntityLook (const cEntity & a_Entity) override; @@ -96,6 +97,7 @@ public: virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; virtual void SendPlayerSpawn (const cPlayer & a_Player) override; + virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; virtual void SendRespawn (void) override; virtual void SendExperience (void) override; virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; From 123799a4e077298907905ab090fd01f532f7d1ef Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 14 Dec 2013 18:19:56 +0100 Subject: [PATCH 03/51] Forgot to commit the ClientHandle. --- src/ClientHandle.cpp | 18 ++++++++++++++++++ src/ClientHandle.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f7e18974f..8a92e1344 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1673,6 +1673,15 @@ void cClientHandle::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) +void cClientHandle::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) +{ + m_Protocol->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration); +} + + + + + void cClientHandle::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) { m_Protocol->SendEntityEquipment(a_Entity, a_SlotNum, a_Item); @@ -1882,6 +1891,15 @@ void cClientHandle::SendPlayerSpawn(const cPlayer & a_Player) +void cClientHandle::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) +{ + m_Protocol->SendRemoveEntityEffect(a_Entity, a_EffectID); +} + + + + + void cClientHandle::SendRespawn(void) { m_Protocol->SendRespawn(); diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 2ff75b28a..19ebc023d 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -100,6 +100,7 @@ public: void SendDestroyEntity (const cEntity & a_Entity); void SendDisconnect (const AString & a_Reason); void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ); + void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration); void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item); void SendEntityHeadLook (const cEntity & a_Entity); void SendEntityLook (const cEntity & a_Entity); @@ -120,6 +121,7 @@ public: void SendPlayerMoveLook (void); void SendPlayerPosition (void); void SendPlayerSpawn (const cPlayer & a_Player); + void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID); void SendRespawn (void); void SendExperience (void); void SendExperienceOrb (const cExpOrb & a_ExpOrb); From 7f9f6f5095719f63132fd16f51fcac7942091370 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 14 Dec 2013 19:11:15 +0000 Subject: [PATCH 04/51] Wires no longer power if a block cuts them off Also reduced more unneeded code. --- src/Simulator/RedstoneSimulator.cpp | 55 +++++++++++++++++------------ 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index e1ffaf30f..8568b6b4b 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -394,18 +394,18 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl int x, y, z; } gCrossCoords[] = { - { 1, 0, 0}, + { 1, 0, 0}, /* Wires on same level start */ {-1, 0, 0}, { 0, 0, 1}, - { 0, 0, -1}, - { 1, 1, 0}, // From here to end, check for wire placed on sides of blocks + { 0, 0, -1}, /* Wires on same level stop */ + { 1, 1, 0}, /* Wires one higher, surrounding self start */ {-1, 1, 0}, { 0, 1, 1}, - { 0, 1, -1}, - { 1,-1, 0}, + { 0, 1, -1}, /* Wires one higher, surrounding self stop */ + { 1,-1, 0}, /* Wires one lower, surrounding self start */ {-1,-1, 0}, { 0,-1, 1}, - { 0,-1, -1}, + { 0,-1, -1}, /* Wires one lower, surrounding self stop */ } ; // Check to see if directly beside a power source @@ -421,6 +421,21 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through all directions to transfer or receive power { + if ((i >= 4) && (i <= 7)) // If we are currently checking for wire surrounding ourself one block above... + { + if (g_BlockIsSolid[m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)]) // If there is something solid above us (wire cut off)... + { + continue; // We don't receive power from that wire + } + } + else if ((i >= 8) && (i <= 11)) // See above, but this is for wire below us + { + if (g_BlockIsSolid[m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y + 1, a_BlockZ + gCrossCoords[i].z)]) + { + continue; + } + } + BLOCKTYPE SurroundType; NIBBLETYPE SurroundMeta; m_World.GetBlockTypeMeta(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, SurroundType, SurroundMeta); @@ -483,37 +498,25 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl } case REDSTONE_X_POS: { - if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) - { - SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - } + SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_WIRE); break; } case REDSTONE_X_NEG: { - if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) - { - SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - } + SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_WIRE); break; } case REDSTONE_Z_POS: { - if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE) - { - SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - } + SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_WIRE); break; } case REDSTONE_Z_NEG: { - if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE) - { - SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - } + SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE); break; } @@ -1147,11 +1150,17 @@ void cRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_B void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock) { - if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) + BLOCKTYPE Block = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ); + if (Block == E_BLOCK_AIR) { // Don't set air, fixes some bugs (wires powering themselves) return; } + if ((Block == E_BLOCK_REDSTONE_WIRE) && (a_SourceBlock == E_BLOCK_REDSTONE_WIRE)) + { + // Wires cannot power themselves normally, instead, the wire handler will manually set meta + return; + } for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list { From 765b8472818767e4c5438fdbf4d3074de6ed086a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 14 Dec 2013 19:29:50 +0000 Subject: [PATCH 05/51] Potentially fixed debug asserts --- src/Simulator/RedstoneSimulator.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index 8568b6b4b..fc9471b91 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -92,8 +92,8 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c if (SourceBlockType != itr->a_SourceBlock) { - itr = m_PoweredBlocks.erase(itr); LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); + itr = m_PoweredBlocks.erase(itr); } else if ( // Changeable sources @@ -103,8 +103,8 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) ) { - itr = m_PoweredBlocks.erase(itr); LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); + itr = m_PoweredBlocks.erase(itr); } else { @@ -133,13 +133,13 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c if (SourceBlockType != itr->a_SourceBlock) { - itr = m_LinkedPoweredBlocks.erase(itr); LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); + itr = m_LinkedPoweredBlocks.erase(itr); } else if (MiddleBlockType != itr->a_MiddleBlock) { - itr = m_LinkedPoweredBlocks.erase(itr); LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); + itr = m_LinkedPoweredBlocks.erase(itr); } else if ( // Things that can send power through a block but which depends on meta @@ -148,8 +148,8 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) ) { - itr = m_LinkedPoweredBlocks.erase(itr); LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); + itr = m_LinkedPoweredBlocks.erase(itr); } else { From 71250b275f2c1b16ff81c74c6e3f5bc2794ebb97 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 14 Dec 2013 22:23:20 +0100 Subject: [PATCH 06/51] Added E_EFFECT_ --- src/Entities/Effects.h | 29 +++++++++++++++++++++++++++++ src/Entities/Player.cpp | 6 +++--- 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 src/Entities/Effects.h diff --git a/src/Entities/Effects.h b/src/Entities/Effects.h new file mode 100644 index 000000000..4fb867e65 --- /dev/null +++ b/src/Entities/Effects.h @@ -0,0 +1,29 @@ +#pragma once + +// tolua_begin +enum ENUM_ENTITY_EFFECT +{ + E_EFFECT_SPEED = 1, + E_EFFECT_SLOWNESS = 2, + E_EFFECT_HASTE = 3, + E_EFFECT_MINING_FATIGUE = 4, + E_EFFECT_STENGTH = 5, + E_EFFECT_INSTANT_HEALTH = 6, + E_EFFECT_INSTANT_DAMAGE = 7, + E_EFFECT_JUMP_BOOST = 8, + E_EFFECT_NAUSEA = 9, + E_EFFECT_REGENERATION = 10, + E_EFFECT_RESISTANCE = 11, + E_EFFECT_FIRE_RESISTANCE = 12, + E_EFFECT_WATER_BREATHING = 13, + E_EFFECT_INVISIBILITY = 14, + E_EFFECT_BLINDNESS = 15, + E_EFFECT_NIGHT_VISION = 16, + E_EFFECT_HUNGER = 17, + E_EFFECT_WEAKNESS = 18, + E_EFFECT_POISON = 19, + E_EFFECT_WITHER = 20, + E_EFFECT_HEALTH_BOOST = 21, + E_EFFECT_ABSORPTION = 22, + E_EFFECT_SATURATION = 23, +} ; \ No newline at end of file diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 20c4818b2..b2485a8e2 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -557,12 +557,12 @@ void cPlayer::FoodPoison(int a_NumTicks) m_FoodPoisonedTicksRemaining = std::max(m_FoodPoisonedTicksRemaining, a_NumTicks); if (!HasBeenFoodPoisoned) { - m_ClientHandle->SendRemoveEntityEffect(*this, 17); + m_ClientHandle->SendRemoveEntityEffect(*this, E_EFFECT_HUNGER); SendHealth(); } else { - m_ClientHandle->SendEntityEffect(*this, 17, 0, 20); + m_ClientHandle->SendEntityEffect(*this, E_EFFECT_HUNGER, 0, 20); } } @@ -1710,7 +1710,7 @@ void cPlayer::HandleFood(void) } else { - m_ClientHandle->SendRemoveEntityEffect(*this, 17); // remove the "Hunger" effect. + m_ClientHandle->SendRemoveEntityEffect(*this, E_EFFECT_HUNGER); // remove the "Hunger" effect. } // Apply food exhaustion that has accumulated: From 8c04afe18a3420574942501a30e3151e89217acd Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 14 Dec 2013 22:34:49 +0100 Subject: [PATCH 07/51] Exported E_EFFECTS_ to lua. Forgot to commit Globals.h. --- src/Bindings/AllToLua.pkg | 1 + src/Bindings/Bindings.cpp | 28 ++++++++++++++++++++++++++-- src/Bindings/Bindings.h | 2 +- src/Entities/Effects.h | 3 ++- src/Globals.h | 1 + 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 6db7b2b0e..e9a5ea0c6 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -37,6 +37,7 @@ $cfile "../Entities/Player.h" $cfile "../Entities/Pickup.h" $cfile "../Entities/ProjectileEntity.h" $cfile "../Entities/TNTEntity.h" +$cfile "../Entities/Effects.h" $cfile "../Server.h" $cfile "../World.h" $cfile "../Inventory.h" diff --git a/src/Bindings/Bindings.cpp b/src/Bindings/Bindings.cpp index 090d8047a..f4fb3f791 100644 --- a/src/Bindings/Bindings.cpp +++ b/src/Bindings/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/14/13 16:22:45. +** Generated automatically by tolua++-1.0.92 on 12/14/13 22:33:52. */ #ifndef __cplusplus @@ -8,7 +8,7 @@ #endif #include "string.h" -#include "tolua++/include/tolua++.h" +#include "tolua++.h" /* Exported function */ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); @@ -35,6 +35,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); #include "../Entities/Pickup.h" #include "../Entities/ProjectileEntity.h" #include "../Entities/TNTEntity.h" +#include "../Entities/Effects.h" #include "../Server.h" #include "../World.h" #include "../Inventory.h" @@ -31064,6 +31065,29 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetCounterTime",tolua_AllToLua_cTNTEntity_GetCounterTime00); tolua_function(tolua_S,"GetMaxFuseTime",tolua_AllToLua_cTNTEntity_GetMaxFuseTime00); tolua_endmodule(tolua_S); + tolua_constant(tolua_S,"E_EFFECT_SPEED",E_EFFECT_SPEED); + tolua_constant(tolua_S,"E_EFFECT_SLOWNESS",E_EFFECT_SLOWNESS); + tolua_constant(tolua_S,"E_EFFECT_HASTE",E_EFFECT_HASTE); + tolua_constant(tolua_S,"E_EFFECT_MINING_FATIGUE",E_EFFECT_MINING_FATIGUE); + tolua_constant(tolua_S,"E_EFFECT_STENGTH",E_EFFECT_STENGTH); + tolua_constant(tolua_S,"E_EFFECT_INSTANT_HEALTH",E_EFFECT_INSTANT_HEALTH); + tolua_constant(tolua_S,"E_EFFECT_INSTANT_DAMAGE",E_EFFECT_INSTANT_DAMAGE); + tolua_constant(tolua_S,"E_EFFECT_JUMP_BOOST",E_EFFECT_JUMP_BOOST); + tolua_constant(tolua_S,"E_EFFECT_NAUSEA",E_EFFECT_NAUSEA); + tolua_constant(tolua_S,"E_EFFECT_REGENERATION",E_EFFECT_REGENERATION); + tolua_constant(tolua_S,"E_EFFECT_RESISTANCE",E_EFFECT_RESISTANCE); + tolua_constant(tolua_S,"E_EFFECT_FIRE_RESISTANCE",E_EFFECT_FIRE_RESISTANCE); + tolua_constant(tolua_S,"E_EFFECT_WATER_BREATHING",E_EFFECT_WATER_BREATHING); + tolua_constant(tolua_S,"E_EFFECT_INVISIBILITY",E_EFFECT_INVISIBILITY); + tolua_constant(tolua_S,"E_EFFECT_BLINDNESS",E_EFFECT_BLINDNESS); + tolua_constant(tolua_S,"E_EFFECT_NIGHT_VISION",E_EFFECT_NIGHT_VISION); + tolua_constant(tolua_S,"E_EFFECT_HUNGER",E_EFFECT_HUNGER); + tolua_constant(tolua_S,"E_EFFECT_WEAKNESS",E_EFFECT_WEAKNESS); + tolua_constant(tolua_S,"E_EFFECT_POISON",E_EFFECT_POISON); + tolua_constant(tolua_S,"E_EFFECT_WITHER",E_EFFECT_WITHER); + tolua_constant(tolua_S,"E_EFFECT_HEALTH_BOOST",E_EFFECT_HEALTH_BOOST); + tolua_constant(tolua_S,"E_EFFECT_ABSORPTION",E_EFFECT_ABSORPTION); + tolua_constant(tolua_S,"E_EFFECT_SATURATION",E_EFFECT_SATURATION); tolua_cclass(tolua_S,"cServer","cServer","",NULL); tolua_beginmodule(tolua_S,"cServer"); tolua_function(tolua_S,"GetDescription",tolua_AllToLua_cServer_GetDescription00); diff --git a/src/Bindings/Bindings.h b/src/Bindings/Bindings.h index 73cf3c7d8..e8f766b43 100644 --- a/src/Bindings/Bindings.h +++ b/src/Bindings/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/14/13 16:22:46. +** Generated automatically by tolua++-1.0.92 on 12/14/13 22:33:53. */ /* Exported function */ diff --git a/src/Entities/Effects.h b/src/Entities/Effects.h index 4fb867e65..e7611847d 100644 --- a/src/Entities/Effects.h +++ b/src/Entities/Effects.h @@ -26,4 +26,5 @@ enum ENUM_ENTITY_EFFECT E_EFFECT_HEALTH_BOOST = 21, E_EFFECT_ABSORPTION = 22, E_EFFECT_SATURATION = 23, -} ; \ No newline at end of file +} ; +// tolua_end \ No newline at end of file diff --git a/src/Globals.h b/src/Globals.h index cb67d9fda..fe6aee5c5 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -220,6 +220,7 @@ public: // Common headers (part 2, with macros): #include "ChunkDef.h" #include "BlockID.h" +#include "Entities/Effects.h" From 322382e37994cdd8bcaaee60f25ba04ac8f5e7bf Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 13 Dec 2013 20:57:11 +0100 Subject: [PATCH 08/51] Removed leftover debugging messages from cProtocol172. --- src/Protocol/Protocol17x.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index bfb38904c..83db17e78 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -921,7 +921,6 @@ void cProtocol172::SendWindowProperty(const cWindow & a_Window, short a_Property void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) { - LOGD("Received %d bytes of data", a_Size); if (!m_ReceivedData.Write(a_Data, a_Size)) { // Too much data in the incoming queue, report to caller: @@ -958,9 +957,6 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) return; } - // DEBUG: - LOGD("Packet 0x%x, len %d (0x%x), start at %d", PacketType, PacketLen, PacketLen, PacketStart); - HandlePacket(bb, PacketType); if (bb.GetReadableSpace() != 1) From 812ea39a5c373f5870562cf24c7282e1cf231599 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 14 Dec 2013 23:34:37 +0100 Subject: [PATCH 09/51] Added tolua++ redirection include. This is needed because ToLua++ regenerates the Bindings file with bad #include, and it would be too difficult to fix ToLua++; this is an easier solution. Should fix PR #431. --- src/Bindings/tolua++.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/Bindings/tolua++.h diff --git a/src/Bindings/tolua++.h b/src/Bindings/tolua++.h new file mode 100644 index 000000000..4dfd06318 --- /dev/null +++ b/src/Bindings/tolua++.h @@ -0,0 +1,13 @@ + +// tolua++.h + +// Redirection file, needed because ToLua++ generates the Bindings.cpp file with >> #include "tolua++.h" << + + + + +#include "tolua++/include/tolua++.h" + + + + From c56af9a214fad89b5d6e119fa830cbdc6c6f5456 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 10:51:46 +0100 Subject: [PATCH 10/51] This adds the cWorld::BroadcastEntityEffect and cWorld::BroadcastRemoveEntityEffect functions. --- src/Chunk.cpp | 32 ++++++++++++++++++++++++++++++++ src/Chunk.h | 2 ++ src/ChunkMap.cpp | 33 +++++++++++++++++++++++++++++++++ src/ChunkMap.h | 2 ++ src/World.cpp | 18 ++++++++++++++++++ src/World.h | 2 ++ 6 files changed, 89 insertions(+) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index b3c1896dc..3eb46213c 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2589,6 +2589,22 @@ void cChunk::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandl +void cChunk::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if (*itr == a_Exclude) + { + continue; + } + (*itr)->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration); + } // for itr - LoadedByClient[] +} + + + + + void cChunk::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude) { for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) @@ -2733,6 +2749,22 @@ void cChunk::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation +void cChunk::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude) +{ + for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if (*itr == a_Exclude) + { + continue; + } + (*itr)->SendRemoveEntityEffect(a_Entity, a_EffectID); + } // for itr - LoadedByClient[] +} + + + + + void cChunk::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude) { for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) diff --git a/src/Chunk.h b/src/Chunk.h index a5bc9863b..1d762c0ca 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -267,6 +267,7 @@ public: void BroadcastChunkData (cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); @@ -276,6 +277,7 @@ public: void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL); + void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // a_Src coords are Block * 8 void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index f2195741d..53b595545 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -445,6 +445,22 @@ void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHa +void cChunkMap::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->BroadcastEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration); +} + + + + + void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); @@ -589,6 +605,23 @@ void cChunkMap::BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animat +void cChunkMap::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSLayers); + + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->BroadcastRemoveEntityEffect(a_Entity, a_EffectID, a_Exclude); +} + + + + + void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); diff --git a/src/ChunkMap.h b/src/ChunkMap.h index f079c9a1b..dcc6abdc3 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -64,6 +64,7 @@ public: void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); void BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); void BroadcastEntityHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); @@ -73,6 +74,7 @@ public: void BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); void BroadcastEntityVelocity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL); + void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); void BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // a_Src coords are Block * 8 void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); void BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); diff --git a/src/World.cpp b/src/World.cpp index 9ec389be9..35887c07d 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1813,6 +1813,15 @@ void cWorld::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandl +void cWorld::BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration, a_Exclude); +} + + + + + void cWorld::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude) { m_ChunkMap->BroadcastEntityEquipment(a_Entity, a_SlotNum, a_Item, a_Exclude); @@ -1911,6 +1920,15 @@ void cWorld::BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, +void cWorld::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastRemoveEntityEffect(a_Entity, a_EffectID, a_Exclude); +} + + + + + void cWorld::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude) { m_ChunkMap->BroadcastSoundEffect(a_SoundName, a_SrcX, a_SrcY, a_SrcZ, a_Volume, a_Pitch, a_Exclude); diff --git a/src/World.h b/src/World.h index 5cd8b41b6..16d7f5146 100644 --- a/src/World.h +++ b/src/World.h @@ -153,6 +153,7 @@ public: void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); @@ -163,6 +164,7 @@ public: void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL); void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL); + void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // tolua_export a_Src coords are Block * 8 void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); // tolua_export void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); From 9c2089dc5a89acc2351fa089558d1e375c1d09f6 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 10:52:54 +0100 Subject: [PATCH 11/51] cPlayer is using the broadcast functions. --- src/Entities/Player.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index b2485a8e2..e057c25fe 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -557,12 +557,12 @@ void cPlayer::FoodPoison(int a_NumTicks) m_FoodPoisonedTicksRemaining = std::max(m_FoodPoisonedTicksRemaining, a_NumTicks); if (!HasBeenFoodPoisoned) { - m_ClientHandle->SendRemoveEntityEffect(*this, E_EFFECT_HUNGER); + m_World->BroadcastRemoveEntityEffect(*this, E_EFFECT_HUNGER); SendHealth(); } else { - m_ClientHandle->SendEntityEffect(*this, E_EFFECT_HUNGER, 0, 20); + m_World->BroadcastEntityEffect(*this, E_EFFECT_HUNGER, 0, 400); // Give the player the "Hunger" effect for 20 seconds. } } @@ -1710,7 +1710,7 @@ void cPlayer::HandleFood(void) } else { - m_ClientHandle->SendRemoveEntityEffect(*this, E_EFFECT_HUNGER); // remove the "Hunger" effect. + m_World->BroadcastRemoveEntityEffect(*this, E_EFFECT_HUNGER); // Remove the "Hunger" effect. } // Apply food exhaustion that has accumulated: From 828cca5c7e1c731f2f2c7c80216db03c2f0948ff Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 11:34:00 +0100 Subject: [PATCH 12/51] Fixed pre 1.7 clients crashing. --- src/Protocol/Protocol125.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index d4c1f0dd5..48f23801c 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -43,8 +43,6 @@ enum PACKET_HANDSHAKE = 0x02, PACKET_CHAT = 0x03, PACKET_UPDATE_TIME = 0x04, - PACKET_ENTITY_EFFECT = 0x1D, - PACKET_REMOVE_ENTITY_EFFECT = 0x1E, PACKET_ENTITY_EQUIPMENT = 0x05, PACKET_USE_ENTITY = 0x07, PACKET_UPDATE_HEALTH = 0x08, @@ -75,7 +73,9 @@ enum PACKET_ENT_STATUS = 0x26, PACKET_ATTACH_ENTITY = 0x27, PACKET_METADATA = 0x28, + PACKET_ENTITY_EFFECT = 0x29, PACKET_SPAWN_EXPERIENCE_ORB = 0x1A, + PACKET_REMOVE_ENTITY_EFFECT = 0x2a, PACKET_EXPERIENCE = 0x2b, PACKET_PRE_CHUNK = 0x32, PACKET_MAP_CHUNK = 0x33, From ceb11cb47752bc7dffedb646df86e9efd0d6ea16 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 15 Dec 2013 12:17:29 +0000 Subject: [PATCH 13/51] Fixed the hopefully final wire self-powering bug --- src/Simulator/RedstoneSimulator.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index fc9471b91..baeef404c 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -82,10 +82,16 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c { int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width; int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width; + int DestRelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width; + int DestRelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width; BLOCKTYPE SourceBlockType; NIBBLETYPE SourceBlockMeta; - if (!a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta)) + BLOCKTYPE DestBlockType; + if ( + !a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) || + !a_Chunk->UnboundedRelGetBlockType(DestRelX, itr->a_SourcePos.y, DestRelZ, DestBlockType) + ) { continue; } @@ -106,6 +112,12 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); itr = m_PoweredBlocks.erase(itr); } + else if ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (DestBlockType == E_BLOCK_REDSTONE_WIRE)) + { + // It is simply not allowed that a wire powers another wire, presuming that data here is sane and a dest and source are beside each other + LOGD("cRedstoneSimulator: Erased redstone wire from powered blocks list because it's source was also wire"); + itr = m_PoweredBlocks.erase(itr); + } else { itr++; From bbcef6d6ebc8c46f99e17acf1cc7d23fe27d16cc Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 15 Dec 2013 13:08:08 +0000 Subject: [PATCH 14/51] Wires now power repeaters properly --- src/Simulator/RedstoneSimulator.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index baeef404c..f036473c1 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -490,6 +490,13 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire { + for (size_t i = 0; i < 4; i++) // Look for repeaters immediately surrounding self and try to power them + { + if (m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z) == E_BLOCK_REDSTONE_REPEATER_OFF) + { + SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); + } + } // Wire still powered, power blocks beneath SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE); From b10d0b95cbdce1d476f14415901c89bf324c0c18 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 14:48:17 +0100 Subject: [PATCH 15/51] Added m_IsFlying and m_CanFly. Both have a Get and Set function. Added cClientHandle::SendPlayerAbilities() function --- src/ClientHandle.cpp | 33 +++++++++++++++++++++++++++++++++ src/ClientHandle.h | 2 ++ src/Entities/Player.cpp | 32 ++++++++++++++++++++++++++++++++ src/Entities/Player.h | 14 +++++++++++++- src/Protocol/Protocol17x.cpp | 12 ++++++++++-- 5 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 8a92e1344..68c511d7c 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -490,6 +490,30 @@ void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_Hel +void cClientHandle::HandlePlayerAbilities(int Flags, float FlyingSpeed, float WalkingSpeed) +{ + if ((Flags & 2) != 0) + { + m_Player->SetFlying(true); + } + else + { + m_Player->SetFlying(false); + } + if ((Flags & 4) != 0) + { + m_Player->SetCanFly(true); + } + else + { + m_Player->SetCanFly(false); + } +} + + + + + void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround) { if ((m_Player == NULL) || (m_State != csPlaying)) @@ -1831,6 +1855,15 @@ void cClientHandle::SendEntityAnimation(const cEntity & a_Entity, char a_Animati +void cClientHandle::SendPlayerAbilities() +{ + m_Protocol->SendPlayerAbilities(); +} + + + + + void cClientHandle::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) { m_Protocol->SendPlayerListItem(a_Player, a_IsOnline); diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 19ebc023d..51068a319 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -116,6 +116,7 @@ public: void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item); void SendPickupSpawn (const cPickup & a_Pickup); void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); + void SendPlayerAbilities (void); void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline); void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+) void SendPlayerMoveLook (void); @@ -175,6 +176,7 @@ public: void HandleKeepAlive (int a_KeepAliveID); void HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status); void HandlePing (void); + void HandlePlayerAbilities (int Flags, float FlyingSpeed, float WalkingSpeed); void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround); void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay) void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index e057c25fe..c2a76342d 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -63,6 +63,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) , m_IsSprinting(false) , m_IsSwimming(false) , m_IsSubmerged(false) + , m_IsFlying(false) + , m_CanFly(false) , m_EatingFinishTick(-1) , m_IsChargingBow(false) , m_BowCharge(0) @@ -751,6 +753,36 @@ void cPlayer::SetSprint(bool a_IsSprinting) +void cPlayer::SetCanFly(bool a_CanFly) +{ + if (a_CanFly == m_CanFly) + { + return; + } + + m_CanFly = a_CanFly; + m_ClientHandle->SendPlayerAbilities(); +} + + + + + +void cPlayer::SetFlying(bool a_IsFlying) +{ + if (a_IsFlying == m_IsFlying) + { + return; + } + + m_IsFlying = a_IsFlying; + m_ClientHandle->SendPlayerAbilities(); +} + + + + + void cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) { if (a_TDI.DamageType != dtInVoid) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 44cab7d74..f3ee841e7 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -250,6 +250,8 @@ public: /// Returns true if the player is currently in the process of eating the currently equipped item bool IsEating(void) const { return (m_EatingFinishTick >= 0); } + /// Returns true if the player is currently flying. + bool IsFlying(void) const { return m_IsFlying; } // tolua_end /// Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet @@ -319,12 +321,20 @@ public: /// Starts or stops sprinting, sends the max speed update to the client, if needed void SetSprint(bool a_IsSprinting); + /// Flags the player as flying + void SetFlying(bool a_IsFlying); + + /// If true the player can fly even when he's not in creative. + void SetCanFly(bool a_CanFly); + /// Returns whether the player is swimming or not virtual bool IsSwimming(void) const{ return m_IsSwimming; } /// Return whether the player is under water or not virtual bool IsSubmerged(void) const{ return m_IsSubmerged; } + /// Returns wheter the player can fly or not. + virtual bool CanFly(void) const { return m_CanFly; } // tolua_end // cEntity overrides: @@ -415,10 +425,12 @@ protected: bool m_IsCrouched; bool m_IsSprinting; - + bool m_IsFlying; bool m_IsSwimming; bool m_IsSubmerged; + bool m_CanFly; // If this is true the player can fly. Even if he is not in creative. + /// The world tick in which eating will be finished. -1 if not eating Int64 m_EatingFinishTick; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 0daf1c932..9b2b19026 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -491,7 +491,15 @@ void cProtocol172::SendPlayerAbilities(void) { Flags |= 0x01; } - // TODO: Other flags (god mode, flying, can fly + if (m_Client->GetPlayer()->IsFlying()) + { + Flags |= 0x02; + } + if (m_Client->GetPlayer()->CanFly()) + { + Flags |= 0x04; + } + // TODO: Other flags (god mode) Pkt.WriteByte(Flags); // TODO: Pkt.WriteFloat(m_Client->GetPlayer()->GetMaxFlyingSpeed()); Pkt.WriteFloat(0.05f); @@ -1278,7 +1286,7 @@ void cProtocol172::HandlePacketPlayerAbilities(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Flags); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, FlyingSpeed); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, WalkingSpeed); - // TODO: m_Client->HandlePlayerAbilities(); + m_Client->HandlePlayerAbilities(Flags, FlyingSpeed, WalkingSpeed); } From 9fe06af598b7e298c0df315f6bdcd65fd1c9b0c4 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 14:52:17 +0100 Subject: [PATCH 16/51] Exported Set and Get functions to Lua. --- src/Bindings/Bindings.cpp | 136 +++++++++++++++++++++++++++++++++++++- src/Bindings/Bindings.h | 2 +- 2 files changed, 136 insertions(+), 2 deletions(-) diff --git a/src/Bindings/Bindings.cpp b/src/Bindings/Bindings.cpp index f4fb3f791..46f8c8f40 100644 --- a/src/Bindings/Bindings.cpp +++ b/src/Bindings/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/14/13 22:33:52. +** Generated automatically by tolua++-1.0.92 on 12/15/13 14:19:12. */ #ifndef __cplusplus @@ -10460,6 +10460,38 @@ static int tolua_AllToLua_cPlayer_IsEating00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: IsFlying of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsFlying00 +static int tolua_AllToLua_cPlayer_IsFlying00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsFlying'", NULL); +#endif + { + bool tolua_ret = (bool) self->IsFlying(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsFlying'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: Respawn of class cPlayer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_Respawn00 static int tolua_AllToLua_cPlayer_Respawn00(lua_State* tolua_S) @@ -10849,6 +10881,72 @@ static int tolua_AllToLua_cPlayer_SetSprint00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: SetFlying of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetFlying00 +static int tolua_AllToLua_cPlayer_SetFlying00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + bool a_IsFlying = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetFlying'", NULL); +#endif + { + self->SetFlying(a_IsFlying); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetFlying'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetCanFly of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_SetCanFly00 +static int tolua_AllToLua_cPlayer_SetCanFly00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isboolean(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + bool a_CanFly = ((bool) tolua_toboolean(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetCanFly'", NULL); +#endif + { + self->SetCanFly(a_CanFly); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetCanFly'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: IsSwimming of class cPlayer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_IsSwimming00 static int tolua_AllToLua_cPlayer_IsSwimming00(lua_State* tolua_S) @@ -10913,6 +11011,38 @@ static int tolua_AllToLua_cPlayer_IsSubmerged00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: CanFly of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_CanFly00 +static int tolua_AllToLua_cPlayer_CanFly00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CanFly'", NULL); +#endif + { + bool tolua_ret = (bool) self->CanFly(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CanFly'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: new of class cPickup */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cPickup_new00 static int tolua_AllToLua_cPickup_new00(lua_State* tolua_S) @@ -30978,6 +31108,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"AddFoodExhaustion",tolua_AllToLua_cPlayer_AddFoodExhaustion00); tolua_function(tolua_S,"FoodPoison",tolua_AllToLua_cPlayer_FoodPoison00); tolua_function(tolua_S,"IsEating",tolua_AllToLua_cPlayer_IsEating00); + tolua_function(tolua_S,"IsFlying",tolua_AllToLua_cPlayer_IsFlying00); tolua_function(tolua_S,"Respawn",tolua_AllToLua_cPlayer_Respawn00); tolua_function(tolua_S,"SetVisible",tolua_AllToLua_cPlayer_SetVisible00); tolua_function(tolua_S,"IsVisible",tolua_AllToLua_cPlayer_IsVisible00); @@ -30990,8 +31121,11 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"SetSprintingMaxSpeed",tolua_AllToLua_cPlayer_SetSprintingMaxSpeed00); tolua_function(tolua_S,"SetCrouch",tolua_AllToLua_cPlayer_SetCrouch00); tolua_function(tolua_S,"SetSprint",tolua_AllToLua_cPlayer_SetSprint00); + tolua_function(tolua_S,"SetFlying",tolua_AllToLua_cPlayer_SetFlying00); + tolua_function(tolua_S,"SetCanFly",tolua_AllToLua_cPlayer_SetCanFly00); tolua_function(tolua_S,"IsSwimming",tolua_AllToLua_cPlayer_IsSwimming00); tolua_function(tolua_S,"IsSubmerged",tolua_AllToLua_cPlayer_IsSubmerged00); + tolua_function(tolua_S,"CanFly",tolua_AllToLua_cPlayer_CanFly00); tolua_endmodule(tolua_S); #ifdef __cplusplus tolua_cclass(tolua_S,"cPickup","cPickup","cEntity",tolua_collect_cPickup); diff --git a/src/Bindings/Bindings.h b/src/Bindings/Bindings.h index e8f766b43..4805c260e 100644 --- a/src/Bindings/Bindings.h +++ b/src/Bindings/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/14/13 22:33:53. +** Generated automatically by tolua++-1.0.92 on 12/15/13 14:19:13. */ /* Exported function */ From b87055f7a5f9fb82378ec6da22002dab8c709fd5 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 15 Dec 2013 13:56:32 +0000 Subject: [PATCH 17/51] Fixed wire repeater checking --- src/Simulator/RedstoneSimulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index f036473c1..e5a3fd735 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -490,7 +490,7 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire { - for (size_t i = 0; i < 4; i++) // Look for repeaters immediately surrounding self and try to power them + for (size_t i = 0; i < 3; i++) // Look for repeaters immediately surrounding self and try to power them { if (m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z) == E_BLOCK_REDSTONE_REPEATER_OFF) { From ffb5a69a9e1e531cb8effc72d2a2ad0a459981e3 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 15:11:59 +0100 Subject: [PATCH 18/51] Moved reading flags to the protocol. --- src/ClientHandle.cpp | 20 +++----------------- src/ClientHandle.h | 2 +- src/Protocol/Protocol17x.cpp | 20 +++++++++++++++++++- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 68c511d7c..d585eccf1 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -490,24 +490,10 @@ void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_Hel -void cClientHandle::HandlePlayerAbilities(int Flags, float FlyingSpeed, float WalkingSpeed) +void cClientHandle::HandlePlayerAbilities(bool a_CanFly, bool a_IsFlying, float FlyingSpeed, float WalkingSpeed) { - if ((Flags & 2) != 0) - { - m_Player->SetFlying(true); - } - else - { - m_Player->SetFlying(false); - } - if ((Flags & 4) != 0) - { - m_Player->SetCanFly(true); - } - else - { - m_Player->SetCanFly(false); - } + m_Player->SetCanFly(a_CanFly); + m_Player->SetFlying(a_IsFlying); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 51068a319..147a5b2b3 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -176,7 +176,7 @@ public: void HandleKeepAlive (int a_KeepAliveID); void HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status); void HandlePing (void); - void HandlePlayerAbilities (int Flags, float FlyingSpeed, float WalkingSpeed); + void HandlePlayerAbilities (bool a_CanFly, bool a_IsFlying, float FlyingSpeed, float WalkingSpeed); void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround); void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay) void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 9b2b19026..edf7d2529 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1286,7 +1286,25 @@ void cProtocol172::HandlePacketPlayerAbilities(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Flags); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, FlyingSpeed); HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, WalkingSpeed); - m_Client->HandlePlayerAbilities(Flags, FlyingSpeed, WalkingSpeed); + + bool IsFlying, CanFly; + if ((Flags & 2) != 0) + { + IsFlying = true; + } + else + { + IsFlying = false; + } + if ((Flags & 4) != 0) + { + CanFly = true; + } + else + { + CanFly = false; + } + m_Client->HandlePlayerAbilities(CanFly, IsFlying, FlyingSpeed, WalkingSpeed); } From ae061d717b6b574c10471e590b4e88b2ee719538 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 15:18:53 +0100 Subject: [PATCH 19/51] APIDump: Documented New functions --- MCServer/Plugins/APIDump/APIDesc.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index b7dddec05..00510b426 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1567,6 +1567,7 @@ a_Player:OpenWindow(Window); AddFoodExhaustion = { Params = "Exhaustion", Return = "", Notes = "Adds the specified number to the food exhaustion. Only positive numbers expected." }, AddToGroup = { Params = "GroupName", Return = "", Notes = "Temporarily adds the player to the specified group. The assignment is lost when the player disconnects." }, CalcLevelFromXp = { Params = "XPAmount", Return = "number", Notes = "Returns the level which is reached with the specified amount of XP. Inverse of XpForLevel()." }, + CanFly = { Return = "bool", Notes = "Returns if the player is able to fly." }, CanUseCommand = { Params = "Command", Return = "bool", Notes = "Returns true if the player is allowed to use the specified command." }, CloseWindow = { Params = "[CanRefuse]", Return = "", Notes = "Closes the currently open UI window. If CanRefuse is true (default), the window may refuse the closing." }, CloseWindowIfID = { Params = "WindowID, [CanRefuse]", Return = "", Notes = "Closes the currently open UI window if its ID matches the given ID. If CanRefuse is true (default), the window may refuse the closing." }, @@ -1605,6 +1606,7 @@ a_Player:OpenWindow(Window); HasPermission = { Params = "PermissionString", Return = "bool", Notes = "Returns true if the player has the specified permission" }, Heal = { Params = "HitPoints", Return = "", Notes = "Heals the player by the specified amount of HPs. Only positive amounts are expected. Sends a health update to the client." }, IsEating = { Params = "", Return = "bool", Notes = "Returns true if the player is currently eating the item in their hand." }, + IsFlying = { Return = "bool", Notes = "Returns true if the player is flying." }, IsGameModeAdventure = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmAdventure gamemode, or has their gamemode unset and the world is a gmAdventure world." }, IsGameModeCreative = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmCreative gamemode, or has their gamemode unset and the world is a gmCreative world." }, IsGameModeSurvival = { Params = "", Return = "bool", Notes = "Returns true if the player is in the gmSurvival gamemode, or has their gamemode unset and the world is a gmSurvival world." }, @@ -1621,8 +1623,10 @@ a_Player:OpenWindow(Window); RemoveFromGroup = { Params = "GroupName", Return = "", Notes = "Temporarily removes the player from the specified group. This change is lost when the player disconnects." }, Respawn = { Params = "", Return = "", Notes = "Restores the health, extinguishes fire, makes visible and sends the Respawn packet." }, SendMessage = { Params = "MessageString", Return = "", Notes = "Sends the specified message to the player." }, + SetCanFly = { Params = "CanFly", Notes = "Sets if the player can fly or not." }, SetCrouch = { Params = "IsCrouched", Return = "", Notes = "Sets the crouch state, broadcasts the change to other players." }, SetCurrentExperience = { Params = "XPAmount", Return = "", Notes = "Sets the current amount of experience (and indirectly, the XP level)." }, + SetFlying = { Params = "IsFlying", Notes = "Sets if the player is flying or not." }, SetFoodExhaustionLevel = { Params = "ExhaustionLevel", Return = "", Notes = "Sets the food exhaustion to the specified level." }, SetFoodLevel = { Params = "FoodLevel", Return = "", Notes = "Sets the food level (number of half-drumsticks on-screen)" }, SetFoodPoisonedTicksRemaining = { Params = "FoodPoisonedTicksRemaining", Return = "", Notes = "Sets the number of ticks remaining for food poisoning. Doesn't send foodpoisoning effect to the client, use FoodPoison() for that." }, From 368b7a40b5c86d5fcd37ac4672a8823cdfb48538 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 15 Dec 2013 15:57:38 +0100 Subject: [PATCH 20/51] Fixed indentation. --- src/Entities/ExpOrb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp index 248fb7278..04ee85823 100644 --- a/src/Entities/ExpOrb.cpp +++ b/src/Entities/ExpOrb.cpp @@ -54,7 +54,7 @@ void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk) Destroy(true); } a_Distance.Normalize(); - a_Distance *= ((float) (5.5 - Distance)); + a_Distance *= ((float) (5.5 - Distance)); SetSpeedX( a_Distance.x ); SetSpeedY( a_Distance.y ); SetSpeedZ( a_Distance.z ); From ba4eae2d161ef7bf47f533f33198242e2bde4eb1 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 15 Dec 2013 15:36:20 +0000 Subject: [PATCH 21/51] Implemented xoft's suggestions --- src/Simulator/RedstoneSimulator.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index e5a3fd735..77301aafa 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -420,6 +420,18 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl { 0,-1, -1}, /* Wires one lower, surrounding self stop */ } ; + static const struct // Define which directions the wire will check for repeater prescence + { + int x, y, z; + } gSideCoords[] = + { + { 1, 0, 0 }, + {-1, 0, 0 }, + { 0, 0, 1 }, + { 0, 0,-1 }, + { 0, 1, 0 }, + }; + // Check to see if directly beside a power source if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { @@ -490,13 +502,14 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire { - for (size_t i = 0; i < 3; i++) // Look for repeaters immediately surrounding self and try to power them + for (size_t i = 0; i < ARRAYCOUNT(gSideCoords); i++) // Look for repeaters immediately surrounding self and try to power them { - if (m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z) == E_BLOCK_REDSTONE_REPEATER_OFF) + if (m_World.GetBlock(a_BlockX + gSideCoords[i].x, a_BlockY + gSideCoords[i].y, a_BlockZ + gSideCoords[i].z) == E_BLOCK_REDSTONE_REPEATER_OFF) { - SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); + SetBlockPowered(a_BlockX + gSideCoords[i].x, a_BlockY + gSideCoords[i].y, a_BlockZ + gSideCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); } } + // Wire still powered, power blocks beneath SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE); From 0efd74f114dad98c4fadc0318718f2e0203bca8b Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 18:54:54 +0100 Subject: [PATCH 22/51] This adds a function that allows you to 'shoot' a player towards a direction. --- src/Bindings/Bindings.cpp | 36 +++++++++++++++++++++++++++++++++++- src/Bindings/Bindings.h | 2 +- src/ClientHandle.cpp | 2 -- src/Entities/Player.cpp | 10 ++++++++++ src/Entities/Player.h | 3 +++ 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/Bindings/Bindings.cpp b/src/Bindings/Bindings.cpp index 46f8c8f40..219f7c31a 100644 --- a/src/Bindings/Bindings.cpp +++ b/src/Bindings/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/15/13 14:19:12. +** Generated automatically by tolua++-1.0.92 on 12/15/13 18:47:13. */ #ifndef __cplusplus @@ -9395,6 +9395,39 @@ static int tolua_AllToLua_cPlayer_GetIP00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: ShootTo of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_ShootTo00 +static int tolua_AllToLua_cPlayer_ShootTo00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"Vector3d",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + Vector3d Vector = *((Vector3d*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ShootTo'", NULL); +#endif + { + self->ShootTo(Vector); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ShootTo'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: MoveTo of class cPlayer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_MoveTo00 static int tolua_AllToLua_cPlayer_MoveTo00(lua_State* tolua_S) @@ -31076,6 +31109,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsGameModeSurvival",tolua_AllToLua_cPlayer_IsGameModeSurvival00); tolua_function(tolua_S,"IsGameModeAdventure",tolua_AllToLua_cPlayer_IsGameModeAdventure00); tolua_function(tolua_S,"GetIP",tolua_AllToLua_cPlayer_GetIP00); + tolua_function(tolua_S,"ShootTo",tolua_AllToLua_cPlayer_ShootTo00); tolua_function(tolua_S,"MoveTo",tolua_AllToLua_cPlayer_MoveTo00); tolua_function(tolua_S,"GetWindow",tolua_AllToLua_cPlayer_GetWindow00); tolua_function(tolua_S,"CloseWindow",tolua_AllToLua_cPlayer_CloseWindow00); diff --git a/src/Bindings/Bindings.h b/src/Bindings/Bindings.h index 4805c260e..0b555e66c 100644 --- a/src/Bindings/Bindings.h +++ b/src/Bindings/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/15/13 14:19:13. +** Generated automatically by tolua++-1.0.92 on 12/15/13 18:47:14. */ /* Exported function */ diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d585eccf1..0d70b2a2b 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1765,8 +1765,6 @@ void cClientHandle::SendEntityStatus(const cEntity & a_Entity, char a_Status) void cClientHandle::SendEntityVelocity(const cEntity & a_Entity) { - ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self - m_Protocol->SendEntityVelocity(a_Entity); } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index c2a76342d..ab7075121 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1069,6 +1069,16 @@ Vector3d cPlayer::GetThrowSpeed(double a_SpeedCoeff) const +void cPlayer::ShootTo(Vector3d a_Direction) +{ + SetSpeed(a_Direction); + m_ClientHandle->SendEntityVelocity(*this); +} + + + + + void cPlayer::MoveTo( const Vector3d & a_NewPos ) { if ((a_NewPos.y < -990) && (GetPosY() > -100)) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index f3ee841e7..8dc6968ff 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -167,6 +167,9 @@ public: // Sets the current gamemode, doesn't check validity, doesn't send update packets to client void LoginSetGameMode(eGameMode a_GameMode); + /// "Shoots" the player in the given direction. + void ShootTo(Vector3d a_Direction); // tolua_export + /// Tries to move to a new position, with attachment-related checks (y == -999) void MoveTo(const Vector3d & a_NewPos); // tolua_export From 4ee4cab2d3f523286ca415cec6b4225fc03b4ea9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 15 Dec 2013 20:12:40 +0100 Subject: [PATCH 23/51] Fixed calling OnPlayerJoined() in the wrong place. This is the first part of a fix for #187. --- src/ClientHandle.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d585eccf1..c5fe270d3 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1498,13 +1498,8 @@ void cClientHandle::Tick(float a_Dt) } // If the chunk the player's in was just sent, spawn the player: - if (m_HasSentPlayerChunk && (m_State != csPlaying) && !IsDestroying()) + if (m_HasSentPlayerChunk && (m_State == csDownloadingWorld)) { - if (!cRoot::Get()->GetPluginManager()->CallHookPlayerJoined(*m_Player)) - { - // Broadcast that this player has joined the game! Yay~ - m_Player->GetWorld()->BroadcastChat(m_Username + " joined the game!", this); - } m_Protocol->SendPlayerMoveLook(); m_State = csPlaying; } From 5e75408b3becd5de0ef88223c789fa6f95ff6619 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 20:19:58 +0100 Subject: [PATCH 24/51] Renamed ShootTo function to ForceSetSpeed. --- src/Entities/Player.cpp | 2 +- src/Entities/Player.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index ab7075121..38b911fd2 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1069,7 +1069,7 @@ Vector3d cPlayer::GetThrowSpeed(double a_SpeedCoeff) const -void cPlayer::ShootTo(Vector3d a_Direction) +void cPlayer::ForceSetSpeed(Vector3d a_Direction) { SetSpeed(a_Direction); m_ClientHandle->SendEntityVelocity(*this); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 8dc6968ff..a09f7f489 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -167,8 +167,8 @@ public: // Sets the current gamemode, doesn't check validity, doesn't send update packets to client void LoginSetGameMode(eGameMode a_GameMode); - /// "Shoots" the player in the given direction. - void ShootTo(Vector3d a_Direction); // tolua_export + /// Forces the player to move in the given direction. + void ForceSetSpeed(Vector3d a_Direction); // tolua_export /// Tries to move to a new position, with attachment-related checks (y == -999) void MoveTo(const Vector3d & a_NewPos); // tolua_export From a2612fa68adacada92874c58b56f2646adda39eb Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 20:25:53 +0100 Subject: [PATCH 25/51] Exported to Lua --- src/Bindings/Bindings.cpp | 18 +++++++++--------- src/Bindings/Bindings.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Bindings/Bindings.cpp b/src/Bindings/Bindings.cpp index 219f7c31a..5536ab2b0 100644 --- a/src/Bindings/Bindings.cpp +++ b/src/Bindings/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/15/13 18:47:13. +** Generated automatically by tolua++-1.0.92 on 12/15/13 20:25:06. */ #ifndef __cplusplus @@ -9395,9 +9395,9 @@ static int tolua_AllToLua_cPlayer_GetIP00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: ShootTo of class cPlayer */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_ShootTo00 -static int tolua_AllToLua_cPlayer_ShootTo00(lua_State* tolua_S) +/* method: ForceSetSpeed of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_ForceSetSpeed00 +static int tolua_AllToLua_cPlayer_ForceSetSpeed00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; @@ -9411,18 +9411,18 @@ static int tolua_AllToLua_cPlayer_ShootTo00(lua_State* tolua_S) #endif { cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - Vector3d Vector = *((Vector3d*) tolua_tousertype(tolua_S,2,0)); + Vector3d a_Direction = *((Vector3d*) tolua_tousertype(tolua_S,2,0)); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ShootTo'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ForceSetSpeed'", NULL); #endif { - self->ShootTo(Vector); + self->ForceSetSpeed(a_Direction); } } return 0; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'ShootTo'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'ForceSetSpeed'.",&tolua_err); return 0; #endif } @@ -31109,7 +31109,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsGameModeSurvival",tolua_AllToLua_cPlayer_IsGameModeSurvival00); tolua_function(tolua_S,"IsGameModeAdventure",tolua_AllToLua_cPlayer_IsGameModeAdventure00); tolua_function(tolua_S,"GetIP",tolua_AllToLua_cPlayer_GetIP00); - tolua_function(tolua_S,"ShootTo",tolua_AllToLua_cPlayer_ShootTo00); + tolua_function(tolua_S,"ForceSetSpeed",tolua_AllToLua_cPlayer_ForceSetSpeed00); tolua_function(tolua_S,"MoveTo",tolua_AllToLua_cPlayer_MoveTo00); tolua_function(tolua_S,"GetWindow",tolua_AllToLua_cPlayer_GetWindow00); tolua_function(tolua_S,"CloseWindow",tolua_AllToLua_cPlayer_CloseWindow00); diff --git a/src/Bindings/Bindings.h b/src/Bindings/Bindings.h index 0b555e66c..ef3b6b49e 100644 --- a/src/Bindings/Bindings.h +++ b/src/Bindings/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/15/13 18:47:14. +** Generated automatically by tolua++-1.0.92 on 12/15/13 20:25:06. */ /* Exported function */ From 6e30e54eb005862a5791faca5c25a0481d0f0915 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 20:27:19 +0100 Subject: [PATCH 26/51] Documented ForceSetSpeed. --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 00510b426..214b45a70 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1574,6 +1574,7 @@ a_Player:OpenWindow(Window); DeltaExperience = { Params = "DeltaXP", Return = "", Notes = "Adds or removes XP from the current XP amount. Won't allow XP to go negative. Returns the new experience, -1 on error (XP overflow)." }, Feed = { Params = "AddFood, AddSaturation", Return = "bool", Notes = "Tries to add the specified amounts to food level and food saturation level (only positive amounts expected). Returns true if player was hungry and the food was consumed, false if too satiated." }, FoodPoison = { Params = "NumTicks", Return = "", Notes = "Starts the food poisoning for the specified amount of ticks; if already foodpoisoned, sets FoodPoisonedTicksRemaining to the larger of the two" }, + ForceSetSpeed = { Params = "{{Vector3d|Direction}}", Notes = "Forces the player to move to the given direction." }, GetAirLevel = { Params = "", Return = "number", Notes = "Returns the air level (number of ticks of air left)." }, GetClientHandle = { Params = "", Return = "{{cClientHandle}}", Notes = "Returns the client handle representing the player's connection. May be nil (AI players)." }, GetColor = { Return = "string", Notes = "Returns the full color code to be used for this player (based on the first group). Prefix player messages with this code." }, From c19f2d7383173c6c1b33bb0653d6ba8ee59240ae Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 15 Dec 2013 20:41:35 +0100 Subject: [PATCH 27/51] ProtoProxy: Fixed description-changing to work with 1.7.4. --- Tools/ProtoProxy/Connection.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index 0b49859cb..10f2b4073 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -2384,10 +2384,11 @@ bool cConnection::HandleServerStatusResponse(void) Log(" Response: %s", Response.c_str()); // Modify the response to show that it's being proto-proxied: - size_t idx = Response.find("\"description\":\""); + const char DescSearch[] = "\"description\":{\"text\":\""; + size_t idx = Response.find(DescSearch); if (idx != AString::npos) { - Response.assign(Response.substr(0, idx + 15) + "ProtoProxy: " + Response.substr(idx + 15)); + Response.assign(Response.substr(0, idx + sizeof(DescSearch) - 1) + "ProtoProxy: " + Response.substr(idx + sizeof(DescSearch) - 1)); } cByteBuffer Packet(1000); Packet.WriteVarInt(0); // Packet type - status response From c33c8882b3a3f63f5fcf89f0cb63269c6f4bd228 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 15 Dec 2013 20:50:07 +0100 Subject: [PATCH 28/51] Fixed player spawning packet. The player was spawned 1.62 blocks below their pos. This fixes #323. --- src/Protocol/Protocol17x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index edf7d2529..5f939be1e 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -562,7 +562,7 @@ void cProtocol172::SendPlayerMoveLook(void) { cPacketizer Pkt(*this, 0x08); // Player Position And Look packet Pkt.WriteDouble(m_Client->GetPlayer()->GetPosX()); - Pkt.WriteDouble(m_Client->GetPlayer()->GetPosY()); + Pkt.WriteDouble(m_Client->GetPlayer()->GetStance()); // Protocol docs say this is PosY, but #323 says this is eye-pos Pkt.WriteDouble(m_Client->GetPlayer()->GetPosZ()); Pkt.WriteFloat((float)m_Client->GetPlayer()->GetYaw()); Pkt.WriteFloat((float)m_Client->GetPlayer()->GetPitch()); From 007d668c1bdd29bc6d28de0db2681f5c2f77ed5c Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 15 Dec 2013 21:25:13 +0100 Subject: [PATCH 29/51] Server saves if a player is flying. --- src/Entities/Player.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 38b911fd2..5165c2f8a 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1517,6 +1517,7 @@ bool cPlayer::LoadFromDisk() m_FoodExhaustionLevel = root.get("foodExhaustion", 0).asDouble(); m_LifetimeTotalXp = (short) root.get("xpTotal", 0).asInt(); m_CurrentXp = (short) root.get("xpCurrent", 0).asInt(); + m_IsFlying = root.get("isflying", 0).asBool(); //SetExperience(root.get("experience", 0).asInt()); @@ -1567,7 +1568,8 @@ bool cPlayer::SaveToDisk() root["foodSaturation"] = m_FoodSaturationLevel; root["foodTickTimer"] = m_FoodTickTimer; root["foodExhaustion"] = m_FoodExhaustionLevel; - root["world"] = GetWorld()->GetName(); + root["world"] = GetWorld()->GetName(); + root["isflying"] = IsFlying(); if (m_GameMode == GetWorld()->GetGameMode()) { From e024278b026c34abaccd46593deefde0ee39ee18 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 15 Dec 2013 21:17:03 +0100 Subject: [PATCH 30/51] Fixed multiple player spawn broadcasts. --- src/ClientHandle.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f3deefe0b..d082725b6 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -270,9 +270,6 @@ void cClientHandle::Authenticate(void) m_Player->Initialize(World); m_State = csAuthenticated; - // Broadcast this player's spawning to all other players in the same chunk - m_Player->GetWorld()->BroadcastSpawnEntity(*m_Player, this); - cRoot::Get()->GetPluginManager()->CallHookPlayerSpawned(*m_Player); } From f521cbeb31e90e4c5c25edb6686544530ddbaf99 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 16 Dec 2013 10:41:35 +0100 Subject: [PATCH 31/51] Fixed cClientHandle::Tick() being called from two threads. When the player was initialized, the Tick() function continued to stream chunk, while the cWorld called Tick() from its tick thread. Final fix for #187. --- src/ClientHandle.cpp | 49 ++++++++++++++++++++++++++++++++++++----- src/ClientHandle.h | 4 ++++ src/Entities/Player.cpp | 22 ------------------ src/Entities/Player.h | 2 -- src/Server.cpp | 2 +- 5 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d082725b6..8a41b5fac 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1476,12 +1476,6 @@ void cClientHandle::Tick(float a_Dt) } m_Protocol->DataReceived(IncomingData.data(), IncomingData.size()); - if (m_State == csAuthenticated) - { - StreamChunks(); - m_State = csDownloadingWorld; - } - m_TimeSinceLastPacket += a_Dt; if (m_TimeSinceLastPacket > 30000.f) // 30 seconds time-out { @@ -1536,6 +1530,49 @@ 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; + { + cCSLock Lock(m_CSIncomingData); + std::swap(IncomingData, m_IncomingData); + } + m_Protocol->DataReceived(IncomingData.data(), IncomingData.size()); + + if (m_State == csAuthenticated) + { + StreamChunks(); + + // Remove the client handle from the server, it will be ticked from its cPlayer object from now on + cRoot::Get()->GetServer()->ClientMovedToWorld(this); + + // Add the player to the world (start ticking from there): + m_State = csDownloadingWorld; + m_Player->GetWorld()->AddPlayer(m_Player); + return; + } + + m_TimeSinceLastPacket += a_Dt; + if (m_TimeSinceLastPacket > 30000.f) // 30 seconds time-out + { + SendDisconnect("Nooooo!! You timed out! D: Come back!"); + Destroy(); + } +} + + + + + void cClientHandle::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle) { m_Protocol->SendAttachEntity(a_Entity, a_Vehicle); diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 147a5b2b3..18274f6ae 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -79,7 +79,11 @@ public: inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); } + /// Called while the client is being ticked from the world via its cPlayer object void Tick(float a_Dt); + + /// Called while the client is being ticked from the cServer object + void ServerTick(float a_Dt); void Destroy(void); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 5165c2f8a..7e7d77433 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -137,28 +137,6 @@ cPlayer::~cPlayer(void) -bool cPlayer::Initialize(cWorld * a_World) -{ - ASSERT(a_World != NULL); - - if (super::Initialize(a_World)) - { - // Remove the client handle from the server, it will be ticked from this object from now on - if (m_ClientHandle != NULL) - { - cRoot::Get()->GetServer()->ClientMovedToWorld(m_ClientHandle); - } - - GetWorld()->AddPlayer(this); - return true; - } - return false; -} - - - - - void cPlayer::Destroyed() { CloseWindow(false); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index a09f7f489..59e941040 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -41,8 +41,6 @@ public: cPlayer(cClientHandle * a_Client, const AString & a_PlayerName); virtual ~cPlayer(); - virtual bool Initialize(cWorld * a_World) override; - virtual void SpawnOn(cClientHandle & a_Client) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; diff --git a/src/Server.cpp b/src/Server.cpp index f90f7a474..a93be9a5b 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -402,7 +402,7 @@ void cServer::TickClients(float a_Dt) itr = m_Clients.erase(itr); continue; } - (*itr)->Tick(a_Dt); + (*itr)->ServerTick(a_Dt); ++itr; } // for itr - m_Clients[] } From 324fa55bf0c72f61ce8b5dfc3df7770d61a8e25f Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 16 Dec 2013 18:01:33 +0100 Subject: [PATCH 32/51] You can spawn boats on water. --- src/Items/ItemBoat.h | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h index 6e3395f1d..c50171c0c 100644 --- a/src/Items/ItemBoat.h +++ b/src/Items/ItemBoat.h @@ -10,6 +10,7 @@ #pragma once #include "../Entities/Boat.h" +#include "../LineBlockTracer.h" @@ -30,23 +31,47 @@ public: virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override { - if (a_Dir < 0) + if (a_Dir > 0) { return false; } + + class cCallbacks : + public cBlockTracer::cCallbacks + { + public: + Vector3d Pos; + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override + { + if (a_BlockType != E_BLOCK_AIR) + { + Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); + return true; + } + return false; + } + } Callbacks; - double x = (double)a_BlockX + 0.5; - double y = (double)a_BlockY + 0.5; - double z = (double)a_BlockZ + 0.5; + cLineBlockTracer Tracer(*a_World, Callbacks); + Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector()); + Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5); - cBoat * Boat = NULL; + Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); - Boat = new cBoat (x, y, z); + double x = Callbacks.Pos.x; + double y = Callbacks.Pos.y; + double z = Callbacks.Pos.z; + + if (x == 0 && y == 0 && z == 0) + { + return false; + } + + cBoat * Boat = new cBoat(x, y + 1, z); Boat->Initialize(a_World); return true; } - } ; From 459d6369484107fbba93817469d038718ce41da2 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 16 Dec 2013 18:02:33 +0100 Subject: [PATCH 33/51] Added HandleSpeedFromAttachee so an entity can override the function. --- src/Entities/Entity.cpp | 18 ++++++++++++++---- src/Entities/Entity.h | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 0a2145e81..7721d58b3 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1341,6 +1341,19 @@ void cEntity::AddSpeedZ(double a_AddSpeedZ) +void cEntity::HandleSpeedFromAttachee(float a_Forward, float a_Sideways) +{ + Vector3d LookVector = m_Attachee->GetLookVector(); + double AddSpeedX = LookVector.x * a_Forward + LookVector.z * a_Sideways; + double AddSpeedZ = LookVector.z * a_Forward - LookVector.x * a_Sideways; + SetSpeed(AddSpeedX, 0, AddSpeedZ); + BroadcastMovementUpdate(); +} + + + + + void cEntity::SteerVehicle(float a_Forward, float a_Sideways) { if (m_AttachedTo == NULL) @@ -1349,10 +1362,7 @@ void cEntity::SteerVehicle(float a_Forward, float a_Sideways) } if ((a_Forward != 0) || (a_Sideways != 0)) { - Vector3d LookVector = GetLookVector(); - double AddSpeedX = LookVector.x * a_Forward + LookVector.z * a_Sideways; - double AddSpeedZ = LookVector.z * a_Forward - LookVector.x * a_Sideways; - m_AttachedTo->AddSpeed(AddSpeedX, 0, AddSpeedZ); + m_AttachedTo->HandleSpeedFromAttachee(a_Forward, a_Sideways); } } diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index de5f176ae..8d1692c98 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -197,6 +197,7 @@ public: void AddSpeedY (double a_AddSpeedY); void AddSpeedZ (double a_AddSpeedZ); + virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways); void SteerVehicle(float a_Forward, float a_Sideways); inline int GetUniqueID(void) const { return m_UniqueID; } From 199123d4f23aa6d1957b96382c96bd89cbcdf092 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 16 Dec 2013 18:03:39 +0100 Subject: [PATCH 34/51] Boats drop a boat pickup when destroyed by hand. You can now actualy use boats. --- src/Entities/Boat.cpp | 33 +++++++++++++++++++++++++++++++-- src/Entities/Boat.h | 3 ++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp index 56e766dd4..184aeeeeb 100644 --- a/src/Entities/Boat.cpp +++ b/src/Entities/Boat.cpp @@ -39,6 +39,15 @@ void cBoat::DoTakeDamage(TakeDamageInfo & TDI) if (GetHealth() == 0) { + if (TDI.Attacker != NULL) + { + if (TDI.Attacker->IsPlayer()) + { + cItems Pickups; + Pickups.Add(cItem(E_ITEM_BOAT)); + m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 0, 0, 0, true); + } + } Destroy(true); } } @@ -76,12 +85,32 @@ void cBoat::OnRightClicked(cPlayer & a_Player) -void cBoat::HandlePhysics(float a_Dt, cChunk & a_Chunk) +void cBoat::Tick(float a_Dt, cChunk & a_Chunk) { - super::HandlePhysics(a_Dt, a_Chunk); + super::Tick(a_Dt, a_Chunk); BroadcastMovementUpdate(); + SetSpeed(GetSpeed() * 0.97); // Slowly decrease the speed. + if (IsBlockWater(m_World->GetBlock((int) GetPosX(), (int) GetPosY(), (int) GetPosZ()))) + { + SetSpeedY(1); + } } + +void cBoat::HandleSpeedFromAttachee(float a_Forward, float a_Sideways) +{ + if (GetSpeed().Length() > 7) + { + return; + } + + Vector3d ToAddSpeed(m_Attachee->GetLookVector() * (a_Sideways * 1.5)); + ToAddSpeed.y = 0; + + AddSpeed(ToAddSpeed); +} + + \ No newline at end of file diff --git a/src/Entities/Boat.h b/src/Entities/Boat.h index 8c51ab86c..c4c9afe7a 100644 --- a/src/Entities/Boat.h +++ b/src/Entities/Boat.h @@ -27,7 +27,8 @@ public: virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void OnRightClicked(cPlayer & a_Player) override; virtual void DoTakeDamage(TakeDamageInfo & TDI) override; - virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways) override; cBoat(double a_X, double a_Y, double a_Z); } ; From 3e6fd5c6e59aace26fcb2a63bbff4ec096a83ce5 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 16 Dec 2013 17:35:20 +0000 Subject: [PATCH 35/51] Removed some old cRedstone remnants --- src/ClientHandle.h | 1 - src/World.cpp | 24 ------------------------ src/World.h | 5 ----- 3 files changed, 30 deletions(-) diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 18274f6ae..b426153b9 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -29,7 +29,6 @@ class cExpOrb; class cPickup; class cPlayer; class cProtocol; -class cRedstone; class cWindow; class cFallingBlock; class cItemHandler; diff --git a/src/World.cpp b/src/World.cpp index 35887c07d..f81456334 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -234,7 +234,6 @@ cWorld::cWorld(const AString & a_WorldName) : m_WorldAge(0), m_TimeOfDay(0), m_LastTimeUpdate(0), - m_RSList(0), m_Weather(eWeather_Sunny), m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) m_TickThread(*this), @@ -716,29 +715,6 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) } TickMobs(a_Dt); - - std::vector m_RSList_copy(m_RSList); - - m_RSList.clear(); - - std::vector::const_iterator cii; // FIXME - Please rename this variable, WTF is cii??? Use human readable variable names or common abbreviations (i, idx, itr, iter) - for (cii = m_RSList_copy.begin(); cii != m_RSList_copy.end();) - { - int tempX = *cii; cii++; - int tempY = *cii; cii++; - int tempZ = *cii; cii++; - int state = *cii; cii++; - - if ((state == 11111) && ((int)GetBlock(tempX, tempY, tempZ) == E_BLOCK_REDSTONE_TORCH_OFF)) - { - FastSetBlock(tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_ON, (int)GetBlockMeta(tempX, tempY, tempZ)); - } - else if ((state == 00000) && ((int)GetBlock(tempX, tempY, tempZ) == E_BLOCK_REDSTONE_TORCH_ON)) - { - FastSetBlock(tempX, tempY, tempZ, E_BLOCK_REDSTONE_TORCH_OFF, (int)GetBlockMeta(tempX, tempY, tempZ)); - } - } - m_RSList_copy.erase(m_RSList_copy.begin(),m_RSList_copy.end()); } diff --git a/src/World.h b/src/World.h index 16d7f5146..2d9e8b551 100644 --- a/src/World.h +++ b/src/World.h @@ -27,7 +27,6 @@ -class cRedstone; class cFireSimulator; class cFluidSimulator; class cSandSimulator; @@ -668,10 +667,6 @@ private: bool m_bEnabledPVP; bool m_IsDeepSnowEnabled; bool m_ShouldLavaSpawnFire; - - // The cRedstone class simulates redstone and needs access to m_RSList - // friend class cRedstone; - std::vector m_RSList; std::vector m_BlockTickQueue; std::vector m_BlockTickQueueCopy; // Second is for safely removing the objects from the queue From 6b21dc6d11673f612d3ca6f3f4ced8809d61ef47 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 16 Dec 2013 20:53:43 +0100 Subject: [PATCH 36/51] Using suggestions for Boat placing. --- src/Items/ItemBoat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h index c50171c0c..0326b13b8 100644 --- a/src/Items/ItemBoat.h +++ b/src/Items/ItemBoat.h @@ -62,7 +62,7 @@ public: double y = Callbacks.Pos.y; double z = Callbacks.Pos.z; - if (x == 0 && y == 0 && z == 0) + if ((x == 0) && (y == 0) && (z == 0)) { return false; } From 59165dcba5df9fc30f4a9795b550364eb89e9c2b Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 16 Dec 2013 21:50:57 +0100 Subject: [PATCH 37/51] Boats spawn on top of a block. not between 4 blocks. --- src/Items/ItemBoat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h index 0326b13b8..79c8e9589 100644 --- a/src/Items/ItemBoat.h +++ b/src/Items/ItemBoat.h @@ -67,7 +67,7 @@ public: return false; } - cBoat * Boat = new cBoat(x, y + 1, z); + cBoat * Boat = new cBoat(x + 0.5, y + 1, z + 0.5); Boat->Initialize(a_World); return true; From daade8ddee96eee7bfe74c75f2de1d2994258b74 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 16 Dec 2013 22:02:28 +0100 Subject: [PATCH 38/51] Fixed multiple inheritance in ToLua++. This fixes #422. --- src/Bindings/Bindings.cpp | 113 +++++++++++++++++++++++--- src/Bindings/Bindings.h | 2 +- src/Bindings/LuaWindow.h | 8 +- src/BlockEntities/ChestEntity.h | 8 +- src/BlockEntities/DropSpenserEntity.h | 8 +- src/BlockEntities/EnderChestEntity.h | 8 +- src/BlockEntities/FurnaceEntity.h | 8 +- src/BlockEntities/HopperEntity.h | 8 +- 8 files changed, 127 insertions(+), 36 deletions(-) diff --git a/src/Bindings/Bindings.cpp b/src/Bindings/Bindings.cpp index 5536ab2b0..e46e42aa4 100644 --- a/src/Bindings/Bindings.cpp +++ b/src/Bindings/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/15/13 20:25:06. +** Generated automatically by tolua++-1.0.92 on 12/16/13 21:57:34. */ #ifndef __cplusplus @@ -220,45 +220,46 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"cItemGrid"); tolua_usertype(tolua_S,"cHTTPServer::cCallbacks"); tolua_usertype(tolua_S,"cLuaWindow"); - tolua_usertype(tolua_S,"cInventory"); + tolua_usertype(tolua_S,"cServer"); tolua_usertype(tolua_S,"cHopperEntity"); tolua_usertype(tolua_S,"std::vector"); - tolua_usertype(tolua_S,"cBlockEntityWithItems"); tolua_usertype(tolua_S,"cWindow"); + tolua_usertype(tolua_S,"cBlockEntityWithItems"); tolua_usertype(tolua_S,"cCraftingGrid"); tolua_usertype(tolua_S,"cBlockArea"); tolua_usertype(tolua_S,"cGroup"); tolua_usertype(tolua_S,"cTracer"); - tolua_usertype(tolua_S,"cItem"); tolua_usertype(tolua_S,"cBoundingBox"); + tolua_usertype(tolua_S,"cItem"); + tolua_usertype(tolua_S,"cCuboid"); tolua_usertype(tolua_S,"cArrowEntity"); tolua_usertype(tolua_S,"cDropSpenserEntity"); - tolua_usertype(tolua_S,"cCuboid"); tolua_usertype(tolua_S,"Vector3i"); tolua_usertype(tolua_S,"Vector3d"); + tolua_usertype(tolua_S,"cTNTEntity"); tolua_usertype(tolua_S,"cNoteEntity"); - tolua_usertype(tolua_S,"cServer"); + tolua_usertype(tolua_S,"cWebAdmin"); tolua_usertype(tolua_S,"cBlockEntity"); tolua_usertype(tolua_S,"cCriticalSection"); tolua_usertype(tolua_S,"HTTPTemplateRequest"); tolua_usertype(tolua_S,"cPickup"); tolua_usertype(tolua_S,"cItems"); tolua_usertype(tolua_S,"cClientHandle"); - tolua_usertype(tolua_S,"cWebAdmin"); - tolua_usertype(tolua_S,"cChatColor"); tolua_usertype(tolua_S,"HTTPRequest"); - tolua_usertype(tolua_S,"cIniFile"); + tolua_usertype(tolua_S,"cChatColor"); tolua_usertype(tolua_S,"HTTPFormData"); + tolua_usertype(tolua_S,"cIniFile"); tolua_usertype(tolua_S,"cSignEntity"); + tolua_usertype(tolua_S,"cDropperEntity"); tolua_usertype(tolua_S,"cPawn"); tolua_usertype(tolua_S,"cThrownEggEntity"); tolua_usertype(tolua_S,"cGroupManager"); + tolua_usertype(tolua_S,"cBlockEntityWindowOwner"); tolua_usertype(tolua_S,"cPluginManager"); - tolua_usertype(tolua_S,"cDropperEntity"); tolua_usertype(tolua_S,"cProjectileEntity"); tolua_usertype(tolua_S,"cItemGrid::cListener"); + tolua_usertype(tolua_S,"cInventory"); tolua_usertype(tolua_S,"cPlayer"); - tolua_usertype(tolua_S,"cTNTEntity"); } /* method: new of class cIniFile */ @@ -3279,6 +3280,23 @@ static int tolua_AllToLua_cLuaWindow_GetContents00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* get function: __cItemGrid of class cLuaWindow */ +#ifndef TOLUA_DISABLE_tolua_get_cLuaWindow___cItemGrid__cListener__ +static int tolua_get_cLuaWindow___cItemGrid__cListener__(lua_State* tolua_S) +{ + cLuaWindow* self = (cLuaWindow*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cItemGrid'",NULL); +#endif +#ifdef __cplusplus + tolua_pushusertype(tolua_S,(void*)static_cast(self), "cItemGrid::cListener"); +#else + tolua_pushusertype(tolua_S,(void*)((cItemGrid::cListener*)self), "cItemGrid::cListener"); +#endif + return 1; +} +#endif //#ifndef TOLUA_DISABLE + /* function: BlockStringToType */ #ifndef TOLUA_DISABLE_tolua_AllToLua_BlockStringToType00 static int tolua_AllToLua_BlockStringToType00(lua_State* tolua_S) @@ -18791,6 +18809,23 @@ static int tolua_AllToLua_cBlockEntityWithItems_GetContents00(lua_State* tolua_S } #endif //#ifndef TOLUA_DISABLE +/* get function: __cBlockEntityWindowOwner__ of class cChestEntity */ +#ifndef TOLUA_DISABLE_tolua_get_cChestEntity___cBlockEntityWindowOwner__ +static int tolua_get_cChestEntity___cBlockEntityWindowOwner__(lua_State* tolua_S) +{ + cChestEntity* self = (cChestEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cBlockEntityWindowOwner__'",NULL); +#endif +#ifdef __cplusplus + tolua_pushusertype(tolua_S,(void*)static_cast(self), "cBlockEntityWindowOwner"); +#else + tolua_pushusertype(tolua_S,(void*)((cBlockEntityWindowOwner*)self), "cBlockEntityWindowOwner"); +#endif + return 1; +} +#endif //#ifndef TOLUA_DISABLE + /* method: AddDropSpenserDir of class cDropSpenserEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cDropSpenserEntity_AddDropSpenserDir00 static int tolua_AllToLua_cDropSpenserEntity_AddDropSpenserDir00(lua_State* tolua_S) @@ -18897,6 +18932,23 @@ static int tolua_AllToLua_cDropSpenserEntity_SetRedstonePower00(lua_State* tolua } #endif //#ifndef TOLUA_DISABLE +/* get function: __cBlockEntityWindowOwner__ of class cDropSpenserEntity */ +#ifndef TOLUA_DISABLE_tolua_get_cDropSpenserEntity___cBlockEntityWindowOwner__ +static int tolua_get_cDropSpenserEntity___cBlockEntityWindowOwner__(lua_State* tolua_S) +{ + cDropSpenserEntity* self = (cDropSpenserEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cBlockEntityWindowOwner__'",NULL); +#endif +#ifdef __cplusplus + tolua_pushusertype(tolua_S,(void*)static_cast(self), "cBlockEntityWindowOwner"); +#else + tolua_pushusertype(tolua_S,(void*)((cBlockEntityWindowOwner*)self), "cBlockEntityWindowOwner"); +#endif + return 1; +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetInputSlot of class cFurnaceEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cFurnaceEntity_GetInputSlot00 static int tolua_AllToLua_cFurnaceEntity_GetInputSlot00(lua_State* tolua_S) @@ -19220,6 +19272,40 @@ static int tolua_AllToLua_cFurnaceEntity_HasFuelTimeLeft00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* get function: __cBlockEntityWindowOwner__ of class cFurnaceEntity */ +#ifndef TOLUA_DISABLE_tolua_get_cFurnaceEntity___cBlockEntityWindowOwner__ +static int tolua_get_cFurnaceEntity___cBlockEntityWindowOwner__(lua_State* tolua_S) +{ + cFurnaceEntity* self = (cFurnaceEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cBlockEntityWindowOwner__'",NULL); +#endif +#ifdef __cplusplus + tolua_pushusertype(tolua_S,(void*)static_cast(self), "cBlockEntityWindowOwner"); +#else + tolua_pushusertype(tolua_S,(void*)((cBlockEntityWindowOwner*)self), "cBlockEntityWindowOwner"); +#endif + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: __cBlockEntityWindowOwner__ of class cHopperEntity */ +#ifndef TOLUA_DISABLE_tolua_get_cHopperEntity___cBlockEntityWindowOwner__ +static int tolua_get_cHopperEntity___cBlockEntityWindowOwner__(lua_State* tolua_S) +{ + cHopperEntity* self = (cHopperEntity*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in accessing variable '__cBlockEntityWindowOwner__'",NULL); +#endif +#ifdef __cplusplus + tolua_pushusertype(tolua_S,(void*)static_cast(self), "cBlockEntityWindowOwner"); +#else + tolua_pushusertype(tolua_S,(void*)((cBlockEntityWindowOwner*)self), "cBlockEntityWindowOwner"); +#endif + return 1; +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetRecord of class cJukeboxEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cJukeboxEntity_GetRecord00 static int tolua_AllToLua_cJukeboxEntity_GetRecord00(lua_State* tolua_S) @@ -30110,6 +30196,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,".call",tolua_AllToLua_cLuaWindow_new00_local); tolua_function(tolua_S,"delete",tolua_AllToLua_cLuaWindow_delete00); tolua_function(tolua_S,"GetContents",tolua_AllToLua_cLuaWindow_GetContents00); + tolua_variable(tolua_S,"__cItemGrid__cListener__",tolua_get_cLuaWindow___cItemGrid__cListener__,NULL); tolua_endmodule(tolua_S); tolua_constant(tolua_S,"E_BLOCK_AIR",E_BLOCK_AIR); tolua_constant(tolua_S,"E_BLOCK_STONE",E_BLOCK_STONE); @@ -31549,6 +31636,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_beginmodule(tolua_S,"cChestEntity"); tolua_constant(tolua_S,"ContentsHeight",cChestEntity::ContentsHeight); tolua_constant(tolua_S,"ContentsWidth",cChestEntity::ContentsWidth); + tolua_variable(tolua_S,"__cBlockEntityWindowOwner__",tolua_get_cChestEntity___cBlockEntityWindowOwner__,NULL); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cDropSpenserEntity","cDropSpenserEntity","cBlockEntityWithItems",NULL); tolua_beginmodule(tolua_S,"cDropSpenserEntity"); @@ -31557,6 +31645,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"AddDropSpenserDir",tolua_AllToLua_cDropSpenserEntity_AddDropSpenserDir00); tolua_function(tolua_S,"Activate",tolua_AllToLua_cDropSpenserEntity_Activate00); tolua_function(tolua_S,"SetRedstonePower",tolua_AllToLua_cDropSpenserEntity_SetRedstonePower00); + tolua_variable(tolua_S,"__cBlockEntityWindowOwner__",tolua_get_cDropSpenserEntity___cBlockEntityWindowOwner__,NULL); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cDispenserEntity","cDispenserEntity","cDropSpenserEntity",NULL); tolua_beginmodule(tolua_S,"cDispenserEntity"); @@ -31581,12 +31670,14 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetCookTimeLeft",tolua_AllToLua_cFurnaceEntity_GetCookTimeLeft00); tolua_function(tolua_S,"GetFuelBurnTimeLeft",tolua_AllToLua_cFurnaceEntity_GetFuelBurnTimeLeft00); tolua_function(tolua_S,"HasFuelTimeLeft",tolua_AllToLua_cFurnaceEntity_HasFuelTimeLeft00); + tolua_variable(tolua_S,"__cBlockEntityWindowOwner__",tolua_get_cFurnaceEntity___cBlockEntityWindowOwner__,NULL); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cHopperEntity","cHopperEntity","cBlockEntityWithItems",NULL); tolua_beginmodule(tolua_S,"cHopperEntity"); tolua_constant(tolua_S,"ContentsHeight",cHopperEntity::ContentsHeight); tolua_constant(tolua_S,"ContentsWidth",cHopperEntity::ContentsWidth); tolua_constant(tolua_S,"TICKS_PER_TRANSFER",cHopperEntity::TICKS_PER_TRANSFER); + tolua_variable(tolua_S,"__cBlockEntityWindowOwner__",tolua_get_cHopperEntity___cBlockEntityWindowOwner__,NULL); tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cJukeboxEntity","cJukeboxEntity","cBlockEntity",NULL); tolua_beginmodule(tolua_S,"cJukeboxEntity"); diff --git a/src/Bindings/Bindings.h b/src/Bindings/Bindings.h index ef3b6b49e..012a8b13a 100644 --- a/src/Bindings/Bindings.h +++ b/src/Bindings/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/15/13 20:25:06. +** Generated automatically by tolua++-1.0.92 on 12/16/13 21:57:35. */ /* Exported function */ diff --git a/src/Bindings/LuaWindow.h b/src/Bindings/LuaWindow.h index 58d26ef96..dab99a2e2 100644 --- a/src/Bindings/LuaWindow.h +++ b/src/Bindings/LuaWindow.h @@ -33,10 +33,10 @@ Additionally, to forbid Lua from deleting this object while it is used by player cPlayer:OpenWindow check if the window is of this class, and if so, make a global Lua reference for this object. This reference needs to be unreferenced in the Destroy() function. */ -class cLuaWindow : // tolua_export - public cItemGrid::cListener, - // tolua_begin - public cWindow +// tolua_begin +class cLuaWindow : + public cWindow, + public cItemGrid::cListener { typedef cWindow super; diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h index 4f2c21e91..4110de1f3 100644 --- a/src/BlockEntities/ChestEntity.h +++ b/src/BlockEntities/ChestEntity.h @@ -21,10 +21,10 @@ class cNBTData; -class cChestEntity : // tolua_export - public cBlockEntityWindowOwner, - // tolua_begin - public cBlockEntityWithItems +// tolua_begin +class cChestEntity : + public cBlockEntityWithItems, + public cBlockEntityWindowOwner { typedef cBlockEntityWithItems super; diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index 0e9039915..f2f1eba36 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -29,10 +29,10 @@ class cServer; -class cDropSpenserEntity : // tolua_export - public cBlockEntityWindowOwner, - // tolua_begin - public cBlockEntityWithItems +// tolua_begin +class cDropSpenserEntity : + public cBlockEntityWithItems, + public cBlockEntityWindowOwner { typedef cBlockEntityWithItems super; diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h index 683b652b2..0ee3cab3b 100644 --- a/src/BlockEntities/EnderChestEntity.h +++ b/src/BlockEntities/EnderChestEntity.h @@ -21,10 +21,10 @@ class cNBTData; -class cEnderChestEntity : // tolua_export - public cBlockEntityWindowOwner, - // tolua_begin - public cBlockEntityWithItems +// tolua_begin +class cEnderChestEntity : + public cBlockEntityWithItems, + public cBlockEntityWindowOwner { typedef cBlockEntityWithItems super; diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h index 9464fd175..8b695d61a 100644 --- a/src/BlockEntities/FurnaceEntity.h +++ b/src/BlockEntities/FurnaceEntity.h @@ -21,10 +21,10 @@ class cServer; -class cFurnaceEntity : // tolua_export - public cBlockEntityWindowOwner, - // tolua_begin - public cBlockEntityWithItems +// tolua_begin +class cFurnaceEntity : + public cBlockEntityWithItems, + public cBlockEntityWindowOwner { typedef cBlockEntityWithItems super; diff --git a/src/BlockEntities/HopperEntity.h b/src/BlockEntities/HopperEntity.h index 3eaa05b7c..2c8b301fe 100644 --- a/src/BlockEntities/HopperEntity.h +++ b/src/BlockEntities/HopperEntity.h @@ -16,10 +16,10 @@ -class cHopperEntity : // tolua_export - public cBlockEntityWindowOwner, - // tolua_begin - public cBlockEntityWithItems +// tolua_begin +class cHopperEntity : + public cBlockEntityWithItems, + public cBlockEntityWindowOwner { typedef cBlockEntityWithItems super; From 5d4e1725d43809baf667c51cba8fa8f1dec3220b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 16 Dec 2013 22:13:31 +0100 Subject: [PATCH 39/51] APIDump: Ignoring the multi-inheritance members. We may get to documenting them one day, but for now they are unused anyway, so there's no point in documenting them. They are a by-product of multiple inheritance, re-introduced due to #422. --- MCServer/Plugins/APIDump/APIDesc.lua | 11 ++++++++++- MCServer/Plugins/APIDump/main_APIDump.lua | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 214b45a70..5bc4a5f39 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2713,8 +2713,8 @@ end "os", "string", "table", - "g_TrackedPages", "g_Stats", + "g_TrackedPages", }, IgnoreFunctions = @@ -2747,6 +2747,15 @@ end "WriteStats", }, + IgnoreConstants = + { + "cChestEntity.__cBlockEntityWindowOwner__", + "cDropSpenserEntity.__cBlockEntityWindowOwner__", + "cFurnaceEntity.__cBlockEntityWindowOwner__", + "cHopperEntity.__cBlockEntityWindowOwner__", + "cLuaWindow.__cItemGrid__cListener__", + }, + IgnoreVariables = { "__.*__", -- tolua exports multiple inheritance this way diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua index de4239f7e..ec5569f55 100644 --- a/MCServer/Plugins/APIDump/main_APIDump.lua +++ b/MCServer/Plugins/APIDump/main_APIDump.lua @@ -700,6 +700,15 @@ function ReadDescriptions(a_API) end ); + -- Remove ignored constants: + local NewConstants = {}; + for j, cn in ipairs(cls.Constants) do + if (not(IsFunctionIgnored(cls.Name, cn.Name))) then + table.insert(NewConstants, cn); + end + end -- for j, cn + cls.Constants = NewConstants; + -- Sort the constants: table.sort(cls.Constants, function(c1, c2) @@ -707,7 +716,7 @@ function ReadDescriptions(a_API) end ); - -- Remove ignored functions: + -- Remove ignored member variables: local NewVariables = {}; for j, var in ipairs(cls.Variables) do if (not(IsVariableIgnored(cls.Name .. "." .. var.Name))) then From d28142ff719ac79977d00fa2f337fecd173ea88d Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 17 Dec 2013 17:33:48 +0100 Subject: [PATCH 40/51] Made buckets work when the player does not 'look' at a block. This fixes #265 --- src/Items/ItemBucket.h | 85 ++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h index fa3d48da1..87f23b554 100644 --- a/src/Items/ItemBucket.h +++ b/src/Items/ItemBucket.h @@ -5,6 +5,7 @@ #include "../World.h" #include "../Simulator/FluidSimulator.h" #include "../Blocks/BlockHandler.h" +#include "../LineBlockTracer.h" @@ -39,45 +40,34 @@ public: bool ScoopUpFluid(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) { - if (a_BlockFace < 0) + if (a_BlockFace > 0) { return false; } - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - BLOCKTYPE ClickedBlock; - NIBBLETYPE ClickedMeta; - a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedMeta); - LOGD("Bucket Clicked BlockType %d, meta %d", ClickedBlock, ClickedMeta); - if (ClickedMeta != 0) + + Vector3i BlockPos; + GetBlockFromTrace(a_World, a_Player, BlockPos); + + if (a_World->GetBlockMeta(BlockPos.x, BlockPos.y, BlockPos.z) != 0) { // Not a source block return false; } - - if (a_Player->GetGameMode() == gmCreative) + + BLOCKTYPE Block = a_World->GetBlock(BlockPos.x, BlockPos.y, BlockPos.z); + ENUM_ITEM_ID NewItem; + + if (IsBlockWater(Block)) { - // In creative mode don't modify the inventory, just remove the fluid: - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); - return true; + NewItem = E_ITEM_WATER_BUCKET; } - - ENUM_ITEM_ID NewItem = E_ITEM_EMPTY; - switch (ClickedBlock) + else if (IsBlockLava(Block)) { - case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: - { - NewItem = E_ITEM_WATER_BUCKET; - break; - } - case E_BLOCK_LAVA: - case E_BLOCK_STATIONARY_LAVA: - { - NewItem = E_ITEM_LAVA_BUCKET; - break; - } - - default: return false; + NewItem = E_ITEM_LAVA_BUCKET; + } + else + { + return false; } // Remove the bucket from the inventory @@ -89,11 +79,10 @@ public: } // Give new bucket, filled with fluid: - cItem Item(NewItem, 1); - a_Player->GetInventory().AddItem(Item, true, true); + a_Player->GetInventory().AddItem(cItem(NewItem), true, true); // Remove water / lava block - a_Player->GetWorld()->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_Player->GetWorld()->SetBlock(BlockPos.x, BlockPos.y, BlockPos.z, E_BLOCK_AIR, 0); return true; } @@ -157,4 +146,36 @@ public: return true; } + bool GetBlockFromTrace(cWorld * a_World, cPlayer * a_Player, Vector3i & BlockPos) + { + class cCallbacks : + public cBlockTracer::cCallbacks + { + public: + Vector3d Pos; + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override + { + if (a_BlockMeta != 0) // Even if it was a water block it would not be a source. + { + return false; + } + if ((IsBlockWater(a_BlockType)) || (IsBlockLava(a_BlockType))) + { + Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); + return true; + } + return false; + } + } Callbacks; + + cLineBlockTracer Tracer(*a_World, Callbacks); + Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector()); + Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5); + + Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); + + BlockPos.Set((int) Callbacks.Pos.x, (int) Callbacks.Pos.y, (int) Callbacks.Pos.z); + return true; + } + }; From f1a1d6fa5c64a88d9b72d70e70c085ce75830933 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 17 Dec 2013 19:42:06 +0100 Subject: [PATCH 41/51] Using Recommendations. --- src/Items/ItemBucket.h | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h index 87f23b554..4cddd64d8 100644 --- a/src/Items/ItemBucket.h +++ b/src/Items/ItemBucket.h @@ -46,7 +46,10 @@ public: } Vector3i BlockPos; - GetBlockFromTrace(a_World, a_Player, BlockPos); + if (!GetBlockFromTrace(a_World, a_Player, BlockPos)) + { + return false; // Nothing in range. + } if (a_World->GetBlockMeta(BlockPos.x, BlockPos.y, BlockPos.z) != 0) { @@ -70,16 +73,18 @@ public: return false; } - // Remove the bucket from the inventory - if (!a_Player->GetInventory().RemoveOneEquippedItem()) + // Give new bucket, filled with fluid when the gamemode is not creative: + if (!a_Player->IsGameModeCreative()) { - LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?"); - ASSERT(!"Inventory bucket mismatch"); - return true; + // Remove the bucket from the inventory + if (!a_Player->GetInventory().RemoveOneEquippedItem()) + { + LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?"); + ASSERT(!"Inventory bucket mismatch"); + return true; + } + a_Player->GetInventory().AddItem(cItem(NewItem), true, true); } - - // Give new bucket, filled with fluid: - a_Player->GetInventory().AddItem(cItem(NewItem), true, true); // Remove water / lava block a_Player->GetWorld()->SetBlock(BlockPos.x, BlockPos.y, BlockPos.z, E_BLOCK_AIR, 0); @@ -153,14 +158,16 @@ public: { public: Vector3d Pos; + bool HitFluid; virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override { if (a_BlockMeta != 0) // Even if it was a water block it would not be a source. { return false; } - if ((IsBlockWater(a_BlockType)) || (IsBlockLava(a_BlockType))) + if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) { + HitFluid = true; Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); return true; } @@ -174,6 +181,12 @@ public: Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); + if (!Callbacks.HitFluid) + { + return false; + } + + BlockPos.Set((int) Callbacks.Pos.x, (int) Callbacks.Pos.y, (int) Callbacks.Pos.z); return true; } From a1bfc8911846ccd9e4aaf36ee7759ab73d5d9844 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 17 Dec 2013 20:02:44 +0100 Subject: [PATCH 42/51] Renamed Pos to m_Pos. --- src/Items/ItemBucket.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h index 4cddd64d8..4f55db7f8 100644 --- a/src/Items/ItemBucket.h +++ b/src/Items/ItemBucket.h @@ -157,7 +157,7 @@ public: public cBlockTracer::cCallbacks { public: - Vector3d Pos; + Vector3i m_Pos; bool HitFluid; virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override { @@ -168,7 +168,7 @@ public: if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) { HitFluid = true; - Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); + m_Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); return true; } return false; @@ -187,7 +187,7 @@ public: } - BlockPos.Set((int) Callbacks.Pos.x, (int) Callbacks.Pos.y, (int) Callbacks.Pos.z); + BlockPos.Set(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z); return true; } From a74fdd902350d76aaad65cfc892dc0abbb59e792 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 17 Dec 2013 20:04:39 +0100 Subject: [PATCH 43/51] Forgot to change one Vector3d to Vector3i. --- src/Items/ItemBucket.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h index 4f55db7f8..9d1fc276b 100644 --- a/src/Items/ItemBucket.h +++ b/src/Items/ItemBucket.h @@ -168,7 +168,7 @@ public: if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) { HitFluid = true; - m_Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); + m_Pos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); return true; } return false; From a4f4ba534ee288c61a579986474296d3910f91e3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 17 Dec 2013 20:06:48 +0100 Subject: [PATCH 44/51] Fixed naming and initialization. --- src/Items/ItemBucket.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h index 9d1fc276b..c9a632580 100644 --- a/src/Items/ItemBucket.h +++ b/src/Items/ItemBucket.h @@ -151,6 +151,7 @@ public: return true; } + bool GetBlockFromTrace(cWorld * a_World, cPlayer * a_Player, Vector3i & BlockPos) { class cCallbacks : @@ -158,7 +159,14 @@ public: { public: Vector3i m_Pos; - bool HitFluid; + bool m_HasHitFluid; + + + cCallbacks(void) : + m_HasHitFluid(false) + { + } + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override { if (a_BlockMeta != 0) // Even if it was a water block it would not be a source. @@ -167,8 +175,8 @@ public: } if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) { - HitFluid = true; - m_Pos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); + m_HasHitFluid = true; + m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); return true; } return false; @@ -181,7 +189,7 @@ public: Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); - if (!Callbacks.HitFluid) + if (!Callbacks.m_HasHitFluid) { return false; } From bd568ed089a763f58188382175241f11bee690b7 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 17 Dec 2013 19:45:34 +0100 Subject: [PATCH 45/51] cBlockArea: origin is initialized in the constructor and the loader. --- src/BlockArea.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 5c15adfef..c9443c702 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -161,6 +161,9 @@ static void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBB // cBlockArea: cBlockArea::cBlockArea(void) : + m_OriginX(0), + m_OriginY(0), + m_OriginZ(0), m_SizeX(0), m_SizeY(0), m_SizeZ(0), @@ -190,6 +193,9 @@ void cBlockArea::Clear(void) delete[] m_BlockMetas; m_BlockMetas = NULL; delete[] m_BlockLight; m_BlockLight = NULL; delete[] m_BlockSkyLight; m_BlockSkyLight = NULL; + m_OriginX = 0; + m_OriginY = 0; + m_OriginZ = 0; m_SizeX = 0; m_SizeY = 0; m_SizeZ = 0; From f8f4ab88f6f8aad918b871c1989fc7698f8cde6a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 17 Dec 2013 19:56:17 +0100 Subject: [PATCH 46/51] Fixed player falling through the floor on spawn. The 1.7 client seems to have math issues with exact coords. Adding 0.001 to the Y coord fixed the problem. --- src/Protocol/Protocol17x.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 5f939be1e..fff5311f6 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -562,7 +562,11 @@ void cProtocol172::SendPlayerMoveLook(void) { cPacketizer Pkt(*this, 0x08); // Player Position And Look packet Pkt.WriteDouble(m_Client->GetPlayer()->GetPosX()); - Pkt.WriteDouble(m_Client->GetPlayer()->GetStance()); // Protocol docs say this is PosY, but #323 says this is eye-pos + + // Protocol docs say this is PosY, but #323 says this is eye-pos + // Moreover, the "+ 0.001" is there because otherwise the player falls through the block they were standing on. + Pkt.WriteDouble(m_Client->GetPlayer()->GetStance() + 0.001); + Pkt.WriteDouble(m_Client->GetPlayer()->GetPosZ()); Pkt.WriteFloat((float)m_Client->GetPlayer()->GetYaw()); Pkt.WriteFloat((float)m_Client->GetPlayer()->GetPitch()); From 09c47fabd2ebfdd929a0e237070b1a3d5e1968b3 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 17 Dec 2013 23:05:27 +0000 Subject: [PATCH 47/51] Fixed bad repeater power queuing in corner case Repeaters remain queued to power even if their original source has since unpowered. Also functionised and cleaned up code. --- src/Simulator/RedstoneSimulator.cpp | 160 +++++++++++++--------------- src/Simulator/RedstoneSimulator.h | 3 + 2 files changed, 78 insertions(+), 85 deletions(-) diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index 77301aafa..7eefd1ba6 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -562,109 +562,75 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState) { - // We do this so that the repeater can continually update block power status (without being affected by it's own block type, which would happen if the block powering code was in an IF statement) - bool IsOn = false; - if (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON) - { - IsOn = true; - } - NIBBLETYPE a_Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta & 0x3)) + // We do this so that the repeater can continually update block power status (without being affected by it's own block type, which would happen if the block powering code was in an IF statement) + bool IsOn = ((a_MyState == E_BLOCK_REDSTONE_REPEATER_ON) ? true : false); + bool IsSelfPowered = IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta & 0x3); + + if (IsSelfPowered && !IsOn) // Queue a power change if I am receiving power but not on { - if (!IsOn) + QueueRepeaterPowerChange(a_BlockX, a_BlockY, a_BlockZ, a_Meta, 0, true); + } + else if (!IsSelfPowered && IsOn) // Queue a power change if I am not receiving power but on + { + QueueRepeaterPowerChange(a_BlockX, a_BlockY, a_BlockZ, a_Meta, 0, false); + } + + for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); itr++) + { + if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { - bool ShouldCreate = true; - // If repeater is not on already (and is POWERED), see if it is in repeater list, or has reached delay time - for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); itr++) + continue; + } + + if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks? + { + if (itr->ShouldPowerOn) { - if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); + + switch (a_Meta & 0x3) // We only want the direction (bottom) bits { - if (itr->a_DelayTicks <= itr->a_ElapsedTicks) // Shouldn't need <=; just in case something happens + case 0x0: { - m_RepeatersDelayList.erase(itr); - ShouldCreate = false; - break; // Delay time reached, break straight out, and into the powering code + SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_REPEATER_ON); + break; } - else + case 0x1: { - itr->a_ElapsedTicks++; // Increment elapsed ticks and quit - return; + SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_REPEATER_ON); + break; + } + case 0x2: + { + SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_REPEATER_ON); + break; + } + case 0x3: + { + SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_REPEATER_ON); + break; } } - } - if (ShouldCreate) - { - // Self not in list, add self to list - sRepeatersDelayList RC; - RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); - RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2) + 1; // Gets the top two bits (delay time), shifts them into the lower two bits, and adds one (meta 0 = 1 tick; 1 = 2 etc.) - RC.a_ElapsedTicks = 0; - m_RepeatersDelayList.push_back(RC); + m_RepeatersDelayList.erase(itr); return; } - - m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // Only set if not on; SetBlock otherwise server doesn't set it in time for SimulateChunk's invalidation - } - switch (a_Meta & 0x3) // We only want the direction (bottom) bits - { - case 0x0: + else { - SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_REPEATER_ON); - break; - } - case 0x1: - { - SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_REPEATER_ON); - break; - } - case 0x2: - { - SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_REPEATER_ON); - break; - } - case 0x3: - { - SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_REPEATER_ON); - break; + m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); + m_RepeatersDelayList.erase(itr); + return; } } - } - else - { - if (IsOn) + else { - // If repeater is not off already (and is NOT POWERED), see if it is in repeater list, or has reached delay time - for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); itr++) - { - if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) - { - if (itr->a_DelayTicks <= itr->a_ElapsedTicks) // Shouldn't need <=; just in case something happens - { - m_RepeatersDelayList.erase(itr); - m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); - return; - } - else - { - itr->a_ElapsedTicks++; // Increment elapsed ticks and quit - return; - } - } - } - - // Self not in list, add self to list - sRepeatersDelayList RC; - RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); - RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2); // Repeaters power off slower than they power on, so no +1. Why? No idea. - RC.a_ElapsedTicks = 0; - m_RepeatersDelayList.push_back(RC); + itr->a_ElapsedTicks++; return; } } @@ -1299,6 +1265,30 @@ void cRedstoneSimulator::SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a +void cRedstoneSimulator::QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, short a_ElapsedTicks, bool ShouldPowerOn) +{ + for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); itr++) + { + if (itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) + { + return; + } + } + + // Self not in list, add self to list + sRepeatersDelayList RC; + RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); + RC.a_DelayTicks = ((a_Meta & 0xC) >> 0x2) + 1; // Gets the top two bits (delay time), shifts them into the lower two bits, and adds one (meta 0 = 1 tick; 1 = 2 etc.) + RC.a_ElapsedTicks = 0; + RC.ShouldPowerOn = ShouldPowerOn; + m_RepeatersDelayList.push_back(RC); + return; +} + + + + + cRedstoneSimulator::eRedstoneDirection cRedstoneSimulator::GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ) { int Dir = REDSTONE_NONE; diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index 9bdeb8f32..d40d88342 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -62,6 +62,7 @@ private: Vector3i a_BlockPos; short a_DelayTicks; short a_ElapsedTicks; + bool ShouldPowerOn; }; typedef std::vector PoweredBlocksList; @@ -127,6 +128,8 @@ private: void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock); /// Marks all blocks immediately surrounding a coordinate as powered void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock); + /// Queues a repeater to be powered or unpowered + void QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, short a_ElapsedTicks, 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); } From 13a22918e572d70c52a79ca8b57a59c2ffafb405 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 17 Dec 2013 23:05:42 +0000 Subject: [PATCH 48/51] Fixed wire powering blocks beneath --- src/Simulator/RedstoneSimulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index 7eefd1ba6..eb26d0ca3 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -90,7 +90,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c BLOCKTYPE DestBlockType; if ( !a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) || - !a_Chunk->UnboundedRelGetBlockType(DestRelX, itr->a_SourcePos.y, DestRelZ, DestBlockType) + !a_Chunk->UnboundedRelGetBlockType(DestRelX, itr->a_BlockPos.y, DestRelZ, DestBlockType) ) { continue; From 4402725c61a2e409d5c42eff89d4d330361d8726 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 18 Dec 2013 12:04:31 +0100 Subject: [PATCH 49/51] Removed offending tr1/memory header inclusion. We already use at line 160, this was a double include, additionally causing problems (#424). --- src/Globals.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Globals.h b/src/Globals.h index fe6aee5c5..58badf4dd 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -124,9 +124,6 @@ typedef unsigned short UInt16; #include #include #include -#if !defined(ANDROID_NDK) - #include -#endif #endif #if defined(ANDROID_NDK) From db5d7963e2dbb3a766850f5ffabd14980beb46b6 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 18 Dec 2013 16:11:15 +0000 Subject: [PATCH 50/51] Renamed back EntityAnimation to PlayerAnimation This fixes #411 and partially reverts 30ead790490f04248b861db79fddde9148b552f4 --- src/Bindings/Bindings.cpp | 40 ++++++++++++++++++++++++++++++++-- src/Bindings/Bindings.h | 2 +- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 8 +++---- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 6 ++--- src/Bindings/PluginManager.h | 4 ++-- src/ClientHandle.cpp | 2 +- 8 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/Bindings/Bindings.cpp b/src/Bindings/Bindings.cpp index e46e42aa4..b53b78853 100644 --- a/src/Bindings/Bindings.cpp +++ b/src/Bindings/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/16/13 21:57:34. +** Generated automatically by tolua++-1.0.92 on 12/18/13 16:09:11. */ #ifndef __cplusplus @@ -7444,6 +7444,41 @@ static int tolua_AllToLua_cEntity_AddSpeedZ00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: HandleSpeedFromAttachee of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_HandleSpeedFromAttachee00 +static int tolua_AllToLua_cEntity_HandleSpeedFromAttachee00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); + float a_Forward = ((float) tolua_tonumber(tolua_S,2,0)); + float a_Sideways = ((float) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HandleSpeedFromAttachee'", NULL); +#endif + { + self->HandleSpeedFromAttachee(a_Forward,a_Sideways); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HandleSpeedFromAttachee'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: SteerVehicle of class cEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SteerVehicle00 static int tolua_AllToLua_cEntity_SteerVehicle00(lua_State* tolua_S) @@ -30110,7 +30145,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"HOOK_COLLECTING_PICKUP",cPluginManager::HOOK_COLLECTING_PICKUP); tolua_constant(tolua_S,"HOOK_CRAFTING_NO_RECIPE",cPluginManager::HOOK_CRAFTING_NO_RECIPE); tolua_constant(tolua_S,"HOOK_DISCONNECT",cPluginManager::HOOK_DISCONNECT); - tolua_constant(tolua_S,"HOOK_ENTITY_ANIMATION",cPluginManager::HOOK_ENTITY_ANIMATION); + tolua_constant(tolua_S,"HOOK_PLAYER_ANIMATION",cPluginManager::HOOK_PLAYER_ANIMATION); tolua_constant(tolua_S,"HOOK_EXECUTE_COMMAND",cPluginManager::HOOK_EXECUTE_COMMAND); tolua_constant(tolua_S,"HOOK_EXPLODED",cPluginManager::HOOK_EXPLODED); tolua_constant(tolua_S,"HOOK_EXPLODING",cPluginManager::HOOK_EXPLODING); @@ -31127,6 +31162,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"AddSpeedX",tolua_AllToLua_cEntity_AddSpeedX00); tolua_function(tolua_S,"AddSpeedY",tolua_AllToLua_cEntity_AddSpeedY00); tolua_function(tolua_S,"AddSpeedZ",tolua_AllToLua_cEntity_AddSpeedZ00); + tolua_function(tolua_S,"HandleSpeedFromAttachee",tolua_AllToLua_cEntity_HandleSpeedFromAttachee00); tolua_function(tolua_S,"SteerVehicle",tolua_AllToLua_cEntity_SteerVehicle00); tolua_function(tolua_S,"GetUniqueID",tolua_AllToLua_cEntity_GetUniqueID00); tolua_function(tolua_S,"IsDestroyed",tolua_AllToLua_cEntity_IsDestroyed00); diff --git a/src/Bindings/Bindings.h b/src/Bindings/Bindings.h index 012a8b13a..2fbd53dcc 100644 --- a/src/Bindings/Bindings.h +++ b/src/Bindings/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/16/13 21:57:35. +** Generated automatically by tolua++-1.0.92 on 12/18/13 16:09:11. */ /* Exported function */ diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 5cb35ac5a..9a3c2383e 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -64,7 +64,7 @@ public: virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) = 0; virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer) = 0; virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) = 0; - virtual bool OnEntityAnimation (cEntity & a_Entity, int a_Animation) = 0; + virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) = 0; virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerEating (cPlayer & a_Player) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index f27cee76e..0d17c9ce2 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -550,14 +550,14 @@ bool cPluginLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, const -bool cPluginLua::OnEntityAnimation(cEntity & a_Entity, int a_Animation) +bool cPluginLua::OnPlayerAnimation(cPlayer & a_Player, int a_Animation) { cCSLock Lock(m_CriticalSection); bool res = false; - cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_ENTITY_ANIMATION]; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_ANIMATION]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), &a_Entity, a_Animation, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Player, a_Animation, cLuaState::Return, res); if (res) { return true; @@ -1302,7 +1302,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType) case cPluginManager::HOOK_COLLECTING_PICKUP: return "OnCollectingPickup"; case cPluginManager::HOOK_CRAFTING_NO_RECIPE: return "OnCraftingNoRecipe"; case cPluginManager::HOOK_DISCONNECT: return "OnDisconnect"; - case cPluginManager::HOOK_ENTITY_ANIMATION: return "OnEntityAnimation"; + case cPluginManager::HOOK_PLAYER_ANIMATION: return "OnPlayerAnimation"; case cPluginManager::HOOK_EXECUTE_COMMAND: return "OnExecuteCommand"; case cPluginManager::HOOK_HANDSHAKE: return "OnHandshake"; case cPluginManager::HOOK_KILLING: return "OnKilling"; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 188d202e0..e1e274c72 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -61,7 +61,7 @@ public: virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) override; virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer) override; virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override; - virtual bool OnEntityAnimation (cEntity & a_Entity, int a_Animation) override; + virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) override; virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual bool OnPlayerEating (cPlayer & a_Player) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 12263605f..732da24fa 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -602,16 +602,16 @@ bool cPluginManager::CallHookLogin(cClientHandle * a_Client, int a_ProtocolVersi -bool cPluginManager::CallHookEntityAnimation(cEntity & a_Entity, int a_Animation) +bool cPluginManager::CallHookPlayerAnimation(cPlayer & a_Player, int a_Animation) { - HookMap::iterator Plugins = m_Hooks.find(HOOK_ENTITY_ANIMATION); + HookMap::iterator Plugins = m_Hooks.find(HOOK_PLAYER_ANIMATION); if (Plugins == m_Hooks.end()) { return false; } for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnEntityAnimation(a_Entity, a_Animation)) + if ((*itr)->OnPlayerAnimation(a_Player, a_Animation)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 09f230475..b69f402c0 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -68,7 +68,7 @@ public: // tolua_export HOOK_COLLECTING_PICKUP, HOOK_CRAFTING_NO_RECIPE, HOOK_DISCONNECT, - HOOK_ENTITY_ANIMATION, + HOOK_PLAYER_ANIMATION, HOOK_EXECUTE_COMMAND, HOOK_EXPLODED, HOOK_EXPLODING, @@ -163,7 +163,7 @@ public: // tolua_export bool CallHookHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum); bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer); bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username); - bool CallHookEntityAnimation (cEntity & a_Entity, int a_Animation); + bool CallHookPlayerAnimation (cPlayer & a_Player, int a_Animation); bool CallHookPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); bool CallHookPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); bool CallHookPlayerEating (cPlayer & a_Player); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 8a41b5fac..9565fc41f 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1060,7 +1060,7 @@ void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_ void cClientHandle::HandleAnimation(char a_Animation) { - if (cPluginManager::Get()->CallHookEntityAnimation(*m_Player, a_Animation)) + if (cPluginManager::Get()->CallHookPlayerAnimation(*m_Player, a_Animation)) { // Plugin disagrees, bail out return; From ffca4f94c180f6241eaf3b0f394cbc28bfb8483d Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 18 Dec 2013 18:33:18 +0100 Subject: [PATCH 51/51] Implented Nether Wart. --- src/Blocks/BlockHandler.cpp | 2 ++ src/Blocks/BlockNetherWart.h | 52 ++++++++++++++++++++++++++++++++++ src/Items/ItemHandler.cpp | 2 ++ src/Items/ItemNetherWart.h | 54 ++++++++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+) create mode 100644 src/Blocks/BlockNetherWart.h create mode 100644 src/Items/ItemNetherWart.h diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index d377823f7..ff1022e12 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -40,6 +40,7 @@ #include "BlockMelon.h" #include "BlockMushroom.h" #include "BlockMycelium.h" +#include "BlockNetherWart.h" #include "BlockNote.h" #include "BlockOre.h" #include "BlockPiston.h" @@ -160,6 +161,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_MYCELIUM: return new cBlockMyceliumHandler (a_BlockType); case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType); + case E_BLOCK_NETHER_WART: return new cBlockNetherWartHandler (a_BlockType); case E_BLOCK_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType); case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType); case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler ( ); diff --git a/src/Blocks/BlockNetherWart.h b/src/Blocks/BlockNetherWart.h new file mode 100644 index 000000000..4cc3d989a --- /dev/null +++ b/src/Blocks/BlockNetherWart.h @@ -0,0 +1,52 @@ + +#pragma once + +#include "BlockHandler.h" +#include "../MersenneTwister.h" +#include "../World.h" + + + + + +/// Common class that takes care of carrots, potatoes and wheat +class cBlockNetherWartHandler : + public cBlockHandler +{ +public: + cBlockNetherWartHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override + { + MTRand rand; + + if (a_Meta == 0x7) + { + // Is fully grown, drop the entire produce: + a_Pickups.push_back(cItem(E_ITEM_NETHER_WART, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); + } + else + { + a_Pickups.push_back(cItem(E_ITEM_NETHER_WART)); + } + } + + void OnUpdate(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override + { + NIBBLETYPE Meta = a_Chunk.GetMeta (a_RelX, a_RelY, a_RelZ); + + if (Meta < 7) + { + a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_NETHER_WART, ++Meta); + } + } + + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_SOULSAND)); + } +} ; \ No newline at end of file diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 92ba94999..23b9a86d4 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -23,6 +23,7 @@ #include "ItemLeaves.h" #include "ItemLighter.h" #include "ItemMinecart.h" +#include "ItemNetherWart.h" #include "ItemPickaxe.h" #include "ItemThrowable.h" #include "ItemRedstoneDust.h" @@ -101,6 +102,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_FIREWORK_ROCKET: return new cItemFireworkHandler(); case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType); case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType); + case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType); case E_ITEM_REDSTONE_DUST: return new cItemRedstoneDustHandler(a_ItemType); case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType); case E_ITEM_SHEARS: return new cItemShearsHandler(a_ItemType); diff --git a/src/Items/ItemNetherWart.h b/src/Items/ItemNetherWart.h new file mode 100644 index 000000000..aa4a44340 --- /dev/null +++ b/src/Items/ItemNetherWart.h @@ -0,0 +1,54 @@ + +#pragma once + +#include "ItemHandler.h" +#include "../World.h" + + + + + +class cItemNetherWartHandler : + public cItemHandler +{ +public: + cItemNetherWartHandler(int a_ItemType) : + cItemHandler(a_ItemType) + { + + } + + virtual bool IsPlaceable(void) override + { + return true; + } + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + if (a_BlockFace != BLOCK_FACE_TOP) + { + // Only allow planting nether wart from the top side of the block + return false; + } + + // Only allow placement on farmland + int X = a_BlockX; + int Y = a_BlockY; + int Z = a_BlockZ; + AddFaceDirection(X, Y, Z, a_BlockFace, true); + if (a_World->GetBlock(X, Y, Z) != E_BLOCK_SOULSAND) + { + return false; + } + + a_BlockMeta = 0; + a_BlockType = E_BLOCK_NETHER_WART; + + return true; + } +} ; \ No newline at end of file