mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-04 00:02:24 +00:00
Added clicky items from bags for clients that support it (RoF, currently)
This commit is contained in:
parent
3e0c1bc02e
commit
83367ee806
@ -1,5 +1,8 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 09/30/2014 ==
|
||||||
|
Uleat: Implemented click-casting from bag slots for clients that natively support it (RoF)
|
||||||
|
|
||||||
== 09/28/2014 ==
|
== 09/28/2014 ==
|
||||||
demonstar55: Add support for post June 18, 2014 Hundred Hands Effect spells (they changed the formula and stuff)
|
demonstar55: Add support for post June 18, 2014 Hundred Hands Effect spells (they changed the formula and stuff)
|
||||||
set Spells:Jun182014HundredHandsRevamp to true if you're using a spell file from June 18, 2014+
|
set Spells:Jun182014HundredHandsRevamp to true if you're using a spell file from June 18, 2014+
|
||||||
|
|||||||
@ -17,7 +17,8 @@ static const uint32 BIT_RoFAndLater = 0xFFFFFFE0;
|
|||||||
static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0;
|
static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0;
|
||||||
static const uint32 BIT_AllClients = 0xFFFFFFFF;
|
static const uint32 BIT_AllClients = 0xFFFFFFFF;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
EQClientUnknown = 0,
|
EQClientUnknown = 0,
|
||||||
EQClient62, // Build: 'Aug 4 2005 15:40:59'
|
EQClient62, // Build: 'Aug 4 2005 15:40:59'
|
||||||
EQClientTitanium, // Build: 'Oct 31 2005 10:33:37'
|
EQClientTitanium, // Build: 'Oct 31 2005 10:33:37'
|
||||||
@ -26,17 +27,50 @@ typedef enum {
|
|||||||
EQClientUnderfoot, // Build: 'Jun 8 2010 16:44:32'
|
EQClientUnderfoot, // Build: 'Jun 8 2010 16:44:32'
|
||||||
EQClientRoF, // Build: 'Dec 10 2012 17:35:44'
|
EQClientRoF, // Build: 'Dec 10 2012 17:35:44'
|
||||||
EQClientRoF2, // Build: 'May 10 2013 23:30:08'
|
EQClientRoF2, // Build: 'May 10 2013 23:30:08'
|
||||||
|
|
||||||
_EQClientCount, // place new clients before this point (preferably, in release/attribute order)
|
_EQClientCount, // place new clients before this point (preferably, in release/attribute order)
|
||||||
|
|
||||||
// Values below are not implemented, as yet...
|
// Values below are not implemented, as yet...
|
||||||
|
|
||||||
EmuNPC = _EQClientCount,
|
EmuNPC = _EQClientCount,
|
||||||
EmuMerc,
|
EmuMerc,
|
||||||
EmuBot,
|
EmuBot,
|
||||||
EmuPet,
|
EmuPet,
|
||||||
|
|
||||||
_EmuClientCount // array size for EQLimits
|
_EmuClientCount // array size for EQLimits
|
||||||
} EQClientVersion;
|
} EQClientVersion;
|
||||||
|
|
||||||
|
static const char* EQClientVersionName(EQClientVersion version)
|
||||||
|
{
|
||||||
|
switch (version)
|
||||||
|
{
|
||||||
|
case EQClientUnknown:
|
||||||
|
return "EQClientUnknown";
|
||||||
|
case EQClient62:
|
||||||
|
return "EQClient62";
|
||||||
|
case EQClientTitanium:
|
||||||
|
return "EQClientTitanium";
|
||||||
|
case EQClientSoF:
|
||||||
|
return "EQClientSoF";
|
||||||
|
case EQClientSoD:
|
||||||
|
return "EQClientSoD";
|
||||||
|
case EQClientUnderfoot:
|
||||||
|
return "EQClientUnderfoot";
|
||||||
|
case EQClientRoF:
|
||||||
|
return "EQClientRoF";
|
||||||
|
case EQClientRoF2:
|
||||||
|
return "EQClientRoF2";
|
||||||
|
case EmuNPC:
|
||||||
|
return "EmuNPC";
|
||||||
|
case EmuMerc:
|
||||||
|
return "EmuMerc";
|
||||||
|
case EmuBot:
|
||||||
|
return "EmuBot";
|
||||||
|
case EmuPet:
|
||||||
|
return "EmuPet";
|
||||||
|
default:
|
||||||
|
return "ERROR: Invalid EQClientVersion";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CLIENTVERSIONS_H */
|
#endif /* CLIENTVERSIONS_H */
|
||||||
|
|||||||
@ -1024,6 +1024,26 @@ bool EQLimits::AllowsEmptyBagInBag(uint32 version) {
|
|||||||
//return local[ValidateMobVersion(version)];
|
//return local[ValidateMobVersion(version)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EQLimits::AllowsClickCastFromBag(uint32 version) {
|
||||||
|
static const bool local[_EmuClientCount] = {
|
||||||
|
/*Unknown*/ false,
|
||||||
|
/*62*/ Client62::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||||
|
/*Titanium*/ Titanium::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||||
|
/*SoF*/ SoF::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||||
|
/*SoD*/ SoD::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||||
|
/*Underfoot*/ Underfoot::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||||
|
/*RoF*/ RoF::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||||
|
/*RoF2*/ false,
|
||||||
|
|
||||||
|
/*NPC*/ false,
|
||||||
|
/*Merc*/ false,
|
||||||
|
/*Bot*/ false,
|
||||||
|
/*Pet*/ false
|
||||||
|
};
|
||||||
|
|
||||||
|
return local[ValidateMobVersion(version)];
|
||||||
|
}
|
||||||
|
|
||||||
// items
|
// items
|
||||||
uint16 EQLimits::ItemCommonSize(uint32 version) {
|
uint16 EQLimits::ItemCommonSize(uint32 version) {
|
||||||
static const uint16 local[_EmuClientCount] = {
|
static const uint16 local[_EmuClientCount] = {
|
||||||
|
|||||||
@ -184,6 +184,7 @@ public:
|
|||||||
static uint64 CursorBitmask(uint32 version);
|
static uint64 CursorBitmask(uint32 version);
|
||||||
|
|
||||||
static bool AllowsEmptyBagInBag(uint32 version);
|
static bool AllowsEmptyBagInBag(uint32 version);
|
||||||
|
static bool AllowsClickCastFromBag(uint32 version);
|
||||||
|
|
||||||
// items
|
// items
|
||||||
static uint16 ItemCommonSize(uint32 version);
|
static uint16 ItemCommonSize(uint32 version);
|
||||||
|
|||||||
@ -911,6 +911,30 @@ bool Inventory::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_S
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Inventory::SupportsClickCasting(int16 slot_id)
|
||||||
|
{
|
||||||
|
// there are a few non-potion items that identify as ItemTypePotion..so, we still need to ubiquitously include the equipment range
|
||||||
|
if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END)
|
||||||
|
{
|
||||||
|
if (EQLimits::AllowsClickCastFromBag(m_version))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Inventory::SupportsPotionBeltCasting(int16 slot_id)
|
||||||
|
{
|
||||||
|
if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource || (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Test whether a given slot can support a container item
|
// Test whether a given slot can support a container item
|
||||||
bool Inventory::SupportsContainers(int16 slot_id)
|
bool Inventory::SupportsContainers(int16 slot_id)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -121,8 +121,22 @@ public:
|
|||||||
// Public Methods
|
// Public Methods
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
|
Inventory() { m_version = EQClientUnknown; m_versionset = false; }
|
||||||
~Inventory();
|
~Inventory();
|
||||||
|
|
||||||
|
// Inventory v2 creep
|
||||||
|
bool SetInventoryVersion(EQClientVersion version) {
|
||||||
|
if (!m_versionset) {
|
||||||
|
m_version = version;
|
||||||
|
return (m_versionset = true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EQClientVersion GetInventoryVersion() { return m_version; }
|
||||||
|
|
||||||
static void CleanDirty();
|
static void CleanDirty();
|
||||||
static void MarkDirty(ItemInst *inst);
|
static void MarkDirty(ItemInst *inst);
|
||||||
|
|
||||||
@ -132,7 +146,7 @@ public:
|
|||||||
|
|
||||||
inline iter_queue cursor_begin() { return m_cursor.begin(); }
|
inline iter_queue cursor_begin() { return m_cursor.begin(); }
|
||||||
inline iter_queue cursor_end() { return m_cursor.end(); }
|
inline iter_queue cursor_end() { return m_cursor.end(); }
|
||||||
inline bool CursorEmpty() { return (m_cursor.size() == 0); }
|
inline bool CursorEmpty() { return (m_cursor.size() == 0); }
|
||||||
|
|
||||||
// Retrieve a read-only item from inventory
|
// Retrieve a read-only item from inventory
|
||||||
inline const ItemInst* operator[](int16 slot_id) const { return GetItem(slot_id); }
|
inline const ItemInst* operator[](int16 slot_id) const { return GetItem(slot_id); }
|
||||||
@ -183,6 +197,10 @@ public:
|
|||||||
|
|
||||||
static bool CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container);
|
static bool CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container);
|
||||||
|
|
||||||
|
// Test for valid inventory casting slot
|
||||||
|
bool SupportsClickCasting(int16 slot_id);
|
||||||
|
bool SupportsPotionBeltCasting(int16 slot_id);
|
||||||
|
|
||||||
// Test whether a given slot can support a container item
|
// Test whether a given slot can support a container item
|
||||||
static bool SupportsContainers(int16 slot_id);
|
static bool SupportsContainers(int16 slot_id);
|
||||||
|
|
||||||
@ -229,7 +247,12 @@ protected:
|
|||||||
std::map<int16, ItemInst*> m_bank; // Items in character bank
|
std::map<int16, ItemInst*> m_bank; // Items in character bank
|
||||||
std::map<int16, ItemInst*> m_shbank; // Items in character shared bank
|
std::map<int16, ItemInst*> m_shbank; // Items in character shared bank
|
||||||
std::map<int16, ItemInst*> m_trade; // Items in a trade session
|
std::map<int16, ItemInst*> m_trade; // Items in a trade session
|
||||||
ItemInstQueue m_cursor; // Items on cursor: FIFO
|
ItemInstQueue m_cursor; // Items on cursor: FIFO
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Active inventory version
|
||||||
|
EQClientVersion m_version;
|
||||||
|
bool m_versionset;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SharedDatabase;
|
class SharedDatabase;
|
||||||
|
|||||||
@ -180,6 +180,7 @@ namespace Client62 {
|
|||||||
|
|
||||||
namespace limits {
|
namespace limits {
|
||||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
||||||
|
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
|
||||||
static const bool COIN_HAS_WEIGHT = true;
|
static const bool COIN_HAS_WEIGHT = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -184,6 +184,7 @@ namespace RoF {
|
|||||||
|
|
||||||
namespace limits {
|
namespace limits {
|
||||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = true;
|
static const bool ALLOWS_EMPTY_BAG_IN_BAG = true;
|
||||||
|
static const bool ALLOWS_CLICK_CAST_FROM_BAG = true;
|
||||||
static const bool COIN_HAS_WEIGHT = false;
|
static const bool COIN_HAS_WEIGHT = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -181,6 +181,7 @@ namespace SoD {
|
|||||||
|
|
||||||
namespace limits {
|
namespace limits {
|
||||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
||||||
|
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
|
||||||
static const bool COIN_HAS_WEIGHT = false;
|
static const bool COIN_HAS_WEIGHT = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -181,6 +181,7 @@ namespace SoF {
|
|||||||
|
|
||||||
namespace limits {
|
namespace limits {
|
||||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
||||||
|
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
|
||||||
static const bool COIN_HAS_WEIGHT = true;
|
static const bool COIN_HAS_WEIGHT = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -180,6 +180,7 @@ namespace Titanium {
|
|||||||
|
|
||||||
namespace limits {
|
namespace limits {
|
||||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
||||||
|
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
|
||||||
static const bool COIN_HAS_WEIGHT = true;
|
static const bool COIN_HAS_WEIGHT = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -181,6 +181,7 @@ namespace Underfoot {
|
|||||||
|
|
||||||
namespace limits {
|
namespace limits {
|
||||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
||||||
|
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
|
||||||
static const bool COIN_HAS_WEIGHT = false;
|
static const bool COIN_HAS_WEIGHT = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1307,7 +1307,13 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
conn_state = ReceivedZoneEntry;
|
conn_state = ReceivedZoneEntry;
|
||||||
|
|
||||||
ClientVersion = Connection()->ClientVersion();
|
ClientVersion = Connection()->ClientVersion();
|
||||||
ClientVersionBit = 1 << (ClientVersion - 1);
|
if (ClientVersion != EQClientUnknown)
|
||||||
|
ClientVersionBit = 1 << (ClientVersion - 1);
|
||||||
|
else
|
||||||
|
ClientVersionBit = 0;
|
||||||
|
|
||||||
|
bool siv = m_inv.SetInventoryVersion(ClientVersion);
|
||||||
|
LogFile->write(EQEMuLog::Debug, "%s inventory version to %s(%i)", (siv ? "Succeeded in setting" : "Failed to set"), EQClientVersionName(ClientVersion), ClientVersion);
|
||||||
|
|
||||||
/* Antighost code
|
/* Antighost code
|
||||||
tmp var is so the search doesnt find this object
|
tmp var is so the search doesnt find this object
|
||||||
@ -3999,15 +4005,16 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
|||||||
else if ((castspell->slot == USE_ITEM_SPELL_SLOT) || (castspell->slot == POTION_BELT_SPELL_SLOT)) // ITEM or POTION cast
|
else if ((castspell->slot == USE_ITEM_SPELL_SLOT) || (castspell->slot == POTION_BELT_SPELL_SLOT)) // ITEM or POTION cast
|
||||||
{
|
{
|
||||||
//discipline, using the item spell slot
|
//discipline, using the item spell slot
|
||||||
if (castspell->inventoryslot == 0xFFFFFFFF) {
|
if (castspell->inventoryslot == INVALID_INDEX) {
|
||||||
if (!UseDiscipline(castspell->spell_id, castspell->target_id)) {
|
if (!UseDiscipline(castspell->spell_id, castspell->target_id)) {
|
||||||
LogFile->write(EQEMuLog::Debug, "Unknown ability being used by %s, spell being cast is: %i\n", GetName(), castspell->spell_id);
|
LogFile->write(EQEMuLog::Debug, "Unknown ability being used by %s, spell being cast is: %i\n", GetName(), castspell->spell_id);
|
||||||
InterruptSpell(castspell->spell_id);
|
InterruptSpell(castspell->spell_id);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((castspell->inventoryslot <= EmuConstants::GENERAL_END) || (castspell->slot == POTION_BELT_SPELL_SLOT)) // sanity check
|
else if (m_inv.SupportsClickCasting(castspell->inventoryslot) || (castspell->slot == POTION_BELT_SPELL_SLOT)) // sanity check
|
||||||
{
|
{
|
||||||
|
// packet field types will be reviewed as packet transistions occur -U
|
||||||
const ItemInst* inst = m_inv[castspell->inventoryslot]; //slot values are int16, need to check packet on this field
|
const ItemInst* inst = m_inv[castspell->inventoryslot]; //slot values are int16, need to check packet on this field
|
||||||
//bool cancast = true;
|
//bool cancast = true;
|
||||||
if (inst && inst->IsType(ItemClassCommon))
|
if (inst && inst->IsType(ItemClassCommon))
|
||||||
@ -8555,7 +8562,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);
|
LogFile->write(EQEMuLog::Debug, "OP ItemVerifyRequest: spell=%i, target=%i, inv=%i", spell_id, target_id, slot_id);
|
||||||
|
|
||||||
if ((slot_id < MainCursor) || (slot_id == MainPowerSource) || (slot_id > 250 && slot_id < 331 && ((item->ItemType == ItemTypePotion) || item->PotionBelt))) // sanity check
|
if (m_inv.SupportsClickCasting(slot_id) || ((item->ItemType == ItemTypePotion || item->PotionBelt) && m_inv.SupportsPotionBeltCasting(slot_id))) // sanity check
|
||||||
{
|
{
|
||||||
ItemInst* p_inst = (ItemInst*)inst;
|
ItemInst* p_inst = (ItemInst*)inst;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user