diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/AI/EventAI/CreatureEventAI.cpp | 2 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 12 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.h | 12 | ||||
-rwxr-xr-x | src/server/game/Conditions/ConditionMgr.cpp | 175 | ||||
-rwxr-xr-x | src/server/game/Conditions/ConditionMgr.h | 29 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.h | 2 | ||||
-rwxr-xr-x | src/server/game/Scripting/ScriptMgr.cpp | 6 | ||||
-rwxr-xr-x | src/server/game/Scripting/ScriptMgr.h | 5 | ||||
-rwxr-xr-x | src/server/game/Spells/Spell.cpp | 17 |
10 files changed, 197 insertions, 65 deletions
diff --git a/src/server/game/AI/EventAI/CreatureEventAI.cpp b/src/server/game/AI/EventAI/CreatureEventAI.cpp index 5db9d0b1cdb..dead8b07ca1 100755 --- a/src/server/game/AI/EventAI/CreatureEventAI.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAI.cpp @@ -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); diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 42a23236182..01f301cc85d 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -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()) diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index fec38a690ed..f7524582ab7 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -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); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 977657a985c..be57ed5c303 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -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; diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index a81f533817b..aca666c55de 100755 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -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 { diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index bedcc214e22..630551cfc2a 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -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); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 489b4eacec5..345df411165 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -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; diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index eccf12aa7e1..b40319358b6 100755 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -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) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 853db564a6d..048a7581215 100755 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -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 */ diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 9dccb0ff341..7c578a39355 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -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) |