bool QuestLogEntry::LoadFromDB(Field *fields) { // playerguid,questid,timeleft,area0,area1,area2,area3,kill0,kill1,kill2,kill3 int f = 3; ASSERT(m_plr && m_quest); m_time_left = fields[f].GetUInt32(); f++; for(int i = 0; i < 4; ++i) { m_explored_areas[i] = fields[f].GetUInt32(); f++; CALL_QUESTSCRIPT_EVENT(this, OnExploreArea)(m_explored_areas[i], m_plr, this); } for(int i = 0; i < 4; ++i) { m_mobcount[i] = fields[f].GetUInt32(); f++; if(GetQuest()->required_mobtype[i] == QUEST_MOB_TYPE_CREATURE) CALL_QUESTSCRIPT_EVENT(this, OnCreatureKill)(GetQuest()->required_mob[i], m_plr, this); else CALL_QUESTSCRIPT_EVENT(this, OnGameObjectActivate)(GetQuest()->required_mob[i], m_plr, this); } mDirty = false; return true; }
bool QuestLogEntry::LoadFromDB(Field* fields) { // playerguid,questid,timeleft,area0,area1,area2,area3,kill0,kill1,kill2,kill3 int f = 3; ARCEMU_ASSERT(m_plr && m_quest); expirytime = fields[f].GetUInt32(); f++; /*for (int i = 0; i < 4; ++i) { m_explored_areas[i] = fields[f].GetUInt32(); f++; CALL_QUESTSCRIPT_EVENT(this, OnExploreArea)(m_explored_areas[i], m_plr, this); }*/ for (int i = 0; i < 4; ++i) { m_mobcount[i] = fields[f].GetUInt32(); f++; if (GetQuest()->m_reqMobType[i] == QUEST_MOB_TYPE_CREATURE) { CALL_QUESTSCRIPT_EVENT(this, OnCreatureKill)(GetQuest()->ReqCreatureOrGOId[i], m_plr, this); } else { CALL_QUESTSCRIPT_EVENT(this, OnGameObjectActivate)(GetQuest()->ReqCreatureOrGOId[i], m_plr, this); } } completed = fields[f].GetUInt32(); mDirty = false; return true; }
void QuestMgr::OnPlayerExploreArea(Player* plr, uint32 AreaID) { uint32 i, j; QuestLogEntry *qle; for(i = 0; i < 25; ++i) { if((qle = plr->GetQuestLogInSlot(i))) { // dont waste time on quests without mobs if(qle->GetQuest()->count_requiredtriggers == 0) continue; for(j = 0; j < 4; ++j) { if(qle->GetQuest()->required_triggers[j] == AreaID && !qle->m_explored_areas[j]) { qle->SetTrigger(j); CALL_QUESTSCRIPT_EVENT(qle, OnExploreArea)(qle->m_explored_areas[j], plr); qle->UpdatePlayerFields(); if(qle->CanBeFinished()) { plr->UpdateNearbyGameObjects(); qle->SendQuestComplete(); } break; } } } } }
void WorldSession::HandleQuestlogRemoveQuestOpcode(WorldPacket& recvPacket) { sLog.outDebug( "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST" ); if(!_player) return; if(!_player->IsInWorld()) return; uint8 quest_slot; recvPacket >> quest_slot; if(quest_slot >= 25) return; QuestLogEntry *qEntry = GetPlayer()->GetQuestLogInSlot(quest_slot); if (!qEntry) { sLog.outDebug("WORLD: No quest in slot %d.", quest_slot); return; } Quest *qPtr = qEntry->GetQuest(); CALL_QUESTSCRIPT_EVENT(qEntry, OnQuestCancel)(GetPlayer()); qEntry->Finish(); // Remove all items given by the questgiver at the beginning for(uint32 i = 0; i < 4; ++i) { if(qPtr->receive_items[i]) GetPlayer()->GetItemInterface()->RemoveItemAmt( qPtr->receive_items[i], 1 ); } if(qPtr->time > 0) { GetPlayer()->timed_quest_slot = 0; } GetPlayer()->UpdateNearbyGameObjects(); sHookInterface.OnQuestCancelled(_player, qPtr); }
void QuestMgr::OnPlayerItemPickup(Player* plr, Item* item) { uint32 i, j; uint32 pcount; uint32 entry = item->GetEntry(); QuestLogEntry *qle; for(i = 0; i < 25; ++i) { if((qle = plr->GetQuestLogInSlot(i))) { for(j = 0; j < qle->GetQuest()->count_required_item; ++j) { if(qle->GetQuest()->required_item[j] == entry) { pcount = plr->GetItemInterface()->GetItemCount(entry, true); CALL_QUESTSCRIPT_EVENT(qle, OnPlayerItemPickup)(entry, pcount, plr); if(pcount < qle->GetQuest()->required_itemcount[j]) { WorldPacket data(8); data.SetOpcode(SMSG_QUESTUPDATE_ADD_ITEM); data << qle->GetQuest()->required_item[j] << uint32(1); plr->GetSession()->SendPacket(&data); if(qle->CanBeFinished()) { plr->UpdateNearbyGameObjects(); qle->SendQuestComplete(); } break; } } } } } }
void WorldSession::HandleQuestlogRemoveQuestOpcode(WorldPacket& recvPacket) { CHECK_INWORLD_RETURN; DEBUG_LOG( "QuestHandler","Received CMSG_QUESTLOG_REMOVE_QUEST" ); uint8 quest_slot; recvPacket >> quest_slot; if(quest_slot >= 25) return; QuestLogEntry *qEntry = _player->GetQuestLogInSlot(quest_slot); if (!qEntry) { DEBUG_LOG("QuestHandler","No quest in slot %d.", quest_slot); return; } Quest *qPtr = qEntry->GetQuest(); if (!qPtr) { DEBUG_LOG("QuestHandler","Quest %u does not exist in database", qPtr->id); return; } CALL_QUESTSCRIPT_EVENT(qPtr->id, OnQuestCancel)(_player); qEntry->Finish(); // Remove all items given by the questgiver at the beginning for(uint32 i = 0; i < 4; i++) { if(qPtr->receive_items[i]) _player->GetItemInterface()->RemoveItemAmt( qPtr->receive_items[i], 1 ); } // Remove source item if(qPtr->srcitem) _player->GetItemInterface()->RemoveItemAmt( qPtr->srcitem, 1 ); // Reset timed quests, remove timed event if(qPtr->time > 0) { if (sEventMgr.HasEvent(_player,EVENT_TIMED_QUEST_EXPIRE)) sEventMgr.RemoveEvents(_player, EVENT_TIMED_QUEST_EXPIRE); } if(qPtr->start_phase != 0) { if(_player->GetPhaseMask() == (int32)qPtr->start_phase) _player->SetPhaseMask(_player->LastPhase, true); } _player->UpdateNearbyGameObjects(); sHookInterface.OnQuestCancelled(_player, qPtr); _player->SaveToDB(false); }
void QuestLogEntry::SendQuestComplete() { WorldPacket data(4); data.SetOpcode(SMSG_QUESTUPDATE_COMPLETE); data << m_quest->id; m_plr->GetSession()->SendPacket(&data); CALL_QUESTSCRIPT_EVENT(this, OnQuestComplete)(m_plr, this); }
string RemoveQuestFromPlayer(Player* plr, Quest *qst) { std::string recout = "|cff00ff00"; bool has = false; if ( plr->HasFinishedQuest(qst->id) ) { if( plr->m_finishedQuests.find(qst->id) != plr->m_finishedQuests.end()) { plr->m_finishedQuests.erase(qst->id); recout += "Quest removed from finished quests history.\n\n"; has = true; } } if ( plr->HasFinishedDailyQuest(qst->id) ) { if( plr->m_finishedDailyQuests.find(qst->id) != plr->m_finishedDailyQuests.end()) { plr->m_finishedDailyQuests.erase(qst->id); recout += "Quest removed from finished dailies history.\n\n"; has = true; } } if (plr->HasQuests()) { QuestLogEntry * qLogEntry = plr->GetQuestLogForEntry(qst->id); if (qLogEntry) { CALL_QUESTSCRIPT_EVENT(qLogEntry, OnQuestCancel)(plr); qLogEntry->Finish(); // Remove all items given by the questgiver at the beginning for(uint32 i = 0; i < 4; ++i) { if(qst->receive_items[i]) plr->GetItemInterface()->RemoveItemAmt(qst->receive_items[i], 1 ); } plr->UpdateNearbyGameObjects(); } recout += "Quest removed from current questlog."; has = true; } if(!has) recout += "Quest not found on player."; recout += "\n\n"; return recout; }
void WorldSession::HandleQuestlogRemoveQuestOpcode(WorldPacket & recvPacket) { CHECK_INWORLD_RETURN LOG_DEBUG("WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST"); uint8 quest_slot; recvPacket >> quest_slot; if(quest_slot >= 25) return; QuestLogEntry* qEntry = GetPlayer()->GetQuestLogInSlot(quest_slot); if(!qEntry) { LOG_DEBUG("WORLD: No quest in slot %d.", quest_slot); return; } Quest* qPtr = qEntry->GetQuest(); CALL_QUESTSCRIPT_EVENT(qEntry, OnQuestCancel)(GetPlayer()); qEntry->Finish(); // Remove all items given by the questgiver at the beginning for(uint32 i = 0; i < 4; ++i) { if(qPtr->receive_items[i]) GetPlayer()->GetItemInterface()->RemoveItemAmt(qPtr->receive_items[i], 1); } if( qPtr->srcitem && qPtr->srcitem != qPtr->receive_items[0] ) { ItemPrototype *itemProto = ::ItemPrototypeStorage.LookupEntry( qPtr->srcitem ); if( itemProto != NULL ) if( itemProto->QuestId != qPtr->id ) _player->GetItemInterface()->RemoveItemAmt(qPtr->srcitem, qPtr->srcitemcount ? qPtr->srcitemcount : 1); } //remove all quest items (but not trade goods) collected and required only by this quest for(uint32 i = 0; i < MAX_REQUIRED_QUEST_ITEM; ++i) { if(qPtr->required_item[i] != 0) { ItemPrototype* itemProto = ItemPrototypeStorage.LookupEntry(qPtr->required_item[i]); if(itemProto != NULL && itemProto->Class == ITEM_CLASS_QUEST) GetPlayer()->GetItemInterface()->RemoveItemAmt(qPtr->required_item[i], qPtr->required_itemcount[i]); } } GetPlayer()->UpdateNearbyGameObjects(); sHookInterface.OnQuestCancelled(_player, qPtr); }
void QuestLogEntry::Init(Quest* quest, Player* plr, uint32 slot) { ARCEMU_ASSERT(quest != NULL); ARCEMU_ASSERT(plr != NULL); m_quest = quest; m_plr = plr; m_slot = slot; iscastquest = false; isemotequest = false; for(uint32 i = 0; i < 4; ++i) { if(quest->required_spell[i] != 0) { iscastquest = true; if(!plr->HasQuestSpell(quest->required_spell[i])) plr->quest_spells.insert(quest->required_spell[i]); } else if(quest->required_emote[i] != 0) { isemotequest = true; } if(quest->required_mob[i] != 0) { if(!plr->HasQuestMob(quest->required_mob[i])) plr->quest_mobs.insert(quest->required_mob[i]); } } // update slot plr->SetQuestLogSlot(this, slot); mDirty = true; memset(m_mobcount, 0, 4 * 4); memset(m_explored_areas, 0, 4 * 4); if( m_quest->time > 0 ) expirytime = UNIXTIME + m_quest->time / 1000; else expirytime = 0; if(!plr->GetSession()->m_loggingInPlayer) //quest script should not be called on login CALL_QUESTSCRIPT_EVENT(this, OnQuestStart)(plr, this); }
void QuestLogEntry::Init(Quest* quest, Player* plr, uint32 slot) { ASSERT(quest); ASSERT(plr); m_quest = quest; m_plr = plr; m_slot = slot; iscastquest = false; for (uint32 i=0;i<4;++i) { if (quest->required_spell[i]!=0) { iscastquest=true; if (!plr->HasQuestSpell(quest->required_spell[i])) plr->quest_spells.insert(quest->required_spell[i]); } else if (quest->required_mob[i]!=0) { if (!plr->HasQuestMob(quest->required_mob[i])) plr->quest_mobs.insert(quest->required_mob[i]); } } // update slot plr->SetQuestLogSlot(this, slot); mDirty = true; memset(m_mobcount, 0, 4*4); memset(m_explored_areas, 0, 4*4); if(m_quest->time) m_time_left = m_quest->time * 1000; else m_time_left = 0; CALL_QUESTSCRIPT_EVENT(this, OnQuestStart)(plr, this); }
string RemoveQuestFromPlayer(Player *plr, Quest *qst) { std::string recout = "|cff00ff00"; if (plr->HasQuests()) { if (plr->HasFinishedQuest(qst->id)) recout += "Player has already completed that quest.\n\n"; else { QuestLogEntry * qLogEntry = plr->GetQuestLogForEntry(qst->id); if (qLogEntry) { CALL_QUESTSCRIPT_EVENT(qLogEntry, OnQuestCancel)(plr); qLogEntry->Finish(); // Remove all items given by the questgiver at the beginning for(uint32 i = 0; i < 4; ++i) { if(qst->receive_items[i]) plr->GetItemInterface()->RemoveItemAmt(qst->receive_items[i], 1 ); } if(qst->time > 0) plr->timed_quest_slot = 0; plr->UpdateNearbyGameObjects(); } else recout += "No quest log entry found for that player."; } } else { recout += "Player has no quests to remove."; } recout += "\n\n"; return recout; }
bool QuestMgr::OnGameObjectActivate(Player *plr, GameObject *go) { uint32 i, j; QuestLogEntry *qle; uint32 entry = go->GetEntry(); for(i = 0; i < 25; ++i) { if((qle = plr->GetQuestLogInSlot(i))) { // dont waste time on quests without mobs if(qle->GetQuest()->count_required_mob == 0) continue; for(j = 0; j < 4; ++j) { if(qle->GetQuest()->required_mob[j] == entry && qle->GetQuest()->required_mobtype[j] == QUEST_MOB_TYPE_GAMEOBJECT && qle->m_mobcount[j] < qle->GetQuest()->required_mobcount[j]) { // add another kill. // (auto-dirtys it) qle->SetMobCount(j, qle->m_mobcount[j] + 1); qle->SendUpdateAddKill(j); CALL_QUESTSCRIPT_EVENT(qle, OnGameObjectActivate)(entry, plr); if(qle->CanBeFinished()) qle->SendQuestComplete(); qle->UpdatePlayerFields(); return true; } } } } return false; }
void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data ) { DEBUG_LOG( "WORLD"," Received CMSG_QUESTGIVER_ACCEPT_QUEST" ); CHECK_INWORLD_RETURN; //WorldPacket data; uint64 guid; uint32 quest_id; uint32 unk; recv_data >> guid; recv_data >> quest_id; recv_data >> unk; bool bValid = false; bool hasquest = true; bool bSkipLevelCheck = false; Quest *qst = NULL; Object* qst_giver = NULLOBJ; uint32 guidtype = GET_TYPE_FROM_GUID(guid); if(guidtype == HIGHGUID_TYPE_CREATURE) { Creature* quest_giver = _player->GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid)); if(quest_giver) qst_giver = TO_OBJECT(quest_giver); else return; bValid = quest_giver->isQuestGiver(); hasquest = quest_giver->HasQuest(quest_id, 1); if(bValid) qst = QuestStorage.LookupEntry(quest_id); } else if(guidtype==HIGHGUID_TYPE_GAMEOBJECT) { GameObject* quest_giver = _player->GetMapMgr()->GetGameObject(GET_LOWGUID_PART(guid)); if(quest_giver) qst_giver = TO_OBJECT(quest_giver); else return; //bValid = quest_giver->isQuestGiver(); //if(bValid) bValid = true; qst = QuestStorage.LookupEntry(quest_id); } else if(guidtype==HIGHGUID_TYPE_ITEM) { Item* quest_giver = GetPlayer()->GetItemInterface()->GetItemByGUID(guid); if(quest_giver) qst_giver = TO_OBJECT(quest_giver); else return; bValid = true; bSkipLevelCheck=true; qst = QuestStorage.LookupEntry(quest_id); if( qst && qst->id != quest_giver->GetProto()->QuestId ) return; } else if(guidtype==HIGHGUID_TYPE_PLAYER) { Player* quest_giver = _player->GetMapMgr()->GetPlayer((uint32)guid); if(quest_giver) qst_giver = TO_OBJECT(quest_giver); else return; bValid = true; qst = QuestStorage.LookupEntry(quest_id); } if (!qst_giver) { OUT_DEBUG("WORLD: Invalid questgiver GUID."); return; } if( !bValid || qst == NULL ) { OUT_DEBUG("WORLD: Creature is not a questgiver."); return; } if( _player->GetQuestLogForEntry( qst->id ) ) return; if( qst_giver->GetTypeId() == TYPEID_UNIT && TO_CREATURE( qst_giver )->m_escorter != NULL ) { SystemMessage("You cannot accept this quest at this time."); return; } // Check the player hasn't already taken this quest, or // it isn't available. uint32 status = sQuestMgr.CalcQuestStatus(_player,qst,3, bSkipLevelCheck); if((!sQuestMgr.IsQuestRepeatable(qst) && _player->HasFinishedQuest(qst->id)) || ( status != QMGR_QUEST_AVAILABLE && status != QMGR_QUEST_REPEATABLE && status != QMGR_QUEST_CHAT ) || !hasquest) { // We've got a hacker. Disconnect them. //sWorld.LogCheater(this, "tried to accept incompatible quest %u from %u.", qst->id, qst_giver->GetEntry()); //Disconnect(); return; } int32 log_slot = _player->GetOpenQuestSlot(); if (log_slot == -1) { sQuestMgr.SendQuestLogFull(GetPlayer()); return; } //FIXME /*if(Player Has Timed quest && qst->HasFlag(QUEST_FLAG_TIMED)) sQuestMgr.SendQuestInvalid(INVALID_REASON_HAVE_TIMED_QUEST);*/ if(qst->count_receiveitems || qst->srcitem) { uint32 slots_required = qst->count_receiveitems; if(_player->GetItemInterface()->CalculateFreeSlots(NULL) < slots_required) { _player->GetItemInterface()->BuildInventoryChangeError(NULLITEM, NULLITEM, INV_ERR_BAG_FULL); sQuestMgr.SendQuestFailed(FAILED_REASON_INV_FULL, qst, _player); return; } } /* if(qst_giver->GetTypeId() == TYPEID_UNIT && !ScriptSystem->OnQuestRequireEvent(qst, TO_CREATURE( qst_giver ), _player, QUEST_EVENT_CAN_ACCEPT)) return;*/ QuestLogEntry *qle = new QuestLogEntry(); qle->Init(qst, _player, log_slot); qle->UpdatePlayerFields(); // If the quest should give any items on begin, give them the items. for(uint32 i = 0; i < 4; i++) { if(qst->receive_items[i]) { Item* item = objmgr.CreateItem( qst->receive_items[i], GetPlayer()); if(item) { if(!_player->GetItemInterface()->AddItemToFreeSlot(item)) { item->DeleteMe(); item = NULLITEM; } else SendItemPushResult(item, false, true, false, true, _player->GetItemInterface()->LastSearchItemBagSlot(), _player->GetItemInterface()->LastSearchItemSlot(), 1); } } } if(qst->srcitem && qst->srcitem != qst->receive_items[0]) { Item* item = objmgr.CreateItem( qst->srcitem, _player ); if(item) { item->SetUInt32Value(ITEM_FIELD_STACK_COUNT, qst->srcitemcount ? qst->srcitemcount : 1); if(!_player->GetItemInterface()->AddItemToFreeSlot(item)) { item->DeleteMe(); item = NULLITEM; } } } if(qst->count_required_item || qst_giver->GetTypeId() == TYPEID_GAMEOBJECT) // gameobject quests deactivate _player->UpdateNearbyGameObjects(); CALL_QUESTSCRIPT_EVENT(qst->id, OnQuestStart)(_player, qle); sQuestMgr.OnQuestAccepted(_player,qst,qst_giver); if(qst->start_phase != 0 ) _player->SetPhaseMask(qst->start_phase, true); sHookInterface.OnQuestAccept(_player, qst, qst_giver); }
bool ChatHandler::HandleQuestStartCommand(const char * args, WorldSession * m_session) { if(!*args) return false; Player* plr = getSelectedChar(m_session, true); if(!plr) { plr = m_session->GetPlayer(); SystemMessage(m_session, "Auto-targeting self."); } uint32 quest_id = atol(args); std::string recout = "|cff00ff00"; Quest * qst = QuestStorage.LookupEntry(quest_id); if(qst) { if (plr->HasFinishedQuest(quest_id) || plr->HasFinishedDailyQuest(quest_id)) recout += "Player has already completed that quest."; else { QuestLogEntry * IsPlrOnQuest = plr->GetQuestLogForEntry(quest_id); if (IsPlrOnQuest) recout += "Player is currently on that quest."; else { int32 open_slot = plr->GetOpenQuestSlot(); if (open_slot == -1) { sQuestMgr.SendQuestLogFull(plr); recout += "Player's quest log is full."; } else { QuestLogEntry *qle = new QuestLogEntry(); qle->Init(qst, plr, (uint32)open_slot); qle->UpdatePlayerFields(); CALL_QUESTSCRIPT_EVENT(qle, OnQuestStart)(plr, qle); // If the quest should give any items on begin, give them the items. for(uint32 i = 0; i < 4; ++i) { if(qst->receive_items[i]) { Item* item = objmgr.CreateItem( qst->receive_items[i], plr); if(!plr->GetItemInterface()->AddItemToFreeSlot(item)) { if(item) item->Destructor(); } } } if(qst->srcitem && qst->srcitem != qst->receive_items[0]) { Item* item = objmgr.CreateItem( qst->srcitem, plr); if(item) { item->SetUInt32Value(ITEM_FIELD_STACK_COUNT, qst->srcitemcount ? qst->srcitemcount : 1); if(!plr->GetItemInterface()->AddItemToFreeSlot(item)) { if(item) item->Destructor(); } } } plr->UpdateNearbyGameObjects(); sHookInterface.OnQuestAccept( plr, qst, NULL ); recout += "Quest has been added to the player's quest log."; } } } } else { recout += "Quest Id ["; recout += args; recout += "] was not found and unable to add it to the player's quest log."; } recout += "\n\n"; SendMultilineMessage(m_session, recout.c_str()); return true; }
void QuestMgr::OnQuestFinished(Player* plr, Quest* qst, Object *qst_giver, uint32 reward_slot) { QuestLogEntry *qle = plr->GetQuestLogForEntry(qst->id); if(!qle) return; BuildQuestComplete(plr, qst); CALL_QUESTSCRIPT_EVENT(qle, OnQuestComplete)(plr); ScriptSystem->OnQuestEvent(qst, ((Creature*)qst_giver), plr, QUEST_EVENT_ON_COMPLETE); qle->Finish(); if(IsQuestRepeatable(qst)) return; if(qst_giver->GetTypeId() == TYPEID_UNIT) { if(!((Creature*)qst_giver)->HasQuest(qst->id, 2)) { sCheatLog.writefromsession(plr->GetSession(), "tried to finish quest from invalid npc."); plr->GetSession()->Disconnect(); return; } } plr->ModUInt32Value(PLAYER_FIELD_COINAGE, qst->reward_money); // Reputation reward for(int z = 0; z < 2; z++) { uint32 fact = 19; // default to 19 if no factiondbc uint32 amt = uint32(float(GenerateQuestXP(plr, qst)) * 0.1f * sWorld.getRate(RATE_QUESTREPUTATION)); // guess if(!qst->reward_repfaction[z]) { if(z == 1) break; // Let's do this properly. Determine the faction of the creature, and give reputation to his faction. if(qst_giver->GetTypeId() == TYPEID_UNIT) if(((Creature*)qst_giver)->m_factionDBC != NULL) fact = ((Creature*)qst_giver)->m_factionDBC->ID; if(qst_giver->GetTypeId() == TYPEID_GAMEOBJECT) fact = qst_giver->GetUInt32Value(GAMEOBJECT_FACTION); } else { fact = qst->reward_repfaction[z]; if(qst->reward_repvalue[z]) amt = qst->reward_repvalue[z]; } if(qst->reward_replimit) if(plr->GetStanding(fact) >= (int32)qst->reward_replimit) continue; plr->ModStanding(fact, amt); } // Static Item reward for(uint32 i = 0; i < 4; ++i) { if(qst->reward_item[i]) { ItemPrototype *proto = ItemPrototypeStorage.LookupEntry(qst->reward_item[i]); if(!proto) { sLog.outError("Invalid item prototype in quest reward! ID %d, quest %d", qst->reward_item[i], qst->id); } else { Item *itm = objmgr.CreateItem(qst->reward_item[i], plr); itm->SetUInt32Value(ITEM_FIELD_STACK_COUNT, uint32(qst->reward_itemcount[i])); plr->GetItemInterface()->AddItemToFreeSlot(itm); //possible memleak and no safe check. } } } // Choice Rewards if(qst->reward_choiceitem[reward_slot]) { ItemPrototype *proto = ItemPrototypeStorage.LookupEntry(qst->reward_choiceitem[reward_slot]); if(!proto) { sLog.outError("Invalid item prototype in quest reward! ID %d, quest %d", qst->reward_choiceitem[reward_slot], qst->id); } else { Item *itm = objmgr.CreateItem(qst->reward_choiceitem[reward_slot], plr); itm->SetUInt32Value(ITEM_FIELD_STACK_COUNT, qst->reward_choiceitemcount[reward_slot]); plr->GetItemInterface()->AddItemToFreeSlot(itm); //possible mem leak and no item check } } // Remove items for(uint32 i = 0; i < 4; ++i) { if(qst->required_item[i]) plr->GetItemInterface()->RemoveItemAmt(qst->required_item[i],qst->required_itemcount[i]); } // Remove srcitem if(qst->srcitem && qst->srcitem != qst->receive_items[0]) plr->GetItemInterface()->RemoveItemAmt(qst->srcitem, qst->srcitemcount ? qst->srcitemcount : 1); // cast learning spell if(qst->reward_spell) { if(!plr->HasSpell(qst->reward_spell)) { // "Teaching" effect WorldPacket data(SMSG_SPELL_START, 200); data << qst_giver->GetNewGUID() << qst_giver->GetNewGUID(); data << uint32(7763); data << uint16(0); data << uint32(0); data << uint16(2); data << plr->GetGUID(); plr->GetSession()->SendPacket( &data ); data.Initialize( SMSG_SPELL_GO ); data << qst_giver->GetNewGUID() << qst_giver->GetNewGUID(); data << uint32(7763); // spellID data << uint8(0) << uint8(1); // flags data << uint8(1); // amount of targets data << plr->GetGUID(); // target data << uint8(0); data << uint16(2); data << plr->GetGUID(); plr->GetSession()->SendPacket( &data ); // Teach the spell plr->addSpell(qst->reward_spell); } } // cast Effect Spell if(qst->effect_on_player) { SpellEntry * inf =sSpellStore.LookupEntry(qst->effect_on_player); if(inf) { Spell * spe = new Spell(qst_giver,inf,true,NULL); SpellCastTargets tgt; tgt.m_unitTarget = plr->GetGUID(); spe->prepare(&tgt); } } //Add to finished quests plr->AddToFinishedQuests(qst->id); }
void QuestMgr::OnPlayerKill(Player* plr, Creature* victim) { if(!plr) return; uint32 i, j; uint32 entry = victim->GetEntry(); QuestLogEntry *qle; for(i = 0; i < 25; ++i) { if((qle = plr->GetQuestLogInSlot(i))) { // dont waste time on quests without mobs if(qle->GetQuest()->count_required_mob == 0) continue; for(j = 0; j < 4; ++j) { if(qle->GetQuest()->required_mob[j] == entry && qle->GetQuest()->required_mobtype[j] == QUEST_MOB_TYPE_CREATURE && qle->m_mobcount[j] < qle->GetQuest()->required_mobcount[j]) { // add another kill. // (auto-dirtys it) qle->SetMobCount(j, qle->m_mobcount[j] + 1); qle->SendUpdateAddKill(j); CALL_QUESTSCRIPT_EVENT(qle, OnCreatureKill)(entry, plr); qle->UpdatePlayerFields(); break; } } } } // Shared kills Player *gplr = NULL; if(plr->InGroup()) { if(Group* pGroup = plr->GetGroup()) { if(pGroup->GetGroupType() != GROUP_TYPE_PARTY) return; // Raid's don't get shared kills. GroupMembersSet::iterator gitr; for(uint32 k = 0; k < pGroup->GetSubGroupCount(); k++) { for(gitr = pGroup->GetSubGroup(k)->GetGroupMembersBegin(); gitr != pGroup->GetSubGroup(k)->GetGroupMembersEnd(); ++gitr) { gplr = (*gitr); if(gplr && gplr != plr) // dont double kills { for(i = 0; i < 20; ++i) { if((qle = gplr->GetQuestLogInSlot(i))) { // dont waste time on quests without mobs if(qle->GetQuest()->count_required_mob == 0) continue; for(j = 0; j < 4; ++j) { if(qle->GetQuest()->required_mob[j] == entry && qle->GetQuest()->required_mobtype[j] == QUEST_MOB_TYPE_CREATURE && qle->m_mobcount[j] < qle->GetQuest()->required_mobcount[j]) { // add another kill. // (auto-dirtys it) qle->SetMobCount(j, qle->m_mobcount[j] + 1); qle->SendUpdateAddKill(j); CALL_QUESTSCRIPT_EVENT(qle, OnCreatureKill)(entry, plr); qle->UpdatePlayerFields(); // lua stuff //QUESTLUA_SendEvent(qst, victim, plr, ON_QUEST_KILLMOB, qle->m_mobcount[j]); if(qle->CanBeFinished()) qle->SendQuestComplete(); break; } } } } } } } } } }