From 8f7b9acb488a2dc4a9c34de499a3cd0e0829ef40 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 12:10:21 +0100 Subject: Fixed forgotten error checking --- src/CraftingRecipes.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 1a31a6e90..085b6e0d5 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -324,7 +324,11 @@ void cCraftingRecipes::LoadRecipes(void) return; } AString Everything; - f.ReadRestOfFile(Everything); + if (!f.ReadRestOfFile(Everything)) + { + LOGWARNING("Cannot read file \"crafting.txt\", no crafting recipes will be available!"); + return; + } f.Close(); // Split it into lines, then process each line as a single recipe: -- cgit v1.2.3 From c3c3d3a72d7517863f015364e62ca0dff46a6807 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 12:14:55 +0100 Subject: Fixed type issues in CraftingRecipe.cpp --- src/CraftingRecipes.cpp | 4 ++-- src/CraftingRecipes.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 085b6e0d5..48178eecb 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -83,7 +83,7 @@ cItem & cCraftingGrid::GetItem(int x, int y) const -void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) +void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) { // Accessible through scripting, must verify parameters: if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) @@ -228,7 +228,7 @@ void cCraftingRecipe::Clear(void) -void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) +void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) { m_Result = cItem(a_ItemType, a_ItemCount, a_ItemHealth); } diff --git a/src/CraftingRecipes.h b/src/CraftingRecipes.h index 0250d2f68..fe1e15817 100644 --- a/src/CraftingRecipes.h +++ b/src/CraftingRecipes.h @@ -33,7 +33,7 @@ public: int GetWidth (void) const {return m_Width; } int GetHeight(void) const {return m_Height; } cItem & GetItem (int x, int y) const; - void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth); + void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth); void SetItem (int x, int y, const cItem & a_Item); void Clear (void); @@ -72,13 +72,13 @@ public: int GetIngredientsHeight(void) const {return m_Ingredients.GetHeight(); } cItem & GetIngredient (int x, int y) const {return m_Ingredients.GetItem(x, y); } const cItem & GetResult (void) const {return m_Result; } - void SetResult (ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth); + void SetResult (ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth); void SetResult (const cItem & a_Item) { m_Result = a_Item; } - void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, int a_ItemCount, short a_ItemHealth) + void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) { m_Ingredients.SetItem(x, y, a_ItemType, a_ItemCount, a_ItemHealth); } -- cgit v1.2.3 From 781e1e6264794ec0fddccd37a76f7a78a3fa8b09 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 13:03:56 +0100 Subject: Fixed Integer pasing warnings in CraftingRecipies.cpp --- src/CraftingRecipes.cpp | 6 ++--- src/StringUtils.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 48178eecb..2d80ecaf8 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -392,8 +392,7 @@ void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine } if (ResultSplit.size() > 1) { - Recipe->m_Result.m_ItemCount = atoi(ResultSplit[1].c_str()); - if (Recipe->m_Result.m_ItemCount == 0) + if (!StringToInteger(ResultSplit[1].c_str(), Recipe->m_Result.m_ItemCount)) { LOGWARNING("crafting.txt: line %d: Cannot parse result count, ignoring the recipe.", a_LineNum); LOGINFO("Offending line: \"%s\"", a_RecipeLine.c_str()); @@ -445,8 +444,7 @@ bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item) if (Split.size() > 1) { AString Damage = TrimString(Split[1]); - a_Item.m_ItemDamage = atoi(Damage.c_str()); - if ((a_Item.m_ItemDamage == 0) && (Damage.compare("0") != 0)) + if (!StringToInteger(Damage.c_str(), a_Item.m_ItemDamage)) { // Parsing the number failed return false; diff --git a/src/StringUtils.h b/src/StringUtils.h index 142aaf59b..56ac83942 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -99,6 +99,68 @@ extern int GetBEInt(const char * a_Mem); /// Writes four bytes to the specified memory location so that they interpret as BigEndian int extern void SetBEInt(char * a_Mem, Int32 a_Value); +/// Parses any integer type. Checks bounds and +template +bool StringToInteger(AString a_str, T& a_Num) +{ + size_t i = 0; + T positive = true; + T result = 0; + if (a_str[0] == '+') + { + i++; + } + else if (a_str[0] == '-') + { + i++; + positive = false; + } + if (positive) + { + for(; i <= a_str.size(); i++) + { + if ((a_str[i] <= '0') || (a_str[i] >= '9')) + { + return false; + } + if (std::numeric_limits::max() / 10 < result) + { + return false; + } + result *= 10; + T digit = a_str[i] - '0'; + if (std::numeric_limits::max() - digit < result) + { + return false; + } + result += digit; + } + } + else + { + for(; i <= a_str.size(); i++) + { + if ((a_str[i] <= '0') || (a_str[i] >= '9')) + { + return false; + } + if (std::numeric_limits::min() / 10 > result) + { + return false; + } + result *= 10; + T digit = a_str[i] - '0'; + if (std::numeric_limits::min() + digit > result) + { + return false; + } + result -= digit; + } + } + a_Num = result; + return true; +} + // If you have any other string helper functions, declare them here -- cgit v1.2.3 From fecd607d7496d77a488757871a5abe60f789572b Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 13:15:29 +0100 Subject: Added missing header --- src/StringUtils.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/StringUtils.h b/src/StringUtils.h index 56ac83942..30a193845 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -9,6 +9,7 @@ #pragma once #include +#include -- cgit v1.2.3 From f4d268636a02346acc46c993666fe02bbc1ff0b8 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 13 Aug 2014 13:37:07 +0100 Subject: Fixed comments --- src/StringUtils.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/StringUtils.h b/src/StringUtils.h index 30a193845..a78f8b0bf 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -100,12 +100,12 @@ extern int GetBEInt(const char * a_Mem); /// Writes four bytes to the specified memory location so that they interpret as BigEndian int extern void SetBEInt(char * a_Mem, Int32 a_Value); -/// Parses any integer type. Checks bounds and +/// Parses any integer type. Checks bounds and returns errors out of band. template -bool StringToInteger(AString a_str, T& a_Num) +bool StringToInteger(const AString& a_str, T& a_Num) { size_t i = 0; - T positive = true; + bool positive = true; T result = 0; if (a_str[0] == '+') { @@ -118,7 +118,7 @@ bool StringToInteger(AString a_str, T& a_Num) } if (positive) { - for(; i <= a_str.size(); i++) + for(size_t size = a_str.size(); i < size; i++) { if ((a_str[i] <= '0') || (a_str[i] >= '9')) { @@ -139,7 +139,7 @@ bool StringToInteger(AString a_str, T& a_Num) } else { - for(; i <= a_str.size(); i++) + for(size_t size = a_str.size(); i < size; i++) { if ((a_str[i] <= '0') || (a_str[i] >= '9')) { -- cgit v1.2.3 From a544c0238ba4c94d78692a7592107f8e510893ee Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Wed, 13 Aug 2014 18:53:23 +0200 Subject: Implement ability to push minecarts on curved rails --- src/Entities/Minecart.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index d4eadc5d5..19eaa207f 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -871,11 +871,79 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) return true; } case E_META_RAIL_CURVED_ZM_XM: + case E_META_RAIL_CURVED_ZP_XP: + { + Vector3d Distance( + MinecartCollisionCallback.GetCollidedEntityPosition().x - GetPosX(), + 0, + MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() + ); + + if ( Distance.z == 0. ) Distance.z = 0.0001; + if ( ((Distance.z>=0)&&((Distance.x/Distance.z)>=1)) || ((Distance.z<0)&&((Distance.x/Distance.z)<=1)) ) + { + if ( (-GetSpeedX() * 0.4) < 0.01 ) + { + AddSpeedX( -4/sqrt(2) ); + AddSpeedZ( 4/sqrt(2) ); + } + else + { + SetSpeedX( -GetSpeedX() * 0.4 ); + SetSpeedZ( GetSpeedZ() * 0.4 ); + } + } + else + { + if ((GetSpeedX() * 0.4) < 0.01) + { + AddSpeedX( 4/sqrt(2) ); + AddSpeedZ( -4/sqrt(2) ); + } + else + { + SetSpeedX( GetSpeedX() * 0.4 ); + SetSpeedZ( -GetSpeedZ() * 0.4 ); + } + } + break; + } case E_META_RAIL_CURVED_ZM_XP: case E_META_RAIL_CURVED_ZP_XM: - case E_META_RAIL_CURVED_ZP_XP: { - // TODO - simply can't be bothered right now + Vector3d Distance( + MinecartCollisionCallback.GetCollidedEntityPosition().x - GetPosX(), + 0, + MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() + ); + + if ( Distance.z == 0. ) Distance.z = 0.0001; + if ( ((Distance.z>=0)&&((Distance.x/Distance.z)<=-1)) || ((Distance.z<0)&&((Distance.x/Distance.z)>=-1)) ) + { + if ( (GetSpeedX() * 0.4) < 0.01 ) + { + AddSpeedX( 4/sqrt(2) ); + AddSpeedZ( 4/sqrt(2) ); + } + else + { + SetSpeedX( GetSpeedX() * 0.4 ); + SetSpeedZ( GetSpeedZ() * 0.4 ); + } + } + else + { + if ((-GetSpeedX() * 0.4) < 0.01) + { + AddSpeedX( -4/sqrt(2) ); + AddSpeedZ( -4/sqrt(2) ); + } + else + { + SetSpeedX( -GetSpeedX() * 0.4 ); + SetSpeedZ( -GetSpeedZ() * 0.4 ); + } + } break; } default: break; -- cgit v1.2.3 From 3698c5c8295e6a6a0f37b17f3c04bb118cc58bf6 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Wed, 13 Aug 2014 19:16:00 +0200 Subject: Fixed braces and intendation errors --- src/Entities/Minecart.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 19eaa207f..5cf56d3d2 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -879,8 +879,12 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() ); - if ( Distance.z == 0. ) Distance.z = 0.0001; - if ( ((Distance.z>=0)&&((Distance.x/Distance.z)>=1)) || ((Distance.z<0)&&((Distance.x/Distance.z)<=1)) ) + if ( Distance.z == 0. ) + { + Distance.z = 0.0001; + } + + if ( ((Distance.z>=0)&&((Distance.x/Distance.z)>=1)) || ((Distance.z<0)&&((Distance.x/Distance.z)<=1)) ) { if ( (-GetSpeedX() * 0.4) < 0.01 ) { @@ -917,7 +921,11 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() ); - if ( Distance.z == 0. ) Distance.z = 0.0001; + if ( Distance.z == 0. ) + { + Distance.z = 0.0001; + } + if ( ((Distance.z>=0)&&((Distance.x/Distance.z)<=-1)) || ((Distance.z<0)&&((Distance.x/Distance.z)>=-1)) ) { if ( (GetSpeedX() * 0.4) < 0.01 ) -- cgit v1.2.3 From 3f117897fbda4eec95ad5cdd728f197840dd7224 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Wed, 13 Aug 2014 19:18:11 +0200 Subject: Another intendation error --- src/Entities/Minecart.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 5cf56d3d2..cd5e2adaa 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -881,9 +881,9 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) if ( Distance.z == 0. ) { - Distance.z = 0.0001; + Distance.z = 0.0001; } - + if ( ((Distance.z>=0)&&((Distance.x/Distance.z)>=1)) || ((Distance.z<0)&&((Distance.x/Distance.z)<=1)) ) { if ( (-GetSpeedX() * 0.4) < 0.01 ) -- cgit v1.2.3 From 2d2d4ff33b74eefe053cce4d9a5daada65ed496b Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Wed, 13 Aug 2014 19:47:43 +0200 Subject: Further fixing of coding style errors --- src/Entities/Minecart.cpp | 48 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index cd5e2adaa..45b9782f3 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -879,14 +879,15 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() ); - if ( Distance.z == 0. ) + if (Distance.z == 0.) { Distance.z = 0.0001; } - if ( ((Distance.z>=0)&&((Distance.x/Distance.z)>=1)) || ((Distance.z<0)&&((Distance.x/Distance.z)<=1)) ) + if (((Distance.z >= 0) && ((Distance.x / Distance.z) >= 1)) || + ((Distance.z<0) && ((Distance.x / Distance.z) <= 1))) { - if ( (-GetSpeedX() * 0.4) < 0.01 ) + if ((-GetSpeedX() * 0.4) < 0.01) { AddSpeedX( -4/sqrt(2) ); AddSpeedZ( 4/sqrt(2) ); @@ -897,18 +898,15 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) SetSpeedZ( GetSpeedZ() * 0.4 ); } } + else if ((GetSpeedX() * 0.4) < 0.01) + { + AddSpeedX( 4/sqrt(2) ); + AddSpeedZ( -4/sqrt(2) ); + } else { - if ((GetSpeedX() * 0.4) < 0.01) - { - AddSpeedX( 4/sqrt(2) ); - AddSpeedZ( -4/sqrt(2) ); - } - else - { - SetSpeedX( GetSpeedX() * 0.4 ); - SetSpeedZ( -GetSpeedZ() * 0.4 ); - } + SetSpeedX( GetSpeedX() * 0.4 ); + SetSpeedZ( -GetSpeedZ() * 0.4 ); } break; } @@ -921,14 +919,15 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() ); - if ( Distance.z == 0. ) + if (Distance.z == 0.) { Distance.z = 0.0001; } - if ( ((Distance.z>=0)&&((Distance.x/Distance.z)<=-1)) || ((Distance.z<0)&&((Distance.x/Distance.z)>=-1)) ) + if (((Distance.z >= 0) && ((Distance.x / Distance.z) <= -1)) || + ((Distance.z<0) && ((Distance.x / Distance.z) >= -1))) { - if ( (GetSpeedX() * 0.4) < 0.01 ) + if ((GetSpeedX() * 0.4) < 0.01) { AddSpeedX( 4/sqrt(2) ); AddSpeedZ( 4/sqrt(2) ); @@ -939,18 +938,15 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) SetSpeedZ( GetSpeedZ() * 0.4 ); } } + else if ((-GetSpeedX() * 0.4) < 0.01) + { + AddSpeedX( -4/sqrt(2) ); + AddSpeedZ( -4/sqrt(2) ); + } else { - if ((-GetSpeedX() * 0.4) < 0.01) - { - AddSpeedX( -4/sqrt(2) ); - AddSpeedZ( -4/sqrt(2) ); - } - else - { - SetSpeedX( -GetSpeedX() * 0.4 ); - SetSpeedZ( -GetSpeedZ() * 0.4 ); - } + SetSpeedX( -GetSpeedX() * 0.4 ); + SetSpeedZ( -GetSpeedZ() * 0.4 ); } break; } -- cgit v1.2.3 From e3a74f379fc103f40e6bf85e626d7bac7db236af Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Thu, 14 Aug 2014 14:29:46 +0200 Subject: Further changes in coding style --- src/Entities/Minecart.cpp | 66 ++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 45b9782f3..8e11d8a07 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -873,80 +873,70 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) case E_META_RAIL_CURVED_ZM_XM: case E_META_RAIL_CURVED_ZP_XP: { - Vector3d Distance( - MinecartCollisionCallback.GetCollidedEntityPosition().x - GetPosX(), - 0, - MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() - ); + Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); - if (Distance.z == 0.) - { - Distance.z = 0.0001; - } + Distance.z = std::max(Distance.z, 0.001); - if (((Distance.z >= 0) && ((Distance.x / Distance.z) >= 1)) || - ((Distance.z<0) && ((Distance.x / Distance.z) <= 1))) + if ( + ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || + ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) + ) { if ((-GetSpeedX() * 0.4) < 0.01) { - AddSpeedX( -4/sqrt(2) ); - AddSpeedZ( 4/sqrt(2) ); + AddSpeedX(-4/sqrt(2)); + AddSpeedZ(4/sqrt(2)); } else { - SetSpeedX( -GetSpeedX() * 0.4 ); - SetSpeedZ( GetSpeedZ() * 0.4 ); + SetSpeedX(-GetSpeedX() * 0.4); + SetSpeedZ(GetSpeedZ() * 0.4); } } else if ((GetSpeedX() * 0.4) < 0.01) { - AddSpeedX( 4/sqrt(2) ); - AddSpeedZ( -4/sqrt(2) ); + AddSpeedX(4/sqrt(2)); + AddSpeedZ(-4/sqrt(2)); } else { - SetSpeedX( GetSpeedX() * 0.4 ); - SetSpeedZ( -GetSpeedZ() * 0.4 ); + SetSpeedX(GetSpeedX() * 0.4); + SetSpeedZ(-GetSpeedZ() * 0.4); } break; } case E_META_RAIL_CURVED_ZM_XP: case E_META_RAIL_CURVED_ZP_XM: { - Vector3d Distance( - MinecartCollisionCallback.GetCollidedEntityPosition().x - GetPosX(), - 0, - MinecartCollisionCallback.GetCollidedEntityPosition().z - GetPosZ() - ); + Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); - if (Distance.z == 0.) - { - Distance.z = 0.0001; - } + Distance.z = std::max(Distance.z, 0.001); - if (((Distance.z >= 0) && ((Distance.x / Distance.z) <= -1)) || - ((Distance.z<0) && ((Distance.x / Distance.z) >= -1))) + if ( + ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || + ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) + ) { if ((GetSpeedX() * 0.4) < 0.01) { - AddSpeedX( 4/sqrt(2) ); - AddSpeedZ( 4/sqrt(2) ); + AddSpeedX(4/sqrt(2)); + AddSpeedZ(4/sqrt(2)); } else { - SetSpeedX( GetSpeedX() * 0.4 ); - SetSpeedZ( GetSpeedZ() * 0.4 ); + SetSpeedX(GetSpeedX() * 0.4); + SetSpeedZ(GetSpeedZ() * 0.4); } } else if ((-GetSpeedX() * 0.4) < 0.01) { - AddSpeedX( -4/sqrt(2) ); - AddSpeedZ( -4/sqrt(2) ); + AddSpeedX(-4/sqrt(2)); + AddSpeedZ(-4/sqrt(2)); } else { - SetSpeedX( -GetSpeedX() * 0.4 ); - SetSpeedZ( -GetSpeedZ() * 0.4 ); + SetSpeedX(-GetSpeedX() * 0.4); + SetSpeedZ(-GetSpeedZ() * 0.4); } break; } -- cgit v1.2.3 From 0f631febfc3f670e8e9eb60ec4f89659ad7d0c71 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Fri, 15 Aug 2014 13:40:56 +0200 Subject: Add some comments --- src/Entities/Minecart.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 8e11d8a07..0455c9ab3 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -875,17 +875,23 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) { Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); + // Prevent division by small numbers Distance.z = std::max(Distance.z, 0.001); + /* Check to which side the minecart is to be pushed. + Let's consider a z-x-coordinate system where the minecart is the center (0/0). + The minecart moves along the line z = -x, the perpendicular line to this is z = x. + In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. + */ if ( ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) ) { - if ((-GetSpeedX() * 0.4) < 0.01) + if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) { - AddSpeedX(-4/sqrt(2)); - AddSpeedZ(4/sqrt(2)); + AddSpeedX(-4 / sqrt(2)); + AddSpeedZ(4 / sqrt(2)); } else { @@ -893,10 +899,10 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) SetSpeedZ(GetSpeedZ() * 0.4); } } - else if ((GetSpeedX() * 0.4) < 0.01) + else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) { - AddSpeedX(4/sqrt(2)); - AddSpeedZ(-4/sqrt(2)); + AddSpeedX(4 / sqrt(2)); + AddSpeedZ(-4 / sqrt(2)); } else { @@ -910,8 +916,13 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) { Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); + // Prevent division by small numbers Distance.z = std::max(Distance.z, 0.001); + /* Check to which side the minecart is to be pushed. + Let's consider a z-x-coordinate system where the minecart is the center (0/0). + The minecart moves along the line z = x, the perpendicular line to this is z = -x. + In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ if ( ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) @@ -919,8 +930,8 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) { if ((GetSpeedX() * 0.4) < 0.01) { - AddSpeedX(4/sqrt(2)); - AddSpeedZ(4/sqrt(2)); + AddSpeedX(4 / sqrt(2)); + AddSpeedZ(4 / sqrt(2)); } else { @@ -930,8 +941,8 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) } else if ((-GetSpeedX() * 0.4) < 0.01) { - AddSpeedX(-4/sqrt(2)); - AddSpeedZ(-4/sqrt(2)); + AddSpeedX(-4 / sqrt(2)); + AddSpeedZ(-4 / sqrt(2)); } else { -- cgit v1.2.3 From be03b84048a49e04db11aa6ce80b3d18fff313b1 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Fri, 15 Aug 2014 13:43:45 +0200 Subject: End of comment moved away from new line --- src/Entities/Minecart.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 0455c9ab3..f190d972e 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -881,8 +881,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) /* Check to which side the minecart is to be pushed. Let's consider a z-x-coordinate system where the minecart is the center (0/0). The minecart moves along the line z = -x, the perpendicular line to this is z = x. - In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. - */ + In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ if ( ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) -- cgit v1.2.3 From c473d8cfb82009411f5a3977b7041ee49ba08003 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Fri, 15 Aug 2014 14:00:51 +0200 Subject: Clarify comment message --- src/Entities/Minecart.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index f190d972e..4753f720d 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -880,7 +880,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) /* Check to which side the minecart is to be pushed. Let's consider a z-x-coordinate system where the minecart is the center (0/0). - The minecart moves along the line z = -x, the perpendicular line to this is z = x. + The minecart moves along the line x = -z, the perpendicular line to this is x = z. In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ if ( ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || @@ -920,7 +920,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) /* Check to which side the minecart is to be pushed. Let's consider a z-x-coordinate system where the minecart is the center (0/0). - The minecart moves along the line z = x, the perpendicular line to this is z = -x. + The minecart moves along the line x = z, the perpendicular line to this is x = -z. In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ if ( ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || -- cgit v1.2.3 From 72c02ceb171949acd07338e77c8ee0d3439f8173 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Fri, 15 Aug 2014 17:54:43 +0200 Subject: Added a lot of comments --- src/Entities/Minecart.cpp | 66 ++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 4753f720d..9420eca02 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -876,7 +876,10 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); // Prevent division by small numbers - Distance.z = std::max(Distance.z, 0.001); + if (abs(Distance.z) < 0.001) + { + Distance.z = 0.001; + } /* Check to which side the minecart is to be pushed. Let's consider a z-x-coordinate system where the minecart is the center (0/0). @@ -886,27 +889,27 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) ) - { - if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) - { + { // Moving -X + Z + if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) // ~ speedX >= 0 + { // Immobile or not moving in the "right" direction. Give it a bump! AddSpeedX(-4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } - else - { - SetSpeedX(-GetSpeedX() * 0.4); - SetSpeedZ(GetSpeedZ() * 0.4); + else // ~ SpeedX < 0 + { // Moving in the "right" direction. Only accelerate it a bit. + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } - } - else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) - { + } // Moving +X -Z + else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) // ~ SpeedX <= 0 + { // Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } - else - { - SetSpeedX(GetSpeedX() * 0.4); - SetSpeedZ(-GetSpeedZ() * 0.4); + else // ~ SpeedX > 0 + { // Moving in the "right" direction + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } break; } @@ -916,37 +919,40 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); // Prevent division by small numbers - Distance.z = std::max(Distance.z, 0.001); + if (abs(Distance.z) < 0.001) + { + Distance.z = 0.001; + } /* Check to which side the minecart is to be pushed. Let's consider a z-x-coordinate system where the minecart is the center (0/0). The minecart moves along the line x = z, the perpendicular line to this is x = -z. In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ - if ( + if ( // Moving +X +Z ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) ) { - if ((GetSpeedX() * 0.4) < 0.01) - { + if ((GetSpeedX() * 0.4) < 0.01) // ~ SpeedX <= 0 + { // Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } - else - { - SetSpeedX(GetSpeedX() * 0.4); - SetSpeedZ(GetSpeedZ() * 0.4); + else // SpeedX > 0 + { // Moving in the "right" direction + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } - } - else if ((-GetSpeedX() * 0.4) < 0.01) - { + } // Moving -X -Z + else if ((-GetSpeedX() * 0.4) < 0.01) // ~ SpeedX >= 0 + { // Immobile or not moving in the "right" direction AddSpeedX(-4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } - else - { - SetSpeedX(-GetSpeedX() * 0.4); - SetSpeedZ(-GetSpeedZ() * 0.4); + else // ~ SpeedX < 0 + { // Moving in the "right" direction + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } break; } -- cgit v1.2.3 From c70886a7124e5940b67cb4f1b4593f103f2707d8 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Mon, 18 Aug 2014 01:57:44 +0200 Subject: Adjust comment formatting --- src/Entities/Minecart.cpp | 60 +++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 9420eca02..13469edb3 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -889,25 +889,35 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) ) - { // Moving -X + Z - if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) // ~ speedX >= 0 - { // Immobile or not moving in the "right" direction. Give it a bump! + // Moving -X +Z + { + if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) + // ~ speedX >= 0 + { + // Immobile or not moving in the "right" direction. Give it a bump! AddSpeedX(-4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } - else // ~ SpeedX < 0 - { // Moving in the "right" direction. Only accelerate it a bit. + else + // ~ SpeedX < 0 + { + // Moving in the "right" direction. Only accelerate it a bit. SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } - } // Moving +X -Z - else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) // ~ SpeedX <= 0 - { // Immobile or not moving in the "right" direction + } + else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) + // Moving +X -Z + // ~ SpeedX <= 0 + { + // Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } - else // ~ SpeedX > 0 - { // Moving in the "right" direction + else + // ~ SpeedX > 0 + { + // Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } @@ -928,29 +938,39 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) Let's consider a z-x-coordinate system where the minecart is the center (0/0). The minecart moves along the line x = z, the perpendicular line to this is x = -z. In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ - if ( // Moving +X +Z + if ( ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) ) + // Moving +X +Z { - if ((GetSpeedX() * 0.4) < 0.01) // ~ SpeedX <= 0 - { // Immobile or not moving in the "right" direction + if ((GetSpeedX() * 0.4) < 0.01) + // ~ SpeedX <= 0 + { + // Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } - else // SpeedX > 0 - { // Moving in the "right" direction + else + // SpeedX > 0 + { + // Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } - } // Moving -X -Z - else if ((-GetSpeedX() * 0.4) < 0.01) // ~ SpeedX >= 0 - { // Immobile or not moving in the "right" direction + } + else if ((-GetSpeedX() * 0.4) < 0.01) + // Moving -X -Z + // ~ SpeedX >= 0 + { + // Immobile or not moving in the "right" direction AddSpeedX(-4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } - else // ~ SpeedX < 0 - { // Moving in the "right" direction + else + // ~ SpeedX < 0 + { + // Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } -- cgit v1.2.3 From d3fd63c9eb5f783da0186efcef81a5b0eb9338d6 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Tue, 19 Aug 2014 12:38:15 +0200 Subject: Added some Enchantments - Bow enchantments: Infinity, Flame and Power - Sword and tools enchantments: Fire Aspect, Bane of Arthropods, Smite, Sharpness --- src/Entities/ArrowEntity.cpp | 26 ++++++++++++++++--- src/Entities/ArrowEntity.h | 7 +++-- src/Entities/Entity.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++- src/Items/ItemBow.h | 12 ++++++++- 4 files changed, 100 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 913519c4c..c4fd378fb 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -18,6 +18,7 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a m_HitGroundTimer(0), m_HasTeleported(false), m_bIsCollected(false), + m_Creator(a_Creator), m_HitBlockPos(Vector3i(0, 0, 0)) { SetSpeed(a_Speed); @@ -43,6 +44,7 @@ cArrowEntity::cArrowEntity(cPlayer & a_Player, double a_Force) : m_HitGroundTimer(0), m_HasTeleported(false), m_bIsCollected(false), + m_Creator(&a_Player), m_HitBlockPos(0, 0, 0) { if (a_Player.IsGameModeCreative()) @@ -68,9 +70,6 @@ bool cArrowEntity::CanPickup(const cPlayer & a_Player) const } - - - void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) { if (GetSpeed().EqualsEps(Vector3d(0, 0, 0), 0.0000001)) @@ -90,6 +89,13 @@ void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFa // Broadcast arrow hit sound m_World->BroadcastSoundEffect("random.bowhit", (double)X, (double)Y, (double)Z, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); + + if ((m_World->GetBlock(Hit) == E_BLOCK_TNT) && (m_TicksLeftBurning > 0)) + { + m_World->SetBlock(X, Y, Z, E_BLOCK_AIR, 0); + m_World->SpawnPrimedTNT(X, Y, Z); + } + } @@ -103,8 +109,22 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) { Damage += m_World->GetTickRandomNumber(Damage / 2 + 2); } + LOGD("Arrow hit an entity"); + + int PowerLevel = m_Creator->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPower); + if (PowerLevel > 0) + { + LOGD("Arrow hit an entity 2"); + int ExtraDamage = 0.25 * (PowerLevel + 1); + Damage += ceil(ExtraDamage); + } a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 1); + if (m_TicksLeftBurning > 0) + { + a_EntityHit.StartBurning(100); + } + // Broadcast successful hit sound GetWorld()->BroadcastSoundEffect("random.successful_hit", GetPosX(), GetPosY(), GetPosZ(), 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h index 4bfcb1f6d..2ea6e9fde 100644 --- a/src/Entities/ArrowEntity.h +++ b/src/Entities/ArrowEntity.h @@ -10,6 +10,7 @@ + // tolua_begin class cArrowEntity : @@ -46,7 +47,7 @@ public: /// Returns the damage modifier coeff. double GetDamageCoeff(void) const { return m_DamageCoeff; } - + /// Sets the damage modifier coeff void SetDamageCoeff(double a_DamageCoeff) { m_DamageCoeff = a_DamageCoeff; } @@ -89,7 +90,9 @@ protected: /// If true, the arrow is in the process of being collected - don't go to anyone else bool m_bIsCollected; - + + cEntity * m_Creator; + /// Stores the block position that arrow is lodged into, sets m_IsInGround to false if it becomes air Vector3i m_HitBlockPos; diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 32f220897..398f7703b 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -316,8 +316,68 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) // IsOnGround() only is false if the player is moving downwards // TODO: Better damage increase, and check for enchantments (and use magic critical instead of plain) - if (!Player->IsOnGround()) + + cEnchantments Enchantments = Player->GetEquippedItem().m_Enchantments; + + int SharpnessLevel = Enchantments.GetLevel(cEnchantments::enchSharpness); + int SmiteLevel = Enchantments.GetLevel(cEnchantments::enchSmite); + int BaneOfArthropodsLevel = Enchantments.GetLevel(cEnchantments::enchBaneOfArthropods); + + if (SharpnessLevel > 0) + { + a_TDI.RawDamage += 1.25 * SharpnessLevel; + } + else if (SmiteLevel > 0) + { + if (IsMob()) + { + cMonster * Monster = (cMonster *)this; + switch (Monster->GetMobType()) + { + case cMonster::mtSkeleton: + case cMonster::mtZombie: + case cMonster::mtWither: + case cMonster::mtZombiePigman: + { + a_TDI.RawDamage += 2.5 * SmiteLevel; + break; + } + } + } + } + else if (BaneOfArthropodsLevel > 0) + { + if (IsMob()) + { + cMonster * Monster = (cMonster *)this; + switch (Monster->GetMobType()) + { + case cMonster::mtSpider: + case cMonster::mtCaveSpider: + case cMonster::mtSilverfish: + { + a_TDI.RawDamage += 2.5 * BaneOfArthropodsLevel; + break; + } + } + } + } + + int FireAspectLevel = Enchantments.GetLevel(cEnchantments::enchFireAspect); + if (FireAspectLevel > 0) { + int BurnTicks = 3; + + if (FireAspectLevel > 1) + { + BurnTicks += 4 * (FireAspectLevel - 1); + } + + StartBurning(BurnTicks * 20); + } + + if (!Player->IsOnGround()) + { if ((a_TDI.DamageType == dtAttack) || (a_TDI.DamageType == dtArrowAttack)) { a_TDI.FinalDamage += 2; diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index fdc24689c..0fc0f0920 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -75,7 +75,6 @@ public: Arrow = NULL; return; } - a_Player->GetWorld()->BroadcastSoundEffect("random.bow", a_Player->GetPosX(), a_Player->GetPosY(), a_Player->GetPosZ(), 0.5, (float)Force); if (!a_Player->IsGameModeCreative()) { @@ -83,8 +82,19 @@ public: { a_Player->GetInventory().RemoveItem(cItem(E_ITEM_ARROW)); } + else + { + Arrow->SetPickupState(cArrowEntity::ePickupState::psNoPickup); + } + + a_Player->UseEquippedItem(); } + + if (a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchFlame) > 0) + { + Arrow->StartBurning(100); + } } } ; -- cgit v1.2.3 From 1897f678f93bb038fdc4caf1fb2995a28ef8f92e Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Tue, 19 Aug 2014 16:08:17 +0200 Subject: Added more enchantments and some fixes - Removed Debug messages - Added Punch enchantment effect - Added Silk Touch enchantment - Added Unbreaking enchantment effect --- src/Blocks/BlockHandler.cpp | 32 ++++++++++++++++++++++++++++---- src/Blocks/BlockIce.h | 24 ++++++++++++------------ src/Entities/ArrowEntity.cpp | 22 ++++++++++++++++++---- src/Entities/ArrowEntity.h | 1 + src/Entities/Entity.cpp | 25 ++++++++++++++++++++++--- src/Entities/Player.cpp | 20 ++++++++++++++++++++ 6 files changed, 101 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 52f7dd608..3c85a31e0 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -424,19 +424,43 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac cItems Pickups; NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (a_CanDrop) + // Thanks to daniel0916 + cPlayer * Player = (cPlayer *)a_Digger; + cEnchantments Enchantments = Player->GetInventory().GetEquippedItem().m_Enchantments; + if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) { - if (!a_DropVerbatim) + BLOCKTYPE Type = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); + if (Type == E_BLOCK_CAKE || Type == E_BLOCK_CARROTS || Type == E_BLOCK_COCOA_POD || Type == E_BLOCK_DOUBLE_STONE_SLAB || + Type == E_BLOCK_DOUBLE_WOODEN_SLAB || Type == E_BLOCK_FIRE || Type == E_BLOCK_FARMLAND || Type == E_BLOCK_MELON_STEM || + Type == E_BLOCK_MOB_SPAWNER || Type == E_BLOCK_NETHER_WART || Type == E_BLOCK_POTATOES || Type == E_BLOCK_PUMPKIN_STEM || + Type == E_BLOCK_SNOW || Type == E_BLOCK_SUGARCANE || Type == E_BLOCK_TALL_GRASS || Type == E_BLOCK_CROPS + ) { + // Silktouch can't be used for this blocks ConvertToPickups(Pickups, Meta); } else { - // TODO: Add a proper overridable function for this Pickups.Add(m_BlockType, 1, Meta); } } - + else + { + if (a_CanDrop) + { + if (!a_DropVerbatim) + { + ConvertToPickups(Pickups, Meta); + } + else + { + // TODO: Add a proper overridable function for this + Pickups.Add(m_BlockType, 1, Meta); + } + } + + } + // Allow plugins to modify the pickups: a_BlockPluginInterface.CallHookBlockToPickups(a_Digger, a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta, Pickups); diff --git a/src/Blocks/BlockIce.h b/src/Blocks/BlockIce.h index c38630fe3..cfe1d179f 100644 --- a/src/Blocks/BlockIce.h +++ b/src/Blocks/BlockIce.h @@ -30,18 +30,18 @@ public: { return; } - - BLOCKTYPE BlockBelow = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); - if (!cBlockInfo::FullyOccupiesVoxel(BlockBelow) && !IsBlockLiquid(BlockBelow)) + + cEnchantments Enchantments = a_Player->GetInventory().GetEquippedItem().m_Enchantments; + if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) == 0) { - return; + BLOCKTYPE BlockBelow = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); + if (!cBlockInfo::FullyOccupiesVoxel(BlockBelow) && !IsBlockLiquid(BlockBelow)) + { + return; + } + + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WATER, 0); + // This is called later than the real destroying of this ice block } - - a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WATER, 0); - // This is called later than the real destroying of this ice block } -} ; - - - - +} ; \ No newline at end of file diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index c4fd378fb..e71f30a66 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -109,18 +109,32 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) { Damage += m_World->GetTickRandomNumber(Damage / 2 + 2); } - LOGD("Arrow hit an entity"); int PowerLevel = m_Creator->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPower); if (PowerLevel > 0) { - LOGD("Arrow hit an entity 2"); int ExtraDamage = 0.25 * (PowerLevel + 1); Damage += ceil(ExtraDamage); } - a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 1); + + int KnockbackAmount = 1; + int PunchLevel = m_Creator->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPunch); + if (PunchLevel > 0) + { + Vector3f LookVector = m_Creator->GetLookVector(); + Vector3f FinalSpeed = Vector3f(0, 0, 0); + switch (PunchLevel) + { + case 1: FinalSpeed = LookVector * Vector3d(5, 0.3, 5); + case 2: FinalSpeed = LookVector * Vector3d(8, 0.3, 8); + default: break; + } + a_EntityHit.SetSpeed(FinalSpeed); + } + + a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount); - if (m_TicksLeftBurning > 0) + if ((m_TicksLeftBurning > 0 && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming())) { a_EntityHit.StartBurning(100); } diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h index 2ea6e9fde..553bcb6e7 100644 --- a/src/Entities/ArrowEntity.h +++ b/src/Entities/ArrowEntity.h @@ -91,6 +91,7 @@ protected: /// If true, the arrow is in the process of being collected - don't go to anyone else bool m_bIsCollected; + // Stores the creator from that arrow cEntity * m_Creator; /// Stores the block position that arrow is lodged into, sets m_IsInGround to false if it becomes air diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 398f7703b..05bad3a78 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -316,7 +316,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) // IsOnGround() only is false if the player is moving downwards // TODO: Better damage increase, and check for enchantments (and use magic critical instead of plain) - + // Thanks to daniel0916 cEnchantments Enchantments = Player->GetEquippedItem().m_Enchantments; int SharpnessLevel = Enchantments.GetLevel(cEnchantments::enchSharpness); @@ -372,8 +372,27 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) { BurnTicks += 4 * (FireAspectLevel - 1); } + if (!IsMob() && !IsSubmerged() && !IsSwimming()) + { + StartBurning(BurnTicks * 20); + } + else if (IsMob() && !IsSubmerged() && !IsSwimming()) + { + cMonster * Monster = (cMonster *)this; + switch (Monster->GetMobType()) + { + case cMonster::mtGhast: + case cMonster::mtZombiePigman: + case cMonster::mtMagmaCube: + { + + break; + }; + default:StartBurning(BurnTicks * 20); + } + } - StartBurning(BurnTicks * 20); + } if (!Player->IsOnGround()) @@ -410,7 +429,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case 2: AdditionalSpeed.Set(8, 0.3, 8); break; default: break; } - AddSpeed(a_TDI.Knockback + AdditionalSpeed); + SetSpeed(a_TDI.Knockback + AdditionalSpeed); } m_World->BroadcastEntityStatus(*this, esGenericHurt); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index ab4ff3161..c1031907d 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -17,6 +17,7 @@ #include "../Chunk.h" #include "../Items/ItemHandler.h" #include "../Vector3.h" +#include "../FastRandom.h" #include "../WorldStorage/StatSerializer.h" #include "../CompositeChat.h" @@ -1962,7 +1963,26 @@ void cPlayer::UseEquippedItem(int a_Amount) { return; } + cItem Item = GetEquippedItem(); + int UnbreakingLevel = Item.m_Enchantments.GetLevel(cEnchantments::enchUnbreaking); + if (UnbreakingLevel > 0) + { + int chance; + if (ItemCategory::IsArmor(Item.m_ItemType)) + { + chance = 60 + (40 / (UnbreakingLevel + 1)); + } + else + { + chance = 100 / (UnbreakingLevel + 1); + } + cFastRandom Random; + if (Random.NextInt(100) <= chance) + { + return; + } + } if (GetInventory().DamageEquippedItem(a_Amount)) { m_World->BroadcastSoundEffect("random.break", GetPosX(), GetPosY(), GetPosZ(), 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); -- cgit v1.2.3 From 07350de514cebd9009f5fbdb5774aa8f1266bdb3 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Tue, 19 Aug 2014 16:47:33 +0200 Subject: Changed if for switch --- src/Blocks/BlockHandler.cpp | 33 ++++++++++++++++++++++----------- src/Blocks/BlockIce.h | 2 +- src/Entities/Entity.cpp | 5 ++--- 3 files changed, 25 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 3c85a31e0..1d537b125 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -430,18 +430,29 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) { BLOCKTYPE Type = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); - if (Type == E_BLOCK_CAKE || Type == E_BLOCK_CARROTS || Type == E_BLOCK_COCOA_POD || Type == E_BLOCK_DOUBLE_STONE_SLAB || - Type == E_BLOCK_DOUBLE_WOODEN_SLAB || Type == E_BLOCK_FIRE || Type == E_BLOCK_FARMLAND || Type == E_BLOCK_MELON_STEM || - Type == E_BLOCK_MOB_SPAWNER || Type == E_BLOCK_NETHER_WART || Type == E_BLOCK_POTATOES || Type == E_BLOCK_PUMPKIN_STEM || - Type == E_BLOCK_SNOW || Type == E_BLOCK_SUGARCANE || Type == E_BLOCK_TALL_GRASS || Type == E_BLOCK_CROPS - ) + switch (Type) { - // Silktouch can't be used for this blocks - ConvertToPickups(Pickups, Meta); - } - else - { - Pickups.Add(m_BlockType, 1, Meta); + case E_BLOCK_CAKE: + case E_BLOCK_CARROTS: + case E_BLOCK_COCOA_POD: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_FIRE: + case E_BLOCK_FARMLAND: + case E_BLOCK_MELON_STEM: + case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_NETHER_WART: + case E_BLOCK_POTATOES: + case E_BLOCK_PUMPKIN_STEM: + case E_BLOCK_SNOW: + case E_BLOCK_SUGARCANE: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_CROPS: + { + // Silktouch can't be used for this blocks + ConvertToPickups(Pickups, Meta); + }; + default: Pickups.Add(m_BlockType, 1, Meta); } } else diff --git a/src/Blocks/BlockIce.h b/src/Blocks/BlockIce.h index cfe1d179f..47a84e5a7 100644 --- a/src/Blocks/BlockIce.h +++ b/src/Blocks/BlockIce.h @@ -44,4 +44,4 @@ public: // This is called later than the real destroying of this ice block } } -} ; \ No newline at end of file +} ; diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 05bad3a78..4316b48e9 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -384,11 +384,10 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtGhast: case cMonster::mtZombiePigman: case cMonster::mtMagmaCube: - { - + { break; }; - default:StartBurning(BurnTicks * 20); + default: StartBurning(BurnTicks * 20); } } -- cgit v1.2.3 From 596203e692e6322c7f989b1625cbe03dc1eb6a6c Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Tue, 19 Aug 2014 17:57:32 +0200 Subject: Fixes - Changed m_TicksLeftBurning > 0 for IsOnFire() - Tried to do the changes in BlockHandler.cpp - Removed m_Creator in ArrowEntity - Added m_Enchantments in ProjectileEntity CreatorData - Added blank lines between functions --- src/Blocks/BlockHandler.cpp | 70 +++++++++++++++++++-------------------- src/Entities/ArrowEntity.cpp | 15 +++++---- src/Entities/ArrowEntity.h | 3 -- src/Entities/ProjectileEntity.cpp | 5 +-- src/Entities/ProjectileEntity.h | 6 ++-- src/Items/ItemBow.h | 2 +- 6 files changed, 51 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 1d537b125..d6be99f83 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -427,49 +427,49 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac // Thanks to daniel0916 cPlayer * Player = (cPlayer *)a_Digger; cEnchantments Enchantments = Player->GetInventory().GetEquippedItem().m_Enchantments; - if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) - { - BLOCKTYPE Type = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); - switch (Type) - { - case E_BLOCK_CAKE: - case E_BLOCK_CARROTS: - case E_BLOCK_COCOA_POD: - case E_BLOCK_DOUBLE_STONE_SLAB: - case E_BLOCK_DOUBLE_WOODEN_SLAB: - case E_BLOCK_FIRE: - case E_BLOCK_FARMLAND: - case E_BLOCK_MELON_STEM: - case E_BLOCK_MOB_SPAWNER: - case E_BLOCK_NETHER_WART: - case E_BLOCK_POTATOES: - case E_BLOCK_PUMPKIN_STEM: - case E_BLOCK_SNOW: - case E_BLOCK_SUGARCANE: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_CROPS: - { - // Silktouch can't be used for this blocks - ConvertToPickups(Pickups, Meta); - }; - default: Pickups.Add(m_BlockType, 1, Meta); - } - } - else + + if (a_CanDrop) { - if (a_CanDrop) + if (!a_DropVerbatim) { - if (!a_DropVerbatim) + if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) { - ConvertToPickups(Pickups, Meta); + switch (m_BlockType) + { + case E_BLOCK_CAKE: + case E_BLOCK_CARROTS: + case E_BLOCK_COCOA_POD: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_FIRE: + case E_BLOCK_FARMLAND: + case E_BLOCK_MELON_STEM: + case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_NETHER_WART: + case E_BLOCK_POTATOES: + case E_BLOCK_PUMPKIN_STEM: + case E_BLOCK_SNOW: + case E_BLOCK_SUGARCANE: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_CROPS: + { + // Silktouch can't be used for this blocks + ConvertToPickups(Pickups, Meta); + break; + }; + default: Pickups.Add(m_BlockType, 1, Meta); + } } else { - // TODO: Add a proper overridable function for this - Pickups.Add(m_BlockType, 1, Meta); + ConvertToPickups(Pickups, Meta); } } - + else + { + // TODO: Add a proper overridable function for this + Pickups.Add(m_BlockType, 1, Meta); + } } // Allow plugins to modify the pickups: diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index e71f30a66..12149b297 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -18,7 +18,6 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a m_HitGroundTimer(0), m_HasTeleported(false), m_bIsCollected(false), - m_Creator(a_Creator), m_HitBlockPos(Vector3i(0, 0, 0)) { SetSpeed(a_Speed); @@ -44,7 +43,6 @@ cArrowEntity::cArrowEntity(cPlayer & a_Player, double a_Force) : m_HitGroundTimer(0), m_HasTeleported(false), m_bIsCollected(false), - m_Creator(&a_Player), m_HitBlockPos(0, 0, 0) { if (a_Player.IsGameModeCreative()) @@ -70,6 +68,9 @@ bool cArrowEntity::CanPickup(const cPlayer & a_Player) const } + + + void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) { if (GetSpeed().EqualsEps(Vector3d(0, 0, 0), 0.0000001)) @@ -90,7 +91,7 @@ void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFa // Broadcast arrow hit sound m_World->BroadcastSoundEffect("random.bowhit", (double)X, (double)Y, (double)Z, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); - if ((m_World->GetBlock(Hit) == E_BLOCK_TNT) && (m_TicksLeftBurning > 0)) + if ((m_World->GetBlock(Hit) == E_BLOCK_TNT) && (IsOnFire())) { m_World->SetBlock(X, Y, Z, E_BLOCK_AIR, 0); m_World->SpawnPrimedTNT(X, Y, Z); @@ -110,7 +111,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) Damage += m_World->GetTickRandomNumber(Damage / 2 + 2); } - int PowerLevel = m_Creator->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPower); + int PowerLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPower); if (PowerLevel > 0) { int ExtraDamage = 0.25 * (PowerLevel + 1); @@ -118,10 +119,10 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) } int KnockbackAmount = 1; - int PunchLevel = m_Creator->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPunch); + int PunchLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPunch); if (PunchLevel > 0) { - Vector3f LookVector = m_Creator->GetLookVector(); + Vector3f LookVector = Vector3d(0, 0, 0); Vector3f FinalSpeed = Vector3f(0, 0, 0); switch (PunchLevel) { @@ -134,7 +135,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount); - if ((m_TicksLeftBurning > 0 && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming())) + if ((IsOnFire() && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming())) { a_EntityHit.StartBurning(100); } diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h index 553bcb6e7..a1e7a17e7 100644 --- a/src/Entities/ArrowEntity.h +++ b/src/Entities/ArrowEntity.h @@ -91,9 +91,6 @@ protected: /// If true, the arrow is in the process of being collected - don't go to anyone else bool m_bIsCollected; - // Stores the creator from that arrow - cEntity * m_Creator; - /// Stores the block position that arrow is lodged into, sets m_IsInGround to false if it becomes air Vector3i m_HitBlockPos; diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 43023ec28..acc9bd674 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -222,7 +222,8 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a m_ProjectileKind(a_Kind), m_CreatorData( ((a_Creator != NULL) ? a_Creator->GetUniqueID() : -1), - ((a_Creator != NULL) ? (a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "") : "") + ((a_Creator != NULL) ? (a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "") : ""), + ((a_Creator != NULL) ? a_Creator->GetEquippedWeapon().m_Enchantments : cEnchantments()) ), m_IsInGround(false) { @@ -235,7 +236,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height) : super(etProjectile, a_Pos.x, a_Pos.y, a_Pos.z, a_Width, a_Height), m_ProjectileKind(a_Kind), - m_CreatorData(a_Creator->GetUniqueID(), a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : ""), + m_CreatorData(a_Creator->GetUniqueID(), a_Creator->IsPlayer() ? ((cPlayer *)a_Creator)->GetName() : "", a_Creator->GetEquippedWeapon().m_Enchantments), m_IsInGround(false) { SetSpeed(a_Speed); diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index 0ebc32f36..58dc38702 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -94,14 +94,16 @@ protected: */ struct CreatorData { - CreatorData(int a_UniqueID, const AString & a_Name) : + CreatorData(int a_UniqueID, const AString & a_Name, cEnchantments a_Enchantments) : m_UniqueID(a_UniqueID), - m_Name(a_Name) + m_Name(a_Name), + m_Enchantments(a_Enchantments) { } const int m_UniqueID; AString m_Name; + cEnchantments m_Enchantments; }; /** The type of projectile I am */ diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index 0fc0f0920..f29cc5d59 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -84,7 +84,7 @@ public: } else { - Arrow->SetPickupState(cArrowEntity::ePickupState::psNoPickup); + Arrow->SetPickupState(cArrowEntity::psNoPickup); } -- cgit v1.2.3 From 5008eb8c8348ad2664158a8a815ef6851d874367 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Tue, 19 Aug 2014 18:40:42 +0200 Subject: Changed if in BlockHandler --- src/Blocks/BlockHandler.cpp | 7 ++----- src/Entities/Entity.cpp | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index d6be99f83..2238a68a0 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -424,15 +424,12 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac cItems Pickups; NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - // Thanks to daniel0916 - cPlayer * Player = (cPlayer *)a_Digger; - cEnchantments Enchantments = Player->GetInventory().GetEquippedItem().m_Enchantments; - if (a_CanDrop) { if (!a_DropVerbatim) { - if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) + cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; + if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && (a_Digger->IsPlayer())) { switch (m_BlockType) { diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 4316b48e9..54e4cf4f5 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -316,7 +316,6 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) // IsOnGround() only is false if the player is moving downwards // TODO: Better damage increase, and check for enchantments (and use magic critical instead of plain) - // Thanks to daniel0916 cEnchantments Enchantments = Player->GetEquippedItem().m_Enchantments; int SharpnessLevel = Enchantments.GetLevel(cEnchantments::enchSharpness); -- cgit v1.2.3 From 19d1c976e7cd7f6c8a4cb3540d5512a035a4162a Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Thu, 21 Aug 2014 12:08:38 +0200 Subject: Protection Enchantments, some fixes - Protection echantments (fire, blast, feather falling, protection and projectile). It isn't finished, add secondary effects and optimize the code. - Removed some brackets. - Silk touch fixed. --- src/Blocks/BlockHandler.cpp | 15 +++--- src/Entities/ArrowEntity.cpp | 10 ++-- src/Entities/Entity.cpp | 110 ++++++++++++++++++++++++++++++++++++++++++- src/Entities/Player.cpp | 2 +- 4 files changed, 122 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 2238a68a0..0155aa97b 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -428,8 +428,14 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac { if (!a_DropVerbatim) { + ConvertToPickups(Pickups, Meta); + } + else + { + // TODO: Add a proper overridable function for this + // Pickups.Add(m_BlockType, 1, Meta); cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; - if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && (a_Digger->IsPlayer())) + if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && a_Digger->IsPlayer()) { switch (m_BlockType) { @@ -459,14 +465,9 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac } else { - ConvertToPickups(Pickups, Meta); + Pickups.Add(m_BlockType, 1, Meta); } } - else - { - // TODO: Add a proper overridable function for this - Pickups.Add(m_BlockType, 1, Meta); - } } // Allow plugins to modify the pickups: diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 12149b297..c3e7c5d79 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -91,7 +91,7 @@ void cArrowEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFa // Broadcast arrow hit sound m_World->BroadcastSoundEffect("random.bowhit", (double)X, (double)Y, (double)Z, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); - if ((m_World->GetBlock(Hit) == E_BLOCK_TNT) && (IsOnFire())) + if ((m_World->GetBlock(Hit) == E_BLOCK_TNT) && IsOnFire()) { m_World->SetBlock(X, Y, Z, E_BLOCK_AIR, 0); m_World->SpawnPrimedTNT(X, Y, Z); @@ -122,12 +122,12 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) int PunchLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPunch); if (PunchLevel > 0) { - Vector3f LookVector = Vector3d(0, 0, 0); + Vector3d LookVector = GetLookVector(); Vector3f FinalSpeed = Vector3f(0, 0, 0); switch (PunchLevel) { - case 1: FinalSpeed = LookVector * Vector3d(5, 0.3, 5); - case 2: FinalSpeed = LookVector * Vector3d(8, 0.3, 8); + case 1: FinalSpeed = LookVector * Vector3d(5, 0.3, 5); break; + case 2: FinalSpeed = LookVector * Vector3d(8, 0.3, 8); break; default: break; } a_EntityHit.SetSpeed(FinalSpeed); @@ -135,7 +135,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount); - if ((IsOnFire() && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming())) + if (IsOnFire() && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming()) { a_EntityHit.StartBurning(100); } diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 54e4cf4f5..a4c5c4b2a 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -13,6 +13,7 @@ #include "../Tracer.h" #include "Player.h" #include "Items/ItemHandler.h" +#include "../FastRandom.h" @@ -324,7 +325,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) if (SharpnessLevel > 0) { - a_TDI.RawDamage += 1.25 * SharpnessLevel; + a_TDI.FinalDamage += 1.25 * SharpnessLevel; } else if (SmiteLevel > 0) { @@ -338,7 +339,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtWither: case cMonster::mtZombiePigman: { - a_TDI.RawDamage += 2.5 * SmiteLevel; + a_TDI.FinalDamage += 2.5 * SmiteLevel; break; } } @@ -404,6 +405,110 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) Player->GetStatManager().AddValue(statDamageDealt, (StatValue)floor(a_TDI.FinalDamage * 10 + 0.5)); } + if (IsPlayer()){ + double TotalEPF = 0.0; + double EPFProtection = 0.00; + double EPFFireProtection = 0.00; + double EPFBlastProtection = 0.00; + double EPFProjectileProtection = 0.00; + double EPFFeatherFalling = 0.00; + + cEnchantments ChestplateEnchantments = GetEquippedChestplate().m_Enchantments; + cEnchantments LeggingsEnchantments = GetEquippedLeggings().m_Enchantments; + cEnchantments BootsEnchantments = GetEquippedBoots().m_Enchantments; + cEnchantments HelmetEnchantments = GetEquippedHelmet().m_Enchantments; + + if ((ChestplateEnchantments.GetLevel(cEnchantments::enchProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchProtection) > 0) + || (BootsEnchantments.GetLevel(cEnchantments::enchProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchProtection) > 0)) + { + EPFProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + EPFProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + EPFProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + EPFProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + + TotalEPF += EPFProtection; + } + + if ((ChestplateEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) + || (BootsEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0)) + { + EPFFireProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + EPFFireProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + EPFFireProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + EPFFireProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + + TotalEPF += EPFFireProtection; + } + + if ((ChestplateEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) + || (BootsEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0)) + { + EPFFeatherFalling += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + EPFFeatherFalling += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + EPFFeatherFalling += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + EPFFeatherFalling += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + + TotalEPF += EPFFeatherFalling; + } + + if ((ChestplateEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) + || (BootsEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0)) + { + EPFBlastProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + EPFBlastProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + EPFBlastProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + EPFBlastProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + + TotalEPF += EPFBlastProtection; + } + + if ((ChestplateEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) + || (BootsEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0)) + { + EPFProjectileProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + EPFProjectileProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + EPFProjectileProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + EPFProjectileProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + + TotalEPF += EPFProjectileProtection; + } + + EPFProtection = EPFProtection / TotalEPF; + EPFFireProtection = EPFFireProtection / TotalEPF; + EPFFeatherFalling = EPFFeatherFalling / TotalEPF; + EPFBlastProtection = EPFBlastProtection / TotalEPF; + EPFProjectileProtection = EPFProjectileProtection / TotalEPF; + + if (TotalEPF > 25) TotalEPF = 25; + + cFastRandom Random; + float randomvalue; + randomvalue = Random.GenerateRandomInteger(50, 100) * 0.01; + + TotalEPF = ceil(TotalEPF * randomvalue); + + if (TotalEPF > 20) TotalEPF = 20; + + EPFProtection = TotalEPF * EPFProtection; + EPFFireProtection = TotalEPF * EPFFireProtection; + EPFFeatherFalling = TotalEPF * EPFFeatherFalling; + EPFBlastProtection = TotalEPF * EPFBlastProtection; + EPFProjectileProtection = TotalEPF * EPFProjectileProtection; + + int RemovedDamage = 0; + + if (a_TDI.DamageType != dtInVoid) RemovedDamage += ceil(EPFProtection * 0.04 * a_TDI.FinalDamage); + + if ((a_TDI.DamageType == dtFalling) || (a_TDI.DamageType == dtFall) || (a_TDI.DamageType == dtEnderPearl)) RemovedDamage += ceil(EPFFeatherFalling * 0.04 * a_TDI.FinalDamage); + + if (a_TDI.DamageType == dtBurning) RemovedDamage += ceil(EPFFireProtection * 0.04 * a_TDI.FinalDamage); + + if (a_TDI.DamageType == dtExplosion) RemovedDamage += ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + + if (a_TDI.DamageType == dtProjectile) RemovedDamage += ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + + a_TDI.FinalDamage -= RemovedDamage; + } m_Health -= (short)a_TDI.FinalDamage; @@ -411,6 +516,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) m_Health = std::max(m_Health, 0); + if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) // Knockback for only players and mobs { int KnockbackLevel = a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback); // More common enchantment diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index c1031907d..8b829d090 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1978,7 +1978,7 @@ void cPlayer::UseEquippedItem(int a_Amount) } cFastRandom Random; - if (Random.NextInt(100) <= chance) + if (Random.NextInt(101) <= chance) { return; } -- cgit v1.2.3 From 7d771953c0e8275311ca13802e52ccf92a170644 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Fri, 22 Aug 2014 11:49:49 +0200 Subject: More Enchantments - Added Thorns and Respiration enchantments --- src/Blocks/BlockHandler.cpp | 1 - src/Entities/Entity.cpp | 127 ++++++++++++++++++++++++-------------------- 2 files changed, 70 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 0155aa97b..c8a57906f 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -433,7 +433,6 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac else { // TODO: Add a proper overridable function for this - // Pickups.Add(m_BlockType, 1, Meta); cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && a_Digger->IsPlayer()) { diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index a4c5c4b2a..760401cc2 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -357,8 +357,11 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtSilverfish: { a_TDI.RawDamage += 2.5 * BaneOfArthropodsLevel; + // TODO: Add slowness effect + break; - } + }; + default: break; } } } @@ -390,8 +393,27 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) default: StartBurning(BurnTicks * 20); } } + } - + int ThornsLevel = 0; + cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) + { + cItem Item = ArmorItems[i]; + if (Item.m_Enchantments.GetLevel(cEnchantments::enchThorns) > ThornsLevel) ThornsLevel = Item.m_Enchantments.GetLevel(cEnchantments::enchThorns); + } + + if (ThornsLevel > 0) + { + int Chance = ThornsLevel * 15; + + cFastRandom Random; + int RandomValue = Random.GenerateRandomInteger(0, 100); + + if (RandomValue <= Chance) + { + a_TDI.Attacker->TakeDamage(dtAttack, this, 0, Random.GenerateRandomInteger(1, 4), 0); + } } if (!Player->IsOnGround()) @@ -405,6 +427,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) Player->GetStatManager().AddValue(statDamageDealt, (StatValue)floor(a_TDI.FinalDamage * 10 + 0.5)); } + if (IsPlayer()){ double TotalEPF = 0.0; double EPFProtection = 0.00; @@ -413,65 +436,39 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) double EPFProjectileProtection = 0.00; double EPFFeatherFalling = 0.00; - cEnchantments ChestplateEnchantments = GetEquippedChestplate().m_Enchantments; - cEnchantments LeggingsEnchantments = GetEquippedLeggings().m_Enchantments; - cEnchantments BootsEnchantments = GetEquippedBoots().m_Enchantments; - cEnchantments HelmetEnchantments = GetEquippedHelmet().m_Enchantments; - - if ((ChestplateEnchantments.GetLevel(cEnchantments::enchProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchProtection) > 0) - || (BootsEnchantments.GetLevel(cEnchantments::enchProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchProtection) > 0)) + cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { - EPFProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; - EPFProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; - EPFProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; - EPFProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; - - TotalEPF += EPFProtection; - } + cItem Item = ArmorItems[i]; + if (Item.m_Enchantments.GetLevel(cEnchantments::enchProtection) > 0) + { + EPFProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + } - if ((ChestplateEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) - || (BootsEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchFireProtection) > 0)) - { - EPFFireProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; - EPFFireProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; - EPFFireProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; - EPFFireProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; - - TotalEPF += EPFFireProtection; - } + if (Item.m_Enchantments.GetLevel(cEnchantments::enchFireProtection) > 0) + { + EPFFireProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + } - if ((ChestplateEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) - || (BootsEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0)) - { - EPFFeatherFalling += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; - EPFFeatherFalling += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; - EPFFeatherFalling += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; - EPFFeatherFalling += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + if (Item.m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) + { + EPFFeatherFalling += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + } - TotalEPF += EPFFeatherFalling; - } + if (Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) + { + EPFBlastProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + } - if ((ChestplateEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) - || (BootsEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchBlastProtection) > 0)) - { - EPFBlastProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; - EPFBlastProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; - EPFBlastProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; - EPFBlastProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + if (Item.m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) + { + EPFProjectileProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + } - TotalEPF += EPFBlastProtection; } - if ((ChestplateEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) || (LeggingsEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) - || (BootsEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) || (HelmetEnchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0)) - { - EPFProjectileProtection += (6 + pow(ChestplateEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; - EPFProjectileProtection += (6 + pow(LeggingsEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; - EPFProjectileProtection += (6 + pow(BootsEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; - EPFProjectileProtection += (6 + pow(HelmetEnchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; - - TotalEPF += EPFProjectileProtection; - } + TotalEPF = EPFProtection + EPFFireProtection + EPFFeatherFalling + EPFBlastProtection + EPFProjectileProtection; + EPFProtection = EPFProtection / TotalEPF; EPFFireProtection = EPFFireProtection / TotalEPF; @@ -482,10 +479,9 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) if (TotalEPF > 25) TotalEPF = 25; cFastRandom Random; - float randomvalue; - randomvalue = Random.GenerateRandomInteger(50, 100) * 0.01; + float RandomValue = Random.GenerateRandomInteger(50, 100) * 0.01; - TotalEPF = ceil(TotalEPF * randomvalue); + TotalEPF = ceil(TotalEPF * RandomValue); if (TotalEPF > 20) TotalEPF = 20; @@ -507,9 +503,13 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) if (a_TDI.DamageType == dtProjectile) RemovedDamage += ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + if (a_TDI.FinalDamage < RemovedDamage) RemovedDamage = 0; + a_TDI.FinalDamage -= RemovedDamage; } + + m_Health -= (short)a_TDI.FinalDamage; // TODO: Apply damage to armor @@ -533,7 +533,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case 2: AdditionalSpeed.Set(8, 0.3, 8); break; default: break; } - SetSpeed(a_TDI.Knockback + AdditionalSpeed); + AddSpeed(a_TDI.Knockback + AdditionalSpeed); } m_World->BroadcastEntityStatus(*this, esGenericHurt); @@ -1435,6 +1435,8 @@ void cEntity::HandleAir(void) // See if the entity is /submerged/ water (block above is water) // Get the type of block the entity is standing in: + int RespirationLevel = GetEquippedHelmet().m_Enchantments.GetLevel(cEnchantments::enchRespiration); + if (IsSubmerged()) { if (!IsPlayer()) // Players control themselves @@ -1442,6 +1444,11 @@ void cEntity::HandleAir(void) SetSpeedY(1); // Float in the water } + if (RespirationLevel > 0) + { + ((cPawn *)this)->AddEntityEffect(cEntityEffect::effNightVision, 200, 5, 0); + } + if (m_AirLevel <= 0) { // Runs the air tick timer to check whether the player should be damaged @@ -1468,6 +1475,12 @@ void cEntity::HandleAir(void) // Set the air back to maximum m_AirLevel = MAX_AIR_LEVEL; m_AirTickTimer = DROWNING_TICKS; + + if (RespirationLevel > 0) + { + m_AirTickTimer = DROWNING_TICKS + (RespirationLevel * 15 * 20); + } + } } -- cgit v1.2.3 From a56634799e1fb7eef3d2817bd7d9c1b42969e934 Mon Sep 17 00:00:00 2001 From: Christophe Piveteau Date: Sun, 24 Aug 2014 15:03:02 +0200 Subject: Change comment formatting --- src/Entities/Minecart.cpp | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 13469edb3..f43c4d163 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -889,35 +889,31 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) ) - // Moving -X +Z { + // Moving -X +Z if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) - // ~ speedX >= 0 { - // Immobile or not moving in the "right" direction. Give it a bump! + // ~ SpeedX >= 0 Immobile or not moving in the "right" direction. Give it a bump! AddSpeedX(-4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } else - // ~ SpeedX < 0 { - // Moving in the "right" direction. Only accelerate it a bit. + // ~ SpeedX < 0 Moving in the "right" direction. Only accelerate it a bit. SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } } else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) - // Moving +X -Z - // ~ SpeedX <= 0 { - // Immobile or not moving in the "right" direction + // Moving +X -T + // ~ SpeedX <= 0 Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } else - // ~ SpeedX > 0 { - // Moving in the "right" direction + // ~ SpeedX > 0 Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } @@ -942,35 +938,31 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) ) - // Moving +X +Z { + // Moving +X +Z if ((GetSpeedX() * 0.4) < 0.01) - // ~ SpeedX <= 0 { - // Immobile or not moving in the "right" direction + // ~ SpeedX <= 0 Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(4 / sqrt(2)); } else - // SpeedX > 0 { - // Moving in the "right" direction + // ~ SpeedX > 0 Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } } else if ((-GetSpeedX() * 0.4) < 0.01) - // Moving -X -Z - // ~ SpeedX >= 0 { - // Immobile or not moving in the "right" direction + // Moving -X -Z + // ~ SpeedX >= 0 Immobile or not moving in the "right" direction AddSpeedX(-4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); } else - // ~ SpeedX < 0 { - // Moving in the "right" direction + // ~ SpeedX < 0 Moving in the "right" direction SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); } -- cgit v1.2.3 From 49ac6fadfc441e1de1a0127ff45996ac3abae150 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 28 Aug 2014 16:44:36 +0300 Subject: Fixed spaces after "template" keyword. --- src/Bindings/ManualBindings.cpp | 12 ++++++------ src/Blocks/ClearMetaOnDrop.h | 2 +- src/Blocks/MetaRotator.h | 10 +++++----- src/OSSupport/Queue.h | 2 +- src/StringUtils.h | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 6b40cece8..23651b0e1 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -301,11 +301,11 @@ static int tolua_cFile_GetFolderContents(lua_State * tolua_S) -template< +template < class Ty1, class Ty2, bool (Ty1::*Func1)(const AString &, cItemCallback &) - > +> static int tolua_DoWith(lua_State* tolua_S) { int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ @@ -395,7 +395,7 @@ static int tolua_DoWith(lua_State* tolua_S) -template< +template < class Ty1, class Ty2, bool (Ty1::*Func1)(int, cItemCallback &) @@ -485,7 +485,7 @@ static int tolua_DoWithID(lua_State* tolua_S) -template< +template < class Ty1, class Ty2, bool (Ty1::*Func1)(int, int, int, cItemCallback &) @@ -580,7 +580,7 @@ static int tolua_DoWithXYZ(lua_State* tolua_S) -template< +template < class Ty1, class Ty2, bool (Ty1::*Func1)(int, int, cItemCallback &) @@ -676,7 +676,7 @@ static int tolua_ForEachInChunk(lua_State * tolua_S) -template< +template < class Ty1, class Ty2, bool (Ty1::*Func1)(cItemCallback &) diff --git a/src/Blocks/ClearMetaOnDrop.h b/src/Blocks/ClearMetaOnDrop.h index f2afbc6ea..aa4f23848 100644 --- a/src/Blocks/ClearMetaOnDrop.h +++ b/src/Blocks/ClearMetaOnDrop.h @@ -7,7 +7,7 @@ // For example to use in class Foo which should inherit Bar use // class Foo : public cClearMetaOnDrop; -template +template class cClearMetaOnDrop : public Base { public: diff --git a/src/Blocks/MetaRotator.h b/src/Blocks/MetaRotator.h index 599aa7ef9..4c268077a 100644 --- a/src/Blocks/MetaRotator.h +++ b/src/Blocks/MetaRotator.h @@ -20,7 +20,7 @@ Usage: Inherit from this class providing your base class as Base, the BitMask for the direction bits in bitmask and the masked value for the directions in North, East, South, West. There is also an aptional parameter AssertIfNotMatched. Set this if it is invalid for a block to exist in any other state. */ -template +template class cMetaRotator : public Base { public: @@ -41,7 +41,7 @@ public: -template +template NIBBLETYPE cMetaRotator::MetaRotateCW(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); @@ -63,7 +63,7 @@ NIBBLETYPE cMetaRotator +template NIBBLETYPE cMetaRotator::MetaRotateCCW(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); @@ -85,7 +85,7 @@ NIBBLETYPE cMetaRotator +template NIBBLETYPE cMetaRotator::MetaMirrorXY(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); @@ -102,7 +102,7 @@ NIBBLETYPE cMetaRotator +template NIBBLETYPE cMetaRotator::MetaMirrorYZ(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); diff --git a/src/OSSupport/Queue.h b/src/OSSupport/Queue.h index bf4d7f004..8d096fe29 100644 --- a/src/OSSupport/Queue.h +++ b/src/OSSupport/Queue.h @@ -20,7 +20,7 @@ cQueueFuncs and is used as the default behavior. */ /// This empty struct allows for the callback functions to be inlined -template +template struct cQueueFuncs { public: diff --git a/src/StringUtils.h b/src/StringUtils.h index a78f8b0bf..7699a18bd 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -101,7 +101,7 @@ extern int GetBEInt(const char * a_Mem); extern void SetBEInt(char * a_Mem, Int32 a_Value); /// Parses any integer type. Checks bounds and returns errors out of band. -template +template bool StringToInteger(const AString& a_str, T& a_Num) { size_t i = 0; -- cgit v1.2.3 From 9b68ff2656d5e662d33c670ee5fa20dd12b8264f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 28 Aug 2014 16:53:26 +0300 Subject: CheckBasicStyle: Added checking for the "template" keyword. --- src/CheckBasicStyle.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/CheckBasicStyle.lua b/src/CheckBasicStyle.lua index bf81a7cd5..b244b1fbc 100644 --- a/src/CheckBasicStyle.lua +++ b/src/CheckBasicStyle.lua @@ -108,7 +108,7 @@ local g_ViolationPatterns = -- Check that all commas have spaces after them and not in front of them: {" ,", "Extra space before a \",\""}, - {",[^%s\"%%]", "Needs a space after a \",\""}, -- Report all except >> "," << needed for splitting and >>,%s<< needed for formatting + {",[^%s\"%%\']", "Needs a space after a \",\""}, -- Report all except >> "," << needed for splitting and >>,%s<< needed for formatting -- Check that opening braces are not at the end of a code line: {"[^%s].-{\n?$", "Brace should be on a separate line"}, @@ -119,6 +119,7 @@ local g_ViolationPatterns = {"while%(", "Needs a space after \"while\""}, {"switch%(", "Needs a space after \"switch\""}, {"catch%(", "Needs a space after \"catch\""}, + {"template<", "Needs a space after \"template\""}, -- No space after keyword's parenthesis: {"[^%a#]if %( ", "Remove the space after \"(\""}, -- cgit v1.2.3 From 271c8c0d3246749087f9772df31896d93f2cb9f3 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 28 Aug 2014 16:58:48 +0300 Subject: More template keyword fixes. --- src/BlockArea.cpp | 18 +++++++++--------- src/BlockArea.h | 2 +- src/Defines.h | 2 +- src/LinearUpscale.h | 6 +++--- src/StringUtils.h | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 90f7ca6c9..ba55528b8 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -28,7 +28,7 @@ typedef void (CombinatorFunc)(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLE // This wild construct allows us to pass a function argument and still have it inlined by the compiler :) /// Merges two blocktypes and blockmetas of the specified sizes and offsets using the specified combinator function -template +template void InternalMergeBlocks( BLOCKTYPE * a_DstTypes, const BLOCKTYPE * a_SrcTypes, NIBBLETYPE * a_DstMetas, const NIBBLETYPE * a_SrcMetas, @@ -74,7 +74,7 @@ void InternalMergeBlocks( /// Combinator used for cBlockArea::msOverwrite merging -template +template void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { a_DstType = a_SrcType; @@ -89,7 +89,7 @@ void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLE /// Combinator used for cBlockArea::msFillAir merging -template +template void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { if (a_DstType == E_BLOCK_AIR) @@ -108,7 +108,7 @@ void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETY /// Combinator used for cBlockArea::msImprint merging -template +template void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { if (a_SrcType != E_BLOCK_AIR) @@ -127,7 +127,7 @@ void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETY /// Combinator used for cBlockArea::msLake merging -template +template void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { // Sponge is the NOP block @@ -201,7 +201,7 @@ void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE /** Combinator used for cBlockArea::msSpongePrint merging */ -template +template void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { // Sponge overwrites nothing, everything else overwrites anything @@ -220,7 +220,7 @@ void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBB /** Combinator used for cBlockArea::msDifference merging */ -template +template void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { if ((a_DstType == a_SrcType) && (!MetaValid || (a_DstMeta == a_SrcMeta))) @@ -246,7 +246,7 @@ void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBL /** Combinator used for cBlockArea::msMask merging */ -template +template void MergeCombinatorMask(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { // If the blocks are the same, keep the dest; otherwise replace with air @@ -2121,7 +2121,7 @@ void cBlockArea::RelSetData( -template +template void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas) { // Block types are compulsory, block metas are voluntary diff --git a/src/BlockArea.h b/src/BlockArea.h index a95ba7788..86f7c4f2d 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -362,7 +362,7 @@ protected: NIBBLETYPE a_BlockLight, NIBBLETYPE a_BlockSkyLight ); - template + template void MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas); // tolua_begin } ; diff --git a/src/Defines.h b/src/Defines.h index 0981077c4..78c58034e 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -528,7 +528,7 @@ inline float GetSpecialSignf( float a_Val) -template inline T Diff(T a_Val1, T a_Val2) +template inline T Diff(T a_Val1, T a_Val2) { return std::abs(a_Val1 - a_Val2); } diff --git a/src/LinearUpscale.h b/src/LinearUpscale.h index 0b04408cf..a49f4bdf9 100644 --- a/src/LinearUpscale.h +++ b/src/LinearUpscale.h @@ -31,7 +31,7 @@ Linearly interpolates values in the array between the equidistant anchor points Works in-place (input is already present at the correct output coords) Uses templates to make it possible for the compiler to further optimizer the loops */ -template< +template < int SizeX, int SizeY, // Dimensions of the array int AnchorStepX, int AnchorStepY, typename TYPE @@ -83,7 +83,7 @@ void LinearUpscale2DArrayInPlace(TYPE * a_Array) Linearly interpolates values in the array between the equidistant anchor points (upscales). Works on two arrays, input is packed and output is to be completely constructed. */ -template void LinearUpscale2DArray( +template void LinearUpscale2DArray( TYPE * a_Src, ///< Source array of size a_SrcSizeX x a_SrcSizeY int a_SrcSizeX, int a_SrcSizeY, ///< Dimensions of the src array TYPE * a_Dst, ///< Dest array, of size (a_SrcSizeX * a_UpscaleX + 1) x (a_SrcSizeY * a_UpscaleY + 1) @@ -153,7 +153,7 @@ template void LinearUpscale2DArray( Linearly interpolates values in the array between the equidistant anchor points (upscales). Works on two arrays, input is packed and output is to be completely constructed. */ -template void LinearUpscale3DArray( +template void LinearUpscale3DArray( TYPE * a_Src, ///< Source array of size a_SrcSizeX x a_SrcSizeY x a_SrcSizeZ int a_SrcSizeX, int a_SrcSizeY, int a_SrcSizeZ, ///< Dimensions of the src array TYPE * a_Dst, ///< Dest array, of size (a_SrcSizeX * a_UpscaleX + 1) x (a_SrcSizeY * a_UpscaleY + 1) x (a_SrcSizeZ * a_UpscaleZ + 1) diff --git a/src/StringUtils.h b/src/StringUtils.h index a63d852ee..4a4c267c7 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -117,7 +117,7 @@ bool StringToInteger(const AString& a_str, T& a_Num) } if (positive) { - for(size_t size = a_str.size(); i < size; i++) + for (size_t size = a_str.size(); i < size; i++) { if ((a_str[i] <= '0') || (a_str[i] >= '9')) { @@ -138,7 +138,7 @@ bool StringToInteger(const AString& a_str, T& a_Num) } else { - for(size_t size = a_str.size(); i < size; i++) + for (size_t size = a_str.size(); i < size; i++) { if ((a_str[i] <= '0') || (a_str[i] >= '9')) { -- cgit v1.2.3 From d74e49ddc00095589cfefb29ceb23da13f3e5f0a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 28 Aug 2014 17:01:59 +0300 Subject: Final template keyword style fix. --- src/AllocationPool.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/AllocationPool.h b/src/AllocationPool.h index 3c9dbe8c9..61431a548 100644 --- a/src/AllocationPool.h +++ b/src/AllocationPool.h @@ -3,7 +3,7 @@ #include -template +template class cAllocationPool { public: @@ -34,7 +34,7 @@ public: /** Allocates memory storing unused elements in a linked list. Keeps at least NumElementsInReserve elements in the list unless malloc fails so that the program has a reserve to handle OOM.**/ -template +template class cListAllocationPool : public cAllocationPool { public: -- cgit v1.2.3 From 1c136a60478811dabfb54e89a27fb1229d0d1b49 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 28 Aug 2014 17:04:26 +0300 Subject: Fixed a typo. --- src/Entities/Minecart.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index f43c4d163..21c58fdba 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -906,7 +906,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) } else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) { - // Moving +X -T + // Moving +X -Z // ~ SpeedX <= 0 Immobile or not moving in the "right" direction AddSpeedX(4 / sqrt(2)); AddSpeedZ(-4 / sqrt(2)); -- cgit v1.2.3 From eaf33e22cf65178d94aafab3df5d8a9f67581529 Mon Sep 17 00:00:00 2001 From: Hownaer Date: Thu, 28 Aug 2014 18:57:56 +0200 Subject: Fixed anvil placing. --- src/Blocks/BlockAnvil.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index 5c4661c11..376bf86a3 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -40,14 +40,15 @@ public: ) override { a_BlockType = m_BlockType; - NIBBLETYPE HighBits = a_BlockMeta & 0x0c; // Only highest two bits are preserved + NIBBLETYPE Meta = a_Player->GetEquippedItem().m_ItemDamage; int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 1.5) & 0x3; + switch (Direction) { - case 0: a_BlockMeta = 0x2 | HighBits; break; - case 1: a_BlockMeta = 0x3 | HighBits; break; - case 2: a_BlockMeta = 0x0 | HighBits; break; - case 3: a_BlockMeta = 0x1 | HighBits; break; + case 0: a_BlockMeta = 0x2 | Meta << 2; break; + case 1: a_BlockMeta = 0x3 | Meta << 2; break; + case 2: a_BlockMeta = 0x0 | Meta << 2; break; + case 3: a_BlockMeta = 0x1 | Meta << 2; break; default: { return false; -- cgit v1.2.3 From 4470ebffd72a091cddc46022bb3f5ed378651584 Mon Sep 17 00:00:00 2001 From: Hownaer Date: Thu, 28 Aug 2014 20:49:34 +0200 Subject: Fire can be destroyed with the sword in creative-mode --- src/ClientHandle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 8aa883144..f9c6a664c 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1059,7 +1059,8 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc if ( m_Player->IsGameModeCreative() && - ItemCategory::IsSword(m_Player->GetInventory().GetEquippedItem().m_ItemType) + ItemCategory::IsSword(m_Player->GetInventory().GetEquippedItem().m_ItemType) && + (m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_FIRE) ) { // Players can't destroy blocks with a Sword in the hand. -- cgit v1.2.3 From c4d7f7996b0dcd784f5e1ccc8553b062c3ac96b6 Mon Sep 17 00:00:00 2001 From: Hownaer Date: Fri, 29 Aug 2014 00:42:33 +0200 Subject: Hotfixed recipe.txt loading. --- src/CraftingRecipes.cpp | 7 +++++-- src/StringUtils.h | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 2d80ecaf8..223184c64 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -1,4 +1,4 @@ - + // CraftingRecipes.cpp // Interfaces to the cCraftingRecipes class representing the storage of crafting recipes @@ -366,7 +366,10 @@ void cCraftingRecipes::ClearRecipes(void) void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine) { - AStringVector Sides = StringSplit(a_RecipeLine, "="); + AString RecipeLine(a_RecipeLine); + RecipeLine.erase(std::remove(RecipeLine.begin(), RecipeLine.end(), ' '), RecipeLine.end()); + + AStringVector Sides = StringSplit(RecipeLine, "="); if (Sides.size() != 2) { LOGWARNING("crafting.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1); diff --git a/src/StringUtils.h b/src/StringUtils.h index 4a4c267c7..c48ca6051 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -119,7 +119,7 @@ bool StringToInteger(const AString& a_str, T& a_Num) { for (size_t size = a_str.size(); i < size; i++) { - if ((a_str[i] <= '0') || (a_str[i] >= '9')) + if ((a_str[i] < '0') || (a_str[i] > '9')) { return false; } @@ -140,7 +140,7 @@ bool StringToInteger(const AString& a_str, T& a_Num) { for (size_t size = a_str.size(); i < size; i++) { - if ((a_str[i] <= '0') || (a_str[i] >= '9')) + if ((a_str[i] < '0') || (a_str[i] > '9')) { return false; } -- cgit v1.2.3 From 42570cbeef6a3634f56c54008277c395edaa041e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 29 Aug 2014 11:20:23 +0300 Subject: Fixed spaces. --- src/StringUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/StringUtils.h b/src/StringUtils.h index c48ca6051..72a90a8c2 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -101,7 +101,7 @@ extern void SetBEInt(char * a_Mem, Int32 a_Value); /// Parses any integer type. Checks bounds and returns errors out of band. template -bool StringToInteger(const AString& a_str, T& a_Num) +bool StringToInteger(const AString & a_str, T & a_Num) { size_t i = 0; bool positive = true; -- cgit v1.2.3 From 97c4c057e4e818562ae0a75520923196044ed55b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 29 Aug 2014 11:20:33 +0300 Subject: Fixed conversion warning. --- src/Blocks/BlockAnvil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index 376bf86a3..20514580e 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -40,7 +40,7 @@ public: ) override { a_BlockType = m_BlockType; - NIBBLETYPE Meta = a_Player->GetEquippedItem().m_ItemDamage; + NIBBLETYPE Meta = (NIBBLETYPE)a_Player->GetEquippedItem().m_ItemDamage; int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 1.5) & 0x3; switch (Direction) -- cgit v1.2.3 From d0551e2e0a98a28f31a88d489d17b408e4a7d38d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 29 Aug 2014 14:58:41 +0300 Subject: VanillaFluidSimulator: Fixed an invalid Y-coord query. This was causing a spam of console messages, along with possible server crash, when liquids passed below the world: http://forum.mc-server.org/showthread.php?tid=1508&pid=15632#pid15632 --- src/Simulator/VanillaFluidSimulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Simulator/VanillaFluidSimulator.cpp b/src/Simulator/VanillaFluidSimulator.cpp index 18d9b07e1..6df75eebb 100644 --- a/src/Simulator/VanillaFluidSimulator.cpp +++ b/src/Simulator/VanillaFluidSimulator.cpp @@ -98,7 +98,7 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int } // Check if block below is passable - if (!a_Chunk->UnboundedRelGetBlock(a_RelX, a_RelY - 1, a_RelZ, BlockType, BlockMeta)) + if ((a_RelY > 0) && !a_Chunk->UnboundedRelGetBlock(a_RelX, a_RelY - 1, a_RelZ, BlockType, BlockMeta)) { return Cost; } -- cgit v1.2.3 From fca5a01145f78a4ae517da6c19ee61ab54574e82 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 29 Aug 2014 13:41:50 +0100 Subject: Improved command block security --- src/BlockEntities/CommandBlockEntity.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 45f8a3e4d..fe2f5e60a 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -13,6 +13,7 @@ #include "../Root.h" #include "../Server.h" // ExecuteConsoleCommand() #include "../Chunk.h" +#include "../ChatColor.h" @@ -206,15 +207,27 @@ void cCommandBlockEntity::Execute() virtual void Out(const AString & a_Text) { // Overwrite field - m_CmdBlock->SetLastOutput(a_Text); + m_CmdBlock->SetLastOutput(cClientHandle::FormatChatPrefix(m_CmdBlock->GetWorld()->ShouldUseChatPrefixes(), "SUCCESS", cChatColor::Green, cChatColor::White) + a_Text); } } CmdBlockOutCb(this); - LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str()); - - cServer * Server = cRoot::Get()->GetServer(); - - Server->ExecuteConsoleCommand(m_Command, CmdBlockOutCb); + if ( // Administrator commands are not executable by command blocks + (m_Command != "stop") && + (m_Command != "restart") && + (m_Command != "kick") && + (m_Command != "ban") && + (m_Command != "ipban") + ) + { + cServer * Server = cRoot::Get()->GetServer(); + LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str()); + Server->ExecuteConsoleCommand(m_Command, CmdBlockOutCb); + } + else + { + SetLastOutput(cClientHandle::FormatChatPrefix(GetWorld()->ShouldUseChatPrefixes(), "FAILURE", cChatColor::Rose, cChatColor::White) + "Adminstration commands can not be executed"); + LOGD("cCommandBlockEntity: Prevented execution of administration command %s", m_Command.c_str()); + } // TODO 2014-01-18 xdot: Update the signal strength. m_Result = 0; -- cgit v1.2.3 From 114b14faad854661040a3a65c027d6b3fa818f56 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 29 Aug 2014 13:44:01 +0100 Subject: Removed unused code --- src/Entities/ItemFrame.cpp | 1 - src/Items/ItemHandler.h | 2 +- src/WorldStorage/NBTChunkSerializer.cpp | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp index f0b0c8c65..0bc10ec60 100644 --- a/src/Entities/ItemFrame.cpp +++ b/src/Entities/ItemFrame.cpp @@ -55,7 +55,6 @@ void cItemFrame::KilledBy(TakeDamageInfo & a_TDI) { if (m_Item.IsEmpty()) { - SetHealth(0); super::KilledBy(a_TDI); Destroy(); return; diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h index 8b554ee34..67c250a97 100644 --- a/src/Items/ItemHandler.h +++ b/src/Items/ItemHandler.h @@ -75,7 +75,7 @@ public: int FoodLevel; double Saturation; - FoodInfo(int a_FoodLevel, double a_Saturation, int a_PoisonChance = 0) : + FoodInfo(int a_FoodLevel, double a_Saturation) : FoodLevel(a_FoodLevel), Saturation(a_Saturation) { diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index e435a1b1f..68e541eba 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -615,7 +615,6 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) { m_Writer.BeginCompound(""); AddBasicEntity(a_Projectile, a_Projectile->GetMCAClassName()); - Vector3d Pos = a_Projectile->GetPosition(); m_Writer.AddByte("inGround", a_Projectile->IsInGround() ? 1 : 0); switch (a_Projectile->GetProjectileKind()) -- cgit v1.2.3 From 21ff1d81ab4e68f31874894a1f4b7feb53d210df Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 29 Aug 2014 13:44:10 +0100 Subject: Improved explosion damage --- src/ChunkMap.cpp | 67 +++++++++++++++++++------------------------------------- src/World.cpp | 9 +++++--- 2 files changed, 28 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index dd8be0631..8ca61e2cf 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1880,21 +1880,18 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ } else if ((m_World->GetTNTShrapnelLevel() > slNone) && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around { - if (!cBlockInfo::FullyOccupiesVoxel(Block)) + if ( + ((m_World->GetTNTShrapnelLevel() == slAll) && cBlockInfo::FullyOccupiesVoxel(Block)) || + ((m_World->GetTNTShrapnelLevel() == slGravityAffectedOnly) && ((Block == E_BLOCK_SAND) || (Block == E_BLOCK_GRAVEL))) + ) { - break; + m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, Block, area.GetBlockMeta(bx + x, by + y, bz + z)); } - else if ((m_World->GetTNTShrapnelLevel() == slGravityAffectedOnly) && ((Block != E_BLOCK_SAND) && (Block != E_BLOCK_GRAVEL))) - { - break; - } - m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, Block, area.GetBlockMeta(bx + x, by + y, bz + z)); } area.SetBlockTypeMeta(bx + x, by + y, bz + z, E_BLOCK_AIR, 0); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); - break; - + break; } } // switch (BlockType) } // for z @@ -1916,51 +1913,31 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ virtual bool Item(cEntity * a_Entity) override { - if (a_Entity->IsPickup()) - { - if (((cPickup *)a_Entity)->GetAge() < 20) // If pickup age is smaller than one second, it is invincible (so we don't kill pickups that were just spawned) - { - return false; - } - } - - Vector3d EntityPos = a_Entity->GetPosition(); - cBoundingBox bbEntity(EntityPos, a_Entity->GetWidth() / 2, a_Entity->GetHeight()); - - if (!m_bbTNT.IsInside(bbEntity)) // IsInside actually acts like DoesSurround + if (a_Entity->IsPickup() && (a_Entity->GetTicksAlive() < 20)) { + // If pickup age is smaller than one second, it is invincible (so we don't kill pickups that were just spawned) return false; } - - Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); - - // Work out how far we are from the edge of the TNT's explosive effect - AbsoluteEntityPos -= m_ExplosionPos; - - // All to positive - AbsoluteEntityPos.x = abs(AbsoluteEntityPos.x); - AbsoluteEntityPos.y = abs(AbsoluteEntityPos.y); - AbsoluteEntityPos.z = abs(AbsoluteEntityPos.z); - - double FinalDamage = (((1 / AbsoluteEntityPos.x) + (1 / AbsoluteEntityPos.y) + (1 / AbsoluteEntityPos.z)) * 2) * m_ExplosionSize; - - // Clip damage values - FinalDamage = Clamp(FinalDamage, 0.0, (double)a_Entity->GetMaxHealth()); + Vector3d DistanceFromExplosion = a_Entity->GetPosition() - m_ExplosionPos; + if (!a_Entity->IsTNT() && !a_Entity->IsFallingBlock()) // Don't apply damage to other TNT entities and falling blocks, they should be invincible { - a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); - } + cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); - // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() - Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; - if (distance_explosion.SqrLength() < 4096.0) - { - distance_explosion.Normalize(); - distance_explosion *= m_ExplosionSize * m_ExplosionSize; + if (!m_bbTNT.IsInside(bbEntity)) // If bbEntity is inside bbTNT, not vice versa! + { + return false; + } - a_Entity->AddSpeed(distance_explosion); + // Ensure that the damage dealt is inversely proportional to the distance to the TNT centre - the closer a player is, the harder they are hit + a_Entity->TakeDamage(dtExplosion, NULL, (int)((1 / DistanceFromExplosion.Length()) * 6 * m_ExplosionSize), 0); } + + // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() + DistanceFromExplosion.Normalize(); + DistanceFromExplosion *= m_ExplosionSize * m_ExplosionSize; + a_Entity->AddSpeed(DistanceFromExplosion); return false; } diff --git a/src/World.cpp b/src/World.cpp index d2213d1e5..c850c50d3 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1188,24 +1188,26 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo return; } - // TODO: Add damage to entities and implement block hardiness + // TODO: Implement block hardiness Vector3d explosion_pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); cVector3iArray BlocksAffected; m_ChunkMap->DoExplosionAt(a_ExplosionSize, a_BlockX, a_BlockY, a_BlockZ, BlocksAffected); BroadcastSoundEffect("random.explode", (double)a_BlockX, (double)a_BlockY, (double)a_BlockZ, 1.0f, 0.6f); + { cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); - if ((ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + if (ch == NULL) { continue; } + Vector3d distance_explosion = (*itr)->GetPosition() - explosion_pos; if (distance_explosion.SqrLength() < 4096.0) { - double real_distance = std::max(0.004, sqrt(distance_explosion.SqrLength())); + double real_distance = std::max(0.004, distance_explosion.Length()); double power = a_ExplosionSize / real_distance; if (power <= 1) { @@ -1217,6 +1219,7 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo } } } + cPluginManager::Get()->CallHookExploded(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData); } -- cgit v1.2.3 From 618741f78e2e840552663590fd0d6eab03aa874e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 29 Aug 2014 14:43:49 +0100 Subject: Added new console command with cleanup --- src/Root.cpp | 14 +++----------- src/Server.cpp | 59 +++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/Root.cpp b/src/Root.cpp index c20cf0d21..f72f0bae3 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -462,16 +462,6 @@ void cRoot::QueueExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCall void cRoot::QueueExecuteConsoleCommand(const AString & a_Cmd) { - // Some commands are built-in: - if (a_Cmd == "stop") - { - m_bStop = true; - } - else if (a_Cmd == "restart") - { - m_bRestart = true; - } - // Put the command into a queue (Alleviates FS #363): cCSLock Lock(m_CSPendingCommands); m_PendingCommands.push_back(cCommand(a_Cmd, new cLogCommandDeleteSelfOutputCallback)); @@ -483,14 +473,16 @@ void cRoot::QueueExecuteConsoleCommand(const AString & a_Cmd) void cRoot::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallback & a_Output) { - // Some commands are built-in: + // cRoot handles stopping and restarting due to our access to controlling variables if (a_Cmd == "stop") { m_bStop = true; + return; } else if (a_Cmd == "restart") { m_bRestart = true; + return; } LOG("Executing console command: \"%s\"", a_Cmd.c_str()); diff --git a/src/Server.cpp b/src/Server.cpp index 42ad133f1..4524ece76 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -457,33 +457,34 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac return; } - // Special handling: "stop" and "restart" are built in - if ((split[0].compare("stop") == 0) || (split[0].compare("restart") == 0)) - { - return; - } + // "stop" and "restart" are handled in cRoot::ExecuteConsoleCommand, our caller, due to its access to controlling variables // "help" and "reload" are to be handled by MCS, so that they work no matter what if (split[0] == "help") { PrintHelp(split, a_Output); + a_Output.Finished(); return; } if (split[0] == "reload") { cPluginManager::Get()->ReloadPlugins(); cRoot::Get()->ReloadGroups(); + a_Output.Out("Plugins and groups reloaded"); + a_Output.Finished(); return; } if (split[0] == "reloadplugins") { cPluginManager::Get()->ReloadPlugins(); + a_Output.Out("Plugins reloaded"); + a_Output.Finished(); return; } if (split[0] == "reloadgroups") { cRoot::Get()->ReloadGroups(); - a_Output.Out("Groups reloaded!"); + a_Output.Out("Groups reloaded"); a_Output.Finished(); return; } @@ -491,31 +492,54 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac { if (split.size() > 1) { - cPluginManager::Get()->LoadPlugin(split[1]); - - return; + a_Output.Out(cPluginManager::Get()->LoadPlugin(split[1]) ? "Plugin loaded" : "Error occurred loading plugin"); } else { - a_Output.Out("No plugin given! Command: load "); - a_Output.Finished(); - return; + a_Output.Out("Usage: load "); } + a_Output.Finished(); + return; } - if (split[0] == "unload") { if (split.size() > 1) { cPluginManager::Get()->RemovePlugin(cPluginManager::Get()->GetPlugin(split[1])); - return; + a_Output.Out("Plugin unloaded"); } else { - a_Output.Out("No plugin given! Command: unload "); - a_Output.Finished(); - return; + a_Output.Out("Usage: unload "); } + a_Output.Finished(); + return; + } + if (split[0] == "destroyentities") + { + class WorldCallback : public cWorldListCallback + { + virtual bool Item(cWorld * a_World) override + { + class EntityCallback : public cEntityCallback + { + virtual bool Item(cEntity * a_Entity) override + { + if (!a_Entity->IsPlayer()) + { + a_Entity->Destroy(); + } + return false; + } + } EC; + a_World->ForEachEntity(EC); + return false; + } + } WC; + cRoot::Get()->ForEachWorld(WC); + a_Output.Out("Destroyed all entities"); + a_Output.Finished(); + return; } // There is currently no way a plugin can do these (and probably won't ever be): @@ -610,6 +634,7 @@ void cServer::BindBuiltInConsoleCommands(void) PlgMgr->BindConsoleCommand("chunkstats", NULL, " - Displays detailed chunk memory statistics"); PlgMgr->BindConsoleCommand("load ", NULL, " - Adds and enables the specified plugin"); PlgMgr->BindConsoleCommand("unload ", NULL, " - Disables the specified plugin"); + PlgMgr->BindConsoleCommand("destroyentities", NULL, " - Destroys all entities in all worlds"); #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) PlgMgr->BindConsoleCommand("dumpmem", NULL, " - Dumps all used memory blocks together with their callstacks into memdump.xml"); -- cgit v1.2.3 From 389614c9599dc6a24a0f22b0a16e8af02e4b4cca Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 29 Aug 2014 15:12:45 +0100 Subject: A better hotfix for CraftingRecipies --- src/CraftingRecipes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 223184c64..ed3409207 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -367,7 +367,7 @@ void cCraftingRecipes::ClearRecipes(void) void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine) { AString RecipeLine(a_RecipeLine); - RecipeLine.erase(std::remove(RecipeLine.begin(), RecipeLine.end(), ' '), RecipeLine.end()); + RecipeLine.erase(std::remove_if(RecipeLine.begin(), RecipeLine.end(), isspace), RecipeLine.end()); AStringVector Sides = StringSplit(RecipeLine, "="); if (Sides.size() != 2) -- cgit v1.2.3 From 22e3bbd0db71f9bd6d0a4306db1127f257bd24b1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 29 Aug 2014 19:19:27 +0300 Subject: Rewritten block entity loading. Block entities are now loaded based on the blocktype at the coords they specify; before loading, their type ("id" NBT tag) is checked. The chunk now expects that all block entities given to it via cChunk::SetAllData() have their valid blocktype; asserts if they don't. Fixes #1354. --- src/Chunk.cpp | 10 + src/Chunk.h | 2 +- src/SetChunkData.cpp | 33 ++++ src/SetChunkData.h | 3 + src/World.cpp | 6 +- src/WorldStorage/WSSAnvil.cpp | 438 +++++++++++++++++++++++------------------- src/WorldStorage/WSSAnvil.h | 31 +-- 7 files changed, 308 insertions(+), 215 deletions(-) (limited to 'src') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 116c0f3a0..40ffff834 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -296,6 +296,16 @@ void cChunk::SetAllData(cSetChunkData & a_SetChunkData) } m_BlockEntities.clear(); std::swap(a_SetChunkData.GetBlockEntities(), m_BlockEntities); + + // Check that all block entities have a valid blocktype at their respective coords (DEBUG-mode only): + #ifdef _DEBUG + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) + { + BLOCKTYPE EntityBlockType = (*itr)->GetBlockType(); + BLOCKTYPE WorldBlockType = GetBlock((*itr)->GetRelX(), (*itr)->GetPosY(), (*itr)->GetRelZ()); + ASSERT(EntityBlockType == WorldBlockType); + } // for itr - m_BlockEntities + #endif // _DEBUG // Set all block entities' World variable: for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) diff --git a/src/Chunk.h b/src/Chunk.h index 72a1f6c95..e7aeff1a4 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -155,7 +155,7 @@ public: void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc. BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const; - BLOCKTYPE GetBlock(Vector3i a_cords) const { return GetBlock(a_cords.x, a_cords.y, a_cords.z);} + BLOCKTYPE GetBlock(Vector3i a_RelCords) const { return GetBlock(a_RelCords.x, a_RelCords.y, a_RelCords.z);} void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp index af6ad1251..97903074a 100644 --- a/src/SetChunkData.cpp +++ b/src/SetChunkData.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "SetChunkData.h" +#include "BlockEntities/BlockEntity.h" @@ -116,3 +117,35 @@ void cSetChunkData::CalculateHeightMap(void) + +void cSetChunkData::RemoveInvalidBlockEntities(void) +{ + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end();) + { + BLOCKTYPE EntityBlockType = (*itr)->GetBlockType(); + BLOCKTYPE WorldBlockType = cChunkDef::GetBlock(m_BlockTypes, (*itr)->GetRelX(), (*itr)->GetPosY(), (*itr)->GetRelZ()); + if (EntityBlockType != WorldBlockType) + { + // Bad blocktype, remove the block entity: + LOGD("Block entity blocktype mismatch at {%d, %d, %d}: entity for blocktype %s(%d) in block %s(%d). Deleting the block entity.", + (*itr)->GetPosX(), (*itr)->GetPosY(), (*itr)->GetPosZ(), + ItemTypeToString(EntityBlockType).c_str(), EntityBlockType, + ItemTypeToString(WorldBlockType).c_str(), WorldBlockType + ); + cBlockEntityList::iterator itr2 = itr; + itr2++; + m_BlockEntities.erase(itr); + delete *itr; + itr = itr2; + } + else + { + // Good blocktype, keep the block entity: + ++itr; + } + } // for itr - m_BlockEntities[] +} + + + + diff --git a/src/SetChunkData.h b/src/SetChunkData.h index a2f776f6b..03e9ef4d9 100644 --- a/src/SetChunkData.h +++ b/src/SetChunkData.h @@ -92,6 +92,9 @@ public: /** Calculates the heightmap based on the contained blocktypes and marks it valid. */ void CalculateHeightMap(void); + /** Removes the block entities that don't have a proper blocktype at their corresponding coords. */ + void RemoveInvalidBlockEntities(void); + protected: int m_ChunkX; int m_ChunkZ; diff --git a/src/World.cpp b/src/World.cpp index 69d1217f1..b01e53638 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3484,14 +3484,16 @@ void cWorld::cChunkGeneratorCallbacks::OnChunkGenerated(cChunkDesc & a_ChunkDesc cChunkDef::BlockNibbles BlockMetas; a_ChunkDesc.CompressBlockMetas(BlockMetas); - m_World->QueueSetChunkData(cSetChunkDataPtr(new cSetChunkData( + cSetChunkDataPtr SetChunkData(new cSetChunkData( a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_ChunkDesc.GetBlockTypes(), BlockMetas, NULL, NULL, // We don't have lighting, chunk will be lighted when needed &a_ChunkDesc.GetHeightMap(), &a_ChunkDesc.GetBiomeMap(), a_ChunkDesc.GetEntities(), a_ChunkDesc.GetBlockEntities(), true - ))); + )); + SetChunkData->RemoveInvalidBlockEntities(); + m_World->QueueSetChunkData(SetChunkData); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index a9c9ae4b5..5978e5ef8 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -396,7 +396,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT } // for y //*/ - m_World->QueueSetChunkData(cSetChunkDataPtr(new cSetChunkData( + cSetChunkDataPtr SetChunkData(new cSetChunkData( a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, BlockTypes, MetaData, IsLightValid ? BlockLight : NULL, @@ -404,7 +404,8 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT NULL, Biomes, Entities, BlockEntities, false - ))); + )); + m_World->QueueSetChunkData(SetChunkData); return true; } @@ -581,64 +582,32 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con { continue; } - int sID = a_NBT.FindChildByName(Child, "id"); - if (sID < 0) + + // Get the BlockEntity's position + int x, y, z; + if (!GetBlockEntityNBTPos(a_NBT, Child, x, y, z)) { + LOGWARNING("Bad block entity, missing the coords. Will be ignored."); continue; } - if (strncmp(a_NBT.GetData(sID), "Beacon", a_NBT.GetDataLength(sID)) == 0) - { - LoadBeaconFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0) - { - LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_CHEST); - } - else if (strncmp(a_NBT.GetData(sID), "Control", a_NBT.GetDataLength(sID)) == 0) - { - LoadCommandBlockFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Dropper", a_NBT.GetDataLength(sID)) == 0) - { - LoadDropperFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "FlowerPot", a_NBT.GetDataLength(sID)) == 0) - { - LoadFlowerPotFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0) - { - LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child, a_BlockTypes, a_BlockMetas); - } - else if (strncmp(a_NBT.GetData(sID), "Hopper", a_NBT.GetDataLength(sID)) == 0) - { - LoadHopperFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Music", a_NBT.GetDataLength(sID)) == 0) - { - LoadNoteFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "RecordPlayer", a_NBT.GetDataLength(sID)) == 0) - { - LoadJukeboxFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Sign", a_NBT.GetDataLength(sID)) == 0) - { - LoadSignFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Skull", a_NBT.GetDataLength(sID)) == 0) - { - LoadMobHeadFromNBT(a_BlockEntities, a_NBT, Child); - } - else if (strncmp(a_NBT.GetData(sID), "Trap", a_NBT.GetDataLength(sID)) == 0) + int RelX = x, RelY = y, RelZ = z, ChunkX, ChunkZ; + cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); + if (RelY == 2) { - LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child); + LOGD("HERE"); } - else if (strncmp(a_NBT.GetData(sID), "TrappedChest", a_NBT.GetDataLength(sID)) == 0) + + // Load the proper BlockEntity type based on the block type: + BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, RelY, RelZ); + NIBBLETYPE BlockMeta = cChunkDef::GetNibble(a_BlockMetas, RelX, RelY, RelZ); + std::auto_ptr be(LoadBlockEntityFromNBT(a_NBT, Child, x, y, z, BlockType, BlockMeta)); + if (be.get() == NULL) { - LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_TRAPPED_CHEST); + continue; } - // TODO: Other block entities + + // Add the BlockEntity to the loaded data: + a_BlockEntities.push_back(be.release()); } // for Child - tag children } @@ -646,6 +615,52 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con +cBlockEntity * cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + // Load the specific BlockEntity type: + switch (a_BlockType) + { + // Specific entity loaders: + case E_BLOCK_BEACON: return LoadBeaconFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_CHEST); + case E_BLOCK_COMMAND_BLOCK: return LoadCommandBlockFromNBT(a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_DISPENSER: return LoadDispenserFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_DROPPER: return LoadDropperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_FLOWER_POT: return LoadFlowerPotFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FURNACE, a_BlockMeta); + case E_BLOCK_HEAD: return LoadMobHeadFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_HOPPER: return LoadHopperFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_JUKEBOX: return LoadJukeboxFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_LIT_FURNACE: return LoadFurnaceFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LIT_FURNACE, a_BlockMeta); + case E_BLOCK_NOTE_BLOCK: return LoadNoteBlockFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ); + case E_BLOCK_SIGN_POST: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SIGN_POST); + case E_BLOCK_TRAPPED_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_TRAPPED_CHEST); + case E_BLOCK_WALLSIGN: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WALLSIGN); + + // Blocktypes that have block entities but don't load their contents from disk: + case E_BLOCK_ENDER_CHEST: return NULL; + } + + // All the other blocktypes should have no entities assigned to them. Report an error: + // Get the "id" tag: + int TagID = a_NBT.FindChildByName(a_Tag, "id"); + AString TypeName(""); + if (TagID >= 0) + { + TypeName.assign(a_NBT.GetData(TagID), (size_t)a_NBT.GetDataLength(TagID)); + } + LOGINFO("WorldLoader(%s): Block entity mismatch: block type %s (%d), type \"%s\", at {%d, %d, %d}; the entity will be lost.", + m_World->GetName().c_str(), + ItemTypeToString(a_BlockType).c_str(), a_BlockType, TypeName.c_str(), + a_BlockX, a_BlockY, a_BlockZ + ); + return NULL; +} + + + + + bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx) { int Type = a_NBT.FindChildByName(a_TagIdx, "id"); @@ -656,7 +671,6 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_ a_Item.m_ItemType = a_NBT.GetShort(Type); if (a_Item.m_ItemType < 0) { - LOGD("Encountered an item with negative type (%d). Replacing with an empty item.", a_NBT.GetShort(Type)); a_Item.Empty(); return true; } @@ -754,16 +768,46 @@ void cWSSAnvil::LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a -void cWSSAnvil::LoadBeaconFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the given tag is a compound: + if (a_NBT.GetType(a_TagIdx) != TAG_Compound) { - return; + return false; } - std::auto_ptr Beacon(new cBeaconEntity(x, y, z, m_World)); + // Get the "id" tag: + int TagID = a_NBT.FindChildByName(a_TagIdx, "id"); + if (TagID < 0) + { + return false; + } + + // Compare the value: + if (strncmp(a_NBT.GetData(TagID), a_ExpectedType, (size_t)a_NBT.GetDataLength(TagID)) == 0) + { + return true; + } + LOGWARNING("Block entity type mismatch: exp \"%s\", got \"%s\".", + a_ExpectedType, + AString(a_NBT.GetData(TagID), (size_t)a_NBT.GetDataLength(TagID)).c_str() + ); + return false; +} + + + + + +cBlockEntity * cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Beacon")) + { + return NULL; + } + + std::auto_ptr Beacon(new cBeaconEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); int CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Levels"); if (CurrentLine >= 0) @@ -790,88 +834,128 @@ void cWSSAnvil::LoadBeaconFromNBT(cBlockEntityList & a_BlockEntities, const cPar LoadItemGridFromNBT(Beacon->GetContents(), a_NBT, Items); } - a_BlockEntities.push_back(Beacon.release()); + return Beacon.release(); } -void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType) +cBlockEntity * cWSSAnvil::LoadChestFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_ChestBlockType) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + // TODO: Does vanilla use "TrappedChest" or not? MCWiki says no, but previous code says yes + // Ref.: http://minecraft.gamepedia.com/Trapped_Chest + // https://github.com/mc-server/MCServer/blob/d0551e2e0a98a28f31a88d489d17b408e4a7d38d/src/WorldStorage/WSSAnvil.cpp#L637 + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Chest") && !CheckBlockEntityType(a_NBT, a_TagIdx, "TrappedChest")) { - return; + return NULL; } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this + return NULL; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this } - std::auto_ptr Chest(new cChestEntity(x, y, z, m_World, a_ChestType)); + std::auto_ptr Chest(new cChestEntity(a_BlockX, a_BlockY, a_BlockZ, m_World, a_ChestBlockType)); LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items); - a_BlockEntities.push_back(Chest.release()); + return Chest.release(); } -void cWSSAnvil::LoadDispenserFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Control")) { - return; + return NULL; + } + + std::auto_ptr CmdBlock(new cCommandBlockEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + + int currentLine = a_NBT.FindChildByName(a_TagIdx, "Command"); + if (currentLine >= 0) + { + CmdBlock->SetCommand(a_NBT.GetString(currentLine)); + } + + currentLine = a_NBT.FindChildByName(a_TagIdx, "SuccessCount"); + if (currentLine >= 0) + { + CmdBlock->SetResult(a_NBT.GetInt(currentLine)); + } + + currentLine = a_NBT.FindChildByName(a_TagIdx, "LastOutput"); + if (currentLine >= 0) + { + CmdBlock->SetLastOutput(a_NBT.GetString(currentLine)); + } + + // TODO 2014-01-18 xdot: Figure out what TrackOutput is and parse it. + + return CmdBlock.release(); +} + + + + + +cBlockEntity * cWSSAnvil::LoadDispenserFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Trap")) + { + return NULL; } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this + return NULL; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this } - std::auto_ptr Dispenser(new cDispenserEntity(x, y, z, m_World)); + std::auto_ptr Dispenser(new cDispenserEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Dispenser->GetContents(), a_NBT, Items); - a_BlockEntities.push_back(Dispenser.release()); + return Dispenser.release(); } -void cWSSAnvil::LoadDropperFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadDropperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Dropper")) { - return; + return NULL; } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this + return NULL; // Make it an empty dropper - the chunk loader will provide an empty cDropperEntity for this } - std::auto_ptr Dropper(new cDropperEntity(x, y, z, m_World)); + std::auto_ptr Dropper(new cDropperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Dropper->GetContents(), a_NBT, Items); - a_BlockEntities.push_back(Dropper.release()); + return Dropper.release(); } -void cWSSAnvil::LoadFlowerPotFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadFlowerPotFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "FlowerPot")) { - return; + return NULL; } - std::auto_ptr FlowerPot(new cFlowerPotEntity(x, y, z, m_World)); + + std::auto_ptr FlowerPot(new cFlowerPotEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); short ItemType = 0, ItemData = 0; int currentLine = a_NBT.FindChildByName(a_TagIdx, "Item"); @@ -887,37 +971,28 @@ void cWSSAnvil::LoadFlowerPotFromNBT(cBlockEntityList & a_BlockEntities, const c } FlowerPot->SetItem(cItem(ItemType, 1, ItemData)); - a_BlockEntities.push_back(FlowerPot.release()); + return FlowerPot.release(); } -void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas) +cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Furnace")) { - return; + return NULL; } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this + return NULL; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this } - // Convert coords to relative: - int RelX = x; - int RelZ = z; - int ChunkX, ChunkZ; - cChunkDef::AbsoluteToRelative(RelX, y, RelZ, ChunkX, ChunkZ); - - // Create the furnace entity, with proper BlockType and BlockMeta info: - BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, y, RelZ); - NIBBLETYPE BlockMeta = cChunkDef::GetNibble(a_BlockMetas, RelX, y, RelZ); - std::auto_ptr Furnace(new cFurnaceEntity(x, y, z, BlockType, BlockMeta, m_World)); + std::auto_ptr Furnace(new cFurnaceEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World)); // Load slots: for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) @@ -954,184 +1029,147 @@ void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cPa // Restart cooking: Furnace->ContinueCooking(); - a_BlockEntities.push_back(Furnace.release()); + return Furnace.release(); } -void cWSSAnvil::LoadHopperFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadHopperFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Hopper")) { - return; + return NULL; } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) { - return; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this + return NULL; // Make it an empty hopper - the chunk loader will provide an empty cHopperEntity for this } - std::auto_ptr Hopper(new cHopperEntity(x, y, z, m_World)); + std::auto_ptr Hopper(new cHopperEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); LoadItemGridFromNBT(Hopper->GetContents(), a_NBT, Items); - a_BlockEntities.push_back(Hopper.release()); + return Hopper.release(); } -void cWSSAnvil::LoadJukeboxFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadJukeboxFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "RecordPlayer")) { - return; + return NULL; } - std::auto_ptr Jukebox(new cJukeboxEntity(x, y, z, m_World)); + + std::auto_ptr Jukebox(new cJukeboxEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); int Record = a_NBT.FindChildByName(a_TagIdx, "Record"); if (Record >= 0) { Jukebox->SetRecord(a_NBT.GetInt(Record)); } - a_BlockEntities.push_back(Jukebox.release()); -} - - - - - -void cWSSAnvil::LoadNoteFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) -{ - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) - { - return; - } - std::auto_ptr Note(new cNoteEntity(x, y, z, m_World)); - int note = a_NBT.FindChildByName(a_TagIdx, "note"); - if (note >= 0) - { - Note->SetPitch(a_NBT.GetByte(note)); - } - a_BlockEntities.push_back(Note.release()); + return Jukebox.release(); } -void cWSSAnvil::LoadSignFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadMobHeadFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Skull")) { - return; + return NULL; } - std::auto_ptr Sign(new cSignEntity(E_BLOCK_SIGN_POST, x, y, z, m_World)); - int currentLine = a_NBT.FindChildByName(a_TagIdx, "Text1"); - if (currentLine >= 0) - { - Sign->SetLine(0, a_NBT.GetString(currentLine)); - } + std::auto_ptr MobHead(new cMobHeadEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); - currentLine = a_NBT.FindChildByName(a_TagIdx, "Text2"); + int currentLine = a_NBT.FindChildByName(a_TagIdx, "SkullType"); if (currentLine >= 0) { - Sign->SetLine(1, a_NBT.GetString(currentLine)); + MobHead->SetType(static_cast(a_NBT.GetByte(currentLine))); } - currentLine = a_NBT.FindChildByName(a_TagIdx, "Text3"); + currentLine = a_NBT.FindChildByName(a_TagIdx, "Rot"); if (currentLine >= 0) { - Sign->SetLine(2, a_NBT.GetString(currentLine)); + MobHead->SetRotation(static_cast(a_NBT.GetByte(currentLine))); } - currentLine = a_NBT.FindChildByName(a_TagIdx, "Text4"); + currentLine = a_NBT.FindChildByName(a_TagIdx, "ExtraType"); if (currentLine >= 0) { - Sign->SetLine(3, a_NBT.GetString(currentLine)); + MobHead->SetOwner(a_NBT.GetString(currentLine)); } - a_BlockEntities.push_back(Sign.release()); + return MobHead.release(); } -void cWSSAnvil::LoadMobHeadFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadNoteBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) - { - return; - } - std::auto_ptr MobHead(new cMobHeadEntity(x, y, z, m_World)); - - int currentLine = a_NBT.FindChildByName(a_TagIdx, "SkullType"); - if (currentLine >= 0) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Music")) { - MobHead->SetType(static_cast(a_NBT.GetByte(currentLine))); + return NULL; } - currentLine = a_NBT.FindChildByName(a_TagIdx, "Rot"); - if (currentLine >= 0) + std::auto_ptr NoteBlock(new cNoteEntity(a_BlockX, a_BlockY, a_BlockZ, m_World)); + int note = a_NBT.FindChildByName(a_TagIdx, "note"); + if (note >= 0) { - MobHead->SetRotation(static_cast(a_NBT.GetByte(currentLine))); + NoteBlock->SetPitch(a_NBT.GetByte(note)); } - - currentLine = a_NBT.FindChildByName(a_TagIdx, "ExtraType"); - if (currentLine >= 0) - { - MobHead->SetOwner(a_NBT.GetString(currentLine)); - } - - a_BlockEntities.push_back(MobHead.release()); + return NoteBlock.release(); } -void cWSSAnvil::LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +cBlockEntity * cWSSAnvil::LoadSignFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType) { - ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); - int x, y, z; - if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + // Check if the data has a proper type: + if (!CheckBlockEntityType(a_NBT, a_TagIdx, "Sign")) { - return; + return NULL; } - std::auto_ptr CmdBlock(new cCommandBlockEntity(x, y, z, m_World)); - int currentLine = a_NBT.FindChildByName(a_TagIdx, "Command"); + std::auto_ptr Sign(new cSignEntity(a_BlockType, a_BlockX, a_BlockY, a_BlockZ, m_World)); + + int currentLine = a_NBT.FindChildByName(a_TagIdx, "Text1"); if (currentLine >= 0) { - CmdBlock->SetCommand(a_NBT.GetString(currentLine)); + Sign->SetLine(0, a_NBT.GetString(currentLine)); } - currentLine = a_NBT.FindChildByName(a_TagIdx, "SuccessCount"); + currentLine = a_NBT.FindChildByName(a_TagIdx, "Text2"); if (currentLine >= 0) { - CmdBlock->SetResult(a_NBT.GetInt(currentLine)); + Sign->SetLine(1, a_NBT.GetString(currentLine)); } - currentLine = a_NBT.FindChildByName(a_TagIdx, "LastOutput"); + currentLine = a_NBT.FindChildByName(a_TagIdx, "Text3"); if (currentLine >= 0) { - CmdBlock->SetLastOutput(a_NBT.GetString(currentLine)); + Sign->SetLine(2, a_NBT.GetString(currentLine)); } - // TODO 2014-01-18 xdot: Figure out what TrackOutput is and parse it. + currentLine = a_NBT.FindChildByName(a_TagIdx, "Text4"); + if (currentLine >= 0) + { + Sign->SetLine(3, a_NBT.GetString(currentLine)); + } - a_BlockEntities.push_back(CmdBlock.release()); + return Sign.release(); } diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index a41268f4c..591ec6757 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -125,6 +125,10 @@ protected: /// Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1) void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas); + /** Loads the data for a block entity from the specified NBT tag. + Returns the loaded block entity, or NULL upon failure. */ + cBlockEntity * LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + /// Loads a cItem contents from the specified NBT tag; returns true if successful. Doesn't load the Slot tag bool LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx); @@ -134,18 +138,21 @@ protected: */ void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0); - void LoadBeaconFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType); - void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadFlowerPotFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadFurnaceFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas); - void LoadHopperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadJukeboxFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadMobHeadFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadCommandBlockFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + /** Returns true iff the "id" child tag inside the specified tag equals the specified expected type. */ + bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType); + + cBlockEntity * LoadBeaconFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadChestFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_ChestBlockType); + cBlockEntity * LoadCommandBlockFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadDispenserFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadDropperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadFlowerPotFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadFurnaceFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + cBlockEntity * LoadHopperFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadJukeboxFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadNoteBlockFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); + cBlockEntity * LoadSignFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SignBlockType); void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, size_t a_IDTagLength); -- cgit v1.2.3 From a2bee74a13989f725e8f8ca3ffe967e157f8d77f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 29 Aug 2014 23:21:58 +0300 Subject: cChunk: Fixed the Coords param. --- src/Chunk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Chunk.h b/src/Chunk.h index e7aeff1a4..e5de22e3b 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -155,7 +155,7 @@ public: void FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta, bool a_SendToClients = true); // Doesn't force block updates on neighbors, use for simple changes such as grass growing etc. BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const; - BLOCKTYPE GetBlock(Vector3i a_RelCords) const { return GetBlock(a_RelCords.x, a_RelCords.y, a_RelCords.z);} + BLOCKTYPE GetBlock(const Vector3i & a_RelCoords) const { return GetBlock(a_RelCoords.x, a_RelCoords.y, a_RelCoords.z); } void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); -- cgit v1.2.3 From 4900645b2838b8a953fba298c5001b4e2d242931 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Sat, 30 Aug 2014 00:27:33 +0200 Subject: Added a_Digger check --- src/Blocks/BlockHandler.cpp | 59 ++++++++++++++++++++++++--------------------- src/Entities/Entity.cpp | 4 +-- 2 files changed, 33 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index c8a57906f..feb024b7f 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -433,38 +433,41 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac else { // TODO: Add a proper overridable function for this - cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; - if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && a_Digger->IsPlayer()) + if (a_Digger != NULL) { - switch (m_BlockType) + cEnchantments Enchantments = a_Digger->GetEquippedWeapon().m_Enchantments; + if ((Enchantments.GetLevel(cEnchantments::enchSilkTouch) > 0) && a_Digger->IsPlayer()) { - case E_BLOCK_CAKE: - case E_BLOCK_CARROTS: - case E_BLOCK_COCOA_POD: - case E_BLOCK_DOUBLE_STONE_SLAB: - case E_BLOCK_DOUBLE_WOODEN_SLAB: - case E_BLOCK_FIRE: - case E_BLOCK_FARMLAND: - case E_BLOCK_MELON_STEM: - case E_BLOCK_MOB_SPAWNER: - case E_BLOCK_NETHER_WART: - case E_BLOCK_POTATOES: - case E_BLOCK_PUMPKIN_STEM: - case E_BLOCK_SNOW: - case E_BLOCK_SUGARCANE: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_CROPS: + switch (m_BlockType) { - // Silktouch can't be used for this blocks - ConvertToPickups(Pickups, Meta); - break; - }; - default: Pickups.Add(m_BlockType, 1, Meta); + case E_BLOCK_CAKE: + case E_BLOCK_CARROTS: + case E_BLOCK_COCOA_POD: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_FIRE: + case E_BLOCK_FARMLAND: + case E_BLOCK_MELON_STEM: + case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_NETHER_WART: + case E_BLOCK_POTATOES: + case E_BLOCK_PUMPKIN_STEM: + case E_BLOCK_SNOW: + case E_BLOCK_SUGARCANE: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_CROPS: + { + // Silktouch can't be used for this blocks + ConvertToPickups(Pickups, Meta); + break; + }; + default: Pickups.Add(m_BlockType, 1, Meta); + } + } + else + { + Pickups.Add(m_BlockType, 1, Meta); } - } - else - { - Pickups.Add(m_BlockType, 1, Meta); } } } diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 760401cc2..10a0f8920 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -400,9 +400,9 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { cItem Item = ArmorItems[i]; - if (Item.m_Enchantments.GetLevel(cEnchantments::enchThorns) > ThornsLevel) ThornsLevel = Item.m_Enchantments.GetLevel(cEnchantments::enchThorns); + ThornsLevel = std::max(ThornsLevel, Item.m_Enchantments.GetLevel(cEnchantments::enchThorns)); } - + if (ThornsLevel > 0) { int Chance = ThornsLevel * 15; -- cgit v1.2.3 From b0a7d93ae1b3de1a6c14caf30f26682108b4a6b7 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 30 Aug 2014 22:11:09 +0200 Subject: Fixed MSVC2008 compilation. It was getting confused about which sqrt() overload to call. --- src/Entities/Minecart.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 21c58fdba..1501eea84 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -891,31 +891,31 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) ) { // Moving -X +Z - if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) + if ((-GetSpeedX() * 0.4 / sqrt(2.0)) < 0.01) { // ~ SpeedX >= 0 Immobile or not moving in the "right" direction. Give it a bump! - AddSpeedX(-4 / sqrt(2)); - AddSpeedZ(4 / sqrt(2)); + AddSpeedX(-4 / sqrt(2.0)); + AddSpeedZ(4 / sqrt(2.0)); } else { // ~ SpeedX < 0 Moving in the "right" direction. Only accelerate it a bit. - SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); - SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0)); } } - else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) + else if ((GetSpeedX() * 0.4 / sqrt(2.0)) < 0.01) { // Moving +X -Z // ~ SpeedX <= 0 Immobile or not moving in the "right" direction - AddSpeedX(4 / sqrt(2)); - AddSpeedZ(-4 / sqrt(2)); + AddSpeedX(4 / sqrt(2.0)); + AddSpeedZ(-4 / sqrt(2.0)); } else { // ~ SpeedX > 0 Moving in the "right" direction - SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); - SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0)); } break; } @@ -943,28 +943,28 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) if ((GetSpeedX() * 0.4) < 0.01) { // ~ SpeedX <= 0 Immobile or not moving in the "right" direction - AddSpeedX(4 / sqrt(2)); - AddSpeedZ(4 / sqrt(2)); + AddSpeedX(4 / sqrt(2.0)); + AddSpeedZ(4 / sqrt(2.0)); } else { // ~ SpeedX > 0 Moving in the "right" direction - SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); - SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0)); } } else if ((-GetSpeedX() * 0.4) < 0.01) { // Moving -X -Z // ~ SpeedX >= 0 Immobile or not moving in the "right" direction - AddSpeedX(-4 / sqrt(2)); - AddSpeedZ(-4 / sqrt(2)); + AddSpeedX(-4 / sqrt(2.0)); + AddSpeedZ(-4 / sqrt(2.0)); } else { // ~ SpeedX < 0 Moving in the "right" direction - SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); - SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2.0)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2.0)); } break; } -- cgit v1.2.3 From fc7da227386a1788a8b6ddaeb5ae5b52fde107be Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 30 Aug 2014 22:11:52 +0200 Subject: WSSAnvil: Removed leftover debugging code. --- src/WorldStorage/WSSAnvil.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 5978e5ef8..e79cc291d 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -592,10 +592,6 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con } int RelX = x, RelY = y, RelZ = z, ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ); - if (RelY == 2) - { - LOGD("HERE"); - } // Load the proper BlockEntity type based on the block type: BLOCKTYPE BlockType = cChunkDef::GetBlock(a_BlockTypes, RelX, RelY, RelZ); -- cgit v1.2.3 From db663c7ee1737f5e03c0bce6584933123b9d58e3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 30 Aug 2014 22:24:04 +0200 Subject: Fixed style. --- src/BlockEntities/CommandBlockEntity.cpp | 5 +++-- src/ChunkMap.cpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index fe2f5e60a..dd0858378 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -211,13 +211,14 @@ void cCommandBlockEntity::Execute() } } CmdBlockOutCb(this); - if ( // Administrator commands are not executable by command blocks + // Administrator commands are not executable by command blocks: + if ( (m_Command != "stop") && (m_Command != "restart") && (m_Command != "kick") && (m_Command != "ban") && (m_Command != "ipban") - ) + ) { cServer * Server = cRoot::Get()->GetServer(); LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str()); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 8ca61e2cf..a3692ef11 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1880,10 +1880,11 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ } else if ((m_World->GetTNTShrapnelLevel() > slNone) && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around { + // If the block is shrapnel-able, make a falling block entity out of it: if ( ((m_World->GetTNTShrapnelLevel() == slAll) && cBlockInfo::FullyOccupiesVoxel(Block)) || ((m_World->GetTNTShrapnelLevel() == slGravityAffectedOnly) && ((Block == E_BLOCK_SAND) || (Block == E_BLOCK_GRAVEL))) - ) + ) { m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, Block, area.GetBlockMeta(bx + x, by + y, bz + z)); } @@ -1891,7 +1892,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ area.SetBlockTypeMeta(bx + x, by + y, bz + z, E_BLOCK_AIR, 0); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); - break; + break; } } // switch (BlockType) } // for z -- cgit v1.2.3 From 365d2447d002747c0f43471e0d3bf42ea9d21363 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 31 Aug 2014 00:15:48 +0100 Subject: Check range of y in HasNearLog Fixes #803 --- src/Blocks/BlockLeaves.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index 972dd6232..a8aa28a0f 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -152,7 +152,7 @@ bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ) a_Area.SetBlockType(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SPONGE); for (int i = 0; i < LEAVES_CHECK_DISTANCE; i++) { - for (int y = a_BlockY - i; y <= a_BlockY + i; y++) + for (int y = std::max(a_BlockY - i, 0); y <= std::min(a_BlockY + i, 255); y++) { for (int z = a_BlockZ - i; z <= a_BlockZ + i; z++) { -- cgit v1.2.3 From 6180f7df095c228530e4c0d2bfaa90fed7b11f49 Mon Sep 17 00:00:00 2001 From: Jaume Aloy Date: Sun, 31 Aug 2014 11:28:42 +0200 Subject: Fixed style --- src/Entities/Entity.cpp | 12 +++++------- src/Entities/Player.cpp | 3 +++ src/Entities/ProjectileEntity.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 10a0f8920..e36ed6c37 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -396,7 +396,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) } int ThornsLevel = 0; - cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { cItem Item = ArmorItems[i]; @@ -428,7 +428,8 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) Player->GetStatManager().AddValue(statDamageDealt, (StatValue)floor(a_TDI.FinalDamage * 10 + 0.5)); } - if (IsPlayer()){ + if (IsPlayer()) + { double TotalEPF = 0.0; double EPFProtection = 0.00; double EPFFireProtection = 0.00; @@ -436,7 +437,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) double EPFProjectileProtection = 0.00; double EPFFeatherFalling = 0.00; - cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { cItem Item = ArmorItems[i]; @@ -469,7 +470,6 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) TotalEPF = EPFProtection + EPFFireProtection + EPFFeatherFalling + EPFBlastProtection + EPFProjectileProtection; - EPFProtection = EPFProtection / TotalEPF; EPFFireProtection = EPFFireProtection / TotalEPF; EPFFeatherFalling = EPFFeatherFalling / TotalEPF; @@ -507,8 +507,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) a_TDI.FinalDamage -= RemovedDamage; } - - + m_Health -= (short)a_TDI.FinalDamage; @@ -516,7 +515,6 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) m_Health = std::max(m_Health, 0); - if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) // Knockback for only players and mobs { int KnockbackLevel = a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback); // More common enchantment diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 8b829d090..338a87ac1 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1963,6 +1963,8 @@ void cPlayer::UseEquippedItem(int a_Amount) { return; } + + // If the item has an unbreaking enchantment, give it a random chance of not breaking: cItem Item = GetEquippedItem(); int UnbreakingLevel = Item.m_Enchantments.GetLevel(cEnchantments::enchUnbreaking); if (UnbreakingLevel > 0) @@ -1983,6 +1985,7 @@ void cPlayer::UseEquippedItem(int a_Amount) return; } } + if (GetInventory().DamageEquippedItem(a_Amount)) { m_World->BroadcastSoundEffect("random.break", GetPosX(), GetPosY(), GetPosZ(), 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index 58dc38702..990136a32 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -94,7 +94,7 @@ protected: */ struct CreatorData { - CreatorData(int a_UniqueID, const AString & a_Name, cEnchantments a_Enchantments) : + CreatorData(int a_UniqueID, const AString & a_Name, const cEnchantments & a_Enchantments) : m_UniqueID(a_UniqueID), m_Name(a_Name), m_Enchantments(a_Enchantments) -- cgit v1.2.3 From 0beed83ae9e6d8502450489edddd27171ff15b53 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 31 Aug 2014 19:00:36 +0200 Subject: Rewrited furnace.txt loading. --- src/Bindings/ManualBindings.cpp | 2 +- src/BlockEntities/FurnaceEntity.h | 2 +- src/FurnaceRecipe.cpp | 241 +++++++++++++++++--------------------- src/FurnaceRecipe.h | 33 ++---- 4 files changed, 119 insertions(+), 159 deletions(-) (limited to 'src') diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index b2c57e52d..adf10a72f 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2663,7 +2663,7 @@ static int tolua_cRoot_GetFurnaceRecipe(lua_State * tolua_S) // Get the recipe for the input cFurnaceRecipe * FR = cRoot::Get()->GetFurnaceRecipe(); - const cFurnaceRecipe::Recipe * Recipe = FR->GetRecipeFrom(*Input); + const cFurnaceRecipe::cRecipe * Recipe = FR->GetRecipeFrom(*Input); if (Recipe == NULL) { // There is no such furnace recipe for this input, return no value diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h index 4f935a74b..cf1a755e0 100644 --- a/src/BlockEntities/FurnaceEntity.h +++ b/src/BlockEntities/FurnaceEntity.h @@ -105,7 +105,7 @@ protected: NIBBLETYPE m_BlockMeta; /// The recipe for the current input slot - const cFurnaceRecipe::Recipe * m_CurrentRecipe; + const cFurnaceRecipe::cRecipe * m_CurrentRecipe; /// The item that is being smelted cItem m_LastInput; diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index ab772e97b..eb64e0a91 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -12,8 +12,8 @@ -typedef std::list< cFurnaceRecipe::Recipe > RecipeList; -typedef std::list< cFurnaceRecipe::Fuel > FuelList; +typedef std::list RecipeList; +typedef std::list FuelList; @@ -30,7 +30,7 @@ struct cFurnaceRecipe::sFurnaceRecipeState cFurnaceRecipe::cFurnaceRecipe() - : m_pState( new sFurnaceRecipeState) + : m_pState(new sFurnaceRecipeState) { ReloadRecipes(); } @@ -68,12 +68,18 @@ void cFurnaceRecipe::ReloadRecipes(void) while (std::getline(f, ParsingLine)) { LineNum++; - ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove ALL whitespace from the line if (ParsingLine.empty()) { continue; } + // Remove comments from the line: + size_t FirstCommentSymbol = ParsingLine.find('#'); + if ((FirstCommentSymbol != AString::npos) && (FirstCommentSymbol != 0)) + { + ParsingLine.erase(ParsingLine.begin() + FirstCommentSymbol, ParsingLine.end()); + } + switch (ParsingLine[0]) { case '#': @@ -105,157 +111,130 @@ void cFurnaceRecipe::ReloadRecipes(void) void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, int a_LineNum) { - // Fuel - int IItemID = 0, IItemCount = 0, IItemHealth = 0, IBurnTime = 0; - AString::size_type BeginPos = 1; // Begin at one after exclamation mark (bang) - - if ( - !ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, IItemID) || // Read item ID - !ReadOptionalNumbers(BeginPos, ":", "=", a_Line, a_LineNum, IItemCount, IItemHealth) || // Read item count (and optionally health) - !ReadMandatoryNumber(BeginPos, "0123456789", a_Line, a_LineNum, IBurnTime, true) // Read item burn time - last value - ) + AString Line(a_Line); + Line.erase(Line.begin()); // Remove the beginning "!" + Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); + + cItem * Item = new cItem(); + int BurnTime; + + const AStringVector & Sides = StringSplit(Line, "="); + if (Sides.size() != 2) { + LOGWARNING("furnace.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); return; } - // Add to fuel list: - Fuel F; - F.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth); - F.BurnTime = IBurnTime; - m_pState->Fuel.push_back(F); -} - - - - + if (!ParseItem(Sides[0], *Item)) + { + LOGWARNING("furnace.txt: line %d: Cannot parse item \"%s\".", a_LineNum, Sides[0].c_str()); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); + return; + } -void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, int a_LineNum) -{ - int IItemID = 0, IItemCount = 0, IItemHealth = 0, IBurnTime = 0; - int OItemID = 0, OItemCount = 0, OItemHealth = 0; - AString::size_type BeginPos = 0; // Begin at start of line - - if ( - !ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, IItemID) || // Read item ID - !ReadOptionalNumbers(BeginPos, ":", "@", a_Line, a_LineNum, IItemCount, IItemHealth) || // Read item count (and optionally health) - !ReadMandatoryNumber(BeginPos, "=", a_Line, a_LineNum, IBurnTime) || // Read item burn time - !ReadMandatoryNumber(BeginPos, ":", a_Line, a_LineNum, OItemID) || // Read result ID - !ReadOptionalNumbers(BeginPos, ":", "012456789", a_Line, a_LineNum, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value - ) + if (!StringToInteger(Sides[1], BurnTime)) { + LOGWARNING("furnace.txt: line %d: Cannot parse burn time.", a_LineNum); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); return; } - // Add to recipe list - Recipe R; - R.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth); - R.Out = new cItem((ENUM_ITEM_ID)OItemID, (char)OItemCount, (short)OItemHealth); - R.CookTime = IBurnTime; - m_pState->Recipes.push_back(R); + // Add to fuel list: + cFuel Fuel; + Fuel.In = Item; + Fuel.BurnTime = BurnTime; + m_pState->Fuel.push_back(Fuel); } -void cFurnaceRecipe::PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing) +void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, int a_LineNum) { - LOGWARN("Error parsing furnace recipes at line %i pos " SIZE_T_FMT ": missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str()); -} - - + AString Line(a_Line); + Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); + int CookTime = 200; + cItem * InputItem = new cItem(); + cItem * OutputItem = new cItem(); + const AStringVector & Sides = StringSplit(Line, "="); + if (Sides.size() != 2) + { + LOGWARNING("furnace.txt: line %d: A single '=' was expected, got %d", a_LineNum, (int)Sides.size() - 1); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); + return; + } -bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, unsigned int a_Line, int & a_Value, bool a_IsLastValue) -{ - // TODO: replace atoi with std::stoi - AString::size_type End; - if (a_IsLastValue) + const AStringVector & InputSplit = StringSplit(Sides[0], "@"); + if (!ParseItem(InputSplit[0], *InputItem)) { - End = a_Text.find_first_not_of(a_Delimiter, a_Begin); + LOGWARNING("furnace.txt: line %d: Cannot parse input item \"%s\".", a_LineNum, InputSplit[0].c_str()); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); + return; } - else + + if (InputSplit.size() > 1) { - End = a_Text.find_first_of(a_Delimiter, a_Begin); - if (End == AString::npos) + if (!StringToInteger(InputSplit[1], CookTime)) { - PrintParseError(a_Line, a_Begin, a_Delimiter); - return false; + LOGWARNING("furnace.txt: line %d: Cannot parse cook time \"%s\".", a_LineNum, InputSplit[1].c_str()); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); + return; } } - - // stoi won't throw an exception if the string is alphanumeric, we should check for this - if (!DoesStringContainOnlyNumbers(a_Text.substr(a_Begin, End - a_Begin))) + + if (!ParseItem(Sides[1], *OutputItem)) { - PrintParseError(a_Line, a_Begin, "number"); - return false; + LOGWARNING("furnace.txt: line %d: Cannot parse output item \"%s\".", a_LineNum, Sides[1].c_str()); + LOGINFO("Offending line: \"%s\"", a_Line.c_str()); + return; } - a_Value = atoi(a_Text.substr(a_Begin, End - a_Begin).c_str()); - a_Begin = End + 1; // Jump over delimiter - return true; + cRecipe Recipe; + Recipe.In = InputItem; + Recipe.Out = OutputItem; + Recipe.CookTime = CookTime; + m_pState->Recipes.push_back(Recipe); } -bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue) +bool cFurnaceRecipe::ParseItem(const AString & a_String, cItem & a_Item) { - // TODO: replace atoi with std::stoi - AString::size_type End, Begin = a_Begin; - - End = a_Text.find_first_of(a_DelimiterOne, Begin); - if (End != AString::npos) - { - if (DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin))) - { - a_ValueOne = std::atoi(a_Text.substr(Begin, End - Begin).c_str()); - Begin = End + 1; + AString ItemString = a_String; + + const AStringVector & SplitAmount = StringSplit(ItemString, ","); + ItemString = SplitAmount[0]; - if (a_IsLastValue) - { - End = a_Text.find_first_not_of(a_DelimiterTwo, Begin); - } - else - { - End = a_Text.find_first_of(a_DelimiterTwo, Begin); - if (End == AString::npos) - { - PrintParseError(a_Line, Begin, a_DelimiterTwo); - return false; - } - } + const AStringVector & SplitMeta = StringSplit(ItemString, ":"); + ItemString = SplitMeta[0]; - // stoi won't throw an exception if the string is alphanumeric, we should check for this - if (!DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin))) - { - PrintParseError(a_Line, Begin, "number"); - return false; - } - a_ValueTwo = atoi(a_Text.substr(Begin, End - Begin).c_str()); + if (!StringToItem(ItemString, a_Item)) + { + return false; + } - a_Begin = End + 1; // Jump over delimiter - return true; - } - else + if (SplitAmount.size() > 1) + { + if (!StringToInteger(SplitAmount[1].c_str(), a_Item.m_ItemCount)) { - return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue); + return false; } } - - return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue); -} - - - - -bool cFurnaceRecipe::DoesStringContainOnlyNumbers(const AString & a_String) -{ - // TODO: replace this with std::all_of(a_String.begin(), a_String.end(), isdigit) - return (a_String.find_first_not_of("0123456789") == AString::npos); + if (SplitMeta.size() > 1) + { + if (!StringToInteger(SplitMeta[1].c_str(), a_Item.m_ItemDamage)) + { + return false; + } + } + return true; } @@ -266,19 +245,19 @@ void cFurnaceRecipe::ClearRecipes(void) { for (RecipeList::iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr) { - Recipe R = *itr; - delete R.In; - R.In = NULL; - delete R.Out; - R.Out = NULL; + cRecipe Recipe = *itr; + delete Recipe.In; + Recipe.In = NULL; + delete Recipe.Out; + Recipe.Out = NULL; } m_pState->Recipes.clear(); for (FuelList::iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr) { - Fuel F = *itr; - delete F.In; - F.In = NULL; + cFuel Fuel = *itr; + delete Fuel.In; + Fuel.In = NULL; } m_pState->Fuel.clear(); } @@ -287,21 +266,21 @@ void cFurnaceRecipe::ClearRecipes(void) -const cFurnaceRecipe::Recipe * cFurnaceRecipe::GetRecipeFrom(const cItem & a_Ingredient) const +const cFurnaceRecipe::cRecipe * cFurnaceRecipe::GetRecipeFrom(const cItem & a_Ingredient) const { - const Recipe * BestRecipe = 0; + const cRecipe * BestRecipe = 0; for (RecipeList::const_iterator itr = m_pState->Recipes.begin(); itr != m_pState->Recipes.end(); ++itr) { - const Recipe & R = *itr; - if ((R.In->m_ItemType == a_Ingredient.m_ItemType) && (R.In->m_ItemCount <= a_Ingredient.m_ItemCount)) + const cRecipe & Recipe = *itr; + if ((Recipe.In->m_ItemType == a_Ingredient.m_ItemType) && (Recipe.In->m_ItemCount <= a_Ingredient.m_ItemCount)) { - if (BestRecipe && (BestRecipe->In->m_ItemCount > R.In->m_ItemCount)) + if (BestRecipe && (BestRecipe->In->m_ItemCount > Recipe.In->m_ItemCount)) { continue; } else { - BestRecipe = &R; + BestRecipe = &Recipe; } } } @@ -317,16 +296,16 @@ int cFurnaceRecipe::GetBurnTime(const cItem & a_Fuel) const int BestFuel = 0; for (FuelList::const_iterator itr = m_pState->Fuel.begin(); itr != m_pState->Fuel.end(); ++itr) { - const Fuel & F = *itr; - if ((F.In->m_ItemType == a_Fuel.m_ItemType) && (F.In->m_ItemCount <= a_Fuel.m_ItemCount)) + const cFuel & Fuel = *itr; + if ((Fuel.In->m_ItemType == a_Fuel.m_ItemType) && (Fuel.In->m_ItemCount <= a_Fuel.m_ItemCount)) { - if (BestFuel > 0 && (BestFuel > F.BurnTime)) + if (BestFuel > 0 && (BestFuel > Fuel.BurnTime)) { continue; } else { - BestFuel = F.BurnTime; + BestFuel = Fuel.BurnTime; } } } diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index 77ed35a57..de3ee56a0 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -19,23 +19,23 @@ public: void ReloadRecipes(void); - struct Fuel + struct cFuel { cItem * In; int BurnTime; ///< How long this fuel burns, in ticks }; - struct Recipe + struct cRecipe { cItem * In; cItem * Out; int CookTime; ///< How long this recipe takes to smelt, in ticks }; - /// Returns a recipe for the specified input, NULL if no recipe found - const Recipe * GetRecipeFrom(const cItem & a_Ingredient) const; + /** Returns a recipe for the specified input, NULL if no recipe found */ + const cRecipe * GetRecipeFrom(const cItem & a_Ingredient) const; - /// Returns the amount of time that the specified fuel burns, in ticks + /** Returns the amount of time that the specified fuel burns, in ticks */ int GetBurnTime(const cItem & a_Fuel) const; private: @@ -49,27 +49,8 @@ private: Logs a warning to the console on input error. */ void AddRecipeFromLine(const AString & a_Line, int a_LineNum); - /** Calls LOGWARN with the line, position, and error */ - static void PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing); - - /** Reads a number from a string given, starting at a given position and ending at a delimiter given - Updates beginning position to the delimiter found + 1, and updates the value to the one read - If it encounters a substring that is not fully numeric, it will call SetParseError() and return false; the caller should abort processing - Otherwise, the function will return true - */ - static bool ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, unsigned int a_Line, int & a_Value, bool a_IsLastValue = false); - - /** Reads two numbers from a string given, starting at a given position and ending at the first delimiter given, then again (with an updated position) until the second delimiter given - Updates beginning position to the second delimiter found + 1, and updates the values to the ones read - If it encounters a substring that is not fully numeric whilst reading the second value, it will call SetParseError() and return false; the caller should abort processing - If this happens whilst reading the first value, it will call ReadMandatoryNumber() with the appropriate position, as this may legitimately occur with the optional value and AString::find_first_of finding the incorrect delimiter. It will return the result of ReadMandatoryNumber() - True will be returned definitively for an optional value that is valid - */ - static bool ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue = false); - - /** Uses std::all_of to determine if a string contains only digits */ - static bool DoesStringContainOnlyNumbers(const AString & a_String); - + /** Parses an item string in the format "[^][,]", returns true if successful. */ + bool ParseItem(const AString & a_String, cItem & a_Item); struct sFurnaceRecipeState; sFurnaceRecipeState * m_pState; -- cgit v1.2.3 From 66417f7a48c36b63a73d8fddc147ef5b90a91e09 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 31 Aug 2014 19:29:54 +0200 Subject: Fixed wrong doxy-comment. --- src/FurnaceRecipe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index de3ee56a0..e3840d0d9 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -49,7 +49,7 @@ private: Logs a warning to the console on input error. */ void AddRecipeFromLine(const AString & a_Line, int a_LineNum); - /** Parses an item string in the format "[^][,]", returns true if successful. */ + /** Parses an item string in the format "[:][,]", returns true if successful. */ bool ParseItem(const AString & a_String, cItem & a_Item); struct sFurnaceRecipeState; -- cgit v1.2.3 From 0d392f53ed5ef96886003afd90c6ce37c16dc7d3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 31 Aug 2014 20:53:41 +0200 Subject: Fixed compile warnings. --- src/FurnaceRecipe.cpp | 6 +++--- src/FurnaceRecipe.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index eb64e0a91..eec76fa4a 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -77,7 +77,7 @@ void cFurnaceRecipe::ReloadRecipes(void) size_t FirstCommentSymbol = ParsingLine.find('#'); if ((FirstCommentSymbol != AString::npos) && (FirstCommentSymbol != 0)) { - ParsingLine.erase(ParsingLine.begin() + FirstCommentSymbol, ParsingLine.end()); + ParsingLine.erase(ParsingLine.begin() + (const long)FirstCommentSymbol, ParsingLine.end()); } switch (ParsingLine[0]) @@ -109,7 +109,7 @@ void cFurnaceRecipe::ReloadRecipes(void) -void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, int a_LineNum) +void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, unsigned int a_LineNum) { AString Line(a_Line); Line.erase(Line.begin()); // Remove the beginning "!" @@ -151,7 +151,7 @@ void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, int a_LineNum) -void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, int a_LineNum) +void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_LineNum) { AString Line(a_Line); Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index e3840d0d9..207480fa9 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -43,11 +43,11 @@ private: /** Parses the fuel contained in the line, adds it to m_pState's fuels. Logs a warning to the console on input error. */ - void AddFuelFromLine(const AString & a_Line, int a_LineNum); + void AddFuelFromLine(const AString & a_Line, unsigned int a_LineNum); /** Parses the recipe contained in the line, adds it to m_pState's recipes. Logs a warning to the console on input error. */ - void AddRecipeFromLine(const AString & a_Line, int a_LineNum); + void AddRecipeFromLine(const AString & a_Line, unsigned int a_LineNum); /** Parses an item string in the format "[:][,]", returns true if successful. */ bool ParseItem(const AString & a_String, cItem & a_Item); -- cgit v1.2.3 From b6d77d9679b7b26f31d6249b66b49d52eabe5bb6 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 31 Aug 2014 20:26:08 +0100 Subject: Init RankMgr pointer to NULL --- src/Protocol/MojangAPI.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 4e5c41a8a..28da83c31 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -158,7 +158,8 @@ cMojangAPI::cMojangAPI(void) : m_NameToUUIDServer(DEFAULT_NAME_TO_UUID_SERVER), m_NameToUUIDAddress(DEFAULT_NAME_TO_UUID_ADDRESS), m_UUIDToProfileServer(DEFAULT_UUID_TO_PROFILE_SERVER), - m_UUIDToProfileAddress(DEFAULT_UUID_TO_PROFILE_ADDRESS) + m_UUIDToProfileAddress(DEFAULT_UUID_TO_PROFILE_ADDRESS), + m_RankMgr(NULL) { } -- cgit v1.2.3 From 3e7332c70ceb372afcd2abf431c6b4c222fe9359 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 31 Aug 2014 20:28:41 +0100 Subject: Delete the entity before removing from the list Old code was calling dereference on invalid iterator --- src/SetChunkData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp index 97903074a..bfe59fbcb 100644 --- a/src/SetChunkData.cpp +++ b/src/SetChunkData.cpp @@ -134,8 +134,8 @@ void cSetChunkData::RemoveInvalidBlockEntities(void) ); cBlockEntityList::iterator itr2 = itr; itr2++; - m_BlockEntities.erase(itr); delete *itr; + m_BlockEntities.erase(itr); itr = itr2; } else -- cgit v1.2.3 From af125d2a61096c6eef97d86bc815196c8d5275de Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 31 Aug 2014 22:04:52 +0200 Subject: Use std::auto_ptr --- src/FurnaceRecipe.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index eec76fa4a..d200ef3d7 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -115,7 +115,7 @@ void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, unsigned int a_Line Line.erase(Line.begin()); // Remove the beginning "!" Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); - cItem * Item = new cItem(); + std::auto_ptr Item(new cItem); int BurnTime; const AStringVector & Sides = StringSplit(Line, "="); @@ -142,7 +142,7 @@ void cFurnaceRecipe::AddFuelFromLine(const AString & a_Line, unsigned int a_Line // Add to fuel list: cFuel Fuel; - Fuel.In = Item; + Fuel.In = Item.release(); Fuel.BurnTime = BurnTime; m_pState->Fuel.push_back(Fuel); } @@ -157,8 +157,8 @@ void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_Li Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); int CookTime = 200; - cItem * InputItem = new cItem(); - cItem * OutputItem = new cItem(); + std::auto_ptr InputItem(new cItem()); + std::auto_ptr OutputItem(new cItem()); const AStringVector & Sides = StringSplit(Line, "="); if (Sides.size() != 2) @@ -194,8 +194,8 @@ void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_Li } cRecipe Recipe; - Recipe.In = InputItem; - Recipe.Out = OutputItem; + Recipe.In = InputItem.release(); + Recipe.Out = OutputItem.release(); Recipe.CookTime = CookTime; m_pState->Recipes.push_back(Recipe); } -- cgit v1.2.3 From 361b7d5379faf59140befa9d3a6c88fcad75535b Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 31 Aug 2014 21:14:42 +0100 Subject: Changed null check to assert Changed the null check to clarify that the function should not be called before the entity has been attached to a world. --- src/BlockEntities/CommandBlockEntity.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index dd0858378..43cdb92fb 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -188,12 +188,10 @@ void cCommandBlockEntity::SaveToJson(Json::Value & a_Value) void cCommandBlockEntity::Execute() { - if (m_World != NULL) + ASSERT(m_World != NULL); //Execute should not be called before the command block is attached to a world + if (!m_World->AreCommandBlocksEnabled()) { - if (!m_World->AreCommandBlocksEnabled()) - { - return; - } + return; } class CommandBlockOutCb : -- cgit v1.2.3 From 468c2558d632bb5702c12577c74967c50327accf Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 31 Aug 2014 21:26:02 +0100 Subject: Removed isDone check The same data is returned by executeStep so why execute a call when you have the data. --- src/RankManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/RankManager.cpp b/src/RankManager.cpp index dc6eec9e4..e5896f8f3 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -477,8 +477,8 @@ AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) { SQLite::Statement stmt(m_DB, "SELECT Rank.Name FROM Rank LEFT JOIN PlayerRank ON Rank.RankID = PlayerRank.RankID WHERE PlayerRank.PlayerUUID = ?"); stmt.bind(1, a_PlayerUUID); - stmt.executeStep(); - if (stmt.isDone()) + // executeStep returns false on no data + if (!stmt.executeStep()) { // No data returned from the DB return AString(); -- cgit v1.2.3 From 1e60265a909884df3c440e298d1400889c07b5fb Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 13:33:17 +0200 Subject: Fixed style. --- src/BlockEntities/CommandBlockEntity.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 43cdb92fb..20702a9ac 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -188,7 +188,8 @@ void cCommandBlockEntity::SaveToJson(Json::Value & a_Value) void cCommandBlockEntity::Execute() { - ASSERT(m_World != NULL); //Execute should not be called before the command block is attached to a world + ASSERT(m_World != NULL); // Execute should not be called before the command block is attached to a world + if (!m_World->AreCommandBlocksEnabled()) { return; -- cgit v1.2.3 From ea39c1d21cab2533504172f735e46b28664c8327 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 13:43:10 +0200 Subject: Avoid false positive in style check. --- src/FurnaceRecipe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index 207480fa9..6a1650695 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -49,7 +49,7 @@ private: Logs a warning to the console on input error. */ void AddRecipeFromLine(const AString & a_Line, unsigned int a_LineNum); - /** Parses an item string in the format "[:][,]", returns true if successful. */ + /** Parses an item string in the format "[: ][, ]", returns true if successful. */ bool ParseItem(const AString & a_String, cItem & a_Item); struct sFurnaceRecipeState; -- cgit v1.2.3 From f22f67a63ced1e99abafd09026b1b4955fb3664e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 14:29:13 +0200 Subject: Fixed MSVC warning. --- src/Entities/ArrowEntity.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index c3e7c5d79..954e0a267 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -114,8 +114,8 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) int PowerLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPower); if (PowerLevel > 0) { - int ExtraDamage = 0.25 * (PowerLevel + 1); - Damage += ceil(ExtraDamage); + int ExtraDamage = (int)ceil(0.25 * (PowerLevel + 1)); + Damage += ExtraDamage; } int KnockbackAmount = 1; -- cgit v1.2.3 From 7d8a474f13c97186eb6d17b3dcf36dd225436fae Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 14:31:05 +0200 Subject: Fixed MSVC compilation, improved performance. We're not creating copies of the equipped items anymore, rather, we're using pointers to them. Also pow() is needlessly slow for a simple second power, and MSVC2008 was confused about the pow() overloads. --- src/Entities/Entity.cpp | 89 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index e36ed6c37..dde45c360 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -317,7 +317,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) // IsOnGround() only is false if the player is moving downwards // TODO: Better damage increase, and check for enchantments (and use magic critical instead of plain) - cEnchantments Enchantments = Player->GetEquippedItem().m_Enchantments; + const cEnchantments & Enchantments = Player->GetEquippedItem().m_Enchantments; int SharpnessLevel = Enchantments.GetLevel(cEnchantments::enchSharpness); int SmiteLevel = Enchantments.GetLevel(cEnchantments::enchSmite); @@ -325,7 +325,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) if (SharpnessLevel > 0) { - a_TDI.FinalDamage += 1.25 * SharpnessLevel; + a_TDI.FinalDamage += (int)ceil(1.25 * SharpnessLevel); } else if (SmiteLevel > 0) { @@ -339,7 +339,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtWither: case cMonster::mtZombiePigman: { - a_TDI.FinalDamage += 2.5 * SmiteLevel; + a_TDI.FinalDamage += (int)ceil(2.5 * SmiteLevel); break; } } @@ -356,7 +356,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtCaveSpider: case cMonster::mtSilverfish: { - a_TDI.RawDamage += 2.5 * BaneOfArthropodsLevel; + a_TDI.RawDamage += (int)ceil(2.5 * BaneOfArthropodsLevel); // TODO: Add slowness effect break; @@ -396,11 +396,11 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) } int ThornsLevel = 0; - const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + const cItem * ArmorItems[] = { &GetEquippedHelmet(), &GetEquippedChestplate(), &GetEquippedLeggings(), &GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { - cItem Item = ArmorItems[i]; - ThornsLevel = std::max(ThornsLevel, Item.m_Enchantments.GetLevel(cEnchantments::enchThorns)); + const cItem * Item = ArmorItems[i]; + ThornsLevel = std::max(ThornsLevel, Item->m_Enchantments.GetLevel(cEnchantments::enchThorns)); } if (ThornsLevel > 0) @@ -437,33 +437,38 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) double EPFProjectileProtection = 0.00; double EPFFeatherFalling = 0.00; - const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; + const cItem * ArmorItems[] = { &GetEquippedHelmet(), &GetEquippedChestplate(), &GetEquippedLeggings(), &GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { - cItem Item = ArmorItems[i]; - if (Item.m_Enchantments.GetLevel(cEnchantments::enchProtection) > 0) + const cItem * Item = ArmorItems[i]; + int Level = Item->m_Enchantments.GetLevel(cEnchantments::enchProtection); + if (Level > 0) { - EPFProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchProtection), 2)) * 0.75 / 3; + EPFProtection += (6 + Level * Level) * 0.75 / 3; } - if (Item.m_Enchantments.GetLevel(cEnchantments::enchFireProtection) > 0) + Level = Item->m_Enchantments.GetLevel(cEnchantments::enchFireProtection); + if (Level > 0) { - EPFFireProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchFireProtection), 2)) * 1.25 / 3; + EPFFireProtection += (6 + Level * Level) * 1.25 / 3; } - if (Item.m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling) > 0) + Level = Item->m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling); + if (Level > 0) { - EPFFeatherFalling += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling), 2)) * 2.5 / 3; + EPFFeatherFalling += (6 + Level * Level) * 2.5 / 3; } - if (Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection) > 0) + Level = Item->m_Enchantments.GetLevel(cEnchantments::enchBlastProtection); + if (Level > 0) { - EPFBlastProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection), 2)) * 1.5 / 3; + EPFBlastProtection += (6 + Level * Level) * 1.5 / 3; } - if (Item.m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection) > 0) + Level = Item->m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection); + if (Level > 0) { - EPFProjectileProtection += (6 + pow(Item.m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection), 2)) * 1.5 / 3; + EPFProjectileProtection += (6 + Level * Level) * 1.5 / 3; } } @@ -476,14 +481,20 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) EPFBlastProtection = EPFBlastProtection / TotalEPF; EPFProjectileProtection = EPFProjectileProtection / TotalEPF; - if (TotalEPF > 25) TotalEPF = 25; + if (TotalEPF > 25) + { + TotalEPF = 25; + } cFastRandom Random; - float RandomValue = Random.GenerateRandomInteger(50, 100) * 0.01; + float RandomValue = Random.GenerateRandomInteger(50, 100) * 0.01f; TotalEPF = ceil(TotalEPF * RandomValue); - if (TotalEPF > 20) TotalEPF = 20; + if (TotalEPF > 20) + { + TotalEPF = 20; + } EPFProtection = TotalEPF * EPFProtection; EPFFireProtection = TotalEPF * EPFFireProtection; @@ -493,21 +504,38 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) int RemovedDamage = 0; - if (a_TDI.DamageType != dtInVoid) RemovedDamage += ceil(EPFProtection * 0.04 * a_TDI.FinalDamage); + if ((a_TDI.DamageType != dtInVoid) && (a_TDI.DamageType != dtAdmin)) + { + RemovedDamage += (int)ceil(EPFProtection * 0.04 * a_TDI.FinalDamage); + } - if ((a_TDI.DamageType == dtFalling) || (a_TDI.DamageType == dtFall) || (a_TDI.DamageType == dtEnderPearl)) RemovedDamage += ceil(EPFFeatherFalling * 0.04 * a_TDI.FinalDamage); + if ((a_TDI.DamageType == dtFalling) || (a_TDI.DamageType == dtFall) || (a_TDI.DamageType == dtEnderPearl)) + { + RemovedDamage += (int)ceil(EPFFeatherFalling * 0.04 * a_TDI.FinalDamage); + } - if (a_TDI.DamageType == dtBurning) RemovedDamage += ceil(EPFFireProtection * 0.04 * a_TDI.FinalDamage); + if (a_TDI.DamageType == dtBurning) + { + RemovedDamage += (int)ceil(EPFFireProtection * 0.04 * a_TDI.FinalDamage); + } - if (a_TDI.DamageType == dtExplosion) RemovedDamage += ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + if (a_TDI.DamageType == dtExplosion) + { + RemovedDamage += (int)ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + } - if (a_TDI.DamageType == dtProjectile) RemovedDamage += ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + if (a_TDI.DamageType == dtProjectile) + { + RemovedDamage += (int)ceil(EPFBlastProtection * 0.04 * a_TDI.FinalDamage); + } - if (a_TDI.FinalDamage < RemovedDamage) RemovedDamage = 0; + if (a_TDI.FinalDamage < RemovedDamage) + { + RemovedDamage = 0; + } a_TDI.FinalDamage -= RemovedDamage; } - m_Health -= (short)a_TDI.FinalDamage; @@ -515,7 +543,8 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) m_Health = std::max(m_Health, 0); - if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) // Knockback for only players and mobs + // Add knockback: + if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != NULL)) { int KnockbackLevel = a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback); // More common enchantment if (KnockbackLevel < 1) -- cgit v1.2.3 From 8821c476bb57a7fe4f45b0ff755394faa378fbef Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 14:35:52 +0200 Subject: Fixed previous commit's wrong assumptions. The equipment-getting functions return a copy already, so we can't take a pointer, really. --- src/Entities/Entity.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index dde45c360..89d1cffa1 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -396,11 +396,11 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) } int ThornsLevel = 0; - const cItem * ArmorItems[] = { &GetEquippedHelmet(), &GetEquippedChestplate(), &GetEquippedLeggings(), &GetEquippedBoots() }; + const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { - const cItem * Item = ArmorItems[i]; - ThornsLevel = std::max(ThornsLevel, Item->m_Enchantments.GetLevel(cEnchantments::enchThorns)); + const cItem & Item = ArmorItems[i]; + ThornsLevel = std::max(ThornsLevel, Item.m_Enchantments.GetLevel(cEnchantments::enchThorns)); } if (ThornsLevel > 0) @@ -437,35 +437,35 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) double EPFProjectileProtection = 0.00; double EPFFeatherFalling = 0.00; - const cItem * ArmorItems[] = { &GetEquippedHelmet(), &GetEquippedChestplate(), &GetEquippedLeggings(), &GetEquippedBoots() }; + const cItem ArmorItems[] = { GetEquippedHelmet(), GetEquippedChestplate(), GetEquippedLeggings(), GetEquippedBoots() }; for (size_t i = 0; i < ARRAYCOUNT(ArmorItems); i++) { - const cItem * Item = ArmorItems[i]; - int Level = Item->m_Enchantments.GetLevel(cEnchantments::enchProtection); + const cItem & Item = ArmorItems[i]; + int Level = Item.m_Enchantments.GetLevel(cEnchantments::enchProtection); if (Level > 0) { EPFProtection += (6 + Level * Level) * 0.75 / 3; } - Level = Item->m_Enchantments.GetLevel(cEnchantments::enchFireProtection); + Level = Item.m_Enchantments.GetLevel(cEnchantments::enchFireProtection); if (Level > 0) { EPFFireProtection += (6 + Level * Level) * 1.25 / 3; } - Level = Item->m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling); + Level = Item.m_Enchantments.GetLevel(cEnchantments::enchFeatherFalling); if (Level > 0) { EPFFeatherFalling += (6 + Level * Level) * 2.5 / 3; } - Level = Item->m_Enchantments.GetLevel(cEnchantments::enchBlastProtection); + Level = Item.m_Enchantments.GetLevel(cEnchantments::enchBlastProtection); if (Level > 0) { EPFBlastProtection += (6 + Level * Level) * 1.5 / 3; } - Level = Item->m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection); + Level = Item.m_Enchantments.GetLevel(cEnchantments::enchProjectileProtection); if (Level > 0) { EPFProjectileProtection += (6 + Level * Level) * 1.5 / 3; -- cgit v1.2.3 From 022f5f141dae1c97cb17a046404755a0be36c26d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 16:10:40 +0200 Subject: Fixed Bindings regeneration under MSVC. --- src/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 37657ba91..2d96662a9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -256,6 +256,11 @@ set(EXECUTABLE MCServer) if (MSVC) get_directory_property(BINDING_OUTPUTS DIRECTORY "Bindings" DEFINITION BINDING_OUTPUTS) get_directory_property(BINDING_DEPENDENCIES DIRECTORY "Bindings" DEFINITION BINDING_DEPENDENCIES) + + # The paths in BINDING_DEPENDENCIES are relative to the Bindings folder, convert them relative to this folder: + foreach (dep ${BINDING_DEPENDENCIES}) + list (APPEND BINDINGS_DEPENDENCIES "Bindings/${dep}") + endforeach(dep) ADD_CUSTOM_COMMAND( OUTPUT ${BINDING_OUTPUTS} @@ -268,7 +273,7 @@ if (MSVC) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/ # add any new generation dependencies here - DEPENDS ${BINDING_DEPENDENCIES} + DEPENDS ${BINDINGS_DEPENDENCIES} ) endif() -- cgit v1.2.3 From de30a8c8c6fac58a137a9d1faf80acc64c04050c Mon Sep 17 00:00:00 2001 From: worktycho Date: Mon, 1 Sep 2014 18:18:07 +0100 Subject: Make sure packets are valid Fixes CID 66408, 66409 and 72045 --- src/Protocol/ProtocolRecognizer.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index c831da251..8b395230a 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -979,9 +979,18 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema AString ServerAddress; short ServerPort; UInt32 NextState; - m_Buffer.ReadVarUTF8String(ServerAddress); - m_Buffer.ReadBEShort(ServerPort); - m_Buffer.ReadVarInt(NextState); + if (!m_Buffer.ReadVarUTF8String(ServerAddress)) + { + break; + } + if (!m_Buffer.ReadBEShort(ServerPort)) + { + break; + } + if (!m_Buffer.ReadVarInt(NextState)) + { + break; + } m_Buffer.CommitRead(); m_Protocol = new cProtocol172(m_Client, ServerAddress, (UInt16)ServerPort, NextState); return true; @@ -991,9 +1000,18 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema AString ServerAddress; short ServerPort; UInt32 NextState; - m_Buffer.ReadVarUTF8String(ServerAddress); - m_Buffer.ReadBEShort(ServerPort); - m_Buffer.ReadVarInt(NextState); + if (!m_Buffer.ReadVarUTF8String(ServerAddress)) + { + break; + } + if (!m_Buffer.ReadBEShort(ServerPort)) + { + break; + } + if (!m_Buffer.ReadVarInt(NextState)) + { + break; + } m_Buffer.CommitRead(); m_Protocol = new cProtocol176(m_Client, ServerAddress, (UInt16)ServerPort, NextState); return true; -- cgit v1.2.3 From 6f18d01b5148e68f640c28dc303efe3cef328a1d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 21:17:22 +0200 Subject: Fixed off-by-one errors in cChunkDef asserts. --- src/ChunkDef.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 51075ab4a..b8b4291c7 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -197,32 +197,32 @@ public: inline static int GetHeight(const HeightMap & a_HeightMap, int a_X, int a_Z) { - ASSERT((a_X >= 0) && (a_X <= Width)); - ASSERT((a_Z >= 0) && (a_Z <= Width)); + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Z >= 0) && (a_Z < Width)); return a_HeightMap[a_X + Width * a_Z]; } inline static void SetHeight(HeightMap & a_HeightMap, int a_X, int a_Z, unsigned char a_Height) { - ASSERT((a_X >= 0) && (a_X <= Width)); - ASSERT((a_Z >= 0) && (a_Z <= Width)); + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Z >= 0) && (a_Z < Width)); a_HeightMap[a_X + Width * a_Z] = a_Height; } inline static EMCSBiome GetBiome(const BiomeMap & a_BiomeMap, int a_X, int a_Z) { - ASSERT((a_X >= 0) && (a_X <= Width)); - ASSERT((a_Z >= 0) && (a_Z <= Width)); + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Z >= 0) && (a_Z < Width)); return a_BiomeMap[a_X + Width * a_Z]; } inline static void SetBiome(BiomeMap & a_BiomeMap, int a_X, int a_Z, EMCSBiome a_Biome) { - ASSERT((a_X >= 0) && (a_X <= Width)); - ASSERT((a_Z >= 0) && (a_Z <= Width)); + ASSERT((a_X >= 0) && (a_X < Width)); + ASSERT((a_Z >= 0) && (a_Z < Width)); a_BiomeMap[a_X + Width * a_Z] = a_Biome; } -- cgit v1.2.3 From b1da567f3db56f7e8ba735817eeb63dbd8d69d9e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 1 Sep 2014 21:43:03 +0200 Subject: Pickups combine only within one chunk. This greatly improves performance of the tick thread. --- src/Entities/Pickup.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index aab534f41..87b5bed07 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -150,10 +150,14 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk) } } - if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't combine into an already full pickup + // Try to combine the pickup with adjacent same-item pickups: + if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't combine if already full { + // By using a_Chunk's ForEachEntity() instead of cWorld's, pickups don't combine across chunk boundaries. + // That is a small price to pay for not having to traverse the entire world for each entity. + // The speedup in the tick thread is quite considerable. cPickupCombiningCallback PickupCombiningCallback(GetPosition(), this); - m_World->ForEachEntity(PickupCombiningCallback); // Not ForEachEntityInChunk, otherwise pickups don't combine across chunk boundaries + a_Chunk.ForEachEntity(PickupCombiningCallback); if (PickupCombiningCallback.FoundMatchingPickup()) { m_World->BroadcastEntityMetadata(*this); -- cgit v1.2.3