Merge branch 'master' into Playerbot
This commit is contained in:
@@ -48,4 +48,4 @@ mark_as_advanced(
|
||||
GPERFTOOLS_PROFILER
|
||||
GPERFTOOLS_TCMALLOC_AND_PROFILER
|
||||
GPERFTOOLS_LIBRARIES
|
||||
GPERFTOOLS_INCLUDE_DIR)
|
||||
GPERFTOOLS_INCLUDE_DIR)
|
||||
|
||||
@@ -45,4 +45,4 @@ macro(GroupSources dir)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endmacro()
|
||||
endmacro()
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
#include "MapDefines.h"
|
||||
#include "MapTree.h"
|
||||
#include "VMapDefinitions.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <iomanip>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using G3D::Vector3;
|
||||
using G3D::AABox;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "OpenSSLCrypto.h"
|
||||
#include "Errors.h"
|
||||
#include <openssl/crypto.h> // NOTE: this import is NEEDED (even though some IDEs report it as unused)
|
||||
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x1010000fL
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
|
||||
#include "Define.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
/** ObjectRegistry holds all registry item of the same type
|
||||
*/
|
||||
|
||||
@@ -68,13 +68,13 @@ public:
|
||||
bool SetLogLevel(std::string const& name, int32 level, bool isLogger = true);
|
||||
|
||||
template<typename... Args>
|
||||
inline void outMessage(std::string const& filter, LogLevel const level, std::string_view fmt, Args&&... 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)...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void outCommand(uint32 account, std::string_view fmt, Args&&... args)
|
||||
void outCommand(uint32 account, Acore::FormatString<Args...> fmt, Args&&... args)
|
||||
{
|
||||
if (!ShouldLog("commands.gm", LOG_LEVEL_INFO))
|
||||
{
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "LogCommon.h"
|
||||
#include "Define.h"
|
||||
#include "LogCommon.h"
|
||||
#include "SmartEnum.h"
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ void Metric::LoadFromConfigs()
|
||||
{
|
||||
bool previousValue = _enabled;
|
||||
_enabled = sConfigMgr->GetOption<bool>("Metric.Enable", false);
|
||||
_updateInterval = sConfigMgr->GetOption<int32>("Metric.Interval", 10);
|
||||
_updateInterval = sConfigMgr->GetOption<int32>("Metric.Interval", 1);
|
||||
|
||||
if (_updateInterval < 1)
|
||||
{
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
*/
|
||||
|
||||
#include "ProcessPriority.h"
|
||||
#include "Log.h"
|
||||
|
||||
#ifdef _WIN32 // Windows
|
||||
#include <Windows.h>
|
||||
#elif defined(__linux__)
|
||||
#include "Log.h"
|
||||
#include <sched.h>
|
||||
#include <sys/resource.h>
|
||||
#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "Define.h"
|
||||
#include "Duration.h"
|
||||
#include "Random.h"
|
||||
#include "advstd.h"
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -90,7 +89,7 @@ class LambdaBasicEvent : public BasicEvent
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using is_lambda_event = std::enable_if_t<!std::is_base_of_v<BasicEvent, std::remove_pointer_t<advstd::remove_cvref_t<T>>>>;
|
||||
using is_lambda_event = std::enable_if_t<!std::is_base_of_v<BasicEvent, std::remove_pointer_t<std::remove_cvref_t<T>>>>;
|
||||
|
||||
typedef std::multimap<uint64, BasicEvent*> EventList;
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "StringFormat.h"
|
||||
#include "Define.h"
|
||||
#include <locale>
|
||||
|
||||
template<class Str>
|
||||
AC_COMMON_API Str Acore::String::Trim(const Str& s, const std::locale& loc /*= std::locale()*/)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Define.h"
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/printf.h>
|
||||
#include <locale>
|
||||
|
||||
namespace Acore
|
||||
{
|
||||
@@ -39,17 +40,20 @@ namespace Acore
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
using FormatString = fmt::format_string<Args...>;
|
||||
|
||||
// Default string format function.
|
||||
template<typename... Args>
|
||||
inline std::string StringFormatFmt(std::string_view fmt, Args&&... args)
|
||||
inline std::string StringFormatFmt(FormatString<Args...> fmt, Args&&... args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return fmt::format(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
catch (const fmt::format_error& formatError)
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
return fmt::format("An error occurred formatting string \"{}\": {}", fmt, formatError.what());
|
||||
return fmt::format("Wrong format occurred ({}). Fmt string: '{}'", e.what(), fmt.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,4 +80,9 @@ namespace Acore::String
|
||||
AC_COMMON_API std::string AddSuffixIfNotExists(std::string str, const char suffix);
|
||||
}
|
||||
|
||||
// Add support enum for fmt
|
||||
//template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
|
||||
template <typename T, FMT_ENABLE_IF(std::is_enum_v<T>)>
|
||||
auto format_as(T f) { return fmt::underlying(f); }
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#ifndef _TYPES_H_
|
||||
#define _TYPES_H_
|
||||
|
||||
#include "advstd.h"
|
||||
|
||||
namespace Acore
|
||||
{
|
||||
// end "iterator" tag for find_type_if
|
||||
@@ -35,7 +33,7 @@ namespace Acore
|
||||
};
|
||||
|
||||
template<template<typename...> typename Check, typename T1, typename... Ts>
|
||||
struct find_type_if<Check, T1, Ts...> : std::conditional_t<Check<T1>::value, advstd::type_identity<T1>, find_type_if<Check, Ts...>>
|
||||
struct find_type_if<Check, T1, Ts...> : std::conditional_t<Check<T1>::value, std::type_identity<T1>, find_type_if<Check, Ts...>>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@@ -24,22 +24,6 @@
|
||||
// this namespace holds implementations of upcoming stdlib features that our c++ version doesn't have yet
|
||||
namespace advstd
|
||||
{
|
||||
// This workaround for std::remove_cvref_t, std::type_identify is needed for GCC 8...
|
||||
/// @todo: remove when we drop GCC 8 support. https://en.cppreference.com/w/cpp/compiler_support/20
|
||||
// C++20 advstd::remove_cvref_t
|
||||
template <class T>
|
||||
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
|
||||
// C++20 std::type_identity
|
||||
template <typename T>
|
||||
struct type_identity
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
// C++20 std::type_identity_t
|
||||
template <typename T>
|
||||
using type_identity_t = typename type_identity<T>::type;
|
||||
}
|
||||
|
||||
#endif // _ADV_STD_H_
|
||||
|
||||
@@ -190,4 +190,4 @@ foreach(APPLICATION_NAME ${APPLICATIONS_BUILD_LIST})
|
||||
if (USE_COREPCH AND EXISTS ${PATH_TO_PCH})
|
||||
add_cxx_pch(${APP_PROJECT_NAME} ${PATH_TO_PCH})
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
#include "Log.h"
|
||||
#include "RealmList.h"
|
||||
#include "SecretMgr.h"
|
||||
#include "StringConvert.h"
|
||||
#include "TOTP.h"
|
||||
#include "Timer.h"
|
||||
#include "Util.h"
|
||||
#include "StringConvert.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Duration.h"
|
||||
#include "Log.h"
|
||||
#include "SRP6.h"
|
||||
#include "MotdMgr.h"
|
||||
#include "SRP6.h"
|
||||
#include "Util.h"
|
||||
#include "World.h"
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
@@ -780,11 +780,13 @@ Metric.Enable = 0
|
||||
|
||||
#
|
||||
# Metric.Interval
|
||||
# Description: Interval between every batch of data sent in seconds
|
||||
# Default: 10 seconds
|
||||
# Description: Interval between every batch of data sent in seconds.
|
||||
# Longer interval means larger batch of data. If the batch
|
||||
# is too big, it might get rejected.
|
||||
# Default: 1 second
|
||||
#
|
||||
|
||||
Metric.Interval = 10
|
||||
Metric.Interval = 1
|
||||
|
||||
#
|
||||
# Metric.ConnectionInfo
|
||||
@@ -939,13 +941,6 @@ ClientCacheVersion = 0
|
||||
|
||||
SessionAddDelay = 10000
|
||||
|
||||
#
|
||||
# GridCleanUpDelay
|
||||
# Description: Time (in milliseconds) grid clean up delay.
|
||||
# Default: 300000 - (5 minutes)
|
||||
|
||||
GridCleanUpDelay = 300000
|
||||
|
||||
#
|
||||
# CloseIdleConnections
|
||||
# Description: Automatically close idle connections.
|
||||
@@ -1251,17 +1246,17 @@ Visibility.GroupMode = 1
|
||||
# Visibility.Distance.Instances
|
||||
# Visibility.Distance.BGArenas
|
||||
# Description: Visibility distance to see other players or gameobjects.
|
||||
# Visibility on continents on retail ~100 yards. In BG/Arenas ~533.
|
||||
# For instances default ~170.
|
||||
# Max limited by grid size: 533.33333
|
||||
# Visibility on continents on retail ~90 yards. In BG/Arenas ~180.
|
||||
# For instances default ~120.
|
||||
# Max limited by active player zone: ~ 333
|
||||
# Min limit is max aggro radius (45) * Rate.Creature.Aggro
|
||||
# Default: 100 - (Visibility.Distance.Continents)
|
||||
# 170 - (Visibility.Distance.Instances)
|
||||
# 533 - (Visibility.Distance.BGArenas)
|
||||
# Default: 90 - (Visibility.Distance.Continents)
|
||||
# 120 - (Visibility.Distance.Instances)
|
||||
# 180 - (Visibility.Distance.BGArenas)
|
||||
|
||||
Visibility.Distance.Continents = 100
|
||||
Visibility.Distance.Instances = 170
|
||||
Visibility.Distance.BGArenas = 533
|
||||
Visibility.Distance.Continents = 90
|
||||
Visibility.Distance.Instances = 120
|
||||
Visibility.Distance.BGArenas = 180
|
||||
|
||||
#
|
||||
# Visibility.Notify.Period.OnContinents
|
||||
@@ -1372,22 +1367,13 @@ DetectPosCollision = 1
|
||||
|
||||
CheckGameObjectLoS = 1
|
||||
|
||||
#
|
||||
# GridUnload
|
||||
# Description: Unload grids to save memory. Can be disabled if enough memory is available
|
||||
# to speed up moving players to new grids.
|
||||
# Default: 1 - (enable, Unload grids)
|
||||
# 0 - (disable, Do not unload grids)
|
||||
|
||||
GridUnload = 1
|
||||
|
||||
#
|
||||
# PreloadAllNonInstancedMapGrids
|
||||
# Description: Preload all grids on all non-instanced maps. Requires GridUnload to be disabled.
|
||||
# This will take a great amount of additional RAM (ca. 9 GB) and causes the server
|
||||
# to take longer to start, but can increase performance if used on a server with a
|
||||
# high amount of players. It will also activate all creatures which are set active
|
||||
# (e.g. the Fel Reavers in Hellfire Peninsula) on server start.
|
||||
# Description: Preload all grids on all non-instanced maps. This will take a great amount
|
||||
# of additional RAM (ca. 9 GB) and causes the server to take longer to start,
|
||||
# but can increase performance if used on a server with a high amount of players.
|
||||
# It will also activate all creatures which are set active (e.g. the Fel Reavers
|
||||
# in Hellfire Peninsula) on server start.
|
||||
# Default: 0 - (Disabled)
|
||||
# 1 - (Enabled)
|
||||
|
||||
@@ -2061,6 +2047,13 @@ Rate.Damage.Fall = 1
|
||||
|
||||
Rate.Talent = 1
|
||||
|
||||
#
|
||||
# Rate.Talent.Pet
|
||||
# Description: Pet Talent point rate.
|
||||
# Default: 1
|
||||
|
||||
Rate.Talent.Pet = 1
|
||||
|
||||
#
|
||||
# Rate.Health
|
||||
# Rate.Mana
|
||||
@@ -3363,6 +3356,13 @@ Guild.BankTabCost3 = 10000000
|
||||
Guild.BankTabCost4 = 25000000
|
||||
Guild.BankTabCost5 = 50000000#
|
||||
|
||||
#
|
||||
# Guild.MemberLimit
|
||||
# Description: Do not allow inviting new players to the guild if the member limit is met or exceeded.
|
||||
# Default: 0 - Disabled
|
||||
|
||||
Guild.MemberLimit = 0
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
@@ -4355,6 +4355,13 @@ TeleportTimeoutNear = 25
|
||||
|
||||
TeleportTimeoutFar = 45
|
||||
|
||||
#
|
||||
# DailyRBGArenaPoints.MinLevel
|
||||
# Description: Allows gaining arena points on the first RBG win at level 70.
|
||||
# Default: 71 - (Blizzlike)
|
||||
|
||||
DailyRBGArenaPoints.MinLevel = 71
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
#include "SQLOperation.h"
|
||||
#include "Transaction.h"
|
||||
#include "WorldDatabase.h"
|
||||
#include <mysqld_error.h>
|
||||
#include <limits>
|
||||
#include <mysqld_error.h>
|
||||
|
||||
#ifdef ACORE_DEBUG
|
||||
#include <boost/stacktrace.hpp>
|
||||
|
||||
@@ -581,7 +581,7 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo, uint8 attempts /*= 5*/)
|
||||
{
|
||||
LOG_FATAL("sql.sql", "Could not re-prepare statements!");
|
||||
std::this_thread::sleep_for(10s);
|
||||
std::abort();
|
||||
ABORT();
|
||||
}
|
||||
|
||||
LOG_INFO("sql.sql", "Successfully reconnected to {} @{}:{} ({}).",
|
||||
@@ -600,7 +600,7 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo, uint8 attempts /*= 5*/)
|
||||
|
||||
// We could also initiate a shutdown through using std::raise(SIGTERM)
|
||||
std::this_thread::sleep_for(10s);
|
||||
std::abort();
|
||||
ABORT();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -624,12 +624,12 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo, uint8 attempts /*= 5*/)
|
||||
case ER_NO_SUCH_TABLE:
|
||||
LOG_ERROR("sql.sql", "Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders.");
|
||||
std::this_thread::sleep_for(10s);
|
||||
std::abort();
|
||||
ABORT();
|
||||
return false;
|
||||
case ER_PARSE_ERROR:
|
||||
LOG_ERROR("sql.sql", "Error while parsing SQL. Core fix required.");
|
||||
std::this_thread::sleep_for(10s);
|
||||
std::abort();
|
||||
ABORT();
|
||||
return false;
|
||||
default:
|
||||
LOG_ERROR("sql.sql", "Unhandled MySQL errno {}. Unexpected behaviour possible.", errNo);
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
KillMagnetEvent(Unit& self) : _self(self) { }
|
||||
bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override
|
||||
{
|
||||
_self.setDeathState(JUST_DIED);
|
||||
_self.setDeathState(DeathState::JustDied);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ struct PowerUsersSelector : public Acore::unary_function<Unit*, bool>
|
||||
|
||||
struct FarthestTargetSelector : public Acore::unary_function<Unit*, bool>
|
||||
{
|
||||
FarthestTargetSelector(Unit const* unit, float dist, bool playerOnly, bool inLos) : _me(unit), _dist(dist), _playerOnly(playerOnly), _inLos(inLos) {}
|
||||
FarthestTargetSelector(Unit const* unit, float maxDist, bool playerOnly, bool inLos, float minDist = 0.f) : _me(unit), _minDist(minDist), _maxDist(maxDist), _playerOnly(playerOnly), _inLos(inLos) {}
|
||||
|
||||
bool operator()(Unit const* target) const
|
||||
{
|
||||
@@ -162,7 +162,7 @@ struct FarthestTargetSelector : public Acore::unary_function<Unit*, bool>
|
||||
if (_playerOnly && target->GetTypeId() != TYPEID_PLAYER)
|
||||
return false;
|
||||
|
||||
if (_dist > 0.0f && !_me->IsWithinCombatRange(target, _dist))
|
||||
if (_maxDist > 0.0f && !_me->IsInRange(target, _minDist, _maxDist))
|
||||
return false;
|
||||
|
||||
if (_inLos && !_me->IsWithinLOSInMap(target))
|
||||
@@ -173,7 +173,7 @@ struct FarthestTargetSelector : public Acore::unary_function<Unit*, bool>
|
||||
|
||||
private:
|
||||
Unit const* _me;
|
||||
float _dist;
|
||||
float _minDist, _maxDist;
|
||||
bool _playerOnly;
|
||||
bool _inLos;
|
||||
};
|
||||
@@ -364,6 +364,13 @@ public:
|
||||
// Called when the unit heals
|
||||
virtual void HealDone(Unit* /*done_to*/, uint32& /*addhealth*/) {}
|
||||
|
||||
// Called during damage calculations
|
||||
virtual void OnCalculateMeleeDamageReceived(uint32& /*damage*/, Unit* /*attacker*/) {}
|
||||
virtual void OnCalculateSpellDamageReceived(int32& /*damage*/, Unit* /*attacker*/) {}
|
||||
|
||||
// Called during calculation when receiving periodic healing or damage (DoT or HoT)
|
||||
virtual void OnCalculatePeriodicTickReceived(uint32& /*damage*/, Unit* /*attacker*/) {}
|
||||
|
||||
void AttackStartCaster(Unit* victim, float dist);
|
||||
|
||||
SpellCastResult DoAddAuraToAllHostilePlayers(uint32 spellid);
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AreaBoundary.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "AreaBoundary.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "CreatureGroups.h"
|
||||
@@ -24,8 +24,8 @@
|
||||
#include "Log.h"
|
||||
#include "MapReference.h"
|
||||
#include "Player.h"
|
||||
#include "Vehicle.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "Vehicle.h"
|
||||
#include "ZoneScript.h"
|
||||
|
||||
//Disable CreatureAI when charmed
|
||||
|
||||
@@ -21,8 +21,9 @@
|
||||
#include "AreaBoundary.h"
|
||||
#include "Common.h"
|
||||
#include "Creature.h"
|
||||
#include "UnitAI.h"
|
||||
#include "EventMap.h"
|
||||
#include "TaskScheduler.h"
|
||||
#include "UnitAI.h"
|
||||
|
||||
class WorldObject;
|
||||
class Unit;
|
||||
@@ -72,6 +73,7 @@ protected:
|
||||
Creature* const me;
|
||||
|
||||
EventMap events;
|
||||
TaskScheduler scheduler;
|
||||
|
||||
bool UpdateVictim();
|
||||
bool UpdateVictimWithGaze();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "CreatureAIRegistry.h"
|
||||
#include "CombatAI.h"
|
||||
#include "CreatureAIFactory.h"
|
||||
#include "GameObjectAIFactory.h"
|
||||
#include "GuardAI.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "PassiveAI.h"
|
||||
@@ -27,7 +28,6 @@
|
||||
#include "SmartAI.h"
|
||||
#include "TotemAI.h"
|
||||
#include "WaypointMovementGenerator.h"
|
||||
#include "GameObjectAIFactory.h"
|
||||
|
||||
namespace AIRegistry
|
||||
{
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "CreatureAISelector.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAIFactory.h"
|
||||
|
||||
#include "MovementGenerator.h"
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#ifndef ACORE_CREATUREAISELECTOR_H
|
||||
#define ACORE_CREATUREAISELECTOR_H
|
||||
|
||||
#include "Define.h"
|
||||
|
||||
class CreatureAI;
|
||||
class Creature;
|
||||
class MovementGenerator;
|
||||
@@ -31,4 +33,5 @@ namespace FactorySelector
|
||||
AC_GAME_API MovementGenerator* SelectMovementGenerator(Unit* unit);
|
||||
AC_GAME_API GameObjectAI* SelectGameObjectAI(GameObject* go);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
#ifndef ACORE_GAMEOBJECTAIFACTORY_H
|
||||
#define ACORE_GAMEOBJECTAIFACTORY_H
|
||||
|
||||
#include "ObjectRegistry.h"
|
||||
#include "FactoryHolder.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "ObjectRegistry.h"
|
||||
|
||||
typedef FactoryHolder<GameObjectAI, GameObject> GameObjectAICreator;
|
||||
|
||||
|
||||
@@ -311,6 +311,29 @@ Creature* ScriptedAI::DoSpawnCreature(uint32 entry, float offsetX, float offsetY
|
||||
return me->SummonCreature(entry, me->GetPositionX() + offsetX, me->GetPositionY() + offsetY, me->GetPositionZ() + offsetZ, angle, TempSummonType(type), despawntime);
|
||||
}
|
||||
|
||||
void ScriptedAI::ScheduleTimedEvent(Milliseconds timerMin, Milliseconds timerMax, std::function<void()> exec, Milliseconds repeatMin, Milliseconds repeatMax, uint32 uniqueId)
|
||||
{
|
||||
if (uniqueId && IsUniqueTimedEventDone(uniqueId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
scheduler.Schedule(timerMin == 0s ? timerMax : timerMin, timerMax, [exec, repeatMin, repeatMax, uniqueId](TaskContext context)
|
||||
{
|
||||
exec();
|
||||
|
||||
if (!uniqueId)
|
||||
{
|
||||
repeatMax > 0s ? context.Repeat(repeatMin, repeatMax) : context.Repeat(repeatMin);
|
||||
}
|
||||
});
|
||||
|
||||
if (uniqueId)
|
||||
{
|
||||
SetUniqueTimedEventDone(uniqueId);
|
||||
}
|
||||
}
|
||||
|
||||
SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, uint32 powerCostMin, uint32 powerCostMax, float rangeMin, float rangeMax, SelectEffect effects)
|
||||
{
|
||||
//No target so we can't cast
|
||||
@@ -556,6 +579,13 @@ BossAI::BossAI(Creature* creature, uint32 bossId) : ScriptedAI(creature),
|
||||
{
|
||||
if (instance)
|
||||
SetBoundary(instance->GetBossBoundary(bossId));
|
||||
|
||||
// Prevents updating the scheduler's timer while the creature is casting.
|
||||
// Clear it in the script if you need it to update while the creature is casting.
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
bool BossAI::CanRespawn()
|
||||
@@ -581,6 +611,7 @@ void BossAI::_Reset()
|
||||
events.Reset();
|
||||
scheduler.CancelAll();
|
||||
summons.DespawnAll();
|
||||
ClearUniqueTimedEventsDone();
|
||||
_healthCheckEvents.clear();
|
||||
if (instance)
|
||||
instance->SetBossState(_bossId, NOT_STARTED);
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "EventMap.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
#define CAST_AI(a, b) (dynamic_cast<a*>(b))
|
||||
@@ -353,6 +353,18 @@ struct ScriptedAI : public CreatureAI
|
||||
//Spawns a creature relative to me
|
||||
Creature* DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, uint32 despawntime);
|
||||
|
||||
bool IsUniqueTimedEventDone(uint32 id) const { return _uniqueTimedEvents.find(id) != _uniqueTimedEvents.end(); }
|
||||
void SetUniqueTimedEventDone(uint32 id) { _uniqueTimedEvents.insert(id); }
|
||||
void ResetUniqueTimedEvent(uint32 id) { _uniqueTimedEvents.erase(id); }
|
||||
void ClearUniqueTimedEventsDone() { _uniqueTimedEvents.clear(); }
|
||||
|
||||
// Schedules a timed event using task scheduler.
|
||||
void ScheduleTimedEvent(Milliseconds timerMin, Milliseconds timerMax, std::function<void()> exec, Milliseconds repeatMin, Milliseconds repeatMax = 0s, uint32 uniqueId = 0);
|
||||
void ScheduleTimedEvent(Milliseconds timerMax, std::function<void()> exec, Milliseconds repeatMin, Milliseconds repeatMax = 0s, uint32 uniqueId = 0) { ScheduleTimedEvent(0s, timerMax, exec, repeatMin, repeatMax, uniqueId); };
|
||||
|
||||
// Schedules a timed event using task scheduler that never repeats. Requires an unique non-zero ID.
|
||||
void ScheduleUniqueTimedEvent(Milliseconds timer, std::function<void()> exec, uint32 uniqueId) { ScheduleTimedEvent(0s, timer, exec, 0s, 0s, uniqueId); };
|
||||
|
||||
bool HealthBelowPct(uint32 pct) const { return me->HealthBelowPct(pct); }
|
||||
bool HealthAbovePct(uint32 pct) const { return me->HealthAbovePct(pct); }
|
||||
|
||||
@@ -442,6 +454,7 @@ private:
|
||||
Difficulty _difficulty;
|
||||
bool _isCombatMovementAllowed;
|
||||
bool _isHeroic;
|
||||
std::unordered_set<uint32> _uniqueTimedEvents;
|
||||
};
|
||||
|
||||
struct HealthCheckEventData
|
||||
@@ -494,9 +507,7 @@ protected:
|
||||
|
||||
void TeleportCheaters();
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
TaskScheduler scheduler;
|
||||
|
||||
private:
|
||||
uint32 const _bossId;
|
||||
|
||||
@@ -259,7 +259,7 @@ void npc_escortAI::UpdateAI(uint32 diff)
|
||||
|
||||
if (m_bCanInstantRespawn)
|
||||
{
|
||||
me->setDeathState(JUST_DIED);
|
||||
me->setDeathState(DeathState::JustDied);
|
||||
me->Respawn();
|
||||
}
|
||||
else
|
||||
@@ -299,7 +299,7 @@ void npc_escortAI::UpdateAI(uint32 diff)
|
||||
{
|
||||
if (m_bCanInstantRespawn)
|
||||
{
|
||||
me->setDeathState(JUST_DIED);
|
||||
me->setDeathState(DeathState::JustDied);
|
||||
me->Respawn();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
*/
|
||||
|
||||
#include "SmartAI.h"
|
||||
#include "AreaTriggerScript.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridDefines.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "Group.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
@@ -3243,7 +3243,7 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
|
||||
case SMART_TARGET_FARTHEST:
|
||||
if (me)
|
||||
{
|
||||
if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::MinDistance, 0, FarthestTargetSelector(me, e.target.farthest.maxDist, e.target.farthest.playerOnly, e.target.farthest.isInLos)))
|
||||
if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::MinDistance, 0, FarthestTargetSelector(me, e.target.farthest.maxDist, e.target.farthest.playerOnly, e.target.farthest.isInLos, e.target.farthest.minDist)))
|
||||
targets.push_back(u);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1488,7 +1488,7 @@ enum SMARTAI_TARGETS
|
||||
SMART_TARGET_CLOSEST_ENEMY = 25, // maxDist, playerOnly
|
||||
SMART_TARGET_CLOSEST_FRIENDLY = 26, // maxDist, playerOnly
|
||||
SMART_TARGET_LOOT_RECIPIENTS = 27, // all players that have tagged this creature (for kill credit)
|
||||
SMART_TARGET_FARTHEST = 28, // maxDist, playerOnly, isInLos
|
||||
SMART_TARGET_FARTHEST = 28, // maxDist, playerOnly, isInLos, minDist
|
||||
SMART_TARGET_VEHICLE_PASSENGER = 29, // seat number (vehicle can target it's own accessory)
|
||||
|
||||
SMART_TARGET_TC_END = 30, // placeholder
|
||||
@@ -1538,6 +1538,7 @@ struct SmartTarget
|
||||
uint32 maxDist;
|
||||
SAIBool playerOnly;
|
||||
SAIBool isInLos;
|
||||
uint32 minDist;
|
||||
} farthest;
|
||||
|
||||
struct
|
||||
|
||||
@@ -278,11 +278,6 @@ namespace AccountMgr
|
||||
return gmlevel == SEC_PLAYER;
|
||||
}
|
||||
|
||||
bool IsGMAccount(uint32 gmlevel)
|
||||
{
|
||||
return gmlevel >= SEC_MODERATOR && gmlevel <= SEC_CONSOLE;
|
||||
}
|
||||
|
||||
bool IsAdminAccount(uint32 gmlevel)
|
||||
{
|
||||
return gmlevel >= SEC_ADMINISTRATOR && gmlevel <= SEC_CONSOLE;
|
||||
|
||||
@@ -49,7 +49,6 @@ namespace AccountMgr
|
||||
uint32 GetCharactersCount(uint32 accountId);
|
||||
|
||||
bool IsPlayerAccount(uint32 gmlevel);
|
||||
bool IsGMAccount(uint32 gmlevel);
|
||||
bool IsAdminAccount(uint32 gmlevel);
|
||||
bool IsConsoleAccount(uint32 gmlevel);
|
||||
};
|
||||
|
||||
@@ -140,8 +140,8 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA:
|
||||
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA:
|
||||
{
|
||||
SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(aura.spell_id);
|
||||
if (!spellEntry)
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(aura.spell_id);
|
||||
if (!spellInfo)
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: {} Type: {}) for data type {} ({}) has wrong spell id in value1 ({}), ignored.",
|
||||
criteria->ID, criteria->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA ? "ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA" : "ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id);
|
||||
@@ -153,7 +153,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
|
||||
criteria->ID, criteria->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA ? "ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA" : "ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.effect_idx);
|
||||
return false;
|
||||
}
|
||||
if (!spellEntry->Effects[aura.effect_idx].ApplyAuraName)
|
||||
if (!spellInfo->Effects[aura.effect_idx].ApplyAuraName)
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: {} Type: {}) for data type {} ({}) has non-aura spell effect (ID: {} Effect: {}), ignores.",
|
||||
criteria->ID, criteria->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA ? "ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA" : "ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id, aura.effect_idx);
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
*/
|
||||
|
||||
#include "AddonMgr.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "CryptoHash.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
#include "Timer.h"
|
||||
#include <list>
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
*/
|
||||
|
||||
#include "AutobroadcastMgr.h"
|
||||
#include "Config.h"
|
||||
#include "Chat.h"
|
||||
#include "Player.h"
|
||||
#include "Config.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "Player.h"
|
||||
|
||||
AutobroadcastMgr* AutobroadcastMgr::instance()
|
||||
{
|
||||
|
||||
@@ -815,7 +815,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl
|
||||
|
||||
// Set creature in world
|
||||
map->AddToMap(creature);
|
||||
creature->SetFarVisible(true);
|
||||
creature->setActive(true);
|
||||
|
||||
return creature;
|
||||
}
|
||||
@@ -840,7 +840,7 @@ GameObject* Battlefield::SpawnGameObject(uint32 entry, float x, float y, float z
|
||||
|
||||
// Add to world
|
||||
map->AddToMap(go);
|
||||
go->SetFarVisible(true);
|
||||
go->setActive(true);
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
@@ -1159,7 +1159,6 @@ struct BfWGGameObjectBuilding
|
||||
// Rebuild gameobject
|
||||
go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, nullptr, true);
|
||||
go->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[m_Team]);
|
||||
go->setActive(false); // Everything is reset, no need keep active at this point.
|
||||
}
|
||||
|
||||
// Update worldstate
|
||||
@@ -1171,10 +1170,6 @@ struct BfWGGameObjectBuilding
|
||||
// Called when associated gameobject is damaged
|
||||
void Damaged()
|
||||
{
|
||||
GameObject* go = m_WG->GetGameObject(m_Build);
|
||||
if (go)
|
||||
go->setActive(true);
|
||||
|
||||
// Update worldstate
|
||||
m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DAMAGE - (m_Team * 3);
|
||||
m_WG->SendUpdateWorldState(m_WorldState, m_State);
|
||||
@@ -1198,10 +1193,6 @@ struct BfWGGameObjectBuilding
|
||||
// Called when associated gameobject is destroyed
|
||||
void Destroyed()
|
||||
{
|
||||
GameObject* go = m_WG->GetGameObject(m_Build);
|
||||
if (go)
|
||||
go->setActive(true);
|
||||
|
||||
// Update worldstate
|
||||
m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY - (m_Team * 3);
|
||||
m_WG->SendUpdateWorldState(m_WorldState, m_State);
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
#include "GroupMgr.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "World.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Pet.h"
|
||||
#include "ScriptMgr.h"
|
||||
//#include "WorldStatePackets.h"
|
||||
|
||||
void ArenaScore::AppendToPacket(WorldPacket& data)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "Creature.h"
|
||||
#include "CreatureTextMgr.h"
|
||||
#include "Formulas.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "GameGraveyard.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "GroupMgr.h"
|
||||
@@ -861,7 +862,7 @@ void Battleground::EndBattleground(PvPTeamId winnerTeamId)
|
||||
UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(winner_kills));
|
||||
|
||||
// Xinef: check player level and not bracket level if (CanAwardArenaPoints())
|
||||
if (player->GetLevel() >= BG_AWARD_ARENA_POINTS_MIN_LEVEL)
|
||||
if (player->GetLevel() >= sWorld->getIntConfig(CONFIG_DAILY_RBG_MIN_LEVEL_AP_REWARD))
|
||||
player->ModifyArenaPoints(winner_arena);
|
||||
|
||||
if (!player->GetRandomWinner())
|
||||
@@ -1635,7 +1636,7 @@ bool Battleground::AddSpiritGuide(uint32 type, float x, float y, float z, float
|
||||
|
||||
if (Creature* creature = AddCreature(entry, type, x, y, z, o))
|
||||
{
|
||||
creature->setDeathState(DEAD);
|
||||
creature->setDeathState(DeathState::Dead);
|
||||
creature->SetGuidValue(UNIT_FIELD_CHANNEL_OBJECT, creature->GetGUID());
|
||||
// aura
|
||||
/// @todo: Fix display here
|
||||
|
||||
@@ -45,7 +45,7 @@ class BattlegroundIC;
|
||||
struct PvPDifficultyEntry;
|
||||
struct GraveyardStruct;
|
||||
|
||||
enum BattlegroundDesertionType
|
||||
enum BattlegroundDesertionType : uint8
|
||||
{
|
||||
BG_DESERTION_TYPE_LEAVE_BG = 0, // player leaves the BG
|
||||
BG_DESERTION_TYPE_OFFLINE = 1, // player is kicked from BG because offline
|
||||
@@ -277,7 +277,6 @@ enum BGHonorMode
|
||||
BG_HONOR_MODE_NUM
|
||||
};
|
||||
|
||||
#define BG_AWARD_ARENA_POINTS_MIN_LEVEL 71
|
||||
#define ARENA_TIMELIMIT_POINTS_LOSS -16
|
||||
#define ARENA_READY_MARKER_ENTRY 301337
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#include "Common.h"
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "DBCEnums.h"
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
typedef std::map<uint32, Battleground*> BattlegroundContainer;
|
||||
typedef std::set<uint32> BattlegroundClientIdsContainer;
|
||||
|
||||
@@ -551,6 +551,6 @@ void BattlegroundAB::ApplyPhaseMask()
|
||||
for (auto const& itr : bgPlayerMap)
|
||||
{
|
||||
itr.second->SetPhaseMask(phaseMask, false);
|
||||
itr.second->UpdateObjectVisibility(true);
|
||||
itr.second->UpdateObjectVisibility(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ Creature* BattlegroundAV::AddAVCreature(uint16 cinfoid, uint16 type)
|
||||
//else wander_distance will be 15, so creatures move maximum=10
|
||||
//creature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
|
||||
creature->GetMotionMaster()->Initialize();
|
||||
creature->setDeathState(JUST_DIED);
|
||||
creature->setDeathState(DeathState::JustDied);
|
||||
creature->Respawn();
|
||||
//TODO: find a way to add a motionmaster without killing the creature (i
|
||||
//just copied this code from a gm-command
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundScore.h"
|
||||
#include "Language.h"
|
||||
#include "EventMap.h"
|
||||
#include "Language.h"
|
||||
|
||||
enum BG_EY_Events
|
||||
{
|
||||
|
||||
@@ -198,8 +198,7 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
|
||||
|
||||
player->JoinedChannel(this);
|
||||
|
||||
if (_announce && (!AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()) ||
|
||||
!sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL)))
|
||||
if (_announce && ShouldAnnouncePlayer(player))
|
||||
{
|
||||
WorldPacket data;
|
||||
MakeJoined(&data, guid);
|
||||
@@ -222,7 +221,7 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
|
||||
|
||||
JoinNotify(player);
|
||||
|
||||
playersStore[guid].SetOwnerGM(AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()));
|
||||
playersStore[guid].SetOwnerGM(player->GetSession()->IsGMAccount());
|
||||
|
||||
// Custom channel handling
|
||||
if (!IsConstant())
|
||||
@@ -276,8 +275,7 @@ void Channel::LeaveChannel(Player* player, bool send)
|
||||
bool changeowner = playersStore[guid].IsOwner();
|
||||
|
||||
playersStore.erase(guid);
|
||||
if (_announce && (!AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()) ||
|
||||
!sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL)))
|
||||
if (_announce && ShouldAnnouncePlayer(player))
|
||||
{
|
||||
WorldPacket data;
|
||||
MakeLeft(&data, guid);
|
||||
@@ -301,7 +299,7 @@ void Channel::LeaveChannel(Player* player, bool send)
|
||||
for (Channel::PlayerContainer::const_iterator itr = playersStore.begin(); itr != playersStore.end(); ++itr)
|
||||
{
|
||||
newowner = itr->second.player;
|
||||
if (AccountMgr::IsGMAccount(itr->second.plrPtr->GetSession()->GetSecurity()))
|
||||
if (itr->second.plrPtr->GetSession()->IsGMAccount())
|
||||
_isOwnerGM = true;
|
||||
else
|
||||
_isOwnerGM = false;
|
||||
@@ -319,7 +317,6 @@ void Channel::LeaveChannel(Player* player, bool send)
|
||||
|
||||
void Channel::KickOrBan(Player const* player, std::string const& badname, bool ban)
|
||||
{
|
||||
AccountTypes sec = player->GetSession()->GetSecurity();
|
||||
ObjectGuid good = player->GetGUID();
|
||||
|
||||
if (!IsOn(good))
|
||||
@@ -330,7 +327,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playersStore[good].IsModerator() && !AccountMgr::IsGMAccount(sec))
|
||||
if (!playersStore[good].IsModerator() && !player->GetSession()->IsGMAccount())
|
||||
{
|
||||
WorldPacket data;
|
||||
MakeNotModerator(&data);
|
||||
@@ -343,19 +340,17 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
|
||||
|
||||
ObjectGuid victim;
|
||||
uint32 badAccId = 0;
|
||||
uint32 badSecurity = 0;
|
||||
Player* bad = ObjectAccessor::FindPlayerByName(badname, false);
|
||||
if (bad)
|
||||
{
|
||||
victim = bad->GetGUID();
|
||||
badAccId = bad->GetSession()->GetAccountId();
|
||||
badSecurity = bad->GetSession()->GetSecurity();
|
||||
}
|
||||
|
||||
bool isOnChannel = victim && IsOn(victim);
|
||||
if (!isOnChannel)
|
||||
{
|
||||
if (ban && (AccountMgr::IsGMAccount(sec) || isGoodConstantModerator))
|
||||
if (ban && (player->GetSession()->IsGMAccount() || isGoodConstantModerator))
|
||||
{
|
||||
if (ObjectGuid guid = sCharacterCache->GetCharacterGuidByName(badname))
|
||||
{
|
||||
@@ -395,7 +390,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
|
||||
bool changeowner = _ownerGUID == victim;
|
||||
bool isBadConstantModerator = _channelRights.moderators.find(badAccId) != _channelRights.moderators.end();
|
||||
|
||||
if (!AccountMgr::IsGMAccount(sec) && !isGoodConstantModerator)
|
||||
if (!player->GetSession()->IsGMAccount() && !isGoodConstantModerator)
|
||||
{
|
||||
if (changeowner && good != _ownerGUID)
|
||||
{
|
||||
@@ -413,7 +408,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBadConstantModerator || AccountMgr::IsGMAccount(badSecurity))
|
||||
if (isBadConstantModerator || bad->GetSession()->IsGMAccount())
|
||||
{
|
||||
WorldPacket data;
|
||||
MakeNotModerator(&data);
|
||||
@@ -422,8 +417,6 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
|
||||
}
|
||||
}
|
||||
|
||||
bool notify = !(AccountMgr::IsGMAccount(sec) && sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL));
|
||||
|
||||
if (ban)
|
||||
{
|
||||
if (!IsBanned(victim))
|
||||
@@ -431,7 +424,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
|
||||
bannedStore[victim] = GameTime::GetGameTime().count() + CHANNEL_BAN_DURATION;
|
||||
AddChannelBanToDB(victim, GameTime::GetGameTime().count() + CHANNEL_BAN_DURATION);
|
||||
|
||||
if (notify)
|
||||
if (ShouldAnnouncePlayer(player))
|
||||
{
|
||||
WorldPacket data;
|
||||
MakePlayerBanned(&data, victim, good);
|
||||
@@ -439,7 +432,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (notify)
|
||||
else if (ShouldAnnouncePlayer(player))
|
||||
{
|
||||
WorldPacket data;
|
||||
MakePlayerKicked(&data, victim, good);
|
||||
@@ -476,7 +469,6 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
|
||||
|
||||
void Channel::UnBan(Player const* player, std::string const& badname)
|
||||
{
|
||||
uint32 sec = player->GetSession()->GetSecurity();
|
||||
ObjectGuid good = player->GetGUID();
|
||||
|
||||
if (!IsOn(good))
|
||||
@@ -487,7 +479,7 @@ void Channel::UnBan(Player const* player, std::string const& badname)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playersStore[good].IsModerator() && !AccountMgr::IsGMAccount(sec))
|
||||
if (!playersStore[good].IsModerator() && !player->GetSession()->IsGMAccount())
|
||||
{
|
||||
WorldPacket data;
|
||||
MakeNotModerator(&data);
|
||||
@@ -510,7 +502,7 @@ void Channel::UnBan(Player const* player, std::string const& badname)
|
||||
}
|
||||
|
||||
bool isConstantModerator = _channelRights.moderators.find(player->GetSession()->GetAccountId()) != _channelRights.moderators.end();
|
||||
if (!AccountMgr::IsGMAccount(sec) && !isConstantModerator)
|
||||
if (!player->GetSession()->IsGMAccount() && !isConstantModerator)
|
||||
{
|
||||
if (_channelRights.flags & CHANNEL_RIGHT_CANT_BAN)
|
||||
{
|
||||
@@ -555,7 +547,7 @@ void Channel::Password(Player const* player, std::string const& pass)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(player->GetSession()->GetSecurity()))
|
||||
if (!playersStore[guid].IsModerator() && !player->GetSession()->IsGMAccount())
|
||||
{
|
||||
WorldPacket data;
|
||||
MakeNotModerator(&data);
|
||||
@@ -583,7 +575,6 @@ void Channel::Password(Player const* player, std::string const& pass)
|
||||
void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bool set)
|
||||
{
|
||||
ObjectGuid guid = player->GetGUID();
|
||||
uint32 sec = player->GetSession()->GetSecurity();
|
||||
|
||||
if (!IsOn(guid))
|
||||
{
|
||||
@@ -593,7 +584,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(sec))
|
||||
if (!playersStore[guid].IsModerator() && !player->GetSession()->IsGMAccount())
|
||||
{
|
||||
WorldPacket data;
|
||||
MakeNotModerator(&data);
|
||||
@@ -610,7 +601,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
|
||||
if (!victim || !IsOn(victim) ||
|
||||
// allow make moderator from another team only if both is GMs
|
||||
// at this moment this only way to show channel post for GM from another team
|
||||
((!AccountMgr::IsGMAccount(sec) || !AccountMgr::IsGMAccount(newp->GetSession()->GetSecurity())) && player->GetTeamId() != newp->GetTeamId() &&
|
||||
((!player->GetSession()->IsGMAccount() || !newp->GetSession()->IsGMAccount()) && player->GetTeamId() != newp->GetTeamId() &&
|
||||
!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)))
|
||||
{
|
||||
WorldPacket data;
|
||||
@@ -636,7 +627,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
|
||||
else
|
||||
{
|
||||
bool isGoodConstantModerator = _channelRights.moderators.find(player->GetSession()->GetAccountId()) != _channelRights.moderators.end();
|
||||
if (!AccountMgr::IsGMAccount(sec) && !isGoodConstantModerator)
|
||||
if (!player->GetSession()->IsGMAccount() && !isGoodConstantModerator)
|
||||
{
|
||||
if (_channelRights.flags & CHANNEL_RIGHT_CANT_MUTE)
|
||||
{
|
||||
@@ -654,7 +645,6 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
|
||||
void Channel::SetOwner(Player const* player, std::string const& newname)
|
||||
{
|
||||
ObjectGuid guid = player->GetGUID();
|
||||
uint32 sec = player->GetSession()->GetSecurity();
|
||||
|
||||
if (!IsOn(guid))
|
||||
{
|
||||
@@ -665,7 +655,7 @@ void Channel::SetOwner(Player const* player, std::string const& newname)
|
||||
}
|
||||
|
||||
bool isGoodConstantModerator = _channelRights.moderators.find(player->GetSession()->GetAccountId()) != _channelRights.moderators.end();
|
||||
if (!AccountMgr::IsGMAccount(sec) && guid != _ownerGUID && !isGoodConstantModerator)
|
||||
if (!player->GetSession()->IsGMAccount() && guid != _ownerGUID && !isGoodConstantModerator)
|
||||
{
|
||||
WorldPacket data;
|
||||
MakeNotOwner(&data);
|
||||
@@ -737,7 +727,6 @@ void Channel::List(Player const* player)
|
||||
void Channel::Announce(Player const* player)
|
||||
{
|
||||
ObjectGuid guid = player->GetGUID();
|
||||
uint32 sec = player->GetSession()->GetSecurity();
|
||||
|
||||
if (!IsOn(guid))
|
||||
{
|
||||
@@ -747,7 +736,7 @@ void Channel::Announce(Player const* player)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playersStore[guid].IsModerator() && !AccountMgr::IsGMAccount(sec))
|
||||
if (!playersStore[guid].IsModerator() && !player->GetSession()->IsGMAccount())
|
||||
{
|
||||
WorldPacket data;
|
||||
MakeNotModerator(&data);
|
||||
@@ -895,30 +884,25 @@ void Channel::SetOwner(ObjectGuid guid, bool exclaim)
|
||||
pinfo.SetModerator(true);
|
||||
uint8 oldFlag = pinfo.flags;
|
||||
pinfo.SetOwner(true);
|
||||
|
||||
bool notify = true;
|
||||
Player* player = ObjectAccessor::FindPlayer(_ownerGUID);
|
||||
|
||||
if (player)
|
||||
{
|
||||
uint32 sec = player->GetSession()->GetSecurity();
|
||||
notify = !(AccountMgr::IsGMAccount(sec) && sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL));
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
|
||||
if (notify)
|
||||
{
|
||||
MakeModeChange(&data, _ownerGUID, oldFlag);
|
||||
SendToAll(&data);
|
||||
}
|
||||
|
||||
FlagsNotify(pinfo.plrPtr);
|
||||
|
||||
if (exclaim && notify)
|
||||
Player* player = ObjectAccessor::FindPlayer(_ownerGUID);
|
||||
if (player)
|
||||
{
|
||||
MakeOwnerChanged(&data, _ownerGUID);
|
||||
SendToAll(&data);
|
||||
if (ShouldAnnouncePlayer(player))
|
||||
{
|
||||
WorldPacket data;
|
||||
|
||||
MakeModeChange(&data, _ownerGUID, oldFlag);
|
||||
SendToAll(&data);
|
||||
|
||||
if (exclaim)
|
||||
{
|
||||
// MakeOwnerChanged will reset the packet for us
|
||||
MakeOwnerChanged(&data, _ownerGUID);
|
||||
SendToAll(&data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -949,6 +933,11 @@ void Channel::SendToAllWatching(WorldPacket* data)
|
||||
(*i)->GetSession()->SendPacket(data);
|
||||
}
|
||||
|
||||
bool Channel::ShouldAnnouncePlayer(Player const* player) const
|
||||
{
|
||||
return !(player->GetSession()->IsGMAccount() && sWorld->getBoolConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL));
|
||||
}
|
||||
|
||||
void Channel::Voice(ObjectGuid /*guid1*/, ObjectGuid /*guid2*/)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -271,6 +271,8 @@ private:
|
||||
void SendToOne(WorldPacket* data, ObjectGuid who);
|
||||
void SendToAllWatching(WorldPacket* data);
|
||||
|
||||
bool ShouldAnnouncePlayer(Player const* player) const;
|
||||
|
||||
[[nodiscard]] bool IsOn(ObjectGuid who) const { return playersStore.find(who) != playersStore.end(); }
|
||||
[[nodiscard]] bool IsBanned(ObjectGuid guid) const;
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
#include "ChannelMgr.h"
|
||||
#include "Log.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include "World.h"
|
||||
|
||||
ChannelMgr::~ChannelMgr()
|
||||
{
|
||||
|
||||
@@ -62,8 +62,7 @@ bool ChatHandler::HasLowerSecurity(Player* target, ObjectGuid guid, bool strong)
|
||||
|
||||
if (!target_session && !target_account)
|
||||
{
|
||||
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||
SetSentErrorMessage(true);
|
||||
SendErrorMessage(LANG_PLAYER_NOT_FOUND);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -92,8 +91,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac
|
||||
AccountTypes target_ac_sec = AccountTypes(target_sec);
|
||||
if (m_session->GetSecurity() < target_ac_sec || (strong && m_session->GetSecurity() <= target_ac_sec))
|
||||
{
|
||||
SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
|
||||
SetSentErrorMessage(true);
|
||||
SendErrorMessage(LANG_YOURS_SECURITY_IS_LOW);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -151,6 +149,18 @@ void ChatHandler::SendSysMessage(uint32 entry)
|
||||
SendSysMessage(GetAcoreString(entry));
|
||||
}
|
||||
|
||||
void ChatHandler::SendErrorMessage(uint32 entry)
|
||||
{
|
||||
SendSysMessage(entry);
|
||||
SetSentErrorMessage(true);
|
||||
}
|
||||
|
||||
void ChatHandler::SendErrorMessage(std::string_view str, bool escapeCharacters)
|
||||
{
|
||||
SendSysMessage(str, escapeCharacters);
|
||||
SetSentErrorMessage(true);
|
||||
}
|
||||
|
||||
bool ChatHandler::_ParseCommands(std::string_view text)
|
||||
{
|
||||
if (Acore::ChatCommands::TryExecuteCommand(*this, text))
|
||||
@@ -161,8 +171,7 @@ bool ChatHandler::_ParseCommands(std::string_view text)
|
||||
return false;
|
||||
|
||||
// Send error message for GMs
|
||||
PSendSysMessage(LANG_CMD_INVALID, STRING_VIEW_FMT_ARG(text));
|
||||
SetSentErrorMessage(true);
|
||||
SendErrorMessage(LANG_CMD_INVALID, STRING_VIEW_FMT_ARG(text));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -682,8 +691,7 @@ bool ChatHandler::extractPlayerTarget(char* args, Player** player, ObjectGuid* p
|
||||
std::string name = extractPlayerNameFromLink(args);
|
||||
if (name.empty())
|
||||
{
|
||||
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||
SetSentErrorMessage(true);
|
||||
SendErrorMessage(LANG_PLAYER_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -725,8 +733,7 @@ bool ChatHandler::extractPlayerTarget(char* args, Player** player, ObjectGuid* p
|
||||
// some from req. data must be provided (note: name is empty if player not exist)
|
||||
if ((!player || !*player) && (!player_guid || !*player_guid) && (!player_name || player_name->empty()))
|
||||
{
|
||||
SendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||
SetSentErrorMessage(true);
|
||||
SendErrorMessage(LANG_PLAYER_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -839,8 +846,7 @@ bool ChatHandler::GetPlayerGroupAndGUIDByName(const char* cname, Player*& player
|
||||
{
|
||||
if (!normalizePlayerName(name))
|
||||
{
|
||||
PSendSysMessage(LANG_PLAYER_NOT_FOUND);
|
||||
SetSentErrorMessage(true);
|
||||
SendErrorMessage(LANG_PLAYER_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,23 @@ public:
|
||||
return Acore::StringFormat(GetAcoreString(entry), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void SendErrorMessage(uint32 entry);
|
||||
void SendErrorMessage(std::string_view str, bool escapeCharacters);
|
||||
|
||||
template<typename... Args>
|
||||
void SendErrorMessage(char const* fmt, Args&&... args)
|
||||
{
|
||||
PSendSysMessage(fmt, std::forward<Args>(args)...);
|
||||
SetSentErrorMessage(true);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void SendErrorMessage(uint32 entry, Args&&... args)
|
||||
{
|
||||
PSendSysMessage(entry, std::forward<Args>(args)...);
|
||||
SetSentErrorMessage(true);
|
||||
}
|
||||
|
||||
bool _ParseCommands(std::string_view text);
|
||||
virtual bool ParseCommands(std::string_view text);
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "Optional.h"
|
||||
#include "StringFormat.h"
|
||||
#include "Util.h"
|
||||
#include "advstd.h"
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
@@ -115,7 +114,7 @@ namespace Acore::Impl::ChatCommands
|
||||
}
|
||||
|
||||
template <typename T> struct HandlerToTuple { static_assert(Acore::dependant_false_v<T>, "Invalid command handler signature"); };
|
||||
template <typename... Ts> struct HandlerToTuple<bool(ChatHandler*, Ts...)> { using type = std::tuple<ChatHandler*, advstd::remove_cvref_t<Ts>...>; };
|
||||
template <typename... Ts> struct HandlerToTuple<bool(ChatHandler*, Ts...)> { using type = std::tuple<ChatHandler*, std::remove_cvref_t<Ts>...>; };
|
||||
template <typename T> using TupleType = typename HandlerToTuple<T>::type;
|
||||
|
||||
struct CommandInvoker
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "ObjectGuid.h"
|
||||
#include "Optional.h"
|
||||
#include "Util.h"
|
||||
#include "advstd.h"
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <cmath>
|
||||
@@ -204,7 +203,7 @@ namespace Acore::ChatCommands
|
||||
struct Hyperlink : Acore::Impl::ChatCommands::ContainerTag
|
||||
{
|
||||
using value_type = typename linktag::value_type;
|
||||
using storage_type = advstd::remove_cvref_t<value_type>;
|
||||
using storage_type = std::remove_cvref_t<value_type>;
|
||||
|
||||
operator value_type() const { return val; }
|
||||
value_type operator*() const { return val; }
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#include "GameEventMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "World.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include "World.h"
|
||||
|
||||
namespace DisableMgr
|
||||
{
|
||||
|
||||
@@ -448,8 +448,8 @@ void LoadDBCStores(const std::string& dataPath)
|
||||
|
||||
for (SkillLineAbilityEntry const* skillLine : sSkillLineAbilityStore)
|
||||
{
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->Spell);
|
||||
if (spellInfo && spellInfo->Attributes & SPELL_ATTR0_PASSIVE)
|
||||
SpellEntry const* spellEntry = sSpellStore.LookupEntry(skillLine->Spell);
|
||||
if (spellEntry && spellEntry->Attributes & SPELL_ATTR0_PASSIVE)
|
||||
{
|
||||
for (CreatureFamilyEntry const* cFamily : sCreatureFamilyStore)
|
||||
{
|
||||
@@ -458,7 +458,7 @@ void LoadDBCStores(const std::string& dataPath)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (spellInfo->SpellLevel)
|
||||
if (spellEntry->SpellLevel)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -468,7 +468,7 @@ void LoadDBCStores(const std::string& dataPath)
|
||||
continue;
|
||||
}
|
||||
|
||||
sPetFamilySpellsStore[cFamily->ID].insert(spellInfo->Id);
|
||||
sPetFamilySpellsStore[cFamily->ID].insert(spellEntry->Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid
|
||||
|
||||
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
|
||||
|
||||
enum ContentLevels
|
||||
enum ContentLevels : uint8
|
||||
{
|
||||
CONTENT_1_60 = 0,
|
||||
CONTENT_61_70,
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "DBCStores.h"
|
||||
#include "M2Stores.h"
|
||||
#include "Containers.h"
|
||||
#include "DBCStores.h"
|
||||
#include "Log.h"
|
||||
#include "M2Structure.h"
|
||||
#include "M2Stores.h"
|
||||
#include "World.h"
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <fstream>
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#ifndef ACORE_M2STRUCTURE_H
|
||||
#define ACORE_M2STRUCTURE_H
|
||||
|
||||
#include <G3D/Vector3.h>
|
||||
#include <G3D/AABox.h>
|
||||
#include <G3D/Vector3.h>
|
||||
|
||||
// Structures for M2 file. Source: https://wowdev.wiki
|
||||
#pragma pack(push, 1)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
@@ -43,9 +44,6 @@ namespace lfg
|
||||
{
|
||||
LFGMgr::LFGMgr(): m_lfgProposalId(1), m_options(sWorld->getIntConfig(CONFIG_LFG_OPTIONSMASK)), m_Testing(false)
|
||||
{
|
||||
new LFGPlayerScript();
|
||||
new LFGGroupScript();
|
||||
|
||||
for (uint8 team = 0; team < 2; ++team)
|
||||
{
|
||||
m_raidBrowserUpdateTimer[team] = 10000;
|
||||
@@ -2128,14 +2126,6 @@ namespace lfg
|
||||
return;
|
||||
}
|
||||
|
||||
if (out)
|
||||
{
|
||||
if (player->GetMapId() == uint32(dungeon->map))
|
||||
player->TeleportToEntryPoint();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LfgTeleportError error = LFG_TELEPORTERROR_OK;
|
||||
|
||||
if (!player->IsAlive())
|
||||
@@ -2158,6 +2148,13 @@ namespace lfg
|
||||
{
|
||||
error = LFG_TELEPORTERROR_COMBAT;
|
||||
}
|
||||
else if (out && error == LFG_TELEPORTERROR_OK)
|
||||
{
|
||||
if (player->GetMapId() == uint32(dungeon->map))
|
||||
player->TeleportToEntryPoint();
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 mapid = dungeon->map;
|
||||
@@ -2183,11 +2180,18 @@ namespace lfg
|
||||
}
|
||||
|
||||
if (error != LFG_TELEPORTERROR_OK)
|
||||
{
|
||||
player->GetSession()->SendLfgTeleportError(uint8(error));
|
||||
|
||||
//LOG_DEBUG("lfg", "TeleportPlayer: Player {} is being teleported in to map {} "
|
||||
// "(x: {}, y: {}, z: {}) Result: {}", player->GetName(), dungeon->map,
|
||||
// dungeon->x, dungeon->y, dungeon->z, error);
|
||||
LOG_DEBUG("lfg", "Player [{}] could NOT be teleported in to map [{}] (x: {}, y: {}, z: {}) Error: {}",
|
||||
player->GetName(), dungeon->map, dungeon->x, dungeon->y, dungeon->z, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("lfg", "Player [{}] is being teleported in to map [{}] (x: {}, y: {}, z: {})",
|
||||
player->GetName(), dungeon->map, dungeon->x, dungeon->y, dungeon->z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -633,6 +633,9 @@ namespace lfg
|
||||
bool m_Testing;
|
||||
};
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_enum_v<T>)>
|
||||
auto format_as(T f) { return fmt::underlying(f); }
|
||||
|
||||
} // namespace lfg
|
||||
|
||||
#define sLFGMgr lfg::LFGMgr::instance()
|
||||
|
||||
@@ -297,4 +297,9 @@ namespace lfg
|
||||
}
|
||||
}
|
||||
|
||||
void AddSC_LFGScripts()
|
||||
{
|
||||
new LFGPlayerScript();
|
||||
new LFGGroupScript();
|
||||
}
|
||||
} // namespace lfg
|
||||
|
||||
@@ -19,16 +19,15 @@
|
||||
* Interaction between core and LFGScripts
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "GroupScript.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "PlayerScript.h"
|
||||
|
||||
class Player;
|
||||
class Group;
|
||||
|
||||
namespace lfg
|
||||
{
|
||||
|
||||
class LFGPlayerScript : public PlayerScript
|
||||
{
|
||||
public:
|
||||
@@ -55,4 +54,6 @@ namespace lfg
|
||||
void OnInviteMember(Group* group, ObjectGuid guid) override;
|
||||
};
|
||||
|
||||
void AddSC_LFGScripts();
|
||||
|
||||
} // namespace lfg
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
#include "GroupMgr.h"
|
||||
#include "Log.h"
|
||||
#include "LootMgr.h"
|
||||
#include "MapMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "PoolMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellMgr.h"
|
||||
@@ -301,6 +301,9 @@ void Creature::RemoveFromWorld()
|
||||
if (m_formation)
|
||||
sFormationMgr->RemoveCreatureFromGroup(m_formation, this);
|
||||
|
||||
if (Transport* transport = GetTransport())
|
||||
transport->RemovePassenger(this, true);
|
||||
|
||||
Unit::RemoveFromWorld();
|
||||
|
||||
if (m_spawnId)
|
||||
@@ -316,7 +319,7 @@ void Creature::DisappearAndDie()
|
||||
//SetVisibility(VISIBILITY_OFF);
|
||||
//ObjectAccessor::UpdateObjectVisibility(this);
|
||||
if (IsAlive())
|
||||
setDeathState(JUST_DIED, true);
|
||||
setDeathState(DeathState::JustDied, true);
|
||||
RemoveCorpse(false, true);
|
||||
}
|
||||
|
||||
@@ -342,11 +345,11 @@ void Creature::SearchFormation()
|
||||
|
||||
void Creature::RemoveCorpse(bool setSpawnTime, bool skipVisibility)
|
||||
{
|
||||
if (getDeathState() != CORPSE)
|
||||
if (getDeathState() != DeathState::Corpse)
|
||||
return;
|
||||
|
||||
m_corpseRemoveTime = GameTime::GetGameTime().count();
|
||||
setDeathState(DEAD);
|
||||
setDeathState(DeathState::Dead);
|
||||
RemoveAllAuras();
|
||||
if (!skipVisibility) // pussywizard
|
||||
DestroyForNearbyPlayers(); // pussywizard: previous UpdateObjectVisibility()
|
||||
@@ -362,15 +365,17 @@ void Creature::RemoveCorpse(bool setSpawnTime, bool skipVisibility)
|
||||
//SaveRespawnTime();
|
||||
}
|
||||
|
||||
float x, y, z, o;
|
||||
GetRespawnPosition(x, y, z, &o);
|
||||
SetHomePosition(x, y, z, o);
|
||||
SetPosition(x, y, z, o);
|
||||
|
||||
// xinef: relocate notifier
|
||||
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
|
||||
|
||||
// pussywizard: if corpse was removed during falling then the falling will continue after respawn, so stop falling is such case
|
||||
if (IsFalling())
|
||||
StopMoving();
|
||||
|
||||
float x, y, z, o;
|
||||
GetRespawnPosition(x, y, z, &o);
|
||||
UpdateAllowedPositionZ(x, y, z);
|
||||
SetHomePosition(x, y, z, o);
|
||||
GetMap()->CreatureRelocation(this, x, y, z, o);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -604,61 +609,28 @@ void Creature::Update(uint32 diff)
|
||||
|
||||
switch (m_deathState)
|
||||
{
|
||||
case JUST_RESPAWNED:
|
||||
case DeathState::JustRespawned:
|
||||
// Must not be called, see Creature::setDeathState JUST_RESPAWNED -> ALIVE promoting.
|
||||
LOG_ERROR("entities.unit", "Creature ({}) in wrong state: JUST_RESPAWNED (4)", GetGUID().ToString());
|
||||
LOG_ERROR("entities.unit", "Creature ({}) in wrong state: DeathState::JustRespawned (4)", GetGUID().ToString());
|
||||
break;
|
||||
case JUST_DIED:
|
||||
case DeathState::JustDied:
|
||||
// Must not be called, see Creature::setDeathState JUST_DIED -> CORPSE promoting.
|
||||
LOG_ERROR("entities.unit", "Creature ({}) in wrong state: JUST_DEAD (1)", GetGUID().ToString());
|
||||
LOG_ERROR("entities.unit", "Creature ({}) in wrong state: DeathState::JustDead (1)", GetGUID().ToString());
|
||||
break;
|
||||
case DEAD:
|
||||
case DeathState::Dead:
|
||||
{
|
||||
time_t now = GameTime::GetGameTime().count();
|
||||
if (m_respawnTime <= now)
|
||||
{
|
||||
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_RESPAWN, GetEntry());
|
||||
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(this, conditions))
|
||||
{
|
||||
// Creature should not respawn, reset respawn timer. Conditions will be checked again the next time it tries to respawn.
|
||||
m_respawnTime = GameTime::GetGameTime().count() + m_respawnDelay;
|
||||
break;
|
||||
}
|
||||
|
||||
bool allowed = !IsAIEnabled || AI()->CanRespawn(); // First check if there are any scripts that prevent us respawning
|
||||
if (!allowed) // Will be rechecked on next Update call
|
||||
break;
|
||||
|
||||
ObjectGuid dbtableHighGuid = ObjectGuid::Create<HighGuid::Unit>(m_creatureData ? m_creatureData->id1 : GetEntry(), m_spawnId);
|
||||
time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
|
||||
|
||||
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(GetEntry());
|
||||
|
||||
if (!linkedRespawntime || (cInfo && cInfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_HARD_RESET))) // Can respawn
|
||||
Respawn();
|
||||
else // the master is dead
|
||||
{
|
||||
ObjectGuid targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid);
|
||||
if (targetGuid == dbtableHighGuid) // if linking self, never respawn (check delayed to next day)
|
||||
{
|
||||
SetRespawnTime(DAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_respawnTime = (now > linkedRespawntime ? now : linkedRespawntime) + urand(5, MINUTE); // else copy time from master and add a little
|
||||
}
|
||||
SaveRespawnTime(); // also save to DB immediately
|
||||
}
|
||||
Respawn();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CORPSE:
|
||||
case DeathState::Corpse:
|
||||
{
|
||||
Unit::Update(diff);
|
||||
// deathstate changed on spells update, prevent problems
|
||||
if (m_deathState != CORPSE)
|
||||
if (m_deathState != DeathState::Corpse)
|
||||
break;
|
||||
|
||||
if (m_groupLootTimer && lootingGroupLowGUID)
|
||||
@@ -683,7 +655,7 @@ void Creature::Update(uint32 diff)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ALIVE:
|
||||
case DeathState::Alive:
|
||||
{
|
||||
Unit::Update(diff);
|
||||
|
||||
@@ -1721,12 +1693,12 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool ad
|
||||
m_wanderDistance = data->wander_distance;
|
||||
|
||||
m_respawnDelay = data->spawntimesecs;
|
||||
m_deathState = ALIVE;
|
||||
m_deathState = DeathState::Alive;
|
||||
|
||||
m_respawnTime = GetMap()->GetCreatureRespawnTime(m_spawnId);
|
||||
if (m_respawnTime) // respawn on Update
|
||||
{
|
||||
m_deathState = DEAD;
|
||||
m_deathState = DeathState::Dead;
|
||||
if (CanFly())
|
||||
{
|
||||
float tz = map->GetHeight(GetPhaseMask(), data->posX, data->posY, data->posZ, true, MAX_FALL_DISTANCE);
|
||||
@@ -1756,7 +1728,7 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool ad
|
||||
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
|
||||
}
|
||||
|
||||
SetHealth(m_deathState == ALIVE ? curhealth : 0);
|
||||
SetHealth(m_deathState == DeathState::Alive ? curhealth : 0);
|
||||
|
||||
// checked at creature_template loading
|
||||
m_defaultMovementType = MovementGeneratorType(data->movementType);
|
||||
@@ -1824,25 +1796,7 @@ void Creature::DeleteFromDB()
|
||||
return;
|
||||
}
|
||||
|
||||
CreatureData const* data = sObjectMgr->GetCreatureData(m_spawnId);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
CharacterDatabaseTransaction charTrans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
sMapMgr->DoForAllMapsWithMapId(data->mapid,
|
||||
[this, charTrans](Map* map) -> void
|
||||
{
|
||||
// despawn all active creatures, and remove their respawns
|
||||
std::vector<Creature*> toUnload;
|
||||
for (auto const& pair : Acore::Containers::MapEqualRange(map->GetCreatureBySpawnIdStore(), m_spawnId))
|
||||
toUnload.push_back(pair.second);
|
||||
for (Creature* creature : toUnload)
|
||||
map->AddObjectToRemoveList(creature);
|
||||
map->RemoveCreatureRespawnTime(m_spawnId);
|
||||
}
|
||||
);
|
||||
|
||||
GetMap()->RemoveCreatureRespawnTime(m_spawnId);
|
||||
sObjectMgr->DeleteCreatureData(m_spawnId);
|
||||
|
||||
WorldDatabaseTransaction trans = WorldDatabase.BeginTransaction();
|
||||
@@ -1951,7 +1905,7 @@ void Creature::setDeathState(DeathState s, bool despawn)
|
||||
{
|
||||
Unit::setDeathState(s, despawn);
|
||||
|
||||
if (s == JUST_DIED)
|
||||
if (s == DeathState::JustDied)
|
||||
{
|
||||
_lastDamagedTime.reset();
|
||||
|
||||
@@ -1985,9 +1939,9 @@ void Creature::setDeathState(DeathState s, bool despawn)
|
||||
if (needsFalling)
|
||||
GetMotionMaster()->MoveFall(0, true);
|
||||
|
||||
Unit::setDeathState(CORPSE, despawn);
|
||||
Unit::setDeathState(DeathState::Corpse, despawn);
|
||||
}
|
||||
else if (s == JUST_RESPAWNED)
|
||||
else if (s == DeathState::JustRespawned)
|
||||
{
|
||||
//if (IsPet())
|
||||
// setActive(true);
|
||||
@@ -2009,7 +1963,7 @@ void Creature::setDeathState(DeathState s, bool despawn)
|
||||
ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_IGNORE_PATHFINDING | UNIT_STATE_NO_ENVIRONMENT_UPD)));
|
||||
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
|
||||
|
||||
Unit::setDeathState(ALIVE, despawn);
|
||||
Unit::setDeathState(DeathState::Alive, despawn);
|
||||
|
||||
Motion_Initialize();
|
||||
LoadCreaturesAddon(true);
|
||||
@@ -2020,81 +1974,121 @@ void Creature::setDeathState(DeathState s, bool despawn)
|
||||
|
||||
void Creature::Respawn(bool force)
|
||||
{
|
||||
//DestroyForNearbyPlayers(); // pussywizard: not needed
|
||||
|
||||
if (force)
|
||||
{
|
||||
if (IsAlive())
|
||||
setDeathState(JUST_DIED);
|
||||
else if (getDeathState() != CORPSE)
|
||||
setDeathState(CORPSE);
|
||||
{
|
||||
setDeathState(DeathState::JustDied);
|
||||
}
|
||||
else if (getDeathState() != DeathState::Corpse)
|
||||
{
|
||||
setDeathState(DeathState::Corpse);
|
||||
}
|
||||
}
|
||||
|
||||
RemoveCorpse(false, false);
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_RESPAWN, GetEntry());
|
||||
|
||||
if (getDeathState() == DEAD)
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(this, conditions) && !force)
|
||||
{
|
||||
if (m_spawnId)
|
||||
{
|
||||
GetMap()->RemoveCreatureRespawnTime(m_spawnId);
|
||||
CreatureData const* data = sObjectMgr->GetCreatureData(m_spawnId);
|
||||
// Respawn check if spawn has 2 entries
|
||||
if (data->id2)
|
||||
{
|
||||
uint32 entry = GetRandomId(data->id1, data->id2, data->id3);
|
||||
UpdateEntry(entry, data, true); // Select Random Entry
|
||||
m_defaultMovementType = MovementGeneratorType(data->movementType); // Reload Movement Type
|
||||
LoadEquipment(data->equipmentId); // Reload Equipment
|
||||
AIM_Initialize(); // Reload AI
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_originalEntry != GetEntry())
|
||||
UpdateEntry(m_originalEntry);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("entities.unit", "Respawning creature {} (SpawnId: {}, {})", GetName(), GetSpawnId(), GetGUID().ToString());
|
||||
m_respawnTime = 0;
|
||||
ResetPickPocketLootTime();
|
||||
loot.clear();
|
||||
SelectLevel();
|
||||
|
||||
setDeathState(JUST_RESPAWNED);
|
||||
|
||||
// MDic - Acidmanifesto
|
||||
// Do not override transform auras
|
||||
if (GetAuraEffectsByType(SPELL_AURA_TRANSFORM).empty())
|
||||
{
|
||||
uint32 displayID = GetNativeDisplayId();
|
||||
if (sObjectMgr->GetCreatureModelRandomGender(&displayID)) // Cancel load if no model defined
|
||||
{
|
||||
SetDisplayId(displayID);
|
||||
SetNativeDisplayId(displayID);
|
||||
}
|
||||
}
|
||||
|
||||
GetMotionMaster()->InitDefault();
|
||||
|
||||
//Call AI respawn virtual function
|
||||
if (IsAIEnabled)
|
||||
{
|
||||
//reset the AI to be sure no dirty or uninitialized values will be used till next tick
|
||||
AI()->Reset();
|
||||
TriggerJustRespawned = true;//delay event to next tick so all creatures are created on the map before processing
|
||||
}
|
||||
|
||||
uint32 poolid = m_spawnId ? sPoolMgr->IsPartOfAPool<Creature>(m_spawnId) : 0;
|
||||
if (poolid)
|
||||
sPoolMgr->UpdatePool<Creature>(poolid, m_spawnId);
|
||||
|
||||
//Re-initialize reactstate that could be altered by movementgenerators
|
||||
InitializeReactState();
|
||||
|
||||
m_respawnedTime = GameTime::GetGameTime().count();
|
||||
// Creature should not respawn, reset respawn timer. Conditions will be checked again the next time it tries to respawn.
|
||||
m_respawnTime = GameTime::GetGameTime().count() + m_respawnDelay;
|
||||
return;
|
||||
}
|
||||
|
||||
bool allowed = !IsAIEnabled || AI()->CanRespawn(); // First check if there are any scripts that prevent us respawning
|
||||
if (!allowed && !force) // Will be rechecked on next Update call
|
||||
return;
|
||||
|
||||
ObjectGuid dbtableHighGuid = ObjectGuid::Create<HighGuid::Unit>(m_creatureData ? m_creatureData->id1 : GetEntry(), m_spawnId);
|
||||
time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
|
||||
|
||||
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(GetEntry());
|
||||
|
||||
if (!linkedRespawntime || (cInfo && cInfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_HARD_RESET)) || force) // Should respawn
|
||||
{
|
||||
RemoveCorpse(false, false);
|
||||
|
||||
if (getDeathState() == DeathState::Dead)
|
||||
{
|
||||
if (m_spawnId)
|
||||
{
|
||||
GetMap()->RemoveCreatureRespawnTime(m_spawnId);
|
||||
CreatureData const* data = sObjectMgr->GetCreatureData(m_spawnId);
|
||||
// Respawn check if spawn has 2 entries
|
||||
if (data->id2)
|
||||
{
|
||||
uint32 entry = GetRandomId(data->id1, data->id2, data->id3);
|
||||
UpdateEntry(entry, data, true); // Select Random Entry
|
||||
m_defaultMovementType = MovementGeneratorType(data->movementType); // Reload Movement Type
|
||||
LoadEquipment(data->equipmentId); // Reload Equipment
|
||||
AIM_Initialize(); // Reload AI
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_originalEntry != GetEntry())
|
||||
UpdateEntry(m_originalEntry);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("entities.unit", "Respawning creature {} (SpawnId: {}, {})", GetName(), GetSpawnId(), GetGUID().ToString());
|
||||
m_respawnTime = 0;
|
||||
ResetPickPocketLootTime();
|
||||
loot.clear();
|
||||
SelectLevel();
|
||||
|
||||
setDeathState(DeathState::JustRespawned);
|
||||
|
||||
// MDic - Acidmanifesto
|
||||
// Do not override transform auras
|
||||
if (GetAuraEffectsByType(SPELL_AURA_TRANSFORM).empty())
|
||||
{
|
||||
uint32 displayID = GetNativeDisplayId();
|
||||
if (sObjectMgr->GetCreatureModelRandomGender(&displayID)) // Cancel load if no model defined
|
||||
{
|
||||
SetDisplayId(displayID);
|
||||
SetNativeDisplayId(displayID);
|
||||
}
|
||||
}
|
||||
|
||||
GetMotionMaster()->InitDefault();
|
||||
|
||||
//Call AI respawn virtual function
|
||||
if (IsAIEnabled)
|
||||
{
|
||||
//reset the AI to be sure no dirty or uninitialized values will be used till next tick
|
||||
AI()->Reset();
|
||||
TriggerJustRespawned = true;//delay event to next tick so all creatures are created on the map before processing
|
||||
}
|
||||
|
||||
uint32 poolid = m_spawnId ? sPoolMgr->IsPartOfAPool<Creature>(m_spawnId) : 0;
|
||||
if (poolid)
|
||||
sPoolMgr->UpdatePool<Creature>(poolid, m_spawnId);
|
||||
|
||||
//Re-initialize reactstate that could be altered by movementgenerators
|
||||
InitializeReactState();
|
||||
|
||||
m_respawnedTime = GameTime::GetGameTime().count();
|
||||
}
|
||||
m_respawnedTime = GameTime::GetGameTime().count();
|
||||
// xinef: relocate notifier, fixes npc appearing in corpse position after forced respawn (instead of spawn)
|
||||
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
|
||||
UpdateObjectVisibility(false);
|
||||
|
||||
}
|
||||
else // the master is dead
|
||||
{
|
||||
ObjectGuid targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid);
|
||||
if (targetGuid == dbtableHighGuid) // if linking self, never respawn (check delayed to next day)
|
||||
{
|
||||
SetRespawnTime(DAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t now = GameTime::GetGameTime().count();
|
||||
m_respawnTime = (now > linkedRespawntime ? now : linkedRespawntime) + urand(5, MINUTE); // else copy time from master and add a little
|
||||
}
|
||||
SaveRespawnTime(); // also save to DB immediately
|
||||
}
|
||||
m_respawnedTime = GameTime::GetGameTime().count();
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer)
|
||||
@@ -2107,15 +2101,17 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer)
|
||||
}
|
||||
|
||||
if (IsAlive())
|
||||
setDeathState(JUST_DIED, true);
|
||||
setDeathState(DeathState::JustDied, true);
|
||||
|
||||
// Xinef: set new respawn time, ignore corpse decay time...
|
||||
RemoveCorpse(true);
|
||||
|
||||
if (forceRespawnTimer > Seconds::zero())
|
||||
{
|
||||
m_respawnTime = GameTime::GetGameTime().count() + forceRespawnTimer.count();
|
||||
m_respawnDelay = forceRespawnTimer.count();
|
||||
if (GetMap())
|
||||
{
|
||||
GetMap()->ScheduleCreatureRespawn(GetGUID(), forceRespawnTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3076,7 +3072,10 @@ std::string const& Creature::GetNameForLocaleIdx(LocaleConstant loc_idx) const
|
||||
|
||||
void Creature::SetPosition(float x, float y, float z, float o)
|
||||
{
|
||||
UpdatePosition(x, y, z, o, false);
|
||||
if (!Acore::IsValidMapCoord(x, y, z, o))
|
||||
return;
|
||||
|
||||
GetMap()->CreatureRelocation(this, x, y, z, o);
|
||||
}
|
||||
|
||||
bool Creature::IsDungeonBoss() const
|
||||
@@ -3745,6 +3744,15 @@ bool Creature::CanCastSpell(uint32 spellID) const
|
||||
return true;
|
||||
}
|
||||
|
||||
ObjectGuid Creature::GetSummonerGUID() const
|
||||
{
|
||||
if (TempSummon const* temp = ToTempSummon())
|
||||
return temp->GetSummonerGUID();
|
||||
|
||||
LOG_DEBUG("entities.unit", "Creature::GetSummonerGUID() called by creature that is not a summon. Creature: {} ({})", GetEntry(), GetName());
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
|
||||
std::string Creature::GetDebugInfo() const
|
||||
{
|
||||
std::stringstream sstr;
|
||||
|
||||
@@ -68,7 +68,6 @@ public:
|
||||
|
||||
void Update(uint32 time) override; // overwrited Unit::Update
|
||||
void GetRespawnPosition(float& x, float& y, float& z, float* ori = nullptr, float* dist = nullptr) const;
|
||||
bool IsSpawnedOnTransport() const { return m_creatureData && m_creatureData->mapid != GetMapId(); }
|
||||
|
||||
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
||||
void SetCorpseRemoveTime(uint32 delay);
|
||||
@@ -408,6 +407,12 @@ public:
|
||||
* */
|
||||
bool CanCastSpell(uint32 spellID) const;
|
||||
|
||||
/**
|
||||
* @brief Helper to get the creature's summoner GUID, if it is a summon
|
||||
*
|
||||
* */
|
||||
[[nodiscard]] ObjectGuid GetSummonerGUID() const;
|
||||
|
||||
std::string GetDebugInfo() const override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
|
||||
#include "GossipDef.h"
|
||||
#include "Formulas.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "QuestDef.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ void TempSummon::Update(uint32 diff)
|
||||
{
|
||||
Creature::Update(diff);
|
||||
|
||||
if (m_deathState == DEAD)
|
||||
if (m_deathState == DeathState::Dead)
|
||||
{
|
||||
UnSummon();
|
||||
return;
|
||||
@@ -107,7 +107,7 @@ void TempSummon::Update(uint32 diff)
|
||||
}
|
||||
case TEMPSUMMON_TIMED_DESPAWN_OOC_ALIVE:
|
||||
{
|
||||
if (!IsInCombat() && m_deathState != CORPSE)
|
||||
if (!IsInCombat() && m_deathState != DeathState::Corpse)
|
||||
{
|
||||
if (m_timer <= diff)
|
||||
{
|
||||
@@ -124,7 +124,7 @@ void TempSummon::Update(uint32 diff)
|
||||
}
|
||||
case TEMPSUMMON_CORPSE_TIMED_DESPAWN:
|
||||
{
|
||||
if (m_deathState == CORPSE)
|
||||
if (m_deathState == DeathState::Corpse)
|
||||
{
|
||||
if (m_timer <= diff)
|
||||
{
|
||||
@@ -139,7 +139,7 @@ void TempSummon::Update(uint32 diff)
|
||||
case TEMPSUMMON_CORPSE_DESPAWN:
|
||||
{
|
||||
// if m_deathState is DEAD, CORPSE was skipped
|
||||
if (m_deathState == CORPSE)
|
||||
if (m_deathState == DeathState::Corpse)
|
||||
{
|
||||
UnSummon();
|
||||
return;
|
||||
@@ -154,7 +154,7 @@ void TempSummon::Update(uint32 diff)
|
||||
case TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN:
|
||||
{
|
||||
// if m_deathState is DEAD, CORPSE was skipped
|
||||
if (m_deathState == CORPSE)
|
||||
if (m_deathState == DeathState::Corpse)
|
||||
{
|
||||
UnSummon();
|
||||
return;
|
||||
@@ -395,7 +395,7 @@ bool Minion::IsGuardianPet() const
|
||||
void Minion::setDeathState(DeathState s, bool despawn)
|
||||
{
|
||||
Creature::setDeathState(s, despawn);
|
||||
if (s == JUST_DIED && IsGuardianPet())
|
||||
if (s == DeathState::JustDied && IsGuardianPet())
|
||||
if (Unit* owner = GetOwner())
|
||||
if (owner->GetTypeId() == TYPEID_PLAYER && owner->GetMinionGUID() == GetGUID())
|
||||
for (Unit::ControlSet::const_iterator itr = owner->m_Controlled.begin(); itr != owner->m_Controlled.end(); ++itr)
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "GameTime.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Opcodes.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "Transport.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "World.h"
|
||||
@@ -47,6 +47,14 @@ DynamicObject::~DynamicObject()
|
||||
|
||||
void DynamicObject::CleanupsBeforeDelete(bool finalCleanup /* = true */)
|
||||
{
|
||||
if (Transport* transport = GetTransport())
|
||||
{
|
||||
transport->RemovePassenger(this);
|
||||
SetTransport(nullptr);
|
||||
m_movementInfo.transport.Reset();
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
}
|
||||
|
||||
WorldObject::CleanupsBeforeDelete(finalCleanup);
|
||||
}
|
||||
|
||||
@@ -80,6 +88,9 @@ void DynamicObject::RemoveFromWorld()
|
||||
|
||||
UnbindFromCaster();
|
||||
|
||||
if (Transport* transport = GetTransport())
|
||||
transport->RemovePassenger(this, true);
|
||||
|
||||
WorldObject::RemoveFromWorld();
|
||||
|
||||
GetMap()->GetObjectsStore().Remove<DynamicObject>(GetGUID());
|
||||
@@ -114,15 +125,17 @@ bool DynamicObject::CreateDynamicObject(ObjectGuid::LowType guidlow, Unit* caste
|
||||
SetFloatValue(DYNAMICOBJECT_RADIUS, radius);
|
||||
SetUInt32Value(DYNAMICOBJECT_CASTTIME, GameTime::GetGameTimeMS().count());
|
||||
|
||||
if (IsWorldObject())
|
||||
setActive(true); //must before add to map to be put in world container
|
||||
|
||||
if (!GetMap()->AddToMap(this, true))
|
||||
{
|
||||
// Returning false will cause the object to be deleted - remove from transport
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsWorldObject())
|
||||
{
|
||||
setActive(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "Group.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "MapMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "PoolMgr.h"
|
||||
@@ -103,9 +102,18 @@ std::string const& GameObject::GetAIName() const
|
||||
return sObjectMgr->GetGameObjectTemplate(GetEntry())->AIName;
|
||||
}
|
||||
|
||||
void GameObject::CleanupsBeforeDelete(bool finalCleanup)
|
||||
void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
|
||||
{
|
||||
WorldObject::CleanupsBeforeDelete(finalCleanup);
|
||||
if (GetTransport() && !ToTransport())
|
||||
{
|
||||
GetTransport()->RemovePassenger(this);
|
||||
SetTransport(nullptr);
|
||||
m_movementInfo.transport.Reset();
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
}
|
||||
|
||||
if (IsInWorld())
|
||||
RemoveFromWorld();
|
||||
|
||||
if (m_uint32Values) // field array can be not exist if GameOBject not loaded
|
||||
RemoveFromOwner();
|
||||
@@ -174,6 +182,9 @@ void GameObject::RemoveFromWorld()
|
||||
if (GetMap()->ContainsGameObjectModel(*m_model))
|
||||
GetMap()->RemoveGameObjectModel(*m_model);
|
||||
|
||||
if (Transport* transport = GetTransport())
|
||||
transport->RemovePassenger(this, true);
|
||||
|
||||
// If linked trap exists, despawn it
|
||||
if (GameObject* linkedTrap = GetLinkedTrap())
|
||||
{
|
||||
@@ -877,11 +888,7 @@ void GameObject::Update(uint32 diff)
|
||||
if (!m_spawnedByDefault)
|
||||
{
|
||||
m_respawnTime = 0;
|
||||
if (m_spawnId)
|
||||
DestroyForNearbyPlayers(); // xinef: old UpdateObjectVisibility();
|
||||
else
|
||||
Delete();
|
||||
|
||||
DestroyForNearbyPlayers(); // xinef: old UpdateObjectVisibility();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1178,31 +1185,7 @@ bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, boo
|
||||
|
||||
void GameObject::DeleteFromDB()
|
||||
{
|
||||
if (!m_spawnId)
|
||||
{
|
||||
LOG_ERROR("entities.gameobject", "Trying to delete not saved gameobject: {}", GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
GameObjectData const* data = sObjectMgr->GetGameObjectData(m_spawnId);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
CharacterDatabaseTransaction charTrans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
sMapMgr->DoForAllMapsWithMapId(data->mapid,
|
||||
[this, charTrans](Map* map) -> void
|
||||
{
|
||||
// despawn all active objects, and remove their respawns
|
||||
std::vector<GameObject*> toUnload;
|
||||
for (auto const& pair : Acore::Containers::MapEqualRange(map->GetGameObjectBySpawnIdStore(), m_spawnId))
|
||||
toUnload.push_back(pair.second);
|
||||
for (GameObject* obj : toUnload)
|
||||
map->AddObjectToRemoveList(obj);
|
||||
map->RemoveGORespawnTime(m_spawnId);
|
||||
}
|
||||
);
|
||||
|
||||
GetMap()->RemoveGORespawnTime(m_spawnId);
|
||||
sObjectMgr->DeleteGOData(m_spawnId);
|
||||
|
||||
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT);
|
||||
@@ -2191,6 +2174,15 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const
|
||||
&& dz < (info->maxZ * scale) + radius && dz > (info->minZ * scale) - radius;
|
||||
}
|
||||
|
||||
void GameObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin, Player const* skipped_rcvr) const
|
||||
{
|
||||
dist += GetObjectSize();
|
||||
if (includeMargin)
|
||||
dist += VISIBILITY_COMPENSATION * 2.0f; // pussywizard: to ensure everyone receives all important packets
|
||||
Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr);
|
||||
Cell::VisitWorldObjects(this, notifier, dist);
|
||||
}
|
||||
|
||||
void GameObject::EventInform(uint32 eventId)
|
||||
{
|
||||
if (!eventId)
|
||||
@@ -2807,7 +2799,7 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
|
||||
return;
|
||||
|
||||
bool forcedFlags = GetGoType() == GAMEOBJECT_TYPE_CHEST && GetGOInfo()->chest.groupLootRules && HasLootRecipient();
|
||||
bool targetIsGM = target->IsGameMaster() && AccountMgr::IsGMAccount(target->GetSession()->GetSecurity());
|
||||
bool targetIsGM = target->IsGameMaster() && target->GetSession()->IsGMAccount();
|
||||
|
||||
ByteBuffer fieldBuffer;
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
#include "Common.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "G3D/Quat.h"
|
||||
#include "GameObjectData.h"
|
||||
#include "LootMgr.h"
|
||||
#include "Object.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "GameObjectData.h"
|
||||
#include "Unit.h"
|
||||
#include <array>
|
||||
|
||||
@@ -289,6 +289,8 @@ public:
|
||||
void SendCustomAnim(uint32 anim);
|
||||
[[nodiscard]] bool IsInRange(float x, float y, float z, float radius) const;
|
||||
|
||||
void SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const override; // pussywizard!
|
||||
|
||||
void ModifyHealth(int32 change, Unit* attackerOrHealer = nullptr, uint32 spellId = 0);
|
||||
void SetDestructibleBuildingModifyState(bool allow) { m_allowModifyDestructibleBuilding = allow; }
|
||||
// sets GameObject type 33 destruction flags and optionally default health for that state
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
void AddItemsSetItem(Player* player, Item* item)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ struct ItemSetEffect
|
||||
};
|
||||
|
||||
// EnumUtils: DESCRIBE THIS
|
||||
enum InventoryResult
|
||||
enum InventoryResult : uint8
|
||||
{
|
||||
EQUIP_ERR_OK = 0,
|
||||
EQUIP_ERR_CANT_EQUIP_LEVEL_I = 1,
|
||||
@@ -158,7 +158,7 @@ enum SellResult
|
||||
};
|
||||
|
||||
// -1 from client enchantment slot number
|
||||
enum EnchantmentSlot
|
||||
enum EnchantmentSlot : uint8
|
||||
{
|
||||
PERM_ENCHANTMENT_SLOT = 0,
|
||||
TEMP_ENCHANTMENT_SLOT = 1,
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Item.h"
|
||||
#include "Define.h"
|
||||
#include "Item.h"
|
||||
#include "SmartEnum.h"
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "CellImpl.h"
|
||||
#include "Chat.h"
|
||||
#include "Creature.h"
|
||||
#include "DynamicVisibility.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "GameTime.h"
|
||||
#include "GridNotifiers.h"
|
||||
@@ -37,8 +38,10 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "StringConvert.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Totem.h"
|
||||
#include "Transport.h"
|
||||
#include "UpdateData.h"
|
||||
@@ -48,8 +51,6 @@
|
||||
#include "Vehicle.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
|
||||
/// @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
|
||||
@@ -64,7 +65,7 @@ constexpr float VisibilityDistances[AsUnderlyingType(VisibilityDistanceType::Max
|
||||
VISIBILITY_DISTANCE_SMALL,
|
||||
VISIBILITY_DISTANCE_LARGE,
|
||||
VISIBILITY_DISTANCE_GIGANTIC,
|
||||
MAX_VISIBILITY_DISTANCE
|
||||
VISIBILITY_DISTANCE_INFINITE
|
||||
};
|
||||
|
||||
Object::Object() : m_PackGUID(sizeof(uint64) + 1)
|
||||
@@ -248,10 +249,7 @@ void Object::SendUpdateToPlayer(Player* player)
|
||||
UpdateData upd;
|
||||
WorldPacket packet;
|
||||
|
||||
if (player->HaveAtClient(this))
|
||||
BuildValuesUpdateBlockForPlayer(&upd, player);
|
||||
else
|
||||
BuildCreateUpdateBlockForPlayer(&upd, player);
|
||||
BuildCreateUpdateBlockForPlayer(&upd, player);
|
||||
upd.BuildPacket(&packet);
|
||||
player->GetSession()->SendPacket(&packet);
|
||||
}
|
||||
@@ -1050,7 +1048,7 @@ void MovementInfo::OutDebug()
|
||||
}
|
||||
|
||||
WorldObject::WorldObject(bool isWorldObject) : WorldLocation(),
|
||||
LastUsedScriptID(0), m_name(""), m_isActive(false), m_isFarVisible(false), m_visibilityDistanceOverride(), m_isWorldObject(isWorldObject), m_zoneScript(nullptr),
|
||||
LastUsedScriptID(0), m_name(""), m_isActive(false), m_visibilityDistanceOverride(), m_isWorldObject(isWorldObject), m_zoneScript(nullptr),
|
||||
_zoneId(0), _areaId(0), _floorZ(INVALID_HEIGHT), _outdoors(false), _liquidData(), _updatePositionData(false), m_transport(nullptr),
|
||||
m_currMap(nullptr), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_useCombinedPhases(true), m_notifyflags(0), m_executed_notifies(0)
|
||||
{
|
||||
@@ -1107,6 +1105,8 @@ void WorldObject::setActive(bool on)
|
||||
map->AddToActive(this->ToCreature());
|
||||
else if (GetTypeId() == TYPEID_DYNAMICOBJECT)
|
||||
map->AddToActive((DynamicObject*)this);
|
||||
else if (GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
map->AddToActive((GameObject*)this);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1114,17 +1114,11 @@ void WorldObject::setActive(bool on)
|
||||
map->RemoveFromActive(this->ToCreature());
|
||||
else if (GetTypeId() == TYPEID_DYNAMICOBJECT)
|
||||
map->RemoveFromActive((DynamicObject*)this);
|
||||
else if (GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
map->RemoveFromActive((GameObject*)this);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldObject::SetFarVisible(bool on)
|
||||
{
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
m_isFarVisible = on;
|
||||
}
|
||||
|
||||
void WorldObject::SetVisibilityDistanceOverride(VisibilityDistanceType type)
|
||||
{
|
||||
ASSERT(type < VisibilityDistanceType::Max);
|
||||
@@ -1140,9 +1134,6 @@ void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
|
||||
{
|
||||
if (IsInWorld())
|
||||
RemoveFromWorld();
|
||||
|
||||
if (Transport* transport = GetTransport())
|
||||
transport->RemovePassenger(this, true);
|
||||
}
|
||||
|
||||
void WorldObject::_Create(ObjectGuid::LowType guidlow, HighGuid guidhigh, uint32 phaseMask)
|
||||
@@ -1635,9 +1626,9 @@ float WorldObject::GetGridActivationRange() const
|
||||
{
|
||||
if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
|
||||
{
|
||||
return std::max(DEFAULT_VISIBILITY_INSTANCE, GetMap()->GetVisibilityRange());
|
||||
return DEFAULT_VISIBILITY_INSTANCE;
|
||||
}
|
||||
return IsInWintergrasp() ? VISIBILITY_DISTANCE_LARGE : GetMap()->GetVisibilityRange();
|
||||
return IsInWintergrasp() ? VISIBILITY_DIST_WINTERGRASP : GetMap()->GetVisibilityRange();
|
||||
}
|
||||
else if (ToCreature())
|
||||
{
|
||||
@@ -1653,12 +1644,29 @@ float WorldObject::GetGridActivationRange() const
|
||||
|
||||
float WorldObject::GetVisibilityRange() const
|
||||
{
|
||||
if (IsVisibilityOverridden() && !ToPlayer())
|
||||
if (IsVisibilityOverridden() && GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
return *m_visibilityDistanceOverride;
|
||||
else if (IsFarVisible() && !ToPlayer())
|
||||
return MAX_VISIBILITY_DISTANCE;
|
||||
}
|
||||
else if (GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
{
|
||||
{
|
||||
if (IsInWintergrasp())
|
||||
{
|
||||
return VISIBILITY_DIST_WINTERGRASP + VISIBILITY_INC_FOR_GOBJECTS;
|
||||
}
|
||||
else if (IsVisibilityOverridden())
|
||||
{
|
||||
return *m_visibilityDistanceOverride;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetMap()->GetVisibilityRange() + VISIBILITY_INC_FOR_GOBJECTS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return IsInWintergrasp() ? VISIBILITY_DISTANCE_LARGE : GetMap()->GetVisibilityRange();
|
||||
return IsInWintergrasp() ? VISIBILITY_DIST_WINTERGRASP : GetMap()->GetVisibilityRange();
|
||||
}
|
||||
|
||||
float WorldObject::GetSightRange(WorldObject const* target) const
|
||||
@@ -1667,19 +1675,44 @@ float WorldObject::GetSightRange(WorldObject const* target) const
|
||||
{
|
||||
if (ToPlayer())
|
||||
{
|
||||
if (target && target->IsVisibilityOverridden() && !target->ToPlayer())
|
||||
return *target->m_visibilityDistanceOverride;
|
||||
else if (target && target->IsFarVisible() && !target->ToPlayer())
|
||||
return MAX_VISIBILITY_DISTANCE;
|
||||
else if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
|
||||
return DEFAULT_VISIBILITY_INSTANCE;
|
||||
else
|
||||
return IsInWintergrasp() ? VISIBILITY_DISTANCE_LARGE : GetMap()->GetVisibilityRange();
|
||||
if (target)
|
||||
{
|
||||
if (target->IsVisibilityOverridden() && target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
return *target->m_visibilityDistanceOverride;
|
||||
}
|
||||
else if (target->GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
{
|
||||
if (IsInWintergrasp() && target->IsInWintergrasp())
|
||||
{
|
||||
return VISIBILITY_DIST_WINTERGRASP + VISIBILITY_INC_FOR_GOBJECTS;
|
||||
}
|
||||
else if (target->IsVisibilityOverridden())
|
||||
{
|
||||
return *target->m_visibilityDistanceOverride;
|
||||
}
|
||||
else if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
|
||||
{
|
||||
return DEFAULT_VISIBILITY_INSTANCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetMap()->GetVisibilityRange() + VISIBILITY_INC_FOR_GOBJECTS;
|
||||
}
|
||||
}
|
||||
|
||||
return IsInWintergrasp() && target->IsInWintergrasp() ? VISIBILITY_DIST_WINTERGRASP : GetMap()->GetVisibilityRange();
|
||||
}
|
||||
return IsInWintergrasp() ? VISIBILITY_DIST_WINTERGRASP : GetMap()->GetVisibilityRange();
|
||||
}
|
||||
else if (ToCreature())
|
||||
{
|
||||
return ToCreature()->m_SightDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SIGHT_RANGE_UNIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (ToDynObject() && isActiveObject())
|
||||
@@ -2044,8 +2077,11 @@ void Unit::BuildHeartBeatMsg(WorldPacket* data) const
|
||||
BuildMovementPacket(data);
|
||||
}
|
||||
|
||||
void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, Player const* skipped_rcvr) const
|
||||
void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin, Player const* skipped_rcvr) const
|
||||
{
|
||||
dist += GetObjectSize();
|
||||
if (includeMargin)
|
||||
dist += VISIBILITY_COMPENSATION; // pussywizard: to ensure everyone receives all important packets
|
||||
Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr);
|
||||
Cell::VisitWorldObjects(this, notifier, dist);
|
||||
}
|
||||
@@ -2192,8 +2228,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!IsGridLoaded(pos.GetPositionX(), pos.GetPositionY()))
|
||||
EnsureGridLoaded(Cell(pos.GetPositionX(), pos.GetPositionY()));
|
||||
EnsureGridLoaded(Cell(pos.GetPositionX(), pos.GetPositionY()));
|
||||
if (!summon->Create(GenerateLowGuid<HighGuid::Unit>(), this, phase, entry, vehId, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()))
|
||||
{
|
||||
delete summon;
|
||||
@@ -2866,8 +2901,8 @@ void WorldObject::DestroyForNearbyPlayers()
|
||||
return;
|
||||
|
||||
std::list<Player*> targets;
|
||||
Acore::AnyPlayerInObjectRangeCheck check(this, GetVisibilityRange(), false);
|
||||
Acore::PlayerListSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(this, targets, check);
|
||||
Acore::AnyPlayerInObjectRangeCheck check(this, GetVisibilityRange() + VISIBILITY_COMPENSATION, false);
|
||||
Acore::PlayerListSearcherWithSharedVision<Acore::AnyPlayerInObjectRangeCheck> searcher(this, targets, check);
|
||||
Cell::VisitWorldObjects(this, searcher, GetVisibilityRange());
|
||||
for (std::list<Player*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
|
||||
{
|
||||
@@ -2887,7 +2922,7 @@ void WorldObject::DestroyForNearbyPlayers()
|
||||
}
|
||||
}
|
||||
|
||||
void WorldObject::UpdateObjectVisibility(bool /*forced*/)
|
||||
void WorldObject::UpdateObjectVisibility(bool /*forced*/, bool /*fromUpdate*/)
|
||||
{
|
||||
//updates object's visibility for nearby players
|
||||
Acore::VisibleChangesNotifier notifier(*this);
|
||||
@@ -2896,7 +2931,28 @@ void WorldObject::UpdateObjectVisibility(bool /*forced*/)
|
||||
|
||||
void WorldObject::AddToNotify(uint16 f)
|
||||
{
|
||||
m_notifyflags |= f;
|
||||
if (!(m_notifyflags & f))
|
||||
if (Unit* u = ToUnit())
|
||||
{
|
||||
if (f & NOTIFY_VISIBILITY_CHANGED)
|
||||
{
|
||||
uint32 EVENT_VISIBILITY_DELAY = u->FindMap() ? DynamicVisibilityMgr::GetVisibilityNotifyDelay(u->FindMap()->GetEntry()->map_type) : 1000;
|
||||
|
||||
uint32 diff = getMSTimeDiff(u->m_last_notify_mstime, GameTime::GetGameTimeMS().count());
|
||||
if (diff >= EVENT_VISIBILITY_DELAY / 2)
|
||||
EVENT_VISIBILITY_DELAY /= 2;
|
||||
else
|
||||
EVENT_VISIBILITY_DELAY -= diff;
|
||||
u->m_delayed_unit_relocation_timer = EVENT_VISIBILITY_DELAY;
|
||||
u->m_last_notify_mstime = GameTime::GetGameTimeMS().count() + EVENT_VISIBILITY_DELAY - 1;
|
||||
}
|
||||
else if (f & NOTIFY_AI_RELOCATION)
|
||||
{
|
||||
u->m_delayed_unit_ai_notify_timer = u->FindMap() ? DynamicVisibilityMgr::GetAINotifyDelay(u->FindMap()->GetEntry()->map_type) : 500;
|
||||
}
|
||||
|
||||
m_notifyflags |= f;
|
||||
}
|
||||
}
|
||||
|
||||
struct WorldObjectChangeAccumulator
|
||||
@@ -2949,7 +3005,7 @@ struct WorldObjectChangeAccumulator
|
||||
source = iter->GetSource();
|
||||
ObjectGuid guid = source->GetCasterGUID();
|
||||
|
||||
if (guid.IsPlayer())
|
||||
if (guid)
|
||||
{
|
||||
//Caster may be nullptr if DynObj is in removelist
|
||||
if (Player* caster = ObjectAccessor::FindPlayer(guid))
|
||||
|
||||
@@ -379,23 +379,14 @@ class MovableMapObject
|
||||
template<class T> friend class RandomMovementGenerator;
|
||||
|
||||
protected:
|
||||
MovableMapObject() : _moveState(MAP_OBJECT_CELL_MOVE_NONE)
|
||||
{
|
||||
_newPosition.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
MovableMapObject() = default;
|
||||
|
||||
private:
|
||||
Cell _currentCell;
|
||||
[[nodiscard]] Cell const& GetCurrentCell() const { return _currentCell; }
|
||||
void SetCurrentCell(Cell const& cell) { _currentCell = cell; }
|
||||
|
||||
MapObjectCellMoveState _moveState;
|
||||
Position _newPosition;
|
||||
void SetNewCellPosition(float x, float y, float z, float o)
|
||||
{
|
||||
_moveState = MAP_OBJECT_CELL_MOVE_ACTIVE;
|
||||
_newPosition.Relocate(x, y, z, o);
|
||||
}
|
||||
Cell _currentCell;
|
||||
MapObjectCellMoveState _moveState{MAP_OBJECT_CELL_MOVE_NONE};
|
||||
};
|
||||
|
||||
class WorldObject : public Object, public WorldLocation
|
||||
@@ -488,9 +479,9 @@ public:
|
||||
|
||||
virtual void CleanupsBeforeDelete(bool finalCleanup = true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
|
||||
|
||||
virtual void SendMessageToSet(WorldPacket const* data, bool self) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), self); } // pussywizard!
|
||||
virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, Player const* skipped_rcvr = nullptr) const; // pussywizard!
|
||||
virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), false, skipped_rcvr); } // pussywizard!
|
||||
virtual void SendMessageToSet(WorldPacket const* data, bool self) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), self, true); } // pussywizard!
|
||||
virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const; // pussywizard!
|
||||
virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), false, true, skipped_rcvr); } // pussywizard!
|
||||
|
||||
virtual uint8 getLevelForTarget(WorldObject const* /*target*/) const { return 1; }
|
||||
|
||||
@@ -547,7 +538,7 @@ public:
|
||||
void GetDeadCreatureListInGrid(std::list<Creature*>& lList, float maxSearchRange, bool alive = false) const;
|
||||
|
||||
void DestroyForNearbyPlayers();
|
||||
virtual void UpdateObjectVisibility(bool forced = true);
|
||||
virtual void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false);
|
||||
void BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet& player_set) override;
|
||||
void GetCreaturesWithEntryInRange(std::list<Creature*>& creatureList, float radius, uint32 entry);
|
||||
|
||||
@@ -569,7 +560,6 @@ public:
|
||||
[[nodiscard]] bool isActiveObject() const { return m_isActive; }
|
||||
void setActive(bool isActiveObject);
|
||||
[[nodiscard]] bool IsFarVisible() const { return m_isFarVisible; }
|
||||
void SetFarVisible(bool on);
|
||||
[[nodiscard]] bool IsVisibilityOverridden() const { return m_visibilityDistanceOverride.has_value(); }
|
||||
void SetVisibilityDistanceOverride(VisibilityDistanceType type);
|
||||
void SetWorldObject(bool apply);
|
||||
@@ -578,7 +568,7 @@ public:
|
||||
|
||||
[[nodiscard]] bool IsInWintergrasp() const
|
||||
{
|
||||
return GetMapId() == 571 && GetZoneId() == 4197;
|
||||
return GetMapId() == 571 && GetPositionX() > 3733.33331f && GetPositionX() < 5866.66663f && GetPositionY() > 1599.99999f && GetPositionY() < 4799.99997f;
|
||||
}
|
||||
|
||||
#ifdef MAP_BASED_RAND_GEN
|
||||
|
||||
@@ -23,18 +23,23 @@
|
||||
#define CONTACT_DISTANCE 0.5f
|
||||
#define INTERACTION_DISTANCE 5.5f
|
||||
#define ATTACK_DISTANCE 5.0f
|
||||
#define VISIBILITY_COMPENSATION 15.0f // increase searchers
|
||||
#define INSPECT_DISTANCE 28.0f
|
||||
#define VISIBILITY_INC_FOR_GOBJECTS 30.0f // pussywizard
|
||||
#define SPELL_SEARCHER_COMPENSATION 30.0f // increase searchers size in case we have large npc near cell border
|
||||
#define TRADE_DISTANCE 11.11f
|
||||
#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects, experimental
|
||||
#define MAX_VISIBILITY_DISTANCE 250.0f // max distance for visible objects, experimental
|
||||
#define SIGHT_RANGE_UNIT 50.0f
|
||||
#define MAX_SEARCHER_DISTANCE 150.0f // pussywizard: replace the use of MAX_VISIBILITY_DISTANCE in searchers, because MAX_VISIBILITY_DISTANCE is quite too big for this purpose
|
||||
#define VISIBILITY_DISTANCE_INFINITE 533.0f
|
||||
#define VISIBILITY_DISTANCE_GIGANTIC 400.0f
|
||||
#define VISIBILITY_DISTANCE_LARGE 200.0f
|
||||
#define VISIBILITY_DISTANCE_NORMAL 100.0f
|
||||
#define VISIBILITY_DISTANCE_SMALL 50.0f
|
||||
#define VISIBILITY_DISTANCE_TINY 25.0f
|
||||
#define DEFAULT_VISIBILITY_DISTANCE VISIBILITY_DISTANCE_NORMAL // default visible distance, 100 yards on continents
|
||||
#define DEFAULT_VISIBILITY_DISTANCE 100.0f // default visible distance, 100 yards on continents
|
||||
#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
|
||||
#define VISIBILITY_DIST_WINTERGRASP 175.0f
|
||||
#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
|
||||
|
||||
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
|
||||
|
||||
@@ -134,7 +134,6 @@ class ObjectGuid
|
||||
ObjectGuid(HighGuid hi, uint32 entry, LowType counter) : _guid(counter ? uint64(counter) | (uint64(entry) << 24) | (uint64(hi) << 48) : 0) { }
|
||||
ObjectGuid(HighGuid hi, LowType counter) : _guid(counter ? uint64(counter) | (uint64(hi) << 48) : 0) { }
|
||||
|
||||
operator uint64() const { return _guid; }
|
||||
PackedGuidReader ReadAsPacked() { return PackedGuidReader(*this); }
|
||||
|
||||
void Set(uint64 guid) { _guid = guid; }
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "Define.h"
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <math.h>
|
||||
|
||||
enum UsedPosType { USED_POS_PLUS, USED_POS_MINUS };
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#include "Position.h"
|
||||
#include "ByteBuffer.h"
|
||||
#include "GridDefines.h"
|
||||
#include "Geometry.h"
|
||||
#include "GridDefines.h"
|
||||
#include <G3D/g3dmath.h>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
#ifndef ACore_game_Position_h__
|
||||
#define ACore_game_Position_h__
|
||||
|
||||
#include <cmath>
|
||||
#include "Common.h"
|
||||
#include "G3D/Vector3.h"
|
||||
#include <cmath>
|
||||
|
||||
class ByteBuffer;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "DatabaseEnv.h"
|
||||
#include "GameTime.h"
|
||||
#include "Group.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PetPackets.h"
|
||||
@@ -472,7 +473,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
|
||||
else
|
||||
{
|
||||
if (!curHealth && getPetType() == HUNTER_PET)
|
||||
setDeathState(JUST_DIED);
|
||||
setDeathState(DeathState::JustDied);
|
||||
else
|
||||
{
|
||||
SetHealth(curHealth > GetMaxHealth() ? GetMaxHealth() : curHealth);
|
||||
@@ -616,7 +617,7 @@ void Pet::DeleteFromDB(ObjectGuid::LowType guidlow)
|
||||
void Pet::setDeathState(DeathState s, bool /*despawn = false*/) // overwrite virtual Creature::setDeathState and Unit::setDeathState
|
||||
{
|
||||
Creature::setDeathState(s);
|
||||
if (getDeathState() == CORPSE)
|
||||
if (getDeathState() == DeathState::Corpse)
|
||||
{
|
||||
if (getPetType() == HUNTER_PET)
|
||||
{
|
||||
@@ -632,7 +633,7 @@ void Pet::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
//SetUnitFlag(UNIT_FLAG_STUNNED);
|
||||
}
|
||||
}
|
||||
else if (getDeathState() == ALIVE)
|
||||
else if (getDeathState() == DeathState::Alive)
|
||||
{
|
||||
//RemoveUnitFlag(UNIT_FLAG_STUNNED);
|
||||
CastPetAuras(true);
|
||||
@@ -651,7 +652,7 @@ void Pet::Update(uint32 diff)
|
||||
|
||||
switch (m_deathState)
|
||||
{
|
||||
case CORPSE:
|
||||
case DeathState::Corpse:
|
||||
{
|
||||
if (getPetType() != HUNTER_PET || m_corpseRemoveTime <= GameTime::GetGameTime().count())
|
||||
{
|
||||
@@ -660,7 +661,7 @@ void Pet::Update(uint32 diff)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ALIVE:
|
||||
case DeathState::Alive:
|
||||
{
|
||||
// unsummon pet that lost owner
|
||||
Player* owner = GetOwner();
|
||||
@@ -1941,16 +1942,16 @@ void Pet::InitLevelupSpellsForLevel()
|
||||
{
|
||||
for (uint32 spellId : defSpells->spellid)
|
||||
{
|
||||
SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellEntry)
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellInfo)
|
||||
continue;
|
||||
|
||||
// will called first if level down
|
||||
if (spellEntry->SpellLevel > level && sScriptMgr->CanUnlearnSpellDefault(this, spellEntry))
|
||||
unlearnSpell(spellEntry->Id, true);
|
||||
if (spellInfo->SpellLevel > level && sScriptMgr->CanUnlearnSpellDefault(this, spellInfo))
|
||||
unlearnSpell(spellInfo->Id, true);
|
||||
// will called if level up
|
||||
else
|
||||
learnSpell(spellEntry->Id);
|
||||
learnSpell(spellInfo->Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2240,7 +2241,7 @@ uint8 Pet::GetMaxTalentPointsForLevel(uint8 level)
|
||||
|
||||
sScriptMgr->OnCalculateMaxTalentPointsForLevel(this, level, points);
|
||||
|
||||
return points;
|
||||
return uint8(points * sWorld->getRate(RATE_TALENT_PET));
|
||||
}
|
||||
|
||||
void Pet::ToggleAutocast(SpellInfo const* spellInfo, bool apply)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "Group.h"
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
|
||||
// KillRewarder incapsulates logic of rewarding player upon kill with:
|
||||
|
||||
@@ -53,14 +53,12 @@
|
||||
#include "InstanceSaveMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "LFGMgr.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
#include "LootItemStorage.h"
|
||||
#include "MapMgr.h"
|
||||
#include "MiscPackets.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "OutdoorPvP.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "Pet.h"
|
||||
@@ -75,18 +73,17 @@
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "StringConvert.h"
|
||||
#include "TicketMgr.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Transport.h"
|
||||
#include "UpdateData.h"
|
||||
#include "UpdateFieldFlags.h"
|
||||
#include "Util.h"
|
||||
#include "Vehicle.h"
|
||||
#include "Weather.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
|
||||
/// @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
|
||||
@@ -1010,7 +1007,7 @@ void Player::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
|
||||
bool cur = IsAlive();
|
||||
|
||||
if (s == JUST_DIED)
|
||||
if (s == DeathState::JustDied)
|
||||
{
|
||||
if (!cur)
|
||||
{
|
||||
@@ -1025,7 +1022,7 @@ void Player::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
|
||||
clearResurrectRequestData();
|
||||
|
||||
//FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
|
||||
//FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DeathState::Dead) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
|
||||
RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
|
||||
|
||||
// save value before aura remove in Unit::setDeathState
|
||||
@@ -1045,7 +1042,7 @@ void Player::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH, 0);
|
||||
}
|
||||
// xinef: enable passive area auras!
|
||||
else if (s == ALIVE)
|
||||
else if (s == DeathState::Alive)
|
||||
ClearUnitState(UNIT_STATE_ISOLATED);
|
||||
|
||||
Unit::setDeathState(s);
|
||||
@@ -1054,7 +1051,7 @@ void Player::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "STA", IsAlive() ? 1 : 0);
|
||||
|
||||
// restore resurrection spell id for player after aura remove
|
||||
if (s == JUST_DIED && cur && ressSpellId)
|
||||
if (s == DeathState::JustDied && cur && ressSpellId)
|
||||
SetUInt32Value(PLAYER_SELF_RES_SPELL, ressSpellId);
|
||||
|
||||
if (IsAlive() && !cur)
|
||||
@@ -1313,9 +1310,6 @@ void Player::SendTeleportAckPacket()
|
||||
|
||||
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options /*= 0*/, Unit* target /*= nullptr*/, bool newInstance /*= false*/)
|
||||
{
|
||||
// for except kick by antispeedhack
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(this, true);
|
||||
|
||||
if (!MapMgr::IsValidMapCoord(mapid, x, y, z, orientation))
|
||||
{
|
||||
LOG_ERROR("entities.player", "TeleportTo: invalid map ({}) or invalid coordinates (X: {}, Y: {}, Z: {}, O: {}) given when teleporting player ({}, name: {}, map: {}, X: {}, Y: {}, Z: {}, O: {}).",
|
||||
@@ -1353,7 +1347,10 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
|
||||
if (GetTransport())
|
||||
{
|
||||
m_transport->RemovePassenger(this, true);
|
||||
m_transport->RemovePassenger(this);
|
||||
m_transport = nullptr;
|
||||
m_movementInfo.transport.Reset();
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :)
|
||||
}
|
||||
|
||||
@@ -1395,7 +1392,10 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
else
|
||||
{
|
||||
m_transport->RemovePassenger(this, true);
|
||||
m_transport->RemovePassenger(this);
|
||||
m_transport = nullptr;
|
||||
m_movementInfo.transport.Reset();
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2186,14 +2186,14 @@ void Player::SetGameMaster(bool on)
|
||||
if (on)
|
||||
{
|
||||
m_ExtraFlags |= PLAYER_EXTRA_GM_ON;
|
||||
if (AccountMgr::IsGMAccount(GetSession()->GetSecurity()))
|
||||
if (GetSession()->IsGMAccount())
|
||||
SetFaction(FACTION_FRIENDLY);
|
||||
SetPlayerFlag(PLAYER_FLAGS_GM);
|
||||
SetUnitFlag2(UNIT_FLAG2_ALLOW_CHEAT_SPELLS);
|
||||
|
||||
if (Pet* pet = GetPet())
|
||||
{
|
||||
if (AccountMgr::IsGMAccount(GetSession()->GetSecurity()))
|
||||
if (GetSession()->IsGMAccount())
|
||||
pet->SetFaction(FACTION_FRIENDLY);
|
||||
pet->getHostileRefMgr().setOnlineOfflineState(false);
|
||||
}
|
||||
@@ -2292,7 +2292,6 @@ bool Player::IsInSameGroupWith(Player const* p) const
|
||||
}
|
||||
|
||||
///- If the player is invited, remove him. If the group if then only 1 person, disband the group.
|
||||
/// \todo Shouldn't we also check if there is no other invitees before disbanding the group?
|
||||
void Player::UninviteFromGroup()
|
||||
{
|
||||
Group* group = GetGroupInvite();
|
||||
@@ -2301,14 +2300,17 @@ void Player::UninviteFromGroup()
|
||||
|
||||
group->RemoveInvite(this);
|
||||
|
||||
if (group->GetMembersCount() <= 1) // group has just 1 member => disband
|
||||
if (group->IsCreated())
|
||||
{
|
||||
if (group->IsCreated())
|
||||
if (group->GetMembersCount() <= 1) // group has just 1 member => disband
|
||||
{
|
||||
group->Disband(true);
|
||||
group = nullptr; // gets deleted in disband
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (group->GetInviteeCount() <= 1)
|
||||
{
|
||||
group->RemoveAllInvites();
|
||||
delete group;
|
||||
@@ -4398,7 +4400,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
|
||||
if (GetSession()->IsARecruiter() || (GetSession()->GetRecruiterId() != 0))
|
||||
SetDynamicFlag(UNIT_DYNFLAG_REFER_A_FRIEND);
|
||||
|
||||
setDeathState(ALIVE);
|
||||
setDeathState(DeathState::Alive);
|
||||
SetMovement(MOVE_LAND_WALK);
|
||||
SetMovement(MOVE_UNROOT);
|
||||
SetWaterWalking(false);
|
||||
@@ -4465,7 +4467,7 @@ void Player::KillPlayer()
|
||||
|
||||
StopMirrorTimers(); //disable timers(bars)
|
||||
|
||||
setDeathState(CORPSE);
|
||||
setDeathState(DeathState::Corpse);
|
||||
//SetUnitFlag(UNIT_FLAG_NOT_IN_PVP);
|
||||
|
||||
ReplaceAllDynamicFlags(UNIT_DYNFLAG_NONE);
|
||||
@@ -4481,6 +4483,7 @@ void Player::KillPlayer()
|
||||
if (corpseReclaimDelay >= 0)
|
||||
SendCorpseReclaimDelay(corpseReclaimDelay);
|
||||
|
||||
sScriptMgr->OnPlayerJustDied(this);
|
||||
// don't create corpse at this moment, player might be falling
|
||||
|
||||
// update visibility
|
||||
@@ -5577,11 +5580,14 @@ void Player::SaveRecallPosition()
|
||||
m_recallO = GetOrientation();
|
||||
}
|
||||
|
||||
void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, Player const* skipped_rcvr) const
|
||||
void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin, Player const* skipped_rcvr) const
|
||||
{
|
||||
if (self)
|
||||
GetSession()->SendPacket(data);
|
||||
|
||||
dist += GetObjectSize();
|
||||
if (includeMargin)
|
||||
dist += VISIBILITY_COMPENSATION; // pussywizard: to ensure everyone receives all important packets
|
||||
Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr);
|
||||
Cell::VisitWorldObjects(this, notifier, dist);
|
||||
}
|
||||
@@ -11315,7 +11321,7 @@ WorldLocation Player::GetStartPosition() const
|
||||
return WorldLocation(mapId, info->positionX, info->positionY, info->positionZ, 0);
|
||||
}
|
||||
|
||||
bool Player::HaveAtClient(Object const* u) const
|
||||
bool Player::HaveAtClient(WorldObject const* u) const
|
||||
{
|
||||
if (u == this)
|
||||
{
|
||||
@@ -13089,11 +13095,14 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
|
||||
UpdateVisibilityOf(target);
|
||||
|
||||
if (target->isType(TYPEMASK_UNIT) && !GetVehicle())
|
||||
static_cast<Unit*>(target)->AddPlayerToVision(this);
|
||||
((Unit*)target)->AddPlayerToVision(this);
|
||||
SetSeer(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
//must immediately set seer back otherwise may crash
|
||||
m_seer = this;
|
||||
|
||||
LOG_DEBUG("maps", "Player::CreateViewpoint: Player {} remove seer", GetName());
|
||||
|
||||
if (!RemoveGuidValue(PLAYER_FARSIGHT, target->GetGUID()))
|
||||
@@ -15173,6 +15182,8 @@ void Player::ActivateSpec(uint8 spec)
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
|
||||
sScriptMgr->OnAfterSpecSlotChanged(this, GetActiveSpec());
|
||||
}
|
||||
|
||||
void Player::LoadActions(PreparedQueryResult result)
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
#include "PlayerTaxi.h"
|
||||
#include "QuestDef.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "TradeData.h"
|
||||
#include "Unit.h"
|
||||
#include "WorldSession.h"
|
||||
@@ -1986,10 +1986,10 @@ public:
|
||||
|
||||
void ProcessTerrainStatusUpdate() override;
|
||||
|
||||
void SendMessageToSet(WorldPacket const* data, bool self) const override { SendMessageToSetInRange(data, GetVisibilityRange(), self); } // pussywizard!
|
||||
void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, Player const* skipped_rcvr = nullptr) const override; // pussywizard!
|
||||
void SendMessageToSetInRange_OwnTeam(WorldPacket const* data, float dist, bool self) const; // pussywizard!
|
||||
void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const override { SendMessageToSetInRange(data, GetVisibilityRange(), skipped_rcvr != this, skipped_rcvr); } // pussywizard!
|
||||
void SendMessageToSet(WorldPacket const* data, bool self) const override { SendMessageToSetInRange(data, GetVisibilityRange(), self, true); } // pussywizard!
|
||||
void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const override; // pussywizard!
|
||||
void SendMessageToSetInRange_OwnTeam(WorldPacket const* data, float dist, bool self) const; // pussywizard! param includeMargin not needed here
|
||||
void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const override { SendMessageToSetInRange(data, GetVisibilityRange(), skipped_rcvr != this, true, skipped_rcvr); } // pussywizard!
|
||||
|
||||
void SendTeleportAckPacket();
|
||||
|
||||
@@ -2342,8 +2342,9 @@ public:
|
||||
|
||||
// currently visible objects at player client
|
||||
GuidUnorderedSet m_clientGUIDs;
|
||||
std::vector<Unit*> m_newVisible; // pussywizard
|
||||
|
||||
[[nodiscard]] bool HaveAtClient(Object const* u) const;
|
||||
[[nodiscard]] bool HaveAtClient(WorldObject const* u) const;
|
||||
[[nodiscard]] bool HaveAtClient(ObjectGuid guid) const;
|
||||
|
||||
[[nodiscard]] bool IsNeverVisible() const override;
|
||||
@@ -2351,13 +2352,13 @@ public:
|
||||
bool IsVisibleGloballyFor(Player const* player) const;
|
||||
|
||||
void GetInitialVisiblePackets(Unit* target);
|
||||
void UpdateObjectVisibility(bool forced = true) override;
|
||||
void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false) override;
|
||||
void UpdateVisibilityForPlayer(bool mapChange = false);
|
||||
void UpdateVisibilityOf(WorldObject* target);
|
||||
void UpdateTriggerVisibility();
|
||||
|
||||
template<class T>
|
||||
void UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
void UpdateVisibilityOf(T* target, UpdateData& data, std::vector<Unit*>& visibleNow);
|
||||
|
||||
uint8 m_forced_speed_changes[MAX_MOVE_TYPE];
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "CreatureAI.h"
|
||||
#include "DisableMgr.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "GameTime.h"
|
||||
#include "GitRevision.h"
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Transport.h"
|
||||
#include "UpdateData.h"
|
||||
#include "UpdateFieldFlags.h"
|
||||
@@ -70,8 +72,6 @@
|
||||
#include "Weather.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
|
||||
/// @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
|
||||
@@ -5454,7 +5454,7 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons
|
||||
// add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura)
|
||||
if (HasPlayerFlag(PLAYER_FLAGS_GHOST))
|
||||
{
|
||||
m_deathState = DEAD;
|
||||
m_deathState = DeathState::Dead;
|
||||
AddUnitState(UNIT_STATE_ISOLATED);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
|
||||
void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint8 level)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AchievementMgr.h"
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "CellImpl.h"
|
||||
#include "Channel.h"
|
||||
@@ -35,6 +36,7 @@
|
||||
#include "SpellMgr.h"
|
||||
#include "UpdateFieldFlags.h"
|
||||
#include "Vehicle.h"
|
||||
#include "Weather.h"
|
||||
#include "WeatherMgr.h"
|
||||
#include "WorldStatePackets.h"
|
||||
|
||||
@@ -311,7 +313,7 @@ void Player::Update(uint32 p_time)
|
||||
RegenerateAll();
|
||||
}
|
||||
|
||||
if (m_deathState == JUST_DIED)
|
||||
if (m_deathState == DeathState::JustDied)
|
||||
KillPlayer();
|
||||
|
||||
if (m_nextSave)
|
||||
@@ -413,6 +415,13 @@ void Player::Update(uint32 p_time)
|
||||
TeleportTo(teleportStore_dest, teleportStore_options);
|
||||
}
|
||||
|
||||
if (!IsBeingTeleported() && bRequestForcedVisibilityUpdate)
|
||||
{
|
||||
bRequestForcedVisibilityUpdate = false;
|
||||
UpdateObjectVisibility(true, true);
|
||||
m_delayed_unit_relocation_timer = 0;
|
||||
RemoveFromNotify(NOTIFY_VISIBILITY_CHANGED);
|
||||
}
|
||||
sScriptMgr->OnAfterPlayerUpdate(this, p_time);
|
||||
}
|
||||
|
||||
@@ -789,8 +798,8 @@ bool Player::UpdateCraftSkill(uint32 spellid)
|
||||
GetPureSkillValue(_spell_idx->second->SkillLine);
|
||||
|
||||
// Alchemy Discoveries here
|
||||
SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spellid);
|
||||
if (spellEntry && spellEntry->Mechanic == MECHANIC_DISCOVERY)
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid);
|
||||
if (spellInfo && spellInfo->Mechanic == MECHANIC_DISCOVERY)
|
||||
{
|
||||
if (uint32 discoveredSpell = GetSkillDiscoverySpell(
|
||||
_spell_idx->second->SkillLine, spellid, this))
|
||||
@@ -1523,11 +1532,17 @@ void Player::UpdatePotionCooldown(Spell* spell)
|
||||
SetLastPotionId(0);
|
||||
}
|
||||
|
||||
template void Player::UpdateVisibilityOf(Player* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Creature* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(DynamicObject* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Player* target, UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Creature* target, UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(DynamicObject* target,
|
||||
UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow);
|
||||
|
||||
void Player::UpdateVisibilityForPlayer(bool mapChange)
|
||||
{
|
||||
@@ -1538,13 +1553,23 @@ void Player::UpdateVisibilityForPlayer(bool mapChange)
|
||||
m_seer = this;
|
||||
}
|
||||
|
||||
// updates visibility of all objects around point of view for current player
|
||||
Acore::VisibleNotifier notifier(*this);
|
||||
Cell::VisitAllObjects(m_seer, notifier, GetSightRange());
|
||||
notifier.SendToSelf(); // send gathered data
|
||||
Acore::VisibleNotifier notifierNoLarge(
|
||||
*this, mapChange,
|
||||
false); // visit only objects which are not large; default distance
|
||||
Cell::VisitAllObjects(m_seer, notifierNoLarge,
|
||||
GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
|
||||
notifierNoLarge.SendToSelf();
|
||||
|
||||
Acore::VisibleNotifier notifierLarge(
|
||||
*this, mapChange, true); // visit only large objects; maximum distance
|
||||
Cell::VisitAllObjects(m_seer, notifierLarge, GetSightRange());
|
||||
notifierLarge.SendToSelf();
|
||||
|
||||
if (mapChange)
|
||||
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
|
||||
}
|
||||
|
||||
void Player::UpdateObjectVisibility(bool forced)
|
||||
void Player::UpdateObjectVisibility(bool forced, bool fromUpdate)
|
||||
{
|
||||
// Prevent updating visibility if player is not in world (example: LoadFromDB sets drunkstate which updates invisibility while player is not in map)
|
||||
if (!IsInWorld())
|
||||
@@ -1554,19 +1579,26 @@ void Player::UpdateObjectVisibility(bool forced)
|
||||
AddToNotify(NOTIFY_VISIBILITY_CHANGED);
|
||||
else if (!isBeingLoaded())
|
||||
{
|
||||
if (!fromUpdate) // pussywizard:
|
||||
{
|
||||
bRequestForcedVisibilityUpdate = true;
|
||||
return;
|
||||
}
|
||||
Unit::UpdateObjectVisibility(true);
|
||||
UpdateVisibilityForPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, T* target, std::set<Unit*>& /*v*/)
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, T* target,
|
||||
std::vector<Unit*>& /*v*/)
|
||||
{
|
||||
s64.insert(target->GetGUID());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, GameObject* target, std::set<Unit*>& /*v*/)
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, GameObject* target,
|
||||
std::vector<Unit*>& /*v*/)
|
||||
{
|
||||
// @HACK: This is to prevent objects like deeprun tram from disappearing
|
||||
// when player moves far from its spawn point while riding it
|
||||
@@ -1575,17 +1607,19 @@ inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, GameObject* target,
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Creature* target, std::set<Unit*>& v)
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Creature* target,
|
||||
std::vector<Unit*>& v)
|
||||
{
|
||||
s64.insert(target->GetGUID());
|
||||
v.insert(target);
|
||||
v.push_back(target);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Player* target, std::set<Unit*>& v)
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Player* target,
|
||||
std::vector<Unit*>& v)
|
||||
{
|
||||
s64.insert(target->GetGUID());
|
||||
v.insert(target);
|
||||
v.push_back(target);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -1601,7 +1635,8 @@ inline void BeforeVisibilityDestroy<Creature>(Creature* t, Player* p)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow)
|
||||
void Player::UpdateVisibilityOf(T* target, UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow)
|
||||
{
|
||||
if (HaveAtClient(target))
|
||||
{
|
||||
|
||||
@@ -220,7 +220,7 @@ void SocialMgr::GetFriendInfo(Player* player, ObjectGuid friendGUID, FriendInfo&
|
||||
friendInfo.Class = 0;
|
||||
|
||||
Player* pFriend = ObjectAccessor::FindConnectedPlayer(friendGUID);
|
||||
if (!pFriend || AccountMgr::IsGMAccount(pFriend->GetSession()->GetSecurity()))
|
||||
if (!pFriend || pFriend->GetSession()->IsGMAccount())
|
||||
return;
|
||||
|
||||
TeamId teamId = player->GetTeamId();
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "World.h"
|
||||
#include "WorldModel.h"
|
||||
|
||||
MotionTransport::MotionTransport() : Transport(), _transportInfo(nullptr), _isMoving(true), _pendingStop(false), _triggeredArrivalEvent(false), _triggeredDepartureEvent(false), _delayedTeleport(false)
|
||||
MotionTransport::MotionTransport() : Transport(), _transportInfo(nullptr), _isMoving(true), _pendingStop(false), _triggeredArrivalEvent(false), _triggeredDepartureEvent(false), _passengersLoaded(false), _delayedTeleport(false)
|
||||
{
|
||||
m_updateFlag = UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION;
|
||||
}
|
||||
@@ -230,14 +230,8 @@ void MotionTransport::Update(uint32 diff)
|
||||
3. transport moves from active to inactive grid
|
||||
4. the grid that transport is currently in unloads
|
||||
*/
|
||||
bool gridActive = GetMap()->IsGridLoaded(GetPositionX(), GetPositionY());
|
||||
|
||||
if (_staticPassengers.empty() && gridActive) // 2.
|
||||
if (_staticPassengers.empty() && GetMap()->IsGridLoaded(GetPositionX(), GetPositionY())) // 2.
|
||||
LoadStaticPassengers();
|
||||
else if (!_staticPassengers.empty() && !gridActive)
|
||||
// 4. - if transports stopped on grid edge, some passengers can remain in active grids
|
||||
// unload all static passengers otherwise passengers won't load correctly when the grid that transport is currently in becomes active
|
||||
UnloadStaticPassengers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,27 +248,18 @@ void MotionTransport::DelayedUpdate(uint32 /*diff*/)
|
||||
|
||||
void MotionTransport::UpdatePosition(float x, float y, float z, float o)
|
||||
{
|
||||
bool newActive = GetMap()->IsGridLoaded(x, y);
|
||||
Cell oldCell(GetPositionX(), GetPositionY());
|
||||
if (!GetMap()->IsGridLoaded(x, y)) // pussywizard: should not happen, but just in case
|
||||
GetMap()->LoadGrid(x, y);
|
||||
|
||||
Relocate(x, y, z, o);
|
||||
UpdateModelPosition();
|
||||
|
||||
UpdatePassengerPositions(_passengers);
|
||||
|
||||
/* There are four possible scenarios that trigger loading/unloading passengers:
|
||||
1. transport moves from inactive to active grid
|
||||
2. the grid that transport is currently in becomes active
|
||||
3. transport moves from active to inactive grid
|
||||
4. the grid that transport is currently in unloads
|
||||
*/
|
||||
if (_staticPassengers.empty() && newActive) // 1.
|
||||
if (_staticPassengers.empty())
|
||||
LoadStaticPassengers();
|
||||
else if (!_staticPassengers.empty() && !newActive && oldCell.DiffGrid(Cell(GetPositionX(), GetPositionY()))) // 3.
|
||||
UnloadStaticPassengers();
|
||||
else
|
||||
UpdatePassengerPositions(_staticPassengers);
|
||||
// 4. is handed by grid unload
|
||||
}
|
||||
|
||||
void MotionTransport::AddPassenger(WorldObject* passenger, bool withAll)
|
||||
@@ -321,7 +306,8 @@ void MotionTransport::RemovePassenger(WorldObject* passenger, bool withAll)
|
||||
{
|
||||
passenger->SetTransport(nullptr);
|
||||
passenger->m_movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
|
||||
passenger->m_movementInfo.transport.Reset();
|
||||
passenger->m_movementInfo.transport.guid.Clear();
|
||||
passenger->m_movementInfo.transport.pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
if (passenger->ToUnit())
|
||||
{
|
||||
passenger->ToUnit()->ClearUnitState(UNIT_STATE_IGNORE_PATHFINDING);
|
||||
@@ -421,6 +407,9 @@ GameObject* MotionTransport::CreateGOPassenger(ObjectGuid::LowType guid, GameObj
|
||||
|
||||
void MotionTransport::LoadStaticPassengers()
|
||||
{
|
||||
if (PassengersLoaded())
|
||||
return;
|
||||
SetPassengersLoaded(true);
|
||||
if (uint32 mapId = GetGOInfo()->moTransport.mapID)
|
||||
{
|
||||
CellObjectGuidsMap const& cells = sObjectMgr->GetMapObjectGuids(mapId, GetMap()->GetSpawnMode());
|
||||
@@ -442,6 +431,7 @@ void MotionTransport::LoadStaticPassengers()
|
||||
|
||||
void MotionTransport::UnloadStaticPassengers()
|
||||
{
|
||||
SetPassengersLoaded(false);
|
||||
while (!_staticPassengers.empty())
|
||||
{
|
||||
WorldObject* obj = *_staticPassengers.begin();
|
||||
@@ -552,19 +542,11 @@ void MotionTransport::DelayedTeleportTransport()
|
||||
_delayedTeleport = false;
|
||||
|
||||
uint32 newMapId = _nextFrame->Node->mapid;
|
||||
Map* newMap = sMapMgr->CreateBaseMap(newMapId);
|
||||
GetMap()->RemoveFromMap<MotionTransport>(this, false);
|
||||
|
||||
float x = _nextFrame->Node->x,
|
||||
y = _nextFrame->Node->y,
|
||||
z = _nextFrame->Node->z,
|
||||
o = _nextFrame->InitialOrientation;
|
||||
|
||||
if (!newMap->IsGridLoaded(x, y) && !_passengers.empty())
|
||||
newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map
|
||||
|
||||
SetMap(newMap);
|
||||
|
||||
PassengerSet _passengersCopy = _passengers;
|
||||
for (PassengerSet::iterator itr = _passengersCopy.begin(); itr != _passengersCopy.end(); )
|
||||
{
|
||||
@@ -610,8 +592,15 @@ void MotionTransport::DelayedTeleportTransport()
|
||||
}
|
||||
}
|
||||
|
||||
Map* newMap = sMapMgr->CreateBaseMap(newMapId);
|
||||
GetMap()->RemoveFromMap<MotionTransport>(this, false);
|
||||
newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map
|
||||
SetMap(newMap);
|
||||
|
||||
Relocate(x, y, z, o);
|
||||
GetMap()->AddToMap<MotionTransport>(this);
|
||||
|
||||
LoadStaticPassengers();
|
||||
}
|
||||
|
||||
void MotionTransport::UpdatePassengerPositions(PassengerSet& passengers)
|
||||
@@ -642,7 +631,7 @@ void MotionTransport::UpdatePassengerPositions(PassengerSet& passengers)
|
||||
case TYPEID_UNIT:
|
||||
{
|
||||
Creature* creature = passenger->ToCreature();
|
||||
GetMap()->CreatureRelocation(creature, x, y, z, o, false);
|
||||
GetMap()->CreatureRelocation(creature, x, y, z, o);
|
||||
|
||||
creature->GetTransportHomePosition(x, y, z, o);
|
||||
CalculatePassengerPosition(x, y, z, &o);
|
||||
@@ -654,7 +643,7 @@ void MotionTransport::UpdatePassengerPositions(PassengerSet& passengers)
|
||||
GetMap()->PlayerRelocation(passenger->ToPlayer(), x, y, z, o);
|
||||
break;
|
||||
case TYPEID_GAMEOBJECT:
|
||||
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o, false);
|
||||
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o);
|
||||
break;
|
||||
case TYPEID_DYNAMICOBJECT:
|
||||
GetMap()->DynamicObjectRelocation(passenger->ToDynObject(), x, y, z, o);
|
||||
@@ -791,6 +780,7 @@ bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* m
|
||||
LastUsedScriptID = GetGOInfo()->ScriptId;
|
||||
AIM_Initialize();
|
||||
|
||||
this->setActive(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -925,8 +915,7 @@ void StaticTransport::UpdatePosition(float x, float y, float z, float o)
|
||||
if (!GetMap()->IsGridLoaded(x, y)) // pussywizard: should not happen, but just in case
|
||||
GetMap()->LoadGrid(x, y);
|
||||
|
||||
Relocate(x, y, z, o);
|
||||
UpdateModelPosition();
|
||||
GetMap()->GameObjectRelocation(this, x, y, z, o); // this also relocates the model
|
||||
UpdatePassengerPositions();
|
||||
}
|
||||
|
||||
@@ -953,14 +942,17 @@ void StaticTransport::UpdatePassengerPositions()
|
||||
switch (passenger->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
GetMap()->CreatureRelocation(passenger->ToCreature(), x, y, z, o, false);
|
||||
GetMap()->CreatureRelocation(passenger->ToCreature(), x, y, z, o);
|
||||
break;
|
||||
case TYPEID_PLAYER:
|
||||
if (passenger->IsInWorld())
|
||||
{
|
||||
GetMap()->PlayerRelocation(passenger->ToPlayer(), x, y, z, o);
|
||||
passenger->ToPlayer()->SetFallInformation(GameTime::GetGameTime().count(), z);
|
||||
}
|
||||
break;
|
||||
case TYPEID_GAMEOBJECT:
|
||||
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o, false);
|
||||
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o);
|
||||
break;
|
||||
case TYPEID_DYNAMICOBJECT:
|
||||
GetMap()->DynamicObjectRelocation(passenger->ToDynObject(), x, y, z, o);
|
||||
@@ -1009,7 +1001,8 @@ void StaticTransport::RemovePassenger(WorldObject* passenger, bool withAll)
|
||||
{
|
||||
passenger->SetTransport(nullptr);
|
||||
passenger->m_movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
|
||||
passenger->m_movementInfo.transport.Reset();
|
||||
passenger->m_movementInfo.transport.guid.Clear();
|
||||
passenger->m_movementInfo.transport.pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ public:
|
||||
PassengerSet const& GetStaticPassengers() const { return _staticPassengers; }
|
||||
void UnloadStaticPassengers();
|
||||
void UnloadNonStaticPassengers();
|
||||
void SetPassengersLoaded(bool loaded) { _passengersLoaded = loaded; }
|
||||
bool PassengersLoaded() const { return _passengersLoaded; }
|
||||
|
||||
KeyFrameVec const& GetKeyFrames() const { return _transportInfo->keyFrames; }
|
||||
void EnableMovement(bool enabled);
|
||||
@@ -102,6 +104,7 @@ private:
|
||||
|
||||
PassengerSet _staticPassengers;
|
||||
mutable std::mutex Lock;
|
||||
bool _passengersLoaded;
|
||||
bool _delayedTeleport;
|
||||
};
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "Config.h"
|
||||
#include "Creature.h"
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "CreatureGroups.h"
|
||||
#include "DisableMgr.h"
|
||||
#include "DynamicVisibility.h"
|
||||
#include "Formulas.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "GameTime.h"
|
||||
@@ -43,23 +44,24 @@
|
||||
#include "MoveSpline.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "MovementPacketBuilder.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "OutdoorPvP.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Pet.h"
|
||||
#include "PetAI.h"
|
||||
#include "Player.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "Spell.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "StringConvert.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Totem.h"
|
||||
#include "TotemAI.h"
|
||||
#include "Transport.h"
|
||||
@@ -68,8 +70,6 @@
|
||||
#include "Vehicle.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
#include <math.h>
|
||||
|
||||
float baseMoveSpeed[MAX_MOVE_TYPE] =
|
||||
@@ -247,7 +247,7 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
|
||||
m_rootTimes = 0;
|
||||
|
||||
m_state = 0;
|
||||
m_deathState = ALIVE;
|
||||
m_deathState = DeathState::Alive;
|
||||
|
||||
for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
|
||||
m_currentSpells[i] = nullptr;
|
||||
@@ -317,6 +317,12 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
|
||||
|
||||
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
|
||||
|
||||
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
|
||||
m_last_notify_mstime = 0;
|
||||
m_delayed_unit_relocation_timer = 0;
|
||||
m_delayed_unit_ai_notify_timer = 0;
|
||||
bRequestForcedVisibilityUpdate = false;
|
||||
|
||||
m_applyResilience = false;
|
||||
_instantCast = false;
|
||||
|
||||
@@ -405,6 +411,32 @@ void Unit::Update(uint32 p_time)
|
||||
if (!IsInWorld())
|
||||
return;
|
||||
|
||||
// pussywizard:
|
||||
if (GetTypeId() != TYPEID_PLAYER || (!ToPlayer()->IsBeingTeleported() && !bRequestForcedVisibilityUpdate))
|
||||
{
|
||||
if (m_delayed_unit_relocation_timer)
|
||||
{
|
||||
if (m_delayed_unit_relocation_timer <= p_time)
|
||||
{
|
||||
m_delayed_unit_relocation_timer = 0;
|
||||
//ExecuteDelayedUnitRelocationEvent();
|
||||
FindMap()->i_objectsForDelayedVisibility.insert(this);
|
||||
}
|
||||
else
|
||||
m_delayed_unit_relocation_timer -= p_time;
|
||||
}
|
||||
if (m_delayed_unit_ai_notify_timer)
|
||||
{
|
||||
if (m_delayed_unit_ai_notify_timer <= p_time)
|
||||
{
|
||||
m_delayed_unit_ai_notify_timer = 0;
|
||||
ExecuteDelayedUnitAINotifyEvent();
|
||||
}
|
||||
else
|
||||
m_delayed_unit_ai_notify_timer -= p_time;
|
||||
}
|
||||
}
|
||||
|
||||
_UpdateSpells( p_time );
|
||||
|
||||
if (CanHaveThreatList() && GetThreatMgr().isNeedUpdateToClient(p_time))
|
||||
@@ -568,27 +600,14 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
|
||||
SplineHandler handler(this);
|
||||
movespline->updateState(t_diff, handler);
|
||||
// Xinef: Spline was cleared by StopMoving, return
|
||||
if (!movespline->Initialized()) {
|
||||
if (!movespline->Initialized())
|
||||
{
|
||||
DisableSpline();
|
||||
return;
|
||||
}
|
||||
|
||||
bool arrived = movespline->Finalized();
|
||||
|
||||
if (movespline->isCyclic())
|
||||
{
|
||||
m_splineSyncTimer.Update(t_diff);
|
||||
if (m_splineSyncTimer.Passed())
|
||||
{
|
||||
m_splineSyncTimer.Reset(5000); // Retail value, do not change
|
||||
|
||||
WorldPacket data(SMSG_FLIGHT_SPLINE_SYNC, 4 + GetPackGUID().size());
|
||||
Movement::PacketBuilder::WriteSplineSync(*movespline, data);
|
||||
data.appendPackGUID(GetGUID());
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (arrived)
|
||||
{
|
||||
DisableSpline();
|
||||
@@ -597,11 +616,17 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, movespline->GetAnimationType());
|
||||
}
|
||||
|
||||
// pussywizard: update always! not every 400ms, because movement generators need the actual position
|
||||
//m_movesplineTimer.Update(t_diff);
|
||||
//if (m_movesplineTimer.Passed() || arrived)
|
||||
UpdateSplinePosition();
|
||||
}
|
||||
|
||||
void Unit::UpdateSplinePosition()
|
||||
{
|
||||
//static uint32 const positionUpdateDelay = 400;
|
||||
|
||||
//m_movesplineTimer.Reset(positionUpdateDelay);
|
||||
Movement::Location loc = movespline->ComputePosition();
|
||||
|
||||
if (movespline->onTransport)
|
||||
@@ -614,14 +639,16 @@ void Unit::UpdateSplinePosition()
|
||||
|
||||
if (TransportBase* transport = GetDirectTransport())
|
||||
transport->CalculatePassengerPosition(loc.x, loc.y, loc.z, &loc.orientation);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasUnitState(UNIT_STATE_CANNOT_TURN))
|
||||
loc.orientation = GetOrientation();
|
||||
// Xinef: if we had spline running update orientation along with position
|
||||
//if (HasUnitState(UNIT_STATE_CANNOT_TURN))
|
||||
// loc.orientation = GetOrientation();
|
||||
|
||||
UpdatePosition(loc.x, loc.y, loc.z, loc.orientation);
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
UpdatePosition(loc.x, loc.y, loc.z, loc.orientation);
|
||||
else
|
||||
ToCreature()->SetPosition(loc.x, loc.y, loc.z, loc.orientation);
|
||||
}
|
||||
|
||||
void Unit::DisableSpline()
|
||||
@@ -1281,6 +1308,11 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
|
||||
// Script Hook For CalculateSpellDamageTaken -- Allow scripts to change the Damage post class mitigation calculations
|
||||
sScriptMgr->ModifySpellDamageTaken(damageInfo->target, damageInfo->attacker, damage, spellInfo);
|
||||
|
||||
if (victim->GetAI())
|
||||
{
|
||||
victim->GetAI()->OnCalculateSpellDamageReceived(damage, this);
|
||||
}
|
||||
|
||||
int32 cleanDamage = 0;
|
||||
if (Unit::IsDamageReducedByArmor(damageSchoolMask, spellInfo))
|
||||
{
|
||||
@@ -1531,6 +1563,11 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon
|
||||
// Script Hook For CalculateMeleeDamage -- Allow scripts to change the Damage pre class mitigation calculations
|
||||
sScriptMgr->ModifyMeleeDamage(damageInfo->target, damageInfo->attacker, damage);
|
||||
|
||||
if (victim->GetAI())
|
||||
{
|
||||
victim->GetAI()->OnCalculateMeleeDamageReceived(damage, this);
|
||||
}
|
||||
|
||||
// Calculate armor reduction
|
||||
if (IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->damages[i].damageSchoolMask)))
|
||||
{
|
||||
@@ -4535,7 +4572,7 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMo
|
||||
if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE && IsTotem() && GetGUID() == aura->GetCasterGUID())
|
||||
{
|
||||
if (ToTotem()->GetSpell() == aura->GetId() && ToTotem()->GetTotemType() == TOTEM_PASSIVE)
|
||||
ToTotem()->setDeathState(JUST_DIED);
|
||||
ToTotem()->setDeathState(DeathState::JustDied);
|
||||
}
|
||||
|
||||
// Remove aurastates only if were not found
|
||||
@@ -5502,7 +5539,7 @@ Aura* Unit::GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID, ObjectGu
|
||||
return aurApp ? aurApp->GetBase() : nullptr;
|
||||
}
|
||||
|
||||
void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList)
|
||||
void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList, SpellInfo const* dispelSpell)
|
||||
{
|
||||
// we should not be able to dispel diseases if the target is affected by unholy blight
|
||||
if (dispelMask & (1 << DISPEL_DISEASE) && HasAura(50536))
|
||||
@@ -5548,6 +5585,12 @@ void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelCharges
|
||||
continue;
|
||||
}
|
||||
|
||||
// Banish should only be dispelled by Mass Dispel
|
||||
if (aura->GetSpellInfo()->Mechanic == MECHANIC_BANISH && !dispelSpell->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// The charges / stack amounts don't count towards the total number of auras that can be dispelled.
|
||||
// Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
|
||||
// Polymorph instead of 1 / (5 + 1) -> 16%.
|
||||
@@ -9592,7 +9635,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
|
||||
// Cast positive spell on enemy target
|
||||
case 7099: // Curse of Mending
|
||||
case 39703: // Curse of Mending
|
||||
case 29494: // Temptation
|
||||
case 20233: // Improved Lay on Hands (cast on target)
|
||||
{
|
||||
target = victim;
|
||||
@@ -14514,7 +14556,7 @@ void Unit::setDeathState(DeathState s, bool despawn)
|
||||
// death state needs to be updated before RemoveAllAurasOnDeath() calls HandleChannelDeathItem(..) so that
|
||||
// it can be used to check creation of death items (such as soul shards).
|
||||
|
||||
if (s != ALIVE && s != JUST_RESPAWNED)
|
||||
if (s != DeathState::Alive && s != DeathState::JustRespawned)
|
||||
{
|
||||
CombatStop();
|
||||
GetThreatMgr().ClearAllThreat();
|
||||
@@ -14529,7 +14571,7 @@ void Unit::setDeathState(DeathState s, bool despawn)
|
||||
RemoveAllAurasOnDeath();
|
||||
}
|
||||
|
||||
if (s == JUST_DIED)
|
||||
if (s == DeathState::JustDied)
|
||||
{
|
||||
// remove aurastates allowing special moves
|
||||
ClearAllReactives();
|
||||
@@ -14558,7 +14600,7 @@ void Unit::setDeathState(DeathState s, bool despawn)
|
||||
if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : (ZoneScript*)GetInstanceScript())
|
||||
zoneScript->OnUnitDeath(this);
|
||||
}
|
||||
else if (s == JUST_RESPAWNED)
|
||||
else if (s == DeathState::JustRespawned)
|
||||
{
|
||||
RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground)
|
||||
}
|
||||
@@ -15437,9 +15479,9 @@ void Unit::SetLevel(uint8 lvl, bool showLevelChange)
|
||||
|
||||
void Unit::SetHealth(uint32 val)
|
||||
{
|
||||
if (getDeathState() == JUST_DIED)
|
||||
if (getDeathState() == DeathState::JustDied)
|
||||
val = 0;
|
||||
else if (GetTypeId() == TYPEID_PLAYER && getDeathState() == DEAD)
|
||||
else if (GetTypeId() == TYPEID_PLAYER && getDeathState() == DeathState::Dead)
|
||||
val = 1;
|
||||
else
|
||||
{
|
||||
@@ -15731,9 +15773,15 @@ void Unit::CleanupBeforeRemoveFromMap(bool finalCleanup)
|
||||
|
||||
void Unit::CleanupsBeforeDelete(bool finalCleanup)
|
||||
{
|
||||
CleanupBeforeRemoveFromMap(finalCleanup);
|
||||
if (GetTransport())
|
||||
{
|
||||
GetTransport()->RemovePassenger(this);
|
||||
SetTransport(nullptr);
|
||||
m_movementInfo.transport.Reset();
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
}
|
||||
|
||||
WorldObject::CleanupsBeforeDelete(finalCleanup);
|
||||
CleanupBeforeRemoveFromMap(finalCleanup);
|
||||
}
|
||||
|
||||
void Unit::UpdateCharmAI()
|
||||
@@ -17506,17 +17554,13 @@ void Unit::SetContestedPvP(Player* attackedPlayer, bool lookForNearContestedGuar
|
||||
player->AddUnitState(UNIT_STATE_ATTACK_PLAYER);
|
||||
player->SetPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP);
|
||||
// call MoveInLineOfSight for nearby contested guards
|
||||
Acore::AIRelocationNotifier notifier(*this);
|
||||
Cell::VisitWorldObjects(this, notifier, GetVisibilityRange());
|
||||
AddToNotify(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
for (Unit* unit : m_Controlled)
|
||||
if (!HasUnitState(UNIT_STATE_ATTACK_PLAYER))
|
||||
{
|
||||
if (!unit->HasUnitState(UNIT_STATE_ATTACK_PLAYER))
|
||||
{
|
||||
unit->AddUnitState(UNIT_STATE_ATTACK_PLAYER);
|
||||
Acore::AIRelocationNotifier notifier(*unit);
|
||||
Cell::VisitWorldObjects(this, notifier, GetVisibilityRange());
|
||||
}
|
||||
AddUnitState(UNIT_STATE_ATTACK_PLAYER);
|
||||
// call MoveInLineOfSight for nearby contested guards
|
||||
AddToNotify(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18103,12 +18147,12 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp
|
||||
|
||||
if (!spiritOfRedemption)
|
||||
{
|
||||
LOG_DEBUG("entities.unit", "SET JUST_DIED");
|
||||
victim->setDeathState(JUST_DIED);
|
||||
LOG_DEBUG("entities.unit", "SET DeathState::JustDied");
|
||||
victim->setDeathState(DeathState::JustDied);
|
||||
}
|
||||
|
||||
// Inform pets (if any) when player kills target)
|
||||
// MUST come after victim->setDeathState(JUST_DIED); or pet next target
|
||||
// MUST come after victim->setDeathState(DeathState::JustDied); or pet next target
|
||||
// selection will get stuck on same target and break pet react state
|
||||
if (player)
|
||||
{
|
||||
@@ -18517,11 +18561,6 @@ void Unit::SetFeared(bool apply, Unit* fearedBy /*= nullptr*/, bool isFear /*= f
|
||||
{
|
||||
SetTarget();
|
||||
GetMotionMaster()->MoveFleeing(fearedBy, isFear ? 0 : sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_FLEE_DELAY));
|
||||
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -18554,11 +18593,6 @@ void Unit::SetConfused(bool apply)
|
||||
{
|
||||
SetTarget();
|
||||
GetMotionMaster()->MoveConfused();
|
||||
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -19377,7 +19411,7 @@ void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::UpdateObjectVisibility(bool forced)
|
||||
void Unit::UpdateObjectVisibility(bool forced, bool /*fromUpdate*/)
|
||||
{
|
||||
if (!forced)
|
||||
AddToNotify(NOTIFY_VISIBILITY_CHANGED);
|
||||
@@ -19385,7 +19419,8 @@ void Unit::UpdateObjectVisibility(bool forced)
|
||||
{
|
||||
WorldObject::UpdateObjectVisibility(true);
|
||||
Acore::AIRelocationNotifier notifier(*this);
|
||||
Cell::VisitAllObjects(this, notifier, GetVisibilityRange());
|
||||
float radius = 60.0f;
|
||||
Cell::VisitAllObjects(this, notifier, radius);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19424,7 +19459,6 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
|
||||
if (player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || player->HasAuraType(SPELL_AURA_FLY))
|
||||
player->SetCanFly(true, true);
|
||||
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
|
||||
player->SetCanKnockback(true);
|
||||
}
|
||||
}
|
||||
@@ -19821,10 +19855,10 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
|
||||
Unit* target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_CLICKER) ? clicker : this;
|
||||
ObjectGuid origCasterGUID = (itr->second.castFlags & NPC_CLICK_CAST_ORIG_CASTER_OWNER) ? GetOwnerGUID() : clicker->GetGUID();
|
||||
|
||||
SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(itr->second.spellId);
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->second.spellId);
|
||||
|
||||
// xinef: dont allow players to enter vehicles on arena
|
||||
if (spellEntry->HasAura(SPELL_AURA_CONTROL_VEHICLE) && caster->GetTypeId() == TYPEID_PLAYER && caster->FindMap() && caster->FindMap()->IsBattleArena())
|
||||
if (spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) && caster->GetTypeId() == TYPEID_PLAYER && caster->FindMap() && caster->FindMap()->IsBattleArena())
|
||||
continue;
|
||||
|
||||
if (seatId > -1)
|
||||
@@ -19833,7 +19867,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
|
||||
bool valid = false;
|
||||
while (i < MAX_SPELL_EFFECTS)
|
||||
{
|
||||
if (spellEntry->Effects[i].ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE)
|
||||
if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE)
|
||||
{
|
||||
valid = true;
|
||||
break;
|
||||
@@ -19853,18 +19887,18 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
|
||||
{
|
||||
int32 bp0[MAX_SPELL_EFFECTS];
|
||||
for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
|
||||
bp0[j] = spellEntry->Effects[j].BasePoints;
|
||||
bp0[j] = spellInfo->Effects[j].BasePoints;
|
||||
|
||||
bp0[i] = seatId;
|
||||
Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, bp0, nullptr, origCasterGUID);
|
||||
Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, this, clicker, bp0, nullptr, origCasterGUID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsInMap(caster))
|
||||
caster->CastSpell(target, spellEntry, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, nullptr, nullptr, origCasterGUID);
|
||||
caster->CastSpell(target, spellInfo, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, nullptr, nullptr, origCasterGUID);
|
||||
else
|
||||
Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, nullptr, nullptr, origCasterGUID);
|
||||
Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, this, clicker, nullptr, nullptr, origCasterGUID);
|
||||
}
|
||||
|
||||
result = true;
|
||||
@@ -19883,7 +19917,6 @@ void Unit::EnterVehicle(Unit* base, int8 seatId)
|
||||
if (Player* player = ToPlayer())
|
||||
{
|
||||
sScriptMgr->AnticheatSetUnderACKmount(player);
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19926,7 +19959,6 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a
|
||||
return;
|
||||
|
||||
sScriptMgr->AnticheatSetUnderACKmount(player);
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
|
||||
|
||||
InterruptNonMeleeSpells(false);
|
||||
player->StopCastingCharm();
|
||||
@@ -19999,7 +20031,6 @@ void Unit::ExitVehicle(Position const* /*exitPosition*/)
|
||||
if (Player* player = ToPlayer())
|
||||
{
|
||||
sScriptMgr->AnticheatSetUnderACKmount(player);
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20073,7 +20104,6 @@ void Unit::_ExitVehicle(Position const* exitPosition)
|
||||
player->SetFallInformation(GameTime::GetGameTime().count(), GetPositionZ());
|
||||
|
||||
sScriptMgr->AnticheatSetUnderACKmount(player);
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
|
||||
}
|
||||
else if (HasUnitMovementFlag(MOVEMENTFLAG_ROOT))
|
||||
{
|
||||
@@ -20136,8 +20166,8 @@ void Unit::_ExitVehicle(Position const* exitPosition)
|
||||
if (HasUnitTypeMask(UNIT_MASK_ACCESSORY))
|
||||
{
|
||||
// Vehicle just died, we die too
|
||||
if (vehicleBase->getDeathState() == JUST_DIED)
|
||||
setDeathState(JUST_DIED);
|
||||
if (vehicleBase->getDeathState() == DeathState::JustDied)
|
||||
setDeathState(DeathState::JustDied);
|
||||
// If for other reason we as minion are exiting the vehicle (ejected, master dismounted) - unsummon
|
||||
else
|
||||
{
|
||||
@@ -20283,14 +20313,10 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel
|
||||
if (!Acore::IsValidMapCoord(x, y, z, orientation))
|
||||
return false;
|
||||
|
||||
// Check if angular distance changed
|
||||
bool const turn = G3D::fuzzyGt(M_PI - fabs(fabs(GetOrientation() - orientation) - M_PI), 0.0f);
|
||||
|
||||
// G3D::fuzzyEq won't help here, in some cases magnitudes differ by a little more than G3D::eps, but should be considered equal
|
||||
bool const relocated = (teleport ||
|
||||
std::fabs(GetPositionX() - x) > 0.001f ||
|
||||
std::fabs(GetPositionY() - y) > 0.001f ||
|
||||
std::fabs(GetPositionZ() - z) > 0.001f);
|
||||
float old_orientation = GetOrientation();
|
||||
float current_z = GetPositionZ();
|
||||
bool turn = (old_orientation != orientation);
|
||||
bool relocated = (teleport || GetPositionX() != x || GetPositionY() != y || current_z != z);
|
||||
|
||||
if (!GetVehicle())
|
||||
{
|
||||
@@ -20316,8 +20342,6 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel
|
||||
UpdateObjectVisibility(false);
|
||||
}
|
||||
|
||||
UpdatePositionData();
|
||||
|
||||
return (relocated || turn);
|
||||
}
|
||||
|
||||
@@ -20748,6 +20772,124 @@ bool ConflagrateAuraStateDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unit::ExecuteDelayedUnitRelocationEvent()
|
||||
{
|
||||
this->RemoveFromNotify(NOTIFY_VISIBILITY_CHANGED);
|
||||
if (!this->IsInWorld() || this->IsDuringRemoveFromWorld())
|
||||
return;
|
||||
|
||||
if (this->HasSharedVision())
|
||||
for (SharedVisionList::const_iterator itr = this->GetSharedVisionList().begin(); itr != this->GetSharedVisionList().end(); ++itr)
|
||||
if (Player* player = (*itr))
|
||||
{
|
||||
if (player->IsOnVehicle(this) || !player->IsInWorld() || player->IsDuringRemoveFromWorld()) // players on vehicles have their own event executed (due to passenger relocation)
|
||||
continue;
|
||||
WorldObject* viewPoint = player;
|
||||
if (player->m_seer && player->m_seer->IsInWorld())
|
||||
viewPoint = player->m_seer;
|
||||
if (!viewPoint->IsPositionValid() || !player->IsPositionValid())
|
||||
continue;
|
||||
|
||||
if (Unit* active = viewPoint->ToUnit())
|
||||
{
|
||||
//if (active->IsVehicle()) // always check original unit here, last notify position is not relocated
|
||||
// active = player;
|
||||
|
||||
float dx = active->m_last_notify_position.GetPositionX() - active->GetPositionX();
|
||||
float dy = active->m_last_notify_position.GetPositionY() - active->GetPositionY();
|
||||
float dz = active->m_last_notify_position.GetPositionZ() - active->GetPositionZ();
|
||||
float distsq = dx * dx + dy * dy + dz * dz;
|
||||
float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(active->FindMap()->GetEntry()->map_type);
|
||||
if (distsq < mindistsq)
|
||||
continue;
|
||||
|
||||
// this will be relocated below sharedvision!
|
||||
//active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ());
|
||||
}
|
||||
|
||||
Acore::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance
|
||||
Cell::VisitAllObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
|
||||
relocateNoLarge.SendToSelf();
|
||||
Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance
|
||||
Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
|
||||
relocateLarge.SendToSelf();
|
||||
}
|
||||
|
||||
if (Player* player = this->ToPlayer())
|
||||
{
|
||||
WorldObject* viewPoint = player;
|
||||
if (player->m_seer && player->m_seer->IsInWorld())
|
||||
viewPoint = player->m_seer;
|
||||
|
||||
if (viewPoint->GetMapId() != player->GetMapId() || !viewPoint->IsPositionValid() || !player->IsPositionValid())
|
||||
return;
|
||||
|
||||
if (Unit* active = viewPoint->ToUnit())
|
||||
{
|
||||
if (active->IsVehicle())
|
||||
active = player;
|
||||
|
||||
if (!player->GetFarSightDistance())
|
||||
{
|
||||
float dx = active->m_last_notify_position.GetPositionX() - active->GetPositionX();
|
||||
float dy = active->m_last_notify_position.GetPositionY() - active->GetPositionY();
|
||||
float dz = active->m_last_notify_position.GetPositionZ() - active->GetPositionZ();
|
||||
float distsq = dx * dx + dy * dy + dz * dz;
|
||||
|
||||
float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(active->FindMap()->GetEntry()->map_type);
|
||||
if (distsq < mindistsq)
|
||||
return;
|
||||
|
||||
active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ());
|
||||
}
|
||||
}
|
||||
|
||||
Acore::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance
|
||||
Cell::VisitAllObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
|
||||
relocateNoLarge.SendToSelf();
|
||||
|
||||
if (!player->GetFarSightDistance())
|
||||
{
|
||||
Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance
|
||||
Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
|
||||
relocateLarge.SendToSelf();
|
||||
}
|
||||
|
||||
this->AddToNotify(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
else if (Creature* unit = this->ToCreature())
|
||||
{
|
||||
if (!unit->IsPositionValid())
|
||||
return;
|
||||
|
||||
float dx = unit->m_last_notify_position.GetPositionX() - unit->GetPositionX();
|
||||
float dy = unit->m_last_notify_position.GetPositionY() - unit->GetPositionY();
|
||||
float dz = unit->m_last_notify_position.GetPositionZ() - unit->GetPositionZ();
|
||||
float distsq = dx * dx + dy * dy + dz * dz;
|
||||
float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(unit->FindMap()->GetEntry()->map_type);
|
||||
if (distsq < mindistsq)
|
||||
return;
|
||||
|
||||
unit->m_last_notify_position.Relocate(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ());
|
||||
|
||||
Acore::CreatureRelocationNotifier relocate(*unit);
|
||||
Cell::VisitAllObjects(unit, relocate, unit->GetVisibilityRange() + VISIBILITY_COMPENSATION);
|
||||
|
||||
this->AddToNotify(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::ExecuteDelayedUnitAINotifyEvent()
|
||||
{
|
||||
this->RemoveFromNotify(NOTIFY_AI_RELOCATION);
|
||||
if (!this->IsInWorld() || this->IsDuringRemoveFromWorld())
|
||||
return;
|
||||
|
||||
Acore::AIRelocationNotifier notifier(*this);
|
||||
float radius = 60.0f;
|
||||
Cell::VisitAllObjects(this, notifier, radius);
|
||||
}
|
||||
|
||||
void Unit::SetInFront(WorldObject const* target)
|
||||
{
|
||||
if (!HasUnitState(UNIT_STATE_CANNOT_TURN))
|
||||
@@ -21016,7 +21158,7 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
|
||||
else if (index == UNIT_FIELD_FLAGS)
|
||||
{
|
||||
uint32 appendValue = m_uint32Values[UNIT_FIELD_FLAGS];
|
||||
if (target->IsGameMaster() && AccountMgr::IsGMAccount(target->GetSession()->GetSecurity()))
|
||||
if (target->IsGameMaster() && target->GetSession()->IsGMAccount())
|
||||
appendValue &= ~UNIT_FLAG_NOT_SELECTABLE;
|
||||
|
||||
fieldBuffer << uint32(appendValue);
|
||||
@@ -21041,7 +21183,7 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
|
||||
|
||||
if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
|
||||
{
|
||||
if (target->IsGameMaster() && AccountMgr::IsGMAccount(target->GetSession()->GetSecurity()))
|
||||
if (target->IsGameMaster() && target->GetSession()->IsGMAccount())
|
||||
{
|
||||
if (cinfo->Modelid1)
|
||||
displayId = cinfo->Modelid1; // Modelid1 is a visible model for gms
|
||||
@@ -21176,6 +21318,18 @@ void Unit::setRace(uint8 race)
|
||||
m_race = race;
|
||||
}
|
||||
|
||||
DisplayRace Unit::GetDisplayRaceFromModelId(uint32 modelId) const
|
||||
{
|
||||
if (CreatureDisplayInfoEntry const* display = sCreatureDisplayInfoStore.LookupEntry(modelId))
|
||||
{
|
||||
if (CreatureDisplayInfoExtraEntry const* displayExtra = sCreatureDisplayInfoExtraStore.LookupEntry(display->ExtendedDisplayInfoID))
|
||||
{
|
||||
return DisplayRace(displayExtra->DisplayRaceID);
|
||||
}
|
||||
}
|
||||
return DisplayRace::None;
|
||||
}
|
||||
|
||||
// Check if unit in combat with specific unit
|
||||
bool Unit::IsInCombatWith(Unit const* who) const
|
||||
{
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#ifndef __UNIT_H
|
||||
#define __UNIT_H
|
||||
|
||||
#include "EventProcessor.h"
|
||||
#include "EnumFlag.h"
|
||||
#include "EventProcessor.h"
|
||||
#include "FollowerRefMgr.h"
|
||||
#include "FollowerReference.h"
|
||||
#include "HostileRefMgr.h"
|
||||
@@ -311,13 +311,13 @@ enum BaseModType
|
||||
|
||||
#define MOD_END (PCT_MOD+1)
|
||||
|
||||
enum DeathState
|
||||
enum class DeathState : uint8
|
||||
{
|
||||
ALIVE = 0,
|
||||
JUST_DIED = 1,
|
||||
CORPSE = 2,
|
||||
DEAD = 3,
|
||||
JUST_RESPAWNED = 4,
|
||||
Alive = 0,
|
||||
JustDied = 1,
|
||||
Corpse = 2,
|
||||
Dead = 3,
|
||||
JustRespawned = 4,
|
||||
};
|
||||
|
||||
enum UnitState
|
||||
@@ -391,7 +391,7 @@ enum UnitMoveType
|
||||
extern float baseMoveSpeed[MAX_MOVE_TYPE];
|
||||
extern float playerBaseMoveSpeed[MAX_MOVE_TYPE];
|
||||
|
||||
enum WeaponAttackType
|
||||
enum WeaponAttackType : uint8
|
||||
{
|
||||
BASE_ATTACK = 0,
|
||||
OFF_ATTACK = 1,
|
||||
@@ -430,7 +430,7 @@ enum CombatRating
|
||||
|
||||
#define MAX_COMBAT_RATING 25
|
||||
|
||||
enum DamageEffectType
|
||||
enum DamageEffectType : uint8
|
||||
{
|
||||
DIRECT_DAMAGE = 0, // used for normal weapon damage (not for class abilities or spells)
|
||||
SPELL_DIRECT_DAMAGE = 1, // spell/class abilities damage
|
||||
@@ -1438,6 +1438,8 @@ public:
|
||||
[[nodiscard]] uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
|
||||
[[nodiscard]] uint32 getClassMask() const { return 1 << (getClass() - 1); }
|
||||
[[nodiscard]] uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); }
|
||||
[[nodiscard]] DisplayRace GetDisplayRaceFromModelId(uint32 modelId) const;
|
||||
[[nodiscard]] DisplayRace GetDisplayRace() const { return GetDisplayRaceFromModelId(GetDisplayId()); };
|
||||
|
||||
[[nodiscard]] float GetStat(Stats stat) const { return float(GetUInt32Value(static_cast<uint16>(UNIT_FIELD_STAT0) + stat)); }
|
||||
void SetStat(Stats stat, int32 val) { SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_STAT0) + stat, val); }
|
||||
@@ -1819,9 +1821,9 @@ public:
|
||||
|
||||
void BuildHeartBeatMsg(WorldPacket* data) const;
|
||||
|
||||
[[nodiscard]] bool IsAlive() const { return (m_deathState == ALIVE); };
|
||||
[[nodiscard]] bool isDying() const { return (m_deathState == JUST_DIED); };
|
||||
[[nodiscard]] bool isDead() const { return (m_deathState == DEAD || m_deathState == CORPSE); };
|
||||
[[nodiscard]] bool IsAlive() const { return (m_deathState == DeathState::Alive); };
|
||||
[[nodiscard]] bool isDying() const { return (m_deathState == DeathState::JustDied); };
|
||||
[[nodiscard]] bool isDead() const { return (m_deathState == DeathState::Dead || m_deathState == DeathState::Corpse); };
|
||||
DeathState getDeathState() { return m_deathState; };
|
||||
virtual void setDeathState(DeathState s, bool despawn = false); // overwrited in Creature/Player/Pet
|
||||
|
||||
@@ -1995,7 +1997,7 @@ public:
|
||||
AuraApplication* GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraApplication* except = nullptr) const;
|
||||
[[nodiscard]] Aura* GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0) const;
|
||||
|
||||
void GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList);
|
||||
void GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList, SpellInfo const* dispelSpell);
|
||||
|
||||
[[nodiscard]] bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster = ObjectGuid::Empty) const;
|
||||
[[nodiscard]] uint32 GetAuraCount(uint32 spellId) const;
|
||||
@@ -2145,7 +2147,7 @@ public:
|
||||
// common function for visibility checks for player/creatures with detection code
|
||||
[[nodiscard]] uint32 GetPhaseByAuras() const;
|
||||
void SetPhaseMask(uint32 newPhaseMask, bool update) override;// overwrite WorldObject::SetPhaseMask
|
||||
void UpdateObjectVisibility(bool forced = true) override;
|
||||
void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false) override;
|
||||
|
||||
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
|
||||
uint32 m_lastSanctuaryTime;
|
||||
@@ -2419,6 +2421,14 @@ public:
|
||||
void AddPointedBy(SafeUnitPointer* sup) { SafeUnitPointerSet.insert(sup); }
|
||||
void RemovePointedBy(SafeUnitPointer* sup) { SafeUnitPointerSet.erase(sup); }
|
||||
static void HandleSafeUnitPointersOnDelete(Unit* thisUnit);
|
||||
// Relocation Nofier optimization
|
||||
Position m_last_notify_position;
|
||||
uint32 m_last_notify_mstime;
|
||||
uint16 m_delayed_unit_relocation_timer;
|
||||
uint16 m_delayed_unit_ai_notify_timer;
|
||||
bool bRequestForcedVisibilityUpdate;
|
||||
void ExecuteDelayedUnitRelocationEvent();
|
||||
void ExecuteDelayedUnitAINotifyEvent();
|
||||
|
||||
// cooldowns
|
||||
[[nodiscard]] virtual bool HasSpellCooldown(uint32 /*spell_id*/) const { return false; }
|
||||
@@ -2581,7 +2591,7 @@ private:
|
||||
uint32 m_state; // Even derived shouldn't modify
|
||||
uint32 m_CombatTimer;
|
||||
uint32 m_lastManaUse; // msecs
|
||||
TimeTrackerSmall m_splineSyncTimer;
|
||||
//TimeTrackerSmall m_movesplineTimer;
|
||||
|
||||
Diminishing m_Diminishing;
|
||||
// Manage all Units that are threatened by us
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Unit.h"
|
||||
#include "Define.h"
|
||||
#include "SmartEnum.h"
|
||||
#include "Unit.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Acore::Impl::EnumUtilsImpl
|
||||
|
||||
@@ -545,8 +545,7 @@ bool Vehicle::IsVehicleInUse()
|
||||
|
||||
void Vehicle::TeleportVehicle(float x, float y, float z, float ang)
|
||||
{
|
||||
if (!_me->GetMap()->IsGridLoaded(x, y))
|
||||
_me->GetMap()->LoadGrid(x, y);
|
||||
_me->GetMap()->LoadGrid(x, y);
|
||||
_me->NearTeleportTo(x, y, z, ang, true);
|
||||
|
||||
for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
|
||||
|
||||
@@ -22,20 +22,19 @@
|
||||
#include "CharacterCache.h"
|
||||
#include "Chat.h"
|
||||
#include "Common.h"
|
||||
#include "CreatureAIFactory.h"
|
||||
#include "Config.h"
|
||||
#include "Containers.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "CreatureAIFactory.h"
|
||||
#include "DBCStructure.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "DisableMgr.h"
|
||||
#include "GameObjectAIFactory.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "GameObjectAIFactory.h"
|
||||
#include "GameTime.h"
|
||||
#include "GossipDef.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "GuildMgr.h"
|
||||
#include "LFGMgr.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
#include "MapMgr.h"
|
||||
#include "Pet.h"
|
||||
@@ -45,13 +44,14 @@
|
||||
#include "Spell.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellScriptLoader.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Transport.h"
|
||||
#include "Unit.h"
|
||||
#include "Util.h"
|
||||
#include "Vehicle.h"
|
||||
#include "World.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
ScriptMapMap sSpellScripts;
|
||||
@@ -591,7 +591,7 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||
"ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, ExperienceModifier, "
|
||||
// 64 65 66 67 68 69 70
|
||||
"RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName "
|
||||
"FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId;");
|
||||
"FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId ORDER BY entry DESC;");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
@@ -600,6 +600,7 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||
}
|
||||
|
||||
_creatureTemplateStore.rehash(result->GetRowCount());
|
||||
_creatureTemplateStoreFast.clear();
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
@@ -609,20 +610,7 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
// pussywizard:
|
||||
{
|
||||
uint32 max = 0;
|
||||
for (CreatureTemplateContainer::const_iterator itr = _creatureTemplateStore.begin(); itr != _creatureTemplateStore.end(); ++itr)
|
||||
if (itr->first > max)
|
||||
max = itr->first;
|
||||
if (max)
|
||||
{
|
||||
_creatureTemplateStoreFast.clear();
|
||||
_creatureTemplateStoreFast.resize(max + 1, nullptr);
|
||||
for (CreatureTemplateContainer::iterator itr = _creatureTemplateStore.begin(); itr != _creatureTemplateStore.end(); ++itr)
|
||||
_creatureTemplateStoreFast[itr->first] = &(itr->second);
|
||||
}
|
||||
}
|
||||
sScriptMgr->OnAfterDatabaseLoadCreatureTemplates(_creatureTemplateStoreFast);
|
||||
|
||||
LoadCreatureTemplateResistances();
|
||||
LoadCreatureTemplateSpells();
|
||||
@@ -638,12 +626,28 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||
LOG_INFO("server.loading", " ");
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCreatureTemplate(Field* fields)
|
||||
/**
|
||||
* @brief Loads a creature template from a database result
|
||||
*
|
||||
* @param fields Database result
|
||||
* @param triggerHook If true, will trigger the OnAfterDatabaseLoadCreatureTemplates hook. Useful if you are not calling the hook yourself.
|
||||
*/
|
||||
void ObjectMgr::LoadCreatureTemplate(Field* fields, bool triggerHook)
|
||||
{
|
||||
uint32 entry = fields[0].Get<uint32>();
|
||||
|
||||
CreatureTemplate& creatureTemplate = _creatureTemplateStore[entry];
|
||||
|
||||
// enlarge the fast cache as necessary
|
||||
if (_creatureTemplateStoreFast.size() < entry + 1)
|
||||
{
|
||||
_creatureTemplateStoreFast.resize(entry + 1, nullptr);
|
||||
}
|
||||
|
||||
// load a pointer to this creatureTemplate into the fast cache
|
||||
_creatureTemplateStoreFast[entry] = &creatureTemplate;
|
||||
|
||||
// build the creatureTemplate
|
||||
creatureTemplate.Entry = entry;
|
||||
|
||||
for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i)
|
||||
@@ -750,6 +754,13 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
|
||||
creatureTemplate.SpellSchoolImmuneMask = fields[68].Get<uint8>();
|
||||
creatureTemplate.flags_extra = fields[69].Get<uint32>();
|
||||
creatureTemplate.ScriptID = GetScriptId(fields[70].Get<std::string>());
|
||||
|
||||
// useful if the creature template load is being triggered from outside this class
|
||||
if (triggerHook)
|
||||
{
|
||||
sScriptMgr->OnAfterDatabaseLoadCreatureTemplates(_creatureTemplateStoreFast);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadCreatureTemplateResistances()
|
||||
@@ -4931,6 +4942,25 @@ void ObjectMgr::LoadQuests()
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8 j = 0; j < QUEST_REWARDS_COUNT; ++j)
|
||||
{
|
||||
if (!qinfo->RewardItemId[0] && qinfo->RewardItemId[j])
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Quest {} has no `RewardItemId1` but has `RewardItem{}`. Reward item will not be loaded.",
|
||||
qinfo->GetQuestId(), j + 1);
|
||||
}
|
||||
if (!qinfo->RewardItemId[1] && j > 1 && qinfo->RewardItemId[j])
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Quest {} has no `RewardItemId2` but has `RewardItem{}`. Reward item will not be loaded.",
|
||||
qinfo->GetQuestId(), j + 1);
|
||||
}
|
||||
if (!qinfo->RewardItemId[2] && j > 2 && qinfo->RewardItemId[j])
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Quest {} has no `RewardItemId3` but has `RewardItem{}`. Reward item will not be loaded.",
|
||||
qinfo->GetQuestId(), j + 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8 j = 0; j < QUEST_REWARDS_COUNT; ++j)
|
||||
{
|
||||
uint32 id = qinfo->RewardItemId[j];
|
||||
@@ -5660,7 +5690,7 @@ void ObjectMgr::ValidateSpellScripts()
|
||||
|
||||
for (SpellScriptsContainer::iterator itr = _spellScriptsStore.begin(); itr != _spellScriptsStore.end();)
|
||||
{
|
||||
SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(itr->first);
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
|
||||
std::vector<std::pair<SpellScriptLoader*, SpellScriptsContainer::iterator> > SpellScriptLoaders;
|
||||
sScriptMgr->CreateSpellScriptLoaders(itr->first, SpellScriptLoaders);
|
||||
itr = _spellScriptsStore.upper_bound(itr->first);
|
||||
@@ -5677,17 +5707,17 @@ void ObjectMgr::ValidateSpellScripts()
|
||||
}
|
||||
if (spellScript)
|
||||
{
|
||||
spellScript->_Init(&sitr->first->GetName(), spellEntry->Id);
|
||||
spellScript->_Init(&sitr->first->GetName(), spellInfo->Id);
|
||||
spellScript->_Register();
|
||||
if (!spellScript->_Validate(spellEntry))
|
||||
if (!spellScript->_Validate(spellInfo))
|
||||
valid = false;
|
||||
delete spellScript;
|
||||
}
|
||||
if (auraScript)
|
||||
{
|
||||
auraScript->_Init(&sitr->first->GetName(), spellEntry->Id);
|
||||
auraScript->_Init(&sitr->first->GetName(), spellInfo->Id);
|
||||
auraScript->_Register();
|
||||
if (!auraScript->_Validate(spellEntry))
|
||||
if (!auraScript->_Validate(spellInfo))
|
||||
valid = false;
|
||||
delete auraScript;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user