diff options
Diffstat (limited to 'src/server/game/Conditions/ConditionMgr.cpp')
-rwxr-xr-x | src/server/game/Conditions/ConditionMgr.cpp | 224 |
1 files changed, 148 insertions, 76 deletions
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 964abe6ae57..81db61171a3 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -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 |