Cuberite
A lightweight, fast and extensible game server for Minecraft
Enchantments.cpp
Go to the documentation of this file.
1 // Enchantments.cpp
2 
3 // Implements the cEnchantments class representing a storage for item enchantments and stored-enchantments
4 
5 #include "Globals.h"
6 #include "Enchantments.h"
7 #include "WorldStorage/FastNBT.h"
8 #include "FastRandom.h"
9 #include "Noise/Noise.h"
10 #include "BlockType.h"
11 
12 
13 
14 
15 
17 {
18  // Nothing needed yet, but the constructor needs to be declared and impemented in order to be usable
19 }
20 
21 
22 
23 
24 
26 {
27  AddFromString(a_StringSpec);
28 }
29 
30 
31 
32 
33 
34 void cEnchantments::Add(const cEnchantments & a_Other)
35 {
36  for (cEnchantments::cMap::const_iterator itr = a_Other.m_Enchantments.begin(), end = a_Other.m_Enchantments.end(); itr != end; ++itr)
37  {
38  SetLevel(itr->first, itr->second);
39  } // for itr - a_Other.m_Enchantments[]
40 }
41 
42 
43 
44 
45 
46 void cEnchantments::AddFromString(const AString & a_StringSpec)
47 {
48  // Add enchantments in the stringspec; if a specified enchantment already exists, overwrites it
49 
50  // Split the StringSpec into separate declarations, each in the form "id=lvl":
51  AStringVector Decls = StringSplit(a_StringSpec, ";");
52  for (AStringVector::const_iterator itr = Decls.begin(), end = Decls.end(); itr != end; ++itr)
53  {
54  // Split each declaration into the id and lvl part:
55  if (itr->empty())
56  {
57  // The decl is empty (may happen if there's an extra semicolon at the end), ignore silently
58  continue;
59  }
60  AStringVector Split = StringSplitAndTrim(*itr, "=");
61  if (Split.size() != 2)
62  {
63  // Malformed decl
64  LOG("%s: Malformed enchantment decl: \"%s\", skipping.", __FUNCTION__, itr->c_str());
65  continue;
66  }
67  int id = StringToEnchantmentID(Split[0]);
68  if (id < 0)
69  {
70  LOG("%s: Failed to parse enchantment \"%s\", skipping.", __FUNCTION__, Split[0].c_str());
71  continue;
72  }
73  unsigned int lvl;
74  if (!StringToInteger(Split[1], lvl))
75  {
76  // Level failed to parse
77  LOG("%s: Failed to parse enchantment level \"%s\", skipping.", __FUNCTION__, Split[1].c_str());
78  continue;
79  }
80  SetLevel(id, lvl);
81  } // for itr - Decls[]
82 }
83 
84 
85 
86 
87 
88 size_t cEnchantments::Count() const
89 {
90  return m_Enchantments.size();
91 }
92 
93 
94 
95 
96 
98 {
99  // Serialize all the enchantments into a string
100  AString res;
101  for (cEnchantments::cMap::const_iterator itr = m_Enchantments.begin(), end = m_Enchantments.end(); itr != end; ++itr)
102  {
103  res.append(fmt::format(FMT_STRING("{}={};"), itr->first, itr->second));
104  } // for itr - m_Enchantments[]
105  return res;
106 }
107 
108 
109 
110 
111 
112 unsigned int cEnchantments::GetLevel(int a_EnchantmentID) const
113 {
114  // Return the level for the specified enchantment; 0 if not stored
115  cMap::const_iterator itr = m_Enchantments.find(a_EnchantmentID);
116  if (itr != m_Enchantments.end())
117  {
118  return itr->second;
119  }
120 
121  // Not stored, return zero
122  return 0;
123 }
124 
125 
126 
127 
128 
129 void cEnchantments::SetLevel(int a_EnchantmentID, unsigned int a_Level)
130 {
131  // Sets the level for the specified enchantment, adding it if not stored before or removing it if level <= 0
132  if (a_Level == 0)
133  {
134  // Delete enchantment, if present:
135  cMap::iterator itr = m_Enchantments.find(a_EnchantmentID);
136  if (itr != m_Enchantments.end())
137  {
138  m_Enchantments.erase(itr);
139  }
140  }
141  else
142  {
143  // Add / overwrite enchantment
144  m_Enchantments[a_EnchantmentID] = a_Level;
145  }
146 }
147 
148 
149 
150 
151 
153 {
154  m_Enchantments.clear();
155 }
156 
157 
158 
159 
160 
161 bool cEnchantments::IsEmpty(void) const
162 {
163  return m_Enchantments.empty();
164 }
165 
166 
167 
168 
169 
170 unsigned int cEnchantments::GetLevelCap(int a_EnchantmentID)
171 {
172  switch (a_EnchantmentID)
173  {
174  case enchProtection: return 4;
175  case enchFireProtection: return 4;
176  case enchFeatherFalling: return 4;
177  case enchBlastProtection: return 4;
178  case enchProjectileProtection: return 4;
179  case enchRespiration: return 3;
180  case enchAquaAffinity: return 1;
181  case enchThorns: return 3;
182  case enchDepthStrider: return 3;
183  case enchSharpness: return 5;
184  case enchSmite: return 5;
185  case enchBaneOfArthropods: return 5;
186  case enchKnockback: return 2;
187  case enchFireAspect: return 2;
188  case enchLooting: return 3;
189  case enchEfficiency: return 5;
190  case enchSilkTouch: return 1;
191  case enchUnbreaking: return 3;
192  case enchFortune: return 3;
193  case enchPower: return 5;
194  case enchPunch: return 2;
195  case enchFlame: return 1;
196  case enchInfinity: return 1;
197  case enchLuckOfTheSea: return 3;
198  case enchLure: return 3;
199  }
200  LOGWARNING("Unknown enchantment ID %d", a_EnchantmentID);
201  return 0;
202 }
203 
204 
205 
206 
207 
208 int cEnchantments::GetXPCostMultiplier(int a_EnchantmentID, bool FromBook)
209 {
210  if (FromBook)
211  {
212  switch (a_EnchantmentID)
213  {
214  case enchProtection: return 1;
215  case enchFireProtection: return 1;
216  case enchFeatherFalling: return 1;
217  case enchBlastProtection: return 2;
218  case enchProjectileProtection: return 1;
219  case enchRespiration: return 2;
220  case enchAquaAffinity: return 2;
221  case enchThorns: return 4;
222  case enchDepthStrider: return 2;
223  case enchSharpness: return 1;
224  case enchSmite: return 1;
225  case enchBaneOfArthropods: return 1;
226  case enchKnockback: return 1;
227  case enchFireAspect: return 2;
228  case enchLooting: return 2;
229  case enchEfficiency: return 1;
230  case enchSilkTouch: return 4;
231  case enchUnbreaking: return 1;
232  case enchFortune: return 1;
233  case enchPower: return 1;
234  case enchPunch: return 2;
235  case enchFlame: return 2;
236  case enchInfinity: return 4;
237  case enchLuckOfTheSea: return 2;
238  case enchLure: return 2;
239  }
240  }
241  else // Without book
242  {
243  switch (a_EnchantmentID)
244  {
245  case enchProtection: return 1;
246  case enchFireProtection: return 2;
247  case enchFeatherFalling: return 2;
248  case enchBlastProtection: return 4;
249  case enchProjectileProtection: return 2;
250  case enchRespiration: return 4;
251  case enchAquaAffinity: return 4;
252  case enchThorns: return 8;
253  case enchDepthStrider: return 4;
254 
255  case enchSharpness: return 1;
256  case enchSmite: return 2;
257  case enchBaneOfArthropods: return 2;
258  case enchKnockback: return 2;
259  case enchFireAspect: return 4;
260  case enchLooting: return 4;
261 
262  case enchEfficiency: return 1;
263  case enchSilkTouch: return 8;
264  case enchUnbreaking: return 2;
265  case enchFortune: return 4;
266  case enchPower: return 1;
267  case enchPunch: return 4;
268  case enchFlame: return 4;
269  case enchInfinity: return 8;
270  case enchLuckOfTheSea: return 4;
271  case enchLure: return 4;
272  }
273  }
274  LOGWARNING("Unknown enchantment ID %d", a_EnchantmentID);
275  return 0;
276 }
277 
278 
279 
280 
281 
282 bool cEnchantments::CanAddEnchantment(int a_EnchantmentID) const
283 {
284  if (GetLevel(a_EnchantmentID) > 0)
285  {
286  return true;
287  }
288 
289  static const std::vector<std::set<int> > IncompatibleEnchantments =
290  {
291  // Armor
293 
294  // Tool
296 
297  // Sword
299 
300  // Boots
301  // {enchDepthStrider, enchFrostWalker},
302 
303  // Bow
304  // {enchInfinity, enchMending}
305  };
306 
307  for (const auto & excl: IncompatibleEnchantments)
308  {
309  if (excl.count(a_EnchantmentID) != 0)
310  {
311  // See if we also have any of the enchantments
312  for (auto ench: excl)
313  {
314  if (GetLevel(ench) > 0)
315  {
316  return false;
317  }
318  }
319  }
320  }
321  return true;
322 }
323 
324 
325 
326 
327 
328 int cEnchantments::StringToEnchantmentID(const AString & a_EnchantmentName)
329 {
330  static const struct
331  {
332  int m_Value;
333  const char * m_Name;
334  } EnchantmentNames[] =
335  {
336  { enchProtection, "Protection" },
337  { enchFireProtection, "FireProtection" },
338  { enchFeatherFalling, "FeatherFalling" },
339  { enchBlastProtection, "BlastProtection" },
340  { enchProjectileProtection, "ProjectileProtection" },
341  { enchRespiration, "Respiration" },
342  { enchAquaAffinity, "AquaAffinity" },
343  { enchThorns, "Thorns" },
344  { enchDepthStrider, "DepthStrider" },
345  { enchSharpness, "Sharpness" },
346  { enchSmite, "Smite" },
347  { enchBaneOfArthropods, "BaneOfArthropods" },
348  { enchKnockback, "Knockback" },
349  { enchFireAspect, "FireAspect" },
350  { enchLooting, "Looting" },
351  { enchEfficiency, "Efficiency" },
352  { enchSilkTouch, "SilkTouch" },
353  { enchUnbreaking, "Unbreaking" },
354  { enchFortune, "Fortune" },
355  { enchPower, "Power" },
356  { enchPunch, "Punch" },
357  { enchFlame, "Flame" },
358  { enchInfinity, "Infinity" },
359  { enchLuckOfTheSea, "LuckOfTheSea" },
360  { enchLure, "Lure" },
361  } ;
362 
363  // First try to parse as a number:
364  int id = atoi(a_EnchantmentName.c_str());
365  if ((id != 0) || (a_EnchantmentName == "0"))
366  {
367  return id;
368  }
369 
370  // It wasn't a number, do a lookup:
371  for (size_t i = 0; i < ARRAYCOUNT(EnchantmentNames); i++)
372  {
373  if (NoCaseCompare(EnchantmentNames[i].m_Name, a_EnchantmentName) == 0)
374  {
375  return EnchantmentNames[i].m_Value;
376  }
377  } // for i - EnchantmentNames[]
378  return -1;
379 }
380 
381 
382 
383 
384 
385 bool cEnchantments::operator ==(const cEnchantments & a_Other) const
386 {
387  return m_Enchantments == a_Other.m_Enchantments;
388 }
389 
390 
391 
392 
393 
394 bool cEnchantments::operator !=(const cEnchantments & a_Other) const
395 {
396  return m_Enchantments != a_Other.m_Enchantments;
397 }
398 
399 
400 
401 
402 
403 void cEnchantments::AddItemEnchantmentWeights(cWeightedEnchantments & a_Enchantments, short a_ItemType, unsigned a_EnchantmentLevel)
404 {
405  if (ItemCategory::IsSword(a_ItemType))
406  {
407  // Sharpness
408  if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54))
409  {
410  AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 4);
411  }
412  else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43))
413  {
414  AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 3);
415  }
416  else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32))
417  {
418  AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 2);
419  }
420  else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21))
421  {
422  AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 1);
423  }
424 
425  // Smite
426  if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49))
427  {
428  AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 4);
429  }
430  else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41))
431  {
432  AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 3);
433  }
434  else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33))
435  {
436  AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 2);
437  }
438  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25))
439  {
440  AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 1);
441  }
442 
443  // Bane of Arthropods
444  if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49))
445  {
446  AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 4);
447  }
448  else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41))
449  {
450  AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 3);
451  }
452  else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33))
453  {
454  AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 2);
455  }
456  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25))
457  {
458  AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 1);
459  }
460 
461  // Knockback
462  if ((a_EnchantmentLevel >= 25) && (a_EnchantmentLevel <= 75))
463  {
464  AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 2);
465  }
466  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 55))
467  {
468  AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 1);
469  }
470 
471  // Fire Aspect
472  if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80))
473  {
474  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 2);
475  }
476  else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60))
477  {
478  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 1);
479  }
480 
481  // Looting
482  if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
483  {
484  AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 3);
485  }
486  else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
487  {
488  AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 2);
489  }
490  else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
491  {
492  AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 1);
493  }
494  }
495 
496  else if (ItemCategory::IsTool(a_ItemType))
497  {
498  // Efficiency
499  if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 81))
500  {
501  AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 4);
502  }
503  else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 71))
504  {
505  AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 3);
506  }
507  else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 61))
508  {
509  AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 2);
510  }
511  else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 51))
512  {
513  AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 1);
514  }
515 
516  // Silk Touch
517  if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
518  {
519  AddEnchantmentWeightToVector(a_Enchantments, 1, enchSilkTouch, 1);
520  }
521 
522  // Fortune
523  if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
524  {
525  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 3);
526  }
527  else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
528  {
529  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 2);
530  }
531  else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
532  {
533  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 1);
534  }
535  }
536 
537  else if (ItemCategory::IsArmor(a_ItemType))
538  {
539  // Protection
540  if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54))
541  {
542  AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 4);
543  }
544  else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43))
545  {
546  AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 3);
547  }
548  else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32))
549  {
550  AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 2);
551  }
552  else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21))
553  {
554  AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 1);
555  }
556 
557  // Fire Protection
558  if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 46))
559  {
560  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 4);
561  }
562  else if ((a_EnchantmentLevel >= 26) && (a_EnchantmentLevel <= 38))
563  {
564  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 3);
565  }
566  else if ((a_EnchantmentLevel >= 18) && (a_EnchantmentLevel <= 30))
567  {
568  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 2);
569  }
570  else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 22))
571  {
572  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 1);
573  }
574 
575  // Blast Protection
576  if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 41))
577  {
578  AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 4);
579  }
580  else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 33))
581  {
582  AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 3);
583  }
584  else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 25))
585  {
586  AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 2);
587  }
588  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 17))
589  {
590  AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 1);
591  }
592 
593  // Projectile Protection
594  if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36))
595  {
597  }
598  else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 30))
599  {
601  }
602  else if ((a_EnchantmentLevel >= 9) && (a_EnchantmentLevel <= 24))
603  {
605  }
606  else if ((a_EnchantmentLevel >= 3) && (a_EnchantmentLevel <= 18))
607  {
609  }
610 
611  // Thorns
612  if ((a_EnchantmentLevel >= 50) && (a_EnchantmentLevel <= 100))
613  {
614  AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 3);
615  }
616  else if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80))
617  {
618  AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 2);
619  }
620  else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60))
621  {
622  AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 1);
623  }
624 
625 
626  if (ItemCategory::IsHelmet(a_ItemType))
627  {
628  // Respiration
629  if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 60))
630  {
631  AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 3);
632  }
633  else if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50))
634  {
635  AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 2);
636  }
637  else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 40))
638  {
639  AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 1);
640  }
641 
642  // Aqua Affinity
643  if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 41))
644  {
645  AddEnchantmentWeightToVector(a_Enchantments, 2, enchAquaAffinity, 1);
646  }
647  }
648 
649  else if (ItemCategory::IsBoots(a_ItemType))
650  {
651  // Feather Fall
652  if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 33))
653  {
654  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 4);
655  }
656  else if ((a_EnchantmentLevel >= 17) && (a_EnchantmentLevel <= 27))
657  {
658  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 3);
659  }
660  else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 21))
661  {
662  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 2);
663  }
664  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 15))
665  {
666  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 1);
667  }
668 
669  // Depth Strider
670  if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 45))
671  {
672  AddEnchantmentWeightToVector(a_Enchantments, 2, enchDepthStrider, 3);
673  }
674  else if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 35))
675  {
676  AddEnchantmentWeightToVector(a_Enchantments, 2, enchDepthStrider, 2);
677  }
678  else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 25))
679  {
680  AddEnchantmentWeightToVector(a_Enchantments, 2, enchDepthStrider, 1);
681  }
682  }
683  }
684 
685  else if (a_ItemType == E_ITEM_BOW)
686  {
687  // Power
688  if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 46))
689  {
690  AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 4);
691  }
692  else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36))
693  {
694  AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 3);
695  }
696  else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 26))
697  {
698  AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 2);
699  }
700  else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 16))
701  {
702  AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 1);
703  }
704 
705  // Punch
706  if ((a_EnchantmentLevel >= 32) && (a_EnchantmentLevel <= 57))
707  {
708  AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 2);
709  }
710  else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 37))
711  {
712  AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 1);
713  }
714 
715  // Flame and Infinity
716  if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50))
717  {
718  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFlame, 1);
719  AddEnchantmentWeightToVector(a_Enchantments, 1, enchInfinity, 1);
720  }
721  }
722 
723  else if (a_ItemType == E_ITEM_FISHING_ROD)
724  {
725  // Luck of the Sea and Lure
726  if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
727  {
728  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 3);
729  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 3);
730  }
731  else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
732  {
733  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 2);
734  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 2);
735  }
736  else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
737  {
738  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 1);
739  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 1);
740  }
741  }
742 
743  else if (a_ItemType == E_ITEM_BOOK)
744  {
745  // All Enchantments
746 
747  // Sharpness
748  if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54))
749  {
750  AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 4);
751  }
752  else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43))
753  {
754  AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 3);
755  }
756  else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32))
757  {
758  AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 2);
759  }
760  else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21))
761  {
762  AddEnchantmentWeightToVector(a_Enchantments, 10, enchSharpness, 1);
763  }
764 
765  // Smite
766  if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49))
767  {
768  AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 4);
769  }
770  else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41))
771  {
772  AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 3);
773  }
774  else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33))
775  {
776  AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 2);
777  }
778  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25))
779  {
780  AddEnchantmentWeightToVector(a_Enchantments, 5, enchSmite, 1);
781  }
782 
783  // Bane of Arthropods
784  if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 49))
785  {
786  AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 4);
787  }
788  else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 41))
789  {
790  AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 3);
791  }
792  else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 33))
793  {
794  AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 2);
795  }
796  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 25))
797  {
798  AddEnchantmentWeightToVector(a_Enchantments, 5, enchBaneOfArthropods, 1);
799  }
800 
801  // Knockback
802  if ((a_EnchantmentLevel >= 25) && (a_EnchantmentLevel <= 75))
803  {
804  AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 2);
805  }
806  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 55))
807  {
808  AddEnchantmentWeightToVector(a_Enchantments, 5, enchKnockback, 1);
809  }
810 
811  // Fire Aspect
812  if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80))
813  {
814  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 2);
815  }
816  else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60))
817  {
818  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFireAspect, 1);
819  }
820 
821  // Looting
822  if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
823  {
824  AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 3);
825  }
826  else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
827  {
828  AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 2);
829  }
830  else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
831  {
832  AddEnchantmentWeightToVector(a_Enchantments, 2, enchLooting, 1);
833  }
834 
835  // Efficiency
836  if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 81))
837  {
838  AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 4);
839  }
840  else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 71))
841  {
842  AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 3);
843  }
844  else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 61))
845  {
846  AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 2);
847  }
848  else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 51))
849  {
850  AddEnchantmentWeightToVector(a_Enchantments, 10, enchEfficiency, 1);
851  }
852 
853  // Silk Touch
854  if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
855  {
856  AddEnchantmentWeightToVector(a_Enchantments, 1, enchSilkTouch, 1);
857  }
858 
859  // Fortune
860  if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
861  {
862  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 3);
863  }
864  else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
865  {
866  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 2);
867  }
868  else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
869  {
870  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFortune, 1);
871  }
872 
873  // Protection
874  if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 54))
875  {
876  AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 4);
877  }
878  else if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 43))
879  {
880  AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 3);
881  }
882  else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 32))
883  {
884  AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 2);
885  }
886  else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 21))
887  {
888  AddEnchantmentWeightToVector(a_Enchantments, 10, enchProtection, 1);
889  }
890 
891  // Fire Protection
892  if ((a_EnchantmentLevel >= 34) && (a_EnchantmentLevel <= 46))
893  {
894  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 4);
895  }
896  else if ((a_EnchantmentLevel >= 26) && (a_EnchantmentLevel <= 38))
897  {
898  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 3);
899  }
900  else if ((a_EnchantmentLevel >= 18) && (a_EnchantmentLevel <= 30))
901  {
902  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 2);
903  }
904  else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 22))
905  {
906  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFireProtection, 1);
907  }
908 
909  // Blast Protection
910  if ((a_EnchantmentLevel >= 29) && (a_EnchantmentLevel <= 41))
911  {
912  AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 4);
913  }
914  else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 33))
915  {
916  AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 3);
917  }
918  else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 25))
919  {
920  AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 2);
921  }
922  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 17))
923  {
924  AddEnchantmentWeightToVector(a_Enchantments, 2, enchBlastProtection, 1);
925  }
926 
927  // Projectile Protection
928  if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36))
929  {
931  }
932  else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 30))
933  {
935  }
936  else if ((a_EnchantmentLevel >= 9) && (a_EnchantmentLevel <= 24))
937  {
939  }
940  else if ((a_EnchantmentLevel >= 3) && (a_EnchantmentLevel <= 18))
941  {
943  }
944 
945  // Thorns
946  if ((a_EnchantmentLevel >= 50) && (a_EnchantmentLevel <= 100))
947  {
948  AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 3);
949  }
950  else if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 80))
951  {
952  AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 2);
953  }
954  else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 60))
955  {
956  AddEnchantmentWeightToVector(a_Enchantments, 1, enchThorns, 1);
957  }
958 
959  // Respiration
960  if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 60))
961  {
962  AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 3);
963  }
964  else if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50))
965  {
966  AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 2);
967  }
968  else if ((a_EnchantmentLevel >= 10) && (a_EnchantmentLevel <= 40))
969  {
970  AddEnchantmentWeightToVector(a_Enchantments, 2, enchRespiration, 1);
971  }
972 
973  // Aqua Affinity
974  if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 41))
975  {
976  AddEnchantmentWeightToVector(a_Enchantments, 2, enchAquaAffinity, 1);
977  }
978 
979  // Feather Fall
980  if ((a_EnchantmentLevel >= 23) && (a_EnchantmentLevel <= 33))
981  {
982  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 4);
983  }
984  else if ((a_EnchantmentLevel >= 17) && (a_EnchantmentLevel <= 27))
985  {
986  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 3);
987  }
988  else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 21))
989  {
990  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 2);
991  }
992  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 15))
993  {
994  AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 1);
995  }
996 
997  // Power
998  if ((a_EnchantmentLevel >= 31) && (a_EnchantmentLevel <= 46))
999  {
1000  AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 4);
1001  }
1002  else if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 36))
1003  {
1004  AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 3);
1005  }
1006  else if ((a_EnchantmentLevel >= 11) && (a_EnchantmentLevel <= 26))
1007  {
1008  AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 2);
1009  }
1010  else if ((a_EnchantmentLevel >= 1) && (a_EnchantmentLevel <= 16))
1011  {
1012  AddEnchantmentWeightToVector(a_Enchantments, 10, enchPower, 1);
1013  }
1014 
1015  // Punch
1016  if ((a_EnchantmentLevel >= 32) && (a_EnchantmentLevel <= 57))
1017  {
1018  AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 2);
1019  }
1020  else if ((a_EnchantmentLevel >= 12) && (a_EnchantmentLevel <= 37))
1021  {
1022  AddEnchantmentWeightToVector(a_Enchantments, 2, enchPunch, 1);
1023  }
1024 
1025  // Flame and Infinity
1026  if ((a_EnchantmentLevel >= 20) && (a_EnchantmentLevel <= 50))
1027  {
1028  AddEnchantmentWeightToVector(a_Enchantments, 2, enchFlame, 1);
1029  AddEnchantmentWeightToVector(a_Enchantments, 1, enchInfinity, 1);
1030  }
1031 
1032  // Luck of the Sea and Lure
1033  if ((a_EnchantmentLevel >= 33) && (a_EnchantmentLevel <= 83))
1034  {
1035  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 3);
1036  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 3);
1037  }
1038  else if ((a_EnchantmentLevel >= 24) && (a_EnchantmentLevel <= 74))
1039  {
1040  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 2);
1041  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 2);
1042  }
1043  else if ((a_EnchantmentLevel >= 15) && (a_EnchantmentLevel <= 65))
1044  {
1045  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLuckOfTheSea, 1);
1046  AddEnchantmentWeightToVector(a_Enchantments, 1, enchLure, 1);
1047  }
1048  }
1049 
1050  // Unbreaking
1051  if ((a_EnchantmentLevel >= 21) && (a_EnchantmentLevel <= 71))
1052  {
1053  AddEnchantmentWeightToVector(a_Enchantments, 5, enchUnbreaking, 3);
1054  }
1055  else if ((a_EnchantmentLevel >= 13) && (a_EnchantmentLevel <= 63))
1056  {
1057  AddEnchantmentWeightToVector(a_Enchantments, 5, enchUnbreaking, 2);
1058  }
1059  else if ((a_EnchantmentLevel >= 5) && (a_EnchantmentLevel <= 55))
1060  {
1061  AddEnchantmentWeightToVector(a_Enchantments, 5, enchUnbreaking, 1);
1062  }
1063 }
1064 
1065 
1066 
1067 
1068 
1069 void cEnchantments::AddEnchantmentWeightToVector(cWeightedEnchantments & a_Enchantments, int a_Weight, int a_EnchantmentID, unsigned int a_EnchantmentLevel)
1070 {
1071  cWeightedEnchantment weightedenchantment;
1072  weightedenchantment.m_Weight = a_Weight;
1073  cEnchantments enchantment;
1074  enchantment.SetLevel(a_EnchantmentID, a_EnchantmentLevel);
1075  weightedenchantment.m_Enchantments = enchantment;
1076  a_Enchantments.push_back(weightedenchantment);
1077 }
1078 
1079 
1080 
1081 
1082 
1084 {
1085  for (cWeightedEnchantments::iterator it = a_Enchantments.begin(); it != a_Enchantments.end(); ++it)
1086  {
1087  if ((*it).m_Enchantments.GetLevel(a_EnchantmentID) > 0)
1088  {
1089  a_Enchantments.erase(it);
1090  break;
1091  }
1092  }
1093 }
1094 
1095 
1096 
1097 
1098 
1100 {
1101  for (cWeightedEnchantments::iterator it = a_Enchantments.begin(); it != a_Enchantments.end(); ++it)
1102  {
1103  if ((*it).m_Enchantments == a_Enchantment)
1104  {
1105  a_Enchantments.erase(it);
1106  break;
1107  }
1108  }
1109 }
1110 
1111 
1112 
1113 
1114 
1116  cWeightedEnchantments & a_Enchantments, const cEnchantments & a_FirstEnchantment
1117 )
1118 {
1119  if (a_FirstEnchantment.GetLevel(cEnchantments::enchProtection) > 0)
1120  {
1124  }
1125  else if (a_FirstEnchantment.GetLevel(cEnchantments::enchFireProtection) > 0)
1126  {
1130  }
1131  else if (a_FirstEnchantment.GetLevel(cEnchantments::enchBlastProtection) > 0)
1132  {
1136  }
1137  else if (a_FirstEnchantment.GetLevel(cEnchantments::enchProjectileProtection) > 0)
1138  {
1142  }
1143 
1144  else if (a_FirstEnchantment.GetLevel(cEnchantments::enchSharpness) > 0)
1145  {
1148  }
1149  else if (a_FirstEnchantment.GetLevel(cEnchantments::enchSmite) > 0)
1150  {
1153  }
1154  else if (a_FirstEnchantment.GetLevel(cEnchantments::enchBaneOfArthropods) > 0)
1155  {
1158  }
1159  else if (a_FirstEnchantment.GetLevel(cEnchantments::enchSilkTouch) > 0)
1160  {
1162  }
1163  else if (a_FirstEnchantment.GetLevel(cEnchantments::enchFortune) > 0)
1164  {
1166  }
1167 }
1168 
1169 
1170 
1171 
1172 
1174 {
1175  int AllWeights = 0;
1176  for (const auto & Enchantment: a_Enchantments)
1177  {
1178  AllWeights += Enchantment.m_Weight;
1179  }
1180  int RandomNumber = a_Random.RandInt(AllWeights - 1);
1181  for (const auto & Enchantment: a_Enchantments)
1182  {
1183  RandomNumber -= Enchantment.m_Weight;
1184  if (RandomNumber < 0)
1185  {
1186  return Enchantment.m_Enchantments;
1187  }
1188  }
1189 
1190  return cEnchantments();
1191 }
1192 
1193 
1194 
1195 
1196 
1198 {
1199  // Sum up all the enchantments' weights:
1200  int AllWeights = 0;
1201  for (const auto & Enchantment : a_Enchantments)
1202  {
1203  AllWeights += Enchantment.m_Weight;
1204  }
1205 
1206  // If there's no weight for any of the enchantments, return an empty enchantment
1207  if (AllWeights <= 0)
1208  {
1209  return cEnchantments();
1210  }
1211 
1212  // Pick a random enchantment:
1213  cNoise Noise(a_Seed);
1214  int RandomNumber = Noise.IntNoise1DInt(AllWeights) / 7 % AllWeights;
1215  for (const auto & Enchantment : a_Enchantments)
1216  {
1217  RandomNumber -= Enchantment.m_Weight;
1218  if (RandomNumber <= 0)
1219  {
1220  return Enchantment.m_Enchantments;
1221  }
1222  }
1223 
1224  // No enchantment picked, return an empty one (we probably shouldn't ever get here):
1225  return cEnchantments();
1226 }
1227 
1228 
1229 
1230 
@ E_ITEM_FISHING_ROD
Definition: BlockType.h:391
@ E_ITEM_BOOK
Definition: BlockType.h:385
@ E_ITEM_BOW
Definition: BlockType.h:305
std::vector< cWeightedEnchantment > cWeightedEnchantments
Definition: Enchantments.h:23
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Definition: Globals.h:231
void LOGWARNING(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:67
void LOG(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:55
AStringVector StringSplitAndTrim(const AString &str, const AString &delim)
Split the string at any of the listed delimiters and trim each value.
AStringVector StringSplit(const AString &str, const AString &delim)
Split the string at any of the listed delimiters.
Definition: StringUtils.cpp:55
int NoCaseCompare(const AString &s1, const AString &s2)
Case-insensitive string comparison.
std::vector< AString > AStringVector
Definition: StringUtils.h:12
std::string AString
Definition: StringUtils.h:11
bool StringToInteger(const AString &a_str, T &a_Num)
Parses any integer type.
Definition: StringUtils.h:143
bool IsHelmet(short a_ItemType)
Definition: Defines.cpp:512
bool IsTool(short a_ItemType)
Definition: Defines.cpp:499
bool IsArmor(short a_ItemType)
Definition: Defines.cpp:588
bool IsBoots(short a_ItemType)
Definition: Defines.cpp:558
bool IsSword(short a_ItemType)
Definition: Defines.cpp:460
Class that stores item enchantments or stored-enchantments The enchantments may be serialized to a st...
Definition: Enchantments.h:42
cMap m_Enchantments
Currently stored enchantments.
Definition: Enchantments.h:165
bool CanAddEnchantment(int a_EnchantmentID) const
Returns true if the given enchantment could be legally added to this object.
void Add(const cEnchantments &a_Other)
Adds the enchantments contained in a_Other into this object.
void Clear(void)
Removes all enchantments.
@ enchProjectileProtection
Definition: Enchantments.h:54
void SetLevel(int a_EnchantmentID, unsigned int a_Level)
Sets the level for the specified enchantment, adding it if not stored before or removing it if level ...
size_t Count(void) const
Get the count of enchantments.
static void AddEnchantmentWeightToVector(cWeightedEnchantments &a_Enchantments, int a_Weight, int a_EnchantmentID, unsigned int a_EnchantmentLevel)
Add a enchantment with weight to the vector.
static unsigned int GetLevelCap(int a_EnchantmentID)
Get the maximum level the enchantment can have.
static int StringToEnchantmentID(const AString &a_EnchantmentName)
Converts enchantment name or ID (number in string) to the numeric representation; returns -1 if encha...
static cEnchantments SelectEnchantmentFromVector(const cWeightedEnchantments &a_Enchantments, int a_Seed)
Selects one enchantment from a Vector using cNoise.
unsigned int GetLevel(int a_EnchantmentID) const
Returns the level for the specified enchantment; 0 if not stored.
static void RemoveEnchantmentWeightFromVector(cWeightedEnchantments &a_Enchantments, int a_EnchantmentID)
Remove the entire enchantment (with weight) from the vector.
void AddFromString(const AString &a_StringSpec)
Adds enchantments in the stringspec; if a specified enchantment already exists, overwrites it.
AString ToString(void) const
Serializes all the enchantments into a string.
bool operator!=(const cEnchantments &a_Other) const
Returns true if a_Other doesn't contain exactly the same enchantments and levels.
cMap::const_iterator end() const
Definition: Enchantments.h:170
static cEnchantments GetRandomEnchantmentFromVector(const cWeightedEnchantments &a_Enchantments, MTRand &a_Random)
Gets random enchantment from Vector and returns it, with randomness derived from the provided PRNG.
static int GetXPCostMultiplier(int a_EnchantmentID, bool FromBook)
Get the XP cost multiplier for the enchantment (for anvils).
static void CheckEnchantmentConflictsFromVector(cWeightedEnchantments &a_Enchantments, const cEnchantments &a_FirstEnchantment)
Check enchantment conflicts from enchantments from the vector.
static void AddItemEnchantmentWeights(cWeightedEnchantments &a_Enchantments, short a_ItemType, unsigned a_EnchantmentLevel)
Add enchantment weights from item to the vector.
cEnchantments(void)
Creates an empty enchantments container.
bool operator==(const cEnchantments &a_Other) const
Returns true if a_Other contains exactly the same enchantments and levels.
bool IsEmpty(void) const
Returns true if there are no enchantments.
cEnchantments m_Enchantments
Definition: Enchantments.h:180
Class to wrap any random engine to provide a more convenient interface.
Definition: FastRandom.h:58
IntType RandInt(IntType a_Min, IntType a_Max)
Return a random IntType in the range [a_Min, a_Max].
Definition: FastRandom.h:78
Definition: Noise.h:20
int IntNoise1DInt(int a_X) const
Definition: Noise.h:233