Core/Conditions: Refactor ConditionMgr internals to get rid of separate containers for some condition source types
Port From (https://github.com/TrinityCore/TrinityCore/commit/0b5406dd882c6d96bc1be6fd0a78375c3b316415)
This commit is contained in:
@@ -102,6 +102,9 @@ namespace Framework.Constants
|
|||||||
TrainerSpell = 31,
|
TrainerSpell = 31,
|
||||||
ObjectIdVisibility = 32,
|
ObjectIdVisibility = 32,
|
||||||
SpawnGroup = 33,
|
SpawnGroup = 33,
|
||||||
|
|
||||||
|
MaxDbAllowed,
|
||||||
|
ReferenceCondition = MaxDbAllowed,
|
||||||
Max
|
Max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ namespace Game.Chat
|
|||||||
{
|
{
|
||||||
handler.SendSysMessage(CypherStrings.CommandNpcShowlootLabel, "Standard items", loot.items.Count);
|
handler.SendSysMessage(CypherStrings.CommandNpcShowlootLabel, "Standard items", loot.items.Count);
|
||||||
foreach (LootItem item in loot.items)
|
foreach (LootItem item in loot.items)
|
||||||
if (!item.is_looted && !item.freeforall && item.conditions.Empty())
|
if (!item.is_looted && !item.freeforall && item.conditions.IsEmpty())
|
||||||
_ShowLootEntry(handler, item.itemid, item.count);
|
_ShowLootEntry(handler, item.itemid, item.count);
|
||||||
|
|
||||||
if (!loot.GetPlayerFFAItems().Empty())
|
if (!loot.GetPlayerFFAItems().Empty())
|
||||||
|
|||||||
@@ -619,8 +619,10 @@ namespace Game.Conditions
|
|||||||
{
|
{
|
||||||
StringBuilder ss = new();
|
StringBuilder ss = new();
|
||||||
ss.AppendFormat("[Condition SourceType: {0}", SourceType);
|
ss.AppendFormat("[Condition SourceType: {0}", SourceType);
|
||||||
if (SourceType < ConditionSourceType.Max)
|
if (SourceType < ConditionSourceType.MaxDbAllowed)
|
||||||
ss.AppendFormat(" ({0})", Global.ConditionMgr.StaticSourceTypeData[(int)SourceType]);
|
ss.AppendFormat(" ({0})", Global.ConditionMgr.StaticSourceTypeData[(int)SourceType]);
|
||||||
|
else if (SourceType == ConditionSourceType.ReferenceCondition)
|
||||||
|
ss.Append(" (Reference)");
|
||||||
else
|
else
|
||||||
ss.Append(" (Unknown)");
|
ss.Append(" (Unknown)");
|
||||||
if (Global.ConditionMgr.CanHaveSourceGroupSet(SourceType))
|
if (Global.ConditionMgr.CanHaveSourceGroupSet(SourceType))
|
||||||
@@ -659,6 +661,52 @@ namespace Game.Conditions
|
|||||||
public bool NegativeCondition;
|
public bool NegativeCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct ConditionId
|
||||||
|
{
|
||||||
|
public uint SourceGroup;
|
||||||
|
public int SourceEntry;
|
||||||
|
public uint SourceId;
|
||||||
|
|
||||||
|
public ConditionId(uint sourceGroup, int sourceEntry, uint sourceId)
|
||||||
|
{
|
||||||
|
SourceGroup = sourceGroup;
|
||||||
|
SourceEntry = sourceEntry;
|
||||||
|
SourceId = sourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return SourceGroup.GetHashCode() ^ SourceEntry.GetHashCode() ^ SourceId.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is ConditionId)
|
||||||
|
return (ConditionId)obj == this;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(ConditionId left, ConditionId right)
|
||||||
|
{
|
||||||
|
if (left.SourceGroup != right.SourceGroup)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (left.SourceEntry != right.SourceEntry)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (left.SourceId != right.SourceId)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(ConditionId left, ConditionId right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class ConditionSourceInfo
|
public class ConditionSourceInfo
|
||||||
{
|
{
|
||||||
public ConditionSourceInfo(WorldObject target0, WorldObject target1 = null, WorldObject target2 = null)
|
public ConditionSourceInfo(WorldObject target0, WorldObject target1 = null, WorldObject target2 = null)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace Game
|
|||||||
|
|
||||||
if (i.ReferenceId != 0) // handle reference
|
if (i.ReferenceId != 0) // handle reference
|
||||||
{
|
{
|
||||||
var refe = conditionReferenceStorage.LookupByKey(i.ReferenceId);
|
var refe = ConditionStorage[ConditionSourceType.ReferenceCondition].LookupByKey(new ConditionId(i.ReferenceId, 0, 0));
|
||||||
Cypher.Assert(refe.Empty(), "ConditionMgr.GetSearcherTypeMaskForConditionList - incorrect reference");
|
Cypher.Assert(refe.Empty(), "ConditionMgr.GetSearcherTypeMaskForConditionList - incorrect reference");
|
||||||
elseGroupSearcherTypeMasks[i.ElseGroup] &= GetSearcherTypeMaskForConditionList(refe);
|
elseGroupSearcherTypeMasks[i.ElseGroup] &= GetSearcherTypeMaskForConditionList(refe);
|
||||||
}
|
}
|
||||||
@@ -71,15 +71,13 @@ namespace Game
|
|||||||
if (condition.IsLoaded())
|
if (condition.IsLoaded())
|
||||||
{
|
{
|
||||||
//! Find ElseGroup in ElseGroupStore
|
//! Find ElseGroup in ElseGroupStore
|
||||||
//! If not found, add an entry in the store and set to true (placeholder)
|
var added = elseGroupStore.TryAdd(condition.ElseGroup, true);
|
||||||
if (!elseGroupStore.ContainsKey(condition.ElseGroup))
|
if (!added) //! If another condition in this group was unmatched before this, don't bother checking (the group is false anyway)
|
||||||
elseGroupStore[condition.ElseGroup] = true;
|
|
||||||
else if (!elseGroupStore[condition.ElseGroup]) //! If another condition in this group was unmatched before this, don't bother checking (the group is false anyway)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (condition.ReferenceId != 0)//handle reference
|
if (condition.ReferenceId != 0)//handle reference
|
||||||
{
|
{
|
||||||
var refe = conditionReferenceStorage.LookupByKey(condition.ReferenceId);
|
var refe = ConditionStorage[ConditionSourceType.ReferenceCondition].LookupByKey(new ConditionId(condition.ReferenceId, 0, 0));
|
||||||
if (!refe.Empty())
|
if (!refe.Empty())
|
||||||
{
|
{
|
||||||
if (!IsObjectMeetToConditionList(sourceInfo, refe))
|
if (!IsObjectMeetToConditionList(sourceInfo, refe))
|
||||||
@@ -152,7 +150,8 @@ namespace Game
|
|||||||
sourceType == ConditionSourceType.Graveyard ||
|
sourceType == ConditionSourceType.Graveyard ||
|
||||||
sourceType == ConditionSourceType.AreaTrigger ||
|
sourceType == ConditionSourceType.AreaTrigger ||
|
||||||
sourceType == ConditionSourceType.TrainerSpell ||
|
sourceType == ConditionSourceType.TrainerSpell ||
|
||||||
sourceType == ConditionSourceType.ObjectIdVisibility;
|
sourceType == ConditionSourceType.ObjectIdVisibility ||
|
||||||
|
sourceType == ConditionSourceType.ReferenceCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanHaveSourceIdSet(ConditionSourceType sourceType)
|
public bool CanHaveSourceIdSet(ConditionSourceType sourceType)
|
||||||
@@ -189,7 +188,7 @@ namespace Game
|
|||||||
{
|
{
|
||||||
if (sourceType > ConditionSourceType.None && sourceType < ConditionSourceType.Max)
|
if (sourceType > ConditionSourceType.None && sourceType < ConditionSourceType.Max)
|
||||||
{
|
{
|
||||||
var conditions = conditionStorage[sourceType].LookupByKey(entry);
|
var conditions = ConditionStorage[sourceType].LookupByKey(new ConditionId(0, (int)entry, 0));
|
||||||
if (!conditions.Empty())
|
if (!conditions.Empty())
|
||||||
{
|
{
|
||||||
Log.outDebug(LogFilter.Condition, "GetConditionsForNotGroupedEntry: found conditions for type {0} and entry {1}", sourceType, entry);
|
Log.outDebug(LogFilter.Condition, "GetConditionsForNotGroupedEntry: found conditions for type {0} and entry {1}", sourceType, entry);
|
||||||
@@ -211,92 +210,75 @@ namespace Game
|
|||||||
ConditionSourceInfo conditionSource = new(map);
|
ConditionSourceInfo conditionSource = new(map);
|
||||||
return IsObjectMeetingNotGroupedConditions(sourceType, entry, conditionSource);
|
return IsObjectMeetingNotGroupedConditions(sourceType, entry, conditionSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint entry)
|
public bool HasConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint entry)
|
||||||
{
|
{
|
||||||
if (sourceType > ConditionSourceType.None && sourceType < ConditionSourceType.Max)
|
if (sourceType > ConditionSourceType.None && sourceType < ConditionSourceType.Max)
|
||||||
if (conditionStorage[sourceType].ContainsKey(entry))
|
return ConditionStorage[sourceType].ContainsKey(new ConditionId(0, (int)entry, 0));
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsObjectMeetingSpellClickConditions(uint creatureId, uint spellId, WorldObject clicker, WorldObject target)
|
public bool IsObjectMeetingSpellClickConditions(uint creatureId, uint spellId, WorldObject clicker, WorldObject target)
|
||||||
{
|
{
|
||||||
var multiMap = spellClickEventConditionStorage.LookupByKey(creatureId);
|
var conditions = ConditionStorage[ConditionSourceType.SpellClickEvent].LookupByKey(new ConditionId(creatureId, (int)spellId, 0));
|
||||||
if (multiMap != null)
|
if (!conditions.Empty())
|
||||||
{
|
{
|
||||||
var conditions = multiMap.LookupByKey(spellId);
|
Log.outDebug(LogFilter.Condition, "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry {0} spell {1}", creatureId, spellId);
|
||||||
if (!conditions.Empty())
|
ConditionSourceInfo sourceInfo = new(clicker, target);
|
||||||
{
|
return IsObjectMeetToConditions(sourceInfo, conditions);
|
||||||
Log.outDebug(LogFilter.Condition, "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry {0} spell {1}", creatureId, spellId);
|
|
||||||
ConditionSourceInfo sourceInfo = new(clicker, target);
|
|
||||||
return IsObjectMeetToConditions(sourceInfo, conditions);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Condition> GetConditionsForSpellClickEvent(uint creatureId, uint spellId)
|
public bool HasConditionsForSpellClickEvent(uint creatureId, uint spellId)
|
||||||
{
|
{
|
||||||
var multiMap = spellClickEventConditionStorage.LookupByKey(creatureId);
|
if (ConditionStorage[ConditionSourceType.SpellClickEvent].ContainsKey(new ConditionId(creatureId, (int)spellId, 0)))
|
||||||
if (multiMap != null)
|
|
||||||
{
|
{
|
||||||
var conditions = multiMap.LookupByKey(spellId);
|
Log.outDebug(LogFilter.Condition, "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry {0} spell {1}", creatureId, spellId);
|
||||||
if (!conditions.Empty())
|
return true;
|
||||||
{
|
|
||||||
Log.outDebug(LogFilter.Condition, "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry {0} spell {1}", creatureId, spellId);
|
|
||||||
return conditions;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsObjectMeetingVehicleSpellConditions(uint creatureId, uint spellId, Player player, Unit vehicle)
|
public bool IsObjectMeetingVehicleSpellConditions(uint creatureId, uint spellId, Player player, Unit vehicle)
|
||||||
{
|
{
|
||||||
var multiMap = vehicleSpellConditionStorage.LookupByKey(creatureId);
|
var conditions = ConditionStorage[ConditionSourceType.VehicleSpell].LookupByKey(new ConditionId(creatureId, (int)spellId, 0));
|
||||||
if (multiMap != null)
|
if (conditions != null)
|
||||||
{
|
{
|
||||||
var conditions = multiMap.LookupByKey(spellId);
|
Log.outDebug(LogFilter.Condition, "GetConditionsForVehicleSpell: found conditions for Vehicle entry {0} spell {1}", creatureId, spellId);
|
||||||
if (!conditions.Empty())
|
ConditionSourceInfo sourceInfo = new(player, vehicle);
|
||||||
{
|
return IsObjectMeetToConditions(sourceInfo, conditions);
|
||||||
Log.outDebug(LogFilter.Condition, "GetConditionsForVehicleSpell: found conditions for Vehicle entry {0} spell {1}", creatureId, spellId);
|
|
||||||
ConditionSourceInfo sourceInfo = new(player, vehicle);
|
|
||||||
return IsObjectMeetToConditions(sourceInfo, conditions);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsObjectMeetingSmartEventConditions(long entryOrGuid, uint eventId, SmartScriptType sourceType, Unit unit, WorldObject baseObject)
|
public bool IsObjectMeetingSmartEventConditions(long entryOrGuid, uint eventId, SmartScriptType sourceType, Unit unit, WorldObject baseObject)
|
||||||
{
|
{
|
||||||
var multiMap = smartEventConditionStorage.LookupByKey(Tuple.Create((int)entryOrGuid, (uint)sourceType));
|
var conditions = ConditionStorage[ConditionSourceType.SmartEvent].LookupByKey(new ConditionId(eventId + 1, (int)entryOrGuid, (uint)sourceType));
|
||||||
if (multiMap != null)
|
if (!conditions.Empty())
|
||||||
{
|
{
|
||||||
var conditions = multiMap.LookupByKey(eventId + 1);
|
Log.outDebug(LogFilter.Condition, "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid {0} eventId {1}", entryOrGuid, eventId);
|
||||||
if (!conditions.Empty())
|
ConditionSourceInfo sourceInfo = new(unit, baseObject);
|
||||||
{
|
return IsObjectMeetToConditions(sourceInfo, conditions);
|
||||||
Log.outDebug(LogFilter.Condition, "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid {0} eventId {1}", entryOrGuid, eventId);
|
|
||||||
ConditionSourceInfo sourceInfo = new(unit, baseObject);
|
|
||||||
return IsObjectMeetToConditions(sourceInfo, conditions);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsObjectMeetingVendorItemConditions(uint creatureId, uint itemId, Player player, Creature vendor)
|
public bool IsObjectMeetingVendorItemConditions(uint creatureId, uint itemId, Player player, Creature vendor)
|
||||||
{
|
{
|
||||||
var multiMap = npcVendorConditionContainerStorage.LookupByKey(creatureId);
|
var conditions = ConditionStorage[ConditionSourceType.NpcVendor].LookupByKey(new ConditionId(creatureId, (int)itemId, 0));
|
||||||
if (multiMap != null)
|
if (!conditions.Empty())
|
||||||
{
|
{
|
||||||
var conditions = multiMap.LookupByKey(itemId);
|
Log.outDebug(LogFilter.Condition, "GetConditionsForNpcVendor: found conditions for creature entry {0} item {1}", creatureId, itemId);
|
||||||
if (!conditions.Empty())
|
ConditionSourceInfo sourceInfo = new(player, vendor);
|
||||||
{
|
return IsObjectMeetToConditions(sourceInfo, conditions);
|
||||||
Log.outDebug(LogFilter.Condition, "GetConditionsForNpcVendor: found conditions for creature entry {0} item {1}", creatureId, itemId);
|
|
||||||
ConditionSourceInfo sourceInfo = new(player, vendor);
|
|
||||||
return IsObjectMeetToConditions(sourceInfo, conditions);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,38 +286,35 @@ namespace Game
|
|||||||
{
|
{
|
||||||
return spellsUsedInSpellClickConditions.Contains(spellId);
|
return spellsUsedInSpellClickConditions.Contains(spellId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Condition> GetConditionsForAreaTrigger(uint areaTriggerId, bool isServerSide)
|
public List<Condition> GetConditionsForAreaTrigger(uint areaTriggerId, bool isServerSide)
|
||||||
{
|
{
|
||||||
return areaTriggerConditionContainerStorage.LookupByKey(Tuple.Create(areaTriggerId, isServerSide));
|
return ConditionStorage[ConditionSourceType.AreaTrigger].LookupByKey(new ConditionId(areaTriggerId, isServerSide ? 1 : 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsObjectMeetingTrainerSpellConditions(uint trainerId, uint spellId, Player player)
|
public bool IsObjectMeetingTrainerSpellConditions(uint trainerId, uint spellId, Player player)
|
||||||
{
|
{
|
||||||
var multiMap = trainerSpellConditionContainerStorage.LookupByKey(trainerId);
|
var conditions = ConditionStorage[ConditionSourceType.NpcVendor].LookupByKey(new ConditionId(trainerId, (int)spellId, 0));
|
||||||
if (multiMap != null)
|
if (!conditions.Empty())
|
||||||
{
|
{
|
||||||
var conditionList = multiMap.LookupByKey(spellId);
|
Log.outDebug(LogFilter.Condition, $"GetConditionsForTrainerSpell: found conditions for trainer id {trainerId} spell {spellId}");
|
||||||
if (!conditionList.Empty())
|
return IsObjectMeetToConditions(player, conditions);
|
||||||
{
|
|
||||||
Log.outDebug(LogFilter.Condition, $"GetConditionsForTrainerSpell: found conditions for trainer id {trainerId} spell {spellId}");
|
|
||||||
return IsObjectMeetToConditions(player, conditionList);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsObjectMeetingVisibilityByObjectIdConditions(uint objectType, uint entry, WorldObject seer)
|
public bool IsObjectMeetingVisibilityByObjectIdConditions(uint objectType, uint entry, WorldObject seer)
|
||||||
{
|
{
|
||||||
var conditions = objectVisibilityConditionStorage.LookupByKey((objectType, entry));
|
var conditions = ConditionStorage[ConditionSourceType.ObjectIdVisibility].LookupByKey(new ConditionId(objectType, (int)entry, 0));
|
||||||
if (conditions != null)
|
if (!conditions.Empty())
|
||||||
{
|
{
|
||||||
Log.outDebug(LogFilter.Condition, $"IsObjectMeetingVisibilityByObjectIdConditions: found conditions for objectType {objectType} entry {entry}");
|
Log.outDebug(LogFilter.Condition, $"IsObjectMeetingVisibilityByObjectIdConditions: found conditions for objectType {objectType} entry {entry}");
|
||||||
return IsObjectMeetToConditions(seer, conditions);
|
return IsObjectMeetToConditions(seer, conditions);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadConditions(bool isReload = false)
|
public void LoadConditions(bool isReload = false)
|
||||||
{
|
{
|
||||||
uint oldMSTime = Time.GetMSTime();
|
uint oldMSTime = Time.GetMSTime();
|
||||||
@@ -345,25 +324,6 @@ namespace Game
|
|||||||
//must clear all custom handled cases (groupped types) before reload
|
//must clear all custom handled cases (groupped types) before reload
|
||||||
if (isReload)
|
if (isReload)
|
||||||
{
|
{
|
||||||
Log.outInfo(LogFilter.Server, "Reseting Loot Conditions...");
|
|
||||||
LootStorage.Creature.ResetConditions();
|
|
||||||
LootStorage.Fishing.ResetConditions();
|
|
||||||
LootStorage.Gameobject.ResetConditions();
|
|
||||||
LootStorage.Items.ResetConditions();
|
|
||||||
LootStorage.Mail.ResetConditions();
|
|
||||||
LootStorage.Milling.ResetConditions();
|
|
||||||
LootStorage.Pickpocketing.ResetConditions();
|
|
||||||
LootStorage.Reference.ResetConditions();
|
|
||||||
LootStorage.Skinning.ResetConditions();
|
|
||||||
LootStorage.Disenchant.ResetConditions();
|
|
||||||
LootStorage.Prospecting.ResetConditions();
|
|
||||||
LootStorage.Spell.ResetConditions();
|
|
||||||
|
|
||||||
Log.outInfo(LogFilter.Server, "Re-Loading `gossip_menu` Table for Conditions!");
|
|
||||||
Global.ObjectMgr.LoadGossipMenu();
|
|
||||||
|
|
||||||
Log.outInfo(LogFilter.Server, "Re-Loading `gossip_menu_option` Table for Conditions!");
|
|
||||||
Global.ObjectMgr.LoadGossipMenuItems();
|
|
||||||
Global.SpellMgr.UnloadSpellInfoImplicitTargetConditionLists();
|
Global.SpellMgr.UnloadSpellInfoImplicitTargetConditionLists();
|
||||||
|
|
||||||
Global.ObjectMgr.UnloadPhaseConditions();
|
Global.ObjectMgr.UnloadPhaseConditions();
|
||||||
@@ -379,6 +339,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint count = 0;
|
uint count = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Condition cond = new();
|
Condition cond = new();
|
||||||
@@ -410,6 +371,7 @@ namespace Game
|
|||||||
Log.outError(LogFilter.Sql, "Condition reference {1} is referencing self, skipped", iSourceTypeOrReferenceId);
|
Log.outError(LogFilter.Sql, "Condition reference {1} is referencing self, skipped", iSourceTypeOrReferenceId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cond.ReferenceId = (uint)Math.Abs(iConditionTypeOrReference);
|
cond.ReferenceId = (uint)Math.Abs(iConditionTypeOrReference);
|
||||||
|
|
||||||
string rowType = "reference template";
|
string rowType = "reference template";
|
||||||
@@ -426,8 +388,6 @@ namespace Game
|
|||||||
Log.outError(LogFilter.Sql, "Condition {0} {1} has useless data in value3 ({2})!", rowType, iSourceTypeOrReferenceId, cond.ConditionValue3);
|
Log.outError(LogFilter.Sql, "Condition {0} {1} has useless data in value3 ({2})!", rowType, iSourceTypeOrReferenceId, cond.ConditionValue3);
|
||||||
if (cond.NegativeCondition)
|
if (cond.NegativeCondition)
|
||||||
Log.outError(LogFilter.Sql, "Condition {0} {1} has useless data in NegativeCondition ({2})!", rowType, iSourceTypeOrReferenceId, cond.NegativeCondition);
|
Log.outError(LogFilter.Sql, "Condition {0} {1} has useless data in NegativeCondition ({2})!", rowType, iSourceTypeOrReferenceId, cond.NegativeCondition);
|
||||||
if (cond.SourceGroup != 0 && iSourceTypeOrReferenceId < 0)
|
|
||||||
Log.outError(LogFilter.Sql, "Condition {0} {1} has useless data in SourceGroup ({2})!", rowType, iSourceTypeOrReferenceId, cond.SourceGroup);
|
|
||||||
if (cond.SourceEntry != 0 && iSourceTypeOrReferenceId < 0)
|
if (cond.SourceEntry != 0 && iSourceTypeOrReferenceId < 0)
|
||||||
Log.outError(LogFilter.Sql, "Condition {0} {1} has useless data in SourceEntry ({2})!", rowType, iSourceTypeOrReferenceId, cond.SourceEntry);
|
Log.outError(LogFilter.Sql, "Condition {0} {1} has useless data in SourceEntry ({2})!", rowType, iSourceTypeOrReferenceId, cond.SourceEntry);
|
||||||
}
|
}
|
||||||
@@ -436,13 +396,17 @@ namespace Game
|
|||||||
|
|
||||||
if (iSourceTypeOrReferenceId < 0)//it is a reference template
|
if (iSourceTypeOrReferenceId < 0)//it is a reference template
|
||||||
{
|
{
|
||||||
conditionReferenceStorage.Add((uint)Math.Abs(iSourceTypeOrReferenceId), cond);//add to reference storage
|
if (cond.SourceGroup != 0)
|
||||||
count++;
|
Log.outError(LogFilter.Sql, $"Condition reference template {iSourceTypeOrReferenceId} has useless data in SourceGroup ({cond.SourceGroup})!");
|
||||||
continue;
|
if (cond.SourceEntry != 0)
|
||||||
}//end of reference templates
|
Log.outError(LogFilter.Sql, $"Condition reference template {iSourceTypeOrReferenceId} has useless data in SourceEntry ({cond.SourceEntry})!");
|
||||||
|
if (cond.SourceId != 0)
|
||||||
|
Log.outError(LogFilter.Sql, $"Condition reference template {iSourceTypeOrReferenceId} has useless data in SourceId ({cond.SourceId})!");
|
||||||
|
|
||||||
//if not a reference and SourceType is invalid, skip
|
cond.SourceType = ConditionSourceType.ReferenceCondition;
|
||||||
if (iConditionTypeOrReference >= 0 && !IsSourceTypeValid(cond))
|
cond.SourceGroup = (uint)-iSourceTypeOrReferenceId;
|
||||||
|
}
|
||||||
|
else if (!IsSourceTypeValid(cond)) //if not a reference and SourceType is invalid, skip
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//Grouping is only allowed for some types (loot templates, gossip menus, gossip items)
|
//Grouping is only allowed for some types (loot templates, gossip menus, gossip items)
|
||||||
@@ -469,197 +433,127 @@ namespace Game
|
|||||||
cond.ErrorTextId = 0;
|
cond.ErrorTextId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond.SourceGroup != 0)
|
var key = new ConditionId(cond.SourceGroup, cond.SourceEntry, cond.SourceId);
|
||||||
{
|
if (!ConditionStorage[cond.SourceType].ContainsKey(key))
|
||||||
bool valid = false;
|
ConditionStorage[cond.SourceType][key] = new List<Condition>();
|
||||||
// handle grouped conditions
|
|
||||||
switch (cond.SourceType)
|
|
||||||
{
|
|
||||||
case ConditionSourceType.CreatureLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Creature.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.DisenchantLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Disenchant.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.FishingLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Fishing.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.GameobjectLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Gameobject.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.ItemLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Items.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.MailLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Mail.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.MillingLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Milling.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.PickpocketingLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Pickpocketing.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.ProspectingLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Prospecting.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.ReferenceLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Reference.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.SkinningLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Skinning.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.SpellLootTemplate:
|
|
||||||
valid = AddToLootTemplate(cond, LootStorage.Spell.GetLootForConditionFill(cond.SourceGroup));
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.GossipMenu:
|
|
||||||
valid = AddToGossipMenus(cond);
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.GossipMenuOption:
|
|
||||||
valid = AddToGossipMenuItems(cond);
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.SpellClickEvent:
|
|
||||||
{
|
|
||||||
if (!spellClickEventConditionStorage.ContainsKey(cond.SourceGroup))
|
|
||||||
spellClickEventConditionStorage[cond.SourceGroup] = new MultiMap<uint, Condition>();
|
|
||||||
|
|
||||||
spellClickEventConditionStorage[cond.SourceGroup].Add((uint)cond.SourceEntry, cond);
|
ConditionStorage[cond.SourceType][key].Add(cond);
|
||||||
if (cond.ConditionType == ConditionTypes.Aura)
|
|
||||||
spellsUsedInSpellClickConditions.Add(cond.ConditionValue1);
|
|
||||||
++count;
|
|
||||||
continue; // do not add to m_AllocatedMemory to avoid double deleting
|
|
||||||
}
|
|
||||||
case ConditionSourceType.SpellImplicitTarget:
|
|
||||||
valid = AddToSpellImplicitTargetConditions(cond);
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.VehicleSpell:
|
|
||||||
{
|
|
||||||
if (!vehicleSpellConditionStorage.ContainsKey(cond.SourceGroup))
|
|
||||||
vehicleSpellConditionStorage[cond.SourceGroup] = new MultiMap<uint, Condition>();
|
|
||||||
|
|
||||||
vehicleSpellConditionStorage[cond.SourceGroup].Add((uint)cond.SourceEntry, cond);
|
|
||||||
++count;
|
|
||||||
continue; // do not add to m_AllocatedMemory to avoid double deleting
|
|
||||||
}
|
|
||||||
case ConditionSourceType.SmartEvent:
|
|
||||||
{
|
|
||||||
//! TODO: PAIR_32 ?
|
|
||||||
var key = Tuple.Create(cond.SourceEntry, cond.SourceId);
|
|
||||||
if (!smartEventConditionStorage.ContainsKey(key))
|
|
||||||
smartEventConditionStorage[key] = new MultiMap<uint, Condition>();
|
|
||||||
|
|
||||||
smartEventConditionStorage[key].Add(cond.SourceGroup, cond);
|
|
||||||
++count;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case ConditionSourceType.NpcVendor:
|
|
||||||
{
|
|
||||||
if (!npcVendorConditionContainerStorage.ContainsKey(cond.SourceGroup))
|
|
||||||
npcVendorConditionContainerStorage[cond.SourceGroup] = new MultiMap<uint, Condition>();
|
|
||||||
|
|
||||||
npcVendorConditionContainerStorage[cond.SourceGroup].Add((uint)cond.SourceEntry, cond);
|
|
||||||
++count;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case ConditionSourceType.Phase:
|
|
||||||
valid = AddToPhases(cond);
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.Graveyard:
|
|
||||||
valid = AddToGraveyardData(cond);
|
|
||||||
break;
|
|
||||||
case ConditionSourceType.AreaTrigger:
|
|
||||||
areaTriggerConditionContainerStorage.Add(Tuple.Create(cond.SourceGroup, cond.SourceEntry != 0), cond);
|
|
||||||
++count;
|
|
||||||
continue;
|
|
||||||
case ConditionSourceType.TrainerSpell:
|
|
||||||
{
|
|
||||||
if (!trainerSpellConditionContainerStorage.ContainsKey(cond.SourceGroup))
|
|
||||||
trainerSpellConditionContainerStorage[cond.SourceGroup] = new MultiMap<uint, Condition>();
|
|
||||||
|
|
||||||
trainerSpellConditionContainerStorage[cond.SourceGroup].Add((uint)cond.SourceEntry, cond);
|
|
||||||
++count;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case ConditionSourceType.ObjectIdVisibility:
|
|
||||||
{
|
|
||||||
objectVisibilityConditionStorage.Add((cond.SourceGroup, (uint)cond.SourceEntry), cond);
|
|
||||||
valid = true;
|
|
||||||
++count;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!valid)
|
|
||||||
Log.outError(LogFilter.Sql, "{0} Not handled grouped condition.", cond.ToString());
|
|
||||||
else
|
|
||||||
++count;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//add new Condition to storage based on Type/Entry
|
|
||||||
if (cond.SourceType == ConditionSourceType.SpellClickEvent && cond.ConditionType == ConditionTypes.Aura)
|
|
||||||
spellsUsedInSpellClickConditions.Add(cond.ConditionValue1);
|
|
||||||
|
|
||||||
conditionStorage[cond.SourceType].Add((uint)cond.SourceEntry, cond);
|
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
while (result.NextRow());
|
while (result.NextRow());
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.CreatureLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Creature.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.DisenchantLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Disenchant.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.FishingLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Fishing.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.GameobjectLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Gameobject.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.ItemLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Items.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.MailLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Mail.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.MillingLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Milling.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.PickpocketingLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Pickpocketing.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.ProspectingLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Prospecting.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.ReferenceLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Reference.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.SkinningLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Skinning.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.SpellLootTemplate])
|
||||||
|
AddToLootTemplate(id, conditions, LootStorage.Spell.GetLootForConditionFill(id.SourceGroup));
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.GossipMenu])
|
||||||
|
AddToGossipMenus(id, conditions);
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.GossipMenuOption])
|
||||||
|
AddToGossipMenuItems(id, conditions);
|
||||||
|
|
||||||
|
spellsUsedInSpellClickConditions.Clear();
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.SpellClickEvent])
|
||||||
|
foreach (Condition condition in conditions)
|
||||||
|
if (condition.ConditionType == ConditionTypes.Aura)
|
||||||
|
spellsUsedInSpellClickConditions.Add(condition.ConditionValue1);
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.SpellImplicitTarget])
|
||||||
|
foreach (Condition condition in conditions)
|
||||||
|
AddToSpellImplicitTargetConditions(condition);
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.Phase])
|
||||||
|
AddToPhases(id, conditions);
|
||||||
|
|
||||||
|
foreach (var (id, conditions) in ConditionStorage[ConditionSourceType.Graveyard])
|
||||||
|
AddToGraveyardData(id, conditions);
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} conditions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} conditions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddToLootTemplate(Condition cond, LootTemplate loot)
|
void AddToLootTemplate(ConditionId id, List<Condition> conditions, LootTemplate loot)
|
||||||
{
|
{
|
||||||
if (loot == null)
|
if (loot == null)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "{0} LootTemplate {1} not found.", cond.ToString(), cond.SourceGroup);
|
foreach (Condition condition in conditions)
|
||||||
return false;
|
Log.outError(LogFilter.Sql, $"{condition} LootTemplate {condition.SourceGroup} not found.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loot.AddConditionItem(cond))
|
if (loot.LinkConditions(id, new ConditionsReference(conditions)))
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
Log.outError(LogFilter.Sql, "{0} Item {1} not found in LootTemplate {2}.", cond.ToString(), cond.SourceEntry, cond.SourceGroup);
|
foreach (Condition condition in conditions)
|
||||||
return false;
|
Log.outError(LogFilter.Sql, $"{condition} Item {condition.SourceEntry} not found in LootTemplate {condition.SourceGroup}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddToGossipMenus(Condition cond)
|
void AddToGossipMenus(ConditionId id, List<Condition> conditions)
|
||||||
{
|
{
|
||||||
var pMenuBounds = Global.ObjectMgr.GetGossipMenusMapBounds(cond.SourceGroup);
|
var pMenuBounds = Global.ObjectMgr.GetGossipMenusMapBounds(id.SourceGroup);
|
||||||
if (!pMenuBounds.Empty())
|
if (!pMenuBounds.Empty())
|
||||||
{
|
{
|
||||||
foreach (var menu in pMenuBounds)
|
foreach (var menu in pMenuBounds)
|
||||||
{
|
{
|
||||||
if (menu.MenuId == cond.SourceGroup && (menu.TextId == cond.SourceEntry || cond.SourceEntry == 0))
|
if (menu.MenuId == id.SourceGroup && (menu.TextId == id.SourceEntry || id.SourceEntry == 0))
|
||||||
menu.Conditions.Add(cond);
|
menu.Conditions = new(conditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.outError(LogFilter.Sql, $"{cond} GossipMenu {cond.SourceGroup} not found.");
|
foreach (Condition condition in conditions)
|
||||||
return false;
|
Log.outError(LogFilter.Sql, $"{condition} GossipMenu {condition.SourceGroup} not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddToGossipMenuItems(Condition cond)
|
void AddToGossipMenuItems(ConditionId id, List<Condition> conditions)
|
||||||
{
|
{
|
||||||
var pMenuItemBounds = Global.ObjectMgr.GetGossipMenuItemsMapBounds(cond.SourceGroup);
|
var pMenuItemBounds = Global.ObjectMgr.GetGossipMenuItemsMapBounds(id.SourceGroup);
|
||||||
foreach (var gossipMenuItem in pMenuItemBounds)
|
foreach (var gossipMenuItem in pMenuItemBounds)
|
||||||
{
|
{
|
||||||
if (gossipMenuItem.MenuID == cond.SourceGroup && gossipMenuItem.OrderIndex == cond.SourceEntry)
|
if (gossipMenuItem.MenuID == id.SourceGroup && gossipMenuItem.OrderIndex == id.SourceEntry)
|
||||||
{
|
{
|
||||||
gossipMenuItem.Conditions.Add(cond);
|
gossipMenuItem.Conditions = new(conditions);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.outError(LogFilter.Sql, "{0} GossipMenuId {1} Item {2} not found.", cond.ToString(), cond.SourceGroup, cond.SourceEntry);
|
foreach (Condition condition in conditions)
|
||||||
return false;
|
Log.outError(LogFilter.Sql, $"{condition} GossipMenuId {condition.SourceGroup} Item {condition.SourceEntry} not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddToSpellImplicitTargetConditions(Condition cond)
|
void AddToSpellImplicitTargetConditions(Condition cond)
|
||||||
{
|
{
|
||||||
Global.SpellMgr.ForEachSpellInfoDifficulty((uint)cond.SourceEntry, spellInfo =>
|
Global.SpellMgr.ForEachSpellInfoDifficulty((uint)cond.SourceEntry, spellInfo =>
|
||||||
{
|
{
|
||||||
@@ -705,9 +599,8 @@ namespace Game
|
|||||||
|
|
||||||
// build new shared mask with found effect
|
// build new shared mask with found effect
|
||||||
uint sharedMask = (uint)(1 << (int)spellEffectInfo.EffectIndex);
|
uint sharedMask = (uint)(1 << (int)spellEffectInfo.EffectIndex);
|
||||||
List<Condition> cmp = spellEffectInfo.ImplicitTargetConditions;
|
|
||||||
for (uint effIndex = spellEffectInfo.EffectIndex + 1; effIndex < spellInfo.GetEffects().Count; ++effIndex)
|
for (uint effIndex = spellEffectInfo.EffectIndex + 1; effIndex < spellInfo.GetEffects().Count; ++effIndex)
|
||||||
if (spellInfo.GetEffect(effIndex).ImplicitTargetConditions == cmp)
|
if (spellInfo.GetEffect(effIndex).ImplicitTargetConditions == spellEffectInfo.ImplicitTargetConditions)
|
||||||
sharedMask |= (uint)(1 << (int)effIndex);
|
sharedMask |= (uint)(1 << (int)effIndex);
|
||||||
|
|
||||||
sharedMasks.Add(sharedMask);
|
sharedMasks.Add(sharedMask);
|
||||||
@@ -764,14 +657,13 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddToPhases(Condition cond)
|
void AddToPhases(ConditionId id, List<Condition> conditions)
|
||||||
{
|
{
|
||||||
if (cond.SourceEntry == 0)
|
if (id.SourceEntry == 0)
|
||||||
{
|
{
|
||||||
PhaseInfoStruct phaseInfo = Global.ObjectMgr.GetPhaseInfo(cond.SourceGroup);
|
PhaseInfoStruct phaseInfo = Global.ObjectMgr.GetPhaseInfo(id.SourceGroup);
|
||||||
if (phaseInfo != null)
|
if (phaseInfo != null)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@@ -782,9 +674,9 @@ namespace Game
|
|||||||
{
|
{
|
||||||
foreach (PhaseAreaInfo phase in phases)
|
foreach (PhaseAreaInfo phase in phases)
|
||||||
{
|
{
|
||||||
if (phase.PhaseInfo.Id == cond.SourceGroup)
|
if (phase.PhaseInfo.Id == id.SourceGroup)
|
||||||
{
|
{
|
||||||
phase.Conditions.Add(cond);
|
phase.Conditions.AddRange(conditions);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -792,39 +684,39 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var phases = Global.ObjectMgr.GetPhasesForArea((uint)cond.SourceEntry);
|
var phases = Global.ObjectMgr.GetPhasesForArea((uint)id.SourceEntry);
|
||||||
foreach (PhaseAreaInfo phase in phases)
|
foreach (PhaseAreaInfo phase in phases)
|
||||||
{
|
{
|
||||||
if (phase.PhaseInfo.Id == cond.SourceGroup)
|
if (phase.PhaseInfo.Id == id.SourceGroup)
|
||||||
{
|
{
|
||||||
phase.Conditions.Add(cond);
|
phase.Conditions.AddRange(conditions);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.outError(LogFilter.Sql, $"{cond} Area {cond.SourceEntry} does not have phase {cond.SourceGroup}.");
|
foreach (Condition condition in conditions)
|
||||||
return false;
|
Log.outError(LogFilter.Sql, $"{condition} Area {condition.SourceEntry} does not have phase {condition.SourceGroup}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddToGraveyardData(Condition cond)
|
void AddToGraveyardData(ConditionId id, List<Condition> conditions)
|
||||||
{
|
{
|
||||||
GraveyardData graveyard = Global.ObjectMgr.FindGraveyardData((uint)cond.SourceEntry, cond.SourceGroup);
|
GraveyardData graveyard = Global.ObjectMgr.FindGraveyardData((uint)id.SourceEntry, id.SourceGroup);
|
||||||
if (graveyard != null)
|
if (graveyard != null)
|
||||||
{
|
{
|
||||||
graveyard.Conditions.Add(cond);
|
graveyard.Conditions = new(conditions);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.outError(LogFilter.Sql, $"{cond}, Graveyard {cond.SourceEntry} does not have ghostzone {cond.SourceGroup}.");
|
foreach (Condition condition in conditions)
|
||||||
return false;
|
Log.outError(LogFilter.Sql, $"{condition}, Graveyard {condition.SourceEntry} does not have ghostzone {condition.SourceGroup}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSourceTypeValid(Condition cond)
|
bool IsSourceTypeValid(Condition cond)
|
||||||
{
|
{
|
||||||
switch (cond.SourceType)
|
switch (cond.SourceType)
|
||||||
@@ -1206,7 +1098,7 @@ namespace Game
|
|||||||
Log.outError(LogFilter.Sql, $"{cond.ToString()} in `condition` table, unexpected SourceEntry value (expected 0 or 1), ignoring.");
|
Log.outError(LogFilter.Sql, $"{cond.ToString()} in `condition` table, unexpected SourceEntry value (expected 0 or 1), ignoring.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (Global.AreaTriggerDataStorage.GetAreaTriggerTemplate(new AreaTriggerId(cond.SourceGroup, cond.SourceEntry != 0)) == null)
|
if (Global.AreaTriggerDataStorage.GetAreaTriggerTemplate(new AreaTriggerId(cond.SourceGroup, cond.SourceEntry == 1)) == null)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"{cond.ToString()} in `condition` table, does not exist in `areatrigger_template`, ignoring.");
|
Log.outError(LogFilter.Sql, $"{cond.ToString()} in `condition` table, does not exist in `areatrigger_template`, ignoring.");
|
||||||
return false;
|
return false;
|
||||||
@@ -1883,26 +1775,10 @@ namespace Game
|
|||||||
|
|
||||||
void Clean()
|
void Clean()
|
||||||
{
|
{
|
||||||
conditionReferenceStorage.Clear();
|
foreach (var (_, conditionsMap) in ConditionStorage)
|
||||||
|
conditionsMap.Clear();
|
||||||
|
|
||||||
conditionStorage.Clear();
|
|
||||||
for (ConditionSourceType i = 0; i < ConditionSourceType.Max; ++i)
|
|
||||||
conditionStorage[i] = new MultiMap<uint, Condition>();//add new empty list for SourceType
|
|
||||||
|
|
||||||
vehicleSpellConditionStorage.Clear();
|
|
||||||
|
|
||||||
smartEventConditionStorage.Clear();
|
|
||||||
|
|
||||||
spellClickEventConditionStorage.Clear();
|
|
||||||
spellsUsedInSpellClickConditions.Clear();
|
spellsUsedInSpellClickConditions.Clear();
|
||||||
|
|
||||||
npcVendorConditionContainerStorage.Clear();
|
|
||||||
|
|
||||||
areaTriggerConditionContainerStorage.Clear();
|
|
||||||
|
|
||||||
trainerSpellConditionContainerStorage.Clear();
|
|
||||||
|
|
||||||
objectVisibilityConditionStorage.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PlayerConditionCompare(int comparisonType, int value1, int value2)
|
static bool PlayerConditionCompare(int comparisonType, int value1, int value2)
|
||||||
@@ -2619,7 +2495,7 @@ namespace Game
|
|||||||
case UnitConditionVariable.InCombat:
|
case UnitConditionVariable.InCombat:
|
||||||
return unit.IsInCombat() ? 1 : 0;
|
return unit.IsInCombat() ? 1 : 0;
|
||||||
case UnitConditionVariable.IsMoving:
|
case UnitConditionVariable.IsMoving:
|
||||||
return unit.HasUnitMovementFlag(MovementFlag.Forward | MovementFlag.Backward | MovementFlag.StrafeLeft | MovementFlag.StrafeRight) ? 1:0;
|
return unit.HasUnitMovementFlag(MovementFlag.Forward | MovementFlag.Backward | MovementFlag.StrafeLeft | MovementFlag.StrafeRight) ? 1 : 0;
|
||||||
case UnitConditionVariable.IsCasting:
|
case UnitConditionVariable.IsCasting:
|
||||||
case UnitConditionVariable.IsCastingSpell: // this is supposed to return spell id by client code but data always has 0 or 1
|
case UnitConditionVariable.IsCastingSpell: // this is supposed to return spell id by client code but data always has 0 or 1
|
||||||
return unit.GetCurrentSpell(CurrentSpellTypes.Generic) != null ? 1 : 0;
|
return unit.GetCurrentSpell(CurrentSpellTypes.Generic) != null ? 1 : 0;
|
||||||
@@ -2635,7 +2511,7 @@ namespace Game
|
|||||||
return unit.GetExactDistSq(attacker) < distance * distance;
|
return unit.GetExactDistSq(attacker) < distance * distance;
|
||||||
});
|
});
|
||||||
case UnitConditionVariable.IsAttackingMe:
|
case UnitConditionVariable.IsAttackingMe:
|
||||||
return (otherUnit != null && unit.GetTarget() == otherUnit.GetGUID()) ? 1:0;
|
return (otherUnit != null && unit.GetTarget() == otherUnit.GetGUID()) ? 1 : 0;
|
||||||
case UnitConditionVariable.Range:
|
case UnitConditionVariable.Range:
|
||||||
return otherUnit != null ? (int)unit.GetExactDist(otherUnit) : 0;
|
return otherUnit != null ? (int)unit.GetExactDist(otherUnit) : 0;
|
||||||
case UnitConditionVariable.InMeleeRange:
|
case UnitConditionVariable.InMeleeRange:
|
||||||
@@ -2802,7 +2678,7 @@ namespace Game
|
|||||||
{
|
{
|
||||||
if (condition.Variable[i] == 0)
|
if (condition.Variable[i] == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
int unitValue = GetUnitConditionVariable(unit, otherUnit, (UnitConditionVariable)condition.Variable[i], condition.Value[i]);
|
int unitValue = GetUnitConditionVariable(unit, otherUnit, (UnitConditionVariable)condition.Variable[i], condition.Value[i]);
|
||||||
bool meets = false;
|
bool meets = false;
|
||||||
switch ((UnitConditionOp)condition.Op[i])
|
switch ((UnitConditionOp)condition.Op[i])
|
||||||
@@ -2840,7 +2716,7 @@ namespace Game
|
|||||||
|
|
||||||
return !condition.GetFlags().HasFlag(UnitConditionFlags.LogicOr);
|
return !condition.GetFlags().HasFlag(UnitConditionFlags.LogicOr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int EvalSingleValue(ByteBuffer buffer, Map map)
|
static int EvalSingleValue(ByteBuffer buffer, Map map)
|
||||||
{
|
{
|
||||||
WorldStateExpressionValueType valueType = (WorldStateExpressionValueType)buffer.ReadUInt8();
|
WorldStateExpressionValueType valueType = (WorldStateExpressionValueType)buffer.ReadUInt8();
|
||||||
@@ -3024,16 +2900,8 @@ namespace Game
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<ConditionSourceType, MultiMap<uint, Condition>> conditionStorage = new();
|
Dictionary<ConditionSourceType, Dictionary<ConditionId, List<Condition>>> ConditionStorage = new();
|
||||||
MultiMap<uint, Condition> conditionReferenceStorage = new();
|
|
||||||
Dictionary<uint, MultiMap<uint, Condition>> vehicleSpellConditionStorage = new();
|
|
||||||
Dictionary<uint, MultiMap<uint, Condition>> spellClickEventConditionStorage = new();
|
|
||||||
List<uint> spellsUsedInSpellClickConditions = new();
|
List<uint> spellsUsedInSpellClickConditions = new();
|
||||||
Dictionary<uint, MultiMap<uint, Condition>> npcVendorConditionContainerStorage = new();
|
|
||||||
Dictionary<Tuple<int, uint>, MultiMap<uint, Condition>> smartEventConditionStorage = new();
|
|
||||||
MultiMap<Tuple<uint, bool>, Condition> areaTriggerConditionContainerStorage = new();
|
|
||||||
Dictionary<uint, MultiMap<uint, Condition>> trainerSpellConditionContainerStorage = new();
|
|
||||||
MultiMap<(uint objectType, uint objectId), Condition> objectVisibilityConditionStorage = new();
|
|
||||||
|
|
||||||
public string[] StaticSourceTypeData =
|
public string[] StaticSourceTypeData =
|
||||||
{
|
{
|
||||||
@@ -3150,4 +3018,34 @@ namespace Game
|
|||||||
public bool HasConditionValue3;
|
public bool HasConditionValue3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct ConditionsReference
|
||||||
|
{
|
||||||
|
public List<Condition> Conditions = new();
|
||||||
|
|
||||||
|
public ConditionsReference(List<Condition> conditions)
|
||||||
|
{
|
||||||
|
Conditions = conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Meets(WorldObject obj)
|
||||||
|
{
|
||||||
|
return Global.ConditionMgr.IsObjectMeetToConditions(obj, Conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Meets(WorldObject obj1, WorldObject obj2)
|
||||||
|
{
|
||||||
|
return Global.ConditionMgr.IsObjectMeetToConditions(obj1, obj2, Conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Meets(ConditionSourceInfo sourceInfo)
|
||||||
|
{
|
||||||
|
return Global.ConditionMgr.IsObjectMeetToConditions(sourceInfo, Conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty()
|
||||||
|
{
|
||||||
|
return Conditions.Empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -789,7 +789,7 @@ namespace Game.Misc
|
|||||||
public uint BoxBroadcastTextId;
|
public uint BoxBroadcastTextId;
|
||||||
public int? SpellID;
|
public int? SpellID;
|
||||||
public int? OverrideIconID;
|
public int? OverrideIconID;
|
||||||
public List<Condition> Conditions = new();
|
public ConditionsReference Conditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GossipMenuAddon
|
public class GossipMenuAddon
|
||||||
@@ -817,6 +817,6 @@ namespace Game.Misc
|
|||||||
{
|
{
|
||||||
public uint MenuId;
|
public uint MenuId;
|
||||||
public uint TextId;
|
public uint TextId;
|
||||||
public List<Condition> Conditions = new();
|
public ConditionsReference Conditions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3301,8 +3301,7 @@ namespace Game.Entities
|
|||||||
var clickBounds = Global.ObjectMgr.GetSpellClickInfoMapBounds(obj.GetEntry());
|
var clickBounds = Global.ObjectMgr.GetSpellClickInfoMapBounds(obj.GetEntry());
|
||||||
foreach (var spellClickInfo in clickBounds)
|
foreach (var spellClickInfo in clickBounds)
|
||||||
{
|
{
|
||||||
List<Condition> conds = Global.ConditionMgr.GetConditionsForSpellClickEvent(obj.GetEntry(), spellClickInfo.spellId);
|
if (Global.ConditionMgr.HasConditionsForSpellClickEvent(obj.GetEntry(), spellClickInfo.spellId))
|
||||||
if (conds != null)
|
|
||||||
{
|
{
|
||||||
ObjectFieldData objMask = new();
|
ObjectFieldData objMask = new();
|
||||||
UnitData unitMask = new();
|
UnitData unitMask = new();
|
||||||
|
|||||||
@@ -2564,7 +2564,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
foreach (var gossipMenuItem in menuItemBounds)
|
foreach (var gossipMenuItem in menuItemBounds)
|
||||||
{
|
{
|
||||||
if (!ConditionMgr.IsObjectMeetToConditions(this, source, gossipMenuItem.Conditions))
|
if (!gossipMenuItem.Conditions.Meets(this, source))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bool canTalk = true;
|
bool canTalk = true;
|
||||||
@@ -2889,7 +2889,7 @@ namespace Game.Entities
|
|||||||
if (menu.TextId == 0)
|
if (menu.TextId == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ConditionMgr.IsObjectMeetToConditions(this, source, menu.Conditions))
|
if (menu.Conditions.Meets(this, source))
|
||||||
textId = menu.TextId;
|
textId = menu.TextId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2913,9 +2913,9 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
var menuBounds = ObjectMgr.GetGossipMenusMapBounds(menuId);
|
var menuBounds = ObjectMgr.GetGossipMenusMapBounds(menuId);
|
||||||
|
|
||||||
foreach (var itr in menuBounds)
|
foreach (var menu in menuBounds)
|
||||||
{
|
{
|
||||||
if (!ConditionMgr.IsObjectMeetToConditions(this, source, itr.Conditions))
|
if (!menu.Conditions.Meets(this, source))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
menuIdToShow = menuId;
|
menuIdToShow = menuId;
|
||||||
|
|||||||
@@ -901,7 +901,7 @@ namespace Game
|
|||||||
|
|
||||||
if (conditionObject != null)
|
if (conditionObject != null)
|
||||||
{
|
{
|
||||||
if (!Global.ConditionMgr.IsObjectMeetToConditions(conditionSource, data.Conditions))
|
if (!data.Conditions.Meets(conditionSource))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (entry.Loc.GetMapId() == mapEntry.ParentMapID && !conditionObject.GetPhaseShift().HasVisibleMapId(entry.Loc.GetMapId()))
|
if (entry.Loc.GetMapId() == mapEntry.ParentMapID && !conditionObject.GetPhaseShift().HasVisibleMapId(entry.Loc.GetMapId()))
|
||||||
@@ -910,7 +910,7 @@ namespace Game
|
|||||||
else if (team != 0)
|
else if (team != 0)
|
||||||
{
|
{
|
||||||
bool teamConditionMet = true;
|
bool teamConditionMet = true;
|
||||||
foreach (Condition cond in data.Conditions)
|
foreach (Condition cond in data.Conditions.Conditions)
|
||||||
{
|
{
|
||||||
if (cond.ConditionType != ConditionTypes.Team)
|
if (cond.ConditionType != ConditionTypes.Team)
|
||||||
continue;
|
continue;
|
||||||
@@ -11309,7 +11309,7 @@ namespace Game
|
|||||||
public class GraveyardData
|
public class GraveyardData
|
||||||
{
|
{
|
||||||
public uint SafeLocId;
|
public uint SafeLocId;
|
||||||
public List<Condition> Conditions = new();
|
public ConditionsReference Conditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class QuestPOIBlobData
|
public class QuestPOIBlobData
|
||||||
|
|||||||
@@ -2436,7 +2436,7 @@ namespace Game
|
|||||||
{
|
{
|
||||||
var gYard = range[(int)i];
|
var gYard = range[(int)i];
|
||||||
ConditionSourceInfo conditionSource = new(_player);
|
ConditionSourceInfo conditionSource = new(_player);
|
||||||
if (!Global.ConditionMgr.IsObjectMeetToConditions(conditionSource, gYard.Conditions))
|
if (!gYard.Conditions.Meets(conditionSource))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
graveyardIds.Add(i);
|
graveyardIds.Add(i);
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ namespace Game.Loots
|
|||||||
return AllowedForPlayer(player, loot, itemid, needs_quest, follow_loot_rules, false, conditions);
|
return AllowedForPlayer(player, loot, itemid, needs_quest, follow_loot_rules, false, conditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool AllowedForPlayer(Player player, Loot loot, uint itemid, bool needs_quest, bool follow_loot_rules, bool strictUsabilityCheck, List<Condition> conditions)
|
public static bool AllowedForPlayer(Player player, Loot loot, uint itemid, bool needs_quest, bool follow_loot_rules, bool strictUsabilityCheck, ConditionsReference conditions)
|
||||||
{
|
{
|
||||||
// DB conditions check
|
// DB conditions check
|
||||||
if (!Global.ConditionMgr.IsObjectMeetToConditions(player, conditions))
|
if (!conditions.Meets(player))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ItemTemplate pProto = Global.ObjectMgr.GetItemTemplate(itemid);
|
ItemTemplate pProto = Global.ObjectMgr.GetItemTemplate(itemid);
|
||||||
@@ -180,7 +180,7 @@ namespace Game.Loots
|
|||||||
public uint randomBonusListId;
|
public uint randomBonusListId;
|
||||||
public List<uint> BonusListIDs = new();
|
public List<uint> BonusListIDs = new();
|
||||||
public ItemContext context;
|
public ItemContext context;
|
||||||
public List<Condition> conditions = new(); // additional loot condition
|
public ConditionsReference conditions; // additional loot condition
|
||||||
public List<ObjectGuid> allowedGUIDs = new();
|
public List<ObjectGuid> allowedGUIDs = new();
|
||||||
public ObjectGuid rollWinnerGUID; // Stores the guid of person who won loot, if his bags are full only he can see the item in loot list!
|
public ObjectGuid rollWinnerGUID; // Stores the guid of person who won loot, if his bags are full only he can see the item in loot list!
|
||||||
public byte count;
|
public byte count;
|
||||||
@@ -999,7 +999,7 @@ namespace Game.Loots
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
foreach (LootItem item in items)
|
foreach (LootItem item in items)
|
||||||
if (!item.is_looted && item.follow_loot_rules && !item.freeforall && item.conditions.Empty())
|
if (!item.is_looted && item.follow_loot_rules && !item.freeforall && item.conditions.IsEmpty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ namespace Game.Loots
|
|||||||
public byte groupid;
|
public byte groupid;
|
||||||
public byte mincount; // mincount for drop items
|
public byte mincount; // mincount for drop items
|
||||||
public byte maxcount; // max drop count for the item mincount or Ref multiplicator
|
public byte maxcount; // max drop count for the item mincount or Ref multiplicator
|
||||||
public List<Condition> conditions; // additional loot condition
|
public ConditionsReference conditions; // additional loot condition
|
||||||
|
|
||||||
public LootStoreItem(uint _itemid, uint _reference, float _chance, bool _needs_quest, ushort _lootmode, byte _groupid, byte _mincount, byte _maxcount)
|
public LootStoreItem(uint _itemid, uint _reference, float _chance, bool _needs_quest, ushort _lootmode, byte _groupid, byte _mincount, byte _maxcount)
|
||||||
{
|
{
|
||||||
@@ -502,7 +502,6 @@ namespace Game.Loots
|
|||||||
groupid = _groupid;
|
groupid = _groupid;
|
||||||
mincount = _mincount;
|
mincount = _mincount;
|
||||||
maxcount = _maxcount;
|
maxcount = _maxcount;
|
||||||
conditions = new List<Condition>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Roll(bool rate)
|
public bool Roll(bool rate)
|
||||||
@@ -581,7 +580,7 @@ namespace Game.Loots
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class LootStore
|
public class LootStore
|
||||||
{
|
{
|
||||||
public LootStore(string name, string entryName, bool ratesAllowed = true)
|
public LootStore(string name, string entryName, bool ratesAllowed = true)
|
||||||
{
|
{
|
||||||
m_name = name;
|
m_name = name;
|
||||||
@@ -614,11 +613,11 @@ namespace Game.Loots
|
|||||||
{
|
{
|
||||||
// all still listed ids isn't referenced
|
// all still listed ids isn't referenced
|
||||||
foreach (var id in lootIdSet)
|
foreach (var id in lootIdSet)
|
||||||
Log.outError( LogFilter.Sql, "Table '{0}' entry {1} isn't {2} and not referenced from loot, and then useless.", GetName(), id, GetEntryName());
|
Log.outError(LogFilter.Sql, "Table '{0}' entry {1} isn't {2} and not referenced from loot, and then useless.", GetName(), id, GetEntryName());
|
||||||
}
|
}
|
||||||
public void ReportNonExistingId(uint lootId, uint ownerId)
|
public void ReportNonExistingId(uint lootId, uint ownerId)
|
||||||
{
|
{
|
||||||
Log.outError( LogFilter.Sql, "Table '{0}' Entry {1} does not exist but it is used by {2} {3}", GetName(), lootId, GetEntryName(), ownerId);
|
Log.outError(LogFilter.Sql, "Table '{0}' Entry {1} does not exist but it is used by {2} {3}", GetName(), lootId, GetEntryName(), ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HaveLootFor(uint loot_id) { return m_LootTemplates.LookupByKey(loot_id) != null; }
|
public bool HaveLootFor(uint loot_id) { return m_LootTemplates.LookupByKey(loot_id) != null; }
|
||||||
@@ -650,14 +649,7 @@ namespace Game.Loots
|
|||||||
|
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
public void ResetConditions()
|
|
||||||
{
|
|
||||||
foreach (var pair in m_LootTemplates)
|
|
||||||
{
|
|
||||||
List<Condition> empty = new();
|
|
||||||
pair.Value.CopyConditions(empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public LootTemplate GetLootForConditionFill(uint loot_id)
|
public LootTemplate GetLootForConditionFill(uint loot_id)
|
||||||
{
|
{
|
||||||
var tab = m_LootTemplates.LookupByKey(loot_id);
|
var tab = m_LootTemplates.LookupByKey(loot_id);
|
||||||
@@ -928,14 +920,6 @@ namespace Game.Loots
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyConditions(List<Condition> conditions)
|
|
||||||
{
|
|
||||||
foreach (var i in Entries)
|
|
||||||
i.conditions.Clear();
|
|
||||||
|
|
||||||
foreach (var group in Groups.Values)
|
|
||||||
group.CopyConditions(conditions);
|
|
||||||
}
|
|
||||||
public void CopyConditions(LootItem li)
|
public void CopyConditions(LootItem li)
|
||||||
{
|
{
|
||||||
// Copies the conditions list from a template item to a LootItem
|
// Copies the conditions list from a template item to a LootItem
|
||||||
@@ -1044,21 +1028,16 @@ namespace Game.Loots
|
|||||||
foreach (var group in Groups.Values)
|
foreach (var group in Groups.Values)
|
||||||
group.CheckLootRefs(store, ref_set);
|
group.CheckLootRefs(store, ref_set);
|
||||||
}
|
}
|
||||||
public bool AddConditionItem(Condition cond)
|
|
||||||
{
|
|
||||||
if (cond == null || !cond.IsLoaded())//should never happen, checked at loading
|
|
||||||
{
|
|
||||||
Log.outError(LogFilter.Loot, "LootTemplate.addConditionItem: condition is null");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public bool LinkConditions(ConditionId id, ConditionsReference reference)
|
||||||
|
{
|
||||||
if (!Entries.Empty())
|
if (!Entries.Empty())
|
||||||
{
|
{
|
||||||
foreach (var i in Entries)
|
foreach (var item in Entries)
|
||||||
{
|
{
|
||||||
if (i.itemid == cond.SourceEntry)
|
if (item.itemid == id.SourceEntry)
|
||||||
{
|
{
|
||||||
i.conditions.Add(cond);
|
item.conditions = reference;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1066,7 +1045,7 @@ namespace Game.Loots
|
|||||||
|
|
||||||
if (!Groups.Empty())
|
if (!Groups.Empty())
|
||||||
{
|
{
|
||||||
foreach (var group in Groups.Values)
|
foreach (var (_, group) in Groups)
|
||||||
{
|
{
|
||||||
if (group == null)
|
if (group == null)
|
||||||
continue;
|
continue;
|
||||||
@@ -1074,11 +1053,11 @@ namespace Game.Loots
|
|||||||
LootStoreItemList itemList = group.GetExplicitlyChancedItemList();
|
LootStoreItemList itemList = group.GetExplicitlyChancedItemList();
|
||||||
if (!itemList.Empty())
|
if (!itemList.Empty())
|
||||||
{
|
{
|
||||||
foreach (var i in itemList)
|
foreach (var item in itemList)
|
||||||
{
|
{
|
||||||
if (i.itemid == cond.SourceEntry)
|
if (item.itemid == id.SourceEntry)
|
||||||
{
|
{
|
||||||
i.conditions.Add(cond);
|
item.conditions = reference;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1087,11 +1066,11 @@ namespace Game.Loots
|
|||||||
itemList = group.GetEqualChancedItemList();
|
itemList = group.GetEqualChancedItemList();
|
||||||
if (!itemList.Empty())
|
if (!itemList.Empty())
|
||||||
{
|
{
|
||||||
foreach (var i in itemList)
|
foreach (var item in itemList)
|
||||||
{
|
{
|
||||||
if (i.itemid == cond.SourceEntry)
|
if (item.itemid == id.SourceEntry)
|
||||||
{
|
{
|
||||||
i.conditions.Add(cond);
|
item.conditions = reference;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1100,6 +1079,7 @@ namespace Game.Loots
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsReference(uint id)
|
public bool IsReference(uint id)
|
||||||
{
|
{
|
||||||
foreach (var storeItem in Entries)
|
foreach (var storeItem in Entries)
|
||||||
@@ -1210,14 +1190,6 @@ namespace Game.Loots
|
|||||||
}
|
}
|
||||||
public LootStoreItemList GetExplicitlyChancedItemList() { return ExplicitlyChanced; }
|
public LootStoreItemList GetExplicitlyChancedItemList() { return ExplicitlyChanced; }
|
||||||
public LootStoreItemList GetEqualChancedItemList() { return EqualChanced; }
|
public LootStoreItemList GetEqualChancedItemList() { return EqualChanced; }
|
||||||
public void CopyConditions(List<Condition> conditions)
|
|
||||||
{
|
|
||||||
foreach (var i in ExplicitlyChanced)
|
|
||||||
i.conditions.Clear();
|
|
||||||
|
|
||||||
foreach (var i in EqualChanced)
|
|
||||||
i.conditions.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
LootStoreItemList ExplicitlyChanced = new(); // Entries with chances defined in DB
|
LootStoreItemList ExplicitlyChanced = new(); // Entries with chances defined in DB
|
||||||
LootStoreItemList EqualChanced = new(); // Zero chances - every entry takes the same chance
|
LootStoreItemList EqualChanced = new(); // Zero chances - every entry takes the same chance
|
||||||
|
|||||||
@@ -3883,19 +3883,8 @@ namespace Game.Spells
|
|||||||
public void _UnloadImplicitTargetConditionLists()
|
public void _UnloadImplicitTargetConditionLists()
|
||||||
{
|
{
|
||||||
// find the same instances of ConditionList and delete them.
|
// find the same instances of ConditionList and delete them.
|
||||||
foreach (var effectInfo in _effects)
|
foreach (SpellEffectInfo effect in _effects)
|
||||||
{
|
effect.ImplicitTargetConditions = null;
|
||||||
var cur = effectInfo.ImplicitTargetConditions;
|
|
||||||
if (cur == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (int j = (int)effectInfo.EffectIndex; j < _effects.Count; ++j)
|
|
||||||
{
|
|
||||||
SpellEffectInfo eff = _effects[j];
|
|
||||||
if (eff.ImplicitTargetConditions == cur)
|
|
||||||
eff.ImplicitTargetConditions = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MeetsFutureSpellPlayerCondition(Player player)
|
public bool MeetsFutureSpellPlayerCondition(Player player)
|
||||||
|
|||||||
Reference in New Issue
Block a user