diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 4d8390dce8..005cc8a4d8 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -9390,6 +9390,9 @@ Note: 'bg_reserve' and 'bg_unbook' prevent the Battlegrounds queue from joining Same as 'bg_leave' but slaps the player with a deserter status so they can't enter another queue for the time defined in battleground_db (10 minutes by default). +With the Battleground Queue System, it will also warp the player to their previous position when they joined or +to their save point if the map had MF_NOSAVE. + --------------------------------------- *bg_warp ,"",,; @@ -9451,6 +9454,9 @@ OnTimer1000: Removes attached player from their Battle Group. +With the Battleground Queue System, it will also warp the player to their previous position when they joined or +to their save point if the map had MF_NOSAVE. + --------------------------------------- *bg_destroy ; diff --git a/npc/battleground/flavius/flavius01.txt b/npc/battleground/flavius/flavius01.txt index af61c09a46..e4f7c93420 100644 --- a/npc/battleground/flavius/flavius01.txt +++ b/npc/battleground/flavius/flavius01.txt @@ -538,7 +538,8 @@ bat_b01,10,294,3 script Vintenar#bat_b01_aover 419,{ close; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: @@ -562,7 +563,8 @@ bat_b01,389,14,3 script Vintenar#bat_b01_bover 415,{ close; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: diff --git a/npc/battleground/flavius/flavius02.txt b/npc/battleground/flavius/flavius02.txt index 29ffe62d3a..c99bef9d34 100644 --- a/npc/battleground/flavius/flavius02.txt +++ b/npc/battleground/flavius/flavius02.txt @@ -539,7 +539,8 @@ bat_b02,10,294,3 script Vintenar#bat_b02_aover 419,{ close; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: @@ -563,7 +564,8 @@ bat_b02,389,14,3 script Vintenar#bat_b02_bover 415,{ close; } bg_leave; - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; end; OnInit: diff --git a/npc/battleground/kvm/kvm02.txt b/npc/battleground/kvm/kvm02.txt index 1d90b7d80c..97a15be08d 100644 --- a/npc/battleground/kvm/kvm02.txt +++ b/npc/battleground/kvm/kvm02.txt @@ -375,8 +375,8 @@ bat_c02,51,130,5 script KVM Officer#KVM02A 419,{ set Bat_Team,0; if (!getbattleflag("feature.bgqueue")) warp "bat_room",154,150; - end; } + end; } bat_c02,148,53,1 duplicate(KVM Officer#KVM02A) KVM Officer#KVM02B 415 diff --git a/npc/battleground/kvm/kvm03.txt b/npc/battleground/kvm/kvm03.txt index ea6bfe80f1..6e15648916 100644 --- a/npc/battleground/kvm/kvm03.txt +++ b/npc/battleground/kvm/kvm03.txt @@ -374,8 +374,8 @@ bat_c03,51,130,5 script KVM Officer#KVM03A 419,{ } bg_leave; set Bat_Team,0; - if (!getbattleflag("feature.bgqueue")) - warp "bat_room",154,150; + if (!getbattleflag("feature.bgqueue")) + warp "bat_room",154,150; } end; } diff --git a/npc/battleground/tierra/tierra02.txt b/npc/battleground/tierra/tierra02.txt index 3a00008ca9..a7ebd1798e 100644 --- a/npc/battleground/tierra/tierra02.txt +++ b/npc/battleground/tierra/tierra02.txt @@ -723,7 +723,7 @@ bat_a02,45,19,3 script Croix Vintenar#a02_b 415,{ callfunc "F_BG_Badge",1,"Croix","Tierra"; } bg_leave; - if (getbattleflag("feature.bgqueue")) + if (!getbattleflag("feature.bgqueue")) warp "bat_room",154,150; end; diff --git a/src/map/battleground.cpp b/src/map/battleground.cpp index 760afa2e82..71bb9b236f 100644 --- a/src/map/battleground.cpp +++ b/src/map/battleground.cpp @@ -420,22 +420,26 @@ int bg_team_leave(struct map_session_data *sd, bool quit, bool deserter) sd->bg_id = 0; if (bgteam) { - char output[CHAT_SIZE_MAX]; - int i; + // Warping members out only applies to the Battleground Queue System + if (battle_config.feature_bgqueue) { + auto member = bgteam->members.begin(); - ARR_FIND(0, bgteam->members.size(), i, bgteam->members[i].sd == sd); - if (i < bgteam->members.size()) { // Removes member from BG - if (bgteam->members[i].entry_point.map != 0) { - int16 map_id = map_mapindex2mapid(bgteam->members[i].entry_point.map); + while (member != bgteam->members.end()) { + if (member->sd == sd && member->entry_point.map != 0) { + if (!map_getmapflag(map_mapindex2mapid(member->entry_point.map), MF_NOSAVE)) + pc_setpos(sd, member->entry_point.map, member->entry_point.x, member->entry_point.y, CLR_TELEPORT); + else + pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); // Warp to save point if the entry map has no save flag. - if (!map_getmapflag(map_id, MF_NOSAVE)) - pc_setpos(sd, bgteam->members[i].entry_point.map, bgteam->members[i].entry_point.x, bgteam->members[i].entry_point.y, CLR_TELEPORT); - else - pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); // Warp to save point if the entry map has no save flag. + bgteam->members.erase(member); + break; + } else + member++; } - util::erase_at(bgteam->members, i); } + char output[CHAT_SIZE_MAX]; + if (quit) sprintf(output, "Server: %s has quit the game...", sd->status.name); else @@ -681,7 +685,9 @@ static TIMER_FUNC(bg_on_ready_start) nullpo_retr(1, queue); - bg_queue_start_battleground(std::shared_ptr(queue)); + queue->tid_start = INVALID_TIMER; + bg_queue_start_battleground(queue); + return 0; } @@ -794,154 +800,25 @@ bool bg_queue_reservation(const char *name, bool state) return false; } -/** - * Initialize a Battleground queue - * @param bg_id: Battleground ID - * @param req_players: Required amount of players - * @return s_battleground_queue* - */ -std::shared_ptr bg_queue_create(int bg_id, int req_players) -{ - auto queue = std::make_shared(); - - queue->id = bg_id; - queue->required_players = req_players; - queue->accepted_players = 0; - queue->tid_expire = INVALID_TIMER; - queue->tid_start = INVALID_TIMER; - queue->tid_requeue = INVALID_TIMER; - queue->in_ready_state = false; - - return queue; -} - -/** - * Allow a player to join a Battleground queue - * @param name: Battleground name - * @param sd: Player data - * @return @see e_bg_queue_apply_ack - */ -e_bg_queue_apply_ack bg_queue_join(const char *name, struct map_session_data *sd) -{ - if (!sd) { - ShowError("bg_queue_join: Tried to join non-existent player.\n."); - return BG_APPLY_NONE; - } - - if (!bg_queue_check_status(sd, name)) - return BG_APPLY_NONE; - - if (bg_player_is_in_bg_map(sd)) { - clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], msg_txt(sd, 337), false, SELF); // You may not join a battleground queue when you're in a battleground map. - return BG_APPLY_NONE; - } - - std::shared_ptr bg = bg_search_name(name); - - if (!bg) { - ShowWarning("bq_queue_join: Could not find battleground \"%s\" requested by %s (AID: %d / CID: %d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id); - return BG_APPLY_INVALID_NAME; - } - - if (bg->min_lvl && sd->status.base_level < bg->min_lvl) - return BG_APPLY_PLAYER_LEVEL; // Level too low - - if (bg->max_lvl && sd->status.base_level > bg->max_lvl) - return BG_APPLY_PLAYER_LEVEL; // Level too high - - std::shared_ptr queue; - bool r; - - if (bg_queues.empty()) { - r = rnd() % 2 != 0; - - queue = bg_queue_create(bg->id, bg->required_players); - - if (!r) - queue->teama_members.push_back(sd); - else - queue->teamb_members.push_back(sd); - - sd->bg_queue = queue; - bg_queues.insert(bg_queues.begin(), queue); - return BG_APPLY_ACCEPT; - } else { - r = rnd() % 2 != 0; - - for (const auto &it : bg_queues) { - try { - queue = it; - } catch (std::out_of_range &) { - continue; - } - - if (queue->in_ready_state) - continue; - if (!r) { - if (queue->teama_members.size() != queue->required_players) { - sd->bg_queue = queue; - queue->teama_members.push_back(sd); - - if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined - bg_queue_on_ready(name, queue); - return BG_APPLY_ACCEPT; - } else if (queue->teamb_members.size() != queue->required_players) { - sd->bg_queue = queue; - queue->teamb_members.push_back(sd); - - if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined - bg_queue_on_ready(name, queue); - return BG_APPLY_ACCEPT; - } - } else { - if (queue->teamb_members.size() != queue->required_players) { - sd->bg_queue = queue; - queue->teamb_members.push_back(sd); - - if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined - bg_queue_on_ready(name, queue); - return BG_APPLY_ACCEPT; - } else if (queue->teama_members.size() != queue->required_players) { - sd->bg_queue = queue; - queue->teama_members.push_back(sd); - - if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined - bg_queue_on_ready(name, queue); - return BG_APPLY_ACCEPT; - } - } - } - } - - queue = bg_queue_create(bg->id, bg->required_players); - r = rnd() % 2 != 0; - - if (!r) - queue->teama_members.push_back(sd); - else - queue->teamb_members.push_back(sd); - - sd->bg_queue = queue; - bg_queues.insert(bg_queues.begin(), queue); - return BG_APPLY_ACCEPT; -} - /** * Join a party onto the same side of a Battleground * @param name: Battleground name * @param sd: Player who requested to join the battlegrounds - * @return @see e_bg_queue_apply_ack */ -e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_data *sd) +void bg_queue_join_party(const char *name, struct map_session_data *sd) { struct party_data *p = party_search(sd->status.party_id); - if (!p) - return BG_APPLY_INVALID_APP; // Someone has bypassed the client check for being in a party + if (!p) { + clif_bg_queue_apply_result(BG_APPLY_INVALID_APP, name, sd); + return; // Someone has bypassed the client check for being in a party + } for (const auto &it : p->party.member) { - if (it.leader && sd->status.char_id != it.char_id) - return BG_APPLY_PARTYGUILD_LEADER; // Not the party leader + if (it.leader && sd->status.char_id != it.char_id) { + clif_bg_queue_apply_result(BG_APPLY_PARTYGUILD_LEADER, name, sd); + return; // Not the party leader + } } std::shared_ptr bg = bg_search_name(name); @@ -954,8 +831,10 @@ e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_da p_online++; } - if (p_online > bg->max_players) - return BG_APPLY_PLAYER_COUNT; // Too many party members online + if (p_online > bg->max_players) { + clif_bg_queue_apply_result(BG_APPLY_PLAYER_COUNT, name, sd); + return; // Too many party members online + } std::vector list; @@ -971,10 +850,11 @@ e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_da } } - return bg_queue_join_multi(name, sd, list); // Join as party, all on the same side of the BG + bg_queue_join_multi(name, sd, list); // Join as party, all on the same side of the BG } else { ShowWarning("clif_parse_bg_queue_apply_request: Could not find Battleground: \"%s\" requested by player: %s (AID:%d CID:%d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id); - return BG_APPLY_INVALID_NAME; // Invalid BG name + clif_bg_queue_apply_result(BG_APPLY_INVALID_NAME, name, sd); + return; // Invalid BG name } } @@ -982,30 +862,29 @@ e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_da * Join a guild onto the same side of a Battleground * @param name: Battleground name * @param sd: Player who requested to join the battlegrounds - * @return @see e_bg_queue_apply_ack */ -e_bg_queue_apply_ack bg_queue_join_guild(const char *name, struct map_session_data *sd) +void bg_queue_join_guild(const char *name, struct map_session_data *sd) { - if (!sd->guild) - return BG_APPLY_INVALID_APP; // Someone has bypassed the client check for being in a guild + if (!sd->guild) { + clif_bg_queue_apply_result(BG_APPLY_INVALID_APP, name, sd); + return; // Someone has bypassed the client check for being in a guild + } - if (strcmp(sd->status.name, sd->guild->master) != 0) - return BG_APPLY_PARTYGUILD_LEADER; // Not the guild leader + if (strcmp(sd->status.name, sd->guild->master) != 0) { + clif_bg_queue_apply_result(BG_APPLY_PARTYGUILD_LEADER, name, sd); + return; // Not the guild leader + } std::shared_ptr bg = bg_search_name(name); if (bg) { - struct guild *g = guild_search(sd->status.guild_id); - int g_online = 0; + struct guild* g = sd->guild; - for (const auto &it : g->member) { - if (it.online) - g_online++; + if (g->connect_member > bg->max_players) { + clif_bg_queue_apply_result(BG_APPLY_PLAYER_COUNT, name, sd); + return; // Too many guild members online } - if (g_online > bg->max_players) - return BG_APPLY_PLAYER_COUNT; // Too many guild members online - std::vector list; for (const auto &it : g->member) { @@ -1020,10 +899,11 @@ e_bg_queue_apply_ack bg_queue_join_guild(const char *name, struct map_session_da } } - return bg_queue_join_multi(name, sd, list); // Join as guild, all on the same side of the BG + bg_queue_join_multi(name, sd, list); // Join as guild, all on the same side of the BG } else { ShowWarning("clif_parse_bg_queue_apply_request: Could not find Battleground: \"%s\" requested by player: %s (AID:%d CID:%d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id); - return BG_APPLY_INVALID_NAME; // Invalid BG name + clif_bg_queue_apply_result(BG_APPLY_INVALID_NAME, name, sd); + return; // Invalid BG name } } @@ -1032,186 +912,102 @@ e_bg_queue_apply_ack bg_queue_join_guild(const char *name, struct map_session_da * @param name: Battleground name * @param sd: Player who requested to join the battlegrounds * @param list: Contains all players including the player who requested to join - * @return @see e_bg_queue_apply_ack */ -e_bg_queue_apply_ack bg_queue_join_multi(const char *name, struct map_session_data *sd, std::vector list) +void bg_queue_join_multi(const char *name, struct map_session_data *sd, std::vector list) { if (!sd) { ShowError("bg_queue_join_multi: Tried to join non-existent player\n."); - return BG_APPLY_NONE; - } - - if (!bg_queue_check_status(sd, name)) - return BG_APPLY_NONE; - - if (bg_player_is_in_bg_map(sd)) { - clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], msg_txt(sd, 337), false, SELF); // You may not join a battleground queue when you're in a battleground map. - return BG_APPLY_NONE; + return; } std::shared_ptr bg = bg_search_name(name); if (!bg) { ShowWarning("bq_queue_join_multi: Could not find battleground \"%s\" requested by %s (AID: %d / CID: %d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id); - return BG_APPLY_INVALID_NAME; + return; } - if (bg->min_lvl && sd->status.base_level < bg->min_lvl) - return BG_APPLY_PLAYER_LEVEL; // Level too low - - if (bg->max_lvl && sd->status.base_level > bg->max_lvl) - return BG_APPLY_PLAYER_LEVEL; // Level too high - - if (bg_queues.empty()) { - std::shared_ptr queue = bg_queue_create(bg->id, bg->required_players); - bool r = rnd() % 2 != 0; - - if (!r) { - while (!list.empty() && queue->teama_members.size() < bg->required_players) { - struct map_session_data *sd2 = list.back(); - - list.pop_back(); - - if (!sd2 || sd2->bg_queue) - continue; - - if (!bg_queue_check_joinable(bg, sd2, name)) - continue; - - sd2->bg_queue = queue; - clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); - clif_bg_queue_apply_notify(name, sd2); - queue->teama_members.insert(queue->teama_members.begin(), sd2); - } - } else { - while (!list.empty() && queue->teamb_members.size() < bg->required_players) { - struct map_session_data *sd2 = list.back(); - - list.pop_back(); - - if (!sd2 || sd2->bg_queue) - continue; - - if (!bg_queue_check_joinable(bg, sd2, name)) - continue; - - sd2->bg_queue = queue; - clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); - clif_bg_queue_apply_notify(name, sd2); - queue->teamb_members.insert(queue->teamb_members.begin(), sd2); - } - } - - bg_queues.insert(bg_queues.begin(), queue); - - return BG_APPLY_ACCEPT; - } else { - std::shared_ptr queue; - bool r = rnd() % 2 != 0; - - for (const auto &it : bg_queues) { - try { - queue = it; - } catch (std::out_of_range &) { - continue; - } - - if (queue->in_ready_state) - continue; - - if (queue->teama_members.size() + list.size() <= bg->required_players || queue->teamb_members.size() + list.size() <= bg->required_players) { // Make sure there's enough space on one side to join as a party/guild in this queue - if (!r && queue->teama_members.size() + list.size() <= bg->required_players) { - while (!list.empty() && queue->teama_members.size() < bg->required_players) { - struct map_session_data *sd2 = list.back(); - - list.pop_back(); - - if (!sd2 || sd2->bg_queue) - continue; - - if (!bg_queue_check_joinable(bg, sd2, name)) - continue; - - sd2->bg_queue = queue; - clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); - clif_bg_queue_apply_notify(name, sd2); - queue->teama_members.insert(queue->teama_members.begin(), sd2); - } - - if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined - bg_queue_on_ready(name, queue); - - return BG_APPLY_ACCEPT; - } else { - while (!list.empty() && queue->teamb_members.size() < bg->required_players) { - struct map_session_data *sd2 = list.back(); - - list.pop_back(); - - if (!sd2) - continue; - - if (!bg_queue_check_joinable(bg, sd2, name)) - continue; - - sd2->bg_queue = queue; - clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); - clif_bg_queue_apply_notify(name, sd2); - queue->teamb_members.insert(queue->teamb_members.begin(), sd2); - } - } - - return BG_APPLY_ACCEPT; - } - } - - // Create a new queue if none of the existing ones are joinable for this party/guild - queue = nullptr; - queue = bg_queue_create(bg->id, bg->required_players); - r = rnd() % 2 != 0; - - if (!r) { - while (!list.empty() && queue->teama_members.size() < bg->required_players) { - struct map_session_data *sd2 = list.back(); - - list.pop_back(); - - if (!sd2 || sd2->bg_queue) - continue; - - if (!bg_queue_check_joinable(bg, sd2, name)) - continue; - - sd2->bg_queue = queue; - clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); - clif_bg_queue_apply_notify(name, sd2); - queue->teama_members.insert(queue->teama_members.begin(), sd2); - } - } else { - while (!list.empty() && queue->teamb_members.size() < bg->required_players) { - struct map_session_data *sd2 = list.back(); - - list.pop_back(); - - if (!sd2 || sd2->bg_queue) - continue; - - if (!bg_queue_check_joinable(bg, sd2, name)) - continue; - - sd2->bg_queue = queue; - clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); - clif_bg_queue_apply_notify(name, sd2); - queue->teamb_members.insert(queue->teamb_members.begin(), sd2); - } - } - - bg_queues.insert(bg_queues.begin(), queue); - - return BG_APPLY_ACCEPT; + if (!bg_queue_check_joinable(bg, sd, name)){ + return; } - return BG_APPLY_RECONNECT; // Something went wrong, sends reconnect and then reapply message to client. + for (const auto &queue : bg_queues) { + if (queue->id != bg->id) + continue; + if (queue->in_ready_state) + continue; + + // Make sure there's enough space on one side to join as a party/guild in this queue + if (queue->teama_members.size() + list.size() > bg->required_players && queue->teamb_members.size() + list.size() > bg->required_players) { + break; + } + + bool r = rnd() % 2 != 0; + std::vector* team = r ? &queue->teamb_members : &queue->teama_members; + + // If the designated team is full, put the player into the other team + if (team->size() + list.size() > bg->required_players) { + team = r ? &queue->teama_members : &queue->teamb_members; + } + + while (!list.empty() && team->size() < bg->required_players) { + struct map_session_data *sd2 = list.back(); + + list.pop_back(); + + if (!sd2 || sd2->bg_queue) + continue; + + if (!bg_queue_check_joinable(bg, sd2, name)) + continue; + + sd2->bg_queue = queue; + team->push_back(sd2); + clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2); + clif_bg_queue_apply_notify(name, sd2); + } + + // Enough players have joined + if (queue->teamb_members.size() == bg->required_players && queue->teama_members.size() == bg->required_players) + bg_queue_on_ready(name, queue); + + return; + } + + // Something went wrong, sends reconnect and then reapply message to client. + clif_bg_queue_apply_result(BG_APPLY_RECONNECT, name, sd); +} + +/** + * Clear Battleground queue for next one + * @param queue: Queue to clean up + */ +static void bg_queue_clear(s_battleground_queue *queue) +{ + if (!queue) + return; + + if (queue->tid_requeue != INVALID_TIMER) { + delete_timer(queue->tid_requeue, bg_on_ready_loopback); + queue->tid_requeue = INVALID_TIMER; + } + + if (queue->tid_expire != INVALID_TIMER) { + delete_timer(queue->tid_expire, bg_on_ready_expire); + queue->tid_expire = INVALID_TIMER; + } + + if (queue->tid_start != INVALID_TIMER) { + delete_timer(queue->tid_start, bg_on_ready_start); + queue->tid_start = INVALID_TIMER; + } + + if (queue->map != nullptr) { + queue->map->isReserved = false; // Remove reservation to free up for future queue + queue->map = nullptr; + } + queue->in_ready_state = false; + queue->accepted_players = 0; // Reset the queue count } /** @@ -1238,22 +1034,12 @@ static bool bg_queue_leave_sub(struct map_session_data *sd, std::vectorbg_queue_accept_state = false; } - list_it = lista.erase(list_it); + lista.erase(list_it); if (lista.empty() && listb.empty()) { // If there are no players left in the queue, discard it - auto queue_it = bg_queues.begin(); - - while (queue_it != bg_queues.end()) { - std::shared_ptr q = *queue_it; - - if (sd->bg_queue == q) { - if (q->tid_requeue != INVALID_TIMER && get_timer(q->tid_requeue)) { - delete_timer(q->tid_requeue, bg_on_ready_loopback); - q->tid_requeue = INVALID_TIMER; - } - - queue_it = bg_queues.erase(queue_it); - } + for (auto &queue : bg_queues) { + if (sd->bg_queue == queue) + bg_queue_clear(queue.get()); } } @@ -1349,7 +1135,7 @@ void bg_queue_on_accept_invite(std::shared_ptr queue, stru if (queue->accepted_players == queue->required_players * 2) { queue->tid_start = add_timer(gettick() + battleground_db.find(queue->id)->start_delay * 1000, bg_on_ready_start, 0, (intptr_t)queue.get()); - if (queue->tid_expire != INVALID_TIMER && get_timer(queue->tid_expire)) { + if (queue->tid_expire != INVALID_TIMER) { delete_timer(queue->tid_expire, bg_on_ready_expire); queue->tid_expire = INVALID_TIMER; } @@ -1360,13 +1146,8 @@ void bg_queue_on_accept_invite(std::shared_ptr queue, stru * Begin the Battleground from the given queue * @param queue: Battleground queue */ -void bg_queue_start_battleground(std::shared_ptr queue) +void bg_queue_start_battleground(s_battleground_queue *queue) { - if (queue->tid_start != INVALID_TIMER && get_timer(queue->tid_start)) { - delete_timer(queue->tid_start, bg_on_ready_start); - queue->tid_start = INVALID_TIMER; - } - std::shared_ptr bg = battleground_db.find(queue->id); if (!bg) { @@ -1401,15 +1182,28 @@ void bg_queue_start_battleground(std::shared_ptr queue) queue->teamb_members.clear(); queue->teama_members.shrink_to_fit(); queue->teamb_members.shrink_to_fit(); + bg_queue_clear(queue); +} - auto queue_it = bg_queues.begin(); +/** + * Initialize a Battleground queue + * @param bg_id: Battleground ID + * @param req_players: Required amount of players + * @return s_battleground_queue* + */ +static void bg_queue_create(int bg_id, int req_players) +{ + auto queue = std::make_shared(); - while (queue_it != bg_queues.end()) { - if (*queue_it == queue) - queue_it = bg_queues.erase(queue_it); - } + queue->id = bg_id; + queue->required_players = req_players; + queue->accepted_players = 0; + queue->tid_expire = INVALID_TIMER; + queue->tid_start = INVALID_TIMER; + queue->tid_requeue = INVALID_TIMER; + queue->in_ready_state = false; - return; + bg_queues.push_back(queue); } /** @@ -1417,9 +1211,13 @@ void bg_queue_start_battleground(std::shared_ptr queue) */ void do_init_battleground(void) { - if (battle_config.feature_bgqueue) + if (battle_config.feature_bgqueue) { battleground_db.load(); + for (const auto &bg : battleground_db) + bg_queue_create(bg.first, bg.second->required_players); + } + add_timer_func_list(bg_send_xy_timer, "bg_send_xy_timer"); add_timer_func_list(bg_on_ready_loopback, "bg_on_ready_loopback"); add_timer_func_list(bg_on_ready_expire, "bg_on_ready_expire"); diff --git a/src/map/battleground.hpp b/src/map/battleground.hpp index b761ada07d..e2377d69bf 100644 --- a/src/map/battleground.hpp +++ b/src/map/battleground.hpp @@ -126,15 +126,13 @@ int bg_team_leave(struct map_session_data *sd, bool quit, bool deserter); bool bg_team_warp(int bg_id, unsigned short mapindex, short x, short y); bool bg_player_is_in_bg_map(struct map_session_data *sd); bool bg_queue_check_joinable(std::shared_ptr bg, struct map_session_data *sd, const char *name); -std::shared_ptr bg_queue_create(int bg_id, int req_players); -e_bg_queue_apply_ack bg_queue_join(const char *name, struct map_session_data *sd); -e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_data *sd); -e_bg_queue_apply_ack bg_queue_join_guild(const char *name, struct map_session_data *sd); -e_bg_queue_apply_ack bg_queue_join_multi(const char *name, struct map_session_data *sd, std::vector list); +void bg_queue_join_party(const char *name, struct map_session_data *sd); +void bg_queue_join_guild(const char *name, struct map_session_data *sd); +void bg_queue_join_multi(const char *name, struct map_session_data *sd, std::vector list); bool bg_queue_leave(struct map_session_data *sd); bool bg_queue_on_ready(const char *name, std::shared_ptr queue); void bg_queue_on_accept_invite(std::shared_ptr queue, struct map_session_data *sd); -void bg_queue_start_battleground(std::shared_ptr queue); +void bg_queue_start_battleground(s_battleground_queue *queue); bool bg_member_respawn(struct map_session_data *sd); void bg_send_message(struct map_session_data *sd, const char *mes, int len); diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 379c12d5d9..74bf7f0715 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -17482,7 +17482,6 @@ void clif_parse_bg_queue_apply_request(int fd, struct map_session_data *sd) short type = RFIFOW(fd,2); char name[NAME_LENGTH]; - e_bg_queue_apply_ack result; safestrncpy(name, RFIFOCP(fd, 4), NAME_LENGTH); @@ -17491,20 +17490,16 @@ void clif_parse_bg_queue_apply_request(int fd, struct map_session_data *sd) clif_bg_queue_apply_result(BG_APPLY_DUPLICATE, name, sd); // Duplicate application warning return; } else if (type == 1) // Solo - result = bg_queue_join(name, sd); + bg_queue_join_multi(name, sd, { sd }); else if (type == 2) // Party - result = bg_queue_join_party(name, sd); + bg_queue_join_party(name, sd); else if (type == 4) // Guild - result = bg_queue_join_guild(name, sd); + bg_queue_join_guild(name, sd); else { ShowWarning("clif_parse_bg_queue_apply_request: Received invalid queue type: %d from player %s (AID:%d CID:%d).\n", type, sd->status.name, sd->status.account_id, sd->status.char_id); clif_bg_queue_apply_result(BG_APPLY_INVALID_APP, name, sd); // Someone sent an invalid queue type packet return; } - - clif_bg_queue_apply_result(result, name, sd); - if (result == BG_APPLY_ACCEPT) - clif_bg_queue_apply_notify(name, sd); } /// Outgoing battlegrounds queue apply result.