mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-18 03:15:41 +00:00
Big update.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "CreatureAI.h"
|
||||
#include "DisableMgr.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "GameTime.h"
|
||||
#include "GitRevision.h"
|
||||
#include "GossipDef.h"
|
||||
#include "Group.h"
|
||||
@@ -87,7 +88,9 @@ void Player::PrepareQuestMenu(ObjectGuid guid)
|
||||
if (!CanTakeQuest(quest, false))
|
||||
continue;
|
||||
|
||||
if (quest->IsAutoComplete())
|
||||
if (quest->IsAutoComplete() && (!quest->IsRepeatable() || quest->IsDaily() || quest->IsWeekly() || quest->IsMonthly()))
|
||||
qm.AddMenuItem(quest_id, 0);
|
||||
else if (quest->IsAutoComplete())
|
||||
qm.AddMenuItem(quest_id, 4);
|
||||
else if (GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
|
||||
qm.AddMenuItem(quest_id, 2);
|
||||
@@ -146,7 +149,7 @@ void Player::SendPreparedQuest(ObjectGuid guid)
|
||||
}
|
||||
}
|
||||
}
|
||||
// multiple entries
|
||||
// multiple entries
|
||||
else
|
||||
{
|
||||
QEmote qe;
|
||||
@@ -176,8 +179,8 @@ void Player::SendPreparedQuest(ObjectGuid guid)
|
||||
|
||||
int loc_idx = GetSession()->GetSessionDbLocaleIndex();
|
||||
if (loc_idx >= 0)
|
||||
if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid))
|
||||
ObjectMgr::GetLocaleString(nl->Text_0[0], loc_idx, title);
|
||||
if (NpcTextLocale const* npcTextLocale = sObjectMgr->GetNpcTextLocale(textid))
|
||||
ObjectMgr::GetLocaleString(npcTextLocale->Text_0[0], loc_idx, title);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -185,11 +188,12 @@ void Player::SendPreparedQuest(ObjectGuid guid)
|
||||
|
||||
int loc_idx = GetSession()->GetSessionDbLocaleIndex();
|
||||
if (loc_idx >= 0)
|
||||
if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid))
|
||||
ObjectMgr::GetLocaleString(nl->Text_1[0], loc_idx, title);
|
||||
if (NpcTextLocale const* npcTextLocale = sObjectMgr->GetNpcTextLocale(textid))
|
||||
ObjectMgr::GetLocaleString(npcTextLocale->Text_1[0], loc_idx, title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlayerTalkClass->SendQuestGiverQuestList(qe, title, guid);
|
||||
}
|
||||
}
|
||||
@@ -551,7 +555,7 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
|
||||
|
||||
AddTimedQuest(quest_id);
|
||||
questStatusData.Timer = timeAllowed * IN_MILLISECONDS;
|
||||
qtime = static_cast<uint32>(time(nullptr)) + timeAllowed;
|
||||
qtime = static_cast<uint32>(GameTime::GetGameTime().count()) + timeAllowed;
|
||||
}
|
||||
else
|
||||
questStatusData.Timer = 0;
|
||||
@@ -575,10 +579,10 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
|
||||
{
|
||||
// prepare Quest Tracker datas
|
||||
auto stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_QUEST_TRACK);
|
||||
stmt->setUInt32(0, quest_id);
|
||||
stmt->setUInt32(1, GetGUID().GetCounter());
|
||||
stmt->setString(2, GitRevision::GetHash());
|
||||
stmt->setString(3, GitRevision::GetDate());
|
||||
stmt->SetData(0, quest_id);
|
||||
stmt->SetData(1, GetGUID().GetCounter());
|
||||
stmt->SetData(2, GitRevision::GetHash());
|
||||
stmt->SetData(3, GitRevision::GetDate());
|
||||
|
||||
// add to Quest Tracker
|
||||
CharacterDatabase.Execute(stmt);
|
||||
@@ -620,8 +624,8 @@ void Player::CompleteQuest(uint32 quest_id)
|
||||
{
|
||||
// prepare Quest Tracker datas
|
||||
auto stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_COMPLETE_TIME);
|
||||
stmt->setUInt32(0, quest_id);
|
||||
stmt->setUInt32(1, GetGUID().GetCounter());
|
||||
stmt->SetData(0, quest_id);
|
||||
stmt->SetData(1, GetGUID().GetCounter());
|
||||
|
||||
// add to Quest Tracker
|
||||
CharacterDatabase.Execute(stmt);
|
||||
@@ -657,14 +661,14 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
{
|
||||
if (sObjectMgr->GetItemTemplate(quest->RequiredItemId[i]))
|
||||
{
|
||||
DestroyItemCount(quest->RequiredItemId[i], quest->RequiredItemCount[i], true);
|
||||
DestroyItemCount(quest->RequiredItemId[i], quest->RequiredItemCount[i], true, true);
|
||||
}
|
||||
}
|
||||
for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
{
|
||||
if (sObjectMgr->GetItemTemplate(quest->ItemDrop[i]))
|
||||
{
|
||||
DestroyItemCount(quest->ItemDrop[i], quest->ItemDropQuantity[i], true);
|
||||
DestroyItemCount(quest->ItemDrop[i], quest->ItemDropQuantity[i], true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,7 +730,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
bool rewarded = IsQuestRewarded(quest_id) && !quest->IsDFQuest();
|
||||
|
||||
// Not give XP in case already completed once repeatable quest
|
||||
uint32 XP = rewarded ? 0 : uint32(quest->XPValue(getLevel()) * GetQuestRate());
|
||||
uint32 XP = rewarded ? 0 : uint32(quest->XPValue(getLevel()) * GetQuestRate(quest->IsDFQuest()));
|
||||
|
||||
// handle SPELL_AURA_MOD_XP_QUEST_PCT auras
|
||||
Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT);
|
||||
@@ -815,25 +819,29 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
|
||||
// cast spells after mark quest complete (some spells have quest completed state requirements in spell_area data)
|
||||
if (quest->GetRewSpellCast() > 0)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpellCast());
|
||||
if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
|
||||
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpellCast()))
|
||||
{
|
||||
if (Creature* creature = GetMap()->GetCreature(questGiver->GetGUID()))
|
||||
creature->CastSpell(this, quest->GetRewSpellCast(), true);
|
||||
if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
|
||||
{
|
||||
if (Creature* creature = GetMap()->GetCreature(questGiver->GetGUID()))
|
||||
creature->CastSpell(this, quest->GetRewSpellCast(), true);
|
||||
}
|
||||
else
|
||||
CastSpell(this, quest->GetRewSpellCast(), true);
|
||||
}
|
||||
else
|
||||
CastSpell(this, quest->GetRewSpellCast(), true);
|
||||
}
|
||||
else if (quest->GetRewSpell() > 0)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpell());
|
||||
if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
|
||||
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpell()))
|
||||
{
|
||||
if (Creature* creature = GetMap()->GetCreature(questGiver->GetGUID()))
|
||||
creature->CastSpell(this, quest->GetRewSpell(), true);
|
||||
if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM) && !spellInfo->IsSelfCast())
|
||||
{
|
||||
if (Creature* creature = GetMap()->GetCreature(questGiver->GetGUID()))
|
||||
creature->CastSpell(this, quest->GetRewSpell(), true);
|
||||
}
|
||||
else
|
||||
CastSpell(this, quest->GetRewSpell(), true);
|
||||
}
|
||||
else
|
||||
CastSpell(this, quest->GetRewSpell(), true);
|
||||
}
|
||||
|
||||
if (quest->GetZoneOrSort() > 0)
|
||||
@@ -985,7 +993,7 @@ bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg) const
|
||||
|
||||
for (Quest::PrevQuests::const_iterator iter = qInfo->prevQuests.begin(); iter != qInfo->prevQuests.end(); ++iter)
|
||||
{
|
||||
uint32 prevId = abs(*iter);
|
||||
uint32 prevId = std::abs(*iter);
|
||||
|
||||
Quest const* qPrevInfo = sObjectMgr->GetQuestTemplate(prevId);
|
||||
|
||||
@@ -1144,7 +1152,7 @@ bool Player::SatisfyQuestConditions(Quest const* qInfo, bool msg)
|
||||
{
|
||||
if (msg)
|
||||
SendCanTakeQuestResponse(INVALIDREASON_DONT_HAVE_REQ);
|
||||
LOG_DEBUG("condition", "Player::SatisfyQuestConditions: conditions not met for quest %u", qInfo->GetQuestId());
|
||||
LOG_DEBUG("condition", "Player::SatisfyQuestConditions: conditions not met for quest {}", qInfo->GetQuestId());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -1399,18 +1407,26 @@ QuestStatus Player::GetQuestStatus(uint32 quest_id) const
|
||||
if (quest_id)
|
||||
{
|
||||
QuestStatusMap::const_iterator itr = m_QuestStatus.find(quest_id);
|
||||
|
||||
if (itr != m_QuestStatus.end())
|
||||
{
|
||||
return itr->second.Status;
|
||||
}
|
||||
|
||||
if (Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id))
|
||||
{
|
||||
if (qInfo->IsSeasonal())
|
||||
{
|
||||
return SatisfyQuestSeasonal(qInfo, false) ? QUEST_STATUS_NONE : QUEST_STATUS_REWARDED;
|
||||
}
|
||||
|
||||
if (!qInfo->IsRepeatable() && IsQuestRewarded(quest_id))
|
||||
{
|
||||
return QUEST_STATUS_REWARDED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QUEST_STATUS_NONE;
|
||||
}
|
||||
|
||||
@@ -1580,7 +1596,7 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
|
||||
}
|
||||
default:
|
||||
// it's impossible, but check
|
||||
//TC_LOG_ERROR("entities.player.quest", "GetQuestDialogStatus called for unexpected type %u", questgiver->GetTypeId());
|
||||
//LOG_ERROR("entities.player.quest", "GetQuestDialogStatus called for unexpected type {}", questgiver->GetTypeId());
|
||||
return DIALOG_STATUS_NONE;
|
||||
}
|
||||
|
||||
@@ -1601,20 +1617,9 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
|
||||
QuestStatus status = GetQuestStatus(questId);
|
||||
if ((status == QUEST_STATUS_COMPLETE && !GetQuestRewardStatus(questId)) || (quest->IsAutoComplete() && CanTakeQuest(quest, false)))
|
||||
{
|
||||
if (quest->IsRepeatable() && quest->IsDailyOrWeekly())
|
||||
if (quest->IsRepeatable() || quest->IsDailyOrWeekly())
|
||||
{
|
||||
if (quest->IsAutoComplete())
|
||||
{
|
||||
result2 = DIALOG_STATUS_AVAILABLE_REP;
|
||||
}
|
||||
else
|
||||
{
|
||||
result2 = DIALOG_STATUS_REWARD_REP;
|
||||
}
|
||||
}
|
||||
else if (quest->IsAutoComplete())
|
||||
{
|
||||
result2 = DIALOG_STATUS_AVAILABLE;
|
||||
result2 = DIALOG_STATUS_REWARD_REP;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1649,35 +1654,64 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
|
||||
{
|
||||
if (SatisfyQuestLevel(quest, false))
|
||||
{
|
||||
bool isLowLevel = (getLevel() > (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)));
|
||||
bool isNotLowLevelQuest = getLevel() <= (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF));
|
||||
|
||||
if (quest->IsAutoComplete())
|
||||
{
|
||||
if (isLowLevel)
|
||||
result2 = DIALOG_STATUS_LOW_LEVEL_REWARD_REP;
|
||||
else
|
||||
result2 = DIALOG_STATUS_REWARD_REP;
|
||||
}
|
||||
else
|
||||
if (quest->IsRepeatable())
|
||||
{
|
||||
if (quest->IsDaily())
|
||||
{
|
||||
if (isLowLevel)
|
||||
result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE_REP;
|
||||
else
|
||||
if (isNotLowLevelQuest)
|
||||
{
|
||||
result2 = DIALOG_STATUS_AVAILABLE_REP;
|
||||
}
|
||||
else
|
||||
{
|
||||
result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE_REP;
|
||||
}
|
||||
}
|
||||
else if (quest->IsWeekly() || quest->IsMonthly())
|
||||
{
|
||||
if (isNotLowLevelQuest)
|
||||
{
|
||||
result2 = DIALOG_STATUS_AVAILABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE;
|
||||
}
|
||||
}
|
||||
else if (quest->IsAutoComplete())
|
||||
{
|
||||
if (isNotLowLevelQuest)
|
||||
{
|
||||
result2 = DIALOG_STATUS_REWARD_REP;
|
||||
}
|
||||
else
|
||||
{
|
||||
result2 = DIALOG_STATUS_LOW_LEVEL_REWARD_REP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isLowLevel)
|
||||
result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE;
|
||||
if (isNotLowLevelQuest)
|
||||
{
|
||||
result2 = DIALOG_STATUS_REWARD_REP;
|
||||
}
|
||||
else
|
||||
result2 = DIALOG_STATUS_AVAILABLE;
|
||||
{
|
||||
result2 = DIALOG_STATUS_LOW_LEVEL_REWARD_REP;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result2 = isNotLowLevelQuest ? DIALOG_STATUS_AVAILABLE : DIALOG_STATUS_LOW_LEVEL_AVAILABLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result2 = DIALOG_STATUS_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1933,19 +1967,22 @@ void Player::KilledMonsterCredit(uint32 entry, ObjectGuid guid)
|
||||
}
|
||||
}
|
||||
|
||||
void Player::KilledPlayerCredit()
|
||||
void Player::KilledPlayerCredit(uint16 count)
|
||||
{
|
||||
uint16 addkillcount = 1;
|
||||
|
||||
for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
|
||||
{
|
||||
uint32 questid = GetQuestSlotQuestId(i);
|
||||
if (!questid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Quest const* qInfo = sObjectMgr->GetQuestTemplate(questid);
|
||||
if (!qInfo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// just if !ingroup || !noraidgroup || raidgroup
|
||||
QuestStatusData& q_status = m_QuestStatus[questid];
|
||||
if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficulty())))
|
||||
@@ -1953,27 +1990,44 @@ void Player::KilledPlayerCredit()
|
||||
// Xinef: PvP Killing quest require player to be in same zone as quest zone (only 2 quests so no doubt, can be extended to conditions in cata ;s)
|
||||
if (qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_PLAYER_KILL) && (qInfo->GetZoneOrSort() >= 0 && GetZoneId() == uint32(qInfo->GetZoneOrSort())))
|
||||
{
|
||||
uint32 reqkill = qInfo->GetPlayersSlain();
|
||||
uint16 curkill = q_status.PlayerCount;
|
||||
|
||||
if (curkill < reqkill)
|
||||
{
|
||||
q_status.PlayerCount = curkill + addkillcount;
|
||||
|
||||
m_QuestStatusSave[questid] = true;
|
||||
|
||||
SendQuestUpdateAddPlayer(qInfo, curkill, addkillcount);
|
||||
}
|
||||
|
||||
if (CanCompleteQuest(questid))
|
||||
CompleteQuest(questid);
|
||||
|
||||
break;
|
||||
KilledPlayerCreditForQuest(count, qInfo);
|
||||
break; // there is only one quest per zone
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::KilledPlayerCreditForQuest(uint16 count, Quest const* quest)
|
||||
{
|
||||
uint32 const questId = quest->GetQuestId();
|
||||
|
||||
auto it = m_QuestStatus.find(questId);
|
||||
if (it == m_QuestStatus.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QuestStatusData& questStatus = it->second;
|
||||
|
||||
uint16 curKill = questStatus.PlayerCount;
|
||||
uint32 reqKill = quest->GetPlayersSlain();
|
||||
|
||||
if (curKill < reqKill)
|
||||
{
|
||||
count = std::min<uint16>(reqKill - curKill, count);
|
||||
questStatus.PlayerCount = curKill + count;
|
||||
|
||||
m_QuestStatusSave[quest->GetQuestId()] = true;
|
||||
|
||||
SendQuestUpdateAddPlayer(quest, curKill, count);
|
||||
}
|
||||
|
||||
if (CanCompleteQuest(questId))
|
||||
{
|
||||
CompleteQuest(questId);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::KillCreditGO(uint32 entry, ObjectGuid guid)
|
||||
{
|
||||
uint16 addCastCount = 1;
|
||||
@@ -2267,14 +2321,14 @@ void Player::SendQuestComplete(uint32 quest_id)
|
||||
WorldPacket data(SMSG_QUESTUPDATE_COMPLETE, 4);
|
||||
data << uint32(quest_id);
|
||||
GetSession()->SendPacket(&data);
|
||||
LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest_id);
|
||||
LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = {}", quest_id);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::SendQuestReward(Quest const* quest, uint32 XP)
|
||||
{
|
||||
uint32 questid = quest->GetQuestId();
|
||||
LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid);
|
||||
LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = {}", questid);
|
||||
sGameEventMgr->HandleQuestComplete(questid);
|
||||
WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4 + 4 + 4 + 4 + 4));
|
||||
data << uint32(questid);
|
||||
|
||||
Reference in New Issue
Block a user