Core/Db/Conditions: Prepare conditions system to work on objects of different type than players.

Warning: API has changed a bit:
ConditionScript::OnConditionCheck(Condition* condition, Player* player, Unit* invoker) is now
ConditionScript::OnConditionCheck(Condition* condition, WorldObject* object, WorldObject* invoker)
This commit is contained in:
QAston
2012-02-10 14:18:59 +01:00
parent e0ad0f0e8d
commit 8713b44ee7
10 changed files with 166 additions and 94 deletions
+148 -76
View File
@@ -27,14 +27,15 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
// Checks if player meets the condition
// Checks if object meets the condition
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI)
bool Condition::Meets(Player* player, Unit* invoker)
bool Condition::Meets(WorldObject* object, WorldObject* invoker)
{
if (!player)
// object not present, return false
if (!object)
{
sLog->outDebug(LOG_FILTER_CONDITIONSYS, "Condition player not found");
return false; // player not present, return false
sLog->outDebug(LOG_FILTER_CONDITIONSYS, "Condition object not found");
return false;
}
uint32 refId = mConditionValue3;//value 3 can be a 'quick' reference
bool condMeets = false;
@@ -45,72 +46,119 @@ bool Condition::Meets(Player* player, Unit* invoker)
condMeets = true; // empty condition, always met
break;
case CONDITION_AURA:
refId = 0;
if (!mConditionValue3)
condMeets = player->HasAuraEffect(mConditionValue1, mConditionValue2);
else if (Unit* target = player->GetSelectedUnit())
condMeets = target->HasAuraEffect(mConditionValue1, mConditionValue2);
{
if (Unit* unit = object->ToUnit())
{
refId = 0;
if (!mConditionValue3)
condMeets = unit->HasAuraEffect(mConditionValue1, mConditionValue2);
else if (Player* player = unit->ToPlayer())
{
if (Unit* target = player->GetSelectedUnit())
condMeets = target->HasAuraEffect(mConditionValue1, mConditionValue2);
}
}
break;
}
case CONDITION_ITEM:
condMeets = (mConditionValue2 && player->HasItemCount(mConditionValue1, mConditionValue2)) || (!mConditionValue2 && !player->HasItemCount(mConditionValue1, mConditionValue2));//HasItemCount returns false if 0 count is used
{
if (Player* player = object->ToPlayer())
condMeets = (mConditionValue2 && player->HasItemCount(mConditionValue1, mConditionValue2)) || (!mConditionValue2 && !player->HasItemCount(mConditionValue1, mConditionValue2));//HasItemCount returns false if 0 count is used
break;
}
case CONDITION_ITEM_EQUIPPED:
condMeets = player->HasItemOrGemWithIdEquipped(mConditionValue1, 1);
{
if (Player* player = object->ToPlayer())
condMeets = player->HasItemOrGemWithIdEquipped(mConditionValue1, 1);
break;
}
case CONDITION_ZONEID:
condMeets = player->GetZoneId() == mConditionValue1;
condMeets = object->GetZoneId() == mConditionValue1;
break;
case CONDITION_REPUTATION_RANK:
{
if (FactionEntry const* faction = sFactionStore.LookupEntry(mConditionValue1))
condMeets = (mConditionValue2 & (1 << player->GetReputationMgr().GetRank(faction)));
if (Player* player = object->ToPlayer())
{
if (FactionEntry const* faction = sFactionStore.LookupEntry(mConditionValue1))
condMeets = (mConditionValue2 & (1 << player->GetReputationMgr().GetRank(faction)));
}
break;
}
case CONDITION_ACHIEVEMENT:
condMeets = player->GetAchievementMgr().HasAchieved(mConditionValue1);
{
if (Player* player = object->ToPlayer())
condMeets = player->GetAchievementMgr().HasAchieved(mConditionValue1);
break;
}
case CONDITION_TEAM:
condMeets = player->GetTeam() == mConditionValue1;
{
if (Player* player = object->ToPlayer())
condMeets = player->GetTeam() == mConditionValue1;
break;
}
case CONDITION_CLASS:
condMeets = player->getClassMask() & mConditionValue1;
{
if (Player* player = object->ToPlayer())
condMeets = player->getClassMask() & mConditionValue1;
break;
}
case CONDITION_RACE:
condMeets = player->getRaceMask() & mConditionValue1;
{
if (Player* player = object->ToPlayer())
condMeets = player->getRaceMask() & mConditionValue1;
break;
}
case CONDITION_SKILL:
condMeets = player->HasSkill(mConditionValue1) && player->GetBaseSkillValue(mConditionValue1) >= mConditionValue2;
{
if (Player* player = object->ToPlayer())
condMeets = player->HasSkill(mConditionValue1) && player->GetBaseSkillValue(mConditionValue1) >= mConditionValue2;
break;
}
case CONDITION_QUESTREWARDED:
condMeets = (player->GetQuestRewardStatus(mConditionValue1) == !mConditionValue2);
{
if (Player* player = object->ToPlayer())
condMeets = (player->GetQuestRewardStatus(mConditionValue1) == !mConditionValue2);
break;
}
case CONDITION_QUESTTAKEN:
{
QuestStatus status = player->GetQuestStatus(mConditionValue1);
condMeets = ((status == QUEST_STATUS_INCOMPLETE) == !mConditionValue2);
if (Player* player = object->ToPlayer())
{
QuestStatus status = player->GetQuestStatus(mConditionValue1);
condMeets = ((status == QUEST_STATUS_INCOMPLETE) == !mConditionValue2);
}
break;
}
case CONDITION_QUEST_COMPLETE:
{
QuestStatus status = player->GetQuestStatus(mConditionValue1);
condMeets = ((status == QUEST_STATUS_COMPLETE && !player->GetQuestRewardStatus(mConditionValue1)) == !mConditionValue2);
if (Player* player = object->ToPlayer())
{
QuestStatus status = player->GetQuestStatus(mConditionValue1);
condMeets = ((status == QUEST_STATUS_COMPLETE && !player->GetQuestRewardStatus(mConditionValue1)) == !mConditionValue2);
}
break;
}
case CONDITION_QUEST_NONE:
{
QuestStatus status = player->GetQuestStatus(mConditionValue1);
condMeets = ((status == QUEST_STATUS_NONE) == !mConditionValue2);
if (Player* player = object->ToPlayer())
{
QuestStatus status = player->GetQuestStatus(mConditionValue1);
condMeets = ((status == QUEST_STATUS_NONE) == !mConditionValue2);
}
break;
}
case CONDITION_NO_AURA:
condMeets = !player->HasAuraEffect(mConditionValue1, mConditionValue2);
{
if (Unit* unit = object->ToUnit())
condMeets = !unit->HasAuraEffect(mConditionValue1, mConditionValue2);
break;
}
case CONDITION_ACTIVE_EVENT:
condMeets = sGameEventMgr->IsActiveEvent(mConditionValue1);
break;
case CONDITION_INSTANCE_DATA:
{
Map* map = player->GetMap();
Map* map = object->GetMap();
if (map && map->IsDungeon() && ((InstanceMap*)map)->GetInstanceScript())
condMeets = ((InstanceMap*)map)->GetInstanceScript()->GetData(mConditionValue1) == mConditionValue2;
break;
@@ -121,32 +169,41 @@ bool Condition::Meets(Player* player, Unit* invoker)
break;
case CONDITION_CREATURE_TARGET:
{
Unit* target = player->GetSelectedUnit();
if (target)
if (Creature* cTarget = target->ToCreature())
if (cTarget->GetEntry() == mConditionValue1)
condMeets = true;
if (Player* player = object->ToPlayer())
{
Unit* target = player->GetSelectedUnit();
if (target)
if (Creature* cTarget = target->ToCreature())
if (cTarget->GetEntry() == mConditionValue1)
condMeets = true;
}
break;
}
case CONDITION_TARGET_HEALTH_BELOW_PCT:
{
Unit* target = player->GetSelectedUnit();
if (target)
condMeets = !target->HealthAbovePct(mConditionValue1);
break;
if (Player* player = object->ToPlayer())
{
Unit* target = player->GetSelectedUnit();
if (target)
condMeets = !target->HealthAbovePct(mConditionValue1);
break;
}
}
case CONDITION_TARGET_RANGE:
{
if (Unit* target = player->GetSelectedUnit())
if (player->GetDistance(target) >= mConditionValue1 && (!mConditionValue2 || player->GetDistance(target) <= mConditionValue2))
condMeets = true;
if (Player* player = object->ToPlayer())
{
if (Unit* target = player->GetSelectedUnit())
if (player->GetDistance(target) >= mConditionValue1 && (!mConditionValue2 || player->GetDistance(target) <= mConditionValue2))
condMeets = true;
}
break;
}
case CONDITION_MAPID:
condMeets = player->GetMapId() == mConditionValue1;
condMeets = object->GetMapId() == mConditionValue1;
break;
case CONDITION_AREAID:
condMeets = player->GetAreaId() == mConditionValue1;
condMeets = object->GetAreaId() == mConditionValue1;
break;
case CONDITION_ITEM_TARGET:
{
@@ -155,49 +212,61 @@ bool Condition::Meets(Player* player, Unit* invoker)
break;
}
case CONDITION_SPELL:
if (mConditionValue2 == 1)
condMeets = player->HasSpell(mConditionValue1);
else
condMeets = !player->HasSpell(mConditionValue1);
{
if (Player* player = object->ToPlayer())
{
if (mConditionValue2 == 1)
condMeets = player->HasSpell(mConditionValue1);
else
condMeets = !player->HasSpell(mConditionValue1);
}
break;
}
case CONDITION_NOITEM:
condMeets = !player->HasItemCount(mConditionValue1, 1, mConditionValue2 ? true : false);
{
if (Player* player = object->ToPlayer())
condMeets = !player->HasItemCount(mConditionValue1, 1, mConditionValue2 ? true : false);
break;
}
case CONDITION_LEVEL:
{
switch (mConditionValue2)
if (Unit* unit = object->ToUnit())
{
case LVL_COND_EQ:
condMeets = player->getLevel() == mConditionValue1;
break;
case LVL_COND_HIGH:
condMeets = player->getLevel() > mConditionValue1;
break;
case LVL_COND_LOW:
condMeets = player->getLevel() < mConditionValue1;
break;
case LVL_COND_HIGH_EQ:
condMeets = player->getLevel() >= mConditionValue1;
break;
case LVL_COND_LOW_EQ:
condMeets = player->getLevel() <= mConditionValue1;
break;
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;
}
case CONDITION_DRUNKENSTATE:
{
condMeets = (uint32)Player::GetDrunkenstateByValue(player->GetDrunkValue()) >= mConditionValue1;
if (Player* player = object->ToPlayer())
condMeets = (uint32)Player::GetDrunkenstateByValue(player->GetDrunkValue()) >= mConditionValue1;
break;
}
case CONDITION_NEAR_CREATURE:
{
condMeets = GetClosestCreatureWithEntry(player, mConditionValue1, (float)mConditionValue2) ? true : false;
condMeets = GetClosestCreatureWithEntry(object, mConditionValue1, (float)mConditionValue2) ? true : false;
break;
}
case CONDITION_NEAR_GAMEOBJECT:
{
condMeets = GetClosestGameObjectWithEntry(player, mConditionValue1, (float)mConditionValue2) ? true : false;
condMeets = GetClosestGameObjectWithEntry(object, mConditionValue1, (float)mConditionValue2) ? true : false;
break;
}
default:
@@ -222,15 +291,16 @@ bool Condition::Meets(Player* player, Unit* invoker)
if (condMeets && refId)//only have to check references if 'this' is met
{
ConditionList ref = sConditionMgr->GetConditionReferences(refId);
refMeets = sConditionMgr->IsPlayerMeetToConditions(player, ref, invoker);
refMeets = sConditionMgr->IsObjectMeetToConditions(object, ref, invoker);
}
else
refMeets = true;
if (sendErrorMsg && ErrorTextd && (!condMeets || !refMeets))//send special error from DB
player->m_ConditionErrorMsgId = ErrorTextd;
if (Player* player = object->ToPlayer())
if (sendErrorMsg && ErrorTextd && (!condMeets || !refMeets))//send special error from DB
player->m_ConditionErrorMsgId = ErrorTextd;
bool script = sScriptMgr->OnConditionCheck(this, player, invoker); // Returns true by default.
bool script = sScriptMgr->OnConditionCheck(this, object, invoker); // Returns true by default.
return condMeets && refMeets && script;
}
@@ -252,7 +322,7 @@ ConditionList ConditionMgr::GetConditionReferences(uint32 refId)
return conditions;
}
bool ConditionMgr::IsPlayerMeetToConditionList(Player* player, ConditionList const& conditions, Unit* invoker /*= NULL*/)
bool ConditionMgr::IsObjectMeetToConditionList(WorldObject* object, ConditionList const& conditions, WorldObject* invoker /*= NULL*/)
{
std::map<uint32, bool> ElseGroupStore;
for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
@@ -271,7 +341,7 @@ bool ConditionMgr::IsPlayerMeetToConditionList(Player* player, ConditionList con
ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find((*i)->mReferenceId);
if (ref != ConditionReferenceStore.end())
{
if (!IsPlayerMeetToConditionList(player, (*ref).second, invoker))
if (!IsObjectMeetToConditionList(object, (*ref).second, invoker))
ElseGroupStore[(*i)->mElseGroup] = false;
}
else
@@ -283,7 +353,7 @@ bool ConditionMgr::IsPlayerMeetToConditionList(Player* player, ConditionList con
}
else //handle normal condition
{
if (!(*i)->Meets(player, invoker))
if (!(*i)->Meets(object, invoker))
ElseGroupStore[(*i)->mElseGroup] = false;
}
}
@@ -295,16 +365,18 @@ bool ConditionMgr::IsPlayerMeetToConditionList(Player* player, ConditionList con
return false;
}
bool ConditionMgr::IsPlayerMeetToConditions(Player* player, ConditionList const& conditions, Unit* invoker /*= NULL*/)
bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions, WorldObject* invoker /*= NULL*/)
{
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 = IsPlayerMeetToConditionList(player, conditions, invoker);
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
+3 -3
View File
@@ -132,7 +132,7 @@ struct Condition
mNegativeCondition = false;
}
bool Meets(Player* player, Unit* invoker = NULL);
bool Meets(WorldObject* player, WorldObject* invoker = NULL);
bool isLoaded() const { return mConditionType > CONDITION_NONE || mReferenceId; }
};
@@ -157,7 +157,7 @@ class ConditionMgr
bool isConditionTypeValid(Condition* cond);
ConditionList GetConditionReferences(uint32 refId);
bool IsPlayerMeetToConditions(Player* player, ConditionList const& conditions, Unit* invoker = NULL);
bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions, WorldObject* invoker = NULL);
ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry);
ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType);
ConditionList GetConditionsForVehicleSpell(uint32 creatureID, uint32 spellID);
@@ -167,7 +167,7 @@ class ConditionMgr
bool addToLootTemplate(Condition* cond, LootTemplate* loot);
bool addToGossipMenus(Condition* cond);
bool addToGossipMenuItems(Condition* cond);
bool IsPlayerMeetToConditionList(Player* player, ConditionList const& conditions, Unit* invoker = NULL);
bool IsObjectMeetToConditionList(WorldObject* player, ConditionList const& conditions, WorldObject* invoker = NULL);
bool isGroupable(ConditionSourceType sourceType) const
{