damage.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #ifndef __DAMAGE_H
  2. #define __DAMAGE_H
  3. #include <vector>
  4. #include <unordered_map>
  5. #include <map>
  6. struct Damage {
  7. tag_t tag;
  8. std::string name;
  9. struct damage_to_turns_t {
  10. int scale;
  11. int offset;
  12. damage_to_turns_t(int s = 0, int o = 0) : scale(s), offset(o) {}
  13. inline unsigned int get(double v) const {
  14. int n = (v * scale) - offset;
  15. return std::max(0, n);
  16. }
  17. };
  18. std::vector< std::pair<tag_t,damage_to_turns_t> > inc_counts;
  19. std::vector<tag_t> dec_stats;
  20. std::vector<tag_t> inc_stats;
  21. std::vector<tag_t> transfer_stats;
  22. double threshold;
  23. double levelup_threshold;
  24. bool visible_damage;
  25. std::vector< std::pair<tag_t,double> > karmic_scale;
  26. tag_t polymorph;
  27. damage_to_turns_t player_poly;
  28. struct flags_t {
  29. struct tristate_t {
  30. int v;
  31. tristate_t() : v(-1) {}
  32. bool operator()(bool f) const {
  33. if (v < 0) return true;
  34. return ((bool)v == f);
  35. }
  36. };
  37. tristate_t eyeless;
  38. tristate_t undead;
  39. tristate_t animal;
  40. tristate_t plant;
  41. tristate_t robot;
  42. tristate_t magic;
  43. tristate_t player;
  44. tristate_t cosmic;
  45. };
  46. flags_t flags;
  47. struct msg_t {
  48. std::string str;
  49. bool important;
  50. msg_t(const std::string& s = "", bool i = false) : str(s), important(i) {}
  51. };
  52. msg_t melee_msg;
  53. msg_t env_msg;
  54. std::pair<tag_t,tag_t> infect;
  55. tag_t ally;
  56. Damage() : threshold(0), levelup_threshold(0), visible_damage(false) {}
  57. };
  58. struct DamageBank {
  59. std::unordered_map<tag_t, Damage> bank;
  60. void copy(const Damage& t) {
  61. if (bank.count(t.tag) != 0) {
  62. throw std::runtime_error("Duplicate damage tag: " + t.name);
  63. }
  64. bank[t.tag] = t;
  65. }
  66. const Damage& get(tag_t tag) const {
  67. auto i = bank.find(tag);
  68. if (i == bank.end()) {
  69. throw std::runtime_error("Invalid damage tag: " + std::to_string(tag.v));
  70. }
  71. return i->second;
  72. }
  73. };
  74. inline DamageBank& __damages__() {
  75. static DamageBank ret;
  76. return ret;
  77. }
  78. inline const DamageBank& damages() {
  79. return __damages__();
  80. }
  81. inline void init_damage_copy(const Damage& t) {
  82. __damages__().copy(t);
  83. }
  84. namespace damage {
  85. struct val_t {
  86. double val;
  87. tag_t type;
  88. val_t(double v = 0, tag_t t = tag_t()) : val(v), type(t) {}
  89. };
  90. struct attacks_t {
  91. std::vector<val_t> attacks;
  92. void add(const val_t& a) {
  93. attacks.push_back(a);
  94. }
  95. void add(const attacks_t& a) {
  96. attacks.insert(attacks.end(), a.begin(), a.end());
  97. }
  98. std::vector<val_t>::const_iterator begin() const {
  99. return attacks.begin();
  100. }
  101. std::vector<val_t>::const_iterator end() const {
  102. return attacks.end();
  103. }
  104. bool empty() const { return attacks.empty(); }
  105. size_t size() const { return attacks.size(); }
  106. };
  107. struct defenses_t {
  108. std::map<tag_t,double> defenses;
  109. void add(const val_t& d) {
  110. defenses[d.type] += d.val;
  111. }
  112. void add(const defenses_t& d) {
  113. for (const auto& v : d) {
  114. defenses[v.first] += v.second;
  115. }
  116. }
  117. double get(tag_t t) const {
  118. auto i = defenses.find(t);
  119. if (i == defenses.end()) {
  120. return 0;
  121. }
  122. return i->second;
  123. }
  124. std::map<tag_t,double>::const_iterator begin() const {
  125. return defenses.begin();
  126. }
  127. std::map<tag_t,double>::const_iterator end() const {
  128. return defenses.end();
  129. }
  130. };
  131. }
  132. #endif