1
0

Adding basic Banner functionality (#4806)

+ Added item and block for banners

Co-authored-by: 12xx12 <12xx12100@gmail.com>
Co-authored-by: Tiger Wang <ziwei.tiger@outlook.com>
This commit is contained in:
12xx12 2021-03-15 03:47:55 +01:00 committed by GitHub
parent ca5608c66c
commit 243083e01a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 617 additions and 15 deletions

View File

@ -0,0 +1,78 @@
// BannerEntity.cpp
// Implements the cBannerEntity class representing a banner block in the world
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "BannerEntity.h"
#include "../World.h"
#include "../ClientHandle.h"
cBannerEntity::cBannerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World) :
cBannerEntity(a_BlockType, a_BlockMeta, a_Pos, a_World, 1)
{
}
cBannerEntity::cBannerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World, unsigned char a_BaseColor):
Super(a_BlockType, a_BlockMeta, a_Pos, a_World),
m_BaseColor(a_BaseColor)
{
ASSERT((a_BlockType == E_BLOCK_WALL_BANNER) || (a_BlockType == E_BLOCK_STANDING_BANNER));
}
void cBannerEntity::CopyFrom(const cBlockEntity & a_Src)
{
Super::CopyFrom(a_Src);
auto & src = static_cast<const cBannerEntity &>(a_Src);
m_BaseColor = src.m_BaseColor;
}
void cBannerEntity::SendTo(cClientHandle & a_Client)
{
a_Client.SendBlockChange(m_Pos.x, m_Pos.y, m_Pos.z, m_BlockType, m_BlockMeta);
a_Client.SendUpdateBlockEntity(*this);
}
cItems cBannerEntity::ConvertToPickups() const
{
return cItem(E_ITEM_BANNER, 1, static_cast<NIBBLETYPE>(GetBaseColor()));
}
unsigned char cBannerEntity::GetBaseColor() const
{
return m_BaseColor;
}
void cBannerEntity::SetBaseColor(const unsigned char a_Color)
{
m_BaseColor = a_Color;
}

View File

@ -0,0 +1,43 @@
// BannerEntity.h
// Declares the cBannerEntity class representing a single banner in the world
#pragma once
#include "BlockEntity.h"
// tolua_begin
class cBannerEntity :
public cBlockEntity
{
// tolua_end
using Super = cBlockEntity;
public:
cBannerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World);
cBannerEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos, cWorld * a_World, unsigned char a_BaseColor);
unsigned char GetBaseColor() const;
void SetBaseColor(unsigned char a_Color);
private:
unsigned char m_BaseColor;
// cBlockEntity overrides:
virtual cItems ConvertToPickups() const override;
virtual void CopyFrom(const cBlockEntity & a_Src) override;
virtual void SendTo(cClientHandle & a_Client) override;
virtual bool UsedBy(cPlayer * a_Player) override { return true; }
} ; // tolua_export

View File

