2010-10-07 15:35:36 +02:00
/*
2012-01-01 00:32:13 +01:00
* Copyright (C) 2008-2012 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"
2012-02-21 20:03:27 +01:00
#include "Spell.h"
2010-06-04 23:24:48 +02:00
2012-02-10 14:18:59 +01:00
// Checks if object meets the condition
2010-06-04 23:24:48 +02:00
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI)
2012-02-10 23:40:38 +01:00
bool Condition :: Meets ( ConditionSourceInfo & sourceInfo )
2010-06-10 20:52:15 +02:00
{
2012-02-14 12:46:26 -05:00
ASSERT ( ConditionTarget < MAX_CONDITION_TARGETS );
WorldObject * object = sourceInfo . mConditionTargets [ ConditionTarget ];
2012-02-10 14:18:59 +01:00
// object not present, return false
if ( ! object )
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "Condition object not found for condition (Entry: %u Type: %u Group: %u)" , SourceEntry , SourceType , SourceGroup );
2012-02-10 14:18:59 +01:00
return false ;
2010-06-04 23:24:48 +02:00
}
bool condMeets = false ;
2012-02-14 12:46:26 -05:00
switch ( ConditionType )
2010-06-04 23:24:48 +02:00
{
case CONDITION_NONE :
condMeets = true ; // empty condition, always met
break ;
case CONDITION_AURA :
2012-02-10 14:18:59 +01:00
{
if ( Unit * unit = object -> ToUnit ())
2012-02-16 13:16:43 +01:00
condMeets = unit -> HasAuraEffect ( ConditionValue1 , ConditionValue2 );
2010-06-04 23:24:48 +02:00
break ;
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
case CONDITION_ITEM :
2012-02-10 14:18:59 +01:00
{
if ( Player * player = object -> ToPlayer ())
2012-02-10 16:47:22 +01:00
{
// don't allow 0 items (it's checked during table load)
2012-02-14 12:46:26 -05:00
ASSERT ( ConditionValue2 );
bool checkBank = ConditionValue3 ? true : false ;
condMeets = player -> HasItemCount ( ConditionValue1 , ConditionValue2 , checkBank );
2012-02-10 16:47:22 +01:00
}
2010-06-04 23:24:48 +02:00
break ;
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
case CONDITION_ITEM_EQUIPPED :
2012-02-10 14:18:59 +01:00
{
if ( Player * player = object -> ToPlayer ())
2012-02-14 12:46:26 -05:00
condMeets = player -> HasItemOrGemWithIdEquipped ( ConditionValue1 , 1 );
2010-06-04 23:24:48 +02:00
break ;
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
case CONDITION_ZONEID :
2012-02-14 12:46:26 -05:00
condMeets = object -> GetZoneId () == ConditionValue1 ;
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_REPUTATION_RANK :
{
2012-02-10 14:18:59 +01:00
if ( Player * player = object -> ToPlayer ())
{
2012-02-14 12:46:26 -05:00
if ( FactionEntry const * faction = sFactionStore . LookupEntry ( ConditionValue1 ))
condMeets = ( ConditionValue2 & ( 1 << player -> GetReputationMgr (). GetRank ( faction )));
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_ACHIEVEMENT :
2012-02-10 14:18:59 +01:00
{
if ( Player * player = object -> ToPlayer ())
2012-02-14 12:46:26 -05:00
condMeets = player -> GetAchievementMgr (). HasAchieved ( ConditionValue1 );
2010-06-04 23:24:48 +02:00
break ;
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
case CONDITION_TEAM :
2012-02-10 14:18:59 +01:00
{
if ( Player * player = object -> ToPlayer ())
2012-02-14 12:46:26 -05:00
condMeets = player -> GetTeam () == ConditionValue1 ;
2010-06-04 23:24:48 +02:00
break ;
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
case CONDITION_CLASS :
2012-02-10 14:18:59 +01:00
{
2012-02-21 20:03:27 +01:00
if ( Unit * unit = object -> ToUnit ())
condMeets = unit -> getClassMask () & ConditionValue1 ;
2010-06-04 23:24:48 +02:00
break ;
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
case CONDITION_RACE :
2012-02-10 14:18:59 +01:00
{
2012-02-21 20:03:27 +01:00
if ( Unit * unit = object -> ToUnit ())
condMeets = unit -> getRaceMask () & ConditionValue1 ;
2010-06-04 23:24:48 +02:00
break ;
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
case CONDITION_SKILL :
2012-02-10 14:18:59 +01:00
{
if ( Player * player = object -> ToPlayer ())
2012-02-14 12:46:26 -05:00
condMeets = player -> HasSkill ( ConditionValue1 ) && player -> GetBaseSkillValue ( ConditionValue1 ) >= ConditionValue2 ;
2010-06-04 23:24:48 +02:00
break ;
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
case CONDITION_QUESTREWARDED :
2012-02-10 14:18:59 +01:00
{
if ( Player * player = object -> ToPlayer ())
2012-02-29 13:55:57 +01:00
condMeets = player -> GetQuestRewardStatus ( ConditionValue1 );
2010-06-04 23:24:48 +02:00
break ;
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
case CONDITION_QUESTTAKEN :
{
2012-02-10 14:18:59 +01:00
if ( Player * player = object -> ToPlayer ())
{
2012-02-14 12:46:26 -05:00
QuestStatus status = player -> GetQuestStatus ( ConditionValue1 );
2012-02-29 13:55:57 +01:00
condMeets = ( status == QUEST_STATUS_INCOMPLETE );
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
break ;
}
2010-10-24 21:44:58 +02:00
case CONDITION_QUEST_COMPLETE :
{
2012-02-10 14:18:59 +01:00
if ( Player * player = object -> ToPlayer ())
{
2012-02-14 12:46:26 -05:00
QuestStatus status = player -> GetQuestStatus ( ConditionValue1 );
2012-02-29 13:55:57 +01:00
condMeets = ( status == QUEST_STATUS_COMPLETE && ! player -> GetQuestRewardStatus ( ConditionValue1 ));
2012-02-10 14:18:59 +01:00
}
2010-10-24 21:44:58 +02:00
break ;
}
2010-06-04 23:24:48 +02:00
case CONDITION_QUEST_NONE :
{
2012-02-10 14:18:59 +01:00
if ( Player * player = object -> ToPlayer ())
{
2012-02-14 12:46:26 -05:00
QuestStatus status = player -> GetQuestStatus ( ConditionValue1 );
2012-02-29 13:55:57 +01:00
condMeets = ( status == QUEST_STATUS_NONE );
2012-02-10 14:18:59 +01:00
}
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_ACTIVE_EVENT :
2012-02-14 12:46:26 -05:00
condMeets = sGameEventMgr -> IsActiveEvent ( ConditionValue1 );
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_INSTANCE_DATA :
{
2012-02-10 14:18:59 +01:00
Map * map = object -> GetMap ();
2010-08-08 22:54:58 +06:00
if ( map && map -> IsDungeon () && (( InstanceMap * ) map ) -> GetInstanceScript ())
2012-02-14 12:46:26 -05:00
condMeets = (( InstanceMap * ) map ) -> GetInstanceScript () -> GetData ( ConditionValue1 ) == ConditionValue2 ;
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_MAPID :
2012-02-14 12:46:26 -05:00
condMeets = object -> GetMapId () == ConditionValue1 ;
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_AREAID :
2012-02-14 12:46:26 -05:00
condMeets = object -> GetAreaId () == ConditionValue1 ;
2010-06-04 23:24:48 +02:00
break ;
2010-09-10 20:49:29 +02:00
case CONDITION_SPELL :
2012-02-10 14:18:59 +01:00
{
if ( Player * player = object -> ToPlayer ())
2012-02-14 12:46:26 -05:00
condMeets = player -> HasSpell ( ConditionValue1 );
2010-09-10 20:49:29 +02:00
break ;
2012-02-10 14:18:59 +01:00
}
2010-10-05 17:54:27 +02:00
case CONDITION_LEVEL :
2011-08-04 14:27:10 +02:00
{
2012-02-10 14:18:59 +01:00
if ( Unit * unit = object -> ToUnit ())
2012-02-14 12:46:26 -05:00
condMeets = CompareValues ( static_cast < ComparisionType > ( ConditionValue2 ), static_cast < uint32 > ( unit -> getLevel ()), ConditionValue1 );
2011-08-04 14:27:10 +02:00
break ;
}
2010-10-11 23:35:55 +02:00
case CONDITION_DRUNKENSTATE :
2011-08-04 14:27:10 +02:00
{
2012-02-10 14:18:59 +01:00
if ( Player * player = object -> ToPlayer ())
2012-02-14 12:46:26 -05:00
condMeets = ( uint32 ) Player :: GetDrunkenstateByValue ( player -> GetDrunkValue ()) >= ConditionValue1 ;
2011-08-04 14:27:10 +02:00
break ;
}
2010-10-31 22:10:31 +01:00
case CONDITION_NEAR_CREATURE :
2011-08-04 14:27:10 +02:00
{
2012-02-14 12:46:26 -05:00
condMeets = GetClosestCreatureWithEntry ( object , ConditionValue1 , ( float ) ConditionValue2 ) ? true : false ;
2011-08-04 14:27:10 +02:00
break ;
}
2010-10-31 22:10:31 +01:00
case CONDITION_NEAR_GAMEOBJECT :
2011-08-04 14:27:10 +02:00
{
2012-02-14 12:46:26 -05:00
condMeets = GetClosestGameObjectWithEntry ( object , ConditionValue1 , ( float ) ConditionValue2 ) ? true : false ;
2011-08-04 14:27:10 +02:00
break ;
}
2012-02-11 15:16:18 +01:00
case CONDITION_OBJECT_ENTRY :
{
2012-02-14 12:46:26 -05:00
if ( object -> GetTypeId () == ConditionValue1 )
2012-02-18 16:52:08 +01:00
condMeets = ( ! ConditionValue2 ) || ( object -> GetEntry () == ConditionValue2 );
2012-02-11 15:16:18 +01:00
break ;
}
case CONDITION_TYPE_MASK :
{
2012-02-14 12:46:26 -05:00
condMeets = object -> isType ( ConditionValue1 );
2012-02-11 15:16:18 +01:00
break ;
}
case CONDITION_RELATION_TO :
{
2012-02-14 12:46:26 -05:00
if ( WorldObject * toObject = sourceInfo . mConditionTargets [ ConditionValue1 ])
2012-02-11 15:16:18 +01:00
{
Unit * toUnit = toObject -> ToUnit ();
Unit * unit = object -> ToUnit ();
if ( toUnit && unit )
{
2012-02-14 12:46:26 -05:00
switch ( ConditionValue2 )
2012-02-11 15:16:18 +01:00
{
case RELATION_SELF :
condMeets = unit == toUnit ;
break ;
case RELATION_IN_PARTY :
condMeets = unit -> IsInPartyWith ( toUnit );
break ;
case RELATION_IN_RAID_OR_PARTY :
condMeets = unit -> IsInRaidWith ( toUnit );
break ;
case RELATION_OWNED_BY :
condMeets = unit -> GetOwnerGUID () == toUnit -> GetGUID ();
break ;
case RELATION_PASSENGER_OF :
condMeets = unit -> IsOnVehicle ( toUnit );
break ;
}
}
}
break ;
}
case CONDITION_REACTION_TO :
{
2012-02-14 12:46:26 -05:00
if ( WorldObject * toObject = sourceInfo . mConditionTargets [ ConditionValue1 ])
2012-02-11 15:16:18 +01:00
{
Unit * toUnit = toObject -> ToUnit ();
Unit * unit = object -> ToUnit ();
if ( toUnit && unit )
2012-02-14 12:46:26 -05:00
condMeets = ( 1 << unit -> GetReactionTo ( toUnit )) & ConditionValue2 ;
2012-02-11 15:16:18 +01:00
}
break ;
}
case CONDITION_DISTANCE_TO :
{
2012-02-14 12:46:26 -05:00
if ( WorldObject * toObject = sourceInfo . mConditionTargets [ ConditionValue1 ])
condMeets = CompareValues ( static_cast < ComparisionType > ( ConditionValue3 ), object -> GetDistance ( toObject ), static_cast < float > ( ConditionValue2 ));
2012-02-11 15:16:18 +01:00
break ;
}
case CONDITION_ALIVE :
{
if ( Unit * unit = object -> ToUnit ())
condMeets = unit -> isAlive ();
break ;
}
case CONDITION_HP_VAL :
{
if ( Unit * unit = object -> ToUnit ())
2012-02-14 12:46:26 -05:00
condMeets = CompareValues ( static_cast < ComparisionType > ( ConditionValue2 ), unit -> GetHealth (), static_cast < uint32 > ( ConditionValue1 ));
2012-02-11 15:16:18 +01:00
break ;
}
case CONDITION_HP_PCT :
{
if ( Unit * unit = object -> ToUnit ())
2012-02-14 12:46:26 -05:00
condMeets = CompareValues ( static_cast < ComparisionType > ( ConditionValue2 ), unit -> GetHealthPct (), static_cast < float > ( ConditionValue1 ));
2012-02-11 15:16:18 +01:00
break ;
}
2012-02-11 19:46:41 +00:00
case CONDITION_WORLD_STATE :
{
2012-02-14 12:46:26 -05:00
condMeets = ConditionValue2 == sWorld -> getWorldState ( ConditionValue1 );
2012-02-11 19:46:41 +00:00
break ;
}
case CONDITION_PHASEMASK :
{
2012-02-14 12:46:26 -05:00
condMeets = object -> GetPhaseMask () & ConditionValue1 ;
2012-02-11 19:46:41 +00:00
break ;
}
2010-06-04 23:24:48 +02:00
default :
condMeets = false ;
break ;
}
2012-02-14 12:46:26 -05:00
if ( NegativeCondition )
2012-02-10 12:44:07 +01:00
condMeets = ! condMeets ;
2012-02-10 23:40:38 +01:00
if ( ! condMeets )
sourceInfo . mLastFailedCondition = this ;
2010-06-04 23:24:48 +02:00
2012-02-10 23:40:38 +01:00
bool script = sScriptMgr -> OnConditionCheck ( this , sourceInfo ); // Returns true by default.
2012-02-10 15:43:19 +01:00
return condMeets && script ;
2010-06-04 23:24:48 +02:00
}
2012-02-21 20:03:27 +01:00
uint32 Condition :: GetSearcherTypeMaskForCondition ()
{
// build mask of types for which condition can return true
// this is used for speeding up gridsearches
if ( NegativeCondition )
return ( GRID_MAP_TYPE_MASK_ALL );
uint32 mask = 0 ;
switch ( ConditionType )
{
case CONDITION_NONE :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
case CONDITION_AURA :
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_ITEM :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_ITEM_EQUIPPED :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_ZONEID :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
case CONDITION_REPUTATION_RANK :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_ACHIEVEMENT :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_TEAM :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_CLASS :
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_RACE :
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_SKILL :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_QUESTREWARDED :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_QUESTTAKEN :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_QUEST_COMPLETE :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_QUEST_NONE :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_ACTIVE_EVENT :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
case CONDITION_INSTANCE_DATA :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
case CONDITION_MAPID :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
case CONDITION_AREAID :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
case CONDITION_SPELL :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_LEVEL :
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_DRUNKENSTATE :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_NEAR_CREATURE :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
case CONDITION_NEAR_GAMEOBJECT :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
case CONDITION_OBJECT_ENTRY :
switch ( ConditionValue1 )
{
case TYPEID_UNIT :
mask |= GRID_MAP_TYPE_MASK_CREATURE ;
break ;
case TYPEID_PLAYER :
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case TYPEID_GAMEOBJECT :
mask |= GRID_MAP_TYPE_MASK_GAMEOBJECT ;
break ;
case TYPEID_CORPSE :
mask |= GRID_MAP_TYPE_MASK_CORPSE ;
break ;
default :
break ;
}
case CONDITION_TYPE_MASK :
if ( ConditionValue1 & TYPEMASK_UNIT )
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER ;
if ( ConditionValue1 & TYPEMASK_PLAYER )
mask |= GRID_MAP_TYPE_MASK_PLAYER ;
if ( ConditionValue1 & TYPEMASK_GAMEOBJECT )
mask |= GRID_MAP_TYPE_MASK_GAMEOBJECT ;
if ( ConditionValue1 & TYPEMASK_CORPSE )
mask |= GRID_MAP_TYPE_MASK_CORPSE ;
break ;
case CONDITION_RELATION_TO :
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_REACTION_TO :
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_DISTANCE_TO :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
case CONDITION_ALIVE :
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_HP_VAL :
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_HP_PCT :
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER ;
break ;
case CONDITION_WORLD_STATE :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
case CONDITION_PHASEMASK :
mask |= GRID_MAP_TYPE_MASK_ALL ;
break ;
default :
ASSERT ( false && "Condition::GetSearcherTypeMaskForCondition - missing condition handling!" );
break ;
}
return mask ;
}
2012-02-11 15:16:18 +01:00
uint32 Condition :: GetMaxAvailableConditionTargets ()
{
// returns number of targets which are available for given source type
2012-02-14 12:46:26 -05:00
switch ( SourceType )
2012-02-11 15:16:18 +01:00
{
case CONDITION_SOURCE_TYPE_SPELL :
2012-02-21 20:03:27 +01:00
case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET :
2012-02-15 22:12:15 +01:00
case CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE :
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL :
2012-02-20 23:21:12 +01:00
case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT :
2012-02-15 22:12:15 +01:00
case CONDITION_SOURCE_TYPE_GOSSIP_MENU :
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION :
2012-02-18 16:52:08 +01:00
case CONDITION_SOURCE_TYPE_SMART_EVENT :
return 2 ;
2012-02-11 15:16:18 +01:00
default :
return 1 ;
}
}
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 ;
2012-01-29 13:49:19 -05:00
ConditionReferenceContainer :: const_iterator ref = ConditionReferenceStore . find ( refId );
if ( ref != ConditionReferenceStore . end ())
2010-06-04 23:24:48 +02:00
conditions = ( * ref ). second ;
return conditions ;
}
2012-02-21 20:03:27 +01:00
uint32 ConditionMgr :: GetSearcherTypeMaskForConditionList ( ConditionList const & conditions )
{
if ( conditions . empty ())
return GRID_MAP_TYPE_MASK_ALL ;
// groupId, typeMask
std :: map < uint32 , uint32 > ElseGroupStore ;
for ( ConditionList :: const_iterator i = conditions . begin (); i != conditions . end (); ++ i )
{
// no point of having not loaded conditions in list
ASSERT (( * i ) -> isLoaded () && "ConditionMgr::GetSearcherTypeMaskForConditionList - not yet loaded condition found in list" );
std :: map < uint32 , uint32 >:: const_iterator itr = ElseGroupStore . find (( * i ) -> ElseGroup );
// group not filled yet, fill with widest mask possible
if ( itr == ElseGroupStore . end ())
ElseGroupStore [( * i ) -> ElseGroup ] = GRID_MAP_TYPE_MASK_ALL ;
// no point of checking anymore, empty mask
else if ( ! ( * itr ). second )
continue ;
if (( * i ) -> ReferenceId ) // handle reference
{
ConditionReferenceContainer :: const_iterator ref = ConditionReferenceStore . find (( * i ) -> ReferenceId );
ASSERT ( ref != ConditionReferenceStore . end () && "ConditionMgr::GetSearcherTypeMaskForConditionList - incorrect reference" );
ElseGroupStore [( * i ) -> ElseGroup ] &= GetSearcherTypeMaskForConditionList (( * ref ). second );
}
else // handle normal condition
{
// object will match conditions in one ElseGroupStore only when it matches all of them
// so, let's find a smallest possible mask which satisfies all conditions
ElseGroupStore [( * i ) -> ElseGroup ] &= ( * i ) -> GetSearcherTypeMaskForCondition ();
}
}
// object will match condition when one of the checks in ElseGroupStore is matching
// so, let's include all possible masks
uint32 mask = 0 ;
for ( std :: map < uint32 , uint32 >:: const_iterator i = ElseGroupStore . begin (); i != ElseGroupStore . end (); ++ i )
mask |= i -> second ;
return mask ;
}
2012-02-10 23:40:38 +01:00
bool ConditionMgr :: IsObjectMeetToConditionList ( ConditionSourceInfo & sourceInfo , ConditionList const & conditions )
2010-06-04 23:24:48 +02:00
{
2012-02-21 20:03:27 +01:00
// groupId, groupCheckPassed
2012-01-29 13:49:19 -05:00
std :: map < uint32 , bool > ElseGroupStore ;
2010-06-04 23:24:48 +02:00
for ( ConditionList :: const_iterator i = conditions . begin (); i != conditions . end (); ++ i )
{
2012-02-14 13:53:33 -05:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "ConditionMgr::IsPlayerMeetToConditionList condType: %u val1: %u" , ( * i ) -> ConditionType , ( * i ) -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
if (( * i ) -> isLoaded ())
{
2012-02-14 13:53:33 -05:00
std :: map < uint32 , bool >:: const_iterator itr = ElseGroupStore . find (( * i ) -> ElseGroup );
2012-01-29 13:49:19 -05:00
if ( itr == ElseGroupStore . end ())
2012-02-14 13:53:33 -05:00
ElseGroupStore [( * i ) -> ElseGroup ] = true ;
2010-06-04 23:24:48 +02:00
else if ( ! ( * itr ). second )
continue ;
2012-02-14 13:53:33 -05:00
if (( * i ) -> ReferenceId ) //handle reference
2010-06-04 23:24:48 +02:00
{
2012-02-14 13:53:33 -05:00
ConditionReferenceContainer :: const_iterator ref = ConditionReferenceStore . find (( * i ) -> ReferenceId );
2012-01-29 13:49:19 -05:00
if ( ref != ConditionReferenceStore . end ())
2010-06-04 23:24:48 +02:00
{
2012-02-10 23:40:38 +01:00
if ( ! IsObjectMeetToConditionList ( sourceInfo , ( * ref ). second ))
2012-02-14 13:53:33 -05:00
ElseGroupStore [( * i ) -> ElseGroup ] = 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" ,
2012-02-14 13:53:33 -05:00
( * i ) -> ReferenceId ); //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
{
2012-02-10 23:40:38 +01:00
if ( ! ( * i ) -> Meets ( sourceInfo ))
2012-02-14 13:53:33 -05:00
ElseGroupStore [( * i ) -> ElseGroup ] = false ;
2010-06-10 20:52:15 +02:00
}
2010-06-04 23:24:48 +02:00
}
}
2012-01-29 13:49:19 -05:00
for ( std :: map < uint32 , bool >:: const_iterator i = ElseGroupStore . begin (); i != ElseGroupStore . end (); ++ i )
2010-06-04 23:24:48 +02:00
if ( i -> second )
return true ;
2010-08-06 19:23:43 +02:00
2010-06-04 23:24:48 +02:00
return false ;
}
2012-02-10 23:40:38 +01:00
bool ConditionMgr :: IsObjectMeetToConditions ( WorldObject * object , ConditionList const & conditions )
{
2012-02-11 00:15:05 +01:00
ConditionSourceInfo srcInfo = ConditionSourceInfo ( object );
return IsObjectMeetToConditions ( srcInfo , conditions );
2012-02-10 23:40:38 +01:00
}
2012-02-15 22:12:15 +01:00
bool ConditionMgr :: IsObjectMeetToConditions ( WorldObject * object1 , WorldObject * object2 , ConditionList const & conditions )
{
ConditionSourceInfo srcInfo = ConditionSourceInfo ( object1 , object2 );
return IsObjectMeetToConditions ( srcInfo , conditions );
}
2012-02-10 23:40:38 +01:00
bool ConditionMgr :: IsObjectMeetToConditions ( ConditionSourceInfo & sourceInfo , ConditionList const & conditions )
2010-06-04 23:24:48 +02:00
{
if ( conditions . empty ())
return true ;
2010-08-06 19:23:43 +02:00
2012-02-10 23:40:38 +01:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "ConditionMgr::IsObjectMeetToConditions" );
return IsObjectMeetToConditionList ( sourceInfo , conditions );
2010-06-04 23:24:48 +02:00
}
2012-02-21 20:03:27 +01:00
bool ConditionMgr :: CanHaveSourceGroupSet ( ConditionSourceType sourceType ) const
{
return ( sourceType == CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU ||
sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION ||
sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL ||
sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET ||
2012-02-21 20:17:32 +01:00
sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT ||
2012-02-21 20:03:27 +01:00
sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT );
}
bool ConditionMgr :: CanHaveSourceIdSet ( ConditionSourceType sourceType ) const
{
return ( sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT );
}
2012-01-29 13:49:19 -05:00
ConditionList ConditionMgr :: GetConditionsForNotGroupedEntry ( ConditionSourceType sourceType , uint32 entry )
2010-06-04 23:24:48 +02:00
{
ConditionList spellCond ;
2012-01-29 13:49:19 -05:00
if ( sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX )
2010-06-04 23:24:48 +02:00
{
2012-01-29 13:49:19 -05:00
ConditionContainer :: const_iterator itr = ConditionStore . find ( sourceType );
if ( itr != ConditionStore . end ())
2010-06-11 01:25:10 +02:00
{
2012-01-29 13:49:19 -05:00
ConditionTypeContainer :: const_iterator i = ( * itr ). second . find ( entry );
2010-06-04 23:24:48 +02:00
if ( i != ( * itr ). second . end ())
{
spellCond = ( * i ). second ;
2012-01-29 13:49:19 -05:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "GetConditionsForNotGroupedEntry: found conditions for type %u and entry %u" , uint32 ( sourceType ), entry );
2010-06-04 23:24:48 +02:00
}
}
}
return spellCond ;
}
2012-02-20 23:21:12 +01:00
ConditionList ConditionMgr :: GetConditionsForSpellClickEvent ( uint32 creatureId , uint32 spellId )
{
ConditionList cond ;
CreatureSpellConditionContainer :: const_iterator itr = SpellClickEventConditionStore . find ( creatureId );
if ( itr != SpellClickEventConditionStore . end ())
{
ConditionTypeContainer :: const_iterator i = ( * itr ). second . find ( spellId );
if ( i != ( * itr ). second . end ())
{
cond = ( * i ). second ;
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "GetConditionsForSpellClickEvent: found conditions for Vehicle entry %u spell %u" , creatureId , spellId );
}
}
return cond ;
}
ConditionList ConditionMgr :: GetConditionsForVehicleSpell ( uint32 creatureId , uint32 spellId )
2010-10-22 22:45:11 +02:00
{
ConditionList cond ;
2012-02-20 23:21:12 +01:00
CreatureSpellConditionContainer :: const_iterator itr = VehicleSpellConditionStore . find ( creatureId );
2012-01-29 13:49:19 -05:00
if ( itr != VehicleSpellConditionStore . end ())
2010-10-22 22:45:11 +02:00
{
2012-02-20 23:21:12 +01:00
ConditionTypeContainer :: const_iterator i = ( * itr ). second . find ( spellId );
2010-10-22 22:45:11 +02:00
if ( i != ( * itr ). second . end ())
{
cond = ( * i ). second ;
2012-02-20 23:21:12 +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 ;
}
2012-01-31 09:50:02 -05:00
ConditionList ConditionMgr :: GetConditionsForSmartEvent ( int32 entryOrGuid , uint32 eventId , uint32 sourceType )
2012-01-29 13:49:19 -05:00
{
ConditionList cond ;
2012-01-31 09:50:02 -05:00
SmartEventConditionContainer :: const_iterator itr = SmartEventConditionStore . find ( std :: make_pair ( entryOrGuid , sourceType ));
2012-01-29 13:49:19 -05:00
if ( itr != SmartEventConditionStore . end ())
{
ConditionTypeContainer :: const_iterator i = ( * itr ). second . find ( eventId + 1 );
if ( i != ( * itr ). second . end ())
{
cond = ( * i ). second ;
2012-01-31 09:50:02 -05:00
sLog -> outDebug ( LOG_FILTER_CONDITIONSYS , "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid %d event_id %u" , entryOrGuid , eventId );
2012-01-29 13:49:19 -05: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 ();
2012-02-21 20:03:27 +01:00
sSpellMgr -> UnloadSpellInfoImplicitTargetConditionLists ();
2010-06-04 23:24:48 +02:00
}
2012-02-10 23:40:38 +01:00
QueryResult result = WorldDatabase . Query ( "SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, "
2012-02-10 12:54:06 +01:00
" ConditionValue1, ConditionValue2, ConditionValue3, NegativeCondition, ErrorTextId, ScriptName FROM conditions" );
2010-06-04 23:24:48 +02:00
if ( ! result )
{
2011-08-04 14:27:10 +02:00
sLog -> outErrorDb ( ">> Loaded 0 conditions. DB table `conditions` is empty!" );
2010-12-23 23:25:44 +01:00
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
{
2011-09-15 14:08:17 +02:00
Field * fields = result -> Fetch ();
2010-06-04 23:24:48 +02:00
Condition * cond = new Condition ();
2010-06-11 01:25:10 +02:00
int32 iSourceTypeOrReferenceId = fields [ 0 ]. GetInt32 ();
2012-02-14 12:46:26 -05:00
cond -> SourceGroup = fields [ 1 ]. GetUInt32 ();
cond -> SourceEntry = fields [ 2 ]. GetInt32 ();
cond -> SourceId = fields [ 3 ]. GetUInt32 ();
cond -> ElseGroup = fields [ 4 ]. GetUInt32 ();
2012-01-29 13:49:19 -05:00
int32 iConditionTypeOrReference = fields [ 5 ]. GetInt32 ();
2012-02-14 12:46:26 -05:00
cond -> ConditionTarget = fields [ 6 ]. GetUInt8 ();
cond -> ConditionValue1 = fields [ 7 ]. GetUInt32 ();
cond -> ConditionValue2 = fields [ 8 ]. GetUInt32 ();
cond -> ConditionValue3 = fields [ 9 ]. GetUInt32 ();
cond -> NegativeCondition = fields [ 10 ]. GetUInt8 ();
cond -> ErrorTextId = fields [ 11 ]. GetUInt32 ();
cond -> ScriptId = sObjectMgr -> GetScriptId ( fields [ 12 ]. GetCString ());
2010-06-04 23:24:48 +02:00
if ( iConditionTypeOrReference >= 0 )
2012-02-14 12:46:26 -05:00
cond -> ConditionType = ConditionTypes ( iConditionTypeOrReference );
2010-06-04 23:24:48 +02:00
2012-02-16 12:06:14 +01:00
if ( iSourceTypeOrReferenceId >= 0 )
cond -> SourceType = ConditionSourceType ( iSourceTypeOrReferenceId );
2010-06-04 23:24:48 +02:00
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 ;
}
2012-02-14 12:46:26 -05:00
cond -> ReferenceId = uint32 ( abs ( iConditionTypeOrReference ));
2010-06-04 23:24:48 +02:00
const char * rowType = "reference template" ;
if ( iSourceTypeOrReferenceId >= 0 )
rowType = "reference" ;
//check for useless data
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionTarget )
sLog -> outErrorDb ( "Condition %s %i has useless data in ConditionTarget (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> ConditionTarget );
if ( cond -> ConditionValue1 )
sLog -> outErrorDb ( "Condition %s %i has useless data in value1 (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> ConditionValue1 );
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "Condition %s %i has useless data in value2 (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Condition %s %i has useless data in value3 (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> ConditionValue3 );
if ( cond -> NegativeCondition )
sLog -> outErrorDb ( "Condition %s %i has useless data in NegativeCondition (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> NegativeCondition );
if ( cond -> SourceGroup && iSourceTypeOrReferenceId < 0 )
sLog -> outErrorDb ( "Condition %s %i has useless data in SourceGroup (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> SourceGroup );
if ( cond -> SourceEntry && iSourceTypeOrReferenceId < 0 )
sLog -> outErrorDb ( "Condition %s %i has useless data in SourceEntry (%u)!" , rowType , iSourceTypeOrReferenceId , cond -> SourceEntry );
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 );
2012-01-29 13:49:19 -05:00
if ( ConditionReferenceStore . find ( uRefId ) == ConditionReferenceStore . end ()) //make sure we have a list for our conditions, based on reference id
2010-06-04 23:24:48 +02:00
{
ConditionList mCondList ;
2012-01-29 13:49:19 -05:00
ConditionReferenceStore [ uRefId ] = mCondList ;
2010-06-04 23:24:48 +02:00
}
2012-01-29 13:49:19 -05:00
ConditionReferenceStore [ uRefId ]. push_back ( cond ); //add to reference storage
2010-06-04 23:24:48 +02:00
count ++ ;
continue ;
} //end of reference templates
//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)
2012-02-21 20:03:27 +01:00
if ( cond -> SourceGroup && ! CanHaveSourceGroupSet ( cond -> SourceType ))
{
sLog -> outErrorDb ( "Condition type %u has not allowed value of SourceGroup = %u!" , uint32 ( cond -> SourceType ), cond -> SourceGroup );
delete cond ;
continue ;
}
if ( cond -> SourceId && ! CanHaveSourceIdSet ( cond -> SourceType ))
2010-06-04 23:24:48 +02:00
{
2012-02-21 20:03:27 +01:00
sLog -> outErrorDb ( "Condition type %u has not allowed value of SourceId = %u!" , uint32 ( cond -> SourceType ), cond -> SourceId );
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
}
2012-02-21 20:03:27 +01:00
if ( cond -> SourceGroup )
2010-06-04 23:24:48 +02:00
{
2012-01-29 13:49:19 -05:00
bool valid = false ;
2012-02-21 20:03:27 +01:00
// handle grouped conditions
2012-02-14 12:46:26 -05:00
switch ( cond -> SourceType )
2010-06-04 23:24:48 +02:00
{
case CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Creature . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Disenchant . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Fishing . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Gameobject . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Item . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Mail . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Milling . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Pickpocketing . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Prospecting . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Reference . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Skinning . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE :
2012-02-14 12:46:26 -05:00
valid = addToLootTemplate ( cond , LootTemplates_Spell . GetLootForConditionFill ( cond -> SourceGroup ));
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_GOSSIP_MENU :
2012-01-29 13:49:19 -05:00
valid = addToGossipMenus ( cond );
2010-06-04 23:24:48 +02:00
break ;
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION :
2012-01-29 13:49:19 -05:00
valid = addToGossipMenuItems ( cond );
2010-06-04 23:24:48 +02:00
break ;
2012-02-22 11:43:38 +01:00
case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT :
{
//if no list for npc create one
if ( SpellClickEventConditionStore . find ( cond -> SourceGroup ) == SpellClickEventConditionStore . end ())
{
ConditionTypeContainer cmap ;
SpellClickEventConditionStore [ cond -> SourceGroup ] = cmap ;
}
//if no list for spellclick spell create one
if ( SpellClickEventConditionStore [ cond -> SourceGroup ]. find ( cond -> SourceEntry ) == SpellClickEventConditionStore [ cond -> SourceGroup ]. end ())
{
ConditionList clist ;
SpellClickEventConditionStore [ cond -> SourceGroup ][ cond -> SourceEntry ] = clist ;
}
SpellClickEventConditionStore [ cond -> SourceGroup ][ cond -> SourceEntry ]. push_back ( cond );
valid = true ;
++ count ;
continue ; // do not add to m_AllocatedMemory to avoid double deleting
break ;
}
2012-02-21 20:03:27 +01:00
case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET :
valid = addToSpellImplicitTargetConditions ( 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
2012-02-14 12:46:26 -05:00
if ( VehicleSpellConditionStore . find ( cond -> SourceGroup ) == VehicleSpellConditionStore . end ())
2010-10-22 22:45:11 +02:00
{
2012-01-29 13:49:19 -05:00
ConditionTypeContainer cmap ;
2012-02-14 12:46:26 -05:00
VehicleSpellConditionStore [ cond -> SourceGroup ] = 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
2012-02-14 12:46:26 -05:00
if ( VehicleSpellConditionStore [ cond -> SourceGroup ]. find ( cond -> SourceEntry ) == VehicleSpellConditionStore [ cond -> SourceGroup ]. end ())
2010-11-13 20:48:20 +01:00
{
ConditionList clist ;
2012-02-14 12:46:26 -05:00
VehicleSpellConditionStore [ cond -> SourceGroup ][ cond -> SourceEntry ] = clist ;
2010-11-13 20:48:20 +01:00
}
2012-02-14 12:46:26 -05:00
VehicleSpellConditionStore [ cond -> SourceGroup ][ cond -> SourceEntry ]. push_back ( cond );
2012-01-29 13:49:19 -05:00
valid = true ;
2010-11-13 20:48:20 +01:00
++ count ;
continue ; // do not add to m_AllocatedMemory to avoid double deleting
}
2012-01-29 13:49:19 -05:00
case CONDITION_SOURCE_TYPE_SMART_EVENT :
{
// If the entry does not exist, create a new list
2012-02-14 12:46:26 -05:00
std :: pair < int32 , uint32 > key = std :: make_pair ( cond -> SourceEntry , cond -> SourceId );
2012-01-29 13:49:19 -05:00
if ( SmartEventConditionStore . find ( key ) == SmartEventConditionStore . end ())
{
ConditionTypeContainer cmap ;
SmartEventConditionStore [ key ] = cmap ;
}
2012-02-14 12:46:26 -05:00
if ( SmartEventConditionStore [ key ]. find ( cond -> SourceGroup ) == SmartEventConditionStore [ key ]. end ())
2012-01-29 13:49:19 -05:00
{
ConditionList clist ;
2012-02-14 12:46:26 -05:00
SmartEventConditionStore [ key ][ cond -> SourceGroup ] = clist ;
2012-01-29 13:49:19 -05:00
}
2012-02-14 12:46:26 -05:00
SmartEventConditionStore [ key ][ cond -> SourceGroup ]. push_back ( cond );
2012-01-29 13:49:19 -05:00
valid = true ;
++ count ;
continue ;
}
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
2012-01-29 13:49:19 -05:00
if ( ! valid )
2010-06-11 01:25:10 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Not handled grouped condition, SourceGroup %u" , cond -> SourceGroup );
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
{
2012-01-29 13:49:19 -05:00
AllocatedMemoryStore . 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
2012-02-14 12:46:26 -05:00
if ( ConditionStore . find ( cond -> SourceType ) == ConditionStore . end ())
2010-06-04 23:24:48 +02:00
{
2012-01-29 13:49:19 -05:00
ConditionTypeContainer mTypeMap ;
2012-02-14 12:46:26 -05:00
ConditionStore [ cond -> SourceType ] = mTypeMap ; //add new empty list for SourceType
2010-06-04 23:24:48 +02:00
}
//make sure we have a condition list for our SourceType's entry
2012-02-14 12:46:26 -05:00
if ( ConditionStore [ cond -> SourceType ]. find ( cond -> SourceEntry ) == ConditionStore [ cond -> SourceType ]. end ())
2010-06-04 23:24:48 +02:00
{
ConditionList mCondList ;
2012-02-14 12:46:26 -05:00
ConditionStore [ cond -> SourceType ][ cond -> SourceEntry ] = mCondList ;
2010-06-04 23:24:48 +02:00
}
//add new Condition to storage based on Type/Entry
2012-02-14 12:46:26 -05:00
ConditionStore [ cond -> SourceType ][ cond -> SourceEntry ]. push_back ( cond );
2010-06-04 23:24:48 +02:00
++ 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 )
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ConditionMgr: LootTemplate %u not found" , cond -> SourceGroup );
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
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ConditionMgr: Item %u not found in LootTemplate %u" , cond -> SourceEntry , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
bool ConditionMgr :: addToGossipMenus ( Condition * cond )
{
2012-02-14 12:46:26 -05:00
GossipMenusMapBoundsNonConst pMenuBounds = sObjectMgr -> GetGossipMenusMapBoundsNonConst ( cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
if ( pMenuBounds . first != pMenuBounds . second )
{
2012-02-12 20:10:09 -05:00
for ( GossipMenusContainer :: iterator itr = pMenuBounds . first ; itr != pMenuBounds . second ; ++ itr )
2010-06-04 23:24:48 +02:00
{
2012-02-16 13:56:08 +01:00
if (( * itr ). second . entry == cond -> SourceGroup && ( * itr ). second . text_id == uint32 ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
( * itr ). second . conditions . push_back ( cond );
return true ;
}
}
2010-06-11 01:25:10 +02:00
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "addToGossipMenus: GossipMenu %u not found" , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
bool ConditionMgr :: addToGossipMenuItems ( Condition * cond )
{
2012-02-14 12:46:26 -05:00
GossipMenuItemsMapBoundsNonConst pMenuItemBounds = sObjectMgr -> GetGossipMenuItemsMapBoundsNonConst ( cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
if ( pMenuItemBounds . first != pMenuItemBounds . second )
{
2012-02-12 20:10:09 -05:00
for ( GossipMenuItemsContainer :: iterator itr = pMenuItemBounds . first ; itr != pMenuItemBounds . second ; ++ itr )
2010-06-04 23:24:48 +02:00
{
2012-02-16 13:56:08 +01:00
if (( * itr ). second . MenuId == cond -> SourceGroup && ( * itr ). second . OptionIndex == uint32 ( cond -> SourceEntry ))
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
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "addToGossipMenuItems: GossipMenuId %u Item %u not found" , cond -> SourceGroup , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
2012-02-21 20:03:27 +01:00
bool ConditionMgr :: addToSpellImplicitTargetConditions ( Condition * cond )
{
uint32 conditionEffMask = cond -> SourceGroup ;
SpellInfo * spellInfo = const_cast < SpellInfo *> ( sSpellMgr -> GetSpellInfo ( cond -> SourceEntry ));
ASSERT ( spellInfo );
std :: list < uint32 > sharedMasks ;
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
// check if effect is already a part of some shared mask
bool found = false ;
for ( std :: list < uint32 >:: iterator itr = sharedMasks . begin (); itr != sharedMasks . end (); ++ itr )
{
if (( 1 << i ) & * itr )
{
found = true ;
break ;
}
}
if ( found )
continue ;
// build new shared mask with found effect
uint32 sharedMask = ( 1 << i );
ConditionList * cmp = spellInfo -> Effects [ i ]. ImplicitTargetConditions ;
for ( uint8 effIndex = i + 1 ; effIndex < MAX_SPELL_EFFECTS ; ++ effIndex )
{
if ( spellInfo -> Effects [ effIndex ]. ImplicitTargetConditions == cmp )
sharedMask |= 1 << effIndex ;
}
sharedMasks . push_back ( sharedMask );
}
for ( std :: list < uint32 >:: iterator itr = sharedMasks . begin (); itr != sharedMasks . end (); ++ itr )
{
// some effect indexes should have same data
if ( uint32 commonMask = * itr & conditionEffMask )
{
uint8 firstEffIndex = 0 ;
for (; firstEffIndex < MAX_SPELL_EFFECTS ; ++ firstEffIndex )
if (( 1 << firstEffIndex ) & * itr )
break ;
// get shared data
ConditionList * sharedList = spellInfo -> Effects [ firstEffIndex ]. ImplicitTargetConditions ;
// there's already data entry for that sharedMask
if ( sharedList )
{
// we have overlapping masks in db
if ( conditionEffMask != * itr )
{
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - "
"effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring." , cond -> SourceEntry , cond -> SourceGroup );
return false ;
}
}
// no data for shared mask, we can create new submask
else
{
// add new list, create new shared mask
sharedList = new ConditionList ();
for ( uint8 i = firstEffIndex ; i < MAX_SPELL_EFFECTS ; ++ i )
if (( 1 << i ) & commonMask )
spellInfo -> Effects [ i ]. ImplicitTargetConditions = sharedList ;
}
sharedList -> push_back ( cond );
break ;
}
}
return true ;
}
2010-06-04 23:24:48 +02:00
bool ConditionMgr :: isSourceTypeValid ( Condition * cond )
{
2012-02-14 12:46:26 -05:00
if ( cond -> SourceType == CONDITION_SOURCE_TYPE_NONE || cond -> SourceType >= CONDITION_SOURCE_TYPE_MAX )
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Invalid ConditionSourceType %u in `condition` table, ignoring." , uint32 ( cond -> SourceType ));
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
switch ( cond -> SourceType )
2010-06-04 23:24:48 +02:00
{
case CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE :
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Creature . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `creature_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Creature . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE :
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Disenchant . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `disenchant_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Disenchant . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE :
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Fishing . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `fishing_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Fishing . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
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
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Gameobject . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `gameobject_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Gameobject . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
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
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Item . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `item_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Item . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE :
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Mail . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `mail_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Mail . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE :
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Milling . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `milling_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Milling . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE :
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Pickpocketing . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Pickpocketing . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE :
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Prospecting . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `prospecting_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Prospecting . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE :
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Reference . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `reference_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Reference . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE :
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Skinning . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `skinning_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Skinning . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE :
{
2012-02-14 12:46:26 -05:00
if ( ! LootTemplates_Spell . HaveLootFor ( cond -> SourceGroup ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceGroup %u in `condition` table, does not exist in `spell_loot_template`, ignoring." , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
LootTemplate * loot = LootTemplates_Spell . GetLootForConditionFill ( cond -> SourceGroup );
ItemTemplate const * pItemProto = sObjectMgr -> GetItemTemplate ( cond -> SourceEntry );
if ( ! pItemProto && ! loot -> isReference ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring." , cond -> SourceType , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
2012-02-21 20:03:27 +01:00
case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET :
2010-06-04 23:24:48 +02:00
{
2012-02-21 20:03:27 +01:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( cond -> SourceEntry );
if ( ! spellInfo )
2010-06-04 23:24:48 +02:00
{
2012-02-21 20:03:27 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring." , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
2012-02-21 20:03:27 +01:00
if (( cond -> SourceGroup > MAX_EFFECT_MASK ) || ! cond -> SourceGroup )
2010-06-04 23:24:48 +02:00
{
2012-02-21 20:03:27 +01:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set , ignoring." , cond -> SourceEntry , cond -> SourceGroup );
2010-06-04 23:24:48 +02:00
return false ;
}
2012-02-21 20:03:27 +01:00
uint32 origGroup = cond -> SourceGroup ;
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
{
2012-02-21 20:03:27 +01:00
if ( ! (( 1 << i ) & cond -> SourceGroup ))
continue ;
switch ( spellInfo -> Effects [ i ]. TargetA . GetSelectionCategory ())
2010-06-04 23:24:48 +02:00
{
2012-02-21 20:03:27 +01:00
case TARGET_SELECT_CATEGORY_NEARBY :
case TARGET_SELECT_CATEGORY_CONE :
case TARGET_SELECT_CATEGORY_AREA :
continue ;
2012-02-22 09:15:57 +01:00
default :
break ;
2010-10-16 16:34:21 +02:00
}
2012-02-22 09:15:57 +01:00
2012-02-21 20:03:27 +01:00
switch ( spellInfo -> Effects [ i ]. TargetB . GetSelectionCategory ())
2010-10-16 16:34:21 +02:00
{
2012-02-21 20:03:27 +01:00
case TARGET_SELECT_CATEGORY_NEARBY :
case TARGET_SELECT_CATEGORY_CONE :
case TARGET_SELECT_CATEGORY_AREA :
continue ;
2012-02-22 09:15:57 +01:00
default :
break ;
2010-06-04 23:24:48 +02:00
}
2012-02-22 09:15:57 +01:00
2012-02-21 20:03:27 +01:00
sLog -> outErrorDb ( "SourceEntry %u SourceGroup %u in `condition` table - spell %u does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_ for effect %u, SourceGroup needs correction, ignoring." , cond -> SourceEntry , origGroup , cond -> SourceEntry , uint32 ( i ));
cond -> SourceGroup &= ~ ( 1 << i );
2010-06-04 23:24:48 +02:00
}
2012-02-21 20:03:27 +01:00
// all effects were removed, no need to add the condition at all
if ( ! cond -> SourceGroup )
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 :
{
2012-02-14 12:46:26 -05:00
if ( ! sObjectMgr -> GetCreatureTemplate ( cond -> SourceEntry ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring." , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_SOURCE_TYPE_SPELL :
{
2012-02-14 12:46:26 -05:00
SpellInfo const * spellProto = sSpellMgr -> GetSpellInfo ( cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
if ( ! spellProto )
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring." , cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
2010-09-19 19:49:23 +02:00
case CONDITION_SOURCE_TYPE_QUEST_ACCEPT :
2012-02-14 12:46:26 -05:00
if ( ! sObjectMgr -> GetQuestTemplate ( cond -> SourceEntry ))
2010-09-19 19:49:23 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "CONDITION_SOURCE_TYPE_QUEST_ACCEPT specifies non-existing quest (%u), skipped" , cond -> SourceEntry );
2011-08-04 14:27:10 +02:00
return false ;
2010-09-20 10:19:20 +02:00
}
break ;
case CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK :
2012-02-14 12:46:26 -05:00
if ( ! sObjectMgr -> GetQuestTemplate ( cond -> SourceEntry ))
2010-09-20 10:19:20 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK specifies non-existing quest (%u), skipped" , cond -> SourceEntry );
2011-08-04 14:27:10 +02:00
return false ;
2010-09-19 19:49:23 +02:00
}
break ;
2010-10-22 22:45:11 +02:00
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL :
2012-02-14 12:46:26 -05:00
if ( ! sObjectMgr -> GetCreatureTemplate ( cond -> SourceGroup ))
2010-10-22 22:45:11 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring." , cond -> SourceGroup );
2011-08-04 14:27:10 +02:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( ! sSpellMgr -> GetSpellInfo ( cond -> SourceEntry ))
2011-08-04 14:27:10 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring." , cond -> SourceEntry );
2011-08-04 14:27:10 +02:00
return false ;
2010-10-22 22:45:11 +02:00
}
2011-08-04 14:27:10 +02:00
break ;
2012-02-20 23:21:12 +01:00
case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT :
if ( ! sObjectMgr -> GetCreatureTemplate ( cond -> SourceGroup ))
{
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring." , cond -> SourceGroup );
return false ;
}
if ( ! sSpellMgr -> GetSpellInfo ( cond -> SourceEntry ))
{
sLog -> outErrorDb ( "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring." , cond -> SourceEntry );
return false ;
}
break ;
2010-06-04 23:24:48 +02:00
case CONDITION_SOURCE_TYPE_GOSSIP_MENU :
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION :
2012-01-29 13:49:19 -05:00
case CONDITION_SOURCE_TYPE_SMART_EVENT :
2010-06-04 23:24:48 +02:00
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 )
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionType == CONDITION_NONE || cond -> ConditionType >= CONDITION_MAX )
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Invalid ConditionType %u at SourceEntry %u in `condition` table, ignoring." , uint32 ( cond -> ConditionType ), cond -> SourceEntry );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionTarget >= cond -> GetMaxAvailableConditionTargets ())
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "SourceType %u, SourceEntry %u in `condition` table, has incorrect ConditionTarget set, ignoring." , cond -> SourceType , cond -> SourceEntry );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
switch ( cond -> ConditionType )
2010-06-04 23:24:48 +02:00
{
case CONDITION_AURA :
{
2012-02-14 12:46:26 -05:00
if ( ! sSpellMgr -> GetSpellInfo ( cond -> ConditionValue1 ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Aura condition has non existing spell (Id: %d), skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-20 23:21:12 +01:00
if ( cond -> ConditionValue2 > EFFECT_2 )
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Aura condition has non existing effect index (%u) (must be 0..2), skipped" , cond -> ConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
2012-02-16 13:16:43 +01:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Aura condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_ITEM :
{
2012-02-14 12:46:26 -05:00
ItemTemplate const * proto = sObjectMgr -> GetItemTemplate ( cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! proto )
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Item condition has non existing item (%u), skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( ! cond -> ConditionValue2 )
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Item condition has 0 set for item count in value2 (%u), skipped" , cond -> ConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
break ;
}
case CONDITION_ITEM_EQUIPPED :
{
2012-02-14 12:46:26 -05:00
ItemTemplate const * proto = sObjectMgr -> GetItemTemplate ( cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! proto )
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ItemEquipped condition has non existing item (%u), skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "ItemEquipped condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "ItemEquipped condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_ZONEID :
{
2012-02-14 12:46:26 -05:00
AreaTableEntry const * areaEntry = GetAreaEntryByAreaID ( cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! areaEntry )
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ZoneID condition has non existing area (%u), skipped" , cond -> ConditionValue1 );
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 )
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ZoneID condition requires to be in area (%u) which is a subzone but zone expected, skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "ZoneID condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "ZoneID condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_REPUTATION_RANK :
{
2012-02-14 12:46:26 -05:00
FactionEntry const * factionEntry = sFactionStore . LookupEntry ( cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! factionEntry )
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Reputation condition has non existing faction (%u), skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Reputation condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_TEAM :
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 != ALLIANCE && cond -> ConditionValue1 != HORDE )
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Team condition specifies unknown team (%u), skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "Team condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Team condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_SKILL :
{
2012-02-14 12:46:26 -05:00
SkillLineEntry const * pSkill = sSkillLineStore . LookupEntry ( cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! pSkill )
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Skill condition specifies non-existing skill (%u), skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 < 1 || cond -> ConditionValue2 > sWorld -> GetConfigMaxSkillValue ())
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Skill condition specifies invalid skill value (%u), skipped" , cond -> ConditionValue2 );
2010-06-04 23:24:48 +02:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Skill condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
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
{
2012-02-14 12:46:26 -05:00
if ( ! sObjectMgr -> GetQuestTemplate ( cond -> ConditionValue1 ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Quest condition specifies non-existing quest (%u), skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 > 1 )
sLog -> outErrorDb ( "Quest condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Quest condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_ACTIVE_EVENT :
{
2010-12-22 21:25:23 +01:00
GameEventMgr :: GameEventDataMap const & events = sGameEventMgr -> GetEventMap ();
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 >= events . size () || ! events [ cond -> ConditionValue1 ]. isValid ())
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ActiveEvent condition has non existing event id (%u), skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "ActiveEvent condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "ActiveEvent condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_ACHIEVEMENT :
{
2012-02-14 12:46:26 -05:00
AchievementEntry const * achievement = GetAchievementStore () -> LookupEntry ( cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! achievement )
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Achivement condition has non existing achivement id (%u), skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "Achivement condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Achivement condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_CLASS :
{
2012-02-14 12:46:26 -05:00
if ( ! ( cond -> ConditionValue1 & CLASSMASK_ALL_PLAYABLE ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Class condition has non existing classmask (%u), skipped" , cond -> ConditionValue1 & ~ CLASSMASK_ALL_PLAYABLE );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "Class condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Class condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_RACE :
{
2012-02-14 12:46:26 -05:00
if ( ! ( cond -> ConditionValue1 & RACEMASK_ALL_PLAYABLE ))
2010-06-04 23:24:48 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Race condition has non existing racemask (%u), skipped" , cond -> ConditionValue1 & ~ RACEMASK_ALL_PLAYABLE );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "Race condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Race condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
case CONDITION_MAPID :
{
2012-02-14 12:46:26 -05:00
MapEntry const * me = sMapStore . LookupEntry ( cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
if ( ! me )
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Map condition has non existing map (%u), skipped" , cond -> ConditionValue1 );
2010-06-04 23:24:48 +02:00
return false ;
}
2010-08-06 19:23:43 +02:00
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "Map condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Map condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-06-04 23:24:48 +02:00
break ;
}
2010-09-10 20:49:29 +02:00
case CONDITION_SPELL :
{
2012-02-14 12:46:26 -05:00
if ( ! sSpellMgr -> GetSpellInfo ( cond -> ConditionValue1 ))
2010-09-10 20:49:29 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Spell condition has non existing spell (Id: %d), skipped" , cond -> ConditionValue1 );
2010-09-10 20:49:29 +02:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "Spell condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Spell condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-09-10 20:49:29 +02:00
break ;
}
2010-10-05 17:54:27 +02:00
case CONDITION_LEVEL :
2011-08-04 14:27:10 +02:00
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 >= COMP_TYPE_MAX )
2010-10-05 17:54:27 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "Level condition has invalid option (%u), skipped" , cond -> ConditionValue2 );
2011-08-04 14:27:10 +02:00
return false ;
2010-10-05 17:54:27 +02:00
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Level condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2011-08-04 14:27:10 +02:00
break ;
}
2010-10-11 23:35:55 +02:00
case CONDITION_DRUNKENSTATE :
2011-08-04 14:27:10 +02:00
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 > DRUNKEN_SMASHED )
2010-10-11 23:35:55 +02:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "DrunkState condition has invalid state (%u), skipped" , cond -> ConditionValue1 );
2011-08-04 14:27:10 +02:00
return false ;
2010-10-11 23:35:55 +02:00
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
2012-02-10 15:30:33 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "DrunkState condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
2012-02-10 15:30:33 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "DrunkState condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2011-08-04 14:27:10 +02:00
break ;
}
2010-10-31 22:10:31 +01:00
case CONDITION_NEAR_CREATURE :
{
2012-02-14 12:46:26 -05:00
if ( ! sObjectMgr -> GetCreatureTemplate ( cond -> ConditionValue1 ))
2010-10-31 22:10:31 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "NearCreature condition has non existing creature template entry (%u), skipped" , cond -> ConditionValue1 );
2010-10-31 22:10:31 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "NearCreature condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-10-31 22:10:31 +01:00
break ;
}
case CONDITION_NEAR_GAMEOBJECT :
{
2012-02-14 12:46:26 -05:00
if ( ! sObjectMgr -> GetGameObjectTemplate ( cond -> ConditionValue1 ))
2010-10-31 22:10:31 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "NearGameObject condition has non existing gameobject template entry (%u), skipped" , cond -> ConditionValue1 );
2010-10-31 22:10:31 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "NearGameObject condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2010-10-31 22:10:31 +01:00
break ;
}
2012-02-11 15:16:18 +01:00
case CONDITION_OBJECT_ENTRY :
{
2012-02-14 12:46:26 -05:00
switch ( cond -> ConditionValue1 )
2012-02-11 15:16:18 +01:00
{
case TYPEID_UNIT :
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 && ! sObjectMgr -> GetCreatureTemplate ( cond -> ConditionValue2 ))
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ObjectEntry condition has non existing creature template entry (%u), skipped" , cond -> ConditionValue2 );
2012-02-11 15:16:18 +01:00
return false ;
}
break ;
case TYPEID_GAMEOBJECT :
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 && ! sObjectMgr -> GetGameObjectTemplate ( cond -> ConditionValue2 ))
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ObjectEntry condition has non existing game object template entry (%u), skipped" , cond -> ConditionValue2 );
2012-02-11 15:16:18 +01:00
return false ;
}
break ;
case TYPEID_PLAYER :
case TYPEID_CORPSE :
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "ObjectEntry condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
2012-02-11 15:16:18 +01:00
break ;
default :
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ObjectEntry condition has wrong typeid set (%u), skipped" , cond -> ConditionValue1 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
2012-02-18 16:52:08 +01:00
sLog -> outErrorDb ( "ObjectEntry condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2012-02-11 15:16:18 +01:00
break ;
}
case CONDITION_TYPE_MASK :
{
2012-02-14 12:46:26 -05:00
if ( ! cond -> ConditionValue1 || ( cond -> ConditionValue1 & ~ ( TYPEMASK_UNIT | TYPEMASK_PLAYER | TYPEMASK_GAMEOBJECT | TYPEMASK_CORPSE )))
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "TypeMask condition has invalid typemask set (%u), skipped" , cond -> ConditionValue2 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "TypeMask condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "TypeMask condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2012-02-11 15:16:18 +01:00
break ;
}
case CONDITION_RELATION_TO :
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 >= cond -> GetMaxAvailableConditionTargets ())
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "RelationTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped" , cond -> ConditionValue1 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 == cond -> ConditionTarget )
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "RelationTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped" , cond -> ConditionValue1 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 >= RELATION_MAX )
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "RelationTo condition has invalid ConditionValue2(RelationType) (%u), skipped" , cond -> ConditionValue2 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "RelationTo condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2012-02-11 15:16:18 +01:00
break ;
}
case CONDITION_REACTION_TO :
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 >= cond -> GetMaxAvailableConditionTargets ())
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ReactionTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped" , cond -> ConditionValue1 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 == cond -> ConditionTarget )
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "ReactionTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped" , cond -> ConditionValue1 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( ! cond -> ConditionValue2 )
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "mConditionValue2 condition has invalid ConditionValue2(rankMask) (%u), skipped" , cond -> ConditionValue2 );
2012-02-11 15:16:18 +01:00
return false ;
}
break ;
}
case CONDITION_DISTANCE_TO :
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 >= cond -> GetMaxAvailableConditionTargets ())
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "DistanceTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped" , cond -> ConditionValue1 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 == cond -> ConditionTarget )
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "DistanceTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped" , cond -> ConditionValue1 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 >= COMP_TYPE_MAX )
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "DistanceTo condition has invalid ComparisionType (%u), skipped" , cond -> ConditionValue3 );
2012-02-11 15:16:18 +01:00
return false ;
}
break ;
}
case CONDITION_ALIVE :
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 )
sLog -> outErrorDb ( "Alive condition has useless data in value1 (%u)!" , cond -> ConditionValue1 );
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "Alive condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Alive condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2012-02-11 15:16:18 +01:00
break ;
}
case CONDITION_HP_VAL :
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 >= COMP_TYPE_MAX )
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "HpVal condition has invalid ComparisionType (%u), skipped" , cond -> ConditionValue2 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "HpVal condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2012-02-11 15:16:18 +01:00
break ;
}
case CONDITION_HP_PCT :
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue1 > 100 )
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "HpPct condition has too big percent value (%u), skipped" , cond -> ConditionValue1 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 >= COMP_TYPE_MAX )
2012-02-11 15:16:18 +01:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "HpPct condition has invalid ComparisionType (%u), skipped" , cond -> ConditionValue2 );
2012-02-11 15:16:18 +01:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "HpPct condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2012-02-11 15:16:18 +01:00
break ;
}
2010-06-04 23:24:48 +02:00
case CONDITION_AREAID :
case CONDITION_INSTANCE_DATA :
break ;
2012-02-11 19:46:41 +00:00
case CONDITION_WORLD_STATE :
{
2012-02-14 12:46:26 -05:00
if ( ! sWorld -> getWorldState ( cond -> ConditionValue1 ))
2012-02-11 19:46:41 +00:00
{
2012-02-14 12:46:26 -05:00
sLog -> outErrorDb ( "World state condition has non existing world state in value1 (%u), skipped" , cond -> ConditionValue1 );
2012-02-11 19:46:41 +00:00
return false ;
}
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "World state condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2012-02-11 19:46:41 +00:00
break ;
}
case CONDITION_PHASEMASK :
{
2012-02-14 12:46:26 -05:00
if ( cond -> ConditionValue2 )
sLog -> outErrorDb ( "Phasemask condition has useless data in value2 (%u)!" , cond -> ConditionValue2 );
if ( cond -> ConditionValue3 )
sLog -> outErrorDb ( "Phasemask condition has useless data in value3 (%u)!" , cond -> ConditionValue3 );
2012-02-11 19:46:41 +00:00
break ;
}
2012-02-21 20:03:27 +01:00
case CONDITION_UNUSED_18 :
sLog -> outErrorDb ( "Found ConditionTypeOrReference = CONDITION_UNUSED_18 in `conditions` table - ignoring" );
return false ;
2012-02-16 13:16:43 +01:00
case CONDITION_UNUSED_19 :
sLog -> outErrorDb ( "Found ConditionTypeOrReference = CONDITION_UNUSED_19 in `conditions` table - ignoring" );
return false ;
case CONDITION_UNUSED_20 :
2012-02-20 23:21:12 +01:00
sLog -> outErrorDb ( "Found ConditionTypeOrReference = CONDITION_UNUSED_20 in `conditions` table - ignoring" );
2012-02-16 13:16:43 +01:00
return false ;
case CONDITION_UNUSED_21 :
2012-02-20 23:21:12 +01:00
sLog -> outErrorDb ( "Found ConditionTypeOrReference = CONDITION_UNUSED_21 in `conditions` table - ignoring" );
2012-02-16 13:16:43 +01:00
return false ;
case CONDITION_UNUSED_24 :
2012-02-20 23:21:12 +01:00
sLog -> outErrorDb ( "Found ConditionTypeOrReference = CONDITION_UNUSED_24 in `conditions` table - ignoring" );
2012-02-16 13:16:43 +01:00
return false ;
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 ()
{
2012-01-29 13:49:19 -05:00
for ( ConditionReferenceContainer :: iterator itr = ConditionReferenceStore . begin (); itr != ConditionReferenceStore . end (); ++ itr )
2010-06-11 01:25:10 +02:00
{
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
2012-01-29 13:49:19 -05:00
ConditionReferenceStore . clear ();
for ( ConditionContainer :: iterator itr = ConditionStore . begin (); itr != ConditionStore . end (); ++ itr )
{
for ( ConditionTypeContainer :: 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 ();
}
ConditionStore . clear ();
2010-06-11 01:25:10 +02:00
2012-02-20 23:21:12 +01:00
for ( CreatureSpellConditionContainer :: iterator itr = VehicleSpellConditionStore . begin (); itr != VehicleSpellConditionStore . end (); ++ itr )
2010-06-11 01:25:10 +02:00
{
2012-01-29 13:49:19 -05:00
for ( ConditionTypeContainer :: iterator it = itr -> second . begin (); it != itr -> second . end (); ++ it )
2010-06-11 01:25:10 +02:00
{
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
2012-01-29 13:49:19 -05:00
VehicleSpellConditionStore . clear ();
2010-06-11 01:25:10 +02:00
2012-01-29 13:49:19 -05:00
for ( SmartEventConditionContainer :: iterator itr = SmartEventConditionStore . begin (); itr != SmartEventConditionStore . end (); ++ itr )
2010-10-22 22:45:11 +02:00
{
2012-01-29 13:49:19 -05:00
for ( ConditionTypeContainer :: iterator it = itr -> second . begin (); it != itr -> second . end (); ++ it )
2010-10-22 22:45:11 +02:00
{
for ( ConditionList :: const_iterator i = it -> second . begin (); i != it -> second . end (); ++ i )
delete * i ;
it -> second . clear ();
}
itr -> second . clear ();
}
2012-01-29 13:49:19 -05:00
SmartEventConditionStore . clear ();
2010-10-22 22:45:11 +02:00
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 ;)
2012-01-29 13:49:19 -05:00
for ( std :: list < Condition *>:: const_iterator itr = AllocatedMemoryStore . begin (); itr != AllocatedMemoryStore . end (); ++ itr )
2010-06-11 01:25:10 +02:00
delete * itr ;
2010-08-06 19:23:43 +02:00
2012-01-29 13:49:19 -05:00
AllocatedMemoryStore . clear ();
2010-06-11 01:25:10 +02:00
}