void WorldSession::HandleTrainerBuySpellOpcode(WorldPackets::NPC::TrainerBuySpell& packet) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_TRAINER_BUY_SPELL %s, learn spell id is: %i", packet.TrainerGUID.ToString().c_str(), packet.SpellID); Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.TrainerGUID, UNIT_NPC_FLAG_TRAINER); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleTrainerBuySpellOpcode - %s not found or you can not interact with him.", packet.TrainerGUID.ToString().c_str()); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); // check present spell in trainer spell list TrainerSpellData const* trainer_spells = unit->GetTrainerSpells(); if (!trainer_spells) { SendTrainerBuyFailed(packet.TrainerGUID, packet.SpellID, 0); return; } // not found, cheat? TrainerSpell const* trainerSpell = trainer_spells->Find(packet.SpellID); if (!trainerSpell) { SendTrainerBuyFailed(packet.TrainerGUID, packet.SpellID, 0); return; } // can't be learn, cheat? Or double learn with lags... if (_player->GetTrainerSpellState(trainerSpell) != TRAINER_SPELL_GREEN) { SendTrainerBuyFailed(packet.TrainerGUID, packet.SpellID, 0); return; } // apply reputation discount uint32 nSpellCost = uint32(floor(trainerSpell->MoneyCost * _player->GetReputationPriceDiscount(unit))); // check money requirement if (!_player->HasEnoughMoney(uint64(nSpellCost))) { SendTrainerBuyFailed(packet.TrainerGUID, packet.SpellID, 1); return; } _player->ModifyMoney(-int64(nSpellCost)); unit->SendPlaySpellVisualKit(179, 0); // 53 SpellCastDirected _player->SendPlaySpellVisualKit(362, 1); // 113 EmoteSalute // learn explicitly or cast explicitly if (trainerSpell->IsCastable()) _player->CastSpell(_player, trainerSpell->SpellID, true); else _player->LearnSpell(packet.SpellID, false); }
void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData) { ObjectGuid guid; uint32 spellId; uint32 trainerId; recvData >> spellId >> trainerId; guid[1] = recvData.ReadBit(); guid[4] = recvData.ReadBit(); guid[0] = recvData.ReadBit(); guid[6] = recvData.ReadBit(); guid[3] = recvData.ReadBit(); guid[2] = recvData.ReadBit(); guid[5] = recvData.ReadBit(); guid[7] = recvData.ReadBit(); recvData.ReadByteSeq(guid[3]); recvData.ReadByteSeq(guid[1]); recvData.ReadByteSeq(guid[4]); recvData.ReadByteSeq(guid[7]); recvData.ReadByteSeq(guid[0]); recvData.ReadByteSeq(guid[5]); recvData.ReadByteSeq(guid[6]); recvData.ReadByteSeq(guid[2]); TC_LOG_DEBUG("network", "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); if (!unit) { TC_LOG_DEBUG("network", "WORLD: HandleTrainerBuySpellOpcode - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(guid))); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); // 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(uint64(nSpellCost))) { SendTrainerBuyFailed(guid, spellId, 1); return; } _player->ModifyMoney(-int64(nSpellCost)); unit->SendPlaySpellVisualKit(179, 0); // 53 SpellCastDirected _player->SendPlaySpellVisualKit(362, 1); // 113 EmoteSalute // learn explicitly or cast explicitly if (trainer_spell->IsCastable()) _player->CastSpell(_player, trainer_spell->spell, true); else _player->learnSpell(spellId, false); WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12); data << uint64(guid); data << uint32(spellId); SendPacket(&data); }