Try to fix trainer service, not tested

Signed-off-by: Netcho <kkotlarski@abv.bg>

[0170] Fix QuestGiverStatus enum, this should resolve the problem with ! and ? signs appearing over the NPC
This commit is contained in:
Netcho 2012-08-24 14:30:09 +03:00 committed by Antz
parent 6dd0ba1d14
commit 417b746f29
5 changed files with 62 additions and 47 deletions

View file

@ -249,19 +249,23 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recv_data)
return;
}
data.Initialize(SMSG_TRAINER_SERVICE, 16);
uint32 trainState = 2;
// remove fake death
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
if (!unit->IsTrainerOf(_player, true))
return;
trainState = 1;
// check present spell in trainer spell list
TrainerSpellData const* cSpells = unit->GetTrainerSpells();
TrainerSpellData const* tSpells = unit->GetTrainerTemplateSpells();
if (!cSpells && !tSpells)
return;
trainState = 1;
// Try find spell in npc_trainer
TrainerSpell const* trainer_spell = cSpells ? cSpells->Find(spellId) : NULL;
@ -272,45 +276,56 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recv_data)
// Not found anywhere, cheating?
if (!trainer_spell)
return;
trainState = 1;
// can't be learn, cheat? Or double learn with lags...
uint32 reqLevel = 0;
if (!_player->IsSpellFitByClassAndRace(trainer_spell->learnedSpell, &reqLevel))
return;
trainState = 1;
reqLevel = trainer_spell->isProvidedReqLevel ? trainer_spell->reqLevel : std::max(reqLevel, trainer_spell->reqLevel);
if (_player->GetTrainerSpellState(trainer_spell, reqLevel) != TRAINER_SPELL_GREEN)
return;
trainState = 1;
// apply reputation discount
uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
// check money requirement
if (_player->GetMoney() < nSpellCost)
return;
if ((_player->GetMoney() < nSpellCost) && !trainState)
trainState = 0;
_player->ModifyMoney(-int32(nSpellCost));
// visual effect on trainer
WorldPacket data;
unit->BuildSendPlayVisualPacket(&data, 0xB3, false);
SendPacket(&data);
// visual effect on player
_player->BuildSendPlayVisualPacket(&data, 0x016A, true);
SendPacket(&data);
// learn explicitly or cast explicitly
if (trainer_spell->IsCastable())
_player->CastSpell(_player, trainer_spell->spell, true);
if(trainState != 2)
{
data << ObjectGuid(guid);
data << uint32(spellId);
data << trainState;
SendPacket(&data);
}
else
_player->learnSpell(spellId, false);
{
_player->ModifyMoney(-int32(nSpellCost));
data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12);
data << ObjectGuid(guid);
data << uint32(spellId); // should be same as in packet from client
SendPacket(&data);
// visual effect on trainer
WorldPacket data;
unit->BuildSendPlayVisualPacket(&data, 0xB3, false);
SendPacket(&data);
// visual effect on player
_player->BuildSendPlayVisualPacket(&data, 0x016A, true);
SendPacket(&data);
// learn explicitly or cast explicitly
if (trainer_spell->IsCastable())
_player->CastSpell(_player, trainer_spell->spell, true);
else
_player->learnSpell(spellId, false);
data << ObjectGuid(guid);
data << uint32(spellId); // should be same as in packet from client
data << uint32(2);
SendPacket(&data);
}
}
void WorldSession::HandleGossipHelloOpcode(WorldPacket& recv_data)

View file

@ -499,11 +499,11 @@ void InitializeOpcodes()
//OPCODE(CMSG_ACTIVATETAXI, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiOpcode );
//OPCODE(SMSG_ACTIVATETAXIREPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_NEW_TAXI_PATH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_TRAINER_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerListOpcode );
//OPCODE(SMSG_TRAINER_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_TRAINER_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerListOpcode );
OPCODE(SMSG_TRAINER_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_TRAINER_BUY_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerBuySpellOpcode );
OPCODE(SMSG_TRAINER_BUY_SUCCEEDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(SMSG_TRAINER_BUY_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_TRAINER_SERVICE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(SMSG_TRAINER_BUY_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
OPCODE(CMSG_BINDER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBinderActivateOpcode );
//OPCODE(SMSG_PLAYERBINDERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//OPCODE(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode );

View file

@ -484,11 +484,11 @@ enum Opcodes
CMSG_ACTIVATETAXI = 0x11AE,
SMSG_ACTIVATETAXIREPLY = 0x11AF,
SMSG_NEW_TAXI_PATH = 0x11B0,
CMSG_TRAINER_LIST = 0x11B1,
SMSG_TRAINER_LIST = 0x11B2,
CMSG_TRAINER_BUY_SPELL = 0x11B3,
SMSG_TRAINER_BUY_SUCCEEDED = 0x11B4,
SMSG_TRAINER_BUY_FAILED = 0x11B5,
CMSG_TRAINER_LIST = 0x2336, // 4.3.4 15595
SMSG_TRAINER_LIST = 0x4414, // 4.3.4 15595
CMSG_TRAINER_BUY_SPELL = 0x4415, // 4.3.4 15595
SMSG_TRAINER_SERVICE = 0x6A05, // 4.3.4 15595
SMSG_TRAINER_BUY_FAILED = 0x0004, // 4.3.4 15595
CMSG_BINDER_ACTIVATE = 0x4006, // 4.3.4 15595
SMSG_PLAYERBINDERROR = 0x11B7,
CMSG_BANKER_ACTIVATE = 0x11B8,

View file

@ -107,17 +107,17 @@ enum QuestStatus
enum __QuestGiverStatus
{
DIALOG_STATUS_NONE = 0,
DIALOG_STATUS_UNAVAILABLE = 1,
DIALOG_STATUS_LOW_LEVEL_AVAILABLE = 2,
DIALOG_STATUS_LOW_LEVEL_REWARD_REP = 3,
DIALOG_STATUS_LOW_LEVEL_AVAILABLE_REP = 4,
DIALOG_STATUS_INCOMPLETE = 5,
DIALOG_STATUS_REWARD_REP = 6,
DIALOG_STATUS_AVAILABLE_REP = 7,
DIALOG_STATUS_AVAILABLE = 8,
DIALOG_STATUS_REWARD2 = 9, // no yellow dot on minimap
DIALOG_STATUS_REWARD = 10 // yellow dot on minimap
DIALOG_STATUS_NONE = 0x000,
DIALOG_STATUS_UNAVAILABLE = 0x002,
DIALOG_STATUS_LOW_LEVEL_AVAILABLE = 0x004,
DIALOG_STATUS_LOW_LEVEL_REWARD_REP = 0x008,
DIALOG_STATUS_LOW_LEVEL_AVAILABLE_REP = 0x010,
DIALOG_STATUS_INCOMPLETE = 0x020,
DIALOG_STATUS_REWARD_REP = 0x040,
DIALOG_STATUS_AVAILABLE_REP = 0x080,
DIALOG_STATUS_AVAILABLE = 0x100,
DIALOG_STATUS_REWARD2 = 0x200, // no yellow dot on minimap
DIALOG_STATUS_REWARD = 0x400 // yellow dot on minimap
};
// values based at QuestInfo.dbc

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "0169"
#define REVISION_NR "0170"
#endif // __REVISION_NR_H__