mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
Updated to client build 11723.
This commit is contained in:
parent
811f0e7ebf
commit
dd3d5eec69
14 changed files with 102 additions and 110 deletions
|
|
@ -3989,7 +3989,7 @@ void ChatHandler::HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id)
|
||||||
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,player,false))
|
if(!spellInfo || !SpellMgr::IsSpellValid(spellInfo,player,false))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
player->learnSpell(skillLine->spellId,false);
|
player->learnSpell(skillLine->spellId, 0, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1817,7 +1817,7 @@ bool ChatHandler::HandleLearnAllCommand(const char* /*args*/)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_session->GetPlayer()->learnSpell(spell,false);
|
m_session->GetPlayer()->learnSpell(spell, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
|
SendSysMessage(LANG_COMMAND_LEARN_MANY_SPELLS);
|
||||||
|
|
@ -1857,7 +1857,7 @@ bool ChatHandler::HandleLearnAllGMCommand(const char* /*args*/)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_session->GetPlayer()->learnSpell(spell,false);
|
m_session->GetPlayer()->learnSpell(spell, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSysMessage(LANG_LEARNING_GM_SKILLS);
|
SendSysMessage(LANG_LEARNING_GM_SKILLS);
|
||||||
|
|
@ -1905,7 +1905,7 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)
|
||||||
if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
|
if(!SpellMgr::IsSpellValid(spellInfo,m_session->GetPlayer(),false))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_session->GetPlayer()->learnSpell(i,false);
|
m_session->GetPlayer()->learnSpell(i, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
|
SendSysMessage(LANG_COMMAND_LEARN_CLASS_SPELLS);
|
||||||
|
|
@ -2037,7 +2037,7 @@ bool ChatHandler::HandleLearnAllLangCommand(const char* /*args*/)
|
||||||
{
|
{
|
||||||
// skipping UNIVERSAL language (0)
|
// skipping UNIVERSAL language (0)
|
||||||
for(int i = 1; i < LANGUAGES_COUNT; ++i)
|
for(int i = 1; i < LANGUAGES_COUNT; ++i)
|
||||||
m_session->GetPlayer()->learnSpell(lang_description[i].spell_id,false);
|
m_session->GetPlayer()->learnSpell(lang_description[i].spell_id, 0, false);
|
||||||
|
|
||||||
SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
|
SendSysMessage(LANG_COMMAND_LEARN_ALL_LANG);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -2096,7 +2096,7 @@ bool ChatHandler::HandleLearnCommand(const char* args)
|
||||||
if(allRanks)
|
if(allRanks)
|
||||||
targetPlayer->learnSpellHighRank(spell);
|
targetPlayer->learnSpellHighRank(spell);
|
||||||
else
|
else
|
||||||
targetPlayer->learnSpell(spell,false);
|
targetPlayer->learnSpell(spell, 0, false);
|
||||||
|
|
||||||
uint32 first_spell = sSpellMgr.GetFirstSpellInChain(spell);
|
uint32 first_spell = sSpellMgr.GetFirstSpellInChain(spell);
|
||||||
if(GetTalentSpellCost(first_spell))
|
if(GetTalentSpellCost(first_spell))
|
||||||
|
|
|
||||||
|
|
@ -41,17 +41,7 @@
|
||||||
#include "BattleGroundMgr.h"
|
#include "BattleGroundMgr.h"
|
||||||
#include "Item.h"
|
#include "Item.h"
|
||||||
#include "AuctionHouseMgr.h"
|
#include "AuctionHouseMgr.h"
|
||||||
/**
|
|
||||||
* Flags that specify special action to be take by the client when displaying this mail.
|
|
||||||
*/
|
|
||||||
enum MailShowFlags
|
|
||||||
{
|
|
||||||
MAIL_SHOW_UNK0 = 0x0001,
|
|
||||||
MAIL_SHOW_DELETE = 0x0002, ///< forced show of the delete button instead of the return button
|
|
||||||
MAIL_SHOW_AUCTION = 0x0004, ///< from old comment
|
|
||||||
MAIL_SHOW_UNK2 = 0x0008, ///< unknown, COD will be shown even without that flag
|
|
||||||
MAIL_SHOW_RETURN = 0x0010,
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* Handles the Packet sent by the client when sending a mail.
|
* Handles the Packet sent by the client when sending a mail.
|
||||||
*
|
*
|
||||||
|
|
@ -168,7 +158,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
|
// do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
|
||||||
if (mails_count > 100)
|
if (mails_count > 100)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED);
|
||||||
|
|
@ -312,8 +302,8 @@ void WorldSession::HandleMailMarkAsRead(WorldPacket & recv_data )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Player *pl = _player;
|
Player *pl = _player;
|
||||||
Mail *m = pl->GetMail(mailId);
|
|
||||||
if (m)
|
if (Mail *m = pl->GetMail(mailId))
|
||||||
{
|
{
|
||||||
if (pl->unReadMails)
|
if (pl->unReadMails)
|
||||||
--pl->unReadMails;
|
--pl->unReadMails;
|
||||||
|
|
@ -344,8 +334,8 @@ void WorldSession::HandleMailDelete(WorldPacket & recv_data )
|
||||||
|
|
||||||
Player* pl = _player;
|
Player* pl = _player;
|
||||||
pl->m_mailsUpdated = true;
|
pl->m_mailsUpdated = true;
|
||||||
Mail *m = pl->GetMail(mailId);
|
|
||||||
if(m)
|
if(Mail *m = pl->GetMail(mailId))
|
||||||
{
|
{
|
||||||
// delete shouldn't show up for COD mails
|
// delete shouldn't show up for COD mails
|
||||||
if (m->COD)
|
if (m->COD)
|
||||||
|
|
@ -385,6 +375,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
||||||
pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_ERR_INTERNAL_ERROR);
|
pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_ERR_INTERNAL_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//we can return mail now
|
//we can return mail now
|
||||||
//so firstly delete the old one
|
//so firstly delete the old one
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
|
|
@ -399,19 +390,14 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
MailDraft draft(m->subject, m->body);
|
MailDraft draft(m->subject, m->body);
|
||||||
if (m->mailTemplateId)
|
if (m->mailTemplateId)
|
||||||
draft = MailDraft(m->mailTemplateId,false); // items already included
|
draft = MailDraft(m->mailTemplateId, false); // items already included
|
||||||
|
|
||||||
if(m->HasItems())
|
if(m->HasItems())
|
||||||
{
|
{
|
||||||
for(std::vector<MailItemInfo>::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
|
for(std::vector<MailItemInfo>::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
|
||||||
{
|
{
|
||||||
Item *item = pl->GetMItem(itr2->item_guid);
|
if(Item *item = pl->GetMItem(itr2->item_guid))
|
||||||
if(item)
|
|
||||||
draft.AddItem(item);
|
draft.AddItem(item);
|
||||||
else
|
|
||||||
{
|
|
||||||
//WTF?
|
|
||||||
}
|
|
||||||
|
|
||||||
pl->RemoveMItem(itr2->item_guid);
|
pl->RemoveMItem(itr2->item_guid);
|
||||||
}
|
}
|
||||||
|
|
@ -559,7 +545,7 @@ void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the packet sent by the client when requesting the current mail list.
|
* Handles the packet sent by the client when requesting the current mail list.
|
||||||
* It will send a list of all avaible mails in the players mailbox to the client.
|
* It will send a list of all available mails in the players mailbox to the client.
|
||||||
*/
|
*/
|
||||||
void WorldSession::HandleGetMailList(WorldPacket & recv_data )
|
void WorldSession::HandleGetMailList(WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
|
|
@ -625,7 +611,7 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data )
|
||||||
data << uint32((*itr)->COD); // COD
|
data << uint32((*itr)->COD); // COD
|
||||||
data << uint32(0); // unknown, probably changed in 3.3.3
|
data << uint32(0); // unknown, probably changed in 3.3.3
|
||||||
data << uint32((*itr)->stationery); // stationery (Stationery.dbc)
|
data << uint32((*itr)->stationery); // stationery (Stationery.dbc)
|
||||||
data << uint32((*itr)->money); // Gold
|
data << uint32((*itr)->money); // copper
|
||||||
data << uint32((*itr)->checked); // flags
|
data << uint32((*itr)->checked); // flags
|
||||||
data << float(((*itr)->expire_time-time(NULL))/DAY);// Time
|
data << float(((*itr)->expire_time-time(NULL))/DAY);// Time
|
||||||
data << uint32((*itr)->mailTemplateId); // mail template (MailTemplate.dbc)
|
data << uint32((*itr)->mailTemplateId); // mail template (MailTemplate.dbc)
|
||||||
|
|
@ -693,20 +679,18 @@ void WorldSession::HandleItemTextQuery(WorldPacket & recv_data )
|
||||||
|
|
||||||
sLog.outDebug("CMSG_ITEM_TEXT_QUERY item guid: %u", GUID_LOPART(itemGuid));
|
sLog.outDebug("CMSG_ITEM_TEXT_QUERY item guid: %u", GUID_LOPART(itemGuid));
|
||||||
|
|
||||||
WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, (4+10));// guess size
|
WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, (4+10)); // guess size
|
||||||
|
|
||||||
Item *item = _player->GetItemByGuid(itemGuid);
|
if(Item *item = _player->GetItemByGuid(itemGuid))
|
||||||
|
|
||||||
if(!item)
|
|
||||||
{
|
|
||||||
data << uint8(1); // no text
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
data << uint8(0); // has text
|
data << uint8(0); // has text
|
||||||
data << uint64(itemGuid); // item guid
|
data << uint64(itemGuid); // item guid
|
||||||
data << sObjectMgr.GetItemText(item->GetGUIDLow()); // max 8000
|
data << sObjectMgr.GetItemText(item->GetGUIDLow()); // max 8000
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data << uint8(1); // no text
|
||||||
|
}
|
||||||
SendPacket(&data);
|
SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -787,7 +771,6 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
|
||||||
*/
|
*/
|
||||||
void WorldSession::HandleQueryNextMailTime(WorldPacket & /**recv_data*/ )
|
void WorldSession::HandleQueryNextMailTime(WorldPacket & /**recv_data*/ )
|
||||||
{
|
{
|
||||||
//TODO Fix me! ... this void has probably bad condition, but good data are sent
|
|
||||||
WorldPacket data(MSG_QUERY_NEXT_MAIL_TIME, 8);
|
WorldPacket data(MSG_QUERY_NEXT_MAIL_TIME, 8);
|
||||||
|
|
||||||
if( _player->unReadMails > 0 )
|
if( _player->unReadMails > 0 )
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle )
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldPacket data( SMSG_TRAINER_LIST, 8+4+4+trainer_spells->spellList.size()*38 + strTitle.size()+1);
|
WorldPacket data( SMSG_TRAINER_LIST, 8+4+4+trainer_spells->spellList.size()*38 + strTitle.size()+1);
|
||||||
data << guid;
|
data << uint64(guid);
|
||||||
data << uint32(trainer_spells->trainerType);
|
data << uint32(trainer_spells->trainerType);
|
||||||
|
|
||||||
size_t count_pos = data.wpos();
|
size_t count_pos = data.wpos();
|
||||||
|
|
@ -230,22 +230,24 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
|
||||||
_player->ModifyMoney( -int32(nSpellCost) );
|
_player->ModifyMoney( -int32(nSpellCost) );
|
||||||
|
|
||||||
WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer
|
WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer
|
||||||
data << uint64(guid) << uint32(0xB3);
|
data << uint64(guid);
|
||||||
|
data << uint32(0xB3); // index from SpellVisualKit.dbc
|
||||||
SendPacket(&data);
|
SendPacket(&data);
|
||||||
|
|
||||||
data.Initialize(SMSG_PLAY_SPELL_IMPACT, 12); // visual effect on player
|
data.Initialize(SMSG_PLAY_SPELL_IMPACT, 12); // visual effect on player
|
||||||
data << uint64(_player->GetGUID()) << uint32(0x016A);
|
data << uint64(_player->GetGUID());
|
||||||
|
data << uint32(0x016A); // index from SpellVisualKit.dbc
|
||||||
SendPacket(&data);
|
SendPacket(&data);
|
||||||
|
|
||||||
// learn explicitly or cast explicitly
|
// learn explicitly or cast explicitly
|
||||||
if(trainer_spell->IsCastable ())
|
if(trainer_spell->IsCastable())
|
||||||
//FIXME: prof. spell entry in trainer list not marked gray until list re-open.
|
_player->CastSpell(_player, trainer_spell->spell, true);
|
||||||
_player->CastSpell(_player,trainer_spell->spell,true);
|
|
||||||
else
|
else
|
||||||
_player->learnSpell(spellId,false);
|
_player->learnSpell(spellId, 0, false);
|
||||||
|
|
||||||
data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12);
|
data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12);
|
||||||
data << uint64(guid) << uint32(trainer_spell->spell);
|
data << uint64(guid);
|
||||||
|
data << uint32(trainer_spell->spell);
|
||||||
SendPacket(&data);
|
SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -470,7 +470,7 @@ enum Opcodes
|
||||||
SMSG_TRAINER_LIST = 0x1B1,
|
SMSG_TRAINER_LIST = 0x1B1,
|
||||||
CMSG_TRAINER_BUY_SPELL = 0x1B2,
|
CMSG_TRAINER_BUY_SPELL = 0x1B2,
|
||||||
SMSG_TRAINER_BUY_SUCCEEDED = 0x1B3,
|
SMSG_TRAINER_BUY_SUCCEEDED = 0x1B3,
|
||||||
SMSG_TRAINER_BUY_FAILED = 0x1B4,
|
SMSG_TRAINER_BUY_FAILED = 0x1B4, // uint64, uint32, uint32 (0...2)
|
||||||
CMSG_BINDER_ACTIVATE = 0x1B5,
|
CMSG_BINDER_ACTIVATE = 0x1B5,
|
||||||
SMSG_PLAYERBINDERROR = 0x1B6,
|
SMSG_PLAYERBINDERROR = 0x1B6,
|
||||||
CMSG_BANKER_ACTIVATE = 0x1B7,
|
CMSG_BANKER_ACTIVATE = 0x1B7,
|
||||||
|
|
|
||||||
|
|
@ -2957,7 +2957,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||||
if(active)
|
if(active)
|
||||||
{
|
{
|
||||||
if (IsPassiveSpell(spell_id) && IsNeedCastPassiveSpellAtLearn(spellInfo))
|
if (IsPassiveSpell(spell_id) && IsNeedCastPassiveSpellAtLearn(spellInfo))
|
||||||
CastSpell (this,spell_id,true);
|
CastSpell (this, spell_id, true);
|
||||||
}
|
}
|
||||||
else if(IsInWorld())
|
else if(IsInWorld())
|
||||||
{
|
{
|
||||||
|
|
@ -3023,10 +3023,10 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||||
{
|
{
|
||||||
// skip learning spell and no rank spell case
|
// skip learning spell and no rank spell case
|
||||||
uint32 rankSpellId = talentInfo->RankID[i];
|
uint32 rankSpellId = talentInfo->RankID[i];
|
||||||
if(!rankSpellId || rankSpellId==spell_id)
|
if(!rankSpellId || rankSpellId == spell_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
removeSpell(rankSpellId,false,false);
|
removeSpell(rankSpellId, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3034,9 +3034,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||||
else if(uint32 prev_spell = sSpellMgr.GetPrevSpellInChain(spell_id))
|
else if(uint32 prev_spell = sSpellMgr.GetPrevSpellInChain(spell_id))
|
||||||
{
|
{
|
||||||
if(!IsInWorld() || disabled) // at spells loading, no output, but allow save
|
if(!IsInWorld() || disabled) // at spells loading, no output, but allow save
|
||||||
addSpell(prev_spell,active,true,true,disabled);
|
addSpell(prev_spell, active, true, true, disabled);
|
||||||
else // at normal learning
|
else // at normal learning
|
||||||
learnSpell(prev_spell,true);
|
learnSpell(prev_spell, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerSpell newspell;
|
PlayerSpell newspell;
|
||||||
|
|
@ -3054,7 +3054,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||||
SpellEntry const *i_spellInfo = sSpellStore.LookupEntry(itr2->first);
|
SpellEntry const *i_spellInfo = sSpellStore.LookupEntry(itr2->first);
|
||||||
if(!i_spellInfo) continue;
|
if(!i_spellInfo) continue;
|
||||||
|
|
||||||
if( sSpellMgr.IsRankSpellDueToSpell(spellInfo,itr2->first) )
|
if( sSpellMgr.IsRankSpellDueToSpell(spellInfo, itr2->first) )
|
||||||
{
|
{
|
||||||
if(itr2->second.active)
|
if(itr2->second.active)
|
||||||
{
|
{
|
||||||
|
|
@ -3198,7 +3198,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||||
if (!IsInWorld() || !itr2->second.active) // at spells loading, no output, but allow save
|
if (!IsInWorld() || !itr2->second.active) // at spells loading, no output, but allow save
|
||||||
addSpell(itr2->second.spell,itr2->second.active,true,true,false);
|
addSpell(itr2->second.spell,itr2->second.active,true,true,false);
|
||||||
else // at normal learning
|
else // at normal learning
|
||||||
learnSpell(itr2->second.spell,true);
|
learnSpell(itr2->second.spell, 0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3228,14 +3228,14 @@ bool Player::IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const
|
||||||
return need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState)));
|
return need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraState(spellInfo->CasterAuraState)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::learnSpell(uint32 spell_id, bool dependent)
|
void Player::learnSpell(uint32 spell_id, uint32 triggeredBySpell, bool dependent)
|
||||||
{
|
{
|
||||||
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
|
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
|
||||||
|
|
||||||
bool disabled = (itr != m_spells.end()) ? itr->second.disabled : false;
|
bool disabled = (itr != m_spells.end()) ? itr->second.disabled : false;
|
||||||
bool active = disabled ? itr->second.active : true;
|
bool active = disabled ? itr->second.active : true;
|
||||||
|
|
||||||
bool learning = addSpell(spell_id,active,true,dependent,false);
|
bool learning = addSpell(spell_id, active, true, dependent, false);
|
||||||
|
|
||||||
// learn all disabled higher ranks (recursive)
|
// learn all disabled higher ranks (recursive)
|
||||||
if(disabled)
|
if(disabled)
|
||||||
|
|
@ -3245,7 +3245,7 @@ void Player::learnSpell(uint32 spell_id, bool dependent)
|
||||||
{
|
{
|
||||||
PlayerSpellMap::iterator iter = m_spells.find(i->second);
|
PlayerSpellMap::iterator iter = m_spells.find(i->second);
|
||||||
if (iter != m_spells.end() && iter->second.disabled)
|
if (iter != m_spells.end() && iter->second.disabled)
|
||||||
learnSpell(i->second,false);
|
learnSpell(i->second, 0, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3253,8 +3253,9 @@ void Player::learnSpell(uint32 spell_id, bool dependent)
|
||||||
if(!learning || !IsInWorld ())
|
if(!learning || !IsInWorld ())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WorldPacket data(SMSG_LEARNED_SPELL, 4);
|
WorldPacket data(SMSG_LEARNED_SPELL, 6);
|
||||||
data << uint32(spell_id);
|
data << uint32((triggeredBySpell == 0) ? spell_id : triggeredBySpell);
|
||||||
|
data << uint16(0);
|
||||||
GetSession()->SendPacket(&data);
|
GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3400,7 +3401,7 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank, bo
|
||||||
if (talentCosts)
|
if (talentCosts)
|
||||||
{
|
{
|
||||||
if(learn_low_rank)
|
if(learn_low_rank)
|
||||||
learnSpell (prev_id,false);
|
learnSpell(prev_id, 0, false);
|
||||||
}
|
}
|
||||||
// if ranked non-stackable spell: need activate lesser rank and update dendence state
|
// if ranked non-stackable spell: need activate lesser rank and update dendence state
|
||||||
else if (cur_active && !SpellMgr::canStackSpellRanks(spellInfo) && sSpellMgr.GetSpellRank(spellInfo->Id) != 0)
|
else if (cur_active && !SpellMgr::canStackSpellRanks(spellInfo) && sSpellMgr.GetSpellRank(spellInfo->Id) != 0)
|
||||||
|
|
@ -5165,10 +5166,10 @@ bool Player::UpdateCraftSkill(uint32 spellid)
|
||||||
|
|
||||||
// Alchemy Discoveries here
|
// Alchemy Discoveries here
|
||||||
SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellid);
|
SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellid);
|
||||||
if (spellEntry && spellEntry->Mechanic==MECHANIC_DISCOVERY)
|
if (spellEntry && spellEntry->Mechanic == MECHANIC_DISCOVERY)
|
||||||
{
|
{
|
||||||
if (uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->skillId, spellid, this))
|
if (uint32 discoveredSpell = GetSkillDiscoverySpell(_spell_idx->second->skillId, spellid, this))
|
||||||
learnSpell(discoveredSpell,false);
|
learnSpell(discoveredSpell, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 craft_skill_gain = sWorld.getConfig(CONFIG_UINT32_SKILL_GAIN_CRAFTING);
|
uint32 craft_skill_gain = sWorld.getConfig(CONFIG_UINT32_SKILL_GAIN_CRAFTING);
|
||||||
|
|
@ -19208,9 +19209,9 @@ void Player::learnDefaultSpells()
|
||||||
uint32 tspell = *itr;
|
uint32 tspell = *itr;
|
||||||
sLog.outDebug("PLAYER (Class: %u Race: %u): Adding initial spell, id = %u",uint32(getClass()),uint32(getRace()), tspell);
|
sLog.outDebug("PLAYER (Class: %u Race: %u): Adding initial spell, id = %u",uint32(getClass()),uint32(getRace()), tspell);
|
||||||
if(!IsInWorld()) // will send in INITIAL_SPELLS in list anyway at map add
|
if(!IsInWorld()) // will send in INITIAL_SPELLS in list anyway at map add
|
||||||
addSpell(tspell,true,true,true,false);
|
addSpell(tspell, true, true, true, false);
|
||||||
else // but send in normal spell in game learn case
|
else // but send in normal spell in game learn case
|
||||||
learnSpell(tspell,true);
|
learnSpell(tspell, 0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -19306,7 +19307,7 @@ void Player::learnSkillRewardedSpells(uint32 skill_id, uint32 skill_value )
|
||||||
{
|
{
|
||||||
uint32 raceMask = getRaceMask();
|
uint32 raceMask = getRaceMask();
|
||||||
uint32 classMask = getClassMask();
|
uint32 classMask = getClassMask();
|
||||||
for (uint32 j=0; j<sSkillLineAbilityStore.GetNumRows(); ++j)
|
for (uint32 j = 0; j<sSkillLineAbilityStore.GetNumRows(); ++j)
|
||||||
{
|
{
|
||||||
SkillLineAbilityEntry const *pAbility = sSkillLineAbilityStore.LookupEntry(j);
|
SkillLineAbilityEntry const *pAbility = sSkillLineAbilityStore.LookupEntry(j);
|
||||||
if (!pAbility || pAbility->skillId!=skill_id || pAbility->learnOnGetSkill != ABILITY_LEARNED_ON_GET_PROFESSION_SKILL)
|
if (!pAbility || pAbility->skillId!=skill_id || pAbility->learnOnGetSkill != ABILITY_LEARNED_ON_GET_PROFESSION_SKILL)
|
||||||
|
|
@ -19325,9 +19326,9 @@ void Player::learnSkillRewardedSpells(uint32 skill_id, uint32 skill_value )
|
||||||
removeSpell(pAbility->spellId);
|
removeSpell(pAbility->spellId);
|
||||||
// need learn
|
// need learn
|
||||||
else if (!IsInWorld())
|
else if (!IsInWorld())
|
||||||
addSpell(pAbility->spellId,true,true,true,false);
|
addSpell(pAbility->spellId, true, true, true, false);
|
||||||
else
|
else
|
||||||
learnSpell(pAbility->spellId,true);
|
learnSpell(pAbility->spellId, 0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -20614,16 +20615,16 @@ bool Player::IsKnowHowFlyIn(uint32 mapid, uint32 zone) const
|
||||||
struct DoPlayerLearnSpell
|
struct DoPlayerLearnSpell
|
||||||
{
|
{
|
||||||
DoPlayerLearnSpell(Player& _player) : player(_player) {}
|
DoPlayerLearnSpell(Player& _player) : player(_player) {}
|
||||||
void operator() (uint32 spell_id) { player.learnSpell(spell_id,false); }
|
void operator() (uint32 spell_id) { player.learnSpell(spell_id, 0, false); }
|
||||||
Player& player;
|
Player& player;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Player::learnSpellHighRank(uint32 spellid)
|
void Player::learnSpellHighRank(uint32 spellid)
|
||||||
{
|
{
|
||||||
learnSpell(spellid,false);
|
learnSpell(spellid, 0, false);
|
||||||
|
|
||||||
DoPlayerLearnSpell worker(*this);
|
DoPlayerLearnSpell worker(*this);
|
||||||
sSpellMgr.doForHighRanks(spellid,worker);
|
sSpellMgr.doForHighRanks(spellid, worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::_LoadSkills(QueryResult *result)
|
void Player::_LoadSkills(QueryResult *result)
|
||||||
|
|
@ -20971,7 +20972,7 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// learn! (other talent ranks will unlearned at learning)
|
// learn! (other talent ranks will unlearned at learning)
|
||||||
learnSpell(spellid, false);
|
learnSpell(spellid, 0, false);
|
||||||
sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
|
sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
|
||||||
|
|
||||||
// update free talent points
|
// update free talent points
|
||||||
|
|
|
||||||
|
|
@ -1543,7 +1543,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void SendProficiency(uint8 pr1, uint32 pr2);
|
void SendProficiency(uint8 pr1, uint32 pr2);
|
||||||
void SendInitialSpells();
|
void SendInitialSpells();
|
||||||
bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled);
|
bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled);
|
||||||
void learnSpell(uint32 spell_id, bool dependent);
|
void learnSpell(uint32 spell_id, uint32 triggeredBySpell, bool dependent);
|
||||||
void removeSpell(uint32 spell_id, bool disabled = false, bool learn_low_rank = true, bool sendUpdate = true);
|
void removeSpell(uint32 spell_id, bool disabled = false, bool learn_low_rank = true, bool sendUpdate = true);
|
||||||
void resetSpells();
|
void resetSpells();
|
||||||
void learnDefaultSpells();
|
void learnDefaultSpells();
|
||||||
|
|
|
||||||
|
|
@ -691,7 +691,9 @@ enum SpellEffects
|
||||||
SPELL_EFFECT_160 = 160,
|
SPELL_EFFECT_160 = 160,
|
||||||
SPELL_EFFECT_TALENT_SPEC_COUNT = 161,
|
SPELL_EFFECT_TALENT_SPEC_COUNT = 161,
|
||||||
SPELL_EFFECT_TALENT_SPEC_SELECT = 162,
|
SPELL_EFFECT_TALENT_SPEC_SELECT = 162,
|
||||||
TOTAL_SPELL_EFFECTS = 163
|
SPELL_EFFECT_163 = 163,
|
||||||
|
SPELL_EFFECT_164 = 164,
|
||||||
|
TOTAL_SPELL_EFFECTS = 165
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SpellCastResult
|
enum SpellCastResult
|
||||||
|
|
@ -2543,24 +2545,25 @@ enum ResponseCodes
|
||||||
CHAR_LOGIN_NO_CHARACTER = 0x53,
|
CHAR_LOGIN_NO_CHARACTER = 0x53,
|
||||||
CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x54,
|
CHAR_LOGIN_LOCKED_FOR_TRANSFER = 0x54,
|
||||||
CHAR_LOGIN_LOCKED_BY_BILLING = 0x55,
|
CHAR_LOGIN_LOCKED_BY_BILLING = 0x55,
|
||||||
|
CHAR_LOGIN_LOCKED_BY_MOBILE_AH = 0x56,
|
||||||
|
|
||||||
CHAR_NAME_SUCCESS = 0x56,
|
CHAR_NAME_SUCCESS = 0x57,
|
||||||
CHAR_NAME_FAILURE = 0x57,
|
CHAR_NAME_FAILURE = 0x58,
|
||||||
CHAR_NAME_NO_NAME = 0x58,
|
CHAR_NAME_NO_NAME = 0x59,
|
||||||
CHAR_NAME_TOO_SHORT = 0x59,
|
CHAR_NAME_TOO_SHORT = 0x5A,
|
||||||
CHAR_NAME_TOO_LONG = 0x5A,
|
CHAR_NAME_TOO_LONG = 0x5B,
|
||||||
CHAR_NAME_INVALID_CHARACTER = 0x5B,
|
CHAR_NAME_INVALID_CHARACTER = 0x5C,
|
||||||
CHAR_NAME_MIXED_LANGUAGES = 0x5C,
|
CHAR_NAME_MIXED_LANGUAGES = 0x5D,
|
||||||
CHAR_NAME_PROFANE = 0x5D,
|
CHAR_NAME_PROFANE = 0x5E,
|
||||||
CHAR_NAME_RESERVED = 0x5E,
|
CHAR_NAME_RESERVED = 0x5F,
|
||||||
CHAR_NAME_INVALID_APOSTROPHE = 0x5F,
|
CHAR_NAME_INVALID_APOSTROPHE = 0x60,
|
||||||
CHAR_NAME_MULTIPLE_APOSTROPHES = 0x60,
|
CHAR_NAME_MULTIPLE_APOSTROPHES = 0x61,
|
||||||
CHAR_NAME_THREE_CONSECUTIVE = 0x61,
|
CHAR_NAME_THREE_CONSECUTIVE = 0x62,
|
||||||
CHAR_NAME_INVALID_SPACE = 0x62,
|
CHAR_NAME_INVALID_SPACE = 0x63,
|
||||||
CHAR_NAME_CONSECUTIVE_SPACES = 0x63,
|
CHAR_NAME_CONSECUTIVE_SPACES = 0x64,
|
||||||
CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x64,
|
CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 0x65,
|
||||||
CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x65,
|
CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x66,
|
||||||
CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x66
|
CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 0x67
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Ban function modes
|
/// Ban function modes
|
||||||
|
|
@ -2661,9 +2664,9 @@ enum TotemSlot
|
||||||
|
|
||||||
// we need to stick to 1 version or half of the stuff will work for someone
|
// we need to stick to 1 version or half of the stuff will work for someone
|
||||||
// others will not and opposite
|
// others will not and opposite
|
||||||
// will only support WoW, WoW:TBC and WoW:WotLK 3.3.3 client build 11685...
|
// will only support WoW, WoW:TBC and WoW:WotLK 3.3.3 client build 11723...
|
||||||
|
|
||||||
#define EXPECTED_MANGOSD_CLIENT_BUILD {11685, 0}
|
#define EXPECTED_MANGOSD_CLIENT_BUILD {11723, 0}
|
||||||
|
|
||||||
// max supported expansion level in mangosd
|
// max supported expansion level in mangosd
|
||||||
// NOTE: not set it more that supported by targeted client version with all expansions installed
|
// NOTE: not set it more that supported by targeted client version with all expansions installed
|
||||||
|
|
|
||||||
|
|
@ -3676,7 +3676,7 @@ void Spell::TakeCastItem()
|
||||||
((Player*)m_caster)->DestroyItemCount(m_CastItem, count, true);
|
((Player*)m_caster)->DestroyItemCount(m_CastItem, count, true);
|
||||||
|
|
||||||
// prevent crash at access to deleted m_targets.getItemTarget
|
// prevent crash at access to deleted m_targets.getItemTarget
|
||||||
if(m_CastItem==m_targets.getItemTarget())
|
if(m_CastItem == m_targets.getItemTarget())
|
||||||
m_targets.setItemTarget(NULL);
|
m_targets.setItemTarget(NULL);
|
||||||
|
|
||||||
m_CastItem = NULL;
|
m_CastItem = NULL;
|
||||||
|
|
|
||||||
|
|
@ -2337,7 +2337,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
||||||
case 63624: // Learn a Second Talent Specialization
|
case 63624: // Learn a Second Talent Specialization
|
||||||
// Teach Learn Talent Specialization Switches, required for client triggered casts, allow after 30 sec delay
|
// Teach Learn Talent Specialization Switches, required for client triggered casts, allow after 30 sec delay
|
||||||
if (m_target->GetTypeId() == TYPEID_PLAYER)
|
if (m_target->GetTypeId() == TYPEID_PLAYER)
|
||||||
((Player*)m_target)->learnSpell(63680, false);
|
((Player*)m_target)->learnSpell(63680, 0, false);
|
||||||
return;
|
return;
|
||||||
case 63651: // Revert to One Talent Specialization
|
case 63651: // Revert to One Talent Specialization
|
||||||
// Teach Learn Talent Specialization Switches, remove
|
// Teach Learn Talent Specialization Switches, remove
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,8 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
||||||
&Spell::EffectNULL, //160 SPELL_EFFECT_160 single spell: Nerub'ar Web Random Unit
|
&Spell::EffectNULL, //160 SPELL_EFFECT_160 single spell: Nerub'ar Web Random Unit
|
||||||
&Spell::EffectSpecCount, //161 SPELL_EFFECT_TALENT_SPEC_COUNT second talent spec (learn/revert)
|
&Spell::EffectSpecCount, //161 SPELL_EFFECT_TALENT_SPEC_COUNT second talent spec (learn/revert)
|
||||||
&Spell::EffectActivateSpec, //162 SPELL_EFFECT_TALENT_SPEC_SELECT activate primary/secondary spec
|
&Spell::EffectActivateSpec, //162 SPELL_EFFECT_TALENT_SPEC_SELECT activate primary/secondary spec
|
||||||
|
&Spell::EffectNULL, //163
|
||||||
|
&Spell::EffectNULL, //164 cancel's some aura...
|
||||||
};
|
};
|
||||||
|
|
||||||
void Spell::EffectEmpty(SpellEffectIndex /*eff_idx*/)
|
void Spell::EffectEmpty(SpellEffectIndex /*eff_idx*/)
|
||||||
|
|
@ -3938,7 +3940,7 @@ void Spell::EffectLearnSpell(SpellEffectIndex eff_idx)
|
||||||
Player *player = (Player*)unitTarget;
|
Player *player = (Player*)unitTarget;
|
||||||
|
|
||||||
uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[eff_idx];
|
uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[eff_idx];
|
||||||
player->learnSpell(spellToLearn,false);
|
player->learnSpell(spellToLearn, m_spellInfo->Id, false);
|
||||||
|
|
||||||
sLog.outDebug( "Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );
|
sLog.outDebug( "Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );
|
||||||
}
|
}
|
||||||
|
|
@ -5698,11 +5700,11 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
|
||||||
|
|
||||||
// learn random explicit discovery recipe (if any)
|
// learn random explicit discovery recipe (if any)
|
||||||
if (uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, (Player*)m_caster))
|
if (uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, (Player*)m_caster))
|
||||||
((Player*)m_caster)->learnSpell(discoveredSpell, false);
|
((Player*)m_caster)->learnSpell(discoveredSpell, 0, false);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 69377: //Fortitude
|
case 69377: // Fortitude
|
||||||
{
|
{
|
||||||
if (!unitTarget)
|
if (!unitTarget)
|
||||||
return;
|
return;
|
||||||
|
|
@ -5710,7 +5712,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
|
||||||
m_caster->CastSpell(unitTarget, 72590, true);
|
m_caster->CastSpell(unitTarget, 72590, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 69378: //Blessing of Forgotten Kings
|
case 69378: // Blessing of Forgotten Kings
|
||||||
{
|
{
|
||||||
if (!unitTarget)
|
if (!unitTarget)
|
||||||
return;
|
return;
|
||||||
|
|
@ -5718,7 +5720,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
|
||||||
m_caster->CastSpell(unitTarget, 72586, true);
|
m_caster->CastSpell(unitTarget, 72586, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 69381: //Gift of the Wild
|
case 69381: // Gift of the Wild
|
||||||
{
|
{
|
||||||
if (!unitTarget)
|
if (!unitTarget)
|
||||||
return;
|
return;
|
||||||
|
|
@ -5807,15 +5809,15 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
|
||||||
uint32 spellID;
|
uint32 spellID;
|
||||||
switch(entry)
|
switch(entry)
|
||||||
{
|
{
|
||||||
case 416: spellID = 54444; break; //imp
|
case 416: spellID = 54444; break; // imp
|
||||||
case 417: spellID = 54509; break; //fellhunter
|
case 417: spellID = 54509; break; // fellhunter
|
||||||
case 1860: spellID = 54443; break; //void
|
case 1860: spellID = 54443; break; // void
|
||||||
case 1863: spellID = 54435; break; //succubus
|
case 1863: spellID = 54435; break; // succubus
|
||||||
case 17252: spellID = 54508; break; //fellguard
|
case 17252: spellID = 54508; break; // fellguard
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unitTarget->CastSpell(unitTarget,spellID,true);
|
unitTarget->CastSpell(unitTarget, spellID, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 47422: // Everlasting Affliction
|
case 47422: // Everlasting Affliction
|
||||||
|
|
@ -5827,7 +5829,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
|
||||||
SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
|
SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
|
||||||
if(spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
|
if(spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
|
||||||
(spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000002)) &&
|
(spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000002)) &&
|
||||||
(*itr).second->GetCasterGUID()==m_caster->GetGUID())
|
(*itr).second->GetCasterGUID() == m_caster->GetGUID())
|
||||||
(*itr).second->RefreshAura();
|
(*itr).second->RefreshAura();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
#ifndef _UPDATEFIELDS_AUTO_H
|
#ifndef _UPDATEFIELDS_AUTO_H
|
||||||
#define _UPDATEFIELDS_AUTO_H
|
#define _UPDATEFIELDS_AUTO_H
|
||||||
|
|
||||||
// Auto generated for version 3, 3, 3, 11685
|
// Auto generated for version 3, 3, 3, 11723
|
||||||
|
|
||||||
enum EObjectFields
|
enum EObjectFields
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -842,6 +842,7 @@ void WorldSession::SendAddonsInfo()
|
||||||
string (16 bytes)
|
string (16 bytes)
|
||||||
uint32
|
uint32
|
||||||
uint32
|
uint32
|
||||||
|
uint32
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
SendPacket(&data);
|
SendPacket(&data);
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ enum eAuthResults
|
||||||
|
|
||||||
#define EXPECTED_REALMD_CLIENT_BUILD \
|
#define EXPECTED_REALMD_CLIENT_BUILD \
|
||||||
{ \
|
{ \
|
||||||
11685, /* 3.3.3 and higher */ \
|
11723, /* 3.3.3a and higher */ \
|
||||||
11159, /* 3.3.0a */ \
|
11159, /* 3.3.0a */ \
|
||||||
10505, /* 3.2.2a */ \
|
10505, /* 3.2.2a */ \
|
||||||
8606, /* 2.4.3 */ \
|
8606, /* 2.4.3 */ \
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue