Core/Conditions: Added conditions for automatic learning spells with SkillLineAbility::AcquireMethod = 4
Port From (https://github.com/TrinityCore/TrinityCore/commit/7eaa695581589e8cb9a277f9c13ad0e3daf669a7)
This commit is contained in:
@@ -105,6 +105,7 @@ namespace Framework.Constants
|
|||||||
ObjectIdVisibility = 32,
|
ObjectIdVisibility = 32,
|
||||||
SpawnGroup = 33,
|
SpawnGroup = 33,
|
||||||
PlayerCondition = 34,
|
PlayerCondition = 34,
|
||||||
|
SkillLineAbility = 35,
|
||||||
|
|
||||||
MaxDbAllowed,
|
MaxDbAllowed,
|
||||||
ReferenceCondition = MaxDbAllowed,
|
ReferenceCondition = MaxDbAllowed,
|
||||||
|
|||||||
@@ -1156,10 +1156,14 @@ namespace Game.Achievements
|
|||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DB2HotfixGenerator<AchievementRecord> hotfixes = new(CliDB.AchievementStorage);
|
||||||
|
|
||||||
// Once Bitten, Twice Shy (10 player) - Icecrown Citadel
|
// Once Bitten, Twice Shy (10 player) - Icecrown Citadel
|
||||||
AchievementRecord achievement1 = CliDB.AchievementStorage.LookupByKey(4539);
|
// Correct map requirement (currently has Ulduar); 6.0.3 note - it STILL has ulduar requirement
|
||||||
if (achievement1 != null)
|
hotfixes.ApplyHotfix(4539, achievement =>
|
||||||
achievement1.InstanceID = 631; // Correct map requirement (currently has Ulduar); 6.0.3 note - it STILL has ulduar requirement
|
{
|
||||||
|
achievement.InstanceID = 631;
|
||||||
|
});
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} achievement references in {1} ms.", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} achievement references in {1} ms.", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -739,30 +739,22 @@ namespace Game.Conditions
|
|||||||
|
|
||||||
public class ConditionSourceInfo
|
public class ConditionSourceInfo
|
||||||
{
|
{
|
||||||
|
public WorldObject[] mConditionTargets = new WorldObject[SharedConst.MaxConditionTargets]; // an array of targets available for conditions
|
||||||
|
public Map mConditionMap;
|
||||||
|
public Condition mLastFailedCondition;
|
||||||
|
|
||||||
public ConditionSourceInfo(WorldObject target0, WorldObject target1 = null, WorldObject target2 = null)
|
public ConditionSourceInfo(WorldObject target0, WorldObject target1 = null, WorldObject target2 = null)
|
||||||
{
|
{
|
||||||
mConditionTargets[0] = target0;
|
mConditionTargets = [target0, target1, target2];
|
||||||
mConditionTargets[1] = target1;
|
|
||||||
mConditionTargets[2] = target2;
|
var target = target0 ?? target1 ?? target2;
|
||||||
if (target0 != null)
|
if (target != null)
|
||||||
mConditionMap = target0.GetMap();
|
mConditionMap = target.GetMap();
|
||||||
else if (target1 != null)
|
|
||||||
mConditionMap = target1.GetMap();
|
|
||||||
else if (target2 != null)
|
|
||||||
mConditionMap = target2.GetMap();
|
|
||||||
else
|
|
||||||
mConditionMap = null;
|
|
||||||
mLastFailedCondition = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConditionSourceInfo(Map map)
|
public ConditionSourceInfo(Map map)
|
||||||
{
|
{
|
||||||
mConditionMap = map;
|
mConditionMap = map;
|
||||||
mLastFailedCondition = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public WorldObject[] mConditionTargets = new WorldObject[SharedConst.MaxConditionTargets]; // an array of targets available for conditions
|
|
||||||
public Map mConditionMap;
|
|
||||||
public Condition mLastFailedCondition;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1120,6 +1120,21 @@ namespace Game
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ConditionSourceType.SkillLineAbility:
|
||||||
|
{
|
||||||
|
var skillLineAbility = CliDB.SkillLineAbilityStorage.LookupByKey(cond.SourceEntry);
|
||||||
|
if (skillLineAbility == null)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"{cond} SourceEntry in `condition` table, does not exist in SkillLineAbility.db2, ignoring.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (skillLineAbility.AcquireMethod != SkillLineAbilityAcquireMethod.LearnedOrAutomaticCharLevel)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"{cond} in SkillLineAbility.db2 does not have AcquireMethod = {SkillLineAbilityAcquireMethod.LearnedOrAutomaticCharLevel} (LearnedOrAutomaticCharLevel), ignoring.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ConditionSourceType.GossipMenu:
|
case ConditionSourceType.GossipMenu:
|
||||||
case ConditionSourceType.GossipMenuOption:
|
case ConditionSourceType.GossipMenuOption:
|
||||||
case ConditionSourceType.SmartEvent:
|
case ConditionSourceType.SmartEvent:
|
||||||
@@ -2712,8 +2727,8 @@ namespace Game
|
|||||||
}
|
}
|
||||||
case WorldStateExpressionValueType.WorldState:
|
case WorldStateExpressionValueType.WorldState:
|
||||||
{
|
{
|
||||||
uint worldStateId = buffer.ReadUInt32();
|
int worldStateId = buffer.ReadInt32();
|
||||||
value = Global.WorldStateMgr.GetValue((int)worldStateId, map);
|
value = Global.WorldStateMgr.GetValue(worldStateId, map);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WorldStateExpressionValueType.Function:
|
case WorldStateExpressionValueType.Function:
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||||
|
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Game.DataStorage
|
||||||
|
{
|
||||||
|
class DB2HotfixGenerator<T> where T : new()
|
||||||
|
{
|
||||||
|
DB6Storage<T> _storage;
|
||||||
|
uint _count;
|
||||||
|
|
||||||
|
public DB2HotfixGenerator(DB6Storage<T> storage)
|
||||||
|
{
|
||||||
|
_storage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyHotfix(uint id, Action<T> fixer, bool notifyClient = false) { ApplyHotfix([id, 1], fixer, notifyClient); }
|
||||||
|
|
||||||
|
public uint GetAppliedHotfixesCount() { return _count; }
|
||||||
|
|
||||||
|
void ApplyHotfix(Span<uint> ids, Action<T> fixer, bool notifyClient)
|
||||||
|
{
|
||||||
|
foreach (uint id in ids)
|
||||||
|
{
|
||||||
|
T entry = _storage.LookupByKey(id);
|
||||||
|
if (entry == null)
|
||||||
|
{
|
||||||
|
LogMissingRecord(_storage.GetName(), id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixer(entry);
|
||||||
|
++_count;
|
||||||
|
|
||||||
|
if (notifyClient)
|
||||||
|
AddClientHotfix(_storage.GetTableHash(), id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogMissingRecord(string storageName, uint recordId)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Server, $"Hotfix specified for {storageName} row id {recordId} which does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddClientHotfix(uint tableHash, uint recordId)
|
||||||
|
{
|
||||||
|
Global.DB2Mgr.InsertNewHotfix(tableHash, recordId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -801,6 +801,7 @@ namespace Game.DataStorage
|
|||||||
push.Records.Add(hotfixRecord);
|
push.Records.Add(hotfixRecord);
|
||||||
push.AvailableLocalesMask |= hotfixRecord.AvailableLocalesMask;
|
push.AvailableLocalesMask |= hotfixRecord.AvailableLocalesMask;
|
||||||
|
|
||||||
|
_maxHotfixId = Math.Max(_maxHotfixId, id);
|
||||||
deletedRecords[(tableHash, recordId)] = status == HotfixRecord.Status.RecordRemoved;
|
deletedRecords[(tableHash, recordId)] = status == HotfixRecord.Status.RecordRemoved;
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
@@ -960,6 +961,20 @@ namespace Game.DataStorage
|
|||||||
return AnimationDataStorage.GetNumRows();
|
return AnimationDataStorage.GetNumRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InsertNewHotfix(uint tableHash, uint recordId)
|
||||||
|
{
|
||||||
|
HotfixRecord hotfixRecord = new();
|
||||||
|
hotfixRecord.TableHash = tableHash;
|
||||||
|
hotfixRecord.RecordID = (int)recordId;
|
||||||
|
hotfixRecord.ID.PushID = (int)++_maxHotfixId;
|
||||||
|
hotfixRecord.ID.UniqueID = RandomHelper.Rand32();
|
||||||
|
hotfixRecord.AvailableLocalesMask = 0xDFF;
|
||||||
|
|
||||||
|
HotfixPush push = _hotfixData[hotfixRecord.ID.PushID];
|
||||||
|
push.Records.Add(hotfixRecord);
|
||||||
|
push.AvailableLocalesMask |= hotfixRecord.AvailableLocalesMask;
|
||||||
|
}
|
||||||
|
|
||||||
public List<uint> GetAreasForGroup(uint areaGroupId)
|
public List<uint> GetAreasForGroup(uint areaGroupId)
|
||||||
{
|
{
|
||||||
return _areaGroupMembers.LookupByKey(areaGroupId);
|
return _areaGroupMembers.LookupByKey(areaGroupId);
|
||||||
@@ -2479,6 +2494,8 @@ namespace Game.DataStorage
|
|||||||
public static byte[] HordeTaxiNodesMask;
|
public static byte[] HordeTaxiNodesMask;
|
||||||
public static byte[] AllianceTaxiNodesMask;
|
public static byte[] AllianceTaxiNodesMask;
|
||||||
public static Dictionary<uint, TaxiPathNodeRecord[]> TaxiPathNodesByPath = new();
|
public static Dictionary<uint, TaxiPathNodeRecord[]> TaxiPathNodesByPath = new();
|
||||||
|
|
||||||
|
int _maxHotfixId;
|
||||||
}
|
}
|
||||||
|
|
||||||
class UiMapBounds
|
class UiMapBounds
|
||||||
|
|||||||
@@ -1664,8 +1664,10 @@ namespace Game.Entities
|
|||||||
case SkillLineAbilityAcquireMethod.AutomaticCharLevel:
|
case SkillLineAbilityAcquireMethod.AutomaticCharLevel:
|
||||||
break;
|
break;
|
||||||
case SkillLineAbilityAcquireMethod.LearnedOrAutomaticCharLevel:
|
case SkillLineAbilityAcquireMethod.LearnedOrAutomaticCharLevel:
|
||||||
if (!ability.HasFlag(SkillLineAbilityFlags.CanFallbackToLearnedOnSkillLearn) ||
|
// Treat as AutomaticCharLevel when conditions are met, otherwise treat it as Learned (trainer or quest)
|
||||||
!spellInfo.MeetsFutureSpellPlayerCondition(this))
|
if (spellInfo.ShowFutureSpellPlayerConditionID != 0 && !ConditionManager.IsPlayerMeetingCondition(this, spellInfo.ShowFutureSpellPlayerConditionID))
|
||||||
|
continue;
|
||||||
|
if (!Global.ConditionMgr.IsObjectMeetingNotGroupedConditions(ConditionSourceType.SkillLineAbility, ability.Id, this))
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -1655,10 +1655,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
mSkillLineAbilityMap.Clear();
|
mSkillLineAbilityMap.Clear();
|
||||||
|
|
||||||
foreach (var skill in CliDB.SkillLineAbilityStorage.Values)
|
foreach (var (_, skillLineAbility) in CliDB.SkillLineAbilityStorage)
|
||||||
mSkillLineAbilityMap.Add(skill.Spell, skill);
|
mSkillLineAbilityMap.Add(skillLineAbility.Spell, skillLineAbility);
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} SkillLineAbility MultiMap Data in {1} ms", mSkillLineAbilityMap.Count, Time.GetMSTimeDiffToNow(oldMSTime));
|
Log.outInfo(LogFilter.ServerLoading, $"Loaded {mSkillLineAbilityMap.Count} SkillLineAbility MultiMap Data in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadSpellPetAuras()
|
public void LoadSpellPetAuras()
|
||||||
@@ -4515,15 +4515,19 @@ namespace Game.Entities
|
|||||||
spellInfo.MaxAffectedTargets = 1;
|
spellInfo.MaxAffectedTargets = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SummonPropertiesRecord properties = CliDB.SummonPropertiesStorage.LookupByKey(121);
|
DB2HotfixGenerator<SummonPropertiesRecord> summonProperties = new(CliDB.SummonPropertiesStorage);
|
||||||
if (properties != null)
|
summonProperties.ApplyHotfix(121, properties =>
|
||||||
|
{
|
||||||
properties.Title = SummonTitle.Totem;
|
properties.Title = SummonTitle.Totem;
|
||||||
properties = CliDB.SummonPropertiesStorage.LookupByKey(647); // 52893
|
});
|
||||||
if (properties != null)
|
summonProperties.ApplyHotfix(647, properties => // 52893
|
||||||
|
{
|
||||||
properties.Title = SummonTitle.Totem;
|
properties.Title = SummonTitle.Totem;
|
||||||
properties = CliDB.SummonPropertiesStorage.LookupByKey(628);
|
});
|
||||||
if (properties != null) // Hungry Plaguehound
|
summonProperties.ApplyHotfix(628, properties => // Hungry Plaguehound
|
||||||
|
{
|
||||||
properties.Control = SummonCategory.Pet;
|
properties.Control = SummonCategory.Pet;
|
||||||
|
});
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded SpellInfo corrections in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded SpellInfo corrections in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user