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
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 2053 additions and 278 deletions

View file

@ -5,6 +5,22 @@ MACRO(AC_ADD_SCRIPT path)
CU_ADD_GLOBAL("AC_SCRIPTS_SOURCES" "${path}")
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
#

View file

@ -828,6 +828,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!achievementCriteriaList)
return;
sScriptMgr->OnBeforeCheckCriteria(this, achievementCriteriaList);
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList->begin(); i != achievementCriteriaList->end(); ++i)
{
AchievementCriteriaEntry const* achievementCriteria = (*i);
@ -838,6 +840,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!CanUpdateCriteria(achievementCriteria, achievement))
continue;
if (!sScriptMgr->CanCheckCriteria(this, achievementCriteria))
continue;
switch (type)
{
// std. case: increment at 1
@ -1762,6 +1767,9 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
if (!progress)
return false;
if (!sScriptMgr->IsCompletedCriteria(this, achievementCriteria, achievement, progress))
return false;
switch (achievementCriteria->requiredType)
{
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())
return false;
if (!sScriptMgr->IsRealmCompleted(this, achievement, itr->second))
return false;
if (itr->second == std::chrono::system_clock::time_point::max())
return true;
@ -2403,6 +2414,8 @@ bool AchievementGlobalMgr::IsRealmCompleted(AchievementEntry const* achievement)
if (achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)
return (std::chrono::system_clock::now() - itr->second) > std::chrono::minutes(1);
sScriptMgr->SetRealmCompleted(achievement);
return true;
}

View file

@ -101,6 +101,9 @@ bool ArenaTeam::AddMember(uint64 playerGuid)
playerClass = playerData->playerClass;
}
if (!sScriptMgr->CanAddMember(this, playerGuid))
return false;
// Check if player is already in a similar arena team
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 slot = 0xFF;
switch (type)
auto const& itr = ArenaSlotByType.find(type);
if (itr == ArenaSlotByType.end())
{
case ARENA_TEAM_2v2:
slot = 0;
break;
case ARENA_TEAM_3v3:
slot = 1;
break;
case ARENA_TEAM_5v5:
slot = 2;
break;
default:
break;
sLog->outError("FATAL: Unknown arena team type %u for some arena team", type);
return slot;
}
//Get the changed slot type
slot = ArenaSlotByType.at(type);
// Get the changed slot type
sScriptMgr->OnGetSlotByType(type, slot);
if (slot != 0xFF)
{
return slot;
}
sLog->outError("FATAL: Unknown arena team type %u for some arena team", type);
return 0xFF;
}
@ -868,12 +868,14 @@ void ArenaTeam::MemberWon(Player* player, uint32 againstMatchmakerRating, int32
{
// update personal rating
int32 mod = GetRatingMod(itr->PersonalRating, againstMatchmakerRating, true);
sScriptMgr->OnBeforeUpdatingPersonalRating(mod, GetType());
itr->ModifyPersonalRating(player, mod, GetType());
// update matchmaker rating (pussywizard: but don't allow it to go over team rating)
if (itr->MatchMakerRating < Stats.Rating)
{
mod = std::min(MatchmakerRatingChange, Stats.Rating - itr->MatchMakerRating);
sScriptMgr->OnBeforeUpdatingPersonalRating(mod, GetType());
itr->ModifyMatchmakerRating(mod, GetSlot());
}
@ -922,6 +924,9 @@ void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& playerPoints)
void ArenaTeam::SaveToDB()
{
if (!sScriptMgr->CanSaveToDB(this))
return;
// Save team and member stats to db
// Called after a match has ended or when calculating arena_points
@ -997,3 +1002,83 @@ ArenaTeamMember* ArenaTeam::GetMember(uint64 guid)
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}
};

View file

