diff --git a/changelog.txt b/changelog.txt index 98e1f0606..0b964c528 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,51 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 09/09/2014 == +demonstar55: Incrase Mob kick/bash timer by 3 + see: http://www.eqemulator.org/forums/showthread.php?t=38734 +demonstar55: Fix slow effect on NPC special attack reuse timers + see: http://www.eqemulator.org/forums/showthread.php?t=38734 +demonstar55: Slow fixes to bots! +demonstar55: Revamped how NPC attack rate is set + SQL: 2014_09_09_attack_delay.sql +demonstar55: Added attackdelay to #npcedit + +== 09/08/2014 == +demonstar55: Fix slow calc + see: http://www.eqemulator.org/forums/showthread.php?t=38734 + +== 09/07/2014 == +Akkadius: Fixed ROF Augment item dupe with not checking for available slots properly and adding items to the virtual instance + +== 09/06/2014 == +Uleat: Tweaked 'Smart' trading code to return main slots before sub slots in stackable and free space search processes. (If enough people ask for it, I'll add an optional rule to allow 'bag packing' - the original implementation behavior) + +== 09/05/2014 == +Uleat: Fix for cursor item loss when zoning. (Thanks to the other devs who traced and fixed the 'macro' issue!) +demonstar55: Fix size getting nuked with lua's SendIllusionPacket + +== 09/03/2014 == +Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor. +demonstar55: Added work around command to show numhits on your buffs (#shownumhits) +Uleat: Fix for timer issue introduced by Zone::ShutDown() fix. + +== 09/02/2014 == +Secrets: Identified OP_GuildPromote for RoF clients. +Secrets: Fixed promotion, demotion, transferring a leader and displaying of client ranks in the Rain of Fear client. The rain of fear client, as such, will only have 3 ranks like the other clients, but supports a theoretical 8 ranks later. +Secrets/Akkadius: Fixed an issue involving character name lookup in the new DB code. +demonstar55: crash fix checking DivineAura in hate_list.cpp +Secrets: Reverted some code that got in the main branch that shouldn't have gotten there. +Uleat: Changed #loc to report the same precision as /loc for Cartesians + +== 08/31/2014 == +KLS: Fixed a bug in fishing in S3D zones +KLS: Fixed a bug in turnins with new any abstraction +KLS: Fixed a few quest related inconsistencies. +KLS: Added Lua EntityList::ChannelMessage(from, type, msg, language) + +== 08/30/2014 == +demonstar55: (noudess) Merchants should be more descriptive of why they don't sell to you + == 08/26/2014 == Uleat: Implemented 'Smart' Player Trade transfers. Trades are processed by containers, stackables and then all remaining. QueryServ logs have been updated to match these transactions. Note: QueryServ logs previously listed 'Items' on the main entry table. This indicated the number of slots affected and not the actual number of items. diff --git a/client_files/export/main.cpp b/client_files/export/main.cpp index c4faa4718..e9b127aad 100644 --- a/client_files/export/main.cpp +++ b/client_files/export/main.cpp @@ -81,7 +81,9 @@ void ExportSpells(SharedDatabase *db) { line.push_back('^'); } - line += row[i]; + if(row[i] != nullptr) { + line += row[i]; + } } fprintf(f, "%s\n", line.c_str()); @@ -180,7 +182,9 @@ void ExportBaseData(SharedDatabase *db) { if(rowIndex != 0) line.push_back('^'); - line += row[rowIndex]; + if(row[rowIndex] != nullptr) { + line += row[rowIndex]; + } } fprintf(f, "%s\n", line.c_str()); diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f02212161..a6a25f612 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -93,6 +93,7 @@ SET(common_sources ) SET(common_headers + any.h base_packet.h base_data.h bodytypes.h diff --git a/common/any.h b/common/any.h new file mode 100644 index 000000000..fd80fbc5f --- /dev/null +++ b/common/any.h @@ -0,0 +1,190 @@ +/* + * Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +// EQEmu::Any is a modified version of Boost::Any and as such retains the Boost licensing. + +#ifndef EQEMU_COMMON_ANY_H +#define EQEMU_COMMON_ANY_H + +#include +#include + +namespace EQEmu +{ + class Any + { + public: + Any() + : content(nullptr) + { + } + + template + Any(const ValueType &value) + : content(new Holder(value)) + { + } + + Any(const Any &other) + : content(other.content ? other.content->clone() : 0) + { + } + + ~Any() + { + if(content) + delete content; + } + + Any& swap(Any &rhs) + { + std::swap(content, rhs.content); + return *this; + } + + template + Any& operator=(const ValueType &rhs) + { + Any(rhs).swap(*this); + return *this; + } + + Any& operator=(Any rhs) + { + rhs.swap(*this); + return *this; + } + + bool empty() const + { + return !content; + } + + const std::type_info& type() const + { + return content ? content->type() : typeid(void); + } + + class Placeholder + { + public: + virtual ~Placeholder() + { + } + + virtual const std::type_info& type() const = 0; + virtual Placeholder* clone() const = 0; + }; + + + template + class Holder : public Placeholder + { + public: + Holder(const ValueType &value) + : held(value) + { + } + + virtual const std::type_info& type() const + { + return typeid(ValueType); + } + + virtual Placeholder* clone() const + { + return new Holder(held); + } + + ValueType held; + + private: + Holder& operator=(const Holder&); + }; + + private: + template + friend ValueType* any_cast(Any*); + + template + friend ValueType* unsafe_any_cast(Any*); + + Placeholder* content; + }; + + class bad_any_cast : public std::bad_cast + { + public: + virtual const char * what() const throw() + { + return "DBI::bad_any_cast: failed conversion using DBI::any_cast"; + } + }; + + template + ValueType* any_cast(Any* operand) + { + return operand && + operand->type() == typeid(ValueType) ? &static_cast*>(operand->content)->held : nullptr; + } + + template + inline const ValueType* any_cast(const Any* operand) + { + return any_cast(const_cast(operand)); + } + + template + ValueType any_cast(Any& operand) + { + typedef typename std::remove_reference::type nonref; + nonref* result = any_cast(&operand); + if(!result) + throw bad_any_cast(); + return *result; + } + + template + inline ValueType any_cast(const Any& operand) + { + typedef typename std::remove_reference::type nonref; + return any_cast(const_cast(operand)); + } + + template + inline ValueType* unsafe_any_cast(Any* operand) + { + return &static_cast*>(operand->content)->held; + } + + template + inline const ValueType* unsafe_any_cast(const Any* operand) + { + return unsafe_any_cast(const_cast(operand)); + } +} + +#endif diff --git a/common/database.cpp b/common/database.cpp index 8d27d5b46..88f01a676 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -161,6 +161,9 @@ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStat return 0; } + if(results.RowCount() == 0) + return 0; + auto row = results.begin(); uint32 id = atoi(row[0]); @@ -316,7 +319,7 @@ bool Database::DeleteAccount(const char* name) { } bool Database::SetLocalPassword(uint32 accid, const char* password) { - std::string query = StringFormat("UPDATE account SET password=MD5('%s') where id=%i;", password, accid); + std::string query = StringFormat("UPDATE account SET password=MD5('%s') where id=%i;", EscapeString(password).c_str(), accid); auto results = QueryDatabase(query); @@ -768,7 +771,9 @@ void Database::GetCharName(uint32 char_id, char* name) { } auto row = results.begin(); - strcpy(name, row[0]); + for (auto row = results.begin(); row != results.end(); ++row) { + strcpy(name, row[0]); + } } bool Database::LoadVariables() { diff --git a/common/emu_oplist.h b/common/emu_oplist.h index edee551a1..c1ceb3c80 100644 --- a/common/emu_oplist.h +++ b/common/emu_oplist.h @@ -540,3 +540,4 @@ N(OP_OpenInventory), N(OP_OpenContainer), N(OP_Marquee), N(OP_ClientTimeStamp), +N(OP_GuildPromote), diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index d2fbcbb76..1751f4b4e 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -2287,10 +2287,13 @@ struct Stun_Struct { // 4 bytes total }; struct AugmentItem_Struct { -/*00*/ int16 container_slot; -/*02*/ char unknown02[2]; -/*04*/ int32 augment_slot; -/*08*/ +/*00*/ uint32 container_index; +/*04*/ int32 container_slot; +/*08*/ uint32 augment_index; +/*12*/ int32 augment_slot; +/*16*/ uint32 dest_inst_id; // The unique serial number for the item instance that is being augmented +/*20*/ int32 augment_action; // Guessed - 0 = augment, 1 = remove with distiller, 3 = delete aug +/*24*/ }; // OP_Emote @@ -4461,6 +4464,14 @@ struct GuildBankPromote_Struct /*12*/ uint32 Slot2; // Always appears to be the same as Slot for Action code 3 }; +struct GuildPromoteStruct { +/*000*/ char target[64]; +/*064*/ char name[64]; +/*128*/ uint32 rank; +/*132*/ uint32 myrank; +/*136*/ +}; + struct GuildBankPermissions_Struct { /*00*/ uint32 Action; // 6 diff --git a/common/eq_stream.cpp b/common/eq_stream.cpp index 61dc201be..8cb67e0e0 100644 --- a/common/eq_stream.cpp +++ b/common/eq_stream.cpp @@ -534,7 +534,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req) uint16 opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode); - _log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size); + //_log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size); if (!ack_req) { NonSequencedPush(new EQProtocolPacket(opcode, pack->pBuffer, pack->size)); diff --git a/common/guild_base.cpp b/common/guild_base.cpp index 8f6144270..6546918d0 100644 --- a/common/guild_base.cpp +++ b/common/guild_base.cpp @@ -474,6 +474,11 @@ bool BaseGuildManager::SetBankerFlag(uint32 charid, bool is_banker) { return(true); } +bool BaseGuildManager::ForceRankUpdate(uint32 charid) { + SendRankUpdate(charid); + return(true); +} + bool BaseGuildManager::SetAltFlag(uint32 charid, bool is_alt) { if(!DBSetAltFlag(charid, is_alt)) diff --git a/common/guild_base.h b/common/guild_base.h index 652db0bc8..b59244480 100644 --- a/common/guild_base.h +++ b/common/guild_base.h @@ -54,6 +54,7 @@ public: bool SetGuild(uint32 charid, uint32 guild_id, uint8 rank); bool SetGuildRank(uint32 charid, uint8 rank); bool SetBankerFlag(uint32 charid, bool is_banker); + bool ForceRankUpdate(uint32 charid); bool GetAltFlag(uint32 CharID); bool SetAltFlag(uint32 charid, bool is_alt); bool GetBankerFlag(uint32 CharID); diff --git a/common/item.cpp b/common/item.cpp index bbb6f14f8..513ddb23f 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -683,6 +683,13 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { if ((main_inst->GetID() == inst->GetID()) && (main_inst->GetCharges() < main_inst->GetItem()->StackSize)) return free_slot; + } + + for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) { + const ItemInst* main_inst = m_inv[free_slot]; + + if (!main_inst) + continue; if (main_inst->IsType(ItemClassContainer)) { // if item-specific containers already have bad items, we won't fix it here... for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) { @@ -732,8 +739,12 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { if (!main_inst) return free_slot; + } - if (main_inst->IsType(ItemClassContainer)) { + for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) { + const ItemInst* main_inst = m_inv[free_slot]; + + if (main_inst && main_inst->IsType(ItemClassContainer)) { if ((main_inst->GetItem()->BagSize < inst->GetItem()->Size) || (main_inst->GetItem()->BagType == BagTypeBandolier) || (main_inst->GetItem()->BagType == BagTypeQuiver)) continue; @@ -1569,6 +1580,16 @@ int8 ItemInst::AvailableAugmentSlot(int32 augtype) const return (i < EmuConstants::ITEM_COMMON_SIZE) ? i : INVALID_INDEX; } +bool ItemInst::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const { + if (m_item->ItemClass != ItemClassCommon || !m_item) + return false; + + if ((!GetItem(slot) && m_item->AugSlotVisible[slot]) && augtype == -1 || (m_item->AugSlotType[slot] && ((1 << (m_item->AugSlotType[slot] - 1)) & augtype))) { + return true; + } + return false; +} + // Retrieve item inside container ItemInst* ItemInst::GetItem(uint8 index) const { diff --git a/common/item.h b/common/item.h index f279bd2aa..c24c708b1 100644 --- a/common/item.h +++ b/common/item.h @@ -274,6 +274,7 @@ public: inline bool IsAugmentable() const { return m_item->AugSlotType[0]!=0 || m_item->AugSlotType[1]!=0 || m_item->AugSlotType[2]!=0 || m_item->AugSlotType[3]!=0 || m_item->AugSlotType[4]!=0; } bool AvailableWearSlot(uint32 aug_wear_slots) const; int8 AvailableAugmentSlot(int32 augtype) const; + bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const; inline int32 GetAugmentType() const { return m_item->AugType; } inline bool IsExpendable() const { return ((m_item->Click.Type == ET_Expendable ) || (m_item->ItemType == ItemTypePotion)); } diff --git a/common/logsys.h b/common/logsys.h index 3933e7062..84741cdb4 100644 --- a/common/logsys.h +++ b/common/logsys.h @@ -92,8 +92,8 @@ extern void log_raw_packet(LogType type, uint16 seq, const BasePacket *p); class Mob; extern void log_message_mob(LogType type, Mob *who, const char *fmt, ...); #define mlog( type, format, ...) \ - if(IsLoggingEnabled()) \ do { \ + if(IsLoggingEnabled()) \ if(log_type_info[ type ].enabled) { \ log_message_mob(type, this, format, ##__VA_ARGS__); \ } \ @@ -150,16 +150,16 @@ extern void log_raw_packet(LogType type, uint16 seq, const BasePacket *p); class Mob; extern void log_hex_mob(LogType type, Mob *who, const char *data, uint32 length); #define mhex( type, data, len) \ - if(IsLoggingEnabled()) \ do { \ + if(IsLoggingEnabled()) \ if(log_type_info[ type ].enabled) { \ log_hex_mob(type, this, data, len); \ } \ } while(false) extern void log_packet_mob(LogType type, Mob *who, const BasePacket *p); #define mpkt( type, packet) \ - if(IsLoggingEnabled()) \ do { \ + if(IsLoggingEnabled()) \ if(log_type_info[ type ].enabled) { \ log_packet_mob(type, this, packet); \ } \ diff --git a/common/mysql_request_result.h b/common/mysql_request_result.h index cd561be56..ab84eeb18 100644 --- a/common/mysql_request_result.h +++ b/common/mysql_request_result.h @@ -40,7 +40,7 @@ public: MySQLRequestResult& operator=(MySQLRequestResult&& other); bool Success() const { return m_Success;} - std::string ErrorMessage() const {return std::string(m_ErrorBuffer);} + std::string ErrorMessage() const {return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");} uint32 ErrorNumber() const {return m_ErrorNumber;} uint32 RowsAffected() const {return m_RowsAffected;} uint32 RowCount() const {return m_RowCount;} diff --git a/common/mysql_request_row.cpp b/common/mysql_request_row.cpp index ac5fa1592..9491fd1b2 100644 --- a/common/mysql_request_row.cpp +++ b/common/mysql_request_row.cpp @@ -64,6 +64,5 @@ bool MySQLRequestRow::operator!=(const MySQLRequestRow& rhs) char* MySQLRequestRow::operator[](int index) { - return m_MySQLRow[index]; } diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 90ff9ab9e..d5303ccfb 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -1,4 +1,3 @@ - #include "../debug.h" #include "rof.h" #include "../opcodemgr.h" @@ -1974,7 +1973,14 @@ ENCODE(OP_ZoneSpawns) else { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildID); - VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); + + /* Translate older ranks to new values */ + switch (emu->guildrank) { + case 0: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5); break; } // GUILD_MEMBER 0 + case 1: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 3); break; } // GUILD_OFFICER 1 + case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2 + default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } // + } } VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->class_); @@ -2406,7 +2412,15 @@ ENCODE(OP_GuildMemberList) { PutFieldN(level); PutFieldN(banker); PutFieldN(class_); - PutFieldN(rank); + + /* Translate older ranks to new values */ + switch (emu_e->rank) { + case 0: { e->rank = htonl(5); break; } // GUILD_MEMBER 0 + case 1: { e->rank = htonl(3); break; } // GUILD_OFFICER 1 + case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2 + default: { e->rank = htonl(emu_e->rank); break; } // GUILD_NONE + } + PutFieldN(time_last_on); PutFieldN(tribute_enable); e->unknown01 = 0; @@ -3330,7 +3344,15 @@ ENCODE(OP_SetGuildRank) ENCODE_LENGTH_EXACT(GuildSetRank_Struct); SETUP_DIRECT_ENCODE(GuildSetRank_Struct, structs::GuildSetRank_Struct); eq->GuildID = emu->Unknown00; - OUT(Rank); + + /* Translate older ranks to new values */ + switch (emu->Rank) { + case 0: { eq->Rank = 5; break; } // GUILD_MEMBER 0 + case 1: { eq->Rank = 3; break; } // GUILD_OFFICER 1 + case 2: { eq->Rank = 1; break; } // GUILD_LEADER 2 + default: { eq->Rank = emu->Rank; break; } + } + memcpy(eq->MemberName, emu->MemberName, sizeof(eq->MemberName)); OUT(Banker); eq->Unknown76 = 1; @@ -4660,8 +4682,11 @@ DECODE(OP_AugmentItem) { SETUP_DIRECT_DECODE(AugmentItem_Struct, structs::AugmentItem_Struct); emu->container_slot = RoFToServerSlot(eq->container_slot); - //emu->augment_slot = eq->augment_slot; - + emu->augment_slot = RoFToServerSlot(eq->augment_slot); + emu->container_index = eq->container_index; + emu->augment_index = eq->augment_index; + emu->dest_inst_id = eq->dest_inst_id; + emu->augment_action = eq->augment_action; FINISH_DIRECT_DECODE(); } @@ -5068,7 +5093,7 @@ char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint memset(&isbs, 0, sizeof(RoF::structs::ItemSecondaryBodyStruct)); isbs.augtype = item->AugType; - isbs.augdistiller = 0; + isbs.augdistiller = 65535; isbs.augrestrict = item->AugRestrict; diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index 918bbe68d..2d1b5ef18 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -2519,10 +2519,10 @@ struct Stun_Struct { // 8 bytes total struct AugmentItem_Struct { /*00*/ uint32 dest_inst_id; // The unique serial number for the item instance that is being augmented -/*04*/ uint32 unknown04; // Seen 0 +/*04*/ uint32 container_index; // Seen 0 /*08*/ ItemSlotStruct container_slot; // Slot of the item being augmented -/*20*/ uint32 unknown20; // Seen 0 -/*24*/ ItemSlotStruct distiller_slot; // Slot of the distiller to use (if one applies) +/*20*/ uint32 augment_index; // Seen 0 +/*24*/ ItemSlotStruct augment_slot; // Slot of the distiller to use (if one applies) /*36*/ int32 augment_action; // Guessed - 0 = augment, 1 = remove with distiller, 3 = delete aug /*36*/ //int32 augment_slot; /*40*/ diff --git a/common/ruletypes.h b/common/ruletypes.h index 73d538f8a..c61590ac4 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -212,10 +212,6 @@ RULE_REAL ( Map, FixPathingZMaxDeltaMoving, 20 ) //at runtime while pathing: max RULE_REAL ( Map, FixPathingZMaxDeltaWaypoint, 20 ) //at runtime at each waypoint: max change in Z to allow the BestZ code to apply. RULE_REAL ( Map, FixPathingZMaxDeltaSendTo, 20 ) //at runtime in SendTo: max change in Z to allow the BestZ code to apply. RULE_REAL ( Map, FixPathingZMaxDeltaLoading, 45 ) //while loading each waypoint: max change in Z to allow the BestZ code to apply. -RULE_BOOL ( Map, UseClosestZ, false) // Move mobs to the nearest Z above or below, rather than just the nearest below. - // Only set UseClosestZ true if all your .map files generated from EQGs were created - // with azone2. - // RULE_INT ( Map, FindBestZHeightAdjust, 1) // Adds this to the current Z before seeking the best Z position RULE_CATEGORY_END() diff --git a/common/shareddb.cpp b/common/shareddb.cpp index 8e999da54..10e3d2012 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -143,19 +143,22 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) { bool SharedDatabase::SaveCursor(uint32 char_id, std::list::const_iterator &start, std::list::const_iterator &end) { -iter_queue it; -int i; -bool ret=true; + iter_queue it; + int i; + bool ret = true; char errbuf[MYSQL_ERRMSG_SIZE]; char* query = 0; // Delete cursor items - if ((ret = RunQuery(query, MakeAnyLenString(&query, "DELETE FROM inventory WHERE charid=%i AND ( (slotid >=8000 and slotid<=8999) or slotid=%i or (slotid>=%i and slotid<=%i))", char_id, MainCursor,EmuConstants::CURSOR_BAG_BEGIN,EmuConstants::CURSOR_BAG_END), errbuf))) { - for(it=start,i=8000;it!=end;++it,i++) { - ItemInst *inst=*it; - if (!(ret=SaveInventory(char_id,inst,(i==8000) ? MainCursor : i))) + if ((ret = RunQuery(query, MakeAnyLenString(&query, "DELETE FROM inventory WHERE charid = %i AND ((slotid >= 8000 AND slotid <= 8999) OR slotid = %i OR (slotid >= %i AND slotid <= %i))", + char_id, MainCursor, EmuConstants::CURSOR_BAG_BEGIN, EmuConstants::CURSOR_BAG_END), errbuf))) { + + for (it = start, i = 8000; it != end; ++it, i++) { + ItemInst *inst = *it; + if (!(ret = SaveInventory(char_id, inst, (i == 8000) ? MainCursor : i))) break; } - } else { + } + else { std::cout << "Clearing cursor failed: " << errbuf << std::endl; } safe_delete_array(query); @@ -1632,6 +1635,13 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) { int tempid = 0; int counter = 0; + + if(result && mysql_field_count(getMySQL()) <= SPELL_LOAD_FIELD_COUNT) { + _log(SPELLS__LOAD_ERR, "Fatal error loading spells: Spell field count < SPELL_LOAD_FIELD_COUNT(%u)", SPELL_LOAD_FIELD_COUNT); + mysql_free_result(result); + return; + } + while (row = mysql_fetch_row(result)) { tempid = atoi(row[0]); if(tempid >= max_spells) { @@ -2138,7 +2148,8 @@ void SharedDatabase::SetPlayerInspectMessage(char* playername, const InspectMess char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET inspectmessage='%s' WHERE name='%s'", message->text, playername), errbuf)) { + std::string msg = EscapeString(message->text); + if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET inspectmessage='%s' WHERE name='%s'", msg.c_str(), playername), errbuf)) { std::cerr << "Error in SetPlayerInspectMessage query '" << query << "' " << errbuf << std::endl; } @@ -2173,7 +2184,8 @@ void SharedDatabase::SetBotInspectMessage(uint32 botid, const InspectMessage_Str char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE bots SET BotInspectMessage='%s' WHERE BotID=%i", message->text, botid), errbuf)) { + std::string msg = EscapeString(message->text); + if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE bots SET BotInspectMessage='%s' WHERE BotID=%i", msg.c_str(), botid), errbuf)) { std::cerr << "Error in SetBotInspectMessage query '" << query << "' " << errbuf << std::endl; } diff --git a/common/spdat.h b/common/spdat.h index 40f5e658f..2dfc016b4 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -621,6 +621,8 @@ typedef enum { // number. note that the id field is counted as 0, this way the numbers // here match the numbers given to sep in the loading function net.cpp // +#define SPELL_LOAD_FIELD_COUNT 231 + struct SPDat_Spell_Struct { /* 000 */ int id; // not used diff --git a/loginserver/database_postgreSQL.cpp b/loginserver/database_postgresql.cpp similarity index 100% rename from loginserver/database_postgreSQL.cpp rename to loginserver/database_postgresql.cpp diff --git a/tests/string_util_test.h b/tests/string_util_test.h index 374878065..32efb5320 100644 --- a/tests/string_util_test.h +++ b/tests/string_util_test.h @@ -42,7 +42,7 @@ public: float f = 3.1416; auto s = StringFormat(fmt, c, i, f); - TEST_ASSERT(s.length() == 17); + TEST_ASSERT_EQUALS(s.length(), 17); TEST_ASSERT(s.compare("Test: a 2014 3.14") == 0); } diff --git a/ucs/database.cpp b/ucs/database.cpp index d3c44174c..a2f61c438 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -522,10 +522,11 @@ void Database::ExpireMail() { query = StringFormat("DELETE FROM `mail` WHERE `status`=4 AND `timestamp` < %i", time(nullptr) - RuleI(Mail, ExpireTrash)); results = QueryDatabase(query); - if(!results.Success()) - _log(UCS__INIT, "Expired %i trash messages.", results.RowsAffected()); + if(results.Success()) + _log(UCS__ERROR, "Error expiring trash messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); else - _log(UCS__ERROR, "Error expiring trash messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); + _log(UCS__INIT, "Expired %i trash messages.", results.RowsAffected()); + } // Expire Read @@ -533,7 +534,7 @@ void Database::ExpireMail() { query = StringFormat("DELETE FROM `mail` WHERE `status` = 3 AND `timestamp` < %i", time(nullptr) - RuleI(Mail, ExpireRead)); results = QueryDatabase(query); - if(!results.Success()) + if(results.Success()) _log(UCS__INIT, "Expired %i read messages.", results.RowsAffected()); else _log(UCS__ERROR, "Error expiring read messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); @@ -544,7 +545,7 @@ void Database::ExpireMail() { query = StringFormat("DELETE FROM `mail` WHERE `status`=1 AND `timestamp` < %i", time(nullptr) - RuleI(Mail, ExpireUnread)); results = QueryDatabase(query); - if(!results.Success()) + if(results.Success()) _log(UCS__INIT, "Expired %i unread messages.", results.RowsAffected()); else _log(UCS__ERROR, "Error expiring unread messages, %s %s", query.c_str(), results.ErrorMessage().c_str()); diff --git a/utils/patches/patch_RoF.conf b/utils/patches/patch_RoF.conf index c4e0b7955..50bfd5580 100644 --- a/utils/patches/patch_RoF.conf +++ b/utils/patches/patch_RoF.conf @@ -125,6 +125,7 @@ OP_GuildLeader=0x7c6f OP_GuildDelete=0x241b OP_GuildInviteAccept=0x78a5 OP_GuildDemote=0x3100 +OP_GuildPromote=0x2945 OP_GuildPublicNote=0x3c2c OP_GuildManageBanker=0x096d # Was 0x0737 OP_GuildBank=0x2ab0 # Was 0x10c3 diff --git a/utils/scripts/opcode_handlers.py b/utils/scripts/opcode_handlers.py index 6cad4ade0..ce0e955a3 100644 --- a/utils/scripts/opcode_handlers.py +++ b/utils/scripts/opcode_handlers.py @@ -23,8 +23,8 @@ VERBOSE = False # messaging: {False - minimal, True - robust} base_path = os.getcwd()[:-14] # '/utils/scripts' base_path = base_path.replace('\\', '/') -client_list = ['6.2', 'Titanium', 'SoF', 'SoD', 'Underfoot', 'RoF', 'RoF2', 'ClientTest'] -server_list = ['Login', 'World', 'Zone', 'UCS', 'ServerTest'] +client_list = ['6.2', 'Titanium', 'SoF', 'SoD', 'Underfoot', 'RoF', 'RoF2'] +server_list = ['Login', 'World', 'Zone', 'UCS'] client_opcodes = {} # x[key='Client'][key='OP_CodeName'](value='0x####') server_opcodes = {} # x[key='OP_CodeName'](value=) - opcodes apply to all servers @@ -248,7 +248,7 @@ def loadclientopcodes(): for client in client_list: try: - short_name = '/patch_{0}.conf'.format(client) + short_name = '/patch_{0}.conf'.format(client).lower() file_name = '{0}/utils/patches{1}'.format( base_path, @@ -455,9 +455,9 @@ def loadclienttranslators(): for client in client_list: try: if client == '6.2': - short_name = '/Client62_ops.h' + short_name = '/client62_ops.h' else: - short_name = '/{0}_ops.h'.format(client) + short_name = '/{0}_ops.h'.format(client).lower() file_name = '{0}/common/patches{1}'.format( base_path, @@ -734,15 +734,15 @@ def discoverserverhandlers(): locations[server] = [] if 'Login' in locations: - locations['Login'].append('/loginserver/Client.cpp') - locations['Login'].append('/loginserver/ServerManager.cpp') - locations['Login'].append('/loginserver/WorldServer.cpp') + locations['Login'].append('/loginserver/client.cpp') + locations['Login'].append('/loginserver/server_manager.cpp') + locations['Login'].append('/loginserver/world_server.cpp') if 'World' in locations: locations['World'].append('/world/client.cpp') if 'Zone' in locations: - locations['Zone'].append('/zone/AA.cpp') + locations['Zone'].append('/zone/aa.cpp') locations['Zone'].append('/zone/attack.cpp') locations['Zone'].append('/zone/bot.cpp') locations['Zone'].append('/zone/client.cpp') @@ -762,8 +762,8 @@ def discoverserverhandlers(): locations['Zone'].append('/zone/loottables.cpp') locations['Zone'].append('/zone/merc.cpp') locations['Zone'].append('/zone/mob.cpp') - locations['Zone'].append('/zone/MobAI.cpp') - locations['Zone'].append('/zone/Object.cpp') + locations['Zone'].append('/zone/mob_ai.cpp') + locations['Zone'].append('/zone/object.cpp') locations['Zone'].append('/zone/pathing.cpp') locations['Zone'].append('/zone/petitions.cpp') locations['Zone'].append('/zone/questmgr.cpp') diff --git a/utils/sql/git/queryserv/required/Complete_QueryServ_Rules_Disabled.sql b/utils/sql/git/optional/2014_08_23_Complete_QueryServ_Rules_Disabled.sql similarity index 100% rename from utils/sql/git/queryserv/required/Complete_QueryServ_Rules_Disabled.sql rename to utils/sql/git/optional/2014_08_23_Complete_QueryServ_Rules_Disabled.sql diff --git a/utils/sql/git/queryserv/required/Complete_QueryServ_Rules_Enabled.sql b/utils/sql/git/optional/2014_08_23_Complete_QueryServ_Rules_Enabled.sql similarity index 100% rename from utils/sql/git/queryserv/required/Complete_QueryServ_Rules_Enabled.sql rename to utils/sql/git/optional/2014_08_23_Complete_QueryServ_Rules_Enabled.sql diff --git a/utils/sql/git/queryserv/required/Complete_QueryServ_Table_Structures.sql b/utils/sql/git/required/2014_08_23_Complete_QueryServ_Table_Structures.sql similarity index 100% rename from utils/sql/git/queryserv/required/Complete_QueryServ_Table_Structures.sql rename to utils/sql/git/required/2014_08_23_Complete_QueryServ_Table_Structures.sql diff --git a/utils/sql/git/queryserv/required/08_23_2014_player_events_and_player_aa_rate_hourly.sql b/utils/sql/git/required/2014_08_23_player_events_and_player_aa_rate_hourly.sql similarity index 100% rename from utils/sql/git/queryserv/required/08_23_2014_player_events_and_player_aa_rate_hourly.sql rename to utils/sql/git/required/2014_08_23_player_events_and_player_aa_rate_hourly.sql diff --git a/utils/sql/git/required/2014_09_09_attack_delay.sql b/utils/sql/git/required/2014_09_09_attack_delay.sql new file mode 100644 index 000000000..87efa043a --- /dev/null +++ b/utils/sql/git/required/2014_09_09_attack_delay.sql @@ -0,0 +1,3 @@ +ALTER TABLE `npc_types` ADD `attack_delay` TINYINT(3) UNSIGNED DEFAULT '30' NOT NULL AFTER `attack_speed`; +UPDATE `npc_types` SET `attack_delay` = 36 + 36 * (`attack_speed` / 100); +UPDATE `npc_types` SET `attack_delay` = 30 WHERE `attack_speed` = 0; diff --git a/world/adventure_manager.cpp b/world/adventure_manager.cpp index 047aca326..05337e0ad 100644 --- a/world/adventure_manager.cpp +++ b/world/adventure_manager.cpp @@ -715,7 +715,7 @@ bool AdventureManager::LoadAdventureEntries() std::list temp; auto iter = adventure_entries.find(id); - if(iter == adventure_entries.end()) + if(iter != adventure_entries.end()) temp = adventure_entries[id]; temp.push_back(tid); diff --git a/zone/attack.cpp b/zone/attack.cpp index 5abba347b..62d9f8de9 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -4803,3 +4803,145 @@ void Mob::CommonBreakInvisible() hidden = false; improved_hidden = false; } + +void Mob::SetAttackTimer() +{ + attack_timer.SetAtTrigger(4000, true); +} + +void Client::SetAttackTimer() +{ + float PermaHaste = GetPermaHaste(); + + //default value for attack timer in case they have + //an invalid weapon equipped: + attack_timer.SetAtTrigger(4000, true); + + Timer *TimerToUse = nullptr; + const Item_Struct *PrimaryWeapon = nullptr; + + for (int i = MainRange; i <= MainSecondary; i++) { + //pick a timer + if (i == MainPrimary) + TimerToUse = &attack_timer; + else if (i == MainRange) + TimerToUse = &ranged_timer; + else if (i == MainSecondary) + TimerToUse = &attack_dw_timer; + else //invalid slot (hands will always hit this) + continue; + + const Item_Struct *ItemToUse = nullptr; + + //find our item + ItemInst *ci = GetInv().GetItem(i); + if (ci) + ItemToUse = ci->GetItem(); + + //special offhand stuff + if (i == MainSecondary) { + //if we have a 2H weapon in our main hand, no dual + if (PrimaryWeapon != nullptr) { + if (PrimaryWeapon->ItemClass == ItemClassCommon + && (PrimaryWeapon->ItemType == ItemType2HSlash + || PrimaryWeapon->ItemType == ItemType2HBlunt + || PrimaryWeapon->ItemType == ItemType2HPiercing)) { + attack_dw_timer.Disable(); + continue; + } + } + + //if we cant dual wield, skip it + if (!CanThisClassDualWield()) { + attack_dw_timer.Disable(); + continue; + } + } + + //see if we have a valid weapon + if (ItemToUse != nullptr) { + //check type and damage/delay + if (ItemToUse->ItemClass != ItemClassCommon + || ItemToUse->Damage == 0 + || ItemToUse->Delay == 0) { + //no weapon + ItemToUse = nullptr; + } + // Check to see if skill is valid + else if ((ItemToUse->ItemType > ItemTypeLargeThrowing) && + (ItemToUse->ItemType != ItemTypeMartial) && + (ItemToUse->ItemType != ItemType2HPiercing)) { + //no weapon + ItemToUse = nullptr; + } + } + + int16 DelayMod = std::max(itembonuses.HundredHands + spellbonuses.HundredHands, -99); + int speed = 0; + + //if we have no weapon.. + if (ItemToUse == nullptr) { + //above checks ensure ranged weapons do not fall into here + // Work out if we're a monk + if ((GetClass() == MONK) || (GetClass() == BEASTLORD)) + speed = static_cast((GetMonkHandToHandDelay() * (100 + DelayMod) / 100) * PermaHaste); + else + speed = static_cast((36 * (100 + DelayMod) / 100) * PermaHaste); + } else { + //we have a weapon, use its delay + // Convert weapon delay to timer resolution (milliseconds) + //delay * 100 + speed = static_cast((ItemToUse->Delay * (100 + DelayMod) / 100) * PermaHaste); + if (ItemToUse->ItemType == ItemTypeBow || ItemToUse->ItemType == ItemTypeLargeThrowing) { + float quiver_haste = GetQuiverHaste(); + if (quiver_haste > 0) + speed *= quiver_haste; + } + } + TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true); + + if (i == MainPrimary) + PrimaryWeapon = ItemToUse; + } +} + +void NPC::SetAttackTimer() +{ + float PermaHaste = GetPermaHaste(); + + //default value for attack timer in case they have + //an invalid weapon equipped: + attack_timer.SetAtTrigger(4000, true); + + Timer *TimerToUse = nullptr; + + for (int i = MainRange; i <= MainSecondary; i++) { + //pick a timer + if (i == MainPrimary) + TimerToUse = &attack_timer; + else if (i == MainRange) + TimerToUse = &ranged_timer; + else if (i == MainSecondary) + TimerToUse = &attack_dw_timer; + else //invalid slot (hands will always hit this) + continue; + + //special offhand stuff + if (i == MainSecondary) { + //NPCs get it for free at 13 + if(GetLevel() < 13) { + attack_dw_timer.Disable(); + continue; + } + } + + int16 DelayMod = std::max(itembonuses.HundredHands + spellbonuses.HundredHands, -99); + + // Technically NPCs should do some logic for weapons, but the effect is minimal + // What they do is take the lower of their set delay and the weapon's + // ex. Mob's delay set to 20, weapon set to 19, delay 19 + // Mob's delay set to 20, weapon set to 21, delay 20 + int speed = static_cast((attack_delay * (100 + DelayMod) / 100) * PermaHaste); + TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true); + } +} diff --git a/zone/bot.cpp b/zone/bot.cpp index e782e6db8..d001a0b88 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -8350,12 +8350,10 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) { return; float HasteModifier = 0; - if(GetHaste() >= 0){ + if (GetHaste()) HasteModifier = 10000 / (100 + GetHaste()); - } - else { - HasteModifier = (100 - GetHaste()); - } + else + HasteModifier = 100; int32 dmg = 0; uint16 skill_to_use = -1; @@ -8981,10 +8979,8 @@ int32 Bot::CalcMaxMana() { void Bot::SetAttackTimer() { float PermaHaste; - if(GetHaste() > 0) + if (GetHaste()) PermaHaste = 1 / (1 + (float)GetHaste()/100); - else if(GetHaste() < 0) - PermaHaste = 1 * (1 - (float)GetHaste()/100); else PermaHaste = 1.0f; @@ -11741,8 +11737,6 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) { if(!strcasecmp(sep->arg[1], "augmentitem")) { AugmentItem_Struct* in_augment = new AugmentItem_Struct[sizeof(AugmentItem_Struct)]; in_augment->container_slot = 1000; // - in_augment->unknown02[0] = 0; - in_augment->unknown02[1] = 0; in_augment->augment_slot = -1; Object::HandleAugmentation(c, in_augment, c->GetTradeskillObject()); return; diff --git a/zone/client.cpp b/zone/client.cpp index 37740b472..90f26ff18 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7773,29 +7773,67 @@ int32 Client::GetModCharacterFactionLevel(int32 faction_id) { return Modded; } -bool Client::HatedByClass(uint32 p_race, uint32 p_class, uint32 p_deity, int32 pFaction) +void Client::MerchantRejectMessage(Mob *merchant, int primaryfaction) { + int messageid = 0; + int32 tmpFactionValue = 0; + int32 lowestvalue = 0; + FactionMods fmod; - bool Result = false; - - int32 tmpFactionValue; - FactionMods fmods; - - //First get the NPC's Primary faction - if(pFaction > 0) - { - //Get the faction data from the database - if(database.GetFactionData(&fmods, p_class, p_race, p_deity, pFaction)) - { - tmpFactionValue = GetCharacterFactionLevel(pFaction); - tmpFactionValue += GetFactionBonus(pFaction); - tmpFactionValue += GetItemFactionBonus(pFaction); - CalculateFaction(&fmods, tmpFactionValue); - if(fmods.class_mod < fmods.race_mod) - Result = true; + // If a faction is involved, get the data. + if (primaryfaction > 0) { + if (database.GetFactionData(&fmod, GetClass(), GetRace(), GetDeity(), primaryfaction)) { + tmpFactionValue = GetCharacterFactionLevel(primaryfaction); + lowestvalue = std::min(tmpFactionValue, std::min(fmod.class_mod, fmod.race_mod)); } } - return Result; + // If no primary faction or biggest influence is your faction hit + if (primaryfaction <= 0 || lowestvalue == tmpFactionValue) { + merchant->Say_StringID(MakeRandomInt(WONT_SELL_DEEDS1, WONT_SELL_DEEDS6)); + } else if (lowestvalue == fmod.race_mod) { // race biggest + // Non-standard race (ex. illusioned to wolf) + if (GetRace() > PLAYER_RACE_COUNT) { + messageid = MakeRandomInt(1, 3); // these aren't sequential StringIDs :( + switch (messageid) { + case 1: + messageid = WONT_SELL_NONSTDRACE1; + break; + case 2: + messageid = WONT_SELL_NONSTDRACE2; + break; + case 3: + messageid = WONT_SELL_NONSTDRACE3; + break; + default: // w/e should never happen + messageid = WONT_SELL_NONSTDRACE1; + break; + } + merchant->Say_StringID(messageid); + } else { // normal player races + messageid = MakeRandomInt(1, 4); + switch (messageid) { + case 1: + messageid = WONT_SELL_RACE1; + break; + case 2: + messageid = WONT_SELL_RACE2; + break; + case 3: + messageid = WONT_SELL_RACE3; + break; + case 4: + messageid = WONT_SELL_RACE4; + break; + default: // w/e should never happen + messageid = WONT_SELL_RACE1; + break; + } + merchant->Say_StringID(messageid, itoa(GetRace())); + } + } else if (lowestvalue == fmod.class_mod) { + merchant->Say_StringID(MakeRandomInt(WONT_SELL_CLASS1, WONT_SELL_CLASS5), itoa(GetClass())); + } + return; } //o-------------------------------------------------------------- @@ -7940,7 +7978,7 @@ void Client::ItemTimerCheck() TryItemTimer(i); } - for(i = EmuConstants::GENERAL_BAGS_BEGIN; i <= MainCursor; i++) + for(i = EmuConstants::GENERAL_BEGIN; i <= MainCursor; i++) { TryItemTimer(i); } @@ -8296,3 +8334,31 @@ void Client::ExpeditionSay(const char *str, int ExpID) { mysql_free_result(result); } + +void Client::ShowNumHits() +{ + uint32 buffcount = GetMaxTotalSlots(); + for (uint32 buffslot = 0; buffslot < buffcount; buffslot++) { + const Buffs_Struct &curbuff = buffs[buffslot]; + if (curbuff.spellid != SPELL_UNKNOWN && curbuff.numhits) + Message(0, "You have %d hits left on %s", curbuff.numhits, GetSpellName(curbuff.spellid)); + } + return; +} + +float Client::GetQuiverHaste() +{ + float quiver_haste = 0; + for (int r = EmuConstants::GENERAL_BEGIN; r <= EmuConstants::GENERAL_END; r++) { + const ItemInst *pi = GetInv().GetItem(r); + if (!pi) + continue; + if (pi->IsType(ItemClassContainer) && pi->GetItem()->BagType == BagTypeQuiver) { + float temp_wr = (pi->GetItem()->BagWR / RuleI(Combat, QuiverWRHasteDiv)); + quiver_haste = std::max(temp_wr, quiver_haste); + } + } + if (quiver_haste > 0) + quiver_haste = 1.0f / (1.0f + static_cast(quiver_haste) / 100.0f); + return quiver_haste; +} diff --git a/zone/client.h b/zone/client.h index d3aed5540..697e4e2d3 100644 --- a/zone/client.h +++ b/zone/client.h @@ -222,6 +222,8 @@ public: virtual Group* GetGroup() { return entity_list.GetGroupByClient(this); } virtual inline bool IsBerserk() { return berserk; } virtual int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating); + virtual void SetAttackTimer(); + float GetQuiverHaste(); void AI_Init(); void AI_Start(uint32 iMoveDelay = 0); @@ -594,7 +596,7 @@ public: FACTION_VALUE GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 p_race, uint32 p_class, uint32 p_deity, int32 pFaction, Mob* tnpc); int32 GetCharacterFactionLevel(int32 faction_id); int32 GetModCharacterFactionLevel(int32 faction_id); - bool HatedByClass(uint32 p_race, uint32 p_class, uint32 p_deity, int32 pFaction); + void MerchantRejectMessage(Mob *merchant, int primaryfaction); void SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 totalvalue, uint8 temp); void SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, uint8 char_race, uint8 char_deity); @@ -1194,13 +1196,15 @@ public: int32 mod_client_xp(int32 in_exp, NPC *npc); uint32 mod_client_xp_for_level(uint32 xp, uint16 check_level); int mod_client_haste_cap(int cap); - int mod_consume(Item_Struct *item, ItemUseTypes type, int change); - int mod_food_value(const Item_Struct *item, int change); - int mod_drink_value(const Item_Struct *item, int change); + int mod_consume(Item_Struct *item, ItemUseTypes type, int change); + int mod_food_value(const Item_Struct *item, int change); + int mod_drink_value(const Item_Struct *item, int change); void SetEngagedRaidTarget(bool value) { EngagedRaidTarget = value; } bool GetEngagedRaidTarget() const { return EngagedRaidTarget; } - + + void ShowNumHits(); // work around function for numhits not showing on buffs + protected: friend class Mob; void CalcItemBonuses(StatBonuses* newbon); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 91d99490f..9d7c9e01d 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -190,6 +190,7 @@ void MapOpcodes() { ConnectedOpcodes[OP_GuildWar] = &Client::Handle_OP_GuildWar; ConnectedOpcodes[OP_GuildLeader] = &Client::Handle_OP_GuildLeader; ConnectedOpcodes[OP_GuildDemote] = &Client::Handle_OP_GuildDemote; + ConnectedOpcodes[OP_GuildPromote] = &Client::Handle_OP_GuildPromote; ConnectedOpcodes[OP_GuildInvite] = &Client::Handle_OP_GuildInvite; ConnectedOpcodes[OP_GuildRemove] = &Client::Handle_OP_GuildRemove; ConnectedOpcodes[OP_GetGuildMOTD] = &Client::Handle_OP_GetGuildMOTD; @@ -433,7 +434,7 @@ int Client::HandlePacket(const EQApplicationPacket *app) case CLIENT_CONNECTING: { if(ConnectingOpcodes.count(opcode) != 1) { //Hate const cast but everything in lua needs to be non-const even if i make it non-mutable - std::vector args; + std::vector args; args.push_back(const_cast(app)); parse->EventPlayer(EVENT_UNHANDLED_OPCODE, this, "", 1, &args); @@ -462,7 +463,7 @@ int Client::HandlePacket(const EQApplicationPacket *app) ClientPacketProc p; p = ConnectedOpcodes[opcode]; if(p == nullptr) { - std::vector args; + std::vector args; args.push_back(const_cast(app)); parse->EventPlayer(EVENT_UNHANDLED_OPCODE, this, "", 0, &args); @@ -4088,7 +4089,7 @@ void Client::Handle_OP_GuildLeader(const EQApplicationPacket *app) GuildMakeLeader* gml=(GuildMakeLeader*)app->pBuffer; if (!IsInAGuild()) Message(0, "Error: You arent in a guild!"); - else if (!guild_mgr.IsGuildLeader(GuildID(), CharacterID())) + else if (GuildRank() != GUILD_LEADER) Message(0, "Error: You arent the guild leader!"); else if (!worldserver.Connected()) Message(0, "Error: World server disconnected"); @@ -4169,6 +4170,57 @@ void Client::Handle_OP_GuildDemote(const EQApplicationPacket *app) return; } + +void Client::Handle_OP_GuildPromote(const EQApplicationPacket *app) +{ + mlog(GUILDS__IN_PACKETS, "Received OP_GuildPromote"); + mpkt(GUILDS__IN_PACKET_TRACE, app); + + if(app->size != sizeof(GuildPromoteStruct)) { + mlog(GUILDS__ERROR, "Error: app size of %i != size of GuildDemoteStruct of %i\n",app->size,sizeof(GuildPromoteStruct)); + return; + } + + if (!IsInAGuild()) + Message(0, "Error: You arent in a guild!"); + else if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_PROMOTE)) + Message(0, "You dont have permission to invite."); + else if (!worldserver.Connected()) + Message(0, "Error: World server disconnected"); + else { + GuildPromoteStruct* promote = (GuildPromoteStruct*)app->pBuffer; + + CharGuildInfo gci; + if(!guild_mgr.GetCharInfo(promote->target, gci)) { + Message(0, "Unable to find '%s'", promote->target); + return; + } + if(gci.guild_id != GuildID()) { + Message(0, "You aren't in the same guild, what do you think you are doing?"); + return; + } + + uint8 rank = gci.rank + 1; + + if(rank > GUILD_OFFICER) + return; + + + mlog(GUILDS__ACTIONS, "Promoting %s (%d) from rank %s (%d) to %s (%d) in %s (%d)", + promote->target, gci.char_id, + guild_mgr.GetRankName(GuildID(), gci.rank), gci.rank, + guild_mgr.GetRankName(GuildID(), rank), rank, + guild_mgr.GetGuildName(GuildID()), GuildID()); + + if(!guild_mgr.SetGuildRank(gci.char_id, rank)) { + Message(13, "Error while setting rank %d on '%s'.", rank, promote->target); + return; + } + Message(0, "Successfully promoted %s to rank %d", promote->target, rank); + } + return; +} + void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app) { mlog(GUILDS__IN_PACKETS, "Received OP_GuildInvite"); @@ -4379,6 +4431,16 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app) GuildInviteAccept_Struct* gj = (GuildInviteAccept_Struct*) app->pBuffer; + if(GetClientVersion() >= EQClientRoF) + { + if(gj->response > 9) + { + //dont care if the check fails (since we dont know the rank), just want to clear the entry. + guild_mgr.VerifyAndClearInvite(CharacterID(), gj->guildeqid, gj->response); + worldserver.SendEmoteMessage(gj->inviter, 0, 0, "%s has declined to join the guild.", this->GetName()); + return; + } + } if (gj->response == 5 || gj->response == 4) { //dont care if the check fails (since we dont know the rank), just want to clear the entry. guild_mgr.VerifyAndClearInvite(CharacterID(), gj->guildeqid, gj->response); @@ -4424,15 +4486,24 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app) guild_mgr.GetGuildName(gj->guildeqid), gj->guildeqid, gj->response); - //change guild and rank. - if(!guild_mgr.SetGuild(CharacterID(), gj->guildeqid, gj->response)) { + //change guild and rank + + uint32 guildrank = gj->response; + + if(GetClientVersion() == EQClientRoF) + { + if(gj->response == 8) + { + guildrank = 0; + } + } + + if(!guild_mgr.SetGuild(CharacterID(), gj->guildeqid, guildrank)) { Message(13, "There was an error during the invite, DB may now be inconsistent."); return; } if(zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks) GuildBanks->SendGuildBank(this); - SendGuildRanks(); - } } } @@ -5426,36 +5497,15 @@ void Client::Handle_OP_ShopRequest(const EQApplicationPacket *app) Message(0,"You cannot use a merchant right now."); action = 0; } - int factionlvl = GetFactionLevel(CharacterID(), tmp->CastToNPC()->GetNPCTypeID(), GetRace(), GetClass(), GetDeity(), tmp->CastToNPC()->GetPrimaryFaction(), tmp); - if(factionlvl >= 7) - { - char playerp[16] = "players"; - if(HatedByClass(GetRace(), GetClass(), GetDeity(), tmp->CastToNPC()->GetPrimaryFaction())) - strcpy(playerp,GetClassPlural(this)); - else - strcpy(playerp,GetRacePlural(this)); + int primaryfaction = tmp->CastToNPC()->GetPrimaryFaction(); + int factionlvl = GetFactionLevel(CharacterID(), tmp->CastToNPC()->GetNPCTypeID(), GetRace(), GetClass(), GetDeity(), primaryfaction, tmp); + if (factionlvl >= 7) { + MerchantRejectMessage(tmp, primaryfaction); + action = 0; + } - uint8 rand_ = rand() % 4; - switch(rand_){ - case 1: - Message(0,"%s says 'It's not enough that you %s have ruined your own lands. Now get lost!'", tmp->GetCleanName(), playerp); - break; - case 2: - Message(0,"%s says 'I have something here that %s use... let me see... it's the EXIT, now get LOST!'", tmp->GetCleanName(), playerp); - break; - case 3: - Message(0,"%s says 'Don't you %s have your own merchants? Whatever, I'm not selling anything to you!'", tmp->GetCleanName(), playerp); - break; - default: - Message(0,"%s says 'I don't like to speak to %s much less sell to them!'", tmp->GetCleanName(), playerp); - break; - } - action = 0; - } if (tmp->Charmed()) - { action = 0; - } // 1199 I don't have time for that now. etc if (!tmp->CastToNPC()->IsMerchantOpen()) { @@ -6016,7 +6066,7 @@ void Client::Handle_OP_ClickObject(const EQApplicationPacket *app) object->HandleClick(this, click_object); - std::vector args; + std::vector args; args.push_back(object); char buf[10]; @@ -6231,7 +6281,145 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) // Delegate to tradeskill object to perform combine AugmentItem_Struct* in_augment = (AugmentItem_Struct*)app->pBuffer; - Object::HandleAugmentation(this, in_augment, m_tradeskill_object); + bool deleteItems = false; + if(GetClientVersion() >= EQClientRoF) + { + ItemInst *itemOneToPush = nullptr, *itemTwoToPush = nullptr; + + //Message(15, "%i %i %i %i %i %i", in_augment->container_slot, in_augment->augment_slot, in_augment->container_index, in_augment->augment_index, in_augment->augment_action, in_augment->dest_inst_id); + + // Adding augment + if (in_augment->augment_action == 0) + { + ItemInst *tobe_auged, *auged_with = nullptr; + int8 slot=-1; + Inventory& user_inv = GetInv(); + + uint16 slot_id = in_augment->container_slot; + uint16 aug_slot_id = in_augment->augment_slot; + //Message(13, "%i AugSlot", aug_slot_id); + if(slot_id == INVALID_INDEX || aug_slot_id == INVALID_INDEX) + { + Message(13, "Error: Invalid Aug Index."); + return; + } + + tobe_auged = user_inv.GetItem(slot_id); + auged_with = user_inv.GetItem(MainCursor); + + if (tobe_auged && auged_with) + { + if (((tobe_auged->IsAugmentSlotAvailable(auged_with->GetAugmentType(), in_augment->augment_index)) != -1) && + (tobe_auged->AvailableWearSlot(auged_with->GetItem()->Slots))) + { + tobe_auged->PutAugment(in_augment->augment_index, *auged_with); + + ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_index); + if(aug) { + std::vector args; + args.push_back(aug); + parse->EventItem(EVENT_AUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args); + + args.assign(1, tobe_auged); + parse->EventItem(EVENT_AUGMENT_INSERT, this, aug, nullptr, "", in_augment->augment_index, &args); + } + else + { + Message(13, "Error: Could not find augmentation at index %i. Aborting.", in_augment->augment_index); + return; + } + + itemOneToPush = tobe_auged->Clone(); + // Must push items after the items in inventory are deleted - necessary due to lore items... + if (itemOneToPush) + { + DeleteItemInInventory(slot_id, 0, true); + DeleteItemInInventory(MainCursor, 0, true); + if(PutItemInInventory(slot_id, *itemOneToPush, true)) + { + //Message(13, "Sucessfully added an augment to your item!"); + return; + } + else + { + Message(13, "Error: No available slot for end result. Please free up some bag space."); + } + } + else + { + Message(13, "Error in cloning item for augment. Aborted."); + } + + } + else + { + Message(13, "Error: No available slot for augment in that item."); + } + } + } + else if(in_augment->augment_action == 1) + { + ItemInst *tobe_auged, *auged_with = nullptr; + int8 slot=-1; + Inventory& user_inv = GetInv(); + + uint16 slot_id = in_augment->container_slot; + uint16 aug_slot_id = in_augment->augment_slot; //it's actually solvent slot + if(slot_id == INVALID_INDEX || aug_slot_id == INVALID_INDEX) + { + Message(13, "Error: Invalid Aug Index."); + return; + } + + tobe_auged = user_inv.GetItem(slot_id); + auged_with = user_inv.GetItem(aug_slot_id); + + ItemInst *old_aug = nullptr; + if(!auged_with) + return; + const uint32 id = auged_with->GetID(); + ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_index); + if(aug) { + std::vector args; + args.push_back(aug); + parse->EventItem(EVENT_UNAUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args); + + args.assign(1, tobe_auged); + + args.push_back(false); + + parse->EventItem(EVENT_AUGMENT_REMOVE, this, aug, nullptr, "", in_augment->augment_index, &args); + } + else + { + Message(13, "Error: Could not find augmentation at index %i. Aborting."); + return; + } + old_aug = tobe_auged->RemoveAugment(in_augment->augment_index); + + itemOneToPush = tobe_auged->Clone(); + if (old_aug) + itemTwoToPush = old_aug->Clone(); + if(itemOneToPush && itemTwoToPush && auged_with) + { + DeleteItemInInventory(slot_id, 0, true); + DeleteItemInInventory(aug_slot_id, auged_with->IsStackable() ? 1 : 0, true); + if(!PutItemInInventory(slot_id, *itemOneToPush, true)) + { + Message(15, "Shouldn't happen, contact an admin!"); + } + + if(PutItemInInventory(MainCursor, *itemTwoToPush, true)) + { + //Message(15, "Successfully removed an augmentation!"); + } + } + } + } + else + { + Object::HandleAugmentation(this, in_augment, m_tradeskill_object); + } return; } @@ -6246,13 +6434,13 @@ void Client::Handle_OP_ClickDoor(const EQApplicationPacket *app) if(!currentdoor) { Message(0,"Unable to find door, please notify a GM (DoorID: %i).",cd->doorid); - return; + return; } char buf[20]; snprintf(buf, 19, "%u", cd->doorid); buf[19] = '\0'; - std::vector args; + std::vector args; args.push_back(currentdoor); parse->EventPlayer(EVENT_CLICK_DOOR, this, buf, 0, &args); @@ -9322,8 +9510,18 @@ void Client::CompleteConnect() { UpdateAdmin(false); if (IsInAGuild()){ + uint8 rank = GuildRank(); + if(GetClientVersion() >= EQClientRoF) + { + switch (rank) { + case 0: { rank = 5; break; } // GUILD_MEMBER 0 + case 1: { rank = 3; break; } // GUILD_OFFICER 1 + case 2: { rank = 1; break; } // GUILD_LEADER 2 + default: { break; } // GUILD_NONE + } + } SendAppearancePacket(AT_GuildID, GuildID(), false); - SendAppearancePacket(AT_GuildRank, GuildRank(), false); + SendAppearancePacket(AT_GuildRank, rank, false); } for (uint32 spellInt = 0; spellInt < MAX_PP_SPELLBOOK; spellInt++) { diff --git a/zone/client_packet.h b/zone/client_packet.h index 1b687edb9..424a8f78f 100644 --- a/zone/client_packet.h +++ b/zone/client_packet.h @@ -90,6 +90,7 @@ void Handle_OP_GuildWar(const EQApplicationPacket *app); void Handle_OP_GuildLeader(const EQApplicationPacket *app); void Handle_OP_GuildDemote(const EQApplicationPacket *app); + void Handle_OP_GuildPromote(const EQApplicationPacket *app); void Handle_OP_GuildInvite(const EQApplicationPacket *app); void Handle_OP_GuildRemove(const EQApplicationPacket *app); void Handle_OP_GetGuildMOTD(const EQApplicationPacket *app); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index e39cef0bd..61f4936c8 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -836,8 +836,6 @@ void Client::BulkSendInventoryItems() { } } - // Where are cursor buffer items processed? They need to be validated as well... -U - bool deletenorent = database.NoRentExpired(GetName()); if(deletenorent){ RemoveNoRent(false); } //client was offline for more than 30 minutes, delete no rent items diff --git a/zone/command.cpp b/zone/command.cpp index b14a173bc..cf180f2bd 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -453,7 +453,8 @@ int command_init(void) { command_add("merchant_open_shop", "Opens a merchants shop", 100, command_merchantopenshop) || command_add("open_shop", nullptr, 100, command_merchantopenshop) || command_add("merchant_close_shop", "Closes a merchant shop", 100, command_merchantcloseshop) || - command_add("close_shop", nullptr, 100, command_merchantcloseshop) + command_add("close_shop", nullptr, 100, command_merchantcloseshop) || + command_add("shownumhits", "Shows buffs numhits for yourself.", 0, command_shownumhits) ) { command_deinit(); @@ -4692,7 +4693,7 @@ void command_loc(Client *c, const Seperator *sep) { Mob *t=c->GetTarget()?c->GetTarget():c->CastToMob(); - c->Message(0, "%s's Location (XYZ): %1.1f, %1.1f, %1.1f; heading=%1.1f", t->GetName(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); + c->Message(0, "%s's Location (XYZ): %1.2f, %1.2f, %1.2f; heading=%1.1f", t->GetName(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); } void command_goto(Client *c, const Seperator *sep) @@ -6657,6 +6658,7 @@ void command_npcedit(Client *c, const Seperator *sep) c->Message(0, "#npcedit qglobal - Sets an NPC's quest global flag"); c->Message(0, "#npcedit limit - Sets an NPC's spawn limit counter"); c->Message(0, "#npcedit Attackspeed - Sets an NPC's attack speed modifier"); + c->Message(0, "#npcedit Attackdelay - Sets an NPC's attack delay"); c->Message(0, "#npcedit findable - Sets an NPC's findable flag"); c->Message(0, "#npcedit wep1 - Sets an NPC's primary weapon model"); c->Message(0, "#npcedit wep2 - Sets an NPC's secondary weapon model"); @@ -6767,7 +6769,7 @@ void command_npcedit(Client *c, const Seperator *sep) char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; c->Message(15,"NPCID %u now regens %i hitpoints per tick.",c->GetTarget()->CastToNPC()->GetNPCTypeID(),atoi(sep->arg[2])); - database.RunQuery(query, MakeAnyLenString(&query, "update npc_types set hp_regen_rate=%i where hp_regen_rate=%i",atoi(sep->argplus[2]),c->GetTarget()->CastToNPC()->GetNPCTypeID()), errbuf); + database.RunQuery(query, MakeAnyLenString(&query, "update npc_types set hp_regen_rate=%i where id=%i",atoi(sep->argplus[2]),c->GetTarget()->CastToNPC()->GetNPCTypeID()), errbuf); c->LogSQL(query); safe_delete_array(query); } @@ -7158,6 +7160,15 @@ void command_npcedit(Client *c, const Seperator *sep) c->LogSQL(query); safe_delete_array(query); } + else if ( strcasecmp( sep->arg[1], "Attackdelay" ) == 0 ) + { + char errbuf[MYSQL_ERRMSG_SIZE]; + char *query = 0; + c->Message(15,"NPCID %u now has attack_delay set to %i",c->GetTarget()->CastToNPC()->GetNPCTypeID(),atoi(sep->arg[2])); + database.RunQuery(query, MakeAnyLenString(&query, "update npc_types set attack_delay=%i where id=%i",atoi(sep->argplus[2]),c->GetTarget()->CastToNPC()->GetNPCTypeID()), errbuf); + c->LogSQL(query); + safe_delete_array(query); + } else if ( strcasecmp( sep->arg[1], "findable" ) == 0 ) { char errbuf[MYSQL_ERRMSG_SIZE]; @@ -11429,8 +11440,6 @@ void command_augmentitem(Client *c, const Seperator *sep) AugmentItem_Struct* in_augment = new AugmentItem_Struct[sizeof(AugmentItem_Struct)]; in_augment->container_slot = 1000; // - in_augment->unknown02[0] = 0; - in_augment->unknown02[1] = 0; in_augment->augment_slot = -1; if(c->GetTradeskillObject() != nullptr) Object::HandleAugmentation(c, in_augment, c->GetTradeskillObject()); @@ -11557,3 +11566,9 @@ void command_merchantcloseshop(Client *c, const Seperator *sep) merchant->CastToNPC()->MerchantCloseShop(); } + +void command_shownumhits(Client *c, const Seperator *sep) +{ + c->ShowNumHits(); + return; +} diff --git a/zone/command.h b/zone/command.h index 6a880625e..4846dd09d 100644 --- a/zone/command.h +++ b/zone/command.h @@ -325,6 +325,7 @@ void command_showspellslist(Client *c, const Seperator *sep); void command_npctype_cache(Client *c, const Seperator *sep); void command_merchantopenshop(Client *c, const Seperator *sep); void command_merchantcloseshop(Client *c, const Seperator *sep); +void command_shownumhits(Client *c, const Seperator *sep); #ifdef EQPROFILE void command_profiledump(Client *c, const Seperator *sep); diff --git a/zone/corpse.cpp b/zone/corpse.cpp index aa7841a64..da9ffab17 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -1164,7 +1164,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) strcpy(corpse_name, orgname); snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(), EntityList::RemoveNumbers(corpse_name)); buf[87] = '\0'; - std::vector args; + std::vector args; args.push_back(inst); args.push_back(this); parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args); diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 8c4a82f55..c7a67c388 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -154,7 +154,7 @@ void PerlembParser::ReloadQuests() { } int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob, - uint32 extradata, bool global, std::vector *extra_pointers) + uint32 extradata, bool global, std::vector *extra_pointers) { if(!perl) return 0; @@ -211,32 +211,32 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da } int PerlembParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, false, extra_pointers); } int PerlembParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, true, extra_pointers); } int PerlembParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, false, extra_pointers); } int PerlembParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, true, extra_pointers); } int PerlembParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, item->GetID(), nullptr, nullptr, item, client, extra_data, false, extra_pointers); } int PerlembParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { return EventCommon(evt, 0, itoa(spell_id), npc, nullptr, client, extra_data, false, extra_pointers); } @@ -1114,7 +1114,7 @@ void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob) { #undef HASITEM_ISNULLITEM void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data, - NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector *extra_pointers) + NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector *extra_pointers) { switch (event) { case EVENT_SAY: { @@ -1130,8 +1130,10 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID case EVENT_TRADE: { if(extra_pointers) { - for(size_t i = 0; i < extra_pointers->size(); ++i) { - ItemInst *inst = reinterpret_cast(extra_pointers->at(i)); + size_t sz = extra_pointers->size(); + for(size_t i = 0; i < sz; ++i) { + ItemInst *inst = EQEmu::any_cast(extra_pointers->at(i)); + std::string var_name = "item"; var_name += std::to_string(static_cast(i + 1)); diff --git a/zone/embparser.h b/zone/embparser.h index 3cb3a57f7..1357ae20b 100644 --- a/zone/embparser.h +++ b/zone/embparser.h @@ -45,17 +45,17 @@ public: ~PerlembParser(); virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual bool HasQuestSub(uint32 npcid, QuestEventID evt); virtual bool HasGlobalQuestSub(QuestEventID evt); @@ -86,7 +86,7 @@ private: void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value); int EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob, - uint32 extradata, bool global, std::vector *extra_pointers); + uint32 extradata, bool global, std::vector *extra_pointers); int SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst *iteminst); void MapFunctions(); @@ -103,7 +103,7 @@ private: void ExportZoneVariables(std::string &package_name); void ExportItemVariables(std::string &package_name, Mob *mob); void ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data, - NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector *extra_pointers); + NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector *extra_pointers); std::map npc_quest_status_; PerlQuestStatus global_npc_quest_status_; diff --git a/zone/entity.cpp b/zone/entity.cpp index 2ca3f640d..7054ba8a1 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1476,7 +1476,7 @@ void EntityList::QueueClientsStatus(Mob *sender, const EQApplicationPacket *app, void EntityList::DuelMessage(Mob *winner, Mob *loser, bool flee) { if (winner->GetLevelCon(winner->GetLevel(), loser->GetLevel()) > 2) { - std::vector args; + std::vector args; args.push_back(winner); args.push_back(loser); @@ -2847,7 +2847,7 @@ void EntityList::ClearFeignAggro(Mob *targ) } if (targ->IsClient()) { - std::vector args; + std::vector args; args.push_back(it->second); int i = parse->EventPlayer(EVENT_FEIGN_DEATH, targ->CastToClient(), "", 0, &args); if (i != 0) { @@ -3242,9 +3242,10 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z) for (auto iter = events.begin(); iter != events.end(); ++iter) { quest_proximity_event& evt = (*iter); if (evt.npc) { - parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0); + std::vector args; + parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0, &args); } else { - std::vector args; + std::vector args; args.push_back(&evt.area_id); args.push_back(&evt.area_type); parse->EventPlayer(evt.event_id, evt.client, "", 0, &args); @@ -3298,7 +3299,7 @@ void EntityList::ProcessMove(NPC *n, float x, float y, float z) for (auto iter = events.begin(); iter != events.end(); ++iter) { quest_proximity_event& evt = (*iter); - std::vector args; + std::vector args; args.push_back(&evt.area_id); args.push_back(&evt.area_type); parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0, &args); diff --git a/zone/forage.cpp b/zone/forage.cpp index aaa3451d5..d1008031a 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -235,7 +235,7 @@ bool Client::CanFish() { dest.y = RodY; dest.z = z_pos+10; - RodZ = zone->zonemap->FindBestZ(dest, nullptr) - 1; + RodZ = zone->zonemap->FindBestZ(dest, nullptr) + 4; bool in_lava = zone->watermap->InLava(RodX, RodY, RodZ); bool in_water = zone->watermap->InWater(RodX, RodY, RodZ) || zone->watermap->InVWater(RodX, RodY, RodZ); //Message(0, "Rod is at %4.3f, %4.3f, %4.3f, InWater says %d, InLava says %d", RodX, RodY, RodZ, in_water, in_lava); @@ -355,11 +355,13 @@ void Client::GoFish() safe_delete(inst); inst = m_inv.GetItem(MainCursor); } - } - std::vector args; - args.push_back(inst); - parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst != nullptr ? inst->GetItem()->ID : 0, &args); + if(inst) { + std::vector args; + args.push_back(inst); + parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst->GetID(), &args); + } + } } else { @@ -469,11 +471,13 @@ void Client::ForageItem(bool guarantee) { safe_delete(inst); inst = m_inv.GetItem(MainCursor); } - } - std::vector args; - args.push_back(inst); - parse->EventPlayer(EVENT_FORAGE_SUCCESS, this, "", inst ? inst->GetItem()->ID : 0, &args); + if(inst) { + std::vector args; + args.push_back(inst); + parse->EventPlayer(EVENT_FORAGE_SUCCESS, this, "", inst->GetID(), &args); + } + } int ChanceSecondForage = aabonuses.ForageAdditionalItems + itembonuses.ForageAdditionalItems + spellbonuses.ForageAdditionalItems; if(!guarantee && MakeRandomInt(0,99) < ChanceSecondForage) { diff --git a/zone/groups.cpp b/zone/groups.cpp index 5c34cf359..c73b8f093 100644 --- a/zone/groups.cpp +++ b/zone/groups.cpp @@ -561,6 +561,18 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender) } } + /* This may seem pointless but the case above does not cover the following situation: + * Group has Leader a, member b, member c + * b and c are out of zone + * a disconnects/quits + * b or c zone back in and disconnects/quits + * a is still "leader" from GetLeader()'s perspective and will crash the zone when we DelMember(b) + * Ultimately we should think up a better solution to this. + */ + if(oldmember == GetLeader()) { + SetLeader(nullptr); + } + ServerPacket* pack = new ServerPacket(ServerOP_GroupLeave, sizeof(ServerGroupLeave_Struct)); ServerGroupLeave_Struct* gl = (ServerGroupLeave_Struct*)pack->pBuffer; gl->gid = GetID(); diff --git a/zone/guild.cpp b/zone/guild.cpp index 92635c185..6512bedec 100644 --- a/zone/guild.cpp +++ b/zone/guild.cpp @@ -160,9 +160,17 @@ void Client::SendGuildSpawnAppearance() { uint8 rank = guild_mgr.GetDisplayedRank(GuildID(), GuildRank(), CharacterID()); mlog(GUILDS__OUT_PACKETS, "Sending spawn appearance for guild %d at rank %d", GuildID(), rank); SendAppearancePacket(AT_GuildID, GuildID()); + if(GetClientVersion() >= EQClientRoF) + { + switch (rank) { + case 0: { rank = 5; break; } // GUILD_MEMBER 0 + case 1: { rank = 3; break; } // GUILD_OFFICER 1 + case 2: { rank = 1; break; } // GUILD_LEADER 2 + default: { break; } // GUILD_NONE + } + } SendAppearancePacket(AT_GuildRank, rank); } - UpdateWho(); } diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 37cc7a3de..cc23d14c9 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -374,6 +374,10 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) { else if(c != nullptr && s->guild_id != GUILD_NONE) { //char is in zone, and has changed into a new guild, send MOTD. c->SendGuildMOTD(); + if(c->GetClientVersion() >= EQClientRoF) + { + c->SendGuildRanks(); + } } @@ -686,19 +690,26 @@ bool GuildBankManager::Load(uint32 guildID) else whoFor[0] = '\0'; - if(slot < 0 || - ((area != GuildBankMainArea || slot >= GUILD_BANK_MAIN_AREA_SIZE) || - (area == GuildBankMainArea || slot >= GUILD_BANK_DEPOSIT_AREA_SIZE))) + if(slot < 0) continue; - bank->Items.MainArea[slot].ItemID = itemID; - bank->Items.MainArea[slot].Quantity = qty; + GuildBankItem *itemSection = nullptr; - strn0cpy(bank->Items.MainArea[slot].Donator, donator, sizeof(donator)); + if (area == GuildBankMainArea && slot < GUILD_BANK_MAIN_AREA_SIZE) + itemSection = bank->Items.MainArea; + else if (area != GuildBankMainArea && slot < GUILD_BANK_DEPOSIT_AREA_SIZE) + itemSection = bank->Items.DepositArea; + else + continue; - bank->Items.MainArea[slot].Permissions = permissions; + itemSection[slot].ItemID = itemID; + itemSection[slot].Quantity = qty; - strn0cpy(bank->Items.MainArea[slot].WhoFor, whoFor, sizeof(whoFor)); + strn0cpy(itemSection[slot].Donator, donator, sizeof(donator)); + + itemSection[slot].Permissions = permissions; + + strn0cpy(itemSection[slot].WhoFor, whoFor, sizeof(whoFor)); } Banks.push_back(bank); diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 86b20d313..f26615877 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -163,7 +163,7 @@ Mob* HateList::GetClosest(Mob *hater) { ++iterator; } - if (close == 0 && hater->IsNPC() || close->DivineAura()) + if ((!close && hater->IsNPC()) || (close && close->DivineAura())) close = hater->CastToNPC()->GetHateTop(); return close; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 197841c76..a4625bf80 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -2002,11 +2002,10 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) { } void Client::RemoveNoRent(bool client_update) { + int16 slot_id = 0; - int16 slot_id; - - // personal - for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) { + // equipment + for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) { const ItemInst* inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); @@ -2014,11 +2013,22 @@ void Client::RemoveNoRent(bool client_update) { } } + // general + for (slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; slot_id++) { + const ItemInst* inst = m_inv[slot_id]; + if (inst && !inst->GetItem()->NoRent) { + mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + DeleteItemInInventory(slot_id, 0, client_update); + } + } + // power source - const ItemInst* inst = m_inv[MainPowerSource]; - if(inst && !inst->GetItem()->NoRent) { - mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, MainPowerSource); - DeleteItemInInventory(MainPowerSource, 0, (GetClientVersion() >= EQClientSoF) ? client_update : false); // Ti slot non-existent + if (m_inv[MainPowerSource]) { + const ItemInst* inst = m_inv[MainPowerSource]; + if (inst && !inst->GetItem()->NoRent) { + mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, MainPowerSource); + DeleteItemInInventory(MainPowerSource, 0, (GetClientVersion() >= EQClientSoF) ? client_update : false); // Ti slot non-existent + } } // containers @@ -2065,15 +2075,42 @@ void Client::RemoveNoRent(bool client_update) { DeleteItemInInventory(slot_id, 0, false); // Can't delete from client Shared Bank Container slots } } + + // cursor & limbo + if (!m_inv.CursorEmpty()) { + std::list local; + ItemInst* inst = nullptr; + + while (!m_inv.CursorEmpty()) { + inst = m_inv.PopItem(MainCursor); + if (inst) + local.push_back(inst); + } + + std::list::iterator iter = local.begin(); + while (iter != local.end()) { + inst = *iter; + if (!inst->GetItem()->NoRent) + mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from `Limbo`", inst->GetItem()->Name); + else + m_inv.PushCursor(**iter); + + safe_delete(*iter); + iter = local.erase(iter); + } + + std::list::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + database.SaveCursor(this->CharacterID(), s, e); + local.clear(); + } } // Two new methods to alleviate perpetual login desyncs void Client::RemoveDuplicateLore(bool client_update) { - // Split-charge stacking may be added at some point -U - int16 slot_id; + int16 slot_id = 0; - // personal - for(slot_id = MAIN_BEGIN; slot_id < EmuConstants::MAP_POSSESSIONS_SIZE; slot_id++) { + // equipment + for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) { ItemInst* inst = m_inv.PopItem(slot_id); if(inst) { if(CheckLoreConflict(inst->GetItem())) { @@ -2087,17 +2124,34 @@ void Client::RemoveDuplicateLore(bool client_update) { } } + // general + for (slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; slot_id++) { + ItemInst* inst = m_inv.PopItem(slot_id); + if (inst) { + if (CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + database.SaveInventory(character_id, nullptr, slot_id); + } + else { + m_inv.PutItem(slot_id, *inst); + } + safe_delete(inst); + } + } + // power source - ItemInst* inst = m_inv.PopItem(MainPowerSource); - if(inst) { - if(CheckLoreConflict(inst->GetItem())) { - mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); - database.SaveInventory(character_id, nullptr, MainPowerSource); + if (m_inv[MainPowerSource]) { + ItemInst* inst = m_inv.PopItem(MainPowerSource); + if (inst) { + if (CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + database.SaveInventory(character_id, nullptr, MainPowerSource); + } + else { + m_inv.PutItem(MainPowerSource, *inst); + } + safe_delete(inst); } - else { - m_inv.PutItem(MainPowerSource, *inst); - } - safe_delete(inst); } // containers @@ -2146,11 +2200,56 @@ void Client::RemoveDuplicateLore(bool client_update) { } // Shared Bank and Shared Bank Containers are not checked due to their allowing duplicate lore items -U + + // cursor & limbo + if (!m_inv.CursorEmpty()) { + std::list local; + ItemInst* inst = nullptr; + + while (!m_inv.CursorEmpty()) { + inst = m_inv.PopItem(MainCursor); + if (inst) + local.push_back(inst); + } + + std::list::iterator iter = local.begin(); + while (iter != local.end()) { + inst = *iter; + if (CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from `Limbo`", inst->GetItem()->Name); + safe_delete(*iter); + iter = local.erase(iter); + } + else { + ++iter; + } + } + + iter = local.begin(); + while (iter != local.end()) { + inst = *iter; + if (!inst->GetItem()->LoreFlag || + ((inst->GetItem()->LoreGroup == -1) && (m_inv.HasItem(inst->GetID(), 0, invWhereCursor) == INVALID_INDEX)) || + (inst->GetItem()->LoreGroup && ~inst->GetItem()->LoreGroup && (m_inv.HasItemByLoreGroup(inst->GetItem()->LoreGroup, invWhereCursor) == INVALID_INDEX))) { + + m_inv.PushCursor(**iter); + } + else { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from `Limbo`", inst->GetItem()->Name); + } + + safe_delete(*iter); + iter = local.erase(iter); + } + + std::list::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + database.SaveCursor(this->CharacterID(), s, e); + local.clear(); + } } void Client::MoveSlotNotAllowed(bool client_update) { - - int16 slot_id; + int16 slot_id = 0; // equipment for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) { diff --git a/zone/lua_entity_list.cpp b/zone/lua_entity_list.cpp index 32bd9a89d..eace84a69 100644 --- a/zone/lua_entity_list.cpp +++ b/zone/lua_entity_list.cpp @@ -416,6 +416,11 @@ void Lua_EntityList::SignalAllClients(int signal) { self->SignalAllClients(signal); } +void Lua_EntityList::ChannelMessage(Lua_Mob from, int channel_num, int language, const char *message) { + Lua_Safe_Call_Void(); + self->ChannelMessage(from, channel_num, language, message); +} + luabind::scope lua_register_entity_list() { return luabind::class_("EntityList") .def(luabind::constructor<>()) @@ -479,7 +484,8 @@ luabind::scope lua_register_entity_list() { .def("GetObjectList", (Lua_Object_List(Lua_EntityList::*)(void))&Lua_EntityList::GetObjectList) .def("GetDoorsList", (Lua_Doors_List(Lua_EntityList::*)(void))&Lua_EntityList::GetDoorsList) .def("GetSpawnList", (Lua_Spawn_List(Lua_EntityList::*)(void))&Lua_EntityList::GetSpawnList) - .def("SignalAllClients", (void(Lua_EntityList::*)(int))&Lua_EntityList::SignalAllClients); + .def("SignalAllClients", (void(Lua_EntityList::*)(int))&Lua_EntityList::SignalAllClients) + .def("ChannelMessage", (void(Lua_EntityList::*)(Lua_Mob,int,int,const char*))&Lua_EntityList::ChannelMessage); } luabind::scope lua_register_mob_list() { diff --git a/zone/lua_entity_list.h b/zone/lua_entity_list.h index dc9c1a5ed..823499f24 100644 --- a/zone/lua_entity_list.h +++ b/zone/lua_entity_list.h @@ -106,6 +106,7 @@ public: Lua_Doors_List GetDoorsList(); Lua_Spawn_List GetSpawnList(); void SignalAllClients(int signal); + void ChannelMessage(Lua_Mob from, int channel_num, int language, const char *message); }; #endif diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 878f82225..ccb35f479 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -1451,11 +1451,7 @@ luabind::scope lua_register_slot() { luabind::value("General6", static_cast(MainGeneral6)), luabind::value("General7", static_cast(MainGeneral7)), luabind::value("General8", static_cast(MainGeneral8)), - //luabind::value("General9", static_cast(MainGeneral9)), - //luabind::value("General10", static_cast(MainGeneral10)), luabind::value("Cursor", static_cast(MainCursor)), - //luabind::value("EquipmentBegin", static_cast(EmuConstants::EQUIPMENT_BEGIN)), - //luabind::value("EquipmentEnd", static_cast(EmuConstants::EQUIPMENT_END)), luabind::value("PersonalBegin", static_cast(EmuConstants::GENERAL_BEGIN)), // deprecated luabind::value("GeneralBegin", static_cast(EmuConstants::GENERAL_BEGIN)), luabind::value("PersonalEnd", static_cast(EmuConstants::GENERAL_END)), // deprecated @@ -1483,7 +1479,6 @@ luabind::scope lua_register_material() { luabind::value("Secondary", static_cast(MaterialSecondary)), luabind::value("Max", static_cast(_MaterialCount)), // deprecated luabind::value("Count", static_cast(_MaterialCount)), - //luabind::value("TintCount", static_cast(_MaterialCount - 2)), luabind::value("Invalid", static_cast(_MaterialInvalid)) ]; } @@ -1498,8 +1493,7 @@ luabind::scope lua_register_client_version() { luabind::value("SoF", static_cast(EQClientSoF)), luabind::value("SoD", static_cast(EQClientSoD)), luabind::value("Underfoot", static_cast(EQClientUnderfoot)), - luabind::value("RoF", static_cast(EQClientRoF))//, - //luabind::value("RoF2", static_cast(EQClientRoF2)) + luabind::value("RoF", static_cast(EQClientRoF)) ]; } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 9f082993c..1de119afa 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -220,7 +220,7 @@ LuaParser::~LuaParser() { } int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -239,7 +239,7 @@ int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, } int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -257,7 +257,7 @@ int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string } int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func) { + std::vector *extra_pointers, luabind::adl::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -316,7 +316,7 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M } int LuaParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -334,7 +334,7 @@ int LuaParser::EventPlayer(QuestEventID evt, Client *client, std::string data, u } int LuaParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -352,7 +352,7 @@ int LuaParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string d } int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func) { + std::vector *extra_pointers, luabind::adl::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -409,7 +409,7 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client * } int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -429,7 +429,7 @@ int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob * } int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, Mob *mob, - std::string data, uint32 extra_data, std::vector *extra_pointers, luabind::adl::object *l_func) { + std::string data, uint32 extra_data, std::vector *extra_pointers, luabind::adl::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -492,7 +492,7 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl } int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -508,7 +508,7 @@ int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spe } int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func) { + std::vector *extra_pointers, luabind::adl::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -572,7 +572,7 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, return 0; } -int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, std::vector *extra_pointers) { +int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -588,7 +588,7 @@ int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint } int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); @@ -972,7 +972,7 @@ void LuaParser::MapFunctions(lua_State *L) { } int LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -1018,7 +1018,7 @@ int LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::stri } int LuaParser::DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -1047,7 +1047,7 @@ int LuaParser::DispatchEventPlayer(QuestEventID evt, Client *client, std::string } int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; @@ -1093,7 +1093,7 @@ int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *ite } int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { evt = ConvertLuaEvent(evt); if(evt >= _LargestEventID) { return 0; diff --git a/zone/lua_parser.h b/zone/lua_parser.h index 732f7d235..13cebe0fc 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -28,19 +28,19 @@ public: ~LuaParser(); virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt); virtual bool HasGlobalQuestSub(QuestEventID evt); @@ -65,25 +65,25 @@ public: virtual uint32 GetIdentifier() { return 0xb0712acc; } virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); private: int _EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); + std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); int _EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); + std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); int _EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, - uint32 extra_data, std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); + uint32 extra_data, std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); int _EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); + std::vector *extra_pointers, luabind::adl::object *l_func = nullptr); int _EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void LoadScript(std::string filename, std::string package_name); bool HasFunction(std::string function, std::string package_name); diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 56e5d236d..89f08a81f 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -27,7 +27,7 @@ //NPC void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { npc->DoQuestPause(init); Lua_Client l_client(reinterpret_cast(init)); @@ -43,7 +43,7 @@ void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *in } void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Client l_client(reinterpret_cast(init)); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); @@ -54,9 +54,12 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob * ident << npc->GetNPCTypeID(); if(extra_pointers) { - for(size_t i = 0; i < extra_pointers->size(); ++i) { + size_t sz = extra_pointers->size(); + for(size_t i = 0; i < sz; ++i) { std::string prefix = "item" + std::to_string(static_cast(i + 1)); - Lua_ItemInst l_inst = reinterpret_cast(extra_pointers->at(i)); + ItemInst *inst = EQEmu::any_cast(extra_pointers->at(i)); + + Lua_ItemInst l_inst = inst; luabind::adl::object l_inst_o = luabind::adl::object(L, l_inst); l_inst_o.push(L); @@ -79,7 +82,7 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob * } void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(extra_data == 1) { lua_pushinteger(L, -1); lua_setfield(L, -2, "hp_event"); @@ -96,7 +99,7 @@ void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *ini } void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); @@ -104,7 +107,7 @@ void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *i } void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Client l_client(reinterpret_cast(init)); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); @@ -112,7 +115,7 @@ void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob } void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_NPC l_npc(reinterpret_cast(init)); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); l_npc_o.push(L); @@ -120,7 +123,7 @@ void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *i } void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Client l_client(reinterpret_cast(init)); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); @@ -131,7 +134,7 @@ void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob } void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); @@ -142,7 +145,7 @@ void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, } void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); @@ -153,7 +156,7 @@ void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *ini } void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); @@ -165,19 +168,19 @@ void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, s void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "signal"); } void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushstring(L, data.c_str()); lua_setfield(L, -2, "timer"); } void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(init); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); l_mob_o.push(L); @@ -205,7 +208,7 @@ void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, } void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int spell_id = std::stoi(data); if(IsValidSpell(spell_id)) { Lua_Spell l_spell(&spells[spell_id]); @@ -221,21 +224,21 @@ void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, s } void handle_npc_area(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(0))); lua_setfield(L, -2, "area_id"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(1))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(1))); lua_setfield(L, -2, "area_type"); } void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { } //Player void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushstring(L, data.c_str()); lua_setfield(L, -2, "message"); @@ -244,7 +247,7 @@ void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std: } void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Seperator sep(data.c_str()); Mob *o = entity_list.GetMobID(std::stoi(sep.arg[0])); @@ -274,13 +277,13 @@ void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, st } void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushstring(L, data.c_str()); lua_setfield(L, -2, "timer"); } void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { const Item_Struct *item = database.GetItem(extra_data); if(item) { Lua_Item l_item(item); @@ -296,51 +299,51 @@ void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* cl } void handle_player_fish_forage_success(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); } void handle_player_click_object(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_Object l_object(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_Object l_object(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_object_o = luabind::adl::object(L, l_object); l_object_o.push(L); lua_setfield(L, -2, "object"); } void handle_player_click_door(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_Door l_door(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_Door l_door(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_door_o = luabind::adl::object(L, l_door); l_door_o.push(L); lua_setfield(L, -2, "door"); } void handle_player_signal(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "signal"); } void handle_player_popup_response(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "popup_id"); } void handle_player_pick_up(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); } void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int spell_id = std::stoi(data); if(IsValidSpell(spell_id)) { Lua_Spell l_spell(&spells[spell_id]); @@ -356,48 +359,48 @@ void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std } void handle_player_task_fail(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "task_id"); } void handle_player_zone(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "zone_id"); } void handle_player_duel_win(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_Client l_client(reinterpret_cast(extra_pointers->at(1))); + std::vector *extra_pointers) { + Lua_Client l_client(EQEmu::any_cast(extra_pointers->at(1))); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); lua_setfield(L, -2, "other"); } void handle_player_duel_loss(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_Client l_client(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_Client l_client(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); lua_setfield(L, -2, "other"); } void handle_player_loot(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); - Lua_Corpse l_corpse(reinterpret_cast(extra_pointers->at(1))); + Lua_Corpse l_corpse(EQEmu::any_cast(extra_pointers->at(1))); luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse); l_corpse_o.push(L); lua_setfield(L, -2, "corpse"); } void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Seperator sep(data.c_str()); lua_pushinteger(L, std::stoi(sep.arg[0])); lua_setfield(L, -2, "task_id"); @@ -407,7 +410,7 @@ void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Clie } void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Seperator sep(data.c_str()); lua_pushinteger(L, std::stoi(sep.arg[0])); lua_setfield(L, -2, "count"); @@ -420,7 +423,7 @@ void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* clie } void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Seperator sep(data.c_str(), ' ', 10, 100, true); std::string command(sep.arg[0] + 1); lua_pushstring(L, command.c_str()); @@ -439,7 +442,7 @@ void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, } void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, extra_data); lua_setfield(L, -2, "recipe_id"); @@ -448,24 +451,24 @@ void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client, } void handle_player_feign(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_NPC l_npc(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_NPC l_npc(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); l_npc_o.push(L); lua_setfield(L, -2, "other"); } void handle_player_area(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(0))); lua_setfield(L, -2, "area_id"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(1))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(1))); lua_setfield(L, -2, "area_type"); } void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, std::stoi(data)); lua_setfield(L, -2, "option"); @@ -474,8 +477,8 @@ void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, } void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_Packet l_packet(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_Packet l_packet(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_packet_o = luabind::adl::object(L, l_packet); l_packet_o.push(L); lua_setfield(L, -2, "packet"); @@ -485,24 +488,24 @@ void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, s } void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { } //Item void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, extra_data); lua_setfield(L, -2, "slot_id"); } void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushstring(L, data.c_str()); lua_setfield(L, -2, "timer"); } void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { Lua_Mob l_mob(mob); luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob); @@ -523,7 +526,7 @@ void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemI } void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(mob && mob->IsCorpse()) { Lua_Corpse l_corpse(mob->CastToCorpse()); luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse); @@ -538,14 +541,14 @@ void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemI } void handle_item_equip(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { lua_pushinteger(L, extra_data); lua_setfield(L, -2, "slot_id"); } void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "aug"); @@ -555,8 +558,8 @@ void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, It } void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); @@ -566,8 +569,8 @@ void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* cli } void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { - Lua_ItemInst l_item(reinterpret_cast(extra_pointers->at(0))); + std::vector *extra_pointers) { + Lua_ItemInst l_item(EQEmu::any_cast(extra_pointers->at(0))); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "item"); @@ -575,17 +578,17 @@ void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* cli lua_pushinteger(L, extra_data); lua_setfield(L, -2, "slot_id"); - lua_pushboolean(L, *reinterpret_cast(extra_pointers->at(1))); + lua_pushboolean(L, *EQEmu::any_cast(extra_pointers->at(1))); lua_setfield(L, -2, "destroyed"); } void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { } //Spell void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(npc) { Lua_Mob l_npc(npc); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); @@ -602,7 +605,7 @@ void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* lua_setfield(L, -2, "target"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(0))); lua_setfield(L, -2, "buff_slot"); lua_pushinteger(L, extra_data); @@ -610,7 +613,7 @@ void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* } void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(npc) { Lua_Mob l_npc(npc); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); @@ -627,13 +630,13 @@ void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* cli lua_setfield(L, -2, "target"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(0))); lua_setfield(L, -2, "tics_remaining"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(1))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(1))); lua_setfield(L, -2, "caster_level"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(2))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(2))); lua_setfield(L, -2, "buff_slot"); lua_pushinteger(L, extra_data); @@ -641,7 +644,7 @@ void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* cli } void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(npc) { Lua_Mob l_npc(npc); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); @@ -661,12 +664,12 @@ void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* cl lua_pushinteger(L, extra_data); lua_setfield(L, -2, "buff_slot"); - lua_pushinteger(L, *reinterpret_cast(extra_pointers->at(0))); + lua_pushinteger(L, *EQEmu::any_cast(extra_pointers->at(0))); lua_setfield(L, -2, "caster_id"); } void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(npc) { Lua_Mob l_npc(npc); luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc); @@ -685,7 +688,7 @@ void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Cl } void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { } #endif diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index 8272e30c3..32a59e0da 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -2,128 +2,128 @@ #define _EQE_LUA_PARSER_EVENTS_H #ifdef LUA_EQEMU -typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32, std::vector*); -typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector*); -typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, Mob*, std::string, uint32, std::vector*); -typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32, std::vector*); +typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32, std::vector*); +typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector*); +typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, Mob*, std::string, uint32, std::vector*); +typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32, std::vector*); //NPC void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_area(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); //Player void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + 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); + std::vector *extra_pointers); void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_fish_forage_success(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_click_object(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_click_door(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_signal(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_popup_response(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_pick_up(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_task_fail(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_zone(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_duel_win(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_duel_loss(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_loot(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_feign(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_area(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); //Item void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_equip(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); //Spell void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); #endif #endif diff --git a/zone/mob.cpp b/zone/mob.cpp index 0d7002253..fdce628c4 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -174,8 +174,9 @@ Mob::Mob(const char* in_name, drakkin_heritage = in_drakkin_heritage; drakkin_tattoo = in_drakkin_tattoo; drakkin_details = in_drakkin_details; - attack_speed= 0; - slow_mitigation= 0; + attack_speed = 0; + attack_delay = 0; + slow_mitigation = 0; findable = false; trackable = true; has_shieldequiped = false; @@ -1460,7 +1461,7 @@ void Mob::SendIllusionPacket(uint16 in_race, uint8 in_gender, uint8 in_texture, else this->drakkin_details = in_drakkin_details; - if (in_size == 0xFFFFFFFF) + if (in_size <= 0.0f) this->size = GetSize(); else this->size = in_size; @@ -1939,159 +1940,6 @@ void Mob::Kill() { Death(this, 0, SPELL_UNKNOWN, SkillHandtoHand); } -void Mob::SetAttackTimer() { - float PermaHaste; - if(GetHaste() > 0) - PermaHaste = 1 / (1 + (float)GetHaste()/100); - else if(GetHaste() < 0) - PermaHaste = 1 * (1 - (float)GetHaste()/100); - else - PermaHaste = 1.0f; - - //default value for attack timer in case they have - //an invalid weapon equipped: - attack_timer.SetAtTrigger(4000, true); - - Timer* TimerToUse = nullptr; - const Item_Struct* PrimaryWeapon = nullptr; - - for (int i=MainRange; i<=MainSecondary; i++) { - - //pick a timer - if (i == MainPrimary) - TimerToUse = &attack_timer; - else if (i == MainRange) - TimerToUse = &ranged_timer; - else if(i == MainSecondary) - TimerToUse = &attack_dw_timer; - else //invalid slot (hands will always hit this) - continue; - - const Item_Struct* ItemToUse = nullptr; - - //find our item - if (IsClient()) { - ItemInst* ci = CastToClient()->GetInv().GetItem(i); - if (ci) - ItemToUse = ci->GetItem(); - } else if(IsNPC()) - { - //The code before here was fundementally flawed because equipment[] - //isn't the same as PC inventory and also: - //NPCs don't use weapon speed to dictate how fast they hit anyway. - ItemToUse = nullptr; - } - - //special offhand stuff - if(i == MainSecondary) { - //if we have a 2H weapon in our main hand, no dual - if(PrimaryWeapon != nullptr) { - if( PrimaryWeapon->ItemClass == ItemClassCommon - && (PrimaryWeapon->ItemType == ItemType2HSlash - || PrimaryWeapon->ItemType == ItemType2HBlunt - || PrimaryWeapon->ItemType == ItemType2HPiercing)) { - attack_dw_timer.Disable(); - continue; - } - } - - //clients must have the skill to use it... - if(IsClient()) { - //if we cant dual wield, skip it - if (!CanThisClassDualWield()) { - attack_dw_timer.Disable(); - continue; - } - } else { - //NPCs get it for free at 13 - if(GetLevel() < 13) { - attack_dw_timer.Disable(); - continue; - } - } - } - - //see if we have a valid weapon - if(ItemToUse != nullptr) { - //check type and damage/delay - if(ItemToUse->ItemClass != ItemClassCommon - || ItemToUse->Damage == 0 - || ItemToUse->Delay == 0) { - //no weapon - ItemToUse = nullptr; - } - // Check to see if skill is valid - else if((ItemToUse->ItemType > ItemTypeLargeThrowing) && (ItemToUse->ItemType != ItemTypeMartial) && (ItemToUse->ItemType != ItemType2HPiercing)) { - //no weapon - ItemToUse = nullptr; - } - } - - int16 DelayMod = itembonuses.HundredHands + spellbonuses.HundredHands; - if (DelayMod < -99) - DelayMod = -99; - - //if we have no weapon.. - if (ItemToUse == nullptr) { - //above checks ensure ranged weapons do not fall into here - // Work out if we're a monk - if ((GetClass() == MONK) || (GetClass() == BEASTLORD)) { - //we are a monk, use special delay - int speed = (int)( (GetMonkHandToHandDelay()*(100+DelayMod)/100)*(100.0f+attack_speed)*PermaHaste); - // 1200 seemed too much, with delay 10 weapons available - if(speed < RuleI(Combat, MinHastedDelay)) //lower bound - speed = RuleI(Combat, MinHastedDelay); - TimerToUse->SetAtTrigger(speed, true); // Hand to hand, delay based on level or epic - } else { - //not a monk... using fist, regular delay - int speed = (int)((36 *(100+DelayMod)/100)*(100.0f+attack_speed)*PermaHaste); - if(speed < RuleI(Combat, MinHastedDelay) && IsClient()) //lower bound - speed = RuleI(Combat, MinHastedDelay); - TimerToUse->SetAtTrigger(speed, true); // Hand to hand, non-monk 2/36 - } - } else { - //we have a weapon, use its delay - // Convert weapon delay to timer resolution (milliseconds) - //delay * 100 - int speed = (int)((ItemToUse->Delay*(100+DelayMod)/100)*(100.0f+attack_speed)*PermaHaste); - if(speed < RuleI(Combat, MinHastedDelay)) - speed = RuleI(Combat, MinHastedDelay); - - if(ItemToUse && (ItemToUse->ItemType == ItemTypeBow || ItemToUse->ItemType == ItemTypeLargeThrowing)) - { - if(IsClient()) - { - float max_quiver = 0; - for(int r = EmuConstants::GENERAL_BEGIN; r <= EmuConstants::GENERAL_END; r++) - { - const ItemInst *pi = CastToClient()->GetInv().GetItem(r); - if(!pi) - continue; - if(pi->IsType(ItemClassContainer) && pi->GetItem()->BagType == BagTypeQuiver) - { - float temp_wr = ( pi->GetItem()->BagWR / RuleI(Combat, QuiverWRHasteDiv) ); - if(temp_wr > max_quiver) - { - max_quiver = temp_wr; - } - } - } - if(max_quiver > 0) - { - float quiver_haste = 1 / (1 + max_quiver / 100); - speed *= quiver_haste; - } - } - } - TimerToUse->SetAtTrigger(speed, true); - } - - if(i == MainPrimary) - PrimaryWeapon = ItemToUse; - } - -} - bool Mob::CanThisClassDualWield(void) const { if(!IsClient()) { return(GetSkill(SkillDualWield) > 0); diff --git a/zone/mob.h b/zone/mob.h index 55a57892b..1f1d257f9 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -563,7 +563,7 @@ public: uint8 in_haircolor = 0xFF, uint8 in_beardcolor = 0xFF, uint8 in_eyecolor1 = 0xFF, uint8 in_eyecolor2 = 0xFF, uint8 in_hairstyle = 0xFF, uint8 in_luclinface = 0xFF, uint8 in_beard = 0xFF, uint8 in_aa_title = 0xFF, uint32 in_drakkin_heritage = 0xFFFFFFFF, uint32 in_drakkin_tattoo = 0xFFFFFFFF, - uint32 in_drakkin_details = 0xFFFFFFFF, float in_size = 0xFFFFFFFF); + uint32 in_drakkin_details = 0xFFFFFFFF, float in_size = -1.0f); virtual void Stun(int duration); virtual void UnStun(); inline void Silence(bool newval) { silenced = newval; } @@ -684,6 +684,7 @@ public: inline bool GetInvul(void) { return invulnerable; } inline void SetExtraHaste(int Haste) { ExtraHaste = Haste; } virtual int GetHaste(); + inline float GetPermaHaste() { return GetHaste() ? 100.0f / (1.0f + static_cast(GetHaste()) / 100.0f) : 100.0f; } uint8 GetWeaponDamageBonus(const Item_Struct* Weapon); uint16 GetDamageTable(SkillUseTypes skillinuse); @@ -727,6 +728,7 @@ public: virtual void AI_Init(); virtual void AI_Start(uint32 iMoveDelay = 0); virtual void AI_Stop(); + virtual void AI_ShutDown(); virtual void AI_Process(); const char* GetEntityVariable(const char *id); @@ -1051,6 +1053,7 @@ protected: Timer attack_dw_timer; Timer ranged_timer; float attack_speed; //% increase/decrease in attack speed (not haste) + int8 attack_delay; //delay between attacks in 10ths of seconds float slow_mitigation; // Allows for a slow mitigation (100 = 100%, 50% = 50%) Timer tic_timer; Timer mana_timer; diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 10d41c78e..125e1d85f 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -550,30 +550,6 @@ void Mob::AI_Stop() { safe_delete(AItarget_check_timer); safe_delete(AIscanarea_timer); safe_delete(AIfeignremember_timer); - safe_delete(PathingLOSCheckTimer); - safe_delete(PathingRouteUpdateTimerShort); - safe_delete(PathingRouteUpdateTimerLong); - - attack_timer.Disable(); - attack_dw_timer.Disable(); - ranged_timer.Disable(); - tic_timer.Disable(); - mana_timer.Disable(); - spellend_timer.Disable(); - projectile_timer.Disable(); - rewind_timer.Disable(); - bindwound_timer.Disable(); - stunned_timer.Disable(); - spun_timer.Disable(); - bardsong_timer.Disable(); - gravity_timer.Disable(); - viral_timer.Disable(); - flee_timer.Disable(); - - for (int sat = 0; sat < MAX_SPECIAL_ATTACK; ++sat) { - if (SpecialAbilities[sat].timer) - SpecialAbilities[sat].timer->Disable(); - } hate_list.Wipe(); } @@ -609,6 +585,34 @@ void Client::AI_Stop() { } } +// only call this on a zone shutdown event +void Mob::AI_ShutDown() { + safe_delete(PathingLOSCheckTimer); + safe_delete(PathingRouteUpdateTimerShort); + safe_delete(PathingRouteUpdateTimerLong); + + attack_timer.Disable(); + attack_dw_timer.Disable(); + ranged_timer.Disable(); + tic_timer.Disable(); + mana_timer.Disable(); + spellend_timer.Disable(); + projectile_timer.Disable(); + rewind_timer.Disable(); + bindwound_timer.Disable(); + stunned_timer.Disable(); + spun_timer.Disable(); + bardsong_timer.Disable(); + gravity_timer.Disable(); + viral_timer.Disable(); + flee_timer.Disable(); + + for (int sat = 0; sat < MAX_SPECIAL_ATTACK; ++sat) { + if (SpecialAbilities[sat].timer) + SpecialAbilities[sat].timer->Disable(); + } +} + //todo: expand the logic here to cover: //redundant debuffs //buffing owner diff --git a/zone/npc.cpp b/zone/npc.cpp index f70c1e847..8804c488b 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -248,6 +248,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float delaytimer = false; combat_event = false; attack_speed = d->attack_speed; + attack_delay = d->attack_delay; slow_mitigation = d->slow_mitigation; EntityList::RemoveNumbers(name); @@ -1787,252 +1788,49 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue) { std::string id = identifier; std::string val = newValue; - for(int i = 0; i < id.length(); ++i) - { + for(int i = 0; i < id.length(); ++i) { id[i] = std::tolower(id[i]); } - if(id == "ac") - { - AC = atoi(val.c_str()); - return; - } - - if(id == "str") - { - STR = atoi(val.c_str()); - return; - } - - if(id == "sta") - { - STA = atoi(val.c_str()); - return; - } - - if(id == "agi") - { - AGI = atoi(val.c_str()); - return; - } - - if(id == "dex") - { - DEX = atoi(val.c_str()); - return; - } - - if(id == "wis") - { - WIS = atoi(val.c_str()); - CalcMaxMana(); - return; - } - - if(id == "int" || id == "_int") - { - INT = atoi(val.c_str()); - CalcMaxMana(); - return; - } - - if(id == "cha") - { - CHA = atoi(val.c_str()); - return; - } - - if(id == "max_hp") - { - base_hp = atoi(val.c_str()); - CalcMaxHP(); - if(cur_hp > max_hp) - cur_hp = max_hp; - return; - } - - if(id == "max_mana") - { - npc_mana = atoi(val.c_str()); - CalcMaxMana(); - if(cur_mana > max_mana) - cur_mana = max_mana; - return; - } - - if(id == "mr") - { - MR = atoi(val.c_str()); - return; - } - - if(id == "fr") - { - FR = atoi(val.c_str()); - return; - } - - if(id == "cr") - { - CR = atoi(val.c_str()); - return; - } - - if(id == "pr") - { - PR = atoi(val.c_str()); - return; - } - - if(id == "dr") - { - DR = atoi(val.c_str()); - return; - } - - if(id == "PhR") - { - PhR = atoi(val.c_str()); - return; - } - - if(id == "runspeed") - { - runspeed = (float)atof(val.c_str()); - CalcBonuses(); - return; - } - - if(id == "special_attacks") - { - //Added reset flag. - NPCSpecialAttacks(val.c_str(), 0, 1); - return; - } - - if(id == "attack_speed") - { - attack_speed = (float)atof(val.c_str()); - CalcBonuses(); - return; - } - - if(id == "atk") - { - ATK = atoi(val.c_str()); - return; - } - - if(id == "accuracy") - { - accuracy_rating = atoi(val.c_str()); - return; - } - - if(id == "avoidance") - { - avoidance_rating = atoi(val.c_str()); - return; - } - - if(id == "trackable") - { - trackable = atoi(val.c_str()); - return; - } - - if(id == "min_hit") - { - min_dmg = atoi(val.c_str()); - return; - } - - if(id == "max_hit") - { - max_dmg = atoi(val.c_str()); - return; - } - - if(id == "attack_count") - { - attack_count = atoi(val.c_str()); - return; - } - - if(id == "see_invis") - { - see_invis = atoi(val.c_str()); - return; - } - - if(id == "see_invis_undead") - { - see_invis_undead = atoi(val.c_str()); - return; - } - - if(id == "see_hide") - { - see_hide = atoi(val.c_str()); - return; - } - - if(id == "see_improved_hide") - { - see_improved_hide = atoi(val.c_str()); - return; - } - - if(id == "hp_regen") - { - hp_regen = atoi(val.c_str()); - return; - } - - if(id == "mana_regen") - { - mana_regen = atoi(val.c_str()); - return; - } - - if(id == "level") - { - SetLevel(atoi(val.c_str())); - return; - } - - if(id == "aggro") - { - pAggroRange = atof(val.c_str()); - return; - } - - if(id == "assist") - { - pAssistRange = atof(val.c_str()); - return; - } - - if(id == "slow_mitigation") - { - slow_mitigation = atoi(val.c_str()); - return; - } - if(id == "loottable_id") - { - loottable_id = atof(val.c_str()); - return; - } - if(id == "healscale") - { - healscale = atof(val.c_str()); - return; - } - if(id == "spellscale") - { - spellscale = atof(val.c_str()); - return; - } + if(id == "ac") { AC = atoi(val.c_str()); return; } + else if(id == "str") { STR = atoi(val.c_str()); return; } + else if(id == "sta") { STA = atoi(val.c_str()); return; } + else if(id == "agi") { AGI = atoi(val.c_str()); return; } + else if(id == "dex") { DEX = atoi(val.c_str()); return; } + else if(id == "wis") { WIS = atoi(val.c_str()); CalcMaxMana(); return; } + else if(id == "int" || id == "_int") { INT = atoi(val.c_str()); CalcMaxMana(); return; } + else if(id == "cha") { CHA = atoi(val.c_str()); return; } + else if(id == "max_hp") { base_hp = atoi(val.c_str()); CalcMaxHP(); if (cur_hp > max_hp) { cur_hp = max_hp; } return; } + else if(id == "max_mana") { npc_mana = atoi(val.c_str()); CalcMaxMana(); if (cur_mana > max_mana){ cur_mana = max_mana; } return; } + else if(id == "mr") { MR = atoi(val.c_str()); return; } + else if(id == "fr") { FR = atoi(val.c_str()); return; } + else if(id == "cr") { CR = atoi(val.c_str()); return; } + else if(id == "pr") { PR = atoi(val.c_str()); return; } + else if(id == "dr") { DR = atoi(val.c_str()); return; } + else if(id == "PhR") { PhR = atoi(val.c_str()); return; } + else if(id == "runspeed") { runspeed = (float)atof(val.c_str()); CalcBonuses(); return; } + else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; } + else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; } + else if(id == "atk") { ATK = atoi(val.c_str()); return; } + else if(id == "accuracy") { accuracy_rating = atoi(val.c_str()); return; } + else if(id == "avoidance") { avoidance_rating = atoi(val.c_str()); return; } + else if(id == "trackable") { trackable = atoi(val.c_str()); return; } + else if(id == "min_hit") { min_dmg = atoi(val.c_str()); return; } + else if(id == "max_hit") { max_dmg = atoi(val.c_str()); return; } + else if(id == "attack_count") { attack_count = atoi(val.c_str()); return; } + else if(id == "see_invis") { see_invis = atoi(val.c_str()); return; } + else if(id == "see_invis_undead") { see_invis_undead = atoi(val.c_str()); return; } + else if(id == "see_hide") { see_hide = atoi(val.c_str()); return; } + else if(id == "see_improved_hide") { see_improved_hide = atoi(val.c_str()); return; } + else if(id == "hp_regen") { hp_regen = atoi(val.c_str()); return; } + else if(id == "mana_regen") { mana_regen = atoi(val.c_str()); return; } + else if(id == "level") { SetLevel(atoi(val.c_str())); return; } + else if(id == "aggro") { pAggroRange = atof(val.c_str()); return; } + else if(id == "assist") { pAssistRange = atof(val.c_str()); return; } + else if(id == "slow_mitigation") { slow_mitigation = atoi(val.c_str()); return; } + else if(id == "loottable_id") { loottable_id = atof(val.c_str()); return; } + else if(id == "healscale") { healscale = atof(val.c_str()); return; } + else if(id == "spellscale") { spellscale = atof(val.c_str()); return; } } void NPC::LevelScale() { diff --git a/zone/npc.h b/zone/npc.h index 5b28260d4..b23522bee 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -134,7 +134,6 @@ public: void CalcNPCRegen(); void CalcNPCDamage(); - int32 GetActSpellDamage(uint16 spell_id, int32 value, Mob* target = nullptr); int32 GetActSpellHealing(uint16 spell_id, int32 value, Mob* target = nullptr); inline void SetSpellFocusDMG(int32 NewSpellFocusDMG) {SpellFocusDMG = NewSpellFocusDMG;} @@ -158,6 +157,7 @@ public: virtual void InitializeBuffSlots(); virtual void UninitializeBuffSlots(); + virtual void SetAttackTimer(); virtual void RangedAttack(Mob* other); virtual void ThrowingAttack(Mob* other) { } int32 GetNumberOfAttacks() const { return attack_count; } @@ -388,16 +388,16 @@ public: inline void SetHealScale(float amt) { healscale = amt; } inline float GetHealScale() { return healscale; } - uint32 GetSpawnKillCount(); - int GetScore(); - void SetMerchantProbability(uint8 amt) { probability = amt; } + uint32 GetSpawnKillCount(); + int GetScore(); + void SetMerchantProbability(uint8 amt) { probability = amt; } uint8 GetMerchantProbability() { return probability; } - void mod_prespawn(Spawn2 *sp); - int mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const Item_Struct* weapon, Mob* other); + void mod_prespawn(Spawn2 *sp); + int mod_npc_damage(int damage, SkillUseTypes skillinuse, int hand, const Item_Struct* weapon, Mob* other); void mod_npc_killed_merit(Mob* c); void mod_npc_killed(Mob* oos); - void AISpellsList(Client *c); - + void AISpellsList(Client *c); + bool IsRaidTarget() const { return raid_target; }; protected: diff --git a/zone/object.cpp b/zone/object.cpp index a2c418b40..c560191f1 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -465,7 +465,7 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) char buf[10]; snprintf(buf, 9, "%u", m_inst->GetItem()->ID); buf[9] = '\0'; - std::vector args; + std::vector args; args.push_back(m_inst); parse->EventPlayer(EVENT_PLAYER_PICKUP, sender, buf, 0, &args); diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 14d84a70e..53a5aade8 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -7140,7 +7140,7 @@ XS(XS_Mob_SendIllusion) uint32 drakkin_heritage = 0xFFFFFFFF; uint32 drakkin_tattoo = 0xFFFFFFFF; uint32 drakkin_details = 0xFFFFFFFF; - float size = 0xFFFFFFFF; + float size = -1.0f; if (sv_derived_from(ST(0), "Mob")) { IV tmp = SvIV((SV*)SvRV(ST(0))); diff --git a/zone/quest_interface.h b/zone/quest_interface.h index 8e3e3a93e..68c79923f 100644 --- a/zone/quest_interface.h +++ b/zone/quest_interface.h @@ -20,6 +20,7 @@ #define _EQE_QUESTINTERFACE_H #include "../common/types.h" +#include "../common/any.h" #include "event_codes.h" class ItemInst; @@ -29,19 +30,19 @@ class NPC; class QuestInterface { public: virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual bool HasQuestSub(uint32 npcid, QuestEventID evt) { return false; } virtual bool HasGlobalQuestSub(QuestEventID evt) { return false; } @@ -60,13 +61,13 @@ public: virtual void LoadEncounterScript(std::string filename, std::string encounter_name) { } virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { return 0; } + std::vector *extra_pointers) { return 0; } virtual void AddVar(std::string name, std::string val) { } virtual std::string GetVar(std::string name) { return std::string(); } diff --git a/zone/quest_parser_collection.cpp b/zone/quest_parser_collection.cpp index 8fc0f9c43..10703c299 100644 --- a/zone/quest_parser_collection.cpp +++ b/zone/quest_parser_collection.cpp @@ -234,7 +234,7 @@ bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) { } int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int rd = DispatchEventNPC(evt, npc, init, data, extra_data, extra_pointers); int rl = EventNPCLocal(evt, npc, init, data, extra_data, extra_pointers); int rg = EventNPCGlobal(evt, npc, init, data, extra_data, extra_pointers); @@ -252,7 +252,7 @@ int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std:: } int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { std::map::iterator iter = _npc_quest_status.find(npc->GetNPCTypeID()); if(iter != _npc_quest_status.end()) { //loaded or failed to load @@ -275,7 +275,7 @@ int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, } int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) { std::map::iterator qiter = _interfaces.find(_global_npc_quest_status); return qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data, extra_pointers); @@ -294,7 +294,7 @@ int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, } int QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int rd = DispatchEventPlayer(evt, client, data, extra_data, extra_pointers); int rl = EventPlayerLocal(evt, client, data, extra_data, extra_pointers); int rg = EventPlayerGlobal(evt, client, data, extra_data, extra_pointers); @@ -312,7 +312,7 @@ int QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::st } int QuestParserCollection::EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(_player_quest_status == QuestUnloaded) { std::string filename; QuestInterface *qi = GetQIByPlayerQuest(filename); @@ -331,7 +331,7 @@ int QuestParserCollection::EventPlayerLocal(QuestEventID evt, Client *client, st } int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { if(_global_player_quest_status == QuestUnloaded) { std::string filename; QuestInterface *qi = GetQIByGlobalPlayerQuest(filename); @@ -350,7 +350,7 @@ int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, s } int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { std::string item_script; if(item->GetItem()->ScriptFileID != 0) { item_script = "script_"; @@ -396,7 +396,7 @@ int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst } int QuestParserCollection::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { std::map::iterator iter = _spell_quest_status.find(spell_id); if(iter != _spell_quest_status.end()) { //loaded or failed to load @@ -431,7 +431,7 @@ int QuestParserCollection::EventSpell(QuestEventID evt, NPC* npc, Client *client } int QuestParserCollection::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { auto iter = _encounter_quest_status.find(encounter_name); if(iter != _encounter_quest_status.end()) { //loaded or failed to load @@ -974,7 +974,7 @@ void QuestParserCollection::GetErrors(std::list &err) { } int QuestParserCollection::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int ret = 0; auto iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { @@ -988,7 +988,7 @@ int QuestParserCollection::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *ini } int QuestParserCollection::DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int ret = 0; auto iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { @@ -1002,7 +1002,7 @@ int QuestParserCollection::DispatchEventPlayer(QuestEventID evt, Client *client, } int QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, - uint32 extra_data, std::vector *extra_pointers) { + uint32 extra_data, std::vector *extra_pointers) { int ret = 0; auto iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { @@ -1016,7 +1016,7 @@ int QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, I } int QuestParserCollection::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers) { + std::vector *extra_pointers) { int ret = 0; auto iter = _load_precedence.begin(); while(iter != _load_precedence.end()) { diff --git a/zone/quest_parser_collection.h b/zone/quest_parser_collection.h index 902500231..006bcfe24 100644 --- a/zone/quest_parser_collection.h +++ b/zone/quest_parser_collection.h @@ -51,15 +51,15 @@ public: bool ItemHasQuestSub(ItemInst *itm, QuestEventID evt); int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); + std::vector *extra_pointers = nullptr); int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); + std::vector *extra_pointers = nullptr); int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers = nullptr); + std::vector *extra_pointers = nullptr); int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers = nullptr); + std::vector *extra_pointers = nullptr); int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, - std::vector *extra_pointers = nullptr); + std::vector *extra_pointers = nullptr); void GetErrors(std::list &err); @@ -69,10 +69,10 @@ private: bool PlayerHasQuestSubLocal(QuestEventID evt); bool PlayerHasQuestSubGlobal(QuestEventID evt); - int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers); - int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers); - int EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector *extra_pointers); - int EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector *extra_pointers); + int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers); + int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector *extra_pointers); + int EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector *extra_pointers); + int EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector *extra_pointers); QuestInterface *GetQIByNPCQuest(uint32 npcid, std::string &filename); QuestInterface *GetQIByGlobalNPCQuest(std::string &filename); @@ -83,13 +83,13 @@ private: QuestInterface *GetQIByEncounterQuest(std::string encounter_name, std::string &filename); int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, - std::vector *extra_pointers); + std::vector *extra_pointers); std::map _interfaces; std::map _extensions; diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 0431eb9b1..904dc41b3 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -1413,10 +1413,8 @@ void NPC::DoClassAttacks(Mob *target) { return; float HasteModifier = 0; - if(GetHaste() > 0) + if (GetHaste()) HasteModifier = 10000 / (100 + GetHaste()); - else if(GetHaste() < 0) - HasteModifier = (100 - GetHaste()); else HasteModifier = 100; @@ -1464,7 +1462,7 @@ void NPC::DoClassAttacks(Mob *target) { } } - reuse = KickReuseTime * 1000; + reuse = (KickReuseTime + 3) * 1000; DoSpecialAttackDamage(target, SkillKick, dmg, 1, -1, reuse); did_attack = true; } @@ -1484,7 +1482,7 @@ void NPC::DoClassAttacks(Mob *target) { } } - reuse = BashReuseTime * 1000; + reuse = (BashReuseTime + 3) * 1000; DoSpecialAttackDamage(target, SkillBash, dmg, 1, -1, reuse); did_attack = true; } @@ -1537,7 +1535,7 @@ void NPC::DoClassAttacks(Mob *target) { } } - reuse = KickReuseTime * 1000; + reuse = (KickReuseTime + 3) * 1000; DoSpecialAttackDamage(target, SkillKick, dmg, 1, -1, reuse); did_attack = true; } @@ -1562,7 +1560,7 @@ void NPC::DoClassAttacks(Mob *target) { } } - reuse = BashReuseTime * 1000; + reuse = (BashReuseTime + 3) * 1000; DoSpecialAttackDamage(target, SkillBash, dmg, 1, -1, reuse); did_attack = true; } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index bb1c3c449..b10c436f2 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -139,7 +139,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) if(IsNPC()) { - std::vector args; + std::vector args; args.push_back(&buffslot); int i = parse->EventSpell(EVENT_SPELL_EFFECT_NPC, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0, &args); if(i != 0){ @@ -149,7 +149,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) } else if(IsClient()) { - std::vector args; + std::vector args; args.push_back(&buffslot); int i = parse->EventSpell(EVENT_SPELL_EFFECT_CLIENT, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0, &args); if(i != 0){ @@ -3293,7 +3293,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste if(IsNPC()) { - std::vector args; + std::vector args; args.push_back(&ticsremaining); args.push_back(&caster_level); args.push_back(&slot); @@ -3304,7 +3304,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste } else { - std::vector args; + std::vector args; args.push_back(&ticsremaining); args.push_back(&caster_level); args.push_back(&slot); @@ -3654,12 +3654,12 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses) } if(IsClient()) { - std::vector args; + std::vector args; args.push_back(&buffs[slot].casterid); parse->EventSpell(EVENT_SPELL_FADE, nullptr, CastToClient(), buffs[slot].spellid, slot, &args); } else if(IsNPC()) { - std::vector args; + std::vector args; args.push_back(&buffs[slot].casterid); parse->EventSpell(EVENT_SPELL_FADE, CastToNPC(), nullptr, buffs[slot].spellid, slot, &args); diff --git a/zone/spells.cpp b/zone/spells.cpp index 357fafbd4..b54b0b66c 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -4501,13 +4501,12 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use } else { - resist_chance -= roll; if(resist_chance < 1) { resist_chance = 1; } - int partial_modifier = ((150 * (roll - resist_chance)) / resist_chance); + int partial_modifier = ((150 * (resist_chance - roll)) / resist_chance); if(IsNPC()) { @@ -4535,17 +4534,16 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use } } - if(partial_modifier < 0) + if(partial_modifier <= 0) + { + return 100; + } + else if(partial_modifier >= 100) { return 0; } - if(partial_modifier > 100) - { - return 100; - } - - return partial_modifier; + return (100.0f - partial_modifier); } } } diff --git a/zone/string_ids.h b/zone/string_ids.h index b1e13edca..056513874 100644 --- a/zone/string_ids.h +++ b/zone/string_ids.h @@ -205,6 +205,24 @@ #define MERCHANT_HANDY_ITEM2 1146 //Greetings, %3. You look like you could use a %4. #define MERCHANT_HANDY_ITEM3 1147 //Hi there %3, just browsing? Have you seen the %4 I just got in? #define MERCHANT_HANDY_ITEM4 1148 //Welcome to my shop, %3. You would probably find a %4 handy. +#define WONT_SELL_RACE1 1154 //I don't like to speak to %B3(12) much less sell to them! +#define WONT_SELL_CLASS1 1155 //It's %B3(13) like you that are ruining the continent...get OUT! +#define WONT_SELL_CLASS2 1156 //Isn't there some kind of ordinance against %B3(13) crawling out from under their rocks? +#define WONT_SELL_CLASS3 1157 //%B3(13) like you don't have any place in my shop..now make way for welcome customers. +#define WONT_SELL_CLASS4 1158 //I thought scumbag %B3(13) like you just stole whatever they need. Now GET OUT! +#define WONT_SELL_CLASS5 1159 //I don't have anything to do with %B3(13)..move along. +#define WONT_SELL_NONSTDRACE1 1160 //I don't have anything to do with your little gang..move along. +#define WONT_SELL_RACE2 1161 //It's not enough that you %B3(12) have ruined your own land. Now get lost! +#define WONT_SELL_RACE3 1162 //I have something here that %B3(12) use..let me see...it's the EXIT, now get LOST! +#define WONT_SELL_RACE4 1163 //Don't you %B3(12) have your own merchants? Whatever, I'm not selling anything to you! +#define WONT_SELL_NONSTDRACE2 1164 //Members of your little "club" have ruined things around here..get lost! +#define WONT_SELL_NONSTDRACE3 1165 //I don't have anything to do with your damned club..move along. +#define WONT_SELL_DEEDS1 1166 //Creatures like you make me sick..the things you do..get out of here Pagan! +#define WONT_SELL_DEEDS2 1167 //After all the things you've done..the things you believe in..leave my shop! +#define WONT_SELL_DEEDS3 1168 //Actions speak louder than beliefs, and I despise both your actions and all you believe in. +#define WONT_SELL_DEEDS4 1169 //Get out of here now! +#define WONT_SELL_DEEDS5 1170 //I am tolerant by nature..but infidels like you push me past my limit..get out! +#define WONT_SELL_DEEDS6 1171 //I cannot abide you or your actions against all that is right..BE GONE! #define AA_POINT 1197 //point #define AA_POINTS 1215 //points #define SPELL_FIZZLE_OTHER 1218 //%1's spell fizzles! diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index e8e787de0..91cb458a0 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -149,7 +149,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme ItemInst *aug = tobe_auged->GetAugment(slot); if(aug) { - std::vector args; + std::vector args; args.push_back(aug); parse->EventItem(EVENT_AUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args); @@ -171,7 +171,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme const uint32 id = auged_with->GetID(); ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_slot); if(aug) { - std::vector args; + std::vector args; args.push_back(aug); parse->EventItem(EVENT_UNAUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args); diff --git a/zone/trading.cpp b/zone/trading.cpp index 23d8d77af..c89af4010 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -863,7 +863,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st quest_npc = true; } - std::vector item_list; + std::vector item_list; uint32 items[4] = { 0 }; for(int i = EmuConstants::TRADE_BEGIN; i <= EmuConstants::TRADE_NPC_END; ++i) { ItemInst *inst = m_inv.GetItem(i); @@ -871,7 +871,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st items[i - EmuConstants::TRADE_BEGIN] = inst->GetItem()->ID; item_list.push_back(inst); } else { - item_list.push_back(nullptr); + item_list.push_back((ItemInst*)nullptr); continue; } diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index c3a19a6f3..f1a3dce18 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -568,6 +568,8 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b Map::Vertex dest(x_pos, y_pos, z_pos); float newz = zone->zonemap->FindBestZ(dest, nullptr); + float sz = GetSize(); + newz += sz >= 0.0f ? sz / 2.0f : 0.0f; mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); @@ -697,6 +699,8 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b Map::Vertex dest(x_pos, y_pos, z_pos); float newz = zone->zonemap->FindBestZ(dest, nullptr); + float sz = GetSize(); + newz += sz >= 0.0f ? sz / 2.0f : 0.0f; mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); @@ -822,6 +826,8 @@ bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool chec Map::Vertex dest(x_pos, y_pos, z_pos); float newz = zone->zonemap->FindBestZ(dest, nullptr); + float sz = GetSize(); + newz += sz >= 0.0f ? sz / 2.0f : 0.0f; mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos); @@ -1245,45 +1251,45 @@ void ZoneDatabase::DeleteWaypoint(Client *client, uint32 grid_num, uint32 wp_num uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading) { uint32 grid_num; // The grid number the spawn is assigned to (if spawn has no grid, will be the grid number we end up creating) - uint32 next_wp_num; // The waypoint number we should be assigning to the new waypoint + uint32 next_wp_num; // The waypoint number we should be assigning to the new waypoint bool createdNewGrid; // Did we create a new grid in this function? // See what grid number our spawn is assigned std::string query = StringFormat("SELECT pathgrid FROM spawn2 WHERE id = %i", spawn2id); auto results = QueryDatabase(query); if (!results.Success()) { - // Query error + // Query error LogFile->write(EQEMuLog::Error, "Error setting pathgrid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return 0; } if (results.RowCount() == 0) - return 0; + return 0; - auto row = results.begin(); - grid_num = atoi(row[0]); + auto row = results.begin(); + grid_num = atoi(row[0]); if (grid_num == 0) { // Our spawn doesn't have a grid assigned to it -- we need to create a new grid and assign it to the spawn createdNewGrid = true; grid_num = GetFreeGrid(zoneid); if(grid_num == 0) // There are no grids for the current zone -- create Grid #1 - grid_num = 1; + grid_num = 1; - query = StringFormat("INSERT INTO grid SET id = '%i', zoneid = %i, type ='%i', type2 = '%i'", - grid_num, zoneid, type1, type2); - results = QueryDatabase(query); + query = StringFormat("INSERT INTO grid SET id = '%i', zoneid = %i, type ='%i', type2 = '%i'", + grid_num, zoneid, type1, type2); + results = QueryDatabase(query); if(!results.Success()) LogFile->write(EQEMuLog::Error, "Error adding grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) - client->LogSQL(query.c_str()); + client->LogSQL(query.c_str()); query = StringFormat("UPDATE spawn2 SET pathgrid = '%i' WHERE id = '%i'", grid_num, spawn2id); results = QueryDatabase(query); if(!results.Success()) LogFile->write(EQEMuLog::Error, "Error updating spawn2 pathing '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) - client->LogSQL(query.c_str()); + client->LogSQL(query.c_str()); } else // NPC had a grid assigned to it createdNewGrid = false; @@ -1291,25 +1297,26 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, // Find out what the next waypoint is for this grid query = StringFormat("SELECT max(`number`) FROM grid_entries WHERE zoneid = '%i' AND gridid = '%i'", zoneid, grid_num); + results = QueryDatabase(query); if(!results.Success()) { // Query error LogFile->write(EQEMuLog::Error, "Error getting next waypoint id '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); return 0; } - row = results.begin(); - if(row[0] != 0) - next_wp_num = atoi(row[0]) + 1; - else // No waypoints in this grid yet + row = results.begin(); + if(row[0] != 0) + next_wp_num = atoi(row[0]) + 1; + else // No waypoints in this grid yet next_wp_num = 1; query = StringFormat("INSERT INTO grid_entries(gridid, zoneid, `number`, x, y, z, pause, heading) " - "VALUES (%i, %i, %i, %f, %f, %f, %i, %f)", - grid_num, zoneid, next_wp_num, xpos, ypos, zpos, pause, heading); - results = QueryDatabase(query); + "VALUES (%i, %i, %i, %f, %f, %f, %i, %f)", + grid_num, zoneid, next_wp_num, xpos, ypos, zpos, pause, heading); + results = QueryDatabase(query); if(!results.Success()) LogFile->write(EQEMuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str()); else if(client) - client->LogSQL(query.c_str()); + client->LogSQL(query.c_str()); return createdNewGrid? grid_num: 0; } diff --git a/zone/zone.cpp b/zone/zone.cpp index 8f4b211d8..2f1052f73 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -594,15 +594,17 @@ void Zone::LoadMercTemplates(){ tempMercTemplate.Stances[i] = 0; int stanceIndex = 0; - for (std::list::iterator mercStanceListItr = merc_stances.begin(); mercStanceListItr != merc_stances.end(); ++mercStanceListItr, ++stanceIndex) { + for (auto mercStanceListItr = merc_stances.begin(); mercStanceListItr != merc_stances.end(); ++mercStanceListItr) { if(mercStanceListItr->ClassID != tempMercTemplate.ClassID || mercStanceListItr->ProficiencyID != tempMercTemplate.ProficiencyID) continue; zone->merc_stance_list[tempMercTemplate.MercTemplateID].push_back((*mercStanceListItr)); tempMercTemplate.Stances[stanceIndex] = mercStanceListItr->StanceID; + ++stanceIndex; } merc_templates[tempMercTemplate.MercTemplateID] = tempMercTemplate; + } } @@ -733,6 +735,7 @@ void Zone::Shutdown(bool quite) while (mob_itr != mob_list.end()) { Mob* mob_inst = *mob_itr; mob_inst->AI_Stop(); + mob_inst->AI_ShutDown(); ++mob_itr; } diff --git a/zone/zonedump.h b/zone/zonedump.h index 0d2bcb1d2..a96d276cd 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -111,6 +111,7 @@ struct NPCType uint8 spawn_limit; //only this many may be in zone at a time (0=no limit) uint8 mount_color; //only used by horse class float attack_speed; //%+- on attack delay of the mob. + uint8 attack_delay; //delay between attacks in 10ths of a second int accuracy_rating; //10 = 1% accuracy int avoidance_rating; //10 = 1% avoidance bool findable; //can be found with find command