void PlayerMenu::WriteQuestRewardsData(Quest const* quest, ByteBuffer &data, uint32 xpValue) { data << int32(quest->GetRewChoiceItemsCount()); for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; i++) { data << int32(quest->RewardChoiceItemId[i]); data << int32(quest->RewardChoiceItemCount[i]); } data << int32(quest->GetRewItemsCount()); for (int i = 0; i < QUEST_REWARDS_COUNT; i++) { data << int32(quest->RewardItemId[i]); data << int32(quest->RewardItemIdCount[i]); } data << int32(quest->GetRewMoney()); data << int32(xpValue); data << int32(quest->GetCharTitleId()); data << int32(quest->GetBonusTalents()); data << int32(quest->GetRewardReputationMask()); for (int i = 0; i < QUEST_REPUTATIONS_COUNT; i++) { data << int32(quest->RewardFactionId[i]); data << int32(quest->RewardFactionValueId[i]); data << int32(quest->RewardFactionValueIdOverride[i]); } data << int32(quest->GetRewSpell()); data << int32(quest->GetRewSpellCast()); for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; i++) { data << int32(quest->RewardCurrencyId[i]); data << int32(quest->RewardCurrencyCount[i]); } data << int32(quest->GetRewardSkillId()); data << int32(quest->GetRewardSkillPoints()); data.WriteBit(0); // unknown data.FlushBits(); }
void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) { uint32 type; uint32 lang; recvData >> type; recvData >> lang; if (type >= MAX_CHAT_MSG_TYPE) { TC_LOG_ERROR("network", "CHAT: Wrong message type received: %u", type); recvData.rfinish(); return; } if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND) { TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str()); SendNotification(LANG_UNKNOWN_LANGUAGE); recvData.rfinish(); return; } Player* sender = GetPlayer(); //TC_LOG_DEBUG("CHAT: packet received. type %u, lang %u", type, lang); // prevent talking at unknown language (cheating) LanguageDesc const* langDesc = GetLanguageDescByID(lang); if (!langDesc) { SendNotification(LANG_UNKNOWN_LANGUAGE); recvData.rfinish(); return; } if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id)) { // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE); bool foundAura = false; for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) { if ((*i)->GetMiscValue() == int32(lang)) { foundAura = true; break; } } if (!foundAura) { SendNotification(LANG_NOT_LEARNED_LANGUAGE); recvData.rfinish(); return; } } if (lang == LANG_ADDON) { // LANG_ADDON is only valid for the following message types switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_RAID: case CHAT_MSG_GUILD: case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_WHISPER: // check if addon messages are disabled if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) { recvData.rfinish(); return; } break; default: TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); recvData.rfinish(); return; } } // LANG_ADDON should not be changed nor be affected by flood control else { // send in universal language if player in .gmon mode (ignore spell effects) if (sender->IsGameMaster()) lang = LANG_UNIVERSAL; else { Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE); if (!ModLangAuras.empty()) lang = ModLangAuras.front()->GetMiscValue(); else if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)) lang = LANG_UNIVERSAL; else { switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: // allow two side chat at group channel if two side group allowed if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) lang = LANG_UNIVERSAL; break; case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: // allow two side chat at guild channel if two side guild allowed if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) lang = LANG_UNIVERSAL; break; } } } if (!sender->CanSpeak()) { std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); recvData.rfinish(); // Prevent warnings return; } if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND) sender->UpdateSpeakTime(); } if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER) { SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); recvData.rfinish(); return; } std::string to, channel, msg; bool ignoreChecks = false; switch (type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_YELL: case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_BATTLEGROUND_LEADER: recvData >> msg; break; case CHAT_MSG_WHISPER: recvData >> to; recvData >> msg; break; case CHAT_MSG_CHANNEL: recvData >> channel; recvData >> msg; break; case CHAT_MSG_AFK: case CHAT_MSG_DND: recvData >> msg; ignoreChecks = true; break; } if (!ignoreChecks) { if (msg.empty()) return; if (ChatHandler(this).ParseCommands(msg.c_str())) return; if (lang != LANG_ADDON) { // Strip invisible characters for non-addon messages if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) stripLineInvisibleChars(msg); if (strcmp(sender->GetSession()->m_lastMessage.c_str(), msg.c_str()) != 0) sender->GetSession()->m_lastMessage = msg; else return; DisableMgr::FilterMessage(msg); if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str())) { TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow(), msg.c_str()); if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK)) KickPlayer(); return; } } } switch (type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_YELL: { // Prevent cheating if (!sender->IsAlive()) return; if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)); return; } if (IsWatcher(sender->GetGUIDLow())) { SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); return; } if (type == CHAT_MSG_SAY) sender->Say(msg, lang); else if (type == CHAT_MSG_EMOTE) sender->TextEmote(msg); else if (type == CHAT_MSG_YELL) sender->Yell(msg, lang); } break; case CHAT_MSG_WHISPER: { if (!normalizePlayerName(to)) { SendPlayerNotFoundNotice(to); break; } Player* receiver = sObjectAccessor->FindPlayerByName(to); if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) { SendPlayerNotFoundNotice(to); return; } if (!sender->IsGameMaster() && sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) { SendNotification(GetTrinityString(LANG_WHISPER_REQ), sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ)); return; } if (GetPlayer()->GetTeam() != receiver->GetTeam() && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) { SendWrongFactionNotice(); return; } if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster()) { SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName().c_str()); return; } // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to // We also do that if a player is under the required level for whispers. if (receiver->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) || (HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))) sender->AddWhisperWhiteList(receiver->GetGUID()); GetPlayer()->Whisper(msg, lang, receiver->GetGUID()); } break; case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: { // if player is in battleground, he cannot say to battleground members by /p Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = sender->GetGroup(); if (!group || group->isBGGroup()) return; } if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID())) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID())); } break; case CHAT_MSG_GUILD: { if (GetPlayer()->GetGuildId()) { if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } } } break; case CHAT_MSG_OFFICER: { if (GetPlayer()->GetGuildId()) { if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } } } break; case CHAT_MSG_RAID: { // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = GetPlayer()->GetGroup(); if (!group || group->isBGGroup() || !group->isRaidGroup()) return; } sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_LEADER: { // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = GetPlayer()->GetGroup(); if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID())) return; } sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_WARNING: { Group* group = GetPlayer()->GetGroup(); if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup()) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; //in battleground, raid warning is sent only to players in battleground - code is ok ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND: { //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); if (!group || !group->isBGGroup()) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND_LEADER: { // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID())) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, NULL, msg);; group->BroadcastPacket(&data, false); } break; case CHAT_MSG_CHANNEL: { if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ)) { if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)); return; } } if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeam())) { if (Channel* chn = cMgr->GetChannel(channel, sender)) { sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn); chn->Say(sender->GetGUID(), msg.c_str(), lang); } } } break; case CHAT_MSG_AFK: { if (!sender->IsInCombat()) { if (sender->isAFK()) // Already AFK { if (msg.empty()) sender->ToggleAFK(); // Remove AFK else sender->autoReplyMsg = msg; // Update message } else // New AFK mode { sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg; if (sender->isDND()) sender->ToggleDND(); sender->ToggleAFK(); } sScriptMgr->OnPlayerChat(sender, type, lang, msg); } break; } case CHAT_MSG_DND: { if (sender->isDND()) // Already DND { if (msg.empty()) sender->ToggleDND(); // Remove DND else sender->autoReplyMsg = msg; // Update message } else // New DND mode { sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg; if (sender->isAFK()) sender->ToggleAFK(); sender->ToggleDND(); } sScriptMgr->OnPlayerChat(sender, type, lang, msg); break; } default: TC_LOG_ERROR("network", "CHAT: unknown message type %u, lang: %u", type, lang); break; } sNinjaInquisitor->LogMessage(sender, type, lang, to, channel, msg); }
bool FSLESSoundSource::EnqueuePCMRTBuffer( bool bLoop ) { if (AudioBuffers[0].AudioData || AudioBuffers[1].AudioData) { UE_LOG( LogAndroidAudio, Warning, TEXT("Enqueue PCMRT with buffers already allocated")); } FMemory::Memzero( AudioBuffers, sizeof( SLESAudioBuffer ) * 2 ); // Set up double buffer area to decompress to BufferSize = Buffer->GetRTBufferSize() * Buffer->NumChannels; AudioBuffers[0].AudioData = (uint8*)FMemory::Malloc(BufferSize); AudioBuffers[0].AudioDataSize = BufferSize; AudioBuffers[1].AudioData = (uint8*)FMemory::Malloc(BufferSize); AudioBuffers[1].AudioDataSize = BufferSize; // Decompress two buffers worth of data to fill up the queue ReadMorePCMData(0); ReadMorePCMData(1); SLresult result; // callback is used to submit and decompress next buffer result = (*SL_PlayerBufferQueue)->RegisterCallback(SL_PlayerBufferQueue, OpenSLBufferQueueCallback, (void*)this); // queue one sound buffer, as that is all Android will accept if(result == SL_RESULT_SUCCESS) { result = (*SL_PlayerBufferQueue)->Enqueue(SL_PlayerBufferQueue, AudioBuffers[0].AudioData, AudioBuffers[0].AudioDataSize ); if(result != SL_RESULT_SUCCESS) { UE_LOG( LogAndroidAudio, Fatal,TEXT("FAILED OPENSL BUFFER Enqueue SL_PlayerBufferQueue 0x%x params( %p, %d)"), result, Buffer->AudioData, int32(Buffer->GetSize())); return false;} } else { return false; } bStreamedSound = true; bHasLooped = false; bBuffersToFlush = false; BufferInUse = 1; return true; }
int32 irand(int32 min, int32 max) { return int32(mtRand->randInt (max - min)) + min; }
// this function is called when client bids or buys out auction void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) { uint64 auctioneer; uint32 auctionId; uint32 price; recv_data >> auctioneer; recv_data >> auctionId >> price; if (!auctionId || !price) return; // check for cheaters Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionPlaceBid - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) ); return; } // remove fake death if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap( pCreature->getFaction() ); AuctionEntry *auction = auctionHouse->GetAuction(auctionId); Player *pl = GetPlayer(); if( !auction || auction->owner == pl->GetGUIDLow() ) { // you cannot bid your own auction: SendAuctionCommandResult( 0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR ); return; } // impossible have online own another character (use this for speedup check in case online owner) Player* auction_owner = sObjectMgr.GetPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)); if( !auction_owner && sObjectMgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)) == pl->GetSession()->GetAccountId()) { // you cannot bid your another character auction: SendAuctionCommandResult( 0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR ); return; } // cheating if(price <= auction->bid || price < auction->startbid) return; // price too low for next bid if not buyout if ((price < auction->buyout || auction->buyout == 0) && price < auction->bid + auction->GetAuctionOutBid()) { // auction has already higher bid, client tests it! return; } if (price > pl->GetMoney()) { // you don't have enough money!, client tests! // SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???); return; } if ((price < auction->buyout) || (auction->buyout == 0)) { if (auction->bidder > 0) { if ( auction->bidder == pl->GetGUIDLow() ) { pl->ModifyMoney( -int32(price - auction->bid)); } else { // mail to last bidder and return money SendAuctionOutbiddedMail( auction , price ); pl->ModifyMoney( -int32(price) ); } } else { pl->ModifyMoney( -int32(price) ); } auction->bidder = pl->GetGUIDLow(); auction->bid = price; GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); // after this update we should save player's money ... CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0 ); } else { // buyout: if (pl->GetGUIDLow() == auction->bidder ) { pl->ModifyMoney(-int32(auction->buyout - auction->bid)); } else { pl->ModifyMoney(-int32(auction->buyout)); if ( auction->bidder ) // buyout for bidded auction .. { SendAuctionOutbiddedMail( auction, auction->buyout ); } } auction->bidder = pl->GetGUIDLow(); auction->bid = auction->buyout; GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); sAuctionMgr.SendAuctionSalePendingMail( auction ); sAuctionMgr.SendAuctionSuccessfulMail( auction ); sAuctionMgr.SendAuctionWonMail( auction ); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK); sAuctionMgr.RemoveAItem(auction->item_guidlow); auctionHouse->RemoveAuction(auction->Id); auction->DeleteFromDB(); delete auction; } CharacterDatabase.BeginTransaction(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim() || !CheckInRoom()) return; events.Update(diff); if (me->HasUnitState(UNIT_STAT_CASTING)) return; while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_BONE_SPIKE_GRAVEYARD: if (IsHeroic() || !me->HasAura(SPELL_BONE_STORM)) DoCast(me, SPELL_BONE_SPIKE_GRAVEYARD); events.ScheduleEvent(EVENT_BONE_SPIKE_GRAVEYARD, urand(15000, 20000), EVENT_GROUP_SPECIAL); break; case EVENT_COLDFLAME: coldflameLastPos.Relocate(me); if (!me->HasAura(SPELL_BONE_STORM)) me->CastCustomSpell(SPELL_COLDFLAME_NORMAL, SPELLVALUE_MAX_TARGETS, 1, me); else DoCast(me, SPELL_COLDFLAME_BONE_STORM); events.ScheduleEvent(EVENT_COLDFLAME, 5000, EVENT_GROUP_SPECIAL); break; case EVENT_WARN_BONE_STORM: boneSlice = false; Talk(EMOTE_BONE_STORM); me->FinishSpell(CURRENT_MELEE_SPELL, false); DoCast(me, SPELL_BONE_STORM); events.DelayEvents(3000, EVENT_GROUP_SPECIAL); events.ScheduleEvent(EVENT_BONE_STORM_BEGIN, 3050); events.ScheduleEvent(EVENT_WARN_BONE_STORM, urand(90000, 95000)); break; case EVENT_BONE_STORM_BEGIN: if (Aura* pStorm = me->GetAura(SPELL_BONE_STORM)) pStorm->SetDuration(int32(boneStormDuration)); me->SetSpeed(MOVE_RUN, baseSpeed*3.0f, true); Talk(SAY_BONE_STORM); events.ScheduleEvent(EVENT_BONE_STORM_END, boneStormDuration+1); // no break here case EVENT_BONE_STORM_MOVE: { events.ScheduleEvent(EVENT_BONE_STORM_MOVE, boneStormDuration/3); Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 1); if (!unit) unit = SelectTarget(SELECT_TARGET_RANDOM, 0); if (unit) me->GetMotionMaster()->MovePoint(POINT_TARGET_BONESTORM_PLAYER, unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ()); break; } case EVENT_BONE_STORM_END: if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) me->GetMotionMaster()->MovementExpired(); DoStartMovement(me->getVictim()); me->SetSpeed(MOVE_RUN, baseSpeed, true); events.CancelEvent(EVENT_BONE_STORM_MOVE); events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000); if (!IsHeroic()) events.RescheduleEvent(EVENT_BONE_SPIKE_GRAVEYARD, urand(15000, 20000), EVENT_GROUP_SPECIAL); break; case EVENT_ENABLE_BONE_SLICE: boneSlice = true; break; case EVENT_ENRAGE: DoCast(me, SPELL_BERSERK, true); Talk(SAY_BERSERK); break; } } // We should not melee attack when storming if (me->HasAura(SPELL_BONE_STORM)) return; // After 10 seconds since encounter start Bone Slice replaces melee attacks if (boneSlice && !me->GetCurrentSpell(CURRENT_MELEE_SPELL)) DoCastVictim(SPELL_BONE_SLICE); DoMeleeAttackIfReady(); }
int32 irand (int32 min, int32 max) { return int32(sfmtRand->IRandom(min, max)); }
// send only static data in this packet! void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) { std::string Title, Details, Objectives, EndText, CompletedText; std::string ObjectiveText[QUEST_OBJECTIVES_COUNT]; Title = pQuest->GetTitle(); Details = pQuest->GetDetails(); Objectives = pQuest->GetObjectives(); EndText = pQuest->GetEndText(); CompletedText = pQuest->GetCompletedText(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) ObjectiveText[i] = pQuest->ObjectiveText[i]; int loc_idx = pSession->GetSessionDbLocaleIndex(); if (loc_idx >= 0) { QuestLocale const *ql = sObjectMgr.GetQuestLocale(pQuest->GetQuestId()); if (ql) { if (ql->Title.size() > (size_t)loc_idx && !ql->Title[loc_idx].empty()) Title=ql->Title[loc_idx]; if (ql->Details.size() > (size_t)loc_idx && !ql->Details[loc_idx].empty()) Details=ql->Details[loc_idx]; if (ql->Objectives.size() > (size_t)loc_idx && !ql->Objectives[loc_idx].empty()) Objectives=ql->Objectives[loc_idx]; if (ql->EndText.size() > (size_t)loc_idx && !ql->EndText[loc_idx].empty()) EndText=ql->EndText[loc_idx]; if (ql->CompletedText.size() > (size_t)loc_idx && !ql->CompletedText[loc_idx].empty()) CompletedText=ql->CompletedText[loc_idx]; for (int i = 0;i < QUEST_OBJECTIVES_COUNT; ++i) if (ql->ObjectiveText[i].size() > (size_t)loc_idx && !ql->ObjectiveText[i][loc_idx].empty()) ObjectiveText[i] = ql->ObjectiveText[i][loc_idx]; } } WorldPacket data( SMSG_QUEST_QUERY_RESPONSE, 100 ); // guess size data << uint32(pQuest->GetQuestId()); // quest id data << uint32(pQuest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details) data << int32(pQuest->GetQuestLevel()); // may be -1, static data, in other cases must be used dynamic level: Player::GetQuestLevelForPlayer (0 is not known, but assuming this is no longer valid for quest intended for client) data << uint32(pQuest->GetMinLevel()); // min required level to obtain (added for 3.3). Assumed allowed (database) range is -1 to 255 (still using uint32, since negative value would not be of any known use for client) data << uint32(pQuest->GetZoneOrSort()); // zone or sort to display in quest log data << uint32(pQuest->GetType()); // quest type data << uint32(pQuest->GetSuggestedPlayers()); // suggested players count data << uint32(pQuest->GetRepObjectiveFaction()); // shown in quest log as part of quest objective data << uint32(pQuest->GetRepObjectiveValue()); // shown in quest log as part of quest objective data << uint32(0); // RequiredOpositeRepFaction data << uint32(0); // RequiredOpositeRepValue, required faction value with another (oposite) faction (objective) data << uint32(pQuest->GetNextQuestInChain()); // client will request this quest from NPC, if not 0 data << uint32(pQuest->GetRewXPId()); // column index in QuestXP.dbc (row based on quest level) if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) data << uint32(0); // Hide money rewarded else data << uint32(pQuest->GetRewOrReqMoney()); // reward money (below max lvl) data << uint32(pQuest->GetRewMoneyMaxLevel()); // used in XP calculation at client data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast==0) data << uint32(pQuest->GetRewSpellCast()); // casted spell // rewarded honor points data << uint32(pQuest->GetRewHonorAddition()); data << float(pQuest->GetRewHonorMultiplier()); // new reward honor (multipled by ~62 at client side) data << uint32(pQuest->GetSrcItemId()); // source item id data << uint32(pQuest->GetFlags() & 0xFFFF); // quest flags data << uint32(pQuest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) data << uint32(pQuest->GetPlayersSlain()); // players slain data << uint32(pQuest->GetBonusTalents()); // bonus talents data << uint32(0); // bonus arena points data << uint32(0); // unknown int iI; if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS)) { for (iI = 0; iI < QUEST_REWARDS_COUNT; ++iI) data << uint32(0) << uint32(0); for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; ++iI) data << uint32(0) << uint32(0); } else { for (iI = 0; iI < QUEST_REWARDS_COUNT; ++iI) { data << uint32(pQuest->RewItemId[iI]); data << uint32(pQuest->RewItemCount[iI]); } for (iI = 0; iI < QUEST_REWARD_CHOICES_COUNT; ++iI) { data << uint32(pQuest->RewChoiceItemId[iI]); data << uint32(pQuest->RewChoiceItemCount[iI]); } } for(iI = 0; iI < QUEST_REPUTATIONS_COUNT; ++iI) // reward factions ids data << uint32(0); for(iI = 0; iI < QUEST_REPUTATIONS_COUNT; ++iI) // column index in QuestFactionReward.dbc? data << uint32(0); for(iI = 0; iI < QUEST_REPUTATIONS_COUNT; ++iI) // reward reputation override? data << uint32(0); data << pQuest->GetPointMapId(); data << pQuest->GetPointX(); data << pQuest->GetPointY(); data << pQuest->GetPointOpt(); data << Title; data << Objectives; data << Details; data << EndText; data << CompletedText; // display in quest objectives window once all objectives are completed for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; ++iI) { if (pQuest->ReqCreatureOrGOId[iI] < 0) { // client expected gameobject template id in form (id|0x80000000) data << uint32((pQuest->ReqCreatureOrGOId[iI]*(-1))|0x80000000); } else { data << uint32(pQuest->ReqCreatureOrGOId[iI]); } data << uint32(pQuest->ReqCreatureOrGOCount[iI]); data << uint32(pQuest->ReqSourceId[iI]); data << uint32(0); // req source count? } for (iI = 0; iI < QUEST_ITEM_OBJECTIVES_COUNT; ++iI) { data << uint32(pQuest->ReqItemId[iI]); data << uint32(pQuest->ReqItemCount[iI]); } for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; ++iI) data << ObjectiveText[iI]; pSession->SendPacket( &data ); sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", pQuest->GetQuestId() ); }
void WorldSession::HandleTakeItem(WorldPacket & recv_data ) { uint64 mailbox; uint32 message_id; uint32 lowguid; vector< uint64 >::iterator itr; recv_data >> mailbox >> message_id >> lowguid; WorldPacket data(SMSG_SEND_MAIL_RESULT, 12); data << message_id << uint32(MAIL_RES_ITEM_TAKEN); MailMessage * message = _player->m_mailBox->GetMessage(message_id); if(message == 0 || message->Expired() || message->items.empty()) { data << uint32(MAIL_ERR_INTERNAL_ERROR); SendPacket(&data); return; } for( itr = message->items.begin( ); itr != message->items.end( ); itr++ ) { if ( (*itr) == lowguid ) break; } if( itr == message->items.end( ) ) { data << uint32(MAIL_ERR_INTERNAL_ERROR); SendPacket(&data); return; } // check for cod credit if(message->cod > 0) { if(_player->GetUInt32Value(PLAYER_FIELD_COINAGE) < message->cod) { data << uint32(MAIL_ERR_NOT_ENOUGH_MONEY); SendPacket(&data); return; } } // grab the item Item* item = objmgr.LoadItem( *itr ); if(item == 0) { // doesn't exist data << uint32(MAIL_ERR_INTERNAL_ERROR); SendPacket(&data); return; } // find a free bag slot SlotResult result = _player->GetItemInterface()->FindFreeInventorySlot(item->GetProto()); if(result.Result == 0) { // no free slots left! data << uint32(MAIL_ERR_BAG_FULL); SendPacket(&data); item->DeleteMe(); item = NULLITEM; return; } item->m_isDirty = true; if( !_player->GetItemInterface()->SafeAddItem(item, result.ContainerSlot, result.Slot) ) { if( !_player->GetItemInterface()->AddItemToFreeSlot(item) ) { // no free slots left! data << uint32(MAIL_ERR_BAG_FULL); SendPacket(&data); item->DeleteMe(); item = NULLITEM; return; } } else // true so it waitexecute's item->SaveToDB(result.ContainerSlot, result.Slot, true, NULL); // send complete packet data << uint32(MAIL_OK); data << item->GetUInt32Value(OBJECT_FIELD_GUID); data << item->GetUInt32Value(ITEM_FIELD_STACK_COUNT); message->items.erase( itr ); if ((message->items.size() == 0) && (message->money == 0)) { // mail now has a 3 day expiry time if(!sMailSystem.MailOption(MAIL_FLAG_NO_EXPIRY)) message->expire_time = (uint32)UNIXTIME + (TIME_DAY * 3); } if( message->cod > 0 ) { _player->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -int32(message->cod)); string subject = "COD Payment: "; subject += message->subject; sMailSystem.DeliverMessage(MAILTYPE_NORMAL, message->player_guid, message->sender_guid, subject, "", message->cod, 0, 0, 1, true); message->cod = 0; CharacterDatabase.Execute("UPDATE mailbox SET cod = 0 WHERE message_id = %u", message->message_id); } // re-save (update the items field) message->SaveToDB();// sMailSystem.SaveMessageToSQL( message); SendPacket(&data); // prolly need to send an item push here }
static bool HandleWpShowCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // first arg: on, off, first, last char* show_str = strtok((char*)args, " "); if (!show_str) return false; // second arg: GUID (optional, if a creature is selected) char* guid_str = strtok((char*)NULL, " "); uint32 pathid = 0; Creature* target = handler->getSelectedCreature(); // Did player provide a PathID? if (!guid_str) { // No PathID provided // -> Player must have selected a creature if (!target) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pathid = target->GetWaypointPath(); } else { // PathID provided // Warn if player also selected a creature // -> Creature selection is ignored <- if (target) handler->SendSysMessage(LANG_WAYPOINT_CREATSELECTED); pathid = atoi((char*)guid_str); } std::string show = show_str; //handler->PSendSysMessage("wpshow - show: %s", show); // Show info for the selected waypoint if (show == "info") { // Check if the user did specify a visual waypoint if (target->GetEntry() != VISUAL_WAYPOINT) { handler->PSendSysMessage(LANG_WAYPOINT_VP_SELECT); handler->SetSentErrorMessage(true); return false; } PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_ALL_BY_WPGUID); stmt->setUInt32(0, target->GetGUIDLow()); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->SendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM); return true; } handler->SendSysMessage("|cff00ffffDEBUG: wp show info:|r"); do { Field* fields = result->Fetch(); pathid = fields[0].GetUInt32(); uint32 point = fields[1].GetUInt32(); uint32 delay = fields[2].GetUInt32(); uint32 flag = fields[3].GetUInt32(); uint32 ev_id = fields[4].GetUInt32(); uint32 ev_chance = fields[5].GetUInt32(); handler->PSendSysMessage("|cff00ff00Show info: for current point: |r|cff00ffff%u|r|cff00ff00, Path ID: |r|cff00ffff%u|r", point, pathid); handler->PSendSysMessage("|cff00ff00Show info: delay: |r|cff00ffff%u|r", delay); handler->PSendSysMessage("|cff00ff00Show info: Move flag: |r|cff00ffff%u|r", flag); handler->PSendSysMessage("|cff00ff00Show info: Waypoint event: |r|cff00ffff%u|r", ev_id); handler->PSendSysMessage("|cff00ff00Show info: Event chance: |r|cff00ffff%u|r", ev_chance); } while (result->NextRow()); return true; } if (show == "on") { PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_BY_ID); stmt->setUInt32(0, pathid); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->SendSysMessage("|cffff33ffPath no found.|r"); handler->SetSentErrorMessage(true); return false; } handler->PSendSysMessage("|cff00ff00DEBUG: wp on, PathID: |cff00ffff%u|r", pathid); // Delete all visuals for this NPC stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_WPGUID_BY_ID); stmt->setUInt32(0, pathid); PreparedQueryResult result2 = WorldDatabase.Query(stmt); if (result2) { bool hasError = false; do { Field* fields = result2->Fetch(); uint32 wpguid = fields[0].GetUInt32(); Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid); hasError = true; PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); stmt->setUInt32(0, wpguid); WorldDatabase.Execute(stmt); } else { creature->CombatStop(); creature->DeleteFromDB(); creature->AddObjectToRemoveList(); } } while (result2->NextRow()); if (hasError) { handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR1); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR2); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR3); } } do { Field* fields = result->Fetch(); uint32 point = fields[0].GetUInt32(); float x = fields[1].GetFloat(); float y = fields[2].GetFloat(); float z = fields[3].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); float o = chr->GetOrientation(); Creature* wpCreature = new Creature; if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; return false; } // Set "wpguid" column to the visual waypoint PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); stmt->setInt32(0, int32(wpCreature->GetGUIDLow())); stmt->setUInt32(1, pathid); stmt->setUInt32(2, point); WorldDatabase.Execute(stmt); wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); if (!wpCreature->LoadCreatureFromDB(wpCreature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; return false; } if (target) { wpCreature->SetDisplayId(target->GetDisplayId()); wpCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f); wpCreature->SetLevel(point > STRONG_MAX_LEVEL ? STRONG_MAX_LEVEL : point); } } while (result->NextRow()); handler->SendSysMessage("|cff00ff00Showing the current creature's path.|r"); return true; } if (show == "first") { handler->PSendSysMessage("|cff00ff00DEBUG: wp first, GUID: %u|r", pathid); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_FIRST_BY_ID); stmt->setUInt32(0, pathid); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid); handler->SetSentErrorMessage(true); return false; } Field* fields = result->Fetch(); float x = fields[0].GetFloat(); float y = fields[1].GetFloat(); float z = fields[2].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); float o = chr->GetOrientation(); Map* map = chr->GetMap(); Creature* creature = new Creature; if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } if (target) { creature->SetDisplayId(target->GetDisplayId()); creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f); } return true; } if (show == "last") { handler->PSendSysMessage("|cff00ff00DEBUG: wp last, PathID: |r|cff00ffff%u|r", pathid); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_POS_LAST_BY_ID); stmt->setUInt32(0, pathid); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, pathid); handler->SetSentErrorMessage(true); return false; } Field* fields = result->Fetch(); float x = fields[0].GetFloat(); float y = fields[1].GetFloat(); float z = fields[2].GetFloat(); float o = fields[3].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); Creature* creature = new Creature; if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } if (target) { creature->SetDisplayId(target->GetDisplayId()); creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f); } return true; } if (show == "off") { PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_BY_ID); stmt->setUInt32(0, 1); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND); handler->SetSentErrorMessage(true); return false; } bool hasError = false; do { Field* fields = result->Fetch(); uint32 guid = fields[0].GetUInt32(); Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid); hasError = true; PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); stmt->setUInt32(0, guid); WorldDatabase.Execute(stmt); } else { creature->CombatStop(); creature->DeleteFromDB(); creature->AddObjectToRemoveList(); } } while (result->NextRow()); // set "wpguid" column to "empty" - no visual waypoint spawned stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_ALL_WPGUID); WorldDatabase.Execute(stmt); //WorldDatabase.PExecute("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'"); if (hasError) { handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR1); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR2); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR3); } handler->SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED); return true; } handler->PSendSysMessage("|cffff33ffDEBUG: wpshow - no valid command found|r"); return true; }
static bool HandleMmapLocCommand(ChatHandler* handler, char const* /*args*/) { handler->PSendSysMessage("mmap tileloc:"); // grid tile location Player* player = handler->GetSession()->GetPlayer(); int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS; int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS; handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx); handler->PSendSysMessage("gridloc [%i, %i]", gx, gy); // calculate navmesh tile location dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()); dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(handler->GetSession()->GetPlayer()->GetMapId(), player->GetInstanceId()); if (!navmesh || !navmeshquery) { handler->PSendSysMessage("NavMesh not loaded for current map."); return true; } float const* min = navmesh->getParams()->orig; float x, y, z; player->GetPosition(x, y, z); float location[VERTEX_SIZE] = {y, z, x}; float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS); int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS); handler->PSendSysMessage("Calc [%02i, %02i]", tilex, tiley); // navmesh poly -> navmesh tile location dtQueryFilter filter = dtQueryFilter(); dtPolyRef polyRef = INVALID_POLYREF; if (dtStatusFailed(navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL))) { handler->PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)"); return true; } if (polyRef == INVALID_POLYREF) handler->PSendSysMessage("Dt [??, ??] (invalid poly, probably no tile loaded)"); else { dtMeshTile const* tile; dtPoly const* poly; if (dtStatusSucceed(navmesh->getTileAndPolyByRef(polyRef, &tile, &poly))) { if (tile) { handler->PSendSysMessage("Dt [%02i,%02i]", tile->header->x, tile->header->y); return false; } } handler->PSendSysMessage("Dt [??,??] (no tile loaded)"); } return true; }
void HandleOnHit() { if (Player* _player = GetCaster()->ToPlayer()) { if (Unit* target = GetHitUnit()) { // Calculate damage int32 hitDamage = GetHitDamage(); if (GetSpell()->IsCritForTarget(target)) hitDamage *= 2; float Mastery = (_player->GetFloatValue(PLAYER_MASTERY) * 2.0f) / 100.0f; hitDamage *= Mastery; int8 currentMaxAura = 0; // if hitDamage == 0 we have a miss, so we need to except this variant if (_player->HasAura(SPELL_MAGE_MASTERY_ICICLES) && hitDamage != 0) { // We need to find how much icicles we have, and which is the last. for (int i = 0; i < 5; i++) if (_player->HasAura(IcicleAuras[i])) currentMaxAura = i+1; switch (currentMaxAura) { case 0: _player->AddAura(IcicleAuras[0], _player); break; case 1: _player->AddAura(IcicleAuras[1], _player); break; case 2: _player->AddAura(IcicleAuras[2], _player); break; case 3: _player->AddAura(IcicleAuras[3], _player); break; case 4: _player->AddAura(IcicleAuras[4], _player); break; case 5: { // We need to find an icicle, with the smallest duration. int32 minDuration = 0; int32 smallestIcicle = 0; if (AuraPtr icicleCurrentAura = _player->GetAura(IcicleAuras[smallestIcicle])) minDuration = _player->GetAura(IcicleAuras[0])->GetDuration(); for (int i = 1; i < 5; i++) { if (AuraPtr tmpCurrentAura = _player->GetAura(IcicleAuras[i])) { if (minDuration > tmpCurrentAura->GetDuration()) { minDuration = tmpCurrentAura->GetDuration(); smallestIcicle = i; } } } if (AuraPtr icicleCurrentAura = _player->GetAura(IcicleAuras[smallestIcicle])) { int32 basepoints = icicleCurrentAura->GetEffect(0)->GetAmount(); _player->CastSpell(target, IcicleHits[smallestIcicle], true); _player->CastCustomSpell(target, SPELL_MAGE_ICICLE_DAMAGE, &basepoints, NULL, NULL, true); _player->RemoveAura(IcicleAuras[smallestIcicle]); } _player->AddAura(IcicleAuras[smallestIcicle], _player); if (AuraPtr icicleCurrentAura = _player->GetAura(IcicleAuras[smallestIcicle])) icicleCurrentAura->GetEffect(0)->SetAmount(int32(hitDamage)); IcicleOverstack = true; break; } } if (IcicleOverstack == false) if (AuraPtr icicleCurrentAura = _player->GetAura(IcicleAuras[currentMaxAura])) icicleCurrentAura->GetEffect(0)->SetAmount(hitDamage); } } } }
// Only _static_ data send in this packet !!! void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) { //sLog.outDebug("WORLD: CMSG_ITEM_QUERY_SINGLE"); uint32 item; recv_data >> item; sLog.outDetail("STORAGE: Item Query = %u", item); ItemPrototype const *pProto = ObjectMgr::GetItemPrototype( item ); if( pProto ) { std::string Name = pProto->Name1; std::string Description = pProto->Description; int loc_idx = GetSessionDbLocaleIndex(); if ( loc_idx >= 0 ) { ItemLocale const *il = sObjectMgr.GetItemLocale(pProto->ItemId); if (il) { if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty()) Name = il->Name[loc_idx]; if (il->Description.size() > size_t(loc_idx) && !il->Description[loc_idx].empty()) Description = il->Description[loc_idx]; } } // guess size WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600); data << pProto->ItemId; data << pProto->Class; data << pProto->SubClass; data << int32(pProto->Unk0); // new 2.0.3, not exist in wdb cache? data << Name; data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name... data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00); data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00); data << pProto->DisplayInfoID; data << pProto->Quality; data << pProto->Flags; data << pProto->Faction; // 3.2 faction? data << pProto->BuyPrice; data << pProto->SellPrice; data << pProto->InventoryType; data << pProto->AllowableClass; data << pProto->AllowableRace; data << pProto->ItemLevel; data << pProto->RequiredLevel; data << pProto->RequiredSkill; data << pProto->RequiredSkillRank; data << pProto->RequiredSpell; data << pProto->RequiredHonorRank; data << pProto->RequiredCityRank; data << pProto->RequiredReputationFaction; data << pProto->RequiredReputationRank; data << int32(pProto->MaxCount); data << int32(pProto->Stackable); data << pProto->ContainerSlots; data << pProto->StatsCount; // item stats count for(uint32 i = 0; i < pProto->StatsCount; ++i) { data << pProto->ItemStat[i].ItemStatType; data << pProto->ItemStat[i].ItemStatValue; } data << pProto->ScalingStatDistribution; // scaling stats distribution data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column for(int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) { data << pProto->Damage[i].DamageMin; data << pProto->Damage[i].DamageMax; data << pProto->Damage[i].DamageType; } // resistances (7) data << pProto->Armor; data << pProto->HolyRes; data << pProto->FireRes; data << pProto->NatureRes; data << pProto->FrostRes; data << pProto->ShadowRes; data << pProto->ArcaneRes; data << pProto->Delay; data << pProto->AmmoType; data << pProto->RangedModRange; for(int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s) { // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown // use `item_template` or if not set then only use spell cooldowns SpellEntry const* spell = sSpellStore.LookupEntry(pProto->Spells[s].SpellId); if(spell) { bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0; data << pProto->Spells[s].SpellId; data << pProto->Spells[s].SpellTrigger; data << uint32(-abs(pProto->Spells[s].SpellCharges)); if(db_data) { data << uint32(pProto->Spells[s].SpellCooldown); data << uint32(pProto->Spells[s].SpellCategory); data << uint32(pProto->Spells[s].SpellCategoryCooldown); } else { data << uint32(spell->RecoveryTime); data << uint32(spell->Category); data << uint32(spell->CategoryRecoveryTime); } } else { data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(-1); data << uint32(0); data << uint32(-1); } } data << pProto->Bonding; data << Description; data << pProto->PageText; data << pProto->LanguageID; data << pProto->PageMaterial; data << pProto->StartQuest; data << pProto->LockID; data << int32(pProto->Material); data << pProto->Sheath; data << pProto->RandomProperty; data << pProto->RandomSuffix; data << pProto->Block; data << pProto->ItemSet; data << pProto->MaxDurability; data << pProto->Area; data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch data << pProto->BagFamily; data << pProto->TotemCategory; for(int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s) { data << pProto->Socket[s].Color; data << pProto->Socket[s].Content; } data << pProto->socketBonus; data << pProto->GemProperties; data << pProto->RequiredDisenchantSkill; data << pProto->ArmorDamageModifier; data << pProto->Duration; // added in 2.4.2.8209, duration (seconds) data << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory data << pProto->HolidayId; // Holiday.dbc? SendPacket( &data ); } else { sLog.outDebug( "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item ); WorldPacket data( SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4); data << uint32(item | 0x80000000); SendPacket( &data ); } }
void WorldSession::HandleQuestPOIQueryOpcode(WorldPacket& recv_data) { uint32 count; recv_data >> count; // quest count, max=25 if(count > MAX_QUEST_LOG_SIZE) { recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam return; } WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4+(4+4)*count); data << uint32(count); // count for(uint32 i = 0; i < count; ++i) { uint32 questId; recv_data >> questId; // quest id bool questOk = false; uint16 questSlot = _player->FindQuestSlot(questId); if(questSlot != MAX_QUEST_LOG_SIZE) questOk =_player->GetQuestSlotQuestId(questSlot) == questId; if(questOk) { QuestPOIVector const *POI = sObjectMgr.GetQuestPOIVector(questId); if(POI) { data << uint32(questId); // quest ID data << uint32(POI->size()); // POI count for(QuestPOIVector::const_iterator itr = POI->begin(); itr != POI->end(); ++itr) { data << uint32(itr->PoiId); // POI index data << int32(itr->ObjectiveIndex); // objective index data << uint32(itr->MapId); // mapid data << uint32(itr->MapAreaId); // world map area id data << uint32(itr->FloorId); // floor id data << uint32(itr->Unk3); // unknown data << uint32(itr->Unk4); // unknown data << uint32(itr->points.size()); // POI points count for(std::vector<QuestPOIPoint>::const_iterator itr2 = itr->points.begin(); itr2 != itr->points.end(); ++itr2) { data << int32(itr2->x); // POI point x data << int32(itr2->y); // POI point y } } } else { data << uint32(questId); // quest ID data << uint32(0); // POI count } } else { data << uint32(questId); // quest ID data << uint32(0); // POI count } } SendPacket(&data); }
void LoadSkillDiscoveryTable() { uint32 oldMSTime = getMSTime(); SkillDiscoveryStore.clear(); // need for reload // 0 1 2 3 QueryResult result = WorldDatabase.Query("SELECT spellId, reqSpell, reqSkillValue, chance FROM skill_discovery_template"); if (!result) { sLog->outErrorDb(">> Loaded 0 skill discovery definitions. DB table `skill_discovery_template` is empty."); sLog->outString(); return; } uint32 count = 0; std::ostringstream ssNonDiscoverableEntries; std::set<uint32> reportedReqSpells; do { Field *fields = result->Fetch(); uint32 spellId = fields[0].GetUInt32(); int32 reqSkillOrSpell = fields[1].GetInt32(); uint32 reqSkillValue = fields[2].GetInt32(); float chance = fields[3].GetFloat(); if (chance <= 0) // chance { ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " reqSkillValue = " << reqSkillValue << " chance = " << chance << "(chance problem)\n"; continue; } if (reqSkillOrSpell > 0) // spell case { SpellEntry const* reqSpellEntry = sSpellStore.LookupEntry(reqSkillOrSpell); if (!reqSpellEntry) { if (reportedReqSpells.find(reqSkillOrSpell) == reportedReqSpells.end()) { sLog->outErrorDb("Spell (ID: %u) have not existed spell (ID: %i) in `reqSpell` field in `skill_discovery_template` table", spellId, reqSkillOrSpell); reportedReqSpells.insert(reqSkillOrSpell); } continue; } // mechanic discovery if (reqSpellEntry->Mechanic != MECHANIC_DISCOVERY && // explicit discovery ability !IsExplicitDiscoverySpell(reqSpellEntry)) { if (reportedReqSpells.find(reqSkillOrSpell) == reportedReqSpells.end()) { sLog->outErrorDb("Spell (ID: %u) not have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc" " and not 100%% chance random discovery ability but listed for spellId %u (and maybe more) in `skill_discovery_template` table", reqSkillOrSpell, spellId); reportedReqSpells.insert(reqSkillOrSpell); } continue; } SkillDiscoveryStore[reqSkillOrSpell].push_back(SkillDiscoveryEntry(spellId, reqSkillValue, chance)); } else if (reqSkillOrSpell == 0) // skill case { SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellId); if (bounds.first == bounds.second) { sLog->outErrorDb("Spell (ID: %u) not listed in `SkillLineAbility.dbc` but listed with `reqSpell`=0 in `skill_discovery_template` table", spellId); continue; } for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx) SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back(SkillDiscoveryEntry(spellId, reqSkillValue, chance)); } else { sLog->outErrorDb("Spell (ID: %u) have negative value in `reqSpell` field in `skill_discovery_template` table", spellId); continue; } ++count; } while (result->NextRow()); if (!ssNonDiscoverableEntries.str().empty()) sLog->outErrorDb("Some items can't be successfully discovered: have in chance field value < 0.000001 in `skill_discovery_template` DB table . List:\n%s", ssNonDiscoverableEntries.str().c_str()); // report about empty data for explicit discovery spells for (uint32 spell_id = 1; spell_id < sSpellStore.GetNumRows(); ++spell_id) { SpellEntry const* spellEntry = sSpellStore.LookupEntry(spell_id); if (!spellEntry) continue; // skip not explicit discovery spells if (!IsExplicitDiscoverySpell(spellEntry)) continue; if (SkillDiscoveryStore.find(spell_id) == SkillDiscoveryStore.end()) sLog->outErrorDb("Spell (ID: %u) is 100%% chance random discovery ability but not have data in `skill_discovery_template` table", spell_id); } sLog->outString(">> Loaded %u skill discovery definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); }
void WorldSession::HandleAcceptTradeOpcode(WorldPacket& recvPacket) { recvPacket.read_skip<uint32>(); // 7, amount traded slots ? TradeData* my_trade = _player->m_trade; if (!my_trade) return; Player* trader = my_trade->GetTrader(); TradeData* his_trade = trader->m_trade; if (!his_trade) return; Item *myItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL }; Item *hisItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL }; bool myCanCompleteTrade=true,hisCanCompleteTrade=true; // set before checks for propertly undo at problems (it already set in to client) my_trade->SetAccepted(true); // not accept case incorrect money amount if (my_trade->GetMoney() > _player->GetMoney()) { SendNotification(LANG_NOT_ENOUGH_GOLD); my_trade->SetAccepted(false, true); return; } // not accept case incorrect money amount if (his_trade->GetMoney() > trader->GetMoney()) { trader->GetSession( )->SendNotification(LANG_NOT_ENOUGH_GOLD); his_trade->SetAccepted(false, true); return; } // not accept if some items now can't be trade (cheating) for(int i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) { if (Item* item = my_trade->GetItem(TradeSlots(i))) { if (!item->CanBeTraded()) { SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); return; } } if (Item* item = his_trade->GetItem(TradeSlots(i))) { if (!item->CanBeTraded()) { SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); return; } } } if (his_trade->IsAccepted()) { setAcceptTradeMode(my_trade, his_trade, myItems, hisItems); Spell* my_spell = NULL; SpellCastTargets my_targets; Spell* his_spell = NULL; SpellCastTargets his_targets; // not accept if spell can't be casted now (cheating) if (uint32 my_spell_id = my_trade->GetSpell()) { SpellEntry const* spellEntry = sSpellStore.LookupEntry(my_spell_id); Item* castItem = my_trade->GetSpellCastItem(); if (!spellEntry || !his_trade->GetItem(TRADE_SLOT_NONTRADED) || my_trade->HasSpellCastItem() && !castItem) { clearAcceptTradeMode(my_trade, his_trade); clearAcceptTradeMode(myItems, hisItems); my_trade->SetSpell(0); return; } my_spell = new Spell(_player, spellEntry, true); my_spell->m_CastItem = castItem; my_targets.setTradeItemTarget(_player); my_spell->m_targets = my_targets; SpellCastResult res = my_spell->CheckCast(true); if (res != SPELL_CAST_OK) { my_spell->SendCastResult(res); clearAcceptTradeMode(my_trade, his_trade); clearAcceptTradeMode(myItems, hisItems); delete my_spell; my_trade->SetSpell(0); return; } } // not accept if spell can't be casted now (cheating) if (uint32 his_spell_id = his_trade->GetSpell()) { SpellEntry const* spellEntry = sSpellStore.LookupEntry(his_spell_id); Item* castItem = his_trade->GetSpellCastItem(); if (!spellEntry || !my_trade->GetItem(TRADE_SLOT_NONTRADED) || his_trade->HasSpellCastItem() && !castItem) { delete my_spell; his_trade->SetSpell(0); clearAcceptTradeMode(my_trade, his_trade); clearAcceptTradeMode(myItems, hisItems); return; } his_spell = new Spell(trader, spellEntry, true); his_spell->m_CastItem = castItem; his_targets.setTradeItemTarget(trader); his_spell->m_targets = his_targets; SpellCastResult res = his_spell->CheckCast(true); if (res != SPELL_CAST_OK) { his_spell->SendCastResult(res); clearAcceptTradeMode(my_trade, his_trade); clearAcceptTradeMode(myItems, hisItems); delete my_spell; delete his_spell; his_trade->SetSpell(0); return; } } // inform partner client trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); // test if item will fit in each inventory hisCanCompleteTrade = (trader->CanStoreItems( myItems,TRADE_SLOT_TRADED_COUNT )== EQUIP_ERR_OK); myCanCompleteTrade = (_player->CanStoreItems( hisItems,TRADE_SLOT_TRADED_COUNT ) == EQUIP_ERR_OK); clearAcceptTradeMode(myItems, hisItems); // in case of missing space report error if(!myCanCompleteTrade) { clearAcceptTradeMode(my_trade, his_trade); SendNotification(LANG_NOT_FREE_TRADE_SLOTS); trader->GetSession( )->SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); my_trade->SetAccepted(false); his_trade->SetAccepted(false); return; } else if (!hisCanCompleteTrade) { clearAcceptTradeMode(my_trade, his_trade); SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); trader->GetSession()->SendNotification(LANG_NOT_FREE_TRADE_SLOTS); my_trade->SetAccepted(false); his_trade->SetAccepted(false); return; } // execute trade: 1. remove for(int i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) { if (Item* item = myItems[i]) { item->SetGuidValue(ITEM_FIELD_GIFTCREATOR, _player->GetObjectGuid()); _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true); } if (Item* item = hisItems[i]) { item->SetGuidValue(ITEM_FIELD_GIFTCREATOR, trader->GetObjectGuid()); trader->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true); } } // execute trade: 2. store moveItems(myItems, hisItems); // logging money if (sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE)) { if (_player->GetSession()->GetSecurity() > SEC_PLAYER && my_trade->GetMoney() > 0) { sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", _player->GetName(),_player->GetSession()->GetAccountId(), my_trade->GetMoney(), trader->GetName(), trader->GetSession()->GetAccountId()); } if (trader->GetSession()->GetSecurity() > SEC_PLAYER && his_trade->GetMoney() > 0) { sLog.outCommand(trader->GetSession()->GetAccountId(),"GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", trader->GetName(), trader->GetSession()->GetAccountId(), his_trade->GetMoney(), _player->GetName(),_player->GetSession()->GetAccountId()); } } // update money _player->ModifyMoney( -int32(my_trade->GetMoney()) ); _player->ModifyMoney(his_trade->GetMoney()); trader->ModifyMoney( -int32(his_trade->GetMoney()) ); trader->ModifyMoney(my_trade->GetMoney()); if (my_spell) my_spell->prepare(&my_targets); if (his_spell) his_spell->prepare(&his_targets); // cleanup clearAcceptTradeMode(my_trade, his_trade); delete _player->m_trade; _player->m_trade = NULL; delete trader->m_trade; trader->m_trade = NULL; // desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards) CharacterDatabase.BeginTransaction(); _player->SaveInventoryAndGoldToDB(); trader->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); } else { trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); } }
void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8+4); uint64 guid; uint32 spellId = 0; recv_data >> guid >> spellId; sLog.outDebug( "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u",uint32(GUID_LOPART(guid)), spellId ); Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_TRAINER); if (!unit) { sLog.outDebug( "WORLD: HandleTrainerBuySpellOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); return; } // remove fake death if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); if(!unit->isCanTrainingOf(_player,true)) return; // check present spell in trainer spell list TrainerSpellData const* trainer_spells = unit->GetTrainerSpells(); if(!trainer_spells) return; // not found, cheat? TrainerSpell const* trainer_spell = trainer_spells->Find(spellId); if(!trainer_spell) return; // can't be learn, cheat? Or double learn with lags... if(_player->GetTrainerSpellState(trainer_spell) != TRAINER_SPELL_GREEN) return; // apply reputation discount uint32 nSpellCost = uint32(floor(trainer_spell->spellcost * _player->GetReputationPriceDiscount(unit))); // check money requirement if(_player->GetMoney() < nSpellCost ) return; WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer data << uint64(guid) << uint32(0xB3); SendPacket(&data); data.Initialize(SMSG_PLAY_SPELL_IMPACT, 12); // visual effect on player data << uint64(_player->GetGUID()) << uint32(0x016A); SendPacket(&data); _player->ModifyMoney( -int32(nSpellCost) ); // learn explicitly to prevent lost money at lags, learning spell will be only show spell animation _player->learnSpell(trainer_spell->spell); data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12); data << uint64(guid) << uint32(spellId); SendPacket(&data); }
void HandleDummy(SpellEffIndex /*effIndex*/) { int32 healthModSpellBasePoints0 = int32(GetCaster()->CountPctFromMaxHealth(30)); GetCaster()->CastCustomSpell(GetCaster(), WARRIOR_SPELL_LAST_STAND_TRIGGERED, &healthModSpellBasePoints0, NULL, NULL, true, NULL); }
void CalculateDamage(SpellEffIndex effect) { // Formula: 8 + AttackPower * 60 / 100 if (Unit* caster = GetCaster()) SetHitDamage(int32(8 + caster->GetTotalAttackPowerValue(BASE_ATTACK) * 60 / 100)); }
//this void creates new auction and adds auction to some auctionhouse void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) { uint64 auctioneer, bid, buyout; uint32 itemsCount, etime; recvData >> auctioneer; recvData >> itemsCount; uint64 itemGUIDs[MAX_AUCTION_ITEMS]; // 160 slot = 4x 36 slot bag + backpack 16 slot uint32 count[MAX_AUCTION_ITEMS]; if (itemsCount > MAX_AUCTION_ITEMS) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); recvData.rfinish(); return; } for (uint32 i = 0; i < itemsCount; ++i) { recvData >> itemGUIDs[i]; recvData >> count[i]; if (!itemGUIDs[i] || !count[i] || count[i] > 1000) { recvData.rfinish(); return; } } recvData >> bid; recvData >> buyout; recvData >> etime; if (!bid || !etime) return; if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player %s (GUID %u) attempted to sell item with higher price than max gold amount.", _player->GetName().c_str(), _player->GetGUIDLow()); SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(auctioneer)); return; } AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(creature->getFaction()); if (!auctionHouseEntry) { TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit (GUID: %u) has wrong faction.", GUID_LOPART(auctioneer)); return; } etime *= MINUTE; switch (etime) { case 1*MIN_AUCTION_TIME: case 2*MIN_AUCTION_TIME: case 4*MIN_AUCTION_TIME: break; default: return; } if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); Item* items[MAX_AUCTION_ITEMS]; uint32 finalCount = 0; for (uint32 i = 0; i < itemsCount; ++i) { Item* item = _player->GetItemByGuid(itemGUIDs[i]); if (!item) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_ITEM_NOT_FOUND); return; } if (sAuctionMgr->GetAItem(item->GetGUIDLow()) || !item->CanBeTraded() || item->IsNotEmptyBag() || item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_EXPIRATION) || item->GetCount() < count[i]) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } items[i] = item; finalCount += count[i]; } if (!finalCount) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } for (uint32 i = 0; i < itemsCount; ++i) { Item* item = items[i]; if (item->GetMaxStackCount() < finalCount) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } } Item* item = items[0]; uint32 auctionTime = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME)); AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction()); uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount); if (!_player->HasEnoughMoney((uint64)deposit)) { SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_NOT_ENOUGHT_MONEY); return; } AuctionEntry* AH = new AuctionEntry(); if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) AH->auctioneer = 23442; ///@TODO - HARDCODED DB GUID, BAD BAD BAD else AH->auctioneer = GUID_LOPART(auctioneer); // Required stack size of auction matches to current item stack size, just move item to auctionhouse if (itemsCount == 1 && item->GetCount() == count[0]) { if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount()); } AH->Id = sObjectMgr->GenerateAuctionID(); AH->itemGUIDLow = item->GetGUIDLow(); AH->itemEntry = item->GetEntry(); AH->itemCount = item->GetCount(); AH->owner = _player->GetGUIDLow(); AH->startbid = bid; AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; AH->expire_time = time(NULL) + auctionTime; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) " "to auctioneer %u with count %u with initial bid " UI64FMTD " with buyout " UI64FMTD " and with time %u (in sec) in auctionhouse %u", _player->GetName().c_str(), _player->GetGUIDLow(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUIDLow(), AH->auctioneer, item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(item); auctionHouse->AddAuction(AH); _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true); SQLTransaction trans = CharacterDatabase.BeginTransaction(); item->DeleteFromInventoryDB(trans); item->SaveToDB(trans); AH->SaveToDB(trans); _player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); SendAuctionCommandResult(AH, AUCTION_SELL_ITEM, ERR_AUCTION_OK); GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size { Item* newItem = item->CloneItem(finalCount, _player); if (!newItem) { TC_LOG_ERROR("network", "CMSG_AUCTION_SELL_ITEM: Could not create clone of item %u", item->GetEntry()); SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); delete AH; return; } if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName().c_str(), GetAccountId(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetCount()); } AH->Id = sObjectMgr->GenerateAuctionID(); AH->itemGUIDLow = newItem->GetGUIDLow(); AH->itemEntry = newItem->GetEntry(); AH->itemCount = newItem->GetCount(); AH->owner = _player->GetGUIDLow(); AH->startbid = bid; AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; AH->expire_time = time(NULL) + auctionTime; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to " "auctioneer %u with count %u with initial bid " UI64FMTD " with buyout " UI64FMTD " and with time %u (in sec) in auctionhouse %u", _player->GetName().c_str(), _player->GetGUIDLow(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetGUIDLow(), AH->auctioneer, newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(newItem); auctionHouse->AddAuction(AH); for (uint32 j = 0; j < itemsCount; ++j) { Item* item2 = items[j]; // Item stack count equals required count, ready to delete item - cloned item will be used for auction if (item2->GetCount() == count[j]) { _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true); SQLTransaction trans = CharacterDatabase.BeginTransaction(); item2->DeleteFromInventoryDB(trans); item2->DeleteFromDB(trans); CharacterDatabase.CommitTransaction(trans); } else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction { item2->SetCount(item2->GetCount() - count[j]); item2->SetState(ITEM_CHANGED, _player); _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]); item2->SendUpdateToPlayer(_player); SQLTransaction trans = CharacterDatabase.BeginTransaction(); item2->SaveToDB(trans); CharacterDatabase.CommitTransaction(trans); } } SQLTransaction trans = CharacterDatabase.BeginTransaction(); newItem->SaveToDB(trans); AH->SaveToDB(trans); _player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); SendAuctionCommandResult(AH, AUCTION_SELL_ITEM, ERR_AUCTION_OK); GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } _player->ModifyMoney(-int32(deposit)); }
int32 rand32 () { return int32(sfmtRand->BRandom()); }
void BPose::DrawBar(BPoint where, BView* view, icon_size which) { view->PushState(); int32 size; int32 barWidth; int32 barHeight; int32 yOffset; if (which >= B_LARGE_ICON) { size = which - 1; barWidth = (int32)(7.0f / 32.0f * (float)which); yOffset = 2; barHeight = size - 4 - 2 * yOffset; } else { size = B_MINI_ICON; barWidth = 4; yOffset = 0; barHeight = size - 4 - 2 * yOffset; } // the black shadowed line view->SetHighColor(32, 32, 32, 92); view->MovePenTo(BPoint(where.x + size, where.y + 1 + yOffset)); view->StrokeLine(BPoint(where.x + size, where.y + size - yOffset)); view->StrokeLine(BPoint(where.x + size - barWidth + 1, where.y + size - yOffset)); view->SetDrawingMode(B_OP_ALPHA); // the gray frame view->SetHighColor(76, 76, 76, 192); BRect rect(where.x + size - barWidth,where.y + yOffset, where.x + size - 1,where.y + size - 1 - yOffset); view->StrokeRect(rect); // calculate bar height int32 percent = fPercent > -1 ? fPercent : -2 - fPercent; int32 barPos = int32(barHeight * percent / 100.0); if (barPos < 0) barPos = 0; else if (barPos > barHeight) barPos = barHeight; // the free space bar view->SetHighColor(TrackerSettings().FreeSpaceColor()); rect.InsetBy(1,1); BRect bar(rect); bar.bottom = bar.top + barPos - 1; if (barPos > 0) view->FillRect(bar); // the used space bar bar.top = bar.bottom + 1; bar.bottom = rect.bottom; view->SetHighColor(fPercent < -1 ? TrackerSettings().WarningSpaceColor() : TrackerSettings().UsedSpaceColor()); view->FillRect(bar); view->PopState(); }
// this void creates new auction and adds auction to some auctionhouse void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) { uint64 auctioneer, item; uint32 etime, bid, buyout; recv_data >> auctioneer; recv_data.read_skip<uint32>(); // const 1? recv_data >> item; recv_data.read_skip<uint32>(); // stack size recv_data >> bid; recv_data >> buyout; recv_data >> etime; Player *pl = GetPlayer(); if (!item || !bid || !etime) return; // check for cheaters Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) ); return; } AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(pCreature->getFaction()); if(!auctionHouseEntry) { sLog.outDebug( "WORLD: HandleAuctionSellItem - Unit (GUID: %u) has wrong faction.", uint32(GUID_LOPART(auctioneer)) ); return; } // client send time in minutes, convert to common used sec time etime *= MINUTE; // client understand only 3 auction time switch(etime) { case 1*MIN_AUCTION_TIME: case 2*MIN_AUCTION_TIME: case 4*MIN_AUCTION_TIME: break; default: return; } // remove fake death if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); Item *it = pl->GetItemByGuid( item ); // do not allow to sell already auctioned items if(sAuctionMgr.GetAItem(GUID_LOPART(item))) { sLog.outError("AuctionError, player %s is sending item id: %u, but item is already in another auction", pl->GetName(), GUID_LOPART(item)); SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; } // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to auction) if(!it) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_ITEM_NOT_FOUND); return; } if(!it->CanBeTraded()) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; } if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION)) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; } AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap( pCreature->getFaction() ); //we have to take deposit : uint32 deposit = AuctionHouseMgr::GetAuctionDeposit( auctionHouseEntry, etime, it ); if ( pl->GetMoney() < deposit ) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY); return; } if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE) ) { sLog.outCommand(GetAccountId(),"GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName(), GetAccountId(), it->GetProto()->Name1, it->GetEntry(), it->GetCount()); } pl->ModifyMoney( -int32(deposit) ); uint32 auction_time = uint32(etime * sWorld.getConfig(CONFIG_FLOAT_RATE_AUCTION_TIME)); AuctionEntry *AH = new AuctionEntry; AH->Id = sObjectMgr.GenerateAuctionID(); // Added by AHBot, Unknown use (Commented) /*if(sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) AH->auctioneer = 23442; else AH->auctioneer = GUID_LOPART(auctioneer);*/ // Original AH->auctioneer = GUID_LOPART(auctioneer); AH->item_guidlow = GUID_LOPART(item); AH->item_template = it->GetEntry(); AH->owner = pl->GetGUIDLow(); AH->startbid = bid; AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; AH->expire_time = time(NULL) + auction_time; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; // Modified for AHBot sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", GUID_LOPART(item), AH->auctioneer, bid, buyout, auction_time, AH->GetHouseId()); auctionHouse->AddAuction(AH); sAuctionMgr.AddAItem(it); pl->MoveItemFromInventory( it->GetBagSlot(), it->GetSlot(), true); CharacterDatabase.BeginTransaction(); it->DeleteFromInventoryDB(); it->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone AH->SaveToDB(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); }
Application::Application(int &argc, char **argv) : PsApplication(argc, argv), serverName(psServerPrefix() + cGUIDStr()), closing(false), updateRequestId(0), updateReply(0), updateThread(0), updateDownloader(0) { DEBUG_LOG(("Application Info: creation..")); QByteArray d(QDir((cPlatform() == dbipWindows ? cExeDir() : cWorkingDir()).toLower()).absolutePath().toUtf8()); char h[33] = { 0 }; hashMd5Hex(d.constData(), d.size(), h); serverName = psServerPrefix() + h + '-' + cGUIDStr(); if (mainApp) { DEBUG_LOG(("Application Error: another Application was created, terminating..")); exit(0); } mainApp = this; installEventFilter(new _DebugWaiter(this)); #if defined Q_OS_LINUX || defined Q_OS_LINUX64 QFontDatabase::addApplicationFont(qsl(":/gui/art/fonts/DejaVuSans.ttf")); QFontDatabase::addApplicationFont(qsl(":/gui/art/fonts/NanumMyeongjo-Regular.ttf")); #endif QFontDatabase::addApplicationFont(qsl(":/gui/art/fonts/OpenSans-Regular.ttf")); QFontDatabase::addApplicationFont(qsl(":/gui/art/fonts/OpenSans-Bold.ttf")); QFontDatabase::addApplicationFont(qsl(":/gui/art/fonts/OpenSans-Semibold.ttf")); float64 dpi = primaryScreen()->logicalDotsPerInch(); if (dpi <= 108) { // 0-96-108 cSetScreenScale(dbisOne); } else if (dpi <= 132) { // 108-120-132 cSetScreenScale(dbisOneAndQuarter); } else if (dpi <= 168) { // 132-144-168 cSetScreenScale(dbisOneAndHalf); } else { // 168-192-inf cSetScreenScale(dbisTwo); } if (devicePixelRatio() > 1) { cSetRetina(true); cSetRetinaFactor(devicePixelRatio()); cSetIntRetinaFactor(int32(cRetinaFactor())); } if (!cLangFile().isEmpty() && QFileInfo(cLangFile()).exists()) { LangLoaderPlain loader(cLangFile()); cSetLangErrors(loader.errors()); if (!cLangErrors().isEmpty()) { LOG(("Lang load errors: %1").arg(cLangErrors())); } else if (!loader.warnings().isEmpty()) { LOG(("Lang load warnings: %1").arg(loader.warnings())); } } Local::start(); style::startManager(); anim::startManager(); historyInit(); DEBUG_LOG(("Application Info: inited..")); window = new Window(); psInstallEventFilter(); connect(&socket, SIGNAL(connected()), this, SLOT(socketConnected())); connect(&socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); connect(&socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(socketError(QLocalSocket::LocalSocketError))); connect(&socket, SIGNAL(bytesWritten(qint64)), this, SLOT(socketWritten(qint64))); connect(&socket, SIGNAL(readyRead()), this, SLOT(socketReading())); connect(&server, SIGNAL(newConnection()), this, SLOT(newInstanceConnected())); connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication())); connect(&updateCheckTimer, SIGNAL(timeout()), this, SLOT(startUpdateCheck())); connect(this, SIGNAL(updateFailed()), this, SLOT(onUpdateFailed())); connect(this, SIGNAL(updateReady()), this, SLOT(onUpdateReady())); connect(this, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onAppStateChanged(Qt::ApplicationState))); connect(&writeUserConfigTimer, SIGNAL(timeout()), this, SLOT(onWriteUserConfig())); writeUserConfigTimer.setSingleShot(true); connect(&killDownloadSessionsTimer, SIGNAL(timeout()), this, SLOT(killDownloadSessions())); if (cManyInstance()) { startApp(); } else { DEBUG_LOG(("Application Info: connecting local socket to %1..").arg(serverName)); socket.connectToServer(serverName); } }
// this void is called when auction_owner cancels his auction void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) { uint64 auctioneer; uint32 auctionId; recv_data >> auctioneer; recv_data >> auctionId; //sLog.outDebug( "Cancel AUCTION AuctionID: %u", auctionId); Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionRemoveItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) ); return; } // remove fake death if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap( pCreature->getFaction() ); AuctionEntry *auction = auctionHouse->GetAuction(auctionId); Player *pl = GetPlayer(); if (auction && auction->owner == pl->GetGUIDLow()) { Item *pItem = sAuctionMgr.GetAItem(auction->item_guidlow); if (pItem) { if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid { uint32 auctionCut = auction->GetAuctionCut(); if ( pl->GetMoney() < auctionCut ) //player doesn't have enough money, maybe message needed return; //some auctionBidderNotification would be needed, but don't know that parts.. SendAuctionCancelledToBidderMail( auction ); pl->ModifyMoney( -int32(auctionCut) ); } // Return the item by mail std::ostringstream msgAuctionCanceledOwner; msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED << ":0:0"; // item will deleted or added to received mail list MailDraft(msgAuctionCanceledOwner.str(), "") // TODO: fix body .AddItem(pItem) .SendMailTo(pl, auction); } else { sLog.outError("Auction id: %u has non-existed item (item guid : %u)!!!", auction->Id, auction->item_guidlow); SendAuctionCommandResult( 0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR ); return; } } else { SendAuctionCommandResult( 0, AUCTION_CANCEL, AUCTION_INTERNAL_ERROR ); //this code isn't possible ... maybe there should be ASSERT sLog.outError("CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", pl->GetGUIDLow(), auctionId ); return; } //inform player, that auction is removed SendAuctionCommandResult( auction->Id, AUCTION_CANCEL, AUCTION_OK ); // Now remove the auction CharacterDatabase.BeginTransaction(); auction->DeleteFromDB(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); sAuctionMgr.RemoveAItem( auction->item_guidlow ); auctionHouse->RemoveAuction( auction->Id ); delete auction; }
bool Rand(float chance) { int32 val = RandomUInt(10000); int32 p = int32(chance * 100.0f); return p >= val; }
bool FSLESSoundSource::EnqueuePCMBuffer( bool bLoop) { SLresult result; // If looping, register a callback to requeue the buffer if( bLoop ) { result = (*SL_PlayerBufferQueue)->RegisterCallback(SL_PlayerBufferQueue, OpenSLBufferQueueCallback, (void*)this); if(result != SL_RESULT_SUCCESS) { UE_LOG( LogAndroidAudio, Fatal,TEXT("FAILED OPENSL BUFFER QUEUE RegisterCallback 0x%x "), result); return false;} } result = (*SL_PlayerBufferQueue)->Enqueue(SL_PlayerBufferQueue, Buffer->AudioData, Buffer->GetSize() ); if(result != SL_RESULT_SUCCESS) { UE_LOG( LogAndroidAudio, Fatal,TEXT("FAILED OPENSL BUFFER Enqueue SL_PlayerBufferQueue 0x%x params( %p, %d)"), result, Buffer->AudioData, int32(Buffer->GetSize())); return false;} bStreamedSound = false; bHasLooped = false; bBuffersToFlush = false; return true; }
bool Rand(uint32 chance) { int32 val = RandomUInt(10000); int32 p = int32(chance * 100); return p >= val; }
/// Process queued scripts void Map::ScriptsProcess() { if (m_scriptSchedule.empty()) return; ///- Process overdue queued scripts ScriptScheduleMap::iterator iter = m_scriptSchedule.begin(); // ok as multimap is a *sorted* associative container while (!m_scriptSchedule.empty() && (iter->first <= sWorld->GetGameTime())) { ScriptAction const& step = iter->second; Object* source = NULL; if (step.sourceGUID) { switch (GUID_HIPART(step.sourceGUID)) { case HIGHGUID_ITEM: // as well as HIGHGUID_CONTAINER if (Player* player = HashMapHolder<Player>::Find(step.ownerGUID)) source = player->GetItemByGuid(step.sourceGUID); break; case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: source = HashMapHolder<Creature>::Find(step.sourceGUID); break; case HIGHGUID_PET: source = HashMapHolder<Pet>::Find(step.sourceGUID); break; case HIGHGUID_PLAYER: source = HashMapHolder<Player>::Find(step.sourceGUID); break; case HIGHGUID_GAMEOBJECT: source = HashMapHolder<GameObject>::Find(step.sourceGUID); break; case HIGHGUID_CORPSE: source = HashMapHolder<Corpse>::Find(step.sourceGUID); break; case HIGHGUID_MO_TRANSPORT: for (MapManager::TransportSet::iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == step.sourceGUID) { source = *iter; break; } } break; default: sLog->outError("%s source with unsupported high guid (GUID: " UI64FMTD ", high guid: %u).", step.script->GetDebugInfo().c_str(), step.sourceGUID, GUID_HIPART(step.sourceGUID)); break; } } Object* target = NULL; if (step.targetGUID) { switch (GUID_HIPART(step.targetGUID)) { case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: target = HashMapHolder<Creature>::Find(step.targetGUID); break; case HIGHGUID_PET: target = HashMapHolder<Pet>::Find(step.targetGUID); break; case HIGHGUID_PLAYER: // empty GUID case also target = HashMapHolder<Player>::Find(step.targetGUID); break; case HIGHGUID_GAMEOBJECT: target = HashMapHolder<GameObject>::Find(step.targetGUID); break; case HIGHGUID_CORPSE: target = HashMapHolder<Corpse>::Find(step.targetGUID); break; default: sLog->outError("%s target with unsupported high guid (GUID: " UI64FMTD ", high guid: %u).", step.script->GetDebugInfo().c_str(), step.targetGUID, GUID_HIPART(step.targetGUID)); break; } } switch (step.script->command) { case SCRIPT_COMMAND_TALK: if (step.script->Talk.ChatType > CHAT_TYPE_WHISPER && step.script->Talk.ChatType != CHAT_MSG_RAID_BOSS_WHISPER) { sLog->outError("%s invalid chat type (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->Talk.ChatType); break; } if (step.script->Talk.Flags & SF_TALK_USE_PLAYER) { if (Player* pSource = _GetScriptPlayerSourceOrTarget(source, target, step.script)) { LocaleConstant loc_idx = pSource->GetSession()->GetSessionDbLocaleIndex(); std::string text(sObjectMgr->GetTrinityString(step.script->Talk.TextID, loc_idx)); switch (step.script->Talk.ChatType) { case CHAT_TYPE_SAY: pSource->Say(text, LANG_UNIVERSAL); break; case CHAT_TYPE_YELL: pSource->Yell(text, LANG_UNIVERSAL); break; case CHAT_TYPE_TEXT_EMOTE: case CHAT_TYPE_BOSS_EMOTE: pSource->TextEmote(text); break; case CHAT_TYPE_WHISPER: case CHAT_MSG_RAID_BOSS_WHISPER: { uint64 targetGUID = target ? target->GetGUID() : 0; if (!targetGUID || !IS_PLAYER_GUID(targetGUID)) sLog->outError("%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str()); else pSource->Whisper(text, LANG_UNIVERSAL, targetGUID); break; } default: break; // must be already checked at load } } } else { // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { uint64 targetGUID = target ? target->GetGUID() : 0; switch (step.script->Talk.ChatType) { case CHAT_TYPE_SAY: cSource->Say(step.script->Talk.TextID, LANG_UNIVERSAL, targetGUID); break; case CHAT_TYPE_YELL: cSource->Yell(step.script->Talk.TextID, LANG_UNIVERSAL, targetGUID); break; case CHAT_TYPE_TEXT_EMOTE: cSource->TextEmote(step.script->Talk.TextID, targetGUID); break; case CHAT_TYPE_BOSS_EMOTE: cSource->MonsterTextEmote(step.script->Talk.TextID, targetGUID, true); break; case CHAT_TYPE_WHISPER: if (!targetGUID || !IS_PLAYER_GUID(targetGUID)) sLog->outError("%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str()); else cSource->Whisper(step.script->Talk.TextID, targetGUID); break; case CHAT_MSG_RAID_BOSS_WHISPER: if (!targetGUID || !IS_PLAYER_GUID(targetGUID)) sLog->outError("%s attempt to raidbosswhisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str()); else cSource->MonsterWhisper(step.script->Talk.TextID, targetGUID, true); break; default: break; // must be already checked at load } } } break; case SCRIPT_COMMAND_EMOTE: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { if (step.script->Emote.Flags & SF_EMOTE_USE_STATE) cSource->SetUInt32Value(UNIT_NPC_EMOTESTATE, step.script->Emote.EmoteID); else cSource->HandleEmoteCommand(step.script->Emote.EmoteID); } break; case SCRIPT_COMMAND_FIELD_SET: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { // Validate field number. if (step.script->FieldSet.FieldID <= OBJECT_FIELD_ENTRY || step.script->FieldSet.FieldID >= cSource->GetValuesCount()) sLog->outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FieldSet.FieldID, cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUIDLow()); else cSource->SetUInt32Value(step.script->FieldSet.FieldID, step.script->FieldSet.FieldValue); } break; case SCRIPT_COMMAND_MOVE_TO: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { cSource->SendMonsterMoveWithSpeed(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, step.script->MoveTo.TravelTime); cSource->GetMap()->CreatureRelocation(cSource, step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, 0); } break; case SCRIPT_COMMAND_FLAG_SET: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { // Validate field number. if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount()) sLog->outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID, source->GetValuesCount(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow()); else cSource->SetFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue); } break; case SCRIPT_COMMAND_FLAG_REMOVE: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { // Validate field number. if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount()) sLog->outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID, source->GetValuesCount(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow()); else cSource->RemoveFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue); } break; case SCRIPT_COMMAND_TELEPORT_TO: if (step.script->TeleportTo.Flags & SF_TELEPORT_USE_CREATURE) { // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true)) cSource->NearTeleportTo(step.script->TeleportTo.DestX, step.script->TeleportTo.DestY, step.script->TeleportTo.DestZ, step.script->TeleportTo.Orientation); } else { // Source or target must be Player. if (Player* pSource = _GetScriptPlayerSourceOrTarget(source, target, step.script)) pSource->TeleportTo(step.script->TeleportTo.MapID, step.script->TeleportTo.DestX, step.script->TeleportTo.DestY, step.script->TeleportTo.DestZ, step.script->TeleportTo.Orientation); } break; case SCRIPT_COMMAND_QUEST_EXPLORED: { if (!source) { sLog->outError("%s source object is NULL.", step.script->GetDebugInfo().c_str()); break; } if (!target) { sLog->outError("%s target object is NULL.", step.script->GetDebugInfo().c_str()); break; } // when script called for item spell casting then target == (unit or GO) and source is player WorldObject* worldObject; Player* plrTarget = target->ToPlayer(); if (plrTarget) { if (source->GetTypeId() != TYPEID_UNIT && source->GetTypeId() != TYPEID_GAMEOBJECT && source->GetTypeId() != TYPEID_PLAYER) { sLog->outError("%s source is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow()); break; } worldObject = dynamic_cast<WorldObject*>(source); } else { plrTarget = source->ToPlayer(); if (plrTarget) { if (target->GetTypeId() != TYPEID_UNIT && target->GetTypeId() != TYPEID_GAMEOBJECT && target->GetTypeId() != TYPEID_PLAYER) { sLog->outError("%s target is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); break; } worldObject = dynamic_cast<WorldObject*>(target); } else { sLog->outError("%s neither source nor target is player (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); break; } } // quest id and flags checked at script loading if ((worldObject->GetTypeId() != TYPEID_UNIT || ((Unit*)worldObject)->isAlive()) && (step.script->QuestExplored.Distance == 0 || worldObject->IsWithinDistInMap(plrTarget, float(step.script->QuestExplored.Distance)))) plrTarget->AreaExploredOrEventHappens(step.script->QuestExplored.QuestID); else plrTarget->FailQuest(step.script->QuestExplored.QuestID); break; } case SCRIPT_COMMAND_KILL_CREDIT: // Source or target must be Player. if (Player* pSource = _GetScriptPlayerSourceOrTarget(source, target, step.script)) { if (step.script->KillCredit.Flags & SF_KILLCREDIT_REWARD_GROUP) pSource->RewardPlayerAndGroupAtEvent(step.script->KillCredit.CreatureEntry, pSource); else pSource->KilledMonsterCredit(step.script->KillCredit.CreatureEntry, 0); } break; case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT: if (!step.script->RespawnGameobject.GOGuid) { sLog->outError("%s gameobject guid (datalong) is not specified.", step.script->GetDebugInfo().c_str()); break; } // Source or target must be WorldObject. if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script)) { GameObject* pGO = _FindGameObject(pSummoner, step.script->RespawnGameobject.GOGuid); if (!pGO) { sLog->outError("%s gameobject was not found (guid: %u).", step.script->GetDebugInfo().c_str(), step.script->RespawnGameobject.GOGuid); break; } if (pGO->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE || pGO->GetGoType() == GAMEOBJECT_TYPE_DOOR || pGO->GetGoType() == GAMEOBJECT_TYPE_BUTTON || pGO->GetGoType() == GAMEOBJECT_TYPE_TRAP) { sLog->outError("%s can not be used with gameobject of type %u (guid: %u).", step.script->GetDebugInfo().c_str(), uint32(pGO->GetGoType()), step.script->RespawnGameobject.GOGuid); break; } // Check that GO is not spawned if (!pGO->isSpawned()) { int32 nTimeToDespawn = std::max(5, int32(step.script->RespawnGameobject.DespawnDelay)); pGO->SetLootState(GO_READY); pGO->SetRespawnTime(nTimeToDespawn); pGO->GetMap()->AddToMap(pGO); } } break; case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE: { // Source must be WorldObject. if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script)) { if (!step.script->TempSummonCreature.CreatureEntry) sLog->outError("%s creature entry (datalong) is not specified.", step.script->GetDebugInfo().c_str()); else { float x = step.script->TempSummonCreature.PosX; float y = step.script->TempSummonCreature.PosY; float z = step.script->TempSummonCreature.PosZ; float o = step.script->TempSummonCreature.Orientation; if (!pSummoner->SummonCreature(step.script->TempSummonCreature.CreatureEntry, x, y, z, o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, step.script->TempSummonCreature.DespawnDelay)) sLog->outError("%s creature was not spawned (entry: %u).", step.script->GetDebugInfo().c_str(), step.script->TempSummonCreature.CreatureEntry); } } break; } case SCRIPT_COMMAND_OPEN_DOOR: case SCRIPT_COMMAND_CLOSE_DOOR: _ScriptProcessDoor(source, target, step.script); break; case SCRIPT_COMMAND_ACTIVATE_OBJECT: // Source must be Unit. if (Unit* pSource = _GetScriptUnit(source, true, step.script)) { // Target must be GameObject. if (!target) { sLog->outError("%s target object is NULL.", step.script->GetDebugInfo().c_str()); break; } if (target->GetTypeId() != TYPEID_GAMEOBJECT) { sLog->outError("%s target object is not gameobject (TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); break; } if (GameObject* pGO = target->ToGameObject()) pGO->Use(pSource); } break; case SCRIPT_COMMAND_REMOVE_AURA: { // Source (datalong2 != 0) or target (datalong2 == 0) must be Unit. bool bReverse = step.script->RemoveAura.Flags & SF_REMOVEAURA_REVERSE; if (Unit* pTarget = _GetScriptUnit(bReverse ? source : target, bReverse, step.script)) pTarget->RemoveAurasDueToSpell(step.script->RemoveAura.SpellID); break; } case SCRIPT_COMMAND_CAST_SPELL: { // TODO: Allow gameobjects to be targets and casters if (!source && !target) { sLog->outError("%s source and target objects are NULL.", step.script->GetDebugInfo().c_str()); break; } Unit* uSource = NULL; Unit* uTarget = NULL; // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s switch (step.script->CastSpell.Flags) { case SF_CASTSPELL_SOURCE_TO_TARGET: // source -> target uSource = source ? source->ToUnit() : NULL; uTarget = target ? target->ToUnit() : NULL; break; case SF_CASTSPELL_SOURCE_TO_SOURCE: // source -> source uSource = source ? source->ToUnit() : NULL; uTarget = uSource; break; case SF_CASTSPELL_TARGET_TO_TARGET: // target -> target uSource = target ? target->ToUnit() : NULL; uTarget = uSource; break; case SF_CASTSPELL_TARGET_TO_SOURCE: // target -> source uSource = target ? target->ToUnit() : NULL; uTarget = source ? source->ToUnit() : NULL; break; case SF_CASTSPELL_SEARCH_CREATURE: // source -> creature with entry uSource = source ? source->ToUnit() : NULL; uTarget = uSource ? GetClosestCreatureWithEntry(uSource, abs(step.script->CastSpell.CreatureEntry), step.script->CastSpell.SearchRadius) : NULL; break; } if (!uSource || !uSource->isType(TYPEMASK_UNIT)) { sLog->outError("%s no source unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->CastSpell.SpellID); break; } if (!uTarget || !uTarget->isType(TYPEMASK_UNIT)) { sLog->outError("%s no target unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->CastSpell.SpellID); break; } bool triggered = (step.script->CastSpell.Flags != 4) ? step.script->CastSpell.CreatureEntry & SF_CASTSPELL_TRIGGERED : step.script->CastSpell.CreatureEntry < 0; uSource->CastSpell(uTarget, step.script->CastSpell.SpellID, triggered); break; } case SCRIPT_COMMAND_PLAY_SOUND: // Source must be WorldObject. if (WorldObject* pSource = _GetScriptWorldObject(source, true, step.script)) { // PlaySound.Flags bitmask: 0/1=anyone/target Player* pTarget = NULL; if (step.script->PlaySound.Flags & SF_PLAYSOUND_TARGET_PLAYER) { // Target must be Player. pTarget = _GetScriptPlayer(target, false, step.script); if (!pTarget) break; } // PlaySound.Flags bitmask: 0/2=without/with distance dependent if (step.script->PlaySound.Flags & SF_PLAYSOUND_DISTANCE_SOUND) pSource->PlayDistanceSound(step.script->PlaySound.SoundID, pTarget); else pSource->PlayDirectSound(step.script->PlaySound.SoundID, pTarget); } break; case SCRIPT_COMMAND_CREATE_ITEM: // Target or source must be Player. if (Player* pReceiver = _GetScriptPlayerSourceOrTarget(source, target, step.script)) { ItemPosCountVec dest; InventoryResult msg = pReceiver->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, step.script->CreateItem.ItemEntry, step.script->CreateItem.Amount); if (msg == EQUIP_ERR_OK) { if (Item* item = pReceiver->StoreNewItem(dest, step.script->CreateItem.ItemEntry, true)) pReceiver->SendNewItem(item, step.script->CreateItem.Amount, false, true); } else pReceiver->SendEquipError(msg, NULL, NULL, step.script->CreateItem.ItemEntry); } break; case SCRIPT_COMMAND_DESPAWN_SELF: // Target or source must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true)) cSource->DespawnOrUnsummon(step.script->DespawnSelf.DespawnDelay); break; case SCRIPT_COMMAND_LOAD_PATH: // Source must be Unit. if (Unit* pSource = _GetScriptUnit(source, true, step.script)) { if (!sWaypointMgr->GetPath(step.script->LoadPath.PathID)) sLog->outError("%s source object has an invalid path (%u), skipping.", step.script->GetDebugInfo().c_str(), step.script->LoadPath.PathID); else pSource->GetMotionMaster()->MovePath(step.script->LoadPath.PathID, step.script->LoadPath.IsRepeatable); } break; case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT: { if (!step.script->CallScript.CreatureEntry) { sLog->outError("%s creature entry is not specified, skipping.", step.script->GetDebugInfo().c_str()); break; } if (!step.script->CallScript.ScriptID) { sLog->outError("%s script id is not specified, skipping.", step.script->GetDebugInfo().c_str()); break; } Creature* cTarget = NULL; if (source) //using grid searcher { WorldObject* wSource = dynamic_cast <WorldObject*> (source); CellCoord p(Trinity::ComputeCellCoord(wSource->GetPositionX(), wSource->GetPositionY())); Cell cell(p); Trinity::CreatureWithDbGUIDCheck target_check(wSource, step.script->CallScript.CreatureEntry); Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(wSource, cTarget, target_check); TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker); cell.Visit(p, unit_checker, *wSource->GetMap(), *wSource, wSource->GetGridActivationRange()); } else //check hashmap holders { if (CreatureData const* data = sObjectMgr->GetCreatureData(step.script->CallScript.CreatureEntry)) cTarget = ObjectAccessor::GetObjectInWorld<Creature>(data->mapid, data->posX, data->posY, MAKE_NEW_GUID(step.script->CallScript.CreatureEntry, data->id, HIGHGUID_UNIT), cTarget); } if (!cTarget) { sLog->outError("%s target was not found (entry: %u)", step.script->GetDebugInfo().c_str(), step.script->CallScript.CreatureEntry); break; } //Lets choose our ScriptMap map ScriptMapMap* datamap = GetScriptsMapByType(ScriptsType(step.script->CallScript.ScriptType)); //if no scriptmap present... if (!datamap) { sLog->outError("%s unknown scriptmap (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->CallScript.ScriptType); break; } // Insert script into schedule but do not start it ScriptsStart(*datamap, step.script->CallScript.ScriptID, cTarget, NULL); break; } case SCRIPT_COMMAND_KILL: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { if (cSource->isDead()) sLog->outError("%s creature is already dead (Entry: %u, GUID: %u)", step.script->GetDebugInfo().c_str(), cSource->GetEntry(), cSource->GetGUIDLow()); else { cSource->setDeathState(JUST_DIED); if (step.script->Kill.RemoveCorpse == 1) cSource->RemoveCorpse(); } } break; case SCRIPT_COMMAND_ORIENTATION: // Source must be Unit. if (Unit* pSource = _GetScriptUnit(source, true, step.script)) { if (step.script->Orientation.Flags& SF_ORIENTATION_FACE_TARGET) { // Target must be Unit. Unit* pTarget = _GetScriptUnit(target, false, step.script); if (!pTarget) break; pSource->SetInFront(pTarget); } else pSource->SetOrientation(step.script->Orientation.Orientation); pSource->SendMovementFlagUpdate(); } break; case SCRIPT_COMMAND_EQUIP: // Source must be Creature. if (Creature* cSource = _GetScriptCreature(source, true, step.script)) cSource->LoadEquipment(step.script->Equip.EquipmentID); break; case SCRIPT_COMMAND_MODEL: // Source must be Creature. if (Creature* cSource = _GetScriptCreature(source, true, step.script)) cSource->SetDisplayId(step.script->Model.ModelID); break; case SCRIPT_COMMAND_CLOSE_GOSSIP: // Source must be Player. if (Player* pSource = _GetScriptPlayer(source, true, step.script)) pSource->PlayerTalkClass->SendCloseGossip(); break; case SCRIPT_COMMAND_PLAYMOVIE: // Source must be Player. if (Player* pSource = _GetScriptPlayer(source, true, step.script)) pSource->SendMovieStart(step.script->PlayMovie.MovieID); break; default: sLog->outError("Unknown script command %s.", step.script->GetDebugInfo().c_str()); break; } m_scriptSchedule.erase(iter); iter = m_scriptSchedule.begin(); sScriptMgr->DecreaseScheduledScriptCount(); } }
void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGuid, bool canComplete, bool closeOnCancel) const { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward uint32 itemCounter = quest->GetQuestObjectiveCountType(QUEST_OBJECTIVE_TYPE_ITEM); if (!itemCounter && canComplete) { SendQuestGiverOfferReward(quest, npcGuid, true); return; } std::string questTitle = quest->GetTitle(); std::string requestItemsText = quest->GetRequestItemsText(); int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) { if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle); ObjectMgr::GetLocaleString(localeData->RequestItemsText, locale, requestItemsText); } } uint32 requiredMoney = 0, itemCount = 0, currencyCount = 0; ByteBuffer currencyData, itemData; for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); citr++) { QuestObjective const* questObjective = *citr; switch (questObjective->Type) { case QUEST_OBJECTIVE_TYPE_ITEM: { itemData << int32(questObjective->ObjectId); itemData << int32(questObjective->Amount); itemCount++; break; } case QUEST_OBJECTIVE_TYPE_CURRENCY: { currencyData << int32(questObjective->ObjectId); currencyData << int32(questObjective->Amount); currencyCount++; break; } case QUEST_OBJECTIVE_TYPE_MONEY: { requiredMoney = questObjective->Amount; break; } default: break; } } if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); ObjectGuid guid = npcGuid; uint32 currencyCounter = quest->GetQuestObjectiveCountType(QUEST_OBJECTIVE_TYPE_CURRENCY); WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 16 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + itemCount * (4 + 4) + currencyCount * (4 + 4)); data << guid; data << int32(0); // QuestGiverCreatureID data << int32(quest->GetQuestId()); data << int32(0); // CompEmoteDelay data << int32(canComplete ? quest->GetCompleteEmote() : quest->GetIncompleteEmote()); data << int32(quest->GetFlags()); data << int32(quest->GetFlags2()); data << int32(quest->GetSuggestedPlayers()); data << int32(requiredMoney); data << uint32(itemCount); data << uint32(currencyCount); data << int32(canComplete ? 0xDF : 0xDB); // StatusFlags data.append(itemData); data.append(currencyData); data.WriteBit(closeOnCancel); data.FlushBits(); data.WriteBits(questTitle.size(), 9); data.WriteBits(requestItemsText.size(), 12); data.FlushBits(); data.WriteString(questTitle); data.WriteString(requestItemsText); _session->SendPacket(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGuid), quest->GetQuestId()); }