@ -58,6 +58,19 @@ enum ArenaTeamEvents
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:
ERR_ARENA_TEAM_YOU_JOIN_S - client show it automatically when accept invite
@ -73,6 +86,13 @@ enum ArenaTeamTypes
ARENA_TEAM_5v5 = 5
};
enum ArenaSlot
{
ARENA_SLOT_2v2,
ARENA_SLOT_3v3,
ARENA_SLOT_5v5
};
struct ArenaTeamMember
{
uint64 Guid;
@ -118,9 +138,11 @@ public:
[[nodiscard]] uint32 GetType() const { return Type; }
[[nodiscard]] uint8 GetSlot() const { return GetSlotByType(GetType()); }
static uint8 GetSlotByType(uint32 type);
static uint8 GetReqPlayersForType(uint32 type);
[[nodiscard]] uint64 GetCaptain() const { return CaptainGuid; }
[[nodiscard]] std::string const& GetName() const { return TeamName; }
[[nodiscard]] const ArenaTeamStats& GetStats() const { return Stats; }
void SetArenaTeamStats(ArenaTeamStats& stats) { Stats = stats; }
[[nodiscard]] uint32 GetRating() const { return Stats.Rating; }
uint32 GetAverageMMR(Group* group) const;
@ -137,6 +159,7 @@ public:
[[nodiscard]] bool Empty() const { return Members.empty(); }
MemberList::iterator m_membersBegin() { return Members.begin(); }
MemberList::iterator m_membersEnd() { return Members.end(); }
MemberList& GetMembers() { return Members; }
[[nodiscard]] bool IsMember(uint64 guid) const;
ArenaTeamMember* GetMember(uint64 guid);
@ -174,6 +197,12 @@ public:
void FinishWeek();
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:
uint32 TeamId;
uint8 Type;

View file

@ -14,10 +14,14 @@
#include "ScriptMgr.h"
#include "World.h"
constexpr uint32 MAX_ARENA_TEAM_ID = 0xFFF00000;
constexpr uint32 MAX_TEMP_ARENA_TEAM_ID = 0xFFFFFFFE;
ArenaTeamMgr::ArenaTeamMgr()
{
NextArenaTeamId = 1;
LastArenaLogId = 0;
NextTempArenaTeamId = 0xFFF00000;
}
ArenaTeamMgr::~ArenaTeamMgr()
@ -114,14 +118,23 @@ void ArenaTeamMgr::RemoveArenaTeam(uint32 arenaTeamId)
uint32 ArenaTeamMgr::GenerateArenaTeamId()
{
if (NextArenaTeamId >= 0xFFFFFFFE)
if (NextArenaTeamId >= MAX_ARENA_TEAM_ID)
{
sLog->outError("Arena team ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return NextArenaTeamId++;
}
uint32 ArenaTeamMgr::GenerateTempArenaTeamId()
{
if (NextTempArenaTeamId >= MAX_TEMP_ARENA_TEAM_ID)
NextTempArenaTeamId = MAX_ARENA_TEAM_ID;
return NextTempArenaTeamId++;
}
void ArenaTeamMgr::LoadArenaTeams()
{
uint32 oldMSTime = getMSTime();

View file

@ -31,6 +31,7 @@ public:
ArenaTeamContainer::iterator GetArenaTeamMapBegin() { return ArenaTeamStore.begin(); }
ArenaTeamContainer::iterator GetArenaTeamMapEnd() { return ArenaTeamStore.end(); }
ArenaTeamContainer& GetArenaTeams() { return ArenaTeamStore; }
void DistributeArenaPoints();
@ -40,8 +41,11 @@ public:
uint32 GetNextArenaLogId() { return ++LastArenaLogId; }
void SetLastArenaLogId(uint32 id) { LastArenaLogId = id; }
uint32 GenerateTempArenaTeamId();
protected:
uint32 NextArenaTeamId;
uint32 NextTempArenaTeamId;
ArenaTeamContainer ArenaTeamStore;
uint32 LastArenaLogId;
};

View file

@ -1382,7 +1382,7 @@ void Battleground::ReadyMarkerClicked(Player* p)
return;
readyMarkerClickedSet.insert(p->GetGUIDLow());
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);
if (count == req)
{

View file

@ -468,19 +468,7 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
// Set up correct min/max player counts for scoreboards
if (bg->isArena())
{
uint32 maxPlayersPerTeam = 0;
switch (arenaType)
{
case ARENA_TYPE_2v2:
maxPlayersPerTeam = 2;
break;
case ARENA_TYPE_3v3:
maxPlayersPerTeam = 3;
break;
case ARENA_TYPE_5v5:
maxPlayersPerTeam = 5;
break;
}
uint32 maxPlayersPerTeam = ArenaTeam::GetReqPlayersForType(arenaType) / 2;
sScriptMgr->OnSetArenaMaxPlayersPerTeam(arenaType, maxPlayersPerTeam);
bg->SetMaxPlayersPerTeam(maxPlayersPerTeam);
}
@ -748,31 +736,24 @@ bool BattlegroundMgr::IsArenaType(BattlegroundTypeId bgTypeId)
BattlegroundQueueTypeId BattlegroundMgr::BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
{
if (arenaType) {
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);
}
uint32 queueTypeID = BATTLEGROUND_QUEUE_NONE;
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)
@ -788,21 +769,14 @@ BattlegroundTypeId BattlegroundMgr::BGTemplateId(BattlegroundQueueTypeId bgQueue
uint8 BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId bgQueueTypeId)
{
uint8 arenaType = 0;
switch (bgQueueTypeId)
if (BattlegroundMgr::QueueToArenaType.find(bgQueueTypeId) != BattlegroundMgr::QueueToArenaType.end())
{
case BATTLEGROUND_QUEUE_2v2:
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;
arenaType = BattlegroundMgr::QueueToArenaType.at(bgQueueTypeId);
}
sScriptMgr->OnArenaQueueIdToArenaType(bgQueueTypeId, 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 }
};

View file

@ -127,6 +127,8 @@ public:
static std::unordered_map<int, bgRef> bgTypeToTemplate; // BattlegroundTypeId -> bgRef
static std::unordered_map<int, bgMapRef> getBgFromMap; // BattlegroundMapID -> bgMapRef
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:
bool CreateBattleground(CreateBattlegroundData& data);

View file

@ -152,9 +152,7 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, PvPDiffi
ginfo->_groupType = index;
// announce world (this doesn't need mutex)
if (isRated && sWorld->getBoolConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE))
if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(arenateamid))
sWorld->SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, team->GetName().c_str(), ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating);
SendMessageArenaQueue(ginfo, true);
//add players from group to ginfo
if (grp)
@ -185,7 +183,7 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, PvPDiffi
return ginfo;
if (!isRated && !isPremade && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
SendMessageQueue(leader, bg, bracketEntry);
SendMessageBGQueue(leader, bg, bracketEntry);
return ginfo;
}
@ -298,9 +296,7 @@ void BattlegroundQueue::RemovePlayer(uint64 guid, bool sentToBg, uint32 playerQu
m_QueuedPlayers.erase(itr);
// 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))
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);
SendMessageArenaQueue(groupInfo, false);
// 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)
@ -726,6 +722,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(BattlegroundBracketId bracket_id
MaxPlayersPerTeam = m_arenaType;
}
sScriptMgr->OnQueueUpdate(this, bracket_id, isRated, arenaRatedTeamId);
// check if can start new premade battleground
if (bg_template->isBattleground() && m_bgTypeId != BATTLEGROUND_RB)
if (CheckPremadeMatch(bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam))
@ -963,9 +961,9 @@ bool BattlegroundQueue::IsAllQueuesEmpty(BattlegroundBracketId bracket_id)
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;
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 ***/
/*********************************************************/

View file

@ -71,7 +71,8 @@ public:
uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo) const;
uint32 GetPlayersCountInGroupsQueue(BattlegroundBracketId bracketId, BattlegroundQueueGroupTypes bgqueue);
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 AddEvent(BasicEvent* Event, uint64 e_time);
@ -110,6 +111,9 @@ public:
//one selection pool for horde, other one for alliance
SelectionPool m_SelectionPools[BG_TEAMS_COUNT];
ArenaType GetArenaType() { return m_arenaType; }
BattlegroundTypeId GetBGTypeID() { return m_bgTypeId; }
private:
BattlegroundTypeId m_bgTypeId;
ArenaType m_arenaType;

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)
lockData = LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE;
@ -500,6 +500,9 @@ namespace lfg
if (grp && (grp->isBGGroup() || grp->isBFGroup()))
return;
if (!sScriptMgr->CanJoinLfg(player, roles, dungeons, comment))
return;
// pussywizard: can't join LFG/LFR while using LFR
if (GetState(player->GetGUID()) == LFG_STATE_RAIDBROWSER)
{

View file

@ -11,6 +11,8 @@
#include "QuestDef.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Formulas.h"
#include "Player.h"
GossipMenu::GossipMenu()
{
@ -420,7 +422,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID,
}
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
@ -650,7 +652,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, b
}
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
data << uint32(10 * quest->CalculateHonorGain(_session->GetPlayer()->GetQuestLevel(quest)));

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
player->ApplyEquipSpell(spellInfo, nullptr, true);
if (sScriptMgr->CanItemApplyEquipSpell(player, item))
{
player->ApplyEquipSpell(spellInfo, nullptr, true);
}
eff->spells[y] = spellInfo;
break;
}
@ -266,6 +270,7 @@ bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner)
SetUInt32Value(ITEM_FIELD_DURATION, itemProto->Duration);
SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, 0);
sScriptMgr->OnItemCreate(this, itemProto, owner);
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());
// 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);
need_save = true;

View file

@ -87,6 +87,8 @@ Object::Object() : m_PackGUID(sizeof(uint64) + 1)
m_objectUpdated = false;
m_PackGUID.appendPackGUID(0);
sScriptMgr->OnConstructObject(this);
}
WorldObject::~WorldObject()
@ -110,6 +112,8 @@ WorldObject::~WorldObject()
Object::~Object()
{
sScriptMgr->OnDestructObject(this);
if (IsInWorld())
{
sLog->outCrash("Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in world!!", GetGUID(), GetTypeId(), GetEntry());

View file

@ -15,6 +15,7 @@
#include "Log.h"
#include "ObjectMgr.h"
#include "Pet.h"
#include "ScriptMgr.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
#include "SpellMgr.h"
@ -1073,6 +1074,8 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
}
}
sScriptMgr->OnInitStatsForLevel(this, petlevel);
UpdateAllStats();
SetFullHealth();
@ -1585,7 +1588,7 @@ void Pet::InitLevelupSpellsForLevel()
for (PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr)
{
// 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
// will called if level up
else
@ -1605,7 +1608,7 @@ void Pet::InitLevelupSpellsForLevel()
continue;
// will called first if level down
if (spellEntry->SpellLevel > level)
if (spellEntry->SpellLevel > level && sScriptMgr->CanUnlearnSpellDefault(this, spellEntry))
unlearnSpell(spellEntry->Id, true);
// will called if level up
else
@ -1710,6 +1713,9 @@ bool Pet::resetTalents()
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
return false;
if (!sScriptMgr->CanResetTalents(this))
return false;
// not need after this call
if (owner->ToPlayer()->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS))
owner->ToPlayer()->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS, true);
@ -1863,16 +1869,17 @@ void Pet::InitTalentForLevel()
{
uint8 level = getLevel();
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)
if (talentPointsForLevel == 0 || m_usedTalentCount > talentPointsForLevel)
resetTalents(); // Remove all talent points
SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount);
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
return;
if (!m_loading)
owner->ToPlayer()->SendTalentsInfoData(true);
}
@ -1883,6 +1890,9 @@ uint8 Pet::GetMaxTalentPointsForLevel(uint8 level)
// Mod points from owner SPELL_AURA_MOD_PET_TALENT_POINTS
if (Unit* owner = GetOwner())
points += owner->GetTotalAuraModifier(SPELL_AURA_MOD_PET_TALENT_POINTS);
sScriptMgr->OnCalculateMaxTalentPointsForLevel(this, level, points);
return points;
}

View file

@ -611,9 +611,9 @@ void KillRewarder::_RewardPlayer(Player* player, bool isDungeon)
// Give reputation and kill credit only in PvE.
if (!_isPvP || _isBattleGround)
{
const float rate = _group ?
_groupRate * float(player->getLevel()) / _sumLevel : // Group rate depends on summary level.
1.0f; // Personal rate is 100%.
float rate = _group ? _groupRate * float(player->getLevel()) / _sumLevel : /*Personal rate is 100%.*/ 1.0f; // Group rate depends on summary level.
sScriptMgr->OnRewardKillRewarder(player, isDungeon, rate); // Personal rate is 100%.
if (_xp)
// 4.2. Give XP.
_RewardXP(player, rate);
@ -976,10 +976,14 @@ Player::Player(WorldSession* session): Unit(true), m_mover(this)
m_applyResilience = true;
m_isInstantFlightOn = true;
sScriptMgr->OnConstructPlayer(this);
}
Player::~Player()
{
sScriptMgr->OnDestructPlayer(this);
// it must be unloaded already in PlayerLogout and accessed only for loggined player
//m_social = nullptr;
@ -3389,7 +3393,8 @@ void Player::GiveLevel(uint8 level)
if (Pet* pet = GetPet())
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
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@ -5144,6 +5149,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
stmt->setUInt32(0, guid);
trans->Append(stmt);
sScriptMgr->OnDeleteFromDB(trans, guid);
CharacterDatabase.CommitTransaction(trans);
break;
}
@ -5713,6 +5720,9 @@ void Player::RepopAtGraveyard()
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
// Xinef: Get Transport Check is not needed
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));
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_PERM_BONUS(bonus);
return result < 0 ? 0 : result;
@ -6817,7 +6828,11 @@ uint16 Player::GetPureMaxSkillValue(uint32 skill) const
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
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
@ -7075,6 +7090,9 @@ void Player::CheckAreaExploreAndOutdoor()
if (sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK) && !isOutdoor)
RemoveAurasWithAttribute(SPELL_ATTR0_OUTDOORS_ONLY);
if (!sScriptMgr->CanAreaExploreAndOutdoor(this))
return;
if (!areaId)
return;
@ -7466,6 +7484,8 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool awar
// [29..38] Other title and player name
// [39+] Nothing
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
// Ranks:
// 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, 1, 0, victim);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim);
sScriptMgr->OnVictimRewardAfter(this, victim, killer_title, victim_rank, honor_f);
}
else
{
@ -7646,14 +7667,6 @@ uint32 Player::GetArenaTeamIdFromStorage(uint32 guid, uint8 slot)
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)
{
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
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)
ssd_level = ssd->MaxLevel;
@ -8093,17 +8112,30 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
uint32 statType = 0;
int32 val = 0;
// If set ScalingStatDistribution need get stats and values from it
if (ssd && ssv)
if (ssv)
{
if (ssd->StatMod[i] < 0)
continue;
statType = ssd->StatMod[i];
val = (ssv->getssdMultiplier(proto->ScalingStatValue) * ssd->Modifier[i]) / 10000;
if (ssd)
{
if (ssd->StatMod[i] < 0)
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
{
if (i >= proto->StatsCount)
continue;
statType = proto->ItemStat[i].ItemStatType;
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
if (ssv)
if (int32 spellbonus = ssv->getSpellBonus(proto->ScalingStatValue))
if (int32 spellbonus = ssv->getSpellBonus(ScalingStatValue))
ApplySpellPowerBonus(spellbonus, apply);
// If set ScalingStatValue armor get it or use item armor
uint32 armor = proto->Armor;
if (ssv)
{
if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue))
armor = ssvarmor;
if (uint32 ssvarmor = ssv->getArmorMod(ScalingStatValue))
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)
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
if (proto->ArmorDamageModifier > 0)
if (proto->ArmorDamageModifier > 0 && sScriptMgr->CanArmorDamageModifier(this))
HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(proto->ArmorDamageModifier), apply);
if (proto->Block)
@ -8342,11 +8375,12 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
int32 feral_bonus = 0;
if (ssv)
{
dpsMod = ssv->getDPSMod(proto->ScalingStatValue);
feral_bonus += ssv->getFeralBonus(proto->ScalingStatValue);
dpsMod = ssv->getDPSMod(ScalingStatValue);
feral_bonus += ssv->getFeralBonus(ScalingStatValue);
}
feral_bonus += proto->getFeralBonus(dpsMod);
sScriptMgr->OnGetFeralApBonus(this, feral_bonus, dpsMod, proto, ssv);
if (feral_bonus)
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)
{
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;
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 (ssv)
{
int32 extraDPS = ssv->getDPSMod(proto->ScalingStatValue);
int32 extraDPS = ssv->getDPSMod(ScalingStatValue);
if (extraDPS)
{
float average = extraDPS * proto->Delay / 1000.0f;
@ -8438,6 +8493,9 @@ void Player::_ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attac
if (aura->GetSpellInfo()->EquippedItemClass == -1)
return;
if (!sScriptMgr->CanApplyWeaponDependentAuraDamageMod(this, item, attackType, aura, apply))
return;
BaseModGroup mod = BASEMOD_END;
switch (attackType)
{
@ -8548,6 +8606,9 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply,
{
if (apply)
{
if (!sScriptMgr->CanApplyEquipSpell(this, spellInfo, item, apply, form_change))
return;
// Cannot be used in this stance/form
if (spellInfo->CheckShapeshift(GetShapeshiftForm()) != SPELL_CAST_OK)
return;
@ -8619,6 +8680,8 @@ void Player::UpdateEquipSpellsAtFormChange()
continue;
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
}
}
@ -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)
{
if (!sScriptMgr->CanCastItemCombatSpell(this, target, attType, procVictim, procEx, item, proto))
return;
// Can do effect if any damage done to target
if (procVictim & PROC_FLAG_TAKEN_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)
{
if (!sScriptMgr->CanCastItemUseSpell(this, item, targets, cast_count, glyphIndex))
return;
ItemTemplate const* proto = item->GetTemplate();
// special learning case
if (proto->Spells[0].SpellId == 483 || proto->Spells[0].SpellId == 55884)
@ -9056,6 +9125,8 @@ void Player::_ApplyAmmoBonuses()
else
currentAmmoDPS = (ammo_proto->Damage[0].DamageMin + ammo_proto->Damage[0].DamageMax) / 2;
sScriptMgr->OnApplyAmmoBonuses(this, ammo_proto, currentAmmoDPS);
if (currentAmmoDPS == GetAmmoDPS())
return;
@ -12047,6 +12118,9 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool
ItemTemplate const* pProto = pItem->GetTemplate();
if (pProto)
{
if (!sScriptMgr->CanEquipItem(const_cast<Player*>(this), slot, dest, pItem, swap, not_loading))
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
// item used
if (pItem->m_lootGenerated)
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
{
if (!sScriptMgr->CanUnequipItem(const_cast<Player*>(this), pos, swap))
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
// Applied only to equipped items and bank bags
if (!IsEquipmentPos(pos) && !IsBagPos(pos))
return EQUIP_ERR_OK;
@ -12529,6 +12606,11 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
if (proto->RequiredSpell != 0 && !HasSpell(proto->RequiredSpell))
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)
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)
{
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
if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item))
@ -12881,10 +12967,9 @@ Item* Player::EquipNewItem(uint16 pos, uint32 item, bool update)
ItemAddedQuestCheck(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)
@ -14497,6 +14582,9 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
if (pEnchant->requiredSkill > 0 && pEnchant->requiredSkillValue > GetSkillValue(pEnchant->requiredSkill))
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
// 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)
@ -16096,7 +16184,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
bool rewarded = IsQuestRewarded(quest_id) && !quest->IsDFQuest();
// 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
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()) ||
(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)*/)
{
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);
for (uint8 slot = 0; slot < MAX_ARENA_SLOT; ++slot)
if (uint32 arenaTeamId = Player::GetArenaTeamIdFromStorage(GetGUIDLow(), slot))
for (auto const& itr : ArenaTeam::ArenaSlotByType)
if (uint32 arenaTeamId = Player::GetArenaTeamIdFromStorage(GetGUIDLow(), itr.second))
{
ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
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
continue;
uint8 slot = itr.second;
SetArenaTeamInfoField(slot, ARENA_TEAM_ID, arenaTeamId);
SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, arenaTeam->GetType());
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))
{
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)
QuickEquipItem(dest, item);
}
@ -19858,6 +19952,9 @@ bool Player::Satisfy(DungeonProgressionRequirements const* ar, uint32 target_map
|| missingPlayerItems.size() || missingPlayerQuests.size() || missingPlayerAchievements.size()
|| missingLeaderItems.size() || missingLeaderQuests.size() || missingLeaderAchievements.size())
{
if (!sScriptMgr->NotAvoidSatisfy(partyLeader, ar, target_map, report))
return true;
if (report)
{
uint8 requirementPrintMode = sWorld->getIntConfig(CONFIG_DUNGEON_ACCESS_REQUIREMENTS_PRINT_MODE);
@ -22020,36 +22117,6 @@ void Player::LeaveAllArenaTeams(uint64 guid)
} 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)
{
// Prevent resting on max level
@ -22492,9 +22559,9 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
}
}
Item* it = bStore ?
StoreNewItem(vDest, item, true) :
EquipNewItem(uiDest, item, true);
sScriptMgr->OnBeforeStoreOrEquipNewItem(this, vendorslot, item, count, bag, slot, pProto, pVendor, crItem, bStore);
Item* it = bStore ? StoreNewItem(vDest, item, true) : EquipNewItem(uiDest, item, true);
if (it)
{
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());
}
}
sScriptMgr->OnAfterStoreOrEquipNewItem(this, vendorslot, it, count, bag, slot, pProto, pVendor, crItem, bStore);
return true;
}
@ -23371,6 +23441,9 @@ bool Player::IsVisibleGloballyFor(Player const* u) const
if (!AccountMgr::IsPlayerAccount(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
return false;
}
@ -28457,3 +28530,77 @@ void Player::RemoveRestFlag(RestFlag restFlag)
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);
}

