diff --git a/changelog.txt b/changelog.txt index 5711f9d01..88180df59 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,50 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 01/31/2015 == +Trevius: Fixed FindGroundZ() and GetGroundZ() to once again utilize the X and Y arguments that are passed to them. + +== 01/30/2015 == +Akkadius: Implemented event type "EVENT_ENVIRONMENTAL_DAMAGE" + - This event triggers when taking any sort of environmental damage. Example use: + sub EVENT_ENVIRONMENTAL_DAMAGE{ + quest::debug("EVENT_ENVIRONMENTAL_DAMAGE"); + quest::debug("env_damage is " . $env_damage); + quest::debug("env_damage_type is " . $env_damage_type); + quest::debug("env_final_damage is " . $env_final_damage); + } + Result: (Test falling in Velks): http://i.imgur.com/tPRL7yL.png + - Implemented LUA counterpart of this same implementation above +Akkadius (Bobaski): Add PoK New Merchant sql/git/optional/2015_01_30_poknowledge_spell_vendors.sql + +== 01/29/2015 == +Trevius: Added more information to Mercenary Logging. +Trevius: Added potential fix for Mercenaries that fail to unsuspend. +Trevius: Added a new "statscale" field to the merc_stats table that can be used to quickly balance Mercenary Stats based on Level. +Trevius: The new "statscale" field now combines with the Mercs::ScaleRate rule value (default 100 percent for both). + +== 01/28/2015 == +Akkadius: Added Logs::DebugQuest category per request from Trevius (Great idea) + - Exported quest::debug(log_message, [debug_level = 1) + - Example: + quest::debug("This is a test debug message, level 1 (default)"); + quest::debug("This is a test debug message, level 1", 1); + quest::debug("This is a test debug message, level 2", 2); + quest::debug("This is a test debug message, level 3", 3); + + Result: http://i.imgur.com/6VoafGE.png + - Uses traditional logging system to output this category + - Required MySQL Source in Database version 9070 + +== 01/27/2015 == +Trevius: Removed "Mercenary Debug:" from the Mercenary Log entries. +Trevius: Resolved duplicate "You have no Mercenaries" messages when zoning without owning a Mercenary. +Trevius: Mercenaries should now always be able to unsuspend if the timer is up. +Trevius: More work on Mercenaries and Grouping to reduce bugs and redundant queries. +Uleat: Finished ClientVersion update to include patch file and namespace updates - don't forget to copy the renamed 'patch_UF.conf' into your eqemu directory.) + +== 01/26/2015 == +Uleat: Changed Corpse::MoveItemToCorpse() to allow 'by address' passing of removed item slot list. Fixed a bug that kept soul-bound items inside of bags from attuning properly + == 01/25/2015 == Trevius: Fixed an issue where Mercenaries were causing several DB queries per second while suspended. Trevius: Added Logs::Mercenaries to the new Logging System. Logging of Mercenary information is off by default with the required SQL. @@ -7,7 +52,7 @@ Trevius: Added Logs::Mercenaries to the new Logging System. Logging of Mercenar == 01/24/2015 == Uleat: Added equipment light source functionality to all mob derived classes (may still need tweaking...) Notes: - - In addition to equipment light sources, innate npc type light sources have already been activated + - In addition to equipment light sources, innate npc_type light sources have already been activated - Valid light source values are 0 thru 15 (values are bitmask checked and limited to 0x0F) - Not all classes handle equipment light sources the same way due to their equipment/loot list configurations - Spell (casting?) light sources may be implemented at some point..more information is needed @@ -18,7 +63,7 @@ Notes: Akkadius: Massive Log System overhaul, see: http://wiki.eqemulator.org/p?Logging_System_Overhaul&frm=Main == 01/21/2015 == -Uleat: Added `light` field to npctypes load query (all six clients tested positive for functionality.) +Uleat: Added `light` field to npc_types load query (all six clients tested positive for functionality.) Note: This only affects 'innate' light. Equipment (other) light is still in-work. Optional SQL: utils/sql/git/optional/2015_01_21_NPC_Types_Light_Field_Primer.sql diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index a9ae3fce3..f847957db 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -71,7 +71,7 @@ SET(common_sources patches/rof.cpp patches/rof2.cpp patches/titanium.cpp - patches/underfoot.cpp + patches/uf.cpp SocketLib/Base64.cpp SocketLib/File.cpp SocketLib/HttpdCookies.cpp @@ -216,11 +216,11 @@ SET(common_headers patches/titanium_itemfields.h patches/titanium_ops.h patches/titanium_structs.h - patches/underfoot.h - patches/underfoot_constants.h - patches/underfoot_itemfields.h - patches/underfoot_ops.h - patches/underfoot_structs.h + patches/uf.h + patches/uf_constants.h + patches/uf_itemfields.h + patches/uf_ops.h + patches/uf_structs.h SocketLib/Base64.h SocketLib/File.h SocketLib/HttpdCookies.h @@ -269,18 +269,18 @@ SOURCE_GROUP(Patches FILES patches/titanium_ops.h patches/titanium_constants.h patches/titanium_structs.h - patches/underfoot.h - patches/underfoot_itemfields.h - patches/underfoot_ops.h - patches/underfoot_constants.h - patches/underfoot_structs.h + patches/uf.h + patches/uf_itemfields.h + patches/uf_ops.h + patches/uf_constants.h + patches/uf_structs.h patches/patches.cpp patches/sod.cpp patches/sof.cpp patches/rof.cpp patches/rof2.cpp patches/titanium.cpp - patches/underfoot.cpp + patches/uf.cpp ) SOURCE_GROUP(SocketLib FILES @@ -330,7 +330,7 @@ ADD_LIBRARY(common ${common_sources} ${common_headers}) IF(UNIX) ADD_DEFINITIONS(-fPIC) SET_SOURCE_FILES_PROPERTIES("SocketLib/Mime.cpp" PROPERTY COMPILE_FLAGS -Wno-unused-result) - SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/underfoot.cpp" PROPERTIES COMPILE_FLAGS -O0) + SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0) ENDIF(UNIX) diff --git a/common/clientversions.h b/common/clientversions.h index a124ceae7..d0b5f7c41 100644 --- a/common/clientversions.h +++ b/common/clientversions.h @@ -7,14 +7,14 @@ static const uint32 BIT_Client62 = 1; static const uint32 BIT_Titanium = 2; static const uint32 BIT_SoF = 4; static const uint32 BIT_SoD = 8; -static const uint32 BIT_Underfoot = 16; +static const uint32 BIT_UF = 16; static const uint32 BIT_RoF = 32; static const uint32 BIT_RoF2 = 64; static const uint32 BIT_TitaniumAndEarlier = 0x00000003; static const uint32 BIT_SoFAndLater = 0xFFFFFFFC; static const uint32 BIT_SoDAndLater = 0xFFFFFFF8; -static const uint32 BIT_UnderfootAndLater = 0xFFFFFFF0; +static const uint32 BIT_UFAndLater = 0xFFFFFFF0; static const uint32 BIT_RoFAndLater = 0xFFFFFFE0; static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0; static const uint32 BIT_AllClients = 0xFFFFFFFF; @@ -23,10 +23,10 @@ enum class ClientVersion { Unknown = 0, Client62, // Build: 'Aug 4 2005 15:40:59' - Tit, // Build: 'Oct 31 2005 10:33:37' + Titanium, // Build: 'Oct 31 2005 10:33:37' SoF, // Build: 'Sep 7 2007 09:11:49' SoD, // Build: 'Dec 19 2008 15:22:49' - Und, // Build: 'Jun 8 2010 16:44:32' + UF, // Build: 'Jun 8 2010 16:44:32' RoF, // Build: 'Dec 10 2012 17:35:44' RoF2, // Build: 'May 10 2013 23:30:08' @@ -49,14 +49,14 @@ static const char* ClientVersionName(ClientVersion version) return "ClientVersion::Unknown"; case ClientVersion::Client62: return "ClientVersion::Client62"; - case ClientVersion::Tit: - return "ClientVersion::Tit"; + case ClientVersion::Titanium: + return "ClientVersion::Titanium"; case ClientVersion::SoF: return "ClientVersion::SoF"; case ClientVersion::SoD: return "ClientVersion::SoD"; - case ClientVersion::Und: - return "ClientVersion::Und"; + case ClientVersion::UF: + return "ClientVersion::UF"; case ClientVersion::RoF: return "ClientVersion::RoF"; case ClientVersion::RoF2: diff --git a/common/database.cpp b/common/database.cpp index 43a08f394..98639c6af 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -1991,7 +1991,7 @@ void Database::SetRaidGroupLeaderInfo(uint32 gid, uint32 rid) if (results.RowsAffected() != 0) return; - query = StringFormat("INSERT INTO raid_leaders(gid, rid, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%lu, %lu, '', '', '', '', '', '', 0)", + query = StringFormat("REPLACE INTO raid_leaders(gid, rid, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%lu, %lu, '', '', '', '', '', '', 0)", (unsigned long)gid, (unsigned long)rid); results = QueryDatabase(query); diff --git a/common/database.h b/common/database.h index 5c4b31d87..f3b8ba8c1 100644 --- a/common/database.h +++ b/common/database.h @@ -107,9 +107,9 @@ public: /* General Information Queries */ - bool AddBannedIP(char* bannedIP, const char* notes); //Lieka Edit: Add IP address to the Banned_IPs table. + bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the Banned_IPs table. bool AddGMIP(char* ip_address, char* name); - bool CheckBannedIPs(const char* loginIP); //Lieka Edit: Check incomming connection against banned IP table. + bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table. bool CheckGMIPs(const char* loginIP, uint32 account_id); bool CheckNameFilter(const char* name, bool surname = false); bool CheckUsedName(const char* name); @@ -118,7 +118,7 @@ public: uint32 GetAccountIDByChar(uint32 char_id); uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0); uint32 GetCharacterID(const char *name); - uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0,float* oX = 0, float* oY = 0, float* oZ = 0); + uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0); uint32 GetGuildIDByCharID(uint32 char_id); void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0); diff --git a/common/emu_tcp_connection.cpp b/common/emu_tcp_connection.cpp index 2ca55b975..da34f1ee7 100644 --- a/common/emu_tcp_connection.cpp +++ b/common/emu_tcp_connection.cpp @@ -104,7 +104,7 @@ EmuTCPConnection::EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, EmuTCPConne RelayCount = 0; RemoteID = iRemoteID; pOldFormat = false; - ConnectionType = Incomming; + ConnectionType = Incoming; TCPMode = modePacket; PacketMode = packetModeZone; #if TCPN_DEBUG_Memory >= 7 @@ -714,7 +714,7 @@ void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) { SendNetErrorPacket("Switch to RelayServer mode by a Relay Client"); break; } - if (ConnectionType != Incomming) { + if (ConnectionType != Incoming) { SendNetErrorPacket("Switch to RelayServer mode on outgoing connection"); break; } @@ -735,7 +735,7 @@ void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) { SendNetErrorPacket("New RelayClient: wrong size, expected 11"); break; } - if (ConnectionType != Incomming) { + if (ConnectionType != Incoming) { SendNetErrorPacket("New RelayClient: illegal on outgoing connection"); break; } @@ -755,7 +755,7 @@ void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) { } EmuTCPConnection* con = Server->FindConnection(*((uint32*)data)); if (con) { - if (ConnectionType == Incomming) { + if (ConnectionType == Incoming) { if (con->GetRelayLink() != this) { SendNetErrorPacket("Delete RelayClient: RelayLink != this"); break; diff --git a/common/eq_constants.h b/common/eq_constants.h index 3ff7abd6b..14f695069 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -368,7 +368,7 @@ enum { #define AT_DamageState 44 // The damage state of a destructible object (0 through 4) //#define AT_Trader 300 // Bazzar Trader Mode -// solar: animations for AT_Anim +// animations for AT_Anim #define ANIM_FREEZE 102 #define ANIM_STAND 0x64 #define ANIM_SIT 0x6e diff --git a/common/eq_dictionary.cpp b/common/eq_dictionary.cpp index 986f17848..ed3253260 100644 --- a/common/eq_dictionary.cpp +++ b/common/eq_dictionary.cpp @@ -492,7 +492,7 @@ uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion) { /*Titanium*/ Titanium::consts::MAP_CORPSE_SIZE, /*SoF*/ SoF::consts::MAP_CORPSE_SIZE, /*SoD*/ SoD::consts::MAP_CORPSE_SIZE, -/*Underfoot*/ Underfoot::consts::MAP_CORPSE_SIZE, +/*Underfoot*/ UF::consts::MAP_CORPSE_SIZE, /*RoF*/ RoF::consts::MAP_CORPSE_SIZE, /*RoF2*/ RoF2::consts::MAP_CORPSE_SIZE, @@ -522,7 +522,7 @@ uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion) { /*Titanium*/ Titanium::consts::MAP_INSPECT_SIZE, /*SoF*/ SoF::consts::MAP_INSPECT_SIZE, /*SoD*/ SoD::consts::MAP_INSPECT_SIZE, -/*Underfoot*/ Underfoot::consts::MAP_INSPECT_SIZE, +/*Underfoot*/ UF::consts::MAP_INSPECT_SIZE, /*RoF*/ RoF::consts::MAP_INSPECT_SIZE, /*RoF2*/ RoF2::consts::MAP_INSPECT_SIZE, @@ -800,7 +800,7 @@ bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion) { /*Titanium*/ Titanium::limits::ALLOWS_EMPTY_BAG_IN_BAG, /*SoF*/ SoF::limits::ALLOWS_EMPTY_BAG_IN_BAG, /*SoD*/ SoD::limits::ALLOWS_EMPTY_BAG_IN_BAG, -/*Underfoot*/ Underfoot::limits::ALLOWS_EMPTY_BAG_IN_BAG, +/*Underfoot*/ UF::limits::ALLOWS_EMPTY_BAG_IN_BAG, /*RoF*/ RoF::limits::ALLOWS_EMPTY_BAG_IN_BAG, /*RoF2*/ RoF2::limits::ALLOWS_EMPTY_BAG_IN_BAG, @@ -821,7 +821,7 @@ bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion) { /*Titanium*/ Titanium::limits::ALLOWS_CLICK_CAST_FROM_BAG, /*SoF*/ SoF::limits::ALLOWS_CLICK_CAST_FROM_BAG, /*SoD*/ SoD::limits::ALLOWS_CLICK_CAST_FROM_BAG, -/*Underfoot*/ Underfoot::limits::ALLOWS_CLICK_CAST_FROM_BAG, +/*Underfoot*/ UF::limits::ALLOWS_CLICK_CAST_FROM_BAG, /*RoF*/ RoF::limits::ALLOWS_CLICK_CAST_FROM_BAG, /*RoF2*/ RoF2::limits::ALLOWS_CLICK_CAST_FROM_BAG, @@ -882,7 +882,7 @@ bool EQLimits::CoinHasWeight(ClientVersion clientVersion) { /*Titanium*/ Titanium::limits::COIN_HAS_WEIGHT, /*SoF*/ SoF::limits::COIN_HAS_WEIGHT, /*SoD*/ SoD::limits::COIN_HAS_WEIGHT, -/*Underfoot*/ Underfoot::limits::COIN_HAS_WEIGHT, +/*Underfoot*/ UF::limits::COIN_HAS_WEIGHT, /*RoF*/ RoF::limits::COIN_HAS_WEIGHT, /*RoF2*/ RoF::limits::COIN_HAS_WEIGHT, diff --git a/common/eq_dictionary.h b/common/eq_dictionary.h index a61eb7bfd..d1337856e 100644 --- a/common/eq_dictionary.h +++ b/common/eq_dictionary.h @@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/patches/titanium_constants.h" #include "../common/patches/sof_constants.h" #include "../common/patches/sod_constants.h" -#include "../common/patches/underfoot_constants.h" +#include "../common/patches/uf_constants.h" #include "../common/patches/rof_constants.h" #include "../common/patches/rof2_constants.h" diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index a85e45be4..62f6072b3 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -540,7 +540,7 @@ struct SpawnAppearance_Struct }; -// solar: this is used inside profile +// this is used inside profile struct SpellBuff_Struct { /*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise @@ -1268,7 +1268,7 @@ struct Animation_Struct { /*04*/ }; -// solar: this is what causes the caster to animate and the target to +// this is what causes the caster to animate and the target to // get the particle effects around them when a spell is cast // also causes a buff icon struct Action_Struct @@ -1292,7 +1292,7 @@ struct Action_Struct /* 31 */ }; -// solar: this is what prints the You have been struck. and the regular +// this is what prints the You have been struck. and the regular // melee messages like You try to pierce, etc. It's basically the melee // and spell damage message struct CombatDamage_Struct @@ -1811,7 +1811,7 @@ struct RandomReq_Struct { uint32 high; }; -/* solar: 9/23/03 reply to /random command; struct from Zaphod */ +/* 9/23/03 reply to /random command */ struct RandomReply_Struct { /* 00 */ uint32 low; /* 04 */ uint32 high; diff --git a/common/eq_stream.h b/common/eq_stream.h index bcbb548e9..72eb53cdd 100644 --- a/common/eq_stream.h +++ b/common/eq_stream.h @@ -206,8 +206,14 @@ class EQStream : public EQStreamInterface { void init(bool resetSession=true); public: - EQStream() { init(); remote_ip = 0; remote_port = 0; State=UNESTABLISHED; StreamType=UnknownStream; compressed=true; encoded=false; app_opcode_size=2; bytes_sent=0; bytes_recv=0; create_time=Timer::GetTimeSeconds(); sessionAttempts = 0; streamactive=false; } - EQStream(sockaddr_in addr) { init(); remote_ip=addr.sin_addr.s_addr; remote_port=addr.sin_port; State=UNESTABLISHED; StreamType=UnknownStream; compressed=true; encoded=false; app_opcode_size=2; bytes_sent=0; bytes_recv=0; create_time=Timer::GetTimeSeconds(); } + EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED; + StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2; + bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0; + streamactive = false; } + EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr; + remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream; + compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0; + create_time = Timer::GetTimeSeconds(); } virtual ~EQStream() { RemoveData(); SetState(CLOSED); } void SetMaxLen(uint32 length) { MaxLen=length; } diff --git a/common/eq_stream_factory.cpp b/common/eq_stream_factory.cpp index 7563c9b57..f48b0f723 100644 --- a/common/eq_stream_factory.cpp +++ b/common/eq_stream_factory.cpp @@ -116,12 +116,12 @@ struct sockaddr_in address; return true; } -EQStream *EQStreamFactory::Pop() +std::shared_ptr EQStreamFactory::Pop() { -EQStream *s=nullptr; + std::shared_ptr s = nullptr; MNewStreams.lock(); if (NewStreams.size()) { - s=NewStreams.front(); + s = NewStreams.front(); NewStreams.pop(); s->PutInUse(); } @@ -130,7 +130,7 @@ EQStream *s=nullptr; return s; } -void EQStreamFactory::Push(EQStream *s) +void EQStreamFactory::Push(std::shared_ptr s) { MNewStreams.lock(); NewStreams.push(s); @@ -139,17 +139,16 @@ void EQStreamFactory::Push(EQStream *s) void EQStreamFactory::ReaderLoop() { -fd_set readset; -std::map,EQStream *>::iterator stream_itr; -int num; -int length; -unsigned char buffer[2048]; -sockaddr_in from; -int socklen=sizeof(sockaddr_in); -timeval sleep_time; -//time_t now; + fd_set readset; + std::map, std::shared_ptr>::iterator stream_itr; + int num; + int length; + unsigned char buffer[2048]; + sockaddr_in from; + int socklen = sizeof(sockaddr_in); + timeval sleep_time; + ReaderRunning = true; - ReaderRunning=true; while(sock!=-1) { MReaderRunning.lock(); if (!ReaderRunning) @@ -180,10 +179,10 @@ timeval sleep_time; // What do we wanna do? } else { MStreams.lock(); - stream_itr=Streams.find(std::make_pair(from.sin_addr.s_addr, from.sin_port)); + stream_itr = Streams.find(std::make_pair(from.sin_addr.s_addr, from.sin_port)); if (stream_itr == Streams.end()) { if (buffer[1]==OP_SessionRequest) { - EQStream *s = new EQStream(from); + std::shared_ptr s = std::make_shared(from); s->SetStreamType(StreamType); Streams[std::make_pair(from.sin_addr.s_addr, from.sin_port)]=s; WriterWork.Signal(); @@ -194,13 +193,13 @@ timeval sleep_time; } MStreams.unlock(); } else { - EQStream *curstream = stream_itr->second; + std::shared_ptr curstream = stream_itr->second; //dont bother processing incoming packets for closed connections if(curstream->CheckClosed()) curstream = nullptr; else curstream->PutInUse(); - MStreams.unlock(); //the in use flag prevents the stream from being deleted while we are using it. + //the in use flag prevents the stream from being deleted while we are using it. if(curstream) { curstream->AddBytesRecv(length); @@ -208,6 +207,7 @@ timeval sleep_time; curstream->SetLastPacketTime(Timer::GetCurrentTime()); curstream->ReleaseFromUse(); } + MStreams.unlock(); } } } @@ -220,10 +220,10 @@ void EQStreamFactory::CheckTimeout() MStreams.lock(); unsigned long now=Timer::GetCurrentTime(); - std::map,EQStream *>::iterator stream_itr; + std::map, std::shared_ptr>::iterator stream_itr; - for(stream_itr=Streams.begin();stream_itr!=Streams.end();) { - EQStream *s = stream_itr->second; + for(stream_itr = Streams.begin(); stream_itr != Streams.end();) { + std::shared_ptr s = stream_itr->second; s->CheckTimeout(now, stream_timeout); @@ -235,10 +235,9 @@ void EQStreamFactory::CheckTimeout() //give it a little time for everybody to finish with it } else { //everybody is done, we can delete it now - std::map,EQStream *>::iterator temp=stream_itr; + std::map, std::shared_ptr>::iterator temp = stream_itr; ++stream_itr; - //let whoever has the stream outside delete it - delete temp->second; + temp->second = nullptr; Streams.erase(temp); continue; } @@ -251,21 +250,17 @@ void EQStreamFactory::CheckTimeout() void EQStreamFactory::WriterLoop() { -std::map,EQStream *>::iterator stream_itr; -bool havework=true; -std::vector wants_write; -std::vector::iterator cur,end; -bool decay=false; -uint32 stream_count; - -Timer DecayTimer(20); - - WriterRunning=true; + std::map, std::shared_ptr>::iterator stream_itr; + bool havework=true; + std::vector> wants_write; + std::vector>::iterator cur, end; + bool decay = false; + uint32 stream_count; + Timer DecayTimer(20); + WriterRunning = true; DecayTimer.Enable(); + while(sock!=-1) { - //if (!havework) { - //WriterWork.Wait(); - //} MWriterRunning.lock(); if (!WriterRunning) break; @@ -309,7 +304,7 @@ Timer DecayTimer(20); Sleep(10); MStreams.lock(); - stream_count=Streams.size(); + stream_count = Streams.size(); MStreams.unlock(); if (!stream_count) { WriterWork.Wait(); diff --git a/common/eq_stream_factory.h b/common/eq_stream_factory.h index 58fddaa40..86ffff979 100644 --- a/common/eq_stream_factory.h +++ b/common/eq_stream_factory.h @@ -2,6 +2,7 @@ #define _EQSTREAMFACTORY_H +#include #include #include @@ -26,10 +27,10 @@ class EQStreamFactory : private Timeoutable { EQStreamType StreamType; - std::queue NewStreams; + std::queue> NewStreams; Mutex MNewStreams; - std::map,EQStream *> Streams; + std::map, std::shared_ptr> Streams; Mutex MStreams; virtual void CheckTimeout(); @@ -42,8 +43,8 @@ class EQStreamFactory : private Timeoutable { EQStreamFactory(EQStreamType type, uint32 timeout = 135000) : Timeoutable(5000), stream_timeout(timeout) { ReaderRunning=false; WriterRunning=false; StreamType=type; sock=-1; } EQStreamFactory(EQStreamType type, int port, uint32 timeout = 135000); - EQStream *Pop(); - void Push(EQStream *s); + std::shared_ptr Pop(); + void Push(std::shared_ptr s); bool Open(); bool Open(unsigned long port) { Port=port; return Open(); } diff --git a/common/eq_stream_ident.cpp b/common/eq_stream_ident.cpp index 6fef4275e..4640c75f1 100644 --- a/common/eq_stream_ident.cpp +++ b/common/eq_stream_ident.cpp @@ -9,13 +9,12 @@ EQStreamIdentifier::~EQStreamIdentifier() { m_identified.front()->ReleaseFromUse(); m_identified.pop(); } - std::vector::iterator cur, end; + std::vector::iterator cur, end; cur = m_streams.begin(); end = m_streams.end(); for(; cur != end; ++cur) { - Record *r = *cur; - r->stream->ReleaseFromUse(); - delete r; + Record &r = *cur; + r.stream->ReleaseFromUse(); } std::vector::iterator curp, endp; curp = m_patches.begin(); @@ -35,35 +34,34 @@ void EQStreamIdentifier::RegisterPatch(const EQStream::Signature &sig, const cha } void EQStreamIdentifier::Process() { - std::vector::iterator cur; + std::vector::iterator cur; std::vector::iterator curp, endp; //foreach pending stream. cur = m_streams.begin(); while(cur != m_streams.end()) { - Record *r = *cur; + Record &r = *cur; //first see if this stream has expired - if(r->expire.Check(false)) { + if(r.expire.Check(false)) { //this stream has failed to match any pattern in our timeframe. - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before timeout.", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort())); - r->stream->ReleaseFromUse(); - delete r; + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before timeout.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); + r.stream->ReleaseFromUse(); cur = m_streams.erase(cur); continue; } //then make sure the stream is still active //if stream hasn't finished initializing then continue; - if(r->stream->GetState() == UNESTABLISHED) + if(r.stream->GetState() == UNESTABLISHED) { ++cur; continue; } - if(r->stream->GetState() != ESTABLISHED) { + if(r.stream->GetState() != ESTABLISHED) { //the stream closed before it was identified. - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before it closed.", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort())); - switch(r->stream->GetState()) + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before it closed.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); + switch(r.stream->GetState()) { case ESTABLISHED: Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Established"); @@ -81,8 +79,7 @@ void EQStreamIdentifier::Process() { Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Unestablished or unknown"); break; } - r->stream->ReleaseFromUse(); - delete r; + r.stream->ReleaseFromUse(); cur = m_streams.erase(cur); continue; } @@ -99,23 +96,23 @@ void EQStreamIdentifier::Process() { Patch *p = *curp; //ask the stream to see if it matches the supplied signature - EQStream::MatchState res = r->stream->CheckSignature(&p->signature); + EQStream::MatchState res = r.stream->CheckSignature(&p->signature); switch(res) { case EQStream::MatchNotReady: //the stream has not received enough packets to compare with this signature -// Log.LogDebugType(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort()), p->name.c_str()); +// Log.LogDebugType(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str()); all_ready = false; break; case EQStream::MatchSuccessful: { //yay, a match. - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Identified stream %s:%d with signature %s", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort()), p->name.c_str()); + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Identified stream %s:%d with signature %s", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str()); // before we assign the eqstream to an interface, let the stream recognize it is in use and the session should not be reset any further - r->stream->SetActive(true); + r.stream->SetActive(true); //might want to do something less-specific here... some day.. - EQStreamInterface *s = new EQStreamProxy(r->stream, p->structs, p->opcodes); + EQStreamInterface *s = new EQStreamProxy(r.stream, p->structs, p->opcodes); m_identified.push(s); found_one = true; @@ -123,7 +120,7 @@ void EQStreamIdentifier::Process() { } case EQStream::MatchFailed: //do nothing... - Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, and it did not match.", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort()), p->name.c_str()); + Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, and it did not match.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str()); break; } } @@ -131,14 +128,13 @@ void EQStreamIdentifier::Process() { //if we checked all patches and did not find a match. if(all_ready && !found_one) { //the stream cannot be identified. - Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d, no match found.", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort())); - r->stream->ReleaseFromUse(); + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d, no match found.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); + r.stream->ReleaseFromUse(); } //if we found a match, or were not able to identify it if(found_one || all_ready) { - //cannot print ip/port here. r->stream is invalid. - delete r; + //cannot print ip/port here. r.stream is invalid. cur = m_streams.erase(cur); } else { ++cur; @@ -146,8 +142,8 @@ void EQStreamIdentifier::Process() { } //end foreach stream } -void EQStreamIdentifier::AddStream(EQStream *&eqs) { - m_streams.push_back(new Record(eqs)); +void EQStreamIdentifier::AddStream(std::shared_ptr &eqs) { + m_streams.push_back(Record(eqs)); eqs = nullptr; } @@ -159,7 +155,7 @@ EQStreamInterface *EQStreamIdentifier::PopIdentified() { return(res); } -EQStreamIdentifier::Record::Record(EQStream *s) +EQStreamIdentifier::Record::Record(std::shared_ptr s) : stream(s), expire(STREAM_IDENT_WAIT_MS) { diff --git a/common/eq_stream_ident.h b/common/eq_stream_ident.h index 2020c85cf..3b6a63ed9 100644 --- a/common/eq_stream_ident.h +++ b/common/eq_stream_ident.h @@ -5,6 +5,7 @@ #include "timer.h" #include #include +#include #define STREAM_IDENT_WAIT_MS 10000 @@ -21,7 +22,7 @@ public: //main processing interface void Process(); - void AddStream(EQStream *& eqs); + void AddStream(std::shared_ptr &eqs); EQStreamInterface *PopIdentified(); protected: @@ -39,11 +40,11 @@ protected: //pending streams.. class Record { public: - Record(EQStream *s); - EQStream *stream; //we own this + Record(std::shared_ptr s); + std::shared_ptr stream; //we own this Timer expire; }; - std::vector m_streams; //we own these objects, and the streams contained in them. + std::vector m_streams; //we own these objects, and the streams contained in them. std::queue m_identified; //we own these objects }; diff --git a/common/eq_stream_proxy.cpp b/common/eq_stream_proxy.cpp index 968f06d84..117ae8c94 100644 --- a/common/eq_stream_proxy.cpp +++ b/common/eq_stream_proxy.cpp @@ -5,7 +5,7 @@ #include "struct_strategy.h" -EQStreamProxy::EQStreamProxy(EQStream *&stream, const StructStrategy *structs, OpcodeManager **opcodes) +EQStreamProxy::EQStreamProxy(std::shared_ptr &stream, const StructStrategy *structs, OpcodeManager **opcodes) : m_stream(stream), m_structs(structs), m_opcodes(opcodes) @@ -15,7 +15,6 @@ EQStreamProxy::EQStreamProxy(EQStream *&stream, const StructStrategy *structs, O } EQStreamProxy::~EQStreamProxy() { - //delete m_stream; //released by the stream factory. } std::string EQStreamProxy::Describe() const { @@ -85,12 +84,6 @@ const uint32 EQStreamProxy::GetBytesRecvPerSecond() const void EQStreamProxy::ReleaseFromUse() { m_stream->ReleaseFromUse(); - - //this is so ugly, but I cant think of a better way to deal with - //it right now... - if(!m_stream->IsInUse()) { - delete this; - } } void EQStreamProxy::RemoveData() { diff --git a/common/eq_stream_proxy.h b/common/eq_stream_proxy.h index f82dd790f..93ad1d884 100644 --- a/common/eq_stream_proxy.h +++ b/common/eq_stream_proxy.h @@ -4,8 +4,9 @@ #include "types.h" #include "eq_stream_intf.h" +#include "eq_stream.h" +#include -class EQStream; class StructStrategy; class OpcodeManager; class EQApplicationPacket; @@ -13,7 +14,7 @@ class EQApplicationPacket; class EQStreamProxy : public EQStreamInterface { public: //takes ownership of the stream. - EQStreamProxy(EQStream *&stream, const StructStrategy *structs, OpcodeManager **opcodes); + EQStreamProxy(std::shared_ptr &stream, const StructStrategy *structs, OpcodeManager **opcodes); virtual ~EQStreamProxy(); //EQStreamInterface: @@ -35,7 +36,7 @@ public: virtual const uint32 GetBytesRecvPerSecond() const; protected: - EQStream *const m_stream; //we own this stream object. + std::shared_ptr const m_stream; //we own this stream object. const StructStrategy *const m_structs; //we do not own this object. //this is a pointer to a pointer to make it less likely that a packet will //reference an invalid opcode manager when they are being reloaded. diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index 7f462696b..51b069f28 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -72,7 +72,7 @@ namespace Console { LightRed = 12, LightMagenta = 13, Yellow = 14, - White = 15, + White = 15 }; } @@ -174,7 +174,7 @@ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const process_log << time_stamp << " " << message << std::endl; } -uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category){ +uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) { switch (log_category) { case Logs::Status: case Logs::Normal: @@ -197,7 +197,7 @@ uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category){ } } -std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category){ +std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) { switch (log_category) { case Logs::Status: case Logs::Normal: @@ -220,7 +220,7 @@ std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category){ } } -uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category){ +uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) { switch (log_category) { case Logs::Status: case Logs::Normal: @@ -317,7 +317,7 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name) void EQEmuLogSys::CloseFileLogs() { - if (process_log.is_open()){ + if (process_log.is_open()) { process_log.close(); } } diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index 491ded3c6..97aaebe62 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -26,11 +26,11 @@ #include "types.h" -namespace Logs{ +namespace Logs { enum DebugLevel { General = 1, /* 1 - Low-Level general debugging, useful info on single line */ Moderate, /* 2 - Informational based, used in functions, when particular things load */ - Detail, /* 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication */ + Detail /* 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication */ }; /* @@ -77,6 +77,7 @@ namespace Logs{ MySQLError, MySQLQuery, Mercenaries, + QuestDebug, MaxCategoryID /* Don't Remove this*/ }; @@ -120,6 +121,7 @@ namespace Logs{ "MySQL Error", "MySQL Query", "Mercenaries", + "Quest Debug" }; } @@ -141,7 +143,7 @@ public: be checked against to see if that piped output is set to actually process it for the category and debug level */ void Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...); - void SetCurrentTimeStamp(char* time_stamp); /* Used in file logs to prepend a timestamp entry for logs */ + void SetCurrentTimeStamp(char* time_stamp); /* Used in file logs to prepend a timestamp entry for logs */ void StartFileLogs(const std::string &log_name = ""); /* Used to declare the processes file log and to keep it open for later use */ /* @@ -154,7 +156,7 @@ public: log_to_gmsay[category_id] = [1-3] - Sets debug level for category to output to gmsay */ - struct LogSettings{ + struct LogSettings { uint8 log_to_file; uint8 log_to_console; uint8 log_to_gmsay; diff --git a/common/item.cpp b/common/item.cpp index 35de0e773..a43b5d12b 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -1441,6 +1441,7 @@ ItemInst::ItemInst(const Item_Struct* item, int16 charges) { m_ornamenticon = 0; m_ornamentidfile = 0; m_ornament_hero_model = 0; + m_recast_timestamp = 0; } ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) { @@ -1466,6 +1467,7 @@ ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) { m_ornamenticon = 0; m_ornamentidfile = 0; m_ornament_hero_model = 0; + m_recast_timestamp = 0; } ItemInst::ItemInst(ItemInstTypes use_type) { @@ -1486,6 +1488,7 @@ ItemInst::ItemInst(ItemInstTypes use_type) { m_ornamenticon = 0; m_ornamentidfile = 0; m_ornament_hero_model = 0; + m_recast_timestamp = 0; } // Make a copy of an ItemInst object @@ -1539,6 +1542,7 @@ ItemInst::ItemInst(const ItemInst& copy) m_ornamenticon = copy.m_ornamenticon; m_ornamentidfile = copy.m_ornamentidfile; m_ornament_hero_model = copy.m_ornament_hero_model; + m_recast_timestamp = copy.m_recast_timestamp; } // Clean up container contents diff --git a/common/item.h b/common/item.h index 0868e8c5f..fd30b5ea0 100644 --- a/common/item.h +++ b/common/item.h @@ -403,6 +403,8 @@ public: void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; } uint32 GetOrnamentHeroModel(int32 material_slot = -1) const; void SetOrnamentHeroModel(uint32 ornament_hero_model) { m_ornament_hero_model = ornament_hero_model; } + uint32 GetRecastTimestamp() const { return m_recast_timestamp; } + void SetRecastTimestamp(uint32 in) { m_recast_timestamp = in; } void Initialize(SharedDatabase *db = nullptr); void ScaleItem(); @@ -450,6 +452,7 @@ protected: uint32 m_ornamenticon; uint32 m_ornamentidfile; uint32 m_ornament_hero_model; + uint32 m_recast_timestamp; // // Items inside of this item (augs or contents); diff --git a/common/patches/patches.cpp b/common/patches/patches.cpp index 55c0d4e8b..3147b89f6 100644 --- a/common/patches/patches.cpp +++ b/common/patches/patches.cpp @@ -3,7 +3,7 @@ #include "patches.h" #include "titanium.h" -#include "underfoot.h" +#include "uf.h" #include "sof.h" #include "sod.h" #include "rof.h" @@ -13,7 +13,7 @@ void RegisterAllPatches(EQStreamIdentifier &into) { Titanium::Register(into); SoF::Register(into); SoD::Register(into); - Underfoot::Register(into); + UF::Register(into); RoF::Register(into); RoF2::Register(into); } @@ -22,7 +22,7 @@ void ReloadAllPatches() { Titanium::Reload(); SoF::Reload(); SoD::Reload(); - Underfoot::Reload(); + UF::Reload(); RoF::Reload(); RoF2::Reload(); } diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 3440ee3d0..772e60517 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -25,14 +25,14 @@ namespace RoF char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth); // server to client inventory location converters - static inline structs::ItemSlotStruct ServerToRoFSlot(uint32 ServerSlot); - static inline structs::MainInvItemSlotStruct ServerToRoFMainInvSlot(uint32 ServerSlot); - static inline uint32 ServerToRoFCorpseSlot(uint32 ServerCorpse); + static inline structs::ItemSlotStruct ServerToRoFSlot(uint32 serverSlot); + static inline structs::MainInvItemSlotStruct ServerToRoFMainInvSlot(uint32 serverSlot); + static inline uint32 ServerToRoFCorpseSlot(uint32 serverCorpseSlot); // client to server inventory location converters - static inline uint32 RoFToServerSlot(structs::ItemSlotStruct RoFSlot); - static inline uint32 RoFToServerMainInvSlot(structs::MainInvItemSlotStruct RoFSlot); - static inline uint32 RoFToServerCorpseSlot(uint32 RoFCorpse); + static inline uint32 RoFToServerSlot(structs::ItemSlotStruct rofSlot); + static inline uint32 RoFToServerMainInvSlot(structs::MainInvItemSlotStruct rofSlot); + static inline uint32 RoFToServerCorpseSlot(uint32 rofCorpseSlot); // server to client text link converter static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink); @@ -4650,7 +4650,7 @@ namespace RoF SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot.MainSlot, eq->to_slot.MainSlot); - Log.Out(Logs::General, Logs::Netcode, "[ERROR] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack); + Log.Out(Logs::General, Logs::Netcode, "[RoF] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack); emu->from_slot = RoFToServerSlot(eq->from_slot); emu->to_slot = RoFToServerSlot(eq->to_slot); IN(number_in_stack); @@ -5000,7 +5000,7 @@ namespace RoF hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0; hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot; hdr.unknown028 = 0; - hdr.last_cast_time = ((item->RecastDelay > 1) ? 1212693140 : 0); + hdr.last_cast_time = inst->GetRecastTimestamp(); hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges); hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0; hdr.unknown044 = 0; @@ -5507,7 +5507,7 @@ namespace RoF return item_serial; } - static inline structs::ItemSlotStruct ServerToRoFSlot(uint32 ServerSlot) + static inline structs::ItemSlotStruct ServerToRoFSlot(uint32 serverSlot) { structs::ItemSlotStruct RoFSlot; RoFSlot.SlotType = INVALID_INDEX; @@ -5519,17 +5519,17 @@ namespace RoF uint32 TempSlot = 0; - if (ServerSlot < 56 || ServerSlot == MainPowerSource) { // Main Inventory and Cursor + if (serverSlot < 56 || serverSlot == MainPowerSource) { // Main Inventory and Cursor RoFSlot.SlotType = maps::MapPossessions; - RoFSlot.MainSlot = ServerSlot; + RoFSlot.MainSlot = serverSlot; - if (ServerSlot == MainPowerSource) + if (serverSlot == MainPowerSource) RoFSlot.MainSlot = slots::MainPowerSource; - else if (ServerSlot >= MainCursor) // Cursor and Extended Corpse Inventory + else if (serverSlot >= MainCursor) // Cursor and Extended Corpse Inventory RoFSlot.MainSlot += 3; - else if (ServerSlot >= MainAmmo) // (> 20) + else if (serverSlot >= MainAmmo) // (> 20) RoFSlot.MainSlot += 1; } @@ -5538,9 +5538,9 @@ namespace RoF RoFSlot.MainSlot = ServerSlot - 31; }*/ - else if (ServerSlot >= EmuConstants::GENERAL_BAGS_BEGIN && ServerSlot <= EmuConstants::CURSOR_BAG_END) { // (> 250 && < 341) + else if (serverSlot >= EmuConstants::GENERAL_BAGS_BEGIN && serverSlot <= EmuConstants::CURSOR_BAG_END) { // (> 250 && < 341) RoFSlot.SlotType = maps::MapPossessions; - TempSlot = ServerSlot - 1; + TempSlot = serverSlot - 1; RoFSlot.MainSlot = int(TempSlot / EmuConstants::ITEM_CONTAINER_SIZE) - 2; RoFSlot.SubSlot = TempSlot - ((RoFSlot.MainSlot + 2) * EmuConstants::ITEM_CONTAINER_SIZE); @@ -5548,14 +5548,14 @@ namespace RoF RoFSlot.MainSlot = slots::MainCursor; } - else if (ServerSlot >= EmuConstants::TRIBUTE_BEGIN && ServerSlot <= EmuConstants::TRIBUTE_END) { // Tribute + else if (serverSlot >= EmuConstants::TRIBUTE_BEGIN && serverSlot <= EmuConstants::TRIBUTE_END) { // Tribute RoFSlot.SlotType = maps::MapTribute; - RoFSlot.MainSlot = ServerSlot - EmuConstants::TRIBUTE_BEGIN; + RoFSlot.MainSlot = serverSlot - EmuConstants::TRIBUTE_BEGIN; } - else if (ServerSlot >= EmuConstants::BANK_BEGIN && ServerSlot <= EmuConstants::BANK_BAGS_END) { + else if (serverSlot >= EmuConstants::BANK_BEGIN && serverSlot <= EmuConstants::BANK_BAGS_END) { RoFSlot.SlotType = maps::MapBank; - TempSlot = ServerSlot - EmuConstants::BANK_BEGIN; + TempSlot = serverSlot - EmuConstants::BANK_BEGIN; RoFSlot.MainSlot = TempSlot; if (TempSlot > 30) { // (> 30) @@ -5564,9 +5564,9 @@ namespace RoF } } - else if (ServerSlot >= EmuConstants::SHARED_BANK_BEGIN && ServerSlot <= EmuConstants::SHARED_BANK_BAGS_END) { + else if (serverSlot >= EmuConstants::SHARED_BANK_BEGIN && serverSlot <= EmuConstants::SHARED_BANK_BAGS_END) { RoFSlot.SlotType = maps::MapSharedBank; - TempSlot = ServerSlot - EmuConstants::SHARED_BANK_BEGIN; + TempSlot = serverSlot - EmuConstants::SHARED_BANK_BEGIN; RoFSlot.MainSlot = TempSlot; if (TempSlot > 30) { // (> 30) @@ -5575,9 +5575,9 @@ namespace RoF } } - else if (ServerSlot >= EmuConstants::TRADE_BEGIN && ServerSlot <= EmuConstants::TRADE_BAGS_END) { + else if (serverSlot >= EmuConstants::TRADE_BEGIN && serverSlot <= EmuConstants::TRADE_BAGS_END) { RoFSlot.SlotType = maps::MapTrade; - TempSlot = ServerSlot - EmuConstants::TRADE_BEGIN; + TempSlot = serverSlot - EmuConstants::TRADE_BEGIN; RoFSlot.MainSlot = TempSlot; if (TempSlot > 30) { @@ -5599,18 +5599,18 @@ namespace RoF */ } - else if (ServerSlot >= EmuConstants::WORLD_BEGIN && ServerSlot <= EmuConstants::WORLD_END) { + else if (serverSlot >= EmuConstants::WORLD_BEGIN && serverSlot <= EmuConstants::WORLD_END) { RoFSlot.SlotType = maps::MapWorld; - TempSlot = ServerSlot - EmuConstants::WORLD_BEGIN; + TempSlot = serverSlot - EmuConstants::WORLD_BEGIN; RoFSlot.MainSlot = TempSlot; } - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i", ServerSlot, RoFSlot.SlotType, RoFSlot.Unknown02, RoFSlot.MainSlot, RoFSlot.SubSlot, RoFSlot.AugSlot, RoFSlot.Unknown01); + Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i", serverSlot, RoFSlot.SlotType, RoFSlot.Unknown02, RoFSlot.MainSlot, RoFSlot.SubSlot, RoFSlot.AugSlot, RoFSlot.Unknown01); return RoFSlot; } - static inline structs::MainInvItemSlotStruct ServerToRoFMainInvSlot(uint32 ServerSlot) + static inline structs::MainInvItemSlotStruct ServerToRoFMainInvSlot(uint32 serverSlot) { structs::MainInvItemSlotStruct RoFSlot; RoFSlot.MainSlot = INVALID_INDEX; @@ -5620,16 +5620,16 @@ namespace RoF uint32 TempSlot = 0; - if (ServerSlot < 56 || ServerSlot == MainPowerSource) { // (< 52) - RoFSlot.MainSlot = ServerSlot; + if (serverSlot < 56 || serverSlot == MainPowerSource) { // (< 52) + RoFSlot.MainSlot = serverSlot; - if (ServerSlot == MainPowerSource) + if (serverSlot == MainPowerSource) RoFSlot.MainSlot = slots::MainPowerSource; - else if (ServerSlot >= MainCursor) // Cursor and Extended Corpse Inventory + else if (serverSlot >= MainCursor) // Cursor and Extended Corpse Inventory RoFSlot.MainSlot += 3; - else if (ServerSlot >= MainAmmo) // Ammo and Personl Inventory + else if (serverSlot >= MainAmmo) // Ammo and Personl Inventory RoFSlot.MainSlot += 1; /*else if (ServerSlot >= MainCursor) { // Cursor @@ -5640,33 +5640,33 @@ namespace RoF }*/ } - else if (ServerSlot >= EmuConstants::GENERAL_BAGS_BEGIN && ServerSlot <= EmuConstants::CURSOR_BAG_END) { - TempSlot = ServerSlot - 1; + else if (serverSlot >= EmuConstants::GENERAL_BAGS_BEGIN && serverSlot <= EmuConstants::CURSOR_BAG_END) { + TempSlot = serverSlot - 1; RoFSlot.MainSlot = int(TempSlot / EmuConstants::ITEM_CONTAINER_SIZE) - 2; RoFSlot.SubSlot = TempSlot - ((RoFSlot.MainSlot + 2) * EmuConstants::ITEM_CONTAINER_SIZE); } - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF Slots: Main %i, Sub %i, Aug %i, Unk1 %i", ServerSlot, RoFSlot.MainSlot, RoFSlot.SubSlot, RoFSlot.AugSlot, RoFSlot.Unknown01); + Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF Slots: Main %i, Sub %i, Aug %i, Unk1 %i", serverSlot, RoFSlot.MainSlot, RoFSlot.SubSlot, RoFSlot.AugSlot, RoFSlot.Unknown01); return RoFSlot; } - static inline uint32 ServerToRoFCorpseSlot(uint32 ServerCorpse) + static inline uint32 ServerToRoFCorpseSlot(uint32 serverCorpseSlot) { - return (ServerCorpse + 1); + return (serverCorpseSlot + 1); } - static inline uint32 RoFToServerSlot(structs::ItemSlotStruct RoFSlot) + static inline uint32 RoFToServerSlot(structs::ItemSlotStruct rofSlot) { uint32 ServerSlot = INVALID_INDEX; uint32 TempSlot = 0; - if (RoFSlot.SlotType == maps::MapPossessions && RoFSlot.MainSlot < 57) { // Worn/Personal Inventory and Cursor (< 51) - if (RoFSlot.MainSlot == slots::MainPowerSource) + if (rofSlot.SlotType == maps::MapPossessions && rofSlot.MainSlot < 57) { // Worn/Personal Inventory and Cursor (< 51) + if (rofSlot.MainSlot == slots::MainPowerSource) TempSlot = MainPowerSource; - else if (RoFSlot.MainSlot >= slots::MainCursor) // Cursor and Extended Corpse Inventory - TempSlot = RoFSlot.MainSlot - 3; + else if (rofSlot.MainSlot >= slots::MainCursor) // Cursor and Extended Corpse Inventory + TempSlot = rofSlot.MainSlot - 3; /*else if (RoFSlot.MainSlot == slots::MainGeneral9 || RoFSlot.MainSlot == slots::MainGeneral10) { // 9th and 10th RoF inventory/corpse slots // Need to figure out what to do when we get these @@ -5679,61 +5679,61 @@ namespace RoF // For now, it's probably best to leave as-is and let this work itself out in the inventory rework. }*/ - else if (RoFSlot.MainSlot >= slots::MainAmmo) // Ammo and Main Inventory - TempSlot = RoFSlot.MainSlot - 1; + else if (rofSlot.MainSlot >= slots::MainAmmo) // Ammo and Main Inventory + TempSlot = rofSlot.MainSlot - 1; else // Worn Slots - TempSlot = RoFSlot.MainSlot; + TempSlot = rofSlot.MainSlot; - if (RoFSlot.SubSlot >= SUB_BEGIN) // Bag Slots - TempSlot = ((TempSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + RoFSlot.SubSlot + 1; + if (rofSlot.SubSlot >= SUB_BEGIN) // Bag Slots + TempSlot = ((TempSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + rofSlot.SubSlot + 1; ServerSlot = TempSlot; } - else if (RoFSlot.SlotType == maps::MapBank) { + else if (rofSlot.SlotType == maps::MapBank) { TempSlot = EmuConstants::BANK_BEGIN; - if (RoFSlot.SubSlot >= SUB_BEGIN) - TempSlot += ((RoFSlot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + RoFSlot.SubSlot + 1; + if (rofSlot.SubSlot >= SUB_BEGIN) + TempSlot += ((rofSlot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + rofSlot.SubSlot + 1; else - TempSlot += RoFSlot.MainSlot; + TempSlot += rofSlot.MainSlot; ServerSlot = TempSlot; } - else if (RoFSlot.SlotType == maps::MapSharedBank) { + else if (rofSlot.SlotType == maps::MapSharedBank) { TempSlot = EmuConstants::SHARED_BANK_BEGIN; - if (RoFSlot.SubSlot >= SUB_BEGIN) - TempSlot += ((RoFSlot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + RoFSlot.SubSlot + 1; + if (rofSlot.SubSlot >= SUB_BEGIN) + TempSlot += ((rofSlot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + rofSlot.SubSlot + 1; else - TempSlot += RoFSlot.MainSlot; + TempSlot += rofSlot.MainSlot; ServerSlot = TempSlot; } - else if (RoFSlot.SlotType == maps::MapTrade) { + else if (rofSlot.SlotType == maps::MapTrade) { TempSlot = EmuConstants::TRADE_BEGIN; - if (RoFSlot.SubSlot >= SUB_BEGIN) - TempSlot += ((RoFSlot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + RoFSlot.SubSlot + 1; + if (rofSlot.SubSlot >= SUB_BEGIN) + TempSlot += ((rofSlot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + rofSlot.SubSlot + 1; // OLD CODE: //TempSlot += 100 + (RoFSlot.MainSlot * EmuConstants::ITEM_CONTAINER_SIZE) + RoFSlot.SubSlot; else - TempSlot += RoFSlot.MainSlot; + TempSlot += rofSlot.MainSlot; ServerSlot = TempSlot; } - else if (RoFSlot.SlotType == maps::MapWorld) { + else if (rofSlot.SlotType == maps::MapWorld) { TempSlot = EmuConstants::WORLD_BEGIN; - if (RoFSlot.MainSlot >= SUB_BEGIN) - TempSlot += RoFSlot.MainSlot; + if (rofSlot.MainSlot >= SUB_BEGIN) + TempSlot += rofSlot.MainSlot; ServerSlot = TempSlot; } @@ -5747,26 +5747,26 @@ namespace RoF ServerSlot = TempSlot; }*/ - else if (RoFSlot.SlotType == maps::MapGuildTribute) { + else if (rofSlot.SlotType == maps::MapGuildTribute) { ServerSlot = INVALID_INDEX; } - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert RoF Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", RoFSlot.SlotType, RoFSlot.Unknown02, RoFSlot.MainSlot, RoFSlot.SubSlot, RoFSlot.AugSlot, RoFSlot.Unknown01, ServerSlot); + Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert RoF Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", rofSlot.SlotType, rofSlot.Unknown02, rofSlot.MainSlot, rofSlot.SubSlot, rofSlot.AugSlot, rofSlot.Unknown01, ServerSlot); return ServerSlot; } - static inline uint32 RoFToServerMainInvSlot(structs::MainInvItemSlotStruct RoFSlot) + static inline uint32 RoFToServerMainInvSlot(structs::MainInvItemSlotStruct rofSlot) { uint32 ServerSlot = INVALID_INDEX; uint32 TempSlot = 0; - if (RoFSlot.MainSlot < 57) { // Worn/Personal Inventory and Cursor (< 33) - if (RoFSlot.MainSlot == slots::MainPowerSource) + if (rofSlot.MainSlot < 57) { // Worn/Personal Inventory and Cursor (< 33) + if (rofSlot.MainSlot == slots::MainPowerSource) TempSlot = MainPowerSource; - else if (RoFSlot.MainSlot >= slots::MainCursor) // Cursor and Extended Corpse Inventory - TempSlot = RoFSlot.MainSlot - 3; + else if (rofSlot.MainSlot >= slots::MainCursor) // Cursor and Extended Corpse Inventory + TempSlot = rofSlot.MainSlot - 3; /*else if (RoFSlot.MainSlot == slots::MainGeneral9 || RoFSlot.MainSlot == slots::MainGeneral10) { // 9th and 10th RoF inventory slots // Need to figure out what to do when we get these @@ -5774,26 +5774,26 @@ namespace RoF // Same as above }*/ - else if (RoFSlot.MainSlot >= slots::MainAmmo) // Main Inventory and Ammo Slots - TempSlot = RoFSlot.MainSlot - 1; + else if (rofSlot.MainSlot >= slots::MainAmmo) // Main Inventory and Ammo Slots + TempSlot = rofSlot.MainSlot - 1; else - TempSlot = RoFSlot.MainSlot; + TempSlot = rofSlot.MainSlot; - if (RoFSlot.SubSlot >= SUB_BEGIN) // Bag Slots - TempSlot = ((TempSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + RoFSlot.SubSlot + 1; + if (rofSlot.SubSlot >= SUB_BEGIN) // Bag Slots + TempSlot = ((TempSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + rofSlot.SubSlot + 1; ServerSlot = TempSlot; } - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert RoF Slots: Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", RoFSlot.MainSlot, RoFSlot.SubSlot, RoFSlot.AugSlot, RoFSlot.Unknown01, ServerSlot); + Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert RoF Slots: Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", rofSlot.MainSlot, rofSlot.SubSlot, rofSlot.AugSlot, rofSlot.Unknown01, ServerSlot); return ServerSlot; } - static inline uint32 RoFToServerCorpseSlot(uint32 RoFCorpse) + static inline uint32 RoFToServerCorpseSlot(uint32 rofCorpseSlot) { - return (RoFCorpse - 1); + return (rofCorpseSlot - 1); } static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink) diff --git a/common/patches/rof.h b/common/patches/rof.h index 328e5f7f1..4ac7d3532 100644 --- a/common/patches/rof.h +++ b/common/patches/rof.h @@ -1,5 +1,5 @@ -#ifndef RoF_H_ -#define RoF_H_ +#ifndef ROF_H_ +#define ROF_H_ #include "../struct_strategy.h" @@ -32,6 +32,4 @@ namespace RoF { }; - - -#endif /*RoF_H_*/ +#endif /*ROF_H_*/ diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 8c93cc4c7..6947ded15 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -25,14 +25,14 @@ namespace RoF2 char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth, ItemPacketType packet_type); // server to client inventory location converters - static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot, ItemPacketType PacketType = ItemPacketInvalid); - static inline structs::MainInvItemSlotStruct ServerToRoF2MainInvSlot(uint32 ServerSlot); - static inline uint32 ServerToRoF2CorpseSlot(uint32 ServerCorpse); + static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType = ItemPacketInvalid); + static inline structs::MainInvItemSlotStruct ServerToRoF2MainInvSlot(uint32 serverSlot); + static inline uint32 ServerToRoF2CorpseSlot(uint32 serverCorpseSlot); // client to server inventory location converters - static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot, ItemPacketType PacketType = ItemPacketInvalid); - static inline uint32 RoF2ToServerMainInvSlot(structs::MainInvItemSlotStruct RoF2Slot); - static inline uint32 RoF2ToServerCorpseSlot(uint32 RoF2Corpse); + static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct rof2Slot, ItemPacketType PacketType = ItemPacketInvalid); + static inline uint32 RoF2ToServerMainInvSlot(structs::MainInvItemSlotStruct rof2Slot); + static inline uint32 RoF2ToServerCorpseSlot(uint32 rof2CorpseSlot); // server to client text link converter static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink); @@ -4720,7 +4720,7 @@ namespace RoF2 DECODE_LENGTH_EXACT(structs::MoveItem_Struct); SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - Log.Out(Logs::General, Logs::Netcode, "[ERROR] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack); + Log.Out(Logs::General, Logs::Netcode, "[RoF2] MoveItem SlotType from %i to %i, MainSlot from %i to %i, SubSlot from %i to %i, AugSlot from %i to %i, Unknown01 from %i to %i, Number %u", eq->from_slot.SlotType, eq->to_slot.SlotType, eq->from_slot.MainSlot, eq->to_slot.MainSlot, eq->from_slot.SubSlot, eq->to_slot.SubSlot, eq->from_slot.AugSlot, eq->to_slot.AugSlot, eq->from_slot.Unknown01, eq->to_slot.Unknown01, eq->number_in_stack); emu->from_slot = RoF2ToServerSlot(eq->from_slot); emu->to_slot = RoF2ToServerSlot(eq->to_slot); IN(number_in_stack); @@ -5069,7 +5069,7 @@ namespace RoF2 hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0; hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot; hdr.unknown028 = 0; - hdr.last_cast_time = ((item->RecastDelay > 1) ? 1212693140 : 0); + hdr.last_cast_time = inst->GetRecastTimestamp(); hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges); hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0; hdr.unknown044 = 0; @@ -5589,7 +5589,7 @@ namespace RoF2 return item_serial; } - static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 ServerSlot, ItemPacketType PacketType) + static inline structs::ItemSlotStruct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType) { structs::ItemSlotStruct RoF2Slot; RoF2Slot.SlotType = INVALID_INDEX; @@ -5601,25 +5601,25 @@ namespace RoF2 uint32 TempSlot = 0; - if (ServerSlot < 56 || ServerSlot == MainPowerSource) { // Main Inventory and Cursor + if (serverSlot < 56 || serverSlot == MainPowerSource) { // Main Inventory and Cursor if (PacketType == ItemPacketLoot) { RoF2Slot.SlotType = maps::MapCorpse; - RoF2Slot.MainSlot = ServerSlot - EmuConstants::CORPSE_BEGIN; + RoF2Slot.MainSlot = serverSlot - EmuConstants::CORPSE_BEGIN; } else { RoF2Slot.SlotType = maps::MapPossessions; - RoF2Slot.MainSlot = ServerSlot; + RoF2Slot.MainSlot = serverSlot; } - if (ServerSlot == MainPowerSource) + if (serverSlot == MainPowerSource) RoF2Slot.MainSlot = slots::MainPowerSource; - else if (ServerSlot >= MainCursor && PacketType != ItemPacketLoot) // Cursor and Extended Corpse Inventory + else if (serverSlot >= MainCursor && PacketType != ItemPacketLoot) // Cursor and Extended Corpse Inventory RoF2Slot.MainSlot += 3; - else if (ServerSlot >= MainAmmo) // (> 20) + else if (serverSlot >= MainAmmo) // (> 20) RoF2Slot.MainSlot += 1; } @@ -5628,9 +5628,9 @@ namespace RoF2 RoF2Slot.MainSlot = ServerSlot - 31; }*/ - else if (ServerSlot >= EmuConstants::GENERAL_BAGS_BEGIN && ServerSlot <= EmuConstants::CURSOR_BAG_END) { // (> 250 && < 341) + else if (serverSlot >= EmuConstants::GENERAL_BAGS_BEGIN && serverSlot <= EmuConstants::CURSOR_BAG_END) { // (> 250 && < 341) RoF2Slot.SlotType = maps::MapPossessions; - TempSlot = ServerSlot - 1; + TempSlot = serverSlot - 1; RoF2Slot.MainSlot = int(TempSlot / EmuConstants::ITEM_CONTAINER_SIZE) - 2; RoF2Slot.SubSlot = TempSlot - ((RoF2Slot.MainSlot + 2) * EmuConstants::ITEM_CONTAINER_SIZE); @@ -5638,14 +5638,14 @@ namespace RoF2 RoF2Slot.MainSlot = slots::MainCursor; } - else if (ServerSlot >= EmuConstants::TRIBUTE_BEGIN && ServerSlot <= EmuConstants::TRIBUTE_END) { // Tribute + else if (serverSlot >= EmuConstants::TRIBUTE_BEGIN && serverSlot <= EmuConstants::TRIBUTE_END) { // Tribute RoF2Slot.SlotType = maps::MapTribute; - RoF2Slot.MainSlot = ServerSlot - EmuConstants::TRIBUTE_BEGIN; + RoF2Slot.MainSlot = serverSlot - EmuConstants::TRIBUTE_BEGIN; } - else if (ServerSlot >= EmuConstants::BANK_BEGIN && ServerSlot <= EmuConstants::BANK_BAGS_END) { + else if (serverSlot >= EmuConstants::BANK_BEGIN && serverSlot <= EmuConstants::BANK_BAGS_END) { RoF2Slot.SlotType = maps::MapBank; - TempSlot = ServerSlot - EmuConstants::BANK_BEGIN; + TempSlot = serverSlot - EmuConstants::BANK_BEGIN; RoF2Slot.MainSlot = TempSlot; if (TempSlot > 30) { // (> 30) @@ -5654,9 +5654,9 @@ namespace RoF2 } } - else if (ServerSlot >= EmuConstants::SHARED_BANK_BEGIN && ServerSlot <= EmuConstants::SHARED_BANK_BAGS_END) { + else if (serverSlot >= EmuConstants::SHARED_BANK_BEGIN && serverSlot <= EmuConstants::SHARED_BANK_BAGS_END) { RoF2Slot.SlotType = maps::MapSharedBank; - TempSlot = ServerSlot - EmuConstants::SHARED_BANK_BEGIN; + TempSlot = serverSlot - EmuConstants::SHARED_BANK_BEGIN; RoF2Slot.MainSlot = TempSlot; if (TempSlot > 30) { // (> 30) @@ -5665,9 +5665,9 @@ namespace RoF2 } } - else if (ServerSlot >= EmuConstants::TRADE_BEGIN && ServerSlot <= EmuConstants::TRADE_BAGS_END) { + else if (serverSlot >= EmuConstants::TRADE_BEGIN && serverSlot <= EmuConstants::TRADE_BAGS_END) { RoF2Slot.SlotType = maps::MapTrade; - TempSlot = ServerSlot - EmuConstants::TRADE_BEGIN; + TempSlot = serverSlot - EmuConstants::TRADE_BEGIN; RoF2Slot.MainSlot = TempSlot; if (TempSlot > 30) { @@ -5689,18 +5689,18 @@ namespace RoF2 */ } - else if (ServerSlot >= EmuConstants::WORLD_BEGIN && ServerSlot <= EmuConstants::WORLD_END) { + else if (serverSlot >= EmuConstants::WORLD_BEGIN && serverSlot <= EmuConstants::WORLD_END) { RoF2Slot.SlotType = maps::MapWorld; - TempSlot = ServerSlot - EmuConstants::WORLD_BEGIN; + TempSlot = serverSlot - EmuConstants::WORLD_BEGIN; RoF2Slot.MainSlot = TempSlot; } - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF2 Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i", ServerSlot, RoF2Slot.SlotType, RoF2Slot.Unknown02, RoF2Slot.MainSlot, RoF2Slot.SubSlot, RoF2Slot.AugSlot, RoF2Slot.Unknown01); + Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF2 Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i", serverSlot, RoF2Slot.SlotType, RoF2Slot.Unknown02, RoF2Slot.MainSlot, RoF2Slot.SubSlot, RoF2Slot.AugSlot, RoF2Slot.Unknown01); return RoF2Slot; } - static inline structs::MainInvItemSlotStruct ServerToRoF2MainInvSlot(uint32 ServerSlot) + static inline structs::MainInvItemSlotStruct ServerToRoF2MainInvSlot(uint32 serverSlot) { structs::MainInvItemSlotStruct RoF2Slot; RoF2Slot.MainSlot = INVALID_INDEX; @@ -5710,16 +5710,16 @@ namespace RoF2 uint32 TempSlot = 0; - if (ServerSlot < 56 || ServerSlot == MainPowerSource) { // (< 52) - RoF2Slot.MainSlot = ServerSlot; + if (serverSlot < 56 || serverSlot == MainPowerSource) { // (< 52) + RoF2Slot.MainSlot = serverSlot; - if (ServerSlot == MainPowerSource) + if (serverSlot == MainPowerSource) RoF2Slot.MainSlot = slots::MainPowerSource; - else if (ServerSlot >= MainCursor) // Cursor and Extended Corpse Inventory + else if (serverSlot >= MainCursor) // Cursor and Extended Corpse Inventory RoF2Slot.MainSlot += 3; - else if (ServerSlot >= MainAmmo) // Ammo and Personl Inventory + else if (serverSlot >= MainAmmo) // Ammo and Personl Inventory RoF2Slot.MainSlot += 1; /*else if (ServerSlot >= MainCursor) { // Cursor @@ -5730,33 +5730,33 @@ namespace RoF2 }*/ } - else if (ServerSlot >= EmuConstants::GENERAL_BAGS_BEGIN && ServerSlot <= EmuConstants::CURSOR_BAG_END) { - TempSlot = ServerSlot - 1; + else if (serverSlot >= EmuConstants::GENERAL_BAGS_BEGIN && serverSlot <= EmuConstants::CURSOR_BAG_END) { + TempSlot = serverSlot - 1; RoF2Slot.MainSlot = int(TempSlot / EmuConstants::ITEM_CONTAINER_SIZE) - 2; RoF2Slot.SubSlot = TempSlot - ((RoF2Slot.MainSlot + 2) * EmuConstants::ITEM_CONTAINER_SIZE); } - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF2 Slots: Main %i, Sub %i, Aug %i, Unk1 %i", ServerSlot, RoF2Slot.MainSlot, RoF2Slot.SubSlot, RoF2Slot.AugSlot, RoF2Slot.Unknown01); + Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF2 Slots: Main %i, Sub %i, Aug %i, Unk1 %i", serverSlot, RoF2Slot.MainSlot, RoF2Slot.SubSlot, RoF2Slot.AugSlot, RoF2Slot.Unknown01); return RoF2Slot; } - static inline uint32 ServerToRoF2CorpseSlot(uint32 ServerCorpse) + static inline uint32 ServerToRoF2CorpseSlot(uint32 serverCorpseSlot) { - return (ServerCorpse - EmuConstants::CORPSE_BEGIN + 1); + return (serverCorpseSlot - EmuConstants::CORPSE_BEGIN + 1); } - static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct RoF2Slot, ItemPacketType PacketType) + static inline uint32 RoF2ToServerSlot(structs::ItemSlotStruct rof2Slot, ItemPacketType PacketType) { uint32 ServerSlot = INVALID_INDEX; uint32 TempSlot = 0; - if (RoF2Slot.SlotType == maps::MapPossessions && RoF2Slot.MainSlot < 57) { // Worn/Personal Inventory and Cursor (< 51) - if (RoF2Slot.MainSlot == slots::MainPowerSource) + if (rof2Slot.SlotType == maps::MapPossessions && rof2Slot.MainSlot < 57) { // Worn/Personal Inventory and Cursor (< 51) + if (rof2Slot.MainSlot == slots::MainPowerSource) TempSlot = MainPowerSource; - else if (RoF2Slot.MainSlot >= slots::MainCursor) // Cursor and Extended Corpse Inventory - TempSlot = RoF2Slot.MainSlot - 3; + else if (rof2Slot.MainSlot >= slots::MainCursor) // Cursor and Extended Corpse Inventory + TempSlot = rof2Slot.MainSlot - 3; /*else if (RoF2Slot.MainSlot == slots::MainGeneral9 || RoF2Slot.MainSlot == slots::MainGeneral10) { // 9th and 10th RoF2 inventory/corpse slots // Need to figure out what to do when we get these @@ -5769,61 +5769,61 @@ namespace RoF2 // For now, it's probably best to leave as-is and let this work itself out in the inventory rework. }*/ - else if (RoF2Slot.MainSlot >= slots::MainAmmo) // Ammo and Main Inventory - TempSlot = RoF2Slot.MainSlot - 1; + else if (rof2Slot.MainSlot >= slots::MainAmmo) // Ammo and Main Inventory + TempSlot = rof2Slot.MainSlot - 1; else // Worn Slots - TempSlot = RoF2Slot.MainSlot; + TempSlot = rof2Slot.MainSlot; - if (RoF2Slot.SubSlot >= SUB_BEGIN) // Bag Slots - TempSlot = ((TempSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + RoF2Slot.SubSlot + 1; + if (rof2Slot.SubSlot >= SUB_BEGIN) // Bag Slots + TempSlot = ((TempSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + rof2Slot.SubSlot + 1; ServerSlot = TempSlot; } - else if (RoF2Slot.SlotType == maps::MapBank) { + else if (rof2Slot.SlotType == maps::MapBank) { TempSlot = EmuConstants::BANK_BEGIN; - if (RoF2Slot.SubSlot >= SUB_BEGIN) - TempSlot += ((RoF2Slot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + RoF2Slot.SubSlot + 1; + if (rof2Slot.SubSlot >= SUB_BEGIN) + TempSlot += ((rof2Slot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + rof2Slot.SubSlot + 1; else - TempSlot += RoF2Slot.MainSlot; + TempSlot += rof2Slot.MainSlot; ServerSlot = TempSlot; } - else if (RoF2Slot.SlotType == maps::MapSharedBank) { + else if (rof2Slot.SlotType == maps::MapSharedBank) { TempSlot = EmuConstants::SHARED_BANK_BEGIN; - if (RoF2Slot.SubSlot >= SUB_BEGIN) - TempSlot += ((RoF2Slot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + RoF2Slot.SubSlot + 1; + if (rof2Slot.SubSlot >= SUB_BEGIN) + TempSlot += ((rof2Slot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + rof2Slot.SubSlot + 1; else - TempSlot += RoF2Slot.MainSlot; + TempSlot += rof2Slot.MainSlot; ServerSlot = TempSlot; } - else if (RoF2Slot.SlotType == maps::MapTrade) { + else if (rof2Slot.SlotType == maps::MapTrade) { TempSlot = EmuConstants::TRADE_BEGIN; - if (RoF2Slot.SubSlot >= SUB_BEGIN) - TempSlot += ((RoF2Slot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + RoF2Slot.SubSlot + 1; + if (rof2Slot.SubSlot >= SUB_BEGIN) + TempSlot += ((rof2Slot.MainSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + rof2Slot.SubSlot + 1; // OLD CODE: //TempSlot += 100 + (RoF2Slot.MainSlot * EmuConstants::ITEM_CONTAINER_SIZE) + RoF2Slot.SubSlot; else - TempSlot += RoF2Slot.MainSlot; + TempSlot += rof2Slot.MainSlot; ServerSlot = TempSlot; } - else if (RoF2Slot.SlotType == maps::MapWorld) { + else if (rof2Slot.SlotType == maps::MapWorld) { TempSlot = EmuConstants::WORLD_BEGIN; - if (RoF2Slot.MainSlot >= SUB_BEGIN) - TempSlot += RoF2Slot.MainSlot; + if (rof2Slot.MainSlot >= SUB_BEGIN) + TempSlot += rof2Slot.MainSlot; ServerSlot = TempSlot; } @@ -5837,30 +5837,30 @@ namespace RoF2 ServerSlot = TempSlot; }*/ - else if (RoF2Slot.SlotType == maps::MapGuildTribute) { + else if (rof2Slot.SlotType == maps::MapGuildTribute) { ServerSlot = INVALID_INDEX; } - else if (RoF2Slot.SlotType == maps::MapCorpse) { - ServerSlot = RoF2Slot.MainSlot + EmuConstants::CORPSE_BEGIN; + else if (rof2Slot.SlotType == maps::MapCorpse) { + ServerSlot = rof2Slot.MainSlot + EmuConstants::CORPSE_BEGIN; } - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert RoF2 Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", RoF2Slot.SlotType, RoF2Slot.Unknown02, RoF2Slot.MainSlot, RoF2Slot.SubSlot, RoF2Slot.AugSlot, RoF2Slot.Unknown01, ServerSlot); + Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert RoF2 Slots: Type %i, Unk2 %i, Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", rof2Slot.SlotType, rof2Slot.Unknown02, rof2Slot.MainSlot, rof2Slot.SubSlot, rof2Slot.AugSlot, rof2Slot.Unknown01, ServerSlot); return ServerSlot; } - static inline uint32 RoF2ToServerMainInvSlot(structs::MainInvItemSlotStruct RoF2Slot) + static inline uint32 RoF2ToServerMainInvSlot(structs::MainInvItemSlotStruct rof2Slot) { uint32 ServerSlot = INVALID_INDEX; uint32 TempSlot = 0; - if (RoF2Slot.MainSlot < 57) { // Worn/Personal Inventory and Cursor (< 33) - if (RoF2Slot.MainSlot == slots::MainPowerSource) + if (rof2Slot.MainSlot < 57) { // Worn/Personal Inventory and Cursor (< 33) + if (rof2Slot.MainSlot == slots::MainPowerSource) TempSlot = MainPowerSource; - else if (RoF2Slot.MainSlot >= slots::MainCursor) // Cursor and Extended Corpse Inventory - TempSlot = RoF2Slot.MainSlot - 3; + else if (rof2Slot.MainSlot >= slots::MainCursor) // Cursor and Extended Corpse Inventory + TempSlot = rof2Slot.MainSlot - 3; /*else if (RoF2Slot.MainSlot == slots::MainGeneral9 || RoF2Slot.MainSlot == slots::MainGeneral10) { // 9th and 10th RoF2 inventory slots // Need to figure out what to do when we get these @@ -5868,26 +5868,26 @@ namespace RoF2 // Same as above }*/ - else if (RoF2Slot.MainSlot >= slots::MainAmmo) // Main Inventory and Ammo Slots - TempSlot = RoF2Slot.MainSlot - 1; + else if (rof2Slot.MainSlot >= slots::MainAmmo) // Main Inventory and Ammo Slots + TempSlot = rof2Slot.MainSlot - 1; else - TempSlot = RoF2Slot.MainSlot; + TempSlot = rof2Slot.MainSlot; - if (RoF2Slot.SubSlot >= SUB_BEGIN) // Bag Slots - TempSlot = ((TempSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + RoF2Slot.SubSlot + 1; + if (rof2Slot.SubSlot >= SUB_BEGIN) // Bag Slots + TempSlot = ((TempSlot + 3) * EmuConstants::ITEM_CONTAINER_SIZE) + rof2Slot.SubSlot + 1; ServerSlot = TempSlot; } - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert RoF2 Slots: Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", RoF2Slot.MainSlot, RoF2Slot.SubSlot, RoF2Slot.AugSlot, RoF2Slot.Unknown01, ServerSlot); + Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert RoF2 Slots: Main %i, Sub %i, Aug %i, Unk1 %i to Server Slot %i", rof2Slot.MainSlot, rof2Slot.SubSlot, rof2Slot.AugSlot, rof2Slot.Unknown01, ServerSlot); return ServerSlot; } - static inline uint32 RoF2ToServerCorpseSlot(uint32 RoF2Corpse) + static inline uint32 RoF2ToServerCorpseSlot(uint32 rof2CorpseSlot) { - return (RoF2Corpse + EmuConstants::CORPSE_BEGIN - 1); + return (rof2CorpseSlot + EmuConstants::CORPSE_BEGIN - 1); } static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink) diff --git a/common/patches/rof2.h b/common/patches/rof2.h index 888fb3308..8644473db 100644 --- a/common/patches/rof2.h +++ b/common/patches/rof2.h @@ -1,5 +1,5 @@ -#ifndef RoF2_H_ -#define RoF2_H_ +#ifndef ROF2_H_ +#define ROF2_H_ #include "../struct_strategy.h" @@ -32,6 +32,4 @@ namespace RoF2 { }; - - -#endif /*RoF2_H_*/ +#endif /*ROF2_H_*/ diff --git a/common/patches/rof2_constants.h b/common/patches/rof2_constants.h index b4cbb15e0..ca59511a1 100644 --- a/common/patches/rof2_constants.h +++ b/common/patches/rof2_constants.h @@ -19,8 +19,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef RoF2_CONSTANTS_H_ -#define RoF2_CONSTANTS_H_ +#ifndef ROF2_CONSTANTS_H_ +#define ROF2_CONSTANTS_H_ #include "../types.h" @@ -193,7 +193,7 @@ namespace RoF2 { }; //end namespace RoF2 -#endif /*RoF2_CONSTANTS_H_*/ +#endif /*ROF2_CONSTANTS_H_*/ /* RoF2 Notes: diff --git a/common/patches/rof2_itemfields.h b/common/patches/rof2_itemfields.h index b7b2223d3..0a3211898 100644 --- a/common/patches/rof2_itemfields.h +++ b/common/patches/rof2_itemfields.h @@ -439,4 +439,3 @@ These fields must be in the order of how they are serialized! #undef C #undef S #undef F - diff --git a/common/patches/rof2_ops.h b/common/patches/rof2_ops.h index c2a1bb5e6..aa5656f2b 100644 --- a/common/patches/rof2_ops.h +++ b/common/patches/rof2_ops.h @@ -174,5 +174,6 @@ D(OP_WhoAllRequest) D(OP_ZoneChange) D(OP_ZoneEntry) // End RoF Encodes/Decodes + #undef E #undef D diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index baf067bbf..dd9bfb587 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -1,5 +1,5 @@ -#ifndef RoF2_STRUCTS_H_ -#define RoF2_STRUCTS_H_ +#ifndef ROF2_STRUCTS_H_ +#define ROF2_STRUCTS_H_ namespace RoF2 { namespace structs { @@ -1394,7 +1394,7 @@ struct Animation_Struct { /*04*/ }; -// solar: this is what causes the caster to animate and the target to +// this is what causes the caster to animate and the target to // get the particle effects around them when a spell is cast // also causes a buff icon struct Action_Struct @@ -1445,7 +1445,7 @@ struct ActionAlt_Struct /*56*/ }; -// solar: this is what prints the You have been struck. and the regular +// this is what prints the You have been struck. and the regular // melee messages like You try to pierce, etc. It's basically the melee // and spell damage message struct CombatDamage_Struct @@ -1997,7 +1997,7 @@ struct RandomReq_Struct { uint32 high; }; -/* solar: 9/23/03 reply to /random command; struct from Zaphod */ +/* 9/23/03 reply to /random command */ struct RandomReply_Struct { /* 00 */ uint32 low; /* 04 */ uint32 high; @@ -4881,4 +4881,4 @@ struct MercenaryMerchantResponse_Struct { }; //end namespace structs }; //end namespace RoF2 -#endif /*RoF2_STRUCTS_H_*/ +#endif /*ROF2_STRUCTS_H_*/ diff --git a/common/patches/rof_constants.h b/common/patches/rof_constants.h index 233a1b36c..92c019bad 100644 --- a/common/patches/rof_constants.h +++ b/common/patches/rof_constants.h @@ -19,8 +19,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef RoF_CONSTANTS_H_ -#define RoF_CONSTANTS_H_ +#ifndef ROF_CONSTANTS_H_ +#define ROF_CONSTANTS_H_ #include "../types.h" @@ -192,7 +192,7 @@ namespace RoF { }; //end namespace RoF -#endif /*RoF_CONSTANTS_H_*/ +#endif /*ROF_CONSTANTS_H_*/ /* RoF Notes: diff --git a/common/patches/rof_itemfields.h b/common/patches/rof_itemfields.h index b7b2223d3..0a3211898 100644 --- a/common/patches/rof_itemfields.h +++ b/common/patches/rof_itemfields.h @@ -439,4 +439,3 @@ These fields must be in the order of how they are serialized! #undef C #undef S #undef F - diff --git a/common/patches/rof_ops.h b/common/patches/rof_ops.h index ce994ea11..8c55cd857 100644 --- a/common/patches/rof_ops.h +++ b/common/patches/rof_ops.h @@ -162,5 +162,6 @@ D(OP_TributeItem) D(OP_WhoAllRequest) D(OP_ZoneChange) D(OP_ZoneEntry) + #undef E #undef D diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index fb2f09615..eb531e4d5 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -1,5 +1,5 @@ -#ifndef RoF_STRUCTS_H_ -#define RoF_STRUCTS_H_ +#ifndef ROF_STRUCTS_H_ +#define ROF_STRUCTS_H_ namespace RoF { namespace structs { @@ -1425,7 +1425,7 @@ struct Animation_Struct { /*04*/ }; -// solar: this is what causes the caster to animate and the target to +// this is what causes the caster to animate and the target to // get the particle effects around them when a spell is cast // also causes a buff icon struct Action_Struct @@ -1476,7 +1476,7 @@ struct ActionAlt_Struct /*56*/ }; -// solar: this is what prints the You have been struck. and the regular +// this is what prints the You have been struck. and the regular // melee messages like You try to pierce, etc. It's basically the melee // and spell damage message struct CombatDamage_Struct @@ -2028,7 +2028,7 @@ struct RandomReq_Struct { uint32 high; }; -/* solar: 9/23/03 reply to /random command; struct from Zaphod */ +/* 9/23/03 reply to /random command */ struct RandomReply_Struct { /* 00 */ uint32 low; /* 04 */ uint32 high; @@ -4897,4 +4897,4 @@ struct MercenaryMerchantResponse_Struct { }; //end namespace structs }; //end namespace RoF -#endif /*RoF_STRUCTS_H_*/ +#endif /*ROF_STRUCTS_H_*/ diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index 7a67e56c3..98f7faccd 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -26,11 +26,11 @@ namespace SoD // server to client inventory location converters static inline uint32 ServerToSoDSlot(uint32 ServerSlot); - static inline uint32 ServerToSoDCorpseSlot(uint32 ServerCorpse); + static inline uint32 ServerToSoDCorpseSlot(uint32 serverCorpseSlot); // client to server inventory location converters - static inline uint32 SoDToServerSlot(uint32 SoDSlot); - static inline uint32 SoDToServerCorpseSlot(uint32 SoDCorpse); + static inline uint32 SoDToServerSlot(uint32 sodSlot); + static inline uint32 SoDToServerCorpseSlot(uint32 sodCorpseSlot); // server to client text link converter static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink); @@ -3242,7 +3242,7 @@ namespace SoD DECODE_LENGTH_EXACT(structs::MoveItem_Struct); SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot, eq->to_slot); + Log.Out(Logs::General, Logs::Netcode, "[SoD] Moved item from %u to %u", eq->from_slot, eq->to_slot); emu->from_slot = SoDToServerSlot(eq->from_slot); emu->to_slot = SoDToServerSlot(eq->to_slot); @@ -3548,7 +3548,7 @@ namespace SoD hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0; hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot; hdr.unknown028 = 0; - hdr.last_cast_time = ((item->RecastDelay > 1) ? 1212693140 : 0); + hdr.last_cast_time = inst->GetRecastTimestamp(); hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges); hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0; hdr.unknown044 = 0; @@ -3961,54 +3961,54 @@ namespace SoD return item_serial; } - static inline uint32 ServerToSoDSlot(uint32 ServerSlot) + static inline uint32 ServerToSoDSlot(uint32 serverSlot) { uint32 SoDSlot = 0; - if (ServerSlot >= MainAmmo && ServerSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots - SoDSlot = ServerSlot + 1; - else if (ServerSlot >= EmuConstants::GENERAL_BAGS_BEGIN && ServerSlot <= EmuConstants::CURSOR_BAG_END) - SoDSlot = ServerSlot + 11; - else if (ServerSlot >= EmuConstants::BANK_BAGS_BEGIN && ServerSlot <= EmuConstants::BANK_BAGS_END) - SoDSlot = ServerSlot + 1; - else if (ServerSlot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && ServerSlot <= EmuConstants::SHARED_BANK_BAGS_END) - SoDSlot = ServerSlot + 1; - else if (ServerSlot == MainPowerSource) + if (serverSlot >= MainAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots + SoDSlot = serverSlot + 1; + else if (serverSlot >= EmuConstants::GENERAL_BAGS_BEGIN && serverSlot <= EmuConstants::CURSOR_BAG_END) + SoDSlot = serverSlot + 11; + else if (serverSlot >= EmuConstants::BANK_BAGS_BEGIN && serverSlot <= EmuConstants::BANK_BAGS_END) + SoDSlot = serverSlot + 1; + else if (serverSlot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && serverSlot <= EmuConstants::SHARED_BANK_BAGS_END) + SoDSlot = serverSlot + 1; + else if (serverSlot == MainPowerSource) SoDSlot = slots::MainPowerSource; else - SoDSlot = ServerSlot; + SoDSlot = serverSlot; return SoDSlot; } - static inline uint32 ServerToSoDCorpseSlot(uint32 ServerCorpse) + static inline uint32 ServerToSoDCorpseSlot(uint32 serverCorpseSlot) { //uint32 SoDCorpse; - return (ServerCorpse + 1); + return (serverCorpseSlot + 1); } - static inline uint32 SoDToServerSlot(uint32 SoDSlot) + static inline uint32 SoDToServerSlot(uint32 sodSlot) { uint32 ServerSlot = 0; - if (SoDSlot >= slots::MainAmmo && SoDSlot <= consts::CORPSE_END) // Cursor/Ammo/Power Source and Normal Inventory Slots - ServerSlot = SoDSlot - 1; - else if (SoDSlot >= consts::GENERAL_BAGS_BEGIN && SoDSlot <= consts::CURSOR_BAG_END) - ServerSlot = SoDSlot - 11; - else if (SoDSlot >= consts::BANK_BAGS_BEGIN && SoDSlot <= consts::BANK_BAGS_END) - ServerSlot = SoDSlot - 1; - else if (SoDSlot >= consts::SHARED_BANK_BAGS_BEGIN && SoDSlot <= consts::SHARED_BANK_BAGS_END) - ServerSlot = SoDSlot - 1; - else if (SoDSlot == slots::MainPowerSource) + if (sodSlot >= slots::MainAmmo && sodSlot <= consts::CORPSE_END) // Cursor/Ammo/Power Source and Normal Inventory Slots + ServerSlot = sodSlot - 1; + else if (sodSlot >= consts::GENERAL_BAGS_BEGIN && sodSlot <= consts::CURSOR_BAG_END) + ServerSlot = sodSlot - 11; + else if (sodSlot >= consts::BANK_BAGS_BEGIN && sodSlot <= consts::BANK_BAGS_END) + ServerSlot = sodSlot - 1; + else if (sodSlot >= consts::SHARED_BANK_BAGS_BEGIN && sodSlot <= consts::SHARED_BANK_BAGS_END) + ServerSlot = sodSlot - 1; + else if (sodSlot == slots::MainPowerSource) ServerSlot = MainPowerSource; else - ServerSlot = SoDSlot; + ServerSlot = sodSlot; return ServerSlot; } - static inline uint32 SoDToServerCorpseSlot(uint32 SoDCorpse) + static inline uint32 SoDToServerCorpseSlot(uint32 sodCorpseSlot) { //uint32 ServerCorpse; - return (SoDCorpse - 1); + return (sodCorpseSlot - 1); } static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink) diff --git a/common/patches/sod.h b/common/patches/sod.h index 9935cbf2f..65d7f951a 100644 --- a/common/patches/sod.h +++ b/common/patches/sod.h @@ -1,5 +1,5 @@ -#ifndef SoD_H_ -#define SoD_H_ +#ifndef SOD_H_ +#define SOD_H_ #include "../struct_strategy.h" @@ -32,6 +32,4 @@ namespace SoD { }; - - -#endif /*SoD_H_*/ +#endif /*SOD_H_*/ diff --git a/common/patches/sod_constants.h b/common/patches/sod_constants.h index 89749fd56..7731d1d1f 100644 --- a/common/patches/sod_constants.h +++ b/common/patches/sod_constants.h @@ -19,8 +19,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef SoD_CONSTANTS_H_ -#define SoD_CONSTANTS_H_ +#ifndef SOD_CONSTANTS_H_ +#define SOD_CONSTANTS_H_ #include "../types.h" @@ -189,7 +189,7 @@ namespace SoD { }; //end namespace SoD -#endif /*SoD_CONSTANTS_H_*/ +#endif /*SOD_CONSTANTS_H_*/ /* SoD Notes: diff --git a/common/patches/sod_itemfields.h b/common/patches/sod_itemfields.h index ccba333b5..5f8c09354 100644 --- a/common/patches/sod_itemfields.h +++ b/common/patches/sod_itemfields.h @@ -436,4 +436,3 @@ These fields must be in the order of how they are serialized! #undef C #undef S #undef F - diff --git a/common/patches/sod_ops.h b/common/patches/sod_ops.h index 3ce2ac2cb..f599885c1 100644 --- a/common/patches/sod_ops.h +++ b/common/patches/sod_ops.h @@ -120,5 +120,6 @@ D(OP_TradeSkillCombine) D(OP_TributeItem) D(OP_WearChange) D(OP_WhoAllRequest) + #undef E #undef D diff --git a/common/patches/sod_structs.h b/common/patches/sod_structs.h index 24ed9c7cc..810c59b1e 100644 --- a/common/patches/sod_structs.h +++ b/common/patches/sod_structs.h @@ -1,5 +1,5 @@ -#ifndef SoD_STRUCTS_H_ -#define SoD_STRUCTS_H_ +#ifndef SOD_STRUCTS_H_ +#define SOD_STRUCTS_H_ namespace SoD { namespace structs { @@ -538,7 +538,7 @@ struct SpawnAppearance_Struct }; -// solar: this is used inside profile +// this is used inside profile struct SpellBuff_Struct { /*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise @@ -1196,7 +1196,7 @@ struct Animation_Struct { /*04*/ }; -// solar: this is what causes the caster to animate and the target to +// this is what causes the caster to animate and the target to // get the particle effects around them when a spell is cast // also causes a buff icon struct Action_Struct @@ -1248,7 +1248,7 @@ struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes /*0056*/ }; -// solar: this is what prints the You have been struck. and the regular +// this is what prints the You have been struck. and the regular // melee messages like You try to pierce, etc. It's basically the melee // and spell damage message struct CombatDamage_Struct @@ -1791,7 +1791,7 @@ struct RandomReq_Struct { uint32 high; }; -/* solar: 9/23/03 reply to /random command; struct from Zaphod */ +/* 9/23/03 reply to /random command */ struct RandomReply_Struct { /* 00 */ uint32 low; /* 04 */ uint32 high; @@ -4412,4 +4412,4 @@ struct MercenaryAssign_Struct { }; //end namespace structs }; //end namespace SoD -#endif /*SoD_STRUCTS_H_*/ +#endif /*SOD_STRUCTS_H_*/ diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index 094023317..b8a84d993 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -25,12 +25,12 @@ namespace SoF char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth); // server to client inventory location converters - static inline uint32 ServerToSoFSlot(uint32 ServerSlot); - static inline uint32 ServerToSoFCorpseSlot(uint32 ServerCorpse); + static inline uint32 ServerToSoFSlot(uint32 serverSlot); + static inline uint32 ServerToSoFCorpseSlot(uint32 serverCorpseSlot); // client to server inventory location converters - static inline uint32 SoFToServerSlot(uint32 SoFSlot); - static inline uint32 SoFToServerCorpseSlot(uint32 SoFCorpse); + static inline uint32 SoFToServerSlot(uint32 sofSlot); + static inline uint32 SoFToServerCorpseSlot(uint32 sofCorpseSlot); // server to client text link converter static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink); @@ -2580,7 +2580,7 @@ namespace SoF DECODE_LENGTH_EXACT(structs::MoveItem_Struct); SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot, eq->to_slot); + Log.Out(Logs::General, Logs::Netcode, "[SoF] Moved item from %u to %u", eq->from_slot, eq->to_slot); emu->from_slot = SoFToServerSlot(eq->from_slot); emu->to_slot = SoFToServerSlot(eq->to_slot); @@ -2872,7 +2872,7 @@ namespace SoF hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0; hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot; hdr.unknown028 = 0; - hdr.last_cast_time = ((item->RecastDelay > 1) ? 1212693140 : 0); + hdr.last_cast_time = inst->GetRecastTimestamp(); hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges); hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0; hdr.unknown044 = 0; @@ -3281,56 +3281,56 @@ namespace SoF return item_serial; } - static inline uint32 ServerToSoFSlot(uint32 ServerSlot) + static inline uint32 ServerToSoFSlot(uint32 serverSlot) { uint32 SoFSlot = 0; - if (ServerSlot >= MainAmmo && ServerSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots - SoFSlot = ServerSlot + 1; - else if (ServerSlot >= EmuConstants::GENERAL_BAGS_BEGIN && ServerSlot <= EmuConstants::CURSOR_BAG_END) - SoFSlot = ServerSlot + 11; - else if (ServerSlot >= EmuConstants::BANK_BAGS_BEGIN && ServerSlot <= EmuConstants::BANK_BAGS_END) - SoFSlot = ServerSlot + 1; - else if (ServerSlot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && ServerSlot <= EmuConstants::SHARED_BANK_BAGS_END) - SoFSlot = ServerSlot + 1; - else if (ServerSlot == MainPowerSource) + if (serverSlot >= MainAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots + SoFSlot = serverSlot + 1; + else if (serverSlot >= EmuConstants::GENERAL_BAGS_BEGIN && serverSlot <= EmuConstants::CURSOR_BAG_END) + SoFSlot = serverSlot + 11; + else if (serverSlot >= EmuConstants::BANK_BAGS_BEGIN && serverSlot <= EmuConstants::BANK_BAGS_END) + SoFSlot = serverSlot + 1; + else if (serverSlot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && serverSlot <= EmuConstants::SHARED_BANK_BAGS_END) + SoFSlot = serverSlot + 1; + else if (serverSlot == MainPowerSource) SoFSlot = slots::MainPowerSource; else - SoFSlot = ServerSlot; + SoFSlot = serverSlot; return SoFSlot; } - static inline uint32 ServerToSoFCorpseSlot(uint32 ServerCorpse) + static inline uint32 ServerToSoFCorpseSlot(uint32 serverCorpseSlot) { //uint32 SoFCorpse; - return (ServerCorpse + 1); + return (serverCorpseSlot + 1); } - static inline uint32 SoFToServerSlot(uint32 SoFSlot) + static inline uint32 SoFToServerSlot(uint32 sofSlot) { uint32 ServerSlot = 0; - if (SoFSlot >= slots::MainAmmo && SoFSlot <= consts::CORPSE_END) // Cursor/Ammo/Power Source and Normal Inventory Slots - ServerSlot = SoFSlot - 1; - else if (SoFSlot >= consts::GENERAL_BAGS_BEGIN && SoFSlot <= consts::CURSOR_BAG_END) - ServerSlot = SoFSlot - 11; - else if (SoFSlot >= consts::BANK_BAGS_BEGIN && SoFSlot <= consts::BANK_BAGS_END) - ServerSlot = SoFSlot - 1; - else if (SoFSlot >= consts::SHARED_BANK_BAGS_BEGIN && SoFSlot <= consts::SHARED_BANK_BAGS_END) - ServerSlot = SoFSlot - 1; - else if (SoFSlot == slots::MainPowerSource) + if (sofSlot >= slots::MainAmmo && sofSlot <= consts::CORPSE_END) // Cursor/Ammo/Power Source and Normal Inventory Slots + ServerSlot = sofSlot - 1; + else if (sofSlot >= consts::GENERAL_BAGS_BEGIN && sofSlot <= consts::CURSOR_BAG_END) + ServerSlot = sofSlot - 11; + else if (sofSlot >= consts::BANK_BAGS_BEGIN && sofSlot <= consts::BANK_BAGS_END) + ServerSlot = sofSlot - 1; + else if (sofSlot >= consts::SHARED_BANK_BAGS_BEGIN && sofSlot <= consts::SHARED_BANK_BAGS_END) + ServerSlot = sofSlot - 1; + else if (sofSlot == slots::MainPowerSource) ServerSlot = MainPowerSource; else - ServerSlot = SoFSlot; + ServerSlot = sofSlot; return ServerSlot; } - static inline uint32 SoFToServerCorpseSlot(uint32 SoFCorpse) + static inline uint32 SoFToServerCorpseSlot(uint32 sofCorpseSlot) { //uint32 ServerCorpse; - return (SoFCorpse - 1); + return (sofCorpseSlot - 1); } static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink) diff --git a/common/patches/sof.h b/common/patches/sof.h index 15b9aa90c..6a67009d1 100644 --- a/common/patches/sof.h +++ b/common/patches/sof.h @@ -1,5 +1,5 @@ -#ifndef SoF_H_ -#define SoF_H_ +#ifndef SOF_H_ +#define SOF_H_ #include "../struct_strategy.h" @@ -32,6 +32,4 @@ namespace SoF { }; - - -#endif /*SoF_H_*/ +#endif /*SOF_H_*/ diff --git a/common/patches/sof_constants.h b/common/patches/sof_constants.h index 5e0f4b18a..b20e57196 100644 --- a/common/patches/sof_constants.h +++ b/common/patches/sof_constants.h @@ -19,8 +19,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef SoF_CONSTANTS_H_ -#define SoF_CONSTANTS_H_ +#ifndef SOF_CONSTANTS_H_ +#define SOF_CONSTANTS_H_ #include "../types.h" @@ -189,7 +189,7 @@ namespace SoF { }; //end namespace SoF -#endif /*SoF_CONSTANTS_H_*/ +#endif /*SOF_CONSTANTS_H_*/ /* SoF Notes: diff --git a/common/patches/sof_itemfields.h b/common/patches/sof_itemfields.h index ccba333b5..5f8c09354 100644 --- a/common/patches/sof_itemfields.h +++ b/common/patches/sof_itemfields.h @@ -436,4 +436,3 @@ These fields must be in the order of how they are serialized! #undef C #undef S #undef F - diff --git a/common/patches/sof_opcode_list.h b/common/patches/sof_opcode_list.h index 15236862f..b52e973ad 100644 --- a/common/patches/sof_opcode_list.h +++ b/common/patches/sof_opcode_list.h @@ -1226,4 +1226,3 @@ 0xFFFFFFFF, // 1217 (0x4c1) opcodes counted - diff --git a/common/patches/sof_ops.h b/common/patches/sof_ops.h index 14ad69a8b..f7077f05b 100644 --- a/common/patches/sof_ops.h +++ b/common/patches/sof_ops.h @@ -103,5 +103,6 @@ D(OP_TradeSkillCombine) D(OP_TributeItem) D(OP_WearChange) D(OP_WhoAllRequest) + #undef E #undef D diff --git a/common/patches/sof_structs.h b/common/patches/sof_structs.h index 4e84998b7..32b275716 100644 --- a/common/patches/sof_structs.h +++ b/common/patches/sof_structs.h @@ -1,5 +1,5 @@ -#ifndef SoF_STRUCTS_H_ -#define SoF_STRUCTS_H_ +#ifndef SOF_STRUCTS_H_ +#define SOF_STRUCTS_H_ namespace SoF { namespace structs { @@ -515,7 +515,7 @@ struct SpawnAppearance_Struct }; -// solar: this is used inside profile +// this is used inside profile struct SpellBuff_Struct { /*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise @@ -1172,7 +1172,7 @@ struct Animation_Struct { /*04*/ }; -// solar: this is what causes the caster to animate and the target to +// this is what causes the caster to animate and the target to // get the particle effects around them when a spell is cast // also causes a buff icon struct Action_Struct @@ -1224,7 +1224,7 @@ struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes /*0056*/ }; -// solar: this is what prints the You have been struck. and the regular +// this is what prints the You have been struck. and the regular // melee messages like You try to pierce, etc. It's basically the melee // and spell damage message struct CombatDamage_Struct @@ -1768,7 +1768,7 @@ struct RandomReq_Struct { uint32 high; }; -/* solar: 9/23/03 reply to /random command; struct from Zaphod */ +/* 9/23/03 reply to /random command */ struct RandomReply_Struct { /* 00 */ uint32 low; /* 04 */ uint32 high; @@ -4118,4 +4118,4 @@ struct AltCurrencySellItem_Struct { }; //end namespace structs }; //end namespace SoF -#endif /*SoF_STRUCTS_H_*/ +#endif /*SOF_STRUCTS_H_*/ diff --git a/common/patches/ss_declare.h b/common/patches/ss_declare.h index b45c4d722..bc8d8f214 100644 --- a/common/patches/ss_declare.h +++ b/common/patches/ss_declare.h @@ -1,6 +1,6 @@ -#define E(x) static void Encode_##x(EQApplicationPacket **p, EQStream *dest, bool ack_req); +#define E(x) static void Encode_##x(EQApplicationPacket **p, std::shared_ptr dest, bool ack_req); #define D(x) static void Decode_##x(EQApplicationPacket *p); diff --git a/common/patches/ss_define.h b/common/patches/ss_define.h index aaa41db23..3198820b6 100644 --- a/common/patches/ss_define.h +++ b/common/patches/ss_define.h @@ -1,5 +1,5 @@ -#define ENCODE(x) void Strategy::Encode_##x(EQApplicationPacket **p, EQStream *dest, bool ack_req) +#define ENCODE(x) void Strategy::Encode_##x(EQApplicationPacket **p, std::shared_ptr dest, bool ack_req) #define DECODE(x) void Strategy::Decode_##x(EQApplicationPacket *__packet) #define StructDist(in, f1, f2) (uint32(&in->f2)-uint32(&in->f1)) diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index 09e8b22fd..3be2d7d70 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -23,12 +23,12 @@ namespace Titanium char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint8 depth); // server to client inventory location converters - static inline int16 ServerToTitaniumSlot(uint32 ServerSlot); - static inline int16 ServerToTitaniumCorpseSlot(uint32 ServerCorpse); + static inline int16 ServerToTitaniumSlot(uint32 serverSlot); + static inline int16 ServerToTitaniumCorpseSlot(uint32 serverCorpseSlot); // client to server inventory location converters - static inline uint32 TitaniumToServerSlot(int16 TitaniumSlot); - static inline uint32 TitaniumToServerCorpseSlot(int16 TitaniumCorpse); + static inline uint32 TitaniumToServerSlot(int16 titaniumSlot); + static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot); // server to client text link converter static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink); @@ -113,7 +113,7 @@ namespace Titanium const ClientVersion Strategy::GetClientVersion() const { - return ClientVersion::Tit; + return ClientVersion::Titanium; } #include "ss_define.h" @@ -1774,7 +1774,7 @@ namespace Titanium DECODE_LENGTH_EXACT(structs::MoveItem_Struct); SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot, eq->to_slot); + Log.Out(Logs::General, Logs::Netcode, "[Titanium] Moved item from %u to %u", eq->from_slot, eq->to_slot); emu->from_slot = TitaniumToServerSlot(eq->from_slot); emu->to_slot = TitaniumToServerSlot(eq->to_slot); @@ -2004,7 +2004,7 @@ namespace Titanium inst->IsScaling() ? inst->GetExp() / 100 : 0, //merchant_slot, //instance ID, bullshit for now (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot, - 0, // item recast timer timestamp field (aka..last_cast_time field in SoF+ clients) + inst->GetRecastTimestamp(), (stackable ? ((inst->GetItem()->ItemType == ItemTypePotion) ? 1 : 0) : charges), inst->IsAttuned() ? 1 : 0, 0 @@ -2062,34 +2062,34 @@ namespace Titanium return serialization; } - static inline int16 ServerToTitaniumSlot(uint32 ServerSlot) + static inline int16 ServerToTitaniumSlot(uint32 serverSlot) { //int16 TitaniumSlot; - if (ServerSlot == INVALID_INDEX) + if (serverSlot == INVALID_INDEX) return INVALID_INDEX; - return ServerSlot; // deprecated + return serverSlot; // deprecated } - static inline int16 ServerToTitaniumCorpseSlot(uint32 ServerCorpse) + static inline int16 ServerToTitaniumCorpseSlot(uint32 serverCorpseSlot) { //int16 TitaniumCorpse; - return ServerCorpse; + return serverCorpseSlot; } - static inline uint32 TitaniumToServerSlot(int16 TitaniumSlot) + static inline uint32 TitaniumToServerSlot(int16 titaniumSlot) { //uint32 ServerSlot; - if (TitaniumSlot == INVALID_INDEX) + if (titaniumSlot == INVALID_INDEX) return INVALID_INDEX; - return TitaniumSlot; // deprecated + return titaniumSlot; // deprecated } - static inline uint32 TitaniumToServerCorpseSlot(int16 TitaniumCorpse) + static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot) { //uint32 ServerCorpse; - return TitaniumCorpse; + return titaniumCorpseSlot; } static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink) diff --git a/common/patches/titanium.h b/common/patches/titanium.h index de8131545..4b5164330 100644 --- a/common/patches/titanium.h +++ b/common/patches/titanium.h @@ -1,5 +1,5 @@ -#ifndef Titanium_H_ -#define Titanium_H_ +#ifndef TITANIUM_H_ +#define TITANIUM_H_ #include "../struct_strategy.h" @@ -32,6 +32,4 @@ namespace Titanium { }; - - -#endif /*Titanium_H_*/ +#endif /*TITANIUM_H_*/ diff --git a/common/patches/titanium_constants.h b/common/patches/titanium_constants.h index ff44513c2..15338e220 100644 --- a/common/patches/titanium_constants.h +++ b/common/patches/titanium_constants.h @@ -19,8 +19,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef Titanium_CONSTANTS_H_ -#define Titanium_CONSTANTS_H_ +#ifndef TITANIUM_CONSTANTS_H_ +#define TITANIUM_CONSTANTS_H_ #include "../types.h" @@ -188,7 +188,7 @@ namespace Titanium { }; //end namespace Titanium -#endif /*Titanium_CONSTANTS_H_*/ +#endif /*TITANIUM_CONSTANTS_H_*/ /* Titanium Notes: diff --git a/common/patches/titanium_itemfields.h b/common/patches/titanium_itemfields.h index 8030de887..dc87a714e 100644 --- a/common/patches/titanium_itemfields.h +++ b/common/patches/titanium_itemfields.h @@ -167,8 +167,8 @@ These fields must be in the order of how they are serialized! /* 156 */ I(Scroll.Level2) /* 157 */ I(Scroll.Level) /* 158 */ C("0") + #undef I #undef C #undef S #undef F - diff --git a/common/patches/titanium_ops.h b/common/patches/titanium_ops.h index 88c12e3ac..3d8dfbf79 100644 --- a/common/patches/titanium_ops.h +++ b/common/patches/titanium_ops.h @@ -75,5 +75,6 @@ D(OP_TradeSkillCombine) D(OP_TributeItem) D(OP_WearChange) D(OP_WhoAllRequest) + #undef E #undef D diff --git a/common/patches/titanium_structs.h b/common/patches/titanium_structs.h index 7d21ba998..19d82d6af 100644 --- a/common/patches/titanium_structs.h +++ b/common/patches/titanium_structs.h @@ -1,5 +1,5 @@ -#ifndef Titanium_STRUCTS_H_ -#define Titanium_STRUCTS_H_ +#ifndef TITANIUM_STRUCTS_H_ +#define TITANIUM_STRUCTS_H_ namespace Titanium { namespace structs { @@ -438,7 +438,7 @@ struct SpawnAppearance_Struct }; -// solar: this is used inside profile +// this is used inside profile struct SpellBuff_Struct { /*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise @@ -1054,7 +1054,7 @@ struct Animation_Struct { /*04*/ }; -// solar: this is what causes the caster to animate and the target to +// this is what causes the caster to animate and the target to // get the particle effects around them when a spell is cast // also causes a buff icon struct Action_Struct @@ -1078,7 +1078,7 @@ struct Action_Struct /* 31 */ }; -// solar: this is what prints the You have been struck. and the regular +// this is what prints the You have been struck. and the regular // melee messages like You try to pierce, etc. It's basically the melee // and spell damage message struct CombatDamage_Struct @@ -1516,7 +1516,7 @@ struct RandomReq_Struct { uint32 high; }; -/* solar: 9/23/03 reply to /random command; struct from Zaphod */ +/* 9/23/03 reply to /random command */ struct RandomReply_Struct { /* 00 */ uint32 low; /* 04 */ uint32 high; @@ -3332,4 +3332,4 @@ struct LFGuild_GuildToggle_Struct }; //end namespace structs }; //end namespace Titanium -#endif /*Titanium_STRUCTS_H_*/ +#endif /*TITANIUM_STRUCTS_H_*/ diff --git a/common/patches/underfoot.cpp b/common/patches/uf.cpp similarity index 94% rename from common/patches/underfoot.cpp rename to common/patches/uf.cpp index b3fa83419..f772509d0 100644 --- a/common/patches/underfoot.cpp +++ b/common/patches/uf.cpp @@ -1,6 +1,6 @@ #include "../global_define.h" #include "../eqemu_logsys.h" -#include "underfoot.h" +#include "uf.h" #include "../opcodemgr.h" #include "../eq_stream_ident.h" @@ -10,33 +10,33 @@ #include "../misc_functions.h" #include "../string_util.h" #include "../item.h" -#include "underfoot_structs.h" +#include "uf_structs.h" #include "../rulesys.h" #include #include -namespace Underfoot +namespace UF { - static const char *name = "Underfoot"; + static const char *name = "UF"; static OpcodeManager *opcodes = nullptr; static Strategy struct_strategy; char* SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth); // server to client inventory location converters - static inline uint32 ServerToUnderfootSlot(uint32 ServerSlot); - static inline uint32 ServerToUnderFootCorpseSlot(uint32 ServerCorpse); + static inline uint32 ServerToUFSlot(uint32 serverSlot); + static inline uint32 ServerToUFCorpseSlot(uint32 serverCorpseSlot); // client to server inventory location converters - static inline uint32 UnderfootToServerSlot(uint32 UnderfootSlot); - static inline uint32 UnderfootToServerCorpseSlot(uint32 UnderfootCorpse); + static inline uint32 UFToServerSlot(uint32 ufSlot); + static inline uint32 UFToServerCorpseSlot(uint32 ufCorpseSlot); // server to client text link converter - static inline void ServerToUnderfootTextLink(std::string& underfootTextLink, const std::string& serverTextLink); + static inline void ServerToUFTextLink(std::string& ufTextLink, const std::string& serverTextLink); // client to server text link converter - static inline void UnderfootToServerTextLink(std::string& serverTextLink, const std::string& underfootTextLink); + static inline void UFToServerTextLink(std::string& serverTextLink, const std::string& ufTextLink); void Register(EQStreamIdentifier &into) { @@ -102,7 +102,7 @@ namespace Underfoot { //all opcodes default to passthrough. #include "ss_register.h" -#include "underfoot_ops.h" +#include "uf_ops.h" } std::string Strategy::Describe() const @@ -115,7 +115,7 @@ namespace Underfoot const ClientVersion Strategy::GetClientVersion() const { - return ClientVersion::Und; + return ClientVersion::UF; } #include "ss_define.h" @@ -164,7 +164,7 @@ namespace Underfoot eq->unknown000 = 1; OUT(npcid); - eq->slot = ServerToUnderfootSlot(emu->slot); + eq->slot = ServerToUFSlot(emu->slot); OUT(charges); OUT(sell_price); @@ -215,7 +215,7 @@ namespace Underfoot SETUP_DIRECT_ENCODE(AltCurrencySellItem_Struct, structs::AltCurrencySellItem_Struct); OUT(merchant_entity_id); - eq->slot_id = ServerToUnderfootSlot(emu->slot_id); + eq->slot_id = ServerToUFSlot(emu->slot_id); OUT(charges); OUT(cost); @@ -227,7 +227,7 @@ namespace Underfoot ENCODE_LENGTH_EXACT(ApplyPoison_Struct); SETUP_DIRECT_ENCODE(ApplyPoison_Struct, structs::ApplyPoison_Struct); - eq->inventorySlot = ServerToUnderfootSlot(emu->inventorySlot); + eq->inventorySlot = ServerToUFSlot(emu->inventorySlot); OUT(success); FINISH_ENCODE(); @@ -441,7 +441,7 @@ namespace Underfoot std::string old_message = emu->message; std::string new_message; - ServerToUnderfootTextLink(new_message, old_message); + ServerToUFTextLink(new_message, old_message); //in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36; in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39; @@ -593,8 +593,8 @@ namespace Underfoot ENCODE_LENGTH_EXACT(DeleteItem_Struct); SETUP_DIRECT_ENCODE(DeleteItem_Struct, structs::DeleteItem_Struct); - eq->from_slot = ServerToUnderfootSlot(emu->from_slot); - eq->to_slot = ServerToUnderfootSlot(emu->to_slot); + eq->from_slot = ServerToUFSlot(emu->from_slot); + eq->to_slot = ServerToUFSlot(emu->to_slot); OUT(number_in_stack); FINISH_ENCODE(); @@ -755,7 +755,7 @@ namespace Underfoot std::string old_message = emu->message; std::string new_message; - ServerToUnderfootTextLink(new_message, old_message); + ServerToUFTextLink(new_message, old_message); //if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm) // new_message = new_message.substr(0, 512); @@ -807,7 +807,7 @@ namespace Underfoot for (int i = 0; i < 9; ++i) { if (old_message_array[i].length() == 0) { break; } - ServerToUnderfootTextLink(new_message_array[i], old_message_array[i]); + ServerToUFTextLink(new_message_array[i], old_message_array[i]); new_message_size += new_message_array[i].length() + 1; } @@ -1287,7 +1287,7 @@ namespace Underfoot ENCODE_LENGTH_EXACT(ItemVerifyReply_Struct); SETUP_DIRECT_ENCODE(ItemVerifyReply_Struct, structs::ItemVerifyReply_Struct); - eq->slot = ServerToUnderfootSlot(emu->slot); + eq->slot = ServerToUFSlot(emu->slot); OUT(spell); OUT(target); @@ -1344,7 +1344,7 @@ namespace Underfoot OUT(lootee); OUT(looter); - eq->slot_id = ServerToUnderFootCorpseSlot(emu->slot_id); + eq->slot_id = ServerToUFCorpseSlot(emu->slot_id); OUT(auto_loot); FINISH_ENCODE(); @@ -1506,8 +1506,8 @@ namespace Underfoot ENCODE_LENGTH_EXACT(MoveItem_Struct); SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct); - eq->from_slot = ServerToUnderfootSlot(emu->from_slot); - eq->to_slot = ServerToUnderfootSlot(emu->to_slot); + eq->from_slot = ServerToUFSlot(emu->from_slot); + eq->to_slot = ServerToUFSlot(emu->to_slot); OUT(number_in_stack); FINISH_ENCODE(); @@ -2093,7 +2093,7 @@ namespace Underfoot else eq->window = emu->window; OUT(type); - eq->invslot = ServerToUnderfootSlot(emu->invslot); + eq->invslot = ServerToUFSlot(emu->invslot); strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile)); FINISH_ENCODE(); @@ -2290,7 +2290,7 @@ namespace Underfoot SETUP_DIRECT_ENCODE(Merchant_Purchase_Struct, structs::Merchant_Purchase_Struct); OUT(npcid); - eq->itemslot = ServerToUnderfootSlot(emu->itemslot); + eq->itemslot = ServerToUFSlot(emu->itemslot); OUT(quantity); OUT(price); @@ -2399,7 +2399,7 @@ namespace Underfoot std::string old_message = &emu->message[strlen(emu->sayer)]; std::string new_message; - ServerToUnderfootTextLink(new_message, old_message); + ServerToUFTextLink(new_message, old_message); //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; in->size = strlen(emu->sayer) + new_message.length() + 25; @@ -2469,7 +2469,7 @@ namespace Underfoot std::string old_message = InBuffer; // start 'Reward' as string std::string new_message; - ServerToUnderfootTextLink(new_message, old_message); + ServerToUFTextLink(new_message, old_message); in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+ sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+ @@ -2570,7 +2570,7 @@ namespace Underfoot ENCODE_LENGTH_EXACT(TributeItem_Struct); SETUP_DIRECT_ENCODE(TributeItem_Struct, structs::TributeItem_Struct); - eq->slot = ServerToUnderfootSlot(emu->slot); + eq->slot = ServerToUFSlot(emu->slot); OUT(quantity); OUT(tribute_master_id); OUT(tribute_points); @@ -3060,7 +3060,7 @@ namespace Underfoot SETUP_DIRECT_DECODE(Adventure_Sell_Struct, structs::Adventure_Sell_Struct); IN(npcid); - emu->slot = UnderfootToServerSlot(eq->slot); + emu->slot = UFToServerSlot(eq->slot); IN(charges); IN(sell_price); @@ -3073,7 +3073,7 @@ namespace Underfoot SETUP_DIRECT_DECODE(AltCurrencySellItem_Struct, structs::AltCurrencySellItem_Struct); IN(merchant_entity_id); - emu->slot_id = UnderfootToServerSlot(eq->slot_id); + emu->slot_id = UFToServerSlot(eq->slot_id); IN(charges); IN(cost); @@ -3086,7 +3086,7 @@ namespace Underfoot SETUP_DIRECT_DECODE(AltCurrencySelectItem_Struct, structs::AltCurrencySelectItem_Struct); IN(merchant_entity_id); - emu->slot_id = UnderfootToServerSlot(eq->slot_id); + emu->slot_id = UFToServerSlot(eq->slot_id); FINISH_DIRECT_DECODE(); } @@ -3096,7 +3096,7 @@ namespace Underfoot DECODE_LENGTH_EXACT(structs::ApplyPoison_Struct); SETUP_DIRECT_DECODE(ApplyPoison_Struct, structs::ApplyPoison_Struct); - emu->inventorySlot = UnderfootToServerSlot(eq->inventorySlot); + emu->inventorySlot = UFToServerSlot(eq->inventorySlot); IN(success); FINISH_DIRECT_DECODE(); @@ -3118,7 +3118,7 @@ namespace Underfoot DECODE_LENGTH_EXACT(structs::AugmentItem_Struct); SETUP_DIRECT_DECODE(AugmentItem_Struct, structs::AugmentItem_Struct); - emu->container_slot = UnderfootToServerSlot(eq->container_slot); + emu->container_slot = UFToServerSlot(eq->container_slot); emu->augment_slot = eq->augment_slot; FINISH_DIRECT_DECODE(); @@ -3184,7 +3184,7 @@ namespace Underfoot IN(slot); IN(spell_id); - emu->inventoryslot = UnderfootToServerSlot(eq->inventoryslot); + emu->inventoryslot = UFToServerSlot(eq->inventoryslot); IN(target_id); IN(cs_unknown1); IN(cs_unknown2); @@ -3218,7 +3218,7 @@ namespace Underfoot std::string old_message = InBuffer; std::string new_message; - UnderfootToServerTextLink(new_message, old_message); + UFToServerTextLink(new_message, old_message); //__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1; __packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1; @@ -3312,7 +3312,7 @@ namespace Underfoot DECODE_LENGTH_EXACT(structs::Consume_Struct); SETUP_DIRECT_DECODE(Consume_Struct, structs::Consume_Struct); - emu->slot = UnderfootToServerSlot(eq->slot); + emu->slot = UFToServerSlot(eq->slot); IN(auto_consumed); IN(type); @@ -3339,8 +3339,8 @@ namespace Underfoot DECODE_LENGTH_EXACT(structs::DeleteItem_Struct); SETUP_DIRECT_DECODE(DeleteItem_Struct, structs::DeleteItem_Struct); - emu->from_slot = UnderfootToServerSlot(eq->from_slot); - emu->to_slot = UnderfootToServerSlot(eq->to_slot); + emu->from_slot = UFToServerSlot(eq->from_slot); + emu->to_slot = UFToServerSlot(eq->to_slot); IN(number_in_stack); FINISH_DIRECT_DECODE(); @@ -3352,7 +3352,7 @@ namespace Underfoot std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset std::string new_message; - UnderfootToServerTextLink(new_message, old_message); + UFToServerTextLink(new_message, old_message); __packet->size = sizeof(Emote_Struct); __packet->pBuffer = new unsigned char[__packet->size]; @@ -3519,7 +3519,7 @@ namespace Underfoot DECODE_LENGTH_EXACT(structs::ItemVerifyRequest_Struct); SETUP_DIRECT_DECODE(ItemVerifyRequest_Struct, structs::ItemVerifyRequest_Struct); - emu->slot = UnderfootToServerSlot(eq->slot); + emu->slot = UFToServerSlot(eq->slot); IN(target); FINISH_DIRECT_DECODE(); @@ -3546,7 +3546,7 @@ namespace Underfoot IN(lootee); IN(looter); - emu->slot_id = UnderfootToServerCorpseSlot(eq->slot_id); + emu->slot_id = UFToServerCorpseSlot(eq->slot_id); IN(auto_loot); FINISH_DIRECT_DECODE(); @@ -3557,10 +3557,10 @@ namespace Underfoot DECODE_LENGTH_EXACT(structs::MoveItem_Struct); SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct); - Log.Out(Logs::General, Logs::Netcode, "[ERROR] Moved item from %u to %u", eq->from_slot, eq->to_slot); + Log.Out(Logs::General, Logs::Netcode, "[UF] Moved item from %u to %u", eq->from_slot, eq->to_slot); - emu->from_slot = UnderfootToServerSlot(eq->from_slot); - emu->to_slot = UnderfootToServerSlot(eq->to_slot); + emu->from_slot = UFToServerSlot(eq->from_slot); + emu->to_slot = UFToServerSlot(eq->to_slot); IN(number_in_stack); FINISH_DIRECT_DECODE(); @@ -3622,7 +3622,7 @@ namespace Underfoot SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct); IN(type); - emu->invslot = UnderfootToServerSlot(eq->invslot); + emu->invslot = UFToServerSlot(eq->invslot); emu->window = (uint8)eq->window; strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile)); @@ -3672,7 +3672,7 @@ namespace Underfoot SETUP_DIRECT_DECODE(Merchant_Purchase_Struct, structs::Merchant_Purchase_Struct); IN(npcid); - emu->itemslot = UnderfootToServerSlot(eq->itemslot); + emu->itemslot = UFToServerSlot(eq->itemslot); IN(quantity); IN(price); @@ -3700,7 +3700,7 @@ namespace Underfoot DECODE_LENGTH_EXACT(structs::NewCombine_Struct); SETUP_DIRECT_DECODE(NewCombine_Struct, structs::NewCombine_Struct); - emu->container_slot = UnderfootToServerSlot(eq->container_slot); + emu->container_slot = UFToServerSlot(eq->container_slot); IN(guildtribute_slot); FINISH_DIRECT_DECODE(); @@ -3711,7 +3711,7 @@ namespace Underfoot DECODE_LENGTH_EXACT(structs::TributeItem_Struct); SETUP_DIRECT_DECODE(TributeItem_Struct, structs::TributeItem_Struct); - emu->slot = UnderfootToServerSlot(eq->slot); + emu->slot = UFToServerSlot(eq->slot); IN(quantity); IN(tribute_master_id); IN(tribute_points); @@ -3781,11 +3781,11 @@ namespace Underfoot const Item_Struct *item = inst->GetUnscaledItem(); //Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Serialize called for: %s", item->Name); - Underfoot::structs::ItemSerializationHeader hdr; + UF::structs::ItemSerializationHeader hdr; hdr.stacksize = stackable ? charges : 1; hdr.unknown004 = 0; - int32 slot_id = ServerToUnderfootSlot(slot_id_in); + int32 slot_id = ServerToUFSlot(slot_id_in); hdr.slot = (merchant_slot == 0) ? slot_id : merchant_slot; hdr.price = inst->GetPrice(); @@ -3793,17 +3793,17 @@ namespace Underfoot hdr.scaled_value = inst->IsScaling() ? inst->GetExp() / 100 : 0; hdr.instance_id = (merchant_slot == 0) ? inst->GetSerialNumber() : merchant_slot; hdr.unknown028 = 0; - hdr.last_cast_time = ((item->RecastDelay > 1) ? 1212693140 : 0); + hdr.last_cast_time = inst->GetRecastTimestamp(); hdr.charges = (stackable ? (item->MaxCharges ? 1 : 0) : charges); hdr.inst_nodrop = inst->IsAttuned() ? 1 : 0; hdr.unknown044 = 0; hdr.unknown048 = 0; hdr.unknown052 = 0; hdr.isEvolving = item->EvolvingLevel > 0 ? 1 : 0; - ss.write((const char*)&hdr, sizeof(Underfoot::structs::ItemSerializationHeader)); + ss.write((const char*)&hdr, sizeof(UF::structs::ItemSerializationHeader)); if (item->EvolvingLevel > 0) { - Underfoot::structs::EvolvingItem evotop; + UF::structs::EvolvingItem evotop; evotop.unknown001 = 0; evotop.unknown002 = 0; evotop.unknown003 = 0; @@ -3812,7 +3812,7 @@ namespace Underfoot evotop.progress = 95.512; evotop.Activated = 1; evotop.evomaxlevel = 7; - ss.write((const char*)&evotop, sizeof(Underfoot::structs::EvolvingItem)); + ss.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem)); } //ORNAMENT IDFILE / ICON - uint16 ornaIcon = 0; @@ -3832,13 +3832,13 @@ namespace Underfoot ss.write((const char*)&null_term, sizeof(uint8)); //no idfile } - Underfoot::structs::ItemSerializationHeaderFinish hdrf; + UF::structs::ItemSerializationHeaderFinish hdrf; hdrf.ornamentIcon = ornaIcon; hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit.. hdrf.unknown061 = 0; //possibly ornament / special ornament hdrf.isCopied = 0; //Flag for item to be 'Copied' hdrf.ItemClass = item->ItemClass; - ss.write((const char*)&hdrf, sizeof(Underfoot::structs::ItemSerializationHeaderFinish)); + ss.write((const char*)&hdrf, sizeof(UF::structs::ItemSerializationHeaderFinish)); if (strlen(item->Name) > 0) { @@ -3870,8 +3870,8 @@ namespace Underfoot ss.write((const char*)&null_term, sizeof(uint8)); } - Underfoot::structs::ItemBodyStruct ibs; - memset(&ibs, 0, sizeof(Underfoot::structs::ItemBodyStruct)); + UF::structs::ItemBodyStruct ibs; + memset(&ibs, 0, sizeof(UF::structs::ItemBodyStruct)); ibs.id = item->ID; ibs.weight = item->Weight; @@ -3956,7 +3956,7 @@ namespace Underfoot ibs.FactionAmt4 = item->FactionAmt4; ibs.FactionMod4 = item->FactionMod4; - ss.write((const char*)&ibs, sizeof(Underfoot::structs::ItemBodyStruct)); + ss.write((const char*)&ibs, sizeof(UF::structs::ItemBodyStruct)); //charm text if (strlen(item->CharmFile) > 0) @@ -3969,8 +3969,8 @@ namespace Underfoot ss.write((const char*)&null_term, sizeof(uint8)); } - Underfoot::structs::ItemSecondaryBodyStruct isbs; - memset(&isbs, 0, sizeof(Underfoot::structs::ItemSecondaryBodyStruct)); + UF::structs::ItemSecondaryBodyStruct isbs; + memset(&isbs, 0, sizeof(UF::structs::ItemSecondaryBodyStruct)); isbs.augtype = item->AugType; isbs.augrestrict = item->AugRestrict; @@ -3996,7 +3996,7 @@ namespace Underfoot isbs.book = item->Book; isbs.booktype = item->BookType; - ss.write((const char*)&isbs, sizeof(Underfoot::structs::ItemSecondaryBodyStruct)); + ss.write((const char*)&isbs, sizeof(UF::structs::ItemSecondaryBodyStruct)); if (strlen(item->Filename) > 0) { @@ -4008,8 +4008,8 @@ namespace Underfoot ss.write((const char*)&null_term, sizeof(uint8)); } - Underfoot::structs::ItemTertiaryBodyStruct itbs; - memset(&itbs, 0, sizeof(Underfoot::structs::ItemTertiaryBodyStruct)); + UF::structs::ItemTertiaryBodyStruct itbs; + memset(&itbs, 0, sizeof(UF::structs::ItemTertiaryBodyStruct)); itbs.loregroup = item->LoreGroup; itbs.artifact = item->ArtifactFlag; @@ -4030,13 +4030,13 @@ namespace Underfoot itbs.no_transfer = item->NoTransfer; itbs.expendablearrow = item->ExpendableArrow; - ss.write((const char*)&itbs, sizeof(Underfoot::structs::ItemTertiaryBodyStruct)); + ss.write((const char*)&itbs, sizeof(UF::structs::ItemTertiaryBodyStruct)); // Effect Structures Broken down to allow variable length strings for effect names int32 effect_unknown = 0; - Underfoot::structs::ClickEffectStruct ices; - memset(&ices, 0, sizeof(Underfoot::structs::ClickEffectStruct)); + UF::structs::ClickEffectStruct ices; + memset(&ices, 0, sizeof(UF::structs::ClickEffectStruct)); ices.effect = item->Click.Effect; ices.level2 = item->Click.Level2; @@ -4047,7 +4047,7 @@ namespace Underfoot ices.recast = item->RecastDelay; ices.recast_type = item->RecastType; - ss.write((const char*)&ices, sizeof(Underfoot::structs::ClickEffectStruct)); + ss.write((const char*)&ices, sizeof(UF::structs::ClickEffectStruct)); if (strlen(item->ClickName) > 0) { @@ -4061,8 +4061,8 @@ namespace Underfoot ss.write((const char*)&effect_unknown, sizeof(int32)); // clickunk7 - Underfoot::structs::ProcEffectStruct ipes; - memset(&ipes, 0, sizeof(Underfoot::structs::ProcEffectStruct)); + UF::structs::ProcEffectStruct ipes; + memset(&ipes, 0, sizeof(UF::structs::ProcEffectStruct)); ipes.effect = item->Proc.Effect; ipes.level2 = item->Proc.Level2; @@ -4070,7 +4070,7 @@ namespace Underfoot ipes.level = item->Proc.Level; ipes.procrate = item->ProcRate; - ss.write((const char*)&ipes, sizeof(Underfoot::structs::ProcEffectStruct)); + ss.write((const char*)&ipes, sizeof(UF::structs::ProcEffectStruct)); if (strlen(item->ProcName) > 0) { @@ -4084,15 +4084,15 @@ namespace Underfoot ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown5 - Underfoot::structs::WornEffectStruct iwes; - memset(&iwes, 0, sizeof(Underfoot::structs::WornEffectStruct)); + UF::structs::WornEffectStruct iwes; + memset(&iwes, 0, sizeof(UF::structs::WornEffectStruct)); iwes.effect = item->Worn.Effect; iwes.level2 = item->Worn.Level2; iwes.type = item->Worn.Type; iwes.level = item->Worn.Level; - ss.write((const char*)&iwes, sizeof(Underfoot::structs::WornEffectStruct)); + ss.write((const char*)&iwes, sizeof(UF::structs::WornEffectStruct)); if (strlen(item->WornName) > 0) { @@ -4106,15 +4106,15 @@ namespace Underfoot ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 - Underfoot::structs::WornEffectStruct ifes; - memset(&ifes, 0, sizeof(Underfoot::structs::WornEffectStruct)); + UF::structs::WornEffectStruct ifes; + memset(&ifes, 0, sizeof(UF::structs::WornEffectStruct)); ifes.effect = item->Focus.Effect; ifes.level2 = item->Focus.Level2; ifes.type = item->Focus.Type; ifes.level = item->Focus.Level; - ss.write((const char*)&ifes, sizeof(Underfoot::structs::WornEffectStruct)); + ss.write((const char*)&ifes, sizeof(UF::structs::WornEffectStruct)); if (strlen(item->FocusName) > 0) { @@ -4128,15 +4128,15 @@ namespace Underfoot ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 - Underfoot::structs::WornEffectStruct ises; - memset(&ises, 0, sizeof(Underfoot::structs::WornEffectStruct)); + UF::structs::WornEffectStruct ises; + memset(&ises, 0, sizeof(UF::structs::WornEffectStruct)); ises.effect = item->Scroll.Effect; ises.level2 = item->Scroll.Level2; ises.type = item->Scroll.Type; ises.level = item->Scroll.Level; - ss.write((const char*)&ises, sizeof(Underfoot::structs::WornEffectStruct)); + ss.write((const char*)&ises, sizeof(UF::structs::WornEffectStruct)); if (strlen(item->ScrollName) > 0) { @@ -4151,8 +4151,8 @@ namespace Underfoot ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 // Bard Effect? - Underfoot::structs::WornEffectStruct ibes; - memset(&ibes, 0, sizeof(Underfoot::structs::WornEffectStruct)); + UF::structs::WornEffectStruct ibes; + memset(&ibes, 0, sizeof(UF::structs::WornEffectStruct)); ibes.effect = item->Bard.Effect; ibes.level2 = item->Bard.Level2; @@ -4160,7 +4160,7 @@ namespace Underfoot ibes.level = item->Bard.Level; //ibes.unknown6 = 0xffffffff; - ss.write((const char*)&ibes, sizeof(Underfoot::structs::WornEffectStruct)); + ss.write((const char*)&ibes, sizeof(UF::structs::WornEffectStruct)); /* if(strlen(item->BardName) > 0) @@ -4174,8 +4174,8 @@ namespace Underfoot ss.write((const char*)&effect_unknown, sizeof(int32)); // unknown6 // End of Effects - Underfoot::structs::ItemQuaternaryBodyStruct iqbs; - memset(&iqbs, 0, sizeof(Underfoot::structs::ItemQuaternaryBodyStruct)); + UF::structs::ItemQuaternaryBodyStruct iqbs; + memset(&iqbs, 0, sizeof(UF::structs::ItemQuaternaryBodyStruct)); iqbs.scriptfileid = item->ScriptFileID; iqbs.quest_item = item->QuestItemFlag; @@ -4240,7 +4240,7 @@ namespace Underfoot } } - ss.write((const char*)&iqbs, sizeof(Underfoot::structs::ItemQuaternaryBodyStruct)); + ss.write((const char*)&iqbs, sizeof(UF::structs::ItemQuaternaryBodyStruct)); for (int x = 0; x < 10; ++x) { @@ -4262,62 +4262,62 @@ namespace Underfoot return item_serial; } - static inline uint32 ServerToUnderfootSlot(uint32 ServerSlot) + static inline uint32 ServerToUFSlot(uint32 serverSlot) { uint32 UnderfootSlot = 0; - if (ServerSlot >= MainAmmo && ServerSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots - UnderfootSlot = ServerSlot + 1; - else if (ServerSlot >= EmuConstants::GENERAL_BAGS_BEGIN && ServerSlot <= EmuConstants::CURSOR_BAG_END) - UnderfootSlot = ServerSlot + 11; - else if (ServerSlot >= EmuConstants::BANK_BAGS_BEGIN && ServerSlot <= EmuConstants::BANK_BAGS_END) - UnderfootSlot = ServerSlot + 1; - else if (ServerSlot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && ServerSlot <= EmuConstants::SHARED_BANK_BAGS_END) - UnderfootSlot = ServerSlot + 1; - else if (ServerSlot == MainPowerSource) + if (serverSlot >= MainAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots + UnderfootSlot = serverSlot + 1; + else if (serverSlot >= EmuConstants::GENERAL_BAGS_BEGIN && serverSlot <= EmuConstants::CURSOR_BAG_END) + UnderfootSlot = serverSlot + 11; + else if (serverSlot >= EmuConstants::BANK_BAGS_BEGIN && serverSlot <= EmuConstants::BANK_BAGS_END) + UnderfootSlot = serverSlot + 1; + else if (serverSlot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && serverSlot <= EmuConstants::SHARED_BANK_BAGS_END) + UnderfootSlot = serverSlot + 1; + else if (serverSlot == MainPowerSource) UnderfootSlot = slots::MainPowerSource; else - UnderfootSlot = ServerSlot; + UnderfootSlot = serverSlot; return UnderfootSlot; } - static inline uint32 ServerToUnderFootCorpseSlot(uint32 ServerCorpse) + static inline uint32 ServerToUFCorpseSlot(uint32 serverCorpseSlot) { //uint32 UnderfootCorpse; - return (ServerCorpse + 1); + return (serverCorpseSlot + 1); } - static inline uint32 UnderfootToServerSlot(uint32 UnderfootSlot) + static inline uint32 UFToServerSlot(uint32 ufSlot) { uint32 ServerSlot = 0; - if (UnderfootSlot >= slots::MainAmmo && UnderfootSlot <= consts::CORPSE_END) // Cursor/Ammo/Power Source and Normal Inventory Slots - ServerSlot = UnderfootSlot - 1; - else if (UnderfootSlot >= consts::GENERAL_BAGS_BEGIN && UnderfootSlot <= consts::CURSOR_BAG_END) - ServerSlot = UnderfootSlot - 11; - else if (UnderfootSlot >= consts::BANK_BAGS_BEGIN && UnderfootSlot <= consts::BANK_BAGS_END) - ServerSlot = UnderfootSlot - 1; - else if (UnderfootSlot >= consts::SHARED_BANK_BAGS_BEGIN && UnderfootSlot <= consts::SHARED_BANK_BAGS_END) - ServerSlot = UnderfootSlot - 1; - else if (UnderfootSlot == slots::MainPowerSource) + if (ufSlot >= slots::MainAmmo && ufSlot <= consts::CORPSE_END) // Cursor/Ammo/Power Source and Normal Inventory Slots + ServerSlot = ufSlot - 1; + else if (ufSlot >= consts::GENERAL_BAGS_BEGIN && ufSlot <= consts::CURSOR_BAG_END) + ServerSlot = ufSlot - 11; + else if (ufSlot >= consts::BANK_BAGS_BEGIN && ufSlot <= consts::BANK_BAGS_END) + ServerSlot = ufSlot - 1; + else if (ufSlot >= consts::SHARED_BANK_BAGS_BEGIN && ufSlot <= consts::SHARED_BANK_BAGS_END) + ServerSlot = ufSlot - 1; + else if (ufSlot == slots::MainPowerSource) ServerSlot = MainPowerSource; else - ServerSlot = UnderfootSlot; + ServerSlot = ufSlot; return ServerSlot; } - static inline uint32 UnderfootToServerCorpseSlot(uint32 UnderfootCorpse) + static inline uint32 UFToServerCorpseSlot(uint32 ufCorpseSlot) { //uint32 ServerCorpse; - return (UnderfootCorpse - 1); + return (ufCorpseSlot - 1); } - static inline void ServerToUnderfootTextLink(std::string& underfootTextLink, const std::string& serverTextLink) + static inline void ServerToUFTextLink(std::string& ufTextLink, const std::string& serverTextLink) { if ((consts::TEXT_LINK_BODY_LENGTH == EmuConstants::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) { - underfootTextLink = serverTextLink; + ufTextLink = serverTextLink; return; } @@ -4326,7 +4326,7 @@ namespace Underfoot for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { if (segments[segment_iter].length() <= EmuConstants::TEXT_LINK_BODY_LENGTH) { - underfootTextLink.append(segments[segment_iter]); + ufTextLink.append(segments[segment_iter]); // TODO: log size mismatch error continue; } @@ -4336,32 +4336,32 @@ namespace Underfoot // SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50) // Diff: ^^^^^ ^ - underfootTextLink.push_back('\x12'); - underfootTextLink.append(segments[segment_iter].substr(0, 31)); - underfootTextLink.append(segments[segment_iter].substr(36, 5)); + ufTextLink.push_back('\x12'); + ufTextLink.append(segments[segment_iter].substr(0, 31)); + ufTextLink.append(segments[segment_iter].substr(36, 5)); if (segments[segment_iter][41] == '0') - underfootTextLink.push_back(segments[segment_iter][42]); + ufTextLink.push_back(segments[segment_iter][42]); else - underfootTextLink.push_back('F'); + ufTextLink.push_back('F'); - underfootTextLink.append(segments[segment_iter].substr(43)); - underfootTextLink.push_back('\x12'); + ufTextLink.append(segments[segment_iter].substr(43)); + ufTextLink.push_back('\x12'); } else { - underfootTextLink.append(segments[segment_iter]); + ufTextLink.append(segments[segment_iter]); } } } - static inline void UnderfootToServerTextLink(std::string& serverTextLink, const std::string& underfootTextLink) + static inline void UFToServerTextLink(std::string& serverTextLink, const std::string& ufTextLink) { - if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (underfootTextLink.find('\x12') == std::string::npos)) { - serverTextLink = underfootTextLink; + if ((EmuConstants::TEXT_LINK_BODY_LENGTH == consts::TEXT_LINK_BODY_LENGTH) || (ufTextLink.find('\x12') == std::string::npos)) { + serverTextLink = ufTextLink; return; } - auto segments = SplitString(underfootTextLink, '\x12'); + auto segments = SplitString(ufTextLink, '\x12'); for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) { if (segment_iter & 1) { @@ -4390,4 +4390,4 @@ namespace Underfoot } } } -// end namespace Underfoot +// end namespace UF diff --git a/common/patches/underfoot.h b/common/patches/uf.h similarity index 82% rename from common/patches/underfoot.h rename to common/patches/uf.h index 4bf00b0e8..26e2346a7 100644 --- a/common/patches/underfoot.h +++ b/common/patches/uf.h @@ -1,11 +1,11 @@ -#ifndef Underfoot_H_ -#define Underfoot_H_ +#ifndef UF_H_ +#define UF_H_ #include "../struct_strategy.h" class EQStreamIdentifier; -namespace Underfoot { +namespace UF { //these are the only public member of this namespace. extern void Register(EQStreamIdentifier &into); @@ -27,11 +27,9 @@ namespace Underfoot { //magic macro to declare our opcode processors #include "ss_declare.h" - #include "underfoot_ops.h" + #include "uf_ops.h" }; }; - - -#endif /*Underfoot_H_*/ +#endif /*UF_H_*/ diff --git a/common/patches/underfoot_constants.h b/common/patches/uf_constants.h similarity index 97% rename from common/patches/underfoot_constants.h rename to common/patches/uf_constants.h index a656c56eb..70b89df18 100644 --- a/common/patches/underfoot_constants.h +++ b/common/patches/uf_constants.h @@ -19,12 +19,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef Underfoot_CONSTANTS_H_ -#define Underfoot_CONSTANTS_H_ +#ifndef UF_CONSTANTS_H_ +#define UF_CONSTANTS_H_ #include "../types.h" -namespace Underfoot { +namespace UF { namespace maps { typedef enum : int16 { // this needs work to match actual client equivilents @@ -187,12 +187,12 @@ namespace Underfoot { static const bool COIN_HAS_WEIGHT = false; } -}; //end namespace Underfoot +}; //end namespace UF -#endif /*Underfoot_CONSTANTS_H_*/ +#endif /*UF_CONSTANTS_H_*/ /* -Underfoot Notes: +UF Notes: ** Integer-based inventory ** ok Possessions: 0 - 31 (Corpse: 23 - 54 [Offset 23]) ok [Equipment: 0 - 22] diff --git a/common/patches/underfoot_itemfields.h b/common/patches/uf_itemfields.h similarity index 99% rename from common/patches/underfoot_itemfields.h rename to common/patches/uf_itemfields.h index ccba333b5..5f8c09354 100644 --- a/common/patches/underfoot_itemfields.h +++ b/common/patches/uf_itemfields.h @@ -436,4 +436,3 @@ These fields must be in the order of how they are serialized! #undef C #undef S #undef F - diff --git a/common/patches/underfoot_ops.h b/common/patches/uf_ops.h similarity index 99% rename from common/patches/underfoot_ops.h rename to common/patches/uf_ops.h index 188cf3d9e..7f5f500c5 100644 --- a/common/patches/underfoot_ops.h +++ b/common/patches/uf_ops.h @@ -129,5 +129,6 @@ D(OP_TradeSkillCombine) D(OP_TributeItem) D(OP_WearChange) D(OP_WhoAllRequest) + #undef E #undef D diff --git a/common/patches/underfoot_structs.h b/common/patches/uf_structs.h similarity index 99% rename from common/patches/underfoot_structs.h rename to common/patches/uf_structs.h index 3a63a8c0f..fb4d00de3 100644 --- a/common/patches/underfoot_structs.h +++ b/common/patches/uf_structs.h @@ -1,7 +1,7 @@ -#ifndef Underfoot_STRUCTS_H_ -#define Underfoot_STRUCTS_H_ +#ifndef UF_STRUCTS_H_ +#define UF_STRUCTS_H_ -namespace Underfoot { +namespace UF { namespace structs { @@ -1250,7 +1250,7 @@ struct Animation_Struct { /*04*/ }; -// solar: this is what causes the caster to animate and the target to +// this is what causes the caster to animate and the target to // get the particle effects around them when a spell is cast // also causes a buff icon struct Action_Struct @@ -1305,7 +1305,7 @@ struct ActionAlt_Struct /*64*/ }; -// solar: this is what prints the You have been struck. and the regular +// this is what prints the You have been struck. and the regular // melee messages like You try to pierce, etc. It's basically the melee // and spell damage message struct CombatDamage_Struct @@ -1849,7 +1849,7 @@ struct RandomReq_Struct { uint32 high; }; -/* solar: 9/23/03 reply to /random command; struct from Zaphod */ +/* 9/23/03 reply to /random command */ struct RandomReply_Struct { /* 00 */ uint32 low; /* 04 */ uint32 high; @@ -4531,6 +4531,6 @@ struct MercenaryAssign_Struct { }; }; //end namespace structs -}; //end namespace Underfoot +}; //end namespace UF -#endif /*Underfoot_STRUCTS_H_*/ +#endif /*UF_STRUCTS_H_*/ diff --git a/common/ptimer.h b/common/ptimer.h index 829a015b2..d12b6779d 100644 --- a/common/ptimer.h +++ b/common/ptimer.h @@ -79,6 +79,7 @@ public: inline const uint32 GetTimerTime() const { return timer_time; } inline const uint32 GetStartTime() const { return start_time; } inline const pTimerType GetType() const { return _type; } + inline const uint32 GetReadyTimestamp() const { return start_time + timer_time; } inline bool Enabled() { return enabled; } diff --git a/common/ruletypes.h b/common/ruletypes.h index 59726bcaa..136f55026 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -101,6 +101,7 @@ RULE_INT ( Character, FoodLossPerUpdate, 35) // How much food/water you lose per RULE_INT ( Character, BaseInstrumentSoftCap, 36) // Softcap for instrument mods, 36 commonly referred to as "3.6" as well. RULE_INT ( Character, BaseRunSpeedCap, 158) // Base Run Speed Cap, on live it's 158% which will give you a runspeed of 1.580 hard capped to 225. RULE_INT ( Character, OrnamentationAugmentType, 20) //Ornamentation Augment Type +RULE_REAL(Character, EnvironmentDamageMulipliter, 1) RULE_CATEGORY_END() RULE_CATEGORY( Mercs ) diff --git a/common/servertalk.h b/common/servertalk.h index 547dda9b1..af39bfaa4 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -51,7 +51,7 @@ #define ServerOP_AcceptWorldEntrance 0x0024 #define ServerOP_ZAAuth 0x0025 #define ServerOP_ZAAuthFailed 0x0026 -#define ServerOP_ZoneIncClient 0x0027 // Incomming client +#define ServerOP_ZoneIncClient 0x0027 // Incoming client #define ServerOP_ClientListKA 0x0028 #define ServerOP_ChangeWID 0x0029 #define ServerOP_IPLookup 0x002A @@ -307,7 +307,7 @@ struct ServerZoneStateChange_struct { bool makestatic; }; -struct ServerZoneIncommingClient_Struct { +struct ServerZoneIncomingClient_Struct { uint32 zoneid; // in case the zone shut down, boot it back up uint16 instanceid; // instance id if it exists for booting up uint32 ip; // client's IP address diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 969ca2d58..13ae065be 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -382,191 +382,214 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, // Retrieve shared bank inventory based on either account or character -bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) { +bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid) +{ std::string query; if (is_charid) query = StringFormat("SELECT sb.slotid, sb.itemid, sb.charges, " - "sb.augslot1, sb.augslot2, sb.augslot3, " - "sb.augslot4, sb.augslot5, sb.augslot6, sb.custom_data " - "FROM sharedbank sb INNER JOIN character_data ch " - "ON ch.account_id=sb.acctid WHERE ch.id = %i", id); + "sb.augslot1, sb.augslot2, sb.augslot3, " + "sb.augslot4, sb.augslot5, sb.augslot6, sb.custom_data " + "FROM sharedbank sb INNER JOIN character_data ch " + "ON ch.account_id=sb.acctid WHERE ch.id = %i", + id); else query = StringFormat("SELECT slotid, itemid, charges, " - "augslot1, augslot2, augslot3, " - "augslot4, augslot5, augslot6, custom_data " - "FROM sharedbank WHERE acctid=%i", id); - auto results = QueryDatabase(query); - if (!results.Success()) { - Log.Out(Logs::General, Logs::Error, "Database::GetSharedBank(uint32 account_id): %s", results.ErrorMessage().c_str()); - return false; - } + "augslot1, augslot2, augslot3, " + "augslot4, augslot5, augslot6, custom_data " + "FROM sharedbank WHERE acctid=%i", + id); + auto results = QueryDatabase(query); + if (!results.Success()) { + Log.Out(Logs::General, Logs::Error, "Database::GetSharedBank(uint32 account_id): %s", + results.ErrorMessage().c_str()); + return false; + } - for (auto row = results.begin(); row != results.end(); ++row) { - int16 slot_id = (int16)atoi(row[0]); - uint32 item_id = (uint32)atoi(row[1]); - int8 charges = (int8)atoi(row[2]); + for (auto row = results.begin(); row != results.end(); ++row) { + int16 slot_id = (int16)atoi(row[0]); + uint32 item_id = (uint32)atoi(row[1]); + int8 charges = (int8)atoi(row[2]); uint32 aug[EmuConstants::ITEM_COMMON_SIZE]; aug[0] = (uint32)atoi(row[3]); aug[1] = (uint32)atoi(row[4]); - aug[2] = (uint32)atoi(row[5]); - aug[3] = (uint32)atoi(row[6]); - aug[4] = (uint32)atoi(row[7]); + aug[2] = (uint32)atoi(row[5]); + aug[3] = (uint32)atoi(row[6]); + aug[4] = (uint32)atoi(row[7]); aug[5] = (uint32)atoi(row[8]); - const Item_Struct* item = GetItem(item_id); + const Item_Struct *item = GetItem(item_id); - if (!item) { - Log.Out(Logs::General, Logs::Error, - "Warning: %s %i has an invalid item_id %i in inventory slot %i", - ((is_charid==true) ? "charid" : "acctid"), id, item_id, slot_id); - continue; - } + if (!item) { + Log.Out(Logs::General, Logs::Error, + "Warning: %s %i has an invalid item_id %i in inventory slot %i", + ((is_charid == true) ? "charid" : "acctid"), id, item_id, slot_id); + continue; + } - int16 put_slot_id = INVALID_INDEX; + int16 put_slot_id = INVALID_INDEX; - ItemInst* inst = CreateBaseItem(item, charges); - if (inst && item->ItemClass == ItemClassCommon) { - for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - if (aug[i]) + ItemInst *inst = CreateBaseItem(item, charges); + if (inst && item->ItemClass == ItemClassCommon) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { + if (aug[i]) inst->PutAugment(this, i, aug[i]); - } - } + } + } - if(!row[9]) - continue; + if (row[9]) { + std::string data_str(row[9]); + std::string idAsString; + std::string value; + bool use_id = true; - std::string data_str(row[9]); - std::string idAsString; - std::string value; - bool use_id = true; + for (int i = 0; i < data_str.length(); ++i) { + if (data_str[i] == '^') { + if (!use_id) { + inst->SetCustomData(idAsString, value); + idAsString.clear(); + value.clear(); + } + use_id = !use_id; + continue; + } - for(int i = 0; i < data_str.length(); ++i) { - if(data_str[i] == '^') { - if(!use_id) { - inst->SetCustomData(idAsString, value); - idAsString.clear(); - value.clear(); - } - use_id = !use_id; - continue; - } + char v = data_str[i]; + if (use_id) + idAsString.push_back(v); + else + value.push_back(v); + } + } - char v = data_str[i]; - if(use_id) - idAsString.push_back(v); - else - value.push_back(v); - } + put_slot_id = inv->PutItem(slot_id, *inst); + safe_delete(inst); - put_slot_id = inv->PutItem(slot_id, *inst); - safe_delete(inst); + // Save ptr to item in inventory + if (put_slot_id != INVALID_INDEX) + continue; - // Save ptr to item in inventory - if (put_slot_id != INVALID_INDEX) - continue; + Log.Out(Logs::General, Logs::Error, + "Warning: Invalid slot_id for item in shared bank inventory: %s=%i, item_id=%i, slot_id=%i", + ((is_charid == true) ? "charid" : "acctid"), id, item_id, slot_id); - Log.Out(Logs::General, Logs::Error, "Warning: Invalid slot_id for item in shared bank inventory: %s=%i, item_id=%i, slot_id=%i", - ((is_charid==true)? "charid": "acctid"), id, item_id, slot_id); - - if (is_charid) - SaveInventory(id, nullptr, slot_id); + if (is_charid) + SaveInventory(id, nullptr, slot_id); } return true; } - // Overloaded: Retrieve character inventory based on character id -bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) { +bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv) +{ // Retrieve character inventory - std::string query = StringFormat("SELECT slotid, itemid, charges, color, augslot1, " - "augslot2, augslot3, augslot4, augslot5, augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model " - "FROM inventory WHERE charid = %i ORDER BY slotid", char_id); - auto results = QueryDatabase(query); - if (!results.Success()) { - Log.Out(Logs::General, Logs::Error, "If you got an error related to the 'instnodrop' field, run the following SQL Queries:\nalter table inventory add instnodrop tinyint(1) unsigned default 0 not null;\n"); - return false; - } + std::string query = + StringFormat("SELECT slotid, itemid, charges, color, augslot1, augslot2, augslot3, augslot4, augslot5, " + "augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model FROM " + "inventory WHERE charid = %i ORDER BY slotid", + char_id); + auto results = QueryDatabase(query); + if (!results.Success()) { + Log.Out(Logs::General, Logs::Error, "If you got an error related to the 'instnodrop' field, run the " + "following SQL Queries:\nalter table inventory add instnodrop " + "tinyint(1) unsigned default 0 not null;\n"); + return false; + } - for (auto row = results.begin(); row != results.end(); ++row) { - int16 slot_id = atoi(row[0]); - uint32 item_id = atoi(row[1]); - uint16 charges = atoi(row[2]); - uint32 color = atoul(row[3]); + auto timestamps = GetItemRecastTimestamps(char_id); - uint32 aug[EmuConstants::ITEM_COMMON_SIZE]; + for (auto row = results.begin(); row != results.end(); ++row) { + int16 slot_id = atoi(row[0]); + uint32 item_id = atoi(row[1]); + uint16 charges = atoi(row[2]); + uint32 color = atoul(row[3]); - aug[0] = (uint32)atoul(row[4]); - aug[1] = (uint32)atoul(row[5]); - aug[2] = (uint32)atoul(row[6]); - aug[3] = (uint32)atoul(row[7]); - aug[4] = (uint32)atoul(row[8]); + uint32 aug[EmuConstants::ITEM_COMMON_SIZE]; + + aug[0] = (uint32)atoul(row[4]); + aug[1] = (uint32)atoul(row[5]); + aug[2] = (uint32)atoul(row[6]); + aug[3] = (uint32)atoul(row[7]); + aug[4] = (uint32)atoul(row[8]); aug[5] = (uint32)atoul(row[9]); - bool instnodrop = (row[10] && (uint16)atoi(row[10]))? true: false; + bool instnodrop = (row[10] && (uint16)atoi(row[10])) ? true : false; uint32 ornament_icon = (uint32)atoul(row[12]); uint32 ornament_idfile = (uint32)atoul(row[13]); uint32 ornament_hero_model = (uint32)atoul(row[14]); - const Item_Struct* item = GetItem(item_id); + const Item_Struct *item = GetItem(item_id); - if (!item) { - Log.Out(Logs::General, Logs::Error,"Warning: charid %i has an invalid item_id %i in inventory slot %i", char_id, item_id, slot_id); - continue; - } + if (!item) { + Log.Out(Logs::General, Logs::Error, + "Warning: charid %i has an invalid item_id %i in inventory slot %i", char_id, item_id, + slot_id); + continue; + } - int16 put_slot_id = INVALID_INDEX; + int16 put_slot_id = INVALID_INDEX; - ItemInst* inst = CreateBaseItem(item, charges); + ItemInst *inst = CreateBaseItem(item, charges); if (inst == nullptr) continue; - if(row[11]) { - std::string data_str(row[11]); - std::string idAsString; - std::string value; - bool use_id = true; + if (row[11]) { + std::string data_str(row[11]); + std::string idAsString; + std::string value; + bool use_id = true; - for(int i = 0; i < data_str.length(); ++i) { - if(data_str[i] == '^') { - if(!use_id) { - inst->SetCustomData(idAsString, value); - idAsString.clear(); - value.clear(); - } + for (int i = 0; i < data_str.length(); ++i) { + if (data_str[i] == '^') { + if (!use_id) { + inst->SetCustomData(idAsString, value); + idAsString.clear(); + value.clear(); + } - use_id = !use_id; - continue; - } + use_id = !use_id; + continue; + } - char v = data_str[i]; - if(use_id) - idAsString.push_back(v); - else - value.push_back(v); - } - } + char v = data_str[i]; + if (use_id) + idAsString.push_back(v); + else + value.push_back(v); + } + } inst->SetOrnamentIcon(ornament_icon); inst->SetOrnamentationIDFile(ornament_idfile); inst->SetOrnamentHeroModel(ornament_hero_model); - if (instnodrop || (((slot_id >= EmuConstants::EQUIPMENT_BEGIN && slot_id <= EmuConstants::EQUIPMENT_END) || slot_id == MainPowerSource) && inst->GetItem()->Attuneable)) - inst->SetAttuned(true); + if (instnodrop || + (((slot_id >= EmuConstants::EQUIPMENT_BEGIN && slot_id <= EmuConstants::EQUIPMENT_END) || + slot_id == MainPowerSource) && + inst->GetItem()->Attuneable)) + inst->SetAttuned(true); - if (color > 0) - inst->SetColor(color); + if (color > 0) + inst->SetColor(color); - if(charges==0x7FFF) - inst->SetCharges(-1); - else if (charges == 0 && inst->IsStackable()) // Stackable items need a minimum charge of 1 remain moveable. + if (charges == 0x7FFF) + inst->SetCharges(-1); + else if (charges == 0 && + inst->IsStackable()) // Stackable items need a minimum charge of 1 remain moveable. inst->SetCharges(1); else - inst->SetCharges(charges); + inst->SetCharges(charges); + + if (item->RecastDelay) { + if (timestamps.count(item->RecastType)) + inst->SetRecastTimestamp(timestamps.at(item->RecastType)); + else + inst->SetRecastTimestamp(0); + } if (item->ItemClass == ItemClassCommon) { for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { @@ -575,114 +598,116 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) { } } - if (slot_id >= 8000 && slot_id <= 8999) - { - put_slot_id = inv->PushCursor(*inst); - } - else if (slot_id >= 3111 && slot_id <= 3179) - { - // Admins: please report any occurrences of this error - Log.Out(Logs::General, Logs::Error, "Warning: Defunct location for item in inventory: charid=%i, item_id=%i, slot_id=%i .. pushing to cursor...", char_id, item_id, slot_id); - put_slot_id = inv->PushCursor(*inst); - } - else - { + if (slot_id >= 8000 && slot_id <= 8999) { + put_slot_id = inv->PushCursor(*inst); + } else if (slot_id >= 3111 && slot_id <= 3179) { + // Admins: please report any occurrences of this error + Log.Out(Logs::General, Logs::Error, "Warning: Defunct location for item in inventory: " + "charid=%i, item_id=%i, slot_id=%i .. pushing to cursor...", + char_id, item_id, slot_id); + put_slot_id = inv->PushCursor(*inst); + } else { put_slot_id = inv->PutItem(slot_id, *inst); } - safe_delete(inst); + safe_delete(inst); - // Save ptr to item in inventory - if (put_slot_id == INVALID_INDEX) { - Log.Out(Logs::General, Logs::Error, "Warning: Invalid slot_id for item in inventory: charid=%i, item_id=%i, slot_id=%i",char_id, item_id, slot_id); - } - } + // Save ptr to item in inventory + if (put_slot_id == INVALID_INDEX) { + Log.Out(Logs::General, Logs::Error, + "Warning: Invalid slot_id for item in inventory: charid=%i, item_id=%i, slot_id=%i", + char_id, item_id, slot_id); + } + } - // Retrieve shared inventory + // Retrieve shared inventory return GetSharedBank(char_id, inv, true); } // Overloaded: Retrieve character inventory based on account_id and character name -bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv) { +bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv) +{ // Retrieve character inventory - std::string query = StringFormat("SELECT slotid, itemid, charges, color, augslot1, " - "augslot2, augslot3, augslot4, augslot5, augslot6, instnodrop, custom_data, ornamenticon, ornamentidfile, ornament_hero_model " - "FROM inventory INNER JOIN character_data ch " - "ON ch.id = charid WHERE ch.name = '%s' AND ch.account_id = %i ORDER BY slotid", - name, account_id); - auto results = QueryDatabase(query); - if (!results.Success()){ - Log.Out(Logs::General, Logs::Error, "If you got an error related to the 'instnodrop' field, run the following SQL Queries:\nalter table inventory add instnodrop tinyint(1) unsigned default 0 not null;\n"); - return false; + std::string query = + StringFormat("SELECT slotid, itemid, charges, color, augslot1, " + "augslot2, augslot3, augslot4, augslot5, augslot6, instnodrop, custom_data, ornamenticon, " + "ornamentidfile, ornament_hero_model " + "FROM inventory INNER JOIN character_data ch " + "ON ch.id = charid WHERE ch.name = '%s' AND ch.account_id = %i ORDER BY slotid", + name, account_id); + auto results = QueryDatabase(query); + if (!results.Success()) { + Log.Out(Logs::General, Logs::Error, "If you got an error related to the 'instnodrop' field, run the " + "following SQL Queries:\nalter table inventory add instnodrop " + "tinyint(1) unsigned default 0 not null;\n"); + return false; } + for (auto row = results.begin(); row != results.end(); ++row) { + int16 slot_id = atoi(row[0]); + uint32 item_id = atoi(row[1]); + int8 charges = atoi(row[2]); + uint32 color = atoul(row[3]); - for (auto row = results.begin(); row != results.end(); ++row) { - int16 slot_id = atoi(row[0]); - uint32 item_id = atoi(row[1]); - int8 charges = atoi(row[2]); - uint32 color = atoul(row[3]); - - uint32 aug[EmuConstants::ITEM_COMMON_SIZE]; - aug[0] = (uint32)atoi(row[4]); - aug[1] = (uint32)atoi(row[5]); - aug[2] = (uint32)atoi(row[6]); - aug[3] = (uint32)atoi(row[7]); - aug[4] = (uint32)atoi(row[8]); + uint32 aug[EmuConstants::ITEM_COMMON_SIZE]; + aug[0] = (uint32)atoi(row[4]); + aug[1] = (uint32)atoi(row[5]); + aug[2] = (uint32)atoi(row[6]); + aug[3] = (uint32)atoi(row[7]); + aug[4] = (uint32)atoi(row[8]); aug[5] = (uint32)atoi(row[9]); - bool instnodrop = (row[10] && (uint16)atoi(row[10])) ? true : false; + bool instnodrop = (row[10] && (uint16)atoi(row[10])) ? true : false; uint32 ornament_icon = (uint32)atoul(row[12]); uint32 ornament_idfile = (uint32)atoul(row[13]); uint32 ornament_hero_model = (uint32)atoul(row[14]); - - const Item_Struct* item = GetItem(item_id); - int16 put_slot_id = INVALID_INDEX; - if(!item) - continue; - ItemInst* inst = CreateBaseItem(item, charges); + const Item_Struct *item = GetItem(item_id); + int16 put_slot_id = INVALID_INDEX; + if (!item) + continue; + + ItemInst *inst = CreateBaseItem(item, charges); if (inst == nullptr) continue; - inst->SetAttuned(instnodrop); + inst->SetAttuned(instnodrop); - if(row[11]) { - std::string data_str(row[11]); - std::string idAsString; - std::string value; - bool use_id = true; + if (row[11]) { + std::string data_str(row[11]); + std::string idAsString; + std::string value; + bool use_id = true; - for(int i = 0; i < data_str.length(); ++i) { - if(data_str[i] == '^') { - if(!use_id) { - inst->SetCustomData(idAsString, value); - idAsString.clear(); - value.clear(); - } + for (int i = 0; i < data_str.length(); ++i) { + if (data_str[i] == '^') { + if (!use_id) { + inst->SetCustomData(idAsString, value); + idAsString.clear(); + value.clear(); + } - use_id = !use_id; - continue; - } + use_id = !use_id; + continue; + } - char v = data_str[i]; - if(use_id) - idAsString.push_back(v); - else - value.push_back(v); + char v = data_str[i]; + if (use_id) + idAsString.push_back(v); + else + value.push_back(v); + } + } - } - } - inst->SetOrnamentIcon(ornament_icon); inst->SetOrnamentationIDFile(ornament_idfile); inst->SetOrnamentHeroModel(ornament_hero_model); - if (color > 0) - inst->SetColor(color); + if (color > 0) + inst->SetColor(color); - inst->SetCharges(charges); + inst->SetCharges(charges); if (item->ItemClass == ItemClassCommon) { for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { @@ -691,43 +716,77 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv) } } - if (slot_id>=8000 && slot_id <= 8999) - put_slot_id = inv->PushCursor(*inst); - else - put_slot_id = inv->PutItem(slot_id, *inst); + if (slot_id >= 8000 && slot_id <= 8999) + put_slot_id = inv->PushCursor(*inst); + else + put_slot_id = inv->PutItem(slot_id, *inst); - safe_delete(inst); + safe_delete(inst); - // Save ptr to item in inventory - if (put_slot_id == INVALID_INDEX) - Log.Out(Logs::General, Logs::Error, "Warning: Invalid slot_id for item in inventory: name=%s, acctid=%i, item_id=%i, slot_id=%i", name, account_id, item_id, slot_id); + // Save ptr to item in inventory + if (put_slot_id == INVALID_INDEX) + Log.Out(Logs::General, Logs::Error, "Warning: Invalid slot_id for item in inventory: name=%s, " + "acctid=%i, item_id=%i, slot_id=%i", + name, account_id, item_id, slot_id); + } - } - - // Retrieve shared inventory + // Retrieve shared inventory return GetSharedBank(account_id, inv, false); } +std::map SharedDatabase::GetItemRecastTimestamps(uint32 char_id) +{ + std::map timers; + std::string query = StringFormat("SELECT recast_type,timestamp FROM character_item_recast WHERE id=%u", char_id); + auto results = QueryDatabase(query); + if (!results.Success() || results.RowCount() == 0) + return timers; -void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id) { + for (auto row = results.begin(); row != results.end(); ++row) + timers[atoul(row[0])] = atoul(row[1]); + return timers; // RVO or move assigned +} + +uint32 SharedDatabase::GetItemRecastTimestamp(uint32 char_id, uint32 recast_type) +{ + std::string query = StringFormat("SELECT timestamp FROM character_item_recast WHERE id=%u AND recast_type=%u", + char_id, recast_type); + auto results = QueryDatabase(query); + if (!results.Success() || results.RowCount() == 0) + return 0; + + auto row = results.begin(); + return static_cast(atoul(row[0])); +} + +void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id) +{ + // This actually isn't strictly live-like. Live your recast timestamps are forever + std::string query = + StringFormat("DELETE FROM character_item_recast WHERE id = %u and timestamp < UNIX_TIMESTAMP()", char_id); + QueryDatabase(query); +} + +void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id) +{ item_count = -1; max_id = 0; const std::string query = "SELECT MAX(id), count(*) FROM items"; auto results = QueryDatabase(query); if (!results.Success()) { - return; + return; } if (results.RowCount() == 0) - return; + return; - auto row = results.begin(); + auto row = results.begin(); - if(row[0]) - max_id = atoi(row[0]); + if (row[0]) + max_id = atoi(row[0]); - if (row[1]) + if (row[1]) item_count = atoi(row[1]); } diff --git a/common/shareddb.h b/common/shareddb.h index 073c385e8..aef325380 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -11,6 +11,7 @@ #include "fixed_memory_variable_hash_set.h" #include +#include class EvolveInfo; class Inventory; @@ -69,6 +70,9 @@ class SharedDatabase : public Database bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add); bool GetInventory(uint32 char_id, Inventory* inv); bool GetInventory(uint32 account_id, char* name, Inventory* inv); + std::map GetItemRecastTimestamps(uint32 char_id); + uint32 GetItemRecastTimestamp(uint32 char_id, uint32 recast_type); + void ClearOldRecastTimestamps(uint32 char_id); bool SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin); diff --git a/common/spdat.cpp b/common/spdat.cpp index 4b847b75e..e52a06e2e 100644 --- a/common/spdat.cpp +++ b/common/spdat.cpp @@ -19,7 +19,7 @@ /* - solar: General outline of spell casting process + General outline of spell casting process 1. a) Client clicks a spell bar gem, ability, or item. client_process.cpp diff --git a/common/spdat.h b/common/spdat.h index ed8a86e20..b70d708f0 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -618,7 +618,7 @@ typedef enum { #define DF_Permanent 50 -// solar: note this struct is historical, we don't actually need it to be +// note this struct is historical, we don't actually need it to be // aligned to anything, but for maintaining it it is kept in the order that // the fields in the text file are. the numbering is not offset, but field // number. note that the id field is counted as 0, this way the numbers diff --git a/common/string_util.cpp b/common/string_util.cpp index eb1f333f0..a7e5f2af1 100644 --- a/common/string_util.cpp +++ b/common/string_util.cpp @@ -256,7 +256,7 @@ bool atobool(const char* iBool) { return false; } -// solar: removes the crap and turns the underscores into spaces. +// removes the crap and turns the underscores into spaces. char *CleanMobName(const char *in, char *out) { unsigned i, j; diff --git a/common/struct_strategy.cpp b/common/struct_strategy.cpp index 49f422177..ea50c9158 100644 --- a/common/struct_strategy.cpp +++ b/common/struct_strategy.cpp @@ -5,6 +5,7 @@ #include "eq_stream.h" #include +#include //note: all encoders and decoders must be valid functions. @@ -17,7 +18,7 @@ StructStrategy::StructStrategy() { } } -void StructStrategy::Encode(EQApplicationPacket **p, EQStream *dest, bool ack_req) const { +void StructStrategy::Encode(EQApplicationPacket **p, std::shared_ptr dest, bool ack_req) const { if((*p)->GetOpcodeBypass() != 0) { PassEncoder(p, dest, ack_req); return; @@ -35,7 +36,7 @@ void StructStrategy::Decode(EQApplicationPacket *p) const { } -void StructStrategy::ErrorEncoder(EQApplicationPacket **in_p, EQStream *dest, bool ack_req) { +void StructStrategy::ErrorEncoder(EQApplicationPacket **in_p, std::shared_ptr dest, bool ack_req) { EQApplicationPacket *p = *in_p; *in_p = nullptr; @@ -49,7 +50,7 @@ void StructStrategy::ErrorDecoder(EQApplicationPacket *p) { p->SetOpcode(OP_Unknown); } -void StructStrategy::PassEncoder(EQApplicationPacket **p, EQStream *dest, bool ack_req) { +void StructStrategy::PassEncoder(EQApplicationPacket **p, std::shared_ptr dest, bool ack_req) { dest->FastQueuePacket(p, ack_req); } diff --git a/common/struct_strategy.h b/common/struct_strategy.h index a6219a214..f81881c26 100644 --- a/common/struct_strategy.h +++ b/common/struct_strategy.h @@ -7,11 +7,12 @@ class EQStream; #include "clientversions.h" #include +#include class StructStrategy { public: //the encoder takes ownership of the supplied packet, and may enqueue multiple resulting packets into the stream - typedef void (*Encoder)(EQApplicationPacket **p, EQStream *dest, bool ack_req); + typedef void(*Encoder)(EQApplicationPacket **p, std::shared_ptr dest, bool ack_req); //the decoder may only edit the supplied packet, producing a single packet for eqemu to consume. typedef void (*Decoder)(EQApplicationPacket *p); @@ -19,7 +20,7 @@ public: virtual ~StructStrategy() {} //this method takes an eqemu struct, and enqueues the produced structs into the stream. - void Encode(EQApplicationPacket **p, EQStream *dest, bool ack_req) const; + void Encode(EQApplicationPacket **p, std::shared_ptr dest, bool ack_req) const; //this method takes an EQ wire struct, and converts it into an eqemu struct void Decode(EQApplicationPacket *p) const; @@ -29,10 +30,10 @@ public: protected: //some common coders: //Print an error saying unknown struct/opcode and drop it - static void ErrorEncoder(EQApplicationPacket **p, EQStream *dest, bool ack_req); + static void ErrorEncoder(EQApplicationPacket **p, std::shared_ptr dest, bool ack_req); static void ErrorDecoder(EQApplicationPacket *p); //pass the packet through without modification (emu == EQ) (default) - static void PassEncoder(EQApplicationPacket **p, EQStream *dest, bool ack_req); + static void PassEncoder(EQApplicationPacket **p, std::shared_ptr dest, bool ack_req); static void PassDecoder(EQApplicationPacket *p); Encoder encoders[_maxEmuOpcode]; diff --git a/common/tcp_connection.cpp b/common/tcp_connection.cpp index 7a393c8f5..aa687cc01 100644 --- a/common/tcp_connection.cpp +++ b/common/tcp_connection.cpp @@ -69,7 +69,7 @@ TCPConnection::TCPConnection() //server version TCPConnection::TCPConnection(uint32 ID, SOCKET in_socket, uint32 irIP, uint16 irPort) -: ConnectionType(Incomming), +: ConnectionType(Incoming), connection_socket(in_socket), id(ID), rIP(irIP), @@ -104,7 +104,7 @@ TCPConnection::~TCPConnection() { } #if TCPN_DEBUG_Memory >= 5 else { - std::cout << "Deconstructor on incomming TCP# " << GetID() << std::endl; + std::cout << "Deconstructor on incoming TCP# " << GetID() << std::endl; } #endif safe_delete_array(recvbuf); diff --git a/common/tcp_connection.h b/common/tcp_connection.h index db38c941b..ae02b9c56 100644 --- a/common/tcp_connection.h +++ b/common/tcp_connection.h @@ -55,7 +55,7 @@ #ifndef DEF_eConnectionType #define DEF_eConnectionType -enum eConnectionType {Incomming, Outgoing}; +enum eConnectionType {Incoming, Outgoing}; #endif diff --git a/common/version.h b/common/version.h index 624418df5..5841a4119 100644 --- a/common/version.h +++ b/common/version.h @@ -30,7 +30,7 @@ Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9069 +#define CURRENT_BINARY_DATABASE_VERSION 9073 #define COMPILE_DATE __DATE__ #define COMPILE_TIME __TIME__ #ifndef WIN32 diff --git a/loginserver/client.cpp b/loginserver/client.cpp index bd1f282a5..fe43e6675 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -24,7 +24,7 @@ extern ErrorLog *server_log; extern LoginServer server; -Client::Client(EQStream *c, LSClientVersion v) +Client::Client(std::shared_ptr c, LSClientVersion v) { connection = c; version = v; diff --git a/loginserver/client.h b/loginserver/client.h index b20e5ae91..0f5efb1f1 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -59,7 +59,7 @@ public: /** * Constructor, sets our connection to c and version to v */ - Client(EQStream *c, LSClientVersion v); + Client(std::shared_ptr c, LSClientVersion v); /** * Destructor. @@ -129,11 +129,11 @@ public: /** * Gets the connection for this client. */ - EQStream *GetConnection() { return connection; } + std::shared_ptr GetConnection() { return connection; } EQEmu::Random random; private: - EQStream *connection; + std::shared_ptr connection; LSClientVersion version; LSClientStatus status; diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index d6f6b760f..eb982f613 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -94,7 +94,7 @@ ClientManager::~ClientManager() void ClientManager::Process() { ProcessDisconnect(); - EQStream *cur = titanium_stream->Pop(); + std::shared_ptr cur = titanium_stream->Pop(); while(cur) { struct in_addr in; @@ -141,7 +141,7 @@ void ClientManager::ProcessDisconnect() list::iterator iter = clients.begin(); while(iter != clients.end()) { - EQStream *c = (*iter)->GetConnection(); + std::shared_ptr c = (*iter)->GetConnection(); if(c->CheckClosed()) { server_log->Log(log_network, "Client disconnected from the server, removing client."); diff --git a/ucs/clientlist.cpp b/ucs/clientlist.cpp index a643cdfa9..bd79822ab 100644 --- a/ucs/clientlist.cpp +++ b/ucs/clientlist.cpp @@ -485,7 +485,7 @@ Clientlist::Clientlist(int ChatPort) { } } -Client::Client(EQStream *eqs) { +Client::Client(std::shared_ptr eqs) { ClientStream = eqs; @@ -574,7 +574,7 @@ void Clientlist::CheckForStaleConnections(Client *c) { void Clientlist::Process() { - EQStream *eqs; + std::shared_ptr eqs; while((eqs = chatsf->Pop())) { diff --git a/ucs/clientlist.h b/ucs/clientlist.h index 266986542..79b1359b7 100644 --- a/ucs/clientlist.h +++ b/ucs/clientlist.h @@ -84,10 +84,10 @@ struct CharacterEntry { class Client { public: - Client(EQStream* eqs); + Client(std::shared_ptr eqs); ~Client(); - EQStream *ClientStream; + std::shared_ptr ClientStream; void AddCharacter(int CharID, const char *CharacterName, int Level); void ClearCharacters() { Characters.clear(); } void SendMailBoxes(); diff --git a/ucs/database.cpp b/ucs/database.cpp index 75be71377..b80b4fb78 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -195,7 +195,7 @@ bool Database::VerifyMailKey(std::string characterName, int IPAddress, std::stri else sprintf(combinedKey, "%s", MailKey.c_str()); - Log.Out(Logs::Detail, Logs::UCS_Server, "DB key is [%s], Client key is [%s]", row[0], combinedKey); + Log.Out(Logs::Detail, Logs::UCS_Server, "DB key is [%s], Client key is [%s]", (row[0] ? row[0] : ""), combinedKey); return !strcmp(row[0], combinedKey); } diff --git a/utils/patches/patch_Underfoot.conf b/utils/patches/patch_UF.conf similarity index 100% rename from utils/patches/patch_Underfoot.conf rename to utils/patches/patch_UF.conf diff --git a/utils/scripts/eqemu_update.pl b/utils/scripts/eqemu_update.pl index 21ef05b73..04c5367b3 100644 --- a/utils/scripts/eqemu_update.pl +++ b/utils/scripts/eqemu_update.pl @@ -325,7 +325,7 @@ sub OpCodes_Fetch{ 3 => ["Titanium", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_Titanium.conf"], 4 => ["Secrets of Faydwer", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_SoF.conf"], 5 => ["Seeds of Destruction", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_SoD.conf"], - 6 => ["Underfoot", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_Underfoot.conf"], + 6 => ["Underfoot", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_UF.conf"], 7 => ["Rain of Fear", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_RoF.conf"], 8 => ["Rain of Fear 2", "https://raw.githubusercontent.com/EQEmu/Server/master/utils/patches/patch_RoF2.conf"], ); diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index e76c74852..be99178a3 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -323,6 +323,10 @@ 9067|2015_01_21_npc_types_update.sql|SHOW COLUMNS FROM `npc_types` LIKE 'light'|empty| 9068|2015_01_15_logsys_categories_table.sql|SHOW TABLES LIKE 'logsys_categories'|empty| 9069|2015_01_25_logsys_Mercenaries_category.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Mercenaries'|empty| +9070|2015_01_28_quest_debug_log_category.sql|SELECT * FROM `logsys_categories` WHERE `log_category_description` LIKE 'Quest Debug'|empty| +9071|2015_01_29_merc_stats_table_update.sql|SHOW COLUMNS FROM `merc_stats` LIKE 'statscale'|empty| +9072|2015_01_30_merc_attack_delay.sql|SHOW COLUMNS FROM `merc_stats` LIKE 'attack_delay'|empty| +9073|2015_01_31_character_item_recast.sql|SHOW TABLES LIKE 'character_item_recast'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/optional/2015_01_25_MyFaction_Stored_Procedure.sql b/utils/sql/git/optional/2015_01_25_MyFaction_Stored_Procedure.sql index 91d386289..da2bf04da 100644 --- a/utils/sql/git/optional/2015_01_25_MyFaction_Stored_Procedure.sql +++ b/utils/sql/git/optional/2015_01_25_MyFaction_Stored_Procedure.sql @@ -1,8 +1,6 @@ DELIMITER $$ -use peqdb - -CREATE DEFINER=`eqemu`@`%` PROCEDURE `MyFaction`(charname text) +CREATE PROCEDURE `MyFaction`(charname text) BEGIN declare class_mod text default ""; declare race_mod text default ""; @@ -24,7 +22,9 @@ SELECT race_mod as R, class_mod as C, deity_mod as D, f.name as faction, f.id, v @race_bump := IFNULL((select m.mod from faction_list_mod m where faction_id = f.id && race_mod != "" && mod_name = race_mod),0) as race_bump, @deity_bump := IFNULL((select m.mod from faction_list_mod m where faction_id = f.id && race_mod != "" && mod_name = deity_mod),0) as deity_bump, v.current_value + f.base + @class_bump + @race_bump + @deity_bump as TOTAL -FROM peqdb.faction_values v +FROM faction_values v inner join faction_list f on f.id = v.faction_id where v.char_id = (select id from character_data where name=charname) ; -END +END $$ + +DELIMITER ; diff --git a/utils/sql/git/optional/2015_01_30_poknowledge_spell_vendors.sql b/utils/sql/git/optional/2015_01_30_poknowledge_spell_vendors.sql new file mode 100644 index 000000000..7868602fe --- /dev/null +++ b/utils/sql/git/optional/2015_01_30_poknowledge_spell_vendors.sql @@ -0,0 +1,4010 @@ +DELETE FROM merchantlist WHERE merchantid = 202229; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202229, 1, 15700, -1100, 65535), + (202229, 2, 15703, -1100, 65535), + (202229, 3, 15720, -1100, 65535), + (202229, 4, 15717, -1100, 65535), + (202229, 5, 15007, -1100, 65535), + (202229, 6, 15734, -1100, 65535), + (202229, 7, 15728, -1100, 65535), + (202229, 8, 15710, -1100, 65535), + (202229, 9, 7701, -1100, 65535), + (202229, 10, 15701, -1100, 65535), + (202229, 11, 15708, -1100, 65535), + (202229, 12, 15704, -1100, 65535), + (202229, 13, 15711, -1100, 65535), + (202229, 14, 15737, -1100, 65535), + (202229, 15, 15724, -1100, 65535), + (202229, 16, 7702, -1100, 65535), + (202229, 17, 15729, -1100, 65535), + (202229, 18, 15709, -1100, 65535), + (202229, 19, 15730, -1100, 65535), + (202229, 20, 15719, -1100, 65535), + (202229, 21, 15705, -1100, 65535), + (202229, 22, 19504, -1100, 65535), + (202229, 23, 15739, -1100, 65535), + (202229, 24, 15727, -1100, 65535), + (202229, 25, 15738, -1100, 65535), + (202229, 26, 15735, -1100, 65535), + (202229, 27, 15712, -1100, 65535), + (202229, 28, 59807, -1100, 65535); + +UPDATE npc_types SET lastname = 'Bard Songs 1-25' WHERE name = 'Minstrel_Eoweril'; + +UPDATE spawn2 SET x = '1000.00', y = '69.00', z = '-60.68', heading = '90.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Minstrel_Eoweril') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202233; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202233, 1, 15746, -1100, 65535), + (202233, 2, 30450, -1100, 65535), + (202233, 3, 7705, -1100, 65535), + (202233, 4, 15747, -1100, 65535), + (202233, 5, 30449, -1100, 65535), + (202233, 6, 26954, -1100, 65535), + (202233, 7, 15742, -1100, 65535), + (202233, 8, 15745, -1100, 65535), + (202233, 9, 15749, -1100, 65535), + (202233, 10, 59002, -1100, 65535), + (202233, 11, 59603, -1100, 65535), + (202233, 12, 15744, -1100, 65535), + (202233, 13, 15748, -1100, 65535), + (202233, 14, 15706, -1100, 65535), + (202233, 15, 15725, -1100, 65535), + (202233, 16, 15741, -1100, 65535), + (202233, 17, 15715, -1100, 65535), + (202233, 18, 15707, -1100, 65535), + (202233, 19, 7703, -1100, 65535), + (202233, 20, 15718, -1100, 65535), + (202233, 21, 15723, -1100, 65535), + (202233, 22, 15713, -1100, 65535), + (202233, 23, 15721, -1100, 65535), + (202233, 24, 30448, -1100, 65535), + (202233, 25, 15736, -1100, 65535), + (202233, 26, 15740, -1100, 65535), + (202233, 27, 15716, -1100, 65535), + (202233, 28, 15743, -1100, 65535), + (202233, 29, 15750, -1100, 65535), + (202233, 30, 7704, -1100, 65535), + (202233, 31, 15726, -1100, 65535), + (202233, 32, 24547, -1100, 65535), + (202233, 33, 15714, -1100, 65535), + (202233, 34, 15702, -1100, 65535), + (202233, 35, 26953, -1100, 65535); + +UPDATE npc_types SET lastname = 'Bard Songs 26-50' WHERE name = 'Minstrel_Joet'; + +UPDATE spawn2 SET x = '945.00', y = '84.00', z = '-60.25', heading = '90.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Minstrel_Joet') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202232; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202232, 1, 19450, -1100, 65535), + (202232, 2, 19451, -1100, 65535), + (202232, 3, 19452, -1100, 65535), + (202232, 4, 7706, -1100, 65535), + (202232, 5, 59001, -1100, 65535), + (202232, 6, 19453, -1100, 65535), + (202232, 7, 19454, -1100, 65535), + (202232, 8, 59604, -1100, 65535), + (202232, 9, 19457, -1100, 65535), + (202232, 10, 19458, -1100, 65535), + (202232, 11, 7707, -1100, 65535), + (202232, 12, 19459, -1100, 65535), + (202232, 13, 19468, -1100, 65535), + (202232, 14, 30451, -1100, 65535), + (202232, 15, 78024, -1100, 65535), + (202232, 16, 19455, -1100, 65535), + (202232, 17, 19456, -1100, 65535), + (202232, 18, 7708, -1100, 65535), + (202232, 19, 19460, -1100, 65535), + (202232, 20, 19461, -1100, 65535), + (202232, 21, 19462, -1100, 65535), + (202232, 22, 19463, -1100, 65535), + (202232, 23, 24548, -1100, 65535), + (202232, 24, 7709, -1100, 65535), + (202232, 25, 19464, -1100, 65535), + (202232, 26, 19465, -1100, 65535), + (202232, 27, 19466, -1100, 65535), + (202232, 28, 19467, -1100, 65535), + (202232, 29, 30452, -1100, 65535), + (202232, 30, 30479, -1100, 65535), + (202232, 31, 7710, -1100, 65535), + (202232, 32, 59653, -1100, 65535); + +UPDATE npc_types SET lastname = 'Bard Songs 51-60' WHERE name = 'Minstrel_Gwiar'; + +UPDATE spawn2 SET x = '917.00', y = '62.00', z = '-60.87', heading = '272.11' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Minstrel_Gwiar') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202231; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202231, 1, 28474, -1100, 65535), + (202231, 2, 28475, -1100, 65535), + (202231, 3, 28484, -1100, 65535), + (202231, 4, 77853, -1100, 65535), + (202231, 5, 28478, -1100, 65535), + (202231, 6, 28480, -1100, 65535), + (202231, 7, 28483, -1100, 65535), + (202231, 8, 21650, -1100, 65535), + (202231, 9, 28472, -1100, 65535), + (202231, 10, 28479, -1100, 65535), + (202231, 11, 28481, -1100, 65535), + (202231, 12, 28482, -1100, 65535), + (202231, 13, 28477, -1100, 65535), + (202231, 14, 28471, -1100, 65535), + (202231, 15, 28473, -1100, 65535), + (202231, 16, 28476, -1100, 65535), + (202231, 17, 76040, -1100, 65535), + (202231, 18, 16391, -1100, 65535), + (202231, 19, 21636, -1100, 65535), + (202231, 20, 28485, -1100, 65535), + (202231, 21, 28486, -1100, 65535), + (202231, 22, 59808, -1100, 65535), + (202231, 23, 59812, -1100, 65535), + (202231, 24, 59811, -1100, 65535), + (202231, 25, 59810, -1100, 65535), + (202231, 26, 77113, -1100, 65535), + (202231, 27, 77111, -1100, 65535), + (202231, 28, 77112, -1100, 65535), + (202231, 29, 77854, -1100, 65535), + (202231, 30, 77118, -1100, 65535), + (202231, 31, 77114, -1100, 65535), + (202231, 32, 77120, -1100, 65535), + (202231, 33, 77116, -1100, 65535), + (202231, 34, 77676, -1100, 65535), + (202231, 35, 77119, -1100, 65535), + (202231, 36, 77117, -1100, 65535), + (202231, 37, 77121, -1100, 65535), + (202231, 38, 41289, -1100, 65535), + (202231, 39, 77124, -1100, 65535), + (202231, 40, 77122, -1100, 65535), + (202231, 41, 77115, -1100, 65535), + (202231, 42, 76024, -1100, 65535), + (202231, 43, 77123, -1100, 65535), + (202231, 44, 77125, -1100, 65535), + (202231, 45, 77126, -1100, 65535), + (202231, 46, 77992, -1100, 65535), + (202231, 47, 43569, -1100, 65535); + +UPDATE npc_types SET lastname = 'Bard Songs 61-70' WHERE name = 'Minstrel_Silnon'; + +UPDATE spawn2 SET x = '851.00', y = '21.00', z = '-60.68', heading = '181.41' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Minstrel_Silnon') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202157; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202157, 1, 66200, -1100, 65535), + (202157, 2, 66201, -1100, 65535), + (202157, 3, 66210, -1100, 65535), + (202157, 4, 66211, -1100, 65535), + (202157, 5, 41288, -1100, 65535); + +UPDATE npc_types SET lastname = 'Bard Tomes' WHERE name = 'Larquin_Julinok'; + +UPDATE spawn2 SET x = '1092.00', y = '-114.00', z = '33.32', heading = '177.89' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Larquin_Julinok') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202224; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202224, 1, 15201, -1100, 65535), + (202224, 2, 15200, -1100, 65535), + (202224, 3, 15267, -1100, 65535), + (202224, 4, 7712, -1100, 65535), + (202224, 5, 7711, -1100, 65535), + (202224, 6, 15224, -1100, 65535), + (202224, 7, 15274, -1100, 65535), + (202224, 8, 15271, -1100, 65535), + (202224, 9, 28720, -1100, 65535), + (202224, 10, 15203, -1100, 65535), + (202224, 11, 7735, -1100, 65535), + (202224, 12, 15040, -1100, 65535), + (202224, 13, 15075, -1100, 65535), + (202224, 14, 7713, -1100, 65535), + (202224, 15, 7733, -1100, 65535), + (202224, 16, 15276, -1100, 65535), + (202224, 17, 15211, -1100, 65535), + (202224, 18, 15279, -1100, 65535), + (202224, 19, 15227, -1100, 65535), + (202224, 20, 7736, -1100, 65535), + (202224, 21, 59971, -1100, 65535), + (202224, 22, 15238, -1100, 65535), + (202224, 23, 15225, -1100, 65535), + (202224, 24, 15213, -1100, 65535), + (202224, 25, 15277, -1100, 65535), + (202224, 26, 26970, -1100, 65535), + (202224, 27, 15017, -1100, 65535), + (202224, 28, 15270, -1100, 65535), + (202224, 29, 7714, -1100, 65535), + (202224, 30, 15226, -1100, 65535), + (202224, 31, 15345, -1100, 65535), + (202224, 32, 15278, -1100, 65535), + (202224, 33, 15086, -1100, 65535); + +UPDATE npc_types SET lastname = 'Beastlord Spells 1-25' WHERE name = 'Primalist_Saosith'; + +UPDATE spawn2 SET x = '926.00', y = '-116.00', z = '98.38', heading = '178.59' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Primalist_Saosith') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202228; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202228, 1, 7718, -1100, 65535), + (202228, 2, 59648, -1100, 65535), + (202228, 3, 59009, -1100, 65535), + (202228, 4, 15151, -1100, 65535), + (202228, 5, 19498, -1100, 65535), + (202228, 6, 19200, -1100, 65535), + (202228, 7, 15042, -1100, 65535), + (202228, 8, 15162, -1100, 65535), + (202228, 9, 59649, -1100, 65535), + (202228, 10, 15096, -1100, 65535), + (202228, 11, 7721, -1100, 65535), + (202228, 12, 7739, -1100, 65535), + (202228, 13, 15308, -1100, 65535), + (202228, 14, 26956, -1100, 65535), + (202228, 15, 15649, -1100, 65535), + (202228, 16, 7720, -1100, 65535), + (202228, 17, 59650, -1100, 65535), + (202228, 18, 7734, -1100, 65535), + (202228, 19, 15282, -1100, 65535), + (202228, 20, 15283, -1100, 65535), + (202228, 21, 7715, -1100, 65535), + (202228, 22, 15147, -1100, 65535), + (202228, 23, 7737, -1100, 65535), + (202228, 24, 15050, -1100, 65535), + (202228, 25, 15079, -1100, 65535), + (202228, 26, 7716, -1100, 65535), + (202228, 27, 19502, -1100, 65535), + (202228, 28, 15261, -1100, 65535), + (202228, 29, 26955, -1100, 65535), + (202228, 30, 15228, -1100, 65535), + (202228, 31, 15048, -1100, 65535), + (202228, 32, 15434, -1100, 65535), + (202228, 33, 7717, -1100, 65535), + (202228, 34, 15012, -1100, 65535), + (202228, 35, 7719, -1100, 65535), + (202228, 36, 15149, -1100, 65535), + (202228, 37, 15146, -1100, 65535), + (202228, 38, 7738, -1100, 65535); + +UPDATE npc_types SET lastname = 'Beastlord Spells 26-50' WHERE name = 'Primalist_Worenon'; + +UPDATE spawn2 SET x = '998.00', y = '-114.00', z = '99.50', heading = '176.48' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Primalist_Worenon') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202227; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202227, 1, 15046, -1100, 65535), + (202227, 2, 15063, -1100, 65535), + (202227, 3, 7740, -1100, 65535), + (202227, 4, 15161, -1100, 65535), + (202227, 5, 15435, -1100, 65535), + (202227, 6, 7722, -1100, 65535), + (202227, 7, 19499, -1100, 65535), + (202227, 8, 59010, -1100, 65535), + (202227, 9, 15152, -1100, 65535), + (202227, 10, 15167, -1100, 65535), + (202227, 11, 7741, -1100, 65535), + (202227, 12, 15062, -1100, 65535), + (202227, 13, 15153, -1100, 65535), + (202227, 14, 7723, -1100, 65535), + (202227, 15, 19531, -1100, 65535), + (202227, 16, 26957, -1100, 65535), + (202227, 17, 15145, -1100, 65535), + (202227, 18, 7724, -1100, 65535), + (202227, 19, 7725, -1100, 65535), + (202227, 20, 15163, -1100, 65535), + (202227, 21, 15431, -1100, 65535), + (202227, 22, 7726, -1100, 65535), + (202227, 23, 19530, -1100, 65535), + (202227, 24, 15015, -1100, 65535), + (202227, 25, 15157, -1100, 65535), + (202227, 26, 15158, -1100, 65535), + (202227, 27, 15049, -1100, 65535), + (202227, 28, 15168, -1100, 65535), + (202227, 29, 7727, -1100, 65535), + (202227, 30, 59651, -1100, 65535), + (202227, 31, 15510, -1100, 65535), + (202227, 32, 7728, -1100, 65535), + (202227, 33, 7729, -1100, 65535), + (202227, 34, 15170, -1100, 65535), + (202227, 35, 7730, -1100, 65535), + (202227, 36, 7731, -1100, 65535), + (202227, 37, 19537, -1100, 65535), + (202227, 38, 19538, -1100, 65535); + +UPDATE npc_types SET lastname = 'Beastlord Spells 51-60' WHERE name = 'Primalist_Nydalith'; + +UPDATE spawn2 SET x = '1055.00', y = '-115.00', z = '98.69', heading = '181.41' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Primalist_Nydalith') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202226; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202226, 1, 59813, -1100, 65535), + (202226, 2, 77256, -1100, 65535), + (202226, 3, 77255, -1100, 65535), + (202226, 4, 77258, -1100, 65535), + (202226, 5, 77257, -1100, 65535), + (202226, 6, 77259, -1100, 65535), + (202226, 7, 77261, -1100, 65535), + (202226, 8, 77260, -1100, 65535), + (202226, 9, 77262, -1100, 65535), + (202226, 10, 41283, -1100, 65535), + (202226, 11, 77267, -1100, 65535), + (202226, 12, 77264, -1100, 65535), + (202226, 13, 15095, -1100, 65535), + (202226, 14, 19207, -1100, 65535), + (202226, 15, 77263, -1100, 65535), + (202226, 16, 77265, -1100, 65535), + (202226, 17, 76030, -1100, 65535), + (202226, 18, 77269, -1100, 65535), + (202226, 19, 77268, -1100, 65535), + (202226, 20, 77303, -1100, 65535), + (202226, 21, 77266, -1100, 65535), + (202226, 22, 43578, -1100, 65535), + (202226, 23, 17795, -1100, 65535), + (202226, 24, 19267, -1100, 65535), + (202226, 25, 21629, -1100, 65535), + (202226, 26, 28544, -1100, 65535), + (202226, 27, 28545, -1100, 65535), + (202226, 28, 76046, -1100, 65535), + (202226, 29, 19276, -1100, 65535), + (202226, 30, 19507, -1100, 65535), + (202226, 31, 28547, -1100, 65535), + (202226, 32, 28548, -1100, 65535), + (202226, 33, 15098, -1100, 65535), + (202226, 34, 15171, -1100, 65535), + (202226, 35, 19264, -1100, 65535), + (202226, 36, 21630, -1100, 65535), + (202226, 37, 28549, -1100, 65535), + (202226, 38, 28550, -1100, 65535), + (202226, 39, 19243, -1100, 65535), + (202226, 40, 28551, -1100, 65535), + (202226, 41, 28552, -1100, 65535), + (202226, 42, 59652, -1100, 65535), + (202226, 43, 15032, -1100, 65535), + (202226, 44, 19278, -1100, 65535), + (202226, 45, 28553, -1100, 65535), + (202226, 46, 28554, -1100, 65535), + (202226, 47, 59815, -1100, 65535), + (202226, 48, 59814, -1100, 65535); + +UPDATE npc_types SET lastname = 'Beastlord Spells 61-70' WHERE name = 'Primalist_Loerith'; + +UPDATE spawn2 SET x = '1102.00', y = '-58.00', z = '98.06', heading = '90.70' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Primalist_Loerith') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202155; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202155, 1, 66200, -1100, 65535), + (202155, 2, 66201, -1100, 65535), + (202155, 3, 66220, -1100, 65535), + (202155, 4, 66221, -1100, 65535), + (202155, 5, 41299, -1100, 65535), + (202155, 6, 78017, -1100, 65535); + +UPDATE npc_types SET lastname = 'Beastlord Tomes' WHERE name = 'Tana_Clawguard'; + +UPDATE spawn2 SET x = '1030.00', y = '-116.00', z = '34.38', heading = '177.89' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Tana_Clawguard') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202288; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202288, 1, 78022, -1100, 65535), + (202288, 2, 59928, -1100, 65535), + (202288, 3, 59925, -1100, 65535), + (202288, 4, 59888, -1100, 65535), + (202288, 5, 59904, -1100, 65535), + (202288, 6, 59921, -1100, 65535), + (202288, 7, 59931, -1100, 65535), + (202288, 8, 76052, -1100, 65535), + (202288, 9, 59929, -1100, 65535), + (202288, 10, 66410, -1100, 65535), + (202288, 11, 59917, -1100, 65535), + (202288, 12, 59887, -1100, 65535), + (202288, 13, 59900, -1100, 65535), + (202288, 14, 66201, -1100, 65535), + (202288, 15, 59901, -1100, 65535), + (202288, 16, 59890, -1100, 65535), + (202288, 17, 59902, -1100, 65535), + (202288, 18, 59915, -1100, 65535), + (202288, 19, 59926, -1100, 65535), + (202288, 20, 59885, -1100, 65535), + (202288, 21, 59924, -1100, 65535), + (202288, 22, 59903, -1100, 65535), + (202288, 23, 59891, -1100, 65535), + (202288, 24, 59905, -1100, 65535), + (202288, 25, 59930, -1100, 65535), + (202288, 26, 59918, -1100, 65535), + (202288, 27, 68774, -1100, 65535), + (202288, 28, 77300, -1100, 65535), + (202288, 29, 77296, -1100, 65535), + (202288, 30, 77297, -1100, 65535), + (202288, 31, 77298, -1100, 65535), + (202288, 32, 77675, -1100, 65535), + (202288, 33, 41271, -1100, 65535), + (202288, 34, 77299, -1100, 65535), + (202288, 35, 76035, -1100, 65535), + (202288, 36, 77295, -1100, 65535), + (202288, 37, 43566, -1100, 65535), + (202288, 38, 77986, -1100, 65535), + (202288, 39, 59927, -1100, 65535), + (202288, 40, 59916, -1100, 65535), + (202288, 41, 59922, -1100, 65535), + (202288, 42, 59892, -1100, 65535), + (202288, 43, 59973, -1100, 65535), + (202288, 44, 17709, -1100, 65535), + (202288, 45, 59893, -1100, 65535), + (202288, 46, 59883, -1100, 65535), + (202288, 47, 59894, -1100, 65535), + (202288, 48, 66412, -1100, 65535), + (202288, 49, 59895, -1100, 65535), + (202288, 50, 59886, -1100, 65535), + (202288, 51, 59896, -1100, 65535), + (202288, 52, 59889, -1100, 65535), + (202288, 53, 59897, -1100, 65535), + (202288, 54, 59898, -1100, 65535), + (202288, 55, 59914, -1100, 65535), + (202288, 56, 66200, -1100, 65535), + (202288, 57, 59884, -1100, 65535), + (202288, 58, 59899, -1100, 65535); + +UPDATE npc_types SET lastname = 'Berserker Tomes' WHERE name = 'Kurlond_Axebringer'; + +UPDATE spawn2 SET x = '796.00', y = '-99.00', z = '2.50', heading = '90.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Kurlond_Axebringer') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202289; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202289, 1, 59937, -1100, 65535), + (202289, 2, 59895, -1100, 65535), + (202289, 3, 59892, -1100, 65535), + (202289, 4, 59897, -1100, 65535), + (202289, 5, 59934, -1100, 65535), + (202289, 6, 59901, -1100, 65535), + (202289, 7, 59887, -1100, 65535), + (202289, 8, 59900, -1100, 65535), + (202289, 9, 59936, -1100, 65535), + (202289, 10, 59935, -1100, 65535), + (202289, 11, 59899, -1100, 65535), + (202289, 12, 59888, -1100, 65535), + (202289, 13, 59933, -1100, 65535), + (202289, 14, 59886, -1100, 65535), + (202289, 15, 59894, -1100, 65535), + (202289, 16, 59896, -1100, 65535), + (202289, 17, 59898, -1100, 65535), + (202289, 18, 59884, -1100, 65535), + (202289, 19, 59893, -1100, 65535), + (202289, 20, 59889, -1100, 65535), + (202289, 21, 59890, -1100, 65535), + (202289, 22, 59883, -1100, 65535); + +UPDATE npc_types SET lastname = 'Berserker Tomes' WHERE name = 'Gaddi_Buruca'; + +UPDATE spawn2 SET x = '797.00', y = '-87.00', z = '5.50', heading = '76.64' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Gaddi_Buruca') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202221; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202221, 1, 77003, -1100, 65535), + (202221, 2, 77004, -1100, 65535), + (202221, 3, 77009, -1100, 65535), + (202221, 4, 77008, -1100, 65535), + (202221, 5, 77012, -1100, 65535), + (202221, 6, 77010, -1100, 65535), + (202221, 7, 77011, -1100, 65535), + (202221, 8, 77006, -1100, 65535), + (202221, 9, 77831, -1100, 65535), + (202221, 10, 77016, -1100, 65535), + (202221, 11, 17871, -1100, 65535), + (202221, 12, 17872, -1100, 65535), + (202221, 13, 17796, -1100, 65535), + (202221, 14, 28572, -1100, 65535), + (202221, 15, 28646, -1100, 65535), + (202221, 16, 77842, -1100, 65535), + (202221, 17, 76036, -1100, 65535), + (202221, 18, 21690, -1100, 65535), + (202221, 19, 26945, -1100, 65535), + (202221, 20, 28558, -1100, 65535), + (202221, 21, 28563, -1100, 65535), + (202221, 22, 28566, -1100, 65535), + (202221, 23, 28567, -1100, 65535), + (202221, 24, 59578, -1100, 65535), + (202221, 25, 21647, -1100, 65535), + (202221, 26, 28569, -1100, 65535), + (202221, 27, 28571, -1100, 65535), + (202221, 28, 28573, -1100, 65535), + (202221, 29, 77830, -1100, 65535), + (202221, 30, 21692, -1100, 65535), + (202221, 31, 26946, -1100, 65535), + (202221, 32, 28559, -1100, 65535), + (202221, 33, 28560, -1100, 65535), + (202221, 34, 28562, -1100, 65535), + (202221, 35, 28564, -1100, 65535), + (202221, 36, 59579, -1100, 65535), + (202221, 37, 21689, -1100, 65535), + (202221, 38, 26947, -1100, 65535), + (202221, 39, 28555, -1100, 65535), + (202221, 40, 28565, -1100, 65535), + (202221, 41, 28568, -1100, 65535), + (202221, 42, 28570, -1100, 65535), + (202221, 43, 59821, -1100, 65535), + (202221, 44, 59819, -1100, 65535), + (202221, 45, 59820, -1100, 65535), + (202221, 46, 77001, -1100, 65535), + (202221, 47, 77002, -1100, 65535), + (202221, 48, 77843, -1100, 65535), + (202221, 49, 77005, -1100, 65535), + (202221, 50, 77013, -1100, 65535), + (202221, 51, 77014, -1100, 65535), + (202221, 52, 77015, -1100, 65535), + (202221, 53, 77007, -1100, 65535), + (202221, 54, 41272, -1100, 65535), + (202221, 55, 77020, -1100, 65535), + (202221, 56, 77019, -1100, 65535), + (202221, 57, 77017, -1100, 65535), + (202221, 58, 77018, -1100, 65535), + (202221, 59, 77021, -1100, 65535), + (202221, 60, 76020, -1100, 65535), + (202221, 61, 41273, -1100, 65535), + (202221, 62, 77024, -1100, 65535), + (202221, 63, 77025, -1100, 65535), + (202221, 64, 77026, -1100, 65535), + (202221, 65, 77022, -1100, 65535), + (202221, 66, 77023, -1100, 65535), + (202221, 67, 41274, -1100, 65535), + (202221, 68, 77998, -1100, 65535), + (202221, 69, 77996, -1100, 65535), + (202221, 70, 43571, -1100, 65535), + (202221, 71, 28556, -1100, 65535), + (202221, 72, 28557, -1100, 65535), + (202221, 73, 28561, -1100, 65535), + (202221, 74, 77275, -1100, 65535); + +UPDATE npc_types SET lastname = 'Cleric Spells 61-70' WHERE name = 'Vicar_Diarin'; + +UPDATE spawn2 SET x = '1048.00', y = '113.00', z = '-30.25', heading = '0.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Vicar_Diarin') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202222; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202222, 1, 17794, -1100, 65535), + (202222, 2, 17795, -1100, 65535), + (202222, 3, 78025, -1100, 65535), + (202222, 4, 15116, -1100, 65535), + (202222, 5, 15133, -1100, 65535), + (202222, 6, 19217, -1100, 65535), + (202222, 7, 19218, -1100, 65535), + (202222, 8, 7117, -1100, 65535), + (202222, 9, 7118, -1100, 65535), + (202222, 10, 19201, -1100, 65535), + (202222, 11, 19202, -1100, 65535), + (202222, 12, 19203, -1100, 65535), + (202222, 13, 19420, -1100, 65535), + (202222, 14, 59012, -1100, 65535), + (202222, 15, 19204, -1100, 65535), + (202222, 16, 19205, -1100, 65535), + (202222, 17, 19206, -1100, 65535), + (202222, 18, 19224, -1100, 65535), + (202222, 19, 7606, -1100, 65535), + (202222, 20, 19207, -1100, 65535), + (202222, 21, 19208, -1100, 65535), + (202222, 22, 19209, -1100, 65535), + (202222, 23, 19210, -1100, 65535), + (202222, 24, 19211, -1100, 65535), + (202222, 25, 19212, -1100, 65535), + (202222, 26, 7607, -1100, 65535), + (202222, 27, 19522, -1100, 65535), + (202222, 28, 59577, -1100, 65535), + (202222, 29, 19214, -1100, 65535), + (202222, 30, 19215, -1100, 65535), + (202222, 31, 19216, -1100, 65535), + (202222, 32, 30446, -1100, 65535), + (202222, 33, 7608, -1100, 65535), + (202222, 34, 77841, -1100, 65535), + (202222, 35, 19219, -1100, 65535), + (202222, 36, 19220, -1100, 65535), + (202222, 37, 19221, -1100, 65535), + (202222, 38, 19227, -1100, 65535), + (202222, 39, 77865, -1100, 65535), + (202222, 40, 19222, -1100, 65535), + (202222, 41, 19223, -1100, 65535), + (202222, 42, 19435, -1100, 65535), + (202222, 43, 7119, -1100, 65535), + (202222, 44, 7609, -1100, 65535), + (202222, 45, 15997, -1100, 65535), + (202222, 46, 19225, -1100, 65535), + (202222, 47, 19226, -1100, 65535), + (202222, 48, 7121, -1100, 65535), + (202222, 49, 77829, -1100, 65535), + (202222, 50, 19228, -1100, 65535), + (202222, 51, 19229, -1100, 65535), + (202222, 52, 19230, -1100, 65535), + (202222, 53, 30447, -1100, 65535), + (202222, 54, 7120, -1100, 65535), + (202222, 55, 7610, -1100, 65535), + (202222, 56, 15995, -1100, 65535), + (202222, 57, 19533, -1100, 65535); + +UPDATE npc_types SET lastname = 'Cleric Spells 51-60' WHERE name = 'Vicar_Delin'; + +UPDATE spawn2 SET x = '1093.00', y = '115.00', z = '-31.50', heading = '356.48' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Vicar_Delin') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202223; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202223, 1, 26963, -1100, 65535), + (202223, 2, 15045, -1100, 65535), + (202223, 3, 15063, -1100, 65535), + (202223, 4, 15127, -1100, 65535), + (202223, 5, 15115, -1100, 65535), + (202223, 6, 15388, -1100, 65535), + (202223, 7, 30443, -1100, 65535), + (202223, 8, 15049, -1100, 65535), + (202223, 9, 15061, -1100, 65535), + (202223, 10, 19542, -1100, 65535), + (202223, 11, 15013, -1100, 65535), + (202223, 12, 15415, -1100, 65535), + (202223, 13, 7604, -1100, 65535), + (202223, 14, 15675, -1100, 65535), + (202223, 15, 59011, -1100, 65535), + (202223, 16, 59576, -1100, 65535), + (202223, 17, 15044, -1100, 65535), + (202223, 18, 15488, -1100, 65535), + (202223, 19, 15314, -1100, 65535), + (202223, 20, 23484, -1100, 65535), + (202223, 21, 15064, -1100, 65535), + (202223, 22, 15097, -1100, 65535), + (202223, 23, 30411, -1100, 65535), + (202223, 24, 15416, -1100, 65535), + (202223, 25, 7605, -1100, 65535), + (202223, 26, 77864, -1100, 65535), + (202223, 27, 59555, -1100, 65535), + (202223, 28, 59556, -1100, 65535), + (202223, 29, 29011, -1100, 65535), + (202223, 30, 15009, -1100, 65535), + (202223, 31, 15062, -1100, 65535), + (202223, 32, 15135, -1100, 65535), + (202223, 33, 15124, -1100, 65535), + (202223, 34, 15487, -1100, 65535), + (202223, 35, 15504, -1100, 65535), + (202223, 36, 15312, -1100, 65535), + (202223, 37, 15480, -1100, 65535), + (202223, 38, 23483, -1100, 65535), + (202223, 39, 15053, -1100, 65535), + (202223, 40, 15060, -1100, 65535), + (202223, 41, 15059, -1100, 65535), + (202223, 42, 15414, -1100, 65535), + (202223, 43, 15131, -1100, 65535), + (202223, 44, 15391, -1100, 65535), + (202223, 45, 15663, -1100, 65535), + (202223, 46, 15052, -1100, 65535), + (202223, 47, 15096, -1100, 65535), + (202223, 48, 15130, -1100, 65535), + (202223, 49, 15329, -1100, 65535), + (202223, 50, 15798, -1100, 65535), + (202223, 51, 15799, -1100, 65535), + (202223, 52, 15800, -1100, 65535), + (202223, 53, 15885, -1100, 65535), + (202223, 54, 15886, -1100, 65535), + (202223, 55, 15887, -1100, 65535), + (202223, 56, 15888, -1100, 65535), + (202223, 57, 15894, -1100, 65535), + (202223, 58, 15895, -1100, 65535), + (202223, 59, 15896, -1100, 65535), + (202223, 60, 15897, -1100, 65535), + (202223, 61, 15898, -1100, 65535), + (202223, 62, 59542, -1100, 65535), + (202223, 63, 59543, -1100, 65535), + (202223, 64, 59544, -1100, 65535), + (202223, 65, 59545, -1100, 65535), + (202223, 66, 59546, -1100, 65535), + (202223, 67, 59550, -1100, 65535), + (202223, 68, 59551, -1100, 65535), + (202223, 69, 59552, -1100, 65535), + (202223, 70, 59553, -1100, 65535), + (202223, 71, 59554, -1100, 65535), + (202223, 72, 15118, -1100, 65535), + (202223, 73, 15406, -1100, 65535), + (202223, 74, 15672, -1100, 65535), + (202223, 75, 30444, -1100, 65535), + (202223, 76, 15020, -1100, 65535), + (202223, 77, 15136, -1100, 65535), + (202223, 78, 59572, -1100, 65535), + (202223, 79, 15125, -1100, 65535), + (202223, 80, 15132, -1100, 65535), + (202223, 81, 15392, -1100, 65535), + (202223, 82, 15664, -1100, 65535), + (202223, 83, 15662, -1100, 65535), + (202223, 84, 59665, -1100, 65535), + (202223, 85, 15134, -1100, 65535), + (202223, 86, 15405, -1100, 65535), + (202223, 87, 30445, -1100, 65535), + (202223, 88, 59689, -1100, 65535), + (202223, 89, 59677, -1100, 65535), + (202223, 90, 15019, -1100, 65535); + +UPDATE npc_types SET lastname = 'Cleric Spells 26-50' WHERE name = 'Vicar_Thiran'; + +UPDATE spawn2 SET x = '1107.00', y = '60.00', z = '-30.87', heading = '84.38' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Vicar_Thiran') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202219; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202219, 1, 15043, -1100, 65535), + (202219, 2, 15123, -1100, 65535), + (202219, 3, 23482, -1100, 65535), + (202219, 4, 15117, -1100, 65535), + (202219, 5, 59664, -1100, 65535), + (202219, 6, 59574, -1100, 65535), + (202219, 7, 59688, -1100, 65535), + (202219, 8, 59676, -1100, 65535), + (202219, 9, 15018, -1100, 65535), + (202219, 10, 7603, -1100, 65535), + (202219, 11, 15011, -1100, 65535), + (202219, 12, 15014, -1100, 65535), + (202219, 13, 15228, -1100, 65535), + (202219, 14, 15089, -1100, 65535), + (202219, 15, 15248, -1100, 65535), + (202219, 16, 23481, -1100, 65535), + (202219, 17, 7602, -1100, 65535), + (202219, 18, 15413, -1100, 65535), + (202219, 19, 15015, -1100, 65535), + (202219, 20, 15037, -1100, 65535), + (202219, 21, 59575, -1100, 65535), + (202219, 22, 15126, -1100, 65535), + (202219, 23, 15128, -1100, 65535), + (202219, 24, 15486, -1100, 65535), + (202219, 25, 15095, -1100, 65535), + (202219, 26, 15244, -1100, 65535), + (202219, 27, 15200, -1100, 65535), + (202219, 28, 15201, -1100, 65535), + (202219, 29, 15202, -1100, 65535), + (202219, 30, 15203, -1100, 65535), + (202219, 31, 15205, -1100, 65535), + (202219, 32, 15207, -1100, 65535), + (202219, 33, 15208, -1100, 65535), + (202219, 34, 15209, -1100, 65535), + (202219, 35, 15210, -1100, 65535), + (202219, 36, 15215, -1100, 65535), + (202219, 37, 15216, -1100, 65535), + (202219, 38, 15211, -1100, 65535), + (202219, 39, 15212, -1100, 65535), + (202219, 40, 15017, -1100, 65535), + (202219, 41, 15213, -1100, 65535), + (202219, 42, 15218, -1100, 65535), + (202219, 43, 15036, -1100, 65535), + (202219, 44, 15501, -1100, 65535), + (202219, 45, 15560, -1100, 65535), + (202219, 46, 15227, -1100, 65535), + (202219, 47, 15229, -1100, 65535), + (202219, 48, 7601, -1100, 65535), + (202219, 49, 15219, -1100, 65535), + (202219, 50, 15223, -1100, 65535), + (202219, 51, 15230, -1100, 65535), + (202219, 52, 15050, -1100, 65535), + (202219, 53, 15224, -1100, 65535), + (202219, 54, 59573, -1100, 65535), + (202219, 55, 15221, -1100, 65535), + (202219, 56, 15231, -1100, 65535), + (202219, 57, 15012, -1100, 65535), + (202219, 58, 15035, -1100, 65535), + (202219, 59, 59663, -1100, 65535), + (202219, 60, 15226, -1100, 65535), + (202219, 61, 15235, -1100, 65535), + (202219, 62, 15485, -1100, 65535), + (202219, 63, 15232, -1100, 65535), + (202219, 64, 15234, -1100, 65535), + (202219, 65, 23480, -1100, 65535), + (202219, 66, 15048, -1100, 65535), + (202219, 67, 15225, -1100, 65535), + (202219, 68, 15233, -1100, 65535), + (202219, 69, 15016, -1100, 65535), + (202219, 70, 59687, -1100, 65535), + (202219, 71, 59675, -1100, 65535), + (202219, 72, 15047, -1100, 65535), + (202219, 73, 15368, -1100, 65535), + (202219, 74, 26962, -1100, 65535); + +UPDATE npc_types SET lastname = 'Cleric Spells 1-25' WHERE name = 'Vicar_Ceraen'; + +UPDATE spawn2 SET x = '1104.00', y = '8.00', z = '-30.25', heading = '94.22' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Vicar_Ceraen') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202214; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202214, 1, 15086, -1100, 65535), + (202214, 2, 15254, -1100, 65535), + (202214, 3, 15258, -1100, 65535), + (202214, 4, 15256, -1100, 65535), + (202214, 5, 15268, -1100, 65535), + (202214, 6, 15515, -1100, 65535), + (202214, 7, 15091, -1100, 65535), + (202214, 8, 15255, -1100, 65535), + (202214, 9, 59597, -1100, 65535), + (202214, 10, 15017, -1100, 65535), + (202214, 11, 15225, -1100, 65535), + (202214, 12, 15257, -1100, 65535), + (202214, 13, 7611, -1100, 65535), + (202214, 14, 15211, -1100, 65535), + (202214, 15, 15264, -1100, 65535), + (202214, 16, 15278, -1100, 65535), + (202214, 17, 15050, -1100, 65535), + (202214, 18, 15234, -1100, 65535), + (202214, 19, 59666, -1100, 65535), + (202214, 20, 15035, -1100, 65535), + (202214, 21, 15262, -1100, 65535), + (202214, 22, 15080, -1100, 65535), + (202214, 23, 15245, -1100, 65535), + (202214, 24, 15663, -1100, 65535), + (202214, 25, 15261, -1100, 65535), + (202214, 26, 15263, -1100, 65535), + (202214, 27, 59690, -1100, 65535), + (202214, 28, 59678, -1100, 65535), + (202214, 29, 15513, -1100, 65535), + (202214, 30, 15514, -1100, 65535), + (202214, 31, 15530, -1100, 65535), + (202214, 32, 19483, -1100, 65535), + (202214, 33, 15419, -1100, 65535), + (202214, 34, 15520, -1100, 65535), + (202214, 35, 15532, -1100, 65535), + (202214, 36, 15273, -1100, 65535), + (202214, 37, 15516, -1100, 65535), + (202214, 38, 15531, -1100, 65535), + (202214, 39, 15533, -1100, 65535), + (202214, 40, 26970, -1100, 65535), + (202214, 41, 15034, -1100, 65535), + (202214, 42, 15048, -1100, 65535), + (202214, 43, 15139, -1100, 65535), + (202214, 44, 23485, -1100, 65535), + (202214, 45, 27965, -1100, 65535), + (202214, 46, 15012, -1100, 65535), + (202214, 47, 15226, -1100, 65535), + (202214, 48, 15227, -1100, 65535), + (202214, 49, 7612, -1100, 65535), + (202214, 50, 27981, -1100, 65535), + (202214, 51, 15060, -1100, 65535), + (202214, 52, 15425, -1100, 65535), + (202214, 53, 15535, -1100, 65535), + (202214, 54, 59522, -1100, 65535), + (202214, 55, 78294, -1100, 65535), + (202214, 56, 78295, -1100, 65535), + (202214, 57, 78293, -1100, 65535), + (202214, 58, 15076, -1100, 65535), + (202214, 59, 15220, -1100, 65535), + (202214, 60, 15405, -1100, 65535), + (202214, 61, 15537, -1100, 65535), + (202214, 62, 59667, -1100, 65535), + (202214, 63, 15027, -1100, 65535), + (202214, 64, 15143, -1100, 65535), + (202214, 65, 15534, -1100, 65535), + (202214, 66, 15536, -1100, 65535), + (202214, 67, 15115, -1100, 65535), + (202214, 68, 15260, -1100, 65535), + (202214, 69, 27970, -1100, 65535), + (202214, 70, 59598, -1100, 65535), + (202214, 71, 15099, -1100, 65535), + (202214, 72, 15421, -1100, 65535), + (202214, 73, 19472, -1100, 65535), + (202214, 74, 59691, -1100, 65535), + (202214, 75, 59679, -1100, 65535), + (202214, 76, 15078, -1100, 65535), + (202214, 77, 15538, -1100, 65535), + (202214, 78, 15550, -1100, 65535), + (202214, 79, 15552, -1100, 65535), + (202214, 80, 15553, -1100, 65535), + (202214, 81, 26974, -1100, 65535), + (202214, 82, 15026, -1100, 65535), + (202214, 83, 15093, -1100, 65535), + (202214, 84, 15200, -1100, 65535), + (202214, 85, 15224, -1100, 65535), + (202214, 86, 15237, -1100, 65535), + (202214, 87, 15238, -1100, 65535), + (202214, 88, 15239, -1100, 65535), + (202214, 89, 15240, -1100, 65535), + (202214, 90, 15241, -1100, 65535), + (202214, 91, 15242, -1100, 65535), + (202214, 92, 7691, -1100, 65535), + (202214, 93, 15248, -1100, 65535), + (202214, 94, 15249, -1100, 65535), + (202214, 95, 15092, -1100, 65535), + (202214, 96, 15253, -1100, 65535), + (202214, 97, 15213, -1100, 65535), + (202214, 98, 15247, -1100, 65535), + (202214, 99, 15252, -1100, 65535), + (202214, 100, 15036, -1100, 65535), + (202214, 101, 15203, -1100, 65535), + (202214, 102, 15250, -1100, 65535); + +UPDATE npc_types SET lastname = 'Druid Spells 1-25' WHERE name = 'Wanderer_Astobin'; + +UPDATE spawn2 SET x = '985.00', y = '-75.00', z = '3.13', heading = '270.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Wanderer_Astobin') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202216; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202216, 1, 28532, -1100, 65535), + (202216, 2, 28533, -1100, 65535), + (202216, 3, 28535, -1100, 65535), + (202216, 4, 28536, -1100, 65535), + (202216, 5, 28538, -1100, 65535), + (202216, 6, 21657, -1100, 65535), + (202216, 7, 28534, -1100, 65535), + (202216, 8, 28537, -1100, 65535), + (202216, 9, 28539, -1100, 65535), + (202216, 10, 28540, -1100, 65535), + (202216, 11, 59602, -1100, 65535), + (202216, 12, 17796, -1100, 65535), + (202216, 13, 78185, -1100, 65535), + (202216, 14, 77093, -1100, 65535), + (202216, 15, 77097, -1100, 65535), + (202216, 16, 77273, -1100, 65535), + (202216, 17, 77105, -1100, 65535), + (202216, 18, 77103, -1100, 65535), + (202216, 19, 77094, -1100, 65535), + (202216, 20, 77099, -1100, 65535), + (202216, 21, 41275, -1100, 65535), + (202216, 22, 77095, -1100, 65535), + (202216, 23, 77098, -1100, 65535), + (202216, 24, 77102, -1100, 65535), + (202216, 25, 77104, -1100, 65535), + (202216, 26, 76023, -1100, 65535), + (202216, 27, 41276, -1100, 65535), + (202216, 28, 77107, -1100, 65535), + (202216, 29, 77106, -1100, 65535), + (202216, 30, 77108, -1100, 65535), + (202216, 31, 77091, -1100, 65535), + (202216, 32, 77109, -1100, 65535), + (202216, 33, 77101, -1100, 65535), + (202216, 34, 41277, -1100, 65535), + (202216, 35, 78001, -1100, 65535), + (202216, 36, 77999, -1100, 65535), + (202216, 37, 43572, -1100, 65535), + (202216, 38, 78288, -1100, 65535), + (202216, 39, 78289, -1100, 65535), + (202216, 40, 78287, -1100, 65535), + (202216, 41, 77657, -1100, 65535), + (202216, 42, 79453, -1100, 65535), + (202216, 43, 21659, -1100, 65535), + (202216, 44, 28541, -1100, 65535), + (202216, 45, 28542, -1100, 65535), + (202216, 46, 28543, -1100, 65535), + (202216, 47, 28645, -1100, 65535), + (202216, 48, 59824, -1100, 65535), + (202216, 49, 59823, -1100, 65535), + (202216, 50, 59822, -1100, 65535), + (202216, 51, 77088, -1100, 65535), + (202216, 52, 77852, -1100, 65535), + (202216, 53, 77084, -1100, 65535), + (202216, 54, 77085, -1100, 65535), + (202216, 55, 77087, -1100, 65535), + (202216, 56, 77096, -1100, 65535), + (202216, 57, 77090, -1100, 65535), + (202216, 58, 77092, -1100, 65535), + (202216, 59, 77089, -1100, 65535), + (202216, 60, 77100, -1100, 65535), + (202216, 61, 26943, -1100, 65535), + (202216, 62, 28523, -1100, 65535), + (202216, 63, 28524, -1100, 65535), + (202216, 64, 28525, -1100, 65535), + (202216, 65, 28526, -1100, 65535), + (202216, 66, 28564, -1100, 65535), + (202216, 67, 77851, -1100, 65535), + (202216, 68, 76039, -1100, 65535), + (202216, 69, 21656, -1100, 65535), + (202216, 70, 28456, -1100, 65535), + (202216, 71, 28527, -1100, 65535), + (202216, 72, 28528, -1100, 65535), + (202216, 73, 28529, -1100, 65535), + (202216, 74, 28530, -1100, 65535), + (202216, 75, 77658, -1100, 65535), + (202216, 76, 21658, -1100, 65535), + (202216, 77, 28531, -1100, 65535); + +UPDATE npc_types SET lastname = 'Druid Spells 61-70' WHERE name = 'Wanderer_Kedrisan'; + +UPDATE spawn2 SET x = '948.00', y = '-41.00', z = '3.44', heading = '270.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Wanderer_Kedrisan') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202218; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202218, 1, 15423, -1100, 65535), + (202218, 2, 15611, -1100, 65535), + (202218, 3, 15029, -1100, 65535), + (202218, 4, 15356, -1100, 65535), + (202218, 5, 15519, -1100, 65535), + (202218, 6, 15433, -1100, 65535), + (202218, 7, 15671, -1100, 65535), + (202218, 8, 19205, -1100, 65535), + (202218, 9, 30435, -1100, 65535), + (202218, 10, 15064, -1100, 65535), + (202218, 11, 19412, -1100, 65535), + (202218, 12, 7615, -1100, 65535), + (202218, 13, 59600, -1100, 65535), + (202218, 14, 19523, -1100, 65535), + (202218, 15, 19534, -1100, 65535), + (202218, 16, 59680, -1100, 65535), + (202218, 17, 15169, -1100, 65535), + (202218, 18, 15428, -1100, 65535), + (202218, 19, 59596, -1100, 65535), + (202218, 20, 15422, -1100, 65535), + (202218, 21, 15490, -1100, 65535), + (202218, 22, 15558, -1100, 65535), + (202218, 23, 19517, -1100, 65535), + (202218, 24, 26967, -1100, 65535), + (202218, 25, 15028, -1100, 65535), + (202218, 26, 15432, -1100, 65535), + (202218, 27, 15518, -1100, 65535), + (202218, 28, 19428, -1100, 65535), + (202218, 29, 30437, -1100, 65535), + (202218, 30, 27977, -1100, 65535), + (202218, 31, 15057, -1100, 65535), + (202218, 32, 15609, -1100, 65535), + (202218, 33, 30438, -1100, 65535), + (202218, 34, 19542, -1100, 65535), + (202218, 35, 36012, -1100, 65535), + (202218, 36, 26975, -1100, 65535), + (202218, 37, 15137, -1100, 65535), + (202218, 38, 19427, -1100, 65535), + (202218, 39, 19518, -1100, 65535), + (202218, 40, 7614, -1100, 65535), + (202218, 41, 15427, -1100, 65535), + (202218, 42, 15665, -1100, 65535), + (202218, 43, 30398, -1100, 65535), + (202218, 44, 15140, -1100, 65535), + (202218, 45, 15610, -1100, 65535), + (202218, 46, 19502, -1100, 65535), + (202218, 47, 15145, -1100, 65535), + (202218, 48, 30436, -1100, 65535), + (202218, 49, 30440, -1100, 65535), + (202218, 50, 15049, -1100, 65535), + (202218, 51, 15116, -1100, 65535), + (202218, 52, 15142, -1100, 65535), + (202218, 53, 19426, -1100, 65535), + (202218, 54, 15062, -1100, 65535), + (202218, 55, 15063, -1100, 65535), + (202218, 56, 15430, -1100, 65535), + (202218, 57, 27972, -1100, 65535), + (202218, 58, 15144, -1100, 65535), + (202218, 59, 15228, -1100, 65535), + (202218, 60, 15429, -1100, 65535), + (202218, 61, 59692, -1100, 65535), + (202218, 62, 78175, -1100, 65535), + (202218, 63, 125592, -1100, 65535), + (202218, 64, 125590, -1100, 65535), + (202218, 65, 125383, -1100, 65535), + (202218, 66, 125589, -1100, 65535), + (202218, 67, 125385, -1100, 65535), + (202218, 68, 125595, -1100, 65535), + (202218, 69, 125382, -1100, 65535), + (202218, 70, 125386, -1100, 65535), + (202218, 71, 125387, -1100, 65535), + (202218, 72, 125378, -1100, 65535), + (202218, 73, 125379, -1100, 65535), + (202218, 74, 125588, -1100, 65535), + (202218, 75, 125593, -1100, 65535), + (202218, 76, 125384, -1100, 65535), + (202218, 77, 125591, -1100, 65535), + (202218, 78, 125388, -1100, 65535), + (202218, 79, 125594, -1100, 65535), + (202218, 80, 125587, -1100, 65535), + (202218, 81, 21960, -1100, 65535), + (202218, 82, 15061, -1100, 65535), + (202218, 83, 15426, -1100, 65535), + (202218, 84, 15554, -1100, 65535), + (202218, 85, 30439, -1100, 65535), + (202218, 86, 59595, -1100, 65535), + (202218, 87, 15406, -1100, 65535), + (202218, 88, 15418, -1100, 65535), + (202218, 89, 15557, -1100, 65535), + (202218, 90, 30433, -1100, 65535), + (202218, 91, 59668, -1100, 65535), + (202218, 92, 15259, -1100, 65535), + (202218, 93, 15555, -1100, 65535), + (202218, 94, 15556, -1100, 65535), + (202218, 95, 15608, -1100, 65535), + (202218, 96, 30434, -1100, 65535), + (202218, 97, 15141, -1100, 65535), + (202218, 98, 15664, -1100, 65535), + (202218, 99, 15862, -1100, 65535), + (202218, 100, 19516, -1100, 65535), + (202218, 101, 15424, -1100, 65535), + (202218, 102, 15512, -1100, 65535), + (202218, 103, 15607, -1100, 65535), + (202218, 104, 19482, -1100, 65535), + (202218, 105, 27980, -1100, 65535), + (202218, 106, 15129, -1100, 65535), + (202218, 107, 15517, -1100, 65535), + (202218, 108, 15551, -1100, 65535), + (202218, 109, 7613, -1100, 65535), + (202218, 110, 15095, -1100, 65535), + (202218, 111, 15096, -1100, 65535), + (202218, 112, 15217, -1100, 65535), + (202218, 113, 15753, -1100, 65535), + (202218, 114, 59520, -1100, 65535), + (202218, 115, 15015, -1100, 65535), + (202218, 116, 15800, -1100, 65535), + (202218, 117, 15888, -1100, 65535), + (202218, 118, 59546, -1100, 65535), + (202218, 119, 59552, -1100, 65535), + (202218, 120, 27967, -1100, 65535), + (202218, 121, 27975, -1100, 65535), + (202218, 122, 59014, -1100, 65535), + (202218, 123, 15077, -1100, 65535), + (202218, 124, 15138, -1100, 65535), + (202218, 125, 26966, -1100, 65535), + (202218, 126, 15420, -1100, 65535); + +UPDATE npc_types SET lastname = 'Druid Spells 26-50' WHERE name = 'Wanderer_Qenda'; + +UPDATE spawn2 SET x = '1050.00', y = '-85.00', z = '3.75', heading = '179.30' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Wanderer_Qenda') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202217; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202217, 1, 19522, -1100, 65535), + (202217, 2, 59881, -1100, 65535), + (202217, 3, 79455, -1100, 65535), + (202217, 4, 19207, -1100, 65535), + (202217, 5, 19245, -1100, 65535), + (202217, 6, 19246, -1100, 65535), + (202217, 7, 19247, -1100, 65535), + (202217, 8, 19252, -1100, 65535), + (202217, 9, 19507, -1100, 65535), + (202217, 10, 30475, -1100, 65535), + (202217, 11, 17794, -1100, 65535), + (202217, 12, 17795, -1100, 65535), + (202217, 13, 78173, -1100, 65535), + (202217, 14, 78174, -1100, 65535), + (202217, 15, 78186, -1100, 65535), + (202217, 16, 78187, -1100, 65535), + (202217, 17, 125389, -1100, 65535), + (202217, 18, 125380, -1100, 65535), + (202217, 19, 125381, -1100, 65535), + (202217, 20, 59601, -1100, 65535), + (202217, 21, 59991, -1100, 65535), + (202217, 22, 77662, -1100, 65535), + (202217, 23, 78026, -1100, 65535), + (202217, 24, 19248, -1100, 65535), + (202217, 25, 19249, -1100, 65535), + (202217, 26, 19250, -1100, 65535), + (202217, 27, 19413, -1100, 65535), + (202217, 28, 7618, -1100, 65535), + (202217, 29, 19251, -1100, 65535), + (202217, 30, 19253, -1100, 65535), + (202217, 31, 19419, -1100, 65535), + (202217, 32, 77850, -1100, 65535), + (202217, 33, 19254, -1100, 65535), + (202217, 34, 19255, -1100, 65535), + (202217, 35, 19256, -1100, 65535), + (202217, 36, 2482, -1100, 65535), + (202217, 37, 7619, -1100, 65535), + (202217, 38, 19257, -1100, 65535), + (202217, 39, 19258, -1100, 65535), + (202217, 40, 19259, -1100, 65535), + (202217, 41, 9722, -1100, 65535), + (202217, 42, 66281, -1100, 65535), + (202217, 43, 79454, -1100, 65535), + (202217, 44, 19260, -1100, 65535), + (202217, 45, 19261, -1100, 65535), + (202217, 46, 19262, -1100, 65535), + (202217, 47, 19263, -1100, 65535), + (202217, 48, 19508, -1100, 65535), + (202217, 49, 30442, -1100, 65535), + (202217, 50, 7620, -1100, 65535), + (202217, 51, 19519, -1100, 65535), + (202217, 52, 19529, -1100, 65535), + (202217, 53, 78291, -1100, 65535), + (202217, 54, 78292, -1100, 65535), + (202217, 55, 78290, -1100, 65535), + (202217, 56, 15009, -1100, 65535), + (202217, 57, 19231, -1100, 65535), + (202217, 58, 19232, -1100, 65535), + (202217, 59, 19234, -1100, 65535), + (202217, 60, 19235, -1100, 65535), + (202217, 61, 19236, -1100, 65535), + (202217, 62, 19237, -1100, 65535), + (202217, 63, 7616, -1100, 65535), + (202217, 64, 59012, -1100, 65535), + (202217, 65, 59599, -1100, 65535), + (202217, 66, 59993, -1100, 65535), + (202217, 67, 59882, -1100, 65535), + (202217, 68, 77928, -1100, 65535), + (202217, 69, 77930, -1100, 65535), + (202217, 70, 78032, -1100, 65535), + (202217, 71, 78034, -1100, 65535), + (202217, 72, 19238, -1100, 65535), + (202217, 73, 19239, -1100, 65535), + (202217, 74, 19240, -1100, 65535), + (202217, 75, 77663, -1100, 65535), + (202217, 76, 19241, -1100, 65535), + (202217, 77, 19242, -1100, 65535), + (202217, 78, 19243, -1100, 65535), + (202217, 79, 19244, -1100, 65535), + (202217, 80, 7617, -1100, 65535); + +UPDATE npc_types SET lastname = 'Druid Spells 51-60' WHERE name = 'Wanderer_Frardok'; + +UPDATE spawn2 SET x = '1061.00', y = '-50.00', z = '2.19', heading = '1.41' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Wanderer_Frardok') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202209; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202209, 1, 15601, -1100, 65535), + (202209, 2, 15281, -1100, 65535), + (202209, 3, 15304, -1100, 65535), + (202209, 4, 15306, -1100, 65535), + (202209, 5, 15307, -1100, 65535), + (202209, 6, 15309, -1100, 65535), + (202209, 7, 36364, -1100, 65535), + (202209, 8, 36365, -1100, 65535), + (202209, 9, 36366, -1100, 65535), + (202209, 10, 36367, -1100, 65535), + (202209, 11, 15228, -1100, 65535), + (202209, 12, 15593, -1100, 65535), + (202209, 13, 15651, -1100, 65535), + (202209, 14, 15684, -1100, 65535), + (202209, 15, 7662, -1100, 65535), + (202209, 16, 15047, -1100, 65535), + (202209, 17, 15489, -1100, 65535), + (202209, 18, 15592, -1100, 65535), + (202209, 19, 15677, -1100, 65535), + (202209, 20, 15021, -1100, 65535), + (202209, 21, 15179, -1100, 65535), + (202209, 22, 15439, -1100, 65535), + (202209, 23, 26970, -1100, 65535), + (202209, 24, 37591, -1100, 65535), + (202209, 25, 15084, -1100, 65535), + (202209, 26, 15173, -1100, 65535), + (202209, 27, 15177, -1100, 65535), + (202209, 28, 36377, -1100, 65535), + (202209, 29, 36378, -1100, 65535), + (202209, 30, 36379, -1100, 65535), + (202209, 31, 36380, -1100, 65535), + (202209, 32, 59530, -1100, 65535), + (202209, 33, 15243, -1100, 65535), + (202209, 34, 15170, -1100, 65535), + (202209, 35, 15350, -1100, 65535), + (202209, 36, 15584, -1100, 65535), + (202209, 37, 15024, -1100, 65535), + (202209, 38, 15482, -1100, 65535), + (202209, 39, 15685, -1100, 65535), + (202209, 40, 15065, -1100, 65535), + (202209, 41, 15182, -1100, 65535), + (202209, 42, 15185, -1100, 65535), + (202209, 43, 59661, -1100, 65535), + (202209, 44, 15287, -1100, 65535), + (202209, 45, 15288, -1100, 65535), + (202209, 46, 15289, -1100, 65535), + (202209, 47, 15331, -1100, 65535), + (202209, 48, 15292, -1100, 65535), + (202209, 49, 15582, -1100, 65535), + (202209, 50, 15676, -1100, 65535), + (202209, 51, 15681, -1100, 65535), + (202209, 52, 15229, -1100, 65535), + (202209, 53, 15290, -1100, 65535), + (202209, 54, 15293, -1100, 65535), + (202209, 55, 15583, -1100, 65535), + (202209, 56, 15036, -1100, 65535), + (202209, 57, 15042, -1100, 65535), + (202209, 58, 15291, -1100, 65535), + (202209, 59, 15294, -1100, 65535), + (202209, 60, 15297, -1100, 65535), + (202209, 61, 15299, -1100, 65535), + (202209, 62, 15669, -1100, 65535), + (202209, 63, 59536, -1100, 65535), + (202209, 64, 59673, -1100, 65535), + (202209, 65, 59685, -1100, 65535), + (202209, 66, 15131, -1100, 65535), + (202209, 67, 15162, -1100, 65535), + (202209, 68, 15191, -1100, 65535), + (202209, 69, 36368, -1100, 65535), + (202209, 70, 15581, -1100, 65535), + (202209, 71, 15040, -1100, 65535), + (202209, 72, 15041, -1100, 65535), + (202209, 73, 15205, -1100, 65535), + (202209, 74, 15208, -1100, 65535), + (202209, 75, 15285, -1100, 65535), + (202209, 76, 15286, -1100, 65535), + (202209, 77, 15588, -1100, 65535), + (202209, 78, 15080, -1100, 65535), + (202209, 79, 15230, -1100, 65535), + (202209, 80, 15246, -1100, 65535), + (202209, 81, 15501, -1100, 65535), + (202209, 82, 15048, -1100, 65535), + (202209, 83, 15295, -1100, 65535), + (202209, 84, 15296, -1100, 65535), + (202209, 85, 15667, -1100, 65535), + (202209, 86, 59539, -1100, 65535), + (202209, 87, 15298, -1100, 65535), + (202209, 88, 15500, -1100, 65535), + (202209, 89, 15595, -1100, 65535), + (202209, 90, 15796, -1100, 65535), + (202209, 91, 59534, -1100, 65535), + (202209, 92, 15302, -1100, 65535), + (202209, 93, 15303, -1100, 65535), + (202209, 94, 15645, -1100, 65535), + (202209, 95, 15682, -1100, 65535), + (202209, 96, 15276, -1100, 65535), + (202209, 97, 15301, -1100, 65535), + (202209, 98, 15590, -1100, 65535), + (202209, 99, 15650, -1100, 65535), + (202209, 100, 15300, -1100, 65535), + (202209, 101, 15390, -1100, 65535), + (202209, 102, 15521, -1100, 65535), + (202209, 103, 15589, -1100, 65535), + (202209, 104, 37594, -1100, 65535), + (202209, 105, 59558, -1100, 65535), + (202209, 106, 7661, -1100, 65535), + (202209, 107, 15035, -1100, 65535), + (202209, 108, 15086, -1100, 65535), + (202209, 109, 15587, -1100, 65535), + (202209, 110, 15594, -1100, 65535), + (202209, 111, 15187, -1100, 65535), + (202209, 112, 15481, -1100, 65535), + (202209, 113, 15591, -1100, 65535), + (202209, 114, 59660, -1100, 65535), + (202209, 115, 15235, -1100, 65535), + (202209, 116, 15668, -1100, 65535), + (202209, 117, 15683, -1100, 65535), + (202209, 118, 15697, -1100, 65535), + (202209, 119, 59535, -1100, 65535), + (202209, 120, 59672, -1100, 65535), + (202209, 121, 59684, -1100, 65535), + (202209, 122, 15039, -1100, 65535), + (202209, 123, 15261, -1100, 65535), + (202209, 124, 15305, -1100, 65535), + (202209, 125, 15586, -1100, 65535); + +UPDATE npc_types SET lastname = 'Enchanter Spells 1-25' WHERE name = 'Illusionist_Jerup'; + +UPDATE spawn2 SET x = '1041.00', y = '-74.00', z = '-62.12', heading = '267.89' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Illusionist_Jerup') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202213; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202213, 1, 59674, -1100, 65535), + (202213, 2, 59686, -1100, 65535), + (202213, 3, 15045, -1100, 65535), + (202213, 4, 15127, -1100, 65535), + (202213, 5, 15175, -1100, 65535), + (202213, 6, 36369, -1100, 65535), + (202213, 7, 15073, -1100, 65535), + (202213, 8, 15192, -1100, 65535), + (202213, 9, 7664, -1100, 65535), + (202213, 10, 15064, -1100, 65535), + (202213, 11, 15183, -1100, 65535), + (202213, 12, 15596, -1100, 65535), + (202213, 13, 15653, -1100, 65535), + (202213, 14, 15688, -1100, 65535), + (202213, 15, 15600, -1100, 65535), + (202213, 16, 15648, -1100, 65535), + (202213, 17, 15695, -1100, 65535), + (202213, 18, 37593, -1100, 65535), + (202213, 19, 30407, -1100, 65535), + (202213, 20, 15033, -1100, 65535), + (202213, 21, 15186, -1100, 65535), + (202213, 22, 15678, -1100, 65535), + (202213, 23, 15689, -1100, 65535), + (202213, 24, 15025, -1100, 65535), + (202213, 25, 15181, -1100, 65535), + (202213, 26, 15585, -1100, 65535), + (202213, 27, 19386, -1100, 65535), + (202213, 28, 15178, -1100, 65535), + (202213, 29, 15673, -1100, 65535), + (202213, 30, 19502, -1100, 65535), + (202213, 31, 15797, -1100, 65535), + (202213, 32, 59646, -1100, 65535), + (202213, 33, 59541, -1100, 65535), + (202213, 34, 37595, -1100, 65535), + (202213, 35, 26973, -1100, 65535), + (202213, 36, 59015, -1100, 65535), + (202213, 37, 59642, -1100, 65535), + (202213, 38, 15194, -1100, 65535), + (202213, 39, 15696, -1100, 65535), + (202213, 40, 16240, -1100, 65535), + (202213, 41, 36370, -1100, 65535), + (202213, 42, 7665, -1100, 65535), + (202213, 43, 15174, -1100, 65535), + (202213, 44, 15408, -1100, 65535), + (202213, 45, 15450, -1100, 65535), + (202213, 46, 7663, -1100, 65535), + (202213, 47, 15046, -1100, 65535), + (202213, 48, 15540, -1100, 65535), + (202213, 49, 15652, -1100, 65535), + (202213, 50, 15010, -1100, 65535), + (202213, 51, 15049, -1100, 65535), + (202213, 52, 15599, -1100, 65535), + (202213, 53, 15619, -1100, 65535), + (202213, 54, 37592, -1100, 65535), + (202213, 55, 15597, -1100, 65535), + (202213, 56, 15686, -1100, 65535), + (202213, 57, 36381, -1100, 65535), + (202213, 58, 59529, -1100, 65535), + (202213, 59, 59641, -1100, 65535), + (202213, 60, 15074, -1100, 65535), + (202213, 61, 15188, -1100, 65535), + (202213, 62, 26972, -1100, 65535), + (202213, 63, 15066, -1100, 65535), + (202213, 64, 15646, -1100, 65535), + (202213, 65, 15687, -1100, 65535), + (202213, 66, 15071, -1100, 65535), + (202213, 67, 15407, -1100, 65535), + (202213, 68, 15670, -1100, 65535), + (202213, 69, 59538, -1100, 65535), + (202213, 70, 15483, -1100, 65535), + (202213, 71, 15132, -1100, 65535), + (202213, 72, 15171, -1100, 65535), + (202213, 73, 36382, -1100, 65535), + (202213, 74, 59531, -1100, 65535), + (202213, 75, 15067, -1100, 65535), + (202213, 76, 15163, -1100, 65535), + (202213, 77, 15484, -1100, 65535), + (202213, 78, 30474, -1100, 65535), + (202213, 79, 15184, -1100, 65535), + (202213, 80, 15193, -1100, 65535), + (202213, 81, 15647, -1100, 65535), + (202213, 82, 15892, -1100, 65535), + (202213, 83, 15172, -1100, 65535), + (202213, 84, 15176, -1100, 65535), + (202213, 85, 15190, -1100, 65535), + (202213, 86, 15195, -1100, 65535), + (202213, 87, 59557, -1100, 65535), + (202213, 88, 15072, -1100, 65535), + (202213, 89, 15654, -1100, 65535), + (202213, 90, 15690, -1100, 65535), + (202213, 91, 15889, -1100, 65535), + (202213, 92, 15890, -1100, 65535), + (202213, 93, 15893, -1100, 65535), + (202213, 94, 36383, -1100, 65535), + (202213, 95, 59532, -1100, 65535), + (202213, 96, 59533, -1100, 65535), + (202213, 97, 59537, -1100, 65535), + (202213, 98, 59540, -1100, 65535), + (202213, 99, 36371, -1100, 65535), + (202213, 100, 19374, -1100, 65535), + (202213, 101, 19376, -1100, 65535), + (202213, 102, 30406, -1100, 65535), + (202213, 103, 15598, -1100, 65535), + (202213, 104, 59662, -1100, 65535), + (202213, 105, 15180, -1100, 65535), + (202213, 106, 30408, -1100, 65535); + +UPDATE npc_types SET lastname = 'Enchanter Spells 26-50' WHERE name = 'Illusionist_Sevat'; + +UPDATE spawn2 SET x = '1063.00', y = '-85.00', z = '-60.25', heading = '182.81' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Illusionist_Sevat') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202212; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202212, 1, 19215, -1100, 65535), + (202212, 2, 19523, -1100, 65535), + (202212, 3, 19534, -1100, 65535), + (202212, 4, 19377, -1100, 65535), + (202212, 5, 19378, -1100, 65535), + (202212, 6, 19379, -1100, 65535), + (202212, 7, 19380, -1100, 65535), + (202212, 8, 7666, -1100, 65535), + (202212, 9, 59016, -1100, 65535), + (202212, 10, 67011, -1100, 65535), + (202212, 11, 59645, -1100, 65535), + (202212, 12, 19269, -1100, 65535), + (202212, 13, 19381, -1100, 65535), + (202212, 14, 19382, -1100, 65535), + (202212, 15, 19383, -1100, 65535), + (202212, 16, 19300, -1100, 65535), + (202212, 17, 19384, -1100, 65535), + (202212, 18, 19385, -1100, 65535), + (202212, 19, 36384, -1100, 65535), + (202212, 20, 7667, -1100, 65535), + (202212, 21, 19543, -1100, 65535), + (202212, 22, 77918, -1100, 65535), + (202212, 23, 19387, -1100, 65535), + (202212, 24, 19388, -1100, 65535), + (202212, 25, 19389, -1100, 65535), + (202212, 26, 19390, -1100, 65535), + (202212, 27, 36372, -1100, 65535), + (202212, 28, 30409, -1100, 65535), + (202212, 29, 59643, -1100, 65535), + (202212, 30, 78028, -1100, 65535), + (202212, 31, 19220, -1100, 65535), + (202212, 32, 19391, -1100, 65535), + (202212, 33, 19392, -1100, 65535), + (202212, 34, 19401, -1100, 65535), + (202212, 35, 19416, -1100, 65535), + (202212, 36, 7668, -1100, 65535), + (202212, 37, 19393, -1100, 65535), + (202212, 38, 19394, -1100, 65535), + (202212, 39, 19395, -1100, 65535), + (202212, 40, 19396, -1100, 65535), + (202212, 41, 77835, -1100, 65535), + (202212, 42, 19338, -1100, 65535), + (202212, 43, 19397, -1100, 65535), + (202212, 44, 19400, -1100, 65535), + (202212, 45, 19481, -1100, 65535), + (202212, 46, 7669, -1100, 65535), + (202212, 47, 59647, -1100, 65535), + (202212, 48, 19402, -1100, 65535), + (202212, 49, 19403, -1100, 65535), + (202212, 50, 36385, -1100, 65535), + (202212, 51, 19405, -1100, 65535), + (202212, 52, 19406, -1100, 65535), + (202212, 53, 19407, -1100, 65535), + (202212, 54, 30410, -1100, 65535), + (202212, 55, 7670, -1100, 65535), + (202212, 56, 19535, -1100, 65535), + (202212, 57, 36373, -1100, 65535); + +UPDATE npc_types SET lastname = 'Enchanter Spells 51-60' WHERE name = 'Illusionist_Lobaen'; + +UPDATE spawn2 SET x = '1078.00', y = '-64.00', z = '-60.25', heading = '87.89' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Illusionist_Lobaen') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202211; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202211, 1, 77236, -1100, 65535), + (202211, 2, 77239, -1100, 65535), + (202211, 3, 77237, -1100, 65535), + (202211, 4, 77240, -1100, 65535), + (202211, 5, 77855, -1100, 65535), + (202211, 6, 77244, -1100, 65535), + (202211, 7, 77242, -1100, 65535), + (202211, 8, 77249, -1100, 65535), + (202211, 9, 77246, -1100, 65535), + (202211, 10, 41292, -1100, 65535), + (202211, 11, 77241, -1100, 65535), + (202211, 12, 77247, -1100, 65535), + (202211, 13, 77301, -1100, 65535), + (202211, 14, 77251, -1100, 65535), + (202211, 15, 77245, -1100, 65535), + (202211, 16, 77243, -1100, 65535), + (202211, 17, 21691, -1100, 65535), + (202211, 18, 21695, -1100, 65535), + (202211, 19, 26944, -1100, 65535), + (202211, 20, 28413, -1100, 65535), + (202211, 21, 28451, -1100, 65535), + (202211, 22, 28452, -1100, 65535), + (202211, 23, 28453, -1100, 65535), + (202211, 24, 28643, -1100, 65535), + (202211, 25, 28644, -1100, 65535), + (202211, 26, 76045, -1100, 65535), + (202211, 27, 21639, -1100, 65535), + (202211, 28, 21665, -1100, 65535), + (202211, 29, 21667, -1100, 65535), + (202211, 30, 21694, -1100, 65535), + (202211, 31, 26947, -1100, 65535), + (202211, 32, 28454, -1100, 65535), + (202211, 33, 28455, -1100, 65535), + (202211, 34, 28456, -1100, 65535), + (202211, 35, 28457, -1100, 65535), + (202211, 36, 28462, -1100, 65535), + (202211, 37, 28469, -1100, 65535), + (202211, 38, 77836, -1100, 65535), + (202211, 39, 21666, -1100, 65535), + (202211, 40, 21692, -1100, 65535), + (202211, 41, 21693, -1100, 65535), + (202211, 42, 28458, -1100, 65535), + (202211, 43, 28460, -1100, 65535), + (202211, 44, 28461, -1100, 65535), + (202211, 45, 28464, -1100, 65535), + (202211, 46, 59644, -1100, 65535), + (202211, 47, 59806, -1100, 65535), + (202211, 48, 28415, -1100, 65535), + (202211, 49, 28459, -1100, 65535), + (202211, 50, 28463, -1100, 65535), + (202211, 51, 28465, -1100, 65535), + (202211, 52, 28468, -1100, 65535), + (202211, 53, 36386, -1100, 65535), + (202211, 54, 21648, -1100, 65535), + (202211, 55, 76029, -1100, 65535), + (202211, 56, 41291, -1100, 65535), + (202211, 57, 36387, -1100, 65535), + (202211, 58, 77248, -1100, 65535), + (202211, 59, 77252, -1100, 65535), + (202211, 60, 77250, -1100, 65535), + (202211, 61, 77253, -1100, 65535), + (202211, 62, 41290, -1100, 65535), + (202211, 63, 78007, -1100, 65535), + (202211, 64, 43574, -1100, 65535), + (202211, 65, 78005, -1100, 65535), + (202211, 66, 36375, -1100, 65535), + (202211, 67, 21664, -1100, 65535), + (202211, 68, 28466, -1100, 65535), + (202211, 69, 28467, -1100, 65535), + (202211, 70, 28470, -1100, 65535), + (202211, 71, 59817, -1100, 65535), + (202211, 72, 59816, -1100, 65535), + (202211, 73, 59818, -1100, 65535), + (202211, 74, 36374, -1100, 65535), + (202211, 75, 77272, -1100, 65535), + (202211, 76, 77234, -1100, 65535), + (202211, 77, 77235, -1100, 65535), + (202211, 78, 77238, -1100, 65535), + (202211, 79, 77233, -1100, 65535), + (202211, 80, 77837, -1100, 65535); + +UPDATE npc_types SET lastname = 'Enchanter Spells 61-70' WHERE name = 'Illusionist_Acored'; + +UPDATE spawn2 SET x = '1056.00', y = '-53.00', z = '-63.37', heading = '357.89' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Illusionist_Acored') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202204; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202204, 1, 15396, -1100, 65535), + (202204, 2, 36364, -1100, 65535), + (202204, 3, 36365, -1100, 65535), + (202204, 4, 36366, -1100, 65535), + (202204, 5, 23525, -1100, 65535), + (202204, 6, 15004, -1100, 65535), + (202204, 7, 15083, -1100, 65535), + (202204, 8, 15335, -1100, 65535), + (202204, 9, 7632, -1100, 65535), + (202204, 10, 15068, -1100, 65535), + (202204, 11, 15497, -1100, 65535), + (202204, 12, 15663, -1100, 65535), + (202204, 13, 15852, -1100, 65535), + (202204, 14, 15108, -1100, 65535), + (202204, 15, 15411, -1100, 65535), + (202204, 16, 15498, -1100, 65535), + (202204, 17, 26970, -1100, 65535), + (202204, 18, 15101, -1100, 65535), + (202204, 19, 15102, -1100, 65535), + (202204, 20, 15499, -1100, 65535), + (202204, 21, 36367, -1100, 65535), + (202204, 22, 15055, -1100, 65535), + (202204, 23, 15496, -1100, 65535), + (202204, 24, 23517, -1100, 65535), + (202204, 25, 15056, -1100, 65535), + (202204, 26, 15110, -1100, 65535), + (202204, 27, 15189, -1100, 65535), + (202204, 28, 15570, -1100, 65535), + (202204, 29, 15113, -1100, 65535), + (202204, 30, 15571, -1100, 65535), + (202204, 31, 59661, -1100, 65535), + (202204, 32, 15065, -1100, 65535), + (202204, 33, 15572, -1100, 65535), + (202204, 34, 15615, -1100, 65535), + (202204, 35, 36380, -1100, 65535), + (202204, 36, 59673, -1100, 65535), + (202204, 37, 59685, -1100, 65535), + (202204, 38, 15115, -1100, 65535), + (202204, 39, 15569, -1100, 65535), + (202204, 40, 7633, -1100, 65535), + (202204, 41, 15081, -1100, 65535), + (202204, 42, 15246, -1100, 65535), + (202204, 43, 15322, -1100, 65535), + (202204, 44, 15323, -1100, 65535), + (202204, 45, 15325, -1100, 65535), + (202204, 46, 15398, -1100, 65535), + (202204, 47, 36377, -1100, 65535), + (202204, 48, 36378, -1100, 65535), + (202204, 49, 36379, -1100, 65535), + (202204, 50, 59565, -1100, 65535), + (202204, 51, 23522, -1100, 65535), + (202204, 52, 15050, -1100, 65535), + (202204, 53, 15093, -1100, 65535), + (202204, 54, 15205, -1100, 65535), + (202204, 55, 15211, -1100, 65535), + (202204, 56, 15288, -1100, 65535), + (202204, 57, 15310, -1100, 65535), + (202204, 58, 15311, -1100, 65535), + (202204, 59, 15313, -1100, 65535), + (202204, 60, 15331, -1100, 65535), + (202204, 61, 15315, -1100, 65535), + (202204, 62, 15318, -1100, 65535), + (202204, 63, 23516, -1100, 65535), + (202204, 64, 15232, -1100, 65535), + (202204, 65, 15316, -1100, 65535), + (202204, 66, 15321, -1100, 65535), + (202204, 67, 15036, -1100, 65535), + (202204, 68, 15094, -1100, 65535), + (202204, 69, 15317, -1100, 65535), + (202204, 70, 15058, -1100, 65535), + (202204, 71, 15324, -1100, 65535), + (202204, 72, 15332, -1100, 65535), + (202204, 73, 15399, -1100, 65535), + (202204, 74, 15851, -1100, 65535), + (202204, 75, 15042, -1100, 65535), + (202204, 76, 15400, -1100, 65535), + (202204, 77, 15613, -1100, 65535), + (202204, 78, 23519, -1100, 65535), + (202204, 79, 15248, -1100, 65535), + (202204, 80, 15319, -1100, 65535), + (202204, 81, 15397, -1100, 65535), + (202204, 82, 15048, -1100, 65535), + (202204, 83, 15330, -1100, 65535), + (202204, 84, 15402, -1100, 65535), + (202204, 85, 23528, -1100, 65535), + (202204, 86, 15327, -1100, 65535), + (202204, 87, 15403, -1100, 65535), + (202204, 88, 7631, -1100, 65535), + (202204, 89, 15035, -1100, 65535), + (202204, 90, 15328, -1100, 65535), + (202204, 91, 15404, -1100, 65535), + (202204, 92, 15305, -1100, 65535), + (202204, 93, 15333, -1100, 65535), + (202204, 94, 15401, -1100, 65535), + (202204, 95, 59660, -1100, 65535), + (202204, 96, 15336, -1100, 65535), + (202204, 97, 15614, -1100, 65535), + (202204, 98, 59672, -1100, 65535), + (202204, 99, 59684, -1100, 65535), + (202204, 100, 15100, -1100, 65535), + (202204, 101, 15320, -1100, 65535), + (202204, 102, 15334, -1100, 65535), + (202204, 103, 15395, -1100, 65535), + (202204, 104, 15080, -1100, 65535), + (202204, 105, 15309, -1100, 65535); + +UPDATE npc_types SET lastname = 'Magician Spells 1-25' WHERE name = 'Elementalist_Somat'; + +UPDATE spawn2 SET x = '1108.00', y = '100.00', z = '31.88', heading = '92.11' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Elementalist_Somat') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202208; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202208, 1, 15412, -1100, 65535), + (202208, 2, 15632, -1100, 65535), + (202208, 3, 59633, -1100, 65535), + (202208, 4, 15070, -1100, 65535), + (202208, 5, 15107, -1100, 65535), + (202208, 6, 15634, -1100, 65535), + (202208, 7, 15116, -1100, 65535), + (202208, 8, 15635, -1100, 65535), + (202208, 9, 7635, -1100, 65535), + (202208, 10, 15410, -1100, 65535), + (202208, 11, 15633, -1100, 65535), + (202208, 12, 19503, -1100, 65535), + (202208, 13, 23520, -1100, 65535), + (202208, 14, 15479, -1100, 65535), + (202208, 15, 15576, -1100, 65535), + (202208, 16, 15664, -1100, 65535), + (202208, 17, 15103, -1100, 65535), + (202208, 18, 15106, -1100, 65535), + (202208, 19, 15573, -1100, 65535), + (202208, 20, 15618, -1100, 65535), + (202208, 21, 36368, -1100, 65535), + (202208, 22, 30400, -1100, 65535), + (202208, 23, 23529, -1100, 65535), + (202208, 24, 15120, -1100, 65535), + (202208, 25, 15621, -1100, 65535), + (202208, 26, 30401, -1100, 65535), + (202208, 27, 15049, -1100, 65535), + (202208, 28, 15066, -1100, 65535), + (202208, 29, 15622, -1100, 65535), + (202208, 30, 15069, -1100, 65535), + (202208, 31, 15616, -1100, 65535), + (202208, 32, 15623, -1100, 65535), + (202208, 33, 59662, -1100, 65535), + (202208, 34, 15620, -1100, 65535), + (202208, 35, 26971, -1100, 65535), + (202208, 36, 36381, -1100, 65535), + (202208, 37, 59674, -1100, 65535), + (202208, 38, 59686, -1100, 65535), + (202208, 39, 15104, -1100, 65535), + (202208, 40, 15121, -1100, 65535), + (202208, 41, 15625, -1100, 65535), + (202208, 42, 19502, -1100, 65535), + (202208, 43, 15105, -1100, 65535), + (202208, 44, 15626, -1100, 65535), + (202208, 45, 15409, -1100, 65535), + (202208, 46, 15574, -1100, 65535), + (202208, 47, 15617, -1100, 65535), + (202208, 48, 15575, -1100, 65535), + (202208, 49, 36370, -1100, 65535), + (202208, 50, 30402, -1100, 65535), + (202208, 51, 23518, -1100, 65535), + (202208, 52, 23526, -1100, 65535), + (202208, 53, 15627, -1100, 65535), + (202208, 54, 15680, -1100, 65535), + (202208, 55, 7634, -1100, 65535), + (202208, 56, 15122, -1100, 65535), + (202208, 57, 15624, -1100, 65535), + (202208, 58, 36369, -1100, 65535), + (202208, 59, 15109, -1100, 65535), + (202208, 60, 15114, -1100, 65535), + (202208, 61, 15629, -1100, 65535), + (202208, 62, 15082, -1100, 65535), + (202208, 63, 15630, -1100, 65535), + (202208, 64, 23523, -1100, 65535), + (202208, 65, 59637, -1100, 65535), + (202208, 66, 59636, -1100, 65535), + (202208, 67, 15067, -1100, 65535), + (202208, 68, 15631, -1100, 65535), + (202208, 69, 30403, -1100, 65535), + (202208, 70, 15111, -1100, 65535), + (202208, 71, 15628, -1100, 65535), + (202208, 72, 36382, -1100, 65535), + (202208, 73, 59566, -1100, 65535), + (202208, 74, 15850, -1100, 65535), + (202208, 75, 59017, -1100, 65535); + +UPDATE npc_types SET lastname = 'Magician Spells 26-50' WHERE name = 'Elementalist_Kaeob'; + +UPDATE spawn2 SET x = '1101.00', y = '117.00', z = '31.88', heading = '2.11' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Elementalist_Kaeob') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202207; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202207, 1, 19262, -1100, 65535), + (202207, 2, 19372, -1100, 65535), + (202207, 3, 19418, -1100, 65535), + (202207, 4, 15112, -1100, 65535), + (202207, 5, 19346, -1100, 65535), + (202207, 6, 19347, -1100, 65535), + (202207, 7, 36372, -1100, 65535), + (202207, 8, 30404, -1100, 65535), + (202207, 9, 7640, -1100, 65535), + (202207, 10, 19497, -1100, 65535), + (202207, 11, 19536, -1100, 65535), + (202207, 12, 59632, -1100, 65535), + (202207, 13, 19350, -1100, 65535), + (202207, 14, 23521, -1100, 65535), + (202207, 15, 19349, -1100, 65535), + (202207, 16, 19351, -1100, 65535), + (202207, 17, 19352, -1100, 65535), + (202207, 18, 19355, -1100, 65535), + (202207, 19, 7636, -1100, 65535), + (202207, 20, 23530, -1100, 65535), + (202207, 21, 59018, -1100, 65535), + (202207, 22, 19207, -1100, 65535), + (202207, 23, 19354, -1100, 65535), + (202207, 24, 19357, -1100, 65535), + (202207, 25, 19368, -1100, 65535), + (202207, 26, 23527, -1100, 65535), + (202207, 27, 36383, -1100, 65535), + (202207, 28, 19300, -1100, 65535), + (202207, 29, 19356, -1100, 65535), + (202207, 30, 19358, -1100, 65535), + (202207, 31, 19362, -1100, 65535), + (202207, 32, 59567, -1100, 65535), + (202207, 33, 7637, -1100, 65535), + (202207, 34, 19521, -1100, 65535), + (202207, 35, 23524, -1100, 65535), + (202207, 36, 59559, -1100, 65535), + (202207, 37, 26969, -1100, 65535), + (202207, 38, 59939, -1100, 65535), + (202207, 39, 36371, -1100, 65535), + (202207, 40, 19359, -1100, 65535), + (202207, 41, 19360, -1100, 65535), + (202207, 42, 19361, -1100, 65535), + (202207, 43, 19417, -1100, 65535), + (202207, 44, 30405, -1100, 65535), + (202207, 45, 30472, -1100, 65535), + (202207, 46, 78030, -1100, 65535), + (202207, 47, 19245, -1100, 65535), + (202207, 48, 19353, -1100, 65535), + (202207, 49, 19363, -1100, 65535), + (202207, 50, 19364, -1100, 65535), + (202207, 51, 7638, -1100, 65535), + (202207, 52, 29364, -1100, 65535), + (202207, 53, 19365, -1100, 65535), + (202207, 54, 19366, -1100, 65535), + (202207, 55, 19411, -1100, 65535), + (202207, 56, 19282, -1100, 65535), + (202207, 57, 19348, -1100, 65535), + (202207, 58, 19367, -1100, 65535), + (202207, 59, 7639, -1100, 65535), + (202207, 60, 59634, -1100, 65535), + (202207, 61, 59638, -1100, 65535), + (202207, 62, 19369, -1100, 65535), + (202207, 63, 19370, -1100, 65535), + (202207, 64, 19371, -1100, 65535), + (202207, 65, 36384, -1100, 65535), + (202207, 66, 19501, -1100, 65535), + (202207, 67, 15863, -1100, 65535); + +UPDATE npc_types SET lastname = 'Magician Spells 51-60' WHERE name = 'Elementalist_Padan'; + +UPDATE spawn2 SET x = '1088.00', y = '117.00', z = '33.13', heading = '357.89' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Elementalist_Padan') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202206; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202206, 1, 77200, -1100, 65535), + (202206, 2, 77205, -1100, 65535), + (202206, 3, 77207, -1100, 65535), + (202206, 4, 77203, -1100, 65535), + (202206, 5, 77216, -1100, 65535), + (202206, 6, 77215, -1100, 65535), + (202206, 7, 77223, -1100, 65535), + (202206, 8, 77213, -1100, 65535), + (202206, 9, 77221, -1100, 65535), + (202206, 10, 29358, -1100, 65535), + (202206, 11, 29359, -1100, 65535), + (202206, 12, 29360, -1100, 65535), + (202206, 13, 29361, -1100, 65535), + (202206, 14, 59568, -1100, 65535), + (202206, 15, 76044, -1100, 65535), + (202206, 16, 32411, -1100, 65535), + (202206, 17, 21641, -1100, 65535), + (202206, 18, 21642, -1100, 65535), + (202206, 19, 28413, -1100, 65535), + (202206, 20, 28428, -1100, 65535), + (202206, 21, 28429, -1100, 65535), + (202206, 22, 28440, -1100, 65535), + (202206, 23, 29357, -1100, 65535), + (202206, 24, 21644, -1100, 65535), + (202206, 25, 28432, -1100, 65535), + (202206, 26, 28433, -1100, 65535), + (202206, 27, 28497, -1100, 65535), + (202206, 28, 29362, -1100, 65535), + (202206, 29, 29363, -1100, 65535), + (202206, 30, 21645, -1100, 65535), + (202206, 31, 21659, -1100, 65535), + (202206, 32, 21668, -1100, 65535), + (202206, 33, 28415, -1100, 65535), + (202206, 34, 28434, -1100, 65535), + (202206, 35, 28463, -1100, 65535), + (202206, 36, 36385, -1100, 65535), + (202206, 37, 59635, -1100, 65535), + (202206, 38, 16342, -1100, 65535), + (202206, 39, 28435, -1100, 65535), + (202206, 40, 28436, -1100, 65535), + (202206, 41, 28466, -1100, 65535), + (202206, 42, 28467, -1100, 65535), + (202206, 43, 36373, -1100, 65535), + (202206, 44, 59825, -1100, 65535), + (202206, 45, 59827, -1100, 65535), + (202206, 46, 59826, -1100, 65535), + (202206, 47, 77210, -1100, 65535), + (202206, 48, 77209, -1100, 65535), + (202206, 49, 77208, -1100, 65535), + (202206, 50, 77202, -1100, 65535), + (202206, 51, 77206, -1100, 65535), + (202206, 52, 77204, -1100, 65535), + (202206, 53, 77211, -1100, 65535), + (202206, 54, 77201, -1100, 65535), + (202206, 55, 77219, -1100, 65535), + (202206, 56, 77220, -1100, 65535), + (202206, 57, 77212, -1100, 65535), + (202206, 58, 77226, -1100, 65535), + (202206, 59, 77218, -1100, 65535), + (202206, 60, 41294, -1100, 65535), + (202206, 61, 77228, -1100, 65535), + (202206, 62, 77217, -1100, 65535), + (202206, 63, 77224, -1100, 65535), + (202206, 64, 77214, -1100, 65535), + (202206, 65, 36386, -1100, 65535), + (202206, 66, 77225, -1100, 65535), + (202206, 67, 76028, -1100, 65535), + (202206, 68, 41295, -1100, 65535), + (202206, 69, 77229, -1100, 65535), + (202206, 70, 77222, -1100, 65535), + (202206, 71, 77231, -1100, 65535), + (202206, 72, 36374, -1100, 65535), + (202206, 73, 77227, -1100, 65535), + (202206, 74, 77230, -1100, 65535), + (202206, 75, 41293, -1100, 65535), + (202206, 76, 43576, -1100, 65535), + (202206, 77, 78013, -1100, 65535), + (202206, 78, 78011, -1100, 65535), + (202206, 79, 21637, -1100, 65535), + (202206, 80, 21643, -1100, 65535), + (202206, 81, 21646, -1100, 65535), + (202206, 82, 21669, -1100, 65535), + (202206, 83, 28430, -1100, 65535), + (202206, 84, 28431, -1100, 65535), + (202206, 85, 28462, -1100, 65535), + (202206, 86, 59639, -1100, 65535), + (202206, 87, 16341, -1100, 65535); + +UPDATE npc_types SET lastname = 'Magician Spells 61-70' WHERE name = 'Elementalist_Siewth'; + +UPDATE spawn2 SET x = '1044.00', y = '116.00', z = '33.75', heading = '3.52' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Elementalist_Siewth') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202158; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202158, 1, 59973, -1100, 65535), + (202158, 2, 17709, -1100, 65535), + (202158, 3, 66412, -1100, 65535), + (202158, 4, 66200, -1100, 65535), + (202158, 5, 66320, -1100, 65535), + (202158, 6, 66201, -1100, 65535), + (202158, 7, 66321, -1100, 65535), + (202158, 8, 66260, -1100, 65535), + (202158, 9, 66261, -1100, 65535), + (202158, 10, 66262, -1100, 65535), + (202158, 11, 66263, -1100, 65535), + (202158, 12, 78021, -1100, 65535), + (202158, 13, 66264, -1100, 65535), + (202158, 14, 66265, -1100, 65535), + (202158, 15, 66322, -1100, 65535), + (202158, 16, 66266, -1100, 65535), + (202158, 17, 66267, -1100, 65535), + (202158, 18, 66268, -1100, 65535), + (202158, 19, 76051, -1100, 65535), + (202158, 20, 66269, -1100, 65535), + (202158, 21, 66410, -1100, 65535), + (202158, 22, 66323, -1100, 65535), + (202158, 23, 66270, -1100, 65535), + (202158, 24, 59912, -1100, 65535), + (202158, 25, 77289, -1100, 65535), + (202158, 26, 77291, -1100, 65535), + (202158, 27, 41270, -1100, 65535), + (202158, 28, 77285, -1100, 65535), + (202158, 29, 76034, -1100, 65535), + (202158, 30, 77290, -1100, 65535), + (202158, 31, 77984, -1100, 65535), + (202158, 32, 43565, -1100, 65535); + +UPDATE npc_types SET lastname = 'Monk Tomes' WHERE name = 'Beorobin_Amondson'; + +UPDATE spawn2 SET x = '831.00', y = '-73.00', z = '3.75', heading = '358.59' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Beorobin_Amondson') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202199; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202199, 1, 59666, -1100, 65535), + (202199, 2, 59690, -1100, 65535), + (202199, 3, 59672, -1100, 65535), + (202199, 4, 59684, -1100, 65535), + (202199, 5, 15048, -1100, 65535), + (202199, 6, 15364, -1100, 65535), + (202199, 7, 15365, -1100, 65535), + (202199, 8, 15371, -1100, 65535), + (202199, 9, 15309, -1100, 65535), + (202199, 10, 15366, -1100, 65535), + (202199, 11, 15368, -1100, 65535), + (202199, 12, 15369, -1100, 65535), + (202199, 13, 15492, -1100, 65535), + (202199, 14, 36364, -1100, 65535), + (202199, 15, 36365, -1100, 65535), + (202199, 16, 36366, -1100, 65535), + (202199, 17, 15305, -1100, 65535), + (202199, 18, 7642, -1100, 65535), + (202199, 19, 15855, -1100, 65535), + (202199, 20, 15221, -1100, 65535), + (202199, 21, 15235, -1100, 65535), + (202199, 22, 15288, -1100, 65535), + (202199, 23, 15331, -1100, 65535), + (202199, 24, 15338, -1100, 65535), + (202199, 25, 15339, -1100, 65535), + (202199, 26, 15340, -1100, 65535), + (202199, 27, 15341, -1100, 65535), + (202199, 28, 15342, -1100, 65535), + (202199, 29, 15343, -1100, 65535), + (202199, 30, 15205, -1100, 65535), + (202199, 31, 15229, -1100, 65535), + (202199, 32, 15347, -1100, 65535), + (202199, 33, 15225, -1100, 65535), + (202199, 34, 15346, -1100, 65535), + (202199, 35, 15502, -1100, 65535), + (202199, 36, 15036, -1100, 65535), + (202199, 37, 15344, -1100, 65535), + (202199, 38, 15348, -1100, 65535), + (202199, 39, 15196, -1100, 65535), + (202199, 40, 15642, -1100, 65535), + (202199, 41, 15698, -1100, 65535), + (202199, 42, 15233, -1100, 65535), + (202199, 43, 15370, -1100, 65535), + (202199, 44, 26970, -1100, 65535), + (202199, 45, 15199, -1100, 65535), + (202199, 46, 15413, -1100, 65535), + (202199, 47, 15440, -1100, 65535), + (202199, 48, 15446, -1100, 65535), + (202199, 49, 36367, -1100, 65535), + (202199, 50, 36377, -1100, 65535), + (202199, 51, 36378, -1100, 65535), + (202199, 52, 36379, -1100, 65535), + (202199, 53, 15204, -1100, 65535), + (202199, 54, 15478, -1100, 65535), + (202199, 55, 15857, -1100, 65535), + (202199, 56, 15859, -1100, 65535), + (202199, 57, 15090, -1100, 65535), + (202199, 58, 15387, -1100, 65535), + (202199, 59, 15549, -1100, 65535), + (202199, 60, 15448, -1100, 65535), + (202199, 61, 15449, -1100, 65535), + (202199, 62, 59679, -1100, 65535), + (202199, 63, 59661, -1100, 65535), + (202199, 64, 15061, -1100, 65535), + (202199, 65, 15065, -1100, 65535), + (202199, 66, 15493, -1100, 65535), + (202199, 67, 36380, -1100, 65535), + (202199, 68, 59667, -1100, 65535), + (202199, 69, 59691, -1100, 65535), + (202199, 70, 59673, -1100, 65535), + (202199, 71, 59685, -1100, 65535), + (202199, 72, 15059, -1100, 65535), + (202199, 73, 15491, -1100, 65535), + (202199, 74, 15352, -1100, 65535), + (202199, 75, 15354, -1100, 65535), + (202199, 76, 15218, -1100, 65535), + (202199, 77, 15357, -1100, 65535), + (202199, 78, 15641, -1100, 65535), + (202199, 79, 15353, -1100, 65535), + (202199, 80, 15359, -1100, 65535), + (202199, 81, 15522, -1100, 65535), + (202199, 82, 15246, -1100, 65535), + (202199, 83, 15351, -1100, 65535), + (202199, 84, 15358, -1100, 65535), + (202199, 85, 15361, -1100, 65535), + (202199, 86, 15363, -1100, 65535), + (202199, 87, 15854, -1100, 65535), + (202199, 88, 15209, -1100, 65535), + (202199, 89, 15360, -1100, 65535), + (202199, 90, 15856, -1100, 65535), + (202199, 91, 15226, -1100, 65535), + (202199, 92, 15355, -1100, 65535), + (202199, 93, 7641, -1100, 65535), + (202199, 94, 15035, -1100, 65535), + (202199, 95, 15362, -1100, 65535), + (202199, 96, 15445, -1100, 65535), + (202199, 97, 28216, -1100, 65535), + (202199, 98, 15213, -1100, 65535), + (202199, 99, 15367, -1100, 65535), + (202199, 100, 59678, -1100, 65535), + (202199, 101, 59660, -1100, 65535), + (202199, 102, 15236, -1100, 65535); + +UPDATE npc_types SET lastname = 'Necromancer Spells 1-25' WHERE name = 'Heretic_Drahur'; + +UPDATE spawn2 SET x = '738.00', y = '15.00', z = '-92.25', heading = '185.63' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Heretic_Drahur') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202203; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202203, 1, 15230, -1100, 65535), + (202203, 2, 15435, -1100, 65535), + (202203, 3, 36381, -1100, 65535), + (202203, 4, 59668, -1100, 65535), + (202203, 5, 59692, -1100, 65535), + (202203, 6, 59674, -1100, 65535), + (202203, 7, 59686, -1100, 65535), + (202203, 8, 15003, -1100, 65535), + (202203, 9, 15031, -1100, 65535), + (202203, 10, 19495, -1100, 65535), + (202203, 11, 59019, -1100, 65535), + (202203, 12, 15118, -1100, 65535), + (202203, 13, 16240, -1100, 65535), + (202203, 14, 7645, -1100, 65535), + (202203, 15, 15006, -1100, 65535), + (202203, 16, 15198, -1100, 65535), + (202203, 17, 15453, -1100, 65535), + (202203, 18, 15443, -1100, 65535), + (202203, 19, 15447, -1100, 65535), + (202203, 20, 15644, -1100, 65535), + (202203, 21, 15456, -1100, 65535), + (202203, 22, 26958, -1100, 65535), + (202203, 23, 59616, -1100, 65535), + (202203, 24, 15436, -1100, 65535), + (202203, 25, 36370, -1100, 65535), + (202203, 26, 30411, -1100, 65535), + (202203, 27, 15661, -1100, 65535), + (202203, 28, 15096, -1100, 65535), + (202203, 29, 15415, -1100, 65535), + (202203, 30, 30412, -1100, 65535), + (202203, 31, 15049, -1100, 65535), + (202203, 32, 15858, -1100, 65535), + (202203, 33, 15662, -1100, 65535), + (202203, 34, 7644, -1100, 65535), + (202203, 35, 15442, -1100, 65535), + (202203, 36, 15525, -1100, 65535), + (202203, 37, 59619, -1100, 65535), + (202203, 38, 19502, -1100, 65535), + (202203, 39, 36369, -1100, 65535), + (202203, 40, 15853, -1100, 65535), + (202203, 41, 15067, -1100, 65535), + (202203, 42, 15457, -1100, 65535), + (202203, 43, 15559, -1100, 65535), + (202203, 44, 19479, -1100, 65535), + (202203, 45, 15394, -1100, 65535), + (202203, 46, 30413, -1100, 65535), + (202203, 47, 15860, -1100, 65535), + (202203, 48, 15495, -1100, 65535), + (202203, 49, 15694, -1100, 65535), + (202203, 50, 36382, -1100, 65535), + (202203, 51, 59622, -1100, 65535), + (202203, 52, 78325, -1100, 65535), + (202203, 53, 15444, -1100, 65535), + (202203, 54, 15524, -1100, 65535), + (202203, 55, 15414, -1100, 65535), + (202203, 56, 15452, -1100, 65535), + (202203, 57, 7643, -1100, 65535), + (202203, 58, 15117, -1100, 65535), + (202203, 59, 15451, -1100, 65535), + (202203, 60, 15441, -1100, 65535), + (202203, 61, 15454, -1100, 65535), + (202203, 62, 15127, -1100, 65535), + (202203, 63, 36368, -1100, 65535), + (202203, 64, 15063, -1100, 65535), + (202203, 65, 15197, -1100, 65535), + (202203, 66, 15643, -1100, 65535), + (202203, 67, 15393, -1100, 65535), + (202203, 68, 15455, -1100, 65535), + (202203, 69, 30415, -1100, 65535), + (202203, 70, 15066, -1100, 65535), + (202203, 71, 15494, -1100, 65535), + (202203, 72, 59680, -1100, 65535), + (202203, 73, 59662, -1100, 65535); + +UPDATE npc_types SET lastname = 'Necromancer Spells 26-50' WHERE name = 'Heretic_Elirev'; + +UPDATE spawn2 SET x = '717.00', y = '46.00', z = '-91.94', heading = '274.22' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Heretic_Elirev') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202202; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202202, 1, 19220, -1100, 65535), + (202202, 2, 19304, -1100, 65535), + (202202, 3, 19305, -1100, 65535), + (202202, 4, 19314, -1100, 65535), + (202202, 5, 19410, -1100, 65535), + (202202, 6, 7648, -1100, 65535), + (202202, 7, 77844, -1100, 65535), + (202202, 8, 78326, -1100, 65535), + (202202, 9, 19214, -1100, 65535), + (202202, 10, 19306, -1100, 65535), + (202202, 11, 19307, -1100, 65535), + (202202, 12, 77832, -1100, 65535), + (202202, 13, 15132, -1100, 65535), + (202202, 14, 19308, -1100, 65535), + (202202, 15, 19309, -1100, 65535), + (202202, 16, 7649, -1100, 65535), + (202202, 17, 59617, -1100, 65535), + (202202, 18, 59623, -1100, 65535), + (202202, 19, 19310, -1100, 65535), + (202202, 20, 19311, -1100, 65535), + (202202, 21, 19312, -1100, 65535), + (202202, 22, 36384, -1100, 65535), + (202202, 23, 19228, -1100, 65535), + (202202, 24, 19313, -1100, 65535), + (202202, 25, 19425, -1100, 65535), + (202202, 26, 19496, -1100, 65535), + (202202, 27, 36372, -1100, 65535), + (202202, 28, 30416, -1100, 65535), + (202202, 29, 30460, -1100, 65535), + (202202, 30, 7650, -1100, 65535), + (202202, 31, 19527, -1100, 65535), + (202202, 32, 19202, -1100, 65535), + (202202, 33, 19294, -1100, 65535), + (202202, 34, 19421, -1100, 65535), + (202202, 35, 15032, -1100, 65535), + (202202, 36, 19295, -1100, 65535), + (202202, 37, 19296, -1100, 65535), + (202202, 38, 19408, -1100, 65535), + (202202, 39, 7646, -1100, 65535), + (202202, 40, 59005, -1100, 65535), + (202202, 41, 15131, -1100, 65535), + (202202, 42, 19207, -1100, 65535), + (202202, 43, 19297, -1100, 65535), + (202202, 44, 19423, -1100, 65535), + (202202, 45, 36383, -1100, 65535), + (202202, 46, 19298, -1100, 65535), + (202202, 47, 19299, -1100, 65535), + (202202, 48, 19300, -1100, 65535), + (202202, 49, 19409, -1100, 65535), + (202202, 50, 7647, -1100, 65535), + (202202, 51, 26959, -1100, 65535), + (202202, 52, 59620, -1100, 65535), + (202202, 53, 36371, -1100, 65535), + (202202, 54, 19301, -1100, 65535), + (202202, 55, 19302, -1100, 65535), + (202202, 56, 19303, -1100, 65535), + (202202, 57, 19424, -1100, 65535), + (202202, 58, 19480, -1100, 65535), + (202202, 59, 30414, -1100, 65535), + (202202, 60, 78031, -1100, 65535); + +UPDATE npc_types SET lastname = 'Necromancer Spells 51-60' WHERE name = 'Heretic_Edalith'; + +UPDATE spawn2 SET x = '717.00', y = '112.00', z = '-94.12', heading = '272.81' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Heretic_Edalith') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202201; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202201, 1, 59828, -1100, 65535), + (202201, 2, 59830, -1100, 65535), + (202201, 3, 17795, -1100, 65535), + (202201, 4, 77157, -1100, 65535), + (202201, 5, 77159, -1100, 65535), + (202201, 6, 77846, -1100, 65535), + (202201, 7, 77158, -1100, 65535), + (202201, 8, 77168, -1100, 65535), + (202201, 9, 77161, -1100, 65535), + (202201, 10, 77160, -1100, 65535), + (202201, 11, 77167, -1100, 65535), + (202201, 12, 77156, -1100, 65535), + (202201, 13, 77834, -1100, 65535), + (202201, 14, 77166, -1100, 65535), + (202201, 15, 77162, -1100, 65535), + (202201, 16, 77163, -1100, 65535), + (202201, 17, 77274, -1100, 65535), + (202201, 18, 41266, -1100, 65535), + (202201, 19, 77172, -1100, 65535), + (202201, 20, 77165, -1100, 65535), + (202201, 21, 77171, -1100, 65535), + (202201, 22, 77164, -1100, 65535), + (202201, 23, 36386, -1100, 65535), + (202201, 24, 77173, -1100, 65535), + (202201, 25, 76026, -1100, 65535), + (202201, 26, 41267, -1100, 65535), + (202201, 27, 77169, -1100, 65535), + (202201, 28, 77174, -1100, 65535), + (202201, 29, 77170, -1100, 65535), + (202201, 30, 77176, -1100, 65535), + (202201, 31, 36374, -1100, 65535), + (202201, 32, 77175, -1100, 65535), + (202201, 33, 41265, -1100, 65535), + (202201, 34, 78016, -1100, 65535), + (202201, 35, 78014, -1100, 65535), + (202201, 36, 43577, -1100, 65535), + (202201, 37, 21638, -1100, 65535), + (202201, 38, 21640, -1100, 65535), + (202201, 39, 28413, -1100, 65535), + (202201, 40, 28417, -1100, 65535), + (202201, 41, 28426, -1100, 65535), + (202201, 42, 77845, -1100, 65535), + (202201, 43, 76042, -1100, 65535), + (202201, 44, 26946, -1100, 65535), + (202201, 45, 28418, -1100, 65535), + (202201, 46, 28419, -1100, 65535), + (202201, 47, 28454, -1100, 65535), + (202201, 48, 77833, -1100, 65535), + (202201, 49, 21691, -1100, 65535), + (202201, 50, 21694, -1100, 65535), + (202201, 51, 26945, -1100, 65535), + (202201, 52, 28414, -1100, 65535), + (202201, 53, 28420, -1100, 65535), + (202201, 54, 28421, -1100, 65535), + (202201, 55, 28422, -1100, 65535), + (202201, 56, 59621, -1100, 65535), + (202201, 57, 28415, -1100, 65535), + (202201, 58, 28423, -1100, 65535), + (202201, 59, 28424, -1100, 65535), + (202201, 60, 36385, -1100, 65535), + (202201, 61, 59618, -1100, 65535), + (202201, 62, 28416, -1100, 65535), + (202201, 63, 28425, -1100, 65535), + (202201, 64, 28427, -1100, 65535), + (202201, 65, 28559, -1100, 65535), + (202201, 66, 36373, -1100, 65535), + (202201, 67, 59829, -1100, 65535); + +UPDATE npc_types SET lastname = 'Necromancer Spells 61-70' WHERE name = 'Heretic_Ceikon'; + +UPDATE spawn2 SET x = '763.00', y = '94.00', z = '-92.25', heading = '142.03' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Heretic_Ceikon') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202194; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202194, 1, 15209, -1100, 65535), + (202194, 2, 15210, -1100, 65535), + (202194, 3, 15208, -1100, 65535), + (202194, 4, 59971, -1100, 65535), + (202194, 5, 15201, -1100, 65535), + (202194, 6, 15205, -1100, 65535), + (202194, 7, 15221, -1100, 65535), + (202194, 8, 15203, -1100, 65535), + (202194, 9, 15200, -1100, 65535), + (202194, 10, 7681, -1100, 65535), + (202194, 11, 15202, -1100, 65535), + (202194, 12, 15213, -1100, 65535), + (202194, 13, 15017, -1100, 65535), + (202194, 14, 7682, -1100, 65535), + (202194, 15, 15218, -1100, 65535), + (202194, 16, 15223, -1100, 65535), + (202194, 17, 15011, -1100, 65535), + (202194, 18, 15234, -1100, 65535), + (202194, 19, 15235, -1100, 65535), + (202194, 20, 15215, -1100, 65535), + (202194, 21, 15230, -1100, 65535), + (202194, 22, 59580, -1100, 65535), + (202194, 23, 15219, -1100, 65535), + (202194, 24, 15227, -1100, 65535), + (202194, 25, 23480, -1100, 65535), + (202194, 26, 15037, -1100, 65535), + (202194, 27, 15485, -1100, 65535), + (202194, 28, 15501, -1100, 65535); + +UPDATE npc_types SET lastname = 'Paladin Spells 1-25' WHERE name = 'Cavalier_Waut'; + +UPDATE spawn2 SET x = '1076.00', y = '-2.00', z = '66.50', heading = '91.41' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Cavalier_Waut') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202198; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202198, 1, 15391, -1100, 65535), + (202198, 2, 26964, -1100, 65535), + (202198, 3, 15123, -1100, 65535), + (202198, 4, 15047, -1100, 65535), + (202198, 5, 7685, -1100, 65535), + (202198, 6, 59003, -1100, 65535), + (202198, 7, 15693, -1100, 65535), + (202198, 8, 19542, -1100, 65535), + (202198, 9, 36012, -1100, 65535), + (202198, 10, 15117, -1100, 65535), + (202198, 11, 15487, -1100, 65535), + (202198, 12, 30454, -1100, 65535), + (202198, 13, 23482, -1100, 65535), + (202198, 14, 15048, -1100, 65535), + (202198, 15, 15486, -1100, 65535), + (202198, 16, 15095, -1100, 65535), + (202198, 17, 59581, -1100, 65535), + (202198, 18, 7684, -1100, 65535), + (202198, 19, 15015, -1100, 65535), + (202198, 20, 15089, -1100, 65535), + (202198, 21, 30453, -1100, 65535), + (202198, 22, 15043, -1100, 65535), + (202198, 23, 15226, -1100, 65535), + (202198, 24, 15018, -1100, 65535), + (202198, 25, 15312, -1100, 65535), + (202198, 26, 7686, -1100, 65535), + (202198, 27, 15019, -1100, 65535), + (202198, 28, 15207, -1100, 65535), + (202198, 29, 15045, -1100, 65535), + (202198, 30, 23483, -1100, 65535), + (202198, 31, 26965, -1100, 65535), + (202198, 32, 15063, -1100, 65535), + (202198, 33, 15233, -1100, 65535), + (202198, 34, 15368, -1100, 65535), + (202198, 35, 23481, -1100, 65535), + (202198, 36, 7683, -1100, 65535), + (202198, 37, 15012, -1100, 65535), + (202198, 38, 15216, -1100, 65535), + (202198, 39, 15228, -1100, 65535); + +UPDATE npc_types SET lastname = 'Paladin Spells 26-50' WHERE name = 'Cavalier_Aodus'; + +UPDATE spawn2 SET x = '1075.00', y = '-60.00', z = '67.75', heading = '86.48' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Cavalier_Aodus') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202197; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202197, 1, 15124, -1100, 65535), + (202197, 2, 15504, -1100, 65535), + (202197, 3, 59004, -1100, 65535), + (202197, 4, 19505, -1100, 65535), + (202197, 5, 59527, -1100, 65535), + (202197, 6, 15131, -1100, 65535), + (202197, 7, 15662, -1100, 65535), + (202197, 8, 7687, -1100, 65535), + (202197, 9, 15064, -1100, 65535), + (202197, 10, 23484, -1100, 65535), + (202197, 11, 19432, -1100, 65535), + (202197, 12, 30455, -1100, 65535), + (202197, 13, 59582, -1100, 65535), + (202197, 14, 78023, -1100, 65535), + (202197, 15, 15044, -1100, 65535), + (202197, 16, 15096, -1100, 65535), + (202197, 17, 7688, -1100, 65535), + (202197, 18, 15009, -1100, 65535), + (202197, 19, 15049, -1100, 65535), + (202197, 20, 15488, -1100, 65535), + (202197, 21, 7689, -1100, 65535), + (202197, 22, 59583, -1100, 65535), + (202197, 23, 15392, -1100, 65535), + (202197, 24, 19500, -1100, 65535), + (202197, 25, 15020, -1100, 65535), + (202197, 26, 15314, -1100, 65535), + (202197, 27, 19209, -1100, 65535), + (202197, 28, 30456, -1100, 65535), + (202197, 29, 7690, -1100, 65535), + (202197, 30, 19522, -1100, 65535); + +UPDATE npc_types SET lastname = 'Paladin Spells 51-60' WHERE name = 'Cavalier_Preradus'; + +UPDATE spawn2 SET x = '1038.00', y = '-88.00', z = '67.75', heading = '269.30' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Cavalier_Preradus') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202196; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202196, 1, 15062, -1100, 65535), + (202196, 2, 19204, -1100, 65535), + (202196, 3, 21631, -1100, 65535), + (202196, 4, 26945, -1100, 65535), + (202196, 5, 21652, -1100, 65535), + (202196, 6, 26933, -1100, 65535), + (202196, 7, 26937, -1100, 65535), + (202196, 8, 26941, -1100, 65535), + (202196, 9, 19211, -1100, 65535), + (202196, 10, 30411, -1100, 65535), + (202196, 11, 26934, -1100, 65535), + (202196, 12, 26939, -1100, 65535), + (202196, 13, 19224, -1100, 65535), + (202196, 14, 21649, -1100, 65535), + (202196, 15, 21654, -1100, 65535), + (202196, 16, 26935, -1100, 65535), + (202196, 17, 19219, -1100, 65535), + (202196, 18, 77031, -1100, 65535), + (202196, 19, 77029, -1100, 65535), + (202196, 20, 77030, -1100, 65535), + (202196, 21, 77032, -1100, 65535), + (202196, 22, 77033, -1100, 65535), + (202196, 23, 77034, -1100, 65535), + (202196, 24, 77042, -1100, 65535), + (202196, 25, 77036, -1100, 65535), + (202196, 26, 77035, -1100, 65535), + (202196, 27, 77039, -1100, 65535), + (202196, 28, 41286, -1100, 65535), + (202196, 29, 77038, -1100, 65535), + (202196, 30, 77041, -1100, 65535), + (202196, 31, 77037, -1100, 65535), + (202196, 32, 77040, -1100, 65535), + (202196, 33, 41287, -1100, 65535), + (202196, 34, 77045, -1100, 65535), + (202196, 35, 77044, -1100, 65535), + (202196, 36, 77043, -1100, 65535), + (202196, 37, 43567, -1100, 65535), + (202196, 38, 77988, -1100, 65535), + (202196, 39, 17794, -1100, 65535), + (202196, 40, 21653, -1100, 65535), + (202196, 41, 26936, -1100, 65535), + (202196, 42, 26938, -1100, 65535), + (202196, 43, 59584, -1100, 65535), + (202196, 44, 59833, -1100, 65535), + (202196, 45, 59832, -1100, 65535), + (202196, 46, 59831, -1100, 65535), + (202196, 47, 77028, -1100, 65535); + +UPDATE npc_types SET lastname = 'Paladin Spells 61-70' WHERE name = 'Cavalier_Cerakor'; + +UPDATE spawn2 SET x = '1075.00', y = '63.00', z = '67.75', heading = '90.70' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Cavalier_Cerakor') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202195; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202195, 1, 17796, -1100, 65535); + +UPDATE npc_types SET lastname = 'Paladin Spells 71-80' WHERE name = 'Cavalier_Ethigom'; + +UPDATE spawn2 SET x = '1054.00', y = '89.00', z = '67.32', heading = '0.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Cavalier_Ethigom') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202309; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202309, 1, 66200, -1100, 65535), + (202309, 2, 66201, -1100, 65535), + (202309, 3, 66240, -1100, 65535), + (202309, 4, 66241, -1100, 65535), + (202309, 5, 41281, -1100, 65535); + +UPDATE npc_types SET lastname = 'Ranger Tomes' WHERE name = 'Keshyk_Wardorn'; + +UPDATE spawn2 SET x = '943.00', y = '-87.00', z = '3.13', heading = '175.78' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Keshyk_Wardorn') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202189; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202189, 1, 15086, -1100, 65535), + (202189, 2, 15017, -1100, 65535), + (202189, 3, 15263, -1100, 65535), + (202189, 4, 15213, -1100, 65535), + (202189, 5, 15250, -1100, 65535), + (202189, 6, 15256, -1100, 65535), + (202189, 7, 15264, -1100, 65535), + (202189, 8, 59971, -1100, 65535), + (202189, 9, 15051, -1100, 65535), + (202189, 10, 15239, -1100, 65535), + (202189, 11, 15240, -1100, 65535), + (202189, 12, 7691, -1100, 65535), + (202189, 13, 15242, -1100, 65535), + (202189, 14, 15026, -1100, 65535), + (202189, 15, 15200, -1100, 65535), + (202189, 16, 15224, -1100, 65535), + (202189, 17, 15237, -1100, 65535), + (202189, 18, 7692, -1100, 65535), + (202189, 19, 15269, -1100, 65535), + (202189, 20, 15203, -1100, 65535), + (202189, 21, 15515, -1100, 65535), + (202189, 22, 15092, -1100, 65535), + (202189, 23, 15247, -1100, 65535), + (202189, 24, 15249, -1100, 65535), + (202189, 25, 15252, -1100, 65535), + (202189, 26, 15241, -1100, 65535), + (202189, 27, 15248, -1100, 65535), + (202189, 28, 15254, -1100, 65535), + (202189, 29, 15500, -1100, 65535), + (202189, 30, 15225, -1100, 65535), + (202189, 31, 15091, -1100, 65535); + +UPDATE npc_types SET lastname = 'Ranger Spells 1-25' WHERE name = 'Pathfinder_Viliken'; + +UPDATE spawn2 SET x = '882.00', y = '5.00', z = '67.13', heading = '90.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Pathfinder_Viliken') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202193; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202193, 1, 15268, -1100, 65535), + (202193, 2, 15655, -1100, 65535), + (202193, 3, 15278, -1100, 65535), + (202193, 4, 7693, -1100, 65535), + (202193, 5, 26952, -1100, 65535), + (202193, 6, 15048, -1100, 65535), + (202193, 7, 15516, -1100, 65535), + (202193, 8, 15513, -1100, 65535), + (202193, 9, 15080, -1100, 65535), + (202193, 10, 15115, -1100, 65535), + (202193, 11, 15517, -1100, 65535), + (202193, 12, 15261, -1100, 65535), + (202193, 13, 30461, -1100, 65535), + (202193, 14, 15419, -1100, 65535), + (202193, 15, 7694, -1100, 65535), + (202193, 16, 15012, -1100, 65535), + (202193, 17, 15421, -1100, 65535), + (202193, 18, 21960, -1100, 65535), + (202193, 19, 26951, -1100, 65535), + (202193, 20, 59007, -1100, 65535), + (202193, 21, 59585, -1100, 65535), + (202193, 22, 15518, -1100, 65535), + (202193, 23, 15129, -1100, 65535), + (202193, 24, 15078, -1100, 65535), + (202193, 25, 15076, -1100, 65535), + (202193, 26, 15060, -1100, 65535), + (202193, 27, 15034, -1100, 65535), + (202193, 28, 15425, -1100, 65535), + (202193, 29, 7695, -1100, 65535), + (202193, 30, 15691, -1100, 65535), + (202193, 31, 59586, -1100, 65535), + (202193, 32, 19433, -1100, 65535), + (202193, 33, 30462, -1100, 65535); + +UPDATE npc_types SET lastname = 'Ranger Spells 26-50' WHERE name = 'Pathfinder_Vaered'; + +UPDATE spawn2 SET x = '823.00', y = '36.00', z = '66.19', heading = '270.70' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Pathfinder_Vaered') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202192; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202192, 1, 15490, -1100, 65535), + (202192, 2, 15519, -1100, 65535), + (202192, 3, 30464, -1100, 65535), + (202192, 4, 7700, -1100, 65535), + (202192, 5, 15512, -1100, 65535), + (202192, 6, 30476, -1100, 65535), + (202192, 7, 15057, -1100, 65535), + (202192, 8, 7696, -1100, 65535), + (202192, 9, 59008, -1100, 65535), + (202192, 10, 15430, -1100, 65535), + (202192, 11, 15259, -1100, 65535), + (202192, 12, 15422, -1100, 65535), + (202192, 13, 7697, -1100, 65535), + (202192, 14, 15061, -1100, 65535), + (202192, 15, 15145, -1100, 65535), + (202192, 16, 30463, -1100, 65535), + (202192, 17, 30477, -1100, 65535), + (202192, 18, 59589, -1100, 65535), + (202192, 19, 15426, -1100, 65535), + (202192, 20, 15539, -1100, 65535), + (202192, 21, 7698, -1100, 65535), + (202192, 22, 15015, -1100, 65535), + (202192, 23, 15049, -1100, 65535), + (202192, 24, 15432, -1100, 65535), + (202192, 25, 7699, -1100, 65535), + (202192, 26, 59587, -1100, 65535), + (202192, 27, 15423, -1100, 65535), + (202192, 28, 19426, -1100, 65535); + +UPDATE npc_types SET lastname = 'Ranger Spells 51-60' WHERE name = 'Pathfinder_Thoajin'; + +UPDATE spawn2 SET x = '827.00', y = '-40.00', z = '67.13', heading = '270.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Pathfinder_Thoajin') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202191; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202191, 1, 19207, -1100, 65535), + (202191, 2, 19232, -1100, 65535), + (202191, 3, 19245, -1100, 65535), + (202191, 4, 15095, -1100, 65535), + (202191, 5, 15096, -1100, 65535), + (202191, 6, 76038, -1100, 65535), + (202191, 7, 19507, -1100, 65535), + (202191, 8, 15356, -1100, 65535), + (202191, 9, 15665, -1100, 65535), + (202191, 10, 21627, -1100, 65535), + (202191, 11, 21628, -1100, 65535), + (202191, 12, 19234, -1100, 65535), + (202191, 13, 19249, -1100, 65535), + (202191, 14, 26931, -1100, 65535), + (202191, 15, 26943, -1100, 65535), + (202191, 16, 19243, -1100, 65535), + (202191, 17, 21626, -1100, 65535), + (202191, 18, 26929, -1100, 65535), + (202191, 19, 26930, -1100, 65535), + (202191, 20, 59588, -1100, 65535), + (202191, 21, 19251, -1100, 65535), + (202191, 22, 7617, -1100, 65535), + (202191, 23, 19529, -1100, 65535), + (202191, 24, 21655, -1100, 65535), + (202191, 25, 26932, -1100, 65535), + (202191, 26, 59835, -1100, 65535), + (202191, 27, 59836, -1100, 65535), + (202191, 28, 59834, -1100, 65535), + (202191, 29, 77048, -1100, 65535), + (202191, 30, 77047, -1100, 65535), + (202191, 31, 77049, -1100, 65535), + (202191, 32, 77052, -1100, 65535), + (202191, 33, 77050, -1100, 65535), + (202191, 34, 77053, -1100, 65535), + (202191, 35, 77051, -1100, 65535), + (202191, 36, 77054, -1100, 65535), + (202191, 37, 77055, -1100, 65535), + (202191, 38, 77056, -1100, 65535), + (202191, 39, 77677, -1100, 65535), + (202191, 40, 41282, -1100, 65535), + (202191, 41, 77059, -1100, 65535), + (202191, 42, 77058, -1100, 65535), + (202191, 43, 77060, -1100, 65535), + (202191, 44, 77057, -1100, 65535), + (202191, 45, 76022, -1100, 65535), + (202191, 46, 77063, -1100, 65535), + (202191, 47, 77061, -1100, 65535), + (202191, 48, 77062, -1100, 65535), + (202191, 49, 43570, -1100, 65535), + (202191, 50, 77994, -1100, 65535); + +UPDATE npc_types SET lastname = 'Ranger Spells 61-70' WHERE name = 'Pathfinder_Naend'; + +UPDATE spawn2 SET x = '821.00', y = '111.00', z = '67.32', heading = '180.70' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Pathfinder_Naend') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202156; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202156, 1, 59973, -1100, 65535), + (202156, 2, 17709, -1100, 65535), + (202156, 3, 66412, -1100, 65535), + (202156, 4, 66390, -1100, 65535), + (202156, 5, 66200, -1100, 65535), + (202156, 6, 66201, -1100, 65535), + (202156, 7, 66391, -1100, 65535), + (202156, 8, 66330, -1100, 65535), + (202156, 9, 66331, -1100, 65535), + (202156, 10, 66332, -1100, 65535), + (202156, 11, 78020, -1100, 65535), + (202156, 12, 66333, -1100, 65535), + (202156, 13, 66334, -1100, 65535), + (202156, 14, 66335, -1100, 65535), + (202156, 15, 76050, -1100, 65535), + (202156, 16, 66337, -1100, 65535), + (202156, 17, 66392, -1100, 65535), + (202156, 18, 66410, -1100, 65535), + (202156, 19, 66338, -1100, 65535), + (202156, 20, 59910, -1100, 65535), + (202156, 21, 77294, -1100, 65535), + (202156, 22, 77292, -1100, 65535), + (202156, 23, 41269, -1100, 65535), + (202156, 24, 77284, -1100, 65535), + (202156, 25, 76033, -1100, 65535), + (202156, 26, 77293, -1100, 65535), + (202156, 27, 43564, -1100, 65535), + (202156, 28, 77982, -1100, 65535); + +UPDATE npc_types SET lastname = 'Rogue Tomes' WHERE name = 'Blane_Darkblade'; + +UPDATE spawn2 SET x = '1071.00', y = '-115.00', z = '31.88', heading = '177.89' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Blane_Darkblade') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202308; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202308, 1, 66200, -1100, 65535), + (202308, 2, 66201, -1100, 65535), + (202308, 3, 66250, -1100, 65535), + (202308, 4, 77857, -1100, 65535), + (202308, 5, 66434, -1100, 65535), + (202308, 6, 66251, -1100, 65535), + (202308, 7, 76047, -1100, 65535), + (202308, 8, 76031, -1100, 65535); + +UPDATE npc_types SET lastname = 'Shadow Knight Tomes' WHERE name = 'Zhao_V`karin'; + +UPDATE spawn2 SET x = '818.00', y = '-73.00', z = '3.75', heading = '358.59' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Zhao_V`karin') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202184; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202184, 1, 59972, -1100, 65535), + (202184, 2, 15221, -1100, 65535), + (202184, 3, 15342, -1100, 65535), + (202184, 4, 15235, -1100, 65535), + (202184, 5, 15340, -1100, 65535), + (202184, 6, 15343, -1100, 65535), + (202184, 7, 15491, -1100, 65535), + (202184, 8, 15341, -1100, 65535), + (202184, 9, 15347, -1100, 65535), + (202184, 10, 7671, -1100, 65535), + (202184, 11, 15225, -1100, 65535), + (202184, 12, 15344, -1100, 65535), + (202184, 13, 15229, -1100, 65535), + (202184, 14, 28216, -1100, 65535), + (202184, 15, 15354, -1100, 65535), + (202184, 16, 15351, -1100, 65535), + (202184, 17, 15502, -1100, 65535), + (202184, 18, 7672, -1100, 65535), + (202184, 19, 15346, -1100, 65535), + (202184, 20, 15352, -1100, 65535), + (202184, 21, 15218, -1100, 65535), + (202184, 22, 15213, -1100, 65535), + (202184, 23, 26970, -1100, 65535), + (202184, 24, 15209, -1100, 65535), + (202184, 25, 15355, -1100, 65535), + (202184, 26, 15357, -1100, 65535), + (202184, 27, 15359, -1100, 65535), + (202184, 28, 15362, -1100, 65535), + (202184, 29, 7673, -1100, 65535), + (202184, 30, 15366, -1100, 65535); + +UPDATE npc_types SET lastname = 'Shadow Knight Spells 1-25' WHERE name = 'Reaver_Nydlil'; + +UPDATE spawn2 SET x = '790.00', y = '-54.00', z = '-91.94', heading = '265.08' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Reaver_Nydlil') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202188; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202188, 1, 15226, -1100, 65535), + (202188, 2, 15363, -1100, 65535), + (202188, 3, 15360, -1100, 65535), + (202188, 4, 15445, -1100, 65535), + (202188, 5, 19506, -1100, 65535), + (202188, 6, 15492, -1100, 65535), + (202188, 7, 15522, -1100, 65535), + (202188, 8, 15236, -1100, 65535), + (202188, 9, 59590, -1100, 65535), + (202188, 10, 24539, -1100, 65535), + (202188, 11, 26948, -1100, 65535), + (202188, 12, 15003, -1100, 65535), + (202188, 13, 15061, -1100, 65535), + (202188, 14, 30457, -1100, 65535), + (202188, 15, 15048, -1100, 65535), + (202188, 16, 15367, -1100, 65535), + (202188, 17, 15370, -1100, 65535), + (202188, 18, 7674, -1100, 65535), + (202188, 19, 15440, -1100, 65535), + (202188, 20, 15233, -1100, 65535), + (202188, 21, 24543, -1100, 65535), + (202188, 22, 15090, -1100, 65535), + (202188, 23, 59006, -1100, 65535), + (202188, 24, 24540, -1100, 65535), + (202188, 25, 15127, -1100, 65535), + (202188, 26, 15452, -1100, 65535), + (202188, 27, 15414, -1100, 65535), + (202188, 28, 15478, -1100, 65535), + (202188, 29, 15441, -1100, 65535), + (202188, 30, 24544, -1100, 65535), + (202188, 31, 15692, -1100, 65535), + (202188, 32, 59593, -1100, 65535), + (202188, 33, 26949, -1100, 65535), + (202188, 34, 15117, -1100, 65535), + (202188, 35, 15199, -1100, 65535), + (202188, 36, 30458, -1100, 65535); + +UPDATE npc_types SET lastname = 'Shadow Knight Spells 26-50' WHERE name = 'Reaver_Uledrith'; + +UPDATE spawn2 SET x = '733.00', y = '-34.00', z = '-92.25', heading = '359.30' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Reaver_Uledrith') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202187; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202187, 1, 15442, -1100, 65535), + (202187, 2, 15448, -1100, 65535), + (202187, 3, 19502, -1100, 65535), + (202187, 4, 7675, -1100, 65535), + (202187, 5, 7676, -1100, 65535), + (202187, 6, 59005, -1100, 65535), + (202187, 7, 15451, -1100, 65535), + (202187, 8, 24541, -1100, 65535), + (202187, 9, 15059, -1100, 65535), + (202187, 10, 15364, -1100, 65535), + (202187, 11, 7677, -1100, 65535), + (202187, 12, 26950, -1100, 65535), + (202187, 13, 59591, -1100, 65535), + (202187, 14, 59594, -1100, 65535), + (202187, 15, 15524, -1100, 65535), + (202187, 16, 15662, -1100, 65535), + (202187, 17, 19431, -1100, 65535), + (202187, 18, 19490, -1100, 65535), + (202187, 19, 24545, -1100, 65535), + (202187, 20, 30459, -1100, 65535), + (202187, 21, 15393, -1100, 65535), + (202187, 22, 7678, -1100, 65535), + (202187, 23, 77847, -1100, 65535), + (202187, 24, 15454, -1100, 65535), + (202187, 25, 15525, -1100, 65535), + (202187, 26, 19307, -1100, 65535), + (202187, 27, 77838, -1100, 65535), + (202187, 28, 15049, -1100, 65535), + (202187, 29, 15495, -1100, 65535), + (202187, 30, 7679, -1100, 65535), + (202187, 31, 19532, -1100, 65535), + (202187, 32, 15394, -1100, 65535), + (202187, 33, 15453, -1100, 65535), + (202187, 34, 24542, -1100, 65535), + (202187, 35, 15447, -1100, 65535), + (202187, 36, 15661, -1100, 65535), + (202187, 37, 15853, -1100, 65535), + (202187, 38, 24546, -1100, 65535), + (202187, 39, 30460, -1100, 65535), + (202187, 40, 7680, -1100, 65535), + (202187, 41, 15446, -1100, 65535); + +UPDATE npc_types SET lastname = 'Shadow Knight Spells 51-60' WHERE name = 'Reaver_Thirlan'; + +UPDATE spawn2 SET x = '722.00', y = '-56.00', z = '-92.87', heading = '267.19' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Reaver_Thirlan') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202186; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202186, 1, 15006, -1100, 65535), + (202186, 2, 30411, -1100, 65535), + (202186, 3, 26920, -1100, 65535), + (202186, 4, 26924, -1100, 65535), + (202186, 5, 77848, -1100, 65535), + (202186, 6, 15456, -1100, 65535), + (202186, 7, 26921, -1100, 65535), + (202186, 8, 26925, -1100, 65535), + (202186, 9, 26937, -1100, 65535), + (202186, 10, 77839, -1100, 65535), + (202186, 11, 21633, -1100, 65535), + (202186, 12, 21651, -1100, 65535), + (202186, 13, 26922, -1100, 65535), + (202186, 14, 26923, -1100, 65535), + (202186, 15, 15443, -1100, 65535), + (202186, 16, 30414, -1100, 65535), + (202186, 17, 21632, -1100, 65535), + (202186, 18, 21634, -1100, 65535), + (202186, 19, 59592, -1100, 65535), + (202186, 20, 21635, -1100, 65535), + (202186, 21, 26926, -1100, 65535), + (202186, 22, 26927, -1100, 65535), + (202186, 23, 26928, -1100, 65535), + (202186, 24, 59841, -1100, 65535), + (202186, 25, 59840, -1100, 65535), + (202186, 26, 59842, -1100, 65535), + (202186, 27, 77065, -1100, 65535), + (202186, 28, 77067, -1100, 65535), + (202186, 29, 77066, -1100, 65535), + (202186, 30, 77849, -1100, 65535), + (202186, 31, 77069, -1100, 65535), + (202186, 32, 77840, -1100, 65535), + (202186, 33, 77070, -1100, 65535), + (202186, 34, 77072, -1100, 65535), + (202186, 35, 77068, -1100, 65535), + (202186, 36, 77073, -1100, 65535), + (202186, 37, 77078, -1100, 65535), + (202186, 38, 77074, -1100, 65535), + (202186, 39, 77071, -1100, 65535), + (202186, 40, 41284, -1100, 65535), + (202186, 41, 77079, -1100, 65535), + (202186, 42, 77076, -1100, 65535), + (202186, 43, 77075, -1100, 65535), + (202186, 44, 77077, -1100, 65535), + (202186, 45, 41285, -1100, 65535), + (202186, 46, 77082, -1100, 65535), + (202186, 47, 77080, -1100, 65535), + (202186, 48, 77081, -1100, 65535), + (202186, 49, 43568, -1100, 65535), + (202186, 50, 77990, -1100, 65535); + +UPDATE npc_types SET lastname = 'Shadow Knight Spells 61-70' WHERE name = 'Reaver_Muron'; + +UPDATE spawn2 SET x = '719.00', y = '-105.00', z = '-91.31', heading = '270.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Reaver_Muron') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202179; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202179, 1, 15277, -1100, 65535), + (202179, 2, 7621, -1100, 65535), + (202179, 3, 15017, -1100, 65535), + (202179, 4, 15278, -1100, 65535), + (202179, 5, 59610, -1100, 65535), + (202179, 6, 15255, -1100, 65535), + (202179, 7, 15261, -1100, 65535), + (202179, 8, 15284, -1100, 65535), + (202179, 9, 15227, -1100, 65535), + (202179, 10, 15280, -1100, 65535), + (202179, 11, 15283, -1100, 65535), + (202179, 12, 15086, -1100, 65535), + (202179, 13, 15230, -1100, 65535), + (202179, 14, 15281, -1100, 65535), + (202179, 15, 15505, -1100, 65535), + (202179, 16, 59666, -1100, 65535), + (202179, 17, 15035, -1100, 65535), + (202179, 18, 15640, -1100, 65535), + (202179, 19, 15649, -1100, 65535), + (202179, 20, 15146, -1100, 65535), + (202179, 21, 15149, -1100, 65535), + (202179, 22, 15220, -1100, 65535), + (202179, 23, 15096, -1100, 65535), + (202179, 24, 15437, -1100, 65535), + (202179, 25, 15424, -1100, 65535), + (202179, 26, 15144, -1100, 65535), + (202179, 27, 15265, -1100, 65535), + (202179, 28, 15508, -1100, 65535), + (202179, 29, 59667, -1100, 65535), + (202179, 30, 15061, -1100, 65535), + (202179, 31, 15434, -1100, 65535), + (202179, 32, 59691, -1100, 65535), + (202179, 33, 59679, -1100, 65535), + (202179, 34, 59611, -1100, 65535), + (202179, 35, 15245, -1100, 65535), + (202179, 36, 15349, -1100, 65535), + (202179, 37, 7623, -1100, 65535), + (202179, 38, 15282, -1100, 65535), + (202179, 39, 59690, -1100, 65535), + (202179, 40, 59678, -1100, 65535), + (202179, 41, 15345, -1100, 65535), + (202179, 42, 15365, -1100, 65535), + (202179, 43, 15308, -1100, 65535), + (202179, 44, 26970, -1100, 65535), + (202179, 45, 7622, -1100, 65535), + (202179, 46, 15526, -1100, 65535), + (202179, 47, 15580, -1100, 65535), + (202179, 48, 15110, -1100, 65535), + (202179, 49, 15147, -1100, 65535), + (202179, 50, 15148, -1100, 65535), + (202179, 51, 15012, -1100, 65535), + (202179, 52, 15048, -1100, 65535), + (202179, 53, 15228, -1100, 65535), + (202179, 54, 15511, -1100, 65535), + (202179, 55, 15040, -1100, 65535), + (202179, 56, 15093, -1100, 65535), + (202179, 57, 15200, -1100, 65535), + (202179, 58, 15201, -1100, 65535), + (202179, 59, 15205, -1100, 65535), + (202179, 60, 15213, -1100, 65535), + (202179, 61, 15225, -1100, 65535), + (202179, 62, 15266, -1100, 65535), + (202179, 63, 15267, -1100, 65535), + (202179, 64, 15203, -1100, 65535), + (202179, 65, 15211, -1100, 65535), + (202179, 66, 15272, -1100, 65535), + (202179, 67, 15269, -1100, 65535), + (202179, 68, 15274, -1100, 65535), + (202179, 69, 15075, -1100, 65535), + (202179, 70, 15271, -1100, 65535), + (202179, 71, 15275, -1100, 65535), + (202179, 72, 15036, -1100, 65535), + (202179, 73, 15224, -1100, 65535), + (202179, 74, 15270, -1100, 65535), + (202179, 75, 15050, -1100, 65535), + (202179, 76, 15276, -1100, 65535), + (202179, 77, 15279, -1100, 65535), + (202179, 78, 15079, -1100, 65535), + (202179, 79, 15212, -1100, 65535), + (202179, 80, 15238, -1100, 65535), + (202179, 81, 15226, -1100, 65535); + +UPDATE npc_types SET lastname = 'Shaman Spells 1-25' WHERE name = 'Mystic_Abomin'; + +UPDATE spawn2 SET x = '820.00', y = '75.00', z = '3.75', heading = '180.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Mystic_Abomin') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202183; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202183, 1, 15160, -1100, 65535), + (202183, 2, 15431, -1100, 65535), + (202183, 3, 15111, -1100, 65535), + (202183, 4, 15164, -1100, 65535), + (202183, 5, 15260, -1100, 65535), + (202183, 6, 15167, -1100, 65535), + (202183, 7, 15131, -1100, 65535), + (202183, 8, 15509, -1100, 65535), + (202183, 9, 59668, -1100, 65535), + (202183, 10, 30427, -1100, 65535), + (202183, 11, 59612, -1100, 65535), + (202183, 12, 59609, -1100, 65535), + (202183, 13, 59692, -1100, 65535), + (202183, 14, 59680, -1100, 65535), + (202183, 15, 15062, -1100, 65535), + (202183, 16, 30428, -1100, 65535), + (202183, 17, 15384, -1100, 65535), + (202183, 18, 15438, -1100, 65535), + (202183, 19, 15039, -1100, 65535), + (202183, 20, 15046, -1100, 65535), + (202183, 21, 15095, -1100, 65535), + (202183, 22, 7624, -1100, 65535), + (202183, 23, 15155, -1100, 65535), + (202183, 24, 15435, -1100, 65535), + (202183, 25, 15577, -1100, 65535), + (202183, 26, 15507, -1100, 65535), + (202183, 27, 15527, -1100, 65535), + (202183, 28, 15754, -1100, 65535), + (202183, 29, 19542, -1100, 65535), + (202183, 30, 36012, -1100, 65535), + (202183, 31, 15134, -1100, 65535), + (202183, 32, 15145, -1100, 65535), + (202183, 33, 15152, -1100, 65535), + (202183, 34, 15153, -1100, 65535), + (202183, 35, 15168, -1100, 65535), + (202183, 36, 19502, -1100, 65535), + (202183, 37, 15154, -1100, 65535), + (202183, 38, 15163, -1100, 65535), + (202183, 39, 15165, -1100, 65535), + (202183, 40, 15170, -1100, 65535), + (202183, 41, 15389, -1100, 65535), + (202183, 42, 30429, -1100, 65535), + (202183, 43, 15064, -1100, 65535), + (202183, 44, 15158, -1100, 65535), + (202183, 45, 59613, -1100, 65535), + (202183, 46, 15049, -1100, 65535), + (202183, 47, 15510, -1100, 65535), + (202183, 48, 59013, -1100, 65535), + (202183, 49, 15166, -1100, 65535), + (202183, 50, 15337, -1100, 65535), + (202183, 51, 15159, -1100, 65535), + (202183, 52, 7625, -1100, 65535), + (202183, 53, 15156, -1100, 65535), + (202183, 54, 26960, -1100, 65535), + (202183, 55, 15098, -1100, 65535), + (202183, 56, 15112, -1100, 65535), + (202183, 57, 15157, -1100, 65535), + (202183, 58, 15032, -1100, 65535), + (202183, 59, 15436, -1100, 65535), + (202183, 60, 28544, -1100, 65535), + (202183, 61, 19264, -1100, 65535), + (202183, 62, 30430, -1100, 65535), + (202183, 63, 77866, -1100, 65535), + (202183, 64, 15042, -1100, 65535), + (202183, 65, 15060, -1100, 65535), + (202183, 66, 15506, -1100, 65535), + (202183, 67, 15150, -1100, 65535), + (202183, 68, 15151, -1100, 65535), + (202183, 69, 15015, -1100, 65535), + (202183, 70, 15162, -1100, 65535), + (202183, 71, 15884, -1100, 65535), + (202183, 72, 15885, -1100, 65535), + (202183, 73, 15886, -1100, 65535), + (202183, 74, 15891, -1100, 65535), + (202183, 75, 15895, -1100, 65535), + (202183, 76, 59542, -1100, 65535), + (202183, 77, 59545, -1100, 65535), + (202183, 78, 59548, -1100, 65535), + (202183, 79, 59549, -1100, 65535), + (202183, 80, 59555, -1100, 65535), + (202183, 81, 59608, -1100, 65535), + (202183, 82, 15063, -1100, 65535), + (202183, 83, 15161, -1100, 65535), + (202183, 84, 15326, -1100, 65535), + (202183, 85, 15031, -1100, 65535); + +UPDATE npc_types SET lastname = 'Shaman Spells 26-50' WHERE name = 'Mystic_Goharkor'; + +UPDATE spawn2 SET x = '878.00', y = '75.00', z = '4.06', heading = '179.30' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Mystic_Goharkor') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202182; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202182, 1, 19207, -1100, 65535), + (202182, 2, 19274, -1100, 65535), + (202182, 3, 19275, -1100, 65535), + (202182, 4, 19276, -1100, 65535), + (202182, 5, 19507, -1100, 65535), + (202182, 6, 30431, -1100, 65535), + (202182, 7, 78027, -1100, 65535), + (202182, 8, 15171, -1100, 65535), + (202182, 9, 15133, -1100, 65535), + (202182, 10, 19277, -1100, 65535), + (202182, 11, 19278, -1100, 65535), + (202182, 12, 7628, -1100, 65535), + (202182, 13, 19279, -1100, 65535), + (202182, 14, 19280, -1100, 65535), + (202182, 15, 19281, -1100, 65535), + (202182, 16, 19282, -1100, 65535), + (202182, 17, 77867, -1100, 65535), + (202182, 18, 19283, -1100, 65535), + (202182, 19, 19284, -1100, 65535), + (202182, 20, 19285, -1100, 65535), + (202182, 21, 19286, -1100, 65535), + (202182, 22, 19473, -1100, 65535), + (202182, 23, 2483, -1100, 65535), + (202182, 24, 7629, -1100, 65535), + (202182, 25, 19528, -1100, 65535), + (202182, 26, 19287, -1100, 65535), + (202182, 27, 19288, -1100, 65535), + (202182, 28, 19289, -1100, 65535), + (202182, 29, 19290, -1100, 65535), + (202182, 30, 66281, -1100, 65535), + (202182, 31, 19291, -1100, 65535), + (202182, 32, 19292, -1100, 65535), + (202182, 33, 19293, -1100, 65535), + (202182, 34, 19491, -1100, 65535), + (202182, 35, 30432, -1100, 65535), + (202182, 36, 7630, -1100, 65535), + (202182, 37, 15009, -1100, 65535), + (202182, 38, 15132, -1100, 65535), + (202182, 39, 19265, -1100, 65535), + (202182, 40, 19523, -1100, 65535), + (202182, 41, 19534, -1100, 65535), + (202182, 42, 19238, -1100, 65535), + (202182, 43, 19243, -1100, 65535), + (202182, 44, 19266, -1100, 65535), + (202182, 45, 7626, -1100, 65535), + (202182, 46, 19520, -1100, 65535), + (202182, 47, 59525, -1100, 65535), + (202182, 48, 19267, -1100, 65535), + (202182, 49, 19268, -1100, 65535), + (202182, 50, 19269, -1100, 65535), + (202182, 51, 19270, -1100, 65535), + (202182, 52, 19271, -1100, 65535), + (202182, 53, 19272, -1100, 65535), + (202182, 54, 19273, -1100, 65535), + (202182, 55, 7627, -1100, 65535), + (202182, 56, 19522, -1100, 65535), + (202182, 57, 26961, -1100, 65535), + (202182, 58, 59614, -1100, 65535), + (202182, 59, 17794, -1100, 65535), + (202182, 60, 17795, -1100, 65535); + +UPDATE npc_types SET lastname = 'Shaman Spells 51-60' WHERE name = 'Mystic_Ryrin'; + +UPDATE spawn2 SET x = '938.00', y = '87.00', z = '4.38', heading = '1.41' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Mystic_Ryrin') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202181; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202181, 1, 77144, -1100, 65535), + (202181, 2, 77145, -1100, 65535), + (202181, 3, 76025, -1100, 65535), + (202181, 4, 41280, -1100, 65535), + (202181, 5, 77151, -1100, 65535), + (202181, 6, 77154, -1100, 65535), + (202181, 7, 77153, -1100, 65535), + (202181, 8, 77147, -1100, 65535), + (202181, 9, 77152, -1100, 65535), + (202181, 10, 77139, -1100, 65535), + (202181, 11, 21660, -1100, 65535), + (202181, 12, 21661, -1100, 65535), + (202181, 13, 21695, -1100, 65535), + (202181, 14, 26945, -1100, 65535), + (202181, 15, 28491, -1100, 65535), + (202181, 16, 28492, -1100, 65535), + (202181, 17, 28493, -1100, 65535), + (202181, 18, 28494, -1100, 65535), + (202181, 19, 15172, -1100, 65535), + (202181, 20, 21691, -1100, 65535), + (202181, 21, 28495, -1100, 65535), + (202181, 22, 28496, -1100, 65535), + (202181, 23, 28497, -1100, 65535), + (202181, 24, 28498, -1100, 65535), + (202181, 25, 28499, -1100, 65535), + (202181, 26, 28531, -1100, 65535), + (202181, 27, 21693, -1100, 65535), + (202181, 28, 26910, -1100, 65535), + (202181, 29, 26911, -1100, 65535), + (202181, 30, 26912, -1100, 65535), + (202181, 31, 26913, -1100, 65535), + (202181, 32, 26914, -1100, 65535), + (202181, 33, 26946, -1100, 65535), + (202181, 34, 59615, -1100, 65535), + (202181, 35, 26915, -1100, 65535), + (202181, 36, 26916, -1100, 65535), + (202181, 37, 26917, -1100, 65535), + (202181, 38, 26918, -1100, 65535), + (202181, 39, 26919, -1100, 65535), + (202181, 40, 59838, -1100, 65535), + (202181, 41, 59837, -1100, 65535), + (202181, 42, 59839, -1100, 65535), + (202181, 43, 77133, -1100, 65535), + (202181, 44, 77131, -1100, 65535), + (202181, 45, 77132, -1100, 65535), + (202181, 46, 77129, -1100, 65535), + (202181, 47, 77130, -1100, 65535), + (202181, 48, 77136, -1100, 65535), + (202181, 49, 77149, -1100, 65535), + (202181, 50, 77128, -1100, 65535), + (202181, 51, 28487, -1100, 65535), + (202181, 52, 28488, -1100, 65535), + (202181, 53, 28489, -1100, 65535), + (202181, 54, 28490, -1100, 65535), + (202181, 55, 28523, -1100, 65535), + (202181, 56, 76041, -1100, 65535), + (202181, 57, 17796, -1100, 65535), + (202181, 58, 41279, -1100, 65535), + (202181, 59, 43573, -1100, 65535), + (202181, 60, 78004, -1100, 65535), + (202181, 61, 78002, -1100, 65535), + (202181, 62, 77143, -1100, 65535), + (202181, 63, 77141, -1100, 65535), + (202181, 64, 77142, -1100, 65535), + (202181, 65, 77137, -1100, 65535), + (202181, 66, 77138, -1100, 65535), + (202181, 67, 77135, -1100, 65535), + (202181, 68, 77134, -1100, 65535), + (202181, 69, 77140, -1100, 65535), + (202181, 70, 41278, -1100, 65535), + (202181, 71, 77302, -1100, 65535), + (202181, 72, 77150, -1100, 65535), + (202181, 73, 77146, -1100, 65535), + (202181, 74, 77148, -1100, 65535); + +UPDATE npc_types SET lastname = 'Shaman Spells 61-70' WHERE name = 'Mystic_Pikor'; + +UPDATE spawn2 SET x = '945.00', y = '62.00', z = '4.69', heading = '92.81' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Mystic_Pikor') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202174; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202174, 1, 79218, -1100, 65535), + (202174, 2, 79217, -1100, 65535), + (202174, 3, 15387, -1100, 65535), + (202174, 4, 15544, -1100, 65535), + (202174, 5, 59523, -1100, 65535), + (202174, 6, 15261, -1100, 65535), + (202174, 7, 15545, -1100, 65535), + (202174, 8, 15547, -1100, 65535), + (202174, 9, 27971, -1100, 65535), + (202174, 10, 15065, -1100, 65535), + (202174, 11, 15467, -1100, 65535), + (202174, 12, 15546, -1100, 65535), + (202174, 13, 15548, -1100, 65535), + (202174, 14, 59658, -1100, 65535), + (202174, 15, 15461, -1100, 65535), + (202174, 16, 15462, -1100, 65535), + (202174, 17, 15464, -1100, 65535), + (202174, 18, 19471, -1100, 65535), + (202174, 19, 36380, -1100, 65535), + (202174, 20, 59670, -1100, 65535), + (202174, 21, 59682, -1100, 65535), + (202174, 22, 15528, -1100, 65535), + (202174, 23, 15562, -1100, 65535), + (202174, 24, 7653, -1100, 65535), + (202174, 25, 26968, -1100, 65535), + (202174, 26, 15022, -1100, 65535), + (202174, 27, 36365, -1100, 65535), + (202174, 28, 36366, -1100, 65535), + (202174, 29, 15054, -1100, 65535), + (202174, 30, 15205, -1100, 65535), + (202174, 31, 15288, -1100, 65535), + (202174, 32, 15372, -1100, 65535), + (202174, 33, 15373, -1100, 65535), + (202174, 34, 15374, -1100, 65535), + (202174, 35, 15051, -1100, 65535), + (202174, 36, 15378, -1100, 65535), + (202174, 37, 15230, -1100, 65535), + (202174, 38, 15375, -1100, 65535), + (202174, 39, 15036, -1100, 65535), + (202174, 40, 15080, -1100, 65535), + (202174, 41, 15376, -1100, 65535), + (202174, 42, 15379, -1100, 65535), + (202174, 43, 15477, -1100, 65535), + (202174, 44, 15246, -1100, 65535), + (202174, 45, 15377, -1100, 65535), + (202174, 46, 15232, -1100, 65535), + (202174, 47, 15354, -1100, 65535), + (202174, 48, 15323, -1100, 65535), + (202174, 49, 15380, -1100, 65535), + (202174, 50, 15656, -1100, 65535), + (202174, 51, 15234, -1100, 65535), + (202174, 52, 15381, -1100, 65535), + (202174, 53, 15383, -1100, 65535), + (202174, 54, 7651, -1100, 65535), + (202174, 55, 15048, -1100, 65535), + (202174, 56, 15529, -1100, 65535), + (202174, 57, 15035, -1100, 65535), + (202174, 58, 15085, -1100, 65535), + (202174, 59, 15382, -1100, 65535), + (202174, 60, 15236, -1100, 65535), + (202174, 61, 59657, -1100, 65535), + (202174, 62, 15305, -1100, 65535), + (202174, 63, 15385, -1100, 65535), + (202174, 64, 59669, -1100, 65535), + (202174, 65, 59681, -1100, 65535), + (202174, 66, 15309, -1100, 65535), + (202174, 67, 15386, -1100, 65535), + (202174, 68, 15657, -1100, 65535), + (202174, 69, 15038, -1100, 65535), + (202174, 70, 15042, -1100, 65535), + (202174, 71, 15500, -1100, 65535), + (202174, 72, 15679, -1100, 65535), + (202174, 73, 36364, -1100, 65535), + (202174, 74, 15131, -1100, 65535), + (202174, 75, 19541, -1100, 65535), + (202174, 76, 15458, -1100, 65535), + (202174, 77, 15542, -1100, 65535), + (202174, 78, 23486, -1100, 65535), + (202174, 79, 7652, -1100, 65535), + (202174, 80, 15503, -1100, 65535), + (202174, 81, 15541, -1100, 65535), + (202174, 82, 15578, -1100, 65535), + (202174, 83, 15108, -1100, 65535), + (202174, 84, 15543, -1100, 65535), + (202174, 85, 36367, -1100, 65535), + (202174, 86, 36377, -1100, 65535), + (202174, 87, 36378, -1100, 65535), + (202174, 88, 36379, -1100, 65535), + (202174, 89, 27966, -1100, 65535), + (202174, 90, 79219, -1100, 65535); + +UPDATE npc_types SET lastname = 'Wizard Spells 1-25' WHERE name = 'Channeler_Olaemos'; + +UPDATE spawn2 SET x = '836.00', y = '-40.00', z = '-60.87', heading = '267.19' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Channeler_Olaemos') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202178; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202178, 1, 15394, -1100, 65535), + (202178, 2, 19486, -1100, 65535), + (202178, 3, 36369, -1100, 65535), + (202178, 4, 59020, -1100, 65535), + (202178, 5, 15023, -1100, 65535), + (202178, 6, 15660, -1100, 65535), + (202178, 7, 19485, -1100, 65535), + (202178, 8, 27974, -1100, 65535), + (202178, 9, 15109, -1100, 65535), + (202178, 10, 15605, -1100, 65535), + (202178, 11, 19488, -1100, 65535), + (202178, 12, 30399, -1100, 65535), + (202178, 13, 15073, -1100, 65535), + (202178, 14, 15659, -1100, 65535), + (202178, 15, 19487, -1100, 65535), + (202178, 16, 30425, -1100, 65535), + (202178, 17, 15067, -1100, 65535), + (202178, 18, 19489, -1100, 65535), + (202178, 19, 36382, -1100, 65535), + (202178, 20, 30421, -1100, 65535), + (202178, 21, 59630, -1100, 65535), + (202178, 22, 15733, -1100, 65535), + (202178, 23, 19509, -1100, 65535), + (202178, 24, 7655, -1100, 65535), + (202178, 25, 26978, -1100, 65535), + (202178, 26, 15666, -1100, 65535), + (202178, 27, 15674, -1100, 65535), + (202178, 28, 19510, -1100, 65535), + (202178, 29, 15606, -1100, 65535), + (202178, 30, 15612, -1100, 65535), + (202178, 31, 15755, -1100, 65535), + (202178, 32, 19511, -1100, 65535), + (202178, 33, 15731, -1100, 65535), + (202178, 34, 16240, -1100, 65535), + (202178, 35, 19512, -1100, 65535), + (202178, 36, 15732, -1100, 65535), + (202178, 37, 27979, -1100, 65535), + (202178, 38, 59625, -1100, 65535), + (202178, 39, 36370, -1100, 65535), + (202178, 40, 30422, -1100, 65535), + (202178, 41, 19534, -1100, 65535), + (202178, 42, 19429, -1100, 65535), + (202178, 43, 19475, -1100, 65535), + (202178, 44, 30423, -1100, 65535), + (202178, 45, 19539, -1100, 65535), + (202178, 46, 15466, -1100, 65535), + (202178, 47, 15568, -1100, 65535), + (202178, 48, 15465, -1100, 65535), + (202178, 49, 15468, -1100, 65535), + (202178, 50, 15602, -1100, 65535), + (202178, 51, 15899, -1100, 65535), + (202178, 52, 15563, -1100, 65535), + (202178, 53, 15636, -1100, 65535), + (202178, 54, 59521, -1100, 65535), + (202178, 55, 26976, -1100, 65535), + (202178, 56, 15459, -1100, 65535), + (202178, 57, 15470, -1100, 65535), + (202178, 58, 15561, -1100, 65535), + (202178, 59, 59547, -1100, 65535), + (202178, 60, 15579, -1100, 65535), + (202178, 61, 19540, -1100, 65535), + (202178, 62, 27968, -1100, 65535), + (202178, 63, 27976, -1100, 65535), + (202178, 64, 15393, -1100, 65535), + (202178, 65, 15471, -1100, 65535), + (202178, 66, 36368, -1100, 65535), + (202178, 67, 15463, -1100, 65535), + (202178, 68, 30419, -1100, 65535), + (202178, 69, 15469, -1100, 65535), + (202178, 70, 15564, -1100, 65535), + (202178, 71, 15603, -1100, 65535), + (202178, 72, 19434, -1100, 65535), + (202178, 73, 30417, -1100, 65535), + (202178, 74, 15066, -1100, 65535), + (202178, 75, 15565, -1100, 65535), + (202178, 76, 30418, -1100, 65535), + (202178, 77, 27973, -1100, 65535), + (202178, 78, 59659, -1100, 65535), + (202178, 79, 15049, -1100, 65535), + (202178, 80, 15658, -1100, 65535), + (202178, 81, 15861, -1100, 65535), + (202178, 82, 36381, -1100, 65535), + (202178, 83, 19513, -1100, 65535), + (202178, 84, 59671, -1100, 65535), + (202178, 85, 59683, -1100, 65535), + (202178, 86, 15460, -1100, 65535), + (202178, 87, 15566, -1100, 65535), + (202178, 88, 19477, -1100, 65535), + (202178, 89, 7654, -1100, 65535), + (202178, 90, 59524, -1100, 65535), + (202178, 91, 15567, -1100, 65535), + (202178, 92, 15752, -1100, 65535), + (202178, 93, 19430, -1100, 65535), + (202178, 94, 19476, -1100, 65535), + (202178, 95, 15084, -1100, 65535), + (202178, 96, 15539, -1100, 65535), + (202178, 97, 15604, -1100, 65535), + (202178, 98, 19478, -1100, 65535), + (202178, 99, 19514, -1100, 65535), + (202178, 100, 26977, -1100, 65535), + (202178, 101, 15132, -1100, 65535), + (202178, 102, 19515, -1100, 65535), + (202178, 103, 30420, -1100, 65535), + (202178, 104, 27969, -1100, 65535), + (202178, 105, 27978, -1100, 65535); + +UPDATE npc_types SET lastname = 'Wizard Spells 26-50' WHERE name = 'Channeler_Lariland'; + +UPDATE spawn2 SET x = '842.00', y = '-25.00', z = '-62.12', heading = '1.41' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Channeler_Lariland') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202177; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202177, 1, 19342, -1100, 65535), + (202177, 2, 19344, -1100, 65535), + (202177, 3, 36384, -1100, 65535), + (202177, 4, 19343, -1100, 65535), + (202177, 5, 19345, -1100, 65535), + (202177, 6, 19415, -1100, 65535), + (202177, 7, 19422, -1100, 65535), + (202177, 8, 19469, -1100, 65535), + (202177, 9, 19470, -1100, 65535), + (202177, 10, 36372, -1100, 65535), + (202177, 11, 30426, -1100, 65535), + (202177, 12, 7660, -1100, 65535), + (202177, 13, 19525, -1100, 65535), + (202177, 14, 19526, -1100, 65535), + (202177, 15, 59995, -1100, 65535), + (202177, 16, 79216, -1100, 65535), + (202177, 17, 79215, -1100, 65535), + (202177, 18, 79214, -1100, 65535), + (202177, 19, 19318, -1100, 65535), + (202177, 20, 77931, -1100, 65535), + (202177, 21, 77929, -1100, 65535), + (202177, 22, 78035, -1100, 65535), + (202177, 23, 78033, -1100, 65535), + (202177, 24, 19295, -1100, 65535), + (202177, 25, 19315, -1100, 65535), + (202177, 26, 19316, -1100, 65535), + (202177, 27, 19317, -1100, 65535), + (202177, 28, 19319, -1100, 65535), + (202177, 29, 19320, -1100, 65535), + (202177, 30, 19321, -1100, 65535), + (202177, 31, 19474, -1100, 65535), + (202177, 32, 59021, -1100, 65535), + (202177, 33, 59994, -1100, 65535), + (202177, 34, 59878, -1100, 65535), + (202177, 35, 19207, -1100, 65535), + (202177, 36, 19322, -1100, 65535), + (202177, 37, 19323, -1100, 65535), + (202177, 38, 77659, -1100, 65535), + (202177, 39, 36383, -1100, 65535), + (202177, 40, 19300, -1100, 65535), + (202177, 41, 19324, -1100, 65535), + (202177, 42, 19325, -1100, 65535), + (202177, 43, 19326, -1100, 65535), + (202177, 44, 7657, -1100, 65535), + (202177, 45, 26969, -1100, 65535), + (202177, 46, 59628, -1100, 65535), + (202177, 47, 59880, -1100, 65535), + (202177, 48, 36371, -1100, 65535), + (202177, 49, 19327, -1100, 65535), + (202177, 50, 19328, -1100, 65535), + (202177, 51, 19329, -1100, 65535), + (202177, 52, 19330, -1100, 65535), + (202177, 53, 30406, -1100, 65535), + (202177, 54, 59992, -1100, 65535), + (202177, 55, 77661, -1100, 65535), + (202177, 56, 77932, -1100, 65535), + (202177, 57, 78029, -1100, 65535), + (202177, 58, 78036, -1100, 65535), + (202177, 59, 19331, -1100, 65535), + (202177, 60, 19332, -1100, 65535), + (202177, 61, 19333, -1100, 65535), + (202177, 62, 7658, -1100, 65535), + (202177, 63, 19334, -1100, 65535), + (202177, 64, 19335, -1100, 65535), + (202177, 65, 19336, -1100, 65535), + (202177, 66, 19411, -1100, 65535), + (202177, 67, 59626, -1100, 65535), + (202177, 68, 59879, -1100, 65535), + (202177, 69, 19337, -1100, 65535), + (202177, 70, 19338, -1100, 65535), + (202177, 71, 19339, -1100, 65535), + (202177, 72, 19414, -1100, 65535), + (202177, 73, 7659, -1100, 65535), + (202177, 74, 59631, -1100, 65535), + (202177, 75, 77660, -1100, 65535), + (202177, 76, 19340, -1100, 65535), + (202177, 77, 19341, -1100, 65535); + +UPDATE npc_types SET lastname = 'Wizard Spells 51-60' WHERE name = 'Channeler_Cerakoth'; + +UPDATE spawn2 SET x = '889.00', y = '-25.00', z = '-60.25', heading = '359.30' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Channeler_Cerakoth') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202176; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202176, 1, 59844, -1100, 65535), + (202176, 2, 77179, -1100, 65535), + (202176, 3, 77178, -1100, 65535), + (202176, 4, 77182, -1100, 65535), + (202176, 5, 77180, -1100, 65535), + (202176, 6, 77191, -1100, 65535), + (202176, 7, 26944, -1100, 65535), + (202176, 8, 28413, -1100, 65535), + (202176, 9, 28437, -1100, 65535), + (202176, 10, 28438, -1100, 65535), + (202176, 11, 28439, -1100, 65535), + (202176, 12, 76043, -1100, 65535), + (202176, 13, 21662, -1100, 65535), + (202176, 14, 28440, -1100, 65535), + (202176, 15, 28441, -1100, 65535), + (202176, 16, 28442, -1100, 65535), + (202176, 17, 77654, -1100, 65535), + (202176, 18, 59528, -1100, 65535), + (202176, 19, 28414, -1100, 65535), + (202176, 20, 28445, -1100, 65535), + (202176, 21, 28446, -1100, 65535), + (202176, 22, 28448, -1100, 65535), + (202176, 23, 59629, -1100, 65535), + (202176, 24, 26940, -1100, 65535), + (202176, 25, 28415, -1100, 65535), + (202176, 26, 28444, -1100, 65535), + (202176, 27, 77181, -1100, 65535), + (202176, 28, 77271, -1100, 65535), + (202176, 29, 77655, -1100, 65535), + (202176, 30, 77184, -1100, 65535), + (202176, 31, 77183, -1100, 65535), + (202176, 32, 77188, -1100, 65535), + (202176, 33, 77185, -1100, 65535), + (202176, 34, 77186, -1100, 65535), + (202176, 35, 41296, -1100, 65535), + (202176, 36, 77189, -1100, 65535), + (202176, 37, 36386, -1100, 65535), + (202176, 38, 77194, -1100, 65535), + (202176, 39, 77190, -1100, 65535), + (202176, 40, 77196, -1100, 65535), + (202176, 41, 77193, -1100, 65535), + (202176, 42, 76027, -1100, 65535), + (202176, 43, 41298, -1100, 65535), + (202176, 44, 79457, -1100, 65535), + (202176, 45, 77195, -1100, 65535), + (202176, 46, 77187, -1100, 65535), + (202176, 47, 77198, -1100, 65535), + (202176, 48, 36374, -1100, 65535), + (202176, 49, 77197, -1100, 65535), + (202176, 50, 77192, -1100, 65535), + (202176, 51, 41297, -1100, 65535), + (202176, 52, 43575, -1100, 65535), + (202176, 53, 78010, -1100, 65535), + (202176, 54, 78008, -1100, 65535), + (202176, 55, 79213, -1100, 65535), + (202176, 56, 79212, -1100, 65535), + (202176, 57, 79211, -1100, 65535), + (202176, 58, 28447, -1100, 65535), + (202176, 59, 36385, -1100, 65535), + (202176, 60, 59624, -1100, 65535), + (202176, 61, 59627, -1100, 65535), + (202176, 62, 77656, -1100, 65535), + (202176, 63, 79458, -1100, 65535), + (202176, 64, 21663, -1100, 65535), + (202176, 65, 26942, -1100, 65535), + (202176, 66, 28443, -1100, 65535), + (202176, 67, 28450, -1100, 65535), + (202176, 68, 36373, -1100, 65535), + (202176, 69, 59843, -1100, 65535), + (202176, 70, 59845, -1100, 65535); + +UPDATE npc_types SET lastname = 'Wizard Spells 61-70' WHERE name = 'Channeler_Alyrianne'; + +UPDATE spawn2 SET x = '941.00', y = '-62.00', z = '-60.25', heading = '90.70' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Channeler_Alyrianne') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202310; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202310, 1, 59973, -1100, 65535), + (202310, 2, 17709, -1100, 65535), + (202310, 3, 66412, -1100, 65535), + (202310, 4, 66460, -1100, 65535), + (202310, 5, 66200, -1100, 65535), + (202310, 6, 66201, -1100, 65535), + (202310, 7, 66400, -1100, 65535), + (202310, 8, 66461, -1100, 65535), + (202310, 9, 66401, -1100, 65535), + (202310, 10, 66402, -1100, 65535), + (202310, 11, 66403, -1100, 65535), + (202310, 12, 78019, -1100, 65535), + (202310, 13, 66462, -1100, 65535), + (202310, 14, 66404, -1100, 65535), + (202310, 15, 66405, -1100, 65535), + (202310, 16, 66406, -1100, 65535), + (202310, 17, 66407, -1100, 65535), + (202310, 18, 66408, -1100, 65535), + (202310, 19, 66409, -1100, 65535), + (202310, 20, 76049, -1100, 65535), + (202310, 21, 66410, -1100, 65535), + (202310, 22, 66463, -1100, 65535), + (202310, 23, 66411, -1100, 65535), + (202310, 24, 59908, -1100, 65535), + (202310, 25, 77287, -1100, 65535), + (202310, 26, 77288, -1100, 65535), + (202310, 27, 41268, -1100, 65535), + (202310, 28, 77283, -1100, 65535), + (202310, 29, 76032, -1100, 65535), + (202310, 30, 77286, -1100, 65535), + (202310, 31, 43563, -1100, 65535), + (202310, 32, 77980, -1100, 65535); + +UPDATE npc_types SET lastname = 'Warrior Tomes' WHERE name = 'Heldin_Swordbreaker'; + +UPDATE spawn2 SET x = '1106.00', y = '-112.00', z = '-29.62', heading = '92.11' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Heldin_Swordbreaker') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202161; + +INSERT INTO merchantlist (merchantid, slot, item, faction_required, classes_required) +VALUES + (202161, 1, 66231, -1100, 65535), + (202161, 2, 76037, -1100, 65535), + (202161, 3, 76021, -1100, 65535), + (202161, 4, 66200, -1100, 65535), + (202161, 5, 66201, -1100, 65535), + (202161, 6, 66230, -1100, 65535), + (202161, 7, 77856, -1100, 65535), + (202161, 8, 66434, -1100, 65535); + +UPDATE npc_types SET lastname = 'Paladin Tomes' WHERE name = 'Ulin_Velnik'; + +UPDATE spawn2 SET x = '1003.00', y = '-114.00', z = '-30.25', heading = '178.59' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Ulin_Velnik') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202230; + +UPDATE npc_types SET lastname = 'Bard Songs 71-80' WHERE name = 'Minstrel_Cirsaelle'; + +UPDATE spawn2 SET x = '847.00', y = '93.00', z = '-60.87', heading = '1.41' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Minstrel_Cirsaelle') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202225; + +UPDATE npc_types SET lastname = 'Beastlord Spells 71-80' WHERE name = 'Primalist_Uliag'; + +UPDATE spawn2 SET x = '1110.00', y = '9.00', z = '98.38', heading = '90.00' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Primalist_Uliag') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202220; + +UPDATE npc_types SET lastname = 'Cleric Spells 71-80' WHERE name = 'Vicar_Glaunn'; + +UPDATE spawn2 SET x = '998.00', y = '112.00', z = '-30.25', heading = '1.41' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Vicar_Glaunn') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202215; + +UPDATE npc_types SET lastname = 'Druid Spells 71-80' WHERE name = 'Wanderer_Thermon'; + +UPDATE spawn2 SET x = '1067.00', y = '8.00', z = '2.19', heading = '357.19' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Wanderer_Thermon') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202210; + +UPDATE npc_types SET lastname = 'Enchanter Spells 71-80' WHERE name = 'Illusionist_Warek'; + +UPDATE spawn2 SET x = '1074.00', y = '2.00', z = '-60.87', heading = '87.89' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Illusionist_Warek') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202205; + +UPDATE npc_types SET lastname = 'Magician Spells 71-80' WHERE name = 'Elementalist_Onaec'; + +UPDATE spawn2 SET x = '1106.00', y = '56.00', z = '33.75', heading = '89.30' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Elementalist_Onaec') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202200; + +UPDATE npc_types SET lastname = 'Necromancer Spells 71-80' WHERE name = 'Heretic_Niraf'; + +UPDATE spawn2 SET x = '789.00', y = '56.00', z = '-92.87', heading = '271.41' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Heretic_Niraf') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202190; + +UPDATE npc_types SET lastname = 'Ranger Spells 71-80' WHERE name = 'Pathfinder_Arelat'; + +UPDATE spawn2 SET x = '922.00', y = '-23.00', z = '67.75', heading = '85.08' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Pathfinder_Arelat') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202185; + +UPDATE npc_types SET lastname = 'Shadow Knight Spells 71-80' WHERE name = 'Reaver_Praden'; + +UPDATE spawn2 SET x = '764.00', y = '-86.00', z = '-90.50', heading = '30.94' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Reaver_Praden') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202180; + +UPDATE npc_types SET lastname = 'Shaman Spells 71-80' WHERE name = 'Mystic_Somas'; + +UPDATE spawn2 SET x = '980.00', y = '76.00', z = '5.42', heading = '268.59' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Mystic_Somas') LIMIT 1); + + +DELETE FROM merchantlist WHERE merchantid = 202175; + +UPDATE npc_types SET lastname = 'Wizard Spells 71-80' WHERE name = 'Channeler_Keatrem'; + +UPDATE spawn2 SET x = '916.00', y = '-65.00', z = '-60.87', heading = '269.30' +WHERE spawngroupID = (SELECT spawngroupID FROM spawnentry WHERE npcid = (SELECT id from npc_types WHERE name = 'Channeler_Keatrem') LIMIT 1); + + diff --git a/utils/sql/git/required/2015_01_28_quest_debug_log_category.sql b/utils/sql/git/required/2015_01_28_quest_debug_log_category.sql new file mode 100644 index 000000000..98f030dff --- /dev/null +++ b/utils/sql/git/required/2015_01_28_quest_debug_log_category.sql @@ -0,0 +1 @@ +INSERT INTO `logsys_categories` (`log_category_id`, `log_category_description`, `log_to_gmsay`) VALUES ('38', 'Quest Debug', '1'); diff --git a/utils/sql/git/required/2015_01_29_merc_stats_table_update.sql b/utils/sql/git/required/2015_01_29_merc_stats_table_update.sql new file mode 100644 index 000000000..9c149b825 --- /dev/null +++ b/utils/sql/git/required/2015_01_29_merc_stats_table_update.sql @@ -0,0 +1 @@ +ALTER TABLE `merc_stats` ADD `statscale` int( 11 ) NOT NULL DEFAULT '100' AFTER `runspeed`; \ No newline at end of file diff --git a/utils/sql/git/required/2015_01_30_merc_attack_delay.sql b/utils/sql/git/required/2015_01_30_merc_attack_delay.sql new file mode 100644 index 000000000..6aa63e61f --- /dev/null +++ b/utils/sql/git/required/2015_01_30_merc_attack_delay.sql @@ -0,0 +1,3 @@ +ALTER TABLE `merc_stats` ADD `attack_delay` TINYINT(3) UNSIGNED DEFAULT '30' NOT NULL AFTER `attack_speed`; +UPDATE `merc_stats` SET `attack_delay` = 36 + 36 * (`attack_speed` / 100); +UPDATE `merc_stats` SET `attack_delay` = 30 WHERE `attack_speed` = 0; diff --git a/utils/sql/git/required/2015_01_31_character_item_recast.sql b/utils/sql/git/required/2015_01_31_character_item_recast.sql new file mode 100644 index 000000000..fbc222608 --- /dev/null +++ b/utils/sql/git/required/2015_01_31_character_item_recast.sql @@ -0,0 +1,7 @@ +CREATE TABLE `character_item_recast` ( + `id` int(11) UNSIGNED NOT NULL DEFAULT 0, + `recast_type` smallint(11) UNSIGNED NOT NULL DEFAULT 0, + `timestamp` int(11) UNSIGNED NOT NULL DEFAULT 0, + PRIMARY KEY(`id`, `recast_type`), + KEY `id` (`id`) +) ENGINE = InnoDB DEFAULT CHARSET = latin1; diff --git a/world/client.cpp b/world/client.cpp index 50b56cb0d..ace58ffea 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -102,6 +102,7 @@ Client::~Client() { //let the stream factory know were done with this stream eqs->Close(); eqs->ReleaseFromUse(); + safe_delete(eqs); } void Client::SendLogServer() @@ -845,7 +846,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) { char ConnectionType; - if(ClientVersionBit & BIT_UnderfootAndLater) + if(ClientVersionBit & BIT_UFAndLater) ConnectionType = 'U'; else if(ClientVersionBit & BIT_SoFAndLater) ConnectionType = 'S'; @@ -1102,7 +1103,7 @@ void Client::EnterWorld(bool TryBootup) { const char *zone_name=database.GetZoneName(zoneID, true); if (zs) { // warn the world we're comming, so it knows not to shutdown - zs->IncommingClient(this); + zs->IncomingClient(this); } else { if (TryBootup) { @@ -1116,17 +1117,20 @@ void Client::EnterWorld(bool TryBootup) { return; } else { - Log.Out(Logs::Detail, Logs::World_Server,"Requested zone %s is no running.",zone_name); + Log.Out(Logs::Detail, Logs::World_Server,"Requested zone %s is not running.",zone_name); ZoneUnavail(); return; } } pwaitingforbootup = 0; + if(!cle) { + return; + } + cle->SetChar(charid, char_name); database.UpdateLiveChar(char_name, GetAccountID()); Log.Out(Logs::Detail, Logs::World_Server,"%s %s (%d:%d)",seencharsel ? "Entering zone" : "Zoning to",zone_name,zoneID,instanceID); -// database.SetAuthentication(account_id, char_name, zone_name, ip); if (seencharsel) { if (GetAdmin() < 80 && zoneserver_list.IsZoneLocked(zoneID)) { @@ -1612,7 +1616,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc) int Charerrors = 0; -// solar: if this is increased you'll have to add a column to the classrace +// if this is increased you'll have to add a column to the classrace // table below #define _TABLE_RACES 16 @@ -1674,7 +1678,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc) { /*Enchanter*/ true, false, true, false, true, true, false, false, false, false, false, true, false, false, false, true}, { /*Beastlord*/ false, true, false, false, false, false, false, false, true, true, false, false, true, true, false, false}, { /*Berserker*/ false, true, false, false, false, false, false, true, true, true, false, false, false, true, false, false} - };//Initial table by kathgar, editted by Wiz for accuracy, solar too + }; if (!cc) return false; @@ -1707,7 +1711,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc) return false; } - // solar: add up the base values for this class/race + // add up the base values for this class/race // this is what they start with, and they have stat_points more // that can distributed bSTR = BaseClass[classtemp][0] + BaseRace[racetemp][0]; @@ -1721,7 +1725,7 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc) bTOTAL = bSTR + bSTA + bAGI + bDEX + bWIS + bINT + bCHA; cTOTAL = cc->STR + cc->STA + cc->AGI + cc->DEX + cc->WIS + cc->INT + cc->CHA; - // solar: the first check makes sure the total is exactly what was expected. + // the first check makes sure the total is exactly what was expected. // this will catch all the stat cheating, but there's still the issue // of reducing CHA or INT or something, to use for STR, so we check // that none are lower than the base or higher than base + stat_points diff --git a/world/client.h b/world/client.h index 7c460fe9a..c6b67f91d 100644 --- a/world/client.h +++ b/world/client.h @@ -109,7 +109,7 @@ private: bool HandleDeleteCharacterPacket(const EQApplicationPacket *app); bool HandleZoneChangePacket(const EQApplicationPacket *app); - EQStreamInterface* const eqs; + EQStreamInterface* eqs; }; bool CheckCharCreateInfoSoF(CharCreate_Struct *cc); diff --git a/world/cliententry.cpp b/world/cliententry.cpp index 034b7ef9a..5e896dca0 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -93,6 +93,8 @@ ClientListEntry::~ClientListEntry() { Camp(); // updates zoneserver's numplayers client_list.RemoveCLEReferances(this); } + for (auto &elem : tell_queue) + safe_delete_array(elem); tell_queue.clear(); } @@ -234,6 +236,8 @@ void ClientListEntry::ClearVars(bool iAll) { pLFG = 0; gm = 0; pClientVersion = 0; + for (auto &elem : tell_queue) + safe_delete_array(elem); tell_queue.clear(); } @@ -310,6 +314,7 @@ void ClientListEntry::ProcessTellQueue() pack->Deflate(); Server()->SendPacket(pack); safe_delete(pack); + safe_delete_array(*it); it = tell_queue.erase(it); } return; diff --git a/world/net.cpp b/world/net.cpp index 8bc88875c..434491a0a 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -394,7 +394,7 @@ int main(int argc, char** argv) { Timer InterserverTimer(INTERSERVER_TIMER); // does MySQL pings and auto-reconnect InterserverTimer.Trigger(); uint8 ReconnectCounter = 100; - EQStream* eqs; + std::shared_ptr eqs; EmuTCPConnection* tcpc; EQStreamInterface *eqsi; @@ -412,6 +412,8 @@ int main(int argc, char** argv) { stream_identifier.AddStream(eqs); //takes the stream } + eqs = nullptr; + //give the stream identifier a chance to do its work.... stream_identifier.Process(); diff --git a/world/worlddb.cpp b/world/worlddb.cpp index c8b95d0a9..223ae89d6 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -32,7 +32,7 @@ extern std::vector character_create_allocations; extern std::vector character_create_race_class_combos; -// solar: the current stuff is at the bottom of this function +// the current stuff is at the bottom of this function void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs, uint32 ClientVersion) { Inventory *inv; uint8 has_home = 0; diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 65c80cac7..e24dc421c 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -665,7 +665,7 @@ bool ZoneServer::Process() { } case ServerOP_ZoneToZoneRequest: { // - // solar: ZoneChange is received by the zone the player is in, then the + // ZoneChange is received by the zone the player is in, then the // zone sends a ZTZ which ends up here. This code then find the target // (ingress point) and boots it if needed, then sends the ZTZ to it. // The ingress server will decide wether the player can enter, then will @@ -1405,10 +1405,10 @@ void ZoneServer::TriggerBootup(uint32 iZoneID, uint32 iInstanceID, const char* a LSBootUpdate(iZoneID, iInstanceID); } -void ZoneServer::IncommingClient(Client* client) { +void ZoneServer::IncomingClient(Client* client) { BootingUp = true; - auto pack = new ServerPacket(ServerOP_ZoneIncClient, sizeof(ServerZoneIncommingClient_Struct)); - ServerZoneIncommingClient_Struct* s = (ServerZoneIncommingClient_Struct*) pack->pBuffer; + auto pack = new ServerPacket(ServerOP_ZoneIncClient, sizeof(ServerZoneIncomingClient_Struct)); + ServerZoneIncomingClient_Struct* s = (ServerZoneIncomingClient_Struct*) pack->pBuffer; s->zoneid = GetZoneID(); s->instanceid = GetInstanceID(); s->wid = client->GetWID(); diff --git a/world/zoneserver.h b/world/zoneserver.h index 661e03019..1babecc98 100644 --- a/world/zoneserver.h +++ b/world/zoneserver.h @@ -40,7 +40,7 @@ public: bool SetZone(uint32 iZoneID, uint32 iInstanceID = 0, bool iStaticZone = false); void TriggerBootup(uint32 iZoneID = 0, uint32 iInstanceID = 0, const char* iAdminName = 0, bool iMakeStatic = false); void Disconnect() { tcpc->Disconnect(); } - void IncommingClient(Client* client); + void IncomingClient(Client* client); void LSBootUpdate(uint32 zoneid, uint32 iInstanceID = 0, bool startup = false); void LSSleepUpdate(uint32 zoneid); void LSShutDownUpdate(uint32 zoneid); diff --git a/zone/aggro.cpp b/zone/aggro.cpp index 7e4653a11..e983b8ea9 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -481,7 +481,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) { } /* -solar: returns false if attack should not be allowed +returns false if attack should not be allowed I try to list every type of conflict that's possible here, so it's easy to see how the decision is made. Yea, it could be condensed and made faster, but I'm doing it this way to make it readable and easy to modify @@ -550,7 +550,7 @@ bool Mob::IsAttackAllowed(Mob *target, bool isSpellAttack) } } - // solar: the format here is a matrix of mob type vs mob type. + // the format here is a matrix of mob type vs mob type. // redundant ones are omitted and the reverse is tried if it falls through. // first figure out if we're pets. we always look at the master's flags. @@ -701,7 +701,7 @@ type', in which case, the answer is yes. } -// solar: this is to check if non detrimental things are allowed to be done +// this is to check if non detrimental things are allowed to be done // to the target. clients cannot affect npcs and vice versa, and clients // cannot affect other clients that are not of the same pvp flag as them. // also goes for their pets @@ -717,7 +717,7 @@ bool Mob::IsBeneficialAllowed(Mob *target) if (target->GetAllowBeneficial()) return true; - // solar: see IsAttackAllowed for notes + // see IsAttackAllowed for notes // first figure out if we're pets. we always look at the master's flags. // no need to compare pets to anything @@ -1233,7 +1233,7 @@ void Mob::ClearFeignMemory() { AIfeignremember_timer->Disable(); } -bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) { +bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) { /* Charm formula is correct based on over 50 hours of personal live parsing - Kayen @@ -1260,9 +1260,9 @@ bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) { return true; if (RuleB(Spells, CharismaCharmDuration)) - resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster,0,0,true,true); + resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster,false,0,true,true); else - resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, 0,0, false, true); + resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, false,0, false, true); //2: The mob makes a resistance check against the charm if (resist_check == 100) @@ -1286,8 +1286,7 @@ bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) { { // Assume this is a harmony/pacify spell // If 'Lull' spell resists, do a second resist check with a charisma modifier AND regular resist checks. If resists agian you gain aggro. - resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, true); - + resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, false,0,true); if (resist_check == 100) return true; } diff --git a/zone/attack.cpp b/zone/attack.cpp index eae49c57a..25dc88688 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -343,7 +343,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte) { - /* solar: called when a mob is attacked, does the checks to see if it's a hit + /* called when a mob is attacked, does the checks to see if it's a hit * and does other mitigation checks. 'this' is the mob being attacked. * * special return values: @@ -1378,7 +1378,7 @@ void Client::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes att if(spell_id==0) spell_id = SPELL_UNKNOWN; - // cut all PVP spell damage to 2/3 -solar + // cut all PVP spell damage to 2/3 // Blasting ourselfs is considered PvP //Don't do PvP mitigation if the caster is damaging himself if(other && other->IsClient() && (other != this) && damage > 0) { @@ -2545,7 +2545,7 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b } } -// solar: this is called from Damage() when 'this' is attacked by 'other. +// this is called from Damage() when 'this' is attacked by 'other. // 'this' is the one being attacked // 'other' is the attacker // a damage shield causes damage (or healing) to whoever attacks the wearer diff --git a/zone/beacon.cpp b/zone/beacon.cpp index aa44b2504..5a952dc9d 100644 --- a/zone/beacon.cpp +++ b/zone/beacon.cpp @@ -18,7 +18,7 @@ /* -solar: Beacon class, extends Mob. Used for AE rain spells to have a mob +Beacon class, extends Mob. Used for AE rain spells to have a mob target to center around. */ @@ -48,7 +48,7 @@ class Zone; extern EntityList entity_list; extern Zone* zone; -// solar: if lifetime is 0 this is a permanent beacon.. not sure if that'll be +// if lifetime is 0 this is a permanent beacon.. not sure if that'll be // useful for anything Beacon::Beacon(Mob *at_mob, int lifetime) :Mob diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index 70ab56400..8cceb5023 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -2976,7 +2976,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne //Special custom cases for loading effects on to NPC from 'npc_spels_effects' table if (IsAISpellEffect) { - //Non-Focused Effect to modify incomming spell damage by resist type. + //Non-Focused Effect to modify incoming spell damage by resist type. case SE_FcSpellVulnerability: ModVulnerability(base2, effect_value); break; diff --git a/zone/bot.cpp b/zone/bot.cpp index f7e6dbc32..c39696576 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -7406,7 +7406,7 @@ float Bot::GetProcChances(float ProcBonus, uint16 hand) { bool Bot::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte) { - /* solar: called when a mob is attacked, does the checks to see if it's a hit + /* called when a mob is attacked, does the checks to see if it's a hit * and does other mitigation checks. 'this' is the mob being attacked. * * special return values: @@ -7781,7 +7781,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) { if (bIsBehind || bCanFrontalBS){ // Bot is behind other OR can do Frontal Backstab - // solar - chance to assassinate + // chance to assassinate int chance = 10 + (GetDEX()/10) + (itembonuses.HeroicDEX/10); //18.5% chance at 85 dex 40% chance at 300 dex if( level >= 60 && // bot is 60 or higher diff --git a/zone/client.cpp b/zone/client.cpp index 20263ff07..5ceafec49 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -305,6 +305,8 @@ Client::Client(EQStreamInterface* ieqs) active_light = innate_light; spell_light = equip_light = NOT_USED; + + AI_Init(); } Client::~Client() { @@ -402,6 +404,7 @@ Client::~Client() { //let the stream factory know were done with this stream eqs->Close(); eqs->ReleaseFromUse(); + safe_delete(eqs); UninitializeBuffSlots(); } @@ -7275,7 +7278,7 @@ void Client::SendMercPersonalInfo() stancecount += zone->merc_stance_list[GetMercInfo().MercTemplateID].size(); if(stancecount > MAX_MERC_STANCES || mercCount > MAX_MERC || mercTypeCount > MAX_MERC_GRADES) { - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercPersonalInfo canceled: (%i) (%i) (%i)", stancecount, mercCount, mercTypeCount); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo canceled: (%i) (%i) (%i) for %s", stancecount, mercCount, mercTypeCount, GetName()); SendMercMerchantResponsePacket(0); return; } @@ -7369,13 +7372,13 @@ void Client::SendMercPersonalInfo() return; } } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercPersonalInfo Send Successful"); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Send Successful for %s.", GetName()); SendMercMerchantResponsePacket(0); } else { - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercPersonalInfo Send Failed Due to no MercData for %i", GetMercInfo().MercTemplateID); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Send Failed Due to no MercData (%i) for %s", GetMercInfo().MercTemplateID, GetName()); } } diff --git a/zone/client.h b/zone/client.h index 84823085c..fa7da0fc0 100644 --- a/zone/client.h +++ b/zone/client.h @@ -64,6 +64,7 @@ struct Item_Struct; #include #include #include +#include #define CLIENT_TIMEOUT 90000 @@ -201,7 +202,7 @@ struct ClientReward class ClientFactory { public: - Client *MakeClient(EQStream* ieqs); + Client *MakeClient(std::shared_ptr ieqs); }; class Client : public Mob @@ -1138,7 +1139,7 @@ public: void HandleLFGuildResponse(ServerPacket *pack); void SendLFGuildStatus(); void SendGuildLFGuildStatus(); - inline bool XTargettingAvailable() const { return ((ClientVersionBit & BIT_UnderfootAndLater) && RuleB(Character, EnableXTargetting)); } + inline bool XTargettingAvailable() const { return ((ClientVersionBit & BIT_UFAndLater) && RuleB(Character, EnableXTargetting)); } inline uint8 GetMaxXTargets() const { return MaxXTargets; } void SetMaxXTargets(uint8 NewMax); bool IsXTarget(const Mob *m) const; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 309c273f7..a3062891b 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -413,15 +413,6 @@ int Client::HandlePacket(const EQApplicationPacket *app) std::cout << "Received 0x" << std::hex << std::setw(4) << std::setfill('0') << opcode << ", size=" << std::dec << app->size << std::endl; #endif - #ifdef SOLAR - if(0 && opcode != OP_ClientUpdate) - { - Log.LogDebug(Logs::General,"HandlePacket() OPCODE debug enabled client %s", GetName()); - std::cerr << "OPCODE: " << std::hex << std::setw(4) << std::setfill('0') << opcode << std::dec << ", size: " << app->size << std::endl; - DumpPacket(app); - } - #endif - switch(client_state) { case CLIENT_CONNECTING: { if(ConnectingOpcodes.count(opcode) != 1) { @@ -848,7 +839,7 @@ void Client::CompleteConnect() worldserver.SendPacket(pack); delete pack; - if (IsClient() && CastToClient()->GetClientVersionBit() & BIT_UnderfootAndLater) { + if (IsClient() && CastToClient()->GetClientVersionBit() & BIT_UFAndLater) { EQApplicationPacket *outapp = MakeBuffsPacket(false); CastToClient()->FastQueuePacket(&outapp); } @@ -1169,7 +1160,6 @@ void Client::Handle_Connect_OP_SendExpZonein(const EQApplicationPacket *app) //No idea why live sends this if even were not in a guild SendGuildMOTD(); - SpawnMercOnZone(); return; } @@ -1227,8 +1217,7 @@ void Client::Handle_Connect_OP_WearChange(const EQApplicationPacket *app) void Client::Handle_Connect_OP_WorldObjectsSent(const EQApplicationPacket *app) { - //This is a copy of SendExpZonein created for SoF due to packet order change - //This does not affect clients other than SoF + //This is a copy of SendExpZonein created for SoF+ due to packet order change ////////////////////////////////////////////////////// // Spawn Appearance Packet @@ -1295,7 +1284,10 @@ void Client::Handle_Connect_OP_WorldObjectsSent(const EQApplicationPacket *app) //No idea why live sends this if even were not in a guild SendGuildMOTD(); - SpawnMercOnZone(); + if (RuleB(Mercs, AllowMercs)) + { + SpawnMercOnZone(); + } return; } @@ -1400,6 +1392,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) if (RuleB(Character, SharedBankPlat)) m_pp.platinum_shared = database.GetSharedPlatinum(this->AccountID()); + database.ClearOldRecastTimestamps(cid); /* Clear out our old recast timestamps to keep the DB clean */ loaditems = database.GetInventory(cid, &m_inv); /* Load Character Inventory */ database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */ database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */ @@ -1864,7 +1857,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) safe_delete(outapp); } - if (ClientVersionBit & BIT_UnderfootAndLater) { + if (ClientVersionBit & BIT_UFAndLater) { outapp = new EQApplicationPacket(OP_XTargetResponse, 8); outapp->WriteUInt32(GetMaxXTargets()); outapp->WriteUInt32(0); @@ -5503,16 +5496,6 @@ void Client::Handle_OP_EnvDamage(const EQApplicationPacket *app) return; } EnvDamage2_Struct* ed = (EnvDamage2_Struct*)app->pBuffer; - if (admin >= minStatusToAvoidFalling && GetGM()){ - Message(13, "Your GM status protects you from %i points of type %i environmental damage.", ed->damage, ed->dmgtype); - SetHP(GetHP() - 1);//needed or else the client wont acknowledge - return; - } - else if (GetInvul()) { - Message(13, "Your invuln status protects you from %i points of type %i environmental damage.", ed->damage, ed->dmgtype); - SetHP(GetHP() - 1);//needed or else the client wont acknowledge - return; - } int damage = ed->damage; @@ -5534,15 +5517,32 @@ void Client::Handle_OP_EnvDamage(const EQApplicationPacket *app) if (damage < 0) damage = 31337; - else if (zone->GetZoneID() == 183 || zone->GetZoneID() == 184) + if (admin >= minStatusToAvoidFalling && GetGM()){ + Message(13, "Your GM status protects you from %i points of type %i environmental damage.", ed->damage, ed->dmgtype); + SetHP(GetHP() - 1);//needed or else the client wont acknowledge return; - else - SetHP(GetHP() - damage); + } + else if (GetInvul()) { + Message(13, "Your invuln status protects you from %i points of type %i environmental damage.", ed->damage, ed->dmgtype); + SetHP(GetHP() - 1);//needed or else the client wont acknowledge + return; + } - if (GetHP() <= 0) - { - mod_client_death_env(); + else if (zone->GetZoneID() == 183 || zone->GetZoneID() == 184){ + return; + } + else{ + SetHP(GetHP() - (damage * RuleR(Character, EnvironmentDamageMulipliter))); + /* EVENT_ENVIRONMENTAL_DAMAGE */ + int final_damage = (damage * RuleR(Character, EnvironmentDamageMulipliter)); + char buf[24]; + snprintf(buf, 23, "%u %u %i", ed->damage, ed->dmgtype, final_damage); + parse->EventPlayer(EVENT_ENVIRONMENTAL_DAMAGE, this, buf, 0); + } + + if (GetHP() <= 0) { + mod_client_death_env(); Death(0, 32000, SPELL_UNKNOWN, SkillHandtoHand); } SendHPUpdate(); @@ -9314,7 +9314,7 @@ void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app) uint32 merc_command = mc->MercCommand; // Seen 0 (zone in with no merc or suspended), 1 (dismiss merc), 5 (normal state), 20 (unknown), 36 (zone in with merc) int32 option = mc->Option; // Seen -1 (zone in with no merc), 0 (setting to passive stance), 1 (normal or setting to balanced stance) - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Command %i, Option %i received.", merc_command, option); + Log.Out(Logs::General, Logs::Mercenaries, "Command %i, Option %i received from %s.", merc_command, option, GetName()); if (!RuleB(Mercs, AllowMercs)) return; @@ -9348,7 +9348,7 @@ void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app) merc->SetStance(mercTemplate->Stances[option]); GetMercInfo().Stance = mercTemplate->Stances[option]; - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Set Stance: %u", merc->GetStance()); + Log.Out(Logs::General, Logs::Mercenaries, "Set Stance: %u for %s (%s)", merc->GetStance(), merc->GetName(), GetName()); } } } @@ -9371,7 +9371,7 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) uint32 merchant_id = mmsr->MercMerchantID; uint32 altCurrentType = 19; - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Data Request for Merchant ID (%i)", merchant_id); + Log.Out(Logs::General, Logs::Mercenaries, "Data Request for Merchant ID (%i) for %s.", merchant_id, GetName()); //client is requesting data about currently owned mercenary if (merchant_id == 0) { @@ -9379,12 +9379,12 @@ void Client::Handle_OP_MercenaryDataRequest(const EQApplicationPacket *app) //send info about your current merc(s) if (GetMercInfo().mercid) { - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercPersonalInfo Request"); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Request for %s.", GetName()); SendMercPersonalInfo(); } else { - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercPersonalInfo Not Sent - MercID (%i)", GetMercInfo().mercid); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercPersonalInfo Not Sent - MercID (%i) for %s.", GetMercInfo().mercid, GetName()); } } @@ -9497,7 +9497,7 @@ void Client::Handle_OP_MercenaryDataUpdateRequest(const EQApplicationPacket *app return; } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Data Update Request Received."); + Log.Out(Logs::General, Logs::Mercenaries, "Data Update Request Received for %s.", GetName()); if (GetMercID()) { @@ -9523,7 +9523,7 @@ void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app) Command = VARSTRUCT_DECODE_TYPE(uint8, InBuffer); } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Dismiss Request ( %i ) Received.", Command); + Log.Out(Logs::General, Logs::Mercenaries, "Dismiss Request ( %i ) Received for %s.", Command, GetName()); // Handle the dismiss here... DismissMerc(GetMercInfo().mercid); @@ -9548,7 +9548,7 @@ void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app) uint32 merc_unk1 = mmrq->MercUnk01; uint32 merc_unk2 = mmrq->MercUnk02; - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Template ID (%i), Merchant ID (%i), Unknown1 (%i), Unknown2 (%i)", merc_template_id, merchant_id, merc_unk1, merc_unk2); + Log.Out(Logs::General, Logs::Mercenaries, "Template ID (%i), Merchant ID (%i), Unknown1 (%i), Unknown2 (%i), Client: %s", merc_template_id, merchant_id, merc_unk1, merc_unk2, GetName()); //HirePending = true; SetHoTT(0); @@ -9614,7 +9614,7 @@ void Client::Handle_OP_MercenarySuspendRequest(const EQApplicationPacket *app) SuspendMercenary_Struct* sm = (SuspendMercenary_Struct*)app->pBuffer; uint32 merc_suspend = sm->SuspendMerc; // Seen 30 for suspending or unsuspending - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Suspend ( %i ) received.", merc_suspend); + Log.Out(Logs::General, Logs::Mercenaries, "Suspend ( %i ) received for %s.", merc_suspend, GetName()); if (!RuleB(Mercs, AllowMercs)) return; @@ -9634,7 +9634,7 @@ void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app) return; } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Timer Request received."); + Log.Out(Logs::General, Logs::Mercenaries, "Timer Request received for %s.", GetName()); if (!RuleB(Mercs, AllowMercs)) { return; diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 55d9a9f4e..bddc874c2 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -960,6 +960,9 @@ void Client::BulkSendInventoryItems() void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { const Item_Struct* handyitem = nullptr; uint32 numItemSlots = 80; //The max number of items passed in the transaction. + if (ClientVersionBit & BIT_RoFAndLater) { // RoF+ can send 200 items + numItemSlots = 200; + } const Item_Struct *item; std::list merlist = zone->merchanttable[merchant_id]; std::list::const_iterator itr; @@ -2231,7 +2234,7 @@ void Client::ClearHover() entity_list.QueueClients(this, outapp, false); safe_delete(outapp); - if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UnderfootAndLater) + if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UFAndLater) { EQApplicationPacket *outapp = MakeBuffsPacket(false); CastToClient()->FastQueuePacket(&outapp); diff --git a/zone/command.cpp b/zone/command.cpp index 8190bf9fc..f54db9a75 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -8441,25 +8441,25 @@ void command_object(Client *c, const Seperator *sep) return; // Crash Suppressant: No client. How did we get here? // Save it here. We sometimes have need to refer to it in multiple places. - const char* usage_string = "Usage: #object List|Add|Edit|Move|Rotate|Save|Copy|Delete|Undo"; + const char *usage_string = "Usage: #object List|Add|Edit|Move|Rotate|Save|Copy|Delete|Undo"; if ((!sep) || (sep->argnum == 0)) { c->Message(0, usage_string); return; - } + } - Object* o = nullptr; + Object *o = nullptr; Object_Struct od; Door door; - Doors* doors; - Door_Struct* ds; + Doors *doors; + Door_Struct *ds; uint32 id = 0; uint32 itemid = 0; uint32 icon = 0; uint32 instance = 0; uint32 newid = 0; uint16 radius; - EQApplicationPacket* app; + EQApplicationPacket *app; bool bNewObject = false; @@ -8474,8 +8474,9 @@ void command_object(Client *c, const Seperator *sep) strlwr(sep->arg[1]); if (strcasecmp(sep->arg[1], "list") == 0) { - // Insufficient or invalid args - if ((sep->argnum < 2) || (sep->arg[2][0] < '0') || ((sep->arg[2][0] > '9') && ((sep->arg[2][0] & 0xDF) != 'A'))) { + // Insufficient or invalid args + if ((sep->argnum < 2) || (sep->arg[2][0] < '0') || + ((sep->arg[2][0] > '9') && ((sep->arg[2][0] & 0xDF) != 'A'))) { c->Message(0, "Usage: #object List All|(radius)"); return; } @@ -8488,1021 +8489,1090 @@ void command_object(Client *c, const Seperator *sep) if (radius == 0) c->Message(0, "Objects within this zone:"); else - c->Message(0, "Objects within %u units of your current location:", radius); + c->Message(0, "Objects within %u units of your current location:", radius); - std::string query; + std::string query; if (radius) + query = StringFormat( + "SELECT id, xpos, ypos, zpos, heading, itemid, " + "objectname, type, icon, unknown08, unknown10, unknown20 " + "FROM object WHERE zoneid = %u AND version = %u " + "AND (xpos BETWEEN %.1f AND %.1f) " + "AND (ypos BETWEEN %.1f AND %.1f) " + "AND (zpos BETWEEN %.1f AND %.1f) " + "ORDER BY id", + zone->GetZoneID(), zone->GetInstanceVersion(), + c->GetX() - radius, // Yes, we're actually using a bounding box instead of a radius. + c->GetX() + radius, // Much less processing power used this way. + c->GetY() - radius, c->GetY() + radius, c->GetZ() - radius, c->GetZ() + radius); + else query = StringFormat("SELECT id, xpos, ypos, zpos, heading, itemid, " - "objectname, type, icon, unknown08, unknown10, unknown20 " - "FROM object WHERE zoneid = %u AND version = %u " - "AND (xpos BETWEEN %.1f AND %.1f) " - "AND (ypos BETWEEN %.1f AND %.1f) " - "AND (zpos BETWEEN %.1f AND %.1f) " - "ORDER BY id", - zone->GetZoneID(), zone->GetInstanceVersion(), - c->GetX() - radius, // Yes, we're actually using a bounding box instead of a radius. - c->GetX() + radius, // Much less processing power used this way. - c->GetY() - radius, - c->GetY() + radius, - c->GetZ() - radius, - c->GetZ() + radius); - else - query = StringFormat("SELECT id, xpos, ypos, zpos, heading, itemid, " - "objectname, type, icon, unknown08, unknown10, unknown20 " - "FROM object WHERE zoneid = %u AND version = %u " - "ORDER BY id", - zone->GetZoneID(), zone->GetInstanceVersion()); + "objectname, type, icon, unknown08, unknown10, unknown20 " + "FROM object WHERE zoneid = %u AND version = %u " + "ORDER BY id", + zone->GetZoneID(), zone->GetInstanceVersion()); - auto results = database.QueryDatabase(query); - if (!results.Success()) { - c->Message(0, "Error in objects query"); - return; - } + auto results = database.QueryDatabase(query); + if (!results.Success()) { + c->Message(0, "Error in objects query"); + return; + } - for (auto row = results.begin(); row != results.end(); ++row) { - id = atoi(row[0]); - od.x = atof(row[1]); - od.y = atof(row[2]); - od.z = atof(row[3]); - od.heading = atof(row[4]); - itemid = atoi(row[5]); - strn0cpy(od.object_name, row[6], sizeof(od.object_name)); - od.object_name[sizeof(od.object_name) - 1] = '\0'; // Required if strlen(row[col++]) exactly == sizeof(object_name) + for (auto row = results.begin(); row != results.end(); ++row) { + id = atoi(row[0]); + od.x = atof(row[1]); + od.y = atof(row[2]); + od.z = atof(row[3]); + od.heading = atof(row[4]); + itemid = atoi(row[5]); + strn0cpy(od.object_name, row[6], sizeof(od.object_name)); + od.object_name[sizeof(od.object_name) - 1] = + '\0'; // Required if strlen(row[col++]) exactly == sizeof(object_name) - od.object_type = atoi(row[7]); - icon = atoi(row[8]); - od.unknown008 = atoi(row[9]); - od.unknown010 = atoi(row[10]); - od.unknown020 = atoi(row[11]); + od.object_type = atoi(row[7]); + icon = atoi(row[8]); + od.unknown008 = atoi(row[9]); + od.unknown010 = atoi(row[10]); + od.unknown020 = atoi(row[11]); - switch (od.object_type) - { - case 0: // Static Object - case staticType: // Static Object unlocked for changes - if (od.unknown008 == 0) // Unknown08 field is optional Size parameter for static objects - od.unknown008 = 100; // Static object default Size is 100% + switch (od.object_type) { + case 0: // Static Object + case staticType: // Static Object unlocked for changes + if (od.unknown008 == 0) // Unknown08 field is optional Size parameter for static objects + od.unknown008 = 100; // Static object default Size is 100% - c->Message(0,"- STATIC Object (%s): id %u, x %.1f, y %.1f, z %.1f, h %.1f, model %s, size %u, solidtype %u, incline %u", (od.object_type == 0) ? "locked" : "unlocked", id, od.x, od.y, od.z, od.heading, od.object_name, od.unknown008, od.unknown010, od.unknown020); - break; + c->Message(0, "- STATIC Object (%s): id %u, x %.1f, y %.1f, z %.1f, h %.1f, model %s, " + "size %u, solidtype %u, incline %u", + (od.object_type == 0) ? "locked" : "unlocked", id, od.x, od.y, od.z, + od.heading, od.object_name, od.unknown008, od.unknown010, od.unknown020); + break; - case OT_DROPPEDITEM: // Ground Spawn - c->Message(0,"- TEMPORARY Object: id %u, x %.1f, y %.1f, z %.1f, h %.1f, itemid %u, model %s, icon %u", id, od.x, od.y, od.z, od.heading, itemid, od.object_name, icon); - break; + case OT_DROPPEDITEM: // Ground Spawn + c->Message(0, "- TEMPORARY Object: id %u, x %.1f, y %.1f, z %.1f, h %.1f, itemid %u, " + "model %s, icon %u", + id, od.x, od.y, od.z, od.heading, itemid, od.object_name, icon); + break; - default: // All others == Tradeskill Objects - c->Message(0, "- TRADESKILL Object: id %u, x %.1f, y %.1f, z %.1f, h %.1f, model %s, type %u, icon %u", id, od.x, od.y, od.z, od.heading, od.object_name, od.object_type, icon); - break; - } - } + default: // All others == Tradeskill Objects + c->Message(0, "- TRADESKILL Object: id %u, x %.1f, y %.1f, z %.1f, h %.1f, model %s, " + "type %u, icon %u", + id, od.x, od.y, od.z, od.heading, od.object_name, od.object_type, icon); + break; + } + } - c->Message(0, "%u object%s found", results.RowCount(), (results.RowCount() == 1)? "": "s"); - return; - } + c->Message(0, "%u object%s found", results.RowCount(), (results.RowCount() == 1) ? "" : "s"); + return; + } if (strcasecmp(sep->arg[1], "add") == 0) { - // Insufficient or invalid arguments - if ((sep->argnum < 3) || ((sep->arg[3][0] == '\0') && (sep->arg[4][0] < '0') && (sep->arg[4][0] > '9'))) { - c->Message(0, "Usage: (Static Object): #object Add [ObjectID] 0 Model [SizePercent] [SolidType] [Incline]"); - c->Message(0, "Usage: (Tradeskill Object): #object Add [ObjectID] TypeNum Model Icon"); - c->Message(0, "- Notes: Model must start with a letter, max length 16. SolidTypes = 0 (Solid), 1 (Sometimes Non-Solid)"); - return; - } + // Insufficient or invalid arguments + if ((sep->argnum < 3) || + ((sep->arg[3][0] == '\0') && (sep->arg[4][0] < '0') && (sep->arg[4][0] > '9'))) { + c->Message(0, "Usage: (Static Object): #object Add [ObjectID] 0 Model [SizePercent] " + "[SolidType] [Incline]"); + c->Message(0, "Usage: (Tradeskill Object): #object Add [ObjectID] TypeNum Model Icon"); + c->Message(0, "- Notes: Model must start with a letter, max length 16. SolidTypes = 0 (Solid), " + "1 (Sometimes Non-Solid)"); + return; + } - int col; + int col; - if (sep->argnum > 3) { // Model name in arg3? - if ((sep->arg[3][0] <= '9') && (sep->arg[3][0] >= '0')) { - // Nope, user must have specified ObjectID. Extract it. - id = atoi(sep->arg[2]); - col = 1; // Bump all other arguments one to the right. Model is in arg4. - } - else { - // Yep, arg3 is non-numeric, ObjectID must be omitted and model must be arg3 - id = 0; - col = 0; - } - } - else { - // Nope, only 3 args. Object ID must be omitted and arg3 must be model. - id = 0; - col = 0; - } + if (sep->argnum > 3) { // Model name in arg3? + if ((sep->arg[3][0] <= '9') && (sep->arg[3][0] >= '0')) { + // Nope, user must have specified ObjectID. Extract it. + id = atoi(sep->arg[2]); + col = 1; // Bump all other arguments one to the right. Model is in arg4. + } else { + // Yep, arg3 is non-numeric, ObjectID must be omitted and model must be arg3 + id = 0; + col = 0; + } + } else { + // Nope, only 3 args. Object ID must be omitted and arg3 must be model. + id = 0; + col = 0; + } - memset(&od, 0, sizeof(od)); + memset(&od, 0, sizeof(od)); - od.object_type = atoi(sep->arg[2 + col]); + od.object_type = atoi(sep->arg[2 + col]); - switch (od.object_type) { - case 0: // Static Object - if ((sep->argnum - col) > 3) { - od.unknown008 = atoi(sep->arg[4 + col]); // Size specified + switch (od.object_type) { + case 0: // Static Object + if ((sep->argnum - col) > 3) { + od.unknown008 = atoi(sep->arg[4 + col]); // Size specified - if ((sep->argnum - col) > 4) { - od.unknown010 = atoi(sep->arg[5 + col]); // SolidType specified + if ((sep->argnum - col) > 4) { + od.unknown010 = atoi(sep->arg[5 + col]); // SolidType specified - if ((sep->argnum - col) > 5) - od.unknown020 = atoi(sep->arg[6 + col]); // Incline specified - } - } - break; + if ((sep->argnum - col) > 5) + od.unknown020 = atoi(sep->arg[6 + col]); // Incline specified + } + } + break; - case 1: // Ground Spawn - c->Message(0, "ERROR: Object Type 1 is used for temporarily spawned ground spawns and dropped items, which are not supported with #object. See the 'ground_spawns' table in the database."); - return; + case 1: // Ground Spawn + c->Message(0, "ERROR: Object Type 1 is used for temporarily spawned ground spawns and dropped " + "items, which are not supported with #object. See the 'ground_spawns' table in " + "the database."); + return; - default: // Everything else == Tradeskill Object - icon = ((sep->argnum - col) > 3) ? atoi(sep->arg[4 + col]) : 0; + default: // Everything else == Tradeskill Object + icon = ((sep->argnum - col) > 3) ? atoi(sep->arg[4 + col]) : 0; - if (icon == 0) { - c->Message(0, "ERROR: Required property 'Icon' not specified for Tradeskill Object"); - return; - } + if (icon == 0) { + c->Message(0, "ERROR: Required property 'Icon' not specified for Tradeskill Object"); + return; + } - break; - } + break; + } - od.x = c->GetX(); - od.y = c->GetY(); - od.z = c->GetZ() - (c->GetSize() * 0.625f); - od.heading = c->GetHeading() * 2.0f; // GetHeading() is half of actual. Compensate by doubling. + od.x = c->GetX(); + od.y = c->GetY(); + od.z = c->GetZ() - (c->GetSize() * 0.625f); + od.heading = c->GetHeading() * 2.0f; // GetHeading() is half of actual. Compensate by doubling. - std::string query; - if (id) { - // ID specified. Verify that it doesn't already exist. - query = StringFormat("SELECT COUNT(*) FROM object WHERE ID = %u", id); - auto results = database.QueryDatabase(query); - if (results.Success() && results.RowCount() != 0) { - auto row = results.begin(); - if (atoi(row[0]) > 0) // Yep, in database already. - id = 0; - } + std::string query; + if (id) { + // ID specified. Verify that it doesn't already exist. + query = StringFormat("SELECT COUNT(*) FROM object WHERE ID = %u", id); + auto results = database.QueryDatabase(query); + if (results.Success() && results.RowCount() != 0) { + auto row = results.begin(); + if (atoi(row[0]) > 0) // Yep, in database already. + id = 0; + } - // Not in database. Already spawned, just not saved? - // Yep, already spawned. - if (id && entity_list.FindObject(id)) - id = 0; + // Not in database. Already spawned, just not saved? + // Yep, already spawned. + if (id && entity_list.FindObject(id)) + id = 0; - if (id == 0) { - c->Message(0, "ERROR: An object already exists with the id %u", atoi(sep->arg[2])); - return; - } - } + if (id == 0) { + c->Message(0, "ERROR: An object already exists with the id %u", atoi(sep->arg[2])); + return; + } + } - int objectsFound = 0; - // Verify no other objects already in this spot (accidental double-click of Hotkey?) - query = StringFormat("SELECT COUNT(*) FROM object WHERE zoneid = %u " - "AND version=%u AND (posx BETWEEN %.1f AND %.1f) " - "AND (posy BETWEEN %.1f AND %.1f) " - "AND (posz BETWEEN %.1f AND %.1f)", - zone->GetZoneID(), zone->GetInstanceVersion(), - od.x - 0.2f, od.x + 0.2f, // Yes, we're actually using a bounding box instead of a radius. - od.y - 0.2f, od.y + 0.2f, // Much less processing power used this way. - od.z - 0.2f, od.z + 0.2f); // It's pretty forgiving, though, allowing for close-proximity objects + int objectsFound = 0; + // Verify no other objects already in this spot (accidental double-click of Hotkey?) + query = StringFormat( + "SELECT COUNT(*) FROM object WHERE zoneid = %u " + "AND version=%u AND (posx BETWEEN %.1f AND %.1f) " + "AND (posy BETWEEN %.1f AND %.1f) " + "AND (posz BETWEEN %.1f AND %.1f)", + zone->GetZoneID(), zone->GetInstanceVersion(), od.x - 0.2f, + od.x + 0.2f, // Yes, we're actually using a bounding box instead of a radius. + od.y - 0.2f, od.y + 0.2f, // Much less processing power used this way. + od.z - 0.2f, od.z + 0.2f); // It's pretty forgiving, though, allowing for close-proximity objects - auto results = database.QueryDatabase(query); - if (results.Success() && results.RowCount() != 0) { - auto row = results.begin(); - objectsFound = atoi(row[0]); // Number of nearby objects from database - } + auto results = database.QueryDatabase(query); + if (results.Success() && results.RowCount() != 0) { + auto row = results.begin(); + objectsFound = atoi(row[0]); // Number of nearby objects from database + } - // No objects found in database too close. How about spawned but not yet saved? - if (objectsFound == 0 && entity_list.FindNearbyObject(od.x, od.y, od.z, 0.2f)) - objectsFound = 1; + // No objects found in database too close. How about spawned but not yet saved? + if (objectsFound == 0 && entity_list.FindNearbyObject(od.x, od.y, od.z, 0.2f)) + objectsFound = 1; - if (objectsFound) { - c->Message(0, "ERROR: Object already at this location."); - return; - } + if (objectsFound) { + c->Message(0, "ERROR: Object already at this location."); + return; + } - // Strip any single quotes from objectname (SQL injection FTL!) - strn0cpy(od.object_name, sep->arg[3 + col], sizeof(od.object_name)); + // Strip any single quotes from objectname (SQL injection FTL!) + strn0cpy(od.object_name, sep->arg[3 + col], sizeof(od.object_name)); - uint32 len = strlen(od.object_name); - for (col = 0; col < (uint32)len; col++) { - if (od.object_name[col] != '\'') - continue; + uint32 len = strlen(od.object_name); + for (col = 0; col < (uint32)len; col++) { + if (od.object_name[col] != '\'') + continue; - // Uh oh, 1337 h4x0r monkeying around! Strip that apostrophe! - memcpy(&od.object_name[col], &od.object_name[col + 1], len - col); - len--; - col--; - } + // Uh oh, 1337 h4x0r monkeying around! Strip that apostrophe! + memcpy(&od.object_name[col], &od.object_name[col + 1], len - col); + len--; + col--; + } - strupr(od.object_name); // Model names are always upper-case. + strupr(od.object_name); // Model names are always upper-case. - if ((od.object_name[0] < 'A') || (od.object_name[0] > 'Z')) { - c->Message(0, "ERROR: Model name must start with a letter."); - return; - } + if ((od.object_name[0] < 'A') || (od.object_name[0] > 'Z')) { + c->Message(0, "ERROR: Model name must start with a letter."); + return; + } - if (id == 0) { - // No ID specified. Get a best-guess next number from the database - // If there's a problem retrieving an ID from the database, it'll end up being object # 1. No biggie. + if (id == 0) { + // No ID specified. Get a best-guess next number from the database + // If there's a problem retrieving an ID from the database, it'll end up being object # 1. No + // biggie. - query = "SELECT MAX(id) FROM object"; - results = database.QueryDatabase(query); - if (results.Success() && results.RowCount() != 0) { - auto row = results.begin(); - id = atoi(row[0]); - } + query = "SELECT MAX(id) FROM object"; + results = database.QueryDatabase(query); + if (results.Success() && results.RowCount() != 0) { + auto row = results.begin(); + id = atoi(row[0]); + } - id++; - } + id++; + } - // Make sure not to overwrite already-spawned objects that haven't been saved yet. - while (o = entity_list.FindObject(id)) - id++; + // Make sure not to overwrite already-spawned objects that haven't been saved yet. + while (o = entity_list.FindObject(id)) + id++; - // Static object - if (od.object_type == 0) - od.object_type = staticType; // Temporary. We'll make it 0 when we Save + // Static object + if (od.object_type == 0) + od.object_type = staticType; // Temporary. We'll make it 0 when we Save - od.zone_id = zone->GetZoneID(); - od.zone_instance = zone->GetInstanceVersion(); + od.zone_id = zone->GetZoneID(); + od.zone_instance = zone->GetInstanceVersion(); - o = new Object(id, od.object_type, icon, od, nullptr); + o = new Object(id, od.object_type, icon, od, nullptr); - // Add to our zone entity list and spawn immediately for all clients - entity_list.AddObject(o, true); + // Add to our zone entity list and spawn immediately for all clients + entity_list.AddObject(o, true); - // Bump player back to avoid getting stuck inside new object + // Bump player back to avoid getting stuck inside new object - // GetHeading() returns half of the actual heading, for some reason, so we'll double it here for computation - x2 = 10.0f * sin(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); - y2 = 10.0f * cos(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); - c->MovePC(c->GetX() - x2, c->GetY() - y2, c->GetZ(), c->GetHeading() * 2); + // GetHeading() returns half of the actual heading, for some reason, so we'll double it here for + // computation + x2 = 10.0f * sin(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); + y2 = 10.0f * cos(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); + c->MovePC(c->GetX() - x2, c->GetY() - y2, c->GetZ(), c->GetHeading() * 2); - c->Message(0, "Spawning object with tentative id %u at location (%.1f, %.1f, %.1f heading %.1f). Use '#object Save' to save to database when satisfied with placement.", id, od.x, od.y, od.z, od.heading); + c->Message(0, "Spawning object with tentative id %u at location (%.1f, %.1f, %.1f heading %.1f). Use " + "'#object Save' to save to database when satisfied with placement.", + id, od.x, od.y, od.z, od.heading); - // Temporary Static Object - if (od.object_type == staticType) - c->Message(0, "- Note: Static Object will act like a tradeskill container and will not reflect size, solidtype, or incline values until you commit with '#object Save', after which it will be unchangeable until you use '#object Edit' and zone back in."); + // Temporary Static Object + if (od.object_type == staticType) + c->Message(0, "- Note: Static Object will act like a tradeskill container and will not reflect " + "size, solidtype, or incline values until you commit with '#object Save', after " + "which it will be unchangeable until you use '#object Edit' and zone back in."); - return; - } + return; + } - if (strcasecmp(sep->arg[1], "edit") == 0) { + if (strcasecmp(sep->arg[1], "edit") == 0) { if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) < 1)) { - c->Message(0, "Usage: #object Edit (ObjectID) [PropertyName] [NewValue]"); - c->Message(0, "- Static Object (Type 0) Properties: model, type, size, solidtype, incline"); - c->Message(0, "- Tradeskill Object (Type 2+) Properties: model, type, icon"); - - return; - } - - o = entity_list.FindObject(id); - - // Object already available in-zone? - if (o) { - // Yep, looks like we can make real-time changes. - if (sep->argnum < 4) { - // Or not. '#object Edit (ObjectID)' called without PropertyName and NewValue - c->Message(0, "Note: Object %u already unlocked and ready for changes", id); - return; - } - } - else { - // Object not found in-zone in a modifiable form. Check for valid matching circumstances. - std::string query = StringFormat("SELECT zoneid, version, type FROM object WHERE id = %u", id); - auto results = database.QueryDatabase(query); - if (!results.Success() || results.RowCount() == 0) { - c->Message(0, "ERROR: Object %u not found", id); - return; - } - - auto row = results.begin(); - od.zone_id = atoi(row[0]); - od.zone_instance = atoi(row[1]); - od.object_type = atoi(row[2]); - uint32 objectsFound = 1; - - // Object not in this zone? - if (od.zone_id != zone->GetZoneID()) { - c->Message(0, "ERROR: Object %u not in this zone.", id); - return; - } - - // Object not in this instance? - if (od.zone_instance != zone->GetInstanceVersion()) { - c->Message(0, "ERROR: Object %u not part of this instance version.", id); - return; - } - - switch (od.object_type) - { - case 0: // Static object needing unlocking - // Convert to tradeskill object temporarily for changes - query = StringFormat("UPDATE object SET type = %u WHERE id = %u", staticType, id); - - database.QueryDatabase(query); - - c->Message(0, "Static Object %u unlocked for editing. You must zone out and back in to make your changes, then commit them with '#object Save'.", id); - if (sep->argnum >= 4) - c->Message(0, "NOTE: The change you specified has not been applied, since the static object had not been unlocked for editing yet."); - return; - - case OT_DROPPEDITEM: - c->Message(0, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, which cannot be manipulated with #object. See the 'ground_spawns' table in the database.", id); - return; - - case staticType: - c->Message(0, "ERROR: Object %u has been unlocked for editing, but you must zone out and back in for your client to refresh its object table before you can make changes to it.", id); - return; - - default: - // Unknown error preventing us from seeing the object in the zone. - c->Message(0, "ERROR: Unknown problem attempting to manipulate object %u", id); - return; - } - } - - // If we're here, we have a manipulable object ready for changes. - strlwr(sep->arg[3]); // Case insensitive PropertyName - strupr(sep->arg[4]); // In case it's model name, which should always be upper-case - - // Read current object info for reference - icon = o->GetIcon(); - o->GetObjectData(&od); - - // We'll be a little more picky with property names, to prevent errors. Check against the whole word. - if (strcmp(sep->arg[3], "model") == 0) { - - if ((sep->arg[4][0] < 'A') || (sep->arg[4][0] > 'Z')) { - c->Message(0, "ERROR: Model names must begin with a letter."); - return; - } - - strn0cpy(od.object_name, sep->arg[4], sizeof(od.object_name)); - - o->SetObjectData(&od); - - c->Message(0, "Object %u now being rendered with model '%s'", id, od.object_name); - } - else if (strcmp(sep->arg[3], "type") == 0) { - if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { - c->Message(0, "ERROR: Invalid type number"); - return; - } - - od.object_type = atoi(sep->arg[4]); - - switch (od.object_type) { - case 0: - // Convert Static Object to temporary changeable type - od.object_type = staticType; - c->Message(0, "Note: Static Object will still act like tradeskill object and will not reflect size, solidtype, or incline settings until committed to the database with '#object Save', after which it will be unchangeable until it is unlocked again with '#object Edit'."); - break; - - case OT_DROPPEDITEM: - c->Message(0, "ERROR: Object Type 1 is used for temporarily spawned ground spawns and dropped items, which are not supported with #object. See the 'ground_spawns' table in the database."); - return; - - default: - c->Message(0, "Object %u changed to Tradeskill Object Type %u", id, od.object_type); - break; - } - - o->SetType(od.object_type); - } - else if (strcmp(sep->arg[3], "size") == 0) { - if (od.object_type != staticType) { - c->Message(0, "ERROR: Object %u is not a Static Object and does not support the Size property", id); - return; - } - - if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { - c->Message(0, "ERROR: Invalid size specified. Please enter a number."); - return; - } - - od.unknown008 = atoi(sep->arg[4]); - o->SetObjectData(&od); - - if (od.unknown008 == 0) // 0 == unspecified == 100% - od.unknown008 = 100; - - c->Message(0, "Static Object %u set to %u%% size. Size will take effect when you commit to the database with '#object Save', after which the object will be unchangeable until you unlock it again with '#object Edit' and zone out and back in.", id, od.unknown008); - } - else if (strcmp(sep->arg[3], "solidtype") == 0) { - - if (od.object_type != staticType) { - c->Message(0, "ERROR: Object %u is not a Static Object and does not support the SolidType property", id); - return; - } - - if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { - c->Message(0, "ERROR: Invalid solidtype specified. Please enter a number."); - return; - } - - od.unknown010 = atoi(sep->arg[4]); - o->SetObjectData(&od); - - c->Message(0, "Static Object %u set to SolidType %u. Change will take effect when you commit to the database with '#object Save'. Support for this property is on a per-model basis, mostly seen in smaller objects such as chests and tables.", id, od.unknown010); - } - else if (strcmp(sep->arg[3], "icon") == 0) { - - if ((od.object_type < 2) || (od.object_type == staticType)) { - c->Message(0, "ERROR: Object %u is not a Tradeskill Object and does not support the Icon property", id); - return; - } - - if ((icon = atoi(sep->arg[4])) == 0) { - c->Message(0, "ERROR: Invalid Icon specified. Please enter an icon number."); - return; - } - - o->SetIcon(icon); - c->Message(0, "Tradeskill Object %u icon set to %u", id, icon); - } - else if (strcmp(sep->arg[3], "incline") == 0) { - if (od.object_type != staticType) { - c->Message(0, "ERROR: Object %u is not a Static Object and does not support the Incline property", id); - return; - } - - if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { - c->Message(0, "ERROR: Invalid Incline specified. Please enter a number. Normal range is 0-512."); - return; - } - - od.unknown020 = atoi(sep->arg[4]); - o->SetObjectData(&od); - - c->Message(0, "Static Object %u set to %u incline. Incline will take effect when you commit to the database with '#object Save', after which the object will be unchangeable until you unlock it again with '#object Edit' and zone out and back in.", id, od.unknown020); - } - else { - c->Message(0, "ERROR: Unrecognized property name: %s", sep->arg[3]); - return; - } - - // Repop object to have it reflect the change. - app = new EQApplicationPacket(); - o->CreateDeSpawnPacket(app); - entity_list.QueueClients(0, app); - safe_delete(app); - - app = new EQApplicationPacket(); - o->CreateSpawnPacket(app); - entity_list.QueueClients(0, app); - safe_delete(app); - return; - } - - if (strcasecmp(sep->arg[1], "move") == 0) { - - if ((sep->argnum < 2) || // Not enough arguments - ((id = atoi(sep->arg[2])) == 0) || // ID not specified - (((sep->arg[3][0] < '0') || (sep->arg[3][0] > '9')) && - ((sep->arg[3][0] & 0xDF) != 'T') && - (sep->arg[3][0] != '-') && (sep->arg[3][0] != '.'))) { // Location argument not specified correctly - c->Message(0, "Usage: #object Move (ObjectID) ToMe|(x y z [h])"); - return; - } - - if (!(o = entity_list.FindObject(id))) { - std::string query = StringFormat("SELECT zoneid, version, type FROM object WHERE id = %u", id); - auto results = database.QueryDatabase(query); - if (!results.Success() || results.RowCount() == 0) { - c->Message(0, "ERROR: Object %u not found", id); - return; - } - - auto row = results.begin(); - od.zone_id = atoi(row[0]); - od.zone_instance = atoi(row[1]); - od.object_type = atoi(row[2]); - - - if (od.zone_id != zone->GetZoneID()) { - c->Message(0, "ERROR: Object %u is not in this zone", id); - return; - } - - if (od.zone_instance != zone->GetInstanceVersion()) { - c->Message(0, "ERROR: Object %u is not in this instance version", id); - return; - } - - switch (od.object_type) { - case 0: - c->Message(0, "ERROR: Object %u is not yet unlocked for editing. Use '#object Edit' then zone out and back in to move it.", id); - return; - - case staticType: - c->Message(0, "ERROR: Object %u has been unlocked for editing, but you must zone out and back in before your client sees the change and will allow you to move it.", id); - return; - - case 1: - c->Message(0, "ERROR: Object %u is a temporary spawned object and cannot be manipulated with #object. See the 'ground_spawns' table in the database.", id); - return; - - default: - c->Message(0, "ERROR: Object %u not located in zone.", id); - return; - } - } - - // Move To Me - if ((sep->arg[3][0] & 0xDF) == 'T') { - od.x = c->GetX(); - od.y = c->GetY(); - od.z = c->GetZ() - (c->GetSize() * 0.625f); // Compensate for #loc bumping up Z coordinate by 62.5% of character's size. - - o->SetHeading(c->GetHeading() * 2.0f); // Compensate for GetHeading() returning half of actual - - // Bump player back to avoid getting stuck inside object - - // GetHeading() returns half of the actual heading, for some reason - x2 = 10.0f * sin(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); - y2 = 10.0f * cos(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); - c->MovePC(c->GetX() - x2, c->GetY() - y2, c->GetZ(), c->GetHeading() * 2.0f); - } // Move to x, y, z [h] - else { - od.x = atof(sep->arg[3]); - if (sep->argnum > 3) - od.y = atof(sep->arg[4]); - else - o->GetLocation(nullptr, &od.y, nullptr); - - if (sep->argnum > 4) - od.z = atof(sep->arg[5]); - else - o->GetLocation(nullptr, nullptr, &od.z); - - if (sep->argnum > 5) - o->SetHeading(atof(sep->arg[6])); - } - - o->SetLocation(od.x, od.y, od.z); - - // Despawn and respawn object to reflect change - app = new EQApplicationPacket(); - o->CreateDeSpawnPacket(app); - entity_list.QueueClients(0, app); - safe_delete(app); - - app = new EQApplicationPacket(); - o->CreateSpawnPacket(app); - entity_list.QueueClients(0, app); - safe_delete(app); - return; - } - - if (strcasecmp(sep->arg[1], "rotate") == 0) { - // Insufficient or invalid arguments - if ((sep->argnum < 3) || ((id = atoi(sep->arg[2])) == 0)) { - c->Message(0, "Usage: #object Rotate (ObjectID) (Heading, 0-512)"); - return; - } - - if ((o = entity_list.FindObject(id)) == nullptr) { - c->Message(0, "ERROR: Object %u not found in zone, or is a static object not yet unlocked with '#object Edit' for editing.", id); - return; - } - - o->SetHeading(atof(sep->arg[3])); - - // Despawn and respawn object to reflect change - app = new EQApplicationPacket(); - o->CreateDeSpawnPacket(app); - entity_list.QueueClients(0, app); - safe_delete(app); - - app = new EQApplicationPacket(); - o->CreateSpawnPacket(app); - entity_list.QueueClients(0, app); - safe_delete(app); - return; - } - - if (strcasecmp(sep->arg[1], "save") == 0) { - // Insufficient or invalid arguments - if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) == 0)) { - c->Message(0, "Usage: #object Save (ObjectID)"); - return; - } - - o = entity_list.FindObject(id); - - od.zone_id = 0; - od.zone_instance = 0; - od.object_type = 0; - - // If this ID isn't in the database yet, it's a new object - bNewObject = true; - std::string query = StringFormat("SELECT zoneid, version, type FROM object WHERE id = %u", id); - auto results = database.QueryDatabase(query); - if (results.Success() && results.RowCount() != 0) { - auto row = results.begin(); - od.zone_id = atoi(row[0]); - od.zone_instance = atoi(row[1]); - od.object_type = atoi(row[2]); - - // ID already in database. Not a new object. - bNewObject = false; - } - - if (!o) { - // Object not found in zone. Can't save an object we can't see. - - if (bNewObject) { - c->Message(0, "ERROR: Object %u not found", id); - return; - } - - if (od.zone_id != zone->GetZoneID()) { - c->Message(0, "ERROR: Wrong Object ID. %u is not part of this zone.", id); - return; - } - - if (od.zone_instance != zone->GetInstanceVersion()) { - c->Message(0, "ERROR: Wrong Object ID. %u is not part of this instance version.", id); - return; - } - - if (od.object_type == 0) { - c->Message(0, "ERROR: Static Object %u has already been committed. Use '#object Edit %u' and zone out and back in to make changes.", id, id); - return; - } - - if (od.object_type == 1) { - c->Message(0, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, which is not supported with #object. See the 'ground_spawns' table in the database.", id); - return; - } - - c->Message(0, "ERROR: Object %u not found.", id); - return; - } - - // Oops! Another GM already saved an object with our id from another zone. - // We'll have to get a new one. - if ((od.zone_id > 0) && (od.zone_id != zone->GetZoneID())) - id = 0; - - // Oops! Another GM already saved an object with our id from another instance. - // We'll have to get a new one. - if ((id > 0) && (od.zone_instance != zone->GetInstanceVersion())) - id = 0; - - // If we're asking for a new ID, it's a new object. - bNewObject |= (id == 0); - - o->GetObjectData(&od); - od.object_type = o->GetType(); - icon = o->GetIcon(); - - // We're committing to the database now. Return temporary object type to actual. - if (od.object_type == staticType) - od.object_type = 0; - - if (!bNewObject) - query = StringFormat("UPDATE object SET zoneid = %u, version = %u, " - "xpos = %.1f, ypos=%.1f, zpos=%.1f, heading=%.1f, " - "objectname = '%s', type = %u, icon = %u, " - "unknown08 = %u, unknown10 = %u, unknown20 = %u " - "WHERE ID = %u", - zone->GetZoneID(), zone->GetInstanceVersion(), - od.x, od.y, od.z, od.heading, - od.object_name, od.object_type, icon, - od.unknown008, od.unknown010, od.unknown020, id); - else if (id == 0) - query = StringFormat("INSERT INTO object " - "(zoneid, version, xpos, ypos, zpos, heading, objectname, " - "type, icon, unknown08, unknown10, unknown20) " - "VALUES (%u, %u, %.1f, %.1f, %.1f, %.1f, '%s', %u, %u, %u, %u, %u)", - zone->GetZoneID(), zone->GetInstanceVersion(), - od.x, od.y, od.z, od.heading, - od.object_name, od.object_type, icon, - od.unknown008, od.unknown010, od.unknown020); - else - query = StringFormat("INSERT INTO object " - "(id, zoneid, version, xpos, ypos, zpos, heading, objectname, " - "type, icon, unknown08, unknown10, unknown20) " - "VALUES (%u, %u, %u, %.1f, %.1f, %.1f, %.1f, '%s', %u, %u, %u, %u, %u)", - id, zone->GetZoneID(), zone->GetInstanceVersion(), - od.x, od.y, od.z, od.heading, - od.object_name, od.object_type, icon, - od.unknown008, od.unknown010, od.unknown020); - - results = database.QueryDatabase(query); - if (!results.Success()) { - c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); - return; - } - - if (results.RowsAffected() == 0) { - // No change made, but no error message given - c->Message(0, "Database Error: Could not save change to Object %u", id); - return; - } - - if (bNewObject) { - if (newid == results.LastInsertedID()) { - c->Message(0, "Saved new Object %u to database", id); - return; - } - - c->Message(0, "Saved Object. NOTE: Database returned a new ID number for object: %u", newid); - id = newid; - return; - } - - c->Message(0, "Saved changes to Object %u", id); - newid = id; - - if (od.object_type == 0) { - // Static Object - Respawn as nonfunctional door - - app = new EQApplicationPacket(); - o->CreateDeSpawnPacket(app); - entity_list.QueueClients(0, app); - safe_delete(app); - - entity_list.RemoveObject(o->GetID()); - - memset(&door, 0, sizeof(door)); - - strn0cpy(door.zone_name, zone->GetShortName(), sizeof(door.zone_name)); - - door.db_id = 1000000000 + id; // Out of range of normal use for doors.id - door.door_id = -1; // Client doesn't care if these are all the same door_id - door.pos_x = od.x; // xpos - door.pos_y = od.y; // ypos - door.pos_z = od.z; // zpos - door.heading = od.heading; // heading - - strn0cpy(door.door_name, od.object_name, sizeof(door.door_name)); // objectname - - // Strip trailing "_ACTORDEF" if present. Client won't accept it for doors. - uint32 len = strlen(door.door_name); - if ((len > 9) && (memcmp(&door.door_name[len - 9], "_ACTORDEF", 10) == 0)) - door.door_name[len - 9] = '\0'; - - memcpy(door.dest_zone, "NONE", 5); - - if ((door.size = od.unknown008) == 0) // unknown08 = optional size percentage - door.size = 100; - - switch (door.opentype = od.unknown010) // unknown10 = optional request_nonsolid (0 or 1 or experimental number) - { - case 0: - door.opentype = 31; - break; - - case 1: - door.opentype = 9; - break; - - } - - door.incline = od.unknown020; // unknown20 = optional incline value - door.client_version_mask = 0xFFFFFFFF; - - doors = new Doors(&door); - entity_list.AddDoor(doors); - - app = new EQApplicationPacket(OP_SpawnDoor, sizeof(Door_Struct)); - ds = (Door_Struct*)app->pBuffer; - - memset(ds, 0, sizeof(Door_Struct)); - memcpy(ds->name, door.door_name, 32); - ds->xPos = door.pos_x; - ds->yPos = door.pos_y; - ds->zPos = door.pos_z; - ds->heading = door.heading; - ds->incline = door.incline; - ds->size = door.size; - ds->doorId = door.door_id; - ds->opentype = door.opentype; - ds->unknown0052[9] = 1; // *ptr-1 and *ptr-3 from EntityList::MakeDoorSpawnPacket() - ds->unknown0052[11] = 1; - - entity_list.QueueClients(0, app); - safe_delete(app); - - c->Message(0, "NOTE: Object %u is now a static object, and is unchangeable. To make future changes, use '#object Edit' to convert it to a changeable form, then zone out and back in.", id); - } - return; - } - - if (strcasecmp(sep->arg[1], "copy") == 0) { - // Insufficient or invalid arguments - if ((sep->argnum < 3) || (((sep->arg[2][0] & 0xDF) != 'A') && ((sep->arg[2][0] < '0') || (sep->arg[2][0] > '9')))) { - c->Message(0, "Usage: #object Copy All|(ObjectID) (InstanceVersion)"); - c->Message(0, "- Note: Only objects saved in the database can be copied to another instance."); - return; - } - - od.zone_instance = atoi(sep->arg[3]); - - if (od.zone_instance == zone->GetInstanceVersion()) { - c->Message(0, "ERROR: Source and destination instance versions are the same."); - return; - } - - if ((sep->arg[2][0] & 0xDF) == 'A') { - // Copy All - - std::string query = StringFormat("INSERT INTO object " - "(zoneid, version, xpos, ypos, zpos, heading, itemid, " - "objectname, type, icon, unknown08, unknown10, unknown20) " - "SELECT zoneid, %u, xpos, ypos, zpos, heading, itemid, " - "objectname, type, icon, unknown08, unknown10, unknown20 " - "FROM object WHERE zoneid = %u) AND version = %u", - od.zone_instance, zone->GetZoneID(), zone->GetInstanceVersion()); - auto results = database.QueryDatabase(query); - if (!results.Success()) { - c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); - return; - } - - c->Message(0, "Copied %u object%s into instance version %u", results.RowCount(), (results.RowCount() == 1) ? "" : "s", od.zone_instance); - return; - } - - id = atoi(sep->arg[2]); - - std::string query = StringFormat("INSERT INTO object " - "(zoneid, version, xpos, ypos, zpos, heading, itemid, " - "objectname, type, icon, unknown08, unknown10, unknown20) " - "SELECT zoneid, %u, xpos, ypos, zpos, heading, itemid, " - "objectname, type, icon, unknown08, unknown10, unknown20 " - "FROM object WHERE id = %u AND zoneid = %u AND version = %u", - od.zone_instance, id, zone->GetZoneID(), zone->GetInstanceVersion()); - auto results = database.QueryDatabase(query); - if (results.Success() && results.RowsAffected() > 0) { - c->Message(0, "Copied Object %u into instance version %u", id, od.zone_instance); - return; - } - - // Couldn't copy the object. - - // got an error message - if (!results.Success()) { - c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); - return; - } - - // No database error returned. See if we can figure out why. - - query = StringFormat("SELECT zoneid, version FROM object WHERE id = %u", id); - results = database.QueryDatabase(query); - if (!results.Success()) - return; - - if (results.RowCount() == 0) { - c->Message(0, "ERROR: Object %u not found", id); - return; - } - - auto row = results.begin(); - // Wrong ZoneID? - if (atoi(row[0]) != zone->GetZoneID()) { - c->Message(0, "ERROR: Object %u is not part of this zone.", id); - return; - } - - // Wrong Instance Version? - if (atoi(row[1]) != zone->GetInstanceVersion()) { - c->Message(0, "ERROR: Object %u is not part of this instance version.", id); - return; - } - - // Well, NO clue at this point. Just let 'em know something screwed up. - c->Message(0, "ERROR: Unknown database error copying Object %u to instance version %u", id, od.zone_instance); - return; - } - - if (strcasecmp(sep->arg[1], "delete") == 0) { - - if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) <= 0)) { - c->Message(0, "Usage: #object Delete (ObjectID) -- NOTE: Object deletions are permanent and cannot be undone!"); - return; - } - - o = entity_list.FindObject(id); - - if (o) { - // Object found in zone. - - app = new EQApplicationPacket(); - o->CreateDeSpawnPacket(app); - entity_list.QueueClients(nullptr, app); - - entity_list.RemoveObject(o->GetID()); - - // Verifying ZoneID and Version in case someone else ended up adding an object with our ID - // from a different zone/version. Don't want to delete someone else's work. - std::string query = StringFormat("DELETE FROM object " - "WHERE id = %u AND zoneid = %u " - "AND version = %u LIMIT 1", - id, zone->GetZoneID(), zone->GetInstanceVersion()); - auto results = database.QueryDatabase(query); - - c->Message(0, "Object %u deleted", id); - return; - } - - - // Object not found in zone. - std::string query = StringFormat("SELECT type FROM object " - "WHERE id = %u AND zoneid = %u " - "AND version = %u LIMIT 1", - id, zone->GetZoneID(), zone->GetInstanceVersion()); - auto results = database.QueryDatabase(query); - if (!results.Success()) - return; - - if (results.RowCount() == 0) { - c->Message(0, "ERROR: Object %u not found in this zone or instance!", id); - return; - } - - auto row = results.begin(); - - switch (atoi(row[0])) { - case 0: // Static Object - query = StringFormat("DELETE FROM object WHERE id = %u " - "AND zoneid = %u AND version = %u LIMIT 1", - id, zone->GetZoneID(), zone->GetInstanceVersion()); - results = database.QueryDatabase(query); - - c->Message(0, "Object %u deleted. NOTE: This static object will remain for anyone currently in the zone until they next zone out and in.", id); - return; - - case 1: // Temporary Spawn - c->Message(0, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, which is not supported with #object. See the 'ground_spawns' table in the database.", id); - return; - - } - - return; - } - - if (strcasecmp(sep->arg[1], "undo") == 0) { - // Insufficient or invalid arguments - if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) == 0)) { - c->Message(0, "Usage: #object Undo (ObjectID) -- Reload object from database, undoing any changes you have made"); - return; - } - - o = entity_list.FindObject(id); - - if (!o) { - c->Message(0, "ERROR: Object %u not found in zone in a manipulable form. No changes to undo.", id); - return; - } - - if (o->GetType() == OT_DROPPEDITEM) { - c->Message(0, "ERROR: Object %u is a temporary spawned item and cannot be manipulated with #object. See the 'ground_spawns' table in the database.", id); - return; - } - - // Despawn current item for reloading from database - app = new EQApplicationPacket(); - o->CreateDeSpawnPacket(app); - entity_list.QueueClients(0, app); - entity_list.RemoveObject(o->GetID()); - safe_delete(app); - - std::string query = StringFormat("SELECT xpos, ypos, zpos, " - "heading, objectname, type, icon, " - "unknown08, unknown10, unknown20 " - "FROM object WHERE id = %u", id); - auto results = database.QueryDatabase(query); - if (!results.Success() || results.RowCount() == 0) { - c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); - return; - } - - memset(&od, 0, sizeof(od)); - - auto row = results.begin(); - - od.x = atof(row[0]); - od.y = atof(row[1]); - od.z = atof(row[2]); - od.heading = atof(row[3]); - strn0cpy(od.object_name, row[4], sizeof(od.object_name)); - od.object_type = atoi(row[5]); - icon = atoi(row[6]); - od.unknown008 = atoi(row[7]); - od.unknown010 = atoi(row[8]); - od.unknown020 = atoi(row[9]); - - if (od.object_type == 0) - od.object_type = staticType; - - o = new Object(id, od.object_type, icon, od, nullptr); - entity_list.AddObject(o, true); - - c->Message(0, "Object %u reloaded from database.", id); - return; - } - - c->Message(0, usage_string); + c->Message(0, "Usage: #object Edit (ObjectID) [PropertyName] [NewValue]"); + c->Message(0, "- Static Object (Type 0) Properties: model, type, size, solidtype, incline"); + c->Message(0, "- Tradeskill Object (Type 2+) Properties: model, type, icon"); + + return; + } + + o = entity_list.FindObject(id); + + // Object already available in-zone? + if (o) { + // Yep, looks like we can make real-time changes. + if (sep->argnum < 4) { + // Or not. '#object Edit (ObjectID)' called without PropertyName and NewValue + c->Message(0, "Note: Object %u already unlocked and ready for changes", id); + return; + } + } else { + // Object not found in-zone in a modifiable form. Check for valid matching circumstances. + std::string query = StringFormat("SELECT zoneid, version, type FROM object WHERE id = %u", id); + auto results = database.QueryDatabase(query); + if (!results.Success() || results.RowCount() == 0) { + c->Message(0, "ERROR: Object %u not found", id); + return; + } + + auto row = results.begin(); + od.zone_id = atoi(row[0]); + od.zone_instance = atoi(row[1]); + od.object_type = atoi(row[2]); + uint32 objectsFound = 1; + + // Object not in this zone? + if (od.zone_id != zone->GetZoneID()) { + c->Message(0, "ERROR: Object %u not in this zone.", id); + return; + } + + // Object not in this instance? + if (od.zone_instance != zone->GetInstanceVersion()) { + c->Message(0, "ERROR: Object %u not part of this instance version.", id); + return; + } + + switch (od.object_type) { + case 0: // Static object needing unlocking + // Convert to tradeskill object temporarily for changes + query = StringFormat("UPDATE object SET type = %u WHERE id = %u", staticType, id); + + database.QueryDatabase(query); + + c->Message(0, "Static Object %u unlocked for editing. You must zone out and back in to " + "make your changes, then commit them with '#object Save'.", + id); + if (sep->argnum >= 4) + c->Message(0, "NOTE: The change you specified has not been applied, since the " + "static object had not been unlocked for editing yet."); + return; + + case OT_DROPPEDITEM: + c->Message(0, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, " + "which cannot be manipulated with #object. See the 'ground_spawns' table " + "in the database.", + id); + return; + + case staticType: + c->Message(0, "ERROR: Object %u has been unlocked for editing, but you must zone out " + "and back in for your client to refresh its object table before you can " + "make changes to it.", + id); + return; + + default: + // Unknown error preventing us from seeing the object in the zone. + c->Message(0, "ERROR: Unknown problem attempting to manipulate object %u", id); + return; + } + } + + // If we're here, we have a manipulable object ready for changes. + strlwr(sep->arg[3]); // Case insensitive PropertyName + strupr(sep->arg[4]); // In case it's model name, which should always be upper-case + + // Read current object info for reference + icon = o->GetIcon(); + o->GetObjectData(&od); + + // We'll be a little more picky with property names, to prevent errors. Check against the whole word. + if (strcmp(sep->arg[3], "model") == 0) { + + if ((sep->arg[4][0] < 'A') || (sep->arg[4][0] > 'Z')) { + c->Message(0, "ERROR: Model names must begin with a letter."); + return; + } + + strn0cpy(od.object_name, sep->arg[4], sizeof(od.object_name)); + + o->SetObjectData(&od); + + c->Message(0, "Object %u now being rendered with model '%s'", id, od.object_name); + } else if (strcmp(sep->arg[3], "type") == 0) { + if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { + c->Message(0, "ERROR: Invalid type number"); + return; + } + + od.object_type = atoi(sep->arg[4]); + + switch (od.object_type) { + case 0: + // Convert Static Object to temporary changeable type + od.object_type = staticType; + c->Message(0, "Note: Static Object will still act like tradeskill object and will not " + "reflect size, solidtype, or incline settings until committed to the " + "database with '#object Save', after which it will be unchangeable until " + "it is unlocked again with '#object Edit'."); + break; + + case OT_DROPPEDITEM: + c->Message(0, "ERROR: Object Type 1 is used for temporarily spawned ground spawns and " + "dropped items, which are not supported with #object. See the " + "'ground_spawns' table in the database."); + return; + + default: + c->Message(0, "Object %u changed to Tradeskill Object Type %u", id, od.object_type); + break; + } + + o->SetType(od.object_type); + } else if (strcmp(sep->arg[3], "size") == 0) { + if (od.object_type != staticType) { + c->Message( + 0, "ERROR: Object %u is not a Static Object and does not support the Size property", + id); + return; + } + + if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { + c->Message(0, "ERROR: Invalid size specified. Please enter a number."); + return; + } + + od.unknown008 = atoi(sep->arg[4]); + o->SetObjectData(&od); + + if (od.unknown008 == 0) // 0 == unspecified == 100% + od.unknown008 = 100; + + c->Message(0, "Static Object %u set to %u%% size. Size will take effect when you commit to the " + "database with '#object Save', after which the object will be unchangeable until " + "you unlock it again with '#object Edit' and zone out and back in.", + id, od.unknown008); + } else if (strcmp(sep->arg[3], "solidtype") == 0) { + + if (od.object_type != staticType) { + c->Message(0, "ERROR: Object %u is not a Static Object and does not support the " + "SolidType property", + id); + return; + } + + if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { + c->Message(0, "ERROR: Invalid solidtype specified. Please enter a number."); + return; + } + + od.unknown010 = atoi(sep->arg[4]); + o->SetObjectData(&od); + + c->Message(0, "Static Object %u set to SolidType %u. Change will take effect when you commit " + "to the database with '#object Save'. Support for this property is on a " + "per-model basis, mostly seen in smaller objects such as chests and tables.", + id, od.unknown010); + } else if (strcmp(sep->arg[3], "icon") == 0) { + + if ((od.object_type < 2) || (od.object_type == staticType)) { + c->Message(0, "ERROR: Object %u is not a Tradeskill Object and does not support the " + "Icon property", + id); + return; + } + + if ((icon = atoi(sep->arg[4])) == 0) { + c->Message(0, "ERROR: Invalid Icon specified. Please enter an icon number."); + return; + } + + o->SetIcon(icon); + c->Message(0, "Tradeskill Object %u icon set to %u", id, icon); + } else if (strcmp(sep->arg[3], "incline") == 0) { + if (od.object_type != staticType) { + c->Message( + 0, + "ERROR: Object %u is not a Static Object and does not support the Incline property", + id); + return; + } + + if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { + c->Message( + 0, + "ERROR: Invalid Incline specified. Please enter a number. Normal range is 0-512."); + return; + } + + od.unknown020 = atoi(sep->arg[4]); + o->SetObjectData(&od); + + c->Message(0, "Static Object %u set to %u incline. Incline will take effect when you commit to " + "the database with '#object Save', after which the object will be unchangeable " + "until you unlock it again with '#object Edit' and zone out and back in.", + id, od.unknown020); + } else { + c->Message(0, "ERROR: Unrecognized property name: %s", sep->arg[3]); + return; + } + + // Repop object to have it reflect the change. + app = new EQApplicationPacket(); + o->CreateDeSpawnPacket(app); + entity_list.QueueClients(0, app); + safe_delete(app); + + app = new EQApplicationPacket(); + o->CreateSpawnPacket(app); + entity_list.QueueClients(0, app); + safe_delete(app); + return; + } + + if (strcasecmp(sep->arg[1], "move") == 0) { + + if ((sep->argnum < 2) || // Not enough arguments + ((id = atoi(sep->arg[2])) == 0) || // ID not specified + (((sep->arg[3][0] < '0') || (sep->arg[3][0] > '9')) && ((sep->arg[3][0] & 0xDF) != 'T') && + (sep->arg[3][0] != '-') && (sep->arg[3][0] != '.'))) { // Location argument not specified correctly + c->Message(0, "Usage: #object Move (ObjectID) ToMe|(x y z [h])"); + return; + } + + if (!(o = entity_list.FindObject(id))) { + std::string query = StringFormat("SELECT zoneid, version, type FROM object WHERE id = %u", id); + auto results = database.QueryDatabase(query); + if (!results.Success() || results.RowCount() == 0) { + c->Message(0, "ERROR: Object %u not found", id); + return; + } + + auto row = results.begin(); + od.zone_id = atoi(row[0]); + od.zone_instance = atoi(row[1]); + od.object_type = atoi(row[2]); + + if (od.zone_id != zone->GetZoneID()) { + c->Message(0, "ERROR: Object %u is not in this zone", id); + return; + } + + if (od.zone_instance != zone->GetInstanceVersion()) { + c->Message(0, "ERROR: Object %u is not in this instance version", id); + return; + } + + switch (od.object_type) { + case 0: + c->Message(0, "ERROR: Object %u is not yet unlocked for editing. Use '#object Edit' " + "then zone out and back in to move it.", + id); + return; + + case staticType: + c->Message(0, "ERROR: Object %u has been unlocked for editing, but you must zone out " + "and back in before your client sees the change and will allow you to " + "move it.", + id); + return; + + case 1: + c->Message(0, "ERROR: Object %u is a temporary spawned object and cannot be " + "manipulated with #object. See the 'ground_spawns' table in the " + "database.", + id); + return; + + default: + c->Message(0, "ERROR: Object %u not located in zone.", id); + return; + } + } + + // Move To Me + if ((sep->arg[3][0] & 0xDF) == 'T') { + od.x = c->GetX(); + od.y = c->GetY(); + od.z = c->GetZ() - + (c->GetSize() * + 0.625f); // Compensate for #loc bumping up Z coordinate by 62.5% of character's size. + + o->SetHeading(c->GetHeading() * 2.0f); // Compensate for GetHeading() returning half of actual + + // Bump player back to avoid getting stuck inside object + + // GetHeading() returns half of the actual heading, for some reason + x2 = 10.0f * sin(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); + y2 = 10.0f * cos(c->GetHeading() * 2.0f / 256.0f * 3.14159265f); + c->MovePC(c->GetX() - x2, c->GetY() - y2, c->GetZ(), c->GetHeading() * 2.0f); + } // Move to x, y, z [h] + else { + od.x = atof(sep->arg[3]); + if (sep->argnum > 3) + od.y = atof(sep->arg[4]); + else + o->GetLocation(nullptr, &od.y, nullptr); + + if (sep->argnum > 4) + od.z = atof(sep->arg[5]); + else + o->GetLocation(nullptr, nullptr, &od.z); + + if (sep->argnum > 5) + o->SetHeading(atof(sep->arg[6])); + } + + o->SetLocation(od.x, od.y, od.z); + + // Despawn and respawn object to reflect change + app = new EQApplicationPacket(); + o->CreateDeSpawnPacket(app); + entity_list.QueueClients(0, app); + safe_delete(app); + + app = new EQApplicationPacket(); + o->CreateSpawnPacket(app); + entity_list.QueueClients(0, app); + safe_delete(app); + return; + } + + if (strcasecmp(sep->arg[1], "rotate") == 0) { + // Insufficient or invalid arguments + if ((sep->argnum < 3) || ((id = atoi(sep->arg[2])) == 0)) { + c->Message(0, "Usage: #object Rotate (ObjectID) (Heading, 0-512)"); + return; + } + + if ((o = entity_list.FindObject(id)) == nullptr) { + c->Message(0, "ERROR: Object %u not found in zone, or is a static object not yet unlocked with " + "'#object Edit' for editing.", + id); + return; + } + + o->SetHeading(atof(sep->arg[3])); + + // Despawn and respawn object to reflect change + app = new EQApplicationPacket(); + o->CreateDeSpawnPacket(app); + entity_list.QueueClients(0, app); + safe_delete(app); + + app = new EQApplicationPacket(); + o->CreateSpawnPacket(app); + entity_list.QueueClients(0, app); + safe_delete(app); + return; + } + + if (strcasecmp(sep->arg[1], "save") == 0) { + // Insufficient or invalid arguments + if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) == 0)) { + c->Message(0, "Usage: #object Save (ObjectID)"); + return; + } + + o = entity_list.FindObject(id); + + od.zone_id = 0; + od.zone_instance = 0; + od.object_type = 0; + + // If this ID isn't in the database yet, it's a new object + bNewObject = true; + std::string query = StringFormat("SELECT zoneid, version, type FROM object WHERE id = %u", id); + auto results = database.QueryDatabase(query); + if (results.Success() && results.RowCount() != 0) { + auto row = results.begin(); + od.zone_id = atoi(row[0]); + od.zone_instance = atoi(row[1]); + od.object_type = atoi(row[2]); + + // ID already in database. Not a new object. + bNewObject = false; + } + + if (!o) { + // Object not found in zone. Can't save an object we can't see. + + if (bNewObject) { + c->Message(0, "ERROR: Object %u not found", id); + return; + } + + if (od.zone_id != zone->GetZoneID()) { + c->Message(0, "ERROR: Wrong Object ID. %u is not part of this zone.", id); + return; + } + + if (od.zone_instance != zone->GetInstanceVersion()) { + c->Message(0, "ERROR: Wrong Object ID. %u is not part of this instance version.", id); + return; + } + + if (od.object_type == 0) { + c->Message(0, "ERROR: Static Object %u has already been committed. Use '#object Edit " + "%u' and zone out and back in to make changes.", + id, id); + return; + } + + if (od.object_type == 1) { + c->Message(0, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, " + "which is not supported with #object. See the 'ground_spawns' table in " + "the database.", + id); + return; + } + + c->Message(0, "ERROR: Object %u not found.", id); + return; + } + + // Oops! Another GM already saved an object with our id from another zone. + // We'll have to get a new one. + if ((od.zone_id > 0) && (od.zone_id != zone->GetZoneID())) + id = 0; + + // Oops! Another GM already saved an object with our id from another instance. + // We'll have to get a new one. + if ((id > 0) && (od.zone_instance != zone->GetInstanceVersion())) + id = 0; + + // If we're asking for a new ID, it's a new object. + bNewObject |= (id == 0); + + o->GetObjectData(&od); + od.object_type = o->GetType(); + icon = o->GetIcon(); + + // We're committing to the database now. Return temporary object type to actual. + if (od.object_type == staticType) + od.object_type = 0; + + if (!bNewObject) + query = StringFormat("UPDATE object SET zoneid = %u, version = %u, " + "xpos = %.1f, ypos=%.1f, zpos=%.1f, heading=%.1f, " + "objectname = '%s', type = %u, icon = %u, " + "unknown08 = %u, unknown10 = %u, unknown20 = %u " + "WHERE ID = %u", + zone->GetZoneID(), zone->GetInstanceVersion(), od.x, od.y, od.z, + od.heading, od.object_name, od.object_type, icon, od.unknown008, + od.unknown010, od.unknown020, id); + else if (id == 0) + query = StringFormat("INSERT INTO object " + "(zoneid, version, xpos, ypos, zpos, heading, objectname, " + "type, icon, unknown08, unknown10, unknown20) " + "VALUES (%u, %u, %.1f, %.1f, %.1f, %.1f, '%s', %u, %u, %u, %u, %u)", + zone->GetZoneID(), zone->GetInstanceVersion(), od.x, od.y, od.z, + od.heading, od.object_name, od.object_type, icon, od.unknown008, + od.unknown010, od.unknown020); + else + query = StringFormat("INSERT INTO object " + "(id, zoneid, version, xpos, ypos, zpos, heading, objectname, " + "type, icon, unknown08, unknown10, unknown20) " + "VALUES (%u, %u, %u, %.1f, %.1f, %.1f, %.1f, '%s', %u, %u, %u, %u, %u)", + id, zone->GetZoneID(), zone->GetInstanceVersion(), od.x, od.y, od.z, + od.heading, od.object_name, od.object_type, icon, od.unknown008, + od.unknown010, od.unknown020); + + results = database.QueryDatabase(query); + if (!results.Success()) { + c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); + return; + } + + if (results.RowsAffected() == 0) { + // No change made, but no error message given + c->Message(0, "Database Error: Could not save change to Object %u", id); + return; + } + + if (bNewObject) { + if (newid == results.LastInsertedID()) { + c->Message(0, "Saved new Object %u to database", id); + return; + } + + c->Message(0, "Saved Object. NOTE: Database returned a new ID number for object: %u", newid); + id = newid; + return; + } + + c->Message(0, "Saved changes to Object %u", id); + newid = id; + + if (od.object_type == 0) { + // Static Object - Respawn as nonfunctional door + + app = new EQApplicationPacket(); + o->CreateDeSpawnPacket(app); + entity_list.QueueClients(0, app); + safe_delete(app); + + entity_list.RemoveObject(o->GetID()); + + memset(&door, 0, sizeof(door)); + + strn0cpy(door.zone_name, zone->GetShortName(), sizeof(door.zone_name)); + + door.db_id = 1000000000 + id; // Out of range of normal use for doors.id + door.door_id = -1; // Client doesn't care if these are all the same door_id + door.pos_x = od.x; // xpos + door.pos_y = od.y; // ypos + door.pos_z = od.z; // zpos + door.heading = od.heading; // heading + + strn0cpy(door.door_name, od.object_name, sizeof(door.door_name)); // objectname + + // Strip trailing "_ACTORDEF" if present. Client won't accept it for doors. + uint32 len = strlen(door.door_name); + if ((len > 9) && (memcmp(&door.door_name[len - 9], "_ACTORDEF", 10) == 0)) + door.door_name[len - 9] = '\0'; + + memcpy(door.dest_zone, "NONE", 5); + + if ((door.size = od.unknown008) == 0) // unknown08 = optional size percentage + door.size = 100; + + switch ( + door.opentype = + od.unknown010) // unknown10 = optional request_nonsolid (0 or 1 or experimental number) + { + case 0: + door.opentype = 31; + break; + + case 1: + door.opentype = 9; + break; + } + + door.incline = od.unknown020; // unknown20 = optional incline value + door.client_version_mask = 0xFFFFFFFF; + + doors = new Doors(&door); + entity_list.AddDoor(doors); + + app = new EQApplicationPacket(OP_SpawnDoor, sizeof(Door_Struct)); + ds = (Door_Struct *)app->pBuffer; + + memset(ds, 0, sizeof(Door_Struct)); + memcpy(ds->name, door.door_name, 32); + ds->xPos = door.pos_x; + ds->yPos = door.pos_y; + ds->zPos = door.pos_z; + ds->heading = door.heading; + ds->incline = door.incline; + ds->size = door.size; + ds->doorId = door.door_id; + ds->opentype = door.opentype; + ds->unknown0052[9] = 1; // *ptr-1 and *ptr-3 from EntityList::MakeDoorSpawnPacket() + ds->unknown0052[11] = 1; + + entity_list.QueueClients(0, app); + safe_delete(app); + + c->Message(0, "NOTE: Object %u is now a static object, and is unchangeable. To make future " + "changes, use '#object Edit' to convert it to a changeable form, then zone out " + "and back in.", + id); + } + return; + } + + if (strcasecmp(sep->arg[1], "copy") == 0) { + // Insufficient or invalid arguments + if ((sep->argnum < 3) || + (((sep->arg[2][0] & 0xDF) != 'A') && ((sep->arg[2][0] < '0') || (sep->arg[2][0] > '9')))) { + c->Message(0, "Usage: #object Copy All|(ObjectID) (InstanceVersion)"); + c->Message(0, "- Note: Only objects saved in the database can be copied to another instance."); + return; + } + + od.zone_instance = atoi(sep->arg[3]); + + if (od.zone_instance == zone->GetInstanceVersion()) { + c->Message(0, "ERROR: Source and destination instance versions are the same."); + return; + } + + if ((sep->arg[2][0] & 0xDF) == 'A') { + // Copy All + + std::string query = + StringFormat("INSERT INTO object " + "(zoneid, version, xpos, ypos, zpos, heading, itemid, " + "objectname, type, icon, unknown08, unknown10, unknown20) " + "SELECT zoneid, %u, xpos, ypos, zpos, heading, itemid, " + "objectname, type, icon, unknown08, unknown10, unknown20 " + "FROM object WHERE zoneid = %u) AND version = %u", + od.zone_instance, zone->GetZoneID(), zone->GetInstanceVersion()); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); + return; + } + + c->Message(0, "Copied %u object%s into instance version %u", results.RowCount(), + (results.RowCount() == 1) ? "" : "s", od.zone_instance); + return; + } + + id = atoi(sep->arg[2]); + + std::string query = StringFormat("INSERT INTO object " + "(zoneid, version, xpos, ypos, zpos, heading, itemid, " + "objectname, type, icon, unknown08, unknown10, unknown20) " + "SELECT zoneid, %u, xpos, ypos, zpos, heading, itemid, " + "objectname, type, icon, unknown08, unknown10, unknown20 " + "FROM object WHERE id = %u AND zoneid = %u AND version = %u", + od.zone_instance, id, zone->GetZoneID(), zone->GetInstanceVersion()); + auto results = database.QueryDatabase(query); + if (results.Success() && results.RowsAffected() > 0) { + c->Message(0, "Copied Object %u into instance version %u", id, od.zone_instance); + return; + } + + // Couldn't copy the object. + + // got an error message + if (!results.Success()) { + c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); + return; + } + + // No database error returned. See if we can figure out why. + + query = StringFormat("SELECT zoneid, version FROM object WHERE id = %u", id); + results = database.QueryDatabase(query); + if (!results.Success()) + return; + + if (results.RowCount() == 0) { + c->Message(0, "ERROR: Object %u not found", id); + return; + } + + auto row = results.begin(); + // Wrong ZoneID? + if (atoi(row[0]) != zone->GetZoneID()) { + c->Message(0, "ERROR: Object %u is not part of this zone.", id); + return; + } + + // Wrong Instance Version? + if (atoi(row[1]) != zone->GetInstanceVersion()) { + c->Message(0, "ERROR: Object %u is not part of this instance version.", id); + return; + } + + // Well, NO clue at this point. Just let 'em know something screwed up. + c->Message(0, "ERROR: Unknown database error copying Object %u to instance version %u", id, + od.zone_instance); + return; + } + + if (strcasecmp(sep->arg[1], "delete") == 0) { + + if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) <= 0)) { + c->Message(0, "Usage: #object Delete (ObjectID) -- NOTE: Object deletions are permanent and " + "cannot be undone!"); + return; + } + + o = entity_list.FindObject(id); + + if (o) { + // Object found in zone. + + app = new EQApplicationPacket(); + o->CreateDeSpawnPacket(app); + entity_list.QueueClients(nullptr, app); + + entity_list.RemoveObject(o->GetID()); + + // Verifying ZoneID and Version in case someone else ended up adding an object with our ID + // from a different zone/version. Don't want to delete someone else's work. + std::string query = StringFormat("DELETE FROM object " + "WHERE id = %u AND zoneid = %u " + "AND version = %u LIMIT 1", + id, zone->GetZoneID(), zone->GetInstanceVersion()); + auto results = database.QueryDatabase(query); + + c->Message(0, "Object %u deleted", id); + return; + } + + // Object not found in zone. + std::string query = StringFormat("SELECT type FROM object " + "WHERE id = %u AND zoneid = %u " + "AND version = %u LIMIT 1", + id, zone->GetZoneID(), zone->GetInstanceVersion()); + auto results = database.QueryDatabase(query); + if (!results.Success()) + return; + + if (results.RowCount() == 0) { + c->Message(0, "ERROR: Object %u not found in this zone or instance!", id); + return; + } + + auto row = results.begin(); + + switch (atoi(row[0])) { + case 0: // Static Object + query = StringFormat("DELETE FROM object WHERE id = %u " + "AND zoneid = %u AND version = %u LIMIT 1", + id, zone->GetZoneID(), zone->GetInstanceVersion()); + results = database.QueryDatabase(query); + + c->Message(0, "Object %u deleted. NOTE: This static object will remain for anyone currently in " + "the zone until they next zone out and in.", + id); + return; + + case 1: // Temporary Spawn + c->Message(0, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, which " + "is not supported with #object. See the 'ground_spawns' table in the database.", + id); + return; + } + + return; + } + + if (strcasecmp(sep->arg[1], "undo") == 0) { + // Insufficient or invalid arguments + if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) == 0)) { + c->Message(0, "Usage: #object Undo (ObjectID) -- Reload object from database, undoing any " + "changes you have made"); + return; + } + + o = entity_list.FindObject(id); + + if (!o) { + c->Message(0, "ERROR: Object %u not found in zone in a manipulable form. No changes to undo.", + id); + return; + } + + if (o->GetType() == OT_DROPPEDITEM) { + c->Message(0, "ERROR: Object %u is a temporary spawned item and cannot be manipulated with " + "#object. See the 'ground_spawns' table in the database.", + id); + return; + } + + // Despawn current item for reloading from database + app = new EQApplicationPacket(); + o->CreateDeSpawnPacket(app); + entity_list.QueueClients(0, app); + entity_list.RemoveObject(o->GetID()); + safe_delete(app); + + std::string query = StringFormat("SELECT xpos, ypos, zpos, " + "heading, objectname, type, icon, " + "unknown08, unknown10, unknown20 " + "FROM object WHERE id = %u", + id); + auto results = database.QueryDatabase(query); + if (!results.Success() || results.RowCount() == 0) { + c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); + return; + } + + memset(&od, 0, sizeof(od)); + + auto row = results.begin(); + + od.x = atof(row[0]); + od.y = atof(row[1]); + od.z = atof(row[2]); + od.heading = atof(row[3]); + strn0cpy(od.object_name, row[4], sizeof(od.object_name)); + od.object_type = atoi(row[5]); + icon = atoi(row[6]); + od.unknown008 = atoi(row[7]); + od.unknown010 = atoi(row[8]); + od.unknown020 = atoi(row[9]); + + if (od.object_type == 0) + od.object_type = staticType; + + o = new Object(id, od.object_type, icon, od, nullptr); + entity_list.AddObject(o, true); + + c->Message(0, "Object %u reloaded from database.", id); + return; + } + + c->Message(0, usage_string); } void command_showspellslist(Client *c, const Seperator *sep) @@ -10557,4 +10627,4 @@ void command_mysqltest(Client *c, const Seperator *sep) } } Log.Out(Logs::General, Logs::Debug, "MySQL Test... Took %f seconds", ((float)(std::clock() - t)) / CLOCKS_PER_SEC); -} \ No newline at end of file +} diff --git a/zone/common.h b/zone/common.h index 8ec520646..19237d99c 100644 --- a/zone/common.h +++ b/zone/common.h @@ -7,7 +7,7 @@ #define HIGHEST_RESIST 9 //Max resist type value #define MAX_SPELL_PROJECTILE 10 //Max amount of spell projectiles that can be active by a single mob. -/* solar: macros for IsAttackAllowed, IsBeneficialAllowed */ +/* macros for IsAttackAllowed, IsBeneficialAllowed */ #define _CLIENT(x) (x && x->IsClient() && !x->CastToClient()->IsBecomeNPC()) #define _NPC(x) (x && x->IsNPC() && !x->CastToMob()->GetOwnerID()) #define _BECOMENPC(x) (x && x->IsClient() && x->CastToClient()->IsBecomeNPC()) diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 57d4179ed..0dd4ed1f3 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -318,54 +318,30 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( // get their tints memcpy(item_tint, &client->GetPP().item_tint, sizeof(item_tint)); - // solar: TODO soulbound items need not be added to corpse, but they need + // TODO soulbound items need not be added to corpse, but they need // to go into the regular slots on the player, out of bags - - // possessions - // TODO: accomodate soul-bound items std::list removed_list; - //bool cursor = false; - for(i = MAIN_BEGIN; i < EmuConstants::MAP_POSSESSIONS_SIZE; i++) { + + for(i = MAIN_BEGIN; i < EmuConstants::MAP_POSSESSIONS_SIZE; ++i) { if(i == MainAmmo && client->GetClientVersion() >= ClientVersion::SoF) { item = client->GetInv().GetItem(MainPowerSource); - if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) { - std::list slot_list = MoveItemToCorpse(client, item, MainPowerSource); - removed_list.merge(slot_list); + if (item != nullptr) { + if (!client->IsBecomeNPC() || (client->IsBecomeNPC() && !item->GetItem()->NoRent)) + MoveItemToCorpse(client, item, MainPowerSource, removed_list); } - } item = client->GetInv().GetItem(i); - if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) { - std::list slot_list = MoveItemToCorpse(client, item, i); - removed_list.merge(slot_list); - } + if (item == nullptr) { continue; } + + if(!client->IsBecomeNPC() || (client->IsBecomeNPC() && !item->GetItem()->NoRent)) + MoveItemToCorpse(client, item, i, removed_list); } -#if 0 - // This will either be re-enabled or deleted at some point. The client doesn't appear - // to like to have items deleted from it's buffer..or, I just haven't figure out how -U - // (Besides, the 'corpse' slots equal the size of MapPossessions..not MapPossessions + MapCorpse) - - // cursor queue // (change to first client that supports 'death hover' mode, if not SoF.) - if (!RuleB(Character, RespawnFromHover) || client->GetClientVersion() < EQClientSoF) { - - // bumped starting assignment to 8001 because any in-memory 'slot 8000' item was moved above as 'slot 30' - // this was mainly for client profile state reflection..should match db player inventory entries now. - i = 8001; - for (auto it = client->GetInv().cursor_begin(); it != client->GetInv().cursor_end(); ++it, i++) { - item = *it; - if ((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) { - std::list slot_list = MoveItemToCorpse(client, item, i); - removed_list.merge(slot_list); - cursor = true; - } - } - } -#endif - database.TransactionBegin(); - if (removed_list.size() != 0) { + + // I have an untested process that avoids this snarl up when all possessions inventory is removed..but this isn't broke -U + if (!removed_list.empty()) { std::stringstream ss(""); ss << "DELETE FROM inventory WHERE charid=" << client->CharacterID(); ss << " AND ("; @@ -385,18 +361,6 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( database.QueryDatabase(ss.str().c_str()); } -#if 0 - if (cursor) { // all cursor items should be on corpse (client < SoF or RespawnFromHover = false) - while (!client->GetInv().CursorEmpty()) - client->DeleteItemInInventory(MainCursor, 0, false, false); - } - else { // only visible cursor made it to corpse (client >= Sof and RespawnFromHover = true) - std::list::const_iterator start = client->GetInv().cursor_begin(); - std::list::const_iterator finish = client->GetInv().cursor_end(); - database.SaveCursor(client->CharacterID(), start, finish); - } -#endif - auto start = client->GetInv().cursor_begin(); auto finish = client->GetInv().cursor_end(); database.SaveCursor(client->CharacterID(), start, finish); @@ -406,8 +370,13 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( IsRezzed(false); Save(); + database.TransactionCommit(); + UpdateEquipLightValue(); + spell_light = NOT_USED; + UpdateActiveLightValue(); + return; } //end "not leaving naked corpses" @@ -419,32 +388,49 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( Save(); } -std::list Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot) +void Corpse::MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, std::list &removedList) { - int bagindex; - int16 interior_slot; - ItemInst *interior_item; - std::list returnlist; + AddItem( + inst->GetItem()->ID, + inst->GetCharges(), + equipSlot, + inst->GetAugmentItemID(0), + inst->GetAugmentItemID(1), + inst->GetAugmentItemID(2), + inst->GetAugmentItemID(3), + inst->GetAugmentItemID(4), + inst->GetAugmentItemID(5), + inst->IsAttuned() + ); + removedList.push_back(equipSlot); - AddItem(item->GetItem()->ID, item->GetCharges(), equipslot, item->GetAugmentItemID(0), item->GetAugmentItemID(1), item->GetAugmentItemID(2), item->GetAugmentItemID(3), item->GetAugmentItemID(4), item->GetAugmentItemID(5), item->IsAttuned()); - returnlist.push_back(equipslot); + while (true) { + if (!inst->IsType(ItemClassContainer)) { break; } + if (equipSlot < EmuConstants::GENERAL_BEGIN || equipSlot > MainCursor) { break; } - // Qualified bag slot iterations. processing bag slots that don't exist is probably not a good idea. - if (item->IsType(ItemClassContainer) && ((equipslot >= EmuConstants::GENERAL_BEGIN && equipslot <= MainCursor))) { - for (bagindex = SUB_BEGIN; bagindex <= EmuConstants::ITEM_CONTAINER_SIZE; bagindex++) { - // For empty bags in cursor queue, slot was previously being resolved as SLOT_INVALID (-1) - interior_slot = Inventory::CalcSlotId(equipslot, bagindex); - interior_item = client->GetInv().GetItem(interior_slot); + for (auto sub_index = SUB_BEGIN; sub_index < EmuConstants::ITEM_CONTAINER_SIZE; ++sub_index) { + int16 real_bag_slot = Inventory::CalcSlotId(equipSlot, sub_index); + auto bag_inst = client->GetInv().GetItem(real_bag_slot); + if (bag_inst == nullptr) { continue; } - if (interior_item) { - AddItem(interior_item->GetItem()->ID, interior_item->GetCharges(), interior_slot, interior_item->GetAugmentItemID(0), interior_item->GetAugmentItemID(1), interior_item->GetAugmentItemID(2), interior_item->GetAugmentItemID(3), interior_item->GetAugmentItemID(4), interior_item->GetAugmentItemID(5), item->IsAttuned()); - returnlist.push_back(Inventory::CalcSlotId(equipslot, bagindex)); - client->DeleteItemInInventory(interior_slot, 0, true, false); - } + AddItem( + bag_inst->GetItem()->ID, + bag_inst->GetCharges(), + real_bag_slot, + bag_inst->GetAugmentItemID(0), + bag_inst->GetAugmentItemID(1), + bag_inst->GetAugmentItemID(2), + bag_inst->GetAugmentItemID(3), + bag_inst->GetAugmentItemID(4), + bag_inst->GetAugmentItemID(5), + bag_inst->IsAttuned() + ); + removedList.push_back(real_bag_slot); + client->DeleteItemInInventory(real_bag_slot, 0, true, false); } + break; } - client->DeleteItemInInventory(equipslot, 0, true, false); - return returnlist; + client->DeleteItemInInventory(equipSlot, 0, true, false); } // To be called from LoadFromDBData @@ -979,6 +965,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a Save(); } + auto timestamps = database.GetItemRecastTimestamps(client->CharacterID()); outapp->priority = 6; client->QueuePacket(outapp); safe_delete(outapp); @@ -987,6 +974,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a const Item_Struct* item = database.GetItem(pkitem); ItemInst* inst = database.CreateItem(item, item->MaxCharges); if(inst) { + if (item->RecastDelay) + inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0); client->SendItemPacket(EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot); safe_delete(inst); } @@ -1018,6 +1007,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a if(client && item) { ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned); if(inst) { + if (item->RecastDelay) + inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0); // MainGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = MainGeneral1 + MainCursor client->SendItemPacket(i + EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot); safe_delete(inst); @@ -1474,4 +1465,4 @@ void Corpse::LoadPlayerCorpseDecayTime(uint32 corpse_db_id){ else { corpse_graveyard_timer.SetTimer(3000); } -} \ No newline at end of file +} diff --git a/zone/corpse.h b/zone/corpse.h index 8ef644241..3342eae9f 100644 --- a/zone/corpse.h +++ b/zone/corpse.h @@ -128,7 +128,7 @@ class Corpse : public Mob { virtual void UpdateEquipLightValue(); protected: - std::list MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot); + void MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, std::list &removedList); private: bool is_player_corpse; /* Determines if Player Corpse or not */ diff --git a/zone/effects.cpp b/zone/effects.cpp index cc5f6ebdc..802fce796 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -684,7 +684,7 @@ void EntityList::AETaunt(Client* taunter, float range) } } -// solar: causes caster to hit every mob within dist range of center with +// causes caster to hit every mob within dist range of center with // spell_id. // NPC spells will only affect other NPCs with compatible faction void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster, int16 resist_adjust) @@ -820,7 +820,7 @@ void EntityList::MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool a } } -// solar: causes caster to hit every mob within dist range of center with +// causes caster to hit every mob within dist range of center with // a bard pulse of spell_id. // NPC spells will only affect other NPCs with compatible faction void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster) diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 2e038eb5a..e222edfda 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -65,6 +65,7 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_AGGRO_SAY", "EVENT_PLAYER_PICKUP", "EVENT_POPUPRESPONSE", + "EVENT_ENVIRONMENTAL_DAMAGE", "EVENT_PROXIMITY_SAY", "EVENT_CAST", "EVENT_CAST_BEGIN", @@ -1290,6 +1291,13 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID ExportVar(package_name.c_str(), "popupid", data); break; } + case EVENT_ENVIRONMENTAL_DAMAGE:{ + Seperator sep(data); + ExportVar(package_name.c_str(), "env_damage", sep.arg[0]); + ExportVar(package_name.c_str(), "env_damage_type", sep.arg[1]); + ExportVar(package_name.c_str(), "env_final_damage", sep.arg[2]); + break; + } case EVENT_PROXIMITY_SAY: { ExportVar(package_name.c_str(), "data", objid); diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 7a6989c10..8b49f01b2 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -23,6 +23,7 @@ #include "../common/global_define.h" #include "../common/misc_functions.h" +#include "../common/eqemu_logsys.h" #include "embparser.h" #include "embxs.h" @@ -3493,6 +3494,37 @@ XS(XS__crosszonesignalnpcbynpctypeid) XSRETURN_EMPTY; } +XS(XS__debug); +XS(XS__debug) +{ + dXSARGS; + if (items != 1 && items != 2){ + Perl_croak(aTHX_ "Usage: debug(message, [debug_level])"); + } + else{ + std::string log_message = (std::string)SvPV_nolen(ST(0)); + uint8 debug_level = 1; + + if (items == 2) + debug_level = (uint8)SvIV(ST(1)); + + if (debug_level > Logs::Detail) + return; + + if (debug_level == Logs::General){ + Log.Out(Logs::General, Logs::QuestDebug, log_message); + } + else if (debug_level == Logs::Moderate){ + Log.Out(Logs::Moderate, Logs::QuestDebug, log_message); + } + else if (debug_level == Logs::Detail){ + Log.Out(Logs::Detail, Logs::QuestDebug, log_message); + } + } + XSRETURN_EMPTY; +} + + /* This is the callback perl will look for to setup the quest package's XSUBs @@ -3579,6 +3611,7 @@ EXTERN_C XS(boot_quest) newXS(strcpy(buf, "crosszonesignalclientbycharid"), XS__crosszonesignalclientbycharid, file); newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file); newXS(strcpy(buf, "crosszonesignalnpcbynpctypeid"), XS__crosszonesignalnpcbynpctypeid, file); + newXS(strcpy(buf, "debug"), XS__debug, file); newXS(strcpy(buf, "delglobal"), XS__delglobal, file); newXS(strcpy(buf, "depop"), XS__depop, file); newXS(strcpy(buf, "depop_withtimer"), XS__depop_withtimer, file); diff --git a/zone/event_codes.h b/zone/event_codes.h index f78cdfd82..f793efaf6 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -33,6 +33,7 @@ typedef enum { EVENT_AGGRO_SAY, EVENT_PLAYER_PICKUP, EVENT_POPUP_RESPONSE, + EVENT_ENVIRONMENTAL_DAMAGE, EVENT_PROXIMITY_SAY, EVENT_CAST, EVENT_CAST_BEGIN, diff --git a/zone/exp.cpp b/zone/exp.cpp index 7eb2189df..7e878206a 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -506,8 +506,7 @@ void Client::SetLevel(uint8 set_level, bool command) SetMana(CalcMaxMana()); UpdateWho(); - if(GetMerc()) - UpdateMercLevel(); + UpdateMercLevel(); Save(); } diff --git a/zone/inventory.cpp b/zone/inventory.cpp index b5ca717d3..1da2fb13d 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -879,7 +879,7 @@ void Client::PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootI if(bag_item_data) { // bag contents int16 interior_slot; - // solar: our bag went into slot_id, now let's pack the contents in + // our bag went into slot_id, now let's pack the contents in for(int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) { if(bag_item_data[i] == nullptr) continue; @@ -993,7 +993,7 @@ bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_curs return false; } -// solar: helper function for AutoPutLootInInventory +// helper function for AutoPutLootInInventory void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type) { ItemInst *tmp_inst = m_inv.GetItem(to_slot); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 70e5c9334..cdf42005d 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -1612,6 +1612,7 @@ luabind::scope lua_register_events() { luabind::value("cast_on", static_cast(EVENT_CAST_ON)), luabind::value("task_accepted", static_cast(EVENT_TASK_ACCEPTED)), luabind::value("task_stage_complete", static_cast(EVENT_TASK_STAGE_COMPLETE)), + luabind::value("environmental_damage", static_cast(EVENT_ENVIRONMENTAL_DAMAGE)), luabind::value("task_update", static_cast(EVENT_TASK_UPDATE)), luabind::value("task_complete", static_cast(EVENT_TASK_COMPLETE)), luabind::value("task_fail", static_cast(EVENT_TASK_FAIL)), @@ -1759,12 +1760,11 @@ luabind::scope lua_register_client_version() { .enum_("constants") [ luabind::value("Unknown", static_cast(ClientVersion::Unknown)), - luabind::value("Titanium", static_cast(ClientVersion::Tit)), // deprecated - luabind::value("Tit", static_cast(ClientVersion::Tit)), + luabind::value("Titanium", static_cast(ClientVersion::Titanium)), luabind::value("SoF", static_cast(ClientVersion::SoF)), luabind::value("SoD", static_cast(ClientVersion::SoD)), - luabind::value("Underfoot", static_cast(ClientVersion::Und)), // deprecated - luabind::value("Und", static_cast(ClientVersion::Und)), + luabind::value("Underfoot", static_cast(ClientVersion::UF)), // deprecated + luabind::value("UF", static_cast(ClientVersion::UF)), luabind::value("RoF", static_cast(ClientVersion::RoF)), luabind::value("RoF2", static_cast(ClientVersion::RoF2)) ]; diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 2051b31c7..cf6d356dc 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -35,13 +35,14 @@ #include "zone.h" #include "lua_parser.h" -const char *LuaEvents[_LargestEventID] = { +const char *LuaEvents[_LargestEventID] = { "event_say", "event_trade", "event_death", "event_spawn", "event_attack", "event_combat", + "event_environmental_damage", "event_aggro", "event_slay", "event_npc_slay", @@ -164,6 +165,7 @@ LuaParser::LuaParser() { NPCArgumentDispatch[EVENT_LEAVE_AREA] = handle_npc_area; PlayerArgumentDispatch[EVENT_SAY] = handle_player_say; + PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage; PlayerArgumentDispatch[EVENT_DEATH] = handle_player_death; PlayerArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_player_death; PlayerArgumentDispatch[EVENT_TIMER] = handle_player_timer; diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index dbcf86d74..2780d0212 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -246,6 +246,19 @@ void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std: lua_setfield(L, -2, "language"); } +void handle_player_environmental_damage(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, + std::vector *extra_pointers){ + Seperator sep(data.c_str()); + lua_pushinteger(L, std::stoi(sep.arg[0])); + lua_setfield(L, -2, "env_damage"); + + lua_pushinteger(L, std::stoi(sep.arg[1])); + lua_setfield(L, -2, "env_damage_type"); + + lua_pushinteger(L, std::stoi(sep.arg[2])); + lua_setfield(L, -2, "env_final_damage"); +} + void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector *extra_pointers) { Seperator sep(data.c_str()); diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index 32a59e0da..1965a9189 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -44,6 +44,8 @@ void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, s //Player void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector *extra_pointers); +void handle_player_environmental_damage(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, + std::vector *extra_pointers); void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector *extra_pointers); void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, diff --git a/zone/map.cpp b/zone/map.cpp index 41751028b..d4bb5a268 100644 --- a/zone/map.cpp +++ b/zone/map.cpp @@ -413,9 +413,9 @@ bool Map::LoadV2(FILE *f) { buf += sizeof(uint32); } - std::map> models; + std::map> models; for (uint32 i = 0; i < model_count; ++i) { - std::shared_ptr me(new ModelEntry); + std::unique_ptr me(new ModelEntry); std::string name = buf; buf += name.length() + 1; @@ -456,7 +456,7 @@ bool Map::LoadV2(FILE *f) { me->polys[j] = p; } - models[name] = me; + models[name] = std::move(me); } for (uint32 i = 0; i < plac_count; ++i) { @@ -487,7 +487,7 @@ bool Map::LoadV2(FILE *f) { if (models.count(name) == 0) continue; - auto model = models[name]; + auto &model = models[name]; auto &mod_polys = model->polys; auto &mod_verts = model->verts; for (uint32 j = 0; j < mod_polys.size(); ++j) { diff --git a/zone/merc.cpp b/zone/merc.cpp index b37e73567..2fea4aba4 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -42,7 +42,7 @@ Merc::Merc(const NPCType* d, float x, float y, float z, float heading) _baseFR = d->FR; _basePR = d->PR; _baseCorrup = d->Corrup; - _OwnerClientVersion = static_cast(ClientVersion::Tit); + _OwnerClientVersion = static_cast(ClientVersion::Titanium); RestRegenHP = 0; RestRegenMana = 0; RestRegenEndurance = 0; @@ -75,7 +75,6 @@ Merc::Merc(const NPCType* d, float x, float y, float z, float heading) SetMana(GetMaxMana()); SetEndurance(GetMaxEndurance()); - AI_Init(); AI_Start(); } @@ -1737,7 +1736,6 @@ void Merc::AI_Process() { } void Merc::AI_Start(int32 iMoveDelay) { - NPC::AI_Start(iMoveDelay); if (!pAIControlled) return; @@ -2244,7 +2242,7 @@ bool Merc::AICastSpell(int8 iChance, int32 iSpellTypes) { if(CheckAETaunt()) { //get AE taunt selectedMercSpell = GetBestMercSpellForAETaunt(this); - Log.Out(Logs::General, Logs::Mercenaries, "AE Taunting"); + Log.Out(Logs::General, Logs::Mercenaries, "%s AE Taunting.", GetName()); } if(selectedMercSpell.spellid == 0 && CheckTaunt()) { @@ -4766,12 +4764,13 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, npc_type->no_target_hotkey = 1; Merc* merc = new Merc(npc_type, c->GetX(), c->GetY(), c->GetZ(), 0); + merc->GiveNPCTypeData(npc_type); // for clean up, works a bit like pets if(merc) { merc->SetMercData( merc_template->MercTemplateID ); database.LoadMercEquipment(merc); - merc->UpdateMercStats(c); + merc->UpdateMercStats(c, true); if(updateFromDB) { @@ -4809,6 +4808,7 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, merc->LoadMercSpells(); } + Log.Out(Logs::General, Logs::Mercenaries, "LoadMerc Successful for %s (%s).", merc->GetName(), c->GetName()); return merc; } } @@ -4837,50 +4837,184 @@ void Merc::UpdateMercInfo(Client *c) { c->GetMercInfo().drakkinDetails = drakkin_details; } -void Merc::UpdateMercStats(Client *c) { - if(c->GetMercInfo().MercTemplateID >0) - { - const NPCType* npc_type = database.GetMercType( zone->GetMercTemplate(c->GetMercInfo().MercTemplateID)->MercNPCID, GetRace(), c->GetLevel()); - if (npc_type) - { - max_hp = (npc_type->max_hp * npc_type->scalerate) / 100; - base_hp = (npc_type->max_hp * npc_type->scalerate) / 100; - max_mana = (npc_type->Mana * npc_type->scalerate) / 100; - base_mana = (npc_type->Mana * npc_type->scalerate) / 100; - hp_regen = (npc_type->hp_regen * npc_type->scalerate) / 100; - mana_regen = (npc_type->mana_regen * npc_type->scalerate) / 100; +void Merc::UpdateMercStats(Client *c, bool setmax) +{ + if (c->GetMercInfo().MercTemplateID > 0) { + Log.Out(Logs::General, Logs::Mercenaries, "Updating Mercenary Stats for %s (%s).", GetName(), + c->GetName()); + const NPCType *npc_type = database.GetMercType( + zone->GetMercTemplate(c->GetMercInfo().MercTemplateID)->MercNPCID, GetRace(), c->GetLevel()); + if (npc_type) { + max_hp = npc_type->max_hp; + base_hp = npc_type->max_hp; + max_mana = npc_type->Mana; + base_mana = npc_type->Mana; + max_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet + base_end = npc_type->max_hp; // Hack since Endurance does not exist for NPCType yet + hp_regen = npc_type->hp_regen; + mana_regen = npc_type->mana_regen; + max_dmg = npc_type->max_dmg; + min_dmg = npc_type->min_dmg; + + _baseAC = npc_type->AC; + _baseATK = npc_type->ATK; + _baseSTR = npc_type->STR; + _baseSTA = npc_type->STA; + _baseDEX = npc_type->DEX; + _baseAGI = npc_type->AGI; + _baseWIS = npc_type->WIS; + _baseINT = npc_type->INT; + _baseCHA = npc_type->CHA; + _baseATK = npc_type->ATK; + _baseMR = npc_type->MR; + _baseFR = npc_type->FR; + _baseDR = npc_type->DR; + _basePR = npc_type->PR; + _baseCR = npc_type->CR; + _baseCorrup = npc_type->Corrup; + + uint32 scalepercent = (int)(npc_type->scalerate * RuleI(Mercs, ScaleRate) / 100); + + ScaleStats(scalepercent, setmax); + level = npc_type->level; - max_dmg = (npc_type->max_dmg * npc_type->scalerate) / 100; - min_dmg = (npc_type->min_dmg * npc_type->scalerate) / 100; - _baseSTR = (npc_type->STR * npc_type->scalerate) / 100; - _baseSTA = (npc_type->STA * npc_type->scalerate) / 100; - _baseDEX = (npc_type->DEX * npc_type->scalerate) / 100; - _baseAGI = (npc_type->AGI * npc_type->scalerate) / 100; - _baseWIS = (npc_type->WIS * npc_type->scalerate) / 100; - _baseINT = (npc_type->INT * npc_type->scalerate) / 100; - _baseCHA = (npc_type->CHA * npc_type->scalerate) / 100; - _baseATK = (npc_type->ATK * npc_type->scalerate) / 100; - _baseMR = (npc_type->MR * npc_type->scalerate) / 100; - _baseFR = (npc_type->FR * npc_type->scalerate) / 100; - _baseDR = (npc_type->DR * npc_type->scalerate) / 100; - _basePR = (npc_type->PR * npc_type->scalerate) / 100; - _baseCR = (npc_type->CR * npc_type->scalerate) / 100; - _baseCorrup = (npc_type->Corrup * npc_type->scalerate) / 100; - _baseAC = (npc_type->AC * npc_type->scalerate) / 100; - attack_speed = npc_type->attack_speed; attack_count = npc_type->attack_count; + attack_delay = npc_type->attack_delay; spellscale = npc_type->spellscale; healscale = npc_type->healscale; CalcBonuses(); - - CalcMaxEndurance(); CalcMaxHP(); CalcMaxMana(); + CalcMaxEndurance(); } } } +void Merc::ScaleStats(int scalepercent, bool setmax) { + + Log.Out(Logs::General, Logs::Mercenaries, "Scaling Mercenary Stats to %d Percent for %s.", scalepercent, GetName()); + + if (scalepercent <= 0) + return; + + float scalerate = (float)scalepercent / 100.0f; + + if ((int)((float)base_hp * scalerate) > 1) + { + max_hp = (int)((float)base_hp * scalerate); + base_hp = max_hp; + if (setmax) + cur_hp = max_hp; + } + + if (base_mana) + { + max_mana = (int)((float)base_mana * scalerate); + base_mana = max_mana; + if (setmax) + cur_mana = max_mana; + } + + if (base_end) + { + max_end = (int)((float)base_end * scalerate); + base_end = max_end; + if (setmax) + cur_end = max_end; + } + + if (_baseAC) + { + AC = (int)((float)_baseAC * scalerate); + _baseAC = AC; + } + + if (_baseATK) + { + ATK = (int)((float)_baseATK * scalerate); + _baseATK = ATK; + } + + if (_baseSTR) + { + STR = (int)((float)_baseSTR * scalerate); + _baseSTR = STR; + } + if (_baseSTA) + { + STA = (int)((float)_baseSTA * scalerate); + _baseSTA = STA; + } + if (_baseAGI) + { + AGI = (int)((float)_baseAGI * scalerate); + _baseAGI = AGI; + } + if (_baseDEX) + { + DEX = (int)((float)_baseDEX * scalerate); + _baseDEX = DEX; + } + if (_baseINT) + { + INT = (int)((float)_baseINT * scalerate); + _baseINT = INT; + } + if (_baseWIS) + { + WIS = (int)((float)_baseWIS * scalerate); + _baseWIS = WIS; + } + if (_baseCHA) + { + CHA = (int)((float)_baseCHA * scalerate); + _baseCHA = CHA; + } + + if (_baseMR) + { + MR = (int)((float)_baseMR * scalerate); + _baseMR = MR; + } + if (_baseCR) + { + CR = (int)((float)_baseCR * scalerate); + _baseCR = CR; + } + if (_baseDR) + { + DR = (int)((float)_baseDR * scalerate); + _baseDR = DR; + } + if (_baseFR) + { + FR = (int)((float)_baseFR * scalerate); + _baseFR = FR; + } + if (_basePR) + { + PR = (int)((float)_basePR * scalerate); + _basePR = PR; + } + if (_baseCorrup) + { + Corrup = (int)((float)_baseCorrup * scalerate); + _baseCorrup = Corrup; + } + + if (max_dmg) + { + max_dmg = (int)((float)max_dmg * scalerate); + } + if (min_dmg) + { + min_dmg = (int)((float)min_dmg * scalerate); + } + + return; +} + void Merc::UpdateMercAppearance() { // Copied from Bot Code: uint32 itemID = NO_ITEM; @@ -4938,7 +5072,7 @@ bool Merc::Spawn(Client *owner) { SendPosition(); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Spawn."); + Log.Out(Logs::General, Logs::Mercenaries, "Spawn Mercenary %s.", GetName()); //UpdateMercAppearance(); @@ -5084,7 +5218,8 @@ void Client::SendMercResponsePackets(uint32 ResponseType) SendMercMerchantResponsePacket(3); break; } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercResponsePackets %i.", ResponseType); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercResponsePackets %i for %s.", ResponseType, GetName()); + } void Client::UpdateMercTimer() @@ -5125,7 +5260,7 @@ void Client::UpdateMercTimer() SendMercResponsePackets(16); } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: UpdateMercTimer Complete."); + Log.Out(Logs::General, Logs::Mercenaries, "UpdateMercTimer Complete for %s.", GetName()); // Normal upkeep charge message //Message(7, "You have been charged a mercenary upkeep cost of %i plat, and %i gold and your mercenary upkeep cost timer has been reset to 15 minutes.", upkeep_plat, upkeep_gold, (int)(RuleI(Mercs, UpkeepIntervalMS) / 1000 / 60)); @@ -5178,7 +5313,7 @@ bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) { } } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: CheckCanHireMerc True."); + Log.Out(Logs::General, Logs::Mercenaries, "CheckCanHireMerc True for %s.", GetName()); return true; } @@ -5251,7 +5386,7 @@ bool Client::CheckCanSpawnMerc(uint32 template_id) { return false; } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: CheckCanSpawnMerc True."); + Log.Out(Logs::General, Logs::Mercenaries, "CheckCanSpawnMerc True for %s.", GetName()); return true; } @@ -5273,7 +5408,7 @@ bool Client::CheckCanUnsuspendMerc() { return false; } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: CheckCanUnsuspendMerc True."); + Log.Out(Logs::General, Logs::Mercenaries, "CheckCanUnsuspendMerc True for %s.", GetName()); return true; } @@ -5288,7 +5423,7 @@ void Client::CheckMercSuspendTimer() { GetMercInfo().SuspendedTime = 0; SendMercResponsePackets(0); SendMercSuspendResponsePacket(GetMercInfo().SuspendedTime); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: CheckMercSuspendTimer Ready."); + Log.Out(Logs::General, Logs::Mercenaries, "CheckMercSuspendTimer Ready for %s.", GetName()); } } } @@ -5301,7 +5436,7 @@ void Client::SuspendMercCommand() { { if(!CheckCanUnsuspendMerc()) { - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SuspendMercCommand Unable to Unsuspend."); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Unable to Unsuspend Merc for %s.", GetName()); return; } @@ -5311,13 +5446,13 @@ void Client::SuspendMercCommand() { if(merc) { SpawnMerc(merc, true); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SuspendMercCommand Successful Unsuspend."); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Successful Unsuspend for %s.", GetName()); } else { //merc failed to spawn SendMercResponsePackets(3); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SuspendMercCommand Failed to Spawn Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Failed to Spawn Merc for %s.", GetName()); } } else @@ -5327,10 +5462,27 @@ void Client::SuspendMercCommand() { if(CurrentMerc && GetMercID()) { CurrentMerc->Suspend(); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SuspendMercCommand Successful Suspend."); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Successful Suspend for %s.", GetName()); + } + else + { + // Reset Merc Suspend State + GetMercInfo().IsSuspended = true; + //GetMercInfo().SuspendedTime = time(nullptr) + RuleI(Mercs, SuspendIntervalS); + //GetMercInfo().MercTimerRemaining = GetMercTimer()->GetRemainingTime(); + //GetMercInfo().Stance = GetStance(); + GetMercTimer()->Disable(); + SendMercSuspendResponsePacket(GetMercInfo().SuspendedTime); + SendMercTimer(nullptr); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Failed to Get Merc to Suspend. Resetting Suspend State for %s.", GetName()); } } } + else + { + SpawnMercOnZone(); + Log.Out(Logs::General, Logs::Mercenaries, "SuspendMercCommand Request Failed to Load Merc for %s. Trying SpawnMercOnZone.", GetName()); + } } @@ -5362,7 +5514,7 @@ void Client::SpawnMercOnZone() { { SpawnMerc(merc, false); } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SpawnMercOnZone Normal Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SpawnMercOnZone Normal Merc for %s.", GetName()); } else { @@ -5378,13 +5530,15 @@ void Client::SpawnMercOnZone() { // Send Mercenary Status/Timer packet SendMercTimer(GetMerc()); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SpawnMercOnZone Suspended Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SpawnMercOnZone Suspended Merc for %s.", GetName()); } } else { // No Merc Hired - SendClearMercInfo(); + // RoF+ displays a message from the following packet, which seems useless + //SendClearMercInfo(); + Log.Out(Logs::General, Logs::Mercenaries, "SpawnMercOnZone Failed to load Merc Info from the Database for %s.", GetName()); } } @@ -5398,17 +5552,17 @@ void Client::SendMercTimer(Merc* merc) { if (!merc) { SendMercTimerPacket(NO_MERC_ID, MERC_STATE_SUSPENDED, GetMercInfo().SuspendedTime, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercTimer No Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercTimer No Merc for %s.", GetName()); } else if (merc->IsSuspended()) { SendMercTimerPacket(NO_MERC_ID, MERC_STATE_SUSPENDED, GetMercInfo().SuspendedTime, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercTimer Suspended Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercTimer Suspended Merc for %s.", GetName()); } else { SendMercTimerPacket(merc->GetID(), MERC_STATE_NORMAL, NOT_SUSPENDED_TIME, GetMercInfo().MercTimerRemaining, RuleI(Mercs, SuspendIntervalMS)); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SendMercTimer Normal Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SendMercTimer Normal Merc for %s.", GetName()); } } @@ -5430,7 +5584,7 @@ void Client::SpawnMerc(Merc* merc, bool setMaxStats) { merc->Unsuspend(setMaxStats); merc->SetStance(GetMercInfo().Stance); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SpawnMerc Success."); + Log.Out(Logs::General, Logs::Mercenaries, "SpawnMerc Success for %s.", GetName()); return; @@ -5459,7 +5613,7 @@ bool Merc::Suspend() { // Start the timer to send the packet that refreshes the Unsuspend Button mercOwner->GetPTimers().Start(pTimerMercSuspend, RuleI(Mercs, SuspendIntervalS)); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Suspend Complete."); + Log.Out(Logs::General, Logs::Mercenaries, "Suspend Complete for %s.", mercOwner->GetName()); return true; } @@ -5545,12 +5699,12 @@ bool Client::DismissMerc(uint32 MercID) { bool Dismissed = true; if (!database.DeleteMerc(MercID)) { - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Dismiss Failed for MercID %i", MercID); + Log.Out(Logs::General, Logs::Mercenaries, "Dismiss Failed Database Query for MercID: %i, Client: %s.", MercID, GetName()); Dismissed = false; } else { - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Dismiss Successful."); + Log.Out(Logs::General, Logs::Mercenaries, "Dismiss Successful for %s.", GetName()); } if (GetMerc()) @@ -5603,24 +5757,24 @@ bool Merc::RemoveMercFromGroup(Merc* merc, Group* group) { if(merc && group) { + uint32 groupID = group->GetID(); if(merc->HasGroup()) { if(!group->IsLeader(merc)) { merc->SetFollowID(0); - if(group->DelMember(merc, true)) + if (group->GroupCount() <= 2 && merc->GetGroup() == group && ZoneLoaded) + { + group->DisbandGroup(); + } + else if(group->DelMember(merc, true)) { if(merc->GetMercCharacterID() != 0) { database.SetGroupID(merc->GetName(), 0, merc->GetMercCharacterID(), true); } } - - if(group->GroupCount() <= 1 && ZoneLoaded) - { - group->DisbandGroup(); - } } else { @@ -5633,20 +5787,19 @@ bool Merc::RemoveMercFromGroup(Merc* merc, Group* group) { if(!group->members[i]->IsClient()) continue; - group->members[i]->CastToClient()->LeaveGroup(); - } - for(int i = 0; i < MAX_GROUP_MEMBERS; i++) - { - if(!group->members[i]) - continue; - - if(!group->members[i]->IsMerc()) - continue; - - group->members[i]->CastToMerc()->MercJoinClientGroup(); + Client *groupMember = group->members[i]->CastToClient(); + groupMember->LeaveGroup(); + if (groupMember->GetMerc()) + { + groupMember->GetMerc()->MercJoinClientGroup(); + } } // Group should be removed by now, but just in case: - group->DisbandGroup(); + Group *oldGroup = entity_list.GetGroupByID(groupID); + if (oldGroup != nullptr) + { + oldGroup->DisbandGroup(); + } } Result = true; @@ -5696,45 +5849,40 @@ bool Merc::MercJoinClientGroup() { if(g->GetID() == 0) { + delete g; g = nullptr; return false; } - if(AddMercToGroup(this, g)) + if (AddMercToGroup(this, g)) { - entity_list.AddGroup(g, g->GetID()); - database.SetGroupLeaderName(g->GetID(), mercOwner->GetName()); database.SetGroupID(mercOwner->GetName(), g->GetID(), mercOwner->CharacterID(), false); - database.SetGroupID(this->GetName(), g->GetID(), mercOwner->CharacterID(), true); + database.SetGroupLeaderName(g->GetID(), mercOwner->GetName()); database.RefreshGroupFromDB(mercOwner); g->SaveGroupLeaderAA(); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Mercenary joined new group."); + Log.Out(Logs::General, Logs::Mercenaries, "Mercenary joined new group: %s (%s).", GetName(), mercOwner->GetName()); } else { g->DisbandGroup(); Suspend(); - - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Mercenary disbanded new group."); + Log.Out(Logs::General, Logs::Mercenaries, "Mercenary disbanded new group: %s (%s).", GetName(), mercOwner->GetName()); } } else if (AddMercToGroup(this, mercOwner->GetGroup())) { // Group already exists - database.SetGroupID(GetName(), mercOwner->GetGroup()->GetID(), mercOwner->CharacterID(), true); database.RefreshGroupFromDB(mercOwner); // Update members that are out of zone GetGroup()->SendGroupJoinOOZ(this); - - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Mercenary joined existing group."); + Log.Out(Logs::General, Logs::Mercenaries, "Mercenary %s joined existing group with %s.", GetName(), mercOwner->GetName()); } else { Suspend(); - - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Mercenary failed to join the group - Suspending"); + Log.Out(Logs::General, Logs::Mercenaries, "Mercenary failed to join the group - Suspending %s for (%s).", GetName(), mercOwner->GetName()); } } @@ -5785,7 +5933,7 @@ Merc* Client::GetMerc() { if(GetMercID() == 0) { - Log.Out(Logs::Detail, Logs::Mercenaries, "Mercenary Debug: GetMerc 0."); + Log.Out(Logs::Detail, Logs::Mercenaries, "GetMerc - GetMercID: 0 for %s.", GetName()); return (nullptr); } @@ -5793,14 +5941,14 @@ Merc* Client::GetMerc() { if(tmp == nullptr) { SetMercID(0); - Log.Out(Logs::Detail, Logs::Mercenaries, "Mercenary Debug: GetMerc No Merc."); + Log.Out(Logs::Detail, Logs::Mercenaries, "GetMerc No Merc for %s.", GetName()); return (nullptr); } if(tmp->GetOwnerID() != GetID()) { SetMercID(0); - Log.Out(Logs::Detail, Logs::Mercenaries, "Mercenary Debug: GetMerc Owner Mismatch."); + Log.Out(Logs::Detail, Logs::Mercenaries, "GetMerc Owner Mismatch - OwnerID: %d, ClientID: %d, Client: %s.", tmp->GetOwnerID(), GetID(), GetName()); return (nullptr); } @@ -5818,7 +5966,7 @@ uint8 Client::GetNumMercs() { numMercs++; } } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: GetNumMercs %i.", numMercs); + Log.Out(Logs::General, Logs::Mercenaries, "GetNumMercs Number: %i for %s.", numMercs, GetName()); return numMercs; } @@ -5859,7 +6007,7 @@ void Client::SetMerc(Merc* newmerc) { GetMercInfo().Gender = 0; GetMercInfo().State = 0; memset(GetMercInfo().merc_name, 0, 64); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SetMerc No Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SetMerc No Merc for %s.", GetName()); } else { @@ -5876,7 +6024,7 @@ void Client::SetMerc(Merc* newmerc) { GetMercInfo().Gender = newmerc->GetGender(); GetMercInfo().State = newmerc->IsSuspended() ? MERC_STATE_SUSPENDED : MERC_STATE_NORMAL; snprintf(GetMercInfo().merc_name, 64, "%s", newmerc->GetName()); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: SetMerc New Merc."); + Log.Out(Logs::General, Logs::Mercenaries, "SetMerc New Merc for %s.", GetName()); } } @@ -5884,7 +6032,8 @@ void Client::UpdateMercLevel() { Merc* merc = GetMerc(); if (merc) { - merc->UpdateMercStats(this); + merc->UpdateMercStats(this, false); + merc->SendAppearancePacket(AT_WhoLevel, GetLevel(), true, true); } } @@ -5896,7 +6045,7 @@ void Client::SendMercMerchantResponsePacket(int32 response_type) { MercenaryMerchantResponse_Struct* mmr = (MercenaryMerchantResponse_Struct*)outapp->pBuffer; mmr->ResponseType = response_type; // send specified response type FastQueuePacket(&outapp); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Sent SendMercMerchantResponsePacket %i.", response_type); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercMerchantResponsePacket ResponseType: %i, Client: %s.", response_type, GetName()); } } @@ -5905,7 +6054,7 @@ void Client::SendMercenaryUnknownPacket(uint8 type) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryUnknown1, 1); outapp->WriteUInt8(type); FastQueuePacket(&outapp); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Sent SendMercenaryUnknownPacket %i.", type); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercenaryUnknownPacket Type: %i, Client: %s.", type, GetName()); } @@ -5914,7 +6063,7 @@ void Client::SendMercenaryUnsuspendPacket(uint8 type) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryUnsuspendResponse, 1); outapp->WriteUInt8(type); FastQueuePacket(&outapp); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Sent SendMercenaryUnsuspendPacket %i.", type); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercenaryUnsuspendPacket Type: %i, Client: %s.", type, GetName()); } @@ -5924,7 +6073,7 @@ void Client::SendMercSuspendResponsePacket(uint32 suspended_time) { SuspendMercenaryResponse_Struct* smr = (SuspendMercenaryResponse_Struct*)outapp->pBuffer; smr->SuspendTime = suspended_time; // Seen 0 (not suspended) or c9 c2 64 4f (suspended on Sat Mar 17 11:58:49 2012) - Unix Timestamp FastQueuePacket(&outapp); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Sent SendMercSuspendResponsePacket %i.", suspended_time); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercSuspendResponsePacket Time: %i, Client: %s.", suspended_time, GetName()); } @@ -5939,7 +6088,7 @@ void Client::SendMercTimerPacket(int32 entity_id, int32 merc_state, int32 suspen mss->UpdateInterval = update_interval; // Seen 900000 - 15 minutes in ms mss->MercUnk01 = unk01; // Seen 180000 - 3 minutes in ms - Used for the unsuspend button refresh timer FastQueuePacket(&outapp); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Sent SendMercTimerPacket %i, %i, %i, %i, %i.", entity_id, merc_state, suspended_time, update_interval, unk01); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercTimerPacket EndID: %i, State: %i, SuspendTime: %i, Interval: %i, Unk1: %i, Client: %s.", entity_id, merc_state, suspended_time, update_interval, unk01, GetName()); } @@ -5950,7 +6099,7 @@ void Client::SendMercAssignPacket(uint32 entityID, uint32 unk01, uint32 unk02) { mas->MercUnk01 = unk01; mas->MercUnk02 = unk02; FastQueuePacket(&outapp); - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Sent SendMercAssignPacket %i, %i, %i.", entityID, unk01, unk02); + Log.Out(Logs::Moderate, Logs::Mercenaries, "Sent SendMercAssignPacket EndID: %i, Unk1: %i, Unk2: %i, Client: %s.", entityID, unk01, unk02, GetName()); } void NPC::LoadMercTypes() { diff --git a/zone/merc.h b/zone/merc.h index 31433a060..82136c15d 100644 --- a/zone/merc.h +++ b/zone/merc.h @@ -137,7 +137,7 @@ public: virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho); static Merc* LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, bool updateFromDB = false); void UpdateMercInfo(Client *c); - void UpdateMercStats(Client *c); + void UpdateMercStats(Client *c, bool setmax = false); void UpdateMercAppearance(); virtual void UpdateEquipLightValue(); void AddItem(uint8 slot, uint32 item_id); @@ -189,6 +189,7 @@ public: bool TryHide(); // stat functions + virtual void ScaleStats(int scalepercent, bool setmax = false); virtual void CalcBonuses(); int32 GetEndurance() const {return cur_end;} //This gets our current endurance inline virtual int32 GetAC() const { return AC; } @@ -347,6 +348,7 @@ private: // Private "base stats" Members int32 base_mana; + int32 base_end; int32 _baseAC; uint32 _baseSTR; uint32 _baseSTA; diff --git a/zone/mob.cpp b/zone/mob.cpp index c42f26fe4..a54881298 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2792,7 +2792,7 @@ void Mob::Say(const char *format, ...) } // -// solar: this is like the above, but the first parameter is a string id +// this is like the above, but the first parameter is a string id // void Mob::Say_StringID(uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) { @@ -3092,8 +3092,8 @@ float Mob::FindGroundZ(float new_x, float new_y, float z_offset) if (zone->zonemap != nullptr) { glm::vec3 me; - me.x = m_Position.x; - me.y = m_Position.y; + me.x = new_x; + me.y = new_y; me.z = m_Position.z + z_offset; glm::vec3 hit; float best_z = zone->zonemap->FindBestZ(me, &hit); @@ -3112,8 +3112,8 @@ float Mob::GetGroundZ(float new_x, float new_y, float z_offset) if (zone->zonemap != 0) { glm::vec3 me; - me.x = m_Position.x; - me.y = m_Position.y; + me.x = new_x; + me.y = new_y; me.z = m_Position.z+z_offset; glm::vec3 hit; float best_z = zone->zonemap->FindBestZ(me, &hit); diff --git a/zone/mob.h b/zone/mob.h index e2d25a952..9641a2ffb 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -25,6 +25,7 @@ #include "position.h" #include #include +#include char* strn0cpy(char* dest, const char* source, uint32 size); @@ -122,7 +123,7 @@ public: //Attack virtual void RogueBackstab(Mob* other, bool min_damage = false, int ReuseTime = 10); - virtual void RogueAssassinate(Mob* other); // solar + virtual void RogueAssassinate(Mob* other); float MobAngle(Mob *other = 0, float ourx = 0.0f, float oury = 0.0f) const; // greater than 90 is behind inline bool BehindMob(Mob *other = 0, float ourx = 0.0f, float oury = 0.0f) const @@ -577,7 +578,7 @@ public: void WakeTheDead(uint16 spell_id, Mob *target, uint32 duration); void Spin(); void Kill(); - bool PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id); + bool PassCharismaCheck(Mob* caster, uint16 spell_id); bool TryDeathSave(); bool TryDivineSave(); void DoBuffWearOffEffect(uint32 index); @@ -879,8 +880,8 @@ public: virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther) { return FACTION_INDIFFERENT; } inline bool IsTrackable() const { return(trackable); } - Timer* GetAIThinkTimer() { return AIthink_timer; } - Timer* GetAIMovementTimer() { return AImovement_timer; } + Timer* GetAIThinkTimer() { return AIthink_timer.get(); } + Timer* GetAIMovementTimer() { return AImovement_timer.get(); } Timer GetAttackTimer() { return attack_timer; } Timer GetAttackDWTimer() { return attack_dw_timer; } inline bool IsFindable() { return findable; } @@ -1170,14 +1171,14 @@ protected: uint32 maxLastFightingDelayMoving; float pAggroRange; float pAssistRange; - Timer* AIthink_timer; - Timer* AImovement_timer; - Timer* AItarget_check_timer; + std::unique_ptr AIthink_timer; + std::unique_ptr AImovement_timer; + std::unique_ptr AItarget_check_timer; bool movetimercompleted; bool permarooted; - Timer* AIscanarea_timer; - Timer* AIwalking_timer; - Timer* AIfeignremember_timer; + std::unique_ptr AIscanarea_timer; + std::unique_ptr AIwalking_timer; + std::unique_ptr AIfeignremember_timer; uint32 pLastFightingDelayMoving; HateList hate_list; std::set feign_memory_list; diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 59ee8825b..371a8e523 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -422,14 +422,15 @@ bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float return false; } -void Mob::AI_Init() { +void Mob::AI_Init() +{ pAIControlled = false; - AIthink_timer = 0; - AIwalking_timer = 0; - AImovement_timer = 0; - AItarget_check_timer = 0; - AIfeignremember_timer = nullptr; - AIscanarea_timer = 0; + AIthink_timer.reset(nullptr); + AIwalking_timer.reset(nullptr); + AImovement_timer.reset(nullptr); + AItarget_check_timer.reset(nullptr); + AIfeignremember_timer.reset(nullptr); + AIscanarea_timer.reset(nullptr); minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin); maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax); @@ -441,10 +442,9 @@ void Mob::AI_Init() { pDontCureMeBefore = 0; } -void NPC::AI_Init() { - Mob::AI_Init(); - - AIautocastspell_timer = 0; +void NPC::AI_Init() +{ + AIautocastspell_timer.reset(nullptr); casting_spell_AIindex = static_cast(AIspells.size()); roambox_max_x = 0; @@ -458,8 +458,8 @@ void NPC::AI_Init() { roambox_delay = 2500; } -void Client::AI_Init() { - Mob::AI_Init(); +void Client::AI_Init() +{ minLastFightingDelayMoving = CLIENT_LD_TIMEOUT; maxLastFightingDelayMoving = CLIENT_LD_TIMEOUT; } @@ -474,13 +474,13 @@ void Mob::AI_Start(uint32 iMoveDelay) { pLastFightingDelayMoving = 0; pAIControlled = true; - AIthink_timer = new Timer(AIthink_duration); + AIthink_timer = std::unique_ptr(new Timer(AIthink_duration)); AIthink_timer->Trigger(); - AIwalking_timer = new Timer(0); - AImovement_timer = new Timer(AImovement_duration); - AItarget_check_timer = new Timer(AItarget_check_duration); - AIfeignremember_timer = new Timer(AIfeignremember_delay); - AIscanarea_timer = new Timer(AIscanarea_delay); + AIwalking_timer = std::unique_ptr(new Timer(0)); + AImovement_timer = std::unique_ptr(new Timer(AImovement_duration)); + AItarget_check_timer = std::unique_ptr(new Timer(AItarget_check_duration)); + AIfeignremember_timer = std::unique_ptr(new Timer(AIfeignremember_delay)); + AIscanarea_timer = std::unique_ptr(new Timer(AIscanarea_delay)); #ifdef REVERSE_AGGRO if(IsNPC() && !CastToNPC()->WillAggroNPCs()) AIscanarea_timer->Disable(); @@ -516,10 +516,10 @@ void NPC::AI_Start(uint32 iMoveDelay) { return; if (AIspells.size() == 0) { - AIautocastspell_timer = new Timer(1000); + AIautocastspell_timer = std::unique_ptr(new Timer(1000)); AIautocastspell_timer->Disable(); } else { - AIautocastspell_timer = new Timer(750); + AIautocastspell_timer = std::unique_ptr(new Timer(750)); AIautocastspell_timer->Start(RandomTimer(0, 15000), false); } @@ -540,19 +540,19 @@ void Mob::AI_Stop() { pAIControlled = false; - safe_delete(AIthink_timer); - safe_delete(AIwalking_timer); - safe_delete(AImovement_timer); - safe_delete(AItarget_check_timer); - safe_delete(AIscanarea_timer); - safe_delete(AIfeignremember_timer); + AIthink_timer.reset(nullptr); + AIwalking_timer.reset(nullptr); + AImovement_timer.reset(nullptr); + AItarget_check_timer.reset(nullptr); + AIscanarea_timer.reset(nullptr); + AIfeignremember_timer.reset(nullptr); hate_list.WipeHateList(); } void NPC::AI_Stop() { Waypoints.clear(); - safe_delete(AIautocastspell_timer); + AIautocastspell_timer.reset(nullptr); } void Client::AI_Stop() { @@ -2657,7 +2657,7 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) { npc_spells_cache = new DBnpcspells_Struct*[npc_spells_maxid+1]; npc_spells_loadtried = new bool[npc_spells_maxid+1]; for (uint32 i=0; i<=npc_spells_maxid; i++) { - npc_spells_cache[i] = 0; + npc_spells_cache[i] = nullptr; npc_spells_loadtried[i] = false; } } @@ -2795,7 +2795,7 @@ DBnpcspellseffects_Struct *ZoneDatabase::GetNPCSpellsEffects(uint32 iDBSpellsEff npc_spellseffects_cache = new DBnpcspellseffects_Struct *[npc_spellseffects_maxid + 1]; npc_spellseffects_loadtried = new bool[npc_spellseffects_maxid + 1]; for (uint32 i = 0; i <= npc_spellseffects_maxid; i++) { - npc_spellseffects_cache[i] = 0; + npc_spellseffects_cache[i] = nullptr; npc_spellseffects_loadtried[i] = false; } } diff --git a/zone/net.cpp b/zone/net.cpp index c35add8c3..92f568af0 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -332,7 +332,7 @@ int main(int argc, char** argv) { Timer quest_timers(100); UpdateWindowTitle(); bool worldwasconnected = worldserver.Connected(); - EQStream* eqss; + std::shared_ptr eqss; EQStreamInterface *eqsi; uint8 IDLEZONEUPDATE = 200; uint8 ZONEUPDATE = 10; diff --git a/zone/npc.cpp b/zone/npc.cpp index b9c465195..9a142f128 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -250,8 +250,8 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int if npc_aggro = d->npc_aggro; - if(!IsMerc()) - AI_Start(); + AI_Init(); + AI_Start(); d_melee_texture1 = d->d_melee_texture1; d_melee_texture2 = d->d_melee_texture2; @@ -987,298 +987,267 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* } } -uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,Client *client, NPC* spawn, uint32 extra) { +uint32 ZoneDatabase::CreateNewNPCCommand(const char *zone, uint32 zone_version, Client *client, NPC *spawn, + uint32 extra) +{ + uint32 npc_type_id = 0; - uint32 npc_type_id = 0; - - if (extra && client && client->GetZoneID()) - { + if (extra && client && client->GetZoneID()) { // Set an npc_type ID within the standard range for the current zone if possible (zone_id * 1000) int starting_npc_id = client->GetZoneID() * 1000; std::string query = StringFormat("SELECT MAX(id) FROM npc_types WHERE id >= %i AND id < %i", - starting_npc_id, starting_npc_id + 1000); - auto results = QueryDatabase(query); + starting_npc_id, starting_npc_id + 1000); + auto results = QueryDatabase(query); if (results.Success()) { - if (results.RowCount() != 0) - { - auto row = results.begin(); - npc_type_id = atoi(row[0]) + 1; - // Prevent the npc_type id from exceeding the range for this zone - if (npc_type_id >= (starting_npc_id + 1000)) - npc_type_id = 0; - } - else // No npc_type IDs set in this range yet - npc_type_id = starting_npc_id; - } - } + if (results.RowCount() != 0) { + auto row = results.begin(); + npc_type_id = atoi(row[0]) + 1; + // Prevent the npc_type id from exceeding the range for this zone + if (npc_type_id >= (starting_npc_id + 1000)) + npc_type_id = 0; + } else // No npc_type IDs set in this range yet + npc_type_id = starting_npc_id; + } + } char tmpstr[64]; EntityList::RemoveNumbers(strn0cpy(tmpstr, spawn->GetName(), sizeof(tmpstr))); std::string query; - if (npc_type_id) - { - query = StringFormat("INSERT INTO npc_types (id, name, level, race, class, hp, gender, " - "texture, helmtexture, size, loottable_id, merchant_id, face, " - "runspeed, prim_melee_type, sec_melee_type) " - "VALUES(%i, \"%s\" , %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)", - npc_type_id, tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), - spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(), - spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(), - spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28); - auto results = QueryDatabase(query); + if (npc_type_id) { + query = StringFormat("INSERT INTO npc_types (id, name, level, race, class, hp, gender, " + "texture, helmtexture, size, loottable_id, merchant_id, face, " + "runspeed, prim_melee_type, sec_melee_type) " + "VALUES(%i, \"%s\" , %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)", + npc_type_id, tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), + spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(), + spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(), + spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28); + auto results = QueryDatabase(query); + if (!results.Success()) { + return false; + } + npc_type_id = results.LastInsertedID(); + } else { + query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, " + "texture, helmtexture, size, loottable_id, merchant_id, face, " + "runspeed, prim_melee_type, sec_melee_type) " + "VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)", + tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(), + spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(), + spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28); + auto results = QueryDatabase(query); if (!results.Success()) { return false; } npc_type_id = results.LastInsertedID(); } - else - { - query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, " - "texture, helmtexture, size, loottable_id, merchant_id, face, " - "runspeed, prim_melee_type, sec_melee_type) " - "VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)", - tmpstr, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), - spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(), - spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(), - spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28); - auto results = QueryDatabase(query); - if (!results.Success()) { - return false; - } - npc_type_id = results.LastInsertedID(); - } - - if(client) query = StringFormat("INSERT INTO spawngroup (id, name) VALUES(%i, '%s-%s')", 0, zone, spawn->GetName()); - auto results = QueryDatabase(query); + auto results = QueryDatabase(query); if (!results.Success()) { return false; } - uint32 spawngroupid = results.LastInsertedID(); + uint32 spawngroupid = results.LastInsertedID(); - if(client) - - query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) " - "VALUES('%s', %u, %f, %f, %f, %i, %f, %i)", - zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200, - spawn->GetHeading(), spawngroupid); - results = QueryDatabase(query); + query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) " + "VALUES('%s', %u, %f, %f, %f, %i, %f, %i)", + zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), 1200, spawn->GetHeading(), + spawngroupid); + results = QueryDatabase(query); if (!results.Success()) { return false; } - if(client) - - query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)", - spawngroupid, npc_type_id, 100); - results = QueryDatabase(query); + query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)", spawngroupid, + npc_type_id, 100); + results = QueryDatabase(query); if (!results.Success()) { return false; } - if(client) - return true; } -uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime) { - uint32 last_insert_id = 0; +uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char *zone, uint32 zone_version, Client *client, NPC *spawn, + uint32 respawnTime) +{ + uint32 last_insert_id = 0; - std::string query = StringFormat("INSERT INTO spawngroup (name) VALUES('%s%s%i')", - zone, spawn->GetName(), Timer::GetCurrentTime()); - auto results = QueryDatabase(query); + std::string query = StringFormat("INSERT INTO spawngroup (name) VALUES('%s%s%i')", zone, spawn->GetName(), + Timer::GetCurrentTime()); + auto results = QueryDatabase(query); if (!results.Success()) { return 0; } - last_insert_id = results.LastInsertedID(); + last_insert_id = results.LastInsertedID(); - uint32 respawntime = 0; - uint32 spawnid = 0; - if (respawnTime) - respawntime = respawnTime; - else if(spawn->respawn2 && spawn->respawn2->RespawnTimer() != 0) - respawntime = spawn->respawn2->RespawnTimer(); - else - respawntime = 1200; + uint32 respawntime = 0; + uint32 spawnid = 0; + if (respawnTime) + respawntime = respawnTime; + else if (spawn->respawn2 && spawn->respawn2->RespawnTimer() != 0) + respawntime = spawn->respawn2->RespawnTimer(); + else + respawntime = 1200; - query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) " - "VALUES('%s', %u, %f, %f, %f, %i, %f, %i)", - zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), respawntime, - spawn->GetHeading(), last_insert_id); - results = QueryDatabase(query); - if (!results.Success()) { - return 0; - } - spawnid = results.LastInsertedID(); + query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) " + "VALUES('%s', %u, %f, %f, %f, %i, %f, %i)", + zone, zone_version, spawn->GetX(), spawn->GetY(), spawn->GetZ(), respawntime, + spawn->GetHeading(), last_insert_id); + results = QueryDatabase(query); + if (!results.Success()) { + return 0; + } + spawnid = results.LastInsertedID(); - if(client) + query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)", last_insert_id, + spawn->GetNPCTypeID(), 100); + results = QueryDatabase(query); + if (!results.Success()) { + return 0; + } - query = StringFormat("INSERT INTO spawnentry (spawngroupID, npcID, chance) VALUES(%i, %i, %i)", - last_insert_id, spawn->GetNPCTypeID(), 100); - results = QueryDatabase(query); - if (!results.Success()) { - return 0; - } - - if(client) - - return spawnid; + return spawnid; } -uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client *client, NPC* spawn) { - - std::string query = StringFormat("UPDATE npc_types SET name = \"%s\", level = %i, race = %i, class = %i, " - "hp = %i, gender = %i, texture = %i, helmtexture = %i, size = %i, " - "loottable_id = %i, merchant_id = %i, face = %i, WHERE id = %i", - spawn->GetName(), spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), - spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(), - spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(), - spawn->MerchantType, spawn->GetNPCTypeID()); - auto results = QueryDatabase(query); - if (!results.Success() && client) - - return results.Success() == true? 1: 0; +uint32 ZoneDatabase::UpdateNPCTypeAppearance(Client *client, NPC *spawn) +{ + std::string query = + StringFormat("UPDATE npc_types SET name = \"%s\", level = %i, race = %i, class = %i, " + "hp = %i, gender = %i, texture = %i, helmtexture = %i, size = %i, " + "loottable_id = %i, merchant_id = %i, face = %i, WHERE id = %i", + spawn->GetName(), spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(), + spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(), + spawn->GetLoottableID(), spawn->MerchantType, spawn->GetNPCTypeID()); + auto results = QueryDatabase(query); + return results.Success() == true ? 1 : 0; } -uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const char* zone, Client *client, NPC* spawn) { +uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const char *zone, Client *client, NPC *spawn) +{ uint32 id = 0; uint32 spawngroupID = 0; std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE " - "zone='%s' AND spawngroupID=%i", zone, spawn->GetSp2()); - auto results = QueryDatabase(query); - if (!results.Success()) + "zone='%s' AND spawngroupID=%i", + zone, spawn->GetSp2()); + auto results = QueryDatabase(query); + if (!results.Success()) return 0; - if (results.RowCount() == 0) - return 0; + if (results.RowCount() == 0) + return 0; auto row = results.begin(); if (row[0]) - id = atoi(row[0]); + id = atoi(row[0]); if (row[1]) - spawngroupID = atoi(row[1]); + spawngroupID = atoi(row[1]); - query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id); - results = QueryDatabase(query); + query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id); + results = QueryDatabase(query); if (!results.Success()) return 0; - if(client) - - query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID); - results = QueryDatabase(query); + query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID); + results = QueryDatabase(query); if (!results.Success()) return 0; - if(client) - - query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID); - results = QueryDatabase(query); + query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID); + results = QueryDatabase(query); if (!results.Success()) return 0; - if(client) - return 1; } -uint32 ZoneDatabase::DeleteSpawnRemoveFromNPCTypeTable(const char* zone, uint32 zone_version, Client *client, NPC* spawn) { - +uint32 ZoneDatabase::DeleteSpawnRemoveFromNPCTypeTable(const char *zone, uint32 zone_version, Client *client, + NPC *spawn) +{ uint32 id = 0; uint32 spawngroupID = 0; std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE zone = '%s' " - "AND version = %u AND spawngroupID = %i", - zone, zone_version, spawn->GetSp2()); - auto results = QueryDatabase(query); - if (!results.Success()) + "AND version = %u AND spawngroupID = %i", + zone, zone_version, spawn->GetSp2()); + auto results = QueryDatabase(query); + if (!results.Success()) return 0; - if (results.RowCount() == 0) - return 0; + if (results.RowCount() == 0) + return 0; auto row = results.begin(); if (row[0]) - id = atoi(row[0]); + id = atoi(row[0]); if (row[1]) - spawngroupID = atoi(row[1]); + spawngroupID = atoi(row[1]); - query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id); - results = QueryDatabase(query); - if (!results.Success()) - return 0; - - if(client) - - query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID); + query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", id); results = QueryDatabase(query); if (!results.Success()) return 0; - if(client) - - query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID); + query = StringFormat("DELETE FROM spawngroup WHERE id = '%i'", spawngroupID); results = QueryDatabase(query); if (!results.Success()) return 0; - if(client) - - query = StringFormat("DELETE FROM npc_types WHERE id = '%i'", spawn->GetNPCTypeID()); + query = StringFormat("DELETE FROM spawnentry WHERE spawngroupID = '%i'", spawngroupID); results = QueryDatabase(query); if (!results.Success()) return 0; - if(client) + query = StringFormat("DELETE FROM npc_types WHERE id = '%i'", spawn->GetNPCTypeID()); + results = QueryDatabase(query); + if (!results.Success()) + return 0; return 1; } -uint32 ZoneDatabase::AddSpawnFromSpawnGroup(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID) { - +uint32 ZoneDatabase::AddSpawnFromSpawnGroup(const char *zone, uint32 zone_version, Client *client, NPC *spawn, + uint32 spawnGroupID) +{ uint32 last_insert_id = 0; - std::string query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) " - "VALUES('%s', %u, %f, %f, %f, %i, %f, %i)", - zone, zone_version, client->GetX(), client->GetY(), client->GetZ(), - 120, client->GetHeading(), spawnGroupID); - auto results = QueryDatabase(query); - if (!results.Success()) + std::string query = + StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) " + "VALUES('%s', %u, %f, %f, %f, %i, %f, %i)", + zone, zone_version, client->GetX(), client->GetY(), client->GetZ(), 120, client->GetHeading(), + spawnGroupID); + auto results = QueryDatabase(query); + if (!results.Success()) return 0; - if(client) - - return 1; + return 1; } -uint32 ZoneDatabase::AddNPCTypes(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID) { - - uint32 npc_type_id; +uint32 ZoneDatabase::AddNPCTypes(const char *zone, uint32 zone_version, Client *client, NPC *spawn, uint32 spawnGroupID) +{ + uint32 npc_type_id; char numberlessName[64]; EntityList::RemoveNumbers(strn0cpy(numberlessName, spawn->GetName(), sizeof(numberlessName))); - std::string query = StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, " - "texture, helmtexture, size, loottable_id, merchant_id, face, " - "runspeed, prim_melee_type, sec_melee_type) " - "VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)", - numberlessName, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), - spawn->GetMaxHP(), spawn->GetGender(), spawn->GetTexture(), - spawn->GetHelmTexture(), spawn->GetSize(), spawn->GetLoottableID(), - spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28); - auto results = QueryDatabase(query); + std::string query = + StringFormat("INSERT INTO npc_types (name, level, race, class, hp, gender, " + "texture, helmtexture, size, loottable_id, merchant_id, face, " + "runspeed, prim_melee_type, sec_melee_type) " + "VALUES(\"%s\", %i, %i, %i, %i, %i, %i, %i, %f, %i, %i, %i, %f, %i, %i)", + numberlessName, spawn->GetLevel(), spawn->GetRace(), spawn->GetClass(), spawn->GetMaxHP(), + spawn->GetGender(), spawn->GetTexture(), spawn->GetHelmTexture(), spawn->GetSize(), + spawn->GetLoottableID(), spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28); + auto results = QueryDatabase(query); if (!results.Success()) return 0; - npc_type_id = results.LastInsertedID(); + npc_type_id = results.LastInsertedID(); - if(client) - - if(client) - client->Message(0, "%s npc_type ID %i created successfully!", numberlessName, npc_type_id); + if (client) + client->Message(0, "%s npc_type ID %i created successfully!", numberlessName, npc_type_id); return 1; } diff --git a/zone/npc.h b/zone/npc.h index e38aa85aa..6cb31ed87 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -436,7 +436,7 @@ protected: uint32 npc_spells_id; uint8 casting_spell_AIindex; - Timer* AIautocastspell_timer; + std::unique_ptr AIautocastspell_timer; uint32* pDontCastBefore_casting_spell; std::vector AIspells; bool HasAISpell; @@ -444,7 +444,7 @@ protected: virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0); AISpellsVar_Struct AISpellVar; int16 GetFocusEffect(focusType type, uint16 spell_id); - + uint32 npc_spells_effects_id; std::vector AIspellsEffects; bool HasAISpellEffects; diff --git a/zone/object.cpp b/zone/object.cpp index 38f4c67c4..7dd97d355 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -467,16 +467,21 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) if (m_inst && sender) { // if there is a lore conflict, delete the offending item from the server inventory // the client updates itself and takes care of sending "duplicate lore item" messages - if(sender->CheckLoreConflict(m_inst->GetItem())) { - int16 loreslot = sender->GetInv().HasItem(m_inst->GetItem()->ID, 0, invWhereBank); + auto item = m_inst->GetItem(); + if(sender->CheckLoreConflict(item)) { + int16 loreslot = sender->GetInv().HasItem(item->ID, 0, invWhereBank); if (loreslot != INVALID_INDEX) // if the duplicate is in the bank, delete it. sender->DeleteItemInInventory(loreslot); else cursordelete = true; // otherwise, we delete the new one } + if (item->RecastDelay) + m_inst->SetRecastTimestamp( + database.GetItemRecastTimestamp(sender->CharacterID(), item->RecastType)); + char buf[10]; - snprintf(buf, 9, "%u", m_inst->GetItem()->ID); + snprintf(buf, 9, "%u", item->ID); buf[9] = '\0'; std::vector args; args.push_back(m_inst); diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 4998150bd..c0844c2ac 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -663,7 +663,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) DoAnim(animPiercing); } -// solar - assassinate [Kayen: No longer used for regular assassinate 6-29-14] +// assassinate [No longer used for regular assassinate 6-29-14] void Mob::RogueAssassinate(Mob* other) { //can you dodge, parry, etc.. an assassinate?? @@ -857,7 +857,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite if (IsClient()){ _RangeWeapon = CastToClient()->m_inv[MainRange]; - if (_RangeWeapon && !_RangeWeapon->GetItem() && _RangeWeapon->GetItem()->ID == range_id) + if (_RangeWeapon && _RangeWeapon->GetItem() && _RangeWeapon->GetItem()->ID == range_id) RangeWeapon = _RangeWeapon; _Ammo = CastToClient()->m_inv[AmmoSlot]; @@ -996,7 +996,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite } if (LaunchProjectile) - return;//Shouldn't reach this point, but just in case. + return;//Shouldn't reach this point durring initial launch phase, but just in case. //Weapon Proc if(RangeWeapon && other && !other->HasDied()) diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 024c938c9..a6725b296 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -134,7 +134,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) if (spells[spell_id].EndurUpkeep > 0) SetEndurUpkeep(true); - if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UnderfootAndLater) + if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UFAndLater) { EQApplicationPacket *outapp = MakeBuffsPacket(false); CastToClient()->FastQueuePacket(&outapp); @@ -3409,7 +3409,7 @@ void Mob::BuffProcess() { CastToClient()->SendBuffDurationPacket(buffs[buffs_i]); // Hack to get UF to play nicer, RoF seems fine without it - if (CastToClient()->GetClientVersion() == ClientVersion::Und && buffs[buffs_i].numhits > 0) + if (CastToClient()->GetClientVersion() == ClientVersion::UF && buffs[buffs_i].numhits > 0) CastToClient()->SendBuffNumHitPacket(buffs[buffs_i], buffs_i); buffs[buffs_i].UpdateClient = false; } @@ -3586,7 +3586,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste } case SE_Charm: { - if (!caster || !PassCharismaCheck(caster, this, spell_id)) { + if (!caster || !PassCharismaCheck(caster, spell_id)) { BuffFadeByEffect(SE_Charm); } @@ -4175,7 +4175,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses) safe_delete(outapp); } - if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UnderfootAndLater) + if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UFAndLater) { EQApplicationPacket *outapp = MakeBuffsPacket(false); CastToClient()->FastQueuePacket(&outapp); diff --git a/zone/spells.cpp b/zone/spells.cpp index 835861f03..849dacfbe 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1242,6 +1242,8 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, { //Can we start the timer here? I don't see why not. CastToClient()->GetPTimers().Start((pTimerItemStart + recasttype), recastdelay); + database.UpdateItemRecastTimestamps(CastToClient()->CharacterID(), recasttype, + CastToClient()->GetPTimers().Get(pTimerItemStart + recasttype)->GetReadyTimestamp()); } } @@ -2023,6 +2025,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 // // Switch #2 - execute the spell // + switch(CastAction) { default: @@ -2146,6 +2149,15 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 // caster if they're not using TGB // NOTE: this will always hit the caster, plus the target's group so // it can affect up to 7 people if the targeted group is not our own + + // Allow pets who cast group spells to affect the group. + if (spell_target->IsPetOwnerClient()){ + Mob* owner = spell_target->GetOwner(); + + if (owner) + spell_target = owner; + } + if(spell_target->IsGrouped()) { Group *target_group = entity_list.GetGroupByMob(spell_target); @@ -2270,11 +2282,15 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 { ItemInst *itm = CastToClient()->GetInv().GetItem(inventory_slot); if(itm && itm->GetItem()->RecastDelay > 0){ - CastToClient()->GetPTimers().Start((pTimerItemStart + itm->GetItem()->RecastType), itm->GetItem()->RecastDelay); + auto recast_type = itm->GetItem()->RecastType; + CastToClient()->GetPTimers().Start((pTimerItemStart + recast_type), itm->GetItem()->RecastDelay); + database.UpdateItemRecastTimestamps( + CastToClient()->CharacterID(), recast_type, + CastToClient()->GetPTimers().Get(pTimerItemStart + recast_type)->GetReadyTimestamp()); EQApplicationPacket *outapp = new EQApplicationPacket(OP_ItemRecastDelay, sizeof(ItemRecastDelay_Struct)); ItemRecastDelay_Struct *ird = (ItemRecastDelay_Struct *)outapp->pBuffer; ird->recast_delay = itm->GetItem()->RecastDelay; - ird->recast_type = itm->GetItem()->RecastType; + ird->recast_type = recast_type; CastToClient()->QueuePacket(outapp); safe_delete(outapp); } @@ -3659,7 +3675,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r if(!IsHarmonySpell(spell_id)) spelltar->AddToHateList(this, aggro); else - if(!PassCharismaCheck(this, spelltar, spell_id)) + if(!spelltar->PassCharismaCheck(this, spell_id)) spelltar->AddToHateList(this, aggro); } else{ @@ -4388,7 +4404,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use level_mod += (2 * level_diff); } } - + if (CharismaCheck) { /* @@ -4402,7 +4418,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use */ int16 charisma = caster->GetCHA(); - if (IsFear && (spells[spell_id].targettype != 10)){ + if (IsFear && (spells[spell_id].targettype != ST_Undead)){ if (charisma < 100) resist_modifier -= 20; @@ -4423,8 +4439,10 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use else resist_modifier += ((75 - charisma)/10) * 6; //Increase Resist Chance } + } + //Lull spells DO NOT use regular resists on initial cast, instead they use a flat +15 modifier. Live parses confirm this. //Regular resists are used when checking if mob will aggro off of a lull resist. if(!CharismaCheck && IsHarmonySpell(spell_id)) @@ -4452,9 +4470,8 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use //Minimum resist chance should be caclulated factoring in the RuleI(Spells, CharmBreakCheckChance) if (CharmTick) { - int min_charmbreakchance = ((100/RuleI(Spells, CharmBreakCheckChance))/66 * 100)*2; - - if (resist_chance < min_charmbreakchance) + float min_charmbreakchance = ((100.0f/static_cast(RuleI(Spells, CharmBreakCheckChance)))/66.0f * 100.0f)*2.0f; + if (resist_chance < static_cast(min_charmbreakchance)) resist_chance = min_charmbreakchance; } @@ -4462,9 +4479,9 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use //Minimum resist chance should be caclulated factoring in the RuleI(Spells, RootBreakCheckChance) if (IsRoot) { - int min_rootbreakchance = ((100/RuleI(Spells, RootBreakCheckChance))/22 * 100)*2; + float min_rootbreakchance = ((100.0f/static_cast(RuleI(Spells, RootBreakCheckChance)))/22.0f * 100.0f)*2.0f; - if (resist_chance < min_rootbreakchance) + if (resist_chance < static_cast(min_rootbreakchance)) resist_chance = min_rootbreakchance; } @@ -5248,7 +5265,7 @@ void Client::SendBuffDurationPacket(Buffs_Struct &buff) void Client::SendBuffNumHitPacket(Buffs_Struct &buff, int slot) { // UF+ use this packet - if (GetClientVersion() < ClientVersion::Und) + if (GetClientVersion() < ClientVersion::UF) return; EQApplicationPacket *outapp; outapp = new EQApplicationPacket(OP_BuffCreate, sizeof(BuffIcon_Struct) + sizeof(BuffIconEntry_Struct)); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index e3cee409b..ec2893e05 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -473,7 +473,7 @@ void WorldServer::Process() { if (ZoneLoaded) { SetZone(zone->GetZoneID(), zone->GetInstanceID()); if (zst->zoneid == zone->GetZoneID()) { - // This packet also doubles as "incomming client" notification, lets not shut down before they get here + // This packet also doubles as "incoming client" notification, lets not shut down before they get here zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); } else { @@ -488,22 +488,19 @@ void WorldServer::Process() { if (!(Zone::Bootup(zst->zoneid, zst->instanceid, zst->makestatic))) { SendChannelMessage(0, 0, 10, 0, 0, "%s:%i Zone::Bootup failed: %s", net.GetZoneAddress(), net.GetZonePort(), database.GetZoneName(zst->zoneid)); } - // Moved annoucement to ZoneBootup() - // else - // SendEmoteMessage(0, 0, 15, "Zone bootup: %s", zone->GetLongName()); break; } case ServerOP_ZoneIncClient: { - if (pack->size != sizeof(ServerZoneIncommingClient_Struct)) { - std::cout << "Wrong size on ServerOP_ZoneIncClient. Got: " << pack->size << ", Expected: " << sizeof(ServerZoneIncommingClient_Struct) << std::endl; + if (pack->size != sizeof(ServerZoneIncomingClient_Struct)) { + std::cout << "Wrong size on ServerOP_ZoneIncClient. Got: " << pack->size << ", Expected: " << sizeof(ServerZoneIncomingClient_Struct) << std::endl; break; } - ServerZoneIncommingClient_Struct* szic = (ServerZoneIncommingClient_Struct*) pack->pBuffer; + ServerZoneIncomingClient_Struct* szic = (ServerZoneIncomingClient_Struct*) pack->pBuffer; if (ZoneLoaded) { SetZone(zone->GetZoneID(), zone->GetInstanceID()); if (szic->zoneid == zone->GetZoneID()) { zone->AddAuth(szic); - // This packet also doubles as "incomming client" notification, lets not shut down before they get here + // This packet also doubles as "incoming client" notification, lets not shut down before they get here zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); } } @@ -650,7 +647,7 @@ void WorldServer::Process() { case ServerOP_Petition: { std::cout << "Got Server Requested Petition List Refresh" << std::endl; ServerPetitionUpdate_Struct* sus = (ServerPetitionUpdate_Struct*) pack->pBuffer; - // solar: this was typoed to = instead of ==, not that it acts any different now though.. + // this was typoed to = instead of ==, not that it acts any different now though.. if (sus->status == 0) petition_list.ReadDatabase(); else if (sus->status == 1) petition_list.ReadDatabase(); // Until I fix this to be better.... break; diff --git a/zone/zone.cpp b/zone/zone.cpp index 5885b6e95..444e217da 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -656,7 +656,7 @@ void Zone::LoadMercSpells(){ merc_spells_list[classid].push_back(tempMercSpellEntry); } - Log.Out(Logs::General, Logs::Mercenaries, "Mercenary Debug: Loaded %i merc spells.", merc_spells_list[1].size() + merc_spells_list[2].size() + merc_spells_list[9].size() + merc_spells_list[12].size()); + Log.Out(Logs::General, Logs::Mercenaries, "Loaded %i merc spells.", merc_spells_list[1].size() + merc_spells_list[2].size() + merc_spells_list[9].size() + merc_spells_list[12].size()); } @@ -1086,7 +1086,7 @@ bool Zone::SaveZoneCFG() { return database.SaveZoneCFG(GetZoneID(), GetInstanceVersion(), &newzone_data); } -void Zone::AddAuth(ServerZoneIncommingClient_Struct* szic) { +void Zone::AddAuth(ServerZoneIncomingClient_Struct* szic) { ZoneClientAuth_Struct* zca = new ZoneClientAuth_Struct; memset(zca, 0, sizeof(ZoneClientAuth_Struct)); zca->ip = szic->ip; diff --git a/zone/zone.h b/zone/zone.h index adda8f7ff..3d1775718 100644 --- a/zone/zone.h +++ b/zone/zone.h @@ -84,7 +84,7 @@ class PathManager; class WaterMap; extern EntityList entity_list; struct NPCType; -struct ServerZoneIncommingClient_Struct; +struct ServerZoneIncomingClient_Struct; class Zone { @@ -149,7 +149,7 @@ public: void StartShutdownTimer(uint32 set_time = (RuleI(Zone, AutoShutdownDelay))); void ChangeWeather(); bool HasWeather(); - void AddAuth(ServerZoneIncommingClient_Struct* szic); + void AddAuth(ServerZoneIncomingClient_Struct* szic); void RemoveAuth(const char* iCharName); void ResetAuth(); bool GetAuth(uint32 iIP, const char* iCharName, uint32* oWID = 0, uint32* oAccID = 0, uint32* oCharID = 0, int16* oStatus = 0, char* oLSKey = 0, bool* oTellsOff = 0); diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index d50a72473..56236f1b8 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1937,8 +1937,8 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) { return npc; } -const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 clientlevel) { - +const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 clientlevel) +{ //need to save based on merc_npc_type & client level uint32 merc_type_id = id * 100 + clientlevel; @@ -1963,7 +1963,7 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client "0 AS gender, " "m_armorinfo.texture, " "m_armorinfo.helmtexture, " - "m_stats.attack_speed, " + "m_stats.attack_delay, " "m_stats.STR, " "m_stats.STA, " "m_stats.DEX, " @@ -1996,6 +1996,7 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client "m_stats.AC, " "m_stats.ATK, " "m_stats.Accuracy, " + "m_stats.statscale, " "m_stats.spellscale, " "m_stats.healscale " "FROM merc_stats m_stats " @@ -2014,125 +2015,125 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client "WHERE m_templates.merc_npc_type_id = %d AND m_stats.clientlevel = %d AND m_types.race_id = %d", id, clientlevel, raceid); //dual primary keys. one is ID, one is level. - auto results = QueryDatabase(query); - if (!results.Success()) { - return nullptr; - } + auto results = QueryDatabase(query); + if (!results.Success()) { + return nullptr; + } - const NPCType *npc; + const NPCType *npc; - // Process each row returned. - for (auto row = results.begin(); row != results.end(); ++row) { - NPCType *tmpNPCType; - tmpNPCType = new NPCType; - memset (tmpNPCType, 0, sizeof *tmpNPCType); + // Process each row returned. + for (auto row = results.begin(); row != results.end(); ++row) { + NPCType *tmpNPCType; + tmpNPCType = new NPCType; + memset(tmpNPCType, 0, sizeof *tmpNPCType); - tmpNPCType->npc_id = atoi(row[0]); + tmpNPCType->npc_id = atoi(row[0]); - strn0cpy(tmpNPCType->name, row[1], 50); + strn0cpy(tmpNPCType->name, row[1], 50); - tmpNPCType->level = atoi(row[2]); - tmpNPCType->race = atoi(row[3]); - tmpNPCType->class_ = atoi(row[4]); - tmpNPCType->max_hp = atoi(row[5]); - tmpNPCType->cur_hp = tmpNPCType->max_hp; - tmpNPCType->Mana = atoi(row[6]); - tmpNPCType->gender = atoi(row[7]); - tmpNPCType->texture = atoi(row[8]); - tmpNPCType->helmtexture = atoi(row[9]); - tmpNPCType->attack_speed = atof(row[10]); - tmpNPCType->STR = atoi(row[11]); - tmpNPCType->STA = atoi(row[12]); - tmpNPCType->DEX = atoi(row[13]); - tmpNPCType->AGI = atoi(row[14]); - tmpNPCType->INT = atoi(row[15]); - tmpNPCType->WIS = atoi(row[16]); - tmpNPCType->CHA = atoi(row[17]); - tmpNPCType->MR = atoi(row[18]); - tmpNPCType->CR = atoi(row[19]); - tmpNPCType->DR = atoi(row[20]); - tmpNPCType->FR = atoi(row[21]); - tmpNPCType->PR = atoi(row[22]); - tmpNPCType->Corrup = atoi(row[23]); - tmpNPCType->min_dmg = atoi(row[24]); - tmpNPCType->max_dmg = atoi(row[25]); - tmpNPCType->attack_count = atoi(row[26]); + tmpNPCType->level = atoi(row[2]); + tmpNPCType->race = atoi(row[3]); + tmpNPCType->class_ = atoi(row[4]); + tmpNPCType->max_hp = atoi(row[5]); + tmpNPCType->cur_hp = tmpNPCType->max_hp; + tmpNPCType->Mana = atoi(row[6]); + tmpNPCType->gender = atoi(row[7]); + tmpNPCType->texture = atoi(row[8]); + tmpNPCType->helmtexture = atoi(row[9]); + tmpNPCType->attack_delay = atoi(row[10]); + tmpNPCType->STR = atoi(row[11]); + tmpNPCType->STA = atoi(row[12]); + tmpNPCType->DEX = atoi(row[13]); + tmpNPCType->AGI = atoi(row[14]); + tmpNPCType->INT = atoi(row[15]); + tmpNPCType->WIS = atoi(row[16]); + tmpNPCType->CHA = atoi(row[17]); + tmpNPCType->MR = atoi(row[18]); + tmpNPCType->CR = atoi(row[19]); + tmpNPCType->DR = atoi(row[20]); + tmpNPCType->FR = atoi(row[21]); + tmpNPCType->PR = atoi(row[22]); + tmpNPCType->Corrup = atoi(row[23]); + tmpNPCType->min_dmg = atoi(row[24]); + tmpNPCType->max_dmg = atoi(row[25]); + tmpNPCType->attack_count = atoi(row[26]); if (row[27] != nullptr) strn0cpy(tmpNPCType->special_abilities, row[27], 512); else tmpNPCType->special_abilities[0] = '\0'; - tmpNPCType->d_melee_texture1 = atoi(row[28]); - tmpNPCType->d_melee_texture2 = atoi(row[29]); - tmpNPCType->prim_melee_type = atoi(row[30]); - tmpNPCType->sec_melee_type = atoi(row[31]); - tmpNPCType->runspeed= atof(row[32]); + tmpNPCType->d_melee_texture1 = atoi(row[28]); + tmpNPCType->d_melee_texture2 = atoi(row[29]); + tmpNPCType->prim_melee_type = atoi(row[30]); + tmpNPCType->sec_melee_type = atoi(row[31]); + tmpNPCType->runspeed = atof(row[32]); - tmpNPCType->hp_regen = atoi(row[33]); - tmpNPCType->mana_regen = atoi(row[34]); + tmpNPCType->hp_regen = atoi(row[33]); + tmpNPCType->mana_regen = atoi(row[34]); - tmpNPCType->aggroradius = RuleI(Mercs, AggroRadius); + tmpNPCType->aggroradius = RuleI(Mercs, AggroRadius); - if (row[35] && strlen(row[35])) - tmpNPCType->bodytype = (uint8)atoi(row[35]); - else - tmpNPCType->bodytype = 1; + if (row[35] && strlen(row[35])) + tmpNPCType->bodytype = (uint8)atoi(row[35]); + else + tmpNPCType->bodytype = 1; - uint32 armor_tint_id = atoi(row[36]); - tmpNPCType->armor_tint[0] = (atoi(row[37]) & 0xFF) << 16; - tmpNPCType->armor_tint[0] |= (atoi(row[38]) & 0xFF) << 8; - tmpNPCType->armor_tint[0] |= (atoi(row[39]) & 0xFF); - tmpNPCType->armor_tint[0] |= (tmpNPCType->armor_tint[0]) ? (0xFF << 24) : 0; + uint32 armor_tint_id = atoi(row[36]); + tmpNPCType->armor_tint[0] = (atoi(row[37]) & 0xFF) << 16; + tmpNPCType->armor_tint[0] |= (atoi(row[38]) & 0xFF) << 8; + tmpNPCType->armor_tint[0] |= (atoi(row[39]) & 0xFF); + tmpNPCType->armor_tint[0] |= (tmpNPCType->armor_tint[0]) ? (0xFF << 24) : 0; - if (armor_tint_id == 0) - for (int index = MaterialChest; index <= EmuConstants::MATERIAL_END; index++) - tmpNPCType->armor_tint[index] = tmpNPCType->armor_tint[0]; - else if (tmpNPCType->armor_tint[0] == 0) { - std::string armorTint_query = StringFormat("SELECT red1h, grn1h, blu1h, " - "red2c, grn2c, blu2c, " - "red3a, grn3a, blu3a, " - "red4b, grn4b, blu4b, " - "red5g, grn5g, blu5g, " - "red6l, grn6l, blu6l, " - "red7f, grn7f, blu7f, " - "red8x, grn8x, blu8x, " - "red9x, grn9x, blu9x " - "FROM npc_types_tint WHERE id = %d", - armor_tint_id); - auto armorTint_results = QueryDatabase(armorTint_query); - if (!results.Success() || results.RowCount() == 0) - armor_tint_id = 0; - else { - auto armorTint_row = results.begin(); + if (armor_tint_id == 0) + for (int index = MaterialChest; index <= EmuConstants::MATERIAL_END; index++) + tmpNPCType->armor_tint[index] = tmpNPCType->armor_tint[0]; + else if (tmpNPCType->armor_tint[0] == 0) { + std::string armorTint_query = StringFormat("SELECT red1h, grn1h, blu1h, " + "red2c, grn2c, blu2c, " + "red3a, grn3a, blu3a, " + "red4b, grn4b, blu4b, " + "red5g, grn5g, blu5g, " + "red6l, grn6l, blu6l, " + "red7f, grn7f, blu7f, " + "red8x, grn8x, blu8x, " + "red9x, grn9x, blu9x " + "FROM npc_types_tint WHERE id = %d", + armor_tint_id); + auto armorTint_results = QueryDatabase(armorTint_query); + if (!results.Success() || results.RowCount() == 0) + armor_tint_id = 0; + else { + auto armorTint_row = results.begin(); - for (int index = EmuConstants::MATERIAL_BEGIN; index <= EmuConstants::MATERIAL_END; index++) { - tmpNPCType->armor_tint[index] = atoi(armorTint_row[index * 3]) << 16; - tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 1]) << 8; - tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 2]); - tmpNPCType->armor_tint[index] |= (tmpNPCType->armor_tint[index]) ? (0xFF << 24) : 0; - } - } - } else - armor_tint_id = 0; + for (int index = EmuConstants::MATERIAL_BEGIN; index <= EmuConstants::MATERIAL_END; index++) { + tmpNPCType->armor_tint[index] = atoi(armorTint_row[index * 3]) << 16; + tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 1]) << 8; + tmpNPCType->armor_tint[index] |= atoi(armorTint_row[index * 3 + 2]); + tmpNPCType->armor_tint[index] |= (tmpNPCType->armor_tint[index]) ? (0xFF << 24) : 0; + } + } + } else + armor_tint_id = 0; - tmpNPCType->AC = atoi(row[40]); - tmpNPCType->ATK = atoi(row[41]); - tmpNPCType->accuracy_rating = atoi(row[42]); - tmpNPCType->scalerate = RuleI(Mercs, ScaleRate); - tmpNPCType->spellscale = atoi(row[43]); - tmpNPCType->healscale = atoi(row[44]); + tmpNPCType->AC = atoi(row[40]); + tmpNPCType->ATK = atoi(row[41]); + tmpNPCType->accuracy_rating = atoi(row[42]); + tmpNPCType->scalerate = atoi(row[43]); + tmpNPCType->spellscale = atoi(row[44]); + tmpNPCType->healscale = atoi(row[45]); - // If Merc with duplicate NPC id already in table, - // free item we attempted to add. + // If Merc with duplicate NPC id already in table, + // free item we attempted to add. if (zone->merctable.find(merc_type_id) != zone->merctable.end()) { - delete tmpNPCType; - return nullptr; - } + delete tmpNPCType; + return nullptr; + } zone->merctable[merc_type_id] = tmpNPCType; - npc = tmpNPCType; - } + npc = tmpNPCType; + } return npc; } @@ -2998,6 +2999,14 @@ void ZoneDatabase::RemoveTempFactions(Client *client) { QueryDatabase(query); } +void ZoneDatabase::UpdateItemRecastTimestamps(uint32 char_id, uint32 recast_type, uint32 timestamp) +{ + std::string query = + StringFormat("REPLACE INTO character_item_recast (id, recast_type, timestamp) VALUES (%u, %u, %u)", char_id, + recast_type, timestamp); + QueryDatabase(query); +} + void ZoneDatabase::LoadPetInfo(Client *client) { // Load current pet and suspended pet @@ -3413,38 +3422,102 @@ void ZoneDatabase::MarkCorpseAsRezzed(uint32 db_id) { uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const glm::vec4& position) { /* Dump Basic Corpse Data */ - std::string query = StringFormat("INSERT INTO `character_corpses` " - "SET `charname` = '%s', `zone_id` = %u, `instance_id` = %u, `charid` = %d," - "`x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f," - "`time_of_death` = NOW(), `is_buried` = 0, `is_locked` = %d," - "`exp` = %u, `size` = %f, `level` = %u, `race` = %u, `gender` = %u," - "`class` = %u, `deity` = %u, `texture` = %u, `helm_texture` = %u," - "`copper` = %u, `silver` = %u,`gold` = %u,`platinum` = %u," - "`hair_color` = %u, `beard_color` = %u, `eye_color_1` = %u," - "`eye_color_2` = %u, `hair_style` = %u, `face` = %u," - "`beard` = %u, `drakkin_heritage` = %u, `drakkin_tattoo` = %u," - "`drakkin_details` = %u, `wc_1` = %u, `wc_2` = %u," - "`wc_3` = %u, `wc_4` = %u, `wc_5` = %u, `wc_6` = %u," - "`wc_7` = %u,`wc_8` = %u,`wc_9` = %u", - EscapeString(charname).c_str(), zoneid, instanceid, charid, - position.x, position.y, position.z, position.w, - dbpc->locked, dbpc->exp, dbpc->size, dbpc->level, dbpc->race, - dbpc->gender, dbpc->class_, dbpc->deity, dbpc->texture, - dbpc->helmtexture, dbpc->copper, dbpc->silver, dbpc->gold, - dbpc->plat, dbpc->haircolor, dbpc->beardcolor, dbpc->eyecolor1, - dbpc->eyecolor2, dbpc->hairstyle, dbpc->face, dbpc->beard, - dbpc->drakkin_heritage, dbpc->drakkin_tattoo, dbpc->drakkin_details, - dbpc->item_tint[0].color, dbpc->item_tint[1].color, dbpc->item_tint[2].color, - dbpc->item_tint[3].color, dbpc->item_tint[4].color, dbpc->item_tint[5].color, - dbpc->item_tint[6].color, dbpc->item_tint[7].color, dbpc->item_tint[8].color); + std::string query = StringFormat( + "INSERT INTO `character_corpses` " + "SET `charname` = '%s', " + "`zone_id` = %u, " + "`instance_id` = %u, " + "`charid` = %d, " + "`x` = %1.1f, " + "`y` = %1.1f, " + "`z` = %1.1f, " + "`heading` = %1.1f, " + "`time_of_death` = NOW(), " + "`is_buried` = 0, " + "`is_locked` = %d, " + "`exp` = %u, " + "`size` = %f, " + "`level` = %u, " + "`race` = %u, " + "`gender` = %u, " + "`class` = %u, " + "`deity` = %u, " + "`texture` = %u, " + "`helm_texture` = %u, " + "`copper` = %u, " + "`silver` = %u, " + "`gold` = %u, " + "`platinum` = %u, " + "`hair_color` = %u, " + "`beard_color` = %u, " + "`eye_color_1` = %u, " + "`eye_color_2` = %u, " + "`hair_style` = %u, " + "`face` = %u, " + "`beard` = %u, " + "`drakkin_heritage` = %u, " + "`drakkin_tattoo` = %u, " + "`drakkin_details` = %u, " + "`wc_1` = %u, " + "`wc_2` = %u, " + "`wc_3` = %u, " + "`wc_4` = %u, " + "`wc_5` = %u, " + "`wc_6` = %u, " + "`wc_7` = %u, " + "`wc_8` = %u, " + "`wc_9` = %u ", + EscapeString(charname).c_str(), + zoneid, + instanceid, + charid, + position.x, + position.y, + position.z, + position.w, + dbpc->locked, + dbpc->exp, + dbpc->size, + dbpc->level, + dbpc->race, + dbpc->gender, + dbpc->class_, + dbpc->deity, + dbpc->texture, + dbpc->helmtexture, + dbpc->copper, + dbpc->silver, + dbpc->gold, + dbpc->plat, + dbpc->haircolor, + dbpc->beardcolor, + dbpc->eyecolor1, + dbpc->eyecolor2, + dbpc->hairstyle, + dbpc->face, + dbpc->beard, + dbpc->drakkin_heritage, + dbpc->drakkin_tattoo, + dbpc->drakkin_details, + dbpc->item_tint[0].color, + dbpc->item_tint[1].color, + dbpc->item_tint[2].color, + dbpc->item_tint[3].color, + dbpc->item_tint[4].color, + dbpc->item_tint[5].color, + dbpc->item_tint[6].color, + dbpc->item_tint[7].color, + dbpc->item_tint[8].color + ); auto results = QueryDatabase(query); uint32 last_insert_id = results.LastInsertedID(); + std::string corpse_items_query; /* Dump Items from Inventory */ uint8 first_entry = 0; for (unsigned int i = 0; i < dbpc->itemcount; i++) { if (first_entry != 1){ - query = StringFormat("REPLACE INTO `character_corpse_items` \n" + corpse_items_query = StringFormat("REPLACE INTO `character_corpse_items` \n" " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n" " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", last_insert_id, @@ -3462,7 +3535,7 @@ uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, ui first_entry = 1; } else{ - query = query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", + corpse_items_query = corpse_items_query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", last_insert_id, dbpc->items[i].equip_slot, dbpc->items[i].item_id, @@ -3477,7 +3550,9 @@ uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, ui ); } } - auto sc_results = QueryDatabase(query); + if (!corpse_items_query.empty()) + QueryDatabase(corpse_items_query); + return last_insert_id; } diff --git a/zone/zonedb.h b/zone/zonedb.h index 5c3ed3d0e..5e1a55248 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -256,6 +256,7 @@ public: void LoadPetInfo(Client *c); void SavePetInfo(Client *c); void RemoveTempFactions(Client *c); + void UpdateItemRecastTimestamps(uint32 char_id, uint32 recast_type, uint32 timestamp); /* Character Data Loaders */ bool LoadCharacterFactionValues(uint32 character_id, faction_map & val_list);