@ -4,6 +4,7 @@
// Implements the cBlockEntity class that is the common ancestor for all block entities
#include "Globals.h"
#include "BannerEntity.h"
#include "BeaconEntity.h"
#include "BedEntity.h"
#include "BlockEntity.h"
@ -77,6 +78,11 @@ OwnedBlockEntity cBlockEntity::CreateByBlockType(const BLOCKTYPE a_BlockType, co
{
switch (a_BlockType)
{
// Banners:
case E_BLOCK_STANDING_BANNER:
case E_BLOCK_WALL_BANNER: return std::make_unique<cBannerEntity >(a_BlockType, a_BlockMeta, a_Pos, a_World);
// Others:
case E_BLOCK_BEACON: return std::make_unique<cBeaconEntity >(a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_BED: return std::make_unique<cBedEntity >(a_BlockType, a_BlockMeta, a_Pos, a_World);
case E_BLOCK_BREWING_STAND: return std::make_unique<cBrewingstandEntity >(a_BlockType, a_BlockMeta, a_Pos, a_World);
@ -144,7 +150,9 @@ bool cBlockEntity::IsBlockEntityBlockType(const BLOCKTYPE a_BlockType)
case E_BLOCK_MOB_SPAWNER:
case E_BLOCK_NOTE_BLOCK:
case E_BLOCK_SIGN_POST:
case E_BLOCK_STANDING_BANNER:
case E_BLOCK_TRAPPED_CHEST:
case E_BLOCK_WALL_BANNER:
case E_BLOCK_WALLSIGN:
{
return true;

View File

@ -1,6 +1,7 @@
target_sources(
${CMAKE_PROJECT_NAME} PRIVATE
BannerEntity.cpp
BeaconEntity.cpp
BedEntity.cpp
BlockEntity.cpp
@ -23,6 +24,7 @@ target_sources(
NoteEntity.cpp
SignEntity.cpp
BannerEntity.h
BeaconEntity.h
BedEntity.h
BlockEntity.h

51
src/Blocks/BlockBanner.h Normal file
View File

@ -0,0 +1,51 @@
// BlockBanner.h
#pragma once
#include "../BlockInfo.h"
#include "BlockEntity.h"
class cBlockBannerHandler final :
public cBlockEntityHandler
{
using Super = cBlockEntityHandler;
public:
using Super::Super;
virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, const cEntity * a_Digger, const cItem * a_Tool) const override
{
// Drops handled by the block entity:
return {};
}
virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override
{
if (a_RelPos.y < 1)
{
return false;
}
return cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelPos.addedY(-1)));
}
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override
{
UNUSED(a_Meta);
return 0;
}
} ;

View File

@ -7,6 +7,7 @@
#include "BlockPluginInterface.h"
#include "BlockAir.h"
#include "BlockAnvil.h"
#include "BlockBanner.h"
#include "BlockBed.h"
#include "BlockBigFlower.h"
#include "BlockBookShelf.h"
@ -412,7 +413,7 @@ namespace
constexpr cDefaultBlockHandler BlockStainedClayHandler (E_BLOCK_STAINED_CLAY);
constexpr cBlockGlassHandler BlockStainedGlassHandler (E_BLOCK_STAINED_GLASS);
constexpr cBlockGlassHandler BlockStainedGlassPaneHandler (E_BLOCK_STAINED_GLASS_PANE);
constexpr cDefaultBlockHandler BlockStandingBannerHandler (E_BLOCK_STANDING_BANNER); // TODO: drops correct?
constexpr cBlockBannerHandler BlockStandingBannerHandler (E_BLOCK_STANDING_BANNER);
constexpr cBlockLavaHandler BlockStationaryLavaHandler (E_BLOCK_STATIONARY_LAVA);
constexpr cBlockWaterHandler BlockStationaryWaterHandler (E_BLOCK_STATIONARY_WATER);
constexpr cBlockPistonHandler BlockStickyPistonHandler (E_BLOCK_STICKY_PISTON);
@ -433,7 +434,7 @@ namespace
constexpr cBlockTripwireHandler BlockTripwireHandler (E_BLOCK_TRIPWIRE);
constexpr cBlockTripwireHookHandler BlockTripwireHookHandler (E_BLOCK_TRIPWIRE_HOOK);
constexpr cBlockVineHandler BlockVinesHandler (E_BLOCK_VINES);
constexpr cDefaultBlockHandler BlockWallBannerHandler (E_BLOCK_WALL_BANNER); // TODO: drops correct?
constexpr cBlockBannerHandler BlockWallBannerHandler (E_BLOCK_WALL_BANNER);
constexpr cBlockWallSignHandler BlockWallsignHandler (E_BLOCK_WALLSIGN);
constexpr cBlockWaterHandler BlockWaterHandler (E_BLOCK_WATER);
constexpr cBlockGlazedTerracottaHandler BlockWhiteGlazedTerracottaHandler (E_BLOCK_WHITE_GLAZED_TERRACOTTA);

View File

@ -9,6 +9,7 @@ target_sources(
BlockAir.h
BlockAnvil.h
BlockBanner.h
BlockBed.h
BlockBigFlower.h
BlockBookShelf.h

View File

@ -395,6 +395,54 @@ enum eMessageType
enum class BannerPattern
{
BottomStripe,
TopStripe,
LeftStripe,
RightStripe,
CenterStripeVertical,
MiddleStripeHorizontal,
DownRightStripe,
DownLeftStripe,
SmallVerticalStripes,
DiagonalCross,
SquareCross,
LeftOfDiagonal,
RightOfUpsideDownDiagonal,
LeftOfUpsideDownDiagonal,
RightOfDiagonal,
VerticalHalfLeft,
VerticalHalfRight,
HorizontalHalfTop,
HorizontalHalfBottom,
BottomLeftCorner,
BottomRightCorner,
TopLeftCorner,
TopRightCorner,
BottomTriangle,
TopTriangle,
BottomTriangleSawtooth,
TopTriangleSawtooth,
MiddleCircle,
MiddleRhombus,
Border,
CurlyBorder,
Brick,
Gradient,
GradientUpsideDown,
Creeper,
Skull,
Flower,
Mojang,
Globe,
Piglin
};
enum class BossBarColor
{
Pink,

View File

@ -5,6 +5,7 @@ target_sources(
ItemArmor.h
ItemAxe.h
ItemBanner.h
ItemBed.h
ItemBigFlower.h
ItemBoat.h

215
src/Items/ItemBanner.h Normal file
View File

@ -0,0 +1,215 @@
#pragma once
#include "ItemHandler.h"
#include "../World.h"
#include "../Blocks/BlockHandler.h"
#include "../BlockEntities/BannerEntity.h"
#include "../Blocks/ChunkInterface.h"
class cItemBannerHandler:
public cItemHandler
{
using Super = cItemHandler;
public:
cItemBannerHandler(int a_ItemType):
Super(a_ItemType)
{
}
virtual bool IsPlaceable(void) override
{
return true;
}
virtual bool GetPlacementBlockTypeMeta(
cWorld * a_World, cPlayer * a_Player,
const Vector3i a_PlacedBlockPos,
eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override
{
a_BlockMeta = 0x00;
const double Rotation = a_Player->GetYaw();
// Placing on the floor
if (a_ClickedBlockFace == BLOCK_FACE_TOP)
{
if ((Rotation >= - 11.25f) && (Rotation < 11.25f))
{
// South
a_BlockMeta |= 0x08;
}
else if ((Rotation >= 11.25f) && (Rotation < 33.75f))
{
// SouthSouthWest
a_BlockMeta |= 0x09;
}
else if ((Rotation >= 23.75f) && (Rotation < 56.25f))
{
// SouthWest
a_BlockMeta |= 0x0a;
}
else if ((Rotation >= 56.25f) && (Rotation < 78.75f))
{
// WestSouthWest
a_BlockMeta |= 0x0b;
}
else if ((Rotation >= 78.75f) && (Rotation < 101.25f))
{
// West
a_BlockMeta |= 0x0c;
}
else if ((Rotation >= 101.25f) && (Rotation < 123.75f))
{
// WestNorthWest
a_BlockMeta |= 0x0d;
}
else if ((Rotation >= 123.75f) && (Rotation < 146.25f))
{
// NorthWest
a_BlockMeta |= 0x0e;
}
else if ((Rotation >= 146.25f) && (Rotation < 168.75f))
{
// NorthNorthWest
a_BlockMeta |= 0x0f;
}
else if ((Rotation >= -168.75f) && (Rotation < -146.25f))
{
// NorthNorthEast
a_BlockMeta |= 0x01;
}
else if ((Rotation >= -146.25f) && (Rotation < -123.75f))
{
// NorthEast
a_BlockMeta |= 0x02;
}
else if ((Rotation >= -123.75f) && (Rotation < -101.25f))
{
// EastNorthEast
a_BlockMeta |= 0x03;
}
else if ((Rotation >= -101.25) && (Rotation < -78.75f))
{
// East
a_BlockMeta |= 0x04;
}
else if ((Rotation >= -78.75) && (Rotation < -56.25f))
{
// EastSouthEast
a_BlockMeta |= 0x05;
}
else if ((Rotation >= -56.25f) && (Rotation < -33.75f))
{
// SouthEast
a_BlockMeta |= 0x06;
}
else if ((Rotation >= -33.75f) && (Rotation < -11.25f))
{
// SouthSouthEast
a_BlockMeta |= 0x07;
}
else // degrees jumping from 180 to -180
{
// North
a_BlockMeta |= 0x00;
}
a_BlockType = E_BLOCK_STANDING_BANNER;
}
// placing on the sides
else if (a_ClickedBlockFace != BLOCK_FACE_NONE)
{
if (a_ClickedBlockFace == BLOCK_FACE_EAST)
{
a_BlockMeta |= 0x05;
}
else if (a_ClickedBlockFace == BLOCK_FACE_WEST)
{
a_BlockMeta |= 0x04;
}
else if (a_ClickedBlockFace == BLOCK_FACE_NORTH)
{
a_BlockMeta |= 0x02;
}
else // degrees jumping from 180 to -180
{
a_BlockMeta |= 0x03;
}
a_BlockType = E_BLOCK_WALL_BANNER;
}
else
{
return false;
}
return true;
}
virtual bool OnPlayerPlace(
cWorld & a_World,
cPlayer & a_Player,
const cItem & a_EquippedItem,
const Vector3i a_ClickedBlockPos,
eBlockFace a_ClickedBlockFace,
const Vector3i a_CursorPos
) override
{
// Cannot place a banner at "no face" and from the bottom:
if ((a_ClickedBlockFace == BLOCK_FACE_NONE) || (a_ClickedBlockFace == BLOCK_FACE_BOTTOM))
{
return true;
}
// Checks if the banner replaced the block
BLOCKTYPE ClickedBlockType;
NIBBLETYPE ClickedBlockMeta;
a_World.GetBlockTypeMeta(a_ClickedBlockPos, ClickedBlockType, ClickedBlockMeta);
cChunkInterface ChunkInterface(a_World.GetChunkMap());
bool IsReplacingClickedBlock = cBlockHandler::For(ClickedBlockType).DoesIgnoreBuildCollision(ChunkInterface, a_ClickedBlockPos, a_Player, ClickedBlockMeta);
if (IsReplacingClickedBlock)
{
// TODO: There is a bug in the network which prevents the client from receiving the new block entity on placement
// For now the replaced blocks are disabled
return false;
}
// saving the color of the banner in case it's the players last one
NIBBLETYPE Color = static_cast<NIBBLETYPE>(a_EquippedItem.m_ItemDamage);
if (!Super::OnPlayerPlace(a_World, a_Player, a_EquippedItem, a_ClickedBlockPos, a_ClickedBlockFace, a_ClickedBlockPos))
{
return false;
}
const auto BannerPos = AddFaceDirection(a_ClickedBlockPos, a_ClickedBlockFace);
return a_World.DoWithBlockEntityAt(BannerPos.x, BannerPos.y, BannerPos.z, [Color](cBlockEntity & a_BlockEntity)
{
ASSERT((a_BlockEntity.GetBlockType() == E_BLOCK_STANDING_BANNER) || (a_BlockEntity.GetBlockType() == E_BLOCK_WALL_BANNER));
auto & Banner = static_cast<cBannerEntity &>(a_BlockEntity);
Banner.SetBaseColor(Color);
return true;
});
}
};

View File

@ -10,6 +10,7 @@
// Handlers:
#include "ItemArmor.h"
#include "ItemAxe.h"
#include "ItemBanner.h"
#include "ItemBed.h"
#include "ItemBigFlower.h"
#include "ItemBoat.h"
@ -112,6 +113,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType)
default: return new cItemHandler(a_ItemType);
// Single item per handler, alphabetically sorted:
case E_ITEM_BANNER: return new cItemBannerHandler(a_ItemType);
case E_BLOCK_BIG_FLOWER: return new cItemBigFlowerHandler;
case E_BLOCK_CHEST: return new cItemChestHandler(a_ItemType);
case E_BLOCK_ENCHANTMENT_TABLE: return new cItemEnchantingTableHandler(a_ItemType);

View File

@ -35,6 +35,7 @@ Implements the 1.10 protocol classes:
#include "../Mobs/IncludeAllMonsters.h"
#include "../BlockEntities/BannerEntity.h"
#include "../BlockEntities/BeaconEntity.h"
#include "../BlockEntities/CommandBlockEntity.h"
#include "../BlockEntities/MobHeadEntity.h"
@ -586,6 +587,18 @@ void cProtocol_1_10_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity
switch (a_BlockEntity.GetBlockType())
{
case E_BLOCK_WALL_BANNER:
case E_BLOCK_STANDING_BANNER:
{
auto & BannerEntity = static_cast<const cBannerEntity &>(a_BlockEntity);
Writer.AddInt("x", BannerEntity.GetPosX());
Writer.AddInt("y", BannerEntity.GetPosY());
Writer.AddInt("z", BannerEntity.GetPosZ());
Writer.AddString("id", "Banner");
Writer.AddInt("Base", static_cast<Int32>(BannerEntity.GetBaseColor()));
break;
}
case E_BLOCK_BEACON:
{
auto & BeaconEntity = static_cast<const cBeaconEntity &>(a_BlockEntity);

View File

@ -30,6 +30,7 @@ Implements the 1.11 protocol classes:
#include "../Mobs/IncludeAllMonsters.h"
#include "../BlockEntities/BannerEntity.h"
#include "../BlockEntities/BeaconEntity.h"
#include "../BlockEntities/BedEntity.h"
#include "../BlockEntities/CommandBlockEntity.h"
@ -416,6 +417,18 @@ void cProtocol_1_11_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity
switch (a_BlockEntity.GetBlockType())
{
case E_BLOCK_WALL_BANNER:
case E_BLOCK_STANDING_BANNER:
{
auto & BannerEntity = static_cast<const cBannerEntity &>(a_BlockEntity);
Writer.AddInt("x", BannerEntity.GetPosX());
Writer.AddInt("y", BannerEntity.GetPosY());
Writer.AddInt("z", BannerEntity.GetPosZ());
Writer.AddString("id", "Banner");
Writer.AddInt("Base", static_cast<Int32>(BannerEntity.GetBaseColor()));
break;
}
case E_BLOCK_BEACON:
{
auto & BeaconEntity = static_cast<const cBeaconEntity &>(a_BlockEntity);

View File

@ -42,6 +42,7 @@ Implements the 1.8 protocol classes:
#include "../UI/Window.h"
#include "../UI/HorseWindow.h"
#include "../BlockEntities/BannerEntity.h"
#include "../BlockEntities/BeaconEntity.h"
#include "../BlockEntities/CommandBlockEntity.h"
#include "../BlockEntities/EnchantingTableEntity.h"
@ -1603,13 +1604,14 @@ void cProtocol_1_8_0::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
Byte Action = 0;
switch (a_BlockEntity.GetBlockType())
{
case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing
case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text
case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity
case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity
case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot
case E_BLOCK_BED: Action = 11; break; // Update bed color
case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing
case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text
case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity
case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity
case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot
case E_BLOCK_WALL_BANNER:
case E_BLOCK_STANDING_BANNER: Action = 6; break; // Update Banner
case E_BLOCK_BED: Action = 11; break; // Update bed color
case E_BLOCK_ENCHANTMENT_TABLE: Action = 0; break; // The ones with a action of 0 is just a workaround to send the block entities to a client.
case E_BLOCK_END_PORTAL: Action = 0; break; // Todo: 18.09.2020 - remove this when block entities are transmitted in the ChunkData packet - 12xx12
@ -3217,6 +3219,18 @@ void cProtocol_1_8_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity &
switch (a_BlockEntity.GetBlockType())
{
case E_BLOCK_WALL_BANNER:
case E_BLOCK_STANDING_BANNER:
{
auto & BannerEntity = static_cast<const cBannerEntity &>(a_BlockEntity);
Writer.AddInt("x", BannerEntity.GetPosX());
Writer.AddInt("y", BannerEntity.GetPosY());
Writer.AddInt("z", BannerEntity.GetPosZ());
Writer.AddString("id", "Banner");
Writer.AddInt("Base", static_cast<Int32>(BannerEntity.GetBaseColor()));
break;
}
case E_BLOCK_BEACON:
{
auto & BeaconEntity = static_cast<const cBeaconEntity &>(a_BlockEntity);

View File

@ -45,6 +45,7 @@ Implements the 1.9 protocol classes:
#include "../Mobs/IncludeAllMonsters.h"
#include "../UI/HorseWindow.h"
#include "../BlockEntities/BannerEntity.h"
#include "../BlockEntities/BeaconEntity.h"
#include "../BlockEntities/CommandBlockEntity.h"
#include "../BlockEntities/MobHeadEntity.h"
@ -1625,6 +1626,18 @@ void cProtocol_1_9_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity &
switch (a_BlockEntity.GetBlockType())
{
case E_BLOCK_WALL_BANNER:
case E_BLOCK_STANDING_BANNER:
{
auto & BannerEntity = static_cast<const cBannerEntity &>(a_BlockEntity);
Writer.AddInt("x", BannerEntity.GetPosX());
Writer.AddInt("y", BannerEntity.GetPosY());
Writer.AddInt("z", BannerEntity.GetPosZ());
Writer.AddString("id", "Banner");
Writer.AddInt("Base", static_cast<Int32>(BannerEntity.GetBaseColor()));
break;
}
case E_BLOCK_BEACON:
{
auto & BeaconEntity = static_cast<const cBeaconEntity &>(a_BlockEntity);

View File

@ -12,6 +12,7 @@
#include "../UUID.h"
#include "FastNBT.h"
#include "../BlockEntities/BannerEntity.h"
#include "../BlockEntities/BeaconEntity.h"
#include "../BlockEntities/BedEntity.h"
#include "../BlockEntities/BrewingstandEntity.h"
@ -205,6 +206,11 @@ public:
// Add tile-entity into NBT:
switch (a_Entity->GetBlockType())
{
// Banners:
case E_BLOCK_STANDING_BANNER:
case E_BLOCK_WALL_BANNER: AddBannerEntity (static_cast<cBannerEntity *> (a_Entity)); break;
// Others:
case E_BLOCK_BEACON: AddBeaconEntity (static_cast<cBeaconEntity *> (a_Entity)); break;
case E_BLOCK_BED: AddBedEntity (static_cast<cBedEntity *> (a_Entity)); break;
case E_BLOCK_BREWING_STAND: AddBrewingstandEntity (static_cast<cBrewingstandEntity *> (a_Entity)); break;
@ -226,7 +232,6 @@ public:
case E_BLOCK_SIGN_POST: AddSignEntity (static_cast<cSignEntity *> (a_Entity)); break;
case E_BLOCK_TRAPPED_CHEST: AddChestEntity (static_cast<cChestEntity *> (a_Entity), a_Entity->GetBlockType()); break;
case E_BLOCK_WALLSIGN: AddSignEntity (static_cast<cSignEntity *> (a_Entity)); break;
default:
{
ASSERT(!"Unhandled block entity saved into Anvil");
@ -366,6 +371,18 @@ public:
void AddBannerEntity(cBannerEntity * a_Entity)
{
mWriter.BeginCompound("");
AddBasicTileEntity(a_Entity,"Banner");
mWriter.AddInt("Base", static_cast<int>(a_Entity->GetBaseColor()));
mWriter.EndCompound();
}
void AddBeaconEntity(cBeaconEntity * a_Entity)
{
mWriter.BeginCompound("");

View File

@ -140,7 +140,7 @@ std::string_view NamespaceSerializer::From(const Statistic a_ID)
std::string_view NamespaceSerializer::From(eMonsterType a_ID)
std::string_view NamespaceSerializer::From(const eMonsterType a_ID)
{
switch (a_ID)
{
@ -222,6 +222,58 @@ std::string_view NamespaceSerializer::From(eMonsterType a_ID)
std::string_view NamespaceSerializer::From(const BannerPattern a_Pattern)
{
switch (a_Pattern)
{
case BannerPattern::BottomStripe: return "bs";
case BannerPattern::TopStripe: return "ts";
case BannerPattern::LeftStripe: return "ls";
case BannerPattern::RightStripe: return "rs";
case BannerPattern::CenterStripeVertical: return "cs";
case BannerPattern::MiddleStripeHorizontal: return "ms";
case BannerPattern::DownRightStripe: return "drs";
case BannerPattern::DownLeftStripe: return "dls";
case BannerPattern::SmallVerticalStripes: return "ss";
case BannerPattern::DiagonalCross: return "cr";
case BannerPattern::SquareCross: return "sc";
case BannerPattern::LeftOfDiagonal: return "ld";
case BannerPattern::RightOfUpsideDownDiagonal: return "rud";
case BannerPattern::LeftOfUpsideDownDiagonal: return "lud";
case BannerPattern::RightOfDiagonal: return "rd";
case BannerPattern::VerticalHalfLeft: return "vh";
case BannerPattern::VerticalHalfRight: return "vhr";
case BannerPattern::HorizontalHalfTop: return "hh";
case BannerPattern::HorizontalHalfBottom: return "hhb";
case BannerPattern::BottomLeftCorner: return "bl";
case BannerPattern::BottomRightCorner: return "br";
case BannerPattern::TopLeftCorner: return "tl";
case BannerPattern::TopRightCorner: return "tr";
case BannerPattern::BottomTriangle: return "bt";
case BannerPattern::TopTriangle: return "tt";
case BannerPattern::BottomTriangleSawtooth: return "bts";
case BannerPattern::TopTriangleSawtooth: return "tts";
case BannerPattern::MiddleCircle: return "mc";
case BannerPattern::MiddleRhombus: return "mr";
case BannerPattern::Border: return "bo";
case BannerPattern::CurlyBorder: return "cbo";
case BannerPattern::Brick: return "bri";
case BannerPattern::Gradient: return "gra";
case BannerPattern::GradientUpsideDown: return "gru";
case BannerPattern::Creeper: return "cre";
case BannerPattern::Skull: return "sku";
case BannerPattern::Flower: return "flo";
case BannerPattern::Mojang: return "moj";
case BannerPattern::Globe: return "glb";
case BannerPattern::Piglin: return "pig";
}
UNREACHABLE("Unsupported banner pattern");
}
Statistic NamespaceSerializer::ToCustomStatistic(const std::string_view ID)
{
static const std::unordered_map<std::string_view, Statistic> CustomStatistics

View File

@ -1,7 +1,8 @@
#pragma once
#include "../Registries/Statistics.h"
#include "../Mobs/MonsterTypes.h"
#include "Defines.h"
#include "Mobs/MonsterTypes.h"
#include "Registries/Statistics.h"
namespace NamespaceSerializer
{
@ -16,6 +17,7 @@ namespace NamespaceSerializer
std::string_view From(Statistic a_ID);
std::string_view From(eMonsterType a_ID);
std::string_view From(BannerPattern a_ID);
Statistic ToCustomStatistic(std::string_view a_ID);
eMonsterType ToMonsterType(std::string_view a_ID);

View File

@ -19,6 +19,7 @@
#include "../BlockType.h"
#include "../JsonUtils.h"
#include "../BlockEntities/BannerEntity.h"
#include "../BlockEntities/BeaconEntity.h"
#include "../BlockEntities/BedEntity.h"
#include "../BlockEntities/BrewingstandEntity.h"
@ -635,7 +636,11 @@ OwnedBlockEntity cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int
// Load the specific BlockEntity type:
switch (a_BlockType)
{
// Specific entity loaders:
// Banners:
case E_BLOCK_STANDING_BANNER:
case E_BLOCK_WALL_BANNER: return LoadBannerFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos);
// Others:
case E_BLOCK_BEACON: return LoadBeaconFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos);
case E_BLOCK_BED: return LoadBedFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos);
case E_BLOCK_BREWING_STAND: return LoadBrewingstandFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos);
@ -657,7 +662,6 @@ OwnedBlockEntity cWSSAnvil::LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int
case E_BLOCK_SIGN_POST: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos);
case E_BLOCK_TRAPPED_CHEST: return LoadChestFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos);
case E_BLOCK_WALLSIGN: return LoadSignFromNBT (a_NBT, a_Tag, a_BlockType, a_BlockMeta, a_Pos);
default:
{
// All the other blocktypes should have no entities assigned to them. Report an error:
@ -889,6 +893,29 @@ bool cWSSAnvil::CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, con
OwnedBlockEntity cWSSAnvil::LoadBannerFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
{
static const AStringVector expectedTypes({"Banner", "minecraft:standingbanner","minecraft:wallbanner"});
if (!CheckBlockEntityType(a_NBT, a_TagIdx, expectedTypes, a_Pos))
{
return nullptr;
}
// Reads base color from NBT
int CurrentLine = a_NBT.FindChildByName(a_TagIdx, "Base");
if (CurrentLine >= 0)
{
const auto Color = static_cast<unsigned char>(a_NBT.GetInt(CurrentLine));
return std::make_unique<cBannerEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World, Color);
}
return nullptr;
}
OwnedBlockEntity cWSSAnvil::LoadBeaconFromNBT(const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
{
// Check if the data has a proper type:

1
src/WorldStorage/WSSAnvil.h Executable file → Normal file
View File

@ -157,6 +157,7 @@ protected:
The coordinates are used only for the log message. */
bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const AStringVector & a_ExpectedTypes, Vector3i a_Pos);
OwnedBlockEntity LoadBannerFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos);
OwnedBlockEntity LoadBeaconFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos);
OwnedBlockEntity LoadBedFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos);
OwnedBlockEntity LoadBrewingstandFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos);