diff --git a/common/emu_constants.h b/common/emu_constants.h index 9e44976a8..e156fe98a 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -116,6 +116,14 @@ namespace EQEmu const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize; + const int LongBuffs = RoF2::constants::LongBuffs; + const int ShortBuffs = RoF2::constants::ShortBuffs; + const int DiscBuffs = RoF2::constants::DiscBuffs; + const int TotalBuffs = RoF2::constants::TotalBuffs; + const int NPCBuffs = RoF2::constants::NPCBuffs; + const int PetBuffs = RoF2::constants::PetBuffs; + const int MercBuffs = RoF2::constants::MercBuffs; + } /*constants*/ enum class CastingSlot : uint32 { diff --git a/common/eq_limits.cpp b/common/eq_limits.cpp index 1c0140811..ce94c4359 100644 --- a/common/eq_limits.cpp +++ b/common/eq_limits.cpp @@ -24,28 +24,84 @@ static const EQEmu::constants::LookupEntry constants_lookup_entries[EQEmu::versions::ClientVersionCount] = { { + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, + ClientUnknown::Null, ClientUnknown::Null }, { + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, + Client62::Null, Client62::Null }, { - Titanium::constants::CharacterCreationLimit + Titanium::constants::CharacterCreationLimit, + Titanium::constants::LongBuffs, + Titanium::constants::ShortBuffs, + Titanium::constants::DiscBuffs, + Titanium::constants::TotalBuffs, + Titanium::constants::NPCBuffs, + Titanium::constants::PetBuffs, + Titanium::constants::MercBuffs }, { - SoF::constants::CharacterCreationLimit + SoF::constants::CharacterCreationLimit, + SoF::constants::LongBuffs, + SoF::constants::ShortBuffs, + SoF::constants::DiscBuffs, + SoF::constants::TotalBuffs, + SoF::constants::NPCBuffs, + SoF::constants::PetBuffs, + SoF::constants::MercBuffs }, { - SoD::constants::CharacterCreationLimit + SoD::constants::CharacterCreationLimit, + SoD::constants::LongBuffs, + SoD::constants::ShortBuffs, + SoD::constants::DiscBuffs, + SoD::constants::TotalBuffs, + SoD::constants::NPCBuffs, + SoD::constants::PetBuffs, + SoD::constants::MercBuffs }, { - UF::constants::CharacterCreationLimit + UF::constants::CharacterCreationLimit, + UF::constants::LongBuffs, + UF::constants::ShortBuffs, + UF::constants::DiscBuffs, + UF::constants::TotalBuffs, + UF::constants::NPCBuffs, + UF::constants::PetBuffs, + UF::constants::MercBuffs }, { - RoF::constants::CharacterCreationLimit + RoF::constants::CharacterCreationLimit, + RoF::constants::LongBuffs, + RoF::constants::ShortBuffs, + RoF::constants::DiscBuffs, + RoF::constants::TotalBuffs, + RoF::constants::NPCBuffs, + RoF::constants::PetBuffs, + RoF::constants::MercBuffs }, { - RoF2::constants::CharacterCreationLimit + RoF2::constants::CharacterCreationLimit, + RoF2::constants::LongBuffs, + RoF2::constants::ShortBuffs, + RoF2::constants::DiscBuffs, + RoF2::constants::TotalBuffs, + RoF2::constants::NPCBuffs, + RoF2::constants::PetBuffs, + RoF2::constants::MercBuffs } }; diff --git a/common/eq_limits.h b/common/eq_limits.h index 72d710998..252d23053 100644 --- a/common/eq_limits.h +++ b/common/eq_limits.h @@ -38,6 +38,13 @@ namespace EQEmu class LookupEntry { public: size_t CharacterCreationLimit; + int LongBuffs; + int ShortBuffs; + int DiscBuffs; + int TotalBuffs; + int NPCBuffs; + int PetBuffs; + int MercBuffs; }; const LookupEntry* Lookup(versions::ClientVersion client_version); diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 5793e6392..980a4f4ed 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -66,6 +66,9 @@ namespace RoF static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot); static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot); + static inline int ServerToRoFBuffSlot(int index); + static inline int RoFToServerBuffSlot(int index); + void Register(EQStreamIdentifier &into) { //create our opcode manager if we havent already @@ -423,15 +426,8 @@ namespace RoF OUT(buff.y); OUT(buff.x); OUT(buff.z); - uint16 buffslot = emu->slotid; - // Not sure if this is needs amending for RoF yet. - if (buffslot >= 25) - { - buffslot += 17; - } - // TODO: implement slot_data stuff - eq->slotid = buffslot; + eq->slotid = ServerToRoFBuffSlot(emu->slotid); if (emu->bufffade == 1) eq->bufffade = 1; @@ -447,10 +443,10 @@ namespace RoF outapp->WriteUInt32(0); // tic timer outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ? outapp->WriteUInt16(1); // 1 buff in this packet - outapp->WriteUInt32(buffslot); + outapp->WriteUInt32(eq->slotid); outapp->WriteUInt32(0xffffffff); // SpellID (0xffff to remove) outapp->WriteUInt32(0); // Duration - outapp->WriteUInt32(0); // ? + outapp->WriteUInt32(0); // numhits outapp->WriteUInt8(0); // Caster name outapp->WriteUInt8(0); // Type } @@ -474,17 +470,9 @@ namespace RoF __packet->WriteUInt8(emu->all_buffs); // 1 indicates all buffs on the player (0 to add or remove a single buff) __packet->WriteUInt16(emu->count); - for (uint16 i = 0; i < emu->count; ++i) + for (int i = 0; i < emu->count; ++i) { - uint16 buffslot = emu->entries[i].buff_slot; - if (emu->type == 0) { // only correct for self packets - if (emu->entries[i].buff_slot >= 25) - buffslot += 17; - if (buffslot == 54) - buffslot = 62; - } - - __packet->WriteUInt32(buffslot); + __packet->WriteUInt32(emu->type == 0 ? ServerToRoFBuffSlot(emu->entries[i].buff_slot) : emu->entries[i].buff_slot); __packet->WriteUInt32(emu->entries[i].spell_id); __packet->WriteUInt32(emu->entries[i].tics_remaining); __packet->WriteUInt32(emu->entries[i].num_hits); // Unknown @@ -4312,7 +4300,7 @@ namespace RoF IN(buff.unknown003); IN(buff.spellid); IN(buff.duration); - IN(slotid); + emu->slotid = RoFToServerBuffSlot(eq->slotid); IN(bufffade); FINISH_DIRECT_DECODE(); @@ -4325,7 +4313,7 @@ namespace RoF DECODE_LENGTH_EXACT(structs::BuffRemoveRequest_Struct); SETUP_DIRECT_DECODE(BuffRemoveRequest_Struct, structs::BuffRemoveRequest_Struct); - emu->SlotID = (eq->SlotID < 42) ? eq->SlotID : (eq->SlotID - 17); + emu->SlotID = RoFToServerBuffSlot(eq->SlotID); IN(EntityID); @@ -6084,4 +6072,32 @@ namespace RoF return EQEmu::CastingSlot::Discipline; } } + + // these should be optimized out for RoF since they should all boil down to return index :P + // but lets leave it here for future proofing + static inline int ServerToRoFBuffSlot(int index) + { + // we're a disc + if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs) + return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs + + constants::LongBuffs + constants::ShortBuffs; + // we're a song + if (index >= EQEmu::constants::LongBuffs) + return index - EQEmu::constants::LongBuffs + constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } + + static inline int RoFToServerBuffSlot(int index) + { + // we're a disc + if (index >= constants::LongBuffs + constants::ShortBuffs) + return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs + + EQEmu::constants::ShortBuffs; + // we're a song + if (index >= constants::LongBuffs) + return index - constants::LongBuffs + EQEmu::constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } } /*RoF*/ diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index c19203d8a..d14008e93 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -66,6 +66,9 @@ namespace RoF2 static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot); static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot); + static inline int ServerToRoF2BuffSlot(int index); + static inline int RoF2ToServerBuffSlot(int index); + void Register(EQStreamIdentifier &into) { //create our opcode manager if we havent already @@ -492,18 +495,7 @@ namespace RoF2 OUT(buff.y); OUT(buff.x); OUT(buff.z); - uint16 buffslot = emu->slotid; - // Not sure if this is needs amending for RoF2 yet. - if (buffslot >= 25) - { - buffslot += 17; - } - // TODO: We should really just deal with these "server side" - // so we can have clients not limited to other clients. - // This fixes discs, songs were changed to 20 - if (buffslot == 54) - buffslot = 62; - eq->slotid = buffslot; + eq->slotid = ServerToRoF2BuffSlot(emu->slotid); // TODO: implement slot_data stuff if (emu->bufffade == 1) eq->bufffade = 1; @@ -519,10 +511,10 @@ namespace RoF2 outapp->WriteUInt32(0); // tic timer outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ? outapp->WriteUInt16(1); // 1 buff in this packet - outapp->WriteUInt32(buffslot); + outapp->WriteUInt32(eq->slotid); outapp->WriteUInt32(0xffffffff); // SpellID (0xffff to remove) outapp->WriteUInt32(0); // Duration - outapp->WriteUInt32(0); // ? + outapp->WriteUInt32(0); // numhits outapp->WriteUInt8(0); // Caster name outapp->WriteUInt8(0); // Type } @@ -546,20 +538,9 @@ namespace RoF2 __packet->WriteUInt8(emu->all_buffs); // 1 indicates all buffs on the player (0 to add or remove a single buff) __packet->WriteUInt16(emu->count); - for (uint16 i = 0; i < emu->count; ++i) + for (int i = 0; i < emu->count; ++i) { - uint16 buffslot = emu->entries[i].buff_slot; - if (emu->type == 0) { // only correct for self packets - if (emu->entries[i].buff_slot >= 25) - buffslot += 17; - // TODO: We should really just deal with these "server side" - // so we can have clients not limited to other clients. - // This fixes discs, songs were changed to 20 - if (buffslot == 54) - buffslot = 62; - } - - __packet->WriteUInt32(buffslot); + __packet->WriteUInt32(emu->type == 0 ? ServerToRoF2BuffSlot(emu->entries[i].buff_slot) : emu->entries[i].buff_slot); __packet->WriteUInt32(emu->entries[i].spell_id); __packet->WriteUInt32(emu->entries[i].tics_remaining); __packet->WriteUInt32(emu->entries[i].num_hits); // Unknown @@ -4550,7 +4531,7 @@ namespace RoF2 IN(buff.unknown003); IN(buff.spellid); IN(buff.duration); - IN(slotid); + emu->slotid = RoF2ToServerBuffSlot(eq->slotid); IN(bufffade); FINISH_DIRECT_DECODE(); @@ -4563,7 +4544,7 @@ namespace RoF2 DECODE_LENGTH_EXACT(structs::BuffRemoveRequest_Struct); SETUP_DIRECT_DECODE(BuffRemoveRequest_Struct, structs::BuffRemoveRequest_Struct); - emu->SlotID = (eq->SlotID < 42) ? eq->SlotID : (eq->SlotID - 17); + emu->SlotID = RoF2ToServerBuffSlot(eq->SlotID); IN(EntityID); @@ -6388,4 +6369,32 @@ namespace RoF2 return EQEmu::CastingSlot::Discipline; } } + + // these should be optimized out for RoF2 since they should all boil down to return index :P + // but lets leave it here for future proofing + static inline int ServerToRoF2BuffSlot(int index) + { + // we're a disc + if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs) + return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs + + constants::LongBuffs + constants::ShortBuffs; + // we're a song + if (index >= EQEmu::constants::LongBuffs) + return index - EQEmu::constants::LongBuffs + constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } + + static inline int RoF2ToServerBuffSlot(int index) + { + // we're a disc + if (index >= constants::LongBuffs + constants::ShortBuffs) + return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs + + EQEmu::constants::ShortBuffs; + // we're a song + if (index >= constants::LongBuffs) + return index - constants::LongBuffs + EQEmu::constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } } /*RoF2*/ diff --git a/common/patches/rof2_limits.h b/common/patches/rof2_limits.h index fb2f997ca..6f4e649ff 100644 --- a/common/patches/rof2_limits.h +++ b/common/patches/rof2_limits.h @@ -277,6 +277,14 @@ namespace RoF2 const size_t SayLinkBodySize = 56; + const int LongBuffs = 42; + const int ShortBuffs = 20; + const int DiscBuffs = 1; + const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs; + const int NPCBuffs = 97; + const int PetBuffs = NPCBuffs; + const int MercBuffs = LongBuffs; + } /*constants*/ namespace behavior { diff --git a/common/patches/rof_limits.h b/common/patches/rof_limits.h index ed0b9a6d0..952d14b20 100644 --- a/common/patches/rof_limits.h +++ b/common/patches/rof_limits.h @@ -268,6 +268,14 @@ namespace RoF const size_t SayLinkBodySize = 55; + const int LongBuffs = 42; + const int ShortBuffs = 20; + const int DiscBuffs = 1; + const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs; + const int NPCBuffs = 97; + const int PetBuffs = NPCBuffs; + const int MercBuffs = LongBuffs; + } /*constants*/ namespace behavior { diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index 330f7ee20..a3872e9c9 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -62,6 +62,9 @@ namespace SoD static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot); static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot); + static inline int ServerToSoDBuffSlot(int index); + static inline int SoDToServerBuffSlot(int index); + void Register(EQStreamIdentifier &into) { //create our opcode manager if we havent already @@ -315,7 +318,7 @@ namespace SoD OUT(buff.duration); OUT(buff.counters); OUT(buff.player_id); - OUT(slotid); + eq->slotid = ServerToSoDBuffSlot(emu->slotid); OUT(bufffade); FINISH_ENCODE(); @@ -2921,8 +2924,8 @@ namespace SoD IN(buff.bard_modifier); IN(buff.spellid); IN(buff.duration); - IN(buff.counters) - IN(slotid); + IN(buff.counters); + emu->slotid = SoDToServerBuffSlot(eq->slotid); IN(bufffade); FINISH_DIRECT_DECODE(); @@ -4088,4 +4091,30 @@ namespace SoD return EQEmu::CastingSlot::Discipline; } } + + static inline int ServerToSoDBuffSlot(int index) + { + // we're a disc + if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs) + return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs + + constants::LongBuffs + constants::ShortBuffs; + // we're a song + if (index >= EQEmu::constants::LongBuffs) + return index - EQEmu::constants::LongBuffs + constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } + + static inline int SoDToServerBuffSlot(int index) + { + // we're a disc + if (index >= constants::LongBuffs + constants::ShortBuffs) + return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs + + EQEmu::constants::ShortBuffs; + // we're a song + if (index >= constants::LongBuffs) + return index - constants::LongBuffs + EQEmu::constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } } /*SoD*/ diff --git a/common/patches/sod_limits.h b/common/patches/sod_limits.h index fa2c29317..8f8031a3d 100644 --- a/common/patches/sod_limits.h +++ b/common/patches/sod_limits.h @@ -295,6 +295,14 @@ namespace SoD const size_t SayLinkBodySize = 50; + const int LongBuffs = 25; + const int ShortBuffs = 15; + const int DiscBuffs = 1; + const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs; + const int NPCBuffs = 85; + const int PetBuffs = NPCBuffs; + const int MercBuffs = LongBuffs; + } /*constants*/ namespace behavior { diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index 59e0edb5f..9009979ef 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -62,6 +62,9 @@ namespace SoF static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot); static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation); + static inline int ServerToSoFBuffSlot(int index); + static inline int SoFToServerBuffSlot(int index); + void Register(EQStreamIdentifier &into) { //create our opcode manager if we havent already @@ -297,7 +300,7 @@ namespace SoF OUT(buff.duration); OUT(buff.counters); OUT(buff.player_id); - OUT(slotid); + eq->slotid = ServerToSoFBuffSlot(emu->slotid); OUT(bufffade); FINISH_ENCODE(); @@ -2375,7 +2378,7 @@ namespace SoF IN(buff.duration); IN(buff.counters); IN(buff.player_id); - IN(slotid); + emu->slotid = SoFToServerBuffSlot(eq->slotid); IN(bufffade); FINISH_DIRECT_DECODE(); @@ -3461,4 +3464,30 @@ namespace SoF return EQEmu::CastingSlot::Discipline; } } + + static inline int ServerToSoFBuffSlot(int index) + { + // we're a disc + if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs) + return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs + + constants::LongBuffs + constants::ShortBuffs; + // we're a song + if (index >= EQEmu::constants::LongBuffs) + return index - EQEmu::constants::LongBuffs + constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } + + static inline int SoFToServerBuffSlot(int index) + { + // we're a disc + if (index >= constants::LongBuffs + constants::ShortBuffs) + return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs + + EQEmu::constants::ShortBuffs; + // we're a song + if (index >= constants::LongBuffs) + return index - constants::LongBuffs + EQEmu::constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } } /*SoF*/ diff --git a/common/patches/sof_limits.h b/common/patches/sof_limits.h index 575df39ba..d34197a90 100644 --- a/common/patches/sof_limits.h +++ b/common/patches/sof_limits.h @@ -295,6 +295,14 @@ namespace SoF const size_t SayLinkBodySize = 50; + const int LongBuffs = 25; + const int ShortBuffs = 15; + const int DiscBuffs = 1; + const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs; + const int NPCBuffs = 60; + const int PetBuffs = 30; + const int MercBuffs = 0; + } /*constants*/ namespace behavior { diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index 286d09d1b..1c7033186 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -61,6 +61,9 @@ namespace Titanium static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot); static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation); + static inline int ServerToTitaniumBuffSlot(int index); + static inline int TitaniumToServerBuffSlot(int index); + void Register(EQStreamIdentifier &into) { auto Config = EQEmuConfig::get(); @@ -270,7 +273,7 @@ namespace Titanium OUT(buff.duration); OUT(buff.counters); OUT(buff.player_id); - OUT(slotid); + eq->slotid = ServerToTitaniumBuffSlot(emu->slotid); OUT(bufffade); FINISH_ENCODE(); @@ -1779,7 +1782,7 @@ namespace Titanium IN(buff.duration); IN(buff.counters); IN(buff.player_id); - IN(slotid); + emu->slotid = TitaniumToServerBuffSlot(eq->slotid); IN(bufffade); FINISH_DIRECT_DECODE(); @@ -2632,4 +2635,30 @@ namespace Titanium return EQEmu::CastingSlot::Discipline; } } + + static inline int ServerToTitaniumBuffSlot(int index) + { + // we're a disc + if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs) + return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs + + constants::LongBuffs + constants::ShortBuffs; + // we're a song + if (index >= EQEmu::constants::LongBuffs) + return index - EQEmu::constants::LongBuffs + constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } + + static inline int TitaniumToServerBuffSlot(int index) + { + // we're a disc + if (index >= constants::LongBuffs + constants::ShortBuffs) + return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs + + EQEmu::constants::ShortBuffs; + // we're a song + if (index >= constants::LongBuffs) + return index - constants::LongBuffs + EQEmu::constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } } /*Titanium*/ diff --git a/common/patches/titanium_limits.h b/common/patches/titanium_limits.h index e631f8492..3266ade6f 100644 --- a/common/patches/titanium_limits.h +++ b/common/patches/titanium_limits.h @@ -294,6 +294,14 @@ namespace Titanium const size_t SayLinkBodySize = 45; + const int LongBuffs = 25; + const int ShortBuffs = 12; + const int DiscBuffs = 1; + const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs; + const int NPCBuffs = 60; + const int PetBuffs = 30; + const int MercBuffs = 0; + } /*constants*/ namespace behavior { diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index 92be237b1..061444bea 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -62,6 +62,9 @@ namespace UF static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot); static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot); + static inline int ServerToUFBuffSlot(int index); + static inline int UFToServerBuffSlot(int index); + void Register(EQStreamIdentifier &into) { //create our opcode manager if we havent already @@ -377,17 +380,8 @@ namespace UF OUT(buff.spellid); OUT(buff.duration); OUT(buff.num_hits); - uint16 buffslot = emu->slotid; - if (buffslot >= 25 && buffslot < 37) - { - buffslot += 5; - } - else if (buffslot >= 37) - { - buffslot += 14; - } // TODO: implement slot_data stuff - eq->slotid = buffslot; + eq->slotid = ServerToUFBuffSlot(emu->slotid); OUT(bufffade); // Live (October 2011) sends a 2 rather than 0 when a buff is created, but it doesn't seem to matter. FINISH_ENCODE(); @@ -407,17 +401,9 @@ namespace UF __packet->WriteUInt8(emu->all_buffs); // 1 = all buffs, 0 = 1 buff __packet->WriteUInt16(emu->count); - for (uint16 i = 0; i < emu->count; ++i) + for (int i = 0; i < emu->count; ++i) { - uint16 buffslot = emu->entries[i].buff_slot; - if (emu->type == 0) { // only correct for self packets - if (emu->entries[i].buff_slot >= 25 && emu->entries[i].buff_slot < 37) - buffslot += 5; - else if (emu->entries[i].buff_slot >= 37) - buffslot += 14; - } - - __packet->WriteUInt32(buffslot); + __packet->WriteUInt32(emu->type == 0 ? ServerToUFBuffSlot(emu->entries[i].buff_slot) : emu->entries[i].buff_slot); __packet->WriteUInt32(emu->entries[i].spell_id); __packet->WriteUInt32(emu->entries[i].tics_remaining); __packet->WriteUInt32(emu->entries[i].num_hits); @@ -3236,6 +3222,7 @@ namespace UF IN(buff.unknown003); IN(buff.spellid); IN(buff.duration); + emu->slotid = UFToServerBuffSlot(eq->slotid); IN(slotid); IN(bufffade); @@ -3249,7 +3236,7 @@ namespace UF DECODE_LENGTH_EXACT(structs::BuffRemoveRequest_Struct); SETUP_DIRECT_DECODE(BuffRemoveRequest_Struct, structs::BuffRemoveRequest_Struct); - emu->SlotID = (eq->SlotID < 30) ? eq->SlotID : (eq->SlotID - 5); + emu->SlotID = UFToServerBuffSlot(eq->SlotID); IN(EntityID); @@ -4453,4 +4440,30 @@ namespace UF return EQEmu::CastingSlot::Discipline; } } + + static inline int ServerToUFBuffSlot(int index) + { + // we're a disc + if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs) + return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs + + constants::LongBuffs + constants::ShortBuffs; + // we're a song + if (index >= EQEmu::constants::LongBuffs) + return index - EQEmu::constants::LongBuffs + constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } + + static inline int UFToServerBuffSlot(int index) + { + // we're a disc + if (index >= constants::LongBuffs + constants::ShortBuffs) + return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs + + EQEmu::constants::ShortBuffs; + // we're a song + if (index >= constants::LongBuffs) + return index - constants::LongBuffs + EQEmu::constants::LongBuffs; + // we're a normal buff + return index; // as long as we guard against bad slots server side, we should be fine + } } /*UF*/ diff --git a/common/patches/uf_limits.h b/common/patches/uf_limits.h index 2e799ac0c..719fcc394 100644 --- a/common/patches/uf_limits.h +++ b/common/patches/uf_limits.h @@ -64,7 +64,7 @@ namespace UF InvTypeOther, InvTypeCount }; - + } /*invtype*/ namespace invslot { @@ -115,21 +115,21 @@ namespace UF const int GeneralBegin = PossessionsGeneral1; const int GeneralEnd = PossessionsGeneral8; const int GeneralCount = (GeneralEnd - GeneralBegin + 1); - + } /*invslot*/ namespace invbag { inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::UF; } enum : int { InvBagInvalid = -1, InvBagBegin }; - + } /*invbag*/ namespace invaug { inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::UF; } enum : int { InvAugInvalid = -1, InvAugBegin }; - + } /*invaug*/ namespace item { @@ -148,27 +148,27 @@ namespace UF ItemPacketCharmUpdate = 110, ItemPacket11 = 111 }; - + } /*item*/ namespace profile { inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::UF; } - + } /*profile*/ namespace constants { inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::UF; } - + } /*constants*/ namespace behavior { inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::UF; } - + } /*behavior*/ namespace skills { inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::UF; } - + } /*skills*/ @@ -208,7 +208,7 @@ namespace UF extern const char* GetInvTypeName(int inv_type); extern bool IsInvTypePersistent(int inv_type); - + } /*invtype*/ namespace invslot { @@ -237,7 +237,7 @@ namespace UF extern const char* GetInvPossessionsSlotName(int inv_slot); extern const char* GetInvCorpseSlotName(int inv_slot); extern const char* GetInvSlotName(int inv_type, int inv_slot); - + } /*invslot*/ namespace invbag { @@ -264,7 +264,7 @@ namespace UF const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1; extern const char* GetInvBagIndexName(int bag_index); - + } /*invbag*/ namespace invaug { @@ -288,24 +288,32 @@ namespace UF const size_t PotionBeltSize = 5; const size_t SkillArraySize = 100; - + } /*profile*/ namespace constants { const size_t CharacterCreationLimit = 12; const size_t SayLinkBodySize = 50; - + + const int LongBuffs = 30; + const int ShortBuffs = 20; + const int DiscBuffs = 1; + const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs; + const int NPCBuffs = 85; + const int PetBuffs = NPCBuffs; + const int MercBuffs = LongBuffs; + } /*constants*/ namespace behavior { const bool CoinHasWeight = false; - + } /*behavior*/ namespace skills { const size_t LastUsableSkill = EQEmu::skills::SkillTripleAttack; - + } /*skills*/ }; /*UF*/ diff --git a/common/ruletypes.h b/common/ruletypes.h index 0f424072d..9a18ff063 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -333,11 +333,11 @@ RULE_INT(Spells, SacrificeMinLevel, 46) //first level Sacrifice will work on RULE_INT(Spells, SacrificeMaxLevel, 69) //last level Sacrifice will work on RULE_INT(Spells, SacrificeItemID, 9963) //Item ID of the item Sacrifice will return (defaults to an EE) RULE_BOOL(Spells, EnableSpellGlobals, false) // If Enabled, spells check the spell_globals table and compare character data from the quest globals before allowing that spell to scribe with scribespells -RULE_INT(Spells, MaxBuffSlotsNPC, 25) -RULE_INT(Spells, MaxSongSlotsNPC, 10) -RULE_INT(Spells, MaxDiscSlotsNPC, 1) -RULE_INT(Spells, MaxTotalSlotsNPC, 36) -RULE_INT(Spells, MaxTotalSlotsPET, 30) // do not set this higher than 25 until the player profile is removed from the blob +RULE_INT(Spells, MaxBuffSlotsNPC, 60) // default to Tit's limit +RULE_INT(Spells, MaxSongSlotsNPC, 0) // NPCs don't have songs ... +RULE_INT(Spells, MaxDiscSlotsNPC, 0) // NPCs don't have discs ... +RULE_INT(Spells, MaxTotalSlotsNPC, 60) // default to Tit's limit +RULE_INT(Spells, MaxTotalSlotsPET, 30) // default to Tit's limit RULE_BOOL (Spells, EnableBlockedBuffs, true) RULE_INT(Spells, ReflectType, 1) //0 = disabled, 1 = single target player spells only, 2 = all player spells, 3 = all single target spells, 4 = all spells RULE_INT(Spells, VirusSpreadDistance, 30) // The distance a viral spell will jump to its next victim diff --git a/zone/client.h b/zone/client.h index c7973de18..5b2c0a939 100644 --- a/zone/client.h +++ b/zone/client.h @@ -509,10 +509,10 @@ public: virtual int GetCurrentBuffSlots() const; virtual int GetCurrentSongSlots() const; virtual int GetCurrentDiscSlots() const { return 1; } - virtual int GetMaxBuffSlots() const { return 25; } - virtual int GetMaxSongSlots() const { return 12; } - virtual int GetMaxDiscSlots() const { return 1; } - virtual int GetMaxTotalSlots() const { return 38; } + virtual int GetMaxBuffSlots() const { return EQEmu::constants::LongBuffs; } + virtual int GetMaxSongSlots() const { return EQEmu::constants::ShortBuffs; } + virtual int GetMaxDiscSlots() const { return EQEmu::constants::DiscBuffs; } + virtual int GetMaxTotalSlots() const { return EQEmu::constants::TotalBuffs; } virtual uint32 GetFirstBuffSlot(bool disc, bool song); virtual uint32 GetLastBuffSlot(bool disc, bool song); virtual void InitializeBuffSlots(); diff --git a/zone/spells.cpp b/zone/spells.cpp index 6b875c96f..3b232f9cd 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -5534,12 +5534,12 @@ int Client::GetCurrentBuffSlots() const numbuffs++; if (GetLevel() > 74) numbuffs++; - return EQEmu::ClampUpper(numbuffs, GetMaxBuffSlots()); + return EQEmu::ClampUpper(numbuffs, EQEmu::constants::Lookup(m_ClientVersion)->LongBuffs); } int Client::GetCurrentSongSlots() const { - return 12; // AAs dont affect this + return EQEmu::constants::Lookup(m_ClientVersion)->ShortBuffs; // AAs dont affect this } void Client::InitializeBuffSlots() diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 8bf2e4d31..c4fcfc55f 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -3122,7 +3122,8 @@ void ZoneDatabase::LoadBuffs(Client *client) buffs[slot_id].instrument_mod = instrument_mod; } - max_slots = client->GetMaxBuffSlots(); + // We load up to the most our client supports + max_slots = EQEmu::constants::Lookup(client->ClientVersion())->LongBuffs; for (int index = 0; index < max_slots; ++index) { if (!IsValidSpell(buffs[index].spellid)) continue;