Core/Conditions: Added stringid condition type

(cherry picked from commit 151dd67e2e)
This commit is contained in:
Shauren
2024-01-12 12:40:20 +01:00
parent 9e89a4dd71
commit 4fd3669f1b
3 changed files with 92 additions and 60 deletions

View File

@@ -0,0 +1,3 @@
ALTER TABLE `conditions` DROP PRIMARY KEY;
ALTER TABLE `conditions` ADD `ConditionStringValue1` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' AFTER `ConditionValue3`;
ALTER TABLE `conditions` ADD PRIMARY KEY (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`ConditionStringValue1`);

View File

@@ -67,59 +67,65 @@ char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX]
ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[CONDITION_MAX] =
{
{ "None", false, false, false },
{ "Aura", true, true, true },
{ "Item Stored", true, true, true },
{ "Item Equipped", true, false, false },
{ "Zone", true, false, false },
{ "Reputation", true, true, false },
{ "Team", true, false, false },
{ "Skill", true, true, false },
{ "Quest Rewarded", true, false, false },
{ "Quest Taken", true, false, false },
{ "Drunken", true, false, false },
{ "WorldState", true, true, false },
{ "Active Event", true, false, false },
{ "Instance Info", true, true, true },
{ "Quest None", true, false, false },
{ "Class", true, false, false },
{ "Race", true, false, false },
{ "Achievement", true, false, false },
{ "Title", true, false, false },
{ "SpawnMask", true, false, false },
{ "Gender", true, false, false },
{ "Unit State", true, false, false },
{ "Map", true, false, false },
{ "Area", true, false, false },
{ "CreatureType", true, false, false },
{ "Spell Known", true, false, false },
{ "PhaseMask", true, false, false },
{ "Level", true, true, false },
{ "Quest Completed", true, false, false },
{ "Near Creature", true, true, true },
{ "Near GameObject", true, true, false },
{ "Object Entry or Guid", true, true, true },
{ "Object TypeMask", true, false, false },
{ "Relation", true, true, false },
{ "Reaction", true, true, false },
{ "Distance", true, true, true },
{ "Alive", false, false, false },
{ "Health Value", true, true, false },
{ "Health Pct", true, true, false },
{ "Realm Achievement", true, false, false },
{ "In Water", false, false, false },
{ "Terrain Swap", false, false, false },
{ "Sit/stand state", true, true, false },
{ "Daily Quest Completed", true, false, false },
{ "Charmed", false, false, false },
{ "Pet type", true, false, false },
{ "On Taxi", false, false, false },
{ "Quest state mask", true, true, false },
{ "Quest objective progress", true, true, true },
{ "Map difficulty", true, false, false },
{ "Is Gamemaster", true, false, false },
{ "Object Entry or Guid", true, true, true },
{ "Object TypeMask", true, false, false }
{ "None", false, false, false, false },
{ "Aura", true, true, true, false },
{ "Item Stored", true, true, true, false },
{ "Item Equipped", true, false, false, false },
{ "Zone", true, false, false, false },
{ "Reputation", true, true, false, false },
{ "Team", true, false, false, false },
{ "Skill", true, true, false, false },
{ "Quest Rewarded", true, false, false, false },
{ "Quest Taken", true, false, false, false },
{ "Drunken", true, false, false, false },
{ "WorldState", true, true, false, false },
{ "Active Event", true, false, false, false },
{ "Instance Info", true, true, true, false },
{ "Quest None", true, false, false, false },
{ "Class", true, false, false, false },
{ "Race", true, false, false, false },
{ "Achievement", true, false, false, false },
{ "Title", true, false, false, false },
{ "SpawnMask", true, false, false, false },
{ "Gender", true, false, false, false },
{ "Unit State", true, false, false, false },
{ "Map", true, false, false, false },
{ "Area", true, false, false, false },
{ "CreatureType", true, false, false, false },
{ "Spell Known", true, false, false, false },
{ "PhaseMask", true, false, false, false },
{ "Level", true, true, false, false },
{ "Quest Completed", true, false, false, false },
{ "Near Creature", true, true, true, false },
{ "Near GameObject", true, true, false, false },
{ "Object Entry or Guid", true, true, true, false },
{ "Object TypeMask", true, false, false, false },
{ "Relation", true, true, false, false },
{ "Reaction", true, true, false, false },
{ "Distance", true, true, true, false },
{ "Alive", false, false, false, false },
{ "Health Value", true, true, false, false },
{ "Health Pct", true, true, false, false },
{ "Realm Achievement", true, false, false, false },
{ "In Water", false, false, false, false },
{ "Terrain Swap", false, false, false, false },
{ "Sit/stand state", true, true, false, false },
{ "Daily Quest Completed", true, false, false, false },
{ "Charmed", false, false, false, false },
{ "Pet type", true, false, false, false },
{ "On Taxi", false, false, false, false },
{ "Quest state mask", true, true, false, false },
{ "Quest objective progress", true, true, true, false },
{ "Map Difficulty", true, false, false, false },
{ "Is Gamemaster", true, false, false, false },
{ "Object Entry or Guid", true, true, true, false },
{ "Object TypeMask", true, false, false, false },
{ "BattlePet Species Learned", true, true, true, false },
{ "On Scenario Step", true, false, false, false },
{ "Scene In Progress", true, false, false, false },
{ "Player Condition", true, false, false, false },
{ "String ID", false, false, false, true },
{ "Label", false, false, false, false },
};
// Checks if object meets the condition
@@ -533,6 +539,14 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const
}
break;
}
case CONDITION_STRING_ID:
{
if (Creature const* creature = object->ToCreature())
condMeets = creature->HasStringId(ConditionStringValue1);
else if (GameObject const* go = object->ToGameObject())
condMeets = go->HasStringId(ConditionStringValue1);
break;
}
default:
condMeets = false;
break;
@@ -1079,7 +1093,8 @@ void ConditionMgr::LoadConditions(bool isReload)
}
QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, "
" ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition, ErrorType, ErrorTextId, ScriptName FROM conditions");
"ConditionValue1, ConditionValue2, ConditionValue3, ConditionStringValue1, "
"NegativeCondition, ErrorType, ErrorTextId, ScriptName FROM conditions");
if (!result)
{
@@ -1104,10 +1119,11 @@ void ConditionMgr::LoadConditions(bool isReload)
cond->ConditionValue1 = fields[7].GetUInt32();
cond->ConditionValue2 = fields[8].GetUInt32();
cond->ConditionValue3 = fields[9].GetUInt32();
cond->NegativeCondition = fields[10].GetBool();
cond->ErrorType = fields[11].GetUInt32();
cond->ErrorTextId = fields[12].GetUInt32();
cond->ScriptId = sObjectMgr->GetScriptId(fields[13].GetString());
cond->ConditionStringValue1 = fields[10].GetString();
cond->NegativeCondition = fields[11].GetBool();
cond->ErrorType = fields[12].GetUInt32();
cond->ErrorTextId = fields[13].GetUInt32();
cond->ScriptId = sObjectMgr->GetScriptId(fields[14].GetString());
if (iConditionTypeOrReference >= 0)
cond->ConditionType = ConditionTypes(iConditionTypeOrReference);
@@ -2392,15 +2408,22 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) const
LogUselessConditionValue(cond, 2, cond->ConditionValue2);
if (cond->ConditionValue3 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue3)
LogUselessConditionValue(cond, 3, cond->ConditionValue3);
if (!cond->ConditionStringValue1.empty() && !StaticConditionTypeData[cond->ConditionType].HasConditionStringValue1)
LogUselessConditionValue(cond, 1, cond->ConditionStringValue1);
return true;
}
void ConditionMgr::LogUselessConditionValue(Condition* cond, uint8 index, uint32 value)
void ConditionMgr::LogUselessConditionValue(Condition const* cond, uint8 index, uint32 value)
{
TC_LOG_ERROR("sql.sql", "{} has useless data in ConditionValue{} ({})!", cond->ToString(true), index, value);
}
void ConditionMgr::LogUselessConditionValue(Condition const* cond, uint8 index, std::string_view value)
{
TC_LOG_ERROR("sql.sql", "{} has useless data in ConditionStringValue{} ({})!", cond->ToString(true), index, value);
}
void ConditionMgr::Clean()
{
for (ConditionReferenceContainer::iterator itr = ConditionReferenceStore.begin(); itr != ConditionReferenceStore.end(); ++itr)

View File

@@ -92,6 +92,9 @@ enum ConditionTypes
CONDITION_SCENARIO_STEP = 54, // ScenarioStepId 0 0 true if player is at scenario with current step equal to ScenarioStepID
CONDITION_SCENE_IN_PROGRESS = 55, // SceneScriptPackageId 0 0 true if player is playing a scene with ScriptPackageId equal to given value
CONDITION_PLAYER_CONDITION = 56, // PlayerConditionId 0 0 true if player satisfies PlayerCondition
CONDITION_PRIVATE_OBJECT = 57, // 0 0 0 true if entity is private object
CONDITION_STRING_ID = 58,
CONDITION_LABEL = 59, // only for master branch
CONDITION_MAX
};
@@ -209,6 +212,7 @@ struct TC_GAME_API Condition
uint32 ConditionValue1;
uint32 ConditionValue2;
uint32 ConditionValue3;
std::string ConditionStringValue1;
uint32 ErrorType;
uint32 ErrorTextId;
uint32 ReferenceId;
@@ -285,6 +289,7 @@ class TC_GAME_API ConditionMgr
bool HasConditionValue1;
bool HasConditionValue2;
bool HasConditionValue3;
bool HasConditionStringValue1;
};
static char const* const StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX];
static ConditionTypeInfo const StaticConditionTypeData[CONDITION_MAX];
@@ -297,7 +302,8 @@ class TC_GAME_API ConditionMgr
bool addToSpellImplicitTargetConditions(Condition* cond) const;
bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionContainer const& conditions) const;
static void LogUselessConditionValue(Condition* cond, uint8 index, uint32 value);
static void LogUselessConditionValue(Condition const* cond, uint8 index, uint32 value);
static void LogUselessConditionValue(Condition const* cond, uint8 index, std::string_view value);
void Clean(); // free up resources
std::vector<Condition*> AllocatedMemoryStore; // some garbage collection :)