Merge branch 'master' into resend

This commit is contained in:
Akkadius 2019-01-23 19:05:42 -06:00
commit 230d6ae964
95 changed files with 6209 additions and 4450 deletions

View File

@ -1,6 +1,45 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 1/20/2019 ==
Uleat: Added 'spells' entry to EQDictionary
Akkadius:
- [Command] Extended #goto via #goto <player_name> -
- This will work cross zone, cross instance, in zone etc.
- It works on top of the original #goto (target) and #goto x y z
- [Command] Implemented server side #who Example: https://bit.ly/2TZ2hvI
- Searches can be filtered by
- Account Name
- Base Class Name
- Guild Name
- IP
- Player Name
- Race Name
- Zone Short Name
- Features a clickable (Goto) saylink that will bring you directly to a player regardless of
whether or not they are in an instance
- [Command] Implemented: #gmzone [zone_short_name] [zone_version=0] [identifier=gmzone]
- Zones to a private GM instance
- Example: https://i.imgur.com/qswdrzO.gif
- [NPC] Fix issue where NPC's clip into the world and the client interprets them at 0,0,0
- This issue would show itself when NPC's would bunch up by a zone-in
== 1/15/2019 ==
Uleat: Activated per-expansion support for active inventory slot addressing
- Server honors expansions that alter bank size and power source, general9 and general10 slots
- Server honors gm flag behaviors for the active inventory slots of each client
== 1/11/2019 ==
Uleat: Modified rules system to ignore all runtime modifications of 'World:ExpansionSettings' and 'World:UseClientBasedExpansionSettings' fields.
- These fields are no longer allowed to be changed during server runtime through the command system
- Major syncronization issues between server and clients result when these fields are altered in-game
- It is not recommended to update these fields via sql queries while the server is in operation
- Failure to observe these warnings will result in abhorant behavior and loss of items
- Modify these fields during server operation at your own risk!
== 1/4/2019 ==
Akkadius: [Scaling] Global base scaling data has been updated in new database binary revision
== 1/1/2019 ==
Akkadius:
- [Logging] Added new logging category "MobAppearance"

File diff suppressed because it is too large Load Diff

View File

@ -217,7 +217,7 @@ namespace Convert {
/*0245*/ uint8 guildbanker;
/*0246*/ uint8 unknown0246[6]; //
/*0252*/ uint32 intoxication;
/*0256*/ uint32 spellSlotRefresh[MAX_PP_REF_MEMSPELL]; //in ms
/*0256*/ uint32 spellSlotRefresh[9]; //in ms
/*0292*/ uint32 abilitySlotRefresh;
/*0296*/ uint8 haircolor; // Player hair color
/*0297*/ uint8 beardcolor; // Player beard color
@ -256,9 +256,9 @@ namespace Convert {
/*2505*/ uint8 unknown2541[47]; // ?
/*2552*/ uint8 languages[MAX_PP_LANGUAGE];
/*2580*/ uint8 unknown2616[4];
/*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK];
/*2584*/ uint32 spell_book[480];
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
/*4632*/ uint32 mem_spells[MAX_PP_REF_MEMSPELL];
/*4632*/ uint32 mem_spells[9];
/*4668*/ uint8 unknown4704[32]; //
/*4700*/ float y; // Player y position
/*4704*/ float x; // Player x position
@ -1360,7 +1360,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Spell Convert */
first_entry = 0; rquery = "";
for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++){
for (i = 0; i < 480; i++){
if (pp->spell_book[i] > 0 && pp->spell_book[i] != 4294967295 && pp->spell_book[i] < 40000 && pp->spell_book[i] != 1){
if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->spell_book[i]);
@ -1372,7 +1372,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Max Memmed Spell Convert */
first_entry = 0; rquery = "";
for (i = 0; i < MAX_PP_REF_MEMSPELL; i++){
for (i = 0; i < 9; i++){
if (pp->mem_spells[i] > 0 && pp->mem_spells[i] != 65535 && pp->mem_spells[i] != 4294967295){
if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_memmed_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->mem_spells[i]);

View File

@ -38,16 +38,23 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <sys/time.h>
#endif
/**
* @param instance_id
* @param char_id
* @return
*/
bool Database::AddClientToInstance(uint16 instance_id, uint32 char_id)
{
std::string query = StringFormat(
"REPLACE INTO `instance_list_player` (id, charid) "
"VALUES "
"(%lu, %lu)",
(unsigned long)instance_id,
(unsigned long)char_id
);
(unsigned long) instance_id,
(unsigned long) char_id
);
auto results = QueryDatabase(query);
return results.Success();
}

View File

@ -131,6 +131,9 @@ namespace EQEmu
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
using RoF2::invslot::EQUIPMENT_BITMASK;
using RoF2::invslot::GENERAL_BITMASK;
using RoF2::invslot::CURSOR_BITMASK;
using RoF2::invslot::POSSESSIONS_BITMASK;
using RoF2::invslot::CORPSE_BITMASK;
@ -188,6 +191,10 @@ namespace EQEmu
namespace constants {
const EQEmu::versions::ClientVersion CHARACTER_CREATION_CLIENT = EQEmu::versions::ClientVersion::Titanium;
using RoF2::constants::EXPANSION;
using RoF2::constants::EXPANSION_BIT;
using RoF2::constants::EXPANSIONS_MASK;
using RoF2::constants::CHARACTER_CREATION_LIMIT;
const size_t SAY_LINK_OPENER_SIZE = 1;
@ -196,14 +203,6 @@ namespace EQEmu
const size_t SAY_LINK_CLOSER_SIZE = 1;
const size_t SAY_LINK_MAXIMUM_SIZE = (SAY_LINK_OPENER_SIZE + SAY_LINK_BODY_SIZE + SAY_LINK_TEXT_SIZE + SAY_LINK_CLOSER_SIZE);
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*/
namespace profile {
@ -221,6 +220,42 @@ namespace EQEmu
} // namespace behavior
namespace spells {
enum class CastingSlot : uint32 { // hybrid declaration
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
MaxGems = 12,
Ability = 20, // HT/LoH for Tit
PotionBelt = 21, // Tit uses a different slot for PB
Item = 22,
Discipline = 23,
AltAbility = 0xFF
};
using RoF2::spells::SPELL_ID_MAX;
using SoD::spells::SPELLBOOK_SIZE;
using UF::spells::SPELL_GEM_COUNT; // RoF+ clients define more than UF client..but, they are not valid beyond UF
using RoF2::spells::LONG_BUFFS;
using RoF2::spells::SHORT_BUFFS;
using RoF2::spells::DISC_BUFFS;
using RoF2::spells::TOTAL_BUFFS;
using RoF2::spells::NPC_BUFFS;
using RoF2::spells::PET_BUFFS;
using RoF2::spells::MERC_BUFFS;
} // namespace spells
namespace bug {
enum CategoryID : uint32 {
catOther = 0,
@ -252,27 +287,6 @@ namespace EQEmu
} // namespace bug
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
MaxGems = 12,
Ability = 20, // HT/LoH for Tit
PotionBelt = 21, // Tit uses a different slot for PB
Item = 22,
Discipline = 23,
AltAbility = 0xFF
};
} /*EQEmu*/
#endif /*COMMON_EMU_CONSTANTS_H*/

View File

@ -70,7 +70,10 @@ namespace EntityLimits
} // namespace invtype
namespace invslot {
const uint64 POSSESSIONS_BITMASK = 0x00000000007FFFFF; // based on 34-slot count (RoF+)
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
const uint64 GENERAL_BITMASK = 0x0000000000000000;
const uint64 CURSOR_BITMASK = 0x0000000000000000;
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
} // namespace invslot

View File

@ -63,32 +63,26 @@ const char* EQEmu::versions::ClientVersionName(ClientVersion client_version)
uint32 EQEmu::versions::ConvertClientVersionToClientVersionBit(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
return bit_Unknown;
case ClientVersion::Titanium:
return bit_Titanium;
return bitTitanium;
case ClientVersion::SoF:
return bit_SoF;
return bitSoF;
case ClientVersion::SoD:
return bit_SoD;
return bitSoD;
case ClientVersion::UF:
return bit_UF;
return bitUF;
case ClientVersion::RoF:
return bit_RoF;
return bitRoF;
case ClientVersion::RoF2:
return bit_RoF2;
return bitRoF2;
default:
return bit_Unknown;
return bitUnknown;
}
}
EQEmu::versions::ClientVersion EQEmu::versions::ConvertClientVersionBitToClientVersion(uint32 client_version_bit)
{
switch (client_version_bit) {
case (uint32)static_cast<unsigned int>(ClientVersion::Unknown) :
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Client62) - 1)) :
return ClientVersion::Unknown;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Titanium) - 1)) :
return ClientVersion::Titanium;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoF) - 1)) :
@ -106,27 +100,6 @@ EQEmu::versions::ClientVersion EQEmu::versions::ConvertClientVersionBitToClientV
}
}
uint32 EQEmu::versions::ConvertClientVersionToExpansion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
case ClientVersion::Titanium:
return 0x000007FFU;
case ClientVersion::SoF:
return 0x00007FFFU;
case ClientVersion::SoD:
return 0x0000FFFFU;
case ClientVersion::UF:
return 0x0001FFFFU;
case ClientVersion::RoF:
case ClientVersion::RoF2:
return 0x000FFFFFU;
default:
return 0;
}
}
bool EQEmu::versions::IsValidMobVersion(MobVersion mob_version)
{
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
@ -368,3 +341,259 @@ EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToOfflinePCMobV
return MobVersion::Unknown;
}
}
const char* EQEmu::expansions::ExpansionName(Expansion expansion)
{
switch (expansion) {
case Expansion::EverQuest:
return "EverQuest";
case Expansion::RoK:
return "The Ruins of Kunark";
case Expansion::SoV:
return "The Scars of Velious";
case Expansion::SoL:
return "The Shadows of Luclin";
case Expansion::PoP:
return "The Planes of Power";
case Expansion::LoY:
return "The Legacy of Ykesha";
case Expansion::LDoN:
return "Lost Dungeons of Norrath";
case Expansion::GoD:
return "Gates of Discord";
case Expansion::OoW:
return "Omens of War";
case Expansion::DoN:
return "Dragons of Norrath";
case Expansion::DoD:
return "Depths of Darkhollow";
case Expansion::PoR:
return "Prophecy of Ro";
case Expansion::TSS:
return "The Serpent's Spine";
case Expansion::TBS:
return "The Buried Sea";
case Expansion::SoF:
return "Secrets of Faydwer";
case Expansion::SoD:
return "Seeds of Destruction";
case Expansion::UF:
return "Underfoot";
case Expansion::HoT:
return "House of Thule";
case Expansion::VoA:
return "Veil of Alaris";
case Expansion::RoF:
return "Rain of Fear";
case Expansion::CotF:
return "Call of the Forsaken";
default:
return "Invalid Expansion";
}
}
const char* EQEmu::expansions::ExpansionName(uint32 expansion_bit)
{
return ExpansionName(ConvertExpansionBitToExpansion(expansion_bit));
}
uint32 EQEmu::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
{
switch (expansion) {
case Expansion::RoK:
return bitRoK;
case Expansion::SoV:
return bitSoV;
case Expansion::SoL:
return bitSoL;
case Expansion::PoP:
return bitPoP;
case Expansion::LoY:
return bitLoY;
case Expansion::LDoN:
return bitLDoN;
case Expansion::GoD:
return bitGoD;
case Expansion::OoW:
return bitOoW;
case Expansion::DoN:
return bitDoN;
case Expansion::DoD:
return bitDoD;
case Expansion::PoR:
return bitPoR;
case Expansion::TSS:
return bitTSS;
case Expansion::TBS:
return bitTBS;
case Expansion::SoF:
return bitSoF;
case Expansion::SoD:
return bitSoD;
case Expansion::UF:
return bitUF;
case Expansion::HoT:
return bitHoT;
case Expansion::VoA:
return bitVoA;
case Expansion::RoF:
return bitRoF;
case Expansion::CotF:
return bitCotF;
default:
return bitEverQuest;
}
}
EQEmu::expansions::Expansion EQEmu::expansions::ConvertExpansionBitToExpansion(uint32 expansion_bit)
{
switch (expansion_bit) {
case bitRoK:
return Expansion::RoK;
case bitSoV:
return Expansion::SoV;
case bitSoL:
return Expansion::SoL;
case bitPoP:
return Expansion::PoP;
case bitLoY:
return Expansion::LoY;
case bitLDoN:
return Expansion::LDoN;
case bitGoD:
return Expansion::GoD;
case bitOoW:
return Expansion::OoW;
case bitDoN:
return Expansion::DoN;
case bitDoD:
return Expansion::DoD;
case bitPoR:
return Expansion::PoR;
case bitTSS:
return Expansion::TSS;
case bitTBS:
return Expansion::TBS;
case bitSoF:
return Expansion::SoF;
case bitSoD:
return Expansion::SoD;
case bitUF:
return Expansion::UF;
case bitHoT:
return Expansion::HoT;
case bitVoA:
return Expansion::VoA;
case bitRoF:
return Expansion::RoF;
case bitCotF:
return Expansion::CotF;
default:
return Expansion::EverQuest;
}
}
uint32 EQEmu::expansions::ConvertExpansionToExpansionMask(Expansion expansion)
{
switch (expansion) {
case Expansion::RoK:
return maskRoK;
case Expansion::SoV:
return maskSoV;
case Expansion::SoL:
return maskSoL;
case Expansion::PoP:
return maskPoP;
case Expansion::LoY:
return maskLoY;
case Expansion::LDoN:
return maskLDoN;
case Expansion::GoD:
return maskGoD;
case Expansion::OoW:
return maskOoW;
case Expansion::DoN:
return maskDoN;
case Expansion::DoD:
return maskDoD;
case Expansion::PoR:
return maskPoR;
case Expansion::TSS:
return maskTSS;
case Expansion::TBS:
return maskTBS;
case Expansion::SoF:
return maskSoF;
case Expansion::SoD:
return maskSoD;
case Expansion::UF:
return maskUF;
case Expansion::HoT:
return maskHoT;
case Expansion::VoA:
return maskVoA;
case Expansion::RoF:
return maskRoF;
case Expansion::CotF:
return maskCotF;
default:
return maskEverQuest;
}
}
EQEmu::expansions::Expansion EQEmu::expansions::ConvertClientVersionToExpansion(versions::ClientVersion client_version)
{
switch (client_version) {
case versions::ClientVersion::Titanium:
return expansions::Expansion::PoR;
case versions::ClientVersion::SoF:
return expansions::Expansion::SoF;
case versions::ClientVersion::SoD:
return expansions::Expansion::SoD;
case versions::ClientVersion::UF:
return expansions::Expansion::UF;
case versions::ClientVersion::RoF:
case versions::ClientVersion::RoF2:
return expansions::Expansion::RoF;
default:
return expansions::Expansion::EverQuest;
}
}
uint32 EQEmu::expansions::ConvertClientVersionToExpansionBit(versions::ClientVersion client_version)
{
switch (client_version) {
case versions::ClientVersion::Titanium:
return expansions::bitPoR;
case versions::ClientVersion::SoF:
return expansions::bitSoF;
case versions::ClientVersion::SoD:
return expansions::bitSoD;
case versions::ClientVersion::UF:
return expansions::bitUF;
case versions::ClientVersion::RoF:
case versions::ClientVersion::RoF2:
return expansions::bitRoF;
default:
return expansions::bitEverQuest;
}
}
uint32 EQEmu::expansions::ConvertClientVersionToExpansionMask(versions::ClientVersion client_version)
{
switch (client_version) {
case versions::ClientVersion::Titanium:
return expansions::maskPoR;
case versions::ClientVersion::SoF:
return expansions::maskSoF;
case versions::ClientVersion::SoD:
return expansions::maskSoD;
case versions::ClientVersion::UF:
return expansions::maskUF;
case versions::ClientVersion::RoF:
case versions::ClientVersion::RoF2:
return expansions::maskRoF;
default:
return expansions::maskEverQuest;
}
}

View File

@ -39,26 +39,27 @@ namespace EQEmu
RoF2 // Build: 'May 10 2013 23:30:08'
};
enum ClientVersionBit : uint32 {
bit_Unknown = 0,
bit_Client62 = 0x00000001, // unsupported (placeholder for scripts)
bit_Titanium = 0x00000002,
bit_SoF = 0x00000004,
bit_SoD = 0x00000008,
bit_UF = 0x00000010,
bit_RoF = 0x00000020,
bit_RoF2 = 0x00000040,
bit_TitaniumAndEarlier = 0x00000003,
bit_SoFAndEarlier = 0x00000007,
bit_SoDAndEarlier = 0x0000000F,
bit_UFAndEarlier = 0x0000001F,
bit_RoFAndEarlier = 0x0000003F,
bit_SoFAndLater = 0xFFFFFFFC,
bit_SoDAndLater = 0xFFFFFFF8,
bit_UFAndLater = 0xFFFFFFF0,
bit_RoFAndLater = 0xFFFFFFE0,
bit_RoF2AndLater = 0xFFFFFFC0,
bit_AllClients = 0xFFFFFFFF
enum ClientVersionBitmask : uint32 {
bitUnknown = 0x00000000,
bitClient62 = 0x00000001, // unsupported (placeholder for scripts)
bitTitanium = 0x00000002,
bitSoF = 0x00000004,
bitSoD = 0x00000008,
bitUF = 0x00000010,
bitRoF = 0x00000020,
bitRoF2 = 0x00000040,
maskUnknown = 0x00000000,
maskTitaniumAndEarlier = 0x00000003,
maskSoFAndEarlier = 0x00000007,
maskSoDAndEarlier = 0x0000000F,
maskUFAndEarlier = 0x0000001F,
maskRoFAndEarlier = 0x0000003F,
maskSoFAndLater = 0xFFFFFFFC,
maskSoDAndLater = 0xFFFFFFF8,
maskUFAndLater = 0xFFFFFFF0,
maskRoFAndLater = 0xFFFFFFE0,
maskRoF2AndLater = 0xFFFFFFC0,
maskAllClients = 0xFFFFFFFF
};
const ClientVersion LastClientVersion = ClientVersion::RoF2;
@ -69,9 +70,7 @@ namespace EQEmu
const char* ClientVersionName(ClientVersion client_version);
uint32 ConvertClientVersionToClientVersionBit(ClientVersion client_version);
ClientVersion ConvertClientVersionBitToClientVersion(uint32 client_version_bit);
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
enum class MobVersion : uint32 {
Unknown = 0,
Client62,
@ -137,6 +136,87 @@ namespace EQEmu
} /*versions*/
namespace expansions {
enum class Expansion : uint32 {
EverQuest = 0,
RoK,
SoV,
SoL,
PoP,
LoY,
LDoN,
GoD,
OoW,
DoN,
DoD,
PoR,
TSS,
TBS,
SoF,
SoD,
UF,
HoT,
VoA,
RoF,
CotF
};
enum ExpansionBitmask : uint32 {
bitEverQuest = 0x00000000,
bitRoK = 0x00000001,
bitSoV = 0x00000002,
bitSoL = 0x00000004,
bitPoP = 0x00000008,
bitLoY = 0x00000010,
bitLDoN = 0x00000020,
bitGoD = 0x00000040,
bitOoW = 0x00000080,
bitDoN = 0x00000100,
bitDoD = 0x00000200,
bitPoR = 0x00000400,
bitTSS = 0x00000800,
bitTBS = 0x00001000,
bitSoF = 0x00002000,
bitSoD = 0x00004000,
bitUF = 0x00008000,
bitHoT = 0x00010000,
bitVoA = 0x00020000,
bitRoF = 0x00040000,
bitCotF = 0x00080000,
maskEverQuest = 0x00000000,
maskRoK = 0x00000001,
maskSoV = 0x00000003,
maskSoL = 0x00000007,
maskPoP = 0x0000000F,
maskLoY = 0x0000001F,
maskLDoN = 0x0000003F,
maskGoD = 0x0000007F,
maskOoW = 0x000000FF,
maskDoN = 0x000001FF,
maskDoD = 0x000003FF,
maskPoR = 0x000007FF,
maskTSS = 0x00000FFF,
maskTBS = 0x00001FFF,
maskSoF = 0x00003FFF,
maskSoD = 0x00007FFF,
maskUF = 0x0000FFFF,
maskHoT = 0x0001FFFF,
maskVoA = 0x0003FFFF,
maskRoF = 0x0007FFFF,
maskCotF = 0x000FFFFF
};
const char* ExpansionName(Expansion expansion);
const char* ExpansionName(uint32 expansion_bit);
uint32 ConvertExpansionToExpansionBit(Expansion expansion);
Expansion ConvertExpansionBitToExpansion(uint32 expansion_bit);
uint32 ConvertExpansionToExpansionMask(Expansion expansion);
Expansion ConvertClientVersionToExpansion(versions::ClientVersion client_version);
uint32 ConvertClientVersionToExpansionBit(versions::ClientVersion client_version);
uint32 ConvertClientVersionToExpansionMask(versions::ClientVersion client_version);
} /*expansions*/
} /*EQEmu*/
#endif /*COMMON_EMU_VERSIONS_H*/

File diff suppressed because it is too large Load Diff

View File

@ -33,33 +33,90 @@
namespace EQEmu
{
void InitializeDynamicLookups();
namespace constants {
class LookupEntry {
public:
struct LookupEntry {
EQEmu::expansions::Expansion Expansion;
uint32 ExpansionBit;
uint32 ExpansionsMask;
int16 CharacterCreationLimit;
int LongBuffs;
int ShortBuffs;
int DiscBuffs;
int TotalBuffs;
int NPCBuffs;
int PetBuffs;
int MercBuffs;
size_t SayLinkBodySize;
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
EQEmu::expansions::Expansion Expansion,
uint32 ExpansionBit,
uint32 ExpansionsMask,
int16 CharacterCreationLimit,
size_t SayLinkBodySize
) :
Expansion(Expansion),
ExpansionBit(ExpansionBit),
ExpansionsMask(ExpansionsMask),
CharacterCreationLimit(CharacterCreationLimit),
SayLinkBodySize(SayLinkBodySize)
{ }
};
const LookupEntry* Lookup(versions::ClientVersion client_version);
void InitializeDynamicLookups();
const LookupEntry* DynamicLookup(versions::ClientVersion client_version, bool gm_flag);
const LookupEntry* DynamicNonGMLookup(versions::ClientVersion client_version);
const LookupEntry* DynamicGMLookup(versions::ClientVersion client_version);
const LookupEntry* StaticLookup(versions::ClientVersion client_version);
} /*constants*/
namespace inventory {
class LookupEntry {
public:
struct LookupEntry {
// note: 'PossessionsBitmask' needs to be attuned to the client version with the highest number
// of possessions slots and 'InventoryTypeSize[typePossessions]' should reflect the same count
// with translators adjusting for valid slot indices. Server-side validations will be performed
// against 'PossessionsBitmask' (note: the same applies to Corpse type size and bitmask)
// against 'PossessionsBitmask' (note: the same applies to CorpseBitmask..size is not dependent)
int16 InventoryTypeSize[25]; // should reflect EQEmu::invtype::TYPE_COUNT referenced in emu_constants.h
struct InventoryTypeSize_Struct { // should reflect count and naming conventions referenced in emu_constants.h
int16 Possessions, Bank, SharedBank;
int16 Trade, World, Limbo;
int16 Tribute, TrophyTribute, GuildTribute;
int16 Merchant, Deleted, Corpse;
int16 Bazaar, Inspect, RealEstate;
int16 ViewMODPC, ViewMODBank, ViewMODSharedBank;
int16 ViewMODLimbo, AltStorage, Archived;
int16 Mail, GuildTrophyTribute, Krono;
int16 Other;
InventoryTypeSize_Struct(
int16 Possessions, int16 Bank, int16 SharedBank,
int16 Trade, int16 World, int16 Limbo,
int16 Tribute, int16 TrophyTribute, int16 GuildTribute,
int16 Merchant, int16 Deleted, int16 Corpse,
int16 Bazaar, int16 Inspect, int16 RealEstate,
int16 ViewMODPC, int16 ViewMODBank, int16 ViewMODSharedBank,
int16 ViewMODLimbo, int16 AltStorage, int16 Archived,
int16 Mail, int16 GuildTrophyTribute, int16 Krono,
int16 Other
) :
Possessions(Possessions), Bank(Bank), SharedBank(SharedBank),
Trade(Trade), World(World), Limbo(Limbo),
Tribute(Tribute), TrophyTribute(TrophyTribute), GuildTribute(GuildTribute),
Merchant(Merchant), Deleted(Deleted), Corpse(Corpse),
Bazaar(Bazaar), Inspect(Inspect), RealEstate(RealEstate),
ViewMODPC(ViewMODPC), ViewMODBank(ViewMODBank), ViewMODSharedBank(ViewMODSharedBank),
ViewMODLimbo(ViewMODLimbo), AltStorage(AltStorage), Archived(Archived),
Mail(Mail), GuildTrophyTribute(GuildTrophyTribute), Krono(Krono),
Other(Other)
{ }
};
union {
InventoryTypeSize_Struct InventoryTypeSize;
int16 InventoryTypeSizeArray[25]; // should reflect EQEmu::invtype::TYPE_COUNT referenced in emu_constants.h
};
uint64 EquipmentBitmask;
uint64 GeneralBitmask;
uint64 CursorBitmask;
uint64 PossessionsBitmask;
uint64 CorpseBitmask;
int16 BagSlotCount;
@ -69,22 +126,116 @@ namespace EQEmu
bool AllowClickCastFromBag;
bool ConcatenateInvTypeLimbo;
bool AllowOverLevelEquipment;
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
InventoryTypeSize_Struct InventoryTypeSize,
uint64 EquipmentBitmask,
uint64 GeneralBitmask,
uint64 CursorBitmask,
uint64 PossessionsBitmask,
uint64 CorpseBitmask,
int16 BagSlotCount,
int16 AugSocketCount,
bool AllowEmptyBagInBag,
bool AllowClickCastFromBag,
bool ConcatenateInvTypeLimbo,
bool AllowOverLevelEquipment
) :
InventoryTypeSize(InventoryTypeSize),
EquipmentBitmask(EquipmentBitmask),
GeneralBitmask(GeneralBitmask),
CursorBitmask(CursorBitmask),
PossessionsBitmask(PossessionsBitmask),
CorpseBitmask(CorpseBitmask),
BagSlotCount(BagSlotCount),
AugSocketCount(AugSocketCount),
AllowEmptyBagInBag(AllowEmptyBagInBag),
AllowClickCastFromBag(AllowClickCastFromBag),
ConcatenateInvTypeLimbo(ConcatenateInvTypeLimbo),
AllowOverLevelEquipment(AllowOverLevelEquipment)
{ }
};
const LookupEntry* Lookup(versions::MobVersion mob_version);
void InitializeDynamicLookups();
const LookupEntry* DynamicLookup(versions::MobVersion mob_version, bool gm_flag);
const LookupEntry* DynamicNonGMLookup(versions::MobVersion mob_version);
const LookupEntry* DynamicGMLookup(versions::MobVersion mob_version);
const LookupEntry* StaticLookup(versions::MobVersion mob_version);
} /*inventory*/
namespace behavior {
class LookupEntry {
public:
struct LookupEntry {
bool CoinHasWeight;
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
bool CoinHasWeight
) :
CoinHasWeight(CoinHasWeight)
{ }
};
const LookupEntry* Lookup(versions::MobVersion mob_version);
void InitializeDynamicLookups();
const LookupEntry* DynamicLookup(versions::MobVersion mob_version, bool gm_flag);
const LookupEntry* DynamicNonGMLookup(versions::MobVersion mob_version);
const LookupEntry* DynamicGMLookup(versions::MobVersion mob_version);
const LookupEntry* StaticLookup(versions::MobVersion mob_version);
} /*behavior*/
namespace spells {
struct LookupEntry {
int SpellIdMax;
int SpellbookSize;
int SpellGemCount;
int LongBuffs;
int ShortBuffs;
int DiscBuffs;
int TotalBuffs;
int NPCBuffs;
int PetBuffs;
int MercBuffs;
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
int SpellIdMax,
int SpellbookSize,
int SpellGemCount,
int LongBuffs,
int ShortBuffs,
int DiscBuffs,
int TotalBuffs,
int NPCBuffs,
int PetBuffs,
int MercBuffs
) :
SpellIdMax(SpellIdMax),
SpellbookSize(SpellbookSize),
SpellGemCount(SpellGemCount),
LongBuffs(LongBuffs),
ShortBuffs(ShortBuffs),
DiscBuffs(DiscBuffs),
TotalBuffs(TotalBuffs),
NPCBuffs(NPCBuffs),
PetBuffs(PetBuffs),
MercBuffs(MercBuffs)
{ }
};
void InitializeDynamicLookups();
const LookupEntry* DynamicLookup(versions::ClientVersion client_version, bool gm_flag);
const LookupEntry* DynamicNonGMLookup(versions::ClientVersion client_version);
const LookupEntry* DynamicGMLookup(versions::ClientVersion client_version);
const LookupEntry* StaticLookup(versions::ClientVersion client_version);
} /*spells*/
} /*EQEmu*/
namespace ClientUnknown

View File

@ -852,10 +852,6 @@ struct SuspendedMinion_Struct
** OpCode: 0x006a
*/
static const uint32 MAX_PP_LANGUAGE = 28;
static const uint32 MAX_PP_SPELLBOOK = 480; // Set for all functions
static const uint32 MAX_PP_MEMSPELL = static_cast<uint32>(EQEmu::CastingSlot::MaxGems); // Set to latest client so functions can work right -- 12
static const uint32 MAX_PP_REF_SPELLBOOK = 480; // Set for Player Profile size retain
static const uint32 MAX_PP_REF_MEMSPELL = 9; // Set for Player Profile size retain
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
@ -935,7 +931,7 @@ struct PlayerProfile_Struct
/*0245*/ uint8 guildbanker;
/*0246*/ uint8 unknown0246[6]; //
/*0252*/ uint32 intoxication;
/*0256*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; //in ms
/*0256*/ uint32 spellSlotRefresh[EQEmu::spells::SPELL_GEM_COUNT]; //in ms
/*0292*/ uint32 abilitySlotRefresh;
/*0296*/ uint8 haircolor; // Player hair color
/*0297*/ uint8 beardcolor; // Player beard color
@ -974,9 +970,9 @@ struct PlayerProfile_Struct
/*2505*/ uint8 unknown2541[47]; // ?
/*2552*/ uint8 languages[MAX_PP_LANGUAGE];
/*2580*/ uint8 unknown2616[4];
/*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK];
/*2584*/ uint32 spell_book[EQEmu::spells::SPELLBOOK_SIZE];
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
/*4632*/ uint32 mem_spells[MAX_PP_MEMSPELL];
/*4632*/ uint32 mem_spells[EQEmu::spells::SPELL_GEM_COUNT];
/*4668*/ uint8 unknown4704[32]; //
/*4700*/ float y; // Player y position
/*4704*/ float x; // Player x position
@ -4373,7 +4369,7 @@ struct AnnoyingZoneUnknown_Struct {
};
struct LoadSpellSet_Struct {
uint32 spell[MAX_PP_MEMSPELL]; // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
uint32 spell[EQEmu::spells::SPELL_GEM_COUNT]; // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
uint32 unknown; //there seems to be an extra field in this packet...
};

View File

@ -119,19 +119,15 @@ EQEmu::InventoryProfile::~InventoryProfile()
m_trade.clear();
}
bool EQEmu::InventoryProfile::SetInventoryVersion(versions::MobVersion inventory_version) {
if (!m_mob_version_set) {
m_mob_version = versions::ValidateMobVersion(inventory_version);
m_lookup = inventory::Lookup(m_mob_version);
m_mob_version_set = true;
return true;
}
else {
m_lookup = inventory::Lookup(versions::MobVersion::Unknown);
Log(Logs::General, Logs::Error, "InventoryVersion set request after initial set (old: %u, new: %u)",
static_cast<uint32>(m_mob_version), static_cast<uint32>(inventory_version));
return false;
}
void EQEmu::InventoryProfile::SetInventoryVersion(versions::MobVersion inventory_version) {
m_mob_version = versions::ValidateMobVersion(inventory_version);
SetGMInventory(m_gm_inventory);
}
void EQEmu::InventoryProfile::SetGMInventory(bool gmi_flag) {
m_gm_inventory = gmi_flag;
m_lookup = inventory::DynamicLookup(m_mob_version, gmi_flag);
}
void EQEmu::InventoryProfile::CleanDirty() {
@ -241,12 +237,12 @@ int16 EQEmu::InventoryProfile::PutItem(int16 slot_id, const ItemInstance& inst)
return EQEmu::invslot::SLOT_INVALID;
}
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank])
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= m_lookup->InventoryTypeSize.Bank)
return EQEmu::invslot::SLOT_INVALID;
}
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank])
if (temp_slot >= m_lookup->InventoryTypeSize.Bank)
return EQEmu::invslot::SLOT_INVALID;
}
@ -298,14 +294,14 @@ bool EQEmu::InventoryProfile::SwapItem(
}
}
else if (source_slot <= EQEmu::invslot::BANK_END && source_slot >= EQEmu::invslot::BANK_BEGIN) {
if ((source_slot - EQEmu::invslot::BANK_BEGIN) >= m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank]) {
if ((source_slot - EQEmu::invslot::BANK_BEGIN) >= m_lookup->InventoryTypeSize.Bank) {
fail_state = swapNotAllowed;
return false;
}
}
else if (source_slot <= EQEmu::invbag::BANK_BAGS_END && source_slot >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (source_slot - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank]) {
if (temp_slot >= m_lookup->InventoryTypeSize.Bank) {
fail_state = swapNotAllowed;
return false;
}
@ -325,14 +321,14 @@ bool EQEmu::InventoryProfile::SwapItem(
}
}
else if (destination_slot <= EQEmu::invslot::BANK_END && destination_slot >= EQEmu::invslot::BANK_BEGIN) {
if ((destination_slot - EQEmu::invslot::BANK_BEGIN) >= m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank]) {
if ((destination_slot - EQEmu::invslot::BANK_BEGIN) >= m_lookup->InventoryTypeSize.Bank) {
fail_state = swapNotAllowed;
return false;
}
}
else if (destination_slot <= EQEmu::invbag::BANK_BAGS_END && destination_slot >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (destination_slot - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank]) {
if (temp_slot >= m_lookup->InventoryTypeSize.Bank) {
fail_state = swapNotAllowed;
return false;
}
@ -1092,7 +1088,7 @@ bool EQEmu::InventoryProfile::SupportsClickCasting(int16 slot_id)
return true;
}
else if (slot_id >= invbag::GENERAL_BAGS_BEGIN && slot_id <= invbag::GENERAL_BAGS_END) {
if (inventory::Lookup(m_mob_version)->AllowClickCastFromBag)
if (inventory::StaticLookup(m_mob_version)->AllowClickCastFromBag)
return true;
}
@ -1308,7 +1304,7 @@ EQEmu::ItemInstance* EQEmu::InventoryProfile::_GetItem(const std::map<int16, Ite
return nullptr;
}
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
if (slot_id - EQEmu::invslot::BANK_BEGIN >= m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank])
if (slot_id - EQEmu::invslot::BANK_BEGIN >= m_lookup->InventoryTypeSize.Bank)
return nullptr;
}
@ -1360,7 +1356,7 @@ int16 EQEmu::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst)
result = slot_id;
}
else if (slot_id >= invslot::BANK_BEGIN && slot_id <= invslot::BANK_END) {
if (slot_id - EQEmu::invslot::BANK_BEGIN < m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank]) {
if (slot_id - EQEmu::invslot::BANK_BEGIN < m_lookup->InventoryTypeSize.Bank) {
m_bank[slot_id] = inst;
result = slot_id;
}
@ -1403,7 +1399,7 @@ int16 EQEmu::InventoryProfile::_HasItem(std::map<int16, ItemInstance*>& bucket,
continue;
}
else if (iter->first <= EQEmu::invslot::BANK_END && iter->first >= EQEmu::invslot::BANK_BEGIN) {
if (iter->first - EQEmu::invslot::BANK_BEGIN >= m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank])
if (iter->first - EQEmu::invslot::BANK_BEGIN >= m_lookup->InventoryTypeSize.Bank)
continue;
}
@ -1505,7 +1501,7 @@ int16 EQEmu::InventoryProfile::_HasItemByUse(std::map<int16, ItemInstance*>& buc
continue;
}
else if (iter->first <= EQEmu::invslot::BANK_END && iter->first >= EQEmu::invslot::BANK_BEGIN) {
if (iter->first - EQEmu::invslot::BANK_BEGIN >= m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank])
if (iter->first - EQEmu::invslot::BANK_BEGIN >= m_lookup->InventoryTypeSize.Bank)
continue;
}
@ -1578,7 +1574,7 @@ int16 EQEmu::InventoryProfile::_HasItemByLoreGroup(std::map<int16, ItemInstance*
continue;
}
else if (iter->first <= EQEmu::invslot::BANK_END && iter->first >= EQEmu::invslot::BANK_BEGIN) {
if (iter->first - EQEmu::invslot::BANK_BEGIN >= m_lookup->InventoryTypeSize[EQEmu::invtype::typeBank])
if (iter->first - EQEmu::invslot::BANK_BEGIN >= m_lookup->InventoryTypeSize.Bank)
continue;
}

