Implemented basic eating support.
Food is now properly consumed and it takes 1.5 sec.
This commit is contained in:
parent
00196e975a
commit
4746d2251c
@ -555,12 +555,9 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, ch
|
|||||||
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
|
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
|
||||||
if (ItemHandler->IsFood())
|
if (ItemHandler->IsFood())
|
||||||
{
|
{
|
||||||
if (PlgMgr->CallHookPlayerEating(*m_Player))
|
m_Player->AbortEating();
|
||||||
{
|
|
||||||
// A plugin doesn't agree with the action. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (PlgMgr->CallHookPlayerShooting(*m_Player))
|
if (PlgMgr->CallHookPlayerShooting(*m_Player))
|
||||||
@ -569,7 +566,7 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, ch
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOGINFO("%s: Status SHOOT / EAT not implemented", __FUNCTION__);
|
LOGINFO("%s: Status SHOOT not implemented", __FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -804,15 +801,14 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
|||||||
}
|
}
|
||||||
else if (ItemHandler->IsFood())
|
else if (ItemHandler->IsFood())
|
||||||
{
|
{
|
||||||
cItem Item;
|
m_Player->StartEating();
|
||||||
Item.m_ItemType = Equipped.m_ItemType;
|
if (PlgMgr->CallHookPlayerEating(*m_Player))
|
||||||
Item.m_ItemCount = 1;
|
|
||||||
if (ItemHandler->EatItem(m_Player, &Item))
|
|
||||||
{
|
{
|
||||||
ItemHandler->OnFoodEaten(World, m_Player, &Item);
|
// A plugin won't let us eat, abort (send the proper packets to the client, too):
|
||||||
m_Player->GetInventory().RemoveOneEquippedItem();
|
m_Player->AbortEating();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -282,6 +282,9 @@ private:
|
|||||||
/// Buffer for received messages to be processed in the Tick thread
|
/// Buffer for received messages to be processed in the Tick thread
|
||||||
AStringList m_PendingMessages;
|
AStringList m_PendingMessages;
|
||||||
|
|
||||||
|
static int s_ClientCount;
|
||||||
|
int m_UniqueID;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Returns true if the rate block interactions is within a reasonable limit (bot protection)
|
/// Returns true if the rate block interactions is within a reasonable limit (bot protection)
|
||||||
@ -312,9 +315,6 @@ private:
|
|||||||
virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client
|
virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client
|
||||||
virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client
|
virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client
|
||||||
virtual void SocketClosed (void) override; // The socket has been closed for any reason
|
virtual void SocketClosed (void) override; // The socket has been closed for any reason
|
||||||
|
|
||||||
static int s_ClientCount;
|
|
||||||
int m_UniqueID;
|
|
||||||
}; // tolua_export
|
}; // tolua_export
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,53 +4,53 @@
|
|||||||
#include "ItemHandler.h"
|
#include "ItemHandler.h"
|
||||||
|
|
||||||
|
|
||||||
class cItemFoodHandler : public cItemHandler
|
|
||||||
|
|
||||||
|
|
||||||
|
class cItemFoodHandler :
|
||||||
|
public cItemHandler
|
||||||
{
|
{
|
||||||
|
typedef cItemHandler super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cItemFoodHandler(int a_ItemType)
|
cItemFoodHandler(int a_ItemType)
|
||||||
: cItemHandler(a_ItemType)
|
: super(a_ItemType)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool IsFood() override
|
|
||||||
|
virtual bool IsFood(void) override
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual FoodInfo GetFoodInfo() override
|
|
||||||
|
virtual FoodInfo GetFoodInfo(void) override
|
||||||
{
|
{
|
||||||
switch(m_ItemType)
|
switch(m_ItemType)
|
||||||
{
|
{
|
||||||
case E_ITEM_BREAD:
|
case E_ITEM_BREAD: return FoodInfo(5, 6);
|
||||||
return FoodInfo(5, 6.f);
|
case E_ITEM_COOKIE: return FoodInfo(2, 0.4);
|
||||||
case E_ITEM_COOKIE:
|
case E_ITEM_MELON_SLICE: return FoodInfo(2, 1.2);
|
||||||
return FoodInfo(2, 0.4f);
|
case E_ITEM_RAW_CHICKEN: return FoodInfo(2, 1.2, 30);
|
||||||
case E_ITEM_MELON_SLICE:
|
case E_ITEM_COOKED_CHICKEN: return FoodInfo(6, 7.2);
|
||||||
return FoodInfo(2, 1.2f);
|
case E_ITEM_RAW_BEEF: return FoodInfo(3, 1.8);
|
||||||
case E_ITEM_RAW_CHICKEN:
|
case E_ITEM_RAW_PORKCHOP: return FoodInfo(3, 1.8);
|
||||||
return FoodInfo(2, 1.2f, 30);
|
case E_ITEM_STEAK: return FoodInfo(8, 12.8);
|
||||||
case E_ITEM_COOKED_CHICKEN:
|
case E_ITEM_COOKED_PORKCHOP: return FoodInfo(8, 12.8);
|
||||||
return FoodInfo(6, 7.2f);
|
case E_ITEM_RAW_FISH: return FoodInfo(2, 1.2);
|
||||||
case E_ITEM_RAW_BEEF:
|
case E_ITEM_COOKED_FISH: return FoodInfo(5, 6);
|
||||||
case E_ITEM_RAW_PORKCHOP:
|
case E_ITEM_RED_APPLE: return FoodInfo(4, 2.4);
|
||||||
return FoodInfo(3, 1.8f);
|
case E_ITEM_GOLDEN_APPLE: return FoodInfo(4, 9.6);
|
||||||
case E_ITEM_STEAK:
|
case E_ITEM_ROTTEN_FLESH: return FoodInfo(4, 0.8, 80);
|
||||||
case E_ITEM_COOKED_PORKCHOP:
|
case E_ITEM_SPIDER_EYE: return FoodInfo(2, 3.2, 100);
|
||||||
return FoodInfo(8, 12.8f);
|
|
||||||
case E_ITEM_RAW_FISH:
|
|
||||||
return FoodInfo(2, 1.2f);
|
|
||||||
case E_ITEM_COOKED_FISH:
|
|
||||||
return FoodInfo(5, 6.f);
|
|
||||||
case E_ITEM_RED_APPLE:
|
|
||||||
return FoodInfo(4, 2.4f);
|
|
||||||
case E_ITEM_GOLDEN_APPLE:
|
|
||||||
return FoodInfo(4, 9.6f);
|
|
||||||
case E_ITEM_ROTTEN_FLESH:
|
|
||||||
return FoodInfo(4, 0.8f, 80);
|
|
||||||
case E_ITEM_SPIDER_EYE:
|
|
||||||
return FoodInfo(2, 3.2f, 100);
|
|
||||||
}
|
}
|
||||||
|
LOGWARNING("%s: Unknown food item (%d), returning zero nutrition", __FUNCTION__, m_ItemType);
|
||||||
return FoodInfo(0, 0.f);
|
return FoodInfo(0, 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "../Item.h"
|
#include "../Item.h"
|
||||||
#include "../World.h"
|
#include "../World.h"
|
||||||
#include "../Player.h"
|
#include "../Player.h"
|
||||||
|
#include "../FastRandom.h"
|
||||||
|
|
||||||
// Handlers:
|
// Handlers:
|
||||||
#include "ItemBed.h"
|
#include "ItemBed.h"
|
||||||
@ -465,15 +466,17 @@ bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item)
|
|||||||
{
|
{
|
||||||
FoodInfo Info = GetFoodInfo();
|
FoodInfo Info = GetFoodInfo();
|
||||||
|
|
||||||
if(Info.FoodLevel > 0 || Info.Saturation > 0.f)
|
if ((Info.FoodLevel > 0) || (Info.Saturation > 0.f))
|
||||||
{
|
{
|
||||||
bool Success = a_Player->Feed(Info.FoodLevel, Info.Saturation);
|
bool Success = a_Player->Feed(Info.FoodLevel, Info.Saturation);
|
||||||
if(Success && Info.PoisionChance > 0)
|
|
||||||
|
// If consumed and there's chance of foodpoisoning, do it:
|
||||||
|
if (Success && (Info.PoisonChance > 0))
|
||||||
{
|
{
|
||||||
MTRand r1;
|
cFastRandom r1;
|
||||||
if((r1.randInt(100) - Info.PoisionChance) <= 0)
|
if ((r1.NextInt(100, a_Player->GetUniqueID()) - Info.PoisonChance) <= 0)
|
||||||
{ //Unlucky guy :D
|
{
|
||||||
//TODO: Make player ill
|
a_Player->FoodPoison(300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,15 +38,16 @@ public:
|
|||||||
|
|
||||||
struct FoodInfo
|
struct FoodInfo
|
||||||
{
|
{
|
||||||
FoodInfo(short a_FoodLevel, float a_Saturation, char a_PoisionChance = 0)
|
int FoodLevel;
|
||||||
|
double Saturation;
|
||||||
|
int PoisonChance; // 0 - 100, in percent. 0 = no chance of poisoning, 100 = sure poisoning
|
||||||
|
|
||||||
|
FoodInfo(int a_FoodLevel, double a_Saturation, int a_PoisonChance = 0) :
|
||||||
|
FoodLevel(a_FoodLevel),
|
||||||
|
Saturation(a_Saturation),
|
||||||
|
PoisonChance(a_PoisonChance)
|
||||||
{
|
{
|
||||||
FoodLevel = a_FoodLevel;
|
|
||||||
Saturation = a_Saturation;
|
|
||||||
PoisionChance = a_PoisionChance;
|
|
||||||
}
|
}
|
||||||
short FoodLevel;
|
|
||||||
float Saturation;
|
|
||||||
char PoisionChance; //0 - 100
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
/// Returns the FoodInfo for this item. (FoodRecovery, Saturation and PoisionChance)
|
/// Returns the FoodInfo for this item. (FoodRecovery, Saturation and PoisionChance)
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "OSSupport/Timer.h"
|
#include "OSSupport/Timer.h"
|
||||||
#include "MersenneTwister.h"
|
#include "MersenneTwister.h"
|
||||||
#include "Chunk.h"
|
#include "Chunk.h"
|
||||||
|
#include "Items/ItemHandler.h"
|
||||||
|
|
||||||
#include "Vector3d.h"
|
#include "Vector3d.h"
|
||||||
#include "Vector3f.h"
|
#include "Vector3f.h"
|
||||||
@ -58,6 +59,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
|
|||||||
, m_SprintingMaxSpeed(0.13)
|
, m_SprintingMaxSpeed(0.13)
|
||||||
, m_IsCrouched(false)
|
, m_IsCrouched(false)
|
||||||
, m_IsSprinting(false)
|
, m_IsSprinting(false)
|
||||||
|
, m_EatingFinishTick(-1)
|
||||||
{
|
{
|
||||||
LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
|
LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
|
||||||
a_PlayerName.c_str(), a_Client->GetIPString().c_str(),
|
a_PlayerName.c_str(), a_Client->GetIPString().c_str(),
|
||||||
@ -189,6 +191,11 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
|
|||||||
{
|
{
|
||||||
m_World->CollectPickupsByPlayer(this);
|
m_World->CollectPickupsByPlayer(this);
|
||||||
|
|
||||||
|
if ((m_EatingFinishTick >= 0) && (m_EatingFinishTick <= m_World->GetWorldAge()))
|
||||||
|
{
|
||||||
|
FinishEating();
|
||||||
|
}
|
||||||
|
|
||||||
HandleFood();
|
HandleFood();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,6 +356,57 @@ void cPlayer::FoodPoison(int a_NumTicks)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cPlayer::StartEating(void)
|
||||||
|
{
|
||||||
|
// Set the timer:
|
||||||
|
m_EatingFinishTick = m_World->GetWorldAge() + EATING_TICKS;
|
||||||
|
|
||||||
|
// Send the packets:
|
||||||
|
m_World->BroadcastPlayerAnimation(*this, 5);
|
||||||
|
m_World->BroadcastEntityMetadata(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cPlayer::FinishEating(void)
|
||||||
|
{
|
||||||
|
// Reset the timer:
|
||||||
|
m_EatingFinishTick = -1;
|
||||||
|
|
||||||
|
// Send the packets:
|
||||||
|
m_ClientHandle->SendEntityStatus(*this, ENTITY_STATUS_EATING_ACCEPTED);
|
||||||
|
m_World->BroadcastPlayerAnimation(*this, 0);
|
||||||
|
m_World->BroadcastEntityMetadata(*this);
|
||||||
|
|
||||||
|
// consume the item:
|
||||||
|
cItem Item(GetEquippedItem());
|
||||||
|
Item.m_ItemCount = 1;
|
||||||
|
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Item.m_ItemType);
|
||||||
|
if (!ItemHandler->EatItem(this, &Item))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ItemHandler->OnFoodEaten(m_World, this, &Item);
|
||||||
|
GetInventory().RemoveOneEquippedItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cPlayer::AbortEating(void)
|
||||||
|
{
|
||||||
|
m_EatingFinishTick = -1;
|
||||||
|
m_World->BroadcastPlayerAnimation(*this, 0);
|
||||||
|
m_World->BroadcastEntityMetadata(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::SendHealth(void)
|
void cPlayer::SendHealth(void)
|
||||||
{
|
{
|
||||||
if (m_ClientHandle != NULL)
|
if (m_ClientHandle != NULL)
|
||||||
|
@ -28,6 +28,7 @@ public:
|
|||||||
{
|
{
|
||||||
MAX_HEALTH = 20,
|
MAX_HEALTH = 20,
|
||||||
MAX_FOOD_LEVEL = 20,
|
MAX_FOOD_LEVEL = 20,
|
||||||
|
EATING_TICKS = 30, ///< Number of ticks it takes to eat an item
|
||||||
} ;
|
} ;
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
@ -164,6 +165,15 @@ public:
|
|||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
|
/// Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet
|
||||||
|
void StartEating(void);
|
||||||
|
|
||||||
|
/// Finishes eating the currently equipped item. Consumes the item, updates health and broadcasts the packets
|
||||||
|
void FinishEating(void);
|
||||||
|
|
||||||
|
/// Aborts the current eating operation
|
||||||
|
void AbortEating(void);
|
||||||
|
|
||||||
virtual void KilledBy(cEntity * a_Killer) override;
|
virtual void KilledBy(cEntity * a_Killer) override;
|
||||||
|
|
||||||
void Respawn(void); // tolua_export
|
void Respawn(void); // tolua_export
|
||||||
@ -296,6 +306,9 @@ protected:
|
|||||||
bool m_IsCrouched;
|
bool m_IsCrouched;
|
||||||
bool m_IsSprinting;
|
bool m_IsSprinting;
|
||||||
|
|
||||||
|
/// The world tick in which eating will be finished. -1 if not eating
|
||||||
|
Int64 m_EatingFinishTick;
|
||||||
|
|
||||||
|
|
||||||
virtual void Destroyed(void);
|
virtual void Destroyed(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user