View file

@ -11,6 +11,7 @@
#include "DBCStores.h"
#include "GroupReference.h"
#include "InstanceSaveMgr.h"
#include "ArenaTeam.h"
#include "Item.h"
#include "MapReference.h"
#include "ObjectMgr.h"
@ -705,19 +706,6 @@ enum InstanceResetWarningType
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;
enum RestFlag
@ -1466,7 +1454,7 @@ public:
void RemoveRewardedQuest(uint32 questId, bool update = true);
void SendQuestUpdate(uint32 questId);
QuestGiverStatus GetQuestDialogStatus(Object* questGiver);
float GetQuestRate();
void SetDailyQuestStatus(uint32 quest_id);
bool IsDailyQuestDone(uint32 quest_id);
void SetWeeklyQuestStatus(uint32 quest_id);
@ -1616,6 +1604,7 @@ public:
[[nodiscard]] RewardedQuestSet const& getRewardedQuests() const { return m_RewardedQuests; }
QuestStatusMap& getQuestStatusMap() { return m_QuestStatus; }
QuestStatusSaveMap& GetQuestStatusSaveMap() { return m_QuestStatusSave; }
[[nodiscard]] size_t GetRewardedQuestCount() const { return m_RewardedQuests.size(); }
[[nodiscard]] bool IsQuestRewarded(uint32 quest_id) const
@ -1915,10 +1904,10 @@ public:
SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, type);
}
void SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value);
uint32 GetArenaPersonalRating(uint8 slot) const;
static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot);
static void LeaveAllArenaTeams(uint64 guid);
[[nodiscard]] uint32 GetArenaTeamId(uint8 slot) const;
[[nodiscard]] uint32 GetArenaPersonalRating(uint8 slot) const;
void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; }
uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; }
@ -2443,6 +2432,10 @@ public:
void SendCinematicStart(uint32 CinematicSequenceId);
void SendMovieStart(uint32 MovieId);
uint16 GetMaxSkillValueForLevel() const;
bool IsFFAPvP();
bool IsPvP();
/*********************************************************/
/*** INSTANCE SYSTEM ***/
/*********************************************************/
@ -2619,6 +2612,9 @@ public:
[[nodiscard]] uint32 GetNextSave() const { return m_nextSave; }
[[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
// Cinematic camera data and remote sight functions

View file

@ -4363,6 +4363,8 @@ void Unit::RemoveAura(AuraApplicationMap::iterator& i, AuraRemoveMode mode)
// Remove aura - for Area and Target auras
if (aura->GetOwner() == this)
aura->Remove(mode);
sScriptMgr->OnAuraRemove(this, aurApp, mode);
}
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
return GetFactionReactionTo(GetFactionTemplateEntry(), target);
}
@ -10782,6 +10789,9 @@ float Unit::SpellPctDamageModsDone(Unit* victim, SpellInfo const* spellProto, Da
if (!spellProto->ValidateAttribute6SpellDamageMods(this, *i, damagetype == DOT))
continue;
if (!sScriptMgr->IsNeedModSpellDamagePercent(this, *i, DoneTotalMod, spellProto))
continue;
if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
{
if ((*i)->GetSpellInfo()->EquippedItemClass == -1)
@ -11784,8 +11794,13 @@ float Unit::SpellPctHealingModsDone(Unit* victim, SpellInfo const* spellProto, D
// Healing done percent
AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
for (AuraEffectList::const_iterator i = mHealingDonePct.begin(); i != mHealingDonePct.end(); ++i)
AddPct(DoneTotalMod, (*i)->GetAmount());
for (auto const& auraEff : mHealingDonePct)
{
if (!sScriptMgr->IsNeedModHealPercent(this, auraEff, DoneTotalMod, spellProto))
continue;
AddPct(DoneTotalMod, auraEff->GetAmount());
}
// done scripted mod (take it from owner)
Unit* owner = GetOwner() ? GetOwner() : this;
@ -12400,6 +12415,9 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType
if (!spellProto->ValidateAttribute6SpellDamageMods(this, *i, false))
continue;
if (!sScriptMgr->IsNeedModMeleeDamagePercent(this, *i, DoneTotalMod, spellProto))
continue;
if (((*i)->GetMiscValue() & spellProto->GetSchoolMask()) && !((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
{
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
//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
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();
}
else
fieldBuffer << m_uint32Values[index];
if (!sScriptMgr->IsCustomBuildValuesUpdate(this, updateType, fieldBuffer, target, index))
{
fieldBuffer << m_uint32Values[index];
}
}
else
// send in current format (float as float, uint32 as uint32)

View file

@ -59,10 +59,13 @@ Group::Group() : m_leaderGuid(0), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL
{
for (uint8 i = 0; i < TARGETICONCOUNT; ++i)
m_targetIcons[i] = 0;
sScriptMgr->OnConstructGroup(this);
}
Group::~Group()
{
sScriptMgr->OnDestructGroup(this);
if (m_bgGroup)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
@ -142,6 +145,8 @@ bool Group::Create(Player* leader)
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.
sScriptMgr->OnCreate(this, leader);
}
else if (!AddMember(leader))
return false;
@ -1840,6 +1845,9 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
if (!member)
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
if (member->GetTeamId() != teamId)
return ERR_BATTLEGROUND_JOIN_TIMED_OUT;

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
{
if (!sScriptMgr->CanGuildSendBankList(this, session, tabId, sendAllSlots))
return;
WorldPacket data(SMSG_GUILD_BANK_LIST, 500);
data << uint64(m_bankMoney);
data << uint8(tabId);

View file

@ -756,6 +756,9 @@ public:
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:
uint32 m_id;
std::string m_name;

View file

@ -12,6 +12,7 @@
#include "Log.h"
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "ScriptMgr.h"
#include "Player.h"
#include "UpdateMask.h"
#include "Util.h"
@ -50,6 +51,9 @@ void WorldSession::SendAuctionHello(uint64 guid, Creature* unit)
return;
}
if (!sScriptMgr->CanSendAuctionHello(this, guid, unit))
return;
AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction());
if (!ahEntry)
return;

View file

@ -388,6 +388,9 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket& recvData)
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenaType);
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
if (!sScriptMgr->CanBattleFieldPort(_player, arenaType, bgTypeId, action))
return;
// get group info from queue
GroupQueueInfo ginfo;
if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
@ -658,6 +661,14 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
// queue result (default ok)
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:
if (!asGroup)
{

View file

@ -14,6 +14,7 @@
#include "Opcodes.h"
#include "Pet.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "SocialMgr.h"
#include "SpellAuras.h"
#include "Util.h"
@ -74,6 +75,9 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
return;
}
if (!sScriptMgr->CanGroupInvite(GetPlayer(), membername))
return;
if (GetPlayer()->IsSpectator() || player->IsSpectator())
{
SendPartyResult(PARTY_OP_INVITE, membername, ERR_INVITE_RESTRICTED);
@ -224,6 +228,9 @@ void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recvData)
return;
}
if (!sScriptMgr->CanGroupAccept(GetPlayer(), group))
return;
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());