View File

@ -87,15 +87,18 @@ namespace EQEmu
InventoryProfile() {
m_mob_version = versions::MobVersion::Unknown;
m_mob_version_set = false;
m_lookup = inventory::Lookup(versions::MobVersion::Unknown);
m_gm_inventory = false;
m_lookup = inventory::StaticLookup(versions::MobVersion::Unknown);
}
~InventoryProfile();
bool SetInventoryVersion(versions::MobVersion inventory_version);
bool SetInventoryVersion(versions::ClientVersion client_version) { return SetInventoryVersion(versions::ConvertClientVersionToMobVersion(client_version)); }
void SetInventoryVersion(versions::MobVersion inventory_version);
void SetInventoryVersion(versions::ClientVersion client_version) { SetInventoryVersion(versions::ConvertClientVersionToMobVersion(client_version)); }
versions::MobVersion InventoryVersion() { return m_mob_version; }
void SetGMInventory(bool gmi_flag);
bool GMInventory() const { return m_gm_inventory; }
versions::MobVersion InventoryVersion() const { return m_mob_version; }
const inventory::LookupEntry* GetLookup() const { return m_lookup; }
@ -222,7 +225,7 @@ namespace EQEmu
private:
// Active mob version
versions::MobVersion m_mob_version;
bool m_mob_version_set;
bool m_gm_inventory;
const inventory::LookupEntry* m_lookup;
};
}

View File

@ -65,8 +65,8 @@ namespace RoF
// client to server say link converter
static inline void RoFToServerSayLink(std::string& serverSayLink, const std::string& rofSayLink);
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot);
static inline spells::CastingSlot ServerToRoFCastingSlot(EQEmu::spells::CastingSlot slot);
static inline EQEmu::spells::CastingSlot RoFToServerCastingSlot(spells::CastingSlot slot);
static inline int ServerToRoFBuffSlot(int index);
static inline int RoFToServerBuffSlot(int index);
@ -502,7 +502,7 @@ namespace RoF
ENCODE_LENGTH_EXACT(CastSpell_Struct);
SETUP_DIRECT_ENCODE(CastSpell_Struct, structs::CastSpell_Struct);
eq->slot = static_cast<uint32>(ServerToRoFCastingSlot(static_cast<EQEmu::CastingSlot>(emu->slot)));
eq->slot = static_cast<uint32>(ServerToRoFCastingSlot(static_cast<EQEmu::spells::CastingSlot>(emu->slot)));
OUT(spell_id);
eq->inventory_slot = ServerToRoFSlot(emu->inventoryslot);
@ -2124,33 +2124,33 @@ namespace RoF
outapp->WriteUInt32(0);
}
outapp->WriteUInt32(structs::MAX_PP_SPELLBOOK); // Spellbook slots
outapp->WriteUInt32(spells::SPELLBOOK_SIZE); // Spellbook slots
for (uint32 r = 0; r < MAX_PP_SPELLBOOK; r++)
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++)
{
outapp->WriteUInt32(emu->spell_book[r]);
}
// zeroes for the rest of the spellbook slots
for (uint32 r = 0; r < structs::MAX_PP_SPELLBOOK - MAX_PP_SPELLBOOK; r++)
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE - EQEmu::spells::SPELLBOOK_SIZE; r++)
{
outapp->WriteUInt32(0xFFFFFFFFU);
}
outapp->WriteUInt32(structs::MAX_PP_MEMSPELL); // Memorised spell slots
outapp->WriteUInt32(spells::SPELL_GEM_COUNT); // Memorised spell slots
for (uint32 r = 0; r < MAX_PP_MEMSPELL; r++) // first 12
for (uint32 r = 0; r < EQEmu::spells::SPELL_GEM_COUNT; r++) // first 12
{
outapp->WriteUInt32(emu->mem_spells[r]);
}
// zeroes for the rest of the slots -- the other 4 which don't work at all!
for (uint32 r = 0; r < structs::MAX_PP_MEMSPELL - MAX_PP_MEMSPELL; r++)
for (uint32 r = 0; r < spells::SPELL_GEM_COUNT - EQEmu::spells::SPELL_GEM_COUNT; r++)
{
outapp->WriteUInt32(0xFFFFFFFFU);
}
outapp->WriteUInt32(13); // gem refresh count
for (uint32 r = 0; r < MAX_PP_MEMSPELL; r++)
for (uint32 r = 0; r < EQEmu::spells::SPELL_GEM_COUNT; r++)
{
outapp->WriteUInt32(emu->spellSlotRefresh[r]); // spell gem refresh
}
@ -2334,7 +2334,8 @@ namespace RoF
outapp->WriteUInt32(emu->lastlogin);
outapp->WriteUInt32(emu->timePlayedMin);
outapp->WriteUInt32(emu->timeentitledonaccount);
outapp->WriteUInt32(0x0007ffff); // Expansion bitmask
outapp->WriteUInt32(emu->expansions);
//outapp->WriteUInt32(0x0007ffff); // Expansion bitmask
outapp->WriteUInt32(structs::MAX_PP_LANGUAGE);
@ -4220,7 +4221,7 @@ namespace RoF
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
emu->slot = static_cast<uint32>(RoFToServerCastingSlot(static_cast<CastingSlot>(eq->slot)));
emu->slot = static_cast<uint32>(RoFToServerCastingSlot(static_cast<spells::CastingSlot>(eq->slot)));
IN(spell_id);
emu->inventoryslot = RoFToServerSlot(eq->inventory_slot);
@ -4737,7 +4738,7 @@ namespace RoF
DECODE_LENGTH_EXACT(structs::LoadSpellSet_Struct);
SETUP_DIRECT_DECODE(LoadSpellSet_Struct, structs::LoadSpellSet_Struct);
for (unsigned int i = 0; i < MAX_PP_MEMSPELL; ++i)
for (unsigned int i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; ++i)
{
if (eq->spell[i] == 0)
emu->spell[i] = 0xFFFFFFFF;
@ -6086,80 +6087,80 @@ namespace RoF
}
}
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot)
static inline spells::CastingSlot ServerToRoFCastingSlot(EQEmu::spells::CastingSlot slot)
{
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Gem10:
return CastingSlot::Gem10;
case EQEmu::CastingSlot::Gem11:
return CastingSlot::Gem11;
case EQEmu::CastingSlot::Gem12:
return CastingSlot::Gem12;
case EQEmu::CastingSlot::Item:
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::Item;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
case EQEmu::spells::CastingSlot::Gem1:
return spells::CastingSlot::Gem1;
case EQEmu::spells::CastingSlot::Gem2:
return spells::CastingSlot::Gem2;
case EQEmu::spells::CastingSlot::Gem3:
return spells::CastingSlot::Gem3;
case EQEmu::spells::CastingSlot::Gem4:
return spells::CastingSlot::Gem4;
case EQEmu::spells::CastingSlot::Gem5:
return spells::CastingSlot::Gem5;
case EQEmu::spells::CastingSlot::Gem6:
return spells::CastingSlot::Gem6;
case EQEmu::spells::CastingSlot::Gem7:
return spells::CastingSlot::Gem7;
case EQEmu::spells::CastingSlot::Gem8:
return spells::CastingSlot::Gem8;
case EQEmu::spells::CastingSlot::Gem9:
return spells::CastingSlot::Gem9;
case EQEmu::spells::CastingSlot::Gem10:
return spells::CastingSlot::Gem10;
case EQEmu::spells::CastingSlot::Gem11:
return spells::CastingSlot::Gem11;
case EQEmu::spells::CastingSlot::Gem12:
return spells::CastingSlot::Gem12;
case EQEmu::spells::CastingSlot::Item:
case EQEmu::spells::CastingSlot::PotionBelt:
return spells::CastingSlot::Item;
case EQEmu::spells::CastingSlot::Discipline:
return spells::CastingSlot::Discipline;
case EQEmu::spells::CastingSlot::AltAbility:
return spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
return spells::CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot)
static inline EQEmu::spells::CastingSlot RoFToServerCastingSlot(spells::CastingSlot slot)
{
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Gem10:
return EQEmu::CastingSlot::Gem10;
case CastingSlot::Gem11:
return EQEmu::CastingSlot::Gem11;
case CastingSlot::Gem12:
return EQEmu::CastingSlot::Gem12;
case CastingSlot::Discipline:
return EQEmu::CastingSlot::Discipline;
case CastingSlot::Item:
return EQEmu::CastingSlot::Item;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
case spells::CastingSlot::Gem1:
return EQEmu::spells::CastingSlot::Gem1;
case spells::CastingSlot::Gem2:
return EQEmu::spells::CastingSlot::Gem2;
case spells::CastingSlot::Gem3:
return EQEmu::spells::CastingSlot::Gem3;
case spells::CastingSlot::Gem4:
return EQEmu::spells::CastingSlot::Gem4;
case spells::CastingSlot::Gem5:
return EQEmu::spells::CastingSlot::Gem5;
case spells::CastingSlot::Gem6:
return EQEmu::spells::CastingSlot::Gem6;
case spells::CastingSlot::Gem7:
return EQEmu::spells::CastingSlot::Gem7;
case spells::CastingSlot::Gem8:
return EQEmu::spells::CastingSlot::Gem8;
case spells::CastingSlot::Gem9:
return EQEmu::spells::CastingSlot::Gem9;
case spells::CastingSlot::Gem10:
return EQEmu::spells::CastingSlot::Gem10;
case spells::CastingSlot::Gem11:
return EQEmu::spells::CastingSlot::Gem11;
case spells::CastingSlot::Gem12:
return EQEmu::spells::CastingSlot::Gem12;
case spells::CastingSlot::Discipline:
return EQEmu::spells::CastingSlot::Discipline;
case spells::CastingSlot::Item:
return EQEmu::spells::CastingSlot::Item;
case spells::CastingSlot::AltAbility:
return EQEmu::spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
return EQEmu::spells::CastingSlot::Discipline;
}
}
@ -6168,12 +6169,12 @@ namespace RoF
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;
if (index >= EQEmu::spells::LONG_BUFFS + EQEmu::spells::SHORT_BUFFS)
return index - EQEmu::spells::LONG_BUFFS - EQEmu::spells::SHORT_BUFFS +
spells::LONG_BUFFS + spells::SHORT_BUFFS;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
if (index >= EQEmu::spells::LONG_BUFFS)
return index - EQEmu::spells::LONG_BUFFS + spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
@ -6181,12 +6182,12 @@ namespace RoF
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;
if (index >= spells::LONG_BUFFS + spells::SHORT_BUFFS)
return index - spells::LONG_BUFFS - spells::SHORT_BUFFS + EQEmu::spells::LONG_BUFFS +
EQEmu::spells::SHORT_BUFFS;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
if (index >= spells::LONG_BUFFS)
return index - spells::LONG_BUFFS + EQEmu::spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}

View File

@ -50,24 +50,6 @@ namespace RoF
#include "rof_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
Item = 12,
Discipline = 13,
AltAbility = 0xFF
};
}; /*RoF*/
#endif /*COMMON_ROF_H*/

View File

@ -65,8 +65,8 @@ namespace RoF2
// client to server say link converter
static inline void RoF2ToServerSayLink(std::string &server_saylink, const std::string &rof2_saylink);
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot);
static inline spells::CastingSlot ServerToRoF2CastingSlot(EQEmu::spells::CastingSlot slot);
static inline EQEmu::spells::CastingSlot RoF2ToServerCastingSlot(spells::CastingSlot slot);
static inline int ServerToRoF2BuffSlot(int index);
static inline int RoF2ToServerBuffSlot(int index);
@ -570,7 +570,7 @@ namespace RoF2
ENCODE_LENGTH_EXACT(CastSpell_Struct);
SETUP_DIRECT_ENCODE(CastSpell_Struct, structs::CastSpell_Struct);
eq->slot = static_cast<uint32>(ServerToRoF2CastingSlot(static_cast<EQEmu::CastingSlot>(emu->slot)));
eq->slot = static_cast<uint32>(ServerToRoF2CastingSlot(static_cast<EQEmu::spells::CastingSlot>(emu->slot)));
OUT(spell_id);
eq->inventory_slot = ServerToRoF2Slot(emu->inventoryslot);
@ -2200,33 +2200,33 @@ namespace RoF2
outapp->WriteUInt32(0);
}
outapp->WriteUInt32(structs::MAX_PP_SPELLBOOK); // Spellbook slots
outapp->WriteUInt32(spells::SPELLBOOK_SIZE); // Spellbook slots
for (uint32 r = 0; r < MAX_PP_SPELLBOOK; r++)
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++)
{
outapp->WriteUInt32(emu->spell_book[r]);
}
// zeroes for the rest of the spellbook slots
for (uint32 r = 0; r < structs::MAX_PP_SPELLBOOK - MAX_PP_SPELLBOOK; r++)
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE - EQEmu::spells::SPELLBOOK_SIZE; r++)
{
outapp->WriteUInt32(0xFFFFFFFFU);
}
outapp->WriteUInt32(structs::MAX_PP_MEMSPELL); // Memorised spell slots
outapp->WriteUInt32(spells::SPELL_GEM_COUNT); // Memorised spell slots
for (uint32 r = 0; r < MAX_PP_MEMSPELL; r++) // write first 12
for (uint32 r = 0; r < EQEmu::spells::SPELL_GEM_COUNT; r++) // write first 12
{
outapp->WriteUInt32(emu->mem_spells[r]);
}
// zeroes for the rest of the slots the other 4, which actually don't work on the client at all :D
for (uint32 r = 0; r < structs::MAX_PP_MEMSPELL - MAX_PP_MEMSPELL; r++)
for (uint32 r = 0; r < spells::SPELL_GEM_COUNT - EQEmu::spells::SPELL_GEM_COUNT; r++)
{
outapp->WriteUInt32(0xFFFFFFFFU);
}
outapp->WriteUInt32(13); // gem refresh counts
for (uint32 r = 0; r < MAX_PP_MEMSPELL; r++)
for (uint32 r = 0; r < EQEmu::spells::SPELL_GEM_COUNT; r++)
{
outapp->WriteUInt32(emu->spellSlotRefresh[r]); // spell gem refresh
}
@ -4460,7 +4460,7 @@ namespace RoF2
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
emu->slot = static_cast<uint32>(RoF2ToServerCastingSlot(static_cast<CastingSlot>(eq->slot)));
emu->slot = static_cast<uint32>(RoF2ToServerCastingSlot(static_cast<spells::CastingSlot>(eq->slot)));
IN(spell_id);
emu->inventoryslot = RoF2ToServerSlot(eq->inventory_slot);
@ -4976,7 +4976,7 @@ namespace RoF2
DECODE_LENGTH_EXACT(structs::LoadSpellSet_Struct);
SETUP_DIRECT_DECODE(LoadSpellSet_Struct, structs::LoadSpellSet_Struct);
for (unsigned int i = 0; i < MAX_PP_MEMSPELL; ++i)
for (unsigned int i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; ++i)
{
if (eq->spell[i] == 0)
emu->spell[i] = 0xFFFFFFFF;
@ -6342,80 +6342,80 @@ namespace RoF2
}
}
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot)
static inline spells::CastingSlot ServerToRoF2CastingSlot(EQEmu::spells::CastingSlot slot)
{
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Gem10:
return CastingSlot::Gem10;
case EQEmu::CastingSlot::Gem11:
return CastingSlot::Gem11;
case EQEmu::CastingSlot::Gem12:
return CastingSlot::Gem12;
case EQEmu::CastingSlot::Item:
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::Item;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
case EQEmu::spells::CastingSlot::Gem1:
return spells::CastingSlot::Gem1;
case EQEmu::spells::CastingSlot::Gem2:
return spells::CastingSlot::Gem2;
case EQEmu::spells::CastingSlot::Gem3:
return spells::CastingSlot::Gem3;
case EQEmu::spells::CastingSlot::Gem4:
return spells::CastingSlot::Gem4;
case EQEmu::spells::CastingSlot::Gem5:
return spells::CastingSlot::Gem5;
case EQEmu::spells::CastingSlot::Gem6:
return spells::CastingSlot::Gem6;
case EQEmu::spells::CastingSlot::Gem7:
return spells::CastingSlot::Gem7;
case EQEmu::spells::CastingSlot::Gem8:
return spells::CastingSlot::Gem8;
case EQEmu::spells::CastingSlot::Gem9:
return spells::CastingSlot::Gem9;
case EQEmu::spells::CastingSlot::Gem10:
return spells::CastingSlot::Gem10;
case EQEmu::spells::CastingSlot::Gem11:
return spells::CastingSlot::Gem11;
case EQEmu::spells::CastingSlot::Gem12:
return spells::CastingSlot::Gem12;
case EQEmu::spells::CastingSlot::Item:
case EQEmu::spells::CastingSlot::PotionBelt:
return spells::CastingSlot::Item;
case EQEmu::spells::CastingSlot::Discipline:
return spells::CastingSlot::Discipline;
case EQEmu::spells::CastingSlot::AltAbility:
return spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
return spells::CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot)
static inline EQEmu::spells::CastingSlot RoF2ToServerCastingSlot(spells::CastingSlot slot)
{
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Gem10:
return EQEmu::CastingSlot::Gem10;
case CastingSlot::Gem11:
return EQEmu::CastingSlot::Gem11;
case CastingSlot::Gem12:
return EQEmu::CastingSlot::Gem12;
case CastingSlot::Discipline:
return EQEmu::CastingSlot::Discipline;
case CastingSlot::Item:
return EQEmu::CastingSlot::Item;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
case spells::CastingSlot::Gem1:
return EQEmu::spells::CastingSlot::Gem1;
case spells::CastingSlot::Gem2:
return EQEmu::spells::CastingSlot::Gem2;
case spells::CastingSlot::Gem3:
return EQEmu::spells::CastingSlot::Gem3;
case spells::CastingSlot::Gem4:
return EQEmu::spells::CastingSlot::Gem4;
case spells::CastingSlot::Gem5:
return EQEmu::spells::CastingSlot::Gem5;
case spells::CastingSlot::Gem6:
return EQEmu::spells::CastingSlot::Gem6;
case spells::CastingSlot::Gem7:
return EQEmu::spells::CastingSlot::Gem7;
case spells::CastingSlot::Gem8:
return EQEmu::spells::CastingSlot::Gem8;
case spells::CastingSlot::Gem9:
return EQEmu::spells::CastingSlot::Gem9;
case spells::CastingSlot::Gem10:
return EQEmu::spells::CastingSlot::Gem10;
case spells::CastingSlot::Gem11:
return EQEmu::spells::CastingSlot::Gem11;
case spells::CastingSlot::Gem12:
return EQEmu::spells::CastingSlot::Gem12;
case spells::CastingSlot::Discipline:
return EQEmu::spells::CastingSlot::Discipline;
case spells::CastingSlot::Item:
return EQEmu::spells::CastingSlot::Item;
case spells::CastingSlot::AltAbility:
return EQEmu::spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
return EQEmu::spells::CastingSlot::Discipline;
}
}
@ -6424,12 +6424,12 @@ namespace RoF2
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;
if (index >= EQEmu::spells::LONG_BUFFS + EQEmu::spells::SHORT_BUFFS)
return index - EQEmu::spells::LONG_BUFFS - EQEmu::spells::SHORT_BUFFS +
spells::LONG_BUFFS + spells::SHORT_BUFFS;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
if (index >= EQEmu::spells::LONG_BUFFS)
return index - EQEmu::spells::LONG_BUFFS + spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
@ -6437,12 +6437,12 @@ namespace RoF2
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;
if (index >= spells::LONG_BUFFS + spells::SHORT_BUFFS)
return index - spells::LONG_BUFFS - spells::SHORT_BUFFS + EQEmu::spells::LONG_BUFFS +
EQEmu::spells::SHORT_BUFFS;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
if (index >= spells::LONG_BUFFS)
return index - spells::LONG_BUFFS + EQEmu::spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}

View File

@ -50,24 +50,6 @@ namespace RoF2
#include "rof2_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
Item = 12,
Discipline = 13,
AltAbility = 0xFF
};
}; /*RoF2*/
#endif /*COMMON_ROF2_H*/

View File

@ -183,8 +183,12 @@ namespace RoF2
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
const uint64 POSSESSIONS_BITMASK = 0x00000003FFFFFFFF; // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = 0x01FFFFFFFF800000; // based on 34-slot count (RoF+)
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
const uint64 GENERAL_BITMASK = 0x00000001FF800000;
const uint64 CURSOR_BITMASK = 0x0000000200000000;
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 34)); // based on 34-slot count (RoF+)
const char* GetInvPossessionsSlotName(int16 inv_slot);
const char* GetInvSlotName(int16 inv_type, int16 inv_slot);
@ -259,18 +263,14 @@ namespace RoF2
namespace constants {
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::RoF2; }
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::RoF;
const uint32 EXPANSION_BIT = EQEmu::expansions::bitRoF;
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskRoF;
const size_t CHARACTER_CREATION_LIMIT = 12;
const size_t SAY_LINK_BODY_SIZE = 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 {
@ -287,6 +287,42 @@ namespace RoF2
} /*skills*/
namespace spells {
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::RoF2; }
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
MaxGems = 16, // fallacy..only 12 slot are useable...
Item = 12,
Discipline = 13,
AltAbility = 0xFF
};
const int SPELL_ID_MAX = 45000;
const int SPELLBOOK_SIZE = 720;
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
const int LONG_BUFFS = 42;
const int SHORT_BUFFS = 20;
const int DISC_BUFFS = 1;
const int TOTAL_BUFFS = LONG_BUFFS + SHORT_BUFFS + DISC_BUFFS;
const int NPC_BUFFS = 97;
const int PET_BUFFS = NPC_BUFFS;
const int MERC_BUFFS = LONG_BUFFS;
} /*spells*/
}; /*RoF2*/
#endif /*COMMON_ROF2_LIMITS_H*/

View File

@ -128,8 +128,7 @@ static const uint32 MAX_NUMBER_GUILDS = 1500;
// Used primarily in the Player Profile:
static const uint32 MAX_PP_LANGUAGE = 32; // was 25
static const uint32 MAX_PP_SPELLBOOK = 720; // was 480
static const uint32 MAX_PP_MEMSPELL = 16; // was 12
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 300;
@ -1167,9 +1166,9 @@ union
/*06092*/ uint32 timestamp2_count; // Seen 100
/*06096*/ uint32 timestamps2[100]; // Unknown Unix Timestamps - maybe Skill related?
/*06496*/ uint32 spell_book_count; // Seen 720
/*06500*/ uint32 spell_book[MAX_PP_SPELLBOOK]; // List of the Spells in spellbook 720 = 90 pages [2880 bytes]
/*06500*/ uint32 spell_book[spells::SPELLBOOK_SIZE]; // List of the Spells in spellbook 720 = 90 pages [2880 bytes]
/*09380*/ uint32 mem_spell_count; // Seen 16
/*09384*/ int32 mem_spells[MAX_PP_MEMSPELL]; // [16] List of spells memorized - First 12 are set or -1 and last 4 are 0s
/*09384*/ int32 mem_spells[spells::SPELL_GEM_COUNT]; // [16] List of spells memorized - First 12 are set or -1 and last 4 are 0s
/*09448*/ uint32 unknown16_count; // Seen 13
/*09452*/ uint32 unknown_rof16[13]; // Possibly spell or buff related
/*09504*/ uint8 unknown_rof17; // Seen 0 or 8

View File

@ -181,8 +181,12 @@ namespace RoF
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
const uint64 POSSESSIONS_BITMASK = 0x00000003FFFFFFFF; // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = 0x01FFFFFFFF800000; // based on 34-slot count (RoF+)
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
const uint64 GENERAL_BITMASK = 0x00000001FF800000;
const uint64 CURSOR_BITMASK = 0x0000000200000000;
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 34)); // based on 34-slot count (RoF+)
const char* GetInvPossessionsSlotName(int16 inv_slot);
const char* GetInvSlotName(int16 inv_type, int16 inv_slot);
@ -250,18 +254,14 @@ namespace RoF
namespace constants {
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::RoF; }
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::RoF;
const uint32 EXPANSION_BIT = EQEmu::expansions::bitRoF;
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskRoF;
const size_t CHARACTER_CREATION_LIMIT = 12;
const size_t SAY_LINK_BODY_SIZE = 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 {
@ -278,6 +278,42 @@ namespace RoF
} /*skills*/
namespace spells {
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::RoF; }
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
MaxGems = 16, // fallacy..only 12 slots are useable
Item = 12,
Discipline = 13,
AltAbility = 0xFF
};
const int SPELL_ID_MAX = 45000;
const int SPELLBOOK_SIZE = 720;
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
const int LONG_BUFFS = 42;
const int SHORT_BUFFS = 20;
const int DISC_BUFFS = 1;
const int TOTAL_BUFFS = LONG_BUFFS + SHORT_BUFFS + DISC_BUFFS;
const int NPC_BUFFS = 97;
const int PET_BUFFS = NPC_BUFFS;
const int MERC_BUFFS = LONG_BUFFS;
} /*spells*/
}; /*RoF*/
#endif /*COMMON_ROF_LIMITS_H*/

View File

@ -128,8 +128,7 @@ static const uint32 MAX_NUMBER_GUILDS = 1500;
// Used primarily in the Player Profile:
static const uint32 MAX_PP_LANGUAGE = 32; // was 25
static const uint32 MAX_PP_SPELLBOOK = 720; // was 480
static const uint32 MAX_PP_MEMSPELL = 16; // was 12
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 300;
@ -1108,9 +1107,9 @@ union
/*06092*/ uint32 timestamp2_count; // Seen 100
/*06096*/ uint32 timestamps2[100]; // Unknown Unix Timestamps - maybe Skill related?
/*06496*/ uint32 spell_book_count; // Seen 720
/*06500*/ uint32 spell_book[MAX_PP_SPELLBOOK]; // List of the Spells in spellbook 720 = 90 pages [2880 bytes]
/*06500*/ uint32 spell_book[spells::SPELLBOOK_SIZE]; // List of the Spells in spellbook 720 = 90 pages [2880 bytes]
/*09380*/ uint32 mem_spell_count; // Seen 16
/*09384*/ int32 mem_spells[MAX_PP_MEMSPELL]; // [16] List of spells memorized - First 12 are set or -1 and last 4 are 0s
/*09384*/ int32 mem_spells[spells::SPELL_GEM_COUNT]; // [16] List of spells memorized - First 12 are set or -1 and last 4 are 0s
/*09448*/ uint32 unknown16_count; // Seen 13
/*09452*/ uint32 unknown_rof16[13]; // Possibly spell or buff related
/*09504*/ uint8 unknown_rof17; // Seen 0 or 8

View File

@ -59,8 +59,8 @@ namespace SoD
// client to server say link converter
static inline void SoDToServerSayLink(std::string &server_saylink, const std::string &sod_saylink);
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot);
static inline spells::CastingSlot ServerToSoDCastingSlot(EQEmu::spells::CastingSlot slot);
static inline EQEmu::spells::CastingSlot SoDToServerCastingSlot(spells::CastingSlot slot);
static inline int ServerToSoDBuffSlot(int index);
static inline int SoDToServerBuffSlot(int index);
@ -1452,7 +1452,7 @@ namespace SoD
}
OUT(deity);
OUT(intoxication);
OUT_array(spellSlotRefresh, structs::MAX_PP_MEMSPELL);
OUT_array(spellSlotRefresh, spells::SPELL_GEM_COUNT);
OUT(abilitySlotRefresh);
OUT(points); // Relocation Test
// OUT(unknown0166[4]);
@ -1492,9 +1492,9 @@ namespace SoD
OUT(WIS);
OUT(face);
// OUT(unknown02264[47]);
OUT_array(spell_book, structs::MAX_PP_SPELLBOOK);
OUT_array(spell_book, spells::SPELLBOOK_SIZE);
// OUT(unknown4184[128]);
OUT_array(mem_spells, structs::MAX_PP_MEMSPELL);
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
// OUT(unknown04396[32]);
OUT(platinum);
OUT(gold);
@ -2842,7 +2842,7 @@ namespace SoD
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
emu->slot = static_cast<uint32>(SoDToServerCastingSlot(static_cast<CastingSlot>(eq->slot)));
emu->slot = static_cast<uint32>(SoDToServerCastingSlot(static_cast<spells::CastingSlot>(eq->slot)));
IN(slot);
IN(spell_id);
emu->inventoryslot = SoDToServerSlot(eq->inventoryslot);
@ -3136,9 +3136,9 @@ namespace SoD
DECODE_LENGTH_EXACT(structs::LoadSpellSet_Struct);
SETUP_DIRECT_DECODE(LoadSpellSet_Struct, structs::LoadSpellSet_Struct);
for (int i = 0; i < structs::MAX_PP_MEMSPELL; ++i)
for (int i = 0; i < spells::SPELL_GEM_COUNT; ++i)
emu->spell[i] = eq->spell[i];
for (int i = structs::MAX_PP_MEMSPELL; i < MAX_PP_MEMSPELL; ++i)
for (int i = spells::SPELL_GEM_COUNT; i < EQEmu::spells::SPELL_GEM_COUNT; ++i)
emu->spell[i] = 0xFFFFFFFF;
FINISH_DIRECT_DECODE();
@ -4021,84 +4021,84 @@ namespace SoD
}
}
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot)
static inline spells::CastingSlot ServerToSoDCastingSlot(EQEmu::spells::CastingSlot slot)
{
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Gem10:
return CastingSlot::Gem10;
case EQEmu::CastingSlot::Item:
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::Item;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
case EQEmu::spells::CastingSlot::Gem1:
return spells::CastingSlot::Gem1;
case EQEmu::spells::CastingSlot::Gem2:
return spells::CastingSlot::Gem2;
case EQEmu::spells::CastingSlot::Gem3:
return spells::CastingSlot::Gem3;
case EQEmu::spells::CastingSlot::Gem4:
return spells::CastingSlot::Gem4;
case EQEmu::spells::CastingSlot::Gem5:
return spells::CastingSlot::Gem5;
case EQEmu::spells::CastingSlot::Gem6:
return spells::CastingSlot::Gem6;
case EQEmu::spells::CastingSlot::Gem7:
return spells::CastingSlot::Gem7;
case EQEmu::spells::CastingSlot::Gem8:
return spells::CastingSlot::Gem8;
case EQEmu::spells::CastingSlot::Gem9:
return spells::CastingSlot::Gem9;
case EQEmu::spells::CastingSlot::Gem10:
return spells::CastingSlot::Gem10;
case EQEmu::spells::CastingSlot::Item:
case EQEmu::spells::CastingSlot::PotionBelt:
return spells::CastingSlot::Item;
case EQEmu::spells::CastingSlot::Discipline:
return spells::CastingSlot::Discipline;
case EQEmu::spells::CastingSlot::AltAbility:
return spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
return spells::CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot)
static inline EQEmu::spells::CastingSlot SoDToServerCastingSlot(spells::CastingSlot slot)
{
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Gem10:
return EQEmu::CastingSlot::Gem10;
case CastingSlot::Discipline:
return EQEmu::CastingSlot::Discipline;
case CastingSlot::Item:
return EQEmu::CastingSlot::Item;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
case spells::CastingSlot::Gem1:
return EQEmu::spells::CastingSlot::Gem1;
case spells::CastingSlot::Gem2:
return EQEmu::spells::CastingSlot::Gem2;
case spells::CastingSlot::Gem3:
return EQEmu::spells::CastingSlot::Gem3;
case spells::CastingSlot::Gem4:
return EQEmu::spells::CastingSlot::Gem4;
case spells::CastingSlot::Gem5:
return EQEmu::spells::CastingSlot::Gem5;
case spells::CastingSlot::Gem6:
return EQEmu::spells::CastingSlot::Gem6;
case spells::CastingSlot::Gem7:
return EQEmu::spells::CastingSlot::Gem7;
case spells::CastingSlot::Gem8:
return EQEmu::spells::CastingSlot::Gem8;
case spells::CastingSlot::Gem9:
return EQEmu::spells::CastingSlot::Gem9;
case spells::CastingSlot::Gem10:
return EQEmu::spells::CastingSlot::Gem10;
case spells::CastingSlot::Discipline:
return EQEmu::spells::CastingSlot::Discipline;
case spells::CastingSlot::Item:
return EQEmu::spells::CastingSlot::Item;
case spells::CastingSlot::AltAbility:
return EQEmu::spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
return EQEmu::spells::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;
if (index >= EQEmu::spells::LONG_BUFFS + EQEmu::spells::SHORT_BUFFS)
return index - EQEmu::spells::LONG_BUFFS - EQEmu::spells::SHORT_BUFFS +
spells::LONG_BUFFS + spells::SHORT_BUFFS;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
if (index >= EQEmu::spells::LONG_BUFFS)
return index - EQEmu::spells::LONG_BUFFS + spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
@ -4106,12 +4106,12 @@ namespace SoD
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;
if (index >= spells::LONG_BUFFS + spells::SHORT_BUFFS)
return index - spells::LONG_BUFFS - spells::SHORT_BUFFS + EQEmu::spells::LONG_BUFFS +
EQEmu::spells::SHORT_BUFFS;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
if (index >= spells::LONG_BUFFS)
return index - spells::LONG_BUFFS + EQEmu::spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}

View File

@ -50,22 +50,6 @@ namespace SoD
#include "sod_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Item = 10,
Discipline = 11,
AltAbility = 0xFF
};
}; /*SoD*/
#endif /*COMMON_SOD_H*/

View File

@ -191,8 +191,12 @@ namespace SoD
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
const uint64 POSSESSIONS_BITMASK = 0x000000027FFFFFFF; // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = 0x01FFFFFE7F800000; // based on 34-slot count (RoF+)
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
const uint64 GENERAL_BITMASK = 0x000000007F800000;
const uint64 CURSOR_BITMASK = 0x0000000200000000;
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 34)); // based on 34-slot count (RoF+)
const char* GetInvPossessionsSlotName(int16 inv_slot);
const char* GetInvCorpseSlotName(int16 inv_slot);
@ -277,18 +281,14 @@ namespace SoD
namespace constants {
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::SoD; }
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::SoD;
const uint32 EXPANSION_BIT = EQEmu::expansions::bitSoD;
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskSoD;
const size_t CHARACTER_CREATION_LIMIT = 12;
const size_t SAY_LINK_BODY_SIZE = 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 {
@ -305,6 +305,40 @@ namespace SoD
} /*skills*/
namespace spells {
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::SoD; }
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
MaxGems = 10,
Item = 10,
Discipline = 11,
AltAbility = 0xFF
};
const int SPELL_ID_MAX = 23000;
const int SPELLBOOK_SIZE = 480;
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
const int LONG_BUFFS = 25;
const int SHORT_BUFFS = 15;
const int DISC_BUFFS = 1;
const int TOTAL_BUFFS = LONG_BUFFS + SHORT_BUFFS + DISC_BUFFS;
const int NPC_BUFFS = 85;
const int PET_BUFFS = NPC_BUFFS;
const int MERC_BUFFS = LONG_BUFFS;
} /*spells*/
}; /*SoD*/
#endif /*COMMON_SOD_LIMITS_H*/

View File

