1
0
Fork 0

Add repair cost to cItem, add custom name to NBTChunkSerializer and fix anvil bugs.

This commit is contained in:
Howaner 2014-05-07 12:30:30 +02:00
parent 954b59d6f4
commit d6cb6e0423
8 changed files with 124 additions and 56 deletions

View File

@ -151,6 +151,8 @@ void cItem::GetJson(Json::Value & a_OutValue) const
a_OutValue["Colours"] = m_FireworkItem.ColoursToString(m_FireworkItem);
a_OutValue["FadeColours"] = m_FireworkItem.FadeColoursToString(m_FireworkItem);
}
a_OutValue["RepairCost"] = m_RepairCost;
}
}
@ -179,6 +181,8 @@ void cItem::FromJson(const Json::Value & a_Value)
m_FireworkItem.ColoursFromString(a_Value.get("Colours", "").asString(), m_FireworkItem);
m_FireworkItem.FadeColoursFromString(a_Value.get("FadeColours", "").asString(), m_FireworkItem);
}
m_RepairCost = (unsigned short)a_Value.get("RepairCost", 0).asInt();
}
}

View File

@ -40,6 +40,7 @@ public:
m_ItemDamage(0),
m_CustomName(""),
m_Lore(""),
m_RepairCost(0),
m_FireworkItem()
{
}
@ -60,6 +61,7 @@ public:
m_Enchantments(a_Enchantments),
m_CustomName (a_CustomName),
m_Lore (a_Lore),
m_RepairCost (0),
m_FireworkItem()
{
if (!IsValidItem(m_ItemType))
@ -85,7 +87,8 @@ public:
m_Enchantments(a_CopyFrom.m_Enchantments),
m_CustomName (a_CopyFrom.m_CustomName),
m_Lore (a_CopyFrom.m_Lore),
m_FireworkItem(a_CopyFrom.m_FireworkItem)
m_FireworkItem(a_CopyFrom.m_FireworkItem),
m_RepairCost (a_CopyFrom.m_RepairCost)
{
}
@ -100,6 +103,7 @@ public:
m_Enchantments.Clear();
m_CustomName = "";
m_Lore = "";
m_RepairCost = 0;
m_FireworkItem.EmptyData();
}
@ -109,6 +113,7 @@ public:
m_ItemType = E_ITEM_EMPTY;
m_ItemCount = 0;
m_ItemDamage = 0;
m_RepairCost = 0;
}
@ -190,14 +195,15 @@ public:
// tolua_begin
short m_ItemType;
char m_ItemCount;
short m_ItemDamage;
cEnchantments m_Enchantments;
AString m_CustomName;
AString m_Lore;
short m_ItemType;
char m_ItemCount;
short m_ItemDamage;
cEnchantments m_Enchantments;
AString m_CustomName;
AString m_Lore;
cFireworkItem m_FireworkItem;
cFireworkItem m_FireworkItem;
UInt16 m_RepairCost;
};
// tolua_end

View File

