diff options
Diffstat (limited to 'src')
317 files changed, 5219 insertions, 3480 deletions
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index 0b1a93b3d2a..af7ecd15160 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -24,17 +24,11 @@ * authentication server */ -#include <cstdlib> -#include <boost/date_time/posix_time/posix_time.hpp> -#include <boost/program_options.hpp> -#include <iostream> -#include <openssl/opensslv.h> -#include <openssl/crypto.h> #include "AsyncAcceptor.h" #include "AuthSession.h" #include "BattlenetManager.h" -#include "BattlenetSession.h" +#include "BattlenetSessionManager.h" #include "Common.h" #include "Configuration/Config.h" #include "Database/DatabaseEnv.h" @@ -43,6 +37,12 @@ #include "RealmList.h" #include "SystemConfig.h" #include "Util.h" +#include <cstdlib> +#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/program_options.hpp> +#include <iostream> +#include <openssl/opensslv.h> +#include <openssl/crypto.h> using boost::asio::ip::tcp; using namespace boost::program_options; @@ -106,6 +106,7 @@ int main(int argc, char** argv) if (sRealmList->size() == 0) { TC_LOG_ERROR("server.authserver", "No valid realms specified."); + StopDB(); return 1; } @@ -114,12 +115,21 @@ int main(int argc, char** argv) if (port < 0 || port > 0xFFFF) { TC_LOG_ERROR("server.authserver", "Specified port out of allowed range (1-65535)"); + StopDB(); + return 1; + } + + int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119); + if (bnport < 0 || bnport > 0xFFFF) + { + TC_LOG_ERROR("server.authserver", "Specified battle.net port (%d) out of allowed range (1-65535)", bnport); + StopDB(); return 1; } std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); AsyncAcceptor<AuthSession> authServer(_ioService, bindIp, port); - AsyncAcceptor<Battlenet::Session> bnetServer(_ioService, bindIp, 1119); + AsyncAcceptor<Battlenet::Session> bnetServer(_ioService, bindIp, bnport); // Set signal handlers boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM); diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp index 5a03109f717..2110dc1fecc 100644 --- a/src/server/authserver/Realms/RealmList.cpp +++ b/src/server/authserver/Realms/RealmList.cpp @@ -137,8 +137,10 @@ void RealmList::UpdateRealms(bool init) uint32 realmId = fields[0].GetUInt32(); std::string name = fields[1].GetString(); boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), ""); - boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery); - if (endPoint == end) + + boost::system::error_code ec; + boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec); + if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[2].GetString().c_str()); return; @@ -147,8 +149,8 @@ void RealmList::UpdateRealms(bool init) ip::address externalAddress = (*endPoint).endpoint().address(); boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), ""); - endPoint = _resolver->resolve(localAddressQuery); - if (endPoint == end) + endPoint = _resolver->resolve(localAddressQuery, ec); + if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[3].GetString().c_str()); return; @@ -157,8 +159,8 @@ void RealmList::UpdateRealms(bool init) ip::address localAddress = (*endPoint).endpoint().address(); boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), ""); - endPoint = _resolver->resolve(localSubmaskQuery); - if (endPoint == end) + endPoint = _resolver->resolve(localSubmaskQuery, ec); + if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[4].GetString().c_str()); return; diff --git a/src/server/authserver/Server/AuthSession.cpp b/src/server/authserver/Server/AuthSession.cpp index ac7c1cfaee5..91a2ff9757a 100644 --- a/src/server/authserver/Server/AuthSession.cpp +++ b/src/server/authserver/Server/AuthSession.cpp @@ -21,6 +21,7 @@ #include "AuthCodes.h" #include "Database/DatabaseEnv.h" #include "SHA1.h" +#include "TOTP.h" #include "openssl/crypto.h" #include "Configuration/Config.h" #include "RealmList.h" @@ -52,7 +53,6 @@ enum eStatus typedef struct AUTH_LOGON_CHALLENGE_C { - uint8 cmd; uint8 error; uint16 size; uint8 gamename[4]; @@ -71,7 +71,6 @@ typedef struct AUTH_LOGON_CHALLENGE_C typedef struct AUTH_LOGON_PROOF_C { - uint8 cmd; uint8 A[32]; uint8 M1[20]; uint8 crc_hash[20]; @@ -84,8 +83,8 @@ typedef struct AUTH_LOGON_PROOF_S uint8 cmd; uint8 error; uint8 M2[20]; - uint32 unk1; - uint32 unk2; + uint32 AccountFlags; + uint32 SurveyId; uint16 unk3; } sAuthLogonProof_S; @@ -99,7 +98,6 @@ typedef struct AUTH_LOGON_PROOF_S_OLD typedef struct AUTH_RECONNECT_PROOF_C { - uint8 cmd; uint8 R1[16]; uint8 R2[20]; uint8 R3[20]; @@ -114,10 +112,10 @@ enum class BufferSizes : uint32 SRP_6_S = 0x20, }; -#define REALM_LIST_PACKET_SIZE 5 -#define XFER_ACCEPT_SIZE 1 -#define XFER_RESUME_SIZE 9 -#define XFER_CANCEL_SIZE 1 +#define REALM_LIST_PACKET_SIZE 4 +#define XFER_ACCEPT_SIZE 0 +#define XFER_RESUME_SIZE 8 +#define XFER_CANCEL_SIZE 0 std::unordered_map<uint8, AuthHandler> AuthSession::InitHandlers() { @@ -137,48 +135,43 @@ std::unordered_map<uint8, AuthHandler> AuthSession::InitHandlers() std::unordered_map<uint8, AuthHandler> const Handlers = AuthSession::InitHandlers(); -void AuthSession::ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) +void AuthSession::ReadHeaderHandler() { - if (!error && transferedBytes == 1) + uint8 cmd = GetHeaderBuffer()[0]; + auto itr = Handlers.find(cmd); + if (itr != Handlers.end()) { - uint8 cmd = GetReadBuffer()[0]; - auto itr = Handlers.find(cmd); - if (itr != Handlers.end()) + // Handle dynamic size packet + if (cmd == AUTH_LOGON_CHALLENGE || cmd == AUTH_RECONNECT_CHALLENGE) { - // Handle dynamic size packet - if (cmd == AUTH_LOGON_CHALLENGE || cmd == AUTH_RECONNECT_CHALLENGE) - { - ReadData(sizeof(uint8) + sizeof(uint16), sizeof(cmd)); //error + size - sAuthLogonChallenge_C* challenge = reinterpret_cast<sAuthLogonChallenge_C*>(GetReadBuffer()); + ReadData(sizeof(uint8) + sizeof(uint16)); //error + size + sAuthLogonChallenge_C* challenge = reinterpret_cast<sAuthLogonChallenge_C*>(GetDataBuffer()); - AsyncReadData(challenge->size, sizeof(uint8) + sizeof(uint8) + sizeof(uint16)); // cmd + error + size - } - else - AsyncReadData(itr->second.packetSize, sizeof(uint8)); + AsyncReadData(challenge->size); } + else + AsyncReadData(itr->second.packetSize); } else CloseSocket(); } -void AuthSession::ReadDataHandler(boost::system::error_code error, size_t transferedBytes) +void AuthSession::ReadDataHandler() { - if (!error && transferedBytes > 0) + if (!(*this.*Handlers.at(GetHeaderBuffer()[0]).handler)()) { - if (!(*this.*Handlers.at(GetReadBuffer()[0]).handler)()) - { - CloseSocket(); - return; - } - - AsyncReadHeader(); - } - else CloseSocket(); + return; + } + + AsyncReadHeader(); } void AuthSession::AsyncWrite(ByteBuffer& packet) { + if (!IsOpen()) + return; + std::lock_guard<std::mutex> guard(_writeLock); bool needsWriteStart = _writeQueue.empty(); @@ -191,7 +184,7 @@ void AuthSession::AsyncWrite(ByteBuffer& packet) bool AuthSession::HandleLogonChallenge() { - sAuthLogonChallenge_C* challenge = reinterpret_cast<sAuthLogonChallenge_C*>(GetReadBuffer()); + sAuthLogonChallenge_C* challenge = reinterpret_cast<sAuthLogonChallenge_C*>(GetDataBuffer()); //TC_LOG_DEBUG("server.authserver", "[AuthChallenge] got full packet, %#04x bytes", challenge->size); TC_LOG_DEBUG("server.authserver", "[AuthChallenge] name(%d): '%s'", challenge->I_len, challenge->I); @@ -412,7 +405,7 @@ bool AuthSession::HandleLogonProof() TC_LOG_DEBUG("server.authserver", "Entering _HandleLogonProof"); // Read the packet - sAuthLogonProof_C *logonProof = reinterpret_cast<sAuthLogonProof_C*>(GetReadBuffer()); + sAuthLogonProof_C *logonProof = reinterpret_cast<sAuthLogonProof_C*>(GetDataBuffer()); // If the client has no valid version if (_expversion == NO_VALID_EXP_FLAG) @@ -519,17 +512,12 @@ bool AuthSession::HandleLogonProof() // Check auth token if ((logonProof->securityFlags & 0x04) || !_tokenKey.empty()) { - // TODO To be fixed - - /* - uint8 size; - socket().recv((char*)&size, 1); - char* token = new char[size + 1]; - token[size] = '\0'; - socket().recv(token, size); - unsigned int validToken = TOTP::GenerateToken(_tokenKey.c_str()); - unsigned int incomingToken = atoi(token); - delete[] token; + ReadData(1); + uint8 size = *(GetDataBuffer() + sizeof(sAuthLogonProof_C)); + ReadData(size); + std::string token(reinterpret_cast<char*>(GetDataBuffer() + sizeof(sAuthLogonProof_C) + sizeof(size)), size); + uint32 validToken = TOTP::GenerateToken(_tokenKey.c_str()); + uint32 incomingToken = atoi(token.c_str()); if (validToken != incomingToken) { ByteBuffer packet; @@ -539,7 +527,7 @@ bool AuthSession::HandleLogonProof() packet << uint8(0); AsyncWrite(packet); return false; - }*/ + } } ByteBuffer packet; @@ -549,9 +537,9 @@ bool AuthSession::HandleLogonProof() memcpy(proof.M2, sha.GetDigest(), 20); proof.cmd = AUTH_LOGON_PROOF; proof.error = 0; - proof.unk1 = GAMEACCOUNT_FLAG_PROPASS_LOCK; - proof.unk2 = 0x00; // SurveyId - proof.unk3 = 0x00; + proof.AccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK; + proof.SurveyId = 0; + proof.unk3 = 0; packet.resize(sizeof(proof)); std::memcpy(packet.contents(), &proof, sizeof(proof)); @@ -647,7 +635,7 @@ bool AuthSession::HandleLogonProof() bool AuthSession::HandleReconnectChallenge() { TC_LOG_DEBUG("server.authserver", "Entering _HandleReconnectChallenge"); - sAuthLogonChallenge_C* challenge = reinterpret_cast<sAuthLogonChallenge_C*>(GetReadBuffer()); + sAuthLogonChallenge_C* challenge = reinterpret_cast<sAuthLogonChallenge_C*>(GetDataBuffer()); //TC_LOG_DEBUG("server.authserver", "[AuthChallenge] got full packet, %#04x bytes", challenge->size); TC_LOG_DEBUG("server.authserver", "[AuthChallenge] name(%d): '%s'", challenge->I_len, challenge->I); @@ -698,7 +686,7 @@ bool AuthSession::HandleReconnectChallenge() bool AuthSession::HandleReconnectProof() { TC_LOG_DEBUG("server.authserver", "Entering _HandleReconnectProof"); - sAuthReconnectProof_C *reconnectProof = reinterpret_cast<sAuthReconnectProof_C*>(GetReadBuffer()); + sAuthReconnectProof_C *reconnectProof = reinterpret_cast<sAuthReconnectProof_C*>(GetDataBuffer()); if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes()) return false; diff --git a/src/server/authserver/Server/AuthSession.h b/src/server/authserver/Server/AuthSession.h index 2ba6b3efdd4..04ee339df8e 100644 --- a/src/server/authserver/Server/AuthSession.h +++ b/src/server/authserver/Server/AuthSession.h @@ -37,7 +37,8 @@ class AuthSession : public Socket<AuthSession, ByteBuffer> public: static std::unordered_map<uint8, AuthHandler> InitHandlers(); - AuthSession(tcp::socket&& socket) : Socket(std::move(socket), 1) + AuthSession(tcp::socket&& socket) : Socket(std::move(socket), 1), + _isAuthenticated(false), _build(0), _expversion(0), _accountSecurityLevel(SEC_PLAYER) { N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword(7); @@ -51,8 +52,8 @@ public: void AsyncWrite(ByteBuffer& packet); protected: - void ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) override; - void ReadDataHandler(boost::system::error_code error, size_t transferedBytes) override; + void ReadHeaderHandler() override; + void ReadDataHandler() override; private: bool HandleLogonChallenge(); diff --git a/src/server/authserver/Server/BattlenetBitStream.h b/src/server/authserver/Server/BattlenetBitStream.h index 8f369f1d3ce..82c2a0a6d5d 100644 --- a/src/server/authserver/Server/BattlenetBitStream.h +++ b/src/server/authserver/Server/BattlenetBitStream.h @@ -18,8 +18,9 @@ #ifndef __BATTLENETBITSTREAM_H__ #define __BATTLENETBITSTREAM_H__ -#include "ByteConverter.h" #include "Common.h" +#include "ByteConverter.h" +#include "MessageBuffer.h" #include <exception> #include <vector> #include <type_traits> @@ -58,12 +59,16 @@ namespace Battlenet static uint32 const MaxSize = 0x4000; // length : The maximum number of bytes to read - BitStream(uint32 length) : _numBits(length * 8), _readPos(0), _writePos(0) + BitStream(uint32 length) : _writePos(length * 8), _readPos(0) { _buffer.resize(length, 0); } - BitStream() : _numBits(0), _readPos(0), _writePos(0) + BitStream(MessageBuffer&& buffer) : _writePos(buffer.GetReadyDataSize() * 8), _readPos(0), _buffer(buffer.Move()) + { + } + + BitStream() : _writePos(0), _readPos(0) { _buffer.reserve(0x1000); } @@ -86,8 +91,8 @@ namespace Battlenet std::unique_ptr<uint8[]> ReadBytes(uint32 count) { AlignToNextByte(); - if (_readPos + count * 8 > _numBits) - throw BitStreamPositionException(true, count * 8, _readPos, _numBits); + if (_readPos + count * 8 > _writePos) + throw BitStreamPositionException(true, count * 8, _readPos, _writePos); std::unique_ptr<uint8[]> buf(new uint8[count]); memcpy(buf.get(), &_buffer[_readPos >> 3], count); @@ -120,8 +125,8 @@ namespace Battlenet { static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "T must be an integer type"); - if (_readPos + bitCount >= _numBits) - throw BitStreamPositionException(true, bitCount, _readPos, _numBits); + if (_readPos + bitCount >= _writePos) + throw BitStreamPositionException(true, bitCount, _readPos, _writePos); uint64 ret = 0; while (bitCount != 0) @@ -209,26 +214,23 @@ namespace Battlenet void SetReadPos(uint32 bits) { - if (bits >= _numBits) - throw BitStreamPositionException(true, bits, 0, _numBits); + if (bits >= _writePos) + throw BitStreamPositionException(true, bits, 0, _writePos); _readPos = bits; } - bool IsRead() const { return _readPos >= _numBits; } + bool IsRead() const { return _readPos >= _writePos; } uint8* GetBuffer() { return _buffer.data(); } uint8 const* GetBuffer() const { return _buffer.data(); } - size_t GetSize() const { return _buffer.size(); } - - void FinishReading() { _readPos = _numBits; } + size_t GetSize() const { return ((_writePos + 7) & ~7) / 8; } private: - std::vector<uint8> _buffer; - uint32 _numBits; - uint32 _readPos; uint32 _writePos; + uint32 _readPos; + std::vector<uint8> _buffer; }; template<> diff --git a/src/server/authserver/Server/BattlenetSession.cpp b/src/server/authserver/Server/BattlenetSession.cpp index 0fd08c267f1..2c2026253dc 100644 --- a/src/server/authserver/Server/BattlenetSession.cpp +++ b/src/server/authserver/Server/BattlenetSession.cpp @@ -17,7 +17,7 @@ #include "AuthCodes.h" #include "BattlenetBitStream.h" -#include "BattlenetSession.h" +#include "BattlenetSessionManager.h" #include "Database/DatabaseEnv.h" #include "HmacHash.h" #include "Log.h" @@ -57,7 +57,7 @@ Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODUL }; Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket), std::size_t(BufferSizes::Read)), _accountId(0), _accountName(), _locale(), - _os(), _build(0), _gameAccountId(0), _gameAccountIndex(0), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(), + _os(), _build(0), _gameAccountId(0), _gameAccountName(), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(), _reconnectProof(), _crypt(), _authed(false) { static uint8 const N_Bytes[] = @@ -83,6 +83,7 @@ Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket), st Battlenet::Session::~Session() { + sBattlenetSessionMgr.RemoveSession(this); TC_LOG_TRACE("server.battlenet", "Battlenet::Session::OnClose"); } @@ -330,12 +331,10 @@ bool Battlenet::Session::HandleAuthReconnect(PacketHeader& header, BitStream& pa if (baseComponent != reconnect.Components.end()) _build = baseComponent->Build; - uint8 accountIndex = atol(reconnect.GameAccountName.substr(reconnect.GameAccountName.find_last_of('#') + 1).c_str()); - Utf8ToUpperOnlyLatin(_accountName); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO); stmt->setString(0, _accountName); - stmt->setUInt8(1, accountIndex); + stmt->setString(1, reconnect.GameAccountName); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { @@ -350,7 +349,7 @@ bool Battlenet::Session::HandleAuthReconnect(PacketHeader& header, BitStream& pa _accountId = fields[0].GetUInt32(); K.SetHexStr(fields[1].GetString().c_str()); _gameAccountId = fields[2].GetUInt32(); - _gameAccountIndex = accountIndex; + _gameAccountName = reconnect.GameAccountName; ModuleInfo* thumbprint = sBattlenetMgr->CreateModule(_os, "Thumbprint"); ModuleInfo* resume = sBattlenetMgr->CreateModule(_os, "Resume"); @@ -538,17 +537,10 @@ bool Battlenet::Session::HandleRealmJoinRequest(PacketHeader& header, BitStream& return true; } -void Battlenet::Session::ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) +void Battlenet::Session::ReadDataHandler() { - if (error) - { - CloseSocket(); - return; - } - - BitStream packet(transferedBytes); - std::memcpy(packet.GetBuffer(), GetReadBuffer(), transferedBytes); - _crypt.DecryptRecv(packet.GetBuffer(), transferedBytes); + BitStream packet(MoveData()); + _crypt.DecryptRecv(packet.GetBuffer(), packet.GetSize()); while (!packet.IsRead()) { @@ -561,12 +553,12 @@ void Battlenet::Session::ReadHeaderHandler(boost::system::error_code error, size if (header.Channel != AUTHENTICATION && !_authed) { - TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::AsyncRead Received not allowed packet %s", header.ToString().c_str()); + TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Received not allowed packet %s", header.ToString().c_str()); CloseSocket(); return; } - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::AsyncRead %s", header.ToString().c_str()); + TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", header.ToString().c_str()); std::map<PacketHeader, PacketHandler>::const_iterator itr = Handlers.find(header); if (itr != Handlers.end()) { @@ -575,7 +567,7 @@ void Battlenet::Session::ReadHeaderHandler(boost::system::error_code error, size } else { - TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::AsyncRead Unhandled opcode %s", header.ToString().c_str()); + TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Unhandled opcode %s", header.ToString().c_str()); break; } @@ -583,23 +575,29 @@ void Battlenet::Session::ReadHeaderHandler(boost::system::error_code error, size } catch (BitStreamPositionException const& e) { - TC_LOG_ERROR("server.battlenet", "Battlenet::Session::AsyncRead Exception: %s", e.what()); + TC_LOG_ERROR("server.battlenet", "Battlenet::Session::ReadDataHandler Exception: %s", e.what()); CloseSocket(); return; } } - AsyncReadHeader(); + AsyncReadData(size_t(BufferSizes::Read)); } void Battlenet::Session::Start() { TC_LOG_TRACE("server.battlenet", "Battlenet::Session::Start"); - AsyncReadHeader(); + AsyncReadData(size_t(BufferSizes::Read)); } void Battlenet::Session::AsyncWrite(ServerPacket* packet) { + if (!IsOpen()) + { + delete packet; + return; + } + TC_LOG_TRACE("server.battlenet", "Battlenet::Session::AsyncWrite %s", packet->ToString().c_str()); packet->Write(); @@ -781,7 +779,12 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke { fields = result->Fetch(); std::ostringstream name; - name << "WoW" << uint32(fields[0].GetUInt8()); + std::string originalName = fields[1].GetString(); + if (originalName.find('#') != std::string::npos) + name << "WoW" << uint32(fields[0].GetUInt8()); + else + name << originalName; + accounts.Write(2, 8); accounts.WriteString(name.str(), 8); } while (result->NextRow()); @@ -815,8 +818,8 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke return false; } - _gameAccountId = fields[1].GetUInt32(); - _gameAccountIndex = fields[0].GetUInt8(); + _gameAccountId = fields[0].GetUInt32(); + _gameAccountName = fields[1].GetString(); request->Modules.push_back(sBattlenetMgr->CreateModule(_os, "RiskFingerprint")); _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); @@ -838,7 +841,7 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se dataStream->Read<uint8>(8); std::string account = dataStream->ReadString(8); - if (account.length() < 4) + if (account.empty()) { AuthComplete* complete = new AuthComplete(); complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); @@ -846,10 +849,18 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se return false; } - uint8 accountIndex = atol(account.substr(3).c_str()); + PreparedStatement* stmt; + if (account.substr(0, 3) != "WoW") + { + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT); + stmt->setString(0, account); + } + else + { + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED); + stmt->setUInt8(0, atol(account.substr(3).c_str())); + } - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT); - stmt->setUInt8(0, accountIndex); stmt->setUInt32(1, _accountId); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) @@ -861,10 +872,10 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se } Field* fields = result->Fetch(); - if (fields[3].GetBool()) + if (fields[4].GetBool()) { AuthComplete* complete = new AuthComplete(); - if (fields[1].GetUInt32() == fields[2].GetUInt32()) + if (fields[2].GetUInt32() == fields[3].GetUInt32()) { complete->SetAuthResult(LOGIN_BANNED); TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); @@ -880,7 +891,7 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se } _gameAccountId = fields[0].GetUInt32(); - _gameAccountIndex = accountIndex; + _gameAccountName = fields[1].GetString(); ProofRequest* request = new ProofRequest(); request->Modules.push_back(sBattlenetMgr->CreateModule(_os, "RiskFingerprint")); @@ -895,11 +906,8 @@ bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, Serv AuthComplete* complete = new AuthComplete(); if (dataStream->Read<uint8>(8) == 1) { - std::ostringstream str; - str << _accountId << "#" << uint32(_gameAccountIndex); - complete->AccountId = _accountId; - complete->GameAccountName = str.str(); + complete->GameAccountName = _gameAccountName; complete->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK; SQLTransaction trans = LoginDatabase.BeginTransaction(); @@ -920,6 +928,7 @@ bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, Serv LoginDatabase.CommitTransaction(trans); _authed = true; + sBattlenetSessionMgr.AddSession(this); } else complete->SetAuthResult(AUTH_BAD_VERSION_HASH); @@ -943,8 +952,8 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* std::unique_ptr<uint8[]> clientChallenge = dataStream->ReadBytes(16); std::unique_ptr<uint8[]> clientProof = dataStream->ReadBytes(32); - std::unique_ptr<uint8[]> serverChallenge = _reconnectProof.AsByteArray(); - std::unique_ptr<uint8[]> sessionKey = K.AsByteArray(); + std::unique_ptr<uint8[]> serverChallenge = _reconnectProof.AsByteArray(16); + std::unique_ptr<uint8[]> sessionKey = K.AsByteArray(64); HmacSha256 clientPart(64, sessionKey.get()); clientPart.UpdateData(&ResumeClient, 1); @@ -1006,6 +1015,7 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* result->Modules.push_back(resume); ReplaceResponse(response, result); _authed = true; + sBattlenetSessionMgr.AddSession(this); return true; } diff --git a/src/server/authserver/Server/BattlenetSession.h b/src/server/authserver/Server/BattlenetSession.h index 78ae00b4e3e..f32f97d15e7 100644 --- a/src/server/authserver/Server/BattlenetSession.h +++ b/src/server/authserver/Server/BattlenetSession.h @@ -79,9 +79,11 @@ namespace Battlenet void AsyncWrite(ServerPacket* packet); + bool IsDataReady() const override { return GetDataSize() > 0; } + protected: - void ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) override; - void ReadDataHandler(boost::system::error_code /*error*/, size_t /*transferedBytes*/) override { } + void ReadHeaderHandler() override { } + void ReadDataHandler() override; private: void _SetVSFields(std::string const& rI); @@ -101,7 +103,7 @@ namespace Battlenet std::string _os; uint32 _build; uint32 _gameAccountId; - uint8 _gameAccountIndex; + std::string _gameAccountName; AccountTypes _accountSecurityLevel; BigNumber N; diff --git a/src/server/authserver/Server/BattlenetSessionManager.cpp b/src/server/authserver/Server/BattlenetSessionManager.cpp new file mode 100644 index 00000000000..e16057ecbf6 --- /dev/null +++ b/src/server/authserver/Server/BattlenetSessionManager.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "BattlenetSessionManager.h" diff --git a/src/server/authserver/Server/BattlenetSessionManager.h b/src/server/authserver/Server/BattlenetSessionManager.h new file mode 100644 index 00000000000..454bac96ddb --- /dev/null +++ b/src/server/authserver/Server/BattlenetSessionManager.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef BattlenetSessionManager_h__ +#define BattlenetSessionManager_h__ + +#include "BattlenetSession.h" + +namespace Battlenet +{ +#pragma pack(push, 1) + + struct SessionInfo + { + uint32 AccountId; + uint32 GameAccountIndex; + + bool operator<(SessionInfo const& right) const + { + return memcmp(this, &right, sizeof(SessionInfo)) < 0; + } + }; + +#pragma pack(pop) + + class SessionManager + { + public: + static SessionManager& Instance() + { + static SessionManager instance; + return instance; + } + + // noop for now, will be needed later to broadcast realmlist updates for example + void AddSession(Session* /*session*/) { } + + void RemoveSession(Session* /*session*/) { } + + private: + std::map<SessionInfo, Session> _sessions; + }; +} + +#define sBattlenetSessionMgr Battlenet::SessionManager::Instance() + +#endif // BattlenetSessionManager_h__ diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist index b7dee9ac08b..e0ef6982353 100644 --- a/src/server/authserver/authserver.conf.dist +++ b/src/server/authserver/authserver.conf.dist @@ -54,6 +54,13 @@ MaxPingTime = 30 RealmServerPort = 3724 # +# BattlenetPort +# Description: TCP port to reach the auth server for battle.net connections. +# Default: 1119 + +BattlenetPort = 1119 + +# # # BindIP # Description: Bind auth server to IP/hostname diff --git a/src/server/collision/BoundingIntervalHierarchy.cpp b/src/server/collision/BoundingIntervalHierarchy.cpp index d90009c03f3..c933fc8f4e3 100644 --- a/src/server/collision/BoundingIntervalHierarchy.cpp +++ b/src/server/collision/BoundingIntervalHierarchy.cpp @@ -72,11 +72,11 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat axis = d.primaryAxis(); split = 0.5f * (gridBox.lo[axis] + gridBox.hi[axis]); // partition L/R subsets - clipL = -G3D::inf(); - clipR = G3D::inf(); + clipL = -G3D::finf(); + clipR = G3D::finf(); rightOrig = right; // save this for later - float nodeL = G3D::inf(); - float nodeR = -G3D::inf(); + float nodeL = G3D::finf(); + float nodeR = -G3D::finf(); for (int i = left; i <= right;) { int obj = dat.indices[i]; @@ -187,13 +187,13 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat stats.updateInner(); tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex; tempTree[nodeIndex + 1] = floatToRawIntBits(prevClip); - tempTree[nodeIndex + 2] = floatToRawIntBits(G3D::inf()); + tempTree[nodeIndex + 2] = floatToRawIntBits(G3D::finf()); } else { // create a node with a right child // write leaf node stats.updateInner(); tempTree[nodeIndex + 0] = (prevAxis << 30) | (nextIndex - 3); - tempTree[nodeIndex + 1] = floatToRawIntBits(-G3D::inf()); + tempTree[nodeIndex + 1] = floatToRawIntBits(-G3D::finf()); tempTree[nodeIndex + 2] = floatToRawIntBits(prevClip); } // count stats for the unused leaf diff --git a/src/server/collision/DynamicTree.cpp b/src/server/collision/DynamicTree.cpp index f6d85df704a..a88c7573707 100644 --- a/src/server/collision/DynamicTree.cpp +++ b/src/server/collision/DynamicTree.cpp @@ -256,5 +256,5 @@ float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, if (callback.didHit()) return v.z - maxSearchDist; else - return -G3D::inf(); + return -G3D::finf(); } diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp index 1d267cbd2a5..484fdcd8ea4 100644 --- a/src/server/collision/Management/VMapManager2.cpp +++ b/src/server/collision/Management/VMapManager2.cpp @@ -194,7 +194,7 @@ namespace VMAP { Vector3 pos = convertPositionToInternalRep(x, y, z); float height = instanceTree->second->getHeight(pos, maxSearchDist); - if (!(height < G3D::inf())) + if (!(height < G3D::finf())) return height = VMAP_INVALID_HEIGHT_VALUE; // No height return height; diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h index 03de6951d5d..04292e7d8e4 100644 --- a/src/server/collision/Management/VMapManager2.h +++ b/src/server/collision/Management/VMapManager2.h @@ -53,7 +53,7 @@ namespace VMAP class ManagedModel { public: - ManagedModel() : iModel(0), iRefCount(0) { } + ManagedModel() : iModel(nullptr), iRefCount(0) { } void setModel(WorldModel* model) { iModel = model; } WorldModel* getModel() { return iModel; } void incRefCount() { ++iRefCount; } @@ -86,32 +86,32 @@ namespace VMAP VMapManager2(); ~VMapManager2(void); - int loadMap(const char* pBasePath, unsigned int mapId, int x, int y); + int loadMap(const char* pBasePath, unsigned int mapId, int x, int y) override; - void unloadMap(unsigned int mapId, int x, int y); - void unloadMap(unsigned int mapId); + void unloadMap(unsigned int mapId, int x, int y) override; + void unloadMap(unsigned int mapId) override; - bool isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2) ; + bool isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2) override ; /** fill the hit pos and return true, if an object was hit */ - bool getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist); - float getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist); + bool getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist) override; + float getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist) override; - bool processCommand(char* /*command*/) { return false; } // for debug and extensions + bool processCommand(char* /*command*/) override { return false; } // for debug and extensions - bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const; - bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const; + bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const override; + bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const override; WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename); void releaseModelInstance(const std::string& filename); // what's the use of this? o.O - virtual std::string getDirFileName(unsigned int mapId, int /*x*/, int /*y*/) const + virtual std::string getDirFileName(unsigned int mapId, int /*x*/, int /*y*/) const override { return getMapFileName(mapId); } - virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y); + virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y) override; public: void getInstanceMapTree(InstanceTreeMap &instanceMapTree); }; diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp index 6b82e06aff7..d62b2b21224 100644 --- a/src/server/collision/Maps/MapTree.cpp +++ b/src/server/collision/Maps/MapTree.cpp @@ -225,7 +225,7 @@ namespace VMAP float StaticMapTree::getHeight(const Vector3& pPos, float maxSearchDist) const { - float height = G3D::inf(); + float height = G3D::finf(); Vector3 dir = Vector3(0, 0, -1); G3D::Ray ray(pPos, dir); // direction with length of 1 float maxDist = maxSearchDist; diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h index 05351b74019..2f483a8822c 100644 --- a/src/server/collision/Maps/MapTree.h +++ b/src/server/collision/Maps/MapTree.h @@ -31,7 +31,7 @@ namespace VMAP struct LocationInfo { - LocationInfo(): hitInstance(0), hitModel(0), ground_Z(-G3D::inf()) { } + LocationInfo(): hitInstance(nullptr), hitModel(nullptr), ground_Z(-G3D::finf()) { } const ModelInstance* hitInstance; const GroupModel* hitModel; float ground_Z; @@ -89,7 +89,7 @@ namespace VMAP struct AreaInfo { - AreaInfo(): result(false), ground_Z(-G3D::inf()), flags(0), adtId(0), + AreaInfo(): result(false), ground_Z(-G3D::finf()), flags(0), adtId(0), rootId(0), groupId(0) { } bool result; float ground_Z; diff --git a/src/server/collision/Maps/TileAssembler.h b/src/server/collision/Maps/TileAssembler.h index 26a884551cd..2167f1e5689 100644 --- a/src/server/collision/Maps/TileAssembler.h +++ b/src/server/collision/Maps/TileAssembler.h @@ -46,7 +46,7 @@ namespace VMAP float iScale; void init() { - iRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi()*iDir.y/180.f, G3D::pi()*iDir.x/180.f, G3D::pi()*iDir.z/180.f); + iRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::pif()*iDir.y/180.f, G3D::pif()*iDir.x/180.f, G3D::pif()*iDir.z/180.f); } G3D::Vector3 transform(const G3D::Vector3& pIn) const; void moveToBasePos(const G3D::Vector3& pBasePos) { iPos -= pBasePos; } diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp index de97943bb37..bb2837be4c4 100644 --- a/src/server/collision/Models/GameObjectModel.cpp +++ b/src/server/collision/Models/GameObjectModel.cpp @@ -166,7 +166,7 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto return false; float time = ray.intersectionTime(iBound); - if (time == G3D::inf()) + if (time == G3D::finf()) return false; // child bounds are defined in object space: diff --git a/src/server/collision/Models/ModelInstance.cpp b/src/server/collision/Models/ModelInstance.cpp index 475984c4fd3..bd84548d792 100644 --- a/src/server/collision/Models/ModelInstance.cpp +++ b/src/server/collision/Models/ModelInstance.cpp @@ -28,7 +28,7 @@ namespace VMAP { ModelInstance::ModelInstance(const ModelSpawn &spawn, WorldModel* model): ModelSpawn(spawn), iModel(model) { - iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi()*iRot.y/180.f, G3D::pi()*iRot.x/180.f, G3D::pi()*iRot.z/180.f).inverse(); + iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pif()*iRot.y/180.f, G3D::pif()*iRot.x/180.f, G3D::pif()*iRot.z/180.f).inverse(); iInvScale = 1.f/iScale; } @@ -40,7 +40,7 @@ namespace VMAP return false; } float time = pRay.intersectionTime(iBound); - if (time == G3D::inf()) + if (time == G3D::finf()) { // std::cout << "Ray does not hit '" << name << "'\n"; diff --git a/src/server/collision/Models/ModelInstance.h b/src/server/collision/Models/ModelInstance.h index 3ea68f57ba4..1cb8fdde942 100644 --- a/src/server/collision/Models/ModelInstance.h +++ b/src/server/collision/Models/ModelInstance.h @@ -63,9 +63,9 @@ namespace VMAP class ModelInstance: public ModelSpawn { public: - ModelInstance(): iInvScale(0.0f), iModel(0) { } + ModelInstance(): iInvScale(0.0f), iModel(nullptr) { } ModelInstance(const ModelSpawn &spawn, WorldModel* model); - void setUnloaded() { iModel = 0; } + void setUnloaded() { iModel = nullptr; } bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool pStopAtFirstHit) const; void intersectPoint(const G3D::Vector3& p, AreaInfo &info) const; bool GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const; diff --git a/src/server/collision/Models/WorldModel.cpp b/src/server/collision/Models/WorldModel.cpp index 99f3782215d..5962b343544 100644 --- a/src/server/collision/Models/WorldModel.cpp +++ b/src/server/collision/Models/WorldModel.cpp @@ -42,7 +42,7 @@ namespace VMAP const Vector3 p(ray.direction().cross(e2)); const float a = e1.dot(p); - if (fabs(a) < EPS) { + if (std::fabs(a) < EPS) { // Determinant is ill-conditioned; abort early return false; } @@ -108,7 +108,7 @@ namespace VMAP iFlags = new uint8[width*height]; } - WmoLiquid::WmoLiquid(const WmoLiquid &other): iHeight(0), iFlags(0) + WmoLiquid::WmoLiquid(const WmoLiquid &other): iHeight(nullptr), iFlags(nullptr) { *this = other; // use assignment operator... } @@ -135,14 +135,14 @@ namespace VMAP memcpy(iHeight, other.iHeight, (iTilesX+1)*(iTilesY+1)*sizeof(float)); } else - iHeight = 0; + iHeight = nullptr; if (other.iFlags) { iFlags = new uint8[iTilesX * iTilesY]; memcpy(iFlags, other.iFlags, iTilesX * iTilesY); } else - iFlags = 0; + iFlags = nullptr; return *this; } @@ -254,7 +254,7 @@ namespace VMAP GroupModel::GroupModel(const GroupModel &other): iBound(other.iBound), iMogpFlags(other.iMogpFlags), iGroupWMOID(other.iGroupWMOID), - vertices(other.vertices), triangles(other.triangles), meshTree(other.meshTree), iLiquid(0) + vertices(other.vertices), triangles(other.triangles), meshTree(other.meshTree), iLiquid(nullptr) { if (other.iLiquid) iLiquid = new WmoLiquid(*other.iLiquid); @@ -388,7 +388,7 @@ namespace VMAP return false; GModelRayCallback callback(triangles, vertices); Vector3 rPos = pos - 0.1f * down; - float dist = G3D::inf(); + float dist = G3D::finf(); G3D::Ray ray(rPos, down); bool hit = IntersectRay(ray, dist, false); if (hit) @@ -446,7 +446,7 @@ namespace VMAP class WModelAreaCallback { public: WModelAreaCallback(const std::vector<GroupModel> &vals, const Vector3 &down): - prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) { } + prims(vals.begin()), hit(vals.end()), minVol(G3D::finf()), zDist(G3D::finf()), zVec(down) { } std::vector<GroupModel>::const_iterator prims; std::vector<GroupModel>::const_iterator hit; float minVol; diff --git a/src/server/collision/RegularGrid.h b/src/server/collision/RegularGrid.h index d1832c1ea06..6a2a07968ad 100644 --- a/src/server/collision/RegularGrid.h +++ b/src/server/collision/RegularGrid.h @@ -159,8 +159,8 @@ public: //int Cycles = std::max((int)ceilf(max_dist/tMaxX),(int)ceilf(max_dist/tMaxY)); //int i = 0; - float tDeltaX = voxel * fabs(kx_inv); - float tDeltaY = voxel * fabs(ky_inv); + float tDeltaX = voxel * std::fabs(kx_inv); + float tDeltaY = voxel * std::fabs(ky_inv); do { if (Node* node = nodes[cell.x][cell.y]) diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h index f73daa2d720..4b6af3cbdda 100644 --- a/src/server/game/AI/CoreAI/CombatAI.h +++ b/src/server/game/AI/CoreAI/CombatAI.h @@ -30,7 +30,7 @@ class AggressorAI : public CreatureAI public: explicit AggressorAI(Creature* c) : CreatureAI(c) { } - void UpdateAI(uint32); + void UpdateAI(uint32) override; static int Permissible(const Creature*); }; @@ -41,12 +41,12 @@ class CombatAI : public CreatureAI public: explicit CombatAI(Creature* c) : CreatureAI(c) { } - void InitializeAI(); - void Reset(); - void EnterCombat(Unit* who); - void JustDied(Unit* killer); - void UpdateAI(uint32 diff); - void SpellInterrupted(uint32 spellId, uint32 unTimeMs); + void InitializeAI() override; + void Reset() override; + void EnterCombat(Unit* who) override; + void JustDied(Unit* killer) override; + void UpdateAI(uint32 diff) override; + void SpellInterrupted(uint32 spellId, uint32 unTimeMs) override; static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } @@ -59,10 +59,10 @@ class CasterAI : public CombatAI { public: explicit CasterAI(Creature* c) : CombatAI(c) { m_attackDist = MELEE_RANGE; } - void InitializeAI(); - void AttackStart(Unit* victim) { AttackStartCaster(victim, m_attackDist); } - void UpdateAI(uint32 diff); - void EnterCombat(Unit* /*who*/); + void InitializeAI() override; + void AttackStart(Unit* victim) override { AttackStartCaster(victim, m_attackDist); } + void UpdateAI(uint32 diff) override; + void EnterCombat(Unit* /*who*/) override; private: float m_attackDist; }; @@ -71,8 +71,8 @@ struct ArcherAI : public CreatureAI { public: explicit ArcherAI(Creature* c); - void AttackStart(Unit* who); - void UpdateAI(uint32 diff); + void AttackStart(Unit* who) override; + void UpdateAI(uint32 diff) override; static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } @@ -84,9 +84,9 @@ struct TurretAI : public CreatureAI { public: explicit TurretAI(Creature* c); - bool CanAIAttack(Unit const* who) const; - void AttackStart(Unit* who); - void UpdateAI(uint32 diff); + bool CanAIAttack(Unit const* who) const override; + void AttackStart(Unit* who) override; + void UpdateAI(uint32 diff) override; static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } @@ -102,10 +102,10 @@ struct VehicleAI : public CreatureAI public: explicit VehicleAI(Creature* creature); - void UpdateAI(uint32 diff); - void MoveInLineOfSight(Unit*) { } - void AttackStart(Unit*) { } - void OnCharmed(bool apply); + void UpdateAI(uint32 diff) override; + void MoveInLineOfSight(Unit*) override { } + void AttackStart(Unit*) override { } + void OnCharmed(bool apply) override; static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h index 36ca2c3253f..6e03103e269 100644 --- a/src/server/game/AI/CoreAI/GameObjectAI.h +++ b/src/server/game/AI/CoreAI/GameObjectAI.h @@ -68,7 +68,7 @@ class NullGameObjectAI : public GameObjectAI public: explicit NullGameObjectAI(GameObject* g); - void UpdateAI(uint32 /*diff*/) { } + void UpdateAI(uint32 /*diff*/) override { } static int Permissible(GameObject const* /*go*/) { return PERMIT_BASE_IDLE; } }; diff --git a/src/server/game/AI/CoreAI/GuardAI.h b/src/server/game/AI/CoreAI/GuardAI.h index 9af047e8906..c2b05d71e03 100644 --- a/src/server/game/AI/CoreAI/GuardAI.h +++ b/src/server/game/AI/CoreAI/GuardAI.h @@ -29,10 +29,10 @@ class GuardAI : public ScriptedAI explicit GuardAI(Creature* creature); static int Permissible(Creature const* creature); - bool CanSeeAlways(WorldObject const* obj); + bool CanSeeAlways(WorldObject const* obj) override; - void EnterEvadeMode(); - void JustDied(Unit* killer); + void EnterEvadeMode() override; + void JustDied(Unit* killer) override; }; #endif diff --git a/src/server/game/AI/CoreAI/PassiveAI.cpp b/src/server/game/AI/CoreAI/PassiveAI.cpp index 07987cf8cec..3ae73636619 100644 --- a/src/server/game/AI/CoreAI/PassiveAI.cpp +++ b/src/server/game/AI/CoreAI/PassiveAI.cpp @@ -75,5 +75,5 @@ void CritterAI::EnterEvadeMode() void TriggerAI::IsSummonedBy(Unit* summoner) { if (me->m_spells[0]) - me->CastSpell(me, me->m_spells[0], false, 0, 0, summoner->GetGUID()); + me->CastSpell(me, me->m_spells[0], false, nullptr, nullptr, summoner->GetGUID()); } diff --git a/src/server/game/AI/CoreAI/PassiveAI.h b/src/server/game/AI/CoreAI/PassiveAI.h index 33bfde4f9f2..7f5ab5f29a2 100644 --- a/src/server/game/AI/CoreAI/PassiveAI.h +++ b/src/server/game/AI/CoreAI/PassiveAI.h @@ -26,9 +26,9 @@ class PassiveAI : public CreatureAI public: explicit PassiveAI(Creature* c); - void MoveInLineOfSight(Unit*) { } - void AttackStart(Unit*) { } - void UpdateAI(uint32); + void MoveInLineOfSight(Unit*) override { } + void AttackStart(Unit*) override { } + void UpdateAI(uint32) override; static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; } }; @@ -38,13 +38,13 @@ class PossessedAI : public CreatureAI public: explicit PossessedAI(Creature* c); - void MoveInLineOfSight(Unit*) { } - void AttackStart(Unit* target); - void UpdateAI(uint32); - void EnterEvadeMode() { } + void MoveInLineOfSight(Unit*) override { } + void AttackStart(Unit* target) override; + void UpdateAI(uint32) override; + void EnterEvadeMode() override { } - void JustDied(Unit*); - void KilledUnit(Unit* victim); + void JustDied(Unit*) override; + void KilledUnit(Unit* victim) override; static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; } }; @@ -54,11 +54,11 @@ class NullCreatureAI : public CreatureAI public: explicit NullCreatureAI(Creature* c); - void MoveInLineOfSight(Unit*) { } - void AttackStart(Unit*) { } - void UpdateAI(uint32) { } - void EnterEvadeMode() { } - void OnCharmed(bool /*apply*/) { } + void MoveInLineOfSight(Unit*) override { } + void AttackStart(Unit*) override { } + void UpdateAI(uint32) override { } + void EnterEvadeMode() override { } + void OnCharmed(bool /*apply*/) override { } static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; } }; @@ -68,15 +68,15 @@ class CritterAI : public PassiveAI public: explicit CritterAI(Creature* c) : PassiveAI(c) { } - void DamageTaken(Unit* done_by, uint32& /*damage*/); - void EnterEvadeMode(); + void DamageTaken(Unit* done_by, uint32& /*damage*/) override; + void EnterEvadeMode() override; }; class TriggerAI : public NullCreatureAI { public: explicit TriggerAI(Creature* c) : NullCreatureAI(c) { } - void IsSummonedBy(Unit* summoner); + void IsSummonedBy(Unit* summoner) override; }; #endif diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index 8032568434f..603c34e2403 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -236,7 +236,7 @@ void PetAI::UpdateAI(uint32 diff) SpellCastTargets targets; targets.SetUnitTarget(target); - if (!me->HasInArc(M_PI, target)) + if (!me->HasInArc(float(M_PI), target)) { me->SetInFront(target); if (target && target->GetTypeId() == TYPEID_PLAYER) @@ -246,8 +246,6 @@ void PetAI::UpdateAI(uint32 diff) me->SendUpdateToPlayer(owner->ToPlayer()); } - me->AddCreatureSpellCooldown(spell->m_spellInfo->Id); - spell->prepare(&targets); } diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h index 450f68443f0..c24bf3a0c1b 100644 --- a/src/server/game/AI/CoreAI/PetAI.h +++ b/src/server/game/AI/CoreAI/PetAI.h @@ -31,23 +31,23 @@ class PetAI : public CreatureAI explicit PetAI(Creature* c); - void UpdateAI(uint32); + void UpdateAI(uint32) override; static int Permissible(const Creature*); - void KilledUnit(Unit* /*victim*/); - void AttackStart(Unit* target); - void MovementInform(uint32 moveType, uint32 data); - void OwnerAttackedBy(Unit* attacker); - void OwnerAttacked(Unit* target); - void AttackedBy(Unit* attacker); - void ReceiveEmote(Player* player, uint32 textEmote); + void KilledUnit(Unit* /*victim*/) override; + void AttackStart(Unit* target) override; + void MovementInform(uint32 moveType, uint32 data) override; + void OwnerAttackedBy(Unit* attacker) override; + void OwnerAttacked(Unit* target) override; + void AttackedBy(Unit* attacker) override; + void ReceiveEmote(Player* player, uint32 textEmote) override; // The following aren't used by the PetAI but need to be defined to override // default CreatureAI functions which interfere with the PetAI // - void MoveInLineOfSight(Unit* /*who*/) { } // CreatureAI interferes with returning pets + void MoveInLineOfSight(Unit* /*who*/) override { } // CreatureAI interferes with returning pets void MoveInLineOfSight_Safe(Unit* /*who*/) { } // CreatureAI interferes with returning pets - void EnterEvadeMode() { } // For fleeing, pets don't use this type of Evade mechanic + void EnterEvadeMode() override { } // For fleeing, pets don't use this type of Evade mechanic private: bool _isVisible(Unit*) const; diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h index 417944f9ba2..2fdccac802d 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.h +++ b/src/server/game/AI/CoreAI/ReactorAI.h @@ -29,8 +29,8 @@ class ReactorAI : public CreatureAI explicit ReactorAI(Creature* c) : CreatureAI(c) { } - void MoveInLineOfSight(Unit*) { } - void UpdateAI(uint32 diff); + void MoveInLineOfSight(Unit*) override { } + void UpdateAI(uint32 diff) override; static int Permissible(const Creature*); }; diff --git a/src/server/game/AI/CoreAI/TotemAI.h b/src/server/game/AI/CoreAI/TotemAI.h index 4d5f03566ba..93106b91492 100644 --- a/src/server/game/AI/CoreAI/TotemAI.h +++ b/src/server/game/AI/CoreAI/TotemAI.h @@ -31,11 +31,11 @@ class TotemAI : public CreatureAI explicit TotemAI(Creature* c); - void MoveInLineOfSight(Unit* who); - void AttackStart(Unit* victim); - void EnterEvadeMode(); + void MoveInLineOfSight(Unit* who) override; + void AttackStart(Unit* victim) override; + void EnterEvadeMode() override; - void UpdateAI(uint32 diff); + void UpdateAI(uint32 diff) override; static int Permissible(Creature const* creature); private: diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index 6ca79dc0a49..b6743b572cb 100644 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -275,13 +275,13 @@ class PlayerAI : public UnitAI public: explicit PlayerAI(Player* player) : UnitAI((Unit*)player), me(player) { } - void OnCharmed(bool apply); + void OnCharmed(bool apply) override; }; class SimpleCharmedAI : public PlayerAI { public: - void UpdateAI(uint32 diff); + void UpdateAI(uint32 diff) override; SimpleCharmedAI(Player* player): PlayerAI(player) { } }; diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 209995d359d..b79dd6abbc8 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -127,7 +127,7 @@ class CreatureAI : public UnitAI // Called at waypoint reached or point movement finished virtual void MovementInform(uint32 /*type*/, uint32 /*id*/) { } - void OnCharmed(bool apply); + void OnCharmed(bool apply) override; // Called at reaching home after evade virtual void JustReachedHome() { } diff --git a/src/server/game/AI/CreatureAIFactory.h b/src/server/game/AI/CreatureAIFactory.h index f2854f1a9ce..61e3cd2b240 100644 --- a/src/server/game/AI/CreatureAIFactory.h +++ b/src/server/game/AI/CreatureAIFactory.h @@ -34,9 +34,9 @@ struct CreatureAIFactory : public SelectableAI { CreatureAIFactory(const char* name) : SelectableAI(name) { } - CreatureAI* Create(void*) const; + CreatureAI* Create(void*) const override; - int Permit(const Creature* c) const { return REAL_AI::Permissible(c); } + int Permit(const Creature* c) const override { return REAL_AI::Permissible(c); } }; template<class REAL_AI> @@ -61,9 +61,9 @@ struct GameObjectAIFactory : public SelectableGameObjectAI { GameObjectAIFactory(const char* name) : SelectableGameObjectAI(name) { } - GameObjectAI* Create(void*) const; + GameObjectAI* Create(void*) const override; - int Permit(const GameObject* g) const { return REAL_GO_AI::Permissible(g); } + int Permit(const GameObject* g) const override { return REAL_GO_AI::Permissible(g); } }; template<class REAL_GO_AI> diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp index afbd306c184..3643bccdb6f 100644 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -68,7 +68,7 @@ namespace FactorySelector else ai_factory = ai_registry.GetRegistryItem("NullCreatureAI"); } - else if (creature->GetCreatureType() == CREATURE_TYPE_CRITTER && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) + else if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) ai_factory = ai_registry.GetRegistryItem("CritterAI"); } diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index e03bbd8c6a2..6213f559319 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -25,6 +25,15 @@ #include "InstanceScript.h" #define CAST_AI(a, b) (dynamic_cast<a*>(b)) +#define ENSURE_AI(a,b) (EnsureAI<a>(b)) + +template<class T, class U> +T* EnsureAI(U* ai) +{ + T* cast_ai = dynamic_cast<T*>(ai); + ASSERT(cast_ai); + return cast_ai; +}; class InstanceScript; @@ -141,31 +150,31 @@ struct ScriptedAI : public CreatureAI void AttackStartNoMove(Unit* target); // Called at any Damage from any attacker (before damage apply) - void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) { } + void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override { } //Called at World update tick - virtual void UpdateAI(uint32 diff); + virtual void UpdateAI(uint32 diff) override; //Called at creature death - void JustDied(Unit* /*killer*/) { } + void JustDied(Unit* /*killer*/) override { } //Called at creature killing another unit - void KilledUnit(Unit* /*victim*/) { } + void KilledUnit(Unit* /*victim*/) override { } // Called when the creature summon successfully other creature - void JustSummoned(Creature* /*summon*/) { } + void JustSummoned(Creature* /*summon*/) override { } // Called when a summoned creature is despawned - void SummonedCreatureDespawn(Creature* /*summon*/) { } + void SummonedCreatureDespawn(Creature* /*summon*/) override { } // Called when hit by a spell - void SpellHit(Unit* /*caster*/, SpellInfo const* /*spell*/) { } + void SpellHit(Unit* /*caster*/, SpellInfo const* /*spell*/) override { } // Called when spell hits a target - void SpellHitTarget(Unit* /*target*/, SpellInfo const* /*spell*/) { } + void SpellHitTarget(Unit* /*target*/, SpellInfo const* /*spell*/) override { } //Called at waypoint reached or PointMovement end - void MovementInform(uint32 /*type*/, uint32 /*id*/) { } + void MovementInform(uint32 /*type*/, uint32 /*id*/) override { } // Called when AI is temporarily replaced or put back when possess is applied or removed void OnPossess(bool /*apply*/) { } @@ -185,13 +194,13 @@ struct ScriptedAI : public CreatureAI // ************* //Called at creature reset either by death or evade - void Reset() { } + void Reset() override { } //Called at creature aggro either by MoveInLOS or Attack Start - void EnterCombat(Unit* /*victim*/) { } + void EnterCombat(Unit* /*victim*/) override { } // Called before EnterCombat even before the creature is in combat. - void AttackStart(Unit* /*target*/); + void AttackStart(Unit* /*target*/) override; // ************* //AI Helper Functions @@ -339,10 +348,10 @@ class BossAI : public ScriptedAI InstanceScript* const instance; BossBoundaryMap const* GetBoundary() const { return _boundary; } - void JustSummoned(Creature* summon); - void SummonedCreatureDespawn(Creature* summon); + void JustSummoned(Creature* summon) override; + void SummonedCreatureDespawn(Creature* summon) override; - virtual void UpdateAI(uint32 diff); + virtual void UpdateAI(uint32 diff) override; // Hook used to execute events scheduled into EventMap without the need // to override UpdateAI @@ -350,10 +359,10 @@ class BossAI : public ScriptedAI // is supposed to run more than once virtual void ExecuteEvent(uint32 /*eventId*/) { } - void Reset() { _Reset(); } - void EnterCombat(Unit* /*who*/) { _EnterCombat(); } - void JustDied(Unit* /*killer*/) { _JustDied(); } - void JustReachedHome() { _JustReachedHome(); } + void Reset() override { _Reset(); } + void EnterCombat(Unit* /*who*/) override { _EnterCombat(); } + void JustDied(Unit* /*killer*/) override { _JustDied(); } + void JustReachedHome() override { _JustReachedHome(); } protected: void _Reset(); @@ -388,10 +397,10 @@ class WorldBossAI : public ScriptedAI WorldBossAI(Creature* creature); virtual ~WorldBossAI() { } - void JustSummoned(Creature* summon); - void SummonedCreatureDespawn(Creature* summon); + void JustSummoned(Creature* summon) override; + void SummonedCreatureDespawn(Creature* summon) override; - virtual void UpdateAI(uint32 diff); + virtual void UpdateAI(uint32 diff) override; // Hook used to execute events scheduled into EventMap without the need // to override UpdateAI @@ -399,9 +408,9 @@ class WorldBossAI : public ScriptedAI // is supposed to run more than once virtual void ExecuteEvent(uint32 /*eventId*/) { } - void Reset() { _Reset(); } - void EnterCombat(Unit* /*who*/) { _EnterCombat(); } - void JustDied(Unit* /*killer*/) { _JustDied(); } + void Reset() override { _Reset(); } + void EnterCombat(Unit* /*who*/) override { _EnterCombat(); } + void JustDied(Unit* /*killer*/) override { _JustDied(); } protected: void _Reset(); diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h index 177810bbbfd..b8c9ee57aeb 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h @@ -56,22 +56,22 @@ struct npc_escortAI : public ScriptedAI ~npc_escortAI() { } // CreatureAI functions - void AttackStart(Unit* who); + void AttackStart(Unit* who) override; - void MoveInLineOfSight(Unit* who); + void MoveInLineOfSight(Unit* who) override; - void JustDied(Unit*); + void JustDied(Unit*) override; - void JustRespawned(); + void JustRespawned() override; void ReturnToLastPoint(); - void EnterEvadeMode(); + void EnterEvadeMode() override; - void UpdateAI(uint32 diff); //the "internal" update, calls UpdateEscortAI() + void UpdateAI(uint32 diff) override; //the "internal" update, calls UpdateEscortAI() virtual void UpdateEscortAI(uint32 const diff); //used when it's needed to add code in update (abilities, scripted events, etc) - void MovementInform(uint32, uint32); + void MovementInform(uint32, uint32) override; // EscortAI functions void AddWaypoint(uint32 id, float x, float y, float z, uint32 waitTime = 0); // waitTime is in ms @@ -94,7 +94,7 @@ struct npc_escortAI : public ScriptedAI void SetEscortPaused(bool on); bool HasEscortState(uint32 escortState) { return (m_uiEscortState & escortState) != 0; } - virtual bool IsEscorted() { return (m_uiEscortState & STATE_ESCORT_ESCORTING); } + virtual bool IsEscorted() override { return (m_uiEscortState & STATE_ESCORT_ESCORTING); } void SetMaxPlayerDistance(float newMax) { MaxPlayerDistance = newMax; } float GetMaxPlayerDistance() { return MaxPlayerDistance; } diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h index af7508441b9..adb17ef76b1 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h @@ -40,19 +40,19 @@ class FollowerAI : public ScriptedAI //virtual void WaypointReached(uint32 uiPointId) = 0; - void MovementInform(uint32 motionType, uint32 pointId); + void MovementInform(uint32 motionType, uint32 pointId) override; - void AttackStart(Unit*); + void AttackStart(Unit*) override; - void MoveInLineOfSight(Unit*); + void MoveInLineOfSight(Unit*) override; - void EnterEvadeMode(); + void EnterEvadeMode() override; - void JustDied(Unit*); + void JustDied(Unit*) override; - void JustRespawned(); + void JustRespawned() override; - void UpdateAI(uint32); //the "internal" update, calls UpdateFollowerAI() + void UpdateAI(uint32) override; //the "internal" update, calls UpdateFollowerAI() virtual void UpdateFollowerAI(uint32); //used when it's needed to add code in update (abilities, scripted events, etc) void StartFollow(Player* player, uint32 factionForFollower = 0, const Quest* quest = NULL); diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index af47b52f500..41f783f4289 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -931,7 +931,7 @@ class SmartTrigger : public AreaTriggerScript SmartTrigger() : AreaTriggerScript("SmartTrigger") { } - bool OnTrigger(Player* player, AreaTriggerEntry const* trigger) + bool OnTrigger(Player* player, AreaTriggerEntry const* trigger) override { if (!player->IsAlive()) return false; diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 4d66b976746..e674bbfdaac 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -70,94 +70,94 @@ class SmartAI : public CreatureAI bool IsEscortInvokerInRange(); // Called when creature is spawned or respawned - void JustRespawned(); + void JustRespawned() override; // Called at reaching home after evade, InitializeAI(), EnterEvadeMode() for resetting variables - void JustReachedHome(); + void JustReachedHome() override; // Called for reaction at enter to combat if not in combat yet (enemy can be NULL) - void EnterCombat(Unit* enemy); + void EnterCombat(Unit* enemy) override; // Called for reaction at stopping attack at no attackers or targets - void EnterEvadeMode(); + void EnterEvadeMode() override; // Called when the creature is killed - void JustDied(Unit* killer); + void JustDied(Unit* killer) override; // Called when the creature kills a unit - void KilledUnit(Unit* victim); + void KilledUnit(Unit* victim) override; // Called when the creature summon successfully other creature - void JustSummoned(Creature* creature); + void JustSummoned(Creature* creature) override; // Tell creature to attack and follow the victim - void AttackStart(Unit* who); + void AttackStart(Unit* who) override; // Called if IsVisible(Unit* who) is true at each *who move, reaction at visibility zone enter - void MoveInLineOfSight(Unit* who); + void MoveInLineOfSight(Unit* who) override; // Called when hit by a spell - void SpellHit(Unit* unit, const SpellInfo* spellInfo); + void SpellHit(Unit* unit, const SpellInfo* spellInfo) override; // Called when spell hits a target - void SpellHitTarget(Unit* target, const SpellInfo* spellInfo); + void SpellHitTarget(Unit* target, const SpellInfo* spellInfo) override; // Called at any Damage from any attacker (before damage apply) - void DamageTaken(Unit* doneBy, uint32& damage); + void DamageTaken(Unit* doneBy, uint32& damage) override; // Called when the creature receives heal - void HealReceived(Unit* doneBy, uint32& addhealth); + void HealReceived(Unit* doneBy, uint32& addhealth) override; // Called at World update tick - void UpdateAI(uint32 diff); + void UpdateAI(uint32 diff) override; // Called at text emote receive from player - void ReceiveEmote(Player* player, uint32 textEmote); + void ReceiveEmote(Player* player, uint32 textEmote) override; // Called at waypoint reached or point movement finished - void MovementInform(uint32 MovementType, uint32 Data); + void MovementInform(uint32 MovementType, uint32 Data) override; // Called when creature is summoned by another unit - void IsSummonedBy(Unit* summoner); + void IsSummonedBy(Unit* summoner) override; // Called at any Damage to any victim (before damage apply) - void DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType /*damagetype*/); + void DamageDealt(Unit* doneTo, uint32& damage, DamageEffectType /*damagetype*/) override; // Called when a summoned creature dissapears (UnSommoned) - void SummonedCreatureDespawn(Creature* unit); + void SummonedCreatureDespawn(Creature* unit) override; // called when the corpse of this creature gets removed - void CorpseRemoved(uint32& respawnDelay); + void CorpseRemoved(uint32& respawnDelay) override; // Called at World update tick if creature is charmed void UpdateAIWhileCharmed(const uint32 diff); // Called when a Player/Creature enters the creature (vehicle) - void PassengerBoarded(Unit* who, int8 seatId, bool apply); + void PassengerBoarded(Unit* who, int8 seatId, bool apply) override; // Called when gets initialized, when creature is added to world - void InitializeAI(); + void InitializeAI() override; // Called when creature gets charmed by another unit - void OnCharmed(bool apply); + void OnCharmed(bool apply) override; // Called when victim is in line of sight - bool CanAIAttack(const Unit* who) const; + bool CanAIAttack(const Unit* who) const override; // Used in scripts to share variables - void DoAction(int32 param = 0); + void DoAction(int32 param = 0) override; // Used in scripts to share variables - uint32 GetData(uint32 id = 0) const; + uint32 GetData(uint32 id = 0) const override; // Used in scripts to share variables - void SetData(uint32 id, uint32 value); + void SetData(uint32 id, uint32 value) override; // Used in scripts to share variables - void SetGUID(uint64 guid, int32 id = 0); + void SetGUID(uint64 guid, int32 id = 0) override; // Used in scripts to share variables - uint64 GetGUID(int32 id = 0) const; + uint64 GetGUID(int32 id = 0) const override; //core related static int Permissible(const Creature*); @@ -174,15 +174,15 @@ class SmartAI : public CreatureAI void SetInvincibilityHpLevel(uint32 level) { mInvincibilityHpLevel = level; } - void sGossipHello(Player* player); - void sGossipSelect(Player* player, uint32 sender, uint32 action); - void sGossipSelectCode(Player* player, uint32 sender, uint32 action, const char* code); - void sQuestAccept(Player* player, Quest const* quest); + void sGossipHello(Player* player) override; + void sGossipSelect(Player* player, uint32 sender, uint32 action) override; + void sGossipSelectCode(Player* player, uint32 sender, uint32 action, const char* code) override; + void sQuestAccept(Player* player, Quest const* quest) override; //void sQuestSelect(Player* player, Quest const* quest); //void sQuestComplete(Player* player, Quest const* quest); - void sQuestReward(Player* player, Quest const* quest, uint32 opt); - bool sOnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex); - void sOnGameEvent(bool start, uint16 eventId); + void sQuestReward(Player* player, Quest const* quest, uint32 opt) override; + bool sOnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex) override; + void sOnGameEvent(bool start, uint16 eventId) override; uint32 mEscortQuestID; @@ -193,7 +193,7 @@ class SmartAI : public CreatureAI } void StartDespawn() { mDespawnState = 2; } - void OnSpellClick(Unit* clicker, bool& result); + void OnSpellClick(Unit* clicker, bool& result) override; private: uint32 mFollowCreditType; @@ -237,23 +237,23 @@ class SmartGameObjectAI : public GameObjectAI SmartGameObjectAI(GameObject* g) : GameObjectAI(g) { } ~SmartGameObjectAI() { } - void UpdateAI(uint32 diff); - void InitializeAI(); - void Reset(); + void UpdateAI(uint32 diff) override; + void InitializeAI() override; + void Reset() override; SmartScript* GetScript() { return &mScript; } static int Permissible(const GameObject* g); - bool GossipHello(Player* player); - bool GossipSelect(Player* player, uint32 sender, uint32 action); - bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/); - bool QuestAccept(Player* player, Quest const* quest); - bool QuestReward(Player* player, Quest const* quest, uint32 opt); - void Destroyed(Player* player, uint32 eventId); - void SetData(uint32 id, uint32 value); + bool GossipHello(Player* player) override; + bool GossipSelect(Player* player, uint32 sender, uint32 action) override; + bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) override; + bool QuestAccept(Player* player, Quest const* quest) override; + bool QuestReward(Player* player, Quest const* quest, uint32 opt) override; + void Destroyed(Player* player, uint32 eventId) override; + void SetData(uint32 id, uint32 value) override; void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker); - void OnGameEvent(bool start, uint16 eventId); - void OnStateChanged(uint32 state, Unit* unit); - void EventInform(uint32 eventId); + void OnGameEvent(bool start, uint16 eventId) override; + void OnStateChanged(uint32 state, Unit* unit) override; + void EventInform(uint32 eventId) override; private: SmartScript mScript; diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index d4b41f529a9..58e82bfcbbf 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -477,7 +477,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (IsPlayer(*itr)) { - (*itr)->ToPlayer()->AreaExploredOrEventHappens(e.action.quest.quest); + (*itr)->ToPlayer()->GroupEventHappens(e.action.quest.quest, me); + TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: Player guidLow %u credited quest %u", (*itr)->GetGUIDLow(), e.action.quest.quest); } @@ -519,7 +520,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u mana < spellInfo->CalcPowerCost(me, spellInfo->GetSchoolMask())) _allowMove = true; - CAST_AI(SmartAI, me->AI())->SetCombatMove(_allowMove); + ENSURE_AI(SmartAI, me->AI())->SetCombatMove(_allowMove); } me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0); @@ -707,7 +708,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!IsSmart()) break; - CAST_AI(SmartAI, me->AI())->SetAutoAttack(e.action.autoAttack.attack != 0); + ENSURE_AI(SmartAI, me->AI())->SetAutoAttack(e.action.autoAttack.attack != 0); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_AUTO_ATTACK: Creature: %u bool on = %u", me->GetGUIDLow(), e.action.autoAttack.attack); break; @@ -718,7 +719,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; bool move = e.action.combatMove.move != 0; - CAST_AI(SmartAI, me->AI())->SetCombatMove(move); + ENSURE_AI(SmartAI, me->AI())->SetCombatMove(move); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ALLOW_COMBAT_MOVEMENT: Creature %u bool on = %u", me->GetGUIDLow(), e.action.combatMove.move); break; @@ -817,7 +818,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u ObjectList* targets = GetTargets(e, unit); if (!targets) { - CAST_AI(SmartAI, me->AI())->StopFollow(); + ENSURE_AI(SmartAI, me->AI())->StopFollow(); break; } @@ -825,7 +826,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { if (IsUnit(*itr)) { - CAST_AI(SmartAI, me->AI())->SetFollow((*itr)->ToUnit(), (float)e.action.follow.dist, (float)e.action.follow.angle, e.action.follow.credit, e.action.follow.entry, e.action.follow.creditType); + ENSURE_AI(SmartAI, me->AI())->SetFollow((*itr)->ToUnit(), (float)e.action.follow.dist, (float)e.action.follow.angle, e.action.follow.credit, e.action.follow.entry, e.action.follow.creditType); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_FOLLOW: Creature %u following target %u", me->GetGUIDLow(), (*itr)->GetGUIDLow()); break; @@ -1035,8 +1036,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if ((*itr)->ToUnit()->IsAlive() && IsSmart((*itr)->ToCreature())) { - CAST_AI(SmartAI, (*itr)->ToCreature()->AI())->SetDespawnTime(e.action.forceDespawn.delay + 1); // Next tick - CAST_AI(SmartAI, (*itr)->ToCreature()->AI())->StartDespawn(); + ENSURE_AI(SmartAI, (*itr)->ToCreature()->AI())->SetDespawnTime(e.action.forceDespawn.delay + 1); // Next tick + ENSURE_AI(SmartAI, (*itr)->ToCreature()->AI())->StartDespawn(); } else (*itr)->ToCreature()->DespawnOrUnsummon(e.action.forceDespawn.delay); @@ -1331,7 +1332,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!IsSmart()) break; - CAST_AI(SmartAI, me->AI())->SetFly(e.action.setFly.fly != 0); + ENSURE_AI(SmartAI, me->AI())->SetFly(e.action.setFly.fly != 0); break; } case SMART_ACTION_SET_RUN: @@ -1339,7 +1340,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!IsSmart()) break; - CAST_AI(SmartAI, me->AI())->SetRun(e.action.setRun.run != 0); + ENSURE_AI(SmartAI, me->AI())->SetRun(e.action.setRun.run != 0); break; } case SMART_ACTION_SET_SWIM: @@ -1347,7 +1348,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!IsSmart()) break; - CAST_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim != 0); + ENSURE_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim != 0); break; } case SMART_ACTION_WP_START: @@ -1361,12 +1362,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u ObjectList* targets = GetTargets(e, unit); StoreTargetList(targets, SMART_ESCORT_TARGETS); me->SetReactState((ReactStates)e.action.wpStart.reactState); - CAST_AI(SmartAI, me->AI())->StartPath(run, entry, repeat, unit); + ENSURE_AI(SmartAI, me->AI())->StartPath(run, entry, repeat, unit); uint32 quest = e.action.wpStart.quest; uint32 DespawnTime = e.action.wpStart.despawnTime; - CAST_AI(SmartAI, me->AI())->mEscortQuestID = quest; - CAST_AI(SmartAI, me->AI())->SetDespawnTime(DespawnTime); + ENSURE_AI(SmartAI, me->AI())->mEscortQuestID = quest; + ENSURE_AI(SmartAI, me->AI())->SetDespawnTime(DespawnTime); break; } case SMART_ACTION_WP_PAUSE: @@ -1375,7 +1376,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; uint32 delay = e.action.wpPause.delay; - CAST_AI(SmartAI, me->AI())->PausePath(delay, e.GetEventType() == SMART_EVENT_WAYPOINT_REACHED ? false : true); + ENSURE_AI(SmartAI, me->AI())->PausePath(delay, e.GetEventType() == SMART_EVENT_WAYPOINT_REACHED ? false : true); break; } case SMART_ACTION_WP_STOP: @@ -1386,7 +1387,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u uint32 DespawnTime = e.action.wpStop.despawnTime; uint32 quest = e.action.wpStop.quest; bool fail = e.action.wpStop.fail != 0; - CAST_AI(SmartAI, me->AI())->StopPath(DespawnTime, quest, fail); + ENSURE_AI(SmartAI, me->AI())->StopPath(DespawnTime, quest, fail); break; } case SMART_ACTION_WP_RESUME: @@ -1394,7 +1395,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!IsSmart()) break; - CAST_AI(SmartAI, me->AI())->ResumePath(); + ENSURE_AI(SmartAI, me->AI())->ResumePath(); break; } case SMART_ACTION_SET_ORIENTATION: @@ -1622,7 +1623,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; float attackDistance = float(e.action.setRangedMovement.distance); - float attackAngle = float(e.action.setRangedMovement.angle) / 180.0f * M_PI; + float attackAngle = float(e.action.setRangedMovement.angle) / 180.0f * float(M_PI); ObjectList* targets = GetTargets(e, unit); if (targets) @@ -1630,7 +1631,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) if (Creature* target = (*itr)->ToCreature()) if (IsSmart(target) && target->GetVictim()) - if (CAST_AI(SmartAI, target->AI())->CanCombatMove()) + if (ENSURE_AI(SmartAI, target->AI())->CanCombatMove()) target->GetMotionMaster()->MoveChase(target->GetVictim(), attackDistance, attackAngle); delete targets; @@ -1652,12 +1653,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (Creature* target = (*itr)->ToCreature()) { if (IsSmart(target)) - CAST_AI(SmartAI, target->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker()); + ENSURE_AI(SmartAI, target->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker()); } else if (GameObject* goTarget = (*itr)->ToGameObject()) { if (IsSmartGO(goTarget)) - CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker()); + ENSURE_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker()); } } @@ -1788,12 +1789,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (Creature* target = (*itr)->ToCreature()) { if (IsSmart(target)) - CAST_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker()); + ENSURE_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker()); } else if (GameObject* goTarget = (*itr)->ToGameObject()) { if (IsSmartGO(goTarget)) - CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker()); + ENSURE_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker()); } } @@ -1818,12 +1819,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (Creature* target = (*itr)->ToCreature()) { if (IsSmart(target)) - CAST_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker()); + ENSURE_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker()); } else if (GameObject* goTarget = (*itr)->ToGameObject()) { if (IsSmartGO(goTarget)) - CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker()); + ENSURE_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker()); } } @@ -3223,7 +3224,7 @@ void SmartScript::InitTimer(SmartScriptHolder& e) void SmartScript::RecalcTimer(SmartScriptHolder& e, uint32 min, uint32 max) { // min/max was checked at loading! - e.timer = urand(uint32(min), uint32(max)); + e.timer = urand(min, max); e.active = e.timer ? false : true; } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index f09e16268c1..e5abc876648 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1421,7 +1421,7 @@ class SmartWaypointMgr { if (waypoint_map.find(id) != waypoint_map.end()) return waypoint_map[id]; - else return 0; + else return nullptr; } private: diff --git a/src/server/game/Accounts/BattlenetAccountMgr.cpp b/src/server/game/Accounts/BattlenetAccountMgr.cpp index 23c1b7cdd61..da71f02d7d2 100644 --- a/src/server/game/Accounts/BattlenetAccountMgr.cpp +++ b/src/server/game/Accounts/BattlenetAccountMgr.cpp @@ -126,26 +126,3 @@ std::string Battlenet::AccountMgr::CalculateShaPassHash(std::string const& name, return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength(), true); } - -bool Battlenet::AccountMgr::GetAccountIdAndIndex(std::string const& account, uint32* battlenetAccountId, uint8* battlenetAccountIndex) -{ - Tokenizer tokens(account, '#'); - if (tokens.size() != 2) - return false; - - if (!battlenetAccountId) - return false; - - *battlenetAccountId = atol(tokens[0]); - if (!*battlenetAccountId) - return false; - - if (battlenetAccountIndex) - { - *battlenetAccountIndex = atol(tokens[1]); - if (!*battlenetAccountIndex) - return false; - } - - return true; -} diff --git a/src/server/game/Accounts/BattlenetAccountMgr.h b/src/server/game/Accounts/BattlenetAccountMgr.h index c41a54189e5..1e0b7b78a99 100644 --- a/src/server/game/Accounts/BattlenetAccountMgr.h +++ b/src/server/game/Accounts/BattlenetAccountMgr.h @@ -38,7 +38,6 @@ namespace Battlenet uint32 GetIdByGameAccount(uint32 gameAccountId); std::string CalculateShaPassHash(std::string const& name, std::string const& password); - bool GetAccountIdAndIndex(std::string const& account, uint32* battlenetAccountId, uint8* battlenetAccountIndex); } } diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index d7cde6d1794..25f7edd35d7 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -427,8 +427,8 @@ enum RBACPermissions RBAC_PERM_COMMAND_REPAIRITEMS = 521, RBAC_PERM_COMMAND_RESPAWN = 522, RBAC_PERM_COMMAND_REVIVE = 523, - RBAC_PERM_COMMAND_SAVE = 524, - RBAC_PERM_COMMAND_SAVEALL = 525, + RBAC_PERM_COMMAND_SAVEALL = 524, + RBAC_PERM_COMMAND_SAVE = 525, RBAC_PERM_COMMAND_SETSKILL = 526, RBAC_PERM_COMMAND_SHOWAREA = 527, RBAC_PERM_COMMAND_SUMMON = 528, @@ -549,10 +549,10 @@ enum RBACPermissions RBAC_PERM_COMMAND_RELOAD_EVENT_SCRIPTS = 643, RBAC_PERM_COMMAND_RELOAD_FISHING_LOOT_TEMPLATE = 644, RBAC_PERM_COMMAND_RELOAD_GAME_GRAVEYARD_ZONE = 645, - RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTENDER = 646, - RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUEST_LOOT_TEMPLATE = 647, - RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTSTARTER = 648, - RBAC_PERM_COMMAND_RELOAD_GAME_TELE = 649, + RBAC_PERM_COMMAND_RELOAD_GAME_TELE = 646, + RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTENDER = 647, + RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUEST_LOOT_TEMPLATE = 648, + RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTSTARTER = 649, RBAC_PERM_COMMAND_RELOAD_GM_TICKETS = 650, RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU = 651, RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU_OPTION = 652, @@ -585,34 +585,34 @@ enum RBACPermissions RBAC_PERM_COMMAND_RELOAD_QUEST_TEMPLATE = 679, RBAC_PERM_COMMAND_RELOAD_RBAC = 680, RBAC_PERM_COMMAND_RELOAD_REFERENCE_LOOT_TEMPLATE = 681, - RBAC_PERM_COMMAND_RELOAD_REPUTATION_REWARD_RATE = 682, - RBAC_PERM_COMMAND_RELOAD_RESERVED_NAME = 683, - RBAC_PERM_COMMAND_RELOAD_SKILL_DISCOVERY_TEMPLATE = 684, - RBAC_PERM_COMMAND_RELOAD_SKILL_EXTRA_ITEM_TEMPLATE = 685, - RBAC_PERM_COMMAND_RELOAD_SKILL_FISHING_BASE_LEVEL = 686, - RBAC_PERM_COMMAND_RELOAD_SKINNING_LOOT_TEMPLATE = 687, - RBAC_PERM_COMMAND_RELOAD_SMART_SCRIPTS = 688, - RBAC_PERM_COMMAND_RELOAD_SPELL_AREA = 689, - RBAC_PERM_COMMAND_RELOAD_SPELL_BONUS_DATA = 690, - RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP = 691, - RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP_STACK_RULES = 692, - RBAC_PERM_COMMAND_RELOAD_SPELL_LEARN_SPELL = 693, - RBAC_PERM_COMMAND_RELOAD_SPELL_LINKED_SPELL = 694, + RBAC_PERM_COMMAND_RELOAD_RESERVED_NAME = 682, + RBAC_PERM_COMMAND_RELOAD_REPUTATION_REWARD_RATE = 683, + RBAC_PERM_COMMAND_RELOAD_SPILLOVER_TEMPLATE = 684, + RBAC_PERM_COMMAND_RELOAD_SKILL_DISCOVERY_TEMPLATE = 685, + RBAC_PERM_COMMAND_RELOAD_SKILL_EXTRA_ITEM_TEMPLATE = 686, + RBAC_PERM_COMMAND_RELOAD_SKILL_FISHING_BASE_LEVEL = 687, + RBAC_PERM_COMMAND_RELOAD_SKINNING_LOOT_TEMPLATE = 688, + RBAC_PERM_COMMAND_RELOAD_SMART_SCRIPTS = 689, + RBAC_PERM_COMMAND_RELOAD_SPELL_REQUIRED = 690, + RBAC_PERM_COMMAND_RELOAD_SPELL_AREA = 691, + RBAC_PERM_COMMAND_RELOAD_SPELL_BONUS_DATA = 692, + RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP = 693, + RBAC_PERM_COMMAND_RELOAD_SPELL_LEARN_SPELL = 694, RBAC_PERM_COMMAND_RELOAD_SPELL_LOOT_TEMPLATE = 695, - RBAC_PERM_COMMAND_RELOAD_SPELL_PET_AURAS = 696, - RBAC_PERM_COMMAND_RELOAD_SPELL_PROC = 697, + RBAC_PERM_COMMAND_RELOAD_SPELL_LINKED_SPELL = 696, + RBAC_PERM_COMMAND_RELOAD_SPELL_PET_AURAS = 697, RBAC_PERM_COMMAND_RELOAD_SPELL_PROC_EVENT = 698, - RBAC_PERM_COMMAND_RELOAD_SPELL_REQUIRED = 699, + RBAC_PERM_COMMAND_RELOAD_SPELL_PROC = 699, RBAC_PERM_COMMAND_RELOAD_SPELL_SCRIPTS = 700, RBAC_PERM_COMMAND_RELOAD_SPELL_TARGET_POSITION = 701, RBAC_PERM_COMMAND_RELOAD_SPELL_THREATS = 702, - RBAC_PERM_COMMAND_RELOAD_SPILLOVER_TEMPLATE = 703, + RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP_STACK_RULES = 703, RBAC_PERM_COMMAND_RELOAD_TRINITY_STRING = 704, - RBAC_PERM_COMMAND_RELOAD_VEHICLE_ACCESORY = 705, - RBAC_PERM_COMMAND_RELOAD_VEHICLE_TEMPLATE_ACCESSORY = 706, - RBAC_PERM_COMMAND_RELOAD_WARDEN_ACTION = 707, - RBAC_PERM_COMMAND_RELOAD_WAYPOINT_DATA = 708, - RBAC_PERM_COMMAND_RELOAD_WAYPOINT_SCRIPTS = 709, + RBAC_PERM_COMMAND_RELOAD_WARDEN_ACTION = 705, + RBAC_PERM_COMMAND_RELOAD_WAYPOINT_SCRIPTS = 706, + RBAC_PERM_COMMAND_RELOAD_WAYPOINT_DATA = 707, + RBAC_PERM_COMMAND_RELOAD_VEHICLE_ACCESORY = 708, + RBAC_PERM_COMMAND_RELOAD_VEHICLE_TEMPLATE_ACCESSORY = 709, RBAC_PERM_COMMAND_RESET = 710, RBAC_PERM_COMMAND_RESET_ACHIEVEMENTS = 711, RBAC_PERM_COMMAND_RESET_HONOR = 712, diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 2bbdffc1e7b..06e19b6ebd1 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -3356,7 +3356,7 @@ void AchievementGlobalMgr::LoadRewardLocales() AchievementRewardLocale& data = m_achievementRewardLocales[entry]; - for (int i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; ObjectMgr::AddLocaleString(fields[1 + 2 * (i - 1)].GetString(), locale, data.subject); @@ -3365,7 +3365,7 @@ void AchievementGlobalMgr::LoadRewardLocales() } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu achievement reward locale strings in %u ms", (unsigned long)m_achievementRewardLocales.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u achievement reward locale strings in %u ms", uint32(m_achievementRewardLocales.size()), GetMSTimeDiffToNow(oldMSTime)); } AchievementEntry const* AchievementGlobalMgr::GetAchievement(uint32 achievementId) const diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 5ef3426d602..41de1970344 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -908,7 +908,7 @@ void BfCapturePoint::SendChangePhase() // send this too, sometimes the slider disappears, dunno why :( SendUpdateWorldState(capturePoint->GetGOInfo()->capturePoint.worldState1, 1); // send these updates to only the ones in this objective - SendUpdateWorldState(capturePoint->GetGOInfo()->capturePoint.worldstate2, (uint32) ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f)); + SendUpdateWorldState(capturePoint->GetGOInfo()->capturePoint.worldstate2, (uint32) std::ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f)); // send this too, sometimes it resets :S SendUpdateWorldState(capturePoint->GetGOInfo()->capturePoint.worldstate3, m_neutralValuePct); } diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 0aa6a51d6bf..e4fe45d45d5 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -247,12 +247,12 @@ class Battlefield : public ZoneScript void HandlePlayerLeaveZone(Player* player, uint32 zone); // All-purpose data storage 64 bit - virtual uint64 GetData64(uint32 dataId) const { return m_Data64[dataId]; } - virtual void SetData64(uint32 dataId, uint64 value) { m_Data64[dataId] = value; } + virtual uint64 GetData64(uint32 dataId) const override { return m_Data64[dataId]; } + virtual void SetData64(uint32 dataId, uint64 value) override { m_Data64[dataId] = value; } // All-purpose data storage 32 bit - virtual uint32 GetData(uint32 dataId) const { return m_Data32[dataId]; } - virtual void SetData(uint32 dataId, uint32 value) { m_Data32[dataId] = value; } + virtual uint32 GetData(uint32 dataId) const override { return m_Data32[dataId]; } + virtual void SetData(uint32 dataId, uint32 value) override { m_Data32[dataId] = value; } virtual void UpdateData(uint32 index, int32 pad) { m_Data32[index] += pad; } // Battlefield - generic methods diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index 03c2992e812..622236b4162 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -255,7 +255,7 @@ class WintergraspCapturePoint : public BfCapturePoint void LinkToWorkshop(WGWorkshop* workshop) { m_Workshop = workshop; } - void ChangeTeam(TeamId oldteam); + void ChangeTeam(TeamId oldteam) override; TeamId GetTeam() const { return m_team; } protected: @@ -276,7 +276,7 @@ class BattlefieldWG : public Battlefield * - Rebuild tower and wall * - Invite player to war */ - void OnBattleStart(); + void OnBattleStart() override; /** * \brief Called when battle end @@ -287,13 +287,13 @@ class BattlefieldWG : public Battlefield * - Remove vehicle * \param endByTimer : true if battle ended when timer is at 00:00, false if battle ended by clicking on relic */ - void OnBattleEnd(bool endByTimer); + void OnBattleEnd(bool endByTimer) override; /** * \brief Called when grouping starts (15 minutes before battlestart) * - Invite all player in zone to join queue */ - void OnStartGrouping(); + void OnStartGrouping() override; /** * \brief Called when player accept invite to join battle @@ -303,20 +303,20 @@ class BattlefieldWG : public Battlefield * - Update tenacity * \param player: Player who accepted invite */ - void OnPlayerJoinWar(Player* player); + void OnPlayerJoinWar(Player* player) override; /** * \brief Called when player left the battle * - Update player aura * \param player : Player who left the battle */ - void OnPlayerLeaveWar(Player* player); + void OnPlayerLeaveWar(Player* player) override; /** * \brief Called when player left the WG zone * \param player : Player who left the zone */ - void OnPlayerLeaveZone(Player* player); + void OnPlayerLeaveZone(Player* player) override; /** * \brief Called when player enters in WG zone @@ -324,7 +324,7 @@ class BattlefieldWG : public Battlefield * - Update worldstate * \param player : Player who enters the zone */ - void OnPlayerEnterZone(Player* player); + void OnPlayerEnterZone(Player* player) override; /** * \brief Called for update battlefield data @@ -332,24 +332,24 @@ class BattlefieldWG : public Battlefield * - Update imunity aura from graveyard * \param diff : time elapsed since the last call (in ms) */ - bool Update(uint32 diff); + bool Update(uint32 diff) override; /** * \brief Called when a creature is created * - Update vehicle count */ - void OnCreatureCreate(Creature* creature); + void OnCreatureCreate(Creature* creature) override; /** * \brief Called when a creature is removed * - Update vehicle count */ - void OnCreatureRemove(Creature* creature); + void OnCreatureRemove(Creature* creature) override; /** * \brief Called when a gameobject is created */ - void OnGameObjectCreate(GameObject* go); + void OnGameObjectCreate(GameObject* go) override; /** * \brief Called when a wall/tower is broken @@ -370,14 +370,14 @@ class BattlefieldWG : public Battlefield */ void UpdatedDestroyedTowerCount(TeamId team); - void DoCompleteOrIncrementAchievement(uint32 achievement, Player* player, uint8 incrementNumber = 1); + void DoCompleteOrIncrementAchievement(uint32 achievement, Player* player, uint8 incrementNumber = 1) override; void RemoveAurasFromPlayer(Player* player); /** * \brief Called when battlefield is setup, at server start */ - bool SetupBattlefield(); + bool SetupBattlefield() override; /// Return pointer to relic object GameObject* GetRelic() { return GetGameObject(m_titansRelicGUID); } @@ -395,22 +395,22 @@ class BattlefieldWG : public Battlefield void UpdateCounterVehicle(bool init); void SendInitWorldStatesTo(Player* player); - void SendInitWorldStatesToAll(); - void FillInitialWorldStates(WorldPacket& data); + void SendInitWorldStatesToAll() override; + void FillInitialWorldStates(WorldPacket& data) override; - void HandleKill(Player* killer, Unit* victim); - void OnUnitDeath(Unit* unit); + void HandleKill(Player* killer, Unit* victim) override; + void OnUnitDeath(Unit* unit) override; void PromotePlayer(Player* killer); void UpdateTenacity(); - void ProcessEvent(WorldObject* obj, uint32 eventId); + void ProcessEvent(WorldObject* obj, uint32 eventId) override; bool FindAndRemoveVehicleFromList(Unit* vehicle); // returns the graveyardId in the specified area. uint8 GetSpiritGraveyardId(uint32 areaId) const; - uint32 GetData(uint32 data) const; + uint32 GetData(uint32 data) const override; protected: bool m_isRelicInteractible; diff --git a/src/server/game/Battlegrounds/ArenaScore.h b/src/server/game/Battlegrounds/ArenaScore.h index 162cf729181..6de7fae8d05 100644 --- a/src/server/game/Battlegrounds/ArenaScore.h +++ b/src/server/game/Battlegrounds/ArenaScore.h @@ -30,7 +30,7 @@ struct ArenaScore : public BattlegroundScore protected: ArenaScore(uint64 playerGuid, uint32 team) : BattlegroundScore(playerGuid, team), TeamId(team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE) { } - void AppendToPacket(WorldPacket& data, ByteBuffer& content) final + void AppendToPacket(WorldPacket& data, ByteBuffer& content) final override { uint32 primaryTree = 0; if (Player* player = ObjectAccessor::FindPlayer(PlayerGuid)) @@ -87,7 +87,7 @@ struct ArenaScore : public BattlegroundScore content.WriteByteSeq(PlayerGuid[2]); } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& /*content*/) final + void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& /*content*/) final override { data.WriteBits(0, 24); // Objectives Count } diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index 17d95dbbe6b..630780f43bf 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -637,7 +637,7 @@ float ArenaTeam::GetChanceAgainst(uint32 ownRating, uint32 opponentRating) { // Returns the chance to win against a team with the given rating, used in the rating adjustment calculation // ELO system - return 1.0f / (1.0f + exp(log(10.0f) * (float)((float)opponentRating - (float)ownRating) / 650.0f)); + return 1.0f / (1.0f + std::exp(std::log(10.0f) * (float(opponentRating) - float(ownRating)) / 650.0f)); } int32 ArenaTeam::GetMatchmakerRatingMod(uint32 ownRating, uint32 opponentRating, bool won) diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 584117e7666..ed39c3fd6b2 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -897,12 +897,14 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac Player* player = ObjectAccessor::FindPlayer(guid); - // should remove spirit of redemption if (player) { + // should remove spirit of redemption if (player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT); + player->RemoveAurasByType(SPELL_AURA_MOUNTED); + if (!player->IsAlive()) // resurrect on exit { player->ResurrectPlayer(1.0f); diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h index af283cb825f..f95e8bafd06 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.h +++ b/src/server/game/Battlegrounds/BattlegroundQueue.h @@ -143,8 +143,8 @@ class BGQueueInviteEvent : public BasicEvent { } virtual ~BGQueueInviteEvent() { } - virtual bool Execute(uint64 e_time, uint32 p_time); - virtual void Abort(uint64 e_time); + virtual bool Execute(uint64 e_time, uint32 p_time) override; + virtual void Abort(uint64 e_time) override; private: uint64 m_PlayerGuid; uint32 m_BgInstanceGUID; @@ -167,8 +167,8 @@ class BGQueueRemoveEvent : public BasicEvent virtual ~BGQueueRemoveEvent() { } - virtual bool Execute(uint64 e_time, uint32 p_time); - virtual void Abort(uint64 e_time); + virtual bool Execute(uint64 e_time, uint32 p_time) override; + virtual void Abort(uint64 e_time) override; private: uint64 m_PlayerGuid; uint32 m_BgInstanceGUID; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h index 74efe421d35..91bb7104d66 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h @@ -260,7 +260,7 @@ struct BattlegroundABScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final + void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override { data.WriteBits(2, 24); // Objectives Count content << uint32(BasesAssaulted); @@ -277,31 +277,31 @@ class BattlegroundAB : public Battleground BattlegroundAB(); ~BattlegroundAB(); - void AddPlayer(Player* player); - void StartingEventCloseDoors(); - void StartingEventOpenDoors(); - void RemovePlayer(Player* player, uint64 guid, uint32 team); - void HandleAreaTrigger(Player* Source, uint32 Trigger); - bool SetupBattleground(); - void Reset(); - void EndBattleground(uint32 winner); - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); + void AddPlayer(Player* player) override; + void StartingEventCloseDoors() override; + void StartingEventOpenDoors() override; + void RemovePlayer(Player* player, uint64 guid, uint32 team) override; + void HandleAreaTrigger(Player* Source, uint32 Trigger) override; + bool SetupBattleground() override; + void Reset() override; + void EndBattleground(uint32 winner) override; + WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; /* Scorekeeping */ bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true) override; - void FillInitialWorldStates(WorldPacket& data); + void FillInitialWorldStates(WorldPacket& data) override; /* Nodes occupying */ - void EventPlayerClickedOnFlag(Player* source, GameObject* target_obj); + void EventPlayerClickedOnFlag(Player* source, GameObject* target_obj) override; /* achievement req. */ - bool IsAllNodesControlledByTeam(uint32 team) const; - bool CheckAchievementCriteriaMeet(uint32 /*criteriaId*/, Player const* /*player*/, Unit const* /*target*/ = NULL, uint32 /*miscvalue1*/ = 0); + bool IsAllNodesControlledByTeam(uint32 team) const override; + bool CheckAchievementCriteriaMeet(uint32 /*criteriaId*/, Player const* /*player*/, Unit const* /*target*/ = nullptr, uint32 /*miscvalue1*/ = 0) override; - uint32 GetPrematureWinner(); + uint32 GetPrematureWinner() override; private: - void PostUpdateImpl(uint32 diff); + void PostUpdateImpl(uint32 diff) override; /* Gameobject spawning/despawning */ void _CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay); void _DelBanner(uint8 node, uint8 type, uint8 teamIndex); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h index 5255caeda18..a93929672c7 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h @@ -1558,7 +1558,7 @@ struct BattlegroundAVScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final + void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override { data.WriteBits(5, 24); // Objectives Count content << uint32(GraveyardsAssaulted); @@ -1582,37 +1582,37 @@ class BattlegroundAV : public Battleground ~BattlegroundAV(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); - void StartingEventCloseDoors(); - void StartingEventOpenDoors(); + void AddPlayer(Player* player) override; + void StartingEventCloseDoors() override; + void StartingEventOpenDoors() override; - void RemovePlayer(Player* player, uint64 guid, uint32 team); - void HandleAreaTrigger(Player* player, uint32 trigger); - bool SetupBattleground(); - void ResetBGSubclass(); + void RemovePlayer(Player* player, uint64 guid, uint32 team) override; + void HandleAreaTrigger(Player* player, uint32 trigger) override; + bool SetupBattleground() override; + void ResetBGSubclass() override; /*general stuff*/ void UpdateScore(uint16 team, int16 points); bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true) override; /*handlestuff*/ //these are functions which get called from extern - void EventPlayerClickedOnFlag(Player* source, GameObject* target_obj); - void HandleKillPlayer(Player* player, Player* killer); - void HandleKillUnit(Creature* unit, Player* killer); - void HandleQuestComplete(uint32 questid, Player* player); - bool CanActivateGO(int32 GOId, uint32 team) const; + void EventPlayerClickedOnFlag(Player* source, GameObject* target_obj) override; + void HandleKillPlayer(Player* player, Player* killer) override; + void HandleKillUnit(Creature* unit, Player* killer) override; + void HandleQuestComplete(uint32 questid, Player* player) override; + bool CanActivateGO(int32 GOId, uint32 team) const override; - void EndBattleground(uint32 winner); + void EndBattleground(uint32 winner) override; - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); + WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; // Achievement: Av perfection and Everything counts - bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0); + bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* source, Unit const* target = nullptr, uint32 miscvalue1 = 0) override; - uint32 GetPrematureWinner(); + uint32 GetPrematureWinner() override; private: - void PostUpdateImpl(uint32 diff); + void PostUpdateImpl(uint32 diff) override; /* Nodes occupying */ void EventPlayerAssaultsPoint(Player* player, uint32 object); @@ -1636,7 +1636,7 @@ class BattlegroundAV : public Battleground void ChangeMineOwner(uint8 mine, uint32 team, bool initial=false); /*worldstates*/ - void FillInitialWorldStates(WorldPacket& data); + void FillInitialWorldStates(WorldPacket& data) override; uint8 GetWorldStateType(uint8 state, uint16 team); void SendMineWorldStates(uint32 mine); void UpdateNodeWorldState(BG_AV_Nodes node); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.h b/src/server/game/Battlegrounds/Zones/BattlegroundBE.h index f391edbf747..6aa3e56ca13 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundBE.h @@ -48,11 +48,11 @@ class BattlegroundBE : public Arena BattlegroundBE(); /* inherited from BattlegroundClass */ - void StartingEventCloseDoors(); - void StartingEventOpenDoors(); + void StartingEventCloseDoors() override; + void StartingEventOpenDoors() override; - void HandleAreaTrigger(Player* Source, uint32 Trigger); - bool SetupBattleground(); - void FillInitialWorldStates(WorldPacket &d); + void HandleAreaTrigger(Player* Source, uint32 Trigger) override; + bool SetupBattleground() override; + void FillInitialWorldStates(WorldPacket &d) override; }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h index 4c763316d83..7b91996ed0e 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h @@ -94,15 +94,15 @@ class BattlegroundDS : public Arena BattlegroundDS(); /* inherited from BattlegroundClass */ - void StartingEventCloseDoors(); - void StartingEventOpenDoors(); + void StartingEventCloseDoors() override; + void StartingEventOpenDoors() override; - void HandleAreaTrigger(Player* Source, uint32 Trigger); - bool SetupBattleground(); - void FillInitialWorldStates(WorldPacket &d); + void HandleAreaTrigger(Player* Source, uint32 Trigger) override; + bool SetupBattleground() override; + void FillInitialWorldStates(WorldPacket &d) override; private: - void PostUpdateImpl(uint32 diff); + void PostUpdateImpl(uint32 diff) override; EventMap _events; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h index 9ea6d30fe51..9867d878b41 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h @@ -343,7 +343,7 @@ struct BattlegroundEYScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final + void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override { data.WriteBits(1, 24); // Objectives Count content << uint32(FlagCaptures); @@ -359,42 +359,42 @@ class BattlegroundEY : public Battleground ~BattlegroundEY(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); - void StartingEventCloseDoors(); - void StartingEventOpenDoors(); + void AddPlayer(Player* player) override; + void StartingEventCloseDoors() override; + void StartingEventOpenDoors() override; /* BG Flags */ - uint64 GetFlagPickerGUID(int32 /*team*/ = -1) const { return m_FlagKeeper; } + uint64 GetFlagPickerGUID(int32 /*team*/ = -1) const override { return m_FlagKeeper; } void SetFlagPicker(uint64 guid) { m_FlagKeeper = guid; } bool IsFlagPickedup() const { return m_FlagKeeper != 0; } uint8 GetFlagState() const { return m_FlagState; } void RespawnFlag(bool send_message); void RespawnFlagAfterDrop(); - void RemovePlayer(Player* player, uint64 guid, uint32 team); + void RemovePlayer(Player* player, uint64 guid, uint32 team) override; void HandleBuffUse(uint64 buff_guid); - void HandleAreaTrigger(Player* Source, uint32 Trigger); - void HandleKillPlayer(Player* player, Player* killer); - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); - bool SetupBattleground(); - void Reset(); + void HandleAreaTrigger(Player* Source, uint32 Trigger) override; + void HandleKillPlayer(Player* player, Player* killer) override; + WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; + bool SetupBattleground() override; + void Reset() override; void UpdateTeamScore(uint32 Team); - void EndBattleground(uint32 winner); + void EndBattleground(uint32 winner) override; bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true) override; - void FillInitialWorldStates(WorldPacket& data); - void SetDroppedFlagGUID(uint64 guid, int32 /*TeamID*/ = -1) { m_DroppedFlagGUID = guid;} + void FillInitialWorldStates(WorldPacket& data) override; + void SetDroppedFlagGUID(uint64 guid, int32 /*TeamID*/ = -1) override { m_DroppedFlagGUID = guid;} uint64 GetDroppedFlagGUID() const { return m_DroppedFlagGUID;} /* Battleground Events */ - void EventPlayerClickedOnFlag(Player* Source, GameObject* target_obj); - void EventPlayerDroppedFlag(Player* Source); + void EventPlayerClickedOnFlag(Player* Source, GameObject* target_obj) override; + void EventPlayerDroppedFlag(Player* Source) override; /* achievement req. */ - bool IsAllNodesControlledByTeam(uint32 team) const; + bool IsAllNodesControlledByTeam(uint32 team) const override; - uint32 GetPrematureWinner(); + uint32 GetPrematureWinner() override; private: - void PostUpdateImpl(uint32 diff); + void PostUpdateImpl(uint32 diff) override; void EventPlayerCapturedFlag(Player* Source, uint32 BgObjectType); void EventTeamCapturedPoint(Player* Source, uint32 Point); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h index 5153a6fb9cf..a0f03f5727d 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h @@ -871,7 +871,7 @@ struct BattlegroundICScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final + void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override { data.WriteBits(2, 24); // Objectives Count content << uint32(BasesAssaulted); @@ -889,36 +889,36 @@ class BattlegroundIC : public Battleground ~BattlegroundIC(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); - void StartingEventCloseDoors(); - void StartingEventOpenDoors(); - void PostUpdateImpl(uint32 diff); - - void RemovePlayer(Player* player, uint64 guid, uint32 team); - void HandleAreaTrigger(Player* player, uint32 trigger); - bool SetupBattleground(); + void AddPlayer(Player* player) override; + void StartingEventCloseDoors() override; + void StartingEventOpenDoors() override; + void PostUpdateImpl(uint32 diff) override; + + void RemovePlayer(Player* player, uint64 guid, uint32 team) override; + void HandleAreaTrigger(Player* player, uint32 trigger) override; + bool SetupBattleground() override; void SpawnLeader(uint32 teamid); - void HandleKillUnit(Creature* unit, Player* killer); - void HandleKillPlayer(Player* player, Player* killer); - void EndBattleground(uint32 winner); - void EventPlayerClickedOnFlag(Player* source, GameObject* /*target_obj*/); + void HandleKillUnit(Creature* unit, Player* killer) override; + void HandleKillPlayer(Player* player, Player* killer) override; + void EndBattleground(uint32 winner) override; + void EventPlayerClickedOnFlag(Player* source, GameObject* /*target_obj*/) override; - void DestroyGate(Player* player, GameObject* go); + void DestroyGate(Player* player, GameObject* go) override; - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); + WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; /* Scorekeeping */ - void FillInitialWorldStates(WorldPacket& data); + void FillInitialWorldStates(WorldPacket& data) override; - void DoAction(uint32 action, uint64 var); + void DoAction(uint32 action, uint64 var) override; - void HandlePlayerResurrect(Player* player); + void HandlePlayerResurrect(Player* player) override; uint32 GetNodeState(uint8 nodeType) const { return (uint8)nodePoint[nodeType].nodeState; } - bool IsAllNodesControlledByTeam(uint32 team) const; + bool IsAllNodesControlledByTeam(uint32 team) const override; - bool IsSpellAllowed(uint32 spellId, Player const* player) const; + bool IsSpellAllowed(uint32 spellId, Player const* player) const override; private: uint32 closeFortressDoorsTimer; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.h b/src/server/game/Battlegrounds/Zones/BattlegroundNA.h index 2fa93a07651..17df258a0b8 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundNA.h @@ -47,11 +47,11 @@ class BattlegroundNA : public Arena BattlegroundNA(); /* inherited from BattlegroundClass */ - void StartingEventCloseDoors(); - void StartingEventOpenDoors(); + void StartingEventCloseDoors() override; + void StartingEventOpenDoors() override; - void HandleAreaTrigger(Player* Source, uint32 Trigger); - bool SetupBattleground(); - void FillInitialWorldStates(WorldPacket &d); + void HandleAreaTrigger(Player* Source, uint32 Trigger) override; + bool SetupBattleground() override; + void FillInitialWorldStates(WorldPacket &d) override; }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.h b/src/server/game/Battlegrounds/Zones/BattlegroundRL.h index ad4fe18a3c7..e96129b05f0 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRL.h @@ -43,11 +43,11 @@ class BattlegroundRL : public Arena BattlegroundRL(); /* inherited from BattlegroundClass */ - void FillInitialWorldStates(WorldPacket &d); - void StartingEventCloseDoors(); - void StartingEventOpenDoors(); + void FillInitialWorldStates(WorldPacket &d) override; + void StartingEventCloseDoors() override; + void StartingEventOpenDoors() override; - void HandleAreaTrigger(Player* Source, uint32 Trigger); - bool SetupBattleground(); + void HandleAreaTrigger(Player* Source, uint32 Trigger) override; + bool SetupBattleground() override; }; #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h index d23f6757b83..eda4bf7fa00 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h @@ -96,14 +96,14 @@ class BattlegroundRV : public Arena BattlegroundRV(); /* inherited from BattlegroundClass */ - void StartingEventOpenDoors(); - void FillInitialWorldStates(WorldPacket &d); + void StartingEventOpenDoors() override; + void FillInitialWorldStates(WorldPacket &d) override; - void HandleAreaTrigger(Player* Source, uint32 Trigger); - bool SetupBattleground(); + void HandleAreaTrigger(Player* Source, uint32 Trigger) override; + bool SetupBattleground() override; private: - void PostUpdateImpl(uint32 diff); + void PostUpdateImpl(uint32 diff) override; void TogglePillarCollision(); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp index 10ede74685c..11e07566092 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp @@ -712,7 +712,7 @@ WorldSafeLocsEntry const* BattlegroundSA::GetClosestGraveYard(Player* player) safeloc = BG_SA_GYEntries[BG_SA_DEFENDER_LAST_GY]; closest = sWorldSafeLocsStore.LookupEntry(safeloc); - nearest = sqrt((closest->x - x)*(closest->x - x) + (closest->y - y)*(closest->y - y) + (closest->z - z)*(closest->z - z)); + nearest = std::sqrt((closest->x - x)*(closest->x - x) + (closest->y - y)*(closest->y - y) + (closest->z - z)*(closest->z - z)); for (uint8 i = BG_SA_RIGHT_CAPTURABLE_GY; i < BG_SA_MAX_GY; i++) { @@ -720,7 +720,7 @@ WorldSafeLocsEntry const* BattlegroundSA::GetClosestGraveYard(Player* player) continue; ret = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]); - dist = sqrt((ret->x - x)*(ret->x - x) + (ret->y - y)*(ret->y - y) + (ret->z - z)*(ret->z - z)); + dist = std::sqrt((ret->x - x)*(ret->x - x) + (ret->y - y)*(ret->y - y) + (ret->z - z)*(ret->z - z)); if (dist < nearest) { closest = ret; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h index 474a2ff8dc3..7019d785503 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h @@ -531,7 +531,7 @@ struct BattlegroundSAScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final + void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override { data.WriteBits(2, 24); // Objectives Count content << uint32(DemolishersDestroyed); @@ -554,27 +554,27 @@ class BattlegroundSA : public Battleground * -Update timer * -Round switch */ - void PostUpdateImpl(uint32 diff); + void PostUpdateImpl(uint32 diff) override; /* inherited from BattlegroundClass */ /// Called when a player join battle - void AddPlayer(Player* player); + void AddPlayer(Player* player) override; /// Called when battle start - void StartingEventCloseDoors(); - void StartingEventOpenDoors(); + void StartingEventCloseDoors() override; + void StartingEventOpenDoors() override; /// Called for ini battleground, after that the first player be entered - bool SetupBattleground(); - void Reset(); + bool SetupBattleground() override; + void Reset() override; /// Called for generate packet contain worldstate data - void FillInitialWorldStates(WorldPacket& data); + void FillInitialWorldStates(WorldPacket& data) override; /// Called when a player kill a unit in bg - void HandleKillUnit(Creature* creature, Player* killer); + void HandleKillUnit(Creature* creature, Player* killer) override; /// Return the nearest graveyard where player can respawn - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); + WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; /// Called when someone activates an event void ProcessEvent(WorldObject* /*obj*/, uint32 /*eventId*/, WorldObject* /*invoker*/ = NULL) override; /// Called when a player click on flag (graveyard flag) - void EventPlayerClickedOnFlag(Player* source, GameObject* go); + void EventPlayerClickedOnFlag(Player* source, GameObject* go) override; /// Called when a player clicked on relic void TitanRelicActivated(Player* clicker); @@ -588,11 +588,11 @@ class BattlegroundSA : public Battleground } /// Called on battleground ending - void EndBattleground(uint32 winner); + void EndBattleground(uint32 winner) override; /// Called when a player leave battleground - void RemovePlayer(Player* player, uint64 guid, uint32 team); - void HandleAreaTrigger(Player* Source, uint32 Trigger); + void RemovePlayer(Player* player, uint64 guid, uint32 team) override; + void HandleAreaTrigger(Player* Source, uint32 Trigger) override; /* Scorekeeping */ @@ -630,7 +630,7 @@ class BattlegroundSA : public Battleground * -Update worldstate * -Delete gameobject in front of door (lighting object, with different colours for each door) */ - void DestroyGate(Player* player, GameObject* go); + void DestroyGate(Player* player, GameObject* go) override; /// Update timer worldstate void SendTime(); /** diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h index 1c3ee932b76..2fdb6dd120e 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h @@ -170,7 +170,7 @@ struct BattlegroundWGScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final + void BuildObjectivesBlock(WorldPacket& data, ByteBuffer& content) final override { data.WriteBits(2, 24); // Objectives Count content << uint32(FlagCaptures); @@ -189,12 +189,12 @@ class BattlegroundWS : public Battleground ~BattlegroundWS(); /* inherited from BattlegroundClass */ - void AddPlayer(Player* player); - void StartingEventCloseDoors(); - void StartingEventOpenDoors(); + void AddPlayer(Player* player) override; + void StartingEventCloseDoors() override; + void StartingEventOpenDoors() override; /* BG Flags */ - uint64 GetFlagPickerGUID(int32 team) const + uint64 GetFlagPickerGUID(int32 team) const override { if (team == TEAM_ALLIANCE || team == TEAM_HORDE) return m_FlagKeepers[team]; @@ -209,40 +209,40 @@ class BattlegroundWS : public Battleground uint8 GetFlagState(uint32 team) { return _flagState[GetTeamIndexByTeamId(team)]; } /* Battleground Events */ - void EventPlayerDroppedFlag(Player* player); - void EventPlayerClickedOnFlag(Player* player, GameObject* target_obj); + void EventPlayerDroppedFlag(Player* player) override; + void EventPlayerClickedOnFlag(Player* player, GameObject* target_obj) override; void EventPlayerCapturedFlag(Player* player); - void RemovePlayer(Player* player, uint64 guid, uint32 team); - void HandleAreaTrigger(Player* player, uint32 trigger); - void HandleKillPlayer(Player* player, Player* killer); - bool SetupBattleground(); - void Reset(); - void EndBattleground(uint32 winner); - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); + void RemovePlayer(Player* player, uint64 guid, uint32 team) override; + void HandleAreaTrigger(Player* player, uint32 trigger) override; + void HandleKillPlayer(Player* player, Player* killer) override; + bool SetupBattleground() override; + void Reset() override; + void EndBattleground(uint32 winner) override; + WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; void UpdateFlagState(uint32 team, uint32 value); void SetLastFlagCapture(uint32 team) { _lastFlagCaptureTeam = team; } void UpdateTeamScore(uint32 team); bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true) override; - void SetDroppedFlagGUID(uint64 guid, int32 team = -1) + void SetDroppedFlagGUID(uint64 guid, int32 team = -1) override { if (team == TEAM_ALLIANCE || team == TEAM_HORDE) m_DroppedFlagGUID[team] = guid; } uint64 GetDroppedFlagGUID(uint32 TeamID) { return m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)];} - void FillInitialWorldStates(WorldPacket& data); + void FillInitialWorldStates(WorldPacket& data) override; /* Scorekeeping */ void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; } void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; } void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; } - uint32 GetPrematureWinner(); + uint32 GetPrematureWinner() override; /* Achievements*/ - bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* source, Unit const* target = NULL, uint32 miscvalue1 = 0); + bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* source, Unit const* target = nullptr, uint32 miscvalue1 = 0) override; private: uint64 m_FlagKeepers[2]; // 0 - alliance, 1 - horde @@ -260,6 +260,6 @@ class BattlegroundWS : public Battleground uint8 _flagDebuffState; // 0 - no debuffs, 1 - focused assault, 2 - brutal assault uint8 _minutesElapsed; - void PostUpdateImpl(uint32 diff); + void PostUpdateImpl(uint32 diff) override; }; #endif diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 0686272f191..961824b1d86 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -984,7 +984,7 @@ static char const* const spellKeys[] = "Henchant", // enchanting recipe spell "Htrade", // profession/skill spell "Hglyph", // glyph - 0 + nullptr }; uint32 ChatHandler::extractSpellIdFromLink(char* text) @@ -1068,7 +1068,7 @@ static char const* const guidKeys[] = "Hplayer", "Hcreature", "Hgameobject", - 0 + nullptr }; uint64 ChatHandler::extractGuidFromLink(char* text) diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 5c541d07b5a..7c9ad68a7f3 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -148,14 +148,14 @@ class CliHandler : public ChatHandler explicit CliHandler(void* callbackArg, Print* zprint) : m_callbackArg(callbackArg), m_print(zprint) { } // overwrite functions - const char *GetTrinityString(int32 entry) const; - bool isAvailable(ChatCommand const& cmd) const; - bool HasPermission(uint32 /*permission*/) const { return true; } - void SendSysMessage(const char *str); - std::string GetNameLink() const; - bool needReportToTarget(Player* chr) const; - LocaleConstant GetSessionDbcLocale() const; - int GetSessionDbLocaleIndex() const; + const char *GetTrinityString(int32 entry) const override; + bool isAvailable(ChatCommand const& cmd) const override; + bool HasPermission(uint32 /*permission*/) const override { return true; } + void SendSysMessage(const char *str) override; + std::string GetNameLink() const override; + bool needReportToTarget(Player* chr) const override; + LocaleConstant GetSessionDbcLocale() const override; + int GetSessionDbLocaleIndex() const override; private: void* m_callbackArg; diff --git a/src/server/game/Chat/ChatLink.h b/src/server/game/Chat/ChatLink.h index ebe2583dc1c..a13cd2a0964 100644 --- a/src/server/game/Chat/ChatLink.h +++ b/src/server/game/Chat/ChatLink.h @@ -61,8 +61,8 @@ public: { memset(_data, 0, sizeof(_data)); } - virtual bool Initialize(std::istringstream& iss); - virtual bool ValidateName(char* buffer, const char* context); + virtual bool Initialize(std::istringstream& iss) override; + virtual bool ValidateName(char* buffer, const char* context) override; protected: std::string FormatName(uint8 index, ItemLocale const* locale, char* suffixStrings) const; @@ -77,9 +77,9 @@ protected: class QuestChatLink : public ChatLink { public: - QuestChatLink() : ChatLink(), _quest(NULL), _questLevel(0) { } - virtual bool Initialize(std::istringstream& iss); - virtual bool ValidateName(char* buffer, const char* context); + QuestChatLink() : ChatLink(), _quest(nullptr), _questLevel(0) { } + virtual bool Initialize(std::istringstream& iss) override; + virtual bool ValidateName(char* buffer, const char* context) override; protected: Quest const* _quest; @@ -90,9 +90,9 @@ protected: class SpellChatLink : public ChatLink { public: - SpellChatLink() : ChatLink(), _spell(NULL) { } - virtual bool Initialize(std::istringstream& iss); - virtual bool ValidateName(char* buffer, const char* context); + SpellChatLink() : ChatLink(), _spell(nullptr) { } + virtual bool Initialize(std::istringstream& iss) override; + virtual bool ValidateName(char* buffer, const char* context) override; protected: SpellInfo const* _spell; @@ -106,8 +106,8 @@ public: { memset(_data, 0, sizeof(_data)); } - virtual bool Initialize(std::istringstream& iss); - virtual bool ValidateName(char* buffer, const char* context); + virtual bool Initialize(std::istringstream& iss) override; + virtual bool ValidateName(char* buffer, const char* context) override; protected: uint32 _guid; @@ -120,7 +120,7 @@ class TradeChatLink : public SpellChatLink { public: TradeChatLink() : SpellChatLink(), _minSkillLevel(0), _maxSkillLevel(0), _guid(0) { } - virtual bool Initialize(std::istringstream& iss); + virtual bool Initialize(std::istringstream& iss) override; private: int32 _minSkillLevel; int32 _maxSkillLevel; @@ -133,7 +133,7 @@ class TalentChatLink : public SpellChatLink { public: TalentChatLink() : SpellChatLink(), _talentId(0), _rankId(0) { } - virtual bool Initialize(std::istringstream& iss); + virtual bool Initialize(std::istringstream& iss) override; private: uint32 _talentId; @@ -145,7 +145,7 @@ class EnchantmentChatLink : public SpellChatLink { public: EnchantmentChatLink() : SpellChatLink() { } - virtual bool Initialize(std::istringstream& iss); + virtual bool Initialize(std::istringstream& iss) override; }; // GlyphChatLink - link to glyph @@ -153,7 +153,7 @@ class GlyphChatLink : public SpellChatLink { public: GlyphChatLink() : SpellChatLink(), _slotId(0), _glyph(NULL) { } - virtual bool Initialize(std::istringstream& iss); + virtual bool Initialize(std::istringstream& iss) override; private: uint32 _slotId; GlyphPropertiesEntry const* _glyph; diff --git a/src/server/game/Combat/ThreatManager.h b/src/server/game/Combat/ThreatManager.h index dd5904ae2ec..f0741f81067 100644 --- a/src/server/game/Combat/ThreatManager.h +++ b/src/server/game/Combat/ThreatManager.h @@ -117,13 +117,13 @@ class HostileReference : public Reference<Unit, ThreatManager> //================================================= // Tell our refTo (target) object that we have a link - void targetObjectBuildLink(); + void targetObjectBuildLink() override; // Tell our refTo (taget) object, that the link is cut - void targetObjectDestroyLink(); + void targetObjectDestroyLink() override; // Tell our refFrom (source) object, that the link is cut (Target destroyed) - void sourceObjectDestroyLink(); + void sourceObjectDestroyLink() override; private: // Inform the source, that the status of that reference was changed void fireStatusChanged(ThreatRefStatusChangeEvent& threatRefStatusChangeEvent); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 6083895ab26..739a373dbf0 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -211,10 +211,27 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) condMeets = GetClosestGameObjectWithEntry(object, ConditionValue1, (float)ConditionValue2) ? true : false; break; } - case CONDITION_OBJECT_ENTRY: + case CONDITION_OBJECT_ENTRY_GUID: { if (uint32(object->GetTypeId()) == ConditionValue1) - condMeets = (!ConditionValue2) || (object->GetEntry() == ConditionValue2); + { + condMeets = !ConditionValue2 || (object->GetEntry() == ConditionValue2); + + if (ConditionValue3) + { + switch (object->GetTypeId()) + { + case TYPEID_UNIT: + condMeets &= object->ToCreature()->GetDBTableGUIDLow() == ConditionValue3; + break; + case TYPEID_GAMEOBJECT: + condMeets &= object->ToGameObject()->GetDBTableGUIDLow() == ConditionValue3; + break; + default: + break; + } + } + } break; } case CONDITION_TYPE_MASK: @@ -419,7 +436,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition() case CONDITION_NEAR_GAMEOBJECT: mask |= GRID_MAP_TYPE_MASK_ALL; break; - case CONDITION_OBJECT_ENTRY: + case CONDITION_OBJECT_ENTRY_GUID: switch (ConditionValue1) { case TYPEID_UNIT: @@ -1841,35 +1858,67 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) TC_LOG_ERROR("sql.sql", "NearGameObject condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } - case CONDITION_OBJECT_ENTRY: + case CONDITION_OBJECT_ENTRY_GUID: { switch (cond->ConditionValue1) { case TYPEID_UNIT: if (cond->ConditionValue2 && !sObjectMgr->GetCreatureTemplate(cond->ConditionValue2)) { - TC_LOG_ERROR("sql.sql", "ObjectEntry condition has non existing creature template entry (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing creature template entry (%u), skipped", cond->ConditionValue2); return false; } + if (cond->ConditionValue3) + { + if (CreatureData const* creatureData = sObjectMgr->GetCreatureData(cond->ConditionValue3)) + { + if (cond->ConditionValue2 && creatureData->id != cond->ConditionValue2) + { + TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match creature entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2); + return false; + } + } + else + { + TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing creature guid (%u), skipped", cond->ConditionValue3); + return false; + } + } break; case TYPEID_GAMEOBJECT: if (cond->ConditionValue2 && !sObjectMgr->GetGameObjectTemplate(cond->ConditionValue2)) { - TC_LOG_ERROR("sql.sql", "ObjectEntry condition has non existing game object template entry (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing gameobject template entry (%u), skipped", cond->ConditionValue2); return false; } + if (cond->ConditionValue3) + { + if (GameObjectData const* goData = sObjectMgr->GetGOData(cond->ConditionValue3)) + { + if (cond->ConditionValue2 && goData->id != cond->ConditionValue2) + { + TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match gameobject entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2); + return false; + } + } + else + { + TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing gameobject guid (%u), skipped", cond->ConditionValue3); + return false; + } + } break; case TYPEID_PLAYER: case TYPEID_CORPSE: if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "ObjectEntry condition has useless data in value2 (%u)!", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has useless data in value2 (%u)!", cond->ConditionValue2); + if (cond->ConditionValue3) + TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has useless data in value3 (%u)!", cond->ConditionValue3); break; default: - TC_LOG_ERROR("sql.sql", "ObjectEntry condition has wrong typeid set (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has wrong typeid set (%u), skipped", cond->ConditionValue1); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "ObjectEntry condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_TYPE_MASK: diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 9a48985b90d..317db5b2019 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -63,7 +63,7 @@ enum ConditionTypes CONDITION_QUEST_COMPLETE = 28, // quest_id 0 0 true if player has quest_id with all objectives complete, but not yet rewarded CONDITION_NEAR_CREATURE = 29, // creature entry distance 0 true if there is a creature of entry in range CONDITION_NEAR_GAMEOBJECT = 30, // gameobject entry distance 0 true if there is a gameobject of entry in range - CONDITION_OBJECT_ENTRY = 31, // TypeID entry 0 true if object is type TypeID and the entry is 0 or matches entry of the object + CONDITION_OBJECT_ENTRY_GUID = 31, // TypeID entry guid true if object is type TypeID and the entry is 0 or matches entry of the object or matches guid of the object CONDITION_TYPE_MASK = 32, // TypeMask 0 0 true if object is type object's TypeMask matches provided TypeMask CONDITION_RELATION_TO = 33, // ConditionTarget RelationType 0 true if object is in given relation with object specified by ConditionTarget CONDITION_REACTION_TO = 34, // ConditionTarget rankMask 0 true if object's reaction matches rankMask object specified by ConditionTarget diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h index 1ed37bd9d05..3f1dcbb218b 100644 --- a/src/server/game/DungeonFinding/LFGScripts.h +++ b/src/server/game/DungeonFinding/LFGScripts.h @@ -35,9 +35,9 @@ class LFGPlayerScript : public PlayerScript LFGPlayerScript(); // Player Hooks - void OnLogout(Player* player); - void OnLogin(Player* player, bool loginFirst); - void OnMapChanged(Player* player); + void OnLogout(Player* player) override; + void OnLogin(Player* player, bool loginFirst) override; + void OnMapChanged(Player* player) override; }; class LFGGroupScript : public GroupScript @@ -46,11 +46,11 @@ class LFGGroupScript : public GroupScript LFGGroupScript(); // Group Hooks - void OnAddMember(Group* group, uint64 guid); - void OnRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, char const* reason); - void OnDisband(Group* group); - void OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid); - void OnInviteMember(Group* group, uint64 guid); + void OnAddMember(Group* group, uint64 guid) override; + void OnRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, char const* reason) override; + void OnDisband(Group* group) override; + void OnChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid) override; + void OnInviteMember(Group* group, uint64 guid) override; }; } // namespace lfg diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h index def84dd93a9..5039c85bcb9 100644 --- a/src/server/game/Entities/Corpse/Corpse.h +++ b/src/server/game/Entities/Corpse/Corpse.h @@ -52,8 +52,8 @@ class Corpse : public WorldObject, public GridObject<Corpse> explicit Corpse(CorpseType type = CORPSE_BONES); ~Corpse(); - void AddToWorld(); - void RemoveFromWorld(); + void AddToWorld() override; + void RemoveFromWorld() override; bool Create(uint32 guidlow, Map* map); bool Create(uint32 guidlow, Player* owner); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 992894a1a3c..6a6caa72e76 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -385,9 +385,9 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/) RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); - SetAttackTime(BASE_ATTACK, cInfo->baseattacktime); - SetAttackTime(OFF_ATTACK, cInfo->baseattacktime); - SetAttackTime(RANGED_ATTACK, cInfo->rangeattacktime); + SetAttackTime(BASE_ATTACK, cInfo->BaseAttackTime); + SetAttackTime(OFF_ATTACK, cInfo->BaseAttackTime); + SetAttackTime(RANGED_ATTACK, cInfo->RangeAttackTime); SelectLevel(); @@ -548,15 +548,6 @@ void Creature::Update(uint32 diff) if (!IsAlive()) break; - time_t now = time(NULL); - - // Check if we should refill the pickpocketing loot - if (loot.loot_type == LOOT_PICKPOCKETING && _pickpocketLootRestore && _pickpocketLootRestore <= now) - { - loot.clear(); - _pickpocketLootRestore = 0; - } - if (m_regenTimer > 0) { if (diff >= m_regenTimer) @@ -828,7 +819,7 @@ bool Creature::Create(uint32 guidlow, Map* map, uint32 /*phaseMask*/, uint32 ent void Creature::InitializeReactState() { - if (IsTotem() || IsTrigger() || GetCreatureType() == CREATURE_TYPE_CRITTER || IsSpiritService()) + if (IsTotem() || IsTrigger() || IsCritter() || IsSpiritService()) SetReactState(REACT_PASSIVE); /* else if (IsCivilian()) @@ -1098,7 +1089,7 @@ void Creature::SelectLevel() float basedamage = stats->GenerateBaseDamage(cInfo); float weaponBaseMinDamage = basedamage; - float weaponBaseMaxDamage = basedamage * 1.5; + float weaponBaseMaxDamage = basedamage * 1.5f; SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, weaponBaseMinDamage); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, weaponBaseMaxDamage); @@ -1542,7 +1533,7 @@ void Creature::Respawn(bool force) TC_LOG_DEBUG("entities.unit", "Respawning creature %s (GuidLow: %u, Full GUID: " UI64FMTD " Entry: %u)", GetName().c_str(), GetGUIDLow(), GetGUID(), GetEntry()); m_respawnTime = 0; - _pickpocketLootRestore = 0; + ResetPickPocketRefillTimer(); loot.clear(); if (m_originalEntry != GetEntry()) UpdateEntry(m_originalEntry); @@ -2292,7 +2283,7 @@ void Creature::AllLootRemovedFromCorpse() if (loot.loot_type == LOOT_SKINNING) m_corpseRemoveTime = now; else - m_corpseRemoveTime = now + m_corpseDelay * decayRate; + m_corpseRemoveTime = now + uint32(m_corpseDelay * decayRate); m_respawnTime = m_corpseRemoveTime + m_respawnDelay; } diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index f5a0abfc469..0f4dda4c319 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -65,12 +65,12 @@ enum CreatureFlagsExtra CREATURE_FLAG_EXTRA_NO_SKILLGAIN | CREATURE_FLAG_EXTRA_TAUNT_DIMINISH | CREATURE_FLAG_EXTRA_ALL_DIMINISH | \ CREATURE_FLAG_EXTRA_GUARD | CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING) -#define MAX_KILL_CREDIT 2 #define CREATURE_REGEN_INTERVAL 2 * IN_MILLISECONDS +#define MAX_KILL_CREDIT 2 +#define MAX_CREATURE_MODELS 4 #define MAX_CREATURE_QUEST_ITEMS 6 - -#define MAX_EQUIPMENT_ITEMS 3 +#define CREATURE_MAX_SPELLS 8 // from `creature_template` table struct CreatureTemplate @@ -97,13 +97,11 @@ struct CreatureTemplate float speed_run; float scale; uint32 rank; - float mindmg; - float maxdmg; uint32 dmgschool; - uint32 attackpower; - float dmg_multiplier; - uint32 baseattacktime; - uint32 rangeattacktime; + uint32 BaseAttackTime; + uint32 RangeAttackTime; + float BaseVariance; + float RangeVariance; uint32 unit_class; // enum Classes. Note only 4 classes are known for creatures. uint32 unit_flags; // enum UnitFlags mask values uint32 unit_flags2; // enum UnitFlags2 mask values @@ -112,9 +110,6 @@ struct CreatureTemplate uint32 trainer_type; uint32 trainer_class; uint32 trainer_race; - float minrangedmg; - float maxrangedmg; - uint32 rangedattackpower; uint32 type; // enum CreatureType values uint32 type_flags; // enum CreatureTypeFlags mask values uint32 type_flags2; // unknown enum, only set for 4 creatures (with value 1) @@ -135,6 +130,8 @@ struct CreatureTemplate float ModMana; float ModManaExtra; // Added in 4.x, this value is usually 2 for a small group of creatures with double mana float ModArmor; + float ModDamage; + float ModExperience; bool RacialLeader; uint32 questItems[MAX_CREATURE_QUEST_ITEMS]; uint32 movementId; @@ -242,6 +239,8 @@ struct PointOfInterestLocale StringVector IconName; }; +#define MAX_EQUIPMENT_ITEMS 3 + struct EquipmentInfo { uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]; @@ -436,11 +435,11 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject explicit Creature(bool isWorldObject = false); virtual ~Creature(); - void AddToWorld(); - void RemoveFromWorld(); + void AddToWorld() override; + void RemoveFromWorld() override; - void SetObjectScale(float scale); - void SetDisplayId(uint32 modelId); + void SetObjectScale(float scale) override; + void SetDisplayId(uint32 modelId) override; void DisappearAndDie(); @@ -451,8 +450,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; } - void Update(uint32 time); // overwrited Unit::Update - void GetRespawnPosition(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const; + void Update(uint32 time) override; // overwrited Unit::Update + void GetRespawnPosition(float &x, float &y, float &z, float* ori = nullptr, float* dist =nullptr) const; void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; } uint32 GetCorpseDelay() const { return m_corpseDelay; } @@ -462,7 +461,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject bool IsGuard() const { return (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_GUARD) != 0; } bool CanWalk() const { return (GetCreatureTemplate()->InhabitType & INHABIT_GROUND) != 0; } bool CanSwim() const { return (GetCreatureTemplate()->InhabitType & INHABIT_WATER) != 0 || IsPet(); } - bool CanFly() const { return (GetCreatureTemplate()->InhabitType & INHABIT_AIR) != 0; } + bool CanFly() const override { return (GetCreatureTemplate()->InhabitType & INHABIT_AIR) != 0; } void SetReactState(ReactStates st) { m_reactState = st; } ReactStates GetReactState() { return m_reactState; } @@ -473,14 +472,14 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject bool isCanInteractWithBattleMaster(Player* player, bool msg) const; bool isCanTrainingAndResetTalentsOf(Player* player) const; bool CanCreatureAttack(Unit const* victim, bool force = true) const; - bool IsImmunedToSpell(SpellInfo const* spellInfo) const; // override Unit::IsImmunedToSpell - bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; // override Unit::IsImmunedToSpellEffect + bool IsImmunedToSpell(SpellInfo const* spellInfo) const override; // override Unit::IsImmunedToSpell + bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const override; // override Unit::IsImmunedToSpellEffect bool isElite() const; bool isWorldBoss() const; bool IsDungeonBoss() const; - uint8 getLevelForTarget(WorldObject const* target) const; // overwrite Unit::getLevelForTarget for boss level support + uint8 getLevelForTarget(WorldObject const* target) const override; // overwrite Unit::getLevelForTarget for boss level support bool IsInEvadeMode() const { return HasUnitState(UNIT_STATE_EVADE); } @@ -489,7 +488,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject CreatureAI* AI() const { return (CreatureAI*)i_AI; } - SpellSchoolMask GetMeleeDamageSchoolMask() const { return m_meleeDamageSchoolMask; } + SpellSchoolMask GetMeleeDamageSchoolMask() const override { return m_meleeDamageSchoolMask; } void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); } void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time); @@ -498,21 +497,21 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject bool HasSpellCooldown(uint32 spell_id) const; bool HasCategoryCooldown(uint32 spell_id) const; uint32 GetCreatureSpellCooldownDelay(uint32 spellId) const; - virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs); + virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) override; - bool HasSpell(uint32 spellID) const; + bool HasSpell(uint32 spellID) const override; bool UpdateEntry(uint32 entry, CreatureData const* data = nullptr); void UpdateMovementFlags(); - bool UpdateStats(Stats stat); - bool UpdateAllStats(); - void UpdateResistances(uint32 school); - void UpdateArmor(); - void UpdateMaxHealth(); - void UpdateMaxPower(Powers power); - void UpdateAttackPowerAndDamage(bool ranged = false); + bool UpdateStats(Stats stat) override; + bool UpdateAllStats() override; + void UpdateResistances(uint32 school) override; + void UpdateArmor() override; + void UpdateMaxHealth() override; + void UpdateMaxPower(Powers power) override; + void UpdateAttackPowerAndDamage(bool ranged = false) override; void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) override; void SetCanDualWield(bool value) override; @@ -537,9 +536,9 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject uint32 GetScriptId() const; // override WorldObject function for proper name localization - std::string const& GetNameForLocaleIdx(LocaleConstant locale_idx) const; + std::string const& GetNameForLocaleIdx(LocaleConstant locale_idx) const override; - void setDeathState(DeathState s); // override virtual Unit::setDeathState + void setDeathState(DeathState s) override; // override virtual Unit::setDeathState bool LoadFromDB(uint32 guid, Map* map) { return LoadCreatureFromDB(guid, map, false); } bool LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap = true); @@ -551,6 +550,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject Loot loot; void StartPickPocketRefillTimer(); void ResetPickPocketRefillTimer() { _pickpocketLootRestore = 0; } + bool CanGeneratePickPocketLoot() const { return _pickpocketLootRestore <= time(NULL); } void SetSkinner(uint64 guid) { _skinner = guid; } uint64 GetSkinner() const { return _skinner; } // Returns the player who skinned this creature Player* GetLootRecipient() const; @@ -606,7 +606,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject time_t GetRespawnTimeEx() const; void SetRespawnTime(uint32 respawn) { m_respawnTime = respawn ? time(NULL) + respawn : 0; } void Respawn(bool force = false); - void SaveRespawnTime(); + void SaveRespawnTime() override; uint32 GetRespawnDelay() const { return m_respawnDelay; } void SetRespawnDelay(uint32 delay) { m_respawnDelay = delay; } @@ -621,8 +621,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject void SetInCombatWithZone(); - bool hasQuest(uint32 quest_id) const; - bool hasInvolvedQuest(uint32 quest_id) const; + bool hasQuest(uint32 quest_id) const override; + bool hasInvolvedQuest(uint32 quest_id) const override; bool isRegeneratingHealth() { return m_regenHealth; } void setRegeneratingHealth(bool regenHealth) { m_regenHealth = regenHealth; } @@ -673,7 +673,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject bool m_isTempWorldObject; //true when possessed // Handling caster facing during spellcast - void SetTarget(uint64 guid); + void SetTarget(uint64 guid) override; void FocusTarget(Spell const* focusSpell, WorldObject const* target); void ReleaseFocus(Spell const* focusSpell); @@ -725,8 +725,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject uint16 m_LootMode; // Bitmask (default: LOOT_MODE_DEFAULT) that determines what loot will be lootable - bool IsInvisibleDueToDespawn() const; - bool CanAlwaysSee(WorldObject const* obj) const; + bool IsInvisibleDueToDespawn() const override; + bool CanAlwaysSee(WorldObject const* obj) const override; private: void ForcedDespawn(uint32 timeMSToDespawn = 0); @@ -747,7 +747,7 @@ class AssistDelayEvent : public BasicEvent public: AssistDelayEvent(uint64 victim, Unit& owner) : BasicEvent(), m_victim(victim), m_owner(owner) { } - bool Execute(uint64 e_time, uint32 p_time); + bool Execute(uint64 e_time, uint32 p_time) override; void AddAssistant(uint64 guid) { m_assistants.push_back(guid); } private: AssistDelayEvent(); @@ -761,7 +761,7 @@ class ForcedDespawnDelayEvent : public BasicEvent { public: ForcedDespawnDelayEvent(Creature& owner) : BasicEvent(), m_owner(owner) { } - bool Execute(uint64 e_time, uint32 p_time); + bool Execute(uint64 e_time, uint32 p_time) override; private: Creature& m_owner; diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp index 14a76ae07ce..f02543a60af 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -107,7 +107,7 @@ void FormationMgr::LoadCreatureFormations() if (group_member->leaderGUID != memberGUID) { group_member->follow_dist = fields[2].GetFloat(); - group_member->follow_angle = fields[3].GetFloat() * M_PI / 180; + group_member->follow_angle = fields[3].GetFloat() * float(M_PI) / 180; } else { @@ -218,7 +218,7 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z) if (!m_leader) return; - float pathangle = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x); + float pathangle = std::atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x); for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) { @@ -229,9 +229,9 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z) if (itr->second->point_1) { if (m_leader->GetCurrentWaypointID() == itr->second->point_1) - itr->second->follow_angle = (2 * M_PI) - itr->second->follow_angle; + itr->second->follow_angle = (2 * float(M_PI)) - itr->second->follow_angle; if (m_leader->GetCurrentWaypointID() == itr->second->point_2) - itr->second->follow_angle = (2 * M_PI) + itr->second->follow_angle; + itr->second->follow_angle = (2 * float(M_PI)) + itr->second->follow_angle; } float angle = itr->second->follow_angle; diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index 1cee6361172..58cc6eb7d0b 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -42,13 +42,13 @@ class TempSummon : public Creature public: explicit TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject); virtual ~TempSummon() { } - void Update(uint32 time); + void Update(uint32 time) override; virtual void InitStats(uint32 lifetime); virtual void InitSummon(); virtual void UnSummon(uint32 msTime = 0); - void RemoveFromWorld(); + void RemoveFromWorld() override; void SetTempSummonType(TempSummonType type); - void SaveToDB(uint32 /*mapid*/, uint8 /*spawnMask*/, uint32 /*phaseMask*/) { } + void SaveToDB(uint32 /*mapid*/, uint8 /*spawnMask*/, uint32 /*phaseMask*/) override { } Unit* GetSummoner() const; Creature* GetSummonerCreatureBase() const; uint64 GetSummonerGUID() const { return m_summonerGUID; } @@ -67,10 +67,10 @@ class Minion : public TempSummon { public: Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject); - void InitStats(uint32 duration); - void RemoveFromWorld(); + void InitStats(uint32 duration) override; + void RemoveFromWorld() override; Unit* GetOwner() const { return m_owner; } - float GetFollowAngle() const { return m_followAngle; } + float GetFollowAngle() const override { return m_followAngle; } void SetFollowAngle(float angle) { m_followAngle = angle; } bool IsPetGhoul() const {return GetEntry() == 26125;} // Ghoul may be guardian or pet bool IsSpiritWolf() const {return GetEntry() == 29264;} // Spirit wolf from feral spirits @@ -84,17 +84,17 @@ class Guardian : public Minion { public: Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject); - void InitStats(uint32 duration); + void InitStats(uint32 duration) override; bool InitStatsForLevel(uint8 level); - void InitSummon(); + void InitSummon() override; - bool UpdateStats(Stats stat); - bool UpdateAllStats(); - void UpdateResistances(uint32 school); - void UpdateArmor(); - void UpdateMaxHealth(); - void UpdateMaxPower(Powers power); - void UpdateAttackPowerAndDamage(bool ranged = false); + bool UpdateStats(Stats stat) override; + bool UpdateAllStats() override; + void UpdateResistances(uint32 school) override; + void UpdateArmor() override; + void UpdateMaxHealth() override; + void UpdateMaxPower(Powers power) override; + void UpdateAttackPowerAndDamage(bool ranged = false) override; void UpdateDamagePhysical(WeaponAttackType attType) override; int32 GetBonusDamage() const { return m_bonusSpellDamage; } @@ -108,17 +108,17 @@ class Puppet : public Minion { public: Puppet(SummonPropertiesEntry const* properties, Unit* owner); - void InitStats(uint32 duration); - void InitSummon(); - void Update(uint32 time); - void RemoveFromWorld(); + void InitStats(uint32 duration) override; + void InitSummon() override; + void Update(uint32 time) override; + void RemoveFromWorld() override; }; class ForcedUnsummonDelayEvent : public BasicEvent { public: ForcedUnsummonDelayEvent(TempSummon& owner) : BasicEvent(), m_owner(owner) { } - bool Execute(uint64 e_time, uint32 p_time); + bool Execute(uint64 e_time, uint32 p_time) override; private: TempSummon& m_owner; diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h index ed9b5a3af68..c185c669e7b 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.h +++ b/src/server/game/Entities/DynamicObject/DynamicObject.h @@ -38,11 +38,11 @@ class DynamicObject : public WorldObject, public GridObject<DynamicObject>, publ DynamicObject(bool isWorldObject); ~DynamicObject(); - void AddToWorld(); - void RemoveFromWorld(); + void AddToWorld() override; + void RemoveFromWorld() override; bool CreateDynamicObject(uint32 guidlow, Unit* caster, SpellInfo const* spell, Position const& pos, float radius, DynamicObjectType type); - void Update(uint32 p_time); + void Update(uint32 p_time) override; void Remove(); void SetDuration(int32 newDuration); int32 GetDuration() const; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 90f46c4ad86..567ada4cccf 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -143,7 +143,12 @@ void GameObject::AddToWorld() // The state can be changed after GameObject::Create but before GameObject::AddToWorld bool toggledState = GetGoType() == GAMEOBJECT_TYPE_CHEST ? getLootState() == GO_READY : (GetGoState() == GO_STATE_READY || IsTransport()); if (m_model) - GetMap()->InsertGameObjectModel(*m_model); + { + if (Transport* trans = ToTransport()) + trans->SetDelayedAddModelToMap(); + else + GetMap()->InsertGameObjectModel(*m_model); + } EnableCollision(toggledState); WorldObject::AddToWorld(); @@ -1265,7 +1270,7 @@ void GameObject::Use(Unit* user) // the object orientation + 1/2 pi // every slot will be on that straight line - float orthogonalOrientation = GetOrientation()+M_PI*0.5f; + float orthogonalOrientation = GetOrientation() + float(M_PI) * 0.5f; // find nearest slot bool found_free_slot = false; for (ChairSlotAndUser::iterator itr = ChairListSlots.begin(); itr != ChairListSlots.end(); ++itr) @@ -1800,14 +1805,14 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, bool triggered /*= true trigger->setFaction(owner->getFaction()); // needed for GO casts for proper target validation checks trigger->SetOwnerGUID(owner->GetGUID()); - trigger->CastSpell(target ? target : trigger, spellInfo, triggered, 0, 0, owner->GetGUID()); + trigger->CastSpell(target ? target : trigger, spellInfo, triggered, nullptr, nullptr, owner->GetGUID()); } else { trigger->setFaction(14); // Set owner guid for target if no owner available - needed by trigger auras // - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell()) - trigger->CastSpell(target ? target : trigger, spellInfo, triggered, 0, 0, target ? target->GetGUID() : 0); + trigger->CastSpell(target ? target : trigger, spellInfo, triggered, nullptr, nullptr, target ? target->GetGUID() : 0); } } @@ -1830,7 +1835,7 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const float dx = x - GetPositionX(); float dy = y - GetPositionY(); float dz = z - GetPositionZ(); - float dist = sqrt(dx*dx + dy*dy); + float dist = std::sqrt(dx*dx + dy*dy); //! Check if the distance between the 2 objects is 0, can happen if both objects are on the same position. //! The code below this check wont crash if dist is 0 because 0/0 in float operations is valid, and returns infinite if (G3D::fuzzyEq(dist, 0.0f)) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 09c84c71244..c372f05a3ee 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -638,14 +638,14 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map explicit GameObject(); ~GameObject(); - void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const; + void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const override; - void AddToWorld(); - void RemoveFromWorld(); - void CleanupsBeforeDelete(bool finalCleanup = true); + void AddToWorld() override; + void RemoveFromWorld() override; + void CleanupsBeforeDelete(bool finalCleanup = true) override; bool Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit = 0); - void Update(uint32 p_time); + void Update(uint32 p_time) override; static GameObject* GetGameObject(WorldObject& object, uint64 guid); GameObjectTemplate const* GetGOInfo() const { return m_goInfo; } GameObjectData const* GetGOData() const { return m_goData; } @@ -660,7 +660,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map void UpdateRotationFields(float rotation2 = 0.0f, float rotation3 = 0.0f); // overwrite WorldObject function for proper name localization - std::string const& GetNameForLocaleIdx(LocaleConstant locale_idx) const; + std::string const& GetNameForLocaleIdx(LocaleConstant locale_idx) const override; void SaveToDB(); void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask); @@ -760,7 +760,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map uint32 GetUseCount() const { return m_usetimes; } uint32 GetUniqueUseCount() const { return m_unique_users.size(); } - void SaveRespawnTime(); + void SaveRespawnTime() override; Loot loot; @@ -772,8 +772,8 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map uint32 m_groupLootTimer; // (msecs)timer used for group loot uint32 lootingGroupLowGUID; // used to find group which is looting - bool hasQuest(uint32 quest_id) const; - bool hasInvolvedQuest(uint32 quest_id) const; + bool hasQuest(uint32 quest_id) const override; + bool hasInvolvedQuest(uint32 quest_id) const override; bool ActivateToQuest(Player* target) const; void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false, Unit* user = NULL); // 0 = use `gameobject`.`spawntimesecs` @@ -783,10 +783,10 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map bool IsNeverVisible() const override; - bool IsAlwaysVisibleFor(WorldObject const* seer) const; - bool IsInvisibleDueToDespawn() const; + bool IsAlwaysVisibleFor(WorldObject const* seer) const override; + bool IsInvisibleDueToDespawn() const override; - uint8 getLevelForTarget(WorldObject const* target) const + uint8 getLevelForTarget(WorldObject const* target) const override { if (Unit* owner = GetOwner()) return owner->getLevelForTarget(target); @@ -831,10 +831,10 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map Transport* ToTransport() { if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT) return reinterpret_cast<Transport*>(this); else return NULL; } Transport const* ToTransport() const { if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT) return reinterpret_cast<Transport const*>(this); else return NULL; } - float GetStationaryX() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionX(); return GetPositionX(); } - float GetStationaryY() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionY(); return GetPositionY(); } - float GetStationaryZ() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionZ(); return GetPositionZ(); } - float GetStationaryO() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetOrientation(); return GetOrientation(); } + float GetStationaryX() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionX(); return GetPositionX(); } + float GetStationaryY() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionY(); return GetPositionY(); } + float GetStationaryZ() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionZ(); return GetPositionZ(); } + float GetStationaryO() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetOrientation(); return GetOrientation(); } float GetInteractionDistance() const; @@ -876,7 +876,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map void SwitchDoorOrButton(bool activate, bool alternative = false); //! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size. - bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/) const + bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/) const override { //! Following check does check 3d distance return IsInRange(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), dist2compare); diff --git a/src/server/game/Entities/Item/Container/Bag.h b/src/server/game/Entities/Item/Container/Bag.h index 1e39e5a41ad..db0c8edf556 100644 --- a/src/server/game/Entities/Item/Container/Bag.h +++ b/src/server/game/Entities/Item/Container/Bag.h @@ -32,10 +32,10 @@ class Bag : public Item Bag(); ~Bag(); - void AddToWorld(); - void RemoveFromWorld(); + void AddToWorld() override; + void RemoveFromWorld() override; - bool Create(uint32 guidlow, uint32 itemid, Player const* owner); + bool Create(uint32 guidlow, uint32 itemid, Player const* owner) override; void Clear(); void StoreItem(uint8 slot, Item* pItem, bool update); @@ -52,13 +52,13 @@ class Bag : public Item // DB operations // overwrite virtual Item::SaveToDB - void SaveToDB(SQLTransaction& trans); + void SaveToDB(SQLTransaction& trans) override; // overwrite virtual Item::LoadFromDB - bool LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entry); + bool LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entry) override; // overwrite virtual Item::DeleteFromDB - void DeleteFromDB(SQLTransaction& trans); + void DeleteFromDB(SQLTransaction& trans) override; - void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const; + void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override; protected: diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index dcf534690db..2bef85be046 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1545,6 +1545,14 @@ void Item::ItemContainerSaveLootToDB() // but we don't want to resave it. if (!_li->canSave) continue; + // Conditions are not checked when loot is generated, it is checked when loot is sent to a player. + // For items that are lootable, loot is saved to the DB immediately, that means that loot can be + // saved to the DB that the player never should have gotten. This check prevents that, so that only + // items that the player should get in loot are in the DB. + // IE: Horde items are not saved to the DB for Ally players. + Player* const guid = GetOwner(); + if (!_li->AllowedForPlayer(guid)) + continue; stmt_items = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEMCONTAINER_ITEMS); diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index ebd66a64838..25472ff83ee 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -331,8 +331,8 @@ class Item : public Object uState = state; } - bool hasQuest(uint32 quest_id) const { return GetTemplate()->StartQuest == quest_id; } - bool hasInvolvedQuest(uint32 /*quest_id*/) const { return false; } + bool hasQuest(uint32 quest_id) const override { return GetTemplate()->StartQuest == quest_id; } + bool hasInvolvedQuest(uint32 /*quest_id*/) const override { return false; } bool HasStats() const; bool IsPotion() const { return GetTemplate()->IsPotion(); } bool IsVellum() const { return GetTemplate()->IsVellum(); } @@ -358,7 +358,7 @@ class Item : public Object void ClearSoulboundTradeable(Player* currentOwner); bool CheckSoulboundTradeExpire(); - void BuildUpdate(UpdateDataMapType&); + void BuildUpdate(UpdateDataMapType&) override; uint32 GetScriptId() const { return GetTemplate()->ScriptId; } diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 51087e0f966..32a9496803d 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -121,7 +121,7 @@ Object::~Object() } delete [] m_uint32Values; - m_uint32Values = 0; + m_uint32Values = nullptr; } void Object::_InitValues() @@ -1190,11 +1190,11 @@ bool Position::operator==(Position const &a) bool Position::HasInLine(WorldObject const* target, float width) const { - if (!HasInArc(M_PI, target)) + if (!HasInArc(float(M_PI), target)) return false; width += target->GetObjectSize(); float angle = GetRelativeAngle(target); - return fabs(sin(angle)) * GetExactDist2d(target->GetPositionX(), target->GetPositionY()) < width; + return std::fabs(std::sin(angle)) * GetExactDist2d(target->GetPositionX(), target->GetPositionY()) < width; } std::string Position::ToString() const @@ -1379,7 +1379,7 @@ InstanceScript* WorldObject::GetInstanceScript() float WorldObject::GetDistanceZ(const WorldObject* obj) const { - float dz = fabs(GetPositionZ() - obj->GetPositionZ()); + float dz = std::fabs(GetPositionZ() - obj->GetPositionZ()); float sizefactor = GetObjectSize() + obj->GetObjectSize(); float dist = dz - sizefactor; return (dist > 0 ? dist : 0); @@ -1602,7 +1602,7 @@ bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float m void Position::RelocateOffset(const Position & offset) { - m_positionX = GetPositionX() + (offset.GetPositionX() * std::cos(GetOrientation()) + offset.GetPositionY() * std::sin(GetOrientation() + M_PI)); + m_positionX = GetPositionX() + (offset.GetPositionX() * std::cos(GetOrientation()) + offset.GetPositionY() * std::sin(GetOrientation() + float(M_PI))); m_positionY = GetPositionY() + (offset.GetPositionY() * std::cos(GetOrientation()) + offset.GetPositionX() * std::sin(GetOrientation())); m_positionZ = GetPositionZ() + offset.GetPositionZ(); SetOrientation(GetOrientation() + offset.GetOrientation()); @@ -1633,8 +1633,8 @@ float Position::GetAngle(const float x, const float y) const float dx = x - GetPositionX(); float dy = y - GetPositionY(); - float ang = atan2(dy, dx); - ang = (ang >= 0) ? ang : 2 * M_PI + ang; + float ang = std::atan2(dy, dx); + ang = (ang >= 0) ? ang : 2 * float(M_PI) + ang; return ang; } @@ -1643,7 +1643,7 @@ void Position::GetSinCos(const float x, const float y, float &vsin, float &vcos) float dx = GetPositionX() - x; float dy = GetPositionY() - y; - if (fabs(dx) < 0.001f && fabs(dy) < 0.001f) + if (std::fabs(dx) < 0.001f && std::fabs(dy) < 0.001f) { float angle = (float)rand_norm()*static_cast<float>(2*M_PI); vcos = std::cos(angle); @@ -1651,7 +1651,7 @@ void Position::GetSinCos(const float x, const float y, float &vsin, float &vcos) } else { - float dist = sqrt((dx*dx) + (dy*dy)); + float dist = std::sqrt((dx*dx) + (dy*dy)); vcos = dx / dist; vsin = dy / dist; } @@ -1671,8 +1671,8 @@ bool Position::HasInArc(float arc, const Position* obj, float border) const // move angle to range -pi ... +pi angle = NormalizeOrientation(angle); - if (angle > M_PI) - angle -= 2.0f*M_PI; + if (angle > float(M_PI)) + angle -= 2.0f * float(M_PI); float lborder = -1 * (arc/border); // in range -pi..0 float rborder = (arc/border); // in range 0..pi @@ -1706,7 +1706,7 @@ bool WorldObject::isInFront(WorldObject const* target, float arc) const bool WorldObject::isInBack(WorldObject const* target, float arc) const { - return !HasInArc(2 * M_PI - arc, target); + return !HasInArc(2 * float(M_PI) - arc, target); } void WorldObject::GetRandomPoint(const Position &pos, float distance, float &rand_x, float &rand_y, float &rand_z) const @@ -2002,7 +2002,7 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj) const if (distance < combatReach) return true; - if (!HasInArc(M_PI, obj)) + if (!HasInArc(float(M_PI), obj)) return false; GameObject const* go = ToGameObject(); @@ -2670,7 +2670,7 @@ void WorldObject::GetNearPoint(WorldObject const* /*searcher*/, float &x, float float first_z = z; // loop in a circle to look for a point in LoS using small steps - for (float angle = M_PI / 8; angle < M_PI * 2; angle += M_PI / 8) + for (float angle = float(M_PI) / 8; angle < float(M_PI) * 2; angle += float(M_PI) / 8) { GetNearPoint2D(x, y, distance2d + searcher_size, absAngle + angle); z = GetPositionZ(); @@ -2740,20 +2740,20 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle) ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true); floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true); - destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor; + destz = std::fabs(ground - pos.m_positionZ) <= std::fabs(floor - pos.m_positionZ) ? ground : floor; float step = dist/10.0f; for (uint8 j = 0; j < 10; ++j) { // do not allow too big z changes - if (fabs(pos.m_positionZ - destz) > 6) + if (std::fabs(pos.m_positionZ - destz) > 6) { destx -= step * std::cos(angle); desty -= step * std::sin(angle); ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true); floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true); - destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor; + destz = std::fabs(ground - pos.m_positionZ) <= std::fabs(floor - pos.m_positionZ) ? ground : floor; } // we have correct destz now else @@ -2774,7 +2774,7 @@ float NormalizeZforCollision(WorldObject* obj, float x, float y, float z) { float ground = obj->GetMap()->GetHeight(obj->GetPhaseMask(), x, y, MAX_HEIGHT, true); float floor = obj->GetMap()->GetHeight(obj->GetPhaseMask(), x, y, z + 2.0f, true); - float helper = fabs(ground - z) <= fabs(floor - z) ? ground : floor; + float helper = std::fabs(ground - z) <= std::fabs(floor - z) ? ground : floor; if (z > helper) // must be above ground { if (Unit* unit = obj->ToUnit()) @@ -2789,7 +2789,7 @@ float NormalizeZforCollision(WorldObject* obj, float x, float y, float z) if (liquid_status.level > z) // z is underwater return z; else - return fabs(liquid_status.level - z) <= fabs(helper - z) ? liquid_status.level : helper; + return std::fabs(liquid_status.level - z) <= std::fabs(helper - z) ? liquid_status.level : helper; } } return helper; @@ -2818,7 +2818,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float // move back a bit destx -= CONTACT_DISTANCE * std::cos(angle); desty -= CONTACT_DISTANCE * std::sin(angle); - dist = sqrt((pos.m_positionX - destx)*(pos.m_positionX - destx) + (pos.m_positionY - desty)*(pos.m_positionY - desty)); + dist = std::sqrt((pos.m_positionX - destx)*(pos.m_positionX - destx) + (pos.m_positionY - desty)*(pos.m_positionY - desty)); } // check dynamic collision @@ -2829,7 +2829,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float { destx -= CONTACT_DISTANCE * std::cos(angle); desty -= CONTACT_DISTANCE * std::sin(angle); - dist = sqrt((pos.m_positionX - destx)*(pos.m_positionX - destx) + (pos.m_positionY - desty)*(pos.m_positionY - desty)); + dist = std::sqrt((pos.m_positionX - destx)*(pos.m_positionX - destx) + (pos.m_positionY - desty)*(pos.m_positionY - desty)); } float step = dist / 10.0f; @@ -2837,7 +2837,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float for (uint8 j = 0; j < 10; ++j) { // do not allow too big z changes - if (fabs(pos.m_positionZ - destz) > 6.0f) + if (std::fabs(pos.m_positionZ - destz) > 6.0f) { destx -= step * std::cos(angle); desty -= step * std::sin(angle); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 87f94008455..a44c9fa2866 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -263,7 +263,7 @@ class Object void BuildFieldsUpdate(Player*, UpdateDataMapType &) const; void SetFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags |= flag; } - void RemoveFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags &= ~flag; } + void RemoveFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags &= uint16(~flag); } // FG: some hacky helpers void ForceValuesUpdateAtIndex(uint32); @@ -412,19 +412,19 @@ struct Position float GetExactDist2dSq(float x, float y) const { float dx = m_positionX - x; float dy = m_positionY - y; return dx*dx + dy*dy; } float GetExactDist2d(const float x, const float y) const - { return sqrt(GetExactDist2dSq(x, y)); } + { return std::sqrt(GetExactDist2dSq(x, y)); } float GetExactDist2dSq(Position const* pos) const { float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; return dx*dx + dy*dy; } float GetExactDist2d(Position const* pos) const - { return sqrt(GetExactDist2dSq(pos)); } + { return std::sqrt(GetExactDist2dSq(pos)); } float GetExactDistSq(float x, float y, float z) const { float dz = m_positionZ - z; return GetExactDist2dSq(x, y) + dz*dz; } float GetExactDist(float x, float y, float z) const - { return sqrt(GetExactDistSq(x, y, z)); } + { return std::sqrt(GetExactDistSq(x, y, z)); } float GetExactDistSq(Position const* pos) const { float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; float dz = m_positionZ - pos->m_positionZ; return dx*dx + dy*dy + dz*dz; } float GetExactDist(Position const* pos) const - { return sqrt(GetExactDistSq(pos)); } + { return std::sqrt(GetExactDistSq(pos)); } void GetPositionOffsetTo(Position const & endPos, Position & retOffset) const; @@ -455,11 +455,11 @@ struct Position if (o < 0) { float mod = o *-1; - mod = fmod(mod, 2.0f * static_cast<float>(M_PI)); + mod = std::fmod(mod, 2.0f * static_cast<float>(M_PI)); mod = -mod + 2.0f * static_cast<float>(M_PI); return mod; } - return fmod(o, 2.0f * static_cast<float>(M_PI)); + return std::fmod(o, 2.0f * static_cast<float>(M_PI)); } }; ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer); @@ -655,7 +655,7 @@ class WorldObject : public Object, public WorldLocation virtual void Update (uint32 /*time_diff*/) { } void _Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask); - virtual void RemoveFromWorld(); + virtual void RemoveFromWorld() override; void GetNearPoint2D(float &x, float &y, float distance, float absAngle) const; void GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle) const; @@ -718,8 +718,8 @@ class WorldObject : public Object, public WorldLocation bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const; bool IsInRange2d(float x, float y, float minRange, float maxRange) const; bool IsInRange3d(float x, float y, float z, float minRange, float maxRange) const; - bool isInFront(WorldObject const* target, float arc = M_PI) const; - bool isInBack(WorldObject const* target, float arc = M_PI) const; + bool isInFront(WorldObject const* target, float arc = float(M_PI)) const; + bool isInBack(WorldObject const* target, float arc = float(M_PI)) const; bool IsInBetween(WorldObject const* obj1, WorldObject const* obj2, float size = 0) const; @@ -792,7 +792,7 @@ class WorldObject : public Object, public WorldLocation void DestroyForNearbyPlayers(); virtual void UpdateObjectVisibility(bool forced = true); - void BuildUpdate(UpdateDataMapType&); + void BuildUpdate(UpdateDataMapType&) override; //relocation and visibility system functions void AddToNotify(uint16 f) { m_notifyflags |= f;} @@ -885,14 +885,16 @@ namespace Trinity class ObjectDistanceOrderPred { public: - ObjectDistanceOrderPred(WorldObject const* pRefObj, bool ascending = true) : m_refObj(pRefObj), m_ascending(ascending) { } - bool operator()(WorldObject const* pLeft, WorldObject const* pRight) const + ObjectDistanceOrderPred(WorldObject const* refObj, bool ascending = true) : _refObj(refObj), _ascending(ascending) { } + + bool operator()(WorldObject const* left, WorldObject const* right) const { - return m_ascending ? m_refObj->GetDistanceOrder(pLeft, pRight) : !m_refObj->GetDistanceOrder(pLeft, pRight); + return _refObj->GetDistanceOrder(left, right) == _ascending; } + private: - WorldObject const* m_refObj; - const bool m_ascending; + WorldObject const* _refObj; + bool _ascending; }; } diff --git a/src/server/game/Entities/Object/ObjectPosSelector.cpp b/src/server/game/Entities/Object/ObjectPosSelector.cpp index fa7c5dffafa..da2049ac62f 100644 --- a/src/server/game/Entities/Object/ObjectPosSelector.cpp +++ b/src/server/game/Entities/Object/ObjectPosSelector.cpp @@ -21,7 +21,7 @@ ObjectPosSelector::ObjectPosSelector(float x, float y, float size, float dist) : m_center_x(x), m_center_y(y), m_size(size), m_dist(dist) { - m_anglestep = acos(m_dist/(m_dist+2*m_size)); + m_anglestep = std::acos(m_dist/(m_dist+2*m_size)); m_nextUsedPos[USED_POS_PLUS] = m_UsedPosLists[USED_POS_PLUS].end(); m_nextUsedPos[USED_POS_MINUS] = m_UsedPosLists[USED_POS_MINUS].end(); diff --git a/src/server/game/Entities/Object/ObjectPosSelector.h b/src/server/game/Entities/Object/ObjectPosSelector.h index 5bac179880f..44b85dae3dd 100644 --- a/src/server/game/Entities/Object/ObjectPosSelector.h +++ b/src/server/game/Entities/Object/ObjectPosSelector.h @@ -60,10 +60,10 @@ struct ObjectPosSelector float angle_step2 = GetAngle(nextUsedPos.second); float next_angle = nextUsedPos.first; - if (nextUsedPos.second.sign * sign < 0) // last node from diff. list (-pi+alpha) - next_angle = 2*M_PI-next_angle; // move to positive + if (nextUsedPos.second.sign * sign < 0) // last node from diff. list (-pi+alpha) + next_angle = 2 * float(M_PI) - next_angle; // move to positive - return fabs(angle)+angle_step2 <= next_angle; + return std::fabs(angle) + angle_step2 <= next_angle; } bool CheckOriginal() const @@ -105,7 +105,7 @@ struct ObjectPosSelector // next possible angle angle = m_smallStepAngle[uptype] + m_anglestep * sign; - if (fabs(angle) > M_PI) + if (std::fabs(angle) > float(M_PI)) { m_smallStepOk[uptype] = false; return false; @@ -113,7 +113,7 @@ struct ObjectPosSelector if (m_smallStepNextUsedPos[uptype]) { - if (fabs(angle) >= m_smallStepNextUsedPos[uptype]->first) + if (std::fabs(angle) >= m_smallStepNextUsedPos[uptype]->first) { m_smallStepOk[uptype] = false; return false; @@ -136,7 +136,7 @@ struct ObjectPosSelector UsedPosList::value_type const* nextUsedPos(UsedPosType uptype); // angle from used pos to next possible free pos - float GetAngle(UsedPos const& usedPos) const { return acos(m_dist/(usedPos.dist+usedPos.size+m_size)); } + float GetAngle(UsedPos const& usedPos) const { return std::acos(m_dist/(usedPos.dist+usedPos.size+m_size)); } float m_center_x; float m_center_y; diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 5c731c6f8f7..46c9e61886a 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -186,8 +186,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c setFaction(owner->getFaction()); SetUInt32Value(UNIT_CREATED_BY_SPELL, summonSpellId); - CreatureTemplate const* cinfo = GetCreatureTemplate(); - if (cinfo->type == CREATURE_TYPE_CRITTER) + if (IsCritter()) { float px, py, pz; owner->GetClosePoint(px, py, pz, GetObjectSize(), PET_FOLLOW_DIST, GetFollowAngle()); @@ -982,7 +981,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetCreateHealth(30*petlevel); // wolf attack speed is 1.5s - SetAttackTime(BASE_ATTACK, cinfo->baseattacktime); + SetAttackTime(BASE_ATTACK, cinfo->BaseAttackTime); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel))); diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 97323f3f9ab..15383d90bf3 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -43,10 +43,10 @@ class Pet : public Guardian explicit Pet(Player* owner, PetType type = MAX_PET_TYPE); virtual ~Pet(); - void AddToWorld(); - void RemoveFromWorld(); + void AddToWorld() override; + void RemoveFromWorld() override; - void SetDisplayId(uint32 modelId); + void SetDisplayId(uint32 modelId) override; PetType getPetType() const { return m_petType; } void setPetType(PetType type) { m_petType = type; } @@ -60,16 +60,16 @@ class Pet : public Guardian bool CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner); bool CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phaseMask); bool LoadPetFromDB(Player* owner, uint32 petentry = 0, uint32 petnumber = 0, bool current = false); - bool isBeingLoaded() const { return m_loading;} + bool isBeingLoaded() const override { return m_loading;} void SavePetToDB(PetSaveMode mode); void Remove(PetSaveMode mode, bool returnreagent = false); static void DeleteFromDB(uint32 guidlow); - void setDeathState(DeathState s); // overwrite virtual Creature::setDeathState and Unit::setDeathState - void Update(uint32 diff); // overwrite virtual Creature::Update and Unit::Update + void setDeathState(DeathState s) override; // overwrite virtual Creature::setDeathState and Unit::setDeathState + void Update(uint32 diff) override; // overwrite virtual Creature::Update and Unit::Update - uint8 GetPetAutoSpellSize() const { return m_autospells.size(); } - uint32 GetPetAutoSpellOnPos(uint8 pos) const + uint8 GetPetAutoSpellSize() const override { return m_autospells.size(); } + uint32 GetPetAutoSpellOnPos(uint8 pos) const override { if (pos >= m_autospells.size()) return 0; @@ -98,7 +98,7 @@ class Pet : public Guardian void ToggleAutocast(SpellInfo const* spellInfo, bool apply); - bool HasSpell(uint32 spell) const; + bool HasSpell(uint32 spell) const override; void LearnPetPassives(); void CastPetAuras(bool current); @@ -119,7 +119,7 @@ class Pet : public Guardian bool unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true); bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true); void CleanupActionBar(); - virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs); + virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) override; PetSpellMap m_spells; AutoSpellList m_autospells; @@ -127,7 +127,7 @@ class Pet : public Guardian void InitPetCreateSpells(); bool resetTalents(); - static void resetTalentsForAllPetsOf(Player* owner, Pet* online_pet = NULL); + static void resetTalentsForAllPetsOf(Player* owner, Pet* online_pet = nullptr); void InitTalentForLevel(); uint8 GetMaxTalentPointsForLevel(uint8 level); @@ -156,11 +156,11 @@ class Pet : public Guardian DeclinedName *m_declinedname; private: - void SaveToDB(uint32, uint8, uint32) // override of Creature::SaveToDB - must not be called + void SaveToDB(uint32, uint8, uint32) override // override of Creature::SaveToDB - must not be called { ASSERT(false); } - void DeleteFromDB() // override of Creature::DeleteFromDB - must not be called + void DeleteFromDB() override // override of Creature::DeleteFromDB - must not be called { ASSERT(false); } diff --git a/src/server/game/Entities/Pet/PetDefines.h b/src/server/game/Entities/Pet/PetDefines.h index f590bef233e..67435c30577 100644 --- a/src/server/game/Entities/Pet/PetDefines.h +++ b/src/server/game/Entities/Pet/PetDefines.h @@ -75,6 +75,6 @@ enum PetTalk }; #define PET_FOLLOW_DIST 1.0f -#define PET_FOLLOW_ANGLE (M_PI/2) +#define PET_FOLLOW_ANGLE float(M_PI/2) #endif diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 21cb96ac048..6e2706e7607 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -376,7 +376,10 @@ void TradeData::SetMoney(uint64 money) if (!m_player->HasEnoughMoney(money)) { - m_player->GetSession()->SendTradeStatus(TRADE_STATUS_BUSY); + TradeStatusInfo info; + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; + m_player->GetSession()->SendTradeStatus(info); return; } @@ -402,10 +405,12 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/) if (!state) { + TradeStatusInfo info; + info.Status = TRADE_STATUS_BACK_TO_TRADE; if (crosssend) - m_trader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + m_trader->GetSession()->SendTradeStatus(info); else - m_player->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + m_player->GetSession()->SendTradeStatus(info); } } @@ -1636,7 +1641,7 @@ void Player::Update(uint32 p_time) else { q_status.Timer -= p_time; - m_QuestStatusSave[*iter] = true; + m_QuestStatusSave[*iter] = QUEST_DEFAULT_SAVE_TYPE; ++iter; } } @@ -1663,7 +1668,7 @@ void Player::Update(uint32 p_time) } } //120 degrees of radiant range - else if (!HasInArc(2*M_PI/3, victim)) + else if (!HasInArc(2 * float(M_PI) / 3, victim)) { setAttackTimer(BASE_ATTACK, 100); if (m_swingErrorMsg != 2) // send single time (client auto repeat) @@ -1691,7 +1696,7 @@ void Player::Update(uint32 p_time) { if (!IsWithinMeleeRange(victim)) setAttackTimer(OFF_ATTACK, 100); - else if (!HasInArc(2*M_PI/3, victim)) + else if (!HasInArc(2 * float(M_PI) / 3, victim)) setAttackTimer(OFF_ATTACK, 100); else { @@ -2655,7 +2660,7 @@ void Player::Regenerate(Powers power) return; addvalue += m_powerFraction[powerIndex]; - uint32 integerValue = uint32(fabs(addvalue)); + uint32 integerValue = uint32(std::fabs(addvalue)); if (addvalue < 0.0f) { @@ -7102,7 +7107,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto else victim_guid = 0; // Don't show HK: <rank> message, only log. - honor_f = ceil(Trinity::Honor::hk_honor_at_level_f(k_level) * (v_level - k_grey) / (k_level - k_grey)); + honor_f = std::ceil(Trinity::Honor::hk_honor_at_level_f(k_level) * (v_level - k_grey) / (k_level - k_grey)); // count the number of playerkills in one day ApplyModUInt32Value(PLAYER_FIELD_KILLS, 1, true); @@ -9082,7 +9087,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type) loot->FillLoot(1, LootTemplates_Creature, this, true); // It may need a better formula // Now it works like this: lvl10: ~6copper, lvl70: ~9silver - bones->loot.gold = uint32(urand(50, 150) * 0.016f * pow(float(pLevel)/5.76f, 2.5f) * sWorld->getRate(RATE_DROP_MONEY)); + bones->loot.gold = uint32(urand(50, 150) * 0.016f * std::pow(float(pLevel) / 5.76f, 2.5f) * sWorld->getRate(RATE_DROP_MONEY)); } if (bones->lootRecipient != this) @@ -9113,18 +9118,27 @@ void Player::SendLoot(uint64 guid, LootType loot_type) { if (loot->loot_type != LOOT_PICKPOCKETING) { - creature->StartPickPocketRefillTimer(); - loot->clear(); + if (creature->CanGeneratePickPocketLoot()) + { + creature->StartPickPocketRefillTimer(); + loot->clear(); - if (uint32 lootid = creature->GetCreatureTemplate()->pickpocketLootId) - loot->FillLoot(lootid, LootTemplates_Pickpocketing, this, true); + if (uint32 lootid = creature->GetCreatureTemplate()->pickpocketLootId) + loot->FillLoot(lootid, LootTemplates_Pickpocketing, this, true); - // Generate extra money for pick pocket loot - const uint32 a = urand(0, creature->getLevel()/2); - const uint32 b = urand(0, getLevel()/2); - loot->gold = uint32(10 * (a + b) * sWorld->getRate(RATE_DROP_MONEY)); - permission = OWNER_PERMISSION; - } + // Generate extra money for pick pocket loot + const uint32 a = urand(0, creature->getLevel() / 2); + const uint32 b = urand(0, getLevel() / 2); + loot->gold = uint32(10 * (a + b) * sWorld->getRate(RATE_DROP_MONEY)); + permission = OWNER_PERMISSION; + } + else + { + permission = NONE_PERMISSION; + SendLootError(guid, LOOT_ERROR_ALREADY_PICKPOCKETED); + return; + } + } // else - still has pickpocket loot generated & not fully taken } else { @@ -9203,8 +9217,6 @@ void Player::SendLoot(uint64 guid, LootType loot_type) } } - SetLootGUID(guid); - // LOOT_INSIGNIA and LOOT_FISHINGHOLE unsupported by client switch (loot_type) { @@ -9217,21 +9229,35 @@ void Player::SendLoot(uint64 guid, LootType loot_type) // need know merged fishing/corpse loot type for achievements loot->loot_type = loot_type; - WorldPacket data(SMSG_LOOT_RESPONSE, 8 + 1 + 50 + 1 + 1); // we guess size - data << uint64(guid); - data << uint8(loot_type); - data << LootView(*loot, this, permission); + if (permission != NONE_PERMISSION) + { + SetLootGUID(guid); - SendDirectMessage(&data); + WorldPacket data(SMSG_LOOT_RESPONSE, (9 + 50)); // we guess size + data << uint64(guid); + data << uint8(loot_type); + data << LootView(*loot, this, permission); + SendDirectMessage(&data); - // add 'this' player as one of the players that are looting 'loot' - if (permission != NONE_PERMISSION) + // add 'this' player as one of the players that are looting 'loot' loot->AddLooter(GetGUID()); + } + else + SendLootError(GetLootGUID(), LOOT_ERROR_DIDNT_KILL); if (loot_type == LOOT_CORPSE && !IS_ITEM_GUID(guid)) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_LOOTING); } +void Player::SendLootError(uint64 guid, LootError error) +{ + WorldPacket data(SMSG_LOOT_RESPONSE, 10); + data << uint64(guid); + data << uint8(LOOT_NONE); + data << uint8(error); + SendDirectMessage(&data); +} + void Player::SendNotifyLootMoneyRemoved() { WorldPacket data(SMSG_LOOT_CLEAR_MONEY, 0); @@ -10613,7 +10639,7 @@ bool Player::HasItemOrGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 return false; } -InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count) const +InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count /*= NULL*/, uint32* itemLimitCategory /*= NULL*/) const { ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(entry); if (!pProto) @@ -10659,6 +10685,8 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item { if (no_space_count) *no_space_count = count + curcount - limitEntry->maxCount; + if (itemLimitCategory) + *itemLimitCategory = pProto->ItemLimitCategory; return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS; } } @@ -11161,61 +11189,61 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des } ////////////////////////////////////////////////////////////////////////// -InventoryResult Player::CanStoreItems(Item** pItems, int count) const +InventoryResult Player::CanStoreItems(Item** items, int count, uint32* itemLimitCategory) const { - Item* pItem2; + Item* item2; // fill space table - int inv_slot_items[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START]; - int inv_bags[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE]; + uint32 inventoryCounts[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START]; + uint32 bagCounts[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE]; - memset(inv_slot_items, 0, sizeof(int) * (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START)); - memset(inv_bags, 0, sizeof(int) * (INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START) * MAX_BAG_SIZE); + memset(inventoryCounts, 0, sizeof(uint32) * (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START)); + memset(bagCounts, 0, sizeof(uint32) * (INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START) * MAX_BAG_SIZE); for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem2 && !pItem2->IsInTrade()) - inv_slot_items[i - INVENTORY_SLOT_ITEM_START] = pItem2->GetCount(); + item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); + if (item2 && !item2->IsInTrade()) + inventoryCounts[i - INVENTORY_SLOT_ITEM_START] = item2->GetCount(); } for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); j++) { - pItem2 = GetItemByPos(i, j); - if (pItem2 && !pItem2->IsInTrade()) - inv_bags[i - INVENTORY_SLOT_BAG_START][j] = pItem2->GetCount(); + item2 = GetItemByPos(i, j); + if (item2 && !item2->IsInTrade()) + bagCounts[i - INVENTORY_SLOT_BAG_START][j] = item2->GetCount(); } // check free space for all items for (int k = 0; k < count; ++k) { - Item* pItem = pItems[k]; + Item* item = items[k]; // no item - if (!pItem) + if (!item) continue; - TC_LOG_DEBUG("entities.player.items", "STORAGE: CanStoreItems %i. item = %u, count = %u", k + 1, pItem->GetEntry(), pItem->GetCount()); - ItemTemplate const* pProto = pItem->GetTemplate(); + TC_LOG_DEBUG("entities.player.items", "STORAGE: CanStoreItems %i. item = %u, count = %u", k + 1, item->GetEntry(), item->GetCount()); + ItemTemplate const* pProto = item->GetTemplate(); // strange item if (!pProto) return EQUIP_ERR_ITEM_NOT_FOUND; // item used - if (pItem->m_lootGenerated) + if (item->m_lootGenerated) return EQUIP_ERR_LOOT_GONE; // item it 'bind' - if (pItem->IsBindedNotWith(this)) + if (item->IsBindedNotWith(this)) return EQUIP_ERR_NOT_OWNER; ItemTemplate const* pBagProto; // item is 'one item only' - InventoryResult res = CanTakeMoreSimilarItems(pItem); + InventoryResult res = CanTakeMoreSimilarItems(item, itemLimitCategory); if (res != EQUIP_ERR_OK) return res; @@ -11226,10 +11254,10 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const for (int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t) { - pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t); - if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_slot_items[t-INVENTORY_SLOT_ITEM_START] + pItem->GetCount() <= pProto->GetMaxStackSize()) + item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t); + if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inventoryCounts[t-INVENTORY_SLOT_ITEM_START] + item->GetCount() <= pProto->GetMaxStackSize()) { - inv_slot_items[t-INVENTORY_SLOT_ITEM_START] += pItem->GetCount(); + inventoryCounts[t-INVENTORY_SLOT_ITEM_START] += item->GetCount(); b_found = true; break; } @@ -11241,14 +11269,14 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const { if (Bag* bag = GetBagByPos(t)) { - if (ItemCanGoIntoBag(pItem->GetTemplate(), bag->GetTemplate())) + if (ItemCanGoIntoBag(item->GetTemplate(), bag->GetTemplate())) { for (uint32 j = 0; j < bag->GetBagSize(); j++) { - pItem2 = GetItemByPos(t, j); - if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_bags[t-INVENTORY_SLOT_BAG_START][j] + pItem->GetCount() <= pProto->GetMaxStackSize()) + item2 = GetItemByPos(t, j); + if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && bagCounts[t-INVENTORY_SLOT_BAG_START][j] + item->GetCount() <= pProto->GetMaxStackSize()) { - inv_bags[t-INVENTORY_SLOT_BAG_START][j] += pItem->GetCount(); + bagCounts[t-INVENTORY_SLOT_BAG_START][j] += item->GetCount(); b_found = true; break; } @@ -11277,9 +11305,9 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const { for (uint32 j = 0; j < bag->GetBagSize(); j++) { - if (inv_bags[t-INVENTORY_SLOT_BAG_START][j] == 0) + if (bagCounts[t-INVENTORY_SLOT_BAG_START][j] == 0) { - inv_bags[t-INVENTORY_SLOT_BAG_START][j] = 1; + bagCounts[t-INVENTORY_SLOT_BAG_START][j] = 1; b_found = true; break; } @@ -11295,9 +11323,9 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const bool b_found = false; for (int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t) { - if (inv_slot_items[t-INVENTORY_SLOT_ITEM_START] == 0) + if (inventoryCounts[t-INVENTORY_SLOT_ITEM_START] == 0) { - inv_slot_items[t-INVENTORY_SLOT_ITEM_START] = 1; + inventoryCounts[t-INVENTORY_SLOT_ITEM_START] = 1; b_found = true; break; } @@ -11318,9 +11346,9 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const for (uint32 j = 0; j < bag->GetBagSize(); j++) { - if (inv_bags[t-INVENTORY_SLOT_BAG_START][j] == 0) + if (bagCounts[t-INVENTORY_SLOT_BAG_START][j] == 0) { - inv_bags[t-INVENTORY_SLOT_BAG_START][j] = 1; + bagCounts[t-INVENTORY_SLOT_BAG_START][j] = 1; b_found = true; break; } @@ -11330,7 +11358,7 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const // no free slot found? if (!b_found) - return EQUIP_ERR_INV_FULL; + return EQUIP_ERR_BAG_FULL; } return EQUIP_ERR_OK; @@ -11802,39 +11830,42 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const { // Used by group, function NeedBeforeGreed, to know if a prototype can be used by a player - if (proto) - { - if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeam() != HORDE) - return EQUIP_ERR_CANT_EQUIP_EVER; + if (!proto) + return EQUIP_ERR_ITEM_NOT_FOUND; - if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeam() != ALLIANCE) - return EQUIP_ERR_CANT_EQUIP_EVER; + if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeam() != HORDE) + return EQUIP_ERR_CANT_EQUIP_EVER; - if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0) - return EQUIP_ERR_CANT_EQUIP_EVER; + if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeam() != ALLIANCE) + return EQUIP_ERR_CANT_EQUIP_EVER; - if (proto->RequiredSkill != 0) - { - if (GetSkillValue(proto->RequiredSkill) == 0) - return EQUIP_ERR_PROFICIENCY_NEEDED; - else if (GetSkillValue(proto->RequiredSkill) < proto->RequiredSkillRank) - return EQUIP_ERR_CANT_EQUIP_SKILL; - } + if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0) + return EQUIP_ERR_CANT_EQUIP_EVER; - if (proto->RequiredSpell != 0 && !HasSpell(proto->RequiredSpell)) + if (proto->RequiredSkill != 0) + { + if (GetSkillValue(proto->RequiredSkill) == 0) return EQUIP_ERR_PROFICIENCY_NEEDED; + else if (GetSkillValue(proto->RequiredSkill) < proto->RequiredSkillRank) + return EQUIP_ERR_CANT_EQUIP_SKILL; + } + + if (proto->RequiredSpell != 0 && !HasSpell(proto->RequiredSpell)) + return EQUIP_ERR_PROFICIENCY_NEEDED; - if (getLevel() < proto->RequiredLevel) - return EQUIP_ERR_CANT_EQUIP_LEVEL_I; + if (getLevel() < proto->RequiredLevel) + return EQUIP_ERR_CANT_EQUIP_LEVEL_I; - // If World Event is not active, prevent using event dependant items - if (proto->HolidayId && !IsHolidayActive((HolidayIds)proto->HolidayId)) - return EQUIP_ERR_CLIENT_LOCKED_OUT; + // If World Event is not active, prevent using event dependant items + if (proto->HolidayId && !IsHolidayActive((HolidayIds)proto->HolidayId)) + return EQUIP_ERR_CLIENT_LOCKED_OUT; - return EQUIP_ERR_OK; - } + // learning (recipes, mounts, pets, etc.) + if (proto->Spells[0].SpellId == 483 || proto->Spells[0].SpellId == 55884) + if (HasSpell(proto->Spells[1].SpellId)) + return EQUIP_ERR_INTERNAL_BAG_ERROR; - return EQUIP_ERR_ITEM_NOT_FOUND; + return EQUIP_ERR_OK; } InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObject const* lootedObject) const @@ -12895,13 +12926,6 @@ void Player::SwapItem(uint16 src, uint16 dst) // SRC checks - if (pSrcItem->m_lootGenerated) // prevent swap looting item - { - //best error message found for attempting to swap while looting - SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, pSrcItem, NULL); - return; - } - // check unequip potability for equipped items and bank bags if (IsEquipmentPos(src) || IsBagPos(src)) { @@ -12932,13 +12956,6 @@ void Player::SwapItem(uint16 src, uint16 dst) if (pDstItem) { - if (pDstItem->m_lootGenerated) // prevent swap looting item - { - //best error message found for attempting to swap while looting - SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, pDstItem, NULL); - return; - } - // check unequip potability for equipped items and bank bags if (IsEquipmentPos(dst) || IsBagPos(dst)) { @@ -13243,7 +13260,7 @@ void Player::AddItemToBuyBackSlot(Item* pItem) // found empty if (!m_items[i]) { - slot = i; + oldest_slot = i; break; } @@ -15213,7 +15230,7 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) SetQuestSlot(log_slot, quest_id, qtime); - m_QuestStatusSave[quest_id] = true; + m_QuestStatusSave[quest_id] = QUEST_DEFAULT_SAVE_TYPE; StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, quest_id); @@ -15396,7 +15413,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, RemoveActiveQuest(quest_id, false); m_RewardedQuests.insert(quest_id); - m_RewardedQuestsSave[quest_id] = true; + m_RewardedQuestsSave[quest_id] = QUEST_DEFAULT_SAVE_TYPE; // StoreNewItem, mail reward, etc. save data directly to the database // to prevent exploitable data desynchronisation we save the quest status to the database too @@ -16044,7 +16061,7 @@ void Player::SetQuestStatus(uint32 questId, QuestStatus status, bool update /*= if (sObjectMgr->GetQuestTemplate(questId)) { m_QuestStatus[questId].Status = status; - m_QuestStatusSave[questId] = true; + m_QuestStatusSave[questId] = QUEST_DEFAULT_SAVE_TYPE; } if (update) @@ -16057,7 +16074,7 @@ void Player::RemoveActiveQuest(uint32 questId, bool update /*= true*/) if (itr != m_QuestStatus.end()) { m_QuestStatus.erase(itr); - m_QuestStatusSave[questId] = false; + m_QuestStatusSave[questId] = QUEST_DELETE_SAVE_TYPE; } if (update) @@ -16070,7 +16087,7 @@ void Player::RemoveRewardedQuest(uint32 questId, bool update /*= true*/) if (rewItr != m_RewardedQuests.end()) { m_RewardedQuests.erase(rewItr); - m_RewardedQuestsSave[questId] = false; + m_RewardedQuestsSave[questId] = QUEST_FORCE_DELETE_SAVE_TYPE; } if (update) @@ -16236,7 +16253,7 @@ void Player::AdjustQuestReqItemCount(Quest const* quest, QuestStatusData& questS uint32 curitemcount = GetItemCount(quest->RequiredItemId[i], true); questStatusData.ItemCount[i] = std::min(curitemcount, reqitemcount); - m_QuestStatusSave[quest->GetQuestId()] = true; + m_QuestStatusSave[quest->GetQuestId()] = QUEST_DEFAULT_SAVE_TYPE; } } } @@ -16327,7 +16344,7 @@ void Player::AreaExploredOrEventHappens(uint32 questId) if (!q_status.Explored) { q_status.Explored = true; - m_QuestStatusSave[questId] = true; + m_QuestStatusSave[questId] = QUEST_DEFAULT_SAVE_TYPE; } } if (CanCompleteQuest(questId)) @@ -16380,7 +16397,7 @@ void Player::ItemAddedQuestCheck(uint32 entry, uint32 count) if (curitemcount < reqitemcount) { q_status.ItemCount[j] = std::min<uint16>(q_status.ItemCount[j] + count, reqitemcount); - m_QuestStatusSave[questid] = true; + m_QuestStatusSave[questid] = QUEST_DEFAULT_SAVE_TYPE; //SendQuestUpdateAddItem(qInfo, j, additemcount); // FIXME: verify if there's any packet sent updating item @@ -16427,7 +16444,7 @@ void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count) if (newItemCount != q_status.ItemCount[j]) { q_status.ItemCount[j] = newItemCount; - m_QuestStatusSave[questid] = true; + m_QuestStatusSave[questid] = QUEST_DEFAULT_SAVE_TYPE; IncompleteQuest(questid); } return; @@ -16495,7 +16512,7 @@ void Player::KilledMonsterCredit(uint32 entry, uint64 guid /*= 0*/) { q_status.CreatureOrGOCount[j] = curkillcount + addkillcount; - m_QuestStatusSave[questid] = true; + m_QuestStatusSave[questid] = QUEST_DEFAULT_SAVE_TYPE; SendQuestUpdateAddCreatureOrGo(qInfo, guid, j, curkillcount, addkillcount); } @@ -16537,7 +16554,7 @@ void Player::KilledPlayerCredit() { q_status.PlayerCount = curkill + addkillcount; - m_QuestStatusSave[questid] = true; + m_QuestStatusSave[questid] = QUEST_DEFAULT_SAVE_TYPE; SendQuestUpdateAddPlayer(qInfo, curkill, addkillcount); } @@ -16589,7 +16606,7 @@ void Player::KillCreditGO(uint32 entry, uint64 guid) { q_status.CreatureOrGOCount[j] = curCastCount + addCastCount; - m_QuestStatusSave[questid] = true; + m_QuestStatusSave[questid] = QUEST_DEFAULT_SAVE_TYPE; SendQuestUpdateAddCreatureOrGo(qInfo, guid, j, curCastCount, addCastCount); } @@ -16646,7 +16663,7 @@ void Player::TalkedToCreature(uint32 entry, uint64 guid) { q_status.CreatureOrGOCount[j] = curTalkCount + addTalkCount; - m_QuestStatusSave[questid] = true; + m_QuestStatusSave[questid] = QUEST_DEFAULT_SAVE_TYPE; SendQuestUpdateAddCreatureOrGo(qInfo, guid, j, curTalkCount, addTalkCount); } @@ -20008,7 +20025,7 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) for (saveItr = m_QuestStatusSave.begin(); saveItr != m_QuestStatusSave.end(); ++saveItr) { - if (saveItr->second) + if (saveItr->second == QUEST_DEFAULT_SAVE_TYPE) { statusItr = m_QuestStatus.find(saveItr->first); if (statusItr != m_QuestStatus.end() && (keepAbandoned || statusItr->second.Status != QUEST_STATUS_NONE)) @@ -20045,7 +20062,7 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) for (saveItr = m_RewardedQuestsSave.begin(); saveItr != m_RewardedQuestsSave.end(); ++saveItr) { - if (saveItr->second) + if (saveItr->second == QUEST_DEFAULT_SAVE_TYPE) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_QUESTSTATUS_REWARDED); stmt->setUInt32(0, GetGUIDLow()); @@ -20053,7 +20070,7 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) trans->Append(stmt); } - else if (!keepAbandoned) + else if (saveItr->second == QUEST_FORCE_DELETE_SAVE_TYPE || !keepAbandoned) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST); stmt->setUInt32(0, GetGUIDLow()); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index ef65558e13c..80128fcc075 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -606,8 +606,16 @@ enum AtLoginFlags typedef std::map<uint32, QuestStatusData> QuestStatusMap; typedef std::set<uint32> RewardedQuestSet; -// quest, keep -typedef std::map<uint32, bool> QuestStatusSaveMap; +enum QuestSaveType +{ + QUEST_DEFAULT_SAVE_TYPE = 0, + QUEST_DELETE_SAVE_TYPE, + QUEST_FORCE_DELETE_SAVE_TYPE +}; + +// quest +typedef std::map<uint32, QuestSaveType> QuestStatusSaveMap; + enum QuestSlotOffsets { @@ -1061,6 +1069,19 @@ struct BGData bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; } }; +struct TradeStatusInfo +{ + TradeStatusInfo() : Status(TRADE_STATUS_BUSY), TraderGuid(0), Result(EQUIP_ERR_OK), + IsTargetResult(false), ItemLimitCategoryId(0), Slot(0) { } + + TradeStatus Status; + ObjectGuid TraderGuid; + InventoryResult Result; + bool IsTargetResult; + uint32 ItemLimitCategoryId; + uint8 Slot; +}; + struct VoidStorageItem { VoidStorageItem() @@ -1232,12 +1253,12 @@ class Player : public Unit, public GridObject<Player> explicit Player(WorldSession* session); ~Player(); - void CleanupsBeforeDelete(bool finalCleanup = true); + void CleanupsBeforeDelete(bool finalCleanup = true) override; - void AddToWorld(); - void RemoveFromWorld(); + void AddToWorld() override; + void RemoveFromWorld() override; - void SetObjectScale(float scale) + void SetObjectScale(float scale) override { Unit::SetObjectScale(scale); SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, scale * DEFAULT_WORLD_OBJECT_SIZE); @@ -1253,14 +1274,14 @@ class Player : public Unit, public GridObject<Player> bool Create(uint32 guidlow, CharacterCreateInfo* createInfo); - void Update(uint32 time); + void Update(uint32 time) override; static bool BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, ByteBuffer* bitBuffer); void SetInWater(bool apply); - bool IsInWater() const { return m_isInWater; } - bool IsUnderWater() const; + bool IsInWater() const override { return m_isInWater; } + bool IsUnderWater() const override; void SendInitialPacketsBeforeAddToMap(); void SendInitialPacketsAfterAddToMap(); @@ -1319,7 +1340,7 @@ class Player : public Unit, public GridObject<Player> uint32 GetTotalPlayedTime() { return m_Played_time[PLAYED_TIME_TOTAL]; } uint32 GetLevelPlayedTime() { return m_Played_time[PLAYED_TIME_LEVEL]; } - void setDeathState(DeathState s); // overwrite Unit::setDeathState + void setDeathState(DeathState s) override; // overwrite Unit::setDeathState void InnEnter(time_t time, uint32 mapid, float x, float y, float z); @@ -1356,7 +1377,7 @@ class Player : public Unit, public GridObject<Player> /*********************************************************/ void SetVirtualItemSlot(uint8 i, Item* item); - void SetSheath(SheathState sheathed); // overwrite Unit version + void SetSheath(SheathState sheathed) override; // overwrite Unit version uint8 FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) const; uint32 GetItemCount(uint32 item, bool inBankAlso = false, Item* skipItem = NULL) const; uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = NULL) const; @@ -1386,11 +1407,11 @@ class Player : public Unit, public GridObject<Player> bool CanNoReagentCast(SpellInfo const* spellInfo) const; bool HasItemOrGemWithIdEquipped(uint32 item, uint32 count, uint8 except_slot = NULL_SLOT) const; bool HasItemOrGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const; - InventoryResult CanTakeMoreSimilarItems(Item* pItem) const { return CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem); } - InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return CanTakeMoreSimilarItems(entry, count, NULL); } + InventoryResult CanTakeMoreSimilarItems(Item* pItem, uint32* itemLimitCategory = NULL) const { return CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem, NULL, itemLimitCategory); } + InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, uint32* itemLimitCategory = NULL) const { return CanTakeMoreSimilarItems(entry, count, NULL, NULL, itemLimitCategory); } InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = NULL) const; InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap = false) const; - InventoryResult CanStoreItems(Item** pItem, int count) const; + InventoryResult CanStoreItems(Item** items, int count, uint32* itemLimitCategory) const; InventoryResult CanEquipNewItem(uint8 slot, uint16& dest, uint32 item, bool swap) const; InventoryResult CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool swap, bool not_loading = true) const; @@ -1414,7 +1435,7 @@ class Player : public Unit, public GridObject<Player> void AutoStoreLoot(uint32 loot_id, LootStore const& store, bool broadcast = false) { AutoStoreLoot(NULL_BAG, NULL_SLOT, loot_id, store, broadcast); } void StoreLootItem(uint8 lootSlot, Loot* loot); - InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const; + InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL, uint32* itemLimitCategory = NULL) const; InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item* pItem = NULL, bool swap = false, uint32* no_space_count = NULL) const; void AddRefundReference(uint32 it); @@ -1653,7 +1674,7 @@ class Player : public Unit, public GridObject<Player> /*********************************************************/ bool LoadFromDB(uint32 guid, SQLQueryHolder *holder); - bool isBeingLoaded() const; + bool isBeingLoaded() const override; void Initialize(uint32 guid); static uint32 GetUInt32ValueFromArray(Tokenizer const& data, uint16 index); @@ -1758,7 +1779,7 @@ class Player : public Unit, public GridObject<Player> void PossessSpellInitialize(); void VehicleSpellInitialize(); void SendRemoveControlBar(); - bool HasSpell(uint32 spell) const; + bool HasSpell(uint32 spell) const override; bool HasActiveSpell(uint32 spell) const; // show in spellbook TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const; bool IsSpellFitByClassAndRace(uint32 spell_id) const; @@ -1854,7 +1875,7 @@ class Player : public Unit, public GridObject<Player> void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time); void ModifySpellCooldown(uint32 spellId, int32 cooldown); void SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId = 0, Spell* spell = NULL, bool setCooldown = true); - void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs); + void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) override; void RemoveSpellCooldown(uint32 spell_id, bool update = false); void RemoveSpellCategoryCooldown(uint32 cat, bool update = false); void SendClearCooldown(uint32 spell_id, Unit* target); @@ -1975,14 +1996,14 @@ class Player : public Unit, public GridObject<Player> float GetHealthBonusFromStamina(); float GetManaBonusFromIntellect(); - bool UpdateStats(Stats stat); - bool UpdateAllStats(); + bool UpdateStats(Stats stat) override; + bool UpdateAllStats() override; void ApplySpellPenetrationBonus(int32 amount, bool apply); - void UpdateResistances(uint32 school); - void UpdateArmor(); - void UpdateMaxHealth(); - void UpdateMaxPower(Powers power); - void UpdateAttackPowerAndDamage(bool ranged = false); + void UpdateResistances(uint32 school) override; + void UpdateArmor() override; + void UpdateMaxHealth() override; + void UpdateMaxPower(Powers power) override; + void UpdateAttackPowerAndDamage(bool ranged = false) override; void ApplySpellPowerBonus(int32 amount, bool apply); void UpdateSpellDamageAndHealingBonus(); void ApplyRatingMod(CombatRating cr, int32 value, bool apply); @@ -2032,8 +2053,8 @@ class Player : public Unit, public GridObject<Player> WorldSession* GetSession() const { return m_session; } - void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const; - void DestroyForPlayer(Player* target, bool onDeath = false) const; + void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override; + void DestroyForPlayer(Player* target, bool onDeath = false) const override; void SendLogXPGain(uint32 GivenXP, Unit* victim, uint32 BonusXP, bool recruitAFriend = false, float group_rate=1.0f); // notifiers @@ -2052,14 +2073,14 @@ class Player : public Unit, public GridObject<Player> void SendResetInstanceFailed(uint32 reason, uint32 MapId); void SendResetFailedNotify(uint32 mapid); - virtual bool UpdatePosition(float x, float y, float z, float orientation, bool teleport = false); + virtual bool UpdatePosition(float x, float y, float z, float orientation, bool teleport = false) override; bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } - void UpdateUnderwaterState(Map* m, float x, float y, float z); + void UpdateUnderwaterState(Map* m, float x, float y, float z) override; - void SendMessageToSet(WorldPacket* data, bool self) {SendMessageToSetInRange(data, GetVisibilityRange(), self); };// overwrite Object::SendMessageToSet - void SendMessageToSetInRange(WorldPacket* data, float fist, bool self);// overwrite Object::SendMessageToSetInRange + void SendMessageToSet(WorldPacket* data, bool self) override {SendMessageToSetInRange(data, GetVisibilityRange(), self); };// overwrite Object::SendMessageToSet + void SendMessageToSetInRange(WorldPacket* data, float fist, bool self) override;// overwrite Object::SendMessageToSetInRange void SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only); - void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr); + void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) override; Corpse* GetCorpse() const; void SpawnCorpseBones(); @@ -2221,6 +2242,7 @@ class Player : public Unit, public GridObject<Player> std::vector<ItemSetEffect*> ItemSetEff; void SendLoot(uint64 guid, LootType loot_type); + void SendLootError(uint64 guid, LootError error); void SendLootRelease(uint64 guid); void SendNotifyLootItemRemoved(uint8 lootSlot); void SendNotifyLootMoneyRemoved(); @@ -2360,12 +2382,12 @@ class Player : public Unit, public GridObject<Player> bool HaveAtClient(WorldObject const* u) const; - bool IsNeverVisible() const; + bool IsNeverVisible() const override; bool IsVisibleGloballyFor(Player const* player) const; void SendInitialVisiblePackets(Unit* target); - void UpdateObjectVisibility(bool forced = true); + void UpdateObjectVisibility(bool forced = true) override; void UpdateVisibilityForPlayer(); void UpdateVisibilityOf(WorldObject* target); void UpdateTriggerVisibility(); @@ -2462,8 +2484,8 @@ class Player : public Unit, public GridObject<Player> MapReference &GetMapRef() { return m_mapRef; } // Set map to player and add reference - void SetMap(Map* map); - void ResetMap(); + void SetMap(Map* map) override; + void ResetMap() override; bool isAllowedToLoot(const Creature* creature); @@ -2822,9 +2844,9 @@ class Player : public Unit, public GridObject<Player> Runes *m_runes; EquipmentSets m_EquipmentSets; - bool CanAlwaysSee(WorldObject const* obj) const; + bool CanAlwaysSee(WorldObject const* obj) const override; - bool IsAlwaysDetectableFor(WorldObject const* seer) const; + bool IsAlwaysDetectableFor(WorldObject const* seer) const override; uint8 m_grantableLevels; diff --git a/src/server/game/Entities/Totem/Totem.h b/src/server/game/Entities/Totem/Totem.h index 5a2f3f5773a..1d79eb3a3df 100644 --- a/src/server/game/Entities/Totem/Totem.h +++ b/src/server/game/Entities/Totem/Totem.h @@ -40,25 +40,25 @@ class Totem : public Minion public: Totem(SummonPropertiesEntry const* properties, Unit* owner); virtual ~Totem() { } - void Update(uint32 time); - void InitStats(uint32 duration); - void InitSummon(); - void UnSummon(uint32 msTime = 0); + void Update(uint32 time) override; + void InitStats(uint32 duration) override; + void InitSummon() override; + void UnSummon(uint32 msTime = 0) override; uint32 GetSpell(uint8 slot = 0) const { return m_spells[slot]; } uint32 GetTotemDuration() const { return m_duration; } void SetTotemDuration(uint32 duration) { m_duration = duration; } TotemType GetTotemType() const { return m_type; } - bool UpdateStats(Stats /*stat*/) { return true; } - bool UpdateAllStats() { return true; } - void UpdateResistances(uint32 /*school*/) { } - void UpdateArmor() { } - void UpdateMaxHealth() { } - void UpdateMaxPower(Powers /*power*/) { } - void UpdateAttackPowerAndDamage(bool /*ranged*/) { } + bool UpdateStats(Stats /*stat*/) override { return true; } + bool UpdateAllStats() override { return true; } + void UpdateResistances(uint32 /*school*/) override { } + void UpdateArmor() override { } + void UpdateMaxHealth() override { } + void UpdateMaxPower(Powers /*power*/) override { } + void UpdateAttackPowerAndDamage(bool /*ranged*/) override { } void UpdateDamagePhysical(WeaponAttackType /*attType*/) override { } - bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; + bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const override; protected: TotemType m_type; diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 0c22caed882..40e073a1500 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -35,7 +35,8 @@ Transport::Transport() : GameObject(), _transportInfo(NULL), _isMoving(true), _pendingStop(false), - _triggeredArrivalEvent(false), _triggeredDepartureEvent(false), _passengerTeleportItr(_passengers.begin()) + _triggeredArrivalEvent(false), _triggeredDepartureEvent(false), + _passengerTeleportItr(_passengers.begin()), _delayedAddModel(false) { m_updateFlag = UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION; } @@ -186,6 +187,14 @@ void Transport::Update(uint32 diff) return; // Update more in new map thread } + // Add model to map after we are fully done with moving maps + if (_delayedAddModel) + { + _delayedAddModel = false; + if (m_model) + GetMap()->InsertGameObjectModel(*m_model); + } + // Set position _positionChangeTimer.Update(diff); if (_positionChangeTimer.Passed()) @@ -197,7 +206,7 @@ void Transport::Update(uint32 diff) G3D::Vector3 pos, dir; _currentFrame->Spline->evaluate_percent(_currentFrame->Index, t, pos); _currentFrame->Spline->evaluate_derivative(_currentFrame->Index, t, dir); - UpdatePosition(pos.x, pos.y, pos.z, atan2(dir.y, dir.x) + M_PI); + UpdatePosition(pos.x, pos.y, pos.z, std::atan2(dir.y, dir.x) + float(M_PI)); } else { @@ -635,7 +644,6 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl } Relocate(x, y, z, o); - UpdateModelPosition(); GetMap()->AddToMap<Transport>(this); return true; } diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 7da8c11861c..6fd13e76034 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -95,6 +95,8 @@ class Transport : public GameObject, public TransportBase void EnableMovement(bool enabled); + void SetDelayedAddModelToMap() { _delayedAddModel = true; } + TransportTemplate const* GetTransportTemplate() const { return _transportInfo; } private: @@ -123,6 +125,8 @@ class Transport : public GameObject, public TransportBase PassengerSet _passengers; PassengerSet::iterator _passengerTeleportItr; PassengerSet _staticPassengers; + + bool _delayedAddModel; }; #endif diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 06179692845..541a7c711ec 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -750,7 +750,7 @@ void Player::UpdateManaRegen() // SpiritRegen(SPI, INT, LEVEL) = (0.001 + (SPI x sqrt(INT) x BASE_REGEN[LEVEL])) x 5 if (GetStat(STAT_INTELLECT) > 0.0f) - spirit_regen *= sqrt(GetStat(STAT_INTELLECT)); + spirit_regen *= std::sqrt(GetStat(STAT_INTELLECT)); // CombatRegen = 5% of Base Mana float base_regen = GetCreateMana() * 0.01f + GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) / 5.0f; @@ -901,17 +901,21 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged) void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) { + float variance = 1.0f; UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: + variance = GetCreatureTemplate()->BaseVariance; unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: + variance = GetCreatureTemplate()->BaseVariance; unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: + variance = GetCreatureTemplate()->RangeVariance; unitMod = UNIT_MOD_DAMAGE_RANGED; break; } @@ -934,11 +938,11 @@ void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float attackPower = GetTotalAttackPowerValue(attType); float attackSpeedMulti = GetAPMultiplier(attType, normalized); - float baseValue = GetModifierValue(unitMod, BASE_VALUE) + (attackPower / 14.0f); + float baseValue = GetModifierValue(unitMod, BASE_VALUE) + (attackPower / 14.0f) * variance; float basePct = GetModifierValue(unitMod, BASE_PCT) * attackSpeedMulti; float totalValue = GetModifierValue(unitMod, TOTAL_VALUE); float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; - float dmgMultiplier = GetCreatureTemplate()->dmg_multiplier; // = dmg_multiplier * _GetDamageMod(rank); + float dmgMultiplier = GetCreatureTemplate()->ModDamage; // = ModDamage * _GetDamageMod(rank); minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct; maxDamage = ((weaponMaxDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f096170c46d..6742852a481 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -62,7 +62,7 @@ #include "MovementStructures.h" #include "WorldSession.h" -#include <math.h> +#include <cmath> float baseMoveSpeed[MAX_MOVE_TYPE] = { @@ -1322,7 +1322,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) // If this is a creature and it attacks from behind it has a probability to daze it's victim if ((damageInfo->hitOutCome == MELEE_HIT_CRIT || damageInfo->hitOutCome == MELEE_HIT_CRUSHING || damageInfo->hitOutCome == MELEE_HIT_NORMAL || damageInfo->hitOutCome == MELEE_HIT_GLANCING) && - GetTypeId() != TYPEID_PLAYER && !ToCreature()->IsControlledByPlayer() && !victim->HasInArc(M_PI, this) + GetTypeId() != TYPEID_PLAYER && !ToCreature()->IsControlledByPlayer() && !victim->HasInArc(float(M_PI), this) && (victim->GetTypeId() == TYPEID_PLAYER || !victim->ToCreature()->isWorldBoss())&& !victim->IsVehicle()) { // -probability is between 0% and 40% @@ -1336,7 +1336,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) uint32 VictimDefense = victim->GetMaxSkillValueForLevel(this); uint32 AttackerMeleeSkill = GetMaxSkillValueForLevel(); - Probability *= AttackerMeleeSkill/(float)VictimDefense*0.16; + Probability *= AttackerMeleeSkill/(float)VictimDefense*0.16f; if (Probability < 0) Probability = 0; @@ -1456,7 +1456,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo for (AuraEffectList::const_iterator j = resIgnoreAuras.begin(); j != resIgnoreAuras.end(); ++j) { if ((*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) - armor = floor(AddPct(armor, -(*j)->GetAmount())); + armor = std::floor(AddPct(armor, -(*j)->GetAmount())); } // Apply Player CR_ARMOR_PENETRATION rating @@ -1544,7 +1544,7 @@ uint32 Unit::CalcSpellResistance(Unit* victim, SpellSchoolMask schoolMask, Spell float discreteResistProbability[11]; for (uint32 i = 0; i < 11; ++i) { - discreteResistProbability[i] = 0.5f - 2.5f * fabs(0.1f * i - averageResist); + discreteResistProbability[i] = 0.5f - 2.5f * std::fabs(0.1f * i - averageResist); if (discreteResistProbability[i] < 0.0f) discreteResistProbability[i] = 0.0f; } @@ -1932,7 +1932,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT // Dodge chance // only players can't dodge if attacker is behind - if (victim->GetTypeId() == TYPEID_PLAYER && !victim->HasInArc(M_PI, this) && !victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)) + if (victim->GetTypeId() == TYPEID_PLAYER && !victim->HasInArc(float(M_PI), this) && !victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)) { TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: attack came from behind and victim was a player."); } @@ -1961,7 +1961,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT // parry & block chances // check if attack comes from behind, nobody can parry or block if attacker is behind - if (!victim->HasInArc(M_PI, this) && !victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)) + if (!victim->HasInArc(float(M_PI), this) && !victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)) TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: attack came from behind."); else { @@ -2139,7 +2139,7 @@ bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttac if (spellProto && spellProto->Attributes & SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK) return false; - if (victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION) || victim->HasInArc(M_PI, this)) + if (victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION) || victim->HasInArc(float(M_PI), this)) { // Check creatures flags_extra for disable block if (victim->GetTypeId() == TYPEID_UNIT && @@ -2259,7 +2259,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo canDodge = false; // only if in front - if (victim->HasInArc(M_PI, this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)) + if (victim->HasInArc(float(M_PI), this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)) { int32 deflect_chance = victim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS) * 100; tmp += deflect_chance; @@ -2270,7 +2270,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo } // Check for attack from behind - if (!victim->HasInArc(M_PI, this)) + if (!victim->HasInArc(float(M_PI), this)) { if (!victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)) { @@ -2425,7 +2425,7 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo return SPELL_MISS_RESIST; // cast by caster in front of victim - if (victim->HasInArc(M_PI, this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)) + if (victim->HasInArc(float(M_PI), this) || victim->HasAuraType(SPELL_AURA_IGNORE_HIT_DIRECTION)) { int32 deflect_chance = victim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS) * 100; tmp += deflect_chance; @@ -2918,7 +2918,7 @@ bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const { - return IsWithinDistInMap(target, distance) && !HasInArc(2 * M_PI - arc, target); + return IsWithinDistInMap(target, distance) && !HasInArc(2 * float(M_PI) - arc, target); } bool Unit::isInAccessiblePlaceFor(Creature const* c) const @@ -9901,7 +9901,7 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellInfo* spe if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_PROC_PER_MINUTE, PPM); - return floor((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60)) + return std::floor((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60)) } void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) @@ -11133,6 +11133,10 @@ int32 Unit::ModSpellDuration(SpellInfo const* spellProto, Unit const* target, in if (duration < 0) return duration; + // some auras are not affected by duration modifiers + if (spellProto->AttributesEx7 & SPELL_ATTR7_IGNORE_DURATION_MODS) + return duration; + // cut duration only of negative effects if (!positive) { @@ -11983,7 +11987,7 @@ void Unit::DeleteCharmInfo() } CharmInfo::CharmInfo(Unit* unit) -: _unit(unit), _CommandState(COMMAND_FOLLOW), _petnumber(0), _barInit(false), _oldReactState(REACT_PASSIVE), +: _unit(unit), _CommandState(COMMAND_FOLLOW), _petnumber(0), _oldReactState(REACT_PASSIVE), _isCommandAttack(false), _isCommandFollow(false), _isAtStay(false), _isFollowing(false), _isReturning(false), _stayX(0.0f), _stayY(0.0f), _stayZ(0.0f) { @@ -13026,7 +13030,7 @@ Unit* Unit::SelectNearbyTarget(Unit* exclude, float dist) const // remove not LoS targets for (std::list<Unit*>::iterator tIter = targets.begin(); tIter != targets.end();) { - if (!IsWithinLOSInMap(*tIter) || (*tIter)->IsTotem() || (*tIter)->IsSpiritService() || (*tIter)->GetCreatureType() == CREATURE_TYPE_CRITTER) + if (!IsWithinLOSInMap(*tIter) || (*tIter)->IsTotem() || (*tIter)->IsSpiritService() || (*tIter)->IsCritter()) targets.erase(tIter++); else ++tIter; @@ -13651,8 +13655,6 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) if (creature) { Loot* loot = &creature->loot; - if (creature->loot.loot_type == LOOT_PICKPOCKETING) - creature->ResetPickPocketRefillTimer(); loot->clear(); if (uint32 lootid = creature->GetCreatureTemplate()->lootid) @@ -13681,7 +13683,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) if (Unit* owner = GetOwner()) owner->ProcDamageAndSpell(victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_EX_NONE, 0); - if (victim->GetCreatureType() != CREATURE_TYPE_CRITTER) + if (!victim->IsCritter()) ProcDamageAndSpell(victim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0); // Proc auras on death - must be before aura/combat remove @@ -15230,7 +15232,7 @@ uint32 Unit::GetModelForTotem(PlayerTotemType totemType) void Unit::JumpTo(float speedXY, float speedZ, bool forward) { - float angle = forward ? 0 : M_PI; + float angle = forward ? 0 : float(M_PI); if (GetTypeId() == TYPEID_UNIT) GetMotionMaster()->MoveJumpTo(angle, speedXY, speedZ); else diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 035c3a6aa0e..b9d3a287456 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -266,7 +266,6 @@ enum UnitRename UNIT_CAN_BE_ABANDONED = 0x02 }; -#define CREATURE_MAX_SPELLS 8 #define MAX_SPELL_CHARM 4 #define MAX_SPELL_VEHICLE 6 #define MAX_SPELL_POSSESS 8 @@ -1211,7 +1210,6 @@ struct CharmInfo CharmSpellInfo _charmspells[4]; CommandStates _CommandState; uint32 _petnumber; - bool _barInit; //for restoration after charmed ReactStates _oldReactState; @@ -1302,8 +1300,8 @@ class Unit : public WorldObject UnitAI* GetAI() { return i_AI; } void SetAI(UnitAI* newAI) { i_AI = newAI; } - void AddToWorld(); - void RemoveFromWorld(); + void AddToWorld() override; + void RemoveFromWorld() override; void CleanupBeforeRemoveFromMap(bool finalCleanup); void CleanupsBeforeDelete(bool finalCleanup = true) override; // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units) @@ -1318,7 +1316,7 @@ class Unit : public WorldObject float GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const; float GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const; - virtual void Update(uint32 time); + virtual void Update(uint32 time) override; void setAttackTimer(WeaponAttackType type, uint32 time) { m_attackTimer[type] = time; } void resetAttackTimer(WeaponAttackType type = BASE_ATTACK); @@ -1374,7 +1372,7 @@ class Unit : public WorldObject bool IsVehicle() const { return (m_unitTypeMask & UNIT_MASK_VEHICLE) != 0; } uint8 getLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); } - uint8 getLevelForTarget(WorldObject const* /*target*/) const { return getLevel(); } + uint8 getLevelForTarget(WorldObject const* /*target*/) const override { return getLevel(); } void SetLevel(uint8 lvl); uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); } uint32 getRaceMask() const { return 1 << (getRace()-1); } @@ -1539,6 +1537,7 @@ class Unit : public WorldObject bool IsArmorer() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_REPAIR); } bool IsServiceProvider() const; bool IsSpiritService() const { return HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE); } + bool IsCritter() const { return GetCreatureType() == CREATURE_TYPE_CRITTER; } bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); } @@ -1920,8 +1919,8 @@ class Unit : public WorldObject uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct); float GetAPMultiplier(WeaponAttackType attType, bool normalized); - bool isInFrontInMap(Unit const* target, float distance, float arc = M_PI) const; - bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const; + bool isInFrontInMap(Unit const* target, float distance, float arc = float(M_PI)) const; + bool isInBackInMap(Unit const* target, float distance, float arc = float(M_PI)) const; // Visibility system bool IsVisible() const; @@ -1929,7 +1928,7 @@ class Unit : public WorldObject // common function for visibility checks for player/creatures with detection code void SetInPhase(uint32 id, bool update, bool apply); - void UpdateObjectVisibility(bool forced = true); + void UpdateObjectVisibility(bool forced = true) override; SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]; uint32 m_lastSanctuaryTime; @@ -2114,7 +2113,7 @@ class Unit : public WorldObject bool IsOnVehicle(const Unit* vehicle) const; Unit* GetVehicleBase() const; Creature* GetVehicleCreatureBase() const; - uint64 GetTransGUID() const; + uint64 GetTransGUID() const override; /// Returns the transport this unit is on directly (if on vehicle and transport, return vehicle) TransportBase* GetDirectTransport() const; @@ -2170,7 +2169,7 @@ class Unit : public WorldObject protected: explicit Unit (bool isWorldObject); - void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const; + void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const override; UnitAI* i_AI, *i_disabledAI; @@ -2239,8 +2238,8 @@ class Unit : public WorldObject uint32 m_unitTypeMask; LiquidTypeEntry const* _lastLiquid; - bool IsAlwaysVisibleFor(WorldObject const* seer) const; - bool IsAlwaysDetectableFor(WorldObject const* seer) const; + bool IsAlwaysVisibleFor(WorldObject const* seer) const override; + bool IsAlwaysDetectableFor(WorldObject const* seer) const override; void DisableSpline(); private: diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 36119fa0027..be008330f0c 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -89,7 +89,7 @@ class Vehicle : public TransportBase void InitMovementInfoForBase(); /// This method transforms supplied transport offsets into global coordinates - void CalculatePassengerPosition(float& x, float& y, float& z, float* o /*= NULL*/) const + void CalculatePassengerPosition(float& x, float& y, float& z, float* o /*= NULL*/) const override { TransportBase::CalculatePassengerPosition(x, y, z, o, GetBase()->GetPositionX(), GetBase()->GetPositionY(), @@ -97,7 +97,7 @@ class Vehicle : public TransportBase } /// This method transforms supplied global coordinates into local offsets - void CalculatePassengerOffset(float& x, float& y, float& z, float* o /*= NULL*/) const + void CalculatePassengerOffset(float& x, float& y, float& z, float* o /*= NULL*/) const override { TransportBase::CalculatePassengerOffset(x, y, z, o, GetBase()->GetPositionX(), GetBase()->GetPositionY(), @@ -126,8 +126,8 @@ class VehicleJoinEvent : public BasicEvent protected: VehicleJoinEvent(Vehicle* v, Unit* u) : Target(v), Passenger(u), Seat(Target->Seats.end()) { } ~VehicleJoinEvent(); - bool Execute(uint64, uint32); - void Abort(uint64); + bool Execute(uint64, uint32) override; + void Abort(uint64) override; Vehicle* Target; Unit* Passenger; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 93c06146c06..f16ab30567f 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -348,7 +348,7 @@ void ObjectMgr::LoadCreatureLocales() CreatureLocale& data = _creatureLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; AddLocaleString(fields[1 + 3 * (i - 1)].GetString(), locale, data.Name); @@ -357,7 +357,7 @@ void ObjectMgr::LoadCreatureLocales() } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu creature locale strings in %u ms", (unsigned long)_creatureLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u creature locale strings in %u ms", uint32(_creatureLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadGossipMenuItemsLocales() @@ -385,7 +385,7 @@ void ObjectMgr::LoadGossipMenuItemsLocales() GossipMenuItemsLocale& data = _gossipMenuItemsLocaleStore[MAKE_PAIR32(menuId, id)]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; AddLocaleString(fields[2 + 2 * (i - 1)].GetString(), locale, data.OptionText); @@ -394,7 +394,7 @@ void ObjectMgr::LoadGossipMenuItemsLocales() } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu gossip_menu_option locale strings in %u ms", (unsigned long)_gossipMenuItemsLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u gossip_menu_option locale strings in %u ms", uint32(_gossipMenuItemsLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadPointOfInterestLocales() @@ -416,34 +416,36 @@ void ObjectMgr::LoadPointOfInterestLocales() PointOfInterestLocale& data = _pointOfInterestLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.IconName); } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu points_of_interest locale strings in %u ms", (unsigned long)_pointOfInterestLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u points_of_interest locale strings in %u ms", uint32(_pointOfInterestLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadCreatureTemplates() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 8 + // 0 1 2 3 4 5 6 7 8 QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, " - // 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + // 9 10 11 12 13 14 15 16 17 18 19 20 21 22 "modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, " - // 23 24 25 26 27 28 29 30 31 32 33 34 - "scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, " - // 35 36 37 38 39 40 41 42 43 - "dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, " - // 44 45 46 47 48 49 50 51 52 53 54 + // 23 24 25 26 27 28 29 30 31 32 + "scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, " + // 33 34 35 36 37 38 + "dynamicflags, family, trainer_type, trainer_class, trainer_race, type, " + // 39 40 41 42 43 44 45 46 47 48 49 "type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, " - // 55 56 57 58 59 60 61 62 63 64 65 66 67 68 + // 50 51 52 53 54 55 56 57 58 59 60 61 62 63 "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, " - // 69 70 71 72 73 74 75 76 77 78 79 80 - "InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, " - // 81 82 83 84 85 86 - " questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName " - "FROM creature_template;"); + // 64 65 66 67 68 69 70 71 + "InhabitType, HoverHeight, HealthModifier, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, " + // 72 73 74 75 76 77 78 + "RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, " + // 79 80 81 82 83 + "movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName " + "FROM creature_template"); if (!result) { @@ -456,93 +458,7 @@ void ObjectMgr::LoadCreatureTemplates() do { Field* fields = result->Fetch(); - - uint32 entry = fields[0].GetUInt32(); - - - CreatureTemplate& creatureTemplate = _creatureTemplateStore[entry]; - - creatureTemplate.Entry = entry; - - for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i) - creatureTemplate.DifficultyEntry[i] = fields[1 + i].GetUInt32(); - - for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i) - creatureTemplate.KillCredit[i] = fields[4 + i].GetUInt32(); - - creatureTemplate.Modelid1 = fields[6].GetUInt32(); - creatureTemplate.Modelid2 = fields[7].GetUInt32(); - creatureTemplate.Modelid3 = fields[8].GetUInt32(); - creatureTemplate.Modelid4 = fields[9].GetUInt32(); - creatureTemplate.Name = fields[10].GetString(); - creatureTemplate.FemaleName = fields[11].GetString(); - creatureTemplate.SubName = fields[12].GetString(); - creatureTemplate.IconName = fields[13].GetString(); - creatureTemplate.GossipMenuId = fields[14].GetUInt32(); - creatureTemplate.minlevel = fields[15].GetUInt8(); - creatureTemplate.maxlevel = fields[16].GetUInt8(); - creatureTemplate.expansion = uint32(fields[17].GetInt16()); - creatureTemplate.expansionUnknown = uint32(fields[18].GetUInt16()); - creatureTemplate.faction = uint32(fields[19].GetUInt16()); - creatureTemplate.npcflag = fields[20].GetUInt32(); - creatureTemplate.speed_walk = fields[21].GetFloat(); - creatureTemplate.speed_run = fields[22].GetFloat(); - creatureTemplate.scale = fields[23].GetFloat(); - creatureTemplate.rank = uint32(fields[24].GetUInt8()); - creatureTemplate.mindmg = fields[25].GetFloat(); - creatureTemplate.maxdmg = fields[26].GetFloat(); - creatureTemplate.dmgschool = uint32(fields[27].GetInt8()); - creatureTemplate.attackpower = fields[28].GetUInt32(); - creatureTemplate.dmg_multiplier = fields[29].GetFloat(); - creatureTemplate.baseattacktime = fields[30].GetUInt32(); - creatureTemplate.rangeattacktime = fields[31].GetUInt32(); - creatureTemplate.unit_class = uint32(fields[32].GetUInt8()); - creatureTemplate.unit_flags = fields[33].GetUInt32(); - creatureTemplate.unit_flags2 = fields[34].GetUInt32(); - creatureTemplate.dynamicflags = fields[35].GetUInt32(); - creatureTemplate.family = uint32(fields[36].GetUInt8()); - creatureTemplate.trainer_type = uint32(fields[37].GetUInt8()); - creatureTemplate.trainer_class = uint32(fields[38].GetUInt8()); - creatureTemplate.trainer_race = uint32(fields[39].GetUInt8()); - creatureTemplate.minrangedmg = fields[40].GetFloat(); - creatureTemplate.maxrangedmg = fields[41].GetFloat(); - creatureTemplate.rangedattackpower = uint32(fields[42].GetUInt16()); - creatureTemplate.type = uint32(fields[43].GetUInt8()); - creatureTemplate.type_flags = fields[44].GetUInt32(); - creatureTemplate.type_flags2 = fields[45].GetUInt32(); - creatureTemplate.lootid = fields[46].GetUInt32(); - creatureTemplate.pickpocketLootId = fields[47].GetUInt32(); - creatureTemplate.SkinLootId = fields[48].GetUInt32(); - - for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - creatureTemplate.resistance[i] = fields[49 + i - 1].GetInt16(); - - for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) - creatureTemplate.spells[i] = fields[55 + i].GetUInt32(); - - creatureTemplate.PetSpellDataId = fields[63].GetUInt32(); - creatureTemplate.VehicleId = fields[64].GetUInt32(); - creatureTemplate.mingold = fields[65].GetUInt32(); - creatureTemplate.maxgold = fields[66].GetUInt32(); - creatureTemplate.AIName = fields[67].GetString(); - creatureTemplate.MovementType = uint32(fields[68].GetUInt8()); - creatureTemplate.InhabitType = uint32(fields[69].GetUInt8()); - creatureTemplate.HoverHeight = fields[70].GetFloat(); - creatureTemplate.ModHealth = fields[71].GetFloat(); - creatureTemplate.ModMana = fields[72].GetFloat(); - creatureTemplate.ModManaExtra = fields[73].GetFloat(); - creatureTemplate.ModArmor = fields[74].GetFloat(); - creatureTemplate.RacialLeader = fields[75].GetBool(); - - for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - creatureTemplate.questItems[i] = fields[76 + i].GetUInt32(); - - creatureTemplate.movementId = fields[82].GetUInt32(); - creatureTemplate.RegenHealth = fields[83].GetBool(); - creatureTemplate.MechanicImmuneMask = fields[84].GetUInt32(); - creatureTemplate.flags_extra = fields[85].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[86].GetCString()); - + LoadCreatureTemplate(fields); ++count; } while (result->NextRow()); @@ -554,6 +470,91 @@ void ObjectMgr::LoadCreatureTemplates() TC_LOG_INFO("server.loading", ">> Loaded %u creature definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +void ObjectMgr::LoadCreatureTemplate(Field* fields) +{ + uint32 entry = fields[0].GetUInt32(); + + CreatureTemplate& creatureTemplate = _creatureTemplateStore[entry]; + + creatureTemplate.Entry = entry; + + for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i) + creatureTemplate.DifficultyEntry[i] = fields[1 + i].GetUInt32(); + + for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i) + creatureTemplate.KillCredit[i] = fields[4 + i].GetUInt32(); + + creatureTemplate.Modelid1 = fields[6].GetUInt32(); + creatureTemplate.Modelid2 = fields[7].GetUInt32(); + creatureTemplate.Modelid3 = fields[8].GetUInt32(); + creatureTemplate.Modelid4 = fields[9].GetUInt32(); + creatureTemplate.Name = fields[10].GetString(); + creatureTemplate.FemaleName = fields[11].GetString(); + creatureTemplate.SubName = fields[12].GetString(); + creatureTemplate.IconName = fields[13].GetString(); + creatureTemplate.GossipMenuId = fields[14].GetUInt32(); + creatureTemplate.minlevel = fields[15].GetUInt8(); + creatureTemplate.maxlevel = fields[16].GetUInt8(); + creatureTemplate.expansion = uint32(fields[17].GetInt16()); + creatureTemplate.expansionUnknown = uint32(fields[18].GetUInt16()); + creatureTemplate.faction = uint32(fields[19].GetUInt16()); + creatureTemplate.npcflag = fields[20].GetUInt32(); + creatureTemplate.speed_walk = fields[21].GetFloat(); + creatureTemplate.speed_run = fields[22].GetFloat(); + creatureTemplate.scale = fields[23].GetFloat(); + creatureTemplate.rank = uint32(fields[24].GetUInt8()); + creatureTemplate.dmgschool = uint32(fields[25].GetInt8()); + creatureTemplate.BaseAttackTime = fields[26].GetUInt32(); + creatureTemplate.RangeAttackTime = fields[27].GetUInt32(); + creatureTemplate.BaseVariance = fields[28].GetFloat(); + creatureTemplate.RangeVariance = fields[29].GetFloat(); + creatureTemplate.unit_class = uint32(fields[30].GetUInt8()); + creatureTemplate.unit_flags = fields[31].GetUInt32(); + creatureTemplate.unit_flags2 = fields[32].GetUInt32(); + creatureTemplate.dynamicflags = fields[33].GetUInt32(); + creatureTemplate.family = uint32(fields[34].GetUInt8()); + creatureTemplate.trainer_type = uint32(fields[35].GetUInt8()); + creatureTemplate.trainer_class = uint32(fields[36].GetUInt8()); + creatureTemplate.trainer_race = uint32(fields[37].GetUInt8()); + creatureTemplate.type = uint32(fields[38].GetUInt8()); + creatureTemplate.type_flags = fields[39].GetUInt32(); + creatureTemplate.type_flags2 = fields[40].GetUInt32(); + creatureTemplate.lootid = fields[41].GetUInt32(); + creatureTemplate.pickpocketLootId = fields[42].GetUInt32(); + creatureTemplate.SkinLootId = fields[43].GetUInt32(); + + for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) + creatureTemplate.resistance[i] = fields[44 + i - 1].GetInt16(); + + for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) + creatureTemplate.spells[i] = fields[50 + i].GetUInt32(); + + creatureTemplate.PetSpellDataId = fields[58].GetUInt32(); + creatureTemplate.VehicleId = fields[59].GetUInt32(); + creatureTemplate.mingold = fields[60].GetUInt32(); + creatureTemplate.maxgold = fields[61].GetUInt32(); + creatureTemplate.AIName = fields[62].GetString(); + creatureTemplate.MovementType = uint32(fields[63].GetUInt8()); + creatureTemplate.InhabitType = uint32(fields[64].GetUInt8()); + creatureTemplate.HoverHeight = fields[65].GetFloat(); + creatureTemplate.ModHealth = fields[66].GetFloat(); + creatureTemplate.ModMana = fields[67].GetFloat(); + creatureTemplate.ModManaExtra = fields[68].GetFloat(); + creatureTemplate.ModArmor = fields[69].GetFloat(); + creatureTemplate.ModDamage = fields[70].GetFloat(); + creatureTemplate.ModExperience = fields[71].GetFloat(); + creatureTemplate.RacialLeader = fields[72].GetBool(); + + for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) + creatureTemplate.questItems[i] = fields[73 + i].GetUInt32(); + + creatureTemplate.movementId = fields[79].GetUInt32(); + creatureTemplate.RegenHealth = fields[80].GetBool(); + creatureTemplate.MechanicImmuneMask = fields[81].GetUInt32(); + creatureTemplate.flags_extra = fields[82].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[83].GetCString()); +} + void ObjectMgr::LoadCreatureTemplateAddons() { uint32 oldMSTime = getMSTime(); @@ -887,11 +888,11 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) const_cast<CreatureTemplate*>(cInfo)->dmgschool = SPELL_SCHOOL_NORMAL; } - if (cInfo->baseattacktime == 0) - const_cast<CreatureTemplate*>(cInfo)->baseattacktime = BASE_ATTACK_TIME; + if (cInfo->BaseAttackTime == 0) + const_cast<CreatureTemplate*>(cInfo)->BaseAttackTime = BASE_ATTACK_TIME; - if (cInfo->rangeattacktime == 0) - const_cast<CreatureTemplate*>(cInfo)->rangeattacktime = BASE_ATTACK_TIME; + if (cInfo->RangeAttackTime == 0) + const_cast<CreatureTemplate*>(cInfo)->RangeAttackTime = BASE_ATTACK_TIME; if ((cInfo->npcflag & UNIT_NPC_FLAG_TRAINER) && cInfo->trainer_type >= MAX_TRAINER_TYPE) TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong trainer type %u.", cInfo->Entry, cInfo->trainer_type); @@ -992,7 +993,7 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) const_cast<CreatureTemplate*>(cInfo)->flags_extra &= CREATURE_FLAG_EXTRA_DB_ALLOWED; } - const_cast<CreatureTemplate*>(cInfo)->dmg_multiplier *= Creature::_GetDamageMod(cInfo->rank); + const_cast<CreatureTemplate*>(cInfo)->ModDamage *= Creature::_GetDamageMod(cInfo->rank); } void ObjectMgr::LoadCreatureAddons() @@ -2252,7 +2253,7 @@ void ObjectMgr::LoadItemLocales() ItemLocale& data = _itemLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; AddLocaleString(fields[1 + 2 * (i - 1)].GetString(), locale, data.Name); @@ -2260,7 +2261,7 @@ void ObjectMgr::LoadItemLocales() } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu Item locale strings in %u ms", (unsigned long)_itemLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u Item locale strings in %u ms", uint32(_itemLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void FillItemDamageFields(float* minDamage, float* maxDamage, float* dps, uint32 itemLevel, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32 delay, float statScalingFactor, uint32 inventoryType, uint32 flags2) @@ -4569,7 +4570,7 @@ void ObjectMgr::LoadQuestLocales() QuestLocale& data = _questLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; @@ -4591,7 +4592,7 @@ void ObjectMgr::LoadQuestLocales() } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu Quest locale strings in %u ms", (unsigned long)_questLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u Quest locale strings in %u ms", uint32(_questLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadScripts(ScriptsType type) @@ -5202,11 +5203,11 @@ void ObjectMgr::LoadPageTextLocales() PageTextLocale& data = _pageTextLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.Text); } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu PageText locale strings in %u ms", (unsigned long)_pageTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u PageText locale strings in %u ms", uint32(_pageTextLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } void ObjectMgr::LoadInstanceTemplate() @@ -5465,10 +5466,10 @@ void ObjectMgr::LoadNpcTextLocales() NpcTextLocale& data = _npcTextLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = (LocaleConstant) i; - for (uint8 j = 0; j < MAX_LOCALES; ++j) + for (uint8 j = 0; j < MAX_GOSSIP_TEXT_OPTIONS; ++j) { AddLocaleString(fields[1 + 8 * 2 * (i - 1) + 2 * j].GetString(), locale, data.Text_0[j]); AddLocaleString(fields[1 + 8 * 2 * (i - 1) + 2 * j + 1].GetString(), locale, data.Text_1[j]); @@ -5476,7 +5477,7 @@ void ObjectMgr::LoadNpcTextLocales() } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu NpcText locale strings in %u ms", (unsigned long)_npcTextLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u NpcText locale strings in %u ms", uint32(_npcTextLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } //not very fast function but it is called only once a day, or on starting-up @@ -6507,14 +6508,14 @@ void ObjectMgr::LoadGameObjectLocales() GameObjectLocale& data = _gameObjectLocaleStore[entry]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) + { AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.Name); - - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) AddLocaleString(fields[i + (TOTAL_LOCALES - 1)].GetString(), LocaleConstant(i), data.CastBarCaption); + } } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %lu gameobject locale strings in %u ms", (unsigned long)_gameObjectLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u gameobject locale strings in %u ms", uint32(_gameObjectLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime)); } inline void CheckGOLockId(GameObjectTemplate const* goInfo, uint32 dataN, uint32 N) @@ -7850,7 +7851,7 @@ bool ObjectMgr::LoadTrinityStrings(const char* table, int32 min_value, int32 max data.Content.resize(1); ++count; - for (uint8 i = 0; i < TOTAL_LOCALES; ++i) + for (int8 i = TOTAL_LOCALES - 1; i >= 0; --i) AddLocaleString(fields[i + 1].GetString(), LocaleConstant(i), data.Content); } while (result->NextRow()); @@ -8887,11 +8888,11 @@ void ObjectMgr::LoadBroadcastTextLocales() continue; } - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = LocaleConstant(i); - ObjectMgr::AddLocaleString(fields[1 + (i - 1)].GetString(), locale, bct->second.MaleText); - ObjectMgr::AddLocaleString(fields[9 + (i - 1)].GetString(), locale, bct->second.FemaleText); + AddLocaleString(fields[1 + (i - 1)].GetString(), locale, bct->second.MaleText); + AddLocaleString(fields[9 + (i - 1)].GetString(), locale, bct->second.FemaleText); } ++count; diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 45671f016c8..f9f5269e485 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -984,6 +984,7 @@ class ObjectMgr void LoadGraveyardOrientations(); void LoadCreatureTemplates(); void LoadCreatureTemplateAddons(); + void LoadCreatureTemplate(Field* fields); void CheckCreatureTemplate(CreatureTemplate const* cInfo); void LoadTempSummons(); void LoadCreatures(); diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h index 9ed8549e9a1..04973237365 100644 --- a/src/server/game/Grids/GridDefines.h +++ b/src/server/game/Grids/GridDefines.h @@ -201,8 +201,8 @@ namespace Trinity int x_val = int(x_offset + CENTER_GRID_CELL_ID + 0.5f); int y_val = int(y_offset + CENTER_GRID_CELL_ID + 0.5f); - x_off = (float(x_offset) - x_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL; - y_off = (float(y_offset) - y_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL; + x_off = (float(x_offset) - float(x_val) + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL; + y_off = (float(y_offset) - float(y_val) + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL; return CellCoord(x_val, y_val); } diff --git a/src/server/game/Grids/GridStates.h b/src/server/game/Grids/GridStates.h index af11ab08d5e..330b74ec65e 100644 --- a/src/server/game/Grids/GridStates.h +++ b/src/server/game/Grids/GridStates.h @@ -34,24 +34,24 @@ class GridState class InvalidState : public GridState { public: - void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const; + void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; }; class ActiveState : public GridState { public: - void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const; + void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; }; class IdleState : public GridState { public: - void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const; + void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; }; class RemovalState : public GridState { public: - void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const; + void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const override; }; #endif diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 2929c05cace..2a7295b641e 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -133,7 +133,7 @@ class Roll : public LootValidatorRef ~Roll(); void setLoot(Loot* pLoot); Loot* getLoot(); - void targetObjectBuildLink(); + void targetObjectBuildLink() override; uint64 itemGUID; uint32 itemid; diff --git a/src/server/game/Groups/GroupReference.h b/src/server/game/Groups/GroupReference.h index df5683b3edf..dc8480e9463 100644 --- a/src/server/game/Groups/GroupReference.h +++ b/src/server/game/Groups/GroupReference.h @@ -28,9 +28,9 @@ class GroupReference : public Reference<Group, Player> { protected: uint8 iSubGroup; - void targetObjectBuildLink(); - void targetObjectDestroyLink(); - void sourceObjectDestroyLink(); + void targetObjectBuildLink() override; + void targetObjectDestroyLink() override; + void sourceObjectDestroyLink() override; public: GroupReference() : Reference<Group, Player>(), iSubGroup(0) { } ~GroupReference() { unlink(); } diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index d62907ddde5..da5f16d38c5 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -458,8 +458,8 @@ private: ~EventLogEntry() { } - void SaveToDB(SQLTransaction& trans) const; - void WritePacket(WorldPacket& data, ByteBuffer& content) const; + void SaveToDB(SQLTransaction& trans) const override; + void WritePacket(WorldPacket& data, ByteBuffer& content) const override; private: GuildEventLogTypes m_eventType; @@ -496,8 +496,8 @@ private: ~BankEventLogEntry() { } - void SaveToDB(SQLTransaction& trans) const; - void WritePacket(WorldPacket& data, ByteBuffer& content) const; + void SaveToDB(SQLTransaction& trans) const override; + void WritePacket(WorldPacket& data, ByteBuffer& content) const override; private: GuildBankEventLogTypes m_eventType; @@ -711,13 +711,13 @@ private: PlayerMoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) : MoveItemData(guild, player, container, slotId) { } - bool IsBank() const { return false; } - bool InitItem(); - void RemoveItem(SQLTransaction& trans, MoveItemData* pOther, uint32 splitedAmount = 0); - Item* StoreItem(SQLTransaction& trans, Item* pItem); - void LogBankEvent(SQLTransaction& trans, MoveItemData* pFrom, uint32 count) const; + bool IsBank() const override { return false; } + bool InitItem() override; + void RemoveItem(SQLTransaction& trans, MoveItemData* pOther, uint32 splitedAmount = 0) override; + Item* StoreItem(SQLTransaction& trans, Item* pItem) override; + void LogBankEvent(SQLTransaction& trans, MoveItemData* pFrom, uint32 count) const override; protected: - InventoryResult CanStore(Item* pItem, bool swap); + InventoryResult CanStore(Item* pItem, bool swap) override; }; class BankMoveItemData : public MoveItemData @@ -726,17 +726,17 @@ private: BankMoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) : MoveItemData(guild, player, container, slotId) { } - bool IsBank() const { return true; } - bool InitItem(); - bool HasStoreRights(MoveItemData* pOther) const; - bool HasWithdrawRights(MoveItemData* pOther) const; - void RemoveItem(SQLTransaction& trans, MoveItemData* pOther, uint32 splitedAmount); - Item* StoreItem(SQLTransaction& trans, Item* pItem); - void LogBankEvent(SQLTransaction& trans, MoveItemData* pFrom, uint32 count) const; - void LogAction(MoveItemData* pFrom) const; + bool IsBank() const override { return true; } + bool InitItem() override; + bool HasStoreRights(MoveItemData* pOther) const override; + bool HasWithdrawRights(MoveItemData* pOther) const override; + void RemoveItem(SQLTransaction& trans, MoveItemData* pOther, uint32 splitedAmount) override; + Item* StoreItem(SQLTransaction& trans, Item* pItem) override; + void LogBankEvent(SQLTransaction& trans, MoveItemData* pFrom, uint32 count) const override; + void LogAction(MoveItemData* pFrom) const override; protected: - InventoryResult CanStore(Item* pItem, bool swap); + InventoryResult CanStore(Item* pItem, bool swap) override; private: Item* _StoreItem(SQLTransaction& trans, BankTab* pTab, Item* pItem, ItemPosCount& pos, bool clone) const; diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp index b2db2fff6c2..2fa73643499 100644 --- a/src/server/game/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Handlers/ArenaTeamHandler.cpp @@ -365,6 +365,10 @@ void WorldSession::HandleArenaTeamRemoveOpcode(WorldPacket& recvData) SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S); return; } + + // Player cannot be removed during fights + if (arenaTeam->IsFighting()) + return; arenaTeam->DelMember(member->Guid, true); diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 7c3d9e99eee..692f5b80953 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -83,10 +83,9 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recvData) Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid); bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING); - if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE)) { - player->SendLootRelease(lguid); + player->SendLootError(lguid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL); return; } @@ -156,6 +155,8 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) if (creature->IsAlive()) shareMoney = false; } + else + player->SendLootError(guid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL); break; } default: @@ -403,21 +404,28 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData) if (!_player->GetGroup() || _player->GetGroup()->GetMasterLooterGuid() != _player->GetGUID() || _player->GetGroup()->GetLootMethod() != MASTER_LOOT) { - _player->SendLootRelease(GetPlayer()->GetLootGUID()); + _player->SendLootError(lootguid, LOOT_ERROR_DIDNT_KILL); return; } Player* target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(target_playerguid, 0, HIGHGUID_PLAYER)); if (!target) + { + _player->SendLootError(lootguid, LOOT_ERROR_PLAYER_NOT_FOUND); return; + } TC_LOG_DEBUG("network", "WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = [%s].", target->GetName().c_str()); if (_player->GetLootGUID() != lootguid) + { + _player->SendLootError(lootguid, LOOT_ERROR_DIDNT_KILL); return; + } if (!_player->IsInRaidWith(target) || !_player->IsInMap(target)) { + _player->SendLootError(lootguid, LOOT_ERROR_MASTER_OTHER); TC_LOG_INFO("loot", "MasterLootItem: Player %s tried to give an item to ineligible player %s !", GetPlayer()->GetName().c_str(), target->GetName().c_str()); return; } @@ -459,16 +467,21 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData) msg = EQUIP_ERR_CANT_EQUIP_EVER; if (msg != EQUIP_ERR_OK) { + if (msg == EQUIP_ERR_ITEM_MAX_COUNT) + _player->SendLootError(lootguid, LOOT_ERROR_MASTER_UNIQUE_ITEM); + else if (msg == EQUIP_ERR_INV_FULL) + _player->SendLootError(lootguid, LOOT_ERROR_MASTER_INV_FULL); + else + _player->SendLootError(lootguid, LOOT_ERROR_MASTER_OTHER); + target->SendEquipError(msg, NULL, NULL, item.itemid); - // send duplicate of error massage to master looter - _player->SendEquipError(msg, NULL, NULL, item.itemid); return; } // list of players allowed to receive this item in trade AllowedLooterSet looters = item.GetAllowedLooters(); - // not move item from loot to target inventory + // now move item from loot to target inventory Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters); target->SendNewItem(newitem, uint32(item.count), false, false, true); target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); @@ -476,8 +489,8 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData) target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count); // mark as looted - item.count=0; - item.is_looted=true; + item.count = 0; + item.is_looted = true; loot->NotifyItemRemoved(slotid); --loot->unlootedCount; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index c9891de3c16..1162622af60 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -879,9 +879,9 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData) float dz = player->GetPositionZ() - atEntry->z; float dx = rotPlayerX - atEntry->x; float dy = rotPlayerY - atEntry->y; - if ((fabs(dx) > atEntry->box_x / 2 + delta) || - (fabs(dy) > atEntry->box_y / 2 + delta) || - (fabs(dz) > atEntry->box_z / 2 + delta)) + if ((std::fabs(dx) > atEntry->box_x / 2 + delta) || + (std::fabs(dy) > atEntry->box_y / 2 + delta) || + (std::fabs(dz) > atEntry->box_z / 2 + delta)) { TC_LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) too far (1/2 box X: %f 1/2 box Y: %f 1/2 box Z: %f rotatedPlayerX: %f rotatedPlayerY: %f dZ:%f), ignore Area Trigger ID: %u", player->GetName().c_str(), player->GetGUIDLow(), atEntry->box_x/2, atEntry->box_y/2, atEntry->box_z/2, rotPlayerX, rotPlayerY, dz, triggerId); diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index dabe40e427e..b59f9aca943 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -479,7 +479,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recvData) return; } - if (!_player->GetTransport() && fabs(_player->GetSpeed(move_type) - newspeed) > 0.01f) + if (!_player->GetTransport() && std::fabs(_player->GetSpeed(move_type) - newspeed) > 0.01f) { if (_player->GetSpeed(move_type) > newspeed) // must be greater - just correct { diff --git a/src/server/game/Handlers/NPCHandler.h b/src/server/game/Handlers/NPCHandler.h index 7210d9a53b5..855536c7d9e 100644 --- a/src/server/game/Handlers/NPCHandler.h +++ b/src/server/game/Handlers/NPCHandler.h @@ -51,10 +51,10 @@ struct PageTextLocale struct NpcTextLocale { - NpcTextLocale() { Text_0.resize(8); Text_1.resize(8); } + NpcTextLocale() { } - std::vector<StringVector> Text_0; - std::vector<StringVector> Text_1; + StringVector Text_0[MAX_GOSSIP_TEXT_OPTIONS]; + StringVector Text_1[MAX_GOSSIP_TEXT_OPTIONS]; }; #endif diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 04e64634d88..b0e0d60803b 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -578,7 +578,7 @@ void WorldSession::HandleSelfResOpcode(WorldPacket& /*recvData*/) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)); if (spellInfo) - _player->CastSpell(_player, spellInfo, false, 0); + _player->CastSpell(_player, spellInfo, false, nullptr); _player->SetUInt32Value(PLAYER_SELF_RES_SPELL, 0); } diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index f6c403acb66..f4aca0528a0 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -30,43 +30,50 @@ #include "Language.h" #include "AccountMgr.h" -void WorldSession::SendTradeStatus(TradeStatus status, int8 clearSlot) +void WorldSession::SendTradeStatus(TradeStatusInfo const& info) { - WorldPacket data; - Player* trader = GetPlayer()->GetTrader(); - data.Initialize(SMSG_TRADE_STATUS, 1+4+4); + WorldPacket data(SMSG_TRADE_STATUS, 13); data.WriteBit(trader ? (trader->GetSession()->GetBattlenetAccountId() == GetBattlenetAccountId()) : 0); // IsSameBnetAccount, used for trading heirlooms and other battle.net bound items with your other accounts - data.WriteBits(status, 5); + data.WriteBits(info.Status, 5); - switch (status) + switch (info.Status) { case TRADE_STATUS_BEGIN_TRADE: - data.WriteBits(0, 8); // Trader Guid - data.FlushBits(); + data.WriteBit(info.TraderGuid[2]); + data.WriteBit(info.TraderGuid[4]); + data.WriteBit(info.TraderGuid[6]); + data.WriteBit(info.TraderGuid[0]); + data.WriteBit(info.TraderGuid[1]); + data.WriteBit(info.TraderGuid[3]); + data.WriteBit(info.TraderGuid[7]); + data.WriteBit(info.TraderGuid[5]); + + data.WriteByteSeq(info.TraderGuid[4]); + data.WriteByteSeq(info.TraderGuid[1]); + data.WriteByteSeq(info.TraderGuid[2]); + data.WriteByteSeq(info.TraderGuid[3]); + data.WriteByteSeq(info.TraderGuid[0]); + data.WriteByteSeq(info.TraderGuid[7]); + data.WriteByteSeq(info.TraderGuid[6]); + data.WriteByteSeq(info.TraderGuid[5]); break; case TRADE_STATUS_OPEN_WINDOW: - data.FlushBits(); - data << uint32(0); // Trade Id + data << uint32(0); // CGTradeInfo::m_tradeID break; case TRADE_STATUS_CLOSE_WINDOW: - data.WriteBit(0); // Error bool (0 = Target, 1 = Self) - data.FlushBits(); - data << uint32(0); // Error Item (Relevant item to the error) - data << uint32(0); // InventoryResult + data.WriteBit(info.IsTargetResult); // bool isTargetError; used for: EQUIP_ERR_BAG_FULL, EQUIP_ERR_CANT_CARRY_MORE_OF_THIS, EQUIP_ERR_MISSING_REAGENT, EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED + data << uint32(info.Result); // InventoryResult + data << uint32(info.ItemLimitCategoryId); // ItemLimitCategory.dbc entry break; - case TRADE_STATUS_ONLY_CONJURED: // Not Implemented - case TRADE_STATUS_NOT_ELIGIBLE: - // Used when trading loot soulbound items with people that are not eligible (TRADE_STATUS_NOT_ELIGIBLE), - // and when trying to trade items with players in other realms when in a cross realm BG, you can only trade conjured goods with them (TRADE_STATUS_ONLY_CONJURED) - data.FlushBits(); - data << int8(clearSlot); // Trade slot to clear, -1 = Clear the money amount + case TRADE_STATUS_WRONG_REALM: + case TRADE_STATUS_NOT_ON_TAPLIST: + data << uint8(info.Slot); // Trade slot; -1 here clears CGTradeInfo::m_tradeMoney break; case TRADE_STATUS_CURRENCY: // Not implemented case TRADE_STATUS_CURRENCY_NOT_TRADABLE: // Not implemented // Blizzard never implemented these, you can only trade currency with the field9 & 1 in CurrencyTypes.DBC, and only two test currencies have that flag - data.FlushBits(); data << uint32(0); // Trading Currency Id data << uint32(0); // Trading Currency Amount default: @@ -99,7 +106,7 @@ void WorldSession::SendUpdateTrade(bool trader_data /*= true*/) ++count; WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 4*6 + 8 + 1 + 3 + count * 70); - data << uint32(0); // this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?) + data << uint32(0); // CGTradeInfo::m_tradeID data << uint32(0); // unk 2 data << uint64(view_trade->GetMoney()); // trader gold data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item @@ -337,14 +344,15 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) Item* myItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL }; Item* hisItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL }; - bool myCanCompleteTrade = true, hisCanCompleteTrade = true; // set before checks for propertly undo at problems (it already set in to client) my_trade->SetAccepted(true); + TradeStatusInfo info; if (!_player->IsWithinDistInMap(trader, TRADE_DISTANCE, false)) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); my_trade->SetAccepted(false); return; } @@ -352,7 +360,9 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) // not accept case incorrect money amount if (!_player->HasEnoughMoney(my_trade->GetMoney())) { - SendNotification(LANG_NOT_ENOUGH_GOLD); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; + SendTradeStatus(info); my_trade->SetAccepted(false, true); return; } @@ -360,21 +370,27 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) // not accept case incorrect money amount if (!trader->HasEnoughMoney(his_trade->GetMoney())) { - trader->GetSession()->SendNotification(LANG_NOT_ENOUGH_GOLD); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY; + trader->GetSession()->SendTradeStatus(info); his_trade->SetAccepted(false, true); return; } if (_player->GetMoney() >= uint64(MAX_MONEY_AMOUNT) - his_trade->GetMoney()) { - _player->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_TOO_MUCH_GOLD; + SendTradeStatus(info); my_trade->SetAccepted(false, true); return; } if (trader->GetMoney() >= uint64(MAX_MONEY_AMOUNT) - my_trade->GetMoney()) { - trader->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_TOO_MUCH_GOLD; + trader->GetSession()->SendTradeStatus(info); his_trade->SetAccepted(false, true); return; } @@ -386,14 +402,16 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) { if (!item->CanBeTraded(false, true)) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } if (item->IsBindedNotWith(trader)) { - SendTradeStatus(TRADE_STATUS_NOT_ELIGIBLE); - SendTradeStatus(TRADE_STATUS_CLOSE_WINDOW/*TRADE_STATUS_TRADE_CANCELED*/); + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_TRADE_BOUND_ITEM; + SendTradeStatus(info); return; } } @@ -402,7 +420,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) { if (!item->CanBeTraded(false, true)) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } //if (item->IsBindedNotWith(_player)) // dont mark as invalid when his item isnt good (not exploitable because if item is invalid trade will fail anyway later on the same check) @@ -497,31 +516,37 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) } // inform partner client - trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + info.Status = TRADE_STATUS_TRADE_ACCEPT; + trader->GetSession()->SendTradeStatus(info); // test if item will fit in each inventory - hisCanCompleteTrade = (trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK); - myCanCompleteTrade = (_player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK); + TradeStatusInfo myCanCompleteInfo, hisCanCompleteInfo; + hisCanCompleteInfo.Result = trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT, &hisCanCompleteInfo.ItemLimitCategoryId); + myCanCompleteInfo.Result = _player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT, &myCanCompleteInfo.ItemLimitCategoryId); clearAcceptTradeMode(myItems, hisItems); // in case of missing space report error - if (!myCanCompleteTrade) + if (myCanCompleteInfo.Result != EQUIP_ERR_OK) { clearAcceptTradeMode(my_trade, his_trade); - SendNotification(LANG_NOT_FREE_TRADE_SLOTS); - trader->GetSession()->SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); + myCanCompleteInfo.Status = TRADE_STATUS_CLOSE_WINDOW; + trader->GetSession()->SendTradeStatus(myCanCompleteInfo); + myCanCompleteInfo.IsTargetResult = true; + SendTradeStatus(myCanCompleteInfo); my_trade->SetAccepted(false); his_trade->SetAccepted(false); return; } - else if (!hisCanCompleteTrade) + else if (hisCanCompleteInfo.Result != EQUIP_ERR_OK) { clearAcceptTradeMode(my_trade, his_trade); - SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); - trader->GetSession()->SendNotification(LANG_NOT_FREE_TRADE_SLOTS); + hisCanCompleteInfo.Status = TRADE_STATUS_CLOSE_WINDOW; + SendTradeStatus(hisCanCompleteInfo); + hisCanCompleteInfo.IsTargetResult = true; + trader->GetSession()->SendTradeStatus(hisCanCompleteInfo); my_trade->SetAccepted(false); his_trade->SetAccepted(false); return; @@ -590,12 +615,14 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) trader->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); - trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); - SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); + info.Status = TRADE_STATUS_TRADE_COMPLETE; + trader->GetSession()->SendTradeStatus(info); + SendTradeStatus(info); } else { - trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + info.Status = TRADE_STATUS_TRADE_ACCEPT; + trader->GetSession()->SendTradeStatus(info); } } @@ -614,8 +641,10 @@ void WorldSession::HandleBeginTradeOpcode(WorldPacket& /*recvPacket*/) if (!my_trade) return; - my_trade->GetTrader()->GetSession()->SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); - SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); + TradeStatusInfo info; + info.Status = TRADE_STATUS_OPEN_WINDOW; + my_trade->GetTrader()->GetSession()->SendTradeStatus(info); + SendTradeStatus(info); } void WorldSession::SendCancelTrade() @@ -623,7 +652,9 @@ void WorldSession::SendCancelTrade() if (PlayerRecentlyLoggedOut() || PlayerLogout()) return; - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + TradeStatusInfo info; + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); } void WorldSession::HandleCancelTradeOpcode(WorldPacket& /*recvPacket*/) @@ -658,27 +689,32 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) if (GetPlayer()->m_trade) return; + TradeStatusInfo info; if (!GetPlayer()->IsAlive()) { - SendTradeStatus(TRADE_STATUS_YOU_DEAD); + info.Status = TRADE_STATUS_YOU_DEAD; + SendTradeStatus(info); return; } if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED)) { - SendTradeStatus(TRADE_STATUS_YOU_STUNNED); + info.Status = TRADE_STATUS_YOU_STUNNED; + SendTradeStatus(info); return; } if (isLogingOut()) { - SendTradeStatus(TRADE_STATUS_YOU_LOGOUT); + info.Status = TRADE_STATUS_YOU_LOGOUT; + SendTradeStatus(info); return; } if (GetPlayer()->IsInFlight()) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); return; } @@ -692,55 +728,64 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) if (!pOther) { - SendTradeStatus(TRADE_STATUS_NO_TARGET); + info.Status = TRADE_STATUS_NO_TARGET; + SendTradeStatus(info); return; } if (pOther == GetPlayer() || pOther->m_trade) { - SendTradeStatus(TRADE_STATUS_BUSY); + info.Status = TRADE_STATUS_BUSY; + SendTradeStatus(info); return; } if (!pOther->IsAlive()) { - SendTradeStatus(TRADE_STATUS_TARGET_DEAD); + info.Status = TRADE_STATUS_TARGET_DEAD; + SendTradeStatus(info); return; } if (pOther->IsInFlight()) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); return; } if (pOther->HasUnitState(UNIT_STATE_STUNNED)) { - SendTradeStatus(TRADE_STATUS_TARGET_STUNNED); + info.Status = TRADE_STATUS_TARGET_STUNNED; + SendTradeStatus(info); return; } if (pOther->GetSession()->isLogingOut()) { - SendTradeStatus(TRADE_STATUS_TARGET_LOGOUT); + info.Status = TRADE_STATUS_TARGET_LOGOUT; + SendTradeStatus(info); return; } if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { - SendTradeStatus(TRADE_STATUS_IGNORE_YOU); + info.Status = TRADE_STATUS_IGNORE_YOU; + SendTradeStatus(info); return; } if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeam() !=_player->GetTeam()) { - SendTradeStatus(TRADE_STATUS_WRONG_FACTION); + info.Status = TRADE_STATUS_WRONG_FACTION; + SendTradeStatus(info); return; } if (!pOther->IsWithinDistInMap(_player, TRADE_DISTANCE, false)) { - SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); + info.Status = TRADE_STATUS_TARGET_TO_FAR; + SendTradeStatus(info); return; } @@ -754,31 +799,9 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) _player->m_trade = new TradeData(_player, pOther); pOther->m_trade = new TradeData(pOther, _player); - WorldPacket data(SMSG_TRADE_STATUS, 2+7); - data.WriteBit(0); // unk bit, usually 0 - data.WriteBits(TRADE_STATUS_BEGIN_TRADE, 5); - - ObjectGuid playerGuid = _player->GetGUID(); - // WTB StartBitStream... - data.WriteBit(playerGuid[2]); - data.WriteBit(playerGuid[4]); - data.WriteBit(playerGuid[6]); - data.WriteBit(playerGuid[0]); - data.WriteBit(playerGuid[1]); - data.WriteBit(playerGuid[3]); - data.WriteBit(playerGuid[7]); - data.WriteBit(playerGuid[5]); - - data.WriteByteSeq(playerGuid[4]); - data.WriteByteSeq(playerGuid[1]); - data.WriteByteSeq(playerGuid[2]); - data.WriteByteSeq(playerGuid[3]); - data.WriteByteSeq(playerGuid[0]); - data.WriteByteSeq(playerGuid[7]); - data.WriteByteSeq(playerGuid[6]); - data.WriteByteSeq(playerGuid[5]); - - pOther->GetSession()->SendPacket(&data); + info.Status = TRADE_STATUS_BEGIN_TRADE; + info.TraderGuid = _player->GetGUID(); + pOther->GetSession()->SendTradeStatus(info); } void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket) @@ -808,10 +831,12 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) if (!my_trade) return; + TradeStatusInfo info; // invalid slot number if (tradeSlot >= TRADE_SLOT_COUNT) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } @@ -819,7 +844,8 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) Item* item = _player->GetItemByPos(bag, slot); if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded(false, true))) { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } @@ -829,14 +855,16 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) if (my_trade->HasItem(iGUID)) { // cheating attempt - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + info.Status = TRADE_STATUS_TRADE_CANCELED; + SendTradeStatus(info); return; } - if (item->IsBindedNotWith(GetPlayer()->GetTrader())) + if (slot != TRADE_SLOT_NONTRADED && item->IsBindedNotWith(my_trade->GetTrader())) { - // The item is BOP tradeable but the trader wasn't eligible to get it. - SendTradeStatus(TRADE_STATUS_NOT_ELIGIBLE, tradeSlot); + info.Status = TRADE_STATUS_NOT_ON_TAPLIST; + info.Slot = tradeSlot; + SendTradeStatus(info); return; } diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index cb3b9082c20..09905572aae 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -92,6 +92,23 @@ enum LootType LOOT_FISHING_JUNK = 22 // unsupported by client, sending LOOT_FISHING instead }; +enum LootError +{ + LOOT_ERROR_DIDNT_KILL = 0, // You don't have permission to loot that corpse. + LOOT_ERROR_TOO_FAR = 4, // You are too far away to loot that corpse. + LOOT_ERROR_BAD_FACING = 5, // You must be facing the corpse to loot it. + LOOT_ERROR_LOCKED = 6, // Someone is already looting that corpse. + LOOT_ERROR_NOTSTANDING = 8, // You need to be standing up to loot something! + LOOT_ERROR_STUNNED = 9, // You can't loot anything while stunned! + LOOT_ERROR_PLAYER_NOT_FOUND = 10, // Player not found + LOOT_ERROR_PLAY_TIME_EXCEEDED = 11, // Maximum play time exceeded + LOOT_ERROR_MASTER_INV_FULL = 12, // That player's inventory is full + LOOT_ERROR_MASTER_UNIQUE_ITEM = 13, // Player has too many of that item already + LOOT_ERROR_MASTER_OTHER = 14, // Can't assign item to that player + LOOT_ERROR_ALREADY_PICKPOCKETED = 15, // Your target has already had its pockets picked + LOOT_ERROR_NOT_WHILE_SHAPESHIFTED = 16 // You can't do that while shapeshifted. +}; + // type of Loot Item in Loot View enum LootSlotType { @@ -119,7 +136,7 @@ struct LootStoreItem // Constructor, converting ChanceOrQuestChance -> (chance, needs_quest) // displayid is filled in IsValid() which must be called after LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, uint16 _lootmode, uint8 _group, int32 _mincountOrRef, uint8 _maxcount) - : itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef), lootmode(_lootmode), + : itemid(_itemid), chance(std::fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef), lootmode(_lootmode), group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount) { } @@ -263,8 +280,8 @@ class LootValidatorRef : public Reference<Loot, LootValidatorRef> { public: LootValidatorRef() { } - void targetObjectDestroyLink() { } - void sourceObjectDestroyLink() { } + void targetObjectDestroyLink() override { } + void sourceObjectDestroyLink() override { } }; //===================================================== diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 75301da32ed..31b16309fcd 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2171,7 +2171,7 @@ float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float // we are already under the surface or vmap height above map heigt // or if the distance of the vmap height is less the land height distance - if (z < mapHeight || vmapHeight > mapHeight || fabs(mapHeight-z) > fabs(vmapHeight-z)) + if (z < mapHeight || vmapHeight > mapHeight || std::fabs(mapHeight - z) > std::fabs(vmapHeight - z)) return vmapHeight; else return mapHeight; // better use .map surface height @@ -2216,7 +2216,7 @@ bool Map::IsOutdoors(float x, float y, float z) const if (!GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId)) return true; - AreaTableEntry const* atEntry = 0; + AreaTableEntry const* atEntry = nullptr; WMOAreaTableEntry const* wmoEntry= GetWMOAreaTableEntryByTripple(rootId, adtId, groupId); if (wmoEntry) { @@ -2249,8 +2249,8 @@ uint16 Map::GetAreaFlag(float x, float y, float z, bool *isOutdoors) const { uint32 mogpFlags; int32 adtId, rootId, groupId; - WMOAreaTableEntry const* wmoEntry = 0; - AreaTableEntry const* atEntry = 0; + WMOAreaTableEntry const* wmoEntry = nullptr; + AreaTableEntry const* atEntry = nullptr; bool haveAreaInfo = false; if (GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId)) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index c194f4dccd7..a92c78ae951 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -334,16 +334,16 @@ class Map : public GridRefManager<NGridType> // can return INVALID_HEIGHT if under z+2 z coord not found height float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; - ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0) const; + ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const; - uint16 GetAreaFlag(float x, float y, float z, bool *isOutdoors=0) const; + uint16 GetAreaFlag(float x, float y, float z, bool *isOutdoors=nullptr) const; bool GetAreaInfo(float x, float y, float z, uint32 &mogpflags, int32 &adtId, int32 &rootId, int32 &groupId) const; bool IsOutdoors(float x, float y, float z) const; uint8 GetTerrainType(float x, float y) const; float GetWaterLevel(float x, float y) const; - bool IsInWater(float x, float y, float z, LiquidData* data = 0) const; + bool IsInWater(float x, float y, float z, LiquidData* data = nullptr) const; bool IsUnderWater(float x, float y, float z) const; static uint32 GetAreaIdByAreaFlag(uint16 areaflag, uint32 map_id); @@ -680,23 +680,23 @@ class InstanceMap : public Map public: InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent); ~InstanceMap(); - bool AddPlayerToMap(Player*); - void RemovePlayerFromMap(Player*, bool); - void Update(const uint32); + bool AddPlayerToMap(Player*) override; + void RemovePlayerFromMap(Player*, bool) override; + void Update(const uint32) override; void CreateInstanceData(bool load); bool Reset(uint8 method); uint32 GetScriptId() { return i_script_id; } InstanceScript* GetInstanceScript() { return i_data; } void PermBindAllPlayers(Player* source); - void UnloadAll(); - bool CanEnter(Player* player); + void UnloadAll() override; + bool CanEnter(Player* player) override; void SendResetWarnings(uint32 timeLeft) const; void SetResetSchedule(bool on); uint32 GetMaxPlayers() const; uint32 GetMaxResetDelay() const; - virtual void InitVisibilityDistance(); + virtual void InitVisibilityDistance() override; private: bool m_resetAfterUnload; bool m_unloadWhenEmpty; @@ -710,14 +710,14 @@ class BattlegroundMap : public Map BattlegroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, uint8 spawnMode); ~BattlegroundMap(); - bool AddPlayerToMap(Player*); - void RemovePlayerFromMap(Player*, bool); - bool CanEnter(Player* player); + bool AddPlayerToMap(Player*) override; + void RemovePlayerFromMap(Player*, bool) override; + bool CanEnter(Player* player) override; void SetUnload(); //void UnloadAll(bool pForce); - void RemoveAllPlayers(); + void RemoveAllPlayers() override; - virtual void InitVisibilityDistance(); + virtual void InitVisibilityDistance() override; Battleground* GetBG() { return m_bg; } void SetBG(Battleground* bg) { m_bg = bg; } private: diff --git a/src/server/game/Maps/MapInstanced.h b/src/server/game/Maps/MapInstanced.h index 30aec43cc21..614764dbba3 100644 --- a/src/server/game/Maps/MapInstanced.h +++ b/src/server/game/Maps/MapInstanced.h @@ -33,11 +33,11 @@ class MapInstanced : public Map ~MapInstanced() { } // functions overwrite Map versions - void Update(const uint32); - void DelayedUpdate(const uint32 diff); + void Update(const uint32) override; + void DelayedUpdate(const uint32 diff) override; //void RelocationNotify(); - void UnloadAll(); - bool CanEnter(Player* player); + void UnloadAll() override; + bool CanEnter(Player* player) override; Map* CreateInstanceForPlayer(const uint32 mapId, Player* player); Map* FindInstanceMap(uint32 instanceId) const @@ -61,7 +61,7 @@ class MapInstanced : public Map } InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; } - virtual void InitVisibilityDistance(); + virtual void InitVisibilityDistance() override; private: InstanceMap* CreateInstance(uint32 InstanceId, InstanceSave* save, Difficulty difficulty); diff --git a/src/server/game/Maps/MapReference.h b/src/server/game/Maps/MapReference.h index fe5ceb714c5..2742902d558 100644 --- a/src/server/game/Maps/MapReference.h +++ b/src/server/game/Maps/MapReference.h @@ -25,18 +25,18 @@ class MapReference : public Reference<Map, Player> { protected: - void targetObjectBuildLink() + void targetObjectBuildLink() override { // called from link() getTarget()->m_mapRefManager.insertFirst(this); getTarget()->m_mapRefManager.incSize(); } - void targetObjectDestroyLink() + void targetObjectDestroyLink() override { // called from unlink() if (isValid()) getTarget()->m_mapRefManager.decSize(); } - void sourceObjectDestroyLink() + void sourceObjectDestroyLink() override { // called from invalidate() getTarget()->m_mapRefManager.decSize(); diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index ba7d3784157..7df509a6d21 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -139,7 +139,7 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl KeyFrame k(node_i); G3D::Vector3 h; orientationSpline.evaluate_derivative(i + 1, 0.0f, h); - k.InitialOrientation = Position::NormalizeOrientation(atan2(h.y, h.x) + M_PI); + k.InitialOrientation = Position::NormalizeOrientation(std::atan2(h.y, h.x) + float(M_PI)); keyFrames.push_back(k); splinePath.push_back(G3D::Vector3(node_i.x, node_i.y, node_i.z)); @@ -213,7 +213,7 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl for (size_t j = start; j < i + extra; ++j) { keyFrames[j].Index = j - start + 1; - keyFrames[j].DistFromPrev = spline->length(j - start, j + 1 - start); + keyFrames[j].DistFromPrev = float(spline->length(j - start, j + 1 - start)); if (j > 0) keyFrames[j - 1].NextDistFromPrev = keyFrames[j].DistFromPrev; keyFrames[j].Spline = spline; @@ -276,22 +276,22 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl if (keyFrames[i].DistSinceStop < keyFrames[i].DistUntilStop) // is still accelerating { // calculate accel+brake time for this short segment - float segment_time = 2.0f * sqrt((keyFrames[i].DistUntilStop + keyFrames[i].DistSinceStop) / accel); + float segment_time = 2.0f * std::sqrt((keyFrames[i].DistUntilStop + keyFrames[i].DistSinceStop) / accel); // substract acceleration time - keyFrames[i].TimeTo = segment_time - sqrt(2 * keyFrames[i].DistSinceStop / accel); + keyFrames[i].TimeTo = segment_time - std::sqrt(2 * keyFrames[i].DistSinceStop / accel); } else // slowing down - keyFrames[i].TimeTo = sqrt(2 * keyFrames[i].DistUntilStop / accel); + keyFrames[i].TimeTo = std::sqrt(2 * keyFrames[i].DistUntilStop / accel); } else if (keyFrames[i].DistSinceStop < accel_dist) // still accelerating (but will reach full speed) { // calculate accel + cruise + brake time for this long segment float segment_time = (keyFrames[i].DistUntilStop + keyFrames[i].DistSinceStop) / speed + (speed / accel); // substract acceleration time - keyFrames[i].TimeTo = segment_time - sqrt(2 * keyFrames[i].DistSinceStop / accel); + keyFrames[i].TimeTo = segment_time - std::sqrt(2 * keyFrames[i].DistSinceStop / accel); } else if (keyFrames[i].DistUntilStop < accel_dist) // already slowing down (but reached full speed) - keyFrames[i].TimeTo = sqrt(2 * keyFrames[i].DistUntilStop / accel); + keyFrames[i].TimeTo = std::sqrt(2 * keyFrames[i].DistUntilStop / accel); else // at full speed keyFrames[i].TimeTo = (keyFrames[i].DistUntilStop / speed) + (0.5f * speed / accel); } diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h index 924320ac198..537fa7543f7 100644 --- a/src/server/game/Miscellaneous/Formulas.h +++ b/src/server/game/Miscellaneous/Formulas.h @@ -163,27 +163,32 @@ namespace Trinity inline uint32 Gain(Player* player, Unit* u) { - uint32 gain; + Creature* creature = u->ToCreature(); + uint32 gain = 0; - if (u->GetTypeId() == TYPEID_UNIT && - (((Creature*)u)->IsTotem() || ((Creature*)u)->IsPet() || - (((Creature*)u)->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL) || - ((Creature*)u)->GetCreatureTemplate()->type == CREATURE_TYPE_CRITTER)) - gain = 0; - else + if (!creature || (!creature->IsTotem() && !creature->IsPet() && !creature->IsCritter() && + !(creature->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL))) { + float xpMod = 1.0f; + gain = BaseGain(player->getLevel(), u->getLevel(), GetContentLevelsForMapAndZone(u->GetMapId(), u->GetZoneId())); - if (gain != 0 && u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->isElite()) + if (gain && creature) { - // Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus. - if (u->GetMap() && u->GetMap()->IsDungeon()) - gain = uint32(gain * 2.75); - else - gain *= 2; + if (creature->isElite()) + { + // Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus. + if (u->GetMap() && u->GetMap()->IsDungeon()) + xpMod *= 2.75f; + else + xpMod *= 2.0f; + } + + xpMod *= creature->GetCreatureTemplate()->ModExperience; } - gain = uint32(gain * sWorld->getRate(RATE_XP_KILL)); + xpMod *= sWorld->getRate(RATE_XP_KILL); + gain = uint32(gain * xpMod); } sScriptMgr->OnGainCalculation(gain, player, u); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 833e4f7c7bc..6e90412a3b6 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -538,7 +538,7 @@ enum SpellAttr6 enum SpellAttr7 { SPELL_ATTR7_UNK0 = 0x00000001, // 0 Shaman's new spells (Call of the ...), Feign Death. - SPELL_ATTR7_UNK1 = 0x00000002, // 1 Not set in 3.2.2a. + SPELL_ATTR7_IGNORE_DURATION_MODS = 0x00000002, // 1 Duration is not affected by duration modifiers SPELL_ATTR7_REACTIVATE_AT_RESURRECT = 0x00000004, // 2 Paladin's auras and 65607 only. SPELL_ATTR7_IS_CHEAT_SPELL = 0x00000008, // 3 Cannot cast if caster doesn't have UnitFlag2 & UNIT_FLAG2_ALLOW_CHEAT_SPELLS SPELL_ATTR7_UNK4 = 0x00000010, // 4 Only 47883 (Soulstone Resurrection) and test spell. @@ -3889,7 +3889,7 @@ enum TradeStatus { TRADE_STATUS_OPEN_WINDOW = 0, // 1 - Related to EVENT_PLAYER_MONEY - TRADE_STATUS_NOT_ELIGIBLE = 2, // Related to trading soulbound loot items + TRADE_STATUS_NOT_ON_TAPLIST = 2, // Related to trading soulbound loot items TRADE_STATUS_YOU_LOGOUT = 3, TRADE_STATUS_IGNORE_YOU = 4, TRADE_STATUS_TARGET_DEAD = 5, @@ -3913,7 +3913,7 @@ enum TradeStatus TRADE_STATUS_TRADE_CANCELED = 23, TRADE_STATUS_CURRENCY = 24, // new 4.x TRADE_STATUS_BACK_TO_TRADE = 25, - TRADE_STATUS_ONLY_CONJURED = 26, // You can only trade conjured items... (cross realm BG related). + TRADE_STATUS_WRONG_REALM = 26, // You can only trade conjured items... (cross realm BG related). TRADE_STATUS_YOU_STUNNED = 27, // 28 - nonexistent TRADE_STATUS_TARGET_STUNNED = 29, diff --git a/src/server/game/Movement/FollowerReference.h b/src/server/game/Movement/FollowerReference.h index a97104ce72c..ee6901dc2d7 100644 --- a/src/server/game/Movement/FollowerReference.h +++ b/src/server/game/Movement/FollowerReference.h @@ -27,8 +27,8 @@ class Unit; class FollowerReference : public Reference<Unit, TargetedMovementGeneratorBase> { protected: - void targetObjectBuildLink(); - void targetObjectDestroyLink(); - void sourceObjectDestroyLink(); + void targetObjectBuildLink() override; + void targetObjectDestroyLink() override; + void sourceObjectDestroyLink() override; }; #endif diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 72bb0e1d56e..c0d20c20639 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -345,7 +345,7 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa float dist = 2 * moveTimeHalf * speedXY; float max_height = -Movement::computeFallElevation(moveTimeHalf, false, -speedZ); - _owner->GetNearPoint(_owner, x, y, z, _owner->GetObjectSize(), dist, _owner->GetAngle(srcX, srcY) + M_PI); + _owner->GetNearPoint(_owner, x, y, z, _owner->GetObjectSize(), dist, _owner->GetAngle(srcX, srcY) + float(M_PI)); Movement::MoveSplineInit init(_owner); init.MoveTo(x, y, z); @@ -399,7 +399,7 @@ void MotionMaster::MoveFall(uint32 id /*=0*/) } // Abort too if the ground is very near - if (fabs(_owner->GetPositionZ() - tz) < 0.1f) + if (std::fabs(_owner->GetPositionZ() - tz) < 0.1f) return; if (_owner->GetTypeId() == TYPEID_PLAYER) diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h index 12116b5505d..d87344ba089 100755 --- a/src/server/game/Movement/MovementGenerator.h +++ b/src/server/game/Movement/MovementGenerator.h @@ -51,25 +51,25 @@ template<class T, class D> class MovementGeneratorMedium : public MovementGenerator { public: - void Initialize(Unit* u) + void Initialize(Unit* u) override { //u->AssertIsType<T>(); (static_cast<D*>(this))->DoInitialize(static_cast<T*>(u)); } - void Finalize(Unit* u) + void Finalize(Unit* u) override { //u->AssertIsType<T>(); (static_cast<D*>(this))->DoFinalize(static_cast<T*>(u)); } - void Reset(Unit* u) + void Reset(Unit* u) override { //u->AssertIsType<T>(); (static_cast<D*>(this))->DoReset(static_cast<T*>(u)); } - bool Update(Unit* u, uint32 time_diff) + bool Update(Unit* u, uint32 time_diff) override { //u->AssertIsType<T>(); return (static_cast<D*>(this))->DoUpdate(static_cast<T*>(u), time_diff); @@ -86,7 +86,7 @@ struct MovementGeneratorFactory : public SelectableMovement { MovementGeneratorFactory(MovementGeneratorType mgt) : SelectableMovement(mgt) { } - MovementGenerator* Create(void *) const; + MovementGenerator* Create(void *) const override; }; typedef FactoryHolder<MovementGenerator, MovementGeneratorType> MovementGeneratorCreator; diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h index ba8e228873f..c3bcfffb2a7 100755 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h @@ -49,9 +49,9 @@ class TimedFleeingMovementGenerator : public FleeingMovementGenerator<Creature> FleeingMovementGenerator<Creature>(fright), i_totalFleeTime(time) { } - MovementGeneratorType GetMovementGeneratorType() { return TIMED_FLEEING_MOTION_TYPE; } - bool Update(Unit*, uint32); - void Finalize(Unit*); + MovementGeneratorType GetMovementGeneratorType() override { return TIMED_FLEEING_MOTION_TYPE; } + bool Update(Unit*, uint32) override; + void Finalize(Unit*) override; private: TimeTracker i_totalFleeTime; diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h index abe97e21536..8e0b0e335c4 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h @@ -38,7 +38,7 @@ class HomeMovementGenerator<Creature> : public MovementGeneratorMedium< Creature void DoFinalize(Creature*); void DoReset(Creature*); bool DoUpdate(Creature*, const uint32); - MovementGeneratorType GetMovementGeneratorType() { return HOME_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() override { return HOME_MOTION_TYPE; } private: void _setTargetLocation(Creature*); diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h index bdf9d52b93a..0cd9b2777b4 100755 --- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h @@ -25,11 +25,11 @@ class IdleMovementGenerator : public MovementGenerator { public: - void Initialize(Unit*); - void Finalize(Unit*) { } - void Reset(Unit*); - bool Update(Unit*, uint32) { return true; } - MovementGeneratorType GetMovementGeneratorType() { return IDLE_MOTION_TYPE; } + void Initialize(Unit*) override; + void Finalize(Unit*) override { } + void Reset(Unit*) override; + bool Update(Unit*, uint32) override { return true; } + MovementGeneratorType GetMovementGeneratorType() override { return IDLE_MOTION_TYPE; } }; extern IdleMovementGenerator si_idleMovement; @@ -39,11 +39,11 @@ class RotateMovementGenerator : public MovementGenerator public: explicit RotateMovementGenerator(uint32 time, RotateDirection direction) : m_duration(time), m_maxDuration(time), m_direction(direction) { } - void Initialize(Unit*); - void Finalize(Unit*); - void Reset(Unit* owner) { Initialize(owner); } - bool Update(Unit*, uint32); - MovementGeneratorType GetMovementGeneratorType() { return ROTATE_MOTION_TYPE; } + void Initialize(Unit*) override; + void Finalize(Unit*) override; + void Reset(Unit* owner) override { Initialize(owner); } + bool Update(Unit*, uint32) override; + MovementGeneratorType GetMovementGeneratorType() override { return ROTATE_MOTION_TYPE; } private: uint32 m_duration, m_maxDuration; @@ -55,11 +55,11 @@ class DistractMovementGenerator : public MovementGenerator public: explicit DistractMovementGenerator(uint32 timer) : m_timer(timer) { } - void Initialize(Unit*); - void Finalize(Unit*); - void Reset(Unit* owner) { Initialize(owner); } - bool Update(Unit*, uint32); - MovementGeneratorType GetMovementGeneratorType() { return DISTRACT_MOTION_TYPE; } + void Initialize(Unit*) override; + void Finalize(Unit*) override; + void Reset(Unit* owner) override { Initialize(owner); } + bool Update(Unit*, uint32) override; + MovementGeneratorType GetMovementGeneratorType() override { return DISTRACT_MOTION_TYPE; } private: uint32 m_timer; @@ -71,8 +71,8 @@ class AssistanceDistractMovementGenerator : public DistractMovementGenerator AssistanceDistractMovementGenerator(uint32 timer) : DistractMovementGenerator(timer) { } - MovementGeneratorType GetMovementGeneratorType() { return ASSISTANCE_DISTRACT_MOTION_TYPE; } - void Finalize(Unit*); + MovementGeneratorType GetMovementGeneratorType() override { return ASSISTANCE_DISTRACT_MOTION_TYPE; } + void Finalize(Unit*) override; }; #endif diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index c596b406cf3..3c5b33f3736 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -55,8 +55,8 @@ class AssistanceMovementGenerator : public PointMovementGenerator<Creature> AssistanceMovementGenerator(float _x, float _y, float _z) : PointMovementGenerator<Creature>(0, _x, _y, _z, true) { } - MovementGeneratorType GetMovementGeneratorType() { return ASSISTANCE_MOTION_TYPE; } - void Finalize(Unit*); + MovementGeneratorType GetMovementGeneratorType() override { return ASSISTANCE_MOTION_TYPE; } + void Finalize(Unit*) override; }; // Does almost nothing - just doesn't allows previous movegen interrupt current effect. @@ -64,11 +64,11 @@ class EffectMovementGenerator : public MovementGenerator { public: explicit EffectMovementGenerator(uint32 Id) : m_Id(Id) { } - void Initialize(Unit*) { } - void Finalize(Unit*); - void Reset(Unit*) { } - bool Update(Unit*, uint32); - MovementGeneratorType GetMovementGeneratorType() { return EFFECT_MOTION_TYPE; } + void Initialize(Unit*) override { } + void Finalize(Unit*) override; + void Reset(Unit*) override { } + bool Update(Unit*, uint32) override; + MovementGeneratorType GetMovementGeneratorType() override { return EFFECT_MOTION_TYPE; } private: uint32 m_Id; }; diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index 95c342b70b3..dbe8c8b0329 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -61,7 +61,7 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature) if (is_air_ok) // 3D system above ground and above water (flying mode) { // Limit height change - const float distanceZ = float(rand_norm()) * sqrtf(travelDistZ)/2.0f; + const float distanceZ = float(rand_norm()) * std::sqrt(travelDistZ)/2.0f; destZ = respZ + distanceZ; float levelZ = map->GetWaterOrGroundLevel(destX, destY, destZ-2.0f); @@ -73,24 +73,24 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature) else // 2D only { // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE) - travelDistZ = travelDistZ >= 100.0f ? 10.0f : sqrtf(travelDistZ); + travelDistZ = travelDistZ >= 100.0f ? 10.0f : std::sqrt(travelDistZ); // The fastest way to get an accurate result 90% of the time. // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long. destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ+travelDistZ-2.0f, false); - if (fabs(destZ - respZ) > travelDistZ) // Map check + if (std::fabs(destZ - respZ) > travelDistZ) // Map check { // Vmap Horizontal or above destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ - 2.0f, true); - if (fabs(destZ - respZ) > travelDistZ) + if (std::fabs(destZ - respZ) > travelDistZ) { // Vmap Higher destZ = map->GetHeight(creature->GetPhaseMask(), destX, destY, respZ+travelDistZ-2.0f, true); // let's forget this bad coords where a z cannot be find and retry at next tick - if (fabs(destZ - respZ) > travelDistZ) + if (std::fabs(destZ - respZ) > travelDistZ) return; } } diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h index 9b5fe14b9d6..85c39fe0830 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h @@ -72,7 +72,7 @@ class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium< Crea void MovementInform(Creature*); - MovementGeneratorType GetMovementGeneratorType() { return WAYPOINT_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() override { return WAYPOINT_MOTION_TYPE; } // now path movement implmementation void LoadPath(Creature*); @@ -126,7 +126,7 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig void DoReset(Player*); void DoFinalize(Player*); bool DoUpdate(Player*, uint32); - MovementGeneratorType GetMovementGeneratorType() { return FLIGHT_MOTION_TYPE; } + MovementGeneratorType GetMovementGeneratorType() override { return FLIGHT_MOTION_TYPE; } TaxiPathNodeList const& GetPath() { return *i_path; } uint32 GetPathAtMapEnd() const; diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 6e3d7680637..4247197b3b0 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -47,7 +47,7 @@ Location MoveSpline::ComputePosition() const if (splineflags.final_angle) c.orientation = facing.angle; else if (splineflags.final_point) - c.orientation = atan2(facing.f.y - c.y, facing.f.x - c.x); + c.orientation = std::atan2(facing.f.y - c.y, facing.f.x - c.x); //nothing to do for MoveSplineFlag::Final_Target flag } else @@ -56,7 +56,7 @@ Location MoveSpline::ComputePosition() const { Vector3 hermite; spline.evaluate_derivative(point_Idx, u, hermite); - c.orientation = atan2(hermite.y, hermite.x); + c.orientation = std::atan2(hermite.y, hermite.x); } if (splineflags.orientationInversed) @@ -226,7 +226,7 @@ bool MoveSplineInitArgs::_checkPathBounds() const for (uint32 i = 1; i < path.size()-1; ++i) { offset = path[i] - middle; - if (fabs(offset.x) >= MAX_OFFSET || fabs(offset.y) >= MAX_OFFSET || fabs(offset.z) >= MAX_OFFSET) + if (std::fabs(offset.x) >= MAX_OFFSET || std::fabs(offset.y) >= MAX_OFFSET || std::fabs(offset.z) >= MAX_OFFSET) { TC_LOG_ERROR("misc", "MoveSplineInitArgs::_checkPathBounds check failed"); return false; diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h index 134e7a45425..a69af9e3a83 100644 --- a/src/server/game/Movement/Spline/MovementTypedefs.h +++ b/src/server/game/Movement/Spline/MovementTypedefs.h @@ -69,7 +69,7 @@ namespace Movement typedef counter<uint32, 0xFFFFFFFF> UInt32Counter; - extern double gravity; + extern float gravity; extern UInt32Counter splineIdGen; extern std::string MovementFlags_ToString(uint32 flags); extern std::string MovementFlagsExtra_ToString(uint32 flags); diff --git a/src/server/game/Movement/Spline/MovementUtil.cpp b/src/server/game/Movement/Spline/MovementUtil.cpp index f5bdba378d1..3f629238948 100644 --- a/src/server/game/Movement/Spline/MovementUtil.cpp +++ b/src/server/game/Movement/Spline/MovementUtil.cpp @@ -17,12 +17,12 @@ */ #include "MoveSplineFlag.h" -#include <math.h> +#include <cmath> #include <string> namespace Movement { - double gravity = 19.29110527038574; + float gravity = static_cast<float>(19.29110527038574); UInt32Counter splineIdGen; /// Velocity bounds that makes fall speed limited @@ -45,14 +45,14 @@ namespace Movement if (path_length >= terminal_safeFall_length) time = (path_length - terminal_safeFall_length) / terminalSafefallVelocity + terminal_safeFall_fallTime; else - time = sqrtf(2.0f * path_length / gravity); + time = std::sqrt(2.0f * path_length / gravity); } else { if (path_length >= terminal_length) time = (path_length - terminal_length) / terminalVelocity + terminal_fallTime; else - time = sqrtf(2.0f * path_length / gravity); + time = std::sqrt(2.0f * path_length / gravity); } return time; diff --git a/src/server/game/Movement/Spline/Spline.cpp b/src/server/game/Movement/Spline/Spline.cpp index 6424afc5d6e..b8a028b6fc0 100644 --- a/src/server/game/Movement/Spline/Spline.cpp +++ b/src/server/game/Movement/Spline/Spline.cpp @@ -165,7 +165,7 @@ float SplineBase::SegLengthCatmullRom(index_type index) const curPos = nextPos = p[1]; index_type i = 1; - double length = 0; + float length = 0; while (i <= STEPS_PER_SEGMENT) { C_Evaluate(p, float(i) / float(STEPS_PER_SEGMENT), s_catmullRomCoeffs, nextPos); @@ -188,7 +188,7 @@ float SplineBase::SegLengthBezier3(index_type index) const curPos = nextPos; index_type i = 1; - double length = 0; + float length = 0; while (i <= STEPS_PER_SEGMENT) { C_Evaluate(p, float(i) / float(STEPS_PER_SEGMENT), s_Bezier3Coeffs, nextPos); diff --git a/src/server/game/Movement/Waypoints/Path.h b/src/server/game/Movement/Waypoints/Path.h index 4c275cbc15d..c7e701c49ad 100644 --- a/src/server/game/Movement/Waypoints/Path.h +++ b/src/server/game/Movement/Waypoints/Path.h @@ -63,7 +63,7 @@ class Path float xd = node.x - prev.x; float yd = node.y - prev.y; float zd = node.z - prev.z; - len += sqrtf(xd*xd + yd*yd + zd*zd); + len += std::sqrt(xd*xd + yd*yd + zd*zd); } return len; } @@ -80,7 +80,7 @@ class Path float xd = x - node.x; float yd = y - node.y; float zd = z - node.z; - len += sqrtf(xd*xd + yd*yd + zd*zd); + len += std::sqrt(xd*xd + yd*yd + zd*zd); } return len; diff --git a/src/server/game/Movement/Waypoints/WaypointManager.cpp b/src/server/game/Movement/Waypoints/WaypointManager.cpp index 2820c5dee17..21af63868db 100644 --- a/src/server/game/Movement/Waypoints/WaypointManager.cpp +++ b/src/server/game/Movement/Waypoints/WaypointManager.cpp @@ -78,6 +78,7 @@ void WaypointMgr::Load() if (wp->move_type >= WAYPOINT_MOVE_TYPE_MAX) { TC_LOG_ERROR("sql.sql", "Waypoint %u in waypoint_data has invalid move_type, ignoring", wp->id); + delete wp; continue; } @@ -134,13 +135,14 @@ void WaypointMgr::ReloadPath(uint32 id) wp->z = z; wp->orientation = o; wp->move_type = fields[5].GetUInt32(); - + if (wp->move_type >= WAYPOINT_MOVE_TYPE_MAX) { TC_LOG_ERROR("sql.sql", "Waypoint %u in waypoint_data has invalid move_type, ignoring", wp->id); + delete wp; continue; } - + wp->delay = fields[6].GetUInt32(); wp->event_id = fields[7].GetUInt32(); wp->event_chance = fields[8].GetUInt8(); diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h index b7c08d51bda..b4e546164d0 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.h +++ b/src/server/game/OutdoorPvP/OutdoorPvP.h @@ -217,9 +217,9 @@ class OutdoorPvP : public ZoneScript // setup stuff virtual bool SetupOutdoorPvP() {return true;} - void OnGameObjectCreate(GameObject* go); - void OnGameObjectRemove(GameObject* go); - void OnCreatureCreate(Creature*) { } + void OnGameObjectCreate(GameObject* go) override; + void OnGameObjectRemove(GameObject* go) override; + void OnCreatureCreate(Creature*) override { } // send world state update to all players present void SendUpdateWorldState(uint32 field, uint32 value); diff --git a/src/server/game/Pools/PoolMgr.h b/src/server/game/Pools/PoolMgr.h index d1fcadd40de..dd24cceae07 100644 --- a/src/server/game/Pools/PoolMgr.h +++ b/src/server/game/Pools/PoolMgr.h @@ -33,7 +33,7 @@ struct PoolObject { uint32 guid; float chance; - PoolObject(uint32 _guid, float _chance): guid(_guid), chance(fabs(_chance)) { } + PoolObject(uint32 _guid, float _chance) : guid(_guid), chance(std::fabs(_chance)) { } }; class Pool // for Pool of Pool case diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 7c089eee07b..89ca3749a05 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -232,10 +232,12 @@ uint32 Quest::XPValue(Player* player) const int32 Quest::GetRewOrReqMoney() const { + // RequiredMoney: the amount is the negative copper sum. if (RewardOrRequiredMoney <= 0) return RewardOrRequiredMoney; - return int32(RewardOrRequiredMoney * sWorld->getRate(RATE_DROP_MONEY)); + // RewardMoney: the positive amount + return int32(RewardOrRequiredMoney * sWorld->getRate(RATE_MONEY_QUEST)); } void Quest::BuildExtraQuestInfo(WorldPacket& data, Player* player) const @@ -313,10 +315,12 @@ void Quest::BuildExtraQuestInfo(WorldPacket& data, Player* player) const uint32 Quest::GetRewMoneyMaxLevel() const { + // If Quest has flag to not give money on max level, it's 0 if (HasFlag(QUEST_FLAGS_NO_MONEY_FROM_XP)) return 0; - return RewardMoneyMaxLevel; + // Else, return the rewarded copper sum modified by the rate + return uint32(RewardMoneyMaxLevel * sWorld->getRate(RATE_MONEY_MAX_LEVEL_QUEST)); } bool Quest::IsAutoAccept() const diff --git a/src/server/game/Scripting/MapScripts.cpp b/src/server/game/Scripting/MapScripts.cpp index 7c82b806cf8..3ccc876e1a2 100644 --- a/src/server/game/Scripting/MapScripts.cpp +++ b/src/server/game/Scripting/MapScripts.cpp @@ -824,10 +824,9 @@ void Map::ScriptsProcess() } Creature* cTarget = NULL; - if (source) //using grid searcher + WorldObject* wSource = dynamic_cast <WorldObject*> (source); + if (wSource) //using grid searcher { - WorldObject* wSource = dynamic_cast <WorldObject*> (source); - CellCoord p(Trinity::ComputeCellCoord(wSource->GetPositionX(), wSource->GetPositionY())); Cell cell(p); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 29107a72a9e..9bdf591103d 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -266,7 +266,6 @@ void AddSC_blasted_lands(); void AddSC_burning_steppes(); void AddSC_duskwood(); void AddSC_eastern_plaguelands(); -void AddSC_eversong_woods(); void AddSC_ghostlands(); void AddSC_hinterlands(); void AddSC_isle_of_queldanas(); diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 6d0be13c35e..a6201bb7d51 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -32,6 +32,7 @@ #include "CreatureAIImpl.h" #include "Player.h" #include "WorldPacket.h" +#include "WorldSession.h" namespace { @@ -407,44 +408,42 @@ void ScriptMgr::OnSocketOpen(std::shared_ptr<WorldSocket> socket) FOREACH_SCRIPT(ServerScript)->OnSocketOpen(socket); } -void ScriptMgr::OnSocketClose(std::shared_ptr<WorldSocket> socket, bool wasNew) +void ScriptMgr::OnSocketClose(std::shared_ptr<WorldSocket> socket) { ASSERT(socket); - FOREACH_SCRIPT(ServerScript)->OnSocketClose(socket, wasNew); + FOREACH_SCRIPT(ServerScript)->OnSocketClose(socket); } -void ScriptMgr::OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet) +void ScriptMgr::OnPacketReceive(WorldSession* session, WorldPacket const& packet) { - ASSERT(socket); - if (SCR_REG_LST(ServerScript).empty()) return; WorldPacket copy(packet); - FOREACH_SCRIPT(ServerScript)->OnPacketReceive(socket, copy); + FOREACH_SCRIPT(ServerScript)->OnPacketReceive(session, copy); } -void ScriptMgr::OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet) +void ScriptMgr::OnPacketSend(WorldSession* session, WorldPacket const& packet) { - ASSERT(socket); + ASSERT(session); if (SCR_REG_LST(ServerScript).empty()) return; WorldPacket copy(packet); - FOREACH_SCRIPT(ServerScript)->OnPacketSend(socket, copy); + FOREACH_SCRIPT(ServerScript)->OnPacketSend(session, copy); } -void ScriptMgr::OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet) +void ScriptMgr::OnUnknownPacketReceive(WorldSession* session, WorldPacket const& packet) { - ASSERT(socket); + ASSERT(session); if (SCR_REG_LST(ServerScript).empty()) return; WorldPacket copy(packet); - FOREACH_SCRIPT(ServerScript)->OnUnknownPacketReceive(socket, copy); + FOREACH_SCRIPT(ServerScript)->OnUnknownPacketReceive(session, copy); } void ScriptMgr::OnOpenStateChange(bool open) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 104410a1345..9f52aec848f 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -59,6 +59,7 @@ class Vehicle; class WorldPacket; class WorldSocket; class WorldObject; +class WorldSession; struct AuctionEntry; struct ConditionSourceInfo; @@ -196,7 +197,7 @@ class SpellScriptLoader : public ScriptObject public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Should return a fully valid SpellScript pointer. virtual SpellScript* GetSpellScript() const { return NULL; } @@ -224,19 +225,19 @@ class ServerScript : public ScriptObject // Called when a socket is closed. Do not store the socket object, and do not rely on the connection // being open; it is not. - virtual void OnSocketClose(std::shared_ptr<WorldSocket> /*socket*/, bool /*wasNew*/) { } + virtual void OnSocketClose(std::shared_ptr<WorldSocket> /*socket*/) { } // Called when a packet is sent to a client. The packet object is a copy of the original packet, so reading // and modifying it is safe. - virtual void OnPacketSend(std::shared_ptr<WorldSocket> /*socket*/, WorldPacket& /*packet*/) { } + virtual void OnPacketSend(WorldSession* /*session*/, WorldPacket& /*packet*/) { } // Called when a (valid) packet is received by a client. The packet object is a copy of the original packet, so - // reading and modifying it is safe. - virtual void OnPacketReceive(std::shared_ptr<WorldSocket> /*socket*/, WorldPacket& /*packet*/) { } + // reading and modifying it is safe. Make sure to check WorldSession pointer before usage, it might be null in case of auth packets + virtual void OnPacketReceive(WorldSession* /*session*/, WorldPacket& /*packet*/) { } // Called when an invalid (unknown opcode) packet is received by a client. The packet is a reference to the orignal // packet; not a copy. This allows you to actually handle unknown packets (for whatever purpose). - virtual void OnUnknownPacketReceive(std::shared_ptr<WorldSocket> /*socket*/, WorldPacket& /*packet*/) { } + virtual void OnUnknownPacketReceive(WorldSession* /*session*/, WorldPacket& /*packet*/) { } }; class WorldScript : public ScriptObject @@ -354,7 +355,7 @@ class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap> public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Gets an InstanceScript object for this instance. virtual InstanceScript* GetInstanceScript(InstanceMap* /*map*/) const { return NULL; } @@ -375,7 +376,7 @@ class ItemScript : public ScriptObject public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Called when a dummy spell effect is triggered on the item. virtual bool OnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/, Item* /*target*/) { return false; } @@ -424,7 +425,7 @@ class CreatureScript : public UnitScript, public UpdatableScript<Creature> public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Called when a dummy spell effect is triggered on the creature. virtual bool OnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/, Creature* /*target*/) { return false; } @@ -465,7 +466,7 @@ class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject> public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Called when a dummy spell effect is triggered on the gameobject. virtual bool OnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/, GameObject* /*target*/) { return false; } @@ -512,7 +513,7 @@ class AreaTriggerScript : public ScriptObject public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Called when the area trigger is activated by a player. virtual bool OnTrigger(Player* /*player*/, AreaTriggerEntry const* /*trigger*/) { return false; } @@ -526,7 +527,7 @@ class BattlegroundScript : public ScriptObject public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Should return a fully valid Battleground object for the type ID. virtual Battleground* GetBattleground() const = 0; @@ -540,7 +541,7 @@ class OutdoorPvPScript : public ScriptObject public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Should return a fully valid OutdoorPvP object for the type ID. virtual OutdoorPvP* GetOutdoorPvP() const = 0; @@ -566,7 +567,7 @@ class WeatherScript : public ScriptObject, public UpdatableScript<Weather> public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Called when the weather changes in the zone this script is associated with. virtual void OnChange(Weather* /*weather*/, WeatherState /*state*/, float /*grade*/) { } @@ -601,7 +602,7 @@ class ConditionScript : public ScriptObject public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Called when a single condition is checked for a player. virtual bool OnConditionCheck(Condition* /*condition*/, ConditionSourceInfo& /*sourceInfo*/) { return true; } @@ -649,7 +650,7 @@ class TransportScript : public ScriptObject, public UpdatableScript<Transport> public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Called when a player boards the transport. virtual void OnAddPassenger(Transport* /*transport*/, Player* /*player*/) { } @@ -672,7 +673,7 @@ class AchievementCriteriaScript : public ScriptObject public: - bool IsDatabaseBound() const final { return true; } + bool IsDatabaseBound() const final override { return true; } // Called when an additional criteria is checked. virtual bool OnCheck(Player* source, Unit* target) = 0; @@ -804,7 +805,7 @@ class GuildScript : public ScriptObject public: - bool IsDatabaseBound() const final { return false; } + bool IsDatabaseBound() const final override { return false; } // Called when a member is added to the guild. virtual void OnAddMember(Guild* /*guild*/, Player* /*player*/, uint8& /*plRank*/) { } @@ -847,7 +848,7 @@ class GroupScript : public ScriptObject public: - bool IsDatabaseBound() const final { return false; } + bool IsDatabaseBound() const final override { return false; } // Called when a member is added to a group. virtual void OnAddMember(Group* /*group*/, uint64 /*guid*/) { } @@ -908,10 +909,10 @@ class ScriptMgr void OnNetworkStart(); void OnNetworkStop(); void OnSocketOpen(std::shared_ptr<WorldSocket> socket); - void OnSocketClose(std::shared_ptr<WorldSocket> socket, bool wasNew); - void OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet); - void OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet); - void OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet); + void OnSocketClose(std::shared_ptr<WorldSocket> socket); + void OnPacketReceive(WorldSession* session, WorldPacket const& packet); + void OnPacketSend(WorldSession* session, WorldPacket const& packet); + void OnUnknownPacketReceive(WorldSession* session, WorldPacket const& packet); public: /* WorldScript */ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index cc5e9413b7a..63fe4dd3743 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -612,7 +612,6 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER(MSG_SET_RAID_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetRaidDifficultyOpcode ); DEFINE_OPCODE_HANDLER(MSG_TABARDVENDOR_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode); DEFINE_OPCODE_HANDLER(MSG_TALENT_WIPE_CONFIRM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTalentWipeConfirmOpcode ); - DEFINE_OPCODE_HANDLER(MSG_VERIFY_CONNECTIVITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess ); DEFINE_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_ACCOUNT_INFO_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_ACCOUNT_RESTRICTED_WARNING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 4047b1b42c5..c26f018eabf 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -653,7 +653,6 @@ enum Opcodes MSG_START_MOVE_FORWARD = 0x0000, MSG_TABARDVENDOR_ACTIVATE = 0x6926, MSG_TALENT_WIPE_CONFIRM = 0x0107, - MSG_VERIFY_CONNECTIVITY = 0x4F57, SMSG_ACCOUNT_DATA_TIMES = 0x4B05, SMSG_ACCOUNT_INFO_RESPONSE = 0x10A7, SMSG_ACCOUNT_RESTRICTED_WARNING = 0x51A7, diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp index 0d0dd07edf9..9c0bdd5d558 100644 --- a/src/server/game/Server/Protocol/PacketLog.cpp +++ b/src/server/game/Server/Protocol/PacketLog.cpp @@ -58,7 +58,7 @@ struct PacketHeader PacketLog::PacketLog() : _file(NULL) { - Initialize(); + std::call_once(_initializeFlag, &PacketLog::Initialize, this); } PacketLog::~PacketLog() @@ -99,6 +99,8 @@ void PacketLog::Initialize() void PacketLog::LogPacket(WorldPacket const& packet, Direction direction, boost::asio::ip::address addr, uint16 port) { + std::lock_guard<std::mutex> lock(_logPacketLock); + PacketHeader header; *reinterpret_cast<uint32*>(header.Direction) = direction == CLIENT_TO_SERVER ? 0x47534d43 : 0x47534d53; header.ConnectionId = 0; diff --git a/src/server/game/Server/Protocol/PacketLog.h b/src/server/game/Server/Protocol/PacketLog.h index b09e853236a..36e8c675f63 100644 --- a/src/server/game/Server/Protocol/PacketLog.h +++ b/src/server/game/Server/Protocol/PacketLog.h @@ -19,7 +19,9 @@ #define TRINITY_PACKETLOG_H #include "Common.h" + #include <boost/asio/ip/address.hpp> +#include <mutex> enum Direction { @@ -34,6 +36,8 @@ class PacketLog private: PacketLog(); ~PacketLog(); + std::mutex _logPacketLock; + std::once_flag _initializeFlag; public: static PacketLog* instance() diff --git a/src/server/game/Server/WorldPacket.h b/src/server/game/Server/WorldPacket.h index 3e812621b48..b047b20bce2 100644 --- a/src/server/game/Server/WorldPacket.h +++ b/src/server/game/Server/WorldPacket.h @@ -54,6 +54,8 @@ class WorldPacket : public ByteBuffer return *this; } + WorldPacket(Opcodes opcode, MessageBuffer&& buffer) : ByteBuffer(std::move(buffer)), m_opcode(opcode) { } + void Initialize(Opcodes opcode, size_t newres=200) { clear(); @@ -63,6 +65,7 @@ class WorldPacket : public ByteBuffer Opcodes GetOpcode() const { return m_opcode; } void SetOpcode(Opcodes opcode) { m_opcode = opcode; } + bool IsCompressed() const { return (m_opcode & COMPRESSED_OPCODE_MASK) != 0; } void Compress(z_stream_s* compressionStream); void Compress(z_stream_s* compressionStream, WorldPacket const* source); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 227555c1dfa..feef22c8a21 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -266,6 +266,8 @@ void WorldSession::SendPacket(WorldPacket* packet, bool forced /*= false*/) } #endif // !TRINITY_DEBUG + sScriptMgr->OnPacketSend(this, *packet); + m_Socket->AsyncWrite(*packet); } @@ -350,7 +352,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) } else if (_player->IsInWorld()) { - sScriptMgr->OnPacketReceive(m_Socket, *packet); + sScriptMgr->OnPacketReceive(this, *packet); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } @@ -363,7 +365,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) else { // not expected _player or must checked in packet hanlder - sScriptMgr->OnPacketReceive(m_Socket, *packet); + sScriptMgr->OnPacketReceive(this, *packet); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } @@ -375,7 +377,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); else { - sScriptMgr->OnPacketReceive(m_Socket, *packet); + sScriptMgr->OnPacketReceive(this, *packet); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } @@ -393,7 +395,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) if (packet->GetOpcode() == CMSG_CHAR_ENUM) m_playerRecentlyLogout = false; - sScriptMgr->OnPacketReceive(m_Socket, *packet); + sScriptMgr->OnPacketReceive(this, *packet); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); break; @@ -449,7 +451,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) if (m_Socket && !m_Socket->IsOpen()) { expireTime -= expireTime > diff ? diff : expireTime; - if (expireTime < diff || forceExit) + if (expireTime < diff || forceExit || !GetPlayer()) { m_Socket = nullptr; } @@ -1320,6 +1322,10 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case CMSG_MESSAGECHAT_YELL: // 0 3.5 case CMSG_INSPECT: // 0 3.5 case CMSG_AREA_SPIRIT_HEALER_QUERY: // not profiled + case CMSG_STANDSTATECHANGE: // not profiled + case MSG_RANDOM_ROLL: // not profiled + case CMSG_TIME_SYNC_RESP: // not profiled + case CMSG_TRAINER_BUY_SPELL: // not profiled { // "0" is a magic number meaning there's no limit for the opcode. // All the opcodes above must cause little CPU usage and no sync/async database queries at all @@ -1348,6 +1354,9 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case CMSG_CALENDAR_GET_CALENDAR: // 0 1.5 medium upload bandwidth usage case CMSG_GUILD_BANK_QUERY_TAB: // 0 3.5 medium upload bandwidth usage case CMSG_QUERY_INSPECT_ACHIEVEMENTS: // 0 13 high upload bandwidth usage + case CMSG_GAMEOBJ_REPORT_USE: // not profiled + case CMSG_GAMEOBJ_USE: // not profiled + case MSG_PETITION_DECLINE: // not profiled { maxPacketCounterAllowed = 50; break; @@ -1361,8 +1370,7 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case CMSG_GM_REPORT_LAG: // 1 3 1 async db query case CMSG_SPELLCLICK: // not profiled - case CMSG_GAMEOBJ_USE: // not profiled - case CMSG_GAMEOBJ_REPORT_USE: // not profiled + case CMSG_DISMISS_CONTROLLED_VEHICLE: // not profiled { maxPacketCounterAllowed = 20; break; @@ -1390,7 +1398,6 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case CMSG_REQUEST_VEHICLE_PREV_SEAT: // not profiled case CMSG_REQUEST_VEHICLE_NEXT_SEAT: // not profiled case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: // not profiled - case CMSG_DISMISS_CONTROLLED_VEHICLE: // not profiled case CMSG_REQUEST_VEHICLE_EXIT: // not profiled case CMSG_EJECT_PASSENGER: // not profiled case CMSG_ITEM_REFUND: // not profiled @@ -1442,11 +1449,9 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co case CMSG_SET_GUILD_BANK_TEXT: // not profiled case MSG_SAVE_GUILD_EMBLEM: // not profiled case MSG_PETITION_RENAME: // not profiled - case MSG_PETITION_DECLINE: // not profiled case MSG_TALENT_WIPE_CONFIRM: // not profiled case MSG_SET_DUNGEON_DIFFICULTY: // not profiled case MSG_SET_RAID_DIFFICULTY: // not profiled - case MSG_RANDOM_ROLL: // not profiled case MSG_PARTY_ASSIGNMENT: // not profiled case MSG_RAID_READY_CHECK: // not profiled { diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index bd159475c37..f7269ae977c 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -53,6 +53,7 @@ struct AuctionEntry; struct DeclinedName; struct ItemTemplate; struct MovementInfo; +struct TradeStatusInfo; namespace lfg { @@ -159,9 +160,9 @@ public: explicit MapSessionFilter(WorldSession* pSession) : PacketFilter(pSession) { } ~MapSessionFilter() { } - virtual bool Process(WorldPacket* packet); + virtual bool Process(WorldPacket* packet) override; //in Map::Update() we do not process player logout! - virtual bool ProcessLogout() const { return false; } + virtual bool ProcessLogout() const override { return false; } }; //class used to filer only thread-unsafe packets from queue @@ -172,7 +173,7 @@ public: explicit WorldSessionFilter(WorldSession* pSession) : PacketFilter(pSession) { } ~WorldSessionFilter() { } - virtual bool Process(WorldPacket* packet); + virtual bool Process(WorldPacket* packet) override; }; // Proxy structure to contain data passed to callback function, @@ -303,7 +304,7 @@ class WorldSession void SendBattleGroundList(uint64 guid, BattlegroundTypeId bgTypeId = BATTLEGROUND_RB); - void SendTradeStatus(TradeStatus status, int8 clearSlot = 0); + void SendTradeStatus(TradeStatusInfo const& status); void SendUpdateTrade(bool trader_data = true); void SendCancelTrade(); @@ -379,17 +380,22 @@ class WorldSession void SetLatency(uint32 latency) { m_latency = latency; } void ResetClientTimeDelay() { m_clientTimeDelay = 0; } - std::atomic<time_t> m_timeOutTime; + std::atomic<int32> m_timeOutTime; void UpdateTimeOutTime(uint32 diff) { - if (time_t(diff) > m_timeOutTime) - m_timeOutTime = 0; - else - m_timeOutTime -= diff; + m_timeOutTime -= int32(diff); + } + + void ResetTimeOutTime() + { + m_timeOutTime = int32(sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME)); + } + + bool IsConnectionIdle() const + { + return m_timeOutTime <= 0 && !m_inQueue; } - void ResetTimeOutTime() { m_timeOutTime = sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME); } - bool IsConnectionIdle() const { return (m_timeOutTime <= 0 && !m_inQueue); } // Recruit-A-Friend Handling uint32 GetRecruiterId() const { return recruiterId; } diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index e74e7806288..9a7b212da04 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -16,31 +16,35 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <memory> #include "WorldSocket.h" #include "BigNumber.h" #include "Opcodes.h" +#include "Player.h" #include "ScriptMgr.h" #include "SHA1.h" #include "PacketLog.h" #include "BattlenetAccountMgr.h" +#include <memory> using boost::asio::ip::tcp; -WorldSocket::WorldSocket(tcp::socket&& socket) - : Socket(std::move(socket), sizeof(ClientPktHeader)), _authSeed(rand32()), _OverSpeedPings(0), _worldSession(nullptr) +std::string const WorldSocket::ServerConnectionInitialize("WORLD OF WARCRAFT CONNECTION - SERVER TO CLIENT"); + +std::string const WorldSocket::ClientConnectionInitialize("WORLD OF WARCRAFT CONNECTION - CLIENT TO SERVER"); + +WorldSocket::WorldSocket(tcp::socket&& socket) : Socket(std::move(socket), sizeof(ClientPktHeader)), + _authSeed(rand32()), _OverSpeedPings(0), _worldSession(nullptr), _initialized(false) { } void WorldSocket::Start() { - AsyncReadHeader(); + sScriptMgr->OnSocketOpen(shared_from_this()); - // not an opcode. this packet sends raw string WORLD OF WARCRAFT CONNECTION - SERVER TO CLIENT" - // because of our implementation of WorldPacket sending, bytes "WO" become the opcode - WorldPacket packet(MSG_VERIFY_CONNECTIVITY); - packet << "RLD OF WARCRAFT CONNECTION - SERVER TO CLIENT"; - AsyncWrite(packet); + AsyncReadData(ClientConnectionInitialize.length() + 2 /*sizeof(ClientPktHeader::size)*/ + 1 /*null terminator*/); + + _writeQueue.emplace(ServerConnectionInitialize); + AsyncWrite(_writeQueue.front()); } void WorldSocket::HandleSendAuthSession() @@ -59,47 +63,49 @@ void WorldSocket::HandleSendAuthSession() AsyncWrite(packet); } -void WorldSocket::ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) +void WorldSocket::ReadHeaderHandler() { - if (!error && transferedBytes == sizeof(ClientPktHeader)) - { - _authCrypt.DecryptRecv(GetReadBuffer(), sizeof(ClientPktHeader)); + _authCrypt.DecryptRecv(GetHeaderBuffer(), sizeof(ClientPktHeader)); - ClientPktHeader* header = reinterpret_cast<ClientPktHeader*>(GetReadBuffer()); - EndianConvertReverse(header->size); - EndianConvert(header->cmd); + ClientPktHeader* header = reinterpret_cast<ClientPktHeader*>(GetHeaderBuffer()); + EndianConvertReverse(header->size); + EndianConvert(header->cmd); + + if (!header->IsValid()) + { + if (_worldSession) + { + Player* player = _worldSession->GetPlayer(); + TC_LOG_ERROR("network", "WorldSocket::ReadHeaderHandler(): client (account: %u, char [GUID: %u, name: %s]) sent malformed packet (size: %hu, cmd: %u)", + _worldSession->GetAccountId(), player ? player->GetGUIDLow() : 0, player ? player->GetName().c_str() : "<none>", header->size, header->cmd); + } + else + TC_LOG_ERROR("network", "WorldSocket::ReadHeaderHandler(): client %s sent malformed packet (size: %hu, cmd: %u)", + GetRemoteIpAddress().to_string().c_str(), header->size, header->cmd); - AsyncReadData(header->size - sizeof(header->cmd), sizeof(ClientPktHeader)); - } - else CloseSocket(); + return; + } + + AsyncReadData(header->size - sizeof(header->cmd)); } -void WorldSocket::ReadDataHandler(boost::system::error_code error, size_t transferedBytes) +void WorldSocket::ReadDataHandler() { - ClientPktHeader* header = reinterpret_cast<ClientPktHeader*>(GetReadBuffer()); - - if (!error && transferedBytes == (header->size - sizeof(header->cmd))) + if (_initialized) { - header->size -= sizeof(header->cmd); + ClientPktHeader* header = reinterpret_cast<ClientPktHeader*>(GetHeaderBuffer()); Opcodes opcode = PacketFilter::DropHighBytes(Opcodes(header->cmd)); std::string opcodeName = GetOpcodeNameForLogging(opcode); - WorldPacket packet(opcode, header->size); - - if (header->size > 0) - { - packet.resize(header->size); - - std::memcpy(packet.contents(), &(GetReadBuffer()[sizeof(ClientPktHeader)]), header->size); - } + WorldPacket packet(opcode, MoveData()); if (sPacketLog->CanLogPacket()) sPacketLog->LogPacket(packet, CLIENT_TO_SERVER, GetRemoteIpAddress(), GetRemotePort()); - TC_LOG_TRACE("network.opcode", "C->S: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), GetOpcodeNameForLogging(opcode).c_str()); + TC_LOG_TRACE("network.opcode", "C->S: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), opcodeName.c_str()); switch (opcode) { @@ -113,39 +119,21 @@ void WorldSocket::ReadDataHandler(boost::system::error_code error, size_t transf break; } - sScriptMgr->OnPacketReceive(shared_from_this(), packet); HandleAuthSession(packet); break; case CMSG_KEEP_ALIVE: TC_LOG_DEBUG("network", "%s", opcodeName.c_str()); - sScriptMgr->OnPacketReceive(shared_from_this(), packet); + sScriptMgr->OnPacketReceive(_worldSession, packet); break; case CMSG_LOG_DISCONNECT: packet.rfinish(); // contains uint32 disconnectReason; TC_LOG_DEBUG("network", "%s", opcodeName.c_str()); - sScriptMgr->OnPacketReceive(shared_from_this(), packet); + sScriptMgr->OnPacketReceive(_worldSession, packet); return; - // not an opcode, client sends string "WORLD OF WARCRAFT CONNECTION - CLIENT TO SERVER" without opcode - // first 4 bytes become the opcode (2 dropped) - case MSG_VERIFY_CONNECTIVITY: - { - TC_LOG_DEBUG("network", "%s", opcodeName.c_str()); - sScriptMgr->OnPacketReceive(shared_from_this(), packet); - std::string str; - packet >> str; - if (str != "D OF WARCRAFT CONNECTION - CLIENT TO SERVER") - { - CloseSocket(); - break; - } - - HandleSendAuthSession(); - break; - } case CMSG_ENABLE_NAGLE: { TC_LOG_DEBUG("network", "%s", opcodeName.c_str()); - sScriptMgr->OnPacketReceive(shared_from_this(), packet); + sScriptMgr->OnPacketReceive(_worldSession, packet); if (_worldSession) _worldSession->HandleEnableNagleAlgorithm(); break; @@ -155,7 +143,8 @@ void WorldSocket::ReadDataHandler(boost::system::error_code error, size_t transf if (!_worldSession) { TC_LOG_ERROR("network.opcode", "ProcessIncoming: Client not authed opcode = %u", uint32(opcode)); - break; + CloseSocket(); + return; } // Our Idle timer will reset on any non PING opcodes. @@ -163,23 +152,38 @@ void WorldSocket::ReadDataHandler(boost::system::error_code error, size_t transf _worldSession->ResetTimeOutTime(); // Copy the packet to the heap before enqueuing - _worldSession->QueuePacket(new WorldPacket(packet)); + _worldSession->QueuePacket(new WorldPacket(std::move(packet))); break; } } - - AsyncReadHeader(); } else - CloseSocket(); + { + ClientPktHeader* header = reinterpret_cast<ClientPktHeader*>(GetDataBuffer()); + + std::string initializer(reinterpret_cast<char const*>(header) + sizeof(header->size)); + if (initializer != ClientConnectionInitialize) + { + CloseSocket(); + return; + } + + _initialized = true; + HandleSendAuthSession(); + } + + AsyncReadHeader(); } void WorldSocket::AsyncWrite(WorldPacket& packet) { + if (!IsOpen()) + return; + if (sPacketLog->CanLogPacket()) sPacketLog->LogPacket(packet, SERVER_TO_CLIENT, GetRemoteIpAddress(), GetRemotePort()); - if (_worldSession && packet.size() > 0x400) + if (_worldSession && packet.size() > 0x400 && !packet.IsCompressed()) packet.Compress(_worldSession->GetCompressionStream()); TC_LOG_TRACE("network.opcode", "S->C: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress().to_string()).c_str(), GetOpcodeNameForLogging(packet.GetOpcode()).c_str()); @@ -211,10 +215,12 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) BigNumber k; bool wardenActive = sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED); WorldPacket addonsData; + uint8 loginServerType; + uint32 realmIndex; - recvPacket.read_skip<uint32>(); - recvPacket.read_skip<uint32>(); - recvPacket.read_skip<uint8>(); + recvPacket.read_skip<uint32>(); // ServerId - Used for GRUNT only + recvPacket.read_skip<uint32>(); // Battlegroup + recvPacket >> loginServerType; recvPacket >> digest[10]; recvPacket >> digest[18]; recvPacket >> digest[12]; @@ -229,7 +235,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) recvPacket >> digest[3]; recvPacket >> clientBuild; recvPacket >> digest[8]; - recvPacket.read_skip<uint32>(); + recvPacket >> realmIndex; recvPacket.read_skip<uint8>(); recvPacket >> digest[17]; recvPacket >> digest[6]; @@ -238,7 +244,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) recvPacket >> digest[11]; recvPacket >> clientSeed; recvPacket >> digest[2]; - recvPacket.read_skip<uint32>(); + recvPacket.read_skip<uint32>(); // Region recvPacket >> digest[14]; recvPacket >> digest[13]; @@ -250,33 +256,15 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) recvPacket.read((uint8*)addonsData.contents(), addonSize); } - recvPacket.ReadBit(); + recvPacket.ReadBit(); // UseIPv6 uint32 accountNameLength = recvPacket.ReadBits(12); account = recvPacket.ReadString(accountNameLength); - if (sWorld->IsClosed()) - { - SendAuthResponseError(AUTH_REJECT); - TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: World closed, denying client (%s).", GetRemoteIpAddress().to_string().c_str()); - return; - } // Get the account information from the auth database - // 0 1 2 3 4 5 6 7 8 - // SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ? - PreparedStatement* stmt; - uint32 battlenetAccountId = 0; - uint8 battlenetAccountIndex = 0; - if (Battlenet::AccountMgr::GetAccountIdAndIndex(account, &battlenetAccountId, &battlenetAccountIndex)) - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_BNET); - stmt->setUInt32(0, battlenetAccountId); - stmt->setUInt8(1, battlenetAccountIndex); - } - else - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); - stmt->setString(0, account); - } + // 0 1 2 3 4 5 6 7 8 9 + // SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os, battlenet_account FROM account WHERE username = ? + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); + stmt->setString(0, account); PreparedQueryResult result = LoginDatabase.Query(stmt); @@ -286,6 +274,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // We can not log here, as we do not know the account. Thus, no accountId. SendAuthResponseError(AUTH_UNKNOWN_ACCOUNT); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); + DelayedCloseSocket(); return; } @@ -311,6 +300,57 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // id has to be fetched at this point, so that first actual account response that fails can be logged id = fields[0].GetUInt32(); + k.SetHexStr(fields[1].GetCString()); + + // even if auth credentials are bad, try using the session key we have - client cannot read auth response error without it + _authCrypt.Init(&k); + + // First reject the connection if packet contains invalid data or realm state doesn't allow logging in + if (sWorld->IsClosed()) + { + SendAuthResponseError(AUTH_REJECT); + TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: World closed, denying client (%s).", GetRemoteIpAddress().to_string().c_str()); + DelayedCloseSocket(); + return; + } + + if (realmIndex != realmID) + { + SendAuthResponseError(REALM_LIST_REALM_NOT_FOUND); + TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (bad realm)."); + DelayedCloseSocket(); + return; + } + + std::string os = fields[8].GetString(); + + // Must be done before WorldSession is created + if (wardenActive && os != "Win" && os != "OSX") + { + SendAuthResponseError(AUTH_REJECT); + TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Client %s attempted to log in using invalid client OS (%s).", address.c_str(), os.c_str()); + DelayedCloseSocket(); + return; + } + + // Check that Key and account name are the same on client and server + uint32 t = 0; + + sha.UpdateData(account); + sha.UpdateData((uint8*)&t, 4); + sha.UpdateData((uint8*)&clientSeed, 4); + sha.UpdateData((uint8*)&_authSeed, 4); + sha.UpdateBigNumbers(&k, NULL); + sha.Finalize(); + + if (memcmp(sha.GetDigest(), digest, 20)) + { + SendAuthResponseError(AUTH_FAILED); + TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", id, account.c_str(), address.c_str()); + DelayedCloseSocket(); + return; + } + ///- Re-check ip locking (same check as in auth). if (fields[3].GetUInt8() == 1) // if ip is locked { @@ -320,19 +360,18 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs. Original IP: %s, new IP: %s).", fields[2].GetCString(), address.c_str()); // We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well sScriptMgr->OnFailedAccountLogin(id); + DelayedCloseSocket(); return; } } - k.SetHexStr(fields[1].GetCString()); - int64 mutetime = fields[5].GetInt64(); //! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now. if (mutetime < 0) { mutetime = time(NULL) + llabs(mutetime); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME_LOGIN); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME_LOGIN); stmt->setInt64(0, mutetime); stmt->setUInt32(1, id); @@ -345,15 +384,10 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) locale = LOCALE_enUS; uint32 recruiter = fields[7].GetUInt32(); - std::string os = fields[8].GetString(); - // Must be done before WorldSession is created - if (wardenActive && os != "Win" && os != "OSX") - { - SendAuthResponseError(AUTH_REJECT); - TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Client %s attempted to log in using invalid client OS (%s).", address.c_str(), os.c_str()); - return; - } + uint32 battlenetAccountId = 0; + if (loginServerType == 1) + battlenetAccountId = fields[9].GetUInt32(); // Checks gmlevel per Realm stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_GMLEVEL_BY_REALMID); @@ -384,6 +418,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) SendAuthResponseError(AUTH_BANNED); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); sScriptMgr->OnFailedAccountLogin(id); + DelayedCloseSocket(); return; } @@ -395,23 +430,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) SendAuthResponseError(AUTH_UNAVAILABLE); TC_LOG_INFO("network", "WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); sScriptMgr->OnFailedAccountLogin(id); - return; - } - - // Check that Key and account name are the same on client and server - uint32 t = 0; - - sha.UpdateData(account); - sha.UpdateData((uint8*)&t, 4); - sha.UpdateData((uint8*)&clientSeed, 4); - sha.UpdateData((uint8*)&_authSeed, 4); - sha.UpdateBigNumbers(&k, NULL); - sha.Finalize(); - - if (memcmp(sha.GetDigest(), digest, 20)) - { - SendAuthResponseError(AUTH_FAILED); - TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", id, account.c_str(), address.c_str()); + DelayedCloseSocket(); return; } @@ -438,19 +457,15 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) LoginDatabase.Execute(stmt); - // NOTE ATM the socket is single-threaded, have this in mind ... - _worldSession = new WorldSession(id, battlenetAccountId, shared_from_this(), AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter); - - _authCrypt.Init(&k); + // At this point, we can safely hook a successful login + sScriptMgr->OnAccountLogin(id); + _worldSession = new WorldSession(id, battlenetAccountId, shared_from_this(), AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter); _worldSession->LoadGlobalAccountData(); _worldSession->LoadTutorialsData(); _worldSession->ReadAddonsInfo(addonsData); _worldSession->LoadPermissions(); - // At this point, we can safely hook a successful login - sScriptMgr->OnAccountLogin(id); - // Initialize Warden system only if it is enabled by config if (wardenActive) _worldSession->InitWarden(&k, os); @@ -528,3 +543,10 @@ void WorldSocket::HandlePing(WorldPacket& recvPacket) packet << ping; return AsyncWrite(packet); } + +void WorldSocket::CloseSocket() +{ + sScriptMgr->OnSocketClose(shared_from_this()); + + Socket::CloseSocket(); +} diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 2cf6159cb38..9e5f785d939 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -48,6 +48,8 @@ struct ClientPktHeader { uint16 size; uint32 cmd; + + bool IsValid() const { return size >= 4 && size < 10240 && cmd < NUM_OPCODE_HANDLERS; } }; #pragma pack(pop) @@ -58,11 +60,18 @@ struct WorldPacketBuffer typedef boost::asio::const_buffer const* const_iterator; - WorldPacketBuffer(ServerPktHeader header, WorldPacket const& packet) : _header(header), _packet(packet) + WorldPacketBuffer(ServerPktHeader header, WorldPacket const& packet) : _header(header), _packet(packet), _bufferCount(0) { - _buffers[0] = boost::asio::const_buffer(_header.header, _header.getHeaderLength()); + _buffers[_bufferCount++] = boost::asio::const_buffer(_header.header, _header.getHeaderLength()); if (!_packet.empty()) - _buffers[1] = boost::asio::const_buffer(_packet.contents(), _packet.size()); + _buffers[_bufferCount++] = boost::asio::const_buffer(_packet.contents(), _packet.size()); + } + + WorldPacketBuffer(std::string const& str) : _header(str.length() + 1 /*null terminator*/, 0), _packet(), _bufferCount(0) + { + _buffers[_bufferCount++] = boost::asio::const_buffer(_header.header, _header.getHeaderLength() - 2 /*sizeof(opcode)*/); + if (!str.empty()) + _buffers[_bufferCount++] = boost::asio::const_buffer(str.c_str(), _header.size); } const_iterator begin() const @@ -72,13 +81,14 @@ struct WorldPacketBuffer const_iterator end() const { - return _buffers + (_packet.empty() ? 1 : 2); + return _buffers + _bufferCount; } private: boost::asio::const_buffer _buffers[2]; ServerPktHeader _header; WorldPacket _packet; + uint32 _bufferCount; }; namespace boost @@ -96,6 +106,10 @@ class WorldSocket : public Socket<WorldSocket, WorldPacketBuffer> { typedef Socket<WorldSocket, WorldPacketBuffer> Base; + static std::string const ServerConnectionInitialize; + + static std::string const ClientConnectionInitialize; + public: WorldSocket(tcp::socket&& socket); @@ -104,12 +118,14 @@ public: void Start() override; + void CloseSocket() override; + using Base::AsyncWrite; void AsyncWrite(WorldPacket& packet); protected: - void ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) override; - void ReadDataHandler(boost::system::error_code error, size_t transferedBytes) override; + void ReadHeaderHandler() override; + void ReadDataHandler() override; private: void HandleSendAuthSession(); @@ -125,6 +141,7 @@ private: uint32 _OverSpeedPings; WorldSession* _worldSession; + bool _initialized; }; #endif diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index da12ed3da77..e43363e9cf6 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5415,7 +5415,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const int32 mod = (rage < 100) ? rage : 100; int32 points = target->CalculateSpellDamage(target, GetSpellInfo(), 1); int32 regen = target->GetMaxHealth() * (mod * points / 10) / 1000; - target->CastCustomSpell(target, 22845, ®en, 0, 0, true, 0, this); + target->CastCustomSpell(target, 22845, ®en, nullptr, nullptr, true, nullptr, this); target->SetPower(POWER_RAGE, rage-mod); break; } @@ -5436,12 +5436,12 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const // Feeding Frenzy Rank 1 case 53511: if (target->GetVictim() && target->EnsureVictim()->HealthBelowPct(35)) - target->CastSpell(target, 60096, true, 0, this); + target->CastSpell(target, 60096, true, nullptr, this); return; // Feeding Frenzy Rank 2 case 53512: if (target->GetVictim() && target->EnsureVictim()->HealthBelowPct(35)) - target->CastSpell(target, 60097, true, 0, this); + target->CastSpell(target, 60097, true, nullptr, this); return; default: break; @@ -5774,7 +5774,7 @@ void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit* if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target) { int32 basepoints = GetAmount(); - triggerCaster->CastCustomSpell(target, triggerSpellId, &basepoints, &basepoints, &basepoints, true, 0, this); + triggerCaster->CastCustomSpell(target, triggerSpellId, &basepoints, &basepoints, &basepoints, true, nullptr, this); TC_LOG_DEBUG("spells", "AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id); } } diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index e38dc8fdf4a..4d8c1e033ed 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1300,7 +1300,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b { // instantly heal m_amount% of the absorb-value int32 heal = glyph->GetAmount() * GetEffect(0)->GetAmount()/100; - caster->CastCustomSpell(GetUnitOwner(), 56160, &heal, NULL, NULL, true, 0, GetEffect(0)); + caster->CastCustomSpell(GetUnitOwner(), 56160, &heal, nullptr, nullptr, true, nullptr, GetEffect(0)); } } break; diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 19c77c2ac7e..e578c0ffc3a 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -274,12 +274,12 @@ class UnitAura : public Aura protected: explicit UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, uint64 casterGUID); public: - void _ApplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp); - void _UnapplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp); + void _ApplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) override; + void _UnapplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) override; - void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); + void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override; - void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster); + void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) override; // Allow Apply Aura Handler to modify and access m_AuraDRGroup void SetDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; } @@ -295,8 +295,8 @@ class DynObjAura : public Aura protected: explicit DynObjAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, uint64 casterGUID); public: - void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); + void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override; - void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster); + void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) override; }; #endif diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index bf518859b49..4d8ac65e55d 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -602,7 +602,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before. m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before. m_timer = 0; // will set to castime in prepare - + m_channeledDuration = 0; // will be setup in Spell::handle_immediate m_immediateHandled = false; m_channelTargetEffectMask = 0; @@ -821,13 +821,13 @@ void Spell::SelectSpellTargets() { float speed = m_targets.GetSpeedXY(); if (speed > 0.0f) - m_delayMoment = (uint64)floor(m_targets.GetDist2d() / speed * 1000.0f); + m_delayMoment = uint64(std::floor(m_targets.GetDist2d() / speed * 1000.0f)); } else if (m_spellInfo->Speed > 0.0f) { float dist = m_caster->GetDistance(*m_targets.GetDstPos()); if (!(m_spellInfo->AttributesEx9 & SPELL_ATTR9_SPECIAL_DELAY_CALCULATION)) - m_delayMoment = uint64(floor(dist / m_spellInfo->Speed * 1000.0f)); + m_delayMoment = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f)); else m_delayMoment = uint64(m_spellInfo->Speed * 1000.0f); } @@ -1104,7 +1104,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge SpellTargetObjectTypes objectType = targetType.GetObjectType(); SpellTargetCheckTypes selectionType = targetType.GetCheckType(); ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions; - float coneAngle = M_PI/2; + float coneAngle = float(M_PI) / 2; float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod; if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList)) @@ -1200,7 +1200,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) { if (Unit* unitTarget = (*itr)->ToUnit()) - AddUnitTarget(unitTarget, effMask, false); + AddUnitTarget(unitTarget, effMask, false, true, center); else if (GameObject* gObjTarget = (*itr)->ToGameObject()) AddGOTarget(gObjTarget, effMask); } @@ -1465,7 +1465,7 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg float tangent(float x) { - x = tan(x); + x = std::tan(x); //if (x < std::numeric_limits<float>::max() && x > -std::numeric_limits<float>::max()) return x; //if (x >= std::numeric_limits<float>::max()) return std::numeric_limits<float>::max(); //if (x <= -std::numeric_limits<float>::max()) return -std::numeric_limits<float>::max(); @@ -1570,7 +1570,7 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex) float sqrt1 = b * b + 4 * a * height; if (sqrt1 > 0) { - sqrt1 = sqrt(sqrt1); + sqrt1 = std::sqrt(sqrt1); dist = (sqrt1 - b) / (2 * a); CHECK_DIST; } @@ -1579,7 +1579,7 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex) float sqrt2 = b * b + 4 * a * height; if (sqrt2 > 0) { - sqrt2 = sqrt(sqrt2); + sqrt2 = std::sqrt(sqrt2); dist = (sqrt2 - b) / (2 * a); CHECK_DIST; @@ -1608,7 +1608,7 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex) DEBUG_TRAJ(TC_LOG_ERROR("spells", "Initial %f %f %f %f %f", x, y, z, distSq, sizeSq);) if (distSq > sizeSq) { - float factor = 1 - sqrt(sizeSq / distSq); + float factor = 1 - std::sqrt(sizeSq / distSq); x += factor * ((*itr)->GetPositionX() - x); y += factor * ((*itr)->GetPositionY() - y); z += factor * ((*itr)->GetPositionZ() - z); @@ -1997,10 +1997,10 @@ void Spell::CleanupTargetList() m_delayMoment = 0; } -void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= true*/, bool implicit /*= true*/) +void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= true*/, bool implicit /*= true*/, Position const* losPosition /*= nullptr*/) { for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) - if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex)) + if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex, losPosition)) effectMask &= ~(1 << effIndex); // no effects left @@ -2075,7 +2075,7 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= dist = 5.0f; if (!(m_spellInfo->AttributesEx9 & SPELL_ATTR9_SPECIAL_DELAY_CALCULATION)) - targetInfo.timeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f)); + targetInfo.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f)); else targetInfo.timeDelay = uint64(m_spellInfo->Speed * 1000.0f); @@ -2707,7 +2707,7 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask) if (*i < 0) unit->RemoveAurasDueToSpell(-(*i)); else - unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID()); + unit->CastSpell(unit, *i, true, nullptr, nullptr, m_caster->GetGUID()); } } } @@ -3253,6 +3253,7 @@ void Spell::handle_immediate() m_spellState = SPELL_STATE_CASTING; m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags); + m_channeledDuration = duration; SendChannelStart(duration); } else if (duration == -1) @@ -3432,7 +3433,14 @@ void Spell::SendSpellCooldown() { Player* _player = m_caster->ToPlayer(); if (!_player) + { + // Handle pet cooldowns here if needed instead of in PetAI to avoid hidden cooldown restarts + Creature* _creature = m_caster->ToCreature(); + if (_creature && _creature->IsPet()) + _creature->AddCreatureSpellCooldown(m_spellInfo->Id); + return; + } // mana/health/etc potions, disabled by client (until combat out as declarate) if (m_CastItem && (m_CastItem->IsPotion() || m_spellInfo->IsCooldownStartedOnEvent())) @@ -3979,7 +3987,7 @@ void Spell::WriteSpellGoTargets(WorldPacket* data) uint32 hit = 0; size_t hitPos = data->wpos(); *data << (uint8)0; // placeholder - for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit <= 255; ++ihit) + for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit) { if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits { @@ -3989,7 +3997,7 @@ void Spell::WriteSpellGoTargets(WorldPacket* data) } } - for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit <= 255; ++ighit) + for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit) { *data << uint64(ighit->targetGUID); // Always hits ++hit; @@ -3998,7 +4006,7 @@ void Spell::WriteSpellGoTargets(WorldPacket* data) uint32 miss = 0; size_t missPos = data->wpos(); *data << (uint8)0; // placeholder - for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss <= 255; ++ihit) + for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit) { if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss { @@ -4863,7 +4871,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (IsTriggered() && m_triggeredByAuraSpell) if (DynamicObject* dynObj = m_caster->GetDynObject(m_triggeredByAuraSpell->Id)) losTarget = dynObj; - + if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !target->IsWithinLOSInMap(losTarget)) return SPELL_FAILED_LINE_OF_SIGHT; } @@ -5144,7 +5152,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_TARGET_UNSKINNABLE; Creature* creature = m_targets.GetUnitTarget()->ToCreature(); - if (creature->GetCreatureType() != CREATURE_TYPE_CRITTER && !creature->loot.isLooted()) + if (!creature->IsCritter() && !creature->loot.isLooted()) return SPELL_FAILED_TARGET_NOT_LOOTED; uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill(); @@ -6354,7 +6362,10 @@ void Spell::DelayedChannel() return; //check pushback reduce - int32 delaytime = CalculatePct(m_spellInfo->GetDuration(), 25); // channeling delay is normally 25% of its time per hit + // should be affected by modifiers, not take the dbc duration. + int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration()); + + int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit int32 delayReduce = 100; // must be initialized to 100 for percent modifiers m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this); delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100; @@ -6449,7 +6460,7 @@ CurrentSpellTypes Spell::GetCurrentContainer() const return(CURRENT_GENERIC_SPELL); } -bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const +bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* losPosition) const { switch (m_spellInfo->Effects[eff].ApplyAuraName) { @@ -6499,15 +6510,22 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const // all ok by some way or another, skip normal check break; default: // normal case - // Get GO cast coordinates if original caster -> GO - WorldObject* caster = NULL; - if (IS_GAMEOBJECT_GUID(m_originalCasterGUID)) - caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID); - if (!caster) - caster = m_caster; - if (target != m_caster && !target->IsWithinLOSInMap(caster)) - return false; + { + if (losPosition) + return target->IsWithinLOS(losPosition->GetPositionX(), losPosition->GetPositionY(), losPosition->GetPositionZ()); + else + { + // Get GO cast coordinates if original caster -> GO + WorldObject* caster = NULL; + if (IS_GAMEOBJECT_GUID(m_originalCasterGUID)) + caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID); + if (!caster) + caster = m_caster; + if (target != m_caster && !target->IsWithinLOSInMap(caster)) + return false; + } break; + } } return true; diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 5b976ced426..5d854659f4e 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -422,7 +422,7 @@ class Spell void DoCreateItem(uint32 i, uint32 itemtype); void WriteSpellGoTargets(WorldPacket* data); - bool CheckEffectTarget(Unit const* target, uint32 eff) const; + bool CheckEffectTarget(Unit const* target, uint32 eff, Position const* losPosition) const; bool CanAutoCast(Unit* target); void CheckSrc() { if (!m_targets.HasSrc()) m_targets.SetSrc(*m_caster); } void CheckDst() { if (!m_targets.HasDst()) m_targets.SetDst(*m_caster); } @@ -519,6 +519,7 @@ class Spell WeaponAttackType m_attackType; // For weapon based attack int32 m_powerCost; // Calculated spell cost initialized only in Spell::prepare int32 m_casttime; // Calculated spell cast time initialized only in Spell::prepare + int32 m_channeledDuration; // Calculated channeled spell duration in order to calculate correct pushback. bool m_canReflect; // can reflect this spell? bool m_autoRepeat; uint8 m_runesState; @@ -612,7 +613,7 @@ class Spell SpellDestination m_destTargets[MAX_SPELL_EFFECTS]; - void AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid = true, bool implicit = true); + void AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid = true, bool implicit = true, Position const* losPosition = nullptr); void AddGOTarget(GameObject* target, uint32 effectMask); void AddItemTarget(Item* item, uint32 effectMask); void AddDestTarget(SpellDestination const& dest, uint32 effIndex); @@ -757,9 +758,9 @@ class SpellEvent : public BasicEvent SpellEvent(Spell* spell); virtual ~SpellEvent(); - virtual bool Execute(uint64 e_time, uint32 p_time); - virtual void Abort(uint64 e_time); - virtual bool IsDeletable() const; + virtual bool Execute(uint64 e_time, uint32 p_time) override; + virtual void Abort(uint64 e_time) override; + virtual bool IsDeletable() const override; protected: Spell* m_Spell; }; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 7623550d736..e0055cca1f1 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -431,7 +431,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster); if (roll_chance_i(chance)) // Mind Trauma - m_caster->CastSpell(unitTarget, 48301, true, 0); + m_caster->CastSpell(unitTarget, 48301, true, nullptr); break; } } @@ -2065,6 +2065,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) case 1562: case 833: case 1161: + case 713: numSummons = (damage > 0) ? damage : 1; break; default: diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 43d8a577fa3..756644dbd1b 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -187,7 +187,7 @@ class SpellScript : public _SpellScript public: EffectHandler(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName); std::string ToString(); - bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex); + bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) override; void Call(SpellScript* spellScript, SpellEffIndex effIndex); private: SpellEffectFnType pEffectHandlerScript; @@ -206,7 +206,7 @@ class SpellScript : public _SpellScript { public: TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest); - bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex); + bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) override; std::string ToString(); uint16 GetTarget() const { return targetType; } protected: @@ -253,7 +253,7 @@ class SpellScript : public _SpellScript #define PrepareSpellScript(CLASSNAME) SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) public: - bool _Validate(SpellInfo const* entry); + bool _Validate(SpellInfo const* entry) override; bool _Load(Spell* spell); void _InitHit(); bool _IsEffectPrevented(SpellEffIndex effIndex) { return (m_hitPreventEffectMask & (1 << effIndex)) != 0; } @@ -509,7 +509,7 @@ class AuraScript : public _SpellScript public: EffectBase(uint8 _effIndex, uint16 _effName); std::string ToString(); - bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex); + bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex) override; }; class EffectPeriodicHandler : public EffectBase { @@ -630,7 +630,7 @@ class AuraScript : public _SpellScript public: AuraScript() : _SpellScript(), m_aura(NULL), m_auraApplication(NULL), m_defaultActionPrevented(false) { } - bool _Validate(SpellInfo const* entry); + bool _Validate(SpellInfo const* entry) override; bool _Load(Aura* aura); void _PrepareScriptCall(AuraScriptHookType hookType, AuraApplication const* aurApp = NULL); void _FinishScriptCall(); diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 3fbbd34777b..9e05e4874bc 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -180,7 +180,7 @@ void CreatureTextMgr::LoadCreatureTextLocales() { Field* fields = result->Fetch(); CreatureTextLocale& loc = mLocaleTextMap[CreatureTextId(fields[0].GetUInt32(), uint32(fields[1].GetUInt8()), uint32(fields[2].GetUInt8()))]; - for (uint8 i = 1; i < TOTAL_LOCALES; ++i) + for (uint8 i = TOTAL_LOCALES - 1; i > 0; --i) { LocaleConstant locale = LocaleConstant(i); ObjectMgr::AddLocaleString(fields[3 + i - 1].GetString(), locale, loc.Text); diff --git a/src/server/game/Warden/WardenMac.h b/src/server/game/Warden/WardenMac.h index 3ea509c75ef..e9ccfe55438 100644 --- a/src/server/game/Warden/WardenMac.h +++ b/src/server/game/Warden/WardenMac.h @@ -34,13 +34,13 @@ class WardenMac : public Warden WardenMac(); ~WardenMac(); - void Init(WorldSession* session, BigNumber* k); - ClientWardenModule* GetModuleForClient(); - void InitializeModule(); - void RequestHash(); - void HandleHashResult(ByteBuffer& buff); - void RequestData(); - void HandleData(ByteBuffer& buff); + void Init(WorldSession* session, BigNumber* k) override; + ClientWardenModule* GetModuleForClient() override; + void InitializeModule() override; + void RequestHash() override; + void HandleHashResult(ByteBuffer& buff) override; + void RequestData() override; + void HandleData(ByteBuffer& buff) override; }; #endif diff --git a/src/server/game/Warden/WardenWin.h b/src/server/game/Warden/WardenWin.h index 47487ba65a2..d760d9ee981 100644 --- a/src/server/game/Warden/WardenWin.h +++ b/src/server/game/Warden/WardenWin.h @@ -76,13 +76,13 @@ class WardenWin : public Warden WardenWin(); ~WardenWin(); - void Init(WorldSession* session, BigNumber* K); - ClientWardenModule* GetModuleForClient(); - void InitializeModule(); - void RequestHash(); - void HandleHashResult(ByteBuffer &buff); - void RequestData(); - void HandleData(ByteBuffer &buff); + void Init(WorldSession* session, BigNumber* K) override; + ClientWardenModule* GetModuleForClient() override; + void InitializeModule() override; + void RequestHash() override; + void HandleHashResult(ByteBuffer &buff) override; + void RequestData() override; + void HandleData(ByteBuffer &buff) override; private: uint32 _serverTicks; diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index f18809b107a..8bf045c5adc 100644 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -51,7 +51,7 @@ namespace Weather* FindWeather(uint32 id) { WeatherMap::const_iterator itr = m_weathers.find(id); - return (itr != m_weathers.end()) ? itr->second.get() : 0; + return (itr != m_weathers.end()) ? itr->second.get() : nullptr; } /// Remove a Weather object for the given zoneid diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 3af21032cd5..f66c693098b 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -20,69 +20,49 @@ \ingroup world */ -#include <atomic> -#include "Common.h" -#include "Memory.h" -#include "DatabaseEnv.h" -#include "Config.h" -#include "SystemConfig.h" -#include "Log.h" -#include "Opcodes.h" -#include "WorldSession.h" -#include "WorldPacket.h" -#include "Player.h" -#include "Vehicle.h" -#include "SkillExtraItems.h" -#include "SkillDiscovery.h" #include "World.h" -#include "AccountMgr.h" #include "AchievementMgr.h" -#include "AuctionHouseMgr.h" -#include "ObjectMgr.h" #include "ArenaTeamMgr.h" -#include "GuildMgr.h" -#include "GuildFinderMgr.h" -#include "TicketMgr.h" -#include "SpellMgr.h" -#include "GroupMgr.h" +#include "AuctionHouseMgr.h" +#include "BattlefieldMgr.h" +#include "BattlegroundMgr.h" +#include "CalendarMgr.h" +#include "Channel.h" +#include "CharacterDatabaseCleaner.h" #include "Chat.h" -#include "DBCStores.h" -#include "DB2Stores.h" -#include "LootMgr.h" -#include "ItemEnchantmentMgr.h" -#include "MapManager.h" +#include "Config.h" #include "CreatureAIRegistry.h" -#include "BattlegroundMgr.h" -#include "OutdoorPvPMgr.h" -#include "TemporarySummon.h" -#include "WaypointMovementGenerator.h" -#include "VMapFactory.h" -#include "MMapFactory.h" +#include "CreatureGroups.h" +#include "CreatureTextMgr.h" +#include "DatabaseEnv.h" +#include "DisableMgr.h" #include "GameEventMgr.h" -#include "PoolMgr.h" #include "GridNotifiersImpl.h" -#include "CellImpl.h" +#include "GroupMgr.h" +#include "GuildFinderMgr.h" #include "InstanceSaveMgr.h" -#include "Util.h" #include "Language.h" -#include "CreatureGroups.h" -#include "Transport.h" -#include "ScriptMgr.h" -#include "AddonMgr.h" #include "LFGMgr.h" -#include "ConditionMgr.h" -#include "DisableMgr.h" -#include "CharacterDatabaseCleaner.h" +#include "MapManager.h" +#include "Memory.h" +#include "MMapFactory.h" +#include "ObjectMgr.h" +#include "OutdoorPvPMgr.h" +#include "Player.h" +#include "PoolMgr.h" #include "ScriptMgr.h" -#include "WeatherMgr.h" -#include "CreatureTextMgr.h" +#include "SkillDiscovery.h" +#include "SkillExtraItems.h" #include "SmartAI.h" -#include "Channel.h" -#include "WardenCheckMgr.h" -#include "Warden.h" -#include "CalendarMgr.h" -#include "BattlefieldMgr.h" +#include "SystemConfig.h" +#include "TicketMgr.h" #include "TransportMgr.h" +#include "Unit.h" +#include "VMapFactory.h" +#include "WardenCheckMgr.h" +#include "WaypointMovementGenerator.h" +#include "WeatherMgr.h" +#include "WorldSession.h" std::atomic<bool> World::m_stopEvent(false); @@ -588,6 +568,18 @@ void World::LoadConfigSettings(bool reload) TC_LOG_ERROR("server.loading", "DurabilityLossChance.Block (%f) must be >=0. Using 0.0 instead.", rate_values[RATE_DURABILITY_LOSS_BLOCK]); rate_values[RATE_DURABILITY_LOSS_BLOCK] = 0.0f; } + rate_values[RATE_MONEY_QUEST] = sConfigMgr->GetFloatDefault("Rate.Quest.Money.Reward", 1.0f); + if (rate_values[RATE_MONEY_QUEST] < 0.0f) + { + TC_LOG_ERROR("server.loading", "Rate.Quest.Money.Reward (%f) must be >=0. Using 0 instead.", rate_values[RATE_MONEY_QUEST]); + rate_values[RATE_MONEY_QUEST] = 0.0f; + } + rate_values[RATE_MONEY_MAX_LEVEL_QUEST] = sConfigMgr->GetFloatDefault("Rate.Quest.Money.Max.Level.Reward", 1.0f); + if (rate_values[RATE_MONEY_MAX_LEVEL_QUEST] < 0.0f) + { + TC_LOG_ERROR("server.loading", "Rate.Quest.Money.Max.Level.Reward (%f) must be >=0. Using 0 instead.", rate_values[RATE_MONEY_MAX_LEVEL_QUEST]); + rate_values[RATE_MONEY_MAX_LEVEL_QUEST] = 0.0f; + } ///- Read other configuration items from the config file m_bool_configs[CONFIG_DURABILITY_LOSS_IN_PVP] = sConfigMgr->GetBoolDefault("DurabilityLoss.InPvP", false); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 00c897a6f00..51a5f726051 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -416,6 +416,8 @@ enum Rates RATE_DURABILITY_LOSS_ABSORB, RATE_DURABILITY_LOSS_BLOCK, RATE_MOVESPEED, + RATE_MONEY_QUEST, + RATE_MONEY_MAX_LEVEL_QUEST, MAX_RATES }; @@ -642,11 +644,11 @@ class World void SendWorldText(int32 string_id, ...); void SendGlobalText(const char* text, WorldSession* self); void SendGMText(int32 string_id, ...); - void SendGlobalMessage(WorldPacket* packet, WorldSession* self = 0, uint32 team = 0); - void SendGlobalGMMessage(WorldPacket* packet, WorldSession* self = 0, uint32 team = 0); - bool SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self = 0, uint32 team = 0); - void SendZoneText(uint32 zone, const char *text, WorldSession* self = 0, uint32 team = 0); void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = NULL); + void SendGlobalMessage(WorldPacket* packet, WorldSession* self = nullptr, uint32 team = 0); + void SendGlobalGMMessage(WorldPacket* packet, WorldSession* self = nullptr, uint32 team = 0); + bool SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self = nullptr, uint32 team = 0); + void SendZoneText(uint32 zone, const char *text, WorldSession* self = nullptr, uint32 team = 0); /// Are we in the middle of a shutdown? bool IsShuttingDown() const { return m_ShutdownTimer > 0; } diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp index 2f74132fe21..121da6489a3 100644 --- a/src/server/scripts/Commands/cs_ban.cpp +++ b/src/server/scripts/Commands/cs_ban.cpp @@ -109,21 +109,23 @@ public: return false; } - switch (sWorld->BanCharacter(name, durationStr, reasonStr, handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "")) + std::string author = handler->GetSession() ? handler->GetSession()->GetPlayerName() : "Server"; + + switch (sWorld->BanCharacter(name, durationStr, reasonStr, author)) { case BAN_SUCCESS: { if (atoi(durationStr) > 0) { if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) - sWorld->SendWorldText(LANG_BAN_CHARACTER_YOUBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), name.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); + sWorld->SendWorldText(LANG_BAN_CHARACTER_YOUBANNEDMESSAGE_WORLD, author.c_str(), name.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); else handler->PSendSysMessage(LANG_BAN_YOUBANNED, name.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); } else { if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) - sWorld->SendWorldText(LANG_BAN_CHARACTER_YOUPERMBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), name.c_str(), reasonStr); + sWorld->SendWorldText(LANG_BAN_CHARACTER_YOUPERMBANNEDMESSAGE_WORLD, author.c_str(), name.c_str(), reasonStr); else handler->PSendSysMessage(LANG_BAN_YOUPERMBANNED, name.c_str(), reasonStr); } @@ -195,20 +197,22 @@ public: break; } - switch (sWorld->BanAccount(mode, nameOrIP, durationStr, reasonStr, handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "")) + std::string author = handler->GetSession() ? handler->GetSession()->GetPlayerName() : "Server"; + + switch (sWorld->BanAccount(mode, nameOrIP, durationStr, reasonStr, author)) { case BAN_SUCCESS: if (atoi(durationStr) > 0) { if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) - sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); + sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUBANNEDMESSAGE_WORLD, author.c_str(), nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); else handler->PSendSysMessage(LANG_BAN_YOUBANNED, nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr); } else { if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD)) - sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUPERMBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameOrIP.c_str(), reasonStr); + sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUPERMBANNEDMESSAGE_WORLD, author.c_str(), nameOrIP.c_str(), reasonStr); else handler->PSendSysMessage(LANG_BAN_YOUPERMBANNED, nameOrIP.c_str(), reasonStr); } diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 352142baea4..d7b7adc05ba 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -37,7 +37,7 @@ class gobject_commandscript : public CommandScript public: gobject_commandscript() : CommandScript("gobject_commandscript") { } - ChatCommand* GetCommands() const + ChatCommand* GetCommands() const override { static ChatCommand gobjectAddCommandTable[] = { diff --git a/src/server/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp index 928e110e9a1..dfc681a1d87 100644 --- a/src/server/scripts/Commands/cs_guild.cpp +++ b/src/server/scripts/Commands/cs_guild.cpp @@ -35,7 +35,7 @@ class guild_commandscript : public CommandScript public: guild_commandscript() : CommandScript("guild_commandscript") { } - ChatCommand* GetCommands() const + ChatCommand* GetCommands() const override { static ChatCommand guildCommandTable[] = { diff --git a/src/server/scripts/Commands/cs_message.cpp b/src/server/scripts/Commands/cs_message.cpp index dd1366ac09c..f2067e6c70b 100644 --- a/src/server/scripts/Commands/cs_message.cpp +++ b/src/server/scripts/Commands/cs_message.cpp @@ -34,7 +34,7 @@ class message_commandscript : public CommandScript public: message_commandscript() : CommandScript("message_commandscript") { } - ChatCommand* GetCommands() const + ChatCommand* GetCommands() const override { static ChatCommand channelSetCommandTable[] = { diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index b476a2e0a13..2afdff94a0b 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1460,7 +1460,6 @@ public: std::string raceStr, classStr = "None"; uint8 gender = 0; int8 locale = handler->GetSessionDbcLocale(); - std::string genderStr = handler->GetTrinityString(LANG_ERROR); uint32 totalPlayerTime = 0; uint8 level = 0; std::string alive = handler->GetTrinityString(LANG_ERROR); @@ -1611,16 +1610,7 @@ public: banReason = fields[3].GetString(); } - // Can be used to query data from World database - stmt2 = WorldDatabase.GetPreparedStatement(WORLD_SEL_REQ_XP); - stmt2->setUInt8(0, level); - PreparedQueryResult result3 = WorldDatabase.Query(stmt2); - if (result3) - { - Field* fields = result3->Fetch(); - xptotal = fields[0].GetUInt32(); - } // Can be used to query data from Characters database stmt2 = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_XP); @@ -1632,6 +1622,7 @@ public: Field* fields = result4->Fetch(); xp = fields[0].GetUInt32(); // Used for "current xp" output and "%u XP Left" calculation uint32 gguid = fields[1].GetUInt32(); // We check if have a guild for the person, so we might not require to query it at all + xptotal = sObjectMgr->GetXPForLevel(level); if (gguid != 0) { @@ -1768,10 +1759,10 @@ public: Player* player = handler->GetSession()->GetPlayer(); // accept only explicitly selected target (not implicitly self targeting case) - Unit* target = handler->getSelectedUnit(); - if (player->GetTarget() && target) + Creature* target = player->GetTarget() ? handler->getSelectedCreature() : nullptr; + if (target) { - if (target->GetTypeId() != TYPEID_UNIT || target->IsPet()) + if (target->IsPet()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); @@ -1779,19 +1770,13 @@ public: } if (target->isDead()) - target->ToCreature()->Respawn(); + target->Respawn(); return true; } - CellCoord p(Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY())); - Cell cell(p); - cell.SetNoCreate(); - Trinity::RespawnDo u_do; Trinity::WorldObjectWorker<Trinity::RespawnDo> worker(player, u_do); - - TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::RespawnDo>, GridTypeMapContainer > obj_worker(worker); - cell.Visit(p, obj_worker, *player->GetMap(), *player, player->GetGridActivationRange()); + player->VisitNearbyGridObject(player->GetGridActivationRange(), worker); return true; } @@ -1845,14 +1830,9 @@ public: std::string nameLink = handler->playerLink(targetName); if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD)) - { - sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); - } - else - { - ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); - } + sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, muteBy.c_str(), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + + ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteBy.c_str(), muteReasonStr.c_str()); } else { @@ -1867,10 +1847,11 @@ public: LoginDatabase.Execute(stmt); std::string nameLink = handler->playerLink(targetName); - if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD) && !target) - sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, handler->GetSession()->GetPlayerName().c_str(), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); - else - handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD) && !target) + sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, muteBy.c_str(), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + else + handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + return true; } diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 84716ad9590..9ee0411c302 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -1405,7 +1405,7 @@ public: // place pet before player float x, y, z; player->GetClosePoint (x, y, z, creatureTarget->GetObjectSize(), CONTACT_DISTANCE); - pet->Relocate(x, y, z, M_PI-player->GetOrientation()); + pet->Relocate(x, y, z, float(M_PI) - player->GetOrientation()); // set pet to defensive mode by default (some classes can't control controlled pets in fact). pet->SetReactState(REACT_DEFENSIVE); @@ -1460,8 +1460,8 @@ public: FormationInfo* group_member; group_member = new FormationInfo; - group_member->follow_angle = (creature->GetAngle(chr) - chr->GetOrientation()) * 180 / M_PI; - group_member->follow_dist = sqrtf(pow(chr->GetPositionX() - creature->GetPositionX(), int(2))+pow(chr->GetPositionY() - creature->GetPositionY(), int(2))); + group_member->follow_angle = (creature->GetAngle(chr) - chr->GetOrientation()) * 180 / float(M_PI); + group_member->follow_dist = std::sqrt(std::pow(chr->GetPositionX() - creature->GetPositionX(), 2.f) + std::pow(chr->GetPositionY() - creature->GetPositionY(), 2.f)); group_member->leaderGUID = leaderGUID; group_member->groupAI = 0; diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index b9bf0f7d9f6..4b78ab880d4 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -47,7 +47,7 @@ class reload_commandscript : public CommandScript public: reload_commandscript() : CommandScript("reload_commandscript") { } - ChatCommand* GetCommands() const + ChatCommand* GetCommands() const override { static ChatCommand reloadAllCommandTable[] = { @@ -438,7 +438,7 @@ public: continue; } - CreatureTemplate* cInfo = const_cast<CreatureTemplate*>(sObjectMgr->GetCreatureTemplate(entry)); + CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry); if (!cInfo) { handler->PSendSysMessage(LANG_COMMAND_CREATURESTORAGE_NOTFOUND, entry); @@ -448,86 +448,7 @@ public: TC_LOG_INFO("misc", "Reloading creature template entry %u", entry); Field* fields = result->Fetch(); - - for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i) - cInfo->DifficultyEntry[i] = fields[0 + i].GetUInt32(); - - for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i) - cInfo->KillCredit[i] = fields[3 + i].GetUInt32(); - - cInfo->Modelid1 = fields[5].GetUInt32(); - cInfo->Modelid2 = fields[6].GetUInt32(); - cInfo->Modelid3 = fields[7].GetUInt32(); - cInfo->Modelid4 = fields[8].GetUInt32(); - cInfo->Name = fields[9].GetString(); - cInfo->SubName = fields[10].GetString(); - cInfo->FemaleName = fields[11].GetString(); - cInfo->IconName = fields[12].GetString(); - cInfo->GossipMenuId = fields[13].GetUInt32(); - cInfo->minlevel = fields[14].GetUInt8(); - cInfo->maxlevel = fields[15].GetUInt8(); - cInfo->expansion = fields[16].GetUInt16(); - cInfo->expansionUnknown = fields[17].GetUInt16(); - cInfo->faction = fields[18].GetUInt16(); - cInfo->npcflag = fields[19].GetUInt32(); - cInfo->speed_walk = fields[20].GetFloat(); - cInfo->speed_run = fields[21].GetFloat(); - cInfo->scale = fields[22].GetFloat(); - cInfo->rank = fields[23].GetUInt8(); - cInfo->mindmg = fields[24].GetFloat(); - cInfo->maxdmg = fields[25].GetFloat(); - cInfo->dmgschool = fields[26].GetUInt8(); - cInfo->attackpower = fields[27].GetUInt32(); - cInfo->dmg_multiplier = fields[28].GetFloat(); - cInfo->baseattacktime = fields[29].GetUInt32(); - cInfo->rangeattacktime = fields[30].GetUInt32(); - cInfo->unit_class = fields[31].GetUInt8(); - cInfo->unit_flags = fields[32].GetUInt32(); - cInfo->unit_flags2 = fields[33].GetUInt32(); - cInfo->dynamicflags = fields[34].GetUInt32(); - cInfo->family = fields[35].GetUInt8(); - cInfo->trainer_type = fields[36].GetUInt8(); - cInfo->trainer_class = fields[37].GetUInt8(); - cInfo->trainer_race = fields[38].GetUInt8(); - cInfo->minrangedmg = fields[39].GetFloat(); - cInfo->maxrangedmg = fields[40].GetFloat(); - cInfo->rangedattackpower = fields[41].GetUInt16(); - cInfo->type = fields[42].GetUInt8(); - cInfo->type_flags = fields[43].GetUInt32(); - cInfo->type_flags2 = fields[44].GetUInt32(); - cInfo->lootid = fields[45].GetUInt32(); - cInfo->pickpocketLootId = fields[46].GetUInt32(); - cInfo->SkinLootId = fields[47].GetUInt32(); - - for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - cInfo->resistance[i] = fields[48 + i -1].GetUInt16(); - - for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) - cInfo->spells[i] = fields[54 + i].GetUInt32(); - - cInfo->PetSpellDataId = fields[62].GetUInt32(); - cInfo->VehicleId = fields[63].GetUInt32(); - cInfo->mingold = fields[64].GetUInt32(); - cInfo->maxgold = fields[65].GetUInt32(); - cInfo->AIName = fields[66].GetString(); - cInfo->MovementType = fields[67].GetUInt8(); - cInfo->InhabitType = fields[68].GetUInt8(); - cInfo->HoverHeight = fields[69].GetFloat(); - cInfo->ModHealth = fields[70].GetFloat(); - cInfo->ModMana = fields[71].GetFloat(); - cInfo->ModManaExtra = fields[72].GetFloat(); - cInfo->ModArmor = fields[73].GetFloat(); - cInfo->RacialLeader = fields[74].GetBool(); - - for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - cInfo->questItems[i] = fields[75 + i].GetUInt32(); - - cInfo->movementId = fields[81].GetUInt32(); - cInfo->RegenHealth = fields[82].GetBool(); - cInfo->MechanicImmuneMask = fields[83].GetUInt32(); - cInfo->flags_extra = fields[84].GetUInt32(); - cInfo->ScriptID = sObjectMgr->GetScriptId(fields[85].GetCString()); - + sObjectMgr->LoadCreatureTemplate(fields); sObjectMgr->CheckCreatureTemplate(cInfo); } diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp index 2f0b53bff68..a2f1c75106b 100644 --- a/src/server/scripts/Commands/cs_ticket.cpp +++ b/src/server/scripts/Commands/cs_ticket.cpp @@ -36,7 +36,7 @@ class ticket_commandscript : public CommandScript public: ticket_commandscript() : CommandScript("ticket_commandscript") { } - ChatCommand* GetCommands() const + ChatCommand* GetCommands() const override { static ChatCommand ticketResponseCommandTable[] = { diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp b/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp index 47e91cac63d..60a8e943bc7 100644 --- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp +++ b/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp @@ -140,7 +140,7 @@ public: void JustSummoned(Creature* summoned) override { - CAST_AI(npc_water_elemental::npc_water_elementalAI, summoned->AI())->balindaGUID = me->GetGUID(); + ENSURE_AI(npc_water_elemental::npc_water_elementalAI, summoned->AI())->balindaGUID = me->GetGUID(); summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true)); summoned->setFaction(me->getFaction()); summons.Summon(summoned); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp index 90306913534..0f4840c0d1f 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_maiden_of_virtue.cpp @@ -19,7 +19,7 @@ #include "ScriptedCreature.h" #include "karazhan.h" -enum Spells +enum Spells { SPELL_REPENTANCE = 29511, SPELL_HOLYFIRE = 29522, diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp index d812a8e3001..5d1e5451ab1 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_midnight.cpp @@ -230,7 +230,7 @@ public: void SetMidnight(Creature* pAttumen, uint64 value) { - CAST_AI(boss_attumen::boss_attumenAI, pAttumen->AI())->Midnight = value; + ENSURE_AI(boss_attumen::boss_attumenAI, pAttumen->AI())->Midnight = value; } }; }; @@ -307,7 +307,7 @@ void boss_attumen::boss_attumenAI::UpdateAI(uint32 diff) Creature* pMidnight = ObjectAccessor::GetCreature(*me, Midnight); if (pMidnight && pMidnight->GetTypeId() == TYPEID_UNIT) { - CAST_AI(boss_midnight::boss_midnightAI, (pMidnight->AI()))->Mount(me); + ENSURE_AI(boss_midnight::boss_midnightAI, (pMidnight->AI()))->Mount(me); me->SetHealth(pMidnight->GetHealth()); DoResetThreat(); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp index 411ebed869d..6ff1faf35b6 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp @@ -352,7 +352,7 @@ struct boss_moroes_guestAI : public ScriptedAI { if (Creature* Moroes = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MOROES))) for (uint8 i = 0; i < 4; ++i) - if (uint64 GUID = CAST_AI(boss_moroes::boss_moroesAI, Moroes->AI())->AddGUID[i]) + if (uint64 GUID = ENSURE_AI(boss_moroes::boss_moroesAI, Moroes->AI())->AddGUID[i]) GuestGUID[i] = GUID; } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp index e495cae71fc..ac24f868670 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp @@ -124,7 +124,7 @@ public: float dist(float xa, float ya, float xb, float yb) // auxiliary method for distance { - return sqrt((xa-xb)*(xa-xb) + (ya-yb)*(ya-yb)); + return std::sqrt((xa-xb)*(xa-xb) + (ya-yb)*(ya-yb)); } void Reset() override diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp index c8df08937b9..af9f8b72abf 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp @@ -328,7 +328,7 @@ public: if (TailSweepTimer <= diff) { if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - if (!me->HasInArc(M_PI, target)) + if (!me->HasInArc(float(M_PI), target)) DoCast(target, SPELL_TAIL_SWEEP); TailSweepTimer = 15000; } else TailSweepTimer -= diff; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp index e6c544aa0a0..518c4eacbd9 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp @@ -367,8 +367,8 @@ public: infernal->SetDisplayId(INFERNAL_MODEL_INVISIBLE); infernal->setFaction(me->getFaction()); if (point) - CAST_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->point=point; - CAST_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->malchezaar=me->GetGUID(); + ENSURE_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->point = point; + ENSURE_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->malchezaar = me->GetGUID(); infernals.push_back(infernal->GetGUID()); DoCast(infernal, SPELL_INFERNAL_RELAY); @@ -586,7 +586,7 @@ void netherspite_infernal::netherspite_infernalAI::Cleanup() Creature* pMalchezaar = ObjectAccessor::GetCreature(*me, malchezaar); if (pMalchezaar && pMalchezaar->IsAlive()) - CAST_AI(boss_malchezaar::boss_malchezaarAI, pMalchezaar->AI())->Cleanup(me, point); + ENSURE_AI(boss_malchezaar::boss_malchezaarAI, pMalchezaar->AI())->Cleanup(me, point); } void AddSC_boss_malchezaar() diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp index 787e468c3c1..911d4e35797 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp @@ -272,7 +272,7 @@ public: { if (Creature* pPortal = ObjectAccessor::GetCreature(*me, PortalGUID[i])) { - CAST_AI(npc_fiendish_portal::npc_fiendish_portalAI, pPortal->AI())->DespawnAllImp(); + ENSURE_AI(npc_fiendish_portal::npc_fiendish_portalAI, pPortal->AI())->DespawnAllImp(); pPortal->DespawnOrUnsummon(); } @@ -362,7 +362,7 @@ public: if (Creature* Chains = me->FindNearestCreature(NPC_DEMONCHAINS, 5000)) { - CAST_AI(npc_demon_chain::npc_demon_chainAI, Chains->AI())->SacrificeGUID = target->GetGUID(); + ENSURE_AI(npc_demon_chain::npc_demon_chainAI, Chains->AI())->SacrificeGUID = target->GetGUID(); Chains->CastSpell(Chains, SPELL_DEMON_CHAINS, true); Talk(SAY_SACRIFICE); SacrificeTimer = 30000; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp index dd5ad8ee7ae..19ec8da7fc9 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp @@ -257,7 +257,7 @@ public: Creature* Dorothee = (ObjectAccessor::GetCreature((*me), DorotheeGUID)); if (Dorothee && Dorothee->IsAlive()) { - CAST_AI(boss_dorothee::boss_dorotheeAI, Dorothee->AI())->TitoDied = true; + ENSURE_AI(boss_dorothee::boss_dorotheeAI, Dorothee->AI())->TitoDied = true; Talk(SAY_DOROTHEE_TITO_DEATH, Dorothee); } } @@ -284,7 +284,7 @@ void boss_dorothee::boss_dorotheeAI::SummonTito() if (Creature* pTito = me->SummonCreature(CREATURE_TITO, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) { Talk(SAY_DOROTHEE_SUMMON); - CAST_AI(npc_tito::npc_titoAI, pTito->AI())->DorotheeGUID = me->GetGUID(); + ENSURE_AI(npc_tito::npc_titoAI, pTito->AI())->DorotheeGUID = me->GetGUID(); pTito->AI()->AttackStart(me->GetVictim()); SummonedTito = true; TitoDied = false; @@ -1188,8 +1188,8 @@ public: if (Creature* Julianne = (ObjectAccessor::GetCreature((*me), JulianneGUID))) { - CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->RomuloDead = true; - CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->ResurrectSelfTimer = 10000; + ENSURE_AI(boss_julianne::boss_julianneAI, Julianne->AI())->RomuloDead = true; + ENSURE_AI(boss_julianne::boss_julianneAI, Julianne->AI())->ResurrectSelfTimer = 10000; } damage = 0; @@ -1216,8 +1216,8 @@ public: { PretendToDie(me); IsFakingDeath = true; - CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->ResurrectTimer = 10000; - CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->RomuloDead = true; + ENSURE_AI(boss_julianne::boss_julianneAI, Julianne->AI())->ResurrectTimer = 10000; + ENSURE_AI(boss_julianne::boss_julianneAI, Julianne->AI())->RomuloDead = true; damage = 0; return; } @@ -1276,11 +1276,11 @@ public: if (ResurrectTimer <= diff) { Creature* Julianne = (ObjectAccessor::GetCreature((*me), JulianneGUID)); - if (Julianne && CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->IsFakingDeath) + if (Julianne && ENSURE_AI(boss_julianne::boss_julianneAI, Julianne->AI())->IsFakingDeath) { Talk(SAY_ROMULO_RESURRECT); Resurrect(Julianne); - CAST_AI(boss_julianne::boss_julianneAI, Julianne->AI())->IsFakingDeath = false; + ENSURE_AI(boss_julianne::boss_julianneAI, Julianne->AI())->IsFakingDeath = false; JulianneDead = false; ResurrectTimer = 10000; } @@ -1290,7 +1290,7 @@ public: if (BackwardLungeTimer <= diff) { Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); - if (target && !me->HasInArc(M_PI, target)) + if (target && !me->HasInArc(float(M_PI), target)) { DoCast(target, SPELL_BACKWARD_LUNGE); BackwardLungeTimer = urand(15000, 30000); @@ -1362,8 +1362,8 @@ void boss_julianne::boss_julianneAI::UpdateAI(uint32 diff) if (Creature* pRomulo = me->SummonCreature(CREATURE_ROMULO, ROMULO_X, ROMULO_Y, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR*2*IN_MILLISECONDS)) { RomuloGUID = pRomulo->GetGUID(); - CAST_AI(boss_romulo::boss_romuloAI, pRomulo->AI())->JulianneGUID = me->GetGUID(); - CAST_AI(boss_romulo::boss_romuloAI, pRomulo->AI())->Phase = PHASE_ROMULO; + ENSURE_AI(boss_romulo::boss_romuloAI, pRomulo->AI())->JulianneGUID = me->GetGUID(); + ENSURE_AI(boss_romulo::boss_romuloAI, pRomulo->AI())->Phase = PHASE_ROMULO; DoZoneInCombat(pRomulo); pRomulo->setFaction(16); @@ -1396,11 +1396,11 @@ void boss_julianne::boss_julianneAI::UpdateAI(uint32 diff) if (ResurrectTimer <= diff) { Creature* Romulo = (ObjectAccessor::GetCreature((*me), RomuloGUID)); - if (Romulo && CAST_AI(boss_romulo::boss_romuloAI, Romulo->AI())->IsFakingDeath) + if (Romulo && ENSURE_AI(boss_romulo::boss_romuloAI, Romulo->AI())->IsFakingDeath) { Talk(SAY_JULIANNE_RESURRECT); Resurrect(Romulo); - CAST_AI(boss_romulo::boss_romuloAI, Romulo->AI())->IsFakingDeath = false; + ENSURE_AI(boss_romulo::boss_romuloAI, Romulo->AI())->IsFakingDeath = false; RomuloDead = false; ResurrectTimer = 10000; } @@ -1494,8 +1494,8 @@ void boss_julianne::boss_julianneAI::DamageTaken(Unit* /*done_by*/, uint32 &dama { PretendToDie(me); IsFakingDeath = true; - CAST_AI(boss_romulo::boss_romuloAI, Romulo->AI())->ResurrectTimer = 10000; - CAST_AI(boss_romulo::boss_romuloAI, Romulo->AI())->JulianneDead = true; + ENSURE_AI(boss_romulo::boss_romuloAI, Romulo->AI())->ResurrectTimer = 10000; + ENSURE_AI(boss_romulo::boss_romuloAI, Romulo->AI())->JulianneDead = true; damage = 0; return; } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp index 976a83a98c2..c89950b7de3 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp @@ -339,7 +339,7 @@ public: bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override { player->PlayerTalkClass->ClearMenus(); - npc_barnesAI* pBarnesAI = CAST_AI(npc_barnes::npc_barnesAI, creature->AI()); + npc_barnesAI* pBarnesAI = ENSURE_AI(npc_barnes::npc_barnesAI, creature->AI()); switch (action) { diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp index 45fd9fed60a..40dedcf6d93 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp @@ -450,7 +450,7 @@ struct boss_priestess_lackey_commonAI : public ScriptedAI if (Creature* Delrissa = (ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_DELRISSA)))) { for (uint8 i = 0; i < MAX_ACTIVE_LACKEY; ++i) - m_auiLackeyGUIDs[i] = CAST_AI(boss_priestess_delrissa::boss_priestess_delrissaAI, Delrissa->AI())->m_auiLackeyGUID[i]; + m_auiLackeyGUIDs[i] = ENSURE_AI(boss_priestess_delrissa::boss_priestess_delrissaAI, Delrissa->AI())->m_auiLackeyGUID[i]; } } diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index fff8a92dfcd..0189b6040f7 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -315,7 +315,7 @@ public: if (Creature* anchor = go->FindNearestCreature(29521, 15)) if (uint64 prisonerGUID = anchor->AI()->GetGUID()) if (Creature* prisoner = ObjectAccessor::GetCreature(*player, prisonerGUID)) - CAST_AI(npc_unworthy_initiate::npc_unworthy_initiateAI, prisoner->AI())->EventStart(anchor, player); + ENSURE_AI(npc_unworthy_initiate::npc_unworthy_initiateAI, prisoner->AI())->EventStart(anchor, player); return false; } @@ -632,7 +632,7 @@ public: caster->setFaction(35); DoCast(caster, SPELL_CALL_DARK_RIDER, true); if (Creature* Dark_Rider = me->FindNearestCreature(28654, 15)) - CAST_AI(npc_dark_rider_of_acherus::npc_dark_rider_of_acherusAI, Dark_Rider->AI())->InitDespawnHorse(caster); + ENSURE_AI(npc_dark_rider_of_acherus::npc_dark_rider_of_acherusAI, Dark_Rider->AI())->InitDespawnHorse(caster); } } } diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp index 2800e9473b7..72757387b1c 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp @@ -282,8 +282,8 @@ public: { case GOSSIP_ACTION_INFO_DEF+1: player->CLOSE_GOSSIP_MENU(); - CAST_AI(npc_highlord_darion_mograine::npc_highlord_darion_mograineAI, creature->AI())->uiStep = 1; - CAST_AI(npc_highlord_darion_mograine::npc_highlord_darion_mograineAI, creature->AI())->Start(true, false, player->GetGUID()); + ENSURE_AI(npc_highlord_darion_mograine::npc_highlord_darion_mograineAI, creature->AI())->uiStep = 1; + ENSURE_AI(npc_highlord_darion_mograine::npc_highlord_darion_mograineAI, creature->AI())->Start(true, false, player->GetGUID()); break; } return true; diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp index f18c0aac8bb..26937a83e63 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp @@ -70,6 +70,11 @@ class boss_arcanist_doan : public CreatureScript events.ScheduleEvent(EVENT_POLYMORPH, 30 * IN_MILLISECONDS); } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + } + void UpdateAI(uint32 diff) override { if (!UpdateVictim()) @@ -119,7 +124,7 @@ class boss_arcanist_doan : public CreatureScript CreatureAI* GetAI(Creature* creature) const override { - return new boss_arcanist_doanAI(creature); + return GetInstanceAI<boss_arcanist_doanAI>(creature); } }; diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp index dd173c75232..72874bba510 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -25,79 +24,104 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "scarlet_monastery.h" enum Spells { - SPELL_CALLOFTHEGRAVE = 17831, + SPELL_CALL_OF_THE_GRAVE = 17831, SPELL_TERRIFY = 7399, - SPELL_SOULSIPHON = 7290 + SPELL_SOUL_SIPHON = 7290 }; -class boss_azshir_the_sleepless : public CreatureScript +enum Events { -public: - boss_azshir_the_sleepless() : CreatureScript("boss_azshir_the_sleepless") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_azshir_the_sleeplessAI(creature); - } - - struct boss_azshir_the_sleeplessAI : public ScriptedAI - { - boss_azshir_the_sleeplessAI(Creature* creature) : ScriptedAI(creature) { } + EVENT_CALL_OF_GRAVE = 1, + EVENT_TERRIFY, + EVENT_SOUL_SIPHON +}; - uint32 SoulSiphon_Timer; - uint32 CallOftheGrave_Timer; - uint32 Terrify_Timer; +class boss_azshir_the_sleepless : public CreatureScript +{ + public: + boss_azshir_the_sleepless() : CreatureScript("boss_azshir_the_sleepless") { } - void Reset() override + struct boss_azshir_the_sleeplessAI : public BossAI { - SoulSiphon_Timer = 1; - CallOftheGrave_Timer = 30000; - Terrify_Timer = 20000; - } - - void EnterCombat(Unit* /*who*/) override { } + boss_azshir_the_sleeplessAI(Creature* creature) : BossAI(creature, DATA_AZSHIR) + { + _siphon = false; + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void Reset() override + { + _Reset(); + _siphon = false; + } - //If we are <50% hp cast Soul Siphon rank 1 - if (!HealthAbovePct(50) && !me->IsNonMeleeSpellCast(false)) + void EnterCombat(Unit* /*who*/) override { - //SoulSiphon_Timer - if (SoulSiphon_Timer <= diff) - { - DoCastVictim(SPELL_SOULSIPHON); - return; + _EnterCombat(); + events.ScheduleEvent(EVENT_CALL_OF_GRAVE, 30000); + events.ScheduleEvent(EVENT_TERRIFY, 20000); + } - //SoulSiphon_Timer = 20000; - } - else SoulSiphon_Timer -= diff; + void JustDied(Unit* /*killer*/) override + { + _JustDied(); } - //CallOfTheGrave_Timer - if (CallOftheGrave_Timer <= diff) + void DamageTaken(Unit* /*done_by*/, uint32& /*damage*/) override { - DoCastVictim(SPELL_CALLOFTHEGRAVE); - CallOftheGrave_Timer = 30000; + if (HealthBelowPct(50) && !_siphon) + { + DoCastVictim(SPELL_SOUL_SIPHON); + events.ScheduleEvent(EVENT_SOUL_SIPHON, 20000); + _siphon = true; + } } - else CallOftheGrave_Timer -= diff; - //Terrify_Timer - if (Terrify_Timer <= diff) + void UpdateAI(uint32 diff) override { - DoCastVictim(SPELL_TERRIFY); - Terrify_Timer = 20000; + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CALL_OF_GRAVE: + DoCastVictim(SPELL_CALL_OF_THE_GRAVE); + events.ScheduleEvent(EVENT_CALL_OF_GRAVE, 30000); + break; + case EVENT_TERRIFY: + DoCastVictim(SPELL_TERRIFY); + events.ScheduleEvent(EVENT_TERRIFY, 20000); + break; + case EVENT_SOUL_SIPHON: + DoCastVictim(SPELL_SOUL_SIPHON); + events.ScheduleEvent(EVENT_SOUL_SIPHON, 20000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); } - else Terrify_Timer -= diff; - DoMeleeAttackIfReady(); + private: + bool _siphon; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_azshir_the_sleeplessAI>(creature); } - }; }; void AddSC_boss_azshir_the_sleepless() diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp index 207c12f608a..43a9ef32be6 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,15 +15,9 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Bloodmage_Thalnos -SD%Complete: 100 -SDComment: -SDCategory: Scarlet Monastery -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "scarlet_monastery.h" enum Yells { @@ -38,95 +31,102 @@ enum Spells SPELL_FLAMESHOCK = 8053, SPELL_SHADOWBOLT = 1106, SPELL_FLAMESPIKE = 8814, - SPELL_FIRENOVA = 16079, + SPELL_FIRENOVA = 16079 }; -class boss_bloodmage_thalnos : public CreatureScript +enum Events { -public: - boss_bloodmage_thalnos() : CreatureScript("boss_bloodmage_thalnos") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_bloodmage_thalnosAI(creature); - } - - struct boss_bloodmage_thalnosAI : public ScriptedAI - { - boss_bloodmage_thalnosAI(Creature* creature) : ScriptedAI(creature) { } - - bool HpYell; - uint32 FlameShock_Timer; - uint32 ShadowBolt_Timer; - uint32 FlameSpike_Timer; - uint32 FireNova_Timer; + EVENT_FLAME_SHOCK = 1, + EVENT_SHADOW_BOLT, + EVENT_FLAME_SPIKE, + EVENT_FIRE_NOVA +}; - void Reset() override - { - HpYell = false; - FlameShock_Timer = 10000; - ShadowBolt_Timer = 2000; - FlameSpike_Timer = 8000; - FireNova_Timer = 40000; - } +class boss_bloodmage_thalnos : public CreatureScript +{ + public: + boss_bloodmage_thalnos() : CreatureScript("boss_bloodmage_thalnos") { } - void EnterCombat(Unit* /*who*/) override + struct boss_bloodmage_thalnosAI : public BossAI { - Talk(SAY_AGGRO); - } + boss_bloodmage_thalnosAI(Creature* creature) : BossAI(creature, DATA_BLOODMAGE_THALNOS) + { + _hpYell = false; + } - void KilledUnit(Unit* /*Victim*/) override - { - Talk(SAY_KILL); - } + void Reset() override + { + _hpYell = false; + _Reset(); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void EnterCombat(Unit* /*who*/) override + { + Talk(SAY_AGGRO); + _EnterCombat(); + events.ScheduleEvent(EVENT_FLAME_SHOCK, 10000); + events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000); + events.ScheduleEvent(EVENT_FLAME_SPIKE, 8000); + events.ScheduleEvent(EVENT_FIRE_NOVA, 40000); + } - //If we are <35% hp - if (!HpYell && !HealthAbovePct(35)) + void JustDied(Unit* /*killer*/) override { - Talk(SAY_HEALTH); - HpYell = true; + _JustDied(); } - //FlameShock_Timer - if (FlameShock_Timer <= diff) + void KilledUnit(Unit* /*victim*/) override { - DoCastVictim(SPELL_FLAMESHOCK); - FlameShock_Timer = urand(10000, 15000); + Talk(SAY_KILL); } - else FlameShock_Timer -= diff; - //FlameSpike_Timer - if (FlameSpike_Timer <= diff) + void DamageTaken(Unit* /*done_by*/, uint32& /*damage*/) override { - DoCastVictim(SPELL_FLAMESPIKE); - FlameSpike_Timer = 30000; + if (HealthBelowPct(35) && !_hpYell) + { + Talk(SAY_HEALTH); + _hpYell = true; + } } - else FlameSpike_Timer -= diff; - //FireNova_Timer - if (FireNova_Timer <= diff) + void ExecuteEvent(uint32 eventId) override { - DoCastVictim(SPELL_FIRENOVA); - FireNova_Timer = 40000; + switch (eventId) + { + case EVENT_FLAME_SHOCK: + DoCastVictim(SPELL_FLAMESHOCK); + events.ScheduleEvent(EVENT_FLAME_SHOCK, urand(10000, 15000)); + break; + case EVENT_SHADOW_BOLT: + DoCastVictim(SPELL_SHADOWBOLT); + events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000); + break; + case EVENT_FLAME_SPIKE: + DoCastVictim(SPELL_FLAMESPIKE); + events.ScheduleEvent(EVENT_FLAME_SPIKE, 30000); + break; + case EVENT_FIRE_NOVA: + DoCastVictim(SPELL_FIRENOVA); + events.ScheduleEvent(EVENT_FIRE_NOVA, 40000); + break; + default: + break; + } } - else FireNova_Timer -= diff; - //ShadowBolt_Timer - if (ShadowBolt_Timer <= diff) + void UpdateAI(uint32 diff) override { - DoCastVictim(SPELL_SHADOWBOLT); - ShadowBolt_Timer = 2000; + BossAI::UpdateAI(diff); } - else ShadowBolt_Timer -= diff; - DoMeleeAttackIfReady(); + private: + bool _hpYell; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_bloodmage_thalnosAI>(creature); } - }; }; void AddSC_boss_bloodmage_thalnos() diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index e169e521d0b..cad46b84748 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -155,13 +155,13 @@ public: { npc_wisp_invisAI(Creature* creature) : ScriptedAI(creature) { - Creaturetype = delay = spell = spell2 = 0; + Creaturetype = delay = _spell = _spell2 = 0; } uint32 Creaturetype; uint32 delay; - uint32 spell; - uint32 spell2; + uint32 _spell; + uint32 _spell2; void Reset() override { } void EnterCombat(Unit* /*who*/) override { } void SetType(uint32 _type) @@ -169,24 +169,24 @@ public: switch (Creaturetype = _type) { case 1: - spell = SPELL_PUMPKIN_AURA_GREEN; + _spell = SPELL_PUMPKIN_AURA_GREEN; break; case 2: delay = 15000; - spell = SPELL_BODY_FLAME; - spell2 = SPELL_DEATH; + _spell = SPELL_BODY_FLAME; + _spell2 = SPELL_DEATH; break; case 3: delay = 15000; - spell = SPELL_SMOKE; + _spell = SPELL_SMOKE; break; case 4: delay = 7000; - spell2 = SPELL_WISP_BLUE; + _spell2 = SPELL_WISP_BLUE; break; } - if (spell) - DoCast(me, spell); + if (_spell) + DoCast(me, _spell); } void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override @@ -196,7 +196,6 @@ public: } void MoveInLineOfSight(Unit* who) override - { if (!who || Creaturetype != 1 || !who->isTargetableForAttack()) return; @@ -212,8 +211,8 @@ public: if (delay <= diff) { me->RemoveAurasDueToSpell(SPELL_SMOKE); - if (spell2) - DoCast(me, spell2); + if (_spell2) + DoCast(me, _spell2); delay = 0; } else delay -= diff; } @@ -435,7 +434,7 @@ public: } me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - //instance->SetData(DATA_HORSEMAN_EVENT, NOT_STARTED); + //instance->SetBossState(DATA_HORSEMAN_EVENT, NOT_STARTED); } void FlyMode() @@ -466,12 +465,12 @@ public: case 1: { if (Creature* smoke = me->SummonCreature(HELPER, Spawn[1].x, Spawn[1].y, Spawn[1].z, 0, TEMPSUMMON_TIMED_DESPAWN, 20000)) - CAST_AI(npc_wisp_invis::npc_wisp_invisAI, smoke->AI())->SetType(3); + ENSURE_AI(npc_wisp_invis::npc_wisp_invisAI, smoke->AI())->SetType(3); DoCast(me, SPELL_RHYME_BIG); break; } case 6: - instance->SetData(GAMEOBJECT_PUMPKIN_SHRINE, 0); //hide gameobject + instance->SetData(DATA_PUMPKIN_SHRINE, 0); //hide gameobject break; case 19: me->SetDisableGravity(false); @@ -493,7 +492,7 @@ public: void EnterCombat(Unit* /*who*/) override { - instance->SetData(DATA_HORSEMAN_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_HORSEMAN_EVENT, IN_PROGRESS); DoZoneInCombat(); } @@ -503,7 +502,6 @@ public: } void MoveInLineOfSight(Unit* who) override - { if (withhead && Phase != 0) ScriptedAI::MoveInLineOfSight(who); @@ -517,7 +515,7 @@ public: SaySound(SAY_PLAYER_DEATH); //maybe possible when player dies from conflagration else if (Creature* Head = ObjectAccessor::GetCreature((*me), headGUID)) - CAST_AI(npc_head::npc_headAI, Head->AI())->SaySound(SAY_PLAYER_DEATH); + ENSURE_AI(npc_head::npc_headAI, Head->AI())->SaySound(SAY_PLAYER_DEATH); } } @@ -566,8 +564,8 @@ public: if (Creature* flame = DoSpawnCreature(HELPER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 60000)) flame->CastSpell(flame, SPELL_BODY_FLAME, false); if (Creature* wisp = DoSpawnCreature(WISP_INVIS, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 60000)) - CAST_AI(npc_wisp_invis::npc_wisp_invisAI, wisp->AI())->SetType(4); - instance->SetData(DATA_HORSEMAN_EVENT, DONE); + ENSURE_AI(npc_wisp_invis::npc_wisp_invisAI, wisp->AI())->SetType(4); + instance->SetBossState(DATA_HORSEMAN_EVENT, DONE); Map::PlayerList const& players = me->GetMap()->GetPlayers(); if (!players.isEmpty()) @@ -690,7 +688,7 @@ public: if (burn <= diff) { if (Creature* flame = me->SummonCreature(HELPER, Spawn[0].x, Spawn[0].y, Spawn[0].z, 0, TEMPSUMMON_TIMED_DESPAWN, 17000)) - CAST_AI(npc_wisp_invis::npc_wisp_invisAI, flame->AI())->SetType(2); + ENSURE_AI(npc_wisp_invis::npc_wisp_invisAI, flame->AI())->SetType(2); burned = true; } else burn -= diff; @@ -749,8 +747,8 @@ public: Creature* Head = ObjectAccessor::GetCreature((*me), headGUID); if (Head && Head->IsAlive()) { - CAST_AI(npc_head::npc_headAI, Head->AI())->Phase = Phase; - CAST_AI(npc_head::npc_headAI, Head->AI())->Disappear(); + ENSURE_AI(npc_head::npc_headAI, Head->AI())->Phase = Phase; + ENSURE_AI(npc_head::npc_headAI, Head->AI())->Disappear(); } return; } @@ -808,7 +806,7 @@ public: { debuff->SetDisplayId(me->GetDisplayId()); debuff->CastSpell(debuff, SPELL_PUMPKIN_AURA_GREEN, false); - CAST_AI(npc_wisp_invis::npc_wisp_invisAI, debuff->AI())->SetType(1); + ENSURE_AI(npc_wisp_invis::npc_wisp_invisAI, debuff->AI())->SetType(1); debuffGUID = debuff->GetGUID(); } sprouted = false; @@ -852,7 +850,6 @@ public: } void MoveInLineOfSight(Unit* who) override - { if (!who || !me->IsValidAttackTarget(who) || me->GetVictim()) return; @@ -880,9 +877,9 @@ public: InstanceScript* instance = player->GetInstanceScript(); if (instance) { - if (instance->GetData(DATA_HORSEMAN_EVENT) != NOT_STARTED) + if (instance->GetBossState(DATA_HORSEMAN_EVENT) != NOT_STARTED) return true; - instance->SetData(DATA_HORSEMAN_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_HORSEMAN_EVENT, IN_PROGRESS); } /* if (soil->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER && player->getLevel() > 64) { @@ -894,8 +891,8 @@ public: player->AreaExploredOrEventHappens(11405); if (Creature* horseman = soil->SummonCreature(HH_MOUNTED, FlightPoint[20].x, FlightPoint[20].y, FlightPoint[20].z, 0, TEMPSUMMON_MANUAL_DESPAWN, 0)) { - CAST_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->PlayerGUID = player->GetGUID(); - CAST_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->FlyMode(); + ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->PlayerGUID = player->GetGUID(); + ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, horseman->AI())->FlyMode(); } //} return true; @@ -920,7 +917,7 @@ void npc_head::npc_headAI::Disappear() me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->GetMotionMaster()->MoveIdle(); - CAST_AI(boss_headless_horseman::boss_headless_horsemanAI, body->AI())->returned = true; + ENSURE_AI(boss_headless_horseman::boss_headless_horsemanAI, body->AI())->returned = true; } } } diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp index 480b354fe29..0b7ad73fefd 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp @@ -26,6 +26,7 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedEscortAI.h" +#include "scarlet_monastery.h" enum Says { @@ -44,89 +45,103 @@ enum Spells SPELL_FRENZY = 8269 }; -enum Entry +enum Npcs { - ENTRY_SCARLET_TRAINEE = 6575, - ENTRY_SCARLET_MYRMIDON = 4295 + NPC_SCARLET_TRAINEE = 6575, + NPC_SCARLET_MYRMIDON = 4295 }; -class boss_herod : public CreatureScript +enum Events { -public: - boss_herod() : CreatureScript("boss_herod") { } + EVENT_CLEAVE = 1, + EVENT_WHIRLWIND +}; - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_herodAI(creature); - } +Position const ScarletTraineePos = { 1939.18f, -431.58f, 17.09f, 6.22f }; - struct boss_herodAI : public ScriptedAI - { - boss_herodAI(Creature* creature) : ScriptedAI(creature) { } +class boss_herod : public CreatureScript +{ + public: + boss_herod() : CreatureScript("boss_herod") { } - bool Enrage; + struct boss_herodAI : public BossAI + { + boss_herodAI(Creature* creature) : BossAI(creature, DATA_HEROD) + { + _enrage = false; + } - uint32 Cleave_Timer; - uint32 Whirlwind_Timer; + void Reset() override + { + _enrage = false; + _Reset(); + } - void Reset() override - { - Enrage = false; - Cleave_Timer = 12000; - Whirlwind_Timer = 60000; - } + void EnterCombat(Unit* /*who*/) override + { + Talk(SAY_AGGRO); + DoCast(me, SPELL_RUSHINGCHARGE); + _EnterCombat(); - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_AGGRO); - DoCast(me, SPELL_RUSHINGCHARGE); - } + events.ScheduleEvent(EVENT_CLEAVE, 12000); + events.ScheduleEvent(EVENT_WHIRLWIND, 60000); + } - void KilledUnit(Unit* /*victim*/) override - { - Talk(SAY_KILL); - } + void KilledUnit(Unit* /*victim*/) override + { + Talk(SAY_KILL); + } - void JustDied(Unit* /*killer*/) override - { - for (uint8 i = 0; i < 20; ++i) - me->SummonCreature(ENTRY_SCARLET_TRAINEE, 1939.18f, -431.58f, 17.09f, 6.22f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + for (uint8 i = 0; i < 20; ++i) + me->SummonCreature(NPC_SCARLET_TRAINEE, ScarletTraineePos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); + } - //If we are <30% hp goes Enraged - if (!Enrage && !HealthAbovePct(30) && !me->IsNonMeleeSpellCast(false)) + void DamageTaken(Unit* /*done_by*/, uint32& /*damage*/) override { - Talk(EMOTE_ENRAGE); - Talk(SAY_ENRAGE); - DoCast(me, SPELL_FRENZY); - Enrage = true; + if (HealthBelowPct(30) && !_enrage) + { + Talk(EMOTE_ENRAGE); + Talk(SAY_ENRAGE); + DoCast(me, SPELL_FRENZY); + _enrage = true; + } } - //Cleave_Timer - if (Cleave_Timer <= diff) + void ExecuteEvent(uint32 eventId) override { - DoCastVictim(SPELL_CLEAVE); - Cleave_Timer = 12000; + switch (eventId) + { + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + events.ScheduleEvent(EVENT_CLEAVE, 12000); + break; + case EVENT_WHIRLWIND: + Talk(SAY_WHIRLWIND); + DoCastVictim(SPELL_WHIRLWIND); + events.ScheduleEvent(EVENT_WHIRLWIND, 30000); + break; + default: + break; + } } - else Cleave_Timer -= diff; - // Whirlwind_Timer - if (Whirlwind_Timer <= diff) + void UpdateAI(uint32 diff) override { - Talk(SAY_WHIRLWIND); - DoCastVictim(SPELL_WHIRLWIND); - Whirlwind_Timer = 30000; + BossAI::UpdateAI(diff); } - else Whirlwind_Timer -= diff; + + private: + bool _enrage; + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_herodAI>(creature); } - }; }; class npc_scarlet_trainee : public CreatureScript diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp index f58ab1519e4..a4a3660b360 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp @@ -25,6 +25,7 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "scarlet_monastery.h" enum Spells { @@ -43,12 +44,15 @@ public: CreatureAI* GetAI(Creature* creature) const override { - return new boss_high_inquisitor_fairbanksAI(creature); + return GetInstanceAI<boss_high_inquisitor_fairbanksAI>(creature); } struct boss_high_inquisitor_fairbanksAI : public ScriptedAI { - boss_high_inquisitor_fairbanksAI(Creature* creature) : ScriptedAI(creature) { } + boss_high_inquisitor_fairbanksAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + } uint32 CurseOfBlood_Timer; uint32 DispelMagic_Timer; @@ -57,6 +61,7 @@ public: uint32 Sleep_Timer; uint32 Dispel_Timer; bool PowerWordShield; + InstanceScript* instance; void Reset() override { @@ -69,12 +74,19 @@ public: PowerWordShield = false; me->SetStandState(UNIT_STAND_STATE_DEAD); me->SetUInt32Value(UNIT_FIELD_BYTES_1, 7); + instance->SetBossState(DATA_HIGH_INQUISITOR_FAIRBANKS, NOT_STARTED); } void EnterCombat(Unit* /*who*/) override { me->SetStandState(UNIT_STAND_STATE_STAND); me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + instance->SetBossState(DATA_HIGH_INQUISITOR_FAIRBANKS, IN_PROGRESS); + } + + void JustDied(Unit* /*killer*/) override + { + instance->SetBossState(DATA_HIGH_INQUISITOR_FAIRBANKS, DONE); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp index 5aa9729a7e8..40c7667843b 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,15 +15,9 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Houndmaster_Loksey -SD%Complete: 100 -SDComment: -SDCategory: Scarlet Monastery -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "scarlet_monastery.h" enum Yells { @@ -37,47 +30,60 @@ enum Spells SPELL_BLOODLUST = 6742 }; -class boss_houndmaster_loksey : public CreatureScript +enum Events { -public: - boss_houndmaster_loksey() : CreatureScript("boss_houndmaster_loksey") { } + EVENT_BLOODLUST = 1 +}; - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_houndmaster_lokseyAI(creature); - } +class boss_houndmaster_loksey : public CreatureScript +{ + public: + boss_houndmaster_loksey() : CreatureScript("boss_houndmaster_loksey") { } - struct boss_houndmaster_lokseyAI : public ScriptedAI - { - boss_houndmaster_lokseyAI(Creature* creature) : ScriptedAI(creature) { } + struct boss_houndmaster_lokseyAI : public BossAI + { + boss_houndmaster_lokseyAI(Creature* creature) : BossAI(creature, DATA_HOUNDMASTER_LOKSEY) { } - uint32 BloodLust_Timer; + void Reset() override + { + _Reset(); + } - void Reset() override - { - BloodLust_Timer = 20000; - } + void EnterCombat(Unit* /*who*/) override + { + Talk(SAY_AGGRO); + _EnterCombat(); + events.ScheduleEvent(EVENT_BLOODLUST, 20000); + } - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_AGGRO); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void ExecuteEvent(uint32 eventId) override + { + switch (eventId) + { + case EVENT_BLOODLUST: + DoCast(me, SPELL_BLOODLUST); + events.ScheduleEvent(EVENT_BLOODLUST, 20000); + break; + default: + break; + } + } - if (BloodLust_Timer <= diff) + void UpdateAI(uint32 diff) override { - DoCast(me, SPELL_BLOODLUST); - BloodLust_Timer = 20000; + BossAI::UpdateAI(diff); } - else BloodLust_Timer -= diff; + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_houndmaster_lokseyAI>(creature); } - }; }; void AddSC_boss_houndmaster_loksey() diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp index a7c795a81f6..a73cf946a7c 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp @@ -69,11 +69,13 @@ public: ShadowWordPain_Timer = 5000; Yell60 = false; Yell30 = false; + instance->SetBossState(DATA_INTERROGATOR_VISHAS, NOT_STARTED); } void EnterCombat(Unit* /*who*/) override { Talk(SAY_AGGRO); + instance->SetBossState(DATA_INTERROGATOR_VISHAS, IN_PROGRESS); } void KilledUnit(Unit* /*Victim*/) override @@ -86,6 +88,7 @@ public: //Any other Actions to do with vorrel? setStandState? if (Creature* vorrel = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_VORREL))) vorrel->AI()->Talk(SAY_TRIGGER_VORREL); + instance->SetBossState(DATA_INTERROGATOR_VISHAS, DONE); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp index 25bb08620a1..a9988584edd 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp @@ -95,7 +95,7 @@ public: me->SetStandState(UNIT_STAND_STATE_STAND); if (me->IsAlive()) - instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, NOT_STARTED); + instance->SetBossState(DATA_MOGRAINE_AND_WHITE_EVENT, NOT_STARTED); _bHasDied = false; _bHeal = false; @@ -104,8 +104,8 @@ public: void JustReachedHome() override { - if (instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) != NOT_STARTED) - instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, FAIL); + if (instance->GetBossState(DATA_MOGRAINE_AND_WHITE_EVENT) != NOT_STARTED) + instance->SetBossState(DATA_MOGRAINE_AND_WHITE_EVENT, FAIL); } void EnterCombat(Unit* /*who*/) override @@ -129,7 +129,7 @@ public: //On first death, fake death and open door, as well as initiate whitemane if exist if (Unit* Whitemane = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_WHITEMANE))) { - instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_MOGRAINE_AND_WHITE_EVENT, IN_PROGRESS); Whitemane->GetMotionMaster()->MovePoint(1, 1163.113370f, 1398.856812f, 32.527786f); @@ -163,7 +163,7 @@ public: Talk(SAY_MO_RESURRECTED); _bFakeDeath = false; - instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, SPECIAL); + instance->SetBossState(DATA_MOGRAINE_AND_WHITE_EVENT, SPECIAL); } } @@ -172,7 +172,7 @@ public: if (!UpdateVictim()) return; - if (_bHasDied && !_bHeal && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == SPECIAL) + if (_bHasDied && !_bHeal && instance->GetBossState(DATA_MOGRAINE_AND_WHITE_EVENT) == SPECIAL) { //On resurrection, stop fake death and heal whitemane and resume fight if (Unit* Whitemane = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_WHITEMANE))) @@ -254,12 +254,12 @@ public: _bCanResurrect = false; if (me->IsAlive()) - instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, NOT_STARTED); + instance->SetBossState(DATA_MOGRAINE_AND_WHITE_EVENT, NOT_STARTED); } void AttackStart(Unit* who) override { - if (instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == NOT_STARTED) + if (instance->GetBossState(DATA_MOGRAINE_AND_WHITE_EVENT) == NOT_STARTED) return; ScriptedAI::AttackStart(who); diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_scorn.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_scorn.cpp index 3ed32b71cbb..24efd7017ec 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_scorn.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_scorn.cpp @@ -25,84 +25,87 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "scarlet_monastery.h" enum Spells { SPELL_LICHSLAP = 28873, - SPELL_FROSTBOLTVOLLEY = 8398, + SPELL_FROSTBOLT_VOLLEY = 8398, SPELL_MINDFLAY = 17313, SPELL_FROSTNOVA = 15531 }; -class boss_scorn : public CreatureScript +enum Events { -public: - boss_scorn() : CreatureScript("boss_scorn") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new boss_scornAI(creature); - } - - struct boss_scornAI : public ScriptedAI - { - boss_scornAI(Creature* creature) : ScriptedAI(creature) { } + EVENT_LICH_SLAP = 1, + EVENT_FROSTBOLT_VOLLEY, + EVENT_MIND_FLAY, + EVENT_FROST_NOVA +}; - uint32 LichSlap_Timer; - uint32 FrostboltVolley_Timer; - uint32 MindFlay_Timer; - uint32 FrostNova_Timer; +class boss_scorn : public CreatureScript +{ + public: + boss_scorn() : CreatureScript("boss_scorn") { } - void Reset() override + struct boss_scornAI : public BossAI { - LichSlap_Timer = 45000; - FrostboltVolley_Timer = 30000; - MindFlay_Timer = 30000; - FrostNova_Timer = 30000; - } - - void EnterCombat(Unit* /*who*/) override { } + boss_scornAI(Creature* creature) : BossAI(creature, DATA_SCORN) { } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void Reset() override + { + _Reset(); + } - //LichSlap_Timer - if (LichSlap_Timer <= diff) + void EnterCombat(Unit* /*who*/) override { - DoCastVictim(SPELL_LICHSLAP); - LichSlap_Timer = 45000; + _EnterCombat(); + events.ScheduleEvent(EVENT_LICH_SLAP, 45000); + events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 30000); + events.ScheduleEvent(EVENT_MIND_FLAY, 30000); + events.ScheduleEvent(EVENT_FROST_NOVA, 30000); } - else LichSlap_Timer -= diff; - //FrostboltVolley_Timer - if (FrostboltVolley_Timer <= diff) + void JustDied(Unit* /*killer*/) override { - DoCastVictim(SPELL_FROSTBOLTVOLLEY); - FrostboltVolley_Timer = 20000; + _JustDied(); } - else FrostboltVolley_Timer -= diff; - //MindFlay_Timer - if (MindFlay_Timer <= diff) + void ExecuteEvent(uint32 eventId) override { - DoCastVictim(SPELL_MINDFLAY); - MindFlay_Timer = 20000; + switch (eventId) + { + case EVENT_LICH_SLAP: + DoCastVictim(SPELL_LICHSLAP); + events.ScheduleEvent(EVENT_LICH_SLAP, 45000); + break; + case EVENT_FROSTBOLT_VOLLEY: + DoCastVictim(SPELL_FROSTBOLT_VOLLEY); + events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 20000); + break; + case EVENT_MIND_FLAY: + DoCastVictim(SPELL_MINDFLAY); + events.ScheduleEvent(EVENT_MIND_FLAY, 20000); + break; + case EVENT_FROST_NOVA: + DoCastVictim(SPELL_FROSTNOVA); + events.ScheduleEvent(EVENT_FROST_NOVA, 15000); + break; + default: + break; + } } - else MindFlay_Timer -= diff; - //FrostNova_Timer - if (FrostNova_Timer <= diff) + void UpdateAI(uint32 diff) override { - DoCastVictim(SPELL_FROSTNOVA); - FrostNova_Timer = 15000; + BossAI::UpdateAI(diff); } - else FrostNova_Timer -= diff; + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_scornAI>(creature); } - }; }; void AddSC_boss_scorn() diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp index dc564e43af5..78837912688 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,146 +15,205 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Instance_Scarlet_Monastery -SD%Complete: 50 -SDComment: -SDCategory: Scarlet Monastery -EndScriptData */ - #include "ScriptMgr.h" -#include "ScriptedCreature.h" +#include "InstanceScript.h" #include "scarlet_monastery.h" -enum Entry +DoorData const doorData[] = { - ENTRY_PUMPKIN_SHRINE = 186267, - ENTRY_HORSEMAN = 23682, - ENTRY_HEAD = 23775, - ENTRY_PUMPKIN = 23694 + { GO_HIGH_INQUISITORS_DOOR, DATA_MOGRAINE_AND_WHITE_EVENT, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END }; -#define MAX_ENCOUNTER 2 - class instance_scarlet_monastery : public InstanceMapScript { -public: - instance_scarlet_monastery() : InstanceMapScript("instance_scarlet_monastery", 189) { } + public: + instance_scarlet_monastery() : InstanceMapScript("instance_scarlet_monastery", 189) { } - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_scarlet_monastery_InstanceMapScript(map); - } + struct instance_scarlet_monastery_InstanceMapScript : public InstanceScript + { + instance_scarlet_monastery_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + LoadDoorData(doorData); - struct instance_scarlet_monastery_InstanceMapScript : public InstanceScript - { - instance_scarlet_monastery_InstanceMapScript(Map* map) : InstanceScript(map) { } + PumpkinShrineGUID = 0; + HorsemanGUID = 0; + HeadGUID = 0; + MograineGUID = 0; + WhitemaneGUID = 0; + VorrelGUID = 0; - uint64 PumpkinShrineGUID; - uint64 HorsemanGUID; - uint64 HeadGUID; - std::set<uint64> HorsemanAdds; + HorsemanAdds.clear(); + } - uint64 MograineGUID; - uint64 WhitemaneGUID; - uint64 VorrelGUID; - uint64 DoorHighInquisitorGUID; + void OnGameObjectCreate(GameObject* go) override + { + switch (go->GetEntry()) + { + case GO_PUMPKIN_SHRINE: + PumpkinShrineGUID = go->GetGUID(); + break; + case GO_HIGH_INQUISITORS_DOOR: + AddDoor(go, true); + break; + default: + break; + } + } - uint32 encounter[MAX_ENCOUNTER]; + void OnGameObjectRemove(GameObject* go) override + { + switch (go->GetEntry()) + { + case GO_HIGH_INQUISITORS_DOOR: + AddDoor(go, false); + break; + default: + break; + } + } - void Initialize() override - { - memset(&encounter, 0, sizeof(encounter)); + void OnCreatureCreate(Creature* creature) override + { + switch (creature->GetEntry()) + { + case NPC_HORSEMAN: + HorsemanGUID = creature->GetGUID(); + break; + case NPC_HEAD: + HeadGUID = creature->GetGUID(); + break; + case NPC_PUMPKIN: + HorsemanAdds.insert(creature->GetGUID()); + break; + case NPC_MOGRAINE: + MograineGUID = creature->GetGUID(); + break; + case NPC_WHITEMANE: + WhitemaneGUID = creature->GetGUID(); + break; + case NPC_VORREL: + VorrelGUID = creature->GetGUID(); + break; + default: + break; + } + } - PumpkinShrineGUID = 0; - HorsemanGUID = 0; - HeadGUID = 0; - HorsemanAdds.clear(); + void SetData(uint32 type, uint32 /*data*/) override + { + switch (type) + { + case DATA_PUMPKIN_SHRINE: + HandleGameObject(PumpkinShrineGUID, false); + break; + default: + break; + } + } - MograineGUID = 0; - WhitemaneGUID = 0; - VorrelGUID = 0; - DoorHighInquisitorGUID = 0; - } + bool SetBossState(uint32 type, EncounterState state) override + { + if (!InstanceScript::SetBossState(type, state)) + return false; - void OnGameObjectCreate(GameObject* go) override - { - switch (go->GetEntry()) + switch (type) + { + case DATA_HORSEMAN_EVENT: + if (state == DONE) + { + for (uint64 guid : HorsemanAdds) + { + Creature* add = instance->GetCreature(guid); + if (add && add->IsAlive()) + add->Kill(add); + } + HorsemanAdds.clear(); + HandleGameObject(PumpkinShrineGUID, false); + } + break; + default: + break; + } + return true; + } + + uint64 GetData64(uint32 type) const override { - case ENTRY_PUMPKIN_SHRINE: PumpkinShrineGUID = go->GetGUID();break; - case 104600: DoorHighInquisitorGUID = go->GetGUID(); break; + switch (type) + { + case DATA_MOGRAINE: + return MograineGUID; + case DATA_WHITEMANE: + return WhitemaneGUID; + case DATA_VORREL: + return VorrelGUID; + default: + break; + } + return 0; } - } - void OnCreatureCreate(Creature* creature) override - { - switch (creature->GetEntry()) + std::string GetSaveData() override { - case ENTRY_HORSEMAN: HorsemanGUID = creature->GetGUID(); break; - case ENTRY_HEAD: HeadGUID = creature->GetGUID(); break; - case ENTRY_PUMPKIN: HorsemanAdds.insert(creature->GetGUID());break; - case 3976: MograineGUID = creature->GetGUID(); break; - case 3977: WhitemaneGUID = creature->GetGUID(); break; - case 3981: VorrelGUID = creature->GetGUID(); break; + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << "S M " << GetBossSaveData(); + + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); } - } - void SetData(uint32 type, uint32 data) override - { - switch (type) + void Load(const char* str) override { - case TYPE_MOGRAINE_AND_WHITE_EVENT: - if (data == IN_PROGRESS) - DoUseDoorOrButton(DoorHighInquisitorGUID); - if (data == FAIL) - DoUseDoorOrButton(DoorHighInquisitorGUID); - - encounter[0] = data; - break; - case GAMEOBJECT_PUMPKIN_SHRINE: - HandleGameObject(PumpkinShrineGUID, false); - break; - case DATA_HORSEMAN_EVENT: - encounter[1] = data; - if (data == DONE) + if (!str) { - for (std::set<uint64>::const_iterator itr = HorsemanAdds.begin(); itr != HorsemanAdds.end(); ++itr) + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(str); + + char dataHead1, dataHead2; + + std::istringstream loadStream(str); + loadStream >> dataHead1 >> dataHead2; + + if (dataHead1 == 'S' && dataHead2 == 'M') + { + for (uint8 i = 0; i < EncounterCount; ++i) { - Creature* add = instance->GetCreature(*itr); - if (add && add->IsAlive()) - add->Kill(add); + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; + + SetBossState(i, EncounterState(tmpState)); } - HorsemanAdds.clear(); - HandleGameObject(PumpkinShrineGUID, false); } - break; - } - } + else + OUT_LOAD_INST_DATA_FAIL; - uint64 GetData64(uint32 type) const override - { - switch (type) - { - //case GAMEOBJECT_PUMPKIN_SHRINE: return PumpkinShrineGUID; - //case DATA_HORSEMAN: return HorsemanGUID; - //case DATA_HEAD: return HeadGUID; - case DATA_MOGRAINE: return MograineGUID; - case DATA_WHITEMANE: return WhitemaneGUID; - case DATA_VORREL: return VorrelGUID; - case DATA_DOOR_WHITEMANE: return DoorHighInquisitorGUID; + OUT_LOAD_INST_DATA_COMPLETE; } - return 0; - } - uint32 GetData(uint32 type) const override + protected: + uint64 PumpkinShrineGUID; + uint64 HorsemanGUID; + uint64 HeadGUID; + uint64 MograineGUID; + uint64 WhitemaneGUID; + uint64 VorrelGUID; + + std::set<uint64> HorsemanAdds; + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override { - if (type == TYPE_MOGRAINE_AND_WHITE_EVENT) - return encounter[0]; - if (type == DATA_HORSEMAN_EVENT) - return encounter[1]; - return 0; + return new instance_scarlet_monastery_InstanceMapScript(map); } - }; }; void AddSC_instance_scarlet_monastery() diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h b/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h index bdac6b089fd..40089cd9817 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -19,19 +18,43 @@ #ifndef SCARLET_M_ #define SCARLET_M_ +uint32 const EncounterCount = 10; + enum DataTypes { - TYPE_MOGRAINE_AND_WHITE_EVENT = 1, - + DATA_MOGRAINE_AND_WHITE_EVENT = 1, DATA_MOGRAINE = 2, DATA_WHITEMANE = 3, - DATA_DOOR_WHITEMANE = 4, - DATA_HORSEMAN_EVENT = 5, - GAMEOBJECT_PUMPKIN_SHRINE = 6, + DATA_HORSEMAN_EVENT = 4, + DATA_PUMPKIN_SHRINE = 5, + + DATA_VORREL = 6, + DATA_ARCANIST_DOAN = 7, + DATA_AZSHIR = 8, + DATA_BLOODMAGE_THALNOS = 9, + DATA_HEROD = 10, + DATA_HIGH_INQUISITOR_FAIRBANKS = 11, + DATA_HOUNDMASTER_LOKSEY = 12, + DATA_INTERROGATOR_VISHAS = 13, + DATA_SCORN = 14 +}; + +enum CreatureIds +{ + NPC_MOGRAINE = 3976, + NPC_WHITEMANE = 3977, + NPC_VORREL = 3981, + + NPC_HORSEMAN = 23682, + NPC_HEAD = 23775, + NPC_PUMPKIN = 23694 +}; - DATA_VORREL = 7, - DATA_ARCANIST_DOAN = 8 +enum GameObjectIds +{ + GO_HIGH_INQUISITORS_DOOR = 104600, + GO_PUMPKIN_SHRINE = 186267 }; #endif // SCARLET_M_ diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp index 9c83b038545..b7e03fe0459 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp @@ -650,8 +650,8 @@ public: TeleportAllPlayersBack(); if (Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID)) { - CAST_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->TalkTimer = 1; - CAST_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->isFriendly = false; + ENSURE_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->TalkTimer = 1; + ENSURE_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->isFriendly = false; } EnterEvadeMode(); return; @@ -666,8 +666,8 @@ public: TeleportAllPlayersBack(); if (Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID)) { - CAST_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->TalkTimer = 1; - CAST_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->isFriendly = true; + ENSURE_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->TalkTimer = 1; + ENSURE_AI(boss_kalecgos::boss_kalecgosAI, Kalecgos->AI())->isFriendly = true; } instance->SetBossState(DATA_KALECGOS, DONE); diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp index 849b7014d3a..1f66f834b28 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp @@ -370,7 +370,7 @@ public: go->SetUInt32Value(GAMEOBJECT_FACTION, 0); if (Creature* pKalec = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_KALECGOS_KJ))) - CAST_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalec->AI())->SetRingOfBlueFlames(); + ENSURE_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalec->AI())->SetRingOfBlueFlames(); go->Refresh(); } @@ -422,7 +422,7 @@ public: phase = PHASE_DECEIVERS; if (Creature* pKalecKJ = ObjectAccessor::GetCreature((*me), instance->GetData64(DATA_KALECGOS_KJ))) - CAST_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalecKJ->AI())->ResetOrbs(); + ENSURE_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalecKJ->AI())->ResetOrbs(); deceiverDeathCount = 0; bSummonedDeceivers = false; bKiljaedenDeath = false; @@ -612,7 +612,7 @@ public: // Reset the controller if (Creature* pControl = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KILJAEDEN_CONTROLLER))) - CAST_AI(npc_kiljaeden_controller::npc_kiljaeden_controllerAI, pControl->AI())->Reset(); + ENSURE_AI(npc_kiljaeden_controller::npc_kiljaeden_controllerAI, pControl->AI())->Reset(); } void EnterCombat(Unit* /*who*/) override @@ -800,10 +800,10 @@ public: switch (Phase) { case PHASE_SACRIFICE: - CAST_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalec->AI())->EmpowerOrb(true); + ENSURE_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalec->AI())->EmpowerOrb(true); break; default: - CAST_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalec->AI())->EmpowerOrb(false); + ENSURE_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalec->AI())->EmpowerOrb(false); break; } } @@ -924,7 +924,7 @@ public: void JustDied(Unit* /*killer*/) override { if (Creature* pControl = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KILJAEDEN_CONTROLLER))) - ++(CAST_AI(npc_kiljaeden_controller::npc_kiljaeden_controllerAI, pControl->AI())->deceiverDeathCount); + ++(ENSURE_AI(npc_kiljaeden_controller::npc_kiljaeden_controllerAI, pControl->AI())->deceiverDeathCount); } void UpdateAI(uint32 diff) override @@ -1191,8 +1191,8 @@ public: bPointReached = false; uiCheckTimer = 1000; me->GetMotionMaster()->MovePoint(1, x, y, SHIELD_ORB_Z); - c += M_PI/32; - if (c >= 2*M_PI) c = 0; + c += float(M_PI)/32; + if (c >= 2 * float(M_PI)) c = 0; } else { diff --git a/src/server/scripts/EasternKingdoms/zone_undercity.cpp b/src/server/scripts/EasternKingdoms/zone_undercity.cpp index 8baeaec96ff..41e6bafd4a7 100644 --- a/src/server/scripts/EasternKingdoms/zone_undercity.cpp +++ b/src/server/scripts/EasternKingdoms/zone_undercity.cpp @@ -81,8 +81,8 @@ public: { if (_Quest->GetQuestId() == QUEST_JOURNEY_TO_UNDERCITY) { - CAST_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->LamentEvent = true; - CAST_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->DoPlaySoundToSet(creature, SOUND_CREDIT); + ENSURE_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->LamentEvent = true; + ENSURE_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->DoPlaySoundToSet(creature, SOUND_CREDIT); creature->CastSpell(creature, SPELL_SYLVANAS_CAST, false); for (uint8 i = 0; i < 4; ++i) diff --git a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp index 0839a476941..dbcf5998bdb 100644 --- a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp +++ b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp @@ -304,10 +304,11 @@ public: bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override { - npc_escortAI* pEscortAI = CAST_AI(npc_anchorite_truuen::npc_anchorite_truuenAI, creature->AI()); - if (quest->GetQuestId() == QUEST_TOMB_LIGHTBRINGER) + { + npc_escortAI* pEscortAI = ENSURE_AI(npc_anchorite_truuen::npc_anchorite_truuenAI, creature->AI()); pEscortAI->Start(true, true, player->GetGUID()); + } return false; } diff --git a/src/server/scripts/Events/childrens_week.cpp b/src/server/scripts/Events/childrens_week.cpp index c9798338b36..25257848192 100644 --- a/src/server/scripts/Events/childrens_week.cpp +++ b/src/server/scripts/Events/childrens_week.cpp @@ -193,7 +193,7 @@ class npc_winterfin_playmate : public CreatureScript switch (phase) { case 1: - orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); + orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ()); orphan->AI()->Talk(TEXT_ORACLE_ORPHAN_1); timer = 3000; break; @@ -292,7 +292,7 @@ class npc_snowfall_glade_playmate : public CreatureScript switch (phase) { case 1: - orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); + orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ()); orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_1); timer = 5000; break; @@ -393,7 +393,7 @@ class npc_the_biggest_tree : public CreatureScript switch (phase) { case 1: - orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); + orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ()); timer = 2000; break; case 2: @@ -480,7 +480,7 @@ class npc_high_oracle_soo_roo : public CreatureScript switch (phase) { case 1: - orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); + orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ()); orphan->AI()->Talk(TEXT_ORACLE_ORPHAN_5); timer = 3000; break; @@ -569,7 +569,7 @@ class npc_elder_kekek : public CreatureScript switch (phase) { case 1: - orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); + orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ()); orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_4); timer = 3000; break; @@ -658,7 +658,7 @@ class npc_the_etymidian : public CreatureScript switch (phase) { case 1: - orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); + orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ()); orphan->AI()->Talk(TEXT_ORACLE_ORPHAN_7); timer = 5000; break; @@ -780,7 +780,7 @@ class npc_alexstraza_the_lifebinder : public CreatureScript switch (phase) { case 1: - orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); + orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ()); orphan->AI()->Talk(TEXT_ORACLE_ORPHAN_11); timer = 5000; break; @@ -811,7 +811,7 @@ class npc_alexstraza_the_lifebinder : public CreatureScript Reset(); return; case 7: - orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); + orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ()); orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_11); timer = 5000; break; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp index ede038863fc..4a92041f921 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp @@ -56,7 +56,7 @@ public: bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override { player->PlayerTalkClass->ClearMenus(); - hyjalAI* ai = CAST_AI(hyjalAI, creature->AI()); + hyjalAI* ai = ENSURE_AI(hyjalAI, creature->AI()); switch (action) { case GOSSIP_ACTION_INFO_DEF + 1: @@ -80,7 +80,7 @@ public: bool OnGossipHello(Player* player, Creature* creature) override { - hyjalAI* ai = CAST_AI(hyjalAI, creature->AI()); + hyjalAI* ai = ENSURE_AI(hyjalAI, creature->AI()); if (ai->EventBegun) return false; @@ -135,7 +135,7 @@ public: bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override { player->PlayerTalkClass->ClearMenus(); - hyjalAI* ai = CAST_AI(hyjalAI, creature->AI()); + hyjalAI* ai = ENSURE_AI(hyjalAI, creature->AI()); ai->DeSpawnVeins();//despawn the alliance veins switch (action) { @@ -160,7 +160,7 @@ public: bool OnGossipHello(Player* player, Creature* creature) override { - hyjalAI* ai = CAST_AI(hyjalAI, creature->AI()); + hyjalAI* ai = ENSURE_AI(hyjalAI, creature->AI()); if (ai->EventBegun) return false; @@ -242,7 +242,7 @@ public: bool OnGossipHello(Player* player, Creature* creature) override { - hyjalAI* ai = CAST_AI(hyjalAI, creature->AI()); + hyjalAI* ai = ENSURE_AI(hyjalAI, creature->AI()); uint32 AzgalorEvent = ai->GetInstanceData(DATA_AZGALOREVENT); // Only let them get item if Azgalor is dead. diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp index 316834c422a..b9c6025b91c 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp @@ -460,7 +460,7 @@ void hyjalAI::SummonCreature(uint32 entry, float Base[4][3]) {//summon at tower creature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_NEAR_TOWER][0]+irand(-20, 20), SpawnPointSpecial[SPAWN_NEAR_TOWER][1]+irand(-20, 20), SpawnPointSpecial[SPAWN_NEAR_TOWER][2]+irand(-10, 10), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); if (creature) - CAST_AI(hyjal_trashAI, creature->AI())->useFlyPath = true; + ENSURE_AI(hyjal_trashAI, creature->AI())->useFlyPath = true; } else {//summon at gate @@ -474,7 +474,7 @@ void hyjalAI::SummonCreature(uint32 entry, float Base[4][3]) { creature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_NEAR_TOWER][0], SpawnPointSpecial[SPAWN_NEAR_TOWER][1], SpawnPointSpecial[SPAWN_NEAR_TOWER][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); if (creature) - CAST_AI(hyjal_trashAI, creature->AI())->useFlyPath = true; + ENSURE_AI(hyjal_trashAI, creature->AI())->useFlyPath = true; } break; case 17908: //GIANT_INFERNAL @@ -511,7 +511,7 @@ void hyjalAI::SummonCreature(uint32 entry, float Base[4][3]) case ANETHERON: case KAZROGAL: case AZGALOR: - CAST_AI(hyjal_trashAI, creature->AI())->IsEvent = true; + ENSURE_AI(hyjal_trashAI, creature->AI())->IsEvent = true; break; } if (instance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE) @@ -623,7 +623,7 @@ void hyjalAI::Retreat() if (JainaDummy) { JainaDummy->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - CAST_AI(hyjalAI, JainaDummy->AI())->IsDummy = true; + ENSURE_AI(hyjalAI, JainaDummy->AI())->IsDummy = true; DummyGuid = JainaDummy->GetGUID(); } AddWaypoint(0, JainaDummySpawn[1][0], JainaDummySpawn[1][1], JainaDummySpawn[1][2]); @@ -939,7 +939,7 @@ void hyjalAI::WaypointReached(uint32 waypointId) { if (Creature* creature = ObjectAccessor::GetCreature(*me, DummyGuid)) { - hyjalAI* ai = CAST_AI(hyjalAI, creature->AI()); + hyjalAI* ai = ENSURE_AI(hyjalAI, creature->AI()); ai->DoMassTeleport = true; ai->MassTeleportTimer = 20000; creature->CastSpell(me, SPELL_MASS_TELEPORT, false); @@ -1036,9 +1036,9 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) Creature* unit = me->SummonCreature(GHOUL, AllianceBase[r][0]+irand(-15, 15), AllianceBase[r][1]+irand(-15, 15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); if (unit) { - CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + ENSURE_AI(hyjal_trashAI, unit->AI())->faction = Faction; + ENSURE_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + ENSURE_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } @@ -1048,9 +1048,9 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) Creature* unit = me->SummonCreature(ABOMINATION, AllianceBase[r][0]+irand(-15, 15), AllianceBase[r][1]+irand(-15, 15), AllianceBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); if (unit) { - CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + ENSURE_AI(hyjal_trashAI, unit->AI())->faction = Faction; + ENSURE_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + ENSURE_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } @@ -1060,9 +1060,9 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) if (unit) { unit->SetHomePosition(AllianceOverrunGargPos[i][0], AllianceOverrunGargPos[i][1], AllianceOverrunGargPos[i][2], AllianceOverrunGargPos[i][3]); - CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + ENSURE_AI(hyjal_trashAI, unit->AI())->faction = Faction; + ENSURE_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + ENSURE_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } @@ -1077,9 +1077,9 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) if (unit) { unit->SetHomePosition(InfernalSPWP[i][0], InfernalSPWP[i][1], InfernalSPWP[i][2], InfernalSPWP[i][3]); - CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + ENSURE_AI(hyjal_trashAI, unit->AI())->faction = Faction; + ENSURE_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + ENSURE_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } @@ -1089,9 +1089,9 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) Creature* unit = me->SummonCreature(GHOUL, HordeBase[r][0]+irand(-15, 15), HordeBase[r][1]+irand(-15, 15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); if (unit) { - CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + ENSURE_AI(hyjal_trashAI, unit->AI())->faction = Faction; + ENSURE_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + ENSURE_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } @@ -1101,9 +1101,9 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff) Creature* unit = me->SummonCreature(ABOMINATION, HordeBase[r][0]+irand(-15, 15), HordeBase[r][1]+irand(-15, 15), HordeBase[r][2], 0, TEMPSUMMON_MANUAL_DESPAWN, 2*60*1000); if (unit) { - CAST_AI(hyjal_trashAI, unit->AI())->faction = Faction; - CAST_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; - CAST_AI(hyjal_trashAI, unit->AI())->OverrunType = i; + ENSURE_AI(hyjal_trashAI, unit->AI())->faction = Faction; + ENSURE_AI(hyjal_trashAI, unit->AI())->IsOverrun = true; + ENSURE_AI(hyjal_trashAI, unit->AI())->OverrunType = i; unit->setActive(true); } } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp index 3a5025695f8..7537654c09c 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -1184,7 +1184,7 @@ public: if (IsEvent || IsOverrun) { - CAST_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); + ENSURE_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); npc_escortAI::UpdateAI(diff); } @@ -1301,7 +1301,7 @@ public: if (IsEvent || IsOverrun) { - CAST_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); + ENSURE_AI(hyjal_trashAI, me->AI())->SetCanAttack(false); npc_escortAI::UpdateAI(diff); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp index da40ec333a6..1dc86cd4ad4 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -209,9 +209,9 @@ public: if (npc_escortAI* pEscortAI = CAST_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, creature->AI())) pEscortAI->Start(true, true, player->GetGUID()); - CAST_AI(npc_escortAI, (creature->AI()))->SetMaxPlayerDistance(100.0f);//not really needed, because it will not despawn if player is too far - CAST_AI(npc_escortAI, (creature->AI()))->SetDespawnAtEnd(false); - CAST_AI(npc_escortAI, (creature->AI()))->SetDespawnAtFar(false); + ENSURE_AI(npc_escortAI, (creature->AI()))->SetMaxPlayerDistance(100.0f);//not really needed, because it will not despawn if player is too far + ENSURE_AI(npc_escortAI, (creature->AI()))->SetDespawnAtEnd(false); + ENSURE_AI(npc_escortAI, (creature->AI()))->SetDespawnAtFar(false); break; case GOSSIP_ACTION_INFO_DEF+2: @@ -227,14 +227,14 @@ public: creature->AI()->Talk(SAY_TH_START_EVENT_PART2); - CAST_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, creature->AI())->StartWP(); + ENSURE_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, creature->AI())->StartWP(); break; case GOSSIP_ACTION_INFO_DEF+3: player->CLOSE_GOSSIP_MENU(); if (instance) instance->SetData(TYPE_THRALL_PART3, IN_PROGRESS); - CAST_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, creature->AI())->StartWP(); + ENSURE_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, creature->AI())->StartWP(); break; } return true; @@ -423,7 +423,7 @@ public: if (Creature* Taretha = instance->instance->GetCreature(instance->GetData64(DATA_TARETHA))) { if (Player* player = GetPlayerForEscort()) - CAST_AI(npc_escortAI, (Taretha->AI()))->Start(false, true, player->GetGUID()); + ENSURE_AI(npc_escortAI, (Taretha->AI()))->Start(false, true, player->GetGUID()); } //kill credit Creature for quest @@ -586,7 +586,7 @@ public: creature->SummonCreature(ENTRY_EPOCH, 2639.13f, 698.55f, 65.43f, 4.59f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); if (Creature* thrall = (ObjectAccessor::GetCreature(*creature, instance->GetData64(DATA_THRALL)))) - CAST_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, thrall->AI())->StartWP(); + ENSURE_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, thrall->AI())->StartWP(); } } return true; diff --git a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp index 100d14b756b..d76de6eeb42 100644 --- a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp +++ b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp @@ -574,12 +574,12 @@ class spell_alysrazor_turn_monstrosity : public SpellScriptLoader case SPELL_RIGHT_SIDE_SMACK_R: case SPELL_RIGHT_SIDE_SMACK_L: spellId = SPELL_KNOCKBACK_RIGHT; - angle -= M_PI * 0.5f; + angle -= float(M_PI) * 0.5f; break; case SPELL_LEFT_SIDE_SMACK_R: case SPELL_LEFT_SIDE_SMACK_L: spellId = SPELL_KNOCKBACK_LEFT; - angle += M_PI * 0.5f; + angle += float(M_PI) * 0.5f; break; case SPELL_HEAD_BONK_R: case SPELL_HEAD_BONK_L: @@ -588,7 +588,7 @@ class spell_alysrazor_turn_monstrosity : public SpellScriptLoader case SPELL_TICKLE_R: case SPELL_TICKLE_L: spellId = SPELL_KNOCKBACK_BACK; - angle -= M_PI; + angle -= float(M_PI); break; } diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp index ef6d7da5116..ce9ed4f36c8 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp +++ b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp @@ -280,8 +280,8 @@ public: me->SummonCreature(NPC_WITHERED_BATTLE_BOAR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); if (data > 0 && me->GetOrientation() < 4.0f) me->SummonCreature(NPC_WITHERED_BATTLE_BOAR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - me->SummonCreature(NPC_DEATHS_HEAD_GEOMANCER, me->GetPositionX() + (cos(me->GetOrientation() - (M_PI/2)) * 2), me->GetPositionY() + (sin(me->GetOrientation() - (M_PI/2)) * 2), me->GetPositionZ(), me->GetOrientation()); - me->SummonCreature(NPC_WITHERED_QUILGUARD, me->GetPositionX() + (cos(me->GetOrientation() + (M_PI/2)) * 2), me->GetPositionY() + (sin(me->GetOrientation() + (M_PI/2)) * 2), me->GetPositionZ(), me->GetOrientation()); + me->SummonCreature(NPC_DEATHS_HEAD_GEOMANCER, me->GetPositionX() + (std::cos(me->GetOrientation() - (float(M_PI) / 2)) * 2), me->GetPositionY() + (std::sin(me->GetOrientation() - (float(M_PI) / 2)) * 2), me->GetPositionZ(), me->GetOrientation()); + me->SummonCreature(NPC_WITHERED_QUILGUARD, me->GetPositionX() + (std::cos(me->GetOrientation() + (float(M_PI) / 2)) * 2), me->GetPositionY() + (std::sin(me->GetOrientation() + (float(M_PI) / 2)) * 2), me->GetPositionZ(), me->GetOrientation()); } else if (data == 7) me->SummonCreature(NPC_PLAGUEMAW_THE_ROTTING, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); diff --git a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp index 835fd6228e1..e3021ff7a95 100644 --- a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp +++ b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp @@ -47,27 +47,20 @@ class npc_willix : public CreatureScript public: npc_willix() : CreatureScript("npc_willix") { } - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_WILLIX_THE_IMPORTER) - { - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - creature->AI()->Talk(SAY_READY, player); - creature->setFaction(113); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_willixAI(creature); - } - struct npc_willixAI : public npc_escortAI { npc_willixAI(Creature* creature) : npc_escortAI(creature) { } + void sQuestAccept(Player* player, Quest const* quest) override + { + if (quest->GetQuestId() == QUEST_WILLIX_THE_IMPORTER) + { + Start(true, false, player->GetGUID()); + Talk(SAY_READY, player); + me->setFaction(113); + } + } + void WaypointReached(uint32 waypointId) override { Player* player = GetPlayerForEscort(); @@ -137,6 +130,10 @@ public: } }; + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_willixAI(creature); + } }; enum SnufflenoseGopher @@ -147,18 +144,6 @@ enum SnufflenoseGopher POINT_TUBBER = 0 }; -struct DistanceOrder : public std::binary_function<GameObject, GameObject, bool> -{ - DistanceOrder(Creature* me) : me(me) { } - - bool operator() (GameObject* first, GameObject* second) - { - return me->GetDistanceOrder(first, second); - } - - Creature* me; -}; - struct npc_snufflenose_gopher : public CreatureScript { public: @@ -208,18 +193,14 @@ public: if (tubbersInRange.empty()) return; - tubbersInRange.sort(DistanceOrder(me)); - GameObject* nearestTubber = NULL; - - for (std::list<GameObject*>::const_iterator itr = tubbersInRange.begin(); itr != tubbersInRange.end(); ++itr) + tubbersInRange.remove_if([](GameObject* go) { - if (!(*itr)->isSpawned() && (*itr)->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND)) - { - nearestTubber = *itr; - break; - } - } + return go->isSpawned() || !go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); + }); + tubbersInRange.sort(Trinity::ObjectDistanceOrderPred(me)); + + GameObject* nearestTubber = tubbersInRange.front(); if (!nearestTubber) return; @@ -259,21 +240,16 @@ class spell_snufflenose_command : public SpellScriptLoader { PrepareSpellScript(spell_snufflenose_commandSpellScript); - bool Load() override - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - void HandleAfterCast() + void HandleEffect(SpellEffIndex /*effIndex*/) { - if (Unit* target = GetCaster()->ToPlayer()->GetSelectedUnit()) + if (Creature* target = GetHitCreature()) if (target->GetEntry() == NPC_SNUFFLENOSE_GOPHER) - target->ToCreature()->AI()->DoAction(ACTION_FIND_NEW_TUBBER); + target->AI()->DoAction(ACTION_FIND_NEW_TUBBER); } void Register() override { - AfterCast += SpellCastFn(spell_snufflenose_commandSpellScript::HandleAfterCast); + OnEffectHitTarget += SpellEffectFn(spell_snufflenose_commandSpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp index dd0c93e8a28..2cfd977fe99 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp @@ -334,9 +334,9 @@ public: { //Set angle and cast if (ClockWise) - me->SetOrientation(DarkGlareAngle + DarkGlareTick * M_PI / 35); + me->SetOrientation(DarkGlareAngle + DarkGlareTick * float(M_PI) / 35); else - me->SetOrientation(DarkGlareAngle - DarkGlareTick * M_PI / 35); + me->SetOrientation(DarkGlareAngle - DarkGlareTick * float(M_PI) / 35); me->StopMoving(); diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp index c5011eba2f8..3e02406b93d 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp @@ -131,7 +131,7 @@ struct boss_twinemperorsAI : public ScriptedAI pOtherBoss->SetHealth(0); pOtherBoss->setDeathState(JUST_DIED); pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); - CAST_AI(boss_twinemperorsAI, pOtherBoss->AI())->DontYellWhenDead = true; + ENSURE_AI(boss_twinemperorsAI, pOtherBoss->AI())->DontYellWhenDead = true; } if (!DontYellWhenDead) // I hope AI is not threaded DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_DEATH : SOUND_VN_DEATH); @@ -150,9 +150,9 @@ struct boss_twinemperorsAI : public ScriptedAI { /// @todo we should activate the other boss location so he can start attackning even if nobody // is near I dont know how to do that - ScriptedAI* otherAI = CAST_AI(ScriptedAI, pOtherBoss->AI()); if (!pOtherBoss->IsInCombat()) { + ScriptedAI* otherAI = ENSURE_AI(ScriptedAI, pOtherBoss->AI()); DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_AGGRO : SOUND_VN_AGGRO); otherAI->AttackStart(who); otherAI->DoZoneInCombat(); @@ -224,7 +224,7 @@ struct boss_twinemperorsAI : public ScriptedAI me->SetPosition(otherPos); SetAfterTeleport(); - CAST_AI(boss_twinemperorsAI, pOtherBoss->AI())->SetAfterTeleport(); + ENSURE_AI(boss_twinemperorsAI, pOtherBoss->AI())->SetAfterTeleport(); } } diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp index d49a6a312da..a9ec3007e5d 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp @@ -120,7 +120,7 @@ class boss_viscidus : public CreatureScript uint8 NumGlobes = me->GetHealthPct() / 5.0f; for (uint8 i = 0; i < NumGlobes; ++i) { - float Angle = i * 2 * M_PI / NumGlobes; + float Angle = i * 2 * float(M_PI) / NumGlobes; float X = ViscidusCoord.GetPositionX() + std::cos(Angle) * RoomRadius; float Y = ViscidusCoord.GetPositionY() + std::sin(Angle) * RoomRadius; float Z = -35.0f; diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/mob_anubisath_sentinel.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/mob_anubisath_sentinel.cpp index e41fbb7d90d..a0d57481c75 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/mob_anubisath_sentinel.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/mob_anubisath_sentinel.cpp @@ -122,7 +122,7 @@ public: void GiveBuddyMyList(Creature* c) { - aqsentinelAI* cai = CAST_AI(aqsentinelAI, (c)->AI()); + aqsentinelAI* cai = ENSURE_AI(aqsentinelAI, (c)->AI()); for (int i=0; i<3; ++i) if (NearbyGUID[i] && NearbyGUID[i] != c->GetGUID()) cai->AddBuddyToList(NearbyGUID[i]); @@ -200,8 +200,8 @@ public: break; AddSentinelsNear(pNearby); - CAST_AI(aqsentinelAI, pNearby->AI())->gatherOthersWhenAggro = false; - CAST_AI(aqsentinelAI, pNearby->AI())->selectAbility(pickAbilityRandom(chosenAbilities)); + ENSURE_AI(aqsentinelAI, pNearby->AI())->gatherOthersWhenAggro = false; + ENSURE_AI(aqsentinelAI, pNearby->AI())->selectAbility(pickAbilityRandom(chosenAbilities)); } /*if (bli < 3) DoYell("I dont have enough buddies.", LANG_NEUTRAL, 0);*/ @@ -256,7 +256,7 @@ public: if (sent->isDead()) continue; sent->ModifyHealth(int32(sent->CountPctFromMaxHealth(50))); - CAST_AI(aqsentinelAI, sent->AI())->GainSentinelAbility(ability); + ENSURE_AI(aqsentinelAI, sent->AI())->GainSentinelAbility(ability); } } }; diff --git a/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp b/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp index 516da307bfd..bb872421197 100644 --- a/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp +++ b/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp @@ -99,9 +99,9 @@ public: creature->setFaction(250); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - CAST_AI(npc_escortAI, (creature->AI()))->Start(false, false, player->GetGUID()); - CAST_AI(npc_escortAI, (creature->AI()))->SetDespawnAtFar(false); - CAST_AI(npc_escortAI, (creature->AI()))->SetDespawnAtEnd(false); + ENSURE_AI(npc_escortAI, (creature->AI()))->Start(false, false, player->GetGUID()); + ENSURE_AI(npc_escortAI, (creature->AI()))->SetDespawnAtFar(false); + ENSURE_AI(npc_escortAI, (creature->AI()))->SetDespawnAtEnd(false); } return true; } diff --git a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp index 04be688d8aa..7c02ecdb8f2 100644 --- a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp +++ b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp @@ -70,7 +70,7 @@ public: if (action == GOSSIP_ACTION_INFO_DEF+1) { player->CLOSE_GOSSIP_MENU(); - CAST_AI(npc_sergeant_bly::npc_sergeant_blyAI, creature->AI())->PlayerGUID = player->GetGUID(); + ENSURE_AI(npc_sergeant_bly::npc_sergeant_blyAI, creature->AI())->PlayerGUID = player->GetGUID(); creature->AI()->DoAction(0); } return true; diff --git a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp index c3c1d7c146b..9d906acb312 100644 --- a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp +++ b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp @@ -720,7 +720,7 @@ class go_bristlelimb_cage : public GameObjectScript if (Creature* capitive = go->FindNearestCreature(NPC_STILLPINE_CAPITIVE, 5.0f, true)) { go->ResetDoorOrButton(); - CAST_AI(npc_stillpine_capitive::npc_stillpine_capitiveAI, capitive->AI())->StartMoving(player); + ENSURE_AI(npc_stillpine_capitive::npc_stillpine_capitiveAI, capitive->AI())->StartMoving(player); return false; } } diff --git a/src/server/scripts/Kalimdor/zone_silithus.cpp b/src/server/scripts/Kalimdor/zone_silithus.cpp index c024c1a567a..98256006fd3 100644 --- a/src/server/scripts/Kalimdor/zone_silithus.cpp +++ b/src/server/scripts/Kalimdor/zone_silithus.cpp @@ -1258,7 +1258,7 @@ class go_wind_stone : public GameObjectScript void SummonNPC(GameObject* go, Player* player, uint32 npc, uint32 spell) { go->CastSpell(player, spell); - TempSummon* summons = go->SummonCreature(npc, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), player->GetOrientation() - M_PI, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10 * 60 * 1000); + TempSummon* summons = go->SummonCreature(npc, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), player->GetOrientation() - float(M_PI), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10 * 60 * 1000); summons->CastSpell(summons, SPELL_SPAWN_IN, false); switch (summons->GetEntry()) { diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp index b78bdae5c87..bc6807c54d9 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp @@ -373,8 +373,8 @@ public: { if (Creature* boss = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_JEDOGA_SHADOWSEEKER))) { - if (!CAST_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok) - CAST_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = true; + if (!ENSURE_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok) + ENSURE_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = true; if (killer->GetTypeId() == TYPEID_PLAYER) boss->AI()->DoAction(ACTION_INITIAND_KILLED); @@ -421,8 +421,8 @@ public: Creature* boss = me->GetMap()->GetCreature(instance->GetData64(DATA_JEDOGA_SHADOWSEEKER)); if (boss) { - CAST_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok = true; - CAST_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = false; + ENSURE_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok = true; + ENSURE_AI(boss_jedoga_shadowseeker::boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = false; me->Kill(me); } } diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp index e3156e21371..9cc8540342f 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -50,7 +50,7 @@ enum Misc }; #define DATA_SPHERE_DISTANCE 25.0f -#define DATA_SPHERE_ANGLE_OFFSET M_PI / 2 +#define DATA_SPHERE_ANGLE_OFFSET float(M_PI) / 2 #define DATA_GROUND_POSITION_Z 11.30809f enum Yells @@ -403,7 +403,7 @@ class go_prince_taldaram_sphere : public GameObjectScript break; } - CAST_AI(boss_prince_taldaram::boss_prince_taldaramAI, PrinceTaldaram->AI())->CheckSpheres(); + ENSURE_AI(boss_prince_taldaram::boss_prince_taldaramAI, PrinceTaldaram->AI())->CheckSpheres(); } return true; } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp index e22ee040599..e0930a1ae2e 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp @@ -289,13 +289,13 @@ public: switch (i) { case 0: - pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, M_PI); + pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, float(M_PI)); break; case 1: - pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, M_PI / 2); + pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, float(M_PI) / 2); break; case 2: - pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, M_PI / 2 + M_PI); + pAdd->GetMotionMaster()->MoveFollow(pBoss, 2.0f, float(M_PI) / 2 + float(M_PI)); break; } } @@ -494,7 +494,7 @@ public: if (action == GOSSIP_ACTION_INFO_DEF+1) { player->CLOSE_GOSSIP_MENU(); - CAST_AI(npc_announcer_toc5::npc_announcer_toc5AI, creature->AI())->StartEncounter(); + ENSURE_AI(npc_announcer_toc5::npc_announcer_toc5AI, creature->AI())->StartEncounter(); } return true; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index e40cd9d5f41..68de65f9f7b 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -531,8 +531,8 @@ struct npc_unleashed_ballAI : public ScriptedAI float x0 = ToCCommonLoc[1].GetPositionX(), y0 = ToCCommonLoc[1].GetPositionY(), r = 47.0f; float y = y0; float x = frand(x0 - r, x0 + r); - float sq = pow(r, 2) - pow(x - x0, 2); - float rt = sqrtf(fabs(sq)); + float sq = std::pow(r, 2.f) - std::pow(x - x0, 2.f); + float rt = std::sqrt(std::fabs(sq)); if (urand(0, 1)) y = y0 + rt; else @@ -756,7 +756,7 @@ class spell_valkyr_essences : public SpellScriptLoader // Twin Vortex part uint32 lightVortex = sSpellMgr->GetSpellIdForDifficulty(SPELL_LIGHT_VORTEX_DAMAGE, owner); uint32 darkVortex = sSpellMgr->GetSpellIdForDifficulty(SPELL_DARK_VORTEX_DAMAGE, owner); - int32 stacksCount = int32(dmgInfo.GetSpellInfo()->Effects[EFFECT_0].CalcValue()) * 0.001 - 1; + int32 stacksCount = dmgInfo.GetSpellInfo()->Effects[EFFECT_0].CalcValue() / 1000 - 1; if (lightVortex && darkVortex && stacksCount) { @@ -837,7 +837,7 @@ class spell_power_of_the_twins : public SpellScriptLoader if (InstanceScript* instance = GetCaster()->GetInstanceScript()) { if (Creature* Valk = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(GetCaster()->GetEntry()))) - CAST_AI(boss_twin_baseAI, Valk->AI())->EnableDualWield(true); + ENSURE_AI(boss_twin_baseAI, Valk->AI())->EnableDualWield(true); } } @@ -846,7 +846,7 @@ class spell_power_of_the_twins : public SpellScriptLoader if (InstanceScript* instance = GetCaster()->GetInstanceScript()) { if (Creature* Valk = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(GetCaster()->GetEntry()))) - CAST_AI(boss_twin_baseAI, Valk->AI())->EnableDualWield(false); + ENSURE_AI(boss_twin_baseAI, Valk->AI())->EnableDualWield(false); } } diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp index e64067fb995..a048abd6554 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp @@ -292,7 +292,7 @@ class boss_devourer_of_souls : public CreatureScript beamAngle = me->GetOrientation(); - beamAngleDiff = M_PI/30.0f; // PI/2 in 15 sec = PI/30 per tick + beamAngleDiff = float(M_PI)/30.0f; // PI/2 in 15 sec = PI/30 per tick if (RAND(true, false)) beamAngleDiff = -beamAngleDiff; diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp index 1c126bc54fd..3f8e1cc6ee0 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp @@ -624,7 +624,7 @@ class spell_krick_pursuit : public SpellScriptLoader { ick->AI()->Talk(SAY_ICK_CHASE_1, target); ick->AddAura(GetSpellInfo()->Id, target); - CAST_AI(boss_ick::boss_ickAI, ick->AI())->SetTempThreat(ick->getThreatManager().getThreat(target)); + ENSURE_AI(boss_ick::boss_ickAI, ick->AI())->SetTempThreat(ick->getThreatManager().getThreat(target)); ick->AddThreat(target, float(GetEffectValue())); target->AddThreat(ick, float(GetEffectValue())); } @@ -645,7 +645,7 @@ class spell_krick_pursuit : public SpellScriptLoader { if (Unit* caster = GetCaster()) if (Creature* creCaster = caster->ToCreature()) - CAST_AI(boss_ick::boss_ickAI, creCaster->AI())->_ResetThreat(GetTarget()); + ENSURE_AI(boss_ick::boss_ickAI, creCaster->AI())->_ResetThreat(GetTarget()); } void Register() override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index e1658e564ec..5ef84c7bb40 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -299,6 +299,12 @@ class boss_deathbringer_saurfang : public CreatureScript _introDone = true; + if (GameObject* teleporter = GameObject::GetGameObject(*me, instance->GetData64(GO_SCOURGE_TRANSPORTER_DEATHBRINGER))) + { + instance->HandleGameObject(0, false, teleporter); + teleporter->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } + Talk(SAY_AGGRO); events.ScheduleEvent(EVENT_SUMMON_BLOOD_BEAST, 30000, 0, PHASE_COMBAT); events.ScheduleEvent(EVENT_BERSERK, IsHeroic() ? 360000 : 480000, 0, PHASE_COMBAT); @@ -538,12 +544,6 @@ class boss_deathbringer_saurfang : public CreatureScript case PHASE_INTRO_A: case PHASE_INTRO_H: { - if (GameObject* teleporter = GameObject::GetGameObject(*me, instance->GetData64(GO_SCOURGE_TRANSPORTER_SAURFANG))) - { - instance->HandleGameObject(0, false, teleporter); - teleporter->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // controls what events will execute events.SetPhase(uint32(action)); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp index a0f6039d703..535ace3259c 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -205,8 +205,8 @@ enum EncounterActions ACTION_SHIP_VISITS = 5 }; -Position const SkybreakerAddsSpawnPos = { 15.91131f, 0.0f, 20.4628f, M_PI }; -Position const OrgrimsHammerAddsSpawnPos = { 60.728395f, 0.0f, 38.93467f, M_PI }; +Position const SkybreakerAddsSpawnPos = { 15.91131f, 0.0f, 20.4628f, float(M_PI) }; +Position const OrgrimsHammerAddsSpawnPos = { 60.728395f, 0.0f, 38.93467f, float(M_PI) }; // Horde encounter Position const SkybreakerTeleportPortal = { 6.666975f, 0.013001f, 20.87888f, 0.0f }; @@ -439,7 +439,7 @@ private: Position SelectSpawnPoint() const { Position newPos; - float angle = frand(-M_PI * 0.5f, M_PI * 0.5f); + float angle = frand(float(-M_PI) * 0.5f, float(M_PI) * 0.5f); newPos.m_positionX = _spawnPoint->GetPositionX() + 2.0f * std::cos(angle); newPos.m_positionY = _spawnPoint->GetPositionY() + 2.0f * std::sin(angle); newPos.m_positionZ = _spawnPoint->GetPositionZ(); @@ -1455,7 +1455,7 @@ struct npc_gunship_boarding_addAI : public gunship_npc_AI if (Transport* destTransport = go->ToTransport()) destTransport->CalculatePassengerPosition(x, y, z, &o); - float angle = frand(0, M_PI * 2.0f); + float angle = frand(0, float(M_PI) * 2.0f); x += 2.0f * std::cos(angle); y += 2.0f * std::sin(angle); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 5022cd4f645..1ff7e1b1352 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -674,7 +674,7 @@ class spell_marrowgar_bone_storm : public SpellScriptLoader void RecalculateDamage() { - SetHitDamage(int32(GetHitDamage() / std::max(sqrtf(GetHitUnit()->GetExactDist2d(GetCaster())), 1.0f))); + SetHitDamage(int32(GetHitDamage() / std::max(std::sqrt(GetHitUnit()->GetExactDist2d(GetCaster())), 1.0f))); } void Register() override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 592c44940a4..e85ddc21dda 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -2102,7 +2102,15 @@ class at_icc_shutdown_traps : public AreaTriggerScript bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override { if (InstanceScript* instance = player->GetInstanceScript()) - instance->SetData(DATA_COLDFLAME_JETS, DONE); + { + instance->SetData(DATA_UPPERSPIRE_TELE_ACT, DONE); + uint64 teleporterGUID = instance->GetData64(GO_SCOURGE_TRANSPORTER_UPPERSPIRE); + if (GameObject* go = instance->instance->GetGameObject(teleporterGUID)) + { + go->SetGoState(GO_STATE_ACTIVE); + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } + } return true; } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index da4a8f089cc..fbd3a715fb8 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -116,7 +116,8 @@ enum DataTypes DATA_HIGHLORD_TIRION_FORDRING = 37, DATA_ARTHAS_PLATFORM = 38, DATA_TERENAS_MENETHIL = 39, - DATA_ENEMY_GUNSHIP = 40 + DATA_ENEMY_GUNSHIP = 40, + DATA_UPPERSPIRE_TELE_ACT = 41, }; enum CreaturesIds @@ -322,6 +323,15 @@ enum CreaturesIds enum GameObjectsIds { + // ICC Teleporters + GO_SCOURGE_TRANSPORTER_LICHKING = 202223, + GO_SCOURGE_TRANSPORTER_UPPERSPIRE = 202235, + GO_SCOURGE_TRANSPORTER_LIGHTSHAMMER = 202242, + GO_SCOURGE_TRANSPORTER_RAMPART = 202243, + GO_SCOURGE_TRANSPORTER_DEATHBRINGER = 202244, + GO_SCOURGE_TRANSPORTER_ORATORY = 202245, + GO_SCOURGE_TRANSPORTER_SINDRAGOSA = 202246, + // Lower Spire Trash GO_SPIRIT_ALARM_1 = 201814, GO_SPIRIT_ALARM_2 = 201815, @@ -359,7 +369,6 @@ enum GameObjectsIds GO_DEATHBRINGER_S_CACHE_25N = 202240, GO_DEATHBRINGER_S_CACHE_10H = 202238, GO_DEATHBRINGER_S_CACHE_25H = 202241, - GO_SCOURGE_TRANSPORTER_SAURFANG = 202244, // Professor Putricide GO_ORANGE_PLAGUE_MONSTER_ENTRANCE = 201371, @@ -404,7 +413,6 @@ enum GameObjectsIds GO_SIGIL_OF_THE_FROSTWING = 202181, // The Lich King - GO_SCOURGE_TRANSPORTER_LK = 202223, GO_ARTHAS_PLATFORM = 202161, GO_ARTHAS_PRECIPICE = 202078, GO_DOODAD_ICECROWN_THRONEFROSTYWIND01 = 202188, diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp index 537c3c7354d..469bfc1d310 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp @@ -31,19 +31,23 @@ class icecrown_citadel_teleport : public GameObjectScript bool OnGossipHello(Player* player, GameObject* go) override { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to Light's Hammer.", GOSSIP_SENDER_ICC_PORT, LIGHT_S_HAMMER_TELEPORT); if (InstanceScript* instance = go->GetInstanceScript()) { if (instance->GetBossState(DATA_LORD_MARROWGAR) == DONE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Oratory of the Damned.", GOSSIP_SENDER_ICC_PORT, ORATORY_OF_THE_DAMNED_TELEPORT); - if (instance->GetBossState(DATA_LADY_DEATHWHISPER) == DONE) + { + if (go->GetEntry() != GO_SCOURGE_TRANSPORTER_LIGHTSHAMMER) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to Light's Hammer.", GOSSIP_SENDER_ICC_PORT, LIGHT_S_HAMMER_TELEPORT); + if (go->GetEntry() != GO_SCOURGE_TRANSPORTER_ORATORY) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Oratory of the Damned.", GOSSIP_SENDER_ICC_PORT, ORATORY_OF_THE_DAMNED_TELEPORT); + } + if (instance->GetBossState(DATA_LADY_DEATHWHISPER) == DONE && go->GetEntry() != GO_SCOURGE_TRANSPORTER_RAMPART) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Rampart of Skulls.", GOSSIP_SENDER_ICC_PORT, RAMPART_OF_SKULLS_TELEPORT); - if (instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE) + if (instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE && go->GetEntry() != GO_SCOURGE_TRANSPORTER_DEATHBRINGER) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Deathbringer's Rise.", GOSSIP_SENDER_ICC_PORT, DEATHBRINGER_S_RISE_TELEPORT); - if (instance->GetData(DATA_COLDFLAME_JETS) == DONE) + if (instance->GetData(DATA_UPPERSPIRE_TELE_ACT) == DONE && go->GetEntry() != GO_SCOURGE_TRANSPORTER_UPPERSPIRE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Upper Spire.", GOSSIP_SENDER_ICC_PORT, UPPER_SPIRE_TELEPORT); /// @todo Gauntlet event before Sindragosa - if (instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) == DONE) + if (instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) == DONE && go->GetEntry() != GO_SCOURGE_TRANSPORTER_SINDRAGOSA) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to Sindragosa's Lair", GOSSIP_SENDER_ICC_PORT, SINDRAGOSA_S_LAIR_TELEPORT); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index febcf22ba6d..86e4efc5db7 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -127,7 +127,13 @@ class instance_icecrown_citadel : public InstanceMapScript DeathbringerSaurfangDoorGUID = 0; DeathbringerSaurfangEventGUID = 0; DeathbringersCacheGUID = 0; - SaurfangTeleportGUID = 0; + TeleporterLichKingGUID = 0; + TeleporterUpperSpireGUID = 0; + TeleporterLightsHammerGUID = 0; + TeleporterRampartsGUID = 0; + TeleporterDeathBringerGUID = 0; + TeleporterOratoryGUID = 0; + TeleporterSindragosaGUID = 0; PlagueSigilGUID = 0; BloodwingSigilGUID = 0; FrostwingSigilGUID = 0; @@ -164,10 +170,26 @@ class instance_icecrown_citadel : public InstanceMapScript IsNauseaEligible = true; IsOrbWhispererEligible = true; ColdflameJetsState = NOT_STARTED; + UpperSpireTeleporterActiveState = NOT_STARTED; BloodQuickeningState = NOT_STARTED; BloodQuickeningMinutes = 0; } + // A function to help reduce the number of lines for teleporter management. + void SetTeleporterState(GameObject* go, bool usable) + { + if (usable) + { + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + go->SetGoState(GO_STATE_ACTIVE); + } + else + { + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + go->SetGoState(GO_STATE_READY); + } + } + void FillInitialWorldStates(WorldPacket& data) override { data << uint32(WORLDSTATE_SHOW_TIMER) << uint32(BloodQuickeningState == IN_PROGRESS); @@ -542,8 +564,37 @@ class instance_icecrown_citadel : public InstanceMapScript case GO_DEATHBRINGER_S_CACHE_25H: DeathbringersCacheGUID = go->GetGUID(); break; - case GO_SCOURGE_TRANSPORTER_SAURFANG: - SaurfangTeleportGUID = go->GetGUID(); + case GO_SCOURGE_TRANSPORTER_LICHKING: + TeleporterLichKingGUID = go->GetGUID(); + if (GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && GetBossState(DATA_SINDRAGOSA) == DONE) + go->SetGoState(GO_STATE_ACTIVE); + break; + case GO_SCOURGE_TRANSPORTER_UPPERSPIRE: + TeleporterUpperSpireGUID = go->GetGUID(); + if (GetBossState(DATA_DEATHBRINGER_SAURFANG) != DONE || GetData(DATA_UPPERSPIRE_TELE_ACT) != DONE) + SetTeleporterState(go, false); + else + SetTeleporterState(go, true); + break; + case GO_SCOURGE_TRANSPORTER_LIGHTSHAMMER: + TeleporterLightsHammerGUID = go->GetGUID(); + SetTeleporterState(go, GetBossState(DATA_LORD_MARROWGAR) == DONE); + break; + case GO_SCOURGE_TRANSPORTER_RAMPART: + TeleporterRampartsGUID = go->GetGUID(); + SetTeleporterState(go, GetBossState(DATA_LADY_DEATHWHISPER) == DONE); + break; + case GO_SCOURGE_TRANSPORTER_DEATHBRINGER: + TeleporterDeathBringerGUID = go->GetGUID(); + SetTeleporterState(go, GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE); + break; + case GO_SCOURGE_TRANSPORTER_ORATORY: + TeleporterOratoryGUID = go->GetGUID(); + SetTeleporterState(go, GetBossState(DATA_LORD_MARROWGAR) == DONE); + break; + case GO_SCOURGE_TRANSPORTER_SINDRAGOSA: + TeleporterSindragosaGUID = go->GetGUID(); + SetTeleporterState(go, GetBossState(DATA_VALITHRIA_DREAMWALKER) == DONE); break; case GO_PLAGUE_SIGIL: PlagueSigilGUID = go->GetGUID(); @@ -600,11 +651,6 @@ class instance_icecrown_citadel : public InstanceMapScript go->SetLootRecipient(valithria->GetLootRecipient()); go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); break; - case GO_SCOURGE_TRANSPORTER_LK: - TheLichKingTeleportGUID = go->GetGUID(); - if (GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && GetBossState(DATA_SINDRAGOSA) == DONE) - go->SetGoState(GO_STATE_ACTIVE); - break; case GO_ARTHAS_PLATFORM: ArthasPlatformGUID = go->GetGUID(); break; @@ -690,6 +736,8 @@ class instance_icecrown_citadel : public InstanceMapScript return RimefangTrash.size(); case DATA_COLDFLAME_JETS: return ColdflameJetsState; + case DATA_UPPERSPIRE_TELE_ACT: + return UpperSpireTeleporterActiveState; case DATA_TEAM_IN_INSTANCE: return TeamInInstance; case DATA_BLOOD_QUICKENING_STATE: @@ -717,8 +765,20 @@ class instance_icecrown_citadel : public InstanceMapScript return DeathbringerSaurfangEventGUID; case GO_SAURFANG_S_DOOR: return DeathbringerSaurfangDoorGUID; - case GO_SCOURGE_TRANSPORTER_SAURFANG: - return SaurfangTeleportGUID; + case GO_SCOURGE_TRANSPORTER_LICHKING: + return TeleporterLichKingGUID; + case GO_SCOURGE_TRANSPORTER_UPPERSPIRE: + return TeleporterUpperSpireGUID; + case GO_SCOURGE_TRANSPORTER_LIGHTSHAMMER: + return TeleporterLightsHammerGUID; + case GO_SCOURGE_TRANSPORTER_RAMPART: + return TeleporterRampartsGUID; + case GO_SCOURGE_TRANSPORTER_DEATHBRINGER: + return TeleporterDeathBringerGUID; + case GO_SCOURGE_TRANSPORTER_ORATORY: + return TeleporterOratoryGUID; + case GO_SCOURGE_TRANSPORTER_SINDRAGOSA: + return TeleporterSindragosaGUID; case DATA_FESTERGUT: return FestergutGUID; case DATA_ROTFACE: @@ -780,10 +840,24 @@ class instance_icecrown_citadel : public InstanceMapScript switch (type) { + case DATA_LORD_MARROWGAR: + { + if (state == DONE) + { + if (GameObject* teleporter = instance->GetGameObject(TeleporterLightsHammerGUID)) + SetTeleporterState(teleporter, true); + if (GameObject* teleporter = instance->GetGameObject(TeleporterOratoryGUID)) + SetTeleporterState(teleporter, true); + } + break; + } case DATA_LADY_DEATHWHISPER: { if (state == DONE) { + if (GameObject* teleporter = instance->GetGameObject(TeleporterRampartsGUID)) + SetTeleporterState(teleporter, true); + if (GameObject* elevator = instance->GetGameObject(LadyDeathwisperElevatorGUID)) { elevator->SetUInt32Value(GAMEOBJECT_LEVEL, 0); @@ -797,6 +871,9 @@ class instance_icecrown_citadel : public InstanceMapScript case DATA_ICECROWN_GUNSHIP_BATTLE: if (state == DONE) { + if (GameObject* teleporter = instance->GetGameObject(TeleporterDeathBringerGUID)) + SetTeleporterState(teleporter, true); + if (GameObject* loot = instance->GetGameObject(GunshipArmoryGUID)) loot->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); } @@ -807,20 +884,28 @@ class instance_icecrown_citadel : public InstanceMapScript switch (state) { case DONE: + { if (GameObject* loot = instance->GetGameObject(DeathbringersCacheGUID)) { if (Creature* deathbringer = instance->GetCreature(DeathbringerSaurfangGUID)) loot->SetLootRecipient(deathbringer->GetLootRecipient()); loot->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); } - // no break + + if (GameObject* teleporter = instance->GetGameObject(TeleporterUpperSpireGUID)) + SetTeleporterState(teleporter, true); + + if (GameObject* teleporter = instance->GetGameObject(TeleporterDeathBringerGUID)) + SetTeleporterState(teleporter, true); + break; + } case NOT_STARTED: - if (GameObject* teleporter = instance->GetGameObject(SaurfangTeleportGUID)) - { - HandleGameObject(SaurfangTeleportGUID, true, teleporter); - teleporter->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } + { + if (GameObject* teleporter = instance->GetGameObject(TeleporterDeathBringerGUID)) + SetTeleporterState(teleporter, true); + break; + } default: break; } @@ -890,8 +975,13 @@ class instance_icecrown_citadel : public InstanceMapScript } break; case DATA_VALITHRIA_DREAMWALKER: - if (state == DONE && sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[8].questId[instance->GetSpawnMode() & 1])) - instance->SummonCreature(NPC_VALITHRIA_DREAMWALKER_QUEST, ValithriaSpawnPos); + if (state == DONE) + { + if (sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[8].questId[instance->GetSpawnMode() & 1])) + instance->SummonCreature(NPC_VALITHRIA_DREAMWALKER_QUEST, ValithriaSpawnPos); + if (GameObject* teleporter = instance->GetGameObject(TeleporterSindragosaGUID)) + SetTeleporterState(teleporter, true); + } break; case DATA_SINDRAGOSA: HandleGameObject(FrostwingSigilGUID, state != DONE); @@ -1025,6 +1115,11 @@ class instance_icecrown_citadel : public InstanceMapScript SaveToDB(); break; } + case DATA_UPPERSPIRE_TELE_ACT: + UpperSpireTeleporterActiveState = data; + if (UpperSpireTeleporterActiveState == DONE) + SaveToDB(); + break; default: break; } @@ -1231,7 +1326,7 @@ class instance_icecrown_citadel : public InstanceMapScript std::ostringstream saveStream; saveStream << "I C " << GetBossSaveData() << HeroicAttempts << ' ' - << ColdflameJetsState << ' ' << BloodQuickeningState << ' ' << BloodQuickeningMinutes; + << ColdflameJetsState << ' ' << BloodQuickeningState << ' ' << BloodQuickeningMinutes << ' ' << UpperSpireTeleporterActiveState; OUT_SAVE_INST_DATA_COMPLETE; return saveStream.str(); @@ -1267,11 +1362,17 @@ class instance_icecrown_citadel : public InstanceMapScript uint32 temp = 0; loadStream >> temp; - ColdflameJetsState = temp ? DONE : NOT_STARTED; + if (temp == IN_PROGRESS) + ColdflameJetsState = NOT_STARTED; + else + ColdflameJetsState = temp ? DONE : NOT_STARTED; loadStream >> temp; BloodQuickeningState = temp ? DONE : NOT_STARTED; // DONE means finished (not success/fail) loadStream >> BloodQuickeningMinutes; + + loadStream >> temp; + UpperSpireTeleporterActiveState = temp ? DONE : NOT_STARTED; } else OUT_LOAD_INST_DATA_FAIL; @@ -1412,7 +1513,13 @@ class instance_icecrown_citadel : public InstanceMapScript uint64 DeathbringerSaurfangDoorGUID; uint64 DeathbringerSaurfangEventGUID; // Muradin Bronzebeard or High Overlord Saurfang uint64 DeathbringersCacheGUID; - uint64 SaurfangTeleportGUID; + uint64 TeleporterLichKingGUID; + uint64 TeleporterUpperSpireGUID; + uint64 TeleporterLightsHammerGUID; + uint64 TeleporterRampartsGUID; + uint64 TeleporterDeathBringerGUID; + uint64 TeleporterOratoryGUID; + uint64 TeleporterSindragosaGUID; uint64 PlagueSigilGUID; uint64 BloodwingSigilGUID; uint64 FrostwingSigilGUID; @@ -1449,6 +1556,7 @@ class instance_icecrown_citadel : public InstanceMapScript uint64 PillarsUnchainedGUID; uint32 TeamInInstance; uint32 ColdflameJetsState; + uint32 UpperSpireTeleporterActiveState; std::set<uint32> FrostwyrmGUIDs; std::set<uint32> SpinestalkerTrash; std::set<uint32> RimefangTrash; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp index 9a9e7aa6849..e2ff68ab851 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp @@ -147,15 +147,15 @@ public: { if (attack && who) { - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Thane->AI())->encounterActionAttack = true; - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Lady->AI())->encounterActionAttack = true; - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Baron->AI())->encounterActionAttack = true; - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Sir->AI())->encounterActionAttack = true; - - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Thane->AI())->AttackStart(who); - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Lady->AI())->AttackStart(who); - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Baron->AI())->AttackStart(who); - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Sir->AI())->AttackStart(who); + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Thane->AI())->encounterActionAttack = true; + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Lady->AI())->encounterActionAttack = true; + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Baron->AI())->encounterActionAttack = true; + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Sir->AI())->encounterActionAttack = true; + + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Thane->AI())->AttackStart(who); + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Lady->AI())->AttackStart(who); + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Baron->AI())->AttackStart(who); + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Sir->AI())->AttackStart(who); } if (reset) @@ -174,15 +174,15 @@ public: if (!Sir->IsAlive()) Sir->Respawn(); - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Thane->AI())->encounterActionReset = true; - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Lady->AI())->encounterActionReset = true; - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Baron->AI())->encounterActionReset = true; - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Sir->AI())->encounterActionReset = true; + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Thane->AI())->encounterActionReset = true; + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Lady->AI())->encounterActionReset = true; + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Baron->AI())->encounterActionReset = true; + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Sir->AI())->encounterActionReset = true; - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Thane->AI())->EnterEvadeMode(); - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Lady->AI())->EnterEvadeMode(); - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Baron->AI())->EnterEvadeMode(); - CAST_AI(boss_four_horsemen::boss_four_horsemenAI, Sir->AI())->EnterEvadeMode(); + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Thane->AI())->EnterEvadeMode(); + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Lady->AI())->EnterEvadeMode(); + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Baron->AI())->EnterEvadeMode(); + ENSURE_AI(boss_four_horsemen::boss_four_horsemenAI, Sir->AI())->EnterEvadeMode(); } } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp index 53efc628aa2..648da29ca66 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp @@ -126,7 +126,7 @@ public: { float x, y, z, o; me->GetHomePosition(x, y, z, o); - me->NearTeleportTo(x, y, z, o - G3D::halfPi()); + me->NearTeleportTo(x, y, z, o - (float(M_PI) / 2)); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); me->SetTarget(0); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp index 946b60d4e27..5702987cc5a 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp @@ -177,13 +177,13 @@ class spell_loatheb_necrotic_aura_warning : public SpellScriptLoader void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (GetTarget()->IsAIEnabled) - CAST_AI(LoathebAI, GetTarget()->GetAI())->Talk(SAY_NECROTIC_AURA_APPLIED); + ENSURE_AI(LoathebAI, GetTarget()->GetAI())->Talk(SAY_NECROTIC_AURA_APPLIED); } void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (GetTarget()->IsAIEnabled) - CAST_AI(LoathebAI, GetTarget()->GetAI())->Talk(SAY_NECROTIC_AURA_REMOVED); + ENSURE_AI(LoathebAI, GetTarget()->GetAI())->Talk(SAY_NECROTIC_AURA_REMOVED); } void Register() override diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 5291e4baed3..fc1f88c083d 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -1014,7 +1014,7 @@ public: // Used to generate perfect cyclic movements (Enter Circle). void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) { - float step = clockwise ? -M_PI / 8.0f : M_PI / 8.0f; + float step = clockwise ? float(-M_PI) / 8.0f : float(M_PI) / 8.0f; float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY()); for (uint8 i = 0; i < 16; angle += step, ++i) @@ -1326,7 +1326,7 @@ public: private: void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) { - float step = clockwise ? -M_PI / 9.0f : M_PI / 9.0f; + float step = clockwise ? float(-M_PI) / 9.0f : float(M_PI) / 9.0f; float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY()); for (uint8 i = 0; i < 18; angle += step, ++i) diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp index 38e6a3fc816..bfe34ece6cf 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp @@ -220,7 +220,7 @@ public: go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); go->SetGoState(GO_STATE_ACTIVE); - CAST_AI(boss_keristrasza::boss_keristraszaAI, pKeristrasza->AI())->CheckContainmentSpheres(true); + ENSURE_AI(boss_keristrasza::boss_keristraszaAI, pKeristrasza->AI())->CheckContainmentSpheres(true); } return true; } @@ -271,7 +271,7 @@ class achievement_intense_cold : public AchievementCriteriaScript if (!target) return false; - std::list<uint64> intenseColdList = CAST_AI(boss_keristrasza::boss_keristraszaAI, target->ToCreature()->AI())->intenseColdList; + std::list<uint64> intenseColdList = ENSURE_AI(boss_keristrasza::boss_keristraszaAI, target->ToCreature()->AI())->intenseColdList; if (!intenseColdList.empty()) for (std::list<uint64>::iterator itr = intenseColdList.begin(); itr != intenseColdList.end(); ++itr) if (player->GetGUID() == *itr) diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp index 585da8e28d3..d07d68f28c9 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp @@ -310,12 +310,12 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader if (varos->GetEntry() != NPC_VAROS) return; - float orientation = CAST_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation(); + float orientation = ENSURE_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation(); for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();) { float angle = varos->GetAngle((*itr)->GetPositionX(), (*itr)->GetPositionY()); - float diff = fabs(orientation - angle); + float diff = std::fabs(orientation - angle); if (diff > 1.0f) itr = targets.erase(itr); @@ -354,12 +354,12 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader if (varos->GetEntry() != NPC_VAROS) return; - float orientation = CAST_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation(); + float orientation = ENSURE_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation(); for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();) { float angle = varos->GetAngle((*itr)->GetPositionX(), (*itr)->GetPositionY()); - float diff = fabs(orientation - angle); + float diff = std::fabs(orientation - angle); if (diff > 1.0f) itr = targets.erase(itr); diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp index cedf06a3154..683eb97a4f7 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp @@ -272,7 +272,7 @@ public: if (action == GOSSIP_ACTION_INFO_DEF+1 || action == GOSSIP_ACTION_INFO_DEF+2) { player->CLOSE_GOSSIP_MENU(); - CAST_AI(npc_brann_hos::npc_brann_hosAI, creature->AI())->StartWP(); + ENSURE_AI(npc_brann_hos::npc_brann_hosAI, creature->AI())->StartWP(); } return true; @@ -347,7 +347,7 @@ public: { if (!creature->IsAlive()) creature->Respawn(); - CAST_AI(npc_tribuna_controller::npc_tribuna_controllerAI, creature->AI())->UpdateFacesList(); + ENSURE_AI(npc_tribuna_controller::npc_tribuna_controllerAI, creature->AI())->UpdateFacesList(); uiControllerGUID = creature->GetGUID(); } break; @@ -463,7 +463,7 @@ public: Talk(SAY_EVENT_A_3); instance->HandleGameObject(instance->GetData64(DATA_GO_KADDRAK), true); if (Creature* temp = ObjectAccessor::GetCreature(*me, uiControllerGUID)) - CAST_AI(npc_tribuna_controller::npc_tribuna_controllerAI, temp->AI())->bKaddrakActivated = true; + ENSURE_AI(npc_tribuna_controller::npc_tribuna_controllerAI, temp->AI())->bKaddrakActivated = true; JumpToNextStep(5000); break; case 9: @@ -485,7 +485,7 @@ public: Talk(SAY_EVENT_B_3); instance->HandleGameObject(instance->GetData64(DATA_GO_MARNAK), true); if (Creature* temp = ObjectAccessor::GetCreature(*me, uiControllerGUID)) - CAST_AI(npc_tribuna_controller::npc_tribuna_controllerAI, temp->AI())->bMarnakActivated = true; + ENSURE_AI(npc_tribuna_controller::npc_tribuna_controllerAI, temp->AI())->bMarnakActivated = true; JumpToNextStep(10000); break; case 13: @@ -515,7 +515,7 @@ public: Talk(SAY_EVENT_C_3); instance->HandleGameObject(instance->GetData64(DATA_GO_ABEDNEUM), true); if (Creature* temp = ObjectAccessor::GetCreature(*me, uiControllerGUID)) - CAST_AI(npc_tribuna_controller::npc_tribuna_controllerAI, temp->AI())->bAbedneumActivated = true; + ENSURE_AI(npc_tribuna_controller::npc_tribuna_controllerAI, temp->AI())->bAbedneumActivated = true; JumpToNextStep(5000); break; case 19: diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index 57df8c76a56..68bdbe0fdf3 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -1101,7 +1101,7 @@ class npc_ancient_water_spirit : public CreatureScript { instance = me->GetInstanceScript(); if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_FREYA))) - waveCount = CAST_AI(boss_freya::boss_freyaAI, Freya->AI())->trioWaveCount; + waveCount = ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->trioWaveCount; } void Reset() override @@ -1133,8 +1133,8 @@ class npc_ancient_water_spirit : public CreatureScript { if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_FREYA))) { - CAST_AI(boss_freya::boss_freyaAI, Freya->AI())->checkElementalAlive[waveCount] = false; - CAST_AI(boss_freya::boss_freyaAI, Freya->AI())->LasherDead(1); + ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->checkElementalAlive[waveCount] = false; + ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->LasherDead(1); } } @@ -1161,7 +1161,7 @@ class npc_storm_lasher : public CreatureScript { instance = me->GetInstanceScript(); if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_FREYA))) - waveCount = CAST_AI(boss_freya::boss_freyaAI, Freya->AI())->trioWaveCount; + waveCount = ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->trioWaveCount; } void Reset() override @@ -1199,8 +1199,8 @@ class npc_storm_lasher : public CreatureScript { if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_FREYA))) { - CAST_AI(boss_freya::boss_freyaAI, Freya->AI())->checkElementalAlive[waveCount] = false; - CAST_AI(boss_freya::boss_freyaAI, Freya->AI())->LasherDead(2); + ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->checkElementalAlive[waveCount] = false; + ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->LasherDead(2); } } @@ -1228,7 +1228,7 @@ class npc_snaplasher : public CreatureScript { instance = me->GetInstanceScript(); if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_FREYA))) - waveCount = CAST_AI(boss_freya::boss_freyaAI, Freya->AI())->trioWaveCount; + waveCount = ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->trioWaveCount; } void UpdateAI(uint32 /*diff*/) override @@ -1246,8 +1246,8 @@ class npc_snaplasher : public CreatureScript { if (Creature* Freya = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_FREYA))) { - CAST_AI(boss_freya::boss_freyaAI, Freya->AI())->checkElementalAlive[waveCount] = false; - CAST_AI(boss_freya::boss_freyaAI, Freya->AI())->LasherDead(4); + ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->checkElementalAlive[waveCount] = false; + ENSURE_AI(boss_freya::boss_freyaAI, Freya->AI())->LasherDead(4); } } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp index 011d1844adf..196e410f239 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp @@ -526,7 +526,7 @@ class spell_general_vezax_saronite_vapors : public SpellScriptLoader { if (Unit* caster = GetCaster()) { - int32 mana = int32(aurEff->GetAmount() * pow(2.0f, GetStackAmount())); // mana restore - bp * 2^stackamount + int32 mana = int32(aurEff->GetAmount() * std::pow(2.0f, GetStackAmount())); // mana restore - bp * 2^stackamount int32 damage = mana * 2; caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_ENERGIZE, &mana, NULL, NULL, true); caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_DAMAGE, &damage, NULL, NULL, true); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp index 4d904b04618..7f4d585b0a4 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp @@ -985,7 +985,7 @@ public: if (!caster) return; - int32 damage = int32(200 * pow(2.0f, GetStackAmount())); + int32 damage = int32(200 * std::pow(2.0f, GetStackAmount())); caster->CastCustomSpell(caster, SPELL_BITING_COLD_DAMAGE, &damage, NULL, NULL, true); if (caster->isMoving()) diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp index 58969fd63c8..71a89c0e508 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp @@ -498,7 +498,7 @@ class spell_ulduar_squeezed_lifeless : public SpellScriptLoader pos.m_positionX = 1756.25f + irand(-3, 3); pos.m_positionY = -8.3f + irand(-3, 3); pos.m_positionZ = 448.8f; - pos.SetOrientation(M_PI); + pos.SetOrientation(float(M_PI)); GetHitPlayer()->DestroyForNearbyPlayers(); GetHitPlayer()->ExitVehicle(&pos); GetHitPlayer()->UpdateObjectVisibility(false); diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index f284aacf996..b769c7e141e 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -15,10 +15,16 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "Cell.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "SpellScript.h" +#include "SpellAuraEffects.h" #include "ulduar.h" +#include "Vehicle.h" enum Yells { @@ -39,78 +45,1413 @@ enum Yells SAY_BERSERK = 14 }; +enum ComputerYells +{ + SAY_SELF_DESTRUCT_INITIATED = 0, + SAY_SELF_DESTRUCT_TERMINATED = 1, + SAY_SELF_DESTRUCT_10 = 2, + SAY_SELF_DESTRUCT_9 = 3, + SAY_SELF_DESTRUCT_8 = 4, + SAY_SELF_DESTRUCT_7 = 5, + SAY_SELF_DESTRUCT_6 = 6, + SAY_SELF_DESTRUCT_5 = 7, + SAY_SELF_DESTRUCT_4 = 8, + SAY_SELF_DESTRUCT_3 = 9, + SAY_SELF_DESTRUCT_2 = 10, + SAY_SELF_DESTRUCT_1 = 11, + SAY_SELF_DESTRUCT_FINALIZED = 12 +}; + enum Spells { + // Mimiron + SPELL_WELD = 63339, // Idle aura. + SPELL_SEAT_1 = 52391, // Cast on all vehicles, Cycled on MKII + SPELL_SEAT_2 = 63313, // Cast on MKII and VX-001, Cycled on MKII + SPELL_SEAT_3 = 63314, // Cast on MKII, Cycled on MKII + SPELL_SEAT_5 = 63316, // Cast on MKII and VX-001, Cycled on MKII + SPELL_SEAT_6 = 63344, // Cast on MKII + SPELL_SEAT_7 = 63345, // Cast on MKII SPELL_JETPACK = 63341, - SPELL_EMERGENCY_MODE = 64582, - SPELL_SELF_REPAIR = 64383, - SPELL_MAGNETIC_CORE = 64444, + SPELL_DESPAWN_ASSAULT_BOTS = 64463, // only despawns assault bots... no equivalent spell for the other adds... + SPELL_TELEPORT_VISUAL = 41232, + SPELL_SLEEP_VISUAL_1 = 64393, + SPELL_SLEEP_VISUAL_2 = 64394, + // Leviathan MK II SPELL_FLAME_SUPPRESSANT_MK = 64570, SPELL_NAPALM_SHELL = 63666, - SPELL_PLASMA_BLAST = 62977, - SPELL_PROXIMITY_MINES = 63027, + SPELL_FORCE_CAST_NAPALM_SHELL = 64539, + SPELL_PLASMA_BLAST = 62997, + SPELL_SCRIPT_EFFECT_PLASMA_BLAST = 64542, SPELL_SHOCK_BLAST = 63631, - // VX 001 + SPELL_SHOCK_BLAST_AURA = 63632, // Deprecated? It is never cast. + + // VX-001 SPELL_FLAME_SUPPRESSANT_VX = 65192, - SPELL_FROSTBOMB = 64623, - SPELL_HAND_PULSE = 64348, SPELL_SPINNING_UP = 63414, - SPELL_RAPID_BURST = 63387, - SPELL_P3WX2_LASER_BARRAGE = 63293, - SPELL_ROCKET_STRIKE = 63041, - SPELL_HEAT_WAVE = 63677, + SPELL_HEAT_WAVE_AURA = 63679, + SPELL_HAND_PULSE_LEFT = 64348, + SPELL_HAND_PULSE_RIGHT = 64352, + SPELL_MOUNT_MKII = 64387, + SPELL_TORSO_DISABLED = 64120, + // Aerial Command Unit - SPELL_PLASMA_BALL = 63689, - // Additonal spells - SPELL_MAGNETIC_FIELD = 64668, - SPELL_DEAFENING_SIREN = 64616, + SPELL_PLASMA_BALL_P1 = 63689, + SPELL_PLASMA_BALL_P2 = 65647, + SPELL_MOUNT_VX_001 = 64388, + + // Proximity Mines + SPELL_PROXIMITY_MINES = 63027, // Cast by Leviathan MK II + SPELL_PROXIMITY_MINE_EXPLOSION = 66351, + SPELL_PROXIMITY_MINE_TRIGGER = 65346, + SPELL_PROXIMITY_MINE_PERIODIC_TRIGGER = 65345, + SPELL_PERIODIC_PROXIMITY_AURA = 65345, + SPELL_SUMMON_PROXIMITY_MINE = 65347, + + // Rapid Burst + SPELL_RAPID_BURST_LEFT = 63387, + SPELL_RAPID_BURST_RIGHT = 64019, + SPELL_RAPID_BURST = 63382, // Cast by VX-001 + SPELL_RAPID_BURST_TARGET_ME = 64841, // Cast by Burst Target + SPELL_SUMMON_BURST_TARGET = 64840, // Cast by VX-001 + + // Rocket Strike + SPELL_SUMMON_ROCKET_STRIKE = 63036, + SPELL_SCRIPT_EFFECT_ROCKET_STRIKE = 63681, // Cast by Rocket (Mimiron Visual) + SPELL_ROCKET_STRIKE = 64064, // Added in creature_template_addon + SPELL_ROCKET_STRIKE_LEFT = 64402, // Cast by VX-001 + SPELL_ROCKET_STRIKE_BOTH = 65034, // Cast by VX-001 + + // Flames + SPELL_FLAMES_PERIODIC_TRIGGER = 64561, // Added in creature_template_addon + SPELL_SUMMON_FLAMES_SPREAD_TRIGGER = 64562, + SPELL_SUMMON_FLAMES_INITIAL = 64563, + SPELL_SUMMON_FLAMES_SPREAD = 64564, + SPELL_FLAMES = 64566, + SPELL_SCRIPT_EFFECT_SUMMON_FLAMES_INITIAL = 64567, + + // Frost Bomb + SPELL_SCRIPT_EFFECT_FROST_BOMB = 64623, // Cast by VX-001 + SPELL_FROST_BOMB_LINKED = 64624, // Added in creature_template_addon + SPELL_FROST_BOMB_DUMMY = 64625, + SPELL_SUMMON_FROST_BOMB = 64627, // Cast by VX-001 + SPELL_FROST_BOMB_EXPLOSION = 64626, + SPELL_CLEAR_FIRES = 65354, + + // Bots + SPELL_SUMMON_FIRE_BOT = 64622, + SPELL_SUMMON_FIRE_BOT_DUMMY = 64621, + SPELL_SUMMON_FIRE_BOT_TRIGGER = 64620, // Cast by Areal Command Unit + SPELL_DEAFENING_SIREN = 64616, // Added in creature_template_addon + SPELL_FIRE_SEARCH_AURA = 64617, // Added in creature_template_addon + SPELL_FIRE_SEARCH = 64618, SPELL_WATER_SPRAY = 64619, - SPELL_FROST_BOMB_HARD_MODE = 64627, - SPELL_EXPLOSION = 66351, - SPELL_DISARM = 1842, - SPELL_RIDE_VEHICLE = 46598, - SPELL_TRIGGER_MISSILE = 65347, + + SPELL_SUMMON_JUNK_BOT = 63819, + SPELL_SUMMON_JUNK_BOT_TRIGGER = 63820, // Cast by Areal Command Unit + SPELL_SUMMON_JUNK_BOT_DUMMY = 64398, + + SPELL_SUMMON_ASSAULT_BOT_TRIGGER = 64425, // Cast by Areal Command Unit + SPELL_SUMMON_ASSAULT_BOT_DUMMY = 64426, + SPELL_SUMMON_ASSAULT_BOT = 64427, + SPELL_MAGNETIC_FIELD = 64668, + + SPELL_SUMMON_BOMB_BOT = 63811, // Cast by Areal Command Unit + SPELL_BOMB_BOT_AURA = 63767, // Added in creature_template_addon + + // Miscellaneous + SPELL_SELF_DESTRUCTION_AURA = 64610, + SPELL_SELF_DESTRUCTION_VISUAL = 64613, + SPELL_NOT_SO_FRIENDLY_FIRE = 65040, + SPELL_ELEVATOR_KNOCKBACK = 65096, // Cast by worldtrigger. + SPELL_VEHICLE_DAMAGED = 63415, + SPELL_EMERGENCY_MODE = 64582, // mkii, vx001, aerial, assault, junk + SPELL_EMERGENCY_MODE_TURRET = 65101, // Cast by Leviathan MK II, only hits Leviathan MK II turret + SPELL_SELF_REPAIR = 64383, + SPELL_MAGNETIC_CORE = 64436, + SPELL_MAGNETIC_CORE_VISUAL = 64438, + SPELL_HALF_HEAL = 64188, + SPELL_CLEAR_ALL_DEBUFFS = 34098, // TODO: make use of this spell... + SPELL_FREEZE_ANIM_STUN = 63354, // used to prevent mkii from doing stuff?.. + SPELL_FREEZE_ANIM = 16245 // Idle aura. Freezes animation. }; -enum Npc +enum Data { - NPC_ASSAULT_BOT = 34057, - NPC_BOMB_BOT = 33836, - NPC_JUNK_BOT = 33855, - NPC_EMERGENCE_FIRE_BOT = 34147, - NPC_FROST_BOMB = 34149, + DATA_SETUP_MINE, + DATA_SETUP_BOMB, + DATA_SETUP_ROCKET, + DATA_NOT_SO_FRIENDLY_FIRE, + DATA_FIREFIGHTER, + DATA_WATERSPRAY, + DATA_MOVE_NEW }; -class spell_ulduar_proximity_mines : public SpellScriptLoader +enum Events +{ + // Leviathan MK II + EVENT_PROXIMITY_MINE = 1, + EVENT_NAPALM_SHELL, + EVENT_PLASMA_BLAST, + EVENT_SHOCK_BLAST, + EVENT_FLAME_SUPPRESSANT_MK, + EVENT_MOVE_POINT_2, + EVENT_MOVE_POINT_3, + EVENT_MOVE_POINT_5, + + // VX-001 + EVENT_RAPID_BURST, + EVENT_SPINNING_UP, + EVENT_ROCKET_STRIKE, + EVENT_HAND_PULSE, + EVENT_FROST_BOMB, + EVENT_FLAME_SUPPRESSANT_VX, + EVENT_RELOAD, + + // Aerial Command Unit + EVENT_SUMMON_FIRE_BOTS, + EVENT_SUMMON_JUNK_BOT, + EVENT_SUMMON_ASSAULT_BOT, + EVENT_SUMMON_BOMB_BOT, + + // Mimiron + EVENT_SUMMON_FLAMES, + EVENT_INTRO_1, + EVENT_INTRO_2, + EVENT_INTRO_3, + + EVENT_VX001_ACTIVATION_1, + EVENT_VX001_ACTIVATION_2, + EVENT_VX001_ACTIVATION_3, + EVENT_VX001_ACTIVATION_4, + EVENT_VX001_ACTIVATION_5, + EVENT_VX001_ACTIVATION_6, + EVENT_VX001_ACTIVATION_7, + EVENT_VX001_ACTIVATION_8, + EVENT_VX001_ACTIVATION_9, + + EVENT_AERIAL_ACTIVATION_1, + EVENT_AERIAL_ACTIVATION_2, + EVENT_AERIAL_ACTIVATION_3, + EVENT_AERIAL_ACTIVATION_4, + EVENT_AERIAL_ACTIVATION_5, + EVENT_AERIAL_ACTIVATION_6, + + EVENT_VOL7RON_ACTIVATION_1, + EVENT_VOL7RON_ACTIVATION_2, + EVENT_VOL7RON_ACTIVATION_3, + EVENT_VOL7RON_ACTIVATION_4, + EVENT_VOL7RON_ACTIVATION_5, + EVENT_VOL7RON_ACTIVATION_6, + EVENT_VOL7RON_ACTIVATION_7, + + EVENT_OUTTRO_1, + EVENT_OUTTRO_2, + EVENT_OUTTRO_3, + + // Computer + EVENT_SELF_DESTRUCT_10, + EVENT_SELF_DESTRUCT_9, + EVENT_SELF_DESTRUCT_8, + EVENT_SELF_DESTRUCT_7, + EVENT_SELF_DESTRUCT_6, + EVENT_SELF_DESTRUCT_5, + EVENT_SELF_DESTRUCT_4, + EVENT_SELF_DESTRUCT_3, + EVENT_SELF_DESTRUCT_2, + EVENT_SELF_DESTRUCT_1, + EVENT_SELF_DESTRUCT_FINALIZED, + + // Misc + EVENT_MAGNETIC_FIELD, + EVENT_SPREAD_FLAMES, + EVENT_FROST_BOMB_EXPLOSION, + EVENT_FROST_BOMB_CLEAR_FIRES, + EVENT_PROXIMITY_MINE_ARM, + EVENT_PROXIMITY_MINE_DETONATION, + EVENT_SEARCH_FLAMES, + EVENT_WATER_SPRAY +}; + +enum Actions +{ + DO_START_MKII, + DO_HARDMODE_MKII, + + DO_ACTIVATE_VX001, + DO_START_VX001, + DO_HARDMODE_VX001, + + DO_ACTIVATE_AERIAL, + DO_START_AERIAL, + DO_HARDMODE_AERIAL, + DO_DISABLE_AERIAL, + DO_ENABLE_AERIAL, + + DO_ACTIVATE_V0L7R0N_1, + DO_ACTIVATE_V0L7R0N_2, + DO_ASSEMBLED_COMBAT, // All 3 parts use this action, its done on purpose. + + DO_ACTIVATE_HARD_MODE, + DO_ACTIVATE_COMPUTER, + DO_DEACTIVATE_COMPUTER, + DO_ACTIVATE_SELF_DESTRUCT, + + DO_ENCOUNTER_DONE +}; + +enum Phases +{ + // Leviathan MK II + PHASE_LEVIATHAN_SOLO = 1, + PHASE_LEVIATHAN_ASSEMBLED, + + // VX-001 + PHASE_VX001_SOLO, + PHASE_VX001_ASSEMBLED, + + // Aerial Command Unit + PHASE_AERIAL_SOLO, + PHASE_AERIAL_ASSEMBLED +}; + +uint32 const RepairSpells[4] = +{ + SPELL_SEAT_1, + SPELL_SEAT_2, + SPELL_SEAT_3, + SPELL_SEAT_5 +}; + +// 63801 Bomb Bot +class spell_mimiron_bomb_bot : public SpellScriptLoader +{ + public: + spell_mimiron_bomb_bot() : SpellScriptLoader("spell_mimiron_bomb_bot") { } + + class spell_mimiron_bomb_bot_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_bomb_bot_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (GetHitPlayer()) + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (Creature* mkii = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_LEVIATHAN_MK_II))) + mkii->AI()->SetData(DATA_SETUP_BOMB, 0); + } + + void HandleDespawn(SpellEffIndex /*effIndex*/) + { + if (Creature* target = GetHitCreature()) + { + target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED); + target->DespawnOrUnsummon(1000); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_bomb_bot_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + OnEffectHitTarget += SpellEffectFn(spell_mimiron_bomb_bot_SpellScript::HandleDespawn, EFFECT_1, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_bomb_bot_SpellScript(); + } +}; + +// 65192 - Flame Suppressant, 65224 - Clear Fires, 65354 - Clear Fires, 64619 - Water Spray +class spell_mimiron_clear_fires : public SpellScriptLoader { public: - spell_ulduar_proximity_mines() : SpellScriptLoader("spell_ulduar_proximity_mines") { } + spell_mimiron_clear_fires() : SpellScriptLoader("spell_mimiron_clear_fires") { } - class spell_ulduar_proximity_minesSpellScript : public SpellScript + class spell_mimiron_clear_fires_SpellScript : public SpellScript { - PrepareSpellScript(spell_ulduar_proximity_minesSpellScript); + PrepareSpellScript(spell_mimiron_clear_fires_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (GetHitCreature()) + GetHitCreature()->DespawnOrUnsummon(); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_clear_fires_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_clear_fires_SpellScript(); + } +}; + +// 64463 - Despawn Assault Bots +class spell_mimiron_despawn_assault_bots : public SpellScriptLoader +{ + public: + spell_mimiron_despawn_assault_bots() : SpellScriptLoader("spell_mimiron_despawn_assault_bots") { } + + class spell_mimiron_despawn_assault_bots_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_despawn_assault_bots_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (GetHitCreature()) + GetHitCreature()->DespawnOrUnsummon(); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_despawn_assault_bots_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_despawn_assault_bots_SpellScript(); + } +}; + +// 64618 - Fire Search +class spell_mimiron_fire_search : public SpellScriptLoader +{ + public: + spell_mimiron_fire_search() : SpellScriptLoader("spell_mimiron_fire_search") { } + + class spell_mimiron_fire_search_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_fire_search_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_WATER_SPRAY)) + return false; + return true; + } + + bool Load() override + { + _noTarget = false; + return true; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + _noTarget = targets.empty(); + if (_noTarget) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void HandleAftercast() + { + if (_noTarget) + GetCaster()->GetMotionMaster()->MoveRandom(15.0f); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + + if (UnitAI* ai = caster->GetAI()) + { + if (caster->GetDistance2d(GetHitUnit()) <= 15.0f && ai->GetData(DATA_WATERSPRAY)) + { + caster->CastSpell(GetHitUnit(), SPELL_WATER_SPRAY, true); + ai->SetData(DATA_WATERSPRAY, 0); + ai->SetData(DATA_MOVE_NEW, 1); + } + else if (caster->GetAI()->GetData(DATA_MOVE_NEW)) + { + caster->GetMotionMaster()->MoveChase(GetHitUnit()); + ai->SetData(DATA_MOVE_NEW, 0); + } + } + } + + void Register() override + { + AfterCast += SpellCastFn(spell_mimiron_fire_search_SpellScript::HandleAftercast); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mimiron_fire_search_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_mimiron_fire_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + + private: + bool _noTarget; + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_fire_search_SpellScript(); + } +}; + +// 64436 - Magnetic Core +class spell_mimiron_magnetic_core : public SpellScriptLoader +{ + public: + spell_mimiron_magnetic_core() : SpellScriptLoader("spell_mimiron_magnetic_core") { } + + class spell_mimiron_magnetic_core_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_magnetic_core_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if([](WorldObject* obj) { return obj->ToUnit() && (obj->ToUnit()->GetVehicleBase() || obj->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)); }); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mimiron_magnetic_core_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_magnetic_core_SpellScript(); + } + + class spell_mimiron_magnetic_core_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mimiron_magnetic_core_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_MAGNETIC_CORE_VISUAL)) + return false; + return true; + } + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + { + target->GetAI()->DoAction(DO_DISABLE_AERIAL); + target->CastSpell(target, SPELL_MAGNETIC_CORE_VISUAL, true); + } + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + { + target->GetAI()->DoAction(DO_ENABLE_AERIAL); + target->RemoveAurasDueToSpell(SPELL_MAGNETIC_CORE_VISUAL); + } + } - void HandleScript(SpellEffIndex effIndex) + void OnRemoveSelf(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (TempSummon* summ = GetTarget()->ToTempSummon()) + summ->DespawnOrUnsummon(); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_mimiron_magnetic_core_AuraScript::OnApply, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_mimiron_magnetic_core_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_mimiron_magnetic_core_AuraScript::OnRemoveSelf, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mimiron_magnetic_core_AuraScript(); + } +}; + +// 63667 - Napalm Shell +class spell_mimiron_napalm_shell : public SpellScriptLoader +{ + public: + spell_mimiron_napalm_shell() : SpellScriptLoader("spell_mimiron_napalm_shell") { } + + class spell_mimiron_napalm_shell_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_napalm_shell_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_NAPALM_SHELL)) + return false; + return true; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + + targets.remove_if(Trinity::AllWorldObjectsInRange(GetCaster(), 15.0f)); + + if (!targets.empty()) + target = Trinity::Containers::SelectRandomContainerElement(targets); + + targets.clear(); + targets.push_back(target); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_NAPALM_SHELL); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mimiron_napalm_shell_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_mimiron_napalm_shell_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_napalm_shell_SpellScript(); + } +}; + +// 63274 - P3Wx2 Laser Barrage -- HACK! Core will currently not set UNIT_FIELD_CHANNEL_OBJECT automatially if the spell targets more than a single target. +class spell_mimiron_p3wx2_laser_barrage : public SpellScriptLoader +{ + public: + spell_mimiron_p3wx2_laser_barrage() : SpellScriptLoader("spell_mimiron_p3wx2_laser_barrage") { } + + class spell_mimiron_p3wx2_laser_barrage_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_p3wx2_laser_barrage_SpellScript); + + void OnHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, GetHitUnit()->GetGUID()); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_p3wx2_laser_barrage_SpellScript::OnHit, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_p3wx2_laser_barrage_SpellScript(); + } +}; + +// 64542 - Plasma Blast +class spell_mimiron_plasma_blast : public SpellScriptLoader +{ + public: + spell_mimiron_plasma_blast() : SpellScriptLoader("spell_mimiron_plasma_blast") { } + + class spell_mimiron_plasma_blast_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_plasma_blast_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PLASMA_BLAST)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetVehicleKit() != nullptr; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetCaster()->GetVehicleKit()->GetPassenger(3)) + caster->CastSpell(GetHitUnit(), SPELL_PLASMA_BLAST); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_plasma_blast_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_plasma_blast_SpellScript(); + } +}; + +// 66351 - Explosion +class spell_mimiron_proximity_explosion : public SpellScriptLoader +{ + public: + spell_mimiron_proximity_explosion() : SpellScriptLoader("spell_mimiron_proximity_explosion") { } + + class spell_mimiron_proximity_explosion_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_proximity_explosion_SpellScript); + + void OnHit(SpellEffIndex /*effIndex*/) + { + if (GetHitPlayer()) + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (Creature* mkII = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_LEVIATHAN_MK_II))) + mkII->AI()->SetData(DATA_SETUP_MINE, 0); + } + + void HandleAura(SpellEffIndex /*effIndex*/) + { + GetCaster()->RemoveAurasDueToSpell(SPELL_PROXIMITY_MINE_PERIODIC_TRIGGER); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_proximity_explosion_SpellScript::OnHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + OnEffectHitTarget += SpellEffectFn(spell_mimiron_proximity_explosion_SpellScript::HandleAura, EFFECT_1, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_proximity_explosion_SpellScript(); + } +}; + +// 63027 - Proximity Mines +class spell_mimiron_proximity_mines : public SpellScriptLoader +{ + public: + spell_mimiron_proximity_mines() : SpellScriptLoader("spell_mimiron_proximity_mines") { } + + class spell_mimiron_proximity_mines_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_proximity_mines_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_PROXIMITY_MINE)) + return false; + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) { - PreventHitDefaultEffect(effIndex); for (uint8 i = 0; i < 10; ++i) - GetCaster()->CastSpell(GetCaster(), SPELL_TRIGGER_MISSILE, true); + GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_PROXIMITY_MINE, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_proximity_mines_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_proximity_mines_SpellScript(); + } +}; + +// 65346 - Proximity Mine +class spell_mimiron_proximity_trigger : public SpellScriptLoader +{ + public: + spell_mimiron_proximity_trigger() : SpellScriptLoader("spell_mimiron_proximity_trigger") { } + + class spell_mimiron_proximity_trigger_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_proximity_trigger_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_PROXIMITY_MINE_EXPLOSION)) + return false; + return true; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove(GetExplTargetWorldObject()); + + if (targets.empty()) + FinishCast(SPELL_FAILED_NO_VALID_TARGETS); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell((Unit*)NULL, SPELL_PROXIMITY_MINE_EXPLOSION, true); } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_ulduar_proximity_minesSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mimiron_proximity_trigger_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHit += SpellEffectFn(spell_mimiron_proximity_trigger_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; SpellScript* GetSpellScript() const override { - return new spell_ulduar_proximity_minesSpellScript(); + return new spell_mimiron_proximity_trigger_SpellScript(); + } +}; + +// 63382 - Rapid Burst +class spell_mimiron_rapid_burst : public SpellScriptLoader +{ + public: + spell_mimiron_rapid_burst() : SpellScriptLoader("spell_mimiron_rapid_burst") { } + + class spell_mimiron_rapid_burst_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mimiron_rapid_burst_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_RAPID_BURST_LEFT) || !sSpellMgr->GetSpellInfo(SPELL_RAPID_BURST_RIGHT)) + return false; + return true; + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (TempSummon* summ = GetTarget()->ToTempSummon()) + summ->DespawnOrUnsummon(); + } + + void HandleDummyTick(AuraEffect const* aurEff) + { + if (GetCaster()) + GetCaster()->CastSpell(GetTarget(), aurEff->GetTickNumber() % 2 == 0 ? SPELL_RAPID_BURST_RIGHT : SPELL_RAPID_BURST_LEFT, true, NULL, aurEff); + } + + void Register() override + { + AfterEffectRemove += AuraEffectApplyFn(spell_mimiron_rapid_burst_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mimiron_rapid_burst_AuraScript::HandleDummyTick, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mimiron_rapid_burst_AuraScript(); + } +}; + +// 64402 - Rocket Strike, 65034 - Rocket Strike +class spell_mimiron_rocket_strike : public SpellScriptLoader +{ + public: + spell_mimiron_rocket_strike() : SpellScriptLoader("spell_mimiron_rocket_strike") { } + + class spell_mimiron_rocket_strike_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_rocket_strike_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SCRIPT_EFFECT_ROCKET_STRIKE)) + return false; + return true; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + if (m_scriptSpellId == SPELL_ROCKET_STRIKE_LEFT && GetCaster()->IsVehicle()) + if (WorldObject* target = GetCaster()->GetVehicleKit()->GetPassenger(6)) + { + targets.clear(); + targets.push_back(target); + } + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell((Unit*)NULL, SPELL_SCRIPT_EFFECT_ROCKET_STRIKE, true, NULL, NULL, GetCaster()->GetGUID()); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mimiron_rocket_strike_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_mimiron_rocket_strike_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_rocket_strike_SpellScript(); + } +}; + +// 63041 - Rocket Strike +class spell_mimiron_rocket_strike_damage : public SpellScriptLoader +{ + public: + spell_mimiron_rocket_strike_damage() : SpellScriptLoader("spell_mimiron_rocket_strike_damage") { } + + class spell_mimiron_rocket_strike_damage_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_rocket_strike_damage_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_NOT_SO_FRIENDLY_FIRE)) + return false; + return true; + } + + void HandleAfterCast() + { + if (TempSummon* summ = GetCaster()->ToTempSummon()) + summ->DespawnOrUnsummon(); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (GetHitPlayer()) + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + if (Creature* mkii = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_LEVIATHAN_MK_II))) + mkii->AI()->SetData(DATA_SETUP_ROCKET, 0); + } + + void HandleFriendlyFire(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell((Unit*)NULL, SPELL_NOT_SO_FRIENDLY_FIRE, true); + } + + void Register() override + { + AfterCast += SpellCastFn(spell_mimiron_rocket_strike_damage_SpellScript::HandleAfterCast); + OnEffectHitTarget += SpellEffectFn(spell_mimiron_rocket_strike_damage_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + OnEffectHitTarget += SpellEffectFn(spell_mimiron_rocket_strike_damage_SpellScript::HandleFriendlyFire, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_rocket_strike_damage_SpellScript(); + } +}; + +// 63681 - Rocket Strike +class spell_mimiron_rocket_strike_target_select : public SpellScriptLoader +{ + public: + spell_mimiron_rocket_strike_target_select() : SpellScriptLoader("spell_mimiron_rocket_strike_target_select") { } + + class spell_mimiron_rocket_strike_target_select_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_rocket_strike_target_select_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ROCKET_STRIKE)) + return false; + return true; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + + targets.remove_if(Trinity::AllWorldObjectsInRange(GetCaster(), 15.0f)); + + if (!targets.empty()) + target = Trinity::Containers::SelectRandomContainerElement(targets); + + targets.clear(); + targets.push_back(target); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + GetCaster()->CastSpell(GetHitUnit(), SPELL_SUMMON_ROCKET_STRIKE, true, NULL, NULL, instance->GetData64(DATA_VX_001)); + GetCaster()->SetDisplayId(11686); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mimiron_rocket_strike_target_select_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_mimiron_rocket_strike_target_select_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_rocket_strike_target_select_SpellScript(); + } +}; + +// 64383 - Self Repair +class spell_mimiron_self_repair : public SpellScriptLoader +{ + public: + spell_mimiron_self_repair() : SpellScriptLoader("spell_mimiron_self_repair") { } + + class spell_mimiron_self_repair_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_self_repair_SpellScript); + + void HandleScript() + { + if (GetCaster()->GetAI()) + GetCaster()->GetAI()->DoAction(DO_ASSEMBLED_COMBAT); + } + + void Register() override + { + AfterHit += SpellHitFn(spell_mimiron_self_repair_SpellScript::HandleScript); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_self_repair_SpellScript(); + } +}; + +// 63414 - Spinning Up -- HACK! Core will currently not set UNIT_FIELD_CHANNEL_OBJECT automatially if the spell targets more than a single target. +// eff0 will hit both caster and target due to hack in spellmgr.cpp, it is necessary because caster will interrupt itself if aura is not active on caster. +class spell_mimiron_spinning_up : public SpellScriptLoader +{ + public: + spell_mimiron_spinning_up() : SpellScriptLoader("spell_mimiron_spinning_up") { } + + class spell_mimiron_spinning_up_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_spinning_up_SpellScript); + + void OnHit(SpellEffIndex /*effIndex*/) + { + if (GetHitUnit() != GetCaster()) + GetCaster()->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, GetHitUnit()->GetGUID()); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_spinning_up_SpellScript::OnHit, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_spinning_up_SpellScript(); + } +}; + +// 64426 - Summon Scrap Bot +class spell_mimiron_summon_assault_bot : public SpellScriptLoader +{ + public: + spell_mimiron_summon_assault_bot() : SpellScriptLoader("spell_mimiron_summon_assault_bot") { } + + class spell_mimiron_summon_assault_bot_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mimiron_summon_assault_bot_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ASSAULT_BOT)) + return false; + return true; + } + + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + if (InstanceScript* instance = caster->GetInstanceScript()) + if (instance->GetBossState(BOSS_MIMIRON) == IN_PROGRESS) + caster->CastSpell(caster, SPELL_SUMMON_ASSAULT_BOT, false, NULL, aurEff, instance->GetData64(DATA_AERIAL_COMMAND_UNIT)); + } + + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_mimiron_summon_assault_bot_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mimiron_summon_assault_bot_AuraScript(); + } +}; + +// 64425 - Summon Scrap Bot Trigger +class spell_mimiron_summon_assault_bot_target : public SpellScriptLoader +{ + public: + spell_mimiron_summon_assault_bot_target() : SpellScriptLoader("spell_mimiron_summon_assault_bot_target") { } + + class spell_mimiron_summon_assault_bot_target_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_summon_assault_bot_target_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ASSAULT_BOT_DUMMY)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUMMON_ASSAULT_BOT_DUMMY, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_summon_assault_bot_target_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_summon_assault_bot_target_SpellScript(); + } +}; + +// 64621 - Summon Fire Bot +class spell_mimiron_summon_fire_bot : public SpellScriptLoader +{ + public: + spell_mimiron_summon_fire_bot() : SpellScriptLoader("spell_mimiron_summon_fire_bot") { } + + class spell_mimiron_summon_fire_bot_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mimiron_summon_fire_bot_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_FIRE_BOT)) + return false; + + return true; + } + + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + if (InstanceScript* instance = caster->GetInstanceScript()) + if (instance->GetBossState(BOSS_MIMIRON) == IN_PROGRESS) + caster->CastSpell(caster, SPELL_SUMMON_FIRE_BOT, false, NULL, aurEff, instance->GetData64(DATA_AERIAL_COMMAND_UNIT)); + } + + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_mimiron_summon_fire_bot_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mimiron_summon_fire_bot_AuraScript(); + } +}; + +// 64620 - Summon Fire Bot Trigger +class spell_mimiron_summon_fire_bot_target : public SpellScriptLoader +{ + public: + spell_mimiron_summon_fire_bot_target() : SpellScriptLoader("spell_mimiron_summon_fire_bot_target") { } + + class spell_mimiron_summon_fire_bot_target_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_summon_fire_bot_target_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_FIRE_BOT_DUMMY)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUMMON_FIRE_BOT_DUMMY, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_summon_fire_bot_target_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_summon_fire_bot_target_SpellScript(); + } +}; + +// 64562 - Summon Flames Spread Trigger +class spell_mimiron_summon_flames_spread : public SpellScriptLoader +{ + public: + spell_mimiron_summon_flames_spread() : SpellScriptLoader("spell_mimiron_summon_flames_spread") { } + + class spell_mimiron_summon_flames_spread_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_summon_flames_spread_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + // Flames must chase the closest player + WorldObject* target = targets.front(); + + for (std::list<WorldObject*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter) + if (GetCaster()->GetDistance2d(*iter) < GetCaster()->GetDistance2d(target)) + target = *iter; + + targets.clear(); + targets.push_back(target); + } + + void OnHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->SetInFront(GetHitUnit()); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mimiron_summon_flames_spread_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_mimiron_summon_flames_spread_SpellScript::OnHit, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_summon_flames_spread_SpellScript(); + } + + class spell_mimiron_summon_flames_spread_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mimiron_summon_flames_spread_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_FLAMES_SPREAD)) + return false; + return true; + } + + void HandleTick(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + if (Unit* caster = GetCaster()) + if (caster->HasAura(SPELL_FLAMES_PERIODIC_TRIGGER)) + caster->CastSpell(GetTarget(), SPELL_SUMMON_FLAMES_SPREAD, true); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mimiron_summon_flames_spread_AuraScript::HandleTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mimiron_summon_flames_spread_AuraScript(); + } +}; + +// 64623 - Frost Bomb +class spell_mimiron_summon_frost_bomb_target : public SpellScriptLoader +{ + public: + spell_mimiron_summon_frost_bomb_target() : SpellScriptLoader("spell_mimiron_summon_frost_bomb_target") { } + + class spell_mimiron_summon_frost_bomb_target_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_summon_frost_bomb_target_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_FROST_BOMB)) + return false; + return true; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + targets.remove_if(Trinity::AllWorldObjectsInRange(GetCaster(), 15.0f)); + + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + + targets.clear(); + targets.push_back(target); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_SUMMON_FROST_BOMB, true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mimiron_summon_frost_bomb_target_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_mimiron_summon_frost_bomb_target_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_summon_frost_bomb_target_SpellScript(); + } +}; + +// 64398 - Summon Scrap Bot +class spell_mimiron_summon_junk_bot : public SpellScriptLoader +{ + public: + spell_mimiron_summon_junk_bot() : SpellScriptLoader("spell_mimiron_summon_junk_bot") { } + + class spell_mimiron_summon_junk_bot_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mimiron_summon_junk_bot_AuraScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_JUNK_BOT)) + return false; + return true; + } + + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (Unit* caster = GetCaster()) + if (InstanceScript* instance = caster->GetInstanceScript()) + if (instance->GetBossState(BOSS_MIMIRON) == IN_PROGRESS) + caster->CastSpell(caster, SPELL_SUMMON_JUNK_BOT, false, NULL, aurEff, instance->GetData64(DATA_AERIAL_COMMAND_UNIT)); + } + + void Register() override + { + OnEffectRemove += AuraEffectRemoveFn(spell_mimiron_summon_junk_bot_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mimiron_summon_junk_bot_AuraScript(); + } +}; + +// 63820 - Summon Scrap Bot Trigger +class spell_mimiron_summon_junk_bot_target : public SpellScriptLoader +{ + public: + spell_mimiron_summon_junk_bot_target() : SpellScriptLoader("spell_mimiron_summon_junk_bot_target") { } + + class spell_mimiron_summon_junk_bot_target_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mimiron_summon_junk_bot_target_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_JUNK_BOT_DUMMY)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUMMON_JUNK_BOT_DUMMY, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mimiron_summon_junk_bot_target_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mimiron_summon_junk_bot_target_SpellScript(); + } +}; + +// 63339 - Weld +class spell_mimiron_weld : public SpellScriptLoader +{ + public: + spell_mimiron_weld() : SpellScriptLoader("spell_mimiron_weld") { } + + class spell_mimiron_weld_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mimiron_weld_AuraScript); + + void HandleTick(AuraEffect const* aurEff) + { + Unit* caster = GetTarget(); + if (Unit* vehicle = caster->GetVehicleBase()) + { + if (aurEff->GetTickNumber() % 5 == 0) + caster->CastSpell(vehicle, RepairSpells[urand(0, 3)]); + caster->SetFacingToObject(vehicle); + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mimiron_weld_AuraScript::HandleTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mimiron_weld_AuraScript(); } }; void AddSC_boss_mimiron() { - new spell_ulduar_proximity_mines(); + new spell_mimiron_bomb_bot(); + new spell_mimiron_clear_fires(); + new spell_mimiron_despawn_assault_bots(); + new spell_mimiron_fire_search(); + new spell_mimiron_magnetic_core(); + new spell_mimiron_napalm_shell(); + new spell_mimiron_p3wx2_laser_barrage(); + new spell_mimiron_plasma_blast(); + new spell_mimiron_proximity_explosion(); + new spell_mimiron_proximity_mines(); + new spell_mimiron_proximity_trigger(); + new spell_mimiron_rapid_burst(); + new spell_mimiron_rocket_strike(); + new spell_mimiron_rocket_strike_damage(); + new spell_mimiron_rocket_strike_target_select(); + new spell_mimiron_self_repair(); + new spell_mimiron_spinning_up(); + new spell_mimiron_summon_assault_bot(); + new spell_mimiron_summon_assault_bot_target(); + new spell_mimiron_summon_fire_bot(); + new spell_mimiron_summon_fire_bot_target(); + new spell_mimiron_summon_flames_spread(); + new spell_mimiron_summon_frost_bomb_target(); + new spell_mimiron_summon_junk_bot(); + new spell_mimiron_summon_junk_bot_target(); + new spell_mimiron_weld(); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index ed909d459ca..399113e18c8 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -711,7 +711,7 @@ class npc_expedition_commander : public CreatureScript { case GOSSIP_ACTION_INFO_DEF: player->CLOSE_GOSSIP_MENU(); - CAST_AI(npc_expedition_commanderAI, creature->AI())->Phase = 1; + ENSURE_AI(npc_expedition_commanderAI, creature->AI())->Phase = 1; break; } return true; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp index 4abf46be448..2471b705b90 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp @@ -839,7 +839,7 @@ class boss_sara : public CreatureScript { Position pos; float radius = frand(25.0f, 50.0f); - float angle = frand(0.0f, 2.0f * M_PI); + float angle = frand(0.0f, 2.0f * float(M_PI)); pos.m_positionX = YoggSaronSpawnPos.GetPositionX() + radius * cosf(angle); pos.m_positionY = YoggSaronSpawnPos.GetPositionY() + radius * sinf(angle); pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), YoggSaronSpawnPos.GetPositionZ() + 5.0f); @@ -1119,7 +1119,7 @@ class npc_ominous_cloud : public CreatureScript void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) { - float step = clockwise ? -M_PI / 8.0f : M_PI / 8.0f; + float step = clockwise ? float(-M_PI) / 8.0f : float(M_PI) / 8.0f; float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY()); for (uint8 i = 0; i < 16; angle += step, ++i) @@ -2502,7 +2502,7 @@ class spell_yogg_saron_empowered : public SpellScriptLoader // 64161 void OnPeriodic(AuraEffect const* /*aurEff*/) { Unit* target = GetTarget(); - float stack = ceil((target->GetHealthPct() / 10) - 1); + float stack = std::ceil((target->GetHealthPct() / 10) - 1); target->RemoveAurasDueToSpell(SPELL_EMPOWERED_BUFF); if (stack) diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp index 6aa753eac98..79f9283eb40 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp @@ -15,13 +15,12 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "InstanceScript.h" +#include "ulduar.h" #include "Player.h" -#include "WorldPacket.h" +#include "ScriptedCreature.h" +#include "ScriptMgr.h" #include "SpellScript.h" -#include "ulduar.h" +#include "WorldPacket.h" static DoorData const doorData[] = { @@ -32,6 +31,9 @@ static DoorData const doorData[] = { GO_HODIR_ENTRANCE, BOSS_HODIR, DOOR_TYPE_ROOM, BOUNDARY_E }, { GO_HODIR_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, { GO_HODIR_ICE_DOOR, BOSS_HODIR, DOOR_TYPE_PASSAGE, BOUNDARY_W }, + { GO_MIMIRON_DOOR_1, BOSS_MIMIRON, DOOR_TYPE_ROOM, BOUNDARY_W }, + { GO_MIMIRON_DOOR_2, BOSS_MIMIRON, DOOR_TYPE_ROOM, BOUNDARY_E }, + { GO_MIMIRON_DOOR_3, BOSS_MIMIRON, DOOR_TYPE_ROOM, BOUNDARY_S }, { GO_VEZAX_DOOR, BOSS_VEZAX, DOOR_TYPE_PASSAGE, BOUNDARY_E }, { GO_YOGG_SARON_DOOR, BOSS_YOGG_SARON, DOOR_TYPE_ROOM, BOUNDARY_S }, { GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_W }, @@ -70,11 +72,14 @@ class instance_ulduar : public InstanceMapScript uint64 AssemblyGUIDs[3]; uint64 KologarnGUID; uint64 AuriayaGUID; - uint64 MimironGUID; uint64 HodirGUID; uint64 ThorimGUID; uint64 FreyaGUID; uint64 ElderGUIDs[3]; + uint64 MimironGUID; + uint64 MimironVehicleGUIDs[3]; + uint64 MimironComputerGUID; + uint64 MimironWorldTriggerGUID; uint64 VezaxGUID; uint64 YoggSaronGUID; uint64 VoiceOfYoggSaronGUID; @@ -92,6 +97,9 @@ class instance_ulduar : public InstanceMapScript uint64 ThorimChestGUID; uint64 HodirRareCacheGUID; uint64 HodirChestGUID; + uint64 MimironTramGUID; + uint64 MimironElevatorGUID; + uint64 MimironButtonGUID; uint64 BrainRoomDoorGUIDs[3]; uint64 AlgalonSigilDoorGUID[3]; uint64 AlgalonFloorGUID[2]; @@ -126,6 +134,8 @@ class instance_ulduar : public InstanceMapScript KologarnGUID = 0; AuriayaGUID = 0; MimironGUID = 0; + MimironComputerGUID = 0; + MimironWorldTriggerGUID = 0; HodirGUID = 0; ThorimGUID = 0; FreyaGUID = 0; @@ -140,6 +150,9 @@ class instance_ulduar : public InstanceMapScript ThorimChestGUID = 0; HodirRareCacheGUID = 0; HodirChestGUID = 0; + MimironTramGUID = 0; + MimironElevatorGUID = 0; + MimironButtonGUID = 0; LeviathanGateGUID = 0; AlgalonUniverseGUID = 0; AlgalonTrapdoorGUID = 0; @@ -166,6 +179,7 @@ class instance_ulduar : public InstanceMapScript memset(AssemblyGUIDs, 0, sizeof(AssemblyGUIDs)); memset(RazorHarpoonGUIDs, 0, sizeof(RazorHarpoonGUIDs)); memset(ElderGUIDs, 0, sizeof(ElderGUIDs)); + memset(MimironVehicleGUIDs, 0, sizeof(MimironVehicleGUIDs)); memset(BrainRoomDoorGUIDs, 0, sizeof(BrainRoomDoorGUIDs)); memset(KeeperGUIDs, 0, sizeof(KeeperGUIDs)); memset(_summonObservationRingKeeper, false, sizeof(_summonObservationRingKeeper)); @@ -289,9 +303,6 @@ class instance_ulduar : public InstanceMapScript case NPC_AURIAYA: AuriayaGUID = creature->GetGUID(); break; - case NPC_MIMIRON: - MimironGUID = creature->GetGUID(); - break; // Hodir case NPC_HODIR: @@ -354,6 +365,26 @@ class instance_ulduar : public InstanceMapScript creature->DespawnOrUnsummon(); break; + // Mimiron + case NPC_MIMIRON: + MimironGUID = creature->GetGUID(); + break; + case NPC_LEVIATHAN_MKII: + MimironVehicleGUIDs[0] = creature->GetGUID(); + break; + case NPC_VX_001: + MimironVehicleGUIDs[1] = creature->GetGUID(); + break; + case NPC_AERIAL_COMMAND_UNIT: + MimironVehicleGUIDs[2] = creature->GetGUID(); + break; + case NPC_COMPUTER: + MimironComputerGUID = creature->GetGUID(); + break; + case NPC_WORLD_TRIGGER_MIMIRON: + MimironWorldTriggerGUID = creature->GetGUID(); + break; + case NPC_VEZAX: VezaxGUID = creature->GetGUID(); break; @@ -470,6 +501,15 @@ class instance_ulduar : public InstanceMapScript case GO_HODIR_CHEST: HodirChestGUID = gameObject->GetGUID(); break; + case GO_MIMIRON_TRAM: + MimironTramGUID = gameObject->GetGUID(); + break; + case GO_MIMIRON_ELEVATOR: + MimironElevatorGUID = gameObject->GetGUID(); + break; + case GO_MIMIRON_BUTTON: + MimironButtonGUID = gameObject->GetGUID(); + break; case GO_LEVIATHAN_GATE: LeviathanGateGUID = gameObject->GetGUID(); if (GetBossState(BOSS_LEVIATHAN) == DONE) @@ -482,6 +522,9 @@ class instance_ulduar : public InstanceMapScript case GO_HODIR_ENTRANCE: case GO_HODIR_DOOR: case GO_HODIR_ICE_DOOR: + case GO_MIMIRON_DOOR_1: + case GO_MIMIRON_DOOR_2: + case GO_MIMIRON_DOOR_3: case GO_VEZAX_DOOR: case GO_YOGG_SARON_DOOR: AddDoor(gameObject, true); @@ -566,6 +609,9 @@ class instance_ulduar : public InstanceMapScript case GO_HODIR_ENTRANCE: case GO_HODIR_DOOR: case GO_HODIR_ICE_DOOR: + case GO_MIMIRON_DOOR_1: + case GO_MIMIRON_DOOR_2: + case GO_MIMIRON_DOOR_3: case GO_VEZAX_DOOR: case GO_YOGG_SARON_DOOR: case GO_DOODAD_UL_SIGILDOOR_03: @@ -774,6 +820,10 @@ class instance_ulduar : public InstanceMapScript break; case DATA_UNBROKEN: Unbroken = data != 0; + break; + case DATA_MIMIRON_ELEVATOR: + if (GameObject* gameObject = instance->GetGameObject(MimironElevatorGUID)) + gameObject->SetGoState((GOState)data); break; case DATA_ILLUSION: illusion = data; @@ -846,8 +896,6 @@ class instance_ulduar : public InstanceMapScript return KologarnGUID; case BOSS_AURIAYA: return AuriayaGUID; - case BOSS_MIMIRON: - return MimironGUID; case BOSS_HODIR: return HodirGUID; case BOSS_THORIM: @@ -863,6 +911,22 @@ class instance_ulduar : public InstanceMapScript case BOSS_STONEBARK: return ElderGUIDs[2]; + // Mimiron + case BOSS_MIMIRON: + return MimironGUID; + case DATA_LEVIATHAN_MK_II: + return MimironVehicleGUIDs[0]; + case DATA_VX_001: + return MimironVehicleGUIDs[1]; + case DATA_AERIAL_COMMAND_UNIT: + return MimironVehicleGUIDs[2]; + case DATA_COMPUTER: + return MimironComputerGUID; + case DATA_MIMIRON_WORLD_TRIGGER: + return MimironWorldTriggerGUID; + case DATA_MIMIRON_BUTTON: + return MimironButtonGUID; + case BOSS_VEZAX: return VezaxGUID; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h index 3544ff3c079..81cb469318f 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h @@ -18,6 +18,7 @@ #ifndef DEF_ULDUAR_H #define DEF_ULDUAR_H +#include "InstanceScript.h" #include "ObjectMgr.h" #define UlduarScriptName "instance_ulduar" @@ -83,6 +84,18 @@ enum UlduarNPCs NPC_LEVIATHAN_MKII = 33432, NPC_VX_001 = 33651, NPC_AERIAL_COMMAND_UNIT = 33670, + NPC_ASSAULT_BOT = 34057, + NPC_BOMB_BOT = 33836, + NPC_JUNK_BOT = 33855, + NPC_EMERGENCY_FIRE_BOT = 34147, + NPC_FROST_BOMB = 34149, + NPC_BURST_TARGET = 34211, + NPC_FLAME = 34363, + NPC_FLAME_SPREAD = 34121, + NPC_DB_TARGET = 33576, + NPC_ROCKET_MIMIRON_VISUAL = 34050, + NPC_WORLD_TRIGGER_MIMIRON = 21252, + NPC_COMPUTER = 34143, // Freya's Keepers NPC_IRONBRANCH = 32913, @@ -204,6 +217,18 @@ enum UlduarGameObjects GO_THORIM_CHEST_HERO = 194315, GO_THORIM_CHEST = 194314, + // Mimiron + GO_MIMIRON_TRAM = 194675, + GO_MIMIRON_ELEVATOR = 194749, + GO_MIMIRON_BUTTON = 194739, + GO_MIMIRON_DOOR_1 = 194774, + GO_MIMIRON_DOOR_2 = 194775, + GO_MIMIRON_DOOR_3 = 194776, + GO_CACHE_OF_INNOVATION = 194789, + GO_CACHE_OF_INNOVATION_FIREFIGHTER = 194957, + GO_CACHE_OF_INNOVATION_HERO = 194956, + GO_CACHE_OF_INNOVATION_FIREFIGHTER_HERO = 194958, + // Vezax GO_VEZAX_DOOR = 194750, @@ -292,6 +317,16 @@ enum UlduarData // Hodir DATA_HODIR_RARE_CACHE, + // Mimiron + DATA_LEVIATHAN_MK_II, + DATA_VX_001, + DATA_AERIAL_COMMAND_UNIT, + DATA_COMPUTER, + DATA_MIMIRON_WORLD_TRIGGER, + DATA_MIMIRON_ELEVATOR, + DATA_MIMIRON_TRAM, + DATA_MIMIRON_BUTTON, + // Yogg-Saron DATA_VOICE_OF_YOGG_SARON, DATA_SARA, diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp index b623d5e6ddc..9e2bb85e27a 100644 --- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp @@ -267,7 +267,7 @@ public: { case GOSSIP_ACTION_INFO_DEF+1: player->CLOSE_GOSSIP_MENU(); - CAST_AI(npc_sinclari_vh::npc_sinclariAI, (creature->AI()))->uiPhase = 1; + ENSURE_AI(npc_sinclari_vh::npc_sinclariAI, (creature->AI()))->uiPhase = 1; if (InstanceScript* instance = creature->GetInstanceScript()) instance->SetData(DATA_MAIN_EVENT_PHASE, SPECIAL); break; diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index 08936df4589..7f34e470c7e 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -1263,8 +1263,8 @@ public: switch (action) { case GOSSIP_ACTION_INFO_DEF+1: - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - CAST_AI(npc_escortAI, (creature->AI()))->SetMaxPlayerDistance(200.0f); + ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + ENSURE_AI(npc_escortAI, (creature->AI()))->SetMaxPlayerDistance(200.0f); break; } return true; @@ -1301,7 +1301,7 @@ public: if (me->IsSummon()) if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - CAST_AI(npc_thassarian::npc_thassarianAI, summoner->ToCreature()->AI())->arthasInPosition = true; + ENSURE_AI(npc_thassarian::npc_thassarianAI, summoner->ToCreature()->AI())->arthasInPosition = true; } }; @@ -1333,7 +1333,7 @@ public: me->CastSpell(me, SPELL_STUN, true); if (me->IsSummon()) if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - CAST_AI(npc_thassarian::npc_thassarianAI, summoner->ToCreature()->AI())->arlosInPosition = true; + ENSURE_AI(npc_thassarian::npc_thassarianAI, summoner->ToCreature()->AI())->arlosInPosition = true; } }; @@ -1387,7 +1387,7 @@ public: if (me->IsSummon()) if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - CAST_AI(npc_thassarian::npc_thassarianAI, summoner->ToCreature()->AI())->talbotInPosition = true; + ENSURE_AI(npc_thassarian::npc_thassarianAI, summoner->ToCreature()->AI())->talbotInPosition = true; } void UpdateAI(uint32 diff) override @@ -1491,14 +1491,14 @@ public: if (!bDone) { if (Creature* talbot = me->FindNearestCreature(NPC_PRINCE_VALANAR, 50.0f, true)) - CAST_AI(npc_counselor_talbot::npc_counselor_talbotAI, talbot->GetAI())->bCheck = true; + ENSURE_AI(npc_counselor_talbot::npc_counselor_talbotAI, talbot->GetAI())->bCheck = true; me->AddUnitState(UNIT_STATE_STUNNED); me->CastSpell(me, SPELL_STUN, true); if (me->IsSummon()) if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - CAST_AI(npc_thassarian::npc_thassarianAI, summoner->GetAI())->leryssaInPosition = true; + ENSURE_AI(npc_thassarian::npc_thassarianAI, summoner->GetAI())->leryssaInPosition = true; bDone = true; } else @@ -1566,7 +1566,7 @@ public: if (Creature* thassarian = summoner->ToCreature()) { thassarian->AI()->Talk(SAY_THASSARIAN_7); - CAST_AI(npc_thassarian::npc_thassarianAI, thassarian->GetAI())->phase = 16; + ENSURE_AI(npc_thassarian::npc_thassarianAI, thassarian->GetAI())->phase = 16; } phaseTimer = 5000; phase = 0; @@ -1812,7 +1812,7 @@ public: } creature->SetStandState(UNIT_STAND_STATE_STAND); creature->AI()->Talk(SAY_1); - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); } return true; } @@ -1893,7 +1893,7 @@ public: { creature->SetStandState(UNIT_STAND_STATE_STAND); creature->AI()->Talk(SAY_BONKER_2, player); - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, true, player->GetGUID()); + ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, true, player->GetGUID()); } return true; } diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp index d0fd948ce6a..6d41a2e9b21 100644 --- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp +++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp @@ -718,7 +718,7 @@ public: if (me->GetEntry() == NPC_LAKE_FROG) { me->AddAura(SPELL_FROG_LOVE, me); - me->GetMotionMaster()->MoveFollow(player, 0.3f, frand(M_PI/2, M_PI + (M_PI/2))); + me->GetMotionMaster()->MoveFollow(player, 0.3f, frand(float(M_PI) / 2, float(M_PI) + (float(M_PI) / 2))); _following = true; } else if (me->GetEntry() == NPC_LAKE_FROG_QUEST) diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp index c577fb2864f..96fdcbfe990 100644 --- a/src/server/scripts/Northrend/zone_howling_fjord.cpp +++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp @@ -67,7 +67,7 @@ public: creature->setFaction(FACTION_ESCORTEE_H); break; } - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); } return true; } diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp index 3ec138dcfaa..a4d6ab31846 100644 --- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp +++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp @@ -18,12 +18,11 @@ /* ScriptData SDName: Sholazar_Basin SD%Complete: 100 -SDComment: Quest support: 12570, 12573, 12621, 12726 +SDComment: Quest support: 12573, 12621, 12726 SDCategory: Sholazar_Basin EndScriptData */ /* ContentData -npc_injured_rainspeaker_oracle npc_vekjik avatar_of_freya npc_haiphoon (Quest: "Song of Wind and Water") @@ -40,141 +39,6 @@ EndContentData */ #include "Player.h" /*###### -## npc_injured_rainspeaker_oracle -######*/ - -#define GOSSIP_ITEM1 "I am ready to travel to your village now." - -enum Rainspeaker -{ - SAY_START_IRO = 0, - SAY_QUEST_ACCEPT_IRO = 1, - SAY_END_IRO = 2, - - QUEST_FORTUNATE_MISUNDERSTANDINGS = 12570, - FACTION_ESCORTEE_A = 774, - FACTION_ESCORTEE_H = 775 -}; - -class npc_injured_rainspeaker_oracle : public CreatureScript -{ -public: - npc_injured_rainspeaker_oracle() : CreatureScript("npc_injured_rainspeaker_oracle") { } - - struct npc_injured_rainspeaker_oracleAI : public npc_escortAI - { - npc_injured_rainspeaker_oracleAI(Creature* creature) : npc_escortAI(creature) { c_guid = creature->GetGUID(); } - - uint64 c_guid; - - void Reset() override - { - me->RestoreFaction(); - // if we will have other way to assign this to only one npc remove this part - if (GUID_LOPART(me->GetGUID()) != 101030) - { - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - } - } - - void WaypointReached(uint32 waypointId) override - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 1: - SetRun(); - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - me->RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING); - me->SetSpeed(MOVE_SWIM, 0.85f, true); - me->SetSwim(true); - me->SetDisableGravity(true); - break; - case 19: - me->GetMotionMaster()->MoveFall(); - break; - case 28: - player->GroupEventHappens(QUEST_FORTUNATE_MISUNDERSTANDINGS, me); - // me->RestoreFaction(); - Talk(SAY_END_IRO); - SetRun(false); - break; - } - } - - void JustDied(Unit* /*killer*/) override - { - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - return; - - if (Player* player = GetPlayerForEscort()) - { - if (player->GetQuestStatus(QUEST_FORTUNATE_MISUNDERSTANDINGS) != QUEST_STATUS_COMPLETE) - player->FailQuest(QUEST_FORTUNATE_MISUNDERSTANDINGS); - } - } - }; - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_FORTUNATE_MISUNDERSTANDINGS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - CAST_AI(npc_escortAI, (creature->AI()))->SetMaxPlayerDistance(35.0f); - creature->AI()->Talk(SAY_START_IRO); - - switch (player->GetTeam()){ - case ALLIANCE: - creature->setFaction(FACTION_ESCORTEE_A); - break; - case HORDE: - creature->setFaction(FACTION_ESCORTEE_H); - break; - } - } - return true; - } - - bool OnQuestAccept(Player* /*player*/, Creature* creature, Quest const* /*_Quest*/) override - { - creature->AI()->Talk(SAY_QUEST_ACCEPT_IRO); - return false; - } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_injured_rainspeaker_oracleAI(creature); - } -}; - -/*###### ## npc_vekjik ######*/ @@ -546,7 +410,7 @@ public: switch (phase) { case 1: - orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); + orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + std::cos(me->GetOrientation()) * 5, me->GetPositionY() + std::sin(me->GetOrientation()) * 5, me->GetPositionZ()); orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_6); timer = 5000; break; @@ -1143,7 +1007,6 @@ public: void AddSC_sholazar_basin() { - new npc_injured_rainspeaker_oracle(); new npc_vekjik(); new npc_avatar_of_freya(); new npc_bushwhacker(); diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp index cf8c4cd9b36..2e75b10c0e8 100644 --- a/src/server/scripts/Northrend/zone_zuldrak.cpp +++ b/src/server/scripts/Northrend/zone_zuldrak.cpp @@ -247,7 +247,7 @@ public: break; case EVENT_RECRUIT_2: me->SetWalk(true); - me->GetMotionMaster()->MovePoint(0, me->GetPositionX() + (cos(_heading) * 10), me->GetPositionY() + (sin(_heading) * 10), me->GetPositionZ()); + me->GetMotionMaster()->MovePoint(0, me->GetPositionX() + (std::cos(_heading) * 10), me->GetPositionY() + (std::sin(_heading) * 10), me->GetPositionZ()); me->DespawnOrUnsummon(5000); break; default: diff --git a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp index 2b3928f322a..7ba0a452941 100644 --- a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp +++ b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp @@ -225,9 +225,8 @@ public: if (Unit* target = ObjectAccessor::GetUnit(*me, soulholder)) { - - CAST_AI(npc_stolen_soul::npc_stolen_soulAI, summoned->AI())->SetMyClass(soulclass); - summoned->AI()->AttackStart(target); + ENSURE_AI(npc_stolen_soul::npc_stolen_soulAI, summoned->AI())->SetMyClass(soulclass); + summoned->AI()->AttackStart(target); } } } diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index ec89acfb7b6..08fc588e923 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -747,7 +747,7 @@ public: flame->setFaction(me->getFaction()); // Just in case the database has it as a different faction flame->SetMeleeDamageSchool(SPELL_SCHOOL_FIRE); FlameGUID[i] = flame->GetGUID(); // Record GUID in order to check if they're dead later on to move to the next phase - CAST_AI(npc_flame_of_azzinoth::flame_of_azzinothAI, flame->AI())->SetGlaiveGUID(GlaiveGUID[i]); + ENSURE_AI(npc_flame_of_azzinoth::flame_of_azzinothAI, flame->AI())->SetGlaiveGUID(GlaiveGUID[i]); glaive->CastSpell(flame, SPELL_AZZINOTH_CHANNEL, false); // Glaives do some random Beam type channel on it. } } @@ -1325,7 +1325,7 @@ public: me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); if (Creature* illidan = ObjectAccessor::GetCreature(*me, IllidanGUID)) - CAST_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->DeleteFromThreatList(me->GetGUID()); + ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->DeleteFromThreatList(me->GetGUID()); me->AttackStop(); Timer[EVENT_MAIEV_STEALTH] = 60000; // reappear after 1 minute MaxTimer = 1; @@ -1458,8 +1458,8 @@ public: illidan->SetInFront(me); me->GetMotionMaster()->MoveIdle(); illidan->GetMotionMaster()->MoveIdle(); - CAST_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->AkamaGUID = me->GetGUID(); - CAST_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->EnterPhase(PHASE_TALK_SEQUENCE); + ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->AkamaGUID = me->GetGUID(); + ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->EnterPhase(PHASE_TALK_SEQUENCE); } } @@ -1512,7 +1512,7 @@ public: else if (Phase == PHASE_TALK) { if (Creature* illidan = ObjectAccessor::GetCreature(*me, IllidanGUID)) - CAST_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->DeleteFromThreatList(me->GetGUID()); + ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->DeleteFromThreatList(me->GetGUID()); EnterEvadeMode(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); ++WalkCount; @@ -1566,7 +1566,7 @@ public: case 0: if (Creature* illidan = ObjectAccessor::GetCreature(*me, IllidanGUID)) { - CAST_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->Timer[EVENT_TAUNT] += 30000; + ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->Timer[EVENT_TAUNT] += 30000; illidan->AI()->Talk(SAY_ILLIDAN_MINION); } Timer = 8000; @@ -1849,7 +1849,7 @@ void boss_illidan_stormrage::boss_illidan_stormrageAI::JustSummoned(Creature* su summon->SetVisible(false); // Leave her invisible until she has to talk summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); MaievGUID = summon->GetGUID(); - CAST_AI(boss_maiev_shadowsong::boss_maievAI, summon->AI())->GetIllidanGUID(me->GetGUID()); + ENSURE_AI(boss_maiev_shadowsong::boss_maievAI, summon->AI())->GetIllidanGUID(me->GetGUID()); summon->AI()->DoAction(PHASE_TALK_SEQUENCE); } break; @@ -1881,7 +1881,7 @@ void boss_illidan_stormrage::boss_illidan_stormrageAI::HandleTalkSequence() { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); me->AddThreat(akama, 100.0f); - CAST_AI(npc_akama_illidan::npc_akama_illidanAI, akama->AI())->EnterPhase(PHASE_FIGHT_ILLIDAN); + ENSURE_AI(npc_akama_illidan::npc_akama_illidanAI, akama->AI())->EnterPhase(PHASE_FIGHT_ILLIDAN); EnterPhase(PHASE_NORMAL); } break; @@ -2040,7 +2040,7 @@ public: // Grid search for nearest live Creature of entry 23304 within 10 yards if (Creature* pTrigger = go->FindNearestCreature(23304, 10.0f)) - CAST_AI(npc_cage_trap_trigger::cage_trap_triggerAI, pTrigger->AI())->Active = true; + ENSURE_AI(npc_cage_trap_trigger::cage_trap_triggerAI, pTrigger->AI())->Active = true; go->SetGoState(GO_STATE_ACTIVE); return true; } @@ -2158,7 +2158,7 @@ public: && !me->EnsureVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND2)) { if (Creature* illidan = ObjectAccessor::GetCreature((*me), IllidanGUID))// summon only in 1. phase - if (CAST_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->Phase == PHASE_NORMAL) + if (ENSURE_AI(boss_illidan_stormrage::boss_illidan_stormrageAI, illidan->AI())->Phase == PHASE_NORMAL) me->CastSpell(me->GetVictim(), SPELL_PARASITIC_SHADOWFIEND2, true, 0, 0, IllidanGUID); // do not stack } me->AttackerStateUpdate(me->GetVictim()); diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp index 67d456286d5..f3c8af50328 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp @@ -215,7 +215,7 @@ public: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { - CAST_AI(npc_enslaved_soul::npc_enslaved_soulAI, Soul->AI())->ReliquaryGUID = me->GetGUID(); + ENSURE_AI(npc_enslaved_soul::npc_enslaved_soulAI, Soul->AI())->ReliquaryGUID = me->GetGUID(); Soul->AI()->AttackStart(target); } else EnterEvadeMode(); return true; @@ -379,7 +379,7 @@ void npc_enslaved_soul::npc_enslaved_soulAI::JustDied(Unit* /*killer*/) { if (ReliquaryGUID) if (Creature* Reliquary = (ObjectAccessor::GetCreature((*me), ReliquaryGUID))) - ++(CAST_AI(boss_reliquary_of_souls::boss_reliquary_of_soulsAI, Reliquary->AI())->SoulDeathCount); + ++(ENSURE_AI(boss_reliquary_of_souls::boss_reliquary_of_soulsAI, Reliquary->AI())->SoulDeathCount); DoCast(me, SPELL_SOUL_RELEASE, true); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp index b59d073c17d..f1e170c0705 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp @@ -244,8 +244,8 @@ public: if (me->GetAuraCount(SPELL_SHADE_SOUL_CHANNEL_2) <= 3) { - moveSpeed = (2.0 - (0.6 * me->GetAuraCount(SPELL_SHADE_SOUL_CHANNEL_2))); - me->SetSpeed(MOVE_WALK, moveSpeed / 2.5); + moveSpeed = (2.0f - (0.6f * me->GetAuraCount(SPELL_SHADE_SOUL_CHANNEL_2))); + me->SetSpeed(MOVE_WALK, moveSpeed / 2.5f); me->SetSpeed(MOVE_RUN, (moveSpeed * 2) / 7); me->ClearUnitState(UNIT_STATE_ROOT); } @@ -439,7 +439,7 @@ public: { if (Creature* Shade = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SHADE_OF_AKAMA))) if (Shade->IsAlive()) - CAST_AI(boss_shade_of_akama::boss_shade_of_akamaAI, Shade->AI())->HasKilledAkama = true; + ENSURE_AI(boss_shade_of_akama::boss_shade_of_akamaAI, Shade->AI())->HasKilledAkama = true; me->GetMotionMaster()->Clear(true); me->GetMotionMaster()->MoveIdle(); } @@ -778,7 +778,7 @@ public: void IsSummonedBy(Unit* /*summoner*/) override { if (Creature* summoner = (ObjectAccessor::GetCreature((*me), summonerGuid))) - CAST_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me); + ENSURE_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me); } void EnterCombat(Unit* /*who*/) override { } @@ -884,7 +884,7 @@ public: void IsSummonedBy(Unit* /*summoner*/) override { if (Creature* summoner = (ObjectAccessor::GetCreature((*me), summonerGuid))) - CAST_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me); + ENSURE_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me); } void EnterCombat(Unit* /*who*/) override @@ -974,7 +974,7 @@ public: void IsSummonedBy(Unit* /*summoner*/) override { if (Creature* summoner = (ObjectAccessor::GetCreature((*me), summonerGuid))) - CAST_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me); + ENSURE_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me); } void EnterCombat(Unit* /*who*/) override @@ -1054,7 +1054,7 @@ public: void IsSummonedBy(Unit* /*summoner*/) override { if (Creature* summoner = (ObjectAccessor::GetCreature((*me), summonerGuid))) - CAST_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me); + ENSURE_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me); } void EnterCombat(Unit* /*who*/) override @@ -1136,7 +1136,7 @@ public: void IsSummonedBy(Unit* /*summoner*/) override { if (Creature* summoner = (ObjectAccessor::GetCreature((*me), summonerGuid))) - CAST_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me); + ENSURE_AI(npc_creature_generator_akama::npc_creature_generator_akamaAI, summoner->AI())->JustSummoned(me); } void EnterCombat(Unit* /*who*/) override diff --git a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp index c2bf5966a5c..0bbf2cb2a96 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp @@ -366,7 +366,7 @@ public: { Construct->CastSpell(Construct, SPELL_PASSIVE_SHADOWFORM, true); SetThreatList(Construct); // Use same function as Doom Blossom to set Threat List. - CAST_AI(npc_shadowy_construct::npc_shadowy_constructAI, Construct->AI())->GhostGUID = GhostGUID; + ENSURE_AI(npc_shadowy_construct::npc_shadowy_constructAI, Construct->AI())->GhostGUID = GhostGUID; Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!target) // someone's trying to solo. target = me->GetVictim(); @@ -444,7 +444,7 @@ public: DoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoomBlossom->setFaction(me->getFaction()); DoomBlossom->AddThreat(target, 1.0f); - CAST_AI(npc_doom_blossom::npc_doom_blossomAI, DoomBlossom->AI())->SetTeronGUID(me->GetGUID()); + ENSURE_AI(npc_doom_blossom::npc_doom_blossomAI, DoomBlossom->AI())->SetTeronGUID(me->GetGUID()); target->CombatStart(DoomBlossom); SetThreatList(DoomBlossom); SummonDoomBlossomTimer = 35000; diff --git a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp index b9a9f41ca09..64a6add9801 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp @@ -226,7 +226,7 @@ public: { if (InstanceScript* instance = go->GetInstanceScript()) if (Creature* Najentus = ObjectAccessor::GetCreature(*go, instance->GetData64(DATA_HIGH_WARLORD_NAJENTUS))) - if (CAST_AI(boss_najentus::boss_najentusAI, Najentus->AI())->RemoveImpalingSpine()) + if (ENSURE_AI(boss_najentus::boss_najentusAI, Najentus->AI())->RemoveImpalingSpine()) { player->CastSpell(player, SPELL_CREATE_NAJENTUS_SPINE, true); go->Delete(); diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp index ba7730ba566..2c6bac4c9d9 100644 --- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp @@ -291,8 +291,8 @@ public: // Start the event for the Voice Trigger if (Creature* VoiceTrigger = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BLOOD_ELF_COUNCIL_VOICE))) { - CAST_AI(npc_blood_elf_council_voice_trigger::npc_blood_elf_council_voice_triggerAI, VoiceTrigger->AI())->LoadCouncilGUIDs(); - CAST_AI(npc_blood_elf_council_voice_trigger::npc_blood_elf_council_voice_triggerAI, VoiceTrigger->AI())->EventStarted = true; + ENSURE_AI(npc_blood_elf_council_voice_trigger::npc_blood_elf_council_voice_triggerAI, VoiceTrigger->AI())->LoadCouncilGUIDs(); + ENSURE_AI(npc_blood_elf_council_voice_trigger::npc_blood_elf_council_voice_triggerAI, VoiceTrigger->AI())->EventStarted = true; } for (uint8 i = 0; i < 4; ++i) @@ -393,7 +393,7 @@ struct boss_illidari_councilAI : public ScriptedAI void EnterCombat(Unit* who) override { if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ILLIDARI_COUNCIL))) - CAST_AI(npc_illidari_council::npc_illidari_councilAI, controller->AI())->StartEvent(who); + ENSURE_AI(npc_illidari_council::npc_illidari_councilAI, controller->AI())->StartEvent(who); DoZoneInCombat(); // Load GUIDs on first aggro because the Creature guids are only set as the creatures are created in world- // this means that for each creature, it will attempt to LoadGUIDs even though some of the other creatures are diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp index 0f9a10e5c4f..7e24f4b54b2 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp @@ -343,7 +343,7 @@ public: void JustDied(Unit* /*killer*/) override { if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KARATHRESS))) - CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventSharkkisDeath(); + ENSURE_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventSharkkisDeath(); } void EnterCombat(Unit* who) override @@ -469,7 +469,7 @@ public: void JustDied(Unit* /*killer*/) override { if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KARATHRESS))) - CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventTidalvessDeath(); + ENSURE_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventTidalvessDeath(); } void EnterCombat(Unit* who) override @@ -585,7 +585,7 @@ public: void JustDied(Unit* /*killer*/) override { if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KARATHRESS))) - CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventCaribdisDeath(); + ENSURE_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventCaribdisDeath(); } void EnterCombat(Unit* who) override diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp index f877ce83b37..a241f2bea37 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp @@ -621,7 +621,7 @@ public: DoCast(me, SPELL_SURGE); } if (Creature* vashj = ObjectAccessor::GetCreature(*me, VashjGUID)) - if (!vashj->IsInCombat() || CAST_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->Phase != 2 || vashj->isDead()) + if (!vashj->IsInCombat() || ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->Phase != 2 || vashj->isDead()) me->Kill(me); Move = 1000; } else Move -= diff; @@ -663,7 +663,7 @@ public: void JustDied(Unit* /*killer*/) override { if (Creature* vashj = ObjectAccessor::GetCreature((*me), instance->GetData64(DATA_LADYVASHJ))) - CAST_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->EventTaintedElementalDeath(); + ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->EventTaintedElementalDeath(); } void EnterCombat(Unit* who) override @@ -779,7 +779,7 @@ public: { // check if vashj is death Unit* Vashj = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_LADYVASHJ)); - if (!Vashj || !Vashj->IsAlive() || CAST_AI(boss_lady_vashj::boss_lady_vashjAI, Vashj->ToCreature()->AI())->Phase != 3) + if (!Vashj || !Vashj->IsAlive() || ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, Vashj->ToCreature()->AI())->Phase != 3) { // remove me->setDeathState(DEAD); @@ -866,7 +866,7 @@ public: } Creature* vashj = ObjectAccessor::GetCreature((*player), instance->GetData64(DATA_LADYVASHJ)); - if (vashj && (CAST_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->Phase == 2)) + if (vashj && (ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->Phase == 2)) { if (GameObject* gObj = targets.GetGOTarget()) { @@ -901,7 +901,7 @@ public: } // get and remove channel - if (Unit* channel = ObjectAccessor::GetCreature(*vashj, CAST_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->ShieldGeneratorChannel[channelIdentifier])) + if (Unit* channel = ObjectAccessor::GetCreature(*vashj, ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, vashj->AI())->ShieldGeneratorChannel[channelIdentifier])) channel->setDeathState(JUST_DIED); // call Unsummon() instance->SetData(identifier, 1); diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp index cc09952d336..fb5b4579942 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp @@ -278,7 +278,7 @@ public: if (me->IsWithinDistInMap(who, attackRadius)) { // Check first that object is in an angle in front of this one before LoS check - if (me->HasInArc(M_PI/2.0f, who) && me->IsWithinLOSInMap(who)) + if (me->HasInArc(float(M_PI) / 2.0f, who) && me->IsWithinLOSInMap(who)) { AttackStart(who); } @@ -703,7 +703,7 @@ public: instance->SetData64(DATA_LEOTHERAS_EVENT_STARTER, 0); Creature* leotheras = ObjectAccessor::GetCreature(*me, leotherasGUID); if (leotheras && leotheras->IsAlive()) - CAST_AI(boss_leotheras_the_blind::boss_leotheras_the_blindAI, leotheras->AI())->CheckChannelers(/*false*/); + ENSURE_AI(boss_leotheras_the_blind::boss_leotheras_the_blindAI, leotheras->AI())->CheckChannelers(/*false*/); } void EnterCombat(Unit* who) override diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_hydromancer_thespia.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_hydromancer_thespia.cpp index dc0a6643624..d4fdb262c8e 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_hydromancer_thespia.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_hydromancer_thespia.cpp @@ -19,156 +19,169 @@ #include "ScriptedCreature.h" #include "steam_vault.h" -enum HydromancerThespia +enum Yells { SAY_SUMMON = 0, SAY_AGGRO = 1, SAY_SLAY = 2, SAY_DEAD = 3, +}; +enum Spells +{ SPELL_LIGHTNING_CLOUD = 25033, SPELL_LUNG_BURST = 31481, - SPELL_ENVELOPING_WINDS = 31718, + SPELL_ENVELOPING_WINDS = 31718 +}; - SPELL_WATER_BOLT_VOLLEY = 34449, - H_SPELL_WATER_BOLT_VOLLEY = 37924 +enum Events +{ + EVENT_LIGHTNING_CLOUD = 1, + EVENT_LUNG_BURST, + EVENT_ENVELOPING_WINDS }; class boss_hydromancer_thespia : public CreatureScript { -public: - boss_hydromancer_thespia() : CreatureScript("boss_hydromancer_thespia") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_thespiaAI>(creature); - } - - struct boss_thespiaAI : public ScriptedAI - { - boss_thespiaAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 LightningCloud_Timer; - uint32 LungBurst_Timer; - uint32 EnvelopingWinds_Timer; - - void Reset() override - { - LightningCloud_Timer = 15000; - LungBurst_Timer = 7000; - EnvelopingWinds_Timer = 9000; - - instance->SetBossState(DATA_HYDROMANCER_THESPIA, NOT_STARTED); - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEAD); - - instance->SetBossState(DATA_HYDROMANCER_THESPIA, DONE); - } - - void KilledUnit(Unit* /*victim*/) override - { - Talk(SAY_SLAY); - } + public: + boss_hydromancer_thespia() : CreatureScript("boss_hydromancer_thespia") { } - void EnterCombat(Unit* /*who*/) override + struct boss_thespiaAI : public BossAI { - Talk(SAY_AGGRO); + boss_thespiaAI(Creature* creature) : BossAI(creature, DATA_HYDROMANCER_THESPIA) { } - instance->SetBossState(DATA_HYDROMANCER_THESPIA, IN_PROGRESS); - } + void Reset() override + { + _Reset(); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEAD); + _JustDied(); + } - //LightningCloud_Timer - if (LightningCloud_Timer <= diff) + void KilledUnit(Unit* who) override { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_LIGHTNING_CLOUD); + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - //cast twice in Heroic mode - if (IsHeroic()) - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_LIGHTNING_CLOUD); + void EnterCombat(Unit* /*who*/) override + { + Talk(SAY_AGGRO); + _EnterCombat(); - LightningCloud_Timer = 15000 + rand32() % 10000; - } else LightningCloud_Timer -=diff; + events.ScheduleEvent(EVENT_LIGHTNING_CLOUD, 15000); + events.ScheduleEvent(EVENT_LUNG_BURST, 7000); + events.ScheduleEvent(EVENT_ENVELOPING_WINDS, 9000); + } - //LungBurst_Timer - if (LungBurst_Timer <= diff) + void ExecuteEvent(uint32 eventId) override { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_LUNG_BURST); - LungBurst_Timer = 7000 + rand32() % 5000; - } else LungBurst_Timer -=diff; - - //EnvelopingWinds_Timer - if (EnvelopingWinds_Timer <= diff) + switch (eventId) + { + case EVENT_LIGHTNING_CLOUD: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true)) + DoCast(target, SPELL_LIGHTNING_CLOUD); + // cast twice in Heroic mode + if (IsHeroic()) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true)) + DoCast(target, SPELL_LIGHTNING_CLOUD); + + events.ScheduleEvent(EVENT_LIGHTNING_CLOUD, urand(15000, 25000)); + break; + case EVENT_LUNG_BURST: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + DoCast(target, SPELL_LUNG_BURST); + events.ScheduleEvent(EVENT_LUNG_BURST, urand(7000, 12000)); + break; + case EVENT_ENVELOPING_WINDS: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 35.0f, true)) + DoCast(target, SPELL_ENVELOPING_WINDS); + // cast twice in Heroic mode + if (IsHeroic()) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 35.0f, true)) + DoCast(target, SPELL_ENVELOPING_WINDS); + + events.ScheduleEvent(EVENT_ENVELOPING_WINDS, urand(10000, 15000)); + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_ENVELOPING_WINDS); - - //cast twice in Heroic mode - if (IsHeroic()) - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_ENVELOPING_WINDS); - EnvelopingWinds_Timer = 10000 + rand32() % 5000; - } else EnvelopingWinds_Timer -=diff; + BossAI::UpdateAI(diff); + } + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_thespiaAI>(creature); } - }; +}; +enum CoilfangWaterElemental +{ + EVENT_WATER_BOLT_VOLLEY = 1, + SPELL_WATER_BOLT_VOLLEY = 34449 }; class npc_coilfang_waterelemental : public CreatureScript { -public: - npc_coilfang_waterelemental() : CreatureScript("npc_coilfang_waterelemental") { } + public: + npc_coilfang_waterelemental() : CreatureScript("npc_coilfang_waterelemental") { } - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_coilfang_waterelementalAI(creature); - } - - struct npc_coilfang_waterelementalAI : public ScriptedAI - { - npc_coilfang_waterelementalAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 WaterBoltVolley_Timer; - - void Reset() override + struct npc_coilfang_waterelementalAI : public ScriptedAI { - WaterBoltVolley_Timer = 3000 + rand32() % 3000; - } - - void EnterCombat(Unit* /*who*/) override { } + npc_coilfang_waterelementalAI(Creature* creature) : ScriptedAI(creature) { } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void Reset() override + { + _events.Reset(); + } - if (WaterBoltVolley_Timer <= diff) + void EnterCombat(Unit* /*who*/) override { - DoCast(me, SPELL_WATER_BOLT_VOLLEY); - WaterBoltVolley_Timer = 7000 + rand32() % 5000; - } else WaterBoltVolley_Timer -= diff; + _events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(3000, 6000)); + } - DoMeleeAttackIfReady(); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_WATER_BOLT_VOLLEY: + DoCast(me, SPELL_WATER_BOLT_VOLLEY); + _events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(7000, 12000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_coilfang_waterelementalAI(creature); } - }; - }; void AddSC_boss_hydromancer_thespia() diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_warlord_kalithresh.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_warlord_kalithresh.cpp index ab6e0afaab4..8024d5138eb 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_warlord_kalithresh.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_warlord_kalithresh.cpp @@ -168,7 +168,7 @@ public: { Talk(SAY_REGEN); DoCast(me, SPELL_WARLORDS_RAGE); - CAST_AI(npc_naga_distiller::npc_naga_distillerAI, distiller->AI())->StartRageGen(me); + ENSURE_AI(npc_naga_distiller::npc_naga_distillerAI, distiller->AI())->StartRageGen(me); } Rage_Timer = 3000 + rand32() % 15000; } else Rage_Timer -= diff; diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp index e56b82d4507..b2f199008d0 100644 --- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_kelidan_the_breaker.cpp @@ -291,7 +291,7 @@ class npc_shadowmoon_channeler : public CreatureScript void EnterCombat(Unit* who) override { if (Creature* Kelidan = me->FindNearestCreature(ENTRY_KELIDAN, 100)) - CAST_AI(boss_kelidan_the_breaker::boss_kelidan_the_breakerAI, Kelidan->AI())->ChannelerEngaged(who); + ENSURE_AI(boss_kelidan_the_breaker::boss_kelidan_the_breakerAI, Kelidan->AI())->ChannelerEngaged(who); if (me->IsNonMeleeSpellCast(false)) me->InterruptNonMeleeSpells(true); DoStartMovement(who); @@ -300,7 +300,7 @@ class npc_shadowmoon_channeler : public CreatureScript void JustDied(Unit* killer) override { if (Creature* Kelidan = me->FindNearestCreature(ENTRY_KELIDAN, 100)) - CAST_AI(boss_kelidan_the_breaker::boss_kelidan_the_breakerAI, Kelidan->AI())->ChannelerDied(killer); + ENSURE_AI(boss_kelidan_the_breaker::boss_kelidan_the_breakerAI, Kelidan->AI())->ChannelerDied(killer); } void UpdateAI(uint32 diff) override @@ -312,7 +312,7 @@ class npc_shadowmoon_channeler : public CreatureScript if (!me->IsNonMeleeSpellCast(false)) if (Creature* Kelidan = me->FindNearestCreature(ENTRY_KELIDAN, 100)) { - uint64 channeler = CAST_AI(boss_kelidan_the_breaker::boss_kelidan_the_breakerAI, Kelidan->AI())->GetChanneled(me); + uint64 channeler = ENSURE_AI(boss_kelidan_the_breaker::boss_kelidan_the_breakerAI, Kelidan->AI())->GetChanneled(me); if (Unit* channeled = ObjectAccessor::GetUnit(*me, channeler)) DoCast(channeled, SPELL_CHANNELING); } diff --git a/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp b/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp index b15bd18c97c..839dd800721 100644 --- a/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp @@ -468,7 +468,7 @@ class npc_hellfire_sentry : public CreatureScript void JustDied(Unit* killer) override { if (Creature* herald = me->FindNearestCreature(NPC_VAZRUDEN_HERALD, 150)) - CAST_AI(boss_vazruden_the_herald::boss_vazruden_the_heraldAI, herald->AI())->SentryDownBy(killer); + ENSURE_AI(boss_vazruden_the_herald::boss_vazruden_the_heraldAI, herald->AI())->SentryDownBy(killer); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp index c6756feb0ce..8a5d6e41780 100644 --- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp @@ -405,7 +405,7 @@ class boss_magtheridon : public CreatureScript Creature* summon = me->SummonCreature(NPC_ABYSSAL, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); if (summon) { - CAST_AI(npc_abyssal::npc_abyssalAI, summon->AI())->SetTrigger(2); + ENSURE_AI(npc_abyssal::npc_abyssalAI, summon->AI())->SetTrigger(2); DoCast(summon, SPELL_BLAZE_TARGET, true); summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } @@ -437,7 +437,7 @@ class boss_magtheridon : public CreatureScript target->GetPosition(x, y, z); Creature* summon = me->SummonCreature(NPC_ABYSSAL, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); if (summon) - CAST_AI(npc_abyssal::npc_abyssalAI, summon->AI())->SetTrigger(1); + ENSURE_AI(npc_abyssal::npc_abyssalAI, summon->AI())->SetTrigger(1); } Debris_Timer = 10000; } @@ -599,7 +599,7 @@ public: player->InterruptNonMeleeSpells(false); player->CastSpell(player, SPELL_SHADOW_GRASP, true); player->CastSpell(player, SPELL_SHADOW_GRASP_VISUAL, false); - CAST_AI(boss_magtheridon::boss_magtheridonAI, Magtheridon->AI())->SetClicker(go->GetGUID(), player->GetGUID()); + ENSURE_AI(boss_magtheridon::boss_magtheridonAI, Magtheridon->AI())->SetClicker(go->GetGUID(), player->GetGUID()); return true; } }; diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp index be437a154b3..63c01540af2 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp @@ -202,7 +202,7 @@ class boss_high_astromancer_solarian : public CreatureScript { float z = RAND(1.0f, -1.0f); - return (z*sqrt(radius*radius - (x - CENTER_X)*(x - CENTER_X)) + CENTER_Y); + return (z*std::sqrt(radius*radius - (x - CENTER_X)*(x - CENTER_X)) + CENTER_Y); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp index 29f240773e5..64deebce8b8 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp @@ -697,7 +697,7 @@ class boss_kaelthas : public CreatureScript if (!Advisor) TC_LOG_ERROR("scripts", "SD2: Kael'Thas Advisor %u does not exist. Possibly despawned? Incorrectly Killed?", i); else - CAST_AI(advisorbase_ai, Advisor->AI())->Revive(target); + ENSURE_AI(advisorbase_ai, Advisor->AI())->Revive(target); } PhaseSubphase = 1; diff --git a/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp b/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp index a1335290d5a..bbb384ed0f8 100644 --- a/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp +++ b/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp @@ -179,14 +179,14 @@ class boss_warp_splinter : public CreatureScript { for (uint8 i = 0; i < 6; ++i) { - float angle = (M_PI / 3) * i; + float angle = (float(M_PI) / 3) * i; float X = Treant_Spawn_Pos_X + TREANT_SPAWN_DIST * std::cos(angle); float Y = Treant_Spawn_Pos_Y + TREANT_SPAWN_DIST * std::sin(angle); float O = - me->GetAngle(X, Y); if (Creature* pTreant = me->SummonCreature(CREATURE_TREANT, treant_pos[i][0], treant_pos[i][1], treant_pos[i][2], O, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000)) - CAST_AI(npc_warp_splinter_treant::npc_warp_splinter_treantAI, pTreant->AI())->WarpGuid = me->GetGUID(); + ENSURE_AI(npc_warp_splinter_treant::npc_warp_splinter_treantAI, pTreant->AI())->WarpGuid = me->GetGUID(); } Talk(SAY_SUMMON); } diff --git a/src/server/scripts/Outland/zone_netherstorm.cpp b/src/server/scripts/Outland/zone_netherstorm.cpp index 6f331425be0..f82c1f5fb58 100644 --- a/src/server/scripts/Outland/zone_netherstorm.cpp +++ b/src/server/scripts/Outland/zone_netherstorm.cpp @@ -19,13 +19,11 @@ /* ScriptData SDName: Netherstorm SD%Complete: 80 -SDComment: Quest support: 10337, 10438, 10652 (special flight paths), 10299, 10321, 10322, 10323, 10329, 10330, 10338, 10365(Shutting Down Manaforge), 10198, 10191 +SDComment: Quest support: 10337, 10438, 10652 (special flight paths), 10198, 10191 SDCategory: Netherstorm EndScriptData */ /* ContentData -npc_manaforge_control_console -go_manaforge_control_console npc_commander_dawnforge npc_bessy npc_maxx_a_million @@ -39,323 +37,6 @@ EndContentData */ #include "Player.h" /*###### -## npc_manaforge_control_console -######*/ - -//used by 20209, 20417, 20418, 20440, signed for 20209 -enum ManaforgeConsoleData -{ - EMOTE_START = 0, - EMOTE_60 = 1, - EMOTE_30 = 2, - EMOTE_10 = 3, - EMOTE_COMPLETE = 4, - EMOTE_ABORT = 5, - - ENTRY_BNAAR_C_CONSOLE = 20209, - ENTRY_CORUU_C_CONSOLE = 20417, - ENTRY_DURO_C_CONSOLE = 20418, - ENTRY_ARA_C_CONSOLE = 20440, - - ENTRY_SUNFURY_TECH = 20218, - ENTRY_SUNFURY_PROT = 20436, - - ENTRY_ARA_TECH = 20438, - ENTRY_ARA_ENGI = 20439, - ENTRY_ARA_GORKLONN = 20460, - - SPELL_DISABLE_VISUAL = 35031, - SPELL_INTERRUPT_1 = 35016, //ACID mobs should cast this - SPELL_INTERRUPT_2 = 35176, //ACID mobs should cast this (Manaforge Ara-version) -}; - -class npc_manaforge_control_console : public CreatureScript -{ -public: - npc_manaforge_control_console() : CreatureScript("npc_manaforge_control_console") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_manaforge_control_consoleAI(creature); - } - - struct npc_manaforge_control_consoleAI : public ScriptedAI - { - npc_manaforge_control_consoleAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 Event_Timer; - uint32 Wave_Timer; - uint32 Phase; - bool Wave; - uint64 someplayer; - uint64 goConsole; - Creature* add; - - void Reset() override - { - Event_Timer = 3000; - Wave_Timer = 0; - Phase = 1; - Wave = false; - someplayer = 0; - goConsole = 0; - add = NULL; - } - - void EnterCombat(Unit* /*who*/) override { } - - /*void SpellHit(Unit* caster, const SpellInfo* spell) override - { - //we have no way of telling the Creature was hit by spell -> got aura applied after 10-12 seconds - //then no way for the mobs to actually stop the shutdown as intended. - if (spell->Id == SPELL_INTERRUPT_1) - DoSay("Silence! I kill you!", LANG_UNIVERSAL, NULL); - }*/ - - void JustDied(Unit* /*killer*/) override - { - Talk(EMOTE_ABORT); - - if (someplayer) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, someplayer)) - { - switch (me->GetEntry()) - { - case ENTRY_BNAAR_C_CONSOLE: - player->FailQuest(10299); - player->FailQuest(10329); - break; - case ENTRY_CORUU_C_CONSOLE: - player->FailQuest(10321); - player->FailQuest(10330); - break; - case ENTRY_DURO_C_CONSOLE: - player->FailQuest(10322); - player->FailQuest(10338); - break; - case ENTRY_ARA_C_CONSOLE: - player->FailQuest(10323); - player->FailQuest(10365); - break; - } - } - } - - if (goConsole) - if (GameObject* go = GameObject::GetGameObject(*me, goConsole)) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } - - void DoWaveSpawnForCreature(Creature* creature) - { - switch (creature->GetEntry()) - { - case ENTRY_BNAAR_C_CONSOLE: - if (rand32() % 2) - { - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2933.68f, 4162.55f, 164.00f, 1.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2927.36f, 4212.97f, 164.00f); - } - else - { - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2927.36f, 4212.97f, 164.00f, 4.94f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2933.68f, 4162.55f, 164.00f); - } - Wave_Timer = 30000; - break; - case ENTRY_CORUU_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2445.21f, 2765.26f, 134.49f, 3.93f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2424.21f, 2740.15f, 133.81f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2429.86f, 2731.85f, 134.53f, 1.31f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2435.37f, 2766.04f, 133.81f); - Wave_Timer = 20000; - break; - case ENTRY_DURO_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2986.80f, 2205.36f, 165.37f, 3.74f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2985.15f, 2197.32f, 164.79f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2952.91f, 2191.20f, 165.32f, 0.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2060.01f, 2185.27f, 164.67f); - Wave_Timer = 15000; - break; - case ENTRY_ARA_C_CONSOLE: - if (rand32() % 2) - { - add = me->SummonCreature(ENTRY_ARA_TECH, 4035.11f, 4038.97f, 194.27f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); - add = me->SummonCreature(ENTRY_ARA_TECH, 4033.66f, 4036.79f, 194.28f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); - add = me->SummonCreature(ENTRY_ARA_TECH, 4037.13f, 4037.30f, 194.23f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); - } - else - { - add = me->SummonCreature(ENTRY_ARA_TECH, 3099.59f, 4049.30f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); - add = me->SummonCreature(ENTRY_ARA_TECH, 3999.72f, 4046.75f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); - add = me->SummonCreature(ENTRY_ARA_TECH, 3996.81f, 4048.26f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); - } - Wave_Timer = 15000; - break; - } - } - void DoFinalSpawnForCreature(Creature* creature) - { - switch (creature->GetEntry()) - { - case ENTRY_BNAAR_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2946.52f, 4201.42f, 163.47f, 3.54f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2927.49f, 4192.81f, 163.00f); - break; - case ENTRY_CORUU_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2453.88f, 2737.85f, 133.27f, 2.59f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2441.62f, 2735.32f, 134.49f, 1.97f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2450.73f, 2754.50f, 134.49f, 3.29f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); - break; - case ENTRY_DURO_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2956.18f, 2202.85f, 165.32f, 5.45f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2975.30f, 2211.50f, 165.32f, 4.55f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); - add = me->SummonCreature(ENTRY_SUNFURY_PROT, 2965.02f, 2217.45f, 164.16f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); - break; - case ENTRY_ARA_C_CONSOLE: - add = me->SummonCreature(ENTRY_ARA_ENGI, 3994.51f, 4020.46f, 192.18f, 0.91f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4008.35f, 4035.04f, 192.70f); - add = me->SummonCreature(ENTRY_ARA_GORKLONN, 4021.56f, 4059.35f, 193.59f, 4.44f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4016.62f, 4039.89f, 193.46f); - break; - } - } - - void UpdateAI(uint32 diff) override - { - if (Event_Timer <= diff) - { - switch (Phase) - { - case 1: - if (someplayer) - { - Unit* u = ObjectAccessor::GetUnit(*me, someplayer); - if (u && u->GetTypeId() == TYPEID_PLAYER) - Talk(EMOTE_START, u); - } - Event_Timer = 60000; - Wave = true; - ++Phase; - break; - case 2: - Talk(EMOTE_60); - Event_Timer = 30000; - ++Phase; - break; - case 3: - Talk(EMOTE_30); - Event_Timer = 20000; - DoFinalSpawnForCreature(me); - ++Phase; - break; - case 4: - Talk(EMOTE_10); - Event_Timer = 10000; - Wave = false; - ++Phase; - break; - case 5: - Talk(EMOTE_COMPLETE); - if (someplayer) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, someplayer)) - player->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); - DoCast(me, SPELL_DISABLE_VISUAL); - } - - if (goConsole) - if (GameObject* go = GameObject::GetGameObject(*me, goConsole)) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - - ++Phase; - break; - } - } - else - Event_Timer -= diff; - - if (Wave) - { - if (Wave_Timer <= diff) - { - DoWaveSpawnForCreature(me); - } - else - Wave_Timer -= diff; - } - } - }; -}; - -/*###### -## go_manaforge_control_console -######*/ - -/// @todo clean up this workaround when Trinity adds support to do it properly (with gossip selections instead of instant summon) -class go_manaforge_control_console : public GameObjectScript -{ -public: - go_manaforge_control_console() : GameObjectScript("go_manaforge_control_console") { } - - bool OnGossipHello(Player* player, GameObject* go) override - { - if (go->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) - { - player->PrepareQuestMenu(go->GetGUID()); - player->SendPreparedQuest(go->GetGUID()); - } - - Creature* manaforge = NULL; - - switch (go->GetAreaId()) - { - case 3726: //b'naar - if ((player->GetQuestStatus(10299) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10329) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29366)) - manaforge = player->SummonCreature(ENTRY_BNAAR_C_CONSOLE, 2918.95f, 4189.98f, 161.88f, 0.34f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - case 3730: //coruu - if ((player->GetQuestStatus(10321) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10330) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29396)) - manaforge = player->SummonCreature(ENTRY_CORUU_C_CONSOLE, 2426.77f, 2750.38f, 133.24f, 2.14f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - case 3734: //duro - if ((player->GetQuestStatus(10322) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10338) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29397)) - manaforge = player->SummonCreature(ENTRY_DURO_C_CONSOLE, 2976.48f, 2183.29f, 163.20f, 1.85f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - case 3722: //ara - if ((player->GetQuestStatus(10323) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10365) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29411)) - manaforge = player->SummonCreature(ENTRY_ARA_C_CONSOLE, 4013.71f, 4028.76f, 192.10f, 1.25f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - } - - if (manaforge) - { - CAST_AI(npc_manaforge_control_console::npc_manaforge_control_consoleAI, manaforge->AI())->someplayer = player->GetGUID(); - CAST_AI(npc_manaforge_control_console::npc_manaforge_control_consoleAI, manaforge->AI())->goConsole = go->GetGUID(); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } - return true; - } -}; - -/*###### ## npc_commander_dawnforge ######*/ @@ -638,7 +319,7 @@ public: if (!Dawnforge) return false; - if (CAST_AI(npc_commander_dawnforge::npc_commander_dawnforgeAI, Dawnforge->AI())->CanStartEvent(player)) + if (ENSURE_AI(npc_commander_dawnforge::npc_commander_dawnforgeAI, Dawnforge->AI())->CanStartEvent(player)) return true; } return false; @@ -860,7 +541,7 @@ public: { creature->setFaction(113); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); } return true; } @@ -1054,8 +735,6 @@ class go_captain_tyralius_prison : public GameObjectScript void AddSC_netherstorm() { - new go_manaforge_control_console(); - new npc_manaforge_control_console(); new npc_commander_dawnforge(); new at_commander_dawnforge(); new npc_professor_dabiri(); diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp index e1590873455..b9b87fd5d6a 100644 --- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp @@ -643,8 +643,8 @@ public: { if (_Quest->GetQuestId() == QUEST_LORD_ILLIDAN_STORMRAGE) { - CAST_AI(npc_overlord_morghor::npc_overlord_morghorAI, creature->AI())->PlayerGUID = player->GetGUID(); - CAST_AI(npc_overlord_morghor::npc_overlord_morghorAI, creature->AI())->StartEvent(); + ENSURE_AI(npc_overlord_morghor::npc_overlord_morghorAI, creature->AI())->PlayerGUID = player->GetGUID(); + ENSURE_AI(npc_overlord_morghor::npc_overlord_morghorAI, creature->AI())->StartEvent(); return true; } return false; @@ -1509,7 +1509,7 @@ public: me->RemoveCorpse(); if (Creature* LordIllidan = (ObjectAccessor::GetCreature(*me, LordIllidanGUID))) if (LordIllidan) - CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, LordIllidan->AI())->LiveCounter(); + ENSURE_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, LordIllidan->AI())->LiveCounter(); } void UpdateAI(uint32 diff) override @@ -1644,14 +1644,14 @@ void npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI::SummonNextWave() Spawn->GetMotionMaster()->MovePoint(0, x, y, z); } } - CAST_AI(npc_illidari_spawn::npc_illidari_spawnAI, Spawn->AI())->LordIllidanGUID = me->GetGUID(); + ENSURE_AI(npc_illidari_spawn::npc_illidari_spawnAI, Spawn->AI())->LordIllidanGUID = me->GetGUID(); } if (WavesInfo[WaveCount].CreatureId == 22076) // Torloth { - CAST_AI(npc_torloth_the_magnificent::npc_torloth_the_magnificentAI, Spawn->AI())->LordIllidanGUID = me->GetGUID(); + ENSURE_AI(npc_torloth_the_magnificent::npc_torloth_the_magnificentAI, Spawn->AI())->LordIllidanGUID = me->GetGUID(); if (PlayerGUID) - CAST_AI(npc_torloth_the_magnificent::npc_torloth_the_magnificentAI, Spawn->AI())->AggroTargetGUID = PlayerGUID; + ENSURE_AI(npc_torloth_the_magnificent::npc_torloth_the_magnificentAI, Spawn->AI())->AggroTargetGUID = PlayerGUID; } } } @@ -1675,11 +1675,11 @@ public: { Creature* Illidan = player->FindNearestCreature(22083, 50); - if (Illidan && !CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->EventStarted) + if (Illidan && !ENSURE_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->EventStarted) { - CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->PlayerGUID = player->GetGUID(); - CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->LiveCount = 0; - CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->EventStarted=true; + ENSURE_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->PlayerGUID = player->GetGUID(); + ENSURE_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->LiveCount = 0; + ENSURE_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->EventStarted = true; } } return true; diff --git a/src/server/scripts/Outland/zone_terokkar_forest.cpp b/src/server/scripts/Outland/zone_terokkar_forest.cpp index c0755b6b06b..da7ae03a8ee 100644 --- a/src/server/scripts/Outland/zone_terokkar_forest.cpp +++ b/src/server/scripts/Outland/zone_terokkar_forest.cpp @@ -529,7 +529,7 @@ public: { if (quest->GetQuestId() == QUEST_EFTW_H || quest->GetQuestId() == QUEST_EFTW_A) { - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); creature->setFaction(113); } return true; diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp index 7dbdc7af63f..8fd6cb54b0e 100644 --- a/src/server/scripts/Pet/pet_hunter.cpp +++ b/src/server/scripts/Pet/pet_hunter.cpp @@ -57,7 +57,7 @@ class npc_pet_hunter_snake_trap : public CreatureScript me->SetMaxHealth(uint32(107 * (me->getLevel() - 40) * 0.025f)); // Add delta to make them not all hit the same time uint32 delta = (rand32() % 7) * 100; - me->SetAttackTime(BASE_ATTACK, Info->baseattacktime + delta); + me->SetAttackTime(BASE_ATTACK, Info->BaseAttackTime + delta); //me->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER, float(Info->attackpower)); // Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 22a186b523b..fd4c972edbe 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1601,7 +1601,7 @@ class spell_gen_gift_of_naaru : public SpellScriptLoader break; } - int32 healTick = floor(heal / aurEff->GetTotalTicks()); + int32 healTick = std::floor(heal / aurEff->GetTotalTicks()); amount += int32(std::max(healTick, 0)); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index c4bd473f1d1..a8f8dc1f31c 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -991,7 +991,7 @@ class spell_item_unsated_craving : public SpellScriptLoader return false; Unit* target = procInfo.GetActionTarget(); - if (!target || target->GetTypeId() != TYPEID_UNIT || target->GetCreatureType() == CREATURE_TYPE_CRITTER || (target->GetEntry() != NPC_SINDRAGOSA && target->IsSummon())) + if (!target || target->GetTypeId() != TYPEID_UNIT || target->IsCritter() || (target->GetEntry() != NPC_SINDRAGOSA && target->IsSummon())) return false; return true; @@ -2456,7 +2456,7 @@ class spell_item_unusual_compass : public SpellScriptLoader void HandleDummy(SpellEffIndex /* effIndex */) { Unit* caster = GetCaster(); - caster->SetFacingTo(frand(0.0f, 2.0f * M_PI)); + caster->SetFacingTo(frand(0.0f, 2.0f * float(M_PI))); } void Register() override diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 53e86c586a5..e6ad3e83477 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -1078,6 +1078,55 @@ class spell_pal_sacred_shield : public SpellScriptLoader } }; +// 53600 - Shield of the Righteous +/// Updated 4.3.4 +class spell_pal_shield_of_the_righteous : public SpellScriptLoader +{ + public: + spell_pal_shield_of_the_righteous() : SpellScriptLoader("spell_pal_shield_of_the_righteous") { } + + class spell_pal_shield_of_the_righteous_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pal_shield_of_the_righteous_SpellScript); + + bool Load() + { + if (GetCaster()->GetTypeId() != TYPEID_PLAYER) + return false; + + if (GetCaster()->ToPlayer()->getClass() != CLASS_PALADIN) + return false; + + return true; + } + + void ChangeDamage(SpellEffIndex /*effIndex*/) + { + int32 damage = GetHitDamage(); + + // Because 1 Holy Power (HP) is consumed when casting spell, + // GetPower(POWER_HOLY_POWER) will return 0 when player has 1 HP, + // return 1 at 2 HP, and 2 at 3 HP + int32 hp = GetCaster()->GetPower(POWER_HOLY_POWER); + + // Holy Power Scaling: 3 times damage at 2 HP, 6 times at 3 HP + damage *= 0.5*hp*hp + 1.5*hp + 1; + + SetHitDamage(damage); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_pal_shield_of_the_righteous_SpellScript::ChangeDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_pal_shield_of_the_righteous_SpellScript(); + } +}; + // 85256 - Templar's Verdict /// Updated 4.3.4 class spell_pal_templar_s_verdict : public SpellScriptLoader @@ -1218,6 +1267,7 @@ void AddSC_paladin_spell_scripts() new spell_pal_lay_on_hands(); new spell_pal_righteous_defense(); new spell_pal_sacred_shield(); + new spell_pal_shield_of_the_righteous(); new spell_pal_templar_s_verdict(); new spell_pal_seal_of_righteousness(); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 9b9b774fdcc..3bd61ddf465 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -1046,7 +1046,7 @@ class spell_pri_shadow_word_death : public SpellScriptLoader if (AuraEffect* aurEff = GetCaster()->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_PAIN_AND_SUFFERING, EFFECT_1)) AddPct(damage, aurEff->GetAmount()); - GetCaster()->CastCustomSpell(GetCaster(), SPELL_PRIEST_SHADOW_WORD_DEATH, &damage, 0, 0, true); + GetCaster()->CastCustomSpell(GetCaster(), SPELL_PRIEST_SHADOW_WORD_DEATH, &damage, nullptr, nullptr, true); } void Register() override diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 854bc77671b..173e03fef7c 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -1773,7 +1773,7 @@ class spell_q12847_summon_soul_moveto_bunny : public SpellScriptLoader } }; - SpellScript *GetSpellScript() const + SpellScript *GetSpellScript() const override { return new spell_q12847_summon_soul_moveto_bunny_SpellScript(); } @@ -2008,7 +2008,7 @@ class spell_q12308_escape_from_silverbrook_summon_worgen : public SpellScriptLoa void ModDest(SpellDestination& dest) { float dist = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster()); - float angle = frand(0.75f, 1.25f) * M_PI; + float angle = frand(0.75f, 1.25f) * float(M_PI); Position pos = GetCaster()->GetNearPosition(dist, angle); dest.Relocate(pos); diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 7ae666ae192..e8546c4214e 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -647,7 +647,7 @@ class spell_rog_prey_on_the_weak : public SpellScriptLoader if (!target->HasAura(SPELL_ROGUE_PREY_ON_THE_WEAK)) { int32 bp = GetSpellInfo()->Effects[EFFECT_0].CalcValue(); - target->CastCustomSpell(target, SPELL_ROGUE_PREY_ON_THE_WEAK, &bp, 0, 0, true); + target->CastCustomSpell(target, SPELL_ROGUE_PREY_ON_THE_WEAK, &bp, nullptr, nullptr, true); } } else @@ -976,7 +976,7 @@ public: { if (AuraEffect* blade = GetCaster()->GetAuraEffectOfRankedSpell(SPELL_ROGUE_SERRATED_BLADES_R1, EFFECT_0)) { - int8 combo = GetCaster()->ToPlayer()->GetComboPoints(); + uint8 combo = GetCaster()->ToPlayer()->GetComboPoints(); if (roll_chance_i(blade->GetAmount() * combo)) if (Aura* dot = GetHitUnit()->GetAura(SPELL_ROGUE_RUPTURE, GetCaster()->GetGUID())) diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index c65970aed3d..ecbc6ca1bdc 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -621,7 +621,7 @@ class spell_warr_retaliation : public SpellScriptLoader bool CheckProc(ProcEventInfo& eventInfo) { // check attack comes not from behind and warrior is not stunned - return GetTarget()->isInFront(eventInfo.GetProcTarget(), M_PI) && !GetTarget()->HasUnitState(UNIT_STATE_STUNNED); + return GetTarget()->isInFront(eventInfo.GetActor(), float(M_PI)) && !GetTarget()->HasUnitState(UNIT_STATE_STUNNED); } void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 969bfa57d58..ba17dba602a 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -392,7 +392,7 @@ public: bool OnQuestAccept(Player* /*player*/, Creature* creature, Quest const* quest) override { if (quest->GetQuestId() == QUEST_CLUCK) - CAST_AI(npc_chicken_cluck::npc_chicken_cluckAI, creature->AI())->Reset(); + ENSURE_AI(npc_chicken_cluck::npc_chicken_cluckAI, creature->AI())->Reset(); return true; } @@ -400,7 +400,7 @@ public: bool OnQuestComplete(Player* /*player*/, Creature* creature, Quest const* quest) override { if (quest->GetQuestId() == QUEST_CLUCK) - CAST_AI(npc_chicken_cluck::npc_chicken_cluckAI, creature->AI())->Reset(); + ENSURE_AI(npc_chicken_cluck::npc_chicken_cluckAI, creature->AI())->Reset(); return true; } @@ -692,7 +692,7 @@ public: bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override { if ((quest->GetQuestId() == 6624) || (quest->GetQuestId() == 6622)) - CAST_AI(npc_doctor::npc_doctorAI, creature->AI())->BeginEvent(player); + ENSURE_AI(npc_doctor::npc_doctorAI, creature->AI())->BeginEvent(player); return true; } @@ -763,7 +763,7 @@ public: if (player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE) if (DoctorGUID) if (Creature* doctor = ObjectAccessor::GetCreature(*me, DoctorGUID)) - CAST_AI(npc_doctor::npc_doctorAI, doctor->AI())->PatientSaved(me, player, Coord); + ENSURE_AI(npc_doctor::npc_doctorAI, doctor->AI())->PatientSaved(me, player, Coord); //make not selectable me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); @@ -809,7 +809,7 @@ public: if (DoctorGUID) if (Creature* doctor = ObjectAccessor::GetCreature((*me), DoctorGUID)) - CAST_AI(npc_doctor::npc_doctorAI, doctor->AI())->PatientDied(Coord); + ENSURE_AI(npc_doctor::npc_doctorAI, doctor->AI())->PatientDied(Coord); } } }; @@ -859,8 +859,8 @@ void npc_doctor::npc_doctorAI::UpdateAI(uint32 diff) Patient->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); Patients.push_back(Patient->GetGUID()); - CAST_AI(npc_injured_patient::npc_injured_patientAI, Patient->AI())->DoctorGUID = me->GetGUID(); - CAST_AI(npc_injured_patient::npc_injured_patientAI, Patient->AI())->Coord = point; + ENSURE_AI(npc_injured_patient::npc_injured_patientAI, Patient->AI())->DoctorGUID = me->GetGUID(); + ENSURE_AI(npc_injured_patient::npc_injured_patientAI, Patient->AI())->Coord = point; Coordinates.erase(itr); } @@ -2231,7 +2231,7 @@ public: if (GameObject* launcher = FindNearestLauncher()) { launcher->SendCustomAnim(ANIM_GO_LAUNCH_FIREWORK); - me->SetOrientation(launcher->GetOrientation() + M_PI/2); + me->SetOrientation(launcher->GetOrientation() + float(M_PI) / 2); } else return; diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index e74e707a942..4e23b4a4770 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -19,46 +19,6 @@ #ifndef TRINITYCORE_COMMON_H #define TRINITYCORE_COMMON_H -// config.h needs to be included 1st -/// @todo this thingy looks like hack, but its not, need to -// make separate header however, because It makes mess here. -#ifdef HAVE_CONFIG_H -// Remove Some things that we will define -// This is in case including another config.h -// before trinity config.h -#ifdef PACKAGE -#undef PACKAGE -#endif //PACKAGE -#ifdef PACKAGE_BUGREPORT -#undef PACKAGE_BUGREPORT -#endif //PACKAGE_BUGREPORT -#ifdef PACKAGE_NAME -#undef PACKAGE_NAME -#endif //PACKAGE_NAME -#ifdef PACKAGE_STRING -#undef PACKAGE_STRING -#endif //PACKAGE_STRING -#ifdef PACKAGE_TARNAME -#undef PACKAGE_TARNAME -#endif //PACKAGE_TARNAME -#ifdef PACKAGE_VERSION -#undef PACKAGE_VERSION -#endif //PACKAGE_VERSION -#ifdef VERSION -#undef VERSION -#endif //VERSION - -# include "Config.h" - -#undef PACKAGE -#undef PACKAGE_BUGREPORT -#undef PACKAGE_NAME -#undef PACKAGE_STRING -#undef PACKAGE_TARNAME -#undef PACKAGE_VERSION -#undef VERSION -#endif //HAVE_CONFIG_H - #include "Define.h" #include <unordered_map> @@ -66,7 +26,7 @@ #include <stdlib.h> #include <string.h> #include <time.h> -#include <math.h> +#include <cmath> #include <errno.h> #include <signal.h> #include <assert.h> @@ -85,6 +45,13 @@ #if PLATFORM == PLATFORM_WINDOWS # include <ws2tcpip.h> + +# if defined(__INTEL_COMPILER) +# if !defined(BOOST_ASIO_HAS_MOVE) +# define BOOST_ASIO_HAS_MOVE +# endif // !defined(BOOST_ASIO_HAS_MOVE) +# endif // if defined(__INTEL_COMPILER) + #else # include <sys/types.h> # include <sys/ioctl.h> @@ -186,7 +153,7 @@ struct LocalizedString #endif #ifndef M_PI -#define M_PI 3.14159265358979323846f +#define M_PI 3.14159265358979323846 #endif #define MAX_QUERY_LEN 32*1024 diff --git a/src/server/shared/Database/DatabaseWorker.cpp b/src/server/shared/Database/DatabaseWorker.cpp index ca48ebdd811..e130429c8d0 100644 --- a/src/server/shared/Database/DatabaseWorker.cpp +++ b/src/server/shared/Database/DatabaseWorker.cpp @@ -50,7 +50,7 @@ void DatabaseWorker::WorkerThread() _queue->WaitAndPop(operation); - if (_cancelationToken) + if (_cancelationToken || !operation) return; operation->SetConnection(_connection); diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index 18797b6b12a..5548e44c925 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -35,7 +35,7 @@ class PingOperation : public SQLOperation { //! Operation for idle delaythreads - bool Execute() + bool Execute() override { m_conn->Ping(); return true; @@ -45,6 +45,14 @@ class PingOperation : public SQLOperation template <class T> class DatabaseWorkerPool { + private: + enum InternalIndex + { + IDX_ASYNC, + IDX_SYNCH, + IDX_SIZE + }; + public: /* Activity state */ DatabaseWorkerPool() : _connectionInfo(NULL) @@ -74,34 +82,17 @@ class DatabaseWorkerPool TC_LOG_INFO("sql.driver", "Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.", GetDatabaseName(), async_threads, synch_threads); - //! Open asynchronous connections (delayed operations) - _connections[IDX_ASYNC].resize(async_threads); - for (uint8 i = 0; i < async_threads; ++i) - { - T* t = new T(_queue, *_connectionInfo); - res &= t->Open(); - if (res) // only check mysql version if connection is valid - WPFatal(mysql_get_server_version(t->GetHandle()) >= MIN_MYSQL_SERVER_VERSION, "TrinityCore does not support MySQL versions below 5.1"); - _connections[IDX_ASYNC][i] = t; - ++_connectionCount[IDX_ASYNC]; - } + res = OpenConnections(IDX_ASYNC, async_threads); - //! Open synchronous connections (direct, blocking operations) - _connections[IDX_SYNCH].resize(synch_threads); - for (uint8 i = 0; i < synch_threads; ++i) - { - T* t = new T(*_connectionInfo); - res &= t->Open(); - _connections[IDX_SYNCH][i] = t; - ++_connectionCount[IDX_SYNCH]; - } + if (!res) + return res; + + res = OpenConnections(IDX_SYNCH, synch_threads); if (res) TC_LOG_INFO("sql.driver", "DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(), (_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC])); - else - TC_LOG_ERROR("sql.driver", "DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " - "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", GetDatabaseName()); + return res; } @@ -112,8 +103,6 @@ class DatabaseWorkerPool for (uint8 i = 0; i < _connectionCount[IDX_ASYNC]; ++i) { T* t = _connections[IDX_ASYNC][i]; - DatabaseWorker* worker = t->m_worker; - delete worker; t->Close(); //! Closes the actualy MySQL connection. } @@ -442,7 +431,7 @@ class DatabaseWorkerPool if (str.empty()) return; - char* buf = new char[str.size()*2+1]; + char* buf = new char[str.size() * 2 + 1]; EscapeString(buf, str.c_str(), str.size()); str = buf; delete[] buf; @@ -470,6 +459,54 @@ class DatabaseWorkerPool } private: + bool OpenConnections(InternalIndex type, uint8 numConnections) + { + _connections[type].resize(numConnections); + for (uint8 i = 0; i < numConnections; ++i) + { + T* t; + + if (type == IDX_ASYNC) + t = new T(_queue, *_connectionInfo); + else if (type == IDX_SYNCH) + t = new T(*_connectionInfo); + else + ASSERT(false); + + _connections[type][i] = t; + ++_connectionCount[type]; + + bool res = t->Open(); + + if (res) + { + if (mysql_get_server_version(t->GetHandle()) < MIN_MYSQL_SERVER_VERSION) + { + TC_LOG_ERROR("sql.driver", "TrinityCore does not support MySQL versions below 5.1"); + res = false; + } + } + + // Failed to open a connection or invalid version, abort and cleanup + if (!res) + { + TC_LOG_ERROR("sql.driver", "DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " + "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", GetDatabaseName()); + + while (_connectionCount[type] != 0) + { + T* t = _connections[type][i--]; + delete t; + --_connectionCount[type]; + } + + return false; + } + } + + return true; + } + unsigned long EscapeString(char *to, const char *from, unsigned long length) { if (!to || !from || !length) @@ -507,14 +544,6 @@ class DatabaseWorkerPool return _connectionInfo->database.c_str(); } - private: - enum _internalIndex - { - IDX_ASYNC, - IDX_SYNCH, - IDX_SIZE - }; - ProducerConsumerQueue<SQLOperation*>* _queue; //! Queue shared by async worker threads. std::vector< std::vector<T*> > _connections; uint32 _connectionCount[2]; //! Counter of MySQL connections; diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 73eac6e30d6..5accf57f132 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -29,7 +29,7 @@ class CharacterDatabaseConnection : public MySQLConnection CharacterDatabaseConnection(ProducerConsumerQueue<SQLOperation*>* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { } //- Loads database type specific prepared statements - void DoPrepareStatements(); + void DoPrepareStatements() override; }; typedef DatabaseWorkerPool<CharacterDatabaseConnection> CharacterDatabaseWorkerPool; diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index b9f281d3f2a..6189ed4495f 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -43,8 +43,7 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_FAILEDLOGINS, "SELECT id, failed_logins FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_BNET, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE battlenet_account = ? AND battlenet_index = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os, battlenet_account FROM account WHERE username = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_NUM_CHARS_ON_REALM, "SELECT numchars FROM realmcharacters WHERE realmid = ? AND acctid= ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id, username FROM account WHERE last_ip = ?", CONNECTION_SYNCH); @@ -118,9 +117,10 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN, "SELECT bandate, unbandate FROM battlenet_account_bans WHERE id = ? AND active = 1", CONNECTION_SYNCH); PrepareStatement(LOGIN_UPD_BNET_VS_FIELDS, "UPDATE battlenet_accounts SET v = ?, s = ? WHERE email = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_BNET_SESSION_KEY, "UPDATE battlenet_accounts SET sessionKey = ?, online = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_BNET_RECONNECT_INFO, "SELECT ba.id, ba.sessionKey, a.id FROM battlenet_accounts ba LEFT JOIN account a ON ba.id = a.battlenet_account WHERE ba.email = ? AND a.battlenet_index = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNTS, "SELECT a.battlenet_index, a.id, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_account = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT, "SELECT a.id, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_index = ? AND battlenet_account = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_BNET_RECONNECT_INFO, "SELECT ba.id, ba.sessionKey, a.id FROM battlenet_accounts ba LEFT JOIN account a ON ba.id = a.battlenet_account WHERE ba.email = ? AND a.username = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNTS, "SELECT a.id, a.username, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_account = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT, "SELECT a.id, a.username, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE username = ? AND battlenet_account = ?", CONNECTION_SYNCH); + PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED, "SELECT a.id, a.username, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_index = ? AND battlenet_account = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS, "SELECT rc.numchars, r.id, r.Region, r.Battlegroup, r.gamebuild FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_INS_BNET_ACCOUNT, "INSERT INTO battlenet_accounts (`email`,`sha_pass_hash`) VALUES (?, ?)", CONNECTION_ASYNC); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 830fd625931..8c1cc642835 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -29,7 +29,7 @@ class LoginDatabaseConnection : public MySQLConnection LoginDatabaseConnection(ProducerConsumerQueue<SQLOperation*>* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { } //- Loads database type specific prepared statements - void DoPrepareStatements(); + void DoPrepareStatements() override; }; typedef DatabaseWorkerPool<LoginDatabaseConnection> LoginDatabaseWorkerPool; @@ -62,7 +62,6 @@ enum LoginDatabaseStatements LOGIN_SEL_ACCOUNT_ID_BY_NAME, LOGIN_SEL_ACCOUNT_LIST_BY_NAME, LOGIN_SEL_ACCOUNT_INFO_BY_NAME, - LOGIN_SEL_ACCOUNT_INFO_BY_BNET, LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, LOGIN_SEL_NUM_CHARS_ON_REALM, LOGIN_SEL_ACCOUNT_BY_IP, @@ -137,6 +136,7 @@ enum LoginDatabaseStatements LOGIN_SEL_BNET_RECONNECT_INFO, LOGIN_SEL_BNET_GAME_ACCOUNTS, LOGIN_SEL_BNET_GAME_ACCOUNT, + LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED, LOGIN_UPD_BNET_LAST_LOGIN_INFO, LOGIN_SEL_BNET_CHARACTER_COUNTS, LOGIN_INS_BNET_ACCOUNT, diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp index 53f3b5519cd..e5aeaf46c15 100644 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp @@ -76,7 +76,7 @@ void WorldDatabaseConnection::DoPrepareStatements() PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); + PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH); @@ -89,6 +89,4 @@ void WorldDatabaseConnection::DoPrepareStatements() PrepareStatement(WORLD_INS_DISABLES, "INSERT INTO disables (entry, sourceType, flags, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(WORLD_SEL_DISABLES, "SELECT entry FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_DEL_DISABLES, "DELETE FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_ASYNC); - // 0: uint8 - PrepareStatement(WORLD_SEL_REQ_XP, "SELECT xp_for_next_level FROM player_xp_for_level WHERE lvl = ?", CONNECTION_SYNCH); } diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h index c8c38d8a629..8a5bd206021 100644 --- a/src/server/shared/Database/Implementation/WorldDatabase.h +++ b/src/server/shared/Database/Implementation/WorldDatabase.h @@ -29,7 +29,7 @@ class WorldDatabaseConnection : public MySQLConnection WorldDatabaseConnection(ProducerConsumerQueue<SQLOperation*>* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { } //- Loads database type specific prepared statements - void DoPrepareStatements(); + void DoPrepareStatements() override; }; typedef DatabaseWorkerPool<WorldDatabaseConnection> WorldDatabaseWorkerPool; @@ -110,7 +110,6 @@ enum WorldDatabaseStatements WORLD_SEL_DISABLES, WORLD_INS_DISABLES, WORLD_DEL_DISABLES, - WORLD_SEL_REQ_XP, MAX_WORLDDATABASE_STATEMENTS }; diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/shared/Database/MySQLConnection.cpp index 8b24f508331..4e46ff0e3a1 100644 --- a/src/server/shared/Database/MySQLConnection.cpp +++ b/src/server/shared/Database/MySQLConnection.cpp @@ -57,12 +57,14 @@ m_connectionFlags(CONNECTION_ASYNC) MySQLConnection::~MySQLConnection() { - ASSERT (m_Mysql); /// MySQL context must be present at this point - for (size_t i = 0; i < m_stmts.size(); ++i) delete m_stmts[i]; - mysql_close(m_Mysql); + if (m_Mysql) + mysql_close(m_Mysql); + + if (m_worker) + delete m_worker; } void MySQLConnection::Close() @@ -112,7 +114,7 @@ bool MySQLConnection::Open() else // generic case { port = atoi(m_connectionInfo.port_or_socket.c_str()); - unix_socket = 0; + unix_socket = nullptr; } #endif diff --git a/src/server/shared/Database/PreparedStatement.h b/src/server/shared/Database/PreparedStatement.h index 16f7a9141d3..5af52cde016 100644 --- a/src/server/shared/Database/PreparedStatement.h +++ b/src/server/shared/Database/PreparedStatement.h @@ -163,7 +163,7 @@ class PreparedStatementTask : public SQLOperation PreparedStatementTask(PreparedStatement* stmt, bool async = false); ~PreparedStatementTask(); - bool Execute(); + bool Execute() override; PreparedQueryResultFuture GetFuture() { return m_result->get_future(); } protected: diff --git a/src/server/shared/Database/QueryHolder.cpp b/src/server/shared/Database/QueryHolder.cpp index bd938561b50..f0dc3c96e4e 100644 --- a/src/server/shared/Database/QueryHolder.cpp +++ b/src/server/shared/Database/QueryHolder.cpp @@ -166,8 +166,16 @@ void SQLQueryHolder::SetSize(size_t size) m_queries.resize(size); } +SQLQueryHolderTask::~SQLQueryHolderTask() +{ + if (!m_executed) + delete m_holder; +} + bool SQLQueryHolderTask::Execute() { + m_executed = true; + if (!m_holder) return false; diff --git a/src/server/shared/Database/QueryHolder.h b/src/server/shared/Database/QueryHolder.h index 37e23ecd653..39e51b591c5 100644 --- a/src/server/shared/Database/QueryHolder.h +++ b/src/server/shared/Database/QueryHolder.h @@ -47,14 +47,16 @@ class SQLQueryHolderTask : public SQLOperation private: SQLQueryHolder* m_holder; QueryResultHolderPromise m_result; + bool m_executed; public: SQLQueryHolderTask(SQLQueryHolder* holder) - : m_holder(holder) { }; + : m_holder(holder), m_executed(false) { } - bool Execute(); - QueryResultHolderFuture GetFuture() { return m_result.get_future(); } + ~SQLQueryHolderTask(); + bool Execute() override; + QueryResultHolderFuture GetFuture() { return m_result.get_future(); } }; -#endif
\ No newline at end of file +#endif diff --git a/src/server/shared/Database/QueryResult.cpp b/src/server/shared/Database/QueryResult.cpp index 06b09d43168..a7b8ec2b107 100644 --- a/src/server/shared/Database/QueryResult.cpp +++ b/src/server/shared/Database/QueryResult.cpp @@ -124,7 +124,7 @@ m_length(NULL) *m_rBind[fIndex].length); break; default: - m_rows[uint32(m_rowPosition)][fIndex].SetByteValue(0, + m_rows[uint32(m_rowPosition)][fIndex].SetByteValue(nullptr, m_rBind[fIndex].buffer_length, m_rBind[fIndex].buffer_type, *m_rBind[fIndex].length); diff --git a/src/server/shared/Database/Transaction.h b/src/server/shared/Database/Transaction.h index c7cbbbbe712..3822c2c82c1 100644 --- a/src/server/shared/Database/Transaction.h +++ b/src/server/shared/Database/Transaction.h @@ -63,7 +63,7 @@ class TransactionTask : public SQLOperation ~TransactionTask(){ }; protected: - bool Execute(); + bool Execute() override; SQLTransaction m_trans; }; diff --git a/src/server/shared/Define.h b/src/server/shared/Define.h index 2a04b8cdfad..d1501b0c149 100644 --- a/src/server/shared/Define.h +++ b/src/server/shared/Define.h @@ -28,6 +28,9 @@ # if !defined(__STDC_CONSTANT_MACROS) # define __STDC_CONSTANT_MACROS # endif +# if !defined(_GLIBCXX_USE_NANOSLEEP) +# define _GLIBCXX_USE_NANOSLEEP +# endif #endif #include <cstddef> @@ -47,6 +50,7 @@ #if PLATFORM == PLATFORM_WINDOWS # define TRINITY_PATH_MAX MAX_PATH +# define _USE_MATH_DEFINES # ifndef DECLSPEC_NORETURN # define DECLSPEC_NORETURN __declspec(noreturn) # endif //DECLSPEC_NORETURN diff --git a/src/server/shared/Dynamic/LinkedList.h b/src/server/shared/Dynamic/LinkedList.h index 402aaf3d40c..87bbeaac380 100644 --- a/src/server/shared/Dynamic/LinkedList.h +++ b/src/server/shared/Dynamic/LinkedList.h @@ -150,7 +150,7 @@ class LinkedListHead typedef _Ty& reference; typedef _Ty const & const_reference; - Iterator() : _Ptr(0) + Iterator() : _Ptr(nullptr) { // construct with null node pointer } diff --git a/src/server/shared/Logging/AppenderConsole.h b/src/server/shared/Logging/AppenderConsole.h index b8f15b4fa0f..5b66f86650d 100644 --- a/src/server/shared/Logging/AppenderConsole.h +++ b/src/server/shared/Logging/AppenderConsole.h @@ -51,7 +51,7 @@ class AppenderConsole: public Appender private: void SetColor(bool stdout_stream, ColorTypes color); void ResetColor(bool stdout_stream); - void _write(LogMessage const& message); + void _write(LogMessage const& message) override; bool _colored; ColorTypes _colors[MaxLogLevels]; }; diff --git a/src/server/shared/Logging/AppenderDB.h b/src/server/shared/Logging/AppenderDB.h index 660992261fd..b86252d0d67 100644 --- a/src/server/shared/Logging/AppenderDB.h +++ b/src/server/shared/Logging/AppenderDB.h @@ -31,7 +31,7 @@ class AppenderDB: public Appender private: uint32 realmId; bool enabled; - void _write(LogMessage const& message); + void _write(LogMessage const& message) override; }; #endif diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h index a600c92d152..37ba2769e19 100644 --- a/src/server/shared/Logging/AppenderFile.h +++ b/src/server/shared/Logging/AppenderFile.h @@ -30,7 +30,7 @@ class AppenderFile: public Appender private: void CloseFile(); - void _write(LogMessage const& message); + void _write(LogMessage const& message) override; FILE* logfile; std::string filename; std::string logDir; diff --git a/src/server/shared/Networking/AsyncAcceptor.h b/src/server/shared/Networking/AsyncAcceptor.h index d056731bb79..64665c2b198 100644 --- a/src/server/shared/Networking/AsyncAcceptor.h +++ b/src/server/shared/Networking/AsyncAcceptor.h @@ -18,6 +18,7 @@ #ifndef __ASYNCACCEPT_H_ #define __ASYNCACCEPT_H_ +#include "Log.h" #include <boost/asio.hpp> using boost::asio::ip::tcp; @@ -49,8 +50,15 @@ private: { if (!error) { - // this-> is required here to fix an segmentation fault in gcc 4.7.2 - reason is lambdas in a templated class - std::make_shared<T>(std::move(this->_socket))->Start(); + try + { + // this-> is required here to fix an segmentation fault in gcc 4.7.2 - reason is lambdas in a templated class + std::make_shared<T>(std::move(this->_socket))->Start(); + } + catch (boost::system::system_error const& err) + { + TC_LOG_INFO("network", "Failed to retrieve client's remote address %s", err.what()); + } } // lets slap some more this-> on this so we can fix this bug with gcc 4.7.2 throwing internals in yo face diff --git a/src/server/shared/Networking/MessageBuffer.h b/src/server/shared/Networking/MessageBuffer.h new file mode 100644 index 00000000000..c7f8ba31a71 --- /dev/null +++ b/src/server/shared/Networking/MessageBuffer.h @@ -0,0 +1,95 @@ +/* +* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __MESSAGEBUFFER_H_ +#define __MESSAGEBUFFER_H_ + +#include "Define.h" +#include <vector> + +class MessageBuffer +{ + typedef std::vector<uint8>::size_type size_type; + +public: + MessageBuffer() : _wpos(0), _storage() { } + + MessageBuffer(MessageBuffer const& right) : _wpos(right._wpos), _storage(right._storage) { } + + MessageBuffer(MessageBuffer&& right) : _wpos(right._wpos), _storage(right.Move()) { } + + void Reset() + { + _storage.clear(); + _wpos = 0; + } + + bool IsMessageReady() const { return _wpos == _storage.size(); } + + size_type GetSize() const { return _storage.size(); } + + size_type GetReadyDataSize() const { return _wpos; } + + size_type GetMissingSize() const { return _storage.size() - _wpos; } + + uint8* Data() { return _storage.data(); } + + void Grow(size_type bytes) + { + _storage.resize(_storage.size() + bytes); + } + + uint8* GetWritePointer() { return &_storage[_wpos]; } + + void WriteCompleted(size_type bytes) { _wpos += bytes; } + + void ResetWritePointer() { _wpos = 0; } + + std::vector<uint8>&& Move() + { + _wpos = 0; + return std::move(_storage); + } + + MessageBuffer& operator=(MessageBuffer& right) + { + if (this != &right) + { + _wpos = right._wpos; + _storage = right._storage; + } + + return *this; + } + + MessageBuffer& operator=(MessageBuffer&& right) + { + if (this != &right) + { + _wpos = right._wpos; + _storage = right.Move(); + } + + return *this; + } + +private: + size_type _wpos; + std::vector<uint8> _storage; +}; + +#endif /* __MESSAGEBUFFER_H_ */ diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h index 38d88e3592c..3bd30bd731b 100644 --- a/src/server/shared/Networking/Socket.h +++ b/src/server/shared/Networking/Socket.h @@ -18,8 +18,9 @@ #ifndef __SOCKET_H__ #define __SOCKET_H__ -#include "Define.h" +#include "MessageBuffer.h" #include "Log.h" +#include <atomic> #include <vector> #include <mutex> #include <queue> @@ -28,68 +29,92 @@ #include <type_traits> #include <boost/asio/ip/tcp.hpp> #include <boost/asio/write.hpp> +#include <boost/asio/read.hpp> using boost::asio::ip::tcp; +#define READ_BLOCK_SIZE 4096 + template<class T, class PacketType> class Socket : public std::enable_shared_from_this<T> { typedef typename std::conditional<std::is_pointer<PacketType>::value, PacketType, PacketType const&>::type WritePacketType; public: - Socket(tcp::socket&& socket, std::size_t headerSize) : _socket(std::move(socket)), _headerSize(headerSize) { } - - virtual void Start() = 0; + Socket(tcp::socket&& socket, std::size_t headerSize) : _socket(std::move(socket)), _remoteAddress(_socket.remote_endpoint().address()), + _remotePort(_socket.remote_endpoint().port()), _readHeaderBuffer(), _readDataBuffer(), _closed(false), _closing(false) + { + _readHeaderBuffer.Grow(headerSize); + } - boost::asio::ip::address GetRemoteIpAddress() const + virtual ~Socket() { boost::system::error_code error; - auto ep = _socket.remote_endpoint(error); + _socket.close(error); - if (error) + while (!_writeQueue.empty()) { - TC_LOG_DEBUG("network", "Socket::GetRemoteIpAddress: errored with: %i (%s)", error.value(), error.message().c_str()); - return boost::asio::ip::address(); + DeletePacket(_writeQueue.front()); + _writeQueue.pop(); } - else - return ep.address(); } - uint16 GetRemotePort() const + virtual void Start() = 0; + + boost::asio::ip::address GetRemoteIpAddress() const { - boost::system::error_code error; - auto ep = _socket.remote_endpoint(error); + return _remoteAddress; + } - if (error) - { - TC_LOG_DEBUG("network", "Socket::GetRemotePort: errored with: %i (%s)", error.value(), error.message().c_str()); - return 0; - } - else - return ep.port(); + uint16 GetRemotePort() const + { + return _remotePort; } void AsyncReadHeader() { - _socket.async_read_some(boost::asio::buffer(_readBuffer, _headerSize), std::bind(&Socket<T, PacketType>::ReadHeaderHandlerInternal, this->shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + if (!IsOpen()) + return; + + _readHeaderBuffer.ResetWritePointer(); + _readDataBuffer.Reset(); + + AsyncReadMissingHeaderData(); } - void AsyncReadData(std::size_t size, std::size_t bufferOffset) + void AsyncReadData(std::size_t size) { - _socket.async_read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size), std::bind(&Socket<T, PacketType>::ReadDataHandlerInternal, this->shared_from_this(), - std::placeholders::_1, std::placeholders::_2)); + if (!IsOpen()) + return; + + if (!size) + { + // if this is a packet with 0 length body just invoke handler directly + ReadDataHandler(); + return; + } + + _readDataBuffer.Grow(size); + AsyncReadMissingData(); } - void ReadData(std::size_t size, std::size_t bufferOffset) + void ReadData(std::size_t size) { + if (!IsOpen()) + return; + boost::system::error_code error; - _socket.read_some(boost::asio::buffer(&_readBuffer[bufferOffset], size), error); + _readDataBuffer.Grow(size); - if (error) + std::size_t bytesRead = boost::asio::read(_socket, boost::asio::buffer(_readDataBuffer.GetWritePointer(), size), error); + + _readDataBuffer.WriteCompleted(bytesRead); + + if (error || !_readDataBuffer.IsMessageReady()) { - TC_LOG_DEBUG("network", "Socket::ReadData: %s errored with: %i (%s)", GetRemoteIpAddress().to_string().c_str(), error.value(), error.message().c_str()); + TC_LOG_DEBUG("network", "Socket::ReadData: %s errored with: %i (%s)", GetRemoteIpAddress().to_string().c_str(), error.value(), + error.message().c_str()); CloseSocket(); } @@ -97,32 +122,96 @@ public: void AsyncWrite(WritePacketType data) { - boost::asio::async_write(_socket, boost::asio::buffer(data), std::bind(&Socket<T, PacketType>::WriteHandler, this->shared_from_this(), std::placeholders::_1, - std::placeholders::_2)); + boost::asio::async_write(_socket, boost::asio::buffer(data), std::bind(&Socket<T, PacketType>::WriteHandler, this->shared_from_this(), + std::placeholders::_1, std::placeholders::_2)); } - bool IsOpen() const { return _socket.is_open(); } - void CloseSocket() + bool IsOpen() const { return !_closed && !_closing; } + + virtual void CloseSocket() { - boost::system::error_code error; - _socket.close(error); - if (error) - TC_LOG_DEBUG("network", "Socket::CloseSocket: %s errored when closing socket: %i (%s)", GetRemoteIpAddress().to_string().c_str(), - error.value(), error.message().c_str()); + if (_closed.exchange(true)) + return; + + boost::system::error_code shutdownError; + _socket.shutdown(boost::asio::socket_base::shutdown_send, shutdownError); + if (shutdownError) + TC_LOG_DEBUG("network", "Socket::CloseSocket: %s errored when shutting down socket: %i (%s)", GetRemoteIpAddress().to_string().c_str(), + shutdownError.value(), shutdownError.message().c_str()); } - uint8* GetReadBuffer() { return _readBuffer; } + /// Marks the socket for closing after write buffer becomes empty + void DelayedCloseSocket() { _closing = true; } + + virtual bool IsHeaderReady() const { return _readHeaderBuffer.IsMessageReady(); } + virtual bool IsDataReady() const { return _readDataBuffer.IsMessageReady(); } + + uint8* GetHeaderBuffer() { return _readHeaderBuffer.Data(); } + uint8* GetDataBuffer() { return _readDataBuffer.Data(); } + + size_t GetHeaderSize() const { return _readHeaderBuffer.GetReadyDataSize(); } + size_t GetDataSize() const { return _readDataBuffer.GetReadyDataSize(); } + + MessageBuffer&& MoveHeader() { return std::move(_readHeaderBuffer); } + MessageBuffer&& MoveData() { return std::move(_readDataBuffer); } protected: - virtual void ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) = 0; - virtual void ReadDataHandler(boost::system::error_code error, size_t transferedBytes) = 0; + virtual void ReadHeaderHandler() = 0; + virtual void ReadDataHandler() = 0; std::mutex _writeLock; std::queue<PacketType> _writeQueue; private: - void ReadHeaderHandlerInternal(boost::system::error_code error, size_t transferedBytes) { ReadHeaderHandler(error, transferedBytes); } - void ReadDataHandlerInternal(boost::system::error_code error, size_t transferedBytes) { ReadDataHandler(error, transferedBytes); } + void AsyncReadMissingHeaderData() + { + _socket.async_read_some(boost::asio::buffer(_readHeaderBuffer.GetWritePointer(), std::min<std::size_t>(READ_BLOCK_SIZE, _readHeaderBuffer.GetMissingSize())), + std::bind(&Socket<T, PacketType>::ReadHeaderHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2)); + } + + void AsyncReadMissingData() + { + _socket.async_read_some(boost::asio::buffer(_readDataBuffer.GetWritePointer(), std::min<std::size_t>(READ_BLOCK_SIZE, _readDataBuffer.GetMissingSize())), + std::bind(&Socket<T, PacketType>::ReadDataHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2)); + } + + void ReadHeaderHandlerInternal(boost::system::error_code error, size_t transferredBytes) + { + if (error) + { + CloseSocket(); + return; + } + + _readHeaderBuffer.WriteCompleted(transferredBytes); + if (!IsHeaderReady()) + { + // incomplete, read more + AsyncReadMissingHeaderData(); + return; + } + + ReadHeaderHandler(); + } + + void ReadDataHandlerInternal(boost::system::error_code error, size_t transferredBytes) + { + if (error) + { + CloseSocket(); + return; + } + + _readDataBuffer.WriteCompleted(transferredBytes); + if (!IsDataReady()) + { + // incomplete, read more + AsyncReadMissingData(); + return; + } + + ReadDataHandler(); + } void WriteHandler(boost::system::error_code error, size_t /*transferedBytes*/) { @@ -135,6 +224,8 @@ private: if (!_writeQueue.empty()) AsyncWrite(_writeQueue.front()); + else if (_closing) + CloseSocket(); } else CloseSocket(); @@ -148,9 +239,14 @@ private: tcp::socket _socket; - uint8 _readBuffer[4096]; + boost::asio::ip::address _remoteAddress; + uint16 _remotePort; + + MessageBuffer _readHeaderBuffer; + MessageBuffer _readDataBuffer; - std::size_t _headerSize; + std::atomic<bool> _closed; + std::atomic<bool> _closing; }; #endif // __SOCKET_H__ diff --git a/src/server/shared/Packets/ByteBuffer.cpp b/src/server/shared/Packets/ByteBuffer.cpp index 0a911492f85..02713a30cc6 100644 --- a/src/server/shared/Packets/ByteBuffer.cpp +++ b/src/server/shared/Packets/ByteBuffer.cpp @@ -17,11 +17,15 @@ */ #include "ByteBuffer.h" +#include "MessageBuffer.h" #include "Common.h" #include "Log.h" - #include <sstream> +ByteBuffer::ByteBuffer(MessageBuffer&& buffer) : _rpos(0), _wpos(0), _bitpos(InitialBitPos), _curbitval(0), _storage(buffer.Move()) +{ +} + ByteBufferPositionException::ByteBufferPositionException(bool add, size_t pos, size_t size, size_t valueSize) { @@ -69,8 +73,8 @@ void ByteBuffer::textlike() const o << "STORAGE_SIZE: " << size(); for (uint32 i = 0; i < size(); ++i) { - char buf[1]; - snprintf(buf, 1, "%c", read<uint8>(i)); + char buf[2]; + snprintf(buf, 2, "%c", read<uint8>(i)); o << buf; } o << " "; @@ -90,7 +94,7 @@ void ByteBuffer::hexlike() const for (uint32 i = 0; i < size(); ++i) { char buf[3]; - snprintf(buf, 1, "%2X ", read<uint8>(i)); + snprintf(buf, 3, "%2X ", read<uint8>(i)); if ((i == (j * 8)) && ((i != (k * 16)))) { o << "| "; diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 520c1a85fc2..f90f4814f2a 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -31,16 +31,18 @@ #include <vector> #include <cstring> #include <time.h> -#include <math.h> +#include <cmath> #include <boost/asio/buffer.hpp> +class MessageBuffer; + // Root of ByteBuffer exception hierarchy class ByteBufferException : public std::exception { public: ~ByteBufferException() throw() { } - char const* what() const throw() { return msg_.c_str(); } + char const* what() const throw() override { return msg_.c_str(); } protected: std::string & message() throw() { return msg_; } @@ -68,28 +70,27 @@ public: class ByteBuffer { public: - const static size_t DEFAULT_SIZE = 0x1000; + static size_t const DEFAULT_SIZE = 0x1000; + static uint8 const InitialBitPos = 8; // constructor - ByteBuffer() : _rpos(0), _wpos(0), _bitpos(8), _curbitval(0) + ByteBuffer() : _rpos(0), _wpos(0), _bitpos(InitialBitPos), _curbitval(0) { _storage.reserve(DEFAULT_SIZE); } - ByteBuffer(size_t reserve) : _rpos(0), _wpos(0), _bitpos(8), _curbitval(0) + ByteBuffer(size_t reserve) : _rpos(0), _wpos(0), _bitpos(InitialBitPos), _curbitval(0) { _storage.reserve(reserve); } ByteBuffer(ByteBuffer&& buf) : _rpos(buf._rpos), _wpos(buf._wpos), - _bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(std::move(buf._storage)) - { - } + _bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(std::move(buf._storage)) { } ByteBuffer(ByteBuffer const& right) : _rpos(right._rpos), _wpos(right._wpos), - _bitpos(right._bitpos), _curbitval(right._curbitval), _storage(right._storage) - { - } + _bitpos(right._bitpos), _curbitval(right._curbitval), _storage(right._storage) { } + + ByteBuffer(MessageBuffer&& buffer); ByteBuffer& operator=(ByteBuffer const& right) { diff --git a/src/server/shared/Threading/ProcessPriority.h b/src/server/shared/Threading/ProcessPriority.h index 06a5622fb9d..23238c94ace 100644 --- a/src/server/shared/Threading/ProcessPriority.h +++ b/src/server/shared/Threading/ProcessPriority.h @@ -32,7 +32,7 @@ void SetProcessPriority(const std::string logChannel) #if PLATFORM_APPLE (void)logChannel; #endif - + #if defined(_WIN32) || defined(__linux__) ///- Handle affinity for multiple processors and process priority diff --git a/src/server/shared/Threading/ProducerConsumerQueue.h b/src/server/shared/Threading/ProducerConsumerQueue.h index 1fee1d0685f..a76b8b0b5c0 100644 --- a/src/server/shared/Threading/ProducerConsumerQueue.h +++ b/src/server/shared/Threading/ProducerConsumerQueue.h @@ -39,10 +39,8 @@ public: void Push(const T& value) { - { - std::lock_guard<std::mutex> lock(_queueLock); - _queue.push(std::move(value)); - } + std::lock_guard<std::mutex> lock(_queueLock); + _queue.push(std::move(value)); _condition.notify_one(); } @@ -58,7 +56,7 @@ public: { std::lock_guard<std::mutex> lock(_queueLock); - if (_queue.empty()) + if (_queue.empty() || _shutdown) return false; value = _queue.front(); @@ -72,12 +70,9 @@ public: { std::unique_lock<std::mutex> lock(_queueLock); - while (_queue.empty() && !_shutdown) - { - _condition.wait(lock); - } + _condition.wait(lock, [this]() { return !_queue.empty() || _shutdown; }); - if (_queue.empty()) + if (_queue.empty() || _shutdown) return; value = _queue.front(); diff --git a/src/server/shared/Utilities/Timer.h b/src/server/shared/Utilities/Timer.h index 7c62de5f5ed..0e2d6ddbff5 100644 --- a/src/server/shared/Utilities/Timer.h +++ b/src/server/shared/Utilities/Timer.h @@ -27,7 +27,7 @@ inline uint32 getMSTime() { static const system_clock::time_point ApplicationStartTime = system_clock::now(); - return duration_cast<milliseconds>(system_clock::now() - ApplicationStartTime).count(); + return uint32(duration_cast<milliseconds>(system_clock::now() - ApplicationStartTime).count()); } inline uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime) diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index a5279eae03f..0bdc1fb714c 100644 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -18,13 +18,14 @@ #include "Util.h" #include "Common.h" +#include "CompilerDefs.h" #include "utf8.h" #include "SFMT.h" #include "Errors.h" // for ASSERT #include <stdarg.h> #include <boost/thread/tss.hpp> -#if PLATFORM == PLATFORM_UNIX +#if COMPILER == COMPILER_GNU #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index c8883773eed..d674acae09f 100644 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -620,7 +620,7 @@ class EventMap if (!phase) _phase = 0; else if (phase <= 8) - _phase = (1 << (phase - 1)); + _phase = uint8(1 << (phase - 1)); } /** @@ -631,7 +631,7 @@ class EventMap void AddPhase(uint8 phase) { if (phase && phase <= 8) - _phase |= (1 << (phase - 1)); + _phase |= uint8(1 << (phase - 1)); } /** @@ -642,7 +642,7 @@ class EventMap void RemovePhase(uint8 phase) { if (phase && phase <= 8) - _phase &= ~(1 << (phase - 1)); + _phase &= uint8(~(1 << (phase - 1))); } /** diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 3afa9e84e8b..e149902af02 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -87,6 +87,7 @@ bool StartDB(); void StopDB(); void WorldUpdateLoop(); void ClearOnlineAccounts(); +void ShutdownThreadPool(std::vector<std::thread>& threadPool); variables_map GetConsoleArguments(int argc, char** argv, std::string& cfg_file, std::string& cfg_service); /// Launch the Trinity server @@ -179,7 +180,10 @@ extern int main(int argc, char** argv) // Start the databases if (!StartDB()) + { + ShutdownThreadPool(threadPool); return 1; + } // Set server offline (not connectable) LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID); @@ -217,7 +221,7 @@ extern int main(int argc, char** argv) AsyncAcceptor<WorldSocket> worldAcceptor(_ioService, worldListener, worldPort, tcpNoDelay); - sScriptMgr->OnStartup(); + sScriptMgr->OnNetworkStart(); // Set server online (allow connecting now) LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID); @@ -233,16 +237,12 @@ extern int main(int argc, char** argv) TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", _FULLVERSION); + sScriptMgr->OnStartup(); + WorldUpdateLoop(); // Shutdown starts here - - _ioService.stop(); - - for (auto& thread : threadPool) - { - thread.join(); - } + ShutdownThreadPool(threadPool); sScriptMgr->OnShutdown(); @@ -281,41 +281,7 @@ extern int main(int argc, char** argv) if (cliThread != nullptr) { #ifdef _WIN32 - - // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API) - //_exit(1); - // send keyboard input to safely unblock the CLI thread - INPUT_RECORD b[4]; - HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); - b[0].EventType = KEY_EVENT; - b[0].Event.KeyEvent.bKeyDown = TRUE; - b[0].Event.KeyEvent.uChar.AsciiChar = 'X'; - b[0].Event.KeyEvent.wVirtualKeyCode = 'X'; - b[0].Event.KeyEvent.wRepeatCount = 1; - - b[1].EventType = KEY_EVENT; - b[1].Event.KeyEvent.bKeyDown = FALSE; - b[1].Event.KeyEvent.uChar.AsciiChar = 'X'; - b[1].Event.KeyEvent.wVirtualKeyCode = 'X'; - b[1].Event.KeyEvent.wRepeatCount = 1; - - b[2].EventType = KEY_EVENT; - b[2].Event.KeyEvent.bKeyDown = TRUE; - b[2].Event.KeyEvent.dwControlKeyState = 0; - b[2].Event.KeyEvent.uChar.AsciiChar = '\r'; - b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - b[2].Event.KeyEvent.wRepeatCount = 1; - b[2].Event.KeyEvent.wVirtualScanCode = 0x1c; - - b[3].EventType = KEY_EVENT; - b[3].Event.KeyEvent.bKeyDown = FALSE; - b[3].Event.KeyEvent.dwControlKeyState = 0; - b[3].Event.KeyEvent.uChar.AsciiChar = '\r'; - b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - b[3].Event.KeyEvent.wVirtualScanCode = 0x1c; - b[3].Event.KeyEvent.wRepeatCount = 1; - DWORD numb; - WriteConsoleInput(hStdIn, b, 4, &numb); + CancelSynchronousIo(cliThread->native_handle()); #endif cliThread->join(); delete cliThread; @@ -330,6 +296,17 @@ extern int main(int argc, char** argv) return World::GetExitCode(); } +void ShutdownThreadPool(std::vector<std::thread>& threadPool) +{ + sScriptMgr->OnNetworkStop(); + + _ioService.stop(); + + for (auto& thread : threadPool) + { + thread.join(); + } +} void WorldUpdateLoop() { diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h index 999a03a9009..3536d1160bc 100644 --- a/src/server/worldserver/TCSoap/TCSoap.h +++ b/src/server/worldserver/TCSoap/TCSoap.h @@ -21,6 +21,7 @@ #include "Define.h" #include <mutex> #include <future> +#include <string> void process_message(struct soap* soap_message); void TCSoapThread(const std::string& host, uint16 port); diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index ce512628e98..a6cdd2037b5 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -1715,6 +1715,15 @@ Rate.XP.Quest = 1 Rate.XP.Explore = 1 # +# Rate.Quest.Money.Reward +# Rate.Quest.Money.Max.Level.Reward +# Description: Multiplier for money quest rewards. Can not be below 0. +# Default: 1 + +Rate.Quest.Money.Reward = 1 +Rate.Quest.Money.Max.Level.Reward = 1 + +# # Rate.RepairCost # Description: Repair cost rate. # Default: 1 diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index b119b6cdbde..885dd24d760 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -63,7 +63,8 @@ namespace MMAP m_skipBattlegrounds (skipBattlegrounds), m_maxWalkableAngle (maxWalkableAngle), m_bigBaseUnit (bigBaseUnit), - m_rcContext (NULL) + m_rcContext (NULL), + _cancelationToken (false) { m_terrainBuilder = new TerrainBuilder(skipLiquid); diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 3e2025dace8..c2ca184905e 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -276,7 +276,7 @@ int main(int argc, char** argv) } if (!checkDirectories(debugOutput)) - return silent ? -3 : finish("Press any key to close...", -3); + return silent ? -3 : finish("Press ENTER to close...", -3); MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, debugOutput, bigBaseUnit, offMeshInputPath); |