@ -815,8 +815,7 @@ struct BindStruct {
** OpCode: 0x006a
*/
static const uint32 MAX_PP_LANGUAGE = 25; //
static const uint32 MAX_PP_SPELLBOOK = 480; // Confirmed 60 pages on Live now
static const uint32 MAX_PP_MEMSPELL = 10; //was 9 now 10 on Live
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
@ -885,7 +884,7 @@ struct PlayerProfile_Struct
/*00060*/ BindStruct binds[5]; // Bind points (primary is first)
/*00160*/ uint32 deity; // deity
/*00164*/ uint32 intoxication; // Alcohol level (in ticks till sober?)
/*00168*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; // Refresh time (millis) - 4 Octets Each
/*00168*/ uint32 spellSlotRefresh[spells::SPELL_GEM_COUNT]; // Refresh time (millis) - 4 Octets Each
/*00208*/ uint32 abilitySlotRefresh;
/*00212*/ uint8 haircolor; // Player hair color
/*00213*/ uint8 beardcolor; // Player beard color
@ -911,9 +910,9 @@ struct PlayerProfile_Struct
/*04172*/ uint8 unknown04172[28]; //
/*04200*/ uint8 face; // Player face
/*04201*/ uint8 unknown02264[147]; // was [175]
/*04348*/ uint32 spell_book[MAX_PP_SPELLBOOK]; // List of the Spells in spellbook 480 = 60 pages [1920]
/*04348*/ uint32 spell_book[spells::SPELLBOOK_SIZE]; // List of the Spells in spellbook 480 = 60 pages [1920]
/*06268*/ uint8 unknown4184[128]; // was [164] Seen -1
/*06396*/ uint32 mem_spells[MAX_PP_MEMSPELL]; // List of spells memorized
/*06396*/ uint32 mem_spells[spells::SPELL_GEM_COUNT]; // List of spells memorized
/*06436*/ uint8 unknown04396[28]; //#### uint8 unknown04396[32]; in Titanium ####[28]
/*06464*/ uint32 platinum; // Platinum Pieces on player
/*06468*/ uint32 gold; // Gold Pieces on player
@ -3846,7 +3845,7 @@ struct AnnoyingZoneUnknown_Struct {
};
struct LoadSpellSet_Struct {
uint32 spell[MAX_PP_MEMSPELL]; // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
uint32 spell[spells::SPELL_GEM_COUNT]; // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
uint32 unknown; //there seems to be an extra field in this packet...
};

View File

@ -59,8 +59,8 @@ namespace SoF
// client to server say link converter
static inline void SoFToServerSayLink(std::string &server_saylink, const std::string &sof_saylink);
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 item_location);
static inline spells::CastingSlot ServerToSoFCastingSlot(EQEmu::spells::CastingSlot slot);
static inline EQEmu::spells::CastingSlot SoFToServerCastingSlot(spells::CastingSlot slot, uint32 item_location);
static inline int ServerToSoFBuffSlot(int index);
static inline int SoFToServerBuffSlot(int index);
@ -956,7 +956,7 @@ namespace SoF
// Since HT/LoH are translated up, we need to translate down only for memSpellSpellbar case
if (emu->scribing == 3)
eq->slot = static_cast<uint32>(ServerToSoFCastingSlot(static_cast<EQEmu::CastingSlot>(emu->slot)));
eq->slot = static_cast<uint32>(ServerToSoFCastingSlot(static_cast<EQEmu::spells::CastingSlot>(emu->slot)));
else
OUT(slot);
OUT(spell_id);
@ -1116,7 +1116,7 @@ namespace SoF
}
OUT(deity);
OUT(intoxication);
OUT_array(spellSlotRefresh, structs::MAX_PP_MEMSPELL);
OUT_array(spellSlotRefresh, spells::SPELL_GEM_COUNT);
OUT(abilitySlotRefresh);
OUT(points); // Relocation Test
// OUT(unknown0166[4]);
@ -1156,9 +1156,9 @@ namespace SoF
OUT(WIS);
OUT(face);
// OUT(unknown02264[47]);
OUT_array(spell_book, structs::MAX_PP_SPELLBOOK);
OUT_array(spell_book, spells::SPELLBOOK_SIZE);
// OUT(unknown4184[128]);
OUT_array(mem_spells, structs::MAX_PP_MEMSPELL);
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
// OUT(unknown04396[32]);
OUT(platinum);
OUT(gold);
@ -2298,7 +2298,7 @@ namespace SoF
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
emu->slot = static_cast<uint32>(SoFToServerCastingSlot(static_cast<CastingSlot>(eq->slot), eq->inventoryslot));
emu->slot = static_cast<uint32>(SoFToServerCastingSlot(static_cast<spells::CastingSlot>(eq->slot), eq->inventoryslot));
IN(spell_id);
emu->inventoryslot = SoFToServerSlot(eq->inventoryslot);
IN(target_id);
@ -2540,9 +2540,9 @@ namespace SoF
DECODE_LENGTH_EXACT(structs::LoadSpellSet_Struct);
SETUP_DIRECT_DECODE(LoadSpellSet_Struct, structs::LoadSpellSet_Struct);
for (int i = 0; i < structs::MAX_PP_MEMSPELL; ++i)
for (int i = 0; i < spells::SPELL_GEM_COUNT; ++i)
IN(spell[i]);
for (int i = structs::MAX_PP_MEMSPELL; i < MAX_PP_MEMSPELL; ++i)
for (int i = spells::SPELL_GEM_COUNT; i < EQEmu::spells::SPELL_GEM_COUNT; ++i)
emu->spell[i] = 0xFFFFFFFF;
IN(unknown);
@ -3419,84 +3419,84 @@ namespace SoF
}
}
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot) {
static inline spells::CastingSlot ServerToSoFCastingSlot(EQEmu::spells::CastingSlot slot) {
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Item:
return CastingSlot::Item;
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::PotionBelt;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
case EQEmu::spells::CastingSlot::Gem1:
return spells::CastingSlot::Gem1;
case EQEmu::spells::CastingSlot::Gem2:
return spells::CastingSlot::Gem2;
case EQEmu::spells::CastingSlot::Gem3:
return spells::CastingSlot::Gem3;
case EQEmu::spells::CastingSlot::Gem4:
return spells::CastingSlot::Gem4;
case EQEmu::spells::CastingSlot::Gem5:
return spells::CastingSlot::Gem5;
case EQEmu::spells::CastingSlot::Gem6:
return spells::CastingSlot::Gem6;
case EQEmu::spells::CastingSlot::Gem7:
return spells::CastingSlot::Gem7;
case EQEmu::spells::CastingSlot::Gem8:
return spells::CastingSlot::Gem8;
case EQEmu::spells::CastingSlot::Gem9:
return spells::CastingSlot::Gem9;
case EQEmu::spells::CastingSlot::Item:
return spells::CastingSlot::Item;
case EQEmu::spells::CastingSlot::PotionBelt:
return spells::CastingSlot::PotionBelt;
case EQEmu::spells::CastingSlot::Discipline:
return spells::CastingSlot::Discipline;
case EQEmu::spells::CastingSlot::AltAbility:
return spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
return spells::CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 item_location) {
static inline EQEmu::spells::CastingSlot SoFToServerCastingSlot(spells::CastingSlot slot, uint32 item_location) {
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Ability:
return EQEmu::CastingSlot::Ability;
case spells::CastingSlot::Gem1:
return EQEmu::spells::CastingSlot::Gem1;
case spells::CastingSlot::Gem2:
return EQEmu::spells::CastingSlot::Gem2;
case spells::CastingSlot::Gem3:
return EQEmu::spells::CastingSlot::Gem3;
case spells::CastingSlot::Gem4:
return EQEmu::spells::CastingSlot::Gem4;
case spells::CastingSlot::Gem5:
return EQEmu::spells::CastingSlot::Gem5;
case spells::CastingSlot::Gem6:
return EQEmu::spells::CastingSlot::Gem6;
case spells::CastingSlot::Gem7:
return EQEmu::spells::CastingSlot::Gem7;
case spells::CastingSlot::Gem8:
return EQEmu::spells::CastingSlot::Gem8;
case spells::CastingSlot::Gem9:
return EQEmu::spells::CastingSlot::Gem9;
case spells::CastingSlot::Ability:
return EQEmu::spells::CastingSlot::Ability;
// Tit uses 10 for item and discipline casting, but items have a valid location
case CastingSlot::Item:
case spells::CastingSlot::Item:
if (item_location == INVALID_INDEX)
return EQEmu::CastingSlot::Discipline;
return EQEmu::spells::CastingSlot::Discipline;
else
return EQEmu::CastingSlot::Item;
case CastingSlot::PotionBelt:
return EQEmu::CastingSlot::PotionBelt;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
return EQEmu::spells::CastingSlot::Item;
case spells::CastingSlot::PotionBelt:
return EQEmu::spells::CastingSlot::PotionBelt;
case spells::CastingSlot::AltAbility:
return EQEmu::spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
return EQEmu::spells::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;
if (index >= EQEmu::spells::LONG_BUFFS + EQEmu::spells::SHORT_BUFFS)
return index - EQEmu::spells::LONG_BUFFS - EQEmu::spells::SHORT_BUFFS +
spells::LONG_BUFFS + spells::SHORT_BUFFS;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
if (index >= EQEmu::spells::LONG_BUFFS)
return index - EQEmu::spells::LONG_BUFFS + spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
@ -3504,12 +3504,12 @@ namespace SoF
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;
if (index >= spells::LONG_BUFFS + spells::SHORT_BUFFS)
return index - spells::LONG_BUFFS - spells::SHORT_BUFFS + EQEmu::spells::LONG_BUFFS +
EQEmu::spells::SHORT_BUFFS;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
if (index >= spells::LONG_BUFFS)
return index - spells::LONG_BUFFS + EQEmu::spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}

View File

@ -50,23 +50,6 @@ namespace SoF
#include "sof_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Ability = 9,
Item = 10,
Discipline = 10,
PotionBelt = 11,
AltAbility = 0xFF
};
}; /*SoF*/
#endif /*COMMON_SOF_H*/

View File

@ -191,8 +191,12 @@ namespace SoF
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
const uint64 POSSESSIONS_BITMASK = 0x000000027FFFFFFF; // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = 0x01FFFFFE7F800000; // based on 34-slot count (RoF+)
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
const uint64 GENERAL_BITMASK = 0x000000007F800000;
const uint64 CURSOR_BITMASK = 0x0000000200000000;
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 34)); // based on 34-slot count (RoF+)
const char* GetInvPossessionsSlotName(int16 inv_slot);
const char* GetInvCorpseSlotName(int16 inv_slot);
@ -277,18 +281,14 @@ namespace SoF
namespace constants {
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::SoF; }
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::SoF;
const uint32 EXPANSION_BIT = EQEmu::expansions::bitSoF;
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskSoF;
const size_t CHARACTER_CREATION_LIMIT = 12;
const size_t SAY_LINK_BODY_SIZE = 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 {
@ -305,6 +305,41 @@ namespace SoF
} /*skills*/
namespace spells {
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::SoF; }
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
MaxGems = 9,
Ability = 9,
Item = 10,
Discipline = 10,
PotionBelt = 11,
AltAbility = 0xFF
};
const int SPELL_ID_MAX = 15999;
const int SPELLBOOK_SIZE = 480;
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
const int LONG_BUFFS = 25;
const int SHORT_BUFFS = 15;
const int DISC_BUFFS = 1;
const int TOTAL_BUFFS = LONG_BUFFS + SHORT_BUFFS + DISC_BUFFS;
const int NPC_BUFFS = 60;
const int PET_BUFFS = 30;
const int MERC_BUFFS = 0;
} /*spells*/
}; /*SoF*/
#endif /*COMMON_SOF_LIMITS_H*/

View File

@ -816,8 +816,7 @@ struct BindStruct {
** OpCode: 0x006a
*/
static const uint32 MAX_PP_LANGUAGE = 25; //
static const uint32 MAX_PP_SPELLBOOK = 480; // Confirmed 60 pages on Live now
static const uint32 MAX_PP_MEMSPELL = 10; //was 9 now 10 on Live
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
@ -886,7 +885,7 @@ struct PlayerProfile_Struct //23576 Octets
/*00060*/ BindStruct binds[5]; // Bind points (primary is first)
/*00160*/ uint32 deity; // deity
/*00164*/ uint32 intoxication; // Alcohol level (in ticks till sober?)
/*00168*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; // Refresh time (millis) - 4 Octets Each
/*00168*/ uint32 spellSlotRefresh[spells::SPELL_GEM_COUNT]; // Refresh time (millis) - 4 Octets Each
/*00208*/ uint32 abilitySlotRefresh;
/*00212*/ uint8 haircolor; // Player hair color
/*00213*/ uint8 beardcolor; // Player beard color
@ -911,9 +910,9 @@ struct PlayerProfile_Struct //23576 Octets
/*04168*/ uint32 WIS; // Wisdom - 46 00 00 00 - 70
/*04172*/ uint8 face; // Player face
/*04173*/ uint8 unknown02264[147]; // was [139]
/*04312*/ uint32 spell_book[MAX_PP_SPELLBOOK]; // List of the Spells in spellbook 480 = 60 pages
/*04312*/ uint32 spell_book[spells::SPELLBOOK_SIZE]; // List of the Spells in spellbook 480 = 60 pages
/*06232*/ uint8 unknown4184[128]; // was [136]
/*06396*/ uint32 mem_spells[MAX_PP_MEMSPELL]; // List of spells memorized
/*06396*/ uint32 mem_spells[spells::SPELL_GEM_COUNT]; // List of spells memorized
/*06436*/ uint8 unknown04396[28]; //#### uint8 unknown04396[32]; in Titanium ####[28]
/*06464*/ uint32 platinum; // Platinum Pieces on player
/*06468*/ uint32 gold; // Gold Pieces on player
@ -3769,7 +3768,7 @@ struct AnnoyingZoneUnknown_Struct {
};
struct LoadSpellSet_Struct {
uint32 spell[MAX_PP_MEMSPELL];
uint32 spell[spells::SPELL_GEM_COUNT];
uint32 unknown;
};

View File

@ -58,8 +58,8 @@ namespace Titanium
// client to server say link converter
static inline void TitaniumToServerSayLink(std::string &server_saylink, const std::string &titanium_saylink);
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 item_location);
static inline spells::CastingSlot ServerToTitaniumCastingSlot(EQEmu::spells::CastingSlot slot);
static inline EQEmu::spells::CastingSlot TitaniumToServerCastingSlot(spells::CastingSlot slot, uint32 item_location);
static inline int ServerToTitaniumBuffSlot(int index);
static inline int TitaniumToServerBuffSlot(int index);
@ -890,7 +890,7 @@ namespace Titanium
// Since HT/LoH are translated up, we need to translate down only for memSpellSpellbar case
if (emu->scribing == 3)
eq->slot = static_cast<uint32>(ServerToTitaniumCastingSlot(static_cast<EQEmu::CastingSlot>(emu->slot)));
eq->slot = static_cast<uint32>(ServerToTitaniumCastingSlot(static_cast<EQEmu::spells::CastingSlot>(emu->slot)));
else
OUT(slot);
OUT(spell_id);
@ -981,7 +981,7 @@ namespace Titanium
}
OUT(deity);
OUT(intoxication);
OUT_array(spellSlotRefresh, structs::MAX_PP_MEMSPELL);
OUT_array(spellSlotRefresh, spells::SPELL_GEM_COUNT);
OUT(abilitySlotRefresh);
OUT(haircolor);
OUT(beardcolor);
@ -1012,9 +1012,9 @@ namespace Titanium
OUT(WIS);
OUT(face);
// OUT(unknown02264[47]);
OUT_array(spell_book, structs::MAX_PP_SPELLBOOK);
OUT_array(spell_book, spells::SPELLBOOK_SIZE);
// OUT(unknown4184[448]);
OUT_array(mem_spells, structs::MAX_PP_MEMSPELL);
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
// OUT(unknown04396[32]);
OUT(platinum);
OUT(gold);
@ -1815,7 +1815,7 @@ namespace Titanium
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
emu->slot = static_cast<uint32>(TitaniumToServerCastingSlot(static_cast<CastingSlot>(eq->slot), eq->inventoryslot));
emu->slot = static_cast<uint32>(TitaniumToServerCastingSlot(static_cast<spells::CastingSlot>(eq->slot), eq->inventoryslot));
IN(spell_id);
emu->inventoryslot = TitaniumToServerSlot(eq->inventoryslot);
IN(target_id);
@ -2003,9 +2003,9 @@ namespace Titanium
DECODE_LENGTH_EXACT(structs::LoadSpellSet_Struct);
SETUP_DIRECT_DECODE(LoadSpellSet_Struct, structs::LoadSpellSet_Struct);
for (int i = 0; i < structs::MAX_PP_MEMSPELL; ++i)
for (int i = 0; i < spells::SPELL_GEM_COUNT; ++i)
IN(spell[i]);
for (int i = structs::MAX_PP_MEMSPELL; i < MAX_PP_MEMSPELL; ++i)
for (int i = spells::SPELL_GEM_COUNT; i < EQEmu::spells::SPELL_GEM_COUNT; ++i)
emu->spell[i] = 0xFFFFFFFF;
IN(unknown);
@ -2721,85 +2721,85 @@ namespace Titanium
}
}
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot) {
static inline spells::CastingSlot ServerToTitaniumCastingSlot(EQEmu::spells::CastingSlot slot) {
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Item:
return CastingSlot::Item;
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::PotionBelt;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
case EQEmu::spells::CastingSlot::Gem1:
return spells::CastingSlot::Gem1;
case EQEmu::spells::CastingSlot::Gem2:
return spells::CastingSlot::Gem2;
case EQEmu::spells::CastingSlot::Gem3:
return spells::CastingSlot::Gem3;
case EQEmu::spells::CastingSlot::Gem4:
return spells::CastingSlot::Gem4;
case EQEmu::spells::CastingSlot::Gem5:
return spells::CastingSlot::Gem5;
case EQEmu::spells::CastingSlot::Gem6:
return spells::CastingSlot::Gem6;
case EQEmu::spells::CastingSlot::Gem7:
return spells::CastingSlot::Gem7;
case EQEmu::spells::CastingSlot::Gem8:
return spells::CastingSlot::Gem8;
case EQEmu::spells::CastingSlot::Gem9:
return spells::CastingSlot::Gem9;
case EQEmu::spells::CastingSlot::Item:
return spells::CastingSlot::Item;
case EQEmu::spells::CastingSlot::PotionBelt:
return spells::CastingSlot::PotionBelt;
case EQEmu::spells::CastingSlot::Discipline:
return spells::CastingSlot::Discipline;
case EQEmu::spells::CastingSlot::AltAbility:
return spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
return spells::CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 item_location) {
static inline EQEmu::spells::CastingSlot TitaniumToServerCastingSlot(spells::CastingSlot slot, uint32 item_location) {
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Ability:
return EQEmu::CastingSlot::Ability;
case spells::CastingSlot::Gem1:
return EQEmu::spells::CastingSlot::Gem1;
case spells::CastingSlot::Gem2:
return EQEmu::spells::CastingSlot::Gem2;
case spells::CastingSlot::Gem3:
return EQEmu::spells::CastingSlot::Gem3;
case spells::CastingSlot::Gem4:
return EQEmu::spells::CastingSlot::Gem4;
case spells::CastingSlot::Gem5:
return EQEmu::spells::CastingSlot::Gem5;
case spells::CastingSlot::Gem6:
return EQEmu::spells::CastingSlot::Gem6;
case spells::CastingSlot::Gem7:
return EQEmu::spells::CastingSlot::Gem7;
case spells::CastingSlot::Gem8:
return EQEmu::spells::CastingSlot::Gem8;
case spells::CastingSlot::Gem9:
return EQEmu::spells::CastingSlot::Gem9;
case spells::CastingSlot::Ability:
return EQEmu::spells::CastingSlot::Ability;
// Tit uses 10 for item and discipline casting, but items have a valid location
case CastingSlot::Item:
case spells::CastingSlot::Item:
if (item_location == INVALID_INDEX)
return EQEmu::CastingSlot::Discipline;
return EQEmu::spells::CastingSlot::Discipline;
else
return EQEmu::CastingSlot::Item;
case CastingSlot::PotionBelt:
return EQEmu::CastingSlot::PotionBelt;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
return EQEmu::spells::CastingSlot::Item;
case spells::CastingSlot::PotionBelt:
return EQEmu::spells::CastingSlot::PotionBelt;
case spells::CastingSlot::AltAbility:
return EQEmu::spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
return EQEmu::spells::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;
if (index >= EQEmu::spells::LONG_BUFFS + EQEmu::spells::SHORT_BUFFS)
return index - EQEmu::spells::LONG_BUFFS - EQEmu::spells::SHORT_BUFFS +
spells::LONG_BUFFS + spells::SHORT_BUFFS;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
if (index >= EQEmu::spells::LONG_BUFFS)
return index - EQEmu::spells::LONG_BUFFS + spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
@ -2807,12 +2807,12 @@ namespace Titanium
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;
if (index >= spells::LONG_BUFFS + spells::SHORT_BUFFS)
return index - spells::LONG_BUFFS - spells::SHORT_BUFFS + EQEmu::spells::LONG_BUFFS +
EQEmu::spells::SHORT_BUFFS;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
if (index >= spells::LONG_BUFFS)
return index - spells::LONG_BUFFS + EQEmu::spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}

View File

@ -50,23 +50,6 @@ namespace Titanium
#include "titanium_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Ability = 9,
Item = 10,
Discipline = 10,
PotionBelt = 11,
AltAbility = 0xFF
};
}; /*Titanium*/
#endif /*COMMON_TITANIUM_H*/

View File

@ -190,8 +190,12 @@ namespace Titanium
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
const uint64 POSSESSIONS_BITMASK = 0x000000027FDFFFFF; // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = 0x017FFFFE7F800000; // based on 34-slot count (RoF+)
const uint64 EQUIPMENT_BITMASK = 0x00000000005FFFFF;
const uint64 GENERAL_BITMASK = 0x000000007F800000;
const uint64 CURSOR_BITMASK = 0x0000000200000000;
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 34)); // based on 34-slot count (RoF+)
const char* GetInvPossessionsSlotName(int16 inv_slot);
const char* GetInvCorpseSlotName(int16 inv_slot);
@ -276,18 +280,14 @@ namespace Titanium
namespace constants {
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::Titanium; }
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::DoD; // Someone had this as PoR in another section...
const uint32 EXPANSION_BIT = EQEmu::expansions::bitDoD;
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskDoD;
const size_t CHARACTER_CREATION_LIMIT = 8; // Hard-coded in client - DO NOT ALTER
const size_t SAY_LINK_BODY_SIZE = 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 {
@ -304,6 +304,41 @@ namespace Titanium
} /*skills*/
namespace spells {
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::Titanium; }
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
MaxGems = 9,
Ability = 9,
Item = 10,
Discipline = 10,
PotionBelt = 11,
AltAbility = 0xFF
};
const int SPELL_ID_MAX = 9999;
const int SPELLBOOK_SIZE = 400;
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
const int LONG_BUFFS = 25;
const int SHORT_BUFFS = 12;
const int DISC_BUFFS = 1;
const int TOTAL_BUFFS = LONG_BUFFS + SHORT_BUFFS + DISC_BUFFS;
const int NPC_BUFFS = 60;
const int PET_BUFFS = 30;
const int MERC_BUFFS = 0;
} /*spells*/
}; /*Titanium*/
#endif /*COMMON_TITANIUM_LIMITS_H*/

View File

@ -754,8 +754,7 @@ struct BindStruct {
** OpCode: 0x006a
*/
static const uint32 MAX_PP_LANGUAGE = 28;
static const uint32 MAX_PP_SPELLBOOK = 400;
static const uint32 MAX_PP_MEMSPELL = 9;
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 240;
@ -824,7 +823,7 @@ struct PlayerProfile_Struct
/*00024*/ BindStruct binds[5]; // Bind points (primary is first)
/*00124*/ uint32 deity; // deity
/*00128*/ uint32 intoxication; // Alcohol level (in ticks till sober?)
/*00132*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; // Refresh time (millis)
/*00132*/ uint32 spellSlotRefresh[spells::SPELL_GEM_COUNT]; // Refresh time (millis)
/*00168*/ uint32 abilitySlotRefresh;
/*00172*/ uint8 haircolor; // Player hair color
/*00173*/ uint8 beardcolor; // Player beard color
@ -849,9 +848,9 @@ struct PlayerProfile_Struct
/*02260*/ uint32 WIS; // Wisdom
/*02264*/ uint8 face; // Player face
/*02265*/ uint8 unknown02264[47];
/*02312*/ uint32 spell_book[MAX_PP_SPELLBOOK]; // List of the Spells in spellbook
/*02312*/ uint32 spell_book[spells::SPELLBOOK_SIZE]; // List of the Spells in spellbook
/*03912*/ uint8 unknown4184[448]; // all 0xff after last spell
/*04360*/ uint32 mem_spells[MAX_PP_MEMSPELL]; // List of spells memorized
/*04360*/ uint32 mem_spells[spells::SPELL_GEM_COUNT]; // List of spells memorized
/*04396*/ uint8 unknown04396[32];
/*04428*/ uint32 platinum; // Platinum Pieces on player
/*04432*/ uint32 gold; // Gold Pieces on player
@ -3271,7 +3270,7 @@ struct AnnoyingZoneUnknown_Struct {
};
struct LoadSpellSet_Struct {
uint32 spell[MAX_PP_MEMSPELL];
uint32 spell[spells::SPELL_GEM_COUNT];
uint32 unknown;
};

View File

@ -59,8 +59,8 @@ namespace UF
// client to server say link converter
static inline void UFToServerSayLink(std::string& serverSayLink, const std::string& ufSayLink);
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot);
static inline spells::CastingSlot ServerToUFCastingSlot(EQEmu::spells::CastingSlot slot);
static inline EQEmu::spells::CastingSlot UFToServerCastingSlot(spells::CastingSlot slot);
static inline int ServerToUFBuffSlot(int index);
static inline int UFToServerBuffSlot(int index);
@ -1682,7 +1682,7 @@ namespace UF
}
OUT(deity);
OUT(intoxication);
OUT_array(spellSlotRefresh, structs::MAX_PP_MEMSPELL);
OUT_array(spellSlotRefresh, spells::SPELL_GEM_COUNT);
OUT(abilitySlotRefresh);
OUT(points); // Relocation Test
// OUT(unknown0166[4]);
@ -1724,10 +1724,10 @@ namespace UF
OUT(WIS);
OUT(face);
// OUT(unknown02264[47]);
memset(eq->spell_book, 0xFF, sizeof(uint32)* structs::MAX_PP_SPELLBOOK);
memset(eq->spell_book, 0xFF, sizeof(uint32)* spells::SPELLBOOK_SIZE);
OUT_array(spell_book, 480U);
// OUT(unknown4184[128]);
OUT_array(mem_spells, structs::MAX_PP_MEMSPELL);
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
// OUT(unknown04396[32]);
OUT(platinum);
OUT(gold);
@ -3142,7 +3142,7 @@ namespace UF
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
emu->slot = static_cast<uint32>(UFToServerCastingSlot(static_cast<CastingSlot>(eq->slot)));
emu->slot = static_cast<uint32>(UFToServerCastingSlot(static_cast<spells::CastingSlot>(eq->slot)));
IN(spell_id);
emu->inventoryslot = UFToServerSlot(eq->inventoryslot);
@ -3491,7 +3491,7 @@ namespace UF
DECODE_LENGTH_EXACT(structs::LoadSpellSet_Struct);
SETUP_DIRECT_DECODE(LoadSpellSet_Struct, structs::LoadSpellSet_Struct);
for (unsigned int i = 0; i < MAX_PP_MEMSPELL; ++i)
for (unsigned int i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; ++i)
if (eq->spell[i] == 0)
emu->spell[i] = 0xFFFFFFFF;
else
@ -4380,92 +4380,92 @@ namespace UF
}
}
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot)
static inline spells::CastingSlot ServerToUFCastingSlot(EQEmu::spells::CastingSlot slot)
{
switch (slot) {
case EQEmu::CastingSlot::Gem1:
return CastingSlot::Gem1;
case EQEmu::CastingSlot::Gem2:
return CastingSlot::Gem2;
case EQEmu::CastingSlot::Gem3:
return CastingSlot::Gem3;
case EQEmu::CastingSlot::Gem4:
return CastingSlot::Gem4;
case EQEmu::CastingSlot::Gem5:
return CastingSlot::Gem5;
case EQEmu::CastingSlot::Gem6:
return CastingSlot::Gem6;
case EQEmu::CastingSlot::Gem7:
return CastingSlot::Gem7;
case EQEmu::CastingSlot::Gem8:
return CastingSlot::Gem8;
case EQEmu::CastingSlot::Gem9:
return CastingSlot::Gem9;
case EQEmu::CastingSlot::Gem10:
return CastingSlot::Gem10;
case EQEmu::CastingSlot::Gem11:
return CastingSlot::Gem11;
case EQEmu::CastingSlot::Gem12:
return CastingSlot::Gem12;
case EQEmu::CastingSlot::Item:
case EQEmu::CastingSlot::PotionBelt:
return CastingSlot::Item;
case EQEmu::CastingSlot::Discipline:
return CastingSlot::Discipline;
case EQEmu::CastingSlot::AltAbility:
return CastingSlot::AltAbility;
case EQEmu::spells::CastingSlot::Gem1:
return spells::CastingSlot::Gem1;
case EQEmu::spells::CastingSlot::Gem2:
return spells::CastingSlot::Gem2;
case EQEmu::spells::CastingSlot::Gem3:
return spells::CastingSlot::Gem3;
case EQEmu::spells::CastingSlot::Gem4:
return spells::CastingSlot::Gem4;
case EQEmu::spells::CastingSlot::Gem5:
return spells::CastingSlot::Gem5;
case EQEmu::spells::CastingSlot::Gem6:
return spells::CastingSlot::Gem6;
case EQEmu::spells::CastingSlot::Gem7:
return spells::CastingSlot::Gem7;
case EQEmu::spells::CastingSlot::Gem8:
return spells::CastingSlot::Gem8;
case EQEmu::spells::CastingSlot::Gem9:
return spells::CastingSlot::Gem9;
case EQEmu::spells::CastingSlot::Gem10:
return spells::CastingSlot::Gem10;
case EQEmu::spells::CastingSlot::Gem11:
return spells::CastingSlot::Gem11;
case EQEmu::spells::CastingSlot::Gem12:
return spells::CastingSlot::Gem12;
case EQEmu::spells::CastingSlot::Item:
case EQEmu::spells::CastingSlot::PotionBelt:
return spells::CastingSlot::Item;
case EQEmu::spells::CastingSlot::Discipline:
return spells::CastingSlot::Discipline;
case EQEmu::spells::CastingSlot::AltAbility:
return spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return CastingSlot::Discipline;
return spells::CastingSlot::Discipline;
}
}
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot)
static inline EQEmu::spells::CastingSlot UFToServerCastingSlot(spells::CastingSlot slot)
{
switch (slot) {
case CastingSlot::Gem1:
return EQEmu::CastingSlot::Gem1;
case CastingSlot::Gem2:
return EQEmu::CastingSlot::Gem2;
case CastingSlot::Gem3:
return EQEmu::CastingSlot::Gem3;
case CastingSlot::Gem4:
return EQEmu::CastingSlot::Gem4;
case CastingSlot::Gem5:
return EQEmu::CastingSlot::Gem5;
case CastingSlot::Gem6:
return EQEmu::CastingSlot::Gem6;
case CastingSlot::Gem7:
return EQEmu::CastingSlot::Gem7;
case CastingSlot::Gem8:
return EQEmu::CastingSlot::Gem8;
case CastingSlot::Gem9:
return EQEmu::CastingSlot::Gem9;
case CastingSlot::Gem10:
return EQEmu::CastingSlot::Gem10;
case CastingSlot::Gem11:
return EQEmu::CastingSlot::Gem11;
case CastingSlot::Gem12:
return EQEmu::CastingSlot::Gem12;
case CastingSlot::Discipline:
return EQEmu::CastingSlot::Discipline;
case CastingSlot::Item:
return EQEmu::CastingSlot::Item;
case CastingSlot::AltAbility:
return EQEmu::CastingSlot::AltAbility;
case spells::CastingSlot::Gem1:
return EQEmu::spells::CastingSlot::Gem1;
case spells::CastingSlot::Gem2:
return EQEmu::spells::CastingSlot::Gem2;
case spells::CastingSlot::Gem3:
return EQEmu::spells::CastingSlot::Gem3;
case spells::CastingSlot::Gem4:
return EQEmu::spells::CastingSlot::Gem4;
case spells::CastingSlot::Gem5:
return EQEmu::spells::CastingSlot::Gem5;
case spells::CastingSlot::Gem6:
return EQEmu::spells::CastingSlot::Gem6;
case spells::CastingSlot::Gem7:
return EQEmu::spells::CastingSlot::Gem7;
case spells::CastingSlot::Gem8:
return EQEmu::spells::CastingSlot::Gem8;
case spells::CastingSlot::Gem9:
return EQEmu::spells::CastingSlot::Gem9;
case spells::CastingSlot::Gem10:
return EQEmu::spells::CastingSlot::Gem10;
case spells::CastingSlot::Gem11:
return EQEmu::spells::CastingSlot::Gem11;
case spells::CastingSlot::Gem12:
return EQEmu::spells::CastingSlot::Gem12;
case spells::CastingSlot::Discipline:
return EQEmu::spells::CastingSlot::Discipline;
case spells::CastingSlot::Item:
return EQEmu::spells::CastingSlot::Item;
case spells::CastingSlot::AltAbility:
return EQEmu::spells::CastingSlot::AltAbility;
default: // we shouldn't have any issues with other slots ... just return something
return EQEmu::CastingSlot::Discipline;
return EQEmu::spells::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;
if (index >= EQEmu::spells::LONG_BUFFS + EQEmu::spells::SHORT_BUFFS)
return index - EQEmu::spells::LONG_BUFFS - EQEmu::spells::SHORT_BUFFS +
spells::LONG_BUFFS + spells::SHORT_BUFFS;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
if (index >= EQEmu::spells::LONG_BUFFS)
return index - EQEmu::spells::LONG_BUFFS + spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
@ -4473,12 +4473,12 @@ namespace UF
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;
if (index >= spells::LONG_BUFFS + spells::SHORT_BUFFS)
return index - spells::LONG_BUFFS - spells::SHORT_BUFFS + EQEmu::spells::LONG_BUFFS +
EQEmu::spells::SHORT_BUFFS;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
if (index >= spells::LONG_BUFFS)
return index - spells::LONG_BUFFS + EQEmu::spells::LONG_BUFFS;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}

View File

@ -50,24 +50,6 @@ namespace UF
#include "uf_ops.h"
};
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
Item = 12,
Discipline = 13,
AltAbility = 0xFF
};
}; /*UF*/
#endif /*COMMON_UF_H*/

View File

@ -191,8 +191,12 @@ namespace UF
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
const uint64 POSSESSIONS_BITMASK = 0x000000027FFFFFFF; // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = 0x01FFFFFE7F800000; // based on 34-slot count (RoF+)
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
const uint64 GENERAL_BITMASK = 0x000000007F800000;
const uint64 CURSOR_BITMASK = 0x0000000200000000;
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 34)); // based on 34-slot count (RoF+)
const char* GetInvPossessionsSlotName(int16 inv_slot);
const char* GetInvCorpseSlotName(int16 inv_slot);
@ -278,18 +282,14 @@ namespace UF
namespace constants {
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::UF; }
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::UF;
const uint32 EXPANSION_BIT = EQEmu::expansions::bitUF;
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskUF;
const size_t CHARACTER_CREATION_LIMIT = 12;
const size_t SAY_LINK_BODY_SIZE = 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 {
@ -306,6 +306,42 @@ namespace UF
} /*skills*/
namespace spells {
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::UF; }
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
MaxGems = 12,
Item = 12,
Discipline = 13,
AltAbility = 0xFF
};
const int SPELL_ID_MAX = 28000;
const int SPELLBOOK_SIZE = 720;
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
const int LONG_BUFFS = 30;
const int SHORT_BUFFS = 20;
const int DISC_BUFFS = 1;
const int TOTAL_BUFFS = LONG_BUFFS + SHORT_BUFFS + DISC_BUFFS;
const int NPC_BUFFS = 85;
const int PET_BUFFS = NPC_BUFFS;
const int MERC_BUFFS = LONG_BUFFS;
} /*spells*/
}; /*UF*/
#endif /*COMMON_UF_LIMITS_H*/

View File

