Core/Achievements: Fixed achievement criteria StartEvent and FailEvent
* Criteria using StartEvent cannot be updated without that event triggering first (not only for timed achievements) * Implemented most StartEvent and FailEvent types * Fixed saving criteria removed by RemoveCriteriaProgress Port From (https://github.com/TrinityCore/TrinityCore/commit/41a20b1e4008d450d075847ef1fe367f0e3a240f)
This commit is contained in:
@@ -2122,7 +2122,7 @@ namespace Framework.Constants
|
|||||||
Unk17 = 0x20000, // 17
|
Unk17 = 0x20000, // 17
|
||||||
ActivatesRequiredShapeshift = 0x40000, // 18
|
ActivatesRequiredShapeshift = 0x40000, // 18
|
||||||
Unk19 = 0x80000, // 19
|
Unk19 = 0x80000, // 19
|
||||||
Unk20 = 0x100000, // 20
|
PeriodicRefreshExtendsDuration = 0x100000, // 20 Periodic Refresh Extends Duration
|
||||||
Unk21 = 0x200000, // 21
|
Unk21 = 0x200000, // 21
|
||||||
Unk22 = 0x400000, // 22
|
Unk22 = 0x400000, // 22
|
||||||
Unk23 = 0x800000, // 23
|
Unk23 = 0x800000, // 23
|
||||||
|
|||||||
@@ -63,13 +63,6 @@ namespace Game.Achievements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (achievement.InstanceID != -1 && referencePlayer.GetMapId() != achievement.InstanceID)
|
|
||||||
{
|
|
||||||
Log.outTrace(LogFilter.Achievement, "CanUpdateCriteriaTree: (Id: {0} Type {1} Achievement {2}) Wrong map",
|
|
||||||
criteria.Id, criteria.Entry.Type, achievement.Id);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((achievement.Faction == AchievementFaction.Horde && referencePlayer.GetTeam() != Team.Horde) ||
|
if ((achievement.Faction == AchievementFaction.Horde && referencePlayer.GetTeam() != Team.Horde) ||
|
||||||
(achievement.Faction == AchievementFaction.Alliance && referencePlayer.GetTeam() != Team.Alliance))
|
(achievement.Faction == AchievementFaction.Alliance && referencePlayer.GetTeam() != Team.Alliance))
|
||||||
{
|
{
|
||||||
@@ -360,40 +353,6 @@ namespace Game.Achievements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetCriteria(CriteriaFailEvent failEvent, uint failAsset, bool evenIfCriteriaComplete)
|
|
||||||
{
|
|
||||||
Log.outDebug(LogFilter.Achievement, $"ResetAchievementCriteria({failEvent}, {failAsset}, {evenIfCriteriaComplete})");
|
|
||||||
|
|
||||||
// Disable for GameMasters with GM-mode enabled or for players that don't have the related RBAC permission
|
|
||||||
if (_owner.IsGameMaster() || _owner.GetSession().HasPermission(RBACPermissions.CannotEarnAchievements))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var achievementCriteriaList = Global.CriteriaMgr.GetCriteriaByFailEvent(failEvent, (int)failAsset);
|
|
||||||
if (!achievementCriteriaList.Empty())
|
|
||||||
{
|
|
||||||
foreach (Criteria achievementCriteria in achievementCriteriaList)
|
|
||||||
{
|
|
||||||
|
|
||||||
var trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(achievementCriteria.Id);
|
|
||||||
bool allComplete = true;
|
|
||||||
foreach (CriteriaTree tree in trees)
|
|
||||||
{
|
|
||||||
// don't update already completed criteria if not forced or achievement already complete
|
|
||||||
if (!(IsCompletedCriteriaTree(tree) && !evenIfCriteriaComplete) || !HasAchieved(tree.Achievement.Id))
|
|
||||||
{
|
|
||||||
allComplete = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allComplete)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
RemoveCriteriaProgress(achievementCriteria);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SendAllData(Player receiver)
|
public override void SendAllData(Player receiver)
|
||||||
{
|
{
|
||||||
AllAccountCriteria allAccountCriteria = new();
|
AllAccountCriteria allAccountCriteria = new();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Game.Achievements
|
|||||||
public class CriteriaHandler
|
public class CriteriaHandler
|
||||||
{
|
{
|
||||||
protected Dictionary<uint, CriteriaProgress> _criteriaProgress = new();
|
protected Dictionary<uint, CriteriaProgress> _criteriaProgress = new();
|
||||||
Dictionary<uint, uint /*ms time left*/> _timeCriteriaTrees = new();
|
Dictionary<uint /*criteriaID*/, TimeSpan /*time left*/> _startedCriteria = new();
|
||||||
|
|
||||||
public virtual void Reset()
|
public virtual void Reset()
|
||||||
{
|
{
|
||||||
@@ -444,75 +444,89 @@ namespace Game.Achievements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateTimedCriteria(uint timeDiff)
|
public void UpdateTimedCriteria(TimeSpan timeDiff)
|
||||||
{
|
{
|
||||||
if (!_timeCriteriaTrees.Empty())
|
foreach (var key in _startedCriteria.Keys.ToList())
|
||||||
{
|
{
|
||||||
foreach (var key in _timeCriteriaTrees.Keys.ToList())
|
// Time is up, remove timer and reset progress
|
||||||
|
if (_startedCriteria[key] <= timeDiff)
|
||||||
{
|
{
|
||||||
var value = _timeCriteriaTrees[key];
|
RemoveCriteriaProgress(Global.CriteriaMgr.GetCriteria(key));
|
||||||
// Time is up, remove timer and reset progress
|
|
||||||
if (value <= timeDiff)
|
|
||||||
{
|
|
||||||
CriteriaTree criteriaTree = Global.CriteriaMgr.GetCriteriaTree(key);
|
|
||||||
if (criteriaTree.Criteria != null)
|
|
||||||
RemoveCriteriaProgress(criteriaTree.Criteria);
|
|
||||||
|
|
||||||
_timeCriteriaTrees.Remove(key);
|
_startedCriteria.Remove(key);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_timeCriteriaTrees[key] -= timeDiff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
_startedCriteria[key] -= timeDiff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartCriteriaTimer(CriteriaStartEvent startEvent, uint entry, uint timeLost = 0)
|
public void StartCriteria(CriteriaStartEvent startEvent, uint entry, TimeSpan timeLost = default)
|
||||||
{
|
{
|
||||||
List<Criteria> criteriaList = Global.CriteriaMgr.GetTimedCriteriaByType(startEvent);
|
List<Criteria> criteriaList = Global.CriteriaMgr.GetCriteriaByStartEvent(startEvent, (int)entry);
|
||||||
|
if (criteriaList.Empty())
|
||||||
|
return;
|
||||||
|
|
||||||
foreach (Criteria criteria in criteriaList)
|
foreach (Criteria criteria in criteriaList)
|
||||||
{
|
{
|
||||||
if (criteria.Entry.StartAsset != entry)
|
TimeSpan timeLimit = TimeSpan.MaxValue; // this value is for criteria that have a start event requirement but no time limit
|
||||||
|
if (criteria.Entry.StartTimer != 0)
|
||||||
|
timeLimit = TimeSpan.FromSeconds(criteria.Entry.StartTimer);
|
||||||
|
|
||||||
|
timeLimit -= timeLost;
|
||||||
|
|
||||||
|
if (timeLimit <= TimeSpan.Zero)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
List<CriteriaTree> trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(criteria.Id);
|
List<CriteriaTree> trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(criteria.Id);
|
||||||
bool canStart = false;
|
bool canStart = trees.Any(tree => !IsCompletedCriteriaTree(tree));
|
||||||
foreach (CriteriaTree tree in trees)
|
|
||||||
{
|
|
||||||
if ((!_timeCriteriaTrees.ContainsKey(tree.Id) || criteria.Entry.GetFlags().HasFlag(CriteriaFlags.ResetOnStart)) && !IsCompletedCriteriaTree(tree))
|
|
||||||
{
|
|
||||||
// Start the timer
|
|
||||||
if (criteria.Entry.StartTimer * Time.InMilliseconds > timeLost)
|
|
||||||
{
|
|
||||||
_timeCriteriaTrees[tree.Id] = (uint)(criteria.Entry.StartTimer * Time.InMilliseconds - timeLost);
|
|
||||||
canStart = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!canStart)
|
if (!canStart)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
bool isNew = _startedCriteria.TryAdd(criteria.Id, timeLimit);
|
||||||
|
if (!isNew)
|
||||||
|
{
|
||||||
|
if (!criteria.Entry.GetFlags().HasFlag(CriteriaFlags.ResetOnStart))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_startedCriteria[criteria.Id] = timeLimit;
|
||||||
|
}
|
||||||
|
|
||||||
// and at client too
|
// and at client too
|
||||||
SetCriteriaProgress(criteria, 0, null, ProgressType.Set);
|
SetCriteriaProgress(criteria, 0, null, ProgressType.Set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveCriteriaTimer(CriteriaStartEvent startEvent, uint entry)
|
public void FailCriteria(CriteriaFailEvent failEvent, uint asset)
|
||||||
{
|
{
|
||||||
List<Criteria> criteriaList = Global.CriteriaMgr.GetTimedCriteriaByType(startEvent);
|
List<Criteria> criteriaList = Global.CriteriaMgr.GetCriteriaByFailEvent(failEvent, (int)asset);
|
||||||
|
if (criteriaList.Empty())
|
||||||
|
return;
|
||||||
|
|
||||||
foreach (Criteria criteria in criteriaList)
|
foreach (Criteria criteria in criteriaList)
|
||||||
{
|
{
|
||||||
if (criteria.Entry.StartAsset != entry)
|
_startedCriteria.Remove(criteria.Id);
|
||||||
continue;
|
|
||||||
|
|
||||||
List<CriteriaTree> trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(criteria.Id);
|
List<CriteriaTree> trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(criteria.Id);
|
||||||
// Remove the timer from all trees
|
bool allTreesFullyComplete = trees.All(tree =>
|
||||||
foreach (CriteriaTree tree in trees)
|
{
|
||||||
_timeCriteriaTrees.Remove(tree.Id);
|
CriteriaTree root = tree;
|
||||||
|
CriteriaTree parent = Global.CriteriaMgr.GetCriteriaTree(root.Entry.Parent);
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
root = parent;
|
||||||
|
parent = Global.CriteriaMgr.GetCriteriaTree(root.Entry.Parent);
|
||||||
|
} while (parent != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsCompletedCriteriaTree(root);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (allTreesFullyComplete)
|
||||||
|
continue;
|
||||||
|
|
||||||
// remove progress
|
|
||||||
RemoveCriteriaProgress(criteria);
|
RemoveCriteriaProgress(criteria);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -524,29 +538,6 @@ namespace Game.Achievements
|
|||||||
|
|
||||||
public void SetCriteriaProgress(Criteria criteria, ulong changeValue, Player referencePlayer, ProgressType progressType = ProgressType.Set)
|
public void SetCriteriaProgress(Criteria criteria, ulong changeValue, Player referencePlayer, ProgressType progressType = ProgressType.Set)
|
||||||
{
|
{
|
||||||
// Don't allow to cheat - doing timed criteria without timer active
|
|
||||||
List<CriteriaTree> trees = null;
|
|
||||||
if (criteria.Entry.StartTimer != 0)
|
|
||||||
{
|
|
||||||
trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(criteria.Id);
|
|
||||||
if (trees.Empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool hasTreeForTimed = false;
|
|
||||||
foreach (CriteriaTree tree in trees)
|
|
||||||
{
|
|
||||||
var timedIter = _timeCriteriaTrees.LookupByKey(tree.Id);
|
|
||||||
if (timedIter != 0)
|
|
||||||
{
|
|
||||||
hasTreeForTimed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasTreeForTimed)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.outDebug(LogFilter.Achievement, "SetCriteriaProgress({0}, {1}) for {2}", criteria.Id, changeValue, GetOwnerInfo());
|
Log.outDebug(LogFilter.Achievement, "SetCriteriaProgress({0}, {1}) for {2}", criteria.Id, changeValue, GetOwnerInfo());
|
||||||
|
|
||||||
CriteriaProgress progress = GetCriteriaProgress(criteria);
|
CriteriaProgress progress = GetCriteriaProgress(criteria);
|
||||||
@@ -596,20 +587,18 @@ namespace Game.Achievements
|
|||||||
TimeSpan timeElapsed = TimeSpan.Zero;
|
TimeSpan timeElapsed = TimeSpan.Zero;
|
||||||
if (criteria.Entry.StartTimer != 0)
|
if (criteria.Entry.StartTimer != 0)
|
||||||
{
|
{
|
||||||
Cypher.Assert(trees != null);
|
if (_startedCriteria.TryGetValue(criteria.Id, out TimeSpan startedTime))
|
||||||
|
|
||||||
foreach (CriteriaTree tree in trees)
|
|
||||||
{
|
{
|
||||||
var timed = _timeCriteriaTrees.LookupByKey(tree.Id);
|
// Client expects this in packet
|
||||||
if (timed != 0)
|
timeElapsed = TimeSpan.FromSeconds(criteria.Entry.StartTimer) - startedTime;
|
||||||
{
|
|
||||||
// Client expects this in packet
|
|
||||||
timeElapsed = TimeSpan.FromSeconds(criteria.Entry.StartTimer - (timed / Time.InMilliseconds));
|
|
||||||
|
|
||||||
// Remove the timer, we wont need it anymore
|
// Remove the timer, we wont need it anymore
|
||||||
if (IsCompletedCriteriaTree(tree))
|
var trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(criteria.Id);
|
||||||
_timeCriteriaTrees.Remove(tree.Id);
|
|
||||||
}
|
bool allTreesCompleted = trees.All(IsCompletedCriteriaTree);
|
||||||
|
|
||||||
|
if (allTreesCompleted)
|
||||||
|
_startedCriteria.Remove(criteria.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,7 +615,8 @@ namespace Game.Achievements
|
|||||||
|
|
||||||
SendCriteriaProgressRemoved(criteria.Id);
|
SendCriteriaProgressRemoved(criteria.Id);
|
||||||
|
|
||||||
_criteriaProgress.Remove(criteria.Id);
|
_criteriaProgress[criteria.Id].Counter = 0;
|
||||||
|
_criteriaProgress[criteria.Id].Changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsCompletedCriteriaTree(CriteriaTree tree)
|
public bool IsCompletedCriteriaTree(CriteriaTree tree)
|
||||||
@@ -888,22 +878,8 @@ namespace Game.Achievements
|
|||||||
|
|
||||||
bool ConditionsSatisfied(Criteria criteria, Player referencePlayer)
|
bool ConditionsSatisfied(Criteria criteria, Player referencePlayer)
|
||||||
{
|
{
|
||||||
if (criteria.Entry.FailEvent == 0)
|
if (criteria.Entry.StartEvent != 0 && !_startedCriteria.ContainsKey(criteria.Id))
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
switch ((CriteriaFailEvent)criteria.Entry.FailEvent)
|
|
||||||
{
|
|
||||||
case CriteriaFailEvent.LeaveBattleground:
|
|
||||||
if (!referencePlayer.InBattleground())
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case CriteriaFailEvent.ModifyPartyStatus:
|
|
||||||
if (referencePlayer.GetGroup() != null)
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3720,7 +3696,7 @@ namespace Game.Achievements
|
|||||||
MultiMap<uint, Criteria>[] _scenarioCriteriasByTypeAndScenarioId = new MultiMap<uint, Criteria>[(int)CriteriaType.Count];
|
MultiMap<uint, Criteria>[] _scenarioCriteriasByTypeAndScenarioId = new MultiMap<uint, Criteria>[(int)CriteriaType.Count];
|
||||||
MultiMap<CriteriaType, Criteria> _questObjectiveCriteriasByType = new();
|
MultiMap<CriteriaType, Criteria> _questObjectiveCriteriasByType = new();
|
||||||
|
|
||||||
MultiMap<CriteriaStartEvent, Criteria> _criteriasByTimedType = new();
|
MultiMap<int, Criteria>[] _criteriasByStartEvent = new MultiMap<int, Criteria>[(int)CriteriaStartEvent.Max];
|
||||||
MultiMap<int, Criteria>[] _criteriasByFailEvent = new MultiMap<int, Criteria>[(int)CriteriaFailEvent.Max];
|
MultiMap<int, Criteria>[] _criteriasByFailEvent = new MultiMap<int, Criteria>[(int)CriteriaFailEvent.Max];
|
||||||
|
|
||||||
CriteriaManager()
|
CriteriaManager()
|
||||||
@@ -3943,7 +3919,7 @@ namespace Game.Achievements
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (criteriaEntry.StartTimer != 0)
|
if (criteriaEntry.StartTimer != 0)
|
||||||
_criteriasByTimedType.Add((CriteriaStartEvent)criteriaEntry.StartEvent, criteria);
|
_criteriasByStartEvent[criteriaEntry.StartEvent].Add((int)criteriaEntry.StartAsset, criteria);
|
||||||
|
|
||||||
if (criteriaEntry.FailEvent != 0)
|
if (criteriaEntry.FailEvent != 0)
|
||||||
_criteriasByFailEvent[criteriaEntry.FailEvent].Add((int)criteriaEntry.FailAsset, criteria);
|
_criteriasByFailEvent[criteriaEntry.FailEvent].Add((int)criteriaEntry.FailAsset, criteria);
|
||||||
@@ -4084,6 +4060,16 @@ namespace Game.Achievements
|
|||||||
return _scenarioCriteriasByTypeAndScenarioId[(int)type].LookupByKey(scenarioId);
|
return _scenarioCriteriasByTypeAndScenarioId[(int)type].LookupByKey(scenarioId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Criteria> GetCriteriaByStartEvent(CriteriaStartEvent startEvent, int asset)
|
||||||
|
{
|
||||||
|
return _criteriasByStartEvent[(int)startEvent].LookupByKey(asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Criteria> GetCriteriaByFailEvent(CriteriaFailEvent failEvent, int asset)
|
||||||
|
{
|
||||||
|
return _criteriasByFailEvent[(int)failEvent].LookupByKey(asset);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Criteria> GetGuildCriteriaByType(CriteriaType type)
|
public List<Criteria> GetGuildCriteriaByType(CriteriaType type)
|
||||||
{
|
{
|
||||||
return _guildCriteriasByType.LookupByKey(type);
|
return _guildCriteriasByType.LookupByKey(type);
|
||||||
@@ -4099,16 +4085,6 @@ namespace Game.Achievements
|
|||||||
return _criteriaTreeByCriteria.LookupByKey(criteriaId);
|
return _criteriaTreeByCriteria.LookupByKey(criteriaId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Criteria> GetTimedCriteriaByType(CriteriaStartEvent startEvent)
|
|
||||||
{
|
|
||||||
return _criteriasByTimedType.LookupByKey(startEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Criteria> GetCriteriaByFailEvent(CriteriaFailEvent failEvent, int asset)
|
|
||||||
{
|
|
||||||
return _criteriasByFailEvent[(int)failEvent].LookupByKey(asset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CriteriaDataSet GetCriteriaDataSet(Criteria criteria)
|
public CriteriaDataSet GetCriteriaDataSet(Criteria criteria)
|
||||||
{
|
{
|
||||||
return _criteriaDataMap.LookupByKey(criteria.Id);
|
return _criteriaDataMap.LookupByKey(criteria.Id);
|
||||||
|
|||||||
@@ -237,6 +237,7 @@ namespace Game.Arenas
|
|||||||
{
|
{
|
||||||
// update achievement BEFORE personal rating update
|
// update achievement BEFORE personal rating update
|
||||||
uint rating = player.GetArenaPersonalRating(winnerArenaTeam.GetSlot());
|
uint rating = player.GetArenaPersonalRating(winnerArenaTeam.GetSlot());
|
||||||
|
player.StartCriteria(CriteriaStartEvent.WinRankedArenaMatchWithTeamSize, 0);
|
||||||
player.UpdateCriteria(CriteriaType.WinAnyRankedArena, rating != 0 ? rating : 1);
|
player.UpdateCriteria(CriteriaType.WinAnyRankedArena, rating != 0 ? rating : 1);
|
||||||
player.UpdateCriteria(CriteriaType.WinArena, GetMapId());
|
player.UpdateCriteria(CriteriaType.WinArena, GetMapId());
|
||||||
|
|
||||||
@@ -266,7 +267,7 @@ namespace Game.Arenas
|
|||||||
loserArenaTeam.MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange);
|
loserArenaTeam.MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange);
|
||||||
|
|
||||||
// Arena lost => reset the win_rated_arena having the "no_lose" condition
|
// Arena lost => reset the win_rated_arena having the "no_lose" condition
|
||||||
player.ResetCriteria(CriteriaFailEvent.LoseRankedArenaMatchWithTeamSize, 0);
|
player.FailCriteria(CriteriaFailEvent.LoseRankedArenaMatchWithTeamSize, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -352,9 +352,12 @@ namespace Game.BattleGrounds
|
|||||||
|
|
||||||
foreach (var (guid, _) in GetPlayers())
|
foreach (var (guid, _) in GetPlayers())
|
||||||
{
|
{
|
||||||
Player player = Global.ObjAccessor.FindPlayer(guid);
|
Player player = Global.ObjAccessor.GetPlayer(GetBgMap(), guid);
|
||||||
if (player != null)
|
if (player != null)
|
||||||
|
{
|
||||||
|
player.StartCriteria(CriteriaStartEvent.StartBattleground, GetBgMap().GetId());
|
||||||
player.AtStartOfEncounter(EncounterType.Battleground);
|
player.AtStartOfEncounter(EncounterType.Battleground);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove preparation
|
// Remove preparation
|
||||||
@@ -874,7 +877,7 @@ namespace Game.BattleGrounds
|
|||||||
player.SetBGTeam(0);
|
player.SetBGTeam(0);
|
||||||
|
|
||||||
// remove all criterias on bg leave
|
// remove all criterias on bg leave
|
||||||
player.ResetCriteria(CriteriaFailEvent.LeaveBattleground, GetMapId(), true);
|
player.FailCriteria(CriteriaFailEvent.LeaveBattleground, 0);
|
||||||
|
|
||||||
if (Transport)
|
if (Transport)
|
||||||
player.TeleportToBGEntryPoint();
|
player.TeleportToBGEntryPoint();
|
||||||
@@ -1041,10 +1044,6 @@ namespace Game.BattleGrounds
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset all map criterias on map enter
|
|
||||||
if (!isInBattleground)
|
|
||||||
player.ResetCriteria(CriteriaFailEvent.LeaveBattleground, GetMapId(), true);
|
|
||||||
|
|
||||||
// setup BG group membership
|
// setup BG group membership
|
||||||
PlayerAddedToBGCheckIfBGIsRunning(player);
|
PlayerAddedToBGCheckIfBGIsRunning(player);
|
||||||
AddOrSetPlayerToCorrectBgGroup(player, team);
|
AddOrSetPlayerToCorrectBgGroup(player, team);
|
||||||
|
|||||||
@@ -439,7 +439,7 @@ namespace Game.BattleGrounds.Zones
|
|||||||
//update world state to show correct flag carrier
|
//update world state to show correct flag carrier
|
||||||
UpdateFlagState(Team.Horde, WSGFlagState.OnPlayer);
|
UpdateFlagState(Team.Horde, WSGFlagState.OnPlayer);
|
||||||
player.CastSpell(player, WSGSpellId.SilverwingFlag, true);
|
player.CastSpell(player, WSGSpellId.SilverwingFlag, true);
|
||||||
player.StartCriteriaTimer(CriteriaStartEvent.BeSpellTarget, WSGSpellId.SilverwingFlagPicked);
|
//player.StartCriteria(CriteriaStartEvent.BeSpellTarget, WSGSpellId.SilverwingFlagPicked);
|
||||||
if (_flagState[1] == WSGFlagState.OnPlayer)
|
if (_flagState[1] == WSGFlagState.OnPlayer)
|
||||||
_bothFlagsKept = true;
|
_bothFlagsKept = true;
|
||||||
|
|
||||||
@@ -461,7 +461,7 @@ namespace Game.BattleGrounds.Zones
|
|||||||
//update world state to show correct flag carrier
|
//update world state to show correct flag carrier
|
||||||
UpdateFlagState(Team.Alliance, WSGFlagState.OnPlayer);
|
UpdateFlagState(Team.Alliance, WSGFlagState.OnPlayer);
|
||||||
player.CastSpell(player, WSGSpellId.WarsongFlag, true);
|
player.CastSpell(player, WSGSpellId.WarsongFlag, true);
|
||||||
player.StartCriteriaTimer(CriteriaStartEvent.BeSpellTarget, WSGSpellId.WarsongFlagPicked);
|
//player.StartCriteriaTimer(CriteriaStartEvent.BeSpellTarget, WSGSpellId.WarsongFlagPicked);
|
||||||
if (_flagState[0] == WSGFlagState.OnPlayer)
|
if (_flagState[0] == WSGFlagState.OnPlayer)
|
||||||
_bothFlagsKept = true;
|
_bothFlagsKept = true;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Game.Achievements;
|
|||||||
using Game.DataStorage;
|
using Game.DataStorage;
|
||||||
using Game.Guilds;
|
using Game.Guilds;
|
||||||
using Game.Scenarios;
|
using Game.Scenarios;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Game.Entities
|
namespace Game.Entities
|
||||||
@@ -36,20 +37,16 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
return m_achievementSys.HasAchieved(achievementId);
|
return m_achievementSys.HasAchieved(achievementId);
|
||||||
}
|
}
|
||||||
public void StartCriteriaTimer(CriteriaStartEvent startEvent, uint entry, uint timeLost = 0)
|
|
||||||
|
public void StartCriteria(CriteriaStartEvent startEvent, uint entry, TimeSpan timeLost = default)
|
||||||
{
|
{
|
||||||
m_achievementSys.StartCriteriaTimer(startEvent, entry, timeLost);
|
m_achievementSys.StartCriteria(startEvent, entry, timeLost);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveCriteriaTimer(CriteriaStartEvent startEvent, uint entry)
|
public void FailCriteria(CriteriaFailEvent failEvent, uint failAsset)
|
||||||
{
|
{
|
||||||
m_achievementSys.RemoveCriteriaTimer(startEvent, entry);
|
m_achievementSys.FailCriteria(failEvent, failAsset);
|
||||||
}
|
m_questObjectiveCriteriaMgr.FailCriteria(failEvent, failAsset);
|
||||||
|
|
||||||
public void ResetCriteria(CriteriaFailEvent failEvent, uint failAsset, bool evenIfCriteriaComplete = false)
|
|
||||||
{
|
|
||||||
m_achievementSys.ResetCriteria(failEvent, failAsset, evenIfCriteriaComplete);
|
|
||||||
m_questObjectiveCriteriaMgr.ResetCriteria(failEvent, failAsset, evenIfCriteriaComplete);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateCriteria(CriteriaType type, ulong miscValue1 = 0, ulong miscValue2 = 0, ulong miscValue3 = 0, WorldObject refe = null)
|
public void UpdateCriteria(CriteriaType type, ulong miscValue1 = 0, ulong miscValue2 = 0, ulong miscValue3 = 0, WorldObject refe = null)
|
||||||
|
|||||||
@@ -194,6 +194,8 @@ namespace Game.Entities
|
|||||||
|
|
||||||
if (_garrison != null)
|
if (_garrison != null)
|
||||||
_garrison.ResetFollowerActivationLimit();
|
_garrison.ResetFollowerActivationLimit();
|
||||||
|
|
||||||
|
FailCriteria(CriteriaFailEvent.DailyQuestsCleared, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetWeeklyQuestStatus()
|
public void ResetWeeklyQuestStatus()
|
||||||
@@ -837,7 +839,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
m_QuestStatusSave[questId] = QuestSaveType.Default;
|
m_QuestStatusSave[questId] = QuestSaveType.Default;
|
||||||
|
|
||||||
StartCriteriaTimer(CriteriaStartEvent.AcceptQuest, questId);
|
StartCriteria(CriteriaStartEvent.AcceptQuest, questId);
|
||||||
|
|
||||||
SendQuestUpdate(questId);
|
SendQuestUpdate(questId);
|
||||||
|
|
||||||
@@ -1146,6 +1148,7 @@ namespace Game.Entities
|
|||||||
SetDailyQuestStatus(questId);
|
SetDailyQuestStatus(questId);
|
||||||
if (quest.IsDaily())
|
if (quest.IsDaily())
|
||||||
{
|
{
|
||||||
|
StartCriteria(CriteriaStartEvent.CompleteDailyQuest, 0);
|
||||||
UpdateCriteria(CriteriaType.CompleteDailyQuest, questId);
|
UpdateCriteria(CriteriaType.CompleteDailyQuest, questId);
|
||||||
UpdateCriteria(CriteriaType.CompleteAnyDailyQuestPerDay, questId);
|
UpdateCriteria(CriteriaType.CompleteAnyDailyQuestPerDay, questId);
|
||||||
}
|
}
|
||||||
@@ -2393,7 +2396,7 @@ namespace Game.Entities
|
|||||||
real_entry = killed.GetEntry();
|
real_entry = killed.GetEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
StartCriteriaTimer(CriteriaStartEvent.KillNPC, real_entry); // MUST BE CALLED FIRST
|
StartCriteria(CriteriaStartEvent.KillNPC, real_entry); // MUST BE CALLED FIRST
|
||||||
UpdateCriteria(CriteriaType.KillCreature, real_entry, addKillCount, 0, killed);
|
UpdateCriteria(CriteriaType.KillCreature, real_entry, addKillCount, 0, killed);
|
||||||
|
|
||||||
UpdateQuestObjectiveProgress(QuestObjectiveType.Monster, (int)entry, 1, guid);
|
UpdateQuestObjectiveProgress(QuestObjectiveType.Monster, (int)entry, 1, guid);
|
||||||
@@ -2401,6 +2404,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public void KilledPlayerCredit(ObjectGuid victimGuid)
|
public void KilledPlayerCredit(ObjectGuid victimGuid)
|
||||||
{
|
{
|
||||||
|
StartCriteria(CriteriaStartEvent.KillPlayer, 0);
|
||||||
UpdateQuestObjectiveProgress(QuestObjectiveType.PlayerKills, 0, 1, victimGuid);
|
UpdateQuestObjectiveProgress(QuestObjectiveType.PlayerKills, 0, 1, victimGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -416,7 +416,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_achievementSys.UpdateTimedCriteria(diff);
|
m_achievementSys.UpdateTimedCriteria(TimeSpan.FromMilliseconds(diff));
|
||||||
|
|
||||||
if (HasUnitState(UnitState.MeleeAttacking) && !HasUnitState(UnitState.Casting | UnitState.Charging))
|
if (HasUnitState(UnitState.MeleeAttacking) && !HasUnitState(UnitState.Casting | UnitState.Charging))
|
||||||
{
|
{
|
||||||
@@ -662,7 +662,7 @@ namespace Game.Entities
|
|||||||
UpdateCriteria(CriteriaType.DieInInstance, 1);
|
UpdateCriteria(CriteriaType.DieInInstance, 1);
|
||||||
|
|
||||||
// reset all death criterias
|
// reset all death criterias
|
||||||
ResetCriteria(CriteriaFailEvent.Death, 0);
|
FailCriteria(CriteriaFailEvent.Death, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.SetDeathState(s);
|
base.SetDeathState(s);
|
||||||
@@ -5365,6 +5365,7 @@ namespace Game.Entities
|
|||||||
DB.Characters.CommitTransaction(trans);
|
DB.Characters.CommitTransaction(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StartCriteria(CriteriaStartEvent.ReachLevel, level);
|
||||||
UpdateCriteria(CriteriaType.ReachLevel);
|
UpdateCriteria(CriteriaType.ReachLevel);
|
||||||
UpdateCriteria(CriteriaType.ActivelyReachLevel, level);
|
UpdateCriteria(CriteriaType.ActivelyReachLevel, level);
|
||||||
|
|
||||||
|
|||||||
@@ -3754,8 +3754,12 @@ namespace Game.Entities
|
|||||||
|
|
||||||
Player player = ToPlayer();
|
Player player = ToPlayer();
|
||||||
if (player != null)
|
if (player != null)
|
||||||
|
{
|
||||||
if (Global.ConditionMgr.IsSpellUsedInSpellClickConditions(aurApp.GetBase().GetId()))
|
if (Global.ConditionMgr.IsSpellUsedInSpellClickConditions(aurApp.GetBase().GetId()))
|
||||||
player.UpdateVisibleGameobjectsOrSpellClicks();
|
player.UpdateVisibleGameobjectsOrSpellClicks();
|
||||||
|
|
||||||
|
player.FailCriteria(CriteriaFailEvent.LoseAura, aurApp.GetBase().GetId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void _UnapplyAura(AuraApplication aurApp, AuraRemoveMode removeMode)
|
public void _UnapplyAura(AuraApplication aurApp, AuraRemoveMode removeMode)
|
||||||
@@ -3970,8 +3974,14 @@ namespace Game.Entities
|
|||||||
|
|
||||||
Player player = ToPlayer();
|
Player player = ToPlayer();
|
||||||
if (player != null)
|
if (player != null)
|
||||||
|
{
|
||||||
if (Global.ConditionMgr.IsSpellUsedInSpellClickConditions(aurApp.GetBase().GetId()))
|
if (Global.ConditionMgr.IsSpellUsedInSpellClickConditions(aurApp.GetBase().GetId()))
|
||||||
player.UpdateVisibleGameobjectsOrSpellClicks();
|
player.UpdateVisibleGameobjectsOrSpellClicks();
|
||||||
|
|
||||||
|
player.FailCriteria(CriteriaFailEvent.GainAura, aurApp.GetBase().GetId());
|
||||||
|
player.StartCriteria(CriteriaStartEvent.GainAura, aurApp.GetBase().GetId());
|
||||||
|
player.UpdateCriteria(CriteriaType.GainAura, aurApp.GetBase().GetId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void _AddAura(UnitAura aura, Unit caster)
|
public void _AddAura(UnitAura aura, Unit caster)
|
||||||
@@ -4370,10 +4380,19 @@ namespace Game.Entities
|
|||||||
public void _RegisterAuraEffect(AuraEffect aurEff, bool apply)
|
public void _RegisterAuraEffect(AuraEffect aurEff, bool apply)
|
||||||
{
|
{
|
||||||
if (apply)
|
if (apply)
|
||||||
|
{
|
||||||
m_modAuras.Add(aurEff.GetAuraType(), aurEff);
|
m_modAuras.Add(aurEff.GetAuraType(), aurEff);
|
||||||
|
Player player = ToPlayer();
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
player.StartCriteria(CriteriaStartEvent.GainAuraEffect, (uint)aurEff.GetAuraType());
|
||||||
|
player.FailCriteria(CriteriaFailEvent.GainAuraEffect, (uint)aurEff.GetAuraType());
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_modAuras.Remove(aurEff.GetAuraType(), aurEff);
|
m_modAuras.Remove(aurEff.GetAuraType(), aurEff);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetTotalAuraModValue(UnitMods unitMod)
|
public float GetTotalAuraModValue(UnitMods unitMod)
|
||||||
{
|
{
|
||||||
if (unitMod >= UnitMods.End)
|
if (unitMod >= UnitMods.End)
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ namespace Game
|
|||||||
Map map = source.GetMap();
|
Map map = source.GetMap();
|
||||||
if (map.Instanceable())
|
if (map.Instanceable())
|
||||||
{
|
{
|
||||||
source.StartCriteriaTimer(CriteriaStartEvent.SendEvent, gameEventId);
|
source.FailCriteria(CriteriaFailEvent.SendEvent, gameEventId);
|
||||||
source.ResetCriteria(CriteriaFailEvent.SendEvent, gameEventId);
|
source.StartCriteria(CriteriaStartEvent.SendEvent, gameEventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
source.UpdateCriteria(CriteriaType.PlayerTriggerGameEvent, gameEventId, 0, 0, source);
|
source.UpdateCriteria(CriteriaType.PlayerTriggerGameEvent, gameEventId, 0, 0, source);
|
||||||
|
|||||||
@@ -476,6 +476,8 @@ namespace Game.Groups
|
|||||||
if (IsRaidGroup())
|
if (IsRaidGroup())
|
||||||
player.UpdateVisibleGameobjectsOrSpellClicks();
|
player.UpdateVisibleGameobjectsOrSpellClicks();
|
||||||
|
|
||||||
|
player.FailCriteria(CriteriaFailEvent.ModifyPartyStatus, 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
// Broadcast new player group member fields to rest of the group
|
// Broadcast new player group member fields to rest of the group
|
||||||
UpdateData groupData = new(player.GetMapId());
|
UpdateData groupData = new(player.GetMapId());
|
||||||
@@ -544,6 +546,9 @@ namespace Game.Groups
|
|||||||
if (IsLFGGroup() && method == RemoveMethod.Kick)
|
if (IsLFGGroup() && method == RemoveMethod.Kick)
|
||||||
return m_memberSlots.Count != 0;
|
return m_memberSlots.Count != 0;
|
||||||
|
|
||||||
|
if (player != null)
|
||||||
|
player.FailCriteria(CriteriaFailEvent.ModifyPartyStatus, 0);
|
||||||
|
|
||||||
// remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG/BF allow 1 member group)
|
// remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG/BF allow 1 member group)
|
||||||
if (GetMembersCount() > ((IsBGGroup() || IsLFGGroup() || IsBFGroup()) ? 1 : 2))
|
if (GetMembersCount() > ((IsBGGroup() || IsLFGGroup() || IsBFGroup()) ? 1 : 2))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -437,7 +437,6 @@ namespace Game
|
|||||||
GetPlayer().TakeQuestSourceItem(questId, true); // remove quest src item from player
|
GetPlayer().TakeQuestSourceItem(questId, true); // remove quest src item from player
|
||||||
GetPlayer().AbandonQuest(questId); // remove all quest items player received before abandoning quest. Note, this does not remove normal drop items that happen to be quest requirements.
|
GetPlayer().AbandonQuest(questId); // remove all quest items player received before abandoning quest. Note, this does not remove normal drop items that happen to be quest requirements.
|
||||||
GetPlayer().RemoveActiveQuest(questId);
|
GetPlayer().RemoveActiveQuest(questId);
|
||||||
GetPlayer().RemoveCriteriaTimer(CriteriaStartEvent.AcceptQuest, questId);
|
|
||||||
|
|
||||||
Log.outInfo(LogFilter.Network, "Player {0} abandoned quest {1}", GetPlayer().GetGUID().ToString(), questId);
|
Log.outInfo(LogFilter.Network, "Player {0} abandoned quest {1}", GetPlayer().GetGUID().ToString(), questId);
|
||||||
|
|
||||||
|
|||||||
@@ -150,36 +150,6 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetCriteria(CriteriaFailEvent failEvent, uint failAsset, bool evenIfCriteriaComplete)
|
|
||||||
{
|
|
||||||
Log.outDebug(LogFilter.Player, $"QuestObjectiveCriteriaMgr.ResetCriteria({failEvent}, {failAsset}, {evenIfCriteriaComplete})");
|
|
||||||
|
|
||||||
// disable for gamemasters with GM-mode enabled
|
|
||||||
if (_owner.IsGameMaster())
|
|
||||||
return;
|
|
||||||
|
|
||||||
var playerCriteriaList = Global.CriteriaMgr.GetCriteriaByFailEvent(failEvent, (int)failAsset);
|
|
||||||
foreach (Criteria playerCriteria in playerCriteriaList)
|
|
||||||
{
|
|
||||||
var trees = Global.CriteriaMgr.GetCriteriaTreesByCriteria(playerCriteria.Id);
|
|
||||||
bool allComplete = true;
|
|
||||||
foreach (CriteriaTree tree in trees)
|
|
||||||
{
|
|
||||||
// don't update already completed criteria if not forced
|
|
||||||
if (!(IsCompletedCriteriaTree(tree) && !evenIfCriteriaComplete))
|
|
||||||
{
|
|
||||||
allComplete = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allComplete)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
RemoveCriteriaProgress(playerCriteria);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetCriteriaTree(uint criteriaTreeId)
|
public void ResetCriteriaTree(uint criteriaTreeId)
|
||||||
{
|
{
|
||||||
CriteriaTree tree = Global.CriteriaMgr.GetCriteriaTree(criteriaTreeId);
|
CriteriaTree tree = Global.CriteriaMgr.GetCriteriaTree(criteriaTreeId);
|
||||||
|
|||||||
@@ -97,7 +97,15 @@ namespace Game.Scenarios
|
|||||||
{
|
{
|
||||||
_currentstep = step;
|
_currentstep = step;
|
||||||
if (step != null)
|
if (step != null)
|
||||||
|
{
|
||||||
SetStepState(step, ScenarioStepState.InProgress);
|
SetStepState(step, ScenarioStepState.InProgress);
|
||||||
|
foreach (ObjectGuid guid in _players)
|
||||||
|
{
|
||||||
|
Player player = Global.ObjAccessor.GetPlayer(_map, guid);
|
||||||
|
if (player != null)
|
||||||
|
player.StartCriteria(CriteriaStartEvent.BeginScenarioStep, step.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ScenarioState scenarioState = new();
|
ScenarioState scenarioState = new();
|
||||||
BuildScenarioState(scenarioState);
|
BuildScenarioState(scenarioState);
|
||||||
|
|||||||
@@ -2164,17 +2164,14 @@ namespace Game.Spells
|
|||||||
Player player = unit.ToPlayer();
|
Player player = unit.ToPlayer();
|
||||||
if (player != null)
|
if (player != null)
|
||||||
{
|
{
|
||||||
player.StartCriteriaTimer(CriteriaStartEvent.BeSpellTarget, m_spellInfo.Id);
|
player.FailCriteria(CriteriaFailEvent.BeSpellTarget, m_spellInfo.Id);
|
||||||
|
player.StartCriteria(CriteriaStartEvent.BeSpellTarget, m_spellInfo.Id);
|
||||||
player.UpdateCriteria(CriteriaType.BeSpellTarget, m_spellInfo.Id, 0, 0, m_caster);
|
player.UpdateCriteria(CriteriaType.BeSpellTarget, m_spellInfo.Id, 0, 0, m_caster);
|
||||||
player.UpdateCriteria(CriteriaType.GainAura, m_spellInfo.Id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Player casterPlayer = m_caster.ToPlayer();
|
Player casterPlayer = m_caster.ToPlayer();
|
||||||
if (casterPlayer != null)
|
if (casterPlayer != null)
|
||||||
{
|
|
||||||
casterPlayer.StartCriteriaTimer(CriteriaStartEvent.CastSpell, m_spellInfo.Id);
|
|
||||||
casterPlayer.UpdateCriteria(CriteriaType.LandTargetedSpellOnTarget, m_spellInfo.Id, 0, 0, unit);
|
casterPlayer.UpdateCriteria(CriteriaType.LandTargetedSpellOnTarget, m_spellInfo.Id, 0, 0, unit);
|
||||||
}
|
|
||||||
|
|
||||||
if (m_caster != unit)
|
if (m_caster != unit)
|
||||||
{
|
{
|
||||||
@@ -2915,10 +2912,12 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
if (!Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreCastItem) && m_CastItem != null)
|
if (!Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreCastItem) && m_CastItem != null)
|
||||||
{
|
{
|
||||||
player.StartCriteriaTimer(CriteriaStartEvent.UseItem, m_CastItem.GetEntry());
|
player.StartCriteria(CriteriaStartEvent.UseItem, m_CastItem.GetEntry());
|
||||||
player.UpdateCriteria(CriteriaType.UseItem, m_CastItem.GetEntry());
|
player.UpdateCriteria(CriteriaType.UseItem, m_CastItem.GetEntry());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.FailCriteria(CriteriaFailEvent.CastSpell, m_spellInfo.Id);
|
||||||
|
player.StartCriteria(CriteriaStartEvent.CastSpell, m_spellInfo.Id);
|
||||||
player.UpdateCriteria(CriteriaType.CastSpell, m_spellInfo.Id);
|
player.UpdateCriteria(CriteriaType.CastSpell, m_spellInfo.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user