feat(Core/Hooks): added collection of hooks to extends AC (#3047)

This collection of hooks comes from the Maelstrom project. It allows to release modules such as :
- 3v3-soloqueue
- 1v1 arena
- pvestats

and many others
This commit is contained in:
Kargatum
2021-04-13 18:26:39 +07:00
committed by GitHub
parent 911fbb377e
commit 2b3d46bd4f
46 changed files with 2053 additions and 278 deletions
+16
View File
@@ -5,6 +5,22 @@ MACRO(AC_ADD_SCRIPT path)
CU_ADD_GLOBAL("AC_SCRIPTS_SOURCES" "${path}") CU_ADD_GLOBAL("AC_SCRIPTS_SOURCES" "${path}")
ENDMACRO() ENDMACRO()
#
# AC_ADD_SCRIPTS
#
# This macro can be used to automatically load scripts for the ScriptMgr
# from a specified folder, instead of manually list them within the cmake
# NOTE: you must still manually specify the script loader header
#
MACRO(AC_ADD_SCRIPTS path)
CU_SUBDIRLIST(sub_DIRS ${path} TRUE TRUE)
FOREACH(subdir ${sub_DIRS})
file(GLOB sources "${subdir}/*.cpp" "${subdir}/*.h")
CU_LIST_ADD_CACHE(scripts_STAT_SRCS "${sources}")
ENDFOREACH()
ENDMACRO()
# #
# AC_ADD_SCRIPT_LOADER # AC_ADD_SCRIPT_LOADER
# #
@@ -828,6 +828,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!achievementCriteriaList) if (!achievementCriteriaList)
return; return;
sScriptMgr->OnBeforeCheckCriteria(this, achievementCriteriaList);
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList->begin(); i != achievementCriteriaList->end(); ++i) for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList->begin(); i != achievementCriteriaList->end(); ++i)
{ {
AchievementCriteriaEntry const* achievementCriteria = (*i); AchievementCriteriaEntry const* achievementCriteria = (*i);
@@ -838,6 +840,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!CanUpdateCriteria(achievementCriteria, achievement)) if (!CanUpdateCriteria(achievementCriteria, achievement))
continue; continue;
if (!sScriptMgr->CanCheckCriteria(this, achievementCriteria))
continue;
switch (type) switch (type)
{ {
// std. case: increment at 1 // std. case: increment at 1
@@ -1762,6 +1767,9 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
if (!progress) if (!progress)
return false; return false;
if (!sScriptMgr->IsCompletedCriteria(this, achievementCriteria, achievement, progress))
return false;
switch (achievementCriteria->requiredType) switch (achievementCriteria->requiredType)
{ {
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
@@ -2394,6 +2402,9 @@ bool AchievementGlobalMgr::IsRealmCompleted(AchievementEntry const* achievement)
if (itr->second == std::chrono::system_clock::time_point::min()) if (itr->second == std::chrono::system_clock::time_point::min())
return false; return false;
if (!sScriptMgr->IsRealmCompleted(this, achievement, itr->second))
return false;
if (itr->second == std::chrono::system_clock::time_point::max()) if (itr->second == std::chrono::system_clock::time_point::max())
return true; return true;
@@ -2403,6 +2414,8 @@ bool AchievementGlobalMgr::IsRealmCompleted(AchievementEntry const* achievement)
if (achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL) if (achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)
return (std::chrono::system_clock::now() - itr->second) > std::chrono::minutes(1); return (std::chrono::system_clock::now() - itr->second) > std::chrono::minutes(1);
sScriptMgr->SetRealmCompleted(achievement);
return true; return true;
} }
+98 -13
View File
@@ -101,6 +101,9 @@ bool ArenaTeam::AddMember(uint64 playerGuid)
playerClass = playerData->playerClass; playerClass = playerData->playerClass;
} }
if (!sScriptMgr->CanAddMember(this, playerGuid))
return false;
// Check if player is already in a similar arena team // Check if player is already in a similar arena team
if ((player && player->GetArenaTeamId(GetSlot())) || Player::GetArenaTeamIdFromStorage(GUID_LOPART(playerGuid), GetSlot()) != 0) if ((player && player->GetArenaTeamId(GetSlot())) || Player::GetArenaTeamIdFromStorage(GUID_LOPART(playerGuid), GetSlot()) != 0)
{ {
@@ -610,27 +613,24 @@ void ArenaTeam::MassInviteToEvent(WorldSession* session)
uint8 ArenaTeam::GetSlotByType(uint32 type) uint8 ArenaTeam::GetSlotByType(uint32 type)
{ {
uint8 slot = 0xFF; uint8 slot = 0xFF;
switch (type)
auto const& itr = ArenaSlotByType.find(type);
if (itr == ArenaSlotByType.end())
{ {
case ARENA_TEAM_2v2: sLog->outError("FATAL: Unknown arena team type %u for some arena team", type);
slot = 0; return slot;
break;
case ARENA_TEAM_3v3:
slot = 1;
break;
case ARENA_TEAM_5v5:
slot = 2;
break;
default:
break;
} }
//Get the changed slot type
slot = ArenaSlotByType.at(type);
// Get the changed slot type
sScriptMgr->OnGetSlotByType(type, slot); sScriptMgr->OnGetSlotByType(type, slot);
if (slot != 0xFF) if (slot != 0xFF)
{ {
return slot; return slot;
} }
sLog->outError("FATAL: Unknown arena team type %u for some arena team", type); sLog->outError("FATAL: Unknown arena team type %u for some arena team", type);
return 0xFF; return 0xFF;
} }
@@ -868,12 +868,14 @@ void ArenaTeam::MemberWon(Player* player, uint32 againstMatchmakerRating, int32
{ {
// update personal rating // update personal rating
int32 mod = GetRatingMod(itr->PersonalRating, againstMatchmakerRating, true); int32 mod = GetRatingMod(itr->PersonalRating, againstMatchmakerRating, true);
sScriptMgr->OnBeforeUpdatingPersonalRating(mod, GetType());
itr->ModifyPersonalRating(player, mod, GetType()); itr->ModifyPersonalRating(player, mod, GetType());
// update matchmaker rating (pussywizard: but don't allow it to go over team rating) // update matchmaker rating (pussywizard: but don't allow it to go over team rating)
if (itr->MatchMakerRating < Stats.Rating) if (itr->MatchMakerRating < Stats.Rating)
{ {
mod = std::min(MatchmakerRatingChange, Stats.Rating - itr->MatchMakerRating); mod = std::min(MatchmakerRatingChange, Stats.Rating - itr->MatchMakerRating);
sScriptMgr->OnBeforeUpdatingPersonalRating(mod, GetType());
itr->ModifyMatchmakerRating(mod, GetSlot()); itr->ModifyMatchmakerRating(mod, GetSlot());
} }
@@ -922,6 +924,9 @@ void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& playerPoints)
void ArenaTeam::SaveToDB() void ArenaTeam::SaveToDB()
{ {
if (!sScriptMgr->CanSaveToDB(this))
return;
// Save team and member stats to db // Save team and member stats to db
// Called after a match has ended or when calculating arena_points // Called after a match has ended or when calculating arena_points
@@ -997,3 +1002,83 @@ ArenaTeamMember* ArenaTeam::GetMember(uint64 guid)
return nullptr; return nullptr;
} }
uint8 ArenaTeam::GetReqPlayersForType(uint32 type)
{
auto const& itr = ArenaReqPlayersForType.find(type);
if (itr == ArenaReqPlayersForType.end())
{
sLog->outError("FATAL: Unknown arena type %u!", type);
return 0xFF;
}
return ArenaReqPlayersForType.at(type);
}
void ArenaTeam::CreateTempArenaTeam(std::vector<Player*> playerList, uint8 type, std::string const& teamName)
{
auto playerCountInTeam = static_cast<uint32>(playerList.size());
ASSERT(playerCountInTeam == GetReqPlayersForType(type));
// Generate new arena team id
TeamId = sArenaTeamMgr->GenerateTempArenaTeamId();
// Assign member variables
CaptainGuid = playerList[0]->GetGUID();
Type = type;
TeamName = teamName;
BackgroundColor = 0;
EmblemStyle = 0;
EmblemColor = 0;
BorderStyle = 0;
BorderColor = 0;
Stats.WeekGames = 0;
Stats.SeasonGames = 0;
Stats.Rating = 0;
Stats.WeekWins = 0;
Stats.SeasonWins = 0;
for (auto const& _player : playerList)
{
ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(_player->GetArenaTeamId(GetSlotByType(type)));
if (!team)
continue;
ArenaTeamMember newMember;
for (auto const& itr : Members)
newMember = itr;
Stats.WeekGames += team->Stats.WeekGames;
Stats.SeasonGames += team->Stats.SeasonGames;
Stats.Rating += team->GetRating();
Stats.WeekWins += team->Stats.WeekWins;
Stats.SeasonWins += team->Stats.SeasonWins;
Members.push_back(newMember);
}
Stats.WeekGames /= playerCountInTeam;
Stats.SeasonGames /= playerCountInTeam;
Stats.Rating /= playerCountInTeam;
Stats.WeekWins /= playerCountInTeam;
Stats.SeasonWins /= playerCountInTeam;
}
// init/update unordered_map ArenaSlotByType
std::unordered_map<uint32, uint8> ArenaTeam::ArenaSlotByType =
{
{ ARENA_TEAM_2v2, ARENA_SLOT_2v2},
{ ARENA_TEAM_3v3, ARENA_SLOT_3v3},
{ ARENA_TEAM_5v5, ARENA_SLOT_5v5}
};
// init/update unordered_map ArenaReqPlayersForType
std::unordered_map<uint8, uint8> ArenaTeam::ArenaReqPlayersForType =
{
{ ARENA_TYPE_2v2, 4},
{ ARENA_TYPE_3v3, 6},
{ ARENA_TYPE_5v5, 10}
};
+29
View File
@@ -58,6 +58,19 @@ enum ArenaTeamEvents
ERR_ARENA_TEAM_DISBANDED_S = 8 // captain name + arena team name ERR_ARENA_TEAM_DISBANDED_S = 8 // captain name + arena team name
}; };
// PLAYER_FIELD_ARENA_TEAM_INFO_1_1 offsets
enum ArenaTeamInfoType
{
ARENA_TEAM_ID = 0,
ARENA_TEAM_TYPE = 1, // new in 3.2 - team type?
ARENA_TEAM_MEMBER = 2, // 0 - captain, 1 - member
ARENA_TEAM_GAMES_WEEK = 3,
ARENA_TEAM_GAMES_SEASON = 4,
ARENA_TEAM_WINS_SEASON = 5,
ARENA_TEAM_PERSONAL_RATING = 6,
ARENA_TEAM_END = 7
};
/* /*
need info how to send these ones: need info how to send these ones:
ERR_ARENA_TEAM_YOU_JOIN_S - client show it automatically when accept invite ERR_ARENA_TEAM_YOU_JOIN_S - client show it automatically when accept invite
@@ -73,6 +86,13 @@ enum ArenaTeamTypes
ARENA_TEAM_5v5 = 5 ARENA_TEAM_5v5 = 5
}; };
enum ArenaSlot
{
ARENA_SLOT_2v2,
ARENA_SLOT_3v3,
ARENA_SLOT_5v5
};
struct ArenaTeamMember struct ArenaTeamMember
{ {
uint64 Guid; uint64 Guid;
@@ -118,9 +138,11 @@ public:
[[nodiscard]] uint32 GetType() const { return Type; } [[nodiscard]] uint32 GetType() const { return Type; }
[[nodiscard]] uint8 GetSlot() const { return GetSlotByType(GetType()); } [[nodiscard]] uint8 GetSlot() const { return GetSlotByType(GetType()); }
static uint8 GetSlotByType(uint32 type); static uint8 GetSlotByType(uint32 type);
static uint8 GetReqPlayersForType(uint32 type);
[[nodiscard]] uint64 GetCaptain() const { return CaptainGuid; } [[nodiscard]] uint64 GetCaptain() const { return CaptainGuid; }
[[nodiscard]] std::string const& GetName() const { return TeamName; } [[nodiscard]] std::string const& GetName() const { return TeamName; }
[[nodiscard]] const ArenaTeamStats& GetStats() const { return Stats; } [[nodiscard]] const ArenaTeamStats& GetStats() const { return Stats; }
void SetArenaTeamStats(ArenaTeamStats& stats) { Stats = stats; }
[[nodiscard]] uint32 GetRating() const { return Stats.Rating; } [[nodiscard]] uint32 GetRating() const { return Stats.Rating; }
uint32 GetAverageMMR(Group* group) const; uint32 GetAverageMMR(Group* group) const;
@@ -137,6 +159,7 @@ public:
[[nodiscard]] bool Empty() const { return Members.empty(); } [[nodiscard]] bool Empty() const { return Members.empty(); }
MemberList::iterator m_membersBegin() { return Members.begin(); } MemberList::iterator m_membersBegin() { return Members.begin(); }
MemberList::iterator m_membersEnd() { return Members.end(); } MemberList::iterator m_membersEnd() { return Members.end(); }
MemberList& GetMembers() { return Members; }
[[nodiscard]] bool IsMember(uint64 guid) const; [[nodiscard]] bool IsMember(uint64 guid) const;
ArenaTeamMember* GetMember(uint64 guid); ArenaTeamMember* GetMember(uint64 guid);
@@ -174,6 +197,12 @@ public:
void FinishWeek(); void FinishWeek();
void FinishGame(int32 mod, const Map* bgMap); void FinishGame(int32 mod, const Map* bgMap);
void CreateTempArenaTeam(std::vector<Player*> playerList, uint8 type, std::string const& teamName);
// Containers
static std::unordered_map<uint32, uint8> ArenaSlotByType; // Slot -> Type
static std::unordered_map<uint8, uint8> ArenaReqPlayersForType; // Type -> Players count
protected: protected:
uint32 TeamId; uint32 TeamId;
uint8 Type; uint8 Type;
+14 -1
View File
@@ -14,10 +14,14 @@
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "World.h" #include "World.h"
constexpr uint32 MAX_ARENA_TEAM_ID = 0xFFF00000;
constexpr uint32 MAX_TEMP_ARENA_TEAM_ID = 0xFFFFFFFE;
ArenaTeamMgr::ArenaTeamMgr() ArenaTeamMgr::ArenaTeamMgr()
{ {
NextArenaTeamId = 1; NextArenaTeamId = 1;
LastArenaLogId = 0; LastArenaLogId = 0;
NextTempArenaTeamId = 0xFFF00000;
} }
ArenaTeamMgr::~ArenaTeamMgr() ArenaTeamMgr::~ArenaTeamMgr()
@@ -114,14 +118,23 @@ void ArenaTeamMgr::RemoveArenaTeam(uint32 arenaTeamId)
uint32 ArenaTeamMgr::GenerateArenaTeamId() uint32 ArenaTeamMgr::GenerateArenaTeamId()
{ {
if (NextArenaTeamId >= 0xFFFFFFFE) if (NextArenaTeamId >= MAX_ARENA_TEAM_ID)
{ {
sLog->outError("Arena team ids overflow!! Can't continue, shutting down server. "); sLog->outError("Arena team ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE); World::StopNow(ERROR_EXIT_CODE);
} }
return NextArenaTeamId++; return NextArenaTeamId++;
} }
uint32 ArenaTeamMgr::GenerateTempArenaTeamId()
{
if (NextTempArenaTeamId >= MAX_TEMP_ARENA_TEAM_ID)
NextTempArenaTeamId = MAX_ARENA_TEAM_ID;
return NextTempArenaTeamId++;
}
void ArenaTeamMgr::LoadArenaTeams() void ArenaTeamMgr::LoadArenaTeams()
{ {
uint32 oldMSTime = getMSTime(); uint32 oldMSTime = getMSTime();
@@ -31,6 +31,7 @@ public:
ArenaTeamContainer::iterator GetArenaTeamMapBegin() { return ArenaTeamStore.begin(); } ArenaTeamContainer::iterator GetArenaTeamMapBegin() { return ArenaTeamStore.begin(); }
ArenaTeamContainer::iterator GetArenaTeamMapEnd() { return ArenaTeamStore.end(); } ArenaTeamContainer::iterator GetArenaTeamMapEnd() { return ArenaTeamStore.end(); }
ArenaTeamContainer& GetArenaTeams() { return ArenaTeamStore; }
void DistributeArenaPoints(); void DistributeArenaPoints();
@@ -40,8 +41,11 @@ public:
uint32 GetNextArenaLogId() { return ++LastArenaLogId; } uint32 GetNextArenaLogId() { return ++LastArenaLogId; }
void SetLastArenaLogId(uint32 id) { LastArenaLogId = id; } void SetLastArenaLogId(uint32 id) { LastArenaLogId = id; }
uint32 GenerateTempArenaTeamId();
protected: protected:
uint32 NextArenaTeamId; uint32 NextArenaTeamId;
uint32 NextTempArenaTeamId;
ArenaTeamContainer ArenaTeamStore; ArenaTeamContainer ArenaTeamStore;
uint32 LastArenaLogId; uint32 LastArenaLogId;
}; };
@@ -1382,7 +1382,7 @@ void Battleground::ReadyMarkerClicked(Player* p)
return; return;
readyMarkerClickedSet.insert(p->GetGUIDLow()); readyMarkerClickedSet.insert(p->GetGUIDLow());
uint32 count = readyMarkerClickedSet.size(); uint32 count = readyMarkerClickedSet.size();
uint32 req = GetArenaType() * 2; uint32 req = ArenaTeam::GetReqPlayersForType(GetArenaType());
p->GetSession()->SendNotification("You are marked as ready %u/%u", count, req); p->GetSession()->SendNotification("You are marked as ready %u/%u", count, req);
if (count == req) if (count == req)
{ {
@@ -468,19 +468,7 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
// Set up correct min/max player counts for scoreboards // Set up correct min/max player counts for scoreboards
if (bg->isArena()) if (bg->isArena())
{ {
uint32 maxPlayersPerTeam = 0; uint32 maxPlayersPerTeam = ArenaTeam::GetReqPlayersForType(arenaType) / 2;
switch (arenaType)
{
case ARENA_TYPE_2v2:
maxPlayersPerTeam = 2;
break;
case ARENA_TYPE_3v3:
maxPlayersPerTeam = 3;
break;
case ARENA_TYPE_5v5:
maxPlayersPerTeam = 5;
break;
}
sScriptMgr->OnSetArenaMaxPlayersPerTeam(arenaType, maxPlayersPerTeam); sScriptMgr->OnSetArenaMaxPlayersPerTeam(arenaType, maxPlayersPerTeam);
bg->SetMaxPlayersPerTeam(maxPlayersPerTeam); bg->SetMaxPlayersPerTeam(maxPlayersPerTeam);
} }
@@ -748,31 +736,24 @@ bool BattlegroundMgr::IsArenaType(BattlegroundTypeId bgTypeId)
BattlegroundQueueTypeId BattlegroundMgr::BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType) BattlegroundQueueTypeId BattlegroundMgr::BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
{ {
if (arenaType) { uint32 queueTypeID = BATTLEGROUND_QUEUE_NONE;
uint32 queueTypeID = BATTLEGROUND_QUEUE_NONE;
switch (arenaType) {
case ARENA_TYPE_2v2:
queueTypeID = BATTLEGROUND_QUEUE_2v2;
break;
case ARENA_TYPE_3v3:
queueTypeID = BATTLEGROUND_QUEUE_3v3;
break;
case ARENA_TYPE_5v5:
queueTypeID = BATTLEGROUND_QUEUE_5v5;
break;
default:
break;
}
sScriptMgr->OnArenaTypeIDToQueueID(bgTypeId, arenaType, queueTypeID);
return BattlegroundQueueTypeId(queueTypeID);
}
if (BattlegroundMgr::bgToQueue.find(bgTypeId) == BattlegroundMgr::bgToQueue.end()) if (arenaType)
{ {
return BATTLEGROUND_QUEUE_NONE; if (BattlegroundMgr::ArenaTypeToQueue.find(arenaType) != BattlegroundMgr::ArenaTypeToQueue.end())
{
queueTypeID = BattlegroundMgr::ArenaTypeToQueue.at(arenaType);
}
sScriptMgr->OnArenaTypeIDToQueueID(bgTypeId, arenaType, queueTypeID);
} }
return BattlegroundMgr::bgToQueue[bgTypeId]; if (BattlegroundMgr::bgToQueue.find(bgTypeId) != BattlegroundMgr::bgToQueue.end())
{
queueTypeID = BattlegroundMgr::bgToQueue.at(bgTypeId);
}
return static_cast<BattlegroundQueueTypeId>(queueTypeID);
} }
BattlegroundTypeId BattlegroundMgr::BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId) BattlegroundTypeId BattlegroundMgr::BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId)
@@ -788,21 +769,14 @@ BattlegroundTypeId BattlegroundMgr::BGTemplateId(BattlegroundQueueTypeId bgQueue
uint8 BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId bgQueueTypeId) uint8 BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId bgQueueTypeId)
{ {
uint8 arenaType = 0; uint8 arenaType = 0;
switch (bgQueueTypeId)
if (BattlegroundMgr::QueueToArenaType.find(bgQueueTypeId) != BattlegroundMgr::QueueToArenaType.end())
{ {
case BATTLEGROUND_QUEUE_2v2: arenaType = BattlegroundMgr::QueueToArenaType.at(bgQueueTypeId);
arenaType = ARENA_TYPE_2v2;
break;
case BATTLEGROUND_QUEUE_3v3:
arenaType = ARENA_TYPE_3v3;
break;
case BATTLEGROUND_QUEUE_5v5:
arenaType = ARENA_TYPE_5v5;
break;
default:
break;
} }
sScriptMgr->OnArenaQueueIdToArenaType(bgQueueTypeId, arenaType); sScriptMgr->OnArenaQueueIdToArenaType(bgQueueTypeId, arenaType);
return arenaType; return arenaType;
} }
@@ -1166,3 +1140,17 @@ std::unordered_map<int, bgTypeRef> BattlegroundMgr::getBgFromTypeID =
} }
} }
}; };
std::unordered_map<uint32, BattlegroundQueueTypeId> BattlegroundMgr::ArenaTypeToQueue =
{
{ ARENA_TYPE_2v2, BATTLEGROUND_QUEUE_2v2 },
{ ARENA_TYPE_3v3, BATTLEGROUND_QUEUE_3v3 },
{ ARENA_TYPE_5v5, BATTLEGROUND_QUEUE_5v5 }
};
std::unordered_map<uint32, ArenaType> BattlegroundMgr::QueueToArenaType =
{
{ BATTLEGROUND_QUEUE_2v2, ARENA_TYPE_2v2 },
{ BATTLEGROUND_QUEUE_3v3, ARENA_TYPE_3v3 },
{ BATTLEGROUND_QUEUE_5v5, ARENA_TYPE_5v5 }
};
@@ -127,6 +127,8 @@ public:
static std::unordered_map<int, bgRef> bgTypeToTemplate; // BattlegroundTypeId -> bgRef static std::unordered_map<int, bgRef> bgTypeToTemplate; // BattlegroundTypeId -> bgRef
static std::unordered_map<int, bgMapRef> getBgFromMap; // BattlegroundMapID -> bgMapRef static std::unordered_map<int, bgMapRef> getBgFromMap; // BattlegroundMapID -> bgMapRef
static std::unordered_map<int, bgTypeRef> getBgFromTypeID; // BattlegroundTypeID -> bgTypeRef static std::unordered_map<int, bgTypeRef> getBgFromTypeID; // BattlegroundTypeID -> bgTypeRef
static std::unordered_map<uint32, BattlegroundQueueTypeId> ArenaTypeToQueue; // ArenaType -> BattlegroundQueueTypeId
static std::unordered_map<uint32, ArenaType> QueueToArenaType; // BattlegroundQueueTypeId -> ArenaType
private: private:
bool CreateBattleground(CreateBattlegroundData& data); bool CreateBattleground(CreateBattlegroundData& data);
@@ -152,9 +152,7 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, PvPDiffi
ginfo->_groupType = index; ginfo->_groupType = index;
// announce world (this doesn't need mutex) // announce world (this doesn't need mutex)
if (isRated && sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE)) SendMessageArenaQueue(ginfo, true);
if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(arenateamid))
sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, team->GetName().c_str(), ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
//add players from group to ginfo //add players from group to ginfo
if (grp) if (grp)
@@ -185,7 +183,7 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, PvPDiffi
return ginfo; return ginfo;
if (!isRated && !isPremade && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE)) if (!isRated && !isPremade && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
SendMessageQueue(leader, bg, bracketEntry); SendMessageBGQueue(leader, bg, bracketEntry);
return ginfo; return ginfo;
} }
@@ -298,9 +296,7 @@ void BattlegroundQueue::RemovePlayer(uint64 guid, bool sentToBg, uint32 playerQu
m_QueuedPlayers.erase(itr); m_QueuedPlayers.erase(itr);
// announce to world if arena team left queue for rated match, show only once // announce to world if arena team left queue for rated match, show only once
if (groupInfo->ArenaType && groupInfo->IsRated && groupInfo->Players.empty() && sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE)) SendMessageArenaQueue(groupInfo, false);
if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(groupInfo->ArenaTeamId))
sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, team->GetName().c_str(), groupInfo->ArenaType, groupInfo->ArenaType, groupInfo->ArenaTeamRating);
// if player leaves queue and he is invited to a rated arena match, then count it as he lost // if player leaves queue and he is invited to a rated arena match, then count it as he lost
if (groupInfo->IsInvitedToBGInstanceGUID && groupInfo->IsRated && !sentToBg) if (groupInfo->IsInvitedToBGInstanceGUID && groupInfo->IsRated && !sentToBg)
@@ -726,6 +722,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(BattlegroundBracketId bracket_id
MaxPlayersPerTeam = m_arenaType; MaxPlayersPerTeam = m_arenaType;
} }
sScriptMgr->OnQueueUpdate(this, bracket_id, isRated, arenaRatedTeamId);
// check if can start new premade battleground // check if can start new premade battleground
if (bg_template->isBattleground() && m_bgTypeId != BATTLEGROUND_RB) if (bg_template->isBattleground() && m_bgTypeId != BATTLEGROUND_RB)
if (CheckPremadeMatch(bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam)) if (CheckPremadeMatch(bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam))
@@ -963,9 +961,9 @@ bool BattlegroundQueue::IsAllQueuesEmpty(BattlegroundBracketId bracket_id)
return queueEmptyCount == BG_QUEUE_MAX; return queueEmptyCount == BG_QUEUE_MAX;
} }
void BattlegroundQueue::SendMessageQueue(Player* leader, Battleground* bg, PvPDifficultyEntry const* bracketEntry) void BattlegroundQueue::SendMessageBGQueue(Player* leader, Battleground* bg, PvPDifficultyEntry const* bracketEntry)
{ {
if (!sScriptMgr->CanSendMessageQueue(this, leader, bg, bracketEntry)) if (!sScriptMgr->CanSendMessageBGQueue(this, leader, bg, bracketEntry))
return; return;
BattlegroundBracketId bracketId = bracketEntry->GetBracketId(); BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
@@ -1004,6 +1002,32 @@ void BattlegroundQueue::SendMessageQueue(Player* leader, Battleground* bg, PvPDi
} }
} }
void BattlegroundQueue::SendMessageArenaQueue(GroupQueueInfo* ginfo, bool IsJoin)
{
if (!sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE))
return;
if (!sScriptMgr->CanSendMessageArenaQueue(this, ginfo, IsJoin))
return;
ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(ginfo->ArenaTeamId);
if (!team)
return;
if (!ginfo->IsRated)
return;
uint8 ArenaType = ginfo->ArenaType;
uint32 ArenaTeamRating = ginfo->ArenaTeamRating;
std::string TeamName = team->GetName();
if (IsJoin)
sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, TeamName.c_str(), ArenaType, ArenaType, ArenaTeamRating);
if (!IsJoin && ArenaType && ginfo->Players.empty())
sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, TeamName.c_str(), ArenaType, ArenaType, ArenaTeamRating);
}
/*********************************************************/ /*********************************************************/
/*** BATTLEGROUND QUEUE EVENTS ***/ /*** BATTLEGROUND QUEUE EVENTS ***/
/*********************************************************/ /*********************************************************/
@@ -71,7 +71,8 @@ public:
uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo) const; uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo) const;
uint32 GetPlayersCountInGroupsQueue(BattlegroundBracketId bracketId, BattlegroundQueueGroupTypes bgqueue); uint32 GetPlayersCountInGroupsQueue(BattlegroundBracketId bracketId, BattlegroundQueueGroupTypes bgqueue);
bool IsAllQueuesEmpty(BattlegroundBracketId bracket_id); bool IsAllQueuesEmpty(BattlegroundBracketId bracket_id);
void SendMessageQueue(Player* leader, Battleground* bg, PvPDifficultyEntry const* bracketEntry); void SendMessageBGQueue(Player* leader, Battleground* bg, PvPDifficultyEntry const* bracketEntry);
void SendMessageArenaQueue(GroupQueueInfo* ginfo, bool IsJoin);
void SetBgTypeIdAndArenaType(BattlegroundTypeId b, uint8 a) { m_bgTypeId = b; m_arenaType = ArenaType(a); } // pussywizard void SetBgTypeIdAndArenaType(BattlegroundTypeId b, uint8 a) { m_bgTypeId = b; m_arenaType = ArenaType(a); } // pussywizard
void AddEvent(BasicEvent* Event, uint64 e_time); void AddEvent(BasicEvent* Event, uint64 e_time);
@@ -110,6 +111,9 @@ public:
//one selection pool for horde, other one for alliance //one selection pool for horde, other one for alliance
SelectionPool m_SelectionPools[BG_TEAMS_COUNT]; SelectionPool m_SelectionPools[BG_TEAMS_COUNT];
ArenaType GetArenaType() { return m_arenaType; }
BattlegroundTypeId GetBGTypeID() { return m_bgTypeId; }
private: private:
BattlegroundTypeId m_bgTypeId; BattlegroundTypeId m_bgTypeId;
ArenaType m_arenaType; ArenaType m_arenaType;
+4 -1
View File
@@ -456,7 +456,7 @@ namespace lfg
} }
} }
sScriptMgr->OnInitializeLockedDungeons(player, level, lockData); sScriptMgr->OnInitializeLockedDungeons(player, level, lockData, dungeon);
/* TODO VoA closed if WG is not under team control (LFG_LOCKSTATUS_RAID_LOCKED) /* TODO VoA closed if WG is not under team control (LFG_LOCKSTATUS_RAID_LOCKED)
lockData = LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE; lockData = LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE;
@@ -500,6 +500,9 @@ namespace lfg
if (grp && (grp->isBGGroup() || grp->isBFGroup())) if (grp && (grp->isBGGroup() || grp->isBFGroup()))
return; return;
if (!sScriptMgr->CanJoinLfg(player, roles, dungeons, comment))
return;
// pussywizard: can't join LFG/LFR while using LFR // pussywizard: can't join LFG/LFR while using LFR
if (GetState(player->GetGUID()) == LFG_STATE_RAIDBROWSER) if (GetState(player->GetGUID()) == LFG_STATE_RAIDBROWSER)
{ {
@@ -11,6 +11,8 @@
#include "QuestDef.h" #include "QuestDef.h"
#include "WorldPacket.h" #include "WorldPacket.h"
#include "WorldSession.h" #include "WorldSession.h"
#include "Formulas.h"
#include "Player.h"
GossipMenu::GossipMenu() GossipMenu::GossipMenu()
{ {
@@ -420,7 +422,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID,
} }
data << uint32(quest->GetRewOrReqMoney()); data << uint32(quest->GetRewOrReqMoney());
data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST)); data << uint32(quest->XPValue(_session->GetPlayer()) * _session->GetPlayer()->GetQuestRate());
} }
// rewarded honor points. Multiply with 10 to satisfy client // rewarded honor points. Multiply with 10 to satisfy client
@@ -650,7 +652,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, b
} }
data << uint32(quest->GetRewOrReqMoney()); data << uint32(quest->GetRewOrReqMoney());
data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST)); data << uint32(quest->XPValue(_session->GetPlayer()) * _session->GetPlayer()->GetQuestRate());
// rewarded honor points. Multiply with 10 to satisfy client // rewarded honor points. Multiply with 10 to satisfy client
data << uint32(10 * quest->CalculateHonorGain(_session->GetPlayer()->GetQuestLevel(quest))); data << uint32(10 * quest->CalculateHonorGain(_session->GetPlayer()->GetQuestLevel(quest)));
+7 -2
View File
@@ -91,7 +91,11 @@ void AddItemsSetItem(Player* player, Item* item)
} }
// spell casted only if fit form requirement, in other case will casted at form change // spell casted only if fit form requirement, in other case will casted at form change
player->ApplyEquipSpell(spellInfo, nullptr, true); if (sScriptMgr->CanItemApplyEquipSpell(player, item))
{
player->ApplyEquipSpell(spellInfo, nullptr, true);
}
eff->spells[y] = spellInfo; eff->spells[y] = spellInfo;
break; break;
} }
@@ -266,6 +270,7 @@ bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner)
SetUInt32Value(ITEM_FIELD_DURATION, itemProto->Duration); SetUInt32Value(ITEM_FIELD_DURATION, itemProto->Duration);
SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, 0); SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, 0);
sScriptMgr->OnItemCreate(this, itemProto, owner);
return true; return true;
} }
@@ -423,7 +428,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entr
SetUInt32Value(ITEM_FIELD_FLAGS, fields[5].GetUInt32()); SetUInt32Value(ITEM_FIELD_FLAGS, fields[5].GetUInt32());
// Remove bind flag for items vs NO_BIND set // Remove bind flag for items vs NO_BIND set
if (IsSoulBound() && proto->Bonding == NO_BIND) if (IsSoulBound() && proto->Bonding == NO_BIND && sScriptMgr->CanApplySoulboundFlag(this, proto))
{ {
ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_SOULBOUND, false); ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_SOULBOUND, false);
need_save = true; need_save = true;
@@ -87,6 +87,8 @@ Object::Object() : m_PackGUID(sizeof(uint64) + 1)
m_objectUpdated = false; m_objectUpdated = false;
m_PackGUID.appendPackGUID(0); m_PackGUID.appendPackGUID(0);
sScriptMgr->OnConstructObject(this);
} }
WorldObject::~WorldObject() WorldObject::~WorldObject()
@@ -110,6 +112,8 @@ WorldObject::~WorldObject()
Object::~Object() Object::~Object()
{ {
sScriptMgr->OnDestructObject(this);
if (IsInWorld()) if (IsInWorld())
{ {
sLog->outCrash("Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in world!!", GetGUID(), GetTypeId(), GetEntry()); sLog->outCrash("Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in world!!", GetGUID(), GetTypeId(), GetEntry());
+16 -6
View File
@@ -15,6 +15,7 @@
#include "Log.h" #include "Log.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "Pet.h" #include "Pet.h"
#include "ScriptMgr.h"
#include "SpellAuraEffects.h" #include "SpellAuraEffects.h"
#include "SpellAuras.h" #include "SpellAuras.h"
#include "SpellMgr.h" #include "SpellMgr.h"
@@ -1073,6 +1074,8 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
} }
} }
sScriptMgr->OnInitStatsForLevel(this, petlevel);
UpdateAllStats(); UpdateAllStats();
SetFullHealth(); SetFullHealth();
@@ -1585,7 +1588,7 @@ void Pet::InitLevelupSpellsForLevel()
for (PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr) for (PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr)
{ {
// will called first if level down // will called first if level down
if (itr->first > level) if (itr->first > level && sScriptMgr->CanUnlearnSpellSet(this, itr->first, itr->second))
unlearnSpell(itr->second, true); // will learn prev rank if any unlearnSpell(itr->second, true); // will learn prev rank if any
// will called if level up // will called if level up
else else
@@ -1605,7 +1608,7 @@ void Pet::InitLevelupSpellsForLevel()
continue; continue;
// will called first if level down // will called first if level down
if (spellEntry->SpellLevel > level) if (spellEntry->SpellLevel > level && sScriptMgr->CanUnlearnSpellDefault(this, spellEntry))
unlearnSpell(spellEntry->Id, true); unlearnSpell(spellEntry->Id, true);
// will called if level up // will called if level up
else else
@@ -1710,6 +1713,9 @@ bool Pet::resetTalents()
if (!owner || owner->GetTypeId() != TYPEID_PLAYER) if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
return false; return false;
if (!sScriptMgr->CanResetTalents(this))
return false;
// not need after this call // not need after this call
if (owner->ToPlayer()->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) if (owner->ToPlayer()->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS))
owner->ToPlayer()->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS, true); owner->ToPlayer()->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS, true);
@@ -1863,16 +1869,17 @@ void Pet::InitTalentForLevel()
{ {
uint8 level = getLevel(); uint8 level = getLevel();
uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level); uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level);
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
return;
// Reset talents in case low level (on level down) or wrong points for level (hunter can unlearn TP increase talent) // Reset talents in case low level (on level down) or wrong points for level (hunter can unlearn TP increase talent)
if (talentPointsForLevel == 0 || m_usedTalentCount > talentPointsForLevel) if (talentPointsForLevel == 0 || m_usedTalentCount > talentPointsForLevel)
resetTalents(); // Remove all talent points resetTalents(); // Remove all talent points
SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount); SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount);
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
return;
if (!m_loading) if (!m_loading)
owner->ToPlayer()->SendTalentsInfoData(true); owner->ToPlayer()->SendTalentsInfoData(true);
} }
@@ -1883,6 +1890,9 @@ uint8 Pet::GetMaxTalentPointsForLevel(uint8 level)
// Mod points from owner SPELL_AURA_MOD_PET_TALENT_POINTS // Mod points from owner SPELL_AURA_MOD_PET_TALENT_POINTS
if (Unit* owner = GetOwner()) if (Unit* owner = GetOwner())
points += owner->GetTotalAuraModifier(SPELL_AURA_MOD_PET_TALENT_POINTS); points += owner->GetTotalAuraModifier(SPELL_AURA_MOD_PET_TALENT_POINTS);
sScriptMgr->OnCalculateMaxTalentPointsForLevel(this, level, points);
return points; return points;
} }
+212 -65
View File
@@ -611,9 +611,9 @@ void KillRewarder::_RewardPlayer(Player* player, bool isDungeon)
// Give reputation and kill credit only in PvE. // Give reputation and kill credit only in PvE.
if (!_isPvP || _isBattleGround) if (!_isPvP || _isBattleGround)
{ {
const float rate = _group ? float rate = _group ? _groupRate * float(player->getLevel()) / _sumLevel : /*Personal rate is 100%.*/ 1.0f; // Group rate depends on summary level.
_groupRate * float(player->getLevel()) / _sumLevel : // Group rate depends on summary level.
1.0f; // Personal rate is 100%. sScriptMgr->OnRewardKillRewarder(player, isDungeon, rate); // Personal rate is 100%.
if (_xp) if (_xp)
// 4.2. Give XP. // 4.2. Give XP.
_RewardXP(player, rate); _RewardXP(player, rate);
@@ -976,10 +976,14 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
m_applyResilience = true; m_applyResilience = true;
m_isInstantFlightOn = true; m_isInstantFlightOn = true;
sScriptMgr->OnConstructPlayer(this);
} }
Player::~Player() Player::~Player()
{ {
sScriptMgr->OnDestructPlayer(this);
// it must be unloaded already in PlayerLogout and accessed only for loggined player // it must be unloaded already in PlayerLogout and accessed only for loggined player
//m_social = nullptr; //m_social = nullptr;
@@ -3389,7 +3393,8 @@ void Player::GiveLevel(uint8 level)
if (Pet* pet = GetPet()) if (Pet* pet = GetPet())
pet->SynchronizeLevelWithOwner(); pet->SynchronizeLevelWithOwner();
if (MailLevelReward const* mailReward = sObjectMgr->GetMailLevelReward(level, getRaceMask())) MailLevelReward const* mailReward = sObjectMgr->GetMailLevelReward(level, getRaceMask());
if (mailReward && sScriptMgr->CanGiveMailRewardAtGiveLevel(this, level))
{ {
//- TODO: Poor design of mail system //- TODO: Poor design of mail system
SQLTransaction trans = CharacterDatabase.BeginTransaction(); SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -5144,6 +5149,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
stmt->setUInt32(0, guid); stmt->setUInt32(0, guid);
trans->Append(stmt); trans->Append(stmt);
sScriptMgr->OnDeleteFromDB(trans, guid);
CharacterDatabase.CommitTransaction(trans); CharacterDatabase.CommitTransaction(trans);
break; break;
} }
@@ -5713,6 +5720,9 @@ void Player::RepopAtGraveyard()
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetAreaId()); AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetAreaId());
if (!sScriptMgr->CanRepopAtGraveyard(this))
return;
// Such zones are considered unreachable as a ghost and the player must be automatically revived // Such zones are considered unreachable as a ghost and the player must be automatically revived
// Xinef: Get Transport Check is not needed // Xinef: Get Transport Check is not needed
if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) /*|| GetTransport()*/ || GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY())) if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) /*|| GetTransport()*/ || GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY()))
@@ -6803,6 +6813,7 @@ uint16 Player::GetMaxSkillValue(uint32 skill) const
uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos)); uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos));
int32 result = int32(SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos)))); int32 result = int32(SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))));
sScriptMgr->OnGetMaxSkillValue(const_cast<Player*>(this), skill, result, false);
result += SKILL_TEMP_BONUS(bonus); result += SKILL_TEMP_BONUS(bonus);
result += SKILL_PERM_BONUS(bonus); result += SKILL_PERM_BONUS(bonus);
return result < 0 ? 0 : result; return result < 0 ? 0 : result;
@@ -6817,7 +6828,11 @@ uint16 Player::GetPureMaxSkillValue(uint32 skill) const
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED) if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return 0; return 0;
return SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))); int32 result = int32(SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))));
sScriptMgr->OnGetMaxSkillValue(const_cast<Player*>(this), skill, result, true);
return result < 0 ? 0 : result;
} }
uint16 Player::GetBaseSkillValue(uint32 skill) const uint16 Player::GetBaseSkillValue(uint32 skill) const
@@ -7075,6 +7090,9 @@ void Player::CheckAreaExploreAndOutdoor()
if (sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK) && !isOutdoor) if (sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK) && !isOutdoor)
RemoveAurasWithAttribute(SPELL_ATTR0_OUTDOORS_ONLY); RemoveAurasWithAttribute(SPELL_ATTR0_OUTDOORS_ONLY);
if (!sScriptMgr->CanAreaExploreAndOutdoor(this))
return;
if (!areaId) if (!areaId)
return; return;
@@ -7466,6 +7484,8 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool awar
// [29..38] Other title and player name // [29..38] Other title and player name
// [39+] Nothing // [39+] Nothing
uint32 victim_title = victim->GetUInt32Value(PLAYER_CHOSEN_TITLE); uint32 victim_title = victim->GetUInt32Value(PLAYER_CHOSEN_TITLE);
uint32 killer_title = 0;
sScriptMgr->OnVictimRewardBefore(this, victim, killer_title, victim_title);
// Get Killer titles, CharTitlesEntry::bit_index // Get Killer titles, CharTitlesEntry::bit_index
// Ranks: // Ranks:
// title[1..14] -> rank[5..18] // title[1..14] -> rank[5..18]
@@ -7492,6 +7512,7 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool awar
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId()); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId());
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, victim); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, victim);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim);
sScriptMgr->OnVictimRewardAfter(this, victim, killer_title, victim_rank, honor_f);
} }
else else
{ {
@@ -7646,14 +7667,6 @@ uint32 Player::GetArenaTeamIdFromStorage(uint32 guid, uint8 slot)
return 0; return 0;
} }
void Player::SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value)
{
if (slot < MAX_ARENA_SLOT)
{
SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + type, value);
}
}
uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type) uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type)
{ {
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID);
@@ -8081,6 +8094,12 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
// req. check at equip, but allow use for extended range if range limit max level, set proper level // req. check at equip, but allow use for extended range if range limit max level, set proper level
uint32 ssd_level = getLevel(); uint32 ssd_level = getLevel();
uint32 CustomScalingStatValue = 0;
sScriptMgr->OnCustomScalingStatValueBefore(this, proto, slot, apply, CustomScalingStatValue);
uint32 ScalingStatValue = proto->ScalingStatValue > 0 ? proto->ScalingStatValue : CustomScalingStatValue;
if (ssd && ssd_level > ssd->MaxLevel) if (ssd && ssd_level > ssd->MaxLevel)
ssd_level = ssd->MaxLevel; ssd_level = ssd->MaxLevel;
@@ -8093,17 +8112,30 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
uint32 statType = 0; uint32 statType = 0;
int32 val = 0; int32 val = 0;
// If set ScalingStatDistribution need get stats and values from it // If set ScalingStatDistribution need get stats and values from it
if (ssd && ssv) if (ssv)
{ {
if (ssd->StatMod[i] < 0) if (ssd)
continue; {
statType = ssd->StatMod[i]; if (ssd->StatMod[i] < 0)
val = (ssv->getssdMultiplier(proto->ScalingStatValue) * ssd->Modifier[i]) / 10000; continue;
statType = ssd->StatMod[i];
val = (ssv->getssdMultiplier(ScalingStatValue) * ssd->Modifier[i]) / 10000;
}
else
{
if (i >= proto->StatsCount)
continue;
// OnCustomScalingStatValue(Player* player, ItemTemplate const* proto, uint32& statType, int32& val, uint8 itemProtoStatNumber, uint32 ScalingStatValue, ScalingStatValuesEntry const* ssv)
sScriptMgr->OnCustomScalingStatValue(this, proto, statType, val, i, ScalingStatValue, ssv);
}
} }
else else
{ {
if (i >= proto->StatsCount) if (i >= proto->StatsCount)
continue; continue;
statType = proto->ItemStat[i].ItemStatType; statType = proto->ItemStat[i].ItemStatType;
val = proto->ItemStat[i].ItemStatValue; val = proto->ItemStat[i].ItemStatValue;
} }
@@ -8262,15 +8294,16 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
// Apply Spell Power from ScalingStatValue if set // Apply Spell Power from ScalingStatValue if set
if (ssv) if (ssv)
if (int32 spellbonus = ssv->getSpellBonus(proto->ScalingStatValue)) if (int32 spellbonus = ssv->getSpellBonus(ScalingStatValue))
ApplySpellPowerBonus(spellbonus, apply); ApplySpellPowerBonus(spellbonus, apply);
// If set ScalingStatValue armor get it or use item armor // If set ScalingStatValue armor get it or use item armor
uint32 armor = proto->Armor; uint32 armor = proto->Armor;
if (ssv) if (ssv)
{ {
if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue)) if (uint32 ssvarmor = ssv->getArmorMod(ScalingStatValue))
armor = ssvarmor; if (proto->ScalingStatValue > 0 || ssvarmor < proto->Armor) //Check to avoid higher values than stat itself (heirloom OR items with correct armor value)
armor = ssvarmor;
} }
else if (armor && proto->ArmorDamageModifier) else if (armor && proto->ArmorDamageModifier)
armor -= uint32(proto->ArmorDamageModifier); armor -= uint32(proto->ArmorDamageModifier);
@@ -8295,7 +8328,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
} }
// Add armor bonus from ArmorDamageModifier if > 0 // Add armor bonus from ArmorDamageModifier if > 0
if (proto->ArmorDamageModifier > 0) if (proto->ArmorDamageModifier > 0 && sScriptMgr->CanArmorDamageModifier(this))
HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(proto->ArmorDamageModifier), apply); HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(proto->ArmorDamageModifier), apply);
if (proto->Block) if (proto->Block)
@@ -8342,11 +8375,12 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
int32 feral_bonus = 0; int32 feral_bonus = 0;
if (ssv) if (ssv)
{ {
dpsMod = ssv->getDPSMod(proto->ScalingStatValue); dpsMod = ssv->getDPSMod(ScalingStatValue);
feral_bonus += ssv->getFeralBonus(proto->ScalingStatValue); feral_bonus += ssv->getFeralBonus(ScalingStatValue);
} }
feral_bonus += proto->getFeralBonus(dpsMod); feral_bonus += proto->getFeralBonus(dpsMod);
sScriptMgr->OnGetFeralApBonus(this, feral_bonus, dpsMod, proto, ssv);
if (feral_bonus) if (feral_bonus)
ApplyFeralAPBonus(feral_bonus, apply); ApplyFeralAPBonus(feral_bonus, apply);
} }
@@ -8354,6 +8388,27 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply) void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply)
{ {
uint32 CustomScalingStatValue = 0;
sScriptMgr->OnCustomScalingStatValueBefore(this, proto, slot, apply, CustomScalingStatValue);
uint32 ScalingStatValue = proto->ScalingStatValue > 0 ? proto->ScalingStatValue : CustomScalingStatValue;
// following part fix disarm issue
// that doesn't apply the scaling after disarmed
if (!ssv)
{
ScalingStatDistributionEntry const* ssd = proto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution) : nullptr;
// req. check at equip, but allow use for extended range if range limit max level, set proper level
uint32 ssd_level = getLevel();
if (ssd && ssd_level > ssd->MaxLevel)
ssd_level = ssd->MaxLevel;
ssv = ScalingStatValue ? sScalingStatValuesStore.LookupEntry(ssd_level) : nullptr;
}
WeaponAttackType attType = BASE_ATTACK; WeaponAttackType attType = BASE_ATTACK;
float damage = 0.0f; float damage = 0.0f;
@@ -8374,7 +8429,7 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt
// If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage // If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage
if (ssv) if (ssv)
{ {
int32 extraDPS = ssv->getDPSMod(proto->ScalingStatValue); int32 extraDPS = ssv->getDPSMod(ScalingStatValue);
if (extraDPS) if (extraDPS)
{ {
float average = extraDPS * proto->Delay / 1000.0f; float average = extraDPS * proto->Delay / 1000.0f;
@@ -8438,6 +8493,9 @@ void Player::_ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attac
if (aura->GetSpellInfo()->EquippedItemClass == -1) if (aura->GetSpellInfo()->EquippedItemClass == -1)
return; return;
if (!sScriptMgr->CanApplyWeaponDependentAuraDamageMod(this, item, attackType, aura, apply))
return;
BaseModGroup mod = BASEMOD_END; BaseModGroup mod = BASEMOD_END;
switch (attackType) switch (attackType)
{ {
@@ -8548,6 +8606,9 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply,
{ {
if (apply) if (apply)
{ {
if (!sScriptMgr->CanApplyEquipSpell(this, spellInfo, item, apply, form_change))
return;
// Cannot be used in this stance/form // Cannot be used in this stance/form
if (spellInfo->CheckShapeshift(GetShapeshiftForm()) != SPELL_CAST_OK) if (spellInfo->CheckShapeshift(GetShapeshiftForm()) != SPELL_CAST_OK)
return; return;
@@ -8619,6 +8680,8 @@ void Player::UpdateEquipSpellsAtFormChange()
continue; continue;
ApplyEquipSpell(spellInfo, nullptr, false, true); // remove spells that not fit to form ApplyEquipSpell(spellInfo, nullptr, false, true); // remove spells that not fit to form
if (!sScriptMgr->CanApplyEquipSpellsItemSet(this, eff))
break;
ApplyEquipSpell(spellInfo, nullptr, true, true); // add spells that fit form but not active ApplyEquipSpell(spellInfo, nullptr, true, true); // add spells that fit form but not active
} }
} }
@@ -8671,6 +8734,9 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto) void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto)
{ {
if (!sScriptMgr->CanCastItemCombatSpell(this, target, attType, procVictim, procEx, item, proto))
return;
// Can do effect if any damage done to target // Can do effect if any damage done to target
if (procVictim & PROC_FLAG_TAKEN_DAMAGE) if (procVictim & PROC_FLAG_TAKEN_DAMAGE)
//if (damageInfo->procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE) //if (damageInfo->procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE)
@@ -8794,6 +8860,9 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex) void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex)
{ {
if (!sScriptMgr->CanCastItemUseSpell(this, item, targets, cast_count, glyphIndex))
return;
ItemTemplate const* proto = item->GetTemplate(); ItemTemplate const* proto = item->GetTemplate();
// special learning case // special learning case
if (proto->Spells[0].SpellId == 483 || proto->Spells[0].SpellId == 55884) if (proto->Spells[0].SpellId == 483 || proto->Spells[0].SpellId == 55884)
@@ -9056,6 +9125,8 @@ void Player::_ApplyAmmoBonuses()
else else
currentAmmoDPS = (ammo_proto->Damage[0].DamageMin + ammo_proto->Damage[0].DamageMax) / 2; currentAmmoDPS = (ammo_proto->Damage[0].DamageMin + ammo_proto->Damage[0].DamageMax) / 2;
sScriptMgr->OnApplyAmmoBonuses(this, ammo_proto, currentAmmoDPS);
if (currentAmmoDPS == GetAmmoDPS()) if (currentAmmoDPS == GetAmmoDPS())
return; return;
@@ -12047,6 +12118,9 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool
ItemTemplate const* pProto = pItem->GetTemplate(); ItemTemplate const* pProto = pItem->GetTemplate();
if (pProto) if (pProto)
{ {
if (!sScriptMgr->CanEquipItem(const_cast<Player*>(this), slot, dest, pItem, swap, not_loading))
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
// item used // item used
if (pItem->m_lootGenerated) if (pItem->m_lootGenerated)
return EQUIP_ERR_ALREADY_LOOTED; return EQUIP_ERR_ALREADY_LOOTED;
@@ -12208,6 +12282,9 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool
InventoryResult Player::CanUnequipItem(uint16 pos, bool swap) const InventoryResult Player::CanUnequipItem(uint16 pos, bool swap) const
{ {
if (!sScriptMgr->CanUnequipItem(const_cast<Player*>(this), pos, swap))
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
// Applied only to equipped items and bank bags // Applied only to equipped items and bank bags
if (!IsEquipmentPos(pos) && !IsBagPos(pos)) if (!IsEquipmentPos(pos) && !IsBagPos(pos))
return EQUIP_ERR_OK; return EQUIP_ERR_OK;
@@ -12529,6 +12606,11 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
if (proto->RequiredSpell != 0 && !HasSpell(proto->RequiredSpell)) if (proto->RequiredSpell != 0 && !HasSpell(proto->RequiredSpell))
return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
InventoryResult result = EQUIP_ERR_OK;
if (!sScriptMgr->CanUseItem(const_cast<Player*>(this), proto, result))
return result;
if (getLevel() < proto->RequiredLevel) if (getLevel() < proto->RequiredLevel)
return EQUIP_ERR_CANT_EQUIP_LEVEL_I; return EQUIP_ERR_CANT_EQUIP_LEVEL_I;
@@ -12872,7 +12954,11 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool
Item* Player::EquipNewItem(uint16 pos, uint32 item, bool update) Item* Player::EquipNewItem(uint16 pos, uint32 item, bool update)
{ {
if (Item* pItem = Item::CreateItem(item, 1, this)) Item* _item = Item::CreateItem(item, 1, this);
if (!_item)
return nullptr;
if (!IsEquipmentPos(pos) || sScriptMgr->CanSaveEquipNewItem(this, _item, pos, update))
{ {
// pussywizard: obtaining blue or better items saves to db // pussywizard: obtaining blue or better items saves to db
if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item)) if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item))
@@ -12881,10 +12967,9 @@ Item* Player::EquipNewItem(uint16 pos, uint32 item, bool update)
ItemAddedQuestCheck(item, 1); ItemAddedQuestCheck(item, 1);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, 1); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM, item, 1);
return EquipItem(pos, pItem, update);
} }
return nullptr; return EquipItem(pos, _item, update);
} }
Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) Item* Player::EquipItem(uint16 pos, Item* pItem, bool update)
@@ -14497,6 +14582,9 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
if (pEnchant->requiredSkill > 0 && pEnchant->requiredSkillValue > GetSkillValue(pEnchant->requiredSkill)) if (pEnchant->requiredSkill > 0 && pEnchant->requiredSkillValue > GetSkillValue(pEnchant->requiredSkill))
return; return;
if (!sScriptMgr->CanApplyEnchantment(this, item, slot, apply, apply_dur, ignore_condition))
return;
// If we're dealing with a gem inside a prismatic socket we need to check the prismatic socket requirements // If we're dealing with a gem inside a prismatic socket we need to check the prismatic socket requirements
// rather than the gem requirements itself. If the socket has no color it is a prismatic socket. // rather than the gem requirements itself. If the socket has no color it is a prismatic socket.
if ((slot == SOCK_ENCHANTMENT_SLOT || slot == SOCK_ENCHANTMENT_SLOT_2 || slot == SOCK_ENCHANTMENT_SLOT_3) if ((slot == SOCK_ENCHANTMENT_SLOT || slot == SOCK_ENCHANTMENT_SLOT_2 || slot == SOCK_ENCHANTMENT_SLOT_3)
@@ -16096,7 +16184,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
bool rewarded = IsQuestRewarded(quest_id) && !quest->IsDFQuest(); bool rewarded = IsQuestRewarded(quest_id) && !quest->IsDFQuest();
// Not give XP in case already completed once repeatable quest // Not give XP in case already completed once repeatable quest
uint32 XP = rewarded ? 0 : uint32(quest->XPValue(this) * sWorld->getRate(RATE_XP_QUEST)); uint32 XP = rewarded ? 0 : uint32(quest->XPValue(this) * GetQuestRate());
// handle SPELL_AURA_MOD_XP_QUEST_PCT auras // handle SPELL_AURA_MOD_XP_QUEST_PCT auras
Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT); Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT);
@@ -17252,6 +17340,9 @@ void Player::KilledMonsterCredit(uint32 entry, uint64 guid)
if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficulty()) || if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficulty()) ||
(qInfo->IsPVPQuest() && (GetGroup()->isBFGroup() || GetGroup()->isBGGroup())))) (qInfo->IsPVPQuest() && (GetGroup()->isBFGroup() || GetGroup()->isBGGroup()))))
{ {
if (!sScriptMgr->PassedQuestKilledMonsterCredit(this, qInfo, entry, real_entry, guid))
continue;
if (qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_KILL) /*&& !qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_CAST)*/) if (qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_KILL) /*&& !qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_CAST)*/)
{ {
for (uint8 j = 0; j < QUEST_OBJECTIVES_COUNT; ++j) for (uint8 j = 0; j < QUEST_OBJECTIVES_COUNT; ++j)
@@ -17801,8 +17892,8 @@ void Player::_LoadArenaTeamInfo()
{ {
memset((void*)&m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1], 0, sizeof(uint32) * MAX_ARENA_SLOT * ARENA_TEAM_END); memset((void*)&m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1], 0, sizeof(uint32) * MAX_ARENA_SLOT * ARENA_TEAM_END);
for (uint8 slot = 0; slot < MAX_ARENA_SLOT; ++slot) for (auto const& itr : ArenaTeam::ArenaSlotByType)
if (uint32 arenaTeamId = Player::GetArenaTeamIdFromStorage(GetGUIDLow(), slot)) if (uint32 arenaTeamId = Player::GetArenaTeamIdFromStorage(GetGUIDLow(), itr.second))
{ {
ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId); ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
if (!arenaTeam) // some shit, should be assert, but just ignore if (!arenaTeam) // some shit, should be assert, but just ignore
@@ -17811,6 +17902,8 @@ void Player::_LoadArenaTeamInfo()
if (!member) // some shit, should be assert, but just ignore if (!member) // some shit, should be assert, but just ignore
continue; continue;
uint8 slot = itr.second;
SetArenaTeamInfoField(slot, ARENA_TEAM_ID, arenaTeamId); SetArenaTeamInfoField(slot, ARENA_TEAM_ID, arenaTeamId);
SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, arenaTeam->GetType()); SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, arenaTeam->GetType());
SetArenaTeamInfoField(slot, ARENA_TEAM_MEMBER, (arenaTeam->GetCaptain() == GetGUID()) ? 0 : 1); SetArenaTeamInfoField(slot, ARENA_TEAM_MEMBER, (arenaTeam->GetCaptain() == GetGUID()) ? 0 : 1);
@@ -18874,7 +18967,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
else if (IsEquipmentPos(INVENTORY_SLOT_BAG_0, slot)) else if (IsEquipmentPos(INVENTORY_SLOT_BAG_0, slot))
{ {
uint16 dest; uint16 dest;
err = CanEquipItem(slot, dest, item, false, false); if (sScriptMgr->CheckItemInSlotAtLoadInventory(this, item, slot, err, dest))
err = CanEquipItem(slot, dest, item, false, false);
if (err == EQUIP_ERR_OK) if (err == EQUIP_ERR_OK)
QuickEquipItem(dest, item); QuickEquipItem(dest, item);
} }
@@ -19858,6 +19952,9 @@ bool Player::Satisfy(DungeonProgressionRequirements const* ar, uint32 target_map
|| missingPlayerItems.size() || missingPlayerQuests.size() || missingPlayerAchievements.size() || missingPlayerItems.size() || missingPlayerQuests.size() || missingPlayerAchievements.size()
|| missingLeaderItems.size() || missingLeaderQuests.size() || missingLeaderAchievements.size()) || missingLeaderItems.size() || missingLeaderQuests.size() || missingLeaderAchievements.size())
{ {
if (!sScriptMgr->NotAvoidSatisfy(partyLeader, ar, target_map, report))
return true;
if (report) if (report)
{ {
uint8 requirementPrintMode = sWorld->getIntConfig(CONFIG_DUNGEON_ACCESS_REQUIREMENTS_PRINT_MODE); uint8 requirementPrintMode = sWorld->getIntConfig(CONFIG_DUNGEON_ACCESS_REQUIREMENTS_PRINT_MODE);
@@ -22020,36 +22117,6 @@ void Player::LeaveAllArenaTeams(uint64 guid)
} while (result->NextRow()); } while (result->NextRow());
} }
uint32 Player::GetArenaTeamId(uint8 slot) const
{
uint32 rtVal = 0;
if (slot >= MAX_ARENA_SLOT)
{
sScriptMgr->GetCustomGetArenaTeamId(this, slot, rtVal);
}
else
{
rtVal = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_ID);
}
return rtVal;
}
uint32 Player::GetArenaPersonalRating(uint8 slot) const
{
uint32 rtVal = 0;
if (slot >= MAX_ARENA_SLOT)
{
sScriptMgr->GetCustomGetArenaTeamId(this, slot, rtVal);
}
else
{
rtVal = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING);
}
return rtVal;
}
void Player::SetRestBonus(float rest_bonus_new) void Player::SetRestBonus(float rest_bonus_new)
{ {
// Prevent resting on max level // Prevent resting on max level
@@ -22492,9 +22559,9 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
} }
} }
Item* it = bStore ? sScriptMgr->OnBeforeStoreOrEquipNewItem(this, vendorslot, item, count, bag, slot, pProto, pVendor, crItem, bStore);
StoreNewItem(vDest, item, true) :
EquipNewItem(uiDest, item, true); Item* it = bStore ? StoreNewItem(vDest, item, true) : EquipNewItem(uiDest, item, true);
if (it) if (it)
{ {
uint32 new_count = pVendor->UpdateVendorItemCurrentCount(crItem, pProto->BuyCount * count); uint32 new_count = pVendor->UpdateVendorItemCurrentCount(crItem, pProto->BuyCount * count);
@@ -22520,6 +22587,9 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
AddRefundReference(it->GetGUIDLow()); AddRefundReference(it->GetGUIDLow());
} }
} }
sScriptMgr->OnAfterStoreOrEquipNewItem(this, vendorslot, it, count, bag, slot, pProto, pVendor, crItem, bStore);
return true; return true;
} }
@@ -23371,6 +23441,9 @@ bool Player::IsVisibleGloballyFor(Player const* u) const
if (!AccountMgr::IsPlayerAccount(u->GetSession()->GetSecurity())) if (!AccountMgr::IsPlayerAccount(u->GetSession()->GetSecurity()))
return GetSession()->GetSecurity() <= u->GetSession()->GetSecurity(); return GetSession()->GetSecurity() <= u->GetSession()->GetSecurity();
if (!sScriptMgr->NotVisibleGloballyFor(const_cast<Player*>(this), u))
return true;
// non faction visibility non-breakable for non-GMs // non faction visibility non-breakable for non-GMs
return false; return false;
} }
@@ -28457,3 +28530,77 @@ void Player::RemoveRestFlag(RestFlag restFlag)
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
} }
} }
void Player::SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value)
{
if (sScriptMgr->NotSetArenaTeamInfoField(this, slot, type, value))
SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + type, value);
}
uint32 Player::GetArenaPersonalRating(uint8 slot) const
{
uint32 result = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING);
sScriptMgr->OnGetArenaPersonalRating(const_cast<Player*>(this), slot, result);
return result;
}
uint32 Player::GetArenaTeamId(uint8 slot) const
{
uint32 result = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_ID);
sScriptMgr->OnGetArenaTeamId(const_cast<Player*>(this), slot, result);
return result;
}
bool Player::IsFFAPvP()
{
bool result = Unit::IsFFAPvP();
sScriptMgr->OnIsFFAPvP(this, result);
return result;
}
bool Player::IsPvP()
{
bool result = Unit::IsPvP();
sScriptMgr->OnIsPvP(this, result);
return result;
}
uint16 Player::GetMaxSkillValueForLevel() const
{
uint16 result = Unit::GetMaxSkillValueForLevel();
sScriptMgr->OnGetMaxSkillValueForLevel(const_cast<Player*>(this), result);
return result;
}
float Player::GetQuestRate()
{
float result = sWorld->getRate(RATE_XP_QUEST);
sScriptMgr->OnGetQuestRate(this, result);
return result;
}
void Player::SetServerSideVisibility(ServerSideVisibilityType type, AccountTypes sec)
{
sScriptMgr->OnSetServerSideVisibility(this, type, sec);
m_serverSideVisibility.SetValue(type, sec);
}
void Player::SetServerSideVisibilityDetect(ServerSideVisibilityType type, AccountTypes sec)
{
sScriptMgr->OnSetServerSideVisibilityDetect(this, type, sec);
m_serverSideVisibilityDetect.SetValue(type, sec);
}
+11 -15
View File
@@ -11,6 +11,7 @@
#include "DBCStores.h" #include "DBCStores.h"
#include "GroupReference.h" #include "GroupReference.h"
#include "InstanceSaveMgr.h" #include "InstanceSaveMgr.h"
#include "ArenaTeam.h"
#include "Item.h" #include "Item.h"
#include "MapReference.h" #include "MapReference.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
@@ -705,19 +706,6 @@ enum InstanceResetWarningType
RAID_INSTANCE_EXPIRED = 5 RAID_INSTANCE_EXPIRED = 5
}; };
// PLAYER_FIELD_ARENA_TEAM_INFO_1_1 offsets
enum ArenaTeamInfoType
{
ARENA_TEAM_ID = 0,
ARENA_TEAM_TYPE = 1, // new in 3.2 - team type?
ARENA_TEAM_MEMBER = 2, // 0 - captain, 1 - member
ARENA_TEAM_GAMES_WEEK = 3,
ARENA_TEAM_GAMES_SEASON = 4,
ARENA_TEAM_WINS_SEASON = 5,
ARENA_TEAM_PERSONAL_RATING = 6,
ARENA_TEAM_END = 7
};
class InstanceSave; class InstanceSave;
enum RestFlag enum RestFlag
@@ -1466,7 +1454,7 @@ public:
void RemoveRewardedQuest(uint32 questId, bool update = true); void RemoveRewardedQuest(uint32 questId, bool update = true);
void SendQuestUpdate(uint32 questId); void SendQuestUpdate(uint32 questId);
QuestGiverStatus GetQuestDialogStatus(Object* questGiver); QuestGiverStatus GetQuestDialogStatus(Object* questGiver);
float GetQuestRate();
void SetDailyQuestStatus(uint32 quest_id); void SetDailyQuestStatus(uint32 quest_id);
bool IsDailyQuestDone(uint32 quest_id); bool IsDailyQuestDone(uint32 quest_id);
void SetWeeklyQuestStatus(uint32 quest_id); void SetWeeklyQuestStatus(uint32 quest_id);
@@ -1616,6 +1604,7 @@ public:
[[nodiscard]] RewardedQuestSet const& getRewardedQuests() const { return m_RewardedQuests; } [[nodiscard]] RewardedQuestSet const& getRewardedQuests() const { return m_RewardedQuests; }
QuestStatusMap& getQuestStatusMap() { return m_QuestStatus; } QuestStatusMap& getQuestStatusMap() { return m_QuestStatus; }
QuestStatusSaveMap& GetQuestStatusSaveMap() { return m_QuestStatusSave; }
[[nodiscard]] size_t GetRewardedQuestCount() const { return m_RewardedQuests.size(); } [[nodiscard]] size_t GetRewardedQuestCount() const { return m_RewardedQuests.size(); }
[[nodiscard]] bool IsQuestRewarded(uint32 quest_id) const [[nodiscard]] bool IsQuestRewarded(uint32 quest_id) const
@@ -1915,10 +1904,10 @@ public:
SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, type); SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, type);
} }
void SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value); void SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value);
uint32 GetArenaPersonalRating(uint8 slot) const;
static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot); static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot);
static void LeaveAllArenaTeams(uint64 guid); static void LeaveAllArenaTeams(uint64 guid);
[[nodiscard]] uint32 GetArenaTeamId(uint8 slot) const; [[nodiscard]] uint32 GetArenaTeamId(uint8 slot) const;
[[nodiscard]] uint32 GetArenaPersonalRating(uint8 slot) const;
void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; } void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; }
uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; } uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; }
@@ -2443,6 +2432,10 @@ public:
void SendCinematicStart(uint32 CinematicSequenceId); void SendCinematicStart(uint32 CinematicSequenceId);
void SendMovieStart(uint32 MovieId); void SendMovieStart(uint32 MovieId);
uint16 GetMaxSkillValueForLevel() const;
bool IsFFAPvP();
bool IsPvP();
/*********************************************************/ /*********************************************************/
/*** INSTANCE SYSTEM ***/ /*** INSTANCE SYSTEM ***/
/*********************************************************/ /*********************************************************/
@@ -2619,6 +2612,9 @@ public:
[[nodiscard]] uint32 GetNextSave() const { return m_nextSave; } [[nodiscard]] uint32 GetNextSave() const { return m_nextSave; }
[[nodiscard]] SpellModList const& GetSpellModList(uint32 type) const { return m_spellMods[type]; } [[nodiscard]] SpellModList const& GetSpellModList(uint32 type) const { return m_spellMods[type]; }
void SetServerSideVisibility(ServerSideVisibilityType type, AccountTypes sec);
void SetServerSideVisibilityDetect(ServerSideVisibilityType type, AccountTypes sec);
static std::unordered_map<int, bgZoneRef> bgZoneIdToFillWorldStates; // zoneId -> FillInitialWorldStates static std::unordered_map<int, bgZoneRef> bgZoneIdToFillWorldStates; // zoneId -> FillInitialWorldStates
// Cinematic camera data and remote sight functions // Cinematic camera data and remote sight functions
+27 -3
View File
@@ -4363,6 +4363,8 @@ void Unit::RemoveAura(AuraApplicationMap::iterator& i, AuraRemoveMode mode)
// Remove aura - for Area and Target auras // Remove aura - for Area and Target auras
if (aura->GetOwner() == this) if (aura->GetOwner() == this)
aura->Remove(mode); aura->Remove(mode);
sScriptMgr->OnAuraRemove(this, aurApp, mode);
} }
void Unit::RemoveAura(uint32 spellId, uint64 caster, uint8 reqEffMask, AuraRemoveMode removeMode) void Unit::RemoveAura(uint32 spellId, uint64 caster, uint8 reqEffMask, AuraRemoveMode removeMode)
@@ -9687,6 +9689,11 @@ ReputationRank Unit::GetReactionTo(Unit const* target) const
} }
} }
} }
ReputationRank repRank = REP_HATED;
if (!sScriptMgr->IfNormalReaction(this, target, repRank))
return ReputationRank(repRank);
// do checks dependant only on our faction // do checks dependant only on our faction
return GetFactionReactionTo(GetFactionTemplateEntry(), target); return GetFactionReactionTo(GetFactionTemplateEntry(), target);
} }
@@ -10782,6 +10789,9 @@ float Unit::SpellPctDamageModsDone(Unit* victim, SpellInfo const* spellProto, Da
if (!spellProto->ValidateAttribute6SpellDamageMods(this, *i, damagetype == DOT)) if (!spellProto->ValidateAttribute6SpellDamageMods(this, *i, damagetype == DOT))
continue; continue;
if (!sScriptMgr->IsNeedModSpellDamagePercent(this, *i, DoneTotalMod, spellProto))
continue;
if ((*i)->GetMiscValue() & spellProto->GetSchoolMask()) if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
{ {
if ((*i)->GetSpellInfo()->EquippedItemClass == -1) if ((*i)->GetSpellInfo()->EquippedItemClass == -1)
@@ -11784,8 +11794,13 @@ float Unit::SpellPctHealingModsDone(Unit* victim, SpellInfo const* spellProto, D
// Healing done percent // Healing done percent
AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT); AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
for (AuraEffectList::const_iterator i = mHealingDonePct.begin(); i != mHealingDonePct.end(); ++i) for (auto const& auraEff : mHealingDonePct)
AddPct(DoneTotalMod, (*i)->GetAmount()); {
if (!sScriptMgr->IsNeedModHealPercent(this, auraEff, DoneTotalMod, spellProto))
continue;
AddPct(DoneTotalMod, auraEff->GetAmount());
}
// done scripted mod (take it from owner) // done scripted mod (take it from owner)
Unit* owner = GetOwner() ? GetOwner() : this; Unit* owner = GetOwner() ? GetOwner() : this;
@@ -12400,6 +12415,9 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType
if (!spellProto->ValidateAttribute6SpellDamageMods(this, *i, false)) if (!spellProto->ValidateAttribute6SpellDamageMods(this, *i, false))
continue; continue;
if (!sScriptMgr->IsNeedModMeleeDamagePercent(this, *i, DoneTotalMod, spellProto))
continue;
if (((*i)->GetMiscValue() & spellProto->GetSchoolMask()) && !((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)) if (((*i)->GetMiscValue() & spellProto->GetSchoolMask()) && !((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
{ {
if ((*i)->GetSpellInfo()->EquippedItemClass == -1) if ((*i)->GetSpellInfo()->EquippedItemClass == -1)
@@ -18230,6 +18248,9 @@ void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
// pussywizard: goign to other phase (valithria, algalon) should not remove such auras // pussywizard: goign to other phase (valithria, algalon) should not remove such auras
//RemoveNotOwnSingleTargetAuras(newPhaseMask, true); // we can lost access to caster or target //RemoveNotOwnSingleTargetAuras(newPhaseMask, true); // we can lost access to caster or target
if (!sScriptMgr->CanSetPhaseMask(this, newPhaseMask, update))
return;
// modify hostile references for new phasemask, some special cases deal with hostile references themselves // modify hostile references for new phasemask, some special cases deal with hostile references themselves
if (GetTypeId() == TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout())) if (GetTypeId() == TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout()))
{ {
@@ -20077,7 +20098,10 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
fieldBuffer << (uint32)target->getFaction(); fieldBuffer << (uint32)target->getFaction();
} }
else else
fieldBuffer << m_uint32Values[index]; if (!sScriptMgr->IsCustomBuildValuesUpdate(this, updateType, fieldBuffer, target, index))
{
fieldBuffer << m_uint32Values[index];
}
} }
else else
// send in current format (float as float, uint32 as uint32) // send in current format (float as float, uint32 as uint32)
+8
View File
@@ -59,10 +59,13 @@ Group::Group() : m_leaderGuid(0), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL
{ {
for (uint8 i = 0; i < TARGETICONCOUNT; ++i) for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
m_targetIcons[i] = 0; m_targetIcons[i] = 0;
sScriptMgr->OnConstructGroup(this);
} }
Group::~Group() Group::~Group()
{ {
sScriptMgr->OnDestructGroup(this);
if (m_bgGroup) if (m_bgGroup)
{ {
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
@@ -142,6 +145,8 @@ bool Group::Create(Player* leader)
CharacterDatabase.Execute(stmt); CharacterDatabase.Execute(stmt);
ASSERT(AddMember(leader)); // If the leader can't be added to a new group because it appears full, something is clearly wrong. ASSERT(AddMember(leader)); // If the leader can't be added to a new group because it appears full, something is clearly wrong.
sScriptMgr->OnCreate(this, leader);
} }
else if (!AddMember(leader)) else if (!AddMember(leader))
return false; return false;
@@ -1840,6 +1845,9 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
if (!member) if (!member)
return ERR_BATTLEGROUND_JOIN_FAILED; return ERR_BATTLEGROUND_JOIN_FAILED;
if (!sScriptMgr->CanGroupJoinBattlegroundQueue(this, member, bgTemplate, MinPlayerCount, isRated, arenaSlot))
return ERR_BATTLEGROUND_JOIN_FAILED;
// don't allow cross-faction groups to join queue // don't allow cross-faction groups to join queue
if (member->GetTeamId() != teamId) if (member->GetTeamId() != teamId)
return ERR_BATTLEGROUND_JOIN_TIMED_OUT; return ERR_BATTLEGROUND_JOIN_TIMED_OUT;
+3
View File
@@ -2875,6 +2875,9 @@ void Guild::_BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char* par
void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= 0*/, bool sendAllSlots /*= false*/, SlotIds* slots /*= nullptr*/) const void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= 0*/, bool sendAllSlots /*= false*/, SlotIds* slots /*= nullptr*/) const
{ {
if (!sScriptMgr->CanGuildSendBankList(this, session, tabId, sendAllSlots))
return;
WorldPacket data(SMSG_GUILD_BANK_LIST, 500); WorldPacket data(SMSG_GUILD_BANK_LIST, 500);
data << uint64(m_bankMoney); data << uint64(m_bankMoney);
data << uint8(tabId); data << uint8(tabId);
+3
View File
@@ -756,6 +756,9 @@ public:
void ResetTimes(); void ResetTimes();
[[nodiscard]] bool ModifyBankMoney(SQLTransaction& trans, const uint64& amount, bool add) { return _ModifyBankMoney(trans, amount, add); }
[[nodiscard]] uint32 GetMemberSize() const { return m_members.size(); }
protected: protected:
uint32 m_id; uint32 m_id;
std::string m_name; std::string m_name;
@@ -12,6 +12,7 @@
#include "Log.h" #include "Log.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "Opcodes.h" #include "Opcodes.h"
#include "ScriptMgr.h"
#include "Player.h" #include "Player.h"
#include "UpdateMask.h" #include "UpdateMask.h"
#include "Util.h" #include "Util.h"
@@ -50,6 +51,9 @@ void WorldSession::SendAuctionHello(uint64 guid, Creature* unit)
return; return;
} }
if (!sScriptMgr->CanSendAuctionHello(this, guid, unit))
return;
AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction()); AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction());
if (!ahEntry) if (!ahEntry)
return; return;
@@ -388,6 +388,9 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket& recvData)
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenaType); BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenaType);
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
if (!sScriptMgr->CanBattleFieldPort(_player, arenaType, bgTypeId, action))
return;
// get group info from queue // get group info from queue
GroupQueueInfo ginfo; GroupQueueInfo ginfo;
if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo)) if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
@@ -658,6 +661,14 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
// queue result (default ok) // queue result (default ok)
GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult(bgt->GetBgTypeID()); GroupJoinBattlegroundResult err = GroupJoinBattlegroundResult(bgt->GetBgTypeID());
if (!sScriptMgr->CanJoinInArenaQueue(_player, guid, arenaslot, bgTypeId, asGroup, isRated, err) && err <= 0)
{
WorldPacket data;
sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
SendPacket(&data);
return;
}
// check if player can queue: // check if player can queue:
if (!asGroup) if (!asGroup)
{ {
@@ -14,6 +14,7 @@
#include "Opcodes.h" #include "Opcodes.h"
#include "Pet.h" #include "Pet.h"
#include "Player.h" #include "Player.h"
#include "ScriptMgr.h"
#include "SocialMgr.h" #include "SocialMgr.h"
#include "SpellAuras.h" #include "SpellAuras.h"
#include "Util.h" #include "Util.h"
@@ -74,6 +75,9 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
return; return;
} }
if (!sScriptMgr->CanGroupInvite(GetPlayer(), membername))
return;
if (GetPlayer()->IsSpectator() || player->IsSpectator()) if (GetPlayer()->IsSpectator() || player->IsSpectator())
{ {
SendPartyResult(PARTY_OP_INVITE, membername, ERR_INVITE_RESTRICTED); SendPartyResult(PARTY_OP_INVITE, membername, ERR_INVITE_RESTRICTED);
@@ -224,6 +228,9 @@ void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recvData)
return; return;
} }
if (!sScriptMgr->CanGroupAccept(GetPlayer(), group))
return;
if (group->GetLeaderGUID() == GetPlayer()->GetGUID()) if (group->GetLeaderGUID() == GetPlayer()->GetGUID())
{ {
sLog->outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); sLog->outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
+4
View File
@@ -11,6 +11,7 @@
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "Opcodes.h" #include "Opcodes.h"
#include "Player.h" #include "Player.h"
#include "ScriptMgr.h"
#include "SpellInfo.h" #include "SpellInfo.h"
#include "UpdateData.h" #include "UpdateData.h"
#include "WorldPacket.h" #include "WorldPacket.h"
@@ -660,6 +661,9 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData)
Item* pItem = _player->GetItemByGuid(itemguid); Item* pItem = _player->GetItemByGuid(itemguid);
if (pItem) if (pItem)
{ {
if (!sScriptMgr->CanSellItem(_player, pItem, creature))
return;
// prevent sell not owner item // prevent sell not owner item
if (_player->GetGUID() != pItem->GetOwnerGUID()) if (_player->GetGUID() != pItem->GetOwnerGUID())
{ {
+5 -3
View File
@@ -14,6 +14,7 @@
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "Opcodes.h" #include "Opcodes.h"
#include "Player.h" #include "Player.h"
#include "ScriptMgr.h"
#include "World.h" #include "World.h"
#include "WorldPacket.h" #include "WorldPacket.h"
#include "WorldSession.h" #include "WorldSession.h"
@@ -196,9 +197,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
} }
}*/ }*/
uint32 rc_account = receive uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(rc);
? receive->GetSession()->GetAccountId()
: sObjectMgr->GetPlayerAccountIdByGUID(rc);
if (/*!accountBound*/ GetAccountId() != rc_account && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeamId() != rc_teamId && AccountMgr::IsPlayerAccount(GetSecurity())) if (/*!accountBound*/ GetAccountId() != rc_account && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeamId() != rc_teamId && AccountMgr::IsPlayerAccount(GetSecurity()))
{ {
@@ -255,6 +254,9 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
return; return;
} }
if (!sScriptMgr->CanSendMail(player, rc, mailbox, subject, body, money, COD, item))
return;
items[i] = item; items[i] = item;
} }
+2
View File
@@ -1019,6 +1019,8 @@ void WorldSession::HandleRepairItemOpcode(WorldPacket& recvData)
// reputation discount // reputation discount
float discountMod = _player->GetReputationPriceDiscount(unit); float discountMod = _player->GetReputationPriceDiscount(unit);
sScriptMgr->OnBeforePlayerDurabilityRepair(_player, npcGUID, itemGUID, discountMod, guildBank);
if (itemGUID) if (itemGUID)
{ {
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
+43 -24
View File
@@ -15,22 +15,12 @@
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "Opcodes.h" #include "Opcodes.h"
#include "PetitionMgr.h" #include "PetitionMgr.h"
#include "ScriptMgr.h"
#include "SocialMgr.h" #include "SocialMgr.h"
#include "World.h" #include "World.h"
#include "WorldPacket.h" #include "WorldPacket.h"
#include "WorldSession.h" #include "WorldSession.h"
#define CHARTER_DISPLAY_ID 16161
// Charters ID in item_template
enum CharterItemIDs
{
GUILD_CHARTER = 5863,
ARENA_TEAM_CHARTER_2v2 = 23560,
ARENA_TEAM_CHARTER_3v3 = 23561,
ARENA_TEAM_CHARTER_5v5 = 23562
};
void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
{ {
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
@@ -136,6 +126,8 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
} }
} }
sScriptMgr->PetitionBuy(_player, creature, charterid, cost, type);
if (type == GUILD_CHARTER_TYPE) if (type == GUILD_CHARTER_TYPE)
{ {
if (sGuildMgr->GetGuildByName(name)) if (sGuildMgr->GetGuildByName(name))
@@ -880,38 +872,65 @@ void WorldSession::SendPetitionShowList(uint64 guid)
WorldPacket data(SMSG_PETITION_SHOWLIST, 8 + 1 + 4 * 6); WorldPacket data(SMSG_PETITION_SHOWLIST, 8 + 1 + 4 * 6);
data << guid; // npc guid data << guid; // npc guid
// For guild default
uint32 CharterEntry = GUILD_CHARTER;
uint32 CharterDispayID = CHARTER_DISPLAY_ID;
uint32 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
if (creature->IsTabardDesigner()) if (creature->IsTabardDesigner())
{ {
sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
data << uint8(1); // count data << uint8(1); // count
data << uint32(1); // index data << uint32(1); // index
data << uint32(GUILD_CHARTER); // charter entry data << CharterEntry; // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id data << CharterDispayID; // charter display id
data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD)); // charter cost data << CharterCost; // charter cost
data << uint32(0); // unknown data << uint32(0); // unknown
data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs
} }
else else
{ {
data << uint8(3); // count // For 2v2 default
CharterEntry = ARENA_TEAM_CHARTER_2v2;
CharterDispayID = CHARTER_DISPLAY_ID;
CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
// 2v2 // 2v2
data << uint8(3); // count
sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
data << uint32(1); // index data << uint32(1); // index
data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry data << CharterEntry; // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id data << CharterDispayID; // charter display id
data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2)); // charter cost data << CharterCost; // charter cost
data << uint32(2); // unknown data << uint32(2); // unknown
data << uint32(2); // required signs? data << uint32(2); // required signs?
// For 3v3 default
CharterEntry = ARENA_TEAM_CHARTER_3v3;
CharterDispayID = CHARTER_DISPLAY_ID;
CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
// 3v3 // 3v3
sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
data << uint32(2); // index data << uint32(2); // index
data << uint32(ARENA_TEAM_CHARTER_3v3); // charter entry data << CharterEntry; // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id data << CharterDispayID; // charter display id
data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3)); // charter cost data << CharterCost; // charter cost
data << uint32(3); // unknown data << uint32(3); // unknown
data << uint32(3); // required signs? data << uint32(3); // required signs?
// For 3v3 default
CharterEntry = ARENA_TEAM_CHARTER_5v5;
CharterDispayID = CHARTER_DISPLAY_ID;
CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
// 5v5 // 5v5
sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
data << uint32(3); // index data << uint32(3); // index
data << uint32(ARENA_TEAM_CHARTER_5v5); // charter entry data << CharterEntry; // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id data << CharterDispayID; // charter display id
data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5)); // charter cost data << CharterCost; // charter cost
data << uint32(5); // unknown data << uint32(5); // unknown
data << uint32(5); // required signs? data << uint32(5); // required signs?
} }
+11
View File
@@ -15,6 +15,7 @@
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "Spell.h" #include "Spell.h"
#include "SpellAuraEffects.h" #include "SpellAuraEffects.h"
#include "ScriptMgr.h"
#include "SpellAuras.h" #include "SpellAuras.h"
#include "SpellMgr.h" #include "SpellMgr.h"
#include "TemporarySummon.h" #include "TemporarySummon.h"
@@ -343,6 +344,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
uint8 castCount, castFlags; uint8 castCount, castFlags;
recvPacket >> castCount >> spellId >> castFlags; recvPacket >> castCount >> spellId >> castFlags;
uint32 oldSpellId = spellId;
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: got cast spell packet, castCount: %u, spellId: %u, castFlags: %u, data length = %u", castCount, spellId, castFlags, (uint32)recvPacket.size()); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: got cast spell packet, castCount: %u, spellId: %u, castFlags: %u, data length = %u", castCount, spellId, castFlags, (uint32)recvPacket.size());
#endif #endif
@@ -404,6 +407,11 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
} }
} }
sScriptMgr->ValidateSpellAtCastSpell(_player, oldSpellId, spellId, castCount, castFlags);
if (oldSpellId != spellId)
spellInfo = sSpellMgr->GetSpellInfo(spellId);
// Client is resending autoshot cast opcode when other spell is casted during shoot rotation // Client is resending autoshot cast opcode when other spell is casted during shoot rotation
// Skip it to prevent "interrupt" message // Skip it to prevent "interrupt" message
if (spellInfo->IsAutoRepeatRangedSpell() && _player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL) if (spellInfo->IsAutoRepeatRangedSpell() && _player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)
@@ -443,6 +451,9 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
} }
Spell* spell = new Spell(mover, spellInfo, TRIGGERED_NONE, 0, false); Spell* spell = new Spell(mover, spellInfo, TRIGGERED_NONE, 0, false);
sScriptMgr->ValidateSpellAtCastSpellResult(_player, mover, spell, oldSpellId, spellId);
spell->m_cast_count = castCount; // set count of casts spell->m_cast_count = castCount; // set count of casts
spell->prepare(&targets); spell->prepare(&targets);
} }
@@ -12,6 +12,7 @@
#include "ObjectAccessor.h" #include "ObjectAccessor.h"
#include "Opcodes.h" #include "Opcodes.h"
#include "Player.h" #include "Player.h"
#include "ScriptMgr.h"
#include "SocialMgr.h" #include "SocialMgr.h"
#include "Spell.h" #include "Spell.h"
#include "World.h" #include "World.h"
@@ -640,6 +641,9 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
return; return;
} }
if (!sScriptMgr->CanInitTrade(_player, pOther))
return;
// OK start trade // OK start trade
_player->m_trade = new TradeData(_player, pOther); _player->m_trade = new TradeData(_player, pOther);
pOther->m_trade = new TradeData(pOther, _player); pOther->m_trade = new TradeData(pOther, _player);
@@ -134,11 +134,14 @@ bool InstanceSaveManager::DeleteInstanceSaveIfNeeded(InstanceSave* save, bool sk
InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, time_t extendedResetTime) InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, time_t extendedResetTime)
: m_resetTime(resetTime), m_extendedResetTime(extendedResetTime), m_instanceid(InstanceId), m_mapid(MapId), m_difficulty(IsSharedDifficultyMap(MapId) ? Difficulty(difficulty % 2) : difficulty), m_canReset(true), m_instanceData(""), m_completedEncounterMask(0) : m_resetTime(resetTime), m_extendedResetTime(extendedResetTime), m_instanceid(InstanceId), m_mapid(MapId), m_difficulty(IsSharedDifficultyMap(MapId) ? Difficulty(difficulty % 2) : difficulty), m_canReset(true), m_instanceData(""), m_completedEncounterMask(0)
{ {
sScriptMgr->OnConstructInstanceSave(this);
} }
InstanceSave::~InstanceSave() InstanceSave::~InstanceSave()
{ {
ASSERT(m_playerList.empty()); ASSERT(m_playerList.empty());
sScriptMgr->OnDestructInstanceSave(this);
} }
void InstanceSave::InsertToDB() void InstanceSave::InsertToDB()
@@ -169,6 +172,8 @@ void InstanceSave::InsertToDB()
stmt->setUInt32(4, completedEncounters); stmt->setUInt32(4, completedEncounters);
stmt->setString(5, data); stmt->setString(5, data);
CharacterDatabase.Execute(stmt); CharacterDatabase.Execute(stmt);
sScriptMgr->OnInstanceSave(this);
} }
time_t InstanceSave::GetResetTimeForDB() time_t InstanceSave::GetResetTimeForDB()
+2
View File
@@ -503,6 +503,8 @@ bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bo
tab->Process(*this, store, lootMode, lootOwner); // Processing is done there, callback via Loot::AddItem() tab->Process(*this, store, lootMode, lootOwner); // Processing is done there, callback via Loot::AddItem()
sScriptMgr->OnAfterLootTemplateProcess(this, tab, store, lootOwner, personal, noEmptyError, lootMode);
// Setting access rights for group loot case // Setting access rights for group loot case
Group* group = lootOwner->GetGroup(); Group* group = lootOwner->GetGroup();
if (!personal && group) if (!personal && group)
+4
View File
@@ -22,6 +22,7 @@
#include "ObjectAccessor.h" #include "ObjectAccessor.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "Opcodes.h" #include "Opcodes.h"
#include "ScriptMgr.h"
#include "Player.h" #include "Player.h"
#include "Transport.h" #include "Transport.h"
#include "World.h" #include "World.h"
@@ -153,6 +154,9 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck)
char const* mapName = entry->name[player->GetSession()->GetSessionDbcLocale()]; char const* mapName = entry->name[player->GetSession()->GetSessionDbcLocale()];
if (!sScriptMgr->CanEnterMap(player, entry, instance, mapDiff, loginCheck))
return false;
Group* group = player->GetGroup(); Group* group = player->GetGroup();
if (entry->IsRaid()) if (entry->IsRaid())
{ {
+11
View File
@@ -8,6 +8,17 @@ Xinef
#include "Common.h" #include "Common.h"
#include <map> #include <map>
#define CHARTER_DISPLAY_ID 16161
// Charters ID in item_template
enum CharterItemIDs
{
GUILD_CHARTER = 5863,
ARENA_TEAM_CHARTER_2v2 = 23560,
ARENA_TEAM_CHARTER_3v3 = 23561,
ARENA_TEAM_CHARTER_5v5 = 23562
};
typedef std::map<uint32, uint32> SignatureMap; typedef std::map<uint32, uint32> SignatureMap;
struct Petition struct Petition
+898 -14
View File
@@ -64,6 +64,11 @@ template class ScriptRegistry<SpellSC>;
template class ScriptRegistry<AccountScript>; template class ScriptRegistry<AccountScript>;
template class ScriptRegistry<GameEventScript>; template class ScriptRegistry<GameEventScript>;
template class ScriptRegistry<MailScript>; template class ScriptRegistry<MailScript>;
template class ScriptRegistry<AchievementScript>;
template class ScriptRegistry<MiscScript>;
template class ScriptRegistry<PetScript>;
template class ScriptRegistry<ArenaScript>;
template class ScriptRegistry<CommandSC>;
#include "ScriptMgrMacros.h" #include "ScriptMgrMacros.h"
@@ -124,10 +129,15 @@ void ScriptMgr::Unload()
SCR_CLEAR(GlobalScript); SCR_CLEAR(GlobalScript);
SCR_CLEAR(ModuleScript); SCR_CLEAR(ModuleScript);
SCR_CLEAR(BGScript); SCR_CLEAR(BGScript);
SCR_CLEAR(AchievementScript);
SCR_CLEAR(ArenaTeamScript); SCR_CLEAR(ArenaTeamScript);
SCR_CLEAR(SpellSC); SCR_CLEAR(SpellSC);
SCR_CLEAR(GameEventScript); SCR_CLEAR(GameEventScript);
SCR_CLEAR(MailScript); SCR_CLEAR(MailScript);
SCR_CLEAR(MiscScript);
SCR_CLEAR(PetScript);
SCR_CLEAR(ArenaScript);
SCR_CLEAR(CommandSC);
#undef SCR_CLEAR #undef SCR_CLEAR
} }
@@ -198,8 +208,13 @@ void ScriptMgr::CheckIfScriptsInDatabaseExist()
!ScriptRegistry<PlayerScript>::GetScriptById(sid) && !ScriptRegistry<PlayerScript>::GetScriptById(sid) &&
!ScriptRegistry<GuildScript>::GetScriptById(sid) && !ScriptRegistry<GuildScript>::GetScriptById(sid) &&
!ScriptRegistry<BGScript>::GetScriptById(sid) && !ScriptRegistry<BGScript>::GetScriptById(sid) &&
!ScriptRegistry<AchievementScript>::GetScriptById(sid) &&
!ScriptRegistry<ArenaTeamScript>::GetScriptById(sid) && !ScriptRegistry<ArenaTeamScript>::GetScriptById(sid) &&
!ScriptRegistry<SpellSC>::GetScriptById(sid) && !ScriptRegistry<SpellSC>::GetScriptById(sid) &&
!ScriptRegistry<MiscScript>::GetScriptById(sid) &&
!ScriptRegistry<PetScript>::GetScriptById(sid) &&
!ScriptRegistry<CommandSC>::GetScriptById(sid) &&
!ScriptRegistry<ArenaScript>::GetScriptById(sid) &&
!ScriptRegistry<GroupScript>::GetScriptById(sid)) !ScriptRegistry<GroupScript>::GetScriptById(sid))
sLog->outErrorDb("Script named '%s' is assigned in the database, but has no code!", (*itr).c_str()); sLog->outErrorDb("Script named '%s' is assigned in the database, but has no code!", (*itr).c_str());
} }
@@ -347,6 +362,11 @@ void ScriptMgr::CreateSpellScriptLoaders(uint32 spellId, std::vector<std::pair<S
} }
} }
void ScriptMgr::OnBeforePlayerDurabilityRepair(Player* player, uint64 npcGUID, uint64 itemGUID, float& discountMod, uint8 guildBank)
{
FOREACH_SCRIPT(PlayerScript)->OnBeforeDurabilityRepair(player, npcGUID, itemGUID, discountMod, guildBank);
}
void ScriptMgr::OnNetworkStart() void ScriptMgr::OnNetworkStart()
{ {
FOREACH_SCRIPT(ServerScript)->OnNetworkStart(); FOREACH_SCRIPT(ServerScript)->OnNetworkStart();
@@ -1961,9 +1981,9 @@ void ScriptMgr::OnItemRoll(Player const* player, LootStoreItem const* LootStoreI
FOREACH_SCRIPT(GlobalScript)->OnItemRoll(player, LootStoreItem, chance, loot, store); FOREACH_SCRIPT(GlobalScript)->OnItemRoll(player, LootStoreItem, chance, loot, store);
} }
void ScriptMgr::OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData) void ScriptMgr::OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData, lfg::LFGDungeonData const* dungeon)
{ {
FOREACH_SCRIPT(GlobalScript)->OnInitializeLockedDungeons(player, level, lockData); FOREACH_SCRIPT(GlobalScript)->OnInitializeLockedDungeons(player, level, lockData, dungeon);
} }
void ScriptMgr::OnAfterInitializeLockedDungeons(Player* player) void ScriptMgr::OnAfterInitializeLockedDungeons(Player* player)
@@ -2037,7 +2057,7 @@ void ScriptMgr::OnBeforeBuyItemFromVendor(Player* player, uint64 vendorguid, uin
FOREACH_SCRIPT(PlayerScript)->OnBeforeBuyItemFromVendor(player, vendorguid, vendorslot, item, count, bag, slot); FOREACH_SCRIPT(PlayerScript)->OnBeforeBuyItemFromVendor(player, vendorguid, vendorslot, item, count, bag, slot);
} }
void ScriptMgr::OnAfterStoreOrEquipNewItem(Player* player, uint32 vendorslot, uint32& item, uint8 count, uint8 bag, uint8 slot, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore) void ScriptMgr::OnAfterStoreOrEquipNewItem(Player* player, uint32 vendorslot, Item* item, uint8 count, uint8 bag, uint8 slot, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore)
{ {
FOREACH_SCRIPT(PlayerScript)->OnAfterStoreOrEquipNewItem(player, vendorslot, item, count, bag, slot, pProto, pVendor, crItem, bStore); FOREACH_SCRIPT(PlayerScript)->OnAfterStoreOrEquipNewItem(player, vendorslot, item, count, bag, slot, pProto, pVendor, crItem, bStore);
} }
@@ -2136,17 +2156,6 @@ void ScriptMgr::OnCheckNormalMatch(BattlegroundQueue* queue, uint32& Coef, Battl
FOREACH_SCRIPT(BGScript)->OnCheckNormalMatch(queue, Coef, bgTemplate, bracket_id, minPlayers, maxPlayers); FOREACH_SCRIPT(BGScript)->OnCheckNormalMatch(queue, Coef, bgTemplate, bracket_id, minPlayers, maxPlayers);
} }
bool ScriptMgr::CanSendMessageQueue(BattlegroundQueue* queue, Player* leader, Battleground* bg, PvPDifficultyEntry const* bracketEntry)
{
bool ret = true;
FOR_SCRIPTS_RET(BGScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanSendMessageQueue(queue, leader, bg, bracketEntry))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnGetSlotByType(const uint32 type, uint8& slot) void ScriptMgr::OnGetSlotByType(const uint32 type, uint8& slot)
{ {
FOREACH_SCRIPT(ArenaTeamScript)->OnGetSlotByType(type, slot); FOREACH_SCRIPT(ArenaTeamScript)->OnGetSlotByType(type, slot);
@@ -2200,6 +2209,851 @@ void ScriptMgr::OnBeforeMailDraftSendMailTo(MailDraft* mailDraft, MailReceiver c
FOREACH_SCRIPT(MailScript)->OnBeforeMailDraftSendMailTo(mailDraft, receiver, sender, checked, deliver_delay, custom_expiration, deleteMailItemsFromDB, sendMail); FOREACH_SCRIPT(MailScript)->OnBeforeMailDraftSendMailTo(mailDraft, receiver, sender, checked, deliver_delay, custom_expiration, deleteMailItemsFromDB, sendMail);
} }
void ScriptMgr::OnBeforeUpdatingPersonalRating(int32& mod, uint32 type)
{
FOREACH_SCRIPT(FormulaScript)->OnBeforeUpdatingPersonalRating(mod, type);
}
bool ScriptMgr::OnBeforePlayerQuestComplete(Player* player, uint32 quest_id)
{
bool ret=true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->OnBeforeQuestComplete(player, quest_id))
ret=false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnBeforeStoreOrEquipNewItem(Player* player, uint32 vendorslot, uint32& item, uint8 count, uint8 bag, uint8 slot, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore)
{
FOREACH_SCRIPT(PlayerScript)->OnBeforeStoreOrEquipNewItem(player, vendorslot, item, count, bag, slot, pProto, pVendor, crItem, bStore);
}
bool ScriptMgr::CanJoinInArenaQueue(Player* player, uint64 BattlemasterGuid, uint8 arenaslot, BattlegroundTypeId BGTypeID, uint8 joinAsGroup, uint8 IsRated, GroupJoinBattlegroundResult& err)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanJoinInArenaQueue(player, BattlemasterGuid, arenaslot, BGTypeID, joinAsGroup, IsRated, err))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanBattleFieldPort(Player* player, uint8 arenaType, BattlegroundTypeId BGTypeID, uint8 action)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanBattleFieldPort(player, arenaType, BGTypeID, action))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanGroupInvite(Player* player, std::string& membername)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanGroupInvite(player, membername))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanGroupAccept(Player* player, Group* group)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanGroupAccept(player, group))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanSellItem(Player* player, Item* item, Creature* creature)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanSellItem(player, item, creature))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanSendMail(Player* player, uint64 receiverGuid, uint64 mailbox, std::string& subject, std::string& body, uint32 money, uint32 COD, Item* item)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanSendMail(player, receiverGuid, mailbox, subject, body, money, COD, item))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::PetitionBuy(Player* player, Creature* creature, uint32& charterid, uint32& cost, uint32& type)
{
FOREACH_SCRIPT(PlayerScript)->PetitionBuy(player, creature, charterid, cost, type);
}
void ScriptMgr::PetitionShowList(Player* player, Creature* creature, uint32& CharterEntry, uint32& CharterDispayID, uint32& CharterCost)
{
FOREACH_SCRIPT(PlayerScript)->PetitionShowList(player, creature, CharterEntry, CharterDispayID, CharterCost);
}
void ScriptMgr::OnRewardKillRewarder(Player* player, bool isDungeon, float& rate)
{
FOREACH_SCRIPT(PlayerScript)->OnRewardKillRewarder(player, isDungeon, rate);
}
bool ScriptMgr::CanGiveMailRewardAtGiveLevel(Player* player, uint8 level)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanGiveMailRewardAtGiveLevel(player, level))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnDeleteFromDB(SQLTransaction& trans, uint32 guid)
{
FOREACH_SCRIPT(PlayerScript)->OnDeleteFromDB(trans, guid);
}
bool ScriptMgr::CanRepopAtGraveyard(Player* player)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanRepopAtGraveyard(player))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnGetMaxSkillValue(Player* player, uint32 skill, int32& result, bool IsPure)
{
FOREACH_SCRIPT(PlayerScript)->OnGetMaxSkillValue(player, skill, result, IsPure);
}
bool ScriptMgr::CanAreaExploreAndOutdoor(Player* player)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanAreaExploreAndOutdoor(player))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnVictimRewardBefore(Player* player, Player* victim, uint32& killer_title, uint32& victim_title)
{
FOREACH_SCRIPT(PlayerScript)->OnVictimRewardBefore(player, victim, killer_title, victim_title);
}
void ScriptMgr::OnVictimRewardAfter(Player* player, Player* victim, uint32& killer_title, uint32& victim_rank, float& honor_f)
{
FOREACH_SCRIPT(PlayerScript)->OnVictimRewardAfter(player, victim, killer_title, victim_rank, honor_f);
}
void ScriptMgr::OnCustomScalingStatValueBefore(Player* player, ItemTemplate const* proto, uint8 slot, bool apply, uint32& CustomScalingStatValue)
{
FOREACH_SCRIPT(PlayerScript)->OnCustomScalingStatValueBefore(player, proto, slot, apply, CustomScalingStatValue);
}
void ScriptMgr::OnCustomScalingStatValue(Player* player, ItemTemplate const* proto, uint32& statType, int32& val, uint8 itemProtoStatNumber, uint32 ScalingStatValue, ScalingStatValuesEntry const* ssv)
{
FOREACH_SCRIPT(PlayerScript)->OnCustomScalingStatValue(player, proto, statType, val, itemProtoStatNumber, ScalingStatValue, ssv);
}
bool ScriptMgr::CanArmorDamageModifier(Player* player)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanArmorDamageModifier(player))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnGetFeralApBonus(Player* player, int32& feral_bonus, int32 dpsMod, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv)
{
FOREACH_SCRIPT(PlayerScript)->OnGetFeralApBonus(player, feral_bonus, dpsMod, proto, ssv);
}
bool ScriptMgr::CanApplyWeaponDependentAuraDamageMod(Player* player, Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanApplyWeaponDependentAuraDamageMod(player, item, attackType, aura, apply))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanApplyEquipSpell(Player* player, SpellInfo const* spellInfo, Item* item, bool apply, bool form_change)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanApplyEquipSpell(player, spellInfo, item, apply, form_change))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanApplyEquipSpellsItemSet(Player* player, ItemSetEffect* eff)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanApplyEquipSpellsItemSet(player, eff))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanCastItemCombatSpell(Player* player, Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanCastItemCombatSpell(player, target, attType, procVictim, procEx, item, proto))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanCastItemUseSpell(Player* player, Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanCastItemUseSpell(player, item, targets, cast_count, glyphIndex))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnApplyAmmoBonuses(Player* player, ItemTemplate const* proto, float& currentAmmoDPS)
{
FOREACH_SCRIPT(PlayerScript)->OnApplyAmmoBonuses(player, proto, currentAmmoDPS);
}
bool ScriptMgr::CanEquipItem(Player* player, uint8 slot, uint16& dest, Item* pItem, bool swap, bool not_loading)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanEquipItem(player, slot, dest, pItem, swap, not_loading))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanUnequipItem(Player* player, uint16 pos, bool swap)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanUnequipItem(player, pos, swap))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanUseItem(Player* player, ItemTemplate const* proto, InventoryResult& result)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanUseItem(player, proto, result))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanSaveEquipNewItem(Player* player, Item* item, uint16 pos, bool update)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanSaveEquipNewItem(player, item, pos, update))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanApplyEnchantment(Player* player, Item* item, EnchantmentSlot slot, bool apply, bool apply_dur, bool ignore_condition)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanApplyEnchantment(player, item, slot, apply, apply_dur, ignore_condition))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnGetQuestRate(Player* player, float& result)
{
FOREACH_SCRIPT(PlayerScript)->OnGetQuestRate(player, result);
}
bool ScriptMgr::PassedQuestKilledMonsterCredit(Player* player, Quest const* qinfo, uint32 entry, uint32 real_entry, uint64 guid)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->PassedQuestKilledMonsterCredit(player, qinfo, entry, real_entry, guid))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CheckItemInSlotAtLoadInventory(Player* player, Item* item, uint8 slot, uint8& err, uint16& dest)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CheckItemInSlotAtLoadInventory(player, item, slot, err, dest))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::NotAvoidSatisfy(Player* player, DungeonProgressionRequirements const* ar, uint32 target_map, bool report)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->NotAvoidSatisfy(player, ar, target_map, report))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::NotVisibleGloballyFor(Player* player, Player const* u)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->NotVisibleGloballyFor(player, u))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnGetArenaPersonalRating(Player* player, uint8 slot, uint32& result)
{
FOREACH_SCRIPT(PlayerScript)->OnGetArenaPersonalRating(player, slot, result);
}
void ScriptMgr::OnGetArenaTeamId(Player* player, uint8 slot, uint32& result)
{
FOREACH_SCRIPT(PlayerScript)->OnGetArenaTeamId(player, slot, result);
}
void ScriptMgr::OnIsFFAPvP(Player* player, bool& result)
{
FOREACH_SCRIPT(PlayerScript)->OnIsFFAPvP(player, result);
}
void ScriptMgr::OnIsPvP(Player* player, bool& result)
{
FOREACH_SCRIPT(PlayerScript)->OnIsPvP(player, result);
}
void ScriptMgr::OnGetMaxSkillValueForLevel(Player* player, uint16& result)
{
FOREACH_SCRIPT(PlayerScript)->OnGetMaxSkillValueForLevel(player, result);
}
bool ScriptMgr::NotSetArenaTeamInfoField(Player* player, uint8 slot, ArenaTeamInfoType type, uint32 value)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->NotSetArenaTeamInfoField(player, slot, type, value))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanJoinLfg(Player* player, uint8 roles, lfg::LfgDungeonSet& dungeons, const std::string& comment)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanJoinLfg(player, roles, dungeons, comment))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanEnterMap(Player* player, MapEntry const* entry, InstanceTemplate const* instance, MapDifficulty const* mapDiff, bool loginCheck)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanEnterMap(player, entry, instance, mapDiff, loginCheck))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanInitTrade(Player* player, Player* target)
{
bool ret = true;
FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanInitTrade(player, target))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnSetServerSideVisibility(Player* player, ServerSideVisibilityType& type, AccountTypes& sec)
{
FOREACH_SCRIPT(PlayerScript)->OnSetServerSideVisibility(player, type, sec);
}
void ScriptMgr::OnSetServerSideVisibilityDetect(Player* player, ServerSideVisibilityType& type, AccountTypes& sec)
{
FOREACH_SCRIPT(PlayerScript)->OnSetServerSideVisibilityDetect(player, type, sec);
}
bool ScriptMgr::CanGuildSendBankList(Guild const* guild, WorldSession* session, uint8 tabId, bool sendAllSlots)
{
bool ret = true;
FOR_SCRIPTS_RET(GuildScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanGuildSendBankList(guild, session, tabId, sendAllSlots))
ret = false; // we change ret value only when scripts return true
return ret;
}
bool ScriptMgr::CanGroupJoinBattlegroundQueue(Group const* group, Player* member, Battleground const* bgTemplate, uint32 MinPlayerCount, bool isRated, uint32 arenaSlot)
{
bool ret = true;
FOR_SCRIPTS_RET(GroupScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanGroupJoinBattlegroundQueue(group, member, bgTemplate, MinPlayerCount, isRated, arenaSlot))
ret = false; // we change ret value only when scripts return true
return ret;
}
void ScriptMgr::OnCreate(Group* group, Player* leader)
{
FOREACH_SCRIPT(GroupScript)->OnCreate(group, leader);
}
void ScriptMgr::OnAuraRemove(Unit* unit, AuraApplication* aurApp, AuraRemoveMode mode)
{
FOREACH_SCRIPT(UnitScript)->OnAuraRemove(unit, aurApp, mode);
}
bool ScriptMgr::IfNormalReaction(Unit const* unit, Unit const* target, ReputationRank& repRank)
{
bool ret = true;
FOR_SCRIPTS_RET(UnitScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->IfNormalReaction(unit, target, repRank))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::IsNeedModSpellDamagePercent(Unit const* unit, AuraEffect* auraEff, float& doneTotalMod, SpellInfo const* spellProto)
{
bool ret = true;
FOR_SCRIPTS_RET(UnitScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->IsNeedModSpellDamagePercent(unit, auraEff, doneTotalMod, spellProto))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::IsNeedModMeleeDamagePercent(Unit const* unit, AuraEffect* auraEff, float& doneTotalMod, SpellInfo const* spellProto)
{
bool ret = true;
FOR_SCRIPTS_RET(UnitScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->IsNeedModMeleeDamagePercent(unit, auraEff, doneTotalMod, spellProto))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::IsNeedModHealPercent(Unit const* unit, AuraEffect* auraEff, float& doneTotalMod, SpellInfo const* spellProto)
{
bool ret = true;
FOR_SCRIPTS_RET(UnitScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->IsNeedModHealPercent(unit, auraEff, doneTotalMod, spellProto))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanSetPhaseMask(Unit const* unit, uint32 newPhaseMask, bool update)
{
bool ret = true;
FOR_SCRIPTS_RET(UnitScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanSetPhaseMask(unit, newPhaseMask, update))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::IsCustomBuildValuesUpdate(Unit const* unit, uint8 updateType, ByteBuffer& fieldBuffer, Player const* target, uint16 index)
{
bool ret = false;
FOR_SCRIPTS_RET(UnitScript, itr, end, ret) // return true by default if not scripts
if (itr->second->IsCustomBuildValuesUpdate(unit, updateType, fieldBuffer, target, index))
ret = true; // we change ret value only when scripts return true
return ret;
}
void ScriptMgr::OnQueueUpdate(BattlegroundQueue* queue, BattlegroundBracketId bracket_id, bool isRated, uint32 arenaRatedTeamId)
{
FOREACH_SCRIPT(BGScript)->OnQueueUpdate(queue, bracket_id, isRated, arenaRatedTeamId);
}
bool ScriptMgr::CanSendMessageBGQueue(BattlegroundQueue* queue, Player* leader, Battleground* bg, PvPDifficultyEntry const* bracketEntry)
{
bool ret = true;
FOR_SCRIPTS_RET(BGScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanSendMessageBGQueue(queue, leader, bg, bracketEntry))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanSendMessageArenaQueue(BattlegroundQueue* queue, GroupQueueInfo* ginfo, bool IsJoin)
{
bool ret = true;
FOR_SCRIPTS_RET(BGScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanSendMessageArenaQueue(queue, ginfo, IsJoin))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanModAuraEffectDamageDone(AuraEffect const* auraEff, Unit* target, AuraApplication const* aurApp, uint8 mode, bool apply)
{
bool ret = true;
FOR_SCRIPTS_RET(SpellSC, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanModAuraEffectDamageDone(auraEff, target, aurApp, mode, apply))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanModAuraEffectModDamagePercentDone(AuraEffect const* auraEff, Unit* target, AuraApplication const* aurApp, uint8 mode, bool apply)
{
bool ret = true;
FOR_SCRIPTS_RET(SpellSC, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanModAuraEffectModDamagePercentDone(auraEff, target, aurApp, mode, apply))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnSpellCheckCast(Spell* spell, bool strict, SpellCastResult& res)
{
FOREACH_SCRIPT(SpellSC)->OnSpellCheckCast(spell, strict, res);
}
bool ScriptMgr::CanPrepare(Spell* spell, SpellCastTargets const* targets, AuraEffect const* triggeredByAura)
{
bool ret = true;
FOR_SCRIPTS_RET(SpellSC, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanPrepare(spell, targets, triggeredByAura))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanScalingEverything(Spell* spell)
{
bool ret = false;
FOR_SCRIPTS_RET(SpellSC, itr, end, ret) // return true by default if not scripts
if (itr->second->CanScalingEverything(spell))
ret = true; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanSelectSpecTalent(Spell* spell)
{
bool ret = true;
FOR_SCRIPTS_RET(SpellSC, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanSelectSpecTalent(spell))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnScaleAuraUnitAdd(Spell* spell, Unit* target, uint32 effectMask, bool checkIfValid, bool implicit, uint8 auraScaleMask, TargetInfo& targetInfo)
{
FOREACH_SCRIPT(SpellSC)->OnScaleAuraUnitAdd(spell, target, effectMask, checkIfValid, implicit, auraScaleMask, targetInfo);
}
void ScriptMgr::OnRemoveAuraScaleTargets(Spell* spell, TargetInfo& targetInfo, uint8 auraScaleMask, bool& needErase)
{
FOREACH_SCRIPT(SpellSC)->OnRemoveAuraScaleTargets(spell, targetInfo, auraScaleMask, needErase);
}
void ScriptMgr::OnBeforeAuraRankForLevel(SpellInfo const* spellInfo, SpellInfo const* latestSpellInfo, uint8 level)
{
FOREACH_SCRIPT(SpellSC)->OnBeforeAuraRankForLevel(spellInfo, latestSpellInfo, level);
}
void ScriptMgr::SetRealmCompleted(AchievementEntry const* achievement)
{
FOREACH_SCRIPT(AchievementScript)->SetRealmCompleted(achievement);
}
bool ScriptMgr::IsCompletedCriteria(AchievementMgr* mgr, AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement, CriteriaProgress const* progress)
{
bool ret = true;
FOR_SCRIPTS_RET(AchievementScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->IsCompletedCriteria(mgr, achievementCriteria, achievement, progress))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::IsRealmCompleted(AchievementGlobalMgr const* globalmgr, AchievementEntry const* achievement, std::chrono::system_clock::time_point completionTime)
{
bool ret = true;
FOR_SCRIPTS_RET(AchievementScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->IsRealmCompleted(globalmgr, achievement, completionTime))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnBeforeCheckCriteria(AchievementMgr* mgr, AchievementCriteriaEntryList const* achievementCriteriaList)
{
FOREACH_SCRIPT(AchievementScript)->OnBeforeCheckCriteria(mgr, achievementCriteriaList);
}
bool ScriptMgr::CanCheckCriteria(AchievementMgr* mgr, AchievementCriteriaEntry const* achievementCriteria)
{
bool ret = true;
FOR_SCRIPTS_RET(AchievementScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanCheckCriteria(mgr, achievementCriteria))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnInitStatsForLevel(Guardian* guardian, uint8 petlevel)
{
FOREACH_SCRIPT(PetScript)->OnInitStatsForLevel(guardian, petlevel);
}
void ScriptMgr::OnCalculateMaxTalentPointsForLevel(Pet* pet, uint8 level, uint8& points)
{
FOREACH_SCRIPT(PetScript)->OnCalculateMaxTalentPointsForLevel(pet, level, points);
}
bool ScriptMgr::CanUnlearnSpellSet(Pet* pet, uint32 level, uint32 spell)
{
bool ret = true;
FOR_SCRIPTS_RET(PetScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanUnlearnSpellSet(pet, level, spell))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanUnlearnSpellDefault(Pet* pet, SpellInfo const* spellEntry)
{
bool ret = true;
FOR_SCRIPTS_RET(PetScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanUnlearnSpellDefault(pet, spellEntry))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanResetTalents(Pet* pet)
{
bool ret = true;
FOR_SCRIPTS_RET(PetScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanResetTalents(pet))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanAddMember(ArenaTeam* team, uint64 PlayerGuid)
{
bool ret = true;
FOR_SCRIPTS_RET(ArenaScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanAddMember(team, PlayerGuid))
ret = false; // we change ret value only when scripts return true
return ret;
}
void ScriptMgr::OnGetPoints(ArenaTeam* team, uint32 memberRating, float& points)
{
FOREACH_SCRIPT(ArenaScript)->OnGetPoints(team, memberRating, points);
}
bool ScriptMgr::CanSaveToDB(ArenaTeam* team)
{
bool ret = true;
FOR_SCRIPTS_RET(ArenaScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanSaveToDB(team))
ret = false; // we change ret value only when scripts return true
return ret;
}
void ScriptMgr::OnItemCreate(Item* item, ItemTemplate const* itemProto, Player const* owner)
{
FOREACH_SCRIPT(MiscScript)->OnItemCreate(item, itemProto, owner);
}
bool ScriptMgr::CanApplySoulboundFlag(Item* item, ItemTemplate const* proto)
{
bool ret = true;
FOR_SCRIPTS_RET(MiscScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanApplySoulboundFlag(item, proto))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::OnConstructObject(Object* origin)
{
FOREACH_SCRIPT(MiscScript)->OnConstructObject(origin);
}
void ScriptMgr::OnDestructObject(Object* origin)
{
FOREACH_SCRIPT(MiscScript)->OnDestructObject(origin);
}
void ScriptMgr::OnConstructPlayer(Player* origin)
{
FOREACH_SCRIPT(MiscScript)->OnConstructPlayer(origin);
}
void ScriptMgr::OnDestructPlayer(Player* origin)
{
FOREACH_SCRIPT(MiscScript)->OnDestructPlayer(origin);
}
void ScriptMgr::OnConstructGroup(Group* origin)
{
FOREACH_SCRIPT(MiscScript)->OnConstructGroup(origin);
}
void ScriptMgr::OnDestructGroup(Group* origin)
{
FOREACH_SCRIPT(MiscScript)->OnDestructGroup(origin);
}
void ScriptMgr::OnConstructInstanceSave(InstanceSave* origin)
{
FOREACH_SCRIPT(MiscScript)->OnConstructInstanceSave(origin);
}
void ScriptMgr::OnDestructInstanceSave(InstanceSave* origin)
{
FOREACH_SCRIPT(MiscScript)->OnDestructInstanceSave(origin);
}
bool ScriptMgr::CanItemApplyEquipSpell(Player* player, Item* item)
{
bool ret = true;
FOR_SCRIPTS_RET(MiscScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanItemApplyEquipSpell(player, item))
ret = false; // we change ret value only when scripts return false
return ret;
}
bool ScriptMgr::CanSendAuctionHello(WorldSession const* session, uint64 guid, Creature* creature)
{
bool ret = true;
FOR_SCRIPTS_RET(MiscScript, itr, end, ret) // return true by default if not scripts
if (!itr->second->CanSendAuctionHello(session, guid, creature))
ret = false; // we change ret value only when scripts return false
return ret;
}
void ScriptMgr::ValidateSpellAtCastSpell(Player* player, uint32& oldSpellId, uint32& spellId, uint8& castCount, uint8& castFlags)
{
FOREACH_SCRIPT(MiscScript)->ValidateSpellAtCastSpell(player, oldSpellId, spellId, castCount, castFlags);
}
void ScriptMgr::ValidateSpellAtCastSpellResult(Player* player, Unit* mover, Spell* spell, uint32 oldSpellId, uint32 spellId)
{
FOREACH_SCRIPT(MiscScript)->ValidateSpellAtCastSpellResult(player, mover, spell, oldSpellId, spellId);
}
void ScriptMgr::OnAfterLootTemplateProcess(Loot* loot, LootTemplate const* tab, LootStore const& store, Player* lootOwner, bool personal, bool noEmptyError, uint16 lootMode)
{
FOREACH_SCRIPT(MiscScript)->OnAfterLootTemplateProcess(loot, tab, store, lootOwner, personal, noEmptyError, lootMode);
}
void ScriptMgr::OnInstanceSave(InstanceSave* instanceSave)
{
FOREACH_SCRIPT(MiscScript)->OnInstanceSave(instanceSave);
}
void ScriptMgr::OnPlayerSetPhase(const AuraEffect* auraEff, AuraApplication const* aurApp, uint8 mode, bool apply, uint32& newPhase)
{
FOREACH_SCRIPT(MiscScript)->OnPlayerSetPhase(auraEff, aurApp, mode, apply, newPhase);
}
void ScriptMgr::OnHandleDevCommand(Player* player, std::string& argstr)
{
FOREACH_SCRIPT(CommandSC)->OnHandleDevCommand(player, argstr);
}
///-
AllMapScript::AllMapScript(const char* name) AllMapScript::AllMapScript(const char* name)
: ScriptObject(name) : ScriptObject(name)
{ {
@@ -2416,3 +3270,33 @@ MailScript::MailScript(const char* name)
{ {
ScriptRegistry<MailScript>::AddScript(this); ScriptRegistry<MailScript>::AddScript(this);
} }
AchievementScript::AchievementScript(const char* name)
: ScriptObject(name)
{
ScriptRegistry<AchievementScript>::AddScript(this);
}
PetScript::PetScript(const char* name)
: ScriptObject(name)
{
ScriptRegistry<PetScript>::AddScript(this);
}
ArenaScript::ArenaScript(const char* name)
: ScriptObject(name)
{
ScriptRegistry<ArenaScript>::AddScript(this);
}
MiscScript::MiscScript(const char* name)
: ScriptObject(name)
{
ScriptRegistry<MiscScript>::AddScript(this);
}
CommandSC::CommandSC(const char* name)
: ScriptObject(name)
{
ScriptRegistry<CommandSC>::AddScript(this);
}
+418 -31
View File
@@ -15,6 +15,7 @@
#include "DBCStores.h" #include "DBCStores.h"
#include "DynamicObject.h" #include "DynamicObject.h"
#include "GameEventMgr.h" #include "GameEventMgr.h"
#include "LFGMgr.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "PetDefines.h" #include "PetDefines.h"
#include "QuestDef.h" #include "QuestDef.h"
@@ -63,9 +64,11 @@ struct AchievementCriteriaData;
struct AuctionEntry; struct AuctionEntry;
struct ConditionSourceInfo; struct ConditionSourceInfo;
struct Condition; struct Condition;
struct DungeonProgressionRequirements;
struct ItemTemplate; struct ItemTemplate;
struct OutdoorPvPData; struct OutdoorPvPData;
struct GroupQueueInfo; struct GroupQueueInfo;
struct TargetInfo;
#define VISIBLE_RANGE 166.0f //MAX visible range (size of grid) #define VISIBLE_RANGE 166.0f //MAX visible range (size of grid)
@@ -287,6 +290,9 @@ public:
// Called after calculating arena rating changes // Called after calculating arena rating changes
virtual void OnAfterArenaRatingCalculation(Battleground* const /*bg*/, int32& /*winnerMatchmakerChange*/, int32& /*loserMatchmakerChange*/, int32& /*winnerChange*/, int32& /*loserChange*/) { }; virtual void OnAfterArenaRatingCalculation(Battleground* const /*bg*/, int32& /*winnerMatchmakerChange*/, int32& /*loserMatchmakerChange*/, int32& /*winnerChange*/, int32& /*loserChange*/) { };
// Called before modifying a player's personal rating
virtual void OnBeforeUpdatingPersonalRating(int32& /*mod*/, uint32 /*type*/) { }
}; };
template<class TMap> class MapScript : public UpdatableScript<TMap> template<class TMap> class MapScript : public UpdatableScript<TMap>
@@ -397,19 +403,19 @@ public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; } [[nodiscard]] bool IsDatabaseBound() const override { return true; }
// Called when a player accepts a quest from the item. // Called when a player accepts a quest from the item.
virtual bool OnQuestAccept(Player* /*player*/, Item* /*item*/, Quest const* /*quest*/) { return false; } [[nodiscard]] virtual bool OnQuestAccept(Player* /*player*/, Item* /*item*/, Quest const* /*quest*/) { return false; }
// Called when a player uses the item. // Called when a player uses the item.
virtual bool OnUse(Player* /*player*/, Item* /*item*/, SpellCastTargets const& /*targets*/) { return false; } [[nodiscard]] virtual bool OnUse(Player* /*player*/, Item* /*item*/, SpellCastTargets const& /*targets*/) { return false; }
// Called when the item is destroyed. // Called when the item is destroyed.
virtual bool OnRemove(Player* /*player*/, Item* /*item*/) { return false; } [[nodiscard]] virtual bool OnRemove(Player* /*player*/, Item* /*item*/) { return false; }
// Called before casting a combat spell from this item (chance on hit spells of item template, can be used to prevent cast if returning false) // Called before casting a combat spell from this item (chance on hit spells of item template, can be used to prevent cast if returning false)
virtual bool OnCastItemCombatSpell(Player* /*player*/, Unit* /*victim*/, SpellInfo const* /*spellInfo*/, Item* /*item*/) { return true; } [[nodiscard]] virtual bool OnCastItemCombatSpell(Player* /*player*/, Unit* /*victim*/, SpellInfo const* /*spellInfo*/, Item* /*item*/) { return true; }
// Called when the item expires (is destroyed). // Called when the item expires (is destroyed).
virtual bool OnExpire(Player* /*player*/, ItemTemplate const* /*proto*/) { return false; } [[nodiscard]] virtual bool OnExpire(Player* /*player*/, ItemTemplate const* /*proto*/) { return false; }
// Called when a player selects an option in an item gossip window // Called when a player selects an option in an item gossip window
virtual void OnGossipSelect(Player* /*player*/, Item* /*item*/, uint32 /*sender*/, uint32 /*action*/) { } virtual void OnGossipSelect(Player* /*player*/, Item* /*item*/, uint32 /*sender*/, uint32 /*action*/) { }
@@ -447,6 +453,20 @@ public:
virtual uint32 DealDamage(Unit* /*AttackerUnit*/, Unit* /*pVictim*/, uint32 damage, DamageEffectType /*damagetype*/) { return damage; } virtual uint32 DealDamage(Unit* /*AttackerUnit*/, Unit* /*pVictim*/, uint32 damage, DamageEffectType /*damagetype*/) { return damage; }
virtual void OnBeforeRollMeleeOutcomeAgainst(const Unit* /*attacker*/, const Unit* /*victim*/, WeaponAttackType /*attType*/, int32& /*attackerMaxSkillValueForLevel*/, int32& /*victimMaxSkillValueForLevel*/, int32& /*attackerWeaponSkill*/, int32& /*victimDefenseSkill*/, int32& /*crit_chance*/, int32& /*miss_chance*/, int32& /*dodge_chance*/, int32& /*parry_chance*/, int32& /*block_chance*/ ) { }; virtual void OnBeforeRollMeleeOutcomeAgainst(const Unit* /*attacker*/, const Unit* /*victim*/, WeaponAttackType /*attType*/, int32& /*attackerMaxSkillValueForLevel*/, int32& /*victimMaxSkillValueForLevel*/, int32& /*attackerWeaponSkill*/, int32& /*victimDefenseSkill*/, int32& /*crit_chance*/, int32& /*miss_chance*/, int32& /*dodge_chance*/, int32& /*parry_chance*/, int32& /*block_chance*/ ) { };
virtual void OnAuraRemove(Unit* /*unit*/, AuraApplication* /*aurApp*/, AuraRemoveMode /*mode*/) { }
[[nodiscard]] virtual bool IfNormalReaction(Unit const* /*unit*/, Unit const* /*target*/, ReputationRank& /*repRank*/) { return true; }
[[nodiscard]] virtual bool IsNeedModSpellDamagePercent(Unit const* /*unit*/, AuraEffect* /*auraEff*/, float& /*doneTotalMod*/, SpellInfo const* /*spellProto*/) { return true; }
[[nodiscard]] virtual bool IsNeedModMeleeDamagePercent(Unit const* /*unit*/, AuraEffect* /*auraEff*/, float& /*doneTotalMod*/, SpellInfo const* /*spellProto*/) { return true; }
[[nodiscard]] virtual bool IsNeedModHealPercent(Unit const* /*unit*/, AuraEffect* /*auraEff*/, float& /*doneTotalMod*/, SpellInfo const* /*spellProto*/) { return true; }
[[nodiscard]] virtual bool CanSetPhaseMask(Unit const* /*unit*/, uint32 /*newPhaseMask*/, bool /*update*/) { return true; }
[[nodiscard]] virtual bool IsCustomBuildValuesUpdate(Unit const* /*unit*/, uint8 /*updateType*/, ByteBuffer& /*fieldBuffer*/, Player const* /*target*/, uint16 /*index*/) { return false; }
}; };
class MovementHandlerScript : public ScriptObject class MovementHandlerScript : public ScriptObject
@@ -494,25 +514,25 @@ public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; } [[nodiscard]] bool IsDatabaseBound() const override { return true; }
// Called when a player opens a gossip dialog with the creature. // Called when a player opens a gossip dialog with the creature.
virtual bool OnGossipHello(Player* /*player*/, Creature* /*creature*/) { return false; } [[nodiscard]] virtual bool OnGossipHello(Player* /*player*/, Creature* /*creature*/) { return false; }
// Called when a player selects a gossip item in the creature's gossip menu. // Called when a player selects a gossip item in the creature's gossip menu.
virtual bool OnGossipSelect(Player* /*player*/, Creature* /*creature*/, uint32 /*sender*/, uint32 /*action*/) { return false; } [[nodiscard]] virtual bool OnGossipSelect(Player* /*player*/, Creature* /*creature*/, uint32 /*sender*/, uint32 /*action*/) { return false; }
// Called when a player selects a gossip with a code in the creature's gossip menu. // Called when a player selects a gossip with a code in the creature's gossip menu.
virtual bool OnGossipSelectCode(Player* /*player*/, Creature* /*creature*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { return false; } [[nodiscard]] virtual bool OnGossipSelectCode(Player* /*player*/, Creature* /*creature*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { return false; }
// Called when a player accepts a quest from the creature. // Called when a player accepts a quest from the creature.
virtual bool OnQuestAccept(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/) { return false; } [[nodiscard]] virtual bool OnQuestAccept(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/) { return false; }
// Called when a player selects a quest in the creature's quest menu. // Called when a player selects a quest in the creature's quest menu.
virtual bool OnQuestSelect(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/) { return false; } [[nodiscard]] virtual bool OnQuestSelect(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/) { return false; }
// Called when a player completes a quest with the creature. // Called when a player completes a quest with the creature.
virtual bool OnQuestComplete(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/) { return false; } [[nodiscard]] virtual bool OnQuestComplete(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/) { return false; }
// Called when a player selects a quest reward. // Called when a player selects a quest reward.
virtual bool OnQuestReward(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/, uint32 /*opt*/) { return false; } [[nodiscard]] virtual bool OnQuestReward(Player* /*player*/, Creature* /*creature*/, Quest const* /*quest*/, uint32 /*opt*/) { return false; }
// Called when the dialog status between a player and the creature is requested. // Called when the dialog status between a player and the creature is requested.
virtual uint32 GetDialogStatus(Player* /*player*/, Creature* /*creature*/) { return DIALOG_STATUS_SCRIPTED_NO_STATUS; } virtual uint32 GetDialogStatus(Player* /*player*/, Creature* /*creature*/) { return DIALOG_STATUS_SCRIPTED_NO_STATUS; }
@@ -530,19 +550,19 @@ public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; } [[nodiscard]] bool IsDatabaseBound() const override { return true; }
// Called when a player opens a gossip dialog with the gameobject. // Called when a player opens a gossip dialog with the gameobject.
virtual bool OnGossipHello(Player* /*player*/, GameObject* /*go*/) { return false; } [[nodiscard]] virtual bool OnGossipHello(Player* /*player*/, GameObject* /*go*/) { return false; }
// Called when a player selects a gossip item in the gameobject's gossip menu. // Called when a player selects a gossip item in the gameobject's gossip menu.
virtual bool OnGossipSelect(Player* /*player*/, GameObject* /*go*/, uint32 /*sender*/, uint32 /*action*/) { return false; } [[nodiscard]] virtual bool OnGossipSelect(Player* /*player*/, GameObject* /*go*/, uint32 /*sender*/, uint32 /*action*/) { return false; }
// Called when a player selects a gossip with a code in the gameobject's gossip menu. // Called when a player selects a gossip with a code in the gameobject's gossip menu.
virtual bool OnGossipSelectCode(Player* /*player*/, GameObject* /*go*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { return false; } [[nodiscard]] virtual bool OnGossipSelectCode(Player* /*player*/, GameObject* /*go*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { return false; }
// Called when a player accepts a quest from the gameobject. // Called when a player accepts a quest from the gameobject.
virtual bool OnQuestAccept(Player* /*player*/, GameObject* /*go*/, Quest const* /*quest*/) { return false; } [[nodiscard]] virtual bool OnQuestAccept(Player* /*player*/, GameObject* /*go*/, Quest const* /*quest*/) { return false; }
// Called when a player selects a quest reward. // Called when a player selects a quest reward.
virtual bool OnQuestReward(Player* /*player*/, GameObject* /*go*/, Quest const* /*quest*/, uint32 /*opt*/) { return false; } [[nodiscard]] virtual bool OnQuestReward(Player* /*player*/, GameObject* /*go*/, Quest const* /*quest*/, uint32 /*opt*/) { return false; }
// Called when the dialog status between a player and the gameobject is requested. // Called when the dialog status between a player and the gameobject is requested.
virtual uint32 GetDialogStatus(Player* /*player*/, GameObject* /*go*/) { return DIALOG_STATUS_SCRIPTED_NO_STATUS; } virtual uint32 GetDialogStatus(Player* /*player*/, GameObject* /*go*/) { return DIALOG_STATUS_SCRIPTED_NO_STATUS; }
@@ -572,7 +592,7 @@ public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; } [[nodiscard]] bool IsDatabaseBound() const override { return true; }
// Called when the area trigger is activated by a player. // Called when the area trigger is activated by a player.
virtual bool OnTrigger(Player* /*player*/, AreaTrigger const* /*trigger*/) { return false; } [[nodiscard]] virtual bool OnTrigger(Player* /*player*/, AreaTrigger const* /*trigger*/) { return false; }
}; };
class BattlegroundScript : public ScriptObject class BattlegroundScript : public ScriptObject
@@ -670,7 +690,7 @@ public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; } [[nodiscard]] bool IsDatabaseBound() const override { return true; }
// Called when a single condition is checked for a player. // Called when a single condition is checked for a player.
virtual bool OnConditionCheck(Condition* /*condition*/, ConditionSourceInfo& /*sourceInfo*/) { return true; } [[nodiscard]] virtual bool OnConditionCheck(Condition* /*condition*/, ConditionSourceInfo& /*sourceInfo*/) { return true; }
}; };
class VehicleScript : public ScriptObject class VehicleScript : public ScriptObject
@@ -734,7 +754,7 @@ public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; } [[nodiscard]] bool IsDatabaseBound() const override { return true; }
// deprecated/legacy // deprecated/legacy
virtual bool OnCheck(Player* /*source*/, Unit* /*target*/) { return true; }; [[nodiscard]] virtual bool OnCheck(Player* /*source*/, Unit* /*target*/) { return true; };
}; };
class PlayerScript : public ScriptObject class PlayerScript : public ScriptObject
@@ -860,7 +880,7 @@ public:
virtual void OnMapChanged(Player* /*player*/) { } virtual void OnMapChanged(Player* /*player*/) { }
// Called before a player is being teleported to new coords // Called before a player is being teleported to new coords
virtual bool OnBeforeTeleport(Player* /*player*/, uint32 /*mapid*/, float /*x*/, float /*y*/, float /*z*/, float /*orientation*/, uint32 /*options*/, Unit* /*target*/) { return true; } [[nodiscard]] virtual bool OnBeforeTeleport(Player* /*player*/, uint32 /*mapid*/, float /*x*/, float /*y*/, float /*z*/, float /*orientation*/, uint32 /*options*/, Unit* /*target*/) { return true; }
// Called when team/faction is set on player // Called when team/faction is set on player
virtual void OnUpdateFaction(Player* /*player*/) { } virtual void OnUpdateFaction(Player* /*player*/) { }
@@ -922,14 +942,23 @@ public:
//After creating item (eg profession item creation) //After creating item (eg profession item creation)
virtual void OnCreateItem(Player* /*player*/, Item* /*item*/, uint32 /*count*/) { } virtual void OnCreateItem(Player* /*player*/, Item* /*item*/, uint32 /*count*/) { }
//After receiving item as a quest reward // After receiving item as a quest reward
virtual void OnQuestRewardItem(Player* /*player*/, Item* /*item*/, uint32 /*count*/) { } virtual void OnQuestRewardItem(Player* /*player*/, Item* /*item*/, uint32 /*count*/) { }
// After completed a quest
[[nodiscard]] virtual bool OnBeforeQuestComplete(Player* /*player*/, uint32 /*quest_id*/) { return true; }
// Before durability repair action, you can even modify the discount value
virtual void OnBeforeDurabilityRepair(Player* /*player*/, uint64 /*npcGUID*/, uint64 /*itemGUID*/, float&/*discountMod*/, uint8 /*guildBank*/) { }
//Before buying something from any vendor //Before buying something from any vendor
virtual void OnBeforeBuyItemFromVendor(Player* /*player*/, uint64 /*vendorguid*/, uint32 /*vendorslot*/, uint32& /*item*/, uint8 /*count*/, uint8 /*bag*/, uint8 /*slot*/) { }; virtual void OnBeforeBuyItemFromVendor(Player* /*player*/, uint64 /*vendorguid*/, uint32 /*vendorslot*/, uint32& /*item*/, uint8 /*count*/, uint8 /*bag*/, uint8 /*slot*/) { };
//Before buying something from any vendor //Before buying something from any vendor
virtual void OnAfterStoreOrEquipNewItem(Player* /*player*/, uint32 /*vendorslot*/, uint32& /*item*/, uint8 /*count*/, uint8 /*bag*/, uint8 /*slot*/, ItemTemplate const* /*pProto*/, Creature* /*pVendor*/, VendorItem const* /*crItem*/, bool /*bStore*/) { }; virtual void OnBeforeStoreOrEquipNewItem(Player* /*player*/, uint32 /*vendorslot*/, uint32& /*item*/, uint8 /*count*/, uint8 /*bag*/, uint8 /*slot*/, ItemTemplate const* /*pProto*/, Creature* /*pVendor*/, VendorItem const* /*crItem*/, bool /*bStore*/) { };
//After buying something from any vendor
virtual void OnAfterStoreOrEquipNewItem(Player* /*player*/, uint32 /*vendorslot*/, Item* /*item*/, uint8 /*count*/, uint8 /*bag*/, uint8 /*slot*/, ItemTemplate const* /*pProto*/, Creature* /*pVendor*/, VendorItem const* /*crItem*/, bool /*bStore*/) { };
virtual void OnAfterUpdateMaxPower(Player* /*player*/, Powers& /*power*/, float& /*value*/) { } virtual void OnAfterUpdateMaxPower(Player* /*player*/, Powers& /*power*/, float& /*value*/) { }
@@ -942,7 +971,7 @@ public:
virtual void OnFirstLogin(Player* /*player*/) { } virtual void OnFirstLogin(Player* /*player*/) { }
virtual bool CanJoinInBattlegroundQueue(Player* /*player*/, uint64 /*BattlemasterGuid*/, BattlegroundTypeId /*BGTypeID*/, uint8 /*joinAsGroup*/, GroupJoinBattlegroundResult& /*err*/) { return true; } [[nodiscard]] virtual bool CanJoinInBattlegroundQueue(Player* /*player*/, uint64 /*BattlemasterGuid*/, BattlegroundTypeId /*BGTypeID*/, uint8 /*joinAsGroup*/, GroupJoinBattlegroundResult& /*err*/) { return true; }
virtual bool ShouldBeRewardedWithMoneyInsteadOfExp(Player* /*player*/) { return false; } virtual bool ShouldBeRewardedWithMoneyInsteadOfExp(Player* /*player*/) { return false; }
// Called before the player's temporary summoned creature has initialized it's stats // Called before the player's temporary summoned creature has initialized it's stats
@@ -956,6 +985,100 @@ public:
// Called before loading a player's pet from the DB // Called before loading a player's pet from the DB
virtual void OnBeforeLoadPetFromDB(Player* /*player*/, uint32& /*petentry*/, uint32& /*petnumber*/, bool& /*current*/, bool& /*forceLoadFromDB*/) { } virtual void OnBeforeLoadPetFromDB(Player* /*player*/, uint32& /*petentry*/, uint32& /*petnumber*/, bool& /*current*/, bool& /*forceLoadFromDB*/) { }
[[nodiscard]] virtual bool CanJoinInArenaQueue(Player* /*player*/, uint64 /*BattlemasterGuid*/, uint8 /*arenaslot*/, BattlegroundTypeId /*BGTypeID*/, uint8 /*joinAsGroup*/, uint8 /*IsRated*/, GroupJoinBattlegroundResult& /*err*/) { return true; }
[[nodiscard]] virtual bool CanBattleFieldPort(Player* /*player*/, uint8 /*arenaType*/, BattlegroundTypeId /*BGTypeID*/, uint8 /*action*/) { return true; }
[[nodiscard]] virtual bool CanGroupInvite(Player* /*player*/, std::string& /*membername*/) { return true; }
[[nodiscard]] virtual bool CanGroupAccept(Player* /*player*/, Group* /*group*/) { return true; }
[[nodiscard]] virtual bool CanSellItem(Player* /*player*/, Item* /*item*/, Creature* /*creature*/) { return true; }
[[nodiscard]] virtual bool CanSendMail(Player* /*player*/, uint64 /*receiverGuid*/, uint64 /*mailbox*/, std::string& /*subject*/, std::string& /*body*/, uint32 /*money*/, uint32 /*COD*/, Item* /*item*/) { return true; }
virtual void PetitionBuy(Player* /*player*/, Creature* /*creature*/, uint32& /*charterid*/, uint32& /*cost*/, uint32& /*type*/) { }
virtual void PetitionShowList(Player* /*player*/, Creature* /*creature*/, uint32& /*CharterEntry*/, uint32& /*CharterDispayID*/, uint32& /*CharterCost*/) { }
virtual void OnRewardKillRewarder(Player* /*player*/, bool /*isDungeon*/, float& /*rate*/) { }
[[nodiscard]] virtual bool CanGiveMailRewardAtGiveLevel(Player* /*player*/, uint8 /*level*/) { return true; }
virtual void OnDeleteFromDB(SQLTransaction& /*trans*/, uint32 /*guid*/) { }
[[nodiscard]] virtual bool CanRepopAtGraveyard(Player* /*player*/) { return true; }
virtual void OnGetMaxSkillValue(Player* /*player*/, uint32 /*skill*/, int32& /*result*/, bool /*IsPure*/) { }
[[nodiscard]] virtual bool CanAreaExploreAndOutdoor(Player* /*player*/) { return true; }
virtual void OnVictimRewardBefore(Player* /*player*/, Player* /*victim*/, uint32& /*killer_title*/, uint32& /*victim_title*/) { }
virtual void OnVictimRewardAfter(Player* /*player*/, Player* /*victim*/, uint32& /*killer_title*/, uint32& /*victim_rank*/, float& /*honor_f*/) { }
virtual void OnCustomScalingStatValueBefore(Player* /*player*/, ItemTemplate const* /*proto*/, uint8 /*slot*/, bool /*apply*/, uint32& /*CustomScalingStatValue*/) { }
virtual void OnCustomScalingStatValue(Player* /*player*/, ItemTemplate const* /*proto*/, uint32& /*statType*/, int32& /*val*/, uint8 /*itemProtoStatNumber*/, uint32 /*ScalingStatValue*/, ScalingStatValuesEntry const* /*ssv*/) { }
[[nodiscard]] virtual bool CanArmorDamageModifier(Player* /*player*/) { return true; }
virtual void OnGetFeralApBonus(Player* /*player*/, int32& /*feral_bonus*/, int32 /*dpsMod*/, ItemTemplate const* /*proto*/, ScalingStatValuesEntry const* /*ssv*/) { }
[[nodiscard]] virtual bool CanApplyWeaponDependentAuraDamageMod(Player* /*player*/, Item* /*item*/, WeaponAttackType /*attackType*/, AuraEffect const* /*aura*/, bool /*apply*/) { return true; }
[[nodiscard]] virtual bool CanApplyEquipSpell(Player* /*player*/, SpellInfo const* /*spellInfo*/, Item* /*item*/, bool /*apply*/, bool /*form_change*/) { return true; }
[[nodiscard]] virtual bool CanApplyEquipSpellsItemSet(Player* /*player*/, ItemSetEffect* /*eff*/) { return true; }
[[nodiscard]] virtual bool CanCastItemCombatSpell(Player* /*player*/, Unit* /*target*/, WeaponAttackType /*attType*/, uint32 /*procVictim*/, uint32 /*procEx*/, Item* /*item*/, ItemTemplate const* /*proto*/) { return true; }
[[nodiscard]] virtual bool CanCastItemUseSpell(Player* /*player*/, Item* /*item*/, SpellCastTargets const& /*targets*/, uint8 /*cast_count*/, uint32 /*glyphIndex*/) { return true; }
virtual void OnApplyAmmoBonuses(Player* /*player*/, ItemTemplate const* /*proto*/, float& /*currentAmmoDPS*/) { }
[[nodiscard]] virtual bool CanEquipItem(Player* /*player*/, uint8 /*slot*/, uint16& /*dest*/, Item* /*pItem*/, bool /*swap*/, bool /*not_loading*/) { return true; }
[[nodiscard]] virtual bool CanUnequipItem(Player* /*player*/, uint16 /*pos*/, bool /*swap*/) { return true; }
[[nodiscard]] virtual bool CanUseItem(Player* /*player*/, ItemTemplate const* /*proto*/, InventoryResult& /*result*/) { return true; }
[[nodiscard]] virtual bool CanSaveEquipNewItem(Player* /*player*/, Item* /*item*/, uint16 /*pos*/, bool /*update*/) { return true; }
[[nodiscard]] virtual bool CanApplyEnchantment(Player* /*player*/, Item* /*item*/, EnchantmentSlot /*slot*/, bool /*apply*/, bool /*apply_dur*/, bool /*ignore_condition*/) { return true; }
virtual void OnGetQuestRate(Player* /*player*/, float& /*result*/) { }
[[nodiscard]] virtual bool PassedQuestKilledMonsterCredit(Player* /*player*/, Quest const* /*qinfo*/, uint32 /*entry*/, uint32 /*real_entry*/, uint64 /*guid*/) { return true; }
[[nodiscard]] virtual bool CheckItemInSlotAtLoadInventory(Player* /*player*/, Item* /*item*/, uint8 /*slot*/, uint8& /*err*/, uint16& /*dest*/) { return true; }
[[nodiscard]] virtual bool NotAvoidSatisfy(Player* /*player*/, DungeonProgressionRequirements const* /*ar*/, uint32 /*target_map*/, bool /*report*/) { return true; }
[[nodiscard]] virtual bool NotVisibleGloballyFor(Player* /*player*/, Player const* /*u*/) { return true; }
virtual void OnGetArenaPersonalRating(Player* /*player*/, uint8 /*slot*/, uint32& /*result*/) { }
virtual void OnGetArenaTeamId(Player* /*player*/, uint8 /*slot*/, uint32& /*result*/) { }
virtual void OnIsFFAPvP(Player* /*player*/, bool& /*result*/) { }
virtual void OnIsPvP(Player* /*player*/, bool& /*result*/) { }
virtual void OnGetMaxSkillValueForLevel(Player* /*player*/, uint16& /*result*/) { }
[[nodiscard]] virtual bool NotSetArenaTeamInfoField(Player* /*player*/, uint8 /*slot*/, ArenaTeamInfoType /*type*/, uint32 /*value*/) { return true; }
[[nodiscard]] virtual bool CanJoinLfg(Player* /*player*/, uint8 /*roles*/, lfg::LfgDungeonSet& /*dungeons*/, const std::string& /*comment*/) { return true; }
[[nodiscard]] virtual bool CanEnterMap(Player* /*player*/, MapEntry const* /*entry*/, InstanceTemplate const* /*instance*/, MapDifficulty const* /*mapDiff*/, bool /*loginCheck*/) { return true; }
[[nodiscard]] virtual bool CanInitTrade(Player* /*player*/, Player* /*target*/) { return true; }
virtual void OnSetServerSideVisibility(Player* /*player*/, ServerSideVisibilityType& /*type*/, AccountTypes& /*sec*/) { }
virtual void OnSetServerSideVisibilityDetect(Player* /*player*/, ServerSideVisibilityType& /*type*/, AccountTypes& /*sec*/) { }
}; };
class AccountScript : public ScriptObject class AccountScript : public ScriptObject
@@ -1025,6 +1148,8 @@ public:
virtual void OnEvent(Guild* /*guild*/, uint8 /*eventType*/, uint32 /*playerGuid1*/, uint32 /*playerGuid2*/, uint8 /*newRank*/) { } virtual void OnEvent(Guild* /*guild*/, uint8 /*eventType*/, uint32 /*playerGuid1*/, uint32 /*playerGuid2*/, uint8 /*newRank*/) { }
virtual void OnBankEvent(Guild* /*guild*/, uint8 /*eventType*/, uint8 /*tabId*/, uint32 /*playerGuid*/, uint32 /*itemOrMoney*/, uint16 /*itemStackCount*/, uint8 /*destTabId*/) { } virtual void OnBankEvent(Guild* /*guild*/, uint8 /*eventType*/, uint8 /*tabId*/, uint32 /*playerGuid*/, uint32 /*itemOrMoney*/, uint16 /*itemStackCount*/, uint8 /*destTabId*/) { }
[[nodiscard]] virtual bool CanGuildSendBankList(Guild const* /*guild*/, WorldSession* /*session*/, uint8 /*tabId*/, bool /*sendAllSlots*/) { return true; }
}; };
class GroupScript : public ScriptObject class GroupScript : public ScriptObject
@@ -1049,6 +1174,10 @@ public:
// Called when a group is disbanded. // Called when a group is disbanded.
virtual void OnDisband(Group* /*group*/) { } virtual void OnDisband(Group* /*group*/) { }
[[nodiscard]] virtual bool CanGroupJoinBattlegroundQueue(Group const* /*group*/, Player* /*member*/, Battleground const* /*bgTemplate*/, uint32 /*MinPlayerCount*/, bool /*isRated*/, uint32 /*arenaSlot*/) { return true; }
virtual void OnCreate(Group* /*group*/, Player* /*leader*/) { }
}; };
// following hooks can be used anywhere and are not db bounded // following hooks can be used anywhere and are not db bounded
@@ -1067,7 +1196,7 @@ public:
virtual void OnBeforeDropAddItem(Player const* /*player*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, LootStoreItem* /*LootStoreItem*/, LootStore const& /*store*/) { } virtual void OnBeforeDropAddItem(Player const* /*player*/, Loot& /*loot*/, bool /*canRate*/, uint16 /*lootMode*/, LootStoreItem* /*LootStoreItem*/, LootStore const& /*store*/) { }
virtual void OnItemRoll(Player const* /*player*/, LootStoreItem const* /*LootStoreItem*/, float& /*chance*/, Loot& /*loot*/, LootStore const& /*store*/) { }; virtual void OnItemRoll(Player const* /*player*/, LootStoreItem const* /*LootStoreItem*/, float& /*chance*/, Loot& /*loot*/, LootStore const& /*store*/) { };
virtual void OnInitializeLockedDungeons(Player* /*player*/, uint8& /*level*/, uint32& /*lockData*/) { } virtual void OnInitializeLockedDungeons(Player* /*player*/, uint8& /*level*/, uint32& /*lockData*/, lfg::LFGDungeonData const* /*dungeon*/) { }
virtual void OnAfterInitializeLockedDungeons(Player* /*player*/) { } virtual void OnAfterInitializeLockedDungeons(Player* /*player*/) { }
// On Before arena points distribution // On Before arena points distribution
@@ -1106,16 +1235,20 @@ public:
// Remove player at leave BG // Remove player at leave BG
virtual void OnBattlegroundRemovePlayerAtLeave(Battleground* /*bg*/, Player* /*player*/) { } virtual void OnBattlegroundRemovePlayerAtLeave(Battleground* /*bg*/, Player* /*player*/) { }
virtual void OnQueueUpdate(BattlegroundQueue* /*queue*/, BattlegroundBracketId /*bracket_id*/, bool /*isRated*/, uint32 /*arenaRatedTeamId*/) { }
virtual void OnAddGroup(BattlegroundQueue* /*queue*/, GroupQueueInfo* /*ginfo*/, uint32& /*index*/, Player* /*leader*/, Group* /*grp*/, PvPDifficultyEntry const* /*bracketEntry*/, bool /*isPremade*/) { } virtual void OnAddGroup(BattlegroundQueue* /*queue*/, GroupQueueInfo* /*ginfo*/, uint32& /*index*/, Player* /*leader*/, Group* /*grp*/, PvPDifficultyEntry const* /*bracketEntry*/, bool /*isPremade*/) { }
virtual bool CanFillPlayersToBG(BattlegroundQueue* /*queue*/, Battleground* /*bg*/, const int32 /*aliFree*/, const int32 /*hordeFree*/, BattlegroundBracketId /*bracket_id*/) { return true; } [[nodiscard]] virtual bool CanFillPlayersToBG(BattlegroundQueue* /*queue*/, Battleground* /*bg*/, const int32 /*aliFree*/, const int32 /*hordeFree*/, BattlegroundBracketId /*bracket_id*/) { return true; }
virtual bool CanFillPlayersToBGWithSpecific(BattlegroundQueue* /*queue*/, Battleground* /*bg*/, const int32 /*aliFree*/, const int32 /*hordeFree*/, [[nodiscard]] virtual bool CanFillPlayersToBGWithSpecific(BattlegroundQueue* /*queue*/, Battleground* /*bg*/, const int32 /*aliFree*/, const int32 /*hordeFree*/,
BattlegroundBracketId /*thisBracketId*/, BattlegroundQueue* /*specificQueue*/, BattlegroundBracketId /*specificBracketId*/) { return true; } BattlegroundBracketId /*thisBracketId*/, BattlegroundQueue* /*specificQueue*/, BattlegroundBracketId /*specificBracketId*/) { return true; }
virtual void OnCheckNormalMatch(BattlegroundQueue* /*queue*/, uint32& /*Coef*/, Battleground* /*bgTemplate*/, BattlegroundBracketId /*bracket_id*/, uint32& /*minPlayers*/, uint32& /*maxPlayers*/) { } virtual void OnCheckNormalMatch(BattlegroundQueue* /*queue*/, uint32& /*Coef*/, Battleground* /*bgTemplate*/, BattlegroundBracketId /*bracket_id*/, uint32& /*minPlayers*/, uint32& /*maxPlayers*/) { }
virtual bool CanSendMessageQueue(BattlegroundQueue* /*queue*/, Player* /*leader*/, Battleground* /*bg*/, PvPDifficultyEntry const* /*bracketEntry*/) { return true; } [[nodiscard]] virtual bool CanSendMessageBGQueue(BattlegroundQueue* /*queue*/, Player* /*leader*/, Battleground* /*bg*/, PvPDifficultyEntry const* /*bracketEntry*/) { return true; }
[[nodiscard]] virtual bool CanSendMessageArenaQueue(BattlegroundQueue* /*queue*/, GroupQueueInfo* /*ginfo*/, bool /*IsJoin*/) { return true; }
}; };
class ArenaTeamScript : public ScriptObject class ArenaTeamScript : public ScriptObject
@@ -1143,6 +1276,24 @@ public:
// Calculate max duration in applying aura // Calculate max duration in applying aura
virtual void OnCalcMaxDuration(Aura const* /*aura*/, int32& /*maxDuration*/) { } virtual void OnCalcMaxDuration(Aura const* /*aura*/, int32& /*maxDuration*/) { }
[[nodiscard]] virtual bool CanModAuraEffectDamageDone(AuraEffect const* /*auraEff*/, Unit* /*target*/, AuraApplication const* /*aurApp*/, uint8 /*mode*/, bool /*apply*/) { return true; }
[[nodiscard]] virtual bool CanModAuraEffectModDamagePercentDone(AuraEffect const* /*auraEff*/, Unit* /*target*/, AuraApplication const* /*aurApp*/, uint8 /*mode*/, bool /*apply*/) { return true; }
virtual void OnSpellCheckCast(Spell* /*spell*/, bool /*strict*/, SpellCastResult& /*res*/) { }
[[nodiscard]] virtual bool CanPrepare(Spell* /*spell*/, SpellCastTargets const* /*targets*/, AuraEffect const* /*triggeredByAura*/) { return true; }
[[nodiscard]] virtual bool CanScalingEverything(Spell* /*spell*/) { return false; }
[[nodiscard]] virtual bool CanSelectSpecTalent(Spell* /*spell*/) { return true; }
virtual void OnScaleAuraUnitAdd(Spell* /*spell*/, Unit* /*target*/, uint32 /*effectMask*/, bool /*checkIfValid*/, bool /*implicit*/, uint8 /*auraScaleMask*/, TargetInfo& /*targetInfo*/) { }
virtual void OnRemoveAuraScaleTargets(Spell* /*spell*/, TargetInfo& /*targetInfo*/, uint8 /*auraScaleMask*/, bool& /*needErase*/) { }
virtual void OnBeforeAuraRankForLevel(SpellInfo const* /*spellInfo*/, SpellInfo const* /*latestSpellInfo*/, uint8 /*level*/) { }
}; };
// this class can be used to be extended by Modules // this class can be used to be extended by Modules
@@ -1176,6 +1327,124 @@ public:
virtual void OnBeforeMailDraftSendMailTo(MailDraft* /*mailDraft*/, MailReceiver const& /*receiver*/, MailSender const& /*sender*/, MailCheckMask& /*checked*/, uint32& /*deliver_delay*/, uint32& /*custom_expiration*/, bool& /*deleteMailItemsFromDB*/, bool& /*sendMail*/) { } virtual void OnBeforeMailDraftSendMailTo(MailDraft* /*mailDraft*/, MailReceiver const& /*receiver*/, MailSender const& /*sender*/, MailCheckMask& /*checked*/, uint32& /*deliver_delay*/, uint32& /*custom_expiration*/, bool& /*deleteMailItemsFromDB*/, bool& /*sendMail*/) { }
}; };
class AchievementScript : public ScriptObject
{
protected:
AchievementScript(const char* name);
public:
bool IsDatabaseBound() const { return false; }
// After complete global acvievement
virtual void SetRealmCompleted(AchievementEntry const* /*achievement*/) { }
[[nodiscard]] virtual bool IsCompletedCriteria(AchievementMgr* /*mgr*/, AchievementCriteriaEntry const* /*achievementCriteria*/, AchievementEntry const* /*achievement*/, CriteriaProgress const* /*progress*/) { return true; }
[[nodiscard]] virtual bool IsRealmCompleted(AchievementGlobalMgr const* /*globalmgr*/, AchievementEntry const* /*achievement*/, std::chrono::system_clock::time_point /*completionTime*/) { return true; }
virtual void OnBeforeCheckCriteria(AchievementMgr* /*mgr*/, AchievementCriteriaEntryList const* /*achievementCriteriaList*/) { }
[[nodiscard]] virtual bool CanCheckCriteria(AchievementMgr* /*mgr*/, AchievementCriteriaEntry const* /*achievementCriteria*/) { return true; }
};
class PetScript : public ScriptObject
{
protected:
PetScript(const char* name);
public:
bool IsDatabaseBound() const { return false; }
virtual void OnInitStatsForLevel(Guardian* /*guardian*/, uint8 /*petlevel*/) { }
virtual void OnCalculateMaxTalentPointsForLevel(Pet* /*pet*/, uint8 /*level*/, uint8& /*points*/) { }
[[nodiscard]] virtual bool CanUnlearnSpellSet(Pet* /*pet*/, uint32 /*level*/, uint32 /*spell*/) { return true; }
[[nodiscard]] virtual bool CanUnlearnSpellDefault(Pet* /*pet*/, SpellInfo const* /*spellEntry*/) { return true; }
[[nodiscard]] virtual bool CanResetTalents(Pet* /*pet*/) { return true; }
};
class ArenaScript : public ScriptObject
{
protected:
ArenaScript(const char* name);
public:
bool IsDatabaseBound() const { return false; }
[[nodiscard]] virtual bool CanAddMember(ArenaTeam* /*team*/, uint64 /*PlayerGuid*/) { return true; }
virtual void OnGetPoints(ArenaTeam* /*team*/, uint32 /*memberRating*/, float& /*points*/) { }
[[nodiscard]] virtual bool CanSaveToDB(ArenaTeam* /*team*/) { return true; }
};
class MiscScript : public ScriptObject
{
protected:
MiscScript(const char* name);
public:
bool IsDatabaseBound() const { return false; }
virtual void OnConstructObject(Object* /*origin*/) { }
virtual void OnDestructObject(Object* /*origin*/) { }
virtual void OnConstructPlayer(Player* /*origin*/) { }
virtual void OnDestructPlayer(Player* /*origin*/) { }
virtual void OnConstructGroup(Group* /*origin*/) { }
virtual void OnDestructGroup(Group* /*origin*/) { }
virtual void OnConstructInstanceSave(InstanceSave* /*origin*/) { }
virtual void OnDestructInstanceSave(InstanceSave* /*origin*/) { }
virtual void OnItemCreate(Item* /*item*/, ItemTemplate const* /*itemProto*/, Player const* /*owner*/) { }
[[nodiscard]] virtual bool CanApplySoulboundFlag(Item* /*item*/, ItemTemplate const* /*proto*/) { return true; }
[[nodiscard]] virtual bool CanItemApplyEquipSpell(Player* /*player*/, Item* /*item*/) { return true; }
[[nodiscard]] virtual bool CanSendAuctionHello(WorldSession const* /*session*/, uint64 /*guid*/, Creature* /*creature*/) { return true; }
virtual void ValidateSpellAtCastSpell(Player* /*player*/, uint32& /*oldSpellId*/, uint32& /*spellId*/, uint8& /*castCount*/, uint8& /*castFlags*/) { }
virtual void ValidateSpellAtCastSpellResult(Player* /*player*/, Unit* /*mover*/, Spell* /*spell*/, uint32 /*oldSpellId*/, uint32 /*spellId*/) { }
virtual void OnAfterLootTemplateProcess(Loot* /*loot*/, LootTemplate const* /*tab*/, LootStore const& /*store*/, Player* /*lootOwner*/, bool /*personal*/, bool /*noEmptyError*/, uint16 /*lootMode*/) { }
virtual void OnPlayerSetPhase(const AuraEffect* /*auraEff*/, AuraApplication const* /*aurApp*/, uint8 /*mode*/, bool /*apply*/, uint32& /*newPhase*/) { }
virtual void OnInstanceSave(InstanceSave* /*instanceSave*/) { }
};
class CommandSC : public ScriptObject
{
protected:
CommandSC(const char* name);
public:
bool IsDatabaseBound() const { return false; }
virtual void OnHandleDevCommand(Player* /*player*/, std::string& /*argstr*/) { }
};
// Manages registration, loading, and execution of scripts. // Manages registration, loading, and execution of scripts.
class ScriptMgr class ScriptMgr
{ {
@@ -1234,6 +1503,7 @@ public: /* FormulaScript */
void OnGainCalculation(uint32& gain, Player* player, Unit* unit); void OnGainCalculation(uint32& gain, Player* player, Unit* unit);
void OnGroupRateCalculation(float& rate, uint32 count, bool isRaid); void OnGroupRateCalculation(float& rate, uint32 count, bool isRaid);
void OnAfterArenaRatingCalculation(Battleground* const bg, int32& winnerMatchmakerChange, int32& loserMatchmakerChange, int32& winnerChange, int32& loserChange); void OnAfterArenaRatingCalculation(Battleground* const bg, int32& winnerMatchmakerChange, int32& loserMatchmakerChange, int32& winnerChange, int32& loserChange);
void OnBeforeUpdatingPersonalRating(int32& mod, uint32 type);
public: /* MapScript */ public: /* MapScript */
void OnCreateMap(Map* map); void OnCreateMap(Map* map);
@@ -1396,8 +1666,11 @@ public: /* PlayerScript */
void OnLootItem(Player* player, Item* item, uint32 count, uint64 lootguid); void OnLootItem(Player* player, Item* item, uint32 count, uint64 lootguid);
void OnCreateItem(Player* player, Item* item, uint32 count); void OnCreateItem(Player* player, Item* item, uint32 count);
void OnQuestRewardItem(Player* player, Item* item, uint32 count); void OnQuestRewardItem(Player* player, Item* item, uint32 count);
bool OnBeforePlayerQuestComplete(Player* player, uint32 quest_id);
void OnBeforePlayerDurabilityRepair(Player* player, uint64 npcGUID, uint64 itemGUID, float& discountMod, uint8 guildBank);
void OnBeforeBuyItemFromVendor(Player* player, uint64 vendorguid, uint32 vendorslot, uint32& item, uint8 count, uint8 bag, uint8 slot); void OnBeforeBuyItemFromVendor(Player* player, uint64 vendorguid, uint32 vendorslot, uint32& item, uint8 count, uint8 bag, uint8 slot);
void OnAfterStoreOrEquipNewItem(Player* player, uint32 vendorslot, uint32& item, uint8 count, uint8 bag, uint8 slot, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore); void OnBeforeStoreOrEquipNewItem(Player* player, uint32 vendorslot, uint32& item, uint8 count, uint8 bag, uint8 slot, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore);
void OnAfterStoreOrEquipNewItem(Player* player, uint32 vendorslot, Item* item, uint8 count, uint8 bag, uint8 slot, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore);
void OnAfterUpdateMaxPower(Player* player, Powers& power, float& value); void OnAfterUpdateMaxPower(Player* player, Powers& power, float& value);
void OnAfterUpdateMaxHealth(Player* player, float& value); void OnAfterUpdateMaxHealth(Player* player, float& value);
void OnBeforeUpdateAttackPowerAndDamage(Player* player, float& level, float& val2, bool ranged); void OnBeforeUpdateAttackPowerAndDamage(Player* player, float& level, float& val2, bool ranged);
@@ -1412,6 +1685,53 @@ public: /* PlayerScript */
void OnBeforeGuardianInitStatsForLevel(Player* player, Guardian* guardian, CreatureTemplate const* cinfo, PetType& petType); void OnBeforeGuardianInitStatsForLevel(Player* player, Guardian* guardian, CreatureTemplate const* cinfo, PetType& petType);
void OnAfterGuardianInitStatsForLevel(Player* player, Guardian* guardian); void OnAfterGuardianInitStatsForLevel(Player* player, Guardian* guardian);
void OnBeforeLoadPetFromDB(Player* player, uint32& petentry, uint32& petnumber, bool& current, bool& forceLoadFromDB); void OnBeforeLoadPetFromDB(Player* player, uint32& petentry, uint32& petnumber, bool& current, bool& forceLoadFromDB);
bool CanJoinInArenaQueue(Player* player, uint64 BattlemasterGuid, uint8 arenaslot, BattlegroundTypeId BGTypeID, uint8 joinAsGroup, uint8 IsRated, GroupJoinBattlegroundResult& err);
bool CanBattleFieldPort(Player* player, uint8 arenaType, BattlegroundTypeId BGTypeID, uint8 action);
bool CanGroupInvite(Player* player, std::string& membername);
bool CanGroupAccept(Player* player, Group* group);
bool CanSellItem(Player* player, Item* item, Creature* creature);
bool CanSendMail(Player* player, uint64 receiverGuid, uint64 mailbox, std::string& subject, std::string& body, uint32 money, uint32 COD, Item* item);
void PetitionBuy(Player* player, Creature* creature, uint32& charterid, uint32& cost, uint32& type);
void PetitionShowList(Player* player, Creature* creature, uint32& CharterEntry, uint32& CharterDispayID, uint32& CharterCost);
void OnRewardKillRewarder(Player* player, bool isDungeon, float& rate);
bool CanGiveMailRewardAtGiveLevel(Player* player, uint8 level);
void OnDeleteFromDB(SQLTransaction& trans, uint32 guid);
bool CanRepopAtGraveyard(Player* player);
void OnGetMaxSkillValue(Player* player, uint32 skill, int32& result, bool IsPure);
bool CanAreaExploreAndOutdoor(Player* player);
void OnVictimRewardBefore(Player* player, Player* victim, uint32& killer_title, uint32& victim_title);
void OnVictimRewardAfter(Player* player, Player* victim, uint32& killer_title, uint32& victim_rank, float& honor_f);
void OnCustomScalingStatValueBefore(Player* player, ItemTemplate const* proto, uint8 slot, bool apply, uint32& CustomScalingStatValue);
void OnCustomScalingStatValue(Player* player, ItemTemplate const* proto, uint32& statType, int32& val, uint8 itemProtoStatNumber, uint32 ScalingStatValue, ScalingStatValuesEntry const* ssv);
bool CanArmorDamageModifier(Player* player);
void OnGetFeralApBonus(Player* player, int32& feral_bonus, int32 dpsMod, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv);
bool CanApplyWeaponDependentAuraDamageMod(Player* player, Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply);
bool CanApplyEquipSpell(Player* player, SpellInfo const* spellInfo, Item* item, bool apply, bool form_change);
bool CanApplyEquipSpellsItemSet(Player* player, ItemSetEffect* eff);
bool CanCastItemCombatSpell(Player* player, Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto);
bool CanCastItemUseSpell(Player* player, Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex);
void OnApplyAmmoBonuses(Player* player, ItemTemplate const* proto, float& currentAmmoDPS);
bool CanEquipItem(Player* player, uint8 slot, uint16& dest, Item* pItem, bool swap, bool not_loading);
bool CanUnequipItem(Player* player, uint16 pos, bool swap);
bool CanUseItem(Player* player, ItemTemplate const* proto, InventoryResult& result);
bool CanSaveEquipNewItem(Player* player, Item* item, uint16 pos, bool update);
bool CanApplyEnchantment(Player* player, Item* item, EnchantmentSlot slot, bool apply, bool apply_dur, bool ignore_condition);
void OnGetQuestRate(Player* player, float& result);
bool PassedQuestKilledMonsterCredit(Player* player, Quest const* qinfo, uint32 entry, uint32 real_entry, uint64 guid);
bool CheckItemInSlotAtLoadInventory(Player* player, Item* item, uint8 slot, uint8& err, uint16& dest);
bool NotAvoidSatisfy(Player* player, DungeonProgressionRequirements const* ar, uint32 target_map, bool report);
bool NotVisibleGloballyFor(Player* player, Player const* u);
void OnGetArenaPersonalRating(Player* player, uint8 slot, uint32& result);
void OnGetArenaTeamId(Player* player, uint8 slot, uint32& result);
void OnIsFFAPvP(Player* player, bool& result);
void OnIsPvP(Player* player, bool& result);
void OnGetMaxSkillValueForLevel(Player* player, uint16& result);
bool NotSetArenaTeamInfoField(Player* player, uint8 slot, ArenaTeamInfoType type, uint32 value);
bool CanJoinLfg(Player* player, uint8 roles, lfg::LfgDungeonSet& dungeons, const std::string& comment);
bool CanEnterMap(Player* player, MapEntry const* entry, InstanceTemplate const* instance, MapDifficulty const* mapDiff, bool loginCheck);
bool CanInitTrade(Player* player, Player* target);
void OnSetServerSideVisibility(Player* player, ServerSideVisibilityType& type, AccountTypes& sec);
void OnSetServerSideVisibilityDetect(Player* player, ServerSideVisibilityType& type, AccountTypes& sec);
public: /* AccountScript */ public: /* AccountScript */
void OnAccountLogin(uint32 accountId); void OnAccountLogin(uint32 accountId);
@@ -1435,6 +1755,7 @@ public: /* GuildScript */
bool isDestBank, uint8 destContainer, uint8 destSlotId); bool isDestBank, uint8 destContainer, uint8 destSlotId);
void OnGuildEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank); void OnGuildEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank);
void OnGuildBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId); void OnGuildBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId);
bool CanGuildSendBankList(Guild const* guild, WorldSession* session, uint8 tabId, bool sendAllSlots);
public: /* GroupScript */ public: /* GroupScript */
void OnGroupAddMember(Group* group, uint64 guid); void OnGroupAddMember(Group* group, uint64 guid);
@@ -1442,6 +1763,8 @@ public: /* GroupScript */
void OnGroupRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, const char* reason); void OnGroupRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, const char* reason);
void OnGroupChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid); void OnGroupChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid);
void OnGroupDisband(Group* group); void OnGroupDisband(Group* group);
bool CanGroupJoinBattlegroundQueue(Group const* group, Player* member, Battleground const* bgTemplate, uint32 MinPlayerCount, bool isRated, uint32 arenaSlot);
void OnCreate(Group* group, Player* leader);
public: /* GlobalScript */ public: /* GlobalScript */
void OnGlobalItemDelFromDB(SQLTransaction& trans, uint32 itemGuid); void OnGlobalItemDelFromDB(SQLTransaction& trans, uint32 itemGuid);
@@ -1450,7 +1773,7 @@ public: /* GlobalScript */
void OnAfterRefCount(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, uint32& maxcount, LootStore const& store); void OnAfterRefCount(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, uint32& maxcount, LootStore const& store);
void OnBeforeDropAddItem(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store); void OnBeforeDropAddItem(Player const* player, Loot& loot, bool canRate, uint16 lootMode, LootStoreItem* LootStoreItem, LootStore const& store);
void OnItemRoll(Player const* player, LootStoreItem const* LootStoreItem, float& chance, Loot& loot, LootStore const& store); void OnItemRoll(Player const* player, LootStoreItem const* LootStoreItem, float& chance, Loot& loot, LootStore const& store);
void OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData); void OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData, lfg::LFGDungeonData const* dungeon);
void OnAfterInitializeLockedDungeons(Player* player); void OnAfterInitializeLockedDungeons(Player* player);
void OnAfterUpdateEncounterState(Map* map, EncounterCreditType type, uint32 creditEntry, Unit* source, Difficulty difficulty_fixed, DungeonEncounterList const* encounters, uint32 dungeonCompleted, bool updated); void OnAfterUpdateEncounterState(Map* map, EncounterCreditType type, uint32 creditEntry, Unit* source, Difficulty difficulty_fixed, DungeonEncounterList const* encounters, uint32 dungeonCompleted, bool updated);
void OnBeforeWorldObjectSetPhaseMask(WorldObject const* worldObject, uint32& oldPhaseMask, uint32& newPhaseMask, bool& useCombinedPhases, bool& update); void OnBeforeWorldObjectSetPhaseMask(WorldObject const* worldObject, uint32& oldPhaseMask, uint32& newPhaseMask, bool& useCombinedPhases, bool& update);
@@ -1470,6 +1793,13 @@ public: /* UnitScript */
void ModifyHealRecieved(Unit* target, Unit* attacker, uint32& addHealth); void ModifyHealRecieved(Unit* target, Unit* attacker, uint32& addHealth);
uint32 DealDamage(Unit* AttackerUnit, Unit* pVictim, uint32 damage, DamageEffectType damagetype); uint32 DealDamage(Unit* AttackerUnit, Unit* pVictim, uint32 damage, DamageEffectType damagetype);
void OnBeforeRollMeleeOutcomeAgainst(const Unit* attacker, const Unit* victim, WeaponAttackType attType, int32& attackerMaxSkillValueForLevel, int32& victimMaxSkillValueForLevel, int32& attackerWeaponSkill, int32& victimDefenseSkill, int32& crit_chance, int32& miss_chance, int32& dodge_chance, int32& parry_chance, int32& block_chance); void OnBeforeRollMeleeOutcomeAgainst(const Unit* attacker, const Unit* victim, WeaponAttackType attType, int32& attackerMaxSkillValueForLevel, int32& victimMaxSkillValueForLevel, int32& attackerWeaponSkill, int32& victimDefenseSkill, int32& crit_chance, int32& miss_chance, int32& dodge_chance, int32& parry_chance, int32& block_chance);
void OnAuraRemove(Unit* unit, AuraApplication* aurApp, AuraRemoveMode mode);
bool IfNormalReaction(Unit const* unit, Unit const* target, ReputationRank& repRank);
bool IsNeedModSpellDamagePercent(Unit const* unit, AuraEffect* auraEff, float& doneTotalMod, SpellInfo const* spellProto);
bool IsNeedModMeleeDamagePercent(Unit const* unit, AuraEffect* auraEff, float& doneTotalMod, SpellInfo const* spellProto);
bool IsNeedModHealPercent(Unit const* unit, AuraEffect* auraEff, float& doneTotalMod, SpellInfo const* spellProto);
bool CanSetPhaseMask(Unit const* unit, uint32 newPhaseMask, bool update);
bool IsCustomBuildValuesUpdate(Unit const* unit, uint8 updateType, ByteBuffer& fieldBuffer, Player const* target, uint16 index);
public: /* MovementHandlerScript */ public: /* MovementHandlerScript */
void OnPlayerMove(Player* player, MovementInfo movementInfo, uint32 opcode); void OnPlayerMove(Player* player, MovementInfo movementInfo, uint32 opcode);
@@ -1491,12 +1821,14 @@ public: /* BGScript */
void OnBattlegroundAddPlayer(Battleground* bg, Player* player); void OnBattlegroundAddPlayer(Battleground* bg, Player* player);
void OnBattlegroundBeforeAddPlayer(Battleground* bg, Player* player); void OnBattlegroundBeforeAddPlayer(Battleground* bg, Player* player);
void OnBattlegroundRemovePlayerAtLeave(Battleground* bg, Player* player); void OnBattlegroundRemovePlayerAtLeave(Battleground* bg, Player* player);
void OnQueueUpdate(BattlegroundQueue* queue, BattlegroundBracketId bracket_id, bool isRated, uint32 arenaRatedTeamId);
void OnAddGroup(BattlegroundQueue* queue, GroupQueueInfo* ginfo, uint32& index, Player* leader, Group* grp, PvPDifficultyEntry const* bracketEntry, bool isPremade); void OnAddGroup(BattlegroundQueue* queue, GroupQueueInfo* ginfo, uint32& index, Player* leader, Group* grp, PvPDifficultyEntry const* bracketEntry, bool isPremade);
bool CanFillPlayersToBG(BattlegroundQueue* queue, Battleground* bg, const int32 aliFree, const int32 hordeFree, BattlegroundBracketId bracket_id); bool CanFillPlayersToBG(BattlegroundQueue* queue, Battleground* bg, const int32 aliFree, const int32 hordeFree, BattlegroundBracketId bracket_id);
bool CanFillPlayersToBGWithSpecific(BattlegroundQueue* queue, Battleground* bg, const int32 aliFree, const int32 hordeFree, bool CanFillPlayersToBGWithSpecific(BattlegroundQueue* queue, Battleground* bg, const int32 aliFree, const int32 hordeFree,
BattlegroundBracketId thisBracketId, BattlegroundQueue* specificQueue, BattlegroundBracketId specificBracketId); BattlegroundBracketId thisBracketId, BattlegroundQueue* specificQueue, BattlegroundBracketId specificBracketId);
void OnCheckNormalMatch(BattlegroundQueue* queue, uint32& Coef, Battleground* bgTemplate, BattlegroundBracketId bracket_id, uint32& minPlayers, uint32& maxPlayers); void OnCheckNormalMatch(BattlegroundQueue* queue, uint32& Coef, Battleground* bgTemplate, BattlegroundBracketId bracket_id, uint32& minPlayers, uint32& maxPlayers);
bool CanSendMessageQueue(BattlegroundQueue* queue, Player* leader, Battleground* bg, PvPDifficultyEntry const* bracketEntry); bool CanSendMessageBGQueue(BattlegroundQueue* queue, Player* leader, Battleground* bg, PvPDifficultyEntry const* bracketEntry);
bool CanSendMessageArenaQueue(BattlegroundQueue* queue, GroupQueueInfo* ginfo, bool IsJoin);
public: /* Arena Team Script */ public: /* Arena Team Script */
void OnGetSlotByType(const uint32 type, uint8& slot); void OnGetSlotByType(const uint32 type, uint8& slot);
@@ -1507,6 +1839,15 @@ public: /* Arena Team Script */
public: /* SpellSC */ public: /* SpellSC */
void OnCalcMaxDuration(Aura const* aura, int32& maxDuration); void OnCalcMaxDuration(Aura const* aura, int32& maxDuration);
bool CanModAuraEffectDamageDone(AuraEffect const* auraEff, Unit* target, AuraApplication const* aurApp, uint8 mode, bool apply);
bool CanModAuraEffectModDamagePercentDone(AuraEffect const* auraEff, Unit* target, AuraApplication const* aurApp, uint8 mode, bool apply);
void OnSpellCheckCast(Spell* spell, bool strict, SpellCastResult& res);
bool CanPrepare(Spell* spell, SpellCastTargets const* targets, AuraEffect const* triggeredByAura);
bool CanScalingEverything(Spell* spell);
bool CanSelectSpecTalent(Spell* spell);
void OnScaleAuraUnitAdd(Spell* spell, Unit* target, uint32 effectMask, bool checkIfValid, bool implicit, uint8 auraScaleMask, TargetInfo& targetInfo);
void OnRemoveAuraScaleTargets(Spell* spell, TargetInfo& targetInfo, uint8 auraScaleMask, bool& needErase);
void OnBeforeAuraRankForLevel(SpellInfo const* spellInfo, SpellInfo const* latestSpellInfo, uint8 level);
public: /* GameEventScript */ public: /* GameEventScript */
void OnGameEventStart(uint16 EventID); void OnGameEventStart(uint16 EventID);
@@ -1515,6 +1856,52 @@ public: /* GameEventScript */
public: /* MailScript */ public: /* MailScript */
void OnBeforeMailDraftSendMailTo(MailDraft* mailDraft, MailReceiver const& receiver, MailSender const& sender, MailCheckMask& checked, uint32& deliver_delay, uint32& custom_expiration, bool& deleteMailItemsFromDB, bool& sendMail); void OnBeforeMailDraftSendMailTo(MailDraft* mailDraft, MailReceiver const& receiver, MailSender const& sender, MailCheckMask& checked, uint32& deliver_delay, uint32& custom_expiration, bool& deleteMailItemsFromDB, bool& sendMail);
public: /* AchievementScript */
void SetRealmCompleted(AchievementEntry const* achievement);
bool IsCompletedCriteria(AchievementMgr* mgr, AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement, CriteriaProgress const* progress);
bool IsRealmCompleted(AchievementGlobalMgr const* globalmgr, AchievementEntry const* achievement, std::chrono::system_clock::time_point completionTime);
void OnBeforeCheckCriteria(AchievementMgr* mgr, AchievementCriteriaEntryList const* achievementCriteriaList);
bool CanCheckCriteria(AchievementMgr* mgr, AchievementCriteriaEntry const* achievementCriteria);
public: /* PetScript */
void OnInitStatsForLevel(Guardian* guardian, uint8 petlevel);
void OnCalculateMaxTalentPointsForLevel(Pet* pet, uint8 level, uint8& points);
bool CanUnlearnSpellSet(Pet* pet, uint32 level, uint32 spell);
bool CanUnlearnSpellDefault(Pet* pet, SpellInfo const* spellEntry);
bool CanResetTalents(Pet* pet);
public: /* ArenaScript */
bool CanAddMember(ArenaTeam* team, uint64 PlayerGuid);
void OnGetPoints(ArenaTeam* team, uint32 memberRating, float& points);
bool CanSaveToDB(ArenaTeam* team);
public: /* MiscScript */
void OnConstructObject(Object* origin);
void OnDestructObject(Object* origin);
void OnConstructPlayer(Player* origin);
void OnDestructPlayer(Player* origin);
void OnConstructGroup(Group* origin);
void OnDestructGroup(Group* origin);
void OnConstructInstanceSave(InstanceSave* origin);
void OnDestructInstanceSave(InstanceSave* origin);
void OnItemCreate(Item* item, ItemTemplate const* itemProto, Player const* owner);
bool CanApplySoulboundFlag(Item* item, ItemTemplate const* proto);
bool CanItemApplyEquipSpell(Player* player, Item* item);
bool CanSendAuctionHello(WorldSession const* session, uint64 guid, Creature* creature);
void ValidateSpellAtCastSpell(Player* player, uint32& oldSpellId, uint32& spellId, uint8& castCount, uint8& castFlags);
void OnPlayerSetPhase(const AuraEffect* auraEff, AuraApplication const* aurApp, uint8 mode, bool apply, uint32& newPhase);
void ValidateSpellAtCastSpellResult(Player* player, Unit* mover, Spell* spell, uint32 oldSpellId, uint32 spellId);
void OnAfterLootTemplateProcess(Loot* loot, LootTemplate const* tab, LootStore const& store, Player* lootOwner, bool personal, bool noEmptyError, uint16 lootMode);
void OnInstanceSave(InstanceSave* instanceSave);
public: /* CommandSC */
void OnHandleDevCommand(Player* player, std::string& argstr);
private: private:
uint32 _scriptCount; uint32 _scriptCount;
@@ -4726,7 +4726,7 @@ void AuraEffect::HandleModDamageDone(AuraApplication const* aurApp, uint8 mode,
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
// GetMiscValue() comparison with item generated damage types // GetMiscValue() comparison with item generated damage types
if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0) if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0 && sScriptMgr->CanModAuraEffectDamageDone(this, target, aurApp, mode, apply))
{ {
// apply generic physical damage bonuses including wand case // apply generic physical damage bonuses including wand case
if (GetSpellInfo()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER) if (GetSpellInfo()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER)
@@ -4796,6 +4796,9 @@ void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8
if (!target) if (!target)
return; return;
if (!sScriptMgr->CanModAuraEffectModDamagePercentDone(this, target, aurApp, mode, apply))
return;
if (target->GetTypeId() == TYPEID_PLAYER) if (target->GetTypeId() == TYPEID_PLAYER)
{ {
for (int i = 0; i < MAX_ATTACK; ++i) for (int i = 0; i < MAX_ATTACK; ++i)
+31 -10
View File
@@ -836,19 +836,21 @@ void Spell::SelectSpellTargets()
else if (m_auraScaleMask) else if (m_auraScaleMask)
{ {
bool checkLvl = !m_UniqueTargetInfo.empty(); bool checkLvl = !m_UniqueTargetInfo.empty();
for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end();) for (std::list<TargetInfo>::iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
{ {
// remove targets which did not pass min level check // remove targets which did not pass min level check
if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask) if (m_auraScaleMask && itr->effectMask == m_auraScaleMask)
{ {
// Do not check for selfcast bool needErase = false;
if (!ihit->scaleAura && ihit->targetGUID != m_caster->GetGUID())
{ if (!itr->scaleAura && itr->targetGUID != m_caster->GetGUID())
m_UniqueTargetInfo.erase(ihit++); needErase = true;
continue;
} sScriptMgr->OnRemoveAuraScaleTargets(this, *itr, m_auraScaleMask, needErase);
if (needErase)
m_UniqueTargetInfo.erase(itr);
} }
++ihit;
} }
if (checkLvl && m_UniqueTargetInfo.empty()) if (checkLvl && m_UniqueTargetInfo.empty())
{ {
@@ -2154,6 +2156,8 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
if (uint32(target->getLevel() + 10) >= auraSpell->SpellLevel) if (uint32(target->getLevel() + 10) >= auraSpell->SpellLevel)
ihit->scaleAura = true; ihit->scaleAura = true;
} }
sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
return; return;
} }
} }
@@ -2176,6 +2180,8 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
targetInfo.scaleAura = true; targetInfo.scaleAura = true;
} }
sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
// Calculate hit result // Calculate hit result
if (m_originalCaster) if (m_originalCaster)
{ {
@@ -3163,8 +3169,14 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const
InitExplicitTargets(*targets); InitExplicitTargets(*targets);
if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
{
finish(false);
return SPELL_FAILED_UNKNOWN;
}
// Fill aura scaling information // Fill aura scaling information
if (m_caster->IsTotem() || (m_caster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_SCALING))) if (sScriptMgr->CanScalingEverything(this) || m_caster->IsTotem() || (m_caster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_SCALING)))
{ {
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{ {
@@ -5140,6 +5152,13 @@ SpellCastResult Spell::CheckCast(bool strict)
if (((const Player*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT) if (((const Player*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
return SPELL_FAILED_NOT_HERE; return SPELL_FAILED_NOT_HERE;
SpellCastResult res = SPELL_CAST_OK;
sScriptMgr->OnSpellCheckCast(this, strict, res);
if (res != SPELL_CAST_OK)
return res;
// check cooldowns to prevent cheating // check cooldowns to prevent cheating
if (!m_spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE)) if (!m_spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE))
{ {
@@ -5969,6 +5988,8 @@ SpellCastResult Spell::CheckCast(bool strict)
break; break;
} }
case SPELL_EFFECT_TALENT_SPEC_SELECT: case SPELL_EFFECT_TALENT_SPEC_SELECT:
if (!sScriptMgr->CanSelectSpecTalent(this))
return SPELL_FAILED_DONT_REPORT;
// can't change during already started arena/battleground // can't change during already started arena/battleground
if (m_caster->GetTypeId() == TYPEID_PLAYER) if (m_caster->GetTypeId() == TYPEID_PLAYER)
if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground()) if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
+20 -19
View File
@@ -234,6 +234,21 @@ struct ChannelTargetData
SpellDestination spellDst; SpellDestination spellDst;
}; };
// Targets store structures and data
struct TargetInfo
{
uint64 targetGUID;
uint64 timeDelay;
SpellMissInfo missCondition:8;
SpellMissInfo reflectResult:8;
uint8 effectMask:8;
bool processed:1;
bool alive:1;
bool crit:1;
bool scaleAura:1;
int32 damage;
};
static const uint32 SPELL_INTERRUPT_NONPLAYER = 32747; static const uint32 SPELL_INTERRUPT_NONPLAYER = 32747;
class Spell class Spell
@@ -241,6 +256,9 @@ class Spell
friend void Unit::SetCurrentCastedSpell(Spell* pSpell); friend void Unit::SetCurrentCastedSpell(Spell* pSpell);
friend class SpellScript; friend class SpellScript;
public: public:
Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, uint64 originalCasterGUID = 0, bool skipCheck = false);
~Spell();
void EffectNULL(SpellEffIndex effIndex); void EffectNULL(SpellEffIndex effIndex);
void EffectUnused(SpellEffIndex effIndex); void EffectUnused(SpellEffIndex effIndex);
void EffectDistract(SpellEffIndex effIndex); void EffectDistract(SpellEffIndex effIndex);
@@ -369,9 +387,6 @@ public:
typedef std::set<Aura*> UsedSpellMods; typedef std::set<Aura*> UsedSpellMods;
Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, uint64 originalCasterGUID = 0, bool skipCheck = false);
~Spell();
void InitExplicitTargets(SpellCastTargets const& targets); void InitExplicitTargets(SpellCastTargets const& targets);
void SelectExplicitTargets(); void SelectExplicitTargets();
@@ -473,7 +488,7 @@ public:
void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode); void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode);
void HandleThreatSpells(); void HandleThreatSpells();
SpellInfo const* const m_spellInfo; SpellInfo const* m_spellInfo;
Item* m_CastItem; Item* m_CastItem;
uint64 m_castItemGUID; uint64 m_castItemGUID;
uint8 m_cast_count; uint8 m_cast_count;
@@ -511,6 +526,7 @@ public:
Unit* GetCaster() const { return m_caster; } Unit* GetCaster() const { return m_caster; }
Unit* GetOriginalCaster() const { return m_originalCaster; } Unit* GetOriginalCaster() const { return m_originalCaster; }
SpellInfo const* GetSpellInfo() const { return m_spellInfo; } SpellInfo const* GetSpellInfo() const { return m_spellInfo; }
void SetSpellInfo(SpellInfo const* info) { m_spellInfo = info; }
int32 GetPowerCost() const { return m_powerCost; } int32 GetPowerCost() const { return m_powerCost; }
bool UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc) bool UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc)
@@ -522,21 +538,6 @@ public:
// xinef: moved to public // xinef: moved to public
void LoadScripts(); void LoadScripts();
// Targets store structures and data
struct TargetInfo
{
uint64 targetGUID;
uint64 timeDelay;
SpellMissInfo missCondition: 8;
SpellMissInfo reflectResult: 8;
uint8 effectMask: 8;
bool processed: 1;
bool alive: 1;
bool crit: 1;
bool scaleAura: 1;
int32 damage;
};
std::list<TargetInfo>* GetUniqueTargetInfo() { return &m_UniqueTargetInfo; } std::list<TargetInfo>* GetUniqueTargetInfo() { return &m_UniqueTargetInfo; }
protected: protected:
bool HasGlobalCooldown() const; bool HasGlobalCooldown() const;
+9 -1
View File
@@ -9,6 +9,7 @@
#include "ConditionMgr.h" #include "ConditionMgr.h"
#include "DBCStores.h" #include "DBCStores.h"
#include "Player.h" #include "Player.h"
#include "ScriptMgr.h"
#include "Spell.h" #include "Spell.h"
#include "SpellAuraDefines.h" #include "SpellAuraDefines.h"
#include "SpellAuraEffects.h" #include "SpellAuraEffects.h"
@@ -2487,7 +2488,14 @@ SpellInfo const* SpellInfo::GetAuraRankForLevel(uint8 level) const
if (!needRankSelection) if (!needRankSelection)
return this; return this;
for (SpellInfo const* nextSpellInfo = this; nextSpellInfo != nullptr; nextSpellInfo = nextSpellInfo->GetPrevRankSpell()) SpellInfo const* nextSpellInfo = nullptr;
sScriptMgr->OnBeforeAuraRankForLevel(this, nextSpellInfo, level);
if (nextSpellInfo != nullptr)
return nextSpellInfo;
for (nextSpellInfo = this; nextSpellInfo != nullptr; nextSpellInfo = nextSpellInfo->GetPrevRankSpell())
{ {
// if found appropriate level // if found appropriate level
if (uint32(level + 10) >= nextSpellInfo->SpellLevel) if (uint32(level + 10) >= nextSpellInfo->SpellLevel)
+2
View File
@@ -347,12 +347,14 @@ public:
{ {
player->SetDeveloper(true); player->SetDeveloper(true);
handler->GetSession()->SendNotification(LANG_DEV_ON); handler->GetSession()->SendNotification(LANG_DEV_ON);
sScriptMgr->OnHandleDevCommand(handler->GetSession()->GetPlayer(), enablestr);
return true; return true;
} }
else if (enablestr == "off") else if (enablestr == "off")
{ {
player->SetDeveloper(false); player->SetDeveloper(false);
handler->GetSession()->SendNotification(LANG_DEV_OFF); handler->GetSession()->SendNotification(LANG_DEV_OFF);
sScriptMgr->OnHandleDevCommand(handler->GetSession()->GetPlayer(), enablestr);
return true; return true;
} }
@@ -265,8 +265,8 @@ public:
void SetDest(SpellDestination& dest) void SetDest(SpellDestination& dest)
{ {
std::list<Spell::TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo(); std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit) for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (Unit* target = ObjectAccessor::GetUnit(*GetCaster(), ihit->targetGUID)) if (Unit* target = ObjectAccessor::GetUnit(*GetCaster(), ihit->targetGUID))
{ {
dest.Relocate(*target); dest.Relocate(*target);
@@ -613,8 +613,8 @@ public:
} }
float pct = (_sharedHealth / _sharedHealthMax) * 100.0f; float pct = (_sharedHealth / _sharedHealthMax) * 100.0f;
std::list<Spell::TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo(); std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit) for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (Creature* target = ObjectAccessor::GetCreature(*GetCaster(), ihit->targetGUID)) if (Creature* target = ObjectAccessor::GetCreature(*GetCaster(), ihit->targetGUID))
{ {
target->LowerPlayerDamageReq(target->GetMaxHealth()); target->LowerPlayerDamageReq(target->GetMaxHealth());
+2 -2
View File
@@ -606,8 +606,8 @@ public:
{ {
if (GetHitUnit() != GetCaster()) if (GetHitUnit() != GetCaster())
{ {
std::list<Spell::TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo(); std::list<TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit) for (std::list<TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (ihit->targetGUID == GetCaster()->GetGUID()) if (ihit->targetGUID == GetCaster()->GetGUID())
ihit->damage = -int32(GetHitDamage() * 0.25f); ihit->damage = -int32(GetHitDamage() * 0.25f);
} }
+4 -4
View File
@@ -430,8 +430,8 @@ public:
{ {
if (Unit* target = GetExplTargetUnit()) if (Unit* target = GetExplTargetUnit())
{ {
std::list<Spell::TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo(); std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit) for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (ihit->missCondition == SPELL_MISS_NONE && ihit->targetGUID == target->GetGUID()) if (ihit->missCondition == SPELL_MISS_NONE && ihit->targetGUID == target->GetGUID())
GetCaster()->CastSpell(target, 55095 /*SPELL_FROST_FEVER*/, true); GetCaster()->CastSpell(target, 55095 /*SPELL_FROST_FEVER*/, true);
} }
@@ -610,8 +610,8 @@ public:
void RecalculateDamage() void RecalculateDamage()
{ {
std::list<Spell::TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo(); std::list<TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit) for (std::list<TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (ihit->targetGUID == GetCaster()->GetGUID()) if (ihit->targetGUID == GetCaster()->GetGUID())
ihit->crit = roll_chance_f(GetCaster()->GetFloatValue(PLAYER_CRIT_PERCENTAGE)); ihit->crit = roll_chance_f(GetCaster()->GetFloatValue(PLAYER_CRIT_PERCENTAGE));
} }