Big update.

This commit is contained in:
UltraNix
2022-03-12 22:28:00 +01:00
parent 6006eeeb01
commit 12d41d1314
2064 changed files with 427245 additions and 268481 deletions

View File

@@ -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);