summaryrefslogtreecommitdiffstats
path: root/src/Enchantments.h
blob: 5f2d3de4ece3183078c6b11cb795e6baa837c521 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Enchantments.h

// Declares the cEnchantments class representing a storage for item enchantments and stored-enchantments





#pragma once

#include "Defines.h"
#include "WorldStorage/EnchantmentSerializer.h"




// fwd: "WorldStorage/FastNBT.h"
class cFastNBTWriter;
class cParsedNBT;


// fwd:
struct cWeightedEnchantment;

typedef std::vector<cWeightedEnchantment> cWeightedEnchantments;




/** Class that stores item enchantments or stored-enchantments
The enchantments may be serialized to a stringspec and read back from such stringspec.
The format for the stringspec is "id=lvl;id=lvl;id=lvl...", with an optional semicolon at the end,
mapping each enchantment's id onto its level. ID may be either a number or the enchantment name.
Level value of 0 means no such enchantment, and it will not be stored in the m_Enchantments.
Serialization will never put zero-level enchantments into the stringspec and will always use numeric IDs.
*/


// tolua_begin
class cEnchantments
{
public:
	/** Individual enchantment IDs, corresponding to their NBT IDs: https://minecraft.gamepedia.com/Data_values#Enchantment_IDs
	*/

	enum eEnchantment
	{
		// Currently missing: Frost walker, curse of binding, sweeping edge, mending, and curse of vanishing.
		enchProtection           = 0,
		enchFireProtection       = 1,
		enchFeatherFalling       = 2,
		enchBlastProtection      = 3,
		enchProjectileProtection = 4,
		enchRespiration          = 5,
		enchAquaAffinity         = 6,
		enchThorns               = 7,
		enchDepthStrider         = 8,
		enchSharpness            = 16,
		enchSmite                = 17,
		enchBaneOfArthropods     = 18,
		enchKnockback            = 19,
		enchFireAspect           = 20,
		enchLooting              = 21,
		enchEfficiency           = 32,
		enchSilkTouch            = 33,
		enchUnbreaking           = 34,
		enchFortune              = 35,
		enchPower                = 48,
		enchPunch                = 49,
		enchFlame                = 50,
		enchInfinity             = 51,
		enchLuckOfTheSea         = 61,
		enchLure                 = 62,
	} ;

	/** Creates an empty enchantments container */
	cEnchantments(void);

	/** Creates an enchantments container filled with enchantments parsed from stringspec */
	cEnchantments(const AString & a_StringSpec);

	/** Adds the enchantments contained in a_Other into this object.
	Existing enchantments are preserved, unless a_Other specifies a different level, in which case the level is changed to the a_Other's one. */
	void Add(const cEnchantments & a_Other);

	/** Adds enchantments in the stringspec; if a specified enchantment already exists, overwrites it */
	void AddFromString(const AString & a_StringSpec);

	/** Get the count of enchantments */
	size_t Count(void);

	/** Serializes all the enchantments into a string */
	AString ToString(void) const;

	/** Returns the level for the specified enchantment; 0 if not stored */
	unsigned int GetLevel(int a_EnchantmentID) const;

	/** Sets the level for the specified enchantment, adding it if not stored before or removing it if level <= 0 */
	void SetLevel(int a_EnchantmentID, unsigned int a_Level);

	/** Removes all enchantments */
	void Clear(void);

	/** Returns true if there are no enchantments */
	bool IsEmpty(void) const;

	/** Returns true if the given enchantment could be legally added to this object. Note that adding the enchantment may not actually increase the level. */
	bool CanAddEnchantment(int a_EnchantmentID) const;

	/** Converts enchantment name or ID (number in string) to the numeric representation; returns -1 if enchantment name not found; case insensitive */
	static int StringToEnchantmentID(const AString & a_EnchantmentName);

	/** Returns true if a_Other contains exactly the same enchantments and levels */
	bool operator ==(const cEnchantments & a_Other) const;

	// tolua_end

	/** Get the XP cost multiplier for the enchantment (for anvils).
	If FromBook is true, then this function returns the XP multiplier if
	the enchantment is coming from a book, otherwise it returns the normal
	item multiplier. */
	static int GetXPCostMultiplier(int a_EnchantmentID, bool FromBook);

	/** Get the maximum level the enchantment can have */
	static unsigned int GetLevelCap(int a_EnchantmentID);

	/** Add enchantment weights from item to the vector */
	static void AddItemEnchantmentWeights(cWeightedEnchantments & a_Enchantments, short a_ItemType, int a_EnchantmentLevel);

	/** Add a enchantment with weight to the vector */
	static void AddEnchantmentWeightToVector(cWeightedEnchantments & a_Enchantments, int a_Weight, int a_EnchantmentID, unsigned int a_EnchantmentLevel);

	/** Remove the entire enchantment (with weight) from the vector */
	static void RemoveEnchantmentWeightFromVector(cWeightedEnchantments & a_Enchantments, int a_EnchantmentID);

	/** Remove the entire enchantment (with weight) from the vector */
	static void RemoveEnchantmentWeightFromVector(cWeightedEnchantments & a_Enchantments, const cEnchantments & a_Enchantment);

	/** Check enchantment conflicts from enchantments from the vector */
	static void CheckEnchantmentConflictsFromVector(cWeightedEnchantments & a_Enchantments, cEnchantments a_FirstEnchantment);

	/** Gets random enchantment from Vector and returns it */
	static cEnchantments GetRandomEnchantmentFromVector(cWeightedEnchantments & a_Enchantments);

	/** Selects one enchantment from a Vector using cNoise. Mostly used for generators.
	Uses the enchantments' weights for the random distribution.
	If a_Enchantments is empty, returns an empty enchantment. */
	static cEnchantments SelectEnchantmentFromVector(const cWeightedEnchantments & a_Enchantments, int a_Seed);

	/** Returns true if a_Other doesn't contain exactly the same enchantments and levels */
	bool operator !=(const cEnchantments & a_Other) const;

	/** Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments") */
	friend void EnchantmentSerializer::WriteToNBTCompound(const cEnchantments & a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName);

	/** Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments) */
	friend void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx);

protected:
	/** Maps enchantment ID -> enchantment level */
	typedef std::map<int, unsigned int> cMap;

	/** Currently stored enchantments */
	cMap m_Enchantments;

public:
	/** Make this class iterable */
	cMap::const_iterator begin() const { return m_Enchantments.begin(); }
	cMap::const_iterator end()   const { return m_Enchantments.end(); }
};  // tolua_export




// Define the cWeightedEnchantment struct for the Enchanting System to store the EnchantmentWeights:
struct cWeightedEnchantment
{
	int m_Weight;
	cEnchantments m_Enchantments;
};