1
0

Restored chest and furnace functionality as it was (it's basically working but joined chests show single-chest window)

git-svn-id: http://mc-server.googlecode.com/svn/trunk@263 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-02-15 14:22:44 +00:00
parent 5e1033c567
commit 1aebcea095
13 changed files with 194 additions and 104 deletions

View File

@ -41,7 +41,7 @@ public:
cWorld * GetWorld(void) const {return m_World; }
virtual void UsedBy( cPlayer & a_Player ) = 0;
virtual void UsedBy( cPlayer * a_Player ) = 0;
virtual void SendTo( cClientHandle* a_Client ) { (void)a_Client; }
protected:

View File

@ -184,7 +184,7 @@ void cChestEntity::SendTo( cClientHandle* a_Client, cServer* a_Server )
void cChestEntity::UsedBy( cPlayer & a_Player )
void cChestEntity::UsedBy( cPlayer * a_Player )
{
LOG("Used a chest");
// m_Content[0].m_ItemCount = 1;
@ -203,10 +203,10 @@ void cChestEntity::UsedBy( cPlayer & a_Player )
}
if ( GetWindow() )
{
if( a_Player.GetWindow() != GetWindow() )
if( a_Player->GetWindow() != GetWindow() )
{
a_Player.OpenWindow( GetWindow() );
GetWindow()->SendWholeWindow( a_Player.GetClientHandle() );
a_Player->OpenWindow( GetWindow() );
GetWindow()->SendWholeWindow( a_Player->GetClientHandle() );
}
}
cPacket_BlockAction ChestOpen;
@ -215,7 +215,7 @@ void cChestEntity::UsedBy( cPlayer & a_Player )
ChestOpen.m_PosZ = GetPosZ();
ChestOpen.m_Byte1 = (char)1;
ChestOpen.m_Byte2 = (char)1;
m_World->GetChunkOfBlock(m_PosX, m_PosY, m_PosZ)->Broadcast(&ChestOpen);
m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, &ChestOpen);
}

View File

@ -44,14 +44,14 @@ public:
void SendTo( cClientHandle* a_Client, cServer* a_Server );
virtual void UsedBy( cPlayer & a_Player );
virtual void UsedBy( cPlayer * a_Player ) override;
cChestEntity *GetJoinedChest() { return m_JoinedChest; }
void SetJoinedChest(cChestEntity *a_Chest) { m_JoinedChest = a_Chest; }
void RemoveJoinedChest(cChestEntity *a_Chest) { if (m_JoinedChest && m_JoinedChest == a_Chest) { m_JoinedChest = NULL; m_TopChest = false; } }
int GetChestHeight() { return ((m_JoinedChest) ? c_ChestHeight * 2 : c_ChestHeight); }
cItem *GetContents(bool a_OnlyThis = false);
cItem * GetContents(bool a_OnlyThis = false);
static const int c_ChestWidth = 9;
static const int c_ChestHeight = 3;

View File

