Core/Db/Conditions: Add new condition types:
- CONDITION_OBJECT_ENTRY - CONDITION_TYPE_MASK - CONDITION_RELATION_TO - CONDITION_REACTION_TO - CONDITION_DISTANCE_TO - CONDITION_ALIVE - CONDITION_HP_VAL - CONDITION_HP_PCT
This commit is contained in:
@@ -217,26 +217,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
|
|||||||
case CONDITION_LEVEL:
|
case CONDITION_LEVEL:
|
||||||
{
|
{
|
||||||
if (Unit* unit = object->ToUnit())
|
if (Unit* unit = object->ToUnit())
|
||||||
{
|
condMeets = CompareValues(static_cast<ComparisionType>(mConditionValue2), static_cast<uint32>(unit->getLevel()), mConditionValue1);
|
||||||
switch (mConditionValue2)
|
|
||||||
{
|
|
||||||
case LVL_COND_EQ:
|
|
||||||
condMeets = unit->getLevel() == mConditionValue1;
|
|
||||||
break;
|
|
||||||
case LVL_COND_HIGH:
|
|
||||||
condMeets = unit->getLevel() > mConditionValue1;
|
|
||||||
break;
|
|
||||||
case LVL_COND_LOW:
|
|
||||||
condMeets = unit->getLevel() < mConditionValue1;
|
|
||||||
break;
|
|
||||||
case LVL_COND_HIGH_EQ:
|
|
||||||
condMeets = unit->getLevel() >= mConditionValue1;
|
|
||||||
break;
|
|
||||||
case LVL_COND_LOW_EQ:
|
|
||||||
condMeets = unit->getLevel() <= mConditionValue1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_DRUNKENSTATE:
|
case CONDITION_DRUNKENSTATE:
|
||||||
@@ -255,6 +236,82 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
|
|||||||
condMeets = GetClosestGameObjectWithEntry(object, mConditionValue1, (float)mConditionValue2) ? true : false;
|
condMeets = GetClosestGameObjectWithEntry(object, mConditionValue1, (float)mConditionValue2) ? true : false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CONDITION_OBJECT_ENTRY:
|
||||||
|
{
|
||||||
|
if (object->GetTypeId() == mConditionValue1)
|
||||||
|
condMeets = (!mConditionValue2) || (object->GetEntry() == mConditionValue2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_TYPE_MASK:
|
||||||
|
{
|
||||||
|
condMeets = object->isType(mConditionValue1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_RELATION_TO:
|
||||||
|
{
|
||||||
|
if (WorldObject* toObject = sourceInfo.mConditionTargets[mConditionValue1])
|
||||||
|
{
|
||||||
|
Unit* toUnit = toObject->ToUnit();
|
||||||
|
Unit* unit = object->ToUnit();
|
||||||
|
if (toUnit && unit)
|
||||||
|
{
|
||||||
|
switch (mConditionValue2)
|
||||||
|
{
|
||||||
|
case RELATION_SELF:
|
||||||
|
condMeets = unit == toUnit;
|
||||||
|
break;
|
||||||
|
case RELATION_IN_PARTY:
|
||||||
|
condMeets = unit->IsInPartyWith(toUnit);
|
||||||
|
break;
|
||||||
|
case RELATION_IN_RAID_OR_PARTY:
|
||||||
|
condMeets = unit->IsInRaidWith(toUnit);
|
||||||
|
break;
|
||||||
|
case RELATION_OWNED_BY:
|
||||||
|
condMeets = unit->GetOwnerGUID() == toUnit->GetGUID();
|
||||||
|
break;
|
||||||
|
case RELATION_PASSENGER_OF:
|
||||||
|
condMeets = unit->IsOnVehicle(toUnit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_REACTION_TO:
|
||||||
|
{
|
||||||
|
if (WorldObject* toObject = sourceInfo.mConditionTargets[mConditionValue1])
|
||||||
|
{
|
||||||
|
Unit* toUnit = toObject->ToUnit();
|
||||||
|
Unit* unit = object->ToUnit();
|
||||||
|
if (toUnit && unit)
|
||||||
|
condMeets = (1 << unit->GetReactionTo(toUnit)) & mConditionValue2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_DISTANCE_TO:
|
||||||
|
{
|
||||||
|
if (WorldObject* toObject = sourceInfo.mConditionTargets[mConditionValue1])
|
||||||
|
condMeets = CompareValues(static_cast<ComparisionType>(mConditionValue3), object->GetDistance(toObject), static_cast<float>(mConditionValue2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_ALIVE:
|
||||||
|
{
|
||||||
|
if (Unit* unit = object->ToUnit())
|
||||||
|
condMeets = unit->isAlive();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_HP_VAL:
|
||||||
|
{
|
||||||
|
if (Unit* unit = object->ToUnit())
|
||||||
|
condMeets = CompareValues(static_cast<ComparisionType>(mConditionValue2), unit->GetHealth(), static_cast<uint32>(mConditionValue1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_HP_PCT:
|
||||||
|
{
|
||||||
|
if (Unit* unit = object->ToUnit())
|
||||||
|
condMeets = CompareValues(static_cast<ComparisionType>(mConditionValue2), unit->GetHealthPct(), static_cast<float>(mConditionValue1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
condMeets = false;
|
condMeets = false;
|
||||||
break;
|
break;
|
||||||
@@ -270,6 +327,18 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
|
|||||||
return condMeets && script;
|
return condMeets && script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 Condition::GetMaxAvailableConditionTargets()
|
||||||
|
{
|
||||||
|
// returns number of targets which are available for given source type
|
||||||
|
switch(mSourceType)
|
||||||
|
{
|
||||||
|
case CONDITION_SOURCE_TYPE_SPELL:
|
||||||
|
return 2;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConditionMgr::ConditionMgr()
|
ConditionMgr::ConditionMgr()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -733,12 +802,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE:
|
||||||
@@ -756,12 +819,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE:
|
||||||
@@ -779,12 +836,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE:
|
||||||
@@ -802,12 +853,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE:
|
||||||
@@ -825,12 +870,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE:
|
||||||
@@ -848,12 +887,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE:
|
||||||
@@ -871,12 +904,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE:
|
||||||
@@ -894,12 +921,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE:
|
||||||
@@ -917,12 +938,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE:
|
||||||
@@ -940,12 +955,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE:
|
||||||
@@ -963,12 +972,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE:
|
case CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE:
|
||||||
@@ -986,12 +989,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET:
|
case CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET:
|
||||||
@@ -1061,12 +1058,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->mSourceEntry);
|
sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_SPELL:
|
case CONDITION_SOURCE_TYPE_SPELL:
|
||||||
@@ -1077,12 +1068,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->mSourceEntry);
|
sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget > 2)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_ITEM_REQUIRED_TARGET:
|
case CONDITION_SOURCE_TYPE_ITEM_REQUIRED_TARGET:
|
||||||
@@ -1127,12 +1112,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
", or the spells are already listed in CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET conditions.", cond->mSourceEntry);
|
", or the spells are already listed in CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET conditions.", cond->mSourceEntry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond->mConditionTarget > 2)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONDITION_SOURCE_TYPE_QUEST_ACCEPT:
|
case CONDITION_SOURCE_TYPE_QUEST_ACCEPT:
|
||||||
@@ -1141,11 +1120,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("CONDITION_SOURCE_TYPE_QUEST_ACCEPT specifies non-existing quest (%u), skipped", cond->mSourceEntry);
|
sLog->outErrorDb("CONDITION_SOURCE_TYPE_QUEST_ACCEPT specifies non-existing quest (%u), skipped", cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK:
|
case CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK:
|
||||||
if (!sObjectMgr->GetQuestTemplate(cond->mSourceEntry))
|
if (!sObjectMgr->GetQuestTemplate(cond->mSourceEntry))
|
||||||
@@ -1153,11 +1127,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK specifies non-existing quest (%u), skipped", cond->mSourceEntry);
|
sLog->outErrorDb("CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK specifies non-existing quest (%u), skipped", cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
|
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
|
||||||
if (!sObjectMgr->GetCreatureTemplate(cond->mSourceGroup))
|
if (!sObjectMgr->GetCreatureTemplate(cond->mSourceGroup))
|
||||||
@@ -1171,21 +1140,10 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->mSourceEntry);
|
sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->mSourceEntry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
|
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
|
||||||
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
|
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
|
||||||
case CONDITION_SOURCE_TYPE_SMART_EVENT:
|
case CONDITION_SOURCE_TYPE_SMART_EVENT:
|
||||||
if (cond->mConditionTarget)
|
|
||||||
{
|
|
||||||
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CONDITION_SOURCE_TYPE_NONE:
|
case CONDITION_SOURCE_TYPE_NONE:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -1201,6 +1159,12 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cond->mConditionTarget >= cond->GetMaxAvailableConditionTargets())
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->mSourceType, cond->mSourceEntry);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch (cond->mConditionType)
|
switch (cond->mConditionType)
|
||||||
{
|
{
|
||||||
case CONDITION_AURA:
|
case CONDITION_AURA:
|
||||||
@@ -1517,7 +1481,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
|
|||||||
}
|
}
|
||||||
case CONDITION_LEVEL:
|
case CONDITION_LEVEL:
|
||||||
{
|
{
|
||||||
if (cond->mConditionValue2 >= LVL_COND_MAX)
|
if (cond->mConditionValue2 >= COMP_TYPE_MAX)
|
||||||
{
|
{
|
||||||
sLog->outErrorDb("Level condition has invalid option (%u), skipped", cond->mConditionValue2);
|
sLog->outErrorDb("Level condition has invalid option (%u), skipped", cond->mConditionValue2);
|
||||||
return false;
|
return false;
|
||||||
@@ -1564,6 +1528,146 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
|
|||||||
sLog->outErrorDb("NearGameObject condition has useless data in value3 (%u)!", cond->mConditionValue3);
|
sLog->outErrorDb("NearGameObject condition has useless data in value3 (%u)!", cond->mConditionValue3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CONDITION_OBJECT_ENTRY:
|
||||||
|
{
|
||||||
|
switch (cond->mConditionValue1)
|
||||||
|
{
|
||||||
|
case TYPEID_UNIT:
|
||||||
|
if (cond->mConditionValue2 && !sObjectMgr->GetCreatureTemplate(cond->mConditionValue2))
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("ObjectEntry condition has non existing creature template entry (%u), skipped", cond->mConditionValue2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPEID_GAMEOBJECT:
|
||||||
|
if (cond->mConditionValue2 && !sObjectMgr->GetGameObjectTemplate(cond->mConditionValue2))
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("ObjectEntry condition has non existing game object template entry (%u), skipped", cond->mConditionValue2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPEID_PLAYER:
|
||||||
|
case TYPEID_CORPSE:
|
||||||
|
if (cond->mConditionValue2)
|
||||||
|
sLog->outErrorDb("ObjectEntry condition has useless data in value2 (%u)!", cond->mConditionValue2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sLog->outErrorDb("ObjectEntry condition has wrong typeid set (%u), skipped", cond->mConditionValue1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue3)
|
||||||
|
sLog->outErrorDb("ObjectEntry condition has useless data in value3 (%u)!", cond->mConditionValue3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_TYPE_MASK:
|
||||||
|
{
|
||||||
|
if (!cond->mConditionValue1 || (cond->mConditionValue1 & ~(TYPEMASK_UNIT | TYPEMASK_PLAYER | TYPEMASK_GAMEOBJECT | TYPEMASK_CORPSE)))
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("TypeMask condition has invalid typemask set (%u), skipped", cond->mConditionValue2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue2)
|
||||||
|
sLog->outErrorDb("TypeMask condition has useless data in value2 (%u)!", cond->mConditionValue2);
|
||||||
|
if (cond->mConditionValue3)
|
||||||
|
sLog->outErrorDb("TypeMask condition has useless data in value3 (%u)!", cond->mConditionValue3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_RELATION_TO:
|
||||||
|
{
|
||||||
|
if (cond->mConditionValue1 >= cond->GetMaxAvailableConditionTargets())
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("RelationTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->mConditionValue1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue1 == cond->mConditionTarget)
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("RelationTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->mConditionValue1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue2 >= RELATION_MAX)
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("RelationTo condition has invalid ConditionValue2(RelationType) (%u), skipped", cond->mConditionValue2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue3)
|
||||||
|
sLog->outErrorDb("RelationTo condition has useless data in value3 (%u)!", cond->mConditionValue3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_REACTION_TO:
|
||||||
|
{
|
||||||
|
if (cond->mConditionValue1 >= cond->GetMaxAvailableConditionTargets())
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("ReactionTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->mConditionValue1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue1 == cond->mConditionTarget)
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("ReactionTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->mConditionValue1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!cond->mConditionValue2)
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("mConditionValue2 condition has invalid ConditionValue2(rankMask) (%u), skipped", cond->mConditionValue2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_DISTANCE_TO:
|
||||||
|
{
|
||||||
|
if (cond->mConditionValue1 >= cond->GetMaxAvailableConditionTargets())
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("DistanceTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->mConditionValue1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue1 == cond->mConditionTarget)
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("DistanceTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->mConditionValue1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue3 >= COMP_TYPE_MAX)
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("DistanceTo condition has invalid ComparisionType (%u), skipped", cond->mConditionValue3);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_ALIVE:
|
||||||
|
{
|
||||||
|
if (cond->mConditionValue1)
|
||||||
|
sLog->outErrorDb("Alive condition has useless data in value1 (%u)!", cond->mConditionValue1);
|
||||||
|
if (cond->mConditionValue2)
|
||||||
|
sLog->outErrorDb("Alive condition has useless data in value2 (%u)!", cond->mConditionValue2);
|
||||||
|
if (cond->mConditionValue3)
|
||||||
|
sLog->outErrorDb("Alive condition has useless data in value3 (%u)!", cond->mConditionValue3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_HP_VAL:
|
||||||
|
{
|
||||||
|
if (cond->mConditionValue2 >= COMP_TYPE_MAX)
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("HpVal condition has invalid ComparisionType (%u), skipped", cond->mConditionValue2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue3)
|
||||||
|
sLog->outErrorDb("HpVal condition has useless data in value3 (%u)!", cond->mConditionValue3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONDITION_HP_PCT:
|
||||||
|
{
|
||||||
|
if (cond->mConditionValue1 > 100)
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("HpPct condition has too big percent value (%u), skipped", cond->mConditionValue1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue2 >= COMP_TYPE_MAX)
|
||||||
|
{
|
||||||
|
sLog->outErrorDb("HpPct condition has invalid ComparisionType (%u), skipped", cond->mConditionValue2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cond->mConditionValue3)
|
||||||
|
sLog->outErrorDb("HpPct condition has useless data in value3 (%u)!", cond->mConditionValue3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CONDITION_AREAID:
|
case CONDITION_AREAID:
|
||||||
case CONDITION_INSTANCE_DATA:
|
case CONDITION_INSTANCE_DATA:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ enum ConditionType
|
|||||||
CONDITION_ITEM = 2, // item_id count bank true if has #count of item_ids (if 'bank' is set it searches in bank slots too)
|
CONDITION_ITEM = 2, // item_id count bank true if has #count of item_ids (if 'bank' is set it searches in bank slots too)
|
||||||
CONDITION_ITEM_EQUIPPED = 3, // item_id 0 0 true if has item_id equipped
|
CONDITION_ITEM_EQUIPPED = 3, // item_id 0 0 true if has item_id equipped
|
||||||
CONDITION_ZONEID = 4, // zone_id 0 0 true if in zone_id
|
CONDITION_ZONEID = 4, // zone_id 0 0 true if in zone_id
|
||||||
CONDITION_REPUTATION_RANK = 5, // faction_id min_rank 0 true if has min_rank for faction_id
|
CONDITION_REPUTATION_RANK = 5, // faction_id rankMask 0 true if has min_rank for faction_id
|
||||||
CONDITION_TEAM = 6, // player_team 0, 0 469 - Alliance, 67 - Horde)
|
CONDITION_TEAM = 6, // player_team 0, 0 469 - Alliance, 67 - Horde)
|
||||||
CONDITION_SKILL = 7, // skill_id skill_value 0 true if has skill_value for skill_id
|
CONDITION_SKILL = 7, // skill_id skill_value 0 true if has skill_value for skill_id
|
||||||
CONDITION_QUESTREWARDED = 8, // quest_id 0 0 true if quest_id was rewarded before
|
CONDITION_QUESTREWARDED = 8, // quest_id 0 0 true if quest_id was rewarded before
|
||||||
@@ -57,21 +57,19 @@ enum ConditionType
|
|||||||
CONDITION_ITEM_TARGET = 24, // ItemRequiredTargetType, TargetEntry, 0
|
CONDITION_ITEM_TARGET = 24, // ItemRequiredTargetType, TargetEntry, 0
|
||||||
CONDITION_SPELL = 25, // spell_id 0 0 true if player has learned spell
|
CONDITION_SPELL = 25, // spell_id 0 0 true if player has learned spell
|
||||||
CONDITION_UNUSED_26 = 26,
|
CONDITION_UNUSED_26 = 26,
|
||||||
CONDITION_LEVEL = 27, // level opt 0 true if unit's level is equal to param1 (param2 can modify the statement)
|
CONDITION_LEVEL = 27, // level ComparisonType 0 true if unit's level is equal to param1 (param2 can modify the statement)
|
||||||
CONDITION_QUEST_COMPLETE = 28, // quest_id 0 0 true if player has quest_id with all objectives complete, but not yet rewarded
|
CONDITION_QUEST_COMPLETE = 28, // quest_id 0 0 true if player has quest_id with all objectives complete, but not yet rewarded
|
||||||
CONDITION_NEAR_CREATURE = 29, // creature entry distance 0 true if there is a creature of entry in range
|
CONDITION_NEAR_CREATURE = 29, // creature entry distance 0 true if there is a creature of entry in range
|
||||||
CONDITION_NEAR_GAMEOBJECT = 30, // gameobject entry distance 0 true if there is a gameobject of entry in range
|
CONDITION_NEAR_GAMEOBJECT = 30, // gameobject entry distance 0 true if there is a gameobject of entry in range
|
||||||
CONDITION_MAX = 31 // MAX
|
CONDITION_OBJECT_ENTRY = 31, // TypeID entry 0 true if object is type TypeID and the entry is 0 or matches entry of the object
|
||||||
};
|
CONDITION_TYPE_MASK = 32, // TypeMask 0 0 true if object is type object's TypeMask matches provided TypeMask
|
||||||
|
CONDITION_RELATION_TO = 33, // ConditionTarget RelationType 0 true if object is in given relation with object specified by ConditionTarget
|
||||||
enum LevelConditionType
|
CONDITION_REACTION_TO = 34, // ConditionTarget rankMask 0 true if object's reaction matches rankMask object specified by ConditionTarget
|
||||||
{
|
CONDITION_DISTANCE_TO = 35, // ConditionTarget distance ComparisonType true if object and ConditionTarget are within distance given by parameters
|
||||||
LVL_COND_EQ,
|
CONDITION_ALIVE = 36, // 0 0 0 true if unit is alive
|
||||||
LVL_COND_HIGH,
|
CONDITION_HP_VAL = 37, // hpVal ComparisonType 0 true if unit's hp matches given value
|
||||||
LVL_COND_LOW,
|
CONDITION_HP_PCT = 38, // hpPct ComparisonType 0 true if unit's hp matches given pct
|
||||||
LVL_COND_HIGH_EQ,
|
CONDITION_MAX = 39 // MAX
|
||||||
LVL_COND_LOW_EQ,
|
|
||||||
LVL_COND_MAX
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ConditionSourceType
|
enum ConditionSourceType
|
||||||
@@ -102,6 +100,26 @@ enum ConditionSourceType
|
|||||||
CONDITION_SOURCE_TYPE_MAX = 23 //MAX
|
CONDITION_SOURCE_TYPE_MAX = 23 //MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ComparisionType
|
||||||
|
{
|
||||||
|
COMP_TYPE_EQ = 0,
|
||||||
|
COMP_TYPE_HIGH,
|
||||||
|
COMP_TYPE_LOW,
|
||||||
|
COMP_TYPE_HIGH_EQ,
|
||||||
|
COMP_TYPE_LOW_EQ,
|
||||||
|
COMP_TYPE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RelationType
|
||||||
|
{
|
||||||
|
RELATION_SELF = 0,
|
||||||
|
RELATION_IN_PARTY,
|
||||||
|
RELATION_IN_RAID_OR_PARTY,
|
||||||
|
RELATION_OWNED_BY,
|
||||||
|
RELATION_PASSENGER_OF,
|
||||||
|
RELATION_MAX
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MAX_CONDITION_TARGETS = 3,
|
MAX_CONDITION_TARGETS = 3,
|
||||||
@@ -109,7 +127,7 @@ enum
|
|||||||
|
|
||||||
struct ConditionSourceInfo
|
struct ConditionSourceInfo
|
||||||
{
|
{
|
||||||
WorldObject* mConditionTargets[MAX_CONDITION_TARGETS];
|
WorldObject* mConditionTargets[MAX_CONDITION_TARGETS]; // an array of targets available for conditions
|
||||||
Condition* mLastFailedCondition;
|
Condition* mLastFailedCondition;
|
||||||
ConditionSourceInfo(WorldObject* target0, WorldObject* target1 = NULL, WorldObject* target2 = NULL)
|
ConditionSourceInfo(WorldObject* target0, WorldObject* target1 = NULL, WorldObject* target2 = NULL)
|
||||||
{
|
{
|
||||||
@@ -156,6 +174,7 @@ struct Condition
|
|||||||
|
|
||||||
bool Meets(ConditionSourceInfo& sourceInfo);
|
bool Meets(ConditionSourceInfo& sourceInfo);
|
||||||
bool isLoaded() const { return mConditionType > CONDITION_NONE || mReferenceId; }
|
bool isLoaded() const { return mConditionType > CONDITION_NONE || mReferenceId; }
|
||||||
|
uint32 GetMaxAvailableConditionTargets();
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<Condition*> ConditionList;
|
typedef std::list<Condition*> ConditionList;
|
||||||
@@ -221,6 +240,26 @@ class ConditionMgr
|
|||||||
SmartEventConditionContainer SmartEventConditionStore;
|
SmartEventConditionContainer SmartEventConditionStore;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T> bool CompareValues(ComparisionType type, T val1, T val2)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case COMP_TYPE_EQ:
|
||||||
|
return val1 == val2;
|
||||||
|
case COMP_TYPE_HIGH:
|
||||||
|
return val1 > val2;
|
||||||
|
case COMP_TYPE_LOW:
|
||||||
|
return val1 < val2;
|
||||||
|
case COMP_TYPE_HIGH_EQ:
|
||||||
|
return val1 >= val2;
|
||||||
|
case COMP_TYPE_LOW_EQ:
|
||||||
|
return val1 <= val2;
|
||||||
|
}
|
||||||
|
// incorrect parameter
|
||||||
|
ASSERT(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#define sConditionMgr ACE_Singleton<ConditionMgr, ACE_Null_Mutex>::instance()
|
#define sConditionMgr ACE_Singleton<ConditionMgr, ACE_Null_Mutex>::instance()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ enum TypeMask
|
|||||||
TYPEMASK_OBJECT = 0x0001,
|
TYPEMASK_OBJECT = 0x0001,
|
||||||
TYPEMASK_ITEM = 0x0002,
|
TYPEMASK_ITEM = 0x0002,
|
||||||
TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004
|
TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004
|
||||||
TYPEMASK_UNIT = 0x0008, //creature or player
|
TYPEMASK_UNIT = 0x0008, // creature
|
||||||
TYPEMASK_PLAYER = 0x0010,
|
TYPEMASK_PLAYER = 0x0010,
|
||||||
TYPEMASK_GAMEOBJECT = 0x0020,
|
TYPEMASK_GAMEOBJECT = 0x0020,
|
||||||
TYPEMASK_DYNAMICOBJECT = 0x0040,
|
TYPEMASK_DYNAMICOBJECT = 0x0040,
|
||||||
|
|||||||
Reference in New Issue
Block a user