@ -845,8 +845,7 @@ struct BindStruct {
** OpCode: 0x006a
*/
static const uint32 MAX_PP_LANGUAGE = 25; //
static const uint32 MAX_PP_SPELLBOOK = 720; // Confirmed 60 pages on Underfoot now
static const uint32 MAX_PP_MEMSPELL = 12; //was 9 now 10 on Underfoot
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
@ -916,7 +915,7 @@ struct PlayerProfile_Struct
/*00060*/ BindStruct binds[5]; // Bind points (primary is first)
/*00160*/ uint32 deity; // deity
/*00164*/ uint32 intoxication; // Alcohol level (in ticks till sober?)
/*00168*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; // Refresh time (millis) - 4 Octets Each
/*00168*/ uint32 spellSlotRefresh[spells::SPELL_GEM_COUNT]; // Refresh time (millis) - 4 Octets Each
/*00208*/ uint8 unknown00208[6]; // Seen 00 00 00 00 00 00 00 00 00 00 00 00 02 01
/*00222*/ uint32 abilitySlotRefresh;
/*00226*/ uint8 haircolor; // Player hair color
@ -943,8 +942,8 @@ struct PlayerProfile_Struct
/*04188*/ uint8 unknown04188[28]; //
/*04216*/ uint8 face; // Player face - Actually uint32?
/*04217*/ uint8 unknown04217[147]; // was [175]
/*04364*/ uint32 spell_book[MAX_PP_SPELLBOOK]; // List of the Spells in spellbook 720 = 90 pages [2880] was [1920]
/*07244*/ uint32 mem_spells[MAX_PP_MEMSPELL]; // List of spells memorized
/*04364*/ uint32 spell_book[spells::SPELLBOOK_SIZE]; // List of the Spells in spellbook 720 = 90 pages [2880] was [1920]
/*07244*/ uint32 mem_spells[spells::SPELL_GEM_COUNT]; // List of spells memorized
/*07284*/ uint8 unknown07284[20]; //#### uint8 unknown04396[32]; in Titanium ####[28]
/*07312*/ uint32 platinum; // Platinum Pieces on player
/*07316*/ uint32 gold; // Gold Pieces on player
@ -3907,7 +3906,7 @@ struct AnnoyingZoneUnknown_Struct {
};
struct LoadSpellSet_Struct {
uint8 spell[MAX_PP_MEMSPELL]; // 0 if no action
uint8 spell[spells::SPELL_GEM_COUNT]; // 0 if no action
uint32 unknown; // there seems to be an extra field in this packet...
};

View File

@ -61,7 +61,7 @@ RuleManager::RuleManager()
: m_activeRuleset(0),
m_activeName("default")
{
ResetRules();
ResetRules(false);
}
RuleManager::CategoryType RuleManager::FindCategory(const char *catname) {
@ -126,7 +126,7 @@ bool RuleManager::GetRule(const char *rule_name, std::string &return_value) {
return true;
}
bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Database *database, bool db_save) {
bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Database *database, bool db_save, bool reload) {
if(rule_name == nullptr || rule_value == nullptr)
return(false);
@ -135,6 +135,13 @@ bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Databas
if(!_FindRule(rule_name, type, index))
return(false);
if (reload) {
if (strcasecmp(rule_name, "World:ExpansionSettings") == 0)
return(false);
if (strcasecmp(rule_name, "World:UseClientBasedExpansionSettings") == 0)
return(false);
}
switch(type) {
case IntRule:
m_RuleIntValues[index] = atoi(rule_value);
@ -160,7 +167,16 @@ bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Databas
return(true);
}
void RuleManager::ResetRules() {
void RuleManager::ResetRules(bool reload) {
std::string expansion1;
std::string expansion2;
// these rules must not change during server runtime
if (reload) {
GetRule("World:ExpansionSettings", expansion1);
GetRule("World:UseClientBasedExpansionSettings", expansion2);
}
Log(Logs::Detail, Logs::Rules, "Resetting running rules to default values");
#define RULE_INT(cat, rule, default_value) \
m_RuleIntValues[ Int__##rule ] = default_value;
@ -169,6 +185,12 @@ void RuleManager::ResetRules() {
#define RULE_BOOL(cat, rule, default_value) \
m_RuleBoolValues[ Bool__##rule ] = default_value;
#include "ruletypes.h"
// restore these rules to their pre-reset values
if (reload) {
SetRule("World:ExpansionSettings", expansion1.c_str(), nullptr, false, false);
SetRule("World:UseClientBasedExpansionSettings", expansion2.c_str(), nullptr, false, false);
}
}
bool RuleManager::_FindRule(const char *rule_name, RuleType &type_into, uint16 &index_into) {
@ -235,7 +257,7 @@ void RuleManager::SaveRules(Database *database, const char *ruleset_name) {
}
}
bool RuleManager::LoadRules(Database *database, const char *ruleset_name) {
bool RuleManager::LoadRules(Database *database, const char *ruleset_name, bool reload) {
int ruleset_id = this->GetRulesetID(database, ruleset_name);
if (ruleset_id < 0) {
@ -269,7 +291,7 @@ bool RuleManager::LoadRules(Database *database, const char *ruleset_name) {
return false;
for (auto row = results.begin(); row != results.end(); ++row)
if (!SetRule(row[0], row[1], nullptr, false))
if (!SetRule(row[0], row[1], nullptr, false, reload))
Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]);
}
@ -279,7 +301,7 @@ bool RuleManager::LoadRules(Database *database, const char *ruleset_name) {
return false;
for (auto row = results.begin(); row != results.end(); ++row)
if (!SetRule(row[0], row[1], nullptr, false))
if (!SetRule(row[0], row[1], nullptr, false, reload))
Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]);
return true;
@ -288,6 +310,11 @@ bool RuleManager::LoadRules(Database *database, const char *ruleset_name) {
void RuleManager::_SaveRule(Database *database, RuleType type, uint16 index) {
char value_string[100];
if (type == IntRule && strcasecmp(_GetRuleName(type, index), "World:ExpansionSettings") == 0)
return;
if (type == BoolRule && strcasecmp(_GetRuleName(type, index), "World:UseClientBasedExpansionSettings") == 0)
return;
switch (type) {
case IntRule:
sprintf(value_string, "%d", m_RuleIntValues[index]);

View File

@ -102,7 +102,7 @@ public:
bool ListRules(const char *catname, std::vector<const char *> &into);
bool ListCategories(std::vector<const char *> &into);
bool GetRule(const char *rule_name, std::string &ret_val);
bool SetRule(const char *rule_name, const char *rule_value, Database *db = nullptr, bool db_save = false);
bool SetRule(const char *rule_name, const char *rule_value, Database *db = nullptr, bool db_save = false, bool reload = false);
int GetActiveRulesetID() const { return(m_activeRuleset); }
const char *GetActiveRuleset() const { return(m_activeName.c_str()); }
@ -110,8 +110,8 @@ public:
static std::string GetRulesetName(Database *db, int id);
static bool ListRulesets(Database *db, std::map<int, std::string> &into);
void ResetRules();
bool LoadRules(Database *db, const char *ruleset = nullptr);
void ResetRules(bool reload = false);
bool LoadRules(Database *db, const char *ruleset = nullptr, bool reload = false);
void SaveRules(Database *db, const char *ruleset = nullptr);
private:

View File

@ -571,7 +571,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv)
auto cv_conflict = false;
auto pmask = inv->GetLookup()->PossessionsBitmask;
auto bank_size = inv->GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank];
auto bank_size = inv->GetLookup()->InventoryTypeSize.Bank;
for (auto row = results.begin(); row != results.end(); ++row) {
int16 slot_id = atoi(row[0]);
@ -720,9 +720,12 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv)
if (cv_conflict) {
char char_name[64] = "";
GetCharName(char_id, char_name);
Log(Logs::Moderate, Logs::Client_Login,
"ClientVersion conflict during inventory load at zone entry for '%s' (charid: %u, inver: %s)",
char_name, char_id, EQEmu::versions::MobVersionName(inv->InventoryVersion())
Log(Logs::General, Logs::Error,
"ClientVersion/Expansion conflict during inventory load at zone entry for '%s' (charid: %u, inver: %s, gmi: %s)",
char_name,
char_id,
EQEmu::versions::MobVersionName(inv->InventoryVersion()),
(inv->GMInventory() ? "true" : "false")
);
}

View File

@ -30,7 +30,7 @@
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9133
#define CURRENT_BINARY_DATABASE_VERSION 9135
#ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9021
#else

View File

@ -102,19 +102,23 @@ int main() {
char tmp[64];
// ucs has no 'reload rules' handler
if (database.GetVariable("RuleSet", tmp, sizeof(tmp)-1)) {
Log(Logs::General, Logs::UCS_Server, "Loading rule set '%s'", tmp);
if(!RuleManager::Instance()->LoadRules(&database, tmp)) {
if(!RuleManager::Instance()->LoadRules(&database, tmp, false)) {
Log(Logs::General, Logs::UCS_Server, "Failed to load ruleset '%s', falling back to defaults.", tmp);
}
} else {
if(!RuleManager::Instance()->LoadRules(&database, "default")) {
if(!RuleManager::Instance()->LoadRules(&database, "default", false)) {
Log(Logs::General, Logs::UCS_Server, "No rule set configured, using default rules");
} else {
Log(Logs::General, Logs::UCS_Server, "Loaded default rule set 'default'", tmp);
}
}
EQEmu::InitializeDynamicLookups();
Log(Logs::General, Logs::UCS_Server, "Initialized dynamic dictionary entries");
database.ExpireMail();
if(Config->ChatPort != Config->MailPort)

File diff suppressed because it is too large Load Diff

View File

@ -387,6 +387,8 @@
9131|2018_12_13_spell_buckets.sql|SHOW TABLES LIKE 'spell_buckets'|empty|
9132|2018_12_16_global_base_scaling.sql|SHOW TABLES LIKE 'npc_scale_global_base'|empty|
9133|2018_11_25_StuckBehavior.sql|SHOW COLUMNS FROM `npc_types` LIKE 'stuck_behavior'|empty|
9134|2019_01_04_update_global_base_scaling.sql|SELECT * FROM db_version WHERE version >= 9134|empty|
9135|2019_01_10_multi_version_spawns.sql|SHOW COLUMNS FROM `spawn2` LIKE 'version'|contains|unsigned|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1,272 @@
REPLACE INTO `npc_scale_global_base` (`type`, `level`, `ac`, `hp`, `accuracy`, `slow_mitigation`, `attack`, `strength`, `stamina`, `dexterity`, `agility`, `intelligence`, `wisdom`, `charisma`, `magic_resist`, `cold_resist`, `fire_resist`, `poison_resist`, `disease_resist`, `corruption_resist`, `physical_resist`, `min_dmg`, `max_dmg`, `hp_regen_rate`, `attack_delay`, `spell_scale`, `heal_scale`, `special_abilities`)
VALUES
(0, 1, 8, 11, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 10, 1, 6, 1, 30, 100, 100, ''),
(0, 2, 11, 27, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 1, 1, 1, 1, 1, 2, 10, 1, 8, 1, 30, 100, 100, ''),
(0, 3, 14, 43, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 10, 1, 10, 1, 30, 100, 100, ''),
(0, 4, 16, 59, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 2, 2, 2, 2, 2, 3, 10, 1, 12, 1, 30, 100, 100, ''),
(0, 5, 19, 75, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 2, 3, 10, 1, 14, 1, 30, 100, 100, ''),
(0, 6, 22, 100, 0, 0, 0, 23, 23, 23, 23, 23, 23, 23, 2, 2, 2, 2, 2, 4, 10, 1, 16, 1, 30, 100, 100, ''),
(0, 7, 25, 125, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 3, 3, 3, 3, 3, 4, 10, 1, 18, 2, 30, 100, 100, ''),
(0, 8, 28, 150, 0, 0, 0, 29, 29, 29, 29, 29, 29, 29, 3, 3, 3, 3, 3, 5, 10, 1, 20, 2, 30, 100, 100, ''),
(0, 9, 31, 175, 0, 0, 0, 32, 32, 32, 32, 32, 32, 32, 4, 4, 4, 4, 4, 5, 10, 1, 22, 2, 30, 100, 100, ''),
(0, 10, 34, 200, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, 4, 4, 4, 4, 4, 6, 10, 1, 24, 2, 30, 100, 100, ''),
(0, 11, 37, 234, 0, 0, 0, 38, 38, 38, 38, 38, 38, 38, 5, 5, 5, 5, 5, 7, 10, 3, 27, 2, 30, 100, 100, ''),
(0, 12, 40, 268, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 5, 5, 5, 5, 5, 8, 10, 4, 30, 3, 30, 100, 100, ''),
(0, 13, 43, 302, 0, 0, 0, 45, 45, 45, 45, 45, 45, 45, 6, 6, 6, 6, 6, 8, 10, 6, 32, 3, 30, 100, 100, ''),
(0, 14, 46, 336, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 6, 6, 6, 6, 6, 9, 10, 7, 35, 3, 30, 100, 100, ''),
(0, 15, 52, 381, 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, 6, 6, 6, 6, 6, 10, 10, 7, 37, 4, 30, 100, 100, ''),
(0, 16, 59, 426, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 7, 7, 7, 7, 7, 10, 10, 8, 39, 4, 30, 100, 100, ''),
(0, 17, 65, 471, 0, 0, 0, 57, 57, 57, 57, 57, 57, 57, 7, 7, 7, 7, 7, 11, 10, 8, 41, 5, 30, 100, 100, ''),
(0, 18, 72, 516, 0, 0, 0, 60, 60, 60, 60, 60, 60, 60, 7, 7, 7, 7, 7, 11, 10, 9, 42, 5, 30, 100, 100, ''),
(0, 19, 78, 561, 0, 0, 0, 63, 63, 63, 63, 63, 63, 63, 7, 7, 7, 7, 7, 12, 10, 9, 44, 6, 30, 100, 100, ''),
(0, 20, 85, 606, 0, 0, 0, 66, 66, 66, 66, 66, 66, 66, 8, 8, 8, 8, 8, 12, 10, 10, 46, 6, 30, 100, 100, ''),
(0, 21, 91, 651, 0, 0, 0, 69, 69, 69, 69, 69, 69, 69, 8, 8, 8, 8, 8, 13, 10, 10, 48, 7, 30, 100, 100, ''),
(0, 22, 95, 712, 0, 0, 0, 72, 72, 72, 72, 72, 72, 72, 8, 8, 8, 8, 8, 14, 10, 10, 50, 7, 30, 100, 100, ''),
(0, 23, 99, 800, 0, 0, 0, 75, 75, 75, 75, 75, 75, 75, 9, 9, 9, 9, 9, 14, 10, 10, 52, 8, 30, 100, 100, ''),
(0, 24, 103, 845, 0, 0, 0, 78, 78, 78, 78, 78, 78, 78, 9, 9, 9, 9, 9, 15, 10, 11, 55, 8, 30, 100, 100, ''),
(0, 25, 107, 895, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 10, 10, 10, 10, 10, 16, 10, 11, 57, 9, 30, 100, 100, ''),
(0, 26, 111, 956, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 10, 10, 10, 10, 10, 16, 10, 11, 59, 10, 30, 100, 100, ''),
(0, 27, 115, 1100, 0, 0, 0, 88, 88, 88, 88, 88, 88, 88, 11, 11, 11, 11, 11, 17, 10, 11, 61, 10, 30, 100, 100, ''),
(0, 28, 119, 1140, 0, 0, 0, 91, 91, 91, 91, 91, 91, 91, 11, 11, 11, 11, 11, 18, 10, 12, 64, 11, 30, 100, 100, ''),
(0, 29, 123, 1240, 0, 0, 0, 94, 94, 94, 94, 94, 94, 94, 12, 12, 12, 12, 12, 18, 10, 12, 66, 12, 30, 100, 100, ''),
(0, 30, 127, 1350, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 12, 12, 12, 12, 12, 19, 10, 12, 68, 13, 30, 100, 100, ''),
(0, 31, 135, 1450, 4, 0, 4, 104, 104, 104, 104, 104, 104, 104, 13, 13, 13, 13, 13, 20, 10, 14, 74, 14, 30, 100, 100, ''),
(0, 32, 142, 1550, 8, 0, 8, 110, 110, 110, 110, 110, 110, 110, 14, 14, 14, 14, 14, 22, 10, 16, 79, 15, 30, 100, 100, ''),
(0, 33, 150, 1650, 12, 0, 12, 117, 117, 117, 117, 117, 117, 117, 15, 15, 15, 15, 15, 23, 10, 18, 85, 16, 29, 100, 100, ''),
(0, 34, 158, 1750, 16, 0, 16, 123, 123, 123, 123, 123, 123, 123, 16, 16, 16, 16, 16, 25, 10, 20, 90, 17, 28, 100, 100, ''),
(0, 35, 166, 1850, 20, 0, 20, 130, 130, 130, 130, 130, 130, 130, 17, 17, 17, 17, 17, 26, 10, 22, 96, 18, 27, 100, 100, ''),
(0, 36, 173, 1950, 24, 0, 24, 137, 137, 137, 137, 137, 137, 137, 17, 17, 17, 17, 17, 27, 10, 24, 102, 19, 25, 100, 100, ''),
(0, 37, 181, 2100, 28, 0, 28, 143, 143, 143, 143, 143, 143, 143, 18, 18, 18, 18, 18, 29, 10, 26, 107, 21, 24, 100, 100, ''),
(0, 38, 189, 2350, 32, 0, 32, 150, 150, 150, 150, 150, 150, 150, 19, 19, 19, 19, 19, 30, 10, 28, 113, 23, 23, 100, 100, ''),
(0, 39, 196, 2650, 36, 0, 36, 156, 156, 156, 156, 156, 156, 156, 20, 20, 20, 20, 20, 32, 10, 30, 118, 26, 22, 100, 100, ''),
(0, 40, 204, 2900, 40, 0, 40, 163, 163, 163, 163, 163, 163, 163, 21, 21, 21, 21, 21, 33, 10, 32, 124, 29, 21, 100, 100, ''),
(0, 41, 208, 3250, 42, 0, 42, 166, 166, 166, 166, 166, 166, 166, 22, 22, 22, 22, 22, 34, 10, 33, 127, 32, 21, 100, 100, ''),
(0, 42, 212, 3750, 44, 0, 44, 169, 169, 169, 169, 169, 169, 169, 22, 22, 22, 22, 22, 35, 10, 34, 130, 37, 21, 100, 100, ''),
(0, 43, 217, 4250, 46, 0, 46, 173, 173, 173, 173, 173, 173, 173, 23, 23, 23, 23, 23, 35, 10, 34, 133, 42, 21, 100, 100, ''),
(0, 44, 221, 5000, 48, 0, 48, 176, 176, 176, 176, 176, 176, 176, 23, 23, 23, 23, 23, 36, 10, 35, 136, 50, 21, 100, 100, ''),
(0, 45, 225, 5600, 50, 0, 50, 179, 179, 179, 179, 179, 179, 179, 24, 24, 24, 24, 24, 37, 10, 36, 139, 56, 21, 100, 100, ''),
(0, 46, 229, 6000, 50, 0, 50, 182, 182, 182, 182, 182, 182, 182, 24, 24, 24, 24, 24, 38, 10, 44, 152, 60, 21, 100, 100, ''),
(0, 47, 233, 6500, 50, 0, 50, 185, 185, 185, 185, 185, 185, 185, 25, 25, 25, 25, 25, 39, 10, 51, 165, 65, 21, 100, 100, ''),
(0, 48, 237, 7500, 50, 0, 50, 188, 188, 188, 188, 188, 188, 188, 25, 25, 25, 25, 25, 39, 10, 59, 178, 75, 21, 100, 100, ''),
(0, 49, 241, 8500, 50, 0, 50, 191, 191, 191, 191, 191, 191, 191, 26, 26, 26, 26, 26, 40, 10, 66, 191, 85, 21, 100, 100, ''),
(0, 50, 245, 10000, 50, 0, 50, 194, 194, 194, 194, 194, 194, 194, 26, 26, 26, 26, 26, 41, 10, 74, 204, 100, 21, 100, 100, ''),
(0, 51, 249, 11700, 53, 0, 53, 197, 197, 197, 197, 197, 197, 197, 27, 27, 27, 27, 27, 42, 11, 78, 231, 117, 20, 100, 100, ''),
(0, 52, 253, 13400, 56, 0, 56, 200, 200, 200, 200, 200, 200, 200, 27, 27, 27, 27, 27, 43, 12, 81, 258, 134, 20, 100, 100, ''),
(0, 53, 257, 15100, 59, 0, 59, 203, 203, 203, 203, 203, 203, 203, 28, 28, 28, 28, 28, 43, 13, 85, 284, 151, 20, 100, 100, ''),
(0, 54, 261, 16800, 62, 10, 62, 206, 206, 206, 206, 206, 206, 206, 28, 28, 28, 28, 28, 44, 14, 89, 311, 168, 20, 100, 100, ''),
(0, 55, 266, 18500, 65, 10, 65, 210, 210, 210, 210, 210, 210, 210, 29, 29, 29, 29, 29, 45, 15, 93, 338, 185, 20, 100, 100, ''),
(0, 56, 270, 20200, 68, 10, 68, 213, 213, 213, 213, 213, 213, 213, 29, 29, 29, 29, 29, 46, 16, 96, 365, 202, 20, 100, 100, ''),
(0, 57, 274, 21900, 71, 10, 71, 216, 216, 216, 216, 216, 216, 216, 30, 30, 30, 30, 30, 47, 17, 100, 392, 219, 19, 100, 100, ''),
(0, 58, 278, 23600, 74, 10, 74, 219, 219, 219, 219, 219, 219, 219, 30, 30, 30, 30, 30, 47, 18, 104, 418, 236, 19, 100, 100, '8,1'),
(0, 59, 282, 25300, 77, 10, 77, 222, 222, 222, 222, 222, 222, 222, 31, 31, 31, 31, 31, 48, 19, 107, 445, 253, 19, 100, 100, '8,1'),
(0, 60, 286, 27000, 80, 20, 80, 225, 225, 225, 225, 225, 225, 225, 31, 31, 31, 31, 31, 49, 20, 111, 472, 270, 19, 100, 100, '8,1^21,1'),
(0, 61, 290, 28909, 85, 20, 84, 228, 228, 228, 228, 228, 228, 228, 32, 32, 32, 32, 32, 50, 24, 128, 536, 289, 19, 100, 100, '8,1^21,1'),
(0, 62, 294, 30818, 91, 20, 87, 231, 231, 231, 231, 231, 231, 231, 32, 32, 32, 32, 32, 51, 28, 145, 599, 308, 18, 100, 100, '8,1^21,1'),
(0, 63, 299, 32727, 96, 20, 91, 234, 234, 234, 234, 234, 234, 234, 33, 33, 33, 33, 33, 51, 32, 162, 663, 327, 18, 100, 100, '8,1^21,1'),
(0, 64, 303, 34636, 102, 20, 95, 237, 237, 237, 237, 237, 237, 237, 33, 33, 33, 33, 33, 52, 36, 179, 727, 346, 18, 100, 100, '8,1^21,1'),
(0, 65, 307, 36545, 107, 25, 98, 240, 240, 240, 240, 240, 240, 240, 34, 34, 34, 34, 34, 53, 40, 196, 790, 365, 18, 100, 100, '8,1^21,1'),
(0, 66, 311, 38455, 113, 25, 102, 244, 244, 244, 244, 244, 244, 244, 34, 34, 34, 34, 34, 54, 44, 213, 854, 384, 18, 100, 100, '8,1^21,1'),
(0, 67, 315, 40364, 118, 25, 105, 247, 247, 247, 247, 247, 247, 247, 35, 35, 35, 35, 35, 55, 48, 230, 917, 403, 17, 100, 100, '8,1^21,1'),
(0, 68, 319, 42273, 124, 25, 109, 250, 250, 250, 250, 250, 250, 250, 35, 35, 35, 35, 35, 56, 52, 247, 981, 422, 17, 100, 100, '8,1^21,1'),
(0, 69, 324, 44182, 129, 25, 113, 253, 253, 253, 253, 253, 253, 253, 36, 36, 36, 36, 36, 56, 56, 264, 1045, 441, 17, 100, 100, '8,1^21,1'),
(0, 70, 328, 46091, 135, 30, 116, 256, 256, 256, 256, 256, 256, 256, 36, 36, 36, 36, 36, 57, 60, 281, 1108, 460, 17, 100, 100, '8,1^21,1'),
(0, 71, 332, 48000, 140, 30, 120, 259, 259, 259, 259, 259, 259, 259, 37, 37, 37, 37, 37, 58, 64, 298, 1172, 480, 17, 100, 100, '8,1^21,1'),
(0, 72, 336, 49909, 143, 30, 128, 262, 262, 262, 262, 262, 262, 262, 38, 38, 38, 38, 38, 59, 68, 305, 1193, 499, 17, 100, 100, '8,1^21,1'),
(0, 73, 340, 51818, 145, 30, 135, 265, 265, 265, 265, 265, 265, 265, 39, 39, 39, 39, 39, 60, 72, 312, 1214, 518, 17, 100, 100, '8,1^21,1'),
(0, 74, 344, 53727, 148, 30, 143, 268, 268, 268, 268, 268, 268, 268, 39, 39, 39, 39, 39, 61, 76, 318, 1235, 537, 17, 100, 100, '8,1^21,1'),
(0, 75, 348, 55636, 150, 30, 150, 271, 271, 271, 271, 271, 271, 271, 40, 40, 40, 40, 40, 62, 80, 325, 1256, 556, 17, 100, 100, '8,1^21,1'),
(0, 76, 352, 75000, 160, 30, 160, 274, 274, 274, 274, 274, 274, 274, 41, 41, 41, 41, 41, 63, 84, 400, 1600, 750, 17, 100, 100, '8,1^21,1'),
(0, 77, 356, 90000, 170, 30, 170, 277, 277, 277, 277, 277, 277, 277, 42, 42, 42, 42, 42, 64, 88, 500, 2050, 900, 17, 100, 100, '8,1^21,1'),
(0, 78, 360, 113000, 180, 30, 180, 280, 280, 280, 280, 280, 280, 280, 43, 43, 43, 43, 43, 65, 92, 594, 2323, 1130, 17, 100, 100, '8,1^21,1'),
(0, 79, 364, 130000, 190, 30, 190, 283, 283, 283, 283, 283, 283, 283, 44, 44, 44, 44, 44, 66, 96, 650, 2500, 1300, 17, 100, 100, '8,1^21,1'),
(0, 80, 368, 140000, 200, 30, 200, 286, 286, 286, 286, 286, 286, 286, 45, 45, 45, 45, 45, 67, 100, 720, 2799, 1140, 16, 100, 100, '8,1^21,1'),
(0, 81, 372, 240000, 300, 30, 300, 289, 289, 289, 289, 289, 289, 289, 46, 46, 46, 46, 46, 68, 104, 800, 3599, 2400, 16, 100, 100, '8,1^21,1'),
(0, 82, 376, 340000, 400, 30, 400, 292, 292, 292, 292, 292, 292, 292, 47, 47, 47, 47, 47, 69, 108, 900, 4599, 3400, 16, 100, 100, '8,1^21,1'),
(0, 83, 380, 440000, 410, 30, 410, 295, 295, 295, 295, 295, 295, 295, 48, 48, 48, 48, 48, 70, 112, 1275, 4904, 4400, 16, 100, 100, '8,1^21,1'),
(0, 84, 384, 445000, 420, 30, 420, 298, 298, 298, 298, 298, 298, 298, 49, 49, 49, 49, 49, 71, 116, 1300, 5100, 4450, 16, 100, 100, '8,1^21,1'),
(0, 85, 388, 450000, 430, 30, 430, 301, 301, 301, 301, 301, 301, 301, 50, 50, 50, 50, 50, 72, 120, 1359, 5292, 4500, 16, 100, 100, '8,1^21,1'),
(0, 86, 392, 455000, 440, 30, 440, 304, 304, 304, 304, 304, 304, 304, 51, 51, 51, 51, 51, 73, 124, 1475, 5578, 4550, 16, 100, 100, '8,1^21,1'),
(0, 87, 396, 460000, 450, 30, 450, 307, 307, 307, 307, 307, 307, 307, 52, 52, 52, 52, 52, 74, 128, 1510, 5918, 4600, 16, 100, 100, '8,1^21,1'),
(0, 88, 400, 465000, 460, 30, 460, 310, 310, 310, 310, 310, 310, 310, 53, 53, 53, 53, 53, 75, 132, 1610, 6200, 4650, 16, 100, 100, '8,1^21,1'),
(0, 89, 404, 470000, 470, 30, 470, 313, 313, 313, 313, 313, 313, 313, 54, 54, 54, 54, 54, 76, 136, 1650, 6275, 4700, 16, 100, 100, '8,1^21,1'),
(0, 90, 408, 475000, 480, 30, 480, 316, 316, 316, 316, 316, 316, 316, 55, 55, 55, 55, 55, 77, 140, 1700, 6350, 4750, 16, 100, 100, '8,1^21,1'),
(1, 1, 10, 13, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 12, 1, 7, 0, 30, 100, 100, '13,1^14,1^21,1'),
(1, 2, 13, 32, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 2, 12, 1, 10, 0, 30, 100, 100, '13,1^14,1^21,1'),
(1, 3, 17, 52, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 2, 2, 2, 2, 2, 2, 12, 1, 12, 1, 30, 100, 100, '13,1^14,1^21,1'),
(1, 4, 19, 71, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 2, 4, 12, 1, 14, 1, 30, 100, 100, '13,1^14,1^21,1'),
(1, 5, 23, 90, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 2, 4, 12, 1, 17, 1, 30, 100, 100, '13,1^14,1^21,1'),
(1, 6, 26, 120, 0, 0, 0, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 5, 12, 1, 19, 1, 30, 100, 100, '13,1^14,1^21,1'),
(1, 7, 30, 150, 0, 0, 0, 31, 31, 31, 31, 31, 31, 31, 4, 4, 4, 4, 4, 5, 12, 1, 22, 2, 30, 100, 100, '13,1^14,1^21,1'),
(1, 8, 34, 180, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, 4, 4, 4, 4, 4, 6, 12, 1, 24, 2, 30, 100, 100, '13,1^14,1^21,1'),
(1, 9, 37, 210, 0, 0, 0, 38, 38, 38, 38, 38, 38, 38, 5, 5, 5, 5, 5, 6, 12, 1, 26, 2, 30, 100, 100, '13,1^14,1^21,1'),
(1, 10, 41, 240, 0, 0, 0, 42, 42, 42, 42, 42, 42, 42, 5, 5, 5, 5, 5, 7, 12, 1, 29, 2, 30, 100, 100, '13,1^14,1^21,1'),
(1, 11, 44, 281, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 6, 6, 6, 6, 6, 8, 12, 4, 32, 3, 30, 100, 100, '13,1^14,1^21,1'),
(1, 12, 48, 322, 0, 0, 0, 50, 50, 50, 50, 50, 50, 50, 6, 6, 6, 6, 6, 10, 12, 5, 36, 3, 30, 100, 100, '13,1^14,1^21,1'),
(1, 13, 52, 362, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 7, 7, 7, 7, 7, 10, 12, 7, 38, 4, 30, 100, 100, '13,1^14,1^21,1'),
(1, 14, 55, 403, 0, 0, 0, 58, 58, 58, 58, 58, 58, 58, 7, 7, 7, 7, 7, 11, 12, 8, 42, 4, 30, 100, 100, '13,1^14,1^21,1'),
(1, 15, 62, 457, 0, 0, 0, 61, 61, 61, 61, 61, 61, 61, 7, 7, 7, 7, 7, 12, 12, 8, 44, 5, 30, 100, 100, '13,1^14,1^21,1'),
(1, 16, 71, 511, 0, 0, 0, 65, 65, 65, 65, 65, 65, 65, 8, 8, 8, 8, 8, 12, 12, 10, 47, 5, 30, 100, 100, '13,1^14,1^21,1'),
(1, 17, 78, 565, 0, 0, 0, 68, 68, 68, 68, 68, 68, 68, 8, 8, 8, 8, 8, 13, 12, 10, 49, 6, 30, 100, 100, '13,1^14,1^21,1'),
(1, 18, 86, 619, 0, 0, 0, 72, 72, 72, 72, 72, 72, 72, 8, 8, 8, 8, 8, 13, 12, 11, 50, 6, 30, 100, 100, '13,1^14,1^21,1'),
(1, 19, 94, 673, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 8, 8, 8, 8, 8, 14, 12, 11, 53, 7, 30, 100, 100, '13,1^14,1^21,1'),
(1, 20, 102, 727, 0, 0, 0, 79, 79, 79, 79, 79, 79, 79, 10, 10, 10, 10, 10, 14, 12, 12, 55, 7, 30, 100, 100, '13,1^14,1^21,1'),
(1, 21, 109, 781, 0, 0, 0, 83, 83, 83, 83, 83, 83, 83, 10, 10, 10, 10, 10, 16, 12, 12, 58, 8, 30, 100, 100, '13,1^14,1^21,1'),
(1, 22, 114, 854, 0, 0, 0, 86, 86, 86, 86, 86, 86, 86, 10, 10, 10, 10, 10, 17, 12, 12, 60, 9, 30, 100, 100, '13,1^14,1^21,1'),
(1, 23, 119, 928, 0, 0, 0, 90, 90, 90, 90, 90, 90, 90, 11, 11, 11, 11, 11, 17, 12, 12, 62, 9, 30, 100, 100, '13,1^14,1^21,1'),
(1, 24, 124, 1001, 0, 0, 0, 94, 94, 94, 94, 94, 94, 94, 11, 11, 11, 11, 11, 18, 12, 13, 66, 10, 30, 100, 100, '13,1^14,1^21,1'),
(1, 25, 128, 1074, 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 12, 12, 12, 12, 12, 19, 12, 13, 68, 11, 30, 100, 100, '13,1^14,1^21,1'),
(1, 26, 133, 1147, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 12, 12, 12, 12, 12, 19, 12, 13, 71, 11, 30, 100, 100, '13,1^14,1^21,1'),
(1, 27, 138, 1220, 0, 0, 0, 106, 106, 106, 106, 106, 106, 106, 13, 13, 13, 13, 13, 20, 12, 13, 73, 12, 30, 100, 100, '13,1^14,1^21,1'),
(1, 28, 143, 1294, 0, 0, 0, 109, 109, 109, 109, 109, 109, 109, 13, 13, 13, 13, 13, 22, 12, 14, 77, 13, 30, 100, 100, '13,1^14,1^21,1'),
(1, 29, 148, 1367, 0, 0, 0, 113, 113, 113, 113, 113, 113, 113, 14, 14, 14, 14, 14, 22, 12, 14, 79, 14, 30, 100, 100, '13,1^14,1^21,1'),
(1, 30, 152, 1440, 0, 0, 0, 116, 116, 116, 116, 116, 116, 116, 14, 14, 14, 14, 14, 23, 12, 14, 82, 14, 30, 100, 100, '13,1^14,1^21,1'),
(1, 31, 162, 1896, 5, 0, 5, 125, 125, 125, 125, 125, 125, 125, 16, 16, 16, 16, 16, 24, 12, 17, 89, 19, 30, 100, 100, '13,1^14,1^21,1'),
(1, 32, 170, 2352, 10, 0, 10, 132, 132, 132, 132, 132, 132, 132, 17, 17, 17, 17, 17, 26, 12, 19, 95, 24, 30, 100, 100, '13,1^14,1^21,1'),
(1, 33, 180, 2808, 14, 0, 14, 140, 140, 140, 140, 140, 140, 140, 18, 18, 18, 18, 18, 28, 12, 22, 102, 28, 29, 100, 100, '13,1^14,1^21,1'),
(1, 34, 190, 3264, 19, 0, 19, 148, 148, 148, 148, 148, 148, 148, 19, 19, 19, 19, 19, 30, 12, 24, 108, 33, 28, 100, 100, '13,1^14,1^21,1'),
(1, 35, 199, 3720, 24, 0, 24, 156, 156, 156, 156, 156, 156, 156, 20, 20, 20, 20, 20, 31, 12, 26, 115, 37, 27, 100, 100, '13,1^14,1^21,1'),
(1, 36, 208, 4176, 29, 0, 29, 164, 164, 164, 164, 164, 164, 164, 20, 20, 20, 20, 20, 32, 12, 29, 122, 42, 25, 100, 100, '13,1^14,1^21,1'),
(1, 37, 217, 4632, 34, 0, 34, 172, 172, 172, 172, 172, 172, 172, 22, 22, 22, 22, 22, 35, 12, 31, 128, 46, 24, 100, 100, '13,1^14,1^21,1'),
(1, 38, 227, 5088, 38, 0, 38, 180, 180, 180, 180, 180, 180, 180, 23, 23, 23, 23, 23, 36, 12, 34, 136, 51, 23, 100, 100, '13,1^14,1^21,1'),
(1, 39, 235, 5544, 43, 0, 43, 187, 187, 187, 187, 187, 187, 187, 24, 24, 24, 24, 24, 38, 12, 36, 142, 55, 22, 100, 100, '13,1^14,1^21,1'),
(1, 40, 245, 6000, 48, 0, 48, 196, 196, 196, 196, 196, 196, 196, 25, 25, 25, 25, 25, 40, 12, 38, 149, 60, 21, 100, 100, '13,1^14,1^21,1'),
(1, 41, 250, 6360, 50, 0, 50, 199, 199, 199, 199, 199, 199, 199, 26, 26, 26, 26, 26, 41, 12, 40, 152, 64, 21, 100, 100, '13,1^14,1^21,1'),
(1, 42, 254, 6720, 53, 0, 53, 203, 203, 203, 203, 203, 203, 203, 26, 26, 26, 26, 26, 42, 12, 41, 156, 67, 21, 100, 100, '13,1^14,1^21,1'),
(1, 43, 260, 7080, 55, 0, 55, 208, 208, 208, 208, 208, 208, 208, 28, 28, 28, 28, 28, 42, 12, 41, 160, 71, 21, 100, 100, '13,1^14,1^21,1'),
(1, 44, 265, 7440, 58, 0, 58, 211, 211, 211, 211, 211, 211, 211, 28, 28, 28, 28, 28, 43, 12, 42, 163, 74, 21, 100, 100, '13,1^14,1^21,1'),
(1, 45, 270, 7800, 60, 0, 60, 215, 215, 215, 215, 215, 215, 215, 29, 29, 29, 29, 29, 44, 12, 43, 167, 78, 21, 100, 100, '13,1^14,1^21,1'),
(1, 46, 275, 8640, 60, 0, 60, 218, 218, 218, 218, 218, 218, 218, 29, 29, 29, 29, 29, 46, 12, 53, 182, 86, 21, 100, 100, '13,1^14,1^21,1'),
(1, 47, 280, 9480, 60, 0, 60, 222, 222, 222, 222, 222, 222, 222, 30, 30, 30, 30, 30, 47, 12, 61, 198, 95, 21, 100, 100, '13,1^14,1^21,1'),
(1, 48, 284, 10320, 60, 0, 60, 226, 226, 226, 226, 226, 226, 226, 30, 30, 30, 30, 30, 47, 12, 71, 214, 103, 21, 100, 100, '13,1^14,1^21,1'),
(1, 49, 289, 11160, 60, 0, 60, 229, 229, 229, 229, 229, 229, 229, 31, 31, 31, 31, 31, 48, 12, 79, 229, 112, 21, 100, 100, '13,1^14,1^21,1'),
(1, 50, 294, 12000, 60, 0, 60, 233, 233, 233, 233, 233, 233, 233, 31, 31, 31, 31, 31, 49, 12, 89, 245, 120, 21, 100, 100, '13,1^14,1^21,1'),
(1, 51, 299, 14040, 64, 0, 64, 236, 236, 236, 236, 236, 236, 236, 32, 32, 32, 32, 32, 50, 13, 94, 277, 140, 20, 100, 100, '13,1^14,1^21,1'),
(1, 52, 304, 16080, 67, 0, 67, 240, 240, 240, 240, 240, 240, 240, 32, 32, 32, 32, 32, 52, 14, 97, 310, 161, 20, 100, 100, '13,1^14,1^21,1'),
(1, 53, 308, 18120, 71, 0, 71, 244, 244, 244, 244, 244, 244, 244, 34, 34, 34, 34, 34, 52, 16, 102, 341, 181, 20, 100, 100, '13,1^14,1^21,1'),
(1, 54, 313, 20160, 74, 0, 74, 247, 247, 247, 247, 247, 247, 247, 34, 34, 34, 34, 34, 53, 17, 107, 373, 202, 20, 100, 100, '13,1^14,1^21,1'),
(1, 55, 319, 22200, 78, 0, 78, 252, 252, 252, 252, 252, 252, 252, 35, 35, 35, 35, 35, 54, 18, 112, 406, 222, 20, 100, 100, '13,1^14,1^21,1'),
(1, 56, 324, 24240, 82, 0, 82, 256, 256, 256, 256, 256, 256, 256, 35, 35, 35, 35, 35, 55, 19, 115, 438, 242, 20, 100, 100, '13,1^14,1^21,1'),
(1, 57, 329, 26280, 85, 0, 85, 259, 259, 259, 259, 259, 259, 259, 36, 36, 36, 36, 36, 56, 20, 120, 470, 263, 19, 100, 100, '13,1^14,1^21,1'),
(1, 58, 334, 28320, 89, 0, 89, 263, 263, 263, 263, 263, 263, 263, 36, 36, 36, 36, 36, 56, 22, 125, 502, 283, 19, 100, 100, '13,1^14,1^21,1'),
(1, 59, 338, 30360, 92, 0, 92, 266, 266, 266, 266, 266, 266, 266, 37, 37, 37, 37, 37, 58, 23, 128, 534, 304, 19, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 60, 343, 32400, 96, 30, 96, 270, 270, 270, 270, 270, 270, 270, 37, 37, 37, 37, 37, 59, 24, 133, 566, 324, 19, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 61, 348, 34691, 102, 30, 101, 274, 274, 274, 274, 274, 274, 274, 38, 38, 38, 38, 38, 60, 29, 154, 643, 347, 19, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 62, 353, 36982, 109, 30, 104, 277, 277, 277, 277, 277, 277, 277, 38, 38, 38, 38, 38, 61, 34, 174, 719, 370, 18, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 63, 359, 39272, 115, 30, 109, 281, 281, 281, 281, 281, 281, 281, 40, 40, 40, 40, 40, 61, 38, 194, 796, 393, 18, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 64, 364, 41563, 122, 30, 114, 284, 284, 284, 284, 284, 284, 284, 40, 40, 40, 40, 40, 62, 43, 215, 872, 416, 18, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 65, 368, 43854, 128, 35, 118, 288, 288, 288, 288, 288, 288, 288, 41, 41, 41, 41, 41, 64, 48, 235, 948, 439, 18, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 66, 373, 46146, 136, 35, 122, 293, 293, 293, 293, 293, 293, 293, 41, 41, 41, 41, 41, 65, 53, 256, 1025, 461, 18, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 67, 378, 48437, 142, 35, 126, 296, 296, 296, 296, 296, 296, 296, 42, 42, 42, 42, 42, 66, 58, 276, 1100, 484, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 68, 383, 50728, 149, 35, 131, 300, 300, 300, 300, 300, 300, 300, 42, 42, 42, 42, 42, 67, 62, 296, 1177, 507, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 69, 389, 53018, 155, 35, 136, 304, 304, 304, 304, 304, 304, 304, 43, 43, 43, 43, 43, 67, 67, 317, 1254, 530, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 70, 394, 55309, 162, 40, 139, 307, 307, 307, 307, 307, 307, 307, 43, 43, 43, 43, 43, 68, 72, 337, 1330, 553, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 71, 398, 57600, 168, 40, 144, 311, 311, 311, 311, 311, 311, 311, 44, 44, 44, 44, 44, 70, 77, 358, 1406, 576, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 72, 403, 57600, 172, 40, 154, 314, 314, 314, 314, 314, 314, 314, 46, 46, 46, 46, 46, 71, 82, 366, 1432, 576, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 73, 408, 57600, 174, 40, 162, 318, 318, 318, 318, 318, 318, 318, 47, 47, 47, 47, 47, 72, 86, 374, 1457, 576, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 74, 413, 57600, 178, 40, 172, 322, 322, 322, 322, 322, 322, 322, 47, 47, 47, 47, 47, 73, 91, 382, 1482, 576, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 75, 418, 57600, 180, 40, 180, 325, 325, 325, 325, 325, 325, 325, 48, 48, 48, 48, 48, 74, 96, 390, 1507, 576, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 76, 423, 90000, 192, 45, 192, 329, 329, 329, 329, 329, 329, 329, 49, 49, 49, 49, 49, 76, 101, 480, 1920, 900, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 77, 428, 108000, 204, 45, 204, 332, 332, 332, 332, 332, 332, 332, 50, 50, 50, 50, 50, 77, 106, 600, 2460, 1080, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 78, 433, 135600, 216, 45, 216, 336, 336, 336, 336, 336, 336, 336, 52, 52, 52, 52, 52, 78, 110, 713, 2788, 1356, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 79, 438, 156000, 228, 45, 228, 340, 340, 340, 340, 340, 340, 340, 53, 53, 53, 53, 53, 79, 115, 780, 3000, 1560, 17, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 80, 443, 168000, 240, 45, 240, 343, 343, 343, 343, 343, 343, 343, 54, 54, 54, 54, 54, 80, 120, 864, 3359, 1680, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 81, 448, 288000, 360, 45, 360, 347, 347, 347, 347, 347, 347, 347, 55, 55, 55, 55, 55, 82, 125, 960, 4319, 2880, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 82, 453, 408000, 480, 45, 480, 350, 350, 350, 350, 350, 350, 350, 56, 56, 56, 56, 56, 83, 130, 1080, 5519, 4080, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 83, 458, 528000, 492, 45, 492, 354, 354, 354, 354, 354, 354, 354, 58, 58, 58, 58, 58, 84, 134, 1530, 5885, 5280, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 84, 463, 534000, 504, 45, 504, 358, 358, 358, 358, 358, 358, 358, 59, 59, 59, 59, 59, 85, 139, 1560, 6120, 5340, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 85, 468, 540000, 516, 45, 516, 361, 361, 361, 361, 361, 361, 361, 60, 60, 60, 60, 60, 86, 144, 1631, 6350, 5400, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 86, 473, 546000, 528, 45, 528, 365, 365, 365, 365, 365, 365, 365, 61, 61, 61, 61, 61, 88, 149, 1770, 6694, 5460, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 87, 478, 552000, 540, 45, 540, 368, 368, 368, 368, 368, 368, 368, 62, 62, 62, 62, 62, 89, 154, 1812, 7102, 5520, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 88, 483, 558000, 552, 45, 552, 372, 372, 372, 372, 372, 372, 372, 64, 64, 64, 64, 64, 90, 158, 1932, 7440, 5580, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 89, 488, 564000, 564, 45, 564, 376, 376, 376, 376, 376, 376, 376, 65, 65, 65, 65, 65, 91, 163, 1980, 7530, 5640, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(1, 90, 490, 570000, 576, 45, 576, 379, 379, 379, 379, 379, 379, 379, 66, 66, 66, 66, 66, 92, 168, 2040, 7620, 5700, 16, 100, 100, '1,1^8,1^13,1^14,1^21,1'),
(2, 1, 12, 17, 0, 0, 0, 12, 12, 12, 12, 12, 12, 12, 2, 2, 2, 2, 2, 2, 15, 2, 9, 0, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 2, 17, 41, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 4, 4, 4, 4, 4, 4, 15, 2, 12, 0, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 3, 21, 65, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 6, 6, 6, 6, 6, 6, 15, 2, 15, 1, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 4, 24, 89, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 8, 8, 8, 8, 8, 8, 15, 2, 18, 1, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 5, 29, 113, 0, 0, 0, 30, 30, 30, 30, 30, 30, 30, 10, 10, 10, 10, 10, 10, 15, 2, 21, 1, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 6, 33, 150, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, 12, 12, 12, 12, 12, 12, 15, 2, 24, 2, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 7, 38, 188, 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, 14, 14, 14, 14, 14, 14, 15, 2, 27, 2, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 8, 42, 225, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 16, 16, 16, 16, 16, 16, 15, 2, 30, 2, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 9, 47, 263, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 18, 18, 18, 18, 18, 18, 15, 2, 33, 3, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 10, 51, 300, 0, 0, 0, 53, 53, 53, 53, 53, 53, 53, 20, 20, 20, 20, 20, 20, 15, 2, 36, 3, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 11, 56, 351, 0, 0, 0, 57, 57, 57, 57, 57, 57, 57, 22, 22, 22, 22, 22, 22, 15, 5, 41, 4, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 12, 60, 402, 0, 0, 0, 63, 63, 63, 63, 63, 63, 63, 24, 24, 24, 24, 24, 24, 15, 6, 45, 4, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 13, 65, 453, 0, 0, 0, 68, 68, 68, 68, 68, 68, 68, 26, 26, 26, 26, 26, 26, 15, 9, 48, 5, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 14, 69, 504, 0, 0, 0, 72, 72, 72, 72, 72, 72, 72, 28, 28, 28, 28, 28, 28, 15, 11, 53, 5, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 15, 78, 572, 0, 0, 0, 77, 77, 77, 77, 77, 77, 77, 30, 30, 30, 30, 30, 30, 15, 11, 56, 6, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 16, 89, 639, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 32, 32, 32, 32, 32, 32, 15, 12, 59, 6, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 17, 98, 707, 0, 0, 0, 86, 86, 86, 86, 86, 86, 86, 34, 34, 34, 34, 34, 34, 15, 12, 62, 7, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 18, 108, 774, 0, 0, 0, 90, 90, 90, 90, 90, 90, 90, 36, 36, 36, 36, 36, 36, 15, 14, 63, 8, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 19, 117, 842, 0, 0, 0, 95, 95, 95, 95, 95, 95, 95, 38, 38, 38, 38, 38, 38, 15, 14, 66, 8, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 20, 128, 909, 0, 0, 0, 99, 99, 99, 99, 99, 99, 99, 40, 40, 40, 40, 40, 40, 15, 15, 69, 9, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 21, 137, 977, 0, 0, 0, 104, 104, 104, 104, 104, 104, 104, 42, 42, 42, 42, 42, 42, 15, 15, 72, 10, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 22, 143, 1068, 0, 0, 0, 108, 108, 108, 108, 108, 108, 108, 44, 44, 44, 44, 44, 44, 15, 15, 75, 11, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 23, 149, 1160, 0, 0, 0, 113, 113, 113, 113, 113, 113, 113, 46, 46, 46, 46, 46, 46, 15, 15, 78, 12, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 24, 155, 1251, 0, 0, 0, 117, 117, 117, 117, 117, 117, 117, 48, 48, 48, 48, 48, 48, 15, 17, 83, 13, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 25, 161, 1343, 0, 0, 0, 122, 122, 122, 122, 122, 122, 122, 50, 50, 50, 50, 50, 50, 15, 17, 86, 13, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 26, 167, 1434, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 52, 52, 52, 52, 52, 52, 15, 17, 89, 14, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 27, 173, 1526, 0, 0, 0, 132, 132, 132, 132, 132, 132, 132, 54, 54, 54, 54, 54, 54, 15, 17, 92, 15, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 28, 179, 1617, 0, 0, 0, 137, 137, 137, 137, 137, 137, 137, 56, 56, 56, 56, 56, 56, 15, 18, 96, 16, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 29, 185, 1709, 0, 0, 0, 141, 141, 141, 141, 141, 141, 141, 58, 58, 58, 58, 58, 58, 15, 18, 99, 17, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 30, 191, 1800, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 60, 60, 60, 60, 60, 60, 15, 18, 102, 18, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 31, 203, 2370, 6, 0, 6, 156, 156, 156, 156, 156, 156, 156, 62, 62, 62, 62, 62, 62, 15, 21, 111, 24, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 32, 213, 2940, 12, 0, 12, 165, 165, 165, 165, 165, 165, 165, 64, 64, 64, 64, 64, 64, 15, 24, 119, 29, 30, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 33, 225, 3510, 18, 0, 18, 176, 176, 176, 176, 176, 176, 176, 66, 66, 66, 66, 66, 66, 15, 27, 128, 35, 29, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 34, 237, 4080, 24, 0, 24, 185, 185, 185, 185, 185, 185, 185, 68, 68, 68, 68, 68, 68, 15, 30, 135, 41, 28, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 35, 249, 4650, 30, 0, 30, 195, 195, 195, 195, 195, 195, 195, 70, 70, 70, 70, 70, 70, 15, 33, 144, 47, 27, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 36, 260, 5220, 36, 0, 36, 206, 206, 206, 206, 206, 206, 206, 72, 72, 72, 72, 72, 72, 15, 36, 153, 52, 25, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 37, 272, 5790, 42, 0, 42, 215, 215, 215, 215, 215, 215, 215, 74, 74, 74, 74, 74, 74, 15, 39, 161, 58, 24, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 38, 284, 6360, 48, 0, 48, 225, 225, 225, 225, 225, 225, 225, 76, 76, 76, 76, 76, 76, 15, 42, 170, 64, 23, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 39, 294, 6930, 54, 0, 54, 234, 234, 234, 234, 234, 234, 234, 78, 78, 78, 78, 78, 78, 15, 45, 177, 69, 22, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 40, 306, 7500, 60, 0, 60, 245, 245, 245, 245, 245, 245, 245, 80, 80, 80, 80, 80, 80, 15, 48, 186, 75, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 41, 312, 7950, 63, 0, 63, 249, 249, 249, 249, 249, 249, 249, 82, 82, 82, 82, 82, 82, 15, 50, 191, 80, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 42, 318, 8400, 66, 0, 66, 254, 254, 254, 254, 254, 254, 254, 84, 84, 84, 84, 84, 84, 15, 51, 195, 84, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 43, 326, 11000, 69, 0, 69, 260, 260, 260, 260, 260, 260, 260, 86, 86, 86, 86, 86, 86, 15, 51, 200, 110, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 44, 332, 25000, 72, 0, 72, 264, 264, 264, 264, 264, 264, 264, 88, 88, 88, 88, 88, 88, 15, 53, 204, 250, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 45, 338, 35000, 75, 0, 75, 269, 269, 269, 269, 269, 269, 269, 90, 90, 90, 90, 90, 90, 15, 54, 209, 350, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 46, 344, 45000, 75, 0, 75, 273, 273, 273, 273, 273, 273, 273, 92, 92, 92, 92, 92, 92, 15, 66, 228, 450, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 47, 350, 55000, 75, 0, 75, 278, 278, 278, 278, 278, 278, 278, 94, 94, 94, 94, 94, 94, 15, 77, 248, 550, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 48, 356, 70000, 75, 0, 75, 282, 282, 282, 282, 282, 282, 282, 96, 96, 96, 96, 96, 96, 15, 89, 267, 700, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 49, 362, 85000, 75, 0, 75, 287, 287, 287, 287, 287, 287, 287, 98, 98, 98, 98, 98, 98, 15, 99, 287, 850, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 50, 368, 100000, 75, 0, 75, 291, 291, 291, 291, 291, 291, 291, 100, 100, 100, 100, 100, 100, 15, 111, 306, 1000, 21, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 51, 374, 130000, 80, 0, 80, 296, 296, 296, 296, 296, 296, 296, 102, 102, 102, 102, 102, 102, 17, 117, 347, 1300, 20, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 52, 380, 140000, 84, 0, 84, 300, 300, 300, 300, 300, 300, 300, 104, 104, 104, 104, 104, 104, 18, 122, 387, 1400, 20, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 53, 386, 150000, 89, 0, 89, 305, 305, 305, 305, 305, 305, 305, 106, 106, 106, 106, 106, 106, 20, 128, 426, 1500, 19, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 54, 392, 160000, 93, 0, 93, 309, 309, 309, 309, 309, 309, 309, 108, 108, 108, 108, 108, 108, 21, 134, 467, 1600, 19, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 55, 399, 170000, 98, 0, 98, 315, 315, 315, 315, 315, 315, 315, 110, 110, 110, 110, 110, 110, 23, 140, 507, 1700, 18, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 56, 405, 180000, 102, 0, 102, 320, 320, 320, 320, 320, 320, 320, 112, 112, 112, 112, 112, 112, 24, 144, 548, 1800, 17, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 57, 411, 190000, 107, 0, 107, 324, 324, 324, 324, 324, 324, 324, 114, 114, 114, 114, 114, 114, 26, 150, 588, 1900, 17, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 58, 417, 200000, 111, 0, 111, 329, 329, 329, 329, 329, 329, 329, 116, 116, 116, 116, 116, 116, 27, 156, 627, 2000, 16, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 59, 434, 400750, 130, 0, 125, 253, 253, 253, 253, 253, 253, 253, 118, 118, 118, 118, 118, 118, 19, 170, 700, 4008, 16, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 60, 476, 450813, 140, 0, 129, 258, 258, 258, 258, 258, 258, 258, 120, 120, 120, 120, 120, 120, 22, 185, 740, 4508, 15, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 61, 517, 500875, 145, 0, 130, 263, 263, 263, 263, 263, 263, 263, 122, 122, 122, 122, 122, 122, 26, 195, 780, 5009, 15, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 62, 559, 550938, 150, 0, 140, 268, 268, 268, 268, 268, 268, 268, 124, 124, 124, 124, 124, 124, 29, 210, 800, 5509, 15, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 63, 600, 601000, 155, 0, 160, 273, 273, 273, 273, 273, 273, 273, 126, 126, 126, 126, 126, 126, 32, 220, 825, 6010, 15, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 64, 563, 734167, 160, 0, 170, 277, 277, 277, 277, 277, 277, 277, 128, 128, 128, 128, 128, 128, 50, 241, 850, 7342, 15, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 65, 525, 867333, 165, 0, 180, 281, 281, 281, 281, 281, 281, 281, 130, 130, 130, 130, 130, 130, 67, 262, 875, 8673, 14, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 66, 488, 1000500, 170, 0, 190, 285, 285, 285, 285, 285, 285, 285, 132, 132, 132, 132, 132, 132, 85, 283, 904, 10005, 14, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 67, 498, 1013841, 175, 10, 200, 292, 292, 292, 292, 292, 292, 292, 134, 134, 134, 134, 134, 134, 81, 312, 1071, 10138, 14, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 68, 508, 1027182, 180, 20, 225, 300, 300, 300, 300, 300, 300, 300, 136, 136, 136, 136, 136, 136, 77, 341, 1238, 10272, 14, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 69, 519, 1040522, 185, 30, 239, 307, 307, 307, 307, 307, 307, 307, 138, 138, 138, 138, 138, 138, 72, 369, 1404, 10405, 14, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 70, 529, 1053863, 190, 40, 245, 315, 315, 315, 315, 315, 315, 315, 140, 140, 140, 140, 140, 140, 68, 398, 1571, 10539, 14, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 71, 539, 1067204, 200, 50, 255, 322, 322, 322, 322, 322, 322, 322, 142, 142, 142, 142, 142, 142, 64, 427, 1738, 10672, 14, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 72, 547, 1262903, 220, 56, 265, 327, 327, 327, 327, 327, 327, 327, 144, 144, 144, 144, 144, 144, 68, 520, 1979, 12629, 14, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 73, 556, 1458602, 253, 63, 285, 332, 332, 332, 332, 332, 332, 332, 146, 146, 146, 146, 146, 146, 72, 614, 2219, 14586, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 74, 564, 1654301, 306, 69, 300, 337, 337, 337, 337, 337, 337, 337, 148, 148, 148, 148, 148, 148, 76, 707, 2460, 16543, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 75, 572, 1850000, 330, 75, 310, 342, 342, 342, 342, 342, 342, 342, 150, 150, 150, 150, 150, 150, 80, 725, 2700, 18500, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 76, 579, 1900000, 348, 77, 320, 346, 346, 346, 346, 346, 346, 346, 152, 152, 152, 152, 152, 152, 84, 750, 2960, 19000, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 77, 586, 1950000, 355, 79, 330, 350, 350, 350, 350, 350, 350, 350, 154, 154, 154, 154, 154, 154, 88, 775, 3000, 19500, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 78, 594, 2000000, 365, 81, 340, 354, 354, 354, 354, 354, 354, 354, 156, 156, 156, 156, 156, 156, 92, 800, 3100, 20000, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 79, 601, 2050000, 375, 83, 350, 358, 358, 358, 358, 358, 358, 358, 158, 158, 158, 158, 158, 158, 96, 825, 3200, 20500, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 80, 608, 2100000, 380, 85, 360, 362, 362, 362, 362, 362, 362, 362, 160, 160, 160, 160, 160, 160, 100, 850, 3300, 21000, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 81, 615, 2480000, 385, 83, 370, 366, 366, 366, 366, 366, 366, 366, 162, 162, 162, 162, 162, 162, 104, 875, 3350, 24800, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 82, 622, 2860000, 390, 81, 380, 370, 370, 370, 370, 370, 370, 370, 164, 164, 164, 164, 164, 164, 108, 900, 3400, 28600, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 83, 629, 3240000, 395, 79, 390, 375, 375, 375, 375, 375, 375, 375, 166, 166, 166, 166, 166, 166, 112, 925, 3450, 32400, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 84, 636, 3620000, 400, 77, 400, 379, 379, 379, 379, 379, 379, 379, 168, 168, 168, 168, 168, 168, 116, 940, 3500, 36200, 13, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 85, 643, 4000000, 405, 75, 410, 383, 383, 383, 383, 383, 383, 383, 170, 170, 170, 170, 170, 170, 120, 960, 3550, 40000, 12, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 86, 650, 4800000, 410, 77, 420, 387, 387, 387, 387, 387, 387, 387, 172, 172, 172, 172, 172, 172, 124, 980, 3600, 48000, 12, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 87, 657, 5600000, 415, 79, 430, 391, 391, 391, 391, 391, 391, 391, 174, 174, 174, 174, 174, 174, 128, 1000, 3650, 56000, 12, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 88, 665, 6400000, 420, 81, 440, 395, 395, 395, 395, 395, 395, 395, 176, 176, 176, 176, 176, 176, 132, 1010, 3700, 64000, 12, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 89, 672, 7200000, 420, 83, 445, 399, 399, 399, 399, 399, 399, 399, 178, 178, 178, 178, 178, 178, 136, 1018, 3800, 72000, 12, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1'),
(2, 90, 679, 8000000, 420, 85, 450, 403, 403, 403, 403, 403, 403, 403, 180, 180, 180, 180, 180, 180, 140, 1050, 3900, 80000, 12, 100, 100, '1,1^2,1^8,1^13,1^14,1^15,1^16,1^17,1^21,1^31,1');

View File

@ -0,0 +1 @@
ALTER TABLE `spawn2` MODIFY `version` SMALLINT(5) SIGNED NOT NULL DEFAULT '0';

View File

@ -14,12 +14,15 @@ auras
base_data
blocked_spells
books
bug_reports
char_create_combinations
char_create_point_allocations
class_skill
damageshieldtypes
data_buckets
db_str
doors
eqtime
faction_list
faction_list_mod
fear_hints
@ -34,6 +37,7 @@ ground_spawns
horses
instance_list
items
ip_exemptions
ldon_trap_entries
ldon_trap_templates
level_exp_mods
@ -73,6 +77,7 @@ npc_types
npc_types_metadata
npc_types_tint
object
perl_event_export_settings
pets
pets_equipmentset
pets_equipmentset_entries

View File

@ -10,31 +10,33 @@ Banned_IPs
bugs
buyer
char_recipe_list
character_data
character_currency
character_alternate_abilities
character_bind
character_corpses
character_corpse_items
character_languages
character_skills
character_spells
character_memmed_spells
character_disciplines
character_material
character_tribute
character_bandolier
character_potionbelt
character_inspect_messages
character_leadership_abilities
character_activities
character_alt_currency
character_alternate_abilities
character_auras
character_bandolier
character_bind
character_buffs
character_corpse_items
character_corpses
character_currency
character_data
character_disciplines
character_enabledtasks
character_inspect_messages
character_item_recast
character_languages
character_leadership_abilities
character_material
character_memmed_spells
character_pet_buffs
character_pet_info
character_pet_inventory
character_potionbelt
character_skills
character_spells
character_tasks
character_tribute
chatchannels
completed_tasks
discovered_items
@ -44,11 +46,11 @@ friends
gm_ips
group_id
group_leaders
guilds
guild_bank
guild_members
guild_ranks
guild_relations
guild_members
guilds
hackers
instance_list_player
inventory
@ -62,6 +64,14 @@ merchantlist_temp
object_contents
petitions
player_titlesets
qs_merchant_transaction_record
qs_merchant_transaction_record_entries
qs_player_aa_rate_hourly
qs_player_delete_record
qs_player_delete_record_entries
qs_player_events
qs_player_handin_record
qs_player_handin_record_entries
qs_player_move_record
qs_player_move_record_entries
qs_player_npc_kill_record
@ -69,14 +79,6 @@ qs_player_npc_kill_record_entries
qs_player_speech
qs_player_trade_record
qs_player_trade_record_entries
qs_merchant_transaction_record
qs_merchant_transaction_record_entries
qs_player_delete_record
qs_player_delete_record_entries
qs_player_handin_record
qs_player_handin_record_entries
qs_player_aa_rate_hourly
qs_player_events
quest_globals
raid_details
raid_leaders
@ -84,8 +86,8 @@ raid_members
reports
respawn_times
sharedbank
spell_globals
spell_buckets
spell_globals
timers
trader
trader_audit

View File

@ -171,10 +171,13 @@ void Client::SendEnterWorld(std::string name)
void Client::SendExpansionInfo() {
auto outapp = new EQApplicationPacket(OP_ExpansionInfo, sizeof(ExpansionInfo_Struct));
ExpansionInfo_Struct *eis = (ExpansionInfo_Struct*)outapp->pBuffer;
if(RuleB(World, UseClientBasedExpansionSettings)) {
eis->Expansions = EQEmu::versions::ConvertClientVersionToExpansion(eqs->ClientVersion());
} else {
eis->Expansions = (RuleI(World, ExpansionSettings));
// need to rework .. not until full scope of change is accounted for, though
if (RuleB(World, UseClientBasedExpansionSettings)) {
eis->Expansions = EQEmu::expansions::ConvertClientVersionToExpansionMask(eqs->ClientVersion());
}
else {
eis->Expansions = RuleI(World, ExpansionSettings);
}
QueuePacket(outapp);
@ -186,7 +189,7 @@ void Client::SendCharInfo() {
cle->SetOnline(CLE_Status_CharSelect);
}
if (m_ClientVersionBit & EQEmu::versions::bit_RoFAndLater) {
if (m_ClientVersionBit & EQEmu::versions::maskRoFAndLater) {
SendMaxCharCreate();
SendMembership();
SendMembershipSettings();
@ -211,7 +214,7 @@ void Client::SendMaxCharCreate() {
auto outapp = new EQApplicationPacket(OP_SendMaxCharacters, sizeof(MaxCharacters_Struct));
MaxCharacters_Struct* mc = (MaxCharacters_Struct*)outapp->pBuffer;
mc->max_chars = EQEmu::constants::Lookup(m_ClientVersion)->CharacterCreationLimit;
mc->max_chars = EQEmu::constants::StaticLookup(m_ClientVersion)->CharacterCreationLimit;
if (mc->max_chars > EQEmu::constants::CHARACTER_CREATION_LIMIT)
mc->max_chars = EQEmu::constants::CHARACTER_CREATION_LIMIT;
@ -717,7 +720,7 @@ bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
}
else
{
if (m_ClientVersionBit & EQEmu::versions::bit_TitaniumAndEarlier)
if (m_ClientVersionBit & EQEmu::versions::maskTitaniumAndEarlier)
StartInTutorial = true;
SendCharInfo();
}
@ -765,7 +768,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
// This can probably be moved outside and have another method return requested info (don't forget to remove the #include "../common/shareddb.h" above)
// (This is a literal translation of the original process..I don't see why it can't be changed to a single-target query over account iteration)
if (!is_player_zoning) {
size_t character_limit = EQEmu::constants::Lookup(eqs->ClientVersion())->CharacterCreationLimit;
size_t character_limit = EQEmu::constants::StaticLookup(eqs->ClientVersion())->CharacterCreationLimit;
if (character_limit > EQEmu::constants::CHARACTER_CREATION_LIMIT) { character_limit = EQEmu::constants::CHARACTER_CREATION_LIMIT; }
if (eqs->ClientVersion() == EQEmu::versions::ClientVersion::Titanium) { character_limit = Titanium::constants::CHARACTER_CREATION_LIMIT; }
@ -989,7 +992,7 @@ bool Client::HandleDeleteCharacterPacket(const EQApplicationPacket *app) {
bool Client::HandleZoneChangePacket(const EQApplicationPacket *app) {
// HoT sends this to world while zoning and wants it echoed back.
if (m_ClientVersionBit & EQEmu::versions::bit_RoFAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskRoFAndLater)
{
QueuePacket(app);
}
@ -1442,7 +1445,10 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
PlayerProfile_Struct pp;
ExtendedProfile_Struct ext;
EQEmu::InventoryProfile inv;
inv.SetInventoryVersion(EQEmu::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit));
inv.SetGMInventory(false); // character cannot have gm flag at this point
time_t bday = time(nullptr);
char startzone[50]={0};
uint32 i;
@ -1465,7 +1471,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
Log(Logs::Detail, Logs::World_Server, "Beard: %d Beardcolor: %d", cc->beard, cc->beardcolor);
/* Validate the char creation struct */
if (m_ClientVersionBit & EQEmu::versions::bit_SoFAndLater) {
if (m_ClientVersionBit & EQEmu::versions::maskSoFAndLater) {
if (!CheckCharCreateInfoSoF(cc)) {
Log(Logs::Detail, Logs::World_Server,"CheckCharCreateInfo did not validate the request (bad race/class/stats)");
return false;
@ -1523,10 +1529,10 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
// strcpy(pp.servername, WorldConfig::get()->ShortName.c_str());
for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++)
for (i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
pp.spell_book[i] = 0xFFFFFFFF;
for(i = 0; i < MAX_PP_MEMSPELL; i++)
for(i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; i++)
pp.mem_spells[i] = 0xFFFFFFFF;
for(i = 0; i < BUFF_COUNT; i++)
@ -1536,7 +1542,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
pp.pvp = database.GetServerType() == 1 ? 1 : 0;
/* If it is an SoF Client and the SoF Start Zone rule is set, send new chars there */
if (m_ClientVersionBit & EQEmu::versions::bit_SoFAndLater) {
if (m_ClientVersionBit & EQEmu::versions::maskSoFAndLater) {
Log(Logs::Detail, Logs::World_Server,"Found 'SoFStartZoneID' rule setting: %i", RuleI(World, SoFStartZoneID));
if (RuleI(World, SoFStartZoneID) > 0) {
pp.zone_id = RuleI(World, SoFStartZoneID);
@ -1552,7 +1558,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
}
}
/* use normal starting zone logic to either get defaults, or if startzone was set, load that from the db table.*/
bool ValidStartZone = database.GetStartZone(&pp, cc, m_ClientVersionBit & EQEmu::versions::bit_TitaniumAndEarlier);
bool ValidStartZone = database.GetStartZone(&pp, cc, m_ClientVersionBit & EQEmu::versions::maskTitaniumAndEarlier);
if (!ValidStartZone){
return false;

View File

@ -336,18 +336,21 @@ int main(int argc, char** argv) {
std::string tmp;
if (database.GetVariable("RuleSet", tmp)) {
Log(Logs::General, Logs::World_Server, "Loading rule set '%s'", tmp.c_str());
if (!RuleManager::Instance()->LoadRules(&database, tmp.c_str())) {
if (!RuleManager::Instance()->LoadRules(&database, tmp.c_str(), false)) {
Log(Logs::General, Logs::World_Server, "Failed to load ruleset '%s', falling back to defaults.", tmp.c_str());
}
}
else {
if (!RuleManager::Instance()->LoadRules(&database, "default")) {
if (!RuleManager::Instance()->LoadRules(&database, "default", false)) {
Log(Logs::General, Logs::World_Server, "No rule set configured, using default rules");
}
else {
Log(Logs::General, Logs::World_Server, "Loaded default rule set 'default'", tmp.c_str());
}
}
EQEmu::InitializeDynamicLookups();
Log(Logs::General, Logs::World_Server, "Initialized dynamic dictionary entries");
}
if (RuleB(World, ClearTempMerchantlist)) {

View File

@ -36,7 +36,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
{
/* Set Character Creation Limit */
EQEmu::versions::ClientVersion client_version = EQEmu::versions::ConvertClientVersionBitToClientVersion(clientVersionBit);
size_t character_limit = EQEmu::constants::Lookup(client_version)->CharacterCreationLimit;
size_t character_limit = EQEmu::constants::StaticLookup(client_version)->CharacterCreationLimit;
// Validate against absolute server max
if (character_limit > EQEmu::constants::CHARACTER_CREATION_LIMIT)
@ -97,7 +97,10 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
CharacterSelectEntry_Struct *cse = (CharacterSelectEntry_Struct *)buff_ptr;
PlayerProfile_Struct pp;
EQEmu::InventoryProfile inv;
inv.SetInventoryVersion(client_version);
inv.SetGMInventory(true); // charsel can not interact with items..but, no harm in setting to full expansion support
uint32 character_id = (uint32)atoi(row[0]);
uint8 has_home = 0;
uint8 has_bind = 0;

View File

@ -814,12 +814,12 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
}
case ServerOP_ReloadRules: {
zoneserver_list.SendPacket(pack);
RuleManager::Instance()->LoadRules(&database, "default");
RuleManager::Instance()->LoadRules(&database, "default", true);
break;
}
case ServerOP_ReloadRulesWorld:
{
RuleManager::Instance()->LoadRules(&database, "default");
RuleManager::Instance()->LoadRules(&database, "default", true);
break;
}
case ServerOP_ReloadPerlExportSettings:

View File

@ -488,7 +488,7 @@ void Client::ResetAA() {
database.DeleteCharacterLeadershipAAs(CharacterID());
// undefined for these clients
if (ClientVersionBit() & EQEmu::versions::bit_TitaniumAndEarlier)
if (ClientVersionBit() & EQEmu::versions::maskTitaniumAndEarlier)
Kick();
}
@ -1221,12 +1221,12 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
// Bards can cast instant cast AAs while they are casting another song
if(spells[rank->spell].cast_time == 0 && GetClass() == BARD && IsBardSong(casting_spell_id)) {
if(!SpellFinished(rank->spell, entity_list.GetMob(target_id), EQEmu::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].ResistDiff, false)) {
if(!SpellFinished(rank->spell, entity_list.GetMob(target_id), EQEmu::spells::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].ResistDiff, false)) {
return;
}
ExpendAlternateAdvancementCharge(ability->id);
} else {
if(!CastSpell(rank->spell, target_id, EQEmu::CastingSlot::AltAbility, -1, -1, 0, -1, rank->spell_type + pTimerAAStart, cooldown, nullptr, rank->id)) {
if(!CastSpell(rank->spell, target_id, EQEmu::spells::CastingSlot::AltAbility, -1, -1, 0, -1, rank->spell_type + pTimerAAStart, cooldown, nullptr, rank->id)) {
return;
}
}
@ -1455,7 +1455,7 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
//the one titanium hack i will allow
//just to make sure we dont crash the client with newer aas
//we'll exclude any expendable ones
if(IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::bit_TitaniumAndEarlier) {
if(IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::maskTitaniumAndEarlier) {
if(ability->charges > 0) {
return false;
}

View File

@ -1526,7 +1526,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
IsValidSpell(aabonuses.SkillAttackProc[2])) {
float chance = aabonuses.SkillAttackProc[0] / 1000.0f;
if (zone->random.Roll(chance))
SpellFinished(aabonuses.SkillAttackProc[2], other, EQEmu::CastingSlot::Item, 0, -1,
SpellFinished(aabonuses.SkillAttackProc[2], other, EQEmu::spells::CastingSlot::Item, 0, -1,
spells[aabonuses.SkillAttackProc[2]].ResistDiff);
}
other->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, my_hit.skill, true, -1, false, m_specialattacks);
@ -1794,7 +1794,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, EQEmu::skills::Sk
//this generates a lot of 'updates' to the client that the client does not need
BuffFadeNonPersistDeath();
if (RuleB(Character, UnmemSpellsOnDeath)) {
if ((ClientVersionBit() & EQEmu::versions::bit_SoFAndLater) && RuleB(Character, RespawnFromHover))
if ((ClientVersionBit() & EQEmu::versions::maskSoFAndLater) && RuleB(Character, RespawnFromHover))
UnmemSpellAll(true);
else
UnmemSpellAll(false);
@ -1857,7 +1857,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, EQEmu::skills::Sk
from these and overwrite what we set in pp anyway
*/
if (LeftCorpse && (ClientVersionBit() & EQEmu::versions::bit_SoFAndLater) && RuleB(Character, RespawnFromHover))
if (LeftCorpse && (ClientVersionBit() & EQEmu::versions::maskSoFAndLater) && RuleB(Character, RespawnFromHover))
{
ClearDraggedCorpses();
RespawnFromHoverTimer.Start(RuleI(Character, RespawnFromHoverTimer) * 1000);
@ -2130,7 +2130,7 @@ void NPC::Damage(Mob* other, int32 damage, uint16 spell_id, EQEmu::skills::Skill
if (IsLDoNTrapped())
{
Message_StringID(13, LDON_ACCIDENT_SETOFF2);
SpellFinished(GetLDoNTrapSpellID(), other, EQEmu::CastingSlot::Item, 0, -1, spells[GetLDoNTrapSpellID()].ResistDiff, false);
SpellFinished(GetLDoNTrapSpellID(), other, EQEmu::spells::CastingSlot::Item, 0, -1, spells[GetLDoNTrapSpellID()].ResistDiff, false);
SetLDoNTrapSpellID(0);
SetLDoNTrapped(false);
SetLDoNTrapDetected(false);
@ -3791,7 +3791,7 @@ void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id)
if (IsBuffSpell(spell_id)) { // hots
// message to caster
if (caster->IsClient() && caster == this) {
if (caster->CastToClient()->ClientVersionBit() & EQEmu::versions::bit_SoFAndLater)
if (caster->CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoFAndLater)
FilteredMessage_StringID(caster, MT_NonMelee, FilterHealOverTime,
HOT_HEAL_SELF, itoa(acthealed), spells[spell_id].name);
else
@ -3799,7 +3799,7 @@ void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id)
YOU_HEALED, GetCleanName(), itoa(acthealed));
}
else if (caster->IsClient() && caster != this) {
if (caster->CastToClient()->ClientVersionBit() & EQEmu::versions::bit_SoFAndLater)
if (caster->CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoFAndLater)
caster->FilteredMessage_StringID(caster, MT_NonMelee, FilterHealOverTime,
HOT_HEAL_OTHER, GetCleanName(), itoa(acthealed),
spells[spell_id].name);
@ -3809,7 +3809,7 @@ void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id)
}
// message to target
if (IsClient() && caster != this) {
if (CastToClient()->ClientVersionBit() & EQEmu::versions::bit_SoFAndLater)
if (CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoFAndLater)
FilteredMessage_StringID(this, MT_NonMelee, FilterHealOverTime,
HOT_HEALED_OTHER, caster->GetCleanName(),
itoa(acthealed), spells[spell_id].name);
@ -5038,7 +5038,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
hit.damage_done = headshot;
}
else if (GetClass() == RANGER && GetLevel() > 50) { // no double dmg on headshot
if (defender->IsNPC() && !defender->IsMoving() && !defender->IsRooted()) {
if ((defender->IsNPC() && !defender->IsMoving() && !defender->IsRooted()) || !RuleB(Combat, ArcheryBonusRequiresStationary)) {
hit.damage_done *= 2;
Message_StringID(MT_CritMelee, BOW_DOUBLE_DAMAGE);
}
@ -5478,4 +5478,4 @@ int32 Mob::GetHPRegen() const
int32 Mob::GetManaRegen() const
{
return mana_regen;
}
}

View File

@ -39,6 +39,7 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm
}
m_inv.SetInventoryVersion(EQEmu::versions::MobVersion::Bot);
m_inv.SetGMInventory(false); // bot expansions are not currently implemented (defaults to static)
_guildRank = 0;
_guildId = 0;
@ -113,6 +114,7 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
auto bot_owner = GetBotOwner();
m_inv.SetInventoryVersion(EQEmu::versions::MobVersion::Bot);
m_inv.SetGMInventory(false); // bot expansions are not currently implemented (defaults to static)
_guildRank = 0;
_guildId = 0;
@ -6261,7 +6263,7 @@ void Bot::DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster) {
Mob::DoBuffTic(buff, slot, caster);
}
bool Bot::CastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot, int32 cast_time, int32 mana_cost,
bool Bot::CastSpell(uint16 spell_id, uint16 target_id, EQEmu::spells::CastingSlot slot, int32 cast_time, int32 mana_cost,
uint32* oSpellWillFinish, uint32 item_slot, int16 *resist_adjust, uint32 aa_id) {
bool Result = false;
if(zone && !zone->IsSpellBlocked(spell_id, glm::vec3(GetPosition()))) {
@ -6301,7 +6303,7 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot,
return false;
}
if(slot < EQEmu::CastingSlot::MaxGems && !CheckFizzle(spell_id)) {
if(slot < EQEmu::spells::CastingSlot::MaxGems && !CheckFizzle(spell_id)) {
int fizzle_msg = IsBardSong(spell_id) ? MISS_NOTE : SPELL_FIZZLE;
InterruptSpell(fizzle_msg, 0x121, spell_id);
@ -6315,7 +6317,7 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot,
Log(Logs::Detail, Logs::Spells, "Casting a new spell/song while singing a song. Killing old song %d.", bardsong);
bardsong = 0;
bardsong_target_id = 0;
bardsong_slot = EQEmu::CastingSlot::Gem1;
bardsong_slot = EQEmu::spells::CastingSlot::Gem1;
bardsong_timer.Disable();
}
@ -6445,7 +6447,7 @@ bool Bot::IsImmuneToSpell(uint16 spell_id, Mob *caster) {
return Result;
}
bool Bot::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction, EQEmu::CastingSlot slot) {
bool Bot::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction, EQEmu::spells::CastingSlot slot) {
bool Result = false;
SpellTargetType targetType = spells[spell_id].targettype;
if(targetType == ST_GroupClientAndPet) {
@ -6458,7 +6460,7 @@ bool Bot::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
return Result;
}
bool Bot::DoCastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, uint32 aa_id) {
bool Bot::DoCastSpell(uint16 spell_id, uint16 target_id, EQEmu::spells::CastingSlot slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, uint32 aa_id) {
bool Result = false;
if(GetClass() == BARD)
cast_time = 0;
@ -6562,7 +6564,7 @@ void Bot::GenerateSpecialAttacks() {
SetSpecialAbility(SPECATK_TRIPLE, 1);
}
bool Bot::DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQEmu::CastingSlot slot, bool& stopLogic) {
bool Bot::DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQEmu::spells::CastingSlot slot, bool& stopLogic) {
if(GetClass() == BARD) {
if(!ApplyNextBardPulse(bardsong, this, bardsong_slot))
InterruptSpell(SONG_ENDS_ABRUPTLY, 0x121, bardsong);
@ -6572,7 +6574,7 @@ bool Bot::DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQEmu::Cast
return true;
}
bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQEmu::CastingSlot slot, bool& stopLogic) {
bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQEmu::spells::CastingSlot slot, bool& stopLogic) {
if(spellTarget) {
if(IsGrouped() && (spellTarget->IsBot() || spellTarget->IsClient()) && RuleB(Bots, GroupBuffing)) {
bool noGroupSpell = false;
@ -6584,7 +6586,7 @@ bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQEmu::
bool spelltypeequal = ((spelltype == 2) || (spelltype == 16) || (spelltype == 32));
bool spelltypetargetequal = ((spelltype == 8) && (spells[thespell].targettype == ST_Self));
bool spelltypeclassequal = ((spelltype == 1024) && (GetClass() == SHAMAN));
bool slotequal = (slot == EQEmu::CastingSlot::Item);
bool slotequal = (slot == EQEmu::spells::CastingSlot::Item);
if(spellequal || slotequal) {
if((spelltypeequal || spelltypetargetequal) || spelltypeclassequal || slotequal) {
if(((spells[thespell].effectid[0] == 0) && (spells[thespell].base[0] < 0)) &&
@ -6623,7 +6625,7 @@ bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQEmu::
return true;
}
bool Bot::DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQEmu::CastingSlot slot, bool& stopLogic) {
bool Bot::DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQEmu::spells::CastingSlot slot, bool& stopLogic) {
bool isMainGroupMGB = false;
if(isMainGroupMGB && (GetClass() != BARD)) {
BotGroupSay(this, "MGB %s", spells[spell_id].name);
@ -8706,7 +8708,7 @@ bool Bot::UseDiscipline(uint32 spell_id, uint32 target) {
if(IsCasting())
InterruptSpell();
CastSpell(spell_id, target, EQEmu::CastingSlot::Discipline);
CastSpell(spell_id, target, EQEmu::spells::CastingSlot::Discipline);
return true;
}

View File

@ -322,9 +322,9 @@ public:
virtual void SetAttackTimer();
uint32 GetClassHPFactor();
virtual int32 CalcMaxHP();
bool DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQEmu::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQEmu::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQEmu::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQEmu::spells::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQEmu::spells::CastingSlot slot, bool &stopLogic);
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQEmu::spells::CastingSlot slot, bool &stopLogic);
void SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color);
void Camp(bool databaseSave = true);
virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false, bool pet_command = false);
@ -425,12 +425,12 @@ public:
virtual float GetAOERange(uint16 spell_id);
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100);
virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr);
virtual bool CastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0,
virtual bool CastSpell(uint16 spell_id, uint16 target_id, EQEmu::spells::CastingSlot slot = EQEmu::spells::CastingSlot::Item, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0,
uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr, uint32 aa_id = 0);
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar);
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction, EQEmu::CastingSlot slot);
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, uint32 aa_id = 0);
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction, EQEmu::spells::CastingSlot slot);
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, EQEmu::spells::CastingSlot slot = EQEmu::spells::CastingSlot::Item, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, uint32 aa_id = 0);
// Bot Equipment & Inventory Class Methods
void BotTradeSwapItem(Client* client, int16 lootSlot, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* inst_swap, uint32 equipableSlots, std::string* errorMessage, bool swap = true);

View File

@ -7774,7 +7774,7 @@ bool helper_cast_standard_spell(Bot* casting_bot, Mob* target_mob, int spell_id,
if (annouce_cast)
Bot::BotGroupSay(casting_bot, "Attempting to cast '%s' on %s", spells[spell_id].name, target_mob->GetCleanName());
return casting_bot->CastSpell(spell_id, target_mob->GetID(), EQEmu::CastingSlot::Gem2, -1, -1, dont_root_before);
return casting_bot->CastSpell(spell_id, target_mob->GetID(), EQEmu::spells::CastingSlot::Gem2, -1, -1, dont_root_before);
}
bool helper_command_alias_fail(Client *bot_owner, const char* command_handler, const char *alias, const char *command)

View File

@ -1899,9 +1899,9 @@ void Client::CheckManaEndUpdate() {
mana_update->cur_mana = GetMana();
mana_update->max_mana = GetMaxMana();
mana_update->spawn_id = GetID();
if ((ClientVersionBit() & EQEmu::versions::ClientVersionBit::bit_SoDAndLater) != 0)
if ((ClientVersionBit() & EQEmu::versions::ClientVersionBitmask::maskSoDAndLater) != 0)
QueuePacket(mana_packet); // do we need this with the OP_ManaChange packet above?
entity_list.QueueClientsByXTarget(this, mana_packet, false, EQEmu::versions::ClientVersionBit::bit_SoDAndLater);
entity_list.QueueClientsByXTarget(this, mana_packet, false, EQEmu::versions::ClientVersionBitmask::maskSoDAndLater);
safe_delete(mana_packet);
last_reported_mana_percent = this->GetManaPercent();
@ -1924,9 +1924,9 @@ void Client::CheckManaEndUpdate() {
endurance_update->cur_end = GetEndurance();
endurance_update->max_end = GetMaxEndurance();
endurance_update->spawn_id = GetID();
if ((ClientVersionBit() & EQEmu::versions::ClientVersionBit::bit_SoDAndLater) != 0)
if ((ClientVersionBit() & EQEmu::versions::ClientVersionBitmask::maskSoDAndLater) != 0)
QueuePacket(endurance_packet); // do we need this with the OP_ManaChange packet above?
entity_list.QueueClientsByXTarget(this, endurance_packet, false, EQEmu::versions::ClientVersionBit::bit_SoDAndLater);
entity_list.QueueClientsByXTarget(this, endurance_packet, false, EQEmu::versions::ClientVersionBitmask::maskSoDAndLater);
safe_delete(endurance_packet);
last_reported_endurance_percent = this->GetEndurancePercent();
@ -2077,6 +2077,7 @@ bool Client::ChangeFirstName(const char* in_firstname, const char* gmname)
void Client::SetGM(bool toggle) {
m_pp.gm = toggle ? 1 : 0;
m_inv.SetGMInventory((bool)m_pp.gm);
Message(13, "You are %s a GM.", m_pp.gm ? "now" : "no longer");
SendAppearancePacket(AT_GM, m_pp.gm);
Save();
@ -3054,7 +3055,7 @@ void Client::ServerFilter(SetServerFilter_Struct* filter){
Filter0(FilterMissedMe);
Filter1(FilterDamageShields);
if (ClientVersionBit() & EQEmu::versions::bit_SoDAndLater) {
if (ClientVersionBit() & EQEmu::versions::maskSoDAndLater) {
if (filter->filters[FilterDOT] == 0)
ClientFilters[FilterDOT] = FilterShow;
else if (filter->filters[FilterDOT] == 1)
@ -3075,7 +3076,7 @@ void Client::ServerFilter(SetServerFilter_Struct* filter){
Filter1(FilterFocusEffects);
Filter1(FilterPetSpells);
if (ClientVersionBit() & EQEmu::versions::bit_SoDAndLater) {
if (ClientVersionBit() & EQEmu::versions::maskSoDAndLater) {
if (filter->filters[FilterHealOverTime] == 0)
ClientFilters[FilterHealOverTime] = FilterShow;
// This is called 'Show Mine Only' in the clients, but functions the same as show
@ -4949,7 +4950,7 @@ void Client::HandleLDoNOpen(NPC *target)
if(target->GetLDoNTrapSpellID() != 0)
{
Message_StringID(13, LDON_ACCIDENT_SETOFF2);
target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff);
target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff);
target->SetLDoNTrapSpellID(0);
target->SetLDoNTrapped(false);
target->SetLDoNTrapDetected(false);
@ -5071,7 +5072,7 @@ void Client::HandleLDoNDisarm(NPC *target, uint16 skill, uint8 type)
break;
case -1:
Message_StringID(13, LDON_ACCIDENT_SETOFF2);
target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff);
target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff);
target->SetLDoNTrapSpellID(0);
target->SetLDoNTrapped(false);
target->SetLDoNTrapDetected(false);
@ -5090,7 +5091,7 @@ void Client::HandleLDoNPickLock(NPC *target, uint16 skill, uint8 type)
if(target->IsLDoNTrapped())
{
Message_StringID(13, LDON_ACCIDENT_SETOFF2);
target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff);
target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff);
target->SetLDoNTrapSpellID(0);
target->SetLDoNTrapped(false);
target->SetLDoNTrapDetected(false);
@ -5622,7 +5623,7 @@ void Client::SuspendMinion()
memset(&m_suspendedminion, 0, sizeof(struct PetInfo));
// TODO: These pet command states need to be synced ...
// Will just fix them for now
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater) {
if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) {
SetPetCommandState(PET_BUTTON_SIT, 0);
SetPetCommandState(PET_BUTTON_STOP, 0);
SetPetCommandState(PET_BUTTON_REGROUP, 0);
@ -7631,7 +7632,7 @@ void Client::SendClearMercInfo()
void Client::DuplicateLoreMessage(uint32 ItemID)
{
if (!(m_ClientVersionBit & EQEmu::versions::bit_RoFAndLater))
if (!(m_ClientVersionBit & EQEmu::versions::maskRoFAndLater))
{
Message_StringID(0, PICK_LORE);
return;
@ -9074,3 +9075,55 @@ void Client::SetSecondaryWeaponOrnamentation(uint32 model_id)
Message(15, "Your secondary weapon appearance has been modified");
}
}
/**
* Used in #goto <player_name>
*
* @param player_name
*/
bool Client::GotoPlayer(std::string player_name)
{
std::string query = StringFormat(
"SELECT"
" character_data.zone_id,"
" character_data.zone_instance,"
" character_data.x,"
" character_data.y,"
" character_data.z,"
" character_data.heading "
"FROM"
" character_data "
"WHERE"
" TRUE"
" AND character_data.name = '%s'"
" AND character_data.last_login > (UNIX_TIMESTAMP() - 600) LIMIT 1", player_name.c_str());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return false;
}
for (auto row = results.begin(); row != results.end(); ++row) {
auto zone_id = static_cast<uint32>(atoi(row[0]));
auto instance_id = static_cast<uint16>(atoi(row[1]));
auto x = static_cast<float>(atof(row[2]));
auto y = static_cast<float>(atof(row[3]));
auto z = static_cast<float>(atof(row[4]));
auto heading = static_cast<float>(atof(row[5]));
if (instance_id > 0 && !database.CheckInstanceExists(instance_id)) {
this->Message(15, "Instance no longer exists...");
return false;
}
if (instance_id > 0) {
database.AddClientToInstance(instance_id, this->CharacterID());
}
this->MovePC(zone_id, instance_id, x, y, z, heading);
return true;
}
return false;
}

View File

@ -255,6 +255,8 @@ public:
void SetPrimaryWeaponOrnamentation(uint32 model_id);
void SetSecondaryWeaponOrnamentation(uint32 model_id);
bool GotoPlayer(std::string player_name);
//abstract virtual function implementations required by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill);
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None);
@ -557,10 +559,10 @@ public:
virtual int GetCurrentBuffSlots() const;
virtual int GetCurrentSongSlots() const;
virtual int GetCurrentDiscSlots() const { return 1; }
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 int GetMaxBuffSlots() const { return EQEmu::spells::LONG_BUFFS; }
virtual int GetMaxSongSlots() const { return EQEmu::spells::SHORT_BUFFS; }
virtual int GetMaxDiscSlots() const { return EQEmu::spells::DISC_BUFFS; }
virtual int GetMaxTotalSlots() const { return EQEmu::spells::TOTAL_BUFFS; }
virtual uint32 GetFirstBuffSlot(bool disc, bool song);
virtual uint32 GetLastBuffSlot(bool disc, bool song);
virtual void InitializeBuffSlots();
@ -1160,7 +1162,7 @@ public:
void HandleLFGuildResponse(ServerPacket *pack);
void SendLFGuildStatus();
void SendGuildLFGuildStatus();
inline bool XTargettingAvailable() const { return ((m_ClientVersionBit & EQEmu::versions::bit_UFAndLater) && RuleB(Character, EnableXTargetting)); }
inline bool XTargettingAvailable() const { return ((m_ClientVersionBit & EQEmu::versions::maskUFAndLater) && RuleB(Character, EnableXTargetting)); }
inline uint8 GetMaxXTargets() const { return MaxXTargets; }
void SetMaxXTargets(uint8 NewMax);
bool IsXTarget(const Mob *m) const;
@ -1184,7 +1186,7 @@ public:
bool GroupFollow(Client* inviter);
inline bool GetRunMode() const { return runmode; }
inline bool AggroMeterAvailable() const { return ((m_ClientVersionBit & EQEmu::versions::bit_RoF2AndLater)) && RuleB(Character, EnableAggroMeter); } // RoF untested
inline bool AggroMeterAvailable() const { return ((m_ClientVersionBit & EQEmu::versions::maskRoF2AndLater)) && RuleB(Character, EnableAggroMeter); } // RoF untested
inline void SetAggroMeterLock(int in) { m_aggrometer.set_lock_id(in); }
void ProcessAggroMeter(); // builds packet and sends

View File

@ -838,7 +838,7 @@ 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 (EQEmu::behavior::Lookup(EQEmu::versions::ConvertClientVersionToMobVersion(ClientVersion()))->CoinHasWeight) {
if (EQEmu::behavior::StaticLookup(EQEmu::versions::ConvertClientVersionToMobVersion(ClientVersion()))->CoinHasWeight) {
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;

View File

@ -530,7 +530,7 @@ void Client::CompleteConnect()
SendAppearancePacket(AT_GuildID, GuildID(), false);
SendAppearancePacket(AT_GuildRank, rank, false);
}
for (uint32 spellInt = 0; spellInt < MAX_PP_REF_SPELLBOOK; spellInt++) {
for (uint32 spellInt = 0; spellInt < EQEmu::spells::SPELLBOOK_SIZE; spellInt++) {
if (m_pp.spell_book[spellInt] < 3 || m_pp.spell_book[spellInt] > 50000)
m_pp.spell_book[spellInt] = 0xFFFFFFFF;
}
@ -809,6 +809,16 @@ void Client::CompleteConnect()
std::string event_desc = StringFormat("Connect :: Logged into zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID());
QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc);
}
/**
* Update last login since this doesn't get updated until a late save later so we can update online status
*/
database.QueryDatabase(
StringFormat(
"UPDATE `character_data` SET `last_login` = UNIX_TIMESTAMP() WHERE id = %u",
this->CharacterID()
)
);
}
if (zone) {
@ -868,14 +878,14 @@ void Client::CompleteConnect()
worldserver.SendPacket(pack);
delete pack;
if (IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::bit_UFAndLater) {
if (IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::maskUFAndLater) {
EQApplicationPacket *outapp = MakeBuffsPacket(false);
CastToClient()->FastQueuePacket(&outapp);
}
// TODO: load these states
// We at least will set them to the correct state for now
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater && GetPet()) {
if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater && GetPet()) {
SetPetCommandState(PET_BUTTON_SIT, 0);
SetPetCommandState(PET_BUTTON_STOP, 0);
SetPetCommandState(PET_BUTTON_REGROUP, 0);
@ -1144,8 +1154,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
SetClientVersion(Connection()->ClientVersion());
m_ClientVersionBit = EQEmu::versions::ConvertClientVersionToClientVersionBit(Connection()->ClientVersion());
bool siv = m_inv.SetInventoryVersion(m_ClientVersion);
Log(Logs::General, Logs::None, "%s inventory version to %s(%i)", (siv ? "Succeeded in setting" : "Failed to set"), ClientVersionName(m_ClientVersion), m_ClientVersion);
m_inv.SetInventoryVersion(m_ClientVersion);
/* Antighost code
tmp var is so the search doesnt find this object
@ -1185,7 +1194,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
uint32 cid = CharacterID();
character_id = cid; /* Global character_id reference */
/* Flush and reload factions */
/* Flush and reload factions */
database.RemoveTempFactions(this);
database.LoadCharacterFactionValues(cid, factionvalues);
@ -1222,6 +1231,9 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
m_pp.platinum_shared = database.GetSharedPlatinum(this->AccountID());
database.ClearOldRecastTimestamps(cid); /* Clear out our old recast timestamps to keep the DB clean */
// set to full support in case they're a gm with items in disabled expansion slots..but, have their gm flag off...
// item loss will occur when they use the 'empty' slots, if this is not done
m_inv.SetGMInventory(true);
loaditems = database.GetInventory(cid, &m_inv); /* Load Character Inventory */
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */
@ -1238,7 +1250,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
database.LoadCharacterLeadershipAA(cid, &m_pp); /* Load Character Leadership AA's */
database.LoadCharacterTribute(cid, &m_pp); /* Load CharacterTribute */
/* Load AdventureStats */
/* Load AdventureStats */
AdventureStats_Struct as;
if (database.GetAdventureStats(cid, &as))
{
@ -1397,8 +1409,9 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
if (m_pp.ldon_points_tak < 0 || m_pp.ldon_points_tak > 2000000000) { m_pp.ldon_points_tak = 0; }
if (m_pp.ldon_points_available < 0 || m_pp.ldon_points_available > 2000000000) { m_pp.ldon_points_available = 0; }
// need to rework .. not until full scope of change is accounted for, though
if (RuleB(World, UseClientBasedExpansionSettings)) {
m_pp.expansions = EQEmu::versions::ConvertClientVersionToExpansion(ClientVersion());
m_pp.expansions = EQEmu::expansions::ConvertClientVersionToExpansionMask(ClientVersion());
}
else {
m_pp.expansions = RuleI(World, ExpansionSettings);
@ -1409,7 +1422,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
}
if (SPDAT_RECORDS > 0) {
for (uint32 z = 0; z<MAX_PP_MEMSPELL; z++) {
for (uint32 z = 0; z < EQEmu::spells::SPELL_GEM_COUNT; z++) {
if (m_pp.mem_spells[z] >= (uint32)SPDAT_RECORDS)
UnmemSpell(z, false);
}
@ -1516,6 +1529,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
Bot::LoadAndSpawnAllZonedBots(this);
#endif
m_inv.SetGMInventory((bool)m_pp.gm); // set to current gm state for calc
CalcBonuses();
if (RuleB(Zone, EnableLoggedOffReplenishments) &&
time(nullptr) - m_pp.lastlogin >= RuleI(Zone, MinOfflineTimeToReplenishments)) {
@ -1540,7 +1554,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
}
/* Load Spell Slot Refresh from Currently Memoried Spells */
for (unsigned int i = 0; i < MAX_PP_MEMSPELL; ++i)
for (unsigned int i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; ++i)
if (IsValidSpell(m_pp.mem_spells[i]))
m_pp.spellSlotRefresh[i] = p_timers.GetRemainingTime(pTimerSpellStart + m_pp.mem_spells[i]) * 1000;
@ -1639,6 +1653,9 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
this is not quite where live sends inventory, they do it after tribute
*/
if (loaditems) { /* Dont load if a length error occurs */
if (admin >= minStatusToBeGM)
m_inv.SetGMInventory(true); // set to true to allow expansion-restricted packets through
BulkSendInventoryItems();
/* Send stuff on the cursor which isnt sent in bulk */
for (auto iter = m_inv.cursor_cbegin(); iter != m_inv.cursor_cend(); ++iter) {
@ -1648,6 +1665,9 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
const EQEmu::ItemInstance *inst = *iter;
SendItemPacket(EQEmu::invslot::slotCursor, inst, ItemPacketLimbo);
}
// this is kinda hackish atm..this process needs to be realigned to allow a contiguous flow
m_inv.SetGMInventory((bool)m_pp.gm); // reset back to current gm state
}
/* Task Packets */
@ -1663,7 +1683,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
}
}
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater) {
if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) {
outapp = new EQApplicationPacket(OP_XTargetResponse, 8);
outapp->WriteUInt32(GetMaxXTargets());
outapp->WriteUInt32(0);
@ -3996,7 +4016,7 @@ void Client::Handle_OP_CancelTrade(const EQApplicationPacket *app)
void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
{
using EQEmu::CastingSlot;
using EQEmu::spells::CastingSlot;
if (app->size != sizeof(CastSpell_Struct)) {
std::cout << "Wrong size: OP_CastSpell, size=" << app->size << ", expected " << sizeof(CastSpell_Struct) << std::endl;
return;
@ -4017,14 +4037,14 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
/* Memorized Spell */
if (m_pp.mem_spells[castspell->slot] && m_pp.mem_spells[castspell->slot] == castspell->spell_id) {
uint16 spell_to_cast = 0;
if (castspell->slot < MAX_PP_MEMSPELL) {
if (castspell->slot < EQEmu::spells::SPELL_GEM_COUNT) {
spell_to_cast = m_pp.mem_spells[castspell->slot];
if (spell_to_cast != castspell->spell_id) {
InterruptSpell(castspell->spell_id); //CHEATER!!!
return;
}
}
else if (castspell->slot >= MAX_PP_MEMSPELL) {
else if (castspell->slot >= EQEmu::spells::SPELL_GEM_COUNT) {
InterruptSpell();
return;
}
@ -5243,7 +5263,7 @@ void Client::Handle_OP_DeleteSpell(const EQApplicationPacket *app)
EQApplicationPacket* outapp = app->Copy();
DeleteSpell_Struct* dss = (DeleteSpell_Struct*)outapp->pBuffer;
if (dss->spell_slot < 0 || dss->spell_slot > int(MAX_PP_SPELLBOOK))
if (dss->spell_slot < 0 || dss->spell_slot > int(EQEmu::spells::SPELLBOOK_SIZE))
return;
if (m_pp.spell_book[dss->spell_slot] != SPELLBOOK_UNKNOWN) {
@ -8441,7 +8461,7 @@ void Client::Handle_OP_ItemPreview(const EQApplicationPacket *app)
void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
{
using EQEmu::CastingSlot;
using EQEmu::spells::CastingSlot;
if (app->size != sizeof(ItemVerifyRequest_Struct))
{
Log(Logs::General, Logs::Error, "OP size error: OP_ItemVerifyRequest expected:%i got:%i", sizeof(ItemVerifyRequest_Struct), app->size);
@ -9167,7 +9187,7 @@ void Client::Handle_OP_LoadSpellSet(const EQApplicationPacket *app)
}
int i;
LoadSpellSet_Struct* ss = (LoadSpellSet_Struct*)app->pBuffer;
for (i = 0; i<MAX_PP_MEMSPELL; i++) {
for (i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; i++) {
if (ss->spell[i] != 0xFFFFFFFF)
UnmemSpell(i, true);
}
@ -10168,16 +10188,16 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
if (mypet->IsHeld())
{
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_HOLD_SET_OFF);
mypet->SetHeld(false);
}
else
{
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_HOLD_SET_ON);
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater)
mypet->SayTo_StringID(this, MT_PetResponse, PET_NOW_HOLDING);
else
mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_HOLD);
@ -10191,10 +10211,10 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
}
case PET_HOLD_ON: {
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && !mypet->IsHeld()) {
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_HOLD_SET_ON);
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater)
mypet->SayTo_StringID(this, MT_PetResponse, PET_NOW_HOLDING);
else
mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_HOLD);
@ -10206,7 +10226,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
}
case PET_HOLD_OFF: {
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && mypet->IsHeld()) {
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_HOLD_SET_OFF);
mypet->SetHeld(false);
}
@ -10216,13 +10236,13 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
if (mypet->IsGHeld())
{
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater)
Message_StringID(MT_PetResponse, PET_OFF_GHOLD);
mypet->SetGHeld(false);
}
else
{
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater) {
if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) {
Message_StringID(MT_PetResponse, PET_ON_GHOLD);
mypet->SayTo_StringID(this, MT_PetResponse, PET_GHOLD_ON_MSG);
} else {
@ -10237,7 +10257,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
}
case PET_GHOLD_ON: {
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater) {
if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) {
Message_StringID(MT_PetResponse, PET_ON_GHOLD);
mypet->SayTo_StringID(this, MT_PetResponse, PET_GHOLD_ON_MSG);
} else {
@ -10251,7 +10271,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
}
case PET_GHOLD_OFF: {
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && mypet->IsGHeld()) {
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater)
Message_StringID(MT_PetResponse, PET_OFF_GHOLD);
mypet->SetGHeld(false);
}
@ -10263,13 +10283,13 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
break;
if (mypet->IsNoCast()) {
Message_StringID(MT_PetResponse, PET_CASTING);
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_OFF);
mypet->SetNoCast(false);
}
else {
Message_StringID(MT_PetResponse, PET_NOT_CASTING);
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_ON);
mypet->SetNoCast(true);
}
@ -10282,7 +10302,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
break;
if (!mypet->IsNoCast()) {
Message_StringID(MT_PetResponse, PET_NOT_CASTING);
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_ON);
mypet->SetNoCast(true);
}
@ -10295,7 +10315,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
break;
if (mypet->IsNoCast()) {
Message_StringID(MT_PetResponse, PET_CASTING);
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_OFF);
mypet->SetNoCast(false);
}
@ -10308,13 +10328,13 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
break;
if (mypet->IsFocused()) {
Message_StringID(MT_PetResponse, PET_NOT_FOCUSING);
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_FOCUS_SET_OFF);
mypet->SetFocused(false);
}
else {
Message_StringID(MT_PetResponse, PET_NOW_FOCUSING);
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_FOCUS_SET_ON);
mypet->SetFocused(true);
}
@ -10327,7 +10347,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
break;
if (!mypet->IsFocused()) {
Message_StringID(MT_PetResponse, PET_NOW_FOCUSING);
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_FOCUS_SET_ON);
mypet->SetFocused(true);
}
@ -10340,7 +10360,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
break;
if (mypet->IsFocused()) {
Message_StringID(MT_PetResponse, PET_NOT_FOCUSING);
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater)
Message_StringID(MT_PetResponse, PET_FOCUS_SET_OFF);
mypet->SetFocused(false);
}
@ -13317,7 +13337,7 @@ void Client::Handle_OP_SwapSpell(const EQApplicationPacket *app)
const SwapSpell_Struct* swapspell = (const SwapSpell_Struct*)app->pBuffer;
int swapspelltemp;
if (swapspell->from_slot < 0 || swapspell->from_slot > MAX_PP_SPELLBOOK || swapspell->to_slot < 0 || swapspell->to_slot > MAX_PP_SPELLBOOK)
if (swapspell->from_slot < 0 || swapspell->from_slot > EQEmu::spells::SPELLBOOK_SIZE || swapspell->to_slot < 0 || swapspell->to_slot > EQEmu::spells::SPELLBOOK_SIZE)
return;
swapspelltemp = m_pp.spell_book[swapspell->from_slot];

View File

@ -812,7 +812,7 @@ void Client::BulkSendInventoryItems()
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
const EQEmu::ItemData* handyitem = nullptr;
uint32 numItemSlots = 80; //The max number of items passed in the transaction.
if (m_ClientVersionBit & EQEmu::versions::bit_RoFAndLater) { // RoF+ can send 200 items
if (m_ClientVersionBit & EQEmu::versions::maskRoFAndLater) { // RoF+ can send 200 items
numItemSlots = 200;
}
const EQEmu::ItemData *item = nullptr;
@ -1132,7 +1132,7 @@ void Client::CancelSneakHide()
// The later clients send back a OP_Hide (this has a size but data is 0)
// as well as OP_SpawnAppearance with AT_Invis and one with AT_Sneak
// So we don't have to handle any of those flags
if (ClientVersionBit() & EQEmu::versions::bit_SoFAndEarlier)
if (ClientVersionBit() & EQEmu::versions::maskSoFAndEarlier)
sneaking = false;
}
}
@ -2129,7 +2129,7 @@ void Client::ClearHover()
entity_list.QueueClients(this, outapp, false);
safe_delete(outapp);
if (IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::bit_UFAndLater)
if (IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::maskUFAndLater)
{
EQApplicationPacket *outapp = MakeBuffsPacket(false);
CastToClient()->FastQueuePacket(&outapp);

View File

@ -219,6 +219,7 @@ int command_init(void)
command_add("globalview", "Lists all qglobals in cache if you were to do a quest with this target.", 80, command_globalview) ||
command_add("gm", "- Turn player target's or your GM flag on or off", 80, command_gm) ||
command_add("gmspeed", "[on/off] - Turn GM speed hack on/off for you or your player target", 100, command_gmspeed) ||
command_add("gmzone", "[zone_short_name] [zone_version=0] [identifier=gmzone] - Zones to a private GM instance", 100, command_gmzone) ||
command_add("goto", "[x] [y] [z] - Teleport to the provided coordinates or to your target", 10, command_goto) ||
command_add("grid", "[add/delete] [grid_num] [wandertype] [pausetype] - Create/delete a wandering grid", 170, command_grid) ||
command_add("guild", "- Guild manipulation commands. Use argument help for more info.", 10, command_guild) ||
@ -413,6 +414,7 @@ int command_init(void)
command_add("viewpetition", "[petition number] - View a petition", 20, command_viewpetition) ||
command_add("wc", "[wear slot] [material] - Sends an OP_WearChange for your target", 200, command_wc) ||
command_add("weather", "[0/1/2/3] (Off/Rain/Snow/Manual) - Change the weather", 80, command_weather) ||
command_add("who", "[search]", 20, command_who) ||
command_add("worldshutdown", "- Shut down world and all zones", 200, command_worldshutdown) ||
command_add("wp", "[add/delete] [grid_num] [pause] [wp_num] [-h] - Add/delete a waypoint to/from a wandering grid", 170, command_wp) ||
command_add("wpadd", "[pause] [-h] - Add your current location as a waypoint to your NPC target's AI path", 170, command_wpadd) ||
@ -2262,10 +2264,12 @@ void command_sendzonespawns(Client *c, const Seperator *sep)
void command_zsave(Client *c, const Seperator *sep)
{
if(zone->SaveZoneCFG())
if (zone->SaveZoneCFG()) {
c->Message(13, "Zone header saved successfully.");
else
}
else {
c->Message(13, "ERROR: Zone header data was NOT saved.");
}
}
void command_dbspawn2(Client *c, const Seperator *sep)
@ -2609,14 +2613,14 @@ void command_castspell(Client *c, const Seperator *sep)
else
if (c->GetTarget() == 0)
if(c->Admin() >= commandInstacast)
c->SpellFinished(spellid, 0, EQEmu::CastingSlot::Item, 0, -1, spells[spellid].ResistDiff);
c->SpellFinished(spellid, 0, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spellid].ResistDiff);
else
c->CastSpell(spellid, 0, EQEmu::CastingSlot::Item, 0);
c->CastSpell(spellid, 0, EQEmu::spells::CastingSlot::Item, 0);
else
if(c->Admin() >= commandInstacast)
c->SpellFinished(spellid, c->GetTarget(), EQEmu::CastingSlot::Item, 0, -1, spells[spellid].ResistDiff);
c->SpellFinished(spellid, c->GetTarget(), EQEmu::spells::CastingSlot::Item, 0, -1, spells[spellid].ResistDiff);
else
c->CastSpell(spellid, c->GetTarget()->GetID(), EQEmu::CastingSlot::Item, 0);
c->CastSpell(spellid, c->GetTarget()->GetID(), EQEmu::spells::CastingSlot::Item, 0);
}
}
@ -4426,18 +4430,94 @@ void command_fixmob(Client *c, const Seperator *sep)
void command_gmspeed(Client *c, const Seperator *sep)
{
bool state=atobool(sep->arg[1]);
Client *t=c;
bool state = atobool(sep->arg[1]);
Client *t = c;
if(c->GetTarget() && c->GetTarget()->IsClient())
t=c->GetTarget()->CastToClient();
if(sep->arg[1][0] != 0) {
database.SetGMSpeed(t->AccountID(), state?1:0);
c->Message(0, "Turning GMSpeed %s for %s (zone to take effect)", state?"On":"Off", t->GetName());
if (c->GetTarget() && c->GetTarget()->IsClient()) {
t = c->GetTarget()->CastToClient();
}
else
if (sep->arg[1][0] != 0) {
database.SetGMSpeed(t->AccountID(), state ? 1 : 0);
c->Message(0, "Turning GMSpeed %s for %s (zone to take effect)", state ? "On" : "Off", t->GetName());
}
else {
c->Message(0, "Usage: #gmspeed [on/off]");
}
}
void command_gmzone(Client *c, const Seperator *sep)
{
if (!sep->arg[1]) {
c->Message(0, "Usage");
c->Message(0, "-------");
c->Message(0, "#gmzone [zone_short_name] [zone_version=0]");
return;
}
std::string zone_short_name_string = sep->arg[1];
const char *zone_short_name = sep->arg[1];
auto zone_version = static_cast<uint32>(sep->arg[2] ? atoi(sep->arg[2]) : 0);
std::string identifier = "gmzone";
uint32 zone_id = database.GetZoneID(zone_short_name);
uint32 duration = 100000000;
uint16 instance_id = 0;
if (zone_id == 0) {
c->Message(13, "Invalid zone specified");
return;
}
if (sep->arg[3] && sep->arg[3][0]) {
identifier = sep->arg[3];
}
std::string bucket_key = StringFormat("%s-%s-instance", zone_short_name, identifier.c_str());
std::string existing_zone_instance = DataBucket::GetData(bucket_key);
if (existing_zone_instance.length() > 0) {
instance_id = std::stoi(existing_zone_instance);
c->Message(15, "Found already created instance (%s) (%u)", zone_short_name, instance_id);
}
if (instance_id == 0) {
if (!database.GetUnusedInstanceID(instance_id)) {
c->Message(13, "Server was unable to find a free instance id.");
return;
}
if (!database.CreateInstance(instance_id, zone_id, zone_version, duration)) {
c->Message(13, "Server was unable to create a new instance.");
return;
}
c->Message(15, "New private GM instance %s was created with id %lu.", zone_short_name, (unsigned long) instance_id);
DataBucket::SetData(bucket_key, std::to_string(instance_id));
}
if (instance_id > 0) {
float target_x = -1, target_y = -1, target_z = -1;
int16 min_status = 0;
uint8 min_level = 0;
if (!database.GetSafePoints(
zone_short_name,
zone_version,
&target_x,
&target_y,
&target_z,
&min_status,
&min_level
)) {
c->Message(13, "Failed to find safe coordinates for specified zone");
}
c->Message(15, "Zoning to private GM instance (%s) (%u)", zone_short_name, instance_id);
c->AssignToInstance(instance_id);
c->MovePC(zone_id, instance_id, target_x, target_y, target_z, 0, 1);
}
}
void command_title(Client *c, const Seperator *sep)
@ -4620,7 +4700,7 @@ void command_memspell(Client *c, const Seperator *sep)
{
slot = atoi(sep->arg[1]) - 1;
spell_id = atoi(sep->arg[2]);
if (slot > MAX_PP_MEMSPELL || spell_id >= SPDAT_RECORDS)
if (slot > EQEmu::spells::SPELL_GEM_COUNT || spell_id >= SPDAT_RECORDS)
{
c->Message(0, "Error: #MemSpell: Arguement out of range");
}
@ -5015,7 +5095,9 @@ void command_proximity(Client *c, const Seperator *sep)
points.push_back(p);
}
c->SendPathPacket(points);
if (c->ClientVersion() >= EQEmu::versions::ClientVersion::RoF) {
c->SendPathPacket(points);
}
}
void command_pvp(Client *c, const Seperator *sep)
@ -5178,7 +5260,15 @@ void command_killallnpcs(Client *c, const Seperator *sep)
continue;
}
if (entity->IsInvisible() || !entity->IsAttackAllowed(c)) {
bool is_not_attackable =
(
entity->IsInvisible() ||
!entity->IsAttackAllowed(c) ||
entity->GetRace() == 127 ||
entity->GetRace() == 240
);
if (is_not_attackable) {
continue;
}
@ -5347,13 +5437,65 @@ void command_loc(Client *c, const Seperator *sep)
void command_goto(Client *c, const Seperator *sep)
{
// goto function
if (sep->arg[1][0] == '\0' && c->GetTarget())
c->MovePC(zone->GetZoneID(), zone->GetInstanceID(), c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ(), c->GetTarget()->GetHeading());
else if (!(sep->IsNumber(1) && sep->IsNumber(2) && sep->IsNumber(3)))
/**
* Goto via target and no args
*/
if (sep->arg[1][0] == '\0' && c->GetTarget()) {
c->MovePC(
zone->GetZoneID(),
zone->GetInstanceID(),
c->GetTarget()->GetX(),
c->GetTarget()->GetY(),
c->GetTarget()->GetZ(),
c->GetTarget()->GetHeading());
}
/**
* Goto via player name
*/
else if (!sep->IsNumber(1) && sep->arg[1]) {
/**
* Find them in zone first
*/
const char *player_name = sep->arg[1];
std::string player_name_string = sep->arg[1];
Client *client = entity_list.GetClientByName(player_name);
if (client) {
c->MovePC(
zone->GetZoneID(),
zone->GetInstanceID(),
client->GetX(),
client->GetY(),
client->GetZ(),
client->GetHeading());
c->Message(15, "Goto player '%s' same zone", player_name_string.c_str());
}
else if (c->GotoPlayer(player_name_string)) {
c->Message(15, "Goto player '%s' different zone", player_name_string.c_str());
}
else {
c->Message(15, "Player '%s' not found", player_name_string.c_str());
}
}
/**
* Goto via x y z
*/
else if (sep->IsNumber(1) && sep->IsNumber(2) && sep->IsNumber(3)) {
c->MovePC(
zone->GetZoneID(),
zone->GetInstanceID(),
atof(sep->arg[1]),
atof(sep->arg[2]),
atof(sep->arg[3]),
c->GetHeading());
}
else {
c->Message(0, "Usage: #goto [x y z]");
else
c->MovePC(zone->GetZoneID(), zone->GetInstanceID(), atof(sep->arg[1]), atof(sep->arg[2]), atof(sep->arg[3]), c->GetHeading());
c->Message(0, "Usage: #goto [player_name]");
}
}
void command_iteminfo(Client *c, const Seperator *sep)
@ -6299,7 +6441,7 @@ void command_scribespells(Client *c, const Seperator *sep)
c->Message(0, "Scribing spells for %s.", t->GetName());
Log(Logs::General, Logs::Normal, "Scribe spells request for %s from %s, levels: %u -> %u", t->GetName(), c->GetName(), min_level, max_level);
for(curspell = 0, book_slot = t->GetNextAvailableSpellBookSlot(), count = 0; curspell < SPDAT_RECORDS && book_slot < MAX_PP_SPELLBOOK; curspell++, book_slot = t->GetNextAvailableSpellBookSlot(book_slot))
for(curspell = 0, book_slot = t->GetNextAvailableSpellBookSlot(), count = 0; curspell < SPDAT_RECORDS && book_slot < EQEmu::spells::SPELLBOOK_SIZE; curspell++, book_slot = t->GetNextAvailableSpellBookSlot(book_slot))
{
if
(
@ -8343,7 +8485,7 @@ void command_rules(Client *c, const Seperator *sep) {
c->Message(0, "(%d) %s", cur->first, cur->second.c_str());
}
} else if(!strcasecmp(sep->arg[1], "reload")) {
RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset());
RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset(), true);
c->Message(0, "The active ruleset (%s (%d)) has been reloaded", RuleManager::Instance()->GetActiveRuleset(),
RuleManager::Instance()->GetActiveRulesetID());
} else if(!strcasecmp(sep->arg[1], "switch")) {
@ -8359,7 +8501,7 @@ void command_rules(Client *c, const Seperator *sep) {
}
//TODO: we likely want to reload this ruleset everywhere...
RuleManager::Instance()->LoadRules(&database, sep->arg[2]);
RuleManager::Instance()->LoadRules(&database, sep->arg[2], true);
c->Message(0, "The selected ruleset has been changed to (%s (%d)) and reloaded locally", sep->arg[2], rsid);
} else if(!strcasecmp(sep->arg[1], "load")) {
@ -8369,7 +8511,7 @@ void command_rules(Client *c, const Seperator *sep) {
c->Message(13, "Unknown rule set '%s'", sep->arg[2]);
return;
}
RuleManager::Instance()->LoadRules(&database, sep->arg[2]);
RuleManager::Instance()->LoadRules(&database, sep->arg[2], true);
c->Message(0, "Loaded ruleset '%s' (%d) locally", sep->arg[2], rsid);
} else if(!strcasecmp(sep->arg[1], "store")) {
if(sep->argnum == 1) {
@ -8393,9 +8535,9 @@ void command_rules(Client *c, const Seperator *sep) {
return;
}
} else if(!strcasecmp(sep->arg[1], "reset")) {
RuleManager::Instance()->ResetRules();
RuleManager::Instance()->ResetRules(true);
c->Message(0, "The running ruleset has been set to defaults");
} else if(!strcasecmp(sep->arg[1], "get")) {
if(sep->argnum != 2) {
c->Message(13, "Invalid argument count, see help.");
@ -8412,7 +8554,7 @@ void command_rules(Client *c, const Seperator *sep) {
c->Message(13, "Invalid argument count, see help.");
return;
}
if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3])) {
if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3], nullptr, false, true)) {
c->Message(13, "Failed to modify rule");
} else {
c->Message(0, "Rule modified locally.");
@ -8422,7 +8564,7 @@ void command_rules(Client *c, const Seperator *sep) {
c->Message(13, "Invalid argument count, see help.");
return;
}
if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3], &database, true)) {
if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3], &database, true, true)) {
c->Message(13, "Failed to modify rule");
} else {
c->Message(0, "Rule modified locally and in the database.");
@ -11783,6 +11925,126 @@ void command_scale(Client *c, const Seperator *sep)
}
}
void command_who(Client *c, const Seperator *sep)
{
std::string query =
"SELECT\n"
" character_data.account_id,\n"
" character_data.name,\n"
" character_data.zone_id,\n"
" COALESCE((select zone.short_name from zone where zoneidnumber = character_data.zone_id LIMIT 1), \"Not Found\") as zone_name,\n"
" character_data.zone_instance,\n"
" COALESCE((select guilds.name from guilds where id = ((select guild_id from guild_members where char_id = character_data.id))), \"\") as guild_name,\n"
" character_data.level,\n"
" character_data.race,\n"
" character_data.class,\n"
" COALESCE((select account.status from account where account.id = character_data.account_id LIMIT 1), 0) as account_status,\n"
" COALESCE((select account.name from account where account.id = character_data.account_id LIMIT 1), \"\") as account_name,\n"
" COALESCE((select account_ip.ip from account_ip where account_ip.accid = character_data.account_id ORDER BY account_ip.lastused DESC LIMIT 1), \"\") as account_ip\n"
"FROM\n"
" character_data\n"
"WHERE\n"
" last_login > (UNIX_TIMESTAMP() - 600)\n"
"ORDER BY character_data.name;";
auto results = database.QueryDatabase(query);
if (!results.Success())
return;
if (results.RowCount() == 0) {
c->Message(15, "No results found");
return;
}
std::string search_string;
if (sep->arg[1]) {
search_string = str_tolower(sep->arg[1]);
}
int found_count = 0;
c->Message(5, "Players in EverQuest");
c->Message(5, "--------------------");
for (auto row = results.begin(); row != results.end(); ++row) {
auto account_id = static_cast<uint32>(atoi(row[0]));
std::string player_name = row[1];
auto zone_id = static_cast<uint32>(atoi(row[2]));
std::string zone_short_name = row[3];
auto zone_instance = static_cast<uint32>(atoi(row[4]));
std::string guild_name = row[5];
auto player_level = static_cast<uint32>(atoi(row[6]));
auto player_race = static_cast<uint32>(atoi(row[7]));
auto player_class = static_cast<uint32>(atoi(row[8]));
auto account_status = static_cast<uint32>(atoi(row[9]));
std::string account_name = row[10];
std::string account_ip = row[11];
std::string base_class_name = GetClassIDName(static_cast<uint8>(player_class), 1);
std::string displayed_race_name = GetRaceIDName(static_cast<uint16>(player_race));
if (search_string.length() > 0) {
bool found_search_term =
(
str_tolower(player_name).find(search_string) != std::string::npos ||
str_tolower(zone_short_name).find(search_string) != std::string::npos ||
str_tolower(displayed_race_name).find(search_string) != std::string::npos ||
str_tolower(base_class_name).find(search_string) != std::string::npos ||
str_tolower(guild_name).find(search_string) != std::string::npos ||
str_tolower(account_name).find(search_string) != std::string::npos ||
str_tolower(account_ip).find(search_string) != std::string::npos
);
if (!found_search_term) {
continue;
}
}
std::string displayed_guild_name;
if (guild_name.length() > 0) {
displayed_guild_name = EQEmu::SayLinkEngine::GenerateQuestSaylink(
StringFormat(
"#who \"%s\"",
guild_name.c_str()),
false,
StringFormat("<%s>", guild_name.c_str())
);
}
std::string goto_saylink = EQEmu::SayLinkEngine::GenerateQuestSaylink(
StringFormat("#goto %s", player_name.c_str()), false, "Goto"
);
std::string display_class_name = GetClassIDName(static_cast<uint8>(player_class), static_cast<uint8>(player_level));
c->Message(
5, "%s[%u %s] %s (%s) %s ZONE: %s (%u) (%s) (%s) (%s)",
(account_status > 0 ? "* GM * " : ""),
player_level,
EQEmu::SayLinkEngine::GenerateQuestSaylink(StringFormat("#who %s", base_class_name.c_str()), false, display_class_name).c_str(),
player_name.c_str(),
EQEmu::SayLinkEngine::GenerateQuestSaylink(StringFormat("#who %s", displayed_race_name.c_str()), false, displayed_race_name).c_str(),
displayed_guild_name.c_str(),
EQEmu::SayLinkEngine::GenerateQuestSaylink(StringFormat("#who %s", zone_short_name.c_str()), false, zone_short_name).c_str(),
zone_instance,
goto_saylink.c_str(),
EQEmu::SayLinkEngine::GenerateQuestSaylink(StringFormat("#who %s", account_name.c_str()), false, account_name).c_str(),
EQEmu::SayLinkEngine::GenerateQuestSaylink(StringFormat("#who %s", account_ip.c_str()), false, account_ip).c_str()
);
found_count++;
}
std::string message = (
found_count > 0 ?
StringFormat("There is %i player(s) in EverQuest", found_count).c_str() :
"There are no players in EverQuest that match those who filters."
);
c->Message(5, message.c_str());
}
// All new code added to command.cpp should be BEFORE this comment line. Do no append code to this file below the BOTS code block.
#ifdef BOTS
#include "bot_command.h"

View File

@ -117,6 +117,7 @@ void command_givemoney(Client *c, const Seperator *sep);
void command_globalview(Client* c, const Seperator *sep);
void command_gm(Client *c, const Seperator *sep);
void command_gmspeed(Client *c, const Seperator *sep);
void command_gmzone(Client *c, const Seperator *sep);
void command_goto(Client *c, const Seperator *sep);
void command_grid(Client *c, const Seperator *sep);
void command_guild(Client *c, const Seperator *sep);
@ -325,6 +326,7 @@ void command_viewnpctype(Client *c, const Seperator *sep);
void command_viewpetition(Client *c, const Seperator *sep);
void command_wc(Client *c, const Seperator *sep);
void command_weather(Client *c, const Seperator *sep);
void command_who(Client *c, const Seperator *sep);
void command_worldshutdown(Client *c, const Seperator *sep);
void command_wp(Client *c, const Seperator *sep);
void command_wpadd(Client *c, const Seperator *sep);

View File

@ -1374,7 +1374,7 @@ void Corpse::QueryLoot(Client* to) {
cur = itemlist.begin();
end = itemlist.end();
int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToMobVersion(to->ClientVersion()))->InventoryTypeSize[EQEmu::invtype::typeCorpse];
int corpselootlimit = to->GetInv().GetLookup()->InventoryTypeSize.Corpse;
for(; cur != end; ++cur) {
ServerLootItem_Struct* sitem = *cur;

View File

@ -643,9 +643,9 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
}
if (reduced_recast > 0)
CastSpell(spell_id, target, EQEmu::CastingSlot::Discipline, -1, -1, 0, -1, (uint32)DiscTimer, reduced_recast);
CastSpell(spell_id, target, EQEmu::spells::CastingSlot::Discipline, -1, -1, 0, -1, (uint32)DiscTimer, reduced_recast);
else{
CastSpell(spell_id, target, EQEmu::CastingSlot::Discipline);
CastSpell(spell_id, target, EQEmu::spells::CastingSlot::Discipline);
return true;
}
@ -653,7 +653,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
}
else
{
CastSpell(spell_id, target, EQEmu::CastingSlot::Discipline);
CastSpell(spell_id, target, EQEmu::spells::CastingSlot::Discipline);
}
return(true);
}

View File

@ -3622,6 +3622,36 @@ XS(XS__UpdateZoneHeader) {
XSRETURN_EMPTY;
}
XS(XS__set_rule);
XS(XS__set_rule) {
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: quest::set_rule(string rule_name, string rule_value)");
std::string rule_name = (std::string) SvPV_nolen(ST(0));
std::string rule_value = (std::string) SvPV_nolen(ST(1));
RuleManager::Instance()->SetRule(rule_name.c_str(), rule_value.c_str());
XSRETURN_EMPTY;
}
XS(XS__get_rule);
XS(XS__get_rule) {
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: quest::get_rule(string rule_name)");
dXSTARG;
std::string rule_name = (std::string) SvPV_nolen(ST(0));
std::string rule_value;
RuleManager::Instance()->GetRule(rule_name.c_str(), rule_value);
sv_setpv(TARG, rule_value.c_str());
XSprePUSH;
PUSHTARG;
XSRETURN(1);
}
XS(XS__get_data);
XS(XS__get_data) {
dXSARGS;
@ -3734,6 +3764,8 @@ EXTERN_C XS(boot_quest) {
newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file);
newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file);
newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file);
newXS(strcpy(buf, "set_rule"), XS__set_rule, file);
newXS(strcpy(buf, "get_rule"), XS__get_rule, file);
newXS(strcpy(buf, "get_data"), XS__get_data, file);
newXS(strcpy(buf, "get_data_expires"), XS__get_data_expires, file);
newXS(strcpy(buf, "set_data"), XS__set_data, file);

View File

@ -650,8 +650,6 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0);
npc->FixZ();
uint16 emoteid = npc->GetEmoteID();
if (emoteid != 0)
npc->DoNPCEmote(ONSPAWN, emoteid);
@ -1564,7 +1562,7 @@ void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *ap
}
}
void EntityList::QueueClientsByXTarget(Mob *sender, const EQApplicationPacket *app, bool iSendToSender, EQEmu::versions::ClientVersionBit client_version_bits)
void EntityList::QueueClientsByXTarget(Mob *sender, const EQApplicationPacket *app, bool iSendToSender, EQEmu::versions::ClientVersionBitmask client_version_bits)
{
auto it = client_list.begin();
while (it != client_list.end()) {

View File

@ -353,7 +353,7 @@ public:
void QueueClientsByTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, Mob* SkipThisMob = 0, bool ackreq = true,
bool HoTT = true, uint32 ClientVersionBits = 0xFFFFFFFF, bool inspect_buffs = false);
void QueueClientsByXTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, EQEmu::versions::ClientVersionBit client_version_bits = EQEmu::versions::ClientVersionBit::bit_AllClients);
void QueueClientsByXTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, EQEmu::versions::ClientVersionBitmask client_version_bits = EQEmu::versions::ClientVersionBitmask::maskAllClients);
void QueueToGroupsForNPCHealthAA(Mob* sender, const EQApplicationPacket* app);
void QueueManaged(Mob* sender, const EQApplicationPacket* app, bool ignore_sender=false, bool ackreq = true);

View File

@ -1133,7 +1133,7 @@ uint32 Client::GetCharMaxLevelFromQGlobal() {
uint32 Client::GetCharMaxLevelFromBucket() {
uint32 char_id = this->CharacterID();
std::string query = StringFormat("SELECT value FROM data_buckets WHERE key = '%i-CharMaxLevel'", char_id);
std::string query = StringFormat("SELECT value FROM data_buckets WHERE `key` = '%i-CharMaxLevel'", char_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
Log(Logs::General, Logs::Error, "Data bucket for CharMaxLevel for char ID %i failed.", char_id);

View File

@ -691,7 +691,7 @@ void GuildBankManager::SendGuildBank(Client *c)
auto &guild_bank = *Iterator;
// RoF+ uses a bulk list packet -- This is also how the Action 0 of older clients basically works
if (c->ClientVersionBit() & EQEmu::versions::bit_RoFAndLater) {
if (c->ClientVersionBit() & EQEmu::versions::maskRoFAndLater) {
auto outapp = new EQApplicationPacket(OP_GuildBankItemList, sizeof(GuildBankItemListEntry_Struct) * 240);
for (int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i) {
const EQEmu::ItemData *Item = database.GetItem(guild_bank->Items.DepositArea[i].ItemID);

View File

@ -113,7 +113,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
x++;
}
DeleteItemInInventory(i, 0, ((i - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]));
DeleteItemInInventory(i, 0, ((i - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize.Bank));
}
}
@ -126,7 +126,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
x++;
}
DeleteItemInInventory(i, 0, (((i - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]));
DeleteItemInInventory(i, 0, (((i - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT) >= GetInv().GetLookup()->InventoryTypeSize.Bank));
}
}
}
@ -781,12 +781,12 @@ int32 Client::GetItemIDAt(int16 slot_id) {
return INVALID_ID;
}
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize.Bank)
return INVALID_ID;
}
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize.Bank)
return INVALID_ID;
}
@ -811,12 +811,12 @@ int32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) {
return INVALID_ID;
}
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize.Bank)
return INVALID_ID;
}
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize.Bank)
return INVALID_ID;
}
@ -1474,11 +1474,11 @@ bool Client::IsValidSlot(uint32 slot) {
return ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) != 0);
}
else if (slot <= EQEmu::invslot::BANK_END && slot >= EQEmu::invslot::BANK_BEGIN) {
return ((slot - EQEmu::invslot::BANK_BEGIN) < GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]);
return ((slot - EQEmu::invslot::BANK_BEGIN) < GetInv().GetLookup()->InventoryTypeSize.Bank);
}
else if (slot <= EQEmu::invbag::BANK_BAGS_END && slot >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (slot - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
return (temp_slot < GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]);
return (temp_slot < GetInv().GetLookup()->InventoryTypeSize.Bank);
}
else if (
(slot == (uint32)INVALID_INDEX) ||
@ -2500,7 +2500,7 @@ void Client::DisenchantSummonedBags(bool client_update)
}
for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize.Bank)
continue;
auto inst = m_inv[slot_id];
@ -2627,7 +2627,7 @@ void Client::RemoveNoRent(bool client_update)
}
for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize.Bank)
continue;
auto inst = m_inv[slot_id];
@ -2639,7 +2639,7 @@ void Client::RemoveNoRent(bool client_update)
for (auto slot_id = EQEmu::invbag::BANK_BAGS_BEGIN; slot_id <= EQEmu::invbag::BANK_BAGS_END; ++slot_id) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize.Bank)
continue;
auto inst = m_inv[slot_id];
@ -2745,7 +2745,7 @@ void Client::RemoveDuplicateLore(bool client_update)
}
for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize.Bank)
continue;
auto inst = m_inv.PopItem(slot_id);
@ -2762,7 +2762,7 @@ void Client::RemoveDuplicateLore(bool client_update)
for (auto slot_id = EQEmu::invbag::BANK_BAGS_BEGIN; slot_id <= EQEmu::invbag::BANK_BAGS_END; ++slot_id) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize.Bank)
continue;
auto inst = m_inv.PopItem(slot_id);
@ -2925,12 +2925,12 @@ void Client::SendItemPacket(int16 slot_id, const EQEmu::ItemInstance* inst, Item
return;
}
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize.Bank)
return;
}
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize.Bank)
return;
}

View File

@ -814,6 +814,16 @@ std::string lua_say_link(const char *phrase) {
return quest_manager.saylink(text, false, text);
}
void lua_set_rule(std::string rule_name, std::string rule_value) {
RuleManager::Instance()->SetRule(rule_name.c_str(), rule_value.c_str());
}
std::string lua_get_rule(std::string rule_name) {
std::string rule_value;
RuleManager::Instance()->GetRule(rule_name.c_str(), rule_value);
return rule_value;
}
std::string lua_get_data(std::string bucket_key) {
return DataBucket::GetData(bucket_key);
}
@ -1687,6 +1697,8 @@ luabind::scope lua_register_general() {
luabind::def("say_link", (std::string(*)(const char*,bool,const char*))&lua_say_link),
luabind::def("say_link", (std::string(*)(const char*,bool))&lua_say_link),
luabind::def("say_link", (std::string(*)(const char*))&lua_say_link),
luabind::def("set_rule", (void(*)(std::string, std::string))&lua_set_rule),
luabind::def("get_rule", (std::string(*)(std::string))&lua_get_rule),
luabind::def("get_data", (std::string(*)(std::string))&lua_get_data),
luabind::def("get_data_expires", (std::string(*)(std::string))&lua_get_data_expires),
luabind::def("set_data", (void(*)(std::string, std::string))&lua_set_data),

View File

@ -770,28 +770,28 @@ bool Lua_Mob::CastSpell(int spell_id, int target_id) {
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot) {
Lua_Safe_Call_Bool();
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot));
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::spells::CastingSlot>(slot));
}
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time) {
Lua_Safe_Call_Bool();
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot), cast_time);
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::spells::CastingSlot>(slot), cast_time);
}
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost) {
Lua_Safe_Call_Bool();
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot), cast_time, mana_cost);
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::spells::CastingSlot>(slot), cast_time, mana_cost);
}
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot) {
Lua_Safe_Call_Bool();
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot), cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot));
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::spells::CastingSlot>(slot), cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot));
}
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, int mana_cost, int item_slot, int timer,
int timer_duration) {
Lua_Safe_Call_Bool();
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot), cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::spells::CastingSlot>(slot), cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
static_cast<uint32>(timer), static_cast<uint32>(timer_duration));
}
@ -800,7 +800,7 @@ bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time, in
Lua_Safe_Call_Bool();
int16 res = resist_adjust;
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::CastingSlot>(slot), cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
return self->CastSpell(spell_id, target_id, static_cast<EQEmu::spells::CastingSlot>(slot), cast_time, mana_cost, nullptr, static_cast<uint32>(item_slot),
static_cast<uint32>(timer), static_cast<uint32>(timer_duration), &res);
}
@ -811,27 +811,27 @@ bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target) {
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot) {
Lua_Safe_Call_Bool();
return self->SpellFinished(spell_id, target, static_cast<EQEmu::CastingSlot>(slot));
return self->SpellFinished(spell_id, target, static_cast<EQEmu::spells::CastingSlot>(slot));
}
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used) {
Lua_Safe_Call_Bool();
return self->SpellFinished(spell_id, target, static_cast<EQEmu::CastingSlot>(slot), mana_used);
return self->SpellFinished(spell_id, target, static_cast<EQEmu::spells::CastingSlot>(slot), mana_used);
}
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used, uint32 inventory_slot) {
Lua_Safe_Call_Bool();
return self->SpellFinished(spell_id, target, static_cast<EQEmu::CastingSlot>(slot), mana_used, inventory_slot);
return self->SpellFinished(spell_id, target, static_cast<EQEmu::spells::CastingSlot>(slot), mana_used, inventory_slot);
}
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used, uint32 inventory_slot, int resist_adjust) {
Lua_Safe_Call_Bool();
return self->SpellFinished(spell_id, target, static_cast<EQEmu::CastingSlot>(slot), mana_used, inventory_slot, resist_adjust);
return self->SpellFinished(spell_id, target, static_cast<EQEmu::spells::CastingSlot>(slot), mana_used, inventory_slot, resist_adjust);
}
bool Lua_Mob::SpellFinished(int spell_id, Lua_Mob target, int slot, int mana_used, uint32 inventory_slot, int resist_adjust, bool proc) {
Lua_Safe_Call_Bool();
return self->SpellFinished(spell_id, target, static_cast<EQEmu::CastingSlot>(slot), mana_used, inventory_slot, resist_adjust, proc);
return self->SpellFinished(spell_id, target, static_cast<EQEmu::spells::CastingSlot>(slot), mana_used, inventory_slot, resist_adjust, proc);
}
void Lua_Mob::SendBeginCast(int spell_id, int cast_time) {

View File

@ -1993,7 +1993,7 @@ bool Merc::AIDoSpellCast(uint16 spellid, Mob* tar, int32 mana_cost, uint32* oDon
SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0);
SetMoving(false);
result = CastSpell(spellid, tar->GetID(), EQEmu::CastingSlot::Gem2, -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, 0);
result = CastSpell(spellid, tar->GetID(), EQEmu::spells::CastingSlot::Gem2, -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, 0);
if(IsCasting() && IsSitting())
Stand();
@ -4045,7 +4045,7 @@ bool Merc::UseDiscipline(int32 spell_id, int32 target) {
if(IsCasting())
InterruptSpell();
CastSpell(spell_id, target, EQEmu::CastingSlot::Discipline);
CastSpell(spell_id, target, EQEmu::spells::CastingSlot::Discipline);
return(true);
}

View File

@ -1381,7 +1381,7 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal
/**
* Update those who have us targeted
*/
entity_list.QueueClientsByTarget(this, &hp_packet, false, 0, false, true, EQEmu::versions::bit_AllClients);
entity_list.QueueClientsByTarget(this, &hp_packet, false, 0, false, true, EQEmu::versions::maskAllClients);
/**
* Update those who have us on x-target
@ -1663,15 +1663,10 @@ void Mob::ShowBuffList(Client* client) {
}
void Mob::GMMove(float x, float y, float z, float heading, bool SendUpdate) {
if (IsCorpse() || (IsClient() && !IsAIControlled())) {
m_Position.x = x;
m_Position.y = y;
m_Position.z = z;
mMovementManager->SendCommandToClients(this, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny);
}
else {
Teleport(glm::vec4(x, y, z, heading));
}
m_Position.x = x;
m_Position.y = y;
m_Position.z = z;
mMovementManager->SendCommandToClients(this, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny);
if (IsNPC()) {
CastToNPC()->SaveGuardSpot(glm::vec4(x, y, z, heading));
@ -3128,12 +3123,12 @@ void Mob::ExecWeaponProc(const EQEmu::ItemInstance *inst, uint16 spell_id, Mob *
twinproc = true;
if (IsBeneficialSpell(spell_id) && (!IsNPC() || (IsNPC() && CastToNPC()->GetInnateProcSpellID() != spell_id))) { // NPC innate procs don't take this path ever
SpellFinished(spell_id, this, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff, true, level_override);
SpellFinished(spell_id, this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff, true, level_override);
if(twinproc)
SpellOnTarget(spell_id, this, false, false, 0, true, level_override);
}
else if(!(on->IsClient() && on->CastToClient()->dead)) { //dont proc on dead clients
SpellFinished(spell_id, on, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff, true, level_override);
SpellFinished(spell_id, on, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff, true, level_override);
if(twinproc)
SpellOnTarget(spell_id, on, false, false, 0, true, level_override);
}
@ -3470,7 +3465,7 @@ void Mob::TriggerOnCast(uint32 focus_spell, uint32 spell_id, bool aa_trigger)
trigger_spell_id = CastToClient()->CalcAAFocus(focusTriggerOnCast, *rank, spell_id);
if (IsValidSpell(trigger_spell_id) && GetTarget())
SpellFinished(trigger_spell_id, GetTarget(), EQEmu::CastingSlot::Item, 0, -1,
SpellFinished(trigger_spell_id, GetTarget(), EQEmu::spells::CastingSlot::Item, 0, -1,
spells[trigger_spell_id].ResistDiff);
}
@ -3478,7 +3473,7 @@ void Mob::TriggerOnCast(uint32 focus_spell, uint32 spell_id, bool aa_trigger)
trigger_spell_id = CalcFocusEffect(focusTriggerOnCast, focus_spell, spell_id);
if (IsValidSpell(trigger_spell_id) && GetTarget()) {
SpellFinished(trigger_spell_id, GetTarget(), EQEmu::CastingSlot::Item, 0, -1,
SpellFinished(trigger_spell_id, GetTarget(), EQEmu::spells::CastingSlot::Item, 0, -1,
spells[trigger_spell_id].ResistDiff);
CheckNumHitsRemaining(NumHit::MatchingSpells, -1, focus_spell);
}
@ -3509,7 +3504,7 @@ bool Mob::TrySpellTrigger(Mob *target, uint32 spell_id, int effect)
{
// If we trigger an effect then its over.
if (IsValidSpell(spells[spell_id].base2[i])){
SpellFinished(spells[spell_id].base2[i], target, EQEmu::CastingSlot::Item, 0, -1, spells[spells[spell_id].base2[i]].ResistDiff);
SpellFinished(spells[spell_id].base2[i], target, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spells[spell_id].base2[i]].ResistDiff);
return true;
}
}
@ -3528,7 +3523,7 @@ bool Mob::TrySpellTrigger(Mob *target, uint32 spell_id, int effect)
if(zone->random.Int(0, 100) <= spells[spell_id].base[effect])
{
if (IsValidSpell(spells[spell_id].base2[effect])){
SpellFinished(spells[spell_id].base2[effect], target, EQEmu::CastingSlot::Item, 0, -1, spells[spells[spell_id].base2[effect]].ResistDiff);
SpellFinished(spells[spell_id].base2[effect], target, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spells[spell_id].base2[effect]].ResistDiff);
return true; //Only trigger once of these per spell effect.
}
}
@ -3605,7 +3600,7 @@ void Mob::TryTriggerOnValueAmount(bool IsHP, bool IsMana, bool IsEndur, bool IsP
}
if (use_spell){
SpellFinished(spells[spell_id].base[i], this, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
SpellFinished(spells[spell_id].base[i], this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
if(!TryFadeEffect(e))
BuffFadeBySlot(e);
@ -3633,7 +3628,7 @@ void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id)
if(zone->random.Roll(focus))
{
Message(MT_Spells,"You twincast %s!",spells[spell_id].name);
SpellFinished(spell_id, target, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
SpellFinished(spell_id, target, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
}
}
}
@ -3651,7 +3646,7 @@ void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id)
{
if(zone->random.Roll(focus))
{
SpellFinished(spell_id, target, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
SpellFinished(spell_id, target, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
}
}
}
@ -3779,10 +3774,10 @@ bool Mob::TryFadeEffect(int slot)
if(IsValidSpell(spell_id))
{
if (IsBeneficialSpell(spell_id)) {
SpellFinished(spell_id, this, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
SpellFinished(spell_id, this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
}
else if(!(IsClient() && CastToClient()->dead)) {
SpellFinished(spell_id, this, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
SpellFinished(spell_id, this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
}
return true;
}
@ -3816,7 +3811,7 @@ void Mob::TrySympatheticProc(Mob *target, uint32 spell_id)
SpellFinished(focus_trigger, target);
else
SpellFinished(focus_trigger, this, EQEmu::CastingSlot::Item, 0, -1, spells[focus_trigger].ResistDiff);
SpellFinished(focus_trigger, this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[focus_trigger].ResistDiff);
}
// For detrimental spells, if the triggered spell is beneficial, then it will land on the caster
// if the triggered spell is also detrimental, then it will land on the target
@ -3826,7 +3821,7 @@ void Mob::TrySympatheticProc(Mob *target, uint32 spell_id)
SpellFinished(focus_trigger, this);
else
SpellFinished(focus_trigger, target, EQEmu::CastingSlot::Item, 0, -1, spells[focus_trigger].ResistDiff);
SpellFinished(focus_trigger, target, EQEmu::spells::CastingSlot::Item, 0, -1, spells[focus_trigger].ResistDiff);
}
CheckNumHitsRemaining(NumHit::MatchingSpells, -1, focus_spell);
@ -4475,7 +4470,7 @@ void Mob::TrySpellOnKill(uint8 level, uint16 spell_id)
if (IsValidSpell(spells[spell_id].base2[i]) && spells[spell_id].max[i] <= level)
{
if(zone->random.Roll(spells[spell_id].base[i]))
SpellFinished(spells[spell_id].base2[i], this, EQEmu::CastingSlot::Item, 0, -1, spells[spells[spell_id].base2[i]].ResistDiff);
SpellFinished(spells[spell_id].base2[i], this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spells[spell_id].base2[i]].ResistDiff);
}
}
}
@ -4490,17 +4485,17 @@ void Mob::TrySpellOnKill(uint8 level, uint16 spell_id)
if(aabonuses.SpellOnKill[i] && IsValidSpell(aabonuses.SpellOnKill[i]) && (level >= aabonuses.SpellOnKill[i + 2])) {
if(zone->random.Roll(static_cast<int>(aabonuses.SpellOnKill[i + 1])))
SpellFinished(aabonuses.SpellOnKill[i], this, EQEmu::CastingSlot::Item, 0, -1, spells[aabonuses.SpellOnKill[i]].ResistDiff);
SpellFinished(aabonuses.SpellOnKill[i], this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[aabonuses.SpellOnKill[i]].ResistDiff);
}
if(itembonuses.SpellOnKill[i] && IsValidSpell(itembonuses.SpellOnKill[i]) && (level >= itembonuses.SpellOnKill[i + 2])){
if(zone->random.Roll(static_cast<int>(itembonuses.SpellOnKill[i + 1])))
SpellFinished(itembonuses.SpellOnKill[i], this, EQEmu::CastingSlot::Item, 0, -1, spells[aabonuses.SpellOnKill[i]].ResistDiff);
SpellFinished(itembonuses.SpellOnKill[i], this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[aabonuses.SpellOnKill[i]].ResistDiff);
}
if(spellbonuses.SpellOnKill[i] && IsValidSpell(spellbonuses.SpellOnKill[i]) && (level >= spellbonuses.SpellOnKill[i + 2])) {
if(zone->random.Roll(static_cast<int>(spellbonuses.SpellOnKill[i + 1])))
SpellFinished(spellbonuses.SpellOnKill[i], this, EQEmu::CastingSlot::Item, 0, -1, spells[aabonuses.SpellOnKill[i]].ResistDiff);
SpellFinished(spellbonuses.SpellOnKill[i], this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[aabonuses.SpellOnKill[i]].ResistDiff);
}
}
@ -4517,19 +4512,19 @@ bool Mob::TrySpellOnDeath()
for(int i = 0; i < MAX_SPELL_TRIGGER*2; i+=2) {
if(IsClient() && aabonuses.SpellOnDeath[i] && IsValidSpell(aabonuses.SpellOnDeath[i])) {
if(zone->random.Roll(static_cast<int>(aabonuses.SpellOnDeath[i + 1]))) {
SpellFinished(aabonuses.SpellOnDeath[i], this, EQEmu::CastingSlot::Item, 0, -1, spells[aabonuses.SpellOnDeath[i]].ResistDiff);
SpellFinished(aabonuses.SpellOnDeath[i], this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[aabonuses.SpellOnDeath[i]].ResistDiff);
}
}
if(itembonuses.SpellOnDeath[i] && IsValidSpell(itembonuses.SpellOnDeath[i])) {
if(zone->random.Roll(static_cast<int>(itembonuses.SpellOnDeath[i + 1]))) {
SpellFinished(itembonuses.SpellOnDeath[i], this, EQEmu::CastingSlot::Item, 0, -1, spells[itembonuses.SpellOnDeath[i]].ResistDiff);
SpellFinished(itembonuses.SpellOnDeath[i], this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[itembonuses.SpellOnDeath[i]].ResistDiff);
}
}
if(spellbonuses.SpellOnDeath[i] && IsValidSpell(spellbonuses.SpellOnDeath[i])) {
if(zone->random.Roll(static_cast<int>(spellbonuses.SpellOnDeath[i + 1]))) {
SpellFinished(spellbonuses.SpellOnDeath[i], this, EQEmu::CastingSlot::Item, 0, -1, spells[spellbonuses.SpellOnDeath[i]].ResistDiff);
SpellFinished(spellbonuses.SpellOnDeath[i], this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spellbonuses.SpellOnDeath[i]].ResistDiff);
}
}
}

View File

@ -278,7 +278,7 @@ public:
//Song
bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1);
bool ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, EQEmu::CastingSlot slot);
bool ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, EQEmu::spells::CastingSlot slot);
void BardPulse(uint16 spell_id, Mob *caster);
//Spell
@ -309,24 +309,24 @@ public:
void SendSpellBarEnable(uint16 spellid);
void ZeroCastingVars();
virtual void SpellProcess();
virtual bool CastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, int32 casttime = -1,
virtual bool CastSpell(uint16 spell_id, uint16 target_id, EQEmu::spells::CastingSlot slot = EQEmu::spells::CastingSlot::Item, int32 casttime = -1,
int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF,
uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, int16 *resist_adjust = nullptr,
uint32 aa_id = 0);
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, int32 casttime = -1,
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, EQEmu::spells::CastingSlot slot = EQEmu::spells::CastingSlot::Item, int32 casttime = -1,
int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF,
uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, int16 resist_adjust = 0,
uint32 aa_id = 0);
void CastedSpellFinished(uint16 spell_id, uint32 target_id, EQEmu::CastingSlot slot, uint16 mana_used,
void CastedSpellFinished(uint16 spell_id, uint32 target_id, EQEmu::spells::CastingSlot slot, uint16 mana_used,
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0);
bool SpellFinished(uint16 spell_id, Mob *target, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, uint16 mana_used = 0,
bool SpellFinished(uint16 spell_id, Mob *target, EQEmu::spells::CastingSlot slot = EQEmu::spells::CastingSlot::Item, uint16 mana_used = 0,
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false, int level_override = -1);
void SendBeginCast(uint16 spell_id, uint32 casttime);
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect = false,
bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false, int level_override = -1);
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100, int level_override = -1);
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center,
CastAction_type &CastAction, EQEmu::CastingSlot slot, bool isproc = false);
CastAction_type &CastAction, EQEmu::spells::CastingSlot slot, bool isproc = false);
virtual bool CheckFizzle(uint16 spell_id);
virtual bool CheckSpellLevelRestriction(uint16 spell_id);
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
@ -1375,7 +1375,7 @@ protected:
int attacked_count;
bool delaytimer;
uint16 casting_spell_targetid;
EQEmu::CastingSlot casting_spell_slot;
EQEmu::spells::CastingSlot casting_spell_slot;
uint16 casting_spell_mana;
uint32 casting_spell_inventory_slot;
uint32 casting_spell_timer;
@ -1385,7 +1385,7 @@ protected:
uint32 casting_spell_aa_id;
bool casting_spell_checks;
uint16 bardsong;
EQEmu::CastingSlot bardsong_slot;
EQEmu::spells::CastingSlot bardsong_slot;
uint32 bardsong_target_id;
bool ActiveProjectileATK;
@ -1538,7 +1538,7 @@ protected:
glm::vec3 m_TargetRing;
// we might want to do this differently, we gotta do max NPC buffs ... which is 97
uint32 m_spellHitsLeft[EQEmu::constants::TotalBuffs]; // Used to track which spells will have their numhits incremented when spell finishes casting
uint32 m_spellHitsLeft[EQEmu::spells::TOTAL_BUFFS]; // Used to track which spells will have their numhits incremented when spell finishes casting
GravityBehavior flymode;
bool m_targetable;
int QGVarDuration(const char *fmt);

View File

@ -375,7 +375,7 @@ bool NPC::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain
#endif
casting_spell_AIindex = i;
return CastSpell(AIspells[i].spellid, tar->GetID(), EQEmu::CastingSlot::Gem2, AIspells[i].manacost == -2 ? 0 : -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, &(AIspells[i].resist_adjust));
return CastSpell(AIspells[i].spellid, tar->GetID(), EQEmu::spells::CastingSlot::Gem2, AIspells[i].manacost == -2 ? 0 : -1, mana_cost, oDontDoAgainBefore, -1, -1, 0, &(AIspells[i].resist_adjust));
}
bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint32 iSpellTypes) {
@ -688,11 +688,11 @@ void Client::AI_SpellCast()
}
uint32 spell_to_cast = 0xFFFFFFFF;
EQEmu::CastingSlot slot_to_use = EQEmu::CastingSlot::Item;
EQEmu::spells::CastingSlot slot_to_use = EQEmu::spells::CastingSlot::Item;
if(valid_spells.size() == 1)
{
spell_to_cast = valid_spells[0];
slot_to_use = static_cast<EQEmu::CastingSlot>(slots[0]);
slot_to_use = static_cast<EQEmu::spells::CastingSlot>(slots[0]);
}
else if(valid_spells.empty())
{
@ -702,7 +702,7 @@ void Client::AI_SpellCast()
{
uint32 idx = zone->random.Int(0, (valid_spells.size()-1));
spell_to_cast = valid_spells[idx];
slot_to_use = static_cast<EQEmu::CastingSlot>(slots[idx]);
slot_to_use = static_cast<EQEmu::spells::CastingSlot>(slots[idx]);
}
if(IsMezSpell(spell_to_cast) || IsFearSpell(spell_to_cast))

View File

@ -817,7 +817,7 @@ void Mob::DisplayInfo(Mob *mob)
NPCCommandsMenu(client, npc);
}
std::cout << "Window Length: " << window_text.length() << std::endl;
// std::cout << "Window Length: " << window_text.length() << std::endl;
if (client->GetDisplayMobInfoWindow()) {
client->SendFullPopup(

View File

@ -362,18 +362,21 @@ int main(int argc, char** argv) {
std::string tmp;
if (database.GetVariable("RuleSet", tmp)) {
Log(Logs::General, Logs::Zone_Server, "Loading rule set '%s'", tmp.c_str());
if (!RuleManager::Instance()->LoadRules(&database, tmp.c_str())) {
if (!RuleManager::Instance()->LoadRules(&database, tmp.c_str(), false)) {
Log(Logs::General, Logs::Error, "Failed to load ruleset '%s', falling back to defaults.", tmp.c_str());
}
}
else {
if (!RuleManager::Instance()->LoadRules(&database, "default")) {
if (!RuleManager::Instance()->LoadRules(&database, "default", false)) {
Log(Logs::General, Logs::Zone_Server, "No rule set configured, using default rules");
}
else {
Log(Logs::General, Logs::Zone_Server, "Loaded default rule set 'default'", tmp.c_str());
}
}
EQEmu::InitializeDynamicLookups();
Log(Logs::General, Logs::Zone_Server, "Initialized dynamic dictionary entries");
}
#ifdef BOTS

View File

@ -507,7 +507,7 @@ void NPC::SetTarget(Mob* mob) {
if (owner) {
auto client = owner->CastToClient();
if (client->ClientVersionBit() & EQEmu::versions::bit_UFAndLater) {
if (client->ClientVersionBit() & EQEmu::versions::maskUFAndLater) {
auto app = new EQApplicationPacket(OP_PetHoTT, sizeof(ClientTarget_Struct));
auto ct = (ClientTarget_Struct *)app->pBuffer;
ct->new_target = mob ? mob->GetID() : 0;
@ -1388,7 +1388,7 @@ uint32 ZoneDatabase::DeleteSpawnRemoveFromNPCTypeTable(const char *zone, uint32
uint32 spawngroupID = 0;
std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE zone = '%s' "
"AND version = %u AND spawngroupID = %i",
"AND (version = %u OR version = -1) AND spawngroupID = %i",
zone, zone_version, spawn->GetSp2());
auto results = QueryDatabase(query);
if (!results.Success())

View File

@ -100,7 +100,7 @@ void NpcScaleManager::ScaleNPC(NPC * npc)
if (npc->GetPhR() == 0) {
npc->ModifyNPCStat("pr", std::to_string(scale_data.physical_resist).c_str());
}
if (npc->GetMinDMG() == 0) {
if (npc->GetMinDMG() == 0 && npc->GetMaxDMG() == 0) {
int min_dmg = scale_data.min_dmg;
if (RuleB(Combat, UseNPCDamageClassLevelMods)) {
int32 class_level_damage_mod = GetClassLevelDamageMod(npc->GetLevel(), npc->GetClass());

View File

@ -3737,7 +3737,7 @@ XS(XS_Mob_CastSpell) {
Mob *THIS;
uint16 spell_id = (uint16) SvUV(ST(1));
uint16 target_id = (uint16) SvUV(ST(2));
EQEmu::CastingSlot slot;
EQEmu::spells::CastingSlot slot;
int32 casttime;
int32 mana_cost;
int16 resist_adjust;
@ -3751,9 +3751,9 @@ XS(XS_Mob_CastSpell) {
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
if (items < 4)
slot = EQEmu::CastingSlot::Item;
slot = EQEmu::spells::CastingSlot::Item;
else {
slot = static_cast<EQEmu::CastingSlot>(SvUV(ST(3)));
slot = static_cast<EQEmu::spells::CastingSlot>(SvUV(ST(3)));
}
if (items < 5)
@ -3827,7 +3827,7 @@ XS(XS_Mob_SpellFinished) {
resist_diff = spells[spell_id].ResistDiff;
}
THIS->SpellFinished(spell_id, spell_target, EQEmu::CastingSlot::Item, mana_cost, -1, resist_diff);
THIS->SpellFinished(spell_id, spell_target, EQEmu::spells::CastingSlot::Item, mana_cost, -1, resist_diff);
}
XSRETURN_EMPTY;
}

View File

@ -371,14 +371,14 @@ void QuestManager::castspell(int spell_id, int target_id) {
if (owner) {
Mob *tgt = entity_list.GetMob(target_id);
if(tgt != nullptr)
owner->SpellFinished(spell_id, tgt, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
owner->SpellFinished(spell_id, tgt, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
}
}
void QuestManager::selfcast(int spell_id) {
QuestManagerCurrentQuestVars();
if (initiator)
initiator->SpellFinished(spell_id, initiator, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
initiator->SpellFinished(spell_id, initiator, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
}
void QuestManager::addloot(int item_id, int charges, bool equipitem, int aug1, int aug2, int aug3, int aug4, int aug5, int aug6) {
@ -985,7 +985,7 @@ uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) {
bool SpellBucketCheckResult = 0;
for(spell_id = 0, book_slot = initiator->GetNextAvailableSpellBookSlot(), count = 0; spell_id < SPDAT_RECORDS && book_slot < MAX_PP_SPELLBOOK; spell_id++, book_slot = initiator->GetNextAvailableSpellBookSlot(book_slot))
for(spell_id = 0, book_slot = initiator->GetNextAvailableSpellBookSlot(), count = 0; spell_id < SPDAT_RECORDS && book_slot < EQEmu::spells::SPELLBOOK_SIZE; spell_id++, book_slot = initiator->GetNextAvailableSpellBookSlot(book_slot))
{
if
(

View File

@ -488,7 +488,7 @@ bool ZoneDatabase::PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*>
"animation "
"FROM "
"spawn2 "
"WHERE zone = '%s' AND version = %u",
"WHERE zone = '%s' AND (version = %u OR version = -1) ",
zone_name,
version
);
@ -592,7 +592,7 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
"animation "
"FROM "
"spawn2 "
"WHERE zone = '%s' AND version = %u",
"WHERE zone = '%s' AND (version = %u OR version = -1)",
zone_name,
version
);

View File

@ -197,7 +197,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32
IsValidSpell(aabonuses.SkillAttackProc[2])) {
float chance = aabonuses.SkillAttackProc[0] / 1000.0f;
if (zone->random.Roll(chance))
SpellFinished(aabonuses.SkillAttackProc[2], who, EQEmu::CastingSlot::Item, 0, -1,
SpellFinished(aabonuses.SkillAttackProc[2], who, EQEmu::spells::CastingSlot::Item, 0, -1,
spells[aabonuses.SkillAttackProc[2]].ResistDiff);
}
@ -2156,7 +2156,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob *other, uint16 weapon_damage, EQEmu::skills:
IsValidSpell(aabonuses.SkillAttackProc[2])) {
float chance = aabonuses.SkillAttackProc[0] / 1000.0f;
if (zone->random.Roll(chance))
SpellFinished(aabonuses.SkillAttackProc[2], other, EQEmu::CastingSlot::Item, 0, -1,
SpellFinished(aabonuses.SkillAttackProc[2], other, EQEmu::spells::CastingSlot::Item, 0, -1,
spells[aabonuses.SkillAttackProc[2]].ResistDiff);
}

View File

@ -149,7 +149,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if (spells[spell_id].EndurUpkeep > 0)
SetEndurUpkeep(true);
if (IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::bit_UFAndLater)
if (IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::maskUFAndLater)
{
EQApplicationPacket *outapp = MakeBuffsPacket(false);
CastToClient()->FastQueuePacket(&outapp);
@ -826,7 +826,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#endif
if(IsClient())
{
if (CastToClient()->ClientVersionBit() & EQEmu::versions::bit_SoDAndLater)
if (CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoDAndLater)
{
bodyType bt = BT_Undead;
@ -1244,7 +1244,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
// Will fix buttons for now
if (IsClient()) {
auto c = CastToClient();
if (c->ClientVersionBit() & EQEmu::versions::bit_UFAndLater) {
if (c->ClientVersionBit() & EQEmu::versions::maskUFAndLater) {
c->SetPetCommandState(PET_BUTTON_SIT, 0);
c->SetPetCommandState(PET_BUTTON_STOP, 0);
c->SetPetCommandState(PET_BUTTON_REGROUP, 0);
@ -1663,7 +1663,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
#endif
// This is handled by the client prior to SoD.
//
if (IsClient() && (CastToClient()->ClientVersionBit() & EQEmu::versions::bit_SoDAndLater))
if (IsClient() && (CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoDAndLater))
CastToClient()->LocateCorpse();
break;
@ -2470,7 +2470,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
case SE_FcTimerRefresh:
{
if(IsClient()) {
for(unsigned int i =0 ; i < MAX_PP_MEMSPELL; ++i) {
for (unsigned int i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; ++i) {
if(IsValidSpell(CastToClient()->m_pp.mem_spells[i])) {
if (CalcFocusEffect(focusFcTimerRefresh, spell_id, CastToClient()->m_pp.mem_spells[i])){
CastToClient()->m_pp.spellSlotRefresh[i] = 1;
@ -2739,7 +2739,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if (caster && IsValidSpell(spells[spell_id].base2[i])){
if(zone->random.Roll(spells[spell_id].base[i]))
caster->SpellFinished(spells[spell_id].base2[i], this, EQEmu::CastingSlot::Item, 0, -1, spells[spells[spell_id].base2[i]].ResistDiff);
caster->SpellFinished(spells[spell_id].base2[i], this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spells[spell_id].base2[i]].ResistDiff);
}
break;
}
@ -3402,7 +3402,7 @@ void Mob::BuffProcess()
Log(Logs::Detail, Logs::Spells, "Buff %d in slot %d has %d tics remaining.", buffs[buffs_i].spellid, buffs_i, buffs[buffs_i].ticsremaining);
}
}
else if (IsClient() && !(CastToClient()->ClientVersionBit() & EQEmu::versions::bit_SoFAndLater))
else if (IsClient() && !(CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoFAndLater))
{
buffs[buffs_i].UpdateClient = true;
}
@ -3662,14 +3662,14 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
case SE_CastOnFadeEffectNPC:
case SE_CastOnFadeEffectAlways: {
if (buff.ticsremaining == 0) {
SpellFinished(spells[buff.spellid].base[i], this, EQEmu::CastingSlot::Item, 0, -1, spells[spells[buff.spellid].base[i]].ResistDiff);
SpellFinished(spells[buff.spellid].base[i], this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spells[buff.spellid].base[i]].ResistDiff);
}
break;
}
case SE_LocateCorpse: {
// This is handled by the client prior to SoD.
if (IsClient() && (CastToClient()->ClientVersionBit() & EQEmu::versions::bit_SoDAndLater))
if (IsClient() && (CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoDAndLater))
CastToClient()->LocateCorpse();
}
@ -4085,7 +4085,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
{
EQApplicationPacket *outapp = MakeBuffsPacket();
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQEmu::versions::bit_SoDAndLater);
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQEmu::versions::maskSoDAndLater);
if(IsClient() && GetTarget() == this) {
CastToClient()->QueuePacket(outapp);
}
@ -4095,11 +4095,11 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
if (IsNPC()) {
EQApplicationPacket *outapp = MakeBuffsPacket();
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQEmu::versions::bit_SoDAndLater, true);
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQEmu::versions::maskSoDAndLater, true);
safe_delete(outapp);
}
if (IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::bit_UFAndLater)
if (IsClient() && CastToClient()->ClientVersionBit() & EQEmu::versions::maskUFAndLater)
{
EQApplicationPacket *outapp = MakeBuffsPacket(false);
CastToClient()->FastQueuePacket(&outapp);
@ -5100,7 +5100,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
if (Caston_spell_id) {
if (IsValidSpell(Caston_spell_id) && (Caston_spell_id != spell_id))
SpellFinished(Caston_spell_id, this, EQEmu::CastingSlot::Item, 0, -1, spells[Caston_spell_id].ResistDiff);
SpellFinished(Caston_spell_id, this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[Caston_spell_id].ResistDiff);
}
return (value * lvlModifier / 100);
@ -6663,10 +6663,10 @@ void Mob::TryTriggerThreshHold(int32 damage, int effect_id, Mob* attacker){
if (IsValidSpell(spell_id)) {
if (IsBeneficialSpell(spell_id))
SpellFinished(spell_id, this, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
SpellFinished(spell_id, this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
else if(attacker)
SpellFinished(spell_id, attacker, EQEmu::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
SpellFinished(spell_id, attacker, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff);
}
}
}

View File

@ -107,7 +107,7 @@ extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
extern FastMath g_Math;
using EQEmu::CastingSlot;
using EQEmu::spells::CastingSlot;
// this is run constantly for every mob
void Mob::SpellProcess()
@ -3317,7 +3317,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid
{
EQApplicationPacket *outapp = MakeBuffsPacket();
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQEmu::versions::bit_SoDAndLater);
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQEmu::versions::maskSoDAndLater);
if(IsClient() && GetTarget() == this)
CastToClient()->QueuePacket(outapp);
@ -3327,7 +3327,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid
if (IsNPC()) {
EQApplicationPacket *outapp = MakeBuffsPacket();
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQEmu::versions::bit_SoDAndLater, true);
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQEmu::versions::maskSoDAndLater, true);
safe_delete(outapp);
}
@ -4968,7 +4968,7 @@ void Client::MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message)
void Client::MemSpell(uint16 spell_id, int slot, bool update_client)
{
if(slot >= MAX_PP_MEMSPELL || slot < 0)
if(slot >= EQEmu::spells::SPELL_GEM_COUNT || slot < 0)
return;
if(update_client)
@ -4990,7 +4990,7 @@ void Client::MemSpell(uint16 spell_id, int slot, bool update_client)
void Client::UnmemSpell(int slot, bool update_client)
{
if(slot > MAX_PP_MEMSPELL || slot < 0)
if(slot > EQEmu::spells::SPELL_GEM_COUNT || slot < 0)
return;
Log(Logs::Detail, Logs::Spells, "Spell %d forgotten from slot %d", m_pp.mem_spells[slot], slot);
@ -5006,7 +5006,7 @@ void Client::UnmemSpell(int slot, bool update_client)
void Client::UnmemSpellBySpellID(int32 spell_id)
{
for(int i = 0; i < MAX_PP_MEMSPELL; i++) {
for(int i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; i++) {
if(m_pp.mem_spells[i] == spell_id) {
UnmemSpell(i, true);
break;
@ -5018,14 +5018,14 @@ void Client::UnmemSpellAll(bool update_client)
{
int i;
for(i = 0; i < MAX_PP_MEMSPELL; i++)
for(i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; i++)
if(m_pp.mem_spells[i] != 0xFFFFFFFF)
UnmemSpell(i, update_client);
}
void Client::ScribeSpell(uint16 spell_id, int slot, bool update_client)
{
if(slot >= MAX_PP_SPELLBOOK || slot < 0)
if(slot >= EQEmu::spells::SPELLBOOK_SIZE || slot < 0)
return;
if(update_client)
@ -5046,7 +5046,7 @@ void Client::ScribeSpell(uint16 spell_id, int slot, bool update_client)
void Client::UnscribeSpell(int slot, bool update_client)
{
if(slot >= MAX_PP_SPELLBOOK || slot < 0)
if(slot >= EQEmu::spells::SPELLBOOK_SIZE || slot < 0)
return;
Log(Logs::Detail, Logs::Spells, "Spell %d erased from spell book slot %d", m_pp.spell_book[slot], slot);
@ -5068,7 +5068,7 @@ void Client::UnscribeSpellAll(bool update_client)
{
int i;
for(i = 0; i < MAX_PP_SPELLBOOK; i++)
for(i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
{
if(m_pp.spell_book[i] != 0xFFFFFFFF)
UnscribeSpell(i, update_client);
@ -5102,7 +5102,7 @@ void Client::UntrainDiscAll(bool update_client)
}
int Client::GetNextAvailableSpellBookSlot(int starting_slot) {
for (int i = starting_slot; i < MAX_PP_SPELLBOOK; i++) { //using starting_slot should help speed this up when we're iterating through a bunch of spells
for (int i = starting_slot; i < EQEmu::spells::SPELLBOOK_SIZE; i++) { //using starting_slot should help speed this up when we're iterating through a bunch of spells
if (!IsValidSpell(GetSpellByBookSlot(i)))
return i;
}
@ -5111,7 +5111,7 @@ int Client::GetNextAvailableSpellBookSlot(int starting_slot) {
}
int Client::FindSpellBookSlotBySpellID(uint16 spellid) {
for(int i = 0; i < MAX_PP_SPELLBOOK; i++) {
for(int i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++) {
if(m_pp.spell_book[i] == spellid)
return i;
}
@ -5169,7 +5169,7 @@ bool Client::SpellBucketCheck(uint16 spell_id, uint32 char_id) {
std::string spell_bucket_name;
int spell_bucket_value;
int bucket_value;
std::string query = StringFormat("SELECT key, value FROM spell_buckets WHERE spellid = %i", spell_id);
std::string query = StringFormat("SELECT `key`, value FROM spell_buckets WHERE spellid = %i", spell_id);
auto results = database.QueryDatabase(query);
if (!results.Success())
return false;
@ -5183,7 +5183,7 @@ bool Client::SpellBucketCheck(uint16 spell_id, uint32 char_id) {
if (spell_bucket_name.empty())
return true;
query = StringFormat("SELECT value FROM data_buckets WHERE key = '%i-%s'", char_id, spell_bucket_name.c_str());
query = StringFormat("SELECT value FROM data_buckets WHERE `key` = '%i-%s'", char_id, spell_bucket_name.c_str());
results = database.QueryDatabase(query);
if (!results.Success()) {
Log(Logs::General, Logs::Error, "Spell bucket %s for spell ID %i for char ID %i failed.", spell_bucket_name.c_str(), spell_id, char_id);
@ -5410,7 +5410,7 @@ bool Mob::UseBardSpellLogic(uint16 spell_id, int slot)
spell_id != SPELL_UNKNOWN &&
slot != -1 &&
GetClass() == BARD &&
slot <= MAX_PP_MEMSPELL &&
slot <= EQEmu::spells::SPELL_GEM_COUNT &&
IsBardSong(spell_id)
);
}
@ -5531,7 +5531,7 @@ void Mob::SendBuffsToClient(Client *c)
if(!c)
return;
if (c->ClientVersionBit() & EQEmu::versions::bit_SoDAndLater)
if (c->ClientVersionBit() & EQEmu::versions::maskSoDAndLater)
{
EQApplicationPacket *outapp = MakeBuffsPacket();
c->FastQueuePacket(&outapp);
@ -5619,12 +5619,12 @@ int Client::GetCurrentBuffSlots() const
numbuffs++;
if (GetLevel() > 74)
numbuffs++;
return EQEmu::ClampUpper(numbuffs, EQEmu::constants::Lookup(m_ClientVersion)->LongBuffs);
return EQEmu::ClampUpper(numbuffs, EQEmu::spells::StaticLookup(m_ClientVersion)->LongBuffs);
}
int Client::GetCurrentSongSlots() const
{
return EQEmu::constants::Lookup(m_ClientVersion)->ShortBuffs; // AAs dont affect this
return EQEmu::spells::StaticLookup(m_ClientVersion)->ShortBuffs; // AAs dont affect this
}
void Client::InitializeBuffSlots()

View File

@ -2700,7 +2700,7 @@ void TaskManager::SendTaskActivityShort(Client *c, int TaskID, int ActivityID, i
TaskActivityShort_Struct* tass;
if (c->ClientVersionBit() & EQEmu::versions::bit_RoFAndLater)
if (c->ClientVersionBit() & EQEmu::versions::maskRoFAndLater)
{
auto outapp = new EQApplicationPacket(OP_TaskActivity, 25);
outapp->WriteUInt32(ClientTaskIndex);

View File

@ -135,7 +135,7 @@ void Trap::Trigger(Mob* trigger)
entity_list.MessageClose(trigger,false,100,13,"%s",message.c_str());
}
if(hiddenTrigger){
hiddenTrigger->SpellFinished(effectvalue, trigger, EQEmu::CastingSlot::Item, 0, -1, spells[effectvalue].ResistDiff);
hiddenTrigger->SpellFinished(effectvalue, trigger, EQEmu::spells::CastingSlot::Item, 0, -1, spells[effectvalue].ResistDiff);
}
break;
case trapTypeAlarm:

View File

@ -537,9 +537,6 @@ void NPC::AssignWaypoints(int32 grid)
if (wandertype == 1 || wandertype == 2 || wandertype == 5)
CalculateNewWaypoint();
if (wandertype == 1 || wandertype == 2 || wandertype == 5)
CalculateNewWaypoint();
}
void Mob::SendTo(float new_x, float new_y, float new_z) {

View File

@ -1772,7 +1772,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
zone->GetLongName(),
zone->GetInstanceID()
);
RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset());
RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset(), true);
break;
}
case ServerOP_ReloadLogs: {

View File

@ -904,7 +904,7 @@ bool Zone::Init(bool iStaticZone) {
std::string r_name = RuleManager::Instance()->GetRulesetName(&database, default_ruleset);
if(r_name.size() > 0)
{
RuleManager::Instance()->LoadRules(&database, r_name.c_str());
RuleManager::Instance()->LoadRules(&database, r_name.c_str(), false);
}
}

View File

@ -1204,12 +1204,12 @@ bool ZoneDatabase::LoadCharacterMemmedSpells(uint32 character_id, PlayerProfile_
auto results = database.QueryDatabase(query);
int i = 0;
/* Initialize Spells */
for (i = 0; i < MAX_PP_MEMSPELL; i++){
for (i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; i++){
pp->mem_spells[i] = 0xFFFFFFFF;
}
for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]);
if (i < MAX_PP_MEMSPELL && atoi(row[1]) <= SPDAT_RECORDS){
if (i < EQEmu::spells::SPELL_GEM_COUNT && atoi(row[1]) <= SPDAT_RECORDS){
pp->mem_spells[i] = atoi(row[1]);
}
}
@ -1227,12 +1227,12 @@ bool ZoneDatabase::LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Str
auto results = database.QueryDatabase(query);
int i = 0;
/* Initialize Spells */
for (i = 0; i < MAX_PP_SPELLBOOK; i++){
for (i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++){
pp->spell_book[i] = 0xFFFFFFFF;
}
for (auto row = results.begin(); row != results.end(); ++row) {
i = atoi(row[0]);
if (i < MAX_PP_SPELLBOOK && atoi(row[1]) <= SPDAT_RECORDS){
if (i < EQEmu::spells::SPELLBOOK_SIZE && atoi(row[1]) <= SPDAT_RECORDS){
pp->spell_book[i] = atoi(row[1]);
}
}
@ -1535,7 +1535,7 @@ bool ZoneDatabase::SaveCharacterTribute(uint32 character_id, PlayerProfile_Struc
QueryDatabase(query);
/* Save Tributes only if we have values... */
for (int i = 0; i < EQEmu::invtype::TRIBUTE_SIZE; i++){
if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != TRIBUTE_NONE){
if (pp->tributes[i].tribute >= 0 && pp->tributes[i].tribute != TRIBUTE_NONE){
std::string query = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute);
QueryDatabase(query);
Log(Logs::General, Logs::None, "ZoneDatabase::SaveCharacterTribute for character ID: %i, tier:%u tribute:%u done", character_id, pp->tributes[i].tier, pp->tributes[i].tribute);
@ -3646,7 +3646,7 @@ void ZoneDatabase::LoadBuffs(Client *client)
}
// We load up to the most our client supports
max_slots = EQEmu::constants::Lookup(client->ClientVersion())->LongBuffs;
max_slots = EQEmu::spells::StaticLookup(client->ClientVersion())->LongBuffs;
for (int index = 0; index < max_slots; ++index) {
if (!IsValidSpell(buffs[index].spellid))
continue;

View File

@ -588,7 +588,7 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
// If we are SoF and later and are respawning from hover, we want the real zone ID, else zero to use the old hack.
//
if(zone->GetZoneID() == zoneID) {
if ((ClientVersionBit() & EQEmu::versions::bit_SoFAndLater) && (!RuleB(Character, RespawnFromHover) || !IsHoveringForRespawn()))
if ((ClientVersionBit() & EQEmu::versions::maskSoFAndLater) && (!RuleB(Character, RespawnFromHover) || !IsHoveringForRespawn()))
gmg->bind_zone_id = 0;
else
gmg->bind_zone_id = zoneID;