mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-04 07:23:57 +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)
|
||||
-------------------------------------------------------
|
||||
|
||||
== 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 ==
|
||||
Uleat: Added 'spells' entry to EQDictionary
|
||||
Akkadius:
|
||||
|
||||
@ -243,7 +243,7 @@ namespace EQEmu
|
||||
};
|
||||
|
||||
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 RoF2::spells::LONG_BUFFS;
|
||||
|
||||
@ -1091,6 +1091,18 @@ struct PlayerProfile_Struct
|
||||
/*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005)
|
||||
/*19564*/ uint32 RestTimer;
|
||||
/*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
|
||||
|
||||
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++)
|
||||
{
|
||||
outapp->WriteUInt32(emu->spell_book[r]);
|
||||
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)
|
||||
outapp->WriteUInt32(emu->spell_book[r]);
|
||||
else
|
||||
outapp->WriteUInt32(0xFFFFFFFFU);
|
||||
}
|
||||
}
|
||||
// zeroes for the rest of the spellbook slots
|
||||
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE - EQEmu::spells::SPELLBOOK_SIZE; r++)
|
||||
{
|
||||
outapp->WriteUInt32(0xFFFFFFFFU);
|
||||
else {
|
||||
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++) {
|
||||
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||
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
|
||||
|
||||
@ -2202,14 +2202,25 @@ namespace RoF2
|
||||
|
||||
outapp->WriteUInt32(spells::SPELLBOOK_SIZE); // Spellbook slots
|
||||
|
||||
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++)
|
||||
{
|
||||
outapp->WriteUInt32(emu->spell_book[r]);
|
||||
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)
|
||||
outapp->WriteUInt32(emu->spell_book[r]);
|
||||
else
|
||||
outapp->WriteUInt32(0xFFFFFFFFU);
|
||||
}
|
||||
}
|
||||
// zeroes for the rest of the spellbook slots
|
||||
for (uint32 r = 0; r < spells::SPELLBOOK_SIZE - EQEmu::spells::SPELLBOOK_SIZE; r++)
|
||||
{
|
||||
outapp->WriteUInt32(0xFFFFFFFFU);
|
||||
else {
|
||||
for (uint32 r = 0; r < EQEmu::spells::SPELLBOOK_SIZE; r++) {
|
||||
if (emu->spell_book[r] <= spells::SPELL_ID_MAX)
|
||||
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
|
||||
|
||||
@ -1492,7 +1492,26 @@ namespace SoD
|
||||
OUT(WIS);
|
||||
OUT(face);
|
||||
// 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_array(mem_spells, spells::SPELL_GEM_COUNT);
|
||||
// OUT(unknown04396[32]);
|
||||
|
||||
@ -1156,7 +1156,26 @@ namespace SoF
|
||||
OUT(WIS);
|
||||
OUT(face);
|
||||
// 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_array(mem_spells, spells::SPELL_GEM_COUNT);
|
||||
// OUT(unknown04396[32]);
|
||||
|
||||
@ -1012,7 +1012,26 @@ namespace Titanium
|
||||
OUT(WIS);
|
||||
OUT(face);
|
||||
// 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_array(mem_spells, spells::SPELL_GEM_COUNT);
|
||||
// OUT(unknown04396[32]);
|
||||
|
||||
@ -1724,8 +1724,26 @@ namespace UF
|
||||
OUT(WIS);
|
||||
OUT(face);
|
||||
// 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_array(mem_spells, spells::SPELL_GEM_COUNT);
|
||||
// OUT(unknown04396[32]);
|
||||
|
||||
@ -1446,6 +1446,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
ExtendedProfile_Struct ext;
|
||||
EQEmu::InventoryProfile inv;
|
||||
|
||||
pp.SetPlayerProfileVersion(EQEmu::versions::ConvertClientVersionToMobVersion(EQEmu::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit)));
|
||||
inv.SetInventoryVersion(EQEmu::versions::ConvertClientVersionBitToClientVersion(m_ClientVersionBit));
|
||||
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());
|
||||
|
||||
|
||||
for (i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
|
||||
pp.spell_book[i] = 0xFFFFFFFF;
|
||||
|
||||
for(i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; i++)
|
||||
pp.mem_spells[i] = 0xFFFFFFFF;
|
||||
memset(pp.spell_book, 0xFF, (sizeof(uint32) * EQEmu::spells::SPELLBOOK_SIZE));
|
||||
|
||||
memset(pp.mem_spells, 0xFF, (sizeof(uint32) * EQEmu::spells::SPELL_GEM_COUNT));
|
||||
|
||||
for(i = 0; i < BUFF_COUNT; i++)
|
||||
pp.buffs[i].spellid = 0xFFFF;
|
||||
|
||||
@ -98,6 +98,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
|
||||
PlayerProfile_Struct pp;
|
||||
EQEmu::InventoryProfile inv;
|
||||
|
||||
pp.SetPlayerProfileVersion(EQEmu::versions::ConvertClientVersionToMobVersion(client_version));
|
||||
inv.SetInventoryVersion(client_version);
|
||||
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){
|
||||
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));
|
||||
MemorizeSpell_Struct* mss=(MemorizeSpell_Struct*)outapp->pBuffer;
|
||||
mss->scribing=scribing;
|
||||
@ -9126,4 +9131,4 @@ bool Client::GotoPlayer(std::string player_name)
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,10 +530,14 @@ void Client::CompleteConnect()
|
||||
SendAppearancePacket(AT_GuildID, GuildID(), 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;
|
||||
}
|
||||
}*/
|
||||
|
||||
//SendAATable();
|
||||
|
||||
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());
|
||||
m_ClientVersionBit = EQEmu::versions::ConvertClientVersionToClientVersionBit(Connection()->ClientVersion());
|
||||
|
||||
m_pp.SetPlayerProfileVersion(m_ClientVersion);
|
||||
m_inv.SetInventoryVersion(m_ClientVersion);
|
||||
|
||||
/* 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)))
|
||||
m_pp.RestTimer = 0;
|
||||
|
||||
/* This checksum should disappear once dynamic structs are in... each struct strategy will do it */
|
||||
CRC32::SetEQChecksum((unsigned char*)&m_pp, sizeof(PlayerProfile_Struct) - 4);
|
||||
/* 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) - sizeof(m_pp.m_player_profile_version) - 4);
|
||||
|
||||
outapp = new EQApplicationPacket(OP_PlayerProfile, sizeof(PlayerProfile_Struct));
|
||||
|
||||
@ -5263,7 +5268,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(EQEmu::spells::SPELLBOOK_SIZE))
|
||||
if (dss->spell_slot < 0 || dss->spell_slot >= EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
|
||||
return;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
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());
|
||||
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
|
||||
(
|
||||
|
||||
@ -984,8 +984,15 @@ uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) {
|
||||
bool SpellGlobalCheckResult = 0;
|
||||
bool SpellBucketCheckResult = 0;
|
||||
|
||||
|
||||
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))
|
||||
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
|
||||
(
|
||||
|
||||
@ -5053,7 +5053,7 @@ void Client::UnscribeSpell(int slot, bool update_client)
|
||||
m_pp.spell_book[slot] = 0xFFFFFFFF;
|
||||
|
||||
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));
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
|
||||
for(int i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
|
||||
{
|
||||
if(m_pp.spell_book[i] != 0xFFFFFFFF)
|
||||
UnscribeSpell(i, update_client);
|
||||
|
||||
@ -1225,17 +1225,28 @@ bool ZoneDatabase::LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Str
|
||||
"`character_spells` "
|
||||
"WHERE `id` = %u ORDER BY `slot_id`", character_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
int i = 0;
|
||||
|
||||
/* 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) {
|
||||
i = atoi(row[0]);
|
||||
if (i < EQEmu::spells::SPELLBOOK_SIZE && atoi(row[1]) <= SPDAT_RECORDS){
|
||||
pp->spell_book[i] = atoi(row[1]);
|
||||
}
|
||||
int idx = atoi(row[0]);
|
||||
int id = 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;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user