aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/NPCHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Handlers/NPCHandler.cpp')
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp62
1 files changed, 44 insertions, 18 deletions
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index 138daf6d9c2..991838ca304 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -155,6 +155,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);
data << guid;
data << uint32(trainer_spells->trainerType);
+ data << uint32(1); // different value for each trainer, also found in CMSG_TRAINER_BUY_SPELL
size_t count_pos = data.wpos();
data << uint32(trainer_spells->spellList.size());
@@ -192,9 +193,6 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle)
data << uint8(state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
data << uint32(floor(tSpell->spellCost * fDiscountMod));
- data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
- // primary prof. learn confirmation dialog
- data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
data << uint8(tSpell->reqLevel);
data << uint32(tSpell->reqSkill);
data << uint32(tSpell->reqSkillValue);
@@ -209,7 +207,7 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle)
data << uint32(prevSpellId);
++maxReq;
}
- if (maxReq == 3)
+ if (maxReq == 2)
break;
SpellsRequiringSpellMapBounds spellsRequired = sSpellMgr->GetSpellsRequiredForSpellBounds(tSpell->learnedSpell[i]);
for (SpellsRequiringSpellMap::const_iterator itr2 = spellsRequired.first; itr2 != spellsRequired.second && maxReq < 3; ++itr2)
@@ -217,15 +215,19 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle)
data << uint32(itr2->second);
++maxReq;
}
- if (maxReq == 3)
+ if (maxReq == 2)
break;
}
- while (maxReq < 3)
+ while (maxReq < 2)
{
data << uint32(0);
++maxReq;
}
+ data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
+ // primary prof. learn confirmation dialog
+ data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
+
++count;
}
@@ -238,9 +240,10 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle)
void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData)
{
uint64 guid;
- uint32 spellId = 0;
+ uint32 spellId;
+ uint32 trainerId;
- recvData >> guid >> spellId;
+ recvData >> guid >> trainerId >> spellId;
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u", uint32(GUID_LOPART(guid)), spellId);
Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER);
@@ -255,33 +258,48 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData)
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if (!unit->isCanTrainingOf(_player, true))
+ {
+ SendTrainerBuyFailed(guid, spellId, 0);
return;
+ }
// check present spell in trainer spell list
TrainerSpellData const* trainer_spells = unit->GetTrainerSpells();
if (!trainer_spells)
+ {
+ SendTrainerBuyFailed(guid, spellId, 0);
return;
+ }
// not found, cheat?
TrainerSpell const* trainer_spell = trainer_spells->Find(spellId);
if (!trainer_spell)
+ {
+ SendTrainerBuyFailed(guid, spellId, 0);
return;
+ }
// can't be learn, cheat? Or double learn with lags...
if (_player->GetTrainerSpellState(trainer_spell) != TRAINER_SPELL_GREEN)
+ {
+ SendTrainerBuyFailed(guid, spellId, 0);
return;
+ }
// apply reputation discount
uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
// check money requirement
- if (!_player->HasEnoughMoney(nSpellCost))
+ if (!_player->HasEnoughMoney(uint64(nSpellCost)))
+ {
+ SendTrainerBuyFailed(guid, spellId, 1);
return;
+ }
- _player->ModifyMoney(-int32(nSpellCost));
+ _player->ModifyMoney(-int64(nSpellCost));
- unit->SendPlaySpellVisual(179); // 53 SpellCastDirected
- unit->SendPlaySpellImpact(_player->GetGUID(), 362); // 113 EmoteSalute
+ unit->SendPlaySpellVisualKit(179, 0); // 53 SpellCastDirected
+ _player->SendPlaySpellVisualKit(362, 1); // 113 EmoteSalute
// learn explicitly or cast explicitly
if (trainer_spell->IsCastable())
@@ -291,7 +309,16 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData)
WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12);
data << uint64(guid);
- data << uint32(spellId); // should be same as in packet from client
+ data << uint32(spellId);
+ SendPacket(&data);
+}
+
+void WorldSession::SendTrainerBuyFailed(uint64 guid, uint32 spellId, uint32 reason)
+{
+ WorldPacket data(SMSG_TRAINER_BUY_FAILED, 16);
+ data << uint64(guid);
+ data << uint32(spellId); // should be same as in packet from client
+ data << uint32(reason); // 1 == "Not enough money for trainer service." 0 == "Trainer service %d unavailable."
SendPacket(&data);
}
@@ -319,9 +346,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData)
// GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if (unit->isArmorer() || unit->isCivilian() || unit->isQuestGiver() || unit->isServiceProvider() || unit->isGuard())
- {
unit->StopMoving();
- }
// If spiritguide, no need for gossip menu, just put player into resurrect queue
if (unit->isSpiritGuide())
@@ -473,7 +498,7 @@ void WorldSession::SendBindPoint(Creature* npc)
// send spell for homebinding (3286)
npc->CastSpell(_player, bindspell, true);
- WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, (8+4));
+ WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12);
data << uint64(npc->GetGUID());
data << uint32(bindspell);
SendPacket(&data);
@@ -537,6 +562,7 @@ void WorldSession::SendStablePetCallback(PreparedQueryResult result, uint64 guid
// not let move dead pet in slot
if (pet && pet->isAlive() && pet->getPetType() == HUNTER_PET)
{
+ data << uint32(0); // 4.x unknown, some kind of order?
data << uint32(pet->GetCharmInfo()->GetPetNumber());
data << uint32(pet->GetEntry());
data << uint32(pet->getLevel());
@@ -749,7 +775,7 @@ void WorldSession::HandleBuyStableSlot(WorldPacket& recvData)
if (GetPlayer()->m_stableSlots < MAX_PET_STABLES)
{
- StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1);
+ /*StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1);
if (_player->HasEnoughMoney(SlotPrice->Price))
{
++GetPlayer()->m_stableSlots;
@@ -757,7 +783,7 @@ void WorldSession::HandleBuyStableSlot(WorldPacket& recvData)
SendStableResult(STABLE_SUCCESS_BUY_SLOT);
}
else
- SendStableResult(STABLE_ERR_MONEY);
+ SendStableResult(STABLE_ERR_MONEY);*/
}
else
SendStableResult(STABLE_ERR_STABLE);