inventory_state.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #pragma once
  2. #include <array>
  3. #include <cstddef>
  4. #include <cstdint>
  5. #include <optional>
  6. #include <string_view>
  7. #include "item_state.h"
  8. namespace sunrise::state::account::inventory {
  9. /** Authored equipment exposes every named slot currently represented by State. */
  10. enum class EquipmentSlot : std::uint8_t {
  11. kinetic,
  12. energy,
  13. heavy,
  14. helmet,
  15. gauntlets,
  16. chest,
  17. legs,
  18. classItem,
  19. ghost,
  20. vehicle,
  21. ship,
  22. subclass,
  23. clanBanner,
  24. emblem,
  25. emote,
  26. finisher,
  27. artifact,
  28. count,
  29. };
  30. /** One fixed entry exists for every semantic equipment slot. */
  31. inline constexpr std::size_t kEquipmentSlotCount = static_cast<std::size_t>(EquipmentSlot::count);
  32. /** An authored item can pick at most 12 ordinary socket lanes. */
  33. inline constexpr std::size_t kPlugCapacity = 12;
  34. /** The engine no-definition hash cannot identify an authored item or plug. */
  35. inline constexpr std::uint32_t kNoDefinitionHash = 0x811C9DC5U;
  36. /** Says whether Middleware uses native socket defaults or authored lanes. */
  37. enum class SocketPolicy : std::uint8_t {
  38. nativeDefaults,
  39. authored,
  40. };
  41. /** Fixed authored socket choices. An empty optional is an explicit empty lane. */
  42. struct Sockets {
  43. SocketPolicy policy{SocketPolicy::nativeDefaults};
  44. std::array<std::optional<std::uint32_t>, kPlugCapacity> plugs{};
  45. std::size_t plugCount{};
  46. };
  47. /** Account-wide stacks can occupy every row of the native 701-row profile inventory. */
  48. inline constexpr std::size_t kProfileItemCapacity = 701;
  49. /** The supported mod and shader profile bucket runs reserve 50 action-source rows each. */
  50. inline constexpr std::size_t kProfileActionSourceCapacity = 100;
  51. /** Runtime-owned SOIDs for profile stacks use a namespace separate from created item instances. */
  52. inline constexpr std::uint64_t kFirstProfileItemInstanceSoid = 0x5000000000000001ULL;
  53. /**
  54. * 151 native rows minus the 16 equipped rows leaves 135 unequipped item rows.
  55. */
  56. inline constexpr std::size_t kCharacterItemCapacity = 135;
  57. /** Runtime-owned non-instanced character stacks. */
  58. inline constexpr std::size_t kCharacterStackCapacity = 32;
  59. /**
  60. * Definition hash of the real, non-equippable "Emotes" collection item. The Client opens its own
  61. * wheel-configuration screen for this exact item once it is equipped with valid socket data.
  62. */
  63. inline constexpr std::uint32_t kEmoteCollectionDefinitionHash = 3183180185U;
  64. /** Ordinary socket lane count the "Emotes" collection item's real content declares. */
  65. inline constexpr std::size_t kEmoteCollectionSocketLaneCount = 4;
  66. /**
  67. * Native equipment slot the "Emotes" collection item is equipped under.
  68. * It is the one character-scoped item whose content declares no slot of its own.
  69. */
  70. inline constexpr std::uint8_t kEmoteCollectionNativeEquipmentSlot =
  71. static_cast<std::uint8_t>(EquipmentSlot::emote);
  72. /**
  73. * Resolves the native equipment slot a configured item detail occupies.
  74. * Only kEmoteCollectionDefinitionHash may fall back to the constant above; any other item with no
  75. * declared slot is rejected rather than aliased onto it.
  76. * @param definitionHash Authored item definition hash being resolved.
  77. * @param detailEquipmentSlot The installed item detail's own native slot, if it declares one.
  78. * @param nativeSlot Receives the resolved native slot on success.
  79. * @return True when the item declares its own non-negative slot, or is the Emotes collection item.
  80. */
  81. [[nodiscard]] bool
  82. resolve_native_equipment_slot(std::uint32_t definitionHash,
  83. const std::optional<std::int8_t>& detailEquipmentSlot,
  84. std::uint8_t& nativeSlot) noexcept;
  85. /** One authored account-wide item, placed by the inventory bucket its definition names. */
  86. struct ProfileItem {
  87. /** Stable runtime identity required to materialize this row as an inventory action source. */
  88. std::uint64_t instanceSoid{};
  89. std::uint32_t definitionHash{};
  90. std::int32_t quantity{};
  91. /** Rising generation copied into the native row and matched by acquisition feedback. */
  92. std::int32_t mutationSerial{};
  93. /** The client has dismissed this item's new-item marker. */
  94. bool seen{};
  95. };
  96. /** One authored equipment item without native table or wire-layout fields. */
  97. struct Item {
  98. std::uint64_t instanceSoid{};
  99. std::uint32_t definitionHash{};
  100. std::int32_t level{};
  101. std::int32_t quantity{};
  102. /**
  103. * Rising per-character generation assigned whenever this item changes inventory rows. The
  104. * Client also orders a bucket's grid by it, so an equip swap hands the displaced item the
  105. * clicked item's prior serial to keep it in the clicked cell.
  106. */
  107. std::int32_t mutationSerial{};
  108. /** Native accumulated item-state bits such as the finisher favorite marker. */
  109. std::uint32_t flags{};
  110. Sockets sockets;
  111. /**
  112. * Selected ability-node socket entries. Only meaningful on a subclass. Kept on the item, not
  113. * the character, so each owned subclass remembers its own picks. Defaults match
  114. * state::kDefault*AbilityEntry, literal here to avoid a circular include.
  115. */
  116. std::uint8_t movementAbilityEntry{4};
  117. std::uint8_t grenadeAbilityEntry{7};
  118. std::uint8_t superAbilityEntry{10};
  119. std::uint8_t meleeAbilityEntry{11};
  120. std::uint8_t classAbilityEntry{2};
  121. /** The client has dismissed this item's new-item marker. */
  122. bool seen{};
  123. };
  124. /** Ordered unequipped items placed into their native character-inventory bucket ranges. */
  125. struct CharacterItems {
  126. std::array<Item, kCharacterItemCapacity> values{};
  127. std::size_t count{};
  128. };
  129. struct CharacterStack {
  130. std::uint32_t definitionHash{};
  131. std::int32_t quantity{};
  132. std::int32_t mutationSerial{};
  133. };
  134. struct CharacterStacks {
  135. std::array<CharacterStack, kCharacterStackCapacity> values{};
  136. std::size_t count{};
  137. };
  138. /** One optional authored item for every semantic equipment slot. */
  139. struct Equipment {
  140. std::array<std::optional<Item>, kEquipmentSlotCount> slots{};
  141. };
  142. /**
  143. * Finds the semantic State slot for one exact JSON equipment name.
  144. * @param name Borrowed case-sensitive equipment name.
  145. * @return Matching slot, or no value for an unknown name.
  146. */
  147. [[nodiscard]] std::optional<EquipmentSlot> slot_from_name(std::string_view name) noexcept;
  148. /**
  149. * Checks the canonical socket policy and every authored plug hash.
  150. * @return True when the policy, count and fixed tail agree.
  151. */
  152. [[nodiscard]] bool valid(const Sockets& sockets) noexcept;
  153. /**
  154. * Checks one whole authored item without reading installed build data.
  155. * @return True when the id, scalar and socket fields are valid.
  156. */
  157. [[nodiscard]] bool valid(const Item& item) noexcept;
  158. /**
  159. * Checks every item present in the fixed semantic equipment array.
  160. * @return True when every used slot holds a whole item.
  161. */
  162. [[nodiscard]] bool valid(const Equipment& equipment) noexcept;
  163. /** Checks the used prefix and empty tail of one character's unequipped item array. */
  164. [[nodiscard]] bool valid(const CharacterItems& items) noexcept;
  165. [[nodiscard]] bool valid(const CharacterStacks& items) noexcept;
  166. } // namespace sunrise::state::account::inventory