diff options
-rw-r--r-- | VC2010/MCServer.vcxproj | 1 | ||||
-rw-r--r-- | VC2010/MCServer.vcxproj.filters | 3 | ||||
-rw-r--r-- | source/cClientHandle.cpp | 17 | ||||
-rw-r--r-- | source/cPawn.cpp | 16 | ||||
-rw-r--r-- | source/cPawn.h | 14 | ||||
-rw-r--r-- | source/cPlayer.cpp | 132 | ||||
-rw-r--r-- | source/cPlayer.h | 20 | ||||
-rw-r--r-- | source/items/Item.cpp | 55 | ||||
-rw-r--r-- | source/items/Item.h | 19 | ||||
-rw-r--r-- | source/items/ItemFood.h | 55 | ||||
-rw-r--r-- | source/squirrelbindings/SquirrelBindings.cpp | 14 | ||||
-rw-r--r-- | source/squirrelbindings/SquirrelBindings.h | 2 | ||||
-rw-r--r-- | source/squirrelbindings/SquirrelFunctions.cpp | 7 |
13 files changed, 212 insertions, 143 deletions
diff --git a/VC2010/MCServer.vcxproj b/VC2010/MCServer.vcxproj index 1bbf7617c..e085d6a32 100644 --- a/VC2010/MCServer.vcxproj +++ b/VC2010/MCServer.vcxproj @@ -638,6 +638,7 @@ <ClInclude Include="..\source\items\Item.h" />
<ClInclude Include="..\source\items\ItemDoor.h" />
<ClInclude Include="..\source\items\ItemDye.h" />
+ <ClInclude Include="..\source\items\ItemFood.h" />
<ClInclude Include="..\source\items\ItemHoe.h" />
<ClInclude Include="..\source\items\ItemLeaves.h" />
<ClInclude Include="..\source\items\ItemLighter.h" />
diff --git a/VC2010/MCServer.vcxproj.filters b/VC2010/MCServer.vcxproj.filters index b93c2a334..38014365c 100644 --- a/VC2010/MCServer.vcxproj.filters +++ b/VC2010/MCServer.vcxproj.filters @@ -1640,6 +1640,9 @@ <ClInclude Include="..\source\items\ItemRedstoneRepeater.h">
<Filter>Items</Filter>
</ClInclude>
+ <ClInclude Include="..\source\items\ItemFood.h">
+ <Filter>Items</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\source\AllToLua.pkg">
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 |