Core/Db/Conditions: Add ContidionTarget column which allows selection of objects which will be checked by condition, depending on SourceTypeOrReferenceId.
So far usable only with CONDITION_SOURCE_TYPE_SPELL: ContidionTarget = 0 - check caster ContidionTarget = 1 - check explicit target
This commit is contained in:
@@ -1338,7 +1338,7 @@ void CreatureEventAI::ReceiveEmote(Player* player, uint32 textEmote)
|
||||
cond.mConditionValue1 = (*itr).Event.receive_emote.conditionValue1;
|
||||
cond.mConditionValue2 = (*itr).Event.receive_emote.conditionValue2;
|
||||
|
||||
if (cond.Meets(player))
|
||||
if (cond.Meets(ConditionSourceInfo(player)))
|
||||
{
|
||||
sLog->outDebug(LOG_FILTER_DATABASE_AI, "CreatureEventAI: ReceiveEmote CreatureEventAI: Condition ok, processing");
|
||||
ProcessEvent(*itr, player);
|
||||
|
||||
@@ -2783,6 +2783,18 @@ void SmartScript::InstallEvents()
|
||||
}
|
||||
}
|
||||
|
||||
bool SmartScript::ConditionValid(Unit* u, int32 c, int32 v1, int32 v2, int32 v3)
|
||||
{
|
||||
if (c == 0) return true;
|
||||
if (!u || !u->ToPlayer()) return false;
|
||||
Condition cond;
|
||||
cond.mConditionType = ConditionType(uint32(c));
|
||||
cond.mConditionValue1 = uint32(v1);
|
||||
cond.mConditionValue1 = uint32(v2);
|
||||
cond.mConditionValue1 = uint32(v3);
|
||||
return cond.Meets(ConditionSourceInfo(u->ToPlayer()));
|
||||
}
|
||||
|
||||
void SmartScript::OnUpdate(uint32 const diff)
|
||||
{
|
||||
if ((mScriptType == SMART_SCRIPT_TYPE_CREATURE || mScriptType == SMART_SCRIPT_TYPE_GAMEOBJECT) && !GetBaseObject())
|
||||
|
||||
@@ -84,17 +84,7 @@ class SmartScript
|
||||
return obj && obj->GetTypeId() == TYPEID_GAMEOBJECT;
|
||||
}
|
||||
|
||||
bool ConditionValid(Unit* u, int32 c, int32 v1, int32 v2, int32 v3)
|
||||
{
|
||||
if (c == 0) return true;
|
||||
if (!u || !u->ToPlayer()) return false;
|
||||
Condition cond;
|
||||
cond.mConditionType = ConditionType(uint32(c));
|
||||
cond.mConditionValue1 = uint32(v1);
|
||||
cond.mConditionValue1 = uint32(v2);
|
||||
cond.mConditionValue1 = uint32(v3);
|
||||
return cond.Meets(u->ToPlayer());
|
||||
}
|
||||
bool ConditionValid(Unit* u, int32 c, int32 v1, int32 v2, int32 v3);
|
||||
|
||||
void OnUpdate(const uint32 diff);
|
||||
void OnMoveInLineOfSight(Unit* who);
|
||||
|
||||
@@ -29,8 +29,10 @@
|
||||
|
||||
// Checks if object meets the condition
|
||||
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI)
|
||||
bool Condition::Meets(WorldObject* object, WorldObject* invoker)
|
||||
bool Condition::Meets(ConditionSourceInfo& sourceInfo)
|
||||
{
|
||||
ASSERT(mConditionTarget < MAX_CONDITION_TARGETS);
|
||||
WorldObject* object = sourceInfo.mConditionTargets[mConditionTarget];
|
||||
// object not present, return false
|
||||
if (!object)
|
||||
{
|
||||
@@ -257,24 +259,14 @@ bool Condition::Meets(WorldObject* object, WorldObject* invoker)
|
||||
condMeets = false;
|
||||
break;
|
||||
}
|
||||
switch (mSourceType)
|
||||
{
|
||||
case CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET:
|
||||
case CONDITION_SOURCE_TYPE_SPELL:
|
||||
sendErrorMsg = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (mNegativeCondition)
|
||||
condMeets = !condMeets;
|
||||
|
||||
if (Player* player = object->ToPlayer())
|
||||
if (sendErrorMsg && ErrorTextd && (!condMeets))//send special error from DB
|
||||
player->m_ConditionErrorMsgId = ErrorTextd;
|
||||
if (!condMeets)
|
||||
sourceInfo.mLastFailedCondition = this;
|
||||
|
||||
bool script = sScriptMgr->OnConditionCheck(this, object, invoker); // Returns true by default.
|
||||
bool script = sScriptMgr->OnConditionCheck(this, sourceInfo); // Returns true by default.
|
||||
return condMeets && script;
|
||||
}
|
||||
|
||||
@@ -296,7 +288,7 @@ ConditionList ConditionMgr::GetConditionReferences(uint32 refId)
|
||||
return conditions;
|
||||
}
|
||||
|
||||
bool ConditionMgr::IsObjectMeetToConditionList(WorldObject* object, ConditionList const& conditions, WorldObject* invoker /*= NULL*/)
|
||||
bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions)
|
||||
{
|
||||
std::map<uint32, bool> ElseGroupStore;
|
||||
for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
|
||||
@@ -315,7 +307,7 @@ bool ConditionMgr::IsObjectMeetToConditionList(WorldObject* object, ConditionLis
|
||||
ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find((*i)->mReferenceId);
|
||||
if (ref != ConditionReferenceStore.end())
|
||||
{
|
||||
if (!IsObjectMeetToConditionList(object, (*ref).second, invoker))
|
||||
if (!IsObjectMeetToConditionList(sourceInfo, (*ref).second))
|
||||
ElseGroupStore[(*i)->mElseGroup] = false;
|
||||
}
|
||||
else
|
||||
@@ -327,7 +319,7 @@ bool ConditionMgr::IsObjectMeetToConditionList(WorldObject* object, ConditionLis
|
||||
}
|
||||
else //handle normal condition
|
||||
{
|
||||
if (!(*i)->Meets(object, invoker))
|
||||
if (!(*i)->Meets(sourceInfo))
|
||||
ElseGroupStore[(*i)->mElseGroup] = false;
|
||||
}
|
||||
}
|
||||
@@ -339,23 +331,18 @@ bool ConditionMgr::IsObjectMeetToConditionList(WorldObject* object, ConditionLis
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions, WorldObject* invoker /*= NULL*/)
|
||||
bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions)
|
||||
{
|
||||
return IsObjectMeetToConditions(ConditionSourceInfo(object), conditions);
|
||||
}
|
||||
|
||||
bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions)
|
||||
{
|
||||
if (conditions.empty())
|
||||
return true;
|
||||
|
||||
Player* player = object ? object->ToPlayer() : NULL;
|
||||
|
||||
if (player)
|
||||
player->m_ConditionErrorMsgId = 0;
|
||||
|
||||
sLog->outDebug(LOG_FILTER_CONDITIONSYS, "ConditionMgr::IsPlayerMeetToConditions");
|
||||
bool result = IsObjectMeetToConditionList(player, conditions, invoker);
|
||||
|
||||
if (player && player->m_ConditionErrorMsgId && player->GetSession() && !result)
|
||||
player->GetSession()->SendNotification(player->m_ConditionErrorMsgId); //m_ConditionErrorMsgId is set only if a condition was not met
|
||||
|
||||
return result;
|
||||
sLog->outDebug(LOG_FILTER_CONDITIONSYS, "ConditionMgr::IsObjectMeetToConditions");
|
||||
return IsObjectMeetToConditionList(sourceInfo, conditions);
|
||||
}
|
||||
|
||||
ConditionList ConditionMgr::GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry)
|
||||
@@ -439,7 +426,7 @@ void ConditionMgr::LoadConditions(bool isReload)
|
||||
sObjectMgr->LoadGossipMenuItems();
|
||||
}
|
||||
|
||||
QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, "
|
||||
QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, "
|
||||
" ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition, ErrorTextId, ScriptName FROM conditions");
|
||||
|
||||
if (!result)
|
||||
@@ -463,12 +450,13 @@ void ConditionMgr::LoadConditions(bool isReload)
|
||||
cond->mSourceId = fields[3].GetUInt32();
|
||||
cond->mElseGroup = fields[4].GetUInt32();
|
||||
int32 iConditionTypeOrReference = fields[5].GetInt32();
|
||||
cond->mConditionValue1 = fields[6].GetUInt32();
|
||||
cond->mConditionValue2 = fields[7].GetUInt32();
|
||||
cond->mConditionValue3 = fields[8].GetUInt32();
|
||||
cond->mNegativeCondition = fields[9].GetUInt8();
|
||||
cond->ErrorTextd = fields[10].GetUInt32();
|
||||
cond->mScriptId = sObjectMgr->GetScriptId(fields[11].GetCString());
|
||||
cond->mConditionTarget = fields[6].GetUInt8();
|
||||
cond->mConditionValue1 = fields[7].GetUInt32();
|
||||
cond->mConditionValue2 = fields[8].GetUInt32();
|
||||
cond->mConditionValue3 = fields[9].GetUInt32();
|
||||
cond->mNegativeCondition = fields[10].GetUInt8();
|
||||
cond->ErrorTextd = fields[11].GetUInt32();
|
||||
cond->mScriptId = sObjectMgr->GetScriptId(fields[12].GetCString());
|
||||
|
||||
if (iConditionTypeOrReference >= 0)
|
||||
cond->mConditionType = ConditionType(iConditionTypeOrReference);
|
||||
@@ -487,6 +475,8 @@ void ConditionMgr::LoadConditions(bool isReload)
|
||||
if (iSourceTypeOrReferenceId >= 0)
|
||||
rowType = "reference";
|
||||
//check for useless data
|
||||
if (cond->mConditionTarget)
|
||||
sLog->outErrorDb("Condition %s %i has useless data in ConditionTarget (%u)!", rowType, iSourceTypeOrReferenceId, cond->mConditionTarget);
|
||||
if (cond->mConditionValue1)
|
||||
sLog->outErrorDb("Condition %s %i has useless data in value1 (%u)!", rowType, iSourceTypeOrReferenceId, cond->mConditionValue1);
|
||||
if (cond->mConditionValue2)
|
||||
@@ -742,6 +732,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE:
|
||||
@@ -759,6 +755,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE:
|
||||
@@ -776,6 +778,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE:
|
||||
@@ -793,6 +801,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE:
|
||||
@@ -810,6 +824,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE:
|
||||
@@ -827,6 +847,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE:
|
||||
@@ -844,6 +870,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE:
|
||||
@@ -861,6 +893,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE:
|
||||
@@ -878,6 +916,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE:
|
||||
@@ -895,6 +939,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE:
|
||||
@@ -912,6 +962,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE:
|
||||
@@ -929,6 +985,12 @@ 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);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET:
|
||||
@@ -998,6 +1060,12 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
||||
sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->mSourceEntry);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_SPELL:
|
||||
@@ -1008,6 +1076,12 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
||||
sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->mSourceEntry);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_ITEM_REQUIRED_TARGET:
|
||||
@@ -1052,6 +1126,12 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
||||
", or the spells are already listed in CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET conditions.", cond->mSourceEntry);
|
||||
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;
|
||||
}
|
||||
case CONDITION_SOURCE_TYPE_QUEST_ACCEPT:
|
||||
@@ -1060,6 +1140,11 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
||||
sLog->outErrorDb("CONDITION_SOURCE_TYPE_QUEST_ACCEPT specifies non-existing quest (%u), skipped", cond->mSourceEntry);
|
||||
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;
|
||||
case CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK:
|
||||
if (!sObjectMgr->GetQuestTemplate(cond->mSourceEntry))
|
||||
@@ -1067,6 +1152,11 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
||||
sLog->outErrorDb("CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK specifies non-existing quest (%u), skipped", cond->mSourceEntry);
|
||||
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;
|
||||
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
|
||||
if (!sObjectMgr->GetCreatureTemplate(cond->mSourceGroup))
|
||||
@@ -1080,10 +1170,21 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
|
||||
sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->mSourceEntry);
|
||||
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;
|
||||
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
|
||||
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
|
||||
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:
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
|
||||
class Player;
|
||||
class Unit;
|
||||
class WorldObject;
|
||||
class LootTemplate;
|
||||
struct Condition;
|
||||
|
||||
enum ConditionType
|
||||
{ // value1 value2 value3
|
||||
@@ -100,6 +102,24 @@ enum ConditionSourceType
|
||||
CONDITION_SOURCE_TYPE_MAX = 23 //MAX
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_CONDITION_TARGETS = 3,
|
||||
};
|
||||
|
||||
struct ConditionSourceInfo
|
||||
{
|
||||
WorldObject* mConditionTargets[MAX_CONDITION_TARGETS];
|
||||
Condition* mLastFailedCondition;
|
||||
ConditionSourceInfo(WorldObject* target0, WorldObject* target1 = NULL, WorldObject* target2 = NULL)
|
||||
{
|
||||
mConditionTargets[0] = target0;
|
||||
mConditionTargets[1] = target1;
|
||||
mConditionTargets[2] = target2;
|
||||
mLastFailedCondition = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
struct Condition
|
||||
{
|
||||
ConditionSourceType mSourceType; //SourceTypeOrReferenceId
|
||||
@@ -108,6 +128,7 @@ struct Condition
|
||||
uint32 mSourceId; // So far, only used in CONDITION_SOURCE_TYPE_SMART_EVENT
|
||||
uint32 mElseGroup;
|
||||
ConditionType mConditionType; //ConditionTypeOrReference
|
||||
uint8 mConditionTarget;
|
||||
uint32 mConditionValue1;
|
||||
uint32 mConditionValue2;
|
||||
uint32 mConditionValue3;
|
||||
@@ -123,6 +144,7 @@ struct Condition
|
||||
mSourceEntry = 0;
|
||||
mElseGroup = 0;
|
||||
mConditionType = CONDITION_NONE;
|
||||
mConditionTarget = 0;
|
||||
mConditionValue1 = 0;
|
||||
mConditionValue2 = 0;
|
||||
mConditionValue3 = 0;
|
||||
@@ -132,7 +154,7 @@ struct Condition
|
||||
mNegativeCondition = false;
|
||||
}
|
||||
|
||||
bool Meets(WorldObject* player, WorldObject* invoker = NULL);
|
||||
bool Meets(ConditionSourceInfo& sourceInfo);
|
||||
bool isLoaded() const { return mConditionType > CONDITION_NONE || mReferenceId; }
|
||||
};
|
||||
|
||||
@@ -157,7 +179,8 @@ class ConditionMgr
|
||||
bool isConditionTypeValid(Condition* cond);
|
||||
ConditionList GetConditionReferences(uint32 refId);
|
||||
|
||||
bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions, WorldObject* invoker = NULL);
|
||||
bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions);
|
||||
bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
|
||||
ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry);
|
||||
ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType);
|
||||
ConditionList GetConditionsForVehicleSpell(uint32 creatureID, uint32 spellID);
|
||||
@@ -167,7 +190,7 @@ class ConditionMgr
|
||||
bool addToLootTemplate(Condition* cond, LootTemplate* loot);
|
||||
bool addToGossipMenus(Condition* cond);
|
||||
bool addToGossipMenuItems(Condition* cond);
|
||||
bool IsObjectMeetToConditionList(WorldObject* player, ConditionList const& conditions, WorldObject* invoker = NULL);
|
||||
bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
|
||||
|
||||
bool isGroupable(ConditionSourceType sourceType) const
|
||||
{
|
||||
|
||||
@@ -856,8 +856,6 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep
|
||||
for (uint8 i = 0; i < MAX_POWERS; ++i)
|
||||
m_powerFraction[i] = 0;
|
||||
|
||||
m_ConditionErrorMsgId = 0;
|
||||
|
||||
isDebugAreaTriggers = false;
|
||||
|
||||
SetPendingBind(0, 0);
|
||||
|
||||
@@ -2325,8 +2325,6 @@ class Player : public Unit, public GridObject<Player>
|
||||
|
||||
void SetHomebind(WorldLocation const& loc, uint32 area_id);
|
||||
|
||||
uint32 m_ConditionErrorMsgId;
|
||||
|
||||
// Homebind coordinates
|
||||
uint32 m_homebindMapId;
|
||||
uint16 m_homebindAreaId;
|
||||
|
||||
@@ -1036,14 +1036,12 @@ void ScriptMgr::OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry)
|
||||
FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionExpire(ah, entry);
|
||||
}
|
||||
|
||||
bool ScriptMgr::OnConditionCheck(Condition* condition, WorldObject* object, WorldObject* invoker)
|
||||
bool ScriptMgr::OnConditionCheck(Condition* condition, ConditionSourceInfo& sourceInfo)
|
||||
{
|
||||
ASSERT(condition);
|
||||
ASSERT(object);
|
||||
// invoker can be NULL.
|
||||
|
||||
GET_SCRIPT_RET(ConditionScript, condition->mScriptId, tmpscript, true);
|
||||
return tmpscript->OnConditionCheck(condition, object, invoker);
|
||||
return tmpscript->OnConditionCheck(condition, sourceInfo);
|
||||
}
|
||||
|
||||
void ScriptMgr::OnInstall(Vehicle* veh)
|
||||
|
||||
@@ -62,6 +62,7 @@ class WorldObject;
|
||||
|
||||
struct AchievementCriteriaData;
|
||||
struct AuctionEntry;
|
||||
struct ConditionSourceInfo;
|
||||
struct Condition;
|
||||
struct ItemTemplate;
|
||||
struct OutdoorPvPData;
|
||||
@@ -572,7 +573,7 @@ class ConditionScript : public ScriptObject
|
||||
bool IsDatabaseBound() const { return true; }
|
||||
|
||||
// Called when a single condition is checked for a player.
|
||||
virtual bool OnConditionCheck(Condition* /*condition*/, WorldObject* /*object*/, WorldObject* /*invoker*/) { return true; }
|
||||
virtual bool OnConditionCheck(Condition* /*condition*/, ConditionSourceInfo& /*sourceInfo*/) { return true; }
|
||||
};
|
||||
|
||||
class VehicleScript : public ScriptObject
|
||||
@@ -938,7 +939,7 @@ class ScriptMgr
|
||||
|
||||
public: /* ConditionScript */
|
||||
|
||||
bool OnConditionCheck(Condition* condition, WorldObject* object, WorldObject* invoker);
|
||||
bool OnConditionCheck(Condition* condition, ConditionSourceInfo& sourceInfo);
|
||||
|
||||
public: /* VehicleScript */
|
||||
|
||||
|
||||
@@ -4716,12 +4716,23 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||
return SPELL_FAILED_DONT_REPORT;
|
||||
}
|
||||
|
||||
// check spell caster's conditions from database
|
||||
if (Player* plrCaster = m_caster->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
// check spell cast conditions from database
|
||||
{
|
||||
ConditionSourceInfo condInfo = ConditionSourceInfo(m_caster);
|
||||
condInfo.mConditionTargets[1] = m_targets.GetObjectTarget();
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
|
||||
if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(plrCaster, conditions))
|
||||
if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
|
||||
{
|
||||
// send error msg to player if condition failed and text message available
|
||||
// TODO: using WorldSession::SendNotification is not blizzlike
|
||||
if (Player* playerCaster = m_caster->ToPlayer())
|
||||
{
|
||||
if (playerCaster->GetSession() && condInfo.mLastFailedCondition
|
||||
&& condInfo.mLastFailedCondition->ErrorTextd)
|
||||
playerCaster->GetSession()->SendNotification(condInfo.mLastFailedCondition->ErrorTextd);
|
||||
}
|
||||
return SPELL_FAILED_DONT_REPORT;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
|
||||
|
||||
Reference in New Issue
Block a user