From d7068b35a85f0c0248a5533240087747d02e1a17 Mon Sep 17 00:00:00 2001 From: "lapayo94@gmail.com" Date: Sun, 1 Jan 2012 04:55:17 +0000 Subject: - implemented separated inventory for creative mode (cSurvivalInventory and cCreativeInventory) (Separation is not perfect yet, because maybe there are some mayor changes needed :D) - implemented CreativeInventoryAction (was mistakenly called CreateInventoryAction) -> Fixed meta data for creative selected blocks ->->Slabs/Steps are now placed correctly - slabs can now be build to a double slab - fixed a bug in the inventory which put items with different meta values in the same slot git-svn-id: http://mc-server.googlecode.com/svn/trunk@160 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Bindings.cpp | 68 ++++-- source/Bindings.h | 2 +- source/PacketID.h | 2 +- source/cBlockToPickup.cpp | 4 + source/cClientHandle.cpp | 54 +++-- source/cCreativeInventory.cpp | 38 ++++ source/cCreativeInventory.h | 13 ++ source/cInventory.cpp | 232 +++++++-------------- source/cInventory.h | 11 +- source/cPlayer.cpp | 17 +- source/cPlayer.h | 10 +- source/cSurvivalInventory.cpp | 90 ++++++++ source/cSurvivalInventory.h | 14 ++ source/cWindow.cpp | 6 +- source/packets/cPacket_CreateInventoryAction.cpp | 59 ------ source/packets/cPacket_CreateInventoryAction.h | 29 --- source/packets/cPacket_CreativeInventoryAction.cpp | 54 +++++ source/packets/cPacket_CreativeInventoryAction.h | 29 +++ 18 files changed, 434 insertions(+), 298 deletions(-) create mode 100644 source/cCreativeInventory.cpp create mode 100644 source/cCreativeInventory.h create mode 100644 source/cSurvivalInventory.cpp create mode 100644 source/cSurvivalInventory.h delete mode 100644 source/packets/cPacket_CreateInventoryAction.cpp delete mode 100644 source/packets/cPacket_CreateInventoryAction.h create mode 100644 source/packets/cPacket_CreativeInventoryAction.cpp create mode 100644 source/packets/cPacket_CreativeInventoryAction.h (limited to 'source') diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 33d6427d4..0256e02c4 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/28/11 01:31:37. +** Generated automatically by tolua++-1.0.92 on 01/01/12 05:42:24. */ #ifndef __cplusplus @@ -162,50 +162,51 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"cPlugin"); tolua_usertype(tolua_S,"cStringMap"); tolua_usertype(tolua_S,"Json::Value"); - tolua_usertype(tolua_S,"cServer"); + tolua_usertype(tolua_S,"cInventory"); tolua_usertype(tolua_S,"cRoot"); + tolua_usertype(tolua_S,"cGroupManager"); tolua_usertype(tolua_S,"cPlugin::CommandStruct"); tolua_usertype(tolua_S,"cPickup"); - tolua_usertype(tolua_S,"cRecipeChecker"); - tolua_usertype(tolua_S,"cPacket_Login"); - tolua_usertype(tolua_S,"cClientHandle"); tolua_usertype(tolua_S,"Lua__cPacket_BlockDig"); + tolua_usertype(tolua_S,"cPacket_Login"); + tolua_usertype(tolua_S,"cSurvivalInventory"); + tolua_usertype(tolua_S,"Vector3i"); tolua_usertype(tolua_S,"cFurnaceRecipe"); tolua_usertype(tolua_S,"cCuboid"); tolua_usertype(tolua_S,"cChatColor"); - tolua_usertype(tolua_S,"cMCLogger"); + tolua_usertype(tolua_S,"cGroup"); tolua_usertype(tolua_S,"cPacket_PickupSpawn"); tolua_usertype(tolua_S,"Lua__cWebPlugin"); tolua_usertype(tolua_S,"Lua__cPawn"); - tolua_usertype(tolua_S,"cGroup"); + tolua_usertype(tolua_S,"cTracer"); tolua_usertype(tolua_S,"cItem"); tolua_usertype(tolua_S,"Vector3f"); tolua_usertype(tolua_S,"cPlugin_Lua"); - tolua_usertype(tolua_S,"cTracer"); + tolua_usertype(tolua_S,"cMCLogger"); tolua_usertype(tolua_S,"Lua__cPlayer"); tolua_usertype(tolua_S,"cPacket"); tolua_usertype(tolua_S,"cPacket_BlockDig"); tolua_usertype(tolua_S,"cWebAdmin"); - tolua_usertype(tolua_S,"Vector3i"); + tolua_usertype(tolua_S,"cClientHandle"); tolua_usertype(tolua_S,"cBlockEntity"); - tolua_usertype(tolua_S,"cWebPlugin"); tolua_usertype(tolua_S,"Lua__cTCPLink"); - tolua_usertype(tolua_S,"Lua__cPlugin"); tolua_usertype(tolua_S,"cTCPLink"); + tolua_usertype(tolua_S,"Lua__cPlugin"); + tolua_usertype(tolua_S,"cRecipeChecker"); tolua_usertype(tolua_S,"cPacket_BlockPlace"); tolua_usertype(tolua_S,"cLadder"); - tolua_usertype(tolua_S,"cGroupManager"); - tolua_usertype(tolua_S,"cWorld"); - tolua_usertype(tolua_S,"cIniFile"); + tolua_usertype(tolua_S,"Lua__cPickup"); tolua_usertype(tolua_S,"cPluginManager"); + tolua_usertype(tolua_S,"cIniFile"); + tolua_usertype(tolua_S,"cWorld"); tolua_usertype(tolua_S,"HTTPRequest"); tolua_usertype(tolua_S,"cPawn"); tolua_usertype(tolua_S,"cPlayer"); tolua_usertype(tolua_S,"cTorch"); - tolua_usertype(tolua_S,"Lua__cPickup"); tolua_usertype(tolua_S,"cEntity"); - tolua_usertype(tolua_S,"cInventory"); tolua_usertype(tolua_S,"Lua__cEntity"); + tolua_usertype(tolua_S,"cWebPlugin"); + tolua_usertype(tolua_S,"cServer"); tolua_usertype(tolua_S,"cStairs"); tolua_usertype(tolua_S,"Vector3d"); } @@ -5031,6 +5032,38 @@ static int tolua_AllToLua_cPlayer_GetInventory00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: GetSurvivalInventory of class cPlayer */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_GetSurvivalInventory00 +static int tolua_AllToLua_cPlayer_GetSurvivalInventory00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSurvivalInventory'", NULL); +#endif + { + cSurvivalInventory& tolua_ret = (cSurvivalInventory&) self->GetSurvivalInventory(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cSurvivalInventory"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSurvivalInventory'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: TeleportTo of class cPlayer */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cPlayer_TeleportTo00 static int tolua_AllToLua_cPlayer_TeleportTo00(lua_State* tolua_S) @@ -15792,7 +15825,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_INVENTORY_SLOT",E_INVENTORY_SLOT); tolua_constant(tolua_S,"E_INVENTORY_WHOLE",E_INVENTORY_WHOLE); tolua_constant(tolua_S,"E_INVENTORY_PROGRESS",E_INVENTORY_PROGRESS); - tolua_constant(tolua_S,"E_CREATE_INVENTORY_ACTION",E_CREATE_INVENTORY_ACTION); + tolua_constant(tolua_S,"E_CREATIVE_INVENTORY_ACTION",E_CREATIVE_INVENTORY_ACTION); tolua_constant(tolua_S,"E_UPDATE_SIGN",E_UPDATE_SIGN); tolua_constant(tolua_S,"E_PLAYER_LIST_ITEM",E_PLAYER_LIST_ITEM); tolua_constant(tolua_S,"E_PING",E_PING); @@ -15924,6 +15957,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetFlying",tolua_AllToLua_cPlayer_GetFlying00); tolua_function(tolua_S,"GetStance",tolua_AllToLua_cPlayer_GetStance00); tolua_function(tolua_S,"GetInventory",tolua_AllToLua_cPlayer_GetInventory00); + tolua_function(tolua_S,"GetSurvivalInventory",tolua_AllToLua_cPlayer_GetSurvivalInventory00); tolua_function(tolua_S,"TeleportTo",tolua_AllToLua_cPlayer_TeleportTo00); tolua_function(tolua_S,"GetGameMode",tolua_AllToLua_cPlayer_GetGameMode00); tolua_function(tolua_S,"GetIP",tolua_AllToLua_cPlayer_GetIP00); diff --git a/source/Bindings.h b/source/Bindings.h index 7fede45f8..5b0973d35 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 12/28/11 01:31:37. +** Generated automatically by tolua++-1.0.92 on 01/01/12 05:42:24. */ /* Exported function */ diff --git a/source/PacketID.h b/source/PacketID.h index 7fc068b53..bc18cf9c0 100644 --- a/source/PacketID.h +++ b/source/PacketID.h @@ -50,7 +50,7 @@ enum ENUM_PACKET_ID E_INVENTORY_SLOT = 0x67, E_INVENTORY_WHOLE = 0x68, E_INVENTORY_PROGRESS= 0x69, - E_CREATE_INVENTORY_ACTION = 0x6B, + E_CREATIVE_INVENTORY_ACTION = 0x6B, E_UPDATE_SIGN = 0x82, E_PLAYER_LIST_ITEM = 0xC9, E_PING = 0xfe, diff --git a/source/cBlockToPickup.cpp b/source/cBlockToPickup.cpp index 0caca7d1c..53ae84b48 100644 --- a/source/cBlockToPickup.cpp +++ b/source/cBlockToPickup.cpp @@ -64,6 +64,8 @@ ENUM_ITEM_ID cBlockToPickup::ToPickup( unsigned char a_BlockID, ENUM_ITEM_ID a_U return E_ITEM_IRON_DOOR; case E_BLOCK_GLOWSTONE: return E_ITEM_GLOWSTONE_DUST; + case E_BLOCK_DOUBLE_STEP: + return E_ITEM_STEP; default: return (ENUM_ITEM_ID)a_BlockID; } @@ -83,6 +85,8 @@ char cBlockToPickup::PickupCount(unsigned char a_BlockID) return r1.randInt() % 8 + 3; case E_BLOCK_LAPIS_ORE: return r1.randInt() % 5 + 4; + case E_BLOCK_DOUBLE_STEP: + return 2; default: return 1; } diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index b90f50c72..5daa53138 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -60,7 +60,7 @@ #include "packets/cPacket_PickupSpawn.h" #include "packets/cPacket_ItemSwitch.h" #include "packets/cPacket_EntityEquipment.h" -#include "packets/cPacket_CreateInventoryAction.h" +#include "packets/cPacket_CreativeInventoryAction.h" #include "packets/cPacket_NewInvalidState.h" #include "packets/cPacket_UseEntity.h" #include "packets/cPacket_WindowClose.h" @@ -151,7 +151,7 @@ cClientHandle::cClientHandle(const cSocket & a_Socket) m_pState->PacketMap[E_DISCONNECT] = new cPacket_Disconnect; m_pState->PacketMap[E_ITEM_SWITCH] = new cPacket_ItemSwitch; m_pState->PacketMap[E_ENTITY_EQUIPMENT] = new cPacket_EntityEquipment; - m_pState->PacketMap[E_CREATE_INVENTORY_ACTION] = new cPacket_CreateInventoryAction; + m_pState->PacketMap[E_CREATIVE_INVENTORY_ACTION] = new cPacket_CreativeInventoryAction; m_pState->PacketMap[E_NEW_INVALID_STATE] = new cPacket_NewInvalidState; m_pState->PacketMap[E_PICKUP_SPAWN] = new cPacket_PickupSpawn; m_pState->PacketMap[E_USE_ENTITY] = new cPacket_UseEntity; @@ -443,11 +443,7 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) LOGINFO("Got New Invalid State packet"); } break; - case E_CREATE_INVENTORY_ACTION: // I don't think we need to do anything with this packet, but justin case... - { - LOGINFO("Got Create Inventory Action packet"); - } - break; + case E_PING: // Somebody tries to retrieve information about the server { LOGINFO("Got ping"); @@ -545,6 +541,15 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) { switch( a_Packet->m_PacketID ) { + case E_CREATIVE_INVENTORY_ACTION: // This is for creative Inventory changes + { + if(m_Player->GetGameMode() == 1) //Just to be sure + { + m_Player->GetInventory().Clicked(a_Packet); + } + break; + } + break; case E_PLAYERPOS: { cPacket_PlayerPosition* PacketData = reinterpret_cast(a_Packet); @@ -696,9 +701,8 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) cPacket_BlockPlace* PacketData = reinterpret_cast(a_Packet); cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); - //if( (Equipped.m_ItemID != PacketData->m_ItemType) ) // Not valid - if( (Equipped.m_ItemID != PacketData->m_ItemType) && (m_Player->GetGameMode() != 1) ) // Not valid + if( (Equipped.m_ItemID != PacketData->m_ItemType)) // Not valid { LOGWARN("Player %s tried to place a block that was not selected! (could indicate bot)", GetUsername() ); break; @@ -851,19 +855,30 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) break; //TODO: Wrong Blocks! - int clickedBlock = (int)m_Player->GetWorld()->GetBlock( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ ); + int ClickedBlock = (int)m_Player->GetWorld()->GetBlock( PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ ); char MetaData = (char)Equipped.m_ItemHealth; bool LavaBucket = false; bool WaterBucket = false; bool bRemoveItem = true; + bool bIgnoreCollision = false; + + if(ClickedBlock == E_BLOCK_STEP) + { + if(MetaData == m_Player->GetWorld()->GetBlockMeta(PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ) && PacketData->m_Direction == 1) //only make double slab if meta values are the same and if player clicked on top of the block (Dir = 1) + { + PacketData->m_ItemType = E_BLOCK_DOUBLE_STEP; + PacketData->m_PosY--; + bIgnoreCollision = true; + } + } switch( PacketData->m_ItemType ) // Special handling for special items { case E_ITEM_BUCKET: //TODO: Change this, it is just a small hack to get it working a little bit. seems like the Client sends the position from the first hitable block :s - clickedBlock = (int)m_Player->GetWorld()->GetBlock( PacketData->m_PosX, PacketData->m_PosY + 1, PacketData->m_PosZ ); - LOG("Bucket Clicked BlockID: %d", clickedBlock); - switch (clickedBlock) + ClickedBlock = (int)m_Player->GetWorld()->GetBlock( PacketData->m_PosX, PacketData->m_PosY + 1, PacketData->m_PosZ ); + LOG("Bucket Clicked BlockID: %d", ClickedBlock); + switch (ClickedBlock) { case E_BLOCK_WATER: case E_BLOCK_STATIONARY_WATER: @@ -902,9 +917,6 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) } break; - case E_BLOCK_WHITE_CLOTH: - MetaData = (char)PacketData->m_Uses; - break; case E_BLOCK_TORCH: MetaData = cTorch::DirectionToMetaData( PacketData->m_Direction ); break; @@ -1026,7 +1038,12 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) AddDirection( X, Y, Z, PacketData->m_Direction ); int PlaceBlock = m_Player->GetWorld()->GetBlock( X, Y, Z ); - if (!( ( PlaceBlock == E_BLOCK_AIR ) || ( PlaceBlock == E_BLOCK_WATER ) || ( PlaceBlock == E_BLOCK_STATIONARY_WATER ) || ( PlaceBlock == E_BLOCK_LAVA ) || ( PlaceBlock == E_BLOCK_STATIONARY_LAVA ) ) ) { //tried to place a block *into* another? + if (PlaceBlock != E_BLOCK_AIR + && PlaceBlock != E_BLOCK_WATER + && PlaceBlock != E_BLOCK_STATIONARY_WATER + && PlaceBlock != E_BLOCK_LAVA + && PlaceBlock != E_BLOCK_STATIONARY_LAVA + && !bIgnoreCollision ) { //tried to place a block *into* another? break; //happens when you place a block aiming at side of block like torch or stem } @@ -1035,6 +1052,8 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) if((m_Player->GetGameMode() != 1) && !m_Player->GetInventory().RemoveItem( Item )) break; } + + if (isDoor) { if ( ( m_Player->GetWorld()->GetBlock( X, Y+1, Z ) == E_BLOCK_AIR ) || ( m_Player->GetWorld()->GetBlock( X, Y+1, Z ) == E_BLOCK_AIR ) ) @@ -1046,6 +1065,7 @@ void cClientHandle::HandlePacket( cPacket* a_Packet ) m_Player->GetWorld()->SetBlock( X, Y, Z, (char)PacketData->m_ItemType, MetaData ); } + if (UpdateRedstone) { cRedstone Redstone(m_Player->GetWorld()); diff --git a/source/cCreativeInventory.cpp b/source/cCreativeInventory.cpp new file mode 100644 index 000000000..b1606f077 --- /dev/null +++ b/source/cCreativeInventory.cpp @@ -0,0 +1,38 @@ +#include "cCreativeInventory.h" +#include //memset +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cMCLogger.h" +#include "cWindow.h" +#include "cItem.h" +#include "cRecipeChecker.h" +#include "cRoot.h" + +#include + +#include "packets/cPacket_CreativeInventoryAction.h" +#include "packets/cPacket_WholeInventory.h" +#include "packets/cPacket_InventorySlot.h" + +cCreativeInventory::~cCreativeInventory() +{ +} + +cCreativeInventory::cCreativeInventory(cPlayer* a_Owner) + : cInventory(a_Owner) +{ + +} + +void cCreativeInventory::Clicked( cPacket* a_ClickPacket ) +{ + cPacket_CreativeInventoryAction* Packet = reinterpret_cast(a_ClickPacket); + short Slot = Packet->m_Slot; + + cItem* SlotItem = &(this->m_Slots[Slot]); + + SlotItem->m_ItemID = (ENUM_ITEM_ID) Packet->m_ItemID; + SlotItem->m_ItemHealth = Packet->m_Damage; + SlotItem->m_ItemCount = Packet->m_Quantity; +} + diff --git a/source/cCreativeInventory.h b/source/cCreativeInventory.h new file mode 100644 index 000000000..996136a27 --- /dev/null +++ b/source/cCreativeInventory.h @@ -0,0 +1,13 @@ +#pragma once + +#include "cInventory.h" + +class cCreativeInventory //tolua_export + : public cInventory +{ //tolua_export +public: + cCreativeInventory(cPlayer* a_Owner); + ~cCreativeInventory(); + + virtual void Clicked( cPacket* a_ClickPacket ); +}; //tolua_export diff --git a/source/cInventory.cpp b/source/cInventory.cpp index 18862b78b..9236a2387 100644 --- a/source/cInventory.cpp +++ b/source/cInventory.cpp @@ -18,8 +18,6 @@ cInventory::~cInventory() { delete [] m_Slots; delete m_EquippedItem; - if( GetWindow() ) GetWindow()->Close( *m_Owner ); - CloseWindow(); } cInventory::cInventory(cPlayer* a_Owner) @@ -37,155 +35,6 @@ cInventory::cInventory(cPlayer* a_Owner) m_EquippedItem = new cItem(); m_EquippedSlot = 0; - - if( !GetWindow() ) - { - cWindow* Window = new cWindow( this, false ); - Window->SetSlots( m_Slots, c_NumSlots ); - Window->SetWindowID( 0 ); - OpenWindow( Window ); - } -} - -void cInventory::Clear() -{ - for(unsigned int i = 0; i < c_NumSlots; i++) - m_Slots[i].Empty(); -} - -cItem* cInventory::GetSlotsForType( int a_Type ) -{ - switch( a_Type ) - { - case -1: - return m_MainSlots; - case -2: - return m_CraftSlots; - case -3: - return m_ArmorSlots; - } - return 0; -} - -int cInventory::GetSlotCountForType( int a_Type ) -{ - switch( a_Type ) - { - case -1: - return 36; - case -2: - case -3: - return 4; - } - return 0; -} - -void cInventory::Clicked( cPacket_WindowClick* a_ClickPacket ) -{ - bool bDontCook = false; - if( GetWindow() ) - { - // Override for craft result slot - if( a_ClickPacket->m_SlotNum == (short)c_CraftOffset ) - { - LOG("In craft slot: %i x %i !!", m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount ); - cItem* DraggingItem = GetWindow()->GetDraggingItem(); - if( DraggingItem->IsEmpty() ) - { - *DraggingItem = m_Slots[c_CraftOffset]; - m_Slots[c_CraftOffset].Empty(); - } - else if( DraggingItem->Equals( m_Slots[c_CraftOffset] ) ) - { - if( DraggingItem->m_ItemCount + m_Slots[c_CraftOffset].m_ItemCount <= 64 ) - { - DraggingItem->m_ItemCount += m_Slots[c_CraftOffset].m_ItemCount; - m_Slots[0].Empty(); - } - else - { - bDontCook = true; - } - } - else - { - bDontCook = true; - } - LOG("Dragging Dish %i", DraggingItem->m_ItemCount ); - } - else - { - GetWindow()->Clicked( a_ClickPacket, *m_Owner ); - } - } - else - { - LOG("No Inventory window! WTF"); - } - - if( a_ClickPacket->m_SlotNum >= (short)c_CraftOffset && a_ClickPacket->m_SlotNum < (short)(c_CraftOffset+c_CraftSlots+1) ) - { - cItem CookedItem; - if( a_ClickPacket->m_SlotNum == 0 && !bDontCook ) - { - CookedItem = cRoot::Get()->GetRecipeChecker()->CookIngredients( m_Slots+c_CraftOffset+1, 2, 2, true ); - } - else - { - CookedItem = cRoot::Get()->GetRecipeChecker()->CookIngredients( m_Slots+c_CraftOffset+1, 2, 2 ); - } - m_Slots[c_CraftOffset] = CookedItem; - LOG("You cooked: %i x %i !!", m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount ); - SendWholeInventory( m_Owner->GetClientHandle() ); - } - SendSlot( 0 ); -} - -bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode /* = 0 */ ) -{ - // Fill already present stacks - if( a_Mode < 2 ) - { - for(int i = 0; i < a_Size; i++) - { - if( m_Slots[i + a_Offset].m_ItemID == a_Item.m_ItemID && m_Slots[i + a_Offset].m_ItemCount < 64 ) - { - int NumFree = 64 - m_Slots[i + a_Offset].m_ItemCount; - if( NumFree >= a_Item.m_ItemCount ) - { - - //printf("1. Adding %i items ( free: %i )\n", a_Item.m_ItemCount, NumFree ); - m_Slots[i + a_Offset].m_ItemCount += a_Item.m_ItemCount; - a_Item.m_ItemCount = 0; - a_bChangedSlots[i + a_Offset] = true; - break; - } - else - { - //printf("2. Adding %i items\n", NumFree ); - m_Slots[i + a_Offset].m_ItemCount += (char)NumFree; - a_Item.m_ItemCount -= (char)NumFree; - a_bChangedSlots[i + a_Offset] = true; - } - } - } - } - - if( a_Mode > 0 ) - { - // If we got more left, find first empty slot - for(int i = 0; i < a_Size && a_Item.m_ItemCount > 0; i++) - { - if( m_Slots[i + a_Offset].m_ItemID == -1 ) - { - m_Slots[i + a_Offset] = a_Item; - a_Item.m_ItemCount = 0; - a_bChangedSlots[i + a_Offset] = true; - } - } - } - - return true; } bool cInventory::AddItem( cItem & a_Item ) @@ -274,6 +123,40 @@ bool cInventory::RemoveItem( cItem & a_Item ) return false; } +void cInventory::Clear() +{ + for(unsigned int i = 0; i < c_NumSlots; i++) + m_Slots[i].Empty(); +} + +cItem* cInventory::GetSlotsForType( int a_Type ) +{ + switch( a_Type ) + { + case -1: + return m_MainSlots; + case -2: + return m_CraftSlots; + case -3: + return m_ArmorSlots; + } + return 0; +} + +int cInventory::GetSlotCountForType( int a_Type ) +{ + switch( a_Type ) + { + case -1: + return 36; + case -2: + case -3: + return 4; + } + return 0; +} + + cItem* cInventory::GetSlot( int a_SlotNum ) { if( a_SlotNum < 0 || a_SlotNum >= (short)c_NumSlots ) return 0; @@ -328,18 +211,51 @@ void cInventory::SendSlot( int a_SlotNum ) } } -void cInventory::DrawInventory() +bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode /* = 0 */ ) { - printf("%i %i %i %i\n", m_ArmorSlots[0].m_ItemCount, m_ArmorSlots[1].m_ItemCount, m_CraftSlots[0].m_ItemCount, m_CraftSlots[1].m_ItemCount ); - printf("%i %i %i %i\n", m_ArmorSlots[2].m_ItemCount, m_ArmorSlots[3].m_ItemCount, m_CraftSlots[2].m_ItemCount, m_CraftSlots[3].m_ItemCount ); - for(int y = 0; y < 4; y++) + // Fill already present stacks + if( a_Mode < 2 ) + { + for(int i = 0; i < a_Size; i++) + { + if( m_Slots[i + a_Offset].m_ItemID == a_Item.m_ItemID && m_Slots[i + a_Offset].m_ItemCount < 64 && m_Slots[i + a_Offset].m_ItemHealth == a_Item.m_ItemHealth ) + { + int NumFree = 64 - m_Slots[i + a_Offset].m_ItemCount; + if( NumFree >= a_Item.m_ItemCount ) + { + + //printf("1. Adding %i items ( free: %i )\n", a_Item.m_ItemCount, NumFree ); + m_Slots[i + a_Offset].m_ItemCount += a_Item.m_ItemCount; + a_Item.m_ItemCount = 0; + a_bChangedSlots[i + a_Offset] = true; + break; + } + else + { + //printf("2. Adding %i items\n", NumFree ); + m_Slots[i + a_Offset].m_ItemCount += (char)NumFree; + a_Item.m_ItemCount -= (char)NumFree; + a_bChangedSlots[i + a_Offset] = true; + } + } + } + } + + if( a_Mode > 0 ) { - for(int x = 0; x < 9; x++) + // If we got more left, find first empty slot + for(int i = 0; i < a_Size && a_Item.m_ItemCount > 0; i++) { - printf("%i ", m_MainSlots[x + y*9].m_ItemCount ); + if( m_Slots[i + a_Offset].m_ItemID == -1 ) + { + m_Slots[i + a_Offset] = a_Item; + a_Item.m_ItemCount = 0; + a_bChangedSlots[i + a_Offset] = true; + } } - printf("\n"); } + + return true; } void cInventory::SaveToJson(Json::Value & a_Value) diff --git a/source/cInventory.h b/source/cInventory.h index 7d98af853..849cfb440 100644 --- a/source/cInventory.h +++ b/source/cInventory.h @@ -12,10 +12,9 @@ namespace Json class cItem; class cClientHandle; class cPlayer; -class cPacket_WindowClick; +class cPacket; class cPacket_EntityEquipment; -class cInventory //tolua_export - : public cWindowOwner +class cInventory //tolua_export { //tolua_export public: cInventory(cPlayer* a_Owner); @@ -28,7 +27,6 @@ public: bool AddItem( cItem & a_Item ); //tolua_export bool RemoveItem( cItem & a_Item ); //tolua_export - void DrawInventory(); void SaveToJson(Json::Value & a_Value); bool LoadFromJson(Json::Value & a_Value); @@ -42,7 +40,7 @@ public: cItem & GetEquippedItem(); //tolua_export void SetEquippedSlot( int a_SlotNum ); //tolua_export - void Clicked( cPacket_WindowClick* a_ClickPacket ); + virtual void Clicked( cPacket* a_ClickPacket ) = 0; void SendSlot( int a_SlotNum ); //tolua_export @@ -56,7 +54,8 @@ public: static const unsigned int c_ArmorOffset = 5; static const unsigned int c_MainOffset = 9; static const unsigned int c_HotOffset = 36; -private: + +protected: bool AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode = 0 ); cItem* m_Slots; diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index baba0174a..12f3c5a30 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -1,6 +1,7 @@ #include "cPlayer.h" #include "cServer.h" -#include "cInventory.h" +#include "cCreativeInventory.h" +#include "cSurvivalInventory.h" #include "cClientHandle.h" #include "cWorld.h" #include "cPickup.h" @@ -82,7 +83,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const char* a_PlayerName) m_EntityType = E_PLAYER; SetMaxHealth(20); SetMaxFoodLevel(125); - m_Inventory = new cInventory( this ); + m_Inventory = new cSurvivalInventory( this ); + m_CreativeInventory = new cCreativeInventory(this); cTimer t1; m_LastPlayerListTime = t1.GetNowTime(); @@ -118,6 +120,10 @@ cPlayer::~cPlayer(void) delete m_Inventory; m_Inventory = 0; } + if(m_CreativeInventory) + { + delete m_CreativeInventory; + } delete m_pState; GetWorld()->RemovePlayer( this ); // TODO - Remove from correct world? Or get rid of this? } @@ -398,10 +404,10 @@ void cPlayer::OpenWindow( cWindow* a_Window ) void cPlayer::CloseWindow(char a_WindowType) { if (a_WindowType == 0) { // Inventory - if(GetInventory().GetWindow()->GetDraggingItem() && GetInventory().GetWindow()->GetDraggingItem()->m_ItemCount > 0) + if(m_Inventory->GetWindow()->GetDraggingItem() && m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount > 0) { LOG("Player holds item! Dropping it..."); - TossItem( true, GetInventory().GetWindow()->GetDraggingItem()->m_ItemCount ); + TossItem( true, m_Inventory->GetWindow()->GetDraggingItem()->m_ItemCount ); } //Drop whats in the crafting slots (1, 2, 3, 4) @@ -458,6 +464,7 @@ void cPlayer::SetGameMode( int a_GameMode ) GameModePacket.m_Reason = 3; //GameModeChange GameModePacket.m_GameMode = (char)a_GameMode; //GameModeChange m_ClientHandle->Send ( GameModePacket ); + GetInventory().SendWholeInventory(m_ClientHandle); } } } @@ -651,7 +658,7 @@ void cPlayer::TossItem( bool a_bDraggingItem, int a_Amount /* = 1 */ ) { if( a_bDraggingItem ) { - cItem* Item = GetInventory().GetWindow()->GetDraggingItem(); + cItem* Item = GetSurvivalInventory().GetWindow()->GetDraggingItem(); if( Item->m_ItemID > 0 && Item->m_ItemCount >= a_Amount ) { float vX = 0, vY = 0, vZ = 0; diff --git a/source/cPlayer.h b/source/cPlayer.h index 4d348c2ad..d2d1e91d7 100644 --- a/source/cPlayer.h +++ b/source/cPlayer.h @@ -1,6 +1,8 @@ #pragma once #include "cPawn.h" +#include "cSurvivalInventory.h" +#include "cCreativeInventory.h" #include #include // TODO - use const char* @@ -8,6 +10,8 @@ class cGroup; class cWindow; class cInventory; class cClientHandle; + + class cPlayer : public cPawn //tolua_export { //tolua_export public: @@ -27,7 +31,8 @@ public: Vector3d GetEyePosition(); //tolua_export inline bool GetFlying() { return m_bTouchGround; } //tolua_export inline const double & GetStance() { return m_Stance; } //tolua_export - cInventory & GetInventory() { return *m_Inventory; } //tolua_export + cInventory & GetInventory() { if(GetGameMode() == 0) return *m_Inventory; else return *m_CreativeInventory; } //tolua_export + cSurvivalInventory & GetSurvivalInventory() { return *m_Inventory; } //tolua_export virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export @@ -95,7 +100,8 @@ protected: float m_LastGroundHeight; bool m_bTouchGround; double m_Stance; - cInventory* m_Inventory; + cSurvivalInventory* m_Inventory; + cCreativeInventory* m_CreativeInventory; cWindow* m_CurrentWindow; float m_TimeLastPickupCheck; diff --git a/source/cSurvivalInventory.cpp b/source/cSurvivalInventory.cpp new file mode 100644 index 000000000..1618e04ae --- /dev/null +++ b/source/cSurvivalInventory.cpp @@ -0,0 +1,90 @@ +#include "cSurvivalInventory.h" +#include //memset +#include "cPlayer.h" +#include "cClientHandle.h" +#include "cMCLogger.h" +#include "cWindow.h" +#include "cItem.h" +#include "cRecipeChecker.h" +#include "cRoot.h" +#include "packets/cPacket_WindowClick.h" + +cSurvivalInventory::~cSurvivalInventory() +{ + if( GetWindow() ) GetWindow()->Close( *m_Owner ); + CloseWindow(); +} + +cSurvivalInventory::cSurvivalInventory(cPlayer* a_Owner) + : cInventory(a_Owner) +{ + if( !GetWindow() ) + { + cWindow* Window = new cWindow( this, false ); + Window->SetSlots( m_Slots, c_NumSlots ); + Window->SetWindowID( 0 ); + OpenWindow( Window ); + } +} + +void cSurvivalInventory::Clicked( cPacket* a_ClickPacket ) +{ + cPacket_WindowClick *Packet = reinterpret_cast(a_ClickPacket); + bool bDontCook = false; + if( GetWindow() ) + { + // Override for craft result slot + if( Packet->m_SlotNum == (short)c_CraftOffset ) + { + LOG("In craft slot: %i x %i !!", m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount ); + cItem* DraggingItem = GetWindow()->GetDraggingItem(); + if( DraggingItem->IsEmpty() ) + { + *DraggingItem = m_Slots[c_CraftOffset]; + m_Slots[c_CraftOffset].Empty(); + } + else if( DraggingItem->Equals( m_Slots[c_CraftOffset] ) ) + { + if( DraggingItem->m_ItemCount + m_Slots[c_CraftOffset].m_ItemCount <= 64 ) + { + DraggingItem->m_ItemCount += m_Slots[c_CraftOffset].m_ItemCount; + m_Slots[0].Empty(); + } + else + { + bDontCook = true; + } + } + else + { + bDontCook = true; + } + LOG("Dragging Dish %i", DraggingItem->m_ItemCount ); + } + else + { + GetWindow()->Clicked( Packet, *m_Owner ); + } + } + else + { + LOG("No Inventory window! WTF"); + } + + if( Packet->m_SlotNum >= (short)c_CraftOffset && Packet->m_SlotNum < (short)(c_CraftOffset+c_CraftSlots+1) ) + { + cItem CookedItem; + if( Packet->m_SlotNum == 0 && !bDontCook ) + { + CookedItem = cRoot::Get()->GetRecipeChecker()->CookIngredients( m_Slots+c_CraftOffset+1, 2, 2, true ); + } + else + { + CookedItem = cRoot::Get()->GetRecipeChecker()->CookIngredients( m_Slots+c_CraftOffset+1, 2, 2 ); + } + m_Slots[c_CraftOffset] = CookedItem; + LOG("You cooked: %i x %i !!", m_Slots[c_CraftOffset].m_ItemID, m_Slots[c_CraftOffset].m_ItemCount ); + SendWholeInventory( m_Owner->GetClientHandle() ); + } + SendSlot( 0 ); +} diff --git a/source/cSurvivalInventory.h b/source/cSurvivalInventory.h new file mode 100644 index 000000000..525387b08 --- /dev/null +++ b/source/cSurvivalInventory.h @@ -0,0 +1,14 @@ +#pragma once + +#include "cInventory.h" + +class cSurvivalInventory //tolua_export + : public cInventory + , public cWindowOwner +{ //tolua_export +public: + cSurvivalInventory(cPlayer* a_Owner); + ~cSurvivalInventory(); + + virtual void Clicked( cPacket* a_ClickPacket ); +}; //tolua_export diff --git a/source/cWindow.cpp b/source/cWindow.cpp index 68c8d4142..02ee3c541 100644 --- a/source/cWindow.cpp +++ b/source/cWindow.cpp @@ -48,7 +48,7 @@ cItem* cWindow::GetDraggingItem( cPlayer * a_Player /* = 0 */ ) { if( m_bInventoryVisible && a_Player ) { - cWindow* Window = a_Player->GetInventory().GetWindow(); + cWindow* Window = a_Player->GetSurvivalInventory().GetWindow(); if( Window ) { return Window->GetDraggingItem(); @@ -68,7 +68,7 @@ void cWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) if( m_bInventoryVisible ) { - cWindow* Window = a_Player.GetInventory().GetWindow(); + cWindow* Window = a_Player.GetSurvivalInventory().GetWindow(); if( Window ) { m_DraggingItem = Window->GetDraggingItem(); @@ -170,7 +170,7 @@ void cWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) { a_ClickPacket->m_WindowID = 0; a_ClickPacket->m_SlotNum -= (short)(m_NumSlots - 9); - cWindow* Window = a_Player.GetInventory().GetWindow(); + cWindow* Window = a_Player.GetSurvivalInventory().GetWindow(); if( Window ) { Window->Clicked( a_ClickPacket, a_Player ); diff --git a/source/packets/cPacket_CreateInventoryAction.cpp b/source/packets/cPacket_CreateInventoryAction.cpp deleted file mode 100644 index 9ccc9f383..000000000 --- a/source/packets/cPacket_CreateInventoryAction.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "cPacket_CreateInventoryAction.h" -#include "cPacket_ItemData.h" - -cPacket_CreateInventoryAction::cPacket_CreateInventoryAction( const cPacket_CreateInventoryAction & a_Copy ) -{ - m_PacketID = E_CREATE_INVENTORY_ACTION; - m_Slot = a_Copy.m_Slot; - m_ItemID = a_Copy.m_ItemID; - m_Quantity = 0; - m_Damage = 0; -} - -bool cPacket_CreateInventoryAction::Parse(cSocket & a_Socket) -{ - m_Socket = a_Socket; - if( !ReadShort ( m_Slot ) ) return false; - /* - if( !ReadShort ( m_ItemID ) ) return false; - if( !ReadShort ( m_Quantity ) ) return false; - if( !ReadShort ( m_Damage ) ) return false; - */ - - cPacket_ItemData Item; - - Item.Parse(m_Socket); - - m_ItemID = Item.m_ItemID; - m_Quantity = Item.m_ItemCount; - m_Damage = Item.m_ItemUses; - - - return true; -} - -bool cPacket_CreateInventoryAction::Send(cSocket & a_Socket) -{ - //LOG("InventoryChange:"); - unsigned int TotalSize = c_Size; - - cPacket_ItemData Item; - - TotalSize += Item.GetSize(m_ItemID); - - char* Message = new char[TotalSize]; - - if( m_ItemID <= 0 ) m_ItemID = -1; // Fix, to make sure no invalid values are sent. - // WARNING: HERE ITS -1, BUT IN NAMED ENTITY SPAWN PACKET ITS 0 !! - //LOG("cPacket_CreateInventoryAction: Sending Creative item ID: %i", m_ItemID ); - - unsigned int i = 0; - AppendByte ( (char)m_PacketID, Message, i ); - AppendShort ( m_Slot, Message, i ); - - Item.AppendItem(Message, i, m_ItemID, m_Quantity, m_Damage); - - bool RetVal = !cSocket::IsSocketError( SendData( a_Socket, Message, TotalSize, 0 ) ); - delete [] Message; - return RetVal; -} diff --git a/source/packets/cPacket_CreateInventoryAction.h b/source/packets/cPacket_CreateInventoryAction.h deleted file mode 100644 index 083e05446..000000000 --- a/source/packets/cPacket_CreateInventoryAction.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "cPacket.h" -#include "PacketID.h" - -//Sure itīs not Creative Inventory? - -class cPacket_CreateInventoryAction : public cPacket -{ -public: - cPacket_CreateInventoryAction() - : m_Slot( 0 ) - , m_ItemID( 0 ) - , m_Quantity( 0 ) - , m_Damage( 0 ) - { m_PacketID = E_CREATE_INVENTORY_ACTION; m_Quantity = 1; } - cPacket_CreateInventoryAction( const cPacket_CreateInventoryAction & a_Copy ); - virtual cPacket* Clone() const { return new cPacket_CreateInventoryAction(*this); } - - bool Parse(cSocket & a_Socket); - bool Send(cSocket & a_Socket); - - short m_Slot; // 0 = hold 1-4 = armor - short m_ItemID; - char m_Quantity; //Byte not short ;) - short m_Damage; - - static const unsigned int c_Size = 1 + 2; -}; diff --git a/source/packets/cPacket_CreativeInventoryAction.cpp b/source/packets/cPacket_CreativeInventoryAction.cpp new file mode 100644 index 000000000..834a3c2fe --- /dev/null +++ b/source/packets/cPacket_CreativeInventoryAction.cpp @@ -0,0 +1,54 @@ +#include "cPacket_CreativeInventoryAction.h" +#include "cPacket_ItemData.h" + +cPacket_CreativeInventoryAction::cPacket_CreativeInventoryAction( const cPacket_CreativeInventoryAction & a_Copy ) +{ + m_PacketID = E_CREATIVE_INVENTORY_ACTION; + m_Slot = a_Copy.m_Slot; + m_ItemID = a_Copy.m_ItemID; + m_Quantity = a_Copy.m_Quantity; + m_Damage = a_Copy.m_Damage; +} + +bool cPacket_CreativeInventoryAction::Parse(cSocket & a_Socket) +{ + m_Socket = a_Socket; + if( !ReadShort ( m_Slot ) ) return false; + + cPacket_ItemData Item; + + Item.Parse(m_Socket); + + m_ItemID = Item.m_ItemID; + m_Quantity = Item.m_ItemCount; + m_Damage = Item.m_ItemUses; + + + return true; +} + +bool cPacket_CreativeInventoryAction::Send(cSocket & a_Socket) +{ + //LOG("InventoryChange:"); + unsigned int TotalSize = c_Size; + + cPacket_ItemData Item; + + TotalSize += Item.GetSize(m_ItemID); + + char* Message = new char[TotalSize]; + + if( m_ItemID <= 0 ) m_ItemID = -1; // Fix, to make sure no invalid values are sent. + // WARNING: HERE ITS -1, BUT IN NAMED ENTITY SPAWN PACKET ITS 0 !! + //LOG("cPacket_CreateInventoryAction: Sending Creative item ID: %i", m_ItemID ); + + unsigned int i = 0; + AppendByte ( (char)m_PacketID, Message, i ); + AppendShort ( m_Slot, Message, i ); + + Item.AppendItem(Message, i, m_ItemID, m_Quantity, m_Damage); + + bool RetVal = !cSocket::IsSocketError( SendData( a_Socket, Message, TotalSize, 0 ) ); + delete [] Message; + return RetVal; +} diff --git a/source/packets/cPacket_CreativeInventoryAction.h b/source/packets/cPacket_CreativeInventoryAction.h new file mode 100644 index 000000000..bb50c25db --- /dev/null +++ b/source/packets/cPacket_CreativeInventoryAction.h @@ -0,0 +1,29 @@ +#pragma once + +#include "cPacket.h" +#include "PacketID.h" + +//Sure itīs not Creative Inventory? + +class cPacket_CreativeInventoryAction : public cPacket +{ +public: + cPacket_CreativeInventoryAction() + : m_Slot( 0 ) + , m_ItemID( 0 ) + , m_Quantity( 0 ) + , m_Damage( 0 ) + { m_PacketID = E_CREATIVE_INVENTORY_ACTION; m_Quantity = 1; } + cPacket_CreativeInventoryAction( const cPacket_CreativeInventoryAction & a_Copy ); + virtual cPacket* Clone() const { return new cPacket_CreativeInventoryAction(*this); } + + bool Parse(cSocket & a_Socket); + bool Send(cSocket & a_Socket); + + short m_Slot; // 0 = hold 1-4 = armor + short m_ItemID; + char m_Quantity; //Byte not short ;) + short m_Damage; + + static const unsigned int c_Size = 1 + 2; +}; -- cgit v1.2.3