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
@@ -14,7 +14,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Setup python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: AzerothCore codestyle
+10 -10
View File
@@ -62,12 +62,12 @@ def isPAppend(line):
else :
return False
# def isStringFormat(line):
# substring = 'StringFormat'
# if substring in line:
# return True
# else :
# return False
def isStringFormat(line):
substring = 'StringFormat'
if substring in line:
return True
else :
return False
def haveDelimeter(line):
if ';' in line:
@@ -96,8 +96,8 @@ def checkSoloLine(line):
# return handleCleanup(line), False
# elif isPSendSysMessage(line):
# return handleCleanup(line), False
# elif isStringFormat(line):
# return handleCleanup(line), False
elif isStringFormat(line):
return handleCleanup(line), False
else:
return line, False
@@ -122,8 +122,8 @@ def startMultiLine(line):
elif isPAppend(line):
line = line.replace("PAppend", "Append");
return handleCleanup(line), True
# elif isStringFormat(line):
# return handleCleanup(line), True
elif isStringFormat(line):
return handleCleanup(line), True
else :
return line, False
+91 -7
View File
@@ -1,6 +1,7 @@
import io
import os
import sys
import re
# Get the src directory of the project
src_directory = os.path.join(os.getcwd(), 'src')
@@ -11,8 +12,11 @@ results = {
"Multiple blank lines check": "Passed",
"Trailing whitespace check": "Passed",
"GetCounter() check": "Passed",
"Misc codestyle check": "Passed",
"GetTypeId() check": "Passed",
"NpcFlagHelpers check": "Passed"
"NpcFlagHelpers check": "Passed",
"ItemFlagHelpers check": "Passed",
"ItemTemplateFlagHelpers check": "Passed"
}
# Main function to parse all the files of the project
@@ -27,10 +31,15 @@ def parsing_file(directory: str) -> None:
multiple_blank_lines_check(file, file_path)
trailing_whitespace_check(file, file_path)
get_counter_check(file, file_path)
misc_codestyle_check(file, file_path)
if file_name != 'Object.h':
get_typeid_check(file, file_path)
if file_name != 'Unit.h':
npcflags_helpers_check(file, file_path)
if file_name != 'Item.h':
itemflag_helpers_check(file, file_path)
if file_name != 'ItemTemplate.h':
itemtemplateflag_helpers_check(file, file_path)
except UnicodeDecodeError:
print(f"\nCould not decode file {file_path}")
sys.exit(1)
@@ -99,14 +108,20 @@ def get_typeid_check(file: io, file_path: str) -> None:
check_failed = False
# Parse all the file
for line_number, line in enumerate(file, start = 1):
if 'GetTypeId() == TYPEID_PLAYER' in line:
print(f"Please use IsPlayer() instead GetTypeId(): {file_path} at line {line_number}")
if 'GetTypeId() == TYPEID_ITEM' in line or 'GetTypeId() != TYPEID_ITEM' in line:
print(f"Please use IsItem() instead of GetTypeId(): {file_path} at line {line_number}")
check_failed = True
if 'GetTypeId() == TYPEID_ITEM' in line:
print(f"Please use IsItem() instead GetTypeId(): {file_path} at line {line_number}")
if 'GetTypeId() == TYPEID_UNIT' in line or 'GetTypeId() != TYPEID_UNIT' in line:
print(f"Please use IsCreature() instead of GetTypeId(): {file_path} at line {line_number}")
check_failed = True
if 'GetTypeId() == TYPEID_DYNOBJECT' in line:
print(f"Please use IsDynamicObject() instead GetTypeId(): {file_path} at line {line_number}")
if 'GetTypeId() == TYPEID_PLAYER' in line or 'GetTypeId() != TYPEID_PLAYER' in line:
print(f"Please use IsPlayer() instead of GetTypeId(): {file_path} at line {line_number}")
check_failed = True
if 'GetTypeId() == TYPEID_GAMEOBJECT' in line or 'GetTypeId() != TYPEID_GAMEOBJECT' in line:
print(f"Please use IsGameObject() instead of GetTypeId(): {file_path} at line {line_number}")
check_failed = True
if 'GetTypeId() == TYPEID_DYNOBJECT' in line or 'GetTypeId() != TYPEID_DYNOBJECT' in line:
print(f"Please use IsDynamicObject() instead of GetTypeId(): {file_path} at line {line_number}")
check_failed = True
# Handle the script error and update the result output
if check_failed:
@@ -139,10 +154,79 @@ def npcflags_helpers_check(file: io, file_path: str) -> None:
if 'RemoveFlag(UNIT_NPC_FLAGS,' in line:
print(
f"Please use RemoveNpcFlag() instead RemoveFlag(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}")
check_failed = True
# Handle the script error and update the result output
if check_failed:
error_handler = True
results["NpcFlagHelpers check"] = "Failed"
# Codestyle patterns checking for ItemFlag helpers
def itemflag_helpers_check(file: io, file_path: str) -> None:
global error_handler, results
file.seek(0) # Reset file pointer to the beginning
check_failed = False
# Parse all the file
for line_number, line in enumerate(file, start = 1):
if 'HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE)' in line:
print(
f"Please use IsRefundable() instead of HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE): {file_path} at line {line_number}")
check_failed = True
if 'HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE)' in line:
print(
f"Please use IsBOPTradable() instead of HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE): {file_path} at line {line_number}")
check_failed = True
if 'HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)' in line:
print(
f"Please use IsWrapped() instead of HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED): {file_path} at line {line_number}")
check_failed = True
# Handle the script error and update the result output
if check_failed:
error_handler = True
results["ItemFlagHelpers check"] = "Failed"
# Codestyle patterns checking for ItemTemplate helpers
def itemtemplateflag_helpers_check(file: io, file_path: str) -> None:
global error_handler, results
file.seek(0) # Reset file pointer to the beginning
check_failed = False
# Parse all the file
for line_number, line in enumerate(file, start = 1):
if 'Flags & ITEM_FLAG' in line:
print(
f"Please use HasFlag(ItemFlag) instead of 'Flags & ITEM_FLAG_': {file_path} at line {line_number}")
check_failed = True
if 'Flags2 & ITEM_FLAG2' in line:
print(
f"Please use HasFlag2(ItemFlag2) instead of 'Flags2 & ITEM_FLAG2_': {file_path} at line {line_number}")
check_failed = True
if 'FlagsCu & ITEM_FLAGS_CU' in line:
print(
f"Please use HasFlagCu(ItemFlagsCustom) instead of 'FlagsCu & ITEM_FLAGS_CU_': {file_path} at line {line_number}")
check_failed = True
# Handle the script error and update the result output
if check_failed:
error_handler = True
results["ItemTemplateFlagHelpers check"] = "Failed"
# Codestyle patterns checking for various codestyle issues
def misc_codestyle_check(file: io, file_path: str) -> None:
global error_handler, results
file.seek(0) # Reset file pointer to the beginning
check_failed = False
# Parse all the file
for line_number, line in enumerate(file, start = 1):
if 'const auto&' in line:
print(
f"Please use 'auto const&' syntax instead of 'const auto&': {file_path} at line {line_number}")
check_failed = True
if re.search(r'\bconst\s+\w+\s*\*\b', line):
print(
f"Please use the syntax 'Class/ObjectType const*' instead of 'const Class/ObjectType*': {file_path} at line {line_number}")
check_failed = True
# Handle the script error and update the result output
if check_failed:
error_handler = True
results["Misc codestyle check"] = "Failed"
# Main function
parsing_file(src_directory)
@@ -0,0 +1,11 @@
-- DB update 2024_07_05_00 -> 2024_09_03_00
DROP TABLE IF EXISTS `character_achievement_offline_updates`;
CREATE TABLE `character_achievement_offline_updates` (
`guid` BIGINT UNSIGNED NOT NULL COMMENT 'Character\'s GUID',
`update_type` TINYINT UNSIGNED NOT NULL COMMENT 'Supported types: 1 - COMPLETE_ACHIEVEMENT; 2 - UPDATE_CRITERIA',
`arg1` INT UNSIGNED NOT NULL COMMENT 'For type 1: achievement ID; for type 2: ACHIEVEMENT_CRITERIA_TYPE',
`arg2` INT UNSIGNED DEFAULT NULL COMMENT 'For type 2: miscValue1 for updating achievement criteria',
`arg3` INT UNSIGNED DEFAULT NULL COMMENT 'For type 2: miscValue2 for updating achievement criteria',
INDEX `idx_guid` (`guid`)
)
COMMENT = 'Stores updates to character achievements when the character was offline';
@@ -0,0 +1,2 @@
-- DB update 2024_08_30_00 -> 2024_08_30_01
UPDATE `creature_template` SET `flags_extra` = `flags_extra`|256 WHERE `entry` = 22948;
@@ -0,0 +1,4 @@
-- DB update 2024_08_30_01 -> 2024_08_30_02
--
DELETE FROM `spell_script_names` WHERE `spell_id`=39497;
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES(39497, 'spell_kaelthas_remove_enchanted_weapons');
@@ -0,0 +1,6 @@
-- DB update 2024_08_30_02 -> 2024_08_31_00
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 21806;
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 21806) AND (`source_type` = 0) AND (`id` IN (5));
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(21806, 0, 5, 0, 0, 0, 23, 0, 10000, 30000, 10000, 30000, 0, 0, 11, 37527, 0, 0, 0, 0, 0, 5, 40, 0, 0, 0, 0, 0, 0, 0, 'Greyheart Spellbinder - In Combat - Cast Banish');
@@ -0,0 +1,10 @@
-- DB update 2024_08_31_00 -> 2024_08_31_01
UPDATE `item_template`
SET `stat_type1` = 5,
`stat_value1` = 20,
`stat_type2` = 7,
`stat_value2` = 13,
`stat_type3` = 42,
`stat_value3` = 25,
`StatsCount` = 3
WHERE (`entry` = 13113);
@@ -0,0 +1,3 @@
-- DB update 2024_08_31_01 -> 2024_09_01_00
--
UPDATE `creature_template` SET `unit_flags` = 33554432 WHERE `entry` = 23429;
@@ -0,0 +1,2 @@
-- DB update 2024_09_01_00 -> 2024_09_02_00
UPDATE `creature_template` SET `speed_run` = 0.785714 WHERE `entry` = 23111;
@@ -0,0 +1,3 @@
-- DB update 2024_09_02_00 -> 2024_09_02_01
DELETE FROM `spell_custom_attr` WHERE `spell_id` = 40253;
INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES (40253, 536870912);
@@ -0,0 +1,4 @@
-- DB update 2024_09_02_01 -> 2024_09_03_00
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 22960) AND (`source_type` = 0) AND (`id` IN (0));
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(22960, 0, 0, 0, 0, 0, 40, 0, 0, 10000, 0, 10000, 0, 0, 11, 40895, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Dragonmaw Wyrmcaller - In Combat - Cast \'Jab\'');
@@ -0,0 +1,7 @@
-- DB update 2024_09_03_00 -> 2024_09_03_01
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 17803;
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 17803) AND (`source_type` = 0) AND (`id` IN (0, 1));
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(17803, 0, 0, 0, 0, 0, 100, 2, 5000, 8000, 13000, 16000, 0, 0, 11, 22582, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Oracle - In Combat - Cast \'Frost Shock\' (Normal Dungeon)'),
(17803, 0, 1, 0, 0, 0, 100, 4, 5000, 8000, 13000, 16000, 0, 0, 11, 37865, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Coilfang Oracle - In Combat - Cast \'Frost Shock\' (Heroic Dungeon)');
+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; }
+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;
+1
View File
@@ -884,6 +884,7 @@ enum PlayerLoginQueryIndex
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)
{
@@ -829,6 +829,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
if (quest->GetRewSpellCast() > 0)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpellCast()))
if (questGiver->IsUnit() && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
{
if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
{
@@ -842,6 +843,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
else if (quest->GetRewSpell() > 0)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpell()))
if (questGiver->IsUnit() && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
{
if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
{
@@ -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())

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