2010-10-07 15:35:36 +02:00
/*
2011-01-01 15:01:13 +01:00
* Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
2010-06-04 23:24:48 +02:00
*/
#include "Player.h"
#include "SpellAuras.h"
#include "SpellMgr.h"
#include "GameEventMgr.h"
#include "ObjectMgr.h"
2010-08-08 22:54:58 +06:00
#include "InstanceScript.h"
2010-06-04 23:24:48 +02:00
#include "ConditionMgr.h"
2010-08-06 19:23:43 +02:00
#include "ScriptMgr.h"
2010-10-31 22:10:31 +01:00
#include "ScriptedCreature.h"
2010-06-04 23:24:48 +02:00
// Checks if player meets the condition
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI)
2011-06-11 22:35:29 +02:00
bool Condition :: Meets ( Player * player , Unit * invoker )
2010-06-10 20:52:15 +02:00
{
2010-06-04 23:24:48 +02:00
if ( ! player )
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "Condition player not found" );
2010-06-04 23:24:48 +02:00
return false ; // player not present, return false
}
2010-08-06 19:23:43 +02:00
uint32 refId = mConditionValue3 ; //value 3 can be a 'quick' reference
2010-06-04 23:24:48 +02:00
bool condMeets = false ;
bool sendErrorMsg = false ;
switch ( mConditionType )
{
case CONDITION_NONE :
condMeets = true ; // empty condition, always met
break ;
case CONDITION_AURA :
2010-11-05 22:54:51 +01:00
refId = 0 ;
2010-11-05 23:33:31 +01:00
if ( ! mConditionValue3 )
2010-11-05 22:54:51 +01:00
condMeets = player -> HasAuraEffect ( mConditionValue1 , mConditionValue2 );
else if ( Unit * target = player -> GetSelectedUnit ())
condMeets = target -> HasAuraEffect ( mConditionValue1 , mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_ITEM :
2010-11-15 23:20:20 +01:00
condMeets = ( mConditionValue2 && player -> HasItemCount ( mConditionValue1 , mConditionValue2 )) || ( ! mConditionValue2 && ! player -> HasItemCount ( mConditionValue1 , mConditionValue2 )); //HasItemCount returns false if 0 count is used
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_ITEM_EQUIPPED :
2011-04-29 20:47:02 +02:00
condMeets = player -> HasItemOrGemWithIdEquipped ( mConditionValue1 , 1 );
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_ZONEID :
condMeets = player -> GetZoneId () == mConditionValue1 ;
break ;
case CONDITION_REPUTATION_RANK :
{
2011-04-22 17:42:30 +01:00
if ( FactionEntry const * faction = sFactionStore . LookupEntry ( mConditionValue1 ))
condMeets = uint32 ( player -> GetReputationMgr (). GetRank ( faction )) == mConditionValue2 ;
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_ACHIEVEMENT :
{
AchievementEntry const * achievement = GetAchievementStore () -> LookupEntry ( mConditionValue1 );
condMeets = player -> GetAchievementMgr (). HasAchieved ( achievement );
break ;
}
case CONDITION_TEAM :
condMeets = player -> GetTeam () == mConditionValue1 ;
break ;
case CONDITION_CLASS :
condMeets = player -> getClass () == mConditionValue1 ;
break ;
case CONDITION_RACE :
condMeets = player -> getRace () == mConditionValue1 ;
break ;
case CONDITION_SKILL :
condMeets = player -> HasSkill ( mConditionValue1 ) && player -> GetBaseSkillValue ( mConditionValue1 ) >= mConditionValue2 ;
break ;
case CONDITION_QUESTREWARDED :
2011-04-21 16:23:20 +06:00
condMeets = ( player -> GetQuestRewardStatus ( mConditionValue1 ) == ! mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_QUESTTAKEN :
{
QuestStatus status = player -> GetQuestStatus ( mConditionValue1 );
2011-04-21 16:23:20 +06:00
condMeets = (( status == QUEST_STATUS_INCOMPLETE ) == ! mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
2010-10-24 21:44:58 +02:00
case CONDITION_QUEST_COMPLETE :
{
QuestStatus status = player -> GetQuestStatus ( mConditionValue1 );
2011-04-21 16:23:20 +06:00
condMeets = (( status == QUEST_STATUS_COMPLETE && ! player -> GetQuestRewardStatus ( mConditionValue1 )) == ! mConditionValue2 );
2010-10-24 21:44:58 +02:00
break ;
}
2010-06-04 23:24:48 +02:00
case CONDITION_QUEST_NONE :
{
QuestStatus status = player -> GetQuestStatus ( mConditionValue1 );
2011-04-21 16:23:20 +06:00
condMeets = (( status == QUEST_STATUS_NONE ) == ! mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_NO_AURA :
condMeets = ! player -> HasAuraEffect ( mConditionValue1 , mConditionValue2 );
break ;
case CONDITION_ACTIVE_EVENT :
2010-12-22 21:25:23 +01:00
condMeets = sGameEventMgr -> IsActiveEvent ( mConditionValue1 );
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_INSTANCE_DATA :
{
Map * map = player -> GetMap ();
2010-08-08 22:54:58 +06:00
if ( map && map -> IsDungeon () && (( InstanceMap * ) map ) -> GetInstanceScript ())
condMeets = (( InstanceMap * ) map ) -> GetInstanceScript () -> GetData ( mConditionValue1 ) == mConditionValue2 ;
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_SPELL_SCRIPT_TARGET :
2010-06-10 20:52:15 +02:00
condMeets = true ; //spell target condition is handled in spellsystem, here it is always true
2010-06-04 23:24:48 +02:00
refId = 0 ; //cant have references! use CONDITION_SOURCE_TYPE_SPELL for it
break ;
case CONDITION_CREATURE_TARGET :
{
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 )
2010-08-26 01:20:57 +06:00
condMeets = ! target -> HealthAbovePct ( mConditionValue1 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_TARGET_RANGE :
{
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 ;
break ;
case CONDITION_AREAID :
condMeets = player -> GetAreaId () == mConditionValue1 ;
break ;
case CONDITION_ITEM_TARGET :
{
2010-06-10 20:52:15 +02:00
condMeets = true ; //handled in Item::IsTargetValidForItemUse
2010-06-04 23:24:48 +02:00
refId = 0 ; //cant have references for now
break ;
}
2010-09-10 20:49:29 +02:00
case CONDITION_SPELL :
2011-04-09 10:23:54 +02:00
if ( mConditionValue2 == 1 )
2011-04-09 10:12:45 +02:00
condMeets = player -> HasSpell ( mConditionValue1 );
else
condMeets = ! player -> HasSpell ( mConditionValue1 );
2010-09-10 20:49:29 +02:00
break ;
2010-09-30 22:41:19 +02:00
case CONDITION_NOITEM :
condMeets = ! player -> HasItemCount ( mConditionValue1 , 1 , mConditionValue2 ? true : false );
break ;
2010-10-05 17:54:27 +02:00
case CONDITION_LEVEL :
{
switch ( mConditionValue2 )
{
2010-10-05 18:07:41 +02:00
case LVL_COND_EQ :
2010-10-05 17:54:27 +02:00
condMeets = player -> getLevel () == mConditionValue1 ;
break ;
2010-10-05 18:07:41 +02:00
case LVL_COND_HIGH :
2010-10-05 17:54:27 +02:00
condMeets = player -> getLevel () > mConditionValue1 ;
break ;
2010-10-05 18:07:41 +02:00
case LVL_COND_LOW :
2010-10-05 17:54:27 +02:00
condMeets = player -> getLevel () < mConditionValue1 ;
break ;
2010-10-05 18:07:41 +02:00
case LVL_COND_HIGH_EQ :
2010-10-05 17:54:27 +02:00
condMeets = player -> getLevel () >= mConditionValue1 ;
break ;
2010-10-05 18:07:41 +02:00
case LVL_COND_LOW_EQ :
2010-10-05 17:54:27 +02:00
condMeets = player -> getLevel () <= mConditionValue1 ;
break ;
}
break ;
}
2010-10-11 23:35:55 +02:00
case CONDITION_DRUNKENSTATE :
{
condMeets = ( uint32 ) Player :: GetDrunkenstateByValue ( player -> GetDrunkValue ()) >= mConditionValue1 ;
break ;
}
2010-10-31 22:10:31 +01:00
case CONDITION_NEAR_CREATURE :
{
condMeets = GetClosestCreatureWithEntry ( player , mConditionValue1 , ( float ) mConditionValue2 ) ? true : false ;
break ;
}
case CONDITION_NEAR_GAMEOBJECT :
{
condMeets = GetClosestGameObjectWithEntry ( player , mConditionValue1 , ( float ) mConditionValue2 ) ? true : false ;
break ;
}
2010-06-04 23:24:48 +02:00
default :
condMeets = false ;
refId = 0 ;
break ;
}
switch ( mSourceType )
{
case CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET :
case CONDITION_SOURCE_TYPE_SPELL :
sendErrorMsg = true ;
break ;
2010-08-21 20:55:31 +02:00
default :
break ;
2010-06-04 23:24:48 +02:00
}
bool refMeets = false ;
if ( condMeets && refId ) //only have to check references if 'this' is met
{
2010-12-22 21:25:23 +01:00
ConditionList ref = sConditionMgr -> GetConditionReferences ( refId );
refMeets = sConditionMgr -> IsPlayerMeetToConditions ( player , ref );
2010-08-06 19:23:43 +02:00
}
else
refMeets = true ;
2010-06-04 23:24:48 +02:00
if ( sendErrorMsg && ErrorTextd && ( ! condMeets || ! refMeets )) //send special error from DB
player -> m_ConditionErrorMsgId = ErrorTextd ;
2010-12-22 21:25:23 +01:00
bool script = sScriptMgr -> OnConditionCheck ( this , player , invoker ); // Returns true by default.
2010-08-06 19:23:43 +02:00
return condMeets && refMeets && script ;
2010-06-04 23:24:48 +02:00
}
ConditionMgr :: ConditionMgr ()
{
}
ConditionMgr ::~ ConditionMgr ()
{
2010-06-11 01:25:10 +02:00
Clean ();
2010-06-04 23:24:48 +02:00
}
ConditionList ConditionMgr :: GetConditionReferences ( uint32 refId )
{
ConditionList conditions ;
ConditionReferenceMap :: const_iterator ref = m_ConditionReferenceMap . find ( refId );
if ( ref != m_ConditionReferenceMap . end ())
conditions = ( * ref ). second ;
return conditions ;
}
2011-05-26 23:27:43 +02:00
bool ConditionMgr :: IsPlayerMeetToConditionList ( Player * player , ConditionList const & conditions , Unit * invoker /*= NULL*/ )
2010-06-04 23:24:48 +02:00
{
2011-05-26 23:27:43 +02:00
std :: map < uint32 , bool > ElseGroupMap ;
2010-06-04 23:24:48 +02:00
for ( ConditionList :: const_iterator i = conditions . begin (); i != conditions . end (); ++ i )
{
2011-04-29 20:47:02 +02:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "ConditionMgr::IsPlayerMeetToConditionList condType: %u val1: %u" , ( * i ) -> mConditionType , ( * i ) -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
if (( * i ) -> isLoaded ())
{
std :: map < uint32 , bool >:: const_iterator itr = ElseGroupMap . find (( * i ) -> mElseGroup );
if ( itr == ElseGroupMap . end ())
ElseGroupMap [( * i ) -> mElseGroup ] = true ;
else if ( ! ( * itr ). second )
continue ;
if (( * i ) -> mReferenceId ) //handle reference
{
ConditionReferenceMap :: const_iterator ref = m_ConditionReferenceMap . find (( * i ) -> mReferenceId );
if ( ref != m_ConditionReferenceMap . end ())
{
2011-06-12 02:30:32 +02:00
if ( ! IsPlayerMeetToConditionList ( player , ( * ref ). second , invoker ))
2010-06-04 23:24:48 +02:00
ElseGroupMap [( * i ) -> mElseGroup ] = false ;
2010-08-06 19:23:43 +02:00
}
else
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "IsPlayerMeetToConditionList: Reference template -%u not found" ,
2010-08-06 19:23:43 +02:00
( * i ) -> mReferenceId ); //checked at loading, should never happen
2010-06-04 23:24:48 +02:00
}
2010-06-11 01:25:10 +02:00
2010-08-06 19:23:43 +02:00
}
else //handle normal condition
2010-06-04 23:24:48 +02:00
{
2010-09-24 18:16:29 +02:00
if ( ! ( * i ) -> Meets ( player , invoker ))
2010-06-04 23:24:48 +02:00
ElseGroupMap [( * i ) -> mElseGroup ] = false ;
2010-06-10 20:52:15 +02:00
}
2010-06-04 23:24:48 +02:00
}
}
for ( std :: map < uint32 , bool >:: const_iterator i = ElseGroupMap . begin (); i != ElseGroupMap . end (); ++ i )
if ( i -> second )
return true ;
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
return false ;
}
2011-05-26 23:27:43 +02:00
bool ConditionMgr :: IsPlayerMeetToConditions ( Player * player , ConditionList const & conditions , Unit * invoker /*= NULL*/ )
2010-06-04 23:24:48 +02:00
{
if ( conditions . empty ())
return true ;
2010-08-06 19:23:43 +02:00
2011-05-26 23:27:43 +02:00
if ( player )
2010-06-04 23:24:48 +02:00
player -> m_ConditionErrorMsgId = 0 ;
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "ConditionMgr::IsPlayerMeetToConditions" );
2010-09-24 18:16:29 +02:00
bool result = IsPlayerMeetToConditionList ( player , conditions , invoker );
2010-06-04 23:24:48 +02:00
2010-09-21 23:30:37 +02:00
if ( player && player -> m_ConditionErrorMsgId && player -> GetSession () && ! result )
2011-05-26 23:27:43 +02:00
player -> GetSession () -> SendNotification ( player -> m_ConditionErrorMsgId ); //m_ConditionErrorMsgId is set only if a condition was not met
2010-06-04 23:24:48 +02:00
return result ;
}
ConditionList ConditionMgr :: GetConditionsForNotGroupedEntry ( ConditionSourceType sType , uint32 uEntry )
{
ConditionList spellCond ;
2010-09-20 22:11:55 +02:00
if ( sType > CONDITION_SOURCE_TYPE_NONE && sType < CONDITION_SOURCE_TYPE_MAX )
2010-06-04 23:24:48 +02:00
{
ConditionMap :: const_iterator itr = m_ConditionMap . find ( sType );
if ( itr != m_ConditionMap . end ())
2010-06-11 01:25:10 +02:00
{
2010-06-04 23:24:48 +02:00
ConditionTypeMap :: const_iterator i = ( * itr ). second . find ( uEntry );
if ( i != ( * itr ). second . end ())
{
spellCond = ( * i ). second ;
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "GetConditionsForNotGroupedEntry: found conditions for type %u and entry %u" , uint32 ( sType ), uEntry );
2010-06-04 23:24:48 +02:00
}
}
}
return spellCond ;
}
2010-10-22 22:45:11 +02:00
ConditionList ConditionMgr :: GetConditionsForVehicleSpell ( uint32 creatureID , uint32 spellID )
{
ConditionList cond ;
VehicleSpellConditionMap :: const_iterator itr = m_VehicleSpellConditions . find ( creatureID );
if ( itr != m_VehicleSpellConditions . end ())
{
ConditionTypeMap :: const_iterator i = ( * itr ). second . find ( spellID );
if ( i != ( * itr ). second . end ())
{
cond = ( * i ). second ;
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "GetConditionsForVehicleSpell: found conditions for Vehicle entry %u spell %u" , creatureID , spellID );
2010-10-22 22:45:11 +02:00
}
}
return cond ;
}
2010-06-04 23:24:48 +02:00
void ConditionMgr :: LoadConditions ( bool isReload )
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-06-11 01:25:10 +02:00
Clean ();
2010-06-04 23:24:48 +02:00
//must clear all custom handled cases (groupped types) before reload
if ( isReload )
{
2010-12-23 23:25:44 +01:00
sLog -> outString ( "Reseting Loot Conditions..." );
2010-06-04 23:24:48 +02:00
LootTemplates_Creature . ResetConditions ();
LootTemplates_Fishing . ResetConditions ();
LootTemplates_Gameobject . ResetConditions ();
LootTemplates_Item . ResetConditions ();
LootTemplates_Mail . ResetConditions ();
LootTemplates_Milling . ResetConditions ();
LootTemplates_Pickpocketing . ResetConditions ();
LootTemplates_Reference . ResetConditions ();
LootTemplates_Skinning . ResetConditions ();
LootTemplates_Disenchant . ResetConditions ();
LootTemplates_Prospecting . ResetConditions ();
LootTemplates_Spell . ResetConditions ();
2010-12-23 23:25:44 +01:00
sLog -> outString ( "Re-Loading `gossip_menu` Table for Conditions!" );
2010-12-22 21:25:23 +01:00
sObjectMgr -> LoadGossipMenu ();
2010-06-04 23:24:48 +02:00
2010-12-23 23:25:44 +01:00
sLog -> outString ( "Re-Loading `gossip_menu_option` Table for Conditions!" );
2010-12-22 21:25:23 +01:00
sObjectMgr -> LoadGossipMenuItems ();
2010-06-04 23:24:48 +02:00
}
2011-04-29 20:47:02 +02:00
QueryResult result = WorldDatabase . Query ( "SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, ElseGroup, ConditionTypeOrReference, "
2010-12-19 17:06:33 +01:00
" ConditionValue1, ConditionValue2, ConditionValue3, ErrorTextId, ScriptName FROM conditions" );
2010-06-04 23:24:48 +02:00
if ( ! result )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( ">> Loaded 0 conditions. DB table `groups` is empty!" );
sLog -> outString ();
2010-06-04 23:24:48 +02:00
return ;
}
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2010-06-04 23:24:48 +02:00
do
{
Field * fields = result -> Fetch ();
Condition * cond = new Condition ();
2010-06-11 01:25:10 +02:00
int32 iSourceTypeOrReferenceId = fields [ 0 ]. GetInt32 ();
2010-06-04 23:24:48 +02:00
cond -> mSourceGroup = fields [ 1 ]. GetUInt32 ();
cond -> mSourceEntry = fields [ 2 ]. GetUInt32 ();
cond -> mElseGroup = fields [ 3 ]. GetUInt32 ();
2010-06-11 01:25:10 +02:00
int32 iConditionTypeOrReference = fields [ 4 ]. GetInt32 ();
2010-06-04 23:24:48 +02:00
cond -> mConditionValue1 = fields [ 5 ]. GetUInt32 ();
cond -> mConditionValue2 = fields [ 6 ]. GetUInt32 ();
cond -> mConditionValue3 = fields [ 7 ]. GetUInt32 ();
cond -> ErrorTextd = fields [ 8 ]. GetUInt32 ();
2010-12-22 21:25:23 +01:00
cond -> mScriptId = sObjectMgr -> GetScriptId ( fields [ 9 ]. GetCString ());
2010-06-04 23:24:48 +02:00
if ( iConditionTypeOrReference >= 0 )
cond -> mConditionType = ConditionType ( iConditionTypeOrReference );
if ( iConditionTypeOrReference < 0 ) //it has a reference
{
2010-06-10 20:52:15 +02:00
if ( iConditionTypeOrReference == iSourceTypeOrReferenceId ) //self referencing, skip
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Condition reference %i is referencing self, skipped" , iSourceTypeOrReferenceId );
2010-06-11 01:25:10 +02:00
delete cond ;
2010-06-04 23:24:48 +02:00
continue ;
}
cond -> mReferenceId = uint32 ( abs ( iConditionTypeOrReference ));
const char * rowType = "reference template" ;
if ( iSourceTypeOrReferenceId >= 0 )
rowType = "reference" ;
//check for useless data
if ( cond -> mConditionValue1 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Condition %s %i has useless data in value1 (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Condition %s %i has useless data in value2 (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue3 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Condition %s %i has useless data in value3 (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> mConditionValue3 );
2010-06-04 23:24:48 +02:00
if ( cond -> mSourceGroup && iSourceTypeOrReferenceId < 0 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Condition %s %i has useless data in SourceGroup (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
if ( cond -> mSourceEntry && iSourceTypeOrReferenceId < 0 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Condition %s %i has useless data in SourceEntry (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> mSourceEntry );
2010-08-06 19:23:43 +02:00
}
else if ( ! isConditionTypeValid ( cond )) //doesn't have reference, validate ConditionType
2010-06-11 01:25:10 +02:00
{
delete cond ;
continue ;
}
2010-06-04 23:24:48 +02:00
if ( iSourceTypeOrReferenceId < 0 ) //it is a reference template
{
uint32 uRefId = abs ( iSourceTypeOrReferenceId );
if ( m_ConditionReferenceMap . find ( uRefId ) == m_ConditionReferenceMap . end ()) //make sure we have a list for our conditions, based on reference id
{
ConditionList mCondList ;
m_ConditionReferenceMap [ uRefId ] = mCondList ;
}
m_ConditionReferenceMap [ uRefId ]. push_back ( cond ); //add to reference storage
count ++ ;
continue ;
} //end of reference templates
cond -> mSourceType = ConditionSourceType ( iSourceTypeOrReferenceId );
2010-06-11 01:25:10 +02:00
2010-06-04 23:24:48 +02:00
//if not a reference and SourceType is invalid, skip
if ( iConditionTypeOrReference >= 0 && ! isSourceTypeValid ( cond ))
2010-06-11 01:25:10 +02:00
{
delete cond ;
2010-06-04 23:24:48 +02:00
continue ;
2010-06-11 01:25:10 +02:00
}
2010-06-04 23:24:48 +02:00
//Grouping is only allowed for some types (loot templates, gossip menus, gossip items)
if ( cond -> mSourceGroup && ! isGroupable ( cond -> mSourceType ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Condition type %u has not allowed grouping %u!" , uint32 ( cond -> mSourceType ), cond -> mSourceGroup );
2010-06-11 01:25:10 +02:00
delete cond ;
2010-06-04 23:24:48 +02:00
continue ;
2010-08-06 19:23:43 +02:00
}
else if ( cond -> mSourceGroup )
2010-06-04 23:24:48 +02:00
{
bool bIsDone = false ;
//handle grouped conditions
switch ( cond -> mSourceType )
{
case CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Creature . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Disenchant . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Fishing . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Gameobject . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Item . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Mail . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Milling . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Pickpocketing . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Prospecting . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Reference . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Skinning . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE :
bIsDone = addToLootTemplate ( cond , LootTemplates_Spell . GetLootForConditionFill ( cond -> mSourceGroup ));
break ;
case CONDITION_SOURCE_TYPE_GOSSIP_MENU :
bIsDone = addToGossipMenus ( cond );
break ;
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION :
bIsDone = addToGossipMenuItems ( cond );
break ;
2010-10-22 22:45:11 +02:00
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL :
2010-11-13 20:48:20 +01:00
{
//if no list for vehicle create one
if ( m_VehicleSpellConditions . find ( cond -> mSourceGroup ) == m_VehicleSpellConditions . end ())
2010-10-22 22:45:11 +02:00
{
2010-11-13 20:48:20 +01:00
ConditionTypeMap cmap ;
m_VehicleSpellConditions [ cond -> mSourceGroup ] = cmap ;
2010-10-22 22:45:11 +02:00
}
2010-11-13 20:48:20 +01:00
//if no list for vehicle's spell create one
if ( m_VehicleSpellConditions [ cond -> mSourceGroup ]. find ( cond -> mSourceEntry ) == m_VehicleSpellConditions [ cond -> mSourceGroup ]. end ())
{
ConditionList clist ;
m_VehicleSpellConditions [ cond -> mSourceGroup ][ cond -> mSourceEntry ] = clist ;
}
m_VehicleSpellConditions [ cond -> mSourceGroup ][ cond -> mSourceEntry ]. push_back ( cond );
bIsDone = true ;
++ count ;
continue ; // do not add to m_AllocatedMemory to avoid double deleting
}
2010-08-21 20:55:31 +02:00
default :
break ;
2010-06-04 23:24:48 +02:00
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( ! bIsDone )
2010-06-11 01:25:10 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Not handled grouped condition, SourceGroup %u" , cond -> mSourceGroup );
2010-06-11 01:25:10 +02:00
delete cond ;
}
2010-06-04 23:24:48 +02:00
else
2010-06-11 01:25:10 +02:00
{
m_AllocatedMemory . push_back ( cond );
2010-06-04 23:24:48 +02:00
++ count ;
2010-06-11 01:25:10 +02:00
}
2010-06-04 23:24:48 +02:00
continue ;
}
//handle not grouped conditions
//make sure we have a storage list for our SourceType
if ( m_ConditionMap . find ( cond -> mSourceType ) == m_ConditionMap . end ())
{
ConditionTypeMap mTypeMap ;
m_ConditionMap [ cond -> mSourceType ] = mTypeMap ; //add new empty list for SourceType
}
//make sure we have a condition list for our SourceType's entry
if ( m_ConditionMap [ cond -> mSourceType ]. find ( cond -> mSourceEntry ) == m_ConditionMap [ cond -> mSourceType ]. end ())
{
ConditionList mCondList ;
m_ConditionMap [ cond -> mSourceType ][ cond -> mSourceEntry ] = mCondList ;
}
//add new Condition to storage based on Type/Entry
m_ConditionMap [ cond -> mSourceType ][ cond -> mSourceEntry ]. push_back ( cond );
++ count ;
}
while ( result -> NextRow ());
2010-12-23 23:25:44 +01:00
sLog -> outString ( ">> Loaded %u conditions in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
sLog -> outString ();
2010-06-04 23:24:48 +02:00
}
bool ConditionMgr :: addToLootTemplate ( Condition * cond , LootTemplate * loot )
{
if ( ! loot )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "ConditionMgr: LootTemplate %u not found" , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( loot -> addConditionItem ( cond ))
return true ;
2010-08-06 19:23:43 +02:00
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "ConditionMgr: Item %u not found in LootTemplate %u" , cond -> mSourceEntry , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
bool ConditionMgr :: addToGossipMenus ( Condition * cond )
{
2010-12-22 21:25:23 +01:00
GossipMenusMapBoundsNonConst pMenuBounds = sObjectMgr -> GetGossipMenusMapBoundsNonConst ( cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
if ( pMenuBounds . first != pMenuBounds . second )
{
for ( GossipMenusMap :: iterator itr = pMenuBounds . first ; itr != pMenuBounds . second ; ++ itr )
{
if (( * itr ). second . entry == cond -> mSourceGroup && ( * itr ). second . text_id == cond -> mSourceEntry )
{
( * itr ). second . conditions . push_back ( cond );
return true ;
}
}
2010-06-11 01:25:10 +02:00
}
2010-08-06 19:23:43 +02:00
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "addToGossipMenus: GossipMenu %u not found" , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
bool ConditionMgr :: addToGossipMenuItems ( Condition * cond )
{
2010-12-22 21:25:23 +01:00
GossipMenuItemsMapBoundsNonConst pMenuItemBounds = sObjectMgr -> GetGossipMenuItemsMapBoundsNonConst ( cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
if ( pMenuItemBounds . first != pMenuItemBounds . second )
{
for ( GossipMenuItemsMap :: iterator itr = pMenuItemBounds . first ; itr != pMenuItemBounds . second ; ++ itr )
{
2011-05-26 23:57:17 +02:00
if (( * itr ). second . MenuId == cond -> mSourceGroup && ( * itr ). second . OptionIndex == cond -> mSourceEntry )
2010-06-04 23:24:48 +02:00
{
2011-05-26 23:57:17 +02:00
( * itr ). second . Conditions . push_back ( cond );
2010-06-04 23:24:48 +02:00
return true ;
}
}
}
2010-08-06 19:23:43 +02:00
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "addToGossipMenuItems: GossipMenuId %u Item %u not found" , cond -> mSourceGroup , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
bool ConditionMgr :: isSourceTypeValid ( Condition * cond )
{
2010-09-20 22:11:55 +02:00
if ( cond -> mSourceType == CONDITION_SOURCE_TYPE_NONE || cond -> mSourceType >= CONDITION_SOURCE_TYPE_MAX )
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Invalid ConditionSourceType %u in `condition` table, ignoring." , uint32 ( cond -> mSourceType ));
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
switch ( cond -> mSourceType )
{
case CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE :
{
if ( ! LootTemplates_Creature . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `creature_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Creature . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE :
{
if ( ! LootTemplates_Disenchant . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `disenchant_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Disenchant . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE :
{
if ( ! LootTemplates_Fishing . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `fishing_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Fishing . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE :
2010-06-11 01:25:10 +02:00
{
2010-06-04 23:24:48 +02:00
if ( ! LootTemplates_Gameobject . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `gameobject_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Gameobject . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE :
2010-06-11 01:25:10 +02:00
{
2010-06-04 23:24:48 +02:00
if ( ! LootTemplates_Item . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `item_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Item . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE :
{
if ( ! LootTemplates_Mail . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `mail_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Mail . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE :
{
if ( ! LootTemplates_Milling . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `milling_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Milling . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE :
{
if ( ! LootTemplates_Pickpocketing . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Pickpocketing . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE :
{
if ( ! LootTemplates_Prospecting . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `prospecting_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Prospecting . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE :
{
if ( ! LootTemplates_Reference . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `reference_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Reference . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE :
{
if ( ! LootTemplates_Skinning . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `skinning_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Skinning . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE :
{
if ( ! LootTemplates_Spell . HaveLootFor ( cond -> mSourceGroup ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `spell_loot_template`, ignoring." , cond -> mSourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
LootTemplate * loot = LootTemplates_Spell . GetLootForConditionFill ( cond -> mSourceGroup );
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto && ! loot -> isReference ( cond -> mSourceEntry ))
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> mSourceType , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET :
{
if ( cond -> mConditionType != CONDITION_SPELL_SCRIPT_TARGET )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, has ConditionType %u. Only CONDITION_SPELL_SCRIPT_TARGET(18) is valid for CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET(14), ignoring." , cond -> mSourceEntry , uint32 ( cond -> mConditionType ));
2010-06-04 23:24:48 +02:00
return false ;
}
2011-07-26 23:09:28 +02:00
SpellInfo const * spellProto = sSpellMgr -> GetSpellInfo ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! spellProto )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring." , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
bool targetfound = false ;
2010-09-28 08:21:51 +03:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2010-06-04 23:24:48 +02:00
{
2011-07-26 23:09:28 +02:00
if ( spellProto -> Effects [ i ]. TargetA == TARGET_UNIT_AREA_ENTRY_SRC ||
spellProto -> Effects [ i ]. TargetB == TARGET_UNIT_AREA_ENTRY_SRC ||
spellProto -> Effects [ i ]. TargetA == TARGET_UNIT_AREA_ENTRY_DST ||
spellProto -> Effects [ i ]. TargetB == TARGET_UNIT_AREA_ENTRY_DST ||
spellProto -> Effects [ i ]. TargetA == TARGET_UNIT_NEARBY_ENTRY ||
spellProto -> Effects [ i ]. TargetB == TARGET_UNIT_NEARBY_ENTRY ||
spellProto -> Effects [ i ]. TargetA == TARGET_GAMEOBJECT_NEARBY_ENTRY ||
spellProto -> Effects [ i ]. TargetB == TARGET_GAMEOBJECT_NEARBY_ENTRY ||
spellProto -> Effects [ i ]. TargetA == TARGET_GAMEOBJECT_AREA_SRC ||
spellProto -> Effects [ i ]. TargetB == TARGET_GAMEOBJECT_AREA_SRC ||
spellProto -> Effects [ i ]. TargetA == TARGET_GAMEOBJECT_AREA_DST ||
spellProto -> Effects [ i ]. TargetB == TARGET_GAMEOBJECT_AREA_DST ||
spellProto -> Effects [ i ]. TargetA == TARGET_DST_NEARBY_ENTRY ||
spellProto -> Effects [ i ]. TargetB == TARGET_DST_NEARBY_ENTRY ||
spellProto -> Effects [ i ]. TargetA == TARGET_UNIT_CONE_ENTRY ||
spellProto -> Effects [ i ]. TargetB == TARGET_UNIT_CONE_ENTRY )
2010-06-04 23:24:48 +02:00
{
targetfound = true ;
2010-10-16 16:34:21 +02:00
//break;
}
else if ( cond -> mConditionValue3 & ( 1 << i ))
{
cond -> mConditionValue3 &= ~ ( 1 << i );
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table does not have any implicit target TARGET_UNIT_NEARBY_ENTRY(38) or TARGET_DST_NEARBY_ENTRY (46)"
2011-04-29 20:47:02 +02:00
", TARGET_UNIT_AREA_ENTRY_SRC(7), TARGET_UNIT_AREA_ENTRY_DST(8), TARGET_UNIT_CONE_ENTRY(60), TARGET_GAMEOBJECT_NEARBY_ENTRY(40)"
2010-10-16 16:34:21 +02:00
"TARGET_GAMEOBJECT_AREA_SRC(51), TARGET_GAMEOBJECT_AREA_DST(52) in effect %u" , cond -> mSourceEntry , uint32 ( i ));
2010-06-04 23:24:48 +02:00
}
}
2010-10-16 16:34:21 +02:00
if ( ! targetfound && ! cond -> mConditionValue3 ) // cond->mConditionValue3 already errored up there
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table does not have any implicit target TARGET_UNIT_NEARBY_ENTRY(38) or TARGET_DST_NEARBY_ENTRY (46)"
2011-04-29 20:47:02 +02:00
", TARGET_UNIT_AREA_ENTRY_SRC(7), TARGET_UNIT_AREA_ENTRY_DST(8), TARGET_UNIT_CONE_ENTRY(60), TARGET_GAMEOBJECT_NEARBY_ENTRY(40)"
2010-07-30 01:51:33 +02:00
"TARGET_GAMEOBJECT_AREA_SRC(51), TARGET_GAMEOBJECT_AREA_DST(52)" , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
2011-07-26 23:09:28 +02:00
if (( cond -> mConditionValue1 == SPELL_TARGET_TYPE_DEAD ) && ! spellProto -> IsAllowingDeadTarget ())
2010-08-30 17:32:51 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table does have SPELL_TARGET_TYPE_DEAD specified but spell does not have SPELL_ATTR2_ALLOW_DEAD_TARGET" , cond -> mSourceEntry );
2010-08-30 17:32:51 +02:00
return false ;
}
2010-06-04 23:24:48 +02:00
break ;
2010-06-10 20:52:15 +02:00
}
2010-06-04 23:24:48 +02:00
case CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE :
{
2011-04-28 22:57:08 +02:00
if ( ! sObjectMgr -> GetCreatureTemplate ( cond -> mSourceEntry ))
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring." , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_SPELL :
{
2011-07-26 23:09:28 +02:00
SpellInfo const * spellProto = sSpellMgr -> GetSpellInfo ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! spellProto )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring." , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_ITEM_REQUIRED_TARGET :
{
if ( cond -> mConditionType != CONDITION_ITEM_TARGET )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, has ConditionType %u. Only CONDITION_ITEM_TARGET(24) is valid for CONDITION_SOURCE_TYPE_ITEM_REQUIRED_TARGET(18), ignoring." , cond -> mSourceEntry , uint32 ( cond -> mConditionType ));
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2011-04-28 22:42:33 +02:00
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! pItemProto )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `item_tamplate`, ignoring." , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
bool bIsItemSpellValid = false ;
for ( uint8 i = 0 ; i < MAX_ITEM_PROTO_SPELLS ; ++ i )
{
2011-07-26 23:09:28 +02:00
if ( SpellInfo const * pSpellInfo = sSpellMgr -> GetSpellInfo ( pItemProto -> Spells [ i ]. SpellId ))
2010-06-04 23:24:48 +02:00
{
if ( pItemProto -> Spells [ i ]. SpellTrigger == ITEM_SPELLTRIGGER_ON_USE ||
pItemProto -> Spells [ i ]. SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE )
{
2010-12-22 21:25:23 +01:00
ConditionList conditions = sConditionMgr -> GetConditionsForNotGroupedEntry ( CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET , pSpellInfo -> Id ); //script loading is done before item target loading
2010-06-04 23:24:48 +02:00
if ( ! conditions . empty ())
break ;
2010-09-28 08:21:51 +03:00
for ( int j = 0 ; j < MAX_SPELL_EFFECTS ; ++ j )
2010-06-04 23:24:48 +02:00
{
2011-07-26 23:09:28 +02:00
if ( pSpellInfo -> Effects [ j ]. TargetA == TARGET_UNIT_TARGET_ENEMY ||
pSpellInfo -> Effects [ j ]. TargetB == TARGET_UNIT_TARGET_ENEMY ||
pSpellInfo -> Effects [ j ]. TargetA == TARGET_UNIT_TARGET_ANY ||
pSpellInfo -> Effects [ j ]. TargetB == TARGET_UNIT_TARGET_ANY )
2010-06-04 23:24:48 +02:00
{
bIsItemSpellValid = true ;
break ;
}
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( bIsItemSpellValid )
break ;
}
}
}
if ( ! bIsItemSpellValid )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Conditions: CONDITION_SOURCE_TYPE_ITEM_REQUIRED_TARGET for item %u, which either doesn't have item spelltrigger or its spells don't have implicit target "
2010-07-31 04:12:30 +02:00
"TARGET_UNIT_TARGET_ENEMY(6), TARGET_UNIT_TARGET_ANY(25), or the spells are already listed in CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET conditions." , cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
break ;
}
break ;
}
2010-09-19 19:49:23 +02:00
case CONDITION_SOURCE_TYPE_QUEST_ACCEPT :
{
2010-12-22 21:25:23 +01:00
Quest const * Quest = sObjectMgr -> GetQuestTemplate ( cond -> mSourceEntry );
2010-09-19 19:49:23 +02:00
if ( ! Quest )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "CONDITION_SOURCE_TYPE_QUEST_ACCEPT specifies non-existing quest (%u), skipped" , cond -> mSourceEntry );
2010-09-20 10:19:20 +02:00
return false ;
}
}
break ;
case CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK :
{
2010-12-22 21:25:23 +01:00
Quest const * Quest = sObjectMgr -> GetQuestTemplate ( cond -> mSourceEntry );
2010-09-20 10:19:20 +02:00
if ( ! Quest )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK specifies non-existing quest (%u), skipped" , cond -> mSourceEntry );
2010-09-19 19:49:23 +02:00
return false ;
}
}
break ;
2010-10-22 22:45:11 +02:00
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL :
{
2011-04-28 22:57:08 +02:00
if ( ! sObjectMgr -> GetCreatureTemplate ( cond -> mSourceGroup ))
2010-10-22 22:45:11 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring." , cond -> mSourceGroup );
2010-10-22 22:45:11 +02:00
return false ;
}
2011-07-26 23:09:28 +02:00
SpellInfo const * spellProto = sSpellMgr -> GetSpellInfo ( cond -> mSourceEntry );
2010-10-22 22:45:11 +02:00
if ( ! spellProto )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring." , cond -> mSourceEntry );
2010-10-22 22:45:11 +02:00
return false ;
}
break ;
}
2010-06-04 23:24:48 +02:00
case CONDITION_SOURCE_TYPE_GOSSIP_MENU :
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION :
case CONDITION_SOURCE_TYPE_NONE :
2010-09-21 10:11:25 +02:00
default :
2010-06-04 23:24:48 +02:00
break ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
return true ;
}
bool ConditionMgr :: isConditionTypeValid ( Condition * cond )
{
2010-09-20 22:11:55 +02:00
if ( cond -> mConditionType == CONDITION_NONE || cond -> mConditionType >= CONDITION_MAX )
2010-06-04 23:24:48 +02:00
{
2011-04-29 20:47:02 +02:00
sLog -> outErrorDb ( "Invalid ConditionType %u at SourceEntry %u in `condition` table, ignoring." , uint32 ( cond -> mConditionType ), cond -> mSourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
switch ( cond -> mConditionType )
{
case CONDITION_AURA :
{
2011-07-26 23:09:28 +02:00
if ( ! sSpellMgr -> GetSpellInfo ( cond -> mConditionValue1 ))
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Aura condition has non existing spell (Id: %d), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 > 2 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Aura condition has non existing effect index (%u) (must be 0..2), skipped" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_ITEM :
{
2011-04-28 22:42:33 +02:00
ItemTemplate const * proto = sObjectMgr -> GetItemTemplate ( cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! proto )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item condition has non existing item (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( ! cond -> mConditionValue2 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Item condition has 0 set for item count in value2 (%u), skipped" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_ITEM_EQUIPPED :
{
2011-04-28 22:42:33 +02:00
ItemTemplate const * proto = sObjectMgr -> GetItemTemplate ( cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! proto )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "ItemEquipped condition has non existing item (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "ItemEquipped condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_ZONEID :
{
AreaTableEntry const * areaEntry = GetAreaEntryByAreaID ( cond -> mConditionValue1 );
if ( ! areaEntry )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Zone condition has non existing area (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( areaEntry -> zone != 0 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Zone condition requires to be in area (%u) which is a subzone but zone expected, skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Zone condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_REPUTATION_RANK :
{
FactionEntry const * factionEntry = sFactionStore . LookupEntry ( cond -> mConditionValue1 );
if ( ! factionEntry )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Reputation condition has non existing faction (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_TEAM :
{
if ( cond -> mConditionValue1 != ALLIANCE && cond -> mConditionValue1 != HORDE )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Team condition specifies unknown team (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Team condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_SKILL :
{
SkillLineEntry const * pSkill = sSkillLineStore . LookupEntry ( cond -> mConditionValue1 );
if ( ! pSkill )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Skill condition specifies non-existing skill (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-12-23 23:25:44 +01:00
if ( cond -> mConditionValue2 < 1 || cond -> mConditionValue2 > sWorld -> GetConfigMaxSkillValue ())
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Skill condition specifies invalid skill value (%u), skipped" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_QUESTREWARDED :
case CONDITION_QUESTTAKEN :
case CONDITION_QUEST_NONE :
2010-10-24 21:44:58 +02:00
case CONDITION_QUEST_COMPLETE :
2010-06-04 23:24:48 +02:00
{
2010-12-22 21:25:23 +01:00
Quest const * Quest = sObjectMgr -> GetQuestTemplate ( cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! Quest )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest condition specifies non-existing quest (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2011-04-21 16:23:20 +06:00
if ( cond -> mConditionValue2 > 1 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Quest condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_NO_AURA :
{
2011-07-26 23:09:28 +02:00
if ( ! sSpellMgr -> GetSpellInfo ( cond -> mConditionValue1 ))
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Aura condition has non existing spell (Id: %d), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 > 2 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Aura condition has non existing effect index (%u) in value2 (must be 0..2), skipped" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_ACTIVE_EVENT :
{
2010-12-22 21:25:23 +01:00
GameEventMgr :: GameEventDataMap const & events = sGameEventMgr -> GetEventMap ();
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue1 >= events . size () || ! events [ cond -> mConditionValue1 ]. isValid ())
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Active event condition has non existing event id (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Active event condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_ACHIEVEMENT :
{
AchievementEntry const * achievement = GetAchievementStore () -> LookupEntry ( cond -> mConditionValue1 );
if ( ! achievement )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Achivemen condition has non existing achivement id (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Achivemen condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_CLASS :
{
if ( cond -> mConditionValue1 >= MAX_CLASSES )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Class condition has non existing class (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Class condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_RACE :
{
if ( cond -> mConditionValue1 >= MAX_RACES )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Race condition has non existing race (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Race condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_SPELL_SCRIPT_TARGET :
{
if ( cond -> mConditionValue1 >= MAX_SPELL_TARGET_TYPE )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SpellTarget condition has non existing spell target type (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
2010-06-11 01:25:10 +02:00
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
switch ( cond -> mConditionValue1 )
{
2010-06-11 01:25:10 +02:00
case SPELL_TARGET_TYPE_GAMEOBJECT :
2010-06-04 23:24:48 +02:00
{
2011-04-28 22:54:30 +02:00
if ( cond -> mConditionValue2 && ! sObjectMgr -> GetGameObjectTemplate ( cond -> mConditionValue2 ))
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SpellTarget condition has non existing gameobject (%u) as target, skipped" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case SPELL_TARGET_TYPE_CONTROLLED :
case SPELL_TARGET_TYPE_CREATURE :
case SPELL_TARGET_TYPE_DEAD :
{
2011-04-28 22:57:08 +02:00
if ( cond -> mConditionValue2 && ! sObjectMgr -> GetCreatureTemplate ( cond -> mConditionValue2 ))
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SpellTarget condition has non existing creature template entry (%u) as target, skipped" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
2011-04-28 22:57:08 +02:00
const CreatureTemplate * cInfo = sObjectMgr -> GetCreatureTemplate ( cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
if ( cond -> mSourceEntry == 30427 && ! cInfo -> SkinLootId )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "SpellTarget condition has creature entry %u as a target of spellid 30427, but this creature has no skinlootid. Gas extraction will not work!, skipped" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
}
break ;
}
case CONDITION_CREATURE_TARGET :
{
2011-04-28 22:57:08 +02:00
if ( ! cond -> mConditionValue1 && ! sObjectMgr -> GetCreatureTemplate ( cond -> mConditionValue1 ))
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "CreatureTarget condition has non existing creature template entry (%u) as target, skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "CreatureTarget condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_TARGET_HEALTH_BELOW_PCT :
{
if ( cond -> mConditionValue1 > 100 )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "TargetHealthBelowPct condition has invalid data in value1 (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "TargetHealthBelowPct condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_TARGET_RANGE :
{
if ( cond -> mConditionValue2 && cond -> mConditionValue2 < cond -> mConditionValue1 ) //maxDist can be 0 for infinit max range
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "TargetRange condition has max distance closer then min distance, skipped" );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_MAPID :
{
2011-06-11 22:35:29 +02:00
MapEntry const * me = sMapStore . LookupEntry ( cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! me )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Map condition has non existing map (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Map condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_ITEM_TARGET :
{
if ( ! cond -> mConditionValue1 || cond -> mConditionValue1 > MAX_ITEM_REQ_TARGET_TYPE )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "ItemTarget condition has incorrect target type (%u), skipped" , cond -> mConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2011-04-28 22:57:08 +02:00
if ( ! cond -> mConditionValue2 && ! sObjectMgr -> GetCreatureTemplate ( cond -> mConditionValue2 ))
2010-06-04 23:24:48 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "ItemTarget condition has non existing creature template entry (%u) as target, skipped" , cond -> mConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
if ( cond -> mConditionValue3 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "ItemTarget condition has useless data in value3 (%u)!" , cond -> mConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
2010-09-10 20:49:29 +02:00
case CONDITION_SPELL :
{
2011-07-26 23:09:28 +02:00
if ( ! sSpellMgr -> GetSpellInfo ( cond -> mConditionValue1 ))
2010-09-10 20:49:29 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Spell condition has non existing spell (Id: %d), skipped" , cond -> mConditionValue1 );
2010-09-10 20:49:29 +02:00
return false ;
}
if ( cond -> mConditionValue2 )
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Spell condition has useless data in value2 (%u)!" , cond -> mConditionValue2 );
2010-09-10 20:49:29 +02:00
break ;
}
2010-09-30 22:41:19 +02:00
case CONDITION_NOITEM :
{
2011-04-28 22:42:33 +02:00
ItemTemplate const * proto = sObjectMgr -> GetItemTemplate ( cond -> mConditionValue1 );
2010-09-30 22:41:19 +02:00
if ( ! proto )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "NoItem condition has non existing item (%u), skipped" , cond -> mConditionValue1 );
2010-09-30 22:41:19 +02:00
return false ;
}
break ;
}
2010-10-05 17:54:27 +02:00
case CONDITION_LEVEL :
{
2010-10-05 18:07:41 +02:00
if ( cond -> mConditionValue2 >= LVL_COND_MAX )
2010-10-05 17:54:27 +02:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "Level condition has invalid option (%u), skipped" , cond -> mConditionValue2 );
2010-10-05 17:54:27 +02:00
return false ;
}
break ;
}
2010-10-11 23:35:55 +02:00
case CONDITION_DRUNKENSTATE :
{
if ( cond -> mConditionValue1 > DRUNKEN_SMASHED )
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "DrunkState condition has invalid state (%u), skipped" , cond -> mConditionValue1 );
2010-10-11 23:35:55 +02:00
return false ;
}
break ;
}
2010-10-31 22:10:31 +01:00
case CONDITION_NEAR_CREATURE :
{
2011-04-28 22:57:08 +02:00
if ( ! sObjectMgr -> GetCreatureTemplate ( cond -> mConditionValue1 ))
2010-10-31 22:10:31 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "NearCreature condition has non existing creature template entry (%u), skipped" , cond -> mConditionValue1 );
2010-10-31 22:10:31 +01:00
return false ;
}
break ;
}
case CONDITION_NEAR_GAMEOBJECT :
{
2011-04-28 22:54:30 +02:00
if ( ! sObjectMgr -> GetGameObjectTemplate ( cond -> mConditionValue1 ))
2010-10-31 22:10:31 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outErrorDb ( "NearGameObject condition has non existing gameobject template entry (%u), skipped" , cond -> mConditionValue1 );
2010-10-31 22:10:31 +01:00
return false ;
}
break ;
}
2010-06-04 23:24:48 +02:00
case CONDITION_AREAID :
case CONDITION_INSTANCE_DATA :
break ;
2010-08-21 20:55:31 +02:00
default :
break ;
2010-06-04 23:24:48 +02:00
}
return true ;
}
2010-06-11 01:25:10 +02:00
void ConditionMgr :: Clean ()
{
for ( ConditionReferenceMap :: iterator itr = m_ConditionReferenceMap . begin (); itr != m_ConditionReferenceMap . end (); ++ itr )
{
for ( ConditionList :: const_iterator it = itr -> second . begin (); it != itr -> second . end (); ++ it )
delete * it ;
itr -> second . clear ();
}
2010-08-06 19:23:43 +02:00
2010-06-11 01:25:10 +02:00
m_ConditionReferenceMap . clear ();
for ( ConditionMap :: iterator itr = m_ConditionMap . begin (); itr != m_ConditionMap . end (); ++ itr )
{
for ( ConditionTypeMap :: iterator it = itr -> second . begin (); it != itr -> second . end (); ++ it )
{
for ( ConditionList :: const_iterator i = it -> second . begin (); i != it -> second . end (); ++ i )
delete * i ;
it -> second . clear ();
}
itr -> second . clear ();
}
2010-08-06 19:23:43 +02:00
2010-06-11 01:25:10 +02:00
m_ConditionMap . clear ();
2010-10-22 22:45:11 +02:00
for ( VehicleSpellConditionMap :: iterator itr = m_VehicleSpellConditions . begin (); itr != m_VehicleSpellConditions . end (); ++ itr )
{
for ( ConditionTypeMap :: iterator it = itr -> second . begin (); it != itr -> second . end (); ++ it )
{
for ( ConditionList :: const_iterator i = it -> second . begin (); i != it -> second . end (); ++ i )
delete * i ;
it -> second . clear ();
}
itr -> second . clear ();
}
m_VehicleSpellConditions . clear ();
2010-06-11 01:25:10 +02:00
// this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
for ( std :: list < Condition *>:: const_iterator itr = m_AllocatedMemory . begin (); itr != m_AllocatedMemory . end (); ++ itr )
delete * itr ;
2010-08-06 19:23:43 +02:00
2010-06-11 01:25:10 +02:00
m_AllocatedMemory . clear ();
}