void WorldSession::HandleQuestlogRemoveQuestOpcode(WorldPacket& recvPacket) { sLog.outDebug( "WORLD: Recieved CMSG_QUESTLOG_REMOVE_QUEST" ); 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(); 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(); }
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); }
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); }
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 ChatHandler::HandleQuestFinishCommand(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)) recout += "Player has already completed that quest.\n\n"; else { QuestLogEntry * IsPlrOnQuest = plr->GetQuestLogForEntry(quest_id); if (IsPlrOnQuest) { uint32 giver_id = 0; std::string my_query = ""; my_query = "SELECT id FROM creature_quest_starter WHERE quest = " + string(args); QueryResult *creatureResult = WorldDatabase.Query(my_query.c_str()); if(creatureResult) { Field *creatureFields = creatureResult->Fetch(); giver_id = creatureFields[0].GetUInt32(); delete creatureResult; } else { my_query = "SELECT id FROM gameobject_quest_starter WHERE quest = " + string(args); QueryResult *objectResult = WorldDatabase.Query(my_query.c_str()); if(objectResult) { Field *objectFields = objectResult->Fetch(); giver_id = objectFields[0].GetUInt32(); delete objectResult; } } if(giver_id == 0) SystemMessage(m_session, "Unable to find quest giver creature or object."); else { // I need some way to get the guid without targeting the creature or looking through all the spawns... Object *quest_giver; for(uint32 guid=1; guid < plr->GetMapMgr()->m_CreatureArraySize; guid++) { Creature *pCreature = plr->GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid)); if(pCreature) { if(pCreature->GetEntry() == giver_id) //found creature { quest_giver = (Object*)pCreature; guid = plr->GetMapMgr()->m_CreatureArraySize; } } } if(quest_giver) { GreenSystemMessage(m_session, "Found a quest_giver creature."); //WorldPacket data; //sQuestMgr.BuildOfferReward(&data, qst, quest_giver, 1); //m_session->SendPacket(&data); sQuestMgr.GiveQuestRewardReputation(plr, qst, quest_giver); } else RedSystemMessage(m_session, "Unable to find quest_giver object."); } sQuestMgr.GenerateQuestXP(plr, qst); sQuestMgr.BuildQuestComplete(plr, qst); IsPlrOnQuest->Finish(); recout += "Player was on that quest, but has now completed it."; } else recout += "The quest has now been completed for that player."; plr->AddToFinishedQuests(quest_id); } } 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; }
bool ChatHandler::HandleQuestFinishCommand(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); // reward_slot is for when quest has choice of rewards (0 is the first choice, 1 is the second choice, ...) // reward_slot will default to 0 if none is specified uint32 reward_slot; if(quest_id== 0) { quest_id = GetQuestIDFromLink(args); if(quest_id== 0) return false; if(strstr(args,"|r")) { reward_slot = atol(strstr(args,"|r")+2); } else { reward_slot = 0; } } else if(strchr(args,' ')) { reward_slot = atol(strchr(args,' ')+1); } else { reward_slot = 0; } // currently Quest::reward_choiceitem declaration is // uint32 reward_choiceitem[6]; // so reward_slot must be 0 to 5 if(reward_slot > 5) { reward_slot = 0; } std::string recout = "|cff00ff00"; Quest * qst = QuestStorage.LookupEntry(quest_id); if(qst) { if (plr->HasFinishedQuest(quest_id)) recout += "Player has already completed that quest.\n\n"; else { QuestLogEntry * IsPlrOnQuest = plr->GetQuestLogForEntry(quest_id); if (IsPlrOnQuest) { uint32 giver_id = 0; std::string my_query = ""; my_query = "SELECT id FROM creature_quest_starter WHERE quest = " + MyConvertIntToString(quest_id); QueryResult *creatureResult = WorldDatabase.Query(my_query.c_str()); if(creatureResult) { Field *creatureFields = creatureResult->Fetch(); giver_id = creatureFields[0].GetUInt32(); delete creatureResult; } else { my_query = "SELECT id FROM gameobject_quest_starter WHERE quest = " + MyConvertIntToString(quest_id); QueryResult *objectResult = WorldDatabase.Query(my_query.c_str()); if(objectResult) { Field *objectFields = objectResult->Fetch(); giver_id = objectFields[0].GetUInt32(); delete objectResult; } } if(giver_id == 0) SystemMessage(m_session, "Unable to find quest giver creature or object."); else { // I need some way to get the guid without targeting the creature or looking through all the spawns... Object *quest_giver = 0; for(uint32 guid=1; guid < plr->GetMapMgr()->CreatureStorage.size(); guid++) { Creature *pCreature = plr->GetMapMgr()->GetCreature(GET_LOWGUID_PART(guid)); if(pCreature) { if(pCreature->GetEntry() == giver_id) //found creature { quest_giver = (Object*)pCreature; guid = plr->GetMapMgr()->CreatureStorage.size(); } } } if(quest_giver) { GreenSystemMessage(m_session, "Found a quest_giver creature."); sQuestMgr.OnActivateQuestGiver(quest_giver, plr); sQuestMgr.GiveQuestRewardReputation(plr, qst, quest_giver); } else RedSystemMessage(m_session, "Unable to find quest_giver object."); } IsPlrOnQuest->Finish(); recout += "Player was on that quest, but has now completed it."; } else { recout += "The quest has now been completed for that player."; } sGMLog.writefromsession( m_session, "completed quest %u [%s] for player %s", quest_id, qst->title, plr->GetName() ); sQuestMgr.BuildQuestComplete(plr, qst); plr->AddToFinishedQuests(quest_id); // Quest Rewards : Copied from QuestMgr::OnQuestFinished() // Reputation reward for(int z = 0; z < 6; z++) { if( qst->reward_repfaction[z] ) { int32 amt = 0; uint32 fact = qst->reward_repfaction[z]; if( qst->reward_repvalue[z] ) { amt = qst->reward_repvalue[z]; } if( qst->reward_replimit && (plr->GetStanding(fact) >= (int32)qst->reward_replimit) ) { continue; } amt = float2int32( float( amt ) * sWorld.getRate( RATE_QUESTREPUTATION ) ); 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 *add; SlotResult slotresult; add = plr->GetItemInterface()->FindItemLessMax(qst->reward_item[i], qst->reward_itemcount[i], false); if (!add) { slotresult = plr->GetItemInterface()->FindFreeInventorySlot(proto); if(!slotresult.Result) { plr->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, INV_ERR_INVENTORY_FULL); } else { Item *itm = objmgr.CreateItem(qst->reward_item[i], plr); if( itm ) { itm->SetStackCount( uint32(qst->reward_itemcount[i])); if( !plr->GetItemInterface()->SafeAddItem(itm,slotresult.ContainerSlot, slotresult.Slot) ) { itm->DeleteMe(); } } } } else { add->SetStackCount( add->GetStackCount() + qst->reward_itemcount[i]); add->m_isDirty = true; } } } } // Choice Rewards -- Defaulting to choice 0 for ".quest complete" command 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 *add; SlotResult slotresult; add = plr->GetItemInterface()->FindItemLessMax(qst->reward_choiceitem[reward_slot], qst->reward_choiceitemcount[reward_slot], false); if (!add) { slotresult = plr->GetItemInterface()->FindFreeInventorySlot(proto); if(!slotresult.Result) { plr->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, INV_ERR_INVENTORY_FULL); } else { Item *itm = objmgr.CreateItem(qst->reward_choiceitem[reward_slot], plr); if( itm ) { itm->SetStackCount( uint32(qst->reward_choiceitemcount[reward_slot])); if( !plr->GetItemInterface()->SafeAddItem(itm,slotresult.ContainerSlot, slotresult.Slot) ) { itm->DeleteMe(); } } } } else { add->SetStackCount( add->GetStackCount() + qst->reward_choiceitemcount[reward_slot]); add->m_isDirty = true; } } } // if daily then append to finished dailies if ( qst->is_repeatable == arcemu_QUEST_REPEATABLE_DAILY ) plr->PushToFinishedDailies( qst->id ); // Remove quests that are listed to be removed on quest complete. set<uint32>::iterator iter = qst->remove_quest_list.begin(); for(; iter != qst->remove_quest_list.end(); ++iter) { if( !plr->HasFinishedQuest( (*iter ) )) plr->AddToFinishedQuests( (*iter ) ); } #ifdef ENABLE_ACHIEVEMENTS plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT, 1, 0, 0); if( qst->reward_money > 0 ) { // Money reward // Check they don't have more than the max gold if( sWorld.GoldCapEnabled && (plr->GetGold() + qst->reward_money) <= sWorld.GoldLimit ) { plr->ModGold( qst->reward_money ); } plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_QUEST_REWARD_GOLD, qst->reward_money, 0, 0); } plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE, qst->zone_id, 0, 0); plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST, qst->id, 0, 0); #endif } } 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); }