@ -835,6 +835,19 @@ cBlockEntity * cChunk::GetBlockEntity(int a_X, int a_Y, int a_Z)
void cChunk::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z)
{
cBlockEntity * be = GetBlockEntity(a_X, a_Y, a_Z);
if (be != NULL)
{
be->UsedBy(a_Player);
}
}
void cChunk::CollectPickupsByPlayer(cPlayer * a_Player)
{
cCSLock Lock(m_CSEntities);

View File

@ -85,6 +85,8 @@ public:
void AddEntity( cEntity * a_Entity );
void RemoveEntity( cEntity * a_Entity);
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // [x, y, z] in world block coords
inline void RecalculateLighting() { m_bCalculateLighting = true; } // Recalculate lighting next tick
inline void RecalculateHeightmap() { m_bCalculateHeightmap = true; } // Recalculate heightmap next tick

View File

@ -136,6 +136,44 @@ cChunkPtr cChunkMap::GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ )
void cChunkMap::BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude)
{
// Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude
cCSLock Lock(m_CSLayers);
int ChunkX, ChunkZ;
BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ);
if (Chunk == NULL)
{
return;
}
// Packets can be broadcasted even to invalid chunks!
Chunk->Broadcast(a_Packet);
}
void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z)
{
// a_Player rclked block entity at the coords specified, handle it
cCSLock Lock(m_CSLayers);
int ChunkX, ChunkZ;
BlockToChunk(a_X, a_Y, a_Z, ChunkX, ChunkZ);
cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ);
if ((Chunk == NULL) || !Chunk->IsValid())
{
return;
}
Chunk->UseBlockEntity(a_Player, a_X, a_Y, a_Z);
}
void cChunkMap::Tick( float a_Dt, MTRand & a_TickRandom )
{
cCSLock Lock(m_CSLayers);

View File

@ -27,18 +27,51 @@ public:
cChunkMap(cWorld* a_World );
~cChunkMap();
// TODO: Get rid of these in favor of the direct action methods:
cChunkPtr GetChunk ( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); // Also queues the chunk for loading / generating if not valid
cChunkPtr GetChunkNoGen( int a_ChunkX, int a_ChunkY, int a_ChunkZ ); // Also queues the chunk for loading if not valid; doesn't generate
// Direct action methods:
/// Broadcasts a_Packet to all clients in the chunk where block [x, y, z] is, except to client a_Exclude
void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL);
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // a_Player rclked block entity at the coords specified, handle it
void Tick( float a_Dt, MTRand & a_TickRand );
void UnloadUnusedChunks();
void SaveAllChunks();
cWorld* GetWorld() { return m_World; }
cWorld * GetWorld() { return m_World; }
int GetNumChunks(void);
/// Converts absolute block coords into relative (chunk + block) coords:
inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ )
{
BlockToChunk(a_X, a_Y, a_Z, a_ChunkX, a_ChunkZ);
a_X = a_X - a_ChunkX * 16;
a_Z = a_Z - a_ChunkZ*16;
}
/// Converts absolute block coords to chunk coords:
inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkZ )
{
(void)a_Y;
a_ChunkX = a_X / 16;
if ((a_X < 0) && (a_X % 16 != 0))
{
a_ChunkX--;
}
a_ChunkZ = a_Z / 16;
if ((a_Z < 0) && (a_Z % 16 != 0))
{
a_ChunkZ--;
}
}
private:
class cChunkLayer

View File

@ -466,9 +466,6 @@ void cClientHandle::HandlePacket(cPacket * a_Packet)
{
m_TimeLastPacket = cWorld::GetTime();
// cPacket* CopiedPacket = a_Packet->Clone();
// a_Packet = CopiedPacket;
// LOG("Recv packet 0x%02x from client \"%s\" (\"%s\")", a_Packet->m_PacketID, m_Socket.GetIPString().c_str(), m_Username.c_str());
if (m_bKicking)
@ -908,41 +905,42 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
ENUM_BLOCK_ID BlockID = (ENUM_BLOCK_ID)m_Player->GetWorld()->GetBlock(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
switch (BlockID)
{
case E_BLOCK_REDSTONE_REPEATER_ON:
case E_BLOCK_REDSTONE_REPEATER_OFF:
case E_BLOCK_REDSTONE_REPEATER_ON:
case E_BLOCK_REDSTONE_REPEATER_OFF:
{
//no need to update redstone current with a repeater
//todo: Find meta value of repeater and change it to one step more.
// no need to update redstone current with a repeater
// TODO: Find meta value of repeater and change it to one step more.
break;
}
break;
case E_BLOCK_WORKBENCH:
case E_BLOCK_WORKBENCH:
{
bPlaceBlock = false;
cWindow* Window = new cCraftingWindow(0, true);
m_Player->OpenWindow(Window);
break;
}
break;
case E_BLOCK_FURNACE:
case E_BLOCK_CHEST:
case E_BLOCK_FURNACE:
case E_BLOCK_CHEST:
{
bPlaceBlock = false;
cBlockEntity* BlockEntity = m_Player->GetWorld()->GetBlockEntity(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
if (BlockEntity)
{
BlockEntity->UsedBy(*m_Player);
}
m_Player->GetWorld()->UseBlockEntity(m_Player, a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
break;
}
break;
case E_BLOCK_WOODEN_DOOR:
case E_BLOCK_WOODEN_DOOR:
{
bPlaceBlock = false;
cDoors::ChangeDoor(m_Player->GetWorld(), a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ);
break;
}
break;
default:
break;
};
}
default:
{
break;
}
} // switch (BlockID)
} // if (Direction >= 0)
// Some checks to see if it's a placeable item :P
if (bPlaceBlock)
@ -950,7 +948,7 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
cItem Item;
Item.m_ItemID = Equipped.m_ItemID;
Item.m_ItemCount = 1;
LOG("a_Packet->m_ItemType: %i", (int)a_Packet->m_ItemType);
LOG("Placing item of type: %i", (int)a_Packet->m_ItemType);
// Hacked in edible items go!~
// TODO: Handle hunger
@ -958,68 +956,68 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
bool isDoor = false;
switch (Item.m_ItemID)
{
case E_ITEM_APPLE:
//m_Player->Heal(4); // 2 hearts
m_Player->Feed(24); // 2 food bars
bEat = true;
break;
case E_ITEM_GOLDEN_APPLE:
//m_Player->Heal(20); // 10 hearts
m_Player->Feed(60); // 5 food
bEat = true;
break;
case E_ITEM_MUSHROOM_SOUP:
///m_Player->Heal(10); // 5 hearts
m_Player->Feed(48); // 4 food
bEat = true;
break;
case E_ITEM_BREAD:
//m_Player->Heal(5); // 2.5 hearts
m_Player->Feed(30); // 2.5 food
bEat = true;
break;
case E_ITEM_RAW_MEAT:
//m_Player->Heal(3); // 1.5 hearts
m_Player->Feed(18); // 1.5 food
bEat = true;
break;
case E_ITEM_COOKED_MEAT:
//m_Player->Heal(8); // 4 hearts
m_Player->Feed(48); // 4 food
bEat = true;
break;
case E_ITEM_RAW_FISH:
//m_Player->Heal(2); // 1 heart
m_Player->Feed(12); // 1 food
bEat = true;
break;
case E_ITEM_COOKED_FISH:
//m_Player->Heal(5); // 2.5 hearts
m_Player->Feed(30); // 2.5 food
bEat = true;
break;
case E_ITEM_RAW_CHICKEN:
//m_Player->Heal(3);
m_Player->Feed(12); // 1 food
bEat = true;
break;
case E_ITEM_COOKED_CHICKEN:
//m_Player->Heal(8);
m_Player->Feed(36); // 3 food
bEat = true;
break;
case E_ITEM_RAW_BEEF:
//m_Player->Heal(3);
m_Player->Feed(18); // 1.5 food
bEat = true;
break;
case E_ITEM_STEAK:
//m_Player->Heal(8);
m_Player->Feed(48); // 4 food
bEat = true;
break;
default:
break;
case E_ITEM_APPLE:
//m_Player->Heal(4); // 2 hearts
m_Player->Feed(24); // 2 food bars
bEat = true;
break;
case E_ITEM_GOLDEN_APPLE:
//m_Player->Heal(20); // 10 hearts
m_Player->Feed(60); // 5 food
bEat = true;
break;
case E_ITEM_MUSHROOM_SOUP:
///m_Player->Heal(10); // 5 hearts
m_Player->Feed(48); // 4 food
bEat = true;
break;
case E_ITEM_BREAD:
//m_Player->Heal(5); // 2.5 hearts
m_Player->Feed(30); // 2.5 food
bEat = true;
break;
case E_ITEM_RAW_MEAT:
//m_Player->Heal(3); // 1.5 hearts
m_Player->Feed(18); // 1.5 food
bEat = true;
break;
case E_ITEM_COOKED_MEAT:
//m_Player->Heal(8); // 4 hearts
m_Player->Feed(48); // 4 food
bEat = true;
break;
case E_ITEM_RAW_FISH:
//m_Player->Heal(2); // 1 heart
m_Player->Feed(12); // 1 food
bEat = true;
break;
case E_ITEM_COOKED_FISH:
//m_Player->Heal(5); // 2.5 hearts
m_Player->Feed(30); // 2.5 food
bEat = true;
break;
case E_ITEM_RAW_CHICKEN:
//m_Player->Heal(3);
m_Player->Feed(12); // 1 food
bEat = true;
break;
case E_ITEM_COOKED_CHICKEN:
//m_Player->Heal(8);
m_Player->Feed(36); // 3 food
bEat = true;
break;
case E_ITEM_RAW_BEEF:
//m_Player->Heal(3);
m_Player->Feed(18); // 1.5 food
bEat = true;
break;
case E_ITEM_STEAK:
//m_Player->Heal(8);
m_Player->Feed(48); // 4 food
bEat = true;
break;
default:
break;
};
if (bEat)

View File

@ -74,7 +74,7 @@ void cFurnaceEntity::Destroy()
void cFurnaceEntity::UsedBy( cPlayer & a_Player )
void cFurnaceEntity::UsedBy( cPlayer * a_Player )
{
LOG("Used a furnace");
@ -88,11 +88,11 @@ void cFurnaceEntity::UsedBy( cPlayer & a_Player )
}
if( GetWindow() )
{
if( a_Player.GetWindow() != GetWindow() )
if( a_Player->GetWindow() != GetWindow() )
{
a_Player.OpenWindow( GetWindow() );
a_Player->OpenWindow( GetWindow() );
GetWindow()->SendWholeWindow( a_Player.GetClientHandle() );
GetWindow()->SendWholeWindow( a_Player->GetClientHandle() );
}
}
}

