#pragma once #include #include #include #include #include #include #include #include #include "Client.hh" #include "Episode3/BattleRecord.hh" #include "Episode3/Server.hh" #include "ItemCreator.hh" #include "Map.hh" #include "Player.hh" #include "Quest.hh" #include "RareItemSet.hh" #include "StaticGameData.hh" #include "Text.hh" struct Lobby : public std::enable_shared_from_this { enum Flag { GAME = 0x00000001, NON_V1_ONLY = 0x00000002, // DC NTE and DCv1 not allowed PERSISTENT = 0x00000004, // Flags used only for games CHEATS_ENABLED = 0x00000100, QUEST_IN_PROGRESS = 0x00000200, BATTLE_IN_PROGRESS = 0x00000400, JOINABLE_QUEST_IN_PROGRESS = 0x00000800, ITEM_TRACKING_ENABLED = 0x00001000, IS_SPECTATOR_TEAM = 0x00002000, // episode must be EP3 also SPECTATORS_FORBIDDEN = 0x00004000, START_BATTLE_PLAYER_IMMEDIATELY = 0x00008000, DROPS_ENABLED = 0x00010000, // Does not affect BB // Flags used only for lobbies PUBLIC = 0x01000000, DEFAULT = 0x02000000, }; PrefixedLogger log; uint32_t lobby_id; uint32_t min_level; uint32_t max_level; // Item info struct FloorItem { PlayerInventoryItem inv_item; float x; float z; uint8_t area; }; std::shared_ptr map; std::array next_item_id; uint32_t next_game_item_id; std::unordered_map item_id_to_floor_item; parray variations; // Game config GameVersion version; uint8_t section_id; Episode episode; GameMode mode; uint8_t difficulty; // 0-3 uint16_t exp_multiplier; std::u16string password; std::u16string name; // This seed is also sent to the client for rare enemy generation uint32_t random_seed; std::shared_ptr random_crypt; std::shared_ptr item_creator; // Ep3 stuff // There are three kinds of Episode 3 games. All of these types have the flag // EPISODE_3_ONLY; types 2 and 3 additionally have the IS_SPECTATOR_TEAM flag. // 1. Primary games. These are the lobbies where battles may take place. // 2. Watcher games. These lobbies receive all the battle and chat commands // from a primary game. (This the implementation of spectator teams.) // 3. Replay games. These lobbies replay a sequence of battle commands and // chat commands from a previous primary game. // Types 2 and 3 may be distinguished by the presence of the battle_record // field - in replay games, it will be present; in watcher games it will be // absent. std::shared_ptr ep3_server_base; // Only used in primary games std::weak_ptr watched_lobby; // Only used in watcher games std::unordered_set> watcher_lobbies; // Only used in primary games std::shared_ptr battle_record; // Not used in watcher games std::shared_ptr prev_battle_record; // Only used in primary games std::shared_ptr battle_player; // Only used in replay games std::shared_ptr tournament_match; // Lobby stuff uint8_t event; uint8_t block; uint8_t type; // number to give to PSO for the lobby number uint8_t leader_id; uint8_t max_clients; uint32_t flags; std::shared_ptr quest; std::array, 12> clients; // Keys in this map are client_id std::unordered_map> clients_to_add; explicit Lobby(uint32_t id); inline bool is_game() const { return this->flags & Flag::GAME; } inline bool is_ep3() const { return this->episode == Episode::EP3; } void reassign_leader_on_client_departure(size_t leaving_client_id); size_t count_clients() const; bool any_client_loading() const; void add_client(std::shared_ptr c, ssize_t required_client_id = -1); void remove_client(std::shared_ptr c); void move_client_to_lobby( std::shared_ptr dest_lobby, std::shared_ptr c, ssize_t required_client_id = -1); std::shared_ptr find_client( const std::u16string* identifier = nullptr, uint64_t serial_number = 0); void add_item(const PlayerInventoryItem& item, uint8_t area, float x, float z); PlayerInventoryItem remove_item(uint32_t item_id); size_t find_item(uint32_t item_id); uint32_t generate_item_id(uint8_t client_id); static uint8_t game_event_for_lobby_event(uint8_t lobby_event); std::unordered_map> clients_by_serial_number() const; };