Core/Quests: Improved criteria tree quest objective type
* Fixed _completedObjectives not being cleaned when adding quest * Fixed objective credit being granted if just the criteria tree row containing criteria id was completed (instead of the entire tree linked to objective) * Retroactively grant progress on quest accept for criteria types that require action that cannot be repeated (such as learning a spell) Port From (https://github.com/TrinityCore/TrinityCore/commit/4e89a302fcce7644bcd8cf239edad3b409950438)
This commit is contained in:
@@ -70,18 +70,21 @@ namespace Game.Achievements
|
|||||||
|
|
||||||
List<Criteria> criteriaList = GetCriteriaByType(type, (uint)miscValue1);
|
List<Criteria> criteriaList = GetCriteriaByType(type, (uint)miscValue1);
|
||||||
foreach (Criteria criteria in criteriaList)
|
foreach (Criteria criteria in criteriaList)
|
||||||
|
UpdateCriteria(criteria, miscValue1, miscValue2, miscValue3, refe, referencePlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateCriteria(Criteria criteria, ulong miscValue1 = 0, ulong miscValue2 = 0, ulong miscValue3 = 0, WorldObject refe = null, Player referencePlayer = null)
|
||||||
{
|
{
|
||||||
List<CriteriaTree> trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(criteria.Id);
|
var trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(criteria.Id);
|
||||||
if (!CanUpdateCriteria(criteria, trees, miscValue1, miscValue2, miscValue3, refe, referencePlayer))
|
if (!CanUpdateCriteria(criteria, trees, miscValue1, miscValue2, miscValue3, refe, referencePlayer))
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
// requirements not found in the dbc
|
// requirements not found in the dbc
|
||||||
CriteriaDataSet data = Global.CriteriaMgr.GetCriteriaDataSet(criteria);
|
CriteriaDataSet data = Global.CriteriaMgr.GetCriteriaDataSet(criteria);
|
||||||
if (data != null)
|
if (data != null && !data.Meets(referencePlayer, refe, (uint)miscValue1, (uint)miscValue2))
|
||||||
if (!data.Meets(referencePlayer, refe, (uint)miscValue1, (uint)miscValue2))
|
return;
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (type)
|
switch (criteria.Entry.Type)
|
||||||
{
|
{
|
||||||
// std. case: increment at 1
|
// std. case: increment at 1
|
||||||
case CriteriaType.WinBattleground:
|
case CriteriaType.WinBattleground:
|
||||||
@@ -123,7 +126,7 @@ namespace Game.Achievements
|
|||||||
case CriteriaType.KillPlayer:
|
case CriteriaType.KillPlayer:
|
||||||
case CriteriaType.DeliveredKillingBlow:
|
case CriteriaType.DeliveredKillingBlow:
|
||||||
case CriteriaType.PVPKillInArea:
|
case CriteriaType.PVPKillInArea:
|
||||||
case CriteriaType.WinArena: // This also behaves like CriteriaType.WinAnyRankedArena
|
case CriteriaType.WinArena: // This also behaves like CriteriaType::WinAnyRankedArena
|
||||||
case CriteriaType.ParticipateInArena:
|
case CriteriaType.ParticipateInArena:
|
||||||
case CriteriaType.PlayerTriggerGameEvent:
|
case CriteriaType.PlayerTriggerGameEvent:
|
||||||
case CriteriaType.Login:
|
case CriteriaType.Login:
|
||||||
@@ -202,7 +205,7 @@ namespace Game.Achievements
|
|||||||
SetCriteriaProgress(criteria, maxSkillvalue, referencePlayer);
|
SetCriteriaProgress(criteria, maxSkillvalue, referencePlayer);
|
||||||
break;
|
break;
|
||||||
case CriteriaType.CompleteQuestsCount:
|
case CriteriaType.CompleteQuestsCount:
|
||||||
SetCriteriaProgress(criteria, (uint)referencePlayer.GetRewardedQuestCount(), referencePlayer);
|
SetCriteriaProgress(criteria, (ulong)referencePlayer.GetRewardedQuestCount(), referencePlayer);
|
||||||
break;
|
break;
|
||||||
case CriteriaType.CompleteAnyDailyQuestPerDay:
|
case CriteriaType.CompleteAnyDailyQuestPerDay:
|
||||||
{
|
{
|
||||||
@@ -213,8 +216,8 @@ namespace Game.Achievements
|
|||||||
{
|
{
|
||||||
// reset if player missed one day.
|
// reset if player missed one day.
|
||||||
if (progress != null && progress.Date < (nextDailyResetTime - 2 * Time.Day))
|
if (progress != null && progress.Date < (nextDailyResetTime - 2 * Time.Day))
|
||||||
SetCriteriaProgress(criteria, 0, referencePlayer);
|
SetCriteriaProgress(criteria, 0, referencePlayer, ProgressType.Set);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressType progressType;
|
ProgressType progressType;
|
||||||
@@ -229,7 +232,7 @@ namespace Game.Achievements
|
|||||||
progressType = ProgressType.Accumulate;
|
progressType = ProgressType.Accumulate;
|
||||||
else
|
else
|
||||||
// last progress is within the day before the reset => Already counted today.
|
// last progress is within the day before the reset => Already counted today.
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
SetCriteriaProgress(criteria, 1, referencePlayer, progressType);
|
SetCriteriaProgress(criteria, 1, referencePlayer, progressType);
|
||||||
break;
|
break;
|
||||||
@@ -245,13 +248,14 @@ namespace Game.Achievements
|
|||||||
uint counter = 0;
|
uint counter = 0;
|
||||||
|
|
||||||
var rewQuests = referencePlayer.GetRewardedQuests();
|
var rewQuests = referencePlayer.GetRewardedQuests();
|
||||||
foreach (var id in rewQuests)
|
foreach (uint rewQuest in rewQuests)
|
||||||
{
|
{
|
||||||
Quest quest = Global.ObjectMgr.GetQuestTemplate(id);
|
Quest quest = Global.ObjectMgr.GetQuestTemplate(rewQuest);
|
||||||
if (quest != null && quest.QuestSortID >= 0 && quest.QuestSortID == criteria.Entry.Asset)
|
if (quest != null && quest.QuestSortID >= 0 && quest.QuestSortID == criteria.Entry.Asset)
|
||||||
++counter;
|
++counter;
|
||||||
}
|
}
|
||||||
SetCriteriaProgress(criteria, counter, referencePlayer);
|
|
||||||
|
SetCriteriaProgress(criteria, counter, referencePlayer, ProgressType.Highest);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -286,7 +290,7 @@ namespace Game.Achievements
|
|||||||
{
|
{
|
||||||
int reputation = referencePlayer.GetReputationMgr().GetReputation(criteria.Entry.Asset);
|
int reputation = referencePlayer.GetReputationMgr().GetReputation(criteria.Entry.Asset);
|
||||||
if (reputation > 0)
|
if (reputation > 0)
|
||||||
SetCriteriaProgress(criteria, (uint)reputation, referencePlayer);
|
SetCriteriaProgress(criteria, (ulong)reputation, referencePlayer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CriteriaType.TotalExaltedFactions:
|
case CriteriaType.TotalExaltedFactions:
|
||||||
@@ -299,9 +303,9 @@ namespace Game.Achievements
|
|||||||
foreach (var (spellId, _) in referencePlayer.GetSpellMap())
|
foreach (var (spellId, _) in referencePlayer.GetSpellMap())
|
||||||
{
|
{
|
||||||
var bounds = Global.SpellMgr.GetSkillLineAbilityMapBounds(spellId);
|
var bounds = Global.SpellMgr.GetSkillLineAbilityMapBounds(spellId);
|
||||||
foreach (var skill in bounds)
|
foreach (var skillLineRecord in bounds)
|
||||||
{
|
{
|
||||||
if (skill.SkillLine == criteria.Entry.Asset)
|
if (skillLineRecord.SkillLine == criteria.Entry.Asset)
|
||||||
{
|
{
|
||||||
// do not add couter twice if by any chance skill is listed twice in dbc (eg. skill 777 and spell 22717)
|
// do not add couter twice if by any chance skill is listed twice in dbc (eg. skill 777 and spell 22717)
|
||||||
++spellCount;
|
++spellCount;
|
||||||
@@ -309,6 +313,7 @@ namespace Game.Achievements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCriteriaProgress(criteria, spellCount, referencePlayer);
|
SetCriteriaProgress(criteria, spellCount, referencePlayer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -329,7 +334,7 @@ namespace Game.Achievements
|
|||||||
break;
|
break;
|
||||||
case CriteriaType.EarnAchievementPoints:
|
case CriteriaType.EarnAchievementPoints:
|
||||||
if (miscValue1 == 0)
|
if (miscValue1 == 0)
|
||||||
continue;
|
return;
|
||||||
SetCriteriaProgress(criteria, miscValue1, referencePlayer, ProgressType.Accumulate);
|
SetCriteriaProgress(criteria, miscValue1, referencePlayer, ProgressType.Accumulate);
|
||||||
break;
|
break;
|
||||||
case CriteriaType.EarnPersonalArenaRating:
|
case CriteriaType.EarnPersonalArenaRating:
|
||||||
@@ -339,13 +344,12 @@ namespace Game.Achievements
|
|||||||
if (miscValue1 != 0)
|
if (miscValue1 != 0)
|
||||||
{
|
{
|
||||||
if (miscValue2 != reqTeamType)
|
if (miscValue2 != reqTeamType)
|
||||||
continue;
|
return;
|
||||||
|
|
||||||
SetCriteriaProgress(criteria, miscValue1, referencePlayer, ProgressType.Highest);
|
SetCriteriaProgress(criteria, miscValue1, referencePlayer, ProgressType.Highest);
|
||||||
}
|
}
|
||||||
else // login case
|
else // login case
|
||||||
{
|
{
|
||||||
|
|
||||||
for (byte arena_slot = 0; arena_slot < SharedConst.MaxArenaSlot; ++arena_slot)
|
for (byte arena_slot = 0; arena_slot < SharedConst.MaxArenaSlot; ++arena_slot)
|
||||||
{
|
{
|
||||||
uint teamId = referencePlayer.GetArenaTeamId(arena_slot);
|
uint teamId = referencePlayer.GetArenaTeamId(arena_slot);
|
||||||
@@ -363,6 +367,7 @@ namespace Game.Achievements
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -440,6 +445,7 @@ namespace Game.Achievements
|
|||||||
case CriteriaType.ObtainAnyItemWithCurrencyValue:
|
case CriteriaType.ObtainAnyItemWithCurrencyValue:
|
||||||
case CriteriaType.EarnExpansionLevel:
|
case CriteriaType.EarnExpansionLevel:
|
||||||
case CriteriaType.LearnTransmog:
|
case CriteriaType.LearnTransmog:
|
||||||
|
default:
|
||||||
break; // Not implemented yet :(
|
break; // Not implemented yet :(
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,7 +457,6 @@ namespace Game.Achievements
|
|||||||
AfterCriteriaTreeUpdate(tree, referencePlayer);
|
AfterCriteriaTreeUpdate(tree, referencePlayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateTimedCriteria(TimeSpan timeDiff)
|
public void UpdateTimedCriteria(TimeSpan timeDiff)
|
||||||
{
|
{
|
||||||
@@ -3769,7 +3774,7 @@ namespace Game.Achievements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class CriteriaManager : Singleton<CriteriaManager>
|
public class CriteriaManager : Singleton<CriteriaManager>
|
||||||
{
|
{
|
||||||
Dictionary<uint, CriteriaDataSet> _criteriaDataMap = new();
|
Dictionary<uint, CriteriaDataSet> _criteriaDataMap = new();
|
||||||
|
|
||||||
Dictionary<uint, CriteriaTree> _criteriaTrees = new();
|
Dictionary<uint, CriteriaTree> _criteriaTrees = new();
|
||||||
@@ -4280,9 +4285,9 @@ namespace Game.Achievements
|
|||||||
|
|
||||||
func(tree);
|
func(tree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ModifierTreeNode
|
public class ModifierTreeNode
|
||||||
{
|
{
|
||||||
public ModifierTreeRecord Entry;
|
public ModifierTreeRecord Entry;
|
||||||
public List<ModifierTreeNode> Children = new();
|
public List<ModifierTreeNode> Children = new();
|
||||||
|
|||||||
@@ -785,7 +785,7 @@ namespace Game.Entities
|
|||||||
GetReputationMgr().SetVisible(factionEntry);
|
GetReputationMgr().SetVisible(factionEntry);
|
||||||
break;
|
break;
|
||||||
case QuestObjectiveType.CriteriaTree:
|
case QuestObjectiveType.CriteriaTree:
|
||||||
m_questObjectiveCriteriaMgr.ResetCriteriaTree((uint)obj.ObjectID);
|
m_questObjectiveCriteriaMgr.ResetCriteriaTree(obj);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Game.Networking;
|
|||||||
using Game.Networking.Packets;
|
using Game.Networking.Packets;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Game
|
namespace Game
|
||||||
{
|
{
|
||||||
@@ -150,9 +151,11 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetCriteriaTree(uint criteriaTreeId)
|
public void ResetCriteriaTree(QuestObjective questObjective)
|
||||||
{
|
{
|
||||||
CriteriaTree tree = Global.CriteriaMgr.GetCriteriaTree(criteriaTreeId);
|
_completedObjectives.Remove(questObjective.Id);
|
||||||
|
|
||||||
|
CriteriaTree tree = Global.CriteriaMgr.GetCriteriaTree((uint)questObjective.ObjectID);
|
||||||
if (tree == null)
|
if (tree == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -160,6 +163,12 @@ namespace Game
|
|||||||
{
|
{
|
||||||
RemoveCriteriaProgress(criteriaTree.Criteria);
|
RemoveCriteriaProgress(criteriaTree.Criteria);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
CriteriaManager.WalkCriteriaTree(tree, criteriaTree =>
|
||||||
|
{
|
||||||
|
if (criteriaTree.Criteria != null && CriteriaManager.GetRetroactivelyUpdateableCriteriaTypes().Contains(criteriaTree.Criteria.Entry.Type))
|
||||||
|
UpdateCriteria(criteriaTree.Criteria, 0, 0, 0, null, _owner);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SendAllData(Player receiver)
|
public override void SendAllData(Player receiver)
|
||||||
@@ -274,6 +283,8 @@ namespace Game
|
|||||||
if (objective == null)
|
if (objective == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
CriteriaTree entireObjectiveTree = Global.CriteriaMgr.GetCriteriaTree((uint)objective.ObjectID);
|
||||||
|
if (IsCompletedCriteriaTree(entireObjectiveTree))
|
||||||
CompletedObjective(objective, referencePlayer);
|
CompletedObjective(objective, referencePlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user