View File

@ -37,7 +37,8 @@ public:
void SaveToJson (Json::Value& a_Value );
bool Tick( float a_Dt );
virtual void UsedBy( cPlayer & a_Player );
virtual void UsedBy( cPlayer * a_Player ) override;
bool StartCooking();

View File

@ -35,7 +35,7 @@ cSignEntity::~cSignEntity()
// It don't do anything when 'used'
void cSignEntity::UsedBy( cPlayer & a_Player )
void cSignEntity::UsedBy( cPlayer * a_Player )
{
(void)a_Player;
}

View File

@ -33,8 +33,8 @@ public:
AString GetLine( int a_Index ) const;
virtual void UsedBy( cPlayer & a_Player );
virtual void SendTo( cClientHandle* a_Client );
virtual void UsedBy( cPlayer * a_Player ) override;
virtual void SendTo( cClientHandle* a_Client ) override;
private:

View File

@ -67,6 +67,8 @@ public:
void Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude = 0 );
void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL) {return m_ChunkMap->BroadcastToChunkOfBlock(a_X, a_Y, a_Z, a_Packet, a_Exclude); }
// MOTD
const AString & GetDescription(void) const {return m_Description; }
@ -117,6 +119,9 @@ public:
// TODO: This interface is dangerous!
cBlockEntity * GetBlockEntity( int a_X, int a_Y, int a_Z ); //tolua_export
/// a_Player is using block entity at [x, y, z], handle that:
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z) {m_ChunkMap->UseBlockEntity(a_Player, a_X, a_Y, a_Z); }
void GrowTree( int a_X, int a_Y, int a_Z ); //tolua_export