Merge branch 'master' into Playerbot
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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)');
|
||||
@@ -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(" ██╔══██╗╚══███╔╝██╔════╝██╔══██╗██╔═══██╗╚══██╔══╝██║ ██║");
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<>
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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()))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
@@ -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)...);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user