Core/Conditions: Implemented conditions for areatriggers

Port From (https://github.com/TrinityCore/TrinityCore/commit/3548467c93a3859f7df72c456d600300539dc6b2)
This commit is contained in:
hondacrx
2021-10-08 10:20:45 -04:00
parent aee1c82086
commit 06e7a9ddd5
4 changed files with 91 additions and 39 deletions
+2 -1
View File
@@ -102,7 +102,8 @@ namespace Framework.Constants
TerrainSwap = 25, TerrainSwap = 25,
Phase = 26, Phase = 26,
Graveyard = 27, Graveyard = 27,
Max = 28 AreaTrigger = 28,
Max
} }
public enum RelationType public enum RelationType
+63 -38
View File
@@ -53,7 +53,7 @@ namespace Game
if (i.ReferenceId != 0) // handle reference if (i.ReferenceId != 0) // handle reference
{ {
var refe = ConditionReferenceStore.LookupByKey(i.ReferenceId); var refe = conditionReferenceStorage.LookupByKey(i.ReferenceId);
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);
} }
@@ -91,7 +91,7 @@ namespace Game
if (condition.ReferenceId != 0)//handle reference if (condition.ReferenceId != 0)//handle reference
{ {
var refe = ConditionReferenceStore.LookupByKey(condition.ReferenceId); var refe = conditionReferenceStorage.LookupByKey(condition.ReferenceId);
if (!refe.Empty()) if (!refe.Empty())
{ {
if (!IsObjectMeetToConditionList(sourceInfo, refe)) if (!IsObjectMeetToConditionList(sourceInfo, refe))
@@ -160,7 +160,8 @@ namespace Game
sourceType == ConditionSourceType.SpellClickEvent || sourceType == ConditionSourceType.SpellClickEvent ||
sourceType == ConditionSourceType.SmartEvent || sourceType == ConditionSourceType.SmartEvent ||
sourceType == ConditionSourceType.NpcVendor || sourceType == ConditionSourceType.NpcVendor ||
sourceType == ConditionSourceType.Phase); sourceType == ConditionSourceType.Phase ||
sourceType == ConditionSourceType.AreaTrigger);
} }
public bool CanHaveSourceIdSet(ConditionSourceType sourceType) public bool CanHaveSourceIdSet(ConditionSourceType sourceType)
@@ -172,7 +173,7 @@ namespace Game
{ {
if (sourceType > ConditionSourceType.None && sourceType < ConditionSourceType.Max) if (sourceType > ConditionSourceType.None && sourceType < ConditionSourceType.Max)
{ {
var conditions = ConditionStore[sourceType].LookupByKey(entry); var conditions = conditionStorage[sourceType].LookupByKey(entry);
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);
@@ -192,7 +193,7 @@ namespace Game
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 (ConditionStore[sourceType].ContainsKey(entry)) if (conditionStorage[sourceType].ContainsKey(entry))
return true; return true;
return false; return false;
@@ -200,7 +201,7 @@ namespace Game
public bool IsObjectMeetingSpellClickConditions(uint creatureId, uint spellId, WorldObject clicker, WorldObject target) public bool IsObjectMeetingSpellClickConditions(uint creatureId, uint spellId, WorldObject clicker, WorldObject target)
{ {
var multiMap = SpellClickEventConditionStore.LookupByKey(creatureId); var multiMap = spellClickEventConditionStorage.LookupByKey(creatureId);
if (multiMap != null) if (multiMap != null)
{ {
var conditions = multiMap.LookupByKey(spellId); var conditions = multiMap.LookupByKey(spellId);
@@ -216,7 +217,7 @@ namespace Game
public List<Condition> GetConditionsForSpellClickEvent(uint creatureId, uint spellId) public List<Condition> GetConditionsForSpellClickEvent(uint creatureId, uint spellId)
{ {
var multiMap = SpellClickEventConditionStore.LookupByKey(creatureId); var multiMap = spellClickEventConditionStorage.LookupByKey(creatureId);
if (multiMap != null) if (multiMap != null)
{ {
var conditions = multiMap.LookupByKey(spellId); var conditions = multiMap.LookupByKey(spellId);
@@ -231,7 +232,7 @@ namespace Game
public bool IsObjectMeetingVehicleSpellConditions(uint creatureId, uint spellId, Player player, Unit vehicle) public bool IsObjectMeetingVehicleSpellConditions(uint creatureId, uint spellId, Player player, Unit vehicle)
{ {
var multiMap = VehicleSpellConditionStore.LookupByKey(creatureId); var multiMap = vehicleSpellConditionStorage.LookupByKey(creatureId);
if (multiMap != null) if (multiMap != null)
{ {
var conditions = multiMap.LookupByKey(spellId); var conditions = multiMap.LookupByKey(spellId);
@@ -247,7 +248,7 @@ namespace Game
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 = SmartEventConditionStore.LookupByKey(Tuple.Create((int)entryOrGuid, (uint)sourceType)); var multiMap = smartEventConditionStorage.LookupByKey(Tuple.Create((int)entryOrGuid, (uint)sourceType));
if (multiMap != null) if (multiMap != null)
{ {
var conditions = multiMap.LookupByKey(eventId + 1); var conditions = multiMap.LookupByKey(eventId + 1);
@@ -263,7 +264,7 @@ namespace Game
public bool IsObjectMeetingVendorItemConditions(uint creatureId, uint itemId, Player player, Creature vendor) public bool IsObjectMeetingVendorItemConditions(uint creatureId, uint itemId, Player player, Creature vendor)
{ {
var multiMap = NpcVendorConditionContainerStore.LookupByKey(creatureId); var multiMap = npcVendorConditionContainerStorage.LookupByKey(creatureId);
if (multiMap != null) if (multiMap != null)
{ {
var conditions = multiMap.LookupByKey(itemId); var conditions = multiMap.LookupByKey(itemId);
@@ -277,6 +278,11 @@ namespace Game
return true; return true;
} }
public List<Condition> GetConditionsForAreaTrigger(uint areaTriggerId, bool isServerSide)
{
return areaTriggerConditionContainerStorage.LookupByKey(Tuple.Create(areaTriggerId, isServerSide));
}
public void LoadConditions(bool isReload = false) public void LoadConditions(bool isReload = false)
{ {
uint oldMSTime = Time.GetMSTime(); uint oldMSTime = Time.GetMSTime();
@@ -377,7 +383,7 @@ namespace Game
if (iSourceTypeOrReferenceId < 0)//it is a reference template if (iSourceTypeOrReferenceId < 0)//it is a reference template
{ {
ConditionReferenceStore.Add((uint)Math.Abs(iSourceTypeOrReferenceId), cond);//add to reference storage conditionReferenceStorage.Add((uint)Math.Abs(iSourceTypeOrReferenceId), cond);//add to reference storage
count++; count++;
continue; continue;
}//end of reference templates }//end of reference templates
@@ -460,10 +466,10 @@ namespace Game
break; break;
case ConditionSourceType.SpellClickEvent: case ConditionSourceType.SpellClickEvent:
{ {
if (!SpellClickEventConditionStore.ContainsKey(cond.SourceGroup)) if (!spellClickEventConditionStorage.ContainsKey(cond.SourceGroup))
SpellClickEventConditionStore[cond.SourceGroup] = new MultiMap<uint, Condition>(); spellClickEventConditionStorage[cond.SourceGroup] = new MultiMap<uint, Condition>();
SpellClickEventConditionStore[cond.SourceGroup].Add((uint)cond.SourceEntry, cond); spellClickEventConditionStorage[cond.SourceGroup].Add((uint)cond.SourceEntry, cond);
++count; ++count;
continue; // do not add to m_AllocatedMemory to avoid double deleting continue; // do not add to m_AllocatedMemory to avoid double deleting
} }
@@ -472,10 +478,10 @@ namespace Game
break; break;
case ConditionSourceType.VehicleSpell: case ConditionSourceType.VehicleSpell:
{ {
if (!VehicleSpellConditionStore.ContainsKey(cond.SourceGroup)) if (!vehicleSpellConditionStorage.ContainsKey(cond.SourceGroup))
VehicleSpellConditionStore[cond.SourceGroup] = new MultiMap<uint, Condition>(); vehicleSpellConditionStorage[cond.SourceGroup] = new MultiMap<uint, Condition>();
VehicleSpellConditionStore[cond.SourceGroup].Add((uint)cond.SourceEntry, cond); vehicleSpellConditionStorage[cond.SourceGroup].Add((uint)cond.SourceEntry, cond);
++count; ++count;
continue; // do not add to m_AllocatedMemory to avoid double deleting continue; // do not add to m_AllocatedMemory to avoid double deleting
} }
@@ -483,25 +489,29 @@ namespace Game
{ {
//! TODO: PAIR_32 ? //! TODO: PAIR_32 ?
var key = Tuple.Create(cond.SourceEntry, cond.SourceId); var key = Tuple.Create(cond.SourceEntry, cond.SourceId);
if (!SmartEventConditionStore.ContainsKey(key)) if (!smartEventConditionStorage.ContainsKey(key))
SmartEventConditionStore[key] = new MultiMap<uint, Condition>(); smartEventConditionStorage[key] = new MultiMap<uint, Condition>();
SmartEventConditionStore[key].Add(cond.SourceGroup, cond); smartEventConditionStorage[key].Add(cond.SourceGroup, cond);
++count; ++count;
continue; continue;
} }
case ConditionSourceType.NpcVendor: case ConditionSourceType.NpcVendor:
{ {
if (!NpcVendorConditionContainerStore.ContainsKey(cond.SourceGroup)) if (!npcVendorConditionContainerStorage.ContainsKey(cond.SourceGroup))
NpcVendorConditionContainerStore[cond.SourceGroup] = new MultiMap<uint, Condition>(); npcVendorConditionContainerStorage[cond.SourceGroup] = new MultiMap<uint, Condition>();
NpcVendorConditionContainerStore[cond.SourceGroup].Add((uint)cond.SourceEntry, cond); npcVendorConditionContainerStorage[cond.SourceGroup].Add((uint)cond.SourceEntry, cond);
++count; ++count;
continue; continue;
} }
case ConditionSourceType.Phase: case ConditionSourceType.Phase:
valid = AddToPhases(cond); valid = AddToPhases(cond);
break; break;
case ConditionSourceType.AreaTrigger:
areaTriggerConditionContainerStorage.Add(Tuple.Create((int)cond.SourceGroup, cond.SourceEntry != 0), cond);
++count;
continue;
default: default:
break; break;
} }
@@ -515,7 +525,7 @@ namespace Game
} }
//add new Condition to storage based on Type/Entry //add new Condition to storage based on Type/Entry
ConditionStore[cond.SourceType].Add((uint)cond.SourceEntry, cond); conditionStorage[cond.SourceType].Add((uint)cond.SourceEntry, cond);
++count; ++count;
} }
while (result.NextRow()); while (result.NextRow());
@@ -1082,6 +1092,18 @@ namespace Game
return false; return false;
} }
break; break;
case ConditionSourceType.AreaTrigger:
if (cond.SourceEntry != 0 && cond.SourceEntry != 1)
{
Log.outError(LogFilter.Sql, $"{cond.ToString()} in `condition` table, unexpected SourceEntry value (expected 0 or 1), ignoring.");
return false;
}
if (Global.AreaTriggerDataStorage.GetAreaTriggerTemplate(new AreaTriggerId(cond.SourceGroup, cond.SourceEntry != 0)) == null)
{
Log.outError(LogFilter.Sql, $"{cond.ToString()} in `condition` table, does not exist in `areatrigger_template`, ignoring.");
return false;
}
break;
default: default:
Log.outError(LogFilter.Sql, $"{cond.ToString()} Invalid ConditionSourceType in `condition` table, ignoring."); Log.outError(LogFilter.Sql, $"{cond.ToString()} Invalid ConditionSourceType in `condition` table, ignoring.");
break; break;
@@ -1610,19 +1632,19 @@ namespace Game
void Clean() void Clean()
{ {
ConditionReferenceStore.Clear(); conditionReferenceStorage.Clear();
ConditionStore.Clear(); conditionStorage.Clear();
for (ConditionSourceType i = 0; i < ConditionSourceType.Max; ++i) for (ConditionSourceType i = 0; i < ConditionSourceType.Max; ++i)
ConditionStore[i] = new MultiMap<uint, Condition>();//add new empty list for SourceType conditionStorage[i] = new MultiMap<uint, Condition>();//add new empty list for SourceType
VehicleSpellConditionStore.Clear(); vehicleSpellConditionStorage.Clear();
SmartEventConditionStore.Clear(); smartEventConditionStorage.Clear();
SpellClickEventConditionStore.Clear(); spellClickEventConditionStorage.Clear();
NpcVendorConditionContainerStore.Clear(); npcVendorConditionContainerStorage.Clear();
} }
static bool PlayerConditionCompare(int comparisonType, int value1, int value2) static bool PlayerConditionCompare(int comparisonType, int value1, int value2)
@@ -2398,12 +2420,13 @@ namespace Game
return false; return false;
} }
Dictionary<ConditionSourceType, MultiMap<uint, Condition>> ConditionStore = new(); Dictionary<ConditionSourceType, MultiMap<uint, Condition>> conditionStorage = new();
MultiMap<uint, Condition> ConditionReferenceStore = new(); MultiMap<uint, Condition> conditionReferenceStorage = new();
Dictionary<uint, MultiMap<uint, Condition>> VehicleSpellConditionStore = new(); Dictionary<uint, MultiMap<uint, Condition>> vehicleSpellConditionStorage = new();
Dictionary<uint, MultiMap<uint, Condition>> SpellClickEventConditionStore = new(); Dictionary<uint, MultiMap<uint, Condition>> spellClickEventConditionStorage = new();
Dictionary<uint, MultiMap<uint, Condition>> NpcVendorConditionContainerStore = new(); Dictionary<uint, MultiMap<uint, Condition>> npcVendorConditionContainerStorage = new();
Dictionary<Tuple<int, uint>, MultiMap<uint, Condition>> SmartEventConditionStore = new(); Dictionary<Tuple<int, uint>, MultiMap<uint, Condition>> smartEventConditionStorage = new();
MultiMap<Tuple<int, bool>, Condition> areaTriggerConditionContainerStorage = new();
public string[] StaticSourceTypeData = public string[] StaticSourceTypeData =
{ {
@@ -2433,7 +2456,9 @@ namespace Game
"Npc Vendor", "Npc Vendor",
"Spell Proc", "Spell Proc",
"Terrain Swap", "Terrain Swap",
"Phase" "Phase",
"Graveyard",
"AreaTrigger"
}; };
public ConditionTypeInfo[] StaticConditionTypeData = public ConditionTypeInfo[] StaticConditionTypeData =
@@ -355,6 +355,13 @@ namespace Game.Entities
break; break;
} }
if (GetTemplate() != null)
{
var conditions = Global.ConditionMgr.GetConditionsForAreaTrigger(GetTemplate().Id.Id, GetTemplate().Id.IsServerSide);
if (!conditions.Empty())
targetList.RemoveAll(target => !Global.ConditionMgr.IsObjectMeetToConditions(target, conditions));
}
HandleUnitEnterExit(targetList); HandleUnitEnterExit(targetList);
} }
@@ -0,0 +1,19 @@
--
SET @AREATRIGGERGUID := 3;
SET @AREATRIGGERID := 3;
DELETE FROM `areatrigger_template` WHERE `Id`=@AREATRIGGERID+0 AND `IsServerSide`=1;
INSERT INTO `areatrigger_template` (`Id`, `IsServerSide`, `Type`, `Flags`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `ScriptName`, `VerifiedBuild`) VALUES
(@AREATRIGGERID+0, 1, 4, 0, 4, 4, 6, 6, 0, 0, '', 0); -- Areatrigger to give Swear Fealty aura
DELETE FROM `areatrigger_template_actions` WHERE `AreaTriggerId`=@AREATRIGGERID+0 AND `IsServerSide`=1;
INSERT INTO `areatrigger_template_actions` (`AreaTriggerId`, `IsServerSide`, `ActionType`, `ActionParam`, `TargetType`) VALUES
(@AREATRIGGERID+0, 1, 0, 316884, 5);
DELETE FROM `areatrigger` WHERE `SpawnId`=@AREATRIGGERGUID+0;
INSERT INTO `areatrigger` (`SpawnId`, `AreaTriggerId`, `IsServerSide`, `MapId`, `PosX`, `PosY`, `PosZ`, `Orientation`, `PhaseUseFlags`, `PhaseId`, `PhaseGroup`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `Comment`) VALUES
(@AREATRIGGERGUID+0, @AREATRIGGERID+0, 1, 2297, 426.432281494140625, -2123.810791015625, 864.97430419921875, 3.191439628601074218, 0, 0, 0, 4, 4, 4, 6, 6, 0, 0, 'Allied Race DK Start ICC - Swear Fealty AT');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=28 AND `SourceGroup`=@AREATRIGGERID+0 AND `SourceEntry`=1;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `Comment`) VALUES
(28, @AREATRIGGERID+0, 1, 0, 9, 0, 58877, "Only trigger areatrigger when quest Death's Power Grows is taken");