From baf2d8892127cd6da9d2f6f2f8d991d617c87800 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 26 Feb 2014 23:29:14 +0000 Subject: Implemented ballistic missiles (fireworks) + Added fireworks --- src/CraftingRecipes.cpp | 89 ++++++++++- src/Entities/ProjectileEntity.cpp | 87 ++++++----- src/Entities/ProjectileEntity.h | 12 +- src/Item.cpp | 22 ++- src/Item.h | 16 +- src/Items/ItemThrowable.h | 6 +- src/Protocol/Protocol17x.cpp | 77 ++++++---- src/World.cpp | 4 +- src/World.h | 2 +- src/WorldStorage/FastNBT.h | 2 +- src/WorldStorage/FireworksSerializer.cpp | 250 +++++++++++++++++++++++++++++++ src/WorldStorage/FireworksSerializer.h | 88 +++++++++++ src/WorldStorage/NBTChunkSerializer.cpp | 14 +- src/WorldStorage/WSSAnvil.cpp | 6 + 14 files changed, 591 insertions(+), 84 deletions(-) create mode 100644 src/WorldStorage/FireworksSerializer.cpp create mode 100644 src/WorldStorage/FireworksSerializer.h (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index fb1a10cca..41de0da8c 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -1,4 +1,4 @@ - + // CraftingRecipes.cpp // Interfaces to the cCraftingRecipes class representing the storage of crafting recipes @@ -762,6 +762,93 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti Recipe->m_Ingredients.push_back(*itrS); } Recipe->m_Ingredients.insert(Recipe->m_Ingredients.end(), MatchedSlots.begin(), MatchedSlots.end()); + + + // Henceforth is code to handle fireworks + // We use Recipe instead of a_Recipe because we want the wildcard ingredients' slot numbers as well, which was just added previously + + if (Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_ROCKET) + { + for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + { + switch (itr->m_Item.m_ItemType) + { + case E_ITEM_FIREWORK_STAR: + { + // Result was a rocket, found a star - copy star data to rocket data + int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); + Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); + break; + } + case E_ITEM_GUNPOWDER: + { + // Gunpowder - increase flight time + Recipe->m_Result.m_FireworkItem.m_FlightTimeInTicks += 20; + break; + } + case E_ITEM_PAPER: break; + default: LOG("Unexpected item in firework rocket recipe, was the crafting file fireworks section changed?"); break; + } + } + } + else if (Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_STAR) + { + for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + { + switch (itr->m_Item.m_ItemType) + { + case E_ITEM_FIREWORK_STAR: + { + // Result was star, found another star - probably adding fade colours, but copy data over anyhow + int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); + Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); + break; + } + case E_ITEM_DYE: + { + // Found a dye in ingredients... + for (cRecipeSlots::const_iterator itrnumerodos = Recipe->m_Ingredients.begin(); itrnumerodos != Recipe->m_Ingredients.end(); ++itrnumerodos) + { + // Loop through ingredients. Can we find a star? + if (itrnumerodos->m_Item.m_ItemType == E_ITEM_FIREWORK_STAR) + { + // Yes, this is definately adding fade colours, unless crafting.txt was changed :/ + for (cRecipeSlots::const_iterator itrnumerotres = Recipe->m_Ingredients.begin(); itrnumerotres != Recipe->m_Ingredients.end(); ++itrnumerotres) + { + // Loop again, can we find dye? + if (itrnumerotres->m_Item.m_ItemType == E_ITEM_DYE) + { + // Yep, push back fade colour and exit the loop + // There is a potential for flexibility here - we can move the goto out of the loop, so we can add multiple dyes (∴ multiple fade colours) + // That will require lots of dye-adding to crafting.txt though - TODO, perchance? + int GridID = (itrnumerotres->x + a_OffsetX) + a_GridStride * (itrnumerotres->y + a_OffsetY); + Recipe->m_Result.m_FireworkItem.m_FadeColours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); + goto next; + } + } + } + } + + // Just normal crafting of star, push back normal colours + int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); + Recipe->m_Result.m_FireworkItem.m_Colours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); + + next: + break; + } + case E_ITEM_GUNPOWDER: break; + case E_ITEM_DIAMOND: Recipe->m_Result.m_FireworkItem.m_HasTrail = true; break; + case E_ITEM_GLOWSTONE_DUST: Recipe->m_Result.m_FireworkItem.m_HasFlicker = true; break; + + case E_ITEM_FIRE_CHARGE: Recipe->m_Result.m_FireworkItem.m_Type = 1; break; + case E_ITEM_GOLD_NUGGET: Recipe->m_Result.m_FireworkItem.m_Type = 2; break; + case E_ITEM_FEATHER: Recipe->m_Result.m_FireworkItem.m_Type = 4; break; + case E_ITEM_HEAD: Recipe->m_Result.m_FireworkItem.m_Type = 3; break; + default: LOG("Unexpected item in firework star recipe, was the crafting file fireworks section changed?"); break; // ermahgerd BARD ardmins + } + } + } + return Recipe.release(); } diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index ef82c6e94..be8e24540 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -214,7 +214,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Ve -cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d * a_Speed) +cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item, const Vector3d * a_Speed) { Vector3d Speed; if (a_Speed != NULL) @@ -231,8 +231,15 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, case pkGhastFireball: return new cGhastFireballEntity (a_Creator, a_X, a_Y, a_Z, Speed); case pkFireCharge: return new cFireChargeEntity (a_Creator, a_X, a_Y, a_Z, Speed); case pkExpBottle: return new cExpBottleEntity (a_Creator, a_X, a_Y, a_Z, Speed); - case pkFirework: return new cFireworkEntity (a_Creator, a_X, a_Y, a_Z ); - // TODO: the rest + case pkFirework: + { + if (a_Item.m_FireworkItem.m_Colours.empty()) + { + return NULL; + } + + return new cFireworkEntity(a_Creator, a_X, a_Y, a_Z, a_Item); + } } LOGWARNING("%s: Unknown projectile kind: %d", __FUNCTION__, a_Kind); @@ -276,6 +283,7 @@ AString cProjectileEntity::GetMCAClassName(void) const case pkExpBottle: return "ThrownExpBottle"; case pkSplashPotion: return "ThrownPotion"; case pkWitherSkull: return "WitherSkull"; + case pkFirework: return "Firework"; case pkFishingFloat: return ""; // Unknown, perhaps MC doesn't save this? } ASSERT(!"Unhandled projectile entity kind!"); @@ -693,8 +701,10 @@ void cExpBottleEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_H /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cFireworkEntity : -cFireworkEntity::cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z) : -super(pkFirework, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25) +cFireworkEntity::cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item) : +super(pkFirework, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25), + m_ExplodeTimer(0), + m_FireworkItem(a_Item) { } @@ -702,30 +712,20 @@ super(pkFirework, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25) -void cFireworkEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) +void cFireworkEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) { - if ((a_HitFace != BLOCK_FACE_BOTTOM) && (a_HitFace != BLOCK_FACE_NONE)) + int RelX = POSX_TOINT - a_Chunk.GetPosX() * cChunkDef::Width; + int RelZ = POSZ_TOINT - a_Chunk.GetPosZ() * cChunkDef::Width; + int PosY = POSY_TOINT; + + if ((PosY < 0) || (PosY >= cChunkDef::Height)) { - return; + goto setspeed; } - SetSpeed(0, 0, 0); - SetPosition(GetPosX(), GetPosY() - 0.5, GetPosZ()); - - m_IsInGround = true; - - BroadcastMovementUpdate(); -} - - - - - -void cFireworkEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) -{ if (m_IsInGround) { - if (a_Chunk.GetBlock((int)GetPosX(), (int)GetPosY() + 1, (int)GetPosZ()) == E_BLOCK_AIR) + if (a_Chunk.GetBlock(RelX, POSY_TOINT + 1, RelZ) == E_BLOCK_AIR) { m_IsInGround = false; } @@ -734,28 +734,35 @@ void cFireworkEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) return; } } + else + { + if (a_Chunk.GetBlock(RelX, POSY_TOINT + 1, RelZ) != E_BLOCK_AIR) + { + OnHitSolidBlock(GetPosition(), BLOCK_FACE_YM); + return; + } + } - Vector3d PerTickSpeed = GetSpeed() / 20; - Vector3d Pos = GetPosition(); +setspeed: + AddSpeedY(1); + AddPosition(GetSpeed() * (a_Dt / 1000)); +} - // Trace the tick's worth of movement as a line: - Vector3d NextPos = Pos + PerTickSpeed; - cProjectileTracerCallback TracerCallback(this); - if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos)) + + + + +void cFireworkEntity::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + + if (m_ExplodeTimer == m_FireworkItem.m_FireworkItem.m_FlightTimeInTicks) { - // Something has been hit, abort all other processing - return; + m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_FIREWORK_EXPLODE); + Destroy(); } - // The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff - - // Update the position: - SetPosition(NextPos); - // Add slowdown and gravity effect to the speed: - Vector3d NewSpeed(GetSpeed()); - NewSpeed.y += 2; - NewSpeed *= TracerCallback.GetSlowdownCoeff(); - SetSpeed(NewSpeed); + m_ExplodeTimer++; } diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index e80592999..fac592d16 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -46,7 +46,7 @@ public: cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, double a_Width, double a_Height); cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height); - static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d * a_Speed = NULL); + static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item, const Vector3d * a_Speed = NULL); /// Called by the physics blocktracer when the entity hits a solid block, the hit position and the face hit (BLOCK_FACE_) is given virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace); @@ -305,13 +305,19 @@ public: CLASS_PROTODEF(cFireworkEntity); - cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z); + cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item); + const cItem & GetItem(void) const { return m_FireworkItem; } protected: // cProjectileEntity overrides: - virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + +private: + + int m_ExplodeTimer; + cItem m_FireworkItem; // tolua_begin diff --git a/src/Item.cpp b/src/Item.cpp index 9170006b6..61d57e763 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" @@ -139,6 +139,16 @@ void cItem::GetJson(Json::Value & a_OutValue) const { a_OutValue["Lore"] = m_Lore; } + + if ((m_ItemType == E_ITEM_FIREWORK_ROCKET) || (m_ItemType == E_ITEM_FIREWORK_STAR)) + { + a_OutValue["Flicker"] = m_FireworkItem.m_HasFlicker; + a_OutValue["Trail"] = m_FireworkItem.m_HasTrail; + a_OutValue["Type"] = m_FireworkItem.m_Type; + a_OutValue["FlightTimeInTicks"] = m_FireworkItem.m_FlightTimeInTicks; + a_OutValue["Colours"] = m_FireworkItem.ColoursToString(m_FireworkItem); + a_OutValue["FadeColours"] = m_FireworkItem.FadeColoursToString(m_FireworkItem); + } } } @@ -157,6 +167,16 @@ void cItem::FromJson(const Json::Value & a_Value) m_Enchantments.AddFromString(a_Value.get("ench", "").asString()); m_CustomName = a_Value.get("Name", "").asString(); m_Lore = a_Value.get("Lore", "").asString(); + + if ((m_ItemType == E_ITEM_FIREWORK_ROCKET) || (m_ItemType == E_ITEM_FIREWORK_STAR)) + { + m_FireworkItem.m_HasFlicker = a_Value.get("Flicker", false).asBool(); + m_FireworkItem.m_HasTrail = a_Value.get("Trail", false).asBool(); + m_FireworkItem.m_Type = (NIBBLETYPE)a_Value.get("Type", 0).asInt(); + m_FireworkItem.m_FlightTimeInTicks = (short)a_Value.get("FlightTimeInTicks", 0).asInt(); + m_FireworkItem.ColoursFromString(a_Value.get("Colours", "").asString(), m_FireworkItem); + m_FireworkItem.FadeColoursFromString(a_Value.get("FadeColours", "").asString(), m_FireworkItem); + } } } diff --git a/src/Item.h b/src/Item.h index cc3b3c961..4bdfb12dd 100644 --- a/src/Item.h +++ b/src/Item.h @@ -11,6 +11,7 @@ #include "Defines.h" #include "Enchantments.h" +#include "WorldStorage/FireworksSerializer.h" @@ -38,7 +39,8 @@ public: m_ItemCount(0), m_ItemDamage(0), m_CustomName(""), - m_Lore("") + m_Lore(""), + m_FireworkItem() { } @@ -57,7 +59,8 @@ public: m_ItemDamage (a_ItemDamage), m_Enchantments(a_Enchantments), m_CustomName (a_CustomName), - m_Lore (a_Lore) + m_Lore (a_Lore), + m_FireworkItem() { if (!IsValidItem(m_ItemType)) { @@ -77,7 +80,8 @@ public: m_ItemDamage (a_CopyFrom.m_ItemDamage), m_Enchantments(a_CopyFrom.m_Enchantments), m_CustomName (a_CopyFrom.m_CustomName), - m_Lore (a_CopyFrom.m_Lore) + m_Lore (a_CopyFrom.m_Lore), + m_FireworkItem(a_CopyFrom.m_FireworkItem) { } @@ -90,6 +94,7 @@ public: m_Enchantments.Clear(); m_CustomName = ""; m_Lore = ""; + m_FireworkItem.EmptyData(); } @@ -115,7 +120,8 @@ public: (m_ItemDamage == a_Item.m_ItemDamage) && (m_Enchantments == a_Item.m_Enchantments) && (m_CustomName == a_Item.m_CustomName) && - (m_Lore == a_Item.m_Lore) + (m_Lore == a_Item.m_Lore) && + m_FireworkItem.IsEqualTo(a_Item.m_FireworkItem) ); } @@ -177,6 +183,8 @@ public: cEnchantments m_Enchantments; AString m_CustomName; AString m_Lore; + + cFireworkItem m_FireworkItem; }; // tolua_end diff --git a/src/Items/ItemThrowable.h b/src/Items/ItemThrowable.h index 46049f961..c6a4e714e 100644 --- a/src/Items/ItemThrowable.h +++ b/src/Items/ItemThrowable.h @@ -35,7 +35,7 @@ public: Vector3d Pos = a_Player->GetThrowStartPos(); Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff; - a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, &Speed); + a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed); return true; } @@ -127,13 +127,13 @@ public: return false; } + a_World->CreateProjectile(a_BlockX + 0.5, a_BlockY + 1, a_BlockZ + 0.5, m_ProjectileKind, a_Player, a_Player->GetEquippedItem()); + if (!a_Player->IsGameModeCreative()) { a_Player->GetInventory().RemoveOneEquippedItem(); } - a_World->CreateProjectile(a_BlockX + 0.5, a_BlockY + 1, a_BlockZ + 0.5, m_ProjectileKind, a_Player, 0); - return true; } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 992023464..e0f02930c 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2069,36 +2069,47 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) // Load enchantments and custom display names from the NBT data: for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag)) { - if ( - (NBT.GetType(tag) == TAG_List) && - ( - (NBT.GetName(tag) == "ench") || - (NBT.GetName(tag) == "StoredEnchantments") - ) - ) + AString TagName = NBT.GetName(tag); + switch (NBT.GetType(tag)) { - EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag); - } - else if ((NBT.GetType(tag) == TAG_Compound) && (NBT.GetName(tag) == "display")) // Custom name and lore tag - { - for (int displaytag = NBT.GetFirstChild(tag); displaytag >= 0; displaytag = NBT.GetNextSibling(displaytag)) + case TAG_List: { - if ((NBT.GetType(displaytag) == TAG_String) && (NBT.GetName(displaytag) == "Name")) // Custon name tag + if ((TagName == "ench") || (TagName == "StoredEnchantments")) // Enchantments tags { - a_Item.m_CustomName = NBT.GetString(displaytag); + EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag); } - else if ((NBT.GetType(displaytag) == TAG_List) && (NBT.GetName(displaytag) == "Lore")) // Lore tag + break; + } + case TAG_Compound: + { + if (TagName == "display") // Custom name and lore tag { - AString Lore; - - for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings + for (int displaytag = NBT.GetFirstChild(tag); displaytag >= 0; displaytag = NBT.GetNextSibling(displaytag)) { - AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a newline, used internally by MCS to display a new line in the client; don't forget to c_str ;) + if ((NBT.GetType(displaytag) == TAG_String) && (NBT.GetName(displaytag) == "Name")) // Custon name tag + { + a_Item.m_CustomName = NBT.GetString(displaytag); + } + else if ((NBT.GetType(displaytag) == TAG_List) && (NBT.GetName(displaytag) == "Lore")) // Lore tag + { + AString Lore; + + for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings + { + AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a newline, used internally by MCS to display a new line in the client; don't forget to c_str ;) + } + + a_Item.m_Lore = Lore; + } } - - a_Item.m_Lore = Lore; } + else if ((TagName == "Fireworks") || (TagName == "Explosion")) + { + cFireworkItem::ParseFromNBT(a_Item.m_FireworkItem, NBT, tag, (ENUM_ITEM_ID)a_Item.m_ItemType); + } + break; } + default: LOGD("Unimplemented NBT data when parsing!"); break; } } } @@ -2262,7 +2273,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) WriteByte (a_Item.m_ItemCount); WriteShort(a_Item.m_ItemDamage); - if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty()) + if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR)) { WriteShort(-1); return; @@ -2301,6 +2312,10 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) } Writer.EndCompound(); } + if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) + { + cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, (ENUM_ITEM_ID)a_Item.m_ItemType); + } Writer.Finish(); AString Compressed; CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); @@ -2465,10 +2480,22 @@ void cProtocol172::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity) } case cEntity::etProjectile: { - if (((cProjectileEntity &)a_Entity).GetProjectileKind() == cProjectileEntity::pkArrow) + cProjectileEntity & Projectile = (cProjectileEntity &)a_Entity; + switch (Projectile.GetProjectileKind()) { - WriteByte(0x10); - WriteByte(((const cArrowEntity &)a_Entity).IsCritical() ? 1 : 0); + case cProjectileEntity::pkArrow: + { + WriteByte(0x10); + WriteByte(((const cArrowEntity &)a_Entity).IsCritical() ? 1 : 0); + break; + } + case cProjectileEntity::pkFirework: + { + WriteByte(0xA8); + WriteItem(((const cFireworkEntity &)a_Entity).GetItem()); + break; + } + default: break; } break; } diff --git a/src/World.cpp b/src/World.cpp index ffdae2a37..ffb463169 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2904,9 +2904,9 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster) -int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const Vector3d * a_Speed) +int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem a_Item, const Vector3d * a_Speed) { - cProjectileEntity * Projectile = cProjectileEntity::Create(a_Kind, a_Creator, a_PosX, a_PosY, a_PosZ, a_Speed); + cProjectileEntity * Projectile = cProjectileEntity::Create(a_Kind, a_Creator, a_PosX, a_PosY, a_PosZ, a_Item, a_Speed); if (Projectile == NULL) { return -1; diff --git a/src/World.h b/src/World.h index 4b74f7aba..4fdbd8c0d 100644 --- a/src/World.h +++ b/src/World.h @@ -693,7 +693,7 @@ public: int SpawnMobFinalize(cMonster* a_Monster); /** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise */ - int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const Vector3d * a_Speed = NULL); // tolua_export + int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem a_Item, const Vector3d * a_Speed = NULL); // tolua_export /** Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread! */ int GetTickRandomNumber(unsigned a_Range) { return (int)(m_TickRand.randInt(a_Range)); } diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index a78b610cb..e7e56282f 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -266,7 +266,7 @@ protected: eTagType m_ItemType; // for TAG_List, the element type } ; - static const int MAX_STACK = 50; // Highliy doubtful that an NBT would be constructed this many levels deep + static const int MAX_STACK = 50; // Highly doubtful that an NBT would be constructed this many levels deep // These two fields emulate a stack. A raw array is used due to speed issues - no reallocations are allowed. sParent m_Stack[MAX_STACK]; diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp new file mode 100644 index 000000000..eeb4e39ee --- /dev/null +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -0,0 +1,250 @@ + +#include "Globals.h" +#include "FireworksSerializer.h" +#include "WorldStorage/FastNBT.h" +#include + + + + + +void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFastNBTWriter & a_Writer, const ENUM_ITEM_ID a_Type) +{ + switch (a_Type) + { + case E_ITEM_FIREWORK_ROCKET: + { + a_Writer.BeginCompound("Fireworks"); + a_Writer.AddByte("Flight", a_FireworkItem.m_FlightTimeInTicks / 20); + a_Writer.BeginList("Explosions", TAG_Compound); + a_Writer.BeginCompound(""); + a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker); + a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail); + a_Writer.AddByte("Type", a_FireworkItem.m_Type); + a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size()); + a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size()); + a_Writer.EndCompound(); + a_Writer.EndList(); + a_Writer.EndCompound(); + break; + } + case E_ITEM_FIREWORK_STAR: + { + a_Writer.BeginCompound("Explosion"); + a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker); + a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail); + a_Writer.AddByte("Type", a_FireworkItem.m_Type); + if (!a_FireworkItem.m_Colours.empty()) + { + a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size()); + } + if (!a_FireworkItem.m_FadeColours.empty()) + { + a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size()); + } + a_Writer.EndCompound(); + break; + } + default: ASSERT(!"Unhandled firework item!"); break; + } +} + + + + + +void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNBT & a_NBT, int a_TagIdx, const ENUM_ITEM_ID a_Type) +{ + if (a_TagIdx < 0) + { + return; + } + + switch (a_Type) + { + case E_ITEM_FIREWORK_STAR: + { + for (int explosiontag = a_NBT.GetFirstChild(a_TagIdx); explosiontag >= 0; explosiontag = a_NBT.GetNextSibling(explosiontag)) + { + eTagType TagType = a_NBT.GetType(explosiontag); + if (TagType == TAG_Byte) // Custon name tag + { + AString ExplosionName = a_NBT.GetName(explosiontag); + + if (ExplosionName == "Flicker") + { + a_FireworkItem.m_HasFlicker = (a_NBT.GetByte(explosiontag) == 1); + } + else if (ExplosionName == "Trail") + { + a_FireworkItem.m_HasTrail = (a_NBT.GetByte(explosiontag) == 1); + } + else if (ExplosionName == "Type") + { + a_FireworkItem.m_Type = a_NBT.GetByte(explosiontag); + } + } + else if (TagType == TAG_IntArray) + { + AString ExplosionName = a_NBT.GetName(explosiontag); + + if (ExplosionName == "Colors") + { + if (a_NBT.GetDataLength(explosiontag) == 0) + { + continue; + } + + const int * ColourData = (const int *)(a_NBT.GetData(explosiontag)); + for (int i = 0; i < ARRAYCOUNT(ColourData); i++) + { + a_FireworkItem.m_Colours.push_back(ntohl(ColourData[i])); + } + } + else if (ExplosionName == "FadeColors") + { + if (a_NBT.GetDataLength(explosiontag) == 0) + { + continue; + } + + const int * FadeColourData = (const int *)(a_NBT.GetData(explosiontag)); + for (int i = 0; i < ARRAYCOUNT(FadeColourData); i++) + { + a_FireworkItem.m_FadeColours.push_back(ntohl(FadeColourData[i])); + } + } + } + } + break; + } + case E_ITEM_FIREWORK_ROCKET: + { + for (int fireworkstag = a_NBT.GetFirstChild(a_TagIdx); fireworkstag >= 0; fireworkstag = a_NBT.GetNextSibling(fireworkstag)) + { + eTagType TagType = a_NBT.GetType(fireworkstag); + if (TagType == TAG_Byte) // Custon name tag + { + if (a_NBT.GetName(fireworkstag) == "Flight") + { + a_FireworkItem.m_FlightTimeInTicks = a_NBT.GetByte(fireworkstag) * 20; + } + } + else if ((TagType == TAG_List) && (a_NBT.GetName(fireworkstag) == "Explosions")) + { + int ExplosionsChild = a_NBT.GetFirstChild(fireworkstag); + if ((a_NBT.GetType(ExplosionsChild) == TAG_Compound) && (a_NBT.GetName(ExplosionsChild).empty())) + { + ParseFromNBT(a_FireworkItem, a_NBT, ExplosionsChild, E_ITEM_FIREWORK_STAR); + } + } + } + break; + } + default: ASSERT(!"Unhandled firework item!"); break; + } +} + + + + + +AString cFireworkItem::ColoursToString(const cFireworkItem & a_FireworkItem) +{ + AString Result; + + for (std::vector::const_iterator itr = a_FireworkItem.m_Colours.begin(); itr != a_FireworkItem.m_Colours.end(); ++itr) + { + AppendPrintf(Result, "%i;", *itr); + } + + return Result; +} + + + + + +void cFireworkItem::ColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem) +{ + AStringVector Split = StringSplit(a_String, ";"); + + for (size_t itr = 0; itr < Split.size(); ++itr) + { + if (Split[itr].empty()) + { + continue; + } + + a_FireworkItem.m_Colours.push_back(atoi(Split[itr].c_str())); + } +} + + + + + +AString cFireworkItem::FadeColoursToString(const cFireworkItem & a_FireworkItem) +{ + AString Result; + + for (std::vector::const_iterator itr = a_FireworkItem.m_FadeColours.begin(); itr != a_FireworkItem.m_FadeColours.end(); ++itr) + { + AppendPrintf(Result, "%i;", *itr); + } + + return Result; +} + + + + + +void cFireworkItem::FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem) +{ + AStringVector Split = StringSplit(a_String, ";"); + + for (size_t itr = 0; itr < Split.size(); ++itr) + { + if (Split[itr].empty()) + { + continue; + } + + a_FireworkItem.m_FadeColours.push_back(atoi(Split[itr].c_str())); + } +} + + + + + +int GetVanillaColourCodeFromDye(short a_DyeMeta) +{ + /* + Colours are supposed to be calculated via: R << 16 + G << 8 + B + However, the RGB values fireworks use aren't the same as the ones for dyes (the ones listed in the MC Wiki) + Therefore, here is a list of numbers gotten via the Protocol Proxy + */ + + switch (a_DyeMeta) + { + case E_META_DYE_BLACK: return 1973019; + case E_META_DYE_RED: return 11743532; + case E_META_DYE_GREEN: return 3887386; + case E_META_DYE_BROWN: return 5320730; + case E_META_DYE_BLUE: return 2437522; + case E_META_DYE_PURPLE: return 8073150; + case E_META_DYE_CYAN: return 2651799; + case E_META_DYE_LIGHTGRAY: return 11250603; + case E_META_DYE_GRAY: return 4408131; + case E_META_DYE_PINK: return 14188952; + case E_META_DYE_LIGHTGREEN: return 4312372; + case E_META_DYE_YELLOW: return 14602026; + case E_META_DYE_LIGHTBLUE: return 6719955; + case E_META_DYE_MAGENTA: return 12801229; + case E_META_DYE_ORANGE: return 15435844; + case E_META_DYE_WHITE: return 15790320; + default: ASSERT(!"Unhandled dye meta whilst trying to get colour code for fireworks!"); break; + } +} diff --git a/src/WorldStorage/FireworksSerializer.h b/src/WorldStorage/FireworksSerializer.h new file mode 100644 index 000000000..475d80bda --- /dev/null +++ b/src/WorldStorage/FireworksSerializer.h @@ -0,0 +1,88 @@ + +// FireworksSerializer.h + +// Declares the cFireworkItem class representing a firework or firework star + + + + + +#pragma once + +#include "Defines.h" + +class cFastNBTWriter; +class cParsedNBT; + + + + + +class cFireworkItem +{ +public: + cFireworkItem(void) : + m_HasFlicker(false), + m_HasTrail(false), + m_Type(0), + m_FlightTimeInTicks(0) + { + } + + inline void CopyFrom(const cFireworkItem & a_Item) + { + m_FlightTimeInTicks = a_Item.m_FlightTimeInTicks; + m_HasFlicker = a_Item.m_HasFlicker; + m_HasTrail = a_Item.m_HasTrail; + m_Type = a_Item.m_Type; + m_Colours = a_Item.m_Colours; + m_FadeColours = a_Item.m_FadeColours; + } + + inline void EmptyData(void) + { + m_FlightTimeInTicks = 0; + m_HasFlicker = false; + m_Type = 0; + m_HasTrail = false; + m_Colours.clear(); + m_FadeColours.clear(); + } + + inline bool IsEqualTo(const cFireworkItem & a_Item) const + { + return + ( + (m_FlightTimeInTicks == a_Item.m_FlightTimeInTicks) && + (m_HasFlicker == a_Item.m_HasFlicker) && + (m_HasTrail == a_Item.m_HasTrail) && + (m_Type == a_Item.m_Type) && + (m_Colours == a_Item.m_Colours) && + (m_FadeColours == a_Item.m_FadeColours) + ); + } + + /** Writes firework NBT data to a Writer object */ + static void WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFastNBTWriter & a_Writer, const ENUM_ITEM_ID a_Type); + /** Reads NBT data from a NBT object and populates a FireworkItem with it */ + static void ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNBT & a_NBT, int a_TagIdx, const ENUM_ITEM_ID a_Type); + + /** Converts the firework's vector of colours into a string of values separated by a semicolon */ + static AString ColoursToString(const cFireworkItem & a_FireworkItem); + /** Parses a string containing encoded firework colours and populates a FireworkItem with it */ + static void ColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem); + /** Converts the firework's vector of fade colours into a string of values separated by a semicolon */ + static AString FadeColoursToString(const cFireworkItem & a_FireworkItem); + /** Parses a string containing encoded firework fade colours and populates a FireworkItem with it */ + static void FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem); + + /** Returns a colour code for fireworks used by the network code */ + static const inline int GetVanillaColourCodeFromDye(short a_DyeMeta); + + bool m_HasFlicker; + bool m_HasTrail; + NIBBLETYPE m_Type; + short m_FlightTimeInTicks; + std::vector m_Colours; + std::vector m_FadeColours; +}; \ No newline at end of file diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index c1c659b36..6d82cba86 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -90,11 +90,19 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin } // Write the enchantments: - if (!a_Item.m_Enchantments.IsEmpty()) + if (!a_Item.m_Enchantments.IsEmpty() || ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR))) { - const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; m_Writer.BeginCompound("tag"); - EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, m_Writer, TagName); + if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) + { + cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, m_Writer, (ENUM_ITEM_ID)a_Item.m_ItemType); + } + + if (!a_Item.m_Enchantments.IsEmpty()) + { + const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; + EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, m_Writer, TagName); + } m_Writer.EndCompound(); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 05332d23d..0658d5029 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -658,6 +658,12 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_ { EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, a_NBT, EnchTag); } + + int FireworksTag = a_NBT.FindChildByName(TagTag, ((a_Item.m_ItemType == E_ITEM_FIREWORK_STAR) ? "Fireworks" : "Explosion")); + if (EnchTag > 0) + { + cFireworkItem::ParseFromNBT(a_Item.m_FireworkItem, a_NBT, FireworksTag, (ENUM_ITEM_ID)a_Item.m_ItemType); + } return true; } -- cgit v1.2.3 From a97f28939fb706cbe26bc0de400c7bf2f14f19f4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 26 Feb 2014 23:30:10 +0000 Subject: Fixed sheep ASSERTing sometimes --- src/Mobs/Sheep.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 4761103e5..c64360153 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -68,17 +68,28 @@ void cSheep::OnRightClicked(cPlayer & a_Player) void cSheep::Tick(float a_Dt, cChunk & a_Chunk) { - // The sheep should not move when he's eating so only handle the physics. + super::Tick(a_Dt, a_Chunk); + int PosX = POSX_TOINT; + int PosY = POSY_TOINT - 1; + int PosZ = POSZ_TOINT; + + if ((PosY <= 0) || (PosY > cChunkDef::Height)) + { + return; + } + if (m_TimeToStopEating > 0) { - HandlePhysics(a_Dt, a_Chunk); + m_bMovingToDestination = false; // The sheep should not move when he's eating m_TimeToStopEating--; + if (m_TimeToStopEating == 0) { - if (m_World->GetBlock((int) GetPosX(), (int) GetPosY() - 1, (int) GetPosZ()) == E_BLOCK_GRASS) + if (m_World->GetBlock(PosX, PosY, PosZ) == E_BLOCK_GRASS) // Make sure grass hasn't been destroyed in the meantime { - // The sheep ate the grass so we change it to dirt. - m_World->SetBlock((int) GetPosX(), (int) GetPosY() - 1, (int) GetPosZ(), E_BLOCK_DIRT, 0); + // The sheep ate the grass so we change it to dirt + m_World->SetBlock(PosX, PosY, PosZ, E_BLOCK_DIRT, 0); + GetWorld()->BroadcastSoundParticleEffect(2001, PosX, PosY, PosX, E_BLOCK_GRASS); m_IsSheared = false; m_World->BroadcastEntityMetadata(*this); } @@ -86,12 +97,11 @@ void cSheep::Tick(float a_Dt, cChunk & a_Chunk) } else { - super::Tick(a_Dt, a_Chunk); if (m_World->GetTickRandomNumber(600) == 1) { - if (m_World->GetBlock((int) GetPosX(), (int) GetPosY() - 1, (int) GetPosZ()) == E_BLOCK_GRASS) + if (m_World->GetBlock(PosX, PosY, PosZ) == E_BLOCK_GRASS) { - m_World->BroadcastEntityStatus(*this, 10); + m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_SHEEP_EATING); m_TimeToStopEating = 40; } } -- cgit v1.2.3 From 528467bc5c514d8ef193c4e9dd06fb5aeb9f0dd9 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 27 Feb 2014 21:48:49 +0000 Subject: Fixed compile --- src/WorldStorage/FireworksSerializer.cpp | 3 +-- src/WorldStorage/FireworksSerializer.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index eeb4e39ee..7f5077912 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -2,7 +2,6 @@ #include "Globals.h" #include "FireworksSerializer.h" #include "WorldStorage/FastNBT.h" -#include @@ -219,7 +218,7 @@ void cFireworkItem::FadeColoursFromString(const AString & a_String, cFireworkIte -int GetVanillaColourCodeFromDye(short a_DyeMeta) +int cFireworkItem::GetVanillaColourCodeFromDye(short a_DyeMeta) { /* Colours are supposed to be calculated via: R << 16 + G << 8 + B diff --git a/src/WorldStorage/FireworksSerializer.h b/src/WorldStorage/FireworksSerializer.h index 475d80bda..37fb6c883 100644 --- a/src/WorldStorage/FireworksSerializer.h +++ b/src/WorldStorage/FireworksSerializer.h @@ -77,7 +77,7 @@ public: static void FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem); /** Returns a colour code for fireworks used by the network code */ - static const inline int GetVanillaColourCodeFromDye(short a_DyeMeta); + static int GetVanillaColourCodeFromDye(short a_DyeMeta); bool m_HasFlicker; bool m_HasTrail; -- cgit v1.2.3 From 9ac9249acaf21d01af41b4cdfc862961b1f9e286 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 27 Feb 2014 21:49:10 +0000 Subject: Removed unneeded includes in Player.cpp --- src/Entities/Player.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 0152bfc5b..f4039e548 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -10,18 +10,11 @@ #include "../BlockEntities/BlockEntity.h" #include "../GroupManager.h" #include "../Group.h" -#include "../ChatColor.h" -#include "../Item.h" -#include "../Tracer.h" #include "../Root.h" #include "../OSSupport/Timer.h" -#include "../MersenneTwister.h" #include "../Chunk.h" #include "../Items/ItemHandler.h" -#include "../Vector3d.h" -#include "../Vector3f.h" - #include "inifile/iniFile.h" #include "json/json.h" -- cgit v1.2.3 From f5e374be41ef3bde93e0faaa76208e3e0e15e9ea Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 8 Mar 2014 10:25:46 +0100 Subject: Add TNT Save/Load and add Netbeans projects to .gitignore --- src/Entities/TNTEntity.cpp | 27 +++++++++++++++++---------- src/Entities/TNTEntity.h | 23 ++++++++++++++++------- src/WorldStorage/NBTChunkSerializer.cpp | 15 ++++++++++++++- src/WorldStorage/NBTChunkSerializer.h | 2 ++ src/WorldStorage/WSSAnvil.cpp | 28 ++++++++++++++++++++++++++++ src/WorldStorage/WSSAnvil.h | 1 + 6 files changed, 78 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/Entities/TNTEntity.cpp b/src/Entities/TNTEntity.cpp index 339107b2e..4f361403c 100644 --- a/src/Entities/TNTEntity.cpp +++ b/src/Entities/TNTEntity.cpp @@ -10,8 +10,7 @@ cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec) : super(etTNT, a_X, a_Y, a_Z, 0.98, 0.98), - m_Counter(0), - m_MaxFuseTime(a_FuseTimeInSec) + m_FuseTicks(a_FuseTimeInSec) { } @@ -21,8 +20,7 @@ cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSe cTNTEntity::cTNTEntity(const Vector3d & a_Pos, double a_FuseTimeInSec) : super(etTNT, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98), - m_Counter(0), - m_MaxFuseTime(a_FuseTimeInSec) + m_FuseTicks(a_FuseTimeInSec) { } @@ -42,18 +40,27 @@ void cTNTEntity::SpawnOn(cClientHandle & a_ClientHandle) +void cTNTEntity::Explode(void) +{ + m_FuseTicks = 0; + Destroy(true); + LOGD("BOOM at {%f,%f,%f}", GetPosX(), GetPosY(), GetPosZ()); + m_World->DoExplosionAt(4.0, GetPosX() + 0.49, GetPosY() + 0.49, GetPosZ() + 0.49, true, esPrimedTNT, this); +} + + + + + void cTNTEntity::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); BroadcastMovementUpdate(); float delta_time = a_Dt / 1000; // Convert miliseconds to seconds - m_Counter += delta_time; - if (m_Counter > m_MaxFuseTime) // Check if we go KABOOOM + m_FuseTicks -= delta_time; + if (m_FuseTicks <= 0) { - Destroy(true); - LOGD("BOOM at {%f,%f,%f}", GetPosX(), GetPosY(), GetPosZ()); - m_World->DoExplosionAt(4.0, GetPosX() + 0.49, GetPosY() + 0.49, GetPosZ() + 0.49, true, esPrimedTNT, this); - return; + Explode(); } } diff --git a/src/Entities/TNTEntity.h b/src/Entities/TNTEntity.h index d1fcae766..8f83f52d9 100644 --- a/src/Entities/TNTEntity.h +++ b/src/Entities/TNTEntity.h @@ -16,19 +16,28 @@ public: // tolua_end CLASS_PROTODEF(cTNTEntity); - cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec); - cTNTEntity(const Vector3d & a_Pos, double a_FuseTimeInSec); + cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec = 4); + cTNTEntity(const Vector3d & a_Pos, double a_FuseTimeInSec = 4); // cEntity overrides: virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; - - double GetCounterTime(void) const { return m_Counter; } // tolua_export - double GetMaxFuseTime(void) const { return m_MaxFuseTime; } // tolua_export + + // tolua_begin + + /** Explode the tnt */ + void Explode(void); + + /** Returns the fuse ticks until the tnt will explode */ + double GetFuseTicks(void) const { return m_FuseTicks; } + + /** Set the fuse ticks until the tnt will explode */ + void SetFuseTicks(double a_FuseTicks) { m_FuseTicks = a_FuseTicks; } + + // tolua_end protected: - double m_Counter; ///< How much time has elapsed since the object was created, in seconds - double m_MaxFuseTime; ///< How long the fuse is, in seconds + double m_FuseTicks; ///< How much time in seconds is left, while the tnt will explode }; // tolua_export diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 6d0e29958..06b815333 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -28,6 +28,7 @@ #include "../Entities/Minecart.h" #include "../Entities/Pickup.h" #include "../Entities/ProjectileEntity.h" +#include "../Entities/TNTEntity.h" #include "../Mobs/Monster.h" #include "../Mobs/Bat.h" @@ -583,6 +584,18 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) +void cNBTChunkSerializer::AddTNTEntity(cTNTEntity * a_TNT) +{ + m_Writer.BeginCompound(""); + AddBasicEntity(a_TNT, "PrimedTnt"); + m_Writer.AddByte("Fuse", ((unsigned char)a_TNT->GetFuseTicks()) * 10); + m_Writer.EndCompound(); +} + + + + + void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart) { m_Writer.BeginList("Items", TAG_Compound); @@ -662,7 +675,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) case cEntity::etMonster: AddMonsterEntity ((cMonster *) a_Entity); break; case cEntity::etPickup: AddPickupEntity ((cPickup *) a_Entity); break; case cEntity::etProjectile: AddProjectileEntity ((cProjectileEntity *)a_Entity); break; - case cEntity::etTNT: /* TODO */ break; + case cEntity::etTNT: AddTNTEntity ((cTNTEntity *) a_Entity); break; case cEntity::etExpOrb: /* TODO */ break; case cEntity::etItemFrame: /* TODO */ break; case cEntity::etPainting: /* TODO */ break; diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 8a9e18413..3b486d2bc 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -41,6 +41,7 @@ class cMonster; class cPickup; class cItemGrid; class cProjectileEntity; +class cTNTEntity; @@ -107,6 +108,7 @@ protected: void AddMonsterEntity (cMonster * a_Monster); void AddPickupEntity (cPickup * a_Pickup); void AddProjectileEntity (cProjectileEntity * a_Projectile); + void AddTNTEntity (cTNTEntity * a_TNT); void AddMinecartChestContents(cMinecartWithChest * a_Minecart); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 680f2458f..fa0c4dbd9 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -36,6 +36,7 @@ #include "../Entities/Minecart.h" #include "../Entities/Pickup.h" #include "../Entities/ProjectileEntity.h" +#include "../Entities/TNTEntity.h" @@ -1231,6 +1232,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadPigZombieFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } + else if (strncmp(a_IDTag, "PrimedTnt", a_IDTagLength) == 0) + { + LoadTNTFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } // TODO: other entities } @@ -2167,6 +2172,29 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT +void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr TNT(new cTNTEntity(0.0, 0.0, 0.0, 0)); + if (!LoadEntityBaseFromNBT(*TNT.get(), a_NBT, a_TagIdx)) + { + return; + } + + // Load Fuse Ticks: + int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse"); + if (FuseTicks > 0) + { + int MojangFuseTicks = (int) a_NBT.GetByte(FuseTicks); + TNT->SetFuseTicks((double) MojangFuseTicks / 10); + } + + a_Entities.push_back(TNT.release()); +} + + + + + bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx) { double Pos[3]; diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index b26345b13..fe93d16c3 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -192,6 +192,7 @@ protected: void LoadWolfFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPigZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); /// Loads entity common data from the NBT compound; returns true if successful bool LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx); -- cgit v1.2.3 From b37966fd214fb048a415a33291a85ee8c263691c Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 8 Mar 2014 12:24:33 +0100 Subject: Change TNT Fuse to ticks --- src/BlockEntities/DispenserEntity.cpp | 2 +- src/Entities/TNTEntity.cpp | 12 ++++++------ src/Entities/TNTEntity.h | 10 +++++----- src/Items/ItemLighter.h | 4 ++-- src/Simulator/IncrementalRedstoneSimulator.cpp | 2 +- src/World.cpp | 4 ++-- src/World.h | 2 +- src/WorldStorage/NBTChunkSerializer.cpp | 2 +- src/WorldStorage/WSSAnvil.cpp | 3 +-- 9 files changed, 20 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 374f3d6e3..cbfbb1b6a 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -116,7 +116,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) { double TNTX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); double TNTZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - m_World->SpawnPrimedTNT(TNTX, DispY + 0.5, TNTZ, 4, 0); // 4 seconds fuse, no initial velocity + m_World->SpawnPrimedTNT(TNTX, DispY + 0.5, TNTZ, 80, 0); // 80 ticks fuse, no initial velocity m_Contents.ChangeSlotCount(a_SlotNum, -1); } break; diff --git a/src/Entities/TNTEntity.cpp b/src/Entities/TNTEntity.cpp index 4f361403c..02f31f5bb 100644 --- a/src/Entities/TNTEntity.cpp +++ b/src/Entities/TNTEntity.cpp @@ -8,9 +8,9 @@ -cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec) : +cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, int a_FuseTicks) : super(etTNT, a_X, a_Y, a_Z, 0.98, 0.98), - m_FuseTicks(a_FuseTimeInSec) + m_FuseTicks(a_FuseTicks) { } @@ -18,9 +18,9 @@ cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSe -cTNTEntity::cTNTEntity(const Vector3d & a_Pos, double a_FuseTimeInSec) : +cTNTEntity::cTNTEntity(const Vector3d & a_Pos, int a_FuseTicks) : super(etTNT, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98), - m_FuseTicks(a_FuseTimeInSec) + m_FuseTicks(a_FuseTicks) { } @@ -56,8 +56,8 @@ void cTNTEntity::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); BroadcastMovementUpdate(); - float delta_time = a_Dt / 1000; // Convert miliseconds to seconds - m_FuseTicks -= delta_time; + + m_FuseTicks -= 1; if (m_FuseTicks <= 0) { Explode(); diff --git a/src/Entities/TNTEntity.h b/src/Entities/TNTEntity.h index 8f83f52d9..116f5a8cb 100644 --- a/src/Entities/TNTEntity.h +++ b/src/Entities/TNTEntity.h @@ -16,8 +16,8 @@ public: // tolua_end CLASS_PROTODEF(cTNTEntity); - cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec = 4); - cTNTEntity(const Vector3d & a_Pos, double a_FuseTimeInSec = 4); + cTNTEntity(double a_X, double a_Y, double a_Z, int a_FuseTicks = 80); + cTNTEntity(const Vector3d & a_Pos, int a_FuseTicks = 80); // cEntity overrides: virtual void SpawnOn(cClientHandle & a_ClientHandle) override; @@ -29,15 +29,15 @@ public: void Explode(void); /** Returns the fuse ticks until the tnt will explode */ - double GetFuseTicks(void) const { return m_FuseTicks; } + int GetFuseTicks(void) const { return m_FuseTicks; } /** Set the fuse ticks until the tnt will explode */ - void SetFuseTicks(double a_FuseTicks) { m_FuseTicks = a_FuseTicks; } + void SetFuseTicks(int a_FuseTicks) { m_FuseTicks = a_FuseTicks; } // tolua_end protected: - double m_FuseTicks; ///< How much time in seconds is left, while the tnt will explode + int m_FuseTicks; ///< How much ticks is left, while the tnt will explode }; // tolua_export diff --git a/src/Items/ItemLighter.h b/src/Items/ItemLighter.h index cc7daeb08..18873e911 100644 --- a/src/Items/ItemLighter.h +++ b/src/Items/ItemLighter.h @@ -33,8 +33,8 @@ public: case E_BLOCK_TNT: { // Activate the TNT: - a_World->BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); - a_World->SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 4); // 4 seconds to boom + a_World->BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0f, 1.0f); + a_World->SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); // 80 ticks to boom a_World->SetBlock(a_BlockX,a_BlockY,a_BlockZ, E_BLOCK_AIR, 0); break; } diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index f377b0aa7..ca2ef4b1a 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -838,7 +838,7 @@ void cIncrementalRedstoneSimulator::HandleTNT(int a_BlockX, int a_BlockY, int a_ if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { m_World.BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); - m_World.SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 4); // 4 seconds to boom + m_World.SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); // 80 ticks to boom m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); } } diff --git a/src/World.cpp b/src/World.cpp index ecb278e85..ebc37f7b2 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1725,10 +1725,10 @@ int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType -void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec, double a_InitialVelocityCoeff) +void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks, double a_InitialVelocityCoeff) { UNUSED(a_InitialVelocityCoeff); - cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTimeInSec); + cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTicks); TNT->Initialize(this); // TODO: Add a bit of speed in horiz and vert axes, based on the a_InitialVelocityCoeff } diff --git a/src/World.h b/src/World.h index e6c665785..517b6b4fa 100644 --- a/src/World.h +++ b/src/World.h @@ -445,7 +445,7 @@ public: int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward); /** Spawns a new primed TNT entity at the specified block coords and specified fuse duration. Initial velocity is given based on the relative coefficient provided */ - void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec, double a_InitialVelocityCoeff = 1); + void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTimeInSec = 80, double a_InitialVelocityCoeff = 1); // tolua_end diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 06b815333..17cf838c3 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -588,7 +588,7 @@ void cNBTChunkSerializer::AddTNTEntity(cTNTEntity * a_TNT) { m_Writer.BeginCompound(""); AddBasicEntity(a_TNT, "PrimedTnt"); - m_Writer.AddByte("Fuse", ((unsigned char)a_TNT->GetFuseTicks()) * 10); + m_Writer.AddByte("Fuse", (unsigned char)a_TNT->GetFuseTicks()); m_Writer.EndCompound(); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index fa0c4dbd9..b52b74932 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -2184,8 +2184,7 @@ void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse"); if (FuseTicks > 0) { - int MojangFuseTicks = (int) a_NBT.GetByte(FuseTicks); - TNT->SetFuseTicks((double) MojangFuseTicks / 10); + TNT->SetFuseTicks((int) a_NBT.GetByte(FuseTicks)); } a_Entities.push_back(TNT.release()); -- cgit v1.2.3 From e2cbebe522c8d52dc68e513d7896c1f0d21d5b71 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 27 Feb 2014 23:33:46 +0000 Subject: Fix Linux compile --- src/CraftingRecipes.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 41de0da8c..5d9992fd3 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -806,6 +806,8 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti } case E_ITEM_DYE: { + int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); + // Found a dye in ingredients... for (cRecipeSlots::const_iterator itrnumerodos = Recipe->m_Ingredients.begin(); itrnumerodos != Recipe->m_Ingredients.end(); ++itrnumerodos) { @@ -821,7 +823,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti // Yep, push back fade colour and exit the loop // There is a potential for flexibility here - we can move the goto out of the loop, so we can add multiple dyes (∴ multiple fade colours) // That will require lots of dye-adding to crafting.txt though - TODO, perchance? - int GridID = (itrnumerotres->x + a_OffsetX) + a_GridStride * (itrnumerotres->y + a_OffsetY); + GridID = (itrnumerotres->x + a_OffsetX) + a_GridStride * (itrnumerotres->y + a_OffsetY); Recipe->m_Result.m_FireworkItem.m_FadeColours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); goto next; } @@ -830,7 +832,6 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti } // Just normal crafting of star, push back normal colours - int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); Recipe->m_Result.m_FireworkItem.m_Colours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); next: -- cgit v1.2.3 From c05a1db88d2a81b5aa93881c9791bcaadaad6304 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Mar 2014 21:24:36 +0000 Subject: CheckBlockInteractionsRate() fixed & enabled --- src/ClientHandle.cpp | 48 +++++++++++++++++++----------------------------- src/ClientHandle.h | 4 +++- src/Entities/Player.cpp | 25 ------------------------- src/Entities/Player.h | 11 +---------- 4 files changed, 23 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index b08ceb5f6..ef33a313d 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -52,6 +52,9 @@ /** Maximum number of explosions to send this tick, server will start dropping if exceeded */ #define MAX_EXPLOSIONS_PER_TICK 20 +/** Maximum number of block change interactions a player can perform per tick - exceeding this causes a kick */ +#define MAX_BLOCK_CHANGE_INTERACTIONS 20 + /** How many ticks before the socket is closed after the client is destroyed (#31) */ static const int TICKS_BEFORE_CLOSE = 20; @@ -687,6 +690,14 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status ); + m_NumBlockChangeInteractionsThisTick++; + + if (!CheckBlockInteractionsRate()) + { + Kick("Too many blocks were destroyed per unit time - hacked client?"); + return; + } + cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); if (PlgMgr->CallHookPlayerLeftClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status)) { @@ -694,12 +705,6 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); return; } - - if (!CheckBlockInteractionsRate()) - { - // Too many interactions per second, simply ignore. Probably a hacked client, so don't even send bak the block - return; - } switch (a_Status) { @@ -924,7 +929,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e if (PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ)) { // A plugin doesn't agree with the action, replace the block on the client and quit: - if (a_BlockFace > -1) + if (a_BlockFace > BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); @@ -934,7 +939,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e if (!CheckBlockInteractionsRate()) { - LOGD("Too many block interactions, aborting placement"); + Kick("Too many blocks were destroyed per unit time - hacked client?"); return; } @@ -1613,28 +1618,12 @@ bool cClientHandle::CheckBlockInteractionsRate(void) { ASSERT(m_Player != NULL); ASSERT(m_Player->GetWorld() != NULL); - /* - // TODO: _X 2012_11_01: This needs a total re-thinking and rewriting - int LastActionCnt = m_Player->GetLastBlockActionCnt(); - if ((m_Player->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime()) < 0.1) - { - // Limit the number of block interactions per tick - m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time. - m_Player->SetLastBlockActionCnt(LastActionCnt + 1); - if (m_Player->GetLastBlockActionCnt() > MAXBLOCKCHANGEINTERACTIONS) - { - // Kick if more than MAXBLOCKCHANGEINTERACTIONS per tick - LOGWARN("Player %s tried to interact with a block too quickly! (could indicate bot) Was Kicked.", m_Username.c_str()); - Kick("You're a baaaaaad boy!"); - return false; - } - } - else + + if (m_NumBlockChangeInteractionsThisTick > MAX_BLOCK_CHANGE_INTERACTIONS) { - m_Player->SetLastBlockActionCnt(0); // Reset count - m_Player->SetLastBlockActionTime(); // Player tried to interact with a block. Reset last block interation time. + return false; } - */ + return true; } @@ -1707,8 +1696,9 @@ void cClientHandle::Tick(float a_Dt) } } - // Reset explosion counter: + // Reset explosion & block change counters: m_NumExplosionsThisTick = 0; + m_NumBlockChangeInteractionsThisTick = 0; } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 194533402..2382e81cf 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -46,7 +46,6 @@ class cClientHandle : // tolua_export public cSocketThreads::cCallback { // tolua_export public: - static const int MAXBLOCKCHANGEINTERACTIONS = 20; // 5 didn't help, 10 still doesn't work in Creative, 20 seems to have done the trick #if defined(ANDROID_NDK) static const int DEFAULT_VIEW_DISTANCE = 4; // The default ViewDistance (used when no value is set in Settings.ini) @@ -319,6 +318,9 @@ private: /** Number of explosions sent this tick */ int m_NumExplosionsThisTick; + + /** Number of place or break interactions this tick */ + int m_NumBlockChangeInteractionsThisTick; static int s_ClientCount; int m_UniqueID; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index f4039e548..2a62931ab 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -38,10 +38,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) , m_Inventory(*this) , m_CurrentWindow(NULL) , m_InventoryWindow(NULL) - , m_TimeLastPickupCheck(0.f) , m_Color('-') - , m_LastBlockActionTime(0) - , m_LastBlockActionCnt(0) , m_GameMode(eGameMode_NotSet) , m_IP("") , m_ClientHandle(a_Client) @@ -79,7 +76,6 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) m_LastPlayerListTime = t1.GetNowTime(); m_TimeLastTeleportPacket = 0; - m_TimeLastPickupCheck = 0; m_PlayerName = a_PlayerName; m_bDirtyPosition = true; // So chunks are streamed to player at spawn @@ -1055,27 +1051,6 @@ void cPlayer::CloseWindowIfID(char a_WindowID, bool a_CanRefuse) -void cPlayer::SetLastBlockActionTime() -{ - if (m_World != NULL) - { - m_LastBlockActionTime = m_World->GetWorldAge() / 20.0f; - } -} - - - - - -void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt ) -{ - m_LastBlockActionCnt = a_LastBlockActionCnt; -} - - - - - void cPlayer::SetGameMode(eGameMode a_GameMode) { if ((a_GameMode < gmMin) || (a_GameMode >= gmMax)) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index a795bb9eb..f9404dfaf 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -50,7 +50,7 @@ public: /// Returns the curently equipped weapon; empty item if none virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); } - /// Returns the currently equipped helmet; empty item if nonte + /// Returns the currently equipped helmet; empty item if none virtual cItem GetEquippedHelmet(void) const override { return m_Inventory.GetEquippedHelmet(); } /// Returns the currently equipped chestplate; empty item if none @@ -165,11 +165,6 @@ public: // tolua_end void SetIP(const AString & a_IP); - - float GetLastBlockActionTime() { return m_LastBlockActionTime; } - int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } - void SetLastBlockActionCnt( int ); - void SetLastBlockActionTime(); // Sets the current gamemode, doesn't check validity, doesn't send update packets to client void LoginSetGameMode(eGameMode a_GameMode); @@ -416,12 +411,8 @@ protected: cWindow * m_CurrentWindow; cWindow * m_InventoryWindow; - float m_TimeLastPickupCheck; - char m_Color; - float m_LastBlockActionTime; - int m_LastBlockActionCnt; eGameMode m_GameMode; AString m_IP; -- cgit v1.2.3 From 217aaca699cf1fa85740da4d1f0b71d4b8d806d7 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Mar 2014 21:25:01 +0000 Subject: Moved firework handler to separate function * Also simplified and improved readability of code --- src/CraftingRecipes.cpp | 93 ++++++++++++++++++++++++------------------------- src/CraftingRecipes.h | 3 ++ 2 files changed, 48 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 5d9992fd3..868182394 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -763,13 +763,24 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti } Recipe->m_Ingredients.insert(Recipe->m_Ingredients.end(), MatchedSlots.begin(), MatchedSlots.end()); - - // Henceforth is code to handle fireworks // We use Recipe instead of a_Recipe because we want the wildcard ingredients' slot numbers as well, which was just added previously + HandleFireworks(a_CraftingGrid, Recipe.get(), a_GridStride, a_OffsetX, a_OffsetY); + + return Recipe.release(); +} + + + + + +void cCraftingRecipes::HandleFireworks(const cItem * a_CraftingGrid, cCraftingRecipes::cRecipe * a_Recipe, int a_GridStride, int a_OffsetX, int a_OffsetY) +{ + // TODO: add support for more than one dye in the recipe + // A manual and temporary solution (listing everything) is in crafting.txt for fade colours, but a programmatic solutions needs to be done for everything else - if (Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_ROCKET) + if (a_Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_ROCKET) { - for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + for (cRecipeSlots::const_iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr) { switch (itr->m_Item.m_ItemType) { @@ -777,80 +788,66 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti { // Result was a rocket, found a star - copy star data to rocket data int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); - Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); + a_Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); break; } case E_ITEM_GUNPOWDER: { // Gunpowder - increase flight time - Recipe->m_Result.m_FireworkItem.m_FlightTimeInTicks += 20; + a_Recipe->m_Result.m_FireworkItem.m_FlightTimeInTicks += 20; break; } case E_ITEM_PAPER: break; - default: LOG("Unexpected item in firework rocket recipe, was the crafting file fireworks section changed?"); break; + default: LOG("Unexpected item in firework rocket a_Recipe, was the crafting file fireworks section changed?"); break; } } } - else if (Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_STAR) + else if (a_Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_STAR) { - for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + std::vector DyeColours; + bool FoundStar = false; + + for (cRecipeSlots::const_iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr) { switch (itr->m_Item.m_ItemType) { case E_ITEM_FIREWORK_STAR: { // Result was star, found another star - probably adding fade colours, but copy data over anyhow + FoundStar = true; int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); - Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); + a_Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); break; } case E_ITEM_DYE: { int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); - - // Found a dye in ingredients... - for (cRecipeSlots::const_iterator itrnumerodos = Recipe->m_Ingredients.begin(); itrnumerodos != Recipe->m_Ingredients.end(); ++itrnumerodos) - { - // Loop through ingredients. Can we find a star? - if (itrnumerodos->m_Item.m_ItemType == E_ITEM_FIREWORK_STAR) - { - // Yes, this is definately adding fade colours, unless crafting.txt was changed :/ - for (cRecipeSlots::const_iterator itrnumerotres = Recipe->m_Ingredients.begin(); itrnumerotres != Recipe->m_Ingredients.end(); ++itrnumerotres) - { - // Loop again, can we find dye? - if (itrnumerotres->m_Item.m_ItemType == E_ITEM_DYE) - { - // Yep, push back fade colour and exit the loop - // There is a potential for flexibility here - we can move the goto out of the loop, so we can add multiple dyes (∴ multiple fade colours) - // That will require lots of dye-adding to crafting.txt though - TODO, perchance? - GridID = (itrnumerotres->x + a_OffsetX) + a_GridStride * (itrnumerotres->y + a_OffsetY); - Recipe->m_Result.m_FireworkItem.m_FadeColours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); - goto next; - } - } - } - } - - // Just normal crafting of star, push back normal colours - Recipe->m_Result.m_FireworkItem.m_Colours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); - - next: + DyeColours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); break; } case E_ITEM_GUNPOWDER: break; - case E_ITEM_DIAMOND: Recipe->m_Result.m_FireworkItem.m_HasTrail = true; break; - case E_ITEM_GLOWSTONE_DUST: Recipe->m_Result.m_FireworkItem.m_HasFlicker = true; break; - - case E_ITEM_FIRE_CHARGE: Recipe->m_Result.m_FireworkItem.m_Type = 1; break; - case E_ITEM_GOLD_NUGGET: Recipe->m_Result.m_FireworkItem.m_Type = 2; break; - case E_ITEM_FEATHER: Recipe->m_Result.m_FireworkItem.m_Type = 4; break; - case E_ITEM_HEAD: Recipe->m_Result.m_FireworkItem.m_Type = 3; break; - default: LOG("Unexpected item in firework star recipe, was the crafting file fireworks section changed?"); break; // ermahgerd BARD ardmins + case E_ITEM_DIAMOND: a_Recipe->m_Result.m_FireworkItem.m_HasTrail = true; break; + case E_ITEM_GLOWSTONE_DUST: a_Recipe->m_Result.m_FireworkItem.m_HasFlicker = true; break; + + case E_ITEM_FIRE_CHARGE: a_Recipe->m_Result.m_FireworkItem.m_Type = 1; break; + case E_ITEM_GOLD_NUGGET: a_Recipe->m_Result.m_FireworkItem.m_Type = 2; break; + case E_ITEM_FEATHER: a_Recipe->m_Result.m_FireworkItem.m_Type = 4; break; + case E_ITEM_HEAD: a_Recipe->m_Result.m_FireworkItem.m_Type = 3; break; + default: LOG("Unexpected item in firework star a_Recipe, was the crafting file fireworks section changed?"); break; // ermahgerd BARD ardmins } } - } - return Recipe.release(); + if (FoundStar && (!DyeColours.empty())) + { + // Found a star and a dye? Fade colours. + a_Recipe->m_Result.m_FireworkItem.m_FadeColours = DyeColours; + } + else if (!DyeColours.empty()) + { + // Only dye? Normal colours. + a_Recipe->m_Result.m_FireworkItem.m_Colours = DyeColours; + } + } } diff --git a/src/CraftingRecipes.h b/src/CraftingRecipes.h index 9d92cbfab..90e41eddc 100644 --- a/src/CraftingRecipes.h +++ b/src/CraftingRecipes.h @@ -165,6 +165,9 @@ protected: /// Checks if the grid matches the specified recipe, offset by the specified offsets. Returns a matched cRecipe * if so, or NULL if not matching. Caller must delete the return value! cRecipe * MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY); + + /** Searches for anything firework related, and does the data setting if appropriate */ + void HandleFireworks(const cItem * a_CraftingGrid, cCraftingRecipes::cRecipe * a_Recipe, int a_GridStride, int a_OffsetX, int a_OffsetY); } ; -- cgit v1.2.3 From 8f134adb6dab3ad171f34a2e08a314e591380def Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Mar 2014 21:25:27 +0000 Subject: Improved formatting of username tabcomplete --- src/World.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/World.cpp b/src/World.cpp index ffb463169..8b791fa48 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2929,18 +2929,18 @@ void cWorld::TabCompleteUserName(const AString & a_Text, AStringVector & a_Resul cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(), end = m_Players.end(); itr != end; ++itr) { - size_t LastSpace = a_Text.find_last_of(" "); //Find the position of the last space + size_t LastSpace = a_Text.find_last_of(" "); // Find the position of the last space - std::string LastWord = a_Text.substr(LastSpace + 1, a_Text.length()); //Find the last word - std::string PlayerName ((*itr)->GetName()); - std::size_t Found = PlayerName.find(LastWord); //Try to find last word in playername + AString LastWord = a_Text.substr(LastSpace + 1, a_Text.length()); // Find the last word + AString PlayerName ((*itr)->GetName()); + size_t Found = PlayerName.find(LastWord); // Try to find last word in playername - if (Found!=0) + if (Found == AString::npos) { - continue; //No match + continue; // No match } - a_Results.push_back((*itr)->GetName()); //Match! + a_Results.push_back(PlayerName); // Match! } } -- cgit v1.2.3 From 124fc8bc664f96158b4db28372da62896d1db211 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Mar 2014 21:26:43 +0000 Subject: Demonstrated issues with GetDataLength() --- src/WorldStorage/FireworksSerializer.cpp | 12 +++++++----- src/WorldStorage/FireworksSerializer.h | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 7f5077912..34204ae8a 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -89,26 +89,28 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB if (ExplosionName == "Colors") { - if (a_NBT.GetDataLength(explosiontag) == 0) + int DataLength = a_NBT.GetDataLength(explosiontag); + if (DataLength == 0) { continue; } const int * ColourData = (const int *)(a_NBT.GetData(explosiontag)); - for (int i = 0; i < ARRAYCOUNT(ColourData); i++) + for (int i = 0; i < DataLength; i++) { a_FireworkItem.m_Colours.push_back(ntohl(ColourData[i])); } } else if (ExplosionName == "FadeColors") { - if (a_NBT.GetDataLength(explosiontag) == 0) + int DataLength = a_NBT.GetDataLength(explosiontag); + if (DataLength == 0) { continue; } const int * FadeColourData = (const int *)(a_NBT.GetData(explosiontag)); - for (int i = 0; i < ARRAYCOUNT(FadeColourData); i++) + for (int i = 0; i < DataLength; i++) { a_FireworkItem.m_FadeColours.push_back(ntohl(FadeColourData[i])); } @@ -244,6 +246,6 @@ int cFireworkItem::GetVanillaColourCodeFromDye(short a_DyeMeta) case E_META_DYE_MAGENTA: return 12801229; case E_META_DYE_ORANGE: return 15435844; case E_META_DYE_WHITE: return 15790320; - default: ASSERT(!"Unhandled dye meta whilst trying to get colour code for fireworks!"); break; + default: ASSERT(!"Unhandled dye meta whilst trying to get colour code for fireworks!"); return 0; } } diff --git a/src/WorldStorage/FireworksSerializer.h b/src/WorldStorage/FireworksSerializer.h index 37fb6c883..5b87bafdb 100644 --- a/src/WorldStorage/FireworksSerializer.h +++ b/src/WorldStorage/FireworksSerializer.h @@ -64,15 +64,19 @@ public: /** Writes firework NBT data to a Writer object */ static void WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFastNBTWriter & a_Writer, const ENUM_ITEM_ID a_Type); + /** Reads NBT data from a NBT object and populates a FireworkItem with it */ static void ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNBT & a_NBT, int a_TagIdx, const ENUM_ITEM_ID a_Type); /** Converts the firework's vector of colours into a string of values separated by a semicolon */ static AString ColoursToString(const cFireworkItem & a_FireworkItem); + /** Parses a string containing encoded firework colours and populates a FireworkItem with it */ static void ColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem); + /** Converts the firework's vector of fade colours into a string of values separated by a semicolon */ static AString FadeColoursToString(const cFireworkItem & a_FireworkItem); + /** Parses a string containing encoded firework fade colours and populates a FireworkItem with it */ static void FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem); -- cgit v1.2.3 From a2fb28dd082b85d714970f119a82cdba3583037a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Mar 2014 16:28:51 +0000 Subject: Fixed data length issues --- src/ClientHandle.cpp | 2 +- src/WorldStorage/FireworksSerializer.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index ef33a313d..9f08b43a5 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -939,7 +939,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e if (!CheckBlockInteractionsRate()) { - Kick("Too many blocks were destroyed per unit time - hacked client?"); + Kick("Too many blocks were placed/interacted with per unit time - hacked client?"); return; } diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 34204ae8a..464bf225d 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -89,7 +89,8 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB if (ExplosionName == "Colors") { - int DataLength = a_NBT.GetDataLength(explosiontag); + // Divide by four as data length returned in bytes + int DataLength = a_NBT.GetDataLength(explosiontag) / 4; if (DataLength == 0) { continue; @@ -103,7 +104,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB } else if (ExplosionName == "FadeColors") { - int DataLength = a_NBT.GetDataLength(explosiontag); + int DataLength = a_NBT.GetDataLength(explosiontag) / 4; if (DataLength == 0) { continue; -- cgit v1.2.3 From 76bf7ad8132f2d36cf974d7a376ca7b911343eac Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Mar 2014 17:41:34 +0000 Subject: Hexified colours --- src/WorldStorage/FireworksSerializer.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 464bf225d..0e0094e76 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -231,22 +231,22 @@ int cFireworkItem::GetVanillaColourCodeFromDye(short a_DyeMeta) switch (a_DyeMeta) { - case E_META_DYE_BLACK: return 1973019; - case E_META_DYE_RED: return 11743532; - case E_META_DYE_GREEN: return 3887386; - case E_META_DYE_BROWN: return 5320730; - case E_META_DYE_BLUE: return 2437522; - case E_META_DYE_PURPLE: return 8073150; - case E_META_DYE_CYAN: return 2651799; - case E_META_DYE_LIGHTGRAY: return 11250603; - case E_META_DYE_GRAY: return 4408131; - case E_META_DYE_PINK: return 14188952; - case E_META_DYE_LIGHTGREEN: return 4312372; - case E_META_DYE_YELLOW: return 14602026; - case E_META_DYE_LIGHTBLUE: return 6719955; - case E_META_DYE_MAGENTA: return 12801229; - case E_META_DYE_ORANGE: return 15435844; - case E_META_DYE_WHITE: return 15790320; + case E_META_DYE_BLACK: return 0x1E1B1B; + case E_META_DYE_RED: return 0xB3312C; + case E_META_DYE_GREEN: return 0x3B511A; + case E_META_DYE_BROWN: return 0x51301A; + case E_META_DYE_BLUE: return 0x253192; + case E_META_DYE_PURPLE: return 0x7B2FBE; + case E_META_DYE_CYAN: return 0x287697; + case E_META_DYE_LIGHTGRAY: return 0xABABAB; + case E_META_DYE_GRAY: return 0x434343; + case E_META_DYE_PINK: return 0xD88198; + case E_META_DYE_LIGHTGREEN: return 0x41CD34; + case E_META_DYE_YELLOW: return 0xDECF2A; + case E_META_DYE_LIGHTBLUE: return 0x6689D3; + case E_META_DYE_MAGENTA: return 0xC354CD; + case E_META_DYE_ORANGE: return 0xEB8844; + case E_META_DYE_WHITE: return 0xF0F0F0; default: ASSERT(!"Unhandled dye meta whilst trying to get colour code for fireworks!"); return 0; } } -- cgit v1.2.3 From 77787fb719bf6437d4101f091b5b9acedea83dd3 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 9 Mar 2014 14:55:47 +0000 Subject: != FACE_NONE --- src/ClientHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d268a4122..1bd55a461 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -949,7 +949,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - if (a_BlockFace > BLOCK_FACE_NONE) + if (a_BlockFace != BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); -- cgit v1.2.3 From 0b9763fc5a84ac171338484f653fdae2a2bc999a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 10 Mar 2014 07:55:47 +0100 Subject: Fixed MSVC2008 compilation. --- src/WorldStorage/FireworksSerializer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 0e0094e76..1f05b470d 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -20,8 +20,8 @@ void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFa a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker); a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail); a_Writer.AddByte("Type", a_FireworkItem.m_Type); - a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size()); - a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size()); + a_Writer.AddIntArray("Colors", &(a_FireworkItem.m_Colours[0]), a_FireworkItem.m_Colours.size()); + a_Writer.AddIntArray("FadeColors", &(a_FireworkItem.m_FadeColours[0]), a_FireworkItem.m_FadeColours.size()); a_Writer.EndCompound(); a_Writer.EndList(); a_Writer.EndCompound(); @@ -35,11 +35,11 @@ void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFa a_Writer.AddByte("Type", a_FireworkItem.m_Type); if (!a_FireworkItem.m_Colours.empty()) { - a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size()); + a_Writer.AddIntArray("Colors", &(a_FireworkItem.m_Colours[0]), a_FireworkItem.m_Colours.size()); } if (!a_FireworkItem.m_FadeColours.empty()) { - a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size()); + a_Writer.AddIntArray("FadeColors", &(a_FireworkItem.m_FadeColours[0]), a_FireworkItem.m_FadeColours.size()); } a_Writer.EndCompound(); break; -- cgit v1.2.3