eluna-scripts-ornfelt/lua/WowEmulationScriptPack/C++/Challenge/Challenge.cpp
2024-09-23 07:59:23 +02:00

346 lines
No EOL
11 KiB
C++

#include "ScriptPCH.h"
#include "BattlegroundMgr.h"
#include "DisableMgr.h"
#include "ObjectMgr.h"
#include "SocialMgr.h"
/*
class challenge_commands : public CommandScript
{
public:
challenge_commands() : CommandScript("challenge_commands") { }
std::vector<ChatCommand> GetCommands() const override
{
static std::vector<ChatCommand> challengeCommandTable =
{
{ "players", SEC_MODERATOR, false, &HandleChallengePlayersCommand, ""},
{ "", SEC_PLAYER, false, &HandleChallengeCommand, ""},
// { NULL, 0, false, NULL, ""}
};
static std::vector<ChatCommand> CommandTable =
{
{ "challenge", SEC_PLAYER, false, NULL, "", challengeCommandTable },
// { NULL, 0, false, NULL, ""}
};
return CommandTable;
}
static bool HandleChallengeCommand(ChatHandler* handler, const char* args)
{
Player *player = handler->GetSession()->GetPlayer();
Player *target = NULL;
Battleground *arena = NULL;
if (!handler->extractPlayerTarget((char*)args, &target))
{
handler->PSendSysMessage("Can't find player.");
handler->SetSentErrorMessage(true);
return false;
}
// Players in queue are unable to challenge
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA); // All Arenas
BattlegroundTypeId bgTypeId = bg->GetBgTypeID();
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType());
if (player->GetBattlegroundQueueIndex(bgQueueTypeId))
{
handler->PSendSysMessage("You're already in queue. Remove it first.", target->GetName());
handler->SetSentErrorMessage(true);
player->CLOSE_GOSSIP_MENU();
return false;
}
// Players are unable to challenge queued players
if (target->GetBattlegroundQueueIndex(bgQueueTypeId))
{
handler->PSendSysMessage("Player is already in queue.", target->GetName());
handler->SetSentErrorMessage(true);
player->CLOSE_GOSSIP_MENU();
return false;
}
// Dont let challenge players in combat
if (handler->extractPlayerTarget((char*)args, &target) && target->IsInCombat())
{
handler->PSendSysMessage("Target is in combat.");
handler->SetSentErrorMessage(true);
player->CLOSE_GOSSIP_MENU();
return false;
}
// Cannot challenge players which have ignored you
if (handler->extractPlayerTarget((char*)args, &target) && target->GetSocial()->HasIgnore(player->GetGUIDLow()))
{
handler->PSendSysMessage("Player %s has ignored you, so you cannot challenge him.", target->GetName());
handler->SetSentErrorMessage(true);
player->CLOSE_GOSSIP_MENU();
return false;
}
if (target == player)
{
handler->PSendSysMessage("You must select player.");
handler->SetSentErrorMessage(true);
player->CLOSE_GOSSIP_MENU();
return false;
}
if (!(arena = JoinPlayer(target, arena)))
{
handler->PSendSysMessage("Player is already in queue.");
handler->SetSentErrorMessage(true);
player->CLOSE_GOSSIP_MENU();
return false;
}
// Cannot challenge someone when fighting
if (target->IsInCombat())
{
handler->PSendSysMessage("You are in combat.");
player->CLOSE_GOSSIP_MENU();
return false;
}
if (!JoinPlayer(player, arena))
{
if (target->challengeData)
{
target->challengeData->removeEvent->Execute(0, 0);
delete (target->challengeData->removeEvent);
delete target->challengeData;
target->challengeData = NULL;
}
handler->PSendSysMessage("Player is already in Arena or Battleground.");
handler->SetSentErrorMessage(true);
return false;
}
handler->PSendSysMessage("You want to challenge %s to arena.", target->GetName());
handler->PSendSysMessage("Player %s wants to challenge you to arena.", player->GetName());
return true;
}
static bool HandleChallengePlayersCommand(ChatHandler* handler, const char* args)
{
Player *targetOne = NULL;
Player *targetTwo = NULL;
char *targetOne_name_str = strtok((char*)args, " ");
char *targetTwo_name_str = strtok((char*)args, " ");
if (!targetOne_name_str || !targetTwo_name_str)
return false;
std::string targetOne_name = targetOne_name_str;
std::string targetTwo_name = targetOne_name_str;
if (!normalizePlayerName(targetOne_name) && !normalizePlayerName(targetTwo_name))
return false;
Battleground *arena = NULL;
if (!handler->extractPlayerTarget((char*)args, &targetOne) || !handler->extractPlayerTarget((char*)args, &targetTwo))
{
handler->PSendSysMessage("Can't find player.");
handler->SetSentErrorMessage(true);
return false;
}
if (targetOne_name == targetTwo_name)
{
handler->PSendSysMessage("Your opponents should be a different players.");
handler->SetSentErrorMessage(true);
return false;
}
if (!targetOne || !targetTwo)
{
handler->PSendSysMessage("Can't find some of the players.");
handler->SetSentErrorMessage(true);
return false;
}
if (!(arena = JoinPlayer(targetOne, arena)))
{
handler->PSendSysMessage("Cant join to challenge queue when already queued.");
handler->SetSentErrorMessage(true);
return false;
}
if (!JoinPlayer(targetTwo, arena))
{
if (targetOne->challengeData)
{
targetOne->challengeData->removeEvent->Execute(0, 0);
delete (targetOne->challengeData->removeEvent);
delete targetOne->challengeData;
targetOne->challengeData = NULL;
}
handler->PSendSysMessage("Cant join to challenge queue when players already queued.");
handler->SetSentErrorMessage(true);
return false;
}
return true;
}
private:
static Battleground* JoinPlayer(Player *player, Battleground *arena)
{
// ignore if we already in BG or BG queue
if (player->InBattleground())
return NULL;
uint8 arenatype = ARENA_TYPE_2v2;
uint32 matchmakerRating = 0;
//check existance
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA);
if (!bg)
{
sLog->outError("Battleground: template bg (all arenas) not found");
return NULL;
}
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, NULL))
{
//ChatHandler(player).PSendSysMessage(LANG_ARENA_DISABLED);
return NULL;
}
BattlegroundTypeId bgTypeId = bg->GetBgTypeID();
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype);
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), player->getLevel());
if (!bracketEntry)
return NULL;
// check if already in queue
if (player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
//player is already in this queue
return NULL;
// check if has free queue slots
if (!player->HasFreeBattlegroundQueueId())
return NULL;
uint32 queueSlot = player->AddBattlegroundQueueId(bgQueueTypeId);
WorldPacket data;
// send status packet (in queue)
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, 0, 0, arenatype);
player->GetSession()->SendPacket(&data);
sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, player->GetGUIDLow(), player->GetName());
sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
GroupQueueInfo* ginfo = new GroupQueueInfo;
ginfo->BgTypeId = bgTypeId;
ginfo->ArenaType = arenatype;
ginfo->ArenaTeamId = 0;
ginfo->IsRated = 0;
ginfo->IsInvitedToBGInstanceGUID = 0;
ginfo->JoinTime = getMSTime();
ginfo->RemoveInviteTime = 0;
ginfo->Team = player->GetTeam();
ginfo->ArenaTeamRating = 0;
ginfo->ArenaMatchmakerRating = 0;
ginfo->OpponentsTeamRating = 0;
ginfo->OpponentsMatchmakerRating = 0;
ginfo->Players.clear();
PlayerQueueInfo* info = new PlayerQueueInfo;
info->GroupInfo = ginfo;
info->LastOnlineTime = getMSTime();
ginfo->Players[player->GetGUID()] = info;
if (!arena)
{
arena = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenatype, true);
arena->SetRated(false);
arena->SetChallenge(true);
player->challengeData = new ChallengeData;
player->challengeData->bg = arena;
player->challengeData->ginfo = ginfo;
InviteGroupToBG(ginfo, arena, ALLIANCE);
}
else
{
player->challengeData = new ChallengeData;
player->challengeData->bg = arena;
player->challengeData->ginfo = ginfo;
InviteGroupToBG(ginfo, arena, HORDE);
arena->StartBattleground();
if (!sBattlegroundMgr->HasBattleground(arena))
sBattlegroundMgr->AddBattleground(ginfo->IsInvitedToBGInstanceGUID, bgTypeId, arena);
}
return arena;
}
static bool InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, uint32 side)
{
// set side if needed
if (side)
ginfo->Team = side;
if (!ginfo->IsInvitedToBGInstanceGUID)
{
// not yet invited
// set invitation
ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID();
BattlegroundTypeId bgTypeId = bg->GetTypeID();
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType());
// set ArenaTeamId for rated matches
if (bg->isArena() && bg->isRated())
bg->SetArenaTeamIdForTeam(ginfo->Team, ginfo->ArenaTeamId);
ginfo->RemoveInviteTime = getMSTime() + INVITE_ACCEPT_WAIT_TIME;
// loop through the players
for (std::map<uint64, PlayerQueueInfo*>::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr)
{
// get the player
Player* player = ObjectAccessor::FindPlayer(itr->first);
// if offline, skip him, this should not happen - player is removed from queue when he logs out
if (!player)
continue;
// set invited player counters
bg->IncreaseInvitedCount(ginfo->Team);
player->SetInviteForBattlegroundQueueType(bgQueueTypeId, ginfo->IsInvitedToBGInstanceGUID);
BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(player->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime);
player->challengeData->removeEvent = removeEvent;
WorldPacket data;
uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Battleground: invited player %s (%u) to BG instance %u queueindex %u bgtype %u, I can't help it if they don't press the enter battle button.", player->GetName(), player->GetGUIDLow(), bg->GetInstanceID(), queueSlot, bg->GetTypeID());
// send status packet
sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType);
player->GetSession()->SendPacket(&data);
}
return true;
}
return false;
}
};
*/
void AddSC_challenge_script()
{
// new challenge_commands();
}