From e50423991e56f1edb0954f2db066acd1f27b4ed7 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 16 Jun 2014 21:57:23 +0200 Subject: [PATCH 01/58] Add bow charging animation --- src/Entities/Player.cpp | 6 +++++- src/Entities/Player.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index fdc0bb390..978517086 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1,4 +1,4 @@ - + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Player.h" @@ -411,6 +411,7 @@ void cPlayer::StartChargingBow(void) LOGD("Player \"%s\" started charging their bow", GetName().c_str()); m_IsChargingBow = true; m_BowCharge = 0; + m_World->BroadcastEntityMetadata(*this, m_ClientHandle); } @@ -423,6 +424,8 @@ int cPlayer::FinishChargingBow(void) int res = m_BowCharge; m_IsChargingBow = false; m_BowCharge = 0; + m_World->BroadcastEntityMetadata(*this, m_ClientHandle); + return res; } @@ -435,6 +438,7 @@ void cPlayer::CancelChargingBow(void) LOGD("Player \"%s\" cancelled charging their bow at a charge of %d", GetName().c_str(), m_BowCharge); m_IsChargingBow = false; m_BowCharge = 0; + m_World->BroadcastEntityMetadata(*this, m_ClientHandle); } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index b2142a18b..2f7957f16 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -404,7 +404,7 @@ public: // cEntity overrides: virtual bool IsCrouched (void) const { return m_IsCrouched; } virtual bool IsSprinting(void) const { return m_IsSprinting; } - virtual bool IsRclking (void) const { return IsEating(); } + virtual bool IsRclking (void) const { return IsEating() || IsChargingBow(); } virtual void Detach(void); From 885a50d77a26eea6619de681bf6ee746e79308cd Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 16 Jun 2014 22:57:13 +0200 Subject: [PATCH 02/58] Fix bow sound and creative arrow pickup. --- src/Entities/ArrowEntity.cpp | 32 ++++++++++++++++++++++---------- src/Items/ItemBow.h | 17 ++++++++--------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 8d2569125..bdbaaab0d 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -3,6 +3,7 @@ #include "Player.h" #include "ArrowEntity.h" #include "../Chunk.h" +#include "FastRandom.h" @@ -24,9 +25,9 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a SetYawFromSpeed(); SetPitchFromSpeed(); LOGD("Created arrow %d with speed {%.02f, %.02f, %.02f} and rot {%.02f, %.02f}", - m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(), - GetYaw(), GetPitch() - ); + m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(), + GetYaw(), GetPitch() + ); } @@ -44,6 +45,10 @@ cArrowEntity::cArrowEntity(cPlayer & a_Player, double a_Force) : m_bIsCollected(false), m_HitBlockPos(0, 0, 0) { + if (a_Player.IsGameModeCreative()) + { + m_PickupState = psInCreative; + } } @@ -120,16 +125,23 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) void cArrowEntity::CollectedBy(cPlayer * a_Dest) { - if ((m_IsInGround) && (!m_bIsCollected) && (CanPickup(*a_Dest))) + if (m_IsInGround && !m_bIsCollected && CanPickup(*a_Dest)) { - int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW); - if (NumAdded > 0) // Only play effects if there was space in inventory + if (m_PickupState == 1) { - m_World->BroadcastCollectPickup((const cPickup &)*this, *a_Dest); - // Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;) - m_World->BroadcastSoundEffect("random.pop", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); - m_bIsCollected = true; + int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW); + if (NumAdded == 0) + { + // No space in the inventory + return; + } } + + m_World->BroadcastCollectPickup((const cPickup &)*this, *a_Dest); + m_bIsCollected = true; + + cFastRandom Random; + m_World->BroadcastSoundEffect("random.pop", (int)std::floor(GetPosX() * 8.0), (int)std::floor(GetPosY() * 8), (int)std::floor(GetPosZ() * 8), 0.2F, ((Random.NextFloat(1.0F) - Random.NextFloat(1.0F)) * 0.7F + 1.0F) * 2.0F); } } diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index e0ab339d3..a8fac13cc 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -46,20 +46,17 @@ public: { // Actual shot - produce the arrow with speed based on the ticks that the bow was charged ASSERT(a_Player != NULL); - + int BowCharge = a_Player->FinishChargingBow(); - double Force = (double)BowCharge / 20; - Force = (Force * Force + 2 * Force) / 3; // This formula is used by the 1.6.2 client + double Force = (double)BowCharge / 20.0; + Force = (Force * Force + 2.0 * Force) / 3.0; // This formula is used by the 1.6.2 client if (Force < 0.1) { // Too little force, ignore the shot return; } - if (Force > 1) - { - Force = 1; - } - + Force = std::max(Force, 1.0); + // Create the arrow entity: cArrowEntity * Arrow = new cArrowEntity(*a_Player, Force * 2); if (Arrow == NULL) @@ -71,8 +68,10 @@ public: delete Arrow; return; } + + cFastRandom Random; a_Player->GetWorld()->BroadcastSpawnEntity(*Arrow); - a_Player->GetWorld()->BroadcastSoundEffect("random.bow", (int)a_Player->GetPosX() * 8, (int)a_Player->GetPosY() * 8, (int)a_Player->GetPosZ() * 8, 0.5, (float)Force); + a_Player->GetWorld()->BroadcastSoundEffect("random.bow", (int)std::floor(a_Player->GetPosX() * 8.0), (int)std::floor(a_Player->GetPosY() * 8.0), (int)std::floor(a_Player->GetPosZ() * 8.0), 1.0F, 1.0F / (Random.NextFloat(1.0F) * 0.4F + 1.2F) + (float)Force * 0.5F); if (!a_Player->IsGameModeCreative()) { From b45e85a6784861e225c7a4ecfd7838a6d32c7875 Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 16 Jun 2014 22:57:27 +0200 Subject: [PATCH 03/58] This isn't needed --- src/Items/ItemBow.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index a8fac13cc..a2f740ba7 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -70,7 +70,6 @@ public: } cFastRandom Random; - a_Player->GetWorld()->BroadcastSpawnEntity(*Arrow); a_Player->GetWorld()->BroadcastSoundEffect("random.bow", (int)std::floor(a_Player->GetPosX() * 8.0), (int)std::floor(a_Player->GetPosY() * 8.0), (int)std::floor(a_Player->GetPosZ() * 8.0), 1.0F, 1.0F / (Random.NextFloat(1.0F) * 0.4F + 1.2F) + (float)Force * 0.5F); if (!a_Player->IsGameModeCreative()) From a1fd0b0335a5b19af29a4862f4d0ac39bec6887f Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 16 Jun 2014 23:41:23 +0200 Subject: [PATCH 04/58] Split Broadcast Sound Effect function call in multiple lines. --- src/Entities/ArrowEntity.cpp | 18 ++++++++++++++++-- src/Items/ItemBow.h | 9 ++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index bdbaaab0d..7f2c8dca5 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -114,7 +114,14 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 1); // Broadcast successful hit sound - m_World->BroadcastSoundEffect("random.successful_hit", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); + m_World->BroadcastSoundEffect( + "random.successful_hit", + (int)std::floor(GetPosX() * 8.0), + (int)std::floor(GetPosY() * 8.0), + (int)std::floor(GetPosZ() * 8.0), + 0.5, + (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64) + ); Destroy(); } @@ -141,7 +148,14 @@ void cArrowEntity::CollectedBy(cPlayer * a_Dest) m_bIsCollected = true; cFastRandom Random; - m_World->BroadcastSoundEffect("random.pop", (int)std::floor(GetPosX() * 8.0), (int)std::floor(GetPosY() * 8), (int)std::floor(GetPosZ() * 8), 0.2F, ((Random.NextFloat(1.0F) - Random.NextFloat(1.0F)) * 0.7F + 1.0F) * 2.0F); + m_World->BroadcastSoundEffect( + "random.pop", + (int)std::floor(GetPosX() * 8.0), + (int)std::floor(GetPosY() * 8), + (int)std::floor(GetPosZ() * 8), + 0.2F, + ((Random.NextFloat(1.0F) - Random.NextFloat(1.0F)) * 0.7F + 1.0F) * 2.0F + ); } } diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index a2f740ba7..d79fecd30 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -70,7 +70,14 @@ public: } cFastRandom Random; - a_Player->GetWorld()->BroadcastSoundEffect("random.bow", (int)std::floor(a_Player->GetPosX() * 8.0), (int)std::floor(a_Player->GetPosY() * 8.0), (int)std::floor(a_Player->GetPosZ() * 8.0), 1.0F, 1.0F / (Random.NextFloat(1.0F) * 0.4F + 1.2F) + (float)Force * 0.5F); + a_Player->GetWorld()->BroadcastSoundEffect( + "random.bow", + (int)std::floor(a_Player->GetPosX() * 8.0), + (int)std::floor(a_Player->GetPosY() * 8.0), + (int)std::floor(a_Player->GetPosZ() * 8.0), + 1.0F, + 1.0F / (Random.NextFloat(1.0F) * 0.4F + 1.2F) + (float)Force * 0.5F + ); if (!a_Player->IsGameModeCreative()) { From d89f03b90c60c2aaae3f937f5b84dc3c8f2f6ad1 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 17 Jun 2014 12:43:45 +0200 Subject: [PATCH 05/58] Float, not Double --- src/Entities/ArrowEntity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 7f2c8dca5..ea782940a 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -119,7 +119,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) (int)std::floor(GetPosX() * 8.0), (int)std::floor(GetPosY() * 8.0), (int)std::floor(GetPosZ() * 8.0), - 0.5, + 0.5F, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64) ); From 37de63895f029342b92923d08585aa8f4fdae2ea Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 17 Jun 2014 12:45:12 +0200 Subject: [PATCH 06/58] The same: Float, not Double --- src/Entities/ArrowEntity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index ea782940a..9a8571a31 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -120,7 +120,7 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) (int)std::floor(GetPosY() * 8.0), (int)std::floor(GetPosZ() * 8.0), 0.5F, - (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64) + 0.75F + ((float)((GetUniqueID() * 23) % 32)) / 64F ); Destroy(); From ce06ec1632ffb15243e2270ed31632e8d3566f39 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 17 Jun 2014 13:33:41 +0200 Subject: [PATCH 07/58] derp --- src/Entities/ArrowEntity.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 9a8571a31..e46d21515 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -119,8 +119,8 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) (int)std::floor(GetPosX() * 8.0), (int)std::floor(GetPosY() * 8.0), (int)std::floor(GetPosZ() * 8.0), - 0.5F, - 0.75F + ((float)((GetUniqueID() * 23) % 32)) / 64F + 0.5f, + 0.75f + ((float)((GetUniqueID() * 23) % 32)) / 64.0f ); Destroy(); @@ -134,7 +134,7 @@ void cArrowEntity::CollectedBy(cPlayer * a_Dest) { if (m_IsInGround && !m_bIsCollected && CanPickup(*a_Dest)) { - if (m_PickupState == 1) + if (m_PickupState == psInSurvivalOrCreative) { int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW); if (NumAdded == 0) From 3e15c92d18c344c95bd805d7795db990258eed5a Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Fri, 20 Jun 2014 10:50:21 +0200 Subject: [PATCH 08/58] Added pig riding. Now you can ride a pig using a carrot on a stick. --- src/Mobs/Pig.cpp | 13 +++++++++++++ src/Mobs/Pig.h | 1 + 2 files changed, 14 insertions(+) diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp index e862f5aaa..ddd98eb94 100644 --- a/src/Mobs/Pig.cpp +++ b/src/Mobs/Pig.cpp @@ -76,5 +76,18 @@ void cPig::OnRightClicked(cPlayer & a_Player) } } +void cPig::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + + if (m_bIsSaddled && m_Attachee != NULL) + { + if (m_Attachee->IsPlayer() && m_Attachee->GetEquippedWeapon().m_ItemType == E_ITEM_CARROT_ON_STICK) + { + MoveToPosition((m_Attachee->GetPosition()) + (m_Attachee->GetLookVector()*10)); + m_bMovingToDestination = true; + } + } +} diff --git a/src/Mobs/Pig.h b/src/Mobs/Pig.h index d434324c1..313af2f44 100644 --- a/src/Mobs/Pig.h +++ b/src/Mobs/Pig.h @@ -19,6 +19,7 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void OnRightClicked(cPlayer & a_Player) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual const cItem GetFollowedItem(void) const override { return cItem(E_ITEM_CARROT); } From a908f39dde1dc8866bda1a85b8443ae4cdaaa2b4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 21 Jun 2014 20:33:23 +0100 Subject: [PATCH 09/58] Rewrote furnace recipe parser * Fixes #110 --- src/FurnaceRecipe.cpp | 260 ++++++++++++++++++++++++++---------------- src/FurnaceRecipe.h | 22 ++++ 2 files changed, 185 insertions(+), 97 deletions(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index bd7fd8079..b4b3d34d9 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -5,7 +5,8 @@ #include "Item.h" #include -#include + +#define FURNACE_RECIPE_FILE "furnace.txt" @@ -53,128 +54,193 @@ void cFurnaceRecipe::ReloadRecipes(void) ClearRecipes(); LOGD("Loading furnace recipes..."); - std::ifstream f; - char a_File[] = "furnace.txt"; - f.open(a_File, std::ios::in); - - if (!f.good()) + std::ifstream F(FURNACE_RECIPE_FILE, std::ios::in); + if (!F.good()) { - f.close(); - LOG("Could not open the furnace recipes file \"%s\"", a_File); + F.close(); + LOG("Could not open the furnace recipes file \"%s\"", FURNACE_RECIPE_FILE); return; } + + AString SyntaxError; + unsigned int Line = 0; + AString ParsingLine; - // TODO: Replace this messy parse with a high-level-structured one (ReadLine / ProcessLine) - bool bSyntaxError = false; - while (f.good()) + ASSERT(ParsingLine.empty()); + + while (std::getline(F, ParsingLine)) { - char c; - - ////////////////////////////////////////////////////////////////////////// - // comments - f >> c; - f.unget(); - if( c == '#' ) + Line++; + ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove whitespace + if (ParsingLine.empty()) { - while( f.good() && c != '\n' ) - { - f.get( c ); - } continue; } - - ////////////////////////////////////////////////////////////////////////// - // Line breaks - f.get( c ); - while( f.good() && ( c == '\n' || c == '\r' ) ) { f.get( c ); } - if (f.eof()) + // Comments + if (ParsingLine[0] == '#') { - break; + continue; } - f.unget(); - ////////////////////////////////////////////////////////////////////////// - // Check for fuel - f >> c; - if( c == '!' ) // It's fuel :) + if (ParsingLine[0] == '!') // Fuels start with a bang :) { - // Read item - int IItemID = 0, IItemCount = 0, IItemHealth = 0; - f >> IItemID; - f >> c; if( c != ':' ) { bSyntaxError = true; break; } - f >> IItemCount; + int IItemID = 0, IItemCount = 0, IItemHealth = 0, IBurnTime = 0; + AString::size_type BeginPos = 1; // Begin at one after exclamation mark (bang) - // Optional health - f >> c; - if( c != ':' ) - f.unget(); - else + if ( + !ReadMandatoryNumber(BeginPos, ":", ParsingLine, SyntaxError, Line, IItemID) || // Read item ID + !ReadOptionalNumbers(BeginPos, ":", "=", ParsingLine, SyntaxError, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) + !ReadMandatoryNumber(BeginPos, "0123456789", ParsingLine, SyntaxError, Line, IBurnTime, true) // Read item burn time - last value + ) { - f >> IItemHealth; + break; } - // Burn time - int BurnTime; - f >> c; if( c != '=' ) { bSyntaxError = true; break; } - f >> BurnTime; - // Add to fuel list Fuel F; - F.In = new cItem( (ENUM_ITEM_ID) IItemID, (char)IItemCount, (short)IItemHealth ); - F.BurnTime = BurnTime; - m_pState->Fuel.push_back( F ); + F.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth); + F.BurnTime = IBurnTime; + m_pState->Fuel.push_back(F); + printf("%i %i %i %i\n", IItemID, IItemCount, IItemHealth, IBurnTime); continue; } - f.unget(); - - ////////////////////////////////////////////////////////////////////////// - // Read items - int IItemID = 0, IItemCount = 0, IItemHealth = 0; - f >> IItemID; - f >> c; if( c != ':' ) { bSyntaxError = true; break; } - f >> IItemCount; - - // Optional health - f >> c; - if( c != ':' ) - f.unget(); - else + else if (isdigit(ParsingLine[0])) // Recipes start with a numeral :) { - f >> IItemHealth; + 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, ":", ParsingLine, SyntaxError, Line, IItemID) || // Read item ID + !ReadOptionalNumbers(BeginPos, ":", "@", ParsingLine, SyntaxError, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) + !ReadMandatoryNumber(BeginPos, "=", ParsingLine, SyntaxError, Line, IBurnTime) || // Read item burn time + !ReadMandatoryNumber(BeginPos, ":", ParsingLine, SyntaxError, Line, OItemID) || // Read result ID + !ReadOptionalNumbers(BeginPos, ":", "012456789", ParsingLine, SyntaxError, Line, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value + ) + { + break; + } + + // 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); } - - int CookTime; - f >> c; if( c != '@' ) { bSyntaxError = true; break; } - f >> CookTime; - - int OItemID = 0, OItemCount = 0, OItemHealth = 0; - f >> c; if( c != '=' ) { bSyntaxError = true; break; } - f >> OItemID; - f >> c; if( c != ':' ) { bSyntaxError = true; break; } - f >> OItemCount; - - // Optional health - f >> c; - if( c != ':' ) - f.unget(); - else - { - f >> OItemHealth; - } - - // 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 = CookTime; - m_pState->Recipes.push_back( R ); } - if (bSyntaxError) + F.close(); + + if (!SyntaxError.empty()) { - LOGERROR("ERROR: FurnaceRecipe, syntax error" ); + LOGWARN("Error parsing furnace recipes at %s", SyntaxError.c_str()); } - LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); + else + { + LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); + } +} + + + + + +void cFurnaceRecipe::SetParseError(AString & a_ErrorString, unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing) +{ + Printf(a_ErrorString, "line %i pos %i: missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str()); +} + + + + + +bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, AString & a_ErrorString, unsigned int a_Line, int & a_Value, bool a_IsLastValue) +{ + AString::size_type End; + if (a_IsLastValue) + { + End = a_Text.find_first_not_of(a_Delimiter, a_Begin); + } + else + { + End = a_Text.find_first_of(a_Delimiter, a_Begin); + if (End == AString::npos) + { + SetParseError(a_ErrorString, a_Line, a_Begin, a_Delimiter); + return false; + } + } + + // 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))) + { + SetParseError(a_ErrorString, a_Line, a_Begin, "number"); + return false; + } + a_Value = std::stoi(a_Text.substr(a_Begin, End - a_Begin)); + + a_Begin = End + 1; // Jump over delimiter + return true; +} + + + + + +bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, AString & a_ErrorString, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue) +{ + unsigned int 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::stoi(a_Text.substr(Begin, End - Begin)); + Begin = End + 1; + + 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) + { + SetParseError(a_ErrorString, a_Line, Begin, a_DelimiterTwo); + return false; + } + } + + // stoi won't throw an exception if the string is alphanumeric, we should check for this + if (!DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin))) + { + SetParseError(a_ErrorString, a_Line, Begin, "number"); + return false; + } + a_ValueTwo = std::stoi(a_Text.substr(Begin, End - Begin)); + + a_Begin = End + 1; // Jump over delimiter + return true; + } + else + { + return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_ErrorString, a_Line, a_ValueOne, a_IsLastValue); + } + } + + return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_ErrorString, a_Line, a_ValueOne, a_IsLastValue); +} + + + + + +bool cFurnaceRecipe::DoesStringContainOnlyNumbers(const AString & a_String) +{ + return std::all_of(a_String.begin(), a_String.end(), isdigit); } diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index 2f91e9bcb..e0222f2fb 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -41,6 +41,28 @@ public: private: void ClearRecipes(void); + /** PrintFs the line, position, and error into an error string */ + inline static void SetParseError(AString & a_ErrorString, 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, AString & a_ErrorString, 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, AString & a_ErrorString, 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 */ + inline static bool DoesStringContainOnlyNumbers(const AString & a_String); + + struct sFurnaceRecipeState; sFurnaceRecipeState * m_pState; }; From 537467fe25386a67ef5cb9a33b9806ac2db0c894 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 21 Jun 2014 20:35:28 +0100 Subject: [PATCH 10/58] Removed debugging code --- src/FurnaceRecipe.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index b4b3d34d9..ce9233bcc 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -102,7 +102,6 @@ void cFurnaceRecipe::ReloadRecipes(void) F.In = new cItem((ENUM_ITEM_ID)IItemID, (char)IItemCount, (short)IItemHealth); F.BurnTime = IBurnTime; m_pState->Fuel.push_back(F); - printf("%i %i %i %i\n", IItemID, IItemCount, IItemHealth, IBurnTime); continue; } else if (isdigit(ParsingLine[0])) // Recipes start with a numeral :) From 4a01fba3aafef53ac8015bd5f6028fc677d6d245 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 22 Jun 2014 00:06:58 +0100 Subject: [PATCH 11/58] Suggestions --- src/FurnaceRecipe.cpp | 62 ++++++++++++++++++------------------------- src/FurnaceRecipe.h | 8 +++--- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index ce9233bcc..448a4bfa8 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -54,21 +54,18 @@ void cFurnaceRecipe::ReloadRecipes(void) ClearRecipes(); LOGD("Loading furnace recipes..."); - std::ifstream F(FURNACE_RECIPE_FILE, std::ios::in); - if (!F.good()) + std::ifstream f(FURNACE_RECIPE_FILE, std::ios::in); + if (!f.good()) { - F.close(); + f.close(); LOG("Could not open the furnace recipes file \"%s\"", FURNACE_RECIPE_FILE); return; } - AString SyntaxError; unsigned int Line = 0; AString ParsingLine; - ASSERT(ParsingLine.empty()); - - while (std::getline(F, ParsingLine)) + while (std::getline(f, ParsingLine)) { Line++; ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove whitespace @@ -89,12 +86,12 @@ void cFurnaceRecipe::ReloadRecipes(void) AString::size_type BeginPos = 1; // Begin at one after exclamation mark (bang) if ( - !ReadMandatoryNumber(BeginPos, ":", ParsingLine, SyntaxError, Line, IItemID) || // Read item ID - !ReadOptionalNumbers(BeginPos, ":", "=", ParsingLine, SyntaxError, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) - !ReadMandatoryNumber(BeginPos, "0123456789", ParsingLine, SyntaxError, Line, IBurnTime, true) // Read item burn time - last value + !ReadMandatoryNumber(BeginPos, ":", ParsingLine, Line, IItemID) || // Read item ID + !ReadOptionalNumbers(BeginPos, ":", "=", ParsingLine, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) + !ReadMandatoryNumber(BeginPos, "0123456789", ParsingLine, Line, IBurnTime, true) // Read item burn time - last value ) { - break; + return; } // Add to fuel list @@ -111,14 +108,14 @@ void cFurnaceRecipe::ReloadRecipes(void) AString::size_type BeginPos = 0; // Begin at start of line if ( - !ReadMandatoryNumber(BeginPos, ":", ParsingLine, SyntaxError, Line, IItemID) || // Read item ID - !ReadOptionalNumbers(BeginPos, ":", "@", ParsingLine, SyntaxError, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) - !ReadMandatoryNumber(BeginPos, "=", ParsingLine, SyntaxError, Line, IBurnTime) || // Read item burn time - !ReadMandatoryNumber(BeginPos, ":", ParsingLine, SyntaxError, Line, OItemID) || // Read result ID - !ReadOptionalNumbers(BeginPos, ":", "012456789", ParsingLine, SyntaxError, Line, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value + !ReadMandatoryNumber(BeginPos, ":", ParsingLine, Line, IItemID) || // Read item ID + !ReadOptionalNumbers(BeginPos, ":", "@", ParsingLine, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) + !ReadMandatoryNumber(BeginPos, "=", ParsingLine, Line, IBurnTime) || // Read item burn time + !ReadMandatoryNumber(BeginPos, ":", ParsingLine, Line, OItemID) || // Read result ID + !ReadOptionalNumbers(BeginPos, ":", "012456789", ParsingLine, Line, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value ) { - break; + return; } // Add to recipe list @@ -129,32 +126,25 @@ void cFurnaceRecipe::ReloadRecipes(void) m_pState->Recipes.push_back(R); } } - F.close(); + f.close(); - if (!SyntaxError.empty()) - { - LOGWARN("Error parsing furnace recipes at %s", SyntaxError.c_str()); - } - else - { - LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); - } + LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); } -void cFurnaceRecipe::SetParseError(AString & a_ErrorString, unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing) +void cFurnaceRecipe::PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing) { - Printf(a_ErrorString, "line %i pos %i: missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str()); + LOGWARN("Error parsing furnace recipes at line %i pos %i: missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str()); } -bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const AString & a_Delimiter, const AString & a_Text, AString & a_ErrorString, unsigned int a_Line, int & a_Value, bool a_IsLastValue) +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) { AString::size_type End; if (a_IsLastValue) @@ -166,7 +156,7 @@ bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const ASt End = a_Text.find_first_of(a_Delimiter, a_Begin); if (End == AString::npos) { - SetParseError(a_ErrorString, a_Line, a_Begin, a_Delimiter); + PrintParseError(a_Line, a_Begin, a_Delimiter); return false; } } @@ -174,7 +164,7 @@ bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const ASt // 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))) { - SetParseError(a_ErrorString, a_Line, a_Begin, "number"); + PrintParseError(a_Line, a_Begin, "number"); return false; } a_Value = std::stoi(a_Text.substr(a_Begin, End - a_Begin)); @@ -187,7 +177,7 @@ bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const ASt -bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const AString & a_DelimiterOne, const AString & a_DelimiterTwo, const AString & a_Text, AString & a_ErrorString, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue) +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) { unsigned int End, Begin = a_Begin; @@ -208,7 +198,7 @@ bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const ASt End = a_Text.find_first_of(a_DelimiterTwo, Begin); if (End == AString::npos) { - SetParseError(a_ErrorString, a_Line, Begin, a_DelimiterTwo); + PrintParseError(a_Line, Begin, a_DelimiterTwo); return false; } } @@ -216,7 +206,7 @@ bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const ASt // stoi won't throw an exception if the string is alphanumeric, we should check for this if (!DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin))) { - SetParseError(a_ErrorString, a_Line, Begin, "number"); + PrintParseError(a_Line, Begin, "number"); return false; } a_ValueTwo = std::stoi(a_Text.substr(Begin, End - Begin)); @@ -226,11 +216,11 @@ bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const ASt } else { - return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_ErrorString, a_Line, a_ValueOne, a_IsLastValue); + return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue); } } - return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_ErrorString, a_Line, a_ValueOne, a_IsLastValue); + return ReadMandatoryNumber(a_Begin, a_DelimiterTwo, a_Text, a_Line, a_ValueOne, a_IsLastValue); } diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index e0222f2fb..cddcc215f 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -41,15 +41,15 @@ public: private: void ClearRecipes(void); - /** PrintFs the line, position, and error into an error string */ - inline static void SetParseError(AString & a_ErrorString, unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing); + /** Calls LOGWARN with the line, position, and error */ + inline 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, AString & a_ErrorString, unsigned int a_Line, int & a_Value, bool a_IsLastValue = false); + 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 @@ -57,7 +57,7 @@ private: 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, AString & a_ErrorString, unsigned int a_Line, int & a_ValueOne, int & a_ValueTwo, bool a_IsLastValue = false); + 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 */ inline static bool DoesStringContainOnlyNumbers(const AString & a_String); From 63ce2e8b37444f96d7892d555cb296947b3afbe5 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 22 Jun 2014 12:30:37 +0100 Subject: [PATCH 12/58] Fixed compile errors --- src/FurnaceRecipe.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index 448a4bfa8..8040552cc 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -137,7 +137,7 @@ void cFurnaceRecipe::ReloadRecipes(void) void cFurnaceRecipe::PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing) { - LOGWARN("Error parsing furnace recipes at line %i pos %i: missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str()); + LOGWARN("Error parsing furnace recipes at line %i pos " SIZE_T_FMT ": missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str()); } @@ -179,7 +179,7 @@ bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const ASt 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) { - unsigned int End, Begin = a_Begin; + AString::size_type End, Begin = a_Begin; End = a_Text.find_first_of(a_DelimiterOne, Begin); if (End != AString::npos) From c476fc3cf5a2bbdb27b61fcad290c84029721462 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 22 Jun 2014 21:49:37 +0100 Subject: [PATCH 13/58] Suggestions --- src/FurnaceRecipe.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index 448a4bfa8..90b478285 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -57,7 +57,6 @@ void cFurnaceRecipe::ReloadRecipes(void) std::ifstream f(FURNACE_RECIPE_FILE, std::ios::in); if (!f.good()) { - f.close(); LOG("Could not open the furnace recipes file \"%s\"", FURNACE_RECIPE_FILE); return; } @@ -126,7 +125,6 @@ void cFurnaceRecipe::ReloadRecipes(void) m_pState->Recipes.push_back(R); } } - f.close(); LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); } @@ -146,6 +144,7 @@ void cFurnaceRecipe::PrintParseError(unsigned int a_Line, size_t a_Position, con 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) { @@ -167,7 +166,7 @@ bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const ASt PrintParseError(a_Line, a_Begin, "number"); return false; } - a_Value = std::stoi(a_Text.substr(a_Begin, End - a_Begin)); + a_Value = atoi(a_Text.substr(a_Begin, End - a_Begin).c_str()); a_Begin = End + 1; // Jump over delimiter return true; @@ -179,6 +178,7 @@ bool cFurnaceRecipe::ReadMandatoryNumber(AString::size_type & a_Begin, const ASt 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) { + // TODO: replace atoi with std::stoi unsigned int End, Begin = a_Begin; End = a_Text.find_first_of(a_DelimiterOne, Begin); @@ -186,7 +186,7 @@ bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const ASt { if (DoesStringContainOnlyNumbers(a_Text.substr(Begin, End - Begin))) { - a_ValueOne = std::stoi(a_Text.substr(Begin, End - Begin)); + a_ValueOne = std::atoi(a_Text.substr(Begin, End - Begin).c_str()); Begin = End + 1; if (a_IsLastValue) @@ -209,7 +209,7 @@ bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const ASt PrintParseError(a_Line, Begin, "number"); return false; } - a_ValueTwo = std::stoi(a_Text.substr(Begin, End - Begin)); + a_ValueTwo = atoi(a_Text.substr(Begin, End - Begin).c_str()); a_Begin = End + 1; // Jump over delimiter return true; @@ -229,7 +229,8 @@ bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const ASt bool cFurnaceRecipe::DoesStringContainOnlyNumbers(const AString & a_String) { - return std::all_of(a_String.begin(), a_String.end(), isdigit); + // TODO: replace this with std::all_of(a_String.begin(), a_String.end(), isdigit) + return a_String.find_first_not_of("0123456789") == AString::npos; } From 7a236921319c44de38246ff73d5343e174dd560f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 23 Jun 2014 17:40:51 +0100 Subject: [PATCH 14/58] Parenthesised comparison --- src/FurnaceRecipe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index d53854950..36dd2d5e9 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -230,7 +230,7 @@ bool cFurnaceRecipe::ReadOptionalNumbers(AString::size_type & a_Begin, const ASt 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; + return (a_String.find_first_not_of("0123456789") == AString::npos); } From 5ab01c4d4205b61b41855eaeee534ae15b816331 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 24 Jun 2014 15:27:19 +0200 Subject: [PATCH 15/58] Fix pickup combining over the maximum stack size. --- src/Entities/Pickup.cpp | 12 ++++++++---- src/Item.cpp | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index 0fd006485..88d961106 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -38,11 +38,15 @@ public: Vector3d EntityPos = a_Entity->GetPosition(); double Distance = (EntityPos - m_Position).Length(); - if ((Distance < 1.2) && ((cPickup *)a_Entity)->GetItem().IsEqual(m_Pickup->GetItem())) + cItem & Item = ((cPickup *)a_Entity)->GetItem(); + if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem())) { - m_Pickup->GetItem().AddCount(((cPickup *)a_Entity)->GetItem().m_ItemCount); - a_Entity->Destroy(); - m_FoundMatchingPickup = true; + if ((Item.m_ItemCount + m_Pickup->GetItem().m_ItemCount) <= Item.GetMaxStackSize()) + { + m_Pickup->GetItem().AddCount(Item.m_ItemCount); + a_Entity->Destroy(); + m_FoundMatchingPickup = true; + } } return false; } diff --git a/src/Item.cpp b/src/Item.cpp index d6e8b224a..56ceae0b7 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -1,4 +1,4 @@ - + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Item.h" From d4e1277724b8a7629fc0eb4d468319f7bd4a93b0 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 24 Jun 2014 16:06:26 +0200 Subject: [PATCH 16/58] Add entity health saving. --- src/WorldStorage/NBTChunkSerializer.cpp | 3 +-- src/WorldStorage/WSSAnvil.cpp | 21 +++++++-------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 8294d4a00..f35b38859 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -345,6 +345,7 @@ void cNBTChunkSerializer::AddBasicEntity(cEntity * a_Entity, const AString & a_C m_Writer.AddDouble("", a_Entity->GetYaw()); m_Writer.AddDouble("", a_Entity->GetPitch()); m_Writer.EndList(); + m_Writer.AddShort("Health", a_Entity->GetHealth()); } @@ -575,7 +576,6 @@ void cNBTChunkSerializer::AddPickupEntity(cPickup * a_Pickup) m_Writer.BeginCompound(""); AddBasicEntity(a_Pickup, "Item"); AddItem(a_Pickup->GetItem(), -1, "Item"); - m_Writer.AddShort("Health", (Int16)(unsigned char)a_Pickup->GetHealth()); m_Writer.AddShort("Age", (Int16)a_Pickup->GetAge()); m_Writer.EndCompound(); } @@ -678,7 +678,6 @@ void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb * a_ExpOrb) { m_Writer.BeginCompound(""); AddBasicEntity(a_ExpOrb, "XPOrb"); - m_Writer.AddShort("Health", (Int16)(unsigned char)a_ExpOrb->GetHealth()); m_Writer.AddShort("Age", (Int16)a_ExpOrb->GetAge()); m_Writer.AddShort("Value", (Int16)a_ExpOrb->GetReward()); m_Writer.EndCompound(); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 0f84a0eb1..9870c144a 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1461,13 +1461,6 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - - // Load health: - int Health = a_NBT.FindChildByName(a_TagIdx, "Health"); - if (Health > 0) - { - Pickup->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF)); - } // Load age: int Age = a_NBT.FindChildByName(a_TagIdx, "Age"); @@ -1513,13 +1506,6 @@ void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a return; } - // Load Health: - int Health = a_NBT.FindChildByName(a_TagIdx, "Health"); - if (Health > 0) - { - ExpOrb->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF)); - } - // Load Age: int Age = a_NBT.FindChildByName(a_TagIdx, "Age"); if (Age > 0) @@ -2437,6 +2423,13 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N } a_Entity.SetYaw(Rotation[0]); a_Entity.SetRoll(Rotation[1]); + + // Load health: + int Health = a_NBT.FindChildByName(a_TagIdx, "Health"); + if (Health > 0) + { + a_Entity.SetHealth(a_NBT.GetShort(Health)); + } return true; } From 2dd7a0373be83ab917c3c115af519b42ce30e2a9 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 24 Jun 2014 16:19:22 +0200 Subject: [PATCH 17/58] Better combining. --- src/Entities/Pickup.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index 88d961106..6cab79b91 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -41,12 +41,29 @@ public: cItem & Item = ((cPickup *)a_Entity)->GetItem(); if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem())) { - if ((Item.m_ItemCount + m_Pickup->GetItem().m_ItemCount) <= Item.GetMaxStackSize()) + char CombineCount = Item.m_ItemCount; + if ((CombineCount + m_Pickup->GetItem().m_ItemCount) > Item.GetMaxStackSize()) { - m_Pickup->GetItem().AddCount(Item.m_ItemCount); - a_Entity->Destroy(); - m_FoundMatchingPickup = true; + CombineCount = Item.GetMaxStackSize() - m_Pickup->GetItem().m_ItemCount; } + + if (CombineCount <= 0) + { + return false; + } + + m_Pickup->GetItem().AddCount(CombineCount); + Item.m_ItemCount -= CombineCount; + + if (Item.m_ItemCount <= 0) + { + a_Entity->Destroy(); + } + else + { + a_Entity->GetWorld()->BroadcastEntityMetadata(*a_Entity); + } + m_FoundMatchingPickup = true; } return false; } From dbcb7f819fc900164d644a1932d0cdc78b707ae0 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 24 Jun 2014 17:50:38 +0200 Subject: [PATCH 18/58] Optimize combining. --- src/Entities/Pickup.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index 6cab79b91..44a65412f 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -30,7 +30,7 @@ public: virtual bool Item(cEntity * a_Entity) override { - if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() == m_Pickup->GetUniqueID()) || a_Entity->IsDestroyed()) + if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() <= m_Pickup->GetUniqueID()) || a_Entity->IsDestroyed()) { return false; } @@ -150,7 +150,7 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk) } } - if (!IsDestroyed()) // Don't try to combine if someone has tried to combine me + if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't try to combine if someone has tried to combine me { cPickupCombiningCallback PickupCombiningCallback(GetPosition(), this); m_World->ForEachEntity(PickupCombiningCallback); // Not ForEachEntityInChunk, otherwise pickups don't combine across chunk boundaries @@ -227,7 +227,7 @@ bool cPickup::CollectedBy(cPlayer * a_Dest) m_World->BroadcastCollectPickup(*this, *a_Dest); // Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;) m_World->BroadcastSoundEffect("random.pop",(int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); - if (m_Item.m_ItemCount == 0) + if (m_Item.m_ItemCount <= 0) { // All of the pickup has been collected, schedule the pickup for destroying m_bCollected = true; From e9aecfdf112601377ab6f640b77cb49c5a3a45bb Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 25 Jun 2014 08:07:06 +0200 Subject: [PATCH 19/58] BlockInfo is now a proper C++ singleton. It is properly initialized before it is ever used. --- src/BlockInfo.cpp | 732 +++++++++++++++++++++++----------------------- src/BlockInfo.h | 23 +- 2 files changed, 374 insertions(+), 381 deletions(-) diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index b084d0915..26525e264 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -8,13 +8,6 @@ -cBlockInfo cBlockInfo::ms_Info[256]; -static bool g_IsBlockInfoInitialized = false; - - - - - cBlockInfo::cBlockInfo() : m_LightValue(0x00) , m_SpreadLightFalloff(0x0f) @@ -42,12 +35,17 @@ cBlockInfo::~cBlockInfo() +/** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once. +It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable. +It works only if it is called for the first time before the app spawns other threads. */ cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type) { - if (!g_IsBlockInfoInitialized) + static cBlockInfo ms_Info[256]; + static bool IsBlockInfoInitialized = false; + if (!IsBlockInfoInitialized) { - cBlockInfo::Initialize(); - g_IsBlockInfoInitialized = true; + cBlockInfo::Initialize(ms_Info); + IsBlockInfoInitialized = true; } return ms_Info[a_Type]; } @@ -56,399 +54,399 @@ cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type) -void cBlockInfo::Initialize(void) +void cBlockInfo::Initialize(cBlockInfoArray & a_Info) { for (unsigned int i = 0; i < 256; ++i) { - if (ms_Info[i].m_Handler == NULL) + if (a_Info[i].m_Handler == NULL) { - ms_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i); + a_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i); } } // Emissive blocks - ms_Info[E_BLOCK_FIRE ].m_LightValue = 15; - ms_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15; - ms_Info[E_BLOCK_JACK_O_LANTERN ].m_LightValue = 15; - ms_Info[E_BLOCK_LAVA ].m_LightValue = 15; - ms_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15; - ms_Info[E_BLOCK_END_PORTAL ].m_LightValue = 15; - ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_LightValue = 15; - ms_Info[E_BLOCK_TORCH ].m_LightValue = 14; - ms_Info[E_BLOCK_BURNING_FURNACE ].m_LightValue = 13; - ms_Info[E_BLOCK_NETHER_PORTAL ].m_LightValue = 11; - ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9; - ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9; - ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7; - ms_Info[E_BLOCK_BREWING_STAND ].m_LightValue = 1; - ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_LightValue = 1; - ms_Info[E_BLOCK_DRAGON_EGG ].m_LightValue = 1; + a_Info[E_BLOCK_FIRE ].m_LightValue = 15; + a_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15; + a_Info[E_BLOCK_JACK_O_LANTERN ].m_LightValue = 15; + a_Info[E_BLOCK_LAVA ].m_LightValue = 15; + a_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15; + a_Info[E_BLOCK_END_PORTAL ].m_LightValue = 15; + a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_LightValue = 15; + a_Info[E_BLOCK_TORCH ].m_LightValue = 14; + a_Info[E_BLOCK_BURNING_FURNACE ].m_LightValue = 13; + a_Info[E_BLOCK_NETHER_PORTAL ].m_LightValue = 11; + a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9; + a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9; + a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7; + a_Info[E_BLOCK_BREWING_STAND ].m_LightValue = 1; + a_Info[E_BLOCK_BROWN_MUSHROOM ].m_LightValue = 1; + a_Info[E_BLOCK_DRAGON_EGG ].m_LightValue = 1; // Spread blocks - ms_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_CAKE ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_CHEST ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_FENCE ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_FENCE_GATE ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_FIRE ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_GLASS ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_GLASS_PANE ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_GLOWSTONE ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1; - ms_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_CAKE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_CHEST ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_FENCE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_FENCE_GATE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_FIRE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_GLASS ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_GLASS_PANE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_GLOWSTONE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1; // Light in water and lava dissapears faster: - ms_Info[E_BLOCK_LAVA ].m_SpreadLightFalloff = 3; - ms_Info[E_BLOCK_STATIONARY_LAVA ].m_SpreadLightFalloff = 3; - ms_Info[E_BLOCK_STATIONARY_WATER ].m_SpreadLightFalloff = 3; - ms_Info[E_BLOCK_WATER ].m_SpreadLightFalloff = 3; + a_Info[E_BLOCK_LAVA ].m_SpreadLightFalloff = 3; + a_Info[E_BLOCK_STATIONARY_LAVA ].m_SpreadLightFalloff = 3; + a_Info[E_BLOCK_STATIONARY_WATER ].m_SpreadLightFalloff = 3; + a_Info[E_BLOCK_WATER ].m_SpreadLightFalloff = 3; // Transparent blocks - ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true; - ms_Info[E_BLOCK_AIR ].m_Transparent = true; - ms_Info[E_BLOCK_ANVIL ].m_Transparent = true; - ms_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true; - ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true; - ms_Info[E_BLOCK_CAKE ].m_Transparent = true; - ms_Info[E_BLOCK_CARROTS ].m_Transparent = true; - ms_Info[E_BLOCK_CHEST ].m_Transparent = true; - ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_Transparent = true; - ms_Info[E_BLOCK_COBWEB ].m_Transparent = true; - ms_Info[E_BLOCK_CROPS ].m_Transparent = true; - ms_Info[E_BLOCK_DANDELION ].m_Transparent = true; - ms_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true; - ms_Info[E_BLOCK_ENDER_CHEST ].m_Transparent = true; - ms_Info[E_BLOCK_FENCE ].m_Transparent = true; - ms_Info[E_BLOCK_FENCE_GATE ].m_Transparent = true; - ms_Info[E_BLOCK_FIRE ].m_Transparent = true; - ms_Info[E_BLOCK_FLOWER ].m_Transparent = true; - ms_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true; - ms_Info[E_BLOCK_GLASS ].m_Transparent = true; - ms_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true; - ms_Info[E_BLOCK_HEAD ].m_Transparent = true; - ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true; - ms_Info[E_BLOCK_ICE ].m_Transparent = true; - ms_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true; - ms_Info[E_BLOCK_LADDER ].m_Transparent = true; - ms_Info[E_BLOCK_LAVA ].m_Transparent = true; - ms_Info[E_BLOCK_LEAVES ].m_Transparent = true; - ms_Info[E_BLOCK_LEVER ].m_Transparent = true; - ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Transparent = true; - ms_Info[E_BLOCK_MELON_STEM ].m_Transparent = true; - ms_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Transparent = true; - ms_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true; - ms_Info[E_BLOCK_POTATOES ].m_Transparent = true; - ms_Info[E_BLOCK_POWERED_RAIL ].m_Transparent = true; - ms_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true; - ms_Info[E_BLOCK_PUMPKIN_STEM ].m_Transparent = true; - ms_Info[E_BLOCK_RAIL ].m_Transparent = true; - ms_Info[E_BLOCK_RED_MUSHROOM ].m_Transparent = true; - ms_Info[E_BLOCK_SIGN_POST ].m_Transparent = true; - ms_Info[E_BLOCK_SNOW ].m_Transparent = true; - ms_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true; - ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true; - ms_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true; - ms_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true; - ms_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true; - ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true; - ms_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true; - ms_Info[E_BLOCK_TORCH ].m_Transparent = true; - ms_Info[E_BLOCK_VINES ].m_Transparent = true; - ms_Info[E_BLOCK_WALLSIGN ].m_Transparent = true; - ms_Info[E_BLOCK_WATER ].m_Transparent = true; - ms_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true; - ms_Info[E_BLOCK_WOODEN_DOOR ].m_Transparent = true; - ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Transparent = true; + a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true; + a_Info[E_BLOCK_AIR ].m_Transparent = true; + a_Info[E_BLOCK_ANVIL ].m_Transparent = true; + a_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true; + a_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true; + a_Info[E_BLOCK_CAKE ].m_Transparent = true; + a_Info[E_BLOCK_CARROTS ].m_Transparent = true; + a_Info[E_BLOCK_CHEST ].m_Transparent = true; + a_Info[E_BLOCK_COBBLESTONE_WALL ].m_Transparent = true; + a_Info[E_BLOCK_COBWEB ].m_Transparent = true; + a_Info[E_BLOCK_CROPS ].m_Transparent = true; + a_Info[E_BLOCK_DANDELION ].m_Transparent = true; + a_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true; + a_Info[E_BLOCK_ENDER_CHEST ].m_Transparent = true; + a_Info[E_BLOCK_FENCE ].m_Transparent = true; + a_Info[E_BLOCK_FENCE_GATE ].m_Transparent = true; + a_Info[E_BLOCK_FIRE ].m_Transparent = true; + a_Info[E_BLOCK_FLOWER ].m_Transparent = true; + a_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true; + a_Info[E_BLOCK_GLASS ].m_Transparent = true; + a_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true; + a_Info[E_BLOCK_HEAD ].m_Transparent = true; + a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true; + a_Info[E_BLOCK_ICE ].m_Transparent = true; + a_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true; + a_Info[E_BLOCK_LADDER ].m_Transparent = true; + a_Info[E_BLOCK_LAVA ].m_Transparent = true; + a_Info[E_BLOCK_LEAVES ].m_Transparent = true; + a_Info[E_BLOCK_LEVER ].m_Transparent = true; + a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Transparent = true; + a_Info[E_BLOCK_MELON_STEM ].m_Transparent = true; + a_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Transparent = true; + a_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true; + a_Info[E_BLOCK_POTATOES ].m_Transparent = true; + a_Info[E_BLOCK_POWERED_RAIL ].m_Transparent = true; + a_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true; + a_Info[E_BLOCK_PUMPKIN_STEM ].m_Transparent = true; + a_Info[E_BLOCK_RAIL ].m_Transparent = true; + a_Info[E_BLOCK_RED_MUSHROOM ].m_Transparent = true; + a_Info[E_BLOCK_SIGN_POST ].m_Transparent = true; + a_Info[E_BLOCK_SNOW ].m_Transparent = true; + a_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true; + a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true; + a_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true; + a_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true; + a_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true; + a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true; + a_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true; + a_Info[E_BLOCK_TORCH ].m_Transparent = true; + a_Info[E_BLOCK_VINES ].m_Transparent = true; + a_Info[E_BLOCK_WALLSIGN ].m_Transparent = true; + a_Info[E_BLOCK_WATER ].m_Transparent = true; + a_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true; + a_Info[E_BLOCK_WOODEN_DOOR ].m_Transparent = true; + a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Transparent = true; // TODO: Any other transparent blocks? // One hit break blocks: - ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_OneHitDig = true; - ms_Info[E_BLOCK_BIG_FLOWER ].m_OneHitDig = true; - ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_OneHitDig = true; - ms_Info[E_BLOCK_CARROTS ].m_OneHitDig = true; - ms_Info[E_BLOCK_CROPS ].m_OneHitDig = true; - ms_Info[E_BLOCK_DANDELION ].m_OneHitDig = true; - ms_Info[E_BLOCK_FIRE ].m_OneHitDig = true; - ms_Info[E_BLOCK_FLOWER ].m_OneHitDig = true; - ms_Info[E_BLOCK_FLOWER_POT ].m_OneHitDig = true; - ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true; - ms_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true; - ms_Info[E_BLOCK_POTATOES ].m_OneHitDig = true; - ms_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true; - ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true; - ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_OneHitDig = true; - ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_OneHitDig = true; - ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_OneHitDig = true; - ms_Info[E_BLOCK_REDSTONE_WIRE ].m_OneHitDig = true; - ms_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true; - ms_Info[E_BLOCK_REEDS ].m_OneHitDig = true; - ms_Info[E_BLOCK_SAPLING ].m_OneHitDig = true; - ms_Info[E_BLOCK_TNT ].m_OneHitDig = true; - ms_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true; - ms_Info[E_BLOCK_TORCH ].m_OneHitDig = true; + a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_OneHitDig = true; + a_Info[E_BLOCK_BIG_FLOWER ].m_OneHitDig = true; + a_Info[E_BLOCK_BROWN_MUSHROOM ].m_OneHitDig = true; + a_Info[E_BLOCK_CARROTS ].m_OneHitDig = true; + a_Info[E_BLOCK_CROPS ].m_OneHitDig = true; + a_Info[E_BLOCK_DANDELION ].m_OneHitDig = true; + a_Info[E_BLOCK_FIRE ].m_OneHitDig = true; + a_Info[E_BLOCK_FLOWER ].m_OneHitDig = true; + a_Info[E_BLOCK_FLOWER_POT ].m_OneHitDig = true; + a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true; + a_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true; + a_Info[E_BLOCK_POTATOES ].m_OneHitDig = true; + a_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true; + a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true; + a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_OneHitDig = true; + a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_OneHitDig = true; + a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_OneHitDig = true; + a_Info[E_BLOCK_REDSTONE_WIRE ].m_OneHitDig = true; + a_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true; + a_Info[E_BLOCK_REEDS ].m_OneHitDig = true; + a_Info[E_BLOCK_SAPLING ].m_OneHitDig = true; + a_Info[E_BLOCK_TNT ].m_OneHitDig = true; + a_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true; + a_Info[E_BLOCK_TORCH ].m_OneHitDig = true; // Blocks that break when pushed by piston: - ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PistonBreakable = true; - ms_Info[E_BLOCK_AIR ].m_PistonBreakable = true; - ms_Info[E_BLOCK_BED ].m_PistonBreakable = true; - ms_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true; - ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true; - ms_Info[E_BLOCK_CAKE ].m_PistonBreakable = true; - ms_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true; - ms_Info[E_BLOCK_CROPS ].m_PistonBreakable = true; - ms_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true; - ms_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true; - ms_Info[E_BLOCK_FIRE ].m_PistonBreakable = true; - ms_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true; - ms_Info[E_BLOCK_HEAD ].m_PistonBreakable = true; - ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; - ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true; - ms_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true; - ms_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true; - ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; - ms_Info[E_BLOCK_LADDER ].m_PistonBreakable = true; - ms_Info[E_BLOCK_LAVA ].m_PistonBreakable = true; - ms_Info[E_BLOCK_LEVER ].m_PistonBreakable = true; - ms_Info[E_BLOCK_MELON ].m_PistonBreakable = true; - ms_Info[E_BLOCK_MELON_STEM ].m_PistonBreakable = true; - ms_Info[E_BLOCK_PUMPKIN ].m_PistonBreakable = true; - ms_Info[E_BLOCK_PUMPKIN_STEM ].m_PistonBreakable = true; - ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_PistonBreakable = true; - ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_PistonBreakable = true; - ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PistonBreakable = true; - ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PistonBreakable = true; - ms_Info[E_BLOCK_REDSTONE_WIRE ].m_PistonBreakable = true; - ms_Info[E_BLOCK_RED_MUSHROOM ].m_PistonBreakable = true; - ms_Info[E_BLOCK_REEDS ].m_PistonBreakable = true; - ms_Info[E_BLOCK_SNOW ].m_PistonBreakable = true; - ms_Info[E_BLOCK_STATIONARY_LAVA ].m_PistonBreakable = true; - ms_Info[E_BLOCK_STATIONARY_WATER ].m_PistonBreakable = true; - ms_Info[E_BLOCK_STONE_BUTTON ].m_PistonBreakable = true; - ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true; - ms_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true; - ms_Info[E_BLOCK_TORCH ].m_PistonBreakable = true; - ms_Info[E_BLOCK_VINES ].m_PistonBreakable = true; - ms_Info[E_BLOCK_WATER ].m_PistonBreakable = true; - ms_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true; - ms_Info[E_BLOCK_WOODEN_DOOR ].m_PistonBreakable = true; - ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_PistonBreakable = true; + a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PistonBreakable = true; + a_Info[E_BLOCK_AIR ].m_PistonBreakable = true; + a_Info[E_BLOCK_BED ].m_PistonBreakable = true; + a_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true; + a_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true; + a_Info[E_BLOCK_CAKE ].m_PistonBreakable = true; + a_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true; + a_Info[E_BLOCK_CROPS ].m_PistonBreakable = true; + a_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true; + a_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true; + a_Info[E_BLOCK_FIRE ].m_PistonBreakable = true; + a_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true; + a_Info[E_BLOCK_HEAD ].m_PistonBreakable = true; + a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; + a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true; + a_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true; + a_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true; + a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; + a_Info[E_BLOCK_LADDER ].m_PistonBreakable = true; + a_Info[E_BLOCK_LAVA ].m_PistonBreakable = true; + a_Info[E_BLOCK_LEVER ].m_PistonBreakable = true; + a_Info[E_BLOCK_MELON ].m_PistonBreakable = true; + a_Info[E_BLOCK_MELON_STEM ].m_PistonBreakable = true; + a_Info[E_BLOCK_PUMPKIN ].m_PistonBreakable = true; + a_Info[E_BLOCK_PUMPKIN_STEM ].m_PistonBreakable = true; + a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_PistonBreakable = true; + a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_PistonBreakable = true; + a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PistonBreakable = true; + a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PistonBreakable = true; + a_Info[E_BLOCK_REDSTONE_WIRE ].m_PistonBreakable = true; + a_Info[E_BLOCK_RED_MUSHROOM ].m_PistonBreakable = true; + a_Info[E_BLOCK_REEDS ].m_PistonBreakable = true; + a_Info[E_BLOCK_SNOW ].m_PistonBreakable = true; + a_Info[E_BLOCK_STATIONARY_LAVA ].m_PistonBreakable = true; + a_Info[E_BLOCK_STATIONARY_WATER ].m_PistonBreakable = true; + a_Info[E_BLOCK_STONE_BUTTON ].m_PistonBreakable = true; + a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true; + a_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true; + a_Info[E_BLOCK_TORCH ].m_PistonBreakable = true; + a_Info[E_BLOCK_VINES ].m_PistonBreakable = true; + a_Info[E_BLOCK_WATER ].m_PistonBreakable = true; + a_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true; + a_Info[E_BLOCK_WOODEN_DOOR ].m_PistonBreakable = true; + a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_PistonBreakable = true; // Blocks that cannot be snowed over: - ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_IsSnowable = false; - ms_Info[E_BLOCK_AIR ].m_IsSnowable = false; - ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSnowable = false; - ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSnowable = false; - ms_Info[E_BLOCK_CACTUS ].m_IsSnowable = false; - ms_Info[E_BLOCK_CHEST ].m_IsSnowable = false; - ms_Info[E_BLOCK_CROPS ].m_IsSnowable = false; - ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_IsSnowable = false; - ms_Info[E_BLOCK_DANDELION ].m_IsSnowable = false; - ms_Info[E_BLOCK_FIRE ].m_IsSnowable = false; - ms_Info[E_BLOCK_FLOWER ].m_IsSnowable = false; - ms_Info[E_BLOCK_GLASS ].m_IsSnowable = false; - ms_Info[E_BLOCK_ICE ].m_IsSnowable = false; - ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_IsSnowable = false; - ms_Info[E_BLOCK_LAVA ].m_IsSnowable = false; - ms_Info[E_BLOCK_LILY_PAD ].m_IsSnowable = false; - ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_IsSnowable = false; - ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_IsSnowable = false; - ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSnowable = false; - ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSnowable = false; - ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSnowable = false; - ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSnowable = false; - ms_Info[E_BLOCK_REEDS ].m_IsSnowable = false; - ms_Info[E_BLOCK_SAPLING ].m_IsSnowable = false; - ms_Info[E_BLOCK_SIGN_POST ].m_IsSnowable = false; - ms_Info[E_BLOCK_SNOW ].m_IsSnowable = false; - ms_Info[E_BLOCK_STAINED_GLASS ].m_IsSnowable = false; - ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_IsSnowable = false; - ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSnowable = false; - ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSnowable = false; - ms_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false; - ms_Info[E_BLOCK_TNT ].m_IsSnowable = false; - ms_Info[E_BLOCK_TORCH ].m_IsSnowable = false; - ms_Info[E_BLOCK_VINES ].m_IsSnowable = false; - ms_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false; - ms_Info[E_BLOCK_WATER ].m_IsSnowable = false; - ms_Info[E_BLOCK_RAIL ].m_IsSnowable = false; - ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSnowable = false; - ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false; - ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false; - ms_Info[E_BLOCK_COBWEB ].m_IsSnowable = false; - ms_Info[E_BLOCK_HEAD ].m_IsSnowable = false; + a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_IsSnowable = false; + a_Info[E_BLOCK_AIR ].m_IsSnowable = false; + a_Info[E_BLOCK_BIG_FLOWER ].m_IsSnowable = false; + a_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSnowable = false; + a_Info[E_BLOCK_CACTUS ].m_IsSnowable = false; + a_Info[E_BLOCK_CHEST ].m_IsSnowable = false; + a_Info[E_BLOCK_CROPS ].m_IsSnowable = false; + a_Info[E_BLOCK_COBBLESTONE_WALL ].m_IsSnowable = false; + a_Info[E_BLOCK_DANDELION ].m_IsSnowable = false; + a_Info[E_BLOCK_FIRE ].m_IsSnowable = false; + a_Info[E_BLOCK_FLOWER ].m_IsSnowable = false; + a_Info[E_BLOCK_GLASS ].m_IsSnowable = false; + a_Info[E_BLOCK_ICE ].m_IsSnowable = false; + a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_IsSnowable = false; + a_Info[E_BLOCK_LAVA ].m_IsSnowable = false; + a_Info[E_BLOCK_LILY_PAD ].m_IsSnowable = false; + a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_IsSnowable = false; + a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_IsSnowable = false; + a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSnowable = false; + a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSnowable = false; + a_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSnowable = false; + a_Info[E_BLOCK_RED_MUSHROOM ].m_IsSnowable = false; + a_Info[E_BLOCK_REEDS ].m_IsSnowable = false; + a_Info[E_BLOCK_SAPLING ].m_IsSnowable = false; + a_Info[E_BLOCK_SIGN_POST ].m_IsSnowable = false; + a_Info[E_BLOCK_SNOW ].m_IsSnowable = false; + a_Info[E_BLOCK_STAINED_GLASS ].m_IsSnowable = false; + a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_IsSnowable = false; + a_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSnowable = false; + a_Info[E_BLOCK_STATIONARY_WATER ].m_IsSnowable = false; + a_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false; + a_Info[E_BLOCK_TNT ].m_IsSnowable = false; + a_Info[E_BLOCK_TORCH ].m_IsSnowable = false; + a_Info[E_BLOCK_VINES ].m_IsSnowable = false; + a_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false; + a_Info[E_BLOCK_WATER ].m_IsSnowable = false; + a_Info[E_BLOCK_RAIL ].m_IsSnowable = false; + a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSnowable = false; + a_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false; + a_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false; + a_Info[E_BLOCK_COBWEB ].m_IsSnowable = false; + a_Info[E_BLOCK_HEAD ].m_IsSnowable = false; // Blocks that don't drop without a special tool: - ms_Info[E_BLOCK_BRICK ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_COBBLESTONE_WALL ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_DIAMOND_ORE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_EMERALD_ORE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_END_STONE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_GOLD_BLOCK ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_GOLD_ORE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_IRON_BLOCK ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_IRON_ORE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_LAPIS_BLOCK ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_LAPIS_ORE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_NETHERRACK ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_NETHER_BRICK ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_OBSIDIAN ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_REDSTONE_ORE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_SANDSTONE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_SANDSTONE_STAIRS ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_SNOW ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_STONE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_STONE_BRICKS ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_FURNACE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_LIT_FURNACE ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_ANVIL ].m_RequiresSpecialTool = true; - ms_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_BRICK ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_COBBLESTONE_WALL ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_DIAMOND_ORE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_EMERALD_ORE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_END_STONE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_GOLD_BLOCK ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_GOLD_ORE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_IRON_BLOCK ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_IRON_ORE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_LAPIS_BLOCK ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_LAPIS_ORE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_NETHERRACK ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_NETHER_BRICK ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_OBSIDIAN ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_REDSTONE_ORE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_SANDSTONE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_SANDSTONE_STAIRS ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_SNOW ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_STONE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_STONE_BRICKS ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_FURNACE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_LIT_FURNACE ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_ANVIL ].m_RequiresSpecialTool = true; + a_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_RequiresSpecialTool = true; // Nonsolid blocks: - ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSolid = false; - ms_Info[E_BLOCK_AIR ].m_IsSolid = false; - ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false; - ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false; - ms_Info[E_BLOCK_CAKE ].m_IsSolid = false; - ms_Info[E_BLOCK_CARROTS ].m_IsSolid = false; - ms_Info[E_BLOCK_COBWEB ].m_IsSolid = false; - ms_Info[E_BLOCK_CROPS ].m_IsSolid = false; - ms_Info[E_BLOCK_DANDELION ].m_IsSolid = false; - ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false; - ms_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false; - ms_Info[E_BLOCK_FENCE ].m_IsSolid = false; - ms_Info[E_BLOCK_FENCE_GATE ].m_IsSolid = false; - ms_Info[E_BLOCK_FIRE ].m_IsSolid = false; - ms_Info[E_BLOCK_FLOWER ].m_IsSolid = false; - ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false; - ms_Info[E_BLOCK_LAVA ].m_IsSolid = false; - ms_Info[E_BLOCK_LEVER ].m_IsSolid = false; - ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false; - ms_Info[E_BLOCK_MELON_STEM ].m_IsSolid = false; - ms_Info[E_BLOCK_NETHER_PORTAL ].m_IsSolid = false; - ms_Info[E_BLOCK_PISTON_EXTENSION ].m_IsSolid = false; - ms_Info[E_BLOCK_POTATOES ].m_IsSolid = false; - ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false; - ms_Info[E_BLOCK_RAIL ].m_IsSolid = false; - ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false; - ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false; - ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false; - ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false; - ms_Info[E_BLOCK_REEDS ].m_IsSolid = false; - ms_Info[E_BLOCK_SAPLING ].m_IsSolid = false; - ms_Info[E_BLOCK_SIGN_POST ].m_IsSolid = false; - ms_Info[E_BLOCK_SNOW ].m_IsSolid = false; - ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false; - ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false; - ms_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false; - ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false; - ms_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false; - ms_Info[E_BLOCK_TORCH ].m_IsSolid = false; - ms_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false; - ms_Info[E_BLOCK_VINES ].m_IsSolid = false; - ms_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false; - ms_Info[E_BLOCK_WATER ].m_IsSolid = false; - ms_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false; - ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_IsSolid = false; - ms_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false; + a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSolid = false; + a_Info[E_BLOCK_AIR ].m_IsSolid = false; + a_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false; + a_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false; + a_Info[E_BLOCK_CAKE ].m_IsSolid = false; + a_Info[E_BLOCK_CARROTS ].m_IsSolid = false; + a_Info[E_BLOCK_COBWEB ].m_IsSolid = false; + a_Info[E_BLOCK_CROPS ].m_IsSolid = false; + a_Info[E_BLOCK_DANDELION ].m_IsSolid = false; + a_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false; + a_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false; + a_Info[E_BLOCK_FENCE ].m_IsSolid = false; + a_Info[E_BLOCK_FENCE_GATE ].m_IsSolid = false; + a_Info[E_BLOCK_FIRE ].m_IsSolid = false; + a_Info[E_BLOCK_FLOWER ].m_IsSolid = false; + a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false; + a_Info[E_BLOCK_LAVA ].m_IsSolid = false; + a_Info[E_BLOCK_LEVER ].m_IsSolid = false; + a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false; + a_Info[E_BLOCK_MELON_STEM ].m_IsSolid = false; + a_Info[E_BLOCK_NETHER_PORTAL ].m_IsSolid = false; + a_Info[E_BLOCK_PISTON_EXTENSION ].m_IsSolid = false; + a_Info[E_BLOCK_POTATOES ].m_IsSolid = false; + a_Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false; + a_Info[E_BLOCK_RAIL ].m_IsSolid = false; + a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false; + a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false; + a_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false; + a_Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false; + a_Info[E_BLOCK_REEDS ].m_IsSolid = false; + a_Info[E_BLOCK_SAPLING ].m_IsSolid = false; + a_Info[E_BLOCK_SIGN_POST ].m_IsSolid = false; + a_Info[E_BLOCK_SNOW ].m_IsSolid = false; + a_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false; + a_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false; + a_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false; + a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false; + a_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false; + a_Info[E_BLOCK_TORCH ].m_IsSolid = false; + a_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false; + a_Info[E_BLOCK_VINES ].m_IsSolid = false; + a_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false; + a_Info[E_BLOCK_WATER ].m_IsSolid = false; + a_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false; + a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_IsSolid = false; + a_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false; // Blocks that fully occupy their voxel - used as a guide for torch placeable blocks, amongst other things: - ms_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_BOOKCASE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_BRICK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_CLAY ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_COAL_ORE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_COBBLESTONE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_COMMAND_BLOCK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_CRAFTING_TABLE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_DIAMOND_ORE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_DIRT ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_DISPENSER ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_DROPPER ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_EMERALD_BLOCK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_EMERALD_ORE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_END_STONE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_FURNACE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_GLOWSTONE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_GOLD_BLOCK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_GOLD_ORE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_GRASS ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_GRAVEL ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_HARDENED_CLAY ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_ICE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_JUKEBOX ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_LAPIS_BLOCK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_SANDSTONE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_SAND ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_SILVERFISH_EGG ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_SPONGE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_STAINED_CLAY ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true; - ms_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_BOOKCASE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_BRICK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_CLAY ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_COAL_ORE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_COBBLESTONE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_COMMAND_BLOCK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_CRAFTING_TABLE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_DIAMOND_BLOCK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_DIAMOND_ORE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_DIRT ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_DISPENSER ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_DROPPER ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_EMERALD_BLOCK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_EMERALD_ORE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_END_STONE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_FURNACE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_GLOWSTONE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_GOLD_BLOCK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_GOLD_ORE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_GRASS ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_GRAVEL ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_HARDENED_CLAY ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_ICE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_JUKEBOX ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_LAPIS_BLOCK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_SANDSTONE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_SAND ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_SILVERFISH_EGG ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_SPONGE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_STAINED_CLAY ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true; + a_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true; } diff --git a/src/BlockInfo.h b/src/BlockInfo.h index 40c1db867..d6d4e7430 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -16,18 +16,8 @@ class cBlockHandler; class cBlockInfo { public: - // tolua_end - cBlockInfo(); - - ~cBlockInfo(); - - /** (Re-)Initializes the internal BlockInfo structures. */ - static void Initialize(void); - - // tolua_begin - - /** Returns the associated BlockInfo structure. */ + /** Returns the associated BlockInfo structure for the specified block type. */ static cBlockInfo & Get(BLOCKTYPE a_Type); @@ -79,13 +69,18 @@ public: inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler; } - protected: + /** Storage for all the BlockInfo structures. */ + typedef cBlockInfo cBlockInfoArray[256]; - // TODO xdot: Change to std::vector to support dynamic block IDs - static cBlockInfo ms_Info[256]; + /** Creates a default BlockInfo structure, initializes all values to their defaults */ + cBlockInfo(); + /** Cleans up the stored values */ + ~cBlockInfo(); + /** Initializes the specified BlockInfo structures with block-specific values. */ + static void Initialize(cBlockInfoArray & a_BlockInfos); }; // tolua_export From f96955496f4e53105b045fb7f3fa7d34ed82b147 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 26 Jun 2014 15:56:03 +0200 Subject: [PATCH 20/58] GameMode check --- src/Entities/ArrowEntity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index e46d21515..6d74b387a 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -134,7 +134,7 @@ void cArrowEntity::CollectedBy(cPlayer * a_Dest) { if (m_IsInGround && !m_bIsCollected && CanPickup(*a_Dest)) { - if (m_PickupState == psInSurvivalOrCreative) + if (!a_Dest->IsGameModeCreative()) { int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW); if (NumAdded == 0) From cba273dc7e381c00b214fa0806679170f4e4e2f3 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 26 Jun 2014 17:20:48 +0200 Subject: [PATCH 21/58] Fixed a comment and changed CombineCount to short. --- src/Entities/Pickup.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index 44a65412f..969461a6a 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -41,7 +41,7 @@ public: cItem & Item = ((cPickup *)a_Entity)->GetItem(); if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem())) { - char CombineCount = Item.m_ItemCount; + short CombineCount = Item.m_ItemCount; if ((CombineCount + m_Pickup->GetItem().m_ItemCount) > Item.GetMaxStackSize()) { CombineCount = Item.GetMaxStackSize() - m_Pickup->GetItem().m_ItemCount; @@ -150,7 +150,7 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk) } } - if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't try to combine if someone has tried to combine me + if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't combine into an already full pickup { cPickupCombiningCallback PickupCombiningCallback(GetPosition(), this); m_World->ForEachEntity(PickupCombiningCallback); // Not ForEachEntityInChunk, otherwise pickups don't combine across chunk boundaries From bf3229867bc6a7d531fcb43c6519a951b043a732 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 26 Jun 2014 17:26:47 +0200 Subject: [PATCH 22/58] Add comment. --- src/Entities/ArrowEntity.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 6d74b387a..712ae3879 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -134,6 +134,7 @@ void cArrowEntity::CollectedBy(cPlayer * a_Dest) { if (m_IsInGround && !m_bIsCollected && CanPickup(*a_Dest)) { + // The arrow won't added to the inventory, when the player is creative if (!a_Dest->IsGameModeCreative()) { int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW); From b90b0a1dffff366df639f49445afb43ae1a8a73c Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 26 Jun 2014 17:51:19 +0200 Subject: [PATCH 23/58] FurnaceRecipe parser: Added an else branch, changed to a switch. --- src/FurnaceRecipe.cpp | 116 +++++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 46 deletions(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index 92b52c6e8..f8949d45f 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -68,64 +68,88 @@ void cFurnaceRecipe::ReloadRecipes(void) while (std::getline(f, ParsingLine)) { Line++; - ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove whitespace + TrimString(ParsingLine); if (ParsingLine.empty()) { continue; } - // Comments - if (ParsingLine[0] == '#') + switch (ParsingLine[0]) { - continue; - } - - if (ParsingLine[0] == '!') // Fuels start with a bang :) - { - int IItemID = 0, IItemCount = 0, IItemHealth = 0, IBurnTime = 0; - AString::size_type BeginPos = 1; // Begin at one after exclamation mark (bang) - - if ( - !ReadMandatoryNumber(BeginPos, ":", ParsingLine, Line, IItemID) || // Read item ID - !ReadOptionalNumbers(BeginPos, ":", "=", ParsingLine, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) - !ReadMandatoryNumber(BeginPos, "0123456789", ParsingLine, Line, IBurnTime, true) // Read item burn time - last value - ) + case '#': { - return; + // Comment + break; } - // 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); - continue; - } - else if (isdigit(ParsingLine[0])) // Recipes start with a numeral :) - { - 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, ":", ParsingLine, Line, IItemID) || // Read item ID - !ReadOptionalNumbers(BeginPos, ":", "@", ParsingLine, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) - !ReadMandatoryNumber(BeginPos, "=", ParsingLine, Line, IBurnTime) || // Read item burn time - !ReadMandatoryNumber(BeginPos, ":", ParsingLine, Line, OItemID) || // Read result ID - !ReadOptionalNumbers(BeginPos, ":", "012456789", ParsingLine, Line, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value - ) + case '!': { - return; + // 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, ":", ParsingLine, Line, IItemID) || // Read item ID + !ReadOptionalNumbers(BeginPos, ":", "=", ParsingLine, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) + !ReadMandatoryNumber(BeginPos, "0123456789", ParsingLine, Line, IBurnTime, true) // Read item burn time - last value + ) + { + 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); + break; } - // 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); - } - } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + // Recipe + 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, ":", ParsingLine, Line, IItemID) || // Read item ID + !ReadOptionalNumbers(BeginPos, ":", "@", ParsingLine, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) + !ReadMandatoryNumber(BeginPos, "=", ParsingLine, Line, IBurnTime) || // Read item burn time + !ReadMandatoryNumber(BeginPos, ":", ParsingLine, Line, OItemID) || // Read result ID + !ReadOptionalNumbers(BeginPos, ":", "012456789", ParsingLine, Line, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value + ) + { + 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); + break; + } + + default: + { + LOGWARNING("Error in furnace recipes at line %d: Unexpected text: \"%s\". Ignoring line.", + Line, ParsingLine.c_str() + ); + break; + } + } // switch (ParsingLine[0]) + } // while (getline(ParsingLine)) LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); } From 67e3c645d3a648ebd4d797019a993ed9c27cdb5e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 26 Jun 2014 17:52:37 +0200 Subject: [PATCH 24/58] FurnaceRecipe parser: Made the parser more forgiving. Errors don't cause a stop in the parsing, but rather just skip the offending line. --- src/FurnaceRecipe.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index f8949d45f..eff09a8d3 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -94,7 +94,7 @@ void cFurnaceRecipe::ReloadRecipes(void) !ReadMandatoryNumber(BeginPos, "0123456789", ParsingLine, Line, IBurnTime, true) // Read item burn time - last value ) { - return; + break; } // Add to fuel list: @@ -129,7 +129,7 @@ void cFurnaceRecipe::ReloadRecipes(void) !ReadOptionalNumbers(BeginPos, ":", "012456789", ParsingLine, Line, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value ) { - return; + break; } // Add to recipe list From 55bbdfa5d44a4bf7e66aa256ceba9ded3d2682dd Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 26 Jun 2014 18:18:41 +0200 Subject: [PATCH 25/58] FurnaceRecipe: Moved the parsing into separate functions for clarity. --- src/FurnaceRecipe.cpp | 120 +++++++++++++++++++++--------------------- src/FurnaceRecipe.h | 8 +++ 2 files changed, 68 insertions(+), 60 deletions(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index eff09a8d3..cc4098607 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -58,16 +58,16 @@ void cFurnaceRecipe::ReloadRecipes(void) std::ifstream f(FURNACE_RECIPE_FILE, std::ios::in); if (!f.good()) { - LOG("Could not open the furnace recipes file \"%s\"", FURNACE_RECIPE_FILE); + LOG("Could not open the furnace recipes file \"%s\". No furnace recipes are available.", FURNACE_RECIPE_FILE); return; } - unsigned int Line = 0; + unsigned int LineNum = 0; AString ParsingLine; while (std::getline(f, ParsingLine)) { - Line++; + LineNum++; TrimString(ParsingLine); if (ParsingLine.empty()) { @@ -84,68 +84,13 @@ void cFurnaceRecipe::ReloadRecipes(void) case '!': { - // 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, ":", ParsingLine, Line, IItemID) || // Read item ID - !ReadOptionalNumbers(BeginPos, ":", "=", ParsingLine, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) - !ReadMandatoryNumber(BeginPos, "0123456789", ParsingLine, Line, IBurnTime, true) // Read item burn time - last value - ) - { - break; - } - - // 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); - break; - } - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - // Recipe - 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, ":", ParsingLine, Line, IItemID) || // Read item ID - !ReadOptionalNumbers(BeginPos, ":", "@", ParsingLine, Line, IItemCount, IItemHealth) || // Read item count (and optionally health) - !ReadMandatoryNumber(BeginPos, "=", ParsingLine, Line, IBurnTime) || // Read item burn time - !ReadMandatoryNumber(BeginPos, ":", ParsingLine, Line, OItemID) || // Read result ID - !ReadOptionalNumbers(BeginPos, ":", "012456789", ParsingLine, Line, OItemCount, OItemHealth, true) // Read result count (and optionally health) - last value - ) - { - break; - } - - // 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); + AddFuelFromLine(ParsingLine, LineNum); break; } default: { - LOGWARNING("Error in furnace recipes at line %d: Unexpected text: \"%s\". Ignoring line.", - Line, ParsingLine.c_str() - ); + AddRecipeFromLine(ParsingLine, LineNum); break; } } // switch (ParsingLine[0]) @@ -158,6 +103,61 @@ 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 + ) + { + 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); +} + + + + + +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 + ) + { + 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); +} + + + + + void cFurnaceRecipe::PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing) { LOGWARN("Error parsing furnace recipes at line %i pos " SIZE_T_FMT ": missing '%s'", a_Line, a_Position, a_CharactersMissing.c_str()); diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index ab78b6051..77ed35a57 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -41,6 +41,14 @@ public: private: void ClearRecipes(void); + /** 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); + + /** 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); + /** Calls LOGWARN with the line, position, and error */ static void PrintParseError(unsigned int a_Line, size_t a_Position, const AString & a_CharactersMissing); From ec1015112c969798bae3efe87998c17d130b271a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 26 Jun 2014 18:20:12 +0200 Subject: [PATCH 26/58] Fixed misformed trimming. --- src/FurnaceRecipe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index cc4098607..412402cbc 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -68,7 +68,7 @@ void cFurnaceRecipe::ReloadRecipes(void) while (std::getline(f, ParsingLine)) { LineNum++; - TrimString(ParsingLine); + ParsingLine = TrimString(ParsingLine); if (ParsingLine.empty()) { continue; From 0df644c9f7775862c6c359b238e3440536092e04 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 26 Jun 2014 18:28:10 +0200 Subject: [PATCH 27/58] FurnaceRecipe parsing: Fixed whitespace removing. --- src/FurnaceRecipe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index 412402cbc..8add9610c 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -68,7 +68,7 @@ void cFurnaceRecipe::ReloadRecipes(void) while (std::getline(f, ParsingLine)) { LineNum++; - ParsingLine = TrimString(ParsingLine); + ParsingLine.erase(std::remove_if(ParsingLine.begin(), ParsingLine.end(), isspace), ParsingLine.end()); // Remove ALL whitespace from the line if (ParsingLine.empty()) { continue; From f68dc6210fe9b5f84c1f9fb3e57fc6285d71856c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 27 Jun 2014 09:24:11 +0200 Subject: [PATCH 28/58] Moved CodeCoverage into a separate cmake condition. --- SetFlags.cmake | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 6e2417a51..b01643f4e 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -26,10 +26,14 @@ endmacro() macro(set_flags) - # Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC): - if (NOT MSVC) + # Add coverage processing, if requested: + if (BUILD_WITH_COVERAGE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/cmake-coverage/") include(CodeCoverage) + endif() + + # Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC): + if (NOT MSVC) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG") set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -D_DEBUG") From 78442edf1d1c10e473741497d17342e7e330a964 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 27 Jun 2014 11:02:28 +0200 Subject: [PATCH 29/58] CMake: Added log message for coverage. --- SetFlags.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/SetFlags.cmake b/SetFlags.cmake index b01643f4e..903ae0ca8 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -28,6 +28,7 @@ endmacro() macro(set_flags) # Add coverage processing, if requested: if (BUILD_WITH_COVERAGE) + message("Including CodeCoverage") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/cmake-coverage/") include(CodeCoverage) endif() From 62669f64dec3f615518af56a864a72d5c18280b8 Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 27 Jun 2014 10:27:02 +0100 Subject: [PATCH 30/58] Update SetFlags.cmake --- SetFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 903ae0ca8..3f91e3d9c 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -27,7 +27,7 @@ endmacro() macro(set_flags) # Add coverage processing, if requested: - if (BUILD_WITH_COVERAGE) + if (CMAKE_BUILD_TYPE STREQUALS "COVERAGE") message("Including CodeCoverage") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/cmake-coverage/") include(CodeCoverage) From 9e1829e4e6de6cf3c6686a8add8317706968bd46 Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 27 Jun 2014 10:45:43 +0100 Subject: [PATCH 31/58] Update SetFlags.cmake --- SetFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 3f91e3d9c..0b5593b19 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -27,7 +27,7 @@ endmacro() macro(set_flags) # Add coverage processing, if requested: - if (CMAKE_BUILD_TYPE STREQUALS "COVERAGE") + if (${CMAKE_BUILD_TYPE} STREQUAL "COVERAGE") message("Including CodeCoverage") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/cmake-coverage/") include(CodeCoverage) From 833d3284356972b06c6f34d7b91d1360a9570c5e Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 27 Jun 2014 11:07:03 +0100 Subject: [PATCH 32/58] Added MSVC guard --- SetFlags.cmake | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 0b5593b19..e37dcd82c 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -27,10 +27,12 @@ endmacro() macro(set_flags) # Add coverage processing, if requested: - if (${CMAKE_BUILD_TYPE} STREQUAL "COVERAGE") - message("Including CodeCoverage") - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/cmake-coverage/") - include(CodeCoverage) + if (NOT MSVC) + if (${CMAKE_BUILD_TYPE} STREQUAL "COVERAGE") + message("Including CodeCoverage") + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/lib/cmake-coverage/") + include(CodeCoverage) + endif() endif() # Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC): From 9c29afb300200b661e35e3de3b6f26900f43517c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 27 Jun 2014 12:15:24 +0200 Subject: [PATCH 33/58] CMake: pthread is used only on Unix. --- SetFlags.cmake | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 6e2417a51..290804fb6 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -63,12 +63,16 @@ macro(set_flags) else() # Let gcc / clang know that we're compiling a multi-threaded app: - add_flags_cxx("-pthread") + if (UNIX) + add_flags_cxx("-pthread") + endif() + + # Make CLang use C++11, otherwise MSVC2008-supported extensions don't work ("override" keyword etc.): if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11") set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_COVERAGE} -std=c++11") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11") endif() # We use a signed char (fixes #640 on RasPi) From 563f706422554d1d8ff1121b9613ab9d34951a3b Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 27 Jun 2014 19:34:53 +0200 Subject: [PATCH 34/58] Removed the md5 library, obsoleted by PolarSSL. Fixes #1130. --- CMakeLists.txt | 1 - lib/md5/CMakeLists.txt | 12 -- lib/md5/md5.cpp | 369 -------------------------------- lib/md5/md5.h | 93 -------- src/Bindings/ManualBindings.cpp | 11 +- src/CMakeLists.txt | 2 +- src/ClientHandle.cpp | 22 +- 7 files changed, 16 insertions(+), 494 deletions(-) delete mode 100644 lib/md5/CMakeLists.txt delete mode 100644 lib/md5/md5.cpp delete mode 100644 lib/md5/md5.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 56dea1a34..422427414 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,6 @@ add_subdirectory(lib/tolua++/) add_subdirectory(lib/sqlite/) add_subdirectory(lib/expat/) add_subdirectory(lib/luaexpat/) -add_subdirectory(lib/md5/) # We use EXCLUDE_FROM_ALL so that only the explicit dependencies are used diff --git a/lib/md5/CMakeLists.txt b/lib/md5/CMakeLists.txt deleted file mode 100644 index cd9fe6320..000000000 --- a/lib/md5/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ - -cmake_minimum_required (VERSION 2.6) -project (md5) - -include_directories ("${PROJECT_SOURCE_DIR}/../../src/") - -file(GLOB SOURCE - "*.cpp" - "*.h" -) - -add_library(md5 ${SOURCE}) diff --git a/lib/md5/md5.cpp b/lib/md5/md5.cpp deleted file mode 100644 index eae0fc3f2..000000000 --- a/lib/md5/md5.cpp +++ /dev/null @@ -1,369 +0,0 @@ -/* MD5 - converted to C++ class by Frank Thilo (thilo@unix-ag.org) - for bzflag (http://www.bzflag.org) - - based on: - - md5.h and md5.c - reference implemantion of RFC 1321 - - Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - -*/ - -/* interface header */ -#include "md5.h" - -/* system implementation headers */ -#include - -#ifndef _WIN32 - #include -#endif - - - - - -// Constants for MD5Transform routine. -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -/////////////////////////////////////////////// - -// F, G, H and I are basic MD5 functions. -inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) { - return x&y | ~x&z; -} - -inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) { - return x&z | y&~z; -} - -inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) { - return x^y^z; -} - -inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) { - return y ^ (x | ~z); -} - -// rotate_left rotates x left n bits. -inline MD5::uint4 MD5::rotate_left(uint4 x, int n) { - return (x << n) | (x >> (32-n)); -} - -// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -// Rotation is separate from addition to prevent recomputation. -inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { - a = rotate_left(a+ F(b,c,d) + x + ac, s) + b; -} - -inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { - a = rotate_left(a + G(b,c,d) + x + ac, s) + b; -} - -inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { - a = rotate_left(a + H(b,c,d) + x + ac, s) + b; -} - -inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { - a = rotate_left(a + I(b,c,d) + x + ac, s) + b; -} - -////////////////////////////////////////////// - -// default ctor, just initailize -MD5::MD5() -{ - init(); -} - -////////////////////////////////////////////// - -// nifty shortcut ctor, compute MD5 for string and finalize it right away -MD5::MD5(const std::string &text) -{ - init(); - update(text.c_str(), text.length()); - finalize(); -} - -////////////////////////////// - -void MD5::init() -{ - finalized=false; - - count[0] = 0; - count[1] = 0; - - // load magic initialization constants. - state[0] = 0x67452301; - state[1] = 0xefcdab89; - state[2] = 0x98badcfe; - state[3] = 0x10325476; -} - -////////////////////////////// - -// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4. -void MD5::decode(uint4 output[], const uint1 input[], size_type len) -{ - for (unsigned int i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | - (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); -} - -////////////////////////////// - -// encodes input (uint4) into output (unsigned char). Assumes len is -// a multiple of 4. -void MD5::encode(uint1 output[], const uint4 input[], size_type len) -{ - for (size_type i = 0, j = 0; j < len; i++, j += 4) { - output[j] = input[i] & 0xff; - output[j+1] = (input[i] >> 8) & 0xff; - output[j+2] = (input[i] >> 16) & 0xff; - output[j+3] = (input[i] >> 24) & 0xff; - } -} - -////////////////////////////// - -// apply MD5 algo on a block -void MD5::transform(const uint1 block[blocksize]) -{ - uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - decode (x, block, blocksize); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - // Zeroize sensitive information. - memset(x, 0, sizeof x); -} - -////////////////////////////// - -// MD5 block update operation. Continues an MD5 message-digest -// operation, processing another message block -void MD5::update(const unsigned char input[], size_type length) -{ - // compute number of bytes mod 64 - size_type index = count[0] / 8 % blocksize; - - // Update number of bits - if ((count[0] += (length << 3)) < (length << 3)) - count[1]++; - count[1] += (length >> 29); - - // number of bytes we need to fill in buffer - size_type firstpart = 64 - index; - - size_type i; - - // transform as many times as possible. - if (length >= firstpart) - { - // fill buffer first, transform - memcpy(&buffer[index], input, firstpart); - transform(buffer); - - // transform chunks of blocksize (64 bytes) - for (i = firstpart; i + blocksize <= length; i += blocksize) - transform(&input[i]); - - index = 0; - } - else - i = 0; - - // buffer remaining input - memcpy(&buffer[index], &input[i], length-i); -} - -////////////////////////////// - -// for convenience provide a verson with signed char -void MD5::update(const char input[], size_type length) -{ - update((const unsigned char*)input, length); -} - -////////////////////////////// - -// MD5 finalization. Ends an MD5 message-digest operation, writing the -// the message digest and zeroizing the context. -MD5& MD5::finalize() -{ - static unsigned char padding[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - if (!finalized) { - // Save number of bits - unsigned char bits[8]; - encode(bits, count, 8); - - // pad out to 56 mod 64. - size_type index = count[0] / 8 % 64; - size_type padLen = (index < 56) ? (56 - index) : (120 - index); - update(padding, padLen); - - // Append length (before padding) - update(bits, 8); - - // Store state in digest - encode(digest, state, 16); - - // Zeroize sensitive information. - memset(buffer, 0, sizeof buffer); - memset(count, 0, sizeof count); - - finalized=true; - } - - return *this; -} - -////////////////////////////// - -// return hex representation of digest as string -std::string MD5::hexdigest() const -{ - if (!finalized) - return ""; - - char buf[33]; - for (int i=0; i<16; i++) - sprintf(buf+i*2, "%02x", digest[i]); - buf[32]=0; - - return std::string(buf); -} - -////////////////////////////// - -std::ostream& operator<<(std::ostream& out, MD5 md5) -{ - return out << md5.hexdigest(); -} - -////////////////////////////// - -std::string md5(const std::string & str) -{ - MD5 md5 = MD5(str); - - return md5.hexdigest(); -} diff --git a/lib/md5/md5.h b/lib/md5/md5.h deleted file mode 100644 index 3aa88ac22..000000000 --- a/lib/md5/md5.h +++ /dev/null @@ -1,93 +0,0 @@ -/* MD5 - converted to C++ class by Frank Thilo (thilo@unix-ag.org) - for bzflag (http://www.bzflag.org) - - based on: - - md5.h and md5.c - reference implementation of RFC 1321 - - Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - -*/ - -#ifndef BZF_MD5_H -#define BZF_MD5_H - -#include -#include - - -// a small class for calculating MD5 hashes of strings or byte arrays -// it is not meant to be fast or secure -// -// usage: 1) feed it blocks of uchars with update() -// 2) finalize() -// 3) get hexdigest() string -// or -// MD5(std::string).hexdigest() -// -// assumes that char is 8 bit and int is 32 bit -class MD5 -{ -public: - typedef unsigned int size_type; // must be 32bit - - MD5(); - MD5(const std::string& text); - void update(const unsigned char *buf, size_type length); - void update(const char *buf, size_type length); - MD5& finalize(); - std::string hexdigest() const; - friend std::ostream& operator<<(std::ostream&, MD5 md5); - -private: - void init(); - typedef unsigned char uint1; // 8bit - typedef unsigned int uint4; // 32bit - enum {blocksize = 64}; // VC6 won't eat a const static int here - - void transform(const uint1 block[blocksize]); - static void decode(uint4 output[], const uint1 input[], size_type len); - static void encode(uint1 output[], const uint4 input[], size_type len); - - bool finalized; - uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk - uint4 count[2]; // 64bit counter for number of bits (lo, hi) - uint4 state[4]; // digest so far - uint1 digest[16]; // the result - - // low level logic operations - static inline uint4 F(uint4 x, uint4 y, uint4 z); - static inline uint4 G(uint4 x, uint4 y, uint4 z); - static inline uint4 H(uint4 x, uint4 y, uint4 z); - static inline uint4 I(uint4 x, uint4 y, uint4 z); - static inline uint4 rotate_left(uint4 x, int n); - static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); - static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); - static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); - static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); -}; - -std::string md5(const std::string & str); - -#endif diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index f52d970bf..3692851eb 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -4,7 +4,7 @@ #include "ManualBindings.h" #undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" - +#include "polarssl\md5.h" #include "Plugin.h" #include "PluginLua.h" #include "PluginManager.h" @@ -25,7 +25,6 @@ #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/MobHeadEntity.h" #include "../BlockEntities/FlowerPotEntity.h" -#include "md5/md5.h" #include "../LineBlockTracer.h" #include "../WorldStorage/SchematicFileSerializer.h" #include "../CompositeChat.h" @@ -2001,9 +2000,11 @@ static int tolua_cPlugin_Call(lua_State * tolua_S) static int tolua_md5(lua_State* tolua_S) { - std::string SourceString = tolua_tostring(tolua_S, 1, 0); - std::string CryptedString = md5( SourceString ); - tolua_pushstring( tolua_S, CryptedString.c_str() ); + unsigned char Output[16]; + size_t len = 0; + const unsigned char * SourceString = (const unsigned char *)lua_tolstring(tolua_S, 1, &len); + md5(SourceString, len, Output); + lua_pushlstring(tolua_S, (const char *)Output, ARRAYCOUNT(Output)); return 1; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 335ce8315..deea92aec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -260,4 +260,4 @@ endif () if (WIN32) target_link_libraries(${EXECUTABLE} expat tolualib ws2_32.lib Psapi.lib) endif() -target_link_libraries(${EXECUTABLE} md5 luaexpat iniFile jsoncpp polarssl zlib lua sqlite) +target_link_libraries(${EXECUTABLE} luaexpat iniFile jsoncpp polarssl zlib lua sqlite) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 46083a8f1..611995148 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -30,7 +30,7 @@ #include "CompositeChat.h" #include "Items/ItemSword.h" -#include "md5/md5.h" +#include "polarssl/md5.h" @@ -239,18 +239,14 @@ AString cClientHandle::GenerateOfflineUUID(const AString & a_Username) // xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B // Generate an md5 checksum, and use it as base for the ID: - MD5 Checksum(a_Username); - AString UUID = Checksum.hexdigest(); - UUID[12] = '3'; // Version 3 UUID - UUID[16] = '8'; // Variant 1 UUID - - // Now the digest doesn't have the UUID slashes, but the client requires them, so add them into the appropriate positions: - UUID.insert(8, "-"); - UUID.insert(13, "-"); - UUID.insert(18, "-"); - UUID.insert(23, "-"); - - return UUID; + unsigned char MD5[16]; + md5((const unsigned char *)a_Username.c_str(), a_Username.length(), MD5); + return Printf("%02x%02x%02x%02x-%02x%02x-3%01x%02x-8%01x%02x-%02x%02x%02x%02x%02x%02x", + MD5[0], MD5[1], MD5[2], MD5[3], + MD5[4], MD5[5], MD5[6], MD5[7], + MD5[8], MD5[9], MD5[10], MD5[11], + MD5[12], MD5[13], MD5[14], MD5[15] + ); } From d7bc5c5bd32f8b5560403ecf6631040891fe9b9e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 27 Jun 2014 20:23:05 +0200 Subject: [PATCH 35/58] Added PolarSSL dependency to Bindings. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index deea92aec..4b78181ee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -134,7 +134,7 @@ if (NOT MSVC) Bindings/WebPlugin ) - target_link_libraries(Bindings lua sqlite tolualib) + target_link_libraries(Bindings lua sqlite tolualib polarssl) #clear file file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/BindingDependecies.txt) From 9926abd4f55d668dec9e06c2ba23fa3bb9209eeb Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 27 Jun 2014 20:56:29 +0200 Subject: [PATCH 36/58] Added generic entity-collecting. Now any cEntity can be collected, not only cPickups. This should help PR #1098. --- src/Chunk.cpp | 4 ++-- src/Chunk.h | 2 +- src/ChunkMap.cpp | 6 +++--- src/ChunkMap.h | 1 + src/ClientHandle.cpp | 4 ++-- src/ClientHandle.h | 2 +- src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.cpp | 4 ++-- src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol132.cpp | 8 ++++---- src/Protocol/Protocol132.h | 2 +- src/Protocol/Protocol17x.cpp | 4 ++-- src/Protocol/Protocol17x.h | 2 +- src/Protocol/ProtocolRecognizer.cpp | 4 ++-- src/Protocol/ProtocolRecognizer.h | 2 +- src/World.cpp | 11 ++++++++++- src/World.h | 1 + 17 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 1320d5ccd..0fee40cac 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2701,7 +2701,7 @@ void cChunk::BroadcastChunkData(cChunkDataSerializer & a_Serializer, const cClie -void cChunk::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude) +void cChunk::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude) { for (cClientHandleList::iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) { @@ -2709,7 +2709,7 @@ void cChunk::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_ { continue; } - (*itr)->SendCollectPickup(a_Pickup, a_Player); + (*itr)->SendCollectEntity(a_Entity, a_Player); } // for itr - LoadedByClient[] } diff --git a/src/Chunk.h b/src/Chunk.h index 7664a7afd..e9d964e05 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -279,7 +279,7 @@ public: void BroadcastBlockBreakAnimation(int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage, const cClientHandle * a_Exclude = NULL); void BroadcastBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); void BroadcastChunkData (cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); - void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); + void BroadcastCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index d2ccca94e..c9fb0b59e 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -419,16 +419,16 @@ void cChunkMap::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSeriali -void cChunkMap::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude) +void cChunkMap::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoGen(a_Pickup.GetChunkX(), ZERO_CHUNK_Y, a_Pickup.GetChunkZ()); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ()); if (Chunk == NULL) { return; } // It's perfectly legal to broadcast packets even to invalid chunks! - Chunk->BroadcastCollectPickup(a_Pickup, a_Player, a_Exclude); + Chunk->BroadcastCollectEntity(a_Entity, a_Player, a_Exclude); } diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 3ee0bab3c..433516490 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -70,6 +70,7 @@ public: void BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a_blockY, int a_blockZ, char a_stage, const cClientHandle * a_Exclude = NULL); void BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude); void BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); + void BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 46083a8f1..16cfe1aec 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2077,9 +2077,9 @@ void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializ -void cClientHandle::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player) +void cClientHandle::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) { - m_Protocol->SendCollectPickup(a_Pickup, a_Player); + m_Protocol->SendCollectEntity(a_Entity, a_Player); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 3e18cbdad..02bc0c719 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -123,7 +123,7 @@ public: void SendChat (const AString & a_Message, eMessageType a_ChatPrefix, const AString & a_AdditionalData = ""); void SendChat (const cCompositeChat & a_Message); void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer); - void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player); + void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player); void SendDestroyEntity (const cEntity & a_Entity); void SendDisconnect (const AString & a_Reason); void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ); diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index c6e569919..e08a5a51b 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -64,7 +64,7 @@ public: virtual void SendChat (const AString & a_Message) = 0; virtual void SendChat (const cCompositeChat & a_Message) = 0; virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0; - virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) = 0; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) = 0; virtual void SendDestroyEntity (const cEntity & a_Entity) = 0; virtual void SendDisconnect (const AString & a_Reason) = 0; virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; ///< Request the client to open up the sign editor for the sign (1.6+) diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 491058919..d53427bf7 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -274,11 +274,11 @@ void cProtocol125::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize -void cProtocol125::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player) +void cProtocol125::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) { cCSLock Lock(m_CSPacket); WriteByte(PACKET_COLLECT_PICKUP); - WriteInt (a_Pickup.GetUniqueID()); + WriteInt (a_Entity.GetUniqueID()); WriteInt (a_Player.GetUniqueID()); Flush(); } diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 85418f71f..747bf512d 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -36,7 +36,7 @@ public: virtual void SendChat (const AString & a_Message) override; virtual void SendChat (const cCompositeChat & a_Message) override; virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendDisconnect (const AString & a_Reason) override; virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index 1e3fc8de8..31cf99f53 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -188,19 +188,19 @@ void cProtocol132::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize -void cProtocol132::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player) +void cProtocol132::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) { cCSLock Lock(m_CSPacket); WriteByte(PACKET_COLLECT_PICKUP); - WriteInt (a_Pickup.GetUniqueID()); + WriteInt (a_Entity.GetUniqueID()); WriteInt (a_Player.GetUniqueID()); Flush(); // Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;) SendSoundEffect( "random.pop", - (int)(a_Pickup.GetPosX() * 8), (int)(a_Pickup.GetPosY() * 8), (int)(a_Pickup.GetPosZ() * 8), - 0.5, (float)(0.75 + ((float)((a_Pickup.GetUniqueID() * 23) % 32)) / 64) + (int)(a_Entity.GetPosX() * 8), (int)(a_Entity.GetPosY() * 8), (int)(a_Entity.GetPosZ() * 8), + 0.5, (float)(0.75 + ((float)((a_Entity.GetUniqueID() * 23) % 32)) / 64) ); } diff --git a/src/Protocol/Protocol132.h b/src/Protocol/Protocol132.h index 32bc7d581..e5d3ee80c 100644 --- a/src/Protocol/Protocol132.h +++ b/src/Protocol/Protocol132.h @@ -48,7 +48,7 @@ public: virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override; virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 02c577dc8..49fef0b8e 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -351,12 +351,12 @@ void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize -void cProtocol172::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player) +void cProtocol172::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) { ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x0d); // Collect Item packet - Pkt.WriteInt(a_Pickup.GetUniqueID()); + Pkt.WriteInt(a_Entity.GetUniqueID()); Pkt.WriteInt(a_Player.GetUniqueID()); } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 8be1d9211..07c8c8459 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -68,7 +68,7 @@ public: virtual void SendChat (const AString & a_Message) override; virtual void SendChat (const cCompositeChat & a_Message) override; virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendDisconnect (const AString & a_Reason) override; virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 80f5da25a..2436c49c3 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -181,10 +181,10 @@ void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSe -void cProtocolRecognizer::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player) +void cProtocolRecognizer::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) { ASSERT(m_Protocol != NULL); - m_Protocol->SendCollectPickup(a_Pickup, a_Player); + m_Protocol->SendCollectEntity(a_Entity, a_Player); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 5e178447c..a5a6c59b6 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -71,7 +71,7 @@ public: virtual void SendChat (const AString & a_Message) override; virtual void SendChat (const cCompositeChat & a_Message) override; virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override; - virtual void SendCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player) override; + virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override; virtual void SendDestroyEntity (const cEntity & a_Entity) override; virtual void SendDisconnect (const AString & a_Reason) override; virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) diff --git a/src/World.cpp b/src/World.cpp index 5b067b386..bd7694e96 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1877,9 +1877,18 @@ void cWorld::BroadcastChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer +void cWorld::BroadcastCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player, const cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastCollectEntity(a_Entity, a_Player, a_Exclude); +} + + + + + void cWorld::BroadcastCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude) { - m_ChunkMap->BroadcastCollectPickup(a_Pickup, a_Player, a_Exclude); + m_ChunkMap->BroadcastCollectEntity(a_Pickup, a_Player, a_Exclude); } diff --git a/src/World.h b/src/World.h index 2b7f78760..692d5a497 100644 --- a/src/World.h +++ b/src/World.h @@ -206,6 +206,7 @@ public: // tolua_end void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); + void BroadcastCollectEntity (const cEntity & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); From b6df30831d6b9b84bbb231dd8cfe4c1532666da4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 27 Jun 2014 23:13:26 +0100 Subject: [PATCH 37/58] Fixed server forcing players afloat * Fixes #1131 --- src/Entities/Entity.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index ee7ce06ac..2b256e766 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1090,7 +1090,10 @@ void cEntity::HandleAir(void) if (IsSubmerged()) { - SetSpeedY(1); // Float in the water + if (!IsPlayer()) // Players control themselves + { + SetSpeedY(1); // Float in the water + } // Either reduce air level or damage player if (m_AirLevel < 1) From 69befa9851e8957d9efa996b08217287a87dee8c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 27 Jun 2014 23:16:37 +0100 Subject: [PATCH 38/58] Fixed bad water/redstone simulator communication * Fixes #713 --- src/Simulator/FloodyFluidSimulator.cpp | 54 +++++++++++--------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index e95af3a1c..4ffda2365 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -217,14 +217,20 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i { ASSERT(a_NewMeta <= 8); // Invalid meta values ASSERT(a_NewMeta > 0); // Source blocks aren't spread - - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (!a_NearChunk->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta)) + + a_NearChunk = a_NearChunk->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((a_NearChunk == NULL) || (!a_NearChunk->IsValid())) { // Chunk not available return; } + + const int BlockX = a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX; + const int BlockZ = a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ; + + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + a_NearChunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta); if (IsAllowedBlock(BlockType)) { @@ -246,15 +252,9 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i a_RelX, a_RelY, a_RelZ, ItemTypeToString(NewBlock).c_str() ); - a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0); + a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0); - int BaseX = a_NearChunk->GetPosX() * cChunkDef::Width; - int BaseZ = a_NearChunk->GetPosZ() * cChunkDef::Width; - - BaseX += a_RelX; - BaseZ += a_RelZ; - - a_NearChunk->BroadcastSoundEffect("random.fizz", BaseX * 8, a_RelY * 8, BaseZ * 8, 0.5f, 1.5f); + a_NearChunk->BroadcastSoundEffect("random.fizz", BlockX * 8, a_RelY * 8, BlockZ * 8, 0.5f, 1.5f); return; } } @@ -267,15 +267,9 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i FLOG(" Water flowing into lava, turning lava at rel {%d, %d, %d} into %s", a_RelX, a_RelY, a_RelZ, ItemTypeToString(NewBlock).c_str() ); - a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0); + a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0); - int BaseX = a_NearChunk->GetPosX() * cChunkDef::Width; - int BaseZ = a_NearChunk->GetPosZ() * cChunkDef::Width; - - BaseX += a_RelX; - BaseZ += a_RelZ; - - a_NearChunk->BroadcastSoundEffect("random.fizz", BaseX * 8, a_RelY * 8, BaseZ * 8, 0.5f, 1.5f); + a_NearChunk->BroadcastSoundEffect("random.fizz", BlockX * 8, a_RelY * 8, BlockZ * 8, 0.5f, 1.5f); return; } } @@ -303,21 +297,17 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i m_World, PluginInterface, NULL, - a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX, + BlockX, a_RelY, - a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ + BlockZ ); } } // if (CanWashAway) - + // Spread: - FLOG(" Spreading to {%d, %d, %d} with meta %d", - a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX, - a_RelY, - a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ, - a_NewMeta - ); - a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); + FLOG(" Spreading to {%d, %d, %d} with meta %d", BlockX, a_RelY, BlockZ, a_NewMeta); + a_NearChunk->SetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); + m_World.GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, a_NearChunk); HardenBlock(a_NearChunk, a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); } @@ -409,13 +399,13 @@ bool cFloodyFluidSimulator::HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY if (a_Meta == 0) { // Source lava block - a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_OBSIDIAN, 0); + a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_OBSIDIAN, 0); return true; } // Ignore last lava level else if (a_Meta <= 4) { - a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_COBBLESTONE, 0); + a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_COBBLESTONE, 0); return true; } } From 0a20e19a64f88e66af68018cc46bc37dfdca7948 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 28 Jun 2014 00:29:19 +0100 Subject: [PATCH 39/58] Minor change to buttons and levers + They now detect if the block they are on occupies its voxel, instead of just being solid --- src/Blocks/BlockButton.h | 2 +- src/Blocks/BlockLever.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index 4b2f6f618..7d9af207d 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -102,7 +102,7 @@ public: AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && (cBlockInfo::IsSolid(BlockIsOn)); + return (a_RelY > 0) && (cBlockInfo::FullyOccupiesVoxel(BlockIsOn)); } } ; diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index f1d3ff6d2..afe43abf8 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -22,7 +22,7 @@ public: // Flip the ON bit on/off using the XOR bitwise operation NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08); - a_ChunkInterface.SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LEVER, Meta); // SetMeta doesn't work for unpowering levers, so setblock + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); a_WorldInterface.GetBroadcastManager().BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f); } @@ -104,7 +104,7 @@ public: AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn); + return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn); } From de543ff73fa8bb846030ffc702ed4db9f2e89f7b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 28 Jun 2014 00:29:32 +0100 Subject: [PATCH 40/58] Added more block exceptions to torches --- src/Blocks/BlockTorch.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index 8ddec8de1..44c33c429 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -154,7 +154,11 @@ public: if ( (BlockInQuestion == E_BLOCK_GLASS) || + (BlockInQuestion == E_BLOCK_STAINED_GLASS) || (BlockInQuestion == E_BLOCK_FENCE) || + (BlockInQuestion == E_BLOCK_SOULSAND) || + (BlockInQuestion == E_BLOCK_MOB_SPAWNER) || + (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) ) From 3e104c25e930eddedeb456c6cad456d7d01a38de Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 28 Jun 2014 12:49:08 +0200 Subject: [PATCH 41/58] Changed include folders to work for Bindings, too. --- src/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4b78181ee..dab97003e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,9 +1,9 @@ cmake_minimum_required (VERSION 2.8.2) project (MCServer) -include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/") -include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/jsoncpp/include") -include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include") +include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/") +include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/jsoncpp/include") +include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include") set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating PolarSSL++) set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities Generating/Prefabs) From 48639ee4d25268525d94b2da32924164ff055d82 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 28 Jun 2014 18:16:26 +0200 Subject: [PATCH 42/58] CMake: Added polarssl include dir as non-system. --- src/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dab97003e..2f4d6ea13 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -119,7 +119,8 @@ if (NOT MSVC) # lib dependencies are not included - + include_directories ("${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include") + #add cpp files here add_library(Bindings Bindings/Bindings From 1495bba17c04a5c756ba3a8eb3e881ef59aa1adf Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 28 Jun 2014 18:20:46 +0200 Subject: [PATCH 43/58] Fixed a silly path error in #include. --- src/Bindings/ManualBindings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 3692851eb..88d40bfd9 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -4,7 +4,7 @@ #include "ManualBindings.h" #undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" -#include "polarssl\md5.h" +#include "polarssl/md5.h" #include "Plugin.h" #include "PluginLua.h" #include "PluginManager.h" From 61cb08b54698e9b70f629858a6a9c5b389db8b3e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 28 Jun 2014 20:44:34 +0100 Subject: [PATCH 44/58] Implemented tripwire(s) (hooks) * Fixes #944 --- src/BlockInfo.cpp | 9 + src/Blocks/BlockHandler.cpp | 4 + src/Blocks/BlockStone.h | 2 - src/Blocks/BlockTripwire.h | 32 ++++ src/Blocks/BlockTripwireHook.h | 82 +++++++++ src/Items/ItemHandler.cpp | 2 + src/Items/ItemString.h | 39 +++++ .../IncrementalRedstoneSimulator.cpp | 163 ++++++++++++++++-- src/Simulator/IncrementalRedstoneSimulator.h | 8 + 9 files changed, 324 insertions(+), 17 deletions(-) create mode 100644 src/Blocks/BlockTripwire.h create mode 100644 src/Blocks/BlockTripwireHook.h create mode 100644 src/Items/ItemString.h diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 26525e264..16314290a 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -101,6 +101,8 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_TRIPWIRE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1; @@ -160,6 +162,8 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true; a_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true; + a_Info[E_BLOCK_TRIPWIRE ].m_Transparent = true; + a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_Transparent = true; a_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true; a_Info[E_BLOCK_TORCH ].m_Transparent = true; a_Info[E_BLOCK_VINES ].m_Transparent = true; @@ -197,6 +201,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_TNT ].m_OneHitDig = true; a_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true; a_Info[E_BLOCK_TORCH ].m_OneHitDig = true; + a_Info[E_BLOCK_TRIPWIRE ].m_OneHitDig = true; // Blocks that break when pushed by piston: @@ -239,6 +244,8 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true; a_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true; a_Info[E_BLOCK_TORCH ].m_PistonBreakable = true; + a_Info[E_BLOCK_TRIPWIRE ].m_PistonBreakable = true; + a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_PistonBreakable = true; a_Info[E_BLOCK_VINES ].m_PistonBreakable = true; a_Info[E_BLOCK_WATER ].m_PistonBreakable = true; a_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true; @@ -280,6 +287,8 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false; a_Info[E_BLOCK_TNT ].m_IsSnowable = false; a_Info[E_BLOCK_TORCH ].m_IsSnowable = false; + a_Info[E_BLOCK_TRIPWIRE ].m_IsSnowable = false; + a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_IsSnowable = false; a_Info[E_BLOCK_VINES ].m_IsSnowable = false; a_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false; a_Info[E_BLOCK_WATER ].m_IsSnowable = false; diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 405c9bf43..3ddb7531d 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -65,6 +65,8 @@ #include "BlockRedstoneRepeater.h" #include "BlockRedstoneTorch.h" #include "BlockTNT.h" +#include "BlockTripwire.h" +#include "BlockTripwireHook.h" #include "BlockSand.h" #include "BlockSapling.h" #include "BlockSideways.h" @@ -291,6 +293,8 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType); case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType); case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType); + case E_BLOCK_TRIPWIRE: return new cBlockTripwireHandler (a_BlockType); + case E_BLOCK_TRIPWIRE_HOOK: return new cBlockTripwireHookHandler (a_BlockType); case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType); case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType); // TODO: This needs a special handler case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType); diff --git a/src/Blocks/BlockStone.h b/src/Blocks/BlockStone.h index af4c6509a..cd5230f49 100644 --- a/src/Blocks/BlockStone.h +++ b/src/Blocks/BlockStone.h @@ -2,8 +2,6 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" -#include "../World.h" diff --git a/src/Blocks/BlockTripwire.h b/src/Blocks/BlockTripwire.h new file mode 100644 index 000000000..3ab17bf4a --- /dev/null +++ b/src/Blocks/BlockTripwire.h @@ -0,0 +1,32 @@ + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockTripwireHandler : + public cBlockHandler +{ +public: + cBlockTripwireHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_ITEM_STRING, 1, 0)); + } + + virtual const char * GetStepSound(void) override + { + return ""; + } +}; + + + + diff --git a/src/Blocks/BlockTripwireHook.h b/src/Blocks/BlockTripwireHook.h new file mode 100644 index 000000000..f849fb8ad --- /dev/null +++ b/src/Blocks/BlockTripwireHook.h @@ -0,0 +1,82 @@ +#pragma once + +#include "BlockHandler.h" +#include "MetaRotator.h" + + + + + +class cBlockTripwireHookHandler : + public cMetaRotator +{ +public: + cBlockTripwireHookHandler(BLOCKTYPE a_BlockType) + : cMetaRotator(a_BlockType) + { + } + + virtual bool GetPlacementBlockTypeMeta( + cChunkInterface & a_ChunkInterface, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = m_BlockType; + + a_BlockMeta = DirectionToMetadata(a_BlockFace); + + return true; + } + + inline static NIBBLETYPE DirectionToMetadata(eBlockFace a_Direction) + { + switch (a_Direction) + { + case BLOCK_FACE_XM: return 0x1; + case BLOCK_FACE_XP: return 0x3; + case BLOCK_FACE_ZM: return 0x2; + case BLOCK_FACE_ZP: return 0x0; + default: ASSERT(!"Unhandled tripwire hook direction!"); return 0x0; + } + } + + inline static eBlockFace MetadataToDirection(NIBBLETYPE a_Meta) + { + switch (a_Meta & 0x03) + { + case 0x1: return BLOCK_FACE_XM; + case 0x3: return BLOCK_FACE_XP; + case 0x2: return BLOCK_FACE_ZM; + case 0x0: return BLOCK_FACE_ZP; + default: ASSERT(!"Unhandled tripwire hook metadata!"); return BLOCK_FACE_NONE; + } + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Reset meta to 0 + a_Pickups.push_back(cItem(E_BLOCK_TRIPWIRE_HOOK, 1, 0)); + } + + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + NIBBLETYPE Meta; + a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta); + + AddFaceDirection(a_RelX, a_RelY, a_RelZ, MetadataToDirection(Meta), true); + BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); + + return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn); + } + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } +}; + + + + diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index f639423ae..a2fd4e3f8 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -44,6 +44,7 @@ #include "ItemSign.h" #include "ItemMobHead.h" #include "ItemSpawnEgg.h" +#include "ItemString.h" #include "ItemSugarcane.h" #include "ItemSword.h" @@ -129,6 +130,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_HEAD: return new cItemMobHeadHandler(a_ItemType); case E_ITEM_SNOWBALL: return new cItemSnowballHandler(); case E_ITEM_SPAWN_EGG: return new cItemSpawnEggHandler(a_ItemType); + case E_ITEM_STRING: return new cItemStringHandler(a_ItemType); case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemType); case E_ITEM_WOODEN_HOE: diff --git a/src/Items/ItemString.h b/src/Items/ItemString.h new file mode 100644 index 000000000..a97fbe0ce --- /dev/null +++ b/src/Items/ItemString.h @@ -0,0 +1,39 @@ + +#pragma once + +#include "ItemHandler.h" + + + + + +class cItemStringHandler : + public cItemHandler +{ +public: + cItemStringHandler(int a_ItemType) : + cItemHandler(a_ItemType) + { + } + + virtual bool IsPlaceable(void) override + { + return true; + } + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = E_BLOCK_TRIPWIRE; + a_BlockMeta = 0; + return true; + } +}; + + + + diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 10446a879..866a5b65a 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "IncrementalRedstoneSimulator.h" +#include "BoundingBox.h" #include "../BlockEntities/DropSpenserEntity.h" #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/CommandBlockEntity.h" @@ -12,10 +13,13 @@ #include "../Blocks/BlockButton.h" #include "../Blocks/BlockLever.h" #include "../Blocks/BlockPiston.h" +#include "../Blocks/BlockTripwireHook.h" + +#define WAKE_SIMULATOR_IF_DIRTY(a_Chunk, a_BlockX, a_BlockY, a_BlockZ) if (a_Chunk->IsRedstoneDirty()) WakeUp(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); + - cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulator(cWorld & a_World) : super(a_World), @@ -99,10 +103,11 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, // Changeable sources ((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) || ((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) || - ((Block == E_BLOCK_DETECTOR_RAIL) && (Meta & 0x08) == 0) || + ((Block == E_BLOCK_DETECTOR_RAIL) && ((Meta & 0x08) == 0)) || (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) || (((Block == E_BLOCK_STONE_PRESSURE_PLATE) || (Block == E_BLOCK_WOODEN_PRESSURE_PLATE)) && (Meta == 0)) || - (((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0)) + (((Block == E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE) || (Block == E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE)) && (Meta == 0)) || + ((Block == E_BLOCK_TRIPWIRE_HOOK) && ((Meta & 0x08) == 0)) ) { LOGD("cIncrementalRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); @@ -289,6 +294,9 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int switch (dataitr->Data) { case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_TRIPWIRE: HandleTripwire(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_TRIPWIRE_HOOK: HandleTripwireHook(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_WOODEN_PRESSURE_PLATE: case E_BLOCK_STONE_PRESSURE_PLATE: case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: @@ -1120,7 +1128,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R case E_BLOCK_STONE_PRESSURE_PLATE: { // MCS feature - stone pressure plates can only be triggered by players :D - cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.7f, false); + cPlayer * a_Player = m_World.FindClosestPlayer(Vector3f(BlockX + 0.5f, (float)a_RelBlockY, BlockZ + 0.5f), 0.5f, false); if (a_Player != NULL) { @@ -1131,7 +1139,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R else { m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0); - m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); } break; } @@ -1155,7 +1163,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); double Distance = (EntityPos - BlockPos).Length(); - if (Distance <= 0.7) + if (Distance <= 0.5) { m_NumberOfEntities++; } @@ -1177,7 +1185,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R }; cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); - m_World.ForEachEntity(PressurePlateCallback); + m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); unsigned char Power; NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); @@ -1198,7 +1206,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F); } m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); - m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); } break; @@ -1223,7 +1231,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); double Distance = (EntityPos - BlockPos).Length(); - if (Distance <= 0.7) + if (Distance <= 0.5) { m_NumberOfEntities++; } @@ -1232,7 +1240,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R bool GetPowerLevel(unsigned char & a_PowerLevel) const { - a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / (float)10), MAX_POWER_LEVEL); + a_PowerLevel = std::min((int)ceil(m_NumberOfEntities / 10.f), MAX_POWER_LEVEL); return (a_PowerLevel > 0); } @@ -1245,7 +1253,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R }; cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); - m_World.ForEachEntity(PressurePlateCallback); + m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); unsigned char Power; NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); @@ -1266,7 +1274,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F); } m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); - m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); } break; @@ -1291,7 +1299,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); double Distance = (EntityPos - BlockPos).Length(); - if (Distance <= 0.7) + if (Distance <= 0.5) { m_FoundEntity = true; return true; // Break out, we only need to know for plates that at least one entity is on top @@ -1313,7 +1321,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R } ; cPressurePlateCallback PressurePlateCallback(BlockX, a_RelBlockY, BlockZ); - m_World.ForEachEntity(PressurePlateCallback); + m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), PressurePlateCallback); NIBBLETYPE Meta = m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ); if (PressurePlateCallback.FoundEntity()) @@ -1333,7 +1341,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R m_Chunk->BroadcastSoundEffect("random.click", (int)((BlockX + 0.5) * 8.0), (int)((a_RelBlockY + 0.1) * 8.0), (int)((BlockZ + 0.5) * 8.0), 0.3F, 0.6F); } m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_META_PRESSURE_PLATE_RAISED); - m_World.WakeUpSimulators(BlockX, a_RelBlockY, BlockZ); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); } break; } @@ -1349,6 +1357,131 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_RelBlockX, int a_R +void cIncrementalRedstoneSimulator::HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; + int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; + int RelX = a_RelBlockX, RelZ = a_RelBlockZ; + bool FoundActivated = false; + eBlockFace FaceToGoTowards = cBlockTripwireHookHandler::MetadataToDirection(m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ)); + + for (int i = 0; i < 40; ++i) // Tripwires can be connected up to 40 blocks + { + BLOCKTYPE Type; + NIBBLETYPE Meta; + + AddFaceDirection(RelX, a_RelBlockY, RelZ, FaceToGoTowards); + m_Chunk->UnboundedRelGetBlock(RelX, a_RelBlockY, RelZ, Type, Meta); + + if (Type == E_BLOCK_TRIPWIRE) + { + if (Meta == 0x1) + { + FoundActivated = true; + } + } + else if (Type == E_BLOCK_TRIPWIRE_HOOK) + { + if (ReverseBlockFace(cBlockTripwireHookHandler::MetadataToDirection(Meta)) == FaceToGoTowards) + { + // Other hook not facing in opposite direction + break; + } + else + { + // Tripwire hook not connected at all, AND away all the power state bits + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); + return; + } + } + else + { + // Tripwire hook not connected at all, AND away all the power state bits + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x3); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); + return; + } + } + + if (FoundActivated) + { + // Connected and activated, set the 3rd and 4th highest bits + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) | 0xC); + SetAllDirsAsPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ); + } + else + { + // Connected but not activated, AND away the highest bit + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, (m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7) | 0x4); + WAKE_SIMULATOR_IF_DIRTY(m_Chunk, BlockX, a_RelBlockY, BlockZ); + } +} + + + + + +void cIncrementalRedstoneSimulator::HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) +{ + int BlockX = m_Chunk->GetPosX() * cChunkDef::Width + a_RelBlockX; + int BlockZ = m_Chunk->GetPosZ() * cChunkDef::Width + a_RelBlockZ; + + class cTripwireCallback : + public cEntityCallback + { + public: + cTripwireCallback(int a_BlockX, int a_BlockY, int a_BlockZ) : + m_FoundEntity(false), + m_X(a_BlockX), + m_Y(a_BlockY), + m_Z(a_BlockZ) + { + } + + virtual bool Item(cEntity * a_Entity) override + { + cBoundingBox bbWire(m_X, m_X + 1, m_Y, m_Y + 0.1, m_Z, m_Z + 1); + cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); + + if (bbEntity.DoesIntersect(bbWire)) + { + m_FoundEntity = true; + return true; // One entity is sufficient to trigger the wire + } + return false; + } + + bool FoundEntity(void) const + { + return m_FoundEntity; + } + + protected: + bool m_FoundEntity; + + int m_X; + int m_Y; + int m_Z; + }; + + cTripwireCallback TripwireCallback(BlockX, a_RelBlockY, BlockZ); + m_World.ForEachEntityInChunk(m_Chunk->GetPosX(), m_Chunk->GetPosZ(), TripwireCallback); + + if (TripwireCallback.FoundEntity()) + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x1); + } + else + { + m_Chunk->SetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, 0x0); + } +} + + + + + bool cIncrementalRedstoneSimulator::AreCoordsDirectlyPowered(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) { int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index 9c1f9460c..6cefdebf2 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -102,6 +102,11 @@ private: void HandleDaylightSensor(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); /** Handles pressure plates */ void HandlePressurePlate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ, BLOCKTYPE a_MyType); + /** Handles tripwire hooks + Performs correct meta and power setting for self by going in the direction it faces and looking for a continous line of tripwire bounded by another oppositely facing hook + If this line is complete, it verifies that at least on wire reports an entity is on top (via its meta), and performs its task + */ + void HandleTripwireHook(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); /* ==================== */ /* ====== CARRIERS ====== */ @@ -134,6 +139,8 @@ private: void HandleFenceGate(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); /** Handles noteblocks */ void HandleNoteBlock(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); + /** Handles tripwires */ + void HandleTripwire(int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ); /* ===================== */ /* ====== Helper functions ====== */ @@ -271,6 +278,7 @@ private: case E_BLOCK_TNT: case E_BLOCK_TRAPDOOR: case E_BLOCK_TRIPWIRE_HOOK: + case E_BLOCK_TRIPWIRE: case E_BLOCK_WOODEN_BUTTON: case E_BLOCK_WOODEN_DOOR: case E_BLOCK_WOODEN_PRESSURE_PLATE: From 5e66d9aeabcb759319c1045680443e72f0c1d75b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 28 Jun 2014 20:45:05 +0100 Subject: [PATCH 45/58] Fixed issue with breaking blocks at -1 coordinates --- src/ClientHandle.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 16cfe1aec..e7b876b24 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1085,12 +1085,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo void cClientHandle::FinishDigAnimation() { - if ( - !m_HasStartedDigging || // Hasn't received the DIG_STARTED packet - (m_LastDigBlockX == -1) || - (m_LastDigBlockY == -1) || - (m_LastDigBlockZ == -1) - ) + if (!m_HasStartedDigging) // Hasn't received the DIG_STARTED packet { return; } From 35dc056f0350c5fda178d0c28230f0a6b0feabbc Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 28 Jun 2014 21:10:59 +0100 Subject: [PATCH 46/58] Likely fixed too quick food depletion * Fixes FS427 properly, hopefully --- src/Entities/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 7b4fd219d..0abe50d11 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1913,7 +1913,7 @@ void cPlayer::HandleFood(void) { m_FoodTickTimer = 0; - if (m_FoodLevel >= 17) + if ((m_FoodLevel > 17) && (GetHealth() < GetMaxHealth())) { // Regenerate health from food, incur 3 pts of food exhaustion: Heal(1); From 50e112788bc46460ec2c1972f811264c1a9b04cc Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 29 Jun 2014 01:40:15 +0200 Subject: [PATCH 47/58] Send statistics to the player, when he logged in. --- src/ClientHandle.cpp | 3 +++ src/Protocol/Protocol17x.cpp | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 95dfaffb2..abe9a86f5 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -361,6 +361,9 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID) // Send scoreboard data World->GetScoreBoard().SendTo(*this); + // Send statistics + SendStatistics(m_Player->GetStatManager()); + // Delay the first ping until the client "settles down" // This should fix #889, "BadCast exception, cannot convert bit to fm" error in client cTimer t1; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 49fef0b8e..98fabedb2 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1221,10 +1221,9 @@ void cProtocol172::SendStatistics(const cStatManager & a_Manager) cPacketizer Pkt(*this, 0x37); Pkt.WriteVarInt(statCount); // TODO 2014-05-11 xdot: Optimization: Send "dirty" statistics only - for (unsigned int i = 0; i < (unsigned int)statCount; ++i) + for (size_t i = 0; i < (size_t)statCount; ++i) { StatValue Value = a_Manager.GetValue((eStatistic) i); - const AString & StatName = cStatInfo::GetName((eStatistic) i); Pkt.WriteString(StatName); From 3c631fc0f95f383c53d18cd7760ab2e3a8609240 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 29 Jun 2014 18:27:41 +0200 Subject: [PATCH 48/58] Fixed offline UUID generator. It generated invalid UUIDs, too many hex chars. --- src/ClientHandle.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index abe9a86f5..662ee7927 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -241,9 +241,11 @@ AString cClientHandle::GenerateOfflineUUID(const AString & a_Username) // Generate an md5 checksum, and use it as base for the ID: unsigned char MD5[16]; md5((const unsigned char *)a_Username.c_str(), a_Username.length(), MD5); + MD5[6] &= 0x0f; // Need to trim to 4 bits only... + MD5[8] &= 0x0f; // ... otherwise %01x overflows into two chars return Printf("%02x%02x%02x%02x-%02x%02x-3%01x%02x-8%01x%02x-%02x%02x%02x%02x%02x%02x", - MD5[0], MD5[1], MD5[2], MD5[3], - MD5[4], MD5[5], MD5[6], MD5[7], + MD5[0], MD5[1], MD5[2], MD5[3], + MD5[4], MD5[5], MD5[6], MD5[7], MD5[8], MD5[9], MD5[10], MD5[11], MD5[12], MD5[13], MD5[14], MD5[15] ); From b9d4431f6f2b60802d66da03f0b915bbd2c846cb Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 29 Jun 2014 22:44:01 +0100 Subject: [PATCH 49/58] Fixed respawning * Fixes #1103 --- src/ClientHandle.cpp | 4 ++-- src/ClientHandle.h | 2 +- src/Entities/Player.cpp | 2 +- src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.cpp | 6 +++--- src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol16x.cpp | 4 ++-- src/Protocol/Protocol16x.h | 2 +- src/Protocol/Protocol17x.cpp | 6 +++--- src/Protocol/Protocol17x.h | 2 +- src/Protocol/ProtocolRecognizer.cpp | 4 ++-- src/Protocol/ProtocolRecognizer.h | 2 +- 12 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 662ee7927..6b71f0924 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2397,9 +2397,9 @@ void cClientHandle::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effec -void cClientHandle::SendRespawn(const cWorld & a_World) +void cClientHandle::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks) { - m_Protocol->SendRespawn(a_World); + m_Protocol->SendRespawn(a_World, a_ShouldIgnoreDimensionChecks); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 02bc0c719..6f2c86b27 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -156,7 +156,7 @@ public: void SendPlayerSpawn (const cPlayer & a_Player); void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID); - void SendRespawn (const cWorld & a_World); + void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false); void SendExperience (void); void SendExperienceOrb (const cExpOrb & a_ExpOrb); void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 0abe50d11..daf1ef2cc 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -976,7 +976,7 @@ void cPlayer::Respawn(void) m_LifetimeTotalXp = 0; // ToDo: send score to client? How? - m_ClientHandle->SendRespawn(*m_World); + m_ClientHandle->SendRespawn(*m_World, true); // Extinguish the fire: StopBurning(); diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index e08a5a51b..ac872a2f2 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -100,7 +100,7 @@ public: virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0; virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 0; virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0; - virtual void SendRespawn (const cWorld & a_World) = 0; + virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) = 0; virtual void SendExperience (void) = 0; virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0; virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index d53427bf7..6dc2e918d 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -833,12 +833,12 @@ void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect -void cProtocol125::SendRespawn(const cWorld & a_World) +void cProtocol125::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks) { cCSLock Lock(m_CSPacket); - if (m_LastSentDimension == a_World.GetDimension()) + if ((m_LastSentDimension == a_World.GetDimension()) && !a_ShouldIgnoreDimensionChecks) { - // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do + // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do (unless we are respawning from death) return; } cPlayer * Player = m_Client->GetPlayer(); diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 747bf512d..9dbefd3a3 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -72,7 +72,7 @@ public: virtual void SendPlayerSpawn (const cPlayer & a_Player) override; virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; - virtual void SendRespawn (const cWorld & a_World) override; + virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override; virtual void SendExperience (void) override; virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp index 9e0f3f852..eba795f61 100644 --- a/src/Protocol/Protocol16x.cpp +++ b/src/Protocol/Protocol16x.cpp @@ -158,10 +158,10 @@ void cProtocol161::SendPlayerMaxSpeed(void) -void cProtocol161::SendRespawn(const cWorld & a_World) +void cProtocol161::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks) { // Besides sending the respawn, we need to also send the player max speed, otherwise the client reverts to super-fast - super::SendRespawn(a_World); + super::SendRespawn(a_World, a_ShouldIgnoreDimensionChecks); SendPlayerMaxSpeed(); } diff --git a/src/Protocol/Protocol16x.h b/src/Protocol/Protocol16x.h index e91dc8a1c..e6e79027e 100644 --- a/src/Protocol/Protocol16x.h +++ b/src/Protocol/Protocol16x.h @@ -42,7 +42,7 @@ protected: virtual void SendGameMode (eGameMode a_GameMode) override; virtual void SendHealth (void) override; virtual void SendPlayerMaxSpeed(void) override; - virtual void SendRespawn (const cWorld & a_World) override; + virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override; virtual void SendWindowOpen (const cWindow & a_Window) override; virtual int ParseEntityAction (void) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 98fabedb2..df9c6b50d 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -986,11 +986,11 @@ void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect -void cProtocol172::SendRespawn(const cWorld & a_World) +void cProtocol172::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks) { - if (m_LastSentDimension == a_World.GetDimension()) + if ((m_LastSentDimension == a_World.GetDimension()) && !a_ShouldIgnoreDimensionChecks) { - // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do + // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do (unless we are respawning from death) return; } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 07c8c8459..1a65cfa1c 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -104,7 +104,7 @@ public: virtual void SendPlayerSpawn (const cPlayer & a_Player) override; virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; - virtual void SendRespawn (const cWorld & a_World) override; + virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8 virtual void SendExperience (void) override; virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 2436c49c3..c0c9e08ee 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -556,10 +556,10 @@ void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a -void cProtocolRecognizer::SendRespawn(const cWorld & a_World) +void cProtocolRecognizer::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks) { ASSERT(m_Protocol != NULL); - m_Protocol->SendRespawn(a_World); + m_Protocol->SendRespawn(a_World, a_ShouldIgnoreDimensionChecks); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index a5a6c59b6..0a9a42e93 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -107,7 +107,7 @@ public: virtual void SendPlayerSpawn (const cPlayer & a_Player) override; virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override; virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override; - virtual void SendRespawn (const cWorld & a_World) override; + virtual void SendRespawn (const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks = false) override; virtual void SendExperience (void) override; virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override; From 6b8529544e7def8acb38ca80c01b4875ae313681 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 30 Jun 2014 21:00:06 +0200 Subject: [PATCH 50/58] Fixed tolua linking order. Ref.: #1044. --- lib/tolua++/CMakeLists.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index e68a0e15b..44a4f1c6f 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -44,8 +44,6 @@ file(GLOB BIN_SOURCE "src/bin/*.c" ) - - add_executable(tolua ${BIN_SOURCE}) add_library(tolualib ${LIB_SOURCE}) @@ -54,4 +52,4 @@ if(UNIX) target_link_libraries(tolua m ${DYNAMIC_LOADER}) endif() -target_link_libraries(tolua lua tolualib) +target_link_libraries(tolua tolualib lua) From a5a0533d793a64b76a84f23d4ca1754571ee0b40 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 30 Jun 2014 21:41:14 +0200 Subject: [PATCH 51/58] Fixed cFile compilation under MinGW. --- src/OSSupport/File.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 8c24fa541..addf8f928 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -7,6 +7,9 @@ #include "File.h" #include +#ifdef _WIN32 + #include // for _SH_DENYWRITE +#endif // _WIN32 From ac01a8e483f84d94f57c38d6882acd31d7e0fc91 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 30 Jun 2014 21:27:13 +0200 Subject: [PATCH 52/58] Fixed lua compilation under MinGW. --- lib/lua/CMakeLists.txt | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/lua/CMakeLists.txt b/lib/lua/CMakeLists.txt index 6e5e0f565..0a04d1ee6 100644 --- a/lib/lua/CMakeLists.txt +++ b/lib/lua/CMakeLists.txt @@ -11,21 +11,16 @@ file(GLOB SOURCE list(REMOVE_ITEM SOURCE "${PROJECT_SOURCE_DIR}/src/lua.c" "${PROJECT_SOURCE_DIR}/src/luac.c") # add headers to MSVC project files: -if (WIN32) +if (MSVC) file(GLOB HEADERS "src/*.h") list(REMOVE_ITEM SOURCE "${PROJECT_SOURCE_DIR}/src/lua.h" "${PROJECT_SOURCE_DIR}/src/luac.h") set(SOURCE ${SOURCE} ${HEADERS}) source_group("Sources" FILES ${SOURCE}) endif() + # Lua needs to be linked dynamically on Windows and statically on *nix, so that LuaRocks work if (WIN32) - - #for compiliers other than msvc we need to tell lua that its building as a dll - if (NOT MSVC) - add_flags_cxx(-DLUA_BUILD_AS_DLL=1) - endif() - add_library(lua SHARED ${SOURCE}) set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/MCServer) @@ -53,7 +48,7 @@ if (WIN32) ) endif() - set_target_properties(lua PROPERTIES OUTPUT_NAME "lua51") + set_target_properties(lua PROPERTIES OUTPUT_NAME "lua51" PREFIX "") # NOTE: The DLL for each configuration is stored at the same place, thus overwriting each other. # This is known, however such behavior is needed for LuaRocks - they always load "lua5.1.dll" or "lua51.dll" @@ -63,6 +58,7 @@ else() add_library(lua ${SOURCE}) endif() + # Tell Lua what dynamic loader to use (for LuaRocks): if (UNIX) add_definitions(-DLUA_USE_DLOPEN) From f9f3f7eac59c8de2bcb3f878849d355d5b9e3c9a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 30 Jun 2014 21:58:23 +0200 Subject: [PATCH 53/58] Fixed size_t printfing under MinGW. --- src/Globals.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Globals.h b/src/Globals.h index c5768facf..0c11429bd 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -71,9 +71,24 @@ #define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) - #define SIZE_T_FMT "%zu" - #define SIZE_T_FMT_PRECISION(x) "%" #x "zu" - #define SIZE_T_FMT_HEX "%zx" + #if defined(_WIN32) + // We're compiling on MinGW, which uses an old MSVCRT library that has no support for size_t printfing. + // We need direct size formats: + #if defined(_WIN64) + #define SIZE_T_FMT "%I64u" + #define SIZE_T_FMT_PRECISION(x) "%" #x "I64u" + #define SIZE_T_FMT_HEX "%I64x" + #else + #define SIZE_T_FMT "%u" + #define SIZE_T_FMT_PRECISION(x) "%" #x "u" + #define SIZE_T_FMT_HEX "%x" + #endif + #else + // We're compiling on Linux, so we can use libc's size_t printf format: + #define SIZE_T_FMT "%zu" + #define SIZE_T_FMT_PRECISION(x) "%" #x "zu" + #define SIZE_T_FMT_HEX "%zx" + #endif #define NORETURN __attribute((__noreturn__)) From 84272fb155d48f999441b7aaba9ca8b21584ad21 Mon Sep 17 00:00:00 2001 From: worktycho Date: Mon, 30 Jun 2014 22:21:07 +0100 Subject: [PATCH 54/58] Added dependecy of tolualib on lua --- lib/tolua++/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 44a4f1c6f..56ffc0dc1 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -46,6 +46,7 @@ file(GLOB BIN_SOURCE add_executable(tolua ${BIN_SOURCE}) add_library(tolualib ${LIB_SOURCE}) +target_link_library(tolualib lua) #m is the standard math librarys if(UNIX) From 0fb236bfe46782dc4e7c5b76db7b7c25671e3d66 Mon Sep 17 00:00:00 2001 From: worktycho Date: Mon, 30 Jun 2014 22:21:22 +0100 Subject: [PATCH 55/58] typo --- lib/tolua++/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 56ffc0dc1..12054323b 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -46,7 +46,7 @@ file(GLOB BIN_SOURCE add_executable(tolua ${BIN_SOURCE}) add_library(tolualib ${LIB_SOURCE}) -target_link_library(tolualib lua) +target_link_libraries(tolualib lua) #m is the standard math librarys if(UNIX) From 4f60f5aef4517d6d3eaf2ea9f7aae30e6a97da25 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 1 Jul 2014 06:40:38 +0200 Subject: [PATCH 56/58] Fixed linking order under MinGW. Ref.: #1044 --- lib/sqlite/CMakeLists.txt | 10 ++++++++-- src/CMakeLists.txt | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/sqlite/CMakeLists.txt b/lib/sqlite/CMakeLists.txt index 9add2280b..48bb5f15c 100644 --- a/lib/sqlite/CMakeLists.txt +++ b/lib/sqlite/CMakeLists.txt @@ -9,8 +9,14 @@ file(GLOB SOURCE ) -# add headers to MSVC project files: +# Lua is required as a DLL for LuaSQLite: if (WIN32) + add_definitions(-DLUA_BUILD_AS_DLL) +endif() + + +# add headers to MSVC project files: +if (MSVC) file(GLOB HEADERS "src/*.h") list(REMOVE_ITEM SOURCE "${PROJECT_SOURCE_DIR}/src/lua.h" "${PROJECT_SOURCE_DIR}/src/luac.h") set(SOURCE ${SOURCE} ${HEADERS}) @@ -25,5 +31,5 @@ endif() add_library(sqlite ${SOURCE}) if (UNIX) - target_link_libraries(sqlite ${DYNAMIC_LOADER}) + target_link_libraries(sqlite ${DYNAMIC_LOADER} lua) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2f4d6ea13..b1b880b7b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -261,4 +261,4 @@ endif () if (WIN32) target_link_libraries(${EXECUTABLE} expat tolualib ws2_32.lib Psapi.lib) endif() -target_link_libraries(${EXECUTABLE} luaexpat iniFile jsoncpp polarssl zlib lua sqlite) +target_link_libraries(${EXECUTABLE} luaexpat iniFile jsoncpp polarssl zlib sqlite lua) From 194678100a81134eeabb720d84fd987ef35946c6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 1 Jul 2014 06:41:35 +0200 Subject: [PATCH 57/58] Ignore Code:::Blocks project files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 859ef28ea..4a319c5ef 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ cloc.xsl ## Eclipse .cproject .project +*.cbp # world inside source ChunkWorx.ini From eb8244f1c286ec33c30ba205eb5cebc1f2a0430d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 1 Jul 2014 08:01:39 +0200 Subject: [PATCH 58/58] Proper sqlite dependency fix. --- lib/sqlite/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/sqlite/CMakeLists.txt b/lib/sqlite/CMakeLists.txt index 48bb5f15c..993dac146 100644 --- a/lib/sqlite/CMakeLists.txt +++ b/lib/sqlite/CMakeLists.txt @@ -29,7 +29,8 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") endif() add_library(sqlite ${SOURCE}) +target_link_libraries(sqlite lua) if (UNIX) - target_link_libraries(sqlite ${DYNAMIC_LOADER} lua) + target_link_libraries(sqlite ${DYNAMIC_LOADER}) endif()