*Massive cleanup (\n\n -> \n, *\n -> \n, cleanup for(...) to for (...), and some other cleanups by hand)

*Fix a possible crash in Spell::DoAllEffectOnTarget

--HG--
branch : trunk
This commit is contained in:
maximius
2009-10-17 15:35:07 -07:00
parent f21f47005d
commit 26b5e033ff
2257 changed files with 750 additions and 103852 deletions
-51
View File
@@ -17,53 +17,40 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Database/DatabaseEnv.h"
#include "Policies/SingletonImp.h"
#include "AccountMgr.h"
#include "ObjectAccessor.h"
#include "Player.h"
#include "Util.h"
#include "Auth/Sha1.h"
extern DatabaseType loginDatabase;
INSTANTIATE_SINGLETON_1(AccountMgr);
AccountMgr::AccountMgr()
{}
AccountMgr::~AccountMgr()
{}
AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password)
{
if(utf8length(username) > MAX_ACCOUNT_STR)
return AOR_NAME_TOO_LONG; // username's too long
normalizeString(username);
normalizeString(password);
if(GetId(username))
{
return AOR_NAME_ALREDY_EXIST; // username does already exist
}
if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s','%s',NOW())", username.c_str(), CalculateShaPassHash(username, password).c_str()))
return AOR_DB_INTERNAL_ERROR; // unexpected error
loginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist,account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL");
return AOR_OK; // everything's fine
}
AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
{
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
if(!result)
return AOR_NAME_NOT_EXIST; // account doesn't exist
delete result;
result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%d'",accid);
if (result)
{
@@ -72,7 +59,6 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
Field *fields = result->Fetch();
uint32 guidlo = fields[0].GetUInt32();
uint64 guid = MAKE_NEW_GUID(guidlo, 0, HIGHGUID_PLAYER);
// kick if player currently
if(Player* p = ObjectAccessor::GetObjectInWorld(guid, (Player*)NULL))
{
@@ -80,76 +66,54 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
s->KickPlayer(); // mark session to remove at next session list update
s->LogoutPlayer(false); // logout player without waiting next session list update
}
Player::DeleteFromDB(guid, accid, false); // no need to update realm characters
} while (result->NextRow());
delete result;
}
// table realm specific but common for all characters of account for realm
CharacterDatabase.PExecute("DELETE FROM character_tutorial WHERE account = '%u'",accid);
loginDatabase.BeginTransaction();
bool res =
loginDatabase.PExecute("DELETE FROM account WHERE id='%d'", accid) &&
loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid);
loginDatabase.CommitTransaction();
if(!res)
return AOR_DB_INTERNAL_ERROR; // unexpected error;
return AOR_OK;
}
AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd)
{
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
if(!result)
return AOR_NAME_NOT_EXIST; // account doesn't exist
delete result;
if(utf8length(new_uname) > MAX_ACCOUNT_STR)
return AOR_NAME_TOO_LONG;
if(utf8length(new_passwd) > MAX_ACCOUNT_STR)
return AOR_PASS_TOO_LONG;
normalizeString(new_uname);
normalizeString(new_passwd);
std::string safe_new_uname = new_uname;
loginDatabase.escape_string(safe_new_uname);
if(!loginDatabase.PExecute("UPDATE account SET v='0',s='0',username='%s',sha_pass_hash='%s' WHERE id='%d'", safe_new_uname.c_str(),
CalculateShaPassHash(new_uname, new_passwd).c_str(), accid))
return AOR_DB_INTERNAL_ERROR; // unexpected error
return AOR_OK;
}
AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
{
std::string username;
if(!GetName(accid, username))
return AOR_NAME_NOT_EXIST; // account doesn't exist
if (utf8length(new_passwd) > MAX_ACCOUNT_STR)
return AOR_PASS_TOO_LONG;
normalizeString(new_passwd);
// also reset s and v to force update at next realmd login
if(!loginDatabase.PExecute("UPDATE account SET v='0', s='0', sha_pass_hash='%s' WHERE id='%d'",
CalculateShaPassHash(username, new_passwd).c_str(), accid))
return AOR_DB_INTERNAL_ERROR; // unexpected error
return AOR_OK;
}
uint32 AccountMgr::GetId(std::string username)
{
loginDatabase.escape_string(username);
@@ -163,7 +127,6 @@ uint32 AccountMgr::GetId(std::string username)
return id;
}
}
uint32 AccountMgr::GetSecurity(uint32 acc_id)
{
QueryResult *result = loginDatabase.PQuery("SELECT gmlevel FROM account WHERE id = '%u'", acc_id);
@@ -173,10 +136,8 @@ uint32 AccountMgr::GetSecurity(uint32 acc_id)
delete result;
return sec;
}
return 0;
}
bool AccountMgr::GetName(uint32 acc_id, std::string &name)
{
QueryResult *result = loginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", acc_id);
@@ -186,41 +147,31 @@ bool AccountMgr::GetName(uint32 acc_id, std::string &name)
delete result;
return true;
}
return false;
}
bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
{
std::string username;
if(!GetName(accid, username))
return false;
normalizeString(passwd);
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash='%s'", accid, CalculateShaPassHash(username, passwd).c_str());
if (result)
{
delete result;
return true;
}
return false;
}
bool AccountMgr::normalizeString(std::string& utf8str)
{
wchar_t wstr_buf[MAX_ACCOUNT_STR+1];
size_t wstr_len = MAX_ACCOUNT_STR;
if(!Utf8toWStr(utf8str,wstr_buf,wstr_len))
return false;
std::transform( &wstr_buf[0], wstr_buf+wstr_len, &wstr_buf[0], wcharToUpperOnlyLatin );
return WStrToUtf8(wstr_buf,wstr_len,utf8str);
}
std::string AccountMgr::CalculateShaPassHash(std::string& name, std::string& password)
{
Sha1Hash sha;
@@ -229,10 +180,8 @@ std::string AccountMgr::CalculateShaPassHash(std::string& name, std::string& pas
sha.UpdateData(":");
sha.UpdateData(password);
sha.Finalize();
std::string encoded;
hexEncodeByteArray(sha.GetDigest(), sha.GetLength(), encoded);
return encoded;
}
-10
View File
@@ -17,15 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _ACCMGR_H
#define _ACCMGR_H
#include <string>
#include "Common.h"
#include "Policies/Singleton.h"
enum AccountOpResult
{
AOR_OK,
@@ -35,29 +31,23 @@ enum AccountOpResult
AOR_NAME_NOT_EXIST,
AOR_DB_INTERNAL_ERROR
};
#define MAX_ACCOUNT_STR 16
class AccountMgr
{
public:
AccountMgr();
~AccountMgr();
AccountOpResult CreateAccount(std::string username, std::string password);
AccountOpResult DeleteAccount(uint32 accid);
AccountOpResult ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd);
AccountOpResult ChangePassword(uint32 accid, std::string new_passwd);
bool CheckPassword(uint32 accid, std::string passwd);
uint32 GetId(std::string username);
uint32 GetSecurity(uint32 acc_id);
bool GetName(uint32 acc_id, std::string &name);
std::string CalculateShaPassHash(std::string& name, std::string& password);
static bool normalizeString(std::string& utf8str);
};
#define accmgr Trinity::Singleton<AccountMgr>::Instance()
#endif
File diff suppressed because it is too large Load Diff
-38
View File
@@ -17,29 +17,23 @@
*/
#ifndef __MANGOS_ACHIEVEMENTMGR_H
#define __MANGOS_ACHIEVEMENTMGR_H
#include <map>
#include <string>
#include "Common.h"
#include "Policies/Singleton.h"
#include "Database/DatabaseEnv.h"
#include "DBCEnums.h"
#include "DBCStores.h"
typedef std::list<AchievementCriteriaEntry const*> AchievementCriteriaEntryList;
typedef std::list<AchievementEntry const*> AchievementEntryList;
typedef std::map<uint32,AchievementCriteriaEntryList> AchievementCriteriaListByAchievement;
typedef std::map<uint32,AchievementEntryList> AchievementListByReferencedId;
struct CriteriaProgress
{
uint32 counter;
time_t date;
bool changed;
};
enum AchievementCriteriaDataType
{ // value1 value2 comment
ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0, // 0 0
@@ -61,12 +55,9 @@ enum AchievementCriteriaDataType
ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16,// holiday_id 0 event in holiday time
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17,// min_score max_score player's team win bg and opposition team have team score in range
};
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 18 // maximum value in AchievementCriteriaDataType enum
class Player;
class Unit;
struct AchievementCriteriaData
{
AchievementCriteriaDataType dataType;
@@ -160,23 +151,19 @@ struct AchievementCriteriaData
uint32 value2;
} raw;
};
AchievementCriteriaData() : dataType(ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE)
{
raw.value1 = 0;
raw.value2 = 0;
}
AchievementCriteriaData(uint32 _dataType, uint32 _value1, uint32 _value2) : dataType(AchievementCriteriaDataType(_dataType))
{
raw.value1 = _value1;
raw.value2 = _value2;
}
bool IsValid(AchievementCriteriaEntry const* criteria);
bool Meets(Player const* source, Unit const* target, uint32 miscvalue1 = 0) const;
};
struct AchievementCriteriaDataSet
{
typedef std::vector<AchievementCriteriaData> Storage;
@@ -186,9 +173,7 @@ struct AchievementCriteriaDataSet
Storage storage;
};
typedef std::map<uint32,AchievementCriteriaDataSet> AchievementCriteriaDataMap;
struct AchievementReward
{
uint32 titleId[2];
@@ -197,37 +182,29 @@ struct AchievementReward
std::string subject;
std::string text;
};
typedef std::map<uint32,AchievementReward> AchievementRewards;
struct AchievementRewardLocale
{
std::vector<std::string> subject;
std::vector<std::string> text;
};
typedef std::map<uint32,AchievementRewardLocale> AchievementRewardLocales;
struct CompletedAchievementData
{
time_t date;
bool changed;
};
typedef UNORDERED_MAP<uint32, CriteriaProgress> CriteriaProgressMap;
typedef UNORDERED_MAP<uint32, CompletedAchievementData> CompletedAchievementMap;
class Unit;
class Player;
class WorldPacket;
class AchievementMgr
{
public:
AchievementMgr(Player* pl);
~AchievementMgr();
void Reset();
static void DeleteFromDB(uint32 lowguid);
void LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult);
@@ -239,7 +216,6 @@ class AchievementMgr
void SendAllAchievementData();
void SendRespondInspectAchievements(Player* player);
Player* GetPlayer() { return m_player;}
private:
enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST };
void SendAchievementEarned(AchievementEntry const* achievement);
@@ -250,12 +226,10 @@ class AchievementMgr
bool IsCompletedAchievement(AchievementEntry const* entry);
void CompleteAchievementsWithRefs(AchievementEntry const* entry);
void BuildAllDataPacket(WorldPacket *data);
Player* m_player;
CriteriaProgressMap m_criteriaProgress;
CompletedAchievementMap m_completedAchievements;
};
class AchievementGlobalMgr
{
public:
@@ -265,41 +239,34 @@ class AchievementGlobalMgr
AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id);
return itr != m_AchievementCriteriaListByAchievement.end() ? &itr->second : NULL;
}
AchievementEntryList const* GetAchievementByReferencedId(uint32 id) const
{
AchievementListByReferencedId::const_iterator itr = m_AchievementListByReferencedId.find(id);
return itr != m_AchievementListByReferencedId.end() ? &itr->second : NULL;
}
AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const
{
AchievementRewards::const_iterator iter = m_achievementRewards.find(achievement->ID);
return iter!=m_achievementRewards.end() ? &iter->second : NULL;
}
AchievementRewardLocale const* GetAchievementRewardLocale(AchievementEntry const* achievement) const
{
AchievementRewardLocales::const_iterator iter = m_achievementRewardLocales.find(achievement->ID);
return iter!=m_achievementRewardLocales.end() ? &iter->second : NULL;
}
AchievementCriteriaDataSet const* GetCriteriaDataSet(AchievementCriteriaEntry const *achievementCriteria)
{
AchievementCriteriaDataMap::const_iterator iter = m_criteriaDataMap.find(achievementCriteria->ID);
return iter!=m_criteriaDataMap.end() ? &iter->second : NULL;
}
bool IsRealmCompleted(AchievementEntry const* achievement) const
{
return m_allCompletedAchievements.find(achievement->ID) != m_allCompletedAchievements.end();
}
void SetRealmCompleted(AchievementEntry const* achievement)
{
m_allCompletedAchievements.insert(achievement->ID);
}
void LoadAchievementCriteriaList();
void LoadAchievementCriteriaData();
void LoadAchievementReferenceList();
@@ -308,21 +275,16 @@ class AchievementGlobalMgr
void LoadRewardLocales();
private:
AchievementCriteriaDataMap m_criteriaDataMap;
// store achievement criterias by type to speed up lookup
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
// store achievement criterias by achievement to speed up lookup
AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement;
// store achievements by referenced achievement id to speed up lookup
AchievementListByReferencedId m_AchievementListByReferencedId;
typedef std::set<uint32> AllCompletedAchievements;
AllCompletedAchievements m_allCompletedAchievements;
AchievementRewards m_achievementRewards;
AchievementRewardLocales m_achievementRewardLocales;
};
#define achievementmgr Trinity::Singleton<AchievementGlobalMgr>::Instance()
#endif
-2
View File
@@ -17,10 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_ANIMAL_RANDOMMOVEMENTGENERATOR_H
#define TRINITY_ANIMAL_RANDOMMOVEMENTGENERATOR_H
/** AnimalRandomMovementGenerator follows the research on
* quantifying scale-dependant effects of animal movement
* with simple per-location models (R.H. Gardner, R.V. O'Neil,
-90
View File
@@ -15,13 +15,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ObjectMgr.h"
#include "WorldPacket.h"
#include "ArenaTeam.h"
#include "World.h"
void ArenaTeamMember::ModifyPersonalRating(Player* plr, int32 mod, uint32 slot)
{
int32 memberRating = int32(personal_rating) + mod;
@@ -30,7 +27,6 @@ void ArenaTeamMember::ModifyPersonalRating(Player* plr, int32 mod, uint32 slot)
plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot*6) + 5, personal_rating);
//sLog.outArena("Modify personal rating for player %s: personal rating %u, mod %d, rating %d", plr->GetName(), personal_rating, mod, rating);
}
ArenaTeam::ArenaTeam()
{
m_TeamId = 0;
@@ -52,29 +48,22 @@ ArenaTeam::ArenaTeam()
m_stats.wins_week = 0;
m_stats.wins_season = 0;
}
ArenaTeam::~ArenaTeam()
{
}
bool ArenaTeam::Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName)
{
if(!objmgr.GetPlayer(captainGuid)) // player not exist
return false;
if(objmgr.GetArenaTeamByName(ArenaTeamName)) // arena team with this name already exist
return false;
sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(captainGuid));
m_CaptainGuid = captainGuid;
m_Name = ArenaTeamName;
m_Type = type;
m_TeamId = objmgr.GenerateArenaTeamId();
// ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB
CharacterDatabase.escape_string(ArenaTeamName);
CharacterDatabase.BeginTransaction();
// CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", m_TeamId); - MAX(arenateam)+1 not exist
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", m_TeamId);
@@ -83,23 +72,18 @@ bool ArenaTeam::Create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam
m_TeamId, ArenaTeamName.c_str(), GUID_LOPART(m_CaptainGuid), m_Type, m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor);
CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES "
"('%u', '%u', '%u', '%u', '%u', '%u', '%u')", m_TeamId, m_stats.rating, m_stats.games_week, m_stats.wins_week, m_stats.games_season, m_stats.wins_season, m_stats.rank);
CharacterDatabase.CommitTransaction();
AddMember(m_CaptainGuid);
sLog.outArena("New ArenaTeam created [Id: %u] [Type: %u] [Captain GUID: %u]", GetId(), GetType(), GetCaptain());
return true;
}
bool ArenaTeam::AddMember(const uint64& PlayerGuid)
{
std::string plName;
uint8 plClass;
// arena team is full (can't have more than type * 2 players!)
if(GetMembersSize() >= GetType() * 2)
return false;
Player *pl = objmgr.GetPlayer(PlayerGuid);
if(pl)
{
@@ -108,7 +92,6 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
sLog.outError("Arena::AddMember() : player already in this sized team");
return false;
}
plClass = (uint8)pl->getClass();
plName = pl->GetName();
}
@@ -118,11 +101,9 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
QueryResult *result = CharacterDatabase.PQuery("SELECT name, class FROM characters WHERE guid='%u'", GUID_LOPART(PlayerGuid));
if(!result)
return false;
plName = (*result)[0].GetCppString();
plClass = (*result)[1].GetUInt8();
delete result;
// check if player already in arenateam of that size
if(Player::GetArenaTeamIdFromDB(PlayerGuid, GetType()) != 0)
{
@@ -130,11 +111,9 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
return false;
}
}
// remove all player signs from another petitions
// this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity
Player::RemovePetitionsAndSigns(PlayerGuid, GetType());
ArenaTeamMember newmember;
newmember.name = plName;
newmember.guid = PlayerGuid;
@@ -155,15 +134,12 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
newmember.personal_rating = 1500;
}
m_members.push_back(newmember);
CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid, guid, personal_rating) VALUES ('%u', '%u', '%u')", m_TeamId, GUID_LOPART(newmember.guid), newmember.personal_rating );
if(pl)
{
pl->SetInArenaTeam(m_TeamId, GetSlot());
pl->SetArenaTeamIdInvited(0);
pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, newmember.personal_rating );
// hide promote/remove buttons
if(m_CaptainGuid != PlayerGuid)
pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 1, 1);
@@ -171,16 +147,12 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
}
return true;
}
bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId)
{
QueryResult *result = CharacterDatabase.PQuery("SELECT arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor FROM arena_team WHERE arenateamid = '%u'", ArenaTeamId);
if(!result)
return false;
Field *fields = result->Fetch();
m_TeamId = fields[0].GetUInt32();
m_Name = fields[1].GetCppString();
m_CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
@@ -190,13 +162,10 @@ bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId)
m_EmblemColor = fields[6].GetUInt32();
m_BorderStyle = fields[7].GetUInt32();
m_BorderColor = fields[8].GetUInt32();
delete result;
// only load here, so additional checks can be made
LoadStatsFromDB(ArenaTeamId);
LoadMembersFromDB(ArenaTeamId);
if(Empty())
{
// arena team is empty, delete from db
@@ -207,30 +176,23 @@ bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId)
CharacterDatabase.CommitTransaction();
return false;
}
return true;
}
void ArenaTeam::LoadStatsFromDB(uint32 ArenaTeamId)
{
// 0 1 2 3 4 5
QueryResult *result = CharacterDatabase.PQuery("SELECT rating,games,wins,played,wins2,rank FROM arena_team_stats WHERE arenateamid = '%u'", ArenaTeamId);
if(!result)
return;
Field *fields = result->Fetch();
m_stats.rating = fields[0].GetUInt32();
m_stats.games_week = fields[1].GetUInt32();
m_stats.wins_week = fields[2].GetUInt32();
m_stats.games_season = fields[3].GetUInt32();
m_stats.wins_season = fields[4].GetUInt32();
m_stats.rank = fields[5].GetUInt32();
delete result;
}
void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
{
// 0 1 2 3 4 5 6 7
@@ -240,7 +202,6 @@ void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
"WHERE member.arenateamid = '%u'", ArenaTeamId);
if(!result)
return;
do
{
Field *fields = result->Fetch();
@@ -257,20 +218,16 @@ void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
}while( result->NextRow() );
delete result;
}
void ArenaTeam::SetCaptain(const uint64& guid)
{
// disable remove/promote buttons
Player *oldcaptain = objmgr.GetPlayer(GetCaptain());
if(oldcaptain)
oldcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
// set new captain
m_CaptainGuid = guid;
// update database
CharacterDatabase.PExecute("UPDATE arena_team SET captainguid = '%u' WHERE arenateamid = '%u'", GUID_LOPART(guid), m_TeamId);
// enable remove/promote buttons
Player *newcaptain = objmgr.GetPlayer(guid);
if(newcaptain)
@@ -279,7 +236,6 @@ void ArenaTeam::SetCaptain(const uint64& guid)
sLog.outArena("Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].", oldcaptain->GetName(), oldcaptain->GetGUIDLow(), newcaptain->GetName(), newcaptain->GetGUID(), GetId(), GetType());
}
}
void ArenaTeam::DelMember(uint64 guid)
{
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
@@ -290,9 +246,7 @@ void ArenaTeam::DelMember(uint64 guid)
break;
}
}
Player *player = objmgr.GetPlayer(guid);
if(player)
{
player->SetInArenaTeam(0, GetSlot());
@@ -306,23 +260,19 @@ void ArenaTeam::DelMember(uint64 guid)
}
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u' AND guid = '%u'", GetId(), GUID_LOPART(guid));
}
void ArenaTeam::Disband(WorldSession *session)
{
// event
WorldPacket data;
session->BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_DISBANDED_S, 2, session->GetPlayerName(), GetName(), "");
BroadcastPacket(&data);
while (!m_members.empty())
{
// Removing from members is done in DelMember.
DelMember(m_members.front().guid);
}
if(Player *player = session->GetPlayer())
sLog.outArena("Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId());
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", m_TeamId);
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", m_TeamId); //< this should be alredy done by calling DelMember(memberGuids[j]); for each member
@@ -330,23 +280,18 @@ void ArenaTeam::Disband(WorldSession *session)
CharacterDatabase.CommitTransaction();
objmgr.RemoveArenaTeam(m_TeamId);
}
void ArenaTeam::Roster(WorldSession *session)
{
Player *pl = NULL;
uint8 unk308 = 0;
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 = m_members.begin(); itr != m_members.end(); ++itr)
{
pl = objmgr.GetPlayer(itr->guid);
data << uint64(itr->guid); // guid
data << uint8((pl ? 1 : 0)); // online flag
data << itr->name; // member name
@@ -364,11 +309,9 @@ void ArenaTeam::Roster(WorldSession *session)
data << float(0.0); // 308 unk
}
}
session->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER");
}
void ArenaTeam::Query(WorldSession *session)
{
WorldPacket data(SMSG_ARENA_TEAM_QUERY_RESPONSE, 4*7+GetName().size()+1);
@@ -383,7 +326,6 @@ void ArenaTeam::Query(WorldSession *session)
session->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE");
}
void ArenaTeam::Stats(WorldSession *session)
{
WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7);
@@ -396,7 +338,6 @@ void ArenaTeam::Stats(WorldSession *session)
data << uint32(m_stats.rank); // rank
session->SendPacket(&data);
}
void ArenaTeam::NotifyStatsChanged()
{
// this is called after a rated match ended
@@ -408,13 +349,11 @@ void ArenaTeam::NotifyStatsChanged()
Stats(plr->GetSession());
}
}
void ArenaTeam::InspectStats(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)
@@ -426,7 +365,6 @@ void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
data << uint32(member->personal_rating); // personal rating
session->SendPacket(&data);
}
void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor)
{
m_BackgroundColor = backgroundColor;
@@ -434,10 +372,8 @@ void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emb
m_EmblemColor = emblemColor;
m_BorderStyle = borderStyle;
m_BorderColor = borderColor;
CharacterDatabase.PExecute("UPDATE arena_team SET BackgroundColor='%u', EmblemStyle='%u', EmblemColor='%u', BorderStyle='%u', BorderColor='%u' WHERE arenateamid='%u'", m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor, m_TeamId);
}
void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
{
switch(stat_type)
@@ -471,7 +407,6 @@ void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
break;
}
}
void ArenaTeam::BroadcastPacket(WorldPacket *packet)
{
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
@@ -481,7 +416,6 @@ void ArenaTeam::BroadcastPacket(WorldPacket *packet)
player->GetSession()->SendPacket(packet);
}
}
uint8 ArenaTeam::GetSlotByType( uint32 type )
{
switch(type)
@@ -495,56 +429,45 @@ uint8 ArenaTeam::GetSlotByType( uint32 type )
sLog.outError("FATAL: Unknown arena team type %u for some arena team", type);
return 0xFF;
}
bool ArenaTeam::HaveMember( const uint64& guid ) const
{
for (MemberList::const_iterator itr = m_members.begin(); itr != m_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 < m_stats.rating ? MemberRating : m_stats.rating;
if(rating<=1500)
// points = (float)1500 * 0.22f + 14.0f;
points = 344.0f; // 3.1 change - teams with rating below 1500 get arena points for 1500 rating
else
points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating));
// type penalties for <5v5 teams
if(m_Type == ARENA_TEAM_2v2)
points *= 0.76f;
else if(m_Type == ARENA_TEAM_3v3)
points *= 0.88f;
return (uint32) points;
}
float ArenaTeam::GetChanceAgainst(uint32 own_rating, uint32 enemy_rating)
{
// returns the chance to win against a team with the given rating, used in the rating adjustment calculation
// ELO system
if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
if (enemy_rating < 1300)
enemy_rating = 1300;
return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)enemy_rating - (float)own_rating)/400.0f));
}
void ArenaTeam::FinishGame(int32 mod)
{
if (int32(m_stats.rating) + mod < 0)
m_stats.rating = 0;
else
m_stats.rating += mod;
m_stats.games_week += 1;
m_stats.games_season += 1;
// update team's rank
@@ -556,7 +479,6 @@ void ArenaTeam::FinishGame(int32 mod)
++m_stats.rank;
}
}
int32 ArenaTeam::WonAgainst(uint32 againstRating)
{
// called when the team has won
@@ -568,11 +490,9 @@ int32 ArenaTeam::WonAgainst(uint32 againstRating)
FinishGame(mod);
m_stats.wins_week += 1;
m_stats.wins_season += 1;
// return the rating change, used to display it on the results screen
return mod;
}
int32 ArenaTeam::LostAgainst(uint32 againstRating)
{
// called when the team has lost
@@ -582,11 +502,9 @@ int32 ArenaTeam::LostAgainst(uint32 againstRating)
int32 mod = (int32)ceil(32.0f * (0.0f - chance));
// modify the team stats accordingly
FinishGame(mod);
// return the rating change, used to display it on the results screen
return mod;
}
void ArenaTeam::MemberLost(Player * plr, uint32 againstRating)
{
// called for each participant of a match after losing
@@ -608,7 +526,6 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstRating)
}
}
}
void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating)
{
// called for offline player after ending rated arena match!
@@ -630,7 +547,6 @@ void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating)
}
}
}
void ArenaTeam::MemberWon(Player * plr, uint32 againstRating)
{
// called for each participant after winning a match
@@ -654,7 +570,6 @@ void ArenaTeam::MemberWon(Player * plr, uint32 againstRating)
}
}
}
void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints)
{
// called after a match has ended and the stats are already modified
@@ -671,7 +586,6 @@ void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints)
if (itr->games_week >= min_plays)
points_to_add = GetPoints(itr->personal_rating);
// OBSOLETE : CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, m_TeamId, itr->guid);
std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.find(GUID_LOPART(itr->guid));
if (plr_itr != PlayerPoints.end())
{
@@ -683,7 +597,6 @@ void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints)
PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add;
}
}
void ArenaTeam::SaveToDB()
{
// save team and member stats to db
@@ -696,7 +609,6 @@ void ArenaTeam::SaveToDB()
}
CharacterDatabase.CommitTransaction();
}
void ArenaTeam::FinishWeek()
{
m_stats.games_week = 0; // played this week
@@ -707,7 +619,6 @@ void ArenaTeam::FinishWeek()
itr->wins_week = 0;
}
}
bool ArenaTeam::IsFighting() const
{
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
@@ -720,7 +631,6 @@ bool ArenaTeam::IsFighting() const
}
return false;
}
/*
arenateam fields (id from 2.3.3 client):
1414 - arena team id 2v2
-37
View File
@@ -17,10 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_ARENATEAM_H
#define TRINITYCORE_ARENATEAM_H
enum ArenaTeamCommandTypes
{
ERR_ARENA_TEAM_CREATE_S = 0x00,
@@ -29,7 +27,6 @@ enum ArenaTeamCommandTypes
ERR_ARENA_TEAM_QUIT_S = 0x03,
ERR_ARENA_TEAM_FOUNDER_S = 0x0C // need check, probably wrong...
};
enum ArenaTeamCommandErrors
{
//ARENA_TEAM_PLAYER_NO_MORE_IN_ARENA_TEAM = 0x00,
@@ -49,7 +46,6 @@ enum ArenaTeamCommandErrors
ERR_ARENA_TEAM_PLAYER_TO_LOW = 0x15,
ERR_ARENA_TEAM_FULL = 0x16
};
enum ArenaTeamEvents
{
ERR_ARENA_TEAM_JOIN_SS = 3, // player name + arena team name
@@ -59,7 +55,6 @@ enum ArenaTeamEvents
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
@@ -67,7 +62,6 @@ ERR_ARENA_TEAM_TARGET_TOO_LOW_S
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S
ERR_ARENA_TEAM_LEVEL_TOO_LOW_I
*/
enum ArenaTeamStatTypes
{
STAT_TYPE_RATING = 0,
@@ -77,14 +71,12 @@ enum ArenaTeamStatTypes
STAT_TYPE_WINS_SEASON = 4,
STAT_TYPE_RANK = 5
};
enum ArenaTeamTypes
{
ARENA_TEAM_2v2 = 2,
ARENA_TEAM_3v3 = 3,
ARENA_TEAM_5v5 = 5
};
struct ArenaTeamMember
{
uint64 guid;
@@ -95,10 +87,8 @@ struct ArenaTeamMember
uint32 games_season;
uint32 wins_season;
uint32 personal_rating;
void ModifyPersonalRating(Player* plr, int32 mod, uint32 slot);
};
struct ArenaTeamStats
{
uint32 rating;
@@ -108,20 +98,15 @@ struct ArenaTeamStats
uint32 wins_season;
uint32 rank;
};
#define MAX_ARENA_SLOT 3 // 0..2 slots
class ArenaTeam
{
public:
ArenaTeam();
~ArenaTeam();
bool Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName);
void Disband(WorldSession *session);
typedef std::list<ArenaTeamMember> MemberList;
uint32 GetId() const { return m_TeamId; }
uint32 GetType() const { return m_Type; }
uint8 GetSlot() const { return GetSlotByType(GetType()); }
@@ -131,61 +116,46 @@ class ArenaTeam
const ArenaTeamStats& GetStats() const { return m_stats; }
void SetStats(uint32 stat_type, uint32 value);
uint32 GetRating() const { return m_stats.rating; }
uint32 GetEmblemStyle() const { return m_EmblemStyle; }
uint32 GetEmblemColor() const { return m_EmblemColor; }
uint32 GetBorderStyle() const { return m_BorderStyle; }
uint32 GetBorderColor() const { return m_BorderColor; }
uint32 GetBackgroundColor() const { return m_BackgroundColor; }
void SetCaptain(const uint64& guid);
bool AddMember(const uint64& PlayerGuid);
// Shouldn't be const 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);
void SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor);
size_t GetMembersSize() const { return m_members.size(); }
bool Empty() const { return m_members.empty(); }
MemberList::iterator m_membersBegin() { return m_members.begin(); }
MemberList::iterator m_membersEnd() { return m_members.end(); }
bool HaveMember(const uint64& guid) const;
ArenaTeamMember* GetMember(const uint64& guid)
{
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if(itr->guid == guid)
return &(*itr);
return NULL;
}
ArenaTeamMember* GetMember(const std::string& name)
{
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if(itr->name == name)
return &(*itr);
return NULL;
}
bool IsFighting() const;
bool LoadArenaTeamFromDB(uint32 ArenaTeamId);
void LoadMembersFromDB(uint32 ArenaTeamId);
void LoadStatsFromDB(uint32 ArenaTeamId);
void SaveToDB();
void BroadcastPacket(WorldPacket *packet);
void Roster(WorldSession *session);
void Query(WorldSession *session);
void Stats(WorldSession *session);
void InspectStats(WorldSession *session, uint64 guid);
uint32 GetPoints(uint32 MemberRating);
float GetChanceAgainst(uint32 own_rating, uint32 enemy_rating);
int32 WonAgainst(uint32 againstRating);
@@ -193,27 +163,20 @@ class ArenaTeam
int32 LostAgainst(uint32 againstRating);
void MemberLost(Player * plr, uint32 againstRating);
void OfflineMemberLost(uint64 guid, uint32 againstRating);
void UpdateArenaPointsHelper(std::map<uint32, uint32> & PlayerPoints);
void NotifyStatsChanged();
void FinishWeek();
void FinishGame(int32 mod);
protected:
uint32 m_TeamId;
uint32 m_Type;
std::string m_Name;
uint64 m_CaptainGuid;
uint32 m_BackgroundColor; // ARGB format
uint32 m_EmblemStyle; // icon id
uint32 m_EmblemColor; // ARGB format
uint32 m_BorderStyle; // border image id
uint32 m_BorderColor; // ARGB format
MemberList m_members;
ArenaTeamStats m_stats;
};
-85
View File
@@ -17,26 +17,21 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Player.h"
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Database/DatabaseEnv.h"
#include "ArenaTeam.h"
#include "Log.h"
#include "ObjectMgr.h"
#include "SocialMgr.h"
void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket & recv_data)
{
sLog.outDebug("MSG_INSPECT_ARENA_TEAMS");
uint64 guid;
recv_data >> guid;
sLog.outDebug("Inspect Arena stats (GUID: %u TypeId: %u)", GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)));
if(Player *plr = objmgr.GetPlayer(guid))
{
for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
@@ -49,160 +44,123 @@ void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket & recv_data)
}
}
}
void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data)
{
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_QUERY" );
uint32 ArenaTeamId;
recv_data >> ArenaTeamId;
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
if(!arenateam) // arena team not found
return;
arenateam->Query(this);
arenateam->Stats(this);
}
void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data)
{
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_ROSTER" );
uint32 ArenaTeamId; // arena team id
recv_data >> ArenaTeamId;
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
if(!arenateam)
return;
arenateam->Roster(this);
}
void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_INVITE");
uint32 ArenaTeamId; // arena team id
std::string Invitedname;
Player * player = NULL;
recv_data >> ArenaTeamId >> Invitedname;
if(!Invitedname.empty())
{
if(!normalizePlayerName(Invitedname))
return;
player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str());
}
if(!player)
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
return;
}
if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", player->GetName(), ERR_ARENA_TEAM_PLAYER_TO_LOW);
return;
}
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
if(!arenateam)
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM);
return;
}
// OK result but not send invite
if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
return;
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
return;
}
if(player->GetArenaTeamId(arenateam->GetSlot()))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S);
return;
}
if(player->GetArenaTeamIdInvited())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
return;
}
if(arenateam->GetMembersSize() >= arenateam->GetType() * 2)
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,arenateam->GetName(),"",ERR_ARENA_TEAM_FULL);
return;
}
sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str());
player->SetArenaTeamIdInvited(arenateam->GetId());
WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10));
data << GetPlayer()->GetName();
data << arenateam->GetName();
player->GetSession()->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_INVITE");
}
void WorldSession::HandleArenaTeamAcceptOpcode(WorldPacket & /*recv_data*/)
{
sLog.outDebug("CMSG_ARENA_TEAM_ACCEPT"); // empty opcode
ArenaTeam *at = objmgr.GetArenaTeamById(_player->GetArenaTeamIdInvited());
if(!at)
return;
if(_player->GetArenaTeamId(at->GetSlot()))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ALREADY_IN_ARENA_TEAM); // already in arena team that size
return;
}
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != objmgr.GetPlayerTeamByGUID(at->GetCaptain()))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ARENA_TEAM_NOT_ALLIED);// not let enemies sign petition
return;
}
if(!at->AddMember(_player->GetGUID()))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ARENA_TEAM_INTERNAL);// arena team not found
return;
}
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_JOIN_SS, 2, _player->GetName(), at->GetName(), "");
at->BroadcastPacket(&data);
}
void WorldSession::HandleArenaTeamDeclineOpcode(WorldPacket & /*recv_data*/)
{
sLog.outDebug("CMSG_ARENA_TEAM_DECLINE"); // empty opcode
_player->SetArenaTeamIdInvited(0); // no more invited
}
void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_LEAVE");
uint32 ArenaTeamId; // arena team id
recv_data >> ArenaTeamId;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
return;
@@ -219,124 +177,94 @@ void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data)
delete at;
return;
}
at->DelMember(_player->GetGUID());
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEAVE_SS, 2, _player->GetName(), at->GetName(), "");
at->BroadcastPacket(&data);
//send you are no longer member of team
SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0);
}
void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_DISBAND");
uint32 ArenaTeamId; // arena team id
recv_data >> ArenaTeamId;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
return;
if(at->GetCaptain() != _player->GetGUID())
return;
if (at->IsFighting())
return;
at->Disband(this);
delete at;
}
void WorldSession::HandleArenaTeamRemoveOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_REMOVE");
uint32 ArenaTeamId;
std::string name;
recv_data >> ArenaTeamId;
recv_data >> name;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at) // arena team not found
return;
if(at->GetCaptain() != _player->GetGUID())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
if(!normalizePlayerName(name))
return;
ArenaTeamMember* member = at->GetMember(name);
if(!member) // member not found
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
return;
}
if(at->GetCaptain() == member->guid)
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
return;
}
at->DelMember(member->guid);
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_REMOVE_SSS, 3, name, at->GetName(), _player->GetName());
at->BroadcastPacket(&data);
}
void WorldSession::HandleArenaTeamLeaderOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_LEADER");
uint32 ArenaTeamId;
std::string name;
recv_data >> ArenaTeamId;
recv_data >> name;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at) // arena team not found
return;
if(at->GetCaptain() != _player->GetGUID())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
if(!normalizePlayerName(name))
return;
ArenaTeamMember* member = at->GetMember(name);
if(!member) // member not found
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
return;
}
if(at->GetCaptain() == member->guid) // target player already captain
return;
at->SetCaptain(member->guid);
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEADER_CHANGED_SSS, 3, _player->GetName(), name, at->GetName());
at->BroadcastPacket(&data);
}
void WorldSession::SendArenaTeamCommandResult(uint32 team_action, const std::string& team, const std::string& player, uint32 error_id)
{
WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+team.length()+1+player.length()+1+4);
@@ -346,7 +274,6 @@ void WorldSession::SendArenaTeamCommandResult(uint32 team_action, const std::str
data << error_id;
SendPacket(&data);
}
void WorldSession::BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, uint8 str_count, const std::string& str1, const std::string& str2, const std::string& str3)
{
data->Initialize(SMSG_ARENA_TEAM_EVENT, 1+1+1);
@@ -371,7 +298,6 @@ void WorldSession::BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, u
return;
}
}
void WorldSession::SendNotInArenaTeamPacket(uint8 type)
{
WorldPacket data(SMSG_ARENA_ERROR, 4+1); // 886 - You are not in a %uv%u arena team
@@ -381,15 +307,12 @@ void WorldSession::SendNotInArenaTeamPacket(uint8 type)
data << uint8(type); // team type (2=2v2,3=3v3,5=5v5), can be used for custom types...
SendPacket(&data);
}
/*
+ERR_ARENA_NO_TEAM_II "You are not in a %dv%d arena team"
+ERR_ARENA_TEAM_CREATE_S "%s created. To disband, use /teamdisband [2v2, 3v3, 5v5]."
+ERR_ARENA_TEAM_INVITE_SS "You have invited %s to join %s"
+ERR_ARENA_TEAM_QUIT_S "You are no longer a member of %s"
ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To leave, use /teamquit [2v2, 3v3, 5v5]."
+ERR_ARENA_TEAM_INTERNAL "Internal arena team error"
+ERR_ALREADY_IN_ARENA_TEAM "You are already in an arena team of that size"
+ERR_ALREADY_IN_ARENA_TEAM_S "%s is already in an arena team of that size"
@@ -403,23 +326,15 @@ ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS "%s is not in %s"
+ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S "\"%s\" not found"
+ERR_ARENA_TEAM_NOT_ALLIED "You cannot invite players from the opposing alliance"
+ERR_ARENA_TEAM_JOIN_SS "%s has joined %s"
+ERR_ARENA_TEAM_YOU_JOIN_S "You have joined %s. To leave, use /teamquit [2v2, 3v3, 5v5]."
+ERR_ARENA_TEAM_LEAVE_SS "%s has left %s"
+ERR_ARENA_TEAM_LEADER_IS_SS "%s is the captain of %s"
+ERR_ARENA_TEAM_LEADER_CHANGED_SSS "%s has made %s the new captain of %s"
+ERR_ARENA_TEAM_REMOVE_SSS "%s has been kicked out of %s by %s"
+ERR_ARENA_TEAM_DISBANDED_S "%s has disbanded %s"
ERR_ARENA_TEAM_TARGET_TOO_LOW_S "%s is not high enough level to join your team"
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S "%s is full"
ERR_ARENA_TEAM_LEVEL_TOO_LOW_I "You must be level %d to form an arena team"
*/
-172
View File
@@ -2,10 +2,8 @@
#include "AuctionHouseMgr.h"
#include "AuctionHouseBot.h"
#include <vector>
#include "Policies/SingletonImp.h"
INSTANTIATE_SINGLETON_1(AuctionHouseBot);
using namespace std;
vector<uint32> npcItems;
vector<uint32> lootItems;
@@ -29,22 +27,18 @@ AuctionHouseBot::AuctionHouseBot()
debug_Out_Filters = false;
AHBSeller = false;
AHBBuyer = false;
//Begin Filters
Vendor_Items = false;
Loot_Items = false;
Other_Items = false;
Vendor_TGs = false;
Loot_TGs = false;
Other_TGs = false;
No_Bind = false;
Bind_When_Picked_Up = false;
Bind_When_Equipped = false;
Bind_When_Use = false;
Bind_Quest_Item = false;
DisableBeta_PTR_Unused = false;
DisablePermEnchant = false;
#if CLIENT_VER > 300
@@ -57,7 +51,6 @@ AuctionHouseBot::AuctionHouseBot()
DisableKeys = false;
DisableDuration = false;
DisableBOP_Or_Quest_NoReqLevel = false;
DisableWarriorItems = false;
DisablePaladinItems = false;
DisableHunterItems = false;
@@ -69,7 +62,6 @@ AuctionHouseBot::AuctionHouseBot()
DisableWarlockItems = false;
DisableUnusedClassItems = false;
DisableDruidItems = false;
DisableItemsBelowLevel = 0;
DisableItemsAboveLevel = 0;
DisableTGsBelowLevel = 0;
@@ -86,22 +78,17 @@ AuctionHouseBot::AuctionHouseBot()
DisableItemsAboveReqSkillRank = 0;
DisableTGsBelowReqSkillRank = 0;
DisableTGsAboveReqSkillRank = 0;
//End Filters
_lastrun_a = time(NULL);
_lastrun_h = time(NULL);
_lastrun_n = time(NULL);
AllianceConfig = AHBConfig(2);
HordeConfig = AHBConfig(6);
NeutralConfig = AHBConfig(7);
}
AuctionHouseBot::~AuctionHouseBot()
{
}
void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
{
if (!AHBSeller)
@@ -109,16 +96,13 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
if (debug_Out) sLog.outError("AHSeller: Disabled");
return;
}
uint32 minItems = config->GetMinItems();
uint32 maxItems = config->GetMaxItems();
if (maxItems == 0)
{
//if (debug_Out) sLog.outString("AHSeller: Auctions disabled");
return;
}
AuctionHouseEntry const* ahEntry = auctionmgr.GetAuctionHouseEntry(config->GetAHFID());
if (!ahEntry)
{
@@ -129,31 +113,24 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
{
return;
}
uint32 auctions = auctionHouse->Getcount();
if (auctions >= minItems)
{
//if (debug_Out) sLog.outString("AHSeller: Auctions above minimum");
return;
}
if (auctions >= maxItems)
{
//if (debug_Out) sLog.outString("AHSeller: Auctions at or above maximum");
return;
}
uint32 items = 0;
if ((maxItems - auctions) >= ItemsPerCycle)
items = ItemsPerCycle;
else
items = (maxItems - auctions);
if (debug_Out) sLog.outString("AHSeller: Adding %u Auctions", items);
uint32 AuctioneerGUID = 0;
switch (config->GetAHID())
{
case 2:
@@ -170,9 +147,7 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
AuctioneerGUID = 23442; //default to neutral 7
break;
}
if (debug_Out) sLog.outString("AHSeller: Current Auctineer GUID is %u", AuctioneerGUID);
uint32 greyTGcount = config->GetPercents(AHB_GREY_TG);
uint32 whiteTGcount = config->GetPercents(AHB_WHITE_TG);
uint32 greenTGcount = config->GetPercents(AHB_GREEN_TG);
@@ -191,7 +166,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
+ purpleTGcount + orangeTGcount + yellowTGcount
+ whiteIcount + greenIcount + blueIcount + purpleIcount
+ orangeIcount + yellowIcount;
uint32 greyTGoods = config->GetItemCounts(AHB_GREY_TG);
uint32 whiteTGoods = config->GetItemCounts(AHB_WHITE_TG);
uint32 greenTGoods = config->GetItemCounts(AHB_GREEN_TG);
@@ -199,7 +173,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
uint32 purpleTGoods = config->GetItemCounts(AHB_PURPLE_TG);
uint32 orangeTGoods = config->GetItemCounts(AHB_ORANGE_TG);
uint32 yellowTGoods = config->GetItemCounts(AHB_YELLOW_TG);
uint32 greyItems = config->GetItemCounts(AHB_GREY_I);
uint32 whiteItems = config->GetItemCounts(AHB_WHITE_I);
uint32 greenItems = config->GetItemCounts(AHB_GREEN_I);
@@ -208,7 +181,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
uint32 orangeItems = config->GetItemCounts(AHB_ORANGE_I);
uint32 yellowItems = config->GetItemCounts(AHB_YELLOW_I);
if (debug_Out) sLog.outString("AHSeller: %u items", items);
// only insert a few at a time, so as not to peg the processor
for (uint32 cnt = 1;cnt <= items;cnt++)
{
@@ -327,20 +299,17 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
break;
}
}
if (itemID == 0)
{
if (debug_Out) sLog.outError("AHSeller: Item::CreateItem() - ItemID is 0");
continue;
}
ItemPrototype const* prototype = objmgr.GetItemPrototype(itemID);
if (prototype == NULL)
{
if (debug_Out) sLog.outError("AHSeller: Huh?!?! prototype == NULL");
continue;
}
Item* item = Item::CreateItem(itemID, 1, AHBplayer);
if (item == NULL)
{
@@ -348,15 +317,12 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
break;
}
item->AddToUpdateQueueOf(AHBplayer);
uint32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemID);
if (randomPropertyId != 0)
item->SetItemRandomProperties(randomPropertyId);
uint64 buyoutPrice = 0;
uint64 bidPrice = 0;
uint32 stackCount = 1;
switch (SellMethod)
{
case 0:
@@ -366,7 +332,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
buyoutPrice = prototype->BuyPrice;
break;
}
if ((prototype->Quality >= 0) && (prototype->Quality <= AHB_MAX_QUALITY))
{
if (config->GetMaxStack(prototype->Quality) > 1 && item->GetMaxStackCount() > 1)
@@ -387,7 +352,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
item->RemoveFromUpdateQueueOf(AHBplayer);
continue;
}
uint32 etime = urand(1,3);
switch(etime)
{
@@ -405,9 +369,7 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
break;
}
item->SetCount(stackCount);
uint32 dep = auctionmgr.GetAuctionDeposit(ahEntry, etime, item);
AuctionEntry* auctionEntry = new AuctionEntry;
auctionEntry->Id = objmgr.GenerateAuctionID();
auctionEntry->auctioneer = AuctioneerGUID;
@@ -426,7 +388,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config)
auctionmgr.AddAItem(item);
auctionHouse->AddAuction(auctionEntry);
auctionEntry->SaveToDB();
switch(itemColor)
{
case 0:
@@ -484,32 +445,26 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con
if (debug_Out) sLog.outError("AHBuyer: Disabled");
return;
}
QueryResult* result = CharacterDatabase.PQuery("SELECT id FROM auctionhouse WHERE itemowner<>%u AND buyguid<>%u", AHBplayerGUID, AHBplayerGUID);
if (!result)
{
delete result;
return;
}
if (result->GetRowCount() == 0)
{
delete result;
return;
}
// Fetches content of selected AH
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(config->GetAHFID());
vector<uint32> possibleBids;
do
{
uint32 tmpdata = result->Fetch()->GetUInt32();
possibleBids.push_back(tmpdata);
}while (result->NextRow());
delete result;
for (uint32 count = 1;count <= config->GetBidsPerInterval();++count)
{
// Do we have anything to bid? If not, stop here.
@@ -519,23 +474,18 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con
count = config->GetBidsPerInterval();
continue;
}
// Choose random auction from possible auctions
uint32 vectorPos = urand(0, possibleBids.size() - 1);
vector<uint32>::iterator iter = possibleBids.begin();
advance(iter, vectorPos);
// from auctionhousehandler.cpp, creates auction pointer & player pointer
AuctionEntry* auction = auctionHouse->GetAuction(*iter);
// Erase the auction from the vector to prevent bidding on item in next iteration.
possibleBids.erase(iter);
if (!auction)
{
continue;
}
// get exact item information
Item *pItem = auctionmgr.GetAItem(auction->item_guidlow);
if (!pItem)
@@ -543,21 +493,17 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con
if (debug_Out) sLog.outError("AHBuyer: Item %u doesn't exist, perhaps bought already?", auction->item_guidlow);
continue;
}
// get item prototype
ItemPrototype const* prototype = objmgr.GetItemPrototype(auction->item_template);
// check which price we have to use, startbid or if it is bidded already
uint32 currentprice;
if (auction->bid)
currentprice = auction->bid;
else
currentprice = auction->startbid;
// Prepare portion from maximum bid
double bidrate = static_cast<double>(urand(1, 100)) / 100;
long double bidMax = 0;
// check that bid has acceptable value and take bid based on vendorprice, stacksize and quality
switch (BuyMethod)
{
@@ -592,7 +538,6 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con
break;
}
}
// check some special items, and do recalculating to their prices
switch (prototype->Class)
{
@@ -603,22 +548,18 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con
default:
break;
}
if (bidMax == 0)
{
// quality check failed to get bidmax, let's get out of here
continue;
}
// Calculate our bid
long double bidvalue = currentprice + ((bidMax - currentprice) * bidrate);
// Convert to uint32
uint32 bidprice = static_cast<uint32>(bidvalue);
// Check our bid is high enough to be valid. If not, correct it to minimum.
if ((currentprice + auction->GetAuctionOutBid()) > bidprice)
bidprice = currentprice + auction->GetAuctionOutBid();
if (debug_Out)
{
sLog.outString("-------------------------------------------------");
@@ -648,11 +589,9 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con
sLog.outString("AHBuyer: Ammo Type: %u", prototype->AmmoType);
sLog.outString("-------------------------------------------------");
}
// Check whether we do normal bid, or buyout
if ((bidprice < auction->buyout) || (auction->buyout == 0))
{
if (auction->bidder > 0)
{
if (auction->bidder == AHBplayer->GetGUIDLow())
@@ -666,10 +605,8 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con
//pl->ModifyMoney(-int32(price));
}
}
auction->bidder = AHBplayer->GetGUIDLow();
auction->bid = bidprice;
// Saving auction into database
CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id);
}
@@ -682,7 +619,6 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con
}
auction->bidder = AHBplayer->GetGUIDLow();
auction->bid = auction->buyout;
// Send mails to buyer & seller
auctionmgr.SendAuctionSalePendingMail(auction);
auctionmgr.SendAuctionSuccessfulMail(auction);
@@ -694,18 +630,15 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con
}
}
}
void AuctionHouseBot::Update()
{
time_t _newrun = time(NULL);
if ((!AHBSeller) && (!AHBBuyer))
return;
WorldSession _session(AHBplayerAccount, NULL, SEC_PLAYER, true, 0, LOCALE_enUS);
Player _AHBplayer(&_session);
_AHBplayer.MinimalLoadFromDB(NULL, AHBplayerGUID);
ObjectAccessor::Instance().AddObject(&_AHBplayer);
// Only for testing, this can likely be removed, once I know it's working as expected.
/*
AuctionHouseObject* auctionHouse1 = auctionmgr.GetAuctionsMap(55);
@@ -719,7 +652,6 @@ void AuctionHouseBot::Update()
return;
}
*/
// Add New Bids
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
{
@@ -731,7 +663,6 @@ void AuctionHouseBot::Update()
addNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig, &_session);
_lastrun_a = _newrun;
}
addNewAuctions(&_AHBplayer, &HordeConfig);
if (((_newrun - _lastrun_h) >= (HordeConfig.GetBiddingInterval() * MINUTE)) && (HordeConfig.GetBidsPerInterval() > 0))
{
@@ -741,7 +672,6 @@ void AuctionHouseBot::Update()
_lastrun_h = _newrun;
}
}
addNewAuctions(&_AHBplayer, &NeutralConfig);
if (((_newrun - _lastrun_n) >= (NeutralConfig.GetBiddingInterval() * MINUTE)) && (NeutralConfig.GetBidsPerInterval() > 0))
{
@@ -752,37 +682,30 @@ void AuctionHouseBot::Update()
}
ObjectAccessor::Instance().RemoveObject(&_AHBplayer);
}
void AuctionHouseBot::Initialize()
{
debug_Out = sConfig.GetBoolDefault("AuctionHouseBot.DEBUG", false);
debug_Out_Filters = sConfig.GetBoolDefault("AuctionHouseBot.DEBUG_FILTERS", false);
AHBSeller = sConfig.GetBoolDefault("AuctionHouseBot.EnableSeller", false);
AHBBuyer = sConfig.GetBoolDefault("AuctionHouseBot.EnableBuyer", false);
SellMethod = sConfig.GetBoolDefault("AuctionHouseBot.UseBuyPriceForSeller", false);
BuyMethod = sConfig.GetBoolDefault("AuctionHouseBot.UseBuyPriceForBuyer", false);
AHBplayerAccount = sConfig.GetIntDefault("AuctionHouseBot.Account", 0);
AHBplayerGUID = sConfig.GetIntDefault("AuctionHouseBot.GUID", 0);
ItemsPerCycle = sConfig.GetIntDefault("AuctionHouseBot.ItemsPerCycle", 200);
//Begin Filters
Vendor_Items = sConfig.GetBoolDefault("AuctionHouseBot.VendorItems", false);
Loot_Items = sConfig.GetBoolDefault("AuctionHouseBot.LootItems", true);
Other_Items = sConfig.GetBoolDefault("AuctionHouseBot.OtherItems", false);
Vendor_TGs = sConfig.GetBoolDefault("AuctionHouseBot.VendorTradeGoods", false);
Loot_TGs = sConfig.GetBoolDefault("AuctionHouseBot.LootTradeGoods", true);
Other_TGs = sConfig.GetBoolDefault("AuctionHouseBot.OtherTradeGoods", false);
No_Bind = sConfig.GetBoolDefault("AuctionHouseBot.No_Bind", true);
Bind_When_Picked_Up = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Picked_Up", false);
Bind_When_Equipped = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Equipped", true);
Bind_When_Use = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Use", true);
Bind_Quest_Item = sConfig.GetBoolDefault("AuctionHouseBot.Bind_Quest_Item", false);
DisableBeta_PTR_Unused = sConfig.GetBoolDefault("AuctionHouseBot.DisableBeta_PTR_Unused", false);
DisablePermEnchant = sConfig.GetBoolDefault("AuctionHouseBot.DisablePermEnchant", false);
#if CLIENT_VER > 300
@@ -795,7 +718,6 @@ void AuctionHouseBot::Initialize()
DisableKeys = sConfig.GetBoolDefault("AuctionHouseBot.DisableKeys", false);
DisableDuration = sConfig.GetBoolDefault("AuctionHouseBot.DisableDuration", false);
DisableBOP_Or_Quest_NoReqLevel = sConfig.GetBoolDefault("AuctionHouseBot.DisableBOP_Or_Quest_NoReqLevel", false);
DisableWarriorItems = sConfig.GetBoolDefault("AuctionHouseBot.DisableWarriorItems", false);
DisablePaladinItems = sConfig.GetBoolDefault("AuctionHouseBot.DisablePaladinItems", false);
DisableHunterItems = sConfig.GetBoolDefault("AuctionHouseBot.DisableHunterItems", false);
@@ -807,7 +729,6 @@ void AuctionHouseBot::Initialize()
DisableWarlockItems = sConfig.GetBoolDefault("AuctionHouseBot.DisableWarlockItems", false);
DisableUnusedClassItems = sConfig.GetBoolDefault("AuctionHouseBot.DisableUnusedClassItems", false);
DisableDruidItems = sConfig.GetBoolDefault("AuctionHouseBot.DisableDruidItems", false);
DisableItemsBelowLevel = sConfig.GetIntDefault("AuctionHouseBot.DisableItemsBelowLevel", 0);
DisableItemsAboveLevel = sConfig.GetIntDefault("AuctionHouseBot.DisableItemsAboveLevel", 0);
DisableTGsBelowLevel = sConfig.GetIntDefault("AuctionHouseBot.DisableTGsBelowLevel", 0);
@@ -824,7 +745,6 @@ void AuctionHouseBot::Initialize()
DisableItemsAboveReqSkillRank = sConfig.GetIntDefault("AuctionHouseBot.DisableItemsAboveReqSkillRank", 0);
DisableTGsBelowReqSkillRank = sConfig.GetIntDefault("AuctionHouseBot.DisableTGsBelowReqSkillRank", 0);
DisableTGsAboveReqSkillRank = sConfig.GetIntDefault("AuctionHouseBot.DisableTGsAboveReqSkillRank", 0);
//End Filters
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
{
@@ -832,7 +752,6 @@ void AuctionHouseBot::Initialize()
LoadValues(&HordeConfig);
}
LoadValues(&NeutralConfig);
if (AHBSeller)
{
QueryResult* results = (QueryResult*) NULL;
@@ -844,16 +763,13 @@ void AuctionHouseBot::Initialize()
{
Field* fields = results->Fetch();
npcItems.push_back(fields[0].GetUInt32());
} while (results->NextRow());
delete results;
}
else
{
if (debug_Out) sLog.outString("AuctionHouseBot: \"%s\" failed", npcQuery);
}
char lootQuery[] = "SELECT item FROM creature_loot_template UNION "
"SELECT item FROM disenchant_loot_template UNION "
"SELECT item FROM fishing_loot_template UNION "
@@ -865,7 +781,6 @@ void AuctionHouseBot::Initialize()
"SELECT item FROM pickpocketing_loot_template UNION "
"SELECT item FROM prospecting_loot_template UNION "
"SELECT item FROM skinning_loot_template";
results = WorldDatabase.PQuery(lootQuery);
if (results != NULL)
{
@@ -873,23 +788,18 @@ void AuctionHouseBot::Initialize()
{
Field* fields = results->Fetch();
lootItems.push_back(fields[0].GetUInt32());
} while (results->NextRow());
delete results;
}
else
{
if (debug_Out) sLog.outString("AuctionHouseBot: \"%s\" failed", lootQuery);
}
for (uint32 itemID = 0; itemID < sItemStorage.MaxEntry; itemID++)
{
ItemPrototype const* prototype = objmgr.GetItemPrototype(itemID);
if (prototype == NULL)
continue;
switch (prototype->Bonding)
{
case NO_BIND:
@@ -916,7 +826,6 @@ void AuctionHouseBot::Initialize()
continue;
break;
}
switch (SellMethod)
{
case 0:
@@ -928,71 +837,56 @@ void AuctionHouseBot::Initialize()
continue;
break;
}
if ((prototype->Quality < 0) || (prototype->Quality > 6))
continue;
if ((Vendor_Items == 0) && !(prototype->Class == ITEM_CLASS_TRADE_GOODS))
{
bool isVendorItem = false;
for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorItem); i++)
{
if (itemID == npcItems[i])
isVendorItem = true;
}
if (isVendorItem)
continue;
}
if ((Vendor_TGs == 0) && (prototype->Class == ITEM_CLASS_TRADE_GOODS))
{
bool isVendorTG = false;
for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorTG); i++)
{
if (itemID == npcItems[i])
isVendorTG = true;
}
if (isVendorTG)
continue;
}
if ((Loot_Items == 0) && !(prototype->Class == ITEM_CLASS_TRADE_GOODS))
{
bool isLootItem = false;
for (unsigned int i = 0; (i < lootItems.size()) && (!isLootItem); i++)
{
if (itemID == lootItems[i])
isLootItem = true;
}
if (isLootItem)
continue;
}
if ((Loot_TGs == 0) && (prototype->Class == ITEM_CLASS_TRADE_GOODS))
{
bool isLootTG = false;
for (unsigned int i = 0; (i < lootItems.size()) && (!isLootTG); i++)
{
if (itemID == lootItems[i])
isLootTG = true;
}
if (isLootTG)
continue;
}
if ((Other_Items == 0) && !(prototype->Class == ITEM_CLASS_TRADE_GOODS))
{
bool isVendorItem = false;
bool isLootItem = false;
for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorItem); i++)
{
if (itemID == npcItems[i])
@@ -1006,12 +900,10 @@ void AuctionHouseBot::Initialize()
if ((!isLootItem) && (!isVendorItem))
continue;
}
if ((Other_TGs == 0) && (prototype->Class == ITEM_CLASS_TRADE_GOODS))
{
bool isVendorTG = false;
bool isLootTG = false;
for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorTG); i++)
{
if (itemID == npcItems[i])
@@ -1025,7 +917,6 @@ void AuctionHouseBot::Initialize()
if ((!isLootTG) && (!isVendorTG))
continue;
}
//TODO:Make list of items and create a vector
// Disable PTR/Beta/Unused items
if ((DisableBeta_PTR_Unused) && ((prototype->ItemId == 21878) || (prototype->ItemId == 27774) || (prototype->ItemId == 27811) || (prototype->ItemId == 28117) || (prototype->ItemId == 28112)))
@@ -1033,14 +924,12 @@ void AuctionHouseBot::Initialize()
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (PTR/Beta/Unused Item)", prototype->ItemId);
continue;
}
// Disable permanent enchants items
if ((DisablePermEnchant) && (prototype->Class == ITEM_CLASS_PERMANENT))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Permanent Enchant Item)", prototype->ItemId);
continue;
}
#if CLIENT_VER > 300
// Disable conjured items
if ((DisableConjured) && (prototype->IsConjuredConsumable()))
@@ -1049,245 +938,210 @@ void AuctionHouseBot::Initialize()
continue;
}
#endif
// Disable gems
if ((DisableGems) && (prototype->Class == ITEM_CLASS_GEM))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Gem)", prototype->ItemId);
continue;
}
// Disable money
if ((DisableMoney) && (prototype->Class == ITEM_CLASS_MONEY))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Money)", prototype->ItemId);
continue;
}
// Disable moneyloot
if ((DisableMoneyLoot) && (prototype->MinMoneyLoot > 0))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (MoneyLoot)", prototype->ItemId);
continue;
}
// Disable lootable items
if ((DisableLootable) && (prototype->Flags & 4))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Lootable Item)", prototype->ItemId);
continue;
}
// Disable Keys
if ((DisableKeys) && (prototype->Class == ITEM_CLASS_KEY))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Quest Item)", prototype->ItemId);
continue;
}
// Disable items with duration
if ((DisableDuration) && (prototype->Duration > 0))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Has a Duration)", prototype->ItemId);
continue;
}
// Disable items which are BOP or Quest Items and have a required level lower than the item level
if ((DisableBOP_Or_Quest_NoReqLevel) && ((prototype->Bonding == BIND_WHEN_PICKED_UP || prototype->Bonding == BIND_QUEST_ITEM) && (prototype->RequiredLevel < prototype->ItemLevel)))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (BOP or BQI and Required Level is less than Item Level)", prototype->ItemId);
continue;
}
// Disable items specifically for Warrior
if ((DisableWarriorItems) && (prototype->AllowableClass == 1))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Warrior Item)", prototype->ItemId);
continue;
}
// Disable items specifically for Paladin
if ((DisablePaladinItems) && (prototype->AllowableClass == 2))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Paladin Item)", prototype->ItemId);
continue;
}
// Disable items specifically for Hunter
if ((DisableHunterItems) && (prototype->AllowableClass == 4))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Hunter Item)", prototype->ItemId);
continue;
}
// Disable items specifically for Rogue
if ((DisableRogueItems) && (prototype->AllowableClass == 8))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Rogue Item)", prototype->ItemId);
continue;
}
// Disable items specifically for Priest
if ((DisablePriestItems) && (prototype->AllowableClass == 16))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Priest Item)", prototype->ItemId);
continue;
}
// Disable items specifically for DK
if ((DisableDKItems) && (prototype->AllowableClass == 32))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (DK Item)", prototype->ItemId);
continue;
}
// Disable items specifically for Shaman
if ((DisableShamanItems) && (prototype->AllowableClass == 64))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Shaman Item)", prototype->ItemId);
continue;
}
// Disable items specifically for Mage
if ((DisableMageItems) && (prototype->AllowableClass == 128))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Mage Item)", prototype->ItemId);
continue;
}
// Disable items specifically for Warlock
if ((DisableWarlockItems) && (prototype->AllowableClass == 256))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Warlock Item)", prototype->ItemId);
continue;
}
// Disable items specifically for Unused Class
if ((DisableUnusedClassItems) && (prototype->AllowableClass == 512))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Unused Item)", prototype->ItemId);
continue;
}
// Disable items specifically for Druid
if ((DisableDruidItems) && (prototype->AllowableClass == 1024))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Druid Item)", prototype->ItemId);
continue;
}
// Disable Items below level X
if ((DisableItemsBelowLevel) && (prototype->Class != ITEM_CLASS_TRADE_GOODS) && (prototype->ItemLevel < DisableItemsBelowLevel))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Item Level = %u)", prototype->ItemId, prototype->ItemLevel);
continue;
}
// Disable Items above level X
if ((DisableItemsAboveLevel) && (prototype->Class != ITEM_CLASS_TRADE_GOODS) && (prototype->ItemLevel > DisableItemsAboveLevel))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Item Level = %u)", prototype->ItemId, prototype->ItemLevel);
continue;
}
// Disable Trade Goods below level X
if ((DisableTGsBelowLevel) && (prototype->Class == ITEM_CLASS_TRADE_GOODS) && (prototype->ItemLevel < DisableTGsBelowLevel))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Trade Good %u disabled (Trade Good Level = %u)", prototype->ItemId, prototype->ItemLevel);
continue;
}
// Disable Trade Goods above level X
if ((DisableTGsAboveLevel) && (prototype->Class == ITEM_CLASS_TRADE_GOODS) && (prototype->ItemLevel > DisableTGsAboveLevel))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Trade Good %u disabled (Trade Good Level = %u)", prototype->ItemId, prototype->ItemLevel);
continue;
}
// Disable Items below GUID X
if ((DisableItemsBelowGUID) && (prototype->Class != ITEM_CLASS_TRADE_GOODS) && (prototype->ItemId < DisableItemsBelowGUID))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Item Level = %u)", prototype->ItemId, prototype->ItemLevel);
continue;
}
// Disable Items above GUID X
if ((DisableItemsAboveGUID) && (prototype->Class != ITEM_CLASS_TRADE_GOODS) && (prototype->ItemId > DisableItemsAboveGUID))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Item Level = %u)", prototype->ItemId, prototype->ItemLevel);
continue;
}
// Disable Trade Goods below GUID X
if ((DisableTGsBelowGUID) && (prototype->Class == ITEM_CLASS_TRADE_GOODS) && (prototype->ItemId < DisableTGsBelowGUID))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Trade Good Level = %u)", prototype->ItemId, prototype->ItemLevel);
continue;
}
// Disable Trade Goods above GUID X
if ((DisableTGsAboveGUID) && (prototype->Class == ITEM_CLASS_TRADE_GOODS) && (prototype->ItemId > DisableTGsAboveGUID))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Trade Good Level = %u)", prototype->ItemId, prototype->ItemLevel);
continue;
}
// Disable Items for level lower than X
if ((DisableItemsBelowReqLevel) && (prototype->RequiredLevel < DisableItemsBelowReqLevel))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredLevel = %u)", prototype->ItemId, prototype->RequiredLevel);
continue;
}
// Disable Items for level higher than X
if ((DisableItemsAboveReqLevel) && (prototype->RequiredLevel > DisableItemsAboveReqLevel))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredLevel = %u)", prototype->ItemId, prototype->RequiredLevel);
continue;
}
// Disable Trade Goods for level lower than X
if ((DisableTGsBelowReqLevel) && (prototype->RequiredLevel < DisableTGsBelowReqLevel))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Trade Good %u disabled (RequiredLevel = %u)", prototype->ItemId, prototype->RequiredLevel);
continue;
}
// Disable Trade Goods for level higher than X
if ((DisableTGsAboveReqLevel) && (prototype->RequiredLevel > DisableTGsAboveReqLevel))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Trade Good %u disabled (RequiredLevel = %u)", prototype->ItemId, prototype->RequiredLevel);
continue;
}
// Disable Items that require skill lower than X
if ((DisableItemsBelowReqSkillRank) && (prototype->RequiredSkillRank < DisableItemsBelowReqSkillRank))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", prototype->ItemId, prototype->RequiredSkillRank);
continue;
}
// Disable Items that require skill higher than X
if ((DisableItemsAboveReqSkillRank) && (prototype->RequiredSkillRank > DisableItemsAboveReqSkillRank))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", prototype->ItemId, prototype->RequiredSkillRank);
continue;
}
// Disable Trade Goods that require skill lower than X
if ((DisableTGsBelowReqSkillRank) && (prototype->RequiredSkillRank < DisableTGsBelowReqSkillRank))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", prototype->ItemId, prototype->RequiredSkillRank);
continue;
}
// Disable Trade Goods that require skill higher than X
if ((DisableTGsAboveReqSkillRank) && (prototype->RequiredSkillRank > DisableTGsAboveReqSkillRank))
{
if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", prototype->ItemId, prototype->RequiredSkillRank);
continue;
}
switch (prototype->Quality)
{
case AHB_GREY:
@@ -1296,42 +1150,36 @@ void AuctionHouseBot::Initialize()
else
greyItemsBin.push_back(itemID);
break;
case AHB_WHITE:
if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
whiteTradeGoodsBin.push_back(itemID);
else
whiteItemsBin.push_back(itemID);
break;
case AHB_GREEN:
if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
greenTradeGoodsBin.push_back(itemID);
else
greenItemsBin.push_back(itemID);
break;
case AHB_BLUE:
if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
blueTradeGoodsBin.push_back(itemID);
else
blueItemsBin.push_back(itemID);
break;
case AHB_PURPLE:
if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
purpleTradeGoodsBin.push_back(itemID);
else
purpleItemsBin.push_back(itemID);
break;
case AHB_ORANGE:
if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
orangeTradeGoodsBin.push_back(itemID);
else
orangeItemsBin.push_back(itemID);
break;
case AHB_YELLOW:
if (prototype->Class == ITEM_CLASS_TRADE_GOODS)
yellowTradeGoodsBin.push_back(itemID);
@@ -1340,7 +1188,6 @@ void AuctionHouseBot::Initialize()
break;
}
}
if ((greyTradeGoodsBin.size() == 0) &&
(whiteTradeGoodsBin.size() == 0) &&
(greenTradeGoodsBin.size() == 0) &&
@@ -1359,7 +1206,6 @@ void AuctionHouseBot::Initialize()
sLog.outError("AuctionHouseBot: No items");
AHBSeller = 0;
}
sLog.outString("AuctionHouseBot:");
sLog.outString("loaded %u grey trade goods", greyTradeGoodsBin.size());
sLog.outString("loaded %u white trade goods", whiteTradeGoodsBin.size());
@@ -1379,11 +1225,9 @@ void AuctionHouseBot::Initialize()
sLog.outString("AuctionHouseBot by Paradox (original by ChrisK) has been loaded.");
sLog.outString("AuctionHouseBot now includes AHBuyer by Kerbe and Paradox");
}
void AuctionHouseBot::IncrementItemCounts(AuctionEntry* ah)
{
// from auctionhousehandler.cpp, creates auction pointer & player pointer
// get exact item information
Item *pItem = auctionmgr.GetAItem(ah->item_guidlow);
if (!pItem)
@@ -1391,12 +1235,9 @@ void AuctionHouseBot::IncrementItemCounts(AuctionEntry* ah)
if (debug_Out) sLog.outError("AHBot: Item %u doesn't exist, perhaps bought already?", ah->item_guidlow);
return;
}
// get item prototype
ItemPrototype const* prototype = objmgr.GetItemPrototype(ah->item_template);
AHBConfig *config;
FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(ah->GetHouseFaction());
if (!u_entry)
{
@@ -1418,17 +1259,13 @@ void AuctionHouseBot::IncrementItemCounts(AuctionEntry* ah)
if (debug_Out) sLog.outError("AHBot: %u returned as House Faction. Neutral", ah->GetHouseFaction());
config = &NeutralConfig;
}
config->IncItemCounts(prototype->Class, prototype->Quality);
}
void AuctionHouseBot::DecrementItemCounts(AuctionEntry* ah, uint32 item_template)
{
// get item prototype
ItemPrototype const* prototype = objmgr.GetItemPrototype(item_template);
AHBConfig *config;
FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(ah->GetHouseFaction());
if (!u_entry)
{
@@ -1450,10 +1287,8 @@ void AuctionHouseBot::DecrementItemCounts(AuctionEntry* ah, uint32 item_template
if (debug_Out) sLog.outError("AHBot: %u returned as House Faction. Neutral", ah->GetHouseFaction());
config = &NeutralConfig;
}
config->DecItemCounts(prototype->Class, prototype->Quality);
}
void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char* args)
{
AHBConfig *config;
@@ -1501,15 +1336,12 @@ void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char*
case 0: //ahexpire
{
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(config->GetAHFID());
AuctionHouseObject::AuctionEntryMap::iterator itr;
itr = auctionHouse->GetAuctionsBegin();
while (itr != auctionHouse->GetAuctionsEnd())
{
if (itr->second->owner == AHBplayerGUID)
itr->second->expire_time = sWorld.GetGameTime();
++itr;
}
}
@@ -1564,7 +1396,6 @@ void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char*
uint32 purplei = (uint32) strtoul(param12, NULL, 0);
uint32 orangei = (uint32) strtoul(param13, NULL, 0);
uint32 yellowi = (uint32) strtoul(param14, NULL, 0);
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentgreytradegoods = '%u' WHERE auctionhouse = '%u'", greytg, ahMapID);
CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentwhitetradegoods = '%u' WHERE auctionhouse = '%u'", whitetg, ahMapID);
@@ -1652,7 +1483,6 @@ void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char*
break;
}
}
void AuctionHouseBot::LoadValues(AHBConfig *config)
{
if (debug_Out) sLog.outString("Start Settings for %s Auctionhouses:", CharacterDatabase.PQuery("SELECT name FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetString());
@@ -1771,10 +1601,8 @@ void AuctionHouseBot::LoadValues(AHBConfig *config)
}
AuctionHouseEntry const* ahEntry = auctionmgr.GetAuctionHouseEntry(config->GetAHFID());
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(config->GetAHFID());
config->ResetItemCounts();
uint32 auctions = auctionHouse->Getcount();
if (auctions)
{
for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin();itr != auctionHouse->GetAuctionsEnd();++itr)
-34
View File
@@ -1,10 +1,8 @@
#ifndef AUCTION_HOUSE_BOT_H
#define AUCTION_HOUSE_BOT_H
#include "World.h"
#include "Config/ConfigEnv.h"
#include "ItemPrototype.h"
#define AHB_GREY 0
#define AHB_WHITE 1
#define AHB_GREEN 2
@@ -27,7 +25,6 @@
#define AHB_PURPLE_I 11
#define AHB_ORANGE_I 12
#define AHB_YELLOW_I 13
class AHBConfig
{
private:
@@ -84,7 +81,6 @@ private:
uint32 minBidPriceYellow;
uint32 maxBidPriceYellow;
uint32 maxStackYellow;
uint32 buyerPriceGrey;
uint32 buyerPriceWhite;
uint32 buyerPriceGreen;
@@ -94,7 +90,6 @@ private:
uint32 buyerPriceYellow;
uint32 buyerBiddingInterval;
uint32 buyerBidsPerInterval;
uint32 greytgp;
uint32 whitetgp;
uint32 greentgp;
@@ -109,7 +104,6 @@ private:
uint32 purpleip;
uint32 orangeip;
uint32 yellowip;
uint32 greyTGoods;
uint32 whiteTGoods;
uint32 greenTGoods;
@@ -117,7 +111,6 @@ private:
uint32 purpleTGoods;
uint32 orangeTGoods;
uint32 yellowTGoods;
uint32 greyItems;
uint32 whiteItems;
uint32 greenItems;
@@ -125,7 +118,6 @@ private:
uint32 purpleItems;
uint32 orangeItems;
uint32 yellowItems;
public:
AHBConfig(uint32 ahid)
{
@@ -182,7 +174,6 @@ public:
void SetPercentages(uint32 greytg, uint32 whitetg, uint32 greentg, uint32 bluetg, uint32 purpletg, uint32 orangetg, uint32 yellowtg, uint32 greyi, uint32 whitei, uint32 greeni, uint32 bluei, uint32 purplei, uint32 orangei, uint32 yellowi)
{
uint32 totalPercent = greytg + whitetg + greentg + bluetg + purpletg + orangetg + yellowtg + greyi + whitei + greeni + bluei + purplei + orangei + yellowi;
if (totalPercent == 0)
{
maxItems = 0;
@@ -892,7 +883,6 @@ public:
break;
}
}
void DecItemCounts(uint32 Class, uint32 Quality)
{
switch(Class)
@@ -905,7 +895,6 @@ public:
break;
}
}
void DecItemCounts(uint32 color)
{
switch(color)
@@ -956,7 +945,6 @@ public:
break;
}
}
void IncItemCounts(uint32 Class, uint32 Quality)
{
switch(Class)
@@ -969,7 +957,6 @@ public:
break;
}
}
void IncItemCounts(uint32 color)
{
switch(color)
@@ -1020,7 +1007,6 @@ public:
break;
}
}
void ResetItemCounts()
{
greyTGoods = 0;
@@ -1030,7 +1016,6 @@ public:
purpleTGoods = 0;
orangeTGoods = 0;
yellowTGoods = 0;
greyItems = 0;
whiteItems = 0;
greenItems = 0;
@@ -1039,7 +1024,6 @@ public:
orangeItems = 0;
yellowItems = 0;
}
uint32 TotalItemCounts()
{
return(
@@ -1050,7 +1034,6 @@ public:
purpleTGoods +
orangeTGoods +
yellowTGoods +
greyItems +
whiteItems +
greenItems +
@@ -1059,7 +1042,6 @@ public:
orangeItems +
yellowItems);
}
uint32 GetItemCounts(uint32 color)
{
switch(color)
@@ -1126,34 +1108,27 @@ public:
class AuctionHouseBot
{
private:
bool debug_Out;
bool debug_Out_Filters;
bool AHBSeller;
bool AHBBuyer;
bool BuyMethod;
bool SellMethod;
uint32 AHBplayerAccount;
uint32 AHBplayerGUID;
uint32 ItemsPerCycle;
//Begin Filters
bool Vendor_Items;
bool Loot_Items;
bool Other_Items;
bool Vendor_TGs;
bool Loot_TGs;
bool Other_TGs;
bool No_Bind;
bool Bind_When_Picked_Up;
bool Bind_When_Equipped;
bool Bind_When_Use;
bool Bind_Quest_Item;
bool DisableBeta_PTR_Unused;
bool DisablePermEnchant;
#if CLIENT_VER > 300
@@ -1166,7 +1141,6 @@ private:
bool DisableKeys;
bool DisableDuration;
bool DisableBOP_Or_Quest_NoReqLevel;
bool DisableWarriorItems;
bool DisablePaladinItems;
bool DisableHunterItems;
@@ -1178,7 +1152,6 @@ private:
bool DisableWarlockItems;
bool DisableUnusedClassItems;
bool DisableDruidItems;
uint32 DisableItemsBelowLevel;
uint32 DisableItemsAboveLevel;
uint32 DisableTGsBelowLevel;
@@ -1195,21 +1168,16 @@ private:
uint32 DisableItemsAboveReqSkillRank;
uint32 DisableTGsBelowReqSkillRank;
uint32 DisableTGsAboveReqSkillRank;
//End Filters
AHBConfig AllianceConfig;
AHBConfig HordeConfig;
AHBConfig NeutralConfig;
time_t _lastrun_a;
time_t _lastrun_h;
time_t _lastrun_n;
inline uint32 minValue(uint32 a, uint32 b) { return a <= b ? a : b; };
void addNewAuctions(Player *AHBplayer, AHBConfig *config);
void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, WorldSession *session);
public:
AuctionHouseBot();
~AuctionHouseBot();
@@ -1221,7 +1189,5 @@ public:
void Commands(uint32, uint32, uint32, char*);
uint32 GetAHBplayerGUID() { return AHBplayerGUID; };
};
#define auctionbot Trinity::Singleton<AuctionHouseBot>::Instance()
#endif
-99
View File
@@ -17,13 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ObjectMgr.h"
#include "Player.h"
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "AuctionHouseBot.h"
#include "AuctionHouseMgr.h"
#include "Log.h"
@@ -31,43 +29,35 @@
#include "UpdateMask.h"
#include "Util.h"
//please DO NOT use iterator++, because it is slower than ++iterator!!!
//post-incrementation is always slower than pre-incrementation !
//void called when player click on auctioneer npc
void WorldSession::HandleAuctionHelloOpcode(WorldPacket & recv_data)
{
uint64 guid; //NPC guid
recv_data >> guid;
Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
if (!unit)
{
sLog.outDebug("WORLD: HandleAuctionHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
return;
}
// remove fake death
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
SendAuctionHello(guid, unit);
}
//this void causes that auction window is opened
void WorldSession::SendAuctionHello(uint64 guid, Creature* unit)
{
AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction());
if (!ahEntry)
return;
WorldPacket data(MSG_AUCTION_HELLO, 12);
data << (uint64) guid;
data << (uint32) ahEntry->houseId;
SendPacket(&data);
}
//call this method when player bids, creates, or deletes auction
void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError)
{
@@ -79,7 +69,6 @@ void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uin
data << bidError; //when bid, then send 0, once...
SendPacket(&data);
}
//this function sends notification, if bidder is online
void WorldSession::SendAuctionBidderNotification(uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template)
{
@@ -93,7 +82,6 @@ void WorldSession::SendAuctionBidderNotification(uint32 location, uint32 auction
data << uint32(0);
SendPacket(&data);
}
//this void causes on client to display: "Your auction sold"
void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction)
{
@@ -107,53 +95,42 @@ void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction)
data << (uint32) 0; //unk
SendPacket(&data);
}
//this function sends mail to old bidder
void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPrice)
{
uint64 oldBidder_guid = MAKE_NEW_GUID(auction->bidder,0, HIGHGUID_PLAYER);
Player *oldBidder = objmgr.GetPlayer(oldBidder_guid);
uint32 oldBidder_accId = 0;
if (!oldBidder)
oldBidder_accId = objmgr.GetPlayerAccountIdByGUID(oldBidder_guid);
// old bidder exist
if (oldBidder || oldBidder_accId)
{
std::ostringstream msgAuctionOutbiddedSubject;
msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED;
if (oldBidder && !_player)
oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, auctionbot.GetAHBplayerGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
if (oldBidder && _player)
oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
WorldSession::SendMailTo(oldBidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionOutbiddedSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE);
}
}
//this function sends mail, when auction is cancelled to old bidder
void WorldSession::SendAuctionCancelledToBidderMail(AuctionEntry* auction)
{
uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
Player *bidder = objmgr.GetPlayer(bidder_guid);
uint32 bidder_accId = 0;
if (!bidder)
bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid);
// bidder exist
if (bidder || bidder_accId)
{
std::ostringstream msgAuctionCancelledSubject;
msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER;
WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionCancelledSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE);
}
}
//this void creates new auction and adds auction to some auctionhouse
void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
{
@@ -162,31 +139,24 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
recv_data >> auctioneer >> item;
recv_data >> bid >> buyout >> etime;
Player *pl = GetPlayer();
if (!item || !bid || !etime)
return; //check for cheaters
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug("WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)));
return;
}
AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(pCreature->getFaction());
if (!auctionHouseEntry)
{
sLog.outDebug("WORLD: HandleAuctionSellItem - Unit (GUID: %u) has wrong faction.", uint32(GUID_LOPART(auctioneer)));
return;
}
sLog.outDebug("WORLD: HandleAuctionSellItem - ETIME: %u", etime);
// client send time in minutes, convert to common used sec time
etime *= MINUTE;
sLog.outDebug("WORLD: HandleAuctionSellItem - ETIME: %u", etime);
// client understand only 3 auction time
switch(etime)
{
@@ -197,11 +167,9 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
default:
return;
}
// remove fake death
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
Item *it = pl->GetItemByGuid(item);
//do not allow to sell already auctioned items
if (auctionmgr.GetAItem(GUID_LOPART(item)))
@@ -216,21 +184,17 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_ITEM_NOT_FOUND);
return;
}
if (!it->CanBeTraded())
{
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
return;
}
if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION))
{
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
return;
}
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
//we have to take deposit :
uint32 deposit = auctionmgr.GetAuctionDeposit(auctionHouseEntry, etime, it);
if (pl->GetMoney() < deposit)
@@ -238,17 +202,13 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY);
return;
}
if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE))
{
sLog.outCommand(GetAccountId(),"GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",
GetPlayerName(),GetAccountId(),it->GetProto()->Name1,it->GetEntry(),it->GetCount());
}
pl->ModifyMoney(-int32(deposit));
uint32 auction_time = uint32(etime * sWorld.getRate(RATE_AUCTION_TIME));
AuctionEntry *AH = new AuctionEntry;
AH->Id = objmgr.GenerateAuctionID();
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
@@ -265,23 +225,18 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
AH->expire_time = time(NULL) + auction_time;
AH->deposit = deposit;
AH->auctionHouseEntry = auctionHouseEntry;
sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", GUID_LOPART(item), AH->auctioneer, bid, buyout, auction_time, AH->GetHouseId());
auctionmgr.AddAItem(it);
auctionHouse->AddAuction(AH);
pl->MoveItemFromInventory(it->GetBagSlot(), it->GetSlot(), true);
CharacterDatabase.BeginTransaction();
it->DeleteFromInventoryDB();
it->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone
AH->SaveToDB();
pl->SaveInventoryAndGoldToDB();
CharacterDatabase.CommitTransaction();
SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK);
}
//this function is called when client bids or buys out auction
void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
{
@@ -290,33 +245,26 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
uint32 price;
recv_data >> auctioneer;
recv_data >> auctionId >> price;
if (!auctionId || !price)
return; //check for cheaters
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug("WORLD: HandleAuctionPlaceBid - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)));
return;
}
// remove fake death
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
AuctionEntry *auction = auctionHouse->GetAuction(auctionId);
Player *pl = GetPlayer();
if (!auction || auction->owner == pl->GetGUIDLow())
{
//you cannot bid your own auction:
SendAuctionCommandResult(0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR);
return;
}
// impossible have online own another character (use this for speedup check in case online owner)
Player* auction_owner = objmgr.GetPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER));
if (!auction_owner && objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)) == pl->GetSession()->GetAccountId())
@@ -325,11 +273,9 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
SendAuctionCommandResult(0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR);
return;
}
// cheating
if (price <= auction->bid)
return;
// price too low for next bid if not buyout
if ((price < auction->buyout || auction->buyout == 0) &&
price < auction->bid + auction->GetAuctionOutBid())
@@ -337,14 +283,12 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
//auction has already higher bid, client tests it!
return;
}
if (price > pl->GetMoney())
{
//you don't have enought money!, client tests!
//SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
return;
}
if ((price < auction->buyout) || (auction->buyout == 0))
{
if (auction->bidder > 0)
@@ -367,10 +311,8 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
auction->bidder = pl->GetGUIDLow();
auction->bid = price;
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price);
// after this update we should save player's money ...
CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id);
SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0);
}
else
@@ -391,11 +333,9 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
auction->bidder = pl->GetGUIDLow();
auction->bid = auction->buyout;
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
auctionmgr.SendAuctionSalePendingMail(auction);
auctionmgr.SendAuctionSuccessfulMail(auction);
auctionmgr.SendAuctionWonMail(auction);
SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK);
auction->DeleteFromDB();
uint32 item_template = auction->item_template;
@@ -406,7 +346,6 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
pl->SaveInventoryAndGoldToDB();
CharacterDatabase.CommitTransaction();
}
//this void is called when auction_owner cancels his auction
void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
{
@@ -415,23 +354,18 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
recv_data >> auctioneer;
recv_data >> auctionId;
//sLog.outDebug("Cancel AUCTION AuctionID: %u", auctionId);
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug("WORLD: HandleAuctionRemoveItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)));
return;
}
// remove fake death
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
AuctionEntry *auction = auctionHouse->GetAuction(auctionId);
Player *pl = GetPlayer();
if (auction && auction->owner == pl->GetGUIDLow())
{
Item *pItem = auctionmgr.GetAItem(auction->item_guidlow);
@@ -449,10 +383,8 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
// Return the item by mail
std::ostringstream msgAuctionCanceledOwner;
msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED;
MailItemsInfo mi;
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
// item will deleted or added to received mail list
WorldSession::SendMailTo(pl, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), pl->GetGUIDLow(), msgAuctionCanceledOwner.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
}
@@ -470,7 +402,6 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
sLog.outError("CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", pl->GetGUIDLow(), auctionId);
return;
}
//inform player, that auction is removed
SendAuctionCommandResult(auction->Id, AUCTION_CANCEL, AUCTION_OK);
// Now remove the auction
@@ -482,14 +413,12 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
auctionmgr.RemoveAItem(auction->item_guidlow);
auctionHouse->RemoveAuction(auction, item_template);
}
//called when player lists his bids
void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data)
{
uint64 guid; //NPC guid
uint32 listfrom; //page of auctions
uint32 outbiddedCount; //count of outbidded auctions
recv_data >> guid;
recv_data >> listfrom; // not used in fact (this list not have page control in client)
recv_data >> outbiddedCount;
@@ -498,20 +427,16 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data)
sLog.outError("Client sent bad opcode!!! with count: %u and size : %lu (must be: %u)", outbiddedCount, (unsigned long)recv_data.size(),(16 + outbiddedCount * 4));
outbiddedCount = 0;
}
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug("WORLD: HandleAuctionListBidderItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
return;
}
// remove fake death
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
WorldPacket data(SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4));
Player *pl = GetPlayer();
data << (uint32) 0; //add 0 as count
@@ -529,49 +454,39 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data)
++count;
}
}
auctionHouse->BuildListBidderItems(data,pl,count,totalcount);
data.put<uint32>(0, count); // add count to placeholder
data << totalcount;
data << (uint32)300; //unk 2.3.0
SendPacket(&data);
}
//this void sends player info about his auctions
void WorldSession::HandleAuctionListOwnerItems(WorldPacket & recv_data)
{
uint32 listfrom;
uint64 guid;
recv_data >> guid;
recv_data >> listfrom; // not used in fact (this list not have page control in client)
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug("WORLD: HandleAuctionListOwnerItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
return;
}
// remove fake death
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
WorldPacket data(SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4));
data << (uint32) 0; // amount place holder
uint32 count = 0;
uint32 totalcount = 0;
auctionHouse->BuildListOwnerItems(data,_player,count,totalcount);
data.put<uint32>(0, count);
data << (uint32) totalcount;
data << (uint32) 0;
SendPacket(&data);
}
//this void is called when player clicks on search button
void WorldSession::HandleAuctionListItems(WorldPacket & recv_data)
{
@@ -579,61 +494,47 @@ void WorldSession::HandleAuctionListItems(WorldPacket & recv_data)
uint8 levelmin, levelmax, usable;
uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
uint64 guid;
recv_data >> guid;
recv_data >> listfrom; // start, used for page control listing by 50 elements
recv_data >> searchedname;
recv_data >> levelmin >> levelmax;
recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory;
recv_data >> quality >> usable;
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
sLog.outDebug("WORLD: HandleAuctionListItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
return;
}
// remove fake death
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction());
//sLog.outDebug("Auctionhouse search (GUID: %u TypeId: %u)", , list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u",
// GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable);
WorldPacket data(SMSG_AUCTION_LIST_RESULT, (4+4+4));
uint32 count = 0;
uint32 totalcount = 0;
data << (uint32) 0;
// converting string that we try to find to lower case
std::wstring wsearchedname;
if (!Utf8toWStr(searchedname,wsearchedname))
return;
wstrToLower(wsearchedname);
auctionHouse->BuildListAuctionItems(data,_player,
wsearchedname, listfrom, levelmin, levelmax, usable,
auctionSlotID, auctionMainCategory, auctionSubCategory, quality,
count,totalcount);
data.put<uint32>(0, count);
data << (uint32) totalcount;
data << (uint32) 300; // unk 2.3.0 const?
SendPacket(&data);
}
void WorldSession::HandleAuctionListPendingSales(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES");
recv_data.hexlike();
uint32 count = 0;
WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES, 4);
data << uint32(count); // count
/*for (uint32 i = 0; i < count; ++i)
-114
View File
@@ -15,7 +15,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "ObjectMgr.h"
#include "Player.h"
@@ -26,7 +25,6 @@
#include "Database/SQLStorage.h"
#include "Policies/SingletonImp.h"
#include "DBCStores.h"
#include "AccountMgr.h"
#include "AuctionHouseMgr.h"
#include "Item.h"
@@ -35,26 +33,20 @@
#include "ProgressBar.h"
#include <vector>
INSTANTIATE_SINGLETON_1(AuctionHouseMgr);
using namespace std;
AuctionHouseMgr::AuctionHouseMgr()
{
}
AuctionHouseMgr::~AuctionHouseMgr()
{
for (ItemMap::const_iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr)
delete itr->second;
}
AuctionHouseObject * AuctionHouseMgr::GetAuctionsMap(uint32 factionTemplateId)
{
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
return &mNeutralAuctions;
// team have linked auction houses
FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId);
if (!u_entry)
@@ -66,18 +58,15 @@ AuctionHouseObject * AuctionHouseMgr::GetAuctionsMap(uint32 factionTemplateId)
else
return &mNeutralAuctions;
}
uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem)
{
uint32 MSV = pItem->GetProto()->SellPrice;
int32 deposit;
uint32 timeHr = (((time / 60) / 60) / 12);
if (MSV > 0)
deposit = (int32)floor((double)MSV * (((double)(entry->depositPercent * 3) / 100.0f * (double)sWorld.getRate(RATE_AUCTION_DEPOSIT) * (double)pItem->GetCount()))) * timeHr;
else
deposit = 0;
sLog.outDebug("SellPrice:\t\t%u", MSV);
sLog.outDebug("Deposit Percent:\t%f", ((double)entry->depositPercent / 100.0f));
sLog.outDebug("Auction Time1:\t\t%u", time);
@@ -95,14 +84,12 @@ uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32
return 0;
}
}
//does not clear ram
void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
{
Item *pItem = GetAItem(auction->item_guidlow);
if (!pItem)
return;
uint32 bidder_accId = 0;
uint32 bidder_security = 0;
uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
@@ -121,7 +108,6 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
{
bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid);
bidder_security = accmgr.GetSecurity(bidder_accId);
if (bidder_security > SEC_PLAYER) // not do redundant DB requests
{
if (!objmgr.GetPlayerNameByGUID(bidder_guid,bidder_name))
@@ -133,44 +119,34 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
std::string owner_name;
if (!objmgr.GetPlayerNameByGUID(auction->owner,owner_name))
owner_name = objmgr.GetTrinityStringForDBCLocale(LANG_UNKNOWN);
uint32 owner_accid = objmgr.GetPlayerAccountIdByGUID(auction->owner);
sLog.outCommand(bidder_accId,"GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)",
bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid);
}
}
// receiver exist
if (bidder || bidder_accId)
{
std::ostringstream msgAuctionWonSubject;
msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON;
std::ostringstream msgAuctionWonBody;
msgAuctionWonBody.width(16);
msgAuctionWonBody << std::right << std::hex << auction->owner;
msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
sLog.outDebug("AuctionWon body string : %s", msgAuctionWonBody.str().c_str());
//prepare mail data... :
uint32 itemTextId = objmgr.CreateItemText(msgAuctionWonBody.str());
// set owner to bidder (to prevent delete item with sender char deleting)
// owner in `data` will set at mail receive and item extracting
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
CharacterDatabase.CommitTransaction();
MailItemsInfo mi;
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
if (bidder)
bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template);
WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION);
}
}
void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry * auction)
{
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
@@ -181,26 +157,19 @@ void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry * auction)
{
std::ostringstream msgAuctionSalePendingSubject;
msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING;
std::ostringstream msgAuctionSalePendingBody;
uint32 auctionCut = auction->GetAuctionCut();
time_t distrTime = time(NULL) + sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY);
msgAuctionSalePendingBody.width(16);
msgAuctionSalePendingBody << std::right << std::hex << auction->bidder;
msgAuctionSalePendingBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
msgAuctionSalePendingBody << ":" << auction->deposit << ":" << auctionCut << ":0:";
msgAuctionSalePendingBody << secsToTimeBitFields(distrTime);
sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str());
uint32 itemTextId = objmgr.CreateItemText(msgAuctionSalePendingBody.str());
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION);
}
}
//call this method to send mail to auction owner, when auction is successful, it does not clear ram
void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction)
{
@@ -212,21 +181,15 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction)
{
std::ostringstream msgAuctionSuccessfulSubject;
msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL;
std::ostringstream auctionSuccessfulBody;
uint32 auctionCut = auction->GetAuctionCut();
auctionSuccessfulBody.width(16);
auctionSuccessfulBody << std::right << std::hex << auction->bidder;
auctionSuccessfulBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
auctionSuccessfulBody << ":" << auction->deposit << ":" << auctionCut;
sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str());
uint32 itemTextId = objmgr.CreateItemText(auctionSuccessfulBody.str());
uint32 profit = auction->bid + auction->deposit - auctionCut;
//FIXME: what do if owner offline
if (owner && owner->GetGUIDLow() != auctionbot.GetAHBplayerGUID())
{
@@ -237,14 +200,12 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction)
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY));
}
}
//does not clear ram
void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction)
{ //return an item in auction to its owner by mail
Item *pItem = GetAItem(auction->item_guidlow);
if (!pItem)
return;
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
Player *owner = objmgr.GetPlayer(owner_guid);
uint32 owner_accId = objmgr.GetPlayerAccountIdByGUID(owner_guid);
@@ -253,22 +214,17 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction)
{
std::ostringstream subject;
subject << auction->item_template << ":0:" << AUCTION_EXPIRED;
if (owner && owner->GetGUIDLow() != auctionbot.GetAHBplayerGUID())
owner->GetSession()->SendAuctionOwnerNotification(auction);
MailItemsInfo mi;
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
}
}
void AuctionHouseMgr::LoadAuctionItems()
{
// data needs to be at first place for Item::LoadFromDB
QueryResult *result = CharacterDatabase.Query("SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid");
if (!result)
{
barGoLink bar(1);
@@ -277,45 +233,34 @@ void AuctionHouseMgr::LoadAuctionItems()
sLog.outString(">> Loaded 0 auction items");
return;
}
barGoLink bar(result->GetRowCount());
uint32 count = 0;
Field *fields;
do
{
bar.step();
fields = result->Fetch();
uint32 item_guid = fields[1].GetUInt32();
uint32 item_template = fields[2].GetUInt32();
ItemPrototype const *proto = objmgr.GetItemPrototype(item_template);
if (!proto)
{
sLog.outError("AuctionHouseMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid,item_template);
continue;
}
Item *item = NewItemOrBag(proto);
if (!item->LoadFromDB(item_guid,0, result))
{
delete item;
continue;
}
AddAItem(item);
++count;
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString(">> Loaded %u auction items", count);
}
void AuctionHouseMgr::LoadAuctions()
{
QueryResult *result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse");
@@ -327,11 +272,9 @@ void AuctionHouseMgr::LoadAuctions()
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
return;
}
Field *fields = result->Fetch();
uint32 AuctionCount=fields[0].GetUInt32();
delete result;
if (!AuctionCount)
{
barGoLink bar(1);
@@ -340,7 +283,6 @@ void AuctionHouseMgr::LoadAuctions()
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
return;
}
result = CharacterDatabase.Query("SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit FROM auctionhouse");
if (!result)
{
@@ -350,17 +292,12 @@ void AuctionHouseMgr::LoadAuctions()
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
return;
}
barGoLink bar(AuctionCount);
AuctionEntry *aItem;
do
{
fields = result->Fetch();
bar.step();
aItem = new AuctionEntry;
aItem->Id = fields[0].GetUInt32();
aItem->auctioneer = fields[1].GetUInt32();
@@ -373,7 +310,6 @@ void AuctionHouseMgr::LoadAuctions()
aItem->bid = fields[8].GetUInt32();
aItem->startbid = fields[9].GetUInt32();
aItem->deposit = fields[10].GetUInt32();
CreatureData const* auctioneerData = objmgr.GetCreatureData(aItem->auctioneer);
if (!auctioneerData)
{
@@ -382,7 +318,6 @@ void AuctionHouseMgr::LoadAuctions()
delete aItem;
continue;
}
CreatureInfo const* auctioneerInfo = objmgr.GetCreatureTemplate(auctioneerData->id);
if (!auctioneerInfo)
{
@@ -391,7 +326,6 @@ void AuctionHouseMgr::LoadAuctions()
delete aItem;
continue;
}
aItem->auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(auctioneerInfo->faction_A);
if (!aItem->auctionHouseEntry)
{
@@ -401,7 +335,6 @@ void AuctionHouseMgr::LoadAuctions()
delete aItem;
continue;
}
// check if sold item exists for guid
// and item_template in fact (GetAItem will fail if problematic in result check in AuctionHouseMgr::LoadAuctionItems)
if (!GetAItem(aItem->item_guidlow))
@@ -411,44 +344,35 @@ void AuctionHouseMgr::LoadAuctions()
delete aItem;
continue;
}
GetAuctionsMap(auctioneerInfo->faction_A)->AddAuction(aItem);
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString(">> Loaded %u auctions", AuctionCount);
}
void AuctionHouseMgr::AddAItem(Item* it)
{
ASSERT(it);
ASSERT(mAitems.find(it->GetGUIDLow()) == mAitems.end());
mAitems[it->GetGUIDLow()] = it;
}
bool AuctionHouseMgr::RemoveAItem(uint32 id)
{
ItemMap::iterator i = mAitems.find(id);
if (i == mAitems.end())
return false;
mAitems.erase(i);
return true;
}
void AuctionHouseMgr::Update()
{
mHordeAuctions.Update();
mAllianceAuctions.Update();
mNeutralAuctions.Update();
}
AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId)
{
uint32 houseid = 7; // goblin auction house
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
{
//FIXME: found way for proper auctionhouse selection by another way
@@ -481,7 +405,6 @@ AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTem
}
}
}
return sAuctionHouseStore.LookupEntry(houseid);
}
void AuctionHouseObject::AddAuction(AuctionEntry *ah)
@@ -490,57 +413,45 @@ AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTem
AuctionsMap[ah->Id] = ah;
auctionbot.IncrementItemCounts(ah);
}
bool AuctionHouseObject::RemoveAuction(AuctionEntry *auction, uint32 item_template)
{
auctionbot.DecrementItemCounts(auction, item_template);
return AuctionsMap.erase(auction->Id) ? true : false;
}
void AuctionHouseObject::Update()
{
time_t curTime = sWorld.GetGameTime();
///- Handle expired auctions
// If storage is empty, no need to update. next == NULL in this case.
if (AuctionsMap.empty())
return;
QueryResult* result = CharacterDatabase.PQuery("SELECT id FROM auctionhouse WHERE time <= %u ORDER BY TIME ASC", (uint32)curTime+60);
if (!result)
{
delete result;
return;
}
if (result->GetRowCount() == 0)
{
delete result;
return;
}
vector<uint32> expiredAuctions;
do
{
uint32 tmpdata = result->Fetch()->GetUInt32();
expiredAuctions.push_back(tmpdata);
} while (result->NextRow());
delete result;
vector<uint32>::iterator iter = expiredAuctions.begin();
while (!expiredAuctions.empty())
{
// from auctionhousehandler.cpp, creates auction pointer & player pointer
AuctionEntry* auction = GetAuction(*iter);
// Erase the auction from the vector.
expiredAuctions.erase(iter);
if (!auction)
continue;
///- Either cancel the auction if there was no bidder
if (auction->bidder == 0)
auctionmgr.SendAuctionExpiredMail(auction);
@@ -553,7 +464,6 @@ void AuctionHouseObject::Update()
auctionmgr.SendAuctionSuccessfulMail(auction);
auctionmgr.SendAuctionWonMail(auction);
}
///- In any case clear the auction
auction->DeleteFromDB();
uint32 item_template = auction->item_template;
@@ -561,7 +471,6 @@ void AuctionHouseObject::Update()
RemoveAuction(auction, item_template);
}
}
void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount)
{
for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin();itr != AuctionsMap.end();++itr)
@@ -571,12 +480,10 @@ void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player,
{
if (itr->second->BuildAuctionInfo(data))
++count;
++totalcount;
}
}
}
void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount)
{
for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin();itr != AuctionsMap.end();++itr)
@@ -586,50 +493,38 @@ void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player,
{
if (Aentry->BuildAuctionInfo(data))
++count;
++totalcount;
}
}
}
void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player,
std::wstring const& wsearchedname, uint32 listfrom, uint32 levelmin, uint32 levelmax, uint32 usable,
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
uint32& count, uint32& totalcount)
{
int loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin();itr != AuctionsMap.end();++itr)
{
AuctionEntry *Aentry = itr->second;
Item *item = auctionmgr.GetAItem(Aentry->item_guidlow);
if (!item)
continue;
ItemPrototype const *proto = item->GetProto();
if (itemClass != 0xffffffff && proto->Class != itemClass)
continue;
if (itemSubClass != 0xffffffff && proto->SubClass != itemSubClass)
continue;
if (inventoryType != 0xffffffff && proto->InventoryType != inventoryType)
continue;
if (quality != 0xffffffff && proto->Quality != quality)
continue;
if (levelmin != 0x00 && (proto->RequiredLevel < levelmin || (levelmax != 0x00 && proto->RequiredLevel > levelmax)))
continue;
if (usable != 0x00 && player->CanUseItem(item) != EQUIP_ERR_OK)
continue;
std::string name = proto->Name1;
if (name.empty())
continue;
// local name
if (loc_idx >= 0)
{
@@ -640,10 +535,8 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player
name = il->Name[loc_idx];
}
}
if (!wsearchedname.empty() && !Utf8FitTo(name, wsearchedname))
continue;
if (count < 50 && totalcount >= listfrom)
{
++count;
@@ -652,7 +545,6 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player
++totalcount;
}
}
//this function inserts to WorldPacket auction's data
bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const
{
@@ -664,14 +556,12 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const
}
data << uint32(Id);
data << uint32(pItem->GetEntry());
for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i)
{
data << uint32(pItem->GetEnchantmentId(EnchantmentSlot(i)));
data << uint32(pItem->GetEnchantmentDuration(EnchantmentSlot(i)));
data << uint32(pItem->GetEnchantmentCharges(EnchantmentSlot(i)));
}
data << uint32(pItem->GetItemRandomPropertyId()); //random item property id
data << uint32(pItem->GetItemSuffixFactor()); //SuffixFactor
data << uint32(pItem->GetCount()); //item->count
@@ -687,7 +577,6 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const
data << uint32(bid); //current bid
return true;
}
uint32 AuctionEntry::GetAuctionCut() const
{
int32 cut = int32(((double)auctionHouseEntry->cutPercent / 100.0f) * (double)sWorld.getRate(RATE_AUCTION_CUT)) * bid;
@@ -696,7 +585,6 @@ uint32 AuctionEntry::GetAuctionCut() const
else
return 0;
}
/// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
uint32 AuctionEntry::GetAuctionOutBid() const
{
@@ -705,13 +593,11 @@ uint32 AuctionEntry::GetAuctionOutBid() const
outbid = 1;
return outbid;
}
void AuctionEntry::DeleteFromDB() const
{
//No SQL injection (Id is integer)
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",Id);
}
void AuctionEntry::SaveToDB() const
{
//No SQL injection (no strings)
-33
View File
@@ -17,22 +17,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _AUCTION_HOUSE_MGR_H
#define _AUCTION_HOUSE_MGR_H
#include "Policies/Singleton.h"
#include "SharedDefines.h"
#include "AuctionHouseBot.h"
class Item;
class Player;
class WorldPacket;
#define MIN_AUCTION_TIME (12*HOUR)
enum AuctionError
{
AUCTION_OK = 0,
@@ -41,14 +34,12 @@ enum AuctionError
AUCTION_ITEM_NOT_FOUND = 4,
CANNOT_BID_YOUR_AUCTION_ERROR = 10
};
enum AuctionAction
{
AUCTION_SELL_ITEM = 0,
AUCTION_CANCEL = 1,
AUCTION_PLACE_BID = 2
};
struct AuctionEntry
{
uint32 Id;
@@ -63,7 +54,6 @@ struct AuctionEntry
uint32 bidder;
uint32 deposit; //deposit can be calculated only when creating auction
AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc
// helpers
uint32 GetHouseId() const { return auctionHouseEntry->houseId; }
uint32 GetHouseFaction() const { return auctionHouseEntry->faction; }
@@ -73,7 +63,6 @@ struct AuctionEntry
void DeleteFromDB() const;
void SaveToDB() const;
};
//this class is used as auctionhouse instance
class AuctionHouseObject
{
@@ -85,51 +74,37 @@ class AuctionHouseObject
for (AuctionEntryMap::iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
delete itr->second;
}
typedef std::map<uint32, AuctionEntry*> AuctionEntryMap;
uint32 Getcount() { return AuctionsMap.size(); }
AuctionEntryMap::iterator GetAuctionsBegin() {return AuctionsMap.begin();}
AuctionEntryMap::iterator GetAuctionsEnd() {return AuctionsMap.end();}
AuctionEntry* GetAuction(uint32 id) const
{
AuctionEntryMap::const_iterator itr = AuctionsMap.find(id);
return itr != AuctionsMap.end() ? itr->second : NULL;
}
void AddAuction(AuctionEntry *ah);
bool RemoveAuction(AuctionEntry *auction, uint32 item_template);
void Update();
void BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount);
void BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount);
void BuildListAuctionItems(WorldPacket& data, Player* player,
std::wstring const& searchedname, uint32 listfrom, uint32 levelmin, uint32 levelmax, uint32 usable,
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
uint32& count, uint32& totalcount);
private:
AuctionEntryMap AuctionsMap;
// storage for "next" auction item for next Update()
AuctionEntryMap::const_iterator next;
};
class AuctionHouseMgr
{
public:
AuctionHouseMgr();
~AuctionHouseMgr();
typedef UNORDERED_MAP<uint32, Item*> ItemMap;
AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId);
AuctionHouseObject* GetBidsMap(uint32 factionTemplateId);
Item* GetAItem(uint32 id)
{
ItemMap::const_iterator itr = mAitems.find(id);
@@ -139,7 +114,6 @@ class AuctionHouseMgr
}
return NULL;
}
//auction messages
void SendAuctionWonMail(AuctionEntry * auction);
void SendAuctionSalePendingMail(AuctionEntry * auction);
@@ -147,25 +121,18 @@ class AuctionHouseMgr
void SendAuctionExpiredMail(AuctionEntry * auction);
static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem);
static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId);
public:
//load first auction items, because of check if item exists, when loading
void LoadAuctionItems();
void LoadAuctions();
void AddAItem(Item* it);
bool RemoveAItem(uint32 id);
void Update();
private:
AuctionHouseObject mHordeAuctions;
AuctionHouseObject mAllianceAuctions;
AuctionHouseObject mNeutralAuctions;
ItemMap mAitems;
};
#define auctionmgr Trinity::Singleton<AuctionHouseMgr>::Instance()
#endif
-43
View File
@@ -17,25 +17,19 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "ObjectMgr.h"
#include "Database/DatabaseEnv.h"
#include "Bag.h"
#include "Log.h"
#include "UpdateData.h"
Bag::Bag( ): Item()
{
m_objectType |= TYPEMASK_CONTAINER;
m_objectTypeId = TYPEID_CONTAINER;
m_valuesCount = CONTAINER_END;
memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE);
}
Bag::~Bag()
{
for(uint8 i = 0; i < MAX_BAG_SIZE; ++i)
@@ -51,68 +45,52 @@ Bag::~Bag()
delete m_bagslot[i];
}
}
void Bag::AddToWorld()
{
Item::AddToWorld();
for(uint32 i = 0; i < GetBagSize(); ++i)
if(m_bagslot[i])
m_bagslot[i]->AddToWorld();
}
void Bag::RemoveFromWorld()
{
for(uint32 i = 0; i < GetBagSize(); ++i)
if(m_bagslot[i])
m_bagslot[i]->RemoveFromWorld();
Item::RemoveFromWorld();
}
bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner)
{
ItemPrototype const * itemProto = objmgr.GetItemPrototype(itemid);
if(!itemProto || itemProto->ContainerSlots > MAX_BAG_SIZE)
return false;
Object::_Create( guidlow, 0, HIGHGUID_CONTAINER );
SetEntry(itemid);
SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0);
SetUInt64Value(ITEM_FIELD_CONTAINED, owner ? owner->GetGUID() : 0);
SetUInt32Value(ITEM_FIELD_MAXDURABILITY, itemProto->MaxDurability);
SetUInt32Value(ITEM_FIELD_DURABILITY, itemProto->MaxDurability);
SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags);
SetUInt32Value(ITEM_FIELD_STACK_COUNT, 1);
// Setting the number of Slots the Container has
SetUInt32Value(CONTAINER_FIELD_NUM_SLOTS, itemProto->ContainerSlots);
// Cleaning 20 slots
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
{
SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0);
m_bagslot[i] = NULL;
}
return true;
}
void Bag::SaveToDB()
{
Item::SaveToDB();
}
bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result)
{
if(!Item::LoadFromDB(guid, owner_guid, result))
return false;
// cleanup bag content related item value fields (its will be filled correctly from `character_inventory`)
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
{
@@ -123,44 +101,34 @@ bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result)
m_bagslot[i] = NULL;
}
}
return true;
}
void Bag::DeleteFromDB()
{
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
if (m_bagslot[i])
m_bagslot[i]->DeleteFromDB();
Item::DeleteFromDB();
}
uint32 Bag::GetFreeSlots() const
{
uint32 slots = 0;
for (uint32 i=0; i < GetBagSize(); ++i)
if (!m_bagslot[i])
++slots;
return slots;
}
void Bag::RemoveItem( uint8 slot, bool /*update*/ )
{
assert(slot < MAX_BAG_SIZE);
if (m_bagslot[slot])
m_bagslot[slot]->SetContainer(NULL);
m_bagslot[slot] = NULL;
SetUInt64Value( CONTAINER_FIELD_SLOT_1 + (slot * 2), 0 );
}
void Bag::StoreItem( uint8 slot, Item *pItem, bool /*update*/ )
{
assert(slot < MAX_BAG_SIZE);
if( pItem )
{
m_bagslot[slot] = pItem;
@@ -171,26 +139,21 @@ void Bag::StoreItem( uint8 slot, Item *pItem, bool /*update*/ )
pItem->SetSlot(slot);
}
}
void Bag::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const
{
Item::BuildCreateUpdateBlockForPlayer( data, target );
for (uint32 i = 0; i < GetBagSize(); ++i)
if(m_bagslot[i])
m_bagslot[i]->BuildCreateUpdateBlockForPlayer( data, target );
}
// If the bag is empty returns true
bool Bag::IsEmpty() const
{
for(uint32 i = 0; i < GetBagSize(); ++i)
if (m_bagslot[i])
return false;
return true;
}
uint32 Bag::GetItemCount( uint32 item, Item* eItem ) const
{
Item *pItem;
@@ -201,7 +164,6 @@ uint32 Bag::GetItemCount( uint32 item, Item* eItem ) const
if( pItem && pItem != eItem && pItem->GetEntry() == item )
count += pItem->GetCount();
}
if(eItem && eItem->GetProto()->GemProperties)
{
for(uint32 i=0; i < GetBagSize(); ++i)
@@ -211,25 +173,20 @@ uint32 Bag::GetItemCount( uint32 item, Item* eItem ) const
count += pItem->GetGemCountWithID(item);
}
}
return count;
}
uint8 Bag::GetSlotByItemGUID(uint64 guid) const
{
for(uint32 i = 0; i < GetBagSize(); ++i)
if(m_bagslot[i] != 0)
if(m_bagslot[i]->GetGUID() == guid)
return i;
return NULL_SLOT;
}
Item* Bag::GetItemByPos( uint8 slot ) const
{
if( slot < GetBagSize() )
return m_bagslot[slot];
return NULL;
}
-15
View File
@@ -17,40 +17,29 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_BAG_H
#define TRINITY_BAG_H
// Maximum 36 Slots ( (CONTAINER_END - CONTAINER_FIELD_SLOT_1)/2
#define MAX_BAG_SIZE 36 // 2.0.12
#include "Item.h"
#include "ItemPrototype.h"
class Bag : public Item
{
public:
Bag();
~Bag();
void AddToWorld();
void RemoveFromWorld();
bool Create(uint32 guidlow, uint32 itemid, Player const* owner);
void Clear();
void StoreItem( uint8 slot, Item *pItem, bool update );
void RemoveItem( uint8 slot, bool update );
Item* GetItemByPos( uint8 slot ) const;
uint32 GetItemCount( uint32 item, Item* eItem = NULL ) const;
uint8 GetSlotByItemGUID(uint64 guid) const;
bool IsEmpty() const;
uint32 GetFreeSlots() const;
uint32 GetBagSize() const { return GetUInt32Value(CONTAINER_FIELD_NUM_SLOTS); }
// DB operations
// overwrite virtual Item::SaveToDB
void SaveToDB();
@@ -58,15 +47,11 @@ class Bag : public Item
bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result = NULL);
// overwrite virtual Item::DeleteFromDB
void DeleteFromDB();
void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const;
protected:
// Bag Storage space
Item* m_bagslot[MAX_BAG_SIZE];
};
inline Item* NewItemOrBag(ItemPrototype const * proto)
{
return (proto->InventoryType == INVTYPE_BAG) ? new Bag : new Item;
File diff suppressed because it is too large Load Diff
-88
View File
@@ -17,21 +17,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __BATTLEGROUND_H
#define __BATTLEGROUND_H
#include "Common.h"
#include "SharedDefines.h"
class Creature;
class GameObject;
class Group;
class Player;
class WorldPacket;
struct WorldSafeLocsEntry;
enum BattleGroundSounds
{
SOUND_HORDE_WINS = 8454,
@@ -39,7 +34,6 @@ enum BattleGroundSounds
SOUND_BG_START = 3439,
SOUND_BG_START_L70ETC = 11803,
};
enum BattleGroundQuests
{
SPELL_WS_QUEST_REWARD = 43483,
@@ -50,7 +44,6 @@ enum BattleGroundQuests
SPELL_AB_QUEST_REWARD_4_BASES = 24061,
SPELL_AB_QUEST_REWARD_5_BASES = 24064
};
enum BattleGroundMarks
{
SPELL_WS_MARK_LOSER = 24950,
@@ -64,19 +57,16 @@ enum BattleGroundMarks
ITEM_AB_MARK_OF_HONOR = 20559,
ITEM_EY_MARK_OF_HONOR = 29024
};
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
@@ -93,7 +83,6 @@ enum BattleGroundSpells
SPELL_RECENTLY_DROPPED_FLAG = 42792, // Recently Dropped Flag
SPELL_AURA_PLAYER_INACTIVE = 43681 // Inactive
};
enum BattleGroundTimeIntervals
{
RESURRECTION_INTERVAL = 30000, // ms
@@ -106,7 +95,6 @@ enum BattleGroundTimeIntervals
RESPAWN_IMMEDIATELY = 0, // secs
BUFF_RESPAWN_TIME = 180, // secs
};
enum BattleGroundStartTimeIntervals
{
BG_START_DELAY_2M = 120000, // ms (2 minutes)
@@ -115,16 +103,13 @@ enum BattleGroundStartTimeIntervals
BG_START_DELAY_15S = 15000, // ms (15 seconds) Used only in arena
BG_START_DELAY_NONE = 0, // ms
};
enum BattleGroundBuffObjects
{
BG_OBJECTID_SPEEDBUFF_ENTRY = 179871,
BG_OBJECTID_REGENBUFF_ENTRY = 179904,
BG_OBJECTID_BERSERKERBUFF_ENTRY = 179905
};
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
@@ -133,22 +118,18 @@ enum BattleGroundStatus
STATUS_IN_PROGRESS = 3, // means bg is running
STATUS_WAIT_LEAVE = 4 // means some faction has won BG and it is ending
};
struct BattleGroundPlayer
{
time_t OfflineRemoveTime; // for tracking and removing offline players from queue after 5 minutes
uint32 Team; // Player's team
};
struct BattleGroundObjectInfo
{
BattleGroundObjectInfo() : object(NULL), timer(0), spellid(0) {}
GameObject *object;
int32 timer;
uint32 spellid;
};
// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
enum BattleGroundQueueTypeId
{
@@ -163,7 +144,6 @@ enum BattleGroundQueueTypeId
BATTLEGROUND_QUEUE_5v5 = 8
};
#define MAX_BATTLEGROUND_QUEUE_TYPES 9
enum BGQueueIdBasedOnLevel // queue_id for level ranges
{
QUEUE_ID_MAX_LEVEL_19 = 0,
@@ -176,7 +156,6 @@ enum BGQueueIdBasedOnLevel // queue_id for level ranges
QUEUE_ID_MAX_LEVEL_80 = 7
};
#define MAX_BATTLEGROUND_QUEUES 8
enum ScoreType
{
SCORE_KILLING_BLOWS = 1,
@@ -202,34 +181,29 @@ enum ScoreType
SCORE_SECONDARY_OBJECTIVES = 17
// TODO : implement them
};
enum ArenaType
{
ARENA_TYPE_2v2 = 2,
ARENA_TYPE_3v3 = 3,
ARENA_TYPE_5v5 = 5
};
enum BattleGroundType
{
TYPE_BATTLEGROUND = 3,
TYPE_ARENA = 4
};
enum BattleGroundWinner
{
WINNER_HORDE = 0,
WINNER_ALLIANCE = 1,
WINNER_NONE = 2
};
enum BattleGroundTeamId
{
BG_TEAM_ALLIANCE = 0,
BG_TEAM_HORDE = 1
};
#define BG_TEAMS_COUNT 2
enum BattleGroundStartingEvents
{
BG_STARTING_EVENT_NONE = 0x00,
@@ -238,7 +212,6 @@ enum BattleGroundStartingEvents
BG_STARTING_EVENT_3 = 0x04,
BG_STARTING_EVENT_4 = 0x08
};
enum BattleGroundStartingEventsIds
{
BG_STARTING_EVENT_FIRST = 0,
@@ -247,7 +220,6 @@ enum BattleGroundStartingEventsIds
BG_STARTING_EVENT_FOURTH = 3
};
#define BG_STARTING_EVENT_COUNT 4
enum BattleGroundJoinError
{
BG_JOIN_ERR_OK = 0,
@@ -261,7 +233,6 @@ enum BattleGroundJoinError
BG_JOIN_ERR_ALL_QUEUES_USED = 8,
BG_JOIN_ERR_GROUP_NOT_ENOUGH = 9
};
class BattleGroundScore
{
public:
@@ -269,7 +240,6 @@ class BattleGroundScore
BonusHonor(0), DamageDone(0), HealingDone(0)
{}
virtual ~BattleGroundScore() {} //virtual destructor is used when deleting score from scores map
uint32 KillingBlows;
uint32 Deaths;
uint32 HonorableKills;
@@ -277,14 +247,12 @@ class BattleGroundScore
uint32 DamageDone;
uint32 HealingDone;
};
enum BGHonorMode
{
BG_NORMAL = 0,
BG_HOLIDAY,
BG_HONOR_MODE_NUM
};
/*
This class is used to:
1. Add player to battleground
@@ -295,7 +263,6 @@ This class is used to:
class BattleGround
{
friend class BattleGroundMgr;
public:
/* Construction */
BattleGround();
@@ -312,11 +279,9 @@ class BattleGround
virtual void ResetBGSubclass() // must be implemented in BG subclass
{
}
/* achievement req. */
virtual bool IsAllNodesConrolledByTeam(uint32 /*team*/) const { return false; }
bool IsTeamScoreInRange(uint32 team, uint32 minScore, uint32 maxScore) const;
/* Battleground */
// Get methods:
char const* GetName() const { return m_Name; }
@@ -330,19 +295,15 @@ class BattleGround
uint32 GetLastResurrectTime() const { return m_LastResurrectTime; }
uint32 GetMaxPlayers() const { return m_MaxPlayers; }
uint32 GetMinPlayers() const { return m_MinPlayers; }
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; }
uint8 GetWinner() const { return m_Winner; }
uint32 GetBattlemasterEntry() const;
uint32 GetBonusHonorFromKill(uint32 kills) const;
// Set methods:
void SetName(char const* Name) { m_Name = Name; }
void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; }
@@ -366,16 +327,12 @@ class BattleGround
void SetArenaType(uint8 type) { m_ArenaType = type; }
void SetArenaorBGType(bool _isArena) { m_IsArena = _isArena; }
void SetWinner(uint8 winner) { m_Winner = winner; }
void ModifyStartDelayTime(int diff) { m_StartDelayTime -= diff; }
void SetStartDelayTime(int Time) { m_StartDelayTime = Time; }
void SetMaxPlayersPerTeam(uint32 MaxPlayers) { m_MaxPlayersPerTeam = MaxPlayers; }
void SetMinPlayersPerTeam(uint32 MinPlayers) { m_MinPlayersPerTeam = MinPlayers; }
void AddToBGFreeSlotQueue(); //this queue will be useful when more battlegrounds instances will be available
void RemoveFromBGFreeSlotQueue(); //this method could delete whole BG instance, if another free is available
void DecreaseInvitedCount(uint32 team) { (team == ALLIANCE) ? --m_InvitedAlliance : --m_InvitedHorde; }
void IncreaseInvitedCount(uint32 team) { (team == ALLIANCE) ? ++m_InvitedAlliance : ++m_InvitedHorde; }
uint32 GetInvitedCount(uint32 team) const
@@ -387,33 +344,25 @@ class BattleGround
}
bool HasFreeSlots() const;
uint32 GetFreeSlotsForTeam(uint32 Team) const;
bool isArena() const { return m_IsArena; }
bool isBattleGround() const { return !m_IsArena; }
bool isRated() const { return m_IsRated; }
typedef std::map<uint64, BattleGroundPlayer> BattleGroundPlayerMap;
BattleGroundPlayerMap const& GetPlayers() const { return m_Players; }
uint32 GetPlayersSize() const { return m_Players.size(); }
typedef std::map<uint64, BattleGroundScore*> BattleGroundScoreMap;
BattleGroundScoreMap::const_iterator GetPlayerScoresBegin() const { return m_PlayerScores.begin(); }
BattleGroundScoreMap::const_iterator GetPlayerScoresEnd() const { return m_PlayerScores.end(); }
uint32 GetPlayerScoresSize() const { return m_PlayerScores.size(); }
uint32 GetReviveQueueSize() const { return m_ReviveQueue.size(); }
void AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid);
void RemovePlayerFromResurrectQueue(uint64 player_guid);
void StartBattleGround();
GameObject* GetBGObject(uint32 type);
Creature* GetBGCreature(uint32 type);
/* Location */
void SetMapId(uint32 MapID) { m_MapId = MapID; }
uint32 GetMapId() const { return m_MapId; }
void SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O);
void GetTeamStartLoc(uint32 TeamID, float &X, float &Y, float &Z, float &O) const
{
@@ -423,17 +372,14 @@ class BattleGround
Z = m_TeamStartLocZ[idx];
O = m_TeamStartLocO[idx];
}
/* Packet Transfer */
// method that should fill worldpacket with actual world states (not yet implemented for all battlegrounds!)
virtual void FillInitialWorldStates(WorldPacket& /*data*/) {}
void SendPacketToTeam(uint32 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 PlaySoundToTeam(uint32 SoundID, uint32 TeamID);
void PlaySoundToAll(uint32 SoundID);
void CastSpellOnTeam(uint32 SpellID, uint32 TeamID);
@@ -448,19 +394,14 @@ class BattleGround
void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player *Source);
void EndBattleGround(uint32 winner);
void BlockMovement(Player *plr);
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(uint32 TeamID) const { return TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE]; }
void SetBgRaid(uint32 TeamID, Group *bg_raid);
virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
static BattleGroundTeamId GetTeamIndexByTeamId(uint32 Team) { return Team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; }
uint32 GetPlayersCountByTeam(uint32 Team) const { return m_PlayersCount[GetTeamIndexByTeamId(Team)]; }
uint32 GetAlivePlayersCountByTeam(uint32 Team) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases
@@ -471,41 +412,32 @@ class BattleGround
else
++m_PlayersCount[GetTeamIndexByTeamId(Team)];
}
// used for rated arena battles
void SetArenaTeamIdForTeam(uint32 Team, uint32 ArenaTeamId) { m_ArenaTeamIds[GetTeamIndexByTeamId(Team)] = ArenaTeamId; }
uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; }
void SetArenaTeamRatingChangeForTeam(uint32 Team, int32 RatingChange) { m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)] = RatingChange; }
int32 GetArenaTeamRatingChangeForTeam(uint32 Team) const { return m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)]; }
void CheckArenaWinConditions();
/* Triggers handle */
// must be implemented in BG subclass
virtual void HandleAreaTrigger(Player* /*Source*/, 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* /*target_obj*/) {}
virtual void EventPlayerCapturedFlag(Player* /*player*/) {}
void EventPlayerLoggedIn(Player* player, uint64 plr_guid);
void EventPlayerLoggedOut(Player* player);
/* Death related */
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
virtual void AddPlayer(Player *plr); // must be implemented in BG subclass
void AddOrSetPlayerToCorrectBgGroup(Player *plr, uint64 plr_guid, uint32 team);
virtual void RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket);
// can be extended in in BG subclass
void HandleTriggerBuff(uint64 const& go_guid);
void SetHoliday(bool is_holiday);
// TODO: make this protected:
typedef std::vector<uint64> BGObjects;
typedef std::vector<uint64> BGCreatures;
@@ -519,40 +451,30 @@ class BattleGround
bool DelObject(uint32 type);
bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team);
int32 GetObjectType(uint64 guid);
void DoorOpen(uint32 type);
void DoorClose(uint32 type);
//to be removed
const char *GetTrinityString(int32 entry);
virtual bool HandlePlayerUnderMap(Player * /*plr*/) { return false; }
// since arenas can be AvA or Hvh, we have to get the "temporary" team of a player
uint32 GetPlayerTeam(uint64 guid);
uint32 GetOtherTeam(uint32 teamId);
bool IsPlayerInBattleGround(uint64 guid);
void SetDeleteThis() {m_SetDeleteThis = true;}
/* virtual score-array - get's used in bg-subclasses */
int32 m_TeamScores[BG_TEAMS_COUNT];
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* plr);
/* Scorekeeping */
BattleGroundScoreMap m_PlayerScores; // Player scores
// must be implemented in BG subclass
virtual void RemovePlayer(Player * /*player*/, uint64 /*guid*/) {}
/* 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
*/
@@ -560,9 +482,7 @@ class BattleGround
BattleGroundStartTimeIntervals m_StartDelayTimes[BG_STARTING_EVENT_COUNT];
//this must be filled in constructors!
uint32 m_StartMessageIds[BG_STARTING_EVENT_COUNT];
bool m_BuffChange;
BGHonorMode m_HonorMode;
private:
/* Battleground */
@@ -584,28 +504,21 @@ class BattleGround
bool m_PrematureCountDown;
uint32 m_PrematureCountDownTimer;
char const *m_Name;
/* 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_InvitedAlliance;
uint32 m_InvitedHorde;
/* Raid Group */
Group *m_BgRaids[BG_TEAMS_COUNT]; // 0 - alliance, 1 - horde
/* 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];
/* Limits */
uint32 m_LevelMin;
uint32 m_LevelMax;
@@ -613,7 +526,6 @@ class BattleGround
uint32 m_MaxPlayers;
uint32 m_MinPlayersPerTeam;
uint32 m_MinPlayers;
/* Start location */
uint32 m_MapId;
float m_TeamStartLocX[BG_TEAMS_COUNT];
-14
View File
@@ -17,15 +17,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "BattleGround.h"
#include "BattleGroundAA.h"
#include "Language.h"
#include "Player.h"
BattleGroundAA::BattleGroundAA()
{
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
@@ -36,47 +33,36 @@ BattleGroundAA::BattleGroundAA()
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
}
BattleGroundAA::~BattleGroundAA()
{
}
void BattleGroundAA::Update(uint32 diff)
{
BattleGround::Update(diff);
}
void BattleGroundAA::StartingEventCloseDoors()
{
}
void BattleGroundAA::StartingEventOpenDoors()
{
}
void BattleGroundAA::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map, default values are set in constructor
BattleGroundAAScore* sc = new BattleGroundAAScore;
m_PlayerScores[plr->GetGUID()] = sc;
}
void BattleGroundAA::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
{
}
void BattleGroundAA::HandleKillPlayer(Player* player, Player* killer)
{
BattleGround::HandleKillPlayer(player, killer);
}
void BattleGroundAA::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
{
}
bool BattleGroundAA::SetupBattleGround()
{
return true;
-6
View File
@@ -19,9 +19,7 @@
*/
#ifndef __BATTLEGROUNDAA_H
#define __BATTLEGROUNDAA_H
class BattleGround;
class BattleGroundAAScore : public BattleGroundScore
{
public:
@@ -29,21 +27,17 @@ class BattleGroundAAScore : public BattleGroundScore
virtual ~BattleGroundAAScore() {};
//TODO fix me
};
class BattleGroundAA : public BattleGround
{
friend class BattleGroundMgr;
public:
BattleGroundAA();
~BattleGroundAA();
void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
-82
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "World.h"
#include "WorldPacket.h"
#include "ObjectMgr.h"
@@ -29,42 +28,34 @@
#include "Object.h"
#include "Player.h"
#include "Util.h"
// these variables aren't used outside of this file, so declare them only here
uint32 BG_AB_HonorScoreTicks[BG_HONOR_MODE_NUM] = {
330, // normal honor
200 // holiday
};
uint32 BG_AB_ReputationScoreTicks[BG_HONOR_MODE_NUM] = {
200, // normal honor
150 // holiday
};
BattleGroundAB::BattleGroundAB()
{
m_BuffChange = true;
m_BgObjects.resize(BG_AB_OBJECT_MAX);
m_BgCreatures.resize(BG_AB_ALL_NODES_COUNT);
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_AB_START_TWO_MINUTES;
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_AB_START_ONE_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_AB_START_HALF_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_AB_HAS_BEGUN;
}
BattleGroundAB::~BattleGroundAB()
{
}
void BattleGroundAB::Update(uint32 diff)
{
BattleGround::Update(diff);
if (GetStatus() == STATUS_IN_PROGRESS)
{
int team_points[BG_TEAMS_COUNT] = { 0, 0 };
for (int node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
{
// 3 sec delay to spawn new banner instead previous despawned one
@@ -78,7 +69,6 @@ void BattleGroundAB::Update(uint32 diff)
_CreateBanner(node, m_BannerTimers[node].type, m_BannerTimers[node].teamIndex, false);
}
}
// 1-minute to occupy a node from contested state
if (m_NodeTimers[node])
{
@@ -98,7 +88,6 @@ void BattleGroundAB::Update(uint32 diff)
_SendNodeUpdate(node);
_NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE);
// Message to chatlog
if (teamIndex == 0)
{
// FIXME: team and node names not localized
@@ -113,12 +102,10 @@ void BattleGroundAB::Update(uint32 diff)
}
}
}
for (int team = 0; team < BG_TEAMS_COUNT; ++team)
if (m_Nodes[node] == team + BG_AB_NODE_TYPE_OCCUPIED)
++team_points[team];
}
// Accumulate points
for (int team = 0; team < BG_TEAMS_COUNT; ++team)
{
@@ -151,7 +138,6 @@ void BattleGroundAB::Update(uint32 diff)
PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY);
m_IsInformedNearVictory = true;
}
if (m_TeamScores[team] > BG_AB_MAX_TEAM_SCORE)
m_TeamScores[team] = BG_AB_MAX_TEAM_SCORE;
if (team == BG_TEAM_ALLIANCE)
@@ -165,7 +151,6 @@ void BattleGroundAB::Update(uint32 diff)
m_TeamScores500Disadvantage[otherTeam] = true;
}
}
// Test win condition
if (m_TeamScores[BG_TEAM_ALLIANCE] >= BG_AB_MAX_TEAM_SCORE)
EndBattleGround(ALLIANCE);
@@ -173,7 +158,6 @@ void BattleGroundAB::Update(uint32 diff)
EndBattleGround(HORDE);
}
}
void BattleGroundAB::StartingEventCloseDoors()
{
// despawn banners, auras and buffs
@@ -181,18 +165,15 @@ void BattleGroundAB::StartingEventCloseDoors()
SpawnBGObject(obj, RESPAWN_ONE_DAY);
for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT * 3; ++i)
SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + i, RESPAWN_ONE_DAY);
// Starting doors
DoorClose(BG_AB_OBJECT_GATE_A);
DoorClose(BG_AB_OBJECT_GATE_H);
SpawnBGObject(BG_AB_OBJECT_GATE_A, RESPAWN_IMMEDIATELY);
SpawnBGObject(BG_AB_OBJECT_GATE_H, RESPAWN_IMMEDIATELY);
// Starting base spirit guides
_NodeOccupied(BG_AB_SPIRIT_ALIANCE,ALLIANCE);
_NodeOccupied(BG_AB_SPIRIT_HORDE,HORDE);
}
void BattleGroundAB::StartingEventOpenDoors()
{
// spawn neutral banners
@@ -207,26 +188,20 @@ void BattleGroundAB::StartingEventOpenDoors()
DoorOpen(BG_AB_OBJECT_GATE_A);
DoorOpen(BG_AB_OBJECT_GATE_H);
}
void BattleGroundAB::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map, default values are set in the constructor
BattleGroundABScore* sc = new BattleGroundABScore;
m_PlayerScores[plr->GetGUID()] = sc;
}
void BattleGroundAB::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
{
}
void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
switch(Trigger)
{
case 3948: // Arathi Basin Alliance Exit.
@@ -255,7 +230,6 @@ void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger)
break;
}
}
/* type: 0-neutral, 1-contested, 3-occupied
teamIndex: 0-ally, 1-horde */
void BattleGroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay)
@@ -268,30 +242,24 @@ void BattleGroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool
m_BannerTimers[node].teamIndex = teamIndex;
return;
}
uint8 obj = node*8 + type + teamIndex;
SpawnBGObject(obj, RESPAWN_IMMEDIATELY);
// handle aura with banner
if (!type)
return;
obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7);
SpawnBGObject(obj, RESPAWN_IMMEDIATELY);
}
void BattleGroundAB::_DelBanner(uint8 node, uint8 type, uint8 teamIndex)
{
uint8 obj = node*8 + type + teamIndex;
SpawnBGObject(obj, RESPAWN_ONE_DAY);
// handle aura with banner
if (!type)
return;
obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7);
SpawnBGObject(obj, RESPAWN_ONE_DAY);
}
int32 BattleGroundAB::_GetNodeNameId(uint8 node)
{
switch (node)
@@ -306,20 +274,16 @@ int32 BattleGroundAB::_GetNodeNameId(uint8 node)
}
return 0;
}
void BattleGroundAB::FillInitialWorldStates(WorldPacket& data)
{
const uint8 plusArray[] = {0, 2, 3, 0, 1};
// Node icons
for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
data << uint32(BG_AB_OP_NODEICONS[node]) << uint32((m_Nodes[node]==0)?1:0);
// Node occupied states
for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
for (uint8 i = 1; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
data << uint32(BG_AB_OP_NODESTATES[node] + plusArray[i]) << uint32((m_Nodes[node]==i)?1:0);
// How many bases each team owns
uint8 ally = 0, horde = 0;
for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node)
@@ -327,32 +291,25 @@ void BattleGroundAB::FillInitialWorldStates(WorldPacket& data)
++ally;
else if (m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_OCCUPIED)
++horde;
data << uint32(BG_AB_OP_OCCUPIED_BASES_ALLY) << uint32(ally);
data << uint32(BG_AB_OP_OCCUPIED_BASES_HORDE) << uint32(horde);
// Team scores
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[BG_TEAM_ALLIANCE]);
data << uint32(BG_AB_OP_RESOURCES_HORDE) << uint32(m_TeamScores[BG_TEAM_HORDE]);
// other unknown
data << uint32(0x745) << uint32(0x2); // 37 1861 unk
}
void BattleGroundAB::_SendNodeUpdate(uint8 node)
{
// Send node owner state update to refresh map icons on client
const uint8 plusArray[] = {0, 2, 3, 0, 1};
if (m_prevNodes[node])
UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_prevNodes[node]], 0);
else
UpdateWorldState(BG_AB_OP_NODEICONS[node], 0);
UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_Nodes[node]], 1);
// How many bases each team owns
uint8 ally = 0, horde = 0;
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
@@ -360,17 +317,14 @@ void BattleGroundAB::_SendNodeUpdate(uint8 node)
++ally;
else if (m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED)
++horde;
UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_ALLY, ally);
UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_HORDE, horde);
}
void BattleGroundAB::_NodeOccupied(uint8 node,Team team)
{
if (!AddSpiritGuide(node, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], team))
sLog.outError("Failed to spawn spirit guide! point: %u, team: %u,", node, team);
// SpawnBGCreature(node,RESPAWN_IMMEDIATELY);
uint8 capturedNodes = 0;
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
{
@@ -382,12 +336,10 @@ void BattleGroundAB::_NodeOccupied(uint8 node,Team team)
if (capturedNodes >= 4)
CastSpellOnTeam(SPELL_AB_QUEST_REWARD_4_BASES, team);
}
void BattleGroundAB::_NodeDeOccupied(uint8 node)
{
if (node >= BG_AB_DYNAMIC_NODES_COUNT)
return;
// Those who are waiting to resurrect at this node are taken to the closest own node's graveyard
std::vector<uint64> ghost_list = m_ReviveQueue[m_BgCreatures[node]];
if (!ghost_list.empty())
@@ -398,27 +350,21 @@ void BattleGroundAB::_NodeDeOccupied(uint8 node)
Player* plr = objmgr.GetPlayer(*itr);
if (!plr)
continue;
if (!ClosestGrave) // cache
ClosestGrave = GetClosestGraveYard(plr);
if (ClosestGrave)
plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation());
}
}
if (m_BgCreatures[node])
DelCreature(node);
// buff object isn't despawned
}
/* Invoked if a player used a banner as a gameobject */
void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*target_obj*/)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
uint8 node = BG_AB_NODE_STABLES;
GameObject* obj=HashMapHolder<GameObject>::Find(m_BgObjects[node*8+7]);
while ( (node < BG_AB_DYNAMIC_NODES_COUNT) && ((!obj) || (!source->IsWithinDistInMap(obj,10))))
@@ -426,19 +372,15 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
++node;
obj=HashMapHolder<GameObject>::Find(m_BgObjects[node*8+BG_AB_OBJECT_AURA_CONTESTED]);
}
if (node == BG_AB_DYNAMIC_NODES_COUNT)
{
// this means our player isn't close to any of banners - maybe cheater ??
return;
}
BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(source->GetTeam());
// Check if player really could use this banner, not cheated
if (!(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2))
return;
source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
uint32 sound = 0;
// If node is neutral, change to contested
@@ -453,13 +395,11 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
_CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
_SendNodeUpdate(node);
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
// FIXME: team and node names not localized
if (teamIndex == 0)
SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node), LANG_BG_AB_ALLY);
else
SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node), LANG_BG_AB_HORDE);
sound = BG_AB_SOUND_NODE_CLAIMED;
}
// If node is contested
@@ -477,7 +417,6 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
_CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true);
_SendNodeUpdate(node);
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
// FIXME: node names not localized
if (teamIndex == BG_TEAM_ALLIANCE)
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
@@ -497,7 +436,6 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
_SendNodeUpdate(node);
m_NodeTimers[node] = 0;
_NodeOccupied(node,(teamIndex == BG_TEAM_ALLIANCE) ? ALLIANCE:HORDE);
// FIXME: node names not localized
if (teamIndex == BG_TEAM_ALLIANCE)
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
@@ -519,16 +457,13 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
_SendNodeUpdate(node);
_NodeDeOccupied(node);
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
// FIXME: node names not localized
if (teamIndex == BG_TEAM_ALLIANCE)
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
else
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
}
// If node is occupied again, send "X has taken the Y" msg.
if (m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED)
{
@@ -540,7 +475,6 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
}
PlaySoundToAll(sound);
}
bool BattleGroundAB::SetupBattleGround()
{
for (int i = 0 ; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
@@ -575,15 +509,12 @@ bool BattleGroundAB::SetupBattleGround()
)
sLog.outErrorDb("BatteGroundAB: Failed to spawn buff object!");
}
return true;
}
void BattleGroundAB::Reset()
{
//call parent's class reset
BattleGround::Reset();
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
m_TeamScores[BG_TEAM_HORDE] = 0;
m_lastTick[BG_TEAM_ALLIANCE] = 0;
@@ -598,7 +529,6 @@ void BattleGroundAB::Reset()
m_ReputationTics = (isBGWeekend) ? BG_AB_ABBGWeekendReputationTicks : BG_AB_NotABBGWeekendReputationTicks;
m_TeamScores500Disadvantage[BG_TEAM_ALLIANCE] = false;
m_TeamScores500Disadvantage[BG_TEAM_HORDE] = false;
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
{
m_Nodes[i] = 0;
@@ -606,12 +536,10 @@ void BattleGroundAB::Reset()
m_NodeTimers[i] = 0;
m_BannerTimers[i].timer = 0;
}
for (uint8 i = 0; i < BG_AB_ALL_NODES_COUNT; ++i)
if (m_BgCreatures[i])
DelCreature(i);
}
void BattleGroundAB::EndBattleGround(uint32 winner)
{
//win reward
@@ -622,27 +550,22 @@ void BattleGroundAB::EndBattleGround(uint32 winner)
//complete map_end rewards (even if no team wins)
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
BattleGround::EndBattleGround(winner);
}
WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player)
{
BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam());
// Is there any occupied node for this team?
std::vector<uint8> nodes;
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
if (m_Nodes[i] == teamIndex + 3)
nodes.push_back(i);
WorldSafeLocsEntry const* good_entry = NULL;
// If so, select the closest node to place ghost on
if (!nodes.empty())
{
float plr_x = player->GetPositionX();
float plr_y = player->GetPositionY();
float mindist = 999999.0f;
for (uint8 i = 0; i < nodes.size(); ++i)
{
@@ -661,16 +584,13 @@ WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player)
// If not, place ghost on starting location
if (!good_entry)
good_entry = sWorldSafeLocsStore.LookupEntry( BG_AB_GraveyardIds[teamIndex+5] );
return good_entry;
}
void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
{
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if( itr == m_PlayerScores.end() ) // player not found...
return;
switch(type)
{
case SCORE_BASES_ASSAULTED:
@@ -684,7 +604,6 @@ void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value
break;
}
}
bool BattleGroundAB::IsAllNodesConrolledByTeam(uint32 team) const
{
uint32 count = 0;
@@ -692,6 +611,5 @@ bool BattleGroundAB::IsAllNodesConrolledByTeam(uint32 team) const
if ((team == ALLIANCE && m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED) ||
(team == HORDE && m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED))
++count;
return count == BG_AB_DYNAMIC_NODES_COUNT;
}
-37
View File
@@ -19,9 +19,7 @@
*/
#ifndef __BATTLEGROUNDAB_H
#define __BATTLEGROUNDAB_H
class BattleGround;
enum BG_AB_WorldStates
{
BG_AB_OP_OCCUPIED_BASES_HORDE = 1778,
@@ -41,7 +39,6 @@ enum BG_AB_WorldStates
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)
@@ -59,11 +56,8 @@ enum BG_AB_WorldStates
BG_AB_OP_GOLDMINE_STATE_CON_HOR = 1790, //Gold Mine map state (CON HORDE)
*/
};
const uint32 BG_AB_OP_NODESTATES[5] = {1767, 1782, 1772, 1792, 1787};
const uint32 BG_AB_OP_NODEICONS[5] = {1842, 1846, 1845, 1844, 1843};
/* Note: code uses that these IDs follow each other */
enum BG_AB_NodeObjectId
{
@@ -73,7 +67,6 @@ enum BG_AB_NodeObjectId
BG_AB_OBJECTID_NODE_BANNER_3 = 180090, // Lumber mill banner
BG_AB_OBJECTID_NODE_BANNER_4 = 180091 // Gold mine banner
};
enum BG_AB_ObjectType
{
// for all 5 node points 8*5=40 objects
@@ -106,7 +99,6 @@ enum BG_AB_ObjectType
BG_AB_OBJECT_BERSERKBUFF_GOLD_MINE = 56,
BG_AB_OBJECT_MAX = 57,
};
/* Object id templates from DB */
enum BG_AB_ObjectTypes
{
@@ -114,26 +106,21 @@ enum BG_AB_ObjectTypes
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_Timers
{
BG_AB_FLAG_CAPTURING_TIME = 60000,
};
enum BG_AB_Score
{
BG_AB_WARNING_NEAR_VICTORY_SCORE = 1800,
BG_AB_MAX_TEAM_SCORE = 2000
};
/* do NOT change the order, else wrong behaviour */
enum BG_AB_BattleGroundNodes
{
@@ -142,15 +129,11 @@ enum BG_AB_BattleGroundNodes
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_TYPE_NEUTRAL = 0,
@@ -161,7 +144,6 @@ enum BG_AB_NodeStatus
BG_AB_NODE_STATUS_ALLY_OCCUPIED = 3,
BG_AB_NODE_STATUS_HORDE_OCCUPIED = 4
};
enum BG_AB_Sounds
{
BG_AB_SOUND_NODE_CLAIMED = 8192,
@@ -171,12 +153,10 @@ enum BG_AB_Sounds
BG_AB_SOUND_NODE_ASSAULTED_HORDE = 8174,
BG_AB_SOUND_NEAR_VICTORY = 8456
};
#define BG_AB_NotABBGWeekendHonorTicks 330
#define BG_AB_ABBGWeekendHonorTicks 200
#define BG_AB_NotABBGWeekendReputationTicks 200
#define BG_AB_ABBGWeekendReputationTicks 150
// x, y, z, o
const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] = {
{1166.785f, 1200.132f, -56.70859f, 0.9075713f}, // stables
@@ -185,20 +165,16 @@ const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] = {
{856.1419f, 1148.902f, 11.18469f, -2.303835f}, // lumber mill
{1146.923f, 848.1782f, -110.917f, -0.7330382f} // gold mine
};
// x, y, z, o, rot0, rot1, rot2, rot3
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}
};
// Tick intervals and given points: case 0,1,2,3,4,5 captured nodes
const uint32 BG_AB_TickIntervals[6] = {0, 12000, 9000, 6000, 3000, 1000};
const uint32 BG_AB_TickPoints[6] = {0, 10, 10, 10, 10, 30};
// WorldSafeLocs ids for 5 nodes, and for ally, and horde starting location
const uint32 BG_AB_GraveyardIds[BG_AB_ALL_NODES_COUNT] = {895, 894, 893, 897, 896, 898, 899};
// x, y, z, o
const float BG_AB_BuffPositions[BG_AB_DYNAMIC_NODES_COUNT][4] = {
{1185.71f, 1185.24f, -56.36f, 2.56f}, // stables
@@ -207,7 +183,6 @@ const float BG_AB_BuffPositions[BG_AB_DYNAMIC_NODES_COUNT][4] = {
{807.46f, 1189.16f, 11.92f, 5.44f}, // lumber mill
{1146.62f, 816.94f, -98.49f, 6.14f} // gold mine
};
// x, y, z, o
const float BG_AB_SpiritGuidePos[BG_AB_ALL_NODES_COUNT][4] = {
{1200.03f, 1171.09f, -56.47f, 5.15f}, // stables
@@ -218,14 +193,12 @@ const float BG_AB_SpiritGuidePos[BG_AB_ALL_NODES_COUNT][4] = {
{1354.05f, 1275.48f, -11.30f, 4.77f}, // alliance starting base
{714.61f, 646.15f, -10.87f, 4.34f} // horde starting base
};
struct BG_AB_BannerTimer
{
uint32 timer;
uint8 type;
uint8 teamIndex;
};
class BattleGroundABScore : public BattleGroundScore
{
public:
@@ -234,15 +207,12 @@ class BattleGroundABScore : public BattleGroundScore
uint32 BasesAssaulted;
uint32 BasesDefended;
};
class BattleGroundAB : public BattleGround
{
friend class BattleGroundMgr;
public:
BattleGroundAB();
~BattleGroundAB();
void Update(uint32 diff);
void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
@@ -253,15 +223,11 @@ class BattleGroundAB : public BattleGround
virtual void Reset();
void EndBattleGround(uint32 winner);
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
/* Scorekeeping */
virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
virtual void FillInitialWorldStates(WorldPacket& data);
/* Nodes occupying */
virtual void EventPlayerClickedOnFlag(Player *source, GameObject* target_obj);
/* achievement req. */
bool IsAllNodesConrolledByTeam(uint32 team) const; // overwrited
bool IsTeamScores500Disadvantage(uint32 team) const { return m_TeamScores500Disadvantage[GetTeamIndexByTeamId(team)]; }
@@ -270,14 +236,11 @@ class BattleGroundAB : public BattleGround
void _CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay);
void _DelBanner(uint8 node, uint8 type, uint8 teamIndex);
void _SendNodeUpdate(uint8 node);
/* Creature spawning/despawning */
// TODO: working, scripted peons spawning
void _NodeOccupied(uint8 node,Team team);
void _NodeDeOccupied(uint8 node);
int32 _GetNodeNameId(uint8 node);
/* Nodes info:
0: neutral
1: ally contested
-93
View File
@@ -17,10 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ObjectMgr.h"
#include "WorldPacket.h"
#include "BattleGround.h"
#include "BattleGroundAV.h"
#include "Formulas.h"
@@ -28,36 +26,29 @@
#include "Language.h"
#include "Player.h"
#include "SpellAuras.h"
BattleGroundAV::BattleGroundAV()
{
m_BgObjects.resize(BG_AV_OBJECT_MAX);
m_BgCreatures.resize(AV_CPLACE_MAX+AV_STATICCPLACE_MAX);
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_AV_START_TWO_MINUTES;
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_AV_START_ONE_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_AV_START_HALF_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_AV_HAS_BEGUN;
}
BattleGroundAV::~BattleGroundAV()
{
}
const uint16 BattleGroundAV::GetBonusHonor(uint8 kills) //TODO: move this function to Battleground.cpp (needs to find a way to get m_MaxLevel)
{
return Trinity::Honor::hk_honor_at_level(m_MaxLevel, kills);
}
void BattleGroundAV::HandleKillPlayer(Player *player, Player *killer)
{
if(GetStatus() != STATUS_IN_PROGRESS)
return;
BattleGround::HandleKillPlayer(player, killer);
UpdateScore(player->GetTeam(),-1);
}
void BattleGroundAV::HandleKillUnit(Creature *unit, Player *killer)
{
sLog.outDebug("bg_av HandleKillUnit %i",unit->GetEntry());
@@ -95,7 +86,6 @@ void BattleGroundAV::HandleKillUnit(Creature *unit, Player *killer)
Creature* creature = GetBGCreature(AV_CPLACE_HERALD);
if(creature)
YellToAll(creature,GetTrinityString(LANG_BG_AV_A_CAPTAIN_DEAD),LANG_UNIVERSAL);
}
else if ( entry == BG_AV_CreatureInfo[AV_NPC_H_CAPTAIN][0] )
{
@@ -120,7 +110,6 @@ void BattleGroundAV::HandleKillUnit(Creature *unit, Player *killer)
else if ( entry == BG_AV_CreatureInfo[AV_NPC_S_MINE_N_4][0] || entry == BG_AV_CreatureInfo[AV_NPC_S_MINE_A_4][0] || entry == BG_AV_CreatureInfo[AV_NPC_S_MINE_H_4][0])
ChangeMineOwner(AV_SOUTH_MINE,killer->GetTeam());
}
void BattleGroundAV::HandleQuestComplete(uint32 questid, Player *player)
{
if (GetStatus() != STATUS_IN_PROGRESS)
@@ -224,13 +213,11 @@ void BattleGroundAV::HandleQuestComplete(uint32 questid, Player *player)
}
}
void BattleGroundAV::UpdateScore(uint16 team, int16 points )
{ //note: to remove reinforcementpoints points must be negative, for adding reinforcements points must be positive
assert( team == ALLIANCE || team == HORDE);
uint8 teamindex = GetTeamIndexByTeamId(team); //0=ally 1=horde
m_Team_Scores[teamindex] += points;
UpdateWorldState(((teamindex==BG_TEAM_HORDE)?AV_Horde_Score:AV_Alliance_Score), m_Team_Scores[teamindex]);
if( points < 0)
{
@@ -247,7 +234,6 @@ void BattleGroundAV::UpdateScore(uint16 team, int16 points )
}
}
}
Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type )
{
uint32 level;
@@ -271,7 +257,6 @@ Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type )
return NULL;
if(creature->GetEntry() == BG_AV_CreatureInfo[AV_NPC_A_CAPTAIN][0] || creature->GetEntry() == BG_AV_CreatureInfo[AV_NPC_H_CAPTAIN][0])
creature->SetRespawnDelay(RESPAWN_ONE_DAY); // TODO: look if this can be done by database + also add this for the wingcommanders
if((isStatic && cinfoid>=10 && cinfoid<=14) || (!isStatic && ((cinfoid >= AV_NPC_A_GRAVEDEFENSE0 && cinfoid<=AV_NPC_A_GRAVEDEFENSE3) ||
(cinfoid>=AV_NPC_H_GRAVEDEFENSE0 && cinfoid<=AV_NPC_H_GRAVEDEFENSE3))))
{
@@ -289,17 +274,14 @@ Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type )
//TODO: find a way to add a motionmaster without killing the creature (i
//just copied this code from a gm-command
}
if(level != 0)
level += m_MaxLevel-60; //maybe we can do this more generic for custom level-range.. actually it's blizzlike
creature->SetLevel(level);
return creature;
}
void BattleGroundAV::Update(uint32 diff)
{
BattleGround::Update(diff);
if(GetStatus() == STATUS_IN_PROGRESS)
{
for(uint8 i=0; i<=1;i++)//0=alliance, 1=horde
@@ -335,7 +317,6 @@ void BattleGroundAV::Update(uint32 diff)
{
if( m_Mine_Timer <= 0)
UpdateScore(m_Mine_Owner[mine],1);
if(m_Mine_Reclaim_Timer[mine] > diff)
m_Mine_Reclaim_Timer[mine] -= diff;
else{ //we don't need to set this timer to 0 cause this codepart wont get called when this thing is 0
@@ -345,7 +326,6 @@ void BattleGroundAV::Update(uint32 diff)
}
if( m_Mine_Timer <= 0)
m_Mine_Timer=AV_MINE_TICK_TIMER; //this is at the end, cause we need to update both mines
//looks for all timers of the nodes and destroy the building (for graveyards the building wont get destroyed, it goes just to the other team
for(BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i)
if(m_Nodes[i].State == POINT_ASSAULTED) //maybe remove this
@@ -357,13 +337,11 @@ void BattleGroundAV::Update(uint32 diff)
}
}
}
void BattleGroundAV::StartingEventCloseDoors()
{
DoorClose(BG_AV_OBJECT_DOOR_A);
DoorClose(BG_AV_OBJECT_DOOR_H);
}
void BattleGroundAV::StartingEventOpenDoors()
{
sLog.outDebug("BG_AV: start spawning mine stuff");
@@ -373,14 +351,11 @@ void BattleGroundAV::StartingEventOpenDoors()
SpawnBGObject(i,RESPAWN_IMMEDIATELY);
for(uint8 mine = AV_NORTH_MINE; mine <= AV_SOUTH_MINE; mine++) //mine population
ChangeMineOwner(mine, AV_NEUTRAL_TEAM,true);
UpdateWorldState(AV_SHOW_H_SCORE, 1);
UpdateWorldState(AV_SHOW_A_SCORE, 1);
DoorOpen(BG_AV_OBJECT_DOOR_H);
DoorOpen(BG_AV_OBJECT_DOOR_A);
}
void BattleGroundAV::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
@@ -389,9 +364,7 @@ void BattleGroundAV::AddPlayer(Player *plr)
m_PlayerScores[plr->GetGUID()] = sc;
if(m_MaxLevel==0)
m_MaxLevel=(plr->getLevel()%10 == 0)? plr->getLevel() : (plr->getLevel()-(plr->getLevel()%10))+10; //TODO: just look at the code \^_^/ --but queue-info should provide this information..
}
void BattleGroundAV::EndBattleGround(uint32 winner)
{
//calculate bonuskills for both teams:
@@ -414,7 +387,6 @@ void BattleGroundAV::EndBattleGround(uint32 winner)
}
}
}
for(int i=0; i<=1; i++) //0=ally 1=horde
{
if(m_CaptainAlive[i])
@@ -427,11 +399,9 @@ void BattleGroundAV::EndBattleGround(uint32 winner)
if(kills[i] != 0)
RewardHonorToTeam(GetBonusHonor(kills[i]),(i == 0)?ALLIANCE:HORDE);
}
//TODO add enterevademode for all attacking creatures
BattleGround::EndBattleGround(winner);
}
void BattleGroundAV::RemovePlayer(Player* plr,uint64 /*guid*/)
{
if(!plr)
@@ -445,13 +415,11 @@ void BattleGroundAV::RemovePlayer(Player* plr,uint64 /*guid*/)
plr->RemoveAurasDueToSpell(AV_BUFF_H_CAPTAIN);
}
void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
// this is wrong way to implement these things. On official it done by gameobject spell cast.
if (GetStatus() != STATUS_IN_PROGRESS)
return;
uint32 SpellId = 0;
switch(Trigger)
{
@@ -481,18 +449,14 @@ void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger)
// Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
break;
}
if (SpellId)
Source->CastSpell(Source, SpellId, true);
}
void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value)
{
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found...
return;
switch(type)
{
case SCORE_GRAVEYARDS_ASSAULTED:
@@ -522,19 +486,14 @@ void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value
}
}
void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node)
{
uint32 object = GetObjectThroughNode(node);
sLog.outDebug("bg_av: player destroyed point node %i object %i",node,object);
//despawn banner
SpawnBGObject(object, RESPAWN_ONE_DAY);
DestroyNode(node);
UpdateNodeWorldState(node);
uint32 owner = m_Nodes[node].Owner;
if( IsTower(node) )
{
@@ -547,11 +506,9 @@ void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node)
//spawn destroyed aura
for(uint8 i=0; i<=9; i++)
SpawnBGObject(BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH + i + (tmp * 10),RESPAWN_IMMEDIATELY);
UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, (-1)*BG_AV_RES_TOWER);
RewardReputationToTeam((owner == ALLIANCE)?730:729,BG_AV_REP_TOWER,owner);
RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_TOWER),owner);
SpawnBGObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp),RESPAWN_ONE_DAY);
SpawnBGObject(BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp),RESPAWN_ONE_DAY);
}
@@ -579,12 +536,10 @@ void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node)
sprintf(buf, GetTrinityString(LANG_BG_AV_TOWER_TAKEN) , GetNodeName(node),( owner == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) : GetTrinityString(LANG_BG_AV_HORDE) );
else
sprintf(buf, GetTrinityString(LANG_BG_AV_GRAVE_TAKEN) , GetNodeName(node),( owner == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) :GetTrinityString(LANG_BG_AV_HORDE) );
Creature* creature = GetBGCreature(AV_CPLACE_HERALD);
if(creature)
YellToAll(creature,buf,LANG_UNIVERSAL);
}
void BattleGroundAV::ChangeMineOwner(uint8 mine, uint32 team, bool initial)
{ //mine=0 northmine mine=1 southmin
//changing the owner results in setting respawntim to infinite for current creatures, spawning new mine owners creatures and changing the chest-objects so that the current owning team can use them
@@ -593,12 +548,10 @@ void BattleGroundAV::ChangeMineOwner(uint8 mine, uint32 team, bool initial)
team = AV_NEUTRAL_TEAM;
else
PlaySoundToAll((team==ALLIANCE)?AV_SOUND_ALLIANCE_GOOD:AV_SOUND_HORDE_GOOD);
if(m_Mine_Owner[mine] == team && !initial)
return;
m_Mine_PrevOwner[mine] = m_Mine_Owner[mine];
m_Mine_Owner[mine] = team;
if(!initial)
{
sLog.outDebug("bg_av depopulating mine %i (0=north,1=south)",mine);
@@ -611,7 +564,6 @@ void BattleGroundAV::ChangeMineOwner(uint8 mine, uint32 team, bool initial)
DelCreature(i); //TODO here also
}
SendMineWorldStates(mine);
sLog.outDebug("bg_av populating mine %i (0=north,1=south)",mine);
uint16 miner;
//also neutral team exists.. after a big time, the neutral team tries to conquer the mine
@@ -674,7 +626,6 @@ void BattleGroundAV::ChangeMineOwner(uint8 mine, uint32 team, bool initial)
}
return;
}
bool BattleGroundAV::PlayerCanDoMineQuest(int32 GOId,uint32 team)
{
if(GOId == BG_AV_OBJECTID_MINE_N)
@@ -683,12 +634,10 @@ bool BattleGroundAV::PlayerCanDoMineQuest(int32 GOId,uint32 team)
return (m_Mine_Owner[AV_SOUTH_MINE]==team);
return true; //cause it's no mine'object it is ok if this is true
}
void BattleGroundAV::PopulateNode(BG_AV_Nodes node)
{
uint32 owner = m_Nodes[node].Owner;
assert(owner);
uint32 c_place = AV_CPLACE_DEFENSE_STORM_AID + ( 4 * node );
uint32 creatureid;
if(IsTower(node))
@@ -709,7 +658,6 @@ void BattleGroundAV::PopulateNode(BG_AV_Nodes node)
DelCreature(node);
if( !AddSpiritGuide(node, BG_AV_CreaturePos[node][0], BG_AV_CreaturePos[node][1], BG_AV_CreaturePos[node][2], BG_AV_CreaturePos[node][3], owner))
sLog.outError("AV: couldn't spawn spiritguide at node %i",node);
}
for(uint8 i=0; i<4; i++)
{
@@ -727,7 +675,6 @@ void BattleGroundAV::DePopulateNode(BG_AV_Nodes node)
DelCreature(node);
}
const BG_AV_Nodes BattleGroundAV::GetNodeThroughObject(uint32 object)
{
sLog.outDebug("bg_AV getnodethroughobject %i",object);
@@ -749,7 +696,6 @@ const BG_AV_Nodes BattleGroundAV::GetNodeThroughObject(uint32 object)
assert(false);
return BG_AV_Nodes(0);
}
const uint32 BattleGroundAV::GetObjectThroughNode(BG_AV_Nodes node)
{ //this function is the counterpart to GetNodeThroughObject()
sLog.outDebug("bg_AV GetObjectThroughNode %i",node);
@@ -786,9 +732,7 @@ const uint32 BattleGroundAV::GetObjectThroughNode(BG_AV_Nodes node)
return 0;
}
//called when using banner
void BattleGroundAV::EventPlayerClickedOnFlag(Player *source, GameObject* target_obj)
{
if(GetStatus() != STATUS_IN_PROGRESS)
@@ -816,15 +760,12 @@ void BattleGroundAV::EventPlayerClickedOnFlag(Player *source, GameObject* target
break;
}
}
void BattleGroundAV::EventPlayerDefendsPoint(Player* player, uint32 object)
{
assert(GetStatus() == STATUS_IN_PROGRESS);
BG_AV_Nodes node = GetNodeThroughObject(object);
uint32 owner = m_Nodes[node].Owner; //maybe should name it prevowner
uint32 team = player->GetTeam();
if(owner == player->GetTeam() || m_Nodes[node].State != POINT_ASSAULTED)
return;
if(m_Nodes[node].TotalOwner == AV_NEUTRAL_TEAM)
@@ -840,13 +781,11 @@ void BattleGroundAV::EventPlayerDefendsPoint(Player* player, uint32 object)
return;
}
//spawn new go :)
if(m_Nodes[node].Owner == ALLIANCE)
SpawnBGObject(object+22, RESPAWN_IMMEDIATELY); //spawn horde banner
else
SpawnBGObject(object-22, RESPAWN_IMMEDIATELY); //spawn alliance banner
if(!IsTower(node))
{
SpawnBGObject(BG_AV_OBJECT_AURA_N_FIRSTAID_STATION+3*node,RESPAWN_ONE_DAY);
@@ -854,11 +793,9 @@ void BattleGroundAV::EventPlayerDefendsPoint(Player* player, uint32 object)
}
// despawn old go
SpawnBGObject(object, RESPAWN_ONE_DAY);
DefendNode(node,team);
PopulateNode(node);
UpdateNodeWorldState(node);
if(IsTower(node))
{
//spawn big flag+aura on top of tower
@@ -888,11 +825,9 @@ void BattleGroundAV::EventPlayerDefendsPoint(Player* player, uint32 object)
else
PlaySoundToAll((team==ALLIANCE)?AV_SOUND_ALLIANCE_GOOD:AV_SOUND_HORDE_GOOD);
}
void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object)
{
assert(GetStatus() == STATUS_IN_PROGRESS);
BG_AV_Nodes node = GetNodeThroughObject(object);
uint32 owner = m_Nodes[node].Owner; //maybe name it prevowner
uint32 team = player->GetTeam();
@@ -900,7 +835,6 @@ void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object)
if(owner == team || team == m_Nodes[node].TotalOwner)
return; //surely a gm used this object
if(node == BG_AV_NODES_SNOWFALL_GRAVE) //snowfall is a bit special in capping + it gets eyecandy stuff
{
if(object == BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE) //initial capping
@@ -938,7 +872,6 @@ void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object)
SpawnBGObject(spawn+i,RESPAWN_IMMEDIATELY);
}
}
//if snowfall gots capped it can be handled like all other graveyards
if( m_Nodes[node].TotalOwner != AV_NEUTRAL_TEAM)
{
@@ -980,11 +913,9 @@ void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object)
}
DePopulateNode(node);
}
SpawnBGObject(object, RESPAWN_ONE_DAY); //delete old banner
AssaultNode(node,team);
UpdateNodeWorldState(node);
//send a nice message to all :)
char buf[256];
sprintf(buf, ( IsTower(node) ) ? GetTrinityString(LANG_BG_AV_TOWER_ASSAULTED) : GetTrinityString(LANG_BG_AV_GRAVE_ASSAULTED), GetNodeName(node), ( team == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) : GetTrinityString(LANG_BG_AV_HORDE ));
@@ -995,7 +926,6 @@ void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object)
UpdatePlayerScore(player, ( IsTower(node) ) ? SCORE_TOWERS_ASSAULTED : SCORE_GRAVEYARDS_ASSAULTED, 1);
PlaySoundToAll((team==ALLIANCE)?AV_SOUND_ALLIANCE_ASSAULTS:AV_SOUND_HORDE_ASSAULTS);
}
void BattleGroundAV::FillInitialWorldStates(WorldPacket& data)
{
bool stateok;
@@ -1009,7 +939,6 @@ void BattleGroundAV::FillInitialWorldStates(WorldPacket& data)
data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j,HORDE)]) << uint32((m_Nodes[i].Owner == HORDE && stateok)?1:0);
}
}
//towers
for (uint8 i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_MAX; i++)
for (uint8 j =1; j <= 3; j+=2)
@@ -1034,7 +963,6 @@ void BattleGroundAV::FillInitialWorldStates(WorldPacket& data)
SendMineWorldStates(AV_NORTH_MINE);
SendMineWorldStates(AV_SOUTH_MINE);
}
const uint8 BattleGroundAV::GetWorldStateType(uint8 state, uint16 team) //this is used for node worldstates and returns values which fit good into the worldstatesarray
{
//neutral stuff cant get handled (currently its only snowfall)
@@ -1057,7 +985,6 @@ const uint8 BattleGroundAV::GetWorldStateType(uint8 state, uint16 team) //this i
sLog.outError("BG_AV: should update a strange worldstate state:%i team:%i",state,team);
return 5; //this will crash the game, but i want to know if something is wrong here
}
void BattleGroundAV::UpdateNodeWorldState(BG_AV_Nodes node)
{
UpdateWorldState(BG_AV_NodeWorldStates[node][GetWorldStateType(m_Nodes[node].State,m_Nodes[node].Owner)],1);
@@ -1066,14 +993,12 @@ void BattleGroundAV::UpdateNodeWorldState(BG_AV_Nodes node)
else
UpdateWorldState(BG_AV_NodeWorldStates[node][GetWorldStateType(m_Nodes[node].PrevState,m_Nodes[node].PrevOwner)],0);
}
void BattleGroundAV::SendMineWorldStates(uint32 mine)
{
assert(mine == AV_NORTH_MINE || mine==AV_SOUTH_MINE);
// currently i'm sure, that this works (:
// assert(m_Mine_PrevOwner[mine] == ALLIANCE || m_Mine_PrevOwner[mine] == HORDE || m_Mine_PrevOwner[mine] == AV_NEUTRAL_TEAM);
// assert(m_Mine_Owner[mine] == ALLIANCE || m_Mine_Owner[mine] == HORDE || m_Mine_Owner[mine] == AV_NEUTRAL_TEAM);
uint8 owner,prevowner,mine2; //those variables are needed to access the right worldstate in the BG_AV_MineWorldStates array
mine2 = (mine==AV_NORTH_MINE)?0:1;
if(m_Mine_PrevOwner[mine] == ALLIANCE)
@@ -1088,13 +1013,11 @@ void BattleGroundAV::SendMineWorldStates(uint32 mine)
owner = 2;
else
owner = 1;
UpdateWorldState(BG_AV_MineWorldStates[mine2][owner],1);
if( prevowner != owner)
UpdateWorldState(BG_AV_MineWorldStates[mine2][prevowner],0);
}
WorldSafeLocsEntry const* BattleGroundAV::GetClosestGraveYard(Player* player)
{
WorldSafeLocsEntry const* good_entry = NULL;
@@ -1120,11 +1043,9 @@ WorldSafeLocsEntry const* BattleGroundAV::GetClosestGraveYard(Player* player)
// If not, place ghost on starting location
if( !good_entry )
good_entry = sWorldSafeLocsStore.LookupEntry( BG_AV_GraveyardIds[GetTeamIndexByTeamId(player->GetTeam())+7] );
return good_entry;
}
bool BattleGroundAV::SetupBattleGround()
{
// Create starting objects
@@ -1137,7 +1058,6 @@ bool BattleGroundAV::SetupBattleGround()
sLog.outErrorDb("BatteGroundAV: Failed to spawn some object BattleGround not created!1");
return false;
}
//spawn node-objects
for (uint8 i = BG_AV_NODES_FIRSTAID_STATION ; i < BG_AV_NODES_MAX; ++i)
{
@@ -1232,7 +1152,6 @@ bool BattleGroundAV::SetupBattleGround()
return false;
}
}
if(!AddObject(BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE, BG_AV_OBJECTID_BANNER_SNOWFALL_N ,BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][0],BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][1],BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][2],BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3],0,0,sin(BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3]/2), cos(BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3]/2), RESPAWN_ONE_DAY))
{
sLog.outError("BatteGroundAV: Failed to spawn some object BattleGround not created!8");
@@ -1249,7 +1168,6 @@ bool BattleGroundAV::SetupBattleGround()
return false;
}
}
uint16 i;
sLog.outDebug("Alterac Valley: entering state STATUS_WAIT_JOIN ...");
// Initial Nodes
@@ -1280,7 +1198,6 @@ bool BattleGroundAV::SetupBattleGround()
for(i = BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE; i <= BG_AV_OBJECT_DOOR_A; i++)
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
SpawnBGObject(BG_AV_OBJECT_AURA_N_SNOWFALL_GRAVE,RESPAWN_IMMEDIATELY);
//creatures
sLog.outDebug("BG_AV start poputlating nodes");
for(BG_AV_Nodes i= BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i )
@@ -1303,7 +1220,6 @@ bool BattleGroundAV::SetupBattleGround()
AddAVCreature(AV_NPC_HERALD,AV_CPLACE_HERALD);
return true;
}
const char* BattleGroundAV::GetNodeName(BG_AV_Nodes node)
{
switch (node)
@@ -1331,7 +1247,6 @@ const char* BattleGroundAV::GetNodeName(BG_AV_Nodes node)
}
}
}
void BattleGroundAV::AssaultNode(BG_AV_Nodes node, uint16 team)
{
if (m_Nodes[node].TotalOwner == team)
@@ -1361,18 +1276,15 @@ void BattleGroundAV::AssaultNode(BG_AV_Nodes node, uint16 team)
m_Nodes[node].PrevState = m_Nodes[node].State;
m_Nodes[node].State = POINT_ASSAULTED;
}
void BattleGroundAV::DestroyNode(BG_AV_Nodes node)
{
assert(m_Nodes[node].State == POINT_ASSAULTED);
m_Nodes[node].TotalOwner = m_Nodes[node].Owner;
m_Nodes[node].PrevOwner = m_Nodes[node].Owner;
m_Nodes[node].PrevState = m_Nodes[node].State;
m_Nodes[node].State = (m_Nodes[node].Tower)? POINT_DESTROYED : POINT_CONTROLED;
m_Nodes[node].Timer = 0;
}
void BattleGroundAV::InitNode(BG_AV_Nodes node, uint16 team, bool tower)
{
m_Nodes[node].TotalOwner = team;
@@ -1384,7 +1296,6 @@ void BattleGroundAV::InitNode(BG_AV_Nodes node, uint16 team, bool tower)
m_Nodes[node].Timer = 0;
m_Nodes[node].Tower = tower;
}
void BattleGroundAV::DefendNode(BG_AV_Nodes node, uint16 team)
{
assert(m_Nodes[node].TotalOwner == team);
@@ -1396,7 +1307,6 @@ void BattleGroundAV::DefendNode(BG_AV_Nodes node, uint16 team)
m_Nodes[node].State = POINT_CONTROLED;
m_Nodes[node].Timer = 0;
}
void BattleGroundAV::ResetBGSubclass()
{
m_MaxLevel=0;
@@ -1420,12 +1330,9 @@ void BattleGroundAV::ResetBGSubclass()
for(BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_TOWER; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i) //horde towers
InitNode(i,HORDE,true);
InitNode(BG_AV_NODES_SNOWFALL_GRAVE,AV_NEUTRAL_TEAM,false); //give snowfall neutral owner
m_Mine_Timer=AV_MINE_TICK_TIMER;
for(uint16 i = 0; i < AV_CPLACE_MAX+AV_STATICCPLACE_MAX; i++)
if(m_BgCreatures[i])
DelCreature(i);
}
-111
View File
@@ -17,44 +17,32 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __BATTLEGROUNDAV_H
#define __BATTLEGROUNDAV_H
class BattleGround;
#define LANG_BG_AV_A_CAPTAIN_BUFF "Begone. Uncouth scum! The Alliance shall prevail in Alterac Valley!"
#define LANG_BG_AV_H_CAPTAIN_BUFF "Now is the time to attack! For the Horde!"
#define LANG_BG_AV_S_MINE_BOSS_CLAIMS "Snivvle is here! Snivvle claims the Coldtooth Mine!"
#define BG_AV_CAPTIME 240000 //4:00
#define BG_AV_SNOWFALL_FIRSTCAP 300000 //5:00 but i also have seen 4:05
#define BG_AV_SCORE_INITIAL_POINTS 600
#define SEND_MSG_NEAR_LOSE 120
#define BG_AV_KILL_BOSS 4
#define BG_AV_REP_BOSS 350
#define BG_AV_KILL_CAPTAIN 3
#define BG_AV_REP_CAPTAIN 125
#define BG_AV_RES_CAPTAIN 100
#define BG_AV_KILL_TOWER 3
#define BG_AV_REP_TOWER 12
#define BG_AV_RES_TOWER 75
#define BG_AV_GET_COMMANDER 1 //for a safely returned wingcommander
//bonushonor at the end
#define BG_AV_KILL_SURVIVING_TOWER 2
#define BG_AV_REP_SURVIVING_TOWER 12
#define BG_AV_KILL_SURVIVING_CAPTAIN 2
#define BG_AV_REP_SURVIVING_CAPTAIN 125
enum BG_AV_Sounds
{ //TODO: get out if there comes a sound when neutral team captures mine
/*
8212:
alliance grave assault
@@ -62,7 +50,6 @@ enum BG_AV_Sounds
drek "mlanzenabschaum! In meiner Burg?! Toetet sie all" - nicht immer der sound
8333:
galv "sterbt fuer euch ist kein platz hier"
8332:
bal "Verschwinde, dreckiger Abschaum! Die Allianz wird im Alteractal "
8174:
@@ -85,21 +72,16 @@ horde:
mine capture
horde wins
*/
AV_SOUND_NEAR_VICTORY = 8456, //not confirmed yet
AV_SOUND_ALLIANCE_ASSAULTS = 8212, //tower,grave + enemy boss if someone tries to attack him
AV_SOUND_HORDE_ASSAULTS = 8174,
AV_SOUND_ALLIANCE_GOOD = 8173, //if something good happens for the team: wins(maybe only through killing the boss), captures mine or grave, destroys tower and defends grave
AV_SOUND_HORDE_GOOD = 8213,
AV_SOUND_BOTH_TOWER_DEFEND = 8192,
AV_SOUND_ALLIANCE_CAPTAIN = 8232, //gets called when someone attacks them and at the beginning after 3min+rand(x)*10sec (maybe buff)
AV_SOUND_HORDE_CAPTAIN = 8333,
};
enum BG_AV_OTHER_VALUES
{
AV_STATICCPLACE_MAX = 123,
@@ -118,25 +100,21 @@ enum BG_AV_ObjectIds
BG_AV_OBJECTID_BANNER_H = 178943, // can only be used by alliance
BG_AV_OBJECTID_BANNER_CONT_A = 178940, // can only be used by horde
BG_AV_OBJECTID_BANNER_CONT_H = 179435, // can only be used by alliance
BG_AV_OBJECTID_BANNER_A_B = 178365,
BG_AV_OBJECTID_BANNER_H_B = 178364,
BG_AV_OBJECTID_BANNER_CONT_A_B = 179286,
BG_AV_OBJECTID_BANNER_CONT_H_B = 179287,
BG_AV_OBJECTID_BANNER_SNOWFALL_N = 180418,
//snowfall eyecandy banner:
BG_AV_OBJECTID_SNOWFALL_CANDY_A = 179044,
BG_AV_OBJECTID_SNOWFALL_CANDY_PA = 179424,
BG_AV_OBJECTID_SNOWFALL_CANDY_H = 179064,
BG_AV_OBJECTID_SNOWFALL_CANDY_PH = 179425,
//banners on top of towers:
BG_AV_OBJECTID_TOWER_BANNER_A = 178927, //[PH] Alliance A1 Tower Banner BIG
BG_AV_OBJECTID_TOWER_BANNER_H = 178955, //[PH] Horde H1 Tower Banner BIG
BG_AV_OBJECTID_TOWER_BANNER_PA = 179446, //[PH] Alliance H1 Tower Pre-Banner BIG
BG_AV_OBJECTID_TOWER_BANNER_PH = 179436, //[PH] Horde A1 Tower Pre-Banner BIG
//Auras
BG_AV_OBJECTID_AURA_A = 180421,
BG_AV_OBJECTID_AURA_H = 180422,
@@ -144,18 +122,14 @@ enum BG_AV_ObjectIds
BG_AV_OBJECTID_AURA_A_S = 180100,
BG_AV_OBJECTID_AURA_H_S = 180101,
BG_AV_OBJECTID_AURA_N_S = 180102,
BG_AV_OBJECTID_GATE_A = 180424,
BG_AV_OBJECTID_GATE_H = 180424,
//mine supplies
BG_AV_OBJECTID_MINE_N = 178785,
BG_AV_OBJECTID_MINE_S = 178784,
BG_AV_OBJECTID_FIRE = 179065,
BG_AV_OBJECTID_SMOKE = 179066
};
enum BG_AV_Nodes
{
BG_AV_NODES_FIRSTAID_STATION = 0,
@@ -173,10 +147,8 @@ enum BG_AV_Nodes
BG_AV_NODES_TOWER_POINT = 12,
BG_AV_NODES_FROSTWOLF_ETOWER = 13,
BG_AV_NODES_FROSTWOLF_WTOWER = 14,
BG_AV_NODES_MAX = 15
};
enum BG_AV_ObjectTypes
{
BG_AV_OBJECT_FLAG_A_FIRSTAID_STATION = 0,
@@ -190,7 +162,6 @@ enum BG_AV_ObjectTypes
BG_AV_OBJECT_FLAG_A_DUNBALDAR_NORTH = 8,
BG_AV_OBJECT_FLAG_A_ICEWING_BUNKER = 9,
BG_AV_OBJECT_FLAG_A_STONEHEART_BUNKER = 10,
BG_AV_OBJECT_FLAG_C_A_FIRSTAID_STATION = 11,
BG_AV_OBJECT_FLAG_C_A_STORMPIKE_GRAVE = 12,
BG_AV_OBJECT_FLAG_C_A_STONEHEART_GRAVE = 13,
@@ -202,7 +173,6 @@ enum BG_AV_ObjectTypes
BG_AV_OBJECT_FLAG_C_A_TOWER_POINT = 19,
BG_AV_OBJECT_FLAG_C_A_FROSTWOLF_ETOWER = 20,
BG_AV_OBJECT_FLAG_C_A_FROSTWOLF_WTOWER = 21,
BG_AV_OBJECT_FLAG_C_H_FIRSTAID_STATION = 22,
BG_AV_OBJECT_FLAG_C_H_STORMPIKE_GRAVE = 23,
BG_AV_OBJECT_FLAG_C_H_STONEHEART_GRAVE = 24,
@@ -214,7 +184,6 @@ enum BG_AV_ObjectTypes
BG_AV_OBJECT_FLAG_C_H_DUNBALDAR_NORTH = 30,
BG_AV_OBJECT_FLAG_C_H_ICEWING_BUNKER = 31,
BG_AV_OBJECT_FLAG_C_H_STONEHEART_BUNKER = 32,
BG_AV_OBJECT_FLAG_H_FIRSTAID_STATION = 33,
BG_AV_OBJECT_FLAG_H_STORMPIKE_GRAVE = 34,
BG_AV_OBJECT_FLAG_H_STONEHEART_GRAVE = 35,
@@ -226,9 +195,7 @@ enum BG_AV_ObjectTypes
BG_AV_OBJECT_FLAG_H_TOWER_POINT = 41,
BG_AV_OBJECT_FLAG_H_FROSTWOLF_ETOWER = 42,
BG_AV_OBJECT_FLAG_H_FROSTWOLF_WTOWER = 43,
BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE = 44,
BG_AV_OBJECT_DOOR_H = 45,
BG_AV_OBJECT_DOOR_A = 46,
//auras for graveyards (3auras per graveyard neutral,alliance,horde)
@@ -253,7 +220,6 @@ enum BG_AV_ObjectTypes
BG_AV_OBJECT_AURA_N_FROSTWOLF_HUT = 65,
BG_AV_OBJECT_AURA_A_FROSTWOLF_HUT = 66,
BG_AV_OBJECT_AURA_H_FROSTWOLF_HUT = 67,
//big flags on top of towers 2 flags on each (contested,(alliance | horde)) + 2 auras
BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH = 67,
BG_AV_OBJECT_TFLAG_H_DUNBALDAR_SOUTH = 68,
@@ -287,7 +253,6 @@ enum BG_AV_ObjectTypes
BG_AV_OBJECT_TAURA_H_FROSTWOLF_ETOWER = 96,
BG_AV_OBJECT_TAURA_A_FROSTWOLF_WTOWER = 97,
BG_AV_OBJECT_TAURA_H_FROSTWOLF_WTOWER = 98,
BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH = 99,
BG_AV_OBJECT_BURN_DUNBALDAR_NORTH = 109,
BG_AV_OBJECT_BURN_ICEWING_BUNKER = 119,
@@ -306,12 +271,9 @@ enum BG_AV_ObjectTypes
BG_AV_OBJECT_MINE_SUPPLY_N_MAX = 224,
BG_AV_OBJECT_MINE_SUPPLY_S_MIN = 225,
BG_AV_OBJECT_MINE_SUPPLY_S_MAX = 236,
BG_AV_OBJECT_MAX = 237
};
enum BG_AV_OBJECTS
{
AV_OPLACE_FIRSTAID_STATION = 0,
@@ -337,7 +299,6 @@ enum BG_AV_OBJECTS
AV_OPLACE_BIGBANNER_TOWER_POINT = 20,
AV_OPLACE_BIGBANNER_FROSTWOLF_ETOWER = 21,
AV_OPLACE_BIGBANNER_FROSTWOLF_WTOWER = 22,
AV_OPLACE_BURN_DUNBALDAR_SOUTH = 23,
AV_OPLACE_BURN_DUNBALDAR_NORTH = 33,
AV_OPLACE_BURN_ICEWING_BUNKER = 43,
@@ -356,7 +317,6 @@ enum BG_AV_OBJECTS
AV_OPLACE_MINE_SUPPLY_N_MAX = 136,
AV_OPLACE_MINE_SUPPLY_S_MIN = 137,
AV_OPLACE_MINE_SUPPLY_S_MAX = 148,
AV_OPLACE_MAX = 149
};
const float BG_AV_ObjectPos[AV_OPLACE_MAX][4] = {
@@ -473,7 +433,6 @@ const float BG_AV_ObjectPos[AV_OPLACE_MAX][4] = {
{-1295.55f,-263.865f,105.033f,0.925024f},
{-1294.71f,-281.466f,107.664f,-1.50098f},
{-1289.69f,-259.521f,107.612f,-2.19912f},
//the two buildings of the captains
//alliance
{-64.4987f,-289.33f,33.4616f,-2.82743f},
@@ -497,7 +456,6 @@ const float BG_AV_ObjectPos[AV_OPLACE_MAX][4] = {
{-568.04f,-188.707f,81.55f,0},
{-501.775f,-151.581f,81.2027f,0},
{-509.975f,-191.652f,83.2978f,0},
//snowfall eyecandy
{-191.153f,-129.868f,78.5595f,-1.25664f },
{-201.282f,-134.319f,78.6753f,-0.942478f },
@@ -529,13 +487,11 @@ const float BG_AV_ObjectPos[AV_OPLACE_MAX][4] = {
{-947.642f,-208.807f,77.0101f,1.36136f},
{-951.394f,-193.695f,67.634f,0.802851f}
};
const float BG_AV_DoorPositons[2][4] = {
{780.487f, -493.024f, 99.9553f, 3.0976f}, //alliance
{-1375.193f, -538.981f, 55.2824f, 0.72178f} //horde
};
//creaturestuff starts here
//is related to BG_AV_CreaturePos
enum BG_AV_CreaturePlace
@@ -557,7 +513,6 @@ enum BG_AV_CreaturePlace
AV_CPLACE_DEFENSE_FROSTWOLF = 25,
AV_CPLACE_DEFENSE_ICE_GRAVE = 29,
AV_CPLACE_DEFENSE_FROST_HUT = 33,
AV_CPLACE_DEFENSE_DUN_S = 37,
AV_CPLACE_DEFENSE_DUN_N = 41,
AV_CPLACE_DEFENSE_ICEWING = 45,
@@ -566,7 +521,6 @@ enum BG_AV_CreaturePlace
AV_CPLACE_DEFENSE_TOWERPOINT = 57,
AV_CPLACE_DEFENSE_FROST_E = 61,
AV_CPLACE_DEFENSE_FROST_t = 65,
AV_CPLACE_A_MARSHAL_SOUTH = 69,
AV_CPLACE_A_MARSHAL_NORTH = 70,
AV_CPLACE_A_MARSHAL_ICE = 71,
@@ -596,13 +550,10 @@ enum BG_AV_CreaturePlace
AV_CPLACE_MINE_S_S_MAX = 299,
//boss
AV_CPLACE_MINE_S_3 = 300,
//herald
AV_CPLACE_HERALD = 301,
AV_CPLACE_MAX = 302
};
//x, y, z, o
const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = {
//spiritguides
@@ -692,7 +643,6 @@ const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = {
{-1302.41f,-259.256f,114.065f,1.67602f},
{-1287.97f,-262.087f,114.165f,6.18264f},
{-1291.59f,-271.166f,114.151f,5.28257f},
//alliance marshall
{721.104f,-7.64155f,50.7046f,3.45575f},// south
{723.058f,-14.1548f,50.7046f,3.40339f},// north
@@ -703,7 +653,6 @@ const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = {
{-1370.96f,-223.532f,98.4266f,4.93012f},
{-1378.37f,-228.614f,99.3546f,5.38565f},
{-1358.02f,-228.998f,98.868f,3.87768f},
//irondeep mine
//Irondeep Trogg
{971.671f,-442.657f,57.6951f,3.1765f},
@@ -939,13 +888,10 @@ const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = {
{-848.902f,-92.931f,68.6325f,3.33350},
//herald
{-48.459f,-288.802f,55.47f,1.0}
};
enum BG_AV_CreatureIds
{
AV_NPC_A_GRAVEDEFENSE0 = 0, // stormpike Defender
AV_NPC_A_GRAVEDEFENSE1 = 1, // seasoned defender
AV_NPC_A_GRAVEDEFENSE2 = 2, // veteran defender
@@ -953,7 +899,6 @@ enum BG_AV_CreatureIds
AV_NPC_A_TOWERDEFENSE = 4, // stormpike bowman
AV_NPC_A_CAPTAIN = 5, // balinda
AV_NPC_A_BOSS = 6, // vanndar
AV_NPC_H_GRAVEDEFENSE0 = 7, // frostwolf guardian
AV_NPC_H_GRAVEDEFENSE1 = 8, // seasoned guardian
AV_NPC_H_GRAVEDEFENSE2 = 9, // veteran guardian
@@ -961,7 +906,6 @@ enum BG_AV_CreatureIds
AV_NPC_H_TOWERDEFENSE = 11, // frostwolf bowman
AV_NPC_H_CAPTAIN = 12, // galvangar
AV_NPC_H_BOSS = 13, // drek thar
AV_NPC_A_MARSHAL_SOUTH = 14,
AV_NPC_MARSHAL_NORTH = 15,
AV_NPC_A_MARSHAL_ICE = 16,
@@ -997,9 +941,7 @@ enum BG_AV_CreatureIds
AV_NPC_S_MINE_H_4 = 46,
AV_NPC_HERALD = 47,
AV_NPC_INFO_MAX = 48
};
//entry, team, minlevel, maxlevel
//TODO this array should be removed, the only needed things are the entrys (for spawning(?) and handlekillunit)
const uint32 BG_AV_CreatureInfo[AV_NPC_INFO_MAX][4] = {
@@ -1021,46 +963,37 @@ const uint32 BG_AV_CreatureInfo[AV_NPC_INFO_MAX][4] = {
{ 14762, 1534, 60, 60 }, //Dun Baldar North Marshal
{ 14764, 1534, 60, 60 }, //Icewing Marshal
{ 14765, 1534, 60, 60 }, //Stonehearth Marshal
{ 14773, 1214, 60, 60 }, //Iceblood Warmaster
{ 14776, 1214, 60, 60 }, //Tower Point Warmaster
{ 14772, 1214, 60, 60 }, //East Frostwolf Warmaster
{ 14777, 1214, 60, 60 }, //West Frostwolf Warmaster
{ 10987, 59, 52, 53 }, //Irondeep Trogg
{ 11600, 59, 53, 54 }, //Irondeep Shaman
{ 11602, 59, 54, 55 }, //Irondeep Skullthumper
{ 11657, 59, 58, 58 }, //Morloch
{13396,469,52,53}, //irondeep alliance TODO: get the right ids
{13080,469,53,54},
{13098,469,54,55},
{13078,469,58,58},
{13397,67,52,53}, //irondeep horde
{13099,67,53,54},
{13081,67,54,55},
{13079,67,58,58},
{ 11603, 59, 52, 53 }, //south mine neutral
{ 11604, 59, 53, 54 },
{ 11605, 59, 54, 55 },
{ 11677, 59, 58, 58 },
{ 10982, 59, 52, 53 }, //vermin
{13317,469,52,53}, //alliance
{13096,469,54,55}, //explorer
{13087,469,54,55}, //invader
{13086,469,58,58},
{13316,67,52,53}, //horde
{13097,67,54,55}, //surveypr
{13089,67,54,55}, //guard
{13088,67,58,58},
{14848,67,58,58} //Herald
};
//x,y,z,o,static_creature_info-id
const float BG_AV_StaticCreaturePos[AV_STATICCPLACE_MAX][5] = { //static creatures
{-1235.31f,-340.777f,60.5088f,3.31613f,0 },//2225 - Zora Guthrek
@@ -1186,9 +1119,7 @@ const float BG_AV_StaticCreaturePos[AV_STATICCPLACE_MAX][5] = { //static creatur
{773.651f,-497.482f,99.0408f,2.11185f,46 },//14284 - Stormpike Battleguard
{949.1f,-506.913f,95.4237f,3.31613f,46 },//14284 - Stormpike Battleguard
{-1370.9f,-219.793f,98.4258f,5.04381f,47}, //drek thar
};
const uint32 BG_AV_StaticCreatureInfo[51][4] = {
{ 2225, 1215, 55, 55 }, //Zora Guthrek
{ 3343, 1215, 55, 55 }, //Grelkor
@@ -1242,7 +1173,6 @@ const uint32 BG_AV_StaticCreatureInfo[51][4] = {
{ 11947, 1214, 61, 61 }, //Captain Galvangar
{ 11949, 1216, 61, 61 } //Captain Balinda Stonehearth
};
enum BG_AV_Graveyards
{
AV_GRAVE_STORM_AID = 751,
@@ -1256,8 +1186,6 @@ enum BG_AV_Graveyards
AV_GRAVE_MAIN_HORDE = 610
};
const uint32 BG_AV_GraveyardIds[9]= {
AV_GRAVE_STORM_AID,
AV_GRAVE_STORM_GRAVE,
@@ -1269,7 +1197,6 @@ const uint32 BG_AV_GraveyardIds[9]= {
AV_GRAVE_MAIN_ALLIANCE,
AV_GRAVE_MAIN_HORDE
};
enum BG_AV_BUFF
{ //TODO add all other buffs here
AV_BUFF_ARMOR = 21163,
@@ -1283,19 +1210,15 @@ enum BG_AV_States
POINT_DESTROYED = 2,
POINT_CONTROLED = 3
};
enum BG_AV_WorldStates
{
AV_Alliance_Score = 3127,
AV_Horde_Score = 3128,
AV_SHOW_H_SCORE = 3133,
AV_SHOW_A_SCORE = 3134,
/*
//the comments behind the state shows which icon overlaps the other.. but is, until now, unused and maybe not a good solution (but give few performance (: )
// Graves
// Alliance
//Stormpike first aid station
AV_AID_A_C = 1325,
@@ -1338,7 +1261,6 @@ enum BG_AV_WorldStates
AV_FROSTWOLFHUT_H_C = 1330,
AV_FROSTWOLFHUT_H_A = 1332, //over ac
//Towers
//Alliance
//Dunbaldar South Bunker
@@ -1374,38 +1296,30 @@ enum BG_AV_WorldStates
AV_FROSTWOLFE_CONTROLLED = 1383,
AV_FROSTWOLFE_DESTROYED = 1366,
AV_FROSTWOLFE_ASSAULTED = 1388,
//mines
AV_N_MINE_N = 1360,
AV_N_MINE_A = 1358,
AV_N_MINE_H = 1359,
AV_S_MINE_N = 1357,
AV_S_MINE_A = 1355,
AV_S_MINE_H = 1356,
//towers assaulted by own team (unused)
AV_STONEH_UNUSED = 1377,
AV_ICEWING_UNUSED = 1376,
AV_DUNS_UNUSED = 1375,
AV_DUNN_UNUSED = 1374,
AV_ICEBLOOD_UNUSED = 1395,
AV_TOWERPOINT_UNUSED = 1394,
AV_FROSTWOLFE_UNUSED = 1393,
AV_FROSTWOLFW_UNUSED = 1392
*/
};
//alliance_control neutral_control horde_control
const uint32 BG_AV_MineWorldStates[2][3] = {
{1358, 1360,1359},
{1355, 1357,1356}
};
//alliance_control alliance_assault h_control h_assault
const uint32 BG_AV_NodeWorldStates[16][4] = {
//Stormpike first aid station
@@ -1439,7 +1353,6 @@ const uint32 BG_AV_NodeWorldStates[16][4] = {
//Frostwolf West
{1365,1387,1382,1392},
};
enum BG_AV_QuestIds
{
AV_QUEST_A_SCRAPS1 = 7223,
@@ -1465,7 +1378,6 @@ enum BG_AV_QuestIds
AV_QUEST_A_RIDER_TAME = 7027,
AV_QUEST_H_RIDER_TAME = 7001
};
struct BG_AV_NodeInfo
{
uint16 TotalOwner;
@@ -1476,9 +1388,7 @@ struct BG_AV_NodeInfo
int Timer;
bool Tower;
};
inline BG_AV_Nodes &operator++(BG_AV_Nodes &i){ return i = BG_AV_Nodes(i + 1); }
class BattleGroundAVScore : public BattleGroundScore
{
public:
@@ -1492,30 +1402,24 @@ class BattleGroundAVScore : public BattleGroundScore
uint32 LeadersKilled;
uint32 SecondaryObjectives;
};
class BattleGroundAV : public BattleGround
{
friend class BattleGroundMgr;
public:
BattleGroundAV();
~BattleGroundAV();
void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr,uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
virtual void ResetBGSubclass();
/*general stuff*/
void UpdateScore(uint16 team, int16 points);
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
/*handlestuff*/ //these are functions which get called from extern
virtual void EventPlayerClickedOnFlag(Player *source, GameObject* target_obj);
void HandleKillPlayer(Player* player, Player *killer);
@@ -1523,62 +1427,47 @@ class BattleGroundAV : public BattleGround
void HandleQuestComplete(uint32 questid, Player *player);
bool PlayerCanDoMineQuest(int32 GOId,uint32 team);
void EndBattleGround(uint32 winner);
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
private:
/* Nodes occupying */
void EventPlayerAssaultsPoint(Player* player, uint32 object);
void EventPlayerDefendsPoint(Player* player, uint32 object);
void EventPlayerDestroyedPoint(BG_AV_Nodes node);
void AssaultNode(BG_AV_Nodes node,uint16 team);
void DestroyNode(BG_AV_Nodes node);
void InitNode(BG_AV_Nodes node, uint16 team, bool tower);
void DefendNode(BG_AV_Nodes node, uint16 team);
void PopulateNode(BG_AV_Nodes node);
void DePopulateNode(BG_AV_Nodes node);
const BG_AV_Nodes GetNodeThroughObject(uint32 object);
const uint32 GetObjectThroughNode(BG_AV_Nodes node);
const char* GetNodeName(BG_AV_Nodes node);
const bool IsTower(BG_AV_Nodes node) { return m_Nodes[node].Tower; }
/*mine*/
void ChangeMineOwner(uint8 mine, uint32 team, bool initial=false);
/*worldstates*/
void FillInitialWorldStates(WorldPacket& data);
const uint8 GetWorldStateType(uint8 state, uint16 team);
void SendMineWorldStates(uint32 mine);
void UpdateNodeWorldState(BG_AV_Nodes node);
/*general */
Creature* AddAVCreature(uint16 cinfoid, uint16 type);
const uint16 GetBonusHonor(uint8 kills); //TODO remove this when mangos handles this right
/*variables */
int32 m_Team_Scores[2];
uint32 m_Team_QuestStatus[2][9]; //[x][y] x=team y=questcounter
BG_AV_NodeInfo m_Nodes[BG_AV_NODES_MAX];
uint32 m_Mine_Owner[2];
uint32 m_Mine_PrevOwner[2]; //only for worldstates needed
int32 m_Mine_Timer; //ticks for both teams
uint32 m_Mine_Reclaim_Timer[2];
uint32 m_CaptainBuffTimer[2];
bool m_CaptainAlive[2];
uint8 m_MaxLevel; //TODO remove this when battleground-getmaxlevel() returns something usefull
bool m_IsInformedNearVictory[2];
};
#endif
-36
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "BattleGround.h"
#include "BattleGroundBE.h"
#include "Language.h"
@@ -25,11 +24,9 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "WorldPacket.h"
BattleGroundBE::BattleGroundBE()
{
m_BgObjects.resize(BG_BE_OBJECT_MAX);
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
@@ -40,94 +37,72 @@ BattleGroundBE::BattleGroundBE()
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
}
BattleGroundBE::~BattleGroundBE()
{
}
void BattleGroundBE::Update(uint32 diff)
{
BattleGround::Update(diff);
/*if (GetStatus() == STATUS_IN_PROGRESS)
{
// update something
}*/
}
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 *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map, default values are set in constructor
BattleGroundBEScore* sc = new BattleGroundBEScore;
m_PlayerScores[plr->GetGUID()] = sc;
UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
}
void BattleGroundBE::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
{
if (GetStatus() == STATUS_WAIT_LEAVE)
return;
UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
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);
UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
CheckArenaWinConditions();
}
bool BattleGroundBE::HandlePlayerUnderMap(Player *player)
{
player->TeleportTo(GetMapId(),6238.930176,262.963470,0.889519,player->GetOrientation(),false);
return true;
}
void BattleGroundBE::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
// this is wrong way to implement these things. On official it done by gameobject spell cast.
if (GetStatus() != STATUS_IN_PROGRESS)
return;
//uint32 SpellId = 0;
//uint64 buff_guid = 0;
switch(Trigger)
@@ -143,24 +118,20 @@ void BattleGroundBE::HandleAreaTrigger(Player *Source, uint32 Trigger)
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
break;
}
//if (buff_guid)
// HandleTriggerBuff(buff_guid,Source);
}
void BattleGroundBE::FillInitialWorldStates(WorldPacket &data)
{
data << uint32(0x9f1) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7
data << uint32(0x9f0) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8
data << uint32(0x9f3) << uint32(1); // 9
}
void BattleGroundBE::Reset()
{
//call parent's class reset
BattleGround::Reset();
}
bool BattleGroundBE::SetupBattleGround()
{
// gates
@@ -175,22 +146,16 @@ bool BattleGroundBE::SetupBattleGround()
sLog.outErrorDb("BatteGroundBE: Failed to spawn some object!");
return false;
}
return true;
}
void BattleGroundBE::UpdatePlayerScore(Player* Source, uint32 type, uint32 value)
{
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found...
return;
//there is nothing special in this score
BattleGround::UpdatePlayerScore(Source,type,value);
}
/*
21:45:46 id:231310 [S2C] SMSG_INIT_WORLD_STATES (706 = 0x02C2) len: 86
0000: 32 02 00 00 76 0e 00 00 00 00 00 00 09 00 f3 09 | 2...v...........
@@ -199,7 +164,6 @@ void BattleGroundBE::UpdatePlayerScore(Player* Source, uint32 type, uint32 value
0030: 00 00 00 00 00 00 d7 08 00 00 00 00 00 00 d6 08 | ................
0040: 00 00 00 00 00 00 d5 08 00 00 00 00 00 00 d3 08 | ................
0050: 00 00 00 00 00 00 | ......
spell 32724 - Gold Team
spell 32725 - Green Team
35774 Gold Team
-9
View File
@@ -19,9 +19,7 @@
*/
#ifndef __BATTLEGROUNDBE_H
#define __BATTLEGROUNDBE_H
class BattleGround;
enum BattleGroundBEObjectTypes
{
BG_BE_OBJECT_DOOR_1 = 0,
@@ -32,7 +30,6 @@ enum BattleGroundBEObjectTypes
BG_BE_OBJECT_BUFF_2 = 5,
BG_BE_OBJECT_MAX = 6
};
enum BattleGroundBEObjects
{
BG_BE_OBJECT_TYPE_DOOR_1 = 183971,
@@ -42,28 +39,23 @@ enum BattleGroundBEObjects
BG_BE_OBJECT_TYPE_BUFF_1 = 184663,
BG_BE_OBJECT_TYPE_BUFF_2 = 184664
};
class BattleGroundBEScore : public BattleGroundScore
{
public:
BattleGroundBEScore() {};
virtual ~BattleGroundBEScore() {};
};
class BattleGroundBE : public BattleGround
{
friend class BattleGroundMgr;
public:
BattleGroundBE();
~BattleGroundBE();
void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
@@ -71,7 +63,6 @@ class BattleGroundBE : public BattleGround
virtual void FillInitialWorldStates(WorldPacket &d);
void HandleKillPlayer(Player* player, Player *killer);
bool HandlePlayerUnderMap(Player * plr);
/* Scorekeeping */
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
};
-14
View File
@@ -15,15 +15,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "BattleGround.h"
#include "BattleGroundDS.h"
#include "Language.h"
#include "Player.h"
BattleGroundDS::BattleGroundDS()
{
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
@@ -34,47 +31,36 @@ BattleGroundDS::BattleGroundDS()
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
}
BattleGroundDS::~BattleGroundDS()
{
}
void BattleGroundDS::Update(uint32 diff)
{
BattleGround::Update(diff);
}
void BattleGroundDS::StartingEventCloseDoors()
{
}
void BattleGroundDS::StartingEventOpenDoors()
{
}
void BattleGroundDS::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map, default values are set in constructor
BattleGroundDSScore* sc = new BattleGroundDSScore;
m_PlayerScores[plr->GetGUID()] = sc;
}
void BattleGroundDS::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
{
}
void BattleGroundDS::HandleKillPlayer(Player* player, Player* killer)
{
BattleGround::HandleKillPlayer(player, killer);
}
void BattleGroundDS::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
{
}
bool BattleGroundDS::SetupBattleGround()
{
return true;
-6
View File
@@ -17,9 +17,7 @@
*/
#ifndef __BATTLEGROUNDDS_H
#define __BATTLEGROUNDDS_H
class BattleGround;
class BattleGroundDSScore : public BattleGroundScore
{
public:
@@ -27,21 +25,17 @@ class BattleGroundDSScore : public BattleGroundScore
virtual ~BattleGroundDSScore() {};
//TODO fix me
};
class BattleGroundDS : public BattleGround
{
friend class BattleGroundMgr;
public:
BattleGroundDS();
~BattleGroundDS();
void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
-120
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ObjectMgr.h"
#include "World.h"
#include "WorldPacket.h"
@@ -29,13 +28,11 @@
#include "Object.h"
#include "Player.h"
#include "Util.h"
// these variables aren't used outside of this file, so declare them only here
uint32 BG_EY_HonorScoreTicks[BG_HONOR_MODE_NUM] = {
330, // normal honor
200 // holiday
};
BattleGroundEY::BattleGroundEY()
{
m_BuffChange = true;
@@ -45,21 +42,17 @@ BattleGroundEY::BattleGroundEY()
m_Points_Trigger[BLOOD_ELF] = TR_BLOOD_ELF_BUFF;
m_Points_Trigger[DRAENEI_RUINS] = TR_DRAENEI_RUINS_BUFF;
m_Points_Trigger[MAGE_TOWER] = TR_MAGE_TOWER_BUFF;
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_EY_START_TWO_MINUTES;
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_EY_START_HALF_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN;
}
BattleGroundEY::~BattleGroundEY()
{
}
void BattleGroundEY::Update(uint32 diff)
{
BattleGround::Update(diff);
if (GetStatus() == STATUS_IN_PROGRESS)
{
m_PointAddingTimer -= diff;
@@ -71,11 +64,9 @@ void BattleGroundEY::Update(uint32 diff)
if (m_TeamPointsCount[BG_TEAM_HORDE] > 0)
AddPoints(HORDE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_HORDE] - 1]);
}
if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN || m_FlagState == BG_EY_FLAG_STATE_ON_GROUND)
{
m_FlagsTimer -= diff;
if (m_FlagsTimer < 0)
{
m_FlagsTimer = 0;
@@ -85,7 +76,6 @@ void BattleGroundEY::Update(uint32 diff)
RespawnFlagAfterDrop();
}
}
m_TowerCapCheckTimer -= diff;
if (m_TowerCapCheckTimer <= 0)
{
@@ -101,21 +91,17 @@ void BattleGroundEY::Update(uint32 diff)
}
}
}
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_REALVER_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_REALVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i)
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
for(uint32 i = 0; i < EY_POINTS_MAX; ++i)
@@ -125,7 +111,6 @@ void BattleGroundEY::StartingEventOpenDoors()
SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + buff + i * 3, RESPAWN_IMMEDIATELY);
}
}
void BattleGroundEY::AddPoints(uint32 Team, uint32 Points)
{
BattleGroundTeamId team_index = GetTeamIndexByTeamId(Team);
@@ -138,7 +123,6 @@ void BattleGroundEY::AddPoints(uint32 Team, uint32 Points)
}
UpdateTeamScore(Team);
}
void BattleGroundEY::CheckSomeoneJoinedPoint()
{
GameObject *obj = NULL;
@@ -175,7 +159,6 @@ void BattleGroundEY::CheckSomeoneJoinedPoint()
}
}
}
void BattleGroundEY::CheckSomeoneLeftPoint()
{
//reset current point counts
@@ -217,7 +200,6 @@ void BattleGroundEY::CheckSomeoneLeftPoint()
}
}
}
void BattleGroundEY::UpdatePointStatuses()
{
for(uint8 point = 0; point < EY_POINTS_MAX; ++point)
@@ -226,14 +208,12 @@ void BattleGroundEY::UpdatePointStatuses()
continue;
//count new point bar status:
m_PointBarStatus[point] += (m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] < BG_EY_POINT_MAX_CAPTURERS_COUNT) ? m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] : BG_EY_POINT_MAX_CAPTURERS_COUNT;
if (m_PointBarStatus[point] > BG_EY_PROGRESS_BAR_ALI_CONTROLLED)
//point is fully alliance's
m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_ALI_CONTROLLED;
if (m_PointBarStatus[point] < BG_EY_PROGRESS_BAR_HORDE_CONTROLLED)
//point is fully horde's
m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_HORDE_CONTROLLED;
uint32 pointOwnerTeamId = 0;
//find which team should own this point
if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW)
@@ -242,7 +222,6 @@ void BattleGroundEY::UpdatePointStatuses()
pointOwnerTeamId = ALLIANCE;
else
pointOwnerTeamId = EY_POINT_NO_OWNER;
for (uint8 i = 0; i < m_PlayersNearPoint[point].size(); ++i)
{
Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[point][i]);
@@ -255,7 +234,6 @@ void BattleGroundEY::UpdatePointStatuses()
//point was uncontrolled and player is from team which captured point
if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && plr->GetTeam() == pointOwnerTeamId)
this->EventTeamCapturedPoint(plr, point);
//point was under control and player isn't from team which controlled it
if (m_PointState[point] == EY_POINT_UNDER_CONTROL && plr->GetTeam() != m_PointOwnedByTeam[point])
this->EventTeamLostPoint(plr, point);
@@ -264,7 +242,6 @@ void BattleGroundEY::UpdatePointStatuses()
}
}
}
void BattleGroundEY::UpdateTeamScore(uint32 Team)
{
uint32 score = GetTeamScore(Team);
@@ -278,19 +255,16 @@ void BattleGroundEY::UpdateTeamScore(uint32 Team)
PlaySoundToAll(BG_EY_SOUND_NEAR_VICTORY);
m_IsInformedNearVictory = true;
}*/
if (score >= BG_EY_MAX_TEAM_SCORE)
{
score = BG_EY_MAX_TEAM_SCORE;
EndBattleGround(Team);
}
if (Team == ALLIANCE)
UpdateWorldState(EY_ALLIANCE_RESOURCES, score);
else
UpdateWorldState(EY_HORDE_RESOURCES, score);
}
void BattleGroundEY::EndBattleGround(uint32 winner)
{
//win reward
@@ -301,10 +275,8 @@ void BattleGroundEY::EndBattleGround(uint32 winner)
//complete map reward
RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE);
RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE);
BattleGround::EndBattleGround(winner);
}
void BattleGroundEY::UpdatePointsCount(uint32 Team)
{
if (Team == ALLIANCE)
@@ -312,7 +284,6 @@ void BattleGroundEY::UpdatePointsCount(uint32 Team)
else
UpdateWorldState(EY_HORDE_BASE, m_TeamPointsCount[BG_TEAM_HORDE]);
}
void BattleGroundEY::UpdatePointsIcons(uint32 Team, uint32 Point)
{
//we MUST firstly send 0, after that we can send 1!!!
@@ -333,18 +304,14 @@ void BattleGroundEY::UpdatePointsIcons(uint32 Team, uint32 Point)
UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 1);
}
}
void BattleGroundEY::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map
BattleGroundEYScore* sc = new BattleGroundEYScore;
m_PlayersNearPoint[EY_POINTS_MAX].push_back(plr->GetGUID());
m_PlayerScores[plr->GetGUID()] = sc;
}
void BattleGroundEY::RemovePlayer(Player *plr, uint64 guid)
{
// sometimes flag aura not removed :(
@@ -368,15 +335,12 @@ void BattleGroundEY::RemovePlayer(Player *plr, uint64 guid)
}
}
}
void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
if(!Source->isAlive()) //hack code, must be removed later
return;
switch(Trigger)
{
case TR_BLOOD_ELF_POINT:
@@ -416,7 +380,6 @@ void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger)
break;
}
}
bool BattleGroundEY::SetupBattleGround()
{
// doors
@@ -477,7 +440,6 @@ bool BattleGroundEY::SetupBattleGround()
sLog.outErrorDb("BatteGroundEY: Failed to spawn some object BattleGround not created!");
return false;
}
//buffs
for (int i = 0; i < EY_POINTS_MAX; ++i)
{
@@ -493,7 +455,6 @@ bool BattleGroundEY::SetupBattleGround()
)
sLog.outError("BattleGroundEY: Cannot spawn buff");
}
WorldSafeLocsEntry const *sg = NULL;
sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_ALLIANCE);
if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE))
@@ -501,22 +462,18 @@ bool BattleGroundEY::SetupBattleGround()
sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!");
return false;
}
sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_HORDE);
if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE))
{
sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!");
return false;
}
return true;
}
void BattleGroundEY::Reset()
{
//call parent's class reset
BattleGround::Reset();
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
m_TeamScores[BG_TEAM_HORDE] = 0;
m_TeamPointsCount[BG_TEAM_ALLIANCE] = 0;
@@ -531,7 +488,6 @@ void BattleGroundEY::Reset()
m_TowerCapCheckTimer = 0;
bool isBGWeekend = sBattleGroundMgr.IsBGWeekend(GetTypeID());
m_HonorTics = (isBGWeekend) ? BG_EY_EYWeekendHonorTicks : BG_EY_NotEYWeekendHonorTicks;
for(uint8 i = 0; i < EY_POINTS_MAX; ++i)
{
m_PointOwnedByTeam[i] = EY_POINT_NO_OWNER;
@@ -543,47 +499,37 @@ void BattleGroundEY::Reset()
m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].clear();
m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].reserve(30);
}
void BattleGroundEY::RespawnFlag(bool send_message)
{
if (m_FlagCapturedBgObjectType > 0)
SpawnBGObject(m_FlagCapturedBgObjectType, RESPAWN_ONE_DAY);
m_FlagCapturedBgObjectType = 0;
m_FlagState = BG_EY_FLAG_STATE_ON_BASE;
SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_IMMEDIATELY);
if (send_message)
{
SendMessageToAll(LANG_BG_EY_RESETED_FLAG, CHAT_MSG_BG_SYSTEM_NEUTRAL);
PlaySoundToAll(BG_EY_SOUND_FLAG_RESET); // flags respawned sound...
}
UpdateWorldState(NETHERSTORM_FLAG, 1);
}
void BattleGroundEY::RespawnFlagAfterDrop()
{
RespawnFlag(true);
GameObject *obj = HashMapHolder<GameObject>::Find(GetDroppedFlagGUID());
if (obj)
obj->Delete();
else
sLog.outError("BattleGroundEY: Unknown dropped flag guid: %u",GUID_LOPART(GetDroppedFlagGUID()));
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 *Source)
{
if (GetStatus() != STATUS_IN_PROGRESS)
@@ -597,13 +543,10 @@ void BattleGroundEY::EventPlayerDroppedFlag(Player *Source)
}
return;
}
if (!IsFlagPickedup())
return;
if (GetFlagPickerGUID() != Source->GetGUID())
return;
SetFlagPicker(0);
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
m_FlagState = BG_EY_FLAG_STATE_ON_GROUND;
@@ -613,18 +556,15 @@ void BattleGroundEY::EventPlayerDroppedFlag(Player *Source)
//this does not work correctly :( (it should remove flag carrier name)
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
if (Source->GetTeam() == ALLIANCE)
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL);
else
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL);
}
void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
{
if (GetStatus() != STATUS_IN_PROGRESS || IsFlagPickedup() || !Source->IsWithinDistInMap(target_obj, 10))
return;
if (Source->GetTeam() == ALLIANCE)
{
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER);
@@ -635,34 +575,27 @@ void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER);
PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
}
if (m_FlagState == BG_EY_FLAG_STATE_ON_BASE)
UpdateWorldState(NETHERSTORM_FLAG, 0);
m_FlagState = BG_EY_FLAG_STATE_ON_PLAYER;
SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_ONE_DAY);
SetFlagPicker(Source->GetGUID());
//get flag aura on player
Source->CastSpell(Source, BG_EY_NETHERSTORM_FLAG_SPELL, true);
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
if (Source->GetTeam() == ALLIANCE)
PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, Source->GetName());
else
PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL, Source->GetName());
}
void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
//Natural point
uint32 Team = m_PointOwnedByTeam[Point];
if (!Team)
return;
if (Team == ALLIANCE)
{
m_TeamPointsCount[BG_TEAM_ALLIANCE]--;
@@ -677,36 +610,27 @@ void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point)
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY);
SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY);
}
SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType, RESPAWN_IMMEDIATELY);
SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 1, RESPAWN_IMMEDIATELY);
SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 2, RESPAWN_IMMEDIATELY);
//buff isn't despawned
m_PointOwnedByTeam[Point] = EY_POINT_NO_OWNER;
m_PointState[Point] = EY_POINT_NO_OWNER;
if (Team == ALLIANCE)
SendMessageToAll(m_LoosingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
else
SendMessageToAll(m_LoosingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source);
UpdatePointsIcons(Team, Point);
UpdatePointsCount(Team);
}
void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
uint32 Team = Source->GetTeam();
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 (Team == ALLIANCE)
{
m_TeamPointsCount[BG_TEAM_ALLIANCE]++;
@@ -721,53 +645,39 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY);
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY);
}
//buff isn't respawned
m_PointOwnedByTeam[Point] = Team;
m_PointState[Point] = EY_POINT_UNDER_CONTROL;
if (Team == ALLIANCE)
SendMessageToAll(m_CapturingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
else
SendMessageToAll(m_CapturingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source);
if (m_BgCreatures[Point])
DelCreature(Point);
WorldSafeLocsEntry const *sg = NULL;
sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[Point].GraveYardId);
if (!sg || !AddSpiritGuide(Point, sg->x, sg->y, sg->z, 3.124139f, Team))
sLog.outError("BatteGroundEY: Failed to spawn spirit guide! point: %u, team: %u, graveyard_id: %u",
Point, Team, m_CapturingPointTypes[Point].GraveYardId);
// SpawnBGCreature(Point,RESPAWN_IMMEDIATELY);
UpdatePointsIcons(Team, Point);
UpdatePointsCount(Team);
}
void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType)
{
if (GetStatus() != STATUS_IN_PROGRESS || GetFlagPickerGUID() != Source->GetGUID())
return;
SetFlagPicker(0);
m_FlagState = BG_EY_FLAG_STATE_WAIT_RESPAWN;
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
if (Source->GetTeam() == ALLIANCE)
PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
else
PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
SpawnBGObject(BgObjectType, RESPAWN_IMMEDIATELY);
m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME;
m_FlagCapturedBgObjectType = BgObjectType;
uint8 team_id = 0;
if (Source->GetTeam() == ALLIANCE)
{
@@ -779,19 +689,15 @@ void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType
team_id = BG_TEAM_HORDE;
SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_H, CHAT_MSG_BG_SYSTEM_HORDE, Source);
}
if (m_TeamPointsCount[team_id] > 0)
AddPoints(Source->GetTeam(), BG_EY_FlagPoints[m_TeamPointsCount[team_id] - 1]);
UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1);
}
void BattleGroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
{
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found
return;
switch(type)
{
case SCORE_FLAG_CAPTURES: // flags captured
@@ -802,7 +708,6 @@ void BattleGroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value
break;
}
}
void BattleGroundEY::FillInitialWorldStates(WorldPacket& data)
{
data << uint32(EY_HORDE_BASE) << uint32(m_TeamPointsCount[BG_TEAM_HORDE]);
@@ -815,33 +720,19 @@ void BattleGroundEY::FillInitialWorldStates(WorldPacket& data)
data << uint32(0xab1) << uint32(0x0);
data << uint32(0xab0) << uint32(0x0);
data << uint32(0xaaf) << uint32(0x0);
data << uint32(DRAENEI_RUINS_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == HORDE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL);
data << uint32(DRAENEI_RUINS_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == ALLIANCE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL);
data << uint32(DRAENEI_RUINS_UNCONTROL) << uint32(m_PointState[DRAENEI_RUINS] != EY_POINT_UNDER_CONTROL);
data << uint32(MAGE_TOWER_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[MAGE_TOWER] == ALLIANCE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL);
data << uint32(MAGE_TOWER_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[MAGE_TOWER] == HORDE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL);
data << uint32(MAGE_TOWER_UNCONTROL) << uint32(m_PointState[MAGE_TOWER] != EY_POINT_UNDER_CONTROL);
data << uint32(FEL_REAVER_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[FEL_REALVER] == HORDE && m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL);
data << uint32(FEL_REAVER_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[FEL_REALVER] == ALLIANCE && m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL);
data << uint32(FEL_REAVER_UNCONTROL) << uint32(m_PointState[FEL_REALVER] != EY_POINT_UNDER_CONTROL);
data << uint32(BLOOD_ELF_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[BLOOD_ELF] == HORDE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL);
data << uint32(BLOOD_ELF_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[BLOOD_ELF] == ALLIANCE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL);
data << uint32(BLOOD_ELF_UNCONTROL) << uint32(m_PointState[BLOOD_ELF] != EY_POINT_UNDER_CONTROL);
data << uint32(NETHERSTORM_FLAG) << uint32(m_FlagState == BG_EY_FLAG_STATE_ON_BASE);
data << uint32(0xad2) << uint32(0x1);
data << uint32(0xad1) << uint32(0x1);
data << uint32(0xabe) << uint32(GetTeamScore(HORDE));
@@ -852,39 +743,31 @@ void BattleGroundEY::FillInitialWorldStates(WorldPacket& data)
data << uint32(0xa9e) << uint32(0x0);
data << uint32(0xc0d) << uint32(0x17b);
}
WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(Player* player)
{
uint32 g_id = 0;
switch(player->GetTeam())
{
case ALLIANCE: g_id = EY_GRAVEYARD_MAIN_ALLIANCE; break;
case HORDE: g_id = EY_GRAVEYARD_MAIN_HORDE; break;
default: return NULL;
}
float distance, nearestDistance;
WorldSafeLocsEntry const* entry = NULL;
WorldSafeLocsEntry const* nearestEntry = NULL;
entry = sWorldSafeLocsStore.LookupEntry(g_id);
nearestEntry = entry;
if (!entry)
{
sLog.outError("BattleGroundEY: Not found the main team graveyard. Graveyard system isn't working!");
return NULL;
}
float plr_x = player->GetPositionX();
float plr_y = player->GetPositionY();
float plr_z = player->GetPositionZ();
distance = (entry->x - plr_x)*(entry->x - plr_x) + (entry->y - plr_y)*(entry->y - plr_y) + (entry->z - plr_z)*(entry->z - plr_z);
nearestDistance = distance;
for(uint8 i = 0; i < EY_POINTS_MAX; ++i)
{
if (m_PointOwnedByTeam[i]==player->GetTeam() && m_PointState[i]==EY_POINT_UNDER_CONTROL)
@@ -903,16 +786,13 @@ WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(Player* player)
}
}
}
return nearestEntry;
}
bool BattleGroundEY::IsAllNodesConrolledByTeam(uint32 team) const
{
uint32 count = 0;
for(int i = 0; i < EY_POINTS_MAX; ++i)
if (m_PointOwnedByTeam[i] == team && m_PointState[i] == EY_POINT_UNDER_CONTROL)
++count;
return count == EY_POINTS_MAX;
}
-43
View File
@@ -17,17 +17,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __BATTLEGROUNDEY_H
#define __BATTLEGROUNDEY_H
#include "Language.h"
class BattleGround;
#define BG_EY_FLAG_RESPAWN_TIME (10*IN_MILISECONDS) //10 seconds
#define BG_EY_FPOINTS_TICK_TIME (2*IN_MILISECONDS) //2 seconds
enum BG_EY_WorldStates
{
EY_ALLIANCE_RESOURCES = 2749,
@@ -54,7 +49,6 @@ enum BG_EY_WorldStates
NETHERSTORM_FLAG_STATE_ALLIANCE = 2769,
NETHERSTORM_FLAG_STATE_HORDE = 2770
};
enum BG_EY_ProgressBarConsts
{
BG_EY_POINT_MAX_CAPTURERS_COUNT = 5,
@@ -68,7 +62,6 @@ enum BG_EY_ProgressBarConsts
BG_EY_PROGRESS_BAR_NEUTRAL_HIGH = 70,
BG_EY_PROGRESS_BAR_ALI_CONTROLLED = 100
};
enum BG_EY_Sounds
{
//strange ids, but sure about them
@@ -78,13 +71,11 @@ enum BG_EY_Sounds
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 EYBattleGroundObjectEntry
{
BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door
@@ -100,7 +91,6 @@ enum EYBattleGroundObjectEntry
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 EYBattleGroundPointsTrigger
{
TR_BLOOD_ELF_POINT = 4476,
@@ -112,7 +102,6 @@ enum EYBattleGroundPointsTrigger
TR_MAGE_TOWER_BUFF = 4570,
TR_DRAENEI_RUINS_BUFF = 4571
};
enum EYBattleGroundGaveyards
{
EY_GRAVEYARD_MAIN_ALLIANCE = 1103,
@@ -122,18 +111,15 @@ enum EYBattleGroundGaveyards
EY_GRAVEYARD_DRAENEI_RUINS = 1107,
EY_GRAVEYARD_MAGE_TOWER = 1108
};
enum EYBattleGroundPoints
{
FEL_REALVER = 0,
BLOOD_ELF = 1,
DRAENEI_RUINS = 2,
MAGE_TOWER = 3,
EY_PLAYERS_OUT_OF_POINTS = 4,
EY_POINTS_MAX = 4
};
enum EYBattleGroundCreaturesTypes
{
EY_SPIRIT_FEL_REALVER = 0,
@@ -142,10 +128,8 @@ enum EYBattleGroundCreaturesTypes
EY_SPIRIT_MAGE_TOWER = 3,
EY_SPIRIT_MAIN_ALLIANCE = 4,
EY_SPIRIT_MAIN_HORDE = 5,
BG_EY_CREATURES_MAX = 6
};
enum EYBattleGroundObjectTypes
{
BG_EY_OBJECT_DOOR_A = 0,
@@ -210,16 +194,13 @@ enum EYBattleGroundObjectTypes
BG_EY_OBJECT_BERSERKBUFF_MAGE_TOWER = 58,
BG_EY_OBJECT_MAX = 59
};
#define BG_EY_NotEYWeekendHonorTicks 330
#define BG_EY_EYWeekendHonorTicks 200
enum BG_EY_Score
{
BG_EY_WARNING_NEAR_VICTORY_SCORE = 1800,
BG_EY_MAX_TEAM_SCORE = 2000
};
enum BG_EY_FlagState
{
BG_EY_FLAG_STATE_ON_BASE = 0,
@@ -227,14 +208,12 @@ enum BG_EY_FlagState
BG_EY_FLAG_STATE_ON_PLAYER = 2,
BG_EY_FLAG_STATE_ON_GROUND = 3
};
enum EYBattleGroundPointState
{
EY_POINT_NO_OWNER = 0,
EY_POINT_STATE_UNCONTROLLED = 0,
EY_POINT_UNDER_CONTROL = 3
};
struct BattleGroundEYPointIconsStruct
{
BattleGroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex)
@@ -243,7 +222,6 @@ struct BattleGroundEYPointIconsStruct
uint32 WorldStateAllianceControlledIndex;
uint32 WorldStateHordeControlledIndex;
};
struct BattleGroundEYLoosingPointStruct
{
BattleGroundEYLoosingPointStruct(uint32 _SpawnNeutralObjectType, uint32 _DespawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _DespawnObjectTypeHorde, uint32 _MessageIdHorde)
@@ -251,14 +229,12 @@ struct BattleGroundEYLoosingPointStruct
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)
@@ -267,7 +243,6 @@ struct BattleGroundEYCapturingPointStruct
SpawnObjectTypeHorde(_SpawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde),
GraveYardId(_GraveYardId)
{}
uint32 DespawnNeutralObjectType;
uint32 SpawnObjectTypeAlliance;
uint32 MessageIdAlliance;
@@ -275,10 +250,8 @@ struct BattleGroundEYCapturingPointStruct
uint32 MessageIdHorde;
uint32 GraveYardId;
};
const uint8 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] =
{
@@ -301,7 +274,6 @@ const BattleGroundEYCapturingPointStruct m_CapturingPointTypes[EY_POINTS_MAX] =
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, 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, EY_GRAVEYARD_MAGE_TOWER)
};
class BattleGroundEYScore : public BattleGroundScore
{
public:
@@ -309,21 +281,17 @@ class BattleGroundEYScore : public BattleGroundScore
virtual ~BattleGroundEYScore() {};
uint32 FlagCaptures;
};
class BattleGroundEY : public BattleGround
{
friend class BattleGroundMgr;
public:
BattleGroundEY();
~BattleGroundEY();
void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
/* BG Flags */
uint64 GetFlagPickerGUID() const { return m_FlagKeeper; }
void SetFlagPicker(uint64 guid) { m_FlagKeeper = guid; }
@@ -331,7 +299,6 @@ class BattleGroundEY : public BattleGround
uint8 GetFlagState() const { return m_FlagState; }
void RespawnFlag(bool send_message);
void RespawnFlagAfterDrop();
void RemovePlayer(Player *plr,uint64 guid);
void HandleBuffUse(uint64 const& buff_guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
@@ -345,11 +312,9 @@ class BattleGroundEY : public BattleGround
virtual void FillInitialWorldStates(WorldPacket& data);
void SetDroppedFlagGUID(uint64 guid) { m_DroppedFlagGUID = guid;}
uint64 GetDroppedFlagGUID() const { return m_DroppedFlagGUID;}
/* Battleground Events */
virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj);
virtual void EventPlayerDroppedFlag(Player *Source);
/* achievement req. */
bool IsAllNodesConrolledByTeam(uint32 team) const;
private:
@@ -358,38 +323,30 @@ class BattleGroundEY : public BattleGround
void EventTeamLostPoint(Player *Source, uint32 Point);
void UpdatePointsCount(uint32 Team);
void UpdatePointsIcons(uint32 Team, uint32 Point);
/* Point status updating procedures */
void CheckSomeoneLeftPoint();
void CheckSomeoneJoinedPoint();
void UpdatePointStatuses();
/* Scorekeeping */
uint32 GetTeamScore(uint32 Team) const { return m_TeamScores[GetTeamIndexByTeamId(Team)]; }
void AddPoints(uint32 Team, uint32 Points);
void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; }
void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; }
uint32 m_HonorScoreTics[2];
uint32 m_TeamPointsCount[2];
uint32 m_Points_Trigger[EY_POINTS_MAX];
uint64 m_FlagKeeper; // keepers guid
uint64 m_DroppedFlagGUID;
uint32 m_FlagCapturedBgObjectType; // type that should be despawned when flag is captured
uint8 m_FlagState; // for checking flag state
int32 m_FlagsTimer;
int32 m_TowerCapCheckTimer;
uint32 m_PointOwnedByTeam[EY_POINTS_MAX];
uint8 m_PointState[EY_POINTS_MAX];
int32 m_PointBarStatus[EY_POINTS_MAX];
typedef std::vector<uint64> PlayersNearPointType;
PlayersNearPointType m_PlayersNearPoint[EY_POINTS_MAX + 1];
uint8 m_CurrentPointPlayersCount[2*EY_POINTS_MAX];
int32 m_PointAddingTimer;
uint32 m_HonorTics;
};
-106
View File
@@ -17,13 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "ArenaTeam.h"
#include "BattleGroundMgr.h"
#include "BattleGroundWS.h"
@@ -34,42 +32,33 @@
#include "Player.h"
#include "Object.h"
#include "Opcodes.h"
void WorldSession::HandleBattlemasterHelloOpcode( WorldPacket & recv_data )
{
uint64 guid;
recv_data >> guid;
sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)));
Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
if (!unit)
return;
if(!unit->isBattleMaster()) // it's not battlemaster
return;
// Stop the npc if moving
unit->StopMoving();
BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(unit->GetEntry());
if (!_player->GetBGAccessByLevel(bgTypeId))
{
// temp, must be gossip message...
SendNotification(LANG_YOUR_BG_LEVEL_REQ_ERROR);
return;
}
SendBattlegGroundList(guid, bgTypeId);
}
void WorldSession::SendBattlegGroundList( uint64 guid, BattleGroundTypeId bgTypeId )
{
WorldPacket data;
sBattleGroundMgr.BuildBattleGroundListPacket(&data, guid, _player, bgTypeId, 0);
SendPacket( &data );
}
void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
{
uint64 guid;
@@ -78,40 +67,31 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
uint8 joinAsGroup;
bool isPremade = false;
Group * grp;
recv_data >> guid; // battlemaster guid
recv_data >> bgTypeId_; // battleground type id (DBC id)
recv_data >> instanceId; // instance id, 0 if First Available selected
recv_data >> joinAsGroup; // join as group
if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
{
sLog.outError("Battleground: invalid bgtype (%u) received. possible cheater? player guid %u",bgTypeId_,_player->GetGUIDLow());
return;
}
BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);
sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid)));
// can do this, since it's battleground, not arena
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, 0);
// ignore if player is already in BG
if (_player->InBattleGround())
return;
// get bg instance or bg template if instance not found
BattleGround *bg = NULL;
if (instanceId)
bg = sBattleGroundMgr.GetBattleGroundThroughClientInstance(instanceId, bgTypeId);
if (!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)))
{
sLog.outError("Battleground: no available bg / template found");
return;
}
// check queueing conditions
if (!joinAsGroup)
{
@@ -146,7 +126,6 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
}
}
// if we're here, then the conditions to join a bg are met. We can proceed in joining.
// _player->GetGroup() was already checked, grp is already initialized
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, isPremade, 0);
uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
@@ -157,9 +136,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
{
Player *member = itr->getSource();
if(!member) continue; // this should never happen
uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); // add to queue
WorldPacket data;
// send status packet (in queue)
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType);
@@ -175,12 +152,10 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
{
// already checked if queueSlot is valid, now just get it
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
WorldPacket data;
// send status packet (in queue)
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType);
SendPacket(&data);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
}
@@ -188,31 +163,25 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data )
if (!ginfo->IsInvitedToBGInstanceGUID)
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);
}
void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ )
{
// empty opcode
sLog.outDebug("WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message");
BattleGround *bg = _player->GetBattleGround();
if(!bg) // can't be received if player not in battleground
return;
switch( bg->GetTypeID() )
{
case BATTLEGROUND_WS:
{
uint32 count1 = 0; //always constant zero?
uint32 count2 = 0; //count of next fields
Player *ali_plr = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetAllianceFlagPickerGUID());
if (ali_plr)
++count2;
Player *horde_plr = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetHordeFlagPickerGUID());
if (horde_plr)
++count2;
WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4+16*count1+16*count2));
data << count1; // alliance flag holders count - obsolete, now always 0
/*for(uint8 i = 0; i < count1; ++i)
@@ -234,7 +203,6 @@ void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv
data << (float)horde_plr->GetPositionX();
data << (float)horde_plr->GetPositionY();
}
SendPacket(&data);
}
break;
@@ -256,57 +224,44 @@ void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv
break;
}
}
void WorldSession::HandlePVPLogDataOpcode( WorldPacket & /*recv_data*/ )
{
sLog.outDebug( "WORLD: Recvd MSG_PVP_LOG_DATA Message");
BattleGround *bg = _player->GetBattleGround();
if (!bg)
return;
WorldPacket data;
sBattleGroundMgr.BuildPvpLogDataPacket(&data, bg);
SendPacket(&data);
sLog.outDebug( "WORLD: Sent MSG_PVP_LOG_DATA Message");
}
void WorldSession::HandleBattlefieldListOpcode( WorldPacket &recv_data )
{
sLog.outDebug( "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message");
uint32 bgTypeId;
recv_data >> bgTypeId; // id from DBC
uint8 fromWhere;
recv_data >> fromWhere; // 0 - battlemaster, 1 - UI
BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
if (!bl)
{
sLog.outError("Battleground: invalid bgtype received.");
return;
}
WorldPacket data;
sBattleGroundMgr.BuildBattleGroundListPacket(&data, 0, _player, BattleGroundTypeId(bgTypeId), fromWhere);
SendPacket( &data );
}
void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
{
sLog.outDebug( "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message");
uint8 type; // arenatype if arena
uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
uint32 instanceId;
uint32 bgTypeId_; // type id from dbc
uint16 unk; // 0x1F90 constant?
uint8 action; // enter battle 0x1, leave queue 0x0
recv_data >> type >> unk2 >> bgTypeId_ >> unk >> action;
if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
{
sLog.outError("Battleground: invalid bgtype (%u) received.", bgTypeId_);
@@ -327,12 +282,10 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
// if the player is not in queue, continue or no group information - this should never happen
if (itrPlayerStatus == qpMap.end() || !itrPlayerStatus->second.GroupInfo)
continue;
BattleGround * bg = NULL;
// get possibly needed data from groupinfo
uint8 arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
uint8 status = 0;
if (!itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID)
{
// not invited to bg, get template
@@ -345,11 +298,9 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID, bgTypeId);
status = STATUS_WAIT_JOIN;
}
// if bg not found, then continue, don't invite if already in the instance
if (!bg || (_player->InBattleGround() && _player->GetBattleGround() && _player->GetBattleGround()->GetInstanceID() == bg->GetInstanceID()))
continue;
// re - invite player with proper data
WorldPacket data;
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, status, INVITE_ACCEPT_WAIT_TIME, 0, arenatype);
@@ -358,7 +309,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
}
return;
}
//get GroupQueueInfo from BattleGroundQueue
BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_);
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, type);
@@ -369,7 +319,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
sLog.outError("Battleground: itrplayerstatus not found.");
return;
}
instanceId = itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID;
// if action == 1, then instanceId is required
if (!instanceId && action == 1)
@@ -377,9 +326,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
sLog.outError("Battleground: instance not found.");
return;
}
BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId, bgTypeId);
// bg template might and must be used in case of leaving queue, when instance is not created yet
if (!bg && action == 0)
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
@@ -388,7 +335,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
sLog.outError("Battleground: bg_template not found for type id %u.", bgTypeId);
return;
}
if (_player->InBattleGroundQueue())
{
//we must use temporary variables, because GroupQueueInfo pointer can be deleted in BattleGroundQueue::RemovePlayer() function!
@@ -397,7 +343,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
uint32 isRated = itrPlayerStatus->second.GroupInfo->IsRated;
uint32 rating = itrPlayerStatus->second.GroupInfo->ArenaTeamRating;
uint32 opponentsRating = itrPlayerStatus->second.GroupInfo->OpponentsTeamRating;
//some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it
if (action == 1 && arenaType == 0)
{
@@ -425,9 +370,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
case 1: // port to battleground
if (!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId))
return; // cheating?
_player->SetBattleGroundEntryPoint();
// resurrect the player
if (!_player->isAlive())
{
@@ -439,9 +382,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
{
_player->GetMotionMaster()->MovementExpired();
_player->CleanupAfterTaxiFlight();
}
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType());
_player->GetSession()->SendPacket(&data);
// remove battleground queue status from BGmgr
@@ -450,7 +391,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
// also this is required to prevent stuck at old battleground after SetBattleGroundId set to new
if (BattleGround *currentBg = _player->GetBattleGround())
currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true);
// set the destination instance id
_player->SetBattleGroundId(bg->GetInstanceID(), bgTypeId);
// set the destination team
@@ -491,34 +431,26 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data )
}
}
}
void WorldSession::HandleLeaveBattlefieldOpcode( WorldPacket & /*recv_data*/ )
{
sLog.outDebug( "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message");
//uint8 unk1, unk2;
//uint32 bgTypeId; // id from DBC
//uint16 unk3;
//recv_data >> unk1 >> unk2 >> bgTypeId >> unk3; - no used currently
//if(bgTypeId >= MAX_BATTLEGROUND_TYPES) // cheating? but not important in this case
// return;
// not allow leave battleground in combat
if (_player->isInCombat())
if (BattleGround* bg = _player->GetBattleGround())
if (bg->GetStatus() != STATUS_WAIT_LEAVE)
return;
_player->LeaveBattleground();
}
void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
{
// empty opcode
sLog.outDebug( "WORLD: Battleground status" );
WorldPacket data;
// we must update all queues here
BattleGround *bg = NULL;
@@ -571,76 +503,56 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
}
}
}
void WorldSession::HandleAreaSpiritHealerQueryOpcode( WorldPacket & recv_data )
{
sLog.outDebug("WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY");
BattleGround *bg = _player->GetBattleGround();
if (!bg)
return;
uint64 guid;
recv_data >> guid;
Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
if (!unit)
return;
if(!unit->isSpiritService()) // it's not spirit service
return;
sBattleGroundMgr.SendAreaSpiritHealerQueryOpcode(_player, bg, guid);
}
void WorldSession::HandleAreaSpiritHealerQueueOpcode( WorldPacket & recv_data )
{
sLog.outDebug("WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE");
BattleGround *bg = _player->GetBattleGround();
if (!bg)
return;
uint64 guid;
recv_data >> guid;
Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
if (!unit)
return;
if(!unit->isSpiritService()) // it's not spirit service
return;
bg->AddPlayerToResurrectQueue(guid, _player->GetGUID());
}
void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
{
sLog.outDebug("WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
//recv_data.hexlike();
uint64 guid; // arena Battlemaster guid
uint8 arenaslot; // 2v2, 3v3 or 5v5
uint8 asGroup; // asGroup
uint8 isRated; // isRated
Group * grp;
recv_data >> guid >> arenaslot >> asGroup >> isRated;
// ignore if we already in BG or BG queue
if (_player->InBattleGround())
return;
Creature *unit = GetPlayer()->GetMap()->GetCreature(guid);
if (!unit)
return;
if(!unit->isBattleMaster()) // it's not battle master
return;
uint8 arenatype = 0;
uint32 arenaRating = 0;
switch(arenaslot)
{
case 0:
@@ -656,7 +568,6 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
sLog.outError("Unknown arena slot %u at HandleBattlemasterJoinArena()", arenaslot);
return;
}
//check existance
BattleGround* bg = NULL;
if (!(bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA)))
@@ -664,10 +575,8 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
sLog.outError("Battleground: template bg (all arenas) not found");
return;
}
BattleGroundTypeId bgTypeId = bg->GetTypeID();
BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype);
// check queueing conditions
if (!asGroup)
{
@@ -692,9 +601,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
return;
}
}
uint32 ateamId = 0;
if (isRated)
{
ateamId = _player->GetArenaTeamId(arenaslot);
@@ -713,19 +620,15 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player *member = itr->getSource();
// calc avg personal rating
avg_pers_rating += member->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaslot*6) + 5);
}
if (arenatype)
avg_pers_rating /= arenatype;
// if avg personal rating is more than 150 points below the teams rating, the team will be queued against an opponent matching or similar to the average personal rating
if (avg_pers_rating + 150 < arenaRating)
arenaRating = avg_pers_rating;
}
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating, ateamId);
uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId));
if (asGroup)
@@ -738,14 +641,11 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
}
else
bg->SetRated(false);
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player *member = itr->getSource();
if(!member) continue;
uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId);// add to queue
WorldPacket data;
// send status packet (in queue)
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
@@ -762,7 +662,6 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
else
{
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
WorldPacket data;
// send status packet (in queue)
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype);
@@ -772,24 +671,19 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data )
}
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId), arenatype, isRated, arenaRating);
}
void WorldSession::HandleReportPvPAFK( WorldPacket & recv_data )
{
uint64 playerGuid;
recv_data >> playerGuid;
Player *reportedPlayer = objmgr.GetPlayer(playerGuid);
if (!reportedPlayer)
{
sLog.outDebug("WorldSession::HandleReportPvPAFK: player not found");
return;
}
sLog.outDebug("WorldSession::HandleReportPvPAFK: %s reported %s", _player->GetName(), reportedPlayer->GetName());
reportedPlayer->ReportedAfkBy(_player);
}
void WorldSession::SendBattleGroundOrArenaJoinError(uint8 err)
{
WorldPacket data;
File diff suppressed because it is too large Load Diff
-44
View File
@@ -17,32 +17,23 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __BATTLEGROUNDMGR_H
#define __BATTLEGROUNDMGR_H
#include "Common.h"
#include "Policies/Singleton.h"
#include "BattleGround.h"
typedef std::map<uint32, BattleGround*> BattleGroundSet;
//this container can't be deque, because deque doesn't like removing the last element - if you remove it, it invalidates next iterator and crash appears
typedef std::list<BattleGround*> BGFreeSlotQueueType;
typedef UNORDERED_MAP<uint32, BattleGroundTypeId> BattleMastersMap;
#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
#define COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME 10
struct GroupQueueInfo; // type predefinition
struct PlayerQueueInfo // stores information for players in queue
{
uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes
GroupQueueInfo * GroupInfo; // pointer to the associated groupqueueinfo
};
struct GroupQueueInfo // stores information about the group in queue (also used when joined as solo!)
{
std::map<uint64, PlayerQueueInfo*> Players; // player queue info map
@@ -57,7 +48,6 @@ struct GroupQueueInfo // stores informatio
uint32 ArenaTeamRating; // if rated match, inited to the rating of the team
uint32 OpponentsTeamRating; // for rated arena matches
};
enum BattleGroundQueueGroupTypes
{
BG_QUEUE_PREMADE_ALLIANCE = 0,
@@ -66,16 +56,13 @@ enum BattleGroundQueueGroupTypes
BG_QUEUE_NORMAL_HORDE = 3
};
#define BG_QUEUE_GROUP_TYPES_COUNT 4
class BattleGround;
class BattleGroundQueue
{
public:
BattleGroundQueue();
~BattleGroundQueue();
void Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0);
void FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id);
bool CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam);
bool CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers);
@@ -85,16 +72,12 @@ class BattleGroundQueue
void RemovePlayer(const uint64& guid, bool decreaseInvitedCount);
void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id);
void DecreaseGroupLength(uint32 queueId, uint32 AsGroup);
void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue);
typedef std::map<uint64, PlayerQueueInfo> QueuedPlayersMap;
QueuedPlayersMap m_QueuedPlayers;
//we need constant add to begin and constant remove / add from the end, therefore deque suits our problem well
typedef std::list<GroupQueueInfo*> GroupsQueueType;
/*
This two dimensional array is used to store All queued groups
First dimension specifies the bgTypeId
@@ -105,7 +88,6 @@ class BattleGroundQueue
BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches
*/
GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_QUEUES][BG_QUEUE_GROUP_TYPES_COUNT];
// class to select and invite groups to bg
class SelectionPool
{
@@ -119,18 +101,14 @@ class BattleGroundQueue
private:
uint32 PlayerCount;
};
//one selection pool for horde, other one for alliance
SelectionPool m_SelectionPools[BG_TEAMS_COUNT];
private:
bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side);
uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME];
uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES];
uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES];
};
/*
This class is used to invite player to BG again, when minute lasts from his first invitation
it is capable to solve all possibilities
@@ -143,7 +121,6 @@ class BGQueueInviteEvent : public BasicEvent
{
};
virtual ~BGQueueInviteEvent() {};
virtual bool Execute(uint64 e_time, uint32 p_time);
virtual void Abort(uint64 e_time);
private:
@@ -152,7 +129,6 @@ class BGQueueInviteEvent : public BasicEvent
BattleGroundTypeId m_BgTypeId;
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
@@ -164,9 +140,7 @@ class BGQueueRemoveEvent : public BasicEvent
BGQueueRemoveEvent(const uint64& pl_guid, uint32 bgInstanceGUID, BattleGroundTypeId BgTypeId, BattleGroundQueueTypeId bgQueueTypeId, uint32 removeTime)
: m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgTypeId(BgTypeId), m_BgQueueTypeId(bgQueueTypeId)
{}
virtual ~BGQueueRemoveEvent() {}
virtual bool Execute(uint64 e_time, uint32 p_time);
virtual void Abort(uint64 e_time);
private:
@@ -176,7 +150,6 @@ class BGQueueRemoveEvent : public BasicEvent
BattleGroundTypeId m_BgTypeId;
BattleGroundQueueTypeId m_BgQueueTypeId;
};
class BattleGroundMgr
{
public:
@@ -184,7 +157,6 @@ class BattleGroundMgr
BattleGroundMgr();
~BattleGroundMgr();
void Update(uint32 diff);
/* Packet Building */
void BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr);
void BuildPlayerLeftBattleGroundPacket(WorldPacket *data, const uint64& guid);
@@ -195,41 +167,30 @@ class BattleGroundMgr
void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype);
void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid);
void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid);
/* Battlegrounds */
BattleGround* GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId);
BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown
BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId);
BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated);
uint32 CreateBattleGround(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);
void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; };
void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); }
uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id);
void CreateInitialBattleGrounds();
void DeleteAllBattleGrounds();
void SendToBattleGround(Player *pl, uint32 InstanceID, BattleGroundTypeId bgTypeId);
/* Battleground queues */
//these queues are instantiated when creating BattlegroundMrg
BattleGroundQueue m_BattleGroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; // public, because we need to access them in BG handler code
BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID];
void ScheduleQueueUpdate(BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id);
uint32 GetMaxRatingDifference() const;
uint32 GetRatingDiscardTimer() const;
uint32 GetPrematureFinishTime() const;
void InitAutomaticArenaPointDistribution();
void DistributeArenaPoints();
void ToggleArenaTesting();
void ToggleTesting();
void SetHolidayWeekends(uint32 mask);
void LoadBattleMastersEntry();
BattleGroundTypeId GetBattleMasterBG(uint32 entry) const
@@ -239,20 +200,16 @@ class BattleGroundMgr
return itr->second;
return BATTLEGROUND_WS;
}
bool isArenaTesting() const { return m_ArenaTesting; }
bool isTesting() const { return m_Testing; }
static bool IsArenaType(BattleGroundTypeId bgTypeId);
static bool IsBattleGroundType(BattleGroundTypeId bgTypeId) { return !BattleGroundMgr::IsArenaType(bgTypeId); }
static BattleGroundQueueTypeId BGQueueTypeId(BattleGroundTypeId bgTypeId, uint8 arenaType);
static BattleGroundTypeId BGTemplateId(BattleGroundQueueTypeId bgQueueTypeId);
static uint8 BGArenaType(BattleGroundQueueTypeId bgQueueTypeId);
static bool IsBGWeekend(BattleGroundTypeId bgTypeId);
private:
BattleMastersMap mBattleMastersMap;
/* Battlegrounds */
BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID];
std::vector<uint32>m_QueueUpdateScheduler;
@@ -263,7 +220,6 @@ class BattleGroundMgr
bool m_ArenaTesting;
bool m_Testing;
};
#define sBattleGroundMgr Trinity::Singleton<BattleGroundMgr>::Instance()
#endif
-30
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "BattleGround.h"
#include "BattleGroundNA.h"
#include "Language.h"
@@ -25,11 +24,9 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "WorldPacket.h"
BattleGroundNA::BattleGroundNA()
{
m_BgObjects.resize(BG_NA_OBJECT_MAX);
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
@@ -40,90 +37,69 @@ BattleGroundNA::BattleGroundNA()
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
}
BattleGroundNA::~BattleGroundNA()
{
}
void BattleGroundNA::Update(uint32 diff)
{
BattleGround::Update(diff);
/*if (GetStatus() == STATUS_IN_PROGRESS)
{
// update something
}*/
}
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 *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map, default values are set in constructor
BattleGroundNAScore* sc = new BattleGroundNAScore;
m_PlayerScores[plr->GetGUID()] = sc;
UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
}
void BattleGroundNA::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
{
if (GetStatus() == STATUS_WAIT_LEAVE)
return;
UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
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);
UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
CheckArenaWinConditions();
}
bool BattleGroundNA::HandlePlayerUnderMap(Player *player)
{
player->TeleportTo(GetMapId(),4055.504395,2919.660645,13.611241,player->GetOrientation(),false);
return true;
}
void BattleGroundNA::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
//uint32 SpellId = 0;
//uint64 buff_guid = 0;
switch(Trigger)
@@ -136,24 +112,20 @@ void BattleGroundNA::HandleAreaTrigger(Player *Source, uint32 Trigger)
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
break;
}
//if (buff_guid)
// HandleTriggerBuff(buff_guid,Source);
}
void BattleGroundNA::FillInitialWorldStates(WorldPacket &data)
{
data << uint32(0xa0f) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7
data << uint32(0xa10) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8
data << uint32(0xa11) << uint32(1); // 9
}
void BattleGroundNA::Reset()
{
//call parent's class reset
BattleGround::Reset();
}
bool BattleGroundNA::SetupBattleGround()
{
// gates
@@ -168,10 +140,8 @@ bool BattleGroundNA::SetupBattleGround()
sLog.outErrorDb("BatteGroundNA: Failed to spawn some object!");
return false;
}
return true;
}
/*
20:12:14 id:036668 [S2C] SMSG_INIT_WORLD_STATES (706 = 0x02C2) len: 86
0000: 2f 02 00 00 72 0e 00 00 00 00 00 00 09 00 11 0a | /...r...........
-8
View File
@@ -19,9 +19,7 @@
*/
#ifndef __BATTLEGROUNDNA_H
#define __BATTLEGROUNDNA_H
class BattleGround;
enum BattleGroundNAObjectTypes
{
BG_NA_OBJECT_DOOR_1 = 0,
@@ -32,7 +30,6 @@ enum BattleGroundNAObjectTypes
BG_NA_OBJECT_BUFF_2 = 5,
BG_NA_OBJECT_MAX = 6
};
enum BattleGroundNAObjects
{
BG_NA_OBJECT_TYPE_DOOR_1 = 183978,
@@ -42,7 +39,6 @@ enum BattleGroundNAObjects
BG_NA_OBJECT_TYPE_BUFF_1 = 184663,
BG_NA_OBJECT_TYPE_BUFF_2 = 184664
};
class BattleGroundNAScore : public BattleGroundScore
{
public:
@@ -50,21 +46,17 @@ class BattleGroundNAScore : public BattleGroundScore
virtual ~BattleGroundNAScore() {};
//TODO fix me
};
class BattleGroundNA : public BattleGround
{
friend class BattleGroundMgr;
public:
BattleGroundNA();
~BattleGroundNA();
void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
-30
View File
@@ -18,7 +18,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "BattleGround.h"
#include "BattleGroundRL.h"
#include "Language.h"
@@ -26,11 +25,9 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "WorldPacket.h"
BattleGroundRL::BattleGroundRL()
{
m_BgObjects.resize(BG_RL_OBJECT_MAX);
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
@@ -41,91 +38,70 @@ BattleGroundRL::BattleGroundRL()
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
}
BattleGroundRL::~BattleGroundRL()
{
}
void BattleGroundRL::Update(uint32 diff)
{
BattleGround::Update(diff);
/*if (GetStatus() == STATUS_IN_PROGRESS)
{
// update something
}*/
}
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 *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map, default values are set in constructor
BattleGroundRLScore* sc = new BattleGroundRLScore;
m_PlayerScores[plr->GetGUID()] = sc;
UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
}
void BattleGroundRL::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
{
if (GetStatus() == STATUS_WAIT_LEAVE)
return;
UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
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);
UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
CheckArenaWinConditions();
}
bool BattleGroundRL::HandlePlayerUnderMap(Player *player)
{
player->TeleportTo(GetMapId(),1285.810547,1667.896851,39.957642,player->GetOrientation(),false);
return true;
}
void BattleGroundRL::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
// this is wrong way to implement these things. On official it done by gameobject spell cast.
if (GetStatus() != STATUS_IN_PROGRESS)
return;
//uint32 SpellId = 0;
//uint64 buff_guid = 0;
switch(Trigger)
@@ -138,24 +114,20 @@ void BattleGroundRL::HandleAreaTrigger(Player *Source, uint32 Trigger)
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
break;
}
//if (buff_guid)
// HandleTriggerBuff(buff_guid,Source);
}
void BattleGroundRL::FillInitialWorldStates(WorldPacket &data)
{
data << uint32(0xbb8) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7
data << uint32(0xbb9) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8
data << uint32(0xbba) << uint32(1); // 9
}
void BattleGroundRL::Reset()
{
//call parent's reset
BattleGround::Reset();
}
bool BattleGroundRL::SetupBattleGround()
{
// gates
@@ -168,10 +140,8 @@ bool BattleGroundRL::SetupBattleGround()
sLog.outErrorDb("BatteGroundRL: Failed to spawn some object!");
return false;
}
return true;
}
/*
Packet S->C, id 600, SMSG_INIT_WORLD_STATES (706), len 86
0000: 3C 02 00 00 80 0F 00 00 00 00 00 00 09 00 BA 0B | <...............
-8
View File
@@ -19,9 +19,7 @@
*/
#ifndef __BATTLEGROUNDRL_H
#define __BATTLEGROUNDRL_H
class BattleGround;
enum BattleGroundRLObjectTypes
{
BG_RL_OBJECT_DOOR_1 = 0,
@@ -30,7 +28,6 @@ enum BattleGroundRLObjectTypes
BG_RL_OBJECT_BUFF_2 = 3,
BG_RL_OBJECT_MAX = 4
};
enum BattleGroundRLObjects
{
BG_RL_OBJECT_TYPE_DOOR_1 = 185918,
@@ -38,7 +35,6 @@ enum BattleGroundRLObjects
BG_RL_OBJECT_TYPE_BUFF_1 = 184663,
BG_RL_OBJECT_TYPE_BUFF_2 = 184664
};
class BattleGroundRLScore : public BattleGroundScore
{
public:
@@ -46,23 +42,19 @@ class BattleGroundRLScore : public BattleGroundScore
virtual ~BattleGroundRLScore() {};
//TODO fix me
};
class BattleGroundRL : public BattleGround
{
friend class BattleGroundMgr;
public:
BattleGroundRL();
~BattleGroundRL();
void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void Reset();
virtual void FillInitialWorldStates(WorldPacket &d);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
-14
View File
@@ -15,15 +15,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "BattleGround.h"
#include "BattleGroundRV.h"
#include "Language.h"
#include "Player.h"
BattleGroundRV::BattleGroundRV()
{
m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M;
m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S;
m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S;
@@ -34,47 +31,36 @@ BattleGroundRV::BattleGroundRV()
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN;
}
BattleGroundRV::~BattleGroundRV()
{
}
void BattleGroundRV::Update(uint32 diff)
{
BattleGround::Update(diff);
}
void BattleGroundRV::StartingEventCloseDoors()
{
}
void BattleGroundRV::StartingEventOpenDoors()
{
}
void BattleGroundRV::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map, default values are set in constructor
BattleGroundRVScore* sc = new BattleGroundRVScore;
m_PlayerScores[plr->GetGUID()] = sc;
}
void BattleGroundRV::RemovePlayer(Player * /*plr*/, uint64 /*guid*/)
{
}
void BattleGroundRV::HandleKillPlayer(Player* player, Player* killer)
{
BattleGround::HandleKillPlayer(player, killer);
}
void BattleGroundRV::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
{
}
bool BattleGroundRV::SetupBattleGround()
{
return true;
-6
View File
@@ -17,9 +17,7 @@
*/
#ifndef __BATTLEGROUNDRV_H
#define __BATTLEGROUNDRV_H
class BattleGround;
class BattleGroundRVScore : public BattleGroundScore
{
public:
@@ -27,21 +25,17 @@ class BattleGroundRVScore : public BattleGroundScore
virtual ~BattleGroundRVScore() {};
//TODO fix me
};
class BattleGroundRV : public BattleGround
{
friend class BattleGroundMgr;
public:
BattleGroundRV();
~BattleGroundRV();
void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
bool SetupBattleGround();
-15
View File
@@ -15,12 +15,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "BattleGround.h"
#include "BattleGroundSA.h"
#include "Language.h"
#include "Player.h"
BattleGroundSA::BattleGroundSA()
{
//TODO FIX ME!
@@ -29,52 +27,39 @@ BattleGroundSA::BattleGroundSA()
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
}
BattleGroundSA::~BattleGroundSA()
{
}
void BattleGroundSA::Update(uint32 diff)
{
BattleGround::Update(diff);
}
void BattleGroundSA::StartingEventCloseDoors()
{
}
void BattleGroundSA::StartingEventOpenDoors()
{
}
void BattleGroundSA::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map, default values are set in constructor
BattleGroundSAScore* sc = new BattleGroundSAScore;
m_PlayerScores[plr->GetGUID()] = sc;
}
void BattleGroundSA::RemovePlayer(Player* /*plr*/,uint64 /*guid*/)
{
}
void BattleGroundSA::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/)
{
// this is wrong way to implement these things. On official it done by gameobject spell cast.
if (GetStatus() != STATUS_IN_PROGRESS)
return;
}
void BattleGroundSA::UpdatePlayerScore(Player* Source, uint32 type, uint32 value)
{
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found...
return;
BattleGround::UpdatePlayerScore(Source,type,value);
}
-9
View File
@@ -15,40 +15,31 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __BATTLEGROUNDSA_H
#define __BATTLEGROUNDSA_H
class BattleGround;
class BattleGroundSAScore : public BattleGroundScore
{
public:
BattleGroundSAScore() {};
virtual ~BattleGroundSAScore() {};
};
class BattleGroundSA : public BattleGround
{
friend class BattleGroundMgr;
public:
BattleGroundSA();
~BattleGroundSA();
void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
void RemovePlayer(Player *plr,uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
//bool SetupBattleGround();
/* Scorekeeping */
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
private:
};
#endif
-80
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "BattleGround.h"
#include "BattleGroundWS.h"
#include "Creature.h"
@@ -29,7 +28,6 @@
#include "Player.h"
#include "World.h"
#include "WorldPacket.h"
// these variables aren't used outside of this file, so declare them only here
enum BG_WSG_Rewards
{
@@ -38,42 +36,34 @@ enum BG_WSG_Rewards
BG_WSG_MAP_COMPLETE,
BG_WSG_REWARD_NUM
};
uint32 BG_WSG_Honor[BG_HONOR_MODE_NUM][BG_WSG_REWARD_NUM] = {
{20,40,40}, // normal honor
{60,40,80} // holiday
};
uint32 BG_WSG_Reputation[BG_HONOR_MODE_NUM][BG_WSG_REWARD_NUM] = {
{0,35,0}, // normal honor
{0,45,0} // holiday
};
BattleGroundWS::BattleGroundWS()
{
m_BgObjects.resize(BG_WS_OBJECT_MAX);
m_BgCreatures.resize(BG_CREATURES_MAX_WS);
m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES;
m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE;
m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN;
}
BattleGroundWS::~BattleGroundWS()
{
}
void BattleGroundWS::Update(uint32 diff)
{
BattleGround::Update(diff);
if (GetStatus() == STATUS_IN_PROGRESS)
{
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
{
m_FlagsTimer[BG_TEAM_ALLIANCE] -= diff;
if (m_FlagsTimer[BG_TEAM_ALLIANCE] < 0)
{
m_FlagsTimer[BG_TEAM_ALLIANCE] = 0;
@@ -83,7 +73,6 @@ void BattleGroundWS::Update(uint32 diff)
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
{
m_FlagsDropTimer[BG_TEAM_ALLIANCE] -= diff;
if (m_FlagsDropTimer[BG_TEAM_ALLIANCE] < 0)
{
m_FlagsDropTimer[BG_TEAM_ALLIANCE] = 0;
@@ -94,7 +83,6 @@ void BattleGroundWS::Update(uint32 diff)
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN)
{
m_FlagsTimer[BG_TEAM_HORDE] -= diff;
if (m_FlagsTimer[BG_TEAM_HORDE] < 0)
{
m_FlagsTimer[BG_TEAM_HORDE] = 0;
@@ -104,7 +92,6 @@ void BattleGroundWS::Update(uint32 diff)
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
{
m_FlagsDropTimer[BG_TEAM_HORDE] -= diff;
if (m_FlagsDropTimer[BG_TEAM_HORDE] < 0)
{
m_FlagsDropTimer[BG_TEAM_HORDE] = 0;
@@ -145,7 +132,6 @@ void BattleGroundWS::Update(uint32 diff)
}
}
}
void BattleGroundWS::StartingEventCloseDoors()
{
for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i)
@@ -156,32 +142,26 @@ void BattleGroundWS::StartingEventCloseDoors()
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_4; ++i)
DoorOpen(i);
for(uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_2; ++i)
DoorOpen(i);
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);
for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i)
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
}
void BattleGroundWS::AddPlayer(Player *plr)
{
BattleGround::AddPlayer(plr);
//create score and add it to map, default values are set in constructor
BattleGroundWGScore* sc = new BattleGroundWGScore;
m_PlayerScores[plr->GetGUID()] = sc;
}
void BattleGroundWS::RespawnFlag(uint32 Team, bool captured)
{
if (Team == ALLIANCE)
@@ -194,7 +174,6 @@ void BattleGroundWS::RespawnFlag(uint32 Team, bool captured)
sLog.outDebug("Respawn Horde flag");
m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE;
}
if (captured)
{
//when map_update will be allowed for battlegrounds this code will be useless
@@ -205,12 +184,10 @@ void BattleGroundWS::RespawnFlag(uint32 Team, bool captured)
}
m_BothFlagsKept = false;
}
void BattleGroundWS::RespawnFlagAfterDrop(uint32 team)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
RespawnFlag(team,false);
if (team == ALLIANCE)
{
@@ -222,26 +199,20 @@ void BattleGroundWS::RespawnFlagAfterDrop(uint32 team)
SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY);
SendMessageToAll(LANG_BG_WS_HORDE_FLAG_RESPAWNED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
}
PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED);
GameObject *obj = HashMapHolder<GameObject>::Find(GetDroppedFlagGUID(team));
if (obj)
obj->Delete();
else
sLog.outError("unknown droped flag bg, guid: %u",GUID_LOPART(GetDroppedFlagGUID(team)));
SetDroppedFlagGUID(0,team);
m_BothFlagsKept = false;
}
void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
uint32 winner = 0;
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
if (Source->GetTeam() == ALLIANCE)
{
@@ -281,33 +252,26 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
}
//for flag capture is reward 2 honorable kills
RewardHonorToTeam(GetBonusHonorFromKill(2), Source->GetTeam());
SpawnBGObject(BG_WS_OBJECT_H_FLAG, BG_WS_FLAG_RESPAWN_TIME);
SpawnBGObject(BG_WS_OBJECT_A_FLAG, BG_WS_FLAG_RESPAWN_TIME);
if (Source->GetTeam() == ALLIANCE)
SendMessageToAll(LANG_BG_WS_CAPTURED_HF, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
else
SendMessageToAll(LANG_BG_WS_CAPTURED_AF, CHAT_MSG_BG_SYSTEM_HORDE, Source);
UpdateFlagState(Source->GetTeam(), 1); // flag state none
UpdateTeamScore(Source->GetTeam());
// only flag capture should be updated
UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures
if (GetTeamScore(ALLIANCE) == BG_WS_MAX_TEAM_SCORE)
winner = ALLIANCE;
if (GetTeamScore(HORDE) == BG_WS_MAX_TEAM_SCORE)
winner = HORDE;
if (winner)
{
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 0);
UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 0);
UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, 1);
UpdateWorldState(BG_WS_FLAG_STATE_HORDE, 1);
RewardHonorToTeam(BG_WSG_Honor[m_HonorMode][BG_WSG_WIN], winner);
EndBattleGround(winner);
}
@@ -316,7 +280,6 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
m_FlagsTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_RESPAWN_TIME;
}
}
void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
{
if (GetStatus() != STATUS_IN_PROGRESS)
@@ -345,9 +308,7 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
}
return;
}
bool set = false;
if (Source->GetTeam() == ALLIANCE)
{
if (!IsHordeFlagPickedup())
@@ -382,12 +343,10 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
set = true;
}
}
if (set)
{
Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true);
UpdateFlagState(Source->GetTeam(), 1);
if (Source->GetTeam() == ALLIANCE)
{
SendMessageToAll(LANG_BG_WS_DROPPED_HF, CHAT_MSG_BG_SYSTEM_HORDE, Source);
@@ -398,19 +357,15 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
SendMessageToAll(LANG_BG_WS_DROPPED_AF, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source);
UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, uint32(-1));
}
m_FlagsDropTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_DROP_TIME;
}
}
void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
int32 message_id = 0;
ChatMsg type;
//alliance flag picked up from base
if(Source->GetTeam() == HORDE && this->GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE
&& this->m_BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID())
@@ -428,7 +383,6 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
if(m_FlagState[1] == BG_WS_FLAG_STATE_ON_PLAYER)
m_BothFlagsKept = true;
}
//horde flag picked up from base
if (Source->GetTeam() == ALLIANCE && this->GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE
&& this->m_BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID())
@@ -446,7 +400,6 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
if(m_FlagState[0] == BG_WS_FLAG_STATE_ON_PLAYER)
m_BothFlagsKept = true;
}
//Alliance flag on ground(not in base) (returned or picked up again from ground!)
if (GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10))
{
@@ -480,7 +433,6 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
//called in HandleGameObjectUseOpcode:
//target_obj->Delete();
}
//Horde flag on ground(not in base) (returned or picked up again)
if (GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10))
{
@@ -514,14 +466,11 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target
//called in HandleGameObjectUseOpcode:
//target_obj->Delete();
}
if (!message_id)
return;
SendMessageToAll(message_id, type, Source);
Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT);
}
void BattleGroundWS::RemovePlayer(Player *plr, uint64 guid)
{
// sometimes flag aura not removed :(
@@ -548,7 +497,6 @@ void BattleGroundWS::RemovePlayer(Player *plr, uint64 guid)
this->EventPlayerDroppedFlag(plr);
}
}
void BattleGroundWS::UpdateFlagState(uint32 team, uint32 value)
{
if (team == ALLIANCE)
@@ -556,7 +504,6 @@ void BattleGroundWS::UpdateFlagState(uint32 team, uint32 value)
else
UpdateWorldState(BG_WS_FLAG_STATE_HORDE, value);
}
void BattleGroundWS::UpdateTeamScore(uint32 team)
{
if (team == ALLIANCE)
@@ -564,13 +511,11 @@ void BattleGroundWS::UpdateTeamScore(uint32 team)
else
UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(team));
}
void BattleGroundWS::HandleAreaTrigger(Player *Source, uint32 Trigger)
{
// this is wrong way to implement these things. On official it done by gameobject spell cast.
if (GetStatus() != STATUS_IN_PROGRESS)
return;
//uint32 SpellId = 0;
//uint64 buff_guid = 0;
switch(Trigger)
@@ -613,11 +558,9 @@ void BattleGroundWS::HandleAreaTrigger(Player *Source, uint32 Trigger)
Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger);
break;
}
//if (buff_guid)
// HandleTriggerBuff(buff_guid,Source);
}
bool BattleGroundWS::SetupBattleGround()
{
// flags
@@ -647,31 +590,25 @@ bool BattleGroundWS::SetupBattleGround()
sLog.outErrorDb("BatteGroundWS: Failed to spawn some object BattleGround not created!");
return false;
}
WorldSafeLocsEntry const *sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_ALLIANCE);
if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE))
{
sLog.outErrorDb("BatteGroundWS: Failed to spawn Alliance spirit guide! BattleGround not created!");
return false;
}
sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_HORDE);
if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE))
{
sLog.outErrorDb("BatteGroundWS: Failed to spawn Horde spirit guide! BattleGround not created!");
return false;
}
sLog.outDebug("BatteGroundWS: BG objects and spirit guides spawned");
return true;
}
void BattleGroundWS::Reset()
{
//call parent's class reset
BattleGround::Reset();
m_FlagKeepers[BG_TEAM_ALLIANCE] = 0;
m_FlagKeepers[BG_TEAM_HORDE] = 0;
m_DroppedFlagGUID[BG_TEAM_ALLIANCE] = 0;
@@ -684,7 +621,6 @@ void BattleGroundWS::Reset()
m_ReputationCapture = (isBGWeekend) ? 45 : 35;
m_HonorWinKills = (isBGWeekend) ? 3 : 1;
m_HonorEndKills = (isBGWeekend) ? 4 : 2;
/* Spirit nodes is static at this BG and then not required deleting at BG reset.
if (m_BgCreatures[WS_SPIRIT_MAIN_ALLIANCE])
DelCreature(WS_SPIRIT_MAIN_ALLIANCE);
@@ -692,7 +628,6 @@ void BattleGroundWS::Reset()
DelCreature(WS_SPIRIT_MAIN_HORDE);
*/
}
void BattleGroundWS::EndBattleGround(uint32 winner)
{
//win reward
@@ -703,27 +638,20 @@ void BattleGroundWS::EndBattleGround(uint32 winner)
//complete map_end rewards (even if no team wins)
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), ALLIANCE);
RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), HORDE);
BattleGround::EndBattleGround(winner);
}
void BattleGroundWS::HandleKillPlayer(Player *player, Player *killer)
{
if (GetStatus() != STATUS_IN_PROGRESS)
return;
EventPlayerDroppedFlag(player);
BattleGround::HandleKillPlayer(player, killer);
}
void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
{
BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID());
if(itr == m_PlayerScores.end()) // player not found
return;
switch(type)
{
case SCORE_FLAG_CAPTURES: // flags captured
@@ -737,7 +665,6 @@ void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value
break;
}
}
WorldSafeLocsEntry const* BattleGroundWS::GetClosestGraveYard(Player* player)
{
//if status in progress, it returns main graveyards with spiritguides
@@ -760,37 +687,30 @@ WorldSafeLocsEntry const* BattleGroundWS::GetClosestGraveYard(Player* player)
return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_FLAGROOM_HORDE);
}
}
void BattleGroundWS::FillInitialWorldStates(WorldPacket& data)
{
data << uint32(BG_WS_FLAG_CAPTURES_ALLIANCE) << uint32(GetTeamScore(ALLIANCE));
data << uint32(BG_WS_FLAG_CAPTURES_HORDE) << uint32(GetTeamScore(HORDE));
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND)
data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(-1);
else if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(1);
else
data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(0);
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND)
data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(-1);
else if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(1);
else
data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(0);
data << uint32(BG_WS_FLAG_CAPTURES_MAX) << uint32(BG_WS_MAX_TEAM_SCORE);
if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER)
data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(2);
else
data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(1);
if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER)
data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(2);
else
data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(1);
}
-23
View File
@@ -17,12 +17,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __BATTLEGROUNDWS_H
#define __BATTLEGROUNDWS_H
#include "BattleGround.h"
enum BG_WS_TimerOrScore
{
BG_WS_MAX_TEAM_SCORE = 3,
@@ -31,7 +28,6 @@ enum BG_WS_TimerOrScore
BG_WS_SPELL_FORCE_TIME = 600000,
BG_WS_SPELL_BRUTAL_TIME = 900000
};
enum BG_WS_Sound
{
BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
@@ -42,7 +38,6 @@ enum BG_WS_Sound
BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP = 8174,
BG_WS_SOUND_FLAGS_RESPAWNED = 8232
};
enum BG_WS_SpellId
{
BG_WS_SPELL_WARSONG_FLAG = 23333,
@@ -52,7 +47,6 @@ enum BG_WS_SpellId
BG_WS_SPELL_FOCUSED_ASSAULT = 46392,
BG_WS_SPELL_BRUTAL_ASSAULT = 46393
};
enum BG_WS_WorldStates
{
BG_WS_FLAG_UNK_ALLIANCE = 1545,
@@ -64,7 +58,6 @@ enum BG_WS_WorldStates
BG_WS_FLAG_STATE_HORDE = 2338,
BG_WS_FLAG_STATE_ALLIANCE = 2339
};
enum BG_WS_ObjectTypes
{
BG_WS_OBJECT_DOOR_A_1 = 0,
@@ -87,7 +80,6 @@ enum BG_WS_ObjectTypes
BG_WS_OBJECT_BERSERKBUFF_2 = 17,
BG_WS_OBJECT_MAX = 18
};
enum BG_WS_ObjectEntry
{
BG_OBJECT_DOOR_A_1_WS_ENTRY = 179918,
@@ -105,7 +97,6 @@ enum BG_WS_ObjectEntry
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 = 0,
@@ -113,7 +104,6 @@ enum BG_WS_FlagState
BG_WS_FLAG_STATE_ON_PLAYER = 2,
BG_WS_FLAG_STATE_ON_GROUND = 3
};
enum BG_WS_Graveyards
{
WS_GRAVEYARD_FLAGROOM_ALLIANCE = 769,
@@ -121,21 +111,17 @@ enum BG_WS_Graveyards
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_CarrierDebuffs
{
WS_SPELL_FOCUSED_ASSAULT = 46392,
WS_SPELL_BRUTAL_ASSAULT = 46393
};
class BattleGroundWGScore : public BattleGroundScore
{
public:
@@ -144,22 +130,18 @@ class BattleGroundWGScore : public BattleGroundScore
uint32 FlagCaptures;
uint32 FlagReturns;
};
class BattleGroundWS : public BattleGround
{
friend class BattleGroundMgr;
public:
/* Construction */
BattleGroundWS();
~BattleGroundWS();
void Update(uint32 diff);
/* inherited from BattlegroundClass */
virtual void AddPlayer(Player *plr);
virtual void StartingEventCloseDoors();
virtual void StartingEventOpenDoors();
/* BG Flags */
uint64 GetAllianceFlagPickerGUID() const { return m_FlagKeepers[BG_TEAM_ALLIANCE]; }
uint64 GetHordeFlagPickerGUID() const { return m_FlagKeepers[BG_TEAM_HORDE]; }
@@ -174,12 +156,10 @@ class BattleGroundWS : public BattleGround
void RemoveTimedAura(uint32 aura);
bool IsBrutalTimerDone;
bool IsForceTimerDone;
/* Battleground Events */
virtual void EventPlayerDroppedFlag(Player *Source);
virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj);
virtual void EventPlayerCapturedFlag(Player *Source);
void RemovePlayer(Player *plr, uint64 guid);
void HandleAreaTrigger(Player *Source, uint32 Trigger);
void HandleKillPlayer(Player *player, Player *killer);
@@ -187,14 +167,12 @@ class BattleGroundWS : public BattleGround
virtual void Reset();
void EndBattleGround(uint32 winner);
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
void UpdateFlagState(uint32 team, uint32 value);
void UpdateTeamScore(uint32 team);
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
void SetDroppedFlagGUID(uint64 guid, uint32 TeamID) { m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)] = guid;}
uint64 GetDroppedFlagGUID(uint32 TeamID) { return m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)];}
virtual void FillInitialWorldStates(WorldPacket& data);
/* Scorekeeping */
uint32 GetTeamScore(uint32 TeamID) const { return m_TeamScores[GetTeamIndexByTeamId(TeamID)]; }
void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; }
@@ -206,7 +184,6 @@ class BattleGroundWS : public BattleGround
uint8 m_FlagState[2]; // for checking flag state
int32 m_FlagsTimer[2];
int32 m_FlagsDropTimer[2];
uint32 m_ReputationCapture;
uint32 m_HonorWinKills;
uint32 m_HonorEndKills;
-3
View File
@@ -15,12 +15,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MANGOS_CALENDAR_H
#define MANGOS_CALENDAR_H
class Calendar
{
};
#endif
-40
View File
@@ -15,36 +15,27 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "InstanceSaveMgr.h"
#include "Log.h"
#include "Opcodes.h"
#include "Player.h"
void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_GET_CALENDAR"); // empty
time_t cur_time = time(NULL);
WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR,4+4*0+4+4*0+4+4);
// TODO: calendar invite event output
data << (uint32) 0; //invite node count
// TODO: calendar event output
data << (uint32) 0; //event count
data << (uint32) 0; //wtf??
data << (uint32) secsToTimeBitFields(cur_time); // current time
uint32 counter = 0;
size_t p_counter = data.wpos();
data << uint32(counter); // instance save count
for(int i = 0; i < TOTAL_DIFFICULTIES; ++i)
{
for (Player::BoundInstancesMap::const_iterator itr = _player->m_boundInstances[i].begin(); itr != _player->m_boundInstances[i].end(); ++itr)
@@ -61,7 +52,6 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data)
}
}
data.put<uint32>(p_counter,counter);
data << (uint32) 1135753200; //wtf?? (28.12.2005 12:00)
data << (uint32) 0; // unk counter 4
data << (uint32) 0; // unk counter 5
@@ -69,14 +59,12 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data)
//data.hexlike();
SendPacket(&data);
}
void WorldSession::HandleCalendarGetEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_GET_EVENT");
recv_data.hexlike();
recv_data.read_skip<uint64>(); // unk
}
void WorldSession::HandleCalendarGuildFilter(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_GUILD_FILTER");
@@ -85,24 +73,20 @@ void WorldSession::HandleCalendarGuildFilter(WorldPacket &recv_data)
recv_data.read_skip<uint32>(); // unk2
recv_data.read_skip<uint32>(); // unk3
}
void WorldSession::HandleCalendarArenaTeam(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_ARENA_TEAM");
recv_data.hexlike();
recv_data.read_skip<uint32>(); // unk
}
void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_ADD_EVENT");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//std::string unk1, unk2;
//recv_data >> (std::string)unk1;
//recv_data >> (std::string)unk2;
//uint8 unk3, unk4;
//uint32 unk5, unk6, unk7, unk8, unk9, count = 0;
//recv_data >> (uint8)unk3;
@@ -128,13 +112,11 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data)
// }
//}
}
void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_UPDATE_EVENT");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> std::string
@@ -147,110 +129,88 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data)
//recv_data >> uint32
//recv_data >> uint32
}
void WorldSession::HandleCalendarRemoveEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_REMOVE_EVENT");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> uint32
}
void WorldSession::HandleCalendarCopyEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_COPY_EVENT");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> uint32
}
void WorldSession::HandleCalendarEventInvite(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_INVITE");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> std::string
//recv_data >> uint8
//recv_data >> uint8
}
void WorldSession::HandleCalendarEventRsvp(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_RSVP");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> uint32
}
void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_REMOVE_INVITE");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data.readPackGUID(guid)
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> uint64
}
void WorldSession::HandleCalendarEventStatus(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_STATUS");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data.readPackGUID(guid)
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> uint32
}
void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_MODERATOR_STATUS");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data.readPackGUID(guid)
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> uint32
}
void WorldSession::HandleCalendarComplain(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_COMPLAIN");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
//recv_data >> uint64
}
void WorldSession::HandleCalendarGetNumPending(WorldPacket & /*recv_data*/)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_GET_NUM_PENDING"); // empty
WorldPacket data(SMSG_CALENDAR_SEND_NUM_PENDING, 4);
data << uint32(0); // 0 - no pending invites, 1 - some pending invites
SendPacket(&data);
-25
View File
@@ -17,20 +17,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_CELL_H
#define TRINITY_CELL_H
#include <cmath>
#include "GameSystem/TypeContainer.h"
#include "GameSystem/TypeContainerVisitor.h"
#include "GridDefines.h"
class Map;
class WorldObject;
enum District
{
UPPER_DISTRICT = 1,
@@ -44,15 +38,12 @@ enum District
LOWER_RIGHT_DISTRICT = (LOWER_DISTRICT | RIGHT_DISTRICT),
ALL_DISTRICT = (UPPER_DISTRICT | LOWER_DISTRICT | LEFT_DISTRICT | RIGHT_DISTRICT | CENTER_DISTRICT)
};
template<class T> struct CellLock;
struct TRINITY_DLL_DECL CellArea
{
CellArea() : right_offset(0), left_offset(0), upper_offset(0), lower_offset(0) {}
CellArea(int right, int left, int upper, int lower) : right_offset(right), left_offset(left), upper_offset(upper), lower_offset(lower) {}
bool operator!() const { return !right_offset && !left_offset && !upper_offset && !lower_offset; }
void ResizeBorders(CellPair& begin_cell, CellPair& end_cell) const
{
begin_cell << left_offset;
@@ -60,20 +51,17 @@ struct TRINITY_DLL_DECL CellArea
end_cell >> right_offset;
end_cell += upper_offset;
}
int right_offset;
int left_offset;
int upper_offset;
int lower_offset;
};
struct TRINITY_DLL_DECL Cell
{
Cell() { data.All = 0; }
Cell(const Cell &cell) { data.All = cell.data.All; }
explicit Cell(CellPair const& p);
void operator|=(Cell &cell)
{
data.Part.reserved = 0;
@@ -81,14 +69,12 @@ struct TRINITY_DLL_DECL Cell
uint32 x, y, old_x, old_y;
Compute(x, y);
cell.Compute(old_x, old_y);
if( std::abs(int(x-old_x)) > 1 || std::abs(int(y-old_y)) > 1)
{
data.Part.reserved = ALL_DISTRICT;
cell.data.Part.reserved = ALL_DISTRICT;
return;
}
if( x < old_x )
{
data.Part.reserved |= LEFT_DISTRICT;
@@ -110,45 +96,38 @@ struct TRINITY_DLL_DECL Cell
cell.data.Part.reserved |= UPPER_DISTRICT;
}
}
void Compute(uint32 &x, uint32 &y) const
{
x = data.Part.grid_x*MAX_NUMBER_OF_CELLS + data.Part.cell_x;
y = data.Part.grid_y*MAX_NUMBER_OF_CELLS + data.Part.cell_y;
}
bool DiffCell(const Cell &cell) const
{
return( data.Part.cell_x != cell.data.Part.cell_x ||
data.Part.cell_y != cell.data.Part.cell_y );
}
bool DiffGrid(const Cell &cell) const
{
return( data.Part.grid_x != cell.data.Part.grid_x ||
data.Part.grid_y != cell.data.Part.grid_y );
}
uint32 CellX() const { return data.Part.cell_x; }
uint32 CellY() const { return data.Part.cell_y; }
uint32 GridX() const { return data.Part.grid_x; }
uint32 GridY() const { return data.Part.grid_y; }
bool NoCreate() const { return data.Part.nocreate; }
void SetNoCreate() { data.Part.nocreate = 1; }
CellPair cellPair() const
{
return CellPair(
data.Part.grid_x*MAX_NUMBER_OF_CELLS+data.Part.cell_x,
data.Part.grid_y*MAX_NUMBER_OF_CELLS+data.Part.cell_y);
}
Cell& operator=(const Cell &cell)
{
this->data.All = cell.data.All;
return *this;
}
bool operator==(const Cell &cell) const { return (data.All == cell.data.All); }
bool operator!=(const Cell &cell) const { return !operator==(cell); }
union
@@ -164,17 +143,13 @@ struct TRINITY_DLL_DECL Cell
} Part;
uint32 All;
} data;
template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &visitor, Map &) const;
template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const;
template<class LOCK_TYPE, class T, class CONTAINER> void Visit(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &visitor, Map &, float radius, float x_off, float y_off) const;
static CellArea CalculateCellArea(const WorldObject &obj, float radius);
private:
template<class LOCK_TYPE, class T, class CONTAINER> void VisitCircle(const CellLock<LOCK_TYPE> &, TypeContainerVisitor<T, CONTAINER> &, Map &, const CellPair& , const CellPair& ) const;
};
template<class T>
struct TRINITY_DLL_DECL CellLock
{
-36
View File
@@ -17,16 +17,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_CELLIMPL_H
#define TRINITY_CELLIMPL_H
#include <cmath>
#include "Cell.h"
#include "Map.h"
#include "Object.h"
inline Cell::Cell(CellPair const& p)
{
data.Part.grid_x = p.x_coord / MAX_NUMBER_OF_CELLS;
@@ -36,7 +32,6 @@ inline Cell::Cell(CellPair const& p)
data.Part.nocreate = 0;
data.Part.reserved = 0;
}
template<class LOCK_TYPE,class T, class CONTAINER>
inline void
Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m) const
@@ -44,19 +39,16 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
const CellPair &standing_cell = l.i_cellPair;
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
return;
uint16 district = (District)this->data.Part.reserved;
if(district == CENTER_DISTRICT)
{
m.Visit(l, visitor);
return;
}
// set up the cell range based on the district
// the overloaded operators handle range checking
CellPair begin_cell = standing_cell;
CellPair end_cell = standing_cell;
switch( district )
{
case ALL_DISTRICT:
@@ -117,7 +109,6 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
break;
}
}
// loop the cell range
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++)
{
@@ -131,7 +122,6 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
}
}
}
template<class LOCK_TYPE,class T, class CONTAINER>
inline void
Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, float radius, float x_off, float y_off) const
@@ -139,9 +129,7 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
const CellPair &standing_cell = l.i_cellPair;
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
return;
int left = 0, right = 0, upper = 0, lower = 0;
// Origin = (CENTER_GRID_CELL_OFFSET, CENTER_GRID_CELL_OFFSET)
if(CENTER_GRID_CELL_OFFSET - x_off < radius)
++right;
@@ -151,21 +139,17 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
++upper;
if(CENTER_GRID_CELL_OFFSET + y_off < radius)
++lower;
if(!left && !right && !upper && !lower)
{
m.Visit(l, visitor);
return;
}
CellPair begin_cell = standing_cell;
CellPair end_cell = standing_cell;
begin_cell << left; //note: need change << if left > 1
begin_cell -= lower;
end_cell >> right;
end_cell += upper;
// loop the cell range
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++)
{
@@ -179,20 +163,16 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
}
}
}
inline int CellHelper(const float radius)
{
if(radius < 1.0f)
return 0;
return (int)ceilf(radius/SIZE_OF_GRID_CELL);
}
inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius)
{
if(radius <= 0.0f)
return CellArea();
//we should increase search radius by object's radius, otherwise
//we could have problems with huge creatures, which won't attack nearest players etc
radius += obj.GetObjectSize();
@@ -200,23 +180,18 @@ inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius)
//TODO: add more correct/generic method for this task
const float x_offset = (obj.GetPositionX() - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
const float y_offset = (obj.GetPositionY() - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL;
const float x_val = floor(x_offset + CENTER_GRID_CELL_ID + 0.5f);
const float y_val = floor(y_offset + CENTER_GRID_CELL_ID + 0.5f);
const float x_off = (x_offset - x_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL;
const float y_off = (y_offset - y_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL;
const float tmp_diff = radius - CENTER_GRID_CELL_OFFSET;
//lets calculate upper/lower/right/left corners for cell search
int right = CellHelper(tmp_diff + x_off);
int left = CellHelper(tmp_diff - x_off);
int upper = CellHelper(tmp_diff + y_off);
int lower = CellHelper(tmp_diff - y_off);
return CellArea(right, left, upper, lower);
}
template<class LOCK_TYPE, class T, class CONTAINER>
inline void
Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const
@@ -224,7 +199,6 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
const CellPair &standing_cell = l.i_cellPair;
if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
return;
//no jokes here... Actually placing ASSERT() here was good idea, but
//we had some problems with DynamicObjects, which pass radius = 0.0f (DB issue?)
//maybe it is better to just return when radius <= 0.0f?
@@ -236,7 +210,6 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
//lets limit the upper value for search radius
if(radius > 333.0f)
radius = 333.0f;
//lets calculate object coord offsets from cell borders.
CellArea area = Cell::CalculateCellArea(obj, radius);
//if radius fits inside standing cell
@@ -245,10 +218,8 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
m.Visit(l, visitor);
return;
}
CellPair begin_cell = standing_cell;
CellPair end_cell = standing_cell;
area.ResizeBorders(begin_cell, end_cell);
//visit all cells, found in CalculateCellArea()
//if radius is known to reach cell area more than 4x4 then we should call optimized VisitCircle
@@ -259,11 +230,9 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
VisitCircle(l, visitor, m, begin_cell, end_cell);
return;
}
//ALWAYS visit standing cell first!!! Since we deal with small radiuses
//it is very essential to call visitor for standing cell firstly...
m.Visit(l, visitor);
// loop the cell range
for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++)
{
@@ -281,7 +250,6 @@ Cell::Visit(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &vi
}
}
}
template<class LOCK_TYPE, class T, class CONTAINER>
inline void
Cell::VisitCircle(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const CellPair& begin_cell, const CellPair& end_cell) const
@@ -291,7 +259,6 @@ Cell::VisitCircle(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINE
//lets calculate x_start/x_end coords for central strip...
const uint32 x_start = begin_cell.x_coord + x_shift;
const uint32 x_end = end_cell.x_coord - x_shift;
//visit central strip with constant width...
for(uint32 x = x_start; x <= x_end; ++x)
{
@@ -304,12 +271,10 @@ Cell::VisitCircle(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINE
m.Visit(lock, visitor);
}
}
//if x_shift == 0 then we have too small cell area, which were already
//visited at previous step, so just return from procedure...
if(x_shift == 0)
return;
uint32 y_start = end_cell.y_coord;
uint32 y_end = begin_cell.y_coord;
//now we are visiting borders of an octagon...
@@ -327,7 +292,6 @@ Cell::VisitCircle(const CellLock<LOCK_TYPE> &l, TypeContainerVisitor<T, CONTAINE
r_zone_left.data.Part.nocreate = l->data.Part.nocreate;
CellLock<LOCK_TYPE> lock_left(r_zone_left, cell_pair_left);
m.Visit(lock_left, visitor);
//right trapezoid cell visit
CellPair cell_pair_right(x_end + step, y);
Cell r_zone_right(cell_pair_right);
+9 -146
View File
@@ -17,12 +17,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Channel.h"
#include "ObjectMgr.h"
#include "SocialMgr.h"
#include "World.h"
Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team)
: m_name(name), m_announce(true), m_moderate(false), m_channelId(channel_id), m_ownerGUID(0), m_password(""), m_flags(0)
{
@@ -33,20 +31,16 @@ Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team)
{
channel_id = ch->ChannelID; // built-in channel
m_announce = false; // no join/leave announces
m_flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels
if(ch->flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel
m_flags |= CHANNEL_FLAG_TRADE;
if(ch->flags & CHANNEL_DBC_FLAG_CITY_ONLY2) // for city only channels
m_flags |= CHANNEL_FLAG_CITY;
if(ch->flags & CHANNEL_DBC_FLAG_LFG) // for LFG channel
m_flags |= CHANNEL_FLAG_LFG;
else // for all other channels
m_flags |= CHANNEL_FLAG_NOT_LFG;
m_IsSaved = false;
m_IsSaved = false;
}
else // it's custom channel
{
@@ -62,9 +56,7 @@ Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team)
m_moderate = fields[3].GetBool();
m_password = fields[4].GetString();
const char* db_BannedList = fields[5].GetString();
m_IsSaved = true;
if(db_BannedList)
{
Tokens tokens = StrSplit(db_BannedList, " ");
@@ -87,11 +79,10 @@ Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team)
{
sLog.outDebug("New Channel(%s) saved", name.c_str());
m_IsSaved = true;
}
}
}
}
}
void Channel::Join(uint64 p, const char *pass)
{
WorldPacket data;
@@ -104,23 +95,19 @@ void Channel::Join(uint64 p, const char *pass)
}
return;
}
if(IsBanned(p))
{
MakeBanned(&data);
SendToOne(&data, p);
return;
}
if(m_password.length() > 0 && strcmp(pass, m_password.c_str()))
{
MakeWrongPassword(&data);
SendToOne(&data, p);
return;
}
Player *plr = objmgr.GetPlayer(p);
if(plr)
{
if(HasFlag(CHANNEL_FLAG_LFG) &&
@@ -131,36 +118,28 @@ void Channel::Join(uint64 p, const char *pass)
SendToOne(&data, p);
return;
}
if(plr->GetGuildId() && (GetFlags() == 0x38))
return;
plr->JoinedChannel(this);
}
if(m_announce && (!plr || plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || !sWorld.getConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) ))
{
MakeJoined(&data, p);
SendToAll(&data);
}
data.clear();
PlayerInfo pinfo;
pinfo.player = p;
pinfo.flags = MEMBER_FLAG_NONE;
players[p] = pinfo;
MakeYouJoined(&data);
SendToOne(&data, p);
JoinNotify(p);
// if no owner first logged will become
if(!IsConstant() && !m_ownerGUID)
{
SetOwner(p, (players.size() > 1 ? true : false));
players[p].SetModerator(true);
players[p].SetModerator(true);
}
/*
else if(!IsConstant() && m_ownerGUID && plr && m_ownerGUID == plr->GetGUID() ))
@@ -169,7 +148,6 @@ void Channel::Join(uint64 p, const char *pass)
players[p].SetModerator(true);
}*/
}
void Channel::Leave(uint64 p, bool send)
{
if(!IsOn(p))
@@ -184,7 +162,6 @@ void Channel::Leave(uint64 p, bool send)
else
{
Player *plr = objmgr.GetPlayer(p);
if(send)
{
WorldPacket data;
@@ -194,9 +171,7 @@ void Channel::Leave(uint64 p, bool send)
plr->LeftChannel(this);
data.clear();
}
bool changeowner = players[p].IsOwner();
players.erase(p);
if(m_announce && (!plr || plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || !sWorld.getConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) ))
{
@@ -204,9 +179,7 @@ void Channel::Leave(uint64 p, bool send)
MakeLeft(&data, p);
SendToAll(&data);
}
LeaveNotify(p);
if(changeowner)
{
uint64 newowner = !players.empty() ? players.begin()->second.player : 0;
@@ -215,14 +188,12 @@ void Channel::Leave(uint64 p, bool send)
}
}
}
void Channel::KickOrBan(uint64 good, const char *badname, bool ban)
{
AccountTypes sec = SEC_PLAYER;
Player *gplr = objmgr.GetPlayer(good);
if(gplr)
sec = gplr->GetSession()->GetSecurity();
if(!IsOn(good))
{
WorldPacket data;
@@ -253,9 +224,7 @@ void Channel::KickOrBan(uint64 good, const char *badname, bool ban)
else
{
bool changeowner = (m_ownerGUID == bad->GetGUID());
WorldPacket data;
if(ban && !IsBanned(bad->GetGUID()))
{
banned.insert(bad->GetGUID());
@@ -274,17 +243,14 @@ void Channel::KickOrBan(uint64 good, const char *badname, bool ban)
if(CharacterDatabase.PExecute( ss.str( ).c_str( ) ))
{
sLog.outDebug("Channel(%s) BannedList saved", m_name.c_str());
}
}
}
}
else
MakePlayerKicked(&data, bad->GetGUID(), good);
SendToAll(&data);
players.erase(bad->GetGUID());
bad->LeftChannel(this);
if(changeowner)
{
uint64 newowner = !players.empty() ? good : false;
@@ -294,14 +260,12 @@ void Channel::KickOrBan(uint64 good, const char *badname, bool ban)
}
}
}
void Channel::UnBan(uint64 good, const char *badname)
{
uint32 sec = 0;
Player *gplr = objmgr.GetPlayer(good);
if(gplr)
sec = gplr->GetSession()->GetSecurity();
if(!IsOn(good))
{
WorldPacket data;
@@ -326,7 +290,6 @@ void Channel::UnBan(uint64 good, const char *badname)
else
{
banned.erase(bad->GetGUID());
WorldPacket data;
MakePlayerUnbanned(&data, bad->GetGUID(), good);
SendToAll(&data);
@@ -344,19 +307,17 @@ void Channel::UnBan(uint64 good, const char *badname)
if(CharacterDatabase.PExecute( ss.str( ).c_str( ) ))
{
sLog.outDebug("Channel(%s) BannedList saved", m_name.c_str());
}
}
}
}
}
}
void Channel::Password(uint64 p, const char *pass)
{
uint32 sec = 0;
Player *plr = objmgr.GetPlayer(p);
if(plr)
sec = plr->GetSession()->GetSecurity();
if(!IsOn(p))
{
WorldPacket data;
@@ -372,7 +333,6 @@ void Channel::Password(uint64 p, const char *pass)
else
{
m_password = pass;
WorldPacket data;
MakePasswordChanged(&data, p);
SendToAll(&data);
@@ -383,19 +343,16 @@ void Channel::Password(uint64 p, const char *pass)
if(CharacterDatabase.PExecute( ss.str( ).c_str( ) ))
{
sLog.outDebug("Channel(%s) password saved", m_name.c_str());
}
}
}
}
}
void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set)
{
Player *plr = objmgr.GetPlayer(p);
if (!plr)
return;
uint32 sec = plr->GetSession()->GetSecurity();
if(!IsOn(p))
{
WorldPacket data;
@@ -418,11 +375,9 @@ void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set)
SendToOne(&data, p);
return;
}
PlayerInfo inf = players[newp->GetGUID()];
if(p == m_ownerGUID && newp->GetGUID() == m_ownerGUID && mod)
return;
if(!IsOn(newp->GetGUID()))
{
WorldPacket data;
@@ -430,7 +385,6 @@ void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set)
SendToOne(&data, p);
return;
}
// allow make moderator from another team only if both is GMs
// at this moment this only way to show channel post for GM from another team
if( (plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || newp->GetSession()->GetSecurity() < SEC_GAMEMASTER) &&
@@ -441,7 +395,6 @@ void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set)
SendToOne(&data, p);
return;
}
if(m_ownerGUID == newp->GetGUID() && m_ownerGUID != p)
{
WorldPacket data;
@@ -449,22 +402,18 @@ void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set)
SendToOne(&data, p);
return;
}
if(mod)
SetModerator(newp->GetGUID(), set);
else
SetMute(newp->GetGUID(), set);
}
}
void Channel::SetOwner(uint64 p, const char *newname)
{
Player *plr = objmgr.GetPlayer(p);
if (!plr)
return;
uint32 sec = plr->GetSession()->GetSecurity();
if(!IsOn(p))
{
WorldPacket data;
@@ -472,7 +421,6 @@ void Channel::SetOwner(uint64 p, const char *newname)
SendToOne(&data, p);
return;
}
if(sec < SEC_GAMEMASTER && p != m_ownerGUID)
{
WorldPacket data;
@@ -480,7 +428,6 @@ void Channel::SetOwner(uint64 p, const char *newname)
SendToOne(&data, p);
return;
}
Player *newp = objmgr.GetPlayer(newname);
if(newp == NULL || !IsOn(newp->GetGUID()))
{
@@ -489,7 +436,6 @@ void Channel::SetOwner(uint64 p, const char *newname)
SendToOne(&data, p);
return;
}
if(newp->GetTeam() != plr->GetTeam() && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
{
WorldPacket data;
@@ -497,11 +443,9 @@ void Channel::SetOwner(uint64 p, const char *newname)
SendToOne(&data, p);
return;
}
players[newp->GetGUID()].SetModerator(true);
SetOwner(newp->GetGUID());
}
void Channel::SendWhoOwner(uint64 p)
{
if(!IsOn(p))
@@ -517,11 +461,9 @@ void Channel::SendWhoOwner(uint64 p)
SendToOne(&data, p);
}
}
void Channel::List(Player* player)
{
uint64 p = player->GetGUID();
if(!IsOn(p))
{
WorldPacket data;
@@ -534,17 +476,13 @@ void Channel::List(Player* player)
data << uint8(1); // channel type?
data << GetName(); // channel name
data << uint8(GetFlags()); // channel flags?
size_t pos = data.wpos();
data << uint32(0); // size of list, placeholder
uint32 gmLevelInWhoList = sWorld.getConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
uint32 count = 0;
for(PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
{
Player *plr = objmgr.GetPlayer(i->first);
// PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
if (plr && (player->GetSession()->GetSecurity() > SEC_PLAYER || plr->GetSession()->GetSecurity() <= gmLevelInWhoList) &&
@@ -555,20 +493,16 @@ void Channel::List(Player* player)
++count;
}
}
data.put<uint32>(pos,count);
SendToOne(&data, p);
}
}
void Channel::Announce(uint64 p)
{
uint32 sec = 0;
Player *plr = objmgr.GetPlayer(p);
if(plr)
sec = plr->GetSession()->GetSecurity();
if(!IsOn(p))
{
WorldPacket data;
@@ -584,7 +518,6 @@ void Channel::Announce(uint64 p)
else
{
m_announce = !m_announce;
WorldPacket data;
if(m_announce)
MakeAnnouncementsOn(&data, p);
@@ -598,19 +531,16 @@ void Channel::Announce(uint64 p)
if(CharacterDatabase.PExecute( ss.str( ).c_str( ) ))
{
sLog.outDebug("Channel(%s) announce saved", m_name.c_str());
}
}
}
}
}
void Channel::Moderate(uint64 p)
{
uint32 sec = 0;
Player *plr = objmgr.GetPlayer(p);
if(plr)
sec = plr->GetSession()->GetSecurity();
if(!IsOn(p))
{
WorldPacket data;
@@ -626,7 +556,6 @@ void Channel::Moderate(uint64 p)
else
{
m_moderate = !m_moderate;
WorldPacket data;
if(m_moderate)
MakeModerationOn(&data, p);
@@ -640,23 +569,20 @@ void Channel::Moderate(uint64 p)
if(CharacterDatabase.PExecute( ss.str( ).c_str( ) ))
{
sLog.outDebug("Channel(%s) moderate saved", m_name.c_str());
}
}
}
}
}
void Channel::Say(uint64 p, const char *what, uint32 lang)
{
if(!what)
return;
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
lang = LANG_UNIVERSAL;
uint32 sec = 0;
Player *plr = objmgr.GetPlayer(p);
if(plr)
sec = plr->GetSession()->GetSecurity();
if(!IsOn(p))
{
WorldPacket data;
@@ -678,7 +604,6 @@ void Channel::Say(uint64 p, const char *what, uint32 lang)
else
{
uint32 messageLength = strlen(what) + 1;
WorldPacket data(SMSG_MESSAGECHAT, 1+4+8+4+m_name.size()+1+8+4+messageLength+1);
data << (uint8)CHAT_MSG_CHANNEL;
data << (uint32)lang;
@@ -689,11 +614,9 @@ void Channel::Say(uint64 p, const char *what, uint32 lang)
data << messageLength;
data << what;
data << uint8(plr ? plr->chatTag() : 0);
SendToAll(&data, !players[p].IsModerator() ? p : false);
}
}
void Channel::Invite(uint64 p, const char *newname)
{
if(!IsOn(p))
@@ -703,7 +626,6 @@ void Channel::Invite(uint64 p, const char *newname)
SendToOne(&data, p);
return;
}
Player *newp = objmgr.GetPlayer(newname);
if(!newp)
{
@@ -712,11 +634,9 @@ void Channel::Invite(uint64 p, const char *newname)
SendToOne(&data, p);
return;
}
Player *plr = objmgr.GetPlayer(p);
if (!plr)
return;
if (newp->GetTeam() != plr->GetTeam() && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
{
WorldPacket data;
@@ -724,7 +644,6 @@ void Channel::Invite(uint64 p, const char *newname)
SendToOne(&data, p);
return;
}
if(IsOn(newp->GetGUID()))
{
WorldPacket data;
@@ -732,7 +651,6 @@ void Channel::Invite(uint64 p, const char *newname)
SendToOne(&data, p);
return;
}
WorldPacket data;
if(!newp->GetSocial()->HasIgnore(GUID_LOPART(p)))
{
@@ -743,7 +661,6 @@ void Channel::Invite(uint64 p, const char *newname)
MakePlayerInvited(&data, newp->GetName());
SendToOne(&data, p);
}
void Channel::SetOwner(uint64 guid, bool exclaim)
{
if(m_ownerGUID)
@@ -753,18 +670,15 @@ void Channel::SetOwner(uint64 guid, bool exclaim)
if(p_itr != players.end())
p_itr->second.SetOwner(false);
}
m_ownerGUID = guid;
if(m_ownerGUID)
{
uint8 oldFlag = GetPlayerFlags(m_ownerGUID);
players[m_ownerGUID].SetModerator(true);
players[m_ownerGUID].SetOwner(true);
WorldPacket data;
MakeModeChange(&data, m_ownerGUID, oldFlag);
SendToAll(&data);
if(exclaim)
{
MakeOwnerChanged(&data, m_ownerGUID);
@@ -777,12 +691,10 @@ void Channel::SetOwner(uint64 guid, bool exclaim)
if(CharacterDatabase.PExecute( ss.str( ).c_str( ) ))
{
sLog.outDebug("Channel(%s) owner saved", m_name.c_str());
}
}
}*/
}
}
void Channel::SendToAll(WorldPacket *data, uint64 p)
{
for(PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
@@ -795,7 +707,6 @@ void Channel::SendToAll(WorldPacket *data, uint64 p)
}
}
}
void Channel::SendToAllButOne(WorldPacket *data, uint64 who)
{
for(PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
@@ -808,24 +719,18 @@ void Channel::SendToAllButOne(WorldPacket *data, uint64 who)
}
}
}
void Channel::SendToOne(WorldPacket *data, uint64 who)
{
Player *plr = objmgr.GetPlayer(who);
if(plr)
plr->GetSession()->SendPacket(data);
}
void Channel::Voice(uint64 /*guid1*/, uint64 /*guid2*/)
{
}
void Channel::DeVoice(uint64 /*guid1*/, uint64 /*guid2*/)
{
}
// done
void Channel::MakeNotifyPacket(WorldPacket *data, uint8 notify_type)
{
@@ -833,21 +738,18 @@ void Channel::MakeNotifyPacket(WorldPacket *data, uint8 notify_type)
*data << uint8(notify_type);
*data << m_name;
}
// done 0x00
void Channel::MakeJoined(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_JOINED_NOTICE);
*data << uint64(guid);
}
// done 0x01
void Channel::MakeLeft(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_LEFT_NOTICE);
*data << uint64(guid);
}
// done 0x02
void Channel::MakeYouJoined(WorldPacket *data)
{
@@ -856,7 +758,6 @@ void Channel::MakeYouJoined(WorldPacket *data)
*data << uint32(GetChannelId());
*data << uint32(0);
}
// done 0x03
void Channel::MakeYouLeft(WorldPacket *data)
{
@@ -864,64 +765,53 @@ void Channel::MakeYouLeft(WorldPacket *data)
*data << uint32(GetChannelId());
*data << uint8(0); // can be 0x00 and 0x01
}
// done 0x04
void Channel::MakeWrongPassword(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_WRONG_PASSWORD_NOTICE);
}
// done 0x05
void Channel::MakeNotMember(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_NOT_MEMBER_NOTICE);
}
// done 0x06
void Channel::MakeNotModerator(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_NOT_MODERATOR_NOTICE);
}
// done 0x07
void Channel::MakePasswordChanged(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_PASSWORD_CHANGED_NOTICE);
*data << uint64(guid);
}
// done 0x08
void Channel::MakeOwnerChanged(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_OWNER_CHANGED_NOTICE);
*data << uint64(guid);
}
// done 0x09
void Channel::MakePlayerNotFound(WorldPacket *data, const std::string& name)
{
MakeNotifyPacket(data, CHAT_PLAYER_NOT_FOUND_NOTICE);
*data << name;
}
// done 0x0A
void Channel::MakeNotOwner(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_NOT_OWNER_NOTICE);
}
// done 0x0B
void Channel::MakeChannelOwner(WorldPacket *data)
{
std::string name = "";
if(!objmgr.GetPlayerNameByGUID(m_ownerGUID, name) || name.empty())
name = "PLAYER_NOT_FOUND";
MakeNotifyPacket(data, CHAT_CHANNEL_OWNER_NOTICE);
*data << ((IsConstant() || !m_ownerGUID) ? "Nobody" : name);
}
// done 0x0C
void Channel::MakeModeChange(WorldPacket *data, uint64 guid, uint8 oldflags)
{
@@ -930,41 +820,35 @@ void Channel::MakeModeChange(WorldPacket *data, uint64 guid, uint8 oldflags)
*data << uint8(oldflags);
*data << uint8(GetPlayerFlags(guid));
}
// done 0x0D
void Channel::MakeAnnouncementsOn(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_ON_NOTICE);
*data << uint64(guid);
}
// done 0x0E
void Channel::MakeAnnouncementsOff(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_OFF_NOTICE);
*data << uint64(guid);
}
// done 0x0F
void Channel::MakeModerationOn(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_MODERATION_ON_NOTICE);
*data << uint64(guid);
}
// done 0x10
void Channel::MakeModerationOff(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_MODERATION_OFF_NOTICE);
*data << uint64(guid);
}
// done 0x11
void Channel::MakeMuted(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_MUTED_NOTICE);
}
// done 0x12
void Channel::MakePlayerKicked(WorldPacket *data, uint64 bad, uint64 good)
{
@@ -972,13 +856,11 @@ void Channel::MakePlayerKicked(WorldPacket *data, uint64 bad, uint64 good)
*data << uint64(bad);
*data << uint64(good);
}
// done 0x13
void Channel::MakeBanned(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_BANNED_NOTICE);
}
// done 0x14
void Channel::MakePlayerBanned(WorldPacket *data, uint64 bad, uint64 good)
{
@@ -986,7 +868,6 @@ void Channel::MakePlayerBanned(WorldPacket *data, uint64 bad, uint64 good)
*data << uint64(bad);
*data << uint64(good);
}
// done 0x15
void Channel::MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good)
{
@@ -994,107 +875,90 @@ void Channel::MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good)
*data << uint64(bad);
*data << uint64(good);
}
// done 0x16
void Channel::MakePlayerNotBanned(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_PLAYER_NOT_BANNED_NOTICE);
*data << uint64(guid);
}
// done 0x17
void Channel::MakePlayerAlreadyMember(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_PLAYER_ALREADY_MEMBER_NOTICE);
*data << uint64(guid);
}
// done 0x18
void Channel::MakeInvite(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_INVITE_NOTICE);
*data << uint64(guid);
}
// done 0x19
void Channel::MakeInviteWrongFaction(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_INVITE_WRONG_FACTION_NOTICE);
}
// done 0x1A
void Channel::MakeWrongFaction(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_WRONG_FACTION_NOTICE);
}
// done 0x1B
void Channel::MakeInvalidName(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_INVALID_NAME_NOTICE);
}
// done 0x1C
void Channel::MakeNotModerated(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_NOT_MODERATED_NOTICE);
}
// done 0x1D
void Channel::MakePlayerInvited(WorldPacket *data, const std::string& name)
{
MakeNotifyPacket(data, CHAT_PLAYER_INVITED_NOTICE);
*data << name;
}
// done 0x1E
void Channel::MakePlayerInviteBanned(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_PLAYER_INVITE_BANNED_NOTICE);
*data << uint64(guid);
}
// done 0x1F
void Channel::MakeThrottled(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_THROTTLED_NOTICE);
}
// done 0x20
void Channel::MakeNotInArea(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_NOT_IN_AREA_NOTICE);
}
// done 0x21
void Channel::MakeNotInLfg(WorldPacket *data)
{
MakeNotifyPacket(data, CHAT_NOT_IN_LFG_NOTICE);
}
// done 0x22
void Channel::MakeVoiceOn(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_VOICE_ON_NOTICE);
*data << uint64(guid);
}
// done 0x23
void Channel::MakeVoiceOff(WorldPacket *data, uint64 guid)
{
MakeNotifyPacket(data, CHAT_VOICE_OFF_NOTICE);
*data << uint64(guid);
}
void Channel::JoinNotify(uint64 guid)
{
WorldPacket data;
if(IsConstant())
data.Initialize(SMSG_USERLIST_ADD, 8+1+1+4+GetName().size()+1);
else
data.Initialize(SMSG_USERLIST_UPDATE, 8+1+1+4+GetName().size()+1);
data << uint64(guid);
data << uint8(GetPlayerFlags(guid));
data << uint8(GetFlags());
@@ -1102,7 +966,6 @@ void Channel::JoinNotify(uint64 guid)
data << GetName();
SendToAll(&data);
}
void Channel::LeaveNotify(uint64 guid)
{
WorldPacket data(SMSG_USERLIST_REMOVE, 8+1+4+GetName().size()+1);
-22
View File
@@ -17,20 +17,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _CHANNEL_H
#define _CHANNEL_H
#include <list>
#include <map>
#include <string>
#include "Common.h"
#include "Opcodes.h"
#include "Player.h"
#include "WorldPacket.h"
enum ChatNotify
{
CHAT_JOINED_NOTICE = 0x00, //+ "%s joined channel.";
@@ -72,7 +67,6 @@ enum ChatNotify
CHAT_VOICE_ON_NOTICE = 0x22, //+ "[%s] Channel voice enabled by %s.";
CHAT_VOICE_OFF_NOTICE = 0x23, //+ "[%s] Channel voice disabled by %s.";
};
enum ChannelFlags
{
CHANNEL_FLAG_NONE = 0x00,
@@ -90,7 +84,6 @@ enum ChannelFlags
// GuildRecruitment 0x38 = 0x20 | 0x10 | 0x08
// LookingForGroup 0x50 = 0x40 | 0x10
};
enum ChannelDBCFlags
{
CHANNEL_DBC_FLAG_NONE = 0x00000,
@@ -104,7 +97,6 @@ enum ChannelDBCFlags
CHANNEL_DBC_FLAG_GUILD_REQ = 0x20000, // GuildRecruitment
CHANNEL_DBC_FLAG_LFG = 0x40000 // LookingForGroup
};
enum ChannelMemberFlags
{
MEMBER_FLAG_NONE = 0x00,
@@ -117,14 +109,12 @@ enum ChannelMemberFlags
// 0x40
// 0x80
};
class Channel
{
struct PlayerInfo
{
uint64 player;
uint8 flags;
bool HasFlag(uint8 flag) { return flags & flag; }
void SetFlag(uint8 flag) { if(!HasFlag(flag)) flags |= flag; }
bool IsOwner() { return flags & MEMBER_FLAG_OWNER; }
@@ -146,7 +136,6 @@ class Channel
else flags &= ~MEMBER_FLAG_MUTED;
}
};
typedef std::map<uint64, PlayerInfo> PlayerList;
PlayerList players;
typedef std::set<uint64> BannedList;
@@ -159,7 +148,6 @@ class Channel
uint32 m_channelId;
uint64 m_ownerGUID;
bool m_IsSaved;
private:
// initial packet data (notify type and channel name)
void MakeNotifyPacket(WorldPacket *data, uint8 notify_type);
@@ -200,49 +188,40 @@ class Channel
void MakeNotInLfg(WorldPacket *data); //? 0x21
void MakeVoiceOn(WorldPacket *data, uint64 guid); //+ 0x22
void MakeVoiceOff(WorldPacket *data, uint64 guid); //+ 0x23
void SendToAll(WorldPacket *data, uint64 p = 0);
void SendToAllButOne(WorldPacket *data, uint64 who);
void SendToOne(WorldPacket *data, uint64 who);
bool IsOn(uint64 who) const { return players.find(who) != players.end(); }
bool IsBanned(uint64 guid) const { return banned.find(guid) != banned.end(); }
uint8 GetPlayerFlags(uint64 p) const
{
PlayerList::const_iterator p_itr = players.find(p);
if(p_itr == players.end())
return 0;
return p_itr->second.flags;
}
void SetModerator(uint64 p, bool set)
{
if(players[p].IsModerator() != set)
{
uint8 oldFlag = GetPlayerFlags(p);
players[p].SetModerator(set);
WorldPacket data;
MakeModeChange(&data, p, oldFlag);
SendToAll(&data);
}
}
void SetMute(uint64 p, bool set)
{
if(players[p].IsMuted() != set)
{
uint8 oldFlag = GetPlayerFlags(p);
players[p].SetMuted(set);
WorldPacket data;
MakeModeChange(&data, p, oldFlag);
SendToAll(&data);
}
}
public:
uint32 m_Team;
Channel(const std::string& name, uint32 channel_id, uint32 Team = 0);
@@ -257,7 +236,6 @@ class Channel
uint32 GetNumPlayers() const { return players.size(); }
uint8 GetFlags() const { return m_flags; }
bool HasFlag(uint8 flag) { return m_flags & flag; }
void Join(uint64 p, const char *pass);
void Leave(uint64 p, bool send = true);
void KickOrBan(uint64 good, const char *badname, bool ban);
-59
View File
@@ -18,26 +18,19 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Policies/SingletonImp.h"
#include "ObjectMgr.h" // for normalizePlayerName
#include "ChannelMgr.h"
void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
uint32 channel_id;
uint8 unknown1, unknown2;
std::string channelname, pass;
recvPacket >> channel_id >> unknown1 >> unknown2;
recvPacket >> channelname;
if(channelname.empty())
return;
recvPacket >> pass;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
{
@@ -46,20 +39,16 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
chn->Join(_player->GetGUID(), pass.c_str());
}
}
void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
uint32 unk;
std::string channelname;
recvPacket >> unk; // channel id?
recvPacket >> channelname;
if(channelname.empty())
return;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
{
if(Channel *chn = cMgr->GetChannel(channelname, _player))
@@ -67,50 +56,40 @@ void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket)
cMgr->LeftChannel(channelname);
}
}
void WorldSession::HandleChannelList(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname;
recvPacket >> channelname;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->List(_player);
}
void WorldSession::HandleChannelPassword(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname, pass;
recvPacket >> channelname;
recvPacket >> pass;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->Password(_player->GetGUID(), pass.c_str());
}
void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname, newp;
recvPacket >> channelname;
recvPacket >> newp;
if(!normalizePlayerName(newp))
return;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->SetOwner(_player->GetGUID(), newp.c_str());
}
void WorldSession::HandleChannelOwner(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
@@ -121,144 +100,110 @@ void WorldSession::HandleChannelOwner(WorldPacket& recvPacket)
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->SendWhoOwner(_player->GetGUID());
}
void WorldSession::HandleChannelModerator(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname, otp;
recvPacket >> channelname;
recvPacket >> otp;
if(!normalizePlayerName(otp))
return;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->SetModerator(_player->GetGUID(), otp.c_str());
}
void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname, otp;
recvPacket >> channelname;
recvPacket >> otp;
if(!normalizePlayerName(otp))
return;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->UnsetModerator(_player->GetGUID(), otp.c_str());
}
void WorldSession::HandleChannelMute(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname, otp;
recvPacket >> channelname;
recvPacket >> otp;
if(!normalizePlayerName(otp))
return;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->SetMute(_player->GetGUID(), otp.c_str());
}
void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname, otp;
recvPacket >> channelname;
recvPacket >> otp;
if(!normalizePlayerName(otp))
return;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->UnsetMute(_player->GetGUID(), otp.c_str());
}
void WorldSession::HandleChannelInvite(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname, otp;
recvPacket >> channelname;
recvPacket >> otp;
if(!normalizePlayerName(otp))
return;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->Invite(_player->GetGUID(), otp.c_str());
}
void WorldSession::HandleChannelKick(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname, otp;
recvPacket >> channelname;
recvPacket >> otp;
if(!normalizePlayerName(otp))
return;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->Kick(_player->GetGUID(), otp.c_str());
}
void WorldSession::HandleChannelBan(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname, otp;
recvPacket >> channelname;
recvPacket >> otp;
if(!normalizePlayerName(otp))
return;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->Ban(_player->GetGUID(), otp.c_str());
}
void WorldSession::HandleChannelUnban(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
//recvPacket.hexlike();
std::string channelname, otp;
recvPacket >> channelname;
recvPacket >> otp;
if(!normalizePlayerName(otp))
return;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->UnBan(_player->GetGUID(), otp.c_str());
}
void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
@@ -269,7 +214,6 @@ void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket)
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->Announce(_player->GetGUID());
}
void WorldSession::HandleChannelModerate(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
@@ -280,7 +224,6 @@ void WorldSession::HandleChannelModerate(WorldPacket& recvPacket)
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->Moderate(_player->GetGUID());
}
void WorldSession::HandleChannelDisplayListQuery(WorldPacket &recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
@@ -291,7 +234,6 @@ void WorldSession::HandleChannelDisplayListQuery(WorldPacket &recvPacket)
if(Channel *chn = cMgr->GetChannel(channelname, _player))
chn->List(_player);
}
void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
@@ -310,7 +252,6 @@ void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket)
}
}
}
void WorldSession::HandleSetChannelWatch(WorldPacket &recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
-17
View File
@@ -15,35 +15,27 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ChannelMgr.h"
#include "Policies/SingletonImp.h"
#include "World.h"
INSTANTIATE_SINGLETON_1( AllianceChannelMgr );
INSTANTIATE_SINGLETON_1( HordeChannelMgr );
ChannelMgr* channelMgr(uint32 team)
{
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
return &MaNGOS::Singleton<AllianceChannelMgr>::Instance(); // cross-faction
if(team == ALLIANCE)
return &MaNGOS::Singleton<AllianceChannelMgr>::Instance();
if(team == HORDE)
return &MaNGOS::Singleton<HordeChannelMgr>::Instance();
return NULL;
}
ChannelMgr::~ChannelMgr()
{
for(ChannelMap::iterator itr = channels.begin();itr!=channels.end(); ++itr)
delete itr->second;
channels.clear();
}
Channel *ChannelMgr::GetJoinChannel(std::string name, uint32 channel_id)
{
if (channels.find(name) == channels.end())
@@ -51,14 +43,11 @@ Channel *ChannelMgr::GetJoinChannel(std::string name, uint32 channel_id)
Channel *nchan = new Channel(name,channel_id, team);
channels[name] = nchan;
}
return channels[name];
}
Channel *ChannelMgr::GetChannel(std::string name, Player *p, bool pkt)
{
ChannelMap::const_iterator i = channels.find(name);
if(i == channels.end())
{
if(pkt)
@@ -67,29 +56,23 @@ Channel *ChannelMgr::GetChannel(std::string name, Player *p, bool pkt)
MakeNotOnPacket(&data,name);
p->GetSession()->SendPacket(&data);
}
return NULL;
}
else
return i->second;
}
void ChannelMgr::LeftChannel(std::string name)
{
ChannelMap::const_iterator i = channels.find(name);
if(i == channels.end())
return;
Channel* channel = i->second;
if(channel->GetNumPlayers() == 0 && !channel->IsConstant())
{
channels.erase(name);
delete channel;
}
}
void ChannelMgr::MakeNotOnPacket(WorldPacket *data, std::string name)
{
data->Initialize(SMSG_CHANNEL_NOTIFY, (1+10)); // we guess size
-9
View File
@@ -19,19 +19,14 @@
*/
#ifndef MANGOSSERVER_CHANNELMGR_H
#define MANGOSSERVER_CHANNELMGR_H
#include "Common.h"
#include "Channel.h"
#include "Policies/Singleton.h"
#include <map>
#include <string>
#include "Policies/Singleton.h"
#include "Channel.h"
#include "World.h"
class ChannelMgr
{
public:
@@ -39,7 +34,6 @@ class ChannelMgr
typedef std::map<std::string,Channel *> ChannelMap;
ChannelMgr() {team = 0;}
~ChannelMgr();
Channel *GetJoinChannel(std::string name, uint32 channel_id);
Channel *GetChannel(std::string name, Player *p, bool pkt = true);
void LeftChannel(std::string name);
@@ -47,11 +41,8 @@ class ChannelMgr
ChannelMap channels;
void MakeNotOnPacket(WorldPacket *data, std::string name);
};
class AllianceChannelMgr : public ChannelMgr {};
class HordeChannelMgr : public ChannelMgr {};
ChannelMgr* channelMgr(uint32 team);
#endif
File diff suppressed because it is too large Load Diff
+1 -311
View File
File diff suppressed because it is too large Load Diff
-83
View File
@@ -17,19 +17,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_CHAT_H
#define TRINITYCORE_CHAT_H
#include "SharedDefines.h"
class ChatHandler;
class WorldSession;
class Creature;
class Player;
class Unit;
struct GameTele;
class ChatCommand
{
public:
@@ -40,66 +36,50 @@ class ChatCommand
std::string Help;
ChatCommand * ChildCommands;
};
class TRINITY_DLL_SPEC ChatHandler
{
public:
explicit ChatHandler(WorldSession* session) : m_session(session) {}
explicit ChatHandler(Player* player) : m_session(player->GetSession()) {}
~ChatHandler() {}
static void FillMessageData( WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker);
void FillMessageData( WorldPacket *data, uint8 type, uint32 language, uint64 target_guid, const char* message)
{
FillMessageData( data, m_session, type, language, NULL, target_guid, message, NULL);
}
void FillSystemMessageData( WorldPacket *data, const char* message )
{
FillMessageData( data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, 0, message );
}
static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; }
// function with different implementation for chat/console
virtual const char *GetMangosString(int32 entry) const;
virtual void SendSysMessage( const char *str);
void SendSysMessage( int32 entry);
void PSendSysMessage( const char *format, ...) ATTR_PRINTF(2,3);
void PSendSysMessage( int32 entry, ... );
std::string PGetParseString(int32 entry, ...);
int ParseCommands(const char* text);
static ChatCommand* getCommandTable();
bool isValidChatMessage(const char* msg);
void SendGlobalSysMessage(const char *str);
protected:
explicit ChatHandler() : m_session(NULL) {} // for CLI subclass
bool hasStringAbbr(const char* name, const char* part);
// function with different implementation for chat/console
virtual bool isAvailable(ChatCommand const& cmd) const;
virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
virtual bool needReportToTarget(Player* chr) const;
virtual LocaleConstant GetSessionDbcLocale() const;
virtual int GetSessionDbLocaleIndex() const;
bool HasLowerSecurity(Player* target, uint64 guid, bool strong = false);
bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false);
void SendGlobalGMSysMessage(const char *str);
static bool SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand );
bool ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcommand);
bool ShowHelpForCommand(ChatCommand *table, const char* cmd);
bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);
bool HandleAccountCommand(const char* args);
bool HandleAccountAddonCommand(const char* args);
bool HandleAccountCreateCommand(const char* args);
@@ -110,13 +90,11 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleAccountSetAddonCommand(const char* args);
bool HandleAccountSetGmLevelCommand(const char* args);
bool HandleAccountSetPasswordCommand(const char* args);
bool HandleAHBotOptionsCommand(const char * args);
bool HandleNameAnnounceCommand(const char* args);
bool HandleGMNameAnnounceCommand(const char* args);
bool HandleGMAnnounceCommand(const char* args);
bool HandleGMNotifyCommand(const char* args);
bool HandleBanAccountCommand(const char* args);
bool HandleBanCharacterCommand(const char* args);
bool HandleBanIPCommand(const char* args);
@@ -126,19 +104,16 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleBanListAccountCommand(const char* args);
bool HandleBanListCharacterCommand(const char* args);
bool HandleBanListIPCommand(const char* args);
bool HandleCastCommand(const char *args);
bool HandleCastBackCommand(const char *args);
bool HandleCastDistCommand(const char *args);
bool HandleCastSelfCommand(const char *args);
bool HandleCastTargetCommand(const char *args);
bool HandleCharacterCustomizeCommand(const char * args);
bool HandleCharacterDeleteCommand(const char* args);
bool HandleCharacterLevelCommand(const char* args);
bool HandleCharacterRenameCommand(const char * args);
bool HandleCharacterReputationCommand(const char* args);
bool HandleDebugAnimCommand(const char* args);
bool HandleDebugArenaCommand(const char * args);
bool HandleDebugBattlegroundCommand(const char * args);
@@ -156,7 +131,6 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleDebugSpellCheckCommand(const char* args);
bool HandleDebugUpdateCommand(const char* args);
bool HandleDebugUpdateWorldStateCommand(const char* args);
bool HandleDebugSet32Bit(const char* args);
bool HandleDebugThreatList(const char * args);
bool HandleDebugHostilRefList(const char * args);
@@ -164,11 +138,9 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleUnPossessCommand(const char* args);
bool HandleBindSightCommand(const char* args);
bool HandleUnbindSightCommand(const char* args);
bool HandleDebugPlayCinematicCommand(const char* args);
bool HandleDebugPlayMovieCommand(const char* args);
bool HandleDebugPlaySoundCommand(const char* args);
bool HandleDebugSendBuyErrorCommand(const char* args);
bool HandleDebugSendChannelNotifyCommand(const char* args);
bool HandleDebugSendChatMsgCommand(const char* args);
@@ -181,12 +153,10 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleDebugSendSellErrorCommand(const char* args);
bool HandleDebugSendSetPhaseShiftCommand(const char * args);
bool HandleDebugSendSpellFailCommand(const char* args);
bool HandleEventActiveListCommand(const char* args);
bool HandleEventStartCommand(const char* args);
bool HandleEventStopCommand(const char* args);
bool HandleEventInfoCommand(const char* args);
bool HandleGameObjectAddCommand(const char* args);
bool HandleGameObjectDeleteCommand(const char* args);
bool HandleGameObjectMoveCommand(const char* args);
@@ -195,14 +165,12 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleGameObjectStateCommand(const char* args);
bool HandleGameObjectTargetCommand(const char* args);
bool HandleGameObjectTurnCommand(const char* args);
bool HandleGMCommand(const char* args);
bool HandleGMChatCommand(const char* args);
bool HandleGMFlyCommand(const char* args);
bool HandleGMListFullCommand(const char* args);
bool HandleGMListIngameCommand(const char* args);
bool HandleGMVisibleCommand(const char* args);
bool HandleGoCommand(const char* args);
bool HandleGoCreatureCommand(const char* args);
bool HandleGoGraveyardCommand(const char* args);
@@ -213,24 +181,19 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleGoXYCommand(const char* args);
bool HandleGoXYZCommand(const char* args);
bool HandleGoZoneXYCommand(const char* args);
bool HandleGoTicketCommand(const char* args);
bool HandleGuildCreateCommand(const char* args);
bool HandleGuildInviteCommand(const char* args);
bool HandleGuildUninviteCommand(const char* args);
bool HandleGuildRankCommand(const char* args);
bool HandleGuildDeleteCommand(const char* args);
bool HandleHonorAddCommand(const char* args);
bool HandleHonorAddKillCommand(const char* args);
bool HandleHonorUpdateCommand(const char* args);
bool HandleInstanceListBindsCommand(const char* args);
bool HandleInstanceUnbindCommand(const char* args);
bool HandleInstanceStatsCommand(const char* args);
bool HandleInstanceSaveDataCommand(const char * args);
bool HandleLearnCommand(const char* args);
bool HandleLearnAllCommand(const char* args);
bool HandleLearnAllGMCommand(const char* args);
@@ -242,12 +205,10 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleLearnAllMyPetTalentsCommand(const char* args);
bool HandleLearnAllMySpellsCommand(const char* args);
bool HandleLearnAllMyTalentsCommand(const char* args);
bool HandleListAurasCommand(const char * args);
bool HandleListCreatureCommand(const char* args);
bool HandleListItemCommand(const char* args);
bool HandleListObjectCommand(const char* args);
bool HandleLookupAreaCommand(const char* args);
bool HandleLookupCreatureCommand(const char* args);
bool HandleLookupEventCommand(const char* args);
@@ -264,7 +225,6 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleLookupTaxiNodeCommand(const char * args);
bool HandleLookupTeleCommand(const char * args);
bool HandleLookupMapCommand(const char* args);
bool HandleModifyKnownTitlesCommand(const char* args);
bool HandleModifyHPCommand(const char* args);
bool HandleModifyManaCommand(const char* args);
@@ -288,7 +248,6 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleModifyArenaCommand(const char* args);
bool HandleModifyPhaseCommand(const char* args);
bool HandleModifyGenderCommand(const char* args);
//-----------------------Npc Commands-----------------------
bool HandleNpcAddCommand(const char* args);
bool HandleNpcAddMoveCommand(const char* args);
@@ -318,20 +277,16 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleNpcYellCommand(const char* args);
bool HandleNpcAddFormationCommand(const char* args);
bool HandleNpcSetLinkCommand(const char* args);
//TODO: NpcCommands that needs to be fixed :
bool HandleNpcAddWeaponCommand(const char* args);
bool HandleNpcNameCommand(const char* args);
bool HandleNpcSubNameCommand(const char* args);
//----------------------------------------------------------
bool HandlePDumpLoadCommand(const char *args);
bool HandlePDumpWriteCommand(const char *args);
bool HandleQuestAdd(const char * args);
bool HandleQuestRemove(const char * args);
bool HandleQuestComplete(const char * args);
bool HandleReloadAllCommand(const char* args);
bool HandleReloadAllAchievementCommand(const char* args);
bool HandleReloadAllAreaCommand(const char* args);
@@ -343,9 +298,7 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleReloadAllEventAICommand(const char* args);
bool HandleReloadAllSpellCommand(const char* args);
bool HandleReloadAllLocalesCommand(const char* args);
bool HandleReloadConfigCommand(const char* args);
bool HandleReloadAccessRequirementCommand(const char* args);
bool HandleReloadAchievementCriteriaDataCommand(const char* args);
bool HandleReloadAchievementRewardCommand(const char* args);
@@ -420,7 +373,6 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleReloadSpellDisabledCommand(const char* args);
bool HandleReloadAuctionsCommand(const char* args);
bool HandleReloadWpScriptsCommand(const char* args);
bool HandleResetAchievementsCommand(const char * args);
bool HandleResetAllCommand(const char * args);
bool HandleResetHonorCommand(const char * args);
@@ -428,12 +380,10 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleResetSpellsCommand(const char * args);
bool HandleResetStatsCommand(const char * args);
bool HandleResetTalentsCommand(const char * args);
bool HandleSendItemsCommand(const char* args);
bool HandleSendMailCommand(const char* args);
bool HandleSendMessageCommand(const char * args);
bool HandleSendMoneyCommand(const char* args);
bool HandleServerCorpsesCommand(const char* args);
bool HandleServerExitCommand(const char* args);
bool HandleServerIdleRestartCommand(const char* args);
@@ -447,20 +397,16 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleServerShutDownCommand(const char* args);
bool HandleServerShutDownCancelCommand(const char* args);
bool HandleServerSetClosedCommand(const char* args);
bool HandleServerSetLogFileLevelCommand(const char* args);
bool HandleServerSetDiffTimeCommand(const char* args);
bool HandleTeleCommand(const char * args);
bool HandleTeleAddCommand(const char * args);
bool HandleTeleDelCommand(const char * args);
bool HandleTeleGroupCommand(const char* args);
bool HandleTeleNameCommand(const char* args);
bool HandleUnBanAccountCommand(const char* args);
bool HandleUnBanCharacterCommand(const char* args);
bool HandleUnBanIPCommand(const char* args);
bool HandleWpAddCommand(const char* args);
bool HandleWpLoadPathCommand(const char* args);
bool HandleWpUnLoadPathCommand(const char* args);
@@ -468,13 +414,11 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleWpEventCommand(const char* args);
bool HandleWpShowCommand(const char* args);
bool HandleReloadAllPaths(const char *args);
bool HandleHelpCommand(const char* args);
bool HandleCommandsCommand(const char* args);
bool HandleStartCommand(const char* args);
bool HandleDismountCommand(const char* args);
bool HandleSaveCommand(const char* args);
bool HandleNamegoCommand(const char* args);
bool HandleGonameCommand(const char* args);
bool HandleGroupgoCommand(const char* args);
@@ -485,9 +429,7 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleTaxiCheatCommand(const char* args);
bool HandleWhispersCommand(const char* args);
bool HandleModifyDrunkCommand(const char* args);
bool HandleLoadScriptsCommand(const char* args);
bool HandleGUIDCommand(const char* args);
bool HandleItemMoveCommand(const char* args);
bool HandleDeMorphCommand(const char* args);
@@ -498,7 +440,6 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleFreezeCommand(const char *args);
bool HandleUnFreezeCommand(const char *args);
bool HandleListFreezeCommand(const char* args);
bool HandleCooldownCommand(const char* args);
bool HandleUnLearnCommand(const char* args);
bool HandleGetDistanceCommand(const char* args);
@@ -525,15 +466,12 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandlePetUnlearnCommand(const char* args);
bool HandlePetLearnCommand(const char* args);
bool HandleCreatePetCommand(const char* args);
bool HandleGroupLeaderCommand(const char* args);
bool HandleGroupDisbandCommand(const char* args);
bool HandleGroupRemoveCommand(const char* args);
bool HandleBankCommand(const char* args);
bool HandleChangeWeather(const char* args);
bool HandleKickPlayerCommand(const char * args);
// GM ticket command handlers
bool HandleGMTicketListCommand(const char* args);
bool HandleGMTicketListOnlineCommand(const char* args);
@@ -546,44 +484,33 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleGMTicketCommentCommand(const char* args);
bool HandleGMTicketDeleteByIdCommand(const char* args);
bool HandleGMTicketReloadCommand(const char*);
bool HandleMaxSkillCommand(const char* args);
bool HandleSetSkillCommand(const char* args);
bool HandleRespawnCommand(const char* args);
bool HandleComeToMeCommand(const char *args);
bool HandleCombatStopCommand(const char *args);
/*bool HandleCharDeleteCommand(const char *args);
bool HandleSendMessageCommand(const char * args);*/
bool HandleFlushArenaPointsCommand(const char *args);
bool HandlePlayAllCommand(const char* args);
bool HandleRepairitemsCommand(const char* args);
bool HandleTempGameObjectCommand(const char* args);
bool HandleTempAddSpwCommand(const char* args);
//! Development Commands
/*bool HandleQuestAdd(const char * args);
bool HandleQuestRemove(const char * args);
bool HandleQuestComplete(const char * args);*/
//bool HandleSet32Bit(const char* args);
bool HandleSaveAllCommand(const char* args);
Player* getSelectedPlayer();
Creature* getSelectedCreature();
Unit* getSelectedUnit();
WorldObject* getSelectedObject();
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
// if args have single value then it return in arg2 and arg1 == NULL
void extractOptFirstArg(char* args, char** arg1, char** arg2);
char* extractQuotedArg(char* args);
uint32 extractSpellIdFromLink(char* text);
uint64 extractGuidFromLink(char* text);
GameTele const* extractGameTeleFromLink(char* text);
@@ -591,13 +518,10 @@ class TRINITY_DLL_SPEC ChatHandler
std::string extractPlayerNameFromLink(char* text);
// select by arg (name/link) or in-game selection online/offline player
bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL);
std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; }
std::string GetNameLink(Player* chr) const { return playerLink(chr->GetName()); }
GameObject* GetNearbyGameObject();
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry);
// Utility methods for commands
bool LookupPlayerSearchCommand(QueryResult* result, int32 limit);
bool HandleBanListHelper(QueryResult* result);
@@ -606,22 +530,18 @@ class TRINITY_DLL_SPEC ChatHandler
bool HandleUnBanHelper(BanMode mode,char const* args);
void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id);
void SetSentErrorMessage(bool val){ sentErrorMessage = val;};
private:
WorldSession * m_session; // != NULL for chat command call and NULL for CLI command
// common global flag
static bool load_command_table;
bool sentErrorMessage;
};
class CliHandler : public ChatHandler
{
public:
typedef void Print(char const*);
explicit CliHandler(Print* zprint) : m_print(zprint) {}
// overwrite functions
const char *GetTrinityString(int32 entry) const;
bool isAvailable(ChatCommand const& cmd) const;
@@ -630,12 +550,9 @@ class CliHandler : public ChatHandler
bool needReportToTarget(Player* chr) const;
LocaleConstant GetSessionDbcLocale() const;
int GetSessionDbLocaleIndex() const;
private:
Print* m_print;
};
char const *fmtstring( char const *format, ... );
#endif
-120
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
@@ -25,7 +24,6 @@
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Database/DatabaseEnv.h"
#include "CellImpl.h"
#include "Chat.h"
#include "ChannelMgr.h"
@@ -39,7 +37,6 @@
#include "ScriptCalls.h"
#include "SpellAuras.h"
#include "Util.h"
bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg, uint32 lang)
{
if (lang != LANG_ADDON)
@@ -47,7 +44,6 @@ bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg
// strip invisible characters for non-addon messages
if(sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
stripLineInvisibleChars(msg);
if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && GetSecurity() < SEC_MODERATOR
&& !ChatHandler(this).isValidChatMessage(msg.c_str()))
{
@@ -58,26 +54,20 @@ bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg
return false;
}
}
return true;
}
void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
{
uint32 type;
uint32 lang;
recv_data >> type;
recv_data >> lang;
if(type >= MAX_CHAT_MSG_TYPE)
{
sLog.outError("CHAT: Wrong message type received: %u", type);
return;
}
//sLog.outDebug("CHAT: packet received. type %u, lang %u", type, lang );
// prevent talking at unknown language (cheating)
LanguageDesc const* langDesc = GetLanguageDescByID(lang);
if(!langDesc)
@@ -104,24 +94,20 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
return;
}
}
if(lang == LANG_ADDON)
{
if(sWorld.getConfig(CONFIG_CHATLOG_ADDON))
{
std::string msg = "";
recv_data >> msg;
if(msg.empty())
{
sLog.outDebug("Player %s send empty addon msg", GetPlayer()->GetName());
return;
}
sLog.outChat("[ADDON] Player %s sends: %s",
GetPlayer()->GetName(), msg.c_str());
}
// Disabled addon channel?
if(!sWorld.getConfig(CONFIG_ADDON_CHANNEL))
return;
@@ -157,33 +143,27 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
break;
}
}
// but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
Unit::AuraEffectList const& ModLangAuras = _player->GetAurasByType(SPELL_AURA_MOD_LANGUAGE);
if(!ModLangAuras.empty())
lang = ModLangAuras.front()->GetMiscValue();
}
if (!_player->CanSpeak())
{
std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str());
return;
}
if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
GetPlayer()->UpdateSpeakTime();
}
if (GetPlayer()->HasAura(1852) && type != CHAT_MSG_WHISPER)
{
std::string msg="";
recv_data >> msg;
SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName());
return;
}
switch(type)
{
case CHAT_MSG_SAY:
@@ -192,19 +172,14 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
{
std::string msg = "";
recv_data >> msg;
if(msg.empty())
break;
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
break;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
if(type == CHAT_MSG_SAY)
GetPlayer()->Say(msg, lang);
else if(type == CHAT_MSG_EMOTE)
@@ -212,19 +187,15 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
else if(type == CHAT_MSG_YELL)
GetPlayer()->Yell(msg, lang);
} break;
case CHAT_MSG_WHISPER:
{
std::string to, msg;
recv_data >> to;
recv_data >> msg;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
if(!normalizePlayerName(to))
{
WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, (to.size()+1));
@@ -232,7 +203,6 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
SendPacket(&data);
break;
}
Player *player = objmgr.GetPlayer(to.c_str());
uint32 tSecurity = GetSecurity();
uint32 pSecurity = player ? player->GetSession()->GetSecurity() : SEC_PLAYER;
@@ -243,7 +213,6 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
SendPacket(&data);
return;
}
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && tSecurity == SEC_PLAYER && pSecurity == SEC_PLAYER )
{
uint32 sidea = GetPlayer()->GetTeam();
@@ -256,43 +225,33 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
return;
}
}
if (GetPlayer()->HasAura(1852) && !player->isGameMaster())
{
SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName());
return;
}
GetPlayer()->Whisper(msg, lang,player->GetGUID());
} break;
case CHAT_MSG_PARTY:
{
std::string msg = "";
recv_data >> msg;
if(msg.empty())
break;
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
break;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
// if player is in battleground, he cannot say to battleground members by /p
Group *group = GetPlayer()->GetOriginalGroup();
// so if player hasn't OriginalGroup and his player->GetGroup() is BG raid, then return
if( !group && (!(group = GetPlayer()->GetGroup()) || group->isBGGroup()) )
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_PARTY, lang, NULL, 0, msg.c_str(),NULL);
group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
if(sWorld.getConfig(CONFIG_CHATLOG_PARTY))
sLog.outChat("[PARTY] Player %s tells group with leader %s: %s",
GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
@@ -302,25 +261,19 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
{
std::string msg = "";
recv_data >> msg;
if(msg.empty())
break;
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
break;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
if (GetPlayer()->GetGuildId())
{
Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
if (guild)
guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
if(lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHATLOG_GUILD))
{
sLog.outChat("[GUILD] Player %s tells guild %s: %s",
@@ -332,32 +285,25 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
}
}
break;
}
case CHAT_MSG_OFFICER:
{
std::string msg = "";
recv_data >> msg;
if(msg.empty())
break;
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
break;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
if (GetPlayer()->GetGuildId())
{
Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
if (guild)
guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
if(sWorld.getConfig(CONFIG_CHATLOG_GUILD))
sLog.outChat("[OFFICER] Player %s tells guild %s officers: %s",
GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str());
@@ -368,29 +314,22 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
{
std::string msg="";
recv_data >> msg;
if(msg.empty())
break;
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
break;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
// if player is in battleground, he cannot say to battleground members by /ra
Group *group = GetPlayer()->GetOriginalGroup();
// so if player hasn't OriginalGroup and his player->GetGroup() is BG raid or his group isn't raid, then return
if ((!group && !(group = GetPlayer()->GetGroup())) || group->isBGGroup() || !group->isRaidGroup())
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(),NULL);
group->BroadcastPacket(&data, false);
if(sWorld.getConfig(CONFIG_CHATLOG_RAID))
sLog.outChat("[RAID] Player %s tells raid with leader %s: %s",
GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
@@ -399,28 +338,21 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
{
std::string msg="";
recv_data >> msg;
if(msg.empty())
break;
if (ChatHandler(this).ParseCommands(msg.c_str()) > 0)
break;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
// if player is in battleground, he cannot say to battleground members by /ra
Group *group = GetPlayer()->GetOriginalGroup();
if( !group && !(group = GetPlayer()->GetGroup()) || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(),NULL);
group->BroadcastPacket(&data, false);
if(sWorld.getConfig(CONFIG_CHATLOG_RAID))
sLog.outChat("[RAID] Leader player %s tells raid: %s",
GetPlayer()->GetName(), msg.c_str());
@@ -429,97 +361,74 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
{
std::string msg="";
recv_data >> msg;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
Group *group = GetPlayer()->GetGroup();
if(!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
return;
WorldPacket data;
//in battleground, raid warning is sent only to players in battleground - code is ok
ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, "", 0, msg.c_str(),NULL);
group->BroadcastPacket(&data, false);
if(sWorld.getConfig(CONFIG_CHATLOG_RAID))
sLog.outChat("[RAID] Leader player %s warns raid with: %s",
GetPlayer()->GetName(), msg.c_str());
} break;
case CHAT_MSG_BATTLEGROUND:
{
std::string msg="";
recv_data >> msg;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
//battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
Group *group = GetPlayer()->GetGroup();
if(!group || !group->isBGGroup())
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(),NULL);
group->BroadcastPacket(&data, false);
if(sWorld.getConfig(CONFIG_CHATLOG_BGROUND))
sLog.outChat("[BATTLEGROUND] Player %s tells battleground with leader %s: %s",
GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str());
} break;
case CHAT_MSG_BATTLEGROUND_LEADER:
{
std::string msg="";
recv_data >> msg;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
//battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
Group *group = GetPlayer()->GetGroup();
if(!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(),NULL);
group->BroadcastPacket(&data, false);
if(sWorld.getConfig(CONFIG_CHATLOG_BGROUND))
sLog.outChat("[RAID] Leader player %s tells battleground: %s",
GetPlayer()->GetName(), msg.c_str());
} break;
case CHAT_MSG_CHANNEL:
{
std::string channel = "", msg = "";
recv_data >> channel;
recv_data >> msg;
if (!processChatmessageFurtherAfterSecurityChecks(msg, lang))
return;
if(msg.empty())
break;
if(ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
{
Channel *chn = cMgr->GetChannel(channel,_player);
if(chn)
{
chn->Say(_player->GetGUID(),msg.c_str(),lang);
if((chn->HasFlag(CHANNEL_FLAG_TRADE) ||
chn->HasFlag(CHANNEL_FLAG_GENERAL) ||
chn->HasFlag(CHANNEL_FLAG_CITY) ||
@@ -533,12 +442,10 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
}
}
} break;
case CHAT_MSG_AFK:
{
std::string msg;
recv_data >> msg;
if((msg.empty() || !_player->isAFK()) && !_player->isInCombat() )
{
if(!_player->isAFK())
@@ -552,12 +459,10 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
_player->ToggleDND();
}
} break;
case CHAT_MSG_DND:
{
std::string msg;
recv_data >> msg;
if(msg.empty() || !_player->isDND())
{
if(!_player->isDND())
@@ -571,23 +476,19 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
_player->ToggleAFK();
}
} break;
default:
sLog.outError("CHAT: unknown message type %u, lang: %u", type, lang);
break;
}
}
void WorldSession::HandleEmoteOpcode( WorldPacket & recv_data )
{
if(!GetPlayer()->isAlive())
return;
uint32 emote;
recv_data >> emote;
GetPlayer()->HandleEmoteCommand(emote);
}
namespace MaNGOS
{
class EmoteChatBuilder
@@ -595,12 +496,10 @@ namespace MaNGOS
public:
EmoteChatBuilder(Player const& pl, uint32 text_emote, uint32 emote_num, Unit const* target)
: i_player(pl), i_text_emote(text_emote), i_emote_num(emote_num), i_target(target) {}
void operator()(WorldPacket& data, int32 loc_idx)
{
char const* nam = i_target ? i_target->GetNameForLocaleIdx(loc_idx) : NULL;
uint32 namlen = (nam ? strlen(nam) : 0) + 1;
data.Initialize(SMSG_TEXT_EMOTE, (20+namlen));
data << i_player.GetGUID();
data << (uint32)i_text_emote;
@@ -611,7 +510,6 @@ namespace MaNGOS
else
data << (uint8)0x00;
}
private:
Player const& i_player;
uint32 i_text_emote;
@@ -619,32 +517,25 @@ namespace MaNGOS
Unit const* i_target;
};
} // namespace MaNGOS
void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
{
if(!GetPlayer()->isAlive())
return;
if (!GetPlayer()->CanSpeak())
{
std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str());
return;
}
uint32 text_emote, emoteNum;
uint64 guid;
recv_data >> text_emote;
recv_data >> emoteNum;
recv_data >> guid;
EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote);
if (!em)
return;
uint32 emote_anim = em->textid;
switch(emote_anim)
{
case EMOTE_STATE_SLEEP:
@@ -656,47 +547,36 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data )
GetPlayer()->HandleEmoteCommand(emote_anim);
break;
}
Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
CellPair p = MaNGOS::ComputeCellPair(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > emote_do(emote_builder);
MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > > emote_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),emote_do);
TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > >, WorldTypeMapContainer > message(emote_worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
//Send scripted event call
if (unit && unit->GetTypeId()==TYPEID_UNIT && ((Creature*)unit)->AI())
((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(),text_emote);
}
void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data )
{
uint64 iguid;
uint8 unk;
//sLog.outDebug("WORLD: Received CMSG_CHAT_IGNORED");
recv_data >> iguid;
recv_data >> unk; // probably related to spam reporting
Player *player = objmgr.GetPlayer(iguid);
if(!player || !player->GetSession())
return;
WorldPacket data;
ChatHandler::FillMessageData(&data, this, CHAT_MSG_IGNORED, LANG_UNIVERSAL, NULL, GetPlayer()->GetGUID(), GetPlayer()->GetName(),NULL);
player->GetSession()->SendPacket(&data);
}
void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
-40
View File
@@ -17,64 +17,51 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "CombatAI.h"
#include "SpellMgr.h"
int AggressorAI::Permissible(const Creature *creature)
{
// have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
if( !creature->isCivilian() && !creature->IsNeutralToAll() )
return PERMIT_BASE_PROACTIVE;
return PERMIT_BASE_NO;
}
void AggressorAI::UpdateAI(const uint32 /*diff*/)
{
if(!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
// some day we will delete these useless things
int CombatAI::Permissible(const Creature *creature)
{
return PERMIT_BASE_NO;
}
int ArchorAI::Permissible(const Creature *creature)
{
return PERMIT_BASE_NO;
}
int TurretAI::Permissible(const Creature *creature)
{
return PERMIT_BASE_NO;
}
void CombatAI::InitializeAI()
{
for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
if(me->m_spells[i] && GetSpellStore()->LookupEntry(me->m_spells[i]))
spells.push_back(me->m_spells[i]);
CreatureAI::InitializeAI();
}
void CombatAI::Reset()
{
events.Reset();
}
void CombatAI::JustDied(Unit *killer)
{
for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i)
if(AISpellInfo[*i].condition == AICOND_DIE)
me->CastSpell(killer, *i, true);
}
void CombatAI::EnterCombat(Unit *who)
{
for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i)
@@ -85,17 +72,13 @@ void CombatAI::EnterCombat(Unit *who)
events.ScheduleEvent(*i, AISpellInfo[*i].cooldown + rand()%AISpellInfo[*i].cooldown);
}
}
void CombatAI::UpdateAI(const uint32 diff)
{
if(!UpdateVictim())
return;
events.Update(diff);
if(me->hasUnitState(UNIT_STAT_CASTING))
return;
if(uint32 spellId = events.ExecuteEvent())
{
DoCast(spellId);
@@ -105,15 +88,12 @@ void CombatAI::UpdateAI(const uint32 diff)
DoMeleeAttackIfReady();
}
/////////////////
//CasterAI
/////////////////
void CasterAI::InitializeAI()
{
CombatAI::InitializeAI();
float m_attackDist = 30.0f;
for(SpellVct::iterator itr = spells.begin(); itr != spells.end(); ++itr)
if (AISpellInfo[*itr].condition == AICOND_COMBAT && m_attackDist > GetAISpellInfo(*itr)->maxRange)
@@ -121,12 +101,10 @@ void CasterAI::InitializeAI()
if (m_attackDist == 30.0f)
m_attackDist = MELEE_RANGE;
}
void CasterAI::EnterCombat(Unit *who)
{
if (spells.empty())
return;
uint32 spell = rand()%spells.size();
uint32 count = 0;
for(SpellVct::iterator itr = spells.begin(); itr != spells.end(); ++itr, ++count)
@@ -145,17 +123,13 @@ void CasterAI::EnterCombat(Unit *who)
}
}
}
void CasterAI::UpdateAI(const uint32 diff)
{
if(!UpdateVictim())
return;
events.Update(diff);
if(me->hasUnitState(UNIT_STAT_CASTING))
return;
if(uint32 spellId = events.ExecuteEvent())
{
DoCast(spellId);
@@ -164,11 +138,9 @@ void CasterAI::UpdateAI(const uint32 diff)
}
}
//////////////
//ArchorAI
//////////////
ArchorAI::ArchorAI(Creature *c) : CreatureAI(c)
{
ASSERT(me->m_spells[0]);
@@ -178,12 +150,10 @@ ArchorAI::ArchorAI(Creature *c) : CreatureAI(c)
me->m_CombatDistance = GetSpellMaxRange(me->m_spells[0], false);
me->m_SightDistance = me->m_CombatDistance;
}
void ArchorAI::AttackStart(Unit *who)
{
if(!who)
return;
if(me->IsWithinCombatRange(who, m_minRange))
{
if(me->Attack(who, true) && !who->IsFlying())
@@ -194,27 +164,22 @@ void ArchorAI::AttackStart(Unit *who)
if(me->Attack(who, false) && !who->IsFlying())
me->GetMotionMaster()->MoveChase(who, me->m_CombatDistance);
}
if(who->IsFlying())
me->GetMotionMaster()->MoveIdle();
}
void ArchorAI::UpdateAI(const uint32 diff)
{
if(!UpdateVictim())
return;
if(!me->IsWithinCombatRange(me->getVictim(), m_minRange))
DoSpellAttackIfReady(me->m_spells[0]);
else
DoMeleeAttackIfReady();
}
//////////////
//TurretAI
//////////////
TurretAI::TurretAI(Creature *c) : CreatureAI(c)
{
ASSERT(me->m_spells[0]);
@@ -222,7 +187,6 @@ TurretAI::TurretAI(Creature *c) : CreatureAI(c)
me->m_CombatDistance = GetSpellMaxRange(me->m_spells[0], false);
me->m_SightDistance = me->m_CombatDistance;
}
bool TurretAI::CanAIAttack(const Unit *who) const
{
// TODO: use one function to replace it
@@ -231,20 +195,16 @@ bool TurretAI::CanAIAttack(const Unit *who) const
return false;
return true;
}
void TurretAI::AttackStart(Unit *who)
{
if(who)
me->Attack(who, false);
}
void TurretAI::UpdateAI(const uint32 diff)
{
if(!UpdateVictim())
return;
DoSpellAttackIfReady(me->m_spells[0]);
//if(!DoSpellAttackIfReady(me->m_spells[0]))
//if(HostilReference *ref = me->getThreatManager().getCurrentVictim())
//ref->removeReference();
-14
View File
@@ -17,31 +17,23 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_COMBATAI_H
#define TRINITY_COMBATAI_H
#include "CreatureAI.h"
#include "CreatureAIImpl.h"
class Creature;
class TRINITY_DLL_DECL AggressorAI : public CreatureAI
{
public:
explicit AggressorAI(Creature *c) : CreatureAI(c) {}
void UpdateAI(const uint32);
static int Permissible(const Creature *);
};
typedef std::vector<uint32> SpellVct;
class TRINITY_DLL_SPEC CombatAI : public CreatureAI
{
public:
explicit CombatAI(Creature *c) : CreatureAI(c) {}
void InitializeAI();
void Reset();
void EnterCombat(Unit* who);
@@ -52,7 +44,6 @@ class TRINITY_DLL_SPEC CombatAI : public CreatureAI
EventMap events;
SpellVct spells;
};
class TRINITY_DLL_SPEC CasterAI : public CombatAI
{
public:
@@ -64,19 +55,16 @@ class TRINITY_DLL_SPEC CasterAI : public CombatAI
private:
float m_attackDist;
};
struct TRINITY_DLL_SPEC ArchorAI : public CreatureAI
{
public:
explicit ArchorAI(Creature *c);
void AttackStart(Unit *who);
void UpdateAI(const uint32 diff);
static int Permissible(const Creature *);
protected:
float m_minRange;
};
struct TRINITY_DLL_SPEC TurretAI : public CreatureAI
{
public:
@@ -84,10 +72,8 @@ struct TRINITY_DLL_SPEC TurretAI : public CreatureAI
bool CanAIAttack(const Unit *who) const;
void AttackStart(Unit *who);
void UpdateAI(const uint32 diff);
static int Permissible(const Creature *);
protected:
float m_minRange;
};
#endif
-15
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "Log.h"
#include "WorldPacket.h"
@@ -25,61 +24,47 @@
#include "ObjectAccessor.h"
#include "CreatureAI.h"
#include "ObjectDefines.h"
void WorldSession::HandleAttackSwingOpcode( WorldPacket & recv_data )
{
uint64 guid;
recv_data >> guid;
DEBUG_LOG( "WORLD: Recvd CMSG_ATTACKSWING Message guidlow:%u guidhigh:%u", GUID_LOPART(guid), GUID_HIPART(guid) );
Unit *pEnemy = ObjectAccessor::GetUnit(*_player, guid);
if(!pEnemy)
{
if(!IS_UNIT_GUID(guid))
sLog.outError("WORLD: Object %u (TypeID: %u) isn't player, pet or creature",GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)));
else
sLog.outError( "WORLD: Enemy %s %u not found",GetLogNameForGuid(guid),GUID_LOPART(guid));
// stop attack state at client
SendAttackStop(NULL);
return;
}
if(!_player->canAttack(pEnemy))
{
sLog.outError( "WORLD: Enemy %s %u is friendly",(IS_PLAYER_GUID(guid) ? "player" : "creature"),GUID_LOPART(guid));
// stop attack state at client
SendAttackStop(pEnemy);
return;
}
_player->Attack(pEnemy,true);
}
void WorldSession::HandleAttackStopOpcode( WorldPacket & /*recv_data*/ )
{
GetPlayer()->AttackStop();
}
void WorldSession::HandleSetSheathedOpcode( WorldPacket & recv_data )
{
uint32 sheathed;
recv_data >> sheathed;
//sLog.outDebug( "WORLD: Recvd CMSG_SETSHEATHED Message guidlow:%u value1:%u", GetPlayer()->GetGUIDLow(), sheathed );
if(sheathed >= MAX_SHEATH_STATE)
{
sLog.outError("Unknown sheath state %u ??",sheathed);
return;
}
GetPlayer()->SetSheath(SheathState(sheathed));
}
void WorldSession::SendAttackStop(Unit const* enemy)
{
WorldPacket data( SMSG_ATTACKSTOP, (4+20) ); // we guess size
+2 -25
View File
@@ -17,19 +17,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Creature.h"
#include "MapManager.h"
#include "Opcodes.h"
#include "ConfusedMovementGenerator.h"
#include "DestinationHolderImp.h"
#include "VMapFactory.h"
#ifdef MAP_BASED_RAND_GEN
#define rand_norm() unit.rand_norm()
#define urand(a,b) unit.urand(a,b)
#endif
template<class T>
void
ConfusedMovementGenerator<T>::Initialize(T &unit)
@@ -39,35 +36,26 @@ ConfusedMovementGenerator<T>::Initialize(T &unit)
x = unit.GetPositionX();
y = unit.GetPositionY();
z = unit.GetPositionZ();
Map const* map = unit.GetBaseMap();
i_nextMove = 1;
bool is_water_ok, is_land_ok;
_InitSpecific(unit, is_water_ok, is_land_ok);
VMAP::IVMapManager *vMaps = VMAP::VMapFactory::createOrGetVMapManager();
for(unsigned int idx=0; idx < MAX_CONF_WAYPOINTS+1; ++idx)
{
const float wanderX=wander_distance*rand_norm() - wander_distance/2;
const float wanderY=wander_distance*rand_norm() - wander_distance/2;
const bool isInLoS = vMaps->isInLineOfSight(unit.GetMapId(), x, y, z + 2.0f, i_waypoints[idx][0], i_waypoints[idx][1], z + 2.0f);
const bool isInLoS = vMaps->isInLineOfSight(unit.GetMapId(), x, y, z + 2.0f, i_waypoints[idx][0], i_waypoints[idx][1], z + 2.0f);
if (!isInLoS)
{
i_waypoints[idx][0] = x;
i_waypoints[idx][0] = x;
i_waypoints[idx][1] = y;
}
i_waypoints[idx][0] = x + wanderX;
i_waypoints[idx][1] = y + wanderY;
// prevent invalid coordinates generation
Trinity::NormalizeMapCoord(i_waypoints[idx][0]);
Trinity::NormalizeMapCoord(i_waypoints[idx][1]);
bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
// if generated wrong path just ignore
if ((is_water && !is_water_ok) || (!is_water && !is_land_ok))
@@ -75,11 +63,9 @@ ConfusedMovementGenerator<T>::Initialize(T &unit)
i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x;
i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
}
unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z);
i_waypoints[idx][2] = z;
}
unit.SetUInt64Value(UNIT_FIELD_TARGET, 0);
unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
unit.CastStop();
@@ -87,7 +73,6 @@ ConfusedMovementGenerator<T>::Initialize(T &unit)
unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
unit.addUnitState(UNIT_STAT_CONFUSED);
}
template<>
void
ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
@@ -95,7 +80,6 @@ ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_
is_water_ok = creature.canSwim();
is_land_ok = creature.canWalk();
}
template<>
void
ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
@@ -103,7 +87,6 @@ ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bo
is_water_ok = true;
is_land_ok = true;
}
template<class T>
void
ConfusedMovementGenerator<T>::Reset(T &unit)
@@ -113,17 +96,14 @@ ConfusedMovementGenerator<T>::Reset(T &unit)
i_destinationHolder.ResetUpdate();
unit.StopMoving();
}
template<class T>
bool
ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
{
if(!&unit)
return true;
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
return true;
if( i_nextMoveTime.Passed() )
{
// currently moving, update location
@@ -134,7 +114,6 @@ ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
{
// arrived, stop and wait a bit
unit.clearUnitState(UNIT_STAT_MOVE);
i_nextMove = urand(1,MAX_CONF_WAYPOINTS);
i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher
}
@@ -157,7 +136,6 @@ ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
}
return true;
}
template<class T>
void
ConfusedMovementGenerator<T>::Finalize(T &unit)
@@ -167,7 +145,6 @@ ConfusedMovementGenerator<T>::Finalize(T &unit)
if(unit.GetTypeId() == TYPEID_UNIT && unit.getVictim())
unit.SetUInt64Value(UNIT_FIELD_TARGET, unit.getVictim()->GetGUID());
}
template void ConfusedMovementGenerator<Player>::Initialize(Player &player);
template void ConfusedMovementGenerator<Creature>::Initialize(Creature &creature);
template void ConfusedMovementGenerator<Player>::Finalize(Player &player);
-7
View File
@@ -17,35 +17,28 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_CONFUSEDGENERATOR_H
#define TRINITY_CONFUSEDGENERATOR_H
#include "MovementGenerator.h"
#include "DestinationHolder.h"
#include "Traveller.h"
#define MAX_CONF_WAYPOINTS 24
template<class T>
class TRINITY_DLL_SPEC ConfusedMovementGenerator
: public MovementGeneratorMedium< T, ConfusedMovementGenerator<T> >
{
public:
explicit ConfusedMovementGenerator() : i_nextMoveTime(0) {}
void Initialize(T &);
void Finalize(T &);
void Reset(T &);
bool Update(T &, const uint32 &);
bool GetDestination(float &x, float &y, float &z) const
{
if(i_destinationHolder.HasArrived()) return false;
i_destinationHolder.GetDestination(x,y,z);
return true;
}
MovementGeneratorType GetMovementGeneratorType() { return CONFUSED_MOTION_TYPE; }
private:
void _InitSpecific(T &, bool &, bool &);
-48
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "Corpse.h"
#include "Player.h"
@@ -27,87 +26,65 @@
#include "Opcodes.h"
#include "GossipDef.h"
#include "World.h"
Corpse::Corpse(CorpseType type) : WorldObject()
, m_type(type)
{
m_objectType |= TYPEMASK_CORPSE;
m_objectTypeId = TYPEID_CORPSE;
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
m_valuesCount = CORPSE_END;
m_time = time(NULL);
lootForBody = false;
if(type != CORPSE_BONES)
m_isWorldObject = true;
}
Corpse::~Corpse()
{
}
void Corpse::AddToWorld()
{
///- Register the corpse for guid lookup
if(!IsInWorld())
ObjectAccessor::Instance().AddObject(this);
Object::AddToWorld();
}
void Corpse::RemoveFromWorld()
{
///- Remove the corpse from the accessor
if(IsInWorld())
ObjectAccessor::Instance().RemoveObject(this);
Object::RemoveFromWorld();
}
bool Corpse::Create( uint32 guidlow, Map *map )
{
SetMap(map);
Object::_Create(guidlow, 0, HIGHGUID_CORPSE);
return true;
}
bool Corpse::Create( uint32 guidlow, Player *owner)
{
ASSERT(owner);
Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
if(!IsPositionValid())
{
sLog.outError("Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
guidlow, owner->GetName(), owner->GetPositionX(), owner->GetPositionY());
return false;
}
//we need to assign owner's map for corpse
//in other way we will get a crash in Corpse::SaveToDB()
SetMap(owner->GetMap());
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask());
SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
SetUInt64Value( CORPSE_FIELD_OWNER, owner->GetGUID() );
m_grid = Trinity::ComputeGridPair(GetPositionX(), GetPositionY());
return true;
}
void Corpse::SaveToDB()
{
// prevent DB data inconsistence problems and duplicates
CharacterDatabase.BeginTransaction();
DeleteFromDB();
std::ostringstream ss;
ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance,phaseMask) VALUES ("
<< GetGUIDLow() << ", "
@@ -128,21 +105,17 @@ void Corpse::SaveToDB()
CharacterDatabase.Execute( ss.str().c_str() );
CharacterDatabase.CommitTransaction();
}
void Corpse::DeleteBonesFromWorld()
{
assert(GetType() == CORPSE_BONES);
Corpse* corpse = ObjectAccessor::GetCorpse(*this, GetGUID());
if (!corpse)
{
sLog.outError("Bones %u not found in world.", GetGUIDLow());
return;
}
AddObjectToRemoveList();
}
void Corpse::DeleteFromDB()
{
if(GetType() == CORPSE_BONES)
@@ -152,7 +125,6 @@ void Corpse::DeleteFromDB()
// all corpses (not bones)
CharacterDatabase.PExecute("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID()));
}
/*
bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
{
@@ -160,29 +132,22 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId)
if (!external)
// 0 1 2 3 4 5 6 7 8 9
result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
if( !result )
{
sLog.outError("Corpse (GUID: %u) not found in table `corpse`, can't load. ",guid);
return false;
}
Field *fields = result->Fetch();
if(!LoadFromDB(guid, fields))
{
if (!external)
delete result;
return false;
}
if (!external)
delete result;
return true;
}*/
bool Corpse::LoadFromDB(uint32 guid, Field *fields)
{
// 0 1 2 3 4 5 6 7 8 9
@@ -192,52 +157,39 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
float positionZ = fields[2].GetFloat();
float ort = fields[3].GetFloat();
uint32 mapid = fields[4].GetUInt32();
Object::_Create(guid, 0, HIGHGUID_CORPSE);
if(!LoadValues( fields[5].GetString() ))
{
sLog.outError("Corpse #%d have broken data in `data` field. Can't be loaded.",guid);
return false;
}
m_time = time_t(fields[6].GetUInt64());
m_type = CorpseType(fields[7].GetUInt32());
if(m_type >= MAX_CORPSE_TYPE)
{
sLog.outError("Corpse (guidlow %d, owner %d) have wrong corpse type, not load.",GetGUIDLow(),GUID_LOPART(GetOwnerGUID()));
return false;
}
if(m_type != CORPSE_BONES)
m_isWorldObject = true;
uint32 instanceid = fields[8].GetUInt32();
uint32 phaseMask = fields[9].GetUInt32();
// overwrite possible wrong/corrupted guid
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
// place
SetLocationInstanceId(instanceid);
SetLocationMapId(mapid);
SetPhaseMask(phaseMask, false);
Relocate(positionX, positionY, positionZ, ort);
if(!IsPositionValid())
{
sLog.outError("Corpse (guidlow %d, owner %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
GetGUIDLow(), GUID_LOPART(GetOwnerGUID()), GetPositionX(), GetPositionY());
return false;
}
m_grid = Trinity::ComputeGridPair(GetPositionX(), GetPositionY());
return true;
}
bool Corpse::isVisibleForInState(Player const* u, bool inVisibleList) const
{
return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u->m_seer, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
-18
View File
@@ -17,15 +17,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_CORPSE_H
#define TRINITYCORE_CORPSE_H
#include "Object.h"
#include "Database/DatabaseEnv.h"
#include "GridDefines.h"
#include "LootMgr.h"
enum CorpseType
{
CORPSE_BONES = 0,
@@ -33,10 +30,8 @@ enum CorpseType
CORPSE_RESURRECTABLE_PVP = 2
};
#define MAX_CORPSE_TYPE 3
// Value equal client resurrection dialog show radius.
#define CORPSE_RECLAIM_RADIUS 39
enum CorpseFlags
{
CORPSE_FLAG_NONE = 0x00,
@@ -47,51 +42,38 @@ enum CorpseFlags
CORPSE_FLAG_HIDE_CLOAK = 0x10,
CORPSE_FLAG_LOOTABLE = 0x20
};
class Corpse : public WorldObject
{
public:
explicit Corpse( CorpseType type = CORPSE_BONES );
~Corpse( );
void AddToWorld();
void RemoveFromWorld();
bool Create( uint32 guidlow, Map *map );
bool Create( uint32 guidlow, Player *owner );
void SaveToDB();
//bool LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId);
bool LoadFromDB(uint32 guid, Field *fields);
void DeleteBonesFromWorld();
void DeleteFromDB();
uint64 const& GetOwnerGUID() const { return GetUInt64Value(CORPSE_FIELD_OWNER); }
time_t const& GetGhostTime() const { return m_time; }
void ResetGhostTime() { m_time = time(NULL); }
CorpseType GetType() const { return m_type; }
GridPair const& GetGrid() const { return m_grid; }
void SetGrid(GridPair const& grid) { m_grid = grid; }
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
Loot loot; // remove insignia ONLY at BG
Player* lootRecipient;
bool lootForBody;
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); }
void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); }
void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
GridReference<Corpse> &GetGridRef() { return m_gridRef; }
private:
GridReference<Corpse> m_gridRef;
CorpseType m_type;
time_t m_time;
GridPair m_grid; // gride for corpse position for fast search
+4 -415
View File
File diff suppressed because it is too large Load Diff
-128
View File
@@ -17,10 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_CREATURE_H
#define TRINITYCORE_CREATURE_H
#include "Common.h"
#include "Unit.h"
#include "UpdateMask.h"
@@ -28,17 +26,13 @@
#include "LootMgr.h"
#include "Database/DatabaseEnv.h"
#include "Cell.h"
#include <list>
struct SpellEntry;
class CreatureAI;
class Quest;
class Player;
class WorldSession;
class CreatureGroup;
enum Gossip_Option
{
GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE = 0,
@@ -62,7 +56,6 @@ enum Gossip_Option
GOSSIP_OPTION_LEARNDUALSPEC = 18, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER)
GOSSIP_OPTION_OUTDOORPVP = 19 //added by code (option for outdoor pvp creatures)
};
enum Gossip_Guard
{
GOSSIP_GUARD_BANK = 32,
@@ -77,7 +70,6 @@ enum Gossip_Guard
GOSSIP_GUARD_SPELLTRAINER = 41,
GOSSIP_GUARD_SKILLTRAINER = 42
};
enum Gossip_Guard_Spell
{
GOSSIP_GUARD_SPELL_WARRIOR = 64,
@@ -92,7 +84,6 @@ enum Gossip_Guard_Spell
GOSSIP_GUARD_SPELL_UNKNOWN2 = 73,
GOSSIP_GUARD_SPELL_DRUID = 74
};
enum Gossip_Guard_Skill
{
GOSSIP_GUARD_SKILL_ALCHEMY = 80,
@@ -108,7 +99,6 @@ enum Gossip_Guard_Skill
GOSSIP_GUARD_SKILL_TAILORING = 90,
GOSSIP_GUARD_SKILL_ENGINERING = 91
};
enum GossipOptionIcon
{
GOSSIP_ICON_CHAT = 0, //white chat bubble
@@ -123,7 +113,6 @@ enum GossipOptionIcon
GOSSIP_ICON_BATTLE = 9, //two swords
GOSSIP_ICON_DOT = 10 //yellow dot
};
struct GossipOption
{
uint32 Id;
@@ -136,7 +125,6 @@ struct GossipOption
std::string OptionText;
std::string BoxText;
};
enum CreatureFlagsExtra
{
CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group
@@ -153,16 +141,13 @@ enum CreatureFlagsExtra
CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes
CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills
};
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack(1)
#else
#pragma pack(push,1)
#endif
#define MAX_KILL_CREDIT 2
// from `creature_template` table
struct CreatureInfo
{
@@ -238,7 +223,6 @@ struct CreatureInfo
uint32 ScriptID;
uint32 GetRandomValidModelId() const;
uint32 GetFirstValidModelId() const;
// helpers
SkillType GetRequiredLootSkill() const
{
@@ -251,40 +235,33 @@ struct CreatureInfo
else
return SKILL_SKINNING; // normal case
}
bool isTameable(bool exotic) const
{
if(type != CREATURE_TYPE_BEAST || family == 0 || (type_flags & CREATURE_TYPEFLAGS_TAMEABLE)==0)
return false;
// if can tame exotic then can tame any temable
return exotic || (type_flags & CREATURE_TYPEFLAGS_EXOTIC)==0;
}
};
struct CreatureLocale
{
std::vector<std::string> Name;
std::vector<std::string> SubName;
};
struct NpcOptionLocale
{
std::vector<std::string> OptionText;
std::vector<std::string> BoxText;
};
struct PointOfInterestLocale
{
std::vector<std::string> IconName;
};
struct EquipmentInfo
{
uint32 entry;
uint32 equipentry[3];
};
// from `creature` table
struct CreatureData
{
@@ -308,13 +285,11 @@ struct CreatureData
uint8 spawnMask;
bool dbData;
};
struct CreatureDataAddonAura
{
uint32 spell_id;
uint8 effect_idx;
};
// from `creature_addon` table
struct CreatureDataAddon
{
@@ -327,7 +302,6 @@ struct CreatureDataAddon
uint32 move_flags;
CreatureDataAddonAura const* auras; // loaded as char* "spell1 eff1 spell2 eff2 ... "
};
struct CreatureModelInfo
{
uint32 modelid;
@@ -336,7 +310,6 @@ struct CreatureModelInfo
uint8 gender;
uint32 modelid_other_gender;
};
enum InhabitTypeValues
{
INHABIT_GROUND = 1,
@@ -344,7 +317,6 @@ enum InhabitTypeValues
INHABIT_AIR = 4,
INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR
};
// Enums used by StringTextData::Type (CreatureEventAI)
enum ChatType
{
@@ -356,7 +328,6 @@ enum ChatType
CHAT_TYPE_BOSS_WHISPER = 5,
CHAT_TYPE_ZONE_YELL = 6
};
//Selection method used by SelectTarget (CreatureEventAI)
enum AttackingTarget
{
@@ -369,31 +340,26 @@ enum AttackingTarget
ATTACKING_TARGET_BOTTOMAGGRO_PLAYER, //Selects targets from bottom aggro to top (player only)
*/
};
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack()
#else
#pragma pack(pop)
#endif
// Vendors
struct VendorItem
{
VendorItem(uint32 _item, uint32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost)
: item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {}
uint32 item;
uint32 maxcount; // 0 for infinity item amount
uint32 incrtime; // time for restore items amount if maxcount != 0
uint32 ExtendedCost;
};
typedef std::vector<VendorItem*> VendorItemList;
struct VendorItemData
{
VendorItemList m_items;
VendorItem* GetItem(uint32 slot) const
{
if(slot>=m_items.size()) return NULL;
@@ -408,7 +374,6 @@ struct VendorItemData
bool RemoveItem( uint32 item_id );
VendorItem const* FindItem(uint32 item_id) const;
size_t FindItemSlot(uint32 item_id) const;
void Clear()
{
for (VendorItemList::const_iterator itr = m_items.begin(); itr != m_items.end(); ++itr)
@@ -416,84 +381,62 @@ struct VendorItemData
m_items.clear();
}
};
struct VendorItemCount
{
explicit VendorItemCount(uint32 _item, uint32 _count)
: itemId(_item), count(_count), lastIncrementTime(time(NULL)) {}
uint32 itemId;
uint32 count;
time_t lastIncrementTime;
};
typedef std::list<VendorItemCount> VendorItemCounts;
struct TrainerSpell
{
TrainerSpell() : spell(0), spellCost(0), reqSkill(0), reqSkillValue(0), reqLevel(0), learnedSpell(0) {}
TrainerSpell(uint32 _spell, uint32 _spellCost, uint32 _reqSkill, uint32 _reqSkillValue, uint32 _reqLevel, uint32 _learnedspell)
: spell(_spell), spellCost(_spellCost), reqSkill(_reqSkill), reqSkillValue(_reqSkillValue), reqLevel(_reqLevel), learnedSpell(_learnedspell)
{}
uint32 spell;
uint32 spellCost;
uint32 reqSkill;
uint32 reqSkillValue;
uint32 reqLevel;
uint32 learnedSpell;
// helpers
bool IsCastable() const { return learnedSpell != spell; }
};
typedef UNORDERED_MAP<uint32 /*spellid*/, TrainerSpell> TrainerSpellMap;
struct TrainerSpellData
{
TrainerSpellData() : trainerType(0) {}
TrainerSpellMap spellList;
uint32 trainerType; // trainer type based at trainer spells, can be different from creature_template value.
// req. for correct show non-prof. trainers like weaponmaster, allowed values 0 and 2.
TrainerSpell const* Find(uint32 spell_id) const;
void Clear() { spellList.clear(); }
};
typedef std::list<GossipOption> GossipOptionList;
typedef std::map<uint32,time_t> CreatureSpellCooldowns;
// max different by z coordinate for creature aggro reaction
#define CREATURE_Z_ATTACK_RANGE 3
#define MAX_VENDOR_ITEMS 150 // Limitation in 3.x.x item count in SMSG_LIST_INVENTORY
class TRINITY_DLL_SPEC Creature : public Unit
{
public:
explicit Creature();
virtual ~Creature();
void AddToWorld();
void RemoveFromWorld();
void DisappearAndDie();
bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData *data = NULL);
bool LoadCreaturesAddon(bool reload = false);
void SelectLevel(const CreatureInfo *cinfo);
void LoadEquipment(uint32 equip_entry, bool force=false);
uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; }
char const* GetSubName() const { return GetCreatureInfo()->SubName; }
void Update( uint32 time ); // overwrited Unit::Update
void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const;
uint32 GetEquipmentId() const { return GetCreatureInfo()->equipmentId; }
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
@@ -517,45 +460,33 @@ class TRINITY_DLL_SPEC Creature : public Unit
{
if(isPet())
return false;
uint32 rank = GetCreatureInfo()->rank;
return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE;
}
bool isWorldBoss() const
{
if(isPet())
return false;
return GetCreatureInfo()->rank == CREATURE_ELITE_WORLDBOSS;
}
uint32 getLevelForTarget(Unit const* target) const; // overwrite Unit::getLevelForTarget for boss level support
bool IsInEvadeMode() const { return hasUnitState(UNIT_STAT_EVADE); }
bool AIM_Initialize(CreatureAI* ai = NULL);
void Motion_Initialize();
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
CreatureAI * AI() const { return (CreatureAI*)i_AI; }
uint32 GetShieldBlockValue() const //dunno mob block value
{
return (getLevel()/2 + uint32(GetStat(STAT_STRENGTH)/20));
}
SpellSchoolMask GetMeleeDamageSchoolMask() const { return m_meleeDamageSchoolMask; }
void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); }
void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time);
void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time);
void AddCreatureSpellCooldown(uint32 spellid);
bool HasSpellCooldown(uint32 spell_id) const;
bool HasCategoryCooldown(uint32 spell_id) const;
bool HasSpell(uint32 spellID) const;
bool UpdateEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
bool UpdateStats(Stats stat);
bool UpdateAllStats();
@@ -567,72 +498,56 @@ class TRINITY_DLL_SPEC Creature : public Unit
void UpdateDamagePhysical(WeaponAttackType attType);
uint32 GetCurrentEquipmentId() { return m_equipmentId; }
float GetSpellDamageMod(int32 Rank);
VendorItemData const* GetVendorItems() const;
uint32 GetVendorItemCurrentCount(VendorItem const* vItem);
uint32 UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count);
TrainerSpellData const* GetTrainerSpells() const;
CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; }
CreatureData const *GetCreatureData() const { return m_creatureData; }
CreatureDataAddon const* GetCreatureAddon() const;
std::string GetAIName() const;
std::string GetScriptName() const;
uint32 GetScriptId() const;
void prepareGossipMenu( Player *pPlayer, uint32 gossipid = 0 );
void sendPreparedGossip( Player* player );
void OnGossipSelect(Player* player, uint32 option);
void OnPoiSelect(Player* player, GossipOption const *gossip);
uint32 GetGossipTextId(uint32 action, uint32 zoneid);
uint32 GetNpcTextId();
void LoadGossipOptions();
void ResetGossipOptions();
GossipOption const* GetGossipOption( uint32 id ) const;
void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); }
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
void TextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(textId,TargetGuid,IsBossEmote); }
void Whisper(int32 textId, uint64 receiver, bool IsBossWhisper = false) { MonsterWhisper(textId,receiver,IsBossWhisper); }
void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
// overwrite WorldObject function for proper name localization
const char* GetNameForLocaleIdx(int32 locale_idx) const;
void setDeathState(DeathState s); // overwrite virtual Unit::setDeathState
bool FallGround();
bool LoadFromDB(uint32 guid, Map *map);
void SaveToDB();
// overwrited in Pet
virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
virtual void DeleteFromDB(); // overwrited in Pet
Loot loot;
bool lootForPickPocketed;
bool lootForBody;
Player *GetLootRecipient() const;
bool hasLootRecipient() const { return m_lootRecipient!=0; }
void SetLootRecipient (Unit* unit);
void AllLootRemovedFromCorpse();
SpellEntry const *reachWithSpellAttack(Unit *pVictim);
SpellEntry const *reachWithSpellCure(Unit *pVictim);
uint32 m_spells[CREATURE_MAX_SPELLS];
CreatureSpellCooldowns m_CreatureSpellCooldowns;
CreatureSpellCooldowns m_CreatureCategoryCooldowns;
uint32 m_GlobalCooldown;
bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
bool canStartAttack(Unit const* u, bool force) const;
float GetAttackDistance(Unit const* pl) const;
Unit* SelectNearestTarget(float dist = 0) const;
void DoFleeToGetAssistance();
void CallForHelp(float fRadius);
@@ -642,47 +557,33 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; }
bool CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction = true) const;
bool _IsTargetAcceptable(const Unit* target) const;
MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }
// for use only in LoadHelper, Map::Add Map::CreatureCellRelocation
Cell const& GetCurrentCell() const { return m_currentCell; }
void SetCurrentCell(Cell const& cell) { m_currentCell = cell; }
bool IsVisibleInGridForPlayer(Player const* pl) const;
void RemoveCorpse();
bool isDeadByDefault() const { return m_isDeadByDefault; };
void ForcedDespawn();
time_t const& GetRespawnTime() const { return m_respawnTime; }
time_t GetRespawnTimeEx() const;
void SetRespawnTime(uint32 respawn) { m_respawnTime = respawn ? time(NULL) + respawn : 0; }
void Respawn(bool force = false);
void SaveRespawnTime();
uint32 GetRespawnDelay() const { return m_respawnDelay; }
void SetRespawnDelay(uint32 delay) { m_respawnDelay = delay; }
float GetRespawnRadius() const { return m_respawnradius; }
void SetRespawnRadius(float dist) { m_respawnradius = dist; }
// Linked Creature Respawning System
time_t GetLinkedCreatureRespawnTime() const;
const CreatureData* GetLinkedRespawnCreatureData() const;
uint32 m_groupLootTimer; // (msecs)timer used for group loot
uint64 lootingGroupLeaderGUID; // used to find group which is looting corpse
void SendZoneUnderAttackMessage(Player* attacker);
void SetInCombatWithZone();
bool hasQuest(uint32 quest_id) const;
bool hasInvolvedQuest(uint32 quest_id) const;
GridReference<Creature> &GetGridRef() { return m_gridRef; }
bool isRegeneratingHealth() { return m_regenHealth; }
virtual uint8 GetPetAutoSpellSize() const { return CREATURE_MAX_SPELLS; }
@@ -693,26 +594,19 @@ class TRINITY_DLL_SPEC Creature : public Unit
else
return m_charmInfo->GetCharmSpell(pos)->GetAction();
}
void SetHomePosition(float x, float y, float z, float o) { m_homePosition.Relocate(x, y, z, o); }
void SetHomePosition(const Position &pos) { m_homePosition.Relocate(pos);}
void GetHomePosition(float &x, float &y, float &z, float &ori) { m_homePosition.GetPosition(x, y, z, ori); }
uint32 GetGlobalCooldown() const { return m_GlobalCooldown; }
uint32 GetWaypointPath(){return m_path_id;}
void LoadPath(uint32 pathid) { m_path_id = pathid; }
uint32 GetCurrentWaypointID(){return m_waypointID;}
void UpdateWaypointID(uint32 wpID){m_waypointID = wpID;}
void SearchFormation();
CreatureGroup *GetFormation() {return m_formation;}
void SetFormation(CreatureGroup *formation) {m_formation = formation;}
Unit *SelectVictim();
void SetDeadByDefault (bool death_state) {m_isDeadByDefault = death_state;}
void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; }
bool IsReputationGainDisabled() { return DisableReputationGain; }
bool IsDamageEnoughForLootingAndReward() { return m_PlayerDamageReq == 0; }
@@ -723,36 +617,26 @@ class TRINITY_DLL_SPEC Creature : public Unit
}
void ResetPlayerDamageReq() { m_PlayerDamageReq = GetHealth() / 2; }
uint32 m_PlayerDamageReq;
void SetOriginalEntry(uint32 entry) { m_originalEntry = entry; }
static float _GetDamageMod(int32 Rank);
float m_SightDistance, m_CombatDistance;
protected:
bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData *data = NULL);
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
// vendor items
VendorItemCounts m_vendorItemCounts;
void _RealtimeSetCreatureInfo();
static float _GetHealthMod(int32 Rank);
uint32 m_lootMoney;
uint64 m_lootRecipient;
/// Timers
uint32 m_deathTimer; // (msecs)timer for death or corpse disappearance
time_t m_respawnTime; // (secs) time of next respawn
uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning
uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance
float m_respawnradius;
bool m_gossipOptionLoaded;
GossipOptionList m_goptions;
ReactStates m_reactState; // for AI, not charmInfo
void RegenerateMana();
void RegenerateHealth();
@@ -761,48 +645,36 @@ class TRINITY_DLL_SPEC Creature : public Unit
Cell m_currentCell; // store current cell where creature listed
uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid
uint32 m_equipmentId;
bool m_AlreadyCallAssistance;
bool m_AlreadySearchedAssistance;
bool m_regenHealth;
bool m_AI_locked;
bool m_isDeadByDefault;
SpellSchoolMask m_meleeDamageSchoolMask;
uint32 m_originalEntry;
Position m_homePosition;
bool DisableReputationGain;
CreatureInfo const* m_creatureInfo; // in heroic mode can different from ObjMgr::GetCreatureTemplate(GetEntry())
CreatureData const* m_creatureData;
private:
//WaypointMovementGenerator vars
uint32 m_waypointID;
uint32 m_path_id;
//Formation var
CreatureGroup *m_formation;
GridReference<Creature> m_gridRef;
};
class AssistDelayEvent : public BasicEvent
{
public:
AssistDelayEvent(const uint64& victim, Unit& owner) : BasicEvent(), m_victim(victim), m_owner(owner) { }
bool Execute(uint64 e_time, uint32 p_time);
void AddAssistant(const uint64& guid) { m_assistants.push_back(guid); }
private:
AssistDelayEvent();
uint64 m_victim;
std::list<uint64> m_assistants;
Unit& m_owner;
};
#endif
-23
View File
@@ -17,14 +17,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "CreatureAI.h"
#include "CreatureAIImpl.h"
#include "Creature.h"
#include "World.h"
#include "SpellMgr.h"
#include "Vehicle.h"
//Disable CreatureAI when charmed
void CreatureAI::OnCharmed(bool apply)
{
@@ -32,25 +30,20 @@ void CreatureAI::OnCharmed(bool apply)
me->NeedChangeAI = true;
me->IsAIEnabled = false;
}
AISpellInfoType * UnitAI::AISpellInfo;
TRINITY_DLL_SPEC AISpellInfoType * GetAISpellInfo(uint32 i) { return &CreatureAI::AISpellInfo[i]; }
void CreatureAI::DoZoneInCombat(Creature* creature)
{
if (!creature)
creature = me;
if(!creature->CanHaveThreatList())
return;
Map *map = creature->GetMap();
if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
{
sLog.outError("DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? ((Creature*)creature)->GetEntry() : 0);
return;
}
if(!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim())
{
if(Unit *target = creature->SelectNearestTarget(50))
@@ -67,32 +60,26 @@ void CreatureAI::DoZoneInCombat(Creature* creature)
}
}
}
if(!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim())
{
sLog.outError("DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry());
return;
}
Map::PlayerList const &PlList = map->GetPlayers();
if(PlList.isEmpty())
return;
for(Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i)
{
if(Player* pPlayer = i->getSource())
{
if(pPlayer->isGameMaster())
continue;
if(pPlayer->isAlive())
{
creature->SetInCombatWith(pPlayer);
pPlayer->SetInCombatWith(creature);
creature->AddThreat(pPlayer, 0.0f);
}
/* Causes certain things to never leave the threat list (Priest Lightwell, etc):
for(Unit::ControlList::const_iterator itr = pPlayer->m_Controlled.begin(); itr != pPlayer->m_Controlled.end(); ++itr)
{
@@ -103,15 +90,12 @@ void CreatureAI::DoZoneInCombat(Creature* creature)
}
}
}
void CreatureAI::MoveInLineOfSight(Unit *who)
{
if(me->getVictim())
return;
if (me->GetTypeId() == CREATURE_TYPE_NON_COMBAT_PET) // non-combat pets should just stand there and look good;)
return;
if(me->canStartAttack(who, false))
AttackStart(who);
//else if(who->getVictim() && me->IsFriendlyTo(who)
@@ -119,7 +103,6 @@ void CreatureAI::MoveInLineOfSight(Unit *who)
// && me->canStartAttack(who->getVictim(), true)) // TODO: if we use true, it will not attack it when it arrives
// me->GetMotionMaster()->MoveChase(who->getVictim());
}
void CreatureAI::SelectNearestTarget(Unit *who)
{
if(me->getVictim() && me->GetDistanceOrder(who, me->getVictim()) && me->canAttack(who))
@@ -128,14 +111,11 @@ void CreatureAI::SelectNearestTarget(Unit *who)
me->AddThreat(who, 1000000.0f);
}
}
void CreatureAI::EnterEvadeMode()
{
if(!_EnterEvadeMode())
return;
sLog.outDebug("Creature %u enters evade mode.", me->GetEntry());
if(!me->GetVehicle()) // otherwise me will be in evade mode forever
{
if(Unit *owner = me->GetCharmerOrOwner())
@@ -146,13 +126,10 @@ void CreatureAI::EnterEvadeMode()
else
me->GetMotionMaster()->MoveTargetedHome();
}
Reset();
if(me->IsVehicle()) // use the same sequence of addtoworld, aireset may remove all summons!
me->GetVehicleKit()->Reset();
}
/*void CreatureAI::AttackedBy( Unit* attacker )
{
if(!m_creature->getVictim())
+1 -50
View File
@@ -17,38 +17,29 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_CREATUREAI_H
#define TRINITY_CREATUREAI_H
#include "UnitAI.h"
#include "Common.h"
class WorldObject;
class Unit;
class Creature;
class Player;
struct SpellEntry;
#define TIME_INTERVAL_LOOK 5000
#define VISIBILITY_RANGE 10000
//Spell targets used by SelectSpell
enum SelectTargetType
{
SELECT_TARGET_DONTCARE = 0, //All target types allowed
SELECT_TARGET_SELF, //Only Self casting
SELECT_TARGET_SINGLE_ENEMY, //Only Single Enemy
SELECT_TARGET_AOE_ENEMY, //Only AoE Enemy
SELECT_TARGET_ANY_ENEMY, //AoE or Single Enemy
SELECT_TARGET_SINGLE_FRIEND, //Only Single Friend
SELECT_TARGET_AOE_FRIEND, //Only AoE Friend
SELECT_TARGET_ANY_FRIEND, //AoE or Single Friend
};
//Spell Effects used by SelectSpell
enum SelectEffect
{
@@ -57,123 +48,84 @@ enum SelectEffect
SELECT_EFFECT_HEALING, //Spell does healing
SELECT_EFFECT_AURA, //Spell applies an aura
};
enum SCEquip
{
EQUIP_NO_CHANGE = -1,
EQUIP_UNEQUIP = 0
};
class TRINITY_DLL_SPEC CreatureAI : public UnitAI
{
protected:
Creature * const me;
Creature * const m_creature;
bool UpdateVictim();
bool UpdateVictimWithGaze();
bool UpdateCombatState();
void SelectNearestTarget(Unit *who);
void SetGazeOn(Unit *target);
Creature *DoSummon(uint32 uiEntry, const Position &pos, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
Creature *DoSummon(uint32 uiEntry, WorldObject *obj, float fRadius = 5.0f, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
Creature *DoSummonFlyer(uint32 uiEntry, WorldObject *obj, float fZ, float fRadius = 5.0f, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN);
public:
explicit CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c), m_creature(c) {}
virtual ~CreatureAI() {}
///== Reactions At =================================
// Called if IsVisible(Unit *who) is true at each *who move, reaction at visibility zone enter
virtual void MoveInLineOfSight(Unit *);
// Called for reaction at stopping attack at no attackers or targets
virtual void EnterEvadeMode();
// Called for reaction at enter to combat if not in combat yet (enemy can be NULL)
virtual void EnterCombat(Unit* /*enemy*/) {}
// Called at any Damage from any attacker (before damage apply)
// Note: it for recalculation damage or special reaction at damage
// for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also
virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) {}
// Called when the creature is killed
virtual void JustDied(Unit *) {}
// Called when the creature kills a unit
virtual void KilledUnit(Unit *) {}
// Called when the creature summon successfully other creature
virtual void JustSummoned(Creature* ) {}
virtual void IsSummonedBy(Unit *summoner) {}
virtual void SummonedCreatureDespawn(Creature* /*unit*/) {}
// Called when hit by a spell
virtual void SpellHit(Unit*, const SpellEntry*) {}
// Called when spell hits a target
virtual void SpellHitTarget(Unit* target, const SpellEntry*) {}
// Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
//virtual void AttackedBy(Unit* attacker);
virtual bool IsEscorted() {return false;}
// Called when creature is spawned or respawned (for reseting variables)
virtual void JustRespawned() { Reset(); }
// Called at waypoint reached or point movement finished
virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {}
void OnCharmed(bool apply);
//virtual void SpellClick(Player *player) {}
// Called at reaching home after evade
virtual void JustReachedHome() {}
void DoZoneInCombat(Creature* pUnit = NULL);
// Called at text emote receive from player
// Called at text emote receive from player
virtual void ReceiveEmote(Player* pPlayer, uint32 text_emote) {}
///== Triggered Actions Requested ==================
// Called when creature attack expected (if creature can and no have current victim)
// Note: for reaction at hostile action must be called AttackedBy function.
//virtual void AttackStart(Unit *) {}
// Called at World update tick
//virtual void UpdateAI(const uint32 diff ) {}
///== State checks =================================
// Is unit visible for MoveInLineOfSight
//virtual bool IsVisible(Unit *) const { return false; }
// called when the corpse of this creature gets removed
virtual void CorpseRemoved(uint32 & /*respawnDelay*/) {}
// Called when victim entered water and creature can not enter water
//virtual bool canReachByRangeAttack(Unit*) { return false; }
///== Fields =======================================
// Pointer to controlled by AI creature
//Creature* const m_creature;
virtual void PassengerBoarded(Unit *who, int8 seatId, bool apply) {}
protected:
bool _EnterEvadeMode();
};
enum Permitions
{
PERMIT_BASE_NO = -1,
@@ -183,5 +135,4 @@ enum Permitions
PERMIT_BASE_FACTION_SPECIFIC = 400,
PERMIT_BASE_SPECIAL = 800
};
#endif
-7
View File
@@ -19,26 +19,20 @@
*/
#ifndef TRINITY_CREATUREAIFACTORY_H
#define TRINITY_CREATUREAIFACTORY_H
//#include "Policies/Singleton.h"
#include "Dynamic/ObjectRegistry.h"
#include "Dynamic/FactoryHolder.h"
struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
{
SelectableAI(const char *id) : FactoryHolder<CreatureAI>(id) {}
};
template<class REAL_AI>
struct CreatureAIFactory : public SelectableAI
{
CreatureAIFactory(const char *name) : SelectableAI(name) {}
CreatureAI* Create(void *) const;
int Permit(const Creature *c) const { return REAL_AI::Permissible(c); }
};
template<class REAL_AI>
inline CreatureAI*
CreatureAIFactory<REAL_AI>::Create(void *data) const
@@ -46,7 +40,6 @@ CreatureAIFactory<REAL_AI>::Create(void *data) const
Creature* creature = reinterpret_cast<Creature *>(data);
return (new REAL_AI(creature));
}
typedef FactoryHolder<CreatureAI> CreatureAICreator;
typedef FactoryHolder<CreatureAI>::FactoryHolderRegistry CreatureAIRegistry;
typedef FactoryHolder<CreatureAI>::FactoryHolderRepository CreatureAIRepository;
-60
View File
@@ -17,21 +17,17 @@
*/
#ifndef CREATUREAIIMPL_H
#define CREATUREAIIMPL_H
#include "Common.h"
#include "Platform/Define.h"
#include "TemporarySummon.h"
#include "CreatureAI.h"
#define HEROIC(n,h) (HeroicMode ? h : n)
template<class T>
inline
const T& RAND(const T& v1, const T& v2)
{
return (rand()%2) ? v1 : v2;
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3)
@@ -44,7 +40,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3)
case 2: return v3;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4)
@@ -58,7 +53,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4)
case 3: return v4;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
@@ -73,7 +67,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
case 4: return v5;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6)
@@ -89,7 +82,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 5: return v6;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7)
@@ -106,7 +98,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 6: return v7;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8)
@@ -124,7 +115,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 7: return v8;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
@@ -144,7 +134,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 8: return v9;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
@@ -165,7 +154,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 9: return v10;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
@@ -187,7 +175,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 10: return v11;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
@@ -210,7 +197,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 11: return v12;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
@@ -234,7 +220,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 12: return v13;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
@@ -259,7 +244,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 13: return v14;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
@@ -285,7 +269,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 14: return v15;
}
}
template<class T>
inline
const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
@@ -312,26 +295,20 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
case 15: return v16;
}
}
class EventMap : private std::map<uint32, uint32>
{
private:
uint32 m_time, m_phase;
public:
explicit EventMap() : m_phase(0), m_time(0) {}
uint32 GetTimer() const { return m_time; }
void Reset() { clear(); m_time = 0; m_phase = 0; }
void Update(uint32 time) { m_time += time; }
void SetPhase(uint32 phase)
{
if(phase && phase < 9)
m_phase = (1 << (phase + 24));
}
void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0)
{
time += m_time;
@@ -347,13 +324,11 @@ class EventMap : private std::map<uint32, uint32>
}
insert(std::make_pair(time, eventId));
}
void RescheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0)
{
CancelEvent(eventId);
ScheduleEvent(eventId, time, gcd, phase);
}
void RepeatEvent(uint32 time)
{
if(empty())
@@ -369,12 +344,10 @@ class EventMap : private std::map<uint32, uint32>
}
insert(std::make_pair(time, eventId));
}
void PopEvent()
{
erase(begin());
}
uint32 ExecuteEvent()
{
while(!empty())
@@ -392,7 +365,6 @@ class EventMap : private std::map<uint32, uint32>
}
return 0;
}
uint32 GetEvent()
{
while(!empty())
@@ -408,7 +380,6 @@ class EventMap : private std::map<uint32, uint32>
}
return 0;
}
void DelayEvents(uint32 time, uint32 gcd)
{
time += m_time;
@@ -426,7 +397,6 @@ class EventMap : private std::map<uint32, uint32>
++itr;
}
}
void CancelEvent(uint32 eventId)
{
for(iterator itr = begin(); itr != end();)
@@ -437,7 +407,6 @@ class EventMap : private std::map<uint32, uint32>
++itr;
}
}
void CancelEventsByGCD(uint32 gcd)
{
for(iterator itr = begin(); itr != end();)
@@ -449,7 +418,6 @@ class EventMap : private std::map<uint32, uint32>
}
}
};
enum AITarget
{
AITARGET_SELF,
@@ -459,16 +427,13 @@ enum AITarget
AITARGET_BUFF,
AITARGET_DEBUFF,
};
enum AICondition
{
AICOND_AGGRO,
AICOND_COMBAT,
AICOND_DIE,
};
#define AI_DEFAULT_COOLDOWN 5000
struct AISpellInfoType
{
AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT)
@@ -479,10 +444,8 @@ struct AISpellInfoType
uint32 realCooldown;
float maxRange;
};
TRINITY_DLL_SPEC AISpellInfoType * GetAISpellInfo(uint32 i);
inline void CreatureAI::SetGazeOn(Unit *target)
{
if(me->canAttack(target))
@@ -491,12 +454,10 @@ inline void CreatureAI::SetGazeOn(Unit *target)
me->SetReactState(REACT_PASSIVE);
}
}
inline bool CreatureAI::UpdateVictimWithGaze()
{
if(!me->isInCombat())
return false;
if(me->HasReactState(REACT_PASSIVE))
{
if(me->getVictim())
@@ -504,17 +465,14 @@ inline bool CreatureAI::UpdateVictimWithGaze()
else
me->SetReactState(REACT_AGGRESSIVE);
}
if(Unit *victim = me->SelectVictim())
AttackStart(victim);
return me->getVictim();
}
inline bool CreatureAI::UpdateCombatState()
{
if(!me->isInCombat())
return false;
if(!me->HasReactState(REACT_PASSIVE))
{
if(Unit *victim = me->SelectVictim())
@@ -526,15 +484,12 @@ inline bool CreatureAI::UpdateCombatState()
EnterEvadeMode();
return false;
}
return true;
}
inline bool CreatureAI::UpdateVictim()
{
if(!me->isInCombat())
return false;
if(!me->HasReactState(REACT_PASSIVE))
{
if(Unit *victim = me->SelectVictim())
@@ -546,10 +501,8 @@ inline bool CreatureAI::UpdateVictim()
EnterEvadeMode();
return false;
}
return true;
}
/*
inline bool CreatureAI::UpdateVictim()
{
@@ -560,12 +513,10 @@ inline bool CreatureAI::UpdateVictim()
return me->getVictim();
}
*/
inline bool CreatureAI::_EnterEvadeMode()
{
if(!me->isAlive())
return false;
// sometimes bosses stuck in combat?
me->RemoveAllAuras();
me->DeleteThreatList();
@@ -573,46 +524,36 @@ inline bool CreatureAI::_EnterEvadeMode()
me->LoadCreaturesAddon();
me->SetLootRecipient(NULL);
me->ResetPlayerDamageReq();
if(me->IsInEvadeMode())
return false;
return true;
}
inline void UnitAI::DoCast(Unit* victim, uint32 spellId, bool triggered)
{
if(!victim || me->hasUnitState(UNIT_STAT_CASTING) && !triggered)
return;
me->CastSpell(victim, spellId, triggered);
}
inline void UnitAI::DoCastVictim(uint32 spellId, bool triggered)
{
me->CastSpell(me->getVictim(), spellId, triggered);
}
inline void UnitAI::DoCastAOE(uint32 spellId, bool triggered)
{
if(!triggered && me->hasUnitState(UNIT_STAT_CASTING))
return;
me->CastSpell((Unit*)NULL, spellId, triggered);
}
inline Creature *CreatureAI::DoSummon(uint32 uiEntry, const Position &pos, uint32 uiDespawntime, TempSummonType uiType)
{
return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime);
}
inline Creature *CreatureAI::DoSummon(uint32 uiEntry, WorldObject* obj, float fRadius, uint32 uiDespawntime, TempSummonType uiType)
{
Position pos;
obj->GetRandomNearPosition(pos, fRadius);
return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime);
}
inline Creature *CreatureAI::DoSummonFlyer(uint32 uiEntry, WorldObject *obj, float _fZ, float fRadius, uint32 uiDespawntime, TempSummonType uiType)
{
Position pos;
@@ -620,6 +561,5 @@ inline Creature *CreatureAI::DoSummonFlyer(uint32 uiEntry, WorldObject *obj, flo
pos.m_positionZ += _fZ;
return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime);
}
#endif
-3
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "PassiveAI.h"
#include "ReactorAI.h"
#include "CombatAI.h"
@@ -30,7 +29,6 @@
#include "CreatureAIRegistry.h"
#include "WaypointMovementGenerator.h"
#include "CreatureAIFactory.h"
//#include "CreatureAIImpl.h"
namespace AIRegistry
{
@@ -49,7 +47,6 @@ namespace AIRegistry
(new CreatureAIFactory<ArchorAI>("ArchorAI"))->RegisterSelf();
(new CreatureAIFactory<TurretAI>("TurretAI"))->RegisterSelf();
(new CreatureAIFactory<CreatureEventAI>("EventAI"))->RegisterSelf();
(new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf();
(new MovementGeneratorFactory<WaypointMovementGenerator<Creature> >(WAYPOINT_MOTION_TYPE))->RegisterSelf();
}
-2
View File
@@ -17,10 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_CREATUREAIREGISTRY_H
#define TRINITY_CREATUREAIREGISTRY_H
namespace AIRegistry
{
void Initialize(void);
-15
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Creature.h"
#include "CreatureAISelector.h"
#include "PassiveAI.h"
@@ -27,30 +26,24 @@
#include "Pet.h"
#include "TemporarySummon.h"
#include "CreatureAIFactory.h"
INSTANTIATE_SINGLETON_1(CreatureAIRegistry);
INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry);
namespace FactorySelector
{
CreatureAI* selectAI(Creature *creature)
{
const CreatureAICreator *ai_factory = NULL;
CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance());
if(creature->isPet())
ai_factory = ai_registry.GetRegistryItem("PetAI");
//scriptname in db
if(!ai_factory)
if(CreatureAI* scriptedAI = Script->GetAI(creature))
return scriptedAI;
// AIname in db
std::string ainame=creature->GetAIName();
if(!ai_factory && !ainame.empty())
ai_factory = ai_registry.GetRegistryItem( ainame.c_str() );
// select by NPC flags
if(!ai_factory)
{
@@ -74,7 +67,6 @@ namespace FactorySelector
else if(creature->GetCreatureType() == CREATURE_TYPE_CRITTER && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
ai_factory = ai_registry.GetRegistryItem("CritterAI");
}
if(!ai_factory)
{
for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
@@ -86,7 +78,6 @@ namespace FactorySelector
}
}
}
// select by permit check
if(!ai_factory)
{
@@ -106,20 +97,16 @@ namespace FactorySelector
}
}
}
// select NullCreatureAI if not another cases
ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();
DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() );
return ( ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature) );
}
MovementGenerator* selectMovementGenerator(Creature *creature)
{
MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance());
assert( creature->GetCreatureInfo() != NULL );
const MovementGeneratorCreator *mv_factory = mv_registry.GetRegistryItem( creature->GetDefaultMovementType());
/* if( mv_factory == NULL )
{
int best_val = -1;
@@ -138,9 +125,7 @@ namespace FactorySelector
}
}
}*/
return ( mv_factory == NULL ? NULL : mv_factory->Create(creature) );
}
}
-3
View File
@@ -17,14 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_CREATUREAISELECTOR_H
#define TRINITY_CREATUREAISELECTOR_H
class CreatureAI;
class Creature;
class MovementGenerator;
namespace FactorySelector
{
CreatureAI* selectAI(Creature *);
-171
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "CreatureEventAI.h"
#include "CreatureEventAIMgr.h"
@@ -32,7 +31,6 @@
#include "InstanceData.h"
#include "SpellMgr.h"
#include "CreatureAIImpl.h"
bool CreatureEventAIHolder::UpdateRepeatTimer( Creature* creature, uint32 repeatMin, uint32 repeatMax )
{
if (repeatMin == repeatMax)
@@ -45,17 +43,14 @@ bool CreatureEventAIHolder::UpdateRepeatTimer( Creature* creature, uint32 repeat
Enabled = false;
return false;
}
return true;
}
int CreatureEventAI::Permissible(const Creature *creature)
{
if( creature->GetAIName() == "EventAI" )
return PERMIT_BASE_SPECIAL;
return PERMIT_BASE_NO;
}
CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c)
{
// Need make copy for filter unneeded steps and safe in case table reload
@@ -65,7 +60,6 @@ CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c)
std::vector<CreatureEventAI_Event>::const_iterator i;
for (i = (*CreatureEvents).second.begin(); i != (*CreatureEvents).second.end(); ++i)
{
//Debug check
#ifndef TRINITY_DEBUG
if ((*i).event_flags & EFLAG_DEBUG_ONLY)
@@ -89,16 +83,13 @@ CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c)
}
else
sLog.outError("CreatureEventAI: EventMap for Creature %u is empty but creature is using CreatureEventAI.", m_creature->GetEntry());
bEmptyList = CreatureEventAIList.empty();
Phase = 0;
CombatMovementEnabled = true;
MeleeEnabled = true;
AttackDistance = 0.0f;
AttackAngle = 0.0f;
InvinceabilityHpLevel = 0;
//Handle Spawned Events
if (!bEmptyList)
{
@@ -107,32 +98,26 @@ CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c)
ProcessEvent(*i);
}
}
bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker)
{
if (!pHolder.Enabled || pHolder.Time)
return false;
//Check the inverse phase mask (event doesn't trigger if current phase bit is set in mask)
if (pHolder.Event.event_inverse_phase_mask & (1 << Phase))
return false;
CreatureEventAI_Event const& event = pHolder.Event;
//Check event conditions based on the event type, also reset events
switch (event.event_type)
{
case EVENT_T_TIMER:
if (!m_creature->isInCombat())
return false;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.timer.repeatMin,event.timer.repeatMax);
break;
case EVENT_T_TIMER_OOC:
if (m_creature->isInCombat())
return false;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.timer.repeatMin,event.timer.repeatMax);
break;
@@ -140,12 +125,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
{
if (!m_creature->isInCombat() || !m_creature->GetMaxHealth())
return false;
uint32 perc = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth();
if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
return false;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax);
break;
@@ -154,12 +136,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
{
if (!m_creature->isInCombat() || !m_creature->GetMaxPower(POWER_MANA))
return false;
uint32 perc = (m_creature->GetPower(POWER_MANA)*100) / m_creature->GetMaxPower(POWER_MANA);
if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
return false;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax);
break;
@@ -175,7 +154,6 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
break;
case EVENT_T_SPELLHIT:
//Spell hit is special case, param1 and param2 handled within CreatureEventAI::SpellHit
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.spell_hit.repeatMin,event.spell_hit.repeatMax);
break;
@@ -193,12 +171,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
{
if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxHealth())
return false;
uint32 perc = (m_creature->getVictim()->GetHealth()*100) / m_creature->getVictim()->GetMaxHealth();
if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
return false;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax);
break;
@@ -206,7 +181,6 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
case EVENT_T_TARGET_CASTING:
if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->IsNonMeleeSpellCasted(false, false, true))
return false;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.target_casting.repeatMin,event.target_casting.repeatMax);
break;
@@ -214,13 +188,10 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
{
if (!m_creature->isInCombat())
return false;
Unit* pUnit = DoSelectLowestHpFriendly(event.friendly_hp.radius, event.friendly_hp.hpDeficit);
if (!pUnit)
return false;
pActionInvoker = pUnit;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.friendly_hp.repeatMin,event.friendly_hp.repeatMax);
break;
@@ -229,17 +200,13 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
{
if (!m_creature->isInCombat())
return false;
std::list<Creature*> pList;
DoFindFriendlyCC(pList, event.friendly_is_cc.radius);
//List is empty
if (pList.empty())
return false;
//We don't really care about the whole list, just return first available
pActionInvoker = *(pList.begin());
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.friendly_is_cc.repeatMin,event.friendly_is_cc.repeatMax);
break;
@@ -248,14 +215,11 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
{
std::list<Creature*> pList;
DoFindFriendlyMissingBuff(pList, event.friendly_buff.radius, event.friendly_buff.spellId);
//List is empty
if (pList.empty())
return false;
//We don't really care about the whole list, just return first available
pActionInvoker = *(pList.begin());
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.friendly_buff.repeatMin,event.friendly_buff.repeatMax);
break;
@@ -265,11 +229,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
//Prevent event from occuring on no unit or non creatures
if (!pActionInvoker || pActionInvoker->GetTypeId()!=TYPEID_UNIT)
return false;
//Creature id doesn't match up
if (((Creature*)pActionInvoker)->GetEntry() != event.summon_unit.creatureId)
return false;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.summon_unit.repeatMin,event.summon_unit.repeatMax);
break;
@@ -278,12 +240,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
{
if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxPower(POWER_MANA))
return false;
uint32 perc = (m_creature->getVictim()->GetPower(POWER_MANA)*100) / m_creature->getVictim()->GetMaxPower(POWER_MANA);
if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
return false;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax);
break;
@@ -298,7 +257,6 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
Aura* aura = m_creature->GetAura(event.buffed.spellId,0);
if(!aura || aura->GetStackAmount() < event.buffed.amount)
return false;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.buffed.repeatMin,event.buffed.repeatMax);
break;
@@ -308,13 +266,11 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
//Prevent event from occuring on no unit
if (!pActionInvoker)
return false;
//Note: checked only aura for effect 0, if need check aura for effect 1/2 then
// possible way: pack in event.buffed.amount 2 uint16 (ammount+effectIdx)
Aura* aura = pActionInvoker->GetAura(event.buffed.spellId,0);
if(!aura || aura->GetStackAmount() < event.buffed.amount)
return false;
//Repeat Timers
pHolder.UpdateRepeatTimer(m_creature,event.buffed.repeatMin,event.buffed.repeatMax);
break;
@@ -323,25 +279,19 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type);
break;
}
//Disable non-repeatable events
if (!(pHolder.Event.event_flags & EFLAG_REPEATABLE))
pHolder.Enabled = false;
//Store random here so that all random actions match up
uint32 rnd = rand();
//Return if chance for event is not met
if (pHolder.Event.event_chance <= rnd % 100)
return false;
//Process actions
for (uint32 j = 0; j < MAX_ACTIONS; j++)
ProcessAction(pHolder.Event.action[j], rnd, pHolder.Event.event_id, pActionInvoker);
return true;
}
void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 EventId, Unit* pActionInvoker)
{
switch (action.type)
@@ -350,20 +300,16 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
{
if (!action.text.TextId1)
return;
int32 temp = 0;
if (action.text.TextId2 && action.text.TextId3)
temp = RAND(action.text.TextId1,action.text.TextId2,action.text.TextId3);
else if (action.text.TextId2 && urand(0,1))
temp = action.text.TextId2;
else
temp = action.text.TextId1;
if (temp)
{
Unit* target = NULL;
if (pActionInvoker)
{
if (pActionInvoker->GetTypeId() == TYPEID_PLAYER)
@@ -381,7 +327,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
if (owner->GetTypeId() == TYPEID_PLAYER)
target = owner;
}
DoScriptText(temp, m_creature, target);
}
break;
@@ -446,27 +391,21 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
{
Unit* target = GetTargetByType(action.cast.target, pActionInvoker);
Unit* caster = m_creature;
if (!target)
return;
if (action.cast.castFlags & CAST_FORCE_TARGET_SELF)
caster = target;
//Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered
bool canCast = !caster->IsNonMeleeSpellCasted(false) || (action.cast.castFlags & (CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS));
// If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them
if(action.cast.castFlags & CAST_AURA_NOT_PRESENT)
{
if(target->HasAura(action.cast.spellId))
return;
}
if (canCast)
{
const SpellEntry* tSpell = GetSpellStore()->LookupEntry(action.cast.spellId);
//Verify that spell exists
if (tSpell)
{
@@ -481,21 +420,17 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
{
AttackDistance = 0.0f;
AttackAngle = 0.0f;
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
}
}
}
else
{
//Interrupt any previous spell
if (caster->IsNonMeleeSpellCasted(false) && action.cast.castFlags & CAST_INTURRUPT_PREVIOUS)
caster->InterruptNonMeleeSpells(false);
caster->CastSpell(target, action.cast.spellId, (action.cast.castFlags & CAST_TRIGGERED));
}
}
else
sLog.outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature->GetEntry(), action.cast.spellId);
@@ -505,14 +440,11 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
case ACTION_T_SUMMON:
{
Unit* target = GetTargetByType(action.summon.target, pActionInvoker);
Creature* pCreature = NULL;
if (action.summon.duration)
pCreature = m_creature->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, action.summon.duration);
else
pCreature = m_creature->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
if (!pCreature)
sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", action.summon.creatureId, EventId, m_creature->GetEntry());
else if (action.summon.target != TARGET_T_SELF && target)
@@ -544,14 +476,11 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
case ACTION_T_SET_UNIT_FIELD:
{
Unit* target = GetTargetByType(action.set_unit_field.target, pActionInvoker);
// not allow modify important for integrity object fields
if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END)
return;
if (target)
target->SetUInt32Value(action.set_unit_field.field, action.set_unit_field.value);
break;
}
case ACTION_T_SET_UNIT_FLAG:
@@ -569,16 +498,13 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
// ignore no affect case
if(CombatMovementEnabled==(action.combat_movement.state!=0))
return;
CombatMovementEnabled = action.combat_movement.state != 0;
//Allow movement (create new targeted movement gen only if idle)
if (CombatMovementEnabled)
{
if(action.combat_movement.melee && m_creature->isInCombat())
if(Unit* victim = m_creature->getVictim())
m_creature->SendMeleeAttackStart(victim);
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
}
else
@@ -586,7 +512,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
if(action.combat_movement.melee && m_creature->isInCombat())
if(Unit* victim = m_creature->getVictim())
m_creature->SendMeleeAttackStop(victim);
m_creature->GetMotionMaster()->MoveIdle();
}
break;
@@ -608,7 +533,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
}
else
Phase = new_phase;
break;
}
case ACTION_T_EVADE:
@@ -641,7 +565,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
case ACTION_T_RANGED_MOVEMENT:
AttackDistance = (float)action.ranged_movement.distance;
AttackAngle = action.ranged_movement.angle/180.0f*M_PI;
if (CombatMovementEnabled)
{
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
@@ -659,25 +582,21 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
case ACTION_T_SUMMON_ID:
{
Unit* target = GetTargetByType(action.summon_id.target, pActionInvoker);
CreatureEventAI_Summon_Map::const_iterator i = CreatureEAI_Mgr.GetCreatureEventAISummonMap().find(action.summon_id.spawnId);
if (i == CreatureEAI_Mgr.GetCreatureEventAISummonMap().end())
{
sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", action.summon_id.creatureId, action.summon_id.spawnId, EventId, m_creature->GetEntry());
return;
}
Creature* pCreature = NULL;
if ((*i).second.SpawnTimeSecs)
pCreature = m_creature->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs);
else
pCreature = m_creature->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
if (!pCreature)
sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", action.summon_id.creatureId, EventId, m_creature->GetEntry());
else if (action.summon_id.target != TARGET_T_SELF && target)
pCreature->AI()->AttackStart(target);
break;
}
case ACTION_T_KILLED_MONSTER:
@@ -700,7 +619,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data without instance script. Creature %d", EventId, m_creature->GetEntry());
return;
}
pInst->SetData(action.set_inst_data.field, action.set_inst_data.value);
break;
}
@@ -712,31 +630,26 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", EventId, m_creature->GetEntry());
return;
}
InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData();
if (!pInst)
{
sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 without instance script. Creature %d", EventId, m_creature->GetEntry());
return;
}
pInst->SetData64(action.set_inst_data64.field, target->GetGUID());
break;
}
case ACTION_T_UPDATE_TEMPLATE:
if (m_creature->GetEntry() == action.update_template.creatureId)
{
sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", EventId, m_creature->GetEntry());
return;
}
m_creature->UpdateEntry(action.update_template.creatureId, action.update_template.team ? HORDE : ALLIANCE);
break;
case ACTION_T_DIE:
if (m_creature->isDead())
{
sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_DIE on dead creature. Creature %d", EventId, m_creature->GetEntry());
return;
}
@@ -753,7 +666,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
break;
}
break;
// TRINITY ONLY
case ACTION_T_SET_ACTIVE:
me->setActive(action.raw.param1 ? true : false);
@@ -767,7 +679,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
case ACTION_T_SUMMON_GO:
{
GameObject* pObject = NULL;
float x,y,z;
m_creature->GetPosition(x,y,z);
pObject = m_creature->SummonGameObject(action.raw.param1, x, y, z, 0, 0, 0, 0, 0, action.raw.param2);
@@ -777,7 +688,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
}
break;
}
case ACTION_T_SET_SHEATH:
{
m_creature->SetSheath(SheathState(action.set_sheath.sheath));
@@ -798,28 +708,22 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
}
}
}
void CreatureEventAI::JustRespawned()
{
Reset();
if (bEmptyList)
return;
//Handle Spawned Events
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
if (SpawnedEventConditionsCheck((*i).Event))
ProcessEvent(*i);
}
void CreatureEventAI::Reset()
{
EventUpdateTime = EVENT_UPDATE_TIME;
EventDiff = 0;
if (bEmptyList)
return;
//Reset all events to enabled
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
{
@@ -841,11 +745,9 @@ void CreatureEventAI::Reset()
}
}
}
void CreatureEventAI::JustReachedHome()
{
m_creature->LoadCreaturesAddon();
if (!bEmptyList)
{
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
@@ -854,17 +756,13 @@ void CreatureEventAI::JustReachedHome()
ProcessEvent(*i);
}
}
Reset();
}
void CreatureEventAI::EnterEvadeMode()
{
CreatureAI::EnterEvadeMode();
if (bEmptyList)
return;
//Handle Evade events
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
{
@@ -872,49 +770,40 @@ void CreatureEventAI::EnterEvadeMode()
ProcessEvent(*i);
}
}
void CreatureEventAI::JustDied(Unit* killer)
{
Reset();
if (bEmptyList)
return;
//Handle Evade events
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
{
if ((*i).Event.event_type == EVENT_T_DEATH)
ProcessEvent(*i, killer);
}
// reset phase after any death state events
Phase = 0;
}
void CreatureEventAI::KilledUnit(Unit* victim)
{
if (bEmptyList || victim->GetTypeId() != TYPEID_PLAYER)
return;
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
{
if ((*i).Event.event_type == EVENT_T_KILL)
ProcessEvent(*i, victim);
}
}
void CreatureEventAI::JustSummoned(Creature* pUnit)
{
if (bEmptyList || !pUnit)
return;
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
{
if ((*i).Event.event_type == EVENT_T_SUMMONED_UNIT)
ProcessEvent(*i, pUnit);
}
}
void CreatureEventAI::EnterCombat(Unit *enemy)
{
//Check for on combat start events
@@ -942,16 +831,13 @@ void CreatureEventAI::EnterCombat(Unit *enemy)
}
}
}
EventUpdateTime = EVENT_UPDATE_TIME;
EventDiff = 0;
}
void CreatureEventAI::AttackStart(Unit *who)
{
if (!who)
return;
if (m_creature->Attack(who, MeleeEnabled))
{
if (CombatMovementEnabled)
@@ -964,12 +850,10 @@ void CreatureEventAI::AttackStart(Unit *who)
}
}
}
void CreatureEventAI::MoveInLineOfSight(Unit *who)
{
if(me->getVictim())
return;
//Check for OOC LOS Event
if (!bEmptyList)
{
@@ -979,7 +863,6 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
{
//can trigger if closer than fMaxAllowedRange
float fMaxAllowedRange = (*itr).Event.ooc_los.maxRange;
//if range is ok and we are actually in LOS
if (m_creature->IsWithinDistInMap(who, fMaxAllowedRange) && m_creature->IsWithinLOSInMap(who))
{
@@ -991,16 +874,12 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who)
}
}
}
CreatureAI::MoveInLineOfSight(who);
}
void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell)
{
if (bEmptyList)
return;
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
if ((*i).Event.event_type == EVENT_T_SPELLHIT)
//If spell id matches (or no spell id) & if spell school matches (or no spell school)
@@ -1008,19 +887,16 @@ void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell)
if (pSpell->SchoolMask & (*i).Event.spell_hit.schoolMask)
ProcessEvent(*i, pUnit);
}
void CreatureEventAI::UpdateAI(const uint32 diff)
{
//Check if we are in combat (also updates calls threat update code)
bool Combat = UpdateVictim();
if (!bEmptyList)
{
//Events are only updated once every EVENT_UPDATE_TIME ms to prevent lag with large amount of events
if (EventUpdateTime < diff)
{
EventDiff += diff;
//Check for time based events
for (std::list<CreatureEventAIHolder>::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i)
{
@@ -1032,13 +908,11 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
//Do not decrement timers if event cannot trigger in this phase
if (!((*i).Event.event_inverse_phase_mask & (1 << Phase)))
(*i).Time -= EventDiff;
//Skip processing of events that have time remaining
continue;
}
else (*i).Time = 0;
}
//Events that are updated every EVENT_UPDATE_TIME
switch ((*i).Event.event_type)
{
@@ -1062,7 +936,6 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
break;
}
}
EventDiff = 0;
EventUpdateTime = EVENT_UPDATE_TIME;
}
@@ -1072,22 +945,18 @@ void CreatureEventAI::UpdateAI(const uint32 diff)
EventUpdateTime -= diff;
}
}
//Melee Auto-Attack
if (Combat && MeleeEnabled)
DoMeleeAttackIfReady();
}
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
{
//ThreatList m_threatlist;
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
std::list<HostilReference*>::iterator i = m_threatlist.begin();
std::list<HostilReference*>::reverse_iterator r = m_threatlist.rbegin();
if (position >= m_threatlist.size() || !m_threatlist.size())
return NULL;
switch (target)
{
case ATTACKING_TARGET_RANDOM:
@@ -1108,7 +977,6 @@ inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position
}
return NULL;
}
inline uint32 CreatureEventAI::GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3)
{
switch (rnd % 3)
@@ -1119,7 +987,6 @@ inline uint32 CreatureEventAI::GetRandActionParam(uint32 rnd, uint32 param1, uin
}
return 0;
}
inline int32 CreatureEventAI::GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3)
{
switch (rnd % 3)
@@ -1130,7 +997,6 @@ inline int32 CreatureEventAI::GetRandActionParam(uint32 rnd, int32 param1, int32
}
return 0;
}
inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoker)
{
switch (Target)
@@ -1153,65 +1019,50 @@ inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoke
return NULL;
};
}
Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
{
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
Unit* pUnit = NULL;
MaNGOS::MostHPMissingInRange u_check(m_creature, range, MinHPDiff);
MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange> searcher(m_creature, pUnit, u_check);
/*
typedef TYPELIST_4(GameObject, Creature*except pets*, DynamicObject, Corpse*Bones*) AllGridObjectTypes;
This means that if we only search grid then we cannot possibly return pets or players so this is safe
*/
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature->GetMap(), *m_creature, range);
return pUnit;
}
void CreatureEventAI::DoFindFriendlyCC(std::list<Creature*>& _list, float range)
{
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::FriendlyCCedInRange u_check(m_creature, range);
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange> searcher(m_creature, _list, u_check);
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyCCedInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap());
}
void CreatureEventAI::DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid)
{
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::FriendlyMissingBuffInRange u_check(m_creature, range, spellid);
MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange> searcher(m_creature, _list, u_check);
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap());
}
//*********************************
//*** Functions used globally ***
void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target)
{
if (!pSource)
@@ -1219,23 +1070,18 @@ void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit*
sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i, invalid Source pointer.",textEntry);
return;
}
if (textEntry >= 0)
{
sLog.outErrorDb("CreatureEventAI: DoScriptText with source entry %u (TypeId=%u, guid=%u) attempts to process text entry %i, but text entry must be negative.",pSource->GetEntry(),pSource->GetTypeId(),pSource->GetGUIDLow(),textEntry);
return;
}
CreatureEventAI_TextMap::const_iterator i = CreatureEAI_Mgr.GetCreatureEventAITextMap().find(textEntry);
if (i == CreatureEAI_Mgr.GetCreatureEventAITextMap().end())
{
sLog.outErrorDb("CreatureEventAI: DoScriptText with source entry %u (TypeId=%u, guid=%u) could not find text entry %i.",pSource->GetEntry(),pSource->GetTypeId(),pSource->GetGUIDLow(),textEntry);
return;
}
sLog.outDebug("CreatureEventAI: DoScriptText: text entry=%i, Sound=%u, Type=%u, Language=%u, Emote=%u",textEntry,(*i).second.SoundId,(*i).second.Type,(*i).second.Language,(*i).second.Emote);
if((*i).second.SoundId)
{
if (GetSoundEntriesStore()->LookupEntry((*i).second.SoundId))
@@ -1243,7 +1089,6 @@ void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit*
else
sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i tried to process invalid sound id %u.",textEntry,(*i).second.SoundId);
}
if((*i).second.Emote)
{
if (pSource->GetTypeId() == TYPEID_UNIT || pSource->GetTypeId() == TYPEID_PLAYER)
@@ -1253,7 +1098,6 @@ void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit*
else
sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i tried to process emote for invalid TypeId (%u).",textEntry,pSource->GetTypeId());
}
switch((*i).second.Type)
{
case CHAT_TYPE_SAY:
@@ -1285,48 +1129,37 @@ void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit*
break;
}
}
bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered)
{
//No target so we can't cast
if (!Target || !Spell)
return false;
//Silenced so we can't cast
if (!Triggered && me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
return false;
//Check for power
if (!Triggered && me->GetPower((Powers)Spell->powerType) < CalculatePowerCost(Spell, me, GetSpellSchoolMask(Spell)))
return false;
SpellRangeEntry const *TempRange = NULL;
TempRange = GetSpellRangeStore()->LookupEntry(Spell->rangeIndex);
//Spell has invalid range store so we can't use it
if (!TempRange)
return false;
//Unit is out of range of this spell
if (!m_creature->IsInRange(Target,TempRange->minRangeHostile,TempRange->maxRangeHostile))
return false;
return true;
}
void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote)
{
if (bEmptyList)
return;
for (std::list<CreatureEventAIHolder>::iterator itr = CreatureEventAIList.begin(); itr != CreatureEventAIList.end(); ++itr)
{
if ((*itr).Event.event_type == EVENT_T_RECEIVE_EMOTE)
{
if ((*itr).Event.receive_emote.emoteId != text_emote)
return;
PlayerCondition pcon((*itr).Event.receive_emote.condition,(*itr).Event.receive_emote.conditionValue1,(*itr).Event.receive_emote.conditionValue2);
if (pcon.Meets(pPlayer))
{
@@ -1336,7 +1169,6 @@ void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote)
}
}
}
void CreatureEventAI::DamageTaken( Unit* done_by, uint32& damage )
{
if(InvinceabilityHpLevel > 0 && m_creature->GetHealth() < InvinceabilityHpLevel+damage)
@@ -1347,12 +1179,10 @@ void CreatureEventAI::DamageTaken( Unit* done_by, uint32& damage )
damage = m_creature->GetHealth() - InvinceabilityHpLevel;
}
}
bool CreatureEventAI::SpawnedEventConditionsCheck(CreatureEventAI_Event const& event)
{
if(event.event_type != EVENT_T_SPAWNED)
return false;
switch (event.spawned.condition)
{
case SPAWNED_EVENT_ALWAY:
@@ -1371,6 +1201,5 @@ bool CreatureEventAI::SpawnedEventConditionsCheck(CreatureEventAI_Event const& e
default:
break;
}
return false;
}
-41
View File
@@ -15,22 +15,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MANGOS_CREATURE_EAI_H
#define MANGOS_CREATURE_EAI_H
#include "Common.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "Unit.h"
class Player;
class WorldObject;
#define EVENT_UPDATE_TIME 500
#define MAX_ACTIONS 3
#define MAX_PHASE 32
enum EventAI_Type
{
EVENT_T_TIMER = 0, // InitialMin, InitialMax, RepeatMin, RepeatMax
@@ -58,10 +53,8 @@ enum EventAI_Type
EVENT_T_RECEIVE_EMOTE = 22, // EmoteId, Condition, CondValue1, CondValue2
EVENT_T_BUFFED = 23, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max
EVENT_T_TARGET_BUFFED = 24, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max
EVENT_T_END,
};
enum EventAI_ActionType
{
ACTION_T_NONE = 0, // No action
@@ -105,44 +98,35 @@ enum EventAI_ActionType
ACTION_T_ZONE_COMBAT_PULSE = 38, // No Params
ACTION_T_CALL_FOR_HELP = 39, // Radius
ACTION_T_SET_SHEATH = 40, // Sheath (0-passive,1-melee,2-ranged)
ACTION_T_SET_ACTIVE = 101, //Apply
ACTION_T_SET_AGGRESSIVE = 102, //Apply
ACTION_T_ATTACK_START_PULSE = 103, //Distance
ACTION_T_SUMMON_GO = 104, //GameObjectID, DespawnTime in ms
ACTION_T_FORCE_DESPAWN = 41, // No Params
ACTION_T_END = 105,
ACTION_T_SET_INVINCIBILITY_HP_LEVEL = 42, // MinHpValue, format(0-flat,1-percent from max health)
};
enum Target
{
//Self (m_creature)
TARGET_T_SELF = 0, //Self cast
//Hostile targets (if pet then returns pet owner)
TARGET_T_HOSTILE, //Our current target (ie: highest aggro)
TARGET_T_HOSTILE_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
TARGET_T_HOSTILE_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
TARGET_T_HOSTILE_RANDOM, //Just any random target on our threat list
TARGET_T_HOSTILE_RANDOM_NOT_TOP, //Any random target except top threat
//Invoker targets (if pet then returns pet owner)
TARGET_T_ACTION_INVOKER, //Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF)
//Hostile targets (including pets)
TARGET_T_HOSTILE_WPET, //Current target (can be a pet)
TARGET_T_HOSTILE_WPET_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
TARGET_T_HOSTILE_WPET_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
TARGET_T_HOSTILE_WPET_RANDOM, //Just any random target on our threat list
TARGET_T_HOSTILE_WPET_RANDOM_NOT_TOP, //Any random target except top threat
TARGET_T_ACTION_INVOKER_WPET,
TARGET_T_END
};
enum CastFlags
{
CAST_INTURRUPT_PREVIOUS = 0x01, //Interrupt any spell casting
@@ -152,7 +136,6 @@ enum CastFlags
CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself
CAST_AURA_NOT_PRESENT = 0x20, //Only casts the spell if the target does not have an aura from the spell
};
enum EventFlags
{
EFLAG_REPEATABLE = 0x01, //Event repeats
@@ -164,14 +147,12 @@ enum EventFlags
EFLAG_RESERVED_6 = 0x40,
EFLAG_DEBUG_ONLY = 0x80, //Event only occurs in debug build
};
enum SpawnedEventMode
{
SPAWNED_EVENT_ALWAY = 0,
SPAWNED_EVENT_MAP = 1,
SPAWNED_EVENT_ZONE = 2
};
// String text additional data, used in (CreatureEventAI)
struct StringTextData
{
@@ -182,7 +163,6 @@ struct StringTextData
};
// Text Maps
typedef UNORDERED_MAP<int32, StringTextData> CreatureEventAI_TextMap;
struct CreatureEventAI_Action
{
EventAI_ActionType type: 16;
@@ -395,19 +375,14 @@ struct CreatureEventAI_Action
} raw;
};
};
struct CreatureEventAI_Event
{
uint32 event_id;
uint32 creature_id;
uint32 event_inverse_phase_mask;
EventAI_Type event_type : 16;
uint8 event_chance : 8;
uint8 event_flags : 8;
union
{
// EVENT_T_TIMER = 0
@@ -526,7 +501,6 @@ struct CreatureEventAI_Event
uint32 repeatMin;
uint32 repeatMax;
} buffed;
// RAW
struct
{
@@ -536,41 +510,32 @@ struct CreatureEventAI_Event
uint32 param4;
} raw;
};
CreatureEventAI_Action action[MAX_ACTIONS];
};
//Event_Map
typedef UNORDERED_MAP<uint32, std::vector<CreatureEventAI_Event> > CreatureEventAI_Event_Map;
struct CreatureEventAI_Summon
{
uint32 id;
float position_x;
float position_y;
float position_z;
float orientation;
uint32 SpawnTimeSecs;
};
//EventSummon_Map
typedef UNORDERED_MAP<uint32, CreatureEventAI_Summon> CreatureEventAI_Summon_Map;
struct CreatureEventAIHolder
{
CreatureEventAIHolder(CreatureEventAI_Event p) : Event(p), Time(0), Enabled(true){}
CreatureEventAI_Event Event;
uint32 Time;
bool Enabled;
// helper
bool UpdateRepeatTimer(Creature* creature, uint32 repeatMin, uint32 repeatMax);
};
class TRINITY_DLL_SPEC CreatureEventAI : public CreatureAI
{
public:
explicit CreatureEventAI(Creature *c);
~CreatureEventAI()
@@ -592,29 +557,23 @@ class TRINITY_DLL_SPEC CreatureEventAI : public CreatureAI
void UpdateAI(const uint32 diff);
void ReceiveEmote(Player* pPlayer, uint32 text_emote);
static int Permissible(const Creature *);
bool ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker = NULL);
void ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 EventId, Unit* pActionInvoker);
inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3);
inline int32 GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3);
inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker);
inline Unit* SelectUnit(AttackingTarget target, uint32 position);
void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target);
bool CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered);
bool SpawnedEventConditionsCheck(CreatureEventAI_Event const& event);
Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff);
void DoFindFriendlyMissingBuff(std::list<Creature*>& _list, float range, uint32 spellid);
void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
//Holder for events (stores enabled, time, and eventid)
std::list<CreatureEventAIHolder> CreatureEventAIList;
uint32 EventUpdateTime; //Time between event updates
uint32 EventDiff; //Time between the last event call
bool bEmptyList;
//Variables used by Events themselves
uint8 Phase; // Current phase, max 32 phases
bool CombatMovementEnabled; // If we allow targeted movment gen (movement twoards top threat)
+1 -72
View File
@@ -15,7 +15,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "Database/SQLStorage.h"
@@ -26,77 +25,61 @@
#include "Policies/SingletonImp.h"
#include "ObjectDefines.h"
#include "GridDefines.h"
INSTANTIATE_SINGLETON_1(CreatureEventAIMgr);
// -------------------
void CreatureEventAIMgr::LoadCreatureEventAI_Texts()
{
// Drop Existing Text Map, only done once and we are ready to add data from multiple sources.
m_CreatureEventAI_TextMap.clear();
// Load EventAI Text
objmgr.LoadTrinityStrings(WorldDatabase,"creature_ai_texts",MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID);
// Gather Additional data from EventAI Texts
QueryResult *result = WorldDatabase.Query("SELECT entry, sound, type, language, emote FROM creature_ai_texts");
sLog.outString("Loading EventAI Texts additional data...");
if (result)
{
barGoLink bar(result->GetRowCount());
uint32 count = 0;
do
{
bar.step();
Field* fields = result->Fetch();
StringTextData temp;
int32 i = fields[0].GetInt32();
temp.SoundId = fields[1].GetInt32();
temp.Type = fields[2].GetInt32();
temp.Language = fields[3].GetInt32();
temp.Emote = fields[4].GetInt32();
// range negative
if (i > MIN_CREATURE_AI_TEXT_STRING_ID || i <= MAX_CREATURE_AI_TEXT_STRING_ID)
{
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` is not in valid range(%d-%d)",i,MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID);
continue;
}
// range negative (don't must be happen, loaded from same table)
if (!objmgr.GetTrinityStringLocale(i))
{
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` not found",i);
continue;
}
if (temp.SoundId)
{
if (!sSoundEntriesStore.LookupEntry(temp.SoundId))
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Sound %u but sound does not exist.",i,temp.SoundId);
}
if (!GetLanguageDescByID(temp.Language))
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` using Language %u but Language does not exist.",i,temp.Language);
if (temp.Type > CHAT_TYPE_ZONE_YELL)
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Type %u but this Chat Type does not exist.",i,temp.Type);
if (temp.Emote)
{
if (!sEmotesStore.LookupEntry(temp.Emote))
sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Emote %u but emote does not exist.",i,temp.Emote);
}
m_CreatureEventAI_TextMap[i] = temp;
++count;
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString(">> Loaded %u additional CreatureEventAI Texts data.", count);
}
@@ -107,50 +90,39 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Texts()
sLog.outString();
sLog.outString(">> Loaded 0 additional CreatureEventAI Texts data. DB table `creature_ai_texts` is empty.");
}
}
// -------------------
void CreatureEventAIMgr::LoadCreatureEventAI_Summons()
{
//Drop Existing EventSummon Map
m_CreatureEventAI_Summon_Map.clear();
// Gather additional data for EventAI
QueryResult *result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM creature_ai_summons");
if (result)
{
barGoLink bar(result->GetRowCount());
uint32 Count = 0;
do
{
bar.step();
Field *fields = result->Fetch();
CreatureEventAI_Summon temp;
uint32 i = fields[0].GetUInt32();
temp.position_x = fields[1].GetFloat();
temp.position_y = fields[2].GetFloat();
temp.position_z = fields[3].GetFloat();
temp.orientation = fields[4].GetFloat();
temp.SpawnTimeSecs = fields[5].GetUInt32();
if(!MaNGOS::IsValidMapCoord(temp.position_x,temp.position_y,temp.position_z,temp.orientation))
{
sLog.outErrorDb("CreatureEventAI: Summon id %u have wrong coordinates (%f,%f,%f,%f), skipping.", i,temp.position_x,temp.position_y,temp.position_z,temp.orientation);
continue;
}
//Add to map
m_CreatureEventAI_Summon_Map[i] = temp;
++Count;
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString(">> Loaded %u CreatureEventAI summon definitions", Count);
}
@@ -161,15 +133,12 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Summons()
sLog.outString();
sLog.outString(">> Loaded 0 CreatureEventAI Summon definitions. DB table `creature_ai_summons` is empty.");
}
}
// -------------------
void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
{
//Drop Existing EventAI List
m_CreatureEventAI_Event_Map.clear();
// Gather event data
QueryResult *result = WorldDatabase.Query("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, "
"event_param1, event_param2, event_param3, event_param4, "
@@ -181,19 +150,15 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
{
barGoLink bar(result->GetRowCount());
uint32 Count = 0;
do
{
bar.step();
Field *fields = result->Fetch();
CreatureEventAI_Event temp;
temp.event_id = EventAI_Type(fields[0].GetUInt32());
uint32 i = temp.event_id;
temp.creature_id = fields[1].GetUInt32();
uint32 creature_id = temp.creature_id;
uint32 e_type = fields[2].GetUInt32();
//Report any errors in event
if (e_type >= EVENT_T_END)
@@ -202,7 +167,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
continue;
}
temp.event_type = EventAI_Type(e_type);
temp.event_inverse_phase_mask = fields[3].GetUInt32();
temp.event_chance = fields[4].GetUInt8();
temp.event_flags = fields[5].GetUInt8();
@@ -210,14 +174,12 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
temp.raw.param2 = fields[7].GetUInt32();
temp.raw.param3 = fields[8].GetUInt32();
temp.raw.param4 = fields[9].GetUInt32();
//Creature does not exist in database
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id))
{
sLog.outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, temp.creature_id);
continue;
}
//No chance of this event occuring
if (temp.event_chance == 0)
sLog.outErrorDb("CreatureEventAI: Event %u has 0 percent chance. Event will never trigger!", i);
@@ -227,7 +189,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
sLog.outErrorDb("CreatureEventAI: Creature %u are using event %u with more than 100 percent chance. Adjusting to 100 percent.", temp.creature_id, i);
temp.event_chance = 100;
}
//Individual event checks
switch (temp.event_type)
{
@@ -244,10 +205,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
case EVENT_T_TARGET_MANA:
if (temp.percent_range.percentMax > 100)
sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
if (temp.percent_range.percentMax <= temp.percent_range.percentMin)
sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i);
if (temp.event_flags & EFLAG_REPEATABLE && !temp.percent_range.repeatMin && !temp.percent_range.repeatMax)
{
sLog.outErrorDb("CreatureEventAI: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i);
@@ -263,14 +222,11 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i);
continue;
}
if ((temp.spell_hit.schoolMask & pSpell->SchoolMask) != pSpell->SchoolMask)
sLog.outErrorDb("CreatureEventAI: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.spell_hit.schoolMask, i);
}
if (!temp.spell_hit.schoolMask)
sLog.outErrorDb("CreatureEventAI: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.spell_hit.schoolMask, i);
if (temp.spell_hit.repeatMax < temp.spell_hit.repeatMin)
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break;
@@ -341,7 +297,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed qyest id (%u) in param1, skipped.", temp.creature_id, i, temp.quest.questId);
sLog.outErrorDb("CreatureEventAI: Creature %u using not implemented event (%u) in event %u.", temp.creature_id, temp.event_id, i);
continue;
case EVENT_T_AGGRO:
case EVENT_T_DEATH:
case EVENT_T_EVADE:
@@ -352,10 +307,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
sLog.outErrorDb("CreatureEventAI: Creature %u has EFLAG_REPEATABLE set. Event can never be repeatable. Removing flag for event %u.", temp.creature_id, i);
temp.event_flags &= ~EFLAG_REPEATABLE;
}
break;
}
case EVENT_T_RECEIVE_EMOTE:
{
if (!sEmotesTextStore.LookupEntry(temp.receive_emote.emoteId))
@@ -363,22 +316,18 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param1 (EmoteTextId: %u) are not valid.",temp.creature_id, i, temp.receive_emote.emoteId);
continue;
}
if (!PlayerCondition::IsValid(ConditionType(temp.receive_emote.condition), temp.receive_emote.conditionValue1, temp.receive_emote.conditionValue2))
{
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.receive_emote.condition);
continue;
}
if (!(temp.event_flags & EFLAG_REPEATABLE))
{
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: EFLAG_REPEATABLE not set. Event must always be repeatable. Flag applied.", temp.creature_id, i);
temp.event_flags |= EFLAG_REPEATABLE;
}
break;
}
case EVENT_T_BUFFED:
case EVENT_T_TARGET_BUFFED:
{
@@ -392,12 +341,10 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break;
}
default:
sLog.outErrorDb("CreatureEventAI: Creature %u using not checked at load event (%u) in event %u. Need check code update?", temp.creature_id, temp.event_id, i);
break;
}
for (uint32 j = 0; j < MAX_ACTIONS; j++)
{
uint16 action_type = fields[10+(j*4)].GetUInt16();
@@ -407,14 +354,11 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
temp.action[j].type = ACTION_T_NONE;
continue;
}
CreatureEventAI_Action& action = temp.action[j];
action.type = EventAI_ActionType(action_type);
action.raw.param1 = fields[11+(j*4)].GetUInt32();
action.raw.param2 = fields[12+(j*4)].GetUInt32();
action.raw.param3 = fields[13+(j*4)].GetUInt32();
//Report any errors in actions
switch (action.type)
{
@@ -431,7 +375,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
{
if (m_CreatureEventAI_TextMap.find(action.text.TextId2) == m_CreatureEventAI_TextMap.end())
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 refrences non-existing entry in texts table.", i, j+1);
if (!action.text.TextId1)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param2, but param1 is not set. Required for randomized text.", i, j+1);
}
@@ -439,7 +382,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
{
if (m_CreatureEventAI_TextMap.find(action.text.TextId3) == m_CreatureEventAI_TextMap.end())
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 refrences non-existing entry in texts table.", i, j+1);
if (!action.text.TextId1 || !action.text.TextId2)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param3, but param1 and/or param2 is not set. Required for randomized text.", i, j+1);
}
@@ -460,7 +402,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, action.morph.creatureId);
action.morph.creatureId = 0;
}
if (action.morph.modelId)
{
if (action.morph.creatureId)
@@ -516,11 +457,9 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
}
}
*/
//Cast is always triggered if target is forced to cast on self
if (action.cast.castFlags & CAST_FORCE_TARGET_SELF)
action.cast.castFlags |= CAST_TRIGGERED;
if (action.cast.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
@@ -528,7 +467,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
case ACTION_T_SUMMON:
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.summon.creatureId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.summon.creatureId);
if (action.summon.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
@@ -550,10 +488,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
}
else
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent Quest entry %u.", i, j+1, action.quest_event.questId);
if (action.quest_event.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
case ACTION_T_CAST_EVENT:
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.cast_event.creatureId))
@@ -682,29 +618,24 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
case ACTION_T_RANGED_MOVEMENT: //Distance, Angle
case ACTION_T_CALL_FOR_HELP: //Distance
break;
case ACTION_T_RANDOM_SAY:
case ACTION_T_RANDOM_YELL:
case ACTION_T_RANDOM_TEXTEMOTE:
sLog.outErrorDb("CreatureEventAI: Event %u Action %u currently unused ACTION type. Did you forget to update database?", i, j+1);
break;
case ACTION_T_SET_ACTIVE:
case ACTION_T_SET_AGGRESSIVE:
case ACTION_T_ATTACK_START_PULSE:
case ACTION_T_SUMMON_GO:
break;
default:
sLog.outErrorDb("CreatureEventAI: Event %u Action %u have currently not checked at load action type (%u). Need check code update?", i, j+1, temp.action[j].type);
break;
}
}
//Add to list
m_CreatureEventAI_Event_Map[creature_id].push_back(temp);
++Count;
if(CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id))
{
if(!cInfo->AIName || !cInfo->AIName[0])
@@ -722,11 +653,9 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
{
//sLog.outErrorDb("CreatureEventAI: Creature Entry %u has EventAI script but it also has C++ script. EventAI script will be overriden.", cInfo->Entry);
}
}
}
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString(">> Loaded %u CreatureEventAI scripts", Count);
}
-7
View File
@@ -15,32 +15,25 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MANGOS_CREATURE_EAI_MGR_H
#define MANGOS_CREATURE_EAI_MGR_H
#include "Common.h"
#include "CreatureEventAI.h"
class CreatureEventAIMgr
{
public:
CreatureEventAIMgr(){};
~CreatureEventAIMgr(){};
void LoadCreatureEventAI_Texts();
void LoadCreatureEventAI_Summons();
void LoadCreatureEventAI_Scripts();
CreatureEventAI_Event_Map const& GetCreatureEventAIMap() const { return m_CreatureEventAI_Event_Map; }
CreatureEventAI_Summon_Map const& GetCreatureEventAISummonMap() const { return m_CreatureEventAI_Summon_Map; }
CreatureEventAI_TextMap const& GetCreatureEventAITextMap() const { return m_CreatureEventAI_TextMap; }
private:
CreatureEventAI_Event_Map m_CreatureEventAI_Event_Map;
CreatureEventAI_Summon_Map m_CreatureEventAI_Summon_Map;
CreatureEventAI_TextMap m_CreatureEventAI_TextMap;
};
#define CreatureEAI_Mgr MaNGOS::Singleton<CreatureEventAIMgr>::Instance()
#endif
+2 -46
View File
@@ -17,28 +17,21 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Creature.h"
#include "CreatureGroups.h"
#include "ObjectMgr.h"
#include "ProgressBar.h"
#include "Policies/SingletonImp.h"
#include "CreatureAI.h"
#define MAX_DESYNC 5.0f
INSTANTIATE_SINGLETON_1(CreatureGroupManager);
CreatureGroupInfoType CreatureGroupMap;
void CreatureGroupManager::AddCreatureToGroup(uint32 groupId, Creature *member)
{
Map *map = member->FindMap();
if(!map)
return;
CreatureGroupHolderType::iterator itr = map->CreatureGroupHolder.find(groupId);
//Add member to an existing group
if(itr != map->CreatureGroupHolder.end())
{
@@ -54,58 +47,47 @@ void CreatureGroupManager::AddCreatureToGroup(uint32 groupId, Creature *member)
group->AddMember(member);
}
}
void CreatureGroupManager::RemoveCreatureFromGroup(CreatureGroup *group, Creature *member)
{
sLog.outDebug("Deleting member pointer to GUID: %u from group %u", group->GetId(), member->GetDBTableGUIDLow());
group->RemoveMember(member);
if(group->isEmpty())
{
Map *map = member->FindMap();
if(!map)
return;
sLog.outDebug("Deleting group with InstanceID %u", member->GetInstanceId());
map->CreatureGroupHolder.erase(group->GetId());
delete group;
}
}
void CreatureGroupManager::LoadCreatureFormations()
{
//Clear existing map
CreatureGroupMap.clear();
//Check Integrity of the table
QueryResult *result = WorldDatabase.PQuery("SELECT MAX(leaderGUID) FROM creature_formations");
if(!result)
{
sLog.outErrorDb(" ...an error occured while loading the table creature_formations ( maybe it doesn't exist ?)\n");
return;
}
delete result;
//Get group data
result = WorldDatabase.PQuery("SELECT leaderGUID, memberGUID, dist, angle, groupAI FROM creature_formations ORDER BY leaderGUID");
if(!result)
{
sLog.outErrorDb("The table creature_formations is empty or corrupted");
return;
}
uint32 total_records = result->GetRowCount();
barGoLink bar( total_records);
Field *fields;
FormationInfo *group_member;
//Loading data...
do
{
fields = result->Fetch();
bar.step();
//Load group member data
group_member = new FormationInfo;
@@ -123,7 +105,6 @@ void CreatureGroupManager::LoadCreatureFormations()
group_member->follow_dist = 0;
group_member->follow_angle = 0;
}
// check data correctness
{
QueryResult* result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE guid = %u", group_member->leaderGUID);
@@ -132,7 +113,6 @@ void CreatureGroupManager::LoadCreatureFormations()
sLog.outErrorDb("creature_formations table leader guid %u incorrect (not exist)", group_member->leaderGUID);
continue;
}
result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE guid = %u", memberGUID);
if(!result)
{
@@ -140,71 +120,56 @@ void CreatureGroupManager::LoadCreatureFormations()
continue;
}
}
CreatureGroupMap[memberGUID] = group_member;
}
}
while(result->NextRow()) ;
sLog.outString();
sLog.outString( ">> Loaded %u creatures in formations", total_records );
sLog.outString();
//Free some heap
delete result;
}
void CreatureGroup::AddMember(Creature *member)
{
sLog.outDebug("CreatureGroup::AddMember: Adding unit GUID: %u.", member->GetGUIDLow());
//Check if it is a leader
if(member->GetDBTableGUIDLow() == m_groupID)
{
sLog.outDebug("Unit GUID: %u is formation leader. Adding group.", member->GetGUIDLow());
m_leader = member;
}
m_members[member] = CreatureGroupMap.find(member->GetDBTableGUIDLow())->second;
member->SetFormation(this);
}
void CreatureGroup::RemoveMember(Creature *member)
{
if(m_leader == member)
m_leader = NULL;
m_members.erase(member);
member->SetFormation(NULL);
}
void CreatureGroup::MemberAttackStart(Creature *member, Unit *target)
{
uint8 groupAI = CreatureGroupMap[member->GetDBTableGUIDLow()]->groupAI;
if(!groupAI)
return;
if(groupAI == 1 && member != m_leader)
return;
for(CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
sLog.outDebug("GROUP ATTACK: group instance id %u calls member instid %u", m_leader->GetInstanceId(), member->GetInstanceId());
//sLog.outDebug("AI:%u:Group member found: %u, attacked by %s.", groupAI, itr->second->GetGUIDLow(), member->getVictim()->GetName());
//Skip one check
if(itr->first == member)
continue;
if(!itr->first->isAlive())
continue;
if(itr->first->getVictim())
continue;
if(itr->first->canAttack(target))
itr->first->AI()->AttackStart(target);
}
}
void CreatureGroup::FormationReset(bool dismiss)
{
for(CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
@@ -220,37 +185,28 @@ void CreatureGroup::FormationReset(bool dismiss)
}
m_Formed = !dismiss;
}
void CreatureGroup::LeaderMoveTo(float x, float y, float z)
{
if(!m_leader)
return;
float pathangle = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
for(CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
Creature *member = itr->first;
if(member == m_leader || !member->isAlive() || member->getVictim())
continue;
float angle = itr->second->follow_angle;
float dist = itr->second->follow_dist;
float dist = itr->second->follow_dist;
float dx = x + cos(angle + pathangle) * dist;
float dy = y + sin(angle + pathangle) * dist;
float dz = z;
Trinity::NormalizeMapCoord(dx);
Trinity::NormalizeMapCoord(dy);
member->UpdateGroundPositionZ(dx, dy, dz);
if(member->IsWithinDist(m_leader, dist + MAX_DESYNC))
member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
else
member->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
member->SetHomePosition(dx, dy, dz, pathangle);
}
+3 -18
View File
@@ -1,4 +1,4 @@
/*
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
@@ -17,22 +17,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _FORMATIONS_H
#define _FORMATIONS_H
#include "Common.h"
class CreatureGroup;
struct FormationInfo
{
uint32 leaderGUID;
float follow_dist;
float follow_angle;
float follow_dist;
float follow_angle;
uint8 groupAI;
};
class CreatureGroupManager
{
public:
@@ -40,39 +35,29 @@ class CreatureGroupManager
void RemoveCreatureFromGroup(CreatureGroup *group, Creature *creature);
void LoadCreatureFormations();
};
typedef UNORDERED_MAP<uint32/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType;
extern CreatureGroupInfoType CreatureGroupMap;
class CreatureGroup
{
private:
Creature *m_leader; //Important do not forget sometimes to work with pointers instead synonims :D:D
typedef std::map<Creature*, FormationInfo*> CreatureGroupMemberType;
CreatureGroupMemberType m_members;
uint32 m_groupID;
bool m_Formed;
public:
//Group cannot be created empty
explicit CreatureGroup(uint32 id) : m_groupID(id), m_leader(NULL), m_Formed(false) {}
~CreatureGroup() { sLog.outDebug("Destroying group"); }
Creature* getLeader() const { return m_leader; }
uint32 GetId() const { return m_groupID; }
bool isEmpty() const { return m_members.empty(); }
bool isFormed() const { return m_Formed; }
void AddMember(Creature *member);
void RemoveMember(Creature *member);
void FormationReset(bool dismiss);
void LeaderMoveTo(float x, float y, float z);
void MemberAttackStart(Creature* member, Unit *target);
};
#define formation_mgr Trinity::Singleton<CreatureGroupManager>::Instance()
#endif
-22
View File
@@ -15,36 +15,29 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DBCENUMS_H
#define DBCENUMS_H
// Client expected level limitation, like as used in DBC item max levels for "until max player level"
// use as default max player level, must be fit max level for used client
// also see MAX_LEVEL and STRONG_MAX_LEVEL define
#define DEFAULT_MAX_LEVEL 80
// client supported max level for player/pets/etc. Avoid overflow or client stability affected.
// also see GT_MAX_LEVEL define
#define MAX_LEVEL 100
// Server side limitation. Base at used code requirements.
// also see MAX_LEVEL and GT_MAX_LEVEL define
#define STRONG_MAX_LEVEL 255
enum AreaTeams
{
AREATEAM_NONE = 0,
AREATEAM_ALLY = 2,
AREATEAM_HORDE = 4
};
enum AchievementFactionFlags
{
ACHIEVEMENT_FACTION_FLAG_HORDE = 0x00000000,
ACHIEVEMENT_FACTION_FLAG_ALLIANCE = 0x00000001,
};
enum AchievementFlags
{
ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete)
@@ -58,7 +51,6 @@ enum AchievementFlags
ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, //
ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, //
};
enum AchievementCriteriaCondition
{
ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0,
@@ -69,7 +61,6 @@ enum AchievementCriteriaCondition
ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 9, // unk
ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk
};
enum AchievementCriteriaCompletionFlags
{
ACHIEVEMENT_CRITERIA_FLAG_SHOW_PROGRESS_BAR = 0x00000001, // Show progress as bar
@@ -79,13 +70,11 @@ enum AchievementCriteriaCompletionFlags
ACHIEVEMENT_CRITERIA_FLAG_UNK5 = 0x00000010, // not used
ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020, // Displays counter as money
};
enum AchievementCriteriaGroupFlags
{
// you mustn't be in a group while fulfilling this achievement
ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP = 2,
};
enum AchievementCriteriaTypes
{
ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0,
@@ -199,7 +188,6 @@ enum AchievementCriteriaTypes
// 0..114 => 115 criteria types total
ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 115,
};
enum AreaFlags
{
AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring)
@@ -231,12 +219,10 @@ enum AreaFlags
AREA_FLAG_UNK10 = 0x04000000, // unknown
AREA_FLAG_OUTDOOR_PVP2 = 0x08000000 // Wintergrasp and it's subzones
};
enum FactionTemplateFlags
{
FACTION_TEMPLATE_FLAG_CONTESTED_GUARD = 0x00001000, // faction will attack players that were involved in PvP combats
};
enum FactionMasks
{
FACTION_MASK_PLAYER = 1, // any player
@@ -245,7 +231,6 @@ enum FactionMasks
FACTION_MASK_MONSTER = 8 // aggressive creature from monster team
// if none flags set then non-aggressive creature
};
enum MapTypes
{
MAP_COMMON = 0,
@@ -254,13 +239,11 @@ enum MapTypes
MAP_BATTLEGROUND = 3,
MAP_ARENA = 4
};
enum AbilytyLearnType
{
ABILITY_LEARNED_ON_GET_PROFESSION_SKILL = 1,
ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL = 2
};
enum ItemEnchantmentType
{
ITEM_ENCHANTMENT_TYPE_NONE = 0,
@@ -273,7 +256,6 @@ enum ItemEnchantmentType
ITEM_ENCHANTMENT_TYPE_USE_SPELL = 7,
ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET = 8
};
enum TotemCategoryType
{
TOTEM_CATEGORY_TYPE_KNIFE = 1,
@@ -284,7 +266,6 @@ enum TotemCategoryType
TOTEM_CATEGORY_TYPE_HAMMER = 23,
TOTEM_CATEGORY_TYPE_SPANNER = 24
};
// SummonProperties.dbc, col 1
enum SummonPropGroup
{
@@ -294,7 +275,6 @@ enum SummonPropGroup
SUMMON_PROP_GROUP_CONTROLLABLE = 3, // 13 spells in 3.0.3, mostly controllable
SUMMON_PROP_GROUP_UNKNOWN3 = 4 // 86 spells in 3.0.3, taxi/mounts
};
// SummonProperties.dbc, col 3
enum SummonPropType
{
@@ -311,7 +291,6 @@ enum SummonPropType
SUMMON_PROP_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells
SUMMON_PROP_TYPE_LIGHTWELL = 11 // summon lightwell, 6 spells in 3.0.3
};
// SummonProperties.dbc, col 5
enum SummonPropFlags
{
@@ -331,6 +310,5 @@ enum SummonPropFlags
SUMMON_PROP_FLAG_UNK13 = 0x1000, // 8 spells in 3.0.3, siege vehicle
SUMMON_PROP_FLAG_UNK14 = 0x2000, // 2 spells in 3.0.3, escort?
};
#endif
-109
View File
@@ -17,27 +17,21 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "DBCStores.h"
#include "Policies/SingletonImp.h"
#include "Log.h"
#include "ProgressBar.h"
#include "SharedDefines.h"
#include "SpellMgr.h"
#include "DBCfmt.h"
#include <map>
typedef std::map<uint16,uint32> AreaFlagByAreaID;
typedef std::map<uint32,uint32> AreaFlagByMapID;
DBCStorage <AreaTableEntry> sAreaStore(AreaTableEntryfmt);
DBCStorage <AreaGroupEntry> sAreaGroupStore(AreaGroupEntryfmt);
DBCStorage <AreaPOIEntry> sAreaPOIStore(AreaPOIEntryfmt);
static AreaFlagByAreaID sAreaFlagByAreaID;
static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files
DBCStorage <AchievementEntry> sAchievementStore(Achievementfmt);
DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore(AchievementCriteriafmt);
DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt);
@@ -56,23 +50,18 @@ DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
DBCStorage <CreatureTypeEntry> sCreatureTypeStore(CreatureTypefmt);
DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesfmt);
DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore(DurabilityQualityfmt);
DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore(DurabilityCostsfmt);
DBCStorage <EmotesEntry> sEmotesStore(EmotesEntryfmt);
DBCStorage <EmotesTextEntry> sEmotesTextStore(EmotesTextEntryfmt);
typedef std::map<uint32,SimpleFactionsList> FactionTeamMap;
static FactionTeamMap sFactionTeamMap;
DBCStorage <FactionEntry> sFactionStore(FactionEntryfmt);
DBCStorage <FactionTemplateEntry> sFactionTemplateStore(FactionTemplateEntryfmt);
DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt);
DBCStorage <GemPropertiesEntry> sGemPropertiesStore(GemPropertiesEntryfmt);
DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore(GlyphPropertiesfmt);
DBCStorage <GlyphSlotEntry> sGlyphSlotStore(GlyphSlotfmt);
DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt);
DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore(GtCombatRatingsfmt);
DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt);
@@ -83,9 +72,7 @@ DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt);
//DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently
DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore(GtRegenHPPerSptfmt);
DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt);
DBCStorage <HolidaysEntry> sHolidaysStore(Holidaysfmt);
DBCStorage <ItemEntry> sItemStore(Itemfmt);
DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore(ItemBagFamilyfmt);
//DBCStorage <ItemCondExtCostsEntry> sItemCondExtCostsStore(ItemCondExtCostsEntryfmt);
@@ -95,30 +82,22 @@ DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore(ItemLimitCategoryEnt
DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomPropertiesfmt);
DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt);
DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt);
DBCStorage <LockEntry> sLockStore(LockEntryfmt);
DBCStorage <MailTemplateEntry> sMailTemplateStore(MailTemplateEntryfmt);
DBCStorage <MapEntry> sMapStore(MapEntryfmt);
DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt);
DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);
DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore(RandomPropertiesPointsfmt);
DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore(ScalingStatDistributionfmt);
DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore(ScalingStatValuesfmt);
DBCStorage <SkillLineEntry> sSkillLineStore(SkillLinefmt);
DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore(SkillLineAbilityfmt);
DBCStorage <SoundEntriesEntry> sSoundEntriesStore(SoundEntriesfmt);
DBCStorage <SpellItemEnchantmentEntry> sSpellItemEnchantmentStore(SpellItemEnchantmentfmt);
DBCStorage <SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore(SpellItemEnchantmentConditionfmt);
DBCStorage <SpellEntry> sSpellStore(SpellEntryfmt);
SpellCategoryStore sSpellCategoryStore;
PetFamilySpellsStore sPetFamilySpellsStore;
DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore(SpellCastTimefmt);
DBCStorage <SpellDurationEntry> sSpellDurationStore(SpellDurationfmt);
DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore(SpellFocusObjectfmt);
@@ -131,21 +110,16 @@ DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt);
DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt);
TalentSpellPosMap sTalentSpellPosMap;
DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
// store absolute bit position for first rank for talent inspect
static uint32 sTalentTabPages[12/*MAX_CLASSES*/][3];
DBCStorage <TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt);
TaxiMask sTaxiNodesMask;
TaxiMask sOldContinentsNodesMask;
// DBC used only for initialization sTaxiPathSetBySource at startup.
TaxiPathSetBySource sTaxiPathSetBySource;
DBCStorage <TaxiPathEntry> sTaxiPathStore(TaxiPathEntryfmt);
// DBC used only for initialization sTaxiPathSetBySource at startup.
TaxiPathNodesByPath sTaxiPathNodesByPath;
static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
DBCStorage <VehicleEntry> sVehicleStore(VehicleEntryfmt);
@@ -153,28 +127,22 @@ DBCStorage <VehicleSeatEntry> sVehicleSeatStore(VehicleSeatEntryfmt);
DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt);
DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt);
DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt);
typedef std::list<std::string> StoreProblemList;
static bool LoadDBC_assert_print(uint32 fsize,uint32 rsize, const std::string& filename)
{
sLog.outError("ERROR: Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).",filename.c_str(),fsize,rsize);
// assert must fail after function call
return false;
}
template<class T>
inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList& errlist, DBCStorage<T>& storage, const std::string& dbc_path, const std::string& filename, const std::string * custom_entries = NULL, const std::string * idname = NULL)
{
// compatibility format and C++ structure sizes
assert(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()),sizeof(T),filename));
std::string dbc_filename = dbc_path + filename;
SqlDbc * sql = NULL;
if (custom_entries)
sql = new SqlDbc(&filename,custom_entries, idname,storage.GetFormat());
if(storage.Load(dbc_filename.c_str(), sql))
{
bar.step();
@@ -182,7 +150,6 @@ inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList
{
if(!(availableDbcLocales & (1 << i)))
continue;
std::string dbc_filename_loc = dbc_path + localeNames[i] + "/" + filename;
if(!storage.LoadStringsFrom(dbc_filename_loc.c_str()))
availableDbcLocales &= ~(1<<i); // mark as not available for speedup next checks
@@ -205,20 +172,14 @@ inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList
if (sql)
delete sql;
}
void LoadDBCStores(const std::string& dataPath)
{
std::string dbcPath = dataPath+"dbc/";
const uint32 DBCFilesCount = 79;
barGoLink bar( DBCFilesCount );
StoreProblemList bad_dbc_files;
uint32 availableDbcLocales = 0xFFFFFFFF;
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaStore, dbcPath,"AreaTable.dbc");
// must be after sAreaStore loading
for(uint32 i = 0; i < sAreaStore.GetNumRows(); ++i) // areaflag numbered from 0
{
@@ -226,13 +187,11 @@ void LoadDBCStores(const std::string& dataPath)
{
// fill AreaId->DBC records
sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag));
// fill MapId->DBC records ( skip sub zones and continents )
if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571 )
sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag));
}
}
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc");
@@ -243,7 +202,6 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc");
@@ -268,7 +226,6 @@ void LoadDBCStores(const std::string& dataPath)
flist.push_back(i);
}
}
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGameObjectDisplayInfoStore, dbcPath,"GameObjectDisplayInfo.dbc");
for(uint32 i = 0; i < sGameObjectDisplayInfoStore.GetNumRows(); ++i)
@@ -283,20 +240,15 @@ void LoadDBCStores(const std::string& dataPath)
std::swap(*(float*)(&info->maxZ), *(float*)(&info->minZ));
}
}
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphPropertiesStore, dbcPath,"GlyphProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphSlotStore, dbcPath,"GlyphSlot.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritStore, dbcPath,"gtChanceToMeleeCrit.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritBaseStore, dbcPath,"gtChanceToSpellCritBase.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritStore, dbcPath,"gtChanceToSpellCrit.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenHPStore, dbcPath,"gtOCTRegenHP.dbc");
//LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc");
@@ -329,16 +281,12 @@ void LoadDBCStores(const std::string& dataPath)
if(spell && spell->Category)
sSpellCategoryStore[spell->Category].insert(i);
}
for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
{
SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j);
if(!skillLine)
continue;
SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId);
if(spellInfo && IsPassiveSpell(spellInfo->Id))
{
for (uint32 i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i)
@@ -346,20 +294,16 @@ void LoadDBCStores(const std::string& dataPath)
CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i);
if(!cFamily)
continue;
if(skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1])
continue;
if(spellInfo->spellLevel)
continue;
if(skillLine->learnOnGetSkill != ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL)
continue;
sPetFamilySpellsStore[i].insert(spellInfo->Id);
}
}
}
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc");
@@ -372,7 +316,6 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc");
// create talent spells set
for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i)
{
@@ -382,9 +325,7 @@ void LoadDBCStores(const std::string& dataPath)
if(talentInfo->RankID[j])
sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j);
}
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentTabStore, dbcPath,"TalentTab.dbc");
// prepare fast data access to bit pos of talent ranks for use at inspecting
{
// now have all max ranks (and then bit amount used for store talent ranks in inspect)
@@ -393,27 +334,21 @@ void LoadDBCStores(const std::string& dataPath)
TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentTabId );
if(!talentTabInfo)
continue;
// prevent memory corruption; otherwise cls will become 12 below
if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE)==0)
continue;
// store class talent tab pages
uint32 cls = 1;
for(uint32 m=1;!(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES;m <<=1, ++cls) {}
sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId;
}
}
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc");
for(uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
if(TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i))
sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID,entry->price);
uint32 pathCount = sTaxiPathStore.GetNumRows();
//## TaxiPathNode.dbc ## Loaded only for initialization different structures
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathNodeStore, dbcPath,"TaxiPathNode.dbc");
// Calculate path nodes count
@@ -434,7 +369,6 @@ void LoadDBCStores(const std::string& dataPath)
if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i))
sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay);
sTaxiPathNodeStore.Clear();
// Initialize global taxinodes mask
// include existed nodes that have at least single not spell base (scripted) path
{
@@ -444,7 +378,6 @@ void LoadDBCStores(const std::string& dataPath)
for(int j=0; j < 3; ++j)
if(sInfo->Effect[j]==123 /*SPELL_EFFECT_SEND_TAXI*/)
spellPaths.insert(sInfo->EffectMiscValue[j]);
memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask));
memset(sOldContinentsNodesMask,0,sizeof(sTaxiNodesMask));
for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i)
@@ -452,7 +385,6 @@ void LoadDBCStores(const std::string& dataPath)
TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i);
if(!node)
continue;
TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i);
if(src_i!=sTaxiPathSetBySource.end() && !src_i->second.empty())
{
@@ -466,29 +398,24 @@ void LoadDBCStores(const std::string& dataPath)
break;
}
}
if(!ok)
continue;
}
// valid taxi network node
uint8 field = (uint8)((i - 1) / 32);
uint32 submask = 1<<((i-1)%32);
sTaxiNodesMask[field] |= submask;
// old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info)
if (node->map_id < 2 || i == 82 || i == 83 || i == 93 || i == 94)
sOldContinentsNodesMask[field] |= submask;
}
}
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc");
// error checks
if(bad_dbc_files.size() >= DBCFilesCount )
{
@@ -500,11 +427,9 @@ void LoadDBCStores(const std::string& dataPath)
std::string str;
for(std::list<std::string>::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i)
str += *i + "\n";
sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",(uint32)bad_dbc_files.size(),DBCFilesCount,str.c_str());
exit(1);
}
// Check loaded DBC files proper version
if( !sSpellStore.LookupEntry(66530) || // last added spell in 3.1.3
!sMapStore.LookupEntry(624) || // last map added in 3.1.3
@@ -517,11 +442,9 @@ void LoadDBCStores(const std::string& dataPath)
sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client.");
exit(1);
}
sLog.outString();
sLog.outString( ">> Initialized %d data stores", DBCFilesCount );
}
SimpleFactionsList const* GetFactionTeamList(uint32 faction, bool &isTeamMember)
{
for(FactionTeamMap::const_iterator itr = sFactionTeamMap.begin(); itr != sFactionTeamMap.end(); ++itr)
@@ -542,7 +465,6 @@ SimpleFactionsList const* GetFactionTeamList(uint32 faction, bool &isTeamMember)
}
return NULL;
}
char* GetPetName(uint32 petfamily, uint32 dbclang)
{
if(!petfamily)
@@ -552,53 +474,41 @@ char* GetPetName(uint32 petfamily, uint32 dbclang)
return NULL;
return pet_family->Name[dbclang]?pet_family->Name[dbclang]:NULL;
}
TalentSpellPos const* GetTalentSpellPos(uint32 spellId)
{
TalentSpellPosMap::const_iterator itr = sTalentSpellPosMap.find(spellId);
if(itr==sTalentSpellPosMap.end())
return NULL;
return &itr->second;
}
uint32 GetTalentSpellCost(uint32 spellId)
{
if(TalentSpellPos const* pos = GetTalentSpellPos(spellId))
return pos->rank+1;
return 0;
}
int32 GetAreaFlagByAreaID(uint32 area_id)
{
AreaFlagByAreaID::iterator i = sAreaFlagByAreaID.find(area_id);
if(i == sAreaFlagByAreaID.end())
return -1;
return i->second;
}
AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id)
{
int32 areaflag = GetAreaFlagByAreaID(area_id);
if(areaflag < 0)
return NULL;
return sAreaStore.LookupEntry(areaflag );
}
AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id)
{
if(area_flag)
return sAreaStore.LookupEntry(area_flag);
if(MapEntry const* mapEntry = sMapStore.LookupEntry(map_id))
return GetAreaEntryByAreaID(mapEntry->linked_zone);
return NULL;
}
uint32 GetAreaFlagByMapId(uint32 mapid)
{
AreaFlagByMapID::iterator i = sAreaFlagByMapID.find(mapid);
@@ -607,28 +517,22 @@ uint32 GetAreaFlagByMapId(uint32 mapid)
else
return i->second;
}
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
{
if(mapid != 530 && mapid != 571) // speed for most cases
return mapid;
if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId))
return wma->virtual_map_id >= 0 ? wma->virtual_map_id : wma->map_id;
return mapid;
}
ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId)
{
mapid = GetVirtualMapForMapAndZone(mapid,zoneId);
if(mapid < 2)
return CONTENT_1_60;
MapEntry const* mapEntry = sMapStore.LookupEntry(mapid);
if(!mapEntry)
return CONTENT_1_60;
switch(mapEntry->Expansion())
{
default: return CONTENT_1_60;
@@ -636,7 +540,6 @@ ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId)
case 2: return CONTENT_71_80;
}
}
ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id)
{
// not sorted, numbering index from 0
@@ -648,58 +551,46 @@ ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id)
}
return NULL;
}
bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId)
{
if(requiredTotemCategoryId==0)
return true;
if(itemTotemCategoryId==0)
return false;
TotemCategoryEntry const* itemEntry = sTotemCategoryStore.LookupEntry(itemTotemCategoryId);
if(!itemEntry)
return false;
TotemCategoryEntry const* reqEntry = sTotemCategoryStore.LookupEntry(requiredTotemCategoryId);
if(!reqEntry)
return false;
if(itemEntry->categoryType!=reqEntry->categoryType)
return false;
return (itemEntry->categoryMask & reqEntry->categoryMask)==reqEntry->categoryMask;
}
void Zone2MapCoordinates(float& x,float& y,uint32 zone)
{
WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone);
// if not listed then map coordinates (instance)
if(!maEntry)
return;
std::swap(x,y); // at client map coords swapped
x = x*((maEntry->x2-maEntry->x1)/100)+maEntry->x1;
y = y*((maEntry->y2-maEntry->y1)/100)+maEntry->y1; // client y coord from top to down
}
void Map2ZoneCoordinates(float& x,float& y,uint32 zone)
{
WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone);
// if not listed then map coordinates (instance)
if(!maEntry)
return;
x = (x-maEntry->x1)/((maEntry->x2-maEntry->x1)/100);
y = (y-maEntry->y1)/((maEntry->y2-maEntry->y1)/100); // client y coord from top to down
std::swap(x,y); // client have map coords swapped
}
uint32 const* GetTalentTabPages(uint32 cls)
{
return sTalentTabPages[cls];
}
// script support functions
TRINITY_DLL_SPEC DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore() { return &sSoundEntriesStore; }
TRINITY_DLL_SPEC DBCStorage <SpellEntry> const* GetSpellStore() { return &sSpellStore; }
-16
View File
@@ -15,30 +15,22 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MANGOS_DBCSTORES_H
#define MANGOS_DBCSTORES_H
#include "Common.h"
#include "Database/DBCStore.h"
#include "DBCStructure.h"
#include <list>
typedef std::list<uint32> SimpleFactionsList;
SimpleFactionsList const* GetFactionTeamList(uint32 faction, bool &isTeamMember);
char* GetPetName(uint32 petfamily, uint32 dbclang);
uint32 GetTalentSpellCost(uint32 spellId);
TalentSpellPos const* GetTalentSpellPos(uint32 spellId);
int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found
AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id);
AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id);
uint32 GetAreaFlagByMapId(uint32 mapid);
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
enum ContentLevels
{
CONTENT_1_60 = 0,
@@ -46,16 +38,11 @@ enum ContentLevels
CONTENT_71_80
};
ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId);
ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id);
bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId);
void Zone2MapCoordinates(float& x,float& y,uint32 zone);
void Map2ZoneCoordinates(float& x,float& y,uint32 zone);
uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls);
extern DBCStorage <AchievementEntry> sAchievementStore;
extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
@@ -87,7 +74,6 @@ extern DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore;
extern DBCStorage <GemPropertiesEntry> sGemPropertiesStore;
extern DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore;
extern DBCStorage <GlyphSlotEntry> sGlyphSlotStore;
extern DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore;
extern DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore;
extern DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore;
@@ -146,9 +132,7 @@ extern DBCStorage <VehicleSeatEntry> sVehicleSeatStore;
//extern DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates
extern DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore;
extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore;
void LoadDBCStores(const std::string& dataPath);
// script support functions
TRINITY_DLL_SPEC DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore();
TRINITY_DLL_SPEC DBCStorage <SpellEntry> const* GetSpellStore();
File diff suppressed because it is too large Load Diff
-3
View File
@@ -17,10 +17,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MANGOS_DBCSFRM_H
#define MANGOS_DBCSFRM_H
const char Achievementfmt[]="niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii";
const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix";
const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";
@@ -109,5 +107,4 @@ const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiii
const char WorldMapAreaEntryfmt[]="xinxffffix";
const char WorldMapOverlayEntryfmt[]="nxiiiixxxxxxxxxxx";
const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx";
#endif
-178
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
@@ -38,26 +37,20 @@
#include "GridNotifiersImpl.h"
#include "SpellMgr.h"
#include "ScriptCalls.h"
bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args)
{
if (!*args)
return false;
char* px = strtok((char*)args, " ");
if (!px)
return false;
uint8 failnum = (uint8)atoi(px);
if (failnum==0 && *px!='0')
return false;
char* p1 = strtok(NULL, " ");
uint8 failarg1 = p1 ? (uint8)atoi(p1) : 0;
char* p2 = strtok(NULL, " ");
uint8 failarg2 = p2 ? (uint8)atoi(p2) : 0;
WorldPacket data(SMSG_CAST_FAILED, 5);
data << uint8(0);
data << uint32(133);
@@ -66,17 +59,13 @@ bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args)
data << uint32(failarg1);
if (p2)
data << uint32(failarg2);
m_session->SendPacket(&data);
return true;
}
bool ChatHandler::HandleDebugSendPoiCommand(const char* args)
{
if (!*args)
return false;
Player *pPlayer = m_session->GetPlayer();
Unit* target = getSelectedUnit();
if (!target)
@@ -84,50 +73,40 @@ bool ChatHandler::HandleDebugSendPoiCommand(const char* args)
SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
return true;
}
char* icon_text = strtok((char*)args, " ");
char* flags_text = strtok(NULL, " ");
if (!icon_text || !flags_text)
return false;
uint32 icon = atol(icon_text);
uint32 flags = atol(flags_text);
sLog.outDetail("Command : POI, NPC = %u, icon = %u flags = %u", target->GetGUIDLow(), icon,flags);
pPlayer->PlayerTalkClass->SendPointOfInterest(target->GetPositionX(), target->GetPositionY(), Poi_Icon(icon), flags, 30, "Test POI");
return true;
}
bool ChatHandler::HandleDebugSendEquipErrorCommand(const char* args)
{
if (!*args)
return false;
uint8 msg = atoi(args);
m_session->GetPlayer()->SendEquipError(msg, 0, 0);
return true;
}
bool ChatHandler::HandleDebugSendSellErrorCommand(const char* args)
{
if (!*args)
return false;
uint8 msg = atoi(args);
m_session->GetPlayer()->SendSellError(msg, 0, 0, 0);
return true;
}
bool ChatHandler::HandleDebugSendBuyErrorCommand(const char* args)
{
if (!*args)
return false;
uint8 msg = atoi(args);
m_session->GetPlayer()->SendBuyError(msg, 0, 0, 0);
return true;
}
bool ChatHandler::HandleDebugSendOpcodeCommand(const char* /*args*/)
{
Unit *unit = getSelectedUnit();
@@ -137,24 +116,18 @@ bool ChatHandler::HandleDebugSendOpcodeCommand(const char* /*args*/)
else
player = (Player*)unit;
if(!unit) unit = player;
std::ifstream ifs("opcode.txt");
if (ifs.bad())
return false;
uint32 opcode;
ifs >> opcode;
WorldPacket data(opcode, 0);
while(!ifs.eof())
{
std::string type;
ifs >> type;
if(type == "")
break;
if(type == "uint8")
{
uint16 val1;
@@ -256,21 +229,17 @@ bool ChatHandler::HandleDebugSendOpcodeCommand(const char* /*args*/)
PSendSysMessage(LANG_COMMAND_OPCODESENT, data.GetOpcode(), unit->GetName());
return true;
}
bool ChatHandler::HandleDebugUpdateWorldStateCommand(const char* args)
{
char* w = strtok((char*)args, " ");
char* s = strtok(NULL, " ");
if (!w || !s)
return false;
uint32 world = (uint32)atoi(w);
uint32 state = (uint32)atoi(s);
m_session->GetPlayer()->SendUpdateWorldState(world, state);
return true;
}
bool ChatHandler::HandleDebugPlayCinematicCommand(const char* args)
{
// USAGE: .debug play cinematic #cinematicid
@@ -281,20 +250,16 @@ bool ChatHandler::HandleDebugPlayCinematicCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
uint32 dwId = atoi((char*)args);
if (!sCinematicSequencesStore.LookupEntry(dwId))
{
PSendSysMessage(LANG_CINEMATIC_NOT_EXIST, dwId);
SetSentErrorMessage(true);
return false;
}
m_session->GetPlayer()->SendCinematicStart(dwId);
return true;
}
bool ChatHandler::HandleDebugPlayMovieCommand(const char* args)
{
// USAGE: .debug play movie #movieid
@@ -305,20 +270,16 @@ bool ChatHandler::HandleDebugPlayMovieCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
uint32 dwId = atoi((char*)args);
if (!sMovieStore.LookupEntry(dwId))
{
PSendSysMessage(LANG_MOVIE_NOT_EXIST, dwId);
SetSentErrorMessage(true);
return false;
}
m_session->GetPlayer()->SendMovieStart(dwId);
return true;
}
//Play sound
bool ChatHandler::HandleDebugPlaySoundCommand(const char* args)
{
@@ -330,16 +291,13 @@ bool ChatHandler::HandleDebugPlaySoundCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
uint32 dwSoundId = atoi((char*)args);
if (!sSoundEntriesStore.LookupEntry(dwSoundId))
{
PSendSysMessage(LANG_SOUND_NOT_EXIST, dwSoundId);
SetSentErrorMessage(true);
return false;
}
Unit* unit = getSelectedUnit();
if (!unit)
{
@@ -347,25 +305,20 @@ bool ChatHandler::HandleDebugPlaySoundCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
if (m_session->GetPlayer()->GetSelection())
unit->PlayDistanceSound(dwSoundId,m_session->GetPlayer());
else
unit->PlayDirectSound(dwSoundId,m_session->GetPlayer());
PSendSysMessage(LANG_YOU_HEAR_SOUND, dwSoundId);
return true;
}
//Send notification in channel
bool ChatHandler::HandleDebugSendChannelNotifyCommand(const char* args)
{
if (!*args)
return false;
const char *name = "test";
uint8 code = atoi(args);
WorldPacket data(SMSG_CHANNEL_NOTIFY, (1+10));
data << code; // notify type
data << name; // channel name
@@ -374,13 +327,11 @@ bool ChatHandler::HandleDebugSendChannelNotifyCommand(const char* args)
m_session->SendPacket(&data);
return true;
}
//Send notification in chat
bool ChatHandler::HandleDebugSendChatMsgCommand(const char* args)
{
if (!*args)
return false;
const char *msg = "testtest";
uint8 type = atoi(args);
WorldPacket data;
@@ -388,38 +339,31 @@ bool ChatHandler::HandleDebugSendChatMsgCommand(const char* args)
m_session->SendPacket(&data);
return true;
}
bool ChatHandler::HandleDebugSendQuestPartyMsgCommand(const char* args)
{
uint32 msg = atol((char*)args);
m_session->GetPlayer()->SendPushToPartyResponse(m_session->GetPlayer(), msg);
return true;
}
bool ChatHandler::HandleDebugGetLootRecipientCommand(const char* /*args*/)
{
Creature* target = getSelectedCreature();
if (!target)
return false;
PSendSysMessage("loot recipient: %s", target->hasLootRecipient()?(target->GetLootRecipient()?target->GetLootRecipient()->GetName():"offline"):"no loot recipient");
return true;
}
bool ChatHandler::HandleDebugSendQuestInvalidMsgCommand(const char* args)
{
uint32 msg = atol((char*)args);
m_session->GetPlayer()->SendCanTakeQuestResponse(msg);
return true;
}
bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
{
if (!*args)
return false;
std::string state_str = args;
ItemUpdateState state = ITEM_UNCHANGED;
bool list_queue = false, check_all = false;
if (state_str == "unchanged") state = ITEM_UNCHANGED;
@@ -429,10 +373,8 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
else if (state_str == "queue") list_queue = true;
else if (state_str == "check_all") check_all = true;
else return false;
Player* player = getSelectedPlayer();
if (!player) player = m_session->GetPlayer();
if (!list_queue && !check_all)
{
state_str = "The player has the following " + state_str + " items: ";
@@ -441,7 +383,6 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
{
if(i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END)
continue;
Item *item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (!item) continue;
if (!item->IsBag())
@@ -461,7 +402,6 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
}
}
}
if (list_queue)
{
std::vector<Item *> &updateQueue = player->GetItemUpdateQueue();
@@ -469,10 +409,8 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
{
Item *item = updateQueue[i];
if(!item) continue;
Bag *container = item->GetContainer();
uint8 bag_slot = container ? container->GetSlot() : uint8(INVENTORY_SLOT_BAG_0);
std::string st;
switch(item->GetState())
{
@@ -481,13 +419,11 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
case ITEM_NEW: st = "new"; break;
case ITEM_REMOVED: st = "removed"; break;
}
PSendSysMessage("bag: %d slot: %d guid: %d - state: %s", bag_slot, item->GetSlot(), item->GetGUIDLow(), st.c_str());
}
if (updateQueue.empty())
PSendSysMessage("updatequeue empty");
}
if (check_all)
{
bool error = false;
@@ -496,28 +432,23 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
{
if(i >= BUYBACK_SLOT_START && i < BUYBACK_SLOT_END)
continue;
Item *item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
if (!item) continue;
if (item->GetSlot() != i)
{
PSendSysMessage("item at slot %d, guid %d has an incorrect slot value: %d", i, item->GetGUIDLow(), item->GetSlot());
error = true; continue;
}
if (item->GetOwnerGUID() != player->GetGUID())
{
PSendSysMessage("for the item at slot %d and itemguid %d, owner's guid (%d) and player's guid (%d) don't match!", item->GetSlot(), item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow());
error = true; continue;
}
if (Bag *container = item->GetContainer())
{
PSendSysMessage("item at slot: %d guid: %d has a container (slot: %d, guid: %d) but shouldnt!", item->GetSlot(), item->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow());
error = true; continue;
}
if (item->IsInUpdateQueue())
{
uint16 qp = item->GetQueuePos();
@@ -526,13 +457,11 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
PSendSysMessage("item at slot: %d guid: %d has a queuepos (%d) larger than the update queue size! ", item->GetSlot(), item->GetGUIDLow(), qp);
error = true; continue;
}
if (updateQueue[qp] == NULL)
{
PSendSysMessage("item at slot: %d guid: %d has a queuepos (%d) that points to NULL in the queue!", item->GetSlot(), item->GetGUIDLow(), qp);
error = true; continue;
}
if (updateQueue[qp] != item)
{
PSendSysMessage("item at slot: %d guid: %d has has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, guid: %d)", item->GetSlot(), item->GetGUIDLow(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUIDLow());
@@ -544,7 +473,6 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
PSendSysMessage("item at slot: %d guid: %d is not in queue but should be (state: %d)!", item->GetSlot(), item->GetGUIDLow(), item->GetState());
error = true; continue;
}
if(item->IsBag())
{
Bag *bag = (Bag*)item;
@@ -552,32 +480,27 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
{
Item* item2 = bag->GetItemByPos(j);
if (!item2) continue;
if (item2->GetSlot() != j)
{
PSendSysMessage("the item in bag %d slot %d, guid %d has an incorrect slot value: %d", bag->GetSlot(), j, item2->GetGUIDLow(), item2->GetSlot());
error = true; continue;
}
if (item2->GetOwnerGUID() != player->GetGUID())
{
PSendSysMessage("for the item in bag %d at slot %d and itemguid %d, owner's guid (%d) and player's guid (%d) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), GUID_LOPART(item2->GetOwnerGUID()), player->GetGUIDLow());
error = true; continue;
}
Bag *container = item2->GetContainer();
if (!container)
{
PSendSysMessage("the item in bag %d at slot %d with guid %d has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow());
error = true; continue;
}
if (container != bag)
{
PSendSysMessage("the item in bag %d at slot %d with guid %d has a different container(slot %d guid %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow());
error = true; continue;
}
if (item2->IsInUpdateQueue())
{
uint16 qp = item2->GetQueuePos();
@@ -586,13 +509,11 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) larger than the update queue size! ", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp);
error = true; continue;
}
if (updateQueue[qp] == NULL)
{
PSendSysMessage("item in bag: %d at slot: %d guid: %d has a queuepos (%d) that points to NULL in the queue!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp);
error = true; continue;
}
if (updateQueue[qp] != item2)
{
PSendSysMessage("item in bag: %d at slot: %d guid: %d has has a queuepos (%d) that points to another item in the queue (bag: %d, slot: %d, guid: %d)", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), qp, updateQueue[qp]->GetBagSlot(), updateQueue[qp]->GetSlot(), updateQueue[qp]->GetGUIDLow());
@@ -607,33 +528,27 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
}
}
}
for(size_t i = 0; i < updateQueue.size(); ++i)
{
Item *item = updateQueue[i];
if(!item) continue;
if (item->GetOwnerGUID() != player->GetGUID())
{
PSendSysMessage("queue(" SIZEFMTD "): for the an item (guid %d), the owner's guid (%d) and player's guid (%d) don't match!", i, item->GetGUIDLow(), GUID_LOPART(item->GetOwnerGUID()), player->GetGUIDLow());
error = true; continue;
}
if (item->GetQueuePos() != i)
{
PSendSysMessage("queue(" SIZEFMTD "): for the an item (guid %d), the queuepos doesn't match it's position in the queue!", i, item->GetGUIDLow());
error = true; continue;
}
if (item->GetState() == ITEM_REMOVED) continue;
Item *test = player->GetItemByPos( item->GetBagSlot(), item->GetSlot());
if (test == NULL)
{
PSendSysMessage("queue(" SIZEFMTD "): the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the player doesn't have an item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow());
error = true; continue;
}
if (test != item)
{
PSendSysMessage("queue(" SIZEFMTD "): the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the item with guid %d is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow());
@@ -643,28 +558,23 @@ bool ChatHandler::HandleDebugGetItemStateCommand(const char* args)
if (!error)
SendSysMessage("All OK!");
}
return true;
}
bool ChatHandler::HandleDebugBattlegroundCommand(const char * /*args*/)
{
sBattleGroundMgr.ToggleTesting();
return true;
}
bool ChatHandler::HandleDebugArenaCommand(const char * /*args*/)
{
sBattleGroundMgr.ToggleArenaTesting();
return true;
}
bool ChatHandler::HandleDebugThreatList(const char * /*args*/)
{
Creature* target = getSelectedCreature();
if(!target || target->isTotem() || target->isPet())
return false;
std::list<HostilReference*>& tlist = target->getThreatManager().getThreatList();
std::list<HostilReference*>::iterator itr;
uint32 cnt = 0;
@@ -680,7 +590,6 @@ bool ChatHandler::HandleDebugThreatList(const char * /*args*/)
SendSysMessage("End of threat list.");
return true;
}
bool ChatHandler::HandleDebugHostilRefList(const char * /*args*/)
{
Unit* target = getSelectedUnit();
@@ -701,45 +610,35 @@ bool ChatHandler::HandleDebugHostilRefList(const char * /*args*/)
SendSysMessage("End of hostil reference list.");
return true;
}
bool ChatHandler::HandleDebugSetVehicleId(const char *args)
{
Unit* target = getSelectedUnit();
if(!target || target->IsVehicle())
return false;
if(!args)
return false;
char* i = strtok((char*)args, " ");
if(!i)
return false;
uint32 id = (uint32)atoi(i);
//target->SetVehicleId(id);
target->SendUpdateObjectToAllExcept(NULL);
PSendSysMessage("Vehicle id set to %u", id);
return true;
}
bool ChatHandler::HandleDebugEnterVehicle(const char * args)
{
Unit* target = getSelectedUnit();
if(!target || !target->IsVehicle())
return false;
if(!args)
return false;
char* i = strtok((char*)args, " ");
if(!i)
return false;
char* j = strtok(NULL, " ");
uint32 entry = (uint32)atoi(i);
int8 seatId = j ? (int8)atoi(j) : -1;
if(!entry)
m_session->GetPlayer()->EnterVehicle(target, seatId);
else
@@ -752,57 +651,39 @@ bool ChatHandler::HandleDebugEnterVehicle(const char * args)
return false;
passenger->EnterVehicle(target, seatId);
}
PSendSysMessage("Unit %u entered vehicle %d", entry, (int32)seatId);
return true;
}
bool ChatHandler::HandleDebugSpawnVehicle(const char* args)
{
if (!*args)
return false;
char* e = strtok((char*)args, " ");
char* i = strtok(NULL, " ");
if (!e)
return false;
uint32 entry = (uint32)atoi(e);
float x, y, z, o = m_session->GetPlayer()->GetOrientation();
m_session->GetPlayer()->GetClosePoint(x, y, z, m_session->GetPlayer()->GetObjectSize());
if(!i)
return m_session->GetPlayer()->SummonCreature(entry, x, y, z, o);
uint32 id = (uint32)atoi(i);
CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry);
if (!ci)
return false;
VehicleEntry const *ve = sVehicleStore.LookupEntry(id);
if (!ve)
return false;
Creature *v = new Creature;
Map *map = m_session->GetPlayer()->GetMap();
if(!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, m_session->GetPlayer()->GetPhaseMask(), entry, id, m_session->GetPlayer()->GetTeam(), x, y, z, o))
{
delete v;
return false;
}
map->Add((Creature*)v);
return true;
}
bool ChatHandler::HandleDebugSendLargePacketCommand(const char* /*args*/)
{
const char* stuffingString = "This is a dummy string to push the packet's size beyond 128000 bytes. ";
@@ -812,74 +693,54 @@ bool ChatHandler::HandleDebugSendLargePacketCommand(const char* /*args*/)
SendSysMessage(ss.str().c_str());
return true;
}
bool ChatHandler::HandleDebugSendSetPhaseShiftCommand(const char* args)
{
if (!*args)
return false;
uint32 PhaseShift = atoi(args);
m_session->SendSetPhaseShift(PhaseShift);
return true;
}
bool ChatHandler::HandleDebugSetItemFlagCommand(const char* args)
{
if (!*args)
return false;
char* e = strtok((char*)args, " ");
char* f = strtok(NULL, " ");
if (!e || !f)
return false;
uint32 guid = (uint32)atoi(e);
uint32 flag = (uint32)atoi(f);
Item *i = m_session->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM));
if (!i)
return false;
i->SetUInt32Value(ITEM_FIELD_FLAGS, flag);
return true;
}
bool ChatHandler::HandleDebugItemExpireCommand(const char* args)
{
if (!*args)
return false;
char* e = strtok((char*)args, " ");
if (!e)
return false;
uint32 guid = (uint32)atoi(e);
Item *i = m_session->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM));
if (!i)
return false;
m_session->GetPlayer()->DestroyItem( i->GetBagSlot(),i->GetSlot(), true);
Script->ItemExpire(m_session->GetPlayer(),i->GetProto());
return true;
}
//show animation
bool ChatHandler::HandleDebugAnimCommand(const char* args)
{
if (!*args)
return false;
uint32 anim_id = atoi((char*)args);
m_session->GetPlayer()->HandleEmoteCommand(anim_id);
return true;
}
bool ChatHandler::HandleDebugSetAuraStateCommand(const char* args)
{
if (!*args)
@@ -888,7 +749,6 @@ bool ChatHandler::HandleDebugSetAuraStateCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
Unit* unit = getSelectedUnit();
if (!unit)
{
@@ -896,7 +756,6 @@ bool ChatHandler::HandleDebugSetAuraStateCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
int32 state = atoi((char*)args);
if (!state)
{
@@ -905,23 +764,18 @@ bool ChatHandler::HandleDebugSetAuraStateCommand(const char* args)
unit->ModifyAuraState(AuraState(i),false);
return true;
}
unit->ModifyAuraState(AuraState(abs(state)),state > 0);
return true;
}
bool ChatHandler::HandleDebugSetValueCommand(const char* args)
{
if(!*args)
return false;
char* px = strtok((char*)args, " ");
char* py = strtok(NULL, " ");
char* pz = strtok(NULL, " ");
if (!px || !py)
return false;
WorldObject* target = getSelectedObject();
if(!target)
{
@@ -929,9 +783,7 @@ bool ChatHandler::HandleDebugSetValueCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
uint64 guid = target->GetGUID();
uint32 Opcode = (uint32)atoi(px);
if(Opcode >= target->GetValuesCount())
{
@@ -957,21 +809,16 @@ bool ChatHandler::HandleDebugSetValueCommand(const char* args)
target->SetFloatValue( Opcode , fValue );
PSendSysMessage(LANG_SET_FLOAT_FIELD, GUID_LOPART(guid), Opcode,fValue);
}
return true;
}
bool ChatHandler::HandleDebugGetValueCommand(const char* args)
{
if(!*args)
return false;
char* px = strtok((char*)args, " ");
char* pz = strtok(NULL, " ");
if (!px)
return false;
Unit* target = getSelectedUnit();
if(!target)
{
@@ -979,9 +826,7 @@ bool ChatHandler::HandleDebugGetValueCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
uint64 guid = target->GetGUID();
uint32 Opcode = (uint32)atoi(px);
if(Opcode >= target->GetValuesCount())
{
@@ -993,7 +838,6 @@ bool ChatHandler::HandleDebugGetValueCommand(const char* args)
bool isint32 = true;
if(pz)
isint32 = (bool)atoi(pz);
if(isint32)
{
iValue = target->GetUInt32Value( Opcode );
@@ -1006,52 +850,37 @@ bool ChatHandler::HandleDebugGetValueCommand(const char* args)
sLog.outDebug(GetTrinityString(LANG_GET_FLOAT), GUID_LOPART(guid), Opcode, fValue);
PSendSysMessage(LANG_GET_FLOAT_FIELD, GUID_LOPART(guid), Opcode, fValue);
}
return true;
}
bool ChatHandler::HandleDebugMod32ValueCommand(const char* args)
{
if(!*args)
return false;
char* px = strtok((char*)args, " ");
char* py = strtok(NULL, " ");
if (!px || !py)
return false;
uint32 Opcode = (uint32)atoi(px);
int Value = atoi(py);
if(Opcode >= m_session->GetPlayer()->GetValuesCount())
{
PSendSysMessage(LANG_TOO_BIG_INDEX, Opcode, m_session->GetPlayer()->GetGUIDLow(), m_session->GetPlayer( )->GetValuesCount());
return false;
}
sLog.outDebug(GetTrinityString(LANG_CHANGE_32BIT), Opcode, Value);
int CurrentValue = (int)m_session->GetPlayer( )->GetUInt32Value( Opcode );
CurrentValue += Value;
m_session->GetPlayer( )->SetUInt32Value( Opcode , (uint32)CurrentValue );
PSendSysMessage(LANG_CHANGE_32BIT_FIELD, Opcode,CurrentValue);
return true;
}
bool ChatHandler::HandleDebugUpdateCommand(const char* args)
{
if(!*args)
return false;
uint32 updateIndex;
uint32 value;
char* pUpdateIndex = strtok((char*)args, " ");
Unit* chr = getSelectedUnit();
if (chr == NULL)
{
@@ -1059,7 +888,6 @@ bool ChatHandler::HandleDebugUpdateCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
if(!pUpdateIndex)
{
return true;
@@ -1074,21 +902,15 @@ bool ChatHandler::HandleDebugUpdateCommand(const char* args)
{
if (updateIndex>=UNIT_END) return true;
}
char* pvalue = strtok(NULL, " ");
if (!pvalue)
{
value=chr->GetUInt32Value(updateIndex);
PSendSysMessage(LANG_UPDATE, chr->GetGUIDLow(),updateIndex,value);
return true;
}
value=atoi(pvalue);
PSendSysMessage(LANG_UPDATE_CHANGE, chr->GetGUIDLow(),updateIndex,value);
chr->SetUInt32Value(updateIndex,value);
return true;
}
-1
View File
@@ -17,6 +17,5 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "DestinationHolder.h"
-9
View File
@@ -17,18 +17,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_DESTINATION_HOLDER_H
#define TRINITY_DESTINATION_HOLDER_H
#include "Platform/Define.h"
#include "Timer.h"
class WorldObject;
class Map;
#define TRAVELLER_UPDATE_INTERVAL 300
template<typename TRAVELLER>
class TRINITY_DLL_DECL DestinationHolder
{
@@ -38,11 +33,9 @@ class TRINITY_DLL_DECL DestinationHolder
bool i_destSet;
float i_fromX, i_fromY, i_fromZ;
float i_destX, i_destY, i_destZ;
public:
DestinationHolder() : i_tracker(TRAVELLER_UPDATE_INTERVAL), i_totalTravelTime(0), i_timeElapsed(0),
i_destSet(false), i_fromX(0), i_fromY(0), i_fromZ(0), i_destX(0), i_destY(0), i_destZ(0) {}
uint32 SetDestination(TRAVELLER &traveller, float dest_x, float dest_y, float dest_z, bool sendMove = true);
void GetDestination(float &x, float &y, float &z) const { x = i_destX; y = i_destY; z = i_destZ; }
bool UpdateExpired(void) const { return i_tracker.Passed(); }
@@ -57,10 +50,8 @@ class TRINITY_DLL_DECL DestinationHolder
void GetLocationNow(const Map * map, float &x, float &y, float &z, bool is3D = false) const;
void GetLocationNowNoMicroMovement(float &x, float &y, float &z) const; // For use without micro movement
float GetDistance3dFromDestSq(const WorldObject &obj) const;
private:
void _findOffSetPoint(float x1, float y1, float x2, float y2, float offset, float &x, float &y);
};
#endif
-24
View File
@@ -17,15 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_DESTINATIONHOLDERIMP_H
#define TRINITY_DESTINATIONHOLDERIMP_H
#include "MapManager.h"
#include "DestinationHolder.h"
#include <cmath>
template<typename TRAVELLER>
void
DestinationHolder<TRAVELLER>::_findOffSetPoint(float x1, float y1, float x2, float y2, float offset, float &x, float &y)
@@ -61,7 +57,6 @@ DestinationHolder<TRAVELLER>::_findOffSetPoint(float x1, float y1, float x2, flo
}
}
}
template<typename TRAVELLER>
uint32
DestinationHolder<TRAVELLER>::SetDestination(TRAVELLER &traveller, float dest_x, float dest_y, float dest_z, bool sendMove)
@@ -70,42 +65,34 @@ DestinationHolder<TRAVELLER>::SetDestination(TRAVELLER &traveller, float dest_x,
i_destX = dest_x;
i_destY = dest_y;
i_destZ = dest_z;
return StartTravel(traveller, sendMove);
}
template<typename TRAVELLER>
uint32
DestinationHolder<TRAVELLER>::StartTravel(TRAVELLER &traveller, bool sendMove)
{
if(!i_destSet) return 0;
i_fromX = traveller.GetPositionX();
i_fromY = traveller.GetPositionY();
i_fromZ = traveller.GetPositionZ();
i_totalTravelTime = traveller.GetTotalTrevelTimeTo(i_destX,i_destY,i_destZ);
i_timeElapsed = 0;
if(sendMove)
traveller.MoveTo(i_destX, i_destY, i_destZ, i_totalTravelTime);
return i_totalTravelTime;
}
template<typename TRAVELLER>
bool
DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff, bool micro_movement)
{
i_timeElapsed += diff;
// Update every TRAVELLER_UPDATE_INTERVAL
i_tracker.Update(diff);
if(!i_tracker.Passed())
return false;
else
ResetUpdate();
if(!i_destSet) return true;
float x, y, z;
if (!micro_movement)
GetLocationNowNoMicroMovement(x, y, z);
@@ -113,36 +100,29 @@ DestinationHolder<TRAVELLER>::UpdateTraveller(TRAVELLER &traveller, uint32 diff,
{
if (!traveller.GetTraveller().hasUnitState(UNIT_STAT_MOVING | UNIT_STAT_IN_FLIGHT))
return true;
if (traveller.GetTraveller().hasUnitState(UNIT_STAT_IN_FLIGHT))
GetLocationNow(traveller.GetTraveller().GetBaseMap() ,x, y, z, true); // Should reposition Object with right Coord, so I can bypass some Grid Relocation
else
GetLocationNow(traveller.GetTraveller().GetBaseMap(), x, y, z, false);
// Change movement computation to micro movement based on last tick coords, this makes system work
// even on multiple floors zones without hugh vmaps usage ;)
// Take care of underrun of uint32
if (i_totalTravelTime >= i_timeElapsed)
i_totalTravelTime -= i_timeElapsed; // Consider only the remaining part
else
i_totalTravelTime = 0;
i_timeElapsed = 0;
i_fromX = x; // and change origine
i_fromY = y; // then I take into account only micro movement
i_fromZ = z;
}
if (traveller.GetTraveller().GetPositionX() != x || traveller.GetTraveller().GetPositionY() != y || traveller.GetTraveller().GetPositionZ() != z)
{
float ori = traveller.GetTraveller().GetAngle(x, y);
traveller.Relocation(x, y, z, ori);
}
return true;
}
template<typename TRAVELLER>
void
DestinationHolder<TRAVELLER>::GetLocationNow(const Map * map, float &x, float &y, float &z, bool is3D) const
@@ -177,7 +157,6 @@ DestinationHolder<TRAVELLER>::GetLocationNow(const Map * map, float &x, float &y
}
}
}
template<typename TRAVELLER>
float
DestinationHolder<TRAVELLER>::GetDistance3dFromDestSq(const WorldObject &obj) const
@@ -186,14 +165,12 @@ DestinationHolder<TRAVELLER>::GetDistance3dFromDestSq(const WorldObject &obj) co
obj.GetPosition(x,y,z);
return (i_destX-x)*(i_destX-x)+(i_destY-y)*(i_destY-y)+(i_destZ-z)*(i_destZ-z);
}
template<typename TRAVELLER>
float
DestinationHolder<TRAVELLER>::GetDestinationDiff(float x, float y, float z) const
{
return sqrt(((x-i_destX)*(x-i_destX)) + ((y-i_destY)*(y-i_destY)) + ((z-i_destZ)*(z-i_destZ)));
}
template<typename TRAVELLER>
void
DestinationHolder<TRAVELLER>::GetLocationNowNoMicroMovement(float &x, float &y, float &z) const
@@ -212,6 +189,5 @@ DestinationHolder<TRAVELLER>::GetLocationNowNoMicroMovement(float &x, float &y,
z = i_fromZ + ((i_destZ - i_fromZ) * percent_passed);
}
}
#endif
-15
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "WorldPacket.h"
#include "WorldSession.h"
@@ -25,63 +24,49 @@
#include "Opcodes.h"
#include "UpdateData.h"
#include "Player.h"
void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket)
{
uint64 guid;
Player *pl;
Player *plTarget;
if(!GetPlayer()->duel) // ignore accept from duel-sender
return;
recvPacket >> guid;
pl = GetPlayer();
plTarget = pl->duel->opponent;
if(pl == pl->duel->initiator || !plTarget || pl == plTarget || pl->duel->startTime != 0 || plTarget->duel->startTime != 0)
return;
//sLog.outDebug( "WORLD: received CMSG_DUEL_ACCEPTED" );
DEBUG_LOG("Player 1 is: %u (%s)", pl->GetGUIDLow(),pl->GetName());
DEBUG_LOG("Player 2 is: %u (%s)", plTarget->GetGUIDLow(),plTarget->GetName());
time_t now = time(NULL);
pl->duel->startTimer = now;
plTarget->duel->startTimer = now;
WorldPacket data(SMSG_DUEL_COUNTDOWN, 4);
data << (uint32)3000; // 3 seconds
pl->GetSession()->SendPacket(&data);
plTarget->GetSession()->SendPacket(&data);
}
void WorldSession::HandleDuelCancelledOpcode(WorldPacket& recvPacket)
{
//sLog.outDebug( "WORLD: received CMSG_DUEL_CANCELLED" );
// no duel requested
if(!GetPlayer()->duel)
return;
// player surrendered in a duel using /forfeit
if(GetPlayer()->duel->startTime != 0)
{
GetPlayer()->CombatStopWithPets(true);
if(GetPlayer()->duel->opponent)
GetPlayer()->duel->opponent->CombatStopWithPets(true);
GetPlayer()->CastSpell(GetPlayer(), SPELL_ID_DUEL_BEG, true); // beg
GetPlayer()->DuelComplete(DUEL_WON);
return;
}
// player either discarded the duel using the "discard button"
// or used "/forfeit" before countdown reached 0
uint64 guid;
recvPacket >> guid;
GetPlayer()->DuelComplete(DUEL_INTERUPTED);
}
-24
View File
@@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
#include "UpdateMask.h"
#include "Opcodes.h"
@@ -27,17 +26,13 @@
#include "GridNotifiers.h"
#include "CellImpl.h"
#include "GridNotifiersImpl.h"
DynamicObject::DynamicObject() : WorldObject()
{
m_objectType |= TYPEMASK_DYNAMICOBJECT;
m_objectTypeId = TYPEID_DYNAMICOBJECT;
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);
m_valuesCount = DYNAMICOBJECT_END;
}
void DynamicObject::AddToWorld()
{
///- Register the dynamicObject for guid lookup
@@ -47,7 +42,6 @@ void DynamicObject::AddToWorld()
WorldObject::AddToWorld();
}
}
void DynamicObject::RemoveFromWorld()
{
///- Remove the dynamicObject from the accessor
@@ -69,7 +63,6 @@ void DynamicObject::RemoveFromWorld()
ObjectAccessor::Instance().RemoveObject(this);
}
}
bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 effMask, const Position &pos, int32 duration, float radius, bool active)
{
SetMap(caster->GetMap());
@@ -79,9 +72,7 @@ bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32
sLog.outError("DynamicObject (spell %u eff %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,effMask,GetPositionX(),GetPositionY());
return false;
}
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetPhaseMask());
SetEntry(spellId);
SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
SetUInt64Value( DYNAMICOBJECT_CASTER, caster->GetGUID() );
@@ -92,23 +83,19 @@ bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32
SetFloatValue( DYNAMICOBJECT_POS_Y, pos.m_positionY );
SetFloatValue( DYNAMICOBJECT_POS_Z, pos.m_positionZ );
SetUInt32Value( DYNAMICOBJECT_CASTTIME, getMSTime() ); // new 2.4.0
m_aliveDuration = duration;
m_radius = radius;
m_effMask = effMask;
m_spellId = spellId;
m_updateTimer = 0;
m_isWorldObject = active;
return true;
}
Unit* DynamicObject::GetCaster() const
{
// can be not found in some cases
return ObjectAccessor::GetUnit(*this, GetCasterGUID());
}
void DynamicObject::Update(uint32 p_time)
{
// caster can be not in world at time dynamic object update, but dynamic object not yet deleted in Unit destructor
@@ -118,14 +105,11 @@ void DynamicObject::Update(uint32 p_time)
Delete();
return;
}
bool deleteThis = false;
if(m_aliveDuration > int32(p_time))
m_aliveDuration -= p_time;
else
deleteThis = true;
/*
// have radius and work as persistent effect
if(m_radius)
@@ -135,18 +119,14 @@ void DynamicObject::Update(uint32 p_time)
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::DynamicObjectUpdater notifier(*this, caster);
TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, WorldTypeMapContainer > world_object_notifier(notifier);
TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, world_object_notifier, *GetMap(), *this, m_radius);
cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap(), *this, m_radius);
}
*/
if (m_effMask)
{
if (m_updateTimer < p_time)
@@ -156,21 +136,18 @@ void DynamicObject::Update(uint32 p_time)
m_updateTimer = 500; // is this official-like?
} else m_updateTimer -= p_time;
}
if (deleteThis)
{
caster->RemoveDynObjectWithGUID(GetGUID());
Delete();
}
}
void DynamicObject::Delete()
{
SendObjectDeSpawnAnim(GetGUID());
RemoveFromWorld();
AddObjectToRemoveList();
}
void DynamicObject::Delay(int32 delaytime)
{
m_aliveDuration -= delaytime;
@@ -178,7 +155,6 @@ void DynamicObject::Delay(int32 delaytime)
if (*iunit)
(*iunit)->DelayAura(m_spellId, GetCaster()->GetGUID(), delaytime);
}
bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const
{
return IsInWorld() && u->IsInWorld()
-8
View File
@@ -17,24 +17,18 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_DYNAMICOBJECT_H
#define TRINITYCORE_DYNAMICOBJECT_H
#include "Object.h"
class Unit;
struct SpellEntry;
class DynamicObject : public WorldObject
{
public:
typedef std::set<Unit*> AffectedSet;
explicit DynamicObject();
void AddToWorld();
void RemoveFromWorld();
bool Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 effMask, const Position &pos, int32 duration, float radius, bool active);
void Update(uint32 p_time);
void Delete();
@@ -51,13 +45,11 @@ class DynamicObject : public WorldObject
void RemoveAffected(Unit *unit) { m_affected.erase(unit); }
void Delay(int32 delaytime);
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); }
void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); }
void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
GridReference<DynamicObject> &GetGridRef() { return m_gridRef; }
protected:
uint32 m_spellId;
-51
View File
@@ -17,66 +17,53 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Creature.h"
#include "CreatureAI.h"
#include "MapManager.h"
#include "FleeingMovementGenerator.h"
#include "DestinationHolderImp.h"
#include "ObjectAccessor.h"
#define MIN_QUIET_DISTANCE 28.0f
#define MAX_QUIET_DISTANCE 43.0f
template<class T>
void
FleeingMovementGenerator<T>::_setTargetLocation(T &owner)
{
if( !&owner )
return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
return;
if(!_setMoveData(owner))
return;
float x, y, z;
if(!_getPoint(owner, x, y, z))
return;
owner.addUnitState(UNIT_STAT_FLEEING | UNIT_STAT_ROAMING);
Traveller<T> traveller(owner);
i_destinationHolder.SetDestination(traveller, x, y, z);
}
template<>
bool FleeingMovementGenerator<Creature>::GetDestination(float &x, float &y, float &z) const
{
if(i_destinationHolder.HasArrived())
return false;
i_destinationHolder.GetDestination(x, y, z);
return true;
}
template<>
bool FleeingMovementGenerator<Player>::GetDestination(float &x, float &y, float &z) const
{
return false;
}
template<class T>
bool
FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
{
if(!&owner)
return false;
x = owner.GetPositionX();
y = owner.GetPositionY();
z = owner.GetPositionZ();
float temp_x, temp_y, angle;
const Map * _map = owner.GetBaseMap();
//primitive path-finding
@@ -84,9 +71,7 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
{
if(i_only_forward && i > 2)
break;
float distance = 5.0f;
switch(i)
{
case 0:
@@ -164,7 +149,6 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
if( owner.IsWithinLOS(temp_x,temp_y,z))
{
bool is_water_now = _map->IsInWater(x,y,z);
if(is_water_now && _map->IsInWater(temp_x,temp_y,z))
{
x = temp_x;
@@ -172,15 +156,11 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
return true;
}
float new_z = _map->GetHeight(temp_x,temp_y,z,true);
if(new_z <= INVALID_HEIGHT)
continue;
bool is_water_next = _map->IsInWater(temp_x,temp_y,new_z);
if((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok))
continue;
if( !(new_z - z) || distance / fabs(new_z - z) > 1.0f)
{
float new_z_left = _map->GetHeight(temp_x + 1.0f*cos(angle+M_PI/2),temp_y + 1.0f*sin(angle+M_PI/2),z,true);
@@ -199,13 +179,11 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
i_nextCheckTime.Reset( urand(500,1000) );
return false;
}
template<class T>
bool
FleeingMovementGenerator<T>::_setMoveData(T &owner)
{
float cur_dist_xyz = owner.GetDistance(i_caster_x, i_caster_y, i_caster_z);
if(i_to_distance_from_caster > 0.0f)
{
if((i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz < i_to_distance_from_caster) ||
@@ -230,12 +208,9 @@ FleeingMovementGenerator<T>::_setMoveData(T &owner)
return true;
}
}
float cur_dist;
float angle_to_caster;
Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
if(fright)
{
cur_dist = fright->GetDistance(&owner);
@@ -257,13 +232,10 @@ FleeingMovementGenerator<T>::_setMoveData(T &owner)
cur_dist = cur_dist_xyz;
angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
}
// if we too close may use 'path-finding' else just stop
i_only_forward = cur_dist >= MIN_QUIET_DISTANCE/3;
//get angle and 'distance from caster' to run
float angle;
if(i_cur_angle == 0.0f && i_last_distance_from_caster == 0.0f) //just started, first time
{
angle = rand_norm()*(1.0f - cur_dist/MIN_QUIET_DISTANCE) * M_PI/3 + rand_norm()*M_PI*2/3;
@@ -285,30 +257,24 @@ FleeingMovementGenerator<T>::_setMoveData(T &owner)
angle = rand_norm()*M_PI;
i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
}
int8 sign = rand_norm() > 0.5f ? 1 : -1;
i_cur_angle = sign*angle + angle_to_caster;
// current distance
i_last_distance_from_caster = cur_dist;
return true;
}
template<class T>
void
FleeingMovementGenerator<T>::Initialize(T &owner)
{
if(!&owner)
return;
_Init(owner);
owner.CastStop();
owner.addUnitState(UNIT_STAT_FLEEING | UNIT_STAT_ROAMING);
owner.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
owner.SetUInt64Value(UNIT_FIELD_TARGET, 0);
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
if(Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID))
{
i_caster_x = fright->GetPositionX();
@@ -321,25 +287,21 @@ FleeingMovementGenerator<T>::Initialize(T &owner)
i_caster_y = owner.GetPositionY();
i_caster_z = owner.GetPositionZ();
}
i_only_forward = true;
i_cur_angle = 0.0f;
i_last_distance_from_caster = 0.0f;
i_to_distance_from_caster = 0.0f;
_setTargetLocation(owner);
}
template<>
void
FleeingMovementGenerator<Creature>::_Init(Creature &owner)
{
if(!&owner)
return;
is_water_ok = owner.canSwim();
is_land_ok = owner.canWalk();
}
template<>
void
FleeingMovementGenerator<Player>::_Init(Player &)
@@ -347,7 +309,6 @@ FleeingMovementGenerator<Player>::_Init(Player &)
is_water_ok = true;
is_land_ok = true;
}
template<class T>
void
FleeingMovementGenerator<T>::Finalize(T &owner)
@@ -357,14 +318,12 @@ FleeingMovementGenerator<T>::Finalize(T &owner)
if(owner.GetTypeId() == TYPEID_UNIT && owner.getVictim())
owner.SetUInt64Value(UNIT_FIELD_TARGET, owner.getVictim()->GetGUID());
}
template<class T>
void
FleeingMovementGenerator<T>::Reset(T &owner)
{
Initialize(owner);
}
template<class T>
bool
FleeingMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
@@ -373,17 +332,13 @@ FleeingMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
return false;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
return true;
Traveller<T> traveller(owner);
i_nextCheckTime.Update(time_diff);
if( (owner.IsStopped() && !i_destinationHolder.HasArrived()) || !i_destinationHolder.HasDestination() )
{
_setTargetLocation(owner);
return true;
}
if (i_destinationHolder.UpdateTraveller(traveller, time_diff))
{
i_destinationHolder.ResetUpdate(50);
@@ -395,7 +350,6 @@ FleeingMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
}
return true;
}
template void FleeingMovementGenerator<Player>::Initialize(Player &);
template void FleeingMovementGenerator<Creature>::Initialize(Creature &);
template bool FleeingMovementGenerator<Player>::_setMoveData(Player &);
@@ -410,7 +364,6 @@ template void FleeingMovementGenerator<Player>::Reset(Player &);
template void FleeingMovementGenerator<Creature>::Reset(Creature &);
template bool FleeingMovementGenerator<Player>::Update(Player &, const uint32 &);
template bool FleeingMovementGenerator<Creature>::Update(Creature &, const uint32 &);
void TimedFleeingMovementGenerator::Finalize(Unit &owner)
{
owner.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
@@ -424,19 +377,15 @@ void TimedFleeingMovementGenerator::Finalize(Unit &owner)
}
}
}
bool TimedFleeingMovementGenerator::Update(Unit & owner, const uint32 & time_diff)
{
if( !owner.isAlive() )
return false;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
return true;
i_totalFleeTime.Update(time_diff);
if (i_totalFleeTime.Passed())
return false;
// This calls grant-parent Update method hiden by FleeingMovementGenerator::Update(Creature &, const uint32 &) version
// This is done instead of casting Unit& to Creature& and call parent method, then we can use Unit directly
return MovementGeneratorMedium< Creature, FleeingMovementGenerator<Creature> >::Update(owner, time_diff);
-13
View File
@@ -17,39 +17,31 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_FLEEINGMOVEMENTGENERATOR_H
#define TRINITY_FLEEINGMOVEMENTGENERATOR_H
#include "MovementGenerator.h"
#include "DestinationHolder.h"
#include "Traveller.h"
template<class T>
class TRINITY_DLL_SPEC FleeingMovementGenerator
: public MovementGeneratorMedium< T, FleeingMovementGenerator<T> >
{
public:
FleeingMovementGenerator(uint64 fright) : i_frightGUID(fright), i_nextCheckTime(0) {}
void Initialize(T &);
void Finalize(T &);
void Reset(T &);
bool Update(T &, const uint32 &);
bool GetDestination(float &x, float &y, float &z) const;
MovementGeneratorType GetMovementGeneratorType() { return FLEEING_MOTION_TYPE; }
private:
void _setTargetLocation(T &owner);
bool _getPoint(T &owner, float &x, float &y, float &z);
bool _setMoveData(T &owner);
void _Init(T &);
bool is_water_ok :1;
bool is_land_ok :1;
bool i_only_forward:1;
float i_caster_x;
float i_caster_y;
float i_caster_z;
@@ -58,10 +50,8 @@ class TRINITY_DLL_SPEC FleeingMovementGenerator
float i_cur_angle;
uint64 i_frightGUID;
TimeTracker i_nextCheckTime;
DestinationHolder< Traveller<T> > i_destinationHolder;
};
class MANGOS_DLL_SPEC TimedFleeingMovementGenerator
: public FleeingMovementGenerator<Creature>
{
@@ -69,14 +59,11 @@ class MANGOS_DLL_SPEC TimedFleeingMovementGenerator
TimedFleeingMovementGenerator(uint64 fright, uint32 time) :
FleeingMovementGenerator<Creature>(fright),
i_totalFleeTime(time) {}
MovementGeneratorType GetMovementGeneratorType() { return TIMED_FLEEING_MOTION_TYPE; }
bool Update(Unit &, const uint32 &);
void Finalize(Unit &);
private:
TimeTracker i_totalFleeTime;
};
#endif
-5
View File
@@ -17,18 +17,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _FOLLOWERREFMANAGER
#define _FOLLOWERREFMANAGER
#include "Utilities/LinkedReference/RefManager.h"
class Unit;
class TargetedMovementGeneratorBase;
class FollowerRefManager : public RefManager<Unit, TargetedMovementGeneratorBase>
{
};
#endif
-4
View File
@@ -17,21 +17,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Unit.h"
#include "TargetedMovementGenerator.h"
#include "FollowerReference.h"
void FollowerReference::targetObjectBuildLink()
{
getTarget()->addFollower(this);
}
void FollowerReference::targetObjectDestroyLink()
{
getTarget()->removeFollower(this);
}
void FollowerReference::sourceObjectDestroyLink()
{
getSource()->stopFollowing();
-4
View File
@@ -17,15 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _FOLLOWERREFERENCE_H
#define _FOLLOWERREFERENCE_H
#include "Utilities/LinkedReference/Reference.h"
class TargetedMovementGeneratorBase;
class Unit;
class TRINITY_DLL_SPEC FollowerReference : public Reference<Unit, TargetedMovementGeneratorBase>
{
protected:
-13
View File
@@ -17,12 +17,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_FORMULAS_H
#define TRINITY_FORMULAS_H
#include "World.h"
namespace Trinity
{
namespace Honor
@@ -35,7 +32,6 @@ namespace Trinity
namespace XP
{
enum XPColorChar { RED, ORANGE, YELLOW, GREEN, GRAY };
inline uint32 GetGrayLevel(uint32 pl_level)
{
if( pl_level <= 5 )
@@ -47,7 +43,6 @@ namespace Trinity
else
return pl_level - 9;
}
inline XPColorChar GetColorCode(uint32 pl_level, uint32 mob_level)
{
if( mob_level >= pl_level + 5 )
@@ -61,7 +56,6 @@ namespace Trinity
else
return GRAY;
}
inline uint32 GetZeroDifference(uint32 pl_level)
{
if( pl_level < 8 ) return 5;
@@ -77,7 +71,6 @@ namespace Trinity
if( pl_level < 60 ) return 16;
return 17;
}
inline uint32 BaseGain(uint32 pl_level, uint32 mob_level, ContentLevels content)
{
uint32 nBaseExp;
@@ -90,7 +83,6 @@ namespace Trinity
sLog.outError("BaseGain: Unsupported content level %u",content);
nBaseExp = 45; break;
}
if( mob_level >= pl_level )
{
uint32 nLevelDiff = mob_level - pl_level;
@@ -109,24 +101,19 @@ namespace Trinity
return 0;
}
}
inline uint32 Gain(Player *pl, Unit *u)
{
if(u->GetTypeId()==TYPEID_UNIT && (
((Creature*)u)->isTotem() || ((Creature*)u)->isPet() ||
(((Creature*)u)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL) ))
return 0;
uint32 xp_gain= BaseGain(pl->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(u->GetMapId(),u->GetZoneId()));
if( xp_gain == 0 )
return 0;
if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isElite())
xp_gain *= 2;
return (uint32)(xp_gain*sWorld.getRate(RATE_XP_KILL));
}
inline float xp_in_group_rate(uint32 count, bool isRaid)
{
if(isRaid)
File diff suppressed because it is too large Load Diff
-15
View File
@@ -17,17 +17,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITY_GAMEEVENT_MGR_H
#define TRINITY_GAMEEVENT_MGR_H
#include "Common.h"
#include "SharedDefines.h"
#include "Platform/Define.h"
#include "Policies/Singleton.h"
#define max_ge_check_delay 86400 // 1 day in seconds
enum GameEventState
{
GAMEEVENT_NORMAL = 0, // standard game events
@@ -37,7 +33,6 @@ enum GameEventState
GAMEEVENT_WORLD_FINISHED = 4, // next events are started, unapply this one
GAMEEVENT_INTERNAL = 5, // never handled in update
};
struct GameEventFinishCondition
{
float reqNum; // required number // use float, since some events use percent
@@ -45,14 +40,12 @@ struct GameEventFinishCondition
uint32 max_world_state; // max resource count world state update id
uint32 done_world_state; // done resource count world state update id
};
struct GameEventQuestToEventConditionNum
{
uint16 event_id;
uint32 condition;
float num;
};
struct GameEventData
{
GameEventData() : start(1),end(0),nextstart(0),occurence(0),length(0),state(GAMEEVENT_NORMAL) {}
@@ -66,10 +59,8 @@ struct GameEventData
std::map<uint32 /*condition id*/, GameEventFinishCondition> conditions; // conditions to finish
std::set<uint16 /*gameevent id*/> prerequisite_events; // events that must be completed before starting this event
std::string description;
bool isValid() const { return ((length > 0) || (state > GAMEEVENT_NORMAL)); }
};
struct ModelEquip
{
uint32 modelid;
@@ -77,7 +68,6 @@ struct ModelEquip
uint32 modelid_prev;
uint32 equipement_id_prev;
};
struct NPCVendorEntry
{
uint32 entry; // creature entry
@@ -86,10 +76,8 @@ struct NPCVendorEntry
uint32 incrtime; // time for restore items amount if maxcount != 0
uint32 ExtendedCost;
};
class Player;
class Creature;
class GameEventMgr
{
public:
@@ -169,10 +157,7 @@ class GameEventMgr
GameEventGuidMap mGameEventCreatureGuids;
GameEventGuidMap mGameEventGameobjectGuids;
};
#define gameeventmgr Trinity::Singleton<GameEventMgr>::Instance()
TRINITY_DLL_SPEC bool IsHolidayActive(HolidayIds id);
#endif
+1 -240
View File
File diff suppressed because it is too large Load Diff
-54
View File
@@ -17,23 +17,19 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_GAMEOBJECT_H
#define TRINITYCORE_GAMEOBJECT_H
#include "Common.h"
#include "SharedDefines.h"
#include "Object.h"
#include "LootMgr.h"
#include "Database/DatabaseEnv.h"
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack(1)
#else
#pragma pack(push,1)
#endif
// from `gameobject_template`
struct GameObjectInfo
{
@@ -391,7 +387,6 @@ struct GameObjectInfo
uint32 startOpen; // 1
uint32 autoClose; // 2
} trapDoor;
// not use for specific field access (only for output with loop by all filed), also this determinate max union size
struct
{
@@ -399,7 +394,6 @@ struct GameObjectInfo
} raw;
};
uint32 ScriptId;
// helpers
bool IsDespawnAtAction() const
{
@@ -410,7 +404,6 @@ struct GameObjectInfo
default: return false;
}
}
uint32 GetLockId() const
{
switch(type)
@@ -429,7 +422,6 @@ struct GameObjectInfo
default: return 0;
}
}
bool GetDespawnPossibility() const // despawn at targeting of cast?
{
switch(type)
@@ -443,7 +435,6 @@ struct GameObjectInfo
default: return true;
}
}
uint32 GetCharges() const // despawn at uses amount
{
switch(type)
@@ -454,7 +445,6 @@ struct GameObjectInfo
default: return 0;
}
}
uint32 GetLinkedGameObjectEntry() const
{
switch(type)
@@ -465,7 +455,6 @@ struct GameObjectInfo
default: return 0;
}
}
uint32 GetAutoCloseTime() const
{
uint32 autoCloseTime = 0;
@@ -481,7 +470,6 @@ struct GameObjectInfo
}
return autoCloseTime / 0x10000;
}
uint32 GetLootId() const
{
switch(type)
@@ -492,9 +480,7 @@ struct GameObjectInfo
}
}
};
class OPvPCapturePoint;
union GameObjectValue
{
//29 GAMEOBJECT_TYPE_CAPTURE_POINT
@@ -508,20 +494,17 @@ union GameObjectValue
uint32 health;
}building;
};
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack()
#else
#pragma pack(pop)
#endif
struct GameObjectLocale
{
std::vector<std::string> Name;
std::vector<std::string> CastBarCaption;
};
// client side GO show states
enum GOState
{
@@ -529,9 +512,7 @@ enum GOState
GO_STATE_READY = 1, // show in world as ready (closed door close)
GO_STATE_ACTIVE_ALTERNATIVE = 2 // show in world as used in alt way and not reset (closed door open by cannon fire)
};
#define MAX_GO_STATE 3
// from `gameobject`
struct GameObjectData
{
@@ -554,7 +535,6 @@ struct GameObjectData
uint8 artKit;
bool dbData;
};
// For containers: [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY -> ...
// For bobber: GO_NOT_READY ->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED-><deleted>
// For door(closed):[GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY(close) -> ...
@@ -566,49 +546,37 @@ enum LootState
GO_ACTIVATED,
GO_JUST_DEACTIVATED
};
class Unit;
// 5 sec for bobber catch
#define FISHING_BOBBER_READY_TIME 5
class TRINITY_DLL_SPEC GameObject : public WorldObject
{
public:
explicit GameObject();
~GameObject();
void AddToWorld();
void RemoveFromWorld();
void CleanupsBeforeDelete();
bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit = 0);
void Update(uint32 p_time);
static GameObject* GetGameObject(WorldObject& object, uint64 guid);
GameObjectInfo const* GetGOInfo() const { return m_goInfo; }
GameObjectData const* GetGOData() const { return m_goData; }
GameObjectValue * GetGOValue() const { return m_goValue; }
bool IsTransport() const;
uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; }
void UpdateRotationFields(float rotation2 = 0.0f, float rotation3 = 0.0f);
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); }
void Whisper(int32 textId, uint64 receiver) { MonsterWhisper(textId,receiver); }
void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
// overwrite WorldObject function for proper name localization
const char* GetNameForLocaleIdx(int32 locale_idx) const;
void SaveToDB();
void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
bool LoadFromDB(uint32 guid, Map *map);
void DeleteFromDB();
void SetOwnerGUID(uint64 owner)
{
// Owner already found and different than expected owner - remove object from old owner
@@ -621,14 +589,12 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
}
uint64 GetOwnerGUID() const { return GetUInt64Value(OBJECT_FIELD_CREATED_BY); }
Unit* GetOwner(bool inWorld = true) const;
void SetSpellId(uint32 id)
{
m_spawnedByDefault = false; // all summoned object is despawned after delay
m_spellId = id;
}
uint32 GetSpellId() const { return m_spellId;}
time_t GetRespawnTime() const { return m_respawnTime; }
time_t GetRespawnTimeEx() const
{
@@ -638,7 +604,6 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
else
return now;
}
void SetRespawnTime(int32 respawn)
{
m_respawnTime = respawn > 0 ? time(NULL) + respawn : 0;
@@ -666,12 +631,9 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); }
void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); }
static void SetGoArtKit(uint8 artkit, GameObject *go, uint32 lowguid = 0);
void Use(Unit* user);
LootState getLootState() const { return m_lootState; }
void SetLootState(LootState s) { m_lootState = s; }
void AddToSkillupList(uint32 PlayerGuidLow) { m_SkillupList.push_back(PlayerGuidLow); }
bool IsInSkillupList(uint32 PlayerGuidLow) const
{
@@ -680,17 +642,12 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
return false;
}
void ClearSkillupList() { m_SkillupList.clear(); }
void AddUniqueUse(Player* player);
void AddUse() { ++m_usetimes; }
uint32 GetUseCount() const { return m_usetimes; }
uint32 GetUniqueUseCount() const { return m_unique_users.size(); }
void SaveRespawnTime();
Loot loot;
bool hasQuest(uint32 quest_id) const;
bool hasInvolvedQuest(uint32 quest_id) const;
bool ActivateToQuest(Player *pTarget) const;
@@ -698,24 +655,17 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
// 0 = use `gameobject`.`spawntimesecs`
void ResetDoorOrButton();
void TriggeringLinkedGameObject( uint32 trapEntry, Unit* target);
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
bool canDetectTrap(Player const* u, float distance) const;
GameObject* LookupFishingHoleAround(float range);
GridReference<GameObject> &GetGridRef() { return m_gridRef; }
void CastSpell(Unit *target, uint32 spell);
void SendCustomAnim();
bool IsInRange(float x, float y, float z, float radius) const;
void TakenDamage(uint32 damage);
void Rebuild();
void EventInform(uint32 eventId);
uint64 GetRotation() const { return m_rotation; }
protected:
uint32 m_spellId;
@@ -726,19 +676,15 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction).
// For traps this: spell casting cooldown, for doors/buttons: reset time.
std::list<uint32> m_SkillupList;
std::set<uint32> m_unique_users;
uint32 m_usetimes;
uint32 m_DBTableGuid; ///< For new or temporary gameobjects is 0 for saved it is lowguid
GameObjectInfo const* m_goInfo;
GameObjectData const* m_goData;
GameObjectValue * const m_goValue;
uint64 m_rotation;
private:
void SwitchDoorOrButton(bool activate, bool alternative = false);
GridReference<GameObject> m_gridRef;
};
#endif

Some files were not shown because too many files have changed in this diff Show More