@ -521,15 +521,6 @@ bool cItemHandler::CanRepairWithRawMaterial(short a_ItemType)
int cItemHandler::GetRepairCost(void)
{
return 0;
}
bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType)
{
UNUSED(a_BlockType);

View File

@ -88,9 +88,6 @@ public:
/** Can the anvil repair this item, when a_Item is the second input? */
virtual bool CanRepairWithRawMaterial(short a_ItemType);
/** Get the repair cost from the item, or 0 if the item hasn't repair cost. */
virtual int GetRepairCost(void);
/** Called before a block is placed into a world.
The handler should return true to allow placement, false to refuse.
Also, the handler should set a_BlockType and a_BlockMeta to correct values for the newly placed block.

View File

@ -2278,6 +2278,13 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
}
break;
}
case TAG_Int:
{
if (TagName == "RepairCost")
{
a_Item.m_RepairCost = (UInt16)NBT.GetInt(tag);
}
}
default: LOGD("Unimplemented NBT data when parsing!"); break;
}
}
@ -2451,6 +2458,10 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
// Send the enchantments and custom names:
cFastNBTWriter Writer;
if (a_Item.m_RepairCost != 0)
{
Writer.AddInt("RepairCost", (Int32)a_Item.m_RepairCost);
}
if (!a_Item.m_Enchantments.IsEmpty())
{
const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";

View File

@ -866,16 +866,19 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player)
m_MaximumCost = 0;
m_StackSizeToBeUsedInRepair = 0;
int RepairCost = cItemHandler::GetItemHandler(Input)->GetRepairCost();
UInt16 RepairCost = Input.m_RepairCost;
int NeedExp = 0;
bool IsEnchantBook = false;
if (!SecondInput.IsEmpty())
{
RepairCost += cItemHandler::GetItemHandler(SecondInput)->GetRepairCost();
IsEnchantBook = (SecondInput.m_ItemType == E_ITEM_ENCHANTED_BOOK);
RepairCost += SecondInput.m_RepairCost;
if (Input.IsDamageable() && cItemHandler::GetItemHandler(Input)->CanRepairWithRawMaterial(SecondInput.m_ItemType))
{
// Tool and armor repair with special item (iron / gold / diamond / ...)
int DamageDiff = std::min((int)Input.m_ItemDamage, (int)Input.GetMaxDamage() / 4);
if (DamageDiff < 0)
if (DamageDiff <= 0)
{
// No enchantment
Output.Empty();
@ -898,7 +901,7 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player)
else
{
// Tool and armor repair with two tools / armors
if (!Input.IsSameType(SecondInput) || !Input.IsDamageable())
if (!IsEnchantBook && (!Input.IsSameType(SecondInput) || !Input.IsDamageable()))
{
// No enchantment
Output.Empty();
@ -907,20 +910,23 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player)
return;
}
int FirstDamageDiff = Input.GetMaxDamage() - Input.m_ItemDamage;
int SecondDamageDiff = SecondInput.GetMaxDamage() - SecondInput.m_ItemDamage;
int Damage = SecondDamageDiff + Input.GetMaxDamage() * 12 / 100;
int NewItemDamage = Input.GetMaxDamage() - (FirstDamageDiff + Damage);
if (NewItemDamage > 0)
if ((Input.GetMaxDamage() > 0) && !IsEnchantBook)
{
NewItemDamage = 0;
}
int FirstDamageDiff = Input.GetMaxDamage() - Input.m_ItemDamage;
int SecondDamageDiff = SecondInput.GetMaxDamage() - SecondInput.m_ItemDamage;
int Damage = SecondDamageDiff + Input.GetMaxDamage() * 12 / 100;
if (NewItemDamage < Input.m_ItemDamage)
{
Input.m_ItemDamage = NewItemDamage;
NeedExp += std::max(1, Damage / 100);
int NewItemDamage = Input.GetMaxDamage() - (FirstDamageDiff + Damage);
if (NewItemDamage > 0)
{
NewItemDamage = 0;
}
if (NewItemDamage < Input.m_ItemDamage)
{
Input.m_ItemDamage = NewItemDamage;
NeedExp += std::max(1, Damage / 100);
}
}
// TODO: Add enchantments.
@ -934,7 +940,7 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player)
// Remove custom name
if (!Input.m_CustomName.empty())
{
NameChangeExp = (Input.IsDamageable()) ? 4 : (Input.m_ItemCount * 5);
NameChangeExp = (Input.IsDamageable()) ? 7 : (Input.m_ItemCount * 5);
NeedExp += NameChangeExp;
Input.m_CustomName = "";
}
@ -942,7 +948,7 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player)
else if (RepairedItemName != Input.m_CustomName)
{
// Change custom name
NameChangeExp = (Input.IsDamageable()) ? 4 : (Input.m_ItemCount * 5);
NameChangeExp = (Input.IsDamageable()) ? 7 : (Input.m_ItemCount * 5);
NeedExp += NameChangeExp;
if (!Input.m_CustomName.empty())
@ -962,7 +968,7 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player)
Input.Empty();
}
if (NameChangeExp == NeedExp && NameChangeExp > 0 && m_MaximumCost >= 40)
if ((NameChangeExp == NeedExp) && (NameChangeExp > 0) && (m_MaximumCost >= 40))
{
m_MaximumCost = 39;
}
@ -971,17 +977,23 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player)
Input.Empty();
}
/* TODO: Add repair cost to cItem and not ItemHandler. This is required for this function!
if (!Input.IsEmpty())
{
RepairCost = max(cItemHandler::GetItemHandler(Input)->GetRepairCost(), cItemHandler::GetItemHandler(SecondInput)->GetRepairCost());
RepairCost = std::max(Input.m_RepairCost, SecondInput.m_RepairCost);
if (!Input.m_CustomName.empty())
{
RepairCost -= 9;
if (RepairCost < 9)
{
RepairCost = 0;
}
else
{
RepairCost -= 9;
}
}
RepairCost = max(RepairCost, 0);
RepairCost += 2;
}*/
Input.m_RepairCost = RepairCost;
}
SetSlot(2, a_Player, Input);
m_ParentWindow.SetProperty(0, m_MaximumCost, a_Player);

View File

@ -88,23 +88,48 @@ void cNBTChunkSerializer::Finish(void)
void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AString & a_CompoundName)
{
m_Writer.BeginCompound(a_CompoundName);
m_Writer.AddShort("id", (short)(a_Item.m_ItemType));
m_Writer.AddShort("Damage", a_Item.m_ItemDamage);
m_Writer.AddByte ("Count", a_Item.m_ItemCount);
m_Writer.AddShort("id", (short)(a_Item.m_ItemType));
m_Writer.AddShort("Damage", a_Item.m_ItemDamage);
m_Writer.AddByte ("Count", a_Item.m_ItemCount);
if (a_Slot >= 0)
{
m_Writer.AddByte ("Slot", (unsigned char)a_Slot);
}
// Write the enchantments:
if (!a_Item.m_Enchantments.IsEmpty() || ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)))
// Write the tag compound (for enchantment, firework, custom name and repair cost):
if (
(!a_Item.m_Enchantments.IsEmpty()) ||
((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) ||
(a_Item.m_RepairCost > 0) ||
(a_Item.m_CustomName != "") ||
(a_Item.m_Lore != "")
)
{
m_Writer.BeginCompound("tag");
if (a_Item.m_RepairCost > 0)
{
m_Writer.AddInt("RepairCost", (Int32)a_Item.m_RepairCost);
}
if ((a_Item.m_CustomName != "") || (a_Item.m_Lore != ""))
{
m_Writer.BeginCompound("display");
if (a_Item.m_CustomName != "")
{
m_Writer.AddString("Name", a_Item.m_CustomName);
}
if (a_Item.m_Lore != "")
{
m_Writer.AddString("Lore", a_Item.m_Lore);
}
m_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, 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";

View File

@ -645,18 +645,16 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_
}
int Damage = a_NBT.FindChildByName(a_TagIdx, "Damage");
if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short))
if ((Damage > 0) && (a_NBT.GetType(Damage) == TAG_Short))
{
return false;
a_Item.m_ItemDamage = a_NBT.GetShort(Damage);
}
a_Item.m_ItemDamage = a_NBT.GetShort(Damage);
int Count = a_NBT.FindChildByName(a_TagIdx, "Count");
if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte))
if ((Count > 0) && (a_NBT.GetType(Count) == TAG_Byte))
{
return false;
a_Item.m_ItemCount = a_NBT.GetByte(Count);
}
a_Item.m_ItemCount = a_NBT.GetByte(Count);
// Find the "tag" tag, used for enchantments and other extra data
int TagTag = a_NBT.FindChildByName(a_TagIdx, "tag");
@ -666,6 +664,29 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_
return true;
}
// Load repair cost:
int RepairCost = a_NBT.FindChildByName(TagTag, "RepairCost");
if ((RepairCost > 0) && (a_NBT.GetType(RepairCost) == TAG_Int))
{
a_Item.m_RepairCost = (UInt16)a_NBT.GetInt(RepairCost);
}
// Load display name:
int DisplayTag = a_NBT.FindChildByName(TagTag, "display");
if (DisplayTag > 0)
{
int DisplayName = a_NBT.FindChildByName(DisplayTag, "Name");
if ((DisplayName > 0) && (a_NBT.GetType(DisplayName) == TAG_String))
{
a_Item.m_CustomName = a_NBT.GetString(DisplayName);
}
int Lore = a_NBT.FindChildByName(DisplayTag, "Lore");
if ((Lore > 0) && (a_NBT.GetType(Lore) == TAG_String))
{
a_Item.m_Lore = a_NBT.GetString(Lore);
}
}
// Load enchantments:
const char * EnchName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
int EnchTag = a_NBT.FindChildByName(TagTag, EnchName);
@ -674,6 +695,7 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_
EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, a_NBT, EnchTag);
}
// Load firework data:
int FireworksTag = a_NBT.FindChildByName(TagTag, ((a_Item.m_ItemType == E_ITEM_FIREWORK_STAR) ? "Fireworks" : "Explosion"));
if (EnchTag > 0)
{