Implemented custom names and lore
+ Added custom names and lore + Added saving and loading + Added writing and parsing of NBT
This commit is contained in:
parent
3c31f2d8d8
commit
fcafd5a2e0
32
src/Item.cpp
32
src/Item.cpp
@ -91,28 +91,6 @@ bool cItem::DamageItem(short a_Amount)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cItem::IsStackableWith(const cItem & a_OtherStack) const
|
|
||||||
{
|
|
||||||
if (a_OtherStack.m_ItemType != m_ItemType)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (a_OtherStack.m_ItemDamage != m_ItemDamage)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (a_OtherStack.m_Enchantments != m_Enchantments)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cItem::IsFullStack(void) const
|
bool cItem::IsFullStack(void) const
|
||||||
{
|
{
|
||||||
return (m_ItemCount >= ItemHandler(m_ItemType)->GetMaxStackSize());
|
return (m_ItemCount >= ItemHandler(m_ItemType)->GetMaxStackSize());
|
||||||
@ -153,6 +131,14 @@ void cItem::GetJson(Json::Value & a_OutValue) const
|
|||||||
{
|
{
|
||||||
a_OutValue["ench"] = Enchantments;
|
a_OutValue["ench"] = Enchantments;
|
||||||
}
|
}
|
||||||
|
if (!IsCustomNameEmpty())
|
||||||
|
{
|
||||||
|
a_OutValue["Name"] = m_CustomName;
|
||||||
|
}
|
||||||
|
if (!IsLoreEmpty())
|
||||||
|
{
|
||||||
|
a_OutValue["Lore"] = m_Lore;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +155,8 @@ void cItem::FromJson(const Json::Value & a_Value)
|
|||||||
m_ItemDamage = (short)a_Value.get("Health", -1 ).asInt();
|
m_ItemDamage = (short)a_Value.get("Health", -1 ).asInt();
|
||||||
m_Enchantments.Clear();
|
m_Enchantments.Clear();
|
||||||
m_Enchantments.AddFromString(a_Value.get("ench", "").asString());
|
m_Enchantments.AddFromString(a_Value.get("ench", "").asString());
|
||||||
|
m_CustomName = a_Value.get("Name", "").asString();
|
||||||
|
m_Lore = a_Value.get("Lore", "").asString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
src/Item.h
43
src/Item.h
@ -36,7 +36,9 @@ public:
|
|||||||
cItem(void) :
|
cItem(void) :
|
||||||
m_ItemType(E_ITEM_EMPTY),
|
m_ItemType(E_ITEM_EMPTY),
|
||||||
m_ItemCount(0),
|
m_ItemCount(0),
|
||||||
m_ItemDamage(0)
|
m_ItemDamage(0),
|
||||||
|
m_CustomName(""),
|
||||||
|
m_Lore("")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,12 +48,16 @@ public:
|
|||||||
short a_ItemType,
|
short a_ItemType,
|
||||||
char a_ItemCount = 1,
|
char a_ItemCount = 1,
|
||||||
short a_ItemDamage = 0,
|
short a_ItemDamage = 0,
|
||||||
const AString & a_Enchantments = ""
|
const AString & a_Enchantments = "",
|
||||||
|
const AString & a_CustomName = "",
|
||||||
|
const AString & a_Lore = ""
|
||||||
) :
|
) :
|
||||||
m_ItemType (a_ItemType),
|
m_ItemType (a_ItemType),
|
||||||
m_ItemCount (a_ItemCount),
|
m_ItemCount (a_ItemCount),
|
||||||
m_ItemDamage (a_ItemDamage),
|
m_ItemDamage (a_ItemDamage),
|
||||||
m_Enchantments(a_Enchantments)
|
m_Enchantments(a_Enchantments),
|
||||||
|
m_CustomName (a_CustomName),
|
||||||
|
m_Lore (a_Lore)
|
||||||
{
|
{
|
||||||
if (!IsValidItem(m_ItemType))
|
if (!IsValidItem(m_ItemType))
|
||||||
{
|
{
|
||||||
@ -69,7 +75,9 @@ public:
|
|||||||
m_ItemType (a_CopyFrom.m_ItemType),
|
m_ItemType (a_CopyFrom.m_ItemType),
|
||||||
m_ItemCount (a_CopyFrom.m_ItemCount),
|
m_ItemCount (a_CopyFrom.m_ItemCount),
|
||||||
m_ItemDamage (a_CopyFrom.m_ItemDamage),
|
m_ItemDamage (a_CopyFrom.m_ItemDamage),
|
||||||
m_Enchantments(a_CopyFrom.m_Enchantments)
|
m_Enchantments(a_CopyFrom.m_Enchantments),
|
||||||
|
m_CustomName (a_CopyFrom.m_CustomName),
|
||||||
|
m_Lore (a_CopyFrom.m_Lore)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +88,8 @@ public:
|
|||||||
m_ItemCount = 0;
|
m_ItemCount = 0;
|
||||||
m_ItemDamage = 0;
|
m_ItemDamage = 0;
|
||||||
m_Enchantments.Clear();
|
m_Enchantments.Clear();
|
||||||
|
m_CustomName = "";
|
||||||
|
m_Lore = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -96,13 +106,16 @@ public:
|
|||||||
return ((m_ItemType <= 0) || (m_ItemCount <= 0));
|
return ((m_ItemType <= 0) || (m_ItemCount <= 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if this itemstack can stack with the specified stack (types match, enchantments etc.) ItemCounts are ignored!
|
||||||
|
*/
|
||||||
bool IsEqual(const cItem & a_Item) const
|
bool IsEqual(const cItem & a_Item) const
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
IsSameType(a_Item) &&
|
IsSameType(a_Item) &&
|
||||||
(m_ItemDamage == a_Item.m_ItemDamage) &&
|
(m_ItemDamage == a_Item.m_ItemDamage) &&
|
||||||
(m_Enchantments == a_Item.m_Enchantments)
|
(m_Enchantments == a_Item.m_Enchantments) &&
|
||||||
|
(m_CustomName == a_Item.m_CustomName) &&
|
||||||
|
(m_Lore == a_Item.m_Lore)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +126,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsBothNameAndLoreEmpty(void) const
|
||||||
|
{
|
||||||
|
return (m_CustomName.empty() && m_Lore.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsCustomNameEmpty(void) const { return (m_CustomName.empty()); }
|
||||||
|
bool IsLoreEmpty(void) const { return (m_Lore.empty()); }
|
||||||
|
|
||||||
|
|
||||||
/// Returns a copy of this item with m_ItemCount set to 1. Useful to preserve enchantments etc. on stacked items
|
/// Returns a copy of this item with m_ItemCount set to 1. Useful to preserve enchantments etc. on stacked items
|
||||||
cItem CopyOne(void) const;
|
cItem CopyOne(void) const;
|
||||||
|
|
||||||
@ -127,8 +150,10 @@ public:
|
|||||||
|
|
||||||
inline bool IsDamageable(void) const { return (GetMaxDamage() > 0); }
|
inline bool IsDamageable(void) const { return (GetMaxDamage() > 0); }
|
||||||
|
|
||||||
/// Returns true if this itemstack can stack with the specified stack (types match, enchantments etc.) ItemCounts are ignored!
|
/* Returns true if this itemstack can stack with the specified stack (types match, enchantments etc.) ItemCounts are ignored!
|
||||||
bool IsStackableWith(const cItem & a_OtherStack) const;
|
THIS FUNCTION IS OBSOLETE; USE ISEQUAL INSTEAD
|
||||||
|
*/
|
||||||
|
OBSOLETE bool IsStackableWith(const cItem & a_OtherStack) const { return IsEqual(a_OtherStack); }
|
||||||
|
|
||||||
/// Returns true if the item is stacked up to its maximum stacking.
|
/// Returns true if the item is stacked up to its maximum stacking.
|
||||||
bool IsFullStack(void) const;
|
bool IsFullStack(void) const;
|
||||||
@ -155,6 +180,8 @@ public:
|
|||||||
short m_ItemType;
|
short m_ItemType;
|
||||||
char m_ItemCount;
|
char m_ItemCount;
|
||||||
short m_ItemDamage;
|
short m_ItemDamage;
|
||||||
|
AString m_CustomName;
|
||||||
|
AString m_Lore;
|
||||||
cEnchantments m_Enchantments;
|
cEnchantments m_Enchantments;
|
||||||
};
|
};
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
@ -1647,7 +1647,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load enchantments from the NBT:
|
// Load enchantments and custom display names from the NBT data:
|
||||||
for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag))
|
for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag))
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
@ -1660,6 +1660,27 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
|
|||||||
{
|
{
|
||||||
a_Item.m_Enchantments.ParseFromNBT(NBT, tag);
|
a_Item.m_Enchantments.ParseFromNBT(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))
|
||||||
|
{
|
||||||
|
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\n", 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1711,16 +1732,45 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
|
|||||||
WriteByte (a_Item.m_ItemCount);
|
WriteByte (a_Item.m_ItemCount);
|
||||||
WriteShort(a_Item.m_ItemDamage);
|
WriteShort(a_Item.m_ItemDamage);
|
||||||
|
|
||||||
if (a_Item.m_Enchantments.IsEmpty())
|
if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty())
|
||||||
{
|
{
|
||||||
WriteShort(-1);
|
WriteShort(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the enchantments:
|
// Send the enchantments and custom names:
|
||||||
cFastNBTWriter Writer;
|
cFastNBTWriter Writer;
|
||||||
|
if (!a_Item.m_Enchantments.IsEmpty())
|
||||||
|
{
|
||||||
const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
|
const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
|
||||||
a_Item.m_Enchantments.WriteToNBTCompound(Writer, TagName);
|
a_Item.m_Enchantments.WriteToNBTCompound(Writer, TagName);
|
||||||
|
}
|
||||||
|
if (!a_Item.IsBothNameAndLoreEmpty())
|
||||||
|
{
|
||||||
|
Writer.BeginCompound("display");
|
||||||
|
if (!a_Item.IsCustomNameEmpty())
|
||||||
|
{
|
||||||
|
Writer.AddString("Name", a_Item.m_CustomName.c_str());
|
||||||
|
}
|
||||||
|
if (!a_Item.IsLoreEmpty())
|
||||||
|
{
|
||||||
|
Writer.BeginList("Lore", TAG_String);
|
||||||
|
|
||||||
|
AStringVector Decls = StringSplit(a_Item.m_Lore, "\n");
|
||||||
|
for (AStringVector::const_iterator itr = Decls.begin(), end = Decls.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
if (itr->empty())
|
||||||
|
{
|
||||||
|
// The decl is empty (two \ns), ignore
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Writer.AddString("", itr->c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
Writer.EndList();
|
||||||
|
}
|
||||||
|
Writer.EndCompound();
|
||||||
|
}
|
||||||
Writer.Finish();
|
Writer.Finish();
|
||||||
AString Compressed;
|
AString Compressed;
|
||||||
CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
|
CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
|
||||||
|
@ -89,6 +89,9 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA
|
|||||||
Slot.m_ItemCount -= DraggingItem.m_ItemCount;
|
Slot.m_ItemCount -= DraggingItem.m_ItemCount;
|
||||||
DraggingItem.m_ItemType = Slot.m_ItemType;
|
DraggingItem.m_ItemType = Slot.m_ItemType;
|
||||||
DraggingItem.m_ItemDamage = Slot.m_ItemDamage;
|
DraggingItem.m_ItemDamage = Slot.m_ItemDamage;
|
||||||
|
DraggingItem.m_Enchantments = Slot.m_Enchantments;
|
||||||
|
DraggingItem.m_CustomName = Slot.m_CustomName;
|
||||||
|
DraggingItem.m_Lore = Slot.m_Lore;
|
||||||
|
|
||||||
if (Slot.m_ItemCount <= 0)
|
if (Slot.m_ItemCount <= 0)
|
||||||
{
|
{
|
||||||
@ -105,6 +108,10 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA
|
|||||||
Slot.m_ItemCount++;
|
Slot.m_ItemCount++;
|
||||||
Slot.m_ItemDamage = DraggingItem.m_ItemDamage;
|
Slot.m_ItemDamage = DraggingItem.m_ItemDamage;
|
||||||
DraggingItem.m_ItemCount--;
|
DraggingItem.m_ItemCount--;
|
||||||
|
|
||||||
|
Slot.m_Enchantments = DraggingItem.m_Enchantments;
|
||||||
|
Slot.m_CustomName = DraggingItem.m_CustomName;
|
||||||
|
Slot.m_Lore = DraggingItem.m_Lore;
|
||||||
}
|
}
|
||||||
if (DraggingItem.m_ItemCount <= 0)
|
if (DraggingItem.m_ItemCount <= 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user