Revamp Buff slots

Server side we now have 63 total buff slots for clients
They match RoF/RoF2 and are mapped as 42 long, 20 short, 1 disc

The player is limited to what their clients supports, so
Tit players can have 25 buffs and 12 songs, while other can have more

When you log in, we only load up to the max your client supports,
the rest of the buffs are thrown away

Also changed is the default Max Buff slots for NPCs, they now match Tit (60)
If you are thinking about raising that, here are what some other clients support
Tit - SoF 60, SoD - UF 85, RoF - RoF2 97 (although UI only has 85 slots, you can
edit it if you want more)

Also SoD+ the pet limits match the NPC limits.

This will increase memory usage a bit, but I don't see a solution to that
Plus I think most people want this.
This commit is contained in:
Michael Cook (mackal) 2016-11-15 01:37:58 -05:00
parent 04c8fe7d2c
commit 3dec02881a
19 changed files with 358 additions and 113 deletions

View File

@ -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 {

View File

@ -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
}
};

View File

@ -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);

View File

@ -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*/

View File

@ -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*/

View File

@ -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 {

View File

@ -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 {

View File

@ -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*/

View File

@ -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 {

View File

@ -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*/

View File

@ -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 {

View File

@ -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*/

View File

@ -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 {

View File

@ -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*/

View File

@ -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*/

View File

@ -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

View File

@ -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();

View File

@ -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()

View File

@ -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;