diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/BlockEntities/DispenserEntity.cpp | 2 | ||||
-rw-r--r-- | src/Blocks/BlockPortal.h | 2 | ||||
-rw-r--r-- | src/Blocks/WorldInterface.h | 2 | ||||
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/Color.cpp | 76 | ||||
-rw-r--r-- | src/Color.h | 58 | ||||
-rw-r--r-- | src/CraftingRecipes.cpp | 192 | ||||
-rw-r--r-- | src/CraftingRecipes.h | 3 | ||||
-rw-r--r-- | src/Entities/ThrownEggEntity.cpp | 10 | ||||
-rw-r--r-- | src/Item.cpp | 19 | ||||
-rw-r--r-- | src/Item.h | 11 | ||||
-rw-r--r-- | src/Items/ItemMobHead.h | 2 | ||||
-rw-r--r-- | src/Items/ItemPumpkin.h | 4 | ||||
-rw-r--r-- | src/Items/ItemSpawnEgg.h | 2 | ||||
-rw-r--r-- | src/Mobs/Monster.h | 2 | ||||
-rw-r--r-- | src/Mobs/Mooshroom.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Pig.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Villager.cpp | 2 | ||||
-rw-r--r-- | src/Protocol/Protocol17x.cpp | 36 | ||||
-rw-r--r-- | src/Protocol/Protocol18x.cpp | 29 | ||||
-rw-r--r-- | src/Simulator/FloodyFluidSimulator.cpp | 9 | ||||
-rw-r--r-- | src/World.cpp | 7 | ||||
-rw-r--r-- | src/World.h | 2 |
23 files changed, 439 insertions, 36 deletions
diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index a847f1b65..297d5273e 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -105,7 +105,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) { double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - if (m_World->SpawnMob(MobX, DispY, MobZ, static_cast<eMonsterType>(m_Contents.GetSlot(a_SlotNum).m_ItemDamage)) != cEntity::INVALID_ID) + if (m_World->SpawnMob(MobX, DispY, MobZ, static_cast<eMonsterType>(m_Contents.GetSlot(a_SlotNum).m_ItemDamage), false) != cEntity::INVALID_ID) { m_Contents.ChangeSlotCount(a_SlotNum, -1); } diff --git a/src/Blocks/BlockPortal.h b/src/Blocks/BlockPortal.h index c18acbdb5..4af50984e 100644 --- a/src/Blocks/BlockPortal.h +++ b/src/Blocks/BlockPortal.h @@ -49,7 +49,7 @@ public: int PosX = a_Chunk.GetPosX() * cChunkDef::Width + a_RelX; int PosZ = a_Chunk.GetPosZ() * cChunkDef::Width + a_RelZ; - a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, mtZombiePigman); + a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, mtZombiePigman, false); } virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index 826df7034..ede0837a4 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -35,7 +35,7 @@ public: /** Spawns a mob of the specified type. Returns the mob's UniqueID if recognized and spawned, or cEntity::INVALID_ID on failure. */ - virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) = 0; + virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType, bool a_Baby) = 0; /** Spawns an experience orb at the given location with the given reward. Returns the UniqueID of the spawned experience orb, or cEntity::INVALID_ID on failure. */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6c8fe7d0c..d941b7d4c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,6 +28,7 @@ SET (SRCS ChunkSender.cpp ChunkStay.cpp ClientHandle.cpp + Color.cpp CommandOutput.cpp CompositeChat.cpp CraftingRecipes.cpp diff --git a/src/Color.cpp b/src/Color.cpp new file mode 100644 index 000000000..f2180e2d9 --- /dev/null +++ b/src/Color.cpp @@ -0,0 +1,76 @@ +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "Color.h" + + + + + +#define COLOR_RED_BITS 0x00FF0000 +#define COLOR_GREEN_BITS 0x0000FF00 +#define COLOR_BLUE_BITS 0x000000FF +#define COLOR_RED_OFFSET 16 +#define COLOR_GREEN_OFFSET 8 + + + + + +void cColor::SetColor(unsigned char a_Red, unsigned char a_Green, unsigned char a_Blue) +{ + m_Color = (static_cast<unsigned int>(a_Red) << COLOR_RED_OFFSET) + (static_cast<unsigned int>(a_Green) << COLOR_GREEN_OFFSET) + (static_cast<unsigned int>(a_Blue)); +} + + + + + +void cColor::SetRed(unsigned char a_Red) +{ + m_Color = (static_cast<unsigned int>(a_Red) << COLOR_RED_OFFSET) + ((COLOR_GREEN_BITS | COLOR_BLUE_BITS) & m_Color); +} + + + + + +void cColor::SetGreen(unsigned char a_Green) +{ + m_Color = (static_cast<unsigned int>(a_Green) << COLOR_GREEN_OFFSET) + ((COLOR_RED_BITS | COLOR_BLUE_BITS) & m_Color); +} + + + + + +void cColor::SetBlue(unsigned char a_Blue) +{ + m_Color = static_cast<unsigned int>(a_Blue) + ((COLOR_RED_BITS | COLOR_GREEN_BITS) & m_Color); +} + + + + + +unsigned char cColor::GetRed() const +{ + return (m_Color & COLOR_RED_BITS) >> COLOR_RED_OFFSET; +} + + + + + +unsigned char cColor::GetGreen() const +{ + return (m_Color & COLOR_GREEN_BITS) >> COLOR_GREEN_OFFSET; +} + + + + + +unsigned char cColor::GetBlue() const +{ + return m_Color & COLOR_BLUE_BITS; +} diff --git a/src/Color.h b/src/Color.h new file mode 100644 index 000000000..a90e8372b --- /dev/null +++ b/src/Color.h @@ -0,0 +1,58 @@ + +// Color.h + +// Declares a class to handle item color related code + + + + + +#pragma once + + // tolua_begin + +class cColor +{ +public: + + enum + { + COLOR_MIN = 0, + COLOR_MAX = 255, + COLOR_LIMIT = 256, + COLOR_NONE = 0xFFFFFFFF, + }; + cColor() { m_Color = COLOR_NONE;} + cColor(unsigned char a_Red, unsigned char a_Green, unsigned char a_Blue) { SetColor(a_Red, a_Green, a_Blue); } + + /// Returns whether the color is a valid color + bool IsValid() const { return m_Color != COLOR_NONE; } + + /// Changes the color + void SetColor(unsigned char a_Red, unsigned char a_Green, unsigned char a_Blue); + + /// Alters the red value of the color + void SetRed(unsigned char a_Red); + + /// Alters the green value of the color + void SetGreen(unsigned char a_Red); + + /// Alters the blue value of the color + void SetBlue(unsigned char a_Red); + + /// Returns the red value of the color + unsigned char GetRed() const; + + /// Returns the green value of the color + unsigned char GetGreen() const; + + /// Returns the blue value of the color + unsigned char GetBlue() const; + + /// Resets the color + void Clear() { m_Color = COLOR_NONE; } + // tolua_end + + unsigned int m_Color; + +}; diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 0bb77d341..d3a28292a 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -787,6 +787,9 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti // 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); + // Handle Dyed Leather + HandleDyedLeather(a_CraftingGrid, Recipe.get(), a_GridStride, a_GridWidth, a_GridHeight); + return Recipe.release(); } @@ -874,3 +877,192 @@ void cCraftingRecipes::HandleFireworks(const cItem * a_CraftingGrid, cCraftingRe + +void cCraftingRecipes::HandleDyedLeather(const cItem * a_CraftingGrid, cCraftingRecipes::cRecipe * a_Recipe, int a_GridStride, int a_GridWidth, int a_GridHeight) +{ + short result_type = a_Recipe->m_Result.m_ItemType; + if ((result_type == E_ITEM_LEATHER_CAP) || (result_type == E_ITEM_LEATHER_TUNIC) || (result_type == E_ITEM_LEATHER_PANTS) || (result_type == E_ITEM_LEATHER_BOOTS)) + { + bool found = false; + cItem temp; + + float red = 0; + float green = 0; + float blue = 0; + float dye_count = 0; + + for (int x = 0; x < a_GridWidth; ++x) + { + for (int y = 0; y < a_GridHeight; ++y) + { + int GridIdx = x + a_GridStride * y; + if ((a_CraftingGrid[GridIdx].m_ItemType == result_type) && (found == false)) + { + found = true; + temp = a_CraftingGrid[GridIdx].CopyOne(); + // The original color of the item affects the result + if (temp.m_ItemColor.IsValid()) + { + red += temp.m_ItemColor.GetRed(); + green += temp.m_ItemColor.GetGreen(); + blue += temp.m_ItemColor.GetBlue(); + ++dye_count; + } + } + else if (a_CraftingGrid[GridIdx].m_ItemType == E_ITEM_DYE) + { + switch (a_CraftingGrid[GridIdx].m_ItemDamage) + { + case E_META_DYE_BLACK: + { + red += 23; + green += 23; + blue += 23; + break; + } + case E_META_DYE_RED: + { + red += 142; + green += 47; + blue += 47; + break; + } + case E_META_DYE_GREEN: + { + red += 95; + green += 118; + blue += 47; + break; + } + case E_META_DYE_BROWN: + { + red += 95; + green += 71; + blue += 47; + break; + } + case E_META_DYE_BLUE: + { + red += 47; + green += 71; + blue += 165; + break; + } + case E_META_DYE_PURPLE: + { + red += 118; + green += 59; + blue += 165; + break; + } + case E_META_DYE_CYAN: + { + red += 71; + green += 118; + blue += 142; + break; + } + case E_META_DYE_LIGHTGRAY: + { + red += 142; + green += 142; + blue += 142; + break; + } + case E_META_DYE_GRAY: + { + red += 71; + green += 71; + blue += 71; + break; + } + case E_META_DYE_PINK: + { + red += 225; + green += 118; + blue += 153; + break; + } + case E_META_DYE_LIGHTGREEN: + { + red += 118; + green += 190; + blue += 23; + break; + } + case E_META_DYE_YELLOW: + { + red += 213; + green += 213; + blue += 47; + break; + } + case E_META_DYE_LIGHTBLUE: + { + red += 95; + green += 142; + blue += 201; + break; + } + case E_META_DYE_MAGENTA: + { + red += 165; + green += 71; + blue += 201; + break; + } + case E_META_DYE_ORANGE: + { + red += 201; + green += 118; + blue += 47; + break; + } + case E_META_DYE_WHITE: + { + red += 237; + green += 237; + blue += 237; + break; + } + } + ++dye_count; + } + else if (a_CraftingGrid[GridIdx].m_ItemType != E_ITEM_EMPTY) + { + return; + } + } + } + + if (!found) + { + return; + } + + // Calculate the rgb values + double maximum = static_cast<double>(std::max({red, green, blue})); + + double average_red = red / dye_count; + double average_green = green / dye_count; + double average_blue = blue / dye_count; + double average_max = maximum / dye_count; + + double max_average = std::max({average_red, average_green, average_blue}); + + double gain_factor = average_max / max_average; + + + unsigned char result_red = static_cast<unsigned char>(average_red * gain_factor); + unsigned char result_green = static_cast<unsigned char>(average_green * gain_factor); + unsigned char result_blue = static_cast<unsigned char>(average_blue * gain_factor); + + // Set the results values + a_Recipe->m_Result = temp; + a_Recipe->m_Result.m_ItemColor.SetColor(result_red, result_green, result_blue); + } +} + + + + diff --git a/src/CraftingRecipes.h b/src/CraftingRecipes.h index 44444d42e..778dd495a 100644 --- a/src/CraftingRecipes.h +++ b/src/CraftingRecipes.h @@ -168,6 +168,9 @@ protected: /** 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); + + /// Searches for anything dye related for leather, calculates the appropriate color value, and sets the resulting value. + void HandleDyedLeather(const cItem * a_CraftingGrid, cCraftingRecipes::cRecipe * a_Recipe, int a_GridStride, int a_GridWidth, int a_GridHeight); } ; diff --git a/src/Entities/ThrownEggEntity.cpp b/src/Entities/ThrownEggEntity.cpp index e9ef29239..91bca1da7 100644 --- a/src/Entities/ThrownEggEntity.cpp +++ b/src/Entities/ThrownEggEntity.cpp @@ -69,13 +69,13 @@ void cThrownEggEntity::TrySpawnChicken(const Vector3d & a_HitPos) { if (m_World->GetTickRandomNumber(7) == 1) { - m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken); + m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken, false); } else if (m_World->GetTickRandomNumber(32) == 1) { - m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken); - m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken); - m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken); - m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken); + m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken, false); + m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken, false); + m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken, false); + m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken, false); } } diff --git a/src/Item.cpp b/src/Item.cpp index 36c444328..7bd344ae8 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -142,6 +142,13 @@ void cItem::GetJson(Json::Value & a_OutValue) const a_OutValue["Lore"] = m_Lore; } + if (m_ItemColor.IsValid()) + { + a_OutValue["Color_Red"] = m_ItemColor.GetRed(); + a_OutValue["Color_Green"] = m_ItemColor.GetGreen(); + a_OutValue["Color_Blue"] = m_ItemColor.GetBlue(); + } + if ((m_ItemType == E_ITEM_FIREWORK_ROCKET) || (m_ItemType == E_ITEM_FIREWORK_STAR)) { a_OutValue["Flicker"] = m_FireworkItem.m_HasFlicker; @@ -172,6 +179,18 @@ void cItem::FromJson(const Json::Value & a_Value) m_CustomName = a_Value.get("Name", "").asString(); m_Lore = a_Value.get("Lore", "").asString(); + int red = a_Value.get("Color_Red", -1).asInt(); + int green = a_Value.get("Color_Green", -1).asInt(); + int blue = a_Value.get("Color_Blue", -1).asInt(); + if ((red > -1) && (red < static_cast<int>(cColor::COLOR_LIMIT)) && (green > -1) && (green < static_cast<int>(cColor::COLOR_LIMIT)) && (blue > -1) && (blue < static_cast<int>(cColor::COLOR_LIMIT))) + { + m_ItemColor.SetColor(static_cast<unsigned char>(red), static_cast<unsigned char>(green), static_cast<unsigned char>(blue)); + } + else if ((red != -1) || (blue != -1) || (green != -1)) + { + LOGWARNING("Item with invalid red, green, and blue values read in from json file."); + } + if ((m_ItemType == E_ITEM_FIREWORK_ROCKET) || (m_ItemType == E_ITEM_FIREWORK_STAR)) { m_FireworkItem.m_HasFlicker = a_Value.get("Flicker", false).asBool(); diff --git a/src/Item.h b/src/Item.h index 056b5eb8a..8f47c4177 100644 --- a/src/Item.h +++ b/src/Item.h @@ -12,6 +12,7 @@ #include "Defines.h" #include "Enchantments.h" #include "WorldStorage/FireworksSerializer.h" +#include "Color.h" @@ -19,6 +20,7 @@ // fwd: class cItemHandler; +class cColor; namespace Json { @@ -41,7 +43,8 @@ public: m_CustomName(""), m_Lore(""), m_RepairCost(0), - m_FireworkItem() + m_FireworkItem(), + m_ItemColor() { } @@ -62,7 +65,8 @@ public: m_CustomName (a_CustomName), m_Lore (a_Lore), m_RepairCost (0), - m_FireworkItem() + m_FireworkItem(), + m_ItemColor() { if (!IsValidItem(m_ItemType)) { @@ -105,6 +109,7 @@ public: m_Lore = ""; m_RepairCost = 0; m_FireworkItem.EmptyData(); + m_ItemColor.Clear(); } @@ -114,6 +119,7 @@ public: m_ItemCount = 0; m_ItemDamage = 0; m_RepairCost = 0; + m_ItemColor.Clear(); } @@ -206,6 +212,7 @@ public: int m_RepairCost; cFireworkItem m_FireworkItem; + cColor m_ItemColor; }; // tolua_end diff --git a/src/Items/ItemMobHead.h b/src/Items/ItemMobHead.h index 9a4044bc0..e0f72be9b 100644 --- a/src/Items/ItemMobHead.h +++ b/src/Items/ItemMobHead.h @@ -278,7 +278,7 @@ public: // Spawn the wither: int BlockX = a_PlacedHeadX + a_OffsetX; int BlockZ = a_PlacedHeadZ + a_OffsetZ; - a_World.SpawnMob(static_cast<double>(BlockX) + 0.5, a_PlacedHeadY - 2, static_cast<double>(BlockZ) + 0.5, mtWither); + a_World.SpawnMob(static_cast<double>(BlockX) + 0.5, a_PlacedHeadY - 2, static_cast<double>(BlockZ) + 0.5, mtWither, false); AwardSpawnWitherAchievement(a_World, BlockX, a_PlacedHeadY - 2, BlockZ); return true; } diff --git a/src/Items/ItemPumpkin.h b/src/Items/ItemPumpkin.h index fa00179d3..7a53d522f 100644 --- a/src/Items/ItemPumpkin.h +++ b/src/Items/ItemPumpkin.h @@ -96,7 +96,7 @@ public: } // Spawn the golem: - a_World.SpawnMob(static_cast<double>(a_BlockX) + 0.5, a_BlockY - 2, static_cast<double>(a_BlockZ) + 0.5, mtSnowGolem); + a_World.SpawnMob(static_cast<double>(a_BlockX) + 0.5, a_BlockY - 2, static_cast<double>(a_BlockZ) + 0.5, mtSnowGolem, false); return true; } @@ -142,7 +142,7 @@ public: } // Spawn the golem: - a_World.SpawnMob(static_cast<double>(a_BlockX) + 0.5, a_BlockY - 2, static_cast<double>(a_BlockZ) + 0.5, mtIronGolem); + a_World.SpawnMob(static_cast<double>(a_BlockX) + 0.5, a_BlockY - 2, static_cast<double>(a_BlockZ) + 0.5, mtIronGolem, false); return true; } // for i - ArmOffsets[] diff --git a/src/Items/ItemSpawnEgg.h b/src/Items/ItemSpawnEgg.h index b67fe074d..85dd2d245 100644 --- a/src/Items/ItemSpawnEgg.h +++ b/src/Items/ItemSpawnEgg.h @@ -40,7 +40,7 @@ public: eMonsterType MonsterType = ItemDamageToMonsterType(a_Item.m_ItemDamage); if ( (MonsterType != mtInvalidType) && // Valid monster type - (a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, MonsterType) != cEntity::INVALID_ID)) // Spawning succeeded + (a_World->SpawnMob(a_BlockX + 0.5, a_BlockY, a_BlockZ + 0.5, MonsterType, false) != cEntity::INVALID_ID)) // Spawning succeeded { if (!a_Player->IsGameModeCreative()) { diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 2832a1570..d5de3b19e 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -115,9 +115,11 @@ public: virtual bool IsTame (void) const { return false; } virtual bool IsSitting (void) const { return false; } + // tolua_begin bool IsBaby (void) const { return m_Age < 0; } char GetAge (void) const { return m_Age; } void SetAge(char a_Age) { m_Age = a_Age; } + // tolua_end // tolua_begin diff --git a/src/Mobs/Mooshroom.cpp b/src/Mobs/Mooshroom.cpp index 3b2fbad57..08cabe143 100644 --- a/src/Mobs/Mooshroom.cpp +++ b/src/Mobs/Mooshroom.cpp @@ -67,7 +67,7 @@ void cMooshroom::OnRightClicked(cPlayer & a_Player) cItems Drops; Drops.push_back(cItem(E_BLOCK_RED_MUSHROOM, 5, 0)); m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); - m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtCow); + m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtCow, false); Destroy(); } break; } diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp index efa779ac2..21c8e923a 100644 --- a/src/Mobs/Pig.cpp +++ b/src/Mobs/Pig.cpp @@ -108,7 +108,7 @@ bool cPig::DoTakeDamage(TakeDamageInfo & a_TDI) if (a_TDI.DamageType == dtLightning) { Destroy(); - m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtZombiePigman); + m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtZombiePigman, false); return true; } return true; diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index e4953d546..9239575d0 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -41,7 +41,7 @@ bool cVillager::DoTakeDamage(TakeDamageInfo & a_TDI) if (a_TDI.DamageType == dtLightning) { Destroy(); - m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtWitch); + m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtWitch, false); return true; } return true; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index dc602ec6c..098c62a90 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2637,6 +2637,10 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) a_Item.m_Lore = Lore; } + else if ((NBT.GetType(displaytag) == TAG_Int) && (NBT.GetName(displaytag) == "color")) + { + a_Item.m_ItemColor.m_Color = static_cast<unsigned int>(NBT.GetInt(displaytag)); + } } } else if ((TagName == "Fireworks") || (TagName == "Explosion")) @@ -2723,7 +2727,7 @@ void cProtocol172::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) a_Pkt.WriteBEInt8(a_Item.m_ItemCount); a_Pkt.WriteBEInt16(a_Item.m_ItemDamage); - 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)) + 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) && !a_Item.m_ItemColor.IsValid()) { a_Pkt.WriteBEInt16(-1); return; @@ -2740,9 +2744,15 @@ void cProtocol172::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName); } - if (!a_Item.IsBothNameAndLoreEmpty()) + if (!a_Item.IsBothNameAndLoreEmpty() || a_Item.m_ItemColor.IsValid()) { Writer.BeginCompound("display"); + + if (a_Item.m_ItemColor.IsValid()) + { + Writer.AddInt("color", static_cast<int>(a_Item.m_ItemColor.m_Color)); + } + if (!a_Item.IsCustomNameEmpty()) { Writer.AddString("Name", a_Item.m_CustomName.c_str()); @@ -3006,6 +3016,19 @@ void cProtocol172::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_En void cProtocol172::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) { + // Living Enitiy Metadata + if (a_Mob.HasCustomName()) + { + a_Pkt.WriteBEUInt8(0x8a); + a_Pkt.WriteString(a_Mob.GetCustomName()); + + a_Pkt.WriteBEUInt8(0x0b); + a_Pkt.WriteBool(a_Mob.IsCustomNameAlwaysVisible()); + } + + a_Pkt.WriteBEUInt8(0x66); + a_Pkt.WriteBEFloat(a_Mob.GetHealth()); + switch (a_Mob.GetMobType()) { case mtBat: @@ -3199,15 +3222,6 @@ void cProtocol172::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) break; } } // switch (a_Mob.GetType()) - - // Custom name: - if (a_Mob.HasCustomName()) - { - a_Pkt.WriteBEUInt8(0x8a); - a_Pkt.WriteString(a_Mob.GetCustomName()); - a_Pkt.WriteBEUInt8(0x0b); - a_Pkt.WriteBEUInt8(a_Mob.IsCustomNameAlwaysVisible() ? 1 : 0); - } } diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index db510825e..f4f32dfdb 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -2869,6 +2869,10 @@ void cProtocol180::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) a_Item.m_Lore = Lore; } + else if ((NBT.GetType(displaytag) == TAG_Int) && (NBT.GetName(displaytag) == "color")) + { + a_Item.m_ItemColor.m_Color = static_cast<unsigned int>(NBT.GetInt(displaytag)); + } } } else if ((TagName == "Fireworks") || (TagName == "Explosion")) @@ -3018,12 +3022,13 @@ void cProtocol180::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) a_Pkt.WriteBEInt8(a_Item.m_ItemCount); a_Pkt.WriteBEInt16(a_Item.m_ItemDamage); - 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)) + 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) && !a_Item.m_ItemColor.IsValid()) { a_Pkt.WriteBEInt8(0); return; } + // Send the enchantments and custom names: cFastNBTWriter Writer; if (a_Item.m_RepairCost != 0) @@ -3035,9 +3040,14 @@ void cProtocol180::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName); } - if (!a_Item.IsBothNameAndLoreEmpty()) + if (!a_Item.IsBothNameAndLoreEmpty() || a_Item.m_ItemColor.IsValid()) { Writer.BeginCompound("display"); + if (a_Item.m_ItemColor.IsValid()) + { + Writer.AddInt("color", static_cast<int>(a_Item.m_ItemColor.m_Color)); + } + if (!a_Item.IsCustomNameEmpty()) { Writer.AddString("Name", a_Item.m_CustomName.c_str()); @@ -3197,7 +3207,7 @@ void cProtocol180::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_En } a_Pkt.WriteBEUInt8(0); // Byte(0) + index 0 a_Pkt.WriteBEUInt8(Flags); - + switch (a_Entity.GetEntityType()) { case cEntity::etPlayer: break; // TODO? @@ -3303,6 +3313,19 @@ void cProtocol180::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_En void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) { + // Living Enitiy Metadata + if (a_Mob.HasCustomName()) + { + a_Pkt.WriteBEUInt8(0x82); + a_Pkt.WriteString(a_Mob.GetCustomName()); + + a_Pkt.WriteBEUInt8(0x03); + a_Pkt.WriteBool(a_Mob.IsCustomNameAlwaysVisible()); + } + + a_Pkt.WriteBEUInt8(0x66); + a_Pkt.WriteBEFloat(a_Mob.GetHealth()); + switch (a_Mob.GetMobType()) { case mtBat: diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index 69c46f090..1e56f9528 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -111,9 +111,12 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re // If source creation is on, check for it here: if ( - (m_NumNeighborsForSource > 0) && // Source creation is on - (MyMeta == m_Falloff) && // Only exactly one block away from a source (fast bail-out) - !IsPassableForFluid(Below) && // Only exactly 1 block deep + (m_NumNeighborsForSource > 0) && // Source creation is on + (MyMeta == m_Falloff) && // Only exactly one block away from a source (fast bail-out) + ( + !IsPassableForFluid(Below) || // Only exactly 1 block deep + (Below == m_StationaryFluidBlock) // Or a source block underneath + ) && CheckNeighborsForSource(a_Chunk, a_RelX, a_RelY, a_RelZ) // Did we create a source? ) { diff --git a/src/World.cpp b/src/World.cpp index dec335253..b152d119a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3326,7 +3326,7 @@ bool cWorld::IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ) -UInt32 cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) +UInt32 cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType, bool a_Baby) { cMonster * Monster = nullptr; @@ -3337,6 +3337,11 @@ UInt32 cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterTyp } Monster->SetPosition(a_PosX, a_PosY, a_PosZ); + if (a_Baby) + { + Monster->SetAge(-1); + } + return SpawnMobFinalize(Monster); } diff --git a/src/World.h b/src/World.h index 083f3f204..ab2b197c5 100644 --- a/src/World.h +++ b/src/World.h @@ -843,7 +843,7 @@ public: bool IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export /** Spawns a mob of the specified type. Returns the mob's UniqueID if recognized and spawned, cEntity::INVALID_ID otherwise */ - virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType) override; // tolua_export + virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType, bool a_Baby = false) override; // tolua_export UInt32 SpawnMobFinalize(cMonster * a_Monster); |