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());
|
||||
if (ItemHandler->IsFood())
|
||||
{
|
||||
if (PlgMgr->CallHookPlayerEating(*m_Player))
|
||||
{
|
||||
// A plugin doesn't agree with the action. The plugin itself is responsible for handling the consequences (possible inventory mismatch)
|
||||
m_Player->AbortEating();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PlgMgr->CallHookPlayerShooting(*m_Player))
|
||||
@ -569,7 +566,7 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, ch
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOGINFO("%s: Status SHOOT / EAT not implemented", __FUNCTION__);
|
||||
LOGINFO("%s: Status SHOOT not implemented", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -804,15 +801,14 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, c
|
||||
}
|
||||
else if (ItemHandler->IsFood())
|
||||
{
|
||||
cItem Item;
|
||||
Item.m_ItemType = Equipped.m_ItemType;
|
||||
Item.m_ItemCount = 1;
|
||||
if (ItemHandler->EatItem(m_Player, &Item))
|
||||
m_Player->StartEating();
|
||||
if (PlgMgr->CallHookPlayerEating(*m_Player))
|
||||
{
|
||||
ItemHandler->OnFoodEaten(World, m_Player, &Item);
|
||||
m_Player->GetInventory().RemoveOneEquippedItem();
|
||||
// A plugin won't let us eat, abort (send the proper packets to the client, too):
|
||||
m_Player->AbortEating();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -282,6 +282,9 @@ private:
|
||||
/// Buffer for received messages to be processed in the Tick thread
|
||||
AStringList m_PendingMessages;
|
||||
|
||||
static int s_ClientCount;
|
||||
int m_UniqueID;
|
||||
|
||||
|
||||
|
||||
/// 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 GetOutgoingData(AString & a_Data) override; // Data can be sent to client
|
||||
virtual void SocketClosed (void) override; // The socket has been closed for any reason
|
||||
|
||||
static int s_ClientCount;
|
||||
int m_UniqueID;
|
||||
}; // tolua_export
|
||||
|
||||
|
||||
|
@ -4,53 +4,53 @@
|
||||
#include "ItemHandler.h"
|
||||
|
||||
|
||||
class cItemFoodHandler : public cItemHandler
|
||||
|
||||
|
||||
|
||||
class cItemFoodHandler :
|
||||
public cItemHandler
|
||||
{
|
||||
typedef cItemHandler super;
|
||||
|
||||
public:
|
||||
cItemFoodHandler(int a_ItemType)
|
||||
: cItemHandler(a_ItemType)
|
||||
: super(a_ItemType)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool IsFood() override
|
||||
|
||||
virtual bool IsFood(void) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual FoodInfo GetFoodInfo() override
|
||||
|
||||
virtual FoodInfo GetFoodInfo(void) override
|
||||
{
|
||||
switch(m_ItemType)
|
||||
{
|
||||
case E_ITEM_BREAD:
|
||||
return FoodInfo(5, 6.f);
|
||||
case E_ITEM_COOKIE:
|
||||
return FoodInfo(2, 0.4f);
|
||||
case E_ITEM_MELON_SLICE:
|
||||
return FoodInfo(2, 1.2f);
|
||||
case E_ITEM_RAW_CHICKEN:
|
||||
return FoodInfo(2, 1.2f, 30);
|
||||
case E_ITEM_COOKED_CHICKEN:
|
||||
return FoodInfo(6, 7.2f);
|
||||
case E_ITEM_RAW_BEEF:
|
||||
case E_ITEM_RAW_PORKCHOP:
|
||||
return FoodInfo(3, 1.8f);
|
||||
case E_ITEM_STEAK:
|
||||
case E_ITEM_COOKED_PORKCHOP:
|
||||
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);
|
||||
case E_ITEM_BREAD: return FoodInfo(5, 6);
|
||||
case E_ITEM_COOKIE: return FoodInfo(2, 0.4);
|
||||
case E_ITEM_MELON_SLICE: return FoodInfo(2, 1.2);
|
||||
case E_ITEM_RAW_CHICKEN: return FoodInfo(2, 1.2, 30);
|
||||
case E_ITEM_COOKED_CHICKEN: return FoodInfo(6, 7.2);
|
||||
case E_ITEM_RAW_BEEF: return FoodInfo(3, 1.8);
|
||||
case E_ITEM_RAW_PORKCHOP: return FoodInfo(3, 1.8);
|
||||
case E_ITEM_STEAK: return FoodInfo(8, 12.8);
|
||||
case E_ITEM_COOKED_PORKCHOP: return FoodInfo(8, 12.8);
|
||||
case E_ITEM_RAW_FISH: return FoodInfo(2, 1.2);
|
||||
case E_ITEM_COOKED_FISH: return FoodInfo(5, 6);
|
||||
case E_ITEM_RED_APPLE: return FoodInfo(4, 2.4);
|
||||
case E_ITEM_GOLDEN_APPLE: return FoodInfo(4, 9.6);
|
||||
case E_ITEM_ROTTEN_FLESH: return FoodInfo(4, 0.8, 80);
|
||||
case E_ITEM_SPIDER_EYE: return FoodInfo(2, 3.2, 100);
|
||||
}
|
||||
LOGWARNING("%s: Unknown food item (%d), returning zero nutrition", __FUNCTION__, m_ItemType);
|
||||
return FoodInfo(0, 0.f);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "../Item.h"
|
||||
#include "../World.h"
|
||||
#include "../Player.h"
|
||||
#include "../FastRandom.h"
|
||||
|
||||
// Handlers:
|
||||
#include "ItemBed.h"
|
||||
@ -465,15 +466,17 @@ bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item)
|
||||
{
|
||||
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);
|
||||
if(Success && Info.PoisionChance > 0)
|
||||
|
||||
// If consumed and there's chance of foodpoisoning, do it:
|
||||
if (Success && (Info.PoisonChance > 0))
|
||||
{
|
||||
MTRand r1;
|
||||
if((r1.randInt(100) - Info.PoisionChance) <= 0)
|
||||
{ //Unlucky guy :D
|
||||
//TODO: Make player ill
|
||||
cFastRandom r1;
|
||||
if ((r1.NextInt(100, a_Player->GetUniqueID()) - Info.PoisonChance) <= 0)
|
||||
{
|
||||
a_Player->FoodPoison(300);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,16 +38,17 @@ public:
|
||||
|
||||
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)
|
||||
virtual FoodInfo GetFoodInfo();
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "OSSupport/Timer.h"
|
||||
#include "MersenneTwister.h"
|
||||
#include "Chunk.h"
|
||||
#include "Items/ItemHandler.h"
|
||||
|
||||
#include "Vector3d.h"
|
||||
#include "Vector3f.h"
|
||||
@ -58,6 +59,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
|
||||
, m_SprintingMaxSpeed(0.13)
|
||||
, m_IsCrouched(false)
|
||||
, m_IsSprinting(false)
|
||||
, m_EatingFinishTick(-1)
|
||||
{
|
||||
LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
|
||||
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);
|
||||
|
||||
if ((m_EatingFinishTick >= 0) && (m_EatingFinishTick <= m_World->GetWorldAge()))
|
||||
{
|
||||
FinishEating();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (m_ClientHandle != NULL)
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
{
|
||||
MAX_HEALTH = 20,
|
||||
MAX_FOOD_LEVEL = 20,
|
||||
EATING_TICKS = 30, ///< Number of ticks it takes to eat an item
|
||||
} ;
|
||||
// tolua_end
|
||||
|
||||
@ -164,6 +165,15 @@ public:
|
||||
|
||||
// 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;
|
||||
|
||||
void Respawn(void); // tolua_export
|
||||
@ -296,6 +306,9 @@ protected:
|
||||
bool m_IsCrouched;
|
||||
bool m_IsSprinting;
|
||||
|
||||
/// The world tick in which eating will be finished. -1 if not eating
|
||||
Int64 m_EatingFinishTick;
|
||||
|
||||
|
||||
virtual void Destroyed(void);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user