mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-08 22:32:26 +00:00
Extended server spellbook entries to RoF2 standard and added per-client restriction of spell id max
This commit is contained in:
parent
2d5f0dce42
commit
4658ad676f
@ -1,6 +1,17 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
== 1/24/2019 ==
|
||||||
|
Uleat: Extended server spellbook entries to RoF2 standard and added per-client restriction of spell id max
|
||||||
|
- Bumped server spellbook entry capacity to 720 spells
|
||||||
|
- Server keeps all 'learned' spells as found
|
||||||
|
-- Access is limited by the clients' limitations of spellbook capacities and max spell ids
|
||||||
|
-- This is done to avoid losing spells by switching from newer clients to older ones
|
||||||
|
-- Existing behavior is kept in place for illegal access conditions
|
||||||
|
- Each client is still restricted to its spellbook capacity (400, 480, 480, 720, 720, 720 - respectively)
|
||||||
|
- Each client is restricted to its max supported spell id (9999, 15999, 23000, 28000, 45000, 45000 - respectively)
|
||||||
|
- Please report any abnormal behavior so it may be addressed
|
||||||
|
|
||||||
== 1/20/2019 ==
|
== 1/20/2019 ==
|
||||||
Uleat: Added 'spells' entry to EQDictionary
|
Uleat: Added 'spells' entry to EQDictionary
|
||||||
Akkadius:
|
Akkadius:
|
||||||
|
|||||||
@ -243,7 +243,7 @@ namespace EQEmu
|
|||||||
};
|
};
|
||||||
|
|
||||||
using RoF2::spells::SPELL_ID_MAX;
|
using RoF2::spells::SPELL_ID_MAX;
|
||||||
using SoD::spells::SPELLBOOK_SIZE;
|
using RoF2::spells::SPELLBOOK_SIZE;
|
||||||
using UF::spells::SPELL_GEM_COUNT; // RoF+ clients define more than UF client..but, they are not valid beyond UF
|
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::LONG_BUFFS;
|
||||||
|
|||||||
@ -1091,6 +1091,18 @@ struct PlayerProfile_Struct
|
|||||||
/*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005)
|
/*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005)
|
||||||
/*19564*/ uint32 RestTimer;
|
/*19564*/ uint32 RestTimer;
|
||||||
/*19568*/
|
/*19568*/
|
||||||
|
|
||||||
|
// All player profile packets are translated and this overhead is ignored in out-bound packets
|
||||||
|
PlayerProfile_Struct() : m_player_profile_version(EQEmu::versions::MobVersion::Unknown) { }
|
||||||
|
|
||||||
|
EQEmu::versions::MobVersion PlayerProfileVersion() { return m_player_profile_version; }
|
||||||
|
void SetPlayerProfileVersion(EQEmu::versions::MobVersion mob_version) { m_player_profile_version = EQEmu::versions::ValidateMobVersion(mob_version); }
|
||||||
|
void SetPlayerProfileVersion(EQEmu::versions::ClientVersion client_version) { SetPlayerProfileVersion(EQEmu::versions::ConvertClientVersionToMobVersion(client_version)); }
|
||||||
|
|
||||||
|
// private:
|
||||||
|
// No need for gm flag since pp already has one
|
||||||
|
// No need for lookup pointer since this struct is not tied to any one system
|
||||||
|
EQEmu::versions::MobVersion m_player_profile_version; // kept public for now so checksum can calc sizeof (client_packet.cpp:1586)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2126,14 +2126,25 @@ namespace RoF
|
|||||||
|
|
||||||
outapp->WriteUInt32(spells::SPELLBOOK_SIZE); // Spellbook slots
|
outapp->WriteUInt32(spells::SPELLBOOK_SIZE); // Spellbook slots
|
||||||
|
|
||||||
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++)
|
if (spells::SPELLBOOK_SIZE <= EQEmu::spells::SPELLBOOK_SIZE) {
|
||||||
{
|
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE; r++) {
|
||||||
outapp->WriteUInt32(emu->spell_book[r]);
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
|
outapp->WriteUInt32(emu->spell_book[r]);
|
||||||
|
else
|
||||||
|
outapp->WriteUInt32(0xFFFFFFFFU);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// zeroes for the rest of the spellbook slots
|
else {
|
||||||
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE - EQEmu::spells::SPELLBOOK_SIZE; r++)
|
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++) {
|
||||||
{
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
outapp->WriteUInt32(0xFFFFFFFFU);
|
outapp->WriteUInt32(emu->spell_book[r]);
|
||||||
|
else
|
||||||
|
outapp->WriteUInt32(0xFFFFFFFFU);
|
||||||
|
}
|
||||||
|
// invalidate the rest of the spellbook slots
|
||||||
|
for (uint32 r = EQEmu::spells::SPELLBOOK_SIZE; r < spells::SPELLBOOK_SIZE; r++) {
|
||||||
|
outapp->WriteUInt32(0xFFFFFFFFU);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outapp->WriteUInt32(spells::SPELL_GEM_COUNT); // Memorised spell slots
|
outapp->WriteUInt32(spells::SPELL_GEM_COUNT); // Memorised spell slots
|
||||||
|
|||||||
@ -2202,14 +2202,25 @@ namespace RoF2
|
|||||||
|
|
||||||
outapp->WriteUInt32(spells::SPELLBOOK_SIZE); // Spellbook slots
|
outapp->WriteUInt32(spells::SPELLBOOK_SIZE); // Spellbook slots
|
||||||
|
|
||||||
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++)
|
if (spells::SPELLBOOK_SIZE <= EQEmu::spells::SPELLBOOK_SIZE) {
|
||||||
{
|
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE; r++) {
|
||||||
outapp->WriteUInt32(emu->spell_book[r]);
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
|
outapp->WriteUInt32(emu->spell_book[r]);
|
||||||
|
else
|
||||||
|
outapp->WriteUInt32(0xFFFFFFFFU);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// zeroes for the rest of the spellbook slots
|
else {
|
||||||
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE - EQEmu::spells::SPELLBOOK_SIZE; r++)
|
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++) {
|
||||||
{
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
outapp->WriteUInt32(0xFFFFFFFFU);
|
outapp->WriteUInt32(emu->spell_book[r]);
|
||||||
|
else
|
||||||
|
outapp->WriteUInt32(0xFFFFFFFFU);
|
||||||
|
}
|
||||||
|
// invalidate the rest of the spellbook slots
|
||||||
|
for (uint32 r = EQEmu::spells::SPELLBOOK_SIZE; r < spells::SPELLBOOK_SIZE; r++) {
|
||||||
|
outapp->WriteUInt32(0xFFFFFFFFU);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outapp->WriteUInt32(spells::SPELL_GEM_COUNT); // Memorised spell slots
|
outapp->WriteUInt32(spells::SPELL_GEM_COUNT); // Memorised spell slots
|
||||||
|
|||||||
@ -1492,7 +1492,26 @@ namespace SoD
|
|||||||
OUT(WIS);
|
OUT(WIS);
|
||||||
OUT(face);
|
OUT(face);
|
||||||
// OUT(unknown02264[47]);
|
// OUT(unknown02264[47]);
|
||||||
OUT_array(spell_book, spells::SPELLBOOK_SIZE);
|
|
||||||
|
if (spells::SPELLBOOK_SIZE <= EQEmu::spells::SPELLBOOK_SIZE) {
|
||||||
|
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE; r++) {
|
||||||
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
|
eq->spell_book[r] = emu->spell_book[r];
|
||||||
|
else
|
||||||
|
eq->spell_book[r] = 0xFFFFFFFFU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++) {
|
||||||
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
|
eq->spell_book[r] = emu->spell_book[r];
|
||||||
|
else
|
||||||
|
eq->spell_book[r] = 0xFFFFFFFFU;
|
||||||
|
}
|
||||||
|
// invalidate the rest of the spellbook slots
|
||||||
|
memset(&eq->spell_book[EQEmu::spells::SPELLBOOK_SIZE], 0xFF, (sizeof(uint32) * (spells::SPELLBOOK_SIZE - EQEmu::spells::SPELLBOOK_SIZE)));
|
||||||
|
}
|
||||||
|
|
||||||
// OUT(unknown4184[128]);
|
// OUT(unknown4184[128]);
|
||||||
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
||||||
// OUT(unknown04396[32]);
|
// OUT(unknown04396[32]);
|
||||||
|
|||||||
@ -1156,7 +1156,26 @@ namespace SoF
|
|||||||
OUT(WIS);
|
OUT(WIS);
|
||||||
OUT(face);
|
OUT(face);
|
||||||
// OUT(unknown02264[47]);
|
// OUT(unknown02264[47]);
|
||||||
OUT_array(spell_book, spells::SPELLBOOK_SIZE);
|
|
||||||
|
if (spells::SPELLBOOK_SIZE <= EQEmu::spells::SPELLBOOK_SIZE) {
|
||||||
|
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE; r++) {
|
||||||
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
|
eq->spell_book[r] = emu->spell_book[r];
|
||||||
|
else
|
||||||
|
eq->spell_book[r] = 0xFFFFFFFFU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++) {
|
||||||
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
|
eq->spell_book[r] = emu->spell_book[r];
|
||||||
|
else
|
||||||
|
eq->spell_book[r] = 0xFFFFFFFFU;
|
||||||
|
}
|
||||||
|
// invalidate the rest of the spellbook slots
|
||||||
|
memset(&eq->spell_book[EQEmu::spells::SPELLBOOK_SIZE], 0xFF, (sizeof(uint32) * (spells::SPELLBOOK_SIZE - EQEmu::spells::SPELLBOOK_SIZE)));
|
||||||
|
}
|
||||||
|
|
||||||
// OUT(unknown4184[128]);
|
// OUT(unknown4184[128]);
|
||||||
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
||||||
// OUT(unknown04396[32]);
|
// OUT(unknown04396[32]);
|
||||||
|
|||||||
@ -1012,7 +1012,26 @@ namespace Titanium
|
|||||||
OUT(WIS);
|
OUT(WIS);
|
||||||
OUT(face);
|
OUT(face);
|
||||||
// OUT(unknown02264[47]);
|
// OUT(unknown02264[47]);
|
||||||
OUT_array(spell_book, spells::SPELLBOOK_SIZE);
|
|
||||||
|
if (spells::SPELLBOOK_SIZE <= EQEmu::spells::SPELLBOOK_SIZE) {
|
||||||
|
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE; r++) {
|
||||||
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
|
eq->spell_book[r] = emu->spell_book[r];
|
||||||
|
else
|
||||||
|
eq->spell_book[r] = 0xFFFFFFFFU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++) {
|
||||||
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
|
eq->spell_book[r] = emu->spell_book[r];
|
||||||
|
else
|
||||||
|
eq->spell_book[r] = 0xFFFFFFFFU;
|
||||||
|
}
|
||||||
|
// invalidate the rest of the spellbook slots
|
||||||
|
memset(&eq->spell_book[EQEmu::spells::SPELLBOOK_SIZE], 0xFF, (sizeof(uint32) * (spells::SPELLBOOK_SIZE - EQEmu::spells::SPELLBOOK_SIZE)));
|
||||||
|
}
|
||||||
|
|
||||||
// OUT(unknown4184[448]);
|
// OUT(unknown4184[448]);
|
||||||
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
||||||
// OUT(unknown04396[32]);
|
// OUT(unknown04396[32]);
|
||||||
|
|||||||
@ -1724,8 +1724,26 @@ namespace UF
|
|||||||
OUT(WIS);
|
OUT(WIS);
|
||||||
OUT(face);
|
OUT(face);
|
||||||
// OUT(unknown02264[47]);
|
// OUT(unknown02264[47]);
|
||||||
memset(eq->spell_book, 0xFF, sizeof(uint32)* spells::SPELLBOOK_SIZE);
|
|
||||||
OUT_array(spell_book, 480U);
|
if (spells::SPELLBOOK_SIZE <= EQEmu::spells::SPELLBOOK_SIZE) {
|
||||||
|
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE; r++) {
|
||||||
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
|
eq->spell_book[r] = emu->spell_book[r];
|
||||||
|
else
|
||||||
|
eq->spell_book[r] = 0xFFFFFFFFU;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++) {
|
||||||
|
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||||
|
eq->spell_book[r] = emu->spell_book[r];
|
||||||
|
else
|
||||||
|
eq->spell_book[r] = 0xFFFFFFFFU;
|
||||||
|
}
|
||||||
|
// invalidate the rest of the spellbook slots
|
||||||
|
memset(&eq->spell_book[EQEmu::spells::SPELLBOOK_SIZE], 0xFF, (sizeof(uint32) * (spells::SPELLBOOK_SIZE - EQEmu::spells::SPELLBOOK_SIZE)));
|
||||||
|
}
|
||||||
|
|
||||||
// OUT(unknown4184[128]);
|
// OUT(unknown4184[128]);
|
||||||
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
||||||
// OUT(unknown04396[32]);
|
// OUT(unknown04396[32]);
|
||||||
|
|||||||
@ -1446,6 +1446,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
|||||||
ExtendedProfile_Struct ext;
|
ExtendedProfile_Struct ext;
|
||||||
EQEmu::InventoryProfile inv;
|
EQEmu::InventoryProfile inv;
|
||||||
|
|
||||||
|
pp.SetPlayerProfileVersion(EQEmu::versions::ConvertClientVersionToMobVersion(EQEmu::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit)));
|
||||||
inv.SetInventoryVersion(EQEmu::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit));
|
inv.SetInventoryVersion(EQEmu::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit));
|
||||||
inv.SetGMInventory(false); // character cannot have gm flag at this point
|
inv.SetGMInventory(false); // character cannot have gm flag at this point
|
||||||
|
|
||||||
@ -1528,12 +1529,9 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
|||||||
|
|
||||||
// strcpy(pp.servername, WorldConfig::get()->ShortName.c_str());
|
// strcpy(pp.servername, WorldConfig::get()->ShortName.c_str());
|
||||||
|
|
||||||
|
memset(pp.spell_book, 0xFF, (sizeof(uint32) * EQEmu::spells::SPELLBOOK_SIZE));
|
||||||
for (i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
|
|
||||||
pp.spell_book[i] = 0xFFFFFFFF;
|
memset(pp.mem_spells, 0xFF, (sizeof(uint32) * EQEmu::spells::SPELL_GEM_COUNT));
|
||||||
|
|
||||||
for(i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; i++)
|
|
||||||
pp.mem_spells[i] = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
for(i = 0; i < BUFF_COUNT; i++)
|
for(i = 0; i < BUFF_COUNT; i++)
|
||||||
pp.buffs[i].spellid = 0xFFFF;
|
pp.buffs[i].spellid = 0xFFFF;
|
||||||
|
|||||||
@ -98,6 +98,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
|||||||
PlayerProfile_Struct pp;
|
PlayerProfile_Struct pp;
|
||||||
EQEmu::InventoryProfile inv;
|
EQEmu::InventoryProfile inv;
|
||||||
|
|
||||||
|
pp.SetPlayerProfileVersion(EQEmu::versions::ConvertClientVersionToMobVersion(client_version));
|
||||||
inv.SetInventoryVersion(client_version);
|
inv.SetInventoryVersion(client_version);
|
||||||
inv.SetGMInventory(true); // charsel can not interact with items..but, no harm in setting to full expansion support
|
inv.SetGMInventory(true); // charsel can not interact with items..but, no harm in setting to full expansion support
|
||||||
|
|
||||||
|
|||||||
@ -2640,6 +2640,11 @@ bool Client::CheckAccess(int16 iDBLevel, int16 iDefaultLevel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Client::MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing){
|
void Client::MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing){
|
||||||
|
if (slot < 0 || slot >= EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
|
||||||
|
return;
|
||||||
|
if (spellid < 3 || spellid > EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellIdMax)
|
||||||
|
return;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_MemorizeSpell, sizeof(MemorizeSpell_Struct));
|
auto outapp = new EQApplicationPacket(OP_MemorizeSpell, sizeof(MemorizeSpell_Struct));
|
||||||
MemorizeSpell_Struct* mss=(MemorizeSpell_Struct*)outapp->pBuffer;
|
MemorizeSpell_Struct* mss=(MemorizeSpell_Struct*)outapp->pBuffer;
|
||||||
mss->scribing=scribing;
|
mss->scribing=scribing;
|
||||||
@ -9126,4 +9131,4 @@ bool Client::GotoPlayer(std::string player_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -530,10 +530,14 @@ void Client::CompleteConnect()
|
|||||||
SendAppearancePacket(AT_GuildID, GuildID(), false);
|
SendAppearancePacket(AT_GuildID, GuildID(), false);
|
||||||
SendAppearancePacket(AT_GuildRank, rank, false);
|
SendAppearancePacket(AT_GuildRank, rank, false);
|
||||||
}
|
}
|
||||||
for (uint32 spellInt = 0; spellInt < EQEmu::spells::SPELLBOOK_SIZE; spellInt++) {
|
|
||||||
if (m_pp.spell_book[spellInt] < 3 || m_pp.spell_book[spellInt] > 50000)
|
// moved to dbload and translators since we iterate there also .. keep m_pp values whatever they are when they get here
|
||||||
|
/*const auto sbs = EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize;
|
||||||
|
for (uint32 spellInt = 0; spellInt < sbs; ++spellInt) {
|
||||||
|
if (m_pp.spell_book[spellInt] < 3 || m_pp.spell_book[spellInt] > EQEmu::spells::SPELL_ID_MAX)
|
||||||
m_pp.spell_book[spellInt] = 0xFFFFFFFF;
|
m_pp.spell_book[spellInt] = 0xFFFFFFFF;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
//SendAATable();
|
//SendAATable();
|
||||||
|
|
||||||
if (GetHideMe()) Message(13, "[GM] You are currently hidden to all clients");
|
if (GetHideMe()) Message(13, "[GM] You are currently hidden to all clients");
|
||||||
@ -1154,6 +1158,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
SetClientVersion(Connection()->ClientVersion());
|
SetClientVersion(Connection()->ClientVersion());
|
||||||
m_ClientVersionBit = EQEmu::versions::ConvertClientVersionToClientVersionBit(Connection()->ClientVersion());
|
m_ClientVersionBit = EQEmu::versions::ConvertClientVersionToClientVersionBit(Connection()->ClientVersion());
|
||||||
|
|
||||||
|
m_pp.SetPlayerProfileVersion(m_ClientVersion);
|
||||||
m_inv.SetInventoryVersion(m_ClientVersion);
|
m_inv.SetInventoryVersion(m_ClientVersion);
|
||||||
|
|
||||||
/* Antighost code
|
/* Antighost code
|
||||||
@ -1587,8 +1592,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
if ((m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate)) && (m_pp.RestTimer > RuleI(Character, RestRegenRaidTimeToActivate)))
|
if ((m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate)) && (m_pp.RestTimer > RuleI(Character, RestRegenRaidTimeToActivate)))
|
||||||
m_pp.RestTimer = 0;
|
m_pp.RestTimer = 0;
|
||||||
|
|
||||||
/* This checksum should disappear once dynamic structs are in... each struct strategy will do it */
|
/* This checksum should disappear once dynamic structs are in... each struct strategy will do it */ // looks to be in place now
|
||||||
CRC32::SetEQChecksum((unsigned char*)&m_pp, sizeof(PlayerProfile_Struct) - 4);
|
CRC32::SetEQChecksum((unsigned char*)&m_pp, sizeof(PlayerProfile_Struct) - sizeof(m_pp.m_player_profile_version) - 4);
|
||||||
|
|
||||||
outapp = new EQApplicationPacket(OP_PlayerProfile, sizeof(PlayerProfile_Struct));
|
outapp = new EQApplicationPacket(OP_PlayerProfile, sizeof(PlayerProfile_Struct));
|
||||||
|
|
||||||
@ -5263,7 +5268,7 @@ void Client::Handle_OP_DeleteSpell(const EQApplicationPacket *app)
|
|||||||
EQApplicationPacket* outapp = app->Copy();
|
EQApplicationPacket* outapp = app->Copy();
|
||||||
DeleteSpell_Struct* dss = (DeleteSpell_Struct*)outapp->pBuffer;
|
DeleteSpell_Struct* dss = (DeleteSpell_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
if (dss->spell_slot < 0 || dss->spell_slot > int(EQEmu::spells::SPELLBOOK_SIZE))
|
if (dss->spell_slot < 0 || dss->spell_slot >= EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_pp.spell_book[dss->spell_slot] != SPELLBOOK_UNKNOWN) {
|
if (m_pp.spell_book[dss->spell_slot] != SPELLBOOK_UNKNOWN) {
|
||||||
@ -13337,7 +13342,10 @@ void Client::Handle_OP_SwapSpell(const EQApplicationPacket *app)
|
|||||||
const SwapSpell_Struct* swapspell = (const SwapSpell_Struct*)app->pBuffer;
|
const SwapSpell_Struct* swapspell = (const SwapSpell_Struct*)app->pBuffer;
|
||||||
int swapspelltemp;
|
int swapspelltemp;
|
||||||
|
|
||||||
if (swapspell->from_slot < 0 || swapspell->from_slot > EQEmu::spells::SPELLBOOK_SIZE || swapspell->to_slot < 0 || swapspell->to_slot > EQEmu::spells::SPELLBOOK_SIZE)
|
const auto sbs = EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize;
|
||||||
|
if (swapspell->from_slot < 0 || swapspell->from_slot >= sbs)
|
||||||
|
return;
|
||||||
|
if (swapspell->to_slot < 0 || swapspell->to_slot >= sbs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
swapspelltemp = m_pp.spell_book[swapspell->from_slot];
|
swapspelltemp = m_pp.spell_book[swapspell->from_slot];
|
||||||
|
|||||||
@ -6441,7 +6441,15 @@ void command_scribespells(Client *c, const Seperator *sep)
|
|||||||
c->Message(0, "Scribing spells for %s.", t->GetName());
|
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);
|
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 < EQEmu::spells::SPELLBOOK_SIZE; 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
|
if
|
||||||
(
|
(
|
||||||
|
|||||||
@ -984,8 +984,15 @@ uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) {
|
|||||||
bool SpellGlobalCheckResult = 0;
|
bool SpellGlobalCheckResult = 0;
|
||||||
bool SpellBucketCheckResult = 0;
|
bool SpellBucketCheckResult = 0;
|
||||||
|
|
||||||
|
for (
|
||||||
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))
|
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
|
if
|
||||||
(
|
(
|
||||||
|
|||||||
@ -5053,7 +5053,7 @@ void Client::UnscribeSpell(int slot, bool update_client)
|
|||||||
m_pp.spell_book[slot] = 0xFFFFFFFF;
|
m_pp.spell_book[slot] = 0xFFFFFFFF;
|
||||||
|
|
||||||
database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[slot], slot);
|
database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[slot], slot);
|
||||||
if(update_client)
|
if(update_client && slot < EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
|
||||||
{
|
{
|
||||||
auto outapp = new EQApplicationPacket(OP_DeleteSpell, sizeof(DeleteSpell_Struct));
|
auto outapp = new EQApplicationPacket(OP_DeleteSpell, sizeof(DeleteSpell_Struct));
|
||||||
DeleteSpell_Struct* del = (DeleteSpell_Struct*)outapp->pBuffer;
|
DeleteSpell_Struct* del = (DeleteSpell_Struct*)outapp->pBuffer;
|
||||||
@ -5066,9 +5066,7 @@ void Client::UnscribeSpell(int slot, bool update_client)
|
|||||||
|
|
||||||
void Client::UnscribeSpellAll(bool update_client)
|
void Client::UnscribeSpellAll(bool update_client)
|
||||||
{
|
{
|
||||||
int i;
|
for(int i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
|
||||||
|
|
||||||
for(i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
|
|
||||||
{
|
{
|
||||||
if(m_pp.spell_book[i] != 0xFFFFFFFF)
|
if(m_pp.spell_book[i] != 0xFFFFFFFF)
|
||||||
UnscribeSpell(i, update_client);
|
UnscribeSpell(i, update_client);
|
||||||
|
|||||||
@ -1225,17 +1225,28 @@ bool ZoneDatabase::LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Str
|
|||||||
"`character_spells` "
|
"`character_spells` "
|
||||||
"WHERE `id` = %u ORDER BY `slot_id`", character_id);
|
"WHERE `id` = %u ORDER BY `slot_id`", character_id);
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
int i = 0;
|
|
||||||
/* Initialize Spells */
|
/* Initialize Spells */
|
||||||
for (i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++){
|
|
||||||
pp->spell_book[i] = 0xFFFFFFFF;
|
memset(pp->spell_book, 0xFF, (sizeof(uint32) * EQEmu::spells::SPELLBOOK_SIZE));
|
||||||
}
|
|
||||||
|
// We have the ability to block loaded spells by max id on a per-client basis..
|
||||||
|
// but, we do not have to ability to keep players from using older clients after
|
||||||
|
// they have scribed spells on a newer one that exceeds the older one's limit.
|
||||||
|
// Load them all so that server actions are valid..but, nix them in translators.
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
i = atoi(row[0]);
|
int idx = atoi(row[0]);
|
||||||
if (i < EQEmu::spells::SPELLBOOK_SIZE && atoi(row[1]) <= SPDAT_RECORDS){
|
int id = atoi(row[1]);
|
||||||
pp->spell_book[i] = atoi(row[1]);
|
|
||||||
}
|
if (idx < 0 || idx >= EQEmu::spells::SPELLBOOK_SIZE)
|
||||||
|
continue;
|
||||||
|
if (id < 3 || id > SPDAT_RECORDS) // 3 ("Summon Corpse") is the first scribable spell in spells_us.txt
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pp->spell_book[idx] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user