Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2024-09-04 23:45:48 +08:00
282 changed files with 1861 additions and 1430 deletions
+1 -1
View File
@@ -21,7 +21,7 @@
void Acore::Banner::Show(std::string_view applicationName, void(*log)(std::string_view text), void(*logExtraInfo)())
{
log(Acore::StringFormatFmt("{} ({})", GitRevision::GetFullVersion(), applicationName));
log(Acore::StringFormat("{} ({})", GitRevision::GetFullVersion(), applicationName));
log("<Ctrl-C> to stop.\n");
log(" █████╗ ███████╗███████╗██████╗ ██████╗ ████████╗██╗ ██╗");
log(" ██╔══██╗╚══███╔╝██╔════╝██╔══██╗██╔═══██╗╚══██╔══╝██║ ██║");
+2 -2
View File
@@ -85,7 +85,7 @@ namespace MMAP
}
// load and init dtNavMesh - read parameters from file
std::string fileName = Acore::StringFormat(MAP_FILE_NAME_FORMAT, sConfigMgr->GetOption<std::string>("DataDir", ".").c_str(), mapId);
std::string fileName = Acore::StringFormat(MAP_FILE_NAME_FORMAT, sConfigMgr->GetOption<std::string>("DataDir", "."), mapId);
FILE* file = fopen(fileName.c_str(), "rb");
if (!file)
@@ -147,7 +147,7 @@ namespace MMAP
}
// load this tile :: mmaps/MMMXXYY.mmtile
std::string fileName = Acore::StringFormat(TILE_FILE_NAME_FORMAT, sConfigMgr->GetOption<std::string>("DataDir", ".").c_str(), mapId, x, y);
std::string fileName = Acore::StringFormat(TILE_FILE_NAME_FORMAT, sConfigMgr->GetOption<std::string>("DataDir", "."), mapId, x, y);
FILE* file = fopen(fileName.c_str(), "rb");
if (!file)
{
+2 -1
View File
@@ -43,7 +43,8 @@
#define MAX_NETCLIENT_PACKET_SIZE (32767 - 1) // Client hardcap: int16 with trailing zero space otherwise crash on memory free
// TimeConstants
constexpr auto MINUTE = 60;
constexpr auto SECOND = 1;
constexpr auto MINUTE = SECOND * 60;
constexpr auto HOUR = MINUTE * 60;
constexpr auto DAY = HOUR * 24;
constexpr auto WEEK = DAY * 7;
+4 -4
View File
@@ -65,7 +65,7 @@ namespace
template<typename Format, typename... Args>
inline void PrintError(std::string_view filename, Format&& fmt, Args&& ... args)
{
std::string message = Acore::StringFormatFmt(std::forward<Format>(fmt), std::forward<Args>(args)...);
std::string message = Acore::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...);
if (IsAppConfig(filename))
{
@@ -117,7 +117,7 @@ namespace
return false;
}
throw ConfigException(Acore::StringFormatFmt("Config::LoadFile: Failed open {}file '{}'", isOptional ? "optional " : "", file));
throw ConfigException(Acore::StringFormat("Config::LoadFile: Failed open {}file '{}'", isOptional ? "optional " : "", file));
}
uint32 count = 0;
@@ -144,7 +144,7 @@ namespace
// read line error
if (!in.good() && !in.eof())
throw ConfigException(Acore::StringFormatFmt("> Config::LoadFile: Failure to read line number {} in file '{}'", lineNumber, file));
throw ConfigException(Acore::StringFormat("> Config::LoadFile: Failure to read line number {} in file '{}'", lineNumber, file));
// remove whitespace in line
line = Acore::String::Trim(line, in.getloc());
@@ -187,7 +187,7 @@ namespace
return false;
}
throw ConfigException(Acore::StringFormatFmt("Config::LoadFile: Empty file '{}'", file));
throw ConfigException(Acore::StringFormat("Config::LoadFile: Empty file '{}'", file));
}
// Add correct keys if file load without errors
+8 -8
View File
@@ -62,19 +62,19 @@ namespace
inline std::string MakeMessage(std::string_view messageType, std::string_view file, uint32 line, std::string_view function,
std::string_view message, std::string_view fmtMessage = {}, std::string_view debugInfo = {})
{
std::string msg = Acore::StringFormatFmt("\n>> {}\n\n# Location: {}:{}\n# Function: {}\n# Condition: {}\n", messageType, file, line, function, message);
std::string msg = Acore::StringFormat("\n>> {}\n\n# Location: {}:{}\n# Function: {}\n# Condition: {}\n", messageType, file, line, function, message);
if (!fmtMessage.empty())
{
msg.append(Acore::StringFormatFmt("# Message: {}\n", fmtMessage));
msg.append(Acore::StringFormat("# Message: {}\n", fmtMessage));
}
if (!debugInfo.empty())
{
msg.append(Acore::StringFormatFmt("\n# Debug info: {}\n", debugInfo));
msg.append(Acore::StringFormat("\n# Debug info: {}\n", debugInfo));
}
return Acore::StringFormatFmt(
return Acore::StringFormat(
"#{0:-^{2}}#\n"
" {1: ^{2}} \n"
"#{0:-^{2}}#\n", "", msg, 70);
@@ -90,14 +90,14 @@ namespace
*/
inline std::string MakeAbortMessage(std::string_view file, uint32 line, std::string_view function, std::string_view fmtMessage = {})
{
std::string msg = Acore::StringFormatFmt("\n>> ABORTED\n\n# Location '{}:{}'\n# Function '{}'\n", file, line, function);
std::string msg = Acore::StringFormat("\n>> ABORTED\n\n# Location '{}:{}'\n# Function '{}'\n", file, line, function);
if (!fmtMessage.empty())
{
msg.append(Acore::StringFormatFmt("# Message '{}'\n", fmtMessage));
msg.append(Acore::StringFormat("# Message '{}'\n", fmtMessage));
}
return Acore::StringFormatFmt(
return Acore::StringFormat(
"\n#{0:-^{2}}#\n"
" {1: ^{2}} \n"
"#{0:-^{2}}#\n", "", msg, 70);
@@ -148,7 +148,7 @@ void Acore::Abort(std::string_view file, uint32 line, std::string_view function,
void Acore::AbortHandler(int sigval)
{
// nothing useful to log here, no way to pass args
std::string formattedMessage = StringFormatFmt("Caught signal {}\n", sigval);
std::string formattedMessage = StringFormat("Caught signal {}\n", sigval);
fmt::print(stderr, "{}", formattedMessage);
fflush(stderr);
Crash(formattedMessage.c_str());
+3 -3
View File
@@ -31,19 +31,19 @@ namespace Acore
template<typename... Args>
AC_COMMON_API inline void Assert(std::string_view file, uint32 line, std::string_view function, std::string_view debugInfo, std::string_view message, std::string_view fmt, Args&&... args)
{
Assert(file, line, function, debugInfo, message, StringFormatFmt(fmt, std::forward<Args>(args)...));
Assert(file, line, function, debugInfo, message, StringFormat(fmt, std::forward<Args>(args)...));
}
template<typename... Args>
AC_COMMON_API inline void Fatal(std::string_view file, uint32 line, std::string_view function, std::string_view message, std::string_view fmt, Args&&... args)
{
Fatal(file, line, function, message, StringFormatFmt(fmt, std::forward<Args>(args)...));
Fatal(file, line, function, message, StringFormat(fmt, std::forward<Args>(args)...));
}
template<typename... Args>
AC_COMMON_API inline void Abort(std::string_view file, uint32 line, std::string_view function, std::string_view fmt, Args&&... args)
{
Abort(file, line, function, StringFormatFmt(fmt, std::forward<Args>(args)...));
Abort(file, line, function, StringFormat(fmt, std::forward<Args>(args)...));
}
AC_COMMON_API void Warning(std::string_view file, uint32 line, std::string_view function, std::string_view message);
+2 -2
View File
@@ -52,7 +52,7 @@ void AppenderConsole::InitColors(std::string const& name, std::string_view str)
std::vector<std::string_view> colorStrs = Acore::Tokenize(str, ' ', false);
if (colorStrs.size() != NUM_ENABLED_LOG_LEVELS)
{
throw InvalidAppenderArgsException(Acore::StringFormatFmt("Log::CreateAppenderFromConfig: Invalid color data '{}' for console appender {} (expected {} entries, got {})",
throw InvalidAppenderArgsException(Acore::StringFormat("Log::CreateAppenderFromConfig: Invalid color data '{}' for console appender {} (expected {} entries, got {})",
str, name, NUM_ENABLED_LOG_LEVELS, colorStrs.size()));
}
@@ -64,7 +64,7 @@ void AppenderConsole::InitColors(std::string const& name, std::string_view str)
}
else
{
throw InvalidAppenderArgsException(Acore::StringFormatFmt("Log::CreateAppenderFromConfig: Invalid color '{}' for log level {} on console appender {}",
throw InvalidAppenderArgsException(Acore::StringFormat("Log::CreateAppenderFromConfig: Invalid color '{}' for log level {} on console appender {}",
colorStrs[i], EnumUtils::ToTitle(static_cast<LogLevel>(i)), name));
}
}
+2 -2
View File
@@ -31,7 +31,7 @@ AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, Ap
{
if (args.size() < 4)
{
throw InvalidAppenderArgsException(Acore::StringFormatFmt("Log::CreateAppenderFromConfig: Missing file name for appender {}", name));
throw InvalidAppenderArgsException(Acore::StringFormat("Log::CreateAppenderFromConfig: Missing file name for appender {}", name));
}
_fileName.assign(args[3]);
@@ -63,7 +63,7 @@ AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, Ap
}
else
{
throw InvalidAppenderArgsException(Acore::StringFormatFmt("Log::CreateAppenderFromConfig: Invalid size '{}' for appender {}", args[5], name));
throw InvalidAppenderArgsException(Acore::StringFormat("Log::CreateAppenderFromConfig: Invalid size '{}' for appender {}", args[5], name));
}
}
+2 -2
View File
@@ -69,7 +69,7 @@ public:
template<typename... Args>
inline void outMessage(std::string const& filter, LogLevel const level, Acore::FormatString<Args...> fmt, Args&&... args)
{
_outMessage(filter, level, Acore::StringFormatFmt(fmt, std::forward<Args>(args)...));
_outMessage(filter, level, Acore::StringFormat(fmt, std::forward<Args>(args)...));
}
template<typename... Args>
@@ -80,7 +80,7 @@ public:
return;
}
_outCommand(Acore::StringFormatFmt(fmt, std::forward<Args>(args)...), std::to_string(account));
_outCommand(Acore::StringFormat(fmt, std::forward<Args>(args)...), std::to_string(account));
}
void SetRealmId(uint32 id);
+2 -17
View File
@@ -26,27 +26,12 @@
namespace Acore
{
/// Default AC string format function.
template<typename Format, typename... Args>
inline std::string StringFormat(Format&& fmt, Args&& ... args)
{
try
{
return fmt::sprintf(std::forward<Format>(fmt), std::forward<Args>(args)...);
}
catch (const fmt::format_error& formatError)
{
std::string error = "An error occurred formatting string \"" + std::string(fmt) + "\" : " + std::string(formatError.what());
return error;
}
}
template<typename... Args>
using FormatString = fmt::format_string<Args...>;
// Default string format function.
/// Default AC string format function.
template<typename... Args>
inline std::string StringFormatFmt(FormatString<Args...> fmt, Args&&... args)
inline std::string StringFormat(FormatString<Args...> fmt, Args&&... args)
{
try
{
+6 -6
View File
@@ -86,27 +86,27 @@ AC_COMMON_API std::string Acore::Time::ToTimeString<Microseconds>(uint64 duratio
{
if (days)
{
return Acore::StringFormatFmt("{}:{:02}:{:02}:{:02}:{:02}:{:02}", days, hours, minutes, secs, millisecs);
return Acore::StringFormat("{}:{:02}:{:02}:{:02}:{:02}:{:02}", days, hours, minutes, secs, millisecs);
}
else if (hours)
{
return Acore::StringFormatFmt("{}:{:02}:{:02}:{:02}:{:02}", hours, minutes, secs, millisecs);
return Acore::StringFormat("{}:{:02}:{:02}:{:02}:{:02}", hours, minutes, secs, millisecs);
}
else if (minutes)
{
return Acore::StringFormatFmt("{}:{:02}:{:02}:{:02}", minutes, secs, millisecs);
return Acore::StringFormat("{}:{:02}:{:02}:{:02}", minutes, secs, millisecs);
}
else if (secs)
{
return Acore::StringFormatFmt("{}:{:02}:{:02}", secs, millisecs);
return Acore::StringFormat("{}:{:02}:{:02}", secs, millisecs);
}
else if (millisecs)
{
return Acore::StringFormatFmt("{}:{:02}", millisecs);
return Acore::StringFormat("{}:{:02}", millisecs);
}
else // microsecs
{
return Acore::StringFormatFmt("{}", microsecs);
return Acore::StringFormat("{}", microsecs);
}
}
+2 -2
View File
@@ -233,7 +233,7 @@ int main(int argc, char** argv)
signals.async_wait(SignalHandler);
// Start the Boost based thread pool
int numThreads = sConfigMgr->GetOption<int32>("ThreadPool", 1);
int numThreads = sConfigMgr->GetOption<int32>("ThreadPool", 2);
std::shared_ptr<std::vector<std::thread>> threadPool(new std::vector<std::thread>(), [ioContext](std::vector<std::thread>* del)
{
ioContext->stop();
@@ -257,7 +257,7 @@ int main(int argc, char** argv)
}
// Set process priority according to configuration settings
SetProcessPriority("server.worldserver", sConfigMgr->GetOption<int32>(CONFIG_PROCESSOR_AFFINITY, 0), sConfigMgr->GetOption<bool>(CONFIG_HIGH_PRIORITY, false));
SetProcessPriority("server.worldserver", sConfigMgr->GetOption<int32>(CONFIG_PROCESSOR_AFFINITY, 0), sConfigMgr->GetOption<bool>(CONFIG_HIGH_PRIORITY, true));
// Loading modules configs before scripts
sConfigMgr->LoadModulesConfigs();
@@ -139,13 +139,13 @@ CharacterDatabase.WorkerThreads = 1
# WorldDatabase.SynchThreads
# CharacterDatabase.SynchThreads
# Description: The amount of MySQL connections spawned to handle.
# Default: 1 - (LoginDatabase.WorkerThreads)
# 1 - (WorldDatabase.WorkerThreads)
# 2 - (CharacterDatabase.WorkerThreads)
# Default: 1 - (LoginDatabase.SynchThreads)
# 1 - (WorldDatabase.SynchThreads)
# 1 - (CharacterDatabase.SynchThreads)
LoginDatabase.SynchThreads = 1
WorldDatabase.SynchThreads = 1
CharacterDatabase.SynchThreads = 2
CharacterDatabase.SynchThreads = 1
#
# MaxPingTime
@@ -1040,7 +1040,7 @@ MinWorldUpdateTime = 1
# Default: 10 - (10 minutes)
# 1+
UpdateUptimeInterval = 1
UpdateUptimeInterval = 10
#
# MaxCoreStuckTime
@@ -1219,7 +1219,7 @@ Warden.ClientCheckFailAction = 0
# Default: 86400 - (24 hours)
# 0 - (Permanent ban)
Warden.BanDuration = 259200
Warden.BanDuration = 86400
#
###################################################################################################
@@ -1277,17 +1277,17 @@ Visibility.GroupMode = 1
# Visibility.Distance.Instances
# Visibility.Distance.BGArenas
# Description: Visibility distance to see other players or gameobjects.
# Visibility on continents on retail ~90 yards. In BG/Arenas ~180.
# For instances default ~120.
# Visibility on continents on retail ~100 yards. In BG/Arenas ~533.
# For instances default ~170.
# Max limited by active player zone: ~ 333
# Min limit is max aggro radius (45) * Rate.Creature.Aggro
# Default: 90 - (Visibility.Distance.Continents)
# 120 - (Visibility.Distance.Instances)
# 180 - (Visibility.Distance.BGArenas)
# Default: 100 - (Visibility.Distance.Continents)
# 170 - (Visibility.Distance.Instances)
# 533 - (Visibility.Distance.BGArenas)
Visibility.Distance.Continents = 90
Visibility.Distance.Instances = 120
Visibility.Distance.BGArenas = 180
Visibility.Distance.Continents = 100
Visibility.Distance.Instances = 170
Visibility.Distance.BGArenas = 533
#
# Visibility.ObjectSparkles
@@ -2540,7 +2540,7 @@ Death.SicknessLevel = 11
# 0 - (Disabled)
Death.CorpseReclaimDelay.PvP = 1
Death.CorpseReclaimDelay.PvE = 0
Death.CorpseReclaimDelay.PvE = 1
#
# Death.Bones.World
@@ -3415,7 +3415,7 @@ Wintergrasp.Enable = 1
# Description: Maximum number of players allowed in Wintergrasp.
# Default: 100
Wintergrasp.PlayerMax = 120
Wintergrasp.PlayerMax = 100
#
# Wintergrasp.PlayerMin
@@ -3566,14 +3566,14 @@ Battleground.Random.ResetHour = 6
# Default: 0 - (Disabled)
# 1 - (Enabled)
Battleground.StoreStatistics.Enable = 1
Battleground.StoreStatistics.Enable = 0
# Battleground.TrackDeserters.Enable
# Description: Track deserters of Battlegrounds.
# Default: 0 - (Disabled)
# 1 - (Enabled)
Battleground.TrackDeserters.Enable = 1
Battleground.TrackDeserters.Enable = 0
#
# Battleground.InvitationType
@@ -4064,7 +4064,7 @@ PartyLevelReq = 1
# Default: 0 - (Disabled, Blizzlike, Channel settings are lost if last person left)
# 1 - (Enabled)
PreserveCustomChannels = 1
PreserveCustomChannels = 0
#
# PreserveCustomChannelDuration
@@ -32,7 +32,7 @@ class DatabaseWorkerPool;
class AC_DATABASE_API DatabaseLoader
{
public:
DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask = 0, std::string_view modulesList = {});
DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask = 7, std::string_view modulesList = {});
// Register a database to the loader (lazy implemented)
template <class T>
@@ -103,7 +103,7 @@ public:
if (sql.empty())
return;
Execute(Acore::StringFormatFmt(sql, std::forward<Args>(args)...));
Execute(Acore::StringFormat(sql, std::forward<Args>(args)...));
}
//! Enqueues a one-way SQL operation in prepared statement format that will be executed asynchronously.
@@ -126,7 +126,7 @@ public:
if (sql.empty())
return;
DirectExecute(Acore::StringFormatFmt(sql, std::forward<Args>(args)...));
DirectExecute(Acore::StringFormat(sql, std::forward<Args>(args)...));
}
//! Directly executes a one-way SQL operation in prepared statement format, that will block the calling thread until finished.
@@ -149,7 +149,7 @@ public:
if (sql.empty())
return QueryResult(nullptr);
return Query(Acore::StringFormatFmt(sql, std::forward<Args>(args)...));
return Query(Acore::StringFormat(sql, std::forward<Args>(args)...));
}
//! Directly executes an SQL query in prepared format that will block the calling thread until finished.
@@ -441,6 +441,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT, "INSERT INTO character_achievement (guid, achievement, date) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA, "DELETE FROM character_achievement_progress WHERE guid = ? AND criteria = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS, "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES, "INSERT INTO character_achievement_offline_updates (guid, update_type, arg1, arg2, arg3) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES, "SELECT update_type, arg1, arg2, arg3 FROM character_achievement_offline_updates WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES, "DELETE FROM character_achievement_offline_updates WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_REPUTATION_BY_FACTION, "DELETE FROM character_reputation WHERE guid = ? AND faction = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_REPUTATION_BY_FACTION, "INSERT INTO character_reputation (guid, faction, standing, flags) VALUES (?, ?, ? , ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC);
@@ -365,6 +365,9 @@ enum CharacterDatabaseStatements : uint32
CHAR_INS_CHAR_ACHIEVEMENT,
CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA,
CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS,
CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES,
CHAR_SEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES,
CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES,
CHAR_DEL_CHAR_REPUTATION_BY_FACTION,
CHAR_INS_CHAR_REPUTATION_BY_FACTION,
CHAR_UPD_CHAR_ARENA_POINTS,
@@ -104,7 +104,7 @@ bool PreparedStatementTask::Execute()
template<typename T>
std::string PreparedStatementData::ToString(T value)
{
return Acore::StringFormatFmt("{}", value);
return Acore::StringFormat("{}", value);
}
template<>
+1 -1
View File
@@ -45,7 +45,7 @@ public:
template<typename... Args>
void Append(std::string_view sql, Args&&... args)
{
Append(Acore::StringFormatFmt(sql, std::forward<Args>(args)...));
Append(Acore::StringFormat(sql, std::forward<Args>(args)...));
}
[[nodiscard]] std::size_t GetSize() const { return m_queries.size(); }
+4 -4
View File
@@ -293,7 +293,7 @@ bool DBUpdater<T>::Update(DatabaseWorkerPool<T>& pool, std::string_view modulesL
auto CheckUpdateTable = [&](std::string const& tableName)
{
auto checkTable = DBUpdater<T>::Retrieve(pool, Acore::StringFormatFmt("SHOW TABLES LIKE '{}'", tableName));
auto checkTable = DBUpdater<T>::Retrieve(pool, Acore::StringFormat("SHOW TABLES LIKE '{}'", tableName));
if (!checkTable)
{
LOG_WARN("sql.updates", "> Table '{}' not exist! Try add based table", tableName);
@@ -337,7 +337,7 @@ bool DBUpdater<T>::Update(DatabaseWorkerPool<T>& pool, std::string_view modulesL
return false;
}
std::string const info = Acore::StringFormatFmt("Containing {} new and {} archived updates.", result.recent, result.archived);
std::string const info = Acore::StringFormat("Containing {} new and {} archived updates.", result.recent, result.archived);
if (!result.updated)
LOG_INFO("sql.updates", ">> {} database is up-to-date! {}", DBUpdater<T>::GetTableName(), info);
@@ -365,7 +365,7 @@ bool DBUpdater<T>::Update(DatabaseWorkerPool<T>& pool, std::vector<std::string>
auto CheckUpdateTable = [&](std::string const& tableName)
{
auto checkTable = DBUpdater<T>::Retrieve(pool, Acore::StringFormatFmt("SHOW TABLES LIKE '{}'", tableName));
auto checkTable = DBUpdater<T>::Retrieve(pool, Acore::StringFormat("SHOW TABLES LIKE '{}'", tableName));
if (!checkTable)
{
Path const temp(GetBaseFilesDirectory() + tableName + ".sql");
@@ -565,7 +565,7 @@ void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& hos
// Execute sql file
args.emplace_back("-e");
args.emplace_back(Acore::StringFormat("BEGIN; SOURCE %s; COMMIT;", path.generic_string().c_str()));
args.emplace_back(Acore::StringFormat("BEGIN; SOURCE {}; COMMIT;", path.generic_string()));
// Database
if (!database.empty())
+1 -1
View File
@@ -65,7 +65,7 @@ void PossessedAI::JustDied(Unit* /*u*/)
void PossessedAI::KilledUnit(Unit* /*victim*/)
{
// We killed a creature, disable victim's loot
//if (victim->GetTypeId() == TYPEID_UNIT)
//if (victim->IsCreature())
// victim->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
}
+1 -1
View File
@@ -613,7 +613,7 @@ void PetAI::DoAttack(Unit* target, bool chase)
if (_canMeleeAttack())
{
float angle = combatRange == 0.f && target->GetTypeId() != TYPEID_PLAYER && !target->IsPet() ? float(M_PI) : 0.f;
float angle = combatRange == 0.f && !target->IsPlayer() && !target->IsPet() ? float(M_PI) : 0.f;
float tolerance = combatRange == 0.f ? float(M_PI_4) : float(M_PI * 2);
me->GetMotionMaster()->MoveChase(target, ChaseRange(0.f, combatRange), ChaseAngle(angle, tolerance));
}
+1 -1
View File
@@ -427,7 +427,7 @@ bool NonTankTargetSelector::operator()(Unit const* target) const
if (!target)
return false;
if (_playerOnly && target->GetTypeId() != TYPEID_PLAYER)
if (_playerOnly && !target->IsPlayer())
return false;
if (Unit* currentVictim = _source->GetThreatMgr().GetCurrentVictim())
+3 -3
View File
@@ -76,7 +76,7 @@ struct DefaultTargetSelector : public Acore::unary_function<Unit*, bool>
if (target == except)
return false;
if (m_playerOnly && (target->GetTypeId() != TYPEID_PLAYER))
if (m_playerOnly && (!target->IsPlayer()))
return false;
if (m_dist > 0.0f && !me->IsWithinCombatRange(target, m_dist))
@@ -148,7 +148,7 @@ struct PowerUsersSelector : public Acore::unary_function<Unit*, bool>
if (target->getPowerType() != _power)
return false;
if (_playerOnly && target->GetTypeId() != TYPEID_PLAYER)
if (_playerOnly && !target->IsPlayer())
return false;
if (_dist > 0.0f && !_me->IsWithinCombatRange(target, _dist))
@@ -170,7 +170,7 @@ struct FarthestTargetSelector : public Acore::unary_function<Unit*, bool>
if (!_me || !target)
return false;
if (_playerOnly && target->GetTypeId() != TYPEID_PLAYER)
if (_playerOnly && !target->IsPlayer())
return false;
if (_maxDist > 0.0f && !_me->IsInRange(target, _minDist, _maxDist))
+4 -4
View File
@@ -107,7 +107,7 @@ void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/, float maxRange
Map* map = creature->GetMap();
if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
{
LOG_ERROR("entities.unit.ai", "DoZoneInCombat call for map {} that isn't a dungeon (creature entry = {})", map->GetId(), creature->GetTypeId() == TYPEID_UNIT ? creature->ToCreature()->GetEntry() : 0);
LOG_ERROR("entities.unit.ai", "DoZoneInCombat call for map {} that isn't a dungeon (creature entry = {})", map->GetId(), creature->IsCreature() ? creature->ToCreature()->GetEntry() : 0);
return;
}
@@ -175,10 +175,10 @@ void CreatureAI::MoveInLineOfSight(Unit* who)
void CreatureAI::TriggerAlert(Unit const* who) const
{
// If there's no target, or target isn't a player do nothing
if (!who || who->GetTypeId() != TYPEID_PLAYER)
if (!who || !who->IsPlayer())
return;
// If this unit isn't an NPC, is already distracted, is in combat, is confused, stunned or fleeing, do nothing
if (me->GetTypeId() != TYPEID_UNIT || me->IsEngaged() || me->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING | UNIT_STATE_DISTRACTED))
if (!me->IsCreature() || me->IsEngaged() || me->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING | UNIT_STATE_DISTRACTED))
return;
// Only alert for hostiles!
if (me->IsCivilian() || me->HasReactState(REACT_PASSIVE) || !me->IsHostileTo(who) || !me->_IsTargetAcceptable(who))
@@ -307,7 +307,7 @@ bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/)
me->LoadCreaturesAddon(true);
me->SetLootRecipient(nullptr);
me->ResetPlayerDamageReq();
me->SetLastDamagedTime(0);
me->ClearLastLeashExtensionTimePtr();
me->SetCannotReachTarget();
if (ZoneScript* zoneScript = me->GetZoneScript() ? me->GetZoneScript() : (ZoneScript*)me->GetInstanceScript())
+3
View File
@@ -220,6 +220,9 @@ public:
virtual bool OnTeleportUnreacheablePlayer(Player* /*player*/) { return false; }
// Called when an aura is removed or expires.
virtual void OnAuraRemove(AuraApplication* /*aurApp*/, AuraRemoveMode /*mode*/) { }
protected:
virtual void MoveInLineOfSight(Unit* /*who*/);
@@ -190,8 +190,7 @@ bool SummonList::IsAnyCreatureInCombat() const
}
ScriptedAI::ScriptedAI(Creature* creature) : CreatureAI(creature),
me(creature),
IsFleeing(false)
me(creature)
{
_isHeroic = me->GetMap()->IsHeroic();
_difficulty = Difficulty(me->GetMap()->GetSpawnMode());
@@ -178,7 +178,7 @@ class PlayerOrPetCheck
public:
bool operator() (WorldObject* unit) const
{
if (unit->GetTypeId() != TYPEID_PLAYER)
if (!unit->IsPlayer())
if (!unit->ToUnit()->GetOwnerGUID().IsPlayer())
return true;
@@ -279,9 +279,6 @@ struct ScriptedAI : public CreatureAI
//Pointer to creature we are manipulating
Creature* me;
//For fleeing
bool IsFleeing;
// *************
//Pure virtual functions
// *************
@@ -111,7 +111,7 @@ bool npc_escortAI::AssistPlayerInCombatAgainst(Unit* who)
}
// or if enemy is in evade mode
if (who->GetTypeId() == TYPEID_UNIT && who->ToCreature()->IsInEvadeMode())
if (who->IsCreature() && who->ToCreature()->IsInEvadeMode())
{
return false;
}
@@ -4217,7 +4217,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
{
if (!me || !unit)
return;
if (e.event.kill.playerOnly && unit->GetTypeId() != TYPEID_PLAYER)
if (e.event.kill.playerOnly && !unit->IsPlayer())
return;
if (e.event.kill.creature && unit->GetEntry() != e.event.kill.creature)
return;
@@ -4254,7 +4254,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
(hostilityMode == SmartEvent::LOSHostilityMode::NotHostile && !me->IsHostileTo(unit)) ||
(hostilityMode == SmartEvent::LOSHostilityMode::Hostile && me->IsHostileTo(unit)))
{
if (e.event.los.playerOnly && unit->GetTypeId() != TYPEID_PLAYER)
if (e.event.los.playerOnly && !unit->IsPlayer())
return;
RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax);
ProcessAction(e, unit);
@@ -4278,7 +4278,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
(hostilityMode == SmartEvent::LOSHostilityMode::NotHostile && !me->IsHostileTo(unit)) ||
(hostilityMode == SmartEvent::LOSHostilityMode::Hostile && me->IsHostileTo(unit)))
{
if (e.event.los.playerOnly && unit->GetTypeId() != TYPEID_PLAYER)
if (e.event.los.playerOnly && !unit->IsPlayer())
return;
RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax);
ProcessAction(e, unit);
@@ -5269,7 +5269,7 @@ WorldObject* SmartScript::GetLastInvoker(WorldObject* invoker) const
bool SmartScript::IsUnit(WorldObject* obj)
{
return obj && (obj->GetTypeId() == TYPEID_UNIT || obj->IsPlayer());
return obj && (obj->IsCreature() || obj->IsPlayer());
}
bool SmartScript::IsPlayer(WorldObject* obj)
@@ -5279,7 +5279,7 @@ bool SmartScript::IsPlayer(WorldObject* obj)
bool SmartScript::IsCreature(WorldObject* obj)
{
return obj && obj->GetTypeId() == TYPEID_UNIT;
return obj && obj->IsCreature();
}
bool SmartScript::IsCharmedCreature(WorldObject* obj)
@@ -5295,7 +5295,7 @@ bool SmartScript::IsCharmedCreature(WorldObject* obj)
bool SmartScript::IsGameObject(WorldObject* obj)
{
return obj && obj->GetTypeId() == TYPEID_GAMEOBJECT;
return obj && obj->IsGameObject();
}
void SmartScript::IncPhase(uint32 p)
+118 -13
View File
@@ -244,11 +244,11 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE:
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_TEAMS_SCORES:
return true; // not check correctness node indexes
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPPED_ITEM:
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_ITEM_QUALITY:
if (equipped_item.item_quality >= MAX_ITEM_QUALITY)
{
LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: {} Type: {}) for requirement ACHIEVEMENT_CRITERIA_REQUIRE_S_EQUIPED_ITEM ({}) has unknown quality state in value1 ({}), ignored.",
LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: {} Type: {}) for requirement ACHIEVEMENT_CRITERIA_REQUIRE_S_EQUIPPED_ITEM ({}) has unknown quality state in value1 ({}), ignored.",
criteria->ID, criteria->requiredType, dataType, equipped_item.item_quality);
return false;
}
@@ -304,11 +304,11 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE:
if (!target || target->GetTypeId() != TYPEID_UNIT)
if (!target || !target->IsCreature())
return false;
return target->GetEntry() == creature.id;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE:
if (!target || target->GetTypeId() != TYPEID_PLAYER)
if (!target || !target->IsPlayer())
return false;
if (classRace.class_id && classRace.class_id != target->ToPlayer()->getClass())
return false;
@@ -316,7 +316,7 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
return false;
return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE:
if (!source || source->GetTypeId() != TYPEID_PLAYER)
if (!source || !source->IsPlayer())
return false;
if (classRace.class_id && classRace.class_id != source->ToPlayer()->getClass())
return false;
@@ -324,7 +324,7 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
return false;
return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH:
if (!target || target->GetTypeId() != TYPEID_PLAYER)
if (!target || !target->IsPlayer())
return false;
return !target->HealthAbovePct(health.percent);
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD:
@@ -371,7 +371,7 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
return source->GetMap()->GetPlayersCountExceptGMs() <= map_players.maxcount;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM:
{
if (!target || target->GetTypeId() != TYPEID_PLAYER)
if (!target || !target->IsPlayer())
return false;
// DB data compatibility...
@@ -411,7 +411,7 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
}
return instance->CheckAchievementCriteriaMeet(criteria_id, source, target, miscvalue1);
}
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPPED_ITEM:
{
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscvalue1);
if (!pProto)
@@ -481,6 +481,7 @@ bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target,
AchievementMgr::AchievementMgr(Player* player)
{
_player = player;
_offlineUpdatesDelayTimer = 0;
}
AchievementMgr::~AchievementMgr()
@@ -550,6 +551,10 @@ void AchievementMgr::DeleteFromDB(ObjectGuid::LowType lowguid)
stmt->SetData(0, lowguid);
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
stmt->SetData(0, lowguid);
trans->Append(stmt);
CharacterDatabase.CommitTransaction(trans);
}
@@ -609,7 +614,7 @@ void AchievementMgr::SaveToDB(CharacterDatabaseTransaction trans)
}
}
void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult, PreparedQueryResult offlineUpdatesResult)
{
if (achievementResult)
{
@@ -669,6 +674,28 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
progress.changed = false;
} while (criteriaResult->NextRow());
}
if (offlineUpdatesResult)
{
uint32 count = 0;
do
{
Field* fields = offlineUpdatesResult->Fetch();
AchievementOfflinePlayerUpdate update;
update.updateType = static_cast<AchievementOfflinePlayerUpdateType>(fields[0].Get<uint8>());
update.arg1 = fields[1].Get<uint32>();
update.arg2 = fields[2].Get<uint32>();
update.arg3 = fields[3].Get<uint32>();
_offlineUpdatesQueue.push_back(update);
++count;
} while (offlineUpdatesResult->NextRow());
if (count > 0)
_offlineUpdatesDelayTimer = 5 * SECOND * IN_MILLISECONDS;
}
}
void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) const
@@ -884,7 +911,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS:
case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL:
case ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION:
case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS: /* FIXME: for online player only currently */
case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_DISENCHANT:
@@ -904,7 +931,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER:
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL:
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:/* FIXME: for online player only currently */
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED:
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED:
case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS:
@@ -915,7 +942,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
break;
// std case: high value at miscvalue1
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD: /* FIXME: for online player only currently */
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED:
@@ -1474,7 +1501,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
// map specific case (BG in fact) expected player targeted damage/heal
if (!unit || unit->GetTypeId() != TYPEID_PLAYER)
if (!unit || !unit->IsPlayer())
continue;
}
@@ -2158,6 +2185,22 @@ void AchievementMgr::RemoveCriteriaProgress(const AchievementCriteriaEntry* entr
_criteriaProgress.erase(criteriaProgress);
}
void AchievementMgr::Update(uint32 timeDiff)
{
if (_offlineUpdatesDelayTimer > 0)
{
if (timeDiff >= _offlineUpdatesDelayTimer)
{
_offlineUpdatesDelayTimer = 0;
ProcessOfflineUpdatesQueue();
}
else
_offlineUpdatesDelayTimer -= timeDiff;
}
UpdateTimedAchievements(timeDiff);
}
void AchievementMgr::UpdateTimedAchievements(uint32 timeDiff)
{
if (!_timedAchievements.empty())
@@ -2437,6 +2480,46 @@ CompletedAchievementMap const& AchievementMgr::GetCompletedAchievements()
return _completedAchievements;
}
void AchievementMgr::ProcessOfflineUpdatesQueue()
{
if (_offlineUpdatesQueue.empty())
return;
for (auto const& update : _offlineUpdatesQueue)
ProcessOfflineUpdate(update);
_offlineUpdatesQueue.clear();
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
stmt->SetData(0, GetPlayer()->GetGUID().GetCounter());
CharacterDatabase.Execute(stmt);
}
void AchievementMgr::ProcessOfflineUpdate(AchievementOfflinePlayerUpdate const& update)
{
switch (update.updateType)
{
case ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_COMPLETE_ACHIEVEMENT:
{
AchievementEntry const* achievement = sAchievementStore.LookupEntry(update.arg1);
ASSERT(achievement != NULL, "Not found achievement to complete for offline achievements update. Wrong arg1 ({}) value?", update.arg1);
CompletedAchievement(achievement);
break;
}
case ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_UPDATE_CRITERIA:
{
AchievementCriteriaTypes criteriaType = static_cast<AchievementCriteriaTypes>(update.arg1);
UpdateAchievementCriteria(criteriaType, update.arg2, update.arg3);
break;
}
default:
ASSERT(false, "Unknown offline achievement update type ({}) for player - {}", update.updateType, GetPlayer()->GetGUID().GetCounter());
break;
}
}
AchievementGlobalMgr* AchievementGlobalMgr::instance()
{
static AchievementGlobalMgr instance;
@@ -3054,3 +3137,25 @@ AchievementEntry const* AchievementGlobalMgr::GetAchievement(uint32 achievementI
{
return sAchievementStore.LookupEntry(achievementId);
}
void AchievementGlobalMgr::CompletedAchievementForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementEntry const* entry)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
stmt->SetData(0, playerLowGuid);
stmt->SetData(1, uint32(ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_COMPLETE_ACHIEVEMENT));
stmt->SetData(2, entry->ID);
stmt->SetData(3, 0);
stmt->SetData(4, 0);
CharacterDatabase.Execute(stmt);
}
void AchievementGlobalMgr::UpdateAchievementCriteriaForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementCriteriaTypes type, uint32 miscValue1, uint32 miscValue2)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
stmt->SetData(0, playerLowGuid);
stmt->SetData(1, uint32(ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_UPDATE_CRITERIA));
stmt->SetData(2, type);
stmt->SetData(3, miscValue1);
stmt->SetData(4, miscValue2);
CharacterDatabase.Execute(stmt);
}
+33 -4
View File
@@ -33,6 +33,20 @@ typedef std::list<AchievementEntry const*> AchievementEntryList;
typedef std::unordered_map<uint32, AchievementCriteriaEntryList> AchievementCriteriaListByAchievement;
typedef std::map<uint32, AchievementEntryList> AchievementListByReferencedId;
enum AchievementOfflinePlayerUpdateType
{
ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_COMPLETE_ACHIEVEMENT = 1,
ACHIEVEMENT_OFFLINE_PLAYER_UPDATE_TYPE_UPDATE_CRITERIA = 2
};
struct AchievementOfflinePlayerUpdate
{
AchievementOfflinePlayerUpdateType updateType;
uint32 arg1;
uint32 arg2;
uint32 arg3;
};
struct CriteriaProgress
{
uint32 counter;
@@ -62,7 +76,7 @@ enum AchievementCriteriaDataType
ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16, // holiday_id 0 event in holiday time
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17, // min_score max_score player's team win bg and opposition team have team score in range
ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT = 18, // 0 0 maker instance script call for check current criteria requirements fit
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19, // item_level item_quality for equipped item in slot to check item level and quality
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPPED_ITEM = 19, // item_level item_quality for equipped item in slot to check item level and quality
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20, // map_id 0 player must be on map with id in map_id
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21, // class_id race_id
ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 22, // N login on day of N-th Birthday
@@ -170,7 +184,7 @@ struct AchievementCriteriaData
uint32 max_score;
} bg_loss_team_score;
// ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT = 18 (no data)
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPPED_ITEM = 19
struct
{
uint32 item_level;
@@ -284,7 +298,7 @@ public:
void Reset();
static void DeleteFromDB(ObjectGuid::LowType lowguid);
void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult);
void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult, PreparedQueryResult offlineUpdatesResult);
void SaveToDB(CharacterDatabaseTransaction trans);
void ResetAchievementCriteria(AchievementCriteriaCondition condition, uint32 value, bool evenIfCriteriaComplete = false);
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = nullptr);
@@ -294,7 +308,8 @@ public:
void SendRespondInspectAchievements(Player* player) const;
[[nodiscard]] bool HasAchieved(uint32 achievementId) const;
[[nodiscard]] Player* GetPlayer() const { return _player; }
void UpdateTimedAchievements(uint32 timeDiff);
void Update(uint32 timeDiff);
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); // used for quest and scripted timed achievements
@@ -313,11 +328,23 @@ private:
bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
void BuildAllDataPacket(WorldPacket* data) const;
void UpdateTimedAchievements(uint32 timeDiff);
// Handles updates when character was offline.
void ProcessOfflineUpdate(AchievementOfflinePlayerUpdate const& update);
void ProcessOfflineUpdatesQueue();
Player* _player;
CriteriaProgressMap _criteriaProgress;
CompletedAchievementMap _completedAchievements;
typedef std::map<uint32, uint32> TimedAchievementMap;
TimedAchievementMap _timedAchievements; // Criteria id/time left in MS
// Offline updates cannot be processed while players are loading,
// as the player will not be notified of the changes.
// To ensure proper notification, introduce a delay before processing.
uint32 _offlineUpdatesDelayTimer;
std::vector<AchievementOfflinePlayerUpdate> _offlineUpdatesQueue;
};
class AchievementGlobalMgr
@@ -398,6 +425,8 @@ public:
[[nodiscard]] AchievementEntry const* GetAchievement(uint32 achievementId) const;
void CompletedAchievementForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementEntry const* entry);
void UpdateAchievementCriteriaForOfflinePlayer(ObjectGuid::LowType playerLowGuid, AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0);
private:
AchievementCriteriaDataMap _criteriaDataMap;
@@ -318,10 +318,14 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, CharacterDatabas
{
if (sendNotification) // can be changed in the hook
bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, auction->bidder, 0, 0, auction->item_template);
// FIXME: for offline player need also
if (updateAchievementCriteria) // can be changed in the hook
bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);
}
else if (updateAchievementCriteria)
{
sAchievementMgr->UpdateAchievementCriteriaForOfflinePlayer(auction->bidder.GetCounter(), ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1);
}
if (sendMail) // can be changed in the hook
MailDraft(auction->BuildAuctionMailSubject(AUCTION_WON), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout))
@@ -375,6 +379,11 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, Character
if (sendNotification) // can be changed in the hook
owner->GetSession()->SendAuctionOwnerNotification(auction);
}
else if (updateAchievementCriteria)
{
sAchievementMgr->UpdateAchievementCriteriaForOfflinePlayer(auction->owner.GetCounter(), ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit);
sAchievementMgr->UpdateAchievementCriteriaForOfflinePlayer(auction->owner.GetCounter(), ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid);
}
if (sendMail) // can be changed in the hook
MailDraft(auction->BuildAuctionMailSubject(AUCTION_SUCCESSFUL), AuctionEntry::BuildAuctionMailBody(auction->bidder, auction->bid, auction->buyout, auction->deposit, auction->GetAuctionCut()))
+3
View File
@@ -192,6 +192,9 @@ void Arena::RemovePlayerAtLeave(Player* player)
void Arena::CheckWinConditions()
{
if (!sScriptMgr->OnBeforeArenaCheckWinConditions(this))
return;
if (!GetAlivePlayersCountByTeam(TEAM_ALLIANCE) && GetPlayersCountByTeam(TEAM_HORDE))
EndBattleground(TEAM_HORDE);
else if (GetPlayersCountByTeam(TEAM_ALLIANCE) && !GetAlivePlayersCountByTeam(TEAM_HORDE))
+1 -1
View File
@@ -35,7 +35,7 @@ protected:
// For Logging purpose
std::string ToString() const override
{
return Acore::StringFormatFmt("Damage done: {}, Healing done: {}, Killing blows: {}", DamageDone, HealingDone, KillingBlows);
return Acore::StringFormat("Damage done: {}, Healing done: {}, Killing blows: {}", DamageDone, HealingDone, KillingBlows);
}
uint8 PvPTeamId;
@@ -1107,7 +1107,7 @@ void BattlegroundQueue::SendJoinMessageArenaQueue(Player* leader, GroupQueueInfo
BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
auto bgName = bg->GetName();
auto arenatype = Acore::StringFormat("%uv%u", ginfo->ArenaType, ginfo->ArenaType);
auto arenatype = Acore::StringFormat("{}v{}", ginfo->ArenaType, ginfo->ArenaType);
uint32 playersNeed = ArenaTeam::GetReqPlayersForType(ginfo->ArenaType);
uint32 q_min_level = std::min(bracketEntry->minLevel, (uint32)80);
uint32 q_max_level = std::min(bracketEntry->maxLevel, (uint32)80);
+11 -11
View File
@@ -74,13 +74,13 @@ public:
void SendNotification(uint32 strId, Args&&... args)
{
if (HasSession())
SendNotification(Acore::StringFormatFmt(GetAcoreString(strId), std::forward<Args>(args)...));
SendNotification(Acore::StringFormat(GetAcoreString(strId), std::forward<Args>(args)...));
}
template<typename... Args>
void SendNotification(char const* fmt, Args&&... args)
{
if (HasSession())
SendNotification(Acore::StringFormatFmt(fmt, std::forward<Args>(args)...));
SendNotification(Acore::StringFormat(fmt, std::forward<Args>(args)...));
}
void SendGMText(std::string_view str);
@@ -91,7 +91,7 @@ public:
DoForAllValidSessions([&](Player* player)
{
m_session = player->GetSession();
SendGMText(Acore::StringFormatFmt(GetAcoreString(strId), std::forward<Args>(args)...));
SendGMText(Acore::StringFormat(GetAcoreString(strId), std::forward<Args>(args)...));
});
}
template<typename... Args>
@@ -101,7 +101,7 @@ public:
DoForAllValidSessions([&](Player* player)
{
m_session = player->GetSession();
SendGMText(Acore::StringFormatFmt(fmt, std::forward<Args>(args)...));
SendGMText(Acore::StringFormat(fmt, std::forward<Args>(args)...));
});
}
@@ -113,7 +113,7 @@ public:
DoForAllValidSessions([&](Player* player)
{
m_session = player->GetSession();
SendWorldText(Acore::StringFormatFmt(GetAcoreString(strId), std::forward<Args>(args)...));
SendWorldText(Acore::StringFormat(GetAcoreString(strId), std::forward<Args>(args)...));
});
}
template<typename... Args>
@@ -123,7 +123,7 @@ public:
DoForAllValidSessions([&](Player* player)
{
m_session = player->GetSession();
SendWorldText(Acore::StringFormatFmt(fmt, std::forward<Args>(args)...));
SendWorldText(Acore::StringFormat(fmt, std::forward<Args>(args)...));
});
}
@@ -135,7 +135,7 @@ public:
DoForAllValidSessions([&](Player* player)
{
m_session = player->GetSession();
SendWorldTextOptional(Acore::StringFormatFmt(GetAcoreString(strId), std::forward<Args>(args)...), flag);
SendWorldTextOptional(Acore::StringFormat(GetAcoreString(strId), std::forward<Args>(args)...), flag);
});
}
template<typename... Args>
@@ -145,7 +145,7 @@ public:
DoForAllValidSessions([&](Player* player)
{
m_session = player->GetSession();
SendWorldTextOptional(Acore::StringFormatFmt(fmt, std::forward<Args>(args)...), flag);
SendWorldTextOptional(Acore::StringFormat(fmt, std::forward<Args>(args)...), flag);
});
}
@@ -160,7 +160,7 @@ public:
void PSendSysMessage(char const* fmt, Args&&... args)
{
if (HasSession())
SendSysMessage(Acore::StringFormatFmt(fmt, std::forward<Args>(args)...));
SendSysMessage(Acore::StringFormat(fmt, std::forward<Args>(args)...));
}
template<typename... Args>
@@ -173,7 +173,7 @@ public:
template<typename... Args>
std::string PGetParseString(uint32 entry, Args&&... args) const
{
return Acore::StringFormatFmt(GetAcoreString(entry), std::forward<Args>(args)...);
return Acore::StringFormat(GetAcoreString(entry), std::forward<Args>(args)...);
}
std::string const* GetModuleString(std::string module, uint32 id) const;
@@ -188,7 +188,7 @@ public:
template<typename... Args>
std::string PGetParseModuleString(std::string module, uint32 id, Args&&... args) const
{
return Acore::StringFormatFmt(GetModuleString(module, id)->c_str(), std::forward<Args>(args)...);
return Acore::StringFormat(GetModuleString(module, id)->c_str(), std::forward<Args>(args)...);
}
void SendErrorMessage(uint32 entry);
@@ -175,7 +175,7 @@ static void LogCommandUsage(WorldSession const& session, std::string_view cmdStr
zoneName = zone->area_name[locale];
}
std::string logMessage = Acore::StringFormatFmt("Command: {} [Player: {} ({}) (Account: {}) X: {} Y: {} Z: {} Map: {} ({}) Area: {} ({}) Zone: {} ({}) Selected: {} ({})]",
std::string logMessage = Acore::StringFormat("Command: {} [Player: {} ({}) (Account: {}) X: {} Y: {} Z: {} Map: {} ({}) Area: {} ({}) Zone: {} ({}) Selected: {} ({})]",
cmdStr, player->GetName(), player->GetGUID().ToString(),
session.GetAccountId(),
player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(),
@@ -443,11 +443,11 @@ namespace Acore::Impl::ChatCommands
{
if (prefix.empty())
{
return Acore::StringFormatFmt("{}{}{}", match, COMMAND_DELIMITER, suffix);
return Acore::StringFormat("{}{}{}", match, COMMAND_DELIMITER, suffix);
}
else
{
return Acore::StringFormatFmt("{}{}{}{}{}", prefix, COMMAND_DELIMITER, match, COMMAND_DELIMITER, suffix);
return Acore::StringFormat("{}{}{}{}{}", prefix, COMMAND_DELIMITER, match, COMMAND_DELIMITER, suffix);
}
});
@@ -465,7 +465,7 @@ namespace Acore::Impl::ChatCommands
path.assign(it1->first);
else
{
path = Acore::StringFormatFmt("{}{}{}", path, COMMAND_DELIMITER, it1->first);
path = Acore::StringFormat("{}{}{}", path, COMMAND_DELIMITER, it1->first);
}
cmd = &it1->second;
map = &cmd->_subCommands;
@@ -477,7 +477,7 @@ namespace Acore::Impl::ChatCommands
{ /* there is some trailing text, leave it as is */
if (cmd)
{ /* if we matched a command at some point, auto-complete it */
return { Acore::StringFormatFmt("{}{}{}", path, COMMAND_DELIMITER, oldTail) };
return { Acore::StringFormat("{}{}{}", path, COMMAND_DELIMITER, oldTail) };
}
else
return {};
@@ -490,7 +490,7 @@ namespace Acore::Impl::ChatCommands
return std::string(match);
else
{
return Acore::StringFormatFmt("{}{}{}", prefix, COMMAND_DELIMITER, match);
return Acore::StringFormat("{}{}{}", prefix, COMMAND_DELIMITER, match);
}
});
@@ -91,7 +91,7 @@ namespace Acore::Impl::ChatCommands
return result2;
if (result1.HasErrorMessage() && result2.HasErrorMessage())
{
return Acore::StringFormatFmt("{} \"{}\"\n{} \"{}\"",
return Acore::StringFormat("{} \"{}\"\n{} \"{}\"",
GetAcoreString(handler, LANG_CMDPARSER_EITHER), result2.GetErrorMessage(),
GetAcoreString(handler, LANG_CMDPARSER_OR), result1.GetErrorMessage());
}
@@ -273,9 +273,9 @@ namespace Acore::Impl::ChatCommands
if (!nestedResult.HasErrorMessage())
return thisResult;
if (StringStartsWith(nestedResult.GetErrorMessage(), "\""))
return Acore::StringFormat("\"%s\"\n%s %s", thisResult.GetErrorMessage().c_str(), GetAcoreString(handler, LANG_CMDPARSER_OR), nestedResult.GetErrorMessage().c_str());
return Acore::StringFormat("\"{}\"\n{} {}", thisResult.GetErrorMessage(), GetAcoreString(handler, LANG_CMDPARSER_OR), nestedResult.GetErrorMessage());
else
return Acore::StringFormat("\"%s\"\n%s \"%s\"", thisResult.GetErrorMessage().c_str(), GetAcoreString(handler, LANG_CMDPARSER_OR), nestedResult.GetErrorMessage().c_str());
return Acore::StringFormat("\"{}\"\n{} \"{}\"", thisResult.GetErrorMessage(), GetAcoreString(handler, LANG_CMDPARSER_OR), nestedResult.GetErrorMessage());
}
}
else
@@ -286,7 +286,7 @@ namespace Acore::Impl::ChatCommands
{
ChatCommandResult result = TryAtIndex<0>(val, handler, args);
if (result.HasErrorMessage() && (result.GetErrorMessage().find('\n') != std::string::npos))
return Acore::StringFormat("%s %s", GetAcoreString(handler, LANG_CMDPARSER_EITHER), result.GetErrorMessage().c_str());
return Acore::StringFormat("{} {}", GetAcoreString(handler, LANG_CMDPARSER_EITHER), result.GetErrorMessage());
return result;
}
};
@@ -125,7 +125,7 @@ namespace Acore::Impl::ChatCommands
template <typename... Ts>
std::string FormatAcoreString(ChatHandler const* handler, AcoreStrings which, Ts&&... args)
{
return Acore::StringFormatFmt(GetAcoreString(handler, which), std::forward<Ts>(args)...);
return Acore::StringFormat(GetAcoreString(handler, which), std::forward<Ts>(args)...);
}
}
+2 -2
View File
@@ -81,7 +81,7 @@ bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellIn
if (threatSpell && threatSpell->HasAttribute(SPELL_ATTR1_NO_THREAT))
return false;
ASSERT(hatingUnit->GetTypeId() == TYPEID_UNIT);
ASSERT(hatingUnit->IsCreature());
return true;
}
@@ -190,7 +190,7 @@ void HostileReference::updateOnlineStatus()
// target is no player or not gamemaster
// target is not in flight
if (isValid()
&& (getTarget()->GetTypeId() != TYPEID_PLAYER || !getTarget()->ToPlayer()->IsGameMaster())
&& (!getTarget()->IsPlayer() || !getTarget()->ToPlayer()->IsGameMaster())
&& !getTarget()->IsInFlight()
&& getTarget()->IsInMap(GetSourceUnit())
&& getTarget()->InSamePhase(GetSourceUnit())
+1 -1
View File
@@ -326,7 +326,7 @@ namespace DisableMgr
if (unit)
{
if ((spellFlags & SPELL_DISABLE_PLAYER && unit->IsPlayer()) ||
(unit->GetTypeId() == TYPEID_UNIT && ((unit->IsPet() && spellFlags & SPELL_DISABLE_PET) || spellFlags & SPELL_DISABLE_CREATURE)))
(unit->IsCreature() && ((unit->IsPet() && spellFlags & SPELL_DISABLE_PET) || spellFlags & SPELL_DISABLE_CREATURE)))
{
if (spellFlags & SPELL_DISABLE_MAP)
{
+42 -34
View File
@@ -220,9 +220,6 @@ bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
if (Unit* victim = ObjectAccessor::GetUnit(*m_owner, m_victim))
{
// Initialize last damage timer if it doesn't exist
m_owner->SetLastDamagedTime(GameTime::GetGameTime().count() + MAX_AGGRO_RESET_TIME);
while (!m_assistants.empty())
{
Creature* assistant = ObjectAccessor::GetCreature(*m_owner, *m_assistants.begin());
@@ -233,9 +230,14 @@ bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
assistant->SetNoCallAssistance(true);
assistant->CombatStart(victim);
if (assistant->IsAIEnabled)
{
assistant->AI()->AttackStart(victim);
assistant->SetLastDamagedTimePtr(m_owner->GetLastDamagedTimePtr());
// When nearby mobs aggro from another mob's initial call for assistance
// their leash timers become linked and attacking one will keep the rest from evading.
if (assistant->GetVictim())
assistant->SetLastLeashExtensionTimePtr(m_owner->GetLastLeashExtensionTimePtr());
}
}
}
}
@@ -272,7 +274,7 @@ Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(),
m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_regenPower(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_moveInLineOfSightDisabled(false), m_moveInLineOfSightStrictlyDisabled(false),
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), _lastDamagedTime(nullptr), m_cannotReachTimer(0),
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_lastLeashExtensionTime(nullptr), m_cannotReachTimer(0),
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0), _playerDamageReq(0), _damagedByPlayer(false), _isCombatMovementAllowed(true)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
@@ -1905,7 +1907,7 @@ bool Creature::CanStartAttack(Unit const* who) const
return false;
// This set of checks is should be done only for creatures
if ((IsImmuneToNPC() && who->GetTypeId() != TYPEID_PLAYER) || // flag is valid only for non player characters
if ((IsImmuneToNPC() && !who->IsPlayer()) || // flag is valid only for non player characters
(IsImmuneToPC() && who->IsPlayer())) // immune to PC and target is a player, return false
{
return false;
@@ -1916,7 +1918,7 @@ bool Creature::CanStartAttack(Unit const* who) const
return false;
// Do not attack non-combat pets
if (who->GetTypeId() == TYPEID_UNIT && who->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET)
if (who->IsCreature() && who->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET)
return false;
if (!CanFly() && (GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE + m_CombatDistance)) // too much Z difference, skip very costy vmap calculations here
@@ -1962,8 +1964,6 @@ void Creature::setDeathState(DeathState state, bool despawn)
if (state == DeathState::JustDied)
{
_lastDamagedTime.reset();
m_corpseRemoveTime = GameTime::GetGameTime().count() + m_corpseDelay;
m_respawnTime = GameTime::GetGameTime().count() + m_respawnDelay + m_corpseDelay;
@@ -2499,7 +2499,7 @@ bool Creature::CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction /
return false;
// pussywizard: or if enemy is in evade mode
if (enemy && enemy->GetTypeId() == TYPEID_UNIT && enemy->ToCreature()->IsInEvadeMode())
if (enemy && enemy->IsCreature() && enemy->ToCreature()->IsInEvadeMode())
return false;
// we don't need help from non-combatant ;)
@@ -2637,11 +2637,11 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool skipDistCheck) const
return false;
// pussywizard: or if enemy is in evade mode
if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
if (victim->IsCreature() && victim->ToCreature()->IsInEvadeMode())
return false;
// cannot attack if is during 5 second grace period, unless being attacked
if (m_respawnedTime && (GameTime::GetGameTime().count() - m_respawnedTime) < 5 && !GetLastDamagedTime())
if (m_respawnedTime && (GameTime::GetGameTime().count() - m_respawnedTime) < 5 && !IsEngagedBy(victim))
{
return false;
}
@@ -2657,9 +2657,15 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool skipDistCheck) const
if (GetMap()->IsDungeon())
return true;
float visibility = std::max<float>(GetVisibilityRange(), victim->GetVisibilityRange());
// if outside visibility
if (!IsWithinDist(victim, visibility))
return false;
// pussywizard: don't check distance to home position if recently damaged (allow kiting away from spawnpoint!)
// xinef: this should include taunt auras
if (!isWorldBoss() && (GetLastDamagedTime() > GameTime::GetGameTime().count() || HasAuraType(SPELL_AURA_MOD_TAUNT)))
if (!isWorldBoss() && (GetLastLeashExtensionTime() + 12 > GameTime::GetGameTime().count() || HasAuraType(SPELL_AURA_MOD_TAUNT)))
return true;
}
@@ -2667,10 +2673,13 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool skipDistCheck) const
return true;
// xinef: added size factor for huge npcs
float dist = std::min<float>(GetMap()->GetVisibilityRange() + GetObjectSize() * 2, 150.0f);
float dist = std::min<float>(GetDetectionRange() + GetObjectSize() * 2, 150.0f);
if (Unit* unit = GetCharmerOrOwner())
{
dist = std::min<float>(GetMap()->GetVisibilityRange() + GetObjectSize() * 2, 150.0f);
return victim->IsWithinDist(unit, dist);
}
else
{
// to prevent creatures in air ignore attacks because distance is already too high...
@@ -3030,8 +3039,11 @@ std::string Creature::GetScriptName() const
uint32 Creature::GetScriptId() const
{
if (CreatureData const* creatureData = GetCreatureData())
if (uint32 scriptId = creatureData->ScriptId)
{
uint32 scriptId = creatureData->ScriptId;
if (scriptId && GetEntry() == creatureData->id1)
return scriptId;
}
return sObjectMgr->GetCreatureTemplate(GetEntry())->ScriptID;
}
@@ -3664,35 +3676,31 @@ bool Creature::IsNotReachableAndNeedRegen() const
return false;
}
time_t Creature::GetLastDamagedTime() const
std::shared_ptr<time_t> const& Creature::GetLastLeashExtensionTimePtr() const
{
if (!_lastDamagedTime)
return time_t(0);
return *_lastDamagedTime;
if (m_lastLeashExtensionTime == nullptr)
m_lastLeashExtensionTime = std::make_shared<time_t>(time(nullptr));
return m_lastLeashExtensionTime;
}
std::shared_ptr<time_t> const& Creature::GetLastDamagedTimePtr() const
void Creature::SetLastLeashExtensionTimePtr(std::shared_ptr<time_t> const& timer)
{
return _lastDamagedTime;
m_lastLeashExtensionTime = timer;
}
void Creature::SetLastDamagedTime(time_t val)
void Creature::ClearLastLeashExtensionTimePtr()
{
if (val > 0)
{
if (_lastDamagedTime)
*_lastDamagedTime = val;
else
_lastDamagedTime = std::make_shared<time_t>(val);
}
else
_lastDamagedTime.reset();
m_lastLeashExtensionTime.reset();
}
void Creature::SetLastDamagedTimePtr(std::shared_ptr<time_t> const& val)
time_t Creature::GetLastLeashExtensionTime() const
{
_lastDamagedTime = val;
return *GetLastLeashExtensionTimePtr();
}
void Creature::UpdateLeashExtensionTime()
{
(*GetLastLeashExtensionTimePtr()) = time(nullptr);
}
bool Creature::CanPeriodicallyCallForAssistance() const
+8 -5
View File
@@ -381,10 +381,11 @@ public:
[[nodiscard]] bool IsMovementPreventedByCasting() const override;
// Part of Evade mechanics
[[nodiscard]] time_t GetLastDamagedTime() const;
[[nodiscard]] std::shared_ptr<time_t> const& GetLastDamagedTimePtr() const;
void SetLastDamagedTime(time_t val);
void SetLastDamagedTimePtr(std::shared_ptr<time_t> const& val);
std::shared_ptr<time_t> const& GetLastLeashExtensionTimePtr() const;
void SetLastLeashExtensionTimePtr(std::shared_ptr<time_t> const& timer);
void ClearLastLeashExtensionTimePtr();
time_t GetLastLeashExtensionTime() const;
void UpdateLeashExtensionTime();
bool IsFreeToMove();
static constexpr uint32 MOVE_CIRCLE_CHECK_INTERVAL = 3000;
@@ -500,7 +501,9 @@ private:
CreatureGroup* m_formation;
bool TriggerJustRespawned;
mutable std::shared_ptr<time_t> _lastDamagedTime; // Part of Evade mechanics
// Shared timer between mobs who assist another.
// Damaging one extends leash range on all of them.
mutable std::shared_ptr<time_t> m_lastLeashExtensionTime;
ObjectGuid m_cannotReachTarget;
uint32 m_cannotReachTimer;
@@ -465,7 +465,7 @@ struct VendorItem
uint32 ExtendedCost;
//helpers
bool IsGoldRequired(ItemTemplate const* pProto) const { return pProto->Flags2 & ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD || !ExtendedCost; }
bool IsGoldRequired(ItemTemplate const* pProto) const { return pProto->HasFlag2(ITEM_FLAG2_DONT_IGNORE_BUY_PRICE) || !ExtendedCost; }
};
typedef std::vector<VendorItem*> VendorItemList;
@@ -254,14 +254,14 @@ void TempSummon::InitSummon()
WorldObject* owner = GetSummoner();
if (owner)
{
if (owner->GetTypeId() == TYPEID_UNIT)
if (owner->IsCreature())
{
if (owner->ToCreature()->IsAIEnabled)
{
owner->ToCreature()->AI()->JustSummoned(this);
}
}
else if (owner->GetTypeId() == TYPEID_GAMEOBJECT)
else if (owner->IsGameObject())
{
if (owner->ToGameObject()->AI())
{
@@ -304,11 +304,11 @@ void TempSummon::UnSummon(uint32 msTime)
if (WorldObject* owner = GetSummoner())
{
if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->IsAIEnabled)
if (owner->IsCreature() && owner->ToCreature()->IsAIEnabled)
{
owner->ToCreature()->AI()->SummonedCreatureDespawn(this);
}
else if (owner->GetTypeId() == TYPEID_GAMEOBJECT && owner->ToGameObject()->AI())
else if (owner->IsGameObject() && owner->ToGameObject()->AI())
{
owner->ToGameObject()->AI()->SummonedCreatureDespawn(this);
}
@@ -1280,7 +1280,7 @@ bool GameObject::IsAlwaysVisibleFor(WorldObject const* seer) const
Unit* owner = GetOwner();
if (owner)
{
if (seer->isType(TYPEMASK_UNIT) && owner->IsFriendlyTo(seer->ToUnit()))
if (seer->IsUnit() && owner->IsFriendlyTo(seer->ToUnit()))
return true;
}
}
@@ -1521,7 +1521,7 @@ void GameObject::Use(Unit* user)
return;
case GAMEOBJECT_TYPE_QUESTGIVER: //2
{
if (user->GetTypeId() != TYPEID_PLAYER)
if (!user->IsPlayer())
return;
Player* player = user->ToPlayer();
@@ -1550,7 +1550,7 @@ void GameObject::Use(Unit* user)
if (!info)
return;
if (user->GetTypeId() != TYPEID_PLAYER)
if (!user->IsPlayer())
return;
if (ChairListSlots.empty()) // this is called once at first chair use to make list of available slots
@@ -1717,7 +1717,7 @@ void GameObject::Use(Unit* user)
if (!info)
return;
if (user->GetTypeId() != TYPEID_PLAYER)
if (!user->IsPlayer())
return;
Player* player = user->ToPlayer();
@@ -1818,7 +1818,7 @@ void GameObject::Use(Unit* user)
case GAMEOBJECT_TYPE_SUMMONING_RITUAL: //18
{
if (user->GetTypeId() != TYPEID_PLAYER)
if (!user->IsPlayer())
return;
Player* player = user->ToPlayer();
@@ -1831,7 +1831,7 @@ void GameObject::Use(Unit* user)
if (owner)
{
if (owner->GetTypeId() != TYPEID_PLAYER)
if (!owner->IsPlayer())
return;
// accept only use by player from same group as owner, excluding owner itself (unique use already added in spell effect)
@@ -1885,21 +1885,30 @@ void GameObject::Use(Unit* user)
if (info->spellcaster.partyOnly)
{
Player const* caster = ObjectAccessor::FindConnectedPlayer(GetOwnerGUID());
if (!caster || user->GetTypeId() != TYPEID_PLAYER || !user->ToPlayer()->IsInSameRaidWith(caster))
if (!user->IsPlayer())
return;
if (ObjectGuid ownerGuid = GetOwnerGUID())
{
if (user->GetGUID() != ownerGuid)
{
Group* group = user->ToPlayer()->GetGroup();
if (!group)
return;
if (!group->IsMember(ownerGuid))
return;
}
}
}
user->RemoveAurasByType(SPELL_AURA_MOUNTED);
spellId = info->spellcaster.spellId;
break;
}
case GAMEOBJECT_TYPE_MEETINGSTONE: //23
{
GameObjectTemplate const* info = GetGOInfo();
if (user->GetTypeId() != TYPEID_PLAYER)
if (!user->IsPlayer())
return;
Player* player = user->ToPlayer();
@@ -1925,7 +1934,7 @@ void GameObject::Use(Unit* user)
case GAMEOBJECT_TYPE_FLAGSTAND: // 24
{
if (user->GetTypeId() != TYPEID_PLAYER)
if (!user->IsPlayer())
return;
Player* player = user->ToPlayer();
@@ -1957,7 +1966,7 @@ void GameObject::Use(Unit* user)
case GAMEOBJECT_TYPE_FISHINGHOLE: // 25
{
if (user->GetTypeId() != TYPEID_PLAYER)
if (!user->IsPlayer())
return;
Player* player = user->ToPlayer();
@@ -1969,7 +1978,7 @@ void GameObject::Use(Unit* user)
case GAMEOBJECT_TYPE_FLAGDROP: // 26
{
if (user->GetTypeId() != TYPEID_PLAYER)
if (!user->IsPlayer())
return;
Player* player = user->ToPlayer();
@@ -2027,7 +2036,7 @@ void GameObject::Use(Unit* user)
if (!info)
return;
if (user->GetTypeId() != TYPEID_PLAYER)
if (!user->IsPlayer())
return;
Player* player = user->ToPlayer();
@@ -2054,7 +2063,7 @@ void GameObject::Use(Unit* user)
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
if (user->GetTypeId() != TYPEID_PLAYER || !sOutdoorPvPMgr->HandleCustomSpell(user->ToPlayer(), spellId, this))
if (!user->IsPlayer() || !sOutdoorPvPMgr->HandleCustomSpell(user->ToPlayer(), spellId, this))
LOG_ERROR("entities.gameobject", "WORLD: unknown spell id {} at use action for gameobject (Entry: {} GoType: {})", spellId, GetEntry(), GetGoType());
else
LOG_DEBUG("outdoorpvp", "WORLD: {} non-dbc spell was handled by OutdoorPvP", spellId);
+6 -6
View File
@@ -379,7 +379,7 @@ void Item::SaveToDB(CharacterDatabaseTransaction trans)
trans->Append(stmt);
if ((uState == ITEM_CHANGED) && HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED))
if ((uState == ITEM_CHANGED) && IsWrapped())
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GIFT_OWNER);
stmt->SetData(0, GetOwnerGUID().GetCounter());
@@ -394,7 +394,7 @@ void Item::SaveToDB(CharacterDatabaseTransaction trans)
stmt->SetData(0, guid);
trans->Append(stmt);
if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED))
if (IsWrapped())
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
stmt->SetData(0, guid);
@@ -493,7 +493,7 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid owner_guid, Field* fi
// update max durability (and durability) if need
// xinef: do not overwrite durability for wrapped items!!
SetUInt32Value(ITEM_FIELD_MAXDURABILITY, proto->MaxDurability);
if (durability > proto->MaxDurability && !HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED))
if (durability > proto->MaxDurability && !IsWrapped())
{
SetUInt32Value(ITEM_FIELD_DURABILITY, proto->MaxDurability);
need_save = true;
@@ -794,7 +794,7 @@ bool Item::IsEquipped() const
bool Item::CanBeTraded(bool mail, bool trade) const
{
if ((!mail || !IsBoundAccountWide()) && (IsSoulBound() && (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE) || !trade)))
if ((!mail || !IsBoundAccountWide()) && (IsSoulBound() && (!IsBOPTradable() || !trade)))
return false;
if (IsBag() && (Player::IsBagPos(GetPos()) || !((Bag const*)this)->IsEmpty()))
@@ -1141,7 +1141,7 @@ bool Item::IsBindedNotWith(Player const* player) const
if (GetOwnerGUID() == player->GetGUID())
return false;
if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE))
if (IsBOPTradable())
if (allowedGUIDs.find(player->GetGUID()) != allowedGUIDs.end())
return false;
@@ -1201,7 +1201,7 @@ void Item::DeleteRefundDataFromDB(CharacterDatabaseTransaction* trans)
void Item::SetNotRefundable(Player* owner, bool changestate /*=true*/, CharacterDatabaseTransaction* trans /*=nullptr*/)
{
if (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE))
if (!IsRefundable())
return;
RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE);
+4 -1
View File
@@ -234,7 +234,7 @@ public:
void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_SOULBOUND, val); }
[[nodiscard]] bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_SOULBOUND); }
[[nodiscard]] bool IsBoundAccountWide() const { return (GetTemplate()->Flags & ITEM_FLAG_IS_BOUND_TO_ACCOUNT) != 0; }
[[nodiscard]] bool IsBoundAccountWide() const { return GetTemplate()->HasFlag(ITEM_FLAG_IS_BOUND_TO_ACCOUNT) != 0; }
bool IsBindedNotWith(Player const* player) const;
[[nodiscard]] bool IsBoundByEnchant() const;
[[nodiscard]] bool IsBoundByTempEnchant() const;
@@ -258,6 +258,9 @@ public:
[[nodiscard]] bool CanBeTraded(bool mail = false, bool trade = false) const;
void SetInTrade(bool b = true) { mb_in_trade = b; }
[[nodiscard]] bool IsInTrade() const { return mb_in_trade; }
[[nodiscard]] bool IsRefundable() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE); }
[[nodiscard]] bool IsBOPTradable() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE); }
[[nodiscard]] bool IsWrapped() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED); }
bool HasEnchantRequiredSkill(Player const* player) const;
[[nodiscard]] uint32 GetEnchantRequiredLevel() const;
@@ -21,6 +21,7 @@
#include "Log.h"
#include "ObjectMgr.h"
#include "Util.h"
#include <cmath>
#include <functional>
#include <vector>
@@ -105,7 +106,7 @@ uint32 GetItemEnchantMod(int32 entry)
}
//we could get here only if sum of all enchantment chances is lower than 100%
dRoll = (irand(0, (int)floor(fCount * 100) + 1)) / 100;
dRoll = (irand(0, (int)std::floor(fCount * 100) + 1)) / 100;
fCount = 0;
for (EnchStoreList::const_iterator ench_iter = tab->second.begin(); ench_iter != tab->second.end(); ++ench_iter)
+47 -51
View File
@@ -94,7 +94,7 @@ enum ItemBondingType
{
NO_BIND = 0,
BIND_WHEN_PICKED_UP = 1,
BIND_WHEN_EQUIPED = 2,
BIND_WHEN_EQUIPPED = 2,
BIND_WHEN_USE = 3,
BIND_QUEST_ITEM = 4,
BIND_QUEST_ITEM1 = 5 // not used in game
@@ -152,30 +152,30 @@ enum ItemFlags : uint32
ITEM_FLAG_NO_USER_DESTROY = 0x00000020, // Item can not be destroyed, except by using spell (item can be reagent for spell)
ITEM_FLAG_PLAYERCAST = 0x00000040, // Item's spells are castable by players
ITEM_FLAG_NO_EQUIP_COOLDOWN = 0x00000080, // No default 30 seconds cooldown when equipped
ITEM_FLAG_MULTI_LOOT_QUEST = 0x00000100,
ITEM_FLAG_MULTI_LOOT_QUEST = 0x00000100, // NYI
ITEM_FLAG_IS_WRAPPER = 0x00000200, // Item can wrap other items
ITEM_FLAG_USES_RESOURCES = 0x00000400,
ITEM_FLAG_USES_RESOURCES = 0x00000400, // NYI
ITEM_FLAG_MULTI_DROP = 0x00000800, // Looting this item does not remove it from available loot
ITEM_FLAG_ITEM_PURCHASE_RECORD = 0x00001000, // Item can be returned to vendor for its original cost (extended cost)
ITEM_FLAG_PETITION = 0x00002000, // Item is guild or arena charter
ITEM_FLAG_HAS_TEXT = 0x00004000, // Only readable items have this (but not all)
ITEM_FLAG_NO_DISENCHANT = 0x00008000,
ITEM_FLAG_REAL_DURATION = 0x00010000,
ITEM_FLAG_NO_DISENCHANT = 0x00008000, // NYI
ITEM_FLAG_REAL_DURATION = 0x00010000, // NYI
ITEM_FLAG_NO_CREATOR = 0x00020000,
ITEM_FLAG_IS_PROSPECTABLE = 0x00040000, // Item can be prospected
ITEM_FLAG_UNIQUE_EQUIPPABLE = 0x00080000, // You can only equip one of these
ITEM_FLAG_IGNORE_FOR_AURAS = 0x00100000,
ITEM_FLAG_IGNORE_FOR_AURAS = 0x00100000, // NYI
ITEM_FLAG_IGNORE_DEFAULT_ARENA_RESTRICTIONS = 0x00200000, // Item can be used during arena match
ITEM_FLAG_NO_DURABILITY_LOSS = 0x00400000, // Some Thrown weapons have it (and only Thrown) but not all
ITEM_FLAG_USE_WHEN_SHAPESHIFTED = 0x00800000, // Item can be used in shapeshift forms
ITEM_FLAG_HAS_QUEST_GLOW = 0x01000000,
ITEM_FLAG_HAS_QUEST_GLOW = 0x01000000, // NYI
ITEM_FLAG_HIDE_UNUSABLE_RECIPE = 0x02000000, // Profession recipes: can only be looted if you meet requirements and don't already know it
ITEM_FLAG_NOT_USEABLE_IN_ARENA = 0x04000000, // Item cannot be used in arena
ITEM_FLAG_IS_BOUND_TO_ACCOUNT = 0x08000000, // Item binds to account and can be sent only to your own characters
ITEM_FLAG_NO_REAGENT_COST = 0x10000000, // Spell is cast ignoring reagents
ITEM_FLAG_IS_MILLABLE = 0x20000000, // Item can be milled
ITEM_FLAG_REPORT_TO_GUILD_CHAT = 0x40000000,
ITEM_FLAG_NO_PROGRESSIVE_LOOT = 0x80000000
ITEM_FLAG_REPORT_TO_GUILD_CHAT = 0x40000000, // NYI
ITEM_FLAG_NO_PROGRESSIVE_LOOT = 0x80000000 // NYI
};
enum ItemFlags2 : uint32
@@ -183,46 +183,38 @@ enum ItemFlags2 : uint32
ITEM_FLAG2_FACTION_HORDE = 0x00000001,
ITEM_FLAG2_FACTION_ALLIANCE = 0x00000002,
ITEM_FLAG2_DONT_IGNORE_BUY_PRICE = 0x00000004, // when item uses extended cost, gold is also required
ITEM_FLAG2_CLASSIFY_AS_CASTER = 0x00000008,
ITEM_FLAG2_CLASSIFY_AS_PHYSICAL = 0x00000010,
ITEM_FLAG2_EVERYONE_CAN_ROLL_NEED = 0x00000020,
ITEM_FLAG2_NO_TRADE_BIND_ON_ACQUIRE = 0x00000040,
ITEM_FLAG2_CAN_TRADE_BIND_ON_ACQUIRE = 0x00000080,
ITEM_FLAG2_CLASSIFY_AS_CASTER = 0x00000008, // NYI
ITEM_FLAG2_CLASSIFY_AS_PHYSICAL = 0x00000010, // NYI
ITEM_FLAG2_EVERYONE_CAN_ROLL_NEED = 0x00000020, // NYI
ITEM_FLAG2_NO_TRADE_BIND_ON_ACQUIRE = 0x00000040, // NYI
ITEM_FLAG2_CAN_TRADE_BIND_ON_ACQUIRE = 0x00000080, // NYI
ITEM_FLAG2_CAN_ONLY_ROLL_GREED = 0x00000100,
ITEM_FLAG2_CASTER_WEAPON = 0x00000200,
ITEM_FLAG2_DELETE_ON_LOGIN = 0x00000400,
ITEM_FLAG2_INTERNAL_ITEM = 0x00000800,
ITEM_FLAG2_NO_VENDOR_VALUE = 0x00001000,
ITEM_FLAG2_SHOW_BEFORE_DISCOVERED = 0x00002000,
ITEM_FLAG2_OVERRIDE_GOLD_COST = 0x00004000,
ITEM_FLAG2_IGNORE_DEFAULT_RATED_BG_RESTRICTIONS = 0x00008000,
ITEM_FLAG2_NOT_USABLE_IN_RATED_BG = 0x00010000,
ITEM_FLAG2_BNET_ACCOUNT_TRADE_OK = 0x00020000,
ITEM_FLAG2_CONFIRM_BEFORE_USE = 0x00040000,
ITEM_FLAG2_REEVALUATE_BONDING_ON_TRANSFORM = 0x00080000,
ITEM_FLAG2_NO_TRANSFORM_ON_CHARGE_DEPLETION = 0x00100000,
ITEM_FLAG2_NO_ALTER_ITEM_VISUAL = 0x00200000,
ITEM_FLAG2_NO_SOURCE_FOR_ITEM_VISUAL = 0x00400000,
ITEM_FLAG2_IGNORE_QUALITY_FOR_ITEM_VISUAL_SOURCE = 0x00800000,
ITEM_FLAG2_NO_DURABILITY = 0x01000000,
ITEM_FLAG2_ROLE_TANK = 0x02000000,
ITEM_FLAG2_ROLE_HEALER = 0x04000000,
ITEM_FLAG2_ROLE_DAMAGE = 0x08000000,
ITEM_FLAG2_CAN_DROP_IN_CHALLENGE_MODE = 0x10000000,
ITEM_FLAG2_NEVER_STACK_IN_LOOT_UI = 0x20000000,
ITEM_FLAG2_DISENCHANT_TO_LOOT_TABLE = 0x40000000,
ITEM_FLAG2_USED_IN_A_TRADESKILL = 0x80000000
ITEM_FLAG2_CASTER_WEAPON = 0x00000200, // NYI
ITEM_FLAG2_DELETE_ON_LOGIN = 0x00000400, // NYI
ITEM_FLAG2_INTERNAL_ITEM = 0x00000800, // NYI
ITEM_FLAG2_NO_VENDOR_VALUE = 0x00001000, // NYI
ITEM_FLAG2_SHOW_BEFORE_DISCOVERED = 0x00002000, // NYI
ITEM_FLAG2_OVERRIDE_GOLD_COST = 0x00004000, // NYI
ITEM_FLAG2_IGNORE_DEFAULT_RATED_BG_RESTRICTIONS = 0x00008000, // NYI
ITEM_FLAG2_NOT_USABLE_IN_RATED_BG = 0x00010000, // NYI
ITEM_FLAG2_BNET_ACCOUNT_TRADE_OK = 0x00020000, // NYI
ITEM_FLAG2_CONFIRM_BEFORE_USE = 0x00040000, // NYI
ITEM_FLAG2_REEVALUATE_BONDING_ON_TRANSFORM = 0x00080000, // NYI
ITEM_FLAG2_NO_TRANSFORM_ON_CHARGE_DEPLETION = 0x00100000, // NYI
ITEM_FLAG2_NO_ALTER_ITEM_VISUAL = 0x00200000, // NYI
ITEM_FLAG2_NO_SOURCE_FOR_ITEM_VISUAL = 0x00400000, // NYI
ITEM_FLAG2_IGNORE_QUALITY_FOR_ITEM_VISUAL_SOURCE = 0x00800000, // NYI
ITEM_FLAG2_NO_DURABILITY = 0x01000000, // NYI
ITEM_FLAG2_ROLE_TANK = 0x02000000, // NYI
ITEM_FLAG2_ROLE_HEALER = 0x04000000, // NYI
ITEM_FLAG2_ROLE_DAMAGE = 0x08000000, // NYI
ITEM_FLAG2_CAN_DROP_IN_CHALLENGE_MODE = 0x10000000, // NYI
ITEM_FLAG2_NEVER_STACK_IN_LOOT_UI = 0x20000000, // NYI
ITEM_FLAG2_DISENCHANT_TO_LOOT_TABLE = 0x40000000, // NYI
ITEM_FLAG2_USED_IN_A_TRADESKILL = 0x80000000 // NYI
};
enum ItemFlagsExtra
{
ITEM_FLAGS_EXTRA_HORDE_ONLY = 0x00000001,
ITEM_FLAGS_EXTRA_ALLIANCE_ONLY = 0x00000002,
ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD = 0x00000004, // when item uses extended cost, gold is also required
ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100
};
enum ItemFlagsCustom
enum ItemFlagsCustom : uint32
{
ITEM_FLAGS_CU_DURATION_REAL_TIME = 0x0001, // Item duration will tick even if player is offline
ITEM_FLAGS_CU_IGNORE_QUEST_STATUS = 0x0002, // No quest status will be checked when this item drops
@@ -632,8 +624,8 @@ struct ItemTemplate
std::string Name1;
uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc
uint32 Quality;
uint32 Flags;
uint32 Flags2;
ItemFlags Flags;
ItemFlags2 Flags2;
uint32 BuyCount;
int32 BuyPrice;
uint32 SellPrice;
@@ -699,7 +691,7 @@ struct ItemTemplate
uint32 FoodType;
uint32 MinMoneyLoot;
uint32 MaxMoneyLoot;
uint32 FlagsCu;
ItemFlagsCustom FlagsCu;
WorldPacket queryData; // pussywizard
// helpers
@@ -708,7 +700,7 @@ struct ItemTemplate
return GetMaxStackSize() == 1 &&
Class != ITEM_CLASS_CONSUMABLE &&
Class != ITEM_CLASS_QUEST &&
(Flags & ITEM_FLAG_NO_CREATOR) == 0 &&
!HasFlag(ITEM_FLAG_NO_CREATOR) &&
ItemId != 6948; /*Hearthstone*/
}
@@ -827,13 +819,17 @@ struct ItemTemplate
[[nodiscard]] bool IsPotion() const { return Class == ITEM_CLASS_CONSUMABLE && SubClass == ITEM_SUBCLASS_POTION; }
[[nodiscard]] bool IsWeaponVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT; }
[[nodiscard]] bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT; }
[[nodiscard]] bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_FLAG_CONJURED); }
[[nodiscard]] bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && HasFlag(ITEM_FLAG_CONJURED); }
[[nodiscard]] bool IsWeapon() const { return Class == ITEM_CLASS_WEAPON; }
[[nodiscard]] bool IsRangedWeapon() const { return IsWeapon() && (InventoryType == INVTYPE_RANGED || InventoryType == INVTYPE_THROWN || InventoryType == INVTYPE_RANGEDRIGHT); }
[[nodiscard]] bool HasStat(ItemModType stat) const;
[[nodiscard]] bool HasSpellPowerStat() const;
[[nodiscard]] bool HasFlag(ItemFlags flag) const { return (Flags & flag) != 0; }
[[nodiscard]] bool HasFlag2(ItemFlags2 flag) const { return (Flags2 & flag) != 0; }
[[nodiscard]] bool HasFlagCu(ItemFlagsCustom flag) const { return (FlagsCu & flag) != 0; }
void InitializeQueryData();
};
+25 -25
View File
@@ -226,7 +226,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target)
}
}
if (isType(TYPEMASK_UNIT))
if (IsUnit())
{
if (((Unit*)this)->GetVictim())
flags |= UPDATEFLAG_HAS_TARGET;
@@ -275,7 +275,7 @@ void Object::DestroyForPlayer(Player* target, bool onDeath) const
{
ASSERT(target);
if (isType(TYPEMASK_UNIT) || isType(TYPEMASK_PLAYER))
if (IsUnit() || isType(TYPEMASK_PLAYER))
{
if (Battleground* bg = target->GetBattleground())
{
@@ -345,7 +345,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
Unit const* unit = nullptr;
WorldObject const* object = nullptr;
if (isType(TYPEMASK_UNIT))
if (IsUnit())
unit = ToUnit();
else
object = ((WorldObject*)this);
@@ -1101,20 +1101,20 @@ void WorldObject::setActive(bool on)
if (on)
{
if (GetTypeId() == TYPEID_UNIT)
if (IsCreature())
map->AddToActive(this->ToCreature());
else if (IsDynamicObject())
map->AddToActive((DynamicObject*)this);
else if (GetTypeId() == TYPEID_GAMEOBJECT)
else if (IsGameObject())
map->AddToActive((GameObject*)this);
}
else
{
if (GetTypeId() == TYPEID_UNIT)
if (IsCreature())
map->RemoveFromActive(this->ToCreature());
else if (IsDynamicObject())
map->RemoveFromActive((DynamicObject*)this);
else if (GetTypeId() == TYPEID_GAMEOBJECT)
else if (IsGameObject())
map->RemoveFromActive((GameObject*)this);
}
}
@@ -1147,7 +1147,7 @@ void WorldObject::SetPositionDataUpdate()
_updatePositionData = true;
// Calls immediately for charmed units
if (GetTypeId() == TYPEID_UNIT && ToUnit()->IsCharmedOwnedByPlayerOrPlayer())
if (IsCreature() && ToUnit()->IsCharmedOwnedByPlayerOrPlayer())
UpdatePositionData();
}
@@ -1531,7 +1531,7 @@ void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
{
float new_z = GetMapHeight(x, y, z);
if (new_z > INVALID_HEIGHT)
z = new_z + (isType(TYPEMASK_UNIT) ? static_cast<Unit const*>(this)->GetHoverHeight() : 0.0f);
z = new_z + (IsUnit() ? static_cast<Unit const*>(this)->GetHoverHeight() : 0.0f);
}
/**
@@ -1634,7 +1634,7 @@ float WorldObject::GetGridActivationRange() const
{
return ToCreature()->m_SightDistance;
}
else if (((GetTypeId() == TYPEID_GAMEOBJECT && ToGameObject()->IsTransport()) || IsDynamicObject()) && isActiveObject())
else if (((IsGameObject() && ToGameObject()->IsTransport()) || IsDynamicObject()) && isActiveObject())
{
return GetMap()->GetVisibilityRange();
}
@@ -1644,11 +1644,11 @@ float WorldObject::GetGridActivationRange() const
float WorldObject::GetVisibilityRange() const
{
if (IsVisibilityOverridden() && GetTypeId() == TYPEID_UNIT)
if (IsVisibilityOverridden() && IsCreature())
{
return *m_visibilityDistanceOverride;
}
else if (GetTypeId() == TYPEID_GAMEOBJECT)
else if (IsGameObject())
{
{
if (IsInWintergrasp())
@@ -1677,11 +1677,11 @@ float WorldObject::GetSightRange(WorldObject const* target) const
{
if (target)
{
if (target->IsVisibilityOverridden() && target->GetTypeId() == TYPEID_UNIT)
if (target->IsVisibilityOverridden() && target->IsCreature())
{
return *target->m_visibilityDistanceOverride;
}
else if (target->GetTypeId() == TYPEID_GAMEOBJECT)
else if (target->IsGameObject())
{
if (IsInWintergrasp() && target->IsInWintergrasp())
{
@@ -1872,7 +1872,7 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
bool WorldObject::CanNeverSee(WorldObject const* obj) const
{
if (GetTypeId() == TYPEID_UNIT && obj->GetTypeId() == TYPEID_UNIT)
if (IsCreature() && obj->IsCreature())
return GetMap() != obj->GetMap() || (!InSamePhase(obj) && ToUnit()->GetVehicleBase() != obj && this != obj->ToUnit()->GetVehicleBase());
return GetMap() != obj->GetMap() || !InSamePhase(obj);
}
@@ -1901,7 +1901,7 @@ bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth, bool che
// xinef: ignore units players have at client, this cant be cheated!
if (checkClient)
{
if (GetTypeId() != TYPEID_PLAYER || !ToPlayer()->HaveAtClient(obj))
if (!IsPlayer() || !ToPlayer()->HaveAtClient(obj))
return false;
}
else
@@ -1992,7 +1992,7 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj, bool checkAlert) co
float distance = GetExactDist(obj);
float combatReach = 0.0f;
if (isType(TYPEMASK_UNIT))
if (IsUnit())
combatReach = ((Unit*)this)->GetCombatReach();
if (distance < combatReach)
@@ -2006,7 +2006,7 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj, bool checkAlert) co
if (!(obj->m_stealth.GetFlags() & (1 << i)))
continue;
if (isType(TYPEMASK_UNIT))
if (IsUnit())
if (((Unit*)this)->HasAuraTypeWithMiscvalue(SPELL_AURA_DETECT_STEALTH, i))
return true;
@@ -2389,7 +2389,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float
if (respawnTime)
go->SetSpellId(1);
if (IsPlayer() || (GetTypeId() == TYPEID_UNIT && summonType == GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)) //not sure how to handle this
if (IsPlayer() || (IsCreature() && summonType == GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)) //not sure how to handle this
ToUnit()->AddGameObject(go);
else
go->SetSpawnedByDefault(false);
@@ -2406,7 +2406,7 @@ Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint3
return nullptr;
//summon->SetName(GetName());
if (setLevel && (IsPlayer() || GetTypeId() == TYPEID_UNIT))
if (setLevel && (IsPlayer() || IsCreature()))
{
summon->SetFaction(((Unit*)this)->GetFaction());
summon->SetLevel(((Unit*)this)->GetLevel());
@@ -2428,9 +2428,9 @@ Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint3
*/
void WorldObject::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= nullptr*/)
{
ASSERT((GetTypeId() == TYPEID_GAMEOBJECT || GetTypeId() == TYPEID_UNIT) && "Only GOs and creatures can summon npc groups!");
ASSERT((IsGameObject() || IsCreature()) && "Only GOs and creatures can summon npc groups!");
std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetEntry(), GetTypeId() == TYPEID_GAMEOBJECT ? SUMMONER_TYPE_GAMEOBJECT : SUMMONER_TYPE_CREATURE, group);
std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetEntry(), IsGameObject() ? SUMMONER_TYPE_GAMEOBJECT : SUMMONER_TYPE_CREATURE, group);
if (!data)
return;
@@ -2742,7 +2742,7 @@ void WorldObject::GetContactPoint(WorldObject const* obj, float& x, float& y, fl
GetNearPoint(obj, x, y, z, obj->GetObjectSize(), distance2d, GetAngle(obj));
// Exclude gameobjects from LoS calculations
if (std::fabs(this->GetPositionZ() - z) > 3.0f || (GetTypeId() != TYPEID_GAMEOBJECT && !IsWithinLOS(x, y, z)))
if (std::fabs(this->GetPositionZ() - z) > 3.0f || (!IsGameObject() && !IsWithinLOS(x, y, z)))
{
x = this->GetPositionX();
y = this->GetPositionY();
@@ -2955,7 +2955,7 @@ void WorldObject::DestroyForNearbyPlayers()
if (!player->HaveAtClient(this))
continue;
if (isType(TYPEMASK_UNIT) && ((Unit*)this)->GetCharmerGUID() == player->GetGUID()) /// @todo: this is for puppet
if (IsUnit() && ((Unit*)this)->GetCharmerGUID() == player->GetGUID()) /// @todo: this is for puppet
continue;
DestroyForPlayer(player);
@@ -3123,7 +3123,7 @@ float WorldObject::GetMapHeight(float x, float y, float z, bool vmap/* = true*/,
float WorldObject::GetMapWaterOrGroundLevel(float x, float y, float z, float* ground/* = nullptr*/) const
{
return GetMap()->GetWaterOrGroundLevel(GetPhaseMask(), x, y, z, ground,
isType(TYPEMASK_UNIT) ? !static_cast<Unit const*>(this)->HasAuraType(SPELL_AURA_WATER_WALK) : false,
IsUnit() ? !static_cast<Unit const*>(this)->HasAuraType(SPELL_AURA_WATER_WALK) : false,
std::max(GetCollisionHeight(), Z_OFFSET_FIND_HEIGHT));
}
+6 -4
View File
@@ -198,11 +198,13 @@ public:
Player* ToPlayer() { if (IsPlayer()) return reinterpret_cast<Player*>(this); else return nullptr; }
[[nodiscard]] Player const* ToPlayer() const { if (IsPlayer()) return reinterpret_cast<Player const*>(this); else return nullptr; }
Creature* ToCreature() { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature*>(this); else return nullptr; }
[[nodiscard]] Creature const* ToCreature() const { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature const*>(this); else return nullptr; }
[[nodiscard]] inline bool IsCreature() const { return GetTypeId() == TYPEID_UNIT; }
Creature* ToCreature() { if (IsCreature()) return reinterpret_cast<Creature*>(this); else return nullptr; }
[[nodiscard]] Creature const* ToCreature() const { if (IsCreature()) return reinterpret_cast<Creature const*>(this); else return nullptr; }
Unit* ToUnit() { if (GetTypeId() == TYPEID_UNIT || IsPlayer()) return reinterpret_cast<Unit*>(this); else return nullptr; }
[[nodiscard]] Unit const* ToUnit() const { if (GetTypeId() == TYPEID_UNIT || IsPlayer()) return reinterpret_cast<Unit const*>(this); else return nullptr; }
[[nodiscard]] inline bool IsUnit() const { return isType(TYPEMASK_UNIT); }
Unit* ToUnit() { if (IsCreature() || IsPlayer()) return reinterpret_cast<Unit*>(this); else return nullptr; }
[[nodiscard]] Unit const* ToUnit() const { if (IsCreature() || IsPlayer()) return reinterpret_cast<Unit const*>(this); else return nullptr; }
[[nodiscard]] inline bool IsGameObject() const { return GetTypeId() == TYPEID_GAMEOBJECT; }
GameObject* ToGameObject() { if (IsGameObject()) return reinterpret_cast<GameObject*>(this); else return nullptr; }
+10 -10
View File
@@ -181,20 +181,20 @@ class ObjectGuid
{
switch (high)
{
case HighGuid::Item: return TYPEID_ITEM;
//case HighGuid::Container: return TYPEID_CONTAINER; HighGuid::Container == HighGuid::Item currently
case HighGuid::Unit: return TYPEID_UNIT;
case HighGuid::Pet: return TYPEID_UNIT;
case HighGuid::Player: return TYPEID_PLAYER;
case HighGuid::GameObject: return TYPEID_GAMEOBJECT;
case HighGuid::Item: return TYPEID_ITEM;
//case HighGuid::Container: return TYPEID_CONTAINER; HighGuid::Container == HighGuid::Item currently
case HighGuid::Unit: return TYPEID_UNIT;
case HighGuid::Pet: return TYPEID_UNIT;
case HighGuid::Player: return TYPEID_PLAYER;
case HighGuid::GameObject: return TYPEID_GAMEOBJECT;
case HighGuid::DynamicObject: return TYPEID_DYNAMICOBJECT;
case HighGuid::Corpse: return TYPEID_CORPSE;
case HighGuid::Mo_Transport: return TYPEID_GAMEOBJECT;
case HighGuid::Vehicle: return TYPEID_UNIT;
case HighGuid::Corpse: return TYPEID_CORPSE;
case HighGuid::Mo_Transport: return TYPEID_GAMEOBJECT;
case HighGuid::Vehicle: return TYPEID_UNIT;
// unknown
case HighGuid::Instance:
case HighGuid::Group:
default: return TYPEID_OBJECT;
default: return TYPEID_OBJECT;
}
}
+4 -4
View File
@@ -2060,7 +2060,7 @@ void Pet::InitPetCreateSpells()
bool Pet::resetTalents()
{
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
if (!owner || !owner->IsPlayer())
return false;
if (!sScriptMgr->CanResetTalents(this))
@@ -2228,7 +2228,7 @@ void Pet::InitTalentForLevel()
uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level);
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
if (!owner || !owner->IsPlayer())
return;
// Reset talents in case low level (on level down) or wrong points for level (hunter can unlearn TP increase talent)
@@ -2368,7 +2368,7 @@ void Pet::LearnPetPassives()
void Pet::CastPetAuras(bool current)
{
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
if (!owner || !owner->IsPlayer())
return;
if (!IsPermanentPetFor(owner->ToPlayer()))
@@ -2397,7 +2397,7 @@ void Pet::learnSpellHighRank(uint32 spellid)
void Pet::SynchronizeLevelWithOwner()
{
Unit* owner = GetOwner();
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
if (!owner || !owner->IsPlayer())
return;
switch (getPetType())
@@ -130,7 +130,7 @@ void KillRewarder::_InitXP(Player* player)
_xp = Acore::XP::Gain(player, _victim, _isBattleGround);
if (_xp && !_isBattleGround && _victim) // pussywizard: npcs with relatively low hp give lower exp
if (_victim->GetTypeId() == TYPEID_UNIT)
if (_victim->IsCreature())
if (const CreatureTemplate* ct = _victim->ToCreature()->GetCreatureTemplate())
if (ct->ModHealth <= 0.75f && ct->ModHealth >= 0.0f)
_xp = uint32(_xp * ct->ModHealth);
+22 -21
View File
@@ -83,6 +83,7 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include <cmath>
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
// however, for some reasons removing it would cause a damn linking issue
@@ -2384,7 +2385,7 @@ void Player::GiveXP(uint32 xp, Unit* victim, float group_rate, bool isLFGReward)
return;
}
if (victim && victim->GetTypeId() == TYPEID_UNIT && !victim->ToCreature()->hasLootRecipient())
if (victim && victim->IsCreature() && !victim->ToCreature()->hasLootRecipient())
{
return;
}
@@ -6033,7 +6034,7 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool awar
// do not reward honor in arenas, but enable onkill spellproc
if (InArena())
{
if (!uVictim || uVictim == this || uVictim->GetTypeId() != TYPEID_PLAYER)
if (!uVictim || uVictim == this || !uVictim->IsPlayer())
return false;
if (GetBgTeamId() == uVictim->ToPlayer()->GetBgTeamId())
@@ -7749,7 +7750,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
// remove FD and invisibility at all loots
constexpr std::array<AuraType, 2> toRemove = {SPELL_AURA_MOD_INVISIBILITY, SPELL_AURA_FEIGN_DEATH};
for (const auto& aura : toRemove)
for (auto const& aura : toRemove)
{
RemoveAurasByType(aura);
}
@@ -9266,7 +9267,7 @@ void Player::StopCastingCharm(Aura* except /*= nullptr*/)
return;
}
if (charm->GetTypeId() == TYPEID_UNIT)
if (charm->IsCreature())
{
if (charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET))
{
@@ -9621,7 +9622,7 @@ void Player::CharmSpellInitialize()
}
uint8 addlist = 0;
if (charm->GetTypeId() != TYPEID_PLAYER)
if (!charm->IsPlayer())
{
//CreatureInfo const* cinfo = charm->ToCreature()->GetCreatureTemplate();
//if (cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK)
@@ -9637,7 +9638,7 @@ void Player::CharmSpellInitialize()
data << uint16(0);
data << uint32(0);
if (charm->GetTypeId() != TYPEID_PLAYER)
if (!charm->IsPlayer())
data << uint8(charm->ToCreature()->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
else
data << uint32(0);
@@ -10655,7 +10656,7 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
if (!bStore)
AutoUnequipOffhandIfNeed();
if (pProto->Flags & ITEM_FLAG_ITEM_PURCHASE_RECORD && crItem->ExtendedCost && pProto->GetMaxStackSize() == 1)
if (pProto->HasFlag(ITEM_FLAG_ITEM_PURCHASE_RECORD) && crItem->ExtendedCost && pProto->GetMaxStackSize() == 1)
{
it->SetFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE);
it->SetRefundRecipient(GetGUID().GetCounter());
@@ -10703,7 +10704,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
return false;
}
if (!IsGameMaster() && ((pProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && GetTeamId(true) == TEAM_ALLIANCE) || (pProto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && GetTeamId(true) == TEAM_HORDE)))
if (!IsGameMaster() && ((pProto->HasFlag2(ITEM_FLAG2_FACTION_HORDE) && GetTeamId(true) == TEAM_ALLIANCE) || (pProto->HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE) && GetTeamId(true) == TEAM_HORDE)))
{
return false;
}
@@ -10815,7 +10816,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
price = pProto->BuyPrice * count; //it should not exceed MAX_MONEY_AMOUNT
// reputation discount
price = uint32(floor(price * GetReputationPriceDiscount(creature)));
price = uint32(std::floor(price * GetReputationPriceDiscount(creature)));
if (!HasEnoughMoney(price))
{
@@ -11733,7 +11734,7 @@ void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint3
void Player::ApplyEquipCooldown(Item* pItem)
{
if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_NO_EQUIP_COOLDOWN))
if (pItem->GetTemplate()->HasFlag(ITEM_FLAG_NO_EQUIP_COOLDOWN))
return;
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
@@ -12632,7 +12633,7 @@ bool Player::isHonorOrXPTarget(Unit* victim) const
return false;
}
if (victim->GetTypeId() == TYPEID_UNIT)
if (victim->IsCreature())
{
if (victim->IsTotem() || victim->IsCritter() || victim->IsPet() || (victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP))
{
@@ -12694,7 +12695,7 @@ void Player::RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewar
if (!pRewardSource)
return;
ObjectGuid creature_guid = (pRewardSource->GetTypeId() == TYPEID_UNIT) ? pRewardSource->GetGUID() : ObjectGuid::Empty;
ObjectGuid creature_guid = (pRewardSource->IsCreature()) ? pRewardSource->GetGUID() : ObjectGuid::Empty;
// prepare data for near group iteration
if (Group* group = GetGroup())
@@ -12828,7 +12829,7 @@ void Player::SetClientControl(Unit* target, bool allowMove, bool packetOnly /*=
SetMover(target);
// Xinef: disable moving if target has disable move flag
if (target->GetTypeId() != TYPEID_UNIT)
if (!target->IsCreature())
return;
if (allowMove && target->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE))
@@ -12865,12 +12866,12 @@ void Player::SetMover(Unit* target)
LOG_INFO("misc", "Player::SetMover (B2) - {}, {}, {}, {}, {}, {}, {}, {}", target->GetGUID().ToString(), target->GetMapId(), target->GetInstanceId(), target->FindMap()->GetId(), target->IsInWorld() ? 1 : 0, target->IsDuringRemoveFromWorld() ? 1 : 0, (target->ToPlayer() && target->ToPlayer()->IsBeingTeleported() ? 1 : 0), target->isBeingLoaded() ? 1 : 0);
}
m_mover->m_movedByPlayer = nullptr;
if (m_mover->GetTypeId() == TYPEID_UNIT)
if (m_mover->IsCreature())
m_mover->GetMotionMaster()->Initialize();
m_mover = target;
m_mover->m_movedByPlayer = this;
if (m_mover->GetTypeId() == TYPEID_UNIT)
if (m_mover->IsCreature())
m_mover->GetMotionMaster()->Initialize();
}
@@ -13115,7 +13116,7 @@ void Player::StopCastingBindSight(Aura* except /*= nullptr*/)
{
if (WorldObject* target = GetViewpoint())
{
if (target->isType(TYPEMASK_UNIT))
if (target->IsUnit())
{
((Unit*)target)->RemoveAurasByType(SPELL_AURA_BIND_SIGHT, GetGUID(), except);
((Unit*)target)->RemoveAurasByType(SPELL_AURA_MOD_POSSESS, GetGUID(), except);
@@ -13139,7 +13140,7 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
// farsight dynobj or puppet may be very far away
UpdateVisibilityOf(target);
if (target->isType(TYPEMASK_UNIT) && !GetVehicle())
if (target->IsUnit() && !GetVehicle())
((Unit*)target)->AddPlayerToVision(this);
SetSeer(target);
}
@@ -13156,7 +13157,7 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
return;
}
if (target->isType(TYPEMASK_UNIT) && !GetVehicle())
if (target->IsUnit() && !GetVehicle())
static_cast<Unit*>(target)->RemovePlayerFromVision(this);
// must immediately set seer back otherwise may crash
@@ -13776,7 +13777,7 @@ InventoryResult Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limi
InventoryResult Player::CanEquipUniqueItem(ItemTemplate const* itemProto, uint8 except_slot, uint32 limit_count) const
{
// check unique-equipped on item
if (itemProto->Flags & ITEM_FLAG_UNIQUE_EQUIPPABLE)
if (itemProto->HasFlag(ITEM_FLAG_UNIQUE_EQUIPPABLE))
{
// there is an equip limit on this item
if (HasItemOrGemWithIdEquipped(itemProto->ItemId, 1, except_slot))
@@ -15482,7 +15483,7 @@ void Player::SendRefundInfo(Item* item)
// This function call unsets ITEM_FLAGS_REFUNDABLE if played time is over 2 hours.
item->UpdatePlayedTime(this);
if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE))
if (!item->IsRefundable())
{
LOG_DEBUG("entities.player.items", "Item refund: item not refundable!");
return;
@@ -15550,7 +15551,7 @@ PetStable& Player::GetOrInitPetStable()
void Player::RefundItem(Item* item)
{
if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE))
if (!item->IsRefundable())
{
LOG_DEBUG("entities.player.items", "Item refund: item not refundable!");
return;
+34 -33
View File
@@ -851,39 +851,40 @@ enum PlayedTimeIndex
// used at player loading query list preparing, and later result selection
enum PlayerLoginQueryIndex
{
PLAYER_LOGIN_QUERY_LOAD_FROM = 0,
PLAYER_LOGIN_QUERY_LOAD_AURAS = 3,
PLAYER_LOGIN_QUERY_LOAD_SPELLS = 4,
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS = 5,
PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS = 6,
PLAYER_LOGIN_QUERY_LOAD_REPUTATION = 7,
PLAYER_LOGIN_QUERY_LOAD_INVENTORY = 8,
PLAYER_LOGIN_QUERY_LOAD_ACTIONS = 9,
PLAYER_LOGIN_QUERY_LOAD_MAILS = 10,
PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS = 11,
PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST = 13,
PLAYER_LOGIN_QUERY_LOAD_HOME_BIND = 14,
PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS = 15,
PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES = 16,
PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS = 18,
PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS = 19,
PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS = 20,
PLAYER_LOGIN_QUERY_LOAD_ENTRY_POINT = 21,
PLAYER_LOGIN_QUERY_LOAD_GLYPHS = 22,
PLAYER_LOGIN_QUERY_LOAD_TALENTS = 23,
PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA = 24,
PLAYER_LOGIN_QUERY_LOAD_SKILLS = 25,
PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS = 26,
PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG = 27,
PLAYER_LOGIN_QUERY_LOAD_BANNED = 28,
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW = 29,
PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES = 30,
PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS = 31,
PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS = 32,
PLAYER_LOGIN_QUERY_LOAD_BREW_OF_THE_MONTH = 34,
PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 35,
PLAYER_LOGIN_QUERY_LOAD_CHARACTER_SETTINGS = 36,
PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS = 37,
PLAYER_LOGIN_QUERY_LOAD_FROM = 0,
PLAYER_LOGIN_QUERY_LOAD_AURAS = 3,
PLAYER_LOGIN_QUERY_LOAD_SPELLS = 4,
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS = 5,
PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS = 6,
PLAYER_LOGIN_QUERY_LOAD_REPUTATION = 7,
PLAYER_LOGIN_QUERY_LOAD_INVENTORY = 8,
PLAYER_LOGIN_QUERY_LOAD_ACTIONS = 9,
PLAYER_LOGIN_QUERY_LOAD_MAILS = 10,
PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS = 11,
PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST = 13,
PLAYER_LOGIN_QUERY_LOAD_HOME_BIND = 14,
PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS = 15,
PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES = 16,
PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS = 18,
PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS = 19,
PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS = 20,
PLAYER_LOGIN_QUERY_LOAD_ENTRY_POINT = 21,
PLAYER_LOGIN_QUERY_LOAD_GLYPHS = 22,
PLAYER_LOGIN_QUERY_LOAD_TALENTS = 23,
PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA = 24,
PLAYER_LOGIN_QUERY_LOAD_SKILLS = 25,
PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS = 26,
PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG = 27,
PLAYER_LOGIN_QUERY_LOAD_BANNED = 28,
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW = 29,
PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES = 30,
PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS = 31,
PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS = 32,
PLAYER_LOGIN_QUERY_LOAD_BREW_OF_THE_MONTH = 34,
PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 35,
PLAYER_LOGIN_QUERY_LOAD_CHARACTER_SETTINGS = 36,
PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS = 37,
PLAYER_LOGIN_QUERY_LOAD_OFFLINE_ACHIEVEMENTS_UPDATES = 38,
MAX_PLAYER_LOGIN_QUERY
};
@@ -44,13 +44,13 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
uint32 npcflags = 0;
if (source->GetTypeId() == TYPEID_UNIT)
if (source->IsCreature())
{
npcflags = source->ToUnit()->GetNpcFlags();
if (showQuests && npcflags & UNIT_NPC_FLAG_QUESTGIVER)
PrepareQuestMenu(source->GetGUID());
}
else if (source->GetTypeId() == TYPEID_GAMEOBJECT)
else if (source->IsGameObject())
if (showQuests && source->ToGameObject()->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
PrepareQuestMenu(source->GetGUID());
@@ -211,7 +211,7 @@ void Player::SendPreparedGossip(WorldObject* source)
if (!source)
return;
if (source->GetTypeId() == TYPEID_UNIT)
if (source->IsCreature())
{
// in case no gossip flag and quest menu not empty, open quest menu (client expect gossip menu with this flag)
if (!source->ToCreature()->HasNpcFlag(UNIT_NPC_FLAG_GOSSIP) && !PlayerTalkClass->GetQuestMenu().Empty())
@@ -220,7 +220,7 @@ void Player::SendPreparedGossip(WorldObject* source)
return;
}
}
else if (source->GetTypeId() == TYPEID_GAMEOBJECT)
else if (source->IsGameObject())
{
// probably need to find a better way here
if (!PlayerTalkClass->GetGossipMenu().GetMenuId() && !PlayerTalkClass->GetQuestMenu().Empty())
@@ -256,7 +256,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
uint32 gossipOptionId = item->OptionType;
ObjectGuid guid = source->GetGUID();
if (sWorld->getIntConfig(CONFIG_INSTANT_TAXI) == 2 && source->GetTypeId() == TYPEID_UNIT)
if (sWorld->getIntConfig(CONFIG_INSTANT_TAXI) == 2 && source->IsCreature())
{
if (gossipOptionId == GOSSIP_ACTION_TOGGLE_INSTANT_FLIGHT && source->ToUnit()->GetNpcFlags() & UNIT_NPC_FLAG_FLIGHTMASTER)
{
@@ -272,7 +272,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
}
}
if (source->GetTypeId() == TYPEID_GAMEOBJECT)
if (source->IsGameObject())
{
if (gossipOptionId > GOSSIP_OPTION_QUESTGIVER)
{
+16 -14
View File
@@ -829,28 +829,30 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
if (quest->GetRewSpellCast() > 0)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpellCast()))
{
if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
if (questGiver->IsUnit() && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
{
if (Creature* creature = GetMap()->GetCreature(questGiver->GetGUID()))
creature->CastSpell(this, quest->GetRewSpellCast(), true);
if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
{
if (Creature* creature = GetMap()->GetCreature(questGiver->GetGUID()))
creature->CastSpell(this, quest->GetRewSpellCast(), true);
}
else
CastSpell(this, quest->GetRewSpellCast(), true);
}
else
CastSpell(this, quest->GetRewSpellCast(), true);
}
}
else if (quest->GetRewSpell() > 0)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpell()))
{
if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
if (questGiver->IsUnit() && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
{
if (Creature* creature = GetMap()->GetCreature(questGiver->GetGUID()))
creature->CastSpell(this, quest->GetRewSpell(), true);
if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
{
if (Creature* creature = GetMap()->GetCreature(questGiver->GetGUID()))
creature->CastSpell(this, quest->GetRewSpell(), true);
}
else
CastSpell(this, quest->GetRewSpell(), true);
}
else
CastSpell(this, quest->GetRewSpell(), true);
}
}
if (quest->GetZoneOrSort() > 0)
@@ -1897,7 +1897,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool
if (!swap && GetItemByPos(INVENTORY_SLOT_BAG_0, eslot))
return EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE;
// if we are swapping 2 equiped items, CanEquipUniqueItem check
// if we are swapping 2 equipped items, CanEquipUniqueItem check
// should ignore the item we are trying to swap, and not the
// destination item. CanEquipUniqueItem should ignore destination
// item only when we are swapping weapon from bag
@@ -2296,12 +2296,12 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
return EQUIP_ERR_ITEM_NOT_FOUND;
}
if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeamId(true) != TEAM_HORDE)
if (proto->HasFlag2(ITEM_FLAG2_FACTION_HORDE) && GetTeamId(true) != TEAM_HORDE)
{
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
}
if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeamId(true) != TEAM_ALLIANCE)
if (proto->HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE) && GetTeamId(true) != TEAM_ALLIANCE)
{
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
}
@@ -2645,7 +2645,7 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool
if (pItem->GetTemplate()->Bonding == BIND_WHEN_PICKED_UP ||
pItem->GetTemplate()->Bonding == BIND_QUEST_ITEM ||
(pItem->GetTemplate()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos)))
(pItem->GetTemplate()->Bonding == BIND_WHEN_EQUIPPED && IsBagPos(pos)))
pItem->SetBinding(true);
Bag* pBag = (bag == INVENTORY_SLOT_BAG_0) ? nullptr : GetBagByPos(bag);
@@ -2685,7 +2685,7 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool
{
if (pItem2->GetTemplate()->Bonding == BIND_WHEN_PICKED_UP ||
pItem2->GetTemplate()->Bonding == BIND_QUEST_ITEM ||
(pItem2->GetTemplate()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos)))
(pItem2->GetTemplate()->Bonding == BIND_WHEN_EQUIPPED && IsBagPos(pos)))
pItem2->SetBinding(true);
pItem2->SetCount(pItem2->GetCount() + count);
@@ -2893,7 +2893,7 @@ void Player::VisualizeItem(uint8 slot, Item* pItem)
return;
// check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory)
if (pItem->GetTemplate()->Bonding == BIND_WHEN_EQUIPED || pItem->GetTemplate()->Bonding == BIND_WHEN_PICKED_UP || pItem->GetTemplate()->Bonding == BIND_QUEST_ITEM)
if (pItem->GetTemplate()->Bonding == BIND_WHEN_EQUIPPED || pItem->GetTemplate()->Bonding == BIND_WHEN_PICKED_UP || pItem->GetTemplate()->Bonding == BIND_QUEST_ITEM)
pItem->SetBinding(true);
LOG_DEBUG("entities.player.items", "STORAGE: EquipItem slot = {}, item = {}", slot, pItem->GetEntry());
@@ -3030,7 +3030,7 @@ void Player::MoveItemToInventory(ItemPosCountVec const& dest, Item* pItem, bool
// in case trade we already have item in other player inventory
pLastItem->SetState(in_characterInventoryDB ? ITEM_CHANGED : ITEM_NEW, this);
if (pLastItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE))
if (pLastItem->IsBOPTradable())
AddTradeableItem(pLastItem);
}
}
@@ -3047,7 +3047,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
DestroyItem(slot, i, update);
if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED))
if (pItem->IsWrapped())
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
stmt->SetData(0, pItem->GetGUID().GetCounter());
@@ -3117,7 +3117,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
pBag->RemoveItem(slot, update);
// Xinef: item is removed, remove loot from storage if any
if (proto->Flags & ITEM_FLAG_HAS_LOOT)
if (proto->HasFlag(ITEM_FLAG_HAS_LOOT))
sLootItemStorage->RemoveStoredLoot(pItem->GetGUID());
if (IsInWorld() && update)
@@ -4169,7 +4169,7 @@ void Player::UpdateItemDuration(uint32 time, bool realtimeonly)
Item* item = *itr;
++itr; // current element can be erased in UpdateDuration
if (!realtimeonly || item->GetTemplate()->FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME)
if (!realtimeonly || item->GetTemplate()->HasFlagCu(ITEM_FLAGS_CU_DURATION_REAL_TIME))
item->UpdateDuration(this, time);
}
}
@@ -5023,7 +5023,7 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons
SetCreationTime(fields[74].Get<Seconds>());
// load achievements before anything else to prevent multiple gains for the same achievement/criteria on every loading (as loading does call UpdateAchievementCriteria)
m_achievementMgr->LoadFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS));
m_achievementMgr->LoadFromDB(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_OFFLINE_ACHIEVEMENTS_UPDATES));
uint32 money = fields[8].Get<uint32>();
if (money > MAX_MONEY_AMOUNT)
@@ -5999,13 +5999,13 @@ Item* Player::_LoadItem(CharacterDatabaseTransaction trans, uint32 zoneId, uint3
remove = true;
}
// "Conjured items disappear if you are logged out for more than 15 minutes"
else if (timeDiff > 15 * MINUTE && proto->Flags & ITEM_FLAG_CONJURED)
else if (timeDiff > 15 * MINUTE && proto->HasFlag(ITEM_FLAG_CONJURED))
{
LOG_DEBUG("entities.player.loading", "Player::_LoadInventory: player ({}, name: '{}', diff: {}) has conjured item ({}, entry: {}) with expired lifetime (15 minutes). Deleting item.",
GetGUID().ToString(), GetName(), timeDiff, item->GetGUID().ToString(), item->GetEntry());
remove = true;
}
else if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE))
else if (item->IsRefundable())
{
if (item->GetPlayedTime() > (2 * HOUR))
{
@@ -6038,7 +6038,7 @@ Item* Player::_LoadItem(CharacterDatabaseTransaction trans, uint32 zoneId, uint3
}
}
}
else if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE))
else if (item->IsBOPTradable())
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ITEM_BOP_TRADE);
stmt->SetData(0, item->GetGUID().GetCounter());
@@ -7266,7 +7266,7 @@ void Player::_SaveInventory(CharacterDatabaseTransaction trans)
if (item->GetState() == ITEM_NEW)
{
// Xinef: item is removed, remove loot from storage if any
if (item->GetTemplate()->Flags & ITEM_FLAG_HAS_LOOT)
if (item->GetTemplate()->HasFlag(ITEM_FLAG_HAS_LOOT))
sLootItemStorage->RemoveStoredLoot(item->GetGUID());
continue;
}
@@ -7281,7 +7281,7 @@ void Player::_SaveInventory(CharacterDatabaseTransaction trans)
m_items[i]->FSetState(ITEM_NEW);
// Xinef: item is removed, remove loot from storage if any
if (item->GetTemplate()->Flags & ITEM_FLAG_HAS_LOOT)
if (item->GetTemplate()->HasFlag(ITEM_FLAG_HAS_LOOT))
sLootItemStorage->RemoveStoredLoot(item->GetGUID());
}
@@ -159,7 +159,7 @@ void Player::Update(uint32 p_time)
}
}
m_achievementMgr->UpdateTimedAchievements(p_time);
m_achievementMgr->Update(p_time);
if (HasUnitState(UNIT_STATE_MELEE_ATTACKING) && !HasUnitState(UNIT_STATE_CASTING) && !HasUnitState(UNIT_STATE_CHARGING))
{
@@ -940,7 +940,7 @@ void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, Item* ite
if (GetShapeshiftForm() == FORM_TREE)
return; // use weapon but not skill up
if (victim->GetTypeId() == TYPEID_UNIT &&
if (victim->IsCreature() &&
(victim->ToCreature()->GetCreatureTemplate()->flags_extra &
CREATURE_FLAG_EXTRA_NO_SKILL_GAINS))
return;
@@ -1671,7 +1671,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
{
if (!CanSeeOrDetect(target, false, true))
{
if (target->GetTypeId() == TYPEID_UNIT)
if (target->IsCreature())
BeforeVisibilityDestroy<Creature>(target->ToCreature(), this);
target->DestroyForPlayer(this);
@@ -1688,7 +1688,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)
// target aura duration for caster show only if target exist at
// caster client send data at target visibility change (adding to
// client)
if (target->isType(TYPEMASK_UNIT))
if (target->IsUnit())
GetInitialVisiblePackets((Unit*) target);
}
}
@@ -1914,7 +1914,7 @@ void Player::UpdateCharmedAI()
// Xinef: we should be killed if caster enters evade mode and charm is
// infinite
if (charmer->GetTypeId() == TYPEID_UNIT &&
if (charmer->IsCreature() &&
charmer->ToCreature()->IsInEvadeMode())
{
AuraEffectList const& auras =
@@ -29,7 +29,7 @@ PlayerSocial::PlayerSocial(): m_playerGUID() { }
uint32 PlayerSocial::GetNumberOfSocialsWithFlag(SocialFlag flag) const
{
uint32 counter = 0;
for (const auto& itr : m_playerSocialMap)
for (auto const& itr : m_playerSocialMap)
{
if ((itr.second.Flags & flag) != 0)
++counter;
@@ -178,7 +178,7 @@ void PlayerSocial::SendSocialList(Player* player, uint32 flags)
bool PlayerSocial::_checkContact(ObjectGuid guid, SocialFlag flags) const
{
const auto& itr = m_playerSocialMap.find(guid);
auto const& itr = m_playerSocialMap.find(guid);
if (itr != m_playerSocialMap.end())
return (itr->second.Flags & flags) != 0;
+17 -10
View File
@@ -34,7 +34,7 @@ CharmInfo::CharmInfo(Unit* unit)
for (uint8 i = 0; i < MAX_SPELL_CHARM; ++i)
_charmspells[i].SetActionAndType(0, ACT_DISABLED);
if (_unit->GetTypeId() == TYPEID_UNIT)
if (_unit->IsCreature())
{
_oldReactState = _unit->ToCreature()->GetReactState();
_unit->ToCreature()->SetReactState(REACT_PASSIVE);
@@ -76,7 +76,7 @@ void CharmInfo::InitEmptyActionBar(bool withAttack)
void CharmInfo::InitPossessCreateSpells()
{
if (_unit->GetTypeId() == TYPEID_UNIT)
if (_unit->IsCreature())
{
// Adding switch until better way is found. Malcrom
// Adding entrys to this switch will prevent COMMAND_ATTACK being added to pet bar.
@@ -98,12 +98,10 @@ void CharmInfo::InitPossessCreateSpells()
uint32 spellId = _unit->ToCreature()->m_spells[i];
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (spellInfo)
{
if (spellInfo->IsPassive())
_unit->CastSpell(_unit, spellInfo, true);
else
AddSpellToActionBar(spellInfo, ACT_PASSIVE);
}
AddSpellToActionBar(spellInfo, ACT_PASSIVE, i);
}
}
else
@@ -157,10 +155,16 @@ void CharmInfo::InitCharmCreateSpells()
}
}
bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate)
bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate, uint32 index)
{
uint32 spell_id = spellInfo->Id;
uint32 first_id = spellInfo->GetFirstRankSpell()->Id;
uint32 spell_id = 0;
uint32 first_id = 0;
if (spellInfo)
{
spell_id = spellInfo->Id;
first_id = spellInfo->GetFirstRankSpell()->Id;
}
// new spell rank can be already listed
for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
@@ -180,6 +184,9 @@ bool CharmInfo::AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates new
{
if (!PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell())
{
if (i != index && index <= MAX_UNIT_ACTION_BAR_INDEX)
continue;
SetActionBar(i, spell_id, newstate == ACT_DECIDE ? spellInfo->IsAutocastable() ? ACT_DISABLED : ACT_PASSIVE : newstate);
if (_unit->GetCharmer() && _unit->GetCharmer()->IsPlayer())
@@ -218,7 +225,7 @@ bool CharmInfo::RemoveSpellFromActionBar(uint32 spell_id)
{
if (PetActionBar[i].IsActionBarForSpell() && sSpellMgr->GetFirstSpellInChain(action) == first_id)
{
SetActionBar(i, 0, ACT_PASSIVE);
SetActionBar(i, 0, ACT_DISABLED);
return true;
}
}
+1 -1
View File
@@ -140,7 +140,7 @@ public:
void InitEmptyActionBar(bool withAttack = true);
//return true if successful
bool AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate = ACT_DECIDE);
bool AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate = ACT_DECIDE, uint32 index = MAX_UNIT_ACTION_BAR_INDEX + 1);
bool RemoveSpellFromActionBar(uint32 spell_id);
void LoadPetActionBar(const std::string& data);
void BuildActionBar(WorldPacket* data);
File diff suppressed because it is too large Load Diff
+16 -16
View File
@@ -67,7 +67,7 @@ Vehicle::~Vehicle()
void Vehicle::Install()
{
if (_me->GetTypeId() == TYPEID_UNIT)
if (_me->IsCreature())
{
if (PowerDisplayEntry const* powerDisplay = sPowerDisplayStore.LookupEntry(_vehicleInfo->m_powerDisplayId))
_me->setPowerType(Powers(powerDisplay->PowerType));
@@ -76,7 +76,7 @@ void Vehicle::Install()
}
_status = STATUS_INSTALLED;
if (GetBase()->GetTypeId() == TYPEID_UNIT)
if (GetBase()->IsCreature())
sScriptMgr->OnInstall(this);
}
@@ -107,7 +107,7 @@ void Vehicle::Uninstall()
LOG_DEBUG("vehicles", "Vehicle::Uninstall {}", _me->GetGUID().ToString());
RemoveAllPassengers();
if (_me && _me->GetTypeId() == TYPEID_UNIT)
if (_me && _me->IsCreature())
{
sScriptMgr->OnUninstall(this);
}
@@ -129,7 +129,7 @@ void Vehicle::Reset(bool evading /*= false*/)
_me->SetNpcFlag(UNIT_NPC_FLAG_SPELLCLICK);
}
if (GetBase()->GetTypeId() == TYPEID_UNIT)
if (GetBase()->IsCreature())
sScriptMgr->OnReset(this);
}
@@ -274,8 +274,8 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 typ
// already installed
if (passenger->GetEntry() == entry)
{
ASSERT(passenger->GetTypeId() == TYPEID_UNIT);
if (_me->GetTypeId() == TYPEID_UNIT)
ASSERT(passenger->IsCreature());
if (_me->IsCreature())
{
if (_me->ToCreature()->IsInEvadeMode() && passenger->ToCreature()->IsAIEnabled)
passenger->ToCreature()->AI()->EnterEvadeMode();
@@ -297,7 +297,7 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 typ
return;
}
if (GetBase()->GetTypeId() == TYPEID_UNIT)
if (GetBase()->IsCreature())
sScriptMgr->OnInstallAccessory(this, accessory);
}
}
@@ -382,7 +382,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
unit->m_movementInfo.transport.guid = _me->GetGUID();
// xinef: removed seat->first == 0 check...
if (_me->GetTypeId() == TYPEID_UNIT
if (_me->IsCreature()
&& unit->IsPlayer()
&& seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
{
@@ -424,14 +424,14 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
init.SetTransportEnter();
init.Launch();
if (_me->GetTypeId() == TYPEID_UNIT)
if (_me->IsCreature())
{
if (_me->ToCreature()->IsAIEnabled)
_me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true);
}
}
if (GetBase()->GetTypeId() == TYPEID_UNIT)
if (GetBase()->IsCreature())
sScriptMgr->OnAddPassenger(this, unit, seatId);
// Remove parachute on vehicle switch
@@ -468,7 +468,7 @@ void Vehicle::RemovePassenger(Unit* unit)
seat->second.Passenger.Reset();
if (_me->GetTypeId() == TYPEID_UNIT && unit->IsPlayer() && seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
if (_me->IsCreature() && unit->IsPlayer() && seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
_me->RemoveCharmedBy(unit);
if (_me->IsInWorld())
@@ -486,10 +486,10 @@ void Vehicle::RemovePassenger(Unit* unit)
if (_me->IsFlying() && !_me->GetInstanceId() && unit->IsPlayer() && !(unit->ToPlayer()->GetDelayedOperations() & DELAYED_VEHICLE_TELEPORT) && _me->GetEntry() != 30275 /*NPC_WILD_WYRM*/)
_me->CastSpell(unit, VEHICLE_SPELL_PARACHUTE, true);
if (_me->GetTypeId() == TYPEID_UNIT)
if (_me->IsCreature())
sScriptMgr->OnRemovePassenger(this, unit);
if (_me->GetTypeId() == TYPEID_UNIT && _me->ToCreature()->IsAIEnabled)
if (_me->IsCreature() && _me->ToCreature()->IsAIEnabled)
_me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, false);
}
@@ -520,7 +520,7 @@ void Vehicle::RelocatePassengers()
void Vehicle::Dismiss()
{
if (GetBase()->GetTypeId() != TYPEID_UNIT)
if (!GetBase()->IsCreature())
return;
LOG_DEBUG("vehicles", "Vehicle::Dismiss {}", _me->GetGUID().ToString());
@@ -535,7 +535,7 @@ bool Vehicle::IsVehicleInUse()
{
if (passenger->IsPlayer())
return true;
else if (passenger->GetTypeId() == TYPEID_UNIT && passenger->GetVehicleKit() && passenger->GetVehicleKit()->IsVehicleInUse())
else if (passenger->IsCreature() && passenger->GetVehicleKit() && passenger->GetVehicleKit()->IsVehicleInUse())
return true;
}
@@ -556,7 +556,7 @@ void Vehicle::TeleportVehicle(float x, float y, float z, float ang)
passenger->NearTeleportTo(x, y, z, ang, false, true);
passenger->ToPlayer()->ScheduleDelayedOperation(DELAYED_VEHICLE_TELEPORT);
}
else if (passenger->GetTypeId() == TYPEID_UNIT && passenger->GetVehicleKit())
else if (passenger->IsCreature() && passenger->GetVehicleKit())
passenger->GetVehicleKit()->TeleportVehicle(x, y, z, ang);
}
}
+15 -16
View File
@@ -948,7 +948,7 @@ void ObjectMgr::LoadCreatureTemplateAddons()
void ObjectMgr::LoadCreatureCustomIDs()
{
// Hack for modules
std::string stringCreatureIds = sConfigMgr->GetOption<std::string>("Creatures.CustomIDs", "");
std::string stringCreatureIds = sConfigMgr->GetOption<std::string>("Creatures.CustomIDs", "190010,55005,999991,25462,98888,601014,34567,34568");
std::vector<std::string_view> CustomCreatures = Acore::Tokenize(stringCreatureIds, ',', false);
for (auto& itr : CustomCreatures)
@@ -2720,8 +2720,8 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.Name1 = fields[4].Get<std::string>();
itemTemplate.DisplayInfoID = fields[5].Get<uint32>();
itemTemplate.Quality = uint32(fields[6].Get<uint8>());
itemTemplate.Flags = fields[7].Get<uint32>();
itemTemplate.Flags2 = fields[8].Get<uint32>();
itemTemplate.Flags = ItemFlags(fields[7].Get<uint32>());
itemTemplate.Flags2 = ItemFlags2(fields[8].Get<uint32>());
itemTemplate.BuyCount = uint32(fields[9].Get<uint8>());
itemTemplate.BuyPrice = int32(fields[10].Get<int64>() * sWorld->getRate((Rates)(RATE_BUYVALUE_ITEM_POOR + itemTemplate.Quality)));
itemTemplate.SellPrice = uint32(fields[11].Get<uint32>() * sWorld->getRate((Rates)(RATE_SELLVALUE_ITEM_POOR + itemTemplate.Quality)));
@@ -2817,7 +2817,7 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.FoodType = uint32(fields[134].Get<uint8>());
itemTemplate.MinMoneyLoot = fields[135].Get<uint32>();
itemTemplate.MaxMoneyLoot = fields[136].Get<uint32>();
itemTemplate.FlagsCu = fields[137].Get<uint32>();
itemTemplate.FlagsCu = ItemFlagsCustom(fields[137].Get<uint32>());
// Checks
ItemEntry const* dbcitem = sItemStore.LookupEntry(entry);
@@ -2873,23 +2873,23 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.Quality = ITEM_QUALITY_NORMAL;
}
if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY)
if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_HORDE))
{
if (FactionEntry const* faction = sFactionStore.LookupEntry(HORDE))
if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `AllowableRace` races, not compatible with ITEM_FLAGS_EXTRA_HORDE_ONLY ({}) in Flags field, item cannot be equipped or used by these races.",
entry, itemTemplate.AllowableRace, ITEM_FLAGS_EXTRA_HORDE_ONLY);
LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `AllowableRace` races, not compatible with ITEM_FLAG2_FACTION_HORDE ({}) in Flags field, item cannot be equipped or used by these races.",
entry, itemTemplate.AllowableRace, ITEM_FLAG2_FACTION_HORDE);
if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY)
LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `Flags2` flags (ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) and ITEM_FLAGS_EXTRA_HORDE_ONLY ({}) in Flags field, this is a wrong combination.",
entry, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY, ITEM_FLAGS_EXTRA_HORDE_ONLY);
if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE))
LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `Flags2` flags (ITEM_FLAG2_FACTION_ALLIANCE) and ITEM_FLAG2_FACTION_HORDE ({}) in Flags field, this is a wrong combination.",
entry, ITEM_FLAG2_FACTION_ALLIANCE, ITEM_FLAG2_FACTION_HORDE);
}
else if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY)
else if (itemTemplate.HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE))
{
if (FactionEntry const* faction = sFactionStore.LookupEntry(ALLIANCE))
if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `AllowableRace` races, not compatible with ITEM_FLAGS_EXTRA_ALLIANCE_ONLY ({}) in Flags field, item cannot be equipped or used by these races.",
entry, itemTemplate.AllowableRace, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY);
LOG_ERROR("sql.sql", "Item (Entry: {}) has value ({}) in `AllowableRace` races, not compatible with ITEM_FLAG2_FACTION_ALLIANCE ({}) in Flags field, item cannot be equipped or used by these races.",
entry, itemTemplate.AllowableRace, ITEM_FLAG2_FACTION_ALLIANCE);
}
if (itemTemplate.BuyCount <= 0)
@@ -2989,7 +2989,6 @@ void ObjectMgr::LoadItemTemplates()
switch (itemTemplate.ItemStat[j].ItemStatType)
{
case ITEM_MOD_SPELL_HEALING_DONE:
case ITEM_MOD_SPELL_DAMAGE_DONE:
LOG_ERROR("sql.sql", "Item (Entry: {}) has deprecated stat_type{} ({})", entry, j + 1, itemTemplate.ItemStat[j].ItemStatType);
break;
default:
@@ -3201,10 +3200,10 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.HolidayId = 0;
}
if (itemTemplate.FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME && !itemTemplate.Duration)
if (itemTemplate.HasFlagCu(ITEM_FLAGS_CU_DURATION_REAL_TIME) && !itemTemplate.Duration)
{
LOG_ERROR("sql.sql", "Item (Entry {}) has flag ITEM_FLAGS_CU_DURATION_REAL_TIME but it does not have duration limit", entry);
itemTemplate.FlagsCu &= ~ITEM_FLAGS_CU_DURATION_REAL_TIME;
itemTemplate.FlagsCu = static_cast<ItemFlagsCustom>(static_cast<uint32>(itemTemplate.FlagsCu) & ~ITEM_FLAGS_CU_DURATION_REAL_TIME);
}
// Fill categories map
@@ -91,7 +91,7 @@ namespace Acore
{
Unit& i_unit;
bool isCreature;
explicit AIRelocationNotifier(Unit& unit) : i_unit(unit), isCreature(unit.GetTypeId() == TYPEID_UNIT) {}
explicit AIRelocationNotifier(Unit& unit) : i_unit(unit), isCreature(unit.IsCreature()) {}
template<class T> void Visit(GridRefMgr<T>&) {}
void Visit(CreatureMapType&);
};
@@ -864,7 +864,7 @@ namespace Acore
bool operator()(Unit* u)
{
if (u->IsAlive() && !u->IsCritter() && i_obj->IsWithinDistInMap(u, i_range) && !i_funit->IsFriendlyTo(u) &&
(i_funit->GetTypeId() != TYPEID_UNIT || !i_funit->ToCreature()->IsAvoidingAOE())) // pussywizard
(!i_funit->IsCreature() || !i_funit->ToCreature()->IsAvoidingAOE())) // pussywizard
return true;
else
return false;
@@ -887,7 +887,7 @@ namespace Acore
if (u->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET)
return false;
if (u->GetTypeId() == TYPEID_UNIT && (u->ToCreature()->IsTotem() || u->ToCreature()->IsTrigger() || u->ToCreature()->IsAvoidingAOE())) // pussywizard: added IsAvoidingAOE()
if (u->IsCreature() && (u->ToCreature()->IsTotem() || u->ToCreature()->IsTrigger() || u->ToCreature()->IsAvoidingAOE())) // pussywizard: added IsAvoidingAOE()
return false;
if (!u->isTargetableForAttack(false, i_funit))
@@ -918,7 +918,7 @@ namespace Acore
return false;
}
if (u->GetTypeId() == TYPEID_UNIT && u->ToCreature()->IsTotem())
if (u->IsCreature() && u->ToCreature()->IsTotem())
{
return false;
}
@@ -930,7 +930,7 @@ namespace Acore
uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
Optional<float> collisionHeight = { };
if (i_obj->GetTypeId() == TYPEID_GAMEOBJECT)
if (i_obj->IsGameObject())
{
losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
collisionHeight = i_owner->GetCollisionHeight();
@@ -1203,7 +1203,7 @@ namespace Acore
if (!me->IsValidAttackTarget(u))
return false;
if (i_playerOnly && u->GetTypeId() != TYPEID_PLAYER)
if (i_playerOnly && !u->IsPlayer())
return false;
m_range = me->GetDistance(u); // use found unit range as new range limit for next check
+1 -1
View File
@@ -1202,7 +1202,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
if (item->DisenchantID && m_maxEnchantingLevel >= item->RequiredDisenchantSkill)
r->rollVoteMask |= ROLL_FLAG_TYPE_DISENCHANT;
if (item->Flags2 & ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED)
if (item->HasFlag2(ITEM_FLAG2_CAN_ONLY_ROLL_GREED))
r->rollVoteMask &= ~ROLL_FLAG_TYPE_NEED;
loot->items[itemSlot].is_blocked = true;
+3
View File
@@ -1734,6 +1734,9 @@ bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool
if (uint32(_GetMemberRemainingMoney(*member)) < amount) // Check if we have enough slot/money today
return false;
if (!(GetRankRights(member->GetRankId()) & GR_RIGHT_WITHDRAW_REPAIR) && repair)
return false;
// Call script after validation and before money transfer.
sScriptMgr->OnGuildMemberWitdrawMoney(this, player, amount, repair);
@@ -207,7 +207,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
itemEntry = item->GetTemplate()->ItemId;
if (sAuctionMgr->GetAItem(item->GetGUID()) || !item->CanBeTraded() || item->IsNotEmptyBag() ||
item->GetTemplate()->Flags & ITEM_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION) ||
item->GetTemplate()->HasFlag(ITEM_FLAG_CONJURED) || item->GetUInt32Value(ITEM_FIELD_DURATION) ||
item->GetCount() < count[i] || itemEntry != item->GetTemplate()->ItemId)
{
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
@@ -206,6 +206,10 @@ bool LoginQueryHolder::Initialize()
stmt->SetData(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS, stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_ACHIEVEMENT_OFFLINE_UPDATES);
stmt->SetData(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_OFFLINE_ACHIEVEMENTS_UPDATES, stmt);
return res;
}
+1 -1
View File
@@ -802,7 +802,7 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData)
GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
//Send scripted event call
if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI())
if (unit && unit->IsCreature() && ((Creature*)unit)->AI())
((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
}
+1 -1
View File
@@ -956,7 +956,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
recvData >> Guid;
Player* player = HashMapHolder<Player>::Find(Guid);
if (!player)
if (!player || !player->IsInSameRaidWith(_player))
{
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3 + 4 + 2);
data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
+7 -6
View File
@@ -28,6 +28,7 @@
#include "UpdateData.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include <cmath>
void WorldSession::HandleSplitItemOpcode(WorldPacket& recvData)
{
@@ -319,7 +320,7 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket& recvData)
return;
}
if (pItem->GetTemplate()->Flags & ITEM_FLAG_NO_USER_DESTROY)
if (pItem->GetTemplate()->HasFlag(ITEM_FLAG_NO_USER_DESTROY))
{
_player->SendEquipError(EQUIP_ERR_CANT_DROP_SOULBOUND, nullptr, nullptr);
return;
@@ -783,7 +784,7 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData)
// prevent selling item for sellprice when the item is still refundable
// this probably happens when right clicking a refundable item, the client sends both
// CMSG_SELL_ITEM and CMSG_REFUND_ITEM (unverified)
if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE))
if (pItem->IsRefundable())
return; // Therefore, no feedback to client
// special case at auto sell (sell all)
@@ -1091,7 +1092,7 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid, uint32 vendorEntry)
}
// Only display items in vendor lists for the team the
// player is on. If GM on, display all items.
if (!_player->IsGameMaster() && ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeamId() == TEAM_ALLIANCE) || (itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeamId() == TEAM_HORDE)))
if (!_player->IsGameMaster() && ((itemTemplate->HasFlag2(ITEM_FLAG2_FACTION_HORDE) && _player->GetTeamId() == TEAM_ALLIANCE) || (itemTemplate->HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE) && _player->GetTeamId() == TEAM_HORDE)))
{
continue;
}
@@ -1111,7 +1112,7 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid, uint32 vendorEntry)
}
// reputation discount
int32 price = item->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
int32 price = item->IsGoldRequired(itemTemplate) ? uint32(std::floor(itemTemplate->BuyPrice * discountMod)) : 0;
data << uint32(slot + 1); // client expects counting to start at 1
data << uint32(item->item);
@@ -1282,7 +1283,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recvData)
return;
}
if (!(gift->GetTemplate()->Flags & ITEM_FLAG_IS_WRAPPER)) // cheating: non-wrapper wrapper
if (!(gift->GetTemplate()->HasFlag(ITEM_FLAG_IS_WRAPPER))) // cheating: non-wrapper wrapper
{
_player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, nullptr);
return;
@@ -1483,7 +1484,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData)
ItemTemplate const* iGemProto = Gems[i]->GetTemplate();
// unique item (for new and already placed bit removed enchantments
if (iGemProto->Flags & ITEM_FLAG_UNIQUE_EQUIPPABLE)
if (iGemProto->HasFlag(ITEM_FLAG_UNIQUE_EQUIPPABLE))
{
for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
{
+1 -1
View File
@@ -372,7 +372,7 @@ void WorldSession::DoLootRelease(ObjectGuid lguid)
player->DestroyItemCount(pItem, count, true);
}
else if (pItem->loot.isLooted() || !(proto->Flags & ITEM_FLAG_HAS_LOOT))
else if (pItem->loot.isLooted() || !proto->HasFlag(ITEM_FLAG_HAS_LOOT))
{
player->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
return;
+3 -3
View File
@@ -203,7 +203,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
if (item)
{
ItemTemplate const* itemProto = item->GetTemplate();
if (!itemProto || !(itemProto->Flags & ITEM_FLAG_IS_BOUND_TO_ACCOUNT))
if (!itemProto || !itemProto->HasFlag(ITEM_FLAG_IS_BOUND_TO_ACCOUNT))
{
accountBound = false;
break;
@@ -257,13 +257,13 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
return;
}
if (item->GetTemplate()->Flags & ITEM_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION))
if (item->GetTemplate()->HasFlag(ITEM_FLAG_CONJURED) || item->GetUInt32Value(ITEM_FIELD_DURATION))
{
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
return;
}
if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED))
if (COD && item->IsWrapped())
{
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD);
return;
+2 -2
View File
@@ -373,7 +373,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
// Stop emote on move
if (Player* plrMover = mover->ToPlayer())
{
if (plrMover->GetUInt32Value(UNIT_NPC_EMOTESTATE) != EMOTE_ONESHOT_NONE)
if (plrMover->GetUInt32Value(UNIT_NPC_EMOTESTATE) != EMOTE_ONESHOT_NONE && movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING))
{
plrMover->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
}
@@ -410,7 +410,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
}
movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ());
if (mover->GetTypeId() == TYPEID_UNIT)
if (mover->IsCreature())
{
movementInfo.transport.guid = mover->m_movementInfo.transport.guid;
movementInfo.transport.pos.Relocate(mover->m_movementInfo.transport.pos.GetPositionX(), mover->m_movementInfo.transport.pos.GetPositionY(), mover->m_movementInfo.transport.pos.GetPositionZ());
+3 -2
View File
@@ -32,6 +32,7 @@
#include "UpdateMask.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include <cmath>
enum StableResultCode
{
@@ -164,7 +165,7 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle)
data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case)
data << uint8(state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
data << uint32(floor(tSpell->spellCost * fDiscountMod));
data << uint32(std::floor(tSpell->spellCost * fDiscountMod));
data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
// primary prof. learn confirmation dialog
@@ -247,7 +248,7 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData)
return;
// apply reputation discount
uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
uint32 nSpellCost = uint32(std::floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
// check money requirement
if (!_player->HasEnoughMoney(nSpellCost))
+9 -9
View File
@@ -50,7 +50,7 @@ void WorldSession::HandleDismissCritter(WorldPackets::Pet::DismissCritter& packe
if (_player->GetCritterGUID() == pet->GetGUID())
{
if (pet->GetTypeId() == TYPEID_UNIT && pet->ToCreature()->IsSummon())
if (pet->IsCreature() && pet->ToCreature()->IsSummon())
pet->ToTempSummon()->UnSummon();
}
}
@@ -234,7 +234,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
// Not let attack through obstructions
bool checkLos = !DisableMgr::IsPathfindingEnabled(pet->GetMap()) ||
(TargetUnit->GetTypeId() == TYPEID_UNIT && (TargetUnit->ToCreature()->isWorldBoss() || TargetUnit->ToCreature()->IsDungeonBoss()));
(TargetUnit->IsCreature() && (TargetUnit->ToCreature()->isWorldBoss() || TargetUnit->ToCreature()->IsDungeonBoss()));
if (checkLos && !pet->IsWithinLOSInMap(TargetUnit))
{
@@ -252,7 +252,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
{
pet->AttackStop();
if (pet->GetTypeId() != TYPEID_PLAYER && pet->ToCreature()->IsAIEnabled)
if (!pet->IsPlayer() && pet->ToCreature()->IsAIEnabled)
{
charmInfo->SetIsCommandAttack(true);
charmInfo->SetIsAtStay(false);
@@ -292,7 +292,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
}
else if (pet->GetOwnerGUID() == GetPlayer()->GetGUID())
{
ASSERT(pet->GetTypeId() == TYPEID_UNIT);
ASSERT(pet->IsCreature());
if (pet->IsPet())
{
if (pet->ToPet()->getPetType() == HUNTER_PET)
@@ -323,7 +323,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
case REACT_DEFENSIVE: //recovery
case REACT_AGGRESSIVE: //activete
if (pet->GetTypeId() == TYPEID_UNIT)
if (pet->IsCreature())
pet->ToCreature()->SetReactState(ReactStates(spellId));
else
charmInfo->SetPlayerReactState(ReactStates(spellId));
@@ -491,7 +491,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
if (pet->GetVictim())
pet->AttackStop();
if (pet->GetTypeId() != TYPEID_PLAYER && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
if (!pet->IsPlayer() && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
{
charmInfo->SetIsCommandAttack(true);
charmInfo->SetIsAtStay(false);
@@ -537,7 +537,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
else
victim = nullptr;
if (pet->GetTypeId() != TYPEID_PLAYER && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
if (!pet->IsPlayer() && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
{
pet->StopMoving();
pet->GetMotionMaster()->Clear();
@@ -775,7 +775,7 @@ void WorldSession::HandlePetSetAction(WorldPacket& recvData)
//sign for autocast
if (act_state == ACT_ENABLED)
{
if (pet->GetTypeId() == TYPEID_UNIT && pet->IsPet())
if (pet->IsCreature() && pet->IsPet())
{
((Pet*)pet)->ToggleAutocast(spellInfo, true);
}
@@ -793,7 +793,7 @@ void WorldSession::HandlePetSetAction(WorldPacket& recvData)
//sign for no/turn off autocast
else if (act_state == ACT_DISABLED)
{
if (pet->GetTypeId() == TYPEID_UNIT && pet->IsPet())
if (pet->IsCreature() && pet->IsPet())
{
((Pet*)pet)->ToggleAutocast(spellInfo, false);
}
+1 -1
View File
@@ -123,7 +123,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM | TYPEMASK_PLAYER);
// no or incorrect quest giver
if (!object || object == _player || (object->GetTypeId() != TYPEID_PLAYER && !object->hasQuest(questId)) ||
if (!object || object == _player || (!object->IsPlayer() && !object->hasQuest(questId)) ||
(object->IsPlayer() && !object->ToPlayer()->CanShareQuest(questId)))
{
_player->PlayerTalkClass->SendCloseGossip();
+8 -8
View File
@@ -116,14 +116,14 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
}
// only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB)
if (proto->Class == ITEM_CLASS_CONSUMABLE && !(proto->Flags & ITEM_FLAG_IGNORE_DEFAULT_ARENA_RESTRICTIONS) && pUser->InArena())
if (proto->Class == ITEM_CLASS_CONSUMABLE && !proto->HasFlag(ITEM_FLAG_IGNORE_DEFAULT_ARENA_RESTRICTIONS) && pUser->InArena())
{
pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
return;
}
// don't allow items banned in arena
if (proto->Flags & ITEM_FLAG_NOT_USEABLE_IN_ARENA && pUser->InArena())
if (proto->HasFlag(ITEM_FLAG_NOT_USEABLE_IN_ARENA) && pUser->InArena())
{
pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
return;
@@ -204,7 +204,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
}
// Verify that the bag is an actual bag or wrapped item that can be used "normally"
if (!(proto->Flags & ITEM_FLAG_HAS_LOOT) && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED))
if (!proto->HasFlag(ITEM_FLAG_HAS_LOOT) && !item->IsWrapped())
{
pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, nullptr);
LOG_ERROR("network.opcode", "Possible hacking attempt: Player {} [{}] tried to open item [{}, entry: {}] which is not openable!",
@@ -235,7 +235,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
if (sScriptMgr->OnBeforeOpenItem(pUser, item))
{
if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED))// wrapped?
if (item->IsWrapped())// wrapped?
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM);
stmt->SetData(0, item->GetGUID().GetCounter());
@@ -258,7 +258,7 @@ void WorldSession::HandleOpenWrappedItemCallback(uint8 bagIndex, uint8 slot, Obj
if (!item)
return;
if (item->GetGUID().GetCounter() != itemLowGUID || !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) // during getting result, gift was swapped with another item
if (item->GetGUID().GetCounter() != itemLowGUID || !item->IsWrapped()) // during getting result, gift was swapped with another item
return;
if (!result)
@@ -409,7 +409,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
if (Vehicle* veh = mover->GetVehicleKit())
if (const VehicleSeatEntry* seat = veh->GetSeatForPassenger(_player))
if (seat->m_flags & VEHICLE_SEAT_FLAG_CAN_ATTACK || spellInfo->Effects[EFFECT_0].Effect == SPELL_EFFECT_OPEN_LOCK /*allow looting from vehicle, but only if player has required spell (all necessary opening spells are in playercreateinfo_spell)*/)
if ((mover->GetTypeId() == TYPEID_UNIT && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive()) // the creature can't cast that spell, check player instead
if ((mover->IsCreature() && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive()) // the creature can't cast that spell, check player instead
{
if( !(spellInfo->Targets & TARGET_FLAG_GAMEOBJECT_ITEM) && (!_player->HasActiveSpell (spellId) || spellInfo->IsPassive()) )
{
@@ -419,12 +419,12 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
}
// at this point, player is a valid caster
// swapping the mover will stop the check below at == TYPEID_UNIT, so everything works fine
// swapping the mover will stop the check below at IsUnit, so everything works fine
mover = _player;
}
// not have spell in spellbook or spell passive and not casted by client
if ((mover->GetTypeId() == TYPEID_UNIT && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive())
if ((mover->IsCreature() && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive())
{
//cheater? kick? ban?
recvPacket.rfinish(); // prevent spam at ignore packet
+3 -3
View File
@@ -102,7 +102,7 @@ void WorldSession::SendUpdateTrade(bool trader_data /*= true*/)
data << uint32(item->GetTemplate()->DisplayInfoID);// display id
data << uint32(item->GetCount()); // stack count
// wrapped: hide stats but show giftcreator name
data << uint32(item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED) ? 1 : 0);
data << uint32(item->IsWrapped() ? 1 : 0);
data << item->GetGuidValue(ITEM_FIELD_GIFTCREATOR);
// perm. enchantment and gems
data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
@@ -154,7 +154,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
LOG_DEBUG("network", "partner storing: {}", myItems[i]->GetGUID().ToString());
// adjust time (depends on /played)
if (myItems[i]->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE))
if (myItems[i]->IsBOPTradable())
myItems[i]->SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, trader->GetTotalPlayedTime() - (_player->GetTotalPlayedTime() - myItems[i]->GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME)));
// store
trader->MoveItemToInventory(traderDst, myItems[i], true, true);
@@ -165,7 +165,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[])
LOG_DEBUG("network", "player storing: {}", hisItems[i]->GetGUID().ToString());
// adjust time (depends on /played)
if (hisItems[i]->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE))
if (hisItems[i]->IsBOPTradable())
hisItems[i]->SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, _player->GetTotalPlayedTime() - (trader->GetTotalPlayedTime() - hisItems[i]->GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME)));
// store
_player->MoveItemToInventory(playerDst, hisItems[i], true, true);
+1 -1
View File
@@ -679,7 +679,7 @@ void InstanceScript::DoCastSpellOnPlayer(Player* player, uint32 spell, bool incl
for (auto itr2 = player->m_Controlled.begin(); itr2 != player->m_Controlled.end(); ++itr2)
{
if (Unit* controlled = *itr2)
if (controlled->IsInWorld() && controlled->GetTypeId() == TYPEID_UNIT)
if (controlled->IsInWorld() && controlled->IsCreature())
controlled->CastSpell(player, spell, true);
}
}
+1 -1
View File
@@ -214,7 +214,7 @@ bool LootItemStorage::LoadStoredLoot(Item* item, Player* player)
// non-conditional one-player only items are counted here,
// free for all items are counted in FillFFALoot(),
// non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
if ((!li.needs_quest && li.conditions.empty() && !(proto->Flags & ITEM_FLAG_MULTI_DROP)) || li.is_counted)
if ((!li.needs_quest && li.conditions.empty() && !proto->HasFlag(ITEM_FLAG_MULTI_DROP)) || li.is_counted)
{
++loot->unlootedCount;
}
+11 -11
View File
@@ -390,8 +390,8 @@ LootItem::LootItem(LootStoreItem const& li)
conditions = li.conditions;
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemid);
freeforall = proto && (proto->Flags & ITEM_FLAG_MULTI_DROP);
follow_loot_rules = proto && (proto->FlagsCu & ITEM_FLAGS_CU_FOLLOW_LOOT_RULES);
freeforall = proto && proto->HasFlag(ITEM_FLAG_MULTI_DROP);
follow_loot_rules = proto && proto->HasFlagCu(ITEM_FLAGS_CU_FOLLOW_LOOT_RULES);
needs_quest = li.needs_quest;
@@ -429,7 +429,7 @@ bool LootItem::AllowedForPlayer(Player const* player, ObjectGuid source) const
// Master Looter can see conditioned recipes
if (isMasterLooter && itemVisibleForMasterLooter)
{
if ((pProto->Flags & ITEM_FLAG_HIDE_UNUSABLE_RECIPE) || (pProto->Class == ITEM_CLASS_RECIPE && pProto->Bonding == BIND_WHEN_PICKED_UP && pProto->Spells[1].SpellId != 0))
if (pProto->HasFlag(ITEM_FLAG_HIDE_UNUSABLE_RECIPE) || (pProto->Class == ITEM_CLASS_RECIPE && pProto->Bonding == BIND_WHEN_PICKED_UP && pProto->Spells[1].SpellId != 0))
{
return true;
}
@@ -439,12 +439,12 @@ bool LootItem::AllowedForPlayer(Player const* player, ObjectGuid source) const
}
// not show loot for not own team
if ((pProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && player->GetTeamId(true) != TEAM_HORDE)
if (pProto->HasFlag2(ITEM_FLAG2_FACTION_HORDE) && player->GetTeamId(true) != TEAM_HORDE)
{
return false;
}
if ((pProto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && player->GetTeamId(true) != TEAM_ALLIANCE)
if (pProto->HasFlag2(ITEM_FLAG2_FACTION_ALLIANCE) && player->GetTeamId(true) != TEAM_ALLIANCE)
{
return false;
}
@@ -456,7 +456,7 @@ bool LootItem::AllowedForPlayer(Player const* player, ObjectGuid source) const
}
// Don't allow loot for players without profession or those who already know the recipe
if ((pProto->Flags & ITEM_FLAG_HIDE_UNUSABLE_RECIPE) && (!player->HasSkill(pProto->RequiredSkill) || player->HasSpell(pProto->Spells[1].SpellId)))
if (pProto->HasFlag(ITEM_FLAG_HIDE_UNUSABLE_RECIPE) && (!player->HasSkill(pProto->RequiredSkill) || player->HasSpell(pProto->Spells[1].SpellId)))
{
return false;
}
@@ -468,7 +468,7 @@ bool LootItem::AllowedForPlayer(Player const* player, ObjectGuid source) const
}
// check quest requirements
if (!(pProto->FlagsCu & ITEM_FLAGS_CU_IGNORE_QUEST_STATUS))
if (!pProto->HasFlagCu(ITEM_FLAGS_CU_IGNORE_QUEST_STATUS))
{
// Don't drop quest items if the player is missing the relevant quest
if (needs_quest && !player->HasQuestForItem(itemid))
@@ -555,7 +555,7 @@ void Loot::AddItem(LootStoreItem const& item)
// non-conditional one-player only items are counted here,
// free for all items are counted in FillFFALoot(),
// non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()
if (!item.needs_quest && item.conditions.empty() && !(proto->Flags & ITEM_FLAG_MULTI_DROP))
if (!item.needs_quest && item.conditions.empty() && !proto->HasFlag(ITEM_FLAG_MULTI_DROP))
++unlootedCount;
}
}
@@ -2099,7 +2099,7 @@ void LoadLootTemplates_Item()
// remove real entries and check existence loot
ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end() && itr->second.Flags & ITEM_FLAG_HAS_LOOT)
if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end() && itr->second.HasFlag(ITEM_FLAG_HAS_LOOT))
lootIdSet.erase(itr->second.ItemId);
// output error for any still listed (not referenced from appropriate table) ids
@@ -2126,7 +2126,7 @@ void LoadLootTemplates_Milling()
ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
{
if (!(itr->second.Flags & ITEM_FLAG_IS_MILLABLE))
if (!itr->second.HasFlag(ITEM_FLAG_IS_MILLABLE))
continue;
if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end())
@@ -2193,7 +2193,7 @@ void LoadLootTemplates_Prospecting()
ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
{
if (!(itr->second.Flags & ITEM_FLAG_IS_PROSPECTABLE))
if (!itr->second.HasFlag(ITEM_FLAG_IS_PROSPECTABLE))
continue;
if (lootIdSet.find(itr->second.ItemId) != lootIdSet.end())
+4 -4
View File
@@ -587,7 +587,7 @@ bool Map::AddToMap(T* obj, bool checkTransport)
obj->AddToWorld();
if (checkTransport)
if (!(obj->GetTypeId() == TYPEID_GAMEOBJECT && obj->ToGameObject()->IsTransport())) // dont add transport to transport ;d
if (!(obj->IsGameObject() && obj->ToGameObject()->IsTransport())) // dont add transport to transport ;d
if (Transport* transport = GetTransportForPos(obj->GetPhaseMask(), obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj))
transport->AddPassenger(obj, true);
@@ -602,7 +602,7 @@ bool Map::AddToMap(T* obj, bool checkTransport)
// Xinef: little hack for vehicles, accessories have to be added after visibility update so they wont fall off the vehicle, moved from Creature::AIM_Initialize
// Initialize vehicle, this is done only for summoned npcs, DB creatures are handled by grid loaders
if (obj->GetTypeId() == TYPEID_UNIT)
if (obj->IsCreature())
if (Vehicle* vehicle = obj->ToCreature()->GetVehicleKit())
vehicle->Reset();
return true;
@@ -2668,8 +2668,8 @@ void Map::AddObjectToSwitchList(WorldObject* obj, bool on)
{
ASSERT(obj->GetMapId() == GetId() && obj->GetInstanceId() == GetInstanceId());
// i_objectsToSwitch is iterated only in Map::RemoveAllObjectsInRemoveList() and it uses
// the contained objects only if GetTypeId() == TYPEID_UNIT , so we can return in all other cases
if (obj->GetTypeId() != TYPEID_UNIT && obj->GetTypeId() != TYPEID_GAMEOBJECT)
// the contained objects only if IsCreature() , so we can return in all other cases
if (!obj->IsCreature() && !obj->IsGameObject())
return;
std::map<WorldObject*, bool>::iterator itr = i_objectsToSwitch.find(obj);
+4 -4
View File
@@ -244,7 +244,7 @@ void MotionMaster::MoveRandom(float wanderDistance)
if (_owner->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE))
return;
if (_owner->GetTypeId() == TYPEID_UNIT)
if (_owner->IsCreature())
{
LOG_DEBUG("movement.motionmaster", "Creature ({}) start moving random", _owner->GetGUID().ToString());
Mutate(new RandomMovementGenerator<Creature>(wanderDistance), MOTION_SLOT_IDLE);
@@ -260,12 +260,12 @@ void MotionMaster::MoveTargetedHome(bool walk /*= false*/)
{
Clear(false);
if (_owner->GetTypeId() == TYPEID_UNIT && !_owner->ToCreature()->GetCharmerOrOwnerGUID())
if (_owner->IsCreature() && !_owner->ToCreature()->GetCharmerOrOwnerGUID())
{
LOG_DEBUG("movement.motionmaster", "Creature ({}) targeted home", _owner->GetGUID().ToString());
Mutate(new HomeMovementGenerator<Creature>(walk), MOTION_SLOT_ACTIVE);
}
else if (_owner->GetTypeId() == TYPEID_UNIT && _owner->ToCreature()->GetCharmerOrOwnerGUID())
else if (_owner->IsCreature() && _owner->ToCreature()->GetCharmerOrOwnerGUID())
{
_owner->ClearUnitState(UNIT_STATE_EVADE);
@@ -645,7 +645,7 @@ void MotionMaster::MoveFall(uint32 id /*=0*/, bool addFlagForNPC)
_owner->m_movementInfo.SetFallTime(0);
_owner->ToPlayer()->SetFallInformation(GameTime::GetGameTime().count(), _owner->GetPositionZ());
}
else if (_owner->GetTypeId() == TYPEID_UNIT && addFlagForNPC) // pussywizard
else if (_owner->IsCreature() && addFlagForNPC) // pussywizard
{
_owner->RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING);
_owner->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY);
@@ -72,7 +72,7 @@ bool RotateMovementGenerator::Update(Unit* owner, uint32 diff)
void RotateMovementGenerator::Finalize(Unit* unit)
{
unit->ClearUnitState(UNIT_STATE_ROTATING);
if (unit->GetTypeId() == TYPEID_UNIT)
if (unit->IsCreature())
unit->ToCreature()->AI()->MovementInform(ROTATE_MOTION_TYPE, 0);
}
@@ -90,7 +90,7 @@ void DistractMovementGenerator::Finalize(Unit* owner)
owner->ClearUnitState(UNIT_STATE_DISTRACTED);
// If this is a creature, then return orientation to original position (for idle movement creatures)
if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature())
if (owner->IsCreature() && owner->ToCreature())
{
float angle = owner->ToCreature()->GetHomePosition().GetOrientation();
owner->SetFacingTo(angle);
@@ -636,7 +636,7 @@ void PathGenerator::CreateFilter()
uint16 includeFlags = 0;
uint16 excludeFlags = 0;
if (_source->GetTypeId() == TYPEID_UNIT)
if (_source->IsCreature())
{
Creature* creature = (Creature*)_source;
if (creature->CanWalk())
@@ -231,10 +231,10 @@ bool EffectMovementGenerator::Update(Unit* unit, uint32)
void EffectMovementGenerator::Finalize(Unit* unit)
{
if (unit->GetTypeId() != TYPEID_UNIT)
if (!unit->IsCreature())
return;
if (unit->GetTypeId() == TYPEID_UNIT && unit->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) && unit->movespline->isFalling()) // pussywizard
if (unit->IsCreature() && unit->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) && unit->movespline->isFalling()) // pussywizard
unit->RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
// Need restore previous movement since we have no proper states system
@@ -148,6 +148,15 @@ bool ChaseMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
owner->ClearUnitState(UNIT_STATE_CHASE_MOVE);
owner->SetInFront(target);
MovementInform(owner);
// Mobs should chase you infinitely if you stop and wait every few seconds.
i_leashExtensionTimer.Update(time_diff);
if (i_leashExtensionTimer.Passed())
{
i_leashExtensionTimer.Reset(5000);
if (Creature* creature = owner->ToCreature())
creature->UpdateLeashExtensionTime();
}
}
// if the target moved, we have to consider whether to adjust
@@ -305,7 +314,7 @@ void ChaseMovementGenerator<T>::DoReset(T* owner)
template<class T>
void ChaseMovementGenerator<T>::MovementInform(T* owner)
{
if (owner->GetTypeId() != TYPEID_UNIT)
if (!owner->IsCreature())
return;
// Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
@@ -385,7 +394,7 @@ bool FollowMovementGenerator<T>::PositionOkay(Unit* target, bool isPlayerPet, bo
float exactDistSq = target->GetExactDistSq(_lastTargetPosition->GetPositionX(), _lastTargetPosition->GetPositionY(), _lastTargetPosition->GetPositionZ());
float distanceTolerance = 0.25f;
// For creatures, increase tolerance
if (target->GetTypeId() == TYPEID_UNIT)
if (target->IsCreature())
{
distanceTolerance += _range + _range;
}
@@ -554,7 +563,7 @@ void FollowMovementGenerator<T>::DoReset(T* owner)
template<class T>
void FollowMovementGenerator<T>::MovementInform(T* owner)
{
if (owner->GetTypeId() != TYPEID_UNIT)
if (!owner->IsCreature())
return;
// Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
@@ -39,7 +39,7 @@ class ChaseMovementGenerator : public MovementGeneratorMedium<T, ChaseMovementGe
{
public:
ChaseMovementGenerator(Unit* target, Optional<ChaseRange> range = {}, Optional<ChaseAngle> angle = {})
: TargetedMovementGeneratorBase(target), i_path(nullptr), i_recheckDistance(0), i_recalculateTravel(true), _range(range), _angle(angle) {}
: TargetedMovementGeneratorBase(target), i_leashExtensionTimer(0), i_path(nullptr), i_recheckDistance(0), i_recalculateTravel(true), _range(range), _angle(angle) {}
~ChaseMovementGenerator() { }
MovementGeneratorType GetMovementGeneratorType() { return CHASE_MOTION_TYPE; }
@@ -59,6 +59,7 @@ public:
bool HasLostTarget(Unit* unit) const { return unit->GetVictim() != this->GetTarget(); }
private:
TimeTrackerSmall i_leashExtensionTimer;
std::unique_ptr<PathGenerator> i_path;
TimeTrackerSmall i_recheckDistance;
bool i_recalculateTravel;
@@ -101,7 +101,9 @@ namespace Movement
moveFlags = (moveFlags & ~(MOVEMENTFLAG_FORWARD)) | MOVEMENTFLAG_BACKWARD;
}
if (moveFlags & MOVEMENTFLAG_ROOT)
bool isOrientationOnly = args.path.size() == 2 && args.path[0] == args.path[1];
if ((moveFlags & MOVEMENTFLAG_ROOT) || isOrientationOnly)
moveFlags &= ~MOVEMENTFLAG_MASK_MOVING;
if (!args.HasVelocity)
+1 -1
View File
@@ -71,7 +71,7 @@ namespace Movement
1.f, 0.f, 0.f, 0.f);
/* classic view:
inline void C_Evaluate(const Vector3 *vertice, float t, const float (&matrix)[4][4], Vector3 &position)
inline void C_Evaluate(Vector3 const* vertice, float t, const float (&matrix)[4][4], Vector3 &position)
{
Vector3 tvec(t*t*t, t*t, t);
int i = 0;
+2 -2
View File
@@ -513,7 +513,7 @@ void OutdoorPvP::HandleKill(Player* killer, Unit* killed)
// creature kills must be notified, even if not inside objective / not outdoor pvp active
// player kills only count if active and inside objective
if ((groupGuy->IsOutdoorPvPActive() && IsInsideObjective(groupGuy)) || killed->GetTypeId() == TYPEID_UNIT)
if ((groupGuy->IsOutdoorPvPActive() && IsInsideObjective(groupGuy)) || killed->IsCreature())
{
HandleKillImpl(groupGuy, killed);
}
@@ -522,7 +522,7 @@ void OutdoorPvP::HandleKill(Player* killer, Unit* killed)
else
{
// creature kills must be notified, even if not inside objective / not outdoor pvp active
if ((killer->IsOutdoorPvPActive() && IsInsideObjective(killer)) || killed->GetTypeId() == TYPEID_UNIT)
if ((killer->IsOutdoorPvPActive() && IsInsideObjective(killer)) || killed->IsCreature())
{
HandleKillImpl(killer, killed);
}
+8 -8
View File
@@ -157,7 +157,7 @@ inline Unit* Map::_GetScriptUnit(Object* obj, bool isSource, const ScriptInfo* s
Unit* unit = nullptr;
if (!obj)
LOG_ERROR("maps.script", "{} {} object is nullptr.", scriptInfo->GetDebugInfo(), isSource ? "source" : "target");
else if (!obj->isType(TYPEMASK_UNIT))
else if (!obj->IsUnit())
LOG_ERROR("maps.script", "{} {} object is not unit (TypeId: {}, Entry: {}, GUID: {}), skipping.",
scriptInfo->GetDebugInfo(), isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUID().ToString());
else
@@ -236,7 +236,7 @@ inline void Map::_ScriptProcessDoor(Object* source, Object* target, const Script
LOG_ERROR("maps.script", "{} door guid is not specified.", scriptInfo->GetDebugInfo());
else if (!source)
LOG_ERROR("maps.script", "{} source object is nullptr.", scriptInfo->GetDebugInfo());
else if (!source->isType(TYPEMASK_UNIT))
else if (!source->IsUnit())
LOG_ERROR("maps.script", "{} source object is not unit ({}), skipping.", scriptInfo->GetDebugInfo(), source->GetGUID().ToString());
else
{
@@ -510,7 +510,7 @@ void Map::ScriptsProcess()
Player* player = target->ToPlayer();
if (player)
{
if (source->GetTypeId() != TYPEID_UNIT && source->GetTypeId() != TYPEID_GAMEOBJECT && source->GetTypeId() != TYPEID_PLAYER)
if (!source->IsCreature() && !source->IsGameObject() && !source->IsPlayer())
{
LOG_ERROR("maps.script", "{} source is not unit, gameobject or player ({}), skipping.", step.script->GetDebugInfo(), source->GetGUID().ToString());
break;
@@ -522,7 +522,7 @@ void Map::ScriptsProcess()
player = source->ToPlayer();
if (player)
{
if (target->GetTypeId() != TYPEID_UNIT && target->GetTypeId() != TYPEID_GAMEOBJECT && target->GetTypeId() != TYPEID_PLAYER)
if (!target->IsCreature() && !target->IsGameObject() && !target->IsPlayer())
{
LOG_ERROR("maps.script", "{} target is not unit, gameobject or player ({}), skipping.", step.script->GetDebugInfo(), target->GetGUID().ToString());
break;
@@ -538,7 +538,7 @@ void Map::ScriptsProcess()
}
// quest id and flags checked at script loading
if ((worldObject->GetTypeId() != TYPEID_UNIT || ((Unit*)worldObject)->IsAlive()) &&
if ((!worldObject->IsCreature() || ((Unit*)worldObject)->IsAlive()) &&
(step.script->QuestExplored.Distance == 0 || worldObject->IsWithinDistInMap(player, float(step.script->QuestExplored.Distance))))
player->GroupEventHappens(step.script->QuestExplored.QuestID, worldObject);
else
@@ -641,7 +641,7 @@ void Map::ScriptsProcess()
break;
}
if (target->GetTypeId() != TYPEID_GAMEOBJECT)
if (!target->IsGameObject())
{
LOG_ERROR("maps.script", "{} target object is not gameobject ({}), skipping.", step.script->GetDebugInfo(), target->GetGUID().ToString());
break;
@@ -697,13 +697,13 @@ void Map::ScriptsProcess()
break;
}
if (!uSource || !uSource->isType(TYPEMASK_UNIT))
if (!uSource || !uSource->IsUnit())
{
LOG_ERROR("maps.script", "{} no source unit found for spell {}", step.script->GetDebugInfo(), step.script->CastSpell.SpellID);
break;
}
if (!uTarget || !uTarget->isType(TYPEMASK_UNIT))
if (!uTarget || !uTarget->IsUnit())
{
LOG_ERROR("maps.script", "{} no target unit found for spell {}", step.script->GetDebugInfo(), step.script->CastSpell.SpellID);
break;
@@ -34,6 +34,11 @@ bool ScriptMgr::CanSaveToDB(ArenaTeam* team)
CALL_ENABLED_BOOLEAN_HOOKS(ArenaScript, ARENAHOOK_CAN_SAVE_TO_DB, !script->CanSaveToDB(team));
}
bool ScriptMgr::OnBeforeArenaCheckWinConditions(Battleground* const bg)
{
CALL_ENABLED_BOOLEAN_HOOKS(ArenaScript, ARENAHOOK_ON_BEFORE_CHECK_WIN_CONDITION, !script->OnBeforeArenaCheckWinConditions(bg));
}
ArenaScript::ArenaScript(const char* name, std::vector<uint16> enabledHooks)
: ScriptObject(name, ARENAHOOK_END)
{

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