View file

@ -11,6 +11,7 @@
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "SpellInfo.h"
#include "UpdateData.h"
#include "WorldPacket.h"
@ -660,6 +661,9 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData)
Item* pItem = _player->GetItemByGuid(itemguid);
if (pItem)
{
if (!sScriptMgr->CanSellItem(_player, pItem, creature))
return;
// prevent sell not owner item
if (_player->GetGUID() != pItem->GetOwnerGUID())
{

View file

@ -14,6 +14,7 @@
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
@ -196,9 +197,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
}
}*/
uint32 rc_account = receive
? receive->GetSession()->GetAccountId()
: sObjectMgr->GetPlayerAccountIdByGUID(rc);
uint32 rc_account = receive ? 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()))
{
@ -255,6 +254,9 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
return;
}
if (!sScriptMgr->CanSendMail(player, rc, mailbox, subject, body, money, COD, item))
return;
items[i] = item;
}

View file

@ -1019,6 +1019,8 @@ void WorldSession::HandleRepairItemOpcode(WorldPacket& recvData)
// reputation discount
float discountMod = _player->GetReputationPriceDiscount(unit);
sScriptMgr->OnBeforePlayerDurabilityRepair(_player, npcGUID, itemGUID, discountMod, guildBank);
if (itemGUID)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)

View file

@ -15,22 +15,12 @@
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "PetitionMgr.h"
#include "ScriptMgr.h"
#include "SocialMgr.h"
#include "World.h"
#include "WorldPacket.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)
{
#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 (sGuildMgr->GetGuildByName(name))
@ -880,38 +872,65 @@ void WorldSession::SendPetitionShowList(uint64 guid)
WorldPacket data(SMSG_PETITION_SHOWLIST, 8 + 1 + 4 * 6);
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())
{
sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
data << uint8(1); // count
data << uint32(1); // index
data << uint32(GUILD_CHARTER); // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id
data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD)); // charter cost
data << CharterEntry; // charter entry
data << CharterDispayID; // charter display id
data << CharterCost; // charter cost
data << uint32(0); // unknown
data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs
}
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
data << uint8(3); // count
sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
data << uint32(1); // index
data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id
data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2)); // charter cost
data << CharterEntry; // charter entry
data << CharterDispayID; // charter display id
data << CharterCost; // charter cost
data << uint32(2); // unknown
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
sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
data << uint32(2); // index
data << uint32(ARENA_TEAM_CHARTER_3v3); // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id
data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3)); // charter cost
data << CharterEntry; // charter entry
data << CharterDispayID; // charter display id
data << CharterCost; // charter cost
data << uint32(3); // unknown
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
sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
data << uint32(3); // index
data << uint32(ARENA_TEAM_CHARTER_5v5); // charter entry
data << uint32(CHARTER_DISPLAY_ID); // charter display id
data << uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5)); // charter cost
data << CharterEntry; // charter entry
data << CharterDispayID; // charter display id
data << CharterCost; // charter cost
data << uint32(5); // unknown
data << uint32(5); // required signs?
}

View file

@ -15,6 +15,7 @@
#include "ScriptMgr.h"
#include "Spell.h"
#include "SpellAuraEffects.h"
#include "ScriptMgr.h"
#include "SpellAuras.h"
#include "SpellMgr.h"
#include "TemporarySummon.h"
@ -343,6 +344,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
uint8 castCount, castFlags;
recvPacket >> castCount >> spellId >> castFlags;
uint32 oldSpellId = spellId;
#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());
#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
// Skip it to prevent "interrupt" message
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);
sScriptMgr->ValidateSpellAtCastSpellResult(_player, mover, spell, oldSpellId, spellId);
spell->m_cast_count = castCount; // set count of casts
spell->prepare(&targets);
}

View file

@ -12,6 +12,7 @@
#include "ObjectAccessor.h"
#include "Opcodes.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "SocialMgr.h"
#include "Spell.h"
#include "World.h"
@ -640,6 +641,9 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
return;
}
if (!sScriptMgr->CanInitTrade(_player, pOther))
return;
// OK start trade
_player->m_trade = new TradeData(_player, pOther);
pOther->m_trade = new TradeData(pOther, _player);

View file

@ -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)
: 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()
{
ASSERT(m_playerList.empty());
sScriptMgr->OnDestructInstanceSave(this);
}
void InstanceSave::InsertToDB()
@ -169,6 +172,8 @@ void InstanceSave::InsertToDB()
stmt->setUInt32(4, completedEncounters);
stmt->setString(5, data);
CharacterDatabase.Execute(stmt);
sScriptMgr->OnInstanceSave(this);
}
time_t InstanceSave::GetResetTimeForDB()

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()
sScriptMgr->OnAfterLootTemplateProcess(this, tab, store, lootOwner, personal, noEmptyError, lootMode);
// Setting access rights for group loot case
Group* group = lootOwner->GetGroup();
if (!personal && group)

View file

@ -22,6 +22,7 @@
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "ScriptMgr.h"
#include "Player.h"
#include "Transport.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()];
if (!sScriptMgr->CanEnterMap(player, entry, instance, mapDiff, loginCheck))
return false;
Group* group = player->GetGroup();
if (entry->IsRaid())
{

View file

@ -8,6 +8,17 @@ Xinef
#include "Common.h"
#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;
struct Petition

View file

@ -64,6 +64,11 @@ template class ScriptRegistry<SpellSC>;
template class ScriptRegistry<AccountScript>;
template class ScriptRegistry<GameEventScript>;
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"
@ -124,10 +129,15 @@ void ScriptMgr::Unload()
SCR_CLEAR(GlobalScript);
SCR_CLEAR(ModuleScript);
SCR_CLEAR(BGScript);
SCR_CLEAR(AchievementScript);
SCR_CLEAR(ArenaTeamScript);
SCR_CLEAR(SpellSC);
SCR_CLEAR(GameEventScript);
SCR_CLEAR(MailScript);
SCR_CLEAR(MiscScript);
SCR_CLEAR(PetScript);
SCR_CLEAR(ArenaScript);
SCR_CLEAR(CommandSC);
#undef SCR_CLEAR
}
@ -198,8 +208,13 @@ void ScriptMgr::CheckIfScriptsInDatabaseExist()
!ScriptRegistry<PlayerScript>::GetScriptById(sid) &&
!ScriptRegistry<GuildScript>::GetScriptById(sid) &&
!ScriptRegistry<BGScript>::GetScriptById(sid) &&
!ScriptRegistry<AchievementScript>::GetScriptById(sid) &&
!ScriptRegistry<ArenaTeamScript>::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))
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()
{
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);
}
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)
@ -2037,7 +2057,7 @@ void ScriptMgr::OnBeforeBuyItemFromVendor(Player* player, uint64 vendorguid, uin
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);
}
@ -2136,17 +2156,6 @@ void ScriptMgr::OnCheckNormalMatch(BattlegroundQueue* queue, uint32& Coef, Battl
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)
{
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);
}
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)
: ScriptObject(name)
{
@ -2416,3 +3270,33 @@ MailScript::MailScript(const char* name)
{
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);
}

View file

@ -15,6 +15,7 @@
#include "DBCStores.h"
#include "DynamicObject.h"
#include "GameEventMgr.h"
#include "LFGMgr.h"
#include "ObjectMgr.h"
#include "PetDefines.h"
#include "QuestDef.h"
@ -63,9 +64,11 @@ struct AchievementCriteriaData;
struct AuctionEntry;
struct ConditionSourceInfo;
struct Condition;
struct DungeonProgressionRequirements;
struct ItemTemplate;
struct OutdoorPvPData;
struct GroupQueueInfo;
struct TargetInfo;
#define VISIBLE_RANGE 166.0f //MAX visible range (size of grid)
@ -287,6 +290,9 @@ public:
// Called after calculating arena rating changes
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>
@ -397,19 +403,19 @@ public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; }
// 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.
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.
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)
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).
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
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 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
@ -494,25 +514,25 @@ public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; }
// 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.
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.
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.
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.
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.
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.
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.
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; }
// 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.
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.
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.
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.
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.
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; }
// 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
@ -670,7 +690,7 @@ public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; }
// 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
@ -734,7 +754,7 @@ public:
[[nodiscard]] bool IsDatabaseBound() const override { return true; }
// 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
@ -860,7 +880,7 @@ public:
virtual void OnMapChanged(Player* /*player*/) { }
// 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
virtual void OnUpdateFaction(Player* /*player*/) { }
@ -922,14 +942,23 @@ public:
//After creating item (eg profession item creation)
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*/) { }
// 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
virtual void OnBeforeBuyItemFromVendor(Player* /*player*/, uint64 /*vendorguid*/, uint32 /*vendorslot*/, uint32& /*item*/, uint8 /*count*/, uint8 /*bag*/, uint8 /*slot*/) { };
//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*/) { }
@ -942,7 +971,7 @@ public:
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; }
// 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
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
@ -1025,6 +1148,8 @@ public:
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*/) { }
[[nodiscard]] virtual bool CanGuildSendBankList(Guild const* /*guild*/, WorldSession* /*session*/, uint8 /*tabId*/, bool /*sendAllSlots*/) { return true; }
};
class GroupScript : public ScriptObject
@ -1049,6 +1174,10 @@ public:
// Called when a group is disbanded.
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
@ -1067,7 +1196,7 @@ public:
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 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*/) { }
// On Before arena points distribution
@ -1106,16 +1235,20 @@ public:
// Remove player at leave BG
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 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; }
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
@ -1143,6 +1276,24 @@ public:
// Calculate max duration in applying aura
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
@ -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*/) { }
};
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.
class ScriptMgr
{
@ -1234,6 +1503,7 @@ public: /* FormulaScript */
void OnGainCalculation(uint32& gain, Player* player, Unit* unit);
void OnGroupRateCalculation(float& rate, uint32 count, bool isRaid);
void OnAfterArenaRatingCalculation(Battleground* const bg, int32& winnerMatchmakerChange, int32& loserMatchmakerChange, int32& winnerChange, int32& loserChange);
void OnBeforeUpdatingPersonalRating(int32& mod, uint32 type);
public: /* MapScript */
void OnCreateMap(Map* map);
@ -1396,8 +1666,11 @@ public: /* PlayerScript */
void OnLootItem(Player* player, Item* item, uint32 count, uint64 lootguid);
void OnCreateItem(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 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 OnAfterUpdateMaxHealth(Player* player, float& value);
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 OnAfterGuardianInitStatsForLevel(Player* player, Guardian* guardian);
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 */
void OnAccountLogin(uint32 accountId);
@ -1435,6 +1755,7 @@ public: /* GuildScript */
bool isDestBank, uint8 destContainer, uint8 destSlotId);
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);
bool CanGuildSendBankList(Guild const* guild, WorldSession* session, uint8 tabId, bool sendAllSlots);
public: /* GroupScript */
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 OnGroupChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid);
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 */
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 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 OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData);
void OnInitializeLockedDungeons(Player* player, uint8& level, uint32& lockData, lfg::LFGDungeonData const* dungeon);
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 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);
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 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 */
void OnPlayerMove(Player* player, MovementInfo movementInfo, uint32 opcode);
@ -1491,12 +1821,14 @@ public: /* BGScript */
void OnBattlegroundAddPlayer(Battleground* bg, Player* player);
void OnBattlegroundBeforeAddPlayer(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);
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,
BattlegroundBracketId thisBracketId, BattlegroundQueue* specificQueue, BattlegroundBracketId specificBracketId);
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 */
void OnGetSlotByType(const uint32 type, uint8& slot);
@ -1507,6 +1839,15 @@ public: /* Arena Team Script */
public: /* SpellSC */
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 */
void OnGameEventStart(uint16 EventID);
@ -1515,6 +1856,52 @@ public: /* GameEventScript */
public: /* MailScript */
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:
uint32 _scriptCount;

View file

@ -4726,7 +4726,7 @@ void AuraEffect::HandleModDamageDone(AuraApplication const* aurApp, uint8 mode,
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
// 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
if (GetSpellInfo()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER)
@ -4796,6 +4796,9 @@ void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8
if (!target)
return;
if (!sScriptMgr->CanModAuraEffectModDamagePercentDone(this, target, aurApp, mode, apply))
return;
if (target->GetTypeId() == TYPEID_PLAYER)
{
for (int i = 0; i < MAX_ATTACK; ++i)

View file

@ -836,19 +836,21 @@ void Spell::SelectSpellTargets()
else if (m_auraScaleMask)
{
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
if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask)
if (m_auraScaleMask && itr->effectMask == m_auraScaleMask)
{
// Do not check for selfcast
if (!ihit->scaleAura && ihit->targetGUID != m_caster->GetGUID())
{
m_UniqueTargetInfo.erase(ihit++);
continue;
}
bool needErase = false;
if (!itr->scaleAura && itr->targetGUID != m_caster->GetGUID())
needErase = true;
sScriptMgr->OnRemoveAuraScaleTargets(this, *itr, m_auraScaleMask, needErase);
if (needErase)
m_UniqueTargetInfo.erase(itr);
}
++ihit;
}
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)
ihit->scaleAura = true;
}
sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
return;
}
}
@ -2176,6 +2180,8 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
targetInfo.scaleAura = true;
}
sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
// Calculate hit result
if (m_originalCaster)
{
@ -3163,8 +3169,14 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const
InitExplicitTargets(*targets);
if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
{
finish(false);
return SPELL_FAILED_UNKNOWN;
}
// 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)
{
@ -5140,6 +5152,13 @@ SpellCastResult Spell::CheckCast(bool strict)
if (((const Player*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
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
if (!m_spellInfo->HasAttribute(SPELL_ATTR0_PASSIVE))
{
@ -5969,6 +5988,8 @@ SpellCastResult Spell::CheckCast(bool strict)
break;
}
case SPELL_EFFECT_TALENT_SPEC_SELECT:
if (!sScriptMgr->CanSelectSpecTalent(this))
return SPELL_FAILED_DONT_REPORT;
// can't change during already started arena/battleground
if (m_caster->GetTypeId() == TYPEID_PLAYER)
if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())

View file

@ -234,6 +234,21 @@ struct ChannelTargetData
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;
class Spell
@ -241,6 +256,9 @@ class Spell
friend void Unit::SetCurrentCastedSpell(Spell* pSpell);
friend class SpellScript;
public:
Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, uint64 originalCasterGUID = 0, bool skipCheck = false);
~Spell();
void EffectNULL(SpellEffIndex effIndex);
void EffectUnused(SpellEffIndex effIndex);
void EffectDistract(SpellEffIndex effIndex);
@ -369,9 +387,6 @@ public:
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 SelectExplicitTargets();
@ -473,7 +488,7 @@ public:
void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode);
void HandleThreatSpells();
SpellInfo const* const m_spellInfo;
SpellInfo const* m_spellInfo;
Item* m_CastItem;
uint64 m_castItemGUID;
uint8 m_cast_count;
@ -511,6 +526,7 @@ public:
Unit* GetCaster() const { return m_caster; }
Unit* GetOriginalCaster() const { return m_originalCaster; }
SpellInfo const* GetSpellInfo() const { return m_spellInfo; }
void SetSpellInfo(SpellInfo const* info) { m_spellInfo = info; }
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)
@ -522,21 +538,6 @@ public:
// xinef: moved to public
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; }
protected:
bool HasGlobalCooldown() const;

View file

@ -9,6 +9,7 @@
#include "ConditionMgr.h"
#include "DBCStores.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "Spell.h"
#include "SpellAuraDefines.h"
#include "SpellAuraEffects.h"
@ -2487,7 +2488,14 @@ SpellInfo const* SpellInfo::GetAuraRankForLevel(uint8 level) const
if (!needRankSelection)
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 (uint32(level + 10) >= nextSpellInfo->SpellLevel)

View file

@ -347,12 +347,14 @@ public:
{
player->SetDeveloper(true);
handler->GetSession()->SendNotification(LANG_DEV_ON);
sScriptMgr->OnHandleDevCommand(handler->GetSession()->GetPlayer(), enablestr);
return true;
}
else if (enablestr == "off")
{
player->SetDeveloper(false);
handler->GetSession()->SendNotification(LANG_DEV_OFF);
sScriptMgr->OnHandleDevCommand(handler->GetSession()->GetPlayer(), enablestr);
return true;
}

View file

@ -265,8 +265,8 @@ public:
void SetDest(SpellDestination& dest)
{
std::list<Spell::TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (Unit* target = ObjectAccessor::GetUnit(*GetCaster(), ihit->targetGUID))
{
dest.Relocate(*target);

View file

@ -613,8 +613,8 @@ public:
}
float pct = (_sharedHealth / _sharedHealthMax) * 100.0f;
std::list<Spell::TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (Creature* target = ObjectAccessor::GetCreature(*GetCaster(), ihit->targetGUID))
{
target->LowerPlayerDamageReq(target->GetMaxHealth());

View file

@ -606,8 +606,8 @@ public:
{
if (GetHitUnit() != GetCaster())
{
std::list<Spell::TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
std::list<TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (ihit->targetGUID == GetCaster()->GetGUID())
ihit->damage = -int32(GetHitDamage() * 0.25f);
}

View file

@ -430,8 +430,8 @@ public:
{
if (Unit* target = GetExplTargetUnit())
{
std::list<Spell::TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
std::list<TargetInfo> const* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::const_iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (ihit->missCondition == SPELL_MISS_NONE && ihit->targetGUID == target->GetGUID())
GetCaster()->CastSpell(target, 55095 /*SPELL_FROST_FEVER*/, true);
}
@ -610,8 +610,8 @@ public:
void RecalculateDamage()
{
std::list<Spell::TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<Spell::TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
std::list<TargetInfo>* targetsInfo = GetSpell()->GetUniqueTargetInfo();
for (std::list<TargetInfo>::iterator ihit = targetsInfo->begin(); ihit != targetsInfo->end(); ++ihit)
if (ihit->targetGUID == GetCaster()->GetGUID())
ihit->crit = roll_chance_f(GetCaster()->GetFloatValue(PLAYER_CRIT_PERCENTAGE));
}