e14ddff1c0
Created a new class cEnchantmentSerializer to serilize Enchantments to NBT. This breaks a dependecy chain between cChunkGenerator and cWorld. cEnchantmentSerializer is seperate from NBTWriter as it needs to access private members of cEnchantments so having it seperate reduces the spread of the frein modifier
221 lines
4.6 KiB
C++
221 lines
4.6 KiB
C++
// Enchantments.cpp
|
|
|
|
// Implements the cEnchantments class representing a storage for item enchantments and stored-enchantments
|
|
|
|
#include "Globals.h"
|
|
#include "Enchantments.h"
|
|
#include "WorldStorage/FastNBT.h"
|
|
|
|
|
|
|
|
|
|
|
|
cEnchantments::cEnchantments(void)
|
|
{
|
|
// Nothing needed yet, but the constructor needs to be declared and impemented in order to be usable
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cEnchantments::cEnchantments(const AString & a_StringSpec)
|
|
{
|
|
AddFromString(a_StringSpec);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cEnchantments::AddFromString(const AString & a_StringSpec)
|
|
{
|
|
// Add enchantments in the stringspec; if a specified enchantment already exists, overwrites it
|
|
|
|
// Split the StringSpec into separate declarations, each in the form "id=lvl":
|
|
AStringVector Decls = StringSplit(a_StringSpec, ";");
|
|
for (AStringVector::const_iterator itr = Decls.begin(), end = Decls.end(); itr != end; ++itr)
|
|
{
|
|
// Split each declaration into the id and lvl part:
|
|
if (itr->empty())
|
|
{
|
|
// The decl is empty (may happen if there's an extra semicolon at the end), ignore silently
|
|
continue;
|
|
}
|
|
AStringVector Split = StringSplitAndTrim(*itr, "=");
|
|
if (Split.size() != 2)
|
|
{
|
|
// Malformed decl
|
|
LOG("%s: Malformed enchantment decl: \"%s\", skipping.", __FUNCTION__, itr->c_str());
|
|
continue;
|
|
}
|
|
int id = atoi(Split[0].c_str());
|
|
if ((id == 0) && (Split[0] != "0"))
|
|
{
|
|
id = StringToEnchantmentID(Split[0]);
|
|
}
|
|
int lvl = atoi(Split[1].c_str());
|
|
if (
|
|
((id <= 0) && (Split[0] != "0")) ||
|
|
((lvl == 0) && (Split[1] != "0"))
|
|
)
|
|
{
|
|
// Numbers failed to parse
|
|
LOG("%s: Failed to parse enchantment declaration for numbers: \"%s\" and \"%s\", skipping.",
|
|
__FUNCTION__, Split[0].c_str(), Split[1].c_str()
|
|
);
|
|
continue;
|
|
}
|
|
SetLevel(id, lvl);
|
|
} // for itr - Decls[]
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AString cEnchantments::ToString(void) const
|
|
{
|
|
// Serialize all the enchantments into a string
|
|
AString res;
|
|
for (cEnchantments::cMap::const_iterator itr = m_Enchantments.begin(), end = m_Enchantments.end(); itr != end; ++itr)
|
|
{
|
|
AppendPrintf(res, "%d=%d;", itr->first, itr->second);
|
|
} // for itr - m_Enchantments[]
|
|
return res;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cEnchantments::GetLevel(int a_EnchantmentID) const
|
|
{
|
|
// Return the level for the specified enchantment; 0 if not stored
|
|
cMap::const_iterator itr = m_Enchantments.find(a_EnchantmentID);
|
|
if (itr != m_Enchantments.end())
|
|
{
|
|
return itr->second;
|
|
}
|
|
|
|
// Not stored, return zero
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void cEnchantments::SetLevel(int a_EnchantmentID, int a_Level)
|
|
{
|
|
// Sets the level for the specified enchantment, adding it if not stored before or removing it if level <= 0
|
|
if (a_Level == 0)
|
|
{
|
|
// Delete enchantment, if present:
|
|
cMap::iterator itr = m_Enchantments.find(a_EnchantmentID);
|
|
if (itr != m_Enchantments.end())
|
|
{
|
|
m_Enchantments.erase(itr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Add / overwrite enchantment
|
|
m_Enchantments[a_EnchantmentID] = a_Level;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cEnchantments::Clear(void)
|
|
{
|
|
m_Enchantments.clear();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cEnchantments::IsEmpty(void) const
|
|
{
|
|
return m_Enchantments.empty();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cEnchantments::StringToEnchantmentID(const AString & a_EnchantmentName)
|
|
{
|
|
struct
|
|
{
|
|
int m_Value;
|
|
const char * m_Name;
|
|
} EnchantmentNames[] =
|
|
{
|
|
{ enchProtection, "Protection"},
|
|
{ enchFireProtection, "FireProtection"},
|
|
{ enchFeatherFalling, "FeatherFalling"},
|
|
{ enchBlastProtection, "BlastProtection"},
|
|
{ enchProjectileProtection, "ProjectileProtection"},
|
|
{ enchRespiration, "Respiration"},
|
|
{ enchAquaAffinity, "AquaAffinity"},
|
|
{ enchThorns, "Thorns"},
|
|
{ enchSharpness, "Sharpness"},
|
|
{ enchSmite, "Smite"},
|
|
{ enchBaneOfArthropods, "BaneOfArthropods"},
|
|
{ enchKnockback, "Knockback"},
|
|
{ enchFireAspect, "FireAspect"},
|
|
{ enchLooting, "Looting"},
|
|
{ enchEfficiency, "Efficiency"},
|
|
{ enchSilkTouch, "SilkTouch"},
|
|
{ enchUnbreaking, "Unbreaking"},
|
|
{ enchFortune, "Fortune"},
|
|
{ enchPower, "Power"},
|
|
{ enchPunch, "Punch"},
|
|
{ enchFlame, "Flame"},
|
|
{ enchInfinity, "Infinity"},
|
|
{ enchLuckOfTheSea, "LuckOfTheSea"},
|
|
{ enchLure, "Lure"},
|
|
} ;
|
|
for (size_t i = 0; i < ARRAYCOUNT(EnchantmentNames); i++)
|
|
{
|
|
if (NoCaseCompare(EnchantmentNames[i].m_Name, a_EnchantmentName) == 0)
|
|
{
|
|
return EnchantmentNames[i].m_Value;
|
|
}
|
|
} // for i - EnchantmentNames[]
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cEnchantments::operator ==(const cEnchantments & a_Other) const
|
|
{
|
|
return m_Enchantments == a_Other.m_Enchantments;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cEnchantments::operator !=(const cEnchantments & a_Other) const
|
|
{
|
|
return m_Enchantments != a_Other.m_Enchantments;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|