void WorldSession::SendTrainerList(Creature* pCreature) { Trainer * pTrainer = pCreature->GetTrainer(); //if(pTrainer == 0 || !CanTrainAt(_player, pTrainer)) return; if(pTrainer==0) return; if(!CanTrainAt(_player,pTrainer)) { GossipMenu * pMenu; objmgr.CreateGossipMenuForPlayer(&pMenu,pCreature->GetGUID(),pTrainer->Cannot_Train_GossipTextId,_player); pMenu->SendTo(_player); return; } WorldPacket data(SMSG_TRAINER_LIST, 5000); TrainerSpell * pSpell; uint32 Spacer = 0; uint32 Count=0; uint8 Status; string Text; data << pCreature->GetGUID(); data << pTrainer->TrainerType; data << uint32(0); for(vector<TrainerSpell>::iterator itr = pTrainer->Spells.begin(); itr != pTrainer->Spells.end(); ++itr) { pSpell = &(*itr); Status = TrainerGetSpellStatus(pSpell); if( pSpell->pCastRealSpell != NULL ) data << pSpell->pCastRealSpell->Id; else if( pSpell->pLearnSpell ) data << pSpell->pLearnSpell->Id; else continue; data << Status; data << pSpell->Cost; data << Spacer; data << uint32(pSpell->IsProfession); data << uint8(pSpell->RequiredLevel); data << pSpell->RequiredSkillLine; data << pSpell->RequiredSkillLineValue; data << pSpell->RequiredSpell; data << Spacer; //this is like a spell override or something, ex : (id=34568 or id=34547) or (id=36270 or id=34546) or (id=36271 or id=34548) data << Spacer; ++Count; } #ifdef USING_BIG_ENDIAN *(uint32*)&data.contents()[12] = swap32(Count); #else *(uint32*)&data.contents()[12] = Count; #endif data << pTrainer->UIMessage; SendPacket(&data); }
void WorldSession::HandleUnlearnTalents( WorldPacket & recv_data ) { if(!_player->IsInWorld()) { return; } //check if we have nearby trainer -> avoid respecing on the field InRangeSetRecProt::iterator itr; _player->AquireInrangeLock(); //make sure to release lock before exit function ! bool found_trainer = false; InrangeLoopExitAutoCallback AutoLock; for( itr = _player->GetInRangeSetBegin( AutoLock ); itr != _player->GetInRangeSetEnd(); itr++ ) { if(!((*itr)->IsUnit()) || !SafeUnitCast((*itr))->isAlive() || !(*itr)->IsCreature()) continue; Creature *cr = SafeCreatureCast(*itr); Trainer * pTrainer = cr->GetTrainer(); if( pTrainer == NULL || !CanTrainAt(_player, pTrainer) ) continue; found_trainer = true; break; } _player->ReleaseInrangeLock(); //ups, we are using client script to respec anywhere if( found_trainer == false ) { sLog.outDebug("ResetTalent: We are not close enough to a trainer"); return; } #ifndef PVP_AREANA_REALM uint64 playerGold = GetPlayer()->GetGold( ); uint64 price = GetPlayer()->CalcTalentResetCost(GetPlayer()->GetTalentResetTimes()); if( playerGold < price ) { sLog.outDebug("ResetTalent: Not enough gold"); return; } GetPlayer()->SetTalentResetTimes(GetPlayer()->GetTalentResetTimes() + 1); GetPlayer()->ModGold( -(int64)price ); #endif GetPlayer()->Reset_Talents(); GetPlayer()->Event_AchiementCriteria_Received(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS,ACHIEVEMENT_UNUSED_FIELD_VALUE,ACHIEVEMENT_UNUSED_FIELD_VALUE,1,ACHIEVEMENT_EVENT_ACTION_ADD); GetPlayer()->Event_AchiementCriteria_Received(ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS,ACHIEVEMENT_UNUSED_FIELD_VALUE,ACHIEVEMENT_UNUSED_FIELD_VALUE,1,ACHIEVEMENT_EVENT_ACTION_ADD); /* // Unlearn all talent spells WorldPacket data; std::list<uint32> *talentproto = GetPlayer()->getTalentproto(); std::list<uint32>::iterator itr; for (itr = talentproto->begin(); itr != talentproto->end(); ++itr) { GetPlayer()->removeSpell((*itr)); // Handled in removespell. //data.Initialize(SMSG_REMOVED_SPELL); //data << (*itr); //SendPacket( &data ); } talentproto->clear(); */ }
void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvPacket) { if(!_player->IsInWorld()) return; uint64 Guid; uint32 TeachingSpellID; recvPacket >> Guid >> TeachingSpellID; Creature *pCreature = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(Guid)); if(pCreature == 0) return; Trainer *pTrainer = pCreature->GetTrainer(); if(pTrainer == 0 || !CanTrainAt(_player, pTrainer)) return; TrainerSpell * pSpell=NULL; for(vector<TrainerSpell>::iterator itr = pTrainer->Spells.begin(); itr != pTrainer->Spells.end(); ++itr) { if( ( itr->pCastRealSpell && itr->pCastRealSpell->Id == TeachingSpellID ) || ( itr->pLearnSpell && itr->pLearnSpell->Id == TeachingSpellID ) ) { pSpell = &(*itr); } } if(pSpell == NULL) return; if(TrainerGetSpellStatus(pSpell) > 0) return; _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -(int32)pSpell->Cost); if( pSpell->pCastSpell) { // Cast teaching spell on player pCreature->CastSpell(_player, pSpell->pCastSpell, true); } if( pSpell->pLearnSpell ) { packetSMSG_PLAY_SPELL_VISUAL pck; pck.guid = pCreature->GetGUID(); pck.visualid = 0x5b3; _player->OutPacketToSet( SMSG_PLAY_SPELL_VISUAL, sizeof(packetSMSG_PLAY_SPELL_VISUAL), &pck, true ); pck.guid = _player->GetGUID(); pck.visualid = 0x16a; _player->OutPacketToSet( 0x1F7, sizeof(packetSMSG_PLAY_SPELL_VISUAL), &pck, true ); // add the spell _player->addSpell( pSpell->pLearnSpell->Id ); uint32 i; for( i = 0; i < 3; ++i) { if(pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_PROFICIENCY || pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_LEARN_SPELL || pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_WEAPON) { _player->CastSpell(_player, pSpell->pLearnSpell, true); break; } } for( i = 0; i < 3; ++i) { if( pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_SKILL ) { uint32 skill = pSpell->pLearnSpell->EffectMiscValue[i]; uint32 val = (pSpell->pLearnSpell->EffectBasePoints[i]+1) * 75; if( val > 350 ) val = 350; if( _player->_GetSkillLineMax(skill) >= val ) return; if( skill == SKILL_RIDING ) _player->_AddSkillLine( skill, val, val ); else { if( _player->_HasSkillLine(skill) ) _player->_ModifySkillMaximum(skill, val); else _player->_AddSkillLine( skill, 1, val); } } } } if(pSpell->DeleteSpell) { // Remove old spell. if( pSpell->pLearnSpell ) _player->removeSpell(pSpell->DeleteSpell, true, true, pSpell->pLearnSpell->Id); else if(pSpell->pCastSpell) _player->removeSpell(pSpell->DeleteSpell, true, true, pSpell->pCastRealSpell->Id); else _player->removeSpell(pSpell->DeleteSpell,true,false,0); } }
void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvPacket) { CHECK_INWORLD_RETURN; uint64 Guid; uint32 TeachingSpellID; recvPacket >> Guid >> TeachingSpellID; Creature* pCreature = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(Guid)); if(pCreature == NULL) return; Trainer *pTrainer = pCreature->GetTrainer(); if(pTrainer == NULL || !CanTrainAt(_player, pTrainer)) return; TrainerSpell* pSpell = NULL; for(vector<TrainerSpell>::iterator itr = pTrainer->Spells.begin(); itr != pTrainer->Spells.end(); itr++) { if( ( itr->pCastRealSpell && itr->pCastRealSpell->Id == TeachingSpellID ) || ( itr->pLearnSpell && itr->pLearnSpell->Id == TeachingSpellID ) ) { pSpell = &(*itr); } } if(pSpell == NULL) return; if(TrainerGetSpellStatus(pSpell) > 0) return; _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -(int32)pSpell->Cost); if( pSpell->pCastSpell) { // Cast teaching spell on player pCreature->CastSpell(_player, pSpell->pCastSpell, true); } if( pSpell->pLearnSpell ) { packetSMSG_PLAY_SPELL_VISUAL pck; pck.guid = pCreature->GetGUID(); pck.visualid = 0x5b3; _player->OutPacketToSet( SMSG_PLAY_SPELL_VISUAL, sizeof(packetSMSG_PLAY_SPELL_VISUAL), &pck, true ); pck.guid = _player->GetGUID(); pck.visualid = 0x16a; _player->OutPacketToSet( SMSG_PLAY_SPELL_IMPACT, sizeof(packetSMSG_PLAY_SPELL_VISUAL), &pck, true ); // add the spell _player->addSpell( pSpell->pLearnSpell->Id ); uint32 i; for( i = 0; i < 3; ++i) { if(pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_PROFICIENCY || pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_LEARN_SPELL || pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_WEAPON) { _player->CastSpell(_player, pSpell->pLearnSpell, true); break; } } for( i = 0; i < 3; ++i) { if( pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_SKILL ) { uint32 skill = pSpell->pLearnSpell->EffectMiscValue[i]; uint32 val = (pSpell->pLearnSpell->EffectBasePoints[i]+1) * 75; if( val > 350 ) val = 350; if( _player->_GetSkillLineMax(skill) >= val ) return; if( skill == SKILL_RIDING ) _player->_AddSkillLine( skill, val, val ); else { if( _player->_HasSkillLine(skill) ) _player->_ModifySkillMaximum(skill, val); else _player->_AddSkillLine( skill, 1, val); } } } } if(pSpell->DeleteSpell) { // Remove old spell. if( pSpell->pLearnSpell ) _player->removeSpell(pSpell->DeleteSpell, true, true, pSpell->pLearnSpell->Id); else if(pSpell->pCastSpell) _player->removeSpell(pSpell->DeleteSpell, true, true, pSpell->pCastRealSpell->Id); else _player->removeSpell(pSpell->DeleteSpell,true,false,0); } ///////////////////////////////////////////////////////////////////////////////// // As of 3.1.3 this is sent after buying the spell // // // {SERVER} Packet: (0x01B3) SMSG_TRAINER_BUY_SUCCEEDED PacketSize = 12 TimeStamp = 39035968 // A0 85 00 06 7A 00 30 F1 2D 85 00 00 // // structure: // // uint64 GUID - GUID of the trainer // uint32 spellid - ID of the spell we bought ////////////////////////////////////////////////////////////////////////////////// WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12); data << uint64(Guid) << uint32(TeachingSpellID); this->SendPacket(&data); }
void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvPacket) { if(!_player->IsInWorld()) return; //////////////////////////////////////////////////////////////////////////////// // As of 3.1.3 the client sends this when buying a spell // // {CLIENT} Packet: (0x01B2) CMSG_TRAINER_BUY_SPELL PacketSize = 12 TimeStamp = 39035859 // A0 85 00 06 7A 00 30 F1 2D 85 00 00 // // Structure: // uint64 GUID - GUID of the trainer // uint32 spellid - ID of the spell being bought //////////////////////////////////////////////////////////////////////////////// uint64 Guid; uint32 TeachingSpellID; recvPacket >> Guid >> TeachingSpellID; Creature *pCreature = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(Guid)); /////////////////////////////////////////// Checks ////////////////////////////////////// if(pCreature == NULL) return; Trainer *pTrainer = pCreature->GetTrainer(); if(pTrainer == NULL || !CanTrainAt(_player, pTrainer)) return; // Check if the trainer offers that spell TrainerSpell * pSpell = NULL; for(vector<TrainerSpell>::iterator itr = pTrainer->Spells.begin(); itr != pTrainer->Spells.end(); ++itr) { if( ( itr->pCastSpell && itr->pCastSpell->Id == TeachingSpellID ) || ( itr->pLearnSpell && itr->pLearnSpell->Id == TeachingSpellID ) ) { pSpell = &(*itr); } } // If the trainer doesn't offer it, this is probably some packet mangling if(pSpell == NULL){ // Disconnecting the player this->Disconnect(); return; } // We can't learn it if(TrainerGetSpellStatus(pSpell) > 0) return; //////////////////////////////////////////// Teaching //////////////////////////////////// _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -(int32)pSpell->Cost); if( pSpell->pCastSpell) { _player->CastSpell( _player, pSpell->pCastSpell->Id, true ); } else { /////////////////////////////////////// Showing the learning spellvisuals////////////// packetSMSG_PLAY_SPELL_VISUAL pck; pck.guid = pCreature->GetGUID(); pck.visualid = 0x5b3; _player->OutPacketToSet( SMSG_PLAY_SPELL_VISUAL, sizeof(packetSMSG_PLAY_SPELL_VISUAL), &pck, true ); pck.guid = _player->GetGUID(); pck.visualid = 0x16a; _player->OutPacketToSet( SMSG_PLAY_SPELL_IMPACT, sizeof(packetSMSG_PLAY_SPELL_VISUAL), &pck, true ); /////////////////////////////////////////////////////////////////////////////////////// // add the spell itself _player->addSpell( pSpell->pLearnSpell->Id ); } if(pSpell->DeleteSpell) { // Remove old spell. if( pSpell->pLearnSpell ) _player->removeSpell(pSpell->DeleteSpell, true, true, pSpell->pLearnSpell->Id); else if(pSpell->pCastSpell) _player->removeSpell(pSpell->DeleteSpell, true, true, pSpell->pCastRealSpell->Id); else _player->removeSpell(pSpell->DeleteSpell,true,false,0); } _player->_UpdateSkillFields(); ///////////////////////////////////////////////////////////////////////////////// // As of 3.1.3 this is sent after buying the spell // // // {SERVER} Packet: (0x01B3) SMSG_TRAINER_BUY_SUCCEEDED PacketSize = 12 TimeStamp = 39035968 // A0 85 00 06 7A 00 30 F1 2D 85 00 00 // // structure: // // uint64 GUID - GUID of the trainer // uint32 spellid - ID of the spell we bought ////////////////////////////////////////////////////////////////////////////////// WorldPacket data( SMSG_TRAINER_BUY_SUCCEEDED, 12 ); data << uint64( Guid ) << uint32( TeachingSpellID ); this->SendPacket( &data ); }
void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvPacket) { if(!_player->IsInWorld()) { return; } uint64 Guid; uint32 TeachingSpellID; recvPacket >> Guid >> TeachingSpellID; Creature *pCreature = _player->GetMapMgr()->GetCreature( Guid ); if(pCreature == 0) { return; } Trainer *pTrainer = pCreature->GetTrainer(); if(pTrainer == 0 || !CanTrainAt(_player, pTrainer)) { return; } TrainerSpell * pSpell=NULL; for(uint32 itr = 0; itr < pTrainer->SpellCount; ++itr) { TrainerSpell *t = pTrainer->Spells.GetValue( itr ); if( ( t->pCastRealSpell && t->pCastRealSpell->Id == TeachingSpellID ) || ( t->pLearnSpell && t->pLearnSpell->Id == TeachingSpellID ) ) pSpell = t; } if(pSpell == NULL) { return; } if(TrainerGetSpellStatus(pSpell) > 0) { return; } _player->ModGold( -(int32)pSpell->Cost); if( pSpell->pCastSpell) { // Cast teaching spell on player // pCreature->CastSpell(_player, pSpell->pCastSpell, true); _player->CastSpell(_player, pSpell->pCastSpell, true); //creature cast might fail due to bad targeting } //are these required in 3.1.1 ? /* packetSMSG_PLAY_SPELL_VISUAL pck; pck.guid = pCreature->GetGUID(); pck.visualid = 0x5b3; _player->OutPacketToSet( SMSG_PLAY_SPELL_VISUAL, sizeof(packetSMSG_PLAY_SPELL_VISUAL), &pck, true );*/ packetSMSG_PLAY_SPELL_IMPACT pck2; pck2.guid = _player->GetGUID(); pck2.visualid = 0x16a; _player->OutPacketToSet( SMSG_PLAY_SPELL_IMPACT, sizeof(packetSMSG_PLAY_SPELL_VISUAL), &pck2, true );/**/ this->OutPacket( SMSG_TRAINER_BUY_SUCCEEDED, 12, recvPacket.contents() ); if( pSpell->pLearnSpell ) { // add the spell if( pSpell->pLearnSpell->Effect[0] != SPELL_EFFECT_LEARN_SPELL && pSpell->pLearnSpell->Effect[1] != SPELL_EFFECT_LEARN_SPELL && pSpell->pLearnSpell->Effect[2] != SPELL_EFFECT_LEARN_SPELL ) _player->addSpell( pSpell->pLearnSpell->Id ); uint32 i; for( i = 0; i < 3; ++i ) { if( pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_PROFICIENCY || pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_WEAPON || ( pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_LEARN_SPELL && pSpell->pLearnSpell->EffectImplicitTargetA[i] != EFF_TARGET_PET ) ) // avoid direct pet teaching { _player->CastSpell( _player, pSpell->pLearnSpell, true ); break; } } for( i = 0; i < 3; ++i) { if( pSpell->pLearnSpell->Effect[i] == SPELL_EFFECT_SKILL ) { uint32 skill = pSpell->pLearnSpell->EffectMiscValue[i]; uint32 val = (pSpell->pLearnSpell->EffectBasePoints[i]+1) * 75; if( val > PLAYER_SKILL_CAP ) val = PLAYER_SKILL_CAP; if( _player->_GetSkillLineMax(skill) >= val ) { return; } if( skill == SKILL_RIDING ) _player->_AddSkillLine( skill, val, val ); else { if( _player->_HasSkillLine(skill) ) _player->_ModifySkillMaximum(skill, val); else _player->_AddSkillLine( skill, 1, val); } } } } if(pSpell->DeleteSpell) { // Remove old spell. if( pSpell->pLearnSpell ) _player->removeSpell(pSpell->DeleteSpell, true, true, pSpell->pLearnSpell->Id); else if(pSpell->pCastSpell) _player->removeSpell(pSpell->DeleteSpell, true, true, pSpell->pCastRealSpell->Id); else _player->removeSpell(pSpell->DeleteSpell,true,false,0); } }