Core/Scripts: Added script hook to execute actions after completing an achievement
Port From (https://github.com/TrinityCore/TrinityCore/commit/27cba3f52309dad5be964fec11d80cd8cad128cf)
This commit is contained in:
@@ -541,6 +541,8 @@ namespace Game.Achievements
|
||||
UpdateCriteria(CriteriaType.EarnAchievement, achievement.Id, 0, 0, null, referencePlayer);
|
||||
UpdateCriteria(CriteriaType.EarnAchievementPoints, achievement.Points, 0, 0, null, referencePlayer);
|
||||
|
||||
Global.ScriptMgr.OnAchievementCompleted(referencePlayer, achievement);
|
||||
|
||||
// reward items and titles if any
|
||||
AchievementReward reward = Global.AchievementMgr.GetAchievementReward(achievement);
|
||||
|
||||
@@ -1021,6 +1023,8 @@ namespace Game.Achievements
|
||||
|
||||
UpdateCriteria(CriteriaType.EarnAchievement, achievement.Id, 0, 0, null, referencePlayer);
|
||||
UpdateCriteria(CriteriaType.EarnAchievementPoints, achievement.Points, 0, 0, null, referencePlayer);
|
||||
|
||||
Global.ScriptMgr.OnAchievementCompleted(referencePlayer, achievement);
|
||||
}
|
||||
|
||||
public override void SendCriteriaUpdate(Criteria entry, CriteriaProgress progress, TimeSpan timeElapsed, bool timedCompleted)
|
||||
@@ -1095,6 +1099,7 @@ namespace Game.Achievements
|
||||
|
||||
Dictionary<uint, AchievementReward> _achievementRewards = new();
|
||||
Dictionary<uint, AchievementRewardLocale> _achievementRewardLocales = new();
|
||||
Dictionary<uint, uint> _achievementScripts = new();
|
||||
|
||||
AchievementGlobalMgr() { }
|
||||
|
||||
@@ -1171,6 +1176,37 @@ namespace Game.Achievements
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} achievement references in {1} ms.", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
public void LoadAchievementScripts()
|
||||
{
|
||||
uint oldMSTime = Time.GetMSTime();
|
||||
|
||||
_achievementScripts.Clear(); // need for reload case
|
||||
|
||||
SQLResult result = DB.World.Query("SELECT AchievementId, ScriptName FROM achievement_scripts");
|
||||
if (result.IsEmpty())
|
||||
{
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 achievement scripts. DB table `achievement_scripts` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
uint achievementId = result.Read<uint>(0);
|
||||
string scriptName = result.Read<string>(1);
|
||||
|
||||
AchievementRecord achievement = CliDB.AchievementStorage.LookupByKey(achievementId);
|
||||
if (achievement == null)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, $"Table `achievement_scripts` contains non-existing Achievement (ID: {achievementId}), skipped.");
|
||||
continue;
|
||||
}
|
||||
_achievementScripts[achievementId] = Global.ObjectMgr.GetScriptId(scriptName);
|
||||
}
|
||||
while (result.NextRow());
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, $"Loaded {_achievementScripts.Count} achievement scripts in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||
}
|
||||
|
||||
public void LoadCompletedAchievements()
|
||||
{
|
||||
uint oldMSTime = Time.GetMSTime();
|
||||
@@ -1353,7 +1389,7 @@ namespace Game.Achievements
|
||||
|
||||
AchievementRewardLocale data = new();
|
||||
Locale locale = localeName.ToEnum<Locale>();
|
||||
if (!SharedConst.IsValidLocale(locale) || locale == Locale.enUS)
|
||||
if (!SharedConst.IsValidLocale(locale) || locale == Locale.enUS)
|
||||
continue;
|
||||
|
||||
ObjectManager.AddLocaleString(result.Read<string>(2), locale, data.Subject);
|
||||
@@ -1365,6 +1401,11 @@ namespace Game.Achievements
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} achievement reward locale strings in {1} ms.", _achievementRewardLocales.Count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
public uint GetAchievementScriptId(uint achievementId)
|
||||
{
|
||||
return _achievementScripts.LookupByKey(achievementId);
|
||||
}
|
||||
}
|
||||
|
||||
public class AchievementReward
|
||||
|
||||
@@ -586,6 +586,19 @@ namespace Game.Scripting
|
||||
public virtual void OnUpdate(Transport obj, uint diff) { }
|
||||
}
|
||||
|
||||
public class AchievementScript : ScriptObject
|
||||
{
|
||||
public AchievementScript(string name) : base(name)
|
||||
{
|
||||
Global.ScriptMgr.AddScript(this);
|
||||
}
|
||||
|
||||
public override bool IsDatabaseBound() { return true; }
|
||||
|
||||
// Called when an achievement is completed.
|
||||
public virtual void OnCompleted(Player player, AchievementRecord achievement) { }
|
||||
}
|
||||
|
||||
public class AchievementCriteriaScript : ScriptObject
|
||||
{
|
||||
public AchievementCriteriaScript(string name) : base(name)
|
||||
@@ -593,7 +606,7 @@ namespace Game.Scripting
|
||||
Global.ScriptMgr.AddScript(this);
|
||||
}
|
||||
|
||||
public override bool IsDatabaseBound() { return false; }
|
||||
public override bool IsDatabaseBound() { return true; }
|
||||
|
||||
// Called when an additional criteria is checked.
|
||||
public virtual bool OnCheck(Player source, Unit target) { return false; }
|
||||
|
||||
@@ -866,6 +866,15 @@ namespace Game.Scripting
|
||||
RunScript<TransportScript>(p => p.OnRelocate(transport, waypointId, mapId, x, y, z), transport.GetScriptId());
|
||||
}
|
||||
|
||||
// Achievement
|
||||
public void OnAchievementCompleted(Player player, AchievementRecord achievement)
|
||||
{
|
||||
Cypher.Assert(player != null);
|
||||
Cypher.Assert(achievement != null);
|
||||
|
||||
RunScript<AchievementScript>(p => p.OnCompleted(player, achievement), Global.AchievementMgr.GetAchievementScriptId(achievement.Id));
|
||||
}
|
||||
|
||||
// AchievementCriteriaScript
|
||||
public bool OnCriteriaCheck(uint ScriptId, Player source, Unit target)
|
||||
{
|
||||
|
||||
@@ -818,6 +818,8 @@ namespace Game
|
||||
Global.CriteriaMgr.LoadCriteriaData();
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loading Achievements...");
|
||||
Global.AchievementMgr.LoadAchievementReferenceList();
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loading Achievements Scripts...");
|
||||
Global.AchievementMgr.LoadAchievementScripts();
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loading Achievement Rewards...");
|
||||
Global.AchievementMgr.LoadRewards();
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loading Achievement Reward Locales...");
|
||||
|
||||
@@ -20,6 +20,7 @@ using Game.BattleGrounds;
|
||||
using Game.BattleGrounds.Zones;
|
||||
using Game.Entities;
|
||||
using Game.Scripting;
|
||||
using Game.DataStorage;
|
||||
|
||||
namespace Scripts.World.Achievements
|
||||
{
|
||||
@@ -43,7 +44,7 @@ namespace Scripts.World.Achievements
|
||||
}
|
||||
|
||||
struct VehicleIds
|
||||
{
|
||||
{
|
||||
//BgSA Artillery
|
||||
public const uint AntiPersonnalCannon = 27894;
|
||||
}
|
||||
@@ -310,4 +311,27 @@ namespace Scripts.World.Achievements
|
||||
return target && player.IsHonorOrXPTarget(target);
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 7433 - Newbie
|
||||
class achievement_newbie : AchievementScript
|
||||
{
|
||||
public achievement_newbie() : base("achievement_newbie") { }
|
||||
|
||||
public override void OnCompleted(Player player, AchievementRecord achievement)
|
||||
{
|
||||
player.GetSession().GetBattlePetMgr().UnlockSlot(BattlePetSlots.Slot1);
|
||||
// TODO: Unlock trap
|
||||
}
|
||||
}
|
||||
|
||||
[Script] // 6566 - Just a Pup
|
||||
class achievement_just_a_pup : AchievementScript
|
||||
{
|
||||
public achievement_just_a_pup() : base("achievement_just_a_pup") { }
|
||||
|
||||
public override void OnCompleted(Player player, AchievementRecord achievement)
|
||||
{
|
||||
player.GetSession().GetBattlePetMgr().UnlockSlot(BattlePetSlots.Slot2);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user