First Commit
For Azeroth!
This commit is contained in:
@@ -0,0 +1,913 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 "ObjectMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "ArenaTeam.h"
|
||||
#include "World.h"
|
||||
#include "Group.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "Player.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Opcodes.h"
|
||||
|
||||
ArenaTeam::ArenaTeam()
|
||||
: TeamId(0), Type(0), TeamName(), CaptainGuid(0), BackgroundColor(0), EmblemStyle(0), EmblemColor(0),
|
||||
BorderStyle(0), BorderColor(0)
|
||||
{
|
||||
Stats.WeekGames = 0;
|
||||
Stats.SeasonGames = 0;
|
||||
Stats.Rank = 0;
|
||||
Stats.Rating = sWorld->getIntConfig(CONFIG_ARENA_START_RATING);
|
||||
Stats.WeekWins = 0;
|
||||
Stats.SeasonWins = 0;
|
||||
}
|
||||
|
||||
ArenaTeam::~ArenaTeam()
|
||||
{
|
||||
}
|
||||
|
||||
bool ArenaTeam::Create(uint64 captainGuid, uint8 type, std::string const& teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor)
|
||||
{
|
||||
// Check if captain is present
|
||||
if (!ObjectAccessor::FindPlayerInOrOutOfWorld(captainGuid))
|
||||
return false;
|
||||
|
||||
// Check if arena team name is already taken
|
||||
if (sArenaTeamMgr->GetArenaTeamByName(TeamName))
|
||||
return false;
|
||||
|
||||
// Generate new arena team id
|
||||
TeamId = sArenaTeamMgr->GenerateArenaTeamId();
|
||||
|
||||
// Assign member variables
|
||||
CaptainGuid = captainGuid;
|
||||
Type = type;
|
||||
TeamName = teamName;
|
||||
BackgroundColor = backgroundColor;
|
||||
EmblemStyle = emblemStyle;
|
||||
EmblemColor = emblemColor;
|
||||
BorderStyle = borderStyle;
|
||||
BorderColor = borderColor;
|
||||
uint32 captainLowGuid = GUID_LOPART(captainGuid);
|
||||
|
||||
// Save arena team to db
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ARENA_TEAM);
|
||||
stmt->setUInt32(0, TeamId);
|
||||
stmt->setString(1, TeamName);
|
||||
stmt->setUInt32(2, captainLowGuid);
|
||||
stmt->setUInt8(3, Type);
|
||||
stmt->setUInt16(4, Stats.Rating);
|
||||
stmt->setUInt32(5, BackgroundColor);
|
||||
stmt->setUInt8(6, EmblemStyle);
|
||||
stmt->setUInt32(7, EmblemColor);
|
||||
stmt->setUInt8(8, BorderStyle);
|
||||
stmt->setUInt32(9, BorderColor);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
// Add captain as member
|
||||
AddMember(CaptainGuid);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArenaTeam::AddMember(uint64 playerGuid)
|
||||
{
|
||||
std::string playerName;
|
||||
uint8 playerClass;
|
||||
|
||||
// Check if arena team is full (Can't have more than type * 2 players)
|
||||
if (GetMembersSize() >= GetType() * 2)
|
||||
return false;
|
||||
|
||||
// xinef: Get player name and class from player storage or global data storage
|
||||
Player* player = ObjectAccessor::FindPlayerInOrOutOfWorld(playerGuid);
|
||||
if (player)
|
||||
{
|
||||
playerClass = player->getClass();
|
||||
playerName = player->GetName();
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalPlayerData const* playerData = sWorld->GetGlobalPlayerData(GUID_LOPART(playerGuid));
|
||||
if (!playerData)
|
||||
return false;
|
||||
|
||||
playerName = playerData->name;
|
||||
playerClass = playerData->playerClass;
|
||||
}
|
||||
|
||||
// Check if player is already in a similar arena team
|
||||
if ((player && player->GetArenaTeamId(GetSlot())) || Player::GetArenaTeamIdFromStorage(GUID_LOPART(playerGuid), GetSlot()) != 0)
|
||||
{
|
||||
sLog->outError("Arena: Player %s (guid: %u) already has an arena team of type %u", playerName.c_str(), GUID_LOPART(playerGuid), GetType());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set player's personal rating
|
||||
uint32 personalRating = 0;
|
||||
|
||||
if (sWorld->getIntConfig(CONFIG_ARENA_START_PERSONAL_RATING) > 0)
|
||||
personalRating = sWorld->getIntConfig(CONFIG_ARENA_START_PERSONAL_RATING);
|
||||
else if (GetRating() >= 1000)
|
||||
personalRating = 1000;
|
||||
|
||||
// xinef: zomg! sync query
|
||||
// Try to get player's match maker rating from db and fall back to config setting if not found
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MATCH_MAKER_RATING);
|
||||
stmt->setUInt32(0, GUID_LOPART(playerGuid));
|
||||
stmt->setUInt8(1, GetSlot());
|
||||
PreparedQueryResult result = CharacterDatabase.Query(stmt);
|
||||
|
||||
uint16 matchMakerRating;
|
||||
uint16 maxMMR;
|
||||
if (result)
|
||||
{
|
||||
matchMakerRating = (*result)[0].GetUInt16();
|
||||
uint16 Max = (*result)[1].GetUInt16();
|
||||
maxMMR = std::max(Max, matchMakerRating);
|
||||
}
|
||||
else
|
||||
{
|
||||
matchMakerRating = sWorld->getIntConfig(CONFIG_ARENA_START_MATCHMAKER_RATING);
|
||||
maxMMR = matchMakerRating;
|
||||
}
|
||||
|
||||
// Remove all player signatures from other petitions
|
||||
// This will prevent player from joining too many arena teams and corrupt arena team data integrity
|
||||
Player::RemovePetitionsAndSigns(playerGuid, GetType());
|
||||
|
||||
// Feed data to the struct
|
||||
ArenaTeamMember newMember;
|
||||
//newMember.Name = playerName;
|
||||
newMember.Guid = playerGuid;
|
||||
newMember.Class = playerClass;
|
||||
newMember.SeasonGames = 0;
|
||||
newMember.WeekGames = 0;
|
||||
newMember.SeasonWins = 0;
|
||||
newMember.WeekWins = 0;
|
||||
newMember.PersonalRating = personalRating;
|
||||
newMember.MatchMakerRating = matchMakerRating;
|
||||
newMember.MaxMMR = maxMMR;
|
||||
|
||||
Members.push_back(newMember);
|
||||
sWorld->UpdateGlobalPlayerArenaTeam(GUID_LOPART(playerGuid), GetSlot(), GetId());
|
||||
|
||||
// Save player's arena team membership to db
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ARENA_TEAM_MEMBER);
|
||||
stmt->setUInt32(0, TeamId);
|
||||
stmt->setUInt32(1, GUID_LOPART(playerGuid));
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
// Inform player if online
|
||||
if (player)
|
||||
{
|
||||
player->SetInArenaTeam(TeamId, GetSlot(), GetType());
|
||||
player->SetArenaTeamIdInvited(0);
|
||||
|
||||
// Hide promote/remove buttons
|
||||
if (CaptainGuid != playerGuid)
|
||||
player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArenaTeam::LoadArenaTeamFromDB(QueryResult result)
|
||||
{
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
TeamId = fields[0].GetUInt32();
|
||||
TeamName = fields[1].GetString();
|
||||
CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
Type = fields[3].GetUInt8();
|
||||
BackgroundColor = fields[4].GetUInt32();
|
||||
EmblemStyle = fields[5].GetUInt8();
|
||||
EmblemColor = fields[6].GetUInt32();
|
||||
BorderStyle = fields[7].GetUInt8();
|
||||
BorderColor = fields[8].GetUInt32();
|
||||
Stats.Rating = fields[9].GetUInt16();
|
||||
Stats.WeekGames = fields[10].GetUInt16();
|
||||
Stats.WeekWins = fields[11].GetUInt16();
|
||||
Stats.SeasonGames = fields[12].GetUInt16();
|
||||
Stats.SeasonWins = fields[13].GetUInt16();
|
||||
Stats.Rank = fields[14].GetUInt32();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArenaTeam::LoadMembersFromDB(QueryResult result)
|
||||
{
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
bool captainPresentInTeam = false;
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
// Prevent crash if db records are broken when all members in result are already processed and current team doesn't have any members
|
||||
if (!fields)
|
||||
break;
|
||||
|
||||
uint32 arenaTeamId = fields[0].GetUInt32();
|
||||
|
||||
// We loaded all members for this arena_team already, break cycle
|
||||
if (arenaTeamId > TeamId)
|
||||
break;
|
||||
|
||||
ArenaTeamMember newMember;
|
||||
newMember.Guid = MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
newMember.WeekGames = fields[2].GetUInt16();
|
||||
newMember.WeekWins = fields[3].GetUInt16();
|
||||
newMember.SeasonGames = fields[4].GetUInt16();
|
||||
newMember.SeasonWins = fields[5].GetUInt16();
|
||||
//newMember.Name = fields[6].GetString();
|
||||
newMember.Class = fields[7].GetUInt8();
|
||||
newMember.PersonalRating = fields[8].GetUInt16();
|
||||
newMember.MatchMakerRating = fields[9].GetUInt16() > 0 ? fields[9].GetUInt16() : sWorld->getIntConfig(CONFIG_ARENA_START_MATCHMAKER_RATING);;
|
||||
newMember.MaxMMR = std::max(fields[10].GetUInt16(), newMember.MatchMakerRating);
|
||||
|
||||
// Delete member if character information is missing
|
||||
if (fields[6].GetString().empty())
|
||||
{
|
||||
sLog->outErrorDb("ArenaTeam %u has member with empty name - probably player %u doesn't exist, deleting him from memberlist!", arenaTeamId, GUID_LOPART(newMember.Guid));
|
||||
this->DelMember(newMember.Guid, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if team team has a valid captain
|
||||
if (newMember.Guid == GetCaptain())
|
||||
captainPresentInTeam = true;
|
||||
|
||||
// Put the player in the team
|
||||
Members.push_back(newMember);
|
||||
sWorld->UpdateGlobalPlayerArenaTeam(GUID_LOPART(newMember.Guid), GetSlot(), GetId());
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
if (Empty() || !captainPresentInTeam)
|
||||
{
|
||||
// Arena team is empty or captain is not in team, delete from db
|
||||
;//sLog->outDebug(LOG_FILTER_BATTLEGROUND, "ArenaTeam %u does not have any members or its captain is not in team, disbanding it...", TeamId);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ArenaTeam::SetCaptain(uint64 guid)
|
||||
{
|
||||
// Disable remove/promote buttons
|
||||
Player* oldCaptain = ObjectAccessor::FindPlayerInOrOutOfWorld(GetCaptain());
|
||||
if (oldCaptain)
|
||||
oldCaptain->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1);
|
||||
|
||||
// Set new captain
|
||||
CaptainGuid = guid;
|
||||
|
||||
// Update database
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ARENA_TEAM_CAPTAIN);
|
||||
stmt->setUInt32(0, GUID_LOPART(guid));
|
||||
stmt->setUInt32(1, GetId());
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
// Enable remove/promote buttons
|
||||
if (Player* newCaptain = ObjectAccessor::FindPlayerInOrOutOfWorld(guid))
|
||||
{
|
||||
newCaptain->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 0);
|
||||
/*if (oldCaptain)
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].",
|
||||
oldCaptain->GetName().c_str(), oldCaptain->GetGUIDLow(), newCaptain->GetName().c_str(),
|
||||
newCaptain->GetGUIDLow(), GetId(), GetType());
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::DelMember(uint64 guid, bool cleanDb)
|
||||
{
|
||||
// Remove member from team
|
||||
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
if (itr->Guid == guid)
|
||||
{
|
||||
Members.erase(itr);
|
||||
sWorld->UpdateGlobalPlayerArenaTeam(GUID_LOPART(guid), GetSlot(), 0);
|
||||
break;
|
||||
}
|
||||
|
||||
// Inform player and remove arena team info from player data
|
||||
if (Player* player = ObjectAccessor::FindPlayerInOrOutOfWorld(guid))
|
||||
{
|
||||
player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, GetName(), "", 0);
|
||||
// delete all info regarding this team
|
||||
for (uint32 i = 0; i < ARENA_TEAM_END; ++i)
|
||||
player->SetArenaTeamInfoField(GetSlot(), ArenaTeamInfoType(i), 0);
|
||||
}
|
||||
|
||||
// Only used for single member deletion, for arena team disband we use a single query for more efficiency
|
||||
if (cleanDb)
|
||||
{
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ARENA_TEAM_MEMBER);
|
||||
stmt->setUInt32(0, GetId());
|
||||
stmt->setUInt32(1, GUID_LOPART(guid));
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::Disband(WorldSession* session)
|
||||
{
|
||||
// Remove all members from arena team
|
||||
while (!Members.empty())
|
||||
DelMember(Members.front().Guid, false);
|
||||
|
||||
// Broadcast update
|
||||
if (session)
|
||||
{
|
||||
BroadcastEvent(ERR_ARENA_TEAM_DISBANDED_S, 0, 2, session->GetPlayerName(), GetName(), "");
|
||||
}
|
||||
|
||||
// Update database
|
||||
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ARENA_TEAM);
|
||||
stmt->setUInt32(0, TeamId);
|
||||
trans->Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ARENA_TEAM_MEMBERS);
|
||||
stmt->setUInt32(0, TeamId);
|
||||
trans->Append(stmt);
|
||||
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
|
||||
// Remove arena team from ObjectMgr
|
||||
sArenaTeamMgr->RemoveArenaTeam(TeamId);
|
||||
}
|
||||
|
||||
void ArenaTeam::Roster(WorldSession* session)
|
||||
{
|
||||
Player* player = NULL;
|
||||
|
||||
uint8 unk308 = 0;
|
||||
std::string tempName;
|
||||
|
||||
WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100);
|
||||
data << uint32(GetId()); // team id
|
||||
data << uint8(unk308); // 308 unknown value but affect packet structure
|
||||
data << uint32(GetMembersSize()); // members count
|
||||
data << uint32(GetType()); // arena team type?
|
||||
|
||||
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
{
|
||||
player = ObjectAccessor::FindPlayerInOrOutOfWorld(itr->Guid);
|
||||
|
||||
data << uint64(itr->Guid); // guid
|
||||
data << uint8((player ? 1 : 0)); // online flag
|
||||
tempName = "";
|
||||
sObjectMgr->GetPlayerNameByGUID(itr->Guid, tempName);
|
||||
data << tempName; // member name
|
||||
data << uint32((itr->Guid == GetCaptain() ? 0 : 1));// captain flag 0 captain 1 member
|
||||
data << uint8((player ? player->getLevel() : 0)); // unknown, level?
|
||||
data << uint8(itr->Class); // class
|
||||
data << uint32(itr->WeekGames); // played this week
|
||||
data << uint32(itr->WeekWins); // wins this week
|
||||
data << uint32(itr->SeasonGames); // played this season
|
||||
data << uint32(itr->SeasonWins); // wins this season
|
||||
data << uint32(itr->PersonalRating); // personal rating
|
||||
if (unk308)
|
||||
{
|
||||
data << float(0.0f); // 308 unk
|
||||
data << float(0.0f); // 308 unk
|
||||
}
|
||||
}
|
||||
|
||||
session->SendPacket(&data);
|
||||
;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_ARENA_TEAM_ROSTER");
|
||||
}
|
||||
|
||||
void ArenaTeam::Query(WorldSession* session)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_TEAM_QUERY_RESPONSE, 4*7+GetName().size()+1);
|
||||
data << uint32(GetId()); // team id
|
||||
data << GetName(); // team name
|
||||
data << uint32(GetType()); // arena team type (2=2x2, 3=3x3 or 5=5x5)
|
||||
data << uint32(BackgroundColor); // background color
|
||||
data << uint32(EmblemStyle); // emblem style
|
||||
data << uint32(EmblemColor); // emblem color
|
||||
data << uint32(BorderStyle); // border style
|
||||
data << uint32(BorderColor); // border color
|
||||
session->SendPacket(&data);
|
||||
;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE");
|
||||
}
|
||||
|
||||
void ArenaTeam::SendStats(WorldSession* session)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7);
|
||||
data << uint32(GetId()); // team id
|
||||
data << uint32(Stats.Rating); // rating
|
||||
data << uint32(Stats.WeekGames); // games this week
|
||||
data << uint32(Stats.WeekWins); // wins this week
|
||||
data << uint32(Stats.SeasonGames); // played this season
|
||||
data << uint32(Stats.SeasonWins); // wins this season
|
||||
data << uint32(Stats.Rank); // rank
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
|
||||
void ArenaTeam::NotifyStatsChanged()
|
||||
{
|
||||
// This is called after a rated match ended
|
||||
// Updates arena team stats for every member of the team (not only the ones who participated!)
|
||||
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
if (Player* player = ObjectAccessor::FindPlayerInOrOutOfWorld(itr->Guid))
|
||||
SendStats(player->GetSession());
|
||||
}
|
||||
|
||||
void ArenaTeam::Inspect(WorldSession* session, uint64 guid)
|
||||
{
|
||||
ArenaTeamMember* member = GetMember(guid);
|
||||
if (!member)
|
||||
return;
|
||||
|
||||
WorldPacket data(MSG_INSPECT_ARENA_TEAMS, 8+1+4*6);
|
||||
data << uint64(guid); // player guid
|
||||
data << uint8(GetSlot()); // slot (0...2)
|
||||
data << uint32(GetId()); // arena team id
|
||||
data << uint32(Stats.Rating); // rating
|
||||
data << uint32(Stats.SeasonGames); // season played
|
||||
data << uint32(Stats.SeasonWins); // season wins
|
||||
data << uint32(member->SeasonGames); // played (count of all games, that the inspected member participated...)
|
||||
data << uint32(member->PersonalRating); // personal rating
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
|
||||
void ArenaTeamMember::ModifyPersonalRating(Player* player, int32 mod, uint32 type)
|
||||
{
|
||||
if (int32(PersonalRating) + mod < 0)
|
||||
PersonalRating = 0;
|
||||
else
|
||||
PersonalRating += mod;
|
||||
|
||||
if (player)
|
||||
{
|
||||
player->SetArenaTeamInfoField(ArenaTeam::GetSlotByType(type), ARENA_TEAM_PERSONAL_RATING, PersonalRating);
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING, PersonalRating, type);
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeamMember::ModifyMatchmakerRating(int32 mod, uint32 /*slot*/)
|
||||
{
|
||||
if (mod < 0)
|
||||
{
|
||||
// pussywizard: prevent lowering MMR too much from max achieved MMR
|
||||
int32 maxAllowedDrop = (int32)sWorld->getIntConfig(CONFIG_MAX_ALLOWED_MMR_DROP);
|
||||
mod = std::min<int32>(std::max<int32>(-((int32)MatchMakerRating - (int32)MaxMMR + maxAllowedDrop), mod), 0);
|
||||
}
|
||||
|
||||
if (int32(MatchMakerRating) + mod < 0)
|
||||
MatchMakerRating = 0;
|
||||
else
|
||||
MatchMakerRating += mod;
|
||||
|
||||
if (MatchMakerRating > MaxMMR)
|
||||
MaxMMR = MatchMakerRating;
|
||||
}
|
||||
|
||||
void ArenaTeam::BroadcastPacket(WorldPacket* packet)
|
||||
{
|
||||
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
if (Player* player = ObjectAccessor::FindPlayerInOrOutOfWorld(itr->Guid))
|
||||
player->GetSession()->SendPacket(packet);
|
||||
}
|
||||
|
||||
void ArenaTeam::BroadcastEvent(ArenaTeamEvents event, uint64 guid, uint8 strCount, std::string const& str1, std::string const& str2, std::string const& str3)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_TEAM_EVENT, 1+1+1);
|
||||
data << uint8(event);
|
||||
data << uint8(strCount);
|
||||
switch (strCount)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
data << str1;
|
||||
break;
|
||||
case 2:
|
||||
data << str1 << str2;
|
||||
break;
|
||||
case 3:
|
||||
data << str1 << str2 << str3;
|
||||
break;
|
||||
default:
|
||||
sLog->outError("Unhandled strCount %u in ArenaTeam::BroadcastEvent", strCount);
|
||||
return;
|
||||
}
|
||||
|
||||
if (guid)
|
||||
data << uint64(guid);
|
||||
|
||||
BroadcastPacket(&data);
|
||||
|
||||
;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_ARENA_TEAM_EVENT");
|
||||
}
|
||||
|
||||
void ArenaTeam::MassInviteToEvent(WorldSession* session)
|
||||
{
|
||||
WorldPacket data(SMSG_CALENDAR_ARENA_TEAM, (Members.size() - 1) * (4 + 8 + 1));
|
||||
data << uint32(Members.size() - 1);
|
||||
|
||||
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
{
|
||||
if (itr->Guid != session->GetPlayer()->GetGUID())
|
||||
{
|
||||
data.appendPackGUID(itr->Guid);
|
||||
data << uint8(0); // unk
|
||||
}
|
||||
}
|
||||
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
|
||||
uint8 ArenaTeam::GetSlotByType(uint32 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ARENA_TEAM_2v2: return 0;
|
||||
case ARENA_TEAM_3v3: return 1;
|
||||
case ARENA_TEAM_5v5: return 2;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sLog->outError("FATAL: Unknown arena team type %u for some arena team", type);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
bool ArenaTeam::IsMember(uint64 guid) const
|
||||
{
|
||||
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
if (itr->Guid == guid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 ArenaTeam::GetPoints(uint32 memberRating)
|
||||
{
|
||||
// Returns how many points would be awarded with this team type with this rating
|
||||
float points;
|
||||
|
||||
uint32 rating = memberRating + 150 < Stats.Rating ? memberRating : Stats.Rating;
|
||||
|
||||
if (rating <= 1500)
|
||||
{
|
||||
if (sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID) < 6)
|
||||
points = (float)rating * 0.22f + 14.0f;
|
||||
else
|
||||
points = 344;
|
||||
}
|
||||
else
|
||||
points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating));
|
||||
|
||||
// Type penalties for teams < 5v5
|
||||
if (Type == ARENA_TEAM_2v2)
|
||||
points *= 0.76f;
|
||||
else if (Type == ARENA_TEAM_3v3)
|
||||
points *= 0.88f;
|
||||
|
||||
return (uint32) points;
|
||||
}
|
||||
|
||||
uint32 ArenaTeam::GetAverageMMR(Group* group) const
|
||||
{
|
||||
if (!group)
|
||||
return 0;
|
||||
|
||||
uint32 matchMakerRating = 0;
|
||||
uint32 playerDivider = 0;
|
||||
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
{
|
||||
// Skip if player is not online
|
||||
if (!ObjectAccessor::FindPlayerInOrOutOfWorld(itr->Guid))
|
||||
continue;
|
||||
|
||||
// Skip if player is not member of group
|
||||
if (!group->IsMember(itr->Guid))
|
||||
continue;
|
||||
|
||||
matchMakerRating += itr->MatchMakerRating;
|
||||
++playerDivider;
|
||||
}
|
||||
|
||||
// x/0 = crash
|
||||
if (playerDivider == 0)
|
||||
playerDivider = 1;
|
||||
|
||||
matchMakerRating /= playerDivider;
|
||||
|
||||
return matchMakerRating;
|
||||
}
|
||||
|
||||
float ArenaTeam::GetChanceAgainst(uint32 ownRating, uint32 opponentRating)
|
||||
{
|
||||
// Returns the chance to win against a team with the given rating, used in the rating adjustment calculation
|
||||
// ELO system
|
||||
return 1.0f / (1.0f + exp(log(10.0f) * (float)((float)opponentRating - (float)ownRating) / 650.0f));
|
||||
}
|
||||
|
||||
int32 ArenaTeam::GetMatchmakerRatingMod(uint32 ownRating, uint32 opponentRating, bool won /*, float& confidence_factor*/)
|
||||
{
|
||||
// 'Chance' calculation - to beat the opponent
|
||||
// This is a simulation. Not much info on how it really works
|
||||
float chance = GetChanceAgainst(ownRating, opponentRating);
|
||||
float won_mod = (won) ? 1.0f : 0.0f;
|
||||
float mod = won_mod - chance;
|
||||
|
||||
// Work in progress:
|
||||
/*
|
||||
// This is a simulation, as there is not much info on how it really works
|
||||
float confidence_mod = min(1.0f - fabs(mod), 0.5f);
|
||||
|
||||
// Apply confidence factor to the mod:
|
||||
mod *= confidence_factor
|
||||
|
||||
// And only after that update the new confidence factor
|
||||
confidence_factor -= ((confidence_factor - 1.0f) * confidence_mod) / confidence_factor;
|
||||
*/
|
||||
|
||||
// Real rating modification
|
||||
mod *= 24.0f;
|
||||
|
||||
return (int32)ceil(mod);
|
||||
}
|
||||
|
||||
int32 ArenaTeam::GetRatingMod(uint32 ownRating, uint32 opponentRating, bool won /*, float confidence_factor*/)
|
||||
{
|
||||
// 'Chance' calculation - to beat the opponent
|
||||
// This is a simulation. Not much info on how it really works
|
||||
float chance = GetChanceAgainst(ownRating, opponentRating);
|
||||
float won_mod = (won) ? 1.0f : 0.0f;
|
||||
|
||||
// Calculate the rating modification
|
||||
float mod;
|
||||
|
||||
// TODO: Replace this hack with using the confidence factor (limiting the factor to 2.0f)
|
||||
if (won && ownRating < 1300)
|
||||
{
|
||||
if (ownRating < 1000)
|
||||
mod = 48.0f * (won_mod - chance);
|
||||
else
|
||||
mod = (24.0f + (24.0f * (1300.0f - float(ownRating)) / 300.0f)) * (won_mod - chance);
|
||||
}
|
||||
else
|
||||
mod = 24.0f * (won_mod - chance);
|
||||
|
||||
return (int32)ceil(mod);
|
||||
}
|
||||
|
||||
void ArenaTeam::FinishGame(int32 mod, const Map* bgMap)
|
||||
{
|
||||
// Rating can only drop to 0
|
||||
if (int32(Stats.Rating) + mod < 0)
|
||||
Stats.Rating = 0;
|
||||
else
|
||||
{
|
||||
Stats.Rating += mod;
|
||||
|
||||
// Check if rating related achivements are met
|
||||
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
if (Player* member = ObjectAccessor::FindPlayerInOrOutOfWorld(itr->Guid))
|
||||
if (member->FindMap() == bgMap)
|
||||
member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING, Stats.Rating, Type);
|
||||
}
|
||||
|
||||
// Update number of games played per season or week
|
||||
Stats.WeekGames += 1;
|
||||
Stats.SeasonGames += 1;
|
||||
|
||||
// Update team's rank, start with rank 1 and increase until no team with more rating was found
|
||||
Stats.Rank = 1;
|
||||
ArenaTeamMgr::ArenaTeamContainer::const_iterator i = sArenaTeamMgr->GetArenaTeamMapBegin();
|
||||
for (; i != sArenaTeamMgr->GetArenaTeamMapEnd(); ++i)
|
||||
{
|
||||
if (i->second->GetType() == Type && i->second->GetStats().Rating > Stats.Rating)
|
||||
++Stats.Rank;
|
||||
}
|
||||
}
|
||||
|
||||
int32 ArenaTeam::WonAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32& rating_change, const Map* bgMap)
|
||||
{
|
||||
// Called when the team has won
|
||||
// Change in Matchmaker rating
|
||||
int32 mod = GetMatchmakerRatingMod(Own_MMRating, Opponent_MMRating, true);
|
||||
|
||||
// Change in Team Rating
|
||||
rating_change = GetRatingMod(Stats.Rating, Opponent_MMRating, true);
|
||||
|
||||
// Modify the team stats accordingly
|
||||
FinishGame(rating_change, bgMap);
|
||||
|
||||
// Update number of wins per season and week
|
||||
Stats.WeekWins += 1;
|
||||
Stats.SeasonWins += 1;
|
||||
|
||||
// Return the rating change, used to display it on the results screen
|
||||
return mod;
|
||||
}
|
||||
|
||||
int32 ArenaTeam::LostAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32& rating_change, const Map* bgMap)
|
||||
{
|
||||
// Called when the team has lost
|
||||
// Change in Matchmaker Rating
|
||||
int32 mod = GetMatchmakerRatingMod(Own_MMRating, Opponent_MMRating, false);
|
||||
|
||||
// Change in Team Rating
|
||||
rating_change = GetRatingMod(Stats.Rating, Opponent_MMRating, false);
|
||||
|
||||
// Modify the team stats accordingly
|
||||
FinishGame(rating_change, bgMap);
|
||||
|
||||
// return the rating change, used to display it on the results screen
|
||||
return mod;
|
||||
}
|
||||
|
||||
void ArenaTeam::MemberLost(Player* player, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange)
|
||||
{
|
||||
// Called for each participant of a match after losing
|
||||
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
{
|
||||
if (itr->Guid == player->GetGUID())
|
||||
{
|
||||
// Update personal rating
|
||||
int32 mod = GetRatingMod(itr->PersonalRating, againstMatchmakerRating, false);
|
||||
itr->ModifyPersonalRating(player, mod, GetType());
|
||||
|
||||
// Update matchmaker rating
|
||||
itr->ModifyMatchmakerRating(MatchmakerRatingChange, GetSlot());
|
||||
|
||||
// Update personal played stats
|
||||
itr->WeekGames +=1;
|
||||
itr->SeasonGames +=1;
|
||||
|
||||
// update the unit fields
|
||||
player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_WEEK, itr->WeekGames);
|
||||
player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_SEASON, itr->SeasonGames);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::MemberWon(Player* player, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange)
|
||||
{
|
||||
// called for each participant after winning a match
|
||||
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
{
|
||||
if (itr->Guid == player->GetGUID())
|
||||
{
|
||||
// update personal rating
|
||||
int32 mod = GetRatingMod(itr->PersonalRating, againstMatchmakerRating, true);
|
||||
itr->ModifyPersonalRating(player, mod, GetType());
|
||||
|
||||
// update matchmaker rating (pussywizard: but don't allow it to go over team rating)
|
||||
if (itr->MatchMakerRating < Stats.Rating)
|
||||
{
|
||||
mod = std::min(MatchmakerRatingChange, Stats.Rating - itr->MatchMakerRating);
|
||||
itr->ModifyMatchmakerRating(mod, GetSlot());
|
||||
}
|
||||
|
||||
// update personal stats
|
||||
itr->WeekGames +=1;
|
||||
itr->SeasonGames +=1;
|
||||
itr->SeasonWins += 1;
|
||||
itr->WeekWins += 1;
|
||||
// update unit fields
|
||||
player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_WEEK, itr->WeekGames);
|
||||
player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_GAMES_SEASON, itr->SeasonGames);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& playerPoints)
|
||||
{
|
||||
// Called after a match has ended and the stats are already modified
|
||||
// Helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
|
||||
// 10 played games per week is a minimum
|
||||
if (Stats.WeekGames < 10)
|
||||
return;
|
||||
|
||||
// To get points, a player has to participate in at least 30% of the matches
|
||||
uint32 requiredGames = (uint32)ceil(Stats.WeekGames * 0.3f);
|
||||
|
||||
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
{
|
||||
// The player participated in enough games, update his points
|
||||
uint32 pointsToAdd = 0;
|
||||
if (itr->WeekGames >= requiredGames)
|
||||
pointsToAdd = GetPoints(itr->PersonalRating);
|
||||
|
||||
std::map<uint32, uint32>::iterator plr_itr = playerPoints.find(GUID_LOPART(itr->Guid));
|
||||
if (plr_itr != playerPoints.end())
|
||||
{
|
||||
// Check if there is already more points
|
||||
if (plr_itr->second < pointsToAdd)
|
||||
playerPoints[GUID_LOPART(itr->Guid)] = pointsToAdd;
|
||||
}
|
||||
else
|
||||
playerPoints[GUID_LOPART(itr->Guid)] = pointsToAdd;
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::SaveToDB()
|
||||
{
|
||||
// Save team and member stats to db
|
||||
// Called after a match has ended or when calculating arena_points
|
||||
|
||||
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ARENA_TEAM_STATS);
|
||||
stmt->setUInt16(0, Stats.Rating);
|
||||
stmt->setUInt16(1, Stats.WeekGames);
|
||||
stmt->setUInt16(2, Stats.WeekWins);
|
||||
stmt->setUInt16(3, Stats.SeasonGames);
|
||||
stmt->setUInt16(4, Stats.SeasonWins);
|
||||
stmt->setUInt32(5, Stats.Rank);
|
||||
stmt->setUInt32(6, GetId());
|
||||
trans->Append(stmt);
|
||||
|
||||
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
{
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ARENA_TEAM_MEMBER);
|
||||
stmt->setUInt16(0, itr->PersonalRating);
|
||||
stmt->setUInt16(1, itr->WeekGames);
|
||||
stmt->setUInt16(2, itr->WeekWins);
|
||||
stmt->setUInt16(3, itr->SeasonGames);
|
||||
stmt->setUInt16(4, itr->SeasonWins);
|
||||
stmt->setUInt32(5, GetId());
|
||||
stmt->setUInt32(6, GUID_LOPART(itr->Guid));
|
||||
trans->Append(stmt);
|
||||
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHARACTER_ARENA_STATS);
|
||||
stmt->setUInt32(0, GUID_LOPART(itr->Guid));
|
||||
stmt->setUInt8(1, GetSlot());
|
||||
stmt->setUInt16(2, itr->MatchMakerRating);
|
||||
stmt->setUInt16(3, itr->MaxMMR);
|
||||
trans->Append(stmt);
|
||||
}
|
||||
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
void ArenaTeam::FinishWeek()
|
||||
{
|
||||
// Reset team stats
|
||||
Stats.WeekGames = 0;
|
||||
Stats.WeekWins = 0;
|
||||
|
||||
// Reset member stats
|
||||
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
{
|
||||
itr->WeekGames = 0;
|
||||
itr->WeekWins = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ArenaTeam::IsFighting() const
|
||||
{
|
||||
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
if (Player* player = ObjectAccessor::FindPlayer(itr->Guid))
|
||||
if (player->GetMap()->IsBattleArena())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ArenaTeamMember* ArenaTeam::GetMember(const std::string& name)
|
||||
{
|
||||
return GetMember(sObjectMgr->GetPlayerGUIDByName(name));
|
||||
}
|
||||
|
||||
ArenaTeamMember* ArenaTeam::GetMember(uint64 guid)
|
||||
{
|
||||
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
|
||||
if (itr->Guid == guid)
|
||||
return &(*itr);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 SUNWELLCORE_ARENATEAM_H
|
||||
#define SUNWELLCORE_ARENATEAM_H
|
||||
|
||||
#include "QueryResult.h"
|
||||
#include "Map.h"
|
||||
#include <ace/Singleton.h>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
class WorldSession;
|
||||
class WorldPacket;
|
||||
class Player;
|
||||
class Group;
|
||||
|
||||
enum ArenaTeamCommandTypes
|
||||
{
|
||||
ERR_ARENA_TEAM_CREATE_S = 0x00,
|
||||
ERR_ARENA_TEAM_INVITE_SS = 0x01,
|
||||
ERR_ARENA_TEAM_QUIT_S = 0x03,
|
||||
ERR_ARENA_TEAM_FOUNDER_S = 0x0E
|
||||
};
|
||||
|
||||
enum ArenaTeamCommandErrors
|
||||
{
|
||||
ERR_ARENA_TEAM_INTERNAL = 0x01,
|
||||
ERR_ALREADY_IN_ARENA_TEAM = 0x02,
|
||||
ERR_ALREADY_IN_ARENA_TEAM_S = 0x03,
|
||||
ERR_INVITED_TO_ARENA_TEAM = 0x04,
|
||||
ERR_ALREADY_INVITED_TO_ARENA_TEAM_S = 0x05,
|
||||
ERR_ARENA_TEAM_NAME_INVALID = 0x06,
|
||||
ERR_ARENA_TEAM_NAME_EXISTS_S = 0x07,
|
||||
ERR_ARENA_TEAM_LEADER_LEAVE_S = 0x08,
|
||||
ERR_ARENA_TEAM_PERMISSIONS = 0x08,
|
||||
ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM = 0x09,
|
||||
ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS = 0x0A,
|
||||
ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S = 0x0B,
|
||||
ERR_ARENA_TEAM_NOT_ALLIED = 0x0C,
|
||||
ERR_ARENA_TEAM_IGNORING_YOU_S = 0x13,
|
||||
ERR_ARENA_TEAM_TARGET_TOO_LOW_S = 0x15,
|
||||
ERR_ARENA_TEAM_TARGET_TOO_HIGH_S = 0x16,
|
||||
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S = 0x17,
|
||||
ERR_ARENA_TEAM_NOT_FOUND = 0x1B,
|
||||
ERR_ARENA_TEAMS_LOCKED = 0x1E
|
||||
};
|
||||
|
||||
enum ArenaTeamEvents
|
||||
{
|
||||
ERR_ARENA_TEAM_JOIN_SS = 3, // player name + arena team name
|
||||
ERR_ARENA_TEAM_LEAVE_SS = 4, // player name + arena team name
|
||||
ERR_ARENA_TEAM_REMOVE_SSS = 5, // player name + arena team name + captain name
|
||||
ERR_ARENA_TEAM_LEADER_IS_SS = 6, // player name + arena team name
|
||||
ERR_ARENA_TEAM_LEADER_CHANGED_SSS = 7, // old captain + new captain + arena team name
|
||||
ERR_ARENA_TEAM_DISBANDED_S = 8 // captain name + arena team name
|
||||
};
|
||||
|
||||
/*
|
||||
need info how to send these ones:
|
||||
ERR_ARENA_TEAM_YOU_JOIN_S - client show it automatically when accept invite
|
||||
ERR_ARENA_TEAM_TARGET_TOO_LOW_S
|
||||
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S
|
||||
ERR_ARENA_TEAM_LEVEL_TOO_LOW_I
|
||||
*/
|
||||
|
||||
enum ArenaTeamTypes
|
||||
{
|
||||
ARENA_TEAM_2v2 = 2,
|
||||
ARENA_TEAM_3v3 = 3,
|
||||
ARENA_TEAM_5v5 = 5
|
||||
};
|
||||
|
||||
struct ArenaTeamMember
|
||||
{
|
||||
uint64 Guid;
|
||||
//std::string Name;
|
||||
uint8 Class;
|
||||
uint16 WeekGames;
|
||||
uint16 WeekWins;
|
||||
uint16 SeasonGames;
|
||||
uint16 SeasonWins;
|
||||
uint16 PersonalRating;
|
||||
uint16 MatchMakerRating;
|
||||
uint16 MaxMMR;
|
||||
|
||||
void ModifyPersonalRating(Player* player, int32 mod, uint32 type);
|
||||
void ModifyMatchmakerRating(int32 mod, uint32 slot);
|
||||
};
|
||||
|
||||
struct ArenaTeamStats
|
||||
{
|
||||
uint16 Rating;
|
||||
uint16 WeekGames;
|
||||
uint16 WeekWins;
|
||||
uint16 SeasonGames;
|
||||
uint16 SeasonWins;
|
||||
uint32 Rank;
|
||||
};
|
||||
|
||||
#define MAX_ARENA_SLOT 3 // 0..2 slots
|
||||
|
||||
class ArenaTeam
|
||||
{
|
||||
public:
|
||||
ArenaTeam();
|
||||
~ArenaTeam();
|
||||
|
||||
bool Create(uint64 captainGuid, uint8 type, std::string const& teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor);
|
||||
void Disband(WorldSession* session);
|
||||
|
||||
typedef std::list<ArenaTeamMember> MemberList;
|
||||
|
||||
uint32 GetId() const { return TeamId; }
|
||||
uint32 GetType() const { return Type; }
|
||||
uint8 GetSlot() const { return GetSlotByType(GetType()); }
|
||||
static uint8 GetSlotByType(uint32 type);
|
||||
uint64 GetCaptain() const { return CaptainGuid; }
|
||||
std::string const& GetName() const { return TeamName; }
|
||||
const ArenaTeamStats& GetStats() const { return Stats; }
|
||||
|
||||
uint32 GetRating() const { return Stats.Rating; }
|
||||
uint32 GetAverageMMR(Group* group) const;
|
||||
|
||||
void SetCaptain(uint64 guid);
|
||||
bool AddMember(uint64 playerGuid);
|
||||
|
||||
// Shouldn't be uint64 ed, because than can reference guid from members on Disband
|
||||
// and this method removes given record from list. So invalid reference can happen.
|
||||
void DelMember(uint64 guid, bool cleanDb);
|
||||
|
||||
size_t GetMembersSize() const { return Members.size(); }
|
||||
bool Empty() const { return Members.empty(); }
|
||||
MemberList::iterator m_membersBegin() { return Members.begin(); }
|
||||
MemberList::iterator m_membersEnd() { return Members.end(); }
|
||||
bool IsMember(uint64 guid) const;
|
||||
|
||||
ArenaTeamMember* GetMember(uint64 guid);
|
||||
ArenaTeamMember* GetMember(std::string const& name);
|
||||
|
||||
bool IsFighting() const;
|
||||
|
||||
bool LoadArenaTeamFromDB(QueryResult arenaTeamDataResult);
|
||||
bool LoadMembersFromDB(QueryResult arenaTeamMembersResult);
|
||||
void LoadStatsFromDB(uint32 ArenaTeamId);
|
||||
void SaveToDB();
|
||||
|
||||
void BroadcastPacket(WorldPacket* packet);
|
||||
void BroadcastEvent(ArenaTeamEvents event, uint64 guid, uint8 strCount, std::string const& str1, std::string const& str2, std::string const& str3);
|
||||
void NotifyStatsChanged();
|
||||
|
||||
void MassInviteToEvent(WorldSession* session);
|
||||
|
||||
void Roster(WorldSession* session);
|
||||
void Query(WorldSession* session);
|
||||
void SendStats(WorldSession* session);
|
||||
void Inspect(WorldSession* session, uint64 guid);
|
||||
|
||||
uint32 GetPoints(uint32 MemberRating);
|
||||
int32 GetMatchmakerRatingMod(uint32 ownRating, uint32 opponentRating, bool won);
|
||||
int32 GetRatingMod(uint32 ownRating, uint32 opponentRating, bool won);
|
||||
float GetChanceAgainst(uint32 ownRating, uint32 opponentRating);
|
||||
int32 WonAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32& rating_change, const Map* bgMap);
|
||||
void MemberWon(Player* player, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange);
|
||||
int32 LostAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32& rating_change, const Map* bgMap);
|
||||
void MemberLost(Player* player, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange = -12);
|
||||
|
||||
void UpdateArenaPointsHelper(std::map<uint32, uint32> & PlayerPoints);
|
||||
|
||||
void FinishWeek();
|
||||
void FinishGame(int32 mod, const Map* bgMap);
|
||||
|
||||
protected:
|
||||
|
||||
uint32 TeamId;
|
||||
uint8 Type;
|
||||
std::string TeamName;
|
||||
uint64 CaptainGuid;
|
||||
|
||||
uint32 BackgroundColor; // ARGB format
|
||||
uint8 EmblemStyle; // icon id
|
||||
uint32 EmblemColor; // ARGB format
|
||||
uint8 BorderStyle; // border image id
|
||||
uint32 BorderColor; // ARGB format
|
||||
|
||||
MemberList Members;
|
||||
ArenaTeamStats Stats;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 "Define.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "World.h"
|
||||
#include "Log.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Language.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
|
||||
ArenaTeamMgr::ArenaTeamMgr()
|
||||
{
|
||||
NextArenaTeamId = 1;
|
||||
LastArenaLogId = 0;
|
||||
}
|
||||
|
||||
ArenaTeamMgr::~ArenaTeamMgr()
|
||||
{
|
||||
for (ArenaTeamContainer::iterator itr = ArenaTeamStore.begin(); itr != ArenaTeamStore.end(); ++itr)
|
||||
delete itr->second;
|
||||
}
|
||||
|
||||
// Arena teams collection
|
||||
ArenaTeam* ArenaTeamMgr::GetArenaTeamById(uint32 arenaTeamId) const
|
||||
{
|
||||
ArenaTeamContainer::const_iterator itr = ArenaTeamStore.find(arenaTeamId);
|
||||
if (itr != ArenaTeamStore.end())
|
||||
return itr->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ArenaTeam* ArenaTeamMgr::GetArenaTeamByName(const std::string& arenaTeamName) const
|
||||
{
|
||||
std::string search = arenaTeamName;
|
||||
std::transform(search.begin(), search.end(), search.begin(), ::toupper);
|
||||
for (ArenaTeamContainer::const_iterator itr = ArenaTeamStore.begin(); itr != ArenaTeamStore.end(); ++itr)
|
||||
{
|
||||
std::string teamName = itr->second->GetName();
|
||||
std::transform(teamName.begin(), teamName.end(), teamName.begin(), ::toupper);
|
||||
if (search == teamName)
|
||||
return itr->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ArenaTeam* ArenaTeamMgr::GetArenaTeamByCaptain(uint64 guid) const
|
||||
{
|
||||
for (ArenaTeamContainer::const_iterator itr = ArenaTeamStore.begin(); itr != ArenaTeamStore.end(); ++itr)
|
||||
if (itr->second->GetCaptain() == guid)
|
||||
return itr->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ArenaTeamMgr::AddArenaTeam(ArenaTeam* arenaTeam)
|
||||
{
|
||||
ArenaTeamStore[arenaTeam->GetId()] = arenaTeam;
|
||||
}
|
||||
|
||||
void ArenaTeamMgr::RemoveArenaTeam(uint32 arenaTeamId)
|
||||
{
|
||||
ArenaTeamStore.erase(arenaTeamId);
|
||||
}
|
||||
|
||||
uint32 ArenaTeamMgr::GenerateArenaTeamId()
|
||||
{
|
||||
if (NextArenaTeamId >= 0xFFFFFFFE)
|
||||
{
|
||||
sLog->outError("Arena team ids overflow!! Can't continue, shutting down server. ");
|
||||
World::StopNow(ERROR_EXIT_CODE);
|
||||
}
|
||||
return NextArenaTeamId++;
|
||||
}
|
||||
|
||||
void ArenaTeamMgr::LoadArenaTeams()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// Clean out the trash before loading anything
|
||||
CharacterDatabase.Execute("DELETE FROM arena_team_member WHERE arenaTeamId NOT IN (SELECT arenaTeamId FROM arena_team)"); // One-time query
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
QueryResult result = CharacterDatabase.Query("SELECT arenaTeamId, name, captainGuid, type, backgroundColor, emblemStyle, emblemColor, borderStyle, borderColor, "
|
||||
// 9 10 11 12 13 14
|
||||
"rating, weekGames, weekWins, seasonGames, seasonWins, rank FROM arena_team ORDER BY arenaTeamId ASC");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
sLog->outString(">> Loaded 0 arena teams. DB table `arena_team` is empty!");
|
||||
sLog->outString();
|
||||
return;
|
||||
}
|
||||
|
||||
QueryResult result2 = CharacterDatabase.Query(
|
||||
// 0 1 2 3 4 5 6 7 8 9 10
|
||||
"SELECT arenaTeamId, atm.guid, atm.weekGames, atm.weekWins, atm.seasonGames, atm.seasonWins, c.name, class, personalRating, matchMakerRating, maxMMR FROM arena_team_member atm"
|
||||
" INNER JOIN arena_team ate USING (arenaTeamId)"
|
||||
" LEFT JOIN characters AS c ON atm.guid = c.guid"
|
||||
" LEFT JOIN character_arena_stats AS cas ON c.guid = cas.guid AND (cas.slot = 0 AND ate.type = 2 OR cas.slot = 1 AND ate.type = 3 OR cas.slot = 2 AND ate.type = 5)"
|
||||
" ORDER BY atm.arenateamid ASC");
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
ArenaTeam* newArenaTeam = new ArenaTeam;
|
||||
|
||||
if (!newArenaTeam->LoadArenaTeamFromDB(result) || !newArenaTeam->LoadMembersFromDB(result2))
|
||||
{
|
||||
newArenaTeam->Disband(NULL);
|
||||
delete newArenaTeam;
|
||||
continue;
|
||||
}
|
||||
|
||||
AddArenaTeam(newArenaTeam);
|
||||
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
sLog->outString(">> Loaded %u arena teams in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
sLog->outString();
|
||||
}
|
||||
|
||||
void ArenaTeamMgr::DistributeArenaPoints()
|
||||
{
|
||||
// Used to distribute arena points based on last week's stats
|
||||
sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_START);
|
||||
|
||||
sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_START);
|
||||
|
||||
// Temporary structure for storing maximum points to add values for all players
|
||||
std::map<uint32, uint32> PlayerPoints;
|
||||
|
||||
// At first update all points for all team members
|
||||
for (ArenaTeamContainer::iterator teamItr = GetArenaTeamMapBegin(); teamItr != GetArenaTeamMapEnd(); ++teamItr)
|
||||
if (ArenaTeam* at = teamItr->second)
|
||||
at->UpdateArenaPointsHelper(PlayerPoints);
|
||||
|
||||
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
PreparedStatement* stmt;
|
||||
|
||||
// Cycle that gives points to all players
|
||||
for (std::map<uint32, uint32>::iterator playerItr = PlayerPoints.begin(); playerItr != PlayerPoints.end(); ++playerItr)
|
||||
{
|
||||
// Add points to player if online
|
||||
if (Player* player = HashMapHolder<Player>::Find(playerItr->first))
|
||||
player->ModifyArenaPoints(playerItr->second, &trans);
|
||||
else // Update database
|
||||
{
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ARENA_POINTS);
|
||||
stmt->setUInt32(0, playerItr->second);
|
||||
stmt->setUInt32(1, playerItr->first);
|
||||
trans->Append(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
|
||||
PlayerPoints.clear();
|
||||
|
||||
sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_END);
|
||||
|
||||
sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_START);
|
||||
for (ArenaTeamContainer::iterator titr = GetArenaTeamMapBegin(); titr != GetArenaTeamMapEnd(); ++titr)
|
||||
{
|
||||
if (ArenaTeam* at = titr->second)
|
||||
{
|
||||
at->FinishWeek();
|
||||
at->SaveToDB();
|
||||
at->NotifyStatsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_END);
|
||||
|
||||
sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_END);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 _ARENATEAMMGR_H
|
||||
#define _ARENATEAMMGR_H
|
||||
|
||||
#include "ArenaTeam.h"
|
||||
|
||||
class ArenaTeamMgr
|
||||
{
|
||||
friend class ACE_Singleton<ArenaTeamMgr, ACE_Null_Mutex>;
|
||||
ArenaTeamMgr();
|
||||
~ArenaTeamMgr();
|
||||
|
||||
public:
|
||||
typedef UNORDERED_MAP<uint32, ArenaTeam*> ArenaTeamContainer;
|
||||
|
||||
ArenaTeam* GetArenaTeamById(uint32 arenaTeamId) const;
|
||||
ArenaTeam* GetArenaTeamByName(std::string const& arenaTeamName) const;
|
||||
ArenaTeam* GetArenaTeamByCaptain(uint64 guid) const;
|
||||
|
||||
void LoadArenaTeams();
|
||||
void AddArenaTeam(ArenaTeam* arenaTeam);
|
||||
void RemoveArenaTeam(uint32 Id);
|
||||
|
||||
ArenaTeamContainer::iterator GetArenaTeamMapBegin() { return ArenaTeamStore.begin(); }
|
||||
ArenaTeamContainer::iterator GetArenaTeamMapEnd() { return ArenaTeamStore.end(); }
|
||||
|
||||
void DistributeArenaPoints();
|
||||
|
||||
uint32 GenerateArenaTeamId();
|
||||
void SetNextArenaTeamId(uint32 Id) { NextArenaTeamId = Id; }
|
||||
|
||||
uint32 GetNextArenaLogId() { return ++LastArenaLogId; }
|
||||
void SetLastArenaLogId(uint32 id) { LastArenaLogId = id; }
|
||||
|
||||
protected:
|
||||
uint32 NextArenaTeamId;
|
||||
ArenaTeamContainer ArenaTeamStore;
|
||||
uint32 LastArenaLogId;
|
||||
};
|
||||
|
||||
#define sArenaTeamMgr ACE_Singleton<ArenaTeamMgr, ACE_Null_Mutex>::instance()
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,720 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 __BATTLEGROUND_H
|
||||
#define __BATTLEGROUND_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "DBCEnums.h"
|
||||
#include "GameObject.h"
|
||||
|
||||
class Creature;
|
||||
class GameObject;
|
||||
class Group;
|
||||
class Player;
|
||||
class WorldPacket;
|
||||
class BattlegroundMap;
|
||||
class BattlegroundAV;
|
||||
class BattlegroundWS;
|
||||
class BattlegroundAB;
|
||||
class BattlegroundNA;
|
||||
class BattlegroundBE;
|
||||
class BattlegroundEY;
|
||||
class BattlegroundRL;
|
||||
class BattlegroundSA;
|
||||
class BattlegroundDS;
|
||||
class BattlegroundRV;
|
||||
class BattlegroundIC;
|
||||
|
||||
struct PvPDifficultyEntry;
|
||||
struct WorldSafeLocsEntry;
|
||||
|
||||
enum BattlegroundSounds
|
||||
{
|
||||
SOUND_HORDE_WINS = 8454,
|
||||
SOUND_ALLIANCE_WINS = 8455,
|
||||
SOUND_BG_START = 3439,
|
||||
SOUND_BG_START_L70ETC = 11803,
|
||||
};
|
||||
|
||||
enum BattlegroundQuests
|
||||
{
|
||||
SPELL_WS_QUEST_REWARD = 43483,
|
||||
SPELL_AB_QUEST_REWARD = 43484,
|
||||
SPELL_AV_QUEST_REWARD = 43475,
|
||||
SPELL_AV_QUEST_KILLED_BOSS = 23658,
|
||||
SPELL_EY_QUEST_REWARD = 43477,
|
||||
SPELL_SA_QUEST_REWARD = 61213,
|
||||
SPELL_AB_QUEST_REWARD_4_BASES = 24061,
|
||||
SPELL_AB_QUEST_REWARD_5_BASES = 24064
|
||||
};
|
||||
|
||||
enum BattlegroundMarks
|
||||
{
|
||||
SPELL_WS_MARK_LOSER = 24950,
|
||||
SPELL_WS_MARK_WINNER = 24951,
|
||||
SPELL_AB_MARK_LOSER = 24952,
|
||||
SPELL_AB_MARK_WINNER = 24953,
|
||||
SPELL_AV_MARK_LOSER = 24954,
|
||||
SPELL_AV_MARK_WINNER = 24955,
|
||||
SPELL_SA_MARK_WINNER = 61160,
|
||||
SPELL_SA_MARK_LOSER = 61159,
|
||||
SPELL_WG_MARK_WINNER = 56902,
|
||||
ITEM_AV_MARK_OF_HONOR = 20560,
|
||||
ITEM_WS_MARK_OF_HONOR = 20558,
|
||||
ITEM_AB_MARK_OF_HONOR = 20559,
|
||||
ITEM_EY_MARK_OF_HONOR = 29024,
|
||||
ITEM_SA_MARK_OF_HONOR = 42425,
|
||||
ITEM_IC_MARK_OF_HONOR = 47395,
|
||||
};
|
||||
|
||||
enum BattlegroundMarksCount
|
||||
{
|
||||
ITEM_WINNER_COUNT = 3,
|
||||
ITEM_LOSER_COUNT = 1
|
||||
};
|
||||
|
||||
enum BattlegroundCreatures
|
||||
{
|
||||
BG_CREATURE_ENTRY_A_SPIRITGUIDE = 13116, // alliance
|
||||
BG_CREATURE_ENTRY_H_SPIRITGUIDE = 13117, // horde
|
||||
};
|
||||
|
||||
enum BattlegroundSpells
|
||||
{
|
||||
SPELL_WAITING_FOR_RESURRECT = 2584, // Waiting to Resurrect
|
||||
SPELL_SPIRIT_HEAL_CHANNEL = 22011, // Spirit Heal Channel
|
||||
SPELL_SPIRIT_HEAL = 22012, // Spirit Heal
|
||||
SPELL_RESURRECTION_VISUAL = 24171, // Resurrection Impact Visual
|
||||
SPELL_ARENA_PREPARATION = 32727, // use this one, 32728 not correct
|
||||
SPELL_ALLIANCE_GOLD_FLAG = 32724,
|
||||
SPELL_ALLIANCE_GREEN_FLAG = 32725,
|
||||
SPELL_HORDE_GOLD_FLAG = 35774,
|
||||
SPELL_HORDE_GREEN_FLAG = 35775,
|
||||
SPELL_PREPARATION = 44521, // Preparation
|
||||
SPELL_SPIRIT_HEAL_MANA = 44535, // Spirit Heal
|
||||
SPELL_RECENTLY_DROPPED_FLAG = 42792, // Recently Dropped Flag
|
||||
SPELL_AURA_PLAYER_INACTIVE = 43681, // Inactive
|
||||
SPELL_HONORABLE_DEFENDER_25Y = 68652, // +50% honor when standing at a capture point that you control, 25yards radius (added in 3.2)
|
||||
SPELL_HONORABLE_DEFENDER_60Y = 66157, // +50% honor when standing at a capture point that you control, 60yards radius (added in 3.2), probably for 40+ player battlegrounds
|
||||
SPELL_THE_LAST_STANDING = 26549, // Arena achievement related
|
||||
};
|
||||
|
||||
enum BattlegroundTimeIntervals
|
||||
{
|
||||
CHECK_PLAYER_POSITION_INVERVAL = 9000, // ms
|
||||
RESURRECTION_INTERVAL = 30000, // ms
|
||||
//REMIND_INTERVAL = 10000, // ms
|
||||
INVITATION_REMIND_TIME = 20000, // ms
|
||||
INVITE_ACCEPT_WAIT_TIME = 60000, // ms
|
||||
TIME_TO_AUTOREMOVE = 120000, // ms
|
||||
MAX_OFFLINE_TIME = 300, // secs
|
||||
RESPAWN_ONE_DAY = 86400, // secs
|
||||
RESPAWN_IMMEDIATELY = 0, // secs
|
||||
BUFF_RESPAWN_TIME = 180, // secs
|
||||
};
|
||||
|
||||
enum BattlegroundStartTimeIntervals
|
||||
{
|
||||
BG_START_DELAY_2M = 120000, // ms (2 minutes)
|
||||
BG_START_DELAY_1M = 60000, // ms (1 minute)
|
||||
BG_START_DELAY_30S = 30000, // ms (30 seconds)
|
||||
BG_START_DELAY_15S = 15000, // ms (15 seconds) Used only in arena
|
||||
BG_START_DELAY_NONE = 0, // ms
|
||||
};
|
||||
|
||||
#define BATTLEGROUND_UPDATE_INTERVAL 1000
|
||||
|
||||
enum BattlegroundBuffObjects
|
||||
{
|
||||
BG_OBJECTID_SPEEDBUFF_ENTRY = 179871,
|
||||
BG_OBJECTID_REGENBUFF_ENTRY = 179904,
|
||||
BG_OBJECTID_BERSERKERBUFF_ENTRY = 179905
|
||||
};
|
||||
|
||||
enum BattlegroundRandomRewards
|
||||
{
|
||||
BG_REWARD_WINNER_HONOR_FIRST = 30,
|
||||
BG_REWARD_WINNER_ARENA_FIRST = 25,
|
||||
BG_REWARD_WINNER_HONOR_LAST = 15,
|
||||
BG_REWARD_WINNER_ARENA_LAST = 0,
|
||||
BG_REWARD_LOSER_HONOR_FIRST = 5,
|
||||
BG_REWARD_LOSER_HONOR_LAST = 5
|
||||
};
|
||||
|
||||
const uint32 Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENBUFF_ENTRY, BG_OBJECTID_BERSERKERBUFF_ENTRY };
|
||||
|
||||
enum BattlegroundStatus
|
||||
{
|
||||
STATUS_NONE = 0, // first status, should mean bg is not instance
|
||||
STATUS_WAIT_QUEUE = 1, // means bg is empty and waiting for queue
|
||||
STATUS_WAIT_JOIN = 2, // this means, that BG has already started and it is waiting for more players
|
||||
STATUS_IN_PROGRESS = 3, // means bg is running
|
||||
STATUS_WAIT_LEAVE = 4 // means some faction has won BG and it is ending
|
||||
};
|
||||
|
||||
enum BattlegroundTeams
|
||||
{
|
||||
BG_TEAMS_COUNT = 2
|
||||
};
|
||||
|
||||
struct BattlegroundObjectInfo
|
||||
{
|
||||
BattlegroundObjectInfo() : object(NULL), timer(0), spellid(0) {}
|
||||
|
||||
GameObject *object;
|
||||
int32 timer;
|
||||
uint32 spellid;
|
||||
};
|
||||
|
||||
enum ScoreType
|
||||
{
|
||||
SCORE_KILLING_BLOWS = 1,
|
||||
SCORE_DEATHS = 2,
|
||||
SCORE_HONORABLE_KILLS = 3,
|
||||
SCORE_BONUS_HONOR = 4,
|
||||
//EY, but in MSG_PVP_LOG_DATA opcode!
|
||||
SCORE_DAMAGE_DONE = 5,
|
||||
SCORE_HEALING_DONE = 6,
|
||||
//WS
|
||||
SCORE_FLAG_CAPTURES = 7,
|
||||
SCORE_FLAG_RETURNS = 8,
|
||||
//AB and IC
|
||||
SCORE_BASES_ASSAULTED = 9,
|
||||
SCORE_BASES_DEFENDED = 10,
|
||||
//AV
|
||||
SCORE_GRAVEYARDS_ASSAULTED = 11,
|
||||
SCORE_GRAVEYARDS_DEFENDED = 12,
|
||||
SCORE_TOWERS_ASSAULTED = 13,
|
||||
SCORE_TOWERS_DEFENDED = 14,
|
||||
SCORE_MINES_CAPTURED = 15,
|
||||
SCORE_LEADERS_KILLED = 16,
|
||||
SCORE_SECONDARY_OBJECTIVES = 17,
|
||||
//SOTA
|
||||
SCORE_DESTROYED_DEMOLISHER = 18,
|
||||
SCORE_DESTROYED_WALL = 19,
|
||||
};
|
||||
|
||||
enum ArenaType
|
||||
{
|
||||
ARENA_TYPE_2v2 = 2,
|
||||
ARENA_TYPE_3v3 = 3,
|
||||
ARENA_TYPE_5v5 = 5
|
||||
};
|
||||
|
||||
enum BattlegroundType
|
||||
{
|
||||
TYPE_BATTLEGROUND = 3,
|
||||
TYPE_ARENA = 4
|
||||
};
|
||||
|
||||
enum BattlegroundStartingEvents
|
||||
{
|
||||
BG_STARTING_EVENT_NONE = 0x00,
|
||||
BG_STARTING_EVENT_1 = 0x01,
|
||||
BG_STARTING_EVENT_2 = 0x02,
|
||||
BG_STARTING_EVENT_3 = 0x04,
|
||||
BG_STARTING_EVENT_4 = 0x08
|
||||
};
|
||||
|
||||
enum BattlegroundStartingEventsIds
|
||||
{
|
||||
BG_STARTING_EVENT_FIRST = 0,
|
||||
BG_STARTING_EVENT_SECOND = 1,
|
||||
BG_STARTING_EVENT_THIRD = 2,
|
||||
BG_STARTING_EVENT_FOURTH = 3
|
||||
};
|
||||
#define BG_STARTING_EVENT_COUNT 4
|
||||
|
||||
struct BattlegroundScore
|
||||
{
|
||||
BattlegroundScore(Player* player) : KillingBlows(0), Deaths(0), HonorableKills(0), BonusHonor(0),
|
||||
DamageDone(0), HealingDone(0), player(player)
|
||||
{ }
|
||||
|
||||
virtual ~BattlegroundScore() { } //virtual destructor is used when deleting score from scores map
|
||||
|
||||
uint32 KillingBlows;
|
||||
uint32 Deaths;
|
||||
uint32 HonorableKills;
|
||||
uint32 BonusHonor;
|
||||
uint32 DamageDone;
|
||||
uint32 HealingDone;
|
||||
Player* player;
|
||||
};
|
||||
|
||||
class ArenaLogEntryData
|
||||
{
|
||||
public:
|
||||
ArenaLogEntryData() : Guid(0), ArenaTeamId(0), DamageDone(0), HealingDone(0), KillingBlows(0) {}
|
||||
void Fill(const char* name, uint32 guid, uint32 acc, uint32 arenaTeamId, std::string ip)
|
||||
{
|
||||
Name = std::string(name);
|
||||
Guid = guid;
|
||||
Acc = acc;
|
||||
ArenaTeamId = arenaTeamId;
|
||||
IP = ip;
|
||||
}
|
||||
|
||||
std::string Name;
|
||||
uint32 Guid;
|
||||
uint32 Acc;
|
||||
uint32 ArenaTeamId;
|
||||
std::string IP;
|
||||
uint32 DamageDone;
|
||||
uint32 HealingDone;
|
||||
uint32 KillingBlows;
|
||||
};
|
||||
|
||||
enum BGHonorMode
|
||||
{
|
||||
BG_NORMAL = 0,
|
||||
BG_HOLIDAY,
|
||||
BG_HONOR_MODE_NUM
|
||||
};
|
||||
|
||||
#define BG_AWARD_ARENA_POINTS_MIN_LEVEL 71
|
||||
#define ARENA_TIMELIMIT_POINTS_LOSS -16
|
||||
#define ARENA_READY_MARKER_ENTRY 301337
|
||||
|
||||
/*
|
||||
This class is used to:
|
||||
1. Add player to battleground
|
||||
2. Remove player from battleground
|
||||
3. some certain cases, same for all battlegrounds
|
||||
4. It has properties same for all battlegrounds
|
||||
*/
|
||||
class Battleground
|
||||
{
|
||||
public:
|
||||
Battleground();
|
||||
virtual ~Battleground();
|
||||
|
||||
void Update(uint32 diff);
|
||||
|
||||
virtual bool SetupBattleground() // must be implemented in BG subclass
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual void Init();
|
||||
virtual void StartingEventCloseDoors() { }
|
||||
virtual void StartingEventOpenDoors() { }
|
||||
virtual void ResetBGSubclass() { } // must be implemented in BG subclass
|
||||
|
||||
virtual void DestroyGate(Player* /*player*/, GameObject* /*go*/) {}
|
||||
|
||||
/* achievement req. */
|
||||
virtual bool AllNodesConrolledByTeam(TeamId /*teamId*/) const { return false; }
|
||||
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry);
|
||||
|
||||
/* Battleground */
|
||||
// Get methods:
|
||||
char const* GetName() const { return m_Name; }
|
||||
BattlegroundTypeId GetBgTypeID() const { return m_RealTypeID; }
|
||||
uint32 GetInstanceID() const { return m_InstanceID; }
|
||||
BattlegroundStatus GetStatus() const { return m_Status; }
|
||||
uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
|
||||
uint32 GetStartTime() const { return m_StartTime; }
|
||||
uint32 GetEndTime() const { return m_EndTime; }
|
||||
uint32 GetLastResurrectTime() const { return m_LastResurrectTime; }
|
||||
|
||||
uint32 GetMinLevel() const { return m_LevelMin; }
|
||||
uint32 GetMaxLevel() const { return m_LevelMax; }
|
||||
|
||||
uint32 GetMaxPlayersPerTeam() const { return m_MaxPlayersPerTeam; }
|
||||
uint32 GetMinPlayersPerTeam() const { return m_MinPlayersPerTeam; }
|
||||
|
||||
int32 GetStartDelayTime() const { return m_StartDelayTime; }
|
||||
uint8 GetArenaType() const { return m_ArenaType; }
|
||||
TeamId GetWinner() const { return m_WinnerId; }
|
||||
uint32 GetScriptId() const { return ScriptId; }
|
||||
uint32 GetBonusHonorFromKill(uint32 kills) const;
|
||||
|
||||
// Set methods:
|
||||
void SetName(char const* Name) { m_Name = Name; }
|
||||
void SetBgTypeID(BattlegroundTypeId TypeID) { m_RealTypeID = TypeID; }
|
||||
void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
|
||||
void SetStatus(BattlegroundStatus Status) { m_Status = Status; }
|
||||
void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; }
|
||||
void SetStartTime(uint32 Time) { m_StartTime = Time; }
|
||||
void SetEndTime(uint32 Time) { m_EndTime = Time; }
|
||||
void SetLastResurrectTime(uint32 Time) { m_LastResurrectTime = Time; }
|
||||
void SetLevelRange(uint32 min, uint32 max) { m_LevelMin = min; m_LevelMax = max; }
|
||||
void SetRated(bool state) { m_IsRated = state; }
|
||||
void SetArenaType(uint8 type) { m_ArenaType = type; }
|
||||
void SetArenaorBGType(bool _isArena) { m_IsArena = _isArena; }
|
||||
void SetWinner(TeamId winner) { m_WinnerId = winner; }
|
||||
void SetScriptId(uint32 scriptId) { ScriptId = scriptId; }
|
||||
|
||||
void ModifyStartDelayTime(int32 diff) { m_StartDelayTime -= diff; }
|
||||
void SetStartDelayTime(int32 Time) { m_StartDelayTime = Time; }
|
||||
|
||||
void SetMaxPlayersPerTeam(uint32 MaxPlayers) { m_MaxPlayersPerTeam = MaxPlayers; }
|
||||
void SetMinPlayersPerTeam(uint32 MinPlayers) { m_MinPlayersPerTeam = MinPlayers; }
|
||||
|
||||
void DecreaseInvitedCount(TeamId teamId) { ASSERT(m_BgInvitedPlayers[teamId] > 0); --m_BgInvitedPlayers[teamId]; }
|
||||
void IncreaseInvitedCount(TeamId teamId) { ++m_BgInvitedPlayers[teamId]; }
|
||||
uint32 GetInvitedCount(TeamId teamId) const { return m_BgInvitedPlayers[teamId]; }
|
||||
|
||||
bool HasFreeSlots() const;
|
||||
uint32 GetFreeSlotsForTeam(TeamId teamId) const;
|
||||
uint32 GetMaxFreeSlots() const;
|
||||
|
||||
typedef std::set<Player*> SpectatorList;
|
||||
typedef std::map<uint64, uint64> ToBeTeleportedMap;
|
||||
void AddSpectator(Player* p) { m_Spectators.insert(p); }
|
||||
void RemoveSpectator(Player* p) { m_Spectators.erase(p); }
|
||||
bool HaveSpectators() { return !m_Spectators.empty(); }
|
||||
const SpectatorList& GetSpectators() const { return m_Spectators; }
|
||||
void AddToBeTeleported(uint64 spectator, uint64 participant) { m_ToBeTeleported[spectator] = participant; }
|
||||
void RemoveToBeTeleported(uint64 spectator) { ToBeTeleportedMap::iterator itr = m_ToBeTeleported.find(spectator); if (itr != m_ToBeTeleported.end()) m_ToBeTeleported.erase(itr); }
|
||||
void SpectatorsSendPacket(WorldPacket& data);
|
||||
|
||||
bool isArena() const { return m_IsArena; }
|
||||
bool isBattleground() const { return !m_IsArena; }
|
||||
bool isRated() const { return m_IsRated; }
|
||||
|
||||
typedef std::map<uint64, Player*> BattlegroundPlayerMap;
|
||||
BattlegroundPlayerMap const& GetPlayers() const { return m_Players; }
|
||||
uint32 GetPlayersSize() const { return m_Players.size(); }
|
||||
|
||||
void ReadyMarkerClicked(Player* p); // pussywizard
|
||||
std::set<uint32> readyMarkerClickedSet; // pussywizard
|
||||
|
||||
typedef std::map<uint64, BattlegroundScore*> BattlegroundScoreMap;
|
||||
typedef std::map<uint64, ArenaLogEntryData> ArenaLogEntryDataMap;// pussywizard
|
||||
ArenaLogEntryDataMap ArenaLogEntries; // pussywizard
|
||||
BattlegroundScoreMap::const_iterator GetPlayerScoresBegin() const { return PlayerScores.begin(); }
|
||||
BattlegroundScoreMap::const_iterator GetPlayerScoresEnd() const { return PlayerScores.end(); }
|
||||
uint32 GetPlayerScoresSize() const { return PlayerScores.size(); }
|
||||
|
||||
uint32 GetReviveQueueSize() const { return m_ReviveQueue.size(); }
|
||||
|
||||
void AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid);
|
||||
void RemovePlayerFromResurrectQueue(Player* player);
|
||||
|
||||
/// Relocate all players in ReviveQueue to the closest graveyard
|
||||
void RelocateDeadPlayers(uint64 queueIndex);
|
||||
|
||||
void StartBattleground();
|
||||
|
||||
GameObject* GetBGObject(uint32 type);
|
||||
Creature* GetBGCreature(uint32 type);
|
||||
|
||||
// Location
|
||||
void SetMapId(uint32 MapID) { m_MapId = MapID; }
|
||||
uint32 GetMapId() const { return m_MapId; }
|
||||
|
||||
// Map pointers
|
||||
void SetBgMap(BattlegroundMap* map) { m_Map = map; }
|
||||
BattlegroundMap* GetBgMap() const { ASSERT(m_Map); return m_Map; }
|
||||
BattlegroundMap* FindBgMap() const { return m_Map; }
|
||||
|
||||
void SetTeamStartLoc(TeamId teamId, float X, float Y, float Z, float O);
|
||||
void GetTeamStartLoc(TeamId teamId, float &X, float &Y, float &Z, float &O) const
|
||||
{
|
||||
X = m_TeamStartLocX[teamId];
|
||||
Y = m_TeamStartLocY[teamId];
|
||||
Z = m_TeamStartLocZ[teamId];
|
||||
O = m_TeamStartLocO[teamId];
|
||||
}
|
||||
|
||||
void SetStartMaxDist(float startMaxDist) { m_StartMaxDist = startMaxDist; }
|
||||
float GetStartMaxDist() const { return m_StartMaxDist; }
|
||||
|
||||
// Packet Transfer
|
||||
// method that should fill worldpacket with actual world states (not yet implemented for all battlegrounds!)
|
||||
virtual void FillInitialWorldStates(WorldPacket& /*data*/) {}
|
||||
void SendPacketToTeam(TeamId teamId, WorldPacket* packet, Player* sender = NULL, bool self = true);
|
||||
void SendPacketToAll(WorldPacket* packet);
|
||||
void YellToAll(Creature* creature, const char* text, uint32 language);
|
||||
|
||||
template<class Do>
|
||||
void BroadcastWorker(Do& _do);
|
||||
|
||||
void PlaySoundToAll(uint32 soundId);
|
||||
void CastSpellOnTeam(uint32 spellId, TeamId teamId);
|
||||
void RemoveAuraOnTeam(uint32 spellId, TeamId teamId);
|
||||
void RewardHonorToTeam(uint32 honor, TeamId teamId);
|
||||
void RewardReputationToTeam(uint32 factionId, uint32 reputation, TeamId teamId);
|
||||
|
||||
void UpdateWorldState(uint32 Field, uint32 Value);
|
||||
void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player* player);
|
||||
void EndBattleground(TeamId winnerTeamId);
|
||||
void BlockMovement(Player* player);
|
||||
|
||||
void SendWarningToAll(int32 entry, ...);
|
||||
void SendMessageToAll(int32 entry, ChatMsg type, Player const* source = NULL);
|
||||
void PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ...);
|
||||
|
||||
// specialized version with 2 string id args
|
||||
void SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 strId1 = 0, int32 strId2 = 0);
|
||||
|
||||
// Raid Group
|
||||
Group* GetBgRaid(TeamId teamId) const { return m_BgRaids[teamId]; }
|
||||
void SetBgRaid(TeamId teamId, Group* bg_raid);
|
||||
|
||||
virtual void UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
|
||||
uint32 GetPlayersCountByTeam(TeamId teamId) const { return m_PlayersCount[teamId]; }
|
||||
uint32 GetAlivePlayersCountByTeam(TeamId teamId) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases
|
||||
void UpdatePlayersCountByTeam(TeamId teamId, bool remove)
|
||||
{
|
||||
if (remove)
|
||||
--m_PlayersCount[teamId];
|
||||
else
|
||||
++m_PlayersCount[teamId];
|
||||
}
|
||||
|
||||
// used for rated arena battles
|
||||
void SetArenaTeamIdForTeam(TeamId teamId, uint32 ArenaTeamId) { m_ArenaTeamIds[teamId] = ArenaTeamId; }
|
||||
uint32 GetArenaTeamIdForTeam(TeamId teamId) const { return m_ArenaTeamIds[teamId]; }
|
||||
void SetArenaTeamRatingChangeForTeam(TeamId teamId, int32 RatingChange) { m_ArenaTeamRatingChanges[teamId] = RatingChange; }
|
||||
int32 GetArenaTeamRatingChangeForTeam(TeamId teamId) const { return m_ArenaTeamRatingChanges[teamId]; }
|
||||
void SetArenaMatchmakerRating(TeamId teamId, uint32 MMR) { m_ArenaTeamMMR[teamId] = MMR; }
|
||||
uint32 GetArenaMatchmakerRating(TeamId teamId) const { return m_ArenaTeamMMR[teamId]; }
|
||||
void CheckArenaAfterTimerConditions();
|
||||
void CheckArenaWinConditions();
|
||||
virtual void UpdateArenaWorldState();
|
||||
|
||||
// Triggers handle
|
||||
// must be implemented in BG subclass
|
||||
virtual void HandleAreaTrigger(Player* /*player*/, uint32 /*trigger*/) {}
|
||||
// must be implemented in BG subclass if need AND call base class generic code
|
||||
virtual void HandleKillPlayer(Player* player, Player* killer);
|
||||
virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/);
|
||||
|
||||
// Battleground events
|
||||
virtual void EventPlayerDroppedFlag(Player* /*player*/) {}
|
||||
virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*gameObject*/) {}
|
||||
virtual void EventPlayerDamagedGO(Player* /*player*/, GameObject* /*go*/, uint32 /*eventType*/) {}
|
||||
virtual void EventPlayerUsedGO(Player* /*player*/, GameObject* /*go*/){}
|
||||
|
||||
// this function can be used by spell to interact with the BG map
|
||||
virtual void DoAction(uint32 /*action*/, uint64 /*var*/) {}
|
||||
|
||||
virtual void HandlePlayerResurrect(Player* /*player*/) {}
|
||||
|
||||
// Death related
|
||||
virtual WorldSafeLocsEntry const* GetClosestGraveyard(Player* player);
|
||||
|
||||
virtual void AddPlayer(Player* player); // must be implemented in BG subclass
|
||||
|
||||
void AddOrSetPlayerToCorrectBgGroup(Player* player, TeamId teamId);
|
||||
|
||||
void RemovePlayerAtLeave(Player* player);
|
||||
// can be extended in in BG subclass
|
||||
|
||||
void HandleTriggerBuff(GameObject* gameObject);
|
||||
void SetHoliday(bool is_holiday);
|
||||
|
||||
// TODO: make this protected:
|
||||
typedef std::vector<uint64> BGObjects;
|
||||
typedef std::vector<uint64> BGCreatures;
|
||||
BGObjects BgObjects;
|
||||
BGCreatures BgCreatures;
|
||||
void SpawnBGObject(uint32 type, uint32 respawntime);
|
||||
bool AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0, GOState goState = GO_STATE_READY);
|
||||
Creature* AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, uint32 respawntime = 0, MotionTransport* transport = NULL);
|
||||
bool DelCreature(uint32 type);
|
||||
bool DelObject(uint32 type);
|
||||
bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, TeamId teamId);
|
||||
int32 GetObjectType(uint64 guid);
|
||||
|
||||
void DoorOpen(uint32 type);
|
||||
void DoorClose(uint32 type);
|
||||
//to be removed
|
||||
const char* GetTrinityString(int32 entry);
|
||||
|
||||
virtual bool HandlePlayerUnderMap(Player* /*player*/) { return false; }
|
||||
|
||||
// since arenas can be AvA or Hvh, we have to get the "temporary" team of a player
|
||||
static TeamId GetOtherTeamId(TeamId teamId);
|
||||
bool IsPlayerInBattleground(uint64 guid) const;
|
||||
|
||||
bool ToBeDeleted() const { return m_SetDeleteThis; }
|
||||
//void SetDeleteThis() { m_SetDeleteThis = true; }
|
||||
|
||||
void RewardXPAtKill(Player* killer, Player* victim);
|
||||
|
||||
virtual uint64 GetFlagPickerGUID(TeamId /*teamId*/ = TEAM_NEUTRAL) const { return 0; }
|
||||
virtual void SetDroppedFlagGUID(uint64 /*guid*/, TeamId /*teamId*/ = TEAM_NEUTRAL) {}
|
||||
uint32 GetTeamScore(TeamId teamId) const;
|
||||
|
||||
virtual TeamId GetPrematureWinner();
|
||||
|
||||
BattlegroundAV* ToBattlegroundAV() { if (GetBgTypeID() == BATTLEGROUND_AV) return reinterpret_cast<BattlegroundAV*>(this); else return NULL; }
|
||||
BattlegroundAV const* ToBattlegroundAV() const { if (GetBgTypeID() == BATTLEGROUND_AV) return reinterpret_cast<const BattlegroundAV*>(this); else return NULL; }
|
||||
|
||||
BattlegroundWS* ToBattlegroundWS() { if (GetBgTypeID() == BATTLEGROUND_WS) return reinterpret_cast<BattlegroundWS*>(this); else return NULL; }
|
||||
BattlegroundWS const* ToBattlegroundWS() const { if (GetBgTypeID() == BATTLEGROUND_WS) return reinterpret_cast<const BattlegroundWS*>(this); else return NULL; }
|
||||
|
||||
BattlegroundAB* ToBattlegroundAB() { if (GetBgTypeID() == BATTLEGROUND_AB) return reinterpret_cast<BattlegroundAB*>(this); else return NULL; }
|
||||
BattlegroundAB const* ToBattlegroundAB() const { if (GetBgTypeID() == BATTLEGROUND_AB) return reinterpret_cast<const BattlegroundAB*>(this); else return NULL; }
|
||||
|
||||
BattlegroundNA* ToBattlegroundNA() { if (GetBgTypeID() == BATTLEGROUND_NA) return reinterpret_cast<BattlegroundNA*>(this); else return NULL; }
|
||||
BattlegroundNA const* ToBattlegroundNA() const { if (GetBgTypeID() == BATTLEGROUND_NA) return reinterpret_cast<const BattlegroundNA*>(this); else return NULL; }
|
||||
|
||||
BattlegroundBE* ToBattlegroundBE() { if (GetBgTypeID() == BATTLEGROUND_BE) return reinterpret_cast<BattlegroundBE*>(this); else return NULL; }
|
||||
BattlegroundBE const* ToBattlegroundBE() const { if (GetBgTypeID() == BATTLEGROUND_BE) return reinterpret_cast<const BattlegroundBE*>(this); else return NULL; }
|
||||
|
||||
BattlegroundEY* ToBattlegroundEY() { if (GetBgTypeID() == BATTLEGROUND_EY) return reinterpret_cast<BattlegroundEY*>(this); else return NULL; }
|
||||
BattlegroundEY const* ToBattlegroundEY() const { if (GetBgTypeID() == BATTLEGROUND_EY) return reinterpret_cast<const BattlegroundEY*>(this); else return NULL; }
|
||||
|
||||
BattlegroundRL* ToBattlegroundRL() { if (GetBgTypeID() == BATTLEGROUND_RL) return reinterpret_cast<BattlegroundRL*>(this); else return NULL; }
|
||||
BattlegroundRL const* ToBattlegroundRL() const { if (GetBgTypeID() == BATTLEGROUND_RL) return reinterpret_cast<const BattlegroundRL*>(this); else return NULL; }
|
||||
|
||||
BattlegroundSA* ToBattlegroundSA() { if (GetBgTypeID() == BATTLEGROUND_SA) return reinterpret_cast<BattlegroundSA*>(this); else return NULL; }
|
||||
BattlegroundSA const* ToBattlegroundSA() const { if (GetBgTypeID() == BATTLEGROUND_SA) return reinterpret_cast<const BattlegroundSA*>(this); else return NULL; }
|
||||
|
||||
BattlegroundDS* ToBattlegroundDS() { if (GetBgTypeID() == BATTLEGROUND_DS) return reinterpret_cast<BattlegroundDS*>(this); else return NULL; }
|
||||
BattlegroundDS const* ToBattlegroundDS() const { if (GetBgTypeID() == BATTLEGROUND_DS) return reinterpret_cast<const BattlegroundDS*>(this); else return NULL; }
|
||||
|
||||
BattlegroundRV* ToBattlegroundRV() { if (GetBgTypeID() == BATTLEGROUND_RV) return reinterpret_cast<BattlegroundRV*>(this); else return NULL; }
|
||||
BattlegroundRV const* ToBattlegroundRV() const { if (GetBgTypeID() == BATTLEGROUND_RV) return reinterpret_cast<const BattlegroundRV*>(this); else return NULL; }
|
||||
|
||||
BattlegroundIC* ToBattlegroundIC() { if (GetBgTypeID() == BATTLEGROUND_IC) return reinterpret_cast<BattlegroundIC*>(this); else return NULL; }
|
||||
BattlegroundIC const* ToBattlegroundIC() const { if (GetBgTypeID() == BATTLEGROUND_IC) return reinterpret_cast<const BattlegroundIC*>(this); else return NULL; }
|
||||
|
||||
protected:
|
||||
// this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends Battleground
|
||||
void EndNow();
|
||||
void PlayerAddedToBGCheckIfBGIsRunning(Player* player);
|
||||
|
||||
void _ProcessResurrect(uint32 diff);
|
||||
void _ProcessProgress(uint32 diff);
|
||||
void _ProcessLeave(uint32 diff);
|
||||
void _ProcessJoin(uint32 diff);
|
||||
void _CheckSafePositions(uint32 diff);
|
||||
|
||||
// Scorekeeping
|
||||
BattlegroundScoreMap PlayerScores; // Player scores
|
||||
// must be implemented in BG subclass
|
||||
virtual void RemovePlayer(Player* /*player*/) {}
|
||||
|
||||
// Player lists, those need to be accessible by inherited classes
|
||||
BattlegroundPlayerMap m_Players;
|
||||
// Spirit Guide guid + Player list GUIDS
|
||||
std::map<uint64, std::vector<uint64> > m_ReviveQueue;
|
||||
|
||||
// these are important variables used for starting messages
|
||||
uint8 m_Events;
|
||||
BattlegroundStartTimeIntervals StartDelayTimes[BG_STARTING_EVENT_COUNT];
|
||||
// this must be filled in constructors!
|
||||
uint32 StartMessageIds[BG_STARTING_EVENT_COUNT];
|
||||
|
||||
bool m_BuffChange;
|
||||
|
||||
BGHonorMode m_HonorMode;
|
||||
int32 m_TeamScores[BG_TEAMS_COUNT];
|
||||
|
||||
// pussywizard:
|
||||
uint32 m_UpdateTimer;
|
||||
private:
|
||||
// Battleground
|
||||
BattlegroundTypeId m_RealTypeID;
|
||||
uint32 m_InstanceID; // Battleground Instance's GUID!
|
||||
BattlegroundStatus m_Status;
|
||||
uint32 m_ClientInstanceID; // the instance-id which is sent to the client and without any other internal use
|
||||
uint32 m_StartTime;
|
||||
uint32 m_ResetStatTimer;
|
||||
uint32 m_ValidStartPositionTimer;
|
||||
int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
|
||||
uint32 m_LastResurrectTime;
|
||||
uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
|
||||
bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave
|
||||
bool m_IsArena;
|
||||
TeamId m_WinnerId;
|
||||
int32 m_StartDelayTime;
|
||||
bool m_IsRated; // is this battle rated?
|
||||
bool m_PrematureCountDown;
|
||||
uint32 m_PrematureCountDownTimer;
|
||||
char const* m_Name;
|
||||
|
||||
/* Pre- and post-update hooks */
|
||||
|
||||
/**
|
||||
* @brief Pre-update hook.
|
||||
*
|
||||
* Will be called before battleground update is started. Depending on
|
||||
* the result of this call actual update body may be skipped.
|
||||
*
|
||||
* @param diff a time difference between two worldserver update loops in
|
||||
* milliseconds.
|
||||
*
|
||||
* @return @c true if update must be performed, @c false otherwise.
|
||||
*
|
||||
* @see Update(), PostUpdateImpl().
|
||||
*/
|
||||
virtual bool PreUpdateImpl(uint32 /* diff */) { return true; }
|
||||
|
||||
/**
|
||||
* @brief Post-update hook.
|
||||
*
|
||||
* Will be called after battleground update has passed. May be used to
|
||||
* implement custom update effects in subclasses.
|
||||
*
|
||||
* @param diff a time difference between two worldserver update loops in
|
||||
* milliseconds.
|
||||
*
|
||||
* @see Update(), PreUpdateImpl().
|
||||
*/
|
||||
virtual void PostUpdateImpl(uint32 /* diff */) { }
|
||||
|
||||
// Player lists
|
||||
std::vector<uint64> m_ResurrectQueue; // Player GUID
|
||||
std::deque<uint64> m_OfflineQueue; // Player GUID
|
||||
|
||||
// Invited counters are useful for player invitation to BG - do not allow, if BG is started to one faction to have 2 more players than another faction
|
||||
// Invited counters will be changed only when removing already invited player from queue, removing player from battleground and inviting player to BG
|
||||
// Invited players counters
|
||||
uint32 m_BgInvitedPlayers[BG_TEAMS_COUNT];
|
||||
|
||||
// Raid Group
|
||||
Group* m_BgRaids[BG_TEAMS_COUNT]; // 0 - alliance, 1 - horde
|
||||
|
||||
SpectatorList m_Spectators;
|
||||
ToBeTeleportedMap m_ToBeTeleported;
|
||||
|
||||
// Players count by team
|
||||
uint32 m_PlayersCount[BG_TEAMS_COUNT];
|
||||
|
||||
// Arena team ids by team
|
||||
uint32 m_ArenaTeamIds[BG_TEAMS_COUNT];
|
||||
|
||||
int32 m_ArenaTeamRatingChanges[BG_TEAMS_COUNT];
|
||||
uint32 m_ArenaTeamMMR[BG_TEAMS_COUNT];
|
||||
|
||||
// Limits
|
||||
uint32 m_LevelMin;
|
||||
uint32 m_LevelMax;
|
||||
uint32 m_MaxPlayersPerTeam;
|
||||
uint32 m_MinPlayersPerTeam;
|
||||
|
||||
// Start location
|
||||
uint32 m_MapId;
|
||||
BattlegroundMap* m_Map;
|
||||
float m_TeamStartLocX[BG_TEAMS_COUNT];
|
||||
float m_TeamStartLocY[BG_TEAMS_COUNT];
|
||||
float m_TeamStartLocZ[BG_TEAMS_COUNT];
|
||||
float m_TeamStartLocO[BG_TEAMS_COUNT];
|
||||
float m_StartMaxDist;
|
||||
uint32 ScriptId;
|
||||
};
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 __BATTLEGROUNDMGR_H
|
||||
#define __BATTLEGROUNDMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "DBCEnums.h"
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundQueue.h"
|
||||
#include "CreatureAIImpl.h"
|
||||
#include <ace/Singleton.h>
|
||||
|
||||
typedef std::map<uint32, Battleground*> BattlegroundContainer;
|
||||
typedef UNORDERED_MAP<uint32, BattlegroundTypeId> BattleMastersMap;
|
||||
|
||||
#define WS_ARENA_DISTRIBUTION_TIME 20001 // Custom worldstate
|
||||
|
||||
struct CreateBattlegroundData
|
||||
{
|
||||
BattlegroundTypeId bgTypeId;
|
||||
bool IsArena;
|
||||
uint32 MinPlayersPerTeam;
|
||||
uint32 MaxPlayersPerTeam;
|
||||
uint32 LevelMin;
|
||||
uint32 LevelMax;
|
||||
char* BattlegroundName;
|
||||
uint32 MapID;
|
||||
float Team1StartLocX;
|
||||
float Team1StartLocY;
|
||||
float Team1StartLocZ;
|
||||
float Team1StartLocO;
|
||||
float Team2StartLocX;
|
||||
float Team2StartLocY;
|
||||
float Team2StartLocZ;
|
||||
float Team2StartLocO;
|
||||
float StartMaxDist;
|
||||
uint32 scriptId;
|
||||
};
|
||||
|
||||
struct GroupQueueInfo;
|
||||
|
||||
// pussywizard
|
||||
class RandomBattlegroundSystem
|
||||
{
|
||||
public:
|
||||
RandomBattlegroundSystem();
|
||||
void Update(uint32 diff);
|
||||
BattlegroundTypeId GetCurrentRandomBg() const { return m_CurrentRandomBg; }
|
||||
void BattlegroundCreated(BattlegroundTypeId bgTypeId);
|
||||
private:
|
||||
BattlegroundTypeId m_CurrentRandomBg;
|
||||
uint32 m_SwitchTimer;
|
||||
std::vector<BattlegroundTypeId> m_BgOrder;
|
||||
};
|
||||
|
||||
class BattlegroundMgr
|
||||
{
|
||||
friend class ACE_Singleton<BattlegroundMgr, ACE_Null_Mutex>;
|
||||
|
||||
private:
|
||||
BattlegroundMgr();
|
||||
~BattlegroundMgr();
|
||||
|
||||
public:
|
||||
void Update(uint32 diff);
|
||||
|
||||
/* Packet Building */
|
||||
void BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, Player* player);
|
||||
void BuildPlayerLeftBattlegroundPacket(WorldPacket* data, uint64 guid);
|
||||
void BuildBattlegroundListPacket(WorldPacket* data, uint64 guid, Player* player, BattlegroundTypeId bgTypeId, uint8 fromWhere);
|
||||
void BuildGroupJoinedBattlegroundPacket(WorldPacket* data, GroupJoinBattlegroundResult result);
|
||||
void BuildUpdateWorldStatePacket(WorldPacket* data, uint32 field, uint32 value);
|
||||
void BuildPvpLogDataPacket(WorldPacket* data, Battleground* bg);
|
||||
void BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, uint8 queueSlot, uint8 statusId, uint32 time1, uint32 time2, uint8 arenaType, TeamId teamId, bool isRated = false, BattlegroundTypeId forceBgTypeId = BATTLEGROUND_TYPE_NONE);
|
||||
void BuildPlaySoundPacket(WorldPacket* data, uint32 soundid);
|
||||
void SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, uint64 guid);
|
||||
|
||||
/* Battlegrounds */
|
||||
Battleground* GetBattleground(uint32 InstanceID);
|
||||
Battleground* GetBattlegroundTemplate(BattlegroundTypeId bgTypeId);
|
||||
Battleground* CreateNewBattleground(BattlegroundTypeId bgTypeId, uint32 minLevel, uint32 maxLevel, uint8 arenaType, bool isRated);
|
||||
|
||||
void AddBattleground(Battleground* bg);
|
||||
void RemoveBattleground(BattlegroundTypeId bgTypeId, uint32 instanceId);
|
||||
|
||||
void CreateInitialBattlegrounds();
|
||||
void DeleteAllBattlegrounds();
|
||||
|
||||
void SendToBattleground(Player* player, uint32 InstanceID, BattlegroundTypeId bgTypeId);
|
||||
|
||||
/* Battleground queues */
|
||||
BattlegroundQueue& GetBattlegroundQueue(BattlegroundQueueTypeId bgQueueTypeId) { return m_BattlegroundQueues[bgQueueTypeId]; }
|
||||
void ScheduleArenaQueueUpdate(uint32 arenaRatedTeamId, BattlegroundQueueTypeId bgQueueTypeId, BattlegroundBracketId bracket_id);
|
||||
uint32 GetPrematureFinishTime() const;
|
||||
|
||||
static void InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, TeamId teamId);
|
||||
|
||||
void ToggleArenaTesting();
|
||||
void ToggleTesting();
|
||||
|
||||
void SetHolidayWeekends(uint32 mask);
|
||||
|
||||
bool isArenaTesting() const { return m_ArenaTesting; }
|
||||
bool isTesting() const { return m_Testing; }
|
||||
|
||||
static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType);
|
||||
static BattlegroundTypeId BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId);
|
||||
static bool IsArenaType(BattlegroundTypeId bgTypeId);
|
||||
static uint8 BGArenaType(BattlegroundQueueTypeId bgQueueTypeId);
|
||||
|
||||
static HolidayIds BGTypeToWeekendHolidayId(BattlegroundTypeId bgTypeId);
|
||||
static BattlegroundTypeId WeekendHolidayIdToBGType(HolidayIds holiday);
|
||||
static bool IsBGWeekend(BattlegroundTypeId bgTypeId);
|
||||
|
||||
PvPDifficultyEntry randomBgDifficultyEntry;
|
||||
|
||||
uint32 GetRatingDiscardTimer() const;
|
||||
void InitAutomaticArenaPointDistribution();
|
||||
void LoadBattleMastersEntry();
|
||||
void CheckBattleMasters();
|
||||
BattlegroundTypeId GetBattleMasterBG(uint32 entry) const
|
||||
{
|
||||
BattleMastersMap::const_iterator itr = mBattleMastersMap.find(entry);
|
||||
if (itr != mBattleMastersMap.end())
|
||||
return itr->second;
|
||||
return BATTLEGROUND_TYPE_NONE;
|
||||
}
|
||||
|
||||
const BattlegroundContainer& GetBattlegroundList() { return m_Battlegrounds; } // pussywizard
|
||||
RandomBattlegroundSystem RandomSystem; // pussywizard
|
||||
|
||||
private:
|
||||
bool CreateBattleground(CreateBattlegroundData& data);
|
||||
uint32 GetNextClientVisibleInstanceId();
|
||||
|
||||
typedef std::map<BattlegroundTypeId, Battleground*> BattlegroundTemplateContainer;
|
||||
BattlegroundTemplateContainer m_BattlegroundTemplates;
|
||||
BattlegroundContainer m_Battlegrounds;
|
||||
|
||||
BattlegroundQueue m_BattlegroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES];
|
||||
|
||||
std::vector<uint64> m_ArenaQueueUpdateScheduler;
|
||||
uint32 m_lastClientVisibleInstanceId;
|
||||
uint32 m_NextPeriodicQueueUpdateTime;
|
||||
time_t m_NextAutoDistributionTime;
|
||||
bool m_ArenaTesting;
|
||||
bool m_Testing;
|
||||
BattleMastersMap mBattleMastersMap;
|
||||
};
|
||||
|
||||
#define sBattlegroundMgr ACE_Singleton<BattlegroundMgr, ACE_Null_Mutex>::instance()
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 __BATTLEGROUNDQUEUE_H
|
||||
#define __BATTLEGROUNDQUEUE_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "DBCEnums.h"
|
||||
#include "Battleground.h"
|
||||
#include "EventProcessor.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
#define COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME 10
|
||||
|
||||
struct GroupQueueInfo // stores information about the group in queue (also used when joined as solo!)
|
||||
{
|
||||
std::set<uint64> Players; // player guid set
|
||||
TeamId teamId; // Player team (TEAM_ALLIANCE/TEAM_HORDE)
|
||||
BattlegroundTypeId BgTypeId; // battleground type id
|
||||
bool IsRated; // rated
|
||||
uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG
|
||||
uint32 ArenaTeamId; // team id if rated match
|
||||
uint32 JoinTime; // time when group was added
|
||||
uint32 RemoveInviteTime; // time when we will remove invite for players in group
|
||||
uint32 IsInvitedToBGInstanceGUID; // was invited to certain BG
|
||||
uint32 ArenaTeamRating; // if rated match, inited to the rating of the team
|
||||
uint32 ArenaMatchmakerRating; // if rated match, inited to the rating of the team
|
||||
uint32 OpponentsTeamRating; // for rated arena matches
|
||||
uint32 OpponentsMatchmakerRating; // for rated arena matches
|
||||
|
||||
// pussywizard: for internal use
|
||||
uint8 _bracketId;
|
||||
uint8 _groupType;
|
||||
};
|
||||
|
||||
enum BattlegroundQueueGroupTypes
|
||||
{
|
||||
BG_QUEUE_PREMADE_ALLIANCE = 0,
|
||||
BG_QUEUE_PREMADE_HORDE = 1,
|
||||
BG_QUEUE_NORMAL_ALLIANCE = 2,
|
||||
BG_QUEUE_NORMAL_HORDE = 3
|
||||
};
|
||||
#define BG_QUEUE_GROUP_TYPES_COUNT 4
|
||||
|
||||
class Battleground;
|
||||
class BattlegroundQueue
|
||||
{
|
||||
public:
|
||||
BattlegroundQueue();
|
||||
~BattlegroundQueue();
|
||||
|
||||
void BattlegroundQueueUpdate(BattlegroundBracketId bracket_id, uint8 actionMask, bool isRated, uint32 arenaRatedTeamId);
|
||||
void UpdateEvents(uint32 diff);
|
||||
|
||||
void FillPlayersToBG(const int32 aliFree, const int32 hordeFree, BattlegroundBracketId bracket_id);
|
||||
void FillPlayersToBGWithSpecific(const int32 aliFree, const int32 hordeFree, BattlegroundBracketId thisBracketId, BattlegroundQueue* specificQueue, BattlegroundBracketId specificBracketId);
|
||||
bool CheckPremadeMatch(BattlegroundBracketId bracket_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
|
||||
bool CheckNormalMatch(Battleground* bgTemplate, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers);
|
||||
bool CheckSkirmishForSameFaction(BattlegroundBracketId bracket_id, uint32 minPlayersPerTeam);
|
||||
GroupQueueInfo* AddGroup(Player* leader, Group* group, PvPDifficultyEntry const* bracketEntry, bool isRated, bool isPremade, uint32 ArenaRating, uint32 MatchmakerRating, uint32 ArenaTeamId);
|
||||
void RemovePlayer(uint64 guid, bool sentToBg, uint32 playerQueueSlot);
|
||||
bool IsPlayerInvitedToRatedArena(uint64 pl_guid);
|
||||
bool IsPlayerInvited(uint64 pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime);
|
||||
bool GetPlayerGroupInfoData(uint64 guid, GroupQueueInfo* ginfo);
|
||||
void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo);
|
||||
uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo) const;
|
||||
|
||||
void SetBgTypeIdAndArenaType(BattlegroundTypeId b, uint8 a) { m_bgTypeId = b; m_arenaType = ArenaType(a); } // pussywizard
|
||||
void AddEvent(BasicEvent* Event, uint64 e_time);
|
||||
|
||||
typedef std::map<uint64, GroupQueueInfo*> QueuedPlayersMap;
|
||||
QueuedPlayersMap m_QueuedPlayers;
|
||||
|
||||
//do NOT use deque because deque.erase() invalidates ALL iterators
|
||||
typedef std::list<GroupQueueInfo*> GroupsQueueType;
|
||||
|
||||
/*
|
||||
This two dimensional array is used to store All queued groups
|
||||
First dimension specifies the bgTypeId
|
||||
Second dimension specifies the player's group types -
|
||||
BG_QUEUE_PREMADE_ALLIANCE is used for premade alliance groups and alliance rated arena teams
|
||||
BG_QUEUE_PREMADE_HORDE is used for premade horde groups and horde rated arena teams
|
||||
BG_QUEUE_NORMAL_ALLIANCE is used for normal (or small) alliance groups or non-rated arena matches
|
||||
BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches
|
||||
*/
|
||||
GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_BRACKETS][BG_QUEUE_GROUP_TYPES_COUNT];
|
||||
|
||||
// class to select and invite groups to bg
|
||||
class SelectionPool
|
||||
{
|
||||
public:
|
||||
SelectionPool(): PlayerCount(0) {};
|
||||
void Init();
|
||||
bool AddGroup(GroupQueueInfo* ginfo, uint32 desiredCount);
|
||||
bool KickGroup(const uint32 size);
|
||||
uint32 GetPlayerCount() const {return PlayerCount;}
|
||||
public:
|
||||
GroupsQueueType SelectedGroups;
|
||||
private:
|
||||
uint32 PlayerCount;
|
||||
};
|
||||
|
||||
//one selection pool for horde, other one for alliance
|
||||
SelectionPool m_SelectionPools[BG_TEAMS_COUNT];
|
||||
private:
|
||||
|
||||
BattlegroundTypeId m_bgTypeId;
|
||||
ArenaType m_arenaType;
|
||||
uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
|
||||
uint32 m_WaitTimeLastIndex[BG_TEAMS_COUNT][MAX_BATTLEGROUND_BRACKETS];
|
||||
|
||||
// Event handler
|
||||
EventProcessor m_events;
|
||||
};
|
||||
|
||||
/*
|
||||
This class is used to invite player to BG again, when minute lasts from his first invitation
|
||||
it is capable to solve all possibilities
|
||||
*/
|
||||
class BGQueueInviteEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
BGQueueInviteEvent(uint64 pl_guid, uint32 BgInstanceGUID, BattlegroundTypeId BgTypeId, uint8 arenaType, uint32 removeTime) :
|
||||
m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_ArenaType(arenaType), m_RemoveTime(removeTime)
|
||||
{ }
|
||||
virtual ~BGQueueInviteEvent() { }
|
||||
|
||||
virtual bool Execute(uint64 e_time, uint32 p_time);
|
||||
virtual void Abort(uint64 e_time);
|
||||
private:
|
||||
uint64 m_PlayerGuid;
|
||||
uint32 m_BgInstanceGUID;
|
||||
BattlegroundTypeId m_BgTypeId;
|
||||
uint8 m_ArenaType;
|
||||
uint32 m_RemoveTime;
|
||||
};
|
||||
|
||||
/*
|
||||
This class is used to remove player from BG queue after 1 minute 20 seconds from first invitation
|
||||
We must store removeInvite time in case player left queue and joined and is invited again
|
||||
We must store bgQueueTypeId, because battleground can be deleted already, when player entered it
|
||||
*/
|
||||
class BGQueueRemoveEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
BGQueueRemoveEvent(uint64 pl_guid, uint32 bgInstanceGUID, BattlegroundQueueTypeId bgQueueTypeId, uint32 removeTime)
|
||||
: m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgQueueTypeId(bgQueueTypeId)
|
||||
{}
|
||||
|
||||
virtual ~BGQueueRemoveEvent() {}
|
||||
|
||||
virtual bool Execute(uint64 e_time, uint32 p_time);
|
||||
virtual void Abort(uint64 e_time);
|
||||
private:
|
||||
uint64 m_PlayerGuid;
|
||||
uint32 m_BgInstanceGUID;
|
||||
uint32 m_RemoveTime;
|
||||
BattlegroundQueueTypeId m_BgQueueTypeId;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "BattlegroundAB.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "Creature.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "Player.h"
|
||||
#include "Util.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
BattlegroundAB::BattlegroundAB()
|
||||
{
|
||||
m_BuffChange = true;
|
||||
BgObjects.resize(BG_AB_OBJECT_MAX);
|
||||
BgCreatures.resize(BG_AB_ALL_NODES_COUNT + BG_AB_DYNAMIC_NODES_COUNT); // xinef: +BG_AB_DYNAMIC_NODES_COUNT buff triggers
|
||||
|
||||
_controlledPoints[TEAM_ALLIANCE] = 0;
|
||||
_controlledPoints[TEAM_HORDE] = 0;
|
||||
_teamScores500Disadvantage[TEAM_ALLIANCE] = false;
|
||||
_teamScores500Disadvantage[TEAM_HORDE] = false;
|
||||
_honorTics = 0;
|
||||
_reputationTics = 0;
|
||||
|
||||
StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_AB_START_TWO_MINUTES;
|
||||
StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_AB_START_ONE_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_AB_START_HALF_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_AB_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattlegroundAB::~BattlegroundAB()
|
||||
{
|
||||
}
|
||||
|
||||
void BattlegroundAB::PostUpdateImpl(uint32 diff)
|
||||
{
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
_bgEvents.Update(diff);
|
||||
while (uint32 eventId =_bgEvents.ExecuteEvent())
|
||||
switch (eventId)
|
||||
{
|
||||
case BG_AB_EVENT_UPDATE_BANNER_STABLE:
|
||||
case BG_AB_EVENT_UPDATE_BANNER_FARM:
|
||||
case BG_AB_EVENT_UPDATE_BANNER_BLACKSMITH:
|
||||
case BG_AB_EVENT_UPDATE_BANNER_LUMBERMILL:
|
||||
case BG_AB_EVENT_UPDATE_BANNER_GOLDMINE:
|
||||
CreateBanner(eventId - BG_AB_EVENT_UPDATE_BANNER_STABLE, false);
|
||||
break;
|
||||
case BG_AB_EVENT_CAPTURE_STABLE:
|
||||
case BG_AB_EVENT_CAPTURE_FARM:
|
||||
case BG_AB_EVENT_CAPTURE_BLACKSMITH:
|
||||
case BG_AB_EVENT_CAPTURE_LUMBERMILL:
|
||||
case BG_AB_EVENT_CAPTURE_GOLDMINE:
|
||||
{
|
||||
uint8 node = eventId - BG_AB_EVENT_CAPTURE_STABLE;
|
||||
TeamId teamId = _capturePointInfo[node]._state == BG_AB_NODE_STATE_ALLY_CONTESTED ? TEAM_ALLIANCE : TEAM_HORDE;
|
||||
DeleteBanner(node);
|
||||
_capturePointInfo[node]._ownerTeamId = teamId;
|
||||
_capturePointInfo[node]._state = teamId == TEAM_ALLIANCE ? BG_AB_NODE_STATE_ALLY_OCCUPIED : BG_AB_NODE_STATE_HORDE_OCCUPIED;
|
||||
_capturePointInfo[node]._captured = true;
|
||||
|
||||
CreateBanner(node, false);
|
||||
NodeOccupied(node);
|
||||
SendNodeUpdate(node);
|
||||
|
||||
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, teamId == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE, NULL, teamId == TEAM_ALLIANCE ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE, LANG_BG_AB_NODE_STABLES + node);
|
||||
PlaySoundToAll(teamId == TEAM_ALLIANCE ? BG_AB_SOUND_NODE_CAPTURED_ALLIANCE : BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
break;
|
||||
}
|
||||
case BG_AB_EVENT_ALLIANCE_TICK:
|
||||
case BG_AB_EVENT_HORDE_TICK:
|
||||
{
|
||||
TeamId teamId = TeamId(eventId - BG_AB_EVENT_ALLIANCE_TICK);
|
||||
uint8 controlledPoints = _controlledPoints[teamId];
|
||||
if (controlledPoints == 0)
|
||||
{
|
||||
_bgEvents.ScheduleEvent(eventId, 3000);
|
||||
break;
|
||||
}
|
||||
|
||||
uint8 honorRewards = uint8(m_TeamScores[teamId] / _honorTics);
|
||||
uint8 reputationRewards = uint8(m_TeamScores[teamId] / _reputationTics);
|
||||
uint8 information = uint8(m_TeamScores[teamId] / BG_AB_WARNING_NEAR_VICTORY_SCORE);
|
||||
m_TeamScores[teamId] += BG_AB_TickPoints[controlledPoints];
|
||||
if (m_TeamScores[teamId] > BG_AB_MAX_TEAM_SCORE)
|
||||
m_TeamScores[teamId] = BG_AB_MAX_TEAM_SCORE;
|
||||
|
||||
if (honorRewards < uint8(m_TeamScores[teamId] / _honorTics))
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), teamId);
|
||||
if (reputationRewards < uint8(m_TeamScores[teamId] / _reputationTics))
|
||||
RewardReputationToTeam(teamId == TEAM_ALLIANCE ? 509 : 510, 10, teamId);
|
||||
if (information < uint8(m_TeamScores[teamId] / BG_AB_WARNING_NEAR_VICTORY_SCORE))
|
||||
{
|
||||
SendMessageToAll(teamId == TEAM_ALLIANCE ? LANG_BG_AB_A_NEAR_VICTORY : LANG_BG_AB_H_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY);
|
||||
}
|
||||
|
||||
UpdateWorldState(teamId == TEAM_ALLIANCE ? BG_AB_OP_RESOURCES_ALLY : BG_AB_OP_RESOURCES_HORDE, m_TeamScores[teamId]);
|
||||
if (m_TeamScores[teamId] > m_TeamScores[GetOtherTeamId(teamId)] + 500)
|
||||
_teamScores500Disadvantage[GetOtherTeamId(teamId)] = true;
|
||||
if (m_TeamScores[teamId] >= BG_AB_MAX_TEAM_SCORE)
|
||||
EndBattleground(teamId);
|
||||
|
||||
_bgEvents.ScheduleEvent(eventId, BG_AB_TickIntervals[controlledPoints]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundAB::StartingEventCloseDoors()
|
||||
{
|
||||
|
||||
for (uint32 obj = BG_AB_OBJECT_BANNER_NEUTRAL; obj < BG_AB_DYNAMIC_NODES_COUNT * BG_AB_OBJECTS_PER_NODE; ++obj)
|
||||
SpawnBGObject(obj, RESPAWN_ONE_DAY);
|
||||
for (uint32 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT * 3; ++i)
|
||||
SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + i, RESPAWN_ONE_DAY);
|
||||
|
||||
// Starting doors
|
||||
SpawnBGObject(BG_AB_OBJECT_GATE_A, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_AB_OBJECT_GATE_H, RESPAWN_IMMEDIATELY);
|
||||
DoorClose(BG_AB_OBJECT_GATE_A);
|
||||
DoorClose(BG_AB_OBJECT_GATE_H);
|
||||
}
|
||||
|
||||
void BattlegroundAB::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 banner = BG_AB_OBJECT_BANNER_NEUTRAL, i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; banner += BG_AB_OBJECTS_PER_NODE, ++i)
|
||||
SpawnBGObject(banner, RESPAWN_IMMEDIATELY);
|
||||
|
||||
for (uint32 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + urand(0, 2) + i * 3, RESPAWN_IMMEDIATELY);
|
||||
|
||||
DoorOpen(BG_AB_OBJECT_GATE_A);
|
||||
DoorOpen(BG_AB_OBJECT_GATE_H);
|
||||
StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, BG_AB_EVENT_START_BATTLE);
|
||||
_bgEvents.ScheduleEvent(BG_AB_EVENT_ALLIANCE_TICK, 3000);
|
||||
_bgEvents.ScheduleEvent(BG_AB_EVENT_HORDE_TICK, 3000);
|
||||
}
|
||||
|
||||
void BattlegroundAB::AddPlayer(Player* player)
|
||||
{
|
||||
Battleground::AddPlayer(player);
|
||||
PlayerScores[player->GetGUID()] = new BattlegroundABScore(player);
|
||||
}
|
||||
|
||||
void BattlegroundAB::RemovePlayer(Player* player)
|
||||
{
|
||||
player->SetPhaseMask(1, false);
|
||||
}
|
||||
|
||||
void BattlegroundAB::HandleAreaTrigger(Player* player, uint32 trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
switch (trigger)
|
||||
{
|
||||
case 3948: // Arathi Basin Alliance Exit.
|
||||
if (player->GetTeamId() != TEAM_ALLIANCE)
|
||||
player->GetSession()->SendAreaTriggerMessage("Only The Alliance can use that portal");
|
||||
else
|
||||
player->LeaveBattleground();
|
||||
break;
|
||||
case 3949: // Arathi Basin Horde Exit.
|
||||
if (player->GetTeamId() != TEAM_HORDE)
|
||||
player->GetSession()->SendAreaTriggerMessage("Only The Horde can use that portal");
|
||||
else
|
||||
player->LeaveBattleground();
|
||||
break;
|
||||
case 3866: // Stables
|
||||
case 3869: // Gold Mine
|
||||
case 3867: // Farm
|
||||
case 3868: // Lumber Mill
|
||||
case 3870: // Black Smith
|
||||
case 4020: // Unk1
|
||||
case 4021: // Unk2
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundAB::CreateBanner(uint8 node, bool delay)
|
||||
{
|
||||
// Just put it into the queue
|
||||
if (delay)
|
||||
{
|
||||
_bgEvents.RescheduleEvent(BG_AB_EVENT_UPDATE_BANNER_STABLE+node, BG_AB_BANNER_UPDATE_TIME);
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnBGObject(node*BG_AB_OBJECTS_PER_NODE + _capturePointInfo[node]._state, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(node*BG_AB_OBJECTS_PER_NODE + BG_AB_OBJECT_AURA_ALLY + _capturePointInfo[node]._ownerTeamId, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattlegroundAB::DeleteBanner(uint8 node)
|
||||
{
|
||||
SpawnBGObject(node*BG_AB_OBJECTS_PER_NODE + _capturePointInfo[node]._state, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(node*BG_AB_OBJECTS_PER_NODE + BG_AB_OBJECT_AURA_ALLY + _capturePointInfo[node]._ownerTeamId, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
void BattlegroundAB::FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
|
||||
{
|
||||
if (_capturePointInfo[node]._state == BG_AB_NODE_STATE_NEUTRAL)
|
||||
data << uint32(_capturePointInfo[node]._iconNone) << uint32(1);
|
||||
|
||||
for (uint8 i = BG_AB_NODE_STATE_ALLY_OCCUPIED; i <= BG_AB_NODE_STATE_HORDE_CONTESTED; ++i)
|
||||
data << uint32(_capturePointInfo[node]._iconCapture + i-1) << uint32(_capturePointInfo[node]._state == i);
|
||||
}
|
||||
|
||||
data << uint32(BG_AB_OP_OCCUPIED_BASES_ALLY) << uint32(_controlledPoints[TEAM_ALLIANCE]);
|
||||
data << uint32(BG_AB_OP_OCCUPIED_BASES_HORDE) << uint32(_controlledPoints[TEAM_HORDE]);
|
||||
data << uint32(BG_AB_OP_RESOURCES_MAX) << uint32(BG_AB_MAX_TEAM_SCORE);
|
||||
data << uint32(BG_AB_OP_RESOURCES_WARNING) << uint32(BG_AB_WARNING_NEAR_VICTORY_SCORE);
|
||||
data << uint32(BG_AB_OP_RESOURCES_ALLY) << uint32(m_TeamScores[TEAM_ALLIANCE]);
|
||||
data << uint32(BG_AB_OP_RESOURCES_HORDE) << uint32(m_TeamScores[TEAM_HORDE]);
|
||||
data << uint32(0x745) << uint32(0x2); // 37 1861 unk
|
||||
}
|
||||
|
||||
void BattlegroundAB::SendNodeUpdate(uint8 node)
|
||||
{
|
||||
UpdateWorldState(_capturePointInfo[node]._iconNone, 0);
|
||||
for (uint8 i = BG_AB_NODE_STATE_ALLY_OCCUPIED; i <= BG_AB_NODE_STATE_HORDE_CONTESTED; ++i)
|
||||
UpdateWorldState(_capturePointInfo[node]._iconCapture + i-1, _capturePointInfo[node]._state == i);
|
||||
|
||||
UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_ALLY, _controlledPoints[TEAM_ALLIANCE]);
|
||||
UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_HORDE, _controlledPoints[TEAM_HORDE]);
|
||||
}
|
||||
|
||||
void BattlegroundAB::NodeOccupied(uint8 node)
|
||||
{
|
||||
ApplyPhaseMask();
|
||||
AddSpiritGuide(node, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], _capturePointInfo[node]._ownerTeamId);
|
||||
|
||||
++_controlledPoints[_capturePointInfo[node]._ownerTeamId];
|
||||
if (_controlledPoints[_capturePointInfo[node]._ownerTeamId] >= 5)
|
||||
CastSpellOnTeam(SPELL_AB_QUEST_REWARD_5_BASES, _capturePointInfo[node]._ownerTeamId);
|
||||
if (_controlledPoints[_capturePointInfo[node]._ownerTeamId] >= 4)
|
||||
CastSpellOnTeam(SPELL_AB_QUEST_REWARD_4_BASES, _capturePointInfo[node]._ownerTeamId);
|
||||
|
||||
Creature* trigger = GetBgMap()->GetCreature(BgCreatures[BG_AB_ALL_NODES_COUNT + node]);
|
||||
if (!trigger)
|
||||
trigger = AddCreature(WORLD_TRIGGER, BG_AB_ALL_NODES_COUNT + node, BG_AB_NodePositions[node][0], BG_AB_NodePositions[node][1], BG_AB_NodePositions[node][2], BG_AB_NodePositions[node][3]);
|
||||
|
||||
if (trigger)
|
||||
{
|
||||
trigger->setFaction(_capturePointInfo[node]._ownerTeamId == TEAM_ALLIANCE ? 84 : 83);
|
||||
trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false);
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundAB::NodeDeoccupied(uint8 node)
|
||||
{
|
||||
--_controlledPoints[_capturePointInfo[node]._ownerTeamId];
|
||||
|
||||
_capturePointInfo[node]._ownerTeamId = TEAM_NEUTRAL;
|
||||
RelocateDeadPlayers(BgCreatures[node]);
|
||||
|
||||
DelCreature(node); // Delete spirit healer
|
||||
DelCreature(BG_AB_ALL_NODES_COUNT + node); // Delete aura trigger
|
||||
}
|
||||
|
||||
void BattlegroundAB::EventPlayerClickedOnFlag(Player* player, GameObject* gameObject)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS || !player->IsWithinDistInMap(gameObject, 10.0f))
|
||||
return;
|
||||
|
||||
uint8 node = BG_AB_NODE_STABLES;
|
||||
for (; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
|
||||
if (player->GetDistance2d(BG_AB_NodePositions[node][0], BG_AB_NodePositions[node][1]) < 10.0f)
|
||||
break;
|
||||
|
||||
if (node == BG_AB_DYNAMIC_NODES_COUNT || _capturePointInfo[node]._ownerTeamId == player->GetTeamId() ||
|
||||
(_capturePointInfo[node]._state == BG_AB_NODE_STATE_ALLY_CONTESTED && player->GetTeamId() == TEAM_ALLIANCE) ||
|
||||
(_capturePointInfo[node]._state == BG_AB_NODE_STATE_HORDE_CONTESTED && player->GetTeamId() == TEAM_HORDE))
|
||||
return;
|
||||
|
||||
player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
|
||||
uint32 sound = 0;
|
||||
uint32 message = 0;
|
||||
uint32 message2 = 0;
|
||||
DeleteBanner(node);
|
||||
CreateBanner(node, true);
|
||||
|
||||
if (_capturePointInfo[node]._state == BG_AB_NODE_STATE_NEUTRAL)
|
||||
{
|
||||
player->KilledMonsterCredit(BG_AB_QUEST_CREDIT_BASE + node, 0);
|
||||
UpdatePlayerScore(player, SCORE_BASES_ASSAULTED, 1);
|
||||
_capturePointInfo[node]._state = BG_AB_NODE_STATE_ALLY_CONTESTED + player->GetTeamId();
|
||||
_capturePointInfo[node]._ownerTeamId = TEAM_NEUTRAL;
|
||||
_bgEvents.RescheduleEvent(BG_AB_EVENT_CAPTURE_STABLE + node, BG_AB_FLAG_CAPTURING_TIME);
|
||||
sound = BG_AB_SOUND_NODE_CLAIMED;
|
||||
message = LANG_BG_AB_NODE_CLAIMED;
|
||||
message2 = player->GetTeamId() == TEAM_ALLIANCE ? LANG_BG_AB_ALLY : LANG_BG_AB_HORDE;
|
||||
}
|
||||
else if (_capturePointInfo[node]._state == BG_AB_NODE_STATE_ALLY_CONTESTED || _capturePointInfo[node]._state == BG_AB_NODE_STATE_HORDE_CONTESTED)
|
||||
{
|
||||
if (!_capturePointInfo[node]._captured)
|
||||
{
|
||||
player->KilledMonsterCredit(BG_AB_QUEST_CREDIT_BASE + node, 0);
|
||||
UpdatePlayerScore(player, SCORE_BASES_ASSAULTED, 1);
|
||||
_capturePointInfo[node]._state = BG_AB_NODE_STATE_ALLY_CONTESTED + player->GetTeamId();
|
||||
_capturePointInfo[node]._ownerTeamId = TEAM_NEUTRAL;
|
||||
_bgEvents.RescheduleEvent(BG_AB_EVENT_CAPTURE_STABLE + node, BG_AB_FLAG_CAPTURING_TIME);
|
||||
message = LANG_BG_AB_NODE_ASSAULTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdatePlayerScore(player, SCORE_BASES_DEFENDED, 1);
|
||||
_capturePointInfo[node]._state = BG_AB_NODE_STATE_ALLY_OCCUPIED + player->GetTeamId();
|
||||
_capturePointInfo[node]._ownerTeamId = player->GetTeamId();
|
||||
_bgEvents.CancelEvent(BG_AB_EVENT_CAPTURE_STABLE + node);
|
||||
NodeOccupied(node); // after setting team owner
|
||||
message = LANG_BG_AB_NODE_DEFENDED;
|
||||
}
|
||||
sound = player->GetTeamId() == TEAM_ALLIANCE ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->KilledMonsterCredit(BG_AB_QUEST_CREDIT_BASE + node, 0);
|
||||
UpdatePlayerScore(player, SCORE_BASES_ASSAULTED, 1);
|
||||
NodeDeoccupied(node); // before setting team owner to neutral
|
||||
|
||||
_capturePointInfo[node]._state = BG_AB_NODE_STATE_ALLY_CONTESTED + player->GetTeamId();
|
||||
|
||||
ApplyPhaseMask();
|
||||
_bgEvents.RescheduleEvent(BG_AB_EVENT_CAPTURE_STABLE + node, BG_AB_FLAG_CAPTURING_TIME);
|
||||
message = LANG_BG_AB_NODE_ASSAULTED;
|
||||
sound = player->GetTeamId() == TEAM_ALLIANCE ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
|
||||
}
|
||||
|
||||
SendNodeUpdate(node);
|
||||
PlaySoundToAll(sound);
|
||||
SendMessage2ToAll(message, player->GetTeamId() == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE, player, LANG_BG_AB_NODE_STABLES + node, message2);
|
||||
}
|
||||
|
||||
TeamId BattlegroundAB::GetPrematureWinner()
|
||||
{
|
||||
if (_controlledPoints[TEAM_ALLIANCE] > _controlledPoints[TEAM_HORDE])
|
||||
return TEAM_ALLIANCE;
|
||||
return _controlledPoints[TEAM_HORDE] > _controlledPoints[TEAM_ALLIANCE] ? TEAM_HORDE : Battleground::GetPrematureWinner();
|
||||
}
|
||||
|
||||
bool BattlegroundAB::SetupBattleground()
|
||||
{
|
||||
for (uint32 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
{
|
||||
AddObject(BG_AB_OBJECT_BANNER_NEUTRAL + BG_AB_OBJECTS_PER_NODE*i, BG_AB_OBJECTID_NODE_BANNER_0 + i, BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
AddObject(BG_AB_OBJECT_BANNER_ALLY + BG_AB_OBJECTS_PER_NODE*i, BG_AB_OBJECTID_BANNER_A, BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
AddObject(BG_AB_OBJECT_BANNER_HORDE + BG_AB_OBJECTS_PER_NODE*i, BG_AB_OBJECTID_BANNER_H, BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
AddObject(BG_AB_OBJECT_BANNER_CONT_A + BG_AB_OBJECTS_PER_NODE*i, BG_AB_OBJECTID_BANNER_CONT_A, BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
AddObject(BG_AB_OBJECT_BANNER_CONT_H + BG_AB_OBJECTS_PER_NODE*i, BG_AB_OBJECTID_BANNER_CONT_H, BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
AddObject(BG_AB_OBJECT_AURA_ALLY + BG_AB_OBJECTS_PER_NODE*i, BG_AB_OBJECTID_AURA_A, BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
AddObject(BG_AB_OBJECT_AURA_HORDE + BG_AB_OBJECTS_PER_NODE*i, BG_AB_OBJECTID_AURA_H, BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
AddObject(BG_AB_OBJECT_AURA_CONTESTED + BG_AB_OBJECTS_PER_NODE*i, BG_AB_OBJECTID_AURA_C, BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
AddObject(BG_AB_OBJECT_GATE_A, BG_AB_OBJECTID_GATE_A, BG_AB_DoorPositions[0][0], BG_AB_DoorPositions[0][1], BG_AB_DoorPositions[0][2], BG_AB_DoorPositions[0][3], BG_AB_DoorPositions[0][4], BG_AB_DoorPositions[0][5], BG_AB_DoorPositions[0][6], BG_AB_DoorPositions[0][7], RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_AB_OBJECT_GATE_H, BG_AB_OBJECTID_GATE_H, BG_AB_DoorPositions[1][0], BG_AB_DoorPositions[1][1], BG_AB_DoorPositions[1][2], BG_AB_DoorPositions[1][3], BG_AB_DoorPositions[1][4], BG_AB_DoorPositions[1][5], BG_AB_DoorPositions[1][6], BG_AB_DoorPositions[1][7], RESPAWN_IMMEDIATELY);
|
||||
|
||||
for (uint32 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
{
|
||||
AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i, Buff_Entries[0], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i + 1, Buff_Entries[1], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
AddObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + 3 * i + 2, Buff_Entries[2], BG_AB_BuffPositions[i][0], BG_AB_BuffPositions[i][1], BG_AB_BuffPositions[i][2], BG_AB_BuffPositions[i][3], 0, 0, sin(BG_AB_BuffPositions[i][3]/2), cos(BG_AB_BuffPositions[i][3]/2), RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
AddSpiritGuide(BG_AB_SPIRIT_ALIANCE, BG_AB_SpiritGuidePos[BG_AB_SPIRIT_ALIANCE][0], BG_AB_SpiritGuidePos[BG_AB_SPIRIT_ALIANCE][1], BG_AB_SpiritGuidePos[BG_AB_SPIRIT_ALIANCE][2], BG_AB_SpiritGuidePos[BG_AB_SPIRIT_ALIANCE][3], TEAM_ALLIANCE);
|
||||
AddSpiritGuide(BG_AB_SPIRIT_HORDE, BG_AB_SpiritGuidePos[BG_AB_SPIRIT_HORDE][0], BG_AB_SpiritGuidePos[BG_AB_SPIRIT_HORDE][1], BG_AB_SpiritGuidePos[BG_AB_SPIRIT_HORDE][2], BG_AB_SpiritGuidePos[BG_AB_SPIRIT_HORDE][3], TEAM_HORDE);
|
||||
|
||||
for (uint32 i = BG_AB_OBJECT_BANNER_NEUTRAL; i < BG_AB_OBJECT_MAX; ++i)
|
||||
if (BgObjects[i] == 0)
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundAB: Failed to spawn some object Battleground not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32 i = BG_AB_SPIRIT_ALIANCE; i <= BG_AB_SPIRIT_HORDE; ++i)
|
||||
if (BgCreatures[i] == 0)
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundAB: Failed to spawn spirit guides Battleground not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundAB::Init()
|
||||
{
|
||||
//call parent's class reset
|
||||
Battleground::Init();
|
||||
|
||||
_bgEvents.Reset();
|
||||
|
||||
_honorTics = BattlegroundMgr::IsBGWeekend(GetBgTypeID()) ? BG_AB_HONOR_TICK_WEEKEND : BG_AB_HONOR_TICK_NORMAL;
|
||||
_reputationTics = BattlegroundMgr::IsBGWeekend(GetBgTypeID()) ? BG_AB_REP_TICK_WEEKEND : BG_AB_REP_TICK_NORMAL;
|
||||
|
||||
_capturePointInfo[BG_AB_NODE_STABLES]._iconNone = BG_AB_OP_STABLE_ICON;
|
||||
_capturePointInfo[BG_AB_NODE_FARM]._iconNone = BG_AB_OP_FARM_ICON;
|
||||
_capturePointInfo[BG_AB_NODE_BLACKSMITH]._iconNone = BG_AB_OP_BLACKSMITH_ICON;
|
||||
_capturePointInfo[BG_AB_NODE_LUMBER_MILL]._iconNone = BG_AB_OP_LUMBERMILL_ICON;
|
||||
_capturePointInfo[BG_AB_NODE_GOLD_MINE]._iconNone = BG_AB_OP_GOLDMINE_ICON;
|
||||
_capturePointInfo[BG_AB_NODE_STABLES]._iconCapture = BG_AB_OP_STABLE_STATE_ALIENCE;
|
||||
_capturePointInfo[BG_AB_NODE_FARM]._iconCapture = BG_AB_OP_FARM_STATE_ALIENCE;
|
||||
_capturePointInfo[BG_AB_NODE_BLACKSMITH]._iconCapture = BG_AB_OP_BLACKSMITH_STATE_ALIENCE;
|
||||
_capturePointInfo[BG_AB_NODE_LUMBER_MILL]._iconCapture = BG_AB_OP_LUMBERMILL_STATE_ALIENCE;
|
||||
_capturePointInfo[BG_AB_NODE_GOLD_MINE]._iconCapture = BG_AB_OP_GOLDMINE_STATE_ALIENCE;
|
||||
}
|
||||
|
||||
void BattlegroundAB::EndBattleground(TeamId winnerTeamId)
|
||||
{
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), winnerTeamId);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), TEAM_HORDE);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), TEAM_ALLIANCE);
|
||||
Battleground::EndBattleground(winnerTeamId);
|
||||
_bgEvents.Reset();
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const* BattlegroundAB::GetClosestGraveyard(Player* player)
|
||||
{
|
||||
WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(BG_AB_GraveyardIds[BG_AB_SPIRIT_ALIANCE + player->GetTeamId()]);
|
||||
WorldSafeLocsEntry const* nearestEntry = entry;
|
||||
|
||||
float pX = player->GetPositionX();
|
||||
float pY = player->GetPositionY();
|
||||
float dist = (entry->x - pX)*(entry->x - pX)+(entry->y - pY)*(entry->y - pY);
|
||||
float minDist = dist;
|
||||
|
||||
for (uint8 i = BG_AB_NODE_STABLES; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
if (_capturePointInfo[i]._ownerTeamId == player->GetTeamId())
|
||||
{
|
||||
entry = sWorldSafeLocsStore.LookupEntry(BG_AB_GraveyardIds[i]);
|
||||
dist = (entry->x - pX)*(entry->x - pX) + (entry->y - pY)*(entry->y - pY);
|
||||
if (dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
nearestEntry = entry;
|
||||
}
|
||||
}
|
||||
|
||||
return nearestEntry;
|
||||
}
|
||||
|
||||
void BattlegroundAB::UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
BattlegroundScoreMap::iterator itr = PlayerScores.find(player->GetGUID());
|
||||
if (itr == PlayerScores.end())
|
||||
return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SCORE_BASES_ASSAULTED:
|
||||
((BattlegroundABScore*)itr->second)->BasesAssaulted += value;
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, BG_AB_OBJECTIVE_ASSAULT_BASE);
|
||||
break;
|
||||
case SCORE_BASES_DEFENDED:
|
||||
((BattlegroundABScore*)itr->second)->BasesDefended += value;
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, BG_AB_OBJECTIVE_DEFEND_BASE);
|
||||
break;
|
||||
default:
|
||||
Battleground::UpdatePlayerScore(player, type, value, doAddHonor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool BattlegroundAB::AllNodesConrolledByTeam(TeamId teamId) const
|
||||
{
|
||||
return _controlledPoints[teamId] == BG_AB_DYNAMIC_NODES_COUNT;
|
||||
}
|
||||
|
||||
void BattlegroundAB::ApplyPhaseMask()
|
||||
{
|
||||
uint32 phaseMask = 1;
|
||||
for (uint32 i = BG_AB_NODE_STABLES; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
|
||||
if (_capturePointInfo[i]._ownerTeamId != TEAM_NEUTRAL)
|
||||
phaseMask |= 1 << (i*2+1 + _capturePointInfo[i]._ownerTeamId);
|
||||
|
||||
const BattlegroundPlayerMap& bgPlayerMap = GetPlayers();
|
||||
for (BattlegroundPlayerMap::const_iterator itr = bgPlayerMap.begin(); itr != bgPlayerMap.end(); ++itr)
|
||||
{
|
||||
itr->second->SetPhaseMask(phaseMask, false);
|
||||
itr->second->UpdateObjectVisibility(true, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef __BATTLEGROUNDAB_H
|
||||
#define __BATTLEGROUNDAB_H
|
||||
|
||||
#include "Battleground.h"
|
||||
|
||||
enum BG_AB_Events
|
||||
{
|
||||
BG_AB_EVENT_UPDATE_BANNER_STABLE = 1,
|
||||
BG_AB_EVENT_UPDATE_BANNER_FARM = 2,
|
||||
BG_AB_EVENT_UPDATE_BANNER_BLACKSMITH = 3,
|
||||
BG_AB_EVENT_UPDATE_BANNER_LUMBERMILL = 4,
|
||||
BG_AB_EVENT_UPDATE_BANNER_GOLDMINE = 5,
|
||||
|
||||
BG_AB_EVENT_CAPTURE_STABLE = 6,
|
||||
BG_AB_EVENT_CAPTURE_FARM = 7,
|
||||
BG_AB_EVENT_CAPTURE_BLACKSMITH = 8,
|
||||
BG_AB_EVENT_CAPTURE_LUMBERMILL = 9,
|
||||
BG_AB_EVENT_CAPTURE_GOLDMINE = 10,
|
||||
|
||||
BG_AB_EVENT_ALLIANCE_TICK = 11,
|
||||
BG_AB_EVENT_HORDE_TICK = 12
|
||||
};
|
||||
|
||||
enum BG_AB_WorldStates
|
||||
{
|
||||
BG_AB_OP_OCCUPIED_BASES_HORDE = 1778,
|
||||
BG_AB_OP_OCCUPIED_BASES_ALLY = 1779,
|
||||
BG_AB_OP_RESOURCES_ALLY = 1776,
|
||||
BG_AB_OP_RESOURCES_HORDE = 1777,
|
||||
BG_AB_OP_RESOURCES_MAX = 1780,
|
||||
BG_AB_OP_RESOURCES_WARNING = 1955,
|
||||
|
||||
BG_AB_OP_STABLE_ICON = 1842, //Stable map icon (NONE)
|
||||
BG_AB_OP_STABLE_STATE_ALIENCE = 1767, //Stable map state (ALIENCE)
|
||||
BG_AB_OP_STABLE_STATE_HORDE = 1768, //Stable map state (HORDE)
|
||||
BG_AB_OP_STABLE_STATE_CON_ALI = 1769, //Stable map state (CON ALIENCE)
|
||||
BG_AB_OP_STABLE_STATE_CON_HOR = 1770, //Stable map state (CON HORDE)
|
||||
|
||||
BG_AB_OP_FARM_ICON = 1845, //Farm map icon (NONE)
|
||||
BG_AB_OP_FARM_STATE_ALIENCE = 1772, //Farm state (ALIENCE)
|
||||
BG_AB_OP_FARM_STATE_HORDE = 1773, //Farm state (HORDE)
|
||||
BG_AB_OP_FARM_STATE_CON_ALI = 1774, //Farm state (CON ALIENCE)
|
||||
BG_AB_OP_FARM_STATE_CON_HOR = 1775, //Farm state (CON HORDE)
|
||||
|
||||
BG_AB_OP_BLACKSMITH_ICON = 1846, //Blacksmith map icon (NONE)
|
||||
BG_AB_OP_BLACKSMITH_STATE_ALIENCE = 1782, //Blacksmith map state (ALIENCE)
|
||||
BG_AB_OP_BLACKSMITH_STATE_HORDE = 1783, //Blacksmith map state (HORDE)
|
||||
BG_AB_OP_BLACKSMITH_STATE_CON_ALI = 1784, //Blacksmith map state (CON ALIENCE)
|
||||
BG_AB_OP_BLACKSMITH_STATE_CON_HOR = 1785, //Blacksmith map state (CON HORDE)
|
||||
|
||||
BG_AB_OP_LUMBERMILL_ICON = 1844, //Lumber Mill map icon (NONE)
|
||||
BG_AB_OP_LUMBERMILL_STATE_ALIENCE = 1792, //Lumber Mill map state (ALIENCE)
|
||||
BG_AB_OP_LUMBERMILL_STATE_HORDE = 1793, //Lumber Mill map state (HORDE)
|
||||
BG_AB_OP_LUMBERMILL_STATE_CON_ALI = 1794, //Lumber Mill map state (CON ALIENCE)
|
||||
BG_AB_OP_LUMBERMILL_STATE_CON_HOR = 1795, //Lumber Mill map state (CON HORDE)
|
||||
|
||||
BG_AB_OP_GOLDMINE_ICON = 1843, //Gold Mine map icon (NONE)
|
||||
BG_AB_OP_GOLDMINE_STATE_ALIENCE = 1787, //Gold Mine map state (ALIENCE)
|
||||
BG_AB_OP_GOLDMINE_STATE_HORDE = 1788, //Gold Mine map state (HORDE)
|
||||
BG_AB_OP_GOLDMINE_STATE_CON_ALI = 1789, //Gold Mine map state (CON ALIENCE
|
||||
BG_AB_OP_GOLDMINE_STATE_CON_HOR = 1790, //Gold Mine map state (CON HORDE)
|
||||
};
|
||||
|
||||
enum BG_AB_ObjectIds
|
||||
{
|
||||
BG_AB_OBJECTID_NODE_BANNER_0 = 180087, // Stables banner
|
||||
BG_AB_OBJECTID_NODE_BANNER_1 = 180088, // Blacksmith banner
|
||||
BG_AB_OBJECTID_NODE_BANNER_2 = 180089, // Farm banner
|
||||
BG_AB_OBJECTID_NODE_BANNER_3 = 180090, // Lumber mill banner
|
||||
BG_AB_OBJECTID_NODE_BANNER_4 = 180091, // Gold mine banner
|
||||
|
||||
BG_AB_OBJECTID_BANNER_A = 180058,
|
||||
BG_AB_OBJECTID_BANNER_CONT_A = 180059,
|
||||
BG_AB_OBJECTID_BANNER_H = 180060,
|
||||
BG_AB_OBJECTID_BANNER_CONT_H = 180061,
|
||||
|
||||
BG_AB_OBJECTID_AURA_A = 180100,
|
||||
BG_AB_OBJECTID_AURA_H = 180101,
|
||||
BG_AB_OBJECTID_AURA_C = 180102,
|
||||
|
||||
BG_AB_OBJECTID_GATE_A = 180255,
|
||||
BG_AB_OBJECTID_GATE_H = 180256
|
||||
};
|
||||
|
||||
enum BG_AB_ObjectType
|
||||
{
|
||||
BG_AB_OBJECT_BANNER_NEUTRAL = 0,
|
||||
BG_AB_OBJECT_BANNER_ALLY = 1,
|
||||
BG_AB_OBJECT_BANNER_HORDE = 2,
|
||||
BG_AB_OBJECT_BANNER_CONT_A = 3,
|
||||
BG_AB_OBJECT_BANNER_CONT_H = 4,
|
||||
BG_AB_OBJECT_AURA_ALLY = 5,
|
||||
BG_AB_OBJECT_AURA_HORDE = 6,
|
||||
BG_AB_OBJECT_AURA_CONTESTED = 7,
|
||||
BG_AB_OBJECTS_PER_NODE = 8,
|
||||
|
||||
BG_AB_OBJECT_GATE_A = 40,
|
||||
BG_AB_OBJECT_GATE_H = 41,
|
||||
|
||||
BG_AB_OBJECT_SPEEDBUFF_STABLES = 42,
|
||||
BG_AB_OBJECT_REGENBUFF_STABLES = 43,
|
||||
BG_AB_OBJECT_BERSERKBUFF_STABLES = 44,
|
||||
BG_AB_OBJECT_SPEEDBUFF_BLACKSMITH = 45,
|
||||
BG_AB_OBJECT_REGENBUFF_BLACKSMITH = 46,
|
||||
BG_AB_OBJECT_BERSERKBUFF_BLACKSMITH = 47,
|
||||
BG_AB_OBJECT_SPEEDBUFF_FARM = 48,
|
||||
BG_AB_OBJECT_REGENBUFF_FARM = 49,
|
||||
BG_AB_OBJECT_BERSERKBUFF_FARM = 50,
|
||||
BG_AB_OBJECT_SPEEDBUFF_LUMBER_MILL = 51,
|
||||
BG_AB_OBJECT_REGENBUFF_LUMBER_MILL = 52,
|
||||
BG_AB_OBJECT_BERSERKBUFF_LUMBER_MILL = 53,
|
||||
BG_AB_OBJECT_SPEEDBUFF_GOLD_MINE = 54,
|
||||
BG_AB_OBJECT_REGENBUFF_GOLD_MINE = 55,
|
||||
BG_AB_OBJECT_BERSERKBUFF_GOLD_MINE = 56,
|
||||
BG_AB_OBJECT_MAX = 57,
|
||||
};
|
||||
|
||||
enum BG_AB_BattlegroundNodes
|
||||
{
|
||||
BG_AB_NODE_STABLES = 0,
|
||||
BG_AB_NODE_BLACKSMITH = 1,
|
||||
BG_AB_NODE_FARM = 2,
|
||||
BG_AB_NODE_LUMBER_MILL = 3,
|
||||
BG_AB_NODE_GOLD_MINE = 4,
|
||||
BG_AB_DYNAMIC_NODES_COUNT = 5, // dynamic nodes that can be captured
|
||||
|
||||
BG_AB_SPIRIT_ALIANCE = 5,
|
||||
BG_AB_SPIRIT_HORDE = 6,
|
||||
BG_AB_ALL_NODES_COUNT = 7, // all nodes (dynamic and static)
|
||||
};
|
||||
|
||||
enum BG_AB_NodeStatus
|
||||
{
|
||||
BG_AB_NODE_STATE_NEUTRAL = 0,
|
||||
BG_AB_NODE_STATE_ALLY_OCCUPIED = 1,
|
||||
BG_AB_NODE_STATE_HORDE_OCCUPIED = 2,
|
||||
BG_AB_NODE_STATE_ALLY_CONTESTED = 3,
|
||||
BG_AB_NODE_STATE_HORDE_CONTESTED = 4
|
||||
};
|
||||
|
||||
enum BG_AB_Sounds
|
||||
{
|
||||
BG_AB_SOUND_NODE_CLAIMED = 8192,
|
||||
BG_AB_SOUND_NODE_CAPTURED_ALLIANCE = 8173,
|
||||
BG_AB_SOUND_NODE_CAPTURED_HORDE = 8213,
|
||||
BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE = 8212,
|
||||
BG_AB_SOUND_NODE_ASSAULTED_HORDE = 8174,
|
||||
BG_AB_SOUND_NEAR_VICTORY = 8456
|
||||
};
|
||||
|
||||
enum BG_AB_Misc
|
||||
{
|
||||
BG_AB_OBJECTIVE_ASSAULT_BASE = 122,
|
||||
BG_AB_OBJECTIVE_DEFEND_BASE = 123,
|
||||
BG_AB_EVENT_START_BATTLE = 9158, // Achievement: Let's Get This Done
|
||||
BG_AB_QUEST_CREDIT_BASE = 15001,
|
||||
|
||||
BG_AB_HONOR_TICK_NORMAL = 260,
|
||||
BG_AB_HONOR_TICK_WEEKEND = 160,
|
||||
BG_AB_REP_TICK_NORMAL = 160,
|
||||
BG_AB_REP_TICK_WEEKEND = 120,
|
||||
|
||||
BG_AB_WARNING_NEAR_VICTORY_SCORE = 1400,
|
||||
BG_AB_MAX_TEAM_SCORE = 1600,
|
||||
|
||||
BG_AB_FLAG_CAPTURING_TIME = 60000,
|
||||
BG_AB_BANNER_UPDATE_TIME = 2000
|
||||
};
|
||||
|
||||
const uint32 BG_AB_TickIntervals[BG_AB_DYNAMIC_NODES_COUNT+1] = {0, 12000, 9000, 6000, 3000, 1000};
|
||||
const uint32 BG_AB_TickPoints[BG_AB_DYNAMIC_NODES_COUNT+1] = {0, 10, 10, 10, 10, 30};
|
||||
const uint32 BG_AB_GraveyardIds[BG_AB_ALL_NODES_COUNT] = {895, 894, 893, 897, 896, 898, 899};
|
||||
|
||||
const float BG_AB_BuffPositions[BG_AB_DYNAMIC_NODES_COUNT][4] =
|
||||
{
|
||||
{1185.71f, 1185.24f, -56.36f, 2.56f}, // stables
|
||||
{990.75f, 1008.18f, -42.60f, 2.43f}, // blacksmith
|
||||
{817.66f, 843.34f, -56.54f, 3.01f}, // farm
|
||||
{807.46f, 1189.16f, 11.92f, 5.44f}, // lumber mill
|
||||
{1146.62f, 816.94f, -98.49f, 6.14f} // gold mine
|
||||
};
|
||||
|
||||
const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] =
|
||||
{
|
||||
{1166.785f, 1200.132f, -56.70859f, 0.9075713f}, // stables
|
||||
{977.0156f, 1046.616f, -44.80923f, -2.600541f}, // blacksmith
|
||||
{806.1821f, 874.2723f, -55.99371f, -2.303835f}, // farm
|
||||
{856.1419f, 1148.902f, 11.18469f, -2.303835f}, // lumber mill
|
||||
{1146.923f, 848.1782f, -110.917f, -0.7330382f} // gold mine
|
||||
};
|
||||
|
||||
const float BG_AB_DoorPositions[2][8] =
|
||||
{
|
||||
{1284.597f, 1281.167f, -15.97792f, 0.7068594f, 0.012957f, -0.060288f, 0.344959f, 0.93659f},
|
||||
{708.0903f, 708.4479f, -17.8342f, -2.391099f, 0.050291f, 0.015127f, 0.929217f, -0.365784f}
|
||||
};
|
||||
|
||||
const float BG_AB_SpiritGuidePos[BG_AB_ALL_NODES_COUNT][4] =
|
||||
{
|
||||
{1200.03f, 1171.09f, -56.47f, 5.15f}, // stables
|
||||
{1017.43f, 960.61f, -42.95f, 4.88f}, // blacksmith
|
||||
{833.00f, 793.00f, -57.25f, 5.27f}, // farm
|
||||
{775.17f, 1206.40f, 15.79f, 1.90f}, // lumber mill
|
||||
{1207.48f, 787.00f, -83.36f, 5.51f}, // gold mine
|
||||
{1354.05f, 1275.48f, -11.30f, 4.77f}, // alliance starting base
|
||||
{714.61f, 646.15f, -10.87f, 4.34f} // horde starting base
|
||||
};
|
||||
|
||||
struct BattlegroundABScore : public BattlegroundScore
|
||||
{
|
||||
BattlegroundABScore(Player* player) : BattlegroundScore(player), BasesAssaulted(0), BasesDefended(0) { }
|
||||
~BattlegroundABScore() { }
|
||||
uint32 BasesAssaulted;
|
||||
uint32 BasesDefended;
|
||||
};
|
||||
|
||||
class BattlegroundAB : public Battleground
|
||||
{
|
||||
public:
|
||||
BattlegroundAB();
|
||||
~BattlegroundAB();
|
||||
|
||||
void AddPlayer(Player* player);
|
||||
void StartingEventCloseDoors();
|
||||
void StartingEventOpenDoors();
|
||||
void RemovePlayer(Player* player);
|
||||
void HandleAreaTrigger(Player* player, uint32 trigger);
|
||||
bool SetupBattleground();
|
||||
void Init();
|
||||
void EndBattleground(TeamId winnerTeamId);
|
||||
WorldSafeLocsEntry const* GetClosestGraveyard(Player* player);
|
||||
|
||||
void UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
void FillInitialWorldStates(WorldPacket& data);
|
||||
void EventPlayerClickedOnFlag(Player* source, GameObject* gameObject);
|
||||
|
||||
bool AllNodesConrolledByTeam(TeamId teamId) const;
|
||||
bool IsTeamScores500Disadvantage(TeamId teamId) const { return _teamScores500Disadvantage[teamId]; }
|
||||
|
||||
TeamId GetPrematureWinner();
|
||||
private:
|
||||
void PostUpdateImpl(uint32 diff);
|
||||
|
||||
void DeleteBanner(uint8 node);
|
||||
void CreateBanner(uint8 node, bool delay);
|
||||
void SendNodeUpdate(uint8 node);
|
||||
void NodeOccupied(uint8 node);
|
||||
void NodeDeoccupied(uint8 node);
|
||||
void ApplyPhaseMask();
|
||||
|
||||
struct CapturePointInfo
|
||||
{
|
||||
CapturePointInfo() : _ownerTeamId(TEAM_NEUTRAL), _iconNone(0), _iconCapture(0), _state(BG_AB_NODE_STATE_NEUTRAL), _captured(false)
|
||||
{
|
||||
}
|
||||
|
||||
uint8 _state;
|
||||
uint32 _iconNone;
|
||||
uint32 _iconCapture;
|
||||
TeamId _ownerTeamId;
|
||||
bool _captured;
|
||||
};
|
||||
|
||||
CapturePointInfo _capturePointInfo[BG_AB_DYNAMIC_NODES_COUNT];
|
||||
EventMap _bgEvents;
|
||||
uint32 _honorTics;
|
||||
uint32 _reputationTics;
|
||||
uint8 _controlledPoints[BG_TEAMS_COUNT];
|
||||
bool _teamScores500Disadvantage[BG_TEAMS_COUNT];
|
||||
};
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 "BattlegroundBE.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
BattlegroundBE::BattlegroundBE()
|
||||
{
|
||||
BgObjects.resize(BG_BE_OBJECT_MAX);
|
||||
|
||||
StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattlegroundBE::~BattlegroundBE()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattlegroundBE::StartingEventCloseDoors()
|
||||
{
|
||||
for (uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_4; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
for (uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
void BattlegroundBE::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
for (uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
void BattlegroundBE::AddPlayer(Player* player)
|
||||
{
|
||||
Battleground::AddPlayer(player);
|
||||
PlayerScores[player->GetGUID()] = new BattlegroundScore(player);
|
||||
Battleground::UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattlegroundBE::RemovePlayer(Player* /*player*/)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
Battleground::UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattlegroundBE::HandleKillPlayer(Player* player, Player* killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!killer)
|
||||
{
|
||||
sLog->outError("Killer player not found");
|
||||
return;
|
||||
}
|
||||
|
||||
Battleground::HandleKillPlayer(player, killer);
|
||||
|
||||
Battleground::UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattlegroundBE::HandlePlayerUnderMap(Player* player)
|
||||
{
|
||||
player->NearTeleportTo(6238.930176f, 262.963470f, 0.889519f, player->GetOrientation());
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundBE::HandleAreaTrigger(Player* player, uint32 trigger)
|
||||
{
|
||||
// this is wrong way to implement these things. On official it done by gameobject spell cast.
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
switch (trigger)
|
||||
{
|
||||
case 4538: // buff trigger?
|
||||
//buff_guid = BgObjects[BG_BE_OBJECT_BUFF_1];
|
||||
break;
|
||||
case 4539: // buff trigger?
|
||||
//buff_guid = BgObjects[BG_BE_OBJECT_BUFF_2];
|
||||
break;
|
||||
// OUTSIDE OF ARENA, TELEPORT!
|
||||
case 4919:
|
||||
player->NearTeleportTo(6220.90f, 318.94f, 5.1f, 5.3f);
|
||||
break;
|
||||
case 4921:
|
||||
player->NearTeleportTo(6250.27f, 208.50f, 4.77f, 1.9f);
|
||||
break;
|
||||
case 4922:
|
||||
player->NearTeleportTo(6214.4f, 227.12f, 4.28f, 0.8f);
|
||||
break;
|
||||
case 4923:
|
||||
player->NearTeleportTo(6180.98f, 265.28f, 4.27f, 6.06f);
|
||||
break;
|
||||
case 4924:
|
||||
player->NearTeleportTo(6269.0f, 295.06f, 4.46f, 3.98f);
|
||||
break;
|
||||
case 4944: // under arena -20
|
||||
case 5039: // under arena -40
|
||||
case 5040: // under arena -60
|
||||
player->NearTeleportTo(6238.930176f, 262.963470f, 0.889519f, player->GetOrientation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundBE::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(0x9f3) << uint32(1); // 9
|
||||
Battleground::UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattlegroundBE::Init()
|
||||
{
|
||||
//call parent's class reset
|
||||
Battleground::Init();
|
||||
}
|
||||
|
||||
bool BattlegroundBE::SetupBattleground()
|
||||
{
|
||||
// gates
|
||||
if (!AddObject(BG_BE_OBJECT_DOOR_1, BG_BE_OBJECT_TYPE_DOOR_1, 6287.277f, 282.1877f, 3.810925f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_BE_OBJECT_DOOR_2, BG_BE_OBJECT_TYPE_DOOR_2, 6189.546f, 241.7099f, 3.101481f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_BE_OBJECT_DOOR_3, BG_BE_OBJECT_TYPE_DOOR_3, 6299.116f, 296.5494f, 3.308032f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_BE_OBJECT_DOOR_4, BG_BE_OBJECT_TYPE_DOOR_4, 6177.708f, 227.3481f, 3.604374f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f, RESPAWN_IMMEDIATELY)
|
||||
// buffs
|
||||
|| !AddObject(BG_BE_OBJECT_BUFF_1, BG_BE_OBJECT_TYPE_BUFF_1, 6249.042f, 275.3239f, 11.22033f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120)
|
||||
|| !AddObject(BG_BE_OBJECT_BUFF_2, BG_BE_OBJECT_TYPE_BUFF_2, 6228.26f, 249.566f, 11.21812f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120)
|
||||
// Arena Ready Marker
|
||||
|| !AddObject(BG_BE_OBJECT_READY_MARKER_1, ARENA_READY_MARKER_ENTRY, 6189.47f, 235.54f, 5.52f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300)
|
||||
|| !AddObject(BG_BE_OBJECT_READY_MARKER_2, ARENA_READY_MARKER_ENTRY, 6287.19f, 288.25f, 5.33f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300))
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundBE: Failed to spawn some object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundBE::UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
Battleground::UpdatePlayerScore(player, type, value, doAddHonor);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 __BATTLEGROUNDBE_H
|
||||
#define __BATTLEGROUNDBE_H
|
||||
|
||||
#include "Battleground.h"
|
||||
|
||||
enum BattlegroundBEObjectTypes
|
||||
{
|
||||
BG_BE_OBJECT_DOOR_1 = 0,
|
||||
BG_BE_OBJECT_DOOR_2 = 1,
|
||||
BG_BE_OBJECT_DOOR_3 = 2,
|
||||
BG_BE_OBJECT_DOOR_4 = 3,
|
||||
BG_BE_OBJECT_BUFF_1 = 4,
|
||||
BG_BE_OBJECT_BUFF_2 = 5,
|
||||
BG_BE_OBJECT_READY_MARKER_1 = 6,
|
||||
BG_BE_OBJECT_READY_MARKER_2 = 7,
|
||||
BG_BE_OBJECT_MAX = 8
|
||||
};
|
||||
|
||||
enum BattlegroundBEObjects
|
||||
{
|
||||
BG_BE_OBJECT_TYPE_DOOR_1 = 183971,
|
||||
BG_BE_OBJECT_TYPE_DOOR_2 = 183973,
|
||||
BG_BE_OBJECT_TYPE_DOOR_3 = 183970,
|
||||
BG_BE_OBJECT_TYPE_DOOR_4 = 183972,
|
||||
BG_BE_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_BE_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
class BattlegroundBE : public Battleground
|
||||
{
|
||||
public:
|
||||
BattlegroundBE();
|
||||
~BattlegroundBE();
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
void AddPlayer(Player* player);
|
||||
void StartingEventCloseDoors();
|
||||
void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player* player);
|
||||
void HandleAreaTrigger(Player* player, uint32 trigger);
|
||||
bool SetupBattleground();
|
||||
void Init();
|
||||
void FillInitialWorldStates(WorldPacket &d);
|
||||
void HandleKillPlayer(Player* player, Player* killer);
|
||||
bool HandlePlayerUnderMap(Player* player);
|
||||
|
||||
/* Scorekeeping */
|
||||
void UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 "BattlegroundDS.h"
|
||||
#include "Creature.h"
|
||||
#include "GameObject.h"
|
||||
#include "Language.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
BattlegroundDS::BattlegroundDS()
|
||||
{
|
||||
BgObjects.resize(BG_DS_OBJECT_MAX);
|
||||
BgCreatures.resize(BG_DS_NPC_MAX);
|
||||
|
||||
_waterfallTimer = 0;
|
||||
_waterfallStatus = 0;
|
||||
_waterfallKnockbackTimer = 0;
|
||||
_pipeKnockBackTimer = 0;
|
||||
_pipeKnockBackCount = 0;
|
||||
|
||||
StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattlegroundDS::~BattlegroundDS()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattlegroundDS::PostUpdateImpl(uint32 diff)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (getPipeKnockBackCount() < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT)
|
||||
{
|
||||
if (getPipeKnockBackTimer() < diff)
|
||||
{
|
||||
for (uint32 i = BG_DS_NPC_PIPE_KNOCKBACK_1; i <= BG_DS_NPC_PIPE_KNOCKBACK_2; ++i)
|
||||
if (Creature* waterSpout = GetBgMap()->GetCreature(BgCreatures[i]))
|
||||
waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true);
|
||||
|
||||
setPipeKnockBackCount(getPipeKnockBackCount() + 1);
|
||||
setPipeKnockBackTimer(BG_DS_PIPE_KNOCKBACK_DELAY);
|
||||
}
|
||||
else
|
||||
setPipeKnockBackTimer(getPipeKnockBackTimer() - diff);
|
||||
}
|
||||
|
||||
if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_ON) // Repeat knockback while the waterfall still active
|
||||
{
|
||||
if (getWaterFallKnockbackTimer() < diff)
|
||||
{
|
||||
if (Creature* waterSpout = GetBgMap()->GetCreature(BgCreatures[BG_DS_NPC_WATERFALL_KNOCKBACK]))
|
||||
waterSpout->CastSpell(waterSpout, BG_DS_SPELL_WATER_SPOUT, true);
|
||||
|
||||
setWaterFallKnockbackTimer(BG_DS_WATERFALL_KNOCKBACK_TIMER);
|
||||
}
|
||||
else
|
||||
setWaterFallKnockbackTimer(getWaterFallKnockbackTimer() - diff);
|
||||
}
|
||||
|
||||
if (getWaterFallTimer() < diff)
|
||||
{
|
||||
if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_OFF) // Add the water
|
||||
{
|
||||
DoorClose(BG_DS_OBJECT_WATER_2);
|
||||
setWaterFallTimer(BG_DS_WATERFALL_WARNING_DURATION);
|
||||
setWaterFallStatus(BG_DS_WATERFALL_STATUS_WARNING);
|
||||
}
|
||||
else if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_WARNING) // Active collision and perform knockback
|
||||
{
|
||||
if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[BG_DS_OBJECT_WATER_1]))
|
||||
gob->SetGoState(GO_STATE_READY);
|
||||
|
||||
setWaterFallTimer(BG_DS_WATERFALL_DURATION);
|
||||
setWaterFallStatus(BG_DS_WATERFALL_STATUS_ON);
|
||||
setWaterFallKnockbackTimer(BG_DS_WATERFALL_KNOCKBACK_TIMER);
|
||||
}
|
||||
else //if (getWaterFallStatus() == BG_DS_WATERFALL_STATUS_ON) // Remove collision and water
|
||||
{
|
||||
// turn off collision
|
||||
if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[BG_DS_OBJECT_WATER_1]))
|
||||
gob->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
DoorOpen(BG_DS_OBJECT_WATER_2);
|
||||
setWaterFallTimer(urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX));
|
||||
setWaterFallStatus(BG_DS_WATERFALL_STATUS_OFF);
|
||||
}
|
||||
}
|
||||
else
|
||||
setWaterFallTimer(getWaterFallTimer() - diff);
|
||||
}
|
||||
|
||||
void BattlegroundDS::StartingEventCloseDoors()
|
||||
{
|
||||
for (uint32 i = BG_DS_OBJECT_DOOR_1; i <= BG_DS_OBJECT_DOOR_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattlegroundDS::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 i = BG_DS_OBJECT_DOOR_1; i <= BG_DS_OBJECT_DOOR_2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
for (uint32 i = BG_DS_OBJECT_BUFF_1; i <= BG_DS_OBJECT_BUFF_2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
|
||||
setWaterFallTimer(urand(BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX));
|
||||
setWaterFallStatus(BG_DS_WATERFALL_STATUS_OFF);
|
||||
|
||||
setPipeKnockBackTimer(BG_DS_PIPE_KNOCKBACK_FIRST_DELAY);
|
||||
setPipeKnockBackCount(0);
|
||||
|
||||
SpawnBGObject(BG_DS_OBJECT_WATER_2, RESPAWN_IMMEDIATELY);
|
||||
DoorOpen(BG_DS_OBJECT_WATER_2);
|
||||
|
||||
// Turn off collision
|
||||
if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[BG_DS_OBJECT_WATER_1]))
|
||||
gob->SetGoState(GO_STATE_ACTIVE);
|
||||
|
||||
// Remove effects of Demonic Circle Summon
|
||||
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if (itr->second->HasAura(48018))
|
||||
itr->second->RemoveAurasDueToSpell(48018);
|
||||
}
|
||||
|
||||
void BattlegroundDS::AddPlayer(Player* player)
|
||||
{
|
||||
Battleground::AddPlayer(player);
|
||||
PlayerScores[player->GetGUID()] = new BattlegroundScore(player);
|
||||
Battleground::UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattlegroundDS::RemovePlayer(Player* /*player*/)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
Battleground::UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattlegroundDS::HandleKillPlayer(Player* player, Player* killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!killer)
|
||||
{
|
||||
sLog->outError("BattlegroundDS: Killer player not found");
|
||||
return;
|
||||
}
|
||||
|
||||
Battleground::HandleKillPlayer(player, killer);
|
||||
|
||||
Battleground::UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattlegroundDS::HandleAreaTrigger(Player* player, uint32 trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
switch (trigger)
|
||||
{
|
||||
case 5347:
|
||||
case 5348:
|
||||
// Remove effects of Demonic Circle Summon
|
||||
if (player->HasAura(48018))
|
||||
player->RemoveAurasDueToSpell(48018);
|
||||
|
||||
// Someone has get back into the pipes and the knockback has already been performed,
|
||||
// so we reset the knockback count for kicking the player again into the arena.
|
||||
if (getPipeKnockBackCount() >= BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT)
|
||||
setPipeKnockBackCount(0);
|
||||
break;
|
||||
// OUTSIDE OF ARENA, TELEPORT!
|
||||
case 5328:
|
||||
player->NearTeleportTo(1290.44f, 744.96f, 3.16f, 1.6f);
|
||||
break;
|
||||
case 5329:
|
||||
player->NearTeleportTo(1292.6f, 837.07f, 3.161f, 4.7f);
|
||||
break;
|
||||
case 5330:
|
||||
player->NearTeleportTo(1250.68f, 790.86f, 3.16f, 0.0f);
|
||||
break;
|
||||
case 5331:
|
||||
player->NearTeleportTo(1332.50f, 790.9f, 3.16f, 3.14f);
|
||||
break;
|
||||
case 5326: // -10
|
||||
case 5343: // -40
|
||||
case 5344: // -60
|
||||
player->NearTeleportTo(1330.0f, 800.0f, 3.16f, player->GetOrientation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool BattlegroundDS::HandlePlayerUnderMap(Player* player)
|
||||
{
|
||||
player->NearTeleportTo(1299.046f, 784.825f, 9.338f, 2.422f);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundDS::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(3610) << uint32(1); // 9 show
|
||||
Battleground::UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattlegroundDS::Init()
|
||||
{
|
||||
//call parent's class reset
|
||||
Battleground::Init();
|
||||
}
|
||||
|
||||
bool BattlegroundDS::SetupBattleground()
|
||||
{
|
||||
// gates
|
||||
if (!AddObject(BG_DS_OBJECT_DOOR_1, BG_DS_OBJECT_TYPE_DOOR_1, 1350.95f, 817.2f, 20.8096f, 3.15f, 0, 0, 0.99627f, 0.0862864f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_DS_OBJECT_DOOR_2, BG_DS_OBJECT_TYPE_DOOR_2, 1232.65f, 764.913f, 20.0729f, 6.3f, 0, 0, 0.0310211f, -0.999519f, RESPAWN_IMMEDIATELY)
|
||||
// water
|
||||
|| !AddObject(BG_DS_OBJECT_WATER_1, BG_DS_OBJECT_TYPE_WATER_1, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, 120)
|
||||
|| !AddObject(BG_DS_OBJECT_WATER_2, BG_DS_OBJECT_TYPE_WATER_2, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, 120)
|
||||
// buffs
|
||||
|| !AddObject(BG_DS_OBJECT_BUFF_1, BG_DS_OBJECT_TYPE_BUFF_1, 1291.7f, 813.424f, 7.11472f, 4.64562f, 0, 0, 0.730314f, -0.683111f, 120)
|
||||
|| !AddObject(BG_DS_OBJECT_BUFF_2, BG_DS_OBJECT_TYPE_BUFF_2, 1291.7f, 768.911f, 7.11472f, 1.55194f, 0, 0, 0.700409f, 0.713742f, 120)
|
||||
// knockback creatures
|
||||
|| !AddCreature(BG_DS_NPC_TYPE_WATER_SPOUT, BG_DS_NPC_WATERFALL_KNOCKBACK, 1291.76f, 791.02f, 7.115f, 3.054326f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddCreature(BG_DS_NPC_TYPE_WATER_SPOUT, BG_DS_NPC_PIPE_KNOCKBACK_1, 1369.977f, 817.2882f, 16.08718f, 3.106686f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddCreature(BG_DS_NPC_TYPE_WATER_SPOUT, BG_DS_NPC_PIPE_KNOCKBACK_2, 1212.833f, 765.3871f, 16.09484f, 0.0f, RESPAWN_IMMEDIATELY)
|
||||
// Arena Ready Marker
|
||||
|| !AddObject(BG_DS_OBJECT_READY_MARKER_1, ARENA_READY_MARKER_ENTRY, 1229.44f, 759.35f, 17.89f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300)
|
||||
|| !AddObject(BG_DS_OBJECT_READY_MARKER_2, ARENA_READY_MARKER_ENTRY, 1352.90f, 822.77f, 17.96f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300))
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundDS: Failed to spawn some object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 __BATTLEGROUNDDS_H
|
||||
#define __BATTLEGROUNDDS_H
|
||||
|
||||
#include "Battleground.h"
|
||||
|
||||
enum BattlegroundDSObjectTypes
|
||||
{
|
||||
BG_DS_OBJECT_DOOR_1 = 0,
|
||||
BG_DS_OBJECT_DOOR_2 = 1,
|
||||
BG_DS_OBJECT_WATER_1 = 2, // Collision
|
||||
BG_DS_OBJECT_WATER_2 = 3,
|
||||
BG_DS_OBJECT_BUFF_1 = 4,
|
||||
BG_DS_OBJECT_BUFF_2 = 5,
|
||||
BG_DS_OBJECT_READY_MARKER_1 = 6,
|
||||
BG_DS_OBJECT_READY_MARKER_2 = 7,
|
||||
BG_DS_OBJECT_MAX = 8
|
||||
};
|
||||
|
||||
enum BattlegroundDSObjects
|
||||
{
|
||||
BG_DS_OBJECT_TYPE_DOOR_1 = 192642,
|
||||
BG_DS_OBJECT_TYPE_DOOR_2 = 192643,
|
||||
BG_DS_OBJECT_TYPE_WATER_1 = 194395, // Collision
|
||||
BG_DS_OBJECT_TYPE_WATER_2 = 191877,
|
||||
BG_DS_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_DS_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
enum BattlegroundDSCreatureTypes
|
||||
{
|
||||
BG_DS_NPC_WATERFALL_KNOCKBACK = 0,
|
||||
BG_DS_NPC_PIPE_KNOCKBACK_1 = 1,
|
||||
BG_DS_NPC_PIPE_KNOCKBACK_2 = 2,
|
||||
BG_DS_NPC_MAX = 3
|
||||
};
|
||||
|
||||
enum BattlegroundDSCreatures
|
||||
{
|
||||
BG_DS_NPC_TYPE_WATER_SPOUT = 28567,
|
||||
};
|
||||
|
||||
enum BattlegroundDSSpells
|
||||
{
|
||||
BG_DS_SPELL_FLUSH = 57405, // Visual and target selector for the starting knockback from the pipe
|
||||
BG_DS_SPELL_FLUSH_KNOCKBACK = 61698, // Knockback effect for previous spell (triggered, not need to be casted)
|
||||
BG_DS_SPELL_WATER_SPOUT = 58873, // Knockback effect of the central waterfall
|
||||
};
|
||||
|
||||
enum BattlegroundDSData
|
||||
{ // These values are NOT blizzlike... need the correct data!
|
||||
BG_DS_WATERFALL_TIMER_MIN = 30000,
|
||||
BG_DS_WATERFALL_TIMER_MAX = 60000,
|
||||
BG_DS_WATERFALL_WARNING_DURATION = 5000,
|
||||
BG_DS_WATERFALL_DURATION = 30000,
|
||||
BG_DS_WATERFALL_KNOCKBACK_TIMER = 1500,
|
||||
|
||||
BG_DS_PIPE_KNOCKBACK_FIRST_DELAY = 5000,
|
||||
BG_DS_PIPE_KNOCKBACK_DELAY = 3000,
|
||||
BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT = 2,
|
||||
|
||||
BG_DS_WATERFALL_STATUS_WARNING = 1, // Water starting to fall, but no LoS Blocking nor movement blocking
|
||||
BG_DS_WATERFALL_STATUS_ON = 2, // LoS and Movement blocking active
|
||||
BG_DS_WATERFALL_STATUS_OFF = 3,
|
||||
};
|
||||
|
||||
class BattlegroundDS : public Battleground
|
||||
{
|
||||
public:
|
||||
BattlegroundDS();
|
||||
~BattlegroundDS();
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
void AddPlayer(Player* player);
|
||||
void StartingEventCloseDoors();
|
||||
void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player* player);
|
||||
void HandleAreaTrigger(Player* player, uint32 trigger);
|
||||
bool SetupBattleground();
|
||||
void Init();
|
||||
void FillInitialWorldStates(WorldPacket &d);
|
||||
void HandleKillPlayer(Player* player, Player* killer);
|
||||
bool HandlePlayerUnderMap(Player* player);
|
||||
private:
|
||||
uint32 _waterfallTimer;
|
||||
uint8 _waterfallStatus;
|
||||
uint32 _waterfallKnockbackTimer;
|
||||
uint32 _pipeKnockBackTimer;
|
||||
uint8 _pipeKnockBackCount;
|
||||
|
||||
void PostUpdateImpl(uint32 diff);
|
||||
protected:
|
||||
uint32 getWaterFallStatus() { return _waterfallStatus; };
|
||||
void setWaterFallStatus(uint8 status) { _waterfallStatus = status; };
|
||||
uint32 getWaterFallTimer() { return _waterfallTimer; };
|
||||
void setWaterFallTimer(uint32 timer) { _waterfallTimer = timer; };
|
||||
uint32 getWaterFallKnockbackTimer() { return _waterfallKnockbackTimer; };
|
||||
void setWaterFallKnockbackTimer(uint32 timer) { _waterfallKnockbackTimer = timer; };
|
||||
uint8 getPipeKnockBackCount() { return _pipeKnockBackCount; };
|
||||
void setPipeKnockBackCount(uint8 count) { _pipeKnockBackCount = count; };
|
||||
uint32 getPipeKnockBackTimer() { return _pipeKnockBackTimer; };
|
||||
void setPipeKnockBackTimer(uint32 timer) { _pipeKnockBackTimer = timer; };
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,610 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "BattlegroundEY.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "Creature.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "Player.h"
|
||||
#include "Util.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
BattlegroundEY::BattlegroundEY()
|
||||
{
|
||||
m_BuffChange = true;
|
||||
BgObjects.resize(BG_EY_OBJECT_MAX);
|
||||
BgCreatures.resize(BG_EY_CREATURES_MAX);
|
||||
|
||||
_capturePointInfo[POINT_FEL_REAVER]._areaTrigger = AT_FEL_REAVER_BUFF;
|
||||
_capturePointInfo[POINT_BLOOD_ELF]._areaTrigger = AT_BLOOD_ELF_BUFF;
|
||||
_capturePointInfo[POINT_DRAENEI_RUINS]._areaTrigger = AT_DRAENEI_RUINS_BUFF;
|
||||
_capturePointInfo[POINT_MAGE_TOWER]._areaTrigger = AT_MAGE_TOWER_BUFF;
|
||||
_honorTics = 0;
|
||||
_ownedPointsCount[TEAM_ALLIANCE] = 0;
|
||||
_ownedPointsCount[TEAM_HORDE] = 0;
|
||||
_flagKeeperGUID = 0;
|
||||
_droppedFlagGUID = 0;
|
||||
_flagState = BG_EY_FLAG_STATE_ON_BASE;
|
||||
_flagCapturedObject = 0;
|
||||
|
||||
StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_EY_START_TWO_MINUTES;
|
||||
StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_EY_START_HALF_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattlegroundEY::~BattlegroundEY()
|
||||
{
|
||||
}
|
||||
|
||||
void BattlegroundEY::PostUpdateImpl(uint32 diff)
|
||||
{
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
_bgEvents.Update(diff);
|
||||
while (uint32 eventId = _bgEvents.ExecuteEvent())
|
||||
switch (eventId)
|
||||
{
|
||||
case BG_EY_EVENT_ADD_POINTS:
|
||||
if (_ownedPointsCount[TEAM_ALLIANCE] > 0)
|
||||
AddPoints(TEAM_ALLIANCE, BG_EY_TickPoints[_ownedPointsCount[TEAM_ALLIANCE] - 1]);
|
||||
if (_ownedPointsCount[TEAM_HORDE] > 0)
|
||||
AddPoints(TEAM_HORDE, BG_EY_TickPoints[_ownedPointsCount[TEAM_HORDE] - 1]);
|
||||
_bgEvents.ScheduleEvent(BG_EY_EVENT_ADD_POINTS, BG_EY_FPOINTS_TICK_TIME - (World::GetGameTimeMS() % BG_EY_FPOINTS_TICK_TIME));
|
||||
break;
|
||||
case BG_EY_EVENT_FLAG_ON_GROUND:
|
||||
RespawnFlagAfterDrop();
|
||||
break;
|
||||
case BG_EY_EVENT_RESPAWN_FLAG:
|
||||
RespawnFlag();
|
||||
break;
|
||||
case BG_EY_EVENT_CHECK_CPOINTS:
|
||||
UpdatePointsState();
|
||||
_bgEvents.ScheduleEvent(BG_EY_EVENT_CHECK_CPOINTS, BG_EY_FPOINTS_CHECK_TIME - (World::GetGameTimeMS() % BG_EY_FPOINTS_CHECK_TIME));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundEY::StartingEventCloseDoors()
|
||||
{
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY);
|
||||
|
||||
for (uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REAVER_CENTER; i < BG_EY_OBJECT_MAX; ++i)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
void BattlegroundEY::StartingEventOpenDoors()
|
||||
{
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_ONE_DAY);
|
||||
|
||||
for (uint32 i = BG_EY_OBJECT_N_BANNER_FEL_REAVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
for (uint32 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + i*3 + urand(0, 2), RESPAWN_IMMEDIATELY);
|
||||
|
||||
// Achievement: Flurry
|
||||
StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, BG_EY_EVENT_START_BATTLE);
|
||||
_bgEvents.ScheduleEvent(BG_EY_EVENT_ADD_POINTS, 0);
|
||||
_bgEvents.ScheduleEvent(BG_EY_EVENT_CHECK_CPOINTS, 0);
|
||||
}
|
||||
|
||||
void BattlegroundEY::AddPoints(TeamId teamId, uint32 points)
|
||||
{
|
||||
uint8 honorRewards = uint8(m_TeamScores[teamId] / _honorTics);
|
||||
m_TeamScores[teamId] += points;
|
||||
|
||||
for (; honorRewards < uint8(m_TeamScores[teamId] / _honorTics); ++honorRewards)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), teamId);
|
||||
|
||||
UpdateWorldState(teamId == TEAM_ALLIANCE ? EY_ALLIANCE_RESOURCES : EY_HORDE_RESOURCES, std::min<uint32>(m_TeamScores[teamId], BG_EY_MAX_TEAM_SCORE));
|
||||
if (m_TeamScores[teamId] >= BG_EY_MAX_TEAM_SCORE)
|
||||
EndBattleground(teamId);
|
||||
}
|
||||
|
||||
void BattlegroundEY::UpdatePointsState()
|
||||
{
|
||||
std::vector<GameObject*> pointsVec;
|
||||
for (uint8 point = 0; point < EY_POINTS_MAX; ++point)
|
||||
{
|
||||
pointsVec.push_back(GetBGObject(BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + point));
|
||||
_capturePointInfo[point]._playersCount[TEAM_ALLIANCE] = 0;
|
||||
_capturePointInfo[point]._playersCount[TEAM_HORDE] = 0;
|
||||
}
|
||||
|
||||
const BattlegroundPlayerMap& bgPlayerMap = GetPlayers();
|
||||
for (BattlegroundPlayerMap::const_iterator itr = bgPlayerMap.begin(); itr != bgPlayerMap.end(); ++itr)
|
||||
{
|
||||
UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW, itr->second);
|
||||
for (uint8 point = 0; point < EY_POINTS_MAX; ++point)
|
||||
if (GameObject* pointObject = pointsVec[point])
|
||||
if (itr->second->CanCaptureTowerPoint() && itr->second->IsWithinDistInMap(pointObject, BG_EY_POINT_RADIUS))
|
||||
{
|
||||
UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_SHOW, itr->second);
|
||||
UpdateWorldStateForPlayer(PROGRESS_BAR_PERCENT_GREY, BG_EY_PROGRESS_BAR_PERCENT_GREY, itr->second);
|
||||
UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, _capturePointInfo[point]._barStatus, itr->second);
|
||||
++_capturePointInfo[point]._playersCount[itr->second->GetTeamId()];
|
||||
|
||||
// Xinef: ugly hax... area trigger is no longer called by client...
|
||||
if (pointObject->GetEntry() == BG_OBJECT_FR_TOWER_CAP_EY_ENTRY && itr->second->GetDistance2d(2043.96f, 1729.68f) < 3.0f)
|
||||
HandleAreaTrigger(itr->second, AT_FEL_REAVER_POINT);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8 point = 0; point < EY_POINTS_MAX; ++point)
|
||||
{
|
||||
_capturePointInfo[point]._barStatus += std::max<int8>(std::min<int8>(_capturePointInfo[point]._playersCount[TEAM_ALLIANCE] - _capturePointInfo[point]._playersCount[TEAM_HORDE], BG_EY_POINT_MAX_CAPTURERS_COUNT), -BG_EY_POINT_MAX_CAPTURERS_COUNT);
|
||||
_capturePointInfo[point]._barStatus = std::max<int8>(std::min<int8>(_capturePointInfo[point]._barStatus, BG_EY_PROGRESS_BAR_ALI_CONTROLLED), BG_EY_PROGRESS_BAR_HORDE_CONTROLLED);
|
||||
|
||||
TeamId pointOwnerTeamId = TEAM_NEUTRAL;
|
||||
if (_capturePointInfo[point]._barStatus <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW)
|
||||
pointOwnerTeamId = TEAM_HORDE;
|
||||
else if (_capturePointInfo[point]._barStatus >= BG_EY_PROGRESS_BAR_NEUTRAL_HIGH)
|
||||
pointOwnerTeamId = TEAM_ALLIANCE;
|
||||
|
||||
if (pointOwnerTeamId != _capturePointInfo[point]._ownerTeamId)
|
||||
{
|
||||
if (_capturePointInfo[point].IsUncontrolled())
|
||||
EventTeamCapturedPoint(pointOwnerTeamId, point);
|
||||
|
||||
if (pointOwnerTeamId == TEAM_NEUTRAL && _capturePointInfo[point].IsUnderControl())
|
||||
EventTeamLostPoint(pointOwnerTeamId, point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundEY::EndBattleground(TeamId winnerTeamId)
|
||||
{
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), winnerTeamId);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), TEAM_ALLIANCE);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(1), TEAM_HORDE);
|
||||
Battleground::EndBattleground(winnerTeamId);
|
||||
}
|
||||
|
||||
void BattlegroundEY::UpdatePointsCount()
|
||||
{
|
||||
UpdateWorldState(EY_ALLIANCE_BASE, _ownedPointsCount[TEAM_ALLIANCE]);
|
||||
UpdateWorldState(EY_HORDE_BASE, _ownedPointsCount[TEAM_HORDE]);
|
||||
}
|
||||
|
||||
void BattlegroundEY::UpdatePointsIcons(uint32 point)
|
||||
{
|
||||
if (_capturePointInfo[point].IsUnderControl())
|
||||
{
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 0);
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, _capturePointInfo[point].IsUnderControl(TEAM_ALLIANCE));
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, _capturePointInfo[point].IsUnderControl(TEAM_HORDE));
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 0);
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 0);
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundEY::AddPlayer(Player* player)
|
||||
{
|
||||
Battleground::AddPlayer(player);
|
||||
PlayerScores[player->GetGUID()] = new BattlegroundEYScore(player);
|
||||
}
|
||||
|
||||
void BattlegroundEY::RemovePlayer(Player* player)
|
||||
{
|
||||
if (GetFlagPickerGUID() == player->GetGUID())
|
||||
EventPlayerDroppedFlag(player);
|
||||
}
|
||||
|
||||
void BattlegroundEY::HandleAreaTrigger(Player* player, uint32 trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS || !player->IsAlive())
|
||||
return;
|
||||
|
||||
switch (trigger)
|
||||
{
|
||||
case AT_BLOOD_ELF_POINT:
|
||||
if (_capturePointInfo[POINT_BLOOD_ELF].IsUnderControl(player->GetTeamId()))
|
||||
if (_flagState == BG_EY_FLAG_STATE_ON_PLAYER && GetFlagPickerGUID() == player->GetGUID())
|
||||
EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_BLOOD_ELF);
|
||||
break;
|
||||
case AT_FEL_REAVER_POINT:
|
||||
if (_capturePointInfo[POINT_FEL_REAVER].IsUnderControl(player->GetTeamId()))
|
||||
if (_flagState == BG_EY_FLAG_STATE_ON_PLAYER && GetFlagPickerGUID() == player->GetGUID())
|
||||
EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_FEL_REAVER);
|
||||
break;
|
||||
case AT_MAGE_TOWER_POINT:
|
||||
if (_capturePointInfo[POINT_MAGE_TOWER].IsUnderControl(player->GetTeamId()))
|
||||
if (_flagState == BG_EY_FLAG_STATE_ON_PLAYER && GetFlagPickerGUID() == player->GetGUID())
|
||||
EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_MAGE_TOWER);
|
||||
break;
|
||||
case AT_DRAENEI_RUINS_POINT:
|
||||
if (_capturePointInfo[POINT_DRAENEI_RUINS].IsUnderControl(player->GetTeamId()))
|
||||
if (_flagState == BG_EY_FLAG_STATE_ON_PLAYER && GetFlagPickerGUID() == player->GetGUID())
|
||||
EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_DRAENEI_RUINS);
|
||||
break;
|
||||
case 4512:
|
||||
case 4515:
|
||||
case 4517:
|
||||
case 4519:
|
||||
case 4530:
|
||||
case 4531:
|
||||
case 5866:
|
||||
case AT_BLOOD_ELF_BUFF:
|
||||
case AT_FEL_REAVER_BUFF:
|
||||
case AT_MAGE_TOWER_BUFF:
|
||||
case AT_DRAENEI_RUINS_BUFF:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool BattlegroundEY::SetupBattleground()
|
||||
{
|
||||
// doors
|
||||
AddObject(BG_EY_OBJECT_DOOR_A, BG_OBJECT_A_DOOR_EY_ENTRY, 2527.6f, 1596.91f, 1262.13f, -3.12414f, -0.173642f, -0.001515f, 0.98477f, -0.008594f, RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_EY_OBJECT_DOOR_H, BG_OBJECT_H_DOOR_EY_ENTRY, 1803.21f, 1539.49f, 1261.09f, 3.14159f, 0.173648f, 0, 0.984808f, 0, RESPAWN_IMMEDIATELY);
|
||||
// banners (alliance)
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_FEL_REAVER_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_FEL_REAVER_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_FEL_REAVER_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_A_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_A_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_A_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_A_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY);
|
||||
// banners (horde)
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_FEL_REAVER_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_FEL_REAVER_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_FEL_REAVER_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_H_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_H_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_H_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_H_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY);
|
||||
// banners (natural)
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_FEL_REAVER_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2057.46f, 1735.07f, 1187.91f, -0.925024f, 0, 0, 0.446198f, -0.894934f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_FEL_REAVER_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2032.25f, 1729.53f, 1190.33f, 1.8675f, 0, 0, 0.803857f, 0.594823f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_FEL_REAVER_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2092.35f, 1775.46f, 1187.08f, -0.401426f, 0, 0, 0.199368f, -0.979925f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2047.19f, 1349.19f, 1189.0f, -1.62316f, 0, 0, 0.725374f, -0.688354f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2074.32f, 1385.78f, 1194.72f, 0.488692f, 0, 0, 0.241922f, 0.970296f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2025.13f, 1386.12f, 1192.74f, 2.3911f, 0, 0, 0.930418f, 0.366501f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2276.8f, 1400.41f, 1196.33f, 2.44346f, 0, 0, 0.939693f, 0.34202f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2305.78f, 1404.56f, 1199.38f, 1.74533f, 0, 0, 0.766044f, 0.642788f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2245.4f, 1366.41f, 1195.28f, 2.21657f, 0, 0, 0.894934f, 0.446198f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_OBJECT_N_BANNER_EY_ENTRY, 2270.84f, 1784.08f, 1186.76f, 2.42601f, 0, 0, 0.936672f, 0.350207f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_LEFT, BG_OBJECT_N_BANNER_EY_ENTRY, 2269.13f, 1737.7f, 1186.66f, 0.994838f, 0, 0, 0.477159f, 0.878817f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_RIGHT, BG_OBJECT_N_BANNER_EY_ENTRY, 2300.86f, 1741.25f, 1187.7f, -0.785398f, 0, 0, 0.382683f, -0.92388f, RESPAWN_ONE_DAY);
|
||||
// flags
|
||||
AddObject(BG_EY_OBJECT_FLAG_NETHERSTORM, BG_OBJECT_FLAG2_EY_ENTRY, 2174.782227f, 1569.054688f, 1160.361938f, -1.448624f, 0, 0, 0.662620f, -0.748956f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_FLAG_FEL_REAVER, BG_OBJECT_FLAG1_EY_ENTRY, 2044.28f, 1729.68f, 1189.96f, -0.017453f, 0, 0, 0.008727f, -0.999962f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_FLAG_BLOOD_ELF, BG_OBJECT_FLAG1_EY_ENTRY, 2048.83f, 1393.65f, 1194.49f, 0.20944f, 0, 0, 0.104528f, 0.994522f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_FLAG_DRAENEI_RUINS, BG_OBJECT_FLAG1_EY_ENTRY, 2286.56f, 1402.36f, 1197.11f, 3.72381f, 0, 0, 0.957926f, -0.287016f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_FLAG_MAGE_TOWER, BG_OBJECT_FLAG1_EY_ENTRY, 2284.48f, 1731.23f, 1189.99f, 2.89725f, 0, 0, 0.992546f, 0.121869f, RESPAWN_ONE_DAY);
|
||||
// tower cap
|
||||
AddObject(BG_EY_OBJECT_TOWER_CAP_FEL_REAVER, BG_OBJECT_FR_TOWER_CAP_EY_ENTRY, 2024.600708f, 1742.819580f, 1195.157715f, 2.443461f, 0, 0, 0.939693f, 0.342020f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_TOWER_CAP_BLOOD_ELF, BG_OBJECT_BE_TOWER_CAP_EY_ENTRY, 2050.493164f, 1372.235962f, 1194.563477f, 1.710423f, 0, 0, 0.754710f, 0.656059f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_TOWER_CAP_DRAENEI_RUINS, BG_OBJECT_DR_TOWER_CAP_EY_ENTRY, 2301.010498f, 1386.931641f, 1197.183472f, 1.570796f, 0, 0, 0.707107f, 0.707107f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_TOWER_CAP_MAGE_TOWER, BG_OBJECT_HU_TOWER_CAP_EY_ENTRY, 2282.121582f, 1760.006958f, 1189.707153f, 1.919862f, 0, 0, 0.819152f, 0.573576f, RESPAWN_ONE_DAY);
|
||||
|
||||
for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
AreaTriggerEntry const* at = sAreaTriggerStore.LookupEntry(_capturePointInfo[i]._areaTrigger);
|
||||
AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + i * 3 + 0, Buff_Entries[0], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + i * 3 + 1, Buff_Entries[1], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY);
|
||||
AddObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + i * 3 + 2, Buff_Entries[2], at->x, at->y, at->z, 0.907571f, 0, 0, 0.438371f, 0.898794f, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const* sg = NULL;
|
||||
sg = sWorldSafeLocsStore.LookupEntry(BG_EY_GRAVEYARD_MAIN_ALLIANCE);
|
||||
AddSpiritGuide(BG_EY_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, TEAM_ALLIANCE);
|
||||
|
||||
sg = sWorldSafeLocsStore.LookupEntry(BG_EY_GRAVEYARD_MAIN_HORDE);
|
||||
AddSpiritGuide(BG_EY_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, TEAM_HORDE);
|
||||
|
||||
for (uint32 i = BG_EY_OBJECT_DOOR_A; i < BG_EY_OBJECT_MAX; ++i)
|
||||
if (BgObjects[i] == 0)
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundEY: Failed to spawn some object Battleground not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32 i = BG_EY_SPIRIT_MAIN_ALLIANCE; i <= BG_EY_SPIRIT_MAIN_HORDE; ++i)
|
||||
if (BgCreatures[i] == 0)
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundEY: Failed to spawn spirit guides Battleground not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundEY::Init()
|
||||
{
|
||||
//call parent's class reset
|
||||
Battleground::Init();
|
||||
|
||||
_bgEvents.Reset();
|
||||
_honorTics = BattlegroundMgr::IsBGWeekend(GetBgTypeID()) ? BG_EY_HONOR_TICK_WEEKEND : BG_EY_HONOR_TICK_NORMAL;
|
||||
_ownedPointsCount[TEAM_ALLIANCE] = 0;
|
||||
_ownedPointsCount[TEAM_HORDE] = 0;
|
||||
_flagKeeperGUID = 0;
|
||||
_droppedFlagGUID = 0;
|
||||
_flagState = BG_EY_FLAG_STATE_ON_BASE;
|
||||
_flagCapturedObject = 0;
|
||||
}
|
||||
|
||||
void BattlegroundEY::RespawnFlag()
|
||||
{
|
||||
if (_flagState != BG_EY_FLAG_STATE_ON_BASE)
|
||||
return;
|
||||
|
||||
if (_flagCapturedObject > 0)
|
||||
SpawnBGObject(_flagCapturedObject, RESPAWN_ONE_DAY);
|
||||
|
||||
_flagCapturedObject = 0;
|
||||
SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_IMMEDIATELY);
|
||||
|
||||
SendMessageToAll(LANG_BG_EY_RESETED_FLAG, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_RESET);
|
||||
UpdateWorldState(NETHERSTORM_FLAG, 1);
|
||||
}
|
||||
|
||||
void BattlegroundEY::RespawnFlagAfterDrop()
|
||||
{
|
||||
if (_flagState != BG_EY_FLAG_STATE_ON_GROUND)
|
||||
return;
|
||||
|
||||
_flagState = BG_EY_FLAG_STATE_ON_BASE;
|
||||
RespawnFlag();
|
||||
if (GameObject* flag = ObjectAccessor::GetObjectInMap(GetDroppedFlagGUID(), FindBgMap(), (GameObject*)NULL))
|
||||
flag->Delete();
|
||||
SetDroppedFlagGUID(0);
|
||||
}
|
||||
|
||||
void BattlegroundEY::HandleKillPlayer(Player* player, Player* killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
Battleground::HandleKillPlayer(player, killer);
|
||||
EventPlayerDroppedFlag(player);
|
||||
}
|
||||
|
||||
void BattlegroundEY::EventPlayerDroppedFlag(Player* player)
|
||||
{
|
||||
if (GetFlagPickerGUID() != player->GetGUID())
|
||||
return;
|
||||
|
||||
SetFlagPicker(0);
|
||||
player->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
_flagState = BG_EY_FLAG_STATE_ON_GROUND;
|
||||
_bgEvents.RescheduleEvent(BG_EY_EVENT_FLAG_ON_GROUND, BG_EY_FLAG_ON_GROUND_TIME);
|
||||
|
||||
player->CastSpell(player, SPELL_RECENTLY_DROPPED_FLAG, true);
|
||||
player->CastSpell(player, BG_EY_PLAYER_DROPPED_FLAG_SPELL, true);
|
||||
|
||||
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, player->GetTeamId() == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE);
|
||||
}
|
||||
|
||||
void BattlegroundEY::EventPlayerClickedOnFlag(Player* player, GameObject* gameObject)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS || GetFlagPickerGUID() || !player->IsWithinDistInMap(gameObject, 10.0f))
|
||||
return;
|
||||
|
||||
_flagState = BG_EY_FLAG_STATE_ON_PLAYER;
|
||||
SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_ONE_DAY);
|
||||
SetFlagPicker(player->GetGUID());
|
||||
SetDroppedFlagGUID(0);
|
||||
|
||||
player->CastSpell(player, BG_EY_NETHERSTORM_FLAG_SPELL, true);
|
||||
player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
|
||||
PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, player->GetTeamId() == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE, NULL, player->GetName().c_str());
|
||||
PlaySoundToAll(player->GetTeamId() == TEAM_ALLIANCE ? BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE : BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
|
||||
UpdateWorldState(NETHERSTORM_FLAG, 0);
|
||||
}
|
||||
|
||||
void BattlegroundEY::EventTeamLostPoint(TeamId teamId, uint32 point)
|
||||
{
|
||||
TeamId oldTeamId = _capturePointInfo[point]._ownerTeamId;
|
||||
if (oldTeamId == TEAM_ALLIANCE)
|
||||
{
|
||||
_ownedPointsCount[TEAM_ALLIANCE]--;
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeAlliance, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeAlliance + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeAlliance + 2, RESPAWN_ONE_DAY);
|
||||
SendMessageToAll(m_LosingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ownedPointsCount[TEAM_HORDE]--;
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeHorde, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY);
|
||||
SendMessageToAll(m_LosingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE);
|
||||
}
|
||||
|
||||
SpawnBGObject(m_LosingPointTypes[point].SpawnNeutralObjectType, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].SpawnNeutralObjectType + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].SpawnNeutralObjectType + 2, RESPAWN_IMMEDIATELY);
|
||||
|
||||
_capturePointInfo[point]._ownerTeamId = TEAM_NEUTRAL;
|
||||
|
||||
UpdatePointsIcons(point);
|
||||
UpdatePointsCount();
|
||||
DelCreature(BG_EY_TRIGGER_FEL_REAVER + point);
|
||||
}
|
||||
|
||||
void BattlegroundEY::EventTeamCapturedPoint(TeamId teamId, uint32 point)
|
||||
{
|
||||
SpawnBGObject(m_CapturingPointTypes[point].DespawnNeutralObjectType, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].DespawnNeutralObjectType + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].DespawnNeutralObjectType + 2, RESPAWN_ONE_DAY);
|
||||
|
||||
if (teamId == TEAM_ALLIANCE)
|
||||
{
|
||||
_ownedPointsCount[TEAM_ALLIANCE]++;
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeAlliance, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeAlliance + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeAlliance + 2, RESPAWN_IMMEDIATELY);
|
||||
SendMessageToAll(m_CapturingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ownedPointsCount[TEAM_HORDE]++;
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeHorde, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY);
|
||||
SendMessageToAll(m_CapturingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE);
|
||||
}
|
||||
|
||||
_capturePointInfo[point]._ownerTeamId = teamId;
|
||||
if (BgCreatures[point])
|
||||
DelCreature(point);
|
||||
|
||||
WorldSafeLocsEntry const* sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[point].GraveYardId);
|
||||
AddSpiritGuide(point, sg->x, sg->y, sg->z, 3.124139f, teamId);
|
||||
|
||||
UpdatePointsIcons(point);
|
||||
UpdatePointsCount();
|
||||
|
||||
// Xinef: done this way to avoid errors in console
|
||||
Creature* trigger = GetBgMap()->GetCreature(BgCreatures[BG_EY_TRIGGER_FEL_REAVER + point]);
|
||||
if (!trigger)
|
||||
trigger = AddCreature(WORLD_TRIGGER, BG_EY_TRIGGER_FEL_REAVER + point, BG_EY_TriggerPositions[point][0], BG_EY_TriggerPositions[point][1], BG_EY_TriggerPositions[point][2], BG_EY_TriggerPositions[point][3]);
|
||||
|
||||
if (trigger)
|
||||
{
|
||||
trigger->setFaction(teamId == TEAM_ALLIANCE ? 84 : 83);
|
||||
trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, true);
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundEY::EventPlayerCapturedFlag(Player* player, uint32 BgObjectType)
|
||||
{
|
||||
SetFlagPicker(0);
|
||||
_flagState = BG_EY_FLAG_STATE_ON_BASE;
|
||||
player->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
|
||||
player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
|
||||
SpawnBGObject(BgObjectType, RESPAWN_IMMEDIATELY);
|
||||
_bgEvents.RescheduleEvent(BG_EY_EVENT_RESPAWN_FLAG, BG_EY_FLAG_RESPAWN_TIME);
|
||||
_flagCapturedObject = BgObjectType;
|
||||
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE)
|
||||
{
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
|
||||
SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_A, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
|
||||
SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_H, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
}
|
||||
|
||||
UpdatePlayerScore(player, SCORE_FLAG_CAPTURES, 1);
|
||||
if (_ownedPointsCount[player->GetTeamId()] > 0)
|
||||
AddPoints(player->GetTeamId(), BG_EY_FlagPoints[_ownedPointsCount[player->GetTeamId()] - 1]);
|
||||
}
|
||||
|
||||
void BattlegroundEY::UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
if (type == SCORE_FLAG_CAPTURES)
|
||||
{
|
||||
BattlegroundScoreMap::iterator itr = PlayerScores.find(player->GetGUID());
|
||||
if (itr != PlayerScores.end())
|
||||
((BattlegroundEYScore*)itr->second)->FlagCaptures += value;
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, BG_EY_OBJECTIVE_CAPTURE_FLAG);
|
||||
return;
|
||||
}
|
||||
|
||||
Battleground::UpdatePlayerScore(player, type, value, doAddHonor);
|
||||
}
|
||||
|
||||
void BattlegroundEY::FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
data << uint32(EY_HORDE_BASE) << uint32(_ownedPointsCount[TEAM_HORDE]);
|
||||
data << uint32(EY_ALLIANCE_BASE) << uint32(_ownedPointsCount[TEAM_ALLIANCE]);
|
||||
data << uint32(DRAENEI_RUINS_HORDE_CONTROL) << uint32(_capturePointInfo[POINT_DRAENEI_RUINS].IsUnderControl(TEAM_HORDE));
|
||||
data << uint32(DRAENEI_RUINS_ALLIANCE_CONTROL) << uint32(_capturePointInfo[POINT_DRAENEI_RUINS].IsUnderControl(TEAM_ALLIANCE));
|
||||
data << uint32(DRAENEI_RUINS_UNCONTROL) << uint32(_capturePointInfo[POINT_DRAENEI_RUINS].IsUncontrolled());
|
||||
data << uint32(MAGE_TOWER_ALLIANCE_CONTROL) << uint32(_capturePointInfo[POINT_MAGE_TOWER].IsUnderControl(TEAM_HORDE));
|
||||
data << uint32(MAGE_TOWER_HORDE_CONTROL) << uint32(_capturePointInfo[POINT_MAGE_TOWER].IsUnderControl(TEAM_ALLIANCE));
|
||||
data << uint32(MAGE_TOWER_UNCONTROL) << uint32(_capturePointInfo[POINT_MAGE_TOWER].IsUncontrolled());
|
||||
data << uint32(FEL_REAVER_HORDE_CONTROL) << uint32(_capturePointInfo[POINT_FEL_REAVER].IsUnderControl(TEAM_HORDE));
|
||||
data << uint32(FEL_REAVER_ALLIANCE_CONTROL) << uint32(_capturePointInfo[POINT_FEL_REAVER].IsUnderControl(TEAM_ALLIANCE));
|
||||
data << uint32(FEL_REAVER_UNCONTROL) << uint32(_capturePointInfo[POINT_FEL_REAVER].IsUncontrolled());
|
||||
data << uint32(BLOOD_ELF_HORDE_CONTROL) << uint32(_capturePointInfo[POINT_BLOOD_ELF].IsUnderControl(TEAM_HORDE));
|
||||
data << uint32(BLOOD_ELF_ALLIANCE_CONTROL) << uint32(_capturePointInfo[POINT_BLOOD_ELF].IsUnderControl(TEAM_ALLIANCE));
|
||||
data << uint32(BLOOD_ELF_UNCONTROL) << uint32(_capturePointInfo[POINT_BLOOD_ELF].IsUncontrolled());
|
||||
data << uint32(NETHERSTORM_FLAG) << uint32(_flagState == BG_EY_FLAG_STATE_ON_BASE);
|
||||
data << uint32(NETHERSTORM_FLAG_STATE_HORDE) << uint32(1);
|
||||
data << uint32(NETHERSTORM_FLAG_STATE_ALLIANCE) << uint32(1);
|
||||
data << uint32(EY_HORDE_RESOURCES) << uint32(GetTeamScore(TEAM_HORDE));
|
||||
data << uint32(EY_ALLIANCE_RESOURCES) << uint32(GetTeamScore(TEAM_ALLIANCE));
|
||||
data << uint32(PROGRESS_BAR_SHOW) << uint32(0);
|
||||
data << uint32(PROGRESS_BAR_PERCENT_GREY) << uint32(0);
|
||||
data << uint32(PROGRESS_BAR_STATUS) << uint32(0);
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const* BattlegroundEY::GetClosestGraveyard(Player* player)
|
||||
{
|
||||
WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(BG_EY_GRAVEYARD_MAIN_ALLIANCE + player->GetTeamId());
|
||||
WorldSafeLocsEntry const* nearestEntry = entry;
|
||||
|
||||
float pX = player->GetPositionX();
|
||||
float pY = player->GetPositionY();
|
||||
float pZ = player->GetPositionZ();
|
||||
float dist = (entry->x - pX)*(entry->x - pX) + (entry->y - pY)*(entry->y - pY) + (entry->z - pZ)*(entry->z - pZ);
|
||||
float minDist = dist;
|
||||
|
||||
for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
if (_capturePointInfo[i].IsUnderControl(player->GetTeamId()))
|
||||
{
|
||||
entry = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[i].GraveYardId);
|
||||
dist = (entry->x - pX)*(entry->x - pX) + (entry->y - pY)*(entry->y - pY) + (entry->z - pZ)*(entry->z - pZ);
|
||||
if (dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
nearestEntry = entry;
|
||||
}
|
||||
}
|
||||
|
||||
return nearestEntry;
|
||||
}
|
||||
|
||||
bool BattlegroundEY::AllNodesConrolledByTeam(TeamId teamId) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
if (_capturePointInfo[i].IsUnderControl(teamId))
|
||||
++count;
|
||||
|
||||
return count == EY_POINTS_MAX;
|
||||
}
|
||||
|
||||
TeamId BattlegroundEY::GetPrematureWinner()
|
||||
{
|
||||
if (GetTeamScore(TEAM_ALLIANCE) > GetTeamScore(TEAM_HORDE))
|
||||
return TEAM_ALLIANCE;
|
||||
|
||||
return GetTeamScore(TEAM_HORDE) > GetTeamScore(TEAM_ALLIANCE) ? TEAM_HORDE : Battleground::GetPrematureWinner();
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef __BATTLEGROUNDEY_H
|
||||
#define __BATTLEGROUNDEY_H
|
||||
|
||||
#include "Language.h"
|
||||
#include "Battleground.h"
|
||||
|
||||
enum BG_EY_Events
|
||||
{
|
||||
BG_EY_EVENT_ADD_POINTS = 1,
|
||||
BG_EY_EVENT_FLAG_ON_GROUND = 2,
|
||||
BG_EY_EVENT_RESPAWN_FLAG = 3,
|
||||
BG_EY_EVENT_CHECK_CPOINTS = 4
|
||||
};
|
||||
|
||||
enum BG_EY_Timers
|
||||
{
|
||||
BG_EY_FLAG_RESPAWN_TIME = 20*IN_MILLISECONDS,
|
||||
BG_EY_FLAG_ON_GROUND_TIME = 10*IN_MILLISECONDS,
|
||||
BG_EY_FPOINTS_CHECK_TIME = 2*IN_MILLISECONDS,
|
||||
BG_EY_FPOINTS_TICK_TIME = 1*IN_MILLISECONDS
|
||||
};
|
||||
|
||||
enum BG_EY_WorldStates
|
||||
{
|
||||
EY_ALLIANCE_RESOURCES = 2749,
|
||||
EY_HORDE_RESOURCES = 2750,
|
||||
EY_ALLIANCE_BASE = 2752,
|
||||
EY_HORDE_BASE = 2753,
|
||||
DRAENEI_RUINS_HORDE_CONTROL = 2733,
|
||||
DRAENEI_RUINS_ALLIANCE_CONTROL = 2732,
|
||||
DRAENEI_RUINS_UNCONTROL = 2731,
|
||||
MAGE_TOWER_ALLIANCE_CONTROL = 2730,
|
||||
MAGE_TOWER_HORDE_CONTROL = 2729,
|
||||
MAGE_TOWER_UNCONTROL = 2728,
|
||||
FEL_REAVER_HORDE_CONTROL = 2727,
|
||||
FEL_REAVER_ALLIANCE_CONTROL = 2726,
|
||||
FEL_REAVER_UNCONTROL = 2725,
|
||||
BLOOD_ELF_HORDE_CONTROL = 2724,
|
||||
BLOOD_ELF_ALLIANCE_CONTROL = 2723,
|
||||
BLOOD_ELF_UNCONTROL = 2722,
|
||||
PROGRESS_BAR_PERCENT_GREY = 2720, //100 = empty (only grey), 0 = blue|red (no grey)
|
||||
PROGRESS_BAR_STATUS = 2719, //50 init!, 48 ... hordak bere .. 33 .. 0 = full 100% hordacky, 100 = full alliance
|
||||
PROGRESS_BAR_SHOW = 2718, //1 init, 0 druhy send - bez messagu, 1 = controlled aliance
|
||||
NETHERSTORM_FLAG = 2757,
|
||||
//set to 2 when flag is picked up, and to 1 if it is dropped
|
||||
NETHERSTORM_FLAG_STATE_ALLIANCE = 2769,
|
||||
NETHERSTORM_FLAG_STATE_HORDE = 2770
|
||||
};
|
||||
|
||||
enum BG_EY_ProgressBarConsts
|
||||
{
|
||||
BG_EY_POINT_MAX_CAPTURERS_COUNT = 5,
|
||||
BG_EY_POINT_RADIUS = 50,
|
||||
BG_EY_PROGRESS_BAR_DONT_SHOW = 0,
|
||||
BG_EY_PROGRESS_BAR_SHOW = 1,
|
||||
BG_EY_PROGRESS_BAR_PERCENT_GREY = 40,
|
||||
BG_EY_PROGRESS_BAR_STATE_MIDDLE = 50,
|
||||
BG_EY_PROGRESS_BAR_HORDE_CONTROLLED = 0,
|
||||
BG_EY_PROGRESS_BAR_NEUTRAL_LOW = 30,
|
||||
BG_EY_PROGRESS_BAR_NEUTRAL_HIGH = 70,
|
||||
BG_EY_PROGRESS_BAR_ALI_CONTROLLED = 100
|
||||
};
|
||||
|
||||
enum BG_EY_Sounds
|
||||
{
|
||||
BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE = 8212,
|
||||
BG_EY_SOUND_FLAG_CAPTURED_HORDE = 8213,
|
||||
BG_EY_SOUND_FLAG_PICKED_UP_HORDE = 8174,
|
||||
BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
|
||||
BG_EY_SOUND_FLAG_RESET = 8192
|
||||
};
|
||||
|
||||
enum BG_EY_Spells
|
||||
{
|
||||
BG_EY_NETHERSTORM_FLAG_SPELL = 34976,
|
||||
BG_EY_PLAYER_DROPPED_FLAG_SPELL = 34991
|
||||
};
|
||||
|
||||
enum BG_EY_ObjectEntry
|
||||
{
|
||||
BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door
|
||||
BG_OBJECT_H_DOOR_EY_ENTRY = 184720, //Horde door
|
||||
BG_OBJECT_FLAG1_EY_ENTRY = 184493, //Netherstorm flag (generic)
|
||||
BG_OBJECT_FLAG2_EY_ENTRY = 184141, //Netherstorm flag (flagstand)
|
||||
BG_OBJECT_FLAG3_EY_ENTRY = 184142, //Netherstorm flag (flagdrop)
|
||||
BG_OBJECT_A_BANNER_EY_ENTRY = 184381, //Visual Banner (Alliance)
|
||||
BG_OBJECT_H_BANNER_EY_ENTRY = 184380, //Visual Banner (Horde)
|
||||
BG_OBJECT_N_BANNER_EY_ENTRY = 184382, //Visual Banner (Neutral)
|
||||
BG_OBJECT_BE_TOWER_CAP_EY_ENTRY = 184080, //BE Tower Cap Pt
|
||||
BG_OBJECT_FR_TOWER_CAP_EY_ENTRY = 184081, //Fel Reaver Cap Pt
|
||||
BG_OBJECT_HU_TOWER_CAP_EY_ENTRY = 184082, //Human Tower Cap Pt
|
||||
BG_OBJECT_DR_TOWER_CAP_EY_ENTRY = 184083 //Draenei Tower Cap Pt
|
||||
};
|
||||
|
||||
enum BG_EY_AreaTriggers
|
||||
{
|
||||
AT_BLOOD_ELF_POINT = 4476,
|
||||
AT_FEL_REAVER_POINT = 4514,
|
||||
AT_MAGE_TOWER_POINT = 4516,
|
||||
AT_DRAENEI_RUINS_POINT = 4518,
|
||||
AT_BLOOD_ELF_BUFF = 4568,
|
||||
AT_FEL_REAVER_BUFF = 4569,
|
||||
AT_MAGE_TOWER_BUFF = 4570,
|
||||
AT_DRAENEI_RUINS_BUFF = 4571
|
||||
};
|
||||
|
||||
enum BG_EY_Graveyards
|
||||
{
|
||||
BG_EY_GRAVEYARD_MAIN_ALLIANCE = 1103,
|
||||
BG_EY_GRAVEYARD_MAIN_HORDE = 1104,
|
||||
BG_EY_GRAVEYARD_FEL_REAVER = 1105,
|
||||
BG_EY_GRAVEYARD_BLOOD_ELF = 1106,
|
||||
BG_EY_GRAVEYARD_DRAENEI_RUINS = 1107,
|
||||
BG_EY_GRAVEYARD_MAGE_TOWER = 1108
|
||||
};
|
||||
|
||||
enum BG_EY_Points
|
||||
{
|
||||
POINT_FEL_REAVER = 0,
|
||||
POINT_BLOOD_ELF = 1,
|
||||
POINT_DRAENEI_RUINS = 2,
|
||||
POINT_MAGE_TOWER = 3,
|
||||
EY_POINTS_MAX = 4
|
||||
};
|
||||
|
||||
enum BG_EY_CreatureTypes
|
||||
{
|
||||
BG_EY_SPIRIT_FEL_REAVER = 0,
|
||||
BG_EY_SPIRIT_BLOOD_ELF = 1,
|
||||
BG_EY_SPIRIT_DRAENEI_RUINS = 2,
|
||||
BG_EY_SPIRIT_MAGE_TOWER = 3,
|
||||
BG_EY_SPIRIT_MAIN_ALLIANCE = 4,
|
||||
BG_EY_SPIRIT_MAIN_HORDE = 5,
|
||||
|
||||
BG_EY_TRIGGER_FEL_REAVER = 6,
|
||||
BG_EY_TRIGGER_BLOOD_ELF = 7,
|
||||
BG_EY_TRIGGER_DRAENEI_RUINS = 8,
|
||||
BG_EY_TRIGGER_MAGE_TOWER = 9,
|
||||
|
||||
BG_EY_CREATURES_MAX = 10
|
||||
};
|
||||
|
||||
enum BG_EY_ObjectTypes
|
||||
{
|
||||
BG_EY_OBJECT_DOOR_A = 0,
|
||||
BG_EY_OBJECT_DOOR_H = 1,
|
||||
BG_EY_OBJECT_A_BANNER_FEL_REAVER_CENTER = 2,
|
||||
BG_EY_OBJECT_A_BANNER_FEL_REAVER_LEFT = 3,
|
||||
BG_EY_OBJECT_A_BANNER_FEL_REAVER_RIGHT = 4,
|
||||
BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER = 5,
|
||||
BG_EY_OBJECT_A_BANNER_BLOOD_ELF_LEFT = 6,
|
||||
BG_EY_OBJECT_A_BANNER_BLOOD_ELF_RIGHT = 7,
|
||||
BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER = 8,
|
||||
BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_LEFT = 9,
|
||||
BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_RIGHT = 10,
|
||||
BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER = 11,
|
||||
BG_EY_OBJECT_A_BANNER_MAGE_TOWER_LEFT = 12,
|
||||
BG_EY_OBJECT_A_BANNER_MAGE_TOWER_RIGHT = 13,
|
||||
BG_EY_OBJECT_H_BANNER_FEL_REAVER_CENTER = 14,
|
||||
BG_EY_OBJECT_H_BANNER_FEL_REAVER_LEFT = 15,
|
||||
BG_EY_OBJECT_H_BANNER_FEL_REAVER_RIGHT = 16,
|
||||
BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER = 17,
|
||||
BG_EY_OBJECT_H_BANNER_BLOOD_ELF_LEFT = 18,
|
||||
BG_EY_OBJECT_H_BANNER_BLOOD_ELF_RIGHT = 19,
|
||||
BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER = 20,
|
||||
BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_LEFT = 21,
|
||||
BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_RIGHT = 22,
|
||||
BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER = 23,
|
||||
BG_EY_OBJECT_H_BANNER_MAGE_TOWER_LEFT = 24,
|
||||
BG_EY_OBJECT_H_BANNER_MAGE_TOWER_RIGHT = 25,
|
||||
BG_EY_OBJECT_N_BANNER_FEL_REAVER_CENTER = 26,
|
||||
BG_EY_OBJECT_N_BANNER_FEL_REAVER_LEFT = 27,
|
||||
BG_EY_OBJECT_N_BANNER_FEL_REAVER_RIGHT = 28,
|
||||
BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER = 29,
|
||||
BG_EY_OBJECT_N_BANNER_BLOOD_ELF_LEFT = 30,
|
||||
BG_EY_OBJECT_N_BANNER_BLOOD_ELF_RIGHT = 31,
|
||||
BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER = 32,
|
||||
BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_LEFT = 33,
|
||||
BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_RIGHT = 34,
|
||||
BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER = 35,
|
||||
BG_EY_OBJECT_N_BANNER_MAGE_TOWER_LEFT = 36,
|
||||
BG_EY_OBJECT_N_BANNER_MAGE_TOWER_RIGHT = 37,
|
||||
BG_EY_OBJECT_TOWER_CAP_FEL_REAVER = 38,
|
||||
BG_EY_OBJECT_TOWER_CAP_BLOOD_ELF = 39,
|
||||
BG_EY_OBJECT_TOWER_CAP_DRAENEI_RUINS = 40,
|
||||
BG_EY_OBJECT_TOWER_CAP_MAGE_TOWER = 41,
|
||||
BG_EY_OBJECT_FLAG_NETHERSTORM = 42,
|
||||
BG_EY_OBJECT_FLAG_FEL_REAVER = 43,
|
||||
BG_EY_OBJECT_FLAG_BLOOD_ELF = 44,
|
||||
BG_EY_OBJECT_FLAG_DRAENEI_RUINS = 45,
|
||||
BG_EY_OBJECT_FLAG_MAGE_TOWER = 46,
|
||||
//buffs
|
||||
BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER = 47,
|
||||
BG_EY_OBJECT_REGENBUFF_FEL_REAVER = 48,
|
||||
BG_EY_OBJECT_BERSERKBUFF_FEL_REAVER = 49,
|
||||
BG_EY_OBJECT_SPEEDBUFF_BLOOD_ELF = 50,
|
||||
BG_EY_OBJECT_REGENBUFF_BLOOD_ELF = 51,
|
||||
BG_EY_OBJECT_BERSERKBUFF_BLOOD_ELF = 52,
|
||||
BG_EY_OBJECT_SPEEDBUFF_DRAENEI_RUINS = 53,
|
||||
BG_EY_OBJECT_REGENBUFF_DRAENEI_RUINS = 54,
|
||||
BG_EY_OBJECT_BERSERKBUFF_DRAENEI_RUINS = 55,
|
||||
BG_EY_OBJECT_SPEEDBUFF_MAGE_TOWER = 56,
|
||||
BG_EY_OBJECT_REGENBUFF_MAGE_TOWER = 57,
|
||||
BG_EY_OBJECT_BERSERKBUFF_MAGE_TOWER = 58,
|
||||
BG_EY_OBJECT_MAX = 59
|
||||
};
|
||||
|
||||
enum BG_EY_Score
|
||||
{
|
||||
BG_EY_WARNING_NEAR_VICTORY_SCORE = 1400,
|
||||
BG_EY_MAX_TEAM_SCORE = 1600,
|
||||
|
||||
BG_EY_HONOR_TICK_WEEKEND = 160,
|
||||
BG_EY_HONOR_TICK_NORMAL = 260,
|
||||
|
||||
BG_EY_EVENT_START_BATTLE = 13180, // Achievement: Flurry
|
||||
BG_EY_OBJECTIVE_CAPTURE_FLAG = 183
|
||||
};
|
||||
|
||||
enum BG_EY_FlagState
|
||||
{
|
||||
BG_EY_FLAG_STATE_ON_BASE = 1,
|
||||
BG_EY_FLAG_STATE_ON_PLAYER = 2,
|
||||
BG_EY_FLAG_STATE_ON_GROUND = 3
|
||||
};
|
||||
|
||||
struct BattlegroundEYPointIconsStruct
|
||||
{
|
||||
BattlegroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex)
|
||||
: WorldStateControlIndex(_WorldStateControlIndex), WorldStateAllianceControlledIndex(_WorldStateAllianceControlledIndex), WorldStateHordeControlledIndex(_WorldStateHordeControlledIndex) {}
|
||||
uint32 WorldStateControlIndex;
|
||||
uint32 WorldStateAllianceControlledIndex;
|
||||
uint32 WorldStateHordeControlledIndex;
|
||||
};
|
||||
|
||||
const float BG_EY_TriggerPositions[EY_POINTS_MAX][4] =
|
||||
{
|
||||
{2044.28f, 1729.68f, 1189.96f, 0.017453f}, // FEL_REAVER center
|
||||
{2048.83f, 1393.65f, 1194.49f, 0.20944f}, // BLOOD_ELF center
|
||||
{2286.56f, 1402.36f, 1197.11f, 3.72381f}, // DRAENEI_RUINS center
|
||||
{2284.48f, 1731.23f, 1189.99f, 2.89725f} // MAGE_TOWER center
|
||||
};
|
||||
|
||||
struct BattlegroundEYLosingPointStruct
|
||||
{
|
||||
BattlegroundEYLosingPointStruct(uint32 _SpawnNeutralObjectType, uint32 _DespawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _DespawnObjectTypeHorde, uint32 _MessageIdHorde)
|
||||
: SpawnNeutralObjectType(_SpawnNeutralObjectType),
|
||||
DespawnObjectTypeAlliance(_DespawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance),
|
||||
DespawnObjectTypeHorde(_DespawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde)
|
||||
{}
|
||||
|
||||
uint32 SpawnNeutralObjectType;
|
||||
uint32 DespawnObjectTypeAlliance;
|
||||
uint32 MessageIdAlliance;
|
||||
uint32 DespawnObjectTypeHorde;
|
||||
uint32 MessageIdHorde;
|
||||
};
|
||||
|
||||
struct BattlegroundEYCapturingPointStruct
|
||||
{
|
||||
BattlegroundEYCapturingPointStruct(uint32 _DespawnNeutralObjectType, uint32 _SpawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _SpawnObjectTypeHorde, uint32 _MessageIdHorde, uint32 _GraveYardId)
|
||||
: DespawnNeutralObjectType(_DespawnNeutralObjectType),
|
||||
SpawnObjectTypeAlliance(_SpawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance),
|
||||
SpawnObjectTypeHorde(_SpawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde),
|
||||
GraveYardId(_GraveYardId)
|
||||
{}
|
||||
|
||||
uint32 DespawnNeutralObjectType;
|
||||
uint32 SpawnObjectTypeAlliance;
|
||||
uint32 MessageIdAlliance;
|
||||
uint32 SpawnObjectTypeHorde;
|
||||
uint32 MessageIdHorde;
|
||||
uint32 GraveYardId;
|
||||
};
|
||||
|
||||
const uint32 BG_EY_TickPoints[EY_POINTS_MAX] = {1, 2, 5, 10};
|
||||
const uint32 BG_EY_FlagPoints[EY_POINTS_MAX] = {75, 85, 100, 500};
|
||||
|
||||
//constant arrays:
|
||||
const BattlegroundEYPointIconsStruct m_PointsIconStruct[EY_POINTS_MAX] =
|
||||
{
|
||||
BattlegroundEYPointIconsStruct(FEL_REAVER_UNCONTROL, FEL_REAVER_ALLIANCE_CONTROL, FEL_REAVER_HORDE_CONTROL),
|
||||
BattlegroundEYPointIconsStruct(BLOOD_ELF_UNCONTROL, BLOOD_ELF_ALLIANCE_CONTROL, BLOOD_ELF_HORDE_CONTROL),
|
||||
BattlegroundEYPointIconsStruct(DRAENEI_RUINS_UNCONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL, DRAENEI_RUINS_HORDE_CONTROL),
|
||||
BattlegroundEYPointIconsStruct(MAGE_TOWER_UNCONTROL, MAGE_TOWER_ALLIANCE_CONTROL, MAGE_TOWER_HORDE_CONTROL)
|
||||
};
|
||||
|
||||
const BattlegroundEYLosingPointStruct m_LosingPointTypes[EY_POINTS_MAX] =
|
||||
{
|
||||
BattlegroundEYLosingPointStruct(BG_EY_OBJECT_N_BANNER_FEL_REAVER_CENTER, BG_EY_OBJECT_A_BANNER_FEL_REAVER_CENTER, LANG_BG_EY_HAS_LOST_A_F_RUINS, BG_EY_OBJECT_H_BANNER_FEL_REAVER_CENTER, LANG_BG_EY_HAS_LOST_H_F_RUINS),
|
||||
BattlegroundEYLosingPointStruct(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER, BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_LOST_A_B_TOWER, BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_LOST_H_B_TOWER),
|
||||
BattlegroundEYLosingPointStruct(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_LOST_A_D_RUINS, BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_LOST_H_D_RUINS),
|
||||
BattlegroundEYLosingPointStruct(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_LOST_A_M_TOWER, BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_LOST_H_M_TOWER)
|
||||
};
|
||||
|
||||
const BattlegroundEYCapturingPointStruct m_CapturingPointTypes[EY_POINTS_MAX] =
|
||||
{
|
||||
BattlegroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_FEL_REAVER_CENTER, BG_EY_OBJECT_A_BANNER_FEL_REAVER_CENTER, LANG_BG_EY_HAS_TAKEN_A_F_RUINS, BG_EY_OBJECT_H_BANNER_FEL_REAVER_CENTER, LANG_BG_EY_HAS_TAKEN_H_F_RUINS, BG_EY_GRAVEYARD_FEL_REAVER),
|
||||
BattlegroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_BLOOD_ELF_CENTER, BG_EY_OBJECT_A_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_TAKEN_A_B_TOWER, BG_EY_OBJECT_H_BANNER_BLOOD_ELF_CENTER, LANG_BG_EY_HAS_TAKEN_H_B_TOWER, BG_EY_GRAVEYARD_BLOOD_ELF),
|
||||
BattlegroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_TAKEN_A_D_RUINS, BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_TAKEN_H_D_RUINS, BG_EY_GRAVEYARD_DRAENEI_RUINS),
|
||||
BattlegroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_TAKEN_A_M_TOWER, BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_TAKEN_H_M_TOWER, BG_EY_GRAVEYARD_MAGE_TOWER)
|
||||
};
|
||||
|
||||
struct BattlegroundEYScore : public BattlegroundScore
|
||||
{
|
||||
BattlegroundEYScore(Player* player) : BattlegroundScore(player), FlagCaptures(0) { }
|
||||
~BattlegroundEYScore() { }
|
||||
uint32 FlagCaptures;
|
||||
};
|
||||
|
||||
class BattlegroundEY : public Battleground
|
||||
{
|
||||
public:
|
||||
BattlegroundEY();
|
||||
~BattlegroundEY();
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
void AddPlayer(Player* player);
|
||||
void StartingEventCloseDoors();
|
||||
void StartingEventOpenDoors();
|
||||
|
||||
/* BG Flags */
|
||||
uint64 GetFlagPickerGUID(TeamId /*teamId*/ = TEAM_NEUTRAL) const { return _flagKeeperGUID; }
|
||||
void SetFlagPicker(uint64 guid) { _flagKeeperGUID = guid; }
|
||||
uint8 GetFlagState() const { return _flagState; }
|
||||
void RespawnFlag();
|
||||
void RespawnFlagAfterDrop();
|
||||
|
||||
void RemovePlayer(Player* player);
|
||||
void HandleBuffUse(uint64 buff_guid);
|
||||
void HandleAreaTrigger(Player* player, uint32 trigger);
|
||||
void HandleKillPlayer(Player* player, Player* killer);
|
||||
WorldSafeLocsEntry const* GetClosestGraveyard(Player* player);
|
||||
bool SetupBattleground();
|
||||
void Init();
|
||||
void EndBattleground(TeamId winnerTeamId);
|
||||
void UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
void FillInitialWorldStates(WorldPacket& data);
|
||||
void SetDroppedFlagGUID(uint64 guid, TeamId /*teamId*/ = TEAM_NEUTRAL) { _droppedFlagGUID = guid; }
|
||||
uint64 GetDroppedFlagGUID() const { return _droppedFlagGUID; }
|
||||
|
||||
/* Battleground Events */
|
||||
void EventPlayerClickedOnFlag(Player* player, GameObject* gameObject);
|
||||
void EventPlayerDroppedFlag(Player* player);
|
||||
|
||||
/* achievement req. */
|
||||
bool AllNodesConrolledByTeam(TeamId teamId) const;
|
||||
TeamId GetPrematureWinner();
|
||||
|
||||
private:
|
||||
void PostUpdateImpl(uint32 diff);
|
||||
|
||||
void EventPlayerCapturedFlag(Player* Source, uint32 BgObjectType);
|
||||
void EventTeamLostPoint(TeamId teamId, uint32 point);
|
||||
void EventTeamCapturedPoint(TeamId teamId, uint32 point);
|
||||
void UpdatePointsCount();
|
||||
void UpdatePointsIcons(uint32 point);
|
||||
|
||||
/* Point status updating procedures */
|
||||
void UpdatePointsState();
|
||||
|
||||
/* Scorekeeping */
|
||||
void AddPoints(TeamId teamId, uint32 points);
|
||||
|
||||
struct CapturePointInfo
|
||||
{
|
||||
CapturePointInfo() : _ownerTeamId(TEAM_NEUTRAL), _barStatus(BG_EY_PROGRESS_BAR_STATE_MIDDLE), _areaTrigger(0)
|
||||
{
|
||||
_playersCount[TEAM_ALLIANCE] = 0;
|
||||
_playersCount[TEAM_HORDE] = 0;
|
||||
}
|
||||
|
||||
TeamId _ownerTeamId;
|
||||
uint32 _areaTrigger;
|
||||
int8 _barStatus;
|
||||
int8 _playersCount[BG_TEAMS_COUNT];
|
||||
|
||||
bool IsUnderControl(TeamId teamId) const { return _ownerTeamId == teamId; }
|
||||
bool IsUnderControl() const { return _ownerTeamId != TEAM_NEUTRAL; }
|
||||
bool IsUncontrolled() const { return _ownerTeamId == TEAM_NEUTRAL; }
|
||||
};
|
||||
|
||||
CapturePointInfo _capturePointInfo[EY_POINTS_MAX];
|
||||
EventMap _bgEvents;
|
||||
uint32 _honorTics;
|
||||
uint8 _ownedPointsCount[BG_TEAMS_COUNT];
|
||||
uint64 _flagKeeperGUID;
|
||||
uint64 _droppedFlagGUID;
|
||||
uint8 _flagState;
|
||||
uint32 _flagCapturedObject;
|
||||
};
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 "BattlegroundNA.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
BattlegroundNA::BattlegroundNA()
|
||||
{
|
||||
BgObjects.resize(BG_NA_OBJECT_MAX);
|
||||
|
||||
StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattlegroundNA::~BattlegroundNA()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattlegroundNA::StartingEventCloseDoors()
|
||||
{
|
||||
for (uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_4; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattlegroundNA::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
for (uint32 i = BG_NA_OBJECT_BUFF_1; i <= BG_NA_OBJECT_BUFF_2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
void BattlegroundNA::AddPlayer(Player* player)
|
||||
{
|
||||
Battleground::AddPlayer(player);
|
||||
PlayerScores[player->GetGUID()] = new BattlegroundScore(player);
|
||||
Battleground::UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattlegroundNA::RemovePlayer(Player* /*player*/)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
Battleground::UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattlegroundNA::HandleKillPlayer(Player* player, Player* killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!killer)
|
||||
{
|
||||
sLog->outError("BattlegroundNA: Killer player not found");
|
||||
return;
|
||||
}
|
||||
|
||||
Battleground::HandleKillPlayer(player, killer);
|
||||
|
||||
Battleground::UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattlegroundNA::HandlePlayerUnderMap(Player* player)
|
||||
{
|
||||
player->NearTeleportTo(4055.504395f, 2919.660645f, 13.611241f, player->GetOrientation());
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundNA::HandleAreaTrigger(Player* player, uint32 trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
switch (trigger)
|
||||
{
|
||||
case 4536: // buff trigger?
|
||||
case 4537: // buff trigger?
|
||||
break;
|
||||
// OUTSIDE OF ARENA, TELEPORT!
|
||||
case 4917:
|
||||
case 5006:
|
||||
case 5008:
|
||||
player->NearTeleportTo(4054.15f, 2923.7f, 13.4f, player->GetOrientation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundNA::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(0xa11) << uint32(1); // 9
|
||||
Battleground::UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattlegroundNA::Init()
|
||||
{
|
||||
//call parent's class reset
|
||||
Battleground::Init();
|
||||
}
|
||||
|
||||
bool BattlegroundNA::SetupBattleground()
|
||||
{
|
||||
// gates
|
||||
if (!AddObject(BG_NA_OBJECT_DOOR_1, BG_NA_OBJECT_TYPE_DOOR_1, 4031.854f, 2966.833f, 12.6462f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_2, BG_NA_OBJECT_TYPE_DOOR_2, 4081.179f, 2874.97f, 12.39171f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_3, BG_NA_OBJECT_TYPE_DOOR_3, 4023.709f, 2981.777f, 10.70117f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_4, BG_NA_OBJECT_TYPE_DOOR_4, 4090.064f, 2858.438f, 10.23631f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f, RESPAWN_IMMEDIATELY)
|
||||
// buffs
|
||||
|| !AddObject(BG_NA_OBJECT_BUFF_1, BG_NA_OBJECT_TYPE_BUFF_1, 4009.189941f, 2895.250000f, 13.052700f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120)
|
||||
|| !AddObject(BG_NA_OBJECT_BUFF_2, BG_NA_OBJECT_TYPE_BUFF_2, 4103.330078f, 2946.350098f, 13.051300f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120)
|
||||
// Arena Ready Marker
|
||||
|| !AddObject(BG_NA_OBJECT_READY_MARKER_1, ARENA_READY_MARKER_ENTRY, 4090.46f, 2875.43f, 12.16f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300)
|
||||
|| !AddObject(BG_NA_OBJECT_READY_MARKER_2, ARENA_READY_MARKER_ENTRY, 4022.82f, 2966.61f, 12.17f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300))
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundNA: Failed to spawn some object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 __BATTLEGROUNDNA_H
|
||||
#define __BATTLEGROUNDNA_H
|
||||
|
||||
#include "Battleground.h"
|
||||
|
||||
enum BattlegroundNAObjectTypes
|
||||
{
|
||||
BG_NA_OBJECT_DOOR_1 = 0,
|
||||
BG_NA_OBJECT_DOOR_2 = 1,
|
||||
BG_NA_OBJECT_DOOR_3 = 2,
|
||||
BG_NA_OBJECT_DOOR_4 = 3,
|
||||
BG_NA_OBJECT_BUFF_1 = 4,
|
||||
BG_NA_OBJECT_BUFF_2 = 5,
|
||||
BG_NA_OBJECT_READY_MARKER_1 = 6,
|
||||
BG_NA_OBJECT_READY_MARKER_2 = 7,
|
||||
BG_NA_OBJECT_MAX = 8
|
||||
};
|
||||
|
||||
enum BattlegroundNAObjects
|
||||
{
|
||||
BG_NA_OBJECT_TYPE_DOOR_1 = 183978,
|
||||
BG_NA_OBJECT_TYPE_DOOR_2 = 183980,
|
||||
BG_NA_OBJECT_TYPE_DOOR_3 = 183977,
|
||||
BG_NA_OBJECT_TYPE_DOOR_4 = 183979,
|
||||
BG_NA_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_NA_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
class BattlegroundNA : public Battleground
|
||||
{
|
||||
public:
|
||||
BattlegroundNA();
|
||||
~BattlegroundNA();
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
void AddPlayer(Player* player);
|
||||
void StartingEventCloseDoors();
|
||||
void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player* player);
|
||||
void HandleAreaTrigger(Player* player, uint32 trigger);
|
||||
bool SetupBattleground();
|
||||
void Init();
|
||||
void FillInitialWorldStates(WorldPacket &d);
|
||||
void HandleKillPlayer(Player* player, Player* killer);
|
||||
bool HandlePlayerUnderMap(Player* player);
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 "BattlegroundRL.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
BattlegroundRL::BattlegroundRL()
|
||||
{
|
||||
BgObjects.resize(BG_RL_OBJECT_MAX);
|
||||
|
||||
StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
//we must set messageIds
|
||||
StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
}
|
||||
|
||||
BattlegroundRL::~BattlegroundRL()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BattlegroundRL::StartingEventCloseDoors()
|
||||
{
|
||||
for (uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
void BattlegroundRL::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
for (uint32 i = BG_RL_OBJECT_BUFF_1; i <= BG_RL_OBJECT_BUFF_2; ++i)
|
||||
SpawnBGObject(i, 60);
|
||||
}
|
||||
|
||||
void BattlegroundRL::AddPlayer(Player* player)
|
||||
{
|
||||
Battleground::AddPlayer(player);
|
||||
PlayerScores[player->GetGUID()] = new BattlegroundScore(player);
|
||||
Battleground::UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattlegroundRL::RemovePlayer(Player* /*player*/)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattlegroundRL::HandleKillPlayer(Player* player, Player* killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!killer)
|
||||
{
|
||||
sLog->outError("Killer player not found");
|
||||
return;
|
||||
}
|
||||
|
||||
Battleground::HandleKillPlayer(player, killer);
|
||||
|
||||
Battleground::UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattlegroundRL::HandlePlayerUnderMap(Player* player)
|
||||
{
|
||||
player->NearTeleportTo(1285.810547f, 1667.896851f, 39.957642f, player->GetOrientation());
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundRL::HandleAreaTrigger(Player* player, uint32 trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
switch (trigger)
|
||||
{
|
||||
case 4696: // buff trigger?
|
||||
case 4697: // buff trigger?
|
||||
break;
|
||||
// OUTSIDE OF ARENA, TELEPORT!
|
||||
case 4927:
|
||||
case 4928:
|
||||
player->NearTeleportTo(1230.77f, 1662.42f, 34.56f, 0.0f);
|
||||
break;
|
||||
case 4929:
|
||||
case 4930:
|
||||
player->NearTeleportTo(1341.16f, 1673.52f, 34.43f, 3.5f);
|
||||
break;
|
||||
case 4931:
|
||||
player->NearTeleportTo(1294.74f, 1584.5f, 31.62f, 1.66f);
|
||||
break;
|
||||
case 4932:
|
||||
player->NearTeleportTo(1277.5f, 1751.07f, 31.61f, 4.7f);
|
||||
break;
|
||||
case 4933:
|
||||
player->NearTeleportTo(1269.14f, 1713.85f, 34.46f, 5.23f);
|
||||
break;
|
||||
case 4934:
|
||||
player->NearTeleportTo(1298.14f, 1713.8f, 33.58f, 4.55f);
|
||||
break;
|
||||
case 4935:
|
||||
player->NearTeleportTo(1306.32f, 1620.75f, 34.25f, 1.97f);
|
||||
break;
|
||||
case 4936:
|
||||
player->NearTeleportTo(1277.97f, 1615.51f, 34.56f, 1.15f);
|
||||
break;
|
||||
case 4941: // under arena +10
|
||||
case 5041: // under arena -10
|
||||
case 5042: // under arena -30
|
||||
player->NearTeleportTo(1285.810547f, 1667.896851f, 39.957642f, player->GetOrientation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundRL::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(0xbba) << uint32(1); // 9
|
||||
Battleground::UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattlegroundRL::Init()
|
||||
{
|
||||
//call parent's reset
|
||||
Battleground::Init();
|
||||
}
|
||||
|
||||
bool BattlegroundRL::SetupBattleground()
|
||||
{
|
||||
// gates
|
||||
if (!AddObject(BG_RL_OBJECT_DOOR_1, BG_RL_OBJECT_TYPE_DOOR_1, 1293.561f, 1601.938f, 31.60557f, -1.457349f, 0, 0, -0.6658813f, 0.7460576f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RL_OBJECT_DOOR_2, BG_RL_OBJECT_TYPE_DOOR_2, 1278.648f, 1730.557f, 31.60557f, 1.684245f, 0, 0, 0.7460582f, 0.6658807f, RESPAWN_IMMEDIATELY)
|
||||
// buffs
|
||||
|| !AddObject(BG_RL_OBJECT_BUFF_1, BG_RL_OBJECT_TYPE_BUFF_1, 1328.719971f, 1632.719971f, 36.730400f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f, 120)
|
||||
|| !AddObject(BG_RL_OBJECT_BUFF_2, BG_RL_OBJECT_TYPE_BUFF_2, 1243.300049f, 1699.170044f, 34.872601f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f, 120)
|
||||
// Arena Ready Marker
|
||||
|| !AddObject(BG_RL_OBJECT_READY_MARKER_1, ARENA_READY_MARKER_ENTRY, 1298.61f, 1598.59f, 31.62f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300)
|
||||
|| !AddObject(BG_RL_OBJECT_READY_MARKER_2, ARENA_READY_MARKER_ENTRY, 1273.71f, 1734.05f, 31.61f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300))
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundRL: Failed to spawn some object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 __BATTLEGROUNDRL_H
|
||||
#define __BATTLEGROUNDRL_H
|
||||
|
||||
#include "Battleground.h"
|
||||
|
||||
enum BattlegroundRLObjectTypes
|
||||
{
|
||||
BG_RL_OBJECT_DOOR_1 = 0,
|
||||
BG_RL_OBJECT_DOOR_2 = 1,
|
||||
BG_RL_OBJECT_BUFF_1 = 2,
|
||||
BG_RL_OBJECT_BUFF_2 = 3,
|
||||
BG_RL_OBJECT_READY_MARKER_1 = 4,
|
||||
BG_RL_OBJECT_READY_MARKER_2 = 5,
|
||||
BG_RL_OBJECT_MAX = 6
|
||||
};
|
||||
|
||||
enum BattlegroundRLObjects
|
||||
{
|
||||
BG_RL_OBJECT_TYPE_DOOR_1 = 185918,
|
||||
BG_RL_OBJECT_TYPE_DOOR_2 = 185917,
|
||||
BG_RL_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_RL_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
class BattlegroundRL : public Battleground
|
||||
{
|
||||
public:
|
||||
BattlegroundRL();
|
||||
~BattlegroundRL();
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
void AddPlayer(Player* player);
|
||||
void Init();
|
||||
void FillInitialWorldStates(WorldPacket &d);
|
||||
void StartingEventCloseDoors();
|
||||
void StartingEventOpenDoors();
|
||||
|
||||
void RemovePlayer(Player* player);
|
||||
void HandleAreaTrigger(Player* player, uint32 trigger);
|
||||
bool SetupBattleground();
|
||||
void HandleKillPlayer(Player* player, Player* killer);
|
||||
bool HandlePlayerUnderMap(Player* player);
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 "Battleground.h"
|
||||
#include "BattlegroundRV.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Language.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "GameObject.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Pet.h"
|
||||
|
||||
BattlegroundRV::BattlegroundRV()
|
||||
{
|
||||
BgObjects.resize(BG_RV_OBJECT_MAX);
|
||||
|
||||
StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
|
||||
StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
|
||||
StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
|
||||
StartDelayTimes[BG_STARTING_EVENT_FOURTH] = BG_START_DELAY_NONE;
|
||||
StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_ARENA_ONE_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_ARENA_THIRTY_SECONDS;
|
||||
StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
|
||||
StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
|
||||
|
||||
CheckPlayersTimer = 0;
|
||||
}
|
||||
|
||||
BattlegroundRV::~BattlegroundRV() { }
|
||||
|
||||
void BattlegroundRV::TeleportUnitToNewZ(Unit* unit, float newZ, bool casting)
|
||||
{
|
||||
if (!unit->IsAlive())
|
||||
return;
|
||||
unit->NearTeleportTo(unit->GetPositionX(), unit->GetPositionY(), newZ, unit->GetOrientation(), casting);
|
||||
unit->m_positionZ = newZ;
|
||||
}
|
||||
|
||||
void BattlegroundRV::CheckPositionForUnit(Unit* unit)
|
||||
{
|
||||
// get height at current pos, if something is wrong (below or high above) - teleport
|
||||
if (!unit->IsFalling() && unit->IsAlive())
|
||||
{
|
||||
float groundZ_vmap = unit->GetMap()->GetHeight(unit->GetPositionX(), unit->GetPositionY(), 37.0f, true, 50.0f);
|
||||
float groundZ_dyntree = unit->GetMap()->GetDynamicMapTree().getHeight(unit->GetPositionX(), unit->GetPositionY(), 37.0f, 50.0f, unit->GetPhaseMask());
|
||||
if (groundZ_vmap > 28.0f && groundZ_vmap < 29.0f || groundZ_dyntree > 28.0f && groundZ_dyntree < 37.0f)
|
||||
{
|
||||
float groundZ = std::max<float>(groundZ_vmap, groundZ_dyntree);
|
||||
if (unit->GetPositionZ() < groundZ - 0.2f || unit->GetPositionZ() > groundZ + 3.5f)
|
||||
TeleportUnitToNewZ(unit, groundZ+1.0f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundRV::PostUpdateImpl(uint32 diff)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (getTimer() < diff)
|
||||
{
|
||||
switch (getState())
|
||||
{
|
||||
case BG_RV_STATE_OPEN_FENCES:
|
||||
for (uint8 i = BG_RV_OBJECT_FIRE_1; i <= BG_RV_OBJECT_FIREDOOR_2; ++i)
|
||||
DoorOpen(i);
|
||||
setTimer(BG_RV_CLOSE_FIRE_TIMER);
|
||||
setState(BG_RV_STATE_CLOSE_FIRE);
|
||||
|
||||
for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
if (Player* player = itr->second)
|
||||
{
|
||||
// Demonic Circle Summon
|
||||
if (GameObject* gObj = player->GetGameObject(48018))
|
||||
{
|
||||
gObj->Relocate(gObj->GetPositionX(), gObj->GetPositionY(), 28.28f);
|
||||
gObj->UpdateObjectVisibility(true);
|
||||
}
|
||||
|
||||
if (player->GetPositionZ() < 27.0f)
|
||||
TeleportUnitToNewZ(player, 28.28f, true);
|
||||
|
||||
for (uint8 i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i)
|
||||
if (player->m_SummonSlot[i])
|
||||
if (Creature* totem = GetBgMap()->GetCreature(player->m_SummonSlot[i]))
|
||||
if (totem->GetPositionZ() < 28.0f)
|
||||
TeleportUnitToNewZ(totem, 28.28f, true);
|
||||
|
||||
for (Unit::ControlSet::const_iterator itr = player->m_Controlled.begin(); itr != player->m_Controlled.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->GetPositionZ() < 28.0f)
|
||||
TeleportUnitToNewZ((*itr), 28.28f, true);
|
||||
|
||||
// Xinef: override stay position
|
||||
if (CharmInfo* charmInfo = (*itr)->GetCharmInfo())
|
||||
if (charmInfo->IsAtStay())
|
||||
{
|
||||
(*itr)->StopMovingOnCurrentPos();
|
||||
charmInfo->SaveStayPosition(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fix ground on elevators (so aoe spells can be casted there)
|
||||
{
|
||||
uint32 objects[2] = {BG_RV_OBJECT_ELEVATOR_1, BG_RV_OBJECT_ELEVATOR_2};
|
||||
for (uint8 i=0; i<2; ++i)
|
||||
if (GameObject* go = GetBGObject(objects[i]))
|
||||
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_TRANSPORT);
|
||||
}
|
||||
break;
|
||||
case BG_RV_STATE_CLOSE_FIRE:
|
||||
for (uint8 i = BG_RV_OBJECT_FIRE_1; i <= BG_RV_OBJECT_FIREDOOR_2; ++i)
|
||||
DoorClose(i);
|
||||
// Fire got closed after five seconds, leaves twenty seconds before toggling pillars
|
||||
setTimer(BG_RV_FIRE_TO_PILLAR_TIMER);
|
||||
setState(BG_RV_STATE_SWITCH_PILLARS);
|
||||
break;
|
||||
case BG_RV_STATE_SWITCH_PILLARS:
|
||||
UpdatePillars();
|
||||
setTimer(BG_RV_PILLAR_SWITCH_TIMER);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
setTimer(getTimer() - diff);
|
||||
|
||||
if (getState() == BG_RV_STATE_OPEN_FENCES)
|
||||
return;
|
||||
|
||||
if (CheckPlayersTimer <= diff)
|
||||
{
|
||||
CheckPlayersTimer = 0;
|
||||
for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
CheckPositionForUnit(itr->second);
|
||||
|
||||
// maybe for pets and m_Controlled also, but not really necessary
|
||||
}
|
||||
else
|
||||
CheckPlayersTimer -= diff;
|
||||
}
|
||||
|
||||
void BattlegroundRV::StartingEventCloseDoors()
|
||||
{
|
||||
}
|
||||
|
||||
void BattlegroundRV::StartingEventOpenDoors()
|
||||
{
|
||||
for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
itr->second->SetPhaseMask(1, true);
|
||||
|
||||
// Buff respawn
|
||||
SpawnBGObject(BG_RV_OBJECT_BUFF_1, 90);
|
||||
SpawnBGObject(BG_RV_OBJECT_BUFF_2, 90);
|
||||
|
||||
// Elevators
|
||||
DoorOpen(BG_RV_OBJECT_ELEVATOR_1);
|
||||
DoorOpen(BG_RV_OBJECT_ELEVATOR_2);
|
||||
|
||||
setState(BG_RV_STATE_OPEN_FENCES);
|
||||
setTimer(BG_RV_FIRST_TIMER);
|
||||
}
|
||||
|
||||
void BattlegroundRV::AddPlayer(Player* player)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_JOIN && player->GetBgTeamId() == TEAM_HORDE)
|
||||
player->SetPhaseMask(2, true);
|
||||
|
||||
Battleground::AddPlayer(player);
|
||||
PlayerScores[player->GetGUID()] = new BattlegroundScore(player);
|
||||
BattlegroundRV::UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattlegroundRV::RemovePlayer(Player* player)
|
||||
{
|
||||
if (GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
if (GetStatus() == STATUS_WAIT_JOIN)
|
||||
player->SetPhaseMask(1, true);
|
||||
|
||||
BattlegroundRV::UpdateArenaWorldState();
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
void BattlegroundRV::HandleKillPlayer(Player* player, Player* killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
if (!killer)
|
||||
return;
|
||||
|
||||
Battleground::HandleKillPlayer(player, killer);
|
||||
BattlegroundRV::UpdateArenaWorldState();
|
||||
|
||||
CheckArenaWinConditions();
|
||||
}
|
||||
|
||||
bool BattlegroundRV::HandlePlayerUnderMap(Player* player)
|
||||
{
|
||||
player->NearTeleportTo(763.5f, -284, 28.276f, 2.422f);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundRV::HandleAreaTrigger(Player* player, uint32 trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS || getState() == BG_RV_STATE_OPEN_FENCES /*during elevator rising it's possible to jump and cause areatrigger*/)
|
||||
return;
|
||||
|
||||
switch (trigger)
|
||||
{
|
||||
// fire was removed in 3.2.0
|
||||
case 5473:
|
||||
case 5474:
|
||||
break;
|
||||
// OUTSIDE OF ARENA, TELEPORT!
|
||||
case 5224:
|
||||
player->NearTeleportTo(765.0f, -294.0f, 28.3f, player->GetOrientation());
|
||||
break;
|
||||
case 5226:
|
||||
player->NearTeleportTo(765.0f, -272.0f, 28.3f, player->GetOrientation());
|
||||
break;
|
||||
case 5447:
|
||||
player->NearTeleportTo(763.5f, -284, 28.276f, 2.422f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundRV::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(BG_RV_WORLD_STATE) << uint32(1);
|
||||
BattlegroundRV::UpdateArenaWorldState();
|
||||
}
|
||||
|
||||
void BattlegroundRV::UpdateArenaWorldState()
|
||||
{
|
||||
UpdateWorldState(BG_RV_WORLD_STATE_A, GetAlivePlayersCountByTeam(TEAM_ALLIANCE));
|
||||
UpdateWorldState(BG_RV_WORLD_STATE_H, GetAlivePlayersCountByTeam(TEAM_HORDE));
|
||||
}
|
||||
|
||||
void BattlegroundRV::Init()
|
||||
{
|
||||
//call parent's class reset
|
||||
Battleground::Init();
|
||||
}
|
||||
|
||||
bool BattlegroundRV::SetupBattleground()
|
||||
{
|
||||
// elevators
|
||||
if (!AddObject(BG_RV_OBJECT_ELEVATOR_1, BG_RV_OBJECT_TYPE_ELEVATOR_1, 763.536377f, -294.535767f, 0.505383f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_ELEVATOR_2, BG_RV_OBJECT_TYPE_ELEVATOR_2, 763.506348f, -273.873352f, 0.505383f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// buffs
|
||||
|| !AddObject(BG_RV_OBJECT_BUFF_1, BG_RV_OBJECT_TYPE_BUFF_1, 735.551819f, -284.794678f, 28.276682f, 0.034906f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_BUFF_2, BG_RV_OBJECT_TYPE_BUFF_2, 791.224487f, -284.794464f, 28.276682f, 2.600535f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// fire
|
||||
|| !AddObject(BG_RV_OBJECT_FIRE_1, BG_RV_OBJECT_TYPE_FIRE_1, 743.543457f, -283.799469f, 28.286655f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_FIRE_2, BG_RV_OBJECT_TYPE_FIRE_2, 782.971802f, -283.799469f, 28.286655f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_FIREDOOR_1, BG_RV_OBJECT_TYPE_FIREDOOR_1, 743.711060f, -284.099609f, 27.542587f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_FIREDOOR_2, BG_RV_OBJECT_TYPE_FIREDOOR_2, 783.221252f, -284.133362f, 27.535686f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// Gear
|
||||
|| !AddObject(BG_RV_OBJECT_GEAR_1, BG_RV_OBJECT_TYPE_GEAR_1, 763.664551f, -261.872986f, 26.686588f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_GEAR_2, BG_RV_OBJECT_TYPE_GEAR_2, 763.578979f, -306.146149f, 26.665222f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// Pulley
|
||||
|| !AddObject(BG_RV_OBJECT_PULLEY_1, BG_RV_OBJECT_TYPE_PULLEY_1, 700.722290f, -283.990662f, 39.517582f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PULLEY_2, BG_RV_OBJECT_TYPE_PULLEY_2, 826.303833f, -283.996429f, 39.517582f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
// Pilars
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_1, BG_RV_OBJECT_TYPE_PILAR_1, 763.632385f, -306.162384f, 25.909504f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_2, BG_RV_OBJECT_TYPE_PILAR_2, 723.644287f, -284.493256f, 24.648525f, 3.141593f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_3, BG_RV_OBJECT_TYPE_PILAR_3, 763.611145f, -261.856750f, 25.909504f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RV_OBJECT_PILAR_4, BG_RV_OBJECT_TYPE_PILAR_4, 802.211609f, -284.493256f, 24.648525f, 0.000000f, 0, 0, 0, RESPAWN_IMMEDIATELY)
|
||||
|
||||
// Arena Ready Marker
|
||||
|| !AddObject(BG_RV_OBJECT_READY_MARKER_1, ARENA_READY_MARKER_ENTRY, 769.93f, -301.04f, 2.80f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300)
|
||||
|| !AddObject(BG_RV_OBJECT_READY_MARKER_2, ARENA_READY_MARKER_ENTRY, 757.02f, -267.30f, 2.80f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 300)
|
||||
)
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundRV: Failed to spawn some object!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint8 i=0; i<BG_RV_OBJECT_MAX; ++i)
|
||||
if (GameObject* go = GetBGObject(i))
|
||||
go->SetPhaseMask(3, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundRV::UpdatePillars()
|
||||
{
|
||||
GameObject* test = GetBgMap()->GetGameObject(BgObjects[BG_RV_OBJECT_PILAR_1]);
|
||||
if (!test)
|
||||
return;
|
||||
|
||||
if (test->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_GEAR_2; ++i)
|
||||
if (GameObject* go = GetBgMap()->GetGameObject(BgObjects[i]))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
for (uint8 i = BG_RV_OBJECT_PILAR_2; i <= BG_RV_OBJECT_PULLEY_2; ++i)
|
||||
if (GameObject* go = GetBgMap()->GetGameObject(BgObjects[i]))
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_GEAR_2; ++i)
|
||||
if (GameObject* go = GetBgMap()->GetGameObject(BgObjects[i]))
|
||||
go->SetGoState(GO_STATE_READY);
|
||||
for (uint8 i = BG_RV_OBJECT_PILAR_2; i <= BG_RV_OBJECT_PULLEY_2; ++i)
|
||||
if (GameObject* go = GetBgMap()->GetGameObject(BgObjects[i]))
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 BattlegroundRV::GetPillarIdForPos(Position* p)
|
||||
{
|
||||
float range = 1.75f;
|
||||
if (p->GetExactDist2d(763.632385f, -306.162384f) < range)
|
||||
return BG_RV_OBJECT_PILAR_1;
|
||||
if (p->GetExactDist2d(723.644287f, -284.493256f) < 2.0f*range)
|
||||
return BG_RV_OBJECT_PILAR_2;
|
||||
if (p->GetExactDist2d(763.611145f, -261.856750f) < range)
|
||||
return BG_RV_OBJECT_PILAR_3;
|
||||
if (p->GetExactDist2d(802.211609f, -284.493256f) < 2.0f*range)
|
||||
return BG_RV_OBJECT_PILAR_4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
GameObject* BattlegroundRV::GetPillarAtPosition(Position* p)
|
||||
{
|
||||
uint32 pillar = GetPillarIdForPos(p);
|
||||
if (!pillar)
|
||||
return NULL;
|
||||
return GetBgMap()->GetGameObject(BgObjects[pillar]);
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 __BATTLEGROUNDRV_H
|
||||
#define __BATTLEGROUNDRV_H
|
||||
|
||||
#include "Battleground.h"
|
||||
|
||||
enum BattlegroundRVObjectTypes
|
||||
{
|
||||
BG_RV_OBJECT_BUFF_1,
|
||||
BG_RV_OBJECT_BUFF_2,
|
||||
BG_RV_OBJECT_FIRE_1,
|
||||
BG_RV_OBJECT_FIRE_2,
|
||||
BG_RV_OBJECT_FIREDOOR_1,
|
||||
BG_RV_OBJECT_FIREDOOR_2,
|
||||
|
||||
BG_RV_OBJECT_PILAR_1,
|
||||
BG_RV_OBJECT_PILAR_3,
|
||||
BG_RV_OBJECT_GEAR_1,
|
||||
BG_RV_OBJECT_GEAR_2,
|
||||
|
||||
BG_RV_OBJECT_PILAR_2,
|
||||
BG_RV_OBJECT_PILAR_4,
|
||||
BG_RV_OBJECT_PULLEY_1,
|
||||
BG_RV_OBJECT_PULLEY_2,
|
||||
|
||||
BG_RV_OBJECT_ELEVATOR_1,
|
||||
BG_RV_OBJECT_ELEVATOR_2,
|
||||
|
||||
BG_RV_OBJECT_READY_MARKER_1,
|
||||
BG_RV_OBJECT_READY_MARKER_2,
|
||||
|
||||
BG_RV_OBJECT_MAX,
|
||||
};
|
||||
|
||||
enum BattlegroundRVObjects
|
||||
{
|
||||
BG_RV_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_RV_OBJECT_TYPE_BUFF_2 = 184664,
|
||||
BG_RV_OBJECT_TYPE_FIRE_1 = 192704,
|
||||
BG_RV_OBJECT_TYPE_FIRE_2 = 192705,
|
||||
|
||||
BG_RV_OBJECT_TYPE_FIREDOOR_2 = 192387,
|
||||
BG_RV_OBJECT_TYPE_FIREDOOR_1 = 192388,
|
||||
BG_RV_OBJECT_TYPE_PULLEY_1 = 192389,
|
||||
BG_RV_OBJECT_TYPE_PULLEY_2 = 192390,
|
||||
BG_RV_OBJECT_TYPE_GEAR_1 = 192393,
|
||||
BG_RV_OBJECT_TYPE_GEAR_2 = 192394,
|
||||
|
||||
BG_RV_OBJECT_TYPE_ELEVATOR_1 = 194582,
|
||||
BG_RV_OBJECT_TYPE_ELEVATOR_2 = 194586,
|
||||
|
||||
BG_RV_OBJECT_TYPE_PILAR_1 = 194583, // axe
|
||||
BG_RV_OBJECT_TYPE_PILAR_2 = 194584, // arena
|
||||
BG_RV_OBJECT_TYPE_PILAR_3 = 194585, // lightning
|
||||
BG_RV_OBJECT_TYPE_PILAR_4 = 194587, // ivory
|
||||
};
|
||||
|
||||
enum BattlegroundRVData
|
||||
{
|
||||
BG_RV_STATE_OPEN_FENCES,
|
||||
BG_RV_STATE_SWITCH_PILLARS,
|
||||
BG_RV_STATE_CLOSE_FIRE,
|
||||
|
||||
BG_RV_PILLAR_SWITCH_TIMER = 25000,
|
||||
BG_RV_FIRE_TO_PILLAR_TIMER = 20000,
|
||||
BG_RV_CLOSE_FIRE_TIMER = 5000,
|
||||
BG_RV_FIRST_TIMER = 20500, // elevators rise in 20133ms
|
||||
BG_RV_WORLD_STATE_A = 0xe11,
|
||||
BG_RV_WORLD_STATE_H = 0xe10,
|
||||
BG_RV_WORLD_STATE = 0xe1a,
|
||||
};
|
||||
|
||||
class BattlegroundRV : public Battleground
|
||||
{
|
||||
public:
|
||||
BattlegroundRV();
|
||||
~BattlegroundRV();
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
void AddPlayer(Player* player);
|
||||
void RemovePlayer(Player* player);
|
||||
void StartingEventCloseDoors();
|
||||
void StartingEventOpenDoors();
|
||||
void Init();
|
||||
void FillInitialWorldStates(WorldPacket &d);
|
||||
void UpdateArenaWorldState();
|
||||
void HandleAreaTrigger(Player* player, uint32 trigger);
|
||||
bool SetupBattleground();
|
||||
void HandleKillPlayer(Player* player, Player* killer);
|
||||
bool HandlePlayerUnderMap(Player* player);
|
||||
|
||||
GameObject* GetPillarAtPosition(Position* p);
|
||||
|
||||
private:
|
||||
uint32 Timer;
|
||||
uint32 State;
|
||||
uint16 CheckPlayersTimer;
|
||||
|
||||
void PostUpdateImpl(uint32 diff);
|
||||
|
||||
protected:
|
||||
uint32 getTimer() { return Timer; }
|
||||
void setTimer(uint32 timer) { Timer = timer; }
|
||||
uint32 getState() { return State; };
|
||||
void setState(uint32 state) { State = state; }
|
||||
|
||||
void TeleportUnitToNewZ(Unit* unit, float newZ, bool casting);
|
||||
void CheckPositionForUnit(Unit* unit);
|
||||
void UpdatePillars();
|
||||
uint32 GetPillarIdForPos(Position* p);
|
||||
};
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,606 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 __BATTLEGROUNDSA_H
|
||||
#define __BATTLEGROUNDSA_H
|
||||
|
||||
#include "Battleground.h"
|
||||
|
||||
struct BattlegroundSAScore : public BattlegroundScore
|
||||
{
|
||||
BattlegroundSAScore(Player* player) : BattlegroundScore(player), demolishers_destroyed(0), gates_destroyed(0) { }
|
||||
~BattlegroundSAScore() { }
|
||||
uint8 demolishers_destroyed;
|
||||
uint8 gates_destroyed;
|
||||
};
|
||||
|
||||
#define BG_SA_FLAG_AMOUNT 3
|
||||
#define BG_SA_DEMOLISHER_AMOUNT 4
|
||||
#define SPELL_SA_END_OF_ROUND 52459
|
||||
|
||||
enum BG_SA_Status
|
||||
{
|
||||
BG_SA_NOTSTARTED = 0,
|
||||
BG_SA_WARMUP,
|
||||
BG_SA_ROUND_ONE,
|
||||
BG_SA_SECOND_WARMUP,
|
||||
BG_SA_ROUND_TWO,
|
||||
BG_SA_BONUS_ROUND
|
||||
};
|
||||
|
||||
enum BG_SA_GateState
|
||||
{
|
||||
BG_SA_GATE_OK = 1,
|
||||
BG_SA_GATE_DAMAGED = 2,
|
||||
BG_SA_GATE_DESTROYED = 3
|
||||
};
|
||||
|
||||
enum BG_SA_Timers
|
||||
{
|
||||
BG_SA_BOAT_START = 60 * IN_MILLISECONDS,
|
||||
BG_SA_WARMUPLENGTH = 120 * IN_MILLISECONDS,
|
||||
BG_SA_ROUNDLENGTH = 600 * IN_MILLISECONDS
|
||||
};
|
||||
|
||||
enum BG_SA_WorldStates
|
||||
{
|
||||
BG_SA_TIMER_MINS = 3559,
|
||||
BG_SA_TIMER_SEC_TENS = 3560,
|
||||
BG_SA_TIMER_SEC_DECS = 3561,
|
||||
BG_SA_ALLY_ATTACKS = 4352,
|
||||
BG_SA_HORDE_ATTACKS = 4353,
|
||||
BG_SA_PURPLE_GATEWS = 3614,
|
||||
BG_SA_RED_GATEWS = 3617,
|
||||
BG_SA_BLUE_GATEWS = 3620,
|
||||
BG_SA_GREEN_GATEWS = 3623,
|
||||
BG_SA_YELLOW_GATEWS = 3638,
|
||||
BG_SA_ANCIENT_GATEWS = 3849,
|
||||
BG_SA_LEFT_GY_ALLIANCE = 3635,
|
||||
BG_SA_RIGHT_GY_ALLIANCE = 3636,
|
||||
BG_SA_CENTER_GY_ALLIANCE = 3637,
|
||||
BG_SA_RIGHT_ATT_TOKEN_ALL = 3627,
|
||||
BG_SA_LEFT_ATT_TOKEN_ALL = 3626,
|
||||
BG_SA_LEFT_ATT_TOKEN_HRD = 3629,
|
||||
BG_SA_RIGHT_ATT_TOKEN_HRD = 3628,
|
||||
BG_SA_HORDE_DEFENCE_TOKEN = 3631,
|
||||
BG_SA_ALLIANCE_DEFENCE_TOKEN = 3630,
|
||||
BG_SA_RIGHT_GY_HORDE = 3632,
|
||||
BG_SA_LEFT_GY_HORDE = 3633,
|
||||
BG_SA_CENTER_GY_HORDE = 3634,
|
||||
BG_SA_BONUS_TIMER = 0xdf3,
|
||||
BG_SA_ENABLE_TIMER = 3564,
|
||||
};
|
||||
|
||||
enum npc
|
||||
{
|
||||
NPC_ANTI_PERSONNAL_CANNON = 27894,
|
||||
NPC_DEMOLISHER_SA = 28781,
|
||||
NPC_RIGGER_SPARKLIGHT = 29260,
|
||||
NPC_GORGRIL_RIGSPARK = 29262,
|
||||
};
|
||||
|
||||
enum BG_SA_NPCs
|
||||
{
|
||||
BG_SA_GUN_1 = 0,
|
||||
BG_SA_GUN_2,
|
||||
BG_SA_GUN_3,
|
||||
BG_SA_GUN_4,
|
||||
BG_SA_GUN_5,
|
||||
BG_SA_GUN_6,
|
||||
BG_SA_GUN_7,
|
||||
BG_SA_GUN_8,
|
||||
BG_SA_GUN_9,
|
||||
BG_SA_GUN_10,
|
||||
BG_SA_NPC_TRIGGER_1,
|
||||
BG_SA_NPC_TRIGGER_2,
|
||||
BG_SA_NPC_TRIGGER_3,
|
||||
BG_SA_NPC_TRIGGER_4,
|
||||
BG_SA_NPC_TRIGGER_5,
|
||||
BG_SA_DEMOLISHER_1,
|
||||
BG_SA_DEMOLISHER_2,
|
||||
BG_SA_DEMOLISHER_3,
|
||||
BG_SA_DEMOLISHER_4,
|
||||
BG_SA_DEMOLISHER_5,
|
||||
BG_SA_DEMOLISHER_6,
|
||||
BG_SA_DEMOLISHER_7,
|
||||
BG_SA_DEMOLISHER_8,
|
||||
BG_SA_NPC_SPARKLIGHT,
|
||||
BG_SA_NPC_RIGSPARK,
|
||||
BG_SA_MAXNPC
|
||||
};
|
||||
|
||||
enum BG_SA_Boat
|
||||
{
|
||||
BG_SA_BOAT_ONE_A = 193182,
|
||||
BG_SA_BOAT_TWO_H = 193183,
|
||||
BG_SA_BOAT_ONE_H = 193184,
|
||||
BG_SA_BOAT_TWO_A = 193185,
|
||||
};
|
||||
|
||||
uint32 const BG_SA_NpcEntries[BG_SA_MAXNPC] =
|
||||
{
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
NPC_ANTI_PERSONNAL_CANNON,
|
||||
// Triggers
|
||||
23472,
|
||||
23472,
|
||||
23472,
|
||||
23472,
|
||||
23472,
|
||||
// 4 beach demolishers
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
// 4 factory demolishers
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
NPC_DEMOLISHER_SA,
|
||||
// Used Demolisher Salesman
|
||||
NPC_RIGGER_SPARKLIGHT,
|
||||
NPC_GORGRIL_RIGSPARK
|
||||
};
|
||||
|
||||
float const BG_SA_NpcSpawnlocs[BG_SA_MAXNPC][4] =
|
||||
{
|
||||
// Cannons
|
||||
{ 1436.429f, 110.05f, 41.407f, 5.4f },
|
||||
{ 1404.9023f, 84.758f, 41.183f, 5.46f },
|
||||
{ 1068.693f, -86.951f, 93.81f, 0.02f },
|
||||
{ 1068.83f, -127.56f, 96.45f, 0.0912f },
|
||||
{ 1422.115f, -196.433f, 42.1825f, 1.0222f },
|
||||
{ 1454.887f, -220.454f, 41.956f, 0.9627f },
|
||||
{ 1232.345f, -187.517f, 66.945f, 0.45f },
|
||||
{ 1249.634f, -224.189f, 66.72f, 0.635f },
|
||||
{ 1236.213f, 92.287f, 64.965f, 5.751f },
|
||||
{ 1215.11f, 57.772f, 64.739f, 5.78f },
|
||||
// Triggers
|
||||
{ 1453.49f, -250.453f, 30.896f, 4.2883f},
|
||||
{ 1377.05f, 97.036f, 30.8605f, 2.46539f},
|
||||
{ 1186.05f, 58.8048f, 56.5491f, 2.75992f},
|
||||
{ 1042.83f, -72.839f, 84.8145f, 3.58615f},
|
||||
{ 1233.62f, -250.49f, 55.4036f, 3.7016f},
|
||||
// Demolishers
|
||||
{ 1611.597656f, -117.270073f, 8.719355f, 2.513274f},
|
||||
{ 1575.562500f, -158.421875f, 5.024450f, 2.129302f},
|
||||
{ 1618.047729f, 61.424641f, 7.248210f, 3.979351f},
|
||||
{ 1575.103149f, 98.873344f, 2.830360f, 3.752458f},
|
||||
// Demolishers 2
|
||||
{ 1371.055786f, -317.071136f, 35.007359f, 1.947460f},
|
||||
{ 1424.034912f, -260.195190f, 31.084425f, 2.820013f},
|
||||
{ 1353.139893f, 223.745438f, 35.265411f, 4.343684f},
|
||||
{ 1404.809570f, 197.027237f, 32.046032f, 3.605401f},
|
||||
// Npcs
|
||||
{ 1348.644165f, -298.786469f, 31.080130f, 1.710423f},
|
||||
{ 1358.191040f, 195.527786f, 31.018187f, 4.171337f}
|
||||
};
|
||||
|
||||
enum BG_SA_Objects
|
||||
{
|
||||
BG_SA_GREEN_GATE = 0,
|
||||
BG_SA_YELLOW_GATE,
|
||||
BG_SA_BLUE_GATE,
|
||||
BG_SA_RED_GATE,
|
||||
BG_SA_PURPLE_GATE,
|
||||
BG_SA_ANCIENT_GATE,
|
||||
BG_SA_TITAN_RELIC,
|
||||
BG_SA_BOAT_ONE,
|
||||
BG_SA_BOAT_TWO,
|
||||
BG_SA_SIGIL_1,
|
||||
BG_SA_SIGIL_2,
|
||||
BG_SA_SIGIL_3,
|
||||
BG_SA_SIGIL_4,
|
||||
BG_SA_SIGIL_5,
|
||||
BG_SA_CENTRAL_FLAGPOLE,
|
||||
BG_SA_RIGHT_FLAGPOLE,
|
||||
BG_SA_LEFT_FLAGPOLE,
|
||||
BG_SA_CENTRAL_FLAG,
|
||||
BG_SA_RIGHT_FLAG,
|
||||
BG_SA_LEFT_FLAG,
|
||||
BG_SA_PORTAL_DEFFENDER_BLUE,
|
||||
BG_SA_PORTAL_DEFFENDER_GREEN,
|
||||
BG_SA_PORTAL_DEFFENDER_YELLOW,
|
||||
BG_SA_PORTAL_DEFFENDER_PURPLE,
|
||||
BG_SA_PORTAL_DEFFENDER_RED,
|
||||
BG_SA_BOMB,
|
||||
BG_SA_MAXOBJ = BG_SA_BOMB+68
|
||||
};
|
||||
|
||||
float const BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4] =
|
||||
{
|
||||
{ 1411.57f, 108.163f, 28.692f, 5.441f },
|
||||
{ 1055.452f, -108.1f, 82.134f, 0.034f },
|
||||
{ 1431.3413f, -219.437f, 30.893f, 0.9736f },
|
||||
{ 1227.667f, -212.555f, 55.372f, 0.5023f },
|
||||
{ 1214.681f, 81.21f, 53.413f, 5.745f },
|
||||
{ 878.555f, -108.2f, 117.845f, 0.0f },
|
||||
{ 836.5f, -108.8f, 120.219f, 0.0f },
|
||||
// Ships
|
||||
{ 2679.696777f, -826.891235f, 3.712860f, 5.78367f}, //rot2 1 rot3 0.0002f
|
||||
{ 2574.003662f, 981.261475f, 2.603424f, 0.807696f},
|
||||
// Sigils
|
||||
{ 1414.054f, 106.72f, 41.442f, 5.441f },
|
||||
{ 1060.63f, -107.8f, 94.7f, 0.034f },
|
||||
{ 1433.383f, -216.4f, 43.642f, 0.9736f },
|
||||
{ 1230.75f, -210.724f, 67.611f, 0.5023f },
|
||||
{ 1217.8f, 79.532f, 66.58f, 5.745f },
|
||||
// Flagpoles
|
||||
{ 1215.114258f, -65.711861f, 70.084267f, -3.124123f},
|
||||
{1338.863892f, -153.336533f, 30.895121f, -2.530723f},
|
||||
{1309.124268f, 9.410645f, 30.893402f, -1.623156f},
|
||||
// Flags
|
||||
{ 1215.108032f, -65.715767f, 70.084267f, -3.124123f},
|
||||
{ 1338.859253f, -153.327316f, 30.895077f, -2.530723f},
|
||||
{ 1309.192017f, 9.416233f, 30.893402f, 1.518436f},
|
||||
// Portal
|
||||
{1468.380005f, -225.798996f, 30.896200f, 0.0f}, //blue
|
||||
{1394.270020f, 72.551399f, 31.054300f, 0.0f}, //green
|
||||
{1065.260010f, -89.79501f, 81.073402f, 0.0f}, //yellow
|
||||
{1216.069946f, 47.904301f, 54.278198f, 0.0f}, //purple
|
||||
{1255.569946f, -233.548996f, 56.43699f, 0.0f}, //red
|
||||
// Bombs
|
||||
{1333.45f, 211.354f, 31.0538f, 5.03666f},
|
||||
{1334.29f, 209.582f, 31.0532f, 1.28088f},
|
||||
{1332.72f, 210.049f, 31.0532f, 1.28088f},
|
||||
{1334.28f, 210.78f, 31.0538f, 3.85856f},
|
||||
{1332.64f, 211.39f, 31.0532f, 1.29266f},
|
||||
{1371.41f, 194.028f, 31.5107f, 0.753095f},
|
||||
{1372.39f, 194.951f, 31.4679f, 0.753095f},
|
||||
{1371.58f, 196.942f, 30.9349f, 1.01777f},
|
||||
{1370.43f, 196.614f, 30.9349f, 0.957299f},
|
||||
{1369.46f, 196.877f, 30.9351f, 2.45348f},
|
||||
{1370.35f, 197.361f, 30.9349f, 1.08689f},
|
||||
{1369.47f, 197.941f, 30.9349f, 0.984787f},
|
||||
{1592.49f, 47.5969f, 7.52271f, 4.63218f},
|
||||
{1593.91f, 47.8036f, 7.65856f, 4.63218f},
|
||||
{1593.13f, 46.8106f, 7.54073f, 4.63218f},
|
||||
{1589.22f, 36.3616f, 7.45975f, 4.64396f},
|
||||
{1588.24f, 35.5842f, 7.55613f, 4.79564f},
|
||||
{1588.14f, 36.7611f, 7.49675f, 4.79564f},
|
||||
{1595.74f, 35.5278f, 7.46602f, 4.90246f},
|
||||
{1596, 36.6475f, 7.47991f, 4.90246f},
|
||||
{1597.03f, 36.2356f, 7.48631f, 4.90246f},
|
||||
{1597.93f, 37.1214f, 7.51725f, 4.90246f},
|
||||
{1598.16f, 35.888f, 7.50018f, 4.90246f},
|
||||
{1579.6f, -98.0917f, 8.48478f, 1.37996f},
|
||||
{1581.2f, -98.401f, 8.47483f, 1.37996f},
|
||||
{1580.38f, -98.9556f, 8.4772f, 1.38781f},
|
||||
{1585.68f, -104.966f, 8.88551f, 0.493246f},
|
||||
{1586.15f, -106.033f, 9.10616f, 0.493246f},
|
||||
{1584.88f, -105.394f, 8.82985f, 0.493246f},
|
||||
{1581.87f, -100.899f, 8.46164f, 0.929142f},
|
||||
{1581.48f, -99.4657f, 8.46926f, 0.929142f},
|
||||
{1583.2f, -91.2291f, 8.49227f, 1.40038f},
|
||||
{1581.94f, -91.0119f, 8.49977f, 1.40038f},
|
||||
{1582.33f, -91.951f, 8.49353f, 1.1844f},
|
||||
{1342.06f, -304.049f, 30.9532f, 5.59507f},
|
||||
{1340.96f, -304.536f, 30.9458f, 1.28323f},
|
||||
{1341.22f, -303.316f, 30.9413f, 0.486051f},
|
||||
{1342.22f, -302.939f, 30.986f, 4.87643f},
|
||||
{1382.16f, -287.466f, 32.3063f, 4.80968f},
|
||||
{1381, -287.58f, 32.2805f, 4.80968f},
|
||||
{1381.55f, -286.536f, 32.3929f, 2.84225f},
|
||||
{1382.75f, -286.354f, 32.4099f, 1.00442f},
|
||||
{1379.92f, -287.34f, 32.2872f, 3.81615f},
|
||||
{1100.52f, -2.41391f, 70.2984f, 0.131054f},
|
||||
{1099.35f, -2.13851f, 70.3375f, 4.4586f},
|
||||
{1099.59f, -1.00329f, 70.238f, 2.49903f},
|
||||
{1097.79f, 0.571316f, 70.159f, 4.00307f},
|
||||
{1098.74f, -7.23252f, 70.7972f, 4.1523f},
|
||||
{1098.46f, -5.91443f, 70.6715f, 4.1523f},
|
||||
{1097.53f, -7.39704f, 70.7959f, 4.1523f},
|
||||
{1097.32f, -6.64233f, 70.7424f, 4.1523f},
|
||||
{1096.45f, -5.96664f, 70.7242f, 4.1523f},
|
||||
{971.725f, 0.496763f, 86.8467f, 2.09233f},
|
||||
{973.589f, 0.119518f, 86.7985f, 3.17225f},
|
||||
{972.524f, 1.25333f, 86.8351f, 5.28497f},
|
||||
{971.993f, 2.05668f, 86.8584f, 5.28497f},
|
||||
{973.635f, 2.11805f, 86.8197f, 2.36722f},
|
||||
{974.791f, 1.74679f, 86.7942f, 1.5936f},
|
||||
{974.771f, 3.0445f, 86.8125f, 0.647199f},
|
||||
{979.554f, 3.6037f, 86.7923f, 1.69178f},
|
||||
{979.758f, 2.57519f, 86.7748f, 1.76639f},
|
||||
{980.769f, 3.48904f, 86.7939f, 1.76639f},
|
||||
{979.122f, 2.87109f, 86.7794f, 1.76639f},
|
||||
{986.167f, 4.85363f, 86.8439f, 1.5779f},
|
||||
{986.176f, 3.50367f, 86.8217f, 1.5779f},
|
||||
{987.33f, 4.67389f, 86.8486f, 1.5779f},
|
||||
{985.23f, 4.65898f, 86.8368f, 1.5779f},
|
||||
{984.556f, 3.54097f, 86.8137f, 1.5779f},
|
||||
};
|
||||
|
||||
/* Ships:
|
||||
* 193182 - ally
|
||||
* 193183 - horde
|
||||
* 193184 - horde
|
||||
* 193185 - ally
|
||||
* Banners:
|
||||
* 191308 - left one,
|
||||
* 191306 - right one,
|
||||
* 191310 - central,
|
||||
* Ally ones, substract 1
|
||||
* to get horde ones.
|
||||
*/
|
||||
|
||||
uint32 const BG_SA_ObjEntries[BG_SA_MAXOBJ + BG_SA_FLAG_AMOUNT] =
|
||||
{
|
||||
190722,
|
||||
190727,
|
||||
190724,
|
||||
190726,
|
||||
190723,
|
||||
192549,
|
||||
192834,
|
||||
0, // Boat
|
||||
0, // Boat
|
||||
192687,
|
||||
192685,
|
||||
192689,
|
||||
192690,
|
||||
192691,
|
||||
191311,
|
||||
191311,
|
||||
191311,
|
||||
191310,
|
||||
191306,
|
||||
191308,
|
||||
192819,
|
||||
192819,
|
||||
192819,
|
||||
192819,
|
||||
192819,
|
||||
190753
|
||||
};
|
||||
|
||||
uint32 const BG_SA_Factions[2] =
|
||||
{
|
||||
1732,
|
||||
1735,
|
||||
};
|
||||
|
||||
enum BG_SA_Graveyards
|
||||
{
|
||||
BG_SA_BEACH_GY = 0,
|
||||
BG_SA_DEFENDER_LAST_GY,
|
||||
BG_SA_RIGHT_CAPTURABLE_GY,
|
||||
BG_SA_LEFT_CAPTURABLE_GY,
|
||||
BG_SA_CENTRAL_CAPTURABLE_GY,
|
||||
BG_SA_MAX_GY
|
||||
};
|
||||
|
||||
const uint32 BG_SA_GYEntries[BG_SA_MAX_GY] =
|
||||
{
|
||||
1350,
|
||||
1349,
|
||||
1347,
|
||||
1346,
|
||||
1348,
|
||||
};
|
||||
|
||||
float const BG_SA_GYOrientation[BG_SA_MAX_GY] =
|
||||
{
|
||||
6.202f,
|
||||
1.926f, // right capturable GY
|
||||
3.917f, // left capturable GY
|
||||
3.104f, // center, capturable
|
||||
6.148f, // defender last GY
|
||||
};
|
||||
|
||||
struct BG_SA_RoundScore
|
||||
{
|
||||
TeamId winner;
|
||||
uint32 time;
|
||||
};
|
||||
|
||||
const float SOTADefPortalDest[5][4] = {
|
||||
{ 1388.94f, 103.067f, 34.49f, 5.4571f },
|
||||
{ 1043.69f, -87.95f, 87.12f, 0.003f },
|
||||
{ 1441.0411f, -240.974f, 35.264f, 0.949f },
|
||||
{ 1228.342f, -235.234f, 60.03f, 0.4584f },
|
||||
{ 1193.857f, 69.9f, 58.046f, 5.7245f },
|
||||
};
|
||||
|
||||
/// Class for manage Strand of Ancient battleground
|
||||
class BattlegroundSA : public Battleground
|
||||
{
|
||||
public:
|
||||
BattlegroundSA();
|
||||
~BattlegroundSA();
|
||||
|
||||
/**
|
||||
* \brief Called every time for update battle data
|
||||
* -Update timer
|
||||
* -Round switch
|
||||
*/
|
||||
void PostUpdateImpl(uint32 diff);
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
/// Called when a player join battle
|
||||
void AddPlayer(Player* player);
|
||||
/// Called when battle start
|
||||
void StartingEventCloseDoors();
|
||||
void StartingEventOpenDoors();
|
||||
/// Called for ini battleground, after that the first player be entered
|
||||
bool SetupBattleground();
|
||||
void Init();
|
||||
/// Called for generate packet contain worldstate data
|
||||
void FillInitialWorldStates(WorldPacket& data);
|
||||
/// Called when a player deal damage to building (door)
|
||||
void EventPlayerDamagedGO(Player* player, GameObject* go, uint32 eventType);
|
||||
/// Called when a player kill a unit in bg
|
||||
void HandleKillUnit(Creature* creature, Player* killer);
|
||||
/// Return the nearest graveyard where player can respawn
|
||||
WorldSafeLocsEntry const* GetClosestGraveyard(Player* player);
|
||||
/// Called when a player click on flag (graveyard flag)
|
||||
void EventPlayerClickedOnFlag(Player* Source, GameObject* gameObject);
|
||||
/// Called when a player use a gamobject (relic)
|
||||
void EventPlayerUsedGO(Player* Source, GameObject* object);
|
||||
|
||||
/// Return worldstate id, according to door id
|
||||
uint32 GetWorldStateFromGateID(uint32 id)
|
||||
{
|
||||
uint32 uws = 0;
|
||||
switch (id)
|
||||
{
|
||||
case BG_SA_GREEN_GATE: uws = BG_SA_GREEN_GATEWS; break;
|
||||
case BG_SA_YELLOW_GATE: uws = BG_SA_YELLOW_GATEWS; break;
|
||||
case BG_SA_BLUE_GATE: uws = BG_SA_BLUE_GATEWS; break;
|
||||
case BG_SA_RED_GATE: uws = BG_SA_RED_GATEWS; break;
|
||||
case BG_SA_PURPLE_GATE: uws = BG_SA_PURPLE_GATEWS; break;
|
||||
case BG_SA_ANCIENT_GATE: uws = BG_SA_ANCIENT_GATEWS; break;
|
||||
}
|
||||
return uws;
|
||||
}
|
||||
|
||||
/// Called on battleground ending
|
||||
void EndBattleground(TeamId winnerTeamId);
|
||||
|
||||
/// CAlled when a player leave battleground
|
||||
void RemovePlayer(Player* player);
|
||||
void HandleAreaTrigger(Player* player, uint32 trigger);
|
||||
|
||||
/* Scorekeeping */
|
||||
/// Update score board
|
||||
void UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
|
||||
// Teleporters
|
||||
void DefendersPortalTeleport(GameObject* portal, Player* plr);
|
||||
|
||||
// Achievements
|
||||
bool AllowDefenseOfTheAncients(Player* source);
|
||||
|
||||
// Achievement: Not Even a Scratch
|
||||
bool notEvenAScratch(TeamId teamId) const { return _notEvenAScratch[teamId]; }
|
||||
|
||||
private:
|
||||
|
||||
/// Return gate id, relative to bg data, according to gameobject id
|
||||
uint32 GetGateIDFromEntry(uint32 id)
|
||||
{
|
||||
uint32 i = 0;
|
||||
switch(id)
|
||||
{
|
||||
case 190722: i = BG_SA_GREEN_GATE; break; //Green gate destroyed
|
||||
case 190724: i = BG_SA_BLUE_GATE; break; //blue gate
|
||||
case 190726: i = BG_SA_RED_GATE; break; //red gate
|
||||
case 190723: i = BG_SA_PURPLE_GATE; break; //purple gate
|
||||
case 190727: i = BG_SA_YELLOW_GATE; break; //yellow gate
|
||||
case 192549: i = BG_SA_ANCIENT_GATE; break; //ancient gate
|
||||
}
|
||||
return i;
|
||||
}
|
||||
/**
|
||||
* \brief Called on setup and between the two round
|
||||
* -Delete all gameobject / creature
|
||||
* -Respawn all gameobject / creature to have good faction
|
||||
*/
|
||||
bool ResetObjs();
|
||||
/// Called for start ship movement
|
||||
void StartShips();
|
||||
/**
|
||||
* \brief Called between the two round
|
||||
* -Teleport all players to good location
|
||||
*/
|
||||
void TeleportPlayers();
|
||||
void TeleportToEntrancePosition(Player* player);
|
||||
/**
|
||||
* \brief Called on start and between the two round
|
||||
* -Update faction of all vehicle
|
||||
*/
|
||||
void OverrideGunFaction();
|
||||
/// Set selectable or not demolisher, called on battle start, when boats arrive to dock
|
||||
void DemolisherStartState(bool start);
|
||||
/// Checks if a player can interact with the given object
|
||||
bool CanInteractWithObject(uint32 objectId);
|
||||
/// Updates interaction flags of specific objects
|
||||
void UpdateObjectInteractionFlags(uint32 objectId);
|
||||
void UpdateObjectInteractionFlags();
|
||||
/**
|
||||
* \brief Called when a gate is destroy
|
||||
* -Give honor to player witch destroy it
|
||||
* -Update worldstate
|
||||
* -Delete gameobject in front of door (lighting object, with different colours for each door)
|
||||
*/
|
||||
void DestroyGate(Player* player, GameObject* go);
|
||||
/// Update timer worldstate
|
||||
void SendTime();
|
||||
/**
|
||||
* \brief Called when a graveyard is capture
|
||||
* -Update spiritguide
|
||||
* -Update gameobject (flag)
|
||||
* -Update Worldstate
|
||||
* -Send warning for announce this
|
||||
* \param i : id of graveyard
|
||||
* \param Source : Player who capture gy
|
||||
*/
|
||||
void CaptureGraveyard(BG_SA_Graveyards i, Player* Source);
|
||||
/// Switch on/off timer worldstate
|
||||
void ToggleTimer();
|
||||
|
||||
/// Respawn dead demolisher
|
||||
void UpdateDemolisherSpawns();
|
||||
|
||||
/// Send packet to player for create boats (client part)
|
||||
void SendTransportInit(Player* player);
|
||||
/// Send packet to player for destroy boats (client part)
|
||||
void SendTransportsRemove(Player* player);
|
||||
|
||||
/// Id of attacker team
|
||||
TeamId Attackers;
|
||||
/// Totale elapsed time of current round
|
||||
uint32 TotalTime;
|
||||
/// Max time of round
|
||||
uint32 EndRoundTimer;
|
||||
/// For know if boats has start moving or not yet
|
||||
bool ShipsStarted;
|
||||
/// Status of each gate (Destroy/Damage/Intact)
|
||||
BG_SA_GateState GateStatus[6];
|
||||
/// Statu of battle (Start or not, and what round)
|
||||
BG_SA_Status Status;
|
||||
/// Team witch conntrol each graveyard
|
||||
TeamId GraveyardStatus[BG_SA_MAX_GY];
|
||||
/// Score of each round
|
||||
BG_SA_RoundScore RoundScores[2];
|
||||
/// used for know we are in timer phase or not (used for worldstate update)
|
||||
bool TimerEnabled;
|
||||
/// 5secs before starting the 1min countdown for second round
|
||||
uint32 UpdateWaitTimer;
|
||||
/// for know if warning about second round start has been sent
|
||||
bool SignaledRoundTwo;
|
||||
/// for know if warning about second round start has been sent
|
||||
bool SignaledRoundTwoHalfMin;
|
||||
/// for know if second round has been init
|
||||
bool InitSecondRound;
|
||||
std::map<uint32/*id*/, uint32/*timer*/> DemoliserRespawnList;
|
||||
|
||||
// xinef:
|
||||
bool _relicClicked;
|
||||
|
||||
// Achievement: Not Even a Scratch
|
||||
bool _notEvenAScratch[BG_TEAMS_COUNT];
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,551 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "BattlegroundWS.h"
|
||||
#include "Creature.h"
|
||||
#include "GameObject.h"
|
||||
#include "Language.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
BattlegroundWS::BattlegroundWS()
|
||||
{
|
||||
BgObjects.resize(BG_WS_OBJECT_MAX);
|
||||
BgCreatures.resize(BG_CREATURES_MAX_WS);
|
||||
|
||||
StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
|
||||
StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
|
||||
StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
|
||||
|
||||
_flagKeepers[TEAM_ALLIANCE] = 0;
|
||||
_flagKeepers[TEAM_HORDE] = 0;
|
||||
_droppedFlagGUID[TEAM_ALLIANCE] = 0;
|
||||
_droppedFlagGUID[TEAM_HORDE] = 0;
|
||||
_flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||
_flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||
_lastFlagCaptureTeam = TEAM_NEUTRAL;
|
||||
_reputationCapture = 0;
|
||||
_honorWinKills = 0;
|
||||
_honorEndKills = 0;
|
||||
}
|
||||
|
||||
BattlegroundWS::~BattlegroundWS()
|
||||
{
|
||||
}
|
||||
|
||||
void BattlegroundWS::PostUpdateImpl(uint32 diff)
|
||||
{
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
_bgEvents.Update(diff);
|
||||
switch (_bgEvents.ExecuteEvent())
|
||||
{
|
||||
case BG_WS_EVENT_UPDATE_GAME_TIME:
|
||||
UpdateWorldState(BG_WS_STATE_TIMER, GetMatchTime());
|
||||
_bgEvents.ScheduleEvent(BG_WS_EVENT_UPDATE_GAME_TIME, ((BG_WS_TOTAL_GAME_TIME - GetStartTime()) % (MINUTE*IN_MILLISECONDS)) + 1);
|
||||
break;
|
||||
case BG_WS_EVENT_NO_TIME_LEFT:
|
||||
if (GetTeamScore(TEAM_ALLIANCE) == GetTeamScore(TEAM_HORDE))
|
||||
EndBattleground(_lastFlagCaptureTeam);
|
||||
else
|
||||
EndBattleground(GetTeamScore(TEAM_HORDE) > GetTeamScore(TEAM_ALLIANCE) ? TEAM_HORDE : TEAM_ALLIANCE);
|
||||
break;
|
||||
case BG_WS_EVENT_RESPAWN_BOTH_FLAGS:
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SendMessageToAll(LANG_BG_WS_F_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
|
||||
break;
|
||||
case BG_WS_EVENT_ALLIANCE_DROP_FLAG:
|
||||
RespawnFlagAfterDrop(TEAM_ALLIANCE);
|
||||
break;
|
||||
case BG_WS_EVENT_HORDE_DROP_FLAG:
|
||||
RespawnFlagAfterDrop(TEAM_HORDE);
|
||||
break;
|
||||
case BG_WS_EVENT_BOTH_FLAGS_KEPT10:
|
||||
if (Player* player = ObjectAccessor::GetObjectInMap(GetFlagPickerGUID(TEAM_ALLIANCE), this->FindBgMap(), (Player*)NULL))
|
||||
player->CastSpell(player, BG_WS_SPELL_FOCUSED_ASSAULT, true);
|
||||
if (Player* player = ObjectAccessor::GetObjectInMap(GetFlagPickerGUID(TEAM_HORDE), this->FindBgMap(), (Player*)NULL))
|
||||
player->CastSpell(player, BG_WS_SPELL_FOCUSED_ASSAULT, true);
|
||||
break;
|
||||
case BG_WS_EVENT_BOTH_FLAGS_KEPT15:
|
||||
if (Player* player = ObjectAccessor::GetObjectInMap(GetFlagPickerGUID(TEAM_ALLIANCE), this->FindBgMap(), (Player*)NULL))
|
||||
{
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_FOCUSED_ASSAULT);
|
||||
player->CastSpell(player, BG_WS_SPELL_BRUTAL_ASSAULT, true);
|
||||
}
|
||||
if (Player* player = ObjectAccessor::GetObjectInMap(GetFlagPickerGUID(TEAM_HORDE), this->FindBgMap(), (Player*)NULL))
|
||||
{
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_FOCUSED_ASSAULT);
|
||||
player->CastSpell(player, BG_WS_SPELL_BRUTAL_ASSAULT, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundWS::StartingEventCloseDoors()
|
||||
{
|
||||
for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i)
|
||||
{
|
||||
DoorClose(i);
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
for (uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
void BattlegroundWS::StartingEventOpenDoors()
|
||||
{
|
||||
for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_6; ++i)
|
||||
DoorOpen(i);
|
||||
for (uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i)
|
||||
DoorOpen(i);
|
||||
|
||||
for (uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY);
|
||||
|
||||
StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, WS_EVENT_START_BATTLE);
|
||||
UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 1);
|
||||
_bgEvents.ScheduleEvent(BG_WS_EVENT_UPDATE_GAME_TIME, 0);
|
||||
_bgEvents.ScheduleEvent(BG_WS_EVENT_NO_TIME_LEFT, BG_WS_TOTAL_GAME_TIME - 2*MINUTE*IN_MILLISECONDS); // 27 - 2 = 25 minutes
|
||||
}
|
||||
|
||||
void BattlegroundWS::AddPlayer(Player* player)
|
||||
{
|
||||
Battleground::AddPlayer(player);
|
||||
PlayerScores[player->GetGUID()] = new BattlegroundWGScore(player);
|
||||
}
|
||||
|
||||
void BattlegroundWS::RespawnFlagAfterDrop(TeamId teamId)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS || GetFlagState(teamId) != BG_WS_FLAG_STATE_ON_GROUND)
|
||||
return;
|
||||
|
||||
UpdateFlagState(teamId, BG_WS_FLAG_STATE_ON_BASE);
|
||||
SpawnBGObject(teamId == TEAM_ALLIANCE ? BG_WS_OBJECT_A_FLAG : BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
|
||||
SendMessageToAll(teamId == TEAM_ALLIANCE ? LANG_BG_WS_ALLIANCE_FLAG_RESPAWNED : LANG_BG_WS_HORDE_FLAG_RESPAWNED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
|
||||
|
||||
if (GameObject* flag = GetBgMap()->GetGameObject(GetDroppedFlagGUID(teamId)))
|
||||
flag->Delete();
|
||||
|
||||
SetDroppedFlagGUID(0, teamId);
|
||||
_bgEvents.CancelEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT10);
|
||||
_bgEvents.CancelEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT15);
|
||||
RemoveAssaultAuras();
|
||||
}
|
||||
|
||||
void BattlegroundWS::EventPlayerCapturedFlag(Player* player)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
RemoveAssaultAuras();
|
||||
|
||||
AddPoints(player->GetTeamId(), 1);
|
||||
SetFlagPicker(0, GetOtherTeamId(player->GetTeamId()));
|
||||
UpdateFlagState(GetOtherTeamId(player->GetTeamId()), BG_WS_FLAG_STATE_ON_BASE);
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE)
|
||||
{
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE);
|
||||
SendMessageToAll(LANG_BG_WS_CAPTURED_HF, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
RewardReputationToTeam(890, _reputationCapture, TEAM_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAG_CAPTURED_HORDE);
|
||||
SendMessageToAll(LANG_BG_WS_CAPTURED_AF, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
RewardReputationToTeam(889, _reputationCapture, TEAM_HORDE);
|
||||
}
|
||||
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, BG_WS_FLAG_RESPAWN_TIME);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, BG_WS_FLAG_RESPAWN_TIME);
|
||||
|
||||
UpdateWorldState(player->GetTeamId() == TEAM_ALLIANCE ? BG_WS_FLAG_CAPTURES_ALLIANCE : BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(player->GetTeamId()));
|
||||
UpdatePlayerScore(player, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
|
||||
_lastFlagCaptureTeam = player->GetTeamId();
|
||||
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(2), player->GetTeamId());
|
||||
|
||||
if (GetTeamScore(TEAM_ALLIANCE) == BG_WS_MAX_TEAM_SCORE || GetTeamScore(TEAM_HORDE) == BG_WS_MAX_TEAM_SCORE)
|
||||
{
|
||||
UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 0);
|
||||
EndBattleground(GetTeamScore(TEAM_HORDE) == BG_WS_MAX_TEAM_SCORE ? TEAM_HORDE : TEAM_ALLIANCE);
|
||||
}
|
||||
else
|
||||
_bgEvents.ScheduleEvent(BG_WS_EVENT_RESPAWN_BOTH_FLAGS, BG_WS_FLAG_RESPAWN_TIME);
|
||||
|
||||
_bgEvents.CancelEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT10);
|
||||
_bgEvents.CancelEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT15);
|
||||
}
|
||||
|
||||
void BattlegroundWS::EventPlayerDroppedFlag(Player* player)
|
||||
{
|
||||
if (GetFlagPickerGUID(TEAM_HORDE) != player->GetGUID() && GetFlagPickerGUID(TEAM_ALLIANCE) != player->GetGUID())
|
||||
return;
|
||||
|
||||
SetFlagPicker(0, GetOtherTeamId(player->GetTeamId()));
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_FOCUSED_ASSAULT);
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_BRUTAL_ASSAULT);
|
||||
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
player->CastSpell(player, SPELL_RECENTLY_DROPPED_FLAG, true);
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE)
|
||||
{
|
||||
UpdateFlagState(TEAM_HORDE, BG_WS_FLAG_STATE_ON_GROUND);
|
||||
player->CastSpell(player, BG_WS_SPELL_WARSONG_FLAG_DROPPED, true);
|
||||
SendMessageToAll(LANG_BG_WS_DROPPED_HF, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
_bgEvents.RescheduleEvent(BG_WS_EVENT_HORDE_DROP_FLAG, BG_WS_FLAG_DROP_TIME);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateFlagState(TEAM_ALLIANCE, BG_WS_FLAG_STATE_ON_GROUND);
|
||||
player->CastSpell(player, BG_WS_SPELL_SILVERWING_FLAG_DROPPED, true);
|
||||
SendMessageToAll(LANG_BG_WS_DROPPED_AF, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
_bgEvents.RescheduleEvent(BG_WS_EVENT_ALLIANCE_DROP_FLAG, BG_WS_FLAG_DROP_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundWS::EventPlayerClickedOnFlag(Player* player, GameObject* gameObject)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
int32 message_id = 0;
|
||||
ChatMsg type = CHAT_MSG_BG_SYSTEM_NEUTRAL;
|
||||
player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
|
||||
|
||||
// Alliance Flag picked up from base
|
||||
if (player->GetTeamId() == TEAM_HORDE && GetFlagState(TEAM_ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE && BgObjects[BG_WS_OBJECT_A_FLAG] == gameObject->GetGUID())
|
||||
{
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_ONE_DAY);
|
||||
SetFlagPicker(player->GetGUID(), TEAM_ALLIANCE);
|
||||
UpdateFlagState(TEAM_ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||
player->CastSpell(player, BG_WS_SPELL_SILVERWING_FLAG, true);
|
||||
player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, BG_WS_SPELL_SILVERWING_FLAG_PICKED);
|
||||
|
||||
PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
|
||||
SendMessageToAll(LANG_BG_WS_PICKEDUP_AF, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
|
||||
if (GetFlagState(TEAM_HORDE) != BG_WS_FLAG_STATE_ON_BASE)
|
||||
{
|
||||
_bgEvents.RescheduleEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT10, BG_WS_SPELL_FORCE_TIME);
|
||||
_bgEvents.RescheduleEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT15, BG_WS_SPELL_BRUTAL_TIME);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Horde Flag picked up from base
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE && GetFlagState(TEAM_HORDE) == BG_WS_FLAG_STATE_ON_BASE && BgObjects[BG_WS_OBJECT_H_FLAG] == gameObject->GetGUID())
|
||||
{
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_ONE_DAY);
|
||||
SetFlagPicker(player->GetGUID(), TEAM_HORDE);
|
||||
UpdateFlagState(TEAM_HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||
player->CastSpell(player, BG_WS_SPELL_WARSONG_FLAG, true);
|
||||
player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, BG_WS_SPELL_WARSONG_FLAG_PICKED);
|
||||
|
||||
PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
|
||||
SendMessageToAll(LANG_BG_WS_PICKEDUP_HF, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
|
||||
if (GetFlagState(TEAM_ALLIANCE) != BG_WS_FLAG_STATE_ON_BASE)
|
||||
{
|
||||
_bgEvents.RescheduleEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT10, BG_WS_SPELL_FORCE_TIME);
|
||||
_bgEvents.RescheduleEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT15, BG_WS_SPELL_BRUTAL_TIME);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Alliance Flag on ground
|
||||
if (GetFlagState(TEAM_ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && player->IsWithinDistInMap(gameObject, 10.0f) && gameObject->GetEntry() == BG_OBJECT_A_FLAG_GROUND_WS_ENTRY)
|
||||
{
|
||||
SetDroppedFlagGUID(0, TEAM_ALLIANCE);
|
||||
if (player->GetTeamId() == TEAM_ALLIANCE)
|
||||
{
|
||||
UpdateFlagState(TEAM_ALLIANCE, BG_WS_FLAG_STATE_ON_BASE);
|
||||
SpawnBGObject(BG_WS_OBJECT_A_FLAG, RESPAWN_IMMEDIATELY);
|
||||
UpdatePlayerScore(player, SCORE_FLAG_RETURNS, 1);
|
||||
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
|
||||
SendMessageToAll(LANG_BG_WS_RETURNED_AF, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
_bgEvents.CancelEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT10);
|
||||
_bgEvents.CancelEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT15);
|
||||
RemoveAssaultAuras();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFlagPicker(player->GetGUID(), TEAM_ALLIANCE);
|
||||
UpdateFlagState(TEAM_ALLIANCE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||
player->CastSpell(player, BG_WS_SPELL_SILVERWING_FLAG, true);
|
||||
if (uint32 assaultSpellId = GetAssaultSpellId())
|
||||
player->CastSpell(player, assaultSpellId, true);
|
||||
|
||||
PlaySoundToAll(BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP);
|
||||
SendMessageToAll(LANG_BG_WS_PICKEDUP_AF, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Horde Flag on ground
|
||||
if (GetFlagState(TEAM_HORDE) == BG_WS_FLAG_STATE_ON_GROUND && player->IsWithinDistInMap(gameObject, 10.0f) && gameObject->GetEntry() == BG_OBJECT_H_FLAG_GROUND_WS_ENTRY)
|
||||
{
|
||||
SetDroppedFlagGUID(0, TEAM_HORDE);
|
||||
if (player->GetTeamId() == TEAM_HORDE)
|
||||
{
|
||||
UpdateFlagState(TEAM_HORDE, BG_WS_FLAG_STATE_ON_BASE);
|
||||
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
|
||||
UpdatePlayerScore(player, SCORE_FLAG_RETURNS, 1);
|
||||
|
||||
PlaySoundToAll(BG_WS_SOUND_FLAG_RETURNED);
|
||||
SendMessageToAll(LANG_BG_WS_RETURNED_HF, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
_bgEvents.CancelEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT10);
|
||||
_bgEvents.CancelEvent(BG_WS_EVENT_BOTH_FLAGS_KEPT15);
|
||||
RemoveAssaultAuras();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFlagPicker(player->GetGUID(), TEAM_HORDE);
|
||||
UpdateFlagState(TEAM_HORDE, BG_WS_FLAG_STATE_ON_PLAYER);
|
||||
player->CastSpell(player, BG_WS_SPELL_WARSONG_FLAG, true);
|
||||
if (uint32 assaultSpellId = GetAssaultSpellId())
|
||||
player->CastSpell(player, assaultSpellId, true);
|
||||
|
||||
PlaySoundToAll(BG_WS_SOUND_HORDE_FLAG_PICKED_UP);
|
||||
SendMessageToAll(LANG_BG_WS_PICKEDUP_HF, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundWS::RemovePlayer(Player* player)
|
||||
{
|
||||
if (GetFlagPickerGUID(TEAM_ALLIANCE) == player->GetGUID() || GetFlagPickerGUID(TEAM_HORDE) == player->GetGUID())
|
||||
EventPlayerDroppedFlag(player);
|
||||
}
|
||||
|
||||
void BattlegroundWS::UpdateFlagState(TeamId teamId, uint32 value)
|
||||
{
|
||||
_flagState[teamId] = value;
|
||||
UpdateWorldState(teamId == TEAM_ALLIANCE ? BG_WS_FLAG_STATE_HORDE : BG_WS_FLAG_STATE_ALLIANCE, value);
|
||||
}
|
||||
|
||||
void BattlegroundWS::HandleAreaTrigger(Player* player, uint32 trigger)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS || !player->IsAlive())
|
||||
return;
|
||||
|
||||
switch (trigger)
|
||||
{
|
||||
case 3646: // Alliance Flag spawn
|
||||
if (GetFlagState(TEAM_ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE && GetFlagPickerGUID(TEAM_HORDE) == player->GetGUID())
|
||||
EventPlayerCapturedFlag(player);
|
||||
break;
|
||||
case 3647: // Horde Flag spawn
|
||||
if (GetFlagState(TEAM_HORDE) == BG_WS_FLAG_STATE_ON_BASE && GetFlagPickerGUID(TEAM_ALLIANCE) == player->GetGUID())
|
||||
EventPlayerCapturedFlag(player);
|
||||
break;
|
||||
case 3649: // Not used
|
||||
case 3688: // Not used
|
||||
case 4628: // Not used
|
||||
case 4629: // Not used
|
||||
case 3686: // Alliance elixir of speed spawn
|
||||
case 3687: // Horde elixir of speed spawn
|
||||
case 3706: // Alliance elixir of regeneration spawn
|
||||
case 3708: // Horde elixir of regeneration spawn
|
||||
case 3707: // Alliance elixir of berserk spawn
|
||||
case 3709: // Horde elixir of berserk spawn
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool BattlegroundWS::SetupBattleground()
|
||||
{
|
||||
// flags
|
||||
AddObject(BG_WS_OBJECT_A_FLAG, BG_OBJECT_A_FLAG_WS_ENTRY, 1540.423f, 1481.325f, 351.8284f, 3.089233f, 0, 0, 0.9996573f, 0.02617699f, RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_WS_OBJECT_H_FLAG, BG_OBJECT_H_FLAG_WS_ENTRY, 916.0226f, 1434.405f, 345.413f, 0.01745329f, 0, 0, 0.008726535f, 0.9999619f, RESPAWN_IMMEDIATELY);
|
||||
// buffs
|
||||
AddObject(BG_WS_OBJECT_SPEEDBUFF_1, BG_OBJECTID_SPEEDBUFF_ENTRY, 1449.93f, 1470.71f, 342.6346f, -1.64061f, 0, 0, 0.7313537f, -0.6819983f, BUFF_RESPAWN_TIME);
|
||||
AddObject(BG_WS_OBJECT_SPEEDBUFF_2, BG_OBJECTID_SPEEDBUFF_ENTRY, 1005.171f, 1447.946f, 335.9032f, 1.64061f, 0, 0, 0.7313537f, 0.6819984f, BUFF_RESPAWN_TIME);
|
||||
AddObject(BG_WS_OBJECT_REGENBUFF_1, BG_OBJECTID_REGENBUFF_ENTRY, 1317.506f, 1550.851f, 313.2344f, -0.2617996f, 0, 0, 0.1305263f, -0.9914448f, BUFF_RESPAWN_TIME);
|
||||
AddObject(BG_WS_OBJECT_REGENBUFF_2, BG_OBJECTID_REGENBUFF_ENTRY, 1110.451f, 1353.656f, 316.5181f, -0.6806787f, 0, 0, 0.333807f, -0.9426414f, BUFF_RESPAWN_TIME);
|
||||
AddObject(BG_WS_OBJECT_BERSERKBUFF_1, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1320.09f, 1378.79f, 314.7532f, 1.186824f, 0, 0, 0.5591929f, 0.8290376f, BUFF_RESPAWN_TIME);
|
||||
AddObject(BG_WS_OBJECT_BERSERKBUFF_2, BG_OBJECTID_BERSERKERBUFF_ENTRY, 1139.688f, 1560.288f, 306.8432f, -2.443461f, 0, 0, 0.9396926f, -0.3420201f, BUFF_RESPAWN_TIME);
|
||||
// alliance gates
|
||||
AddObject(BG_WS_OBJECT_DOOR_A_1, BG_OBJECT_DOOR_A_1_WS_ENTRY, 1503.335f, 1493.466f, 352.1888f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_WS_OBJECT_DOOR_A_2, BG_OBJECT_DOOR_A_2_WS_ENTRY, 1492.478f, 1457.912f, 342.9689f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_WS_OBJECT_DOOR_A_3, BG_OBJECT_DOOR_A_3_WS_ENTRY, 1468.503f, 1494.357f, 351.8618f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_WS_OBJECT_DOOR_A_4, BG_OBJECT_DOOR_A_4_WS_ENTRY, 1471.555f, 1458.778f, 362.6332f, 3.115414f, 0, 0, 0.9999143f, 0.01308903f, RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_WS_OBJECT_DOOR_A_5, BG_OBJECT_DOOR_A_5_WS_ENTRY, 1492.347f, 1458.34f, 342.3712f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_WS_OBJECT_DOOR_A_6, BG_OBJECT_DOOR_A_6_WS_ENTRY, 1503.466f, 1493.367f, 351.7352f, -0.03490669f, 0, 0, 0.01745246f, -0.9998477f, RESPAWN_IMMEDIATELY);
|
||||
// horde gates
|
||||
AddObject(BG_WS_OBJECT_DOOR_H_1, BG_OBJECT_DOOR_H_1_WS_ENTRY, 949.1663f, 1423.772f, 345.6241f, -0.5756807f, -0.01673368f, -0.004956111f, -0.2839723f, 0.9586737f, RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_WS_OBJECT_DOOR_H_2, BG_OBJECT_DOOR_H_2_WS_ENTRY, 953.0507f, 1459.842f, 340.6526f, -1.99662f, -0.1971825f, 0.1575096f, -0.8239487f, 0.5073641f, RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_WS_OBJECT_DOOR_H_3, BG_OBJECT_DOOR_H_3_WS_ENTRY, 949.9523f, 1422.751f, 344.9273f, 0.0f, 0, 0, 0, 1, RESPAWN_IMMEDIATELY);
|
||||
AddObject(BG_WS_OBJECT_DOOR_H_4, BG_OBJECT_DOOR_H_4_WS_ENTRY, 950.7952f, 1459.583f, 342.1523f, 0.05235988f, 0, 0, 0.02617695f, 0.9996573f, RESPAWN_IMMEDIATELY);
|
||||
|
||||
|
||||
WorldSafeLocsEntry const* sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_ALLIANCE);
|
||||
AddSpiritGuide(WS_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, TEAM_ALLIANCE);
|
||||
|
||||
sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_HORDE);
|
||||
AddSpiritGuide(WS_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, TEAM_HORDE);
|
||||
|
||||
for (uint32 i = BG_WS_OBJECT_DOOR_A_1; i < BG_WS_OBJECT_MAX; ++i)
|
||||
if (BgObjects[i] == 0)
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundWS: Failed to spawn some object Battleground not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32 i = WS_SPIRIT_MAIN_ALLIANCE; i < BG_CREATURES_MAX_WS; ++i)
|
||||
if (BgCreatures[i] == 0)
|
||||
{
|
||||
sLog->outErrorDb("BatteGroundWS: Failed to spawn spirit guides Battleground not created!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattlegroundWS::Init()
|
||||
{
|
||||
//call parent's class reset
|
||||
Battleground::Init();
|
||||
|
||||
_bgEvents.Reset();
|
||||
_flagKeepers[TEAM_ALLIANCE] = 0;
|
||||
_flagKeepers[TEAM_HORDE] = 0;
|
||||
_droppedFlagGUID[TEAM_ALLIANCE] = 0;
|
||||
_droppedFlagGUID[TEAM_HORDE] = 0;
|
||||
_flagState[TEAM_ALLIANCE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||
_flagState[TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
|
||||
_lastFlagCaptureTeam = TEAM_NEUTRAL;
|
||||
|
||||
if (sBattlegroundMgr->IsBGWeekend(GetBgTypeID()))
|
||||
{
|
||||
_reputationCapture = 45;
|
||||
_honorWinKills = 3;
|
||||
_honorEndKills = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
_reputationCapture = 35;
|
||||
_honorWinKills = 1;
|
||||
_honorEndKills = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundWS::EndBattleground(TeamId winnerTeamId)
|
||||
{
|
||||
// Win reward
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(_honorWinKills), winnerTeamId);
|
||||
|
||||
// Complete map_end rewards (even if no team wins)
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(_honorEndKills), TEAM_ALLIANCE);
|
||||
RewardHonorToTeam(GetBonusHonorFromKill(_honorEndKills), TEAM_HORDE);
|
||||
|
||||
Battleground::EndBattleground(winnerTeamId);
|
||||
}
|
||||
|
||||
void BattlegroundWS::HandleKillPlayer(Player* player, Player* killer)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
EventPlayerDroppedFlag(player);
|
||||
Battleground::HandleKillPlayer(player, killer);
|
||||
}
|
||||
|
||||
void BattlegroundWS::UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor)
|
||||
{
|
||||
BattlegroundScoreMap::iterator itr = PlayerScores.find(player->GetGUID());
|
||||
if (itr == PlayerScores.end())
|
||||
return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SCORE_FLAG_CAPTURES:
|
||||
((BattlegroundWGScore*)itr->second)->FlagCaptures += value;
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_CAPTURE_FLAG);
|
||||
break;
|
||||
case SCORE_FLAG_RETURNS:
|
||||
((BattlegroundWGScore*)itr->second)->FlagReturns += value;
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE, WS_OBJECTIVE_RETURN_FLAG);
|
||||
break;
|
||||
default:
|
||||
Battleground::UpdatePlayerScore(player, type, value, doAddHonor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry const* BattlegroundWS::GetClosestGraveyard(Player* player)
|
||||
{
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
return sWorldSafeLocsStore.LookupEntry(player->GetTeamId() == TEAM_ALLIANCE ? WS_GRAVEYARD_MAIN_ALLIANCE : WS_GRAVEYARD_MAIN_HORDE);
|
||||
else
|
||||
return sWorldSafeLocsStore.LookupEntry(player->GetTeamId() == TEAM_ALLIANCE ? WS_GRAVEYARD_FLAGROOM_ALLIANCE : WS_GRAVEYARD_FLAGROOM_HORDE);
|
||||
}
|
||||
|
||||
void BattlegroundWS::FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
data << uint32(BG_WS_FLAG_CAPTURES_ALLIANCE) << uint32(GetTeamScore(TEAM_ALLIANCE));
|
||||
data << uint32(BG_WS_FLAG_CAPTURES_HORDE) << uint32(GetTeamScore(TEAM_HORDE));
|
||||
data << uint32(BG_WS_FLAG_CAPTURES_MAX) << uint32(BG_WS_MAX_TEAM_SCORE);
|
||||
|
||||
data << uint32(BG_WS_STATE_TIMER_ACTIVE) << uint32(GetStatus() == STATUS_IN_PROGRESS);
|
||||
data << uint32(BG_WS_STATE_TIMER) << uint32(GetMatchTime());
|
||||
|
||||
data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(GetFlagState(TEAM_HORDE));
|
||||
data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(GetFlagState(TEAM_ALLIANCE));
|
||||
}
|
||||
|
||||
TeamId BattlegroundWS::GetPrematureWinner()
|
||||
{
|
||||
if (GetTeamScore(TEAM_ALLIANCE) > GetTeamScore(TEAM_HORDE))
|
||||
return TEAM_ALLIANCE;
|
||||
|
||||
return GetTeamScore(TEAM_HORDE) > GetTeamScore(TEAM_ALLIANCE) ? TEAM_HORDE : Battleground::GetPrematureWinner();
|
||||
}
|
||||
|
||||
uint32 BattlegroundWS::GetAssaultSpellId() const
|
||||
{
|
||||
if ((GetFlagPickerGUID(TEAM_ALLIANCE) == 0 && GetFlagState(TEAM_ALLIANCE) != BG_WS_FLAG_STATE_ON_GROUND) ||
|
||||
(GetFlagPickerGUID(TEAM_HORDE) == 0 && GetFlagState(TEAM_HORDE) != BG_WS_FLAG_STATE_ON_GROUND) ||
|
||||
_bgEvents.GetNextEventTime(BG_WS_EVENT_BOTH_FLAGS_KEPT10) > 0)
|
||||
return 0;
|
||||
|
||||
return _bgEvents.GetNextEventTime(BG_WS_EVENT_BOTH_FLAGS_KEPT15) > 0 ? BG_WS_SPELL_FOCUSED_ASSAULT : BG_WS_SPELL_BRUTAL_ASSAULT;
|
||||
}
|
||||
|
||||
void BattlegroundWS::RemoveAssaultAuras()
|
||||
{
|
||||
if (Player* player = ObjectAccessor::GetObjectInMap(GetFlagPickerGUID(TEAM_ALLIANCE), this->FindBgMap(), (Player*)NULL))
|
||||
{
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_FOCUSED_ASSAULT);
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_BRUTAL_ASSAULT);
|
||||
}
|
||||
if (Player* player = ObjectAccessor::GetObjectInMap(GetFlagPickerGUID(TEAM_HORDE), this->FindBgMap(), (Player*)NULL))
|
||||
{
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_FOCUSED_ASSAULT);
|
||||
player->RemoveAurasDueToSpell(BG_WS_SPELL_BRUTAL_ASSAULT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef __BATTLEGROUNDWS_H
|
||||
#define __BATTLEGROUNDWS_H
|
||||
|
||||
#include "Battleground.h"
|
||||
|
||||
enum BG_WS_Events
|
||||
{
|
||||
BG_WS_EVENT_UPDATE_GAME_TIME = 1,
|
||||
BG_WS_EVENT_NO_TIME_LEFT = 2,
|
||||
BG_WS_EVENT_RESPAWN_BOTH_FLAGS = 3,
|
||||
BG_WS_EVENT_ALLIANCE_DROP_FLAG = 4,
|
||||
BG_WS_EVENT_HORDE_DROP_FLAG = 5,
|
||||
BG_WS_EVENT_BOTH_FLAGS_KEPT10 = 6,
|
||||
BG_WS_EVENT_BOTH_FLAGS_KEPT15 = 7
|
||||
};
|
||||
|
||||
enum BG_WS_TimerOrScore
|
||||
{
|
||||
BG_WS_MAX_TEAM_SCORE = 3,
|
||||
|
||||
BG_WS_TOTAL_GAME_TIME = 27*MINUTE*IN_MILLISECONDS,
|
||||
BG_WS_FLAG_RESPAWN_TIME = 23*IN_MILLISECONDS,
|
||||
BG_WS_FLAG_DROP_TIME = 10*IN_MILLISECONDS,
|
||||
BG_WS_SPELL_FORCE_TIME = 10*MINUTE*IN_MILLISECONDS,
|
||||
BG_WS_SPELL_BRUTAL_TIME = 15*MINUTE*IN_MILLISECONDS
|
||||
};
|
||||
|
||||
enum BG_WS_Sound
|
||||
{
|
||||
BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
|
||||
BG_WS_SOUND_FLAG_CAPTURED_HORDE = 8213,
|
||||
BG_WS_SOUND_FLAG_PLACED = 8232,
|
||||
BG_WS_SOUND_FLAG_RETURNED = 8192,
|
||||
BG_WS_SOUND_HORDE_FLAG_PICKED_UP = 8212,
|
||||
BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP = 8174,
|
||||
BG_WS_SOUND_FLAGS_RESPAWNED = 8232
|
||||
};
|
||||
|
||||
enum BG_WS_SpellId
|
||||
{
|
||||
BG_WS_SPELL_WARSONG_FLAG = 23333,
|
||||
BG_WS_SPELL_WARSONG_FLAG_DROPPED = 23334,
|
||||
BG_WS_SPELL_WARSONG_FLAG_PICKED = 61266, // fake spell, does not exist but used as timer start event
|
||||
BG_WS_SPELL_SILVERWING_FLAG = 23335,
|
||||
BG_WS_SPELL_SILVERWING_FLAG_DROPPED = 23336,
|
||||
BG_WS_SPELL_SILVERWING_FLAG_PICKED = 61265, // fake spell, does not exist but used as timer start event
|
||||
BG_WS_SPELL_FOCUSED_ASSAULT = 46392,
|
||||
BG_WS_SPELL_BRUTAL_ASSAULT = 46393
|
||||
};
|
||||
|
||||
enum BG_WS_WorldStates
|
||||
{
|
||||
BG_WS_FLAG_CAPTURES_ALLIANCE = 1581,
|
||||
BG_WS_FLAG_CAPTURES_HORDE = 1582,
|
||||
BG_WS_FLAG_CAPTURES_MAX = 1601,
|
||||
BG_WS_FLAG_STATE_HORDE = 2338,
|
||||
BG_WS_FLAG_STATE_ALLIANCE = 2339,
|
||||
BG_WS_STATE_TIMER = 4248,
|
||||
BG_WS_STATE_TIMER_ACTIVE = 4247
|
||||
};
|
||||
|
||||
enum BG_WS_ObjectTypes
|
||||
{
|
||||
BG_WS_OBJECT_DOOR_A_1 = 0,
|
||||
BG_WS_OBJECT_DOOR_A_2 = 1,
|
||||
BG_WS_OBJECT_DOOR_A_3 = 2,
|
||||
BG_WS_OBJECT_DOOR_A_4 = 3,
|
||||
BG_WS_OBJECT_DOOR_A_5 = 4,
|
||||
BG_WS_OBJECT_DOOR_A_6 = 5,
|
||||
BG_WS_OBJECT_DOOR_H_1 = 6,
|
||||
BG_WS_OBJECT_DOOR_H_2 = 7,
|
||||
BG_WS_OBJECT_DOOR_H_3 = 8,
|
||||
BG_WS_OBJECT_DOOR_H_4 = 9,
|
||||
BG_WS_OBJECT_A_FLAG = 10,
|
||||
BG_WS_OBJECT_H_FLAG = 11,
|
||||
BG_WS_OBJECT_SPEEDBUFF_1 = 12,
|
||||
BG_WS_OBJECT_SPEEDBUFF_2 = 13,
|
||||
BG_WS_OBJECT_REGENBUFF_1 = 14,
|
||||
BG_WS_OBJECT_REGENBUFF_2 = 15,
|
||||
BG_WS_OBJECT_BERSERKBUFF_1 = 16,
|
||||
BG_WS_OBJECT_BERSERKBUFF_2 = 17,
|
||||
BG_WS_OBJECT_MAX = 18
|
||||
};
|
||||
|
||||
enum BG_WS_ObjectEntry
|
||||
{
|
||||
BG_OBJECT_DOOR_A_1_WS_ENTRY = 179918,
|
||||
BG_OBJECT_DOOR_A_2_WS_ENTRY = 179919,
|
||||
BG_OBJECT_DOOR_A_3_WS_ENTRY = 179920,
|
||||
BG_OBJECT_DOOR_A_4_WS_ENTRY = 179921,
|
||||
BG_OBJECT_DOOR_A_5_WS_ENTRY = 180322,
|
||||
BG_OBJECT_DOOR_A_6_WS_ENTRY = 180322,
|
||||
BG_OBJECT_DOOR_H_1_WS_ENTRY = 179916,
|
||||
BG_OBJECT_DOOR_H_2_WS_ENTRY = 179917,
|
||||
BG_OBJECT_DOOR_H_3_WS_ENTRY = 180322,
|
||||
BG_OBJECT_DOOR_H_4_WS_ENTRY = 180322,
|
||||
BG_OBJECT_A_FLAG_WS_ENTRY = 179830,
|
||||
BG_OBJECT_H_FLAG_WS_ENTRY = 179831,
|
||||
BG_OBJECT_A_FLAG_GROUND_WS_ENTRY = 179785,
|
||||
BG_OBJECT_H_FLAG_GROUND_WS_ENTRY = 179786
|
||||
};
|
||||
|
||||
enum BG_WS_FlagState
|
||||
{
|
||||
BG_WS_FLAG_STATE_ON_BASE = 1,
|
||||
BG_WS_FLAG_STATE_ON_PLAYER = 2,
|
||||
BG_WS_FLAG_STATE_ON_GROUND = 3
|
||||
};
|
||||
|
||||
enum BG_WS_Graveyards
|
||||
{
|
||||
WS_GRAVEYARD_FLAGROOM_ALLIANCE = 769,
|
||||
WS_GRAVEYARD_FLAGROOM_HORDE = 770,
|
||||
WS_GRAVEYARD_MAIN_ALLIANCE = 771,
|
||||
WS_GRAVEYARD_MAIN_HORDE = 772
|
||||
};
|
||||
|
||||
enum BG_WS_CreatureTypes
|
||||
{
|
||||
WS_SPIRIT_MAIN_ALLIANCE = 0,
|
||||
WS_SPIRIT_MAIN_HORDE = 1,
|
||||
|
||||
BG_CREATURES_MAX_WS = 2
|
||||
};
|
||||
|
||||
|
||||
enum BG_WS_Objectives
|
||||
{
|
||||
WS_OBJECTIVE_CAPTURE_FLAG = 42,
|
||||
WS_OBJECTIVE_RETURN_FLAG = 44,
|
||||
|
||||
WS_EVENT_START_BATTLE = 8563
|
||||
};
|
||||
|
||||
struct BattlegroundWGScore : public BattlegroundScore
|
||||
{
|
||||
BattlegroundWGScore(Player* player): BattlegroundScore(player), FlagCaptures(0), FlagReturns(0) { }
|
||||
~BattlegroundWGScore() { }
|
||||
uint32 FlagCaptures;
|
||||
uint32 FlagReturns;
|
||||
};
|
||||
|
||||
class BattlegroundWS : public Battleground
|
||||
{
|
||||
public:
|
||||
/* Construction */
|
||||
BattlegroundWS();
|
||||
~BattlegroundWS();
|
||||
|
||||
/* inherited from BattlegroundClass */
|
||||
void AddPlayer(Player* player);
|
||||
void StartingEventCloseDoors();
|
||||
void StartingEventOpenDoors();
|
||||
|
||||
/* BG Flags */
|
||||
uint64 GetFlagPickerGUID(TeamId teamId) const { return _flagKeepers[teamId]; }
|
||||
void SetFlagPicker(uint64 guid, TeamId teamId) { _flagKeepers[teamId] = guid; }
|
||||
void RespawnFlagAfterDrop(TeamId teamId);
|
||||
uint8 GetFlagState(TeamId teamId) const { return _flagState[teamId]; }
|
||||
|
||||
/* Battleground Events */
|
||||
void EventPlayerDroppedFlag(Player* player);
|
||||
void EventPlayerClickedOnFlag(Player* player, GameObject* gameObject);
|
||||
void EventPlayerCapturedFlag(Player* player);
|
||||
|
||||
void RemovePlayer(Player* player);
|
||||
void HandleAreaTrigger(Player* player, uint32 trigger);
|
||||
void HandleKillPlayer(Player* player, Player* killer);
|
||||
bool SetupBattleground();
|
||||
void Init();
|
||||
void EndBattleground(TeamId winnerTeamId);
|
||||
WorldSafeLocsEntry const* GetClosestGraveyard(Player* player);
|
||||
|
||||
void UpdateFlagState(TeamId teamId, uint32 value);
|
||||
void UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true);
|
||||
void SetDroppedFlagGUID(uint64 guid, TeamId teamId) { _droppedFlagGUID[teamId] = guid; }
|
||||
uint64 GetDroppedFlagGUID(TeamId teamId) const { return _droppedFlagGUID[teamId];}
|
||||
void FillInitialWorldStates(WorldPacket& data);
|
||||
|
||||
/* Scorekeeping */
|
||||
void AddPoints(TeamId teamId, uint32 points) { m_TeamScores[teamId] += points; }
|
||||
|
||||
TeamId GetPrematureWinner();
|
||||
uint32 GetMatchTime() const { return 1 + (BG_WS_TOTAL_GAME_TIME - GetStartTime()) / (MINUTE*IN_MILLISECONDS); }
|
||||
uint32 GetAssaultSpellId() const;
|
||||
void RemoveAssaultAuras();
|
||||
|
||||
private:
|
||||
EventMap _bgEvents;
|
||||
|
||||
uint64 _flagKeepers[2];
|
||||
uint64 _droppedFlagGUID[2];
|
||||
uint8 _flagState[2];
|
||||
TeamId _lastFlagCaptureTeam;
|
||||
uint32 _reputationCapture;
|
||||
uint32 _honorWinKills;
|
||||
uint32 _honorEndKills;
|
||||
|
||||
void PostUpdateImpl(uint32 diff);
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user