Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Arthur Ice 2014-07-30 14:08:10 -07:00
commit 7aaf9ae00d
92 changed files with 4376 additions and 1633 deletions

View File

@ -1,4 +1,36 @@
#EQEmu Cmake
#EQEmu CMake
#Variables used:
#EQEMU_DISABLE_CRT_SECURE_WARNINGS
#EQEMU_FAST_FLOATINGPOINT
#EQEMU_ENABLE_CRASH_LOGGING
#EQEMU_DISABLE_SAFESEH
#EQEMU_BUILD_MSVC_MP
#EQEMU_DEBUG_LEVEL
#EQEMU_LOG_LEVEL_STATUS
#EQEMU_LOG_LEVEL_NORMAL
#EQEMU_LOG_LEVEL_ERROR
#EQEMU_LOG_LEVEL_DEBUG
#EQEMU_LOG_LEVEL_QUEST
#EQEMU_LOG_LEVEL_COMMANDS
#EQEMU_LOG_LEVEL_CRASH
#EQEMU_STREAM_SEND_RATE
#EQEMU_STREAM_DECAY_RATE
#EQEMU_STREAM_RETRANSMIT_TIMEOUT_MUL
#EQEMU_STREAM_RETRANSMIT_TIMEOUT_MAX
#EQEMU_STREAM_AVERAGE_DELTA_MAX
#EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS
#EQEMU_DEPOP_INVALIDATES_CACHE
#EQEMU_ENABLE_BOTS
#EQEMU_DISABLE_LOGSYS
#EQEMU_COMMANDS_LOGGING
#EQEMU_BUILD_SERVER
#EQEMU_BUILD_LOGIN
#EQEMU_BUILD_TESTS
#EQEMU_BUILD_PERL
#EQEMU_BUILD_LUA
#EQEMU_SANITIZE_LUA_LIBS
#EQEMU_BUILD_CLIENT_FILES
#EQEMU_MAP_DIR
#We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones
#Can change this if you really want but you should upgrade!
@ -7,9 +39,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
#FindMySQL is located here so lets make it so CMake can find it
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
#For checking includes
INCLUDE (CheckIncludeFiles)
#Our project name is EQEmu
PROJECT(EQEmu)
@ -75,7 +104,7 @@ IF(MSVC)
SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} /SAFESEH:NO")
ENDIF(EQEMU_DISABLE_SAFESEH)
OPTION(EQEMU_BUILD_MSVC_MP "Enable build with multiple processes." TRUE)
OPTION(EQEMU_BUILD_MSVC_MP "Enable build with multiple processes." ON)
IF(EQEMU_BUILD_MSVC_MP)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
ENDIF(EQEMU_BUILD_MSVC_MP)
@ -105,12 +134,6 @@ IF(UNIX)
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
ENDIF(UNIX)
#use stdint.h types if they exist for this platform (we have to guess otherwise)
CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H)
IF(HAVE_STDINT_H)
ADD_DEFINITIONS(-DEQEMU_USE_STDINT)
ENDIF(HAVE_STDINT_H)
#debug level, 5 is default. Most people wont ever change this but it's there if you want to
SET(EQEMU_DEBUG_LEVEL 5 CACHE STRING "EQEmu debug level:
0 - Quiet mode Errors to file Status and Normal ignored
@ -229,10 +252,9 @@ ENDIF(EQEMU_ENABLE_BOTS)
#What to build
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF)
OPTION(EQEMU_BUILD_SOCKET_SERVER "Build the socket server." OFF)
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." OFF)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
#C++11 stuff

View File

@ -1,5 +1,60 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 07/27/2014 ==
Uleat: More updates to the dictionary. Added a 'constants' file for each client translator..these will tie-in to the dictionary. Started
replacement of hard-coded numeric values with a pre-defined constant. This will help in the transition.
== 07/16/2014 ==
Uleat: Initial commit of new client/server 'dictionaries' - work in-progress... Changed equipment slot references to reflect new naming
conventions. Lua enumerations maintain both the old and new names as to not break existing scripts..but, the old names are deprecated.
== 07/14/2014 ==
KLS: Changes to CMake build
-Lua builds by default now
-Common has been renamed common
-Binary files will now be put into ${CMAKE_BINARY_DIR}/bin instead of ${CMAKE_BINARY_DIR}/Bin
The last two are of note to people on non-windows systems as case sensitivity is important. Edit your scripts accordingly, thank you.
== 07/10/2014 ==
Kayen: Updated table npc_spells to now support defensive and ranged procs.
Note: Proc rate modifier work as it does for spell effects (ie 200 = 200% baseline chance modifier)
Table is also now contains 12 AI spell casting variables that can be set to fine tune casting behaviors per spell set.
Global default rules have also been added that can further fine tune all content if no specific variables are set.
Descriptions of new AI casting fields in npc_spells
'fail_recast' AI spell recast time(MS) when an spell is cast but fails (ie stunned)
'engaged_no_sp_recast_min' AI spell recast time(MS) checked when no spell is cast while engaged in combat. (min time in random)
'engaged_no_sp_recast_max' AI spell recast time(MS) checked when no spell is cast while engaged in combat. (max time in random)
'engaged_b_self_chance' Chance during first AI Cast check to do a beneficial spell on self (ie check to heal self)
'engaged_b_other_chance' Chance during second AI Cast check to do a beneficial spell on others.(ie check to heal others)
'engaged_d_chance' 'Chance during third AI Cast check to do a determental spell on others (ie check to nuke others)
'pursue_no_sp_recast_min' AI spell recast time(MS) checked when no spell is cast while chasing target. (min time in random)
'pursue_no_sp_recast_max' AI spell recast time(MS) checked when no spell is cast while chasing target. (max time in random)
'pursue_d_chance' Chance while chasing target to cast a detrimental spell.
'idle_no_sp_recast_min' AI spell recast time(MS) checked when no spell is cast while idle. (min time in random)
'idle_no_sp_recast_max' AI spell recast time(MS) checked when no spell is cast while idle. (max time in random)
'idle_b_chance' Chance to cast a beneficial spell while idle (ie cast heal on self while out of combat).
Kayen: Updated table npc_types, adding field 'ranged_type' and 'ammo_idfile'
'ranged_type' Will set what skill / animation is used when NPC uses a ranged attacked (special ability 11)
'ammo_idfile' Will set what projectile graphic an NPC uses in a ranged attacked (special ability 11) Format IT#### (same as item 'idfile')
(*Set to IT11118 for some fun*)
Added parameters: SPECATK_RANGED_ATK = 11
Param0: Min Ranged distance (default: 25)
Param1: Max Ranged distance (default: 250)
Param2: Percent Chance to Hit modifier
Param3: Percent Total Damage modifier
Kayen: Updated to Chance to Hit code with how bonuses are applied to be consistent for all effects.
Added field to npc_types 'Avoidance' which will modify chance to avoid melee
Added rules to set max and min chance to hit from melee/ranged (Default 95% / 5%)
Required SQL: utils/sql/git/required/2014_07_10_npc_spells.sql
Optional SQL: utils/sql/git/optional/2014_07_10_AICastingRules.sql
== 07/5/2014 ==
Kayen: Updated SE_Sanctuary - Adjust way hate lowering effect worked to be more accurate
Kayen: Updated SE_SympatheticProc - Revised proc rate formula to be accurate to live.

View File

@ -11,7 +11,7 @@ ADD_EXECUTABLE(export_client_files ${export_sources} ${export_headers})
INSTALL(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(export_client_files Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(export_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(export_client_files PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
@ -33,4 +33,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/Bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -11,7 +11,7 @@ ADD_EXECUTABLE(import_client_files ${import_sources} ${import_headers})
INSTALL(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(import_client_files Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(import_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(import_client_files PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
@ -33,4 +33,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/Bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -14,6 +14,7 @@ SET(common_sources
emu_opcodes.cpp
EmuTCPConnection.cpp
EmuTCPServer.cpp
eq_dictionary.cpp
EQDB.cpp
EQDBRes.cpp
eqemu_exception.cpp
@ -71,6 +72,7 @@ SET(common_sources
patches/SoD.cpp
patches/SoF.cpp
patches/RoF.cpp
#patches/RoF2.cpp
patches/Titanium.cpp
patches/Underfoot.cpp
SocketLib/Base64.cpp
@ -111,6 +113,7 @@ SET(common_headers
EmuTCPConnection.h
EmuTCPServer.h
eq_constants.h
eq_dictionary.h
eq_packet_structs.h
EQDB.h
EQDBRes.h
@ -189,15 +192,18 @@ SET(common_headers
ZoneNumbers.h
platform.h
patches/Client62.h
patches/Client62_constants.h
patches/Client62_itemfields.h
patches/Client62_ops.h
patches/Client62_structs.h
patches/patches.h
patches/SoD.h
patches/SoD_constants.h
patches/SoD_itemfields.h
patches/SoD_ops.h
patches/SoD_structs.h
patches/SoF.h
patches/SoF_constants.h
patches/SoF_itemfields.h
patches/SoF_opcode_list.h
patches/SoF_ops.h
@ -206,14 +212,22 @@ SET(common_headers
patches/SSDefine.h
patches/SSRegister.h
patches/RoF.h
patches/RoF_constants.h
patches/RoF_itemfields.h
patches/RoF_ops.h
patches/RoF_structs.h
#patches/RoF2.h
#patches/RoF2_constants.h
#patches/RoF2_itemfields.h
#patches/RoF2_ops.h
#patches/RoF2_structs.h
patches/Titanium.h
patches/Titanium_constants.h
patches/Titanium_itemfields.h
patches/Titanium_ops.h
patches/Titanium_structs.h
patches/Underfoot.h
patches/Underfoot_constants.h
patches/Underfoot_itemfields.h
patches/Underfoot_ops.h
patches/Underfoot_structs.h
@ -238,16 +252,19 @@ SOURCE_GROUP(Patches FILES
patches/Client62.h
patches/Client62_itemfields.h
patches/Client62_ops.h
patches/Client62_constants.h
patches/Client62_structs.h
patches/patches.h
patches/SoD.h
patches/SoD_itemfields.h
patches/SoD_ops.h
patches/SoD_constants.h
patches/SoD_structs.h
patches/SoF.h
patches/SoF_itemfields.h
patches/SoF_opcode_list.h
patches/SoF_ops.h
patches/SoF_constants.h
patches/SoF_structs.h
patches/SSDeclare.h
patches/SSDefine.h
@ -255,20 +272,29 @@ SOURCE_GROUP(Patches FILES
patches/RoF.h
patches/RoF_itemfields.h
patches/RoF_ops.h
patches/RoF_constants.h
patches/RoF_structs.h
#patches/RoF2.h
#patches/RoF2_itemfields.h
#patches/RoF2_ops.h
#patches/RoF2_constants.h
#patches/RoF2_structs.h
patches/Titanium.h
patches/Titanium_itemfields.h
patches/Titanium_ops.h
patches/Titanium_constants.h
patches/Titanium_structs.h
patches/Underfoot.h
patches/Underfoot_itemfields.h
patches/Underfoot_ops.h
patches/Underfoot_constants.h
patches/Underfoot_structs.h
patches/Client62.cpp
patches/patches.cpp
patches/SoD.cpp
patches/SoF.cpp
patches/RoF.cpp
#patches/RoF2.cpp
patches/Titanium.cpp
patches/Underfoot.cpp
)
@ -315,11 +341,12 @@ SOURCE_GROUP(TinyXML FILES
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker TinyXML)
ADD_LIBRARY(Common ${common_sources} ${common_headers})
ADD_LIBRARY(common ${common_sources} ${common_headers})
IF(UNIX)
ADD_DEFINITIONS(-fPIC)
#TODO: Add "patches/RoF2.cpp" when it becomes active
SET_SOURCE_FILES_PROPERTIES("patches/SoD.cpp" "patches/SoF.cpp" "patches/RoF.cpp" "patches/Underfoot.cpp" PROPERTIES COMPILE_FLAGS -O0)
ENDIF(UNIX)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/Bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -366,22 +366,6 @@ bool EmuTCPConnection::LineOutQueuePush(char* line) {
safe_delete_array(line);
return(true);
}
if (strcmp(line, "**PACKETMODESS**") == 0) {
MSendQueue.lock();
safe_delete_array(sendbuf);
if (TCPMode == modeConsole)
Send((const uchar*) "\0**PACKETMODESS**\r", 18);
TCPMode = modePacket;
PacketMode = packetModeSocket_Server;
EmuTCPNetPacket_Struct* tnps = 0;
while ((tnps = InModeQueue.pop())) {
SendPacket(tnps);
safe_delete_array(tnps);
}
MSendQueue.unlock();
safe_delete_array(line);
return(true);
}
}
return(TCPConnection::LineOutQueuePush(line));
@ -435,13 +419,6 @@ bool EmuTCPConnection::ConnectIP(uint32 irIP, uint16 irPort, char* errbuf) {
sendbuf = new uchar[sendbuf_size];
memcpy(sendbuf, "\0**PACKETMODEQS**\r", sendbuf_size);
}
else if (PacketMode == packetModeSocket_Server) {
safe_delete_array(sendbuf);
sendbuf_size = 18;
sendbuf_used = sendbuf_size;
sendbuf = new uchar[sendbuf_size];
memcpy(sendbuf, "\0**PACKETMODESS**\r", sendbuf_size);
}
else {
//default: packetModeZone
safe_delete_array(sendbuf);

View File

@ -30,7 +30,7 @@ class EmuTCPServer;
class EmuTCPConnection : public TCPConnection {
public:
enum eTCPMode { modeConsole, modeTransition, modePacket };
enum ePacketMode { packetModeZone, packetModeLauncher, packetModeLogin, packetModeUCS, packetModeQueryServ, packetModeSocket_Server };
enum ePacketMode { packetModeZone, packetModeLauncher, packetModeLogin, packetModeUCS, packetModeQueryServ };
EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, SOCKET iSock, uint32 irIP, uint16 irPort, bool iOldFormat = false);
EmuTCPConnection(bool iOldFormat = false, EmuTCPServer* iRelayServer = 0, eTCPMode iMode = modePacket); // for outgoing connections

View File

@ -166,63 +166,63 @@ ItemInst* Inventory::GetItem(int16 slot_id) const
ItemInst* result = nullptr;
// Cursor
if (slot_id == SLOT_CURSOR) {
if (slot_id == EmuConstants::CURSOR) {
// Cursor slot
result = m_cursor.peek_front();
}
// Non bag slots
else if (slot_id >= 3000 && slot_id <= 3007) {
// Trade slots
else if (slot_id >= EmuConstants::TRADE_BEGIN && slot_id <= EmuConstants::TRADE_END) {
result = _GetItem(m_trade, slot_id);
}
else if (slot_id >= 2500 && slot_id <= 2501) {
else if (slot_id >= EmuConstants::SHARED_BANK_BEGIN && slot_id <= EmuConstants::SHARED_BANK_END) {
// Shared Bank slots
result = _GetItem(m_shbank, slot_id);
}
else if (slot_id >= 2000 && slot_id <= 2023) {
else if (slot_id >= EmuConstants::BANK_BEGIN && slot_id <= EmuConstants::BANK_END) {
// Bank slots
result = _GetItem(m_bank, slot_id);
}
else if ((slot_id >= 22 && slot_id <= 29)) {
else if ((slot_id >= EmuConstants::GENERAL_BEGIN && slot_id <= EmuConstants::GENERAL_END)) {
// Personal inventory slots
result = _GetItem(m_inv, slot_id);
}
else if ((slot_id >= 0 && slot_id <= 21) || (slot_id >= 400 && slot_id <= 404) || (slot_id == 9999)) {
else if ((slot_id >= EmuConstants::EQUIPMENT_BEGIN && slot_id <= EmuConstants::EQUIPMENT_END) ||
(slot_id >= EmuConstants::TRIBUTE_BEGIN && slot_id <= EmuConstants::TRIBUTE_END) || (slot_id == EmuConstants::POWER_SOURCE)) {
// Equippable slots (on body)
result = _GetItem(m_worn, slot_id);
}
// Inner bag slots
else if (slot_id >= 3031 && slot_id <= 3110) {
else if (slot_id >= EmuConstants::TRADE_BAGS_BEGIN && slot_id <= EmuConstants::TRADE_BAGS_END) {
// Trade bag slots
ItemInst* inst = _GetItem(m_trade, Inventory::CalcSlotId(slot_id));
if (inst && inst->IsType(ItemClassContainer)) {
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
}
}
else if (slot_id >= 2531 && slot_id <= 2550) {
else if (slot_id >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
// Shared Bank bag slots
ItemInst* inst = _GetItem(m_shbank, Inventory::CalcSlotId(slot_id));
if (inst && inst->IsType(ItemClassContainer)) {
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
}
}
else if (slot_id >= 2031 && slot_id <= 2270) {
else if (slot_id >= EmuConstants::BANK_BAGS_BEGIN && slot_id <= EmuConstants::BANK_BAGS_END) {
// Bank bag slots
ItemInst* inst = _GetItem(m_bank, Inventory::CalcSlotId(slot_id));
if (inst && inst->IsType(ItemClassContainer)) {
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
}
}
else if (slot_id >= 331 && slot_id <= 340) {
else if (slot_id >= EmuConstants::CURSOR_BAG_BEGIN && slot_id <= EmuConstants::CURSOR_BAG_END) {
// Cursor bag slots
ItemInst* inst = m_cursor.peek_front();
if (inst && inst->IsType(ItemClassContainer)) {
result = inst->GetItem(Inventory::CalcBagIdx(slot_id));
}
}
else if (slot_id >= 251 && slot_id <= 330) {
else if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END) {
// Personal inventory bag slots
ItemInst* inst = _GetItem(m_inv, Inventory::CalcSlotId(slot_id));
if (inst && inst->IsType(ItemClassContainer)) {
@ -258,7 +258,7 @@ int16 Inventory::PutItem(int16 slot_id, const ItemInst& inst)
int16 Inventory::PushCursor(const ItemInst& inst)
{
m_cursor.push(inst.Clone());
return SLOT_CURSOR;
return MainCursor;
}
// Swap items in inventory
@ -332,7 +332,7 @@ ItemInst* Inventory::PopItem(int16 slot_id)
{
ItemInst* p = nullptr;
if (slot_id == SLOT_CURSOR) { // Cursor
if (slot_id == MainCursor) { // Cursor
p = m_cursor.pop();
}
else if ((slot_id >= 0 && slot_id <= 21) || (slot_id >= 400 && slot_id <= 404) || (slot_id == 9999)) { // Worn slots
@ -469,7 +469,7 @@ bool Inventory::HasSpaceForItem(const Item_Struct *ItemToTry, int16 Quantity) {
//when quantity is greater than 1 and not all of quantity can be found in 1 stack.
int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where)
{
int16 slot_id = SLOT_INVALID;
int16 slot_id = INVALID_INDEX;
//Altered by Father Nitwit to support a specification of
//where to search, with a default value to maintain compatibility
@ -477,38 +477,38 @@ int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where)
// Check each inventory bucket
if (where & invWhereWorn) {
slot_id = _HasItem(m_worn, item_id, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWherePersonal) {
slot_id = _HasItem(m_inv, item_id, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereBank) {
slot_id = _HasItem(m_bank, item_id, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereSharedBank) {
slot_id = _HasItem(m_shbank, item_id, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereTrading) {
slot_id = _HasItem(m_trade, item_id, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereCursor) {
// Check cursor queue
slot_id = _HasItem(m_cursor, item_id, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
@ -518,43 +518,43 @@ int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where)
//this function has the same quantity flaw mentioned above in HasItem()
int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
{
int16 slot_id = SLOT_INVALID;
int16 slot_id = INVALID_INDEX;
// Check each inventory bucket
if (where & invWhereWorn) {
slot_id = _HasItemByUse(m_worn, use, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWherePersonal) {
slot_id = _HasItemByUse(m_inv, use, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereBank) {
slot_id = _HasItemByUse(m_bank, use, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereSharedBank) {
slot_id = _HasItemByUse(m_shbank, use, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereTrading) {
slot_id = _HasItemByUse(m_trade, use, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereCursor) {
// Check cursor queue
slot_id = _HasItemByUse(m_cursor, use, quantity);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
@ -563,43 +563,43 @@ int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
int16 Inventory::HasItemByLoreGroup(uint32 loregroup, uint8 where)
{
int16 slot_id = SLOT_INVALID;
int16 slot_id = INVALID_INDEX;
// Check each inventory bucket
if (where & invWhereWorn) {
slot_id = _HasItemByLoreGroup(m_worn, loregroup);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWherePersonal) {
slot_id = _HasItemByLoreGroup(m_inv, loregroup);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereBank) {
slot_id = _HasItemByLoreGroup(m_bank, loregroup);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereSharedBank) {
slot_id = _HasItemByLoreGroup(m_shbank, loregroup);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereTrading) {
slot_id = _HasItemByLoreGroup(m_trade, loregroup);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
if (where & invWhereCursor) {
// Check cursor queue
slot_id = _HasItemByLoreGroup(m_cursor, loregroup);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
return slot_id;
}
@ -644,74 +644,93 @@ int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, boo
if (try_cursor)
// Always room on cursor (it's a queue)
// (we may wish to cap this in the future)
return SLOT_CURSOR;
return MainCursor;
// No available slots
return SLOT_INVALID;
return INVALID_INDEX;
}
// Opposite of below: Get parent bag slot_id from a slot inside of bag
int16 Inventory::CalcSlotId(int16 slot_id)
{
int16 parent_slot_id = SLOT_INVALID;
int16 Inventory::CalcSlotId(int16 slot_id) {
int16 parent_slot_id = INVALID_INDEX;
if (slot_id >= 251 && slot_id <= 330)
parent_slot_id = IDX_INV + (slot_id - 251) / MAX_ITEMS_PER_BAG;
else if (slot_id >= 331 && slot_id <= 340)
parent_slot_id = SLOT_CURSOR;
else if (slot_id >= 2000 && slot_id <= 2023)
parent_slot_id = IDX_BANK + (slot_id - 2000) / MAX_ITEMS_PER_BAG;
else if (slot_id >= 2031 && slot_id <= 2270)
parent_slot_id = IDX_BANK + (slot_id - 2031) / MAX_ITEMS_PER_BAG;
else if (slot_id >= 2531 && slot_id <= 2550)
parent_slot_id = IDX_SHBANK + (slot_id - 2531) / MAX_ITEMS_PER_BAG;
else if (slot_id >= 3100 && slot_id <= 3179)
parent_slot_id = IDX_TRADE + (slot_id - 3100) / MAX_ITEMS_PER_BAG;
if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END)
parent_slot_id = EmuConstants::GENERAL_BEGIN + (slot_id - EmuConstants::GENERAL_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE;
else if (slot_id >= EmuConstants::CURSOR_BAG_BEGIN && slot_id <= EmuConstants::CURSOR_BAG_END)
parent_slot_id = EmuConstants::CURSOR;
/*
// this is not a bag range...
else if (slot_id >= EmuConstants::BANK_BEGIN && slot_id <= EmuConstants::BANK_END)
parent_slot_id = EmuConstants::BANK_BEGIN + (slot_id - EmuConstants::BANK_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE;
*/
else if (slot_id >= EmuConstants::BANK_BAGS_BEGIN && slot_id <= EmuConstants::BANK_BAGS_END)
parent_slot_id = EmuConstants::BANK_BEGIN + (slot_id - EmuConstants::BANK_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE;
else if (slot_id >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END)
parent_slot_id = EmuConstants::SHARED_BANK_BEGIN + (slot_id - EmuConstants::SHARED_BANK_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE;
//else if (slot_id >= 3100 && slot_id <= 3179) should be {3031..3110}..where did this range come from!!? (verified db save range)
else if (slot_id >= EmuConstants::TRADE_BAGS_BEGIN && slot_id <= EmuConstants::TRADE_BAGS_END)
parent_slot_id = EmuConstants::TRADE_BEGIN + (slot_id - EmuConstants::TRADE_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE;
return parent_slot_id;
}
// Calculate slot_id for an item within a bag
int16 Inventory::CalcSlotId(int16 bagslot_id, uint8 bagidx)
{
if (!Inventory::SupportsContainers(bagslot_id)) {
return SLOT_INVALID;
}
int16 Inventory::CalcSlotId(int16 bagslot_id, uint8 bagidx) {
if (!Inventory::SupportsContainers(bagslot_id))
return INVALID_INDEX;
int16 slot_id = SLOT_INVALID;
int16 slot_id = INVALID_INDEX;
if (bagslot_id == SLOT_CURSOR || bagslot_id == 8000) // Cursor
slot_id = IDX_CURSOR_BAG + bagidx;
else if (bagslot_id >= 22 && bagslot_id <= 29) // Inventory slots
slot_id = IDX_INV_BAG + (bagslot_id - 22)*MAX_ITEMS_PER_BAG + bagidx;
else if (bagslot_id >= 2000 && bagslot_id <= 2023) // Bank slots
slot_id = IDX_BANK_BAG + (bagslot_id - 2000)*MAX_ITEMS_PER_BAG + bagidx;
else if (bagslot_id >= 2500 && bagslot_id <= 2501) // Shared bank slots
slot_id = IDX_SHBANK_BAG + (bagslot_id - 2500)*MAX_ITEMS_PER_BAG + bagidx;
else if (bagslot_id >= 3000 && bagslot_id <= 3007) // Trade window slots
slot_id = IDX_TRADE_BAG + (bagslot_id - 3000)*MAX_ITEMS_PER_BAG + bagidx;
if (bagslot_id == EmuConstants::CURSOR || bagslot_id == 8000)
slot_id = EmuConstants::CURSOR_BAG_BEGIN + bagidx;
else if (bagslot_id >= EmuConstants::GENERAL_BEGIN && bagslot_id <= EmuConstants::GENERAL_END)
slot_id = EmuConstants::GENERAL_BAGS_BEGIN + (bagslot_id - EmuConstants::GENERAL_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE + bagidx;
else if (bagslot_id >= EmuConstants::BANK_BEGIN && bagslot_id <= EmuConstants::BANK_END)
slot_id = EmuConstants::BANK_BAGS_BEGIN + (bagslot_id - EmuConstants::BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE + bagidx;
else if (bagslot_id >= EmuConstants::SHARED_BANK_BEGIN && bagslot_id <= EmuConstants::SHARED_BANK_END)
slot_id = EmuConstants::SHARED_BANK_BAGS_BEGIN + (bagslot_id - EmuConstants::SHARED_BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE + bagidx;
else if (bagslot_id >= EmuConstants::TRADE_BEGIN && bagslot_id <= EmuConstants::TRADE_END)
slot_id = EmuConstants::TRADE_BAGS_BEGIN + (bagslot_id - EmuConstants::TRADE_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE + bagidx;
return slot_id;
}
uint8 Inventory::CalcBagIdx(int16 slot_id)
{
uint8 Inventory::CalcBagIdx(int16 slot_id) {
uint8 index = 0;
if (slot_id >= 251 && slot_id <= 330)
index = (slot_id - 251) % MAX_ITEMS_PER_BAG;
else if (slot_id >= 331 && slot_id <= 340)
index = (slot_id - 331) % MAX_ITEMS_PER_BAG;
else if (slot_id >= 2000 && slot_id <= 2023)
index = (slot_id - 2000) % MAX_ITEMS_PER_BAG;
else if (slot_id >= 2031 && slot_id <= 2270)
index = (slot_id - 2031) % MAX_ITEMS_PER_BAG;
else if (slot_id >= 2531 && slot_id <= 2550)
index = (slot_id - 2531) % MAX_ITEMS_PER_BAG;
else if (slot_id >= 3100 && slot_id <= 3179)
index = (slot_id - 3100) % MAX_ITEMS_PER_BAG;
else if (slot_id >= 4000 && slot_id <= 4009)
index = (slot_id - 4000) % MAX_ITEMS_PER_BAG;
if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END)
index = (slot_id - EmuConstants::GENERAL_BAGS_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE;
else if (slot_id >= EmuConstants::CURSOR_BAG_BEGIN && slot_id <= EmuConstants::CURSOR_BAG_END)
index = (slot_id - EmuConstants::CURSOR_BAG_BEGIN); // % EmuConstants::ITEM_CONTAINER_SIZE; - not needed since range is 10 slots
/*
// this is not a bag range...
else if (slot_id >= EmuConstants::BANK_BEGIN && slot_id <= EmuConstants::BANK_END)
index = (slot_id - EmuConstants::BANK_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE;
*/
else if (slot_id >= EmuConstants::BANK_BAGS_BEGIN && slot_id <= EmuConstants::BANK_BAGS_END)
index = (slot_id - EmuConstants::BANK_BAGS_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE;
else if (slot_id >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END)
index = (slot_id - EmuConstants::SHARED_BANK_BAGS_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE;
else if (slot_id >= EmuConstants::TRADE_BAGS_BEGIN && slot_id <= EmuConstants::TRADE_BAGS_END)
index = (slot_id - EmuConstants::TRADE_BAGS_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE;
// odd..but, ok... (probably a range-slot conversion for ItemInst* Object::item
else if (slot_id >= EmuConstants::WORLD_BEGIN && slot_id <= EmuConstants::WORLD_END)
index = (slot_id - EmuConstants::WORLD_BEGIN); // % EmuConstants::ITEM_CONTAINER_SIZE; - not needed since range is 10 slots
return index;
}
@ -721,25 +740,25 @@ int16 Inventory::CalcSlotFromMaterial(uint8 material)
switch (material)
{
case MaterialHead:
return SLOT_HEAD;
return MainHead;
case MaterialChest:
return SLOT_CHEST;
return MainChest;
case MaterialArms:
return SLOT_ARMS;
return MainArms;
case MaterialWrist:
return SLOT_BRACER01; // there's 2 bracers, only one bracer material
return MainWrist1; // there's 2 bracers, only one bracer material
case MaterialHands:
return SLOT_HANDS;
return MainHands;
case MaterialLegs:
return SLOT_LEGS;
return MainLegs;
case MaterialFeet:
return SLOT_FEET;
return MainFeet;
case MaterialPrimary:
return SLOT_PRIMARY;
return MainPrimary;
case MaterialSecondary:
return SLOT_SECONDARY;
return MainSecondary;
default:
return SLOT_INVALID;
return INVALID_INDEX;
}
}
@ -747,24 +766,24 @@ uint8 Inventory::CalcMaterialFromSlot(int16 equipslot)
{
switch (equipslot)
{
case SLOT_HEAD:
case MainHead:
return MaterialHead;
case SLOT_CHEST:
case MainChest:
return MaterialChest;
case SLOT_ARMS:
case MainArms:
return MaterialArms;
case SLOT_BRACER01:
case SLOT_BRACER02:
case MainWrist1:
//case SLOT_BRACER02: // non-live behavior
return MaterialWrist;
case SLOT_HANDS:
case MainHands:
return MaterialHands;
case SLOT_LEGS:
case MainLegs:
return MaterialLegs;
case SLOT_FEET:
case MainFeet:
return MaterialFeet;
case SLOT_PRIMARY:
case MainPrimary:
return MaterialPrimary;
case SLOT_SECONDARY:
case MainSecondary:
return MaterialSecondary;
default:
return _MaterialInvalid;
@ -790,7 +809,7 @@ bool Inventory::SupportsContainers(int16 slot_id)
if ((slot_id >= 22 && slot_id <= 30) || // Personal inventory slots
(slot_id >= 2000 && slot_id <= 2023) || // Bank slots
(slot_id >= 2500 && slot_id <= 2501) || // Shared bank slots
(slot_id == SLOT_CURSOR) || // Cursor
(slot_id == MainCursor) || // Cursor
(slot_id >= 3000 && slot_id <= 3007)) // Trade window
return true;
return false;
@ -826,7 +845,7 @@ int Inventory::GetSlotByItemInst(ItemInst *inst) {
}
if (m_cursor.peek_front() == inst) {
return SLOT_CURSOR;
return MainCursor;
}
return -1;
@ -944,9 +963,9 @@ int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst)
return slot_id;
}
int16 result = SLOT_INVALID;
int16 result = INVALID_INDEX;
if (slot_id == SLOT_CURSOR) { // Cursor
if (slot_id == MainCursor) { // Cursor
// Replace current item on cursor, if exists
m_cursor.pop(); // no memory delete, clients of this function know what they are doing
m_cursor.push_front(inst);
@ -981,7 +1000,7 @@ int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst)
}
}
if (result == SLOT_INVALID) {
if (result == INVALID_INDEX) {
LogFile->write(EQEMuLog::Error, "Inventory::_PutItem: Invalid slot_id specified (%i)", slot_id);
Inventory::MarkDirty(inst); // Slot not found, clean up
}
@ -1007,7 +1026,7 @@ int16 Inventory::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, ui
return it->first;
}
for (int i = 0; i < MAX_AUGMENT_SLOTS; i++) {
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (inst->GetAugmentItemID(i) == item_id && quantity <= 1)
return SLOT_AUGMENT; // Only one augment per slot.
}
@ -1022,7 +1041,7 @@ int16 Inventory::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, ui
if (quantity_found >= quantity)
return Inventory::CalcSlotId(it->first, itb->first);
}
for (int i = 0; i < MAX_AUGMENT_SLOTS; i++) {
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (baginst->GetAugmentItemID(i) == item_id && quantity <= 1)
return SLOT_AUGMENT; // Only one augment per slot.
}
@ -1031,7 +1050,7 @@ int16 Inventory::_HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, ui
}
// Not found
return SLOT_INVALID;
return INVALID_INDEX;
}
// Internal Method: Checks an inventory queue type bucket for a particular item
@ -1049,9 +1068,9 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
if (inst->GetID() == item_id) {
quantity_found += (inst->GetCharges() <= 0) ? 1 : inst->GetCharges();
if (quantity_found >= quantity)
return SLOT_CURSOR;
return MainCursor;
}
for (int i = 0; i < MAX_AUGMENT_SLOTS; i++) {
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (inst->GetAugmentItemID(i) == item_id && quantity <= 1)
return SLOT_AUGMENT; // Only one augment per slot.
}
@ -1064,9 +1083,9 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
if (baginst->GetID() == item_id) {
quantity_found += (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges();
if (quantity_found >= quantity)
return Inventory::CalcSlotId(SLOT_CURSOR, itb->first);
return Inventory::CalcSlotId(MainCursor, itb->first);
}
for (int i = 0; i < MAX_AUGMENT_SLOTS; i++) {
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (baginst->GetAugmentItemID(i) == item_id && quantity <= 1)
return SLOT_AUGMENT; // Only one augment per slot.
}
@ -1076,7 +1095,7 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
}
// Not found
return SLOT_INVALID;
return INVALID_INDEX;
}
// Internal Method: Checks an inventory bucket for a particular item
@ -1111,7 +1130,7 @@ int16 Inventory::_HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, ui
}
// Not found
return SLOT_INVALID;
return INVALID_INDEX;
}
// Internal Method: Checks an inventory queue type bucket for a particular item
@ -1127,7 +1146,7 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
if (inst && inst->IsType(ItemClassCommon) && inst->GetItem()->ItemType == use) {
quantity_found += (inst->GetCharges() <= 0) ? 1 : inst->GetCharges();
if (quantity_found >= quantity)
return SLOT_CURSOR;
return MainCursor;
}
// Go through bag, if bag
@ -1138,14 +1157,14 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
if (baginst && baginst->IsType(ItemClassCommon) && baginst->GetItem()->ItemType == use) {
quantity_found += (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges();
if (quantity_found >= quantity)
return Inventory::CalcSlotId(SLOT_CURSOR, itb->first);
return Inventory::CalcSlotId(MainCursor, itb->first);
}
}
}
}
// Not found
return SLOT_INVALID;
return INVALID_INDEX;
}
int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32 loregroup)
@ -1162,7 +1181,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32
return it->first;
ItemInst* Aug;
for (int i = 0; i < MAX_AUGMENT_SLOTS; i++) {
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
Aug = inst->GetAugment(i);
if (Aug && Aug->GetItem()->LoreGroup == loregroup)
return SLOT_AUGMENT; // Only one augment per slot.
@ -1177,7 +1196,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32
return Inventory::CalcSlotId(it->first, itb->first);
ItemInst* Aug2;
for (int i = 0; i < MAX_AUGMENT_SLOTS; i++) {
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
Aug2 = baginst->GetAugment(i);
if (Aug2 && Aug2->GetItem()->LoreGroup == loregroup)
return SLOT_AUGMENT; // Only one augment per slot.
@ -1187,7 +1206,7 @@ int16 Inventory::_HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32
}
// Not found
return SLOT_INVALID;
return INVALID_INDEX;
}
// Internal Method: Checks an inventory queue type bucket for a particular item
@ -1202,10 +1221,10 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
if (inst)
{
if (inst->GetItem()->LoreGroup == loregroup)
return SLOT_CURSOR;
return MainCursor;
ItemInst* Aug;
for (int i = 0; i < MAX_AUGMENT_SLOTS; i++) {
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
Aug = inst->GetAugment(i);
if (Aug && Aug->GetItem()->LoreGroup == loregroup)
return SLOT_AUGMENT; // Only one augment per slot.
@ -1217,11 +1236,11 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
for (itb = inst->_begin(); itb != inst->_end(); ++itb) {
ItemInst* baginst = itb->second;
if (baginst && baginst->IsType(ItemClassCommon) && baginst->GetItem()->LoreGroup == loregroup)
return Inventory::CalcSlotId(SLOT_CURSOR, itb->first);
return Inventory::CalcSlotId(MainCursor, itb->first);
ItemInst* Aug2;
for (int i = 0; i < MAX_AUGMENT_SLOTS; i++) {
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
Aug2 = baginst->GetAugment(i);
if (Aug2 && Aug2->GetItem()->LoreGroup == loregroup)
return SLOT_AUGMENT; // Only one augment per slot.
@ -1232,7 +1251,7 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
}
// Not found
return SLOT_INVALID;
return INVALID_INDEX;
}
@ -1656,7 +1675,7 @@ ItemInst* ItemInst::RemoveAugment(uint8 index)
bool ItemInst::IsAugmented()
{
for (int i = 0; i < MAX_AUGMENT_SLOTS; ++i)
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
if (GetAugmentItemID(i))
return true;

View File

@ -55,21 +55,6 @@ namespace ItemField
};
};
// Indexing positions to the beginning slot_id's for a bucket of slots
#define IDX_EQUIP 0
#define IDX_CURSOR_BAG 331
#define IDX_INV 22
#define IDX_INV_BAG 251
#define IDX_TRIBUTE 400
#define IDX_BANK 2000
#define IDX_BANK_BAG 2031
#define IDX_SHBANK 2500
#define IDX_SHBANK_BAG 2531
#define IDX_TRADE 3000
#define IDX_TRADE_BAG 3031
#define IDX_TRADESKILL 4000
#define MAX_ITEMS_PER_BAG 10
// Specifies usage type for item inside ItemInst
enum ItemInstTypes
{

View File

@ -7,8 +7,8 @@
#endif
#include <mysql.h>
#include "../common/types.h"
#include "../common/MySQLRequestRow.h"
#include "types.h"
#include "MySQLRequestRow.h"
#include <string>
#include <string.h>
#include <limits.h>

View File

@ -8,7 +8,7 @@
#include <mysql.h>
#include <iterator>
#include "../common/types.h"
#include "types.h"
class MySQLRequestRow : public std::iterator<std::input_iterator_tag, MYSQL_ROW>
{

View File

@ -1,27 +1,42 @@
#ifndef CLIENTVERSIONS_H
#define CLIENTVERSIONS_H
static const uint32 BIT_Client62 = 1;
static const uint32 BIT_Titanium = 2;
static const uint32 BIT_SoF = 4;
static const uint32 BIT_SoD = 8;
static const uint32 BIT_Underfoot = 16;
static const uint32 BIT_RoF = 32;
static const uint32 BIT_TitaniumAndEarlier = 3;
static const uint32 BIT_SoFAndLater = 0xFFFFFFFC;
static const uint32 BIT_SoDAndLater = 0xFFFFFFF8;
static const uint32 BIT_UnderfootAndLater = 0xFFFFFFF0;
static const uint32 BIT_RoFAndLater = 0xFFFFFFE0;
static const uint32 BIT_AllClients = 0xFFFFFFFF;
static const uint32 BIT_Client62 = 1;
static const uint32 BIT_Titanium = 2;
static const uint32 BIT_SoF = 4;
static const uint32 BIT_SoD = 8;
static const uint32 BIT_Underfoot = 16;
static const uint32 BIT_RoF = 32;
static const uint32 BIT_RoF2 = 64;
static const uint32 BIT_TitaniumAndEarlier = 0x00000003;
static const uint32 BIT_SoFAndLater = 0xFFFFFFFC;
static const uint32 BIT_SoDAndLater = 0xFFFFFFF8;
static const uint32 BIT_UnderfootAndLater = 0xFFFFFFF0;
static const uint32 BIT_RoFAndLater = 0xFFFFFFE0;
static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0;
static const uint32 BIT_AllClients = 0xFFFFFFFF;
typedef enum {
EQClientUnknown = 0,
EQClient62,
EQClientTitanium,
EQClientSoF,
EQClientSoD,
EQClientUnderfoot,
EQClientRoF
EQClient62, // Build: 'Aug 4 2005 15:40:59'
EQClientTitanium, // Build: 'Oct 31 2005 10:33:37'
EQClientSoF, // Build: 'Sep 7 2007 09:11:49'
EQClientSoD, // Build: 'Dec 19 2008 15:22:49'
EQClientUnderfoot, // Build: 'Jun 8 2010 16:44:32'
EQClientRoF, // Build: 'Dec 10 2012 17:35:44'
EQClientRoF2, // Build: 'May 10 2013 23:30:08'
_EQClientCount, // place new clients before this point (preferably, in release/attribute order)
// Values below are not implemented, as yet...
EmuNPC = _EQClientCount,
EmuMerc,
EmuBot,
EmuPet,
_EmuClientCount // array size for EQLimits
} EQClientVersion;
#endif /* CLIENTVERSIONS_H */

View File

@ -793,7 +793,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven
// Doodman: Is this even used?
// now the inventory
for (i=0; i<=2270;)
for (i = EmuConstants::POSSESSIONS_BEGIN; i <= EmuConstants::BANK_BAGS_END;)
{
const ItemInst* newinv = inv->GetItem((int16)i);
if (newinv)
@ -821,14 +821,16 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven
safe_delete_array(invquery);
}
if(i==30){ //end of standard inventory/cursor, jump to internals of bags/cursor
i = 251;
if (i == EmuConstants::CURSOR) {
i = EmuConstants::GENERAL_BAGS_BEGIN;
continue;
} else if(i==340){ //end of internals of bags/cursor, jump to bank slots
i = 2000;
}
else if (i == EmuConstants::CURSOR_BAG_END) {
i = EmuConstants::BANK_BEGIN;
continue;
} else if(i==2023){ //end of bank slots, jump to internals of bank bags
i = 2031;
}
else if (i == EmuConstants::BANK_END) {
i = EmuConstants::BANK_BAGS_BEGIN;
continue;
}

View File

@ -539,3 +539,4 @@ N(OP_MercenaryTimerRequest),
N(OP_OpenInventory),
N(OP_OpenContainer),
N(OP_Marquee),
N(OP_ClientTimeStamp),

View File

@ -138,45 +138,86 @@ enum ItemUseTypes : uint8
};
/*
** Augmentation use types (in-work)
** Augmentation use type bitmasks (1-based)
**
** (ref: dbstr_us.txt)
**
*/
enum AugmentationUseTypes : uint32 {
AugTypeNone = 0, // not 100% sure on this...
AugTypeGeneralSingleStat, /*1^16^1 (General: Single Stat)^0*/
AugTypeGeneralMultipleStat, /*2^16^2 (General: Multiple Stat)^0*/
AugTypeGeneralSpellEffect, /*3^16^3 (General: Spell Effect)^0*/
AugTypeWeaponGeneral, /*4^16^4 (Weapon: General)^0*/
AugTypeWeaponElemDamage, /*5^16^5 (Weapon: Elem Damage)^0*/
AugTypeWeaponBaseDamage, /*6^16^6 (Weapon: Base Damage)^0*/
AugTypeGeneralGroup, /*7^16^7 (General: Group)^0*/
AugTypeGeneralRaid, /*8^16^8 (General: Raid)^0*/
AugTypeGeneralDragonsPoints, /*9^16^9 (General: Dragons Points)^0*/
AugTypeCraftedCommon, /*10^16^10 (Crafted: Common)^0*/
AugTypeCraftedGroup1, /*11^16^11 (Crafted: Group)^0*/
AugTypeCraftedRaid1, /*12^16^12 (Crafted: Raid)^0*/
AugTypeEnergeiacGroup, /*13^16^13 (Energeiac: Group)^0*/
AugTypeEnergeiacRaid, /*14^16^14 (Energeiac: Raid)^0*/
AugTypeEmblem, /*15^16^15 (Emblem)^0*/
AugTypeCraftedGroup2, /*16^16^16 (Crafted: Group)^0*/
AugTypeCraftedRaid2, /*17^16^17 (Crafted: Raid)^0*/
AugTypeUnknown1, /*18^16^18^0*/
AugTypeUnknown2, /*19^16^19^0*/
AugTypeOrnamentation, /*20^16^20 (Ornamentation)^0*/
AugTypeSpecialOrnamentation, /*21^16^21 (Special Ornamentation)^0*/
AugTypeUnknown3, /*22^16^22^0*/
AugTypeUnknown4, /*23^16^23^0*/
AugTypeUnknown5, /*24^16^24^0*/
AugTypeUnknown6, /*25^16^25^0*/
AugTypeUnknown7, /*26^16^26^0*/
AugTypeUnknown8, /*27^16^27^0*/
AugTypeUnknown9, /*28^16^28^0*/
AugTypeUnknown10, /*29^16^29^0*/
AugTypeEpic25, /*30^16^30^0*/
AugTypeTest, /*31^16^Test^0*/ // listed as 31^16^31^0 in 5-10 client
_AugTypeCount
enum AugmentationUseTypeBitmasks : uint32 {
AugUseNone = 0x00000000,
AugUseGeneralSingleStat = 0x00000001, /*1^16^1 (General: Single Stat)^0*/
AugUseGeneralMultipleStat = 0x00000002, /*2^16^2 (General: Multiple Stat)^0*/
AugUseGeneralSpellEffect = 0x00000004, /*3^16^3 (General: Spell Effect)^0*/
AugUseWeaponGeneral = 0x00000008, /*4^16^4 (Weapon: General)^0*/
AugUseWeaponElemDamage = 0x00000010, /*5^16^5 (Weapon: Elem Damage)^0*/
AugUseWeaponBaseDamage = 0x00000020, /*6^16^6 (Weapon: Base Damage)^0*/
AugUseGeneralGroup = 0x00000040, /*7^16^7 (General: Group)^0*/
AugUseGeneralRaid = 0x00000080, /*8^16^8 (General: Raid)^0*/
AugUseGeneralDragonsPoints = 0x00000100, /*9^16^9 (General: Dragons Points)^0*/
AugUseCraftedCommon = 0x00000200, /*10^16^10 (Crafted: Common)^0*/
AugUseCraftedGroup1 = 0x00000400, /*11^16^11 (Crafted: Group)^0*/
AugUseCraftedRaid1 = 0x00000800, /*12^16^12 (Crafted: Raid)^0*/
AugUseEnergeiacGroup = 0x00001000, /*13^16^13 (Energeiac: Group)^0*/
AugUseEnergeiacRaid = 0x00002000, /*14^16^14 (Energeiac: Raid)^0*/
AugUseEmblem = 0x00004000, /*15^16^15 (Emblem)^0*/
AugUseCraftedGroup2 = 0x00008000, /*16^16^16 (Crafted: Group)^0*/
AugUseCraftedRaid2 = 0x00010000, /*17^16^17 (Crafted: Raid)^0*/
AugUseUnknown1 = 0x00020000, /*18^16^18^0*/
AugUseUnknown2 = 0x00040000, /*19^16^19^0*/
AugUseOrnamentation = 0x00080000, /*20^16^20 (Ornamentation)^0*/
AugUseSpecialOrnamentation = 0x00100000, /*21^16^21 (Special Ornamentation)^0*/
AugUseUnknown3 = 0x00200000, /*22^16^22^0*/
AugUseUnknown4 = 0x00400000, /*23^16^23^0*/
AugUseUnknown5 = 0x00800000, /*24^16^24^0*/
AugUseUnknown6 = 0x01000000, /*25^16^25^0*/
AugUseUnknown7 = 0x02000000, /*26^16^26^0*/
AugUseUnknown8 = 0x04000000, /*27^16^27^0*/
AugUseUnknown9 = 0x08000000, /*28^16^28^0*/
AugUseUnknown10 = 0x10000000, /*29^16^29^0*/
AugUseEpic25 = 0x20000000, /*30^16^30^0*/
AugUseTest = 0x40000000, /*31^16^Test^0*/ // listed as 31^16^31^0 in 5-10 client
AugUseAll = 0xFFFFFFFF
};
/*
** Augmentation use types (enumerated)
**
*/
enum AugmentationUseTypes : uint8 {
AugTypeNone = 0,
AugTypeGeneralSingleStat,
AugTypeGeneralMultipleStat,
AugTypeGeneralSpellEffect,
AugTypeWeaponGeneral,
AugTypeWeaponElemDamage,
AugTypeWeaponBaseDamage,
AugTypeGeneralGroup,
AugTypeGeneralRaid,
AugTypeGeneralDragonsPoints,
AugTypeCraftedCommon,
AugTypeCraftedGroup1,
AugTypeCraftedRaid1,
AugTypeEnergeiacGroup,
AugTypeEnergeiacRaid,
AugTypeEmblem,
AugTypeCraftedGroup2,
AugTypeCraftedRaid2,
AugTypeUnknown1,
AugTypeUnknown2,
AugTypeOrnamentation,
AugTypeSpecialOrnamentation,
AugTypeUnknown3,
AugTypeUnknown4,
AugTypeUnknown5,
AugTypeUnknown6,
AugTypeUnknown7,
AugTypeUnknown8,
AugTypeUnknown9,
AugTypeUnknown10,
AugTypeEpic25,
AugTypeTest,
_AugTypeCount,
AugTypeAll = 255
};
/*
@ -735,10 +776,11 @@ enum MaterialUseSlots : uint8
_MaterialInvalid = 255
};
/*
// Used for worn NPC inventory tracking. NPCs don't use
// augments, so only the basic slots need to be kept track of.
#define MAX_WORN_INVENTORY 22
*/
/*
** Inventory Slot Equipment Enum
@ -768,42 +810,109 @@ enum MaterialUseSlots : uint8
**
*/
enum InventoryMapTypes : int16 {
MapPossessions = 0,
MapBank,
MapSharedBank,
MapTrade,
MapWorld,
MapLimbo,
MapTribute,
MapTrophyTribute,
MapGuildTribute,
MapMerchant,
MapDeleted,
MapCorpse,
MapBazaar,
MapInspect,
MapRealEstate,
MapViewMODPC,
MapViewMODBank,
MapViewMODSharedBank,
MapViewMODLimbo,
MapAltStorage,
MapArchived,
MapMail,
MapGuildTrophyTribute,
MapKrono,
MapOther,
_MapCount
};
enum InventoryMainTypes : int16 {
MainCharm = 0,
MainEar1,
MainHead,
MainFace,
MainEar2,
MainNeck,
MainShoulders,
MainArms,
MainBack,
MainWrist1,
MainWrist2,
MainRange,
MainHands,
MainPrimary,
MainSecondary,
MainFinger1,
MainFinger2,
MainChest,
MainLegs,
MainFeet,
MainWaist,
MainPowerSource = 9999, // temp
MainAmmo = 21, // temp
MainGeneral1,
MainGeneral2,
MainGeneral3,
MainGeneral4,
MainGeneral5,
MainGeneral6,
MainGeneral7,
MainGeneral8,
//MainGeneral9,
//MainGeneral10,
MainCursor,
_MainCount
};
enum InventorySlot
{
////////////////////////
// Equip slots
////////////////////////
SLOT_CHARM = 0,
SLOT_EAR01 = 1,
SLOT_HEAD = 2,
SLOT_FACE = 3,
SLOT_EAR02 = 4,
SLOT_NECK = 5,
SLOT_SHOULDER = 6,
SLOT_ARMS = 7,
SLOT_BACK = 8,
SLOT_BRACER01 = 9,
SLOT_BRACER02 = 10,
SLOT_RANGE = 11,
SLOT_HANDS = 12,
SLOT_PRIMARY = 13,
SLOT_SECONDARY = 14,
SLOT_RING01 = 15,
SLOT_RING02 = 16,
SLOT_CHEST = 17,
SLOT_LEGS = 18,
SLOT_FEET = 19,
SLOT_WAIST = 20,
SLOT_AMMO = 21,
//SLOT_CHARM = 0,
//SLOT_EAR01 = 1,
//SLOT_HEAD = 2,
//SLOT_FACE = 3,
//SLOT_EAR02 = 4,
//SLOT_NECK = 5,
//SLOT_SHOULDER = 6,
//SLOT_ARMS = 7,
//SLOT_BACK = 8,
//SLOT_BRACER01 = 9,
//SLOT_BRACER02 = 10,
//SLOT_RANGE = 11,
//SLOT_HANDS = 12,
//SLOT_PRIMARY = 13,
//SLOT_SECONDARY = 14,
//SLOT_RING01 = 15,
//SLOT_RING02 = 16,
//SLOT_CHEST = 17,
//SLOT_LEGS = 18,
//SLOT_FEET = 19,
//SLOT_WAIST = 20,
//SLOT_AMMO = 21,
////////////////////////
// All other slots
////////////////////////
SLOT_PERSONAL_BEGIN = 22,
SLOT_PERSONAL_END = 29,
//SLOT_PERSONAL_BEGIN = 22,
//SLOT_PERSONAL_END = 29,
SLOT_CURSOR = 30,
//SLOT_CURSOR = 30,
SLOT_CURSOR_END = (int16)0xFFFE, // Last item on cursor queue
// Cursor bag slots are 331->340 (10 slots)
@ -830,11 +939,21 @@ enum InventorySlot
// Slot used in OP_TradeSkillCombine for world tradeskill containers
SLOT_TRADESKILL = 1000,
SLOT_AUGMENT = 1001,
SLOT_POWER_SOURCE = 9999,
SLOT_AUGMENT = 1001//,
//SLOT_POWER_SOURCE = 9999//,
// Value recognized by client for destroying an item
SLOT_INVALID = (int16)0xFFFF
//SLOT_INVALID = (int16)0xFFFF
};
#define INVALID_INDEX -1
#define NOT_USED 0
#define NO_ITEM 0
// yes..these are redundant... but, they help to identify and define what is actually being performed
// plus, since they're pre-op's, they don't affect the actual binary size
#define MAP_BEGIN 0
#define MAIN_BEGIN 0
#define SUB_BEGIN 0
#define AUG_BEGIN 0
#endif

961
common/eq_dictionary.cpp Normal file
View File

@ -0,0 +1,961 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "eq_dictionary.h"
#include "StringUtil.h"
//
// class ServerConstants
//
uint16 EmuConstants::InventoryMapSize(int16 map) {
switch (map) {
case MapPossessions:
return MAP_POSSESSIONS_SIZE;
case MapBank:
return MAP_BANK_SIZE;
case MapSharedBank:
return MAP_SHARED_BANK_SIZE;
case MapTrade:
return MAP_TRADE_SIZE;
case MapWorld:
return MAP_WORLD_SIZE;
case MapLimbo:
return MAP_LIMBO_SIZE;
case MapTribute:
return MAP_TRIBUTE_SIZE;
case MapTrophyTribute:
return MAP_TROPHY_TRIBUTE_SIZE;
case MapGuildTribute:
return MAP_GUILD_TRIBUTE_SIZE;
case MapMerchant:
return MAP_MERCHANT_SIZE;
case MapDeleted:
return MAP_DELETED_SIZE;
case MapCorpse:
return MAP_CORPSE_SIZE;
case MapBazaar:
return MAP_BAZAAR_SIZE;
case MapInspect:
return MAP_INSPECT_SIZE;
case MapRealEstate:
return MAP_REAL_ESTATE_SIZE;
case MapViewMODPC:
return MAP_VIEW_MOD_PC_SIZE;
case MapViewMODBank:
return MAP_VIEW_MOD_BANK_SIZE;
case MapViewMODSharedBank:
return MAP_VIEW_MOD_SHARED_BANK_SIZE;
case MapViewMODLimbo:
return MAP_VIEW_MOD_LIMBO_SIZE;
case MapAltStorage:
return MAP_ALT_STORAGE_SIZE;
case MapArchived:
return MAP_ARCHIVED_SIZE;
case MapMail:
return MAP_MAIL_SIZE;
case MapGuildTrophyTribute:
return MAP_GUILD_TROPHY_TRIBUTE_SIZE;
case MapKrono:
return MAP_KRONO_SIZE;
case MapOther:
return MAP_OTHER_SIZE;
default:
return NOT_USED;
}
}
/*
std::string EmuConstants::InventoryLocationName(Location_Struct location) {
// not ready for implementation...
std::string ret_str;
StringFormat(ret_str, "%s, %s, %s, %s", InventoryMapName(location.map), InventoryMainName(location.main), InventorySubName(location.sub), InventoryAugName(location.aug));
return ret_str;
}
*/
std::string EmuConstants::InventoryMapName(int16 map) {
switch (map) {
case INVALID_INDEX:
return "Invalid Map";
case MapPossessions:
return "Possessions";
case MapBank:
return "Bank";
case MapSharedBank:
return "Shared Bank";
case MapTrade:
return "Trade";
case MapWorld:
return "World";
case MapLimbo:
return "Limbo";
case MapTribute:
return "Tribute";
case MapTrophyTribute:
return "Trophy Tribute";
case MapGuildTribute:
return "Guild Tribute";
case MapMerchant:
return "Merchant";
case MapDeleted:
return "Deleted";
case MapCorpse:
return "Corpse";
case MapBazaar:
return "Bazaar";
case MapInspect:
return "Inspect";
case MapRealEstate:
return "Real Estate";
case MapViewMODPC:
return "View MOD PC";
case MapViewMODBank:
return "View MOD Bank";
case MapViewMODSharedBank:
return "View MOD Shared Bank";
case MapViewMODLimbo:
return "View MOD Limbo";
case MapAltStorage:
return "Alt Storage";
case MapArchived:
return "Archived";
case MapMail:
return "Mail";
case MapGuildTrophyTribute:
return "Guild Trophy Tribute";
case MapKrono:
return "Krono";
case MapOther:
return "Other";
default:
return "Unknown Map";
}
}
std::string EmuConstants::InventoryMainName(int16 main) {
switch (main) {
case INVALID_INDEX:
return "Invalid Main";
case MainCharm:
return "Charm";
case MainEar1:
return "Ear 1";
case MainHead:
return "Head";
case MainFace:
return "Face";
case MainEar2:
return "Ear 2";
case MainNeck:
return "Neck";
case MainShoulders:
return "Shoulders";
case MainArms:
return "Arms";
case MainBack:
return "Back";
case MainWrist1:
return "Wrist 1";
case MainWrist2:
return "Wrist 2";
case MainRange:
return "Range";
case MainHands:
return "Hands";
case MainPrimary:
return "Primary";
case MainSecondary:
return "Secondary";
case MainFinger1:
return "Finger 1";
case MainFinger2:
return "Finger 2";
case MainChest:
return "Chest";
case MainLegs:
return "Legs";
case MainFeet:
return "Feet";
case MainWaist:
return "Waist";
case MainPowerSource:
return "Power Source";
case MainAmmo:
return "Ammo";
case MainGeneral1:
return "General 1";
case MainGeneral2:
return "General 2";
case MainGeneral3:
return "General 3";
case MainGeneral4:
return "General 4";
case MainGeneral5:
return "General 5";
case MainGeneral6:
return "General 6";
case MainGeneral7:
return "General 7";
case MainGeneral8:
return "General 8";
/*
case MainGeneral9:
return "General 9";
case MainGeneral10:
return "General 10";
*/
case MainCursor:
return "Cursor";
default:
return "Unknown Main";
}
}
std::string EmuConstants::InventorySubName(int16 sub) {
if (sub == INVALID_INDEX)
return "Invalid Sub";
if ((uint16)sub >= ITEM_CONTAINER_SIZE)
return "Unknown Sub";
std::string ret_str;
StringFormat(ret_str, "Container %i", (sub + 1)); // zero-based index..but, count starts at one
return ret_str;
}
std::string EmuConstants::InventoryAugName(int16 aug) {
if (aug == INVALID_INDEX)
return "Invalid Aug";
if ((uint16)aug >= ITEM_COMMON_SIZE)
return "Unknown Aug";
std::string ret_str;
StringFormat(ret_str, "Augment %i", (aug + 1)); // zero-based index..but, count starts at one
return ret_str;
}
//
// class ClientLimits
//
// client validation
bool EQLimits::IsValidClientVersion(uint32 version) {
if (version < _EQClientCount)
return true;
return false;
}
uint32 EQLimits::ValidateClientVersion(uint32 version) {
if (version < _EQClientCount)
return version;
return EQClientUnknown;
}
EQClientVersion EQLimits::ValidateClientVersion(EQClientVersion version) {
if (version >= EQClientUnknown)
if (version < _EQClientCount)
return version;
return EQClientUnknown;
}
// npc validation
bool EQLimits::IsValidNPCVersion(uint32 version) {
if (version >= _EQClientCount)
if (version < _EmuClientCount)
return true;
return false;
}
uint32 EQLimits::ValidateNPCVersion(uint32 version) {
if (version >= _EQClientCount)
if (version < _EmuClientCount)
return version;
return EQClientUnknown;
}
EQClientVersion EQLimits::ValidateNPCVersion(EQClientVersion version) {
if (version >= _EQClientCount)
if (version < _EmuClientCount)
return version;
return EQClientUnknown;
}
// mob validation
bool EQLimits::IsValidMobVersion(uint32 version) {
if (version < _EmuClientCount)
return true;
return false;
}
uint32 EQLimits::ValidateMobVersion(uint32 version) {
if (version < _EmuClientCount)
return version;
return EQClientUnknown;
}
EQClientVersion EQLimits::ValidateMobVersion(EQClientVersion version) {
if (version >= EQClientUnknown)
if (version < _EmuClientCount)
return version;
return EQClientUnknown;
}
// inventory
uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) {
// not all maps will have an instantiated container..some are references for queue generators (i.e., bazaar, mail, etc...)
// a zero '0' indicates a needed value..otherwise, change to '_NOTUSED' for a null value so indices requiring research can be identified
// ALL of these values need to be verified before pushing to live
//
// make sure that you transcribe the actual value from 'defaults' to here before updating or client crashes will ensue..and/or...
// insert older clients inside of the progression of client order
//
// MAP_POSSESSIONS_SIZE does not reflect all actual <client>_constants size due to bitmask-use compatibility
//
// when setting NPC-based values, try to adhere to an EmuConstants::<property> or NOT_USED value to avoid unnecessary issues
static const uint16 local[_MapCount][_EmuClientCount] = {
// server and database are sync'd to current MapPossessions's client as set in 'using namespace RoF::slots;' and
// 'EmuConstants::MAP_POSSESSIONS_SIZE' - use/update EquipmentBitmask(), GeneralBitmask() and CursorBitmask()
// for partial range validation checks and 'EmuConstants::MAP_POSSESSIONS_SIZE' for full range iterations
{ // local[MainPossessions]
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::MAP_POSSESSIONS_SIZE,
/*Titanium*/ EmuConstants::MAP_POSSESSIONS_SIZE,
/*SoF*/ EmuConstants::MAP_POSSESSIONS_SIZE,
/*SoD*/ EmuConstants::MAP_POSSESSIONS_SIZE,
/*Underfoot*/ EmuConstants::MAP_POSSESSIONS_SIZE,
/*RoF*/ EmuConstants::MAP_POSSESSIONS_SIZE,
/*RoF2*/ 0,
/*NPC*/ EmuConstants::MAP_POSSESSIONS_SIZE,
/*Merc*/ EmuConstants::MAP_POSSESSIONS_SIZE,
/*Bot*/ EmuConstants::MAP_POSSESSIONS_SIZE,
/*Pet*/ EmuConstants::MAP_POSSESSIONS_SIZE
},
{ // local[MapBank]
/*Unknown*/ NOT_USED,
/*62*/ Client62::consts::MAP_BANK_SIZE,
/*Titanium*/ Titanium::consts::MAP_BANK_SIZE,
/*SoF*/ EmuConstants::MAP_BANK_SIZE,
/*SoD*/ EmuConstants::MAP_BANK_SIZE,
/*Underfoot*/ EmuConstants::MAP_BANK_SIZE,
/*RoF*/ EmuConstants::MAP_BANK_SIZE,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
},
{ // local[MapSharedBank]
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::MAP_SHARED_BANK_SIZE,
/*Titanium*/ EmuConstants::MAP_SHARED_BANK_SIZE,
/*SoF*/ EmuConstants::MAP_SHARED_BANK_SIZE,
/*SoD*/ EmuConstants::MAP_SHARED_BANK_SIZE,
/*Underfoot*/ EmuConstants::MAP_SHARED_BANK_SIZE,
/*RoF*/ EmuConstants::MAP_SHARED_BANK_SIZE,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
},
{ // local[MapTrade]
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::MAP_TRADE_SIZE,
/*Titanium*/ EmuConstants::MAP_TRADE_SIZE,
/*SoF*/ EmuConstants::MAP_TRADE_SIZE,
/*SoD*/ EmuConstants::MAP_TRADE_SIZE,
/*Underfoot*/ EmuConstants::MAP_TRADE_SIZE,
/*RoF*/ EmuConstants::MAP_TRADE_SIZE,
/*RoF2*/ 0,
/*NPC*/ 4,
/*Merc*/ 4,
/*Bot*/ EmuConstants::MAP_TRADE_SIZE, // client thinks this is another client
/*Pet*/ 4
},
{ // local[MapWorld]
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::MAP_WORLD_SIZE,
/*Titanium*/ EmuConstants::MAP_WORLD_SIZE,
/*SoF*/ EmuConstants::MAP_WORLD_SIZE,
/*SoD*/ EmuConstants::MAP_WORLD_SIZE,
/*Underfoot*/ EmuConstants::MAP_WORLD_SIZE,
/*RoF*/ EmuConstants::MAP_WORLD_SIZE,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
},
{ // local[MapLimbo]
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::MAP_LIMBO_SIZE,
/*Titanium*/ EmuConstants::MAP_LIMBO_SIZE,
/*SoF*/ EmuConstants::MAP_LIMBO_SIZE,
/*SoD*/ EmuConstants::MAP_LIMBO_SIZE,
/*Underfoot*/ EmuConstants::MAP_LIMBO_SIZE,
/*RoF*/ EmuConstants::MAP_LIMBO_SIZE,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
},
{ // local[MapTribute]
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::MAP_TRIBUTE_SIZE,
/*Titanium*/ EmuConstants::MAP_TRIBUTE_SIZE,
/*SoF*/ EmuConstants::MAP_TRIBUTE_SIZE,
/*SoD*/ EmuConstants::MAP_TRIBUTE_SIZE,
/*Underfoot*/ EmuConstants::MAP_TRIBUTE_SIZE,
/*RoF*/ EmuConstants::MAP_TRIBUTE_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapTrophyTribute]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_TROPHY_TRIBUTE_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapGuildTribute]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_GUILD_TRIBUTE_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapMerchant]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_MERCHANT_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapDeleted]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_DELETED_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapCorpse]
/*Unknown*/ NOT_USED,
/*62*/ Client62::consts::MAP_CORPSE_SIZE,
/*Titanium*/ Titanium::consts::MAP_CORPSE_SIZE,
/*SoF*/ SoF::consts::MAP_CORPSE_SIZE,
/*SoD*/ SoD::consts::MAP_CORPSE_SIZE,
/*Underfoot*/ Underfoot::consts::MAP_CORPSE_SIZE,
/*RoF*/ RoF::consts::MAP_CORPSE_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapBazaar]
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::MAP_BAZAAR_SIZE,
/*Titanium*/ EmuConstants::MAP_BAZAAR_SIZE,
/*SoF*/ EmuConstants::MAP_BAZAAR_SIZE,
/*SoD*/ EmuConstants::MAP_BAZAAR_SIZE,
/*Underfoot*/ EmuConstants::MAP_BAZAAR_SIZE,
/*RoF*/ EmuConstants::MAP_BAZAAR_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0, // this may need to be 'EmuConstants::MAP_BAZAAR_SIZE' if offline client traders respawn as an npc
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapInspect]
/*Unknown*/ NOT_USED,
/*62*/ Client62::consts::MAP_INSPECT_SIZE,
/*Titanium*/ Titanium::consts::MAP_INSPECT_SIZE,
/*SoF*/ SoF::consts::MAP_INSPECT_SIZE,
/*SoD*/ SoD::consts::MAP_INSPECT_SIZE,
/*Underfoot*/ Underfoot::consts::MAP_INSPECT_SIZE,
/*RoF*/ RoF::consts::MAP_INSPECT_SIZE,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
},
{ // local[MapRealEstate]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_REAL_ESTATE_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapViewMODPC]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_VIEW_MOD_PC_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapViewMODBank]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_VIEW_MOD_BANK_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapViewMODSharedBank]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_VIEW_MOD_SHARED_BANK_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapViewMODLimbo]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_VIEW_MOD_LIMBO_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapAltStorage]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_ALT_STORAGE_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapArchived]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_ARCHIVED_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapMail]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_MAIL_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapGuildTrophyTribute]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_GUILD_TROPHY_TRIBUTE_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapKrono]
/*Unknown*/ NOT_USED,
/*62*/ NOT_USED,
/*Titanium*/ NOT_USED,
/*SoF*/ NOT_USED,
/*SoD*/ NOT_USED,
/*Underfoot*/ NOT_USED,
/*RoF*/ EmuConstants::MAP_KRONO_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
},
{ // local[MapOther]
/*Unknown*/ NOT_USED,
/*62*/ 0,
/*Titanium*/ 0,
/*SoF*/ 0,
/*SoD*/ 0,
/*Underfoot*/ 0,
/*RoF*/ EmuConstants::MAP_OTHER_SIZE,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
}
};
if ((uint16)map < _MapCount)
return local[map][ValidateMobVersion(version)];
return NOT_USED;
}
uint64 EQLimits::PossessionsBitmask(uint32 version) {
// these are for the new inventory system (RoF)..not the current (Ti) one...
// 0x0000000000200000 is SlotPowerSource (SoF+)
// 0x0000000080000000 is SlotGeneral9 (RoF+)
// 0x0000000100000000 is SlotGeneral10 (RoF+)
static const uint64 local[_EmuClientCount] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x000000027FDFFFFF,
/*Titanium*/ 0x000000027FDFFFFF,
/*SoF*/ 0x000000027FFFFFFF,
/*SoD*/ 0x000000027FFFFFFF,
/*Underfoot*/ 0x000000027FFFFFFF,
/*RoF*/ 0x00000003FFFFFFFF,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
};
return NOT_USED;
//return local[ValidateMobVersion(version)];
}
uint64 EQLimits::EquipmentBitmask(uint32 version) {
static const uint64 local[_EmuClientCount] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x00000000005FFFFF,
/*Titanium*/ 0x00000000005FFFFF,
/*SoF*/ 0x00000000007FFFFF,
/*SoD*/ 0x00000000007FFFFF,
/*Underfoot*/ 0x00000000007FFFFF,
/*RoF*/ 0x00000000007FFFFF,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
};
return NOT_USED;
//return local[ValidateMobVersion(version)];
}
uint64 EQLimits::GeneralBitmask(uint32 version) {
static const uint64 local[_EmuClientCount] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x000000007F800000,
/*Titanium*/ 0x000000007F800000,
/*SoF*/ 0x000000007F800000,
/*SoD*/ 0x000000007F800000,
/*Underfoot*/ 0x000000007F800000,
/*RoF*/ 0x00000001FF800000,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
};
return NOT_USED;
//return local[ValidateMobVersion(version)];
}
uint64 EQLimits::CursorBitmask(uint32 version) {
static const uint64 local[_EmuClientCount] = {
/*Unknown*/ NOT_USED,
/*62*/ 0x0000000200000000,
/*Titanium*/ 0x0000000200000000,
/*SoF*/ 0x0000000200000000,
/*SoD*/ 0x0000000200000000,
/*Underfoot*/ 0x0000000200000000,
/*RoF*/ 0x0000000200000000,
/*RoF2*/ 0,
/*NPC*/ 0,
/*Merc*/ 0,
/*Bot*/ 0,
/*Pet*/ 0
};
return NOT_USED;
//return local[ValidateMobVersion(version)];
}
bool EQLimits::AllowsEmptyBagInBag(uint32 version) {
static const bool local[_EmuClientCount] = {
/*Unknown*/ false,
/*62*/ Client62::limits::ALLOWS_EMPTY_BAG_IN_BAG,
/*Titanium*/ Titanium::limits::ALLOWS_EMPTY_BAG_IN_BAG,
/*SoF*/ SoF::limits::ALLOWS_EMPTY_BAG_IN_BAG,
/*SoD*/ SoD::limits::ALLOWS_EMPTY_BAG_IN_BAG,
/*Underfoot*/ Underfoot::limits::ALLOWS_EMPTY_BAG_IN_BAG,
/*RoF*/ RoF::limits::ALLOWS_EMPTY_BAG_IN_BAG,
/*RoF2*/ false,
/*NPC*/ false,
/*Merc*/ false,
/*Bot*/ false,
/*Pet*/ false
};
return false; // not implemented
//return local[ValidateMobVersion(version)];
}
// items
uint16 EQLimits::ItemCommonSize(uint32 version) {
static const uint16 local[_EmuClientCount] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::ITEM_COMMON_SIZE,
/*Titanium*/ EmuConstants::ITEM_COMMON_SIZE,
/*SoF*/ EmuConstants::ITEM_COMMON_SIZE,
/*SoD*/ EmuConstants::ITEM_COMMON_SIZE,
/*Underfoot*/ EmuConstants::ITEM_COMMON_SIZE,
/*RoF*/ EmuConstants::ITEM_COMMON_SIZE,
/*RoF2*/ 0,
/*NPC*/ EmuConstants::ITEM_COMMON_SIZE,
/*Merc*/ EmuConstants::ITEM_COMMON_SIZE,
/*Bot*/ EmuConstants::ITEM_COMMON_SIZE,
/*Pet*/ EmuConstants::ITEM_COMMON_SIZE
};
return local[ValidateMobVersion(version)];
}
uint16 EQLimits::ItemContainerSize(uint32 version) {
static const uint16 local[_EmuClientCount] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*Titanium*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*SoF*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*SoD*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*Underfoot*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*RoF*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*RoF2*/ 0,
/*NPC*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*Merc*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*Bot*/ EmuConstants::ITEM_CONTAINER_SIZE,
/*Pet*/ EmuConstants::ITEM_CONTAINER_SIZE
};
return local[ValidateMobVersion(version)];
}
bool EQLimits::CoinHasWeight(uint32 version) {
static const bool local[_EmuClientCount] = {
/*Unknown*/ true,
/*62*/ Client62::limits::COIN_HAS_WEIGHT,
/*Titanium*/ Titanium::limits::COIN_HAS_WEIGHT,
/*SoF*/ SoF::limits::COIN_HAS_WEIGHT,
/*SoD*/ SoD::limits::COIN_HAS_WEIGHT,
/*Underfoot*/ Underfoot::limits::COIN_HAS_WEIGHT,
/*RoF*/ RoF::limits::COIN_HAS_WEIGHT,
/*RoF2*/ true,
/*NPC*/ true,
/*Merc*/ true,
/*Bot*/ true,
/*Pet*/ true
};
return local[ValidateMobVersion(version)];
}
uint32 EQLimits::BandoliersCount(uint32 version) {
static const uint32 local[_EmuClientCount] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::BANDOLIERS_COUNT,
/*Titanium*/ EmuConstants::BANDOLIERS_COUNT,
/*SoF*/ EmuConstants::BANDOLIERS_COUNT,
/*SoD*/ EmuConstants::BANDOLIERS_COUNT,
/*Underfoot*/ EmuConstants::BANDOLIERS_COUNT,
/*RoF*/ EmuConstants::BANDOLIERS_COUNT,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
};
return local[ValidateMobVersion(version)];
}
uint32 EQLimits::BandolierSize(uint32 version) {
static const uint32 local[_EmuClientCount] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::BANDOLIER_SIZE,
/*Titanium*/ EmuConstants::BANDOLIER_SIZE,
/*SoF*/ EmuConstants::BANDOLIER_SIZE,
/*SoD*/ EmuConstants::BANDOLIER_SIZE,
/*Underfoot*/ EmuConstants::BANDOLIER_SIZE,
/*RoF*/ EmuConstants::BANDOLIER_SIZE,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
};
return local[ValidateMobVersion(version)];
}
uint32 EQLimits::PotionBeltSize(uint32 version) {
static const uint32 local[_EmuClientCount] = {
/*Unknown*/ NOT_USED,
/*62*/ EmuConstants::POTION_BELT_SIZE,
/*Titanium*/ EmuConstants::POTION_BELT_SIZE,
/*SoF*/ EmuConstants::POTION_BELT_SIZE,
/*SoD*/ EmuConstants::POTION_BELT_SIZE,
/*Underfoot*/ EmuConstants::POTION_BELT_SIZE,
/*RoF*/ EmuConstants::POTION_BELT_SIZE,
/*RoF2*/ 0,
/*NPC*/ NOT_USED,
/*Merc*/ NOT_USED,
/*Bot*/ NOT_USED,
/*Pet*/ NOT_USED
};
return local[ValidateMobVersion(version)];
}

206
common/eq_dictionary.h Normal file
View File

@ -0,0 +1,206 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQ_DICTIONARY_H
#define EQ_DICTIONARY_H
#include "types.h"
#include "eq_constants.h"
#include "clientversions.h"
#include <string>
#include "../common/patches/Client62_constants.h"
#include "../common/patches/Titanium_constants.h"
#include "../common/patches/SoF_constants.h"
#include "../common/patches/SoD_constants.h"
#include "../common/patches/Underfoot_constants.h"
#include "../common/patches/RoF_constants.h"
//#include "../common/patches/RoF2_constants.h"
// *** DO NOT CHANGE without a full understanding of the consequences..the server is set up to use these settings explicitly!! ***
// *** You will cause compilation failures and corrupt your database if partial or incorrect attempts to them change are made!! ***
// Hard-coded values usually indicate that further research is needed and the values given are from the old (known) system
// (future use)
//using namespace RoF2::maps; // server inventory maps enumeration (code and database sync'd to reference)
//using namespace RoF::slots; // server possessions slots enumeration (code and database sync'd to reference)
class EmuConstants {
// an immutable value is required to initialize arrays, etc... use this class as a repository for those
public:
// database
static const EQClientVersion CHARACTER_CREATION_CLIENT = EQClientRoF; // adjust according to starting item placement and target client
// inventory
static uint16 InventoryMapSize(int16 map);
//static std::string InventoryLocationName(Location_Struct location);
static std::string InventoryMapName(int16 map);
static std::string InventoryMainName(int16 main);
static std::string InventorySubName(int16 sub);
static std::string InventoryAugName(int16 aug);
// these are currently hard-coded for existing inventory system..do not use in place of special client version handlers until ready
static const uint16 MAP_POSSESSIONS_SIZE = _MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
static const uint16 MAP_TRADE_SIZE = 8;
static const uint16 MAP_WORLD_SIZE = 10;
static const uint16 MAP_LIMBO_SIZE = 36;
static const uint16 MAP_TRIBUTE_SIZE = 5; // (need client values)
static const uint16 MAP_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_GUILD_TRIBUTE_SIZE = 0;
static const uint16 MAP_MERCHANT_SIZE = 0;
static const uint16 MAP_DELETED_SIZE = 0;
static const uint16 MAP_CORPSE_SIZE = _MainCount; // no bitmask use..limits to size of client corpse window (see EQLimits::InventoryMapSize(MapCorpse, <EQClientVersion))
static const uint16 MAP_BAZAAR_SIZE = 80;
static const uint16 MAP_INSPECT_SIZE = 22;
static const uint16 MAP_REAL_ESTATE_SIZE = 0;
static const uint16 MAP_VIEW_MOD_PC_SIZE = NOT_USED;
static const uint16 MAP_VIEW_MOD_BANK_SIZE = NOT_USED;
static const uint16 MAP_VIEW_MOD_SHARED_BANK_SIZE = NOT_USED;
static const uint16 MAP_VIEW_MOD_LIMBO_SIZE = NOT_USED;
static const uint16 MAP_ALT_STORAGE_SIZE = 0;
static const uint16 MAP_ARCHIVED_SIZE = 0;
static const uint16 MAP_MAIL_SIZE = 0;
static const uint16 MAP_GUILD_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_KRONO_SIZE = 0;
static const uint16 MAP_OTHER_SIZE = 0;
// most of these definitions will go away with the structure-based system..this maintains compatibility for now
// (these are mainly to assign specific values to constants used in conversions and to identify per-client ranges/offsets)
static const int16 POSSESSIONS_BEGIN = MainCharm;
static const int16 POSSESSIONS_END = MainCursor;
static const int16 EQUIPMENT_BEGIN = MainCharm;
static const int16 EQUIPMENT_END = MainAmmo;
static const uint16 EQUIPMENT_SIZE = 22; // does not account for 'Power Source' - used mainly for npc equipment arrays
static const int16 POWER_SOURCE = MainPowerSource; // temp
static const int16 GENERAL_BEGIN = MainGeneral1;
static const int16 GENERAL_END = MainGeneral8;
static const uint16 GENERAL_SIZE = 8;
static const int16 GENERAL_BAGS_BEGIN = 251;
static const int16 GENERAL_BAGS_END_OFFSET = 79;
static const int16 GENERAL_BAGS_END = GENERAL_BAGS_BEGIN + GENERAL_BAGS_END_OFFSET;
static const int16 CURSOR = MainCursor;
static const int16 CURSOR_BAG_BEGIN = 331;
static const int16 CURSOR_BAG_END_OFFSET = 9;
static const int16 CURSOR_BAG_END = CURSOR_BAG_BEGIN + CURSOR_BAG_END_OFFSET;
static const int16 BANK_BEGIN = 2000;
static const int16 BANK_END = 2023;
static const int16 BANK_BAGS_BEGIN = 2031;
static const int16 BANK_BAGS_END_OFFSET = 239;
static const int16 BANK_BAGS_END = BANK_BAGS_BEGIN + BANK_BAGS_END_OFFSET;
static const int16 SHARED_BANK_BEGIN = 2500;
static const int16 SHARED_BANK_END = 2501;
static const int16 SHARED_BANK_BAGS_BEGIN = 2531;
static const int16 SHARED_BANK_BAGS_END_OFFSET = 19;
static const int16 SHARED_BANK_BAGS_END = SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_END_OFFSET;
static const int16 TRADE_BEGIN = 3000;
static const int16 TRADE_END = 3007;
static const int16 TRADE_NPC_END = 3003;
static const int16 TRADE_BAGS_BEGIN = 3031;
static const int16 TRADE_BAGS_END_OFFSET = 79;
static const int16 TRADE_BAGS_END = TRADE_BAGS_BEGIN + TRADE_BAGS_END_OFFSET;
static const int16 WORLD_BEGIN = 4000;
static const int16 WORLD_END = 4009;
static const int16 WORLD_SIZE = 10;
static const int16 TRIBUTE_BEGIN = 400;
static const int16 TRIBUTE_END = 404;
static const int16 TRIBUTE_SIZE = 5;
static const int16 CORPSE_BEGIN = 22;
//static const int16 CORPSE_END = RoF::consts::CORPSE_END; // not ready for use
static const int16 MATERIAL_BEGIN = MaterialHead;
static const int16 MATERIAL_END = MaterialSecondary;
static const int16 MATERIAL_SIZE = _MaterialCount;
static const int16 TINTABLE_BEGIN = MaterialHead;
static const int16 TINTABLE_END = MaterialFeet;
static const int16 TINTABLE_SIZE = 7;
// items
// common and container sizes will not increase until the new 'location' struct is implemented
static const uint16 ITEM_COMMON_SIZE = Underfoot::consts::ITEM_COMMON_SIZE;
static const uint16 ITEM_CONTAINER_SIZE = Underfoot::consts::ITEM_CONTAINER_SIZE;
// player profile
//static const uint32 CLASS_BITMASK = 0; // needs value
//static const uint32 RACE_BITMASK = 0; // needs value
// BANDOLIERS_COUNT sets maximum limit..active limit will need to be handled by the appropriate AA
static const uint32 BANDOLIERS_COUNT = Titanium::consts::BANDOLIERS_COUNT; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = Titanium::consts::BANDOLIER_SIZE; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = Titanium::consts::POTION_BELT_SIZE;
};
class EQLimits {
// values should default to a non-beneficial value..unless value conflicts with intended operation
//
// EmuConstants may be used as references..but, not every reference needs to be in EmuConstants (i.e., AllowsEmptyBagInBag(), CoinHasWeight(), etc...)
public:
// client version validation (checks to avoid crashing zone server when accessing reference arrays)
// use this inside of class Client (limits to actual clients)
static bool IsValidClientVersion(uint32 version);
static uint32 ValidateClientVersion(uint32 version);
static EQClientVersion ValidateClientVersion(EQClientVersion version);
// basically..any non-client classes - do not when setting a valid client
static bool IsValidNPCVersion(uint32 version);
static uint32 ValidateNPCVersion(uint32 version);
static EQClientVersion ValidateNPCVersion(EQClientVersion version);
// these are 'universal' - do not when setting a valid client
static bool IsValidMobVersion(uint32 version);
static uint32 ValidateMobVersion(uint32 version);
static EQClientVersion ValidateMobVersion(EQClientVersion version);
// inventory
static uint16 InventoryMapSize(int16 map, uint32 version);
static uint64 PossessionsBitmask(uint32 version);
static uint64 EquipmentBitmask(uint32 version);
static uint64 GeneralBitmask(uint32 version);
static uint64 CursorBitmask(uint32 version);
static bool AllowsEmptyBagInBag(uint32 version);
// items
static uint16 ItemCommonSize(uint32 version);
static uint16 ItemContainerSize(uint32 version);
// player profile
static bool CoinHasWeight(uint32 version);
static uint32 BandoliersCount(uint32 version);
static uint32 BandolierSize(uint32 version);
static uint32 PotionBeltSize(uint32 version);
};
#endif /* EQ_LIMITS_H */

View File

@ -32,7 +32,8 @@ static const uint32 MAX_MERC_GRADES = 10;
static const uint32 MAX_MERC_STANCES = 10;
static const uint32 BLOCKED_BUFF_COUNT = 20;
#include "eq_constants.h"
//#include "eq_constants.h"
#include "eq_dictionary.h"
/*
** Compiler override to ensure
@ -720,12 +721,8 @@ struct Disciplines_Struct {
uint32 values[MAX_PP_DISCIPLINES];
};
static const uint32 TRIBUTE_SLOT_START = 400;
static const uint32 MAX_PLAYER_TRIBUTES = 5;
static const uint32 MAX_PLAYER_BANDOLIER = 4;
static const uint32 MAX_PLAYER_BANDOLIER_ITEMS = 4;
static const uint32 MAX_POTIONS_IN_BELT = 4;
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
struct Tribute_Struct {
uint32 tribute;
uint32 tier;
@ -747,10 +744,10 @@ enum { //bandolier item positions
};
struct Bandolier_Struct {
char name[32];
BandolierItem_Struct items[MAX_PLAYER_BANDOLIER_ITEMS];
BandolierItem_Struct items[EmuConstants::BANDOLIER_SIZE];
};
struct PotionBelt_Struct {
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
BandolierItem_Struct items[EmuConstants::POTION_BELT_SIZE];
};
struct MovePotionToBelt_Struct {
@ -999,7 +996,7 @@ struct PlayerProfile_Struct
/*7212*/ uint32 tribute_points;
/*7216*/ uint32 unknown7252;
/*7220*/ uint32 tribute_active; //1=active
/*7224*/ Tribute_Struct tributes[MAX_PLAYER_TRIBUTES];
/*7224*/ Tribute_Struct tributes[EmuConstants::TRIBUTE_SIZE];
/*7264*/ Disciplines_Struct disciplines;
/*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use)
/*7744*/ char unknown7780[160];
@ -1026,7 +1023,7 @@ struct PlayerProfile_Struct
/*12800*/ uint32 expAA;
/*12804*/ uint32 aapoints; //avaliable, unspent
/*12808*/ uint8 unknown12844[36];
/*12844*/ Bandolier_Struct bandoliers[MAX_PLAYER_BANDOLIER];
/*12844*/ Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_COUNT];
/*14124*/ uint8 unknown14160[4506];
/*18630*/ SuspendedMinion_Struct SuspendedMinion; // No longer in use
/*19240*/ uint32 timeentitledonaccount;
@ -1469,6 +1466,16 @@ struct MoveItem_Struct
/*0008*/ uint32 number_in_stack;
};
// both MoveItem_Struct/DeleteItem_Struct server structures will be changing to a structure-based slot format..this will
// be used for handling SoF/SoD/etc... time stamps sent using the MoveItem_Struct format. (nothing will be done with this
// info at the moment..but, it forwards it on to the server for handling/future use)
struct ClientTimeStamp_Struct
{
/*0000*/ uint32 from_slot;
/*0004*/ uint32 to_slot;
/*0008*/ uint32 number_in_stack;
};
//
// from_slot/to_slot
// -1 - destroy
@ -3342,8 +3349,8 @@ struct SelectTributeReply_Struct {
struct TributeInfo_Struct {
uint32 active; //0 == inactive, 1 == active
uint32 tributes[MAX_PLAYER_TRIBUTES]; //-1 == NONE
uint32 tiers[MAX_PLAYER_TRIBUTES]; //all 00's
uint32 tributes[EmuConstants::TRIBUTE_SIZE]; //-1 == NONE
uint32 tiers[EmuConstants::TRIBUTE_SIZE]; //all 00's
uint32 tribute_master_id;
};

View File

@ -42,7 +42,8 @@
* Made ya look! Ha!
*/
#include "eq_constants.h"
//#include "eq_constants.h"
#include "eq_dictionary.h"
/*
** Child struct of Item_Struct:
@ -68,7 +69,8 @@ struct InternalSerializedItem_Struct {
const void * inst;
};
#define MAX_AUGMENT_SLOTS 5
// use EmuConstants::ITEM_COMMON_SIZE
//#define MAX_AUGMENT_SLOTS 5
struct Item_Struct {
bool IsEquipable(uint16 Race, uint16 Class) const;
@ -180,9 +182,9 @@ struct Item_Struct {
int32 FactionAmt4; // Faction Amt 4
char CharmFile[32]; // ?
uint32 AugType;
uint8 AugSlotType[MAX_AUGMENT_SLOTS]; // LDoN: Augment Slot 1-5 Type
uint8 AugSlotVisible[MAX_AUGMENT_SLOTS]; // LDoN: Augment Slot 1-5 Visible
uint8 AugSlotUnk2[MAX_AUGMENT_SLOTS]; // LDoN: Augment Slot 1-5 Unknown
uint8 AugSlotType[EmuConstants::ITEM_COMMON_SIZE]; // LDoN: Augment Slot 1-5 Type
uint8 AugSlotVisible[EmuConstants::ITEM_COMMON_SIZE]; // LDoN: Augment Slot 1-5 Visible
uint8 AugSlotUnk2[EmuConstants::ITEM_COMMON_SIZE]; // LDoN: Augment Slot 1-5 Unknown
uint32 LDoNTheme;
uint32 LDoNPrice;
uint32 LDoNSold;

View File

@ -0,0 +1,214 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CLIENT62_CONSTANTS_H_
#define CLIENT62_CONSTANTS_H_
#include "../common/types.h"
namespace Client62 {
namespace maps {
typedef enum : int16 {
// this needs work to match actual client equivilents
MapPossessions = 0,
MapBank,
MapSharedBank,
MapTrade,
MapWorld,
MapLimbo,
MapTribute,
MapTrophyTribute,
MapGuildTribute,
MapMerchant,
MapDeleted,
MapCorpse,
MapBazaar,
MapInspect,
MapRealEstate,
MapViewMODPC,
MapViewMODBank,
MapViewMODSharedBank,
MapViewMODLimbo,
MapAltStorage,
MapArchived,
MapMail,
MapGuildTrophyTribute,
MapOther,
_MapCount
} InventoryMaps;
}
namespace slots {
typedef enum : int16 {
MainCharm = 0,
MainEar1,
MainHead,
MainFace,
MainEar2,
MainNeck,
MainShoulders,
MainArms,
MainBack,
MainWrist1,
MainWrist2,
MainRange,
MainHands,
MainPrimary,
MainSecondary,
MainFinger1,
MainFinger2,
MainChest,
MainLegs,
MainFeet,
MainWaist,
MainAmmo,
MainGeneral1,
MainGeneral2,
MainGeneral3,
MainGeneral4,
MainGeneral5,
MainGeneral6,
MainGeneral7,
MainGeneral8,
MainCursor,
_MainCount,
_MainEquipmentBegin = MainCharm,
_MainEquipmentEnd = MainAmmo,
_MainEquipmentCount = (_MainEquipmentEnd - _MainEquipmentBegin + 1),
_MainGeneralBegin = MainGeneral1,
_MainGeneralEnd = MainGeneral8,
_MainGeneralCount = (_MainGeneralEnd - _MainGeneralBegin + 1)
} EquipmentSlots;
}
namespace consts {
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 16;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
static const uint16 MAP_TRADE_SIZE = 8;
static const uint16 MAP_WORLD_SIZE = 10;
static const uint16 MAP_LIMBO_SIZE = 36;
static const uint16 MAP_TRIBUTE_SIZE = 0; //?
static const uint16 MAP_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_GUILD_TRIBUTE_SIZE = 0;
static const uint16 MAP_MERCHANT_SIZE = 0;
static const uint16 MAP_DELETED_SIZE = 0;
static const uint16 MAP_CORPSE_SIZE = slots::_MainCount;
static const uint16 MAP_BAZAAR_SIZE = 80;
static const uint16 MAP_INSPECT_SIZE = slots::_MainEquipmentCount;
static const uint16 MAP_REAL_ESTATE_SIZE = 0;
static const uint16 MAP_VIEW_MOD_PC_SIZE = MAP_POSSESSIONS_SIZE;
static const uint16 MAP_VIEW_MOD_BANK_SIZE = MAP_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_SHARED_BANK_SIZE = MAP_SHARED_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_LIMBO_SIZE = MAP_LIMBO_SIZE;
static const uint16 MAP_ALT_STORAGE_SIZE = 0;
static const uint16 MAP_ARCHIVED_SIZE = 0;
static const uint16 MAP_MAIL_SIZE = 0;
static const uint16 MAP_GUILD_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_KRONO_SIZE = NOT_USED;
static const uint16 MAP_OTHER_SIZE = 0;
static const int16 POSSESSIONS_BEGIN = slots::MainCharm;
static const int16 POSSESSIONS_END = slots::MainCursor;
static const int16 EQUIPMENT_BEGIN = slots::MainCharm;
static const int16 EQUIPMENT_END = slots::MainAmmo;
static const uint16 EQUIPMENT_SIZE = slots::_MainEquipmentCount;
static const int16 GENERAL_BEGIN = slots::MainGeneral1;
static const int16 GENERAL_END = slots::MainGeneral8;
static const uint16 GENERAL_SIZE = slots::_MainGeneralCount;
static const int16 GENERAL_BAGS_BEGIN = 251;
static const int16 GENERAL_BAGS_END_OFFSET = 79;
static const int16 GENERAL_BAGS_END = GENERAL_BAGS_BEGIN + GENERAL_BAGS_END_OFFSET;
static const int16 CURSOR = slots::MainCursor;
static const int16 CURSOR_BAG_BEGIN = 331;
static const int16 CURSOR_BAG_END_OFFSET = 9;
static const int16 CURSOR_BAG_END = CURSOR_BAG_BEGIN + CURSOR_BAG_END_OFFSET;
static const int16 BANK_BEGIN = 2000;
static const int16 BANK_END = 2015;
static const int16 BANK_BAGS_BEGIN = 2031;
static const int16 BANK_BAGS_END_OFFSET = 159;
static const int16 BANK_BAGS_END = BANK_BAGS_BEGIN + BANK_BAGS_END_OFFSET;
static const int16 SHARED_BANK_BEGIN = 2500;
static const int16 SHARED_BANK_END = 2501;
static const int16 SHARED_BANK_BAGS_BEGIN = 2531;
static const int16 SHARED_BANK_BAGS_END_OFFSET = 19;
static const int16 SHARED_BANK_BAGS_END = SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_END_OFFSET;
static const int16 TRADE_BEGIN = 3000;
static const int16 TRADE_END = 3007;
static const int16 TRADE_END_NPC = 3003;
static const int16 TRADE_BAGS_BEGIN = 3031;
static const int16 TRADE_BAGS_END_OFFSET = 79;
static const int16 TRADE_BAGS_END = TRADE_BAGS_BEGIN + TRADE_BAGS_END_OFFSET;
static const int16 WORLD_BEGIN = 4000;
static const int16 WORLD_END = 4009;
static const int16 TRIBUTE_BEGIN = 400;
static const int16 TRIBUTE_END = 404;
static const int16 CORPSE_BEGIN = slots::MainGeneral1;
static const int16 CORPSE_END = slots::MainGeneral1 + slots::MainCursor;
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const uint32 BANDOLIERS_COUNT = 4; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 4;
}
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
static const bool COIN_HAS_WEIGHT = true;
}
}; //end namespace Client62
#endif /*CLIENT62_CONSTANTS_H_*/
/*
Client62 Notes:
** Integer-based inventory **
ok Possessions: 0 - 30 (Corpse: 22 - 52 [Offset 22])
ok [Equipment: 0 - 21]
ok [General: 22 - 29]
ok [Cursor: 30]
ok General Bags: 251 - 330
ok Cursor Bags: 331 - 340
ok Bank: 2000 - 2015
ok Bank Bags: 2031 - 2190
ok Shared Bank: 2500 - 2501
ok Shared Bank Bags: 2531 - 2550
Trade: 3000 - 3007
(Trade Bags: 3031 - 3110 -- server values)
World: 4000 - 4009
*/

View File

@ -1200,11 +1200,11 @@ ENCODE(OP_PlayerProfile)
outapp->WriteUInt32(structs::MAX_PLAYER_BANDOLIER);
for(uint32 r = 0; r < MAX_PLAYER_BANDOLIER; r++)
for(uint32 r = 0; r < EmuConstants::BANDOLIERS_COUNT; r++)
{
outapp->WriteString(emu->bandoliers[r].name);
for(uint32 j = 0; j < MAX_PLAYER_BANDOLIER_ITEMS; ++j)
for(uint32 j = 0; j < EmuConstants::BANDOLIER_SIZE; ++j)
{
outapp->WriteString(emu->bandoliers[r].items[j].item_name);
outapp->WriteUInt32(emu->bandoliers[r].items[j].item_id);
@ -1212,11 +1212,11 @@ ENCODE(OP_PlayerProfile)
}
}
for(uint32 r = 0; r < structs::MAX_PLAYER_BANDOLIER - MAX_PLAYER_BANDOLIER; r++)
for(uint32 r = 0; r < structs::MAX_PLAYER_BANDOLIER - EmuConstants::BANDOLIERS_COUNT; r++)
{
outapp->WriteString("");
for(uint32 j = 0; j < MAX_PLAYER_BANDOLIER_ITEMS; ++j)
for(uint32 j = 0; j < EmuConstants::BANDOLIER_SIZE; ++j)
{
outapp->WriteString("");
outapp->WriteUInt32(0);
@ -1227,7 +1227,7 @@ ENCODE(OP_PlayerProfile)
outapp->WriteUInt32(structs::MAX_POTIONS_IN_BELT);
for(uint32 r = 0; r < MAX_POTIONS_IN_BELT; r++)
for(uint32 r = 0; r < EmuConstants::POTION_BELT_SIZE; r++)
{
outapp->WriteString(emu->potionbelt.items[r].item_name);
outapp->WriteUInt32(emu->potionbelt.items[r].item_id);
@ -1235,7 +1235,7 @@ ENCODE(OP_PlayerProfile)
}
for(uint32 r = 0; r < structs::MAX_POTIONS_IN_BELT - MAX_POTIONS_IN_BELT; r++)
for(uint32 r = 0; r < structs::MAX_POTIONS_IN_BELT - EmuConstants::POTION_BELT_SIZE; r++)
{
outapp->WriteString("");
outapp->WriteUInt32(0);
@ -1357,9 +1357,9 @@ ENCODE(OP_PlayerProfile)
outapp->WriteUInt8(0); // Unknown
outapp->WriteUInt8(0); // Unknown
outapp->WriteUInt32(MAX_PLAYER_TRIBUTES);
outapp->WriteUInt32(EmuConstants::TRIBUTE_SIZE);
for(uint32 r = 0; r < MAX_PLAYER_TRIBUTES; r++)
for(uint32 r = 0; r < EmuConstants::TRIBUTE_SIZE; r++)
{
outapp->WriteUInt32(emu->tributes[r].tribute);
outapp->WriteUInt32(emu->tributes[r].tier);

View File

@ -0,0 +1,218 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef RoF_CONSTANTS_H_
#define RoF_CONSTANTS_H_
#include "../common/types.h"
namespace RoF {
namespace maps {
typedef enum : int16 {
MapPossessions = 0,
MapBank,
MapSharedBank,
MapTrade,
MapWorld,
MapLimbo,
MapTribute,
MapTrophyTribute,
MapGuildTribute,
MapMerchant,
MapDeleted,
MapCorpse,
MapBazaar,
MapInspect,
MapRealEstate,
MapViewMODPC,
MapViewMODBank,
MapViewMODSharedBank,
MapViewMODLimbo,
MapAltStorage,
MapArchived,
MapMail,
MapGuildTrophyTribute,
MapOther,
_MapCount
} InventoryMaps;
}
namespace slots {
typedef enum : int16 {
MainCharm = 0,
MainEar1,
MainHead,
MainFace,
MainEar2,
MainNeck,
MainShoulders,
MainArms,
MainBack,
MainWrist1,
MainWrist2,
MainRange,
MainHands,
MainPrimary,
MainSecondary,
MainFinger1,
MainFinger2,
MainChest,
MainLegs,
MainFeet,
MainWaist,
MainPowerSource,
MainAmmo,
MainGeneral1,
MainGeneral2,
MainGeneral3,
MainGeneral4,
MainGeneral5,
MainGeneral6,
MainGeneral7,
MainGeneral8,
MainGeneral9,
MainGeneral10,
MainCursor,
_MainCount,
_MainEquipmentBegin = MainCharm,
_MainEquipmentEnd = MainAmmo,
_MainEquipmentCount = (_MainEquipmentEnd - _MainEquipmentBegin + 1),
_MainGeneralBegin = MainGeneral1,
_MainGeneralEnd = MainGeneral10,
_MainGeneralCount = (_MainGeneralEnd - _MainGeneralBegin + 1)
} EquipmentSlots;
}
namespace consts {
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
static const uint16 MAP_TRADE_SIZE = 8;
static const uint16 MAP_WORLD_SIZE = 10;
static const uint16 MAP_LIMBO_SIZE = 36;
static const uint16 MAP_TRIBUTE_SIZE = 0; //?
static const uint16 MAP_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_GUILD_TRIBUTE_SIZE = 0;
static const uint16 MAP_MERCHANT_SIZE = 0;
static const uint16 MAP_DELETED_SIZE = 0;
static const uint16 MAP_CORPSE_SIZE = slots::_MainCount;
static const uint16 MAP_BAZAAR_SIZE = 200;
static const uint16 MAP_INSPECT_SIZE = slots::_MainEquipmentCount;
static const uint16 MAP_REAL_ESTATE_SIZE = 0;
static const uint16 MAP_VIEW_MOD_PC_SIZE = MAP_POSSESSIONS_SIZE;
static const uint16 MAP_VIEW_MOD_BANK_SIZE = MAP_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_SHARED_BANK_SIZE = MAP_SHARED_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_LIMBO_SIZE = MAP_LIMBO_SIZE;
static const uint16 MAP_ALT_STORAGE_SIZE = 0;
static const uint16 MAP_ARCHIVED_SIZE = 0;
static const uint16 MAP_MAIL_SIZE = 0;
static const uint16 MAP_GUILD_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_KRONO_SIZE = NOT_USED;
static const uint16 MAP_OTHER_SIZE = 0;
// most of these definitions will go away with the structure-based system..this maintains compatibility for now
// (bag slots and main slots beyond Possessions are assigned for compatibility with current server coding)
static const int16 POSSESSIONS_BEGIN = slots::MainCharm;
static const int16 POSSESSIONS_END = slots::MainCursor;
static const int16 EQUIPMENT_BEGIN = slots::MainCharm;
static const int16 EQUIPMENT_END = slots::MainAmmo;
static const uint16 EQUIPMENT_SIZE = slots::_MainEquipmentCount;
static const int16 GENERAL_BEGIN = slots::MainGeneral1;
static const int16 GENERAL_END = slots::MainGeneral10;
static const uint16 GENERAL_SIZE = slots::_MainGeneralCount;
static const int16 GENERAL_BAGS_BEGIN = 251;
static const int16 GENERAL_BAGS_END_OFFSET = 99;
static const int16 GENERAL_BAGS_END = GENERAL_BAGS_BEGIN + GENERAL_BAGS_END_OFFSET;
static const int16 CURSOR = slots::MainCursor;
static const int16 CURSOR_BAG_BEGIN = 351;
static const int16 CURSOR_BAG_END_OFFSET = 9;
static const int16 CURSOR_BAG_END = CURSOR_BAG_BEGIN + CURSOR_BAG_END_OFFSET;
static const int16 BANK_BEGIN = 2000;
static const int16 BANK_END = 2023;
static const int16 BANK_BAGS_BEGIN = 2031;
static const int16 BANK_BAGS_END_OFFSET = 239;
static const int16 BANK_BAGS_END = BANK_BAGS_BEGIN + BANK_BAGS_END_OFFSET;
static const int16 SHARED_BANK_BEGIN = 2500;
static const int16 SHARED_BANK_END = 2501;
static const int16 SHARED_BANK_BAGS_BEGIN = 2531;
static const int16 SHARED_BANK_BAGS_END_OFFSET = 19;
static const int16 SHARED_BANK_BAGS_END = SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_END_OFFSET;
static const int16 TRADE_BEGIN = 3000;
static const int16 TRADE_END = 3007;
static const int16 TRADE_END_NPC = 3003;
static const int16 TRADE_BAGS_BEGIN = 3031;
static const int16 TRADE_BAGS_END_OFFSET = 79;
static const int16 TRADE_BAGS_END = TRADE_BAGS_BEGIN + TRADE_BAGS_END_OFFSET;
static const int16 WORLD_BEGIN = 4000;
static const int16 WORLD_END = 4009;
static const int16 TRIBUTE_BEGIN = 400;
static const int16 TRIBUTE_END = 404;
static const int16 CORPSE_BEGIN = slots::MainGeneral1;
static const int16 CORPSE_END = slots::MainGeneral1 + slots::MainCursor;
static const uint16 ITEM_COMMON_SIZE = 6;
static const uint16 ITEM_CONTAINER_SIZE = 255; // 255; (server max will be 255..unsure what actual client is - test)
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
}
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = true;
static const bool COIN_HAS_WEIGHT = false;
}
}; //end namespace RoF
#endif /*RoF_CONSTANTS_H_*/
/*
RoF Notes:
** Structure-based inventory **
ok Possessions: ( 0, { 0 .. 33 }, -1, -1 ) (Corpse: { 23 .. 56 } [Offset 23])
ok [Equipment: ( 0, { 0 .. 22 }, -1, -1 )]
ok [General: ( 0, { 23 .. 32 }, -1, -1 )]
ok [Cursor: ( 0, 33, -1, -1 )]
General Bags: ( 0, { 23 .. 32 }, { 0 .. (maxsize - 1) }, -1 )
Cursor Bags: ( 0, 33, { 0 .. (maxsize - 1) }, -1 )
Bank: ( 1, { 0 .. 23 }, -1, -1 )
Bank Bags: ( 1, { 0 .. 23 }, { 0 .. (maxsize - 1)}, -1 )
Shared Bank: ( 2, { 0 .. 1 }, -1, -1 )
Shared Bank Bags: ( 2, { 0 .. 1 }, { 0 .. (maxsize - 1) }, -1 )
Trade: ( 3, { 0 .. 8 }, -1, -1 )
(Trade Bags: 3031 - 3110 -- server values)
World: ( 4, { 0 .. 10 }, -1, -1 )
*/

View File

@ -0,0 +1,215 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SoD_CONSTANTS_H_
#define SoD_CONSTANTS_H_
#include "../common/types.h"
namespace SoD {
namespace maps {
typedef enum : int16 {
// this needs work to match actual client equivilents
MapPossessions = 0,
MapBank,
MapSharedBank,
MapTrade,
MapWorld,
MapLimbo,
MapTribute,
MapTrophyTribute,
MapGuildTribute,
MapMerchant,
MapDeleted,
MapCorpse,
MapBazaar,
MapInspect,
MapRealEstate,
MapViewMODPC,
MapViewMODBank,
MapViewMODSharedBank,
MapViewMODLimbo,
MapAltStorage,
MapArchived,
MapMail,
MapGuildTrophyTribute,
MapOther,
_MapCount
} InventoryMaps;
}
namespace slots {
typedef enum : int16 {
MainCharm = 0,
MainEar1,
MainHead,
MainFace,
MainEar2,
MainNeck,
MainShoulders,
MainArms,
MainBack,
MainWrist1,
MainWrist2,
MainRange,
MainHands,
MainPrimary,
MainSecondary,
MainFinger1,
MainFinger2,
MainChest,
MainLegs,
MainFeet,
MainWaist,
MainPowerSource,
MainAmmo,
MainGeneral1,
MainGeneral2,
MainGeneral3,
MainGeneral4,
MainGeneral5,
MainGeneral6,
MainGeneral7,
MainGeneral8,
MainCursor,
_MainCount,
_MainEquipmentBegin = MainCharm,
_MainEquipmentEnd = MainAmmo,
_MainEquipmentCount = (_MainEquipmentEnd - _MainEquipmentBegin + 1),
_MainGeneralBegin = MainGeneral1,
_MainGeneralEnd = MainGeneral8,
_MainGeneralCount = (_MainGeneralEnd - _MainGeneralBegin + 1)
} EquipmentSlots;
}
namespace consts {
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
static const uint16 MAP_TRADE_SIZE = 8;
static const uint16 MAP_WORLD_SIZE = 10;
static const uint16 MAP_LIMBO_SIZE = 36;
static const uint16 MAP_TRIBUTE_SIZE = 0; //?
static const uint16 MAP_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_GUILD_TRIBUTE_SIZE = 0;
static const uint16 MAP_MERCHANT_SIZE = 0;
static const uint16 MAP_DELETED_SIZE = 0;
static const uint16 MAP_CORPSE_SIZE = slots::_MainCount;
static const uint16 MAP_BAZAAR_SIZE = 80;
static const uint16 MAP_INSPECT_SIZE = slots::_MainEquipmentCount;
static const uint16 MAP_REAL_ESTATE_SIZE = 0;
static const uint16 MAP_VIEW_MOD_PC_SIZE = MAP_POSSESSIONS_SIZE;
static const uint16 MAP_VIEW_MOD_BANK_SIZE = MAP_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_SHARED_BANK_SIZE = MAP_SHARED_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_LIMBO_SIZE = MAP_LIMBO_SIZE;
static const uint16 MAP_ALT_STORAGE_SIZE = 0;
static const uint16 MAP_ARCHIVED_SIZE = 0;
static const uint16 MAP_MAIL_SIZE = 0;
static const uint16 MAP_GUILD_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_KRONO_SIZE = NOT_USED;
static const uint16 MAP_OTHER_SIZE = 0;
static const int16 POSSESSIONS_BEGIN = slots::MainCharm;
static const int16 POSSESSIONS_END = slots::MainCursor;
static const int16 EQUIPMENT_BEGIN = slots::MainCharm;
static const int16 EQUIPMENT_END = slots::MainAmmo;
static const uint16 EQUIPMENT_SIZE = slots::_MainEquipmentCount;
static const int16 GENERAL_BEGIN = slots::MainGeneral1;
static const int16 GENERAL_END = slots::MainGeneral8;
static const uint16 GENERAL_SIZE = slots::_MainGeneralCount;
static const int16 GENERAL_BAGS_BEGIN = 262;
static const int16 GENERAL_BAGS_END_OFFSET = 79;
static const int16 GENERAL_BAGS_END = GENERAL_BAGS_BEGIN + GENERAL_BAGS_END_OFFSET;
static const int16 CURSOR = slots::MainCursor;
static const int16 CURSOR_BAG_BEGIN = 342;
static const int16 CURSOR_BAG_END_OFFSET = 9;
static const int16 CURSOR_BAG_END = CURSOR_BAG_BEGIN + CURSOR_BAG_END_OFFSET;
static const int16 BANK_BEGIN = 2000;
static const int16 BANK_END = 2023;
static const int16 BANK_BAGS_BEGIN = 2032;
static const int16 BANK_BAGS_END_OFFSET = 239;
static const int16 BANK_BAGS_END = BANK_BAGS_BEGIN + BANK_BAGS_END_OFFSET;
static const int16 SHARED_BANK_BEGIN = 2500;
static const int16 SHARED_BANK_END = 2501;
static const int16 SHARED_BANK_BAGS_BEGIN = 2532;
static const int16 SHARED_BANK_BAGS_END_OFFSET = 19;
static const int16 SHARED_BANK_BAGS_END = SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_END_OFFSET;
static const int16 TRADE_BEGIN = 3000;
static const int16 TRADE_END = 3007;
static const int16 TRADE_END_NPC = 3003;
static const int16 TRADE_BAGS_BEGIN = 3031; // no change from Ti?
static const int16 TRADE_BAGS_END_OFFSET = 79;
static const int16 TRADE_BAGS_END = TRADE_BAGS_BEGIN + TRADE_BAGS_END_OFFSET;
static const int16 WORLD_BEGIN = 4000;
static const int16 WORLD_END = 4009;
static const int16 TRIBUTE_BEGIN = 400;
static const int16 TRIBUTE_END = 404;
static const int16 CORPSE_BEGIN = slots::MainGeneral1;
static const int16 CORPSE_END = slots::MainGeneral1 + slots::MainCursor;
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
}
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
static const bool COIN_HAS_WEIGHT = false;
}
}; //end namespace SoD
#endif /*SoD_CONSTANTS_H_*/
/*
SoD Notes:
** Integer-based inventory **
ok Possessions: 0 - 31 (Corpse: 23 - 54 [Offset 23])
ok [Equipment: 0 - 22]
ok [General: 23 - 30]
ok [Cursor: 31]
ok General Bags: 262 - 341
ok Cursor Bags: 342 - 351
ok Bank: 2000 - 2023
ok Bank Bags: 2032 - 2271
ok Shared Bank: 2500 - 2501
ok Shared Bank Bags: 2532 - 2551
Trade: 3000 - 3007
(Trade Bags: 3031 - 3110 -- server values)
World: 4000 - 4009
*/

View File

@ -0,0 +1,218 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SoF_CONSTANTS_H_
#define SoF_CONSTANTS_H_
#include "../common/types.h"
namespace SoF {
namespace maps {
typedef enum : int16 {
// this needs work to match actual client equivilents
MapPossessions = 0,
MapBank,
MapSharedBank,
MapTrade,
MapWorld,
MapLimbo,
MapTribute,
MapTrophyTribute,
MapGuildTribute,
MapMerchant,
MapDeleted,
MapCorpse,
MapBazaar,
MapInspect,
MapRealEstate,
MapViewMODPC,
MapViewMODBank,
MapViewMODSharedBank,
MapViewMODLimbo,
MapAltStorage,
MapArchived,
MapMail,
MapGuildTrophyTribute,
MapOther,
_MapCount
} InventoryMaps;
}
namespace slots {
typedef enum : int16 {
MainCharm = 0,
MainEar1,
MainHead,
MainFace,
MainEar2,
MainNeck,
MainShoulders,
MainArms,
MainBack,
MainWrist1,
MainWrist2,
MainRange,
MainHands,
MainPrimary,
MainSecondary,
MainFinger1,
MainFinger2,
MainChest,
MainLegs,
MainFeet,
MainWaist,
MainPowerSource,
MainAmmo,
MainGeneral1,
MainGeneral2,
MainGeneral3,
MainGeneral4,
MainGeneral5,
MainGeneral6,
MainGeneral7,
MainGeneral8,
MainCursor,
_MainCount,
_MainEquipmentBegin = MainCharm,
_MainEquipmentEnd = MainAmmo,
_MainEquipmentCount = (_MainEquipmentEnd - _MainEquipmentBegin + 1),
_MainGeneralBegin = MainGeneral1,
_MainGeneralEnd = MainGeneral8,
_MainGeneralCount = (_MainGeneralEnd - _MainGeneralBegin + 1)
} EquipmentSlots;
}
namespace consts {
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
static const uint16 MAP_TRADE_SIZE = 8;
static const uint16 MAP_WORLD_SIZE = 10;
static const uint16 MAP_LIMBO_SIZE = 36;
static const uint16 MAP_TRIBUTE_SIZE = 0; //?
static const uint16 MAP_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_GUILD_TRIBUTE_SIZE = 0;
static const uint16 MAP_MERCHANT_SIZE = 0;
static const uint16 MAP_DELETED_SIZE = 0;
static const uint16 MAP_CORPSE_SIZE = slots::_MainCount;
static const uint16 MAP_BAZAAR_SIZE = 80;
static const uint16 MAP_INSPECT_SIZE = slots::_MainEquipmentCount;
static const uint16 MAP_REAL_ESTATE_SIZE = 0;
static const uint16 MAP_VIEW_MOD_PC_SIZE = MAP_POSSESSIONS_SIZE;
static const uint16 MAP_VIEW_MOD_BANK_SIZE = MAP_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_SHARED_BANK_SIZE = MAP_SHARED_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_LIMBO_SIZE = MAP_LIMBO_SIZE;
static const uint16 MAP_ALT_STORAGE_SIZE = 0;
static const uint16 MAP_ARCHIVED_SIZE = 0;
static const uint16 MAP_MAIL_SIZE = 0;
static const uint16 MAP_GUILD_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_KRONO_SIZE = NOT_USED;
static const uint16 MAP_OTHER_SIZE = 0;
static const int16 POSSESSIONS_BEGIN = slots::MainCharm;
static const int16 POSSESSIONS_END = slots::MainCursor;
static const int16 EQUIPMENT_BEGIN = slots::MainCharm;
static const int16 EQUIPMENT_END = slots::MainAmmo;
static const uint16 EQUIPMENT_SIZE = slots::_MainEquipmentCount;
static const int16 GENERAL_BEGIN = slots::MainGeneral1;
static const int16 GENERAL_END = slots::MainGeneral8;
static const uint16 GENERAL_SIZE = slots::_MainGeneralCount;
static const int16 GENERAL_BAGS_BEGIN = 262;
static const int16 GENERAL_BAGS_END_OFFSET = 79;
static const int16 GENERAL_BAGS_END = GENERAL_BAGS_BEGIN + GENERAL_BAGS_END_OFFSET;
static const int16 CURSOR = slots::MainCursor;
static const int16 CURSOR_BAG_BEGIN = 342;
static const int16 CURSOR_BAG_END_OFFSET = 9;
static const int16 CURSOR_BAG_END = CURSOR_BAG_BEGIN + CURSOR_BAG_END_OFFSET;
static const int16 BANK_BEGIN = 2000;
static const int16 BANK_END = 2023;
static const int16 BANK_BAGS_BEGIN = 2032;
static const int16 BANK_BAGS_END_OFFSET = 239;
static const int16 BANK_BAGS_END = BANK_BAGS_BEGIN + BANK_BAGS_END_OFFSET;
static const int16 SHARED_BANK_BEGIN = 2500;
static const int16 SHARED_BANK_END = 2501;
static const int16 SHARED_BANK_BAGS_BEGIN = 2532;
static const int16 SHARED_BANK_BAGS_END_OFFSET = 19;
static const int16 SHARED_BANK_BAGS_END = SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_END_OFFSET;
static const int16 TRADE_BEGIN = 3000;
static const int16 TRADE_END = 3007;
static const int16 TRADE_END_NPC = 3003;
static const int16 TRADE_BAGS_BEGIN = 3031; // no change from Ti?
static const int16 TRADE_BAGS_END_OFFSET = 79;
static const int16 TRADE_BAGS_END = TRADE_BAGS_BEGIN + TRADE_BAGS_END_OFFSET;
static const int16 WORLD_BEGIN = 4000;
static const int16 WORLD_END = 4009;
static const int16 TRIBUTE_BEGIN = 400;
static const int16 TRIBUTE_END = 404;
static const int16 CORPSE_BEGIN = slots::MainGeneral1;
static const int16 CORPSE_END = slots::MainGeneral1 + slots::MainCursor;
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
}
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
static const bool COIN_HAS_WEIGHT = true;
}
}; //end namespace SoF
#endif /*SoF_CONSTANTS_H_*/
/*
SoF Notes:
** Integer-based inventory **
ok Possessions: 0 - 31 (Corpse: 23 - 54 [Offset 23])
ok [Equipment: 0 - 22]
ok [General: 23 - 30]
ok [Cursor: 31]
ok General Bags: 262 - 341
ok Cursor Bags: 342 - 351
ok Bank: 2000 - 2023
ok Bank Bags: 2032 - 2271
ok Shared Bank: 2500 - 2501
ok Shared Bank Bags: 2532 - 2551
Trade: 3000 - 3007
(Trade Bags: 3031 - 3110 -- server values)
World: 4000 - 4009
code file reviewed..
..SerializeItem() needs work
..still needs timestamp redirect code
*/

View File

@ -0,0 +1,214 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef Titanium_CONSTANTS_H_
#define Titanium_CONSTANTS_H_
#include "../common/types.h"
namespace Titanium {
namespace maps {
typedef enum : int16 {
// this needs work to match actual client equivilents
MapPossessions = 0,
MapBank,
MapSharedBank,
MapTrade,
MapWorld,
MapLimbo,
MapTribute,
MapTrophyTribute,
MapGuildTribute,
MapMerchant,
MapDeleted,
MapCorpse,
MapBazaar,
MapInspect,
MapRealEstate,
MapViewMODPC,
MapViewMODBank,
MapViewMODSharedBank,
MapViewMODLimbo,
MapAltStorage,
MapArchived,
MapMail,
MapGuildTrophyTribute,
MapOther,
_MapCount
} InventoryMaps;
}
namespace slots {
typedef enum : int16 {
MainCharm = 0,
MainEar1,
MainHead,
MainFace,
MainEar2,
MainNeck,
MainShoulders,
MainArms,
MainBack,
MainWrist1,
MainWrist2,
MainRange,
MainHands,
MainPrimary,
MainSecondary,
MainFinger1,
MainFinger2,
MainChest,
MainLegs,
MainFeet,
MainWaist,
MainAmmo,
MainGeneral1,
MainGeneral2,
MainGeneral3,
MainGeneral4,
MainGeneral5,
MainGeneral6,
MainGeneral7,
MainGeneral8,
MainCursor,
_MainCount,
_MainEquipmentBegin = MainCharm,
_MainEquipmentEnd = MainAmmo,
_MainEquipmentCount = (_MainEquipmentEnd - _MainEquipmentBegin + 1),
_MainGeneralBegin = MainGeneral1,
_MainGeneralEnd = MainGeneral8,
_MainGeneralCount = (_MainGeneralEnd - _MainGeneralBegin + 1)
} EquipmentSlots;
}
namespace consts {
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 16;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
static const uint16 MAP_TRADE_SIZE = 8;
static const uint16 MAP_WORLD_SIZE = 10;
static const uint16 MAP_LIMBO_SIZE = 36;
static const uint16 MAP_TRIBUTE_SIZE = 0; //?
static const uint16 MAP_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_GUILD_TRIBUTE_SIZE = 0;
static const uint16 MAP_MERCHANT_SIZE = 0;
static const uint16 MAP_DELETED_SIZE = 0;
static const uint16 MAP_CORPSE_SIZE = slots::_MainCount;
static const uint16 MAP_BAZAAR_SIZE = 80;
static const uint16 MAP_INSPECT_SIZE = slots::_MainEquipmentCount;
static const uint16 MAP_REAL_ESTATE_SIZE = 0;
static const uint16 MAP_VIEW_MOD_PC_SIZE = MAP_POSSESSIONS_SIZE;
static const uint16 MAP_VIEW_MOD_BANK_SIZE = MAP_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_SHARED_BANK_SIZE = MAP_SHARED_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_LIMBO_SIZE = MAP_LIMBO_SIZE;
static const uint16 MAP_ALT_STORAGE_SIZE = 0;
static const uint16 MAP_ARCHIVED_SIZE = 0;
static const uint16 MAP_MAIL_SIZE = 0;
static const uint16 MAP_GUILD_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_KRONO_SIZE = NOT_USED;
static const uint16 MAP_OTHER_SIZE = 0;
static const int16 POSSESSIONS_BEGIN = slots::MainCharm;
static const int16 POSSESSIONS_END = slots::MainCursor;
static const int16 EQUIPMENT_BEGIN = slots::MainCharm;
static const int16 EQUIPMENT_END = slots::MainAmmo;
static const uint16 EQUIPMENT_SIZE = slots::_MainEquipmentCount;
static const int16 GENERAL_BEGIN = slots::MainGeneral1;
static const int16 GENERAL_END = slots::MainGeneral8;
static const uint16 GENERAL_SIZE = slots::_MainGeneralCount;
static const int16 GENERAL_BAGS_BEGIN = 251;
static const int16 GENERAL_BAGS_END_OFFSET = 79;
static const int16 GENERAL_BAGS_END = GENERAL_BAGS_BEGIN + GENERAL_BAGS_END_OFFSET;
static const int16 CURSOR = slots::MainCursor;
static const int16 CURSOR_BAG_BEGIN = 331;
static const int16 CURSOR_BAG_END_OFFSET = 9;
static const int16 CURSOR_BAG_END = CURSOR_BAG_BEGIN + CURSOR_BAG_END_OFFSET;
static const int16 BANK_BEGIN = 2000;
static const int16 BANK_END = 2015;
static const int16 BANK_BAGS_BEGIN = 2031;
static const int16 BANK_BAGS_END_OFFSET = 159;
static const int16 BANK_BAGS_END = BANK_BAGS_BEGIN + BANK_BAGS_END_OFFSET;
static const int16 SHARED_BANK_BEGIN = 2500;
static const int16 SHARED_BANK_END = 2501;
static const int16 SHARED_BANK_BAGS_BEGIN = 2531;
static const int16 SHARED_BANK_BAGS_END_OFFSET = 19;
static const int16 SHARED_BANK_BAGS_END = SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_END_OFFSET;
static const int16 TRADE_BEGIN = 3000;
static const int16 TRADE_END = 3007;
static const int16 TRADE_END_NPC = 3003;
static const int16 TRADE_BAGS_BEGIN = 3031;
static const int16 TRADE_BAGS_END_OFFSET = 79;
static const int16 TRADE_BAGS_END = TRADE_BAGS_BEGIN + TRADE_BAGS_END_OFFSET;
static const int16 WORLD_BEGIN = 4000;
static const int16 WORLD_END = 4009;
static const int16 TRIBUTE_BEGIN = 400;
static const int16 TRIBUTE_END = 404;
static const int16 CORPSE_BEGIN = slots::MainGeneral1;
static const int16 CORPSE_END = slots::MainGeneral1 + slots::MainCursor;
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const uint32 BANDOLIERS_COUNT = 4; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 4;
}
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
static const bool COIN_HAS_WEIGHT = true;
}
}; //end namespace Titanium
#endif /*Titanium_CONSTANTS_H_*/
/*
Titanium Notes:
** Integer-based inventory **
ok Possessions: 0 - 30 (Corpse: 22 - 52 [Offset 22])
ok [Equipment: 0 - 21]
ok [General: 22 - 29]
ok [Cursor: 30]
ok General Bags: 251 - 330
ok Cursor Bags: 331 - 340
ok Bank: 2000 - 2015
ok Bank Bags: 2031 - 2190
ok Shared Bank: 2500 - 2501
ok Shared Bank Bags: 2531 - 2550
Trade: 3000 - 3007
(Trade Bags: 3031 - 3110 -- server values)
World: 4000 - 4009
*/

View File

@ -0,0 +1,215 @@
/*
EQEMu: Everquest Server Emulator
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef Underfoot_CONSTANTS_H_
#define Underfoot_CONSTANTS_H_
#include "../common/types.h"
namespace Underfoot {
namespace maps {
typedef enum : int16 {
// this needs work to match actual client equivilents
MapPossessions = 0,
MapBank,
MapSharedBank,
MapTrade,
MapWorld,
MapLimbo,
MapTribute,
MapTrophyTribute,
MapGuildTribute,
MapMerchant,
MapDeleted,
MapCorpse,
MapBazaar,
MapInspect,
MapRealEstate,
MapViewMODPC,
MapViewMODBank,
MapViewMODSharedBank,
MapViewMODLimbo,
MapAltStorage,
MapArchived,
MapMail,
MapGuildTrophyTribute,
MapOther,
_MapCount
} InventoryMaps;
}
namespace slots {
typedef enum : int16 {
MainCharm = 0,
MainEar1,
MainHead,
MainFace,
MainEar2,
MainNeck,
MainShoulders,
MainArms,
MainBack,
MainWrist1,
MainWrist2,
MainRange,
MainHands,
MainPrimary,
MainSecondary,
MainFinger1,
MainFinger2,
MainChest,
MainLegs,
MainFeet,
MainWaist,
MainPowerSource,
MainAmmo,
MainGeneral1,
MainGeneral2,
MainGeneral3,
MainGeneral4,
MainGeneral5,
MainGeneral6,
MainGeneral7,
MainGeneral8,
MainCursor,
_MainCount,
_MainEquipmentBegin = MainCharm,
_MainEquipmentEnd = MainAmmo,
_MainEquipmentCount = (_MainEquipmentEnd - _MainEquipmentBegin + 1),
_MainGeneralBegin = MainGeneral1,
_MainGeneralEnd = MainGeneral8,
_MainGeneralCount = (_MainGeneralEnd - _MainGeneralBegin + 1)
} EquipmentSlots;
}
namespace consts {
static const uint16 MAP_POSSESSIONS_SIZE = slots::_MainCount;
static const uint16 MAP_BANK_SIZE = 24;
static const uint16 MAP_SHARED_BANK_SIZE = 2;
static const uint16 MAP_TRADE_SIZE = 8;
static const uint16 MAP_WORLD_SIZE = 10;
static const uint16 MAP_LIMBO_SIZE = 36;
static const uint16 MAP_TRIBUTE_SIZE = 0; //?
static const uint16 MAP_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_GUILD_TRIBUTE_SIZE = 0;
static const uint16 MAP_MERCHANT_SIZE = 0;
static const uint16 MAP_DELETED_SIZE = 0;
static const uint16 MAP_CORPSE_SIZE = slots::_MainCount;
static const uint16 MAP_BAZAAR_SIZE = 80;
static const uint16 MAP_INSPECT_SIZE = slots::_MainEquipmentCount;
static const uint16 MAP_REAL_ESTATE_SIZE = 0;
static const uint16 MAP_VIEW_MOD_PC_SIZE = MAP_POSSESSIONS_SIZE;
static const uint16 MAP_VIEW_MOD_BANK_SIZE = MAP_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_SHARED_BANK_SIZE = MAP_SHARED_BANK_SIZE;
static const uint16 MAP_VIEW_MOD_LIMBO_SIZE = MAP_LIMBO_SIZE;
static const uint16 MAP_ALT_STORAGE_SIZE = 0;
static const uint16 MAP_ARCHIVED_SIZE = 0;
static const uint16 MAP_MAIL_SIZE = 0;
static const uint16 MAP_GUILD_TROPHY_TRIBUTE_SIZE = 0;
static const uint16 MAP_KRONO_SIZE = NOT_USED;
static const uint16 MAP_OTHER_SIZE = 0;
static const int16 POSSESSIONS_BEGIN = slots::MainCharm;
static const int16 POSSESSIONS_END = slots::MainCursor;
static const int16 EQUIPMENT_BEGIN = slots::MainCharm;
static const int16 EQUIPMENT_END = slots::MainAmmo;
static const uint16 EQUIPMENT_SIZE = slots::_MainEquipmentCount;
static const int16 GENERAL_BEGIN = slots::MainGeneral1;
static const int16 GENERAL_END = slots::MainGeneral8;
static const uint16 GENERAL_SIZE = slots::_MainGeneralCount;
static const int16 GENERAL_BAGS_BEGIN = 262;
static const int16 GENERAL_BAGS_END_OFFSET = 79;
static const int16 GENERAL_BAGS_END = GENERAL_BAGS_BEGIN + GENERAL_BAGS_END_OFFSET;
static const int16 CURSOR = slots::MainCursor;
static const int16 CURSOR_BAG_BEGIN = 342;
static const int16 CURSOR_BAG_END_OFFSET = 9;
static const int16 CURSOR_BAG_END = CURSOR_BAG_BEGIN + CURSOR_BAG_END_OFFSET;
static const int16 BANK_BEGIN = 2000;
static const int16 BANK_END = 2023;
static const int16 BANK_BAGS_BEGIN = 2032;
static const int16 BANK_BAGS_END_OFFSET = 239;
static const int16 BANK_BAGS_END = BANK_BAGS_BEGIN + BANK_BAGS_END_OFFSET;
static const int16 SHARED_BANK_BEGIN = 2500;
static const int16 SHARED_BANK_END = 2501;
static const int16 SHARED_BANK_BAGS_BEGIN = 2532;
static const int16 SHARED_BANK_BAGS_END_OFFSET = 19;
static const int16 SHARED_BANK_BAGS_END = SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_END_OFFSET;
static const int16 TRADE_BEGIN = 3000;
static const int16 TRADE_END = 3007;
static const int16 TRADE_END_NPC = 3003;
static const int16 TRADE_BAGS_BEGIN = 3031; // no change from Ti?
static const int16 TRADE_BAGS_END_OFFSET = 79;
static const int16 TRADE_BAGS_END = TRADE_BAGS_BEGIN + TRADE_BAGS_END_OFFSET;
static const int16 WORLD_BEGIN = 4000;
static const int16 WORLD_END = 4009;
static const int16 TRIBUTE_BEGIN = 400;
static const int16 TRIBUTE_END = 404;
static const int16 CORPSE_BEGIN = slots::MainGeneral1;
static const int16 CORPSE_END = slots::MainGeneral1 + slots::MainCursor;
static const uint16 ITEM_COMMON_SIZE = 5;
static const uint16 ITEM_CONTAINER_SIZE = 10;
static const uint32 BANDOLIERS_COUNT = 20; // count = number of bandolier instances
static const uint32 BANDOLIER_SIZE = 4; // size = number of equipment slots in bandolier instance
static const uint32 POTION_BELT_SIZE = 5;
}
namespace limits {
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
static const bool COIN_HAS_WEIGHT = false;
}
}; //end namespace Underfoot
#endif /*Underfoot_CONSTANTS_H_*/
/*
Underfoot Notes:
** Integer-based inventory **
ok Possessions: 0 - 31 (Corpse: 23 - 54 [Offset 23])
ok [Equipment: 0 - 22]
ok [General: 23 - 30]
ok [Cursor: 31]
ok General Bags: 262 - 341
ok Cursor Bags: 342 - 351
ok Bank: 2000 - 2023
ok Bank Bags: 2032 - 2271
ok Shared Bank: 2500 - 2501
ok Shared Bank Bags: 2532 - 2551
Trade: 3000 - 3007
(Trade Bags: 3031 - 3110 -- server values)
World: 4000 - 4009
*/

View File

@ -5,7 +5,7 @@ if [ -z "$1" ]; then
exit 1
fi
for ext in .cpp .h _ops.h _structs.h
for ext in .cpp .h _ops.h _constants.h _structs.h
do
cp template$ext $1$ext
perl -pi -e "s/TEMPLATE/$1/g" $1$ext

View File

@ -8,6 +8,7 @@
#include "SoF.h"
#include "SoD.h"
#include "RoF.h"
//#include "RoF2.h"
void RegisterAllPatches(EQStreamIdentifier &into) {
Client62::Register(into);
@ -16,6 +17,7 @@ void RegisterAllPatches(EQStreamIdentifier &into) {
SoD::Register(into);
Underfoot::Register(into);
RoF::Register(into);
//RoF2::Register(into);
}
void ReloadAllPatches() {
@ -25,4 +27,5 @@ void ReloadAllPatches() {
SoD::Reload();
Underfoot::Reload();
RoF::Reload();
//RoF2::Reload();
}

View File

@ -0,0 +1,20 @@
#ifndef TEMPLATE_CONSTANTS_H_
#define TEMPLATE_CONSTANTS_H_
namespace TEMPLATE {
// put constants here and #include appropriately
}; //end namespace TEMPLATE
#endif /*TEMPLATE_CONSTANTS_H_*/

View File

@ -311,6 +311,19 @@ RULE_INT ( Spells, FRProjectileItem_NPC, 80684) // Item id for NPC Fire 'spell p
RULE_BOOL ( Spells, UseLiveSpellProjectileGFX, false) // Use spell projectile graphics set in the spells_new table (player_1). Server must be using UF+ spell file.
RULE_BOOL ( Spells, FocusCombatProcs, false) //Allow all combat procs to receive focus effects.
RULE_BOOL ( Spells, PreNerfBardAEDoT, false) //Allow bard AOE dots to damage targets when moving.
RULE_INT ( Spells, AI_SpellCastFinishedFailRecast, 800) // AI spell recast time(MS) when an spell is cast but fails (ie stunned).
RULE_INT ( Spells, AI_EngagedNoSpellMinRecast, 500) // AI spell recast time(MS) check when no spell is cast while engaged. (min time in random)
RULE_INT ( Spells, AI_EngagedNoSpellMaxRecast, 1000) // AI spell recast time(MS) check when no spell is cast engaged.(max time in random)
RULE_INT ( Spells, AI_EngagedBeneficialSelfChance, 100) // Chance during first AI Cast check to do a beneficial spell on self.
RULE_INT ( Spells, AI_EngagedBeneficialOtherChance, 25) // Chance during second AI Cast check to do a beneficial spell on others.
RULE_INT ( Spells, AI_EngagedDetrimentalChance, 20) // Chance during third AI Cast check to do a determental spell on others.
RULE_INT ( Spells, AI_PursueNoSpellMinRecast, 500) // AI spell recast time(MS) check when no spell is cast while chasing target. (min time in random)
RULE_INT ( Spells, AI_PursueNoSpellMaxRecast, 2000) // AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)
RULE_INT ( Spells, AI_PursueDetrimentalChance, 90) // Chance while chasing target to cast a detrimental spell.
RULE_INT ( Spells, AI_IdleNoSpellMinRecast, 500) // AI spell recast time(MS) check when no spell is cast while idle. (min time in random)
RULE_INT ( Spells, AI_IdleNoSpellMaxRecast, 2000) // AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)
RULE_INT ( Spells, AI_IdleBeneficialChance, 100) // Chance while idle to do a beneficial spell on self or others.
RULE_CATEGORY_END()
RULE_CATEGORY( Combat )
@ -345,6 +358,8 @@ RULE_REAL ( Combat, HitBonusPerLevel, 1.2) //You gain this % of hit for every le
RULE_REAL ( Combat, WeaponSkillFalloff, 0.33) //For every weapon skill point that's not maxed you lose this % of hit
RULE_REAL ( Combat, ArcheryHitPenalty, 0.25) //Archery has a hit penalty to try to help balance it with the plethora of long term +hit modifiers for it
RULE_REAL ( Combat, AgiHitFactor, 0.01)
RULE_REAL ( Combat, MinChancetoHit, 5.0) //Minimum % chance to hit with regular melee/ranged
RULE_REAL ( Combat, MaxChancetoHit, 95.0) //Maximum % chance to hit with regular melee/ranged
RULE_INT ( Combat, MinRangedAttackDist, 25) //Minimum Distance to use Ranged Attacks
RULE_BOOL ( Combat, ArcheryBonusRequiresStationary, true) //does the 2x archery bonus chance require a stationary npc
RULE_REAL ( Combat, ArcheryBaseDamageBonus, 1) // % Modifier to Base Archery Damage (.5 = 50% base damage, 1 = 100%, 2 = 200%)

View File

@ -439,7 +439,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) {
const Item_Struct* item = GetItem(item_id);
if (item) {
int16 put_slot_id = SLOT_INVALID;
int16 put_slot_id = INVALID_INDEX;
ItemInst* inst = CreateBaseItem(item, charges);
if (item->ItemClass == ItemClassCommon) {
@ -479,7 +479,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) {
safe_delete(inst);
// Save ptr to item in inventory
if (put_slot_id == SLOT_INVALID) {
if (put_slot_id == INVALID_INDEX) {
LogFile->write(EQEMuLog::Error,
"Warning: Invalid slot_id for item in shared bank inventory: %s=%i, item_id=%i, slot_id=%i",
((is_charid==true) ? "charid" : "acctid"), id, item_id, slot_id);
@ -535,7 +535,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
const Item_Struct* item = GetItem(item_id);
if (item) {
int16 put_slot_id = SLOT_INVALID;
int16 put_slot_id = INVALID_INDEX;
ItemInst* inst = CreateBaseItem(item, charges);
@ -589,7 +589,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) {
safe_delete(inst);
// Save ptr to item in inventory
if (put_slot_id == SLOT_INVALID) {
if (put_slot_id == INVALID_INDEX) {
LogFile->write(EQEMuLog::Error,
"Warning: Invalid slot_id for item in inventory: charid=%i, item_id=%i, slot_id=%i",
char_id, item_id, slot_id);
@ -641,7 +641,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
aug[4] = (uint32)atoi(row[8]);
bool instnodrop = (row[9] && (uint16)atoi(row[9])) ? true : false;
const Item_Struct* item = GetItem(item_id);
int16 put_slot_id = SLOT_INVALID;
int16 put_slot_id = INVALID_INDEX;
if(!item)
continue;
@ -692,7 +692,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
safe_delete(inst);
// Save ptr to item in inventory
if (put_slot_id == SLOT_INVALID) {
if (put_slot_id == INVALID_INDEX) {
LogFile->write(EQEMuLog::Error,
"Warning: Invalid slot_id for item in inventory: name=%s, acctid=%i, item_id=%i, slot_id=%i",
name, account_id, item_id, slot_id);

View File

@ -53,7 +53,8 @@ enum SkillUseTypes : uint32
/*13879*/ SkillDivination,
/*13880*/ SkillDodge,
/*13881*/ SkillDoubleAttack,
/*13882*/ SkillDragonPunch, /*13924 SkillTailRake*/
/*13882*/ SkillDragonPunch,
/*13924*/ SkillTailRake = SkillDragonPunch, // Iksar Monk equivilent
/*13883*/ SkillDualWield,
/*13884*/ SkillEagleStrike,
/*13885*/ SkillEvocation,
@ -199,7 +200,7 @@ typedef enum {
DIVINATION = 18,
DODGE = 19,
DOUBLE_ATTACK = 20,
DRAGON_PUNCH = 21 , //aka Tail Rake
DRAGON_PUNCH = 21, //aka Tail Rake
DUAL_WIELD = 22,
EAGLE_STRIKE = 23,
EVOCATION = 24,

View File

@ -18,7 +18,6 @@
#ifndef TYPES_H
#define TYPES_H
#ifdef EQEMU_USE_STDINT
#include <stdint.h>
typedef uint8_t byte;
typedef uint8_t uint8;
@ -29,29 +28,6 @@ typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
#else
typedef unsigned char byte;
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short uint16;
typedef signed short int16;
typedef unsigned int uint32;
typedef signed int int32;
#ifdef _WINDOWS
#if defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64
typedef unsigned __int64 uint64;
typedef unsigned __int64 uint64;
typedef signed __int64 int64;
#else
#error __int64 not supported
#endif
#else
typedef unsigned long long uint64;
typedef unsigned long long uint64;
typedef signed long long int64;
#endif
#endif
#ifdef _WINDOWS
#pragma warning( disable : 4200 )

View File

@ -15,7 +15,7 @@ ADD_EXECUTABLE(eqlaunch ${eqlaunch_sources} ${eqlaunch_headers})
INSTALL(TARGETS eqlaunch RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(eqlaunch Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(eqlaunch common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(eqlaunch PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
@ -37,4 +37,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/Bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -43,7 +43,7 @@ ADD_EXECUTABLE(loginserver ${eqlogin_sources} ${eqlogin_headers})
INSTALL(TARGETS loginserver RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(loginserver Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE})
TARGET_LINK_LIBRARIES(loginserver common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE})
IF(MSVC)
SET_TARGET_PROPERTIES(loginserver PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
@ -67,4 +67,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/Bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -31,4 +31,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(LIBRARY_OUTPUT_PATH ../Bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -21,7 +21,7 @@ INSTALL(TARGETS queryserv RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
ADD_DEFINITIONS(-DQSERV)
TARGET_LINK_LIBRARIES(queryserv Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(queryserv common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(queryserv PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
@ -43,4 +43,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/Bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -23,7 +23,7 @@ ADD_EXECUTABLE(shared_memory ${shared_memory_sources} ${shared_memory_headers})
INSTALL(TARGETS shared_memory RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(shared_memory Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(shared_memory common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(shared_memory PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
@ -45,4 +45,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/Bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -17,7 +17,7 @@ SET(tests_headers
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
TARGET_LINK_LIBRARIES(tests Common cppunit)
TARGET_LINK_LIBRARIES(tests common cppunit)
IF(MSVC)
SET_TARGET_PROPERTIES(tests PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
@ -39,4 +39,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ../Bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -23,7 +23,7 @@ INSTALL(TARGETS ucs RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
ADD_DEFINITIONS(-DUCS)
TARGET_LINK_LIBRARIES(ucs Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(ucs common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(ucs PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
@ -45,4 +45,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/Bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -0,0 +1,15 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_SpellCastFinishedFailRecast','800', 'AI spell recast time(MS) when an spell is cast but fails (ie stunned)');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_EngagedNoSpellMinRecast','500', 'AI spell recast time(MS) check when no spell is cast while engaged. (min time in random)');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_EngagedNoSpellMaxRecast','1000','AI spell recast time(MS) check when no spell is cast engaged.(max time in random)');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_EngagedBeneficialSelfChance,','100', 'Chance during first AI Cast check to do a beneficial spell on self.');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_EngagedBeneficialOtherChance','25', 'Chance during second AI Cast check to do a beneficial spell on others.');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_EngagedDetrimentalChance','20','Chance during third AI Cast check to do a determental spell on others.');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_PursueNoSpellMinRecast','500', 'AI spell recast time(MS) check when no spell is cast while chasing target. (min time in random)');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_PursueNoSpellMaxRecast','2000','AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_PursueDetrimentalChance','90','Chance while chasing target to cast a detrimental spell.');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_IdleNoSpellMinRecast','500','AI spell recast time(MS) check when no spell is cast while idle. (min time in random)');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_IdleNoSpellMaxRecast','2000','AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_IdleBeneficialChance','100','Chance while idle to do a beneficial spell on self or others.');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Combat:MinChancetoHit','5','Minimum % chance to hit with regular melee/ranged.');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Combat:MaxChancetoHit','95','Maximum % chance to hit with regular melee/ranged.');

View File

@ -1,3 +1,5 @@
ALTER TABLE `npc_types` ADD `no_target_hotkey` tinyint( 1 ) UNSIGNED NOT NULL DEFAULT '0' AFTER `healscale`;
-- npc_types
ALTER TABLE `npc_types` ADD `ammo_idfile` varchar( 30 ) NOT NULL DEFAULT 'IT10' AFTER `d_meele_texture2`;
ALTER TABLE `npc_types` ADD `ranged_type` tinyint( 4 ) UNSIGNED NOT NULL DEFAULT '7' AFTER `sec_melee_type`;

View File

@ -0,0 +1,22 @@
-- npc_types
ALTER TABLE `npc_types` ADD `ammo_idfile` varchar( 30 ) NOT NULL DEFAULT 'IT10' AFTER `d_meele_texture2`;
ALTER TABLE `npc_types` ADD `ranged_type` tinyint( 4 ) UNSIGNED NOT NULL DEFAULT '7' AFTER `sec_melee_type`;
ALTER TABLE `npc_types` ADD `Avoidance` mediumint(9) UNSIGNED NOT NULL DEFAULT '0' AFTER `Accuracy`;
-- npc spells
ALTER TABLE `npc_spells` ADD `range_proc` smallint(5) NOT NULL DEFAULT '-1';
ALTER TABLE `npc_spells` ADD `rproc_chance` smallint(5) NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `defensive_proc` smallint(5) NOT NULL DEFAULT '-1';
ALTER TABLE `npc_spells` ADD `dproc_chance` smallint(5) NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `fail_recast` int(11) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `engaged_no_sp_recast_min` int(11) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `engaged_no_sp_recast_max` int(11) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `engaged_b_self_chance` tinyint(3) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `engaged_b_other_chance` tinyint(3) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `engaged_d_chance` tinyint(3) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `pursue_no_sp_recast_min` int(3) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `pursue_no_sp_recast_max` int(11) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `pursue_d_chance` tinyint(3) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `idle_no_sp_recast_min` int(11) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `idle_no_sp_recast_max` int(11) unsigned NOT NULL DEFAULT '0';
ALTER TABLE `npc_spells` ADD `idle_b_chance` tinyint(11) unsigned NOT NULL DEFAULT '0';

View File

@ -23,7 +23,6 @@ SET(world_sources
perl_EQW.cpp
perl_HTTPRequest.cpp
queryserv.cpp
socket_server.cpp
ucs.cpp
wguild_mgr.cpp
world_logsys.cpp
@ -54,7 +53,6 @@ SET(world_headers
LoginServerList.h
net.h
queryserv.h
socket_server.h
SoFCharCreateData.h
ucs.h
wguild_mgr.h
@ -71,7 +69,7 @@ INSTALL(TARGETS world RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
ADD_DEFINITIONS(-DWORLD)
TARGET_LINK_LIBRARIES(world Common ${PERL_LIBRARY} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(world common ${PERL_LIBRARY} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(MSVC)
SET_TARGET_PROPERTIES(world PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
@ -93,4 +91,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/Bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -46,7 +46,6 @@
#include "LauncherList.h"
#include "ucs.h"
#include "queryserv.h"
#include "socket_server.h"
#ifdef _WINDOWS
#define snprintf _snprintf
@ -61,7 +60,6 @@ extern ClientList client_list;
extern LauncherList launcher_list;
extern UCSConnection UCSLink;
extern QueryServConnection QSLink;
extern Socket_Server_Connection SSLink;
extern volatile bool RunLoops;
ConsoleList console_list;
@ -265,12 +263,6 @@ bool Console::Process() {
QSLink.SetConnection(tcpc);
tcpc = 0;
}
else if (tcpc->GetPacketMode() == EmuTCPConnection::packetModeSocket_Server)
{
_log(WORLD__CONSOLE, "New Socket Server Connection from %s:%d", inet_ntoa(in), GetPort());
SSLink.SetConnection(tcpc);
tcpc = 0;
}
else {
_log(WORLD__CONSOLE,"Unsupported packet mode from %s:%d", inet_ntoa(in), GetPort());
}

View File

@ -86,7 +86,6 @@
#include "AdventureManager.h"
#include "ucs.h"
#include "queryserv.h"
#include "socket_server.h"
TimeoutManager timeout_manager;
EQStreamFactory eqsf(WorldStream,9000);
@ -98,7 +97,6 @@ LoginServerList loginserverlist;
EQWHTTPServer http_server;
UCSConnection UCSLink;
QueryServConnection QSLink;
Socket_Server_Connection SSLink;
LauncherList launcher_list;
AdventureManager adventure_manager;
DBAsync *dbasync = nullptr;
@ -456,8 +454,6 @@ int main(int argc, char** argv) {
QSLink.Process();
SSLink.Process();
LFPGroupList.Process();
adventure_manager.Process();

View File

@ -1,127 +0,0 @@
#include "../common/debug.h"
#include "socket_server.h"
#include "WorldConfig.h"
#include "clientlist.h"
#include "zonelist.h"
#include "../common/logsys.h"
#include "../common/logtypes.h"
#include "../common/md5.h"
#include "../common/EmuTCPConnection.h"
#include "../common/packet_dump.h"
extern ClientList client_list;
extern ZSList zoneserver_list;
Socket_Server_Connection::Socket_Server_Connection()
{
Stream = 0;
authenticated = false;
}
void Socket_Server_Connection::SetConnection(EmuTCPConnection *inStream)
{
if(Stream)
{
_log(SOCKET_SERVER__ERROR, "Incoming Socket_Server Connection while we were already connected to a Socket_Server.");
Stream->Disconnect();
}
Stream = inStream;
authenticated = false;
}
bool Socket_Server_Connection::Process()
{
if (!Stream || !Stream->Connected())
return false;
ServerPacket *pack = 0;
while((pack = Stream->PopPacket()))
{
if (!authenticated)
{
if (WorldConfig::get()->SharedKey.length() > 0)
{
if (pack->opcode == ServerOP_ZAAuth && pack->size == 16)
{
uint8 tmppass[16];
MD5::Generate((const uchar*) WorldConfig::get()->SharedKey.c_str(), WorldConfig::get()->SharedKey.length(), tmppass);
if (memcmp(pack->pBuffer, tmppass, 16) == 0)
authenticated = true;
else
{
struct in_addr in;
in.s_addr = GetIP();
_log(SOCKET_SERVER__ERROR, "Socket_Server authorization failed.");
ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
SendPacket(pack);
delete pack;
Disconnect();
return false;
}
}
else
{
struct in_addr in;
in.s_addr = GetIP();
_log(SOCKET_SERVER__ERROR, "Socket_Server_ authorization failed.");
ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
SendPacket(pack);
delete pack;
Disconnect();
return false;
}
}
else
{
_log(SOCKET_SERVER__ERROR,"**WARNING** You have not configured a world shared key in your config file. You should add a <key>STRING</key> element to your <world> element to prevent unauthorized zone access.");
authenticated = true;
}
delete pack;
continue;
}
switch(pack->opcode)
{
case 0:
break;
case ServerOP_KeepAlive:
{
// ignore this
break;
}
case ServerOP_ZAAuth:
{
_log(SOCKET_SERVER__ERROR, "Got authentication from Socket_Server_ when they are already authenticated.");
break;
}
case ServerOP_LFGuildUpdate:
{
zoneserver_list.SendPacket(pack);
break;
}
default:
{
_log(SOCKET_SERVER__ERROR, "Unknown ServerOPcode from Socket_Server_ 0x%04x, size %d", pack->opcode, pack->size);
DumpPacket(pack->pBuffer, pack->size);
break;
}
}
delete pack;
}
return(true);
}
bool Socket_Server_Connection::SendPacket(ServerPacket* pack)
{
if(!Stream)
return false;
return Stream->SendPacket(pack);
}

View File

@ -1,23 +0,0 @@
#ifndef Socket_Server__H
#define Socket_Server__H
#include "../common/types.h"
#include "../common/EmuTCPConnection.h"
#include "../common/servertalk.h"
class Socket_Server_Connection
{
public:
Socket_Server_Connection();
void SetConnection(EmuTCPConnection *inStream);
bool Process();
bool SendPacket(ServerPacket* pack);
void Disconnect() { if(Stream) Stream->Disconnect(); }
void SendMessage(const char *From, const char *Message);
private:
inline uint32 GetIP() const { return Stream ? Stream->GetrIP() : 0; }
EmuTCPConnection *Stream;
bool authenticated;
};
#endif /*Socket_Server__H_*/

View File

@ -218,7 +218,7 @@ INSTALL(TARGETS zone RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
ADD_DEFINITIONS(-DZONE)
TARGET_LINK_LIBRARIES(zone Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
TARGET_LINK_LIBRARIES(zone common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
IF(EQEMU_BUILD_PERL)
TARGET_LINK_LIBRARIES(zone ${PERL_LIBRARY})
@ -249,4 +249,4 @@ IF(UNIX)
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/Bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -824,17 +824,17 @@ void Client::AI_Process()
if(GetTarget() && !IsStunned() && !IsMezzed() && !GetFeigned()) {
if(attack_timer.Check()) {
Attack(GetTarget(), 13);
Attack(GetTarget(), MainPrimary);
if(GetTarget()) {
if(CheckDoubleAttack()) {
Attack(GetTarget(), 13);
Attack(GetTarget(), MainPrimary);
if(GetTarget()) {
bool triple_attack_success = false;
if((((GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
&& GetLevel() >= 60) || GetSpecialAbility(SPECATK_TRIPLE))
&& CheckDoubleAttack(true))
{
Attack(GetTarget(), 13, true);
Attack(GetTarget(), MainPrimary, true);
triple_attack_success = true;
}
@ -848,15 +848,15 @@ void Client::AI_Process()
if(MakeRandomInt(0, 100) < flurrychance)
{
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
Attack(GetTarget(), 13, false);
Attack(GetTarget(), 13, false);
Attack(GetTarget(), MainPrimary, false);
Attack(GetTarget(), MainPrimary, false);
}
}
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance;
if (ExtraAttackChanceBonus && GetTarget()) {
ItemInst *wpn = GetInv().GetItem(SLOT_PRIMARY);
ItemInst *wpn = GetInv().GetItem(MainPrimary);
if(wpn){
if(wpn->GetItem()->ItemType == ItemType2HSlash ||
wpn->GetItem()->ItemType == ItemType2HBlunt ||
@ -864,7 +864,7 @@ void Client::AI_Process()
{
if(MakeRandomInt(0, 100) < ExtraAttackChanceBonus)
{
Attack(GetTarget(), 13, false);
Attack(GetTarget(), MainPrimary, false);
}
}
}
@ -903,10 +903,10 @@ void Client::AI_Process()
if(MakeRandomFloat(0.0, 1.0) < DualWieldProbability)
{
Attack(GetTarget(), 14);
Attack(GetTarget(), MainSecondary);
if(CheckDoubleAttack())
{
Attack(GetTarget(), 14);
Attack(GetTarget(), MainSecondary);
}
}
@ -1145,14 +1145,14 @@ void Mob::AI_Process() {
if(IsNPC()) {
int16 n_atk = CastToNPC()->GetNumberOfAttacks();
if(n_atk <= 1) {
Attack(target, 13);
Attack(target, MainPrimary);
} else {
for(int i = 0; i < n_atk; ++i) {
Attack(target, 13);
Attack(target, MainPrimary);
}
}
} else {
Attack(target, 13);
Attack(target, MainPrimary);
}
if (target) {
@ -1164,16 +1164,16 @@ void Mob::AI_Process() {
|| GetSpecialAbility(SPECATK_QUAD))
//check double attack, this is NOT the same rules that clients use...
&& RandRoll < (GetLevel() + NPCDualAttackModifier)) {
Attack(target, 13);
Attack(target, MainPrimary);
// lets see if we can do a triple attack with the main hand
//pets are excluded from triple and quads...
if ((GetSpecialAbility(SPECATK_TRIPLE) || GetSpecialAbility(SPECATK_QUAD))
&& !IsPet() && RandRoll < (GetLevel() + NPCTripleAttackModifier)) {
Attack(target, 13);
Attack(target, MainPrimary);
// now lets check the quad attack
if (GetSpecialAbility(SPECATK_QUAD)
&& RandRoll < (GetLevel() + NPCQuadAttackModifier)) {
Attack(target, 13);
Attack(target, MainPrimary);
}
}
}
@ -1319,13 +1319,13 @@ void Mob::AI_Process() {
float DualWieldProbability = (GetSkill(SkillDualWield) + GetLevel()) / 400.0f;
if(MakeRandomFloat(0.0, 1.0) < DualWieldProbability)
{
Attack(target, 14);
Attack(target, MainSecondary);
if (CanThisClassDoubleAttack())
{
int32 RandRoll = MakeRandomInt(0, 99);
if (RandRoll < (GetLevel() + 20))
{
Attack(target, 14);
Attack(target, MainSecondary);
}
}
}
@ -1897,7 +1897,7 @@ void NPC::AI_Event_SpellCastFinished(bool iCastSucceeded, uint8 slot) {
AIautocastspell_timer->Start(recovery_time, false);
}
else
AIautocastspell_timer->Start(800, false);
AIautocastspell_timer->Start(AISpellVar.fail_recast, false);
casting_spell_AIindex = AIspells.size();
}
}
@ -1910,13 +1910,13 @@ bool NPC::AI_EngagedCastCheck() {
mlog(AI__SPELLS, "Engaged autocast check triggered. Trying to cast healing spells then maybe offensive spells.");
// try casting a heal or gate
if (!AICastSpell(this, 100, SpellType_Heal | SpellType_Escape | SpellType_InCombatBuff)) {
if (!AICastSpell(this, AISpellVar.engaged_beneficial_self_chance, SpellType_Heal | SpellType_Escape | SpellType_InCombatBuff)) {
// try casting a heal on nearby
if (!entity_list.AICheckCloseBeneficialSpells(this, 25, MobAISpellRange, SpellType_Heal)) {
if (!entity_list.AICheckCloseBeneficialSpells(this, AISpellVar.engaged_beneficial_other_chance, MobAISpellRange, SpellType_Heal)) {
//nobody to heal, try some detrimental spells.
if(!AICastSpell(GetTarget(), 20, SpellType_Nuke | SpellType_Lifetap | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff | SpellType_Charm | SpellType_Root)) {
if(!AICastSpell(GetTarget(), AISpellVar.engaged_detrimental_chance, SpellType_Nuke | SpellType_Lifetap | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff | SpellType_Charm | SpellType_Root)) {
//no spell to cast, try again soon.
AIautocastspell_timer->Start(RandomTimer(500, 1000), false);
AIautocastspell_timer->Start(RandomTimer(AISpellVar.engaged_no_sp_recast_min, AISpellVar.engaged_no_sp_recast_max), false);
}
}
}
@ -1931,9 +1931,9 @@ bool NPC::AI_PursueCastCheck() {
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
mlog(AI__SPELLS, "Engaged (pursuing) autocast check triggered. Trying to cast offensive spells.");
if(!AICastSpell(GetTarget(), 90, SpellType_Root | SpellType_Nuke | SpellType_Lifetap | SpellType_Snare | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff)) {
if(!AICastSpell(GetTarget(), AISpellVar.pursue_detrimental_chance, SpellType_Root | SpellType_Nuke | SpellType_Lifetap | SpellType_Snare | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff)) {
//no spell cast, try again soon.
AIautocastspell_timer->Start(RandomTimer(500, 2000), false);
AIautocastspell_timer->Start(RandomTimer(AISpellVar.pursue_no_sp_recast_min, AISpellVar.pursue_no_sp_recast_max), false);
} //else, spell casting finishing will reset the timer.
return(true);
}
@ -1946,11 +1946,11 @@ bool NPC::AI_IdleCastCheck() {
std::cout << "Non-Engaged autocast check triggered: " << this->GetName() << std::endl;
#endif
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
if (!AICastSpell(this, 100, SpellType_Heal | SpellType_Buff | SpellType_Pet)) {
if (!AICastSpell(this, AISpellVar.idle_beneficial_chance, SpellType_Heal | SpellType_Buff | SpellType_Pet)) {
if(!entity_list.AICheckCloseBeneficialSpells(this, 33, MobAISpellRange, SpellType_Heal | SpellType_Buff)) {
//if we didnt cast any spells, our autocast timer just resets to the
//last duration it was set to... try to put up a more reasonable timer...
AIautocastspell_timer->Start(RandomTimer(1000, 5000), false);
AIautocastspell_timer->Start(RandomTimer(AISpellVar.idle_no_sp_recast_min, AISpellVar.idle_no_sp_recast_max), false);
} //else, spell casting finishing will reset the timer.
} //else, spell casting finishing will reset the timer.
return(true);
@ -2024,7 +2024,7 @@ bool Mob::Flurry(ExtraAttackOptions *opts)
int num_attacks = GetSpecialAbilityParam(SPECATK_FLURRY, 1);
num_attacks = num_attacks > 0 ? num_attacks : RuleI(Combat, MaxFlurryHits);
for (int i = 0; i < num_attacks; i++)
Attack(target, 13, false, false, false, opts);
Attack(target, MainPrimary, false, false, false, opts);
}
return true;
}
@ -2073,14 +2073,14 @@ bool Mob::Rampage(ExtraAttackOptions *opts)
if (m_target == GetTarget())
continue;
if (CombatRange(m_target)) {
Attack(m_target, 13, false, false, false, opts);
Attack(m_target, MainPrimary, false, false, false, opts);
index_hit++;
}
}
}
if (RuleB(Combat, RampageHitsTarget) && index_hit < rampage_targets)
Attack(GetTarget(), 13, false, false, false, opts);
Attack(GetTarget(), MainPrimary, false, false, false, opts);
return true;
}
@ -2099,7 +2099,7 @@ void Mob::AreaRampage(ExtraAttackOptions *opts)
index_hit = hate_list.AreaRampage(this, GetTarget(), rampage_targets, opts);
if(index_hit == 0) {
Attack(GetTarget(), 13, false, false, false, opts);
Attack(GetTarget(), MainPrimary, false, false, false, opts);
}
}
@ -2340,11 +2340,44 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
std::cout << " (not found)";
std::cout << std::endl;
#endif
int16 attack_proc_spell = -1;
uint16 attack_proc_spell = -1;
int8 proc_chance = 3;
uint16 range_proc_spell = -1;
int16 rproc_chance = 0;
uint16 defensive_proc_spell = -1;
int16 dproc_chance = 0;
uint32 _fail_recast = 0;
uint32 _engaged_no_sp_recast_min = 0;
uint32 _engaged_no_sp_recast_max = 0;
uint8 _engaged_beneficial_self_chance = 0;
uint8 _engaged_beneficial_other_chance = 0;
uint8 _engaged_detrimental_chance = 0;
uint32 _pursue_no_sp_recast_min = 0;
uint32 _pursue_no_sp_recast_max = 0;
uint8 _pursue_detrimental_chance = 0;
uint32 _idle_no_sp_recast_min = 0;
uint32 _idle_no_sp_recast_max = 0;
uint8 _idle_beneficial_chance = 0;
if (parentlist) {
attack_proc_spell = parentlist->attack_proc;
proc_chance = parentlist->proc_chance;
range_proc_spell = parentlist->range_proc;
rproc_chance = parentlist->rproc_chance;
defensive_proc_spell = parentlist->defensive_proc;
dproc_chance = parentlist->dproc_chance;
_fail_recast = parentlist->fail_recast;
_engaged_no_sp_recast_min = parentlist->engaged_no_sp_recast_min;
_engaged_no_sp_recast_max = parentlist->engaged_no_sp_recast_max;
_engaged_beneficial_self_chance = parentlist->engaged_beneficial_self_chance;
_engaged_beneficial_other_chance = parentlist->engaged_beneficial_other_chance;
_engaged_detrimental_chance = parentlist->engaged_detrimental_chance;
_pursue_no_sp_recast_min = parentlist->pursue_no_sp_recast_min;
_pursue_no_sp_recast_max = parentlist->pursue_no_sp_recast_max;
_pursue_detrimental_chance = parentlist->pursue_detrimental_chance;
_idle_no_sp_recast_min = parentlist->idle_no_sp_recast_min;
_idle_no_sp_recast_max = parentlist->idle_no_sp_recast_max;
_idle_beneficial_chance = parentlist->idle_beneficial_chance;
for (i=0; i<parentlist->numentries; i++) {
if (GetLevel() >= parentlist->entries[i].minlevel && GetLevel() <= parentlist->entries[i].maxlevel && parentlist->entries[i].spellid > 0) {
if (!IsSpellInList(spell_list, parentlist->entries[i].spellid))
@ -2361,6 +2394,36 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
attack_proc_spell = spell_list->attack_proc;
proc_chance = spell_list->proc_chance;
}
if (spell_list->range_proc >= 0) {
range_proc_spell = spell_list->range_proc;
rproc_chance = spell_list->rproc_chance;
}
if (spell_list->defensive_proc >= 0) {
defensive_proc_spell = spell_list->defensive_proc;
dproc_chance = spell_list->dproc_chance;
}
//If any casting variables are defined in the current list, ignore those in the parent list.
if (spell_list->fail_recast || spell_list->engaged_no_sp_recast_min || spell_list->engaged_no_sp_recast_max
|| spell_list->engaged_beneficial_self_chance || spell_list->engaged_beneficial_other_chance || spell_list->engaged_detrimental_chance
|| spell_list->pursue_no_sp_recast_min || spell_list->pursue_no_sp_recast_max || spell_list->pursue_detrimental_chance
|| spell_list->idle_no_sp_recast_min || spell_list->idle_no_sp_recast_max || spell_list->idle_beneficial_chance) {
_fail_recast = spell_list->fail_recast;
_engaged_no_sp_recast_min = spell_list->engaged_no_sp_recast_min;
_engaged_no_sp_recast_max = spell_list->engaged_no_sp_recast_max;
_engaged_beneficial_self_chance = spell_list->engaged_beneficial_self_chance;
_engaged_beneficial_other_chance = spell_list->engaged_beneficial_other_chance;
_engaged_detrimental_chance = spell_list->engaged_detrimental_chance;
_pursue_no_sp_recast_min = spell_list->pursue_no_sp_recast_min;
_pursue_no_sp_recast_max = spell_list->pursue_no_sp_recast_max;
_pursue_detrimental_chance = spell_list->pursue_detrimental_chance;
_idle_no_sp_recast_min = spell_list->idle_no_sp_recast_min;
_idle_no_sp_recast_max = spell_list->idle_no_sp_recast_max;
_idle_beneficial_chance = spell_list->idle_beneficial_chance;
}
for (i=0; i<spell_list->numentries; i++) {
if (GetLevel() >= spell_list->entries[i].minlevel && GetLevel() <= spell_list->entries[i].maxlevel && spell_list->entries[i].spellid > 0) {
AddSpellToNPCList(spell_list->entries[i].priority,
@ -2371,9 +2434,30 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
}
std::sort(AIspells.begin(), AIspells.end(), Compare_AI_Spells);
if (attack_proc_spell > 0)
if (IsValidSpell(attack_proc_spell))
AddProcToWeapon(attack_proc_spell, true, proc_chance);
if (IsValidSpell(range_proc_spell))
AddRangedProc(range_proc_spell, (rproc_chance + 100));
if (IsValidSpell(defensive_proc_spell))
AddDefensiveProc(defensive_proc_spell, (dproc_chance + 100));
//Set AI casting variables
AISpellVar.fail_recast = (_fail_recast) ? _fail_recast : RuleI(Spells, AI_SpellCastFinishedFailRecast);
AISpellVar.engaged_no_sp_recast_min = (_engaged_no_sp_recast_min) ? _engaged_no_sp_recast_min : RuleI(Spells, AI_EngagedNoSpellMinRecast);
AISpellVar.engaged_no_sp_recast_max = (_engaged_no_sp_recast_max) ? _engaged_no_sp_recast_max : RuleI(Spells, AI_EngagedNoSpellMaxRecast);
AISpellVar.engaged_beneficial_self_chance = (_engaged_beneficial_self_chance) ? _engaged_beneficial_self_chance : RuleI(Spells, AI_EngagedBeneficialSelfChance);
AISpellVar.engaged_beneficial_other_chance = (_engaged_beneficial_other_chance) ? _engaged_beneficial_other_chance : RuleI(Spells, AI_EngagedBeneficialOtherChance);
AISpellVar.engaged_detrimental_chance = (_engaged_detrimental_chance) ? _engaged_detrimental_chance : RuleI(Spells, AI_EngagedDetrimentalChance);
AISpellVar.pursue_no_sp_recast_min = (_pursue_no_sp_recast_min) ? _pursue_no_sp_recast_min : RuleI(Spells, AI_PursueNoSpellMinRecast);
AISpellVar.pursue_no_sp_recast_max = (_pursue_no_sp_recast_max) ? _pursue_no_sp_recast_max : RuleI(Spells, AI_PursueNoSpellMaxRecast);
AISpellVar.pursue_detrimental_chance = (_pursue_detrimental_chance) ? _pursue_detrimental_chance : RuleI(Spells, AI_PursueDetrimentalChance);
AISpellVar.idle_no_sp_recast_min = (_idle_no_sp_recast_min) ? _idle_no_sp_recast_min : RuleI(Spells, AI_IdleNoSpellMinRecast);
AISpellVar.idle_no_sp_recast_max = (_idle_no_sp_recast_max) ? _idle_no_sp_recast_max : RuleI(Spells, AI_IdleNoSpellMaxRecast);
AISpellVar.idle_beneficial_chance = (_idle_beneficial_chance) ? _idle_beneficial_chance : RuleI(Spells, AI_IdleBeneficialChance);
if (AIspells.size() == 0)
AIautocastspell_timer->Disable();
else
@ -2568,13 +2652,29 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) {
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, parent_list, attack_proc, proc_chance from npc_spells where id=%d", iDBSpellsID), errbuf, &result)) {
if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, parent_list, attack_proc, proc_chance, range_proc, rproc_chance, defensive_proc, dproc_chance, fail_recast, engaged_no_sp_recast_min, engaged_no_sp_recast_max, engaged_b_self_chance, engaged_b_other_chance, engaged_d_chance, pursue_no_sp_recast_min, pursue_no_sp_recast_max, pursue_d_chance, idle_no_sp_recast_min, idle_no_sp_recast_max, idle_b_chance from npc_spells where id=%d", iDBSpellsID), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
uint32 tmpparent_list = atoi(row[1]);
int16 tmpattack_proc = atoi(row[2]);
uint16 tmpattack_proc = atoi(row[2]);
uint8 tmpproc_chance = atoi(row[3]);
uint16 tmprange_proc = atoi(row[4]);
int16 tmprproc_chance = atoi(row[5]);
uint16 tmpdefensive_proc = atoi(row[6]);
int16 tmpdproc_chance = atoi(row[7]);
uint32 tmppfail_recast = atoi(row[8]);
uint32 tmpengaged_no_sp_recast_min = atoi(row[9]);
uint32 tmpengaged_no_sp_recast_max = atoi(row[10]);
uint8 tmpengaged_b_self_chance = atoi(row[11]);
uint8 tmpengaged_b_other_chance = atoi(row[12]);
uint8 tmpengaged_d_chance = atoi(row[13]);
uint32 tmppursue_no_sp_recast_min = atoi(row[14]);
uint32 tmppursue_no_sp_recast_max = atoi(row[15]);
uint8 tmppursue_d_chance = atoi(row[16]);
uint32 tmpidle_no_sp_recast_min = atoi(row[17]);
uint32 tmpidle_no_sp_recast_max = atoi(row[18]);
uint8 tmpidle_b_chance = atoi(row[19]);
mysql_free_result(result);
if (RunQuery(query, MakeAnyLenString(&query, "SELECT spellid, type, minlevel, maxlevel, manacost, recast_delay, priority, resist_adjust from npc_spells_entries where npc_spells_id=%d ORDER BY minlevel", iDBSpellsID), errbuf, &result)) {
safe_delete_array(query);
@ -2584,6 +2684,22 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) {
npc_spells_cache[iDBSpellsID]->parent_list = tmpparent_list;
npc_spells_cache[iDBSpellsID]->attack_proc = tmpattack_proc;
npc_spells_cache[iDBSpellsID]->proc_chance = tmpproc_chance;
npc_spells_cache[iDBSpellsID]->range_proc = tmprange_proc;
npc_spells_cache[iDBSpellsID]->rproc_chance = tmpdproc_chance;
npc_spells_cache[iDBSpellsID]->defensive_proc = tmpdefensive_proc;
npc_spells_cache[iDBSpellsID]->dproc_chance = tmpdproc_chance;
npc_spells_cache[iDBSpellsID]->fail_recast = tmppfail_recast;
npc_spells_cache[iDBSpellsID]->engaged_no_sp_recast_min = tmpengaged_no_sp_recast_min;
npc_spells_cache[iDBSpellsID]->engaged_no_sp_recast_max = tmpengaged_no_sp_recast_max;
npc_spells_cache[iDBSpellsID]->engaged_beneficial_self_chance = tmpengaged_b_self_chance;
npc_spells_cache[iDBSpellsID]->engaged_beneficial_other_chance = tmpengaged_b_other_chance;
npc_spells_cache[iDBSpellsID]->engaged_detrimental_chance = tmpengaged_d_chance;
npc_spells_cache[iDBSpellsID]->pursue_no_sp_recast_min = tmppursue_no_sp_recast_min;
npc_spells_cache[iDBSpellsID]->pursue_no_sp_recast_max = tmppursue_no_sp_recast_max;
npc_spells_cache[iDBSpellsID]->pursue_detrimental_chance = tmppursue_d_chance;
npc_spells_cache[iDBSpellsID]->idle_no_sp_recast_min = tmpidle_no_sp_recast_min;
npc_spells_cache[iDBSpellsID]->idle_no_sp_recast_max = tmpidle_no_sp_recast_max;
npc_spells_cache[iDBSpellsID]->idle_beneficial_chance = tmpidle_b_chance;
npc_spells_cache[iDBSpellsID]->numentries = mysql_num_rows(result);
int j = 0;
while ((row = mysql_fetch_row(result))) {

View File

@ -349,7 +349,7 @@ void Object::Close() {
ItemInst* container = this->m_inst;
if(container != nullptr)
{
for (uint8 i = 0; i < MAX_ITEMS_PER_BAG; i++)
for (uint8 i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++)
{
ItemInst* inst = container->PopItem(i);
if(inst != nullptr)
@ -456,7 +456,7 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
// the client updates itself and takes care of sending "duplicate lore item" messages
if(sender->CheckLoreConflict(m_inst->GetItem())) {
int16 loreslot = sender->GetInv().HasItem(m_inst->GetItem()->ID, 0, invWhereBank);
if(loreslot != SLOT_INVALID) // if the duplicate is in the bank, delete it.
if (loreslot != INVALID_INDEX) // if the duplicate is in the bank, delete it.
sender->DeleteItemInInventory(loreslot);
else
cursordelete = true; // otherwise, we delete the new one
@ -470,11 +470,11 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
parse->EventPlayer(EVENT_PLAYER_PICKUP, sender, buf, 0, &args);
// Transfer item to client
sender->PutItemInInventory(SLOT_CURSOR, *m_inst, false);
sender->SendItemPacket(SLOT_CURSOR, m_inst, ItemPacketTrade);
sender->PutItemInInventory(MainCursor, *m_inst, false);
sender->SendItemPacket(MainCursor, m_inst, ItemPacketTrade);
if(cursordelete) // delete the item if it's a duplicate lore. We have to do this because the client expects the item packet
sender->DeleteItemInInventory(SLOT_CURSOR);
sender->DeleteItemInInventory(MainCursor);
if(!m_ground_spawn)
safe_delete(m_inst);

View File

@ -166,7 +166,7 @@ bool Mob::AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* w
}
// If we're attacking with the secondary hand, play the dual wield anim
if (Hand == 14) // DW anim
if (Hand == MainSecondary) // DW anim
type = animDualWield;
DoAnim(type);
@ -202,7 +202,8 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
if (chance_mod >= 10000)
return true;
float bonus;
float avoidanceBonus = 0;
float hitBonus = 0;
////////////////////////////////////////////////////////
// To hit calcs go here
@ -214,6 +215,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
//Calculate the level difference
mlog(COMBAT__TOHIT, "Chance to hit before level diff calc %.2f", chancetohit);
double level_difference = attacker_level - defender_level;
double range = defender->GetLevel();
range = ((range / 4) + 3);
@ -268,37 +270,32 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
mlog(COMBAT__TOHIT, "Applied item melee skill bonus %d, yeilding %.2f", attacker->spellbonuses.MeleeSkillCheck, chancetohit);
}
//subtract off avoidance by the defender. (Live AA - Combat Agility)
bonus = defender->spellbonuses.AvoidMeleeChance + defender->itembonuses.AvoidMeleeChance + (defender->aabonuses.AvoidMeleeChance * 10);
//Avoidance Bonuses on defender decreases baseline hit chance by percent.
avoidanceBonus = defender->spellbonuses.AvoidMeleeChanceEffect +
defender->itembonuses.AvoidMeleeChanceEffect +
defender->aabonuses.AvoidMeleeChanceEffect +
(defender->itembonuses.AvoidMeleeChance / 10.0f); //Item Mod 'Avoidence'
//AA Live - Elemental Agility
if (IsPet()) {
Mob *owner = defender->GetOwner();
if (!owner)return false;
bonus += (owner->aabonuses.PetAvoidance + owner->spellbonuses.PetAvoidance + owner->itembonuses.PetAvoidance)*10;
}
Mob *owner = nullptr;
if (defender->IsPet())
owner = defender->GetOwner();
else if ((defender->IsNPC() && defender->CastToNPC()->GetSwarmOwner()))
owner = entity_list.GetMobID(defender->CastToNPC()->GetSwarmOwner());
if (owner)
avoidanceBonus += owner->aabonuses.PetAvoidance + owner->spellbonuses.PetAvoidance + owner->itembonuses.PetAvoidance;
if(bonus > 0) {
chancetohit -= ((bonus * chancetohit) / 1000);
mlog(COMBAT__TOHIT, "Applied avoidance chance %.2f/10, yeilding %.2f", bonus, chancetohit);
}
if(attacker->IsNPC())
chancetohit += (chancetohit * attacker->CastToNPC()->GetAccuracyRating() / 1000);
mlog(COMBAT__TOHIT, "Chance to hit after accuracy rating calc %.2f", chancetohit);
float hitBonus = 0;
/*
Kayen: Unknown if the HitChance and Accuracy effect's should modify 'chancetohit'
cumulatively or successively. For now all hitBonuses are cumulative.
*/
if(defender->IsNPC())
avoidanceBonus += (defender->CastToNPC()->GetAvoidanceRating() / 10.0f); //Modifier from database
//Hit Chance Bonuses on attacker increases baseline hit chance by percent.
hitBonus += attacker->itembonuses.HitChanceEffect[skillinuse] +
attacker->spellbonuses.HitChanceEffect[skillinuse]+
attacker->aabonuses.HitChanceEffect[skillinuse]+
attacker->itembonuses.HitChanceEffect[HIGHEST_SKILL+1] +
attacker->spellbonuses.HitChanceEffect[HIGHEST_SKILL+1];
attacker->spellbonuses.HitChanceEffect[HIGHEST_SKILL+1] +
attacker->aabonuses.HitChanceEffect[HIGHEST_SKILL+1];
//Accuracy = Spell Effect , HitChance = 'Accuracy' from Item Effect
//Only AA derived accuracy can be skill limited. ie (Precision of the Pathfinder, Dead Aim)
@ -306,26 +303,31 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
attacker->spellbonuses.Accuracy[HIGHEST_SKILL+1] +
attacker->aabonuses.Accuracy[HIGHEST_SKILL+1] +
attacker->aabonuses.Accuracy[skillinuse] +
attacker->itembonuses.HitChance) / 15.0f;
attacker->itembonuses.HitChance) / 15.0f; //Item Mod 'Accuracy'
hitBonus += chance_mod; //Modifier applied from casted/disc skill attacks.
chancetohit += ((chancetohit * hitBonus) / 100.0f);
if(attacker->IsNPC())
hitBonus += (attacker->CastToNPC()->GetAccuracyRating() / 10.0f); //Modifier from database
if(skillinuse == SkillArchery)
chancetohit -= (chancetohit * RuleR(Combat, ArcheryHitPenalty)) / 100.0f;
hitBonus -= hitBonus*(RuleR(Combat, ArcheryHitPenalty)*100.0f);
//Calculate final chance to hit
chancetohit += ((chancetohit * (hitBonus - avoidanceBonus)) / 100.0f);
mlog(COMBAT__TOHIT, "Chance to hit %.2f after accuracy calc %.2f and avoidance calc %.2f", chancetohit, hitBonus, avoidanceBonus);
chancetohit = mod_hit_chance(chancetohit, skillinuse, attacker);
// Chance to hit; Max 95%, Min 30%
// Chance to hit; Max 95%, Min 5% DEFAULTS
if(chancetohit > 1000 || chancetohit < -1000) {
//if chance to hit is crazy high, that means a discipline is in use, and let it stay there
}
else if(chancetohit > 95) {
chancetohit = 95;
else if(chancetohit > RuleR(Combat,MaxChancetoHit)) {
chancetohit = RuleR(Combat,MaxChancetoHit);
}
else if(chancetohit < 5) {
chancetohit = 5;
else if(chancetohit < RuleR(Combat,MinChancetoHit)) {
chancetohit = RuleR(Combat,MinChancetoHit);
}
//I dont know the best way to handle a garunteed hit discipline being used
@ -452,9 +454,9 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
if(damage > 0 && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock)
&& (other->InFrontMob(this, other->GetX(), other->GetY()) || bShieldBlockFromRear)) {
bool equiped2 = CastToClient()->m_inv.GetItem(13);
bool equiped2 = CastToClient()->m_inv.GetItem(MainPrimary);
if(equiped2) {
uint8 TwoHandBlunt = CastToClient()->m_inv.GetItem(13)->GetItem()->ItemType;
uint8 TwoHandBlunt = CastToClient()->m_inv.GetItem(MainPrimary)->GetItem()->ItemType;
float bonusStaffBlock = 0.0f;
if(TwoHandBlunt == ItemType2HBlunt) {
@ -564,15 +566,15 @@ void Mob::MeleeMitigation(Mob *attacker, int32 &damage, int32 minhit, ExtraAttac
if (!IsPet())
armor = (armor / RuleR(Combat, NPCACFactor));
else{
Mob *owner = nullptr;
Mob *owner = nullptr;
if (IsPet())
owner = GetOwner();
if (owner){
PetACBonus = owner->aabonuses.PetMeleeMitigation
+ owner->itembonuses.PetMeleeMitigation +
owner->spellbonuses.PetMeleeMitigation;
}
}
else if ((CastToNPC()->GetSwarmOwner()))
owner = entity_list.GetMobID(CastToNPC()->GetSwarmOwner());
if (owner)
PetACBonus = owner->aabonuses.PetMeleeMitigation + owner->itembonuses.PetMeleeMitigation + owner->spellbonuses.PetMeleeMitigation;
armor += spellbonuses.AC + itembonuses.AC + PetACBonus + 1;
}
@ -713,7 +715,7 @@ void Mob::MeleeMitigation(Mob *attacker, int32 &damage, int32 minhit, ExtraAttac
//reduce the damage from shielding item and aa based on the min dmg
//spells offer pure mitigation
damage -= (minhit * defender->itembonuses.MeleeMitigation / 100);
damage -= (damage * defender->spellbonuses.MeleeMitigation / 100);
damage -= (damage * (defender->spellbonuses.MeleeMitigationEffect + defender->itembonuses.MeleeMitigationEffect + defender->aabonuses.MeleeMitigationEffect) / 100);
}
if (damage < 0)
@ -755,7 +757,7 @@ int32 Mob::GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit,
damage -= ((int)d * interval);
damage -= (minhit * itembonuses.MeleeMitigation / 100);
damage -= (damage * spellbonuses.MeleeMitigation / 100);
damage -= (damage * (spellbonuses.MeleeMitigationEffect + itembonuses.MeleeMitigationEffect + aabonuses.MeleeMitigationEffect) / 100);
return damage;
}
@ -769,7 +771,7 @@ int32 Client::GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit,
// floats for the rounding issues
float dmg_interval = (damage - minhit) / 19.0;
float dmg_bonus = minhit - dmg_interval;
float spellMeleeMit = spellbonuses.MeleeMitigation / 100.0;
float spellMeleeMit = (spellbonuses.MeleeMitigationEffect + itembonuses.MeleeMitigationEffect + aabonuses.MeleeMitigationEffect) / 100.0;
if (GetClass() == WARRIOR)
spellMeleeMit += 0.05;
dmg_bonus -= dmg_bonus * (itembonuses.MeleeMitigation / 100.0);
@ -960,7 +962,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
dmg = weapon_item->GetItem()->Damage;
}
for(int x = 0; x < MAX_AUGMENT_SLOTS; x++){
for(int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; x++){
if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()){
dmg += weapon_item->GetAugment(x)->GetItem()->Damage;
if (hate) *hate += weapon_item->GetAugment(x)->GetItem()->Damage + weapon_item->GetAugment(x)->GetItem()->ElemDmgAmt;
@ -997,7 +999,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
dmg = weapon_item->GetItem()->Damage;
}
for(int x = 0; x < MAX_AUGMENT_SLOTS; x++){
for (int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; x++){
if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()){
dmg += weapon_item->GetAugment(x)->GetItem()->Damage;
if (hate) *hate += weapon_item->GetAugment(x)->GetItem()->Damage + weapon_item->GetAugment(x)->GetItem()->ElemDmgAmt;
@ -1034,7 +1036,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
}
if(weapon_item){
for(int x = 0; x < MAX_AUGMENT_SLOTS; x++){
for (int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; x++){
if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()){
if(weapon_item->GetAugment(x)->GetItem()->ElemDmgAmt)
eledmg += (weapon_item->GetAugment(x)->GetItem()->ElemDmgAmt * against->ResistSpell(weapon_item->GetAugment(x)->GetItem()->ElemDmgType, 0, this) / 100);
@ -1063,7 +1065,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
}
}
for(int x = 0; x < MAX_AUGMENT_SLOTS; x++){
for (int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; x++){
if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()){
if(weapon_item->GetAugment(x)->GetItem()->BaneDmgBody == against->GetBodyType()){
banedmg += weapon_item->GetAugment(x)->GetItem()->BaneDmgAmt;
@ -1108,7 +1110,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
}
}
for(int x = 0; x < MAX_AUGMENT_SLOTS; x++){
for (int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; x++){
if(weapon_item->GetAugment(x) && weapon_item->GetAugment(x)->GetItem()){
if(weapon_item->GetAugment(x)->GetItem()->BaneDmgBody == against->GetBodyType()){
banedmg += weapon_item->GetAugment(x)->GetItem()->BaneDmgAmt;
@ -1170,12 +1172,12 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
ItemInst* weapon;
if (Hand == 14){ // Kaiyodo - Pick weapon from the attacking hand
weapon = GetInv().GetItem(SLOT_SECONDARY);
if (Hand == MainSecondary){ // Kaiyodo - Pick weapon from the attacking hand
weapon = GetInv().GetItem(MainSecondary);
OffHandAtk(true);
}
else{
weapon = GetInv().GetItem(SLOT_PRIMARY);
weapon = GetInv().GetItem(MainPrimary);
OffHandAtk(false);
}
@ -1244,7 +1246,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
int ucDamageBonus = 0;
if( Hand == 13 && GetLevel() >= 28 && IsWarriorClass() )
if( Hand == MainPrimary && GetLevel() >= 28 && IsWarriorClass() )
{
// Damage bonuses apply only to hits from the main hand (Hand == 13) by characters level 28 and above
// who belong to a melee class. If we're here, then all of these conditions apply.
@ -1257,7 +1259,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
}
#endif
//Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon.
if (Hand==14) {
if (Hand == MainSecondary) {
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){
ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const Item_Struct*) nullptr );
@ -1297,11 +1299,9 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
} else { //we hit, try to avoid it
other->AvoidDamage(this, damage);
other->MeleeMitigation(this, damage, min_hit, opts);
if(damage > 0) {
ApplyMeleeDamageBonus(skillinuse, damage);
damage += (itembonuses.HeroicSTR / 10) + (damage * other->GetSkillDmgTaken(skillinuse) / 100) + GetSkillDmgAmt(skillinuse);
TryCriticalHit(other, skillinuse, damage, opts);
}
if(damage > 0)
CommonOutgoingHitSuccess(other, damage, skillinuse);
mlog(COMBAT__DAMAGE, "Final damage after all reductions: %d", damage);
}
@ -1310,7 +1310,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
if (damage == -3) {
if (bRiposte) return false;
else {
if (Hand == 14) {// Do we even have it & was attack with mainhand? If not, don't bother with other calculations
if (Hand == MainSecondary) {// Do we even have it & was attack with mainhand? If not, don't bother with other calculations
//Live AA - SlipperyAttacks
//This spell effect most likely directly modifies the actual riposte chance when using offhand attack.
int16 OffhandRiposteFail = aabonuses.OffhandRiposteFail + itembonuses.OffhandRiposteFail + spellbonuses.OffhandRiposteFail;
@ -1365,39 +1365,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
TrySkillProc(other, skillinuse, 0, true, Hand);
}
//break invis when you attack
if(invisible) {
mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack.");
BuffFadeByEffect(SE_Invisibility);
BuffFadeByEffect(SE_Invisibility2);
invisible = false;
}
if(invisible_undead) {
mlog(COMBAT__ATTACKS, "Removing invisibility vs. undead due to melee attack.");
BuffFadeByEffect(SE_InvisVsUndead);
BuffFadeByEffect(SE_InvisVsUndead2);
invisible_undead = false;
}
if(invisible_animals){
mlog(COMBAT__ATTACKS, "Removing invisibility vs. animals due to melee attack.");
BuffFadeByEffect(SE_InvisVsAnimals);
invisible_animals = false;
}
if (spellbonuses.NegateIfCombat)
BuffFadeByEffect(SE_NegateIfCombat);
if(hidden || improved_hidden){
hidden = false;
improved_hidden = false;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
sa_out->spawn_id = GetID();
sa_out->type = 0x03;
sa_out->parameter = 0;
entity_list.QueueClients(this, outapp, true);
safe_delete(outapp);
}
CommonBreakInvisible();
if(GetTarget())
TriggerDefensiveProcs(weapon, other, Hand, damage);
@ -1775,28 +1743,28 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
FaceTarget(GetTarget());
SkillUseTypes skillinuse = SkillHandtoHand;
if (Hand == 13) {
if (Hand == MainPrimary) {
skillinuse = static_cast<SkillUseTypes>(GetPrimSkill());
OffHandAtk(false);
}
if (Hand == 14) {
if (Hand == MainSecondary) {
skillinuse = static_cast<SkillUseTypes>(GetSecSkill());
OffHandAtk(true);
}
//figure out what weapon they are using, if any
const Item_Struct* weapon = nullptr;
if (Hand == 13 && equipment[SLOT_PRIMARY] > 0)
weapon = database.GetItem(equipment[SLOT_PRIMARY]);
else if (equipment[SLOT_SECONDARY])
weapon = database.GetItem(equipment[SLOT_SECONDARY]);
if (Hand == MainPrimary && equipment[MainPrimary] > 0)
weapon = database.GetItem(equipment[MainPrimary]);
else if (equipment[MainSecondary])
weapon = database.GetItem(equipment[MainSecondary]);
//We dont factor much from the weapon into the attack.
//Just the skill type so it doesn't look silly using punching animations and stuff while wielding weapons
if(weapon) {
mlog(COMBAT__ATTACKS, "Attacking with weapon: %s (%d) (too bad im not using it for much)", weapon->Name, weapon->ID);
if(Hand == 14 && weapon->ItemType == ItemTypeShield){
if(Hand == MainSecondary && weapon->ItemType == ItemTypeShield){
mlog(COMBAT__ATTACKS, "Attack with shield canceled.");
return false;
}
@ -1933,16 +1901,12 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
other->AvoidDamage(this, damage);
other->MeleeMitigation(this, damage, min_dmg+eleBane, opts);
if(damage > 0) {
ApplyMeleeDamageBonus(skillinuse, damage);
damage += (itembonuses.HeroicSTR / 10) + (damage * other->GetSkillDmgTaken(skillinuse) / 100) + GetSkillDmgAmt(skillinuse);
TryCriticalHit(other, skillinuse, damage, opts);
CommonOutgoingHitSuccess(other, damage, skillinuse);
}
mlog(COMBAT__HITS, "Generating hate %d towards %s", hate, GetName());
// now add done damage to the hate list
if(damage > 0)
{
other->AddToHateList(this, hate);
}
else
other->AddToHateList(this, 0);
}
@ -1964,10 +1928,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
return false;
}
int16 DeathHP = 0;
DeathHP = other->GetDelayDeath() * -1;
if(GetHP() > 0 && other->GetHP() >= DeathHP) {
if(GetHP() > 0 && !other->HasDied()) {
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse, false); // Not avoidable client already had thier chance to Avoid
} else
return false;
@ -1977,59 +1938,24 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
MeleeLifeTap(damage);
if (damage > 0)
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
//break invis when you attack
if(invisible) {
mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack.");
BuffFadeByEffect(SE_Invisibility);
BuffFadeByEffect(SE_Invisibility2);
invisible = false;
}
if(invisible_undead) {
mlog(COMBAT__ATTACKS, "Removing invisibility vs. undead due to melee attack.");
BuffFadeByEffect(SE_InvisVsUndead);
BuffFadeByEffect(SE_InvisVsUndead2);
invisible_undead = false;
}
if(invisible_animals){
mlog(COMBAT__ATTACKS, "Removing invisibility vs. animals due to melee attack.");
BuffFadeByEffect(SE_InvisVsAnimals);
invisible_animals = false;
}
if (spellbonuses.NegateIfCombat)
BuffFadeByEffect(SE_NegateIfCombat);
if(hidden || improved_hidden)
{
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
sa_out->spawn_id = GetID();
sa_out->type = 0x03;
sa_out->parameter = 0;
entity_list.QueueClients(this, outapp, true);
safe_delete(outapp);
}
hidden = false;
improved_hidden = false;
CommonBreakInvisible();
//I doubt this works...
if (!GetTarget())
return true; //We killed them
if(!bRiposte && other && other->GetHP() > 0) {
if(!bRiposte && !other->HasDied()) {
TryWeaponProc(nullptr, weapon, other, Hand); //no weapon
TrySpellProc(nullptr, weapon, other, Hand);
if (damage > 0 && HasSkillProcSuccess())
if (!other->HasDied())
TrySpellProc(nullptr, weapon, other, Hand);
if (damage > 0 && HasSkillProcSuccess() && !other->HasDied())
TrySkillProc(other, skillinuse, 0, true, Hand);
}
TriggerDefensiveProcs(nullptr, other, Hand, damage);
if(GetHP() > 0 && !other->HasDied())
TriggerDefensiveProcs(nullptr, other, Hand, damage);
// now check ripostes
if (damage == -3) { // riposting
@ -3923,12 +3849,12 @@ void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id)
}
//proc chance includes proc bonus
float Mob::GetProcChances(float ProcBonus, uint16 weapon_speed, uint16 hand)
float Mob::GetProcChances(float ProcBonus, uint16 hand)
{
int mydex = GetDEX();
float ProcChance = 0.0f;
weapon_speed = GetWeaponSpeedbyHand(hand);
uint16 weapon_speed = GetWeaponSpeedbyHand(hand);
if (RuleB(Combat, AdjustProcPerMinute)) {
ProcChance = (static_cast<float>(weapon_speed) *
@ -3945,12 +3871,16 @@ float Mob::GetProcChances(float ProcBonus, uint16 weapon_speed, uint16 hand)
return ProcChance;
}
float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_speed, uint16 hand) {
int myagi = GetAGI();
float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand, Mob* on) {
if (!on)
return ProcChance;
int myagi = on->GetAGI();
ProcBonus = 0;
ProcChance = 0;
weapon_speed = GetWeaponSpeedbyHand(hand);
uint16 weapon_speed = GetWeaponSpeedbyHand(hand);
ProcChance = (static_cast<float>(weapon_speed) * RuleR(Combat, AvgDefProcsPerMinute) / 60000.0f); // compensate for weapon_speed being in ms
ProcBonus += static_cast<float>(myagi) * RuleR(Combat, DefProcPerMinAgiContrib) / 100.0f;
@ -3960,7 +3890,7 @@ float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 w
return ProcChance;
}
void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand, int damage) {
void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
if (!on) {
SetTarget(nullptr);
@ -3974,10 +3904,8 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand, int dam
return;
float ProcChance, ProcBonus;
if(weapon!=nullptr)
on->GetDefensiveProcChances(ProcBonus, ProcChance, weapon->GetItem()->Delay, hand);
else
on->GetDefensiveProcChances(ProcBonus, ProcChance);
on->GetDefensiveProcChances(ProcBonus, ProcChance, hand , this);
if(hand != 13)
ProcChance /= 2;
@ -4035,7 +3963,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on
float ProcBonus = static_cast<float>(aabonuses.ProcChanceSPA +
spellbonuses.ProcChanceSPA + itembonuses.ProcChanceSPA);
ProcBonus += static_cast<float>(itembonuses.ProcChance) / 10.0f; // Combat Effects
float ProcChance = GetProcChances(ProcBonus, weapon->Delay, hand);
float ProcChance = GetProcChances(ProcBonus, hand);
if (hand != 13) //Is Archery intened to proc at 50% rate?
ProcChance /= 2;
@ -4074,7 +4002,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on
proced = false;
if (!proced && inst) {
for (int r = 0; r < MAX_AUGMENT_SLOTS; r++) {
for (int r = 0; r < EmuConstants::ITEM_COMMON_SIZE; r++) {
const ItemInst *aug_i = inst->GetAugment(r);
if (!aug_i) // no aug, try next slot!
continue;
@ -4113,16 +4041,13 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
float ProcBonus = static_cast<float>(spellbonuses.SpellProcChance +
itembonuses.SpellProcChance + aabonuses.SpellProcChance);
float ProcChance = 0.0f;
if (weapon)
ProcChance = GetProcChances(ProcBonus, weapon->Delay, hand);
else
ProcChance = GetProcChances(ProcBonus);
ProcChance = GetProcChances(ProcBonus, hand);
if (hand != 13) //Is Archery intened to proc at 50% rate?
if (hand != MainPrimary) //Is Archery intened to proc at 50% rate?
ProcChance /= 2;
bool rangedattk = false;
if (weapon && hand == 11) {
if (weapon && hand == MainRange) {
if (weapon->ItemType == ItemTypeArrow ||
weapon->ItemType == ItemTypeLargeThrowing ||
weapon->ItemType == ItemTypeSmallThrowing ||
@ -4130,8 +4055,11 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
rangedattk = true;
}
if (!weapon && hand == MainRange && GetSpecialAbility(SPECATK_RANGED_ATK))
rangedattk = true;
for (uint32 i = 0; i < MAX_PROCS; i++) {
if (IsPet() && hand != 13) //Pets can only proc spell procs from their primay hand (ie; beastlord pets)
if (IsPet() && hand != MainPrimary) //Pets can only proc spell procs from their primay hand (ie; beastlord pets)
continue; // If pets ever can proc from off hand, this will need to change
// Not ranged
@ -4152,7 +4080,7 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
// Spell procs (buffs)
if (SpellProcs[i].spellID != SPELL_UNKNOWN) {
float chance = ProcChance * (SpellProcs[i].chance / 100.0f);
float chance = ProcChance * (static_cast<float>(SpellProcs[i].chance) / 100.0f);
if (MakeRandomFloat(0, 1) <= chance) {
mlog(COMBAT__PROCS,
"Spell proc %d procing spell %d (%.2f percent chance)",
@ -4168,8 +4096,8 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
} else if (rangedattk) { // ranged only
// ranged spell procs (buffs)
if (RangedProcs[i].spellID != SPELL_UNKNOWN) {
float chance = ProcChance * (RangedProcs[i].chance / 100.0f);
if (MakeRandomFloat(0, 1) <= chance) {
float chance = ProcChance * (static_cast<float>(RangedProcs[i].chance) / 100.0f);
if (MakeRandomFloat(0, 1) <= chance) {
mlog(COMBAT__PROCS,
"Ranged proc %d procing spell %d (%.2f percent chance)",
i, RangedProcs[i].spellID, chance);
@ -4184,7 +4112,7 @@ void Mob::TrySpellProc(const ItemInst *inst, const Item_Struct *weapon, Mob *on,
}
}
if (HasSkillProcs() && hand != 11){ //We check ranged skill procs within the attack functions.
if (HasSkillProcs() && hand != MainRange){ //We check ranged skill procs within the attack functions.
uint16 skillinuse = 28;
if (weapon)
skillinuse = GetSkillByItemType(weapon->ItemType);
@ -4430,7 +4358,7 @@ void Mob::DoRiposte(Mob* defender) {
if (!defender)
return;
defender->Attack(this, SLOT_PRIMARY, true);
defender->Attack(this, MainPrimary, true);
if (HasDied()) return;
int16 DoubleRipChance = defender->aabonuses.GiveDoubleRiposte[0] +
@ -4444,7 +4372,7 @@ void Mob::DoRiposte(Mob* defender) {
//Live AA - Double Riposte
if(DoubleRipChance && (DoubleRipChance >= MakeRandomInt(0, 100))) {
mlog(COMBAT__ATTACKS, "Preforming a double riposed (%d percent chance)", DoubleRipChance);
defender->Attack(this, SLOT_PRIMARY, true);
defender->Attack(this, MainPrimary, true);
if (HasDied()) return;
}
@ -4820,3 +4748,56 @@ int32 Mob::RuneAbsorb(int32 damage, uint16 type)
return damage;
}
void Mob::CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes skillInUse)
{
if (!defender)
return;
ApplyMeleeDamageBonus(skillInUse, damage);
damage += (damage * defender->GetSkillDmgTaken(skillInUse) / 100) + (GetSkillDmgAmt(skillInUse) + defender->GetFcDamageAmtIncoming(this, 0, true, skillInUse));
TryCriticalHit(defender, skillInUse, damage);
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
}
void Mob::CommonBreakInvisible()
{
//break invis when you attack
if(invisible) {
mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack.");
BuffFadeByEffect(SE_Invisibility);
BuffFadeByEffect(SE_Invisibility2);
invisible = false;
}
if(invisible_undead) {
mlog(COMBAT__ATTACKS, "Removing invisibility vs. undead due to melee attack.");
BuffFadeByEffect(SE_InvisVsUndead);
BuffFadeByEffect(SE_InvisVsUndead2);
invisible_undead = false;
}
if(invisible_animals){
mlog(COMBAT__ATTACKS, "Removing invisibility vs. animals due to melee attack.");
BuffFadeByEffect(SE_InvisVsAnimals);
invisible_animals = false;
}
if (spellbonuses.NegateIfCombat)
BuffFadeByEffect(SE_NegateIfCombat);
if(hidden || improved_hidden){
hidden = false;
improved_hidden = false;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
sa_out->spawn_id = GetID();
sa_out->type = 0x03;
sa_out->parameter = 0;
entity_list.QueueClients(this, outapp, true);
safe_delete(outapp);
}
if (spellbonuses.NegateIfCombat)
BuffFadeByEffect(SE_NegateIfCombat);
hidden = false;
improved_hidden = false;
}

View File

@ -33,7 +33,7 @@ public:
//abstract virtual function implementations requird by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; }
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; }
virtual bool Attack(Mob* other, int Hand = 13, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
ExtraAttackOptions *opts = nullptr) { return false; }
virtual bool HasRaid() { return false; }
virtual bool HasGroup() { return false; }

View File

@ -139,28 +139,28 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
unsigned int i;
//should not include 21 (SLOT_AMMO)
for (i=0; i<21; i++) {
for (i = MainCharm; i < MainAmmo; i++) {
const ItemInst* inst = m_inv[i];
if(inst == 0)
continue;
AddItemBonuses(inst, newbon);
//Check if item is secondary slot is a 'shield'. Required for multiple spelll effects.
if (i == 14 && (m_inv.GetItem(14)->GetItem()->ItemType == ItemTypeShield))
if (i == MainSecondary && (m_inv.GetItem(MainSecondary)->GetItem()->ItemType == ItemTypeShield))
ShieldEquiped(true);
}
//Power Source Slot
if (GetClientVersion() >= EQClientSoF)
{
const ItemInst* inst = m_inv[9999];
const ItemInst* inst = m_inv[MainPowerSource];
if(inst)
AddItemBonuses(inst, newbon);
}
//tribute items
for (i = 0; i < MAX_PLAYER_TRIBUTES; i++) {
const ItemInst* inst = m_inv[TRIBUTE_SLOT_START + i];
for (i = 0; i < EmuConstants::TRIBUTE_SIZE; i++) {
const ItemInst* inst = m_inv[EmuConstants::TRIBUTE_BEGIN + i];
if(inst == 0)
continue;
AddItemBonuses(inst, newbon, false, true);
@ -528,7 +528,7 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAu
if (!isAug)
{
int i;
for(i = 0; i < MAX_AUGMENT_SLOTS; i++) {
for (i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
AddItemBonuses(inst->GetAugment(i),newbon,true);
}
}
@ -544,7 +544,7 @@ void Client::CalcEdibleBonuses(StatBonuses* newbon) {
bool food = false;
bool drink = false;
for (i = 22; i <= 29; i++)
for (i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_BAGS_BEGIN; i++)
{
if (food && drink)
break;
@ -560,7 +560,7 @@ void Client::CalcEdibleBonuses(StatBonuses* newbon) {
AddItemBonuses(inst, newbon);
}
}
for (i = 251; i <= 330; i++)
for (i = EmuConstants::GENERAL_BAGS_BEGIN; i <= EmuConstants::GENERAL_BAGS_END; i++)
{
if (food && drink)
break;
@ -879,7 +879,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
newbon->PetMaxHP += base1;
break;
case SE_AvoidMeleeChance:
newbon->AvoidMeleeChance += base1;
newbon->AvoidMeleeChanceEffect += base1;
break;
case SE_CombatStability:
newbon->CombatStability += base1;
@ -974,7 +974,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
newbon->FlurryChance += base1;
break;
case SE_PetFlurry:
newbon->PetFlurry = base1;
newbon->PetFlurry += base1;
break;
case SE_BardSongRange:
newbon->SongRange += base1;
@ -989,6 +989,14 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
newbon->CrippBlowChance += base1;
break;
case SE_HitChance:
{
if(base2 == -1)
newbon->HitChanceEffect[HIGHEST_SKILL+1] += base1;
else
newbon->HitChanceEffect[base2] += base1;
}
case SE_ProcOnKillShot:
for(int i = 0; i < MAX_SPELL_TRIGGER*3; i+=3)
{
@ -1368,6 +1376,10 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
break;
}
case SE_MeleeMitigation:
newbon->MeleeMitigationEffect -= base1;
break;
}
}
}
@ -1788,7 +1800,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_MeleeMitigation:
//for some reason... this value is negative for increased mitigation
newbon->MeleeMitigation -= effect_value;
newbon->MeleeMitigationEffect -= effect_value;
break;
case SE_CriticalHitChance:
@ -1833,16 +1845,14 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_AvoidMeleeChance:
{
//multiplier is to be compatible with item effects, watching for overflow too
effect_value = effect_value<3000? effect_value * 10 : 30000;
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
newbon->AvoidMeleeChance += effect_value;
newbon->AvoidMeleeChanceEffect += effect_value;
else if((effect_value < 0) && (newbon->AvoidMeleeChance > effect_value))
newbon->AvoidMeleeChance = effect_value;
else if((effect_value < 0) && (newbon->AvoidMeleeChanceEffect > effect_value))
newbon->AvoidMeleeChanceEffect = effect_value;
else if(newbon->AvoidMeleeChance < effect_value)
newbon->AvoidMeleeChance = effect_value;
else if(newbon->AvoidMeleeChanceEffect < effect_value)
newbon->AvoidMeleeChanceEffect = effect_value;
break;
}
@ -2972,7 +2982,7 @@ void NPC::CalcItemBonuses(StatBonuses *newbon)
{
if(newbon){
for(int i = 0; i < MAX_WORN_INVENTORY; i++){
for(int i = 0; i < EmuConstants::EQUIPMENT_SIZE; i++){
const Item_Struct *cur = database.GetItem(equipment[i]);
if(cur){
//basic stats
@ -3091,7 +3101,7 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y)
}
//iterate all augments
for(int x = 0; x < MAX_AUGMENT_SLOTS; ++x)
for (int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; ++x)
{
ItemInst * a_inst = inst->GetAugment(x);
if(!a_inst)
@ -3160,7 +3170,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
uint16 oldexp = inst->GetExp();
parse->EventItem(EVENT_ITEM_ENTER_ZONE, this, inst, nullptr, "", 0);
if(i < 22 || i == 9999) {
if(i <= MainAmmo || i == MainPowerSource) {
parse->EventItem(EVENT_EQUIP_ITEM, this, inst, nullptr, "", i);
}
@ -3170,7 +3180,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
update_slot = true;
}
} else {
if(i < 22 || i == 9999) {
if(i <= MainAmmo || i == MainPowerSource) {
parse->EventItem(EVENT_EQUIP_ITEM, this, inst, nullptr, "", i);
}
@ -3178,7 +3188,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
}
//iterate all augments
for(int x = 0; x < MAX_AUGMENT_SLOTS; ++x)
for (int x = 0; x < EmuConstants::ITEM_COMMON_SIZE; ++x)
{
ItemInst *a_inst = inst->GetAugment(x);
if(!a_inst)
@ -3588,9 +3598,9 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
break;
case SE_MeleeMitigation:
spellbonuses.MeleeMitigation = effect_value;
itembonuses.MeleeMitigation = effect_value;
aabonuses.MeleeMitigation = effect_value;
spellbonuses.MeleeMitigationEffect = effect_value;
itembonuses.MeleeMitigationEffect = effect_value;
aabonuses.MeleeMitigationEffect = effect_value;
break;
case SE_CriticalHitChance:
@ -3610,9 +3620,9 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
break;
case SE_AvoidMeleeChance:
spellbonuses.AvoidMeleeChance = effect_value;
aabonuses.AvoidMeleeChance = effect_value;
itembonuses.AvoidMeleeChance = effect_value;
spellbonuses.AvoidMeleeChanceEffect = effect_value;
aabonuses.AvoidMeleeChanceEffect = effect_value;
itembonuses.AvoidMeleeChanceEffect = effect_value;
break;
case SE_RiposteChance:

View File

@ -237,7 +237,7 @@ void Bot::SetBotSpellID(uint32 newSpellID) {
uint32 Bot::GetBotArcheryRange() {
uint32 result = 0;
ItemInst* rangeItem = GetBotItem(SLOT_RANGE);
ItemInst* rangeItem = GetBotItem(MainRange);
if(!rangeItem)
return 0;
@ -257,7 +257,7 @@ uint32 Bot::GetBotArcheryRange() {
archeryColor = botweapon->Color;
range =+ botweapon->Range;
rangeItem = GetBotItem(SLOT_AMMO);
rangeItem = GetBotItem(MainAmmo);
if(rangeItem)
botweapon = rangeItem->GetItem();
@ -280,8 +280,8 @@ void Bot::ChangeBotArcherWeapons(bool isArcher) {
|| (GetClass()==SHADOWKNIGHT) || (GetClass()==ROGUE))
{
if(!isArcher) {
BotAddEquipItem(SLOT_PRIMARY, GetBotItemBySlot(SLOT_PRIMARY));
BotAddEquipItem(SLOT_SECONDARY, GetBotItemBySlot(SLOT_SECONDARY));
BotAddEquipItem(MainPrimary, GetBotItemBySlot(MainPrimary));
BotAddEquipItem(MainSecondary, GetBotItemBySlot(MainSecondary));
//archerbot->SendWearChange(MATERIAL_PRIMARY);
//archerbot->SendWearChange(MATERIAL_SECONDARY);
SetAttackTimer();
@ -290,11 +290,11 @@ void Bot::ChangeBotArcherWeapons(bool isArcher) {
else {
//archerbot->SendWearChange(MATERIAL_PRIMARY);
//archerbot->SendWearChange(MATERIAL_SECONDARY);
BotRemoveEquipItem(SLOT_PRIMARY);
BotRemoveEquipItem(SLOT_SECONDARY);
BotRemoveEquipItem(MainPrimary);
BotRemoveEquipItem(MainSecondary);
//archerbot->SendBotArcheryWearChange(MATERIAL_PRIMARY, archeryMaterial, archeryColor);
BotAddEquipItem(SLOT_AMMO, GetBotItemBySlot(SLOT_AMMO));
BotAddEquipItem(SLOT_SECONDARY, GetBotItemBySlot(SLOT_RANGE));
BotAddEquipItem(MainAmmo, GetBotItemBySlot(MainAmmo));
BotAddEquipItem(MainSecondary, GetBotItemBySlot(MainRange));
SetAttackTimer();
Say("My bow is true and ready.");
}
@ -1291,7 +1291,7 @@ void Bot::GenerateArmorClass()
uint16 Bot::GetPrimarySkillValue()
{
SkillUseTypes skill = HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill
bool equiped = m_inv.GetItem(SLOT_PRIMARY);
bool equiped = m_inv.GetItem(MainPrimary);
if(!equiped)
{
@ -1299,7 +1299,7 @@ uint16 Bot::GetPrimarySkillValue()
}
else
{
uint8 type = m_inv.GetItem(SLOT_PRIMARY)->GetItem()->ItemType; //is this the best way to do this?
uint8 type = m_inv.GetItem(MainPrimary)->GetItem()->ItemType; //is this the best way to do this?
switch(type)
{
case ItemType1HSlash: // 1H Slashing
@ -2630,7 +2630,7 @@ void Bot::LoadPet() {
NPC *pet = GetPet()->CastToNPC();
SpellBuff_Struct petBuffs[BUFF_COUNT];
memset(petBuffs, 0, sizeof(petBuffs));
uint32 petItems[MAX_WORN_INVENTORY];
uint32 petItems[EmuConstants::EQUIPMENT_SIZE];
LoadPetBuffs(petBuffs, PetSaveId);
LoadPetItems(petItems, PetSaveId);
@ -2747,7 +2747,7 @@ void Bot::LoadPetItems(uint32* petItems, uint32 botPetSaveId) {
int ItemCount = 0;
while(DataRow = mysql_fetch_row(DatasetResult)) {
if(ItemCount == MAX_WORN_INVENTORY)
if(ItemCount == EmuConstants::EQUIPMENT_SIZE)
break;
petItems[ItemCount] = atoi(DataRow[0]);
@ -2785,7 +2785,7 @@ void Bot::SavePet() {
uint32 botPetId = pet->CastToNPC()->GetPetSpellID();
char* tempPetName = new char[64];
SpellBuff_Struct petBuffs[BUFF_COUNT];
uint32 petItems[MAX_WORN_INVENTORY];
uint32 petItems[EmuConstants::EQUIPMENT_SIZE];
pet->GetPetState(petBuffs, petItems, tempPetName);
@ -2867,7 +2867,7 @@ void Bot::SavePetItems(uint32* petItems, uint32 botPetSaveId) {
char TempErrorMessageBuffer[MYSQL_ERRMSG_SIZE];
int ItemCount = 0;
while(ItemCount < MAX_WORN_INVENTORY) {
while (ItemCount < EmuConstants::EQUIPMENT_SIZE) {
if(petItems[ItemCount] > 0) {
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "INSERT INTO botpetinventory (BotPetsId, ItemId) VALUES(%u, %u);", botPetSaveId, petItems[ItemCount]), TempErrorMessageBuffer)) {
errorMessage = std::string(TempErrorMessageBuffer);
@ -3189,12 +3189,12 @@ void Bot::BotRangedAttack(Mob* other) {
return;
}
ItemInst* rangedItem = GetBotItem(SLOT_RANGE);
ItemInst* rangedItem = GetBotItem(MainRange);
const Item_Struct* RangeWeapon = 0;
if(rangedItem)
RangeWeapon = rangedItem->GetItem();
ItemInst* ammoItem = GetBotItem(SLOT_AMMO);
ItemInst* ammoItem = GetBotItem(MainAmmo);
const Item_Struct* Ammo = 0;
if(ammoItem)
Ammo = ammoItem->GetItem();
@ -3304,7 +3304,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
int damage = 0;
uint32 hate = 0;
int Hand = 13;
int Hand = MainPrimary;
if (hate == 0 && weapon_damage > 1) hate = weapon_damage;
if(weapon_damage > 0){
@ -3363,7 +3363,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
damage = -5;
if(skillinuse == SkillBash){
const ItemInst* inst = GetBotItem(SLOT_SECONDARY);
const ItemInst* inst = GetBotItem(MainSecondary);
const Item_Struct* botweapon = 0;
if(inst)
botweapon = inst->GetItem();
@ -3413,17 +3413,17 @@ void Bot::ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg)
case SkillFlyingKick:
case SkillRoundKick:
case SkillKick:
item_slot = SLOT_FEET;
item_slot = MainFeet;
break;
case SkillBash:
item_slot = SLOT_SECONDARY;
item_slot = MainSecondary;
break;
case SkillDragonPunch:
case SkillEagleStrike:
case SkillTigerClaw:
item_slot = SLOT_HANDS;
item_slot = MainHands;
break;
}
@ -3775,27 +3775,27 @@ void Bot::AI_Process() {
//try main hand first
if(attack_timer.Check()) {
Attack(GetTarget(), SLOT_PRIMARY);
Attack(GetTarget(), MainPrimary);
ItemInst *wpn = GetBotItem(SLOT_PRIMARY);
TryWeaponProc(wpn, GetTarget(), SLOT_PRIMARY);
ItemInst *wpn = GetBotItem(MainPrimary);
TryWeaponProc(wpn, GetTarget(), MainPrimary);
bool tripleSuccess = false;
if(BotOwner && GetTarget() && CanThisClassDoubleAttack()) {
if(BotOwner && CheckBotDoubleAttack()) {
Attack(GetTarget(), SLOT_PRIMARY, true);
Attack(GetTarget(), MainPrimary, true);
}
if(BotOwner && GetTarget() && GetSpecialAbility(SPECATK_TRIPLE) && CheckBotDoubleAttack(true)) {
tripleSuccess = true;
Attack(GetTarget(), SLOT_PRIMARY, true);
Attack(GetTarget(), MainPrimary, true);
}
//quad attack, does this belong here??
if(BotOwner && GetTarget() && GetSpecialAbility(SPECATK_QUAD) && CheckBotDoubleAttack(true)) {
Attack(GetTarget(), SLOT_PRIMARY, true);
Attack(GetTarget(), MainPrimary, true);
}
}
@ -3807,15 +3807,15 @@ void Bot::AI_Process() {
if(MakeRandomInt(0, 100) < flurrychance)
{
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
Attack(GetTarget(), SLOT_PRIMARY, false);
Attack(GetTarget(), SLOT_PRIMARY, false);
Attack(GetTarget(), MainPrimary, false);
Attack(GetTarget(), MainPrimary, false);
}
}
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance;
if (GetTarget() && ExtraAttackChanceBonus) {
ItemInst *wpn = GetBotItem(SLOT_PRIMARY);
ItemInst *wpn = GetBotItem(MainPrimary);
if(wpn){
if(wpn->GetItem()->ItemType == ItemType2HSlash ||
wpn->GetItem()->ItemType == ItemType2HBlunt ||
@ -3823,7 +3823,7 @@ void Bot::AI_Process() {
{
if(MakeRandomInt(0, 100) < ExtraAttackChanceBonus)
{
Attack(GetTarget(), SLOT_PRIMARY, false);
Attack(GetTarget(), MainPrimary, false);
}
}
}
@ -3843,7 +3843,7 @@ void Bot::AI_Process() {
//now off hand
if(GetTarget() && attack_dw_timer.Check() && CanThisClassDualWield()) {
const ItemInst* instweapon = GetBotItem(SLOT_SECONDARY);
const ItemInst* instweapon = GetBotItem(MainSecondary);
const Item_Struct* weapon = 0;
//can only dual wield without a weapon if you're a monk
if(instweapon || (botClass == MONK)) {
@ -3870,14 +3870,14 @@ void Bot::AI_Process() {
if (random < DualWieldProbability){ // Max 78% of DW
Attack(GetTarget(), SLOT_SECONDARY); // Single attack with offhand
Attack(GetTarget(), MainSecondary); // Single attack with offhand
ItemInst *wpn = GetBotItem(SLOT_SECONDARY);
TryWeaponProc(wpn, GetTarget(), SLOT_SECONDARY);
ItemInst *wpn = GetBotItem(MainSecondary);
TryWeaponProc(wpn, GetTarget(), MainSecondary);
if( CanThisClassDoubleAttack() && CheckBotDoubleAttack()) {
if(GetTarget() && GetTarget()->GetHP() > -10)
Attack(GetTarget(), SLOT_SECONDARY); // Single attack with offhand
Attack(GetTarget(), MainSecondary); // Single attack with offhand
}
}
}
@ -4096,14 +4096,14 @@ void Bot::PetAIProcess() {
if(!botPet->BehindMob(botPet->GetTarget(), botPet->GetX(), botPet->GetY()) && botPet->GetTarget()->IsEnraged())
return;
if(botPet->Attack(GetTarget(), SLOT_PRIMARY)) // try the main hand
if(botPet->Attack(GetTarget(), MainPrimary)) // try the main hand
if (botPet->GetTarget()) // Do we still have a target?
{
// We're a pet so we re able to dual attack
int32 RandRoll = MakeRandomInt(0, 99);
if (botPet->CanThisClassDoubleAttack() && (RandRoll < (botPet->GetLevel() + NPCDualAttackModifier)))
{
if(botPet->Attack(botPet->GetTarget(), 13))
if(botPet->Attack(botPet->GetTarget(), MainPrimary))
{}
}
}
@ -4145,13 +4145,13 @@ void Bot::PetAIProcess() {
float DualWieldProbability = (botPet->GetSkill(SkillDualWield) + botPet->GetLevel()) / 400.0f;
DualWieldProbability -= MakeRandomFloat(0, 1);
if(DualWieldProbability < 0){
botPet->Attack(botPet->GetTarget(), 14);
botPet->Attack(botPet->GetTarget(), MainSecondary);
if (botPet->CanThisClassDoubleAttack())
{
int32 RandRoll = MakeRandomInt(0, 99);
if (RandRoll < (botPet->GetLevel() + 20))
{
botPet->Attack(botPet->GetTarget(), 14);
botPet->Attack(botPet->GetTarget(), MainSecondary);
}
}
}
@ -4411,7 +4411,7 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
ItemInst* inst = database.CreateItem(item_id, charges, aug[0], aug[1], aug[2], aug[3], aug[4]);
if(inst) {
int16 put_slot_id = SLOT_INVALID;
int16 put_slot_id = INVALID_INDEX;
if(instnodrop || ((slot_id >= 0) && (slot_id <= 21) && inst->GetItem()->Attuneable))
inst->SetInstNoDrop(true);
if(color > 0)
@ -4429,7 +4429,7 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
safe_delete(inst);
// Save ptr to item in inventory
if (put_slot_id == SLOT_INVALID) {
if (put_slot_id == INVALID_INDEX) {
LogFile->write(EQEMuLog::Error,
"Warning: Invalid slot_id for item in inventory: botid=%i, item_id=%i, slot_id=%i",
this->GetBotID(), item_id, slot_id);
@ -4595,7 +4595,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
uint32 spawnedbotid = 0;
spawnedbotid = this->GetBotID();
inst = GetBotItem(SLOT_HANDS);
inst = GetBotItem(MainHands);
if(inst) {
item = inst->GetItem();
if(item) {
@ -4604,7 +4604,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
}
}
inst = GetBotItem(SLOT_HEAD);
inst = GetBotItem(MainHead);
if(inst) {
item = inst->GetItem();
if(item) {
@ -4613,7 +4613,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
}
}
inst = GetBotItem(SLOT_ARMS);
inst = GetBotItem(MainArms);
if(inst) {
item = inst->GetItem();
if(item) {
@ -4622,7 +4622,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
}
}
inst = GetBotItem(SLOT_BRACER01);
inst = GetBotItem(MainWrist1);
if(inst) {
item = inst->GetItem();
if(item) {
@ -4631,7 +4631,9 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
}
}
inst = GetBotItem(SLOT_BRACER02);
/*
// non-live behavior
inst = GetBotItem(MainWrist2);
if(inst) {
item = inst->GetItem();
if(item) {
@ -4639,8 +4641,9 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
ns->spawn.colors[MaterialWrist].color = GetEquipmentColor(MaterialWrist);
}
}
*/
inst = GetBotItem(SLOT_CHEST);
inst = GetBotItem(MainChest);
if(inst) {
item = inst->GetItem();
if(item) {
@ -4649,7 +4652,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
}
}
inst = GetBotItem(SLOT_LEGS);
inst = GetBotItem(MainLegs);
if(inst) {
item = inst->GetItem();
if(item) {
@ -4658,7 +4661,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
}
}
inst = GetBotItem(SLOT_FEET);
inst = GetBotItem(MainFeet);
if(inst) {
item = inst->GetItem();
if(item) {
@ -4667,7 +4670,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
}
}
inst = GetBotItem(SLOT_PRIMARY);
inst = GetBotItem(MainPrimary);
if(inst) {
item = inst->GetItem();
if(item) {
@ -4677,7 +4680,7 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
}
}
inst = GetBotItem(SLOT_SECONDARY);
inst = GetBotItem(MainSecondary);
if(inst) {
item = inst->GetItem();
if(item) {
@ -6009,7 +6012,7 @@ void Bot::FinishTrade(Client* client, BotTradeType tradeType) {
else if(tradeType == BotTradeClientNoDropNoTrade) {
// Items being traded are found on the Client's cursor slot, slot id 30. This item can be either a single item or it can be a bag.
// If it is a bag, then we have to search for items in slots 331 thru 340
PerformTradeWithClient(SLOT_CURSOR, SLOT_CURSOR, client);
PerformTradeWithClient(MainCursor, MainCursor, client);
// TODO: Add logic here to test if the item in SLOT_CURSOR is a container type, if it is then we need to call the following:
// PerformTradeWithClient(331, 340, client);
@ -6038,7 +6041,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
charges[i] = inst->GetCharges();
}
if(i == SLOT_CURSOR)
if (i == MainCursor)
UpdateClient = true;
//EQoffline: will give the items to the bots and change the bot stats
@ -6046,7 +6049,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
std::string TempErrorMessage;
const Item_Struct* mWeaponItem = inst->GetItem();
bool failedLoreCheck = false;
for(int m=0; m<MAX_AUGMENT_SLOTS; ++m) {
for (int m = 0; m<EmuConstants::ITEM_COMMON_SIZE; ++m) {
ItemInst *itm = inst->GetAugment(m);
if(itm)
{
@ -6075,17 +6078,17 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
if((mWeaponItem->Slots & (1 << j))) {
how_many_slots++;
if(!GetBotItem(j)) {
if(j == SLOT_PRIMARY) {
if(j == MainPrimary) {
if((mWeaponItem->ItemType == ItemType2HSlash) || (mWeaponItem->ItemType == ItemType2HBlunt) || (mWeaponItem->ItemType == ItemType2HPiercing)) {
if(GetBotItem(SLOT_SECONDARY)) {
if(GetBotItem(MainSecondary)) {
if(mWeaponItem && (mWeaponItem->ItemType == ItemType2HSlash) || (mWeaponItem->ItemType == ItemType2HBlunt) || (mWeaponItem->ItemType == ItemType2HPiercing)) {
if(client->CheckLoreConflict(GetBotItem(SLOT_SECONDARY)->GetItem())) {
if(client->CheckLoreConflict(GetBotItem(MainSecondary)->GetItem())) {
failedLoreCheck = true;
}
}
else {
ItemInst* remove_item = GetBotItem(SLOT_SECONDARY);
BotTradeSwapItem(client, SLOT_SECONDARY, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
ItemInst* remove_item = GetBotItem(MainSecondary);
BotTradeSwapItem(client, MainSecondary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
}
}
}
@ -6095,7 +6098,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
}
break;
}
else if(j == SLOT_SECONDARY) {
else if(j == MainSecondary) {
if(inst->IsWeapon()) {
if(CanThisClassDualWield()) {
BotTradeAddItem(mWeaponItem->ID, inst, inst->GetCharges(), mWeaponItem->Slots, j, &TempErrorMessage);
@ -6111,10 +6114,10 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
success = true;
}
if(success) {
if(GetBotItem(SLOT_PRIMARY)) {
ItemInst* remove_item = GetBotItem(SLOT_PRIMARY);
if(GetBotItem(MainPrimary)) {
ItemInst* remove_item = GetBotItem(MainPrimary);
if((remove_item->GetItem()->ItemType == ItemType2HSlash) || (remove_item->GetItem()->ItemType == ItemType2HBlunt) || (remove_item->GetItem()->ItemType == ItemType2HPiercing)) {
BotTradeSwapItem(client, SLOT_PRIMARY, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
BotTradeSwapItem(client, MainPrimary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
}
}
break;
@ -6133,7 +6136,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
if((mWeaponItem->Slots & (1 << j))) {
swap_item = GetBotItem(j);
failedLoreCheck = false;
for(int k=0; k<MAX_AUGMENT_SLOTS; ++k) {
for (int k = 0; k<EmuConstants::ITEM_COMMON_SIZE; ++k) {
ItemInst *itm = swap_item->GetAugment(k);
if(itm)
{
@ -6146,28 +6149,28 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
failedLoreCheck = true;
}
if(!failedLoreCheck) {
if(j == SLOT_PRIMARY) {
if(j == MainPrimary) {
if((mWeaponItem->ItemType == ItemType2HSlash) || (mWeaponItem->ItemType == ItemType2HBlunt) || (mWeaponItem->ItemType == ItemType2HPiercing)) {
if(GetBotItem(SLOT_SECONDARY)) {
if(client->CheckLoreConflict(GetBotItem(SLOT_SECONDARY)->GetItem())) {
if(GetBotItem(MainSecondary)) {
if(client->CheckLoreConflict(GetBotItem(MainSecondary)->GetItem())) {
failedLoreCheck = true;
}
else {
ItemInst* remove_item = GetBotItem(SLOT_SECONDARY);
BotTradeSwapItem(client, SLOT_SECONDARY, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
ItemInst* remove_item = GetBotItem(MainSecondary);
BotTradeSwapItem(client, MainSecondary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
}
}
}
if(!failedLoreCheck) {
BotTradeSwapItem(client, SLOT_PRIMARY, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
BotTradeSwapItem(client, MainPrimary, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
success = true;
}
break;
}
else if(j == SLOT_SECONDARY) {
else if(j == MainSecondary) {
if(inst->IsWeapon()) {
if(CanThisClassDualWield()) {
BotTradeSwapItem(client, SLOT_SECONDARY, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
BotTradeSwapItem(client, MainSecondary, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
success = true;
}
else {
@ -6176,13 +6179,13 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
}
}
else {
BotTradeSwapItem(client, SLOT_SECONDARY, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
BotTradeSwapItem(client, MainSecondary, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
success = true;
}
if(success && GetBotItem(SLOT_PRIMARY)) {
ItemInst* remove_item = GetBotItem(SLOT_PRIMARY);
if(success && GetBotItem(MainPrimary)) {
ItemInst* remove_item = GetBotItem(MainPrimary);
if((remove_item->GetItem()->ItemType == ItemType2HSlash) || (remove_item->GetItem()->ItemType == ItemType2HBlunt) || (remove_item->GetItem()->ItemType == ItemType2HPiercing)) {
BotTradeSwapItem(client, SLOT_PRIMARY, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
BotTradeSwapItem(client, MainPrimary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
}
}
break;
@ -6441,12 +6444,12 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
FaceTarget(GetTarget());
ItemInst* weapon = nullptr;
if(Hand == SLOT_PRIMARY) {
weapon = GetBotItem(SLOT_PRIMARY);
if(Hand == MainPrimary) {
weapon = GetBotItem(MainPrimary);
OffHandAtk(false);
}
if(Hand == SLOT_SECONDARY) {
weapon = GetBotItem(SLOT_SECONDARY);
if(Hand == MainSecondary) {
weapon = GetBotItem(MainSecondary);
OffHandAtk(true);
}
@ -6513,7 +6516,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
int ucDamageBonus = 0;
if( Hand == SLOT_PRIMARY && GetLevel() >= 28 && IsWarriorClass() )
if( Hand == MainPrimary && GetLevel() >= 28 && IsWarriorClass() )
{
// Damage bonuses apply only to hits from the main hand (Hand == 13) by characters level 28 and above
// who belong to a melee class. If we're here, then all of these conditions apply.
@ -6526,7 +6529,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
}
#endif
//Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon.
if (Hand==SLOT_SECONDARY) {
if (Hand==MainSecondary) {
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){
ucDamageBonus = GetWeaponDamageBonus( weapon ? weapon->GetItem() : (const Item_Struct*) nullptr );
@ -6583,7 +6586,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
if (damage == -3) {
if (FromRiposte) return false;
else {
if (Hand == SLOT_SECONDARY) {// Do we even have it & was attack with mainhand? If not, don't bother with other calculations
if (Hand == MainSecondary) {// Do we even have it & was attack with mainhand? If not, don't bother with other calculations
//Live AA - SlipperyAttacks
//This spell effect most likely directly modifies the actual riposte chance when using offhand attack.
int16 OffhandRiposteFail = aabonuses.OffhandRiposteFail + itembonuses.OffhandRiposteFail + spellbonuses.OffhandRiposteFail;
@ -7160,7 +7163,7 @@ int16 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) {
}
}
for(int y = 0; y < MAX_AUGMENT_SLOTS; ++y)
for (int y = 0; y < EmuConstants::ITEM_COMMON_SIZE; ++y)
{
ItemInst *aug = nullptr;
aug = ins->GetAugment(y);
@ -7732,18 +7735,18 @@ int16 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
}
//proc chance includes proc bonus
float Bot::GetProcChances(float ProcBonus, uint16 weapon_speed, uint16 hand) {
float Bot::GetProcChances(float ProcBonus, uint16 hand) {
int mydex = GetDEX();
float ProcChance = 0.0f;
uint16 weapon_speed = 0;
switch (hand) {
case SLOT_PRIMARY:
case MainPrimary:
weapon_speed = attack_timer.GetDuration();
break;
case SLOT_SECONDARY:
case MainSecondary:
weapon_speed = attack_dw_timer.GetDuration();
break;
case SLOT_RANGE:
case MainRange:
weapon_speed = ranged_timer.GetDuration();
break;
}
@ -7860,9 +7863,9 @@ bool Bot::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
if(damage > 0 && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock)
&& (!other->BehindMob(this, other->GetX(), other->GetY()) || bShieldBlockFromRear)) {
bool equiped = GetBotItem(SLOT_SECONDARY);
bool equiped = GetBotItem(MainSecondary);
if(equiped) {
uint8 shield = GetBotItem(SLOT_SECONDARY)->GetItem()->ItemType;
uint8 shield = GetBotItem(MainSecondary)->GetItem()->ItemType;
float bonusShieldBlock = 0.0f;
if(shield == ItemTypeShield) {
@ -7875,9 +7878,9 @@ bool Bot::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
if(damage > 0 && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock)
&& (!other->BehindMob(this, other->GetX(), other->GetY()) || bShieldBlockFromRear)) {
bool equiped2 = GetBotItem(SLOT_PRIMARY);
bool equiped2 = GetBotItem(MainPrimary);
if(equiped2) {
uint8 TwoHandBlunt = GetBotItem(SLOT_PRIMARY)->GetItem()->ItemType;
uint8 TwoHandBlunt = GetBotItem(MainPrimary)->GetItem()->ItemType;
float bonusStaffBlock = 0.0f;
if(TwoHandBlunt == ItemType2HBlunt) {
@ -8015,7 +8018,7 @@ void Bot::DoRiposte(Mob* defender) {
if (!defender)
return;
defender->Attack(this, SLOT_PRIMARY, true);
defender->Attack(this, MainPrimary, true);
//double riposte
int16 DoubleRipChance = defender->GetAABonuses().GiveDoubleRiposte[0] +
@ -8025,7 +8028,7 @@ void Bot::DoRiposte(Mob* defender) {
if(DoubleRipChance && (DoubleRipChance >= MakeRandomInt(0, 100))) {
mlog(COMBAT__ATTACKS, "Preforming a double riposte (%d percent chance)", DoubleRipChance);
defender->Attack(this, SLOT_PRIMARY, true);
defender->Attack(this, MainPrimary, true);
}
//Double Riposte effect, allows for a chance to do RIPOSTE with a skill specfic special attack (ie Return Kick).
@ -8049,7 +8052,7 @@ void Bot::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
hate = hate_override;
if(skill == SkillBash) {
const ItemInst* inst = GetBotItem(SLOT_SECONDARY);
const ItemInst* inst = GetBotItem(MainSecondary);
const Item_Struct* botweapon = 0;
if(inst)
botweapon = inst->GetItem();
@ -8063,7 +8066,7 @@ void Bot::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
min_damage += min_damage * GetMeleeMinDamageMod_SE(skill) / 100;
if(HitChance && !who->CheckHitChance(this, skill, SLOT_PRIMARY))
if(HitChance && !who->CheckHitChance(this, skill, MainPrimary))
max_damage = 0;
else{
@ -8120,7 +8123,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) {
bool bIsBehind = false;
bool bCanFrontalBS = false;
const ItemInst* inst = GetBotItem(SLOT_PRIMARY);
const ItemInst* inst = GetBotItem(MainPrimary);
const Item_Struct* botpiercer = nullptr;
if(inst)
botpiercer = inst->GetItem();
@ -8192,7 +8195,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) {
}
}
else { //We do a single regular attack if we attack from the front without chaotic stab
Attack(other, 13);
Attack(other, MainPrimary);
}
}
@ -8206,11 +8209,11 @@ void Bot::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
int32 primaryweapondamage = 0;
int32 backstab_dmg = 0;
ItemInst* botweaponInst = GetBotItem(SLOT_PRIMARY);
ItemInst* botweaponInst = GetBotItem(MainPrimary);
if(botweaponInst) {
primaryweapondamage = GetWeaponDamage(other, botweaponInst);
backstab_dmg = botweaponInst->GetItem()->BackstabDmg;
for(int i = 0; i < MAX_AUGMENT_SLOTS; ++i)
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
{
ItemInst *aug = botweaponInst->GetAugment(i);
if(aug)
@ -8276,7 +8279,7 @@ void Bot::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
void Bot::RogueAssassinate(Mob* other)
{
ItemInst* botweaponInst = GetBotItem(SLOT_PRIMARY);
ItemInst* botweaponInst = GetBotItem(MainPrimary);
if(botweaponInst) {
if(GetWeaponDamage(other, botweaponInst)) {
other->Damage(this, 32000, SPELL_UNKNOWN, SkillBackstab);
@ -8366,10 +8369,10 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
if(level >= RuleI(Combat, NPCBashKickLevel)){
bool canBash = false;
if((GetRace() == OGRE || GetRace() == TROLL || GetRace() == BARBARIAN) // Racial Slam
|| (m_inv.GetItem(SLOT_SECONDARY) && m_inv.GetItem(SLOT_SECONDARY)->GetItem()->ItemType == ItemTypeShield) //Using Shield
|| (m_inv.GetItem(SLOT_PRIMARY) && (m_inv.GetItem(SLOT_PRIMARY)->GetItem()->ItemType == ItemType2HSlash
|| m_inv.GetItem(SLOT_PRIMARY)->GetItem()->ItemType == ItemType2HBlunt
|| m_inv.GetItem(SLOT_PRIMARY)->GetItem()->ItemType == ItemType2HPiercing)
|| (m_inv.GetItem(MainSecondary) && m_inv.GetItem(MainSecondary)->GetItem()->ItemType == ItemTypeShield) //Using Shield
|| (m_inv.GetItem(MainPrimary) && (m_inv.GetItem(MainPrimary)->GetItem()->ItemType == ItemType2HSlash
|| m_inv.GetItem(MainPrimary)->GetItem()->ItemType == ItemType2HBlunt
|| m_inv.GetItem(MainPrimary)->GetItem()->ItemType == ItemType2HPiercing)
&& GetAA(aa2HandBash) >= 1)) { //Using 2 hand weapon, but has AA 2 Hand Bash
canBash = true;
}
@ -8393,10 +8396,10 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
case PALADIN:
if(level >= RuleI(Combat, NPCBashKickLevel)){
if((GetRace() == OGRE || GetRace() == TROLL || GetRace() == BARBARIAN) // Racial Slam
|| (m_inv.GetItem(SLOT_SECONDARY) && m_inv.GetItem(SLOT_SECONDARY)->GetItem()->ItemType == ItemTypeShield) //Using Shield
|| (m_inv.GetItem(SLOT_PRIMARY) && (m_inv.GetItem(SLOT_PRIMARY)->GetItem()->ItemType == ItemType2HSlash
|| m_inv.GetItem(SLOT_PRIMARY)->GetItem()->ItemType == ItemType2HBlunt
|| m_inv.GetItem(SLOT_PRIMARY)->GetItem()->ItemType == ItemType2HPiercing)
|| (m_inv.GetItem(MainSecondary) && m_inv.GetItem(MainSecondary)->GetItem()->ItemType == ItemTypeShield) //Using Shield
|| (m_inv.GetItem(MainPrimary) && (m_inv.GetItem(MainPrimary)->GetItem()->ItemType == ItemType2HSlash
|| m_inv.GetItem(MainPrimary)->GetItem()->ItemType == ItemType2HBlunt
|| m_inv.GetItem(MainPrimary)->GetItem()->ItemType == ItemType2HPiercing)
&& GetAA(aa2HandBash) >= 1)) { //Using 2 hand weapon, but has AA 2 Hand Bash
skill_to_use = SkillBash;
}
@ -8443,8 +8446,8 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
{
DoAnim(animTailRake);
if(GetWeaponDamage(target, GetBotItem(SLOT_SECONDARY)) <= 0 &&
GetWeaponDamage(target, GetBotItem(SLOT_SHOULDER)) <= 0){
if(GetWeaponDamage(target, GetBotItem(MainSecondary)) <= 0 &&
GetWeaponDamage(target, GetBotItem(MainShoulders)) <= 0){
dmg = -5;
}
else{
@ -8519,7 +8522,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
{
DoAnim(animKick);
if(GetWeaponDamage(target, GetBotItem(SLOT_FEET)) <= 0){
if(GetWeaponDamage(target, GetBotItem(MainFeet)) <= 0){
dmg = -5;
}
else{
@ -8991,14 +8994,14 @@ void Bot::SetAttackTimer() {
Timer* TimerToUse = nullptr;
const Item_Struct* PrimaryWeapon = nullptr;
for (int i=SLOT_RANGE; i<=SLOT_SECONDARY; i++) {
for (int i=MainRange; i<=MainSecondary; i++) {
//pick a timer
if (i == SLOT_PRIMARY)
if (i == MainPrimary)
TimerToUse = &attack_timer;
else if (i == SLOT_RANGE)
else if (i == MainRange)
TimerToUse = &ranged_timer;
else if(i == SLOT_SECONDARY)
else if(i == MainSecondary)
TimerToUse = &attack_dw_timer;
else //invalid slot (hands will always hit this)
continue;
@ -9009,7 +9012,7 @@ void Bot::SetAttackTimer() {
ItemToUse = ci->GetItem();
//special offhand stuff
if(i == SLOT_SECONDARY) {
if(i == MainSecondary) {
//if we have a 2H weapon in our main hand, no dual
if(PrimaryWeapon != nullptr) {
if( PrimaryWeapon->ItemClass == ItemClassCommon
@ -9103,7 +9106,7 @@ void Bot::SetAttackTimer() {
TimerToUse->SetAtTrigger(speed, true);
}
if(i == SLOT_PRIMARY)
if(i == MainPrimary)
PrimaryWeapon = ItemToUse;
}
}
@ -11551,10 +11554,10 @@ bool Bot::CheckLoreConflict(const Item_Struct* item) {
return false;
if (item->LoreGroup == -1) // Standard lore items; look everywhere except the shared bank, return the result
return (m_inv.HasItem(item->ID, 0, invWhereWorn) != SLOT_INVALID);
return (m_inv.HasItem(item->ID, 0, invWhereWorn) != INVALID_INDEX);
//If the item has a lore group, we check for other items with the same group and return the result
return (m_inv.HasItemByLoreGroup(item->LoreGroup, invWhereWorn) != SLOT_INVALID);
return (m_inv.HasItemByLoreGroup(item->LoreGroup, invWhereWorn) != INVALID_INDEX);
}
bool Bot::GroupHasClass(Group* group, uint8 classId) {
@ -12160,7 +12163,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
bool is2Hweapon = false;
for(int i=0; i<22; ++i)
{
if((i == 14) && is2Hweapon) {
if((i == MainSecondary) && is2Hweapon) {
continue;
}
@ -12178,12 +12181,12 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
c->Message(15, "I need something for my %s (Item %i)", equipped[i], i);
continue;
}
if((i == 13) && ((item2->ItemType == ItemType2HSlash) || (item2->ItemType == ItemType2HBlunt) || (item2->ItemType == ItemType2HPiercing))) {
if((i == MainPrimary) && ((item2->ItemType == ItemType2HSlash) || (item2->ItemType == ItemType2HBlunt) || (item2->ItemType == ItemType2HPiercing))) {
is2Hweapon = true;
}
char* itemLink = 0;
if((i == 0) || (i == 11) || (i == 13) || (i == 14) || (i == 21)) {
if((i == MainCharm) || (i == MainRange) || (i == MainPrimary) || (i == MainSecondary) || (i == MainAmmo)) {
if (c->GetClientVersion() >= EQClientSoF)
{
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
@ -12300,7 +12303,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
// Don't allow the player to remove a lore item they already possess and cause a crash
bool failedLoreCheck = false;
if(itminst) {
for(int m=0; m<MAX_AUGMENT_SLOTS; ++m) {
for (int m = 0; m<EmuConstants::ITEM_COMMON_SIZE; ++m) {
ItemInst *itma = itminst->GetAugment(m);
if(itma)
{
@ -12317,7 +12320,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
if(itm) {
c->PushItemOnCursor(*itminst, true);
Bot *gearbot = c->GetTarget()->CastToBot();
if((slotId == SLOT_RANGE)||(slotId == SLOT_AMMO)||(slotId == SLOT_PRIMARY)||(slotId == SLOT_SECONDARY)) {
if((slotId == MainRange)||(slotId == MainAmmo)||(slotId == MainPrimary)||(slotId == MainSecondary)) {
gearbot->SetBotArcher(false);
}
gearbot->RemoveBotItemBySlot(slotId, &TempErrorMessage);
@ -12330,30 +12333,31 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
gearbot->BotRemoveEquipItem(slotId);
gearbot->CalcBotStats();
switch(slotId) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 8:
case 9:
case 10:
case 11:
case 13:
case 14:
case 15:
case 16:
case 17:
case 20:
case 21:
case MainCharm:
case MainEar1:
case MainHead:
case MainFace:
case MainEar2:
case MainNeck:
case MainBack:
case MainWrist1:
case MainWrist2:
case MainRange:
case MainPrimary:
case MainSecondary:
case MainFinger1:
case MainFinger2:
case MainChest:
case MainWaist:
//case MainPowerSource:
case MainAmmo:
gearbot->Say("My %s is now unequipped.", equipped[slotId]);
break;
case 6:
case 7:
case 12:
case 18:
case 19:
case MainShoulders:
case MainArms:
case MainHands:
case MainLegs:
case MainFeet:
gearbot->Say("My %s are now unequipped.", equipped[slotId]);
break;
default:
@ -12362,30 +12366,31 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
}
else {
switch(slotId) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 8:
case 9:
case 10:
case 11:
case 13:
case 14:
case 15:
case 16:
case 17:
case 20:
case 21:
case MainCharm:
case MainEar1:
case MainHead:
case MainFace:
case MainEar2:
case MainNeck:
case MainBack:
case MainWrist1:
case MainWrist2:
case MainRange:
case MainPrimary:
case MainSecondary:
case MainFinger1:
case MainFinger2:
case MainChest:
case MainWaist:
//case MainPowerSource:
case MainAmmo:
c->GetTarget()->Say("My %s is already unequipped.", equipped[slotId]);
break;
case 6:
case 7:
case 12:
case 18:
case 19:
case MainShoulders:
case MainArms:
case MainHands:
case MainLegs:
case MainFeet:
c->GetTarget()->Say("My %s are already unequipped.", equipped[slotId]);
break;
default:
@ -16270,8 +16275,8 @@ void EntityList::BotPickLock(Bot* rogue)
curdist += (tmp * tmp);
if((zdiff < 10) && (curdist <= 130)) {
// All rogue items with lock pick bonuses are hands or primary
const ItemInst* item1 = rogue->GetBotItem(SLOT_HANDS);
const ItemInst* item2 = rogue->GetBotItem(SLOT_PRIMARY);
const ItemInst* item1 = rogue->GetBotItem(MainHands);
const ItemInst* item2 = rogue->GetBotItem(MainPrimary);
float bonus1 = 0.0f;
float bonus2 = 0.0f;
@ -16500,14 +16505,14 @@ int Bot::GetRawACNoShield(int &shield_ac)
{
int ac = itembonuses.AC + spellbonuses.AC;
shield_ac = 0;
ItemInst* inst = GetBotItem(SLOT_SECONDARY);
ItemInst* inst = GetBotItem(MainSecondary);
if(inst)
{
if(inst->GetItem()->ItemType == ItemTypeShield)
{
ac -= inst->GetItem()->AC;
shield_ac = inst->GetItem()->AC;
for(uint8 i = 0; i < MAX_AUGMENT_SLOTS; i++)
for (uint8 i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++)
{
if(inst->GetAugment(i))
{

View File

@ -137,7 +137,7 @@ public:
//abstract virtual function implementations requird by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill);
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false);
virtual bool Attack(Mob* other, int Hand = 13, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
ExtraAttackOptions *opts = nullptr);
virtual bool HasRaid() { return (GetRaid() ? true : false); }
virtual bool HasGroup() { return (GetGroup() ? true : false); }
@ -167,7 +167,7 @@ public:
uint16 BotGetSpells(int spellslot) { return AIspells[spellslot].spellid; }
uint16 BotGetSpellType(int spellslot) { return AIspells[spellslot].type; }
uint16 BotGetSpellPriority(int spellslot) { return AIspells[spellslot].priority; }
virtual float GetProcChances(float ProcBonus, uint16 weapon_speed, uint16 hand);
virtual float GetProcChances(float ProcBonus, uint16 hand);
virtual bool AvoidDamage(Mob* other, int32 &damage, bool CanRiposte);
virtual int GetMonkHandToHandDamage(void);
virtual bool TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse);

View File

@ -1867,52 +1867,57 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
// (update: i think pp should do it, as this holds LoY dye - plus, this is ugly code with Inventory!)
const Item_Struct* item = nullptr;
const ItemInst* inst = nullptr;
if ((inst = m_inv[SLOT_HANDS]) && inst->IsType(ItemClassCommon)) {
if ((inst = m_inv[MainHands]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialHands] = item->Material;
ns->spawn.colors[MaterialHands].color = GetEquipmentColor(MaterialHands);
}
if ((inst = m_inv[SLOT_HEAD]) && inst->IsType(ItemClassCommon)) {
if ((inst = m_inv[MainHead]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialHead] = item->Material;
ns->spawn.colors[MaterialHead].color = GetEquipmentColor(MaterialHead);
}
if ((inst = m_inv[SLOT_ARMS]) && inst->IsType(ItemClassCommon)) {
if ((inst = m_inv[MainArms]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialArms] = item->Material;
ns->spawn.colors[MaterialArms].color = GetEquipmentColor(MaterialArms);
}
if ((inst = m_inv[SLOT_BRACER01]) && inst->IsType(ItemClassCommon)) {
if ((inst = m_inv[MainWrist1]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialWrist]= item->Material;
ns->spawn.colors[MaterialWrist].color = GetEquipmentColor(MaterialWrist);
}
/*
// non-live behavior
if ((inst = m_inv[SLOT_BRACER02]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialWrist]= item->Material;
ns->spawn.colors[MaterialWrist].color = GetEquipmentColor(MaterialWrist);
}
if ((inst = m_inv[SLOT_CHEST]) && inst->IsType(ItemClassCommon)) {
*/
if ((inst = m_inv[MainChest]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialChest] = item->Material;
ns->spawn.colors[MaterialChest].color = GetEquipmentColor(MaterialChest);
}
if ((inst = m_inv[SLOT_LEGS]) && inst->IsType(ItemClassCommon)) {
if ((inst = m_inv[MainLegs]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialLegs] = item->Material;
ns->spawn.colors[MaterialLegs].color = GetEquipmentColor(MaterialLegs);
}
if ((inst = m_inv[SLOT_FEET]) && inst->IsType(ItemClassCommon)) {
if ((inst = m_inv[MainFeet]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
ns->spawn.equipment[MaterialFeet] = item->Material;
ns->spawn.colors[MaterialFeet].color = GetEquipmentColor(MaterialFeet);
}
if ((inst = m_inv[SLOT_PRIMARY]) && inst->IsType(ItemClassCommon)) {
if ((inst = m_inv[MainPrimary]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
if (strlen(item->IDFile) > 2)
ns->spawn.equipment[MaterialPrimary] = atoi(&item->IDFile[2]);
}
if ((inst = m_inv[SLOT_SECONDARY]) && inst->IsType(ItemClassCommon)) {
if ((inst = m_inv[MainSecondary]) && inst->IsType(ItemClassCommon)) {
item = inst->GetItem();
if (strlen(item->IDFile) > 2)
ns->spawn.equipment[MaterialSecondary] = atoi(&item->IDFile[2]);
@ -2624,7 +2629,7 @@ bool Client::BindWound(Mob* bindmob, bool start, bool fail){
if(!bindwound_timer.Enabled()) {
//make sure we actually have a bandage... and consume it.
int16 bslot = m_inv.HasItemByUse(ItemTypeBandage, 1, invWhereWorn|invWherePersonal);
if(bslot == SLOT_INVALID) {
if (bslot == INVALID_INDEX) {
bind_out->type = 3;
QueuePacket(outapp);
bind_out->type = 7; //this is the wrong message, dont know the right one.
@ -2775,28 +2780,31 @@ bool Client::BindWound(Mob* bindmob, bool start, bool fail){
return true;
}
void Client::SetMaterial(int16 in_slot, uint32 item_id){
void Client::SetMaterial(int16 in_slot, uint32 item_id) {
const Item_Struct* item = database.GetItem(item_id);
if (item && (item->ItemClass==ItemClassCommon)) {
if (in_slot==SLOT_HEAD)
if (in_slot==MainHead)
m_pp.item_material[MaterialHead] = item->Material;
else if (in_slot==SLOT_CHEST)
else if (in_slot==MainChest)
m_pp.item_material[MaterialChest] = item->Material;
else if (in_slot==SLOT_ARMS)
else if (in_slot==MainArms)
m_pp.item_material[MaterialArms] = item->Material;
else if (in_slot==SLOT_BRACER01)
else if (in_slot==MainWrist1)
m_pp.item_material[MaterialWrist] = item->Material;
/*
// non-live behavior
else if (in_slot==SLOT_BRACER02)
m_pp.item_material[MaterialWrist] = item->Material;
else if (in_slot==SLOT_HANDS)
*/
else if (in_slot==MainHands)
m_pp.item_material[MaterialHands] = item->Material;
else if (in_slot==SLOT_LEGS)
else if (in_slot==MainLegs)
m_pp.item_material[MaterialLegs] = item->Material;
else if (in_slot==SLOT_FEET)
else if (in_slot==MainFeet)
m_pp.item_material[MaterialFeet] = item->Material;
else if (in_slot==SLOT_PRIMARY)
m_pp.item_material[MaterialPrimary] = atoi(item->IDFile+2);
else if (in_slot==SLOT_SECONDARY)
else if (in_slot==MainPrimary)
m_pp.item_material[MaterialPrimary] = atoi(item->IDFile+2);
else if (in_slot==MainSecondary)
m_pp.item_material[MaterialSecondary] = atoi(item->IDFile+2);
}
}
@ -3118,25 +3126,28 @@ void Client::SetTint(int16 in_slot, uint32 color) {
// Still need to reconcile bracer01 versus bracer02
void Client::SetTint(int16 in_slot, Color_Struct& color) {
if (in_slot==SLOT_HEAD)
if (in_slot==MainHead)
m_pp.item_tint[MaterialHead].color=color.color;
else if (in_slot==SLOT_ARMS)
else if (in_slot==MainArms)
m_pp.item_tint[MaterialArms].color=color.color;
else if (in_slot==SLOT_BRACER01)
else if (in_slot==MainWrist1)
m_pp.item_tint[MaterialWrist].color=color.color;
/*
// non-live behavior
else if (in_slot==SLOT_BRACER02)
m_pp.item_tint[MaterialWrist].color=color.color;
else if (in_slot==SLOT_HANDS)
*/
else if (in_slot==MainHands)
m_pp.item_tint[MaterialHands].color=color.color;
else if (in_slot==SLOT_PRIMARY)
else if (in_slot==MainPrimary)
m_pp.item_tint[MaterialPrimary].color=color.color;
else if (in_slot==SLOT_SECONDARY)
else if (in_slot==MainSecondary)
m_pp.item_tint[MaterialSecondary].color=color.color;
else if (in_slot==SLOT_CHEST)
else if (in_slot==MainChest)
m_pp.item_tint[MaterialChest].color=color.color;
else if (in_slot==SLOT_LEGS)
else if (in_slot==MainLegs)
m_pp.item_tint[MaterialLegs].color=color.color;
else if (in_slot==SLOT_FEET)
else if (in_slot==MainFeet)
m_pp.item_tint[MaterialFeet].color=color.color;
}
@ -3202,57 +3213,57 @@ void Client::LinkDead()
}
uint8 Client::SlotConvert(uint8 slot,bool bracer){
uint8 slot2=0;
uint8 slot2=0; // why are we returning MainCharm instead of INVALID_INDEX? (must be a pre-charm segment...)
if(bracer)
return SLOT_BRACER02;
return MainWrist2;
switch(slot){
case MaterialHead:
slot2=SLOT_HEAD;
slot2=MainHead;
break;
case MaterialChest:
slot2=SLOT_CHEST;
slot2=MainChest;
break;
case MaterialArms:
slot2=SLOT_ARMS;
slot2=MainArms;
break;
case MaterialWrist:
slot2=SLOT_BRACER01;
slot2=MainWrist1;
break;
case MaterialHands:
slot2=SLOT_HANDS;
slot2=MainHands;
break;
case MaterialLegs:
slot2=SLOT_LEGS;
slot2=MainLegs;
break;
case MaterialFeet:
slot2=SLOT_FEET;
slot2=MainFeet;
break;
}
return slot2;
}
uint8 Client::SlotConvert2(uint8 slot){
uint8 slot2=0;
uint8 slot2=0; // same as above...
switch(slot){
case SLOT_HEAD:
case MainHead:
slot2=MaterialHead;
break;
case SLOT_CHEST:
case MainChest:
slot2=MaterialChest;
break;
case SLOT_ARMS:
case MainArms:
slot2=MaterialArms;
break;
case SLOT_BRACER01:
case MainWrist1:
slot2=MaterialWrist;
break;
case SLOT_HANDS:
case MainHands:
slot2=MaterialHands;
break;
case SLOT_LEGS:
case MainLegs:
slot2=MaterialLegs;
break;
case SLOT_FEET:
case MainFeet:
slot2=MaterialFeet;
break;
}
@ -4130,14 +4141,14 @@ void Client::UpdateLFP() {
uint16 Client::GetPrimarySkillValue()
{
SkillUseTypes skill = HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill
bool equiped = m_inv.GetItem(13);
bool equiped = m_inv.GetItem(MainPrimary);
if (!equiped)
skill = SkillHandtoHand;
else {
uint8 type = m_inv.GetItem(13)->GetItem()->ItemType; //is this the best way to do this?
uint8 type = m_inv.GetItem(MainPrimary)->GetItem()->ItemType; //is this the best way to do this?
switch (type)
{
@ -4900,7 +4911,7 @@ void Client::ShowSkillsWindow()
if(GetSkill(it->second) > 0 || MaxSkill(it->second) > 0) {
WindowText += it->first;
// line up the values
for (int j = 0; j < MAX_AUGMENT_SLOTS; j++)
for (int j = 0; j < EmuConstants::ITEM_COMMON_SIZE; j++)
WindowText += "&nbsp;";
WindowText += itoa(this->GetSkill(it->second));
if (MaxSkill(it->second) > 0) {
@ -5691,7 +5702,7 @@ void Client::AddCrystals(uint32 Radiant, uint32 Ebon)
SendCrystalCounts();
}
// Processes a client request to inspect a SoF client's equipment.
// Processes a client request to inspect a SoF+ client's equipment.
void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
if(requestee && requester) {
EQApplicationPacket* outapp = new EQApplicationPacket(OP_InspectAnswer, sizeof(InspectResponse_Struct));
@ -5716,28 +5727,30 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
}
}
inst = requestee->GetInv().GetItem(9999);
inst = requestee->GetInv().GetItem(MainPowerSource);
if(inst) {
item = inst->GetItem();
if(item) {
strcpy(insr->itemnames[21], item->Name);
insr->itemicons[21] = item->Icon;
// we shouldn't do this..but, that's the way it's coded atm...
// (this type of action should be handled exclusively in the client translator)
strcpy(insr->itemnames[SoF::slots::MainPowerSource], item->Name);
insr->itemicons[SoF::slots::MainPowerSource] = item->Icon;
}
else
insr->itemicons[21] = 0xFFFFFFFF;
insr->itemicons[SoF::slots::MainPowerSource] = 0xFFFFFFFF;
}
inst = requestee->GetInv().GetItem(21);
inst = requestee->GetInv().GetItem(MainAmmo);
if(inst) {
item = inst->GetItem();
if(item) {
strcpy(insr->itemnames[22], item->Name);
insr->itemicons[22] = item->Icon;
strcpy(insr->itemnames[SoF::slots::MainAmmo], item->Name);
insr->itemicons[SoF::slots::MainAmmo] = item->Icon;
}
else
insr->itemicons[22] = 0xFFFFFFFF;
insr->itemicons[SoF::slots::MainAmmo] = 0xFFFFFFFF;
}
strcpy(insr->text, requestee->GetInspectMessage().text);
@ -6266,8 +6279,8 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
made_npc->PR = GetPR();
made_npc->Corrup = GetCorrup();
// looks
made_npc->texture = GetEquipmentMaterial(1);
made_npc->helmtexture = GetEquipmentMaterial(0);
made_npc->texture = GetEquipmentMaterial(MaterialChest);
made_npc->helmtexture = GetEquipmentMaterial(MaterialHead);
made_npc->haircolor = GetHairColor();
made_npc->beardcolor = GetBeardColor();
made_npc->eyecolor1 = GetEyeColor1();
@ -6278,9 +6291,9 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
made_npc->drakkin_heritage = GetDrakkinHeritage();
made_npc->drakkin_tattoo = GetDrakkinTattoo();
made_npc->drakkin_details = GetDrakkinDetails();
made_npc->d_meele_texture1 = GetEquipmentMaterial(7);
made_npc->d_meele_texture2 = GetEquipmentMaterial(8);
for (int i = 0; i < _MaterialCount; i++) {
made_npc->d_meele_texture1 = GetEquipmentMaterial(MaterialPrimary);
made_npc->d_meele_texture2 = GetEquipmentMaterial(MaterialSecondary);
for (int i = EmuConstants::MATERIAL_BEGIN; i <= EmuConstants::MATERIAL_END; i++) {
made_npc->armor_tint[i] = GetEquipmentColor(i);
}
made_npc->loottable_id = 0;
@ -7818,17 +7831,17 @@ void Client::TickItemCheck()
if(zone->tick_items.empty()) { return; }
//Scan equip slots for items
for(i = 0; i <= 21; i++)
for(i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; i++)
{
TryItemTick(i);
}
//Scan main inventory + cursor
for(i = 22; i < 31; i++)
for(i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::CURSOR; i++)
{
TryItemTick(i);
}
//Scan bags
for(i = 251; i < 340; i++)
for(i = EmuConstants::GENERAL_BAGS_BEGIN; i <= EmuConstants::CURSOR_BAG_END; i++)
{
TryItemTick(i);
}
@ -7852,9 +7865,9 @@ void Client::TryItemTick(int slot)
}
//Only look at augs in main inventory
if(slot > 21) { return; }
if(slot > EmuConstants::EQUIPMENT_END) { return; }
for(int x = 0; x < MAX_AUGMENT_SLOTS; ++x)
for (int x = AUG_BEGIN; x < EmuConstants::ITEM_COMMON_SIZE; ++x)
{
ItemInst * a_inst = inst->GetAugment(x);
if(!a_inst) { continue; }
@ -7875,17 +7888,17 @@ void Client::TryItemTick(int slot)
void Client::ItemTimerCheck()
{
int i;
for(i = 0; i <= 21; i++)
for(i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; i++)
{
TryItemTimer(i);
}
for(i = 22; i < 31; i++)
for(i = EmuConstants::GENERAL_BAGS_BEGIN; i <= EmuConstants::CURSOR; i++)
{
TryItemTimer(i);
}
for(i = 251; i < 340; i++)
for(i = EmuConstants::GENERAL_BAGS_BEGIN; i <= EmuConstants::CURSOR_BAG_END; i++)
{
TryItemTimer(i);
}
@ -7907,11 +7920,11 @@ void Client::TryItemTimer(int slot)
++it_iter;
}
if(slot > 21) {
if(slot > EmuConstants::EQUIPMENT_END) {
return;
}
for(int x = 0; x < MAX_AUGMENT_SLOTS; ++x)
for (int x = AUG_BEGIN; x < EmuConstants::ITEM_COMMON_SIZE; ++x)
{
ItemInst * a_inst = inst->GetAugment(x);
if(!a_inst) {

View File

@ -214,7 +214,7 @@ public:
//abstract virtual function implementations requird by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill);
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false);
virtual bool Attack(Mob* other, int Hand = 13, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
ExtraAttackOptions *opts = nullptr);
virtual bool HasRaid() { return (GetRaid() ? true : false); }
virtual bool HasGroup() { return (GetGroup() ? true : false); }
@ -799,7 +799,7 @@ public:
void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false);
void PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootItem_Struct** bag_item_data = 0);
bool AutoPutLootInInventory(ItemInst& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0);
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1=0, uint32 aug2=0, uint32 aug3=0, uint32 aug4=0, uint32 aug5=0, bool attuned=false, uint16 to_slot=SLOT_CURSOR);
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, bool attuned = false, uint16 to_slot = MainCursor);
void SetStats(uint8 type,int16 set_val);
void IncStats(uint8 type,int16 increase_val);
void DropItem(int16 slot_id);

View File

@ -873,9 +873,9 @@ int16 Client::CalcAC() {
// Shield AC bonus for HeroicSTR
if(itembonuses.HeroicSTR) {
bool equiped = CastToClient()->m_inv.GetItem(14);
bool equiped = CastToClient()->m_inv.GetItem(MainSecondary);
if(equiped) {
uint8 shield = CastToClient()->m_inv.GetItem(14)->GetItem()->ItemType;
uint8 shield = CastToClient()->m_inv.GetItem(MainSecondary)->GetItem()->ItemType;
if(shield == ItemTypeShield)
displayed += itembonuses.HeroicSTR/2;
}
@ -903,9 +903,9 @@ int16 Client::GetACMit() {
// Shield AC bonus for HeroicSTR
if(itembonuses.HeroicSTR) {
bool equiped = CastToClient()->m_inv.GetItem(14);
bool equiped = CastToClient()->m_inv.GetItem(MainSecondary);
if(equiped) {
uint8 shield = CastToClient()->m_inv.GetItem(14)->GetItem()->ItemType;
uint8 shield = CastToClient()->m_inv.GetItem(MainSecondary)->GetItem()->ItemType;
if(shield == ItemTypeShield)
mitigation += itembonuses.HeroicSTR/2;
}
@ -1127,7 +1127,7 @@ uint32 Client::CalcCurrentWeight() {
ItemInst* ins;
uint32 Total = 0;
int x;
for(x = 0; x <= 30; x++)
for(x = EmuConstants::EQUIPMENT_BEGIN; x <= EmuConstants::CURSOR; x++) // include cursor or not?
{
TempItem = 0;
ins = GetInv().GetItem(x);
@ -1136,7 +1136,7 @@ uint32 Client::CalcCurrentWeight() {
if (TempItem)
Total += TempItem->Weight;
}
for (x = 251; x < 331; x++)
for (x = EmuConstants::GENERAL_BAGS_BEGIN; x <= EmuConstants::GENERAL_BAGS_END; x++) // include cursor bags or not?
{
int TmpWeight = 0;
TempItem = 0;
@ -1147,9 +1147,11 @@ uint32 Client::CalcCurrentWeight() {
TmpWeight = TempItem->Weight;
if (TmpWeight > 0)
{
int bagslot = 22;
// this code indicates that weight redux bags canonly be in the first general inventory slot to be effective...
// is this correct? or can we scan for the highest weight redux and use that? (need client verifications)
int bagslot = MainGeneral1;
int reduction = 0;
for (int m = 261; m < 331; m += 10)
for (int m = MainGeneral2; m <= EmuConstants::GENERAL_BAGS_END; m += 10) // include cursor bags or not?
{
if (x >= m)
bagslot += 1;
@ -1172,10 +1174,9 @@ uint32 Client::CalcCurrentWeight() {
This is the ONLY instance I have seen where the client is hard coded to particular Item IDs to set a certain property for an item. It is very odd.
*/
// SoD client has no weight for coin
if (GetClientVersion() < EQClientSoD) {
// SoD+ client has no weight for coin
if (EQLimits::CoinHasWeight(ClientVersion))
Total += (m_pp.platinum + m_pp.gold + m_pp.silver + m_pp.copper) / 4;
}
float Packrat = (float)spellbonuses.Packrat + (float)aabonuses.Packrat + (float)itembonuses.Packrat;
if (Packrat > 0)
@ -1967,16 +1968,16 @@ int32 Client::CalcEnduranceRegenCap() {
int Client::GetRawACNoShield(int &shield_ac) const
{
int ac = itembonuses.AC + spellbonuses.AC;
int ac = itembonuses.AC + spellbonuses.AC + aabonuses.AC;
shield_ac = 0;
const ItemInst *inst = m_inv.GetItem(SLOT_SECONDARY);
const ItemInst *inst = m_inv.GetItem(MainSecondary);
if(inst)
{
if(inst->GetItem()->ItemType == ItemTypeShield)
{
ac -= inst->GetItem()->AC;
shield_ac = inst->GetItem()->AC;
for(uint8 i = 0; i < MAX_AUGMENT_SLOTS; i++)
for (uint8 i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++)
{
if(inst->GetAugment(i))
{

View File

@ -386,6 +386,7 @@ void MapOpcodes() {
ConnectedOpcodes[OP_MercenaryTimerRequest] = &Client::Handle_OP_MercenaryTimerRequest;
ConnectedOpcodes[OP_OpenInventory] = &Client::Handle_OP_OpenInventory;
ConnectedOpcodes[OP_OpenContainer] = &Client::Handle_OP_OpenContainer;
ConnectedOpcodes[OP_ClientTimeStamp] = &Client::Handle_OP_ClientTimeStamp;
}
void ClearMappedOpcode(EmuOpcode op) {
@ -1629,7 +1630,7 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app)
Shielding_Struct* shield = (Shielding_Struct*)app->pBuffer;
shield_target = entity_list.GetMob(shield->target_id);
bool ack = false;
ItemInst* inst = GetInv().GetItem(14);
ItemInst* inst = GetInv().GetItem(MainSecondary);
if (!shield_target)
return;
if (inst)
@ -2031,7 +2032,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
LogFile->write(EQEMuLog::Debug, "OP ItemVerifyRequest: spell=%i, target=%i, inv=%i", spell_id, target_id, slot_id);
if ((slot_id < 30) || (slot_id == 9999) || (slot_id > 250 && slot_id < 331 && ((item->ItemType == ItemTypePotion) || item->PotionBelt))) // sanity check
if ((slot_id < MainCursor) || (slot_id == MainPowerSource) || (slot_id > 250 && slot_id < 331 && ((item->ItemType == ItemTypePotion) || item->PotionBelt))) // sanity check
{
ItemInst* p_inst = (ItemInst*)inst;
@ -2047,7 +2048,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
ItemInst* clickaug = 0;
Item_Struct* augitem = 0;
for(r = 0; r < MAX_AUGMENT_SLOTS; r++) {
for (r = 0; r < EmuConstants::ITEM_COMMON_SIZE; r++) {
const ItemInst* aug_i = inst->GetAugment(r);
if(!aug_i)
continue;
@ -2465,7 +2466,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app)
ItemInst *inst = database.CreateItem(item, charges);
if(!AutoPutLootInInventory(*inst, true, true))
{
PutLootInInventory(SLOT_CURSOR, *inst);
PutLootInInventory(MainCursor, *inst);
}
Save(1);
}
@ -3259,7 +3260,7 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app)
MoveItem_Struct* mi = (MoveItem_Struct*)app->pBuffer;
if(spellend_timer.Enabled() && casting_spell_id && !IsBardSong(casting_spell_id))
{
if(mi->from_slot != mi->to_slot && (mi->from_slot < 30 || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot))
if(mi->from_slot != mi->to_slot && (mi->from_slot <= EmuConstants::GENERAL_END || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot))
{
char *detect = nullptr;
const ItemInst *itm_from = GetInv().GetItem(mi->from_slot);
@ -3280,8 +3281,8 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app)
// Illegal bagslot useage checks. Currently, user only receives a message if this check is triggered.
bool mi_hack = false;
if(mi->from_slot >= 251 && mi->from_slot <= 340) {
if(mi->from_slot > 330) { mi_hack = true; }
if(mi->from_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->from_slot <= EmuConstants::CURSOR_BAG_END) {
if(mi->from_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; }
else {
int16 from_parent = m_inv.CalcSlotId(mi->from_slot);
if(!m_inv[from_parent]) { mi_hack = true; }
@ -3290,8 +3291,8 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app)
}
}
if(mi->to_slot >= 251 && mi->to_slot <= 340) {
if(mi->to_slot > 330) { mi_hack = true; }
if(mi->to_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->to_slot <= EmuConstants::CURSOR_BAG_END) {
if(mi->to_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; }
else {
int16 to_parent = m_inv.CalcSlotId(mi->to_slot);
if(!m_inv[to_parent]) { mi_hack = true; }
@ -5631,8 +5632,8 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
freeslotid = m_inv.FindFreeSlot(false, true, item->Size);
//make sure we are not completely full...
if(freeslotid == SLOT_CURSOR) {
if(m_inv.GetItem(SLOT_CURSOR) != nullptr) {
if (freeslotid == MainCursor) {
if (m_inv.GetItem(MainCursor) != nullptr) {
Message(13, "You do not have room for any more items.");
safe_delete(outapp);
safe_delete(inst);
@ -5640,7 +5641,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
}
}
if(freeslotid == SLOT_INVALID)
if (freeslotid == INVALID_INDEX)
{
Message(13, "You do not have room for any more items.");
safe_delete(outapp);
@ -6227,7 +6228,7 @@ void Client::Handle_OP_ClickDoor(const EQApplicationPacket *app)
void Client::Handle_OP_CreateObject(const EQApplicationPacket *app)
{
DropItem(SLOT_CURSOR);
DropItem(MainCursor);
return;
}
@ -6782,7 +6783,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app) {
for (int16 L = 0; L <= 20; L++) {
const ItemInst* inst = GetInv().GetItem(L);
item = inst ? inst->GetItem() : nullptr;
item = inst ? inst->GetItem() : nullptr;
if(item) {
strcpy(insr->itemnames[L], item->Name);
@ -6791,14 +6792,15 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app) {
else { insr->itemicons[L] = 0xFFFFFFFF; }
}
const ItemInst* inst = GetInv().GetItem(21);
const ItemInst* inst = GetInv().GetItem(MainAmmo);
item = inst ? inst->GetItem() : nullptr;
if(item) {
strcpy(insr->itemnames[22], item->Name);
insr->itemicons[22] = item->Icon;
// another one..I did these, didn't I!!?
strcpy(insr->itemnames[SoF::slots::MainAmmo], item->Name);
insr->itemicons[SoF::slots::MainAmmo] = item->Icon;
}
else { insr->itemicons[22] = 0xFFFFFFFF; }
else { insr->itemicons[SoF::slots::MainAmmo] = 0xFFFFFFFF; }
InspectMessage_Struct* newmessage = (InspectMessage_Struct*) insr->text;
InspectMessage_Struct& playermessage = this->GetInspectMessage();
@ -9232,7 +9234,7 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
if (it==m_inv.cursor_begin())
continue;
const ItemInst *inst=*it;
SendItemPacket(SLOT_CURSOR, inst, ItemPacketSummonItem);
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
}
}
@ -11037,8 +11039,8 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app) {
}
uint32 ApplyPoisonSuccessResult = 0;
ApplyPoison_Struct* ApplyPoisonData = (ApplyPoison_Struct*)app->pBuffer;
const ItemInst* PrimaryWeapon = GetInv().GetItem(SLOT_PRIMARY);
const ItemInst* SecondaryWeapon = GetInv().GetItem(SLOT_SECONDARY);
const ItemInst* PrimaryWeapon = GetInv().GetItem(MainPrimary);
const ItemInst* SecondaryWeapon = GetInv().GetItem(MainSecondary);
const ItemInst* PoisonItemInstance = GetInv()[ApplyPoisonData->inventorySlot];
bool IsPoison = PoisonItemInstance && (PoisonItemInstance->GetItem()->ItemType == ItemTypePoison);
@ -11822,7 +11824,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
return;
}
ItemInst *CursorItemInst = GetInv().GetItem(SLOT_CURSOR);
ItemInst *CursorItemInst = GetInv().GetItem(MainCursor);
bool Allowed = true;
@ -11879,7 +11881,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
{
GuildBankDepositAck(false);
DeleteItemInInventory(SLOT_CURSOR, 0, false);
DeleteItemInInventory(MainCursor, 0, false);
}
break;
@ -11900,7 +11902,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
case GuildBankWithdraw:
{
if(GetInv()[SLOT_CURSOR])
if (GetInv()[MainCursor])
{
Message_StringID(13, GUILD_BANK_EMPTY_HANDS);
@ -11946,7 +11948,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
{
PushItemOnCursor(*inst);
SendItemPacket(SLOT_CURSOR, inst, ItemPacketSummonItem);
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
GuildBanks->DeleteItem(GuildID(), gbwis->Area, gbwis->SlotID, gbwis->Quantity);
}
@ -12752,7 +12754,7 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app) {
ItemInst *inst = database.CreateItem(item, charges);
if(!AutoPutLootInInventory(*inst, true, true))
{
PutLootInInventory(SLOT_CURSOR, *inst);
PutLootInInventory(MainCursor, *inst);
}
Save(1);
@ -12786,7 +12788,7 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) {
SummonItem(item_id, max_currency);
SetAlternateCurrencyValue(reclaim->currency_id, 0);
} else {
SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, false, SLOT_CURSOR);
SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, false, MainCursor);
AddAlternateCurrencyValue(reclaim->currency_id, -((int32)reclaim->count));
}
}
@ -13866,3 +13868,7 @@ void Client::Handle_OP_OpenContainer(const EQApplicationPacket *app) {
// SideNote: Watching the slot translations, Unknown1 is showing '141' as well on certain item swaps.
// Manually looting a corpse results in a from '34' to '68' value for equipment items, '0' to '0' for inventory.
}
void Client::Handle_OP_ClientTimeStamp(const EQApplicationPacket *app) {
// handle as needed or ignore like we have been doing...
}

View File

@ -288,3 +288,4 @@
void Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app);
void Handle_OP_OpenInventory(const EQApplicationPacket *app);
void Handle_OP_OpenContainer(const EQApplicationPacket *app);
void Handle_OP_ClientTimeStamp(const EQApplicationPacket *app);

View File

@ -293,7 +293,7 @@ bool Client::Process() {
}
if(AutoFireEnabled()){
ItemInst *ranged = GetInv().GetItem(SLOT_RANGE);
ItemInst *ranged = GetInv().GetItem(MainRange);
if(ranged)
{
if(ranged->GetItem() && ranged->GetItem()->ItemType == ItemTypeBow){
@ -402,10 +402,10 @@ bool Client::Process() {
{
entity_list.AEAttack(this, 30);
} else {
Attack(auto_attack_target, 13); // Kaiyodo - added attacking hand to arguments
Attack(auto_attack_target, MainPrimary); // Kaiyodo - added attacking hand to arguments
}
ItemInst *wpn = GetInv().GetItem(SLOT_PRIMARY);
TryWeaponProc(wpn, auto_attack_target, 13);
ItemInst *wpn = GetInv().GetItem(MainPrimary);
TryWeaponProc(wpn, auto_attack_target, MainPrimary);
bool tripleAttackSuccess = false;
if( auto_attack_target && CanThisClassDoubleAttack() ) {
@ -416,7 +416,7 @@ bool Client::Process() {
if(CheckAAEffect(aaEffectRampage)) {
entity_list.AEAttack(this, 30);
} else {
Attack(auto_attack_target, 13, false);
Attack(auto_attack_target, MainPrimary, false);
}
}
@ -426,13 +426,13 @@ bool Client::Process() {
&& CheckDoubleAttack(true))
{
tripleAttackSuccess = true;
Attack(auto_attack_target, 13, false);
Attack(auto_attack_target, MainPrimary, false);
}
//quad attack, does this belong here??
if(GetSpecialAbility(SPECATK_QUAD) && CheckDoubleAttack(true))
{
Attack(auto_attack_target, 13, false);
Attack(auto_attack_target, MainPrimary, false);
}
}
@ -444,15 +444,15 @@ bool Client::Process() {
if(MakeRandomInt(0, 99) < flurrychance)
{
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
Attack(auto_attack_target, 13, false);
Attack(auto_attack_target, 13, false);
Attack(auto_attack_target, MainPrimary, false);
Attack(auto_attack_target, MainPrimary, false);
}
}
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance;
if (auto_attack_target && ExtraAttackChanceBonus) {
ItemInst *wpn = GetInv().GetItem(SLOT_PRIMARY);
ItemInst *wpn = GetInv().GetItem(MainPrimary);
if(wpn){
if(wpn->GetItem()->ItemType == ItemType2HSlash ||
wpn->GetItem()->ItemType == ItemType2HBlunt ||
@ -460,7 +460,7 @@ bool Client::Process() {
{
if(MakeRandomInt(0, 99) < ExtraAttackChanceBonus)
{
Attack(auto_attack_target, 13, false);
Attack(auto_attack_target, MainPrimary, false);
}
}
}
@ -507,19 +507,19 @@ bool Client::Process() {
CheckIncreaseSkill(SkillDualWield, auto_attack_target, -10);
if (random < DualWieldProbability){ // Max 78% of DW
if(CheckAAEffect(aaEffectRampage)) {
entity_list.AEAttack(this, 30, 14);
entity_list.AEAttack(this, 30, MainSecondary);
} else {
Attack(auto_attack_target, 14); // Single attack with offhand
Attack(auto_attack_target, MainSecondary); // Single attack with offhand
}
ItemInst *wpn = GetInv().GetItem(SLOT_SECONDARY);
TryWeaponProc(wpn, auto_attack_target, 14);
ItemInst *wpn = GetInv().GetItem(MainSecondary);
TryWeaponProc(wpn, auto_attack_target, MainSecondary);
if( CanThisClassDoubleAttack() && CheckDoubleAttack()) {
if(CheckAAEffect(aaEffectRampage)) {
entity_list.AEAttack(this, 30, 14);
entity_list.AEAttack(this, 30, MainSecondary);
} else {
if(auto_attack_target && auto_attack_target->GetHP() > -10)
Attack(auto_attack_target, 14); // Single attack with offhand
Attack(auto_attack_target, MainSecondary); // Single attack with offhand
}
}
}
@ -878,9 +878,9 @@ void Client::BulkSendInventoryItems() {
// Power Source
if(GetClientVersion() >= EQClientSoF) {
const ItemInst* inst = m_inv[9999];
const ItemInst* inst = m_inv[MainPowerSource];
if(inst) {
std::string packet = inst->Serialize(9999);
std::string packet = inst->Serialize(MainPowerSource);
ser_items[i++] = packet;
size += packet.length();
}
@ -1217,7 +1217,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
switch(memspell->scribing)
{
case memSpellScribing: { // scribing spell to book
const ItemInst* inst = m_inv[SLOT_CURSOR];
const ItemInst* inst = m_inv[MainCursor];
if(inst && inst->IsType(ItemClassCommon))
{
@ -1226,7 +1226,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
if(item && item->Scroll.Effect == (int32)(memspell->spell_id))
{
ScribeSpell(memspell->spell_id, memspell->slot);
DeleteItemInInventory(SLOT_CURSOR, 1, true);
DeleteItemInInventory(MainCursor, 1, true);
}
else
Message(0,"Scribing spell: inst exists but item does not or spell ids do not match.");

View File

@ -2957,9 +2957,9 @@ void command_peekinv(Client *c, const Seperator *sep)
}
if(c->GetClientVersion() >= EQClientSoF)
{
const ItemInst* inst = client->GetInv().GetItem(9999);
const ItemInst* inst = client->GetInv().GetItem(MainPowerSource);
item = (inst) ? inst->GetItem() : nullptr;
c->Message((item==0), "InvSlot: %i, Item: %i (%c%06X00000000000000000000000000000000000000000000%s%c), Charges: %i", 9999,
c->Message((item==0), "InvSlot: %i, Item: %i (%c%06X00000000000000000000000000000000000000000000%s%c), Charges: %i", MainPowerSource,
((item==0)?0:item->ID),0x12, ((item==0)?0:item->ID),
((item==0)?"null":item->Name), 0x12,
((item==0)?0:inst->GetCharges()));
@ -2977,12 +2977,12 @@ void command_peekinv(Client *c, const Seperator *sep)
if(client->GetInv().CursorEmpty()) { // Display 'front' cursor slot even if 'empty' (item(30[0]) == null)
if (c->GetClientVersion() >= EQClientSoF)
{
c->Message((item==0), "CursorSlot: %i, Depth: %i, Item: %i (%c%06X00000000000000000000000000000000000000000000%s%c), Charges: %i", SLOT_CURSOR,i,
c->Message((item == 0), "CursorSlot: %i, Depth: %i, Item: %i (%c%06X00000000000000000000000000000000000000000000%s%c), Charges: %i", MainCursor, i,
0, 0x12, 0, "null", 0x12, 0);
}
else
{
c->Message((item==0), "CursorSlot: %i, Depth: %i, Item: %i (%c%06X000000000000000000000000000000000000000%s%c), Charges: %i", SLOT_CURSOR,i,
c->Message((item == 0), "CursorSlot: %i, Depth: %i, Item: %i (%c%06X000000000000000000000000000000000000000%s%c), Charges: %i", MainCursor, i,
0, 0x12, 0, "null", 0x12, 0);
}
}
@ -2992,14 +2992,14 @@ void command_peekinv(Client *c, const Seperator *sep)
item = (inst) ? inst->GetItem() : nullptr;
if (c->GetClientVersion() >= EQClientSoF)
{
c->Message((item==0), "CursorSlot: %i, Depth: %i, Item: %i (%c%06X00000000000000000000000000000000000000000000%s%c), Charges: %i", SLOT_CURSOR,i,
c->Message((item == 0), "CursorSlot: %i, Depth: %i, Item: %i (%c%06X00000000000000000000000000000000000000000000%s%c), Charges: %i", MainCursor, i,
((item==0)?0:item->ID),0x12, ((item==0)?0:item->ID),
((item==0)?"null":item->Name), 0x12,
((item==0)?0:inst->GetCharges()));
}
else
{
c->Message((item==0), "CursorSlot: %i, Depth: %i, Item: %i (%c%06X000000000000000000000000000000000000000%s%c), Charges: %i", SLOT_CURSOR,i,
c->Message((item == 0), "CursorSlot: %i, Depth: %i, Item: %i (%c%06X000000000000000000000000000000000000000%s%c), Charges: %i", MainCursor, i,
((item==0)?0:item->ID),0x12, ((item==0)?0:item->ID),
((item==0)?"null":item->Name), 0x12,
((item==0)?0:inst->GetCharges()));
@ -3007,21 +3007,21 @@ void command_peekinv(Client *c, const Seperator *sep)
if (inst && inst->IsType(ItemClassContainer) && i==0) { // 'CSD 1' - only display contents of slot 30[0] container..higher ones don't exist
for (uint8 j=0; j<10; j++) {
const ItemInst* instbag = client->GetInv().GetItem(SLOT_CURSOR, j);
const ItemInst* instbag = client->GetInv().GetItem(MainCursor, j);
item = (instbag) ? instbag->GetItem() : nullptr;
if (c->GetClientVersion() >= EQClientSoF)
{
c->Message((item==0), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%c%06X00000000000000000000000000000000000000000000%s%c), Charges: %i",
Inventory::CalcSlotId(SLOT_CURSOR, j),
SLOT_CURSOR, j, ((item==0)?0:item->ID),0x12, ((item==0)?0:item->ID),
Inventory::CalcSlotId(MainCursor, j),
MainCursor, j, ((item == 0) ? 0 : item->ID), 0x12, ((item == 0) ? 0 : item->ID),
((item==0)?"null":item->Name), 0x12,
((item==0)?0:instbag->GetCharges()));
}
else
{
c->Message((item==0), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%c%06X000000000000000000000000000000000000000%s%c), Charges: %i",
Inventory::CalcSlotId(SLOT_CURSOR, j),
SLOT_CURSOR, j, ((item==0)?0:item->ID),0x12, ((item==0)?0:item->ID),
Inventory::CalcSlotId(MainCursor, j),
MainCursor, j, ((item == 0) ? 0 : item->ID), 0x12, ((item == 0) ? 0 : item->ID),
((item==0)?"null":item->Name), 0x12,
((item==0)?0:instbag->GetCharges()));
}
@ -3034,7 +3034,7 @@ void command_peekinv(Client *c, const Seperator *sep)
if (bAll || (strcasecmp(sep->arg[1], "trib")==0)) {
// Active tribute effect items
bFound = true;
for (int16 i=TRIBUTE_SLOT_START; i<(TRIBUTE_SLOT_START + MAX_PLAYER_TRIBUTES); i++) {
for (int16 i = EmuConstants::TRIBUTE_BEGIN; i <= EmuConstants::TRIBUTE_END; i++) {
const ItemInst* inst = client->GetInv().GetItem(i);
item = (inst) ? inst->GetItem() : nullptr;
if (c->GetClientVersion() >= EQClientSoF)
@ -3533,7 +3533,7 @@ void command_equipitem(Client *c, const Seperator *sep)
{
uint32 slot_id = atoi(sep->arg[1]);
if (sep->IsNumber(1) && (slot_id>=0) && (slot_id<=21)) {
const ItemInst* from_inst = c->GetInv().GetItem(SLOT_CURSOR);
const ItemInst* from_inst = c->GetInv().GetItem(MainCursor);
const ItemInst* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack)
bool partialmove = false;
int16 movecount;
@ -3541,7 +3541,7 @@ void command_equipitem(Client *c, const Seperator *sep)
if (from_inst && from_inst->IsType(ItemClassCommon)) {
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
MoveItem_Struct* mi = (MoveItem_Struct*)outapp->pBuffer;
mi->from_slot = SLOT_CURSOR;
mi->from_slot = MainCursor;
mi->to_slot = slot_id;
// mi->number_in_stack = from_inst->GetCharges(); // replaced with con check for stacking
@ -4698,7 +4698,7 @@ void command_goto(Client *c, const Seperator *sep)
void command_iteminfo(Client *c, const Seperator *sep)
{
const ItemInst* inst = c->GetInv()[SLOT_CURSOR];
const ItemInst* inst = c->GetInv()[MainCursor];
if (!inst)
c->Message(13, "Error: You need an item on your cursor for this command");

View File

@ -266,6 +266,7 @@ struct StatBonuses {
int16 StrikeThrough; // PoP: Strike Through %
int16 MeleeMitigation; //i = Shielding
int16 MeleeMitigationEffect; //i = Spell Effect Melee Mitigation
int16 CriticalHitChance[HIGHEST_SKILL+2]; //i
int16 CriticalSpellChance; //i
int16 SpellCritDmgIncrease; //i
@ -275,7 +276,8 @@ struct StatBonuses {
int16 CriticalHealOverTime; //i
int16 CriticalDoTChance; //i
int16 CrippBlowChance; //
int16 AvoidMeleeChance; //AvoidMeleeChance/10 == % chance i = Avoidance
int16 AvoidMeleeChance; //AvoidMeleeChance/10 == % chance i = Avoidance (item mod)
int16 AvoidMeleeChanceEffect; //AvoidMeleeChance Spell Effect
int16 RiposteChance; //i
int16 DodgeChance; //i
int16 ParryChance; //i

View File

@ -367,9 +367,9 @@ Corpse::Corpse(Client* client, int32 in_rezexp)
for(i = 0; i <= 30; i++)
{
if(i == 21 && client->GetClientVersion() >= EQClientSoF) {
item = client->GetInv().GetItem(9999);
item = client->GetInv().GetItem(MainPowerSource);
if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) {
std::list<uint32> slot_list = MoveItemToCorpse(client, item, 9999);
std::list<uint32> slot_list = MoveItemToCorpse(client, item, MainPowerSource);
removed_list.merge(slot_list);
}
@ -421,7 +421,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp)
if(cursor) { // all cursor items should be on corpse (client < SoF or RespawnFromHover = false)
while(!client->GetInv().CursorEmpty())
client->DeleteItemInInventory(SLOT_CURSOR, 0, false, false);
client->DeleteItemInInventory(MainCursor, 0, false, false);
}
else { // only visible cursor made it to corpse (client >= Sof and RespawnFromHover = true)
std::list<ItemInst*>::const_iterator start = client->GetInv().cursor_begin();
@ -999,12 +999,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
end = itemlist.end();
uint8 containercount = 0;
int corpselootlimit;
if(client->GetClientVersion() >= EQClientRoF) { corpselootlimit = 34; }
else if(client->GetClientVersion() >= EQClientSoF) { corpselootlimit = 32; }
else if(client->GetClientVersion() == EQClientTitanium) { corpselootlimit = 31; }
else { corpselootlimit = 30; }
int corpselootlimit = EQLimits::InventoryMapSize(MapCorpse, client->GetClientVersion());
for(; cur != end; ++cur) {
ServerLootItem_Struct* item_data = *cur;
@ -1013,7 +1009,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
// Dont display the item if it's in a bag
// Added cursor queue slots to corpse item visibility list. Nothing else should be making it to corpse.
if(!IsPlayerCorpse() || item_data->equipSlot <= 30 || item_data->equipSlot == 9999 || tCanLoot>=3 ||
if(!IsPlayerCorpse() || item_data->equipSlot <= MainCursor || item_data->equipSlot == MainPowerSource || tCanLoot>=3 ||
(item_data->equipSlot >= 8000 && item_data->equipSlot <= 8999)) {
if(i < corpselootlimit) {
item = database.GetItem(item_data->item_id);
@ -1145,7 +1141,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app)
if(inst->IsAugmented())
{
for(int i=0; i<MAX_AUGMENT_SLOTS; i++)
for (int i = 0; i<EmuConstants::ITEM_COMMON_SIZE; i++)
{
ItemInst *itm = inst->GetAugment(i);
if(itm)
@ -1227,11 +1223,11 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app)
if(lootitem->auto_loot)
{
if(!client->AutoPutLootInInventory(*inst, true, true, bag_item_data))
client->PutLootInInventory(SLOT_CURSOR, *inst, bag_item_data);
client->PutLootInInventory(MainCursor, *inst, bag_item_data);
}
else
{
client->PutLootInInventory(SLOT_CURSOR, *inst, bag_item_data);
client->PutLootInInventory(MainCursor, *inst, bag_item_data);
}
// Update any tasks that have an activity to loot this item.
if(RuleB(TaskSystem, EnableTaskSystem))
@ -1331,17 +1327,13 @@ void Corpse::QueryLoot(Client* to) {
cur = itemlist.begin();
end = itemlist.end();
int corpselootlimit;
if (to->GetClientVersion() >= EQClientSoF) { corpselootlimit = 32; }
else if (to->GetClientVersion() == EQClientTitanium) { corpselootlimit = 31; }
else { corpselootlimit = 30; }
int corpselootlimit = EQLimits::InventoryMapSize(MapCorpse, to->GetClientVersion());
for(; cur != end; ++cur) {
ServerLootItem_Struct* sitem = *cur;
if (IsPlayerCorpse()) {
if (sitem->equipSlot >= 251 && sitem->equipSlot <= 340)
if (sitem->equipSlot >= EmuConstants::GENERAL_BAGS_BEGIN && sitem->equipSlot <= EmuConstants::CURSOR_BAG_END)
sitem->lootslot = 0xFFFF;
else
x < corpselootlimit ? sitem->lootslot = x : sitem->lootslot = 0xFFFF;

View File

@ -41,7 +41,7 @@ public:
//abstract virtual function implementations requird by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; }
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; }
virtual bool Attack(Mob* other, int Hand = 13, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false,
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false,
ExtraAttackOptions *opts = nullptr) { return false; }
virtual bool HasRaid() { return false; }
virtual bool HasGroup() { return false; }

View File

@ -162,7 +162,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
{
if(!sender->KeyRingCheck(RuleI(Adventure, ItemIDToEnablePorts)))
{
if(sender->GetInv().HasItem(RuleI(Adventure, ItemIDToEnablePorts)) == SLOT_INVALID)
if (sender->GetInv().HasItem(RuleI(Adventure, ItemIDToEnablePorts)) == INVALID_INDEX)
{
sender->Message_StringID(13, DUNGEON_SEALED);
safe_delete(outapp);
@ -195,11 +195,11 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
uint8 keepoffkeyring = GetNoKeyring();
uint32 haskey = 0;
uint32 playerkey = 0;
const ItemInst *lockpicks = sender->GetInv().GetItem(SLOT_CURSOR);
const ItemInst *lockpicks = sender->GetInv().GetItem(MainCursor);
haskey = sender->GetInv().HasItem(keyneeded, 1);
if(haskey != SLOT_INVALID)
if (haskey != INVALID_INDEX)
{
playerkey = keyneeded;
}

View File

@ -305,7 +305,7 @@ public:
void QueueToGroupsForNPCHealthAA(Mob* sender, const EQApplicationPacket* app);
void QueueManaged(Mob* sender, const EQApplicationPacket* app, bool ignore_sender=false, bool ackreq = true);
void AEAttack(Mob *attacker, float dist, int Hand = 13, int count = 0, bool IsFromSpell = false);
void AEAttack(Mob *attacker, float dist, int Hand = MainPrimary, int count = 0, bool IsFromSpell = false);
void AETaunt(Client *caster, float range = 0);
void AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true, int16 resist_adjust = 0);
void MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);

View File

@ -206,10 +206,10 @@ uint32 ZoneDatabase::GetZoneFishing(uint32 ZoneID, uint8 skill, uint32 &npc_id,
//we need this function to immediately determine, after we receive OP_Fishing, if we can even try to fish, otherwise we have to wait a while to get the failure
bool Client::CanFish() {
//make sure we still have a fishing pole on:
const ItemInst* Pole = m_inv[SLOT_PRIMARY];
const ItemInst* Pole = m_inv[MainPrimary];
int32 bslot = m_inv.HasItemByUse(ItemTypeFishingBait, 1, invWhereWorn|invWherePersonal);
const ItemInst* Bait = nullptr;
if(bslot != SLOT_INVALID)
if (bslot != INVALID_INDEX)
Bait = m_inv.GetItem(bslot);
if(!Pole || !Pole->IsType(ItemClassCommon) || Pole->GetItem()->ItemType != ItemTypeFishingPole) {
@ -297,11 +297,11 @@ void Client::GoFish()
//make sure we still have a fishing pole on:
int32 bslot = m_inv.HasItemByUse(ItemTypeFishingBait, 1, invWhereWorn|invWherePersonal);
const ItemInst* Bait = nullptr;
if(bslot != SLOT_INVALID)
if (bslot != INVALID_INDEX)
Bait = m_inv.GetItem(bslot);
//if the bait isnt equipped, need to add its skill bonus
if(bslot >= IDX_INV && Bait->GetItem()->SkillModType == SkillFishing) {
if(bslot >= EmuConstants::GENERAL_BEGIN && Bait->GetItem()->SkillModType == SkillFishing) {
fishing_skill += Bait->GetItem()->SkillModValue;
}
@ -358,12 +358,12 @@ void Client::GoFish()
else
{
PushItemOnCursor(*inst);
SendItemPacket(SLOT_CURSOR,inst,ItemPacketSummonItem);
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
if(RuleB(TaskSystem, EnableTaskSystem))
UpdateTasksForItem(ActivityFish, food_id);
safe_delete(inst);
inst = m_inv.GetItem(SLOT_CURSOR);
inst = m_inv.GetItem(MainCursor);
}
}
@ -393,7 +393,7 @@ void Client::GoFish()
//and then swap out items in primary slot... too lazy to fix right now
if (MakeRandomInt(0, 49) == 1) {
Message_StringID(MT_Skills, FISHING_POLE_BROKE); //Your fishing pole broke!
DeleteItemInInventory(13,0,true);
DeleteItemInInventory(MainPrimary, 0, true);
}
if(CheckIncreaseSkill(SkillFishing, nullptr, 5))
@ -472,12 +472,12 @@ void Client::ForageItem(bool guarantee) {
}
else {
PushItemOnCursor(*inst);
SendItemPacket(SLOT_CURSOR, inst, ItemPacketSummonItem);
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
if(RuleB(TaskSystem, EnableTaskSystem))
UpdateTasksForItem(ActivityForage, foragedfood);
safe_delete(inst);
inst = m_inv.GetItem(SLOT_CURSOR);
inst = m_inv.GetItem(MainCursor);
}
}

View File

@ -545,7 +545,7 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption
if(cur)
{
for(int i = 0; i < count; ++i) {
caster->Attack(cur, 13, false, false, false, opts);
caster->Attack(cur, MainPrimary, false, false, false, opts);
}
}
iter++;

View File

@ -44,7 +44,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
int i;
if(where_to_check & invWhereWorn) {
for (i=0; i<=21; i++) { // Equipped
for (i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; i++) {
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
cur = m_inv.GetItem(i);
if(cur && cur->GetItem()->Stackable) {
@ -57,9 +57,8 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
}
}
// Power Source Slot
if (GetItemIDAt(9999) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(9999) != INVALID_ID)) {
cur = m_inv.GetItem(9999);
if (GetItemIDAt(MainPowerSource) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(MainPowerSource) != INVALID_ID)) {
cur = m_inv.GetItem(MainPowerSource);
if(cur && cur->GetItem()->Stackable) {
x += cur->GetCharges();
} else {
@ -67,25 +66,25 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
}
if (GetClientVersion() >= EQClientSoF)
DeleteItemInInventory(9999, 0, true);
DeleteItemInInventory(MainPowerSource, 0, true);
else
DeleteItemInInventory(9999, 0, false); // Prevents Titanium crash
DeleteItemInInventory(MainPowerSource, 0, false); // Prevents Titanium crash
}
}
if(where_to_check & invWhereCursor) {
if (GetItemIDAt(30) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(30) != INVALID_ID)) {
cur = m_inv.GetItem(30);
if (GetItemIDAt(MainCursor) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(MainCursor) != INVALID_ID)) {
cur = m_inv.GetItem(MainCursor);
if(cur && cur->GetItem()->Stackable) {
x += cur->GetCharges();
} else {
x++;
}
DeleteItemInInventory(30, 0, true);
DeleteItemInInventory(MainCursor, 0, true);
}
for (i=331; i<=340; i++) { // cursor's containers
for (i = EmuConstants::CURSOR_BAG_BEGIN; i <= EmuConstants::CURSOR_BAG_END; i++) {
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
cur = m_inv.GetItem(i);
if(cur && cur->GetItem()->Stackable) {
@ -100,7 +99,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
}
if(where_to_check & invWherePersonal) {
for (i=22; i<=29; i++) { // Equipped
for (i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++) {
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
cur = m_inv.GetItem(i);
if(cur && cur->GetItem()->Stackable) {
@ -113,7 +112,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
}
}
for (i=251; i<=330; i++) { // Main inventory's containers
for (i = EmuConstants::GENERAL_BAGS_BEGIN; i <= EmuConstants::GENERAL_BAGS_END; i++) {
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
cur = m_inv.GetItem(i);
if(cur && cur->GetItem()->Stackable) {
@ -128,7 +127,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
}
if(where_to_check & invWhereBank) {
for (i=2000; i<=2023; i++) { // Bank slots
for (i = EmuConstants::BANK_BEGIN; i <= EmuConstants::BANK_END; i++) {
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
cur = m_inv.GetItem(i);
if(cur && cur->GetItem()->Stackable) {
@ -141,7 +140,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
}
}
for (i=2031; i<=2270; i++) { // Bank's containers
for (i = EmuConstants::BANK_BAGS_BEGIN; i <= EmuConstants::BANK_BAGS_END; i++) {
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
cur = m_inv.GetItem(i);
if(cur && cur->GetItem()->Stackable) {
@ -156,7 +155,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
}
if(where_to_check & invWhereSharedBank) {
for (i=2500; i<=2501; i++) { // Shared bank
for (i = EmuConstants::SHARED_BANK_BEGIN; i <= EmuConstants::SHARED_BANK_END; i++) {
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
cur = m_inv.GetItem(i);
if(cur && cur->GetItem()->Stackable) {
@ -169,7 +168,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
}
}
for (i=2531; i<=2550; i++) { // Shared bank's containers
for (i = EmuConstants::SHARED_BANK_BAGS_BEGIN; i <= EmuConstants::SHARED_BANK_BAGS_END; i++) {
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
cur = m_inv.GetItem(i);
if(cur && cur->GetItem()->Stackable) {
@ -194,10 +193,10 @@ bool Client::CheckLoreConflict(const Item_Struct* item) {
return false;
if (item->LoreGroup == -1) // Standard lore items; look everywhere except the shared bank, return the result
return (m_inv.HasItem(item->ID, 0, ~invWhereSharedBank) != SLOT_INVALID);
return (m_inv.HasItem(item->ID, 0, ~invWhereSharedBank) != INVALID_INDEX);
//If the item has a lore group, we check for other items with the same group and return the result
return (m_inv.HasItemByLoreGroup(item->LoreGroup, ~invWhereSharedBank) != SLOT_INVALID);
return (m_inv.HasItemByLoreGroup(item->LoreGroup, ~invWhereSharedBank) != INVALID_INDEX);
}
bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, bool attuned, uint16 to_slot) {
@ -244,7 +243,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
}
*/
uint32 augments[MAX_AUGMENT_SLOTS] = { aug1, aug2, aug3, aug4, aug5 };
uint32 augments[EmuConstants::ITEM_COMMON_SIZE] = { aug1, aug2, aug3, aug4, aug5 };
uint32 classes = item->Classes;
uint32 races = item->Races;
@ -254,7 +253,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
bool enforcerestr = RuleB(Inventory, EnforceAugmentRestriction);
bool enforceusable = RuleB(Inventory, EnforceAugmentUsability);
for(int iter = 0; iter < MAX_AUGMENT_SLOTS; ++iter) {
for (int iter = 0; iter < EmuConstants::ITEM_COMMON_SIZE; ++iter) {
const Item_Struct* augtest = database.GetItem(augments[iter]);
if(augtest == nullptr) {
@ -548,7 +547,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
}
// add any validated augments
for(int iter = 0; iter < MAX_AUGMENT_SLOTS; ++iter) {
for (int iter = 0; iter < EmuConstants::ITEM_COMMON_SIZE; ++iter) {
if(augments[iter])
inst->PutAugment(&database, iter, augments[iter]);
}
@ -558,22 +557,22 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
inst->SetInstNoDrop(true);
// check to see if item is usable in requested slot
if(enforceusable && (((to_slot >= 0) && (to_slot <= 21)) || (to_slot == 9999))) {
uint32 slottest = (to_slot == 9999) ? 22 : to_slot;
if(enforceusable && (((to_slot >= MainCharm) && (to_slot <= MainAmmo)) || (to_slot == MainPowerSource))) {
uint32 slottest = (to_slot == MainPowerSource) ? 22 : to_slot; // can't change '22' just yet...
if(!(slots & ((uint32)1 << slottest))) {
Message(0, "This item is not equipable at slot %u - moving to cursor.", to_slot);
mlog(INVENTORY__ERROR, "Player %s on account %s attempted to equip an item unusable in slot %u - moved to cursor.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u)\n",
GetName(), account_name, to_slot, item->ID, aug1, aug2, aug3, aug4, aug5);
to_slot = SLOT_CURSOR;
to_slot = MainCursor;
}
}
// put item into inventory
if(to_slot == SLOT_CURSOR) {
if (to_slot == MainCursor) {
PushItemOnCursor(*inst);
SendItemPacket(SLOT_CURSOR, inst, ItemPacketSummonItem);
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
}
else {
PutItemInInventory(to_slot, *inst, true);
@ -586,7 +585,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
if(!IsDiscovered(item_id))
DiscoverItem(item_id);
for(int iter = 0; iter < MAX_AUGMENT_SLOTS; ++iter) {
for (int iter = 0; iter < EmuConstants::ITEM_COMMON_SIZE; ++iter) {
if(augments[iter] && !IsDiscovered(augments[iter]))
DiscoverItem(augments[iter]);
}
@ -619,7 +618,7 @@ void Client::DropItem(int16 slot_id)
}
// Save client inventory change to database
if(slot_id == SLOT_CURSOR) {
if (slot_id == MainCursor) {
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
database.SaveCursor(CharacterID(), s, e);
} else {
@ -755,7 +754,7 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd
bool isDeleted = m_inv.DeleteItem(slot_id, quantity);
const ItemInst* inst=nullptr;
if (slot_id==SLOT_CURSOR) {
if (slot_id == MainCursor) {
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
if(update_db)
database.SaveCursor(character_id, s, e);
@ -807,7 +806,7 @@ bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update)
m_inv.PushCursor(inst);
if (client_update) {
SendItemPacket(SLOT_CURSOR, &inst, ItemPacketSummonItem);
SendItemPacket(MainCursor, &inst, ItemPacketSummonItem);
}
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
@ -817,7 +816,7 @@ bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update)
bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update)
{
mlog(INVENTORY__SLOTS, "Putting item %s (%d) into slot %d", inst.GetItem()->Name, inst.GetItem()->ID, slot_id);
if (slot_id==SLOT_CURSOR)
if (slot_id == MainCursor)
{
return PushItemOnCursor(inst,client_update);
}
@ -825,10 +824,10 @@ bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client
m_inv.PutItem(slot_id, inst);
if (client_update) {
SendItemPacket(slot_id, &inst, (slot_id==SLOT_CURSOR)?ItemPacketSummonItem:ItemPacketTrade);
SendItemPacket(slot_id, &inst, (slot_id == MainCursor) ? ItemPacketSummonItem : ItemPacketTrade);
}
if (slot_id==SLOT_CURSOR) {
if (slot_id == MainCursor) {
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
return database.SaveCursor(this->CharacterID(), s, e);
} else
@ -844,7 +843,7 @@ void Client::PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootI
SendLootItemInPacket(&inst, slot_id);
if (slot_id==SLOT_CURSOR) {
if (slot_id == MainCursor) {
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
database.SaveCursor(this->CharacterID(), s, e);
} else
@ -919,25 +918,25 @@ bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_curs
if (!m_inv[i])
{
if( i == SLOT_PRIMARY && inst.IsWeapon() ) // If item is primary slot weapon
if( i == MainPrimary && inst.IsWeapon() ) // If item is primary slot weapon
{
if( (inst.GetItem()->ItemType == ItemType2HSlash) || (inst.GetItem()->ItemType == ItemType2HBlunt) || (inst.GetItem()->ItemType == ItemType2HPiercing) ) // and uses 2hs \ 2hb \ 2hp
{
if( m_inv[SLOT_SECONDARY] ) // and if secondary slot is not empty
if( m_inv[MainSecondary] ) // and if secondary slot is not empty
{
continue; // Can't auto-equip
}
}
}
if( i== SLOT_SECONDARY && m_inv[SLOT_PRIMARY]) // check to see if primary slot is a two hander
if( i== MainSecondary && m_inv[MainPrimary]) // check to see if primary slot is a two hander
{
uint8 use = m_inv[SLOT_PRIMARY]->GetItem()->ItemType;
uint8 use = m_inv[MainPrimary]->GetItem()->ItemType;
if(use == ItemType2HSlash || use == ItemType2HBlunt || use == ItemType2HPiercing)
continue;
}
if
(
i == SLOT_SECONDARY &&
i == MainSecondary &&
inst.IsWeapon() &&
!CanThisClassDualWield()
)
@ -972,7 +971,7 @@ bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_curs
// #3: put it in inventory
bool is_arrow = (inst.GetItem()->ItemType == ItemTypeArrow) ? true : false;
int16 slot_id = m_inv.FindFreeSlot(inst.IsType(ItemClassContainer), try_cursor, inst.GetItem()->Size, is_arrow);
if (slot_id != SLOT_INVALID)
if (slot_id != INVALID_INDEX)
{
PutLootInInventory(slot_id, inst, bag_item_data);
return true;
@ -1000,7 +999,7 @@ void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type)
tmp_inst->SetCharges(tmp_inst->GetCharges() + charges_to_move);
from.SetCharges(from.GetCharges() - charges_to_move);
SendLootItemInPacket(tmp_inst, to_slot);
if (to_slot==SLOT_CURSOR){
if (to_slot == MainCursor){
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
database.SaveCursor(this->CharacterID(), s, e);
} else
@ -1224,25 +1223,21 @@ void Client::SendLootItemInPacket(const ItemInst* inst, int16 slot_id)
SendItemPacket(slot_id,inst, ItemPacketTrade);
}
bool Client::IsValidSlot(uint32 slot)
{
if((slot == (uint32)SLOT_INVALID) || // Destroying/Dropping item
(slot >= 0 && slot <= 30) || // Worn inventory, normal inventory, and cursor
(slot >= 251 && slot <= 340) || // Normal inventory bags and cursor bag
(slot >= 400 && slot <= 404) || // Tribute
(slot >= 2000 && slot <= 2023) || // Bank
(slot >= 2031 && slot <= 2270) || // Bank bags
(slot >= 2500 && slot <= 2501) || // Shared bank
(slot >= 2531 && slot <= 2550) || // Shared bank bags
(slot >= 3000 && slot <= 3007) || // Trade window
(slot >= 4000 && slot <= 4009) || // Tradeskill container
(slot == 9999)) // Power Source
{
bool Client::IsValidSlot(uint32 slot) {
if ((slot == (uint32)INVALID_INDEX) ||
(slot >= EmuConstants::POSSESSIONS_BEGIN && slot <= EmuConstants::POSSESSIONS_END) ||
(slot >= EmuConstants::GENERAL_BAGS_BEGIN && slot <= EmuConstants::CURSOR_BAG_END) ||
(slot >= EmuConstants::TRIBUTE_BEGIN && slot <= EmuConstants::TRIBUTE_END) ||
(slot >= EmuConstants::BANK_BEGIN && slot <= EmuConstants::BANK_END) ||
(slot >= EmuConstants::BANK_BAGS_BEGIN && slot <= EmuConstants::BANK_BAGS_END) ||
(slot >= EmuConstants::SHARED_BANK_BEGIN && slot <= EmuConstants::SHARED_BANK_END) ||
(slot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot <= EmuConstants::SHARED_BANK_BAGS_END) ||
(slot >= EmuConstants::TRADE_BEGIN && slot <= EmuConstants::TRADE_END) ||
(slot >= EmuConstants::WORLD_BEGIN && slot <= EmuConstants::WORLD_END) ||
(slot == EmuConstants::POWER_SOURCE))
return true;
}
else {
else
return false;
}
}
bool Client::IsBankSlot(uint32 slot)
@ -1289,12 +1284,12 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
return true;
}
if (move_in->to_slot == (uint32)SLOT_INVALID) {
if(move_in->from_slot == (uint32)SLOT_CURSOR) {
if (move_in->to_slot == (uint32)INVALID_INDEX) {
if (move_in->from_slot == (uint32)MainCursor) {
mlog(INVENTORY__SLOTS, "Client destroyed item from cursor slot %d", move_in->from_slot);
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
ItemInst *inst = m_inv.GetItem(SLOT_CURSOR);
ItemInst *inst = m_inv.GetItem(MainCursor);
if(inst) {
parse->EventItem(EVENT_DESTROY_ITEM, this, inst, nullptr, "", 0);
}
@ -1309,9 +1304,9 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
return true; // Item deletetion
}
}
if(auto_attack && (move_in->from_slot == SLOT_PRIMARY || move_in->from_slot == SLOT_SECONDARY || move_in->from_slot == SLOT_RANGE))
if(auto_attack && (move_in->from_slot == MainPrimary || move_in->from_slot == MainSecondary || move_in->from_slot == MainRange))
SetAttackTimer();
else if(auto_attack && (move_in->to_slot == SLOT_PRIMARY || move_in->to_slot == SLOT_SECONDARY || move_in->to_slot == SLOT_RANGE))
else if(auto_attack && (move_in->to_slot == MainPrimary || move_in->to_slot == MainSecondary || move_in->to_slot == MainRange))
SetAttackTimer();
// Step 1: Variables
int16 src_slot_id = (int16)move_in->from_slot;
@ -1501,7 +1496,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
safe_delete(world_inst);
if (src_slot_id==SLOT_CURSOR) {
if (src_slot_id == MainCursor) {
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
database.SaveCursor(character_id, s, e);
} else
@ -1515,14 +1510,14 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
// Step 4: Check for entity trade
if (dst_slot_id>=3000 && dst_slot_id<=3007) {
if (src_slot_id != SLOT_CURSOR) {
if (src_slot_id != MainCursor) {
Kick();
return false;
}
if (with) {
mlog(INVENTORY__SLOTS, "Trade item move from slot %d to slot %d (trade with %s)", src_slot_id, dst_slot_id, with->GetName());
// Fill Trade list with items from cursor
if (!m_inv[SLOT_CURSOR]) {
if (!m_inv[MainCursor]) {
Message(13, "Error: Cursor item not located on server!");
return false;
}
@ -1538,7 +1533,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
SummonItem(src_inst->GetID(), src_inst->GetCharges());
DeleteItemInInventory(SLOT_CURSOR);
DeleteItemInInventory(MainCursor);
return true;
}
@ -1601,12 +1596,12 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
else {
// Not dealing with charges - just do direct swap
if(src_inst && (dst_slot_id < 22 || dst_slot_id == 9999) && dst_slot_id >= 0) {
if(src_inst && (dst_slot_id <= MainAmmo || dst_slot_id == MainPowerSource) && dst_slot_id >= MainCharm) {
if (src_inst->GetItem()->Attuneable) {
src_inst->SetInstNoDrop(true);
}
if (src_inst->IsAugmented()) {
for(int i = 0; i < MAX_AUGMENT_SLOTS; i++) {
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
if (src_inst->GetAugment(i)) {
if (src_inst->GetAugment(i)->GetItem()->Attuneable) {
src_inst->GetAugment(i)->SetInstNoDrop(true);
@ -1619,7 +1614,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
if(!m_inv.SwapItem(src_slot_id, dst_slot_id)) { return false; }
mlog(INVENTORY__SLOTS, "Moving entire item from slot %d to slot %d", src_slot_id, dst_slot_id);
if(src_slot_id < 22 || src_slot_id == 9999) {
if(src_slot_id <= MainAmmo || src_slot_id == MainPowerSource) {
if(src_inst) {
parse->EventItem(EVENT_UNEQUIP_ITEM, this, src_inst, nullptr, "", src_slot_id);
}
@ -1629,7 +1624,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
}
if(dst_slot_id < 22 || dst_slot_id == 9999) {
if(dst_slot_id <= MainAmmo || dst_slot_id == MainPowerSource) {
if(dst_inst) {
parse->EventItem(EVENT_UNEQUIP_ITEM, this, dst_inst, nullptr, "", dst_slot_id);
}
@ -1646,12 +1641,12 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
// Step 7: Save change to the database
if (src_slot_id==SLOT_CURSOR){
if (src_slot_id == MainCursor){
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
database.SaveCursor(character_id, s, e);
} else
database.SaveInventory(character_id, m_inv.GetItem(src_slot_id), src_slot_id);
if (dst_slot_id==SLOT_CURSOR) {
if (dst_slot_id == MainCursor) {
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
database.SaveCursor(character_id, s, e);
} else
@ -1665,14 +1660,17 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
void Client::SwapItemResync(MoveItem_Struct* move_slots) {
// wow..this thing created a helluva memory leak...
// with any luck..this won't be needed in the future
// resync the 'from' and 'to' slots on an as-needed basis
// Not as effective as the full process, but less intrusive to gameplay -U
mlog(INVENTORY__ERROR, "Inventory desyncronization. (charname: %s, source: %i, destination: %i)", GetName(), move_slots->from_slot, move_slots->to_slot);
Message(15, "Inventory Desyncronization detected: Resending slot data...");
if((move_slots->from_slot >= 0 && move_slots->from_slot <= 340) || move_slots->from_slot == 9999) {
int16 resync_slot = (Inventory::CalcSlotId(move_slots->from_slot) == SLOT_INVALID) ? move_slots->from_slot : Inventory::CalcSlotId(move_slots->from_slot);
if(IsValidSlot(resync_slot) && resync_slot != SLOT_INVALID) {
if((move_slots->from_slot >= MainCharm && move_slots->from_slot <= 340) || move_slots->from_slot == MainPowerSource) {
int16 resync_slot = (Inventory::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : Inventory::CalcSlotId(move_slots->from_slot);
if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) {
// This prevents the client from crashing when closing any 'phantom' bags -U
const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin'
ItemInst* token_inst = database.CreateItem(token_struct, 1);
@ -1690,13 +1688,14 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) {
QueuePacket(outapp);
safe_delete(outapp);
}
safe_delete(token_inst);
Message(14, "Source slot %i resyncronized.", move_slots->from_slot);
}
else { Message(13, "Could not resyncronize source slot %i.", move_slots->from_slot); }
}
else {
int16 resync_slot = (Inventory::CalcSlotId(move_slots->from_slot) == SLOT_INVALID) ? move_slots->from_slot : Inventory::CalcSlotId(move_slots->from_slot);
if(IsValidSlot(resync_slot) && resync_slot != SLOT_INVALID) {
int16 resync_slot = (Inventory::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : Inventory::CalcSlotId(move_slots->from_slot);
if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) {
if(m_inv[resync_slot]) {
const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin'
ItemInst* token_inst = database.CreateItem(token_struct, 1);
@ -1704,6 +1703,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) {
SendItemPacket(resync_slot, token_inst, ItemPacketTrade);
SendItemPacket(resync_slot, m_inv[resync_slot], ItemPacketTrade);
safe_delete(token_inst);
Message(14, "Source slot %i resyncronized.", move_slots->from_slot);
}
else { Message(13, "Could not resyncronize source slot %i.", move_slots->from_slot); }
@ -1711,9 +1711,9 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) {
else { Message(13, "Could not resyncronize source slot %i.", move_slots->from_slot); }
}
if((move_slots->to_slot >= 0 && move_slots->to_slot <= 340) || move_slots->to_slot == 9999) {
int16 resync_slot = (Inventory::CalcSlotId(move_slots->to_slot) == SLOT_INVALID) ? move_slots->to_slot : Inventory::CalcSlotId(move_slots->to_slot);
if(IsValidSlot(resync_slot) && resync_slot != SLOT_INVALID) {
if((move_slots->to_slot >= MainCharm && move_slots->to_slot <= 340) || move_slots->to_slot == MainPowerSource) {
int16 resync_slot = (Inventory::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : Inventory::CalcSlotId(move_slots->to_slot);
if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) {
const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin'
ItemInst* token_inst = database.CreateItem(token_struct, 1);
@ -1730,13 +1730,14 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) {
QueuePacket(outapp);
safe_delete(outapp);
}
safe_delete(token_inst);
Message(14, "Destination slot %i resyncronized.", move_slots->to_slot);
}
else { Message(13, "Could not resyncronize destination slot %i.", move_slots->to_slot); }
}
else {
int16 resync_slot = (Inventory::CalcSlotId(move_slots->to_slot) == SLOT_INVALID) ? move_slots->to_slot : Inventory::CalcSlotId(move_slots->to_slot);
if(IsValidSlot(resync_slot) && resync_slot != SLOT_INVALID) {
int16 resync_slot = (Inventory::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : Inventory::CalcSlotId(move_slots->to_slot);
if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) {
if(m_inv[resync_slot]) {
const Item_Struct* token_struct = database.GetItem(22292); // 'Copper Coin'
ItemInst* token_inst = database.CreateItem(token_struct, 1);
@ -1744,6 +1745,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) {
SendItemPacket(resync_slot, token_inst, ItemPacketTrade);
SendItemPacket(resync_slot, m_inv[resync_slot], ItemPacketTrade);
safe_delete(token_inst);
Message(14, "Destination slot %i resyncronized.", move_slots->to_slot);
}
else { Message(13, "Could not resyncronize destination slot %i.", move_slots->to_slot); }
@ -1857,7 +1859,7 @@ void Client::DyeArmor(DyeStruct* dye){
m_pp.item_tint[i].rgb.red!=dye->dye[i].rgb.red ||
m_pp.item_tint[i].rgb.green != dye->dye[i].rgb.green){
slot = m_inv.HasItem(32557, 1, invWherePersonal);
if(slot != SLOT_INVALID){
if (slot != INVALID_INDEX){
DeleteItemInInventory(slot,1,true);
uint8 slot2=SlotConvert(i);
ItemInst* inst = this->m_inv.GetItem(slot2);
@ -1942,10 +1944,10 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) {
ItemInst* ins;
int x;
int num = 0;
for(x=0; x < 331; x++)
for(x = EmuConstants::POSSESSIONS_BEGIN; x <= EmuConstants::GENERAL_BAGS_END; x++)
{
if (x == 31)
x = 251;
if (x == EmuConstants::CURSOR + 1)
x = EmuConstants::GENERAL_BAGS_BEGIN;
TempItem = 0;
ins = GetInv().GetItem(x);
if (ins)
@ -1959,10 +1961,10 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) {
}
if (num < amt)
return false;
for(x=0; x < 331; x++)
for(x = EmuConstants::POSSESSIONS_BEGIN; x <= EmuConstants::GENERAL_BAGS_END; x++) // should this be CURSOR_BAG_END
{
if (x == 31)
x = 251;
if (x == EmuConstants::CURSOR + 1)
x = EmuConstants::GENERAL_BAGS_BEGIN;
TempItem = 0;
ins = GetInv().GetItem(x);
if (ins)
@ -1991,7 +1993,7 @@ void Client::RemoveNoRent(bool client_update) {
int16 slot_id;
// personal
for(slot_id = 0; slot_id <= 30; slot_id++) {
for(slot_id = EmuConstants::POSSESSIONS_BEGIN; slot_id <= EmuConstants::POSSESSIONS_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);
@ -2000,14 +2002,14 @@ void Client::RemoveNoRent(bool client_update) {
}
// power source
const ItemInst* inst = m_inv[9999];
const ItemInst* inst = m_inv[EmuConstants::POWER_SOURCE];
if(inst && !inst->GetItem()->NoRent) {
mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
DeleteItemInInventory(9999, 0, (GetClientVersion() >= EQClientSoF) ? client_update : false); // Ti slot non-existent
mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, EmuConstants::POWER_SOURCE);
DeleteItemInInventory(EmuConstants::POWER_SOURCE, 0, (GetClientVersion() >= EQClientSoF) ? client_update : false); // Ti slot non-existent
}
// containers
for(slot_id = 251; slot_id <= 340; slot_id++) {
for(slot_id = EmuConstants::GENERAL_BAGS_BEGIN; slot_id <= EmuConstants::CURSOR_BAG_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);
@ -2016,7 +2018,7 @@ void Client::RemoveNoRent(bool client_update) {
}
// bank
for(slot_id = 2000; slot_id <= 2023; slot_id++) {
for(slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_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);
@ -2025,7 +2027,7 @@ void Client::RemoveNoRent(bool client_update) {
}
// bank containers
for(slot_id = 2031; slot_id <= 2270; slot_id++) {
for(slot_id = EmuConstants::BANK_BAGS_BEGIN; slot_id <= EmuConstants::BANK_BAGS_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);
@ -2034,7 +2036,7 @@ void Client::RemoveNoRent(bool client_update) {
}
// shared bank
for(slot_id = 2500; slot_id <= 2501; slot_id++) {
for(slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_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);
@ -2043,7 +2045,7 @@ void Client::RemoveNoRent(bool client_update) {
}
// shared bank containers
for(slot_id = 2531; slot_id <= 2550; slot_id++) {
for(slot_id = EmuConstants::SHARED_BANK_BAGS_BEGIN; slot_id <= EmuConstants::SHARED_BANK_BAGS_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);
@ -2058,7 +2060,7 @@ void Client::RemoveDuplicateLore(bool client_update) {
int16 slot_id;
// personal
for(slot_id = 0; slot_id <= 30; slot_id++) {
for(slot_id = EmuConstants::POSSESSIONS_BEGIN; slot_id <= EmuConstants::POSSESSIONS_END; slot_id++) {
ItemInst* inst = m_inv.PopItem(slot_id);
if(inst) {
if(CheckLoreConflict(inst->GetItem())) {
@ -2073,20 +2075,20 @@ void Client::RemoveDuplicateLore(bool client_update) {
}
// power source
ItemInst* inst = m_inv.PopItem(9999);
ItemInst* inst = m_inv.PopItem(EmuConstants::POWER_SOURCE);
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, 9999);
database.SaveInventory(character_id, nullptr, EmuConstants::POWER_SOURCE);
}
else {
m_inv.PutItem(9999, *inst);
m_inv.PutItem(EmuConstants::POWER_SOURCE, *inst);
}
safe_delete(inst);
}
// containers
for(slot_id = 251; slot_id <= 340; slot_id++) {
for(slot_id = EmuConstants::GENERAL_BAGS_BEGIN; slot_id <= EmuConstants::CURSOR_BAG_END; slot_id++) {
ItemInst* inst = m_inv.PopItem(slot_id);
if(inst) {
if(CheckLoreConflict(inst->GetItem())) {
@ -2101,7 +2103,7 @@ void Client::RemoveDuplicateLore(bool client_update) {
}
// bank
for(slot_id = 2000; slot_id <= 2023; slot_id++) {
for(slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; slot_id++) {
ItemInst* inst = m_inv.PopItem(slot_id);
if(inst) {
if(CheckLoreConflict(inst->GetItem())) {
@ -2116,7 +2118,7 @@ void Client::RemoveDuplicateLore(bool client_update) {
}
// bank containers
for(slot_id = 2031; slot_id <= 2270; slot_id++) {
for(slot_id = EmuConstants::BANK_BAGS_BEGIN; slot_id <= EmuConstants::BANK_BAGS_END; slot_id++) {
ItemInst* inst = m_inv.PopItem(slot_id);
if(inst) {
if(CheckLoreConflict(inst->GetItem())) {
@ -2138,7 +2140,7 @@ void Client::MoveSlotNotAllowed(bool client_update) {
int16 slot_id;
// equipment
for(slot_id = 0; slot_id <= 21; slot_id++) {
for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) {
if(m_inv[slot_id] && !m_inv[slot_id]->IsSlotAllowed(slot_id)) {
ItemInst* inst = m_inv.PopItem(slot_id);
bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false;
@ -2151,7 +2153,7 @@ void Client::MoveSlotNotAllowed(bool client_update) {
}
// power source
slot_id = 9999;
slot_id = EmuConstants::POWER_SOURCE;
if(m_inv[slot_id] && !m_inv[slot_id]->IsSlotAllowed(slot_id)) {
ItemInst* inst = m_inv.PopItem(slot_id);
bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false;
@ -2283,13 +2285,13 @@ static int16 BandolierSlotToWeaponSlot(int BandolierSlot) {
switch(BandolierSlot) {
case bandolierMainHand:
return SLOT_PRIMARY;
return MainPrimary;
case bandolierOffHand:
return SLOT_SECONDARY;
return MainSecondary;
case bandolierRange:
return SLOT_RANGE;
return MainRange;
default:
return SLOT_AMMO;
return MainAmmo;
}
}
@ -2365,12 +2367,12 @@ void Client::SetBandolier(const EQApplicationPacket *app) {
invWhereWorn|invWherePersonal);
// removed 'invWhereCursor' argument from above and implemented slots 30, 331-340 checks here
if (slot == SLOT_INVALID) {
if (m_inv.GetItem(SLOT_CURSOR)) {
if (m_inv.GetItem(SLOT_CURSOR)->GetItem()->ID == m_pp.bandoliers[bss->number].items[BandolierSlot].item_id &&
m_inv.GetItem(SLOT_CURSOR)->GetCharges() >= 1) // '> 0' the same, but this matches Inventory::_HasItem conditional check
slot = SLOT_CURSOR;
else if (m_inv.GetItem(SLOT_CURSOR)->GetItem()->ItemClass == 1) {
if (slot == INVALID_INDEX) {
if (m_inv.GetItem(MainCursor)) {
if (m_inv.GetItem(MainCursor)->GetItem()->ID == m_pp.bandoliers[bss->number].items[BandolierSlot].item_id &&
m_inv.GetItem(MainCursor)->GetCharges() >= 1) // '> 0' the same, but this matches Inventory::_HasItem conditional check
slot = MainCursor;
else if (m_inv.GetItem(MainCursor)->GetItem()->ItemClass == 1) {
for(int16 CursorBagSlot = 331; CursorBagSlot <= 340; CursorBagSlot++) {
if (m_inv.GetItem(CursorBagSlot)) {
if (m_inv.GetItem(CursorBagSlot)->GetItem()->ID == m_pp.bandoliers[bss->number].items[BandolierSlot].item_id &&
@ -2385,7 +2387,7 @@ void Client::SetBandolier(const EQApplicationPacket *app) {
}
// if the player has this item in their inventory,
if(slot != SLOT_INVALID) {
if (slot != INVALID_INDEX) {
// Pull the item out of the inventory
BandolierItems[BandolierSlot] = m_inv.PopItem(slot);
// If ammo with charges, only take one charge out to put in the range slot, that is what
@ -2410,7 +2412,7 @@ void Client::SetBandolier(const EQApplicationPacket *app) {
}
else { // The player doesn't have the required weapon with them.
BandolierItems[BandolierSlot] = 0;
if(slot == SLOT_INVALID) {
if (slot == INVALID_INDEX) {
_log(INVENTORY__BANDOLIER, "Character does not have required bandolier item for slot %i", WeaponSlot);
ItemInst *InvItem = m_inv.PopItem(WeaponSlot);
if(InvItem) {

View File

@ -219,7 +219,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
// it is an improvement.
if (!item2->NoPet) {
for (int i=0; !found && i<MAX_WORN_INVENTORY; i++) {
for (int i = 0; !found && i<EmuConstants::EQUIPMENT_SIZE; i++) {
uint32 slots = (1 << i);
if (item2->Slots & slots) {
if(equipment[i])
@ -260,7 +260,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
// @merth: IDFile size has been increased, this needs to change
uint16 emat;
if(item2->Material <= 0
|| item2->Slots & (1 << SLOT_PRIMARY | 1 << SLOT_SECONDARY)) {
|| item2->Slots & (1 << MainPrimary | 1 << MainSecondary)) {
memset(newid, 0, sizeof(newid));
for(int i=0;i<7;i++){
if (!isalpha(item2->IDFile[i])){
@ -274,13 +274,13 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
emat = item2->Material;
}
if (foundslot == SLOT_PRIMARY) {
if (foundslot == MainPrimary) {
if (item2->Proc.Effect != 0)
CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);
eslot = MaterialPrimary;
}
else if (foundslot == SLOT_SECONDARY
else if (foundslot == MainSecondary
&& (GetOwner() != nullptr || (GetLevel() >= 13 && MakeRandomInt(0,99) < NPC_DW_CHANCE) || (item2->Damage==0)) &&
(item2->ItemType == ItemType1HSlash || item2->ItemType == ItemType1HBlunt || item2->ItemType == ItemTypeShield ||
item2->ItemType == ItemType1HPiercing))
@ -290,25 +290,25 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
eslot = MaterialSecondary;
}
else if (foundslot == SLOT_HEAD) {
else if (foundslot == MainHead) {
eslot = MaterialHead;
}
else if (foundslot == SLOT_CHEST) {
else if (foundslot == MainChest) {
eslot = MaterialChest;
}
else if (foundslot == SLOT_ARMS) {
else if (foundslot == MainArms) {
eslot = MaterialArms;
}
else if (foundslot == SLOT_BRACER01 || foundslot == SLOT_BRACER02) {
else if (foundslot == MainWrist1 || foundslot == MainWrist2) {
eslot = MaterialWrist;
}
else if (foundslot == SLOT_HANDS) {
else if (foundslot == MainHands) {
eslot = MaterialHands;
}
else if (foundslot == SLOT_LEGS) {
else if (foundslot == MainLegs) {
eslot = MaterialLegs;
}
else if (foundslot == SLOT_FEET) {
else if (foundslot == MainFeet) {
eslot = MaterialFeet;
}

View File

@ -1415,36 +1415,55 @@ luabind::scope lua_register_slot() {
return luabind::class_<Slots>("Slot")
.enum_("constants")
[
luabind::value("Charm", static_cast<int>(SLOT_CHARM)),
luabind::value("Ear1", static_cast<int>(SLOT_EAR01)),
luabind::value("Head", static_cast<int>(SLOT_HEAD)),
luabind::value("Face", static_cast<int>(SLOT_FACE)),
luabind::value("Ear2", static_cast<int>(SLOT_EAR02)),
luabind::value("Neck", static_cast<int>(SLOT_NECK)),
luabind::value("Shoulder", static_cast<int>(SLOT_SHOULDER)),
luabind::value("Arms", static_cast<int>(SLOT_ARMS)),
luabind::value("Back", static_cast<int>(SLOT_BACK)),
luabind::value("Bracer1", static_cast<int>(SLOT_BRACER01)),
luabind::value("Bracer2", static_cast<int>(SLOT_BRACER02)),
luabind::value("Range", static_cast<int>(SLOT_RANGE)),
luabind::value("Hands", static_cast<int>(SLOT_HANDS)),
luabind::value("Primary", static_cast<int>(SLOT_PRIMARY)),
luabind::value("Secondary", static_cast<int>(SLOT_SECONDARY)),
luabind::value("Ring1", static_cast<int>(SLOT_RING01)),
luabind::value("Ring2", static_cast<int>(SLOT_RING02)),
luabind::value("Chest", static_cast<int>(SLOT_CHEST)),
luabind::value("Legs", static_cast<int>(SLOT_LEGS)),
luabind::value("Feet", static_cast<int>(SLOT_FEET)),
luabind::value("Waist", static_cast<int>(SLOT_WAIST)),
luabind::value("Ammo", static_cast<int>(SLOT_AMMO)),
luabind::value("PersonalBegin", static_cast<int>(SLOT_PERSONAL_BEGIN)),
luabind::value("PersonalEnd", static_cast<int>(SLOT_PERSONAL_END)),
luabind::value("Cursor", static_cast<int>(SLOT_CURSOR)),
luabind::value("CursorEnd", 0xFFFE),
luabind::value("Tradeskill", static_cast<int>(SLOT_TRADESKILL)),
luabind::value("Augment", static_cast<int>(SLOT_AUGMENT)),
luabind::value("PowerSource", static_cast<int>(SLOT_POWER_SOURCE)),
luabind::value("Invalid", 0xFFFF)
luabind::value("Charm", static_cast<int>(MainCharm)),
luabind::value("Ear1", static_cast<int>(MainEar1)),
luabind::value("Head", static_cast<int>(MainHead)),
luabind::value("Face", static_cast<int>(MainFace)),
luabind::value("Ear2", static_cast<int>(MainEar2)),
luabind::value("Neck", static_cast<int>(MainNeck)),
luabind::value("Shoulder", static_cast<int>(MainShoulders)), // deprecated
luabind::value("Shoulders", static_cast<int>(MainShoulders)),
luabind::value("Arms", static_cast<int>(MainArms)),
luabind::value("Back", static_cast<int>(MainBack)),
luabind::value("Bracer1", static_cast<int>(MainWrist1)), // deprecated
luabind::value("Wrist1", static_cast<int>(MainWrist1)),
luabind::value("Bracer2", static_cast<int>(MainWrist2)), // deprecated
luabind::value("Wrist2", static_cast<int>(MainWrist2)),
luabind::value("Range", static_cast<int>(MainRange)),
luabind::value("Hands", static_cast<int>(MainHands)),
luabind::value("Primary", static_cast<int>(MainPrimary)),
luabind::value("Secondary", static_cast<int>(MainSecondary)),
luabind::value("Ring1", static_cast<int>(MainFinger1)), // deprecated
luabind::value("Finger1", static_cast<int>(MainFinger1)),
luabind::value("Ring2", static_cast<int>(MainFinger2)), // deprecated
luabind::value("Finger2", static_cast<int>(MainFinger2)),
luabind::value("Chest", static_cast<int>(MainChest)),
luabind::value("Legs", static_cast<int>(MainLegs)),
luabind::value("Feet", static_cast<int>(MainFeet)),
luabind::value("Waist", static_cast<int>(MainWaist)),
luabind::value("PowerSource", static_cast<int>(MainPowerSource)),
luabind::value("Ammo", static_cast<int>(MainAmmo)),
luabind::value("General1", static_cast<int>(MainGeneral1)),
luabind::value("General2", static_cast<int>(MainGeneral2)),
luabind::value("General3", static_cast<int>(MainGeneral3)),
luabind::value("General4", static_cast<int>(MainGeneral4)),
luabind::value("General5", static_cast<int>(MainGeneral5)),
luabind::value("General6", static_cast<int>(MainGeneral6)),
luabind::value("General7", static_cast<int>(MainGeneral7)),
luabind::value("General8", static_cast<int>(MainGeneral8)),
//luabind::value("General9", static_cast<int>(MainGeneral9)),
//luabind::value("General10", static_cast<int>(MainGeneral10)),
luabind::value("Cursor", static_cast<int>(MainCursor)),
//luabind::value("EquipmentBegin", static_cast<int>(EmuConstants::EQUIPMENT_BEGIN)),
//luabind::value("EquipmentEnd", static_cast<int>(EmuConstants::EQUIPMENT_END)),
luabind::value("PersonalBegin", static_cast<int>(EmuConstants::GENERAL_BEGIN)), // deprecated
luabind::value("GeneralBegin", static_cast<int>(EmuConstants::GENERAL_BEGIN)),
luabind::value("PersonalEnd", static_cast<int>(EmuConstants::GENERAL_END)), // deprecated
luabind::value("GeneralEnd", static_cast<int>(EmuConstants::GENERAL_END)),
luabind::value("CursorEnd", 0xFFFE), // deprecated
luabind::value("Tradeskill", static_cast<int>(SLOT_TRADESKILL)), // deprecated
luabind::value("Augment", static_cast<int>(SLOT_AUGMENT)), // deprecated
luabind::value("Invalid", INVALID_INDEX)
];
}
@ -1464,6 +1483,7 @@ luabind::scope lua_register_material() {
luabind::value("Secondary", static_cast<int>(MaterialSecondary)),
luabind::value("Max", static_cast<int>(_MaterialCount)), // deprecated
luabind::value("Count", static_cast<int>(_MaterialCount)),
//luabind::value("TintCount", static_cast<int>(_MaterialCount - 2)),
luabind::value("Invalid", static_cast<int>(_MaterialInvalid))
];
}
@ -1478,7 +1498,8 @@ luabind::scope lua_register_client_version() {
luabind::value("SoF", static_cast<int>(EQClientSoF)),
luabind::value("SoD", static_cast<int>(EQClientSoD)),
luabind::value("Underfoot", static_cast<int>(EQClientUnderfoot)),
luabind::value("RoF", static_cast<int>(EQClientRoF))
luabind::value("RoF", static_cast<int>(EQClientRoF))//,
//luabind::value("RoF2", static_cast<int>(EQClientRoF2))
];
}

View File

@ -266,7 +266,7 @@ void Merc::CalcItemBonuses(StatBonuses* newbon) {
unsigned int i;
//should not include 21 (SLOT_AMMO)
for (i=0; i<SLOT_AMMO; i++) {
for (i=0; i<MainAmmo; i++) {
if(equipment[i] == 0)
continue;
const Item_Struct * itm = database.GetItem(equipment[i]);
@ -277,7 +277,7 @@ void Merc::CalcItemBonuses(StatBonuses* newbon) {
//Power Source Slot
/*if (GetClientVersion() >= EQClientSoF)
{
const ItemInst* inst = m_inv[9999];
const ItemInst* inst = m_inv[MainPowerSource];
if(inst)
AddItemBonuses(inst, newbon);
}*/
@ -1653,24 +1653,24 @@ void Merc::AI_Process() {
//try main hand first
if(attack_timer.Check()) {
Attack(GetTarget(), SLOT_PRIMARY);
Attack(GetTarget(), MainPrimary);
bool tripleSuccess = false;
if(GetOwner() && GetTarget() && CanThisClassDoubleAttack()) {
if(GetOwner()) {
Attack(GetTarget(), SLOT_PRIMARY, true);
Attack(GetTarget(), MainPrimary, true);
}
if(GetOwner() && GetTarget() && GetSpecialAbility(SPECATK_TRIPLE)) {
tripleSuccess = true;
Attack(GetTarget(), SLOT_PRIMARY, true);
Attack(GetTarget(), MainPrimary, true);
}
//quad attack, does this belong here??
if(GetOwner() && GetTarget() && GetSpecialAbility(SPECATK_QUAD)) {
Attack(GetTarget(), SLOT_PRIMARY, true);
Attack(GetTarget(), MainPrimary, true);
}
}
@ -1682,8 +1682,8 @@ void Merc::AI_Process() {
if(MakeRandomInt(0, 100) < flurrychance)
{
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
Attack(GetTarget(), SLOT_PRIMARY, false);
Attack(GetTarget(), SLOT_PRIMARY, false);
Attack(GetTarget(), MainPrimary, false);
Attack(GetTarget(), MainPrimary, false);
}
}
@ -1692,7 +1692,7 @@ void Merc::AI_Process() {
if (GetTarget() && ExtraAttackChanceBonus) {
if(MakeRandomInt(0, 100) < ExtraAttackChanceBonus)
{
Attack(GetTarget(), SLOT_PRIMARY, false);
Attack(GetTarget(), MainPrimary, false);
}
}
}
@ -1727,11 +1727,11 @@ void Merc::AI_Process() {
if (random < DualWieldProbability){ // Max 78% of DW
Attack(GetTarget(), SLOT_SECONDARY); // Single attack with offhand
Attack(GetTarget(), MainSecondary); // Single attack with offhand
if( CanThisClassDoubleAttack()) {
if(GetTarget() && GetTarget()->GetHP() > -10)
Attack(GetTarget(), SLOT_SECONDARY); // Single attack with offhand
Attack(GetTarget(), MainSecondary); // Single attack with offhand
}
}
}
@ -2640,7 +2640,7 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) {
int16 focus_max_real = 0;
//item focus
for(int x =0; x < MAX_WORN_INVENTORY; ++x)
for (int x = 0; x < EmuConstants::EQUIPMENT_SIZE; ++x)
{
TempItem = nullptr;
if (equipment[x] == 0)

View File

@ -48,7 +48,7 @@ public:
//abstract virtual function implementations requird by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill);
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false);
virtual bool Attack(Mob* other, int Hand = SLOT_PRIMARY, bool FromRiposte = false, bool IsStrikethrough = false,
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr);
virtual bool HasRaid() { return false; }
virtual bool HasGroup() { return (GetGroup() ? true : false); }
@ -273,11 +273,11 @@ protected:
std::map<uint32,MercTimer> timers;
uint16 skills[HIGHEST_SKILL+1];
uint32 equipment[MAX_WORN_INVENTORY]; //this is an array of item IDs
uint16 d_meele_texture1; //this is an item Material value
uint16 d_meele_texture2; //this is an item Material value (offhand)
uint8 prim_melee_type; //Sets the Primary Weapon attack message and animation
uint8 sec_melee_type; //Sets the Secondary Weapon attack message and animation
uint32 equipment[EmuConstants::EQUIPMENT_SIZE]; //this is an array of item IDs
uint16 d_meele_texture1; //this is an item Material value
uint16 d_meele_texture2; //this is an item Material value (offhand)
uint8 prim_melee_type; //Sets the Primary Weapon attack message and animation
uint8 sec_melee_type; //Sets the Secondary Weapon attack message and animation
private:

View File

@ -238,9 +238,6 @@ Mob::Mob(const char* in_name,
RangedProcs[j].spellID = SPELL_UNKNOWN;
RangedProcs[j].chance = 0;
RangedProcs[j].base_spellID = SPELL_UNKNOWN;
SkillProcs[j].spellID = SPELL_UNKNOWN;
SkillProcs[j].chance = 0;
SkillProcs[j].base_spellID = SPELL_UNKNOWN;
}
for (i = 0; i < _MaterialCount; i++)
@ -1955,14 +1952,14 @@ void Mob::SetAttackTimer() {
Timer* TimerToUse = nullptr;
const Item_Struct* PrimaryWeapon = nullptr;
for (int i=SLOT_RANGE; i<=SLOT_SECONDARY; i++) {
for (int i=MainRange; i<=MainSecondary; i++) {
//pick a timer
if (i == SLOT_PRIMARY)
if (i == MainPrimary)
TimerToUse = &attack_timer;
else if (i == SLOT_RANGE)
else if (i == MainRange)
TimerToUse = &ranged_timer;
else if(i == SLOT_SECONDARY)
else if(i == MainSecondary)
TimerToUse = &attack_dw_timer;
else //invalid slot (hands will always hit this)
continue;
@ -1983,7 +1980,7 @@ void Mob::SetAttackTimer() {
}
//special offhand stuff
if(i == SLOT_SECONDARY) {
if(i == MainSecondary) {
//if we have a 2H weapon in our main hand, no dual
if(PrimaryWeapon != nullptr) {
if( PrimaryWeapon->ItemClass == ItemClassCommon
@ -2062,7 +2059,7 @@ void Mob::SetAttackTimer() {
if(IsClient())
{
float max_quiver = 0;
for(int r = SLOT_PERSONAL_BEGIN; r <= SLOT_PERSONAL_END; r++)
for(int r = EmuConstants::GENERAL_BEGIN; r <= EmuConstants::GENERAL_END; r++)
{
const ItemInst *pi = CastToClient()->GetInv().GetItem(r);
if(!pi)
@ -2086,7 +2083,7 @@ void Mob::SetAttackTimer() {
TimerToUse->SetAtTrigger(speed, true);
}
if(i == SLOT_PRIMARY)
if(i == MainPrimary)
PrimaryWeapon = ItemToUse;
}
@ -2097,8 +2094,8 @@ bool Mob::CanThisClassDualWield(void) const {
return(GetSkill(SkillDualWield) > 0);
}
else if(CastToClient()->HasSkill(SkillDualWield)) {
const ItemInst* pinst = CastToClient()->GetInv().GetItem(SLOT_PRIMARY);
const ItemInst* sinst = CastToClient()->GetInv().GetItem(SLOT_SECONDARY);
const ItemInst* pinst = CastToClient()->GetInv().GetItem(MainPrimary);
const ItemInst* sinst = CastToClient()->GetInv().GetItem(MainSecondary);
// 2HS, 2HB, or 2HP
if(pinst && pinst->IsWeapon()) {
@ -3033,7 +3030,7 @@ void Mob::TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand, in
if (!on)
return;
on->TryDefensiveProc(weapon, this, hand, damage);
on->TryDefensiveProc(weapon, this, hand);
//Defensive Skill Procs
if (damage < 0 && damage >= -4) {
@ -4702,6 +4699,11 @@ uint16 Mob::GetSkillByItemType(int ItemType)
return Skill2HBlunt;
case ItemType2HPiercing:
return Skill1HPiercing; // change to 2HPiercing once activated
case ItemTypeBow:
return SkillArchery;
case ItemTypeLargeThrowing:
case ItemTypeSmallThrowing:
return SkillThrowing;
case ItemTypeMartial:
return SkillHandtoHand;
default:
@ -4710,6 +4712,32 @@ uint16 Mob::GetSkillByItemType(int ItemType)
return SkillHandtoHand;
}
uint8 Mob::GetItemTypeBySkill(SkillUseTypes skill)
{
switch (skill)
{
case SkillThrowing:
return ItemTypeSmallThrowing;
case SkillArchery:
return ItemTypeArrow;
case Skill1HSlashing:
return ItemType1HSlash;
case Skill2HSlashing:
return ItemType2HSlash;
case Skill1HPiercing:
return ItemType1HPiercing;
case Skill1HBlunt:
return ItemType1HBlunt;
case Skill2HBlunt:
return ItemType2HBlunt;
case SkillHandtoHand:
return ItemTypeMartial;
default:
return ItemTypeMartial;
}
return ItemTypeMartial;
}
bool Mob::PassLimitToSkill(uint16 spell_id, uint16 skill) {

View File

@ -131,11 +131,11 @@ public:
virtual void ThrowingAttack(Mob* other) { }
uint16 GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg);
// 13 = Primary (default), 14 = secondary
virtual bool Attack(Mob* other, int Hand = 13, bool FromRiposte = false, bool IsStrikethrough = false,
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) = 0;
int MonkSpecialAttack(Mob* other, uint8 skill_used);
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
void TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand = 13, int damage = 0);
void TriggerDefensiveProcs(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary, int damage = 0);
virtual bool AvoidDamage(Mob* attacker, int32 &damage, bool CanRiposte = true);
virtual bool CheckHitChance(Mob* attacker, SkillUseTypes skillinuse, int Hand, int16 chance_mod = 0);
virtual void TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttackOptions *opts = nullptr);
@ -150,6 +150,9 @@ public:
bool CombatRange(Mob* other);
virtual inline bool IsBerserk() { return false; } // only clients
void RogueEvade(Mob *other);
void CommonOutgoingHitSuccess(Mob* defender, int32 &damage, SkillUseTypes skillInUse);
void CommonBreakInvisible();
bool HasDied();
//Appearance
void SendLevelAppearance();
@ -164,7 +167,7 @@ public:
virtual void WearChange(uint8 material_slot, uint16 texture, uint32 color);
void DoAnim(const int animnum, int type=0, bool ackreq = true, eqFilterType filter = FilterNone);
void ProjectileAnimation(Mob* to, int item_id, bool IsArrow = false, float speed = 0,
float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr);
float angle = 0, float tilt = 0, float arc = 0, const char *IDFile = nullptr, SkillUseTypes skillInUse = SkillArchery);
void ChangeSize(float in_size, bool bNoRestriction = false);
inline uint8 SeeInvisible() const { return see_invis; }
inline bool SeeInvisibleUndead() const { return see_invis_undead; }
@ -480,6 +483,7 @@ public:
static uint32 RandomTimer(int min, int max);
static uint8 GetDefaultGender(uint16 in_race, uint8 in_gender = 0xFF);
uint16 GetSkillByItemType(int ItemType);
uint8 GetItemTypeBySkill(SkillUseTypes skill);
virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr);
virtual void MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, const char *petname = nullptr, float in_size = 0.0f);
bool IsWarriorClass() const;
@ -819,7 +823,7 @@ public:
void SetNextIncHPEvent( int inchpevent );
inline bool DivineAura() const { return spellbonuses.DivineAura; }
inline bool Sanctuary() const { return spellbonuses.Sanctuary; }
inline bool Sanctuary() const { return spellbonuses.Sanctuary; }
bool HasNPCSpecialAtk(const char* parse);
int GetSpecialAbility(int ability);
@ -986,26 +990,25 @@ protected:
bool focused;
void CalcSpellBonuses(StatBonuses* newbon);
virtual void CalcBonuses();
void TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success = false, uint16 hand = 0, bool IsDefensive = false);
void TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success = false, uint16 hand = 0, bool IsDefensive = false); // hand = MainCharm?
bool PassLimitToSkill(uint16 spell_id, uint16 skill);
bool PassLimitClass(uint32 Classes_, uint16 Class_);
void TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand = 13, int damage=0);
void TryWeaponProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = 13);
void TrySpellProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = 13);
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = 13);
void TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
void TryWeaponProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary);
void TrySpellProc(const ItemInst* inst, const Item_Struct* weapon, Mob *on, uint16 hand = MainPrimary);
void TryWeaponProc(const ItemInst* weapon, Mob *on, uint16 hand = MainPrimary);
void ExecWeaponProc(const ItemInst* weapon, uint16 spell_id, Mob *on);
virtual float GetProcChances(float ProcBonus, uint16 weapon_speed = 30, uint16 hand = 13);
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 weapon_speed = 30, uint16 hand = 13);
virtual float GetProcChances(float ProcBonus, uint16 hand = MainPrimary);
virtual float GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 hand = MainPrimary, Mob *on = nullptr);
virtual float GetSpecialProcChances(uint16 hand);
virtual float GetAssassinateProcChances(uint16 ReuseTime);
virtual float GetSkillProcChances(uint16 ReuseTime, uint16 hand = 0);
virtual float GetSkillProcChances(uint16 ReuseTime, uint16 hand = 0); // hand = MainCharm?
uint16 GetWeaponSpeedbyHand(uint16 hand);
int GetWeaponDamage(Mob *against, const Item_Struct *weapon_item);
int GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate = nullptr);
int GetKickDamage();
int GetBashDamage();
virtual void ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg);
bool HasDied();
void CalculateNewFearpoint();
float FindGroundZ(float new_x, float new_y, float z_offset=0.0);
Map::Vertex UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &WaypointChange, bool &NodeReached);
@ -1018,7 +1021,6 @@ protected:
tProc SpellProcs[MAX_PROCS];
tProc DefensiveProcs[MAX_PROCS];
tProc RangedProcs[MAX_PROCS];
tProc SkillProcs[MAX_PROCS];
char name[64];
char orig_name[64];

View File

@ -194,6 +194,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
}
accuracy_rating = d->accuracy_rating;
avoidance_rating = d->avoidance_rating;
ATK = d->ATK;
CalcMaxMana();
@ -259,9 +260,11 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
d_meele_texture1 = d->d_meele_texture1;
d_meele_texture2 = d->d_meele_texture2;
ammo_idfile = d->ammo_idfile;
memset(equipment, 0, sizeof(equipment));
prim_melee_type = d->prim_melee_type;
sec_melee_type = d->sec_melee_type;
ranged_type = d->ranged_type;
// If Melee Textures are not set, set attack type to Hand to Hand as default
if(!d_meele_texture1)
@ -1296,7 +1299,7 @@ void NPC::PickPocket(Client* thief) {
bool is_arrow = (item->ItemType == ItemTypeArrow) ? true : false;
int slot_id = thief->GetInv().FindFreeSlot(false, true, inst->GetItem()->Size, is_arrow);
if (/*!Equipped(item->ID) &&*/
!item->Magic && item->NoDrop != 0 && !inst->IsType(ItemClassContainer) && slot_id != SLOT_INVALID
!item->Magic && item->NoDrop != 0 && !inst->IsType(ItemClassContainer) && slot_id != INVALID_INDEX
/*&& steal_skill > item->StealSkill*/ )
{
slot[x] = slot_id;
@ -1925,6 +1928,12 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
return;
}
if(id == "avoidance")
{
avoidance_rating = atoi(val.c_str());
return;
}
if(id == "trackable")
{
trackable = atoi(val.c_str());

View File

@ -73,6 +73,22 @@ struct AISpellsEffects_Struct {
int32 max;
};
struct AISpellsVar_Struct {
uint32 fail_recast;
uint32 engaged_no_sp_recast_min;
uint32 engaged_no_sp_recast_max;
uint8 engaged_beneficial_self_chance;
uint8 engaged_beneficial_other_chance;
uint8 engaged_detrimental_chance;
uint32 pursue_no_sp_recast_min;
uint32 pursue_no_sp_recast_max;
uint8 pursue_detrimental_chance;
uint32 idle_no_sp_recast_min;
uint32 idle_no_sp_recast_max;
uint8 idle_beneficial_chance;
};
class AA_SwarmPetInfo;
class NPC : public Mob
@ -88,7 +104,7 @@ public:
//abstract virtual function implementations requird by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill);
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false);
virtual bool Attack(Mob* other, int Hand = 13, bool FromRiposte = false, bool IsStrikethrough = false,
virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = false,
bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr);
virtual bool HasRaid() { return false; }
virtual bool HasGroup() { return false; }
@ -215,8 +231,10 @@ public:
uint8 GetPrimSkill() const { return prim_melee_type; }
uint8 GetSecSkill() const { return sec_melee_type; }
uint8 GetRangedSkill() const { return ranged_type; }
void SetPrimSkill(uint8 skill_type) { prim_melee_type = skill_type; }
void SetSecSkill(uint8 skill_type) { sec_melee_type = skill_type; }
void SetRangedSkill(uint8 skill_type) { ranged_type = skill_type; }
uint32 MerchantType;
bool merchant_open;
@ -257,6 +275,7 @@ public:
void CheckSignal();
inline bool IsTargetableWithHotkey() const { return no_target_hotkey; }
int32 GetNPCHPRegen() const { return hp_regen + itembonuses.HPRegen + spellbonuses.HPRegen; }
inline const char* GetAmmoIDfile() const { return ammo_idfile; }
//waypoint crap
int GetMaxWp() const { return max_wp; }
@ -314,6 +333,8 @@ public:
int32 GetAccuracyRating() const { return (accuracy_rating); }
void SetAccuracyRating(int32 d) { accuracy_rating = d;}
int32 GetAvoidanceRating() const { return (avoidance_rating); }
void SetAvoidanceRating(int32 d) { avoidance_rating = d;}
int32 GetRawAC() const { return AC; }
void ModifyNPCStat(const char *identifier, const char *newValue);
@ -413,14 +434,16 @@ protected:
bool HasAISpell;
virtual bool AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes);
virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
AISpellsVar_Struct AISpellVar;
uint32 npc_spells_effects_id;
std::vector<AISpellsEffects_Struct> AIspellsEffects;
bool HasAISpellEffects;
uint32 max_dmg;
uint32 min_dmg;
int32 accuracy_rating;
int32 avoidance_rating;
int16 attack_count;
uint32 npc_mana;
float spellscale;
@ -454,11 +477,15 @@ protected:
uint32 roambox_min_delay;
uint16 skills[HIGHEST_SKILL+1];
uint32 equipment[MAX_WORN_INVENTORY]; //this is an array of item IDs
uint32 equipment[EmuConstants::EQUIPMENT_SIZE]; //this is an array of item IDs
uint16 d_meele_texture1; //this is an item Material value
uint16 d_meele_texture2; //this is an item Material value (offhand)
const char* ammo_idfile; //this determines projectile graphic "IT###" (see item field 'idfile')
uint8 prim_melee_type; //Sets the Primary Weapon attack message and animation
uint8 sec_melee_type; //Sets the Secondary Weapon attack message and animation
uint8 ranged_type; //Sets the Ranged Weapon attack message and animation
AA_SwarmPetInfo *swarmInfoPtr;
bool ldon_trapped;

View File

@ -872,7 +872,7 @@ XS(XS_Mob_Attack)
Perl_croak(aTHX_ "other is nullptr, avoiding crash.");
if (items < 3)
Hand = 13;
Hand = MainPrimary;
else {
Hand = (int)SvIV(ST(2));
}

View File

@ -411,12 +411,12 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
// the base items for the pet. These are always loaded
// so that a rank 1 suspend minion does not kill things
// like the special back items some focused pets may receive.
uint32 petinv[MAX_WORN_INVENTORY];
uint32 petinv[EmuConstants::EQUIPMENT_SIZE];
memset(petinv, 0, sizeof(petinv));
const Item_Struct *item = 0;
if (database.GetBasePetItems(record.equipmentset, petinv)) {
for (int i=0; i<MAX_WORN_INVENTORY; i++)
for (int i = 0; i<EmuConstants::EQUIPMENT_SIZE; i++)
if (petinv[i]) {
item = database.GetItem(petinv[i]);
npc->AddLootDrop(item, &npc->itemlist, 0, 1, 127, true, true);
@ -543,7 +543,7 @@ void NPC::GetPetState(SpellBuff_Struct *pet_buffs, uint32 *items, char *name) {
strn0cpy(name, GetName(), 64);
//save their items, we only care about what they are actually wearing
memcpy(items, equipment, sizeof(uint32)*MAX_WORN_INVENTORY);
memcpy(items, equipment, sizeof(uint32)*EmuConstants::EQUIPMENT_SIZE);
//save their buffs.
for (int i=0; i < GetPetMaxTotalSlots(); i++) {
@ -629,7 +629,7 @@ void NPC::SetPetState(SpellBuff_Struct *pet_buffs, uint32 *items) {
}
//restore their equipment...
for(i = 0; i < MAX_WORN_INVENTORY; i++) {
for (i = 0; i < EmuConstants::EQUIPMENT_SIZE; i++) {
if(items[i] == 0)
continue;
@ -693,7 +693,7 @@ bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) {
while ((row = mysql_fetch_row(result)))
{
slot = atoi(row[0]);
if (slot >= MAX_WORN_INVENTORY)
if (slot >= EmuConstants::EQUIPMENT_SIZE)
continue;
if (items[slot] == 0)
items[slot] = atoi(row[1]);

View File

@ -2429,12 +2429,12 @@ int QuestManager::collectitems(uint32 item_id, bool remove)
int quantity = 0;
int slot_id;
for (slot_id = 22; slot_id <= 29; ++slot_id)
for (slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; ++slot_id)
{
quantity += collectitems_processSlot(slot_id, item_id, remove);
}
for (slot_id = 251; slot_id <= 330; ++slot_id)
for (slot_id = EmuConstants::GENERAL_BAGS_BEGIN; slot_id <= EmuConstants::GENERAL_BAGS_END; ++slot_id)
{
quantity += collectitems_processSlot(slot_id, item_id, remove);
}

View File

@ -74,17 +74,17 @@ void Mob::ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg)
case SkillFlyingKick:
case SkillRoundKick:
case SkillKick:
item_slot = SLOT_FEET;
item_slot = MainFeet;
break;
case SkillBash:
item_slot = SLOT_SECONDARY;
item_slot = MainSecondary;
break;
case SkillDragonPunch:
case SkillEagleStrike:
case SkillTigerClaw:
item_slot = SLOT_HANDS;
item_slot = MainHands;
break;
default:
@ -105,6 +105,9 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
//this really should go through the same code as normal melee damage to
//pick up all the special behavior there
if (!who)
return;
int32 hate = max_damage;
if(hate_override > -1)
hate = hate_override;
@ -113,7 +116,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
{
if(IsClient())
{
ItemInst *item = CastToClient()->GetInv().GetItem(SLOT_SECONDARY);
ItemInst *item = CastToClient()->GetInv().GetItem(MainSecondary);
if(item)
{
if(item->GetItem()->ItemType == ItemTypeShield)
@ -128,7 +131,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
min_damage += min_damage * GetMeleeMinDamageMod_SE(skill) / 100;
if(HitChance && !who->CheckHitChance(this, skill, 13))
if(HitChance && !who->CheckHitChance(this, skill, MainPrimary))
max_damage = 0;
else{
@ -141,26 +144,18 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
who->MeleeMitigation(this, max_damage, min_damage);
if(max_damage > 0) {
ApplyMeleeDamageBonus(skill, max_damage);
max_damage += who->GetFcDamageAmtIncoming(this, 0, true, skill);
max_damage += (itembonuses.HeroicSTR / 10) + (max_damage * who->GetSkillDmgTaken(skill) / 100) + GetSkillDmgAmt(skill);
TryCriticalHit(who, skill, max_damage);
}
if(max_damage > 0)
CommonOutgoingHitSuccess(who, max_damage, skill);
}
if(max_damage >= 0) //You should probably get aggro no matter what, but unclear why it was set like this.
who->AddToHateList(this, hate);
who->AddToHateList(this, hate, 0, false);
who->Damage(this, max_damage, SPELL_UNKNOWN, skill, false);
//Make sure 'this' has not killed the target and 'this' is not dead (Damage shield ect).
if(!GetTarget())return;
if (HasDied()) return;
if (max_damage > 0)
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
//[AA Dragon Punch] value[0] = 100 for 25%, chance value[1] = skill
if(aabonuses.SpecialAttackKBProc[0] && aabonuses.SpecialAttackKBProc[1] == skill){
int kb_chance = 25;
@ -200,7 +195,7 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
//These two are not subject to the combat ability timer, as they
//allready do their checking in conjunction with the attack timer
//throwing weapons
if(ca_atk->m_atk == 11) {
if(ca_atk->m_atk == MainRange) {
if (ca_atk->m_skill == SkillThrowing) {
SetAttackTimer();
ThrowingAttack(GetTarget());
@ -242,6 +237,7 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
int32 skill_reduction = this->GetSkillReuseTime(ca_atk->m_skill);
// not sure what the '100' indicates..if ->m_atk is not used as 'slot' reference, then change MainRange above back to '11'
if ((ca_atk->m_atk == 100) && (ca_atk->m_skill == SkillBash)) { // SLAM - Bash without a shield equipped
if (GetTarget() != this) {
@ -249,8 +245,8 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
DoAnim(animTailRake);
int32 ht = 0;
if(GetWeaponDamage(GetTarget(), GetInv().GetItem(SLOT_SECONDARY)) <= 0 &&
GetWeaponDamage(GetTarget(), GetInv().GetItem(SLOT_SHOULDER)) <= 0){
if(GetWeaponDamage(GetTarget(), GetInv().GetItem(MainSecondary)) <= 0 &&
GetWeaponDamage(GetTarget(), GetInv().GetItem(MainShoulders)) <= 0){
dmg = -5;
}
else{
@ -329,7 +325,7 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
DoAnim(animKick);
int32 ht = 0;
if(GetWeaponDamage(GetTarget(), GetInv().GetItem(SLOT_FEET)) <= 0){
if(GetWeaponDamage(GetTarget(), GetInv().GetItem(MainFeet)) <= 0){
dmg = -5;
}
else{
@ -405,7 +401,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type)
int32 min_dmg = 1;
int reuse = 0;
SkillUseTypes skill_type; //to avoid casting... even though it "would work"
uint8 itemslot = SLOT_FEET;
uint8 itemslot = MainFeet;
switch(unchecked_type)
{
@ -421,7 +417,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type)
case SkillDragonPunch:{
skill_type = SkillDragonPunch;
max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, DragonPunchBonus) / 100) + 26;
itemslot = SLOT_HANDS;
itemslot = MainHands;
ApplySpecialAttackMod(skill_type, max_dmg, min_dmg);
DoAnim(animTailRake);
reuse = TailRakeReuseTime;
@ -431,7 +427,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type)
case SkillEagleStrike:{
skill_type = SkillEagleStrike;
max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, EagleStrikeBonus) / 100) + 19;
itemslot = SLOT_HANDS;
itemslot = MainHands;
ApplySpecialAttackMod(skill_type, max_dmg, min_dmg);
DoAnim(animEagleStrike);
reuse = EagleStrikeReuseTime;
@ -441,7 +437,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type)
case SkillTigerClaw:{
skill_type = SkillTigerClaw;
max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, TigerClawBonus) / 100) + 12;
itemslot = SLOT_HANDS;
itemslot = MainHands;
ApplySpecialAttackMod(skill_type, max_dmg, min_dmg);
DoAnim(animTigerClaw);
reuse = TigerClawReuseTime;
@ -511,7 +507,7 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) {
//make sure we have a proper weapon if we are a client.
if(IsClient()) {
const ItemInst *wpn = CastToClient()->GetInv().GetItem(SLOT_PRIMARY);
const ItemInst *wpn = CastToClient()->GetInv().GetItem(MainPrimary);
if(!wpn || (wpn->GetItem()->ItemType != ItemType1HPiercing)){
Message_StringID(13, BACKSTAB_WEAPON);
return;
@ -574,7 +570,7 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) {
CastToClient()->CheckIncreaseSkill(SkillBackstab, other, 10);
}
else { //We do a single regular attack if we attack from the front without chaotic stab
Attack(other, 13);
Attack(other, MainPrimary);
}
}
@ -593,11 +589,11 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
if(IsClient()){
const ItemInst *wpn = nullptr;
wpn = CastToClient()->GetInv().GetItem(SLOT_PRIMARY);
wpn = CastToClient()->GetInv().GetItem(MainPrimary);
if(wpn) {
primaryweapondamage = GetWeaponDamage(other, wpn);
backstab_dmg = wpn->GetItem()->BackstabDmg;
for(int i = 0; i < MAX_AUGMENT_SLOTS; ++i)
for (int i = 0; i < EmuConstants::ITEM_COMMON_SIZE; ++i)
{
ItemInst *aug = wpn->GetAugment(i);
if(aug)
@ -676,7 +672,7 @@ void Mob::RogueAssassinate(Mob* other)
{
//can you dodge, parry, etc.. an assassinate??
//if so, use DoSpecialAttackDamage(other, BACKSTAB, 32000); instead
if(GetWeaponDamage(other, IsClient()?CastToClient()->GetInv().GetItem(SLOT_PRIMARY):(const ItemInst*)nullptr) > 0){
if(GetWeaponDamage(other, IsClient()?CastToClient()->GetInv().GetItem(MainPrimary):(const ItemInst*)nullptr) > 0){
other->Damage(this, 32000, SPELL_UNKNOWN, SkillBackstab);
}else{
other->Damage(this, -5, SPELL_UNKNOWN, SkillBackstab);
@ -695,20 +691,20 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
//Message(0, "Error: Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
return;
}
const ItemInst* RangeWeapon = m_inv[SLOT_RANGE];
const ItemInst* RangeWeapon = m_inv[MainRange];
//locate ammo
int ammo_slot = SLOT_AMMO;
const ItemInst* Ammo = m_inv[SLOT_AMMO];
int ammo_slot = MainAmmo;
const ItemInst* Ammo = m_inv[MainAmmo];
if (!RangeWeapon || !RangeWeapon->IsType(ItemClassCommon)) {
mlog(COMBAT__RANGED, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(SLOT_RANGE), SLOT_RANGE);
Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have no bow!", GetItemIDAt(SLOT_RANGE));
mlog(COMBAT__RANGED, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(MainRange), MainRange);
Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have no bow!", GetItemIDAt(MainRange));
return;
}
if (!Ammo || !Ammo->IsType(ItemClassCommon)) {
mlog(COMBAT__RANGED, "Ranged attack canceled. Missing or invalid ammo item (%d) in slot %d", GetItemIDAt(SLOT_AMMO), SLOT_AMMO);
Message(0, "Error: Ammo: GetItem(%i)==0, you have no ammo!", GetItemIDAt(SLOT_AMMO));
mlog(COMBAT__RANGED, "Ranged attack canceled. Missing or invalid ammo item (%d) in slot %d", GetItemIDAt(MainAmmo), MainAmmo);
Message(0, "Error: Ammo: GetItem(%i)==0, you have no ammo!", GetItemIDAt(MainAmmo));
return;
}
@ -733,7 +729,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
//first look for quivers
int r;
bool found = false;
for(r = SLOT_PERSONAL_BEGIN; r <= SLOT_PERSONAL_END; r++) {
for(r = EmuConstants::GENERAL_BEGIN; r <= EmuConstants::GENERAL_END; r++) {
const ItemInst *pi = m_inv[r];
if(pi == nullptr || !pi->IsType(ItemClassContainer))
continue;
@ -765,7 +761,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
//if we dont find a quiver, look through our inventory again
//not caring if the thing is a quiver.
int32 aslot = m_inv.HasItem(AmmoItem->ID, 1, invWherePersonal);
if(aslot != SLOT_INVALID) {
if (aslot != INVALID_INDEX) {
ammo_slot = aslot;
Ammo = m_inv[aslot];
mlog(COMBAT__RANGED, "Using ammo from inventory stack at slot %d. %d in stack.", ammo_slot, Ammo->GetCharges());
@ -813,39 +809,7 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
CheckIncreaseSkill(SkillArchery, GetTarget(), -15);
//break invis when you attack
if(invisible) {
mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack.");
BuffFadeByEffect(SE_Invisibility);
BuffFadeByEffect(SE_Invisibility2);
invisible = false;
}
if(invisible_undead) {
mlog(COMBAT__ATTACKS, "Removing invisibility vs. undead due to melee attack.");
BuffFadeByEffect(SE_InvisVsUndead);
BuffFadeByEffect(SE_InvisVsUndead2);
invisible_undead = false;
}
if(invisible_animals){
mlog(COMBAT__ATTACKS, "Removing invisibility vs. animals due to melee attack.");
BuffFadeByEffect(SE_InvisVsAnimals);
invisible_animals = false;
}
if (spellbonuses.NegateIfCombat)
BuffFadeByEffect(SE_NegateIfCombat);
if(hidden || improved_hidden){
hidden = false;
improved_hidden = false;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
sa_out->spawn_id = GetID();
sa_out->type = 0x03;
sa_out->parameter = 0;
entity_list.QueueClients(this, outapp, true);
safe_delete(outapp);
}
CommonBreakInvisible();
}
void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime)
@ -853,7 +817,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item
if (!CanDoSpecialAttack(other))
return;
if (!other->CheckHitChance(this, SkillArchery, 13,chance_mod)) {
if (!other->CheckHitChance(this, SkillArchery, MainPrimary, chance_mod)) {
mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName());
other->Damage(this, 0, SPELL_UNKNOWN, SkillArchery);
} else {
@ -975,27 +939,27 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item
if (ReuseTime)
TrySkillProc(other, SkillArchery, ReuseTime);
else
TrySkillProc(other, SkillArchery, 0, true, 11);
TrySkillProc(other, SkillArchery, 0, true, MainRange);
}
}
//try proc on hits and misses
if((RangeWeapon != nullptr) && GetTarget() && other && !other->HasDied())
{
TryWeaponProc(RangeWeapon, other, 11);
TryWeaponProc(RangeWeapon, other, MainRange);
}
//Arrow procs because why not?
if((Ammo != NULL) && GetTarget() && other && !other->HasDied())
{
TryWeaponProc(Ammo, other, 11);
TryWeaponProc(Ammo, other, MainRange);
}
if (HasSkillProcs() && GetTarget() && other && !other->HasDied()){
if (ReuseTime)
TrySkillProc(other, SkillArchery, ReuseTime);
else
TrySkillProc(other, SkillArchery, 0, false, 11);
TrySkillProc(other, SkillArchery, 0, false, MainRange);
}
}
@ -1018,19 +982,30 @@ void NPC::RangedAttack(Mob* other)
return;
}
float range = 250; // needs to be longer than 200(most spells)
mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", range);
range *= range;
if(DistNoRootNoZ(*GetTarget()) > range) {
mlog(COMBAT__RANGED, "Ranged attack out of range...%.2f vs %.2f", DistNoRootNoZ(*GetTarget()), range);
int sa_min_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 0); //Min Range of NPC attack
int sa_max_range = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 1); //Max Range of NPC attack
float min_range = static_cast<float>(RuleI(Combat, MinRangedAttackDist));
float max_range = 250; // needs to be longer than 200(most spells)
if (sa_max_range)
max_range = static_cast<float>(sa_max_range);
if (sa_min_range)
min_range = static_cast<float>(sa_min_range);
mlog(COMBAT__RANGED, "Calculated bow range to be %.1f", max_range);
max_range *= max_range;
if(DistNoRootNoZ(*other) > max_range) {
mlog(COMBAT__RANGED, "Ranged attack out of range...%.2f vs %.2f", DistNoRootNoZ(*other), max_range);
//target is out of range, client does a message
return;
}
else if(DistNoRootNoZ(*GetTarget()) < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
else if(DistNoRootNoZ(*other) < (min_range * min_range))
return;
}
if(!IsAttackAllowed(GetTarget()) ||
if(!other || !IsAttackAllowed(other) ||
IsCasting() ||
DivineAura() ||
IsStunned() ||
@ -1040,32 +1015,33 @@ void NPC::RangedAttack(Mob* other)
return;
}
if(!ammo)
{
SkillUseTypes skillinuse = SkillArchery;
skillinuse = static_cast<SkillUseTypes>(GetRangedSkill());
if(!ammo && !GetAmmoIDfile())
ammo = database.GetItem(8005);
}
if(ammo)
SendItemAnimation(GetTarget(), ammo, SkillArchery);
SendItemAnimation(other, ammo, SkillArchery);
else
ProjectileAnimation(other, 0,false,0,0,0,0,GetAmmoIDfile(),skillinuse);
FaceTarget(other);
// Face the Target
FaceTarget(GetTarget());
// Hit?
if (!GetTarget()->CheckHitChance(this, SkillArchery, 13))
if (!other->CheckHitChance(this, skillinuse, MainRange, GetSpecialAbilityParam(SPECATK_RANGED_ATK, 2)))
{
mlog(COMBAT__RANGED, "Ranged attack missed %s.", GetTarget()->GetName());
GetTarget()->Damage(this, 0, SPELL_UNKNOWN, SkillArchery);
mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName());
other->Damage(this, 0, SPELL_UNKNOWN, skillinuse);
}
else
{
int16 WDmg = GetWeaponDamage(GetTarget(), weapon);
int16 ADmg = GetWeaponDamage(GetTarget(), ammo);
int16 WDmg = GetWeaponDamage(other, weapon);
int16 ADmg = GetWeaponDamage(other, ammo);
int32 TotalDmg = 0;
if(WDmg > 0 || ADmg > 0)
{
mlog(COMBAT__RANGED, "Ranged attack hit %s.", GetTarget()->GetName());
int32 TotalDmg = 0;
mlog(COMBAT__RANGED, "Ranged attack hit %s.", other->GetName());
int32 MaxDmg = max_dmg * RuleR(Combat, ArcheryNPCMultiplier); // should add a field to npc_types
int32 MinDmg = min_dmg * RuleR(Combat, ArcheryNPCMultiplier);
@ -1074,54 +1050,36 @@ void NPC::RangedAttack(Mob* other)
else
TotalDmg = MakeRandomInt(MinDmg, MaxDmg);
int32 hate = TotalDmg;
GetTarget()->MeleeMitigation(this, TotalDmg, MinDmg);
ApplyMeleeDamageBonus(SkillArchery, TotalDmg);
TryCriticalHit(GetTarget(), SkillArchery, TotalDmg);
GetTarget()->AddToHateList(this, hate, 0, false);
GetTarget()->Damage(this, TotalDmg, SPELL_UNKNOWN, SkillArchery);
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
TotalDmg += TotalDmg * GetSpecialAbilityParam(SPECATK_RANGED_ATK, 3) / 100; //Damage modifier
other->AvoidDamage(this, TotalDmg, false);
other->MeleeMitigation(this, TotalDmg, MinDmg);
if (TotalDmg > 0)
CommonOutgoingHitSuccess(other, TotalDmg, skillinuse);
}
else
{
GetTarget()->Damage(this, -5, SPELL_UNKNOWN, SkillArchery);
}
TotalDmg = -5;
if (TotalDmg > 0)
other->AddToHateList(this, TotalDmg, 0, false);
else
other->AddToHateList(this, 0, 0, false);
other->Damage(this, TotalDmg, SPELL_UNKNOWN, skillinuse);
if (TotalDmg > 0 && HasSkillProcSuccess() && GetTarget() && !other->HasDied())
TrySkillProc(other, skillinuse, 0, true, MainRange);
}
//break invis when you attack
if(invisible) {
mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack.");
BuffFadeByEffect(SE_Invisibility);
BuffFadeByEffect(SE_Invisibility2);
invisible = false;
}
if(invisible_undead) {
mlog(COMBAT__ATTACKS, "Removing invisibility vs. undead due to melee attack.");
BuffFadeByEffect(SE_InvisVsUndead);
BuffFadeByEffect(SE_InvisVsUndead2);
invisible_undead = false;
}
if(invisible_animals){
mlog(COMBAT__ATTACKS, "Removing invisibility vs. animals due to melee attack.");
BuffFadeByEffect(SE_InvisVsAnimals);
invisible_animals = false;
}
//try proc on hits and misses
if(other && !other->HasDied())
TrySpellProc(nullptr, (const Item_Struct*)nullptr, other, MainRange);
if (spellbonuses.NegateIfCombat)
BuffFadeByEffect(SE_NegateIfCombat);
if (HasSkillProcs() && other && !other->HasDied())
TrySkillProc(other, skillinuse, 0, false, MainRange);
if(hidden || improved_hidden){
hidden = false;
improved_hidden = false;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
sa_out->spawn_id = GetID();
sa_out->type = 0x03;
sa_out->parameter = 0;
entity_list.QueueClients(this, outapp, true);
safe_delete(outapp);
}
CommonBreakInvisible();
}
uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg)
@ -1165,19 +1123,19 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
return;
}
int ammo_slot = SLOT_RANGE;
const ItemInst* RangeWeapon = m_inv[SLOT_RANGE];
int ammo_slot = MainRange;
const ItemInst* RangeWeapon = m_inv[MainRange];
if (!RangeWeapon || !RangeWeapon->IsType(ItemClassCommon)) {
mlog(COMBAT__RANGED, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(SLOT_RANGE), SLOT_RANGE);
Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing to throw!", GetItemIDAt(SLOT_RANGE));
mlog(COMBAT__RANGED, "Ranged attack canceled. Missing or invalid ranged weapon (%d) in slot %d", GetItemIDAt(MainRange), MainRange);
Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing to throw!", GetItemIDAt(MainRange));
return;
}
const Item_Struct* item = RangeWeapon->GetItem();
if(item->ItemType != ItemTypeLargeThrowing && item->ItemType != ItemTypeSmallThrowing) {
mlog(COMBAT__RANGED, "Ranged attack canceled. Ranged item %d is not a throwing weapon. type %d.", item->ItemType);
Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing useful to throw!", GetItemIDAt(SLOT_RANGE));
Message(0, "Error: Rangeweapon: GetItem(%i)==0, you have nothing useful to throw!", GetItemIDAt(MainRange));
return;
}
@ -1185,16 +1143,16 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
if(RangeWeapon->GetCharges() == 1) {
//first check ammo
const ItemInst* AmmoItem = m_inv[SLOT_AMMO];
const ItemInst* AmmoItem = m_inv[MainAmmo];
if(AmmoItem != nullptr && AmmoItem->GetID() == RangeWeapon->GetID()) {
//more in the ammo slot, use it
RangeWeapon = AmmoItem;
ammo_slot = SLOT_AMMO;
ammo_slot = MainAmmo;
mlog(COMBAT__RANGED, "Using ammo from ammo slot, stack at slot %d. %d in stack.", ammo_slot, RangeWeapon->GetCharges());
} else {
//look through our inventory for more
int32 aslot = m_inv.HasItem(item->ID, 1, invWherePersonal);
if(aslot != SLOT_INVALID) {
if (aslot != INVALID_INDEX) {
//the item wont change, but the instance does, not that it matters
ammo_slot = aslot;
RangeWeapon = m_inv[aslot];
@ -1234,39 +1192,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
DeleteItemInInventory(ammo_slot, 1, true);
CheckIncreaseSkill(SkillThrowing, GetTarget());
//break invis when you attack
if(invisible) {
mlog(COMBAT__ATTACKS, "Removing invisibility due to melee attack.");
BuffFadeByEffect(SE_Invisibility);
BuffFadeByEffect(SE_Invisibility2);
invisible = false;
}
if(invisible_undead) {
mlog(COMBAT__ATTACKS, "Removing invisibility vs. undead due to melee attack.");
BuffFadeByEffect(SE_InvisVsUndead);
BuffFadeByEffect(SE_InvisVsUndead2);
invisible_undead = false;
}
if(invisible_animals){
mlog(COMBAT__ATTACKS, "Removing invisibility vs. animals due to melee attack.");
BuffFadeByEffect(SE_InvisVsAnimals);
invisible_animals = false;
}
if (spellbonuses.NegateIfCombat)
BuffFadeByEffect(SE_NegateIfCombat);
if(hidden || improved_hidden){
hidden = false;
improved_hidden = false;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
SpawnAppearance_Struct* sa_out = (SpawnAppearance_Struct*)outapp->pBuffer;
sa_out->spawn_id = GetID();
sa_out->type = 0x03;
sa_out->parameter = 0;
entity_list.QueueClients(this, outapp, true);
safe_delete(outapp);
}
CommonBreakInvisible();
}
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* item, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime)
@ -1274,7 +1200,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
if (!CanDoSpecialAttack(other))
return;
if (!other->CheckHitChance(this, SkillThrowing, 13, chance_mod)){
if (!other->CheckHitChance(this, SkillThrowing, MainPrimary, chance_mod)){
mlog(COMBAT__RANGED, "Ranged attack missed %s.", other->GetName());
other->Damage(this, 0, SPELL_UNKNOWN, SkillThrowing);
} else {
@ -1312,38 +1238,31 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
other->MeleeMitigation(this, TotalDmg, minDmg);
if(TotalDmg > 0)
{
ApplyMeleeDamageBonus(SkillThrowing, TotalDmg);
TotalDmg += other->GetFcDamageAmtIncoming(this, 0, true, SkillThrowing);
TotalDmg += (itembonuses.HeroicDEX / 10) + (TotalDmg * other->GetSkillDmgTaken(SkillThrowing) / 100) + GetSkillDmgAmt(SkillThrowing);
TryCriticalHit(other, SkillThrowing, TotalDmg);
int32 hate = (2*WDmg);
other->AddToHateList(this, hate, 0, false);
CheckNumHitsRemaining(NUMHIT_OutgoingHitSuccess);
}
CommonOutgoingHitSuccess(other, TotalDmg, SkillThrowing);
}
else
TotalDmg = -5;
other->AddToHateList(this, 2*WDmg, 0, false);
other->Damage(this, TotalDmg, SPELL_UNKNOWN, SkillThrowing);
if (TotalDmg > 0 && HasSkillProcSuccess() && GetTarget() && other && !other->HasDied()){
if (ReuseTime)
TrySkillProc(other, SkillThrowing, ReuseTime);
else
TrySkillProc(other, SkillThrowing, 0, true, 11);
TrySkillProc(other, SkillThrowing, 0, true, MainRange);
}
}
if((RangeWeapon != nullptr) && GetTarget() && other && (other->GetHP() > -10))
TryWeaponProc(RangeWeapon, other, 11);
TryWeaponProc(RangeWeapon, other, MainRange);
if (HasSkillProcs() && GetTarget() && other && !other->HasDied()){
if (ReuseTime)
TrySkillProc(other, SkillThrowing, ReuseTime);
else
TrySkillProc(other, SkillThrowing, 0, false, 11);
TrySkillProc(other, SkillThrowing, 0, false, MainRange);
}
}
@ -1394,7 +1313,10 @@ void Mob::SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skil
safe_delete(outapp);
}
void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, float angle, float tilt, float arc, const char *IDFile) {
void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, float angle, float tilt, float arc, const char *IDFile, SkillUseTypes skillInUse) {
if (!to)
return;
const Item_Struct* item = nullptr;
uint8 item_type = 0;
@ -1412,9 +1334,12 @@ void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, f
if(IsArrow) {
item_type = 27;
}
if(!item_type) {
if(!item_type && !skillInUse) {
item_type = item->ItemType;
}
else if (skillInUse)
item_type = GetItemTypeBySkill(skillInUse);
if(!speed) {
speed = 4.0;
}
@ -1444,7 +1369,7 @@ void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, f
as->target_id = to->GetID();
as->item_id = item->ID;
as->item_type = item_type;
as->skill = 0; // Doesn't seem to have any effect
as->skill = skillInUse; // Doesn't seem to have any effect
strn0cpy(as->model_name, item_IDFile, 16);
as->velocity = speed;
as->launch_angle = angle;
@ -1768,8 +1693,8 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
{
DoAnim(animTailRake);
if(GetWeaponDamage(ca_target, GetInv().GetItem(SLOT_SECONDARY)) <= 0 &&
GetWeaponDamage(ca_target, GetInv().GetItem(SLOT_SHOULDER)) <= 0){
if(GetWeaponDamage(ca_target, GetInv().GetItem(MainSecondary)) <= 0 &&
GetWeaponDamage(ca_target, GetInv().GetItem(MainShoulders)) <= 0){
dmg = -5;
}
else{
@ -1839,7 +1764,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
{
DoAnim(animKick);
if(GetWeaponDamage(ca_target, GetInv().GetItem(SLOT_FEET)) <= 0){
if(GetWeaponDamage(ca_target, GetInv().GetItem(MainFeet)) <= 0){
dmg = -5;
}
else{
@ -2062,7 +1987,7 @@ uint32 Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) {
if(HeadShot_Dmg && HeadShot_Level && (defender->GetLevel() <= HeadShot_Level)){
float ProcChance = GetSpecialProcChances(11);
float ProcChance = GetSpecialProcChances(MainRange);
if(ProcChance > MakeRandomFloat(0,1))
return HeadShot_Dmg;
}
@ -2125,7 +2050,7 @@ uint32 Mob::TryAssassinate(Mob* defender, SkillUseTypes skillInUse, uint16 Reuse
float ProcChance = 0.0f;
if (skillInUse == SkillThrowing)
ProcChance = GetSpecialProcChances(11);
ProcChance = GetSpecialProcChances(MainRange);
else
ProcChance = GetAssassinateProcChances(ReuseTime);
@ -2173,8 +2098,8 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
skillinuse = SkillOffense;
int damage = 0;
uint32 hate = 0;
int Hand = 13;
int32 hate = 0;
int Hand = MainPrimary;
if (hate == 0 && weapon_damage > 1) hate = weapon_damage;
if(weapon_damage > 0){
@ -2199,6 +2124,19 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
hate += ucDamageBonus;
}
if(skillinuse == SkillBash){
if(IsClient()){
ItemInst *item = CastToClient()->GetInv().GetItem(MainSecondary);
if(item){
if(item->GetItem()->ItemType == ItemTypeShield) {
hate += item->GetItem()->AC;
}
const Item_Struct *itm = item->GetItem();
hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100;
}
}
}
ApplySpecialAttackMod(skillinuse, max_hit, min_hit);
min_hit += min_hit * GetMeleeMinDamageMod_SE(skillinuse) / 100;
@ -2210,18 +2148,14 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
damage = max_hit;
else
damage = MakeRandomInt(min_hit, max_hit);
if(!other->CheckHitChance(this, skillinuse, Hand, chance_mod)) {
damage = 0;
} else {
other->AvoidDamage(this, damage, CanRiposte);
other->MeleeMitigation(this, damage, min_hit);
if(damage > 0) {
ApplyMeleeDamageBonus(skillinuse, damage);
damage += other->GetFcDamageAmtIncoming(this, 0, true, skillinuse);
damage += (itembonuses.HeroicSTR / 10) + (damage * other->GetSkillDmgTaken(skillinuse) / 100) + GetSkillDmgAmt(skillinuse);
TryCriticalHit(other, skillinuse, damage);
}
if(damage > 0)
CommonOutgoingHitSuccess(other, damage, skillinuse);
}
if (damage == -3) {
@ -2234,19 +2168,6 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
else
damage = -5;
if(skillinuse == SkillBash){
if(IsClient()){
ItemInst *item = CastToClient()->GetInv().GetItem(SLOT_SECONDARY);
if(item){
if(item->GetItem()->ItemType == ItemTypeShield) {
hate += item->GetItem()->AC;
}
const Item_Struct *itm = item->GetItem();
hate = hate * (100 + GetFuriousBash(itm->Focus.Effect)) / 100;
}
}
}
other->AddToHateList(this, hate);
bool CanSkillProc = true;
@ -2255,6 +2176,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
CanSkillProc = false; //Disable skill procs
}
other->AddToHateList(this, hate, 0, false);
other->Damage(this, damage, SPELL_UNKNOWN, skillinuse);
if (HasDied())

View File

@ -599,7 +599,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
snprintf(effect_desc, _EDLEN, "Flesh To Bone");
#endif
if(IsClient()){
ItemInst* transI = CastToClient()->GetInv().GetItem(SLOT_CURSOR);
ItemInst* transI = CastToClient()->GetInv().GetItem(MainCursor);
if(transI && transI->IsType(ItemClassCommon) && transI->IsStackable()){
uint32 fcharges = transI->GetCharges();
//Does it sound like meat... maybe should check if it looks like meat too...
@ -609,7 +609,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
strstr(transI->GetItem()->Name, "Flesh") ||
strstr(transI->GetItem()->Name, "parts") ||
strstr(transI->GetItem()->Name, "Parts")){
CastToClient()->DeleteItemInInventory(SLOT_CURSOR, fcharges, true);
CastToClient()->DeleteItemInInventory(MainCursor, fcharges, true);
CastToClient()->SummonItem(13073, fcharges);
}
else{
@ -1159,7 +1159,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if (SummonedItem) {
c->PushItemOnCursor(*SummonedItem);
c->SendItemPacket(SLOT_CURSOR, SummonedItem, ItemPacketSummonItem);
c->SendItemPacket(MainCursor, SummonedItem, ItemPacketSummonItem);
safe_delete(SummonedItem);
}
SummonedItem = database.CreateItem(spell.base[i], charges);
@ -2200,7 +2200,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
snprintf(effect_desc, _EDLEN, "Rampage");
#endif
if(caster)
entity_list.AEAttack(caster, 30, 13, 0, true); // on live wars dont get a duration ramp, its a one shot deal
entity_list.AEAttack(caster, 30, MainPrimary, 0, true); // on live wars dont get a duration ramp, its a one shot deal
break;
}
@ -2983,7 +2983,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if (SummonedItem) {
Client *c=CastToClient();
c->PushItemOnCursor(*SummonedItem);
c->SendItemPacket(SLOT_CURSOR, SummonedItem, ItemPacketSummonItem);
c->SendItemPacket(MainCursor, SummonedItem, ItemPacketSummonItem);
safe_delete(SummonedItem);
}
@ -5070,7 +5070,7 @@ int16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
}
}
for(int y = 0; y < MAX_AUGMENT_SLOTS; ++y)
for (int y = 0; y < EmuConstants::ITEM_COMMON_SIZE; ++y)
{
if (SympatheticProcList.size() > MAX_SYMPATHETIC)
continue;
@ -5226,7 +5226,7 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
}
}
for(int y = 0; y < MAX_AUGMENT_SLOTS; ++y)
for (int y = 0; y < EmuConstants::ITEM_COMMON_SIZE; ++y)
{
ItemInst *aug = nullptr;
aug = ins->GetAugment(y);
@ -5264,7 +5264,7 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
}
//Tribute Focus
for(int x = TRIBUTE_SLOT_START; x < (TRIBUTE_SLOT_START + MAX_PLAYER_TRIBUTES); ++x)
for(int x = EmuConstants::TRIBUTE_BEGIN; x <= EmuConstants::TRIBUTE_END; ++x)
{
TempItem = nullptr;
ItemInst* ins = GetInv().GetItem(x);
@ -5765,8 +5765,6 @@ int32 Mob::GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spel
int value = 0;
if (spellbonuses.FocusEffects[type]){
uint32 buff_count = GetMaxTotalSlots();
for(int i = 0; i < buff_count; i++){
int32 tmp_focus = 0;
int tmp_buffslot = -1;
@ -5799,7 +5797,7 @@ int32 Mob::GetFocusIncoming(focusType type, int effect, Mob *caster, uint32 spel
CheckNumHitsRemaining(NUMHIT_MatchingSpells, tmp_buffslot);
}
}
return value;
}

View File

@ -285,7 +285,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
return(false);
}
}
if( itm && (itm->GetItem()->Click.Type == ET_EquipClick) && !(item_slot < 22 || item_slot == 9999) ){
if( itm && (itm->GetItem()->Click.Type == ET_EquipClick) && !(item_slot <= MainAmmo || item_slot == MainPowerSource) ){
if (CastToClient()->GetClientVersion() < EQClientSoF) {
// They are attempting to cast a must equip clicky without having it equipped
LogFile->write(EQEMuLog::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) without equiping it!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
@ -1195,7 +1195,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot,
uint32 recastdelay = 0;
uint32 recasttype = 0;
for(int r = 0; r < MAX_AUGMENT_SLOTS; r++) {
for (int r = 0; r < EmuConstants::ITEM_COMMON_SIZE; r++) {
const ItemInst* aug_i = inst->GetAugment(r);
if(!aug_i)
@ -5018,7 +5018,7 @@ bool Mob::IsCombatProc(uint16 spell_id) {
for (int i = 0; i < MAX_PROCS; i++){
if (PermaProcs[i].spellID == spell_id || SpellProcs[i].spellID == spell_id
|| SkillProcs[i].spellID == spell_id || RangedProcs[i].spellID == spell_id){
|| RangedProcs[i].spellID == spell_id){
return true;
}
}
@ -5075,7 +5075,7 @@ bool Mob::AddDefensiveProc(uint16 spell_id, uint16 iChance, uint16 base_spell_id
{
if(spell_id == SPELL_UNKNOWN)
return(false);
int i;
for (i = 0; i < MAX_PROCS; i++) {
if (DefensiveProcs[i].spellID == SPELL_UNKNOWN) {

View File

@ -201,7 +201,7 @@ bool TitleManager::IsClientEligibleForTitle(Client *c, std::vector<TitleEntry>::
}
if((Title->ItemID >= 1) && (c->GetInv().HasItem(Title->ItemID, 0, 0xFF) == SLOT_INVALID))
if ((Title->ItemID >= 1) && (c->GetInv().HasItem(Title->ItemID, 0, 0xFF) == INVALID_INDEX))
return false;
if((Title->TitleSet > 0) && (!c->CheckTitle(Title->TitleSet)))

View File

@ -482,7 +482,7 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac
//because a HasItem on items with num > 1 only returns the
//last-most slot... the results of this are useless to us
//when we go to delete them because we cannot assume it is in a single stack.
if(user_inv.HasItem(item, num, invWherePersonal) != SLOT_INVALID)
if (user_inv.HasItem(item, num, invWherePersonal) != INVALID_INDEX)
count += num;
else
MissingItems.push_back(item);
@ -524,7 +524,7 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac
//we have to loop here to delete 1 at a time in case its in multiple stacks.
for(k = 0; k < counts[r]; k++) {
slot = user_inv.HasItem(items[r], 1, invWherePersonal);
if(slot == SLOT_INVALID) {
if (slot == INVALID_INDEX) {
//WTF... I just checked this above, but just to be sure...
//we cant undo the previous deletes without a lot of work.
//so just call it quits, this shouldent ever happen anyways.

View File

@ -87,7 +87,7 @@ void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id)
// Item always goes into trade bucket from cursor
Client* client = owner->CastToClient();
const ItemInst* inst = client->GetInv().GetItem(SLOT_CURSOR);
const ItemInst* inst = client->GetInv().GetItem(MainCursor);
if (!inst) {
client->Message(13, "Error: Could not find item on your cursor!");
return;
@ -105,7 +105,7 @@ void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id)
}
else
{
if (client->GetInv().GetItem(SLOT_CURSOR)->GetID() != client->GetInv().GetItem(trade_slot_id)->GetID()) {
if (client->GetInv().GetItem(MainCursor)->GetID() != client->GetInv().GetItem(trade_slot_id)->GetID()) {
client->Kick();
return;
}
@ -146,13 +146,13 @@ void Trade::SendItemData(const ItemInst* inst, int16 dest_slot_id)
Client* with = mob->CastToClient();
Client* trader = owner->CastToClient();
if (with && with->IsClient()) {
with->SendItemPacket(dest_slot_id -IDX_TRADE,inst,ItemPacketTradeView);
with->SendItemPacket(dest_slot_id - EmuConstants::TRADE_BEGIN, inst, ItemPacketTradeView);
if (inst->GetItem()->ItemClass == 1) {
for (uint16 i=0; i<10; i++) {
uint16 bagslot_id = Inventory::CalcSlotId(dest_slot_id, i);
const ItemInst* bagitem = trader->GetInv().GetItem(bagslot_id);
if (bagitem) {
with->SendItemPacket(bagslot_id-IDX_TRADE,bagitem,ItemPacketTradeView);
with->SendItemPacket(bagslot_id - EmuConstants::TRADE_BEGIN, bagitem, ItemPacketTradeView);
}
}
}
@ -318,7 +318,7 @@ void Client::ResetTrade() {
{
bool is_arrow = (TempItem->ItemType == ItemTypeArrow) ? true : false;
int freeslotid = GetInv().FindFreeSlot(ins->IsType(ItemClassContainer), true, TempItem->Size, is_arrow);
if (freeslotid == SLOT_INVALID)
if (freeslotid == INVALID_INDEX)
{
DropInst(ins);
}
@ -441,14 +441,14 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer)
if(QSPLT) {
qsaudit->items[parent_offset].to_id = this->character_id;
qsaudit->items[parent_offset].to_slot = SLOT_CURSOR;
qsaudit->items[parent_offset].to_slot = MainCursor;
if(inst->IsType(ItemClassContainer)) {
for(uint8 bagslot_idx = 0; bagslot_idx < inst->GetItem()->BagSlots; bagslot_idx++) {
const ItemInst* bag_inst = inst->GetItem(bagslot_idx);
if(bag_inst == nullptr) { continue; }
int16 to_bagslot_id = Inventory::CalcSlotId(SLOT_CURSOR, bagslot_idx);
int16 to_bagslot_id = Inventory::CalcSlotId(MainCursor, bagslot_idx);
qsaudit->items[++parent_offset].to_id = this->character_id;
qsaudit->items[parent_offset].to_slot = to_bagslot_id;
@ -465,14 +465,14 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer)
if(QSPLT) {
qsaudit->items[parent_offset].to_id = this->character_id;
qsaudit->items[parent_offset].to_slot = SLOT_CURSOR;
qsaudit->items[parent_offset].to_slot = MainCursor;
if(inst->IsType(ItemClassContainer)) {
for(uint8 bagslot_idx = 0; bagslot_idx < inst->GetItem()->BagSlots; bagslot_idx++) {
const ItemInst* bag_inst = inst->GetItem(bagslot_idx);
if(bag_inst == nullptr) { continue; }
int16 to_bagslot_id = Inventory::CalcSlotId(SLOT_CURSOR, bagslot_idx);
int16 to_bagslot_id = Inventory::CalcSlotId(MainCursor, bagslot_idx);
qsaudit->items[++parent_offset].to_id = this->character_id;
qsaudit->items[parent_offset].to_slot = to_bagslot_id;
@ -2214,7 +2214,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) {
if(!item || !Quantity || !Price || !QtyBuyerWants) return;
if(m_inv.HasItem(ItemID, Quantity, invWhereWorn|invWherePersonal|invWhereCursor) == SLOT_INVALID) {
if (m_inv.HasItem(ItemID, Quantity, invWhereWorn | invWherePersonal | invWhereCursor) == INVALID_INDEX) {
Message(13, "You do not have %i %s on you.", Quantity, item->Name);
return;
}
@ -2264,7 +2264,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) {
int16 SellerSlot = m_inv.HasItem(ItemID, 1, invWhereWorn|invWherePersonal|invWhereCursor);
// This shouldn't happen, as we already checked there was space in the Buyer's inventory
if(SellerSlot == SLOT_INVALID) {
if (SellerSlot == INVALID_INDEX) {
if(i > 0) {
// Set the Quantity to the actual number we successfully transferred.
@ -2316,7 +2316,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) {
// Find the slot on the seller that has a stack of at least 1 of the item
int16 SellerSlot = m_inv.HasItem(ItemID, 1, invWhereWorn|invWherePersonal|invWhereCursor);
if(SellerSlot == SLOT_INVALID) {
if (SellerSlot == INVALID_INDEX) {
_log(TRADING__BARTER, "Unexpected error while moving item from seller to buyer.");
Message(13, "Internal error while processing transaction.");
return;

View File

@ -66,7 +66,7 @@ void Client::ToggleTribute(bool enabled) {
int r;
uint32 cost = 0;
uint32 level = GetLevel();
for(r = 0; r < MAX_PLAYER_TRIBUTES; r++) {
for(r = 0; r < EmuConstants::TRIBUTE_SIZE; r++) {
uint32 tid = m_pp.tributes[r].tribute;
if(tid == TRIBUTE_NONE)
continue;
@ -119,7 +119,7 @@ void Client::DoTributeUpdate() {
tis->tribute_master_id = tribute_master_id; //Dont know what this is for
int r;
for(r = 0; r < MAX_PLAYER_TRIBUTES; r++) {
for(r = 0; r < EmuConstants::TRIBUTE_SIZE; r++) {
if(m_pp.tributes[r].tribute != TRIBUTE_NONE) {
tis->tributes[r] = m_pp.tributes[r].tribute;
tis->tiers[r] = m_pp.tributes[r].tier;
@ -134,24 +134,24 @@ void Client::DoTributeUpdate() {
if(m_pp.tribute_active) {
//send and equip tribute items...
for(r = 0; r < MAX_PLAYER_TRIBUTES; r++) {
for(r = 0; r < EmuConstants::TRIBUTE_SIZE; r++) {
uint32 tid = m_pp.tributes[r].tribute;
if(tid == TRIBUTE_NONE) {
if(m_inv[TRIBUTE_SLOT_START+r])
DeleteItemInInventory(TRIBUTE_SLOT_START+r, 0, false);
if(m_inv[EmuConstants::TRIBUTE_BEGIN + r])
DeleteItemInInventory(EmuConstants::TRIBUTE_BEGIN + r, 0, false);
continue;
}
if(tribute_list.count(tid) != 1) {
if(m_inv[TRIBUTE_SLOT_START+r])
DeleteItemInInventory(TRIBUTE_SLOT_START+r, 0, false);
if (m_inv[EmuConstants::TRIBUTE_BEGIN + r])
DeleteItemInInventory(EmuConstants::TRIBUTE_BEGIN + r, 0, false);
continue;
}
//sanity check
if(m_pp.tributes[r].tier >= MAX_TRIBUTE_TIERS) {
if(m_inv[TRIBUTE_SLOT_START+r])
DeleteItemInInventory(TRIBUTE_SLOT_START+r, 0, false);
if (m_inv[EmuConstants::TRIBUTE_BEGIN + r])
DeleteItemInInventory(EmuConstants::TRIBUTE_BEGIN + r, 0, false);
m_pp.tributes[r].tier = 0;
continue;
}
@ -165,15 +165,15 @@ void Client::DoTributeUpdate() {
if(inst == nullptr)
continue;
PutItemInInventory(TRIBUTE_SLOT_START+r, *inst, false);
SendItemPacket(TRIBUTE_SLOT_START+r, inst, ItemPacketTributeItem);
PutItemInInventory(EmuConstants::TRIBUTE_BEGIN + r, *inst, false);
SendItemPacket(EmuConstants::TRIBUTE_BEGIN + r, inst, ItemPacketTributeItem);
safe_delete(inst);
}
} else {
//unequip tribute items...
for(r = 0; r < MAX_PLAYER_TRIBUTES; r++) {
if(m_inv[TRIBUTE_SLOT_START+r])
DeleteItemInInventory(TRIBUTE_SLOT_START+r, 0, false);
for(r = 0; r < EmuConstants::TRIBUTE_SIZE; r++) {
if (m_inv[EmuConstants::TRIBUTE_BEGIN + r])
DeleteItemInInventory(EmuConstants::TRIBUTE_BEGIN + r, 0, false);
}
}
CalcBonuses();
@ -192,7 +192,7 @@ void Client::SendTributeTimer() {
void Client::ChangeTributeSettings(TributeInfo_Struct *t) {
int r;
for(r = 0; r < MAX_PLAYER_TRIBUTES; r++) {
for(r = 0; r < EmuConstants::TRIBUTE_SIZE; r++) {
m_pp.tributes[r].tribute = TRIBUTE_NONE;

View File

@ -1067,8 +1067,10 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
"npc_types.npc_spells_effects_id,"
"npc_types.d_meele_texture1,"
"npc_types.d_meele_texture2,"
"npc_types.ammo_idfile,"
"npc_types.prim_melee_type,"
"npc_types.sec_melee_type,"
"npc_types.ranged_type,"
"npc_types.runspeed,"
"npc_types.findable,"
"npc_types.trackable,"
@ -1103,6 +1105,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
"npc_types.see_improved_hide,"
"npc_types.ATK,"
"npc_types.Accuracy,"
"npc_types.Avoidance,"
"npc_types.slow_mitigation,"
"npc_types.maxlevel,"
"npc_types.scalerate,"
@ -1166,8 +1169,10 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
tmpNPCType->npc_spells_effects_id = atoi(row[r++]);
tmpNPCType->d_meele_texture1 = atoi(row[r++]);
tmpNPCType->d_meele_texture2 = atoi(row[r++]);
strn0cpy(tmpNPCType->ammo_idfile, row[r++], 30);
tmpNPCType->prim_melee_type = atoi(row[r++]);
tmpNPCType->sec_melee_type = atoi(row[r++]);
tmpNPCType->ranged_type = atoi(row[r++]);
tmpNPCType->runspeed= atof(row[r++]);
tmpNPCType->findable = atoi(row[r++]) == 0? false : true;
tmpNPCType->trackable = atoi(row[r++]) == 0? false : true;
@ -1286,6 +1291,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
tmpNPCType->see_improved_hide = atoi(row[r++])==0?false:true;
tmpNPCType->ATK = atoi(row[r++]);
tmpNPCType->accuracy_rating = atoi(row[r++]);
tmpNPCType->avoidance_rating = atoi(row[r++]);
tmpNPCType->slow_mitigation = atoi(row[r++]);
tmpNPCType->maxlevel = atoi(row[r++]);
tmpNPCType->scalerate = atoi(row[r++]);
@ -1992,7 +1998,7 @@ void ZoneDatabase::LoadMercEquipment(Merc *merc) {
int itemCount = 0;
while(DataRow = mysql_fetch_row(DatasetResult)) {
if(itemCount == MAX_WORN_INVENTORY)
if (itemCount == EmuConstants::EQUIPMENT_SIZE)
break;
if(atoi(DataRow[0]) > 0) {
@ -2768,7 +2774,7 @@ void ZoneDatabase::SavePetInfo(Client *c) {
}
}
for(i=0; i<MAX_WORN_INVENTORY; i++) {
for (i = 0; i<EmuConstants::EQUIPMENT_SIZE; i++) {
if(petinfo->Items[i]) {
database.RunQuery(query, MakeAnyLenString(&query,
"INSERT INTO `character_pet_inventory` (`char_id`, `pet`, `slot`, `item_id`) values (%u, 0, %u, %u)",
@ -2792,7 +2798,7 @@ void ZoneDatabase::SavePetInfo(Client *c) {
}
safe_delete_array(query);
for(i=0; i<MAX_WORN_INVENTORY; i++) {
for (i = 0; i<EmuConstants::EQUIPMENT_SIZE; i++) {
if(suspended->Items[i]) {
database.RunQuery(query, MakeAnyLenString(&query,
"INSERT INTO `character_pet_inventory` (`char_id`, `pet`, `slot`, `item_id`) values (%u, 1, %u, %u)",
@ -2923,9 +2929,9 @@ void ZoneDatabase::LoadPetInfo(Client *c) {
pi = suspended;
else
continue;
int slot = atoi(row[1]);
if (slot < 0 || slot > MAX_WORN_INVENTORY)
if (slot < 0 || slot > EmuConstants::EQUIPMENT_SIZE) // if (slot == 22) { zone.TriggerRandomCrash(); }
continue;
pi->Items[slot] = atoul(row[2]);

View File

@ -43,9 +43,25 @@ struct DBnpcspellseffects_entries_Struct {
struct DBnpcspells_Struct {
uint32 parent_list;
int16 attack_proc;
uint16 attack_proc;
uint8 proc_chance;
uint16 range_proc;
int16 rproc_chance;
uint16 defensive_proc;
int16 dproc_chance;
uint32 numentries;
uint32 fail_recast;
uint32 engaged_no_sp_recast_min;
uint32 engaged_no_sp_recast_max;
uint8 engaged_beneficial_self_chance;
uint8 engaged_beneficial_other_chance;
uint8 engaged_detrimental_chance;
uint32 pursue_no_sp_recast_min;
uint32 pursue_no_sp_recast_max;
uint8 pursue_detrimental_chance;
uint32 idle_no_sp_recast_min;
uint32 idle_no_sp_recast_max;
uint8 idle_beneficial_chance;
DBnpcspells_entries_Struct entries[0];
};
@ -90,7 +106,7 @@ struct PetInfo {
uint32 Mana;
float size;
SpellBuff_Struct Buffs[BUFF_COUNT];
uint32 Items[MAX_WORN_INVENTORY];
uint32 Items[EmuConstants::EQUIPMENT_SIZE];
char Name[64];
};

View File

@ -94,8 +94,10 @@ struct NPCType
char special_abilities[512];
uint16 d_meele_texture1;
uint16 d_meele_texture2;
char ammo_idfile[30];
uint8 prim_melee_type;
uint8 sec_melee_type;
uint8 ranged_type;
int32 hp_regen;
int32 mana_regen;
int32 aggroradius; // added for AI improvement - neotokyo
@ -110,6 +112,7 @@ struct NPCType
uint8 mount_color; //only used by horse class
float attack_speed; //%+- on attack delay of the mob.
int accuracy_rating; //10 = 1% accuracy
int avoidance_rating; //10 = 1% avoidance
bool findable; //can be found with find command
bool trackable;
int16 slow_mitigation;