mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-03 02:53:48 +00:00
feat(Core/Arena): Add support for arena seasons completion with progression in runtime. (#19858)
Co-authored-by: Winfidonarleyan <dowlandtop@yandex.com>
This commit is contained in:
committed by
GitHub
parent
24dd7dfc21
commit
f6a0433297
@@ -3789,21 +3789,6 @@ Arena.QueueAnnouncer.PlayerOnly = 0
|
||||
|
||||
Arena.QueueAnnouncer.Detail = 3
|
||||
|
||||
#
|
||||
# Arena.ArenaSeason.ID
|
||||
# Description: Current arena season id shown in clients.
|
||||
# Default: 8
|
||||
|
||||
Arena.ArenaSeason.ID = 8
|
||||
|
||||
#
|
||||
# Arena.ArenaSeason.InProgress
|
||||
# Description: State of current arena season.
|
||||
# Default: 1 - (Active)
|
||||
# 0 - (Finished)
|
||||
|
||||
Arena.ArenaSeason.InProgress = 1
|
||||
|
||||
#
|
||||
# Arena.ArenaStartRating
|
||||
# Description: Start rating for new arena teams.
|
||||
|
||||
224
src/server/game/Battlegrounds/ArenaSeason/ArenaSeasonMgr.cpp
Normal file
224
src/server/game/Battlegrounds/ArenaSeason/ArenaSeasonMgr.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ArenaSeasonMgr.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "ArenaSeasonRewardsDistributor.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "MapMgr.h"
|
||||
#include "Player.h"
|
||||
|
||||
ArenaSeasonMgr* ArenaSeasonMgr::instance()
|
||||
{
|
||||
static ArenaSeasonMgr instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
void ArenaSeasonMgr::LoadRewards()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
std::unordered_map<std::string, ArenaSeasonRewardGroupCriteriaType> stringToArenaSeasonRewardGroupCriteriaType = {
|
||||
{"pct", ArenaSeasonRewardGroupCriteriaType::ARENA_SEASON_REWARD_CRITERIA_TYPE_PERCENT_VALUE},
|
||||
{"abs", ArenaSeasonRewardGroupCriteriaType::ARENA_SEASON_REWARD_CRITERIA_TYPE_ABSOLUTE_VALUE}
|
||||
};
|
||||
|
||||
QueryResult result = WorldDatabase.Query("SELECT id, arena_season, criteria_type, min_criteria, max_criteria, reward_mail_template_id, reward_mail_subject, reward_mail_body, gold_reward FROM arena_season_reward_group");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
LOG_WARN("server.loading", ">> Loaded 0 arena season rewards. DB table `arena_season_reward_group` is empty.");
|
||||
LOG_INFO("server.loading", " ");
|
||||
return;
|
||||
}
|
||||
|
||||
std::unordered_map<uint32, ArenaSeasonRewardGroup> groupsMap;
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 id = fields[0].Get<uint32>();
|
||||
|
||||
ArenaSeasonRewardGroup group;
|
||||
group.season = fields[1].Get<uint8>();
|
||||
group.criteriaType = stringToArenaSeasonRewardGroupCriteriaType[fields[2].Get<std::string>()];
|
||||
group.minCriteria = fields[3].Get<float>();
|
||||
group.maxCriteria = fields[4].Get<float>();
|
||||
group.rewardMailTemplateID = fields[5].Get<uint32>();
|
||||
group.rewardMailSubject = fields[6].Get<std::string>();
|
||||
group.rewardMailBody = fields[7].Get<std::string>();
|
||||
group.goldReward = fields[8].Get<uint32>();
|
||||
|
||||
groupsMap[id] = group;
|
||||
} while (result->NextRow());
|
||||
|
||||
std::unordered_map<std::string, ArenaSeasonRewardType> stringToArenaSeasonRewardType = {
|
||||
{"achievement", ArenaSeasonRewardType::ARENA_SEASON_REWARD_TYPE_ACHIEVEMENT},
|
||||
{"item", ArenaSeasonRewardType::ARENA_SEASON_REWARD_TYPE_ITEM}
|
||||
};
|
||||
|
||||
result = WorldDatabase.Query("SELECT group_id, type, entry FROM arena_season_reward");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
LOG_WARN("server.loading", ">> Loaded 0 arena season rewards. DB table `arena_season_reward` is empty.");
|
||||
LOG_INFO("server.loading", " ");
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 groupId = fields[0].Get<uint32>();
|
||||
|
||||
ArenaSeasonReward reward;
|
||||
reward.type = stringToArenaSeasonRewardType[fields[1].Get<std::string>()];
|
||||
reward.entry = fields[2].Get<uint32>();
|
||||
|
||||
auto itr = groupsMap.find(groupId);
|
||||
ASSERT(itr != groupsMap.end(), "Unknown arena_season_reward_group ({}) in arena_season_reward", groupId);
|
||||
|
||||
(reward.type == ARENA_SEASON_REWARD_TYPE_ITEM) ?
|
||||
groupsMap[groupId].itemRewards.push_back(reward) :
|
||||
groupsMap[groupId].achievementRewards.push_back(reward);
|
||||
|
||||
} while (result->NextRow());
|
||||
|
||||
for (auto const& itr : groupsMap)
|
||||
_arenaSeasonRewardGroupsStore[itr.second.season].push_back(itr.second);
|
||||
|
||||
LOG_INFO("server.loading", ">> Loaded {} arena season rewards in {} ms", (uint32)groupsMap.size(), GetMSTimeDiffToNow(oldMSTime));
|
||||
LOG_INFO("server.loading", " ");
|
||||
}
|
||||
|
||||
void ArenaSeasonMgr::LoadActiveSeason()
|
||||
{
|
||||
QueryResult result = CharacterDatabase.Query("SELECT season_id, season_state FROM active_arena_season");
|
||||
ASSERT(result, "active_arena_season can't be empty");
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
_currentSeason = fields[0].Get<uint8>();
|
||||
_currentSeasonState = static_cast<ArenaSeasonState>(fields[1].Get<uint8>());
|
||||
|
||||
uint16 eventID = GameEventForArenaSeason(_currentSeason);
|
||||
sGameEventMgr->StartEvent(eventID, true);
|
||||
|
||||
LOG_INFO("server.loading", "Arena Season {} loaded...", _currentSeason);
|
||||
LOG_INFO("server.loading", " ");
|
||||
}
|
||||
|
||||
void ArenaSeasonMgr::RewardTeamsForTheSeason(std::shared_ptr<ArenaTeamFilter> teamsFilter)
|
||||
{
|
||||
ArenaSeasonTeamRewarderImpl rewarder = ArenaSeasonTeamRewarderImpl();
|
||||
ArenaSeasonRewardDistributor distributor = ArenaSeasonRewardDistributor(&rewarder);
|
||||
std::vector<ArenaSeasonRewardGroup> rewards = _arenaSeasonRewardGroupsStore[GetCurrentSeason()];
|
||||
ArenaTeamMgr::ArenaTeamContainer filteredTeams = teamsFilter->Filter(sArenaTeamMgr->GetArenaTeams());
|
||||
distributor.DistributeRewards(filteredTeams, rewards);
|
||||
}
|
||||
|
||||
bool ArenaSeasonMgr::CanDeleteArenaTeams()
|
||||
{
|
||||
std::vector<ArenaSeasonRewardGroup> rewards = _arenaSeasonRewardGroupsStore[GetCurrentSeason()];
|
||||
if (rewards.empty())
|
||||
return false;
|
||||
|
||||
for (auto const& bg : sBattlegroundMgr->GetActiveBattlegrounds())
|
||||
if (bg->isRated())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArenaSeasonMgr::DeleteArenaTeams()
|
||||
{
|
||||
if (!CanDeleteArenaTeams())
|
||||
return;
|
||||
|
||||
// Cleanup queue first.
|
||||
std::vector<BattlegroundQueueTypeId> arenasQueueTypes = {BATTLEGROUND_QUEUE_2v2, BATTLEGROUND_QUEUE_3v3, BATTLEGROUND_QUEUE_5v5};
|
||||
for (BattlegroundQueueTypeId queueType : arenasQueueTypes)
|
||||
{
|
||||
auto queue = sBattlegroundMgr->GetBattlegroundQueue(queueType);
|
||||
for (auto const& [playerGUID, other] : queue.m_QueuedPlayers)
|
||||
queue.RemovePlayer(playerGUID, true);
|
||||
}
|
||||
|
||||
sArenaTeamMgr->DeleteAllArenaTeams();
|
||||
}
|
||||
|
||||
void ArenaSeasonMgr::ChangeCurrentSeason(uint8 season)
|
||||
{
|
||||
if (_currentSeason == season)
|
||||
return;
|
||||
|
||||
uint16 currentEventID = GameEventForArenaSeason(_currentSeason);
|
||||
sGameEventMgr->StopEvent(currentEventID, true);
|
||||
|
||||
uint16 newEventID = GameEventForArenaSeason(season);
|
||||
sGameEventMgr->StartEvent(newEventID, true);
|
||||
|
||||
_currentSeason = season;
|
||||
_currentSeasonState = ARENA_SEASON_STATE_IN_PROGRESS;
|
||||
|
||||
CharacterDatabase.Execute("UPDATE active_arena_season SET season_id = {}, season_state = {}", _currentSeason, _currentSeasonState);
|
||||
|
||||
BroadcastUpdatedWorldState();
|
||||
}
|
||||
|
||||
void ArenaSeasonMgr::SetSeasonState(ArenaSeasonState state)
|
||||
{
|
||||
if (_currentSeasonState == state)
|
||||
return;
|
||||
|
||||
_currentSeasonState = state;
|
||||
|
||||
CharacterDatabase.Execute("UPDATE active_arena_season SET season_state = {}", _currentSeasonState);
|
||||
|
||||
BroadcastUpdatedWorldState();
|
||||
}
|
||||
|
||||
uint16 ArenaSeasonMgr::GameEventForArenaSeason(uint8 season)
|
||||
{
|
||||
QueryResult result = WorldDatabase.Query("SELECT eventEntry FROM game_event_arena_seasons WHERE season = '{}'", season);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
LOG_ERROR("arenaseasonmgr", "ArenaSeason ({}) must be an existant Arena Season", season);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
return fields[0].Get<uint16>();
|
||||
}
|
||||
|
||||
void ArenaSeasonMgr::BroadcastUpdatedWorldState()
|
||||
{
|
||||
sMapMgr->DoForAllMaps([](Map* map)
|
||||
{
|
||||
// Ignore instanceable maps, players will get a fresh state once they change the map.
|
||||
if (map->Instanceable())
|
||||
return;
|
||||
|
||||
map->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
uint32 currZone, currArea;
|
||||
player->GetZoneAndAreaId(currZone, currArea);
|
||||
player->SendInitWorldStates(currZone, currArea);
|
||||
});
|
||||
});
|
||||
}
|
||||
126
src/server/game/Battlegrounds/ArenaSeason/ArenaSeasonMgr.h
Normal file
126
src/server/game/Battlegrounds/ArenaSeason/ArenaSeasonMgr.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ARENASEASONMGR_H
|
||||
#define _ARENASEASONMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "ArenaTeamFilter.h"
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
enum ArenaSeasonState
|
||||
{
|
||||
ARENA_SEASON_STATE_DISABLED = 0,
|
||||
ARENA_SEASON_STATE_IN_PROGRESS = 1
|
||||
};
|
||||
|
||||
enum ArenaSeasonRewardType
|
||||
{
|
||||
ARENA_SEASON_REWARD_TYPE_ITEM,
|
||||
ARENA_SEASON_REWARD_TYPE_ACHIEVEMENT
|
||||
};
|
||||
|
||||
enum ArenaSeasonRewardGroupCriteriaType
|
||||
{
|
||||
ARENA_SEASON_REWARD_CRITERIA_TYPE_PERCENT_VALUE,
|
||||
ARENA_SEASON_REWARD_CRITERIA_TYPE_ABSOLUTE_VALUE
|
||||
};
|
||||
|
||||
// ArenaSeasonReward represents one reward, it can be an item or achievement.
|
||||
struct ArenaSeasonReward
|
||||
{
|
||||
ArenaSeasonReward() = default;
|
||||
|
||||
// Item or acheivement entry.
|
||||
uint32 entry{};
|
||||
|
||||
ArenaSeasonRewardType type{ARENA_SEASON_REWARD_TYPE_ITEM};
|
||||
|
||||
// Used in unit tests.
|
||||
bool operator==(const ArenaSeasonReward& other) const
|
||||
{
|
||||
return entry == other.entry && type == other.type;
|
||||
}
|
||||
};
|
||||
|
||||
struct ArenaSeasonRewardGroup
|
||||
{
|
||||
ArenaSeasonRewardGroup() = default;
|
||||
|
||||
uint8 season{};
|
||||
|
||||
ArenaSeasonRewardGroupCriteriaType criteriaType;
|
||||
|
||||
float minCriteria{};
|
||||
float maxCriteria{};
|
||||
|
||||
uint32 rewardMailTemplateID{};
|
||||
std::string rewardMailSubject{};
|
||||
std::string rewardMailBody{};
|
||||
uint32 goldReward{};
|
||||
|
||||
std::vector<ArenaSeasonReward> itemRewards;
|
||||
std::vector<ArenaSeasonReward> achievementRewards;
|
||||
|
||||
// Used in unit tests.
|
||||
bool operator==(const ArenaSeasonRewardGroup& other) const
|
||||
{
|
||||
return minCriteria == other.minCriteria &&
|
||||
maxCriteria == other.maxCriteria &&
|
||||
criteriaType == other.criteriaType &&
|
||||
itemRewards == other.itemRewards &&
|
||||
achievementRewards == other.achievementRewards;
|
||||
}
|
||||
};
|
||||
|
||||
class ArenaSeasonMgr
|
||||
{
|
||||
public:
|
||||
static ArenaSeasonMgr* instance();
|
||||
|
||||
using ArenaSeasonRewardGroupsBySeasonContainer = std::unordered_map<uint8, std::vector<ArenaSeasonRewardGroup>>;
|
||||
|
||||
// Loading functions
|
||||
void LoadRewards();
|
||||
void LoadActiveSeason();
|
||||
|
||||
// Season management functions
|
||||
void ChangeCurrentSeason(uint8 season);
|
||||
uint8 GetCurrentSeason() { return _currentSeason; }
|
||||
|
||||
void SetSeasonState(ArenaSeasonState state);
|
||||
ArenaSeasonState GetSeasonState() { return _currentSeasonState; }
|
||||
|
||||
// Season completion functions
|
||||
void RewardTeamsForTheSeason(std::shared_ptr<ArenaTeamFilter> teamsFilter);
|
||||
bool CanDeleteArenaTeams();
|
||||
void DeleteArenaTeams();
|
||||
|
||||
private:
|
||||
uint16 GameEventForArenaSeason(uint8 season);
|
||||
void BroadcastUpdatedWorldState();
|
||||
|
||||
ArenaSeasonRewardGroupsBySeasonContainer _arenaSeasonRewardGroupsStore;
|
||||
|
||||
uint8 _currentSeason{};
|
||||
ArenaSeasonState _currentSeasonState{};
|
||||
};
|
||||
|
||||
#define sArenaSeasonMgr ArenaSeasonMgr::instance()
|
||||
|
||||
#endif // _ARENASEASONMGR_H
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ArenaSeasonRewardsDistributor.h"
|
||||
#include "AchievementMgr.h"
|
||||
#include "CharacterDatabase.h"
|
||||
#include "Mail.h"
|
||||
#include "Player.h"
|
||||
#include <algorithm>
|
||||
|
||||
constexpr float minPctTeamGamesForMemberToGetReward = 30;
|
||||
|
||||
void ArenaSeasonTeamRewarderImpl::RewardTeamWithRewardGroup(ArenaTeam *arenaTeam, const ArenaSeasonRewardGroup &rewardGroup)
|
||||
{
|
||||
RewardWithMail(arenaTeam, rewardGroup);
|
||||
RewardWithAchievements(arenaTeam, rewardGroup);
|
||||
}
|
||||
|
||||
void ArenaSeasonTeamRewarderImpl::RewardWithMail(ArenaTeam* arenaTeam, ArenaSeasonRewardGroup const & rewardGroup)
|
||||
{
|
||||
if (rewardGroup.itemRewards.empty() && rewardGroup.goldReward == 0)
|
||||
return;
|
||||
|
||||
const uint32 npcKingDondSender = 18897;
|
||||
|
||||
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
for (auto const& member : arenaTeam->GetMembers())
|
||||
{
|
||||
uint32 teamSeasonGames = arenaTeam->GetStats().SeasonGames;
|
||||
// Avoid division by zero.
|
||||
if (teamSeasonGames == 0)
|
||||
continue;
|
||||
|
||||
float memberParticipationPercentage = (static_cast<float>(member.SeasonGames) / teamSeasonGames) * 100;
|
||||
if (memberParticipationPercentage < minPctTeamGamesForMemberToGetReward)
|
||||
continue;
|
||||
|
||||
Player* player = ObjectAccessor::FindPlayer(member.Guid);
|
||||
|
||||
auto draft = rewardGroup.rewardMailTemplateID > 0 ?
|
||||
MailDraft(rewardGroup.rewardMailTemplateID, false) :
|
||||
MailDraft(rewardGroup.rewardMailSubject, rewardGroup.rewardMailBody);
|
||||
|
||||
if (rewardGroup.goldReward > 0)
|
||||
draft.AddMoney(rewardGroup.goldReward);
|
||||
|
||||
for (auto const& reward : rewardGroup.itemRewards)
|
||||
if (Item* item = Item::CreateItem(reward.entry, 1))
|
||||
{
|
||||
item->SaveToDB(trans);
|
||||
draft.AddItem(item);
|
||||
}
|
||||
|
||||
draft.SendMailTo(trans, MailReceiver(player, member.Guid.GetCounter()), MailSender(npcKingDondSender));
|
||||
}
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
void ArenaSeasonTeamRewarderImpl::RewardWithAchievements(ArenaTeam* arenaTeam, ArenaSeasonRewardGroup const & rewardGroup)
|
||||
{
|
||||
if (rewardGroup.achievementRewards.empty())
|
||||
return;
|
||||
|
||||
for (auto const& member : arenaTeam->GetMembers())
|
||||
{
|
||||
uint32 teamSeasonGames = arenaTeam->GetStats().SeasonGames;
|
||||
// Avoid division by zero.
|
||||
if (teamSeasonGames == 0)
|
||||
continue;
|
||||
|
||||
float memberParticipationPercentage = (static_cast<float>(member.SeasonGames) / teamSeasonGames) * 100;
|
||||
if (memberParticipationPercentage < minPctTeamGamesForMemberToGetReward)
|
||||
continue;
|
||||
|
||||
Player* player = ObjectAccessor::FindPlayer(member.Guid);
|
||||
for (auto const& reward : rewardGroup.achievementRewards)
|
||||
{
|
||||
AchievementEntry const* achievement = sAchievementStore.LookupEntry(reward.entry);
|
||||
if (!achievement)
|
||||
continue;
|
||||
|
||||
if (player)
|
||||
player->CompletedAchievement(achievement);
|
||||
else
|
||||
sAchievementMgr->CompletedAchievementForOfflinePlayer(member.Guid.GetCounter(), achievement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArenaSeasonRewardDistributor::ArenaSeasonRewardDistributor(ArenaSeasonTeamRewarder* rewarder)
|
||||
: _rewarder(rewarder)
|
||||
{
|
||||
}
|
||||
|
||||
void ArenaSeasonRewardDistributor::DistributeRewards(ArenaTeamMgr::ArenaTeamContainer &arenaTeams, std::vector<ArenaSeasonRewardGroup> &rewardGroups)
|
||||
{
|
||||
std::vector<ArenaTeam*> sortedTeams;
|
||||
sortedTeams.reserve(arenaTeams.size());
|
||||
|
||||
static constexpr uint16 minRequiredGames = 30;
|
||||
|
||||
for (auto const& [id, team] : arenaTeams)
|
||||
if (team->GetStats().SeasonGames >= minRequiredGames)
|
||||
sortedTeams.push_back(team);
|
||||
|
||||
std::sort(sortedTeams.begin(), sortedTeams.end(), [](ArenaTeam* a, ArenaTeam* b) {
|
||||
return a->GetRating() > b->GetRating();
|
||||
});
|
||||
|
||||
std::vector<ArenaSeasonRewardGroup> pctRewardGroup;
|
||||
std::vector<ArenaSeasonRewardGroup> absRewardGroup;
|
||||
|
||||
for (auto const& reward : rewardGroups)
|
||||
{
|
||||
if (reward.criteriaType == ARENA_SEASON_REWARD_CRITERIA_TYPE_PERCENT_VALUE)
|
||||
pctRewardGroup.push_back(reward);
|
||||
else
|
||||
absRewardGroup.push_back(reward);
|
||||
}
|
||||
|
||||
size_t totalTeams = sortedTeams.size();
|
||||
for (auto const& rewardGroup : pctRewardGroup)
|
||||
{
|
||||
size_t minIndex = static_cast<size_t>(rewardGroup.minCriteria * totalTeams / 100);
|
||||
size_t maxIndex = static_cast<size_t>(rewardGroup.maxCriteria * totalTeams / 100);
|
||||
|
||||
minIndex = std::min(minIndex, totalTeams);
|
||||
maxIndex = std::min(maxIndex, totalTeams);
|
||||
|
||||
for (size_t i = minIndex; i < maxIndex; ++i)
|
||||
{
|
||||
ArenaTeam* team = sortedTeams[i];
|
||||
_rewarder->RewardTeamWithRewardGroup(team, rewardGroup);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& rewardGroup : absRewardGroup)
|
||||
{
|
||||
size_t minIndex = rewardGroup.minCriteria-1; // Top 1 team is the team with index 0, so we need make -1.
|
||||
size_t maxIndex = rewardGroup.maxCriteria;
|
||||
|
||||
minIndex = std::max(minIndex, size_t(0));
|
||||
minIndex = std::min(minIndex, totalTeams);
|
||||
maxIndex = std::min(maxIndex, totalTeams);
|
||||
|
||||
for (size_t i = minIndex; i < maxIndex; ++i)
|
||||
{
|
||||
ArenaTeam* team = sortedTeams[i];
|
||||
_rewarder->RewardTeamWithRewardGroup(team, rewardGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ARENASEASONREWARDDISTRIBUTOR_H
|
||||
#define _ARENASEASONREWARDDISTRIBUTOR_H
|
||||
|
||||
#include "ArenaSeasonMgr.h"
|
||||
#include "ArenaTeam.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
|
||||
class ArenaSeasonTeamRewarder
|
||||
{
|
||||
public:
|
||||
virtual ~ArenaSeasonTeamRewarder() = default;
|
||||
|
||||
virtual void RewardTeamWithRewardGroup(ArenaTeam* arenaTeam, ArenaSeasonRewardGroup const & rewardGroup) = 0;
|
||||
};
|
||||
|
||||
class ArenaSeasonTeamRewarderImpl: public ArenaSeasonTeamRewarder
|
||||
{
|
||||
public:
|
||||
void RewardTeamWithRewardGroup(ArenaTeam* arenaTeam, ArenaSeasonRewardGroup const & rewardGroup) override;
|
||||
|
||||
private:
|
||||
void RewardWithMail(ArenaTeam* arenaTeam, ArenaSeasonRewardGroup const & rewardGroup);
|
||||
void RewardWithAchievements(ArenaTeam* arenaTeam, ArenaSeasonRewardGroup const & rewardGroup);
|
||||
};
|
||||
|
||||
class ArenaSeasonRewardDistributor
|
||||
{
|
||||
public:
|
||||
ArenaSeasonRewardDistributor(ArenaSeasonTeamRewarder* rewarder);
|
||||
|
||||
void DistributeRewards(ArenaTeamMgr::ArenaTeamContainer& arenaTeams, std::vector<ArenaSeasonRewardGroup>& rewardGroups);
|
||||
|
||||
private:
|
||||
ArenaSeasonTeamRewarder* _rewarder;
|
||||
};
|
||||
|
||||
#endif // _ARENASEASONREWARDDISTRIBUTOR_H
|
||||
113
src/server/game/Battlegrounds/ArenaSeason/ArenaTeamFilter.h
Normal file
113
src/server/game/Battlegrounds/ArenaSeason/ArenaTeamFilter.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _ARENATEAMFILTER_H
|
||||
#define _ARENATEAMFILTER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "ArenaTeam.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
class ArenaTeamFilter
|
||||
{
|
||||
public:
|
||||
virtual ~ArenaTeamFilter() = default;
|
||||
|
||||
virtual ArenaTeamMgr::ArenaTeamContainer Filter(ArenaTeamMgr::ArenaTeamContainer teams) = 0;
|
||||
};
|
||||
|
||||
class ArenaTeamFilterByTypes : public ArenaTeamFilter
|
||||
{
|
||||
public:
|
||||
ArenaTeamFilterByTypes(std::vector<uint8> validTypes) : _validTypes(validTypes) {}
|
||||
|
||||
ArenaTeamMgr::ArenaTeamContainer Filter(ArenaTeamMgr::ArenaTeamContainer teams) override
|
||||
{
|
||||
ArenaTeamMgr::ArenaTeamContainer result;
|
||||
|
||||
for (auto const& pair : teams)
|
||||
{
|
||||
ArenaTeam* team = pair.second;
|
||||
for (uint8 arenaType : _validTypes)
|
||||
{
|
||||
if (team->GetType() == arenaType)
|
||||
{
|
||||
result[pair.first] = team;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<uint8> _validTypes;
|
||||
};
|
||||
|
||||
class ArenaTeamFilterAllTeams : public ArenaTeamFilter
|
||||
{
|
||||
public:
|
||||
ArenaTeamMgr::ArenaTeamContainer Filter(ArenaTeamMgr::ArenaTeamContainer teams) override
|
||||
{
|
||||
return teams;
|
||||
}
|
||||
};
|
||||
|
||||
class ArenaTeamFilterFactoryByUserInput
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<ArenaTeamFilter> CreateFilterByUserInput(std::string userInput)
|
||||
{
|
||||
std::transform(userInput.begin(), userInput.end(), userInput.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
|
||||
if (userInput == "all")
|
||||
return std::make_unique<ArenaTeamFilterAllTeams>();
|
||||
|
||||
// Parse the input string (e.g., "2,3") into valid types
|
||||
std::vector<uint8> validTypes = ParseTypes(userInput);
|
||||
|
||||
if (!validTypes.empty())
|
||||
return std::make_unique<ArenaTeamFilterByTypes>(validTypes);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<uint8> ParseTypes(std::string_view userInput)
|
||||
{
|
||||
std::vector<uint8> validTypes;
|
||||
auto tokens = Acore::Tokenize(userInput, ',', false);
|
||||
|
||||
for (auto const& token : tokens)
|
||||
if (auto typeOpt = Acore::StringTo<uint8>(token))
|
||||
validTypes.push_back(*typeOpt);
|
||||
|
||||
return validTypes;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _ARENATEAMFILTER_H
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "ArenaTeam.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "ArenaSeasonMgr.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "CharacterCache.h"
|
||||
#include "Group.h"
|
||||
@@ -658,7 +659,7 @@ uint32 ArenaTeam::GetPoints(uint32 memberRating)
|
||||
|
||||
if (rating <= 1500)
|
||||
{
|
||||
if (sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID) < 6 && !sWorld->getIntConfig(CONFIG_LEGACY_ARENA_POINTS_CALC))
|
||||
if (sArenaSeasonMgr->GetCurrentSeason() < 6 && !sWorld->getIntConfig(CONFIG_LEGACY_ARENA_POINTS_CALC))
|
||||
points = (float)rating * 0.22f + 14.0f;
|
||||
else
|
||||
points = 344;
|
||||
|
||||
@@ -125,6 +125,27 @@ void ArenaTeamMgr::RemoveArenaTeam(uint32 arenaTeamId)
|
||||
ArenaTeamStore.erase(arenaTeamId);
|
||||
}
|
||||
|
||||
void ArenaTeamMgr::DeleteAllArenaTeams()
|
||||
{
|
||||
for (auto const& [id, team] : ArenaTeamStore)
|
||||
{
|
||||
while (team->GetMembersSize() > 0)
|
||||
team->DelMember(team->GetMembers().front().Guid, false);
|
||||
|
||||
delete team;
|
||||
}
|
||||
|
||||
ArenaTeamStore.clear();
|
||||
|
||||
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
trans->Append("DELETE FROM arena_team_member");
|
||||
trans->Append("DELETE FROM arena_team");
|
||||
trans->Append("DELETE FROM character_arena_stats");
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
|
||||
NextArenaTeamId = 1;
|
||||
}
|
||||
|
||||
uint32 ArenaTeamMgr::GenerateArenaTeamId()
|
||||
{
|
||||
if (NextArenaTeamId >= MAX_ARENA_TEAM_ID)
|
||||
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
void AddArenaTeam(ArenaTeam* arenaTeam);
|
||||
void RemoveArenaTeam(uint32 Id);
|
||||
|
||||
void DeleteAllArenaTeams();
|
||||
|
||||
ArenaTeamContainer::iterator GetArenaTeamMapBegin() { return ArenaTeamStore.begin(); }
|
||||
ArenaTeamContainer::iterator GetArenaTeamMapEnd() { return ArenaTeamStore.end(); }
|
||||
ArenaTeamContainer& GetArenaTeams() { return ArenaTeamStore; }
|
||||
|
||||
@@ -334,6 +334,18 @@ Battleground* BattlegroundMgr::GetBattlegroundTemplate(BattlegroundTypeId bgType
|
||||
return bgs.empty() ? nullptr : bgs.begin()->second;
|
||||
}
|
||||
|
||||
std::vector<Battleground const*> BattlegroundMgr::GetActiveBattlegrounds()
|
||||
{
|
||||
std::vector<Battleground const*> result;
|
||||
|
||||
for (auto const& [bgType, bgData] : bgDataStore)
|
||||
for (auto const& [id, bg] : bgData._Battlegrounds)
|
||||
if (bg->GetStatus() == STATUS_WAIT_JOIN || bg->GetStatus() == STATUS_IN_PROGRESS)
|
||||
result.push_back(static_cast<const Battleground*>(bg));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32 BattlegroundMgr::CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id)
|
||||
{
|
||||
if (IsArenaType(bgTypeId))
|
||||
|
||||
@@ -82,6 +82,7 @@ public:
|
||||
Battleground* GetBattleground(uint32 instanceID, BattlegroundTypeId bgTypeId);
|
||||
Battleground* GetBattlegroundTemplate(BattlegroundTypeId bgTypeId);
|
||||
Battleground* CreateNewBattleground(BattlegroundTypeId bgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated);
|
||||
std::vector<Battleground const*> GetActiveBattlegrounds();
|
||||
|
||||
void AddBattleground(Battleground* bg);
|
||||
void RemoveBattleground(BattlegroundTypeId bgTypeId, uint32 instanceId);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "ArenaSpectator.h"
|
||||
#include "ArenaTeam.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "ArenaSeasonMgr.h"
|
||||
#include "Battlefield.h"
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "BattlefieldWG.h"
|
||||
@@ -8243,9 +8244,9 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
|
||||
data << uint32(0x8d4) << uint32(0x0); // 5
|
||||
data << uint32(0x8d3) << uint32(0x0); // 6
|
||||
// 7 1 - Arena season in progress, 0 - end of season
|
||||
data << uint32(0xC77) << uint32(sWorld->getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS));
|
||||
data << uint32(0xC77) << uint32(sArenaSeasonMgr->GetSeasonState() == ARENA_SEASON_STATE_IN_PROGRESS);
|
||||
// 8 Arena season id
|
||||
data << uint32(0xF3D) << uint32(sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID));
|
||||
data << uint32(0xF3D) << uint32(sArenaSeasonMgr->GetCurrentSeason());
|
||||
|
||||
if (mapid == 530) // Outland
|
||||
{
|
||||
|
||||
@@ -1163,34 +1163,6 @@ uint32 GameEventMgr::StartSystem() // return the next
|
||||
return delay;
|
||||
}
|
||||
|
||||
void GameEventMgr::StartArenaSeason()
|
||||
{
|
||||
uint8 season = sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID);
|
||||
|
||||
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_GAME_EVENT_ARENA_SEASON);
|
||||
stmt->SetData(0, season);
|
||||
PreparedQueryResult result = WorldDatabase.Query(stmt);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
LOG_ERROR("gameevent", "ArenaSeason ({}) must be an existant Arena Season", season);
|
||||
return;
|
||||
}
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
uint16 eventId = fields[0].Get<uint8>();
|
||||
|
||||
if (eventId >= _gameEvent.size())
|
||||
{
|
||||
LOG_ERROR("gameevent", "EventEntry {} for ArenaSeason ({}) does not exists", eventId, season);
|
||||
return;
|
||||
}
|
||||
|
||||
StartEvent(eventId, true);
|
||||
LOG_INFO("server.loading", "Arena Season {} started...", season);
|
||||
LOG_INFO("server.loading", " ");
|
||||
}
|
||||
|
||||
uint32 GameEventMgr::Update() // return the next event delay in ms
|
||||
{
|
||||
time_t currenttime = GameTime::GetGameTime().count();
|
||||
|
||||
@@ -115,11 +115,10 @@ public:
|
||||
bool IsActiveEvent(uint16 eventId) { return (_activeEvents.find(eventId) != _activeEvents.end()); }
|
||||
uint32 StartSystem();
|
||||
void Initialize();
|
||||
void StartArenaSeason();
|
||||
void StartInternalEvent(uint16 eventId);
|
||||
bool StartEvent(uint16 eventId, bool overwrite = false);
|
||||
void StopEvent(uint16 eventId, bool overwrite = false);
|
||||
void HandleQuestComplete(uint32 questId); // called on world event type quest completions
|
||||
void StartInternalEvent(uint16 event_id);
|
||||
bool StartEvent(uint16 event_id, bool overwrite = false);
|
||||
void StopEvent(uint16 event_id, bool overwrite = false);
|
||||
void HandleQuestComplete(uint32 quest_id); // called on world event type quest completions
|
||||
uint32 GetNPCFlag(Creature* cr);
|
||||
// Load the game event npc vendor table from the DB
|
||||
void LoadEventVendors();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "ArenaTeam.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "ArenaSeasonMgr.h"
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "Chat.h"
|
||||
@@ -812,7 +813,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
|
||||
if (isRated)
|
||||
{
|
||||
// pussywizard: for rated matches check if season is in progress!
|
||||
if (!sWorld->getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS))
|
||||
if (sArenaSeasonMgr->GetSeasonState() == ARENA_SEASON_STATE_DISABLED)
|
||||
return;
|
||||
|
||||
ateamId = _player->GetArenaTeamId(arenaslot);
|
||||
|
||||
@@ -116,7 +116,6 @@ enum WorldBoolConfigs
|
||||
CONFIG_BATTLEGROUND_TRACK_DESERTERS,
|
||||
CONFIG_BG_XP_FOR_KILL,
|
||||
CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,
|
||||
CONFIG_ARENA_SEASON_IN_PROGRESS,
|
||||
CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE,
|
||||
CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY,
|
||||
CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN,
|
||||
@@ -325,7 +324,6 @@ enum WorldIntConfigs
|
||||
CONFIG_ARENA_PREV_OPPONENTS_DISCARD_TIMER,
|
||||
CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,
|
||||
CONFIG_ARENA_GAMES_REQUIRED,
|
||||
CONFIG_ARENA_SEASON_ID,
|
||||
CONFIG_ARENA_START_RATING,
|
||||
CONFIG_LEGACY_ARENA_POINTS_CALC,
|
||||
CONFIG_ARENA_START_PERSONAL_RATING,
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "AchievementMgr.h"
|
||||
#include "AddonMgr.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "ArenaSeasonMgr.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "AutobroadcastMgr.h"
|
||||
#include "BattlefieldMgr.h"
|
||||
@@ -1178,12 +1179,10 @@ void World::LoadConfigSettings(bool reload)
|
||||
_bool_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = sConfigMgr->GetOption<bool>("Arena.AutoDistributePoints", false);
|
||||
_int_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = sConfigMgr->GetOption<uint32>("Arena.AutoDistributeInterval", 7); // pussywizard: spoiled by implementing constant day and hour, always 7 now
|
||||
_int_configs[CONFIG_ARENA_GAMES_REQUIRED] = sConfigMgr->GetOption<uint32>("Arena.GamesRequired", 10);
|
||||
_int_configs[CONFIG_ARENA_SEASON_ID] = sConfigMgr->GetOption<uint32>("Arena.ArenaSeason.ID", 8);
|
||||
_int_configs[CONFIG_ARENA_START_RATING] = sConfigMgr->GetOption<uint32>("Arena.ArenaStartRating", 0);
|
||||
_int_configs[CONFIG_LEGACY_ARENA_POINTS_CALC] = sConfigMgr->GetOption<uint32>("Arena.LegacyArenaPoints", 0);
|
||||
_int_configs[CONFIG_ARENA_START_PERSONAL_RATING] = sConfigMgr->GetOption<uint32>("Arena.ArenaStartPersonalRating", 0);
|
||||
_int_configs[CONFIG_ARENA_START_MATCHMAKER_RATING] = sConfigMgr->GetOption<uint32>("Arena.ArenaStartMatchmakerRating", 1500);
|
||||
_bool_configs[CONFIG_ARENA_SEASON_IN_PROGRESS] = sConfigMgr->GetOption<bool>("Arena.ArenaSeason.InProgress", true);
|
||||
_float_configs[CONFIG_ARENA_WIN_RATING_MODIFIER_1] = sConfigMgr->GetOption<float>("Arena.ArenaWinRatingModifier1", 48.0f);
|
||||
_float_configs[CONFIG_ARENA_WIN_RATING_MODIFIER_2] = sConfigMgr->GetOption<float>("Arena.ArenaWinRatingModifier2", 24.0f);
|
||||
_float_configs[CONFIG_ARENA_LOSE_RATING_MODIFIER] = sConfigMgr->GetOption<float>("Arena.ArenaLoseRatingModifier", 24.0f);
|
||||
@@ -2123,9 +2122,10 @@ void World::SetInitialWorldSettings()
|
||||
LOG_INFO("server.loading", "Initializing Opcodes...");
|
||||
opcodeTable.Initialize();
|
||||
|
||||
LOG_INFO("server.loading", "Starting Arena Season...");
|
||||
LOG_INFO("server.loading", " ");
|
||||
sGameEventMgr->StartArenaSeason();
|
||||
LOG_INFO("server.loading", "Loading Arena Season Rewards...");
|
||||
sArenaSeasonMgr->LoadRewards();
|
||||
LOG_INFO("server.loading", "Loading Active Arena Season...");
|
||||
sArenaSeasonMgr->LoadActiveSeason();
|
||||
|
||||
LOG_INFO("server.loading", "Loading WorldState...");
|
||||
sWorldState->Load();
|
||||
|
||||
@@ -23,6 +23,8 @@ Category: commandscripts
|
||||
EndScriptData */
|
||||
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "ArenaSeasonMgr.h"
|
||||
#include "ArenaTeamFilter.h"
|
||||
#include "Chat.h"
|
||||
#include "CommandScript.h"
|
||||
#include "Player.h"
|
||||
@@ -36,6 +38,19 @@ public:
|
||||
|
||||
ChatCommandTable GetCommands() const override
|
||||
{
|
||||
static ChatCommandTable arenaSeasonSetCommandTable =
|
||||
{
|
||||
{ "state", HandleArenaSeasonSetStateCommand, SEC_ADMINISTRATOR, Console::Yes }
|
||||
};
|
||||
|
||||
static ChatCommandTable arenaSeasonCommandTable =
|
||||
{
|
||||
{ "reward", HandleArenaSeasonRewardCommand, SEC_ADMINISTRATOR, Console::Yes },
|
||||
{ "deleteteams", HandleArenaSeasonDeleteTeamsCommand, SEC_ADMINISTRATOR, Console::Yes },
|
||||
{ "start", HandleArenaSeasonStartCommand, SEC_ADMINISTRATOR, Console::Yes },
|
||||
{ "set", arenaSeasonSetCommandTable }
|
||||
};
|
||||
|
||||
static ChatCommandTable arenaCommandTable =
|
||||
{
|
||||
{ "create", HandleArenaCreateCommand, SEC_ADMINISTRATOR, Console::Yes },
|
||||
@@ -44,6 +59,7 @@ public:
|
||||
{ "captain", HandleArenaCaptainCommand, SEC_ADMINISTRATOR, Console::No },
|
||||
{ "info", HandleArenaInfoCommand, SEC_GAMEMASTER, Console::Yes },
|
||||
{ "lookup", HandleArenaLookupCommand, SEC_GAMEMASTER, Console::No },
|
||||
{ "season", arenaSeasonCommandTable }
|
||||
};
|
||||
|
||||
static ChatCommandTable commandTable =
|
||||
@@ -229,6 +245,80 @@ public:
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleArenaSeasonRewardCommand(ChatHandler* handler, std::string teamsFilterStr)
|
||||
{
|
||||
std::unique_ptr<ArenaTeamFilter> uniqueFilter = ArenaTeamFilterFactoryByUserInput().CreateFilterByUserInput(teamsFilterStr);
|
||||
if (!uniqueFilter)
|
||||
{
|
||||
handler->PSendSysMessage("Invalid filter. Please check your input.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<ArenaTeamFilter> sharedFilter = std::move(uniqueFilter);
|
||||
|
||||
if (!sArenaSeasonMgr->CanDeleteArenaTeams())
|
||||
{
|
||||
handler->PSendSysMessage("Cannot proceed. Make sure there are no active arenas and that rewards exist for the current season.");
|
||||
handler->PSendSysMessage("Hint: You can disable the arena queue using the following command: .arena season set state 0");
|
||||
return false;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("Distributing rewards for arena teams (types: "+teamsFilterStr+")...");
|
||||
sArenaSeasonMgr->RewardTeamsForTheSeason(sharedFilter);
|
||||
handler->PSendSysMessage("Rewards distributed.");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleArenaSeasonDeleteTeamsCommand(ChatHandler* handler)
|
||||
{
|
||||
handler->PSendSysMessage("Deleting arena teams...");
|
||||
sArenaSeasonMgr->DeleteArenaTeams();
|
||||
handler->PSendSysMessage("Arena teams deleted.");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleArenaSeasonStartCommand(ChatHandler* handler, uint8 seasonId)
|
||||
{
|
||||
if (seasonId == sArenaSeasonMgr->GetCurrentSeason())
|
||||
{
|
||||
sArenaSeasonMgr->SetSeasonState(ARENA_SEASON_STATE_IN_PROGRESS);
|
||||
handler->PSendSysMessage("Arena season updated.");
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8 maxSeasonId = 8;
|
||||
if (seasonId > maxSeasonId)
|
||||
{
|
||||
handler->PSendSysMessage("Invalid season id.");
|
||||
return false;
|
||||
}
|
||||
|
||||
sArenaSeasonMgr->ChangeCurrentSeason(seasonId);
|
||||
handler->PSendSysMessage("Arena season changed to season {}.", seasonId);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleArenaSeasonSetStateCommand(ChatHandler* handler, uint8 state)
|
||||
{
|
||||
ArenaSeasonState seasonState;
|
||||
switch (state) {
|
||||
case ARENA_SEASON_STATE_DISABLED:
|
||||
seasonState = ARENA_SEASON_STATE_DISABLED;
|
||||
break;
|
||||
case ARENA_SEASON_STATE_IN_PROGRESS:
|
||||
seasonState = ARENA_SEASON_STATE_IN_PROGRESS;
|
||||
break;
|
||||
default:
|
||||
handler->PSendSysMessage("Invalid state.");
|
||||
return false;
|
||||
}
|
||||
|
||||
sArenaSeasonMgr->SetSeasonState(seasonState);
|
||||
handler->PSendSysMessage("Arena season updated.");
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void AddSC_arena_commandscript()
|
||||
|
||||
Reference in New Issue
Block a user