pointabilities.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. Minetest
  3. Copyright (C) 2023 cx384
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "pointabilities.h"
  17. #include "serialize.h"
  18. #include "exceptions.h"
  19. #include <sstream>
  20. PointabilityType Pointabilities::deSerializePointabilityType(std::istream &is)
  21. {
  22. PointabilityType pointable_type = static_cast<PointabilityType>(readU8(is));
  23. switch(pointable_type) {
  24. case PointabilityType::POINTABLE:
  25. case PointabilityType::POINTABLE_NOT:
  26. case PointabilityType::POINTABLE_BLOCKING:
  27. break;
  28. default:
  29. // Default to POINTABLE in case of unknown PointabilityType type.
  30. pointable_type = PointabilityType::POINTABLE;
  31. break;
  32. }
  33. return pointable_type;
  34. }
  35. void Pointabilities::serializePointabilityType(std::ostream &os, PointabilityType pointable_type)
  36. {
  37. writeU8(os, static_cast<u8>(pointable_type));
  38. }
  39. std::string Pointabilities::toStringPointabilityType(PointabilityType pointable_type)
  40. {
  41. switch(pointable_type) {
  42. case PointabilityType::POINTABLE:
  43. return "true";
  44. case PointabilityType::POINTABLE_NOT:
  45. return "false";
  46. case PointabilityType::POINTABLE_BLOCKING:
  47. return "\"blocking\"";
  48. }
  49. return "unknown";
  50. }
  51. std::optional<PointabilityType> Pointabilities::matchNode(const std::string &name,
  52. const ItemGroupList &groups) const
  53. {
  54. auto i = nodes.find(name);
  55. return i == nodes.end() ? matchGroups(groups, node_groups) : i->second;
  56. }
  57. std::optional<PointabilityType> Pointabilities::matchObject(const std::string &name,
  58. const ItemGroupList &groups) const
  59. {
  60. auto i = objects.find(name);
  61. return i == objects.end() ? matchGroups(groups, object_groups) : i->second;
  62. }
  63. std::optional<PointabilityType> Pointabilities::matchPlayer(const ItemGroupList &groups) const
  64. {
  65. return matchGroups(groups, object_groups);
  66. }
  67. std::optional<PointabilityType> Pointabilities::matchGroups(const ItemGroupList &groups,
  68. const std::unordered_map<std::string, PointabilityType> &pointable_groups)
  69. {
  70. // prefers POINTABLE over POINTABLE_NOT over POINTABLE_BLOCKING
  71. bool blocking = false;
  72. bool not_pointable = false;
  73. for (auto const &ability : pointable_groups) {
  74. if (itemgroup_get(groups, ability.first) > 0) {
  75. switch(ability.second) {
  76. case PointabilityType::POINTABLE:
  77. return PointabilityType::POINTABLE;
  78. case PointabilityType::POINTABLE_NOT:
  79. not_pointable = true;
  80. break;
  81. default:
  82. blocking = true;
  83. break;
  84. }
  85. }
  86. }
  87. if (not_pointable)
  88. return PointabilityType::POINTABLE_NOT;
  89. if (blocking)
  90. return PointabilityType::POINTABLE_BLOCKING;
  91. return std::nullopt;
  92. }
  93. void Pointabilities::serializeTypeMap(std::ostream &os,
  94. const std::unordered_map<std::string, PointabilityType> &map)
  95. {
  96. writeU32(os, map.size());
  97. for (const auto &entry : map) {
  98. os << serializeString16(entry.first);
  99. writeU8(os, (u8)entry.second);
  100. }
  101. }
  102. void Pointabilities::deSerializeTypeMap(std::istream &is,
  103. std::unordered_map<std::string, PointabilityType> &map)
  104. {
  105. map.clear();
  106. u32 size = readU32(is);
  107. for (u32 i = 0; i < size; i++) {
  108. std::string name = deSerializeString16(is);
  109. PointabilityType type = Pointabilities::deSerializePointabilityType(is);
  110. map[name] = type;
  111. }
  112. }
  113. void Pointabilities::serialize(std::ostream &os) const
  114. {
  115. writeU8(os, 0); // version
  116. serializeTypeMap(os, nodes);
  117. serializeTypeMap(os, node_groups);
  118. serializeTypeMap(os, objects);
  119. serializeTypeMap(os, object_groups);
  120. }
  121. void Pointabilities::deSerialize(std::istream &is)
  122. {
  123. int version = readU8(is);
  124. if (version != 0)
  125. throw SerializationError("unsupported Pointabilities version");
  126. deSerializeTypeMap(is, nodes);
  127. deSerializeTypeMap(is, node_groups);
  128. deSerializeTypeMap(is, objects);
  129. deSerializeTypeMap(is, object_groups);
  130. }