summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/cClientHandle.cpp17
-rw-r--r--source/cPawn.cpp16
-rw-r--r--source/cPawn.h14
-rw-r--r--source/cPlayer.cpp132
-rw-r--r--source/cPlayer.h20
-rw-r--r--source/items/Item.cpp55
-rw-r--r--source/items/Item.h19
-rw-r--r--source/items/ItemFood.h55
-rw-r--r--source/squirrelbindings/SquirrelBindings.cpp14
-rw-r--r--source/squirrelbindings/SquirrelBindings.h2
-rw-r--r--source/squirrelbindings/SquirrelFunctions.cpp7
11 files changed, 208 insertions, 143 deletions
diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp
index 76aaf2724..5bbf0f512 100644
--- a/source/cClientHandle.cpp
+++ b/source/cClientHandle.cpp
@@ -339,11 +339,7 @@ void cClientHandle::Authenticate(void)
m_Player->GetInventory().SendWholeInventory(this);
// Send health
- cPacket_UpdateHealth Health;
- Health.m_Health = (short)m_Player->GetHealth();
- Health.m_Food = m_Player->GetFood();
- Health.m_Saturation = m_Player->GetFoodSaturation();
- Send(Health);
+ m_Player->SendHealth();
m_Player->Initialize(World);
StreamChunks();
@@ -856,14 +852,7 @@ void cClientHandle::HandleBlockDig(cPacket_BlockDig * a_Packet)
void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
{
- if(a_Packet->m_PosX == -1
- && a_Packet->m_PosY == 255
- && a_Packet->m_PosZ == -1)
- {
- //I donīt know whats the idea behind these packets O.o
- return;
- }
-
+
if (!CheckBlockInteractionsRate())
{
return;
@@ -960,7 +949,7 @@ void cClientHandle::HandleBlockPlace(cPacket_BlockPlace * a_Packet)
cItem Item;
Item.m_ItemID = Equipped.m_ItemID;
Item.m_ItemCount = 1;
- if (m_Player->EatItem(Item.m_ItemID))
+ if (ItemHandler->EatItem(m_Player, &Item))
{
ItemHandler->OnFoodEaten(World, m_Player, &Item);
m_Player->GetInventory().RemoveItem(Item);
diff --git a/source/cPawn.cpp b/source/cPawn.cpp
index 0037e56e4..9fe34059b 100644
--- a/source/cPawn.cpp
+++ b/source/cPawn.cpp
@@ -38,7 +38,6 @@ cPawn::cPawn()
, m_BurnPeriod(0.f)
{
SetMaxHealth(20);
- SetMaxFoodLevel(125);
}
@@ -235,18 +234,3 @@ void cPawn::SetMaxHealth(short a_MaxHealth)
m_Health = a_MaxHealth;
}
-
-
-
-
-void cPawn::SetMaxFoodLevel(short a_MaxFoodLevel)
-{
- m_MaxFoodLevel = a_MaxFoodLevel;
-
- //Reset food level
- m_FoodLevel = a_MaxFoodLevel;
-}
-
-
-
-
diff --git a/source/cPawn.h b/source/cPawn.h
index 2c4444174..dbf60d59e 100644
--- a/source/cPawn.h
+++ b/source/cPawn.h
@@ -47,23 +47,11 @@ public:
virtual void SetMaxHealth(short a_MaxHealth);
virtual short GetMaxHealth() { return m_MaxHealth; }
- //virtual void SetMaxFood(short a_MaxFood);
- virtual short GetMaxFood() { return m_MaxFoodLevel / 6; }
- virtual short GetFood() { return m_FoodLevel / 6; }
-
- //virtual void SetMaxFoodSaturation(float a_MaxFoodSaturation);
- virtual float GetMaxFoodSaturation() { return fmod(m_MaxFoodLevel, 6.f); }
- virtual float GetFoodSaturation() { return fmod(m_FoodLevel, 6.f); }
-
- virtual void SetMaxFoodLevel(short a_MaxFoodLevel);
- virtual short GetMaxFoodLevel() { return m_MaxFoodLevel; }
-
protected:
short m_Health;
- short m_FoodLevel;
short m_MaxHealth;
- short m_MaxFoodLevel;
+
bool m_bBurnable;
diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp
index 9e54b7c44..b7b7919fd 100644
--- a/source/cPlayer.cpp
+++ b/source/cPlayer.cpp
@@ -66,14 +66,22 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
, m_TimeLastPickupCheck( 0.f )
, m_Color('-')
, m_ClientHandle( a_Client )
+ , m_FoodExhaustionLevel(0.f)
+ , m_FoodTickTimer(0)
{
LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d",
a_PlayerName.c_str(), a_Client->GetSocket().GetIPString().c_str(),
this, GetUniqueID()
);
m_EntityType = eEntityType_Player;
+
SetMaxHealth(20);
- SetMaxFoodLevel(125);
+ m_MaxFoodLevel = 20;
+ m_MaxFoodSaturationLevel = 20.f;
+
+ m_FoodLevel = m_MaxFoodLevel;
+ m_FoodSaturationLevel = 5.f;
+
m_Inventory = new cSurvivalInventory( this );
m_CreativeInventory = new cCreativeInventory(this);
cTimer t1;
@@ -242,6 +250,34 @@ void cPlayer::Tick(float a_Dt)
if (m_Health > 0) // make sure player is alive
{
m_World->CollectPickupsByPlayer(this);
+
+ //Handle Health:
+ m_FoodTickTimer++;
+ if(m_FoodTickTimer >= 80)
+ {
+ m_FoodTickTimer = 0;
+
+ if(m_FoodLevel >= 17)
+ {
+ Heal(1);
+ }else if(m_FoodLevel == 0)
+ {
+ TakeDamage(1, NULL);
+ }
+ }
+
+ //TODO: Increase Exhaustion level http://www.minecraftwiki.net/wiki/Hunger#Exhaustion_level_increase
+ if(m_FoodExhaustionLevel >= 4.f)
+ {
+ m_FoodExhaustionLevel -= 4.f;
+
+ if(m_FoodSaturationLevel >= 1.f)
+ m_FoodSaturationLevel--;
+ else
+ m_FoodLevel = MAX(m_FoodLevel -1, 0);
+
+ SendHealth();
+ }
}
cTimer t1;
@@ -297,19 +333,12 @@ void cPlayer::Heal( int a_Health )
{
m_Health = (short) MIN(a_Health + m_Health, GetMaxHealth());
- cPacket_UpdateHealth Health;
- Health.m_Health = m_Health;
- Health.m_Food = GetFood();
- Health.m_Saturation = GetFoodSaturation();
- m_ClientHandle->Send( Health );
+
+ SendHealth();
}
}
-
-
-
-
-bool cPlayer::Feed(short a_Food)
+bool cPlayer::Feed(short a_Food, float a_Saturation)
{
if (m_FoodLevel >= GetMaxFoodLevel())
{
@@ -317,31 +346,31 @@ bool cPlayer::Feed(short a_Food)
}
m_FoodLevel = MIN(a_Food + m_FoodLevel, GetMaxFoodLevel());
-
- cPacket_UpdateHealth Health;
- Health.m_Health = m_Health;
- Health.m_Food = GetFood();
- Health.m_Saturation = GetFoodSaturation();
- m_ClientHandle->Send( Health );
+ m_FoodSaturationLevel = MIN(m_FoodSaturationLevel + a_Saturation, GetMaxFoodSaturationLevel());
+
+ SendHealth();
return true;
}
-
-
-
+void cPlayer::SendHealth()
+{
+ cPacket_UpdateHealth Health;
+ Health.m_Health = GetHealth();
+ Health.m_Food = GetFoodLevel();
+ Health.m_Saturation = GetFoodSaturationLevel();
+ if(m_ClientHandle != 0)
+ m_ClientHandle->Send( Health );
+}
void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator )
{
- if ( !(m_GameMode == 1) ) {
+ if(m_GameMode != eGameMode_Creative)
+ {
cPawn::TakeDamage( a_Damage, a_Instigator );
- cPacket_UpdateHealth Health;
- Health.m_Health = m_Health;
- Health.m_Food = GetFood();
- Health.m_Saturation = GetFoodSaturation();
- //TODO: Causes problems sometimes O.o (E.G. Disconnecting when attacked)
- if(m_ClientHandle != 0)
- m_ClientHandle->Send( Health );
+ AddFoodExhaustion(0.3f);
+
+ SendHealth();
}
}
@@ -914,7 +943,8 @@ bool cPlayer::LoadFromDisk()
}
m_Health = (short)root.get("health", 0 ).asInt();
- m_FoodLevel = (short)root.get("food", 0 ).asInt();
+ m_FoodLevel = (short)root.get("food", m_MaxFoodLevel ).asInt();
+ m_FoodSaturationLevel = (float)root.get("foodSaturation", m_MaxFoodSaturationLevel ).asDouble();
m_GameMode = (eGameMode) root.get("gamemode", eGameMode_NotSet).asInt();
@@ -963,6 +993,7 @@ bool cPlayer::SaveToDisk()
root["creativeinventory"] = JSON_CreativeInventory;
root["health"] = m_Health;
root["food"] = m_FoodLevel;
+ root["foodSaturation"] = m_FoodSaturationLevel;
root["world"] = GetWorld()->GetName();
if(m_GameMode == GetWorld()->GetGameMode())
@@ -1028,46 +1059,3 @@ void cPlayer::UseEquippedItem()
-
-bool cPlayer::EatItem(int a_ItemType)
-{
- // TODO: Handle hunger
- switch (a_ItemType)
- {
- case E_ITEM_APPLE: return Feed(24); // 2 food bars
- case E_ITEM_GOLDEN_APPLE: return Feed(60); // 5 food
- case E_ITEM_MUSHROOM_SOUP: return Feed(48); // 4 food
- case E_ITEM_BREAD: return Feed(30); // 2.5 food
- case E_ITEM_RAW_MEAT: return Feed(18); // 1.5 food
- case E_ITEM_COOKED_MEAT: return Feed(48); // 4 food
- case E_ITEM_RAW_FISH: return Feed(12); // 1 food
- case E_ITEM_COOKED_FISH: return Feed(30); // 2.5 food
- case E_ITEM_COOKED_CHICKEN: return Feed(36); // 3 food
- case E_ITEM_RAW_BEEF: return Feed(18); // 1.5 food
- case E_ITEM_STEAK: return Feed(48); // 4 food
- case E_ITEM_RAW_CHICKEN:
- {
- if (!Feed(12)) // 1 food
- {
- return false;
- }
- // TODO: A random chance to get food-poisoned
- return true;
- }
-
- case E_ITEM_ROTTEN_FLESH:
- {
- if (!Feed(24))
- {
- return false;
- }
- // TODO: Food-poisoning
- return true;
- }
- }
- return false;
-}
-
-
-
-
diff --git a/source/cPlayer.h b/source/cPlayer.h
index ef85a1d4e..c1420023e 100644
--- a/source/cPlayer.h
+++ b/source/cPlayer.h
@@ -83,7 +83,15 @@ public:
void Heal( int a_Health ); //tolua_export
/// Returns true if any food has been consumed, false if player "full"
- bool Feed(short a_Food);
+ bool Feed(short a_Food, float a_Saturation);
+
+ short GetMaxFoodLevel() { return m_MaxFoodLevel; }
+ short GetFoodLevel() { return m_FoodLevel; }
+
+ float GetMaxFoodSaturationLevel() { return m_MaxFoodSaturationLevel; }
+ float GetFoodSaturationLevel() { return m_FoodSaturationLevel; }
+
+ void AddFoodExhaustion(float a_Exhaustion) { m_FoodExhaustionLevel += a_Exhaustion; }
void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export
void KilledBy( cEntity* a_Killer ); //tolua_export
@@ -102,8 +110,7 @@ public:
void UseEquippedItem(void);
- /// Returns true if the item type is edible && it has been consumed, false otherwise
- bool EatItem(int a_ItemType);
+ void SendHealth();
protected:
virtual void Destroyed();
@@ -120,6 +127,13 @@ protected:
bool m_bVisible;
+ short m_FoodLevel;
+ short m_MaxFoodLevel;
+ float m_FoodSaturationLevel;
+ float m_MaxFoodSaturationLevel;
+ float m_FoodExhaustionLevel;
+ char m_FoodTickTimer;
+
float m_LastGroundHeight;
bool m_bTouchGround;
double m_Stance;
diff --git a/source/items/Item.cpp b/source/items/Item.cpp
index 3dd0a4218..ce72cf8b3 100644
--- a/source/items/Item.cpp
+++ b/source/items/Item.cpp
@@ -23,6 +23,7 @@
#include "ItemShovel.h"
#include "ItemSword.h"
#include "ItemDoor.h"
+#include "ItemFood.h"
#include "../blocks/Block.h"
@@ -109,6 +110,23 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemID)
case E_ITEM_WOODEN_DOOR:
return new cItemDoorHandler(a_ItemID);
+ //FOOD:
+ case E_ITEM_BREAD:
+ case E_ITEM_COOKIE:
+ case E_ITEM_MELON_SLICE:
+ case E_ITEM_RAW_CHICKEN:
+ case E_ITEM_COOKED_CHICKEN:
+ case E_ITEM_RAW_BEEF:
+ case E_ITEM_RAW_MEAT:
+ case E_ITEM_STEAK:
+ case E_ITEM_COOKED_MEAT:
+ case E_ITEM_RAW_FISH:
+ case E_ITEM_COOKED_FISH:
+ case E_ITEM_RED_APPLE:
+ case E_ITEM_GOLDEN_APPLE:
+ case E_ITEM_ROTTEN_FLESH:
+ case E_ITEM_SPIDER_EYE:
+ return new cItemFoodHandler(a_ItemID);
default:
return new cItemHandler(a_ItemID);
break;
@@ -159,16 +177,6 @@ void cItemHandler::OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item
}
-int cItemHandler::GetMaxStackSize()
-{
- return 64;
-}
-
-int cItemHandler::GetMaxDamage()
-{
- return 0;
-}
-
bool cItemHandler::IsTool()
{
return
@@ -230,4 +238,31 @@ void cItemHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item,
Handler->PlaceBlock(a_World, a_Player, GetBlockMeta(a_Item->m_ItemHealth), a_X, a_Y, a_Z, a_Dir);
if(a_Player->GetGameMode() == eGameMode_Survival)
a_Player->GetInventory().RemoveItem(cItem(a_Item->m_ItemID, 1));
+}
+
+bool cItemHandler::EatItem(cPlayer *a_Player, cItem *a_Item)
+{
+ FoodInfo Info = GetFoodInfo();
+
+ if(Info.FoodLevel > 0 || Info.Saturation > 0.f)
+ {
+ bool Success = a_Player->Feed(Info.FoodLevel, Info.Saturation);
+ if(Success && Info.PoisionChance > 0)
+ {
+ MTRand r1;
+ if((r1.randInt(100) - Info.PoisionChance) <= 0)
+ { //Unlucky guy :D
+ //TODO: Make player ill
+ }
+ }
+
+ return Success;
+ }
+
+ return false;
+}
+
+cItemHandler::FoodInfo cItemHandler::GetFoodInfo()
+{
+ return FoodInfo(0, 0.f);
} \ No newline at end of file
diff --git a/source/items/Item.h b/source/items/Item.h
index 96f957fcf..0a38ce3c0 100644
--- a/source/items/Item.h
+++ b/source/items/Item.h
@@ -13,8 +13,23 @@ public:
virtual bool OnDiggingBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir);
virtual void OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z);
virtual void OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item);
- virtual int GetMaxStackSize();
- virtual int GetMaxDamage();
+
+ struct FoodInfo
+ {
+ FoodInfo(short a_FoodLevel, float a_Saturation, char a_PoisionChance = 0)
+ {
+ FoodLevel = a_FoodLevel;
+ Saturation = a_Saturation;
+ PoisionChance = a_PoisionChance;
+ }
+ short FoodLevel;
+ float Saturation;
+ char PoisionChance; //0 - 100
+ };
+
+ virtual FoodInfo GetFoodInfo();
+
+ virtual bool EatItem(cPlayer *a_Player, cItem *a_Item);
virtual void PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z, char a_Dir);
diff --git a/source/items/ItemFood.h b/source/items/ItemFood.h
new file mode 100644
index 000000000..8998fd503
--- /dev/null
+++ b/source/items/ItemFood.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "Item.h"
+
+
+class cItemFoodHandler : public cItemHandler
+{
+public:
+ cItemFoodHandler(int a_ItemID)
+ : cItemHandler(a_ItemID)
+ {
+ }
+
+ virtual bool IsFood() override
+ {
+ return true;
+ }
+
+ virtual FoodInfo GetFoodInfo() override
+ {
+ switch(m_ItemID)
+ {
+ 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_MEAT:
+ return FoodInfo(3, 1.8f);
+ case E_ITEM_STEAK:
+ case E_ITEM_COOKED_MEAT:
+ 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);
+ }
+ return FoodInfo(0, 0.f);
+ }
+
+}; \ No newline at end of file
diff --git a/source/squirrelbindings/SquirrelBindings.cpp b/source/squirrelbindings/SquirrelBindings.cpp
index f0291b39b..c24b82c70 100644
--- a/source/squirrelbindings/SquirrelBindings.cpp
+++ b/source/squirrelbindings/SquirrelBindings.cpp
@@ -9,8 +9,7 @@
using namespace Sqrat;
-
-
+#if USE_SQUIRREL
void BindSquirrel(HSQUIRRELVM vm)
{
RootTable()
@@ -91,12 +90,6 @@ void BindSquirrel(HSQUIRRELVM vm)
.Func("GetMetaData", &cPawn::GetMetaData)
.Func("SetMaxHealth", &cPawn::SetMaxHealth)
.Func("GetMaxHealth", &cPawn::GetMaxHealth)
- .Func("GetMaxFood", &cPawn::GetMaxFood)
- .Func("GetFood", &cPawn::GetFood)
- .Func("GetMaxFoodSaturation", &cPawn::GetMaxFoodSaturation)
- .Func("GetFoodSaturation", &cPawn::GetFoodSaturation)
- .Func("SetMaxFoodLevel", &cPawn::SetMaxFoodLevel)
- .Func("GetMaxFoodLevel", &cPawn::SetMaxFoodLevel)
);
RootTable().Bind("cPlayer", DerivedClass<cPlayer, cPawn, NoConstructor>()
@@ -137,8 +130,6 @@ void BindSquirrel(HSQUIRRELVM vm)
.Func("MoveToWorld", &cPlayer::MoveToWorld)
.Func("GetLoadedWorldName", &cPlayer::GetLoadedWorldName)
.Func("UseEquippedItem", &cPlayer::UseEquippedItem)
- .Func("EatItem", &cPlayer::EatItem)
-
);
RootTable().Bind("StringArray", Class<SquirrelStringArray>()
@@ -175,5 +166,6 @@ void BindSquirrel(HSQUIRRELVM vm)
.Const("WeatherChanged", cPluginManager::HOOK_WEATHER_CHANGED)
.Const("UpdatingSign", cPluginManager::HOOK_UPDATING_SIGN)
.Const("UpdatedSign", cPluginManager::HOOK_UPDATED_SIGN));
+}
-} \ No newline at end of file
+#endif \ No newline at end of file
diff --git a/source/squirrelbindings/SquirrelBindings.h b/source/squirrelbindings/SquirrelBindings.h
index 1b71f5e86..d5aee170a 100644
--- a/source/squirrelbindings/SquirrelBindings.h
+++ b/source/squirrelbindings/SquirrelBindings.h
@@ -1,7 +1,7 @@
#pragma once
-#define USE_SQUIRREL 1
+#define USE_SQUIRREL 0
#if USE_SQUIRREL
diff --git a/source/squirrelbindings/SquirrelFunctions.cpp b/source/squirrelbindings/SquirrelFunctions.cpp
index 88871369d..b965c63ab 100644
--- a/source/squirrelbindings/SquirrelFunctions.cpp
+++ b/source/squirrelbindings/SquirrelFunctions.cpp
@@ -3,6 +3,9 @@
#include "SquirrelFunctions.h"
#include "SquirrelBindings.h"
+
+#if USE_SQUIRREL
+
static HSQUIRRELVM squirrelvm = NULL;
SQInteger runtimeErrorHandler(HSQUIRRELVM a_VM)
@@ -62,4 +65,6 @@ void CloseSquirrelVM()
void sqPrint(SQChar * text)
{
LOGINFO("%s", text);
-} \ No newline at end of file
+}
+
+#endif \ No newline at end of file