diff options
Diffstat (limited to 'src/server/game/Handlers/NPCHandler.cpp')
| -rw-r--r-- | src/server/game/Handlers/NPCHandler.cpp | 62 |
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); |
