#pragma once #include #include #include #include #include #include #include "ItemNameIndex.hh" #include "SaveFileFormats.hh" #include "StaticGameData.hh" #include "Text.hh" #include "Version.hh" class TeamIndex { public: struct Team { struct Member { enum class Flag { IS_MASTER = 0x01, IS_LEADER = 0x02, }; uint32_t serial_number = 0; uint8_t flags = 0; uint64_t points = 0; std::string name; Member() = default; explicit Member(const JSON& json); JSON json() const; [[nodiscard]] inline bool check_flag(Flag flag) const { return !!(static_cast(flag) & this->flags); } inline void set_flag(Flag flag) { this->flags |= static_cast(flag); } inline void clear_flag(Flag flag) { this->flags &= (~static_cast(flag)); } uint32_t privilege_level() const; }; enum class RewardFlag { // Only 0x00000001 and 0x00000002 are used by the client; the rest are // free to be used however the server chooses. NONE = 0x00000000, TEAM_FLAG = 0x00000001, DRESSING_ROOM = 0x00000002, MEMBERS_20_LEADERS_3 = 0x00000004, MEMBERS_40_LEADERS_5 = 0x00000008, MEMBERS_70_LEADERS_8 = 0x00000010, MEMBERS_100_LEADERS_10 = 0x00000020, }; uint32_t team_id = 0; uint32_t points = 0; uint32_t spent_points = 0; std::string name; uint32_t master_serial_number = 0; std::unordered_map members; uint32_t reward_flags = 0; std::unordered_set reward_keys; std::shared_ptr> flag_data; Team() = default; explicit Team(uint32_t team_id); JSON json() const; std::string json_filename() const; std::string flag_filename() const; void load_config(); void save_config() const; void load_flag(); void save_flag() const; void delete_files() const; PSOBBTeamMembership membership_for_member(uint32_t serial_number) const; [[nodiscard]] inline bool check_reward_flag(RewardFlag flag) const { return !!(static_cast(flag) & this->reward_flags); } inline void set_reward_flag(RewardFlag flag) { this->reward_flags |= static_cast(flag); } inline void clear_reward_flag(RewardFlag flag) { this->reward_flags &= (~static_cast(flag)); } [[nodiscard]] bool has_reward(const std::string& key) const; size_t num_members() const; size_t num_leaders() const; size_t max_members() const; size_t max_leaders() const; bool can_add_member() const; bool can_promote_leader() const; }; struct Reward { uint32_t menu_item_id = 0; std::string key; std::string name; std::string description; std::unordered_set prerequisite_keys; bool is_unique = true; uint32_t team_points = 0; Team::RewardFlag reward_flag = Team::RewardFlag::NONE; ItemData reward_item; Reward(uint32_t menu_item_id, const JSON& def_json); }; TeamIndex(const std::string& directory, const JSON& reward_defs_json); ~TeamIndex() = default; inline const std::vector& reward_definitions() const { return this->reward_defs; } size_t count() const; std::shared_ptr get_by_id(uint32_t team_id) const; std::shared_ptr get_by_name(const std::string& name) const; std::shared_ptr get_by_serial_number(uint32_t serial_number) const; std::vector> all() const; std::shared_ptr create(const std::string& name, uint32_t master_serial_number, const std::string& master_name); void disband(uint32_t team_id); void rename(uint32_t team_id, const std::string& new_name); void add_member(uint32_t team_id, uint32_t serial_number, const std::string& name); void remove_member(uint32_t serial_number); void update_member_name(uint32_t serial_number, const std::string& name); void add_member_points(uint32_t serial_number, uint32_t points); void set_flag_data(uint32_t team_id, const parray& flag_data); bool promote_leader(uint32_t master_serial_number, uint32_t leader_serial_number); bool demote_leader(uint32_t master_serial_number, uint32_t leader_serial_number); void change_master(uint32_t master_serial_number, uint32_t new_master_serial_number); void buy_reward(uint32_t team_id, const std::string& key, uint32_t points, Team::RewardFlag reward_flag); protected: std::string directory; uint32_t next_team_id; std::unordered_map> id_to_team; std::unordered_map> name_to_team; std::unordered_map> serial_number_to_team; std::vector reward_defs; void add_to_indexes(std::shared_ptr team); void remove_from_indexes(std::shared_ptr team); };