2010-10-07 15:54:07 +02:00
/*
2012-01-01 00:32:13 +01:00
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:54:07 +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
*/
#ifndef TRINITY_CONDITIONMGR_H
#define TRINITY_CONDITIONMGR_H
#include "LootMgr.h"
2011-08-04 14:27:10 +02:00
#include <ace/Singleton.h>
2010-06-04 23:24:48 +02:00
class Player ;
class Unit ;
2012-02-10 23:40:38 +01:00
class WorldObject ;
2010-06-04 23:24:48 +02:00
class LootTemplate ;
2012-02-10 23:40:38 +01:00
struct Condition ;
2010-06-04 23:24:48 +02:00
enum ConditionType
2012-02-11 15:16:18 +01:00
{ // value1 value2 value3
CONDITION_NONE = 0 , // 0 0 0 always true
CONDITION_AURA = 1 , // spell_id effindex use target? true if player (or target, if value3) has aura of spell_id with effect effindex
CONDITION_ITEM = 2 , // item_id count bank true if has #count of item_ids (if 'bank' is set it searches in bank slots too)
CONDITION_ITEM_EQUIPPED = 3 , // item_id 0 0 true if has item_id equipped
CONDITION_ZONEID = 4 , // zone_id 0 0 true if in zone_id
CONDITION_REPUTATION_RANK = 5 , // faction_id rankMask 0 true if has min_rank for faction_id
CONDITION_TEAM = 6 , // player_team 0, 0 469 - Alliance, 67 - Horde)
CONDITION_SKILL = 7 , // skill_id skill_value 0 true if has skill_value for skill_id
CONDITION_QUESTREWARDED = 8 , // quest_id 0 0 true if quest_id was rewarded before
CONDITION_QUESTTAKEN = 9 , // quest_id 0, 0 true while quest active
CONDITION_DRUNKENSTATE = 10 , // DrunkenState 0, 0 true if player is drunk enough
2012-02-10 16:32:26 +00:00
CONDITION_UNUSED_11 = 11 ,
2012-02-11 15:16:18 +01:00
CONDITION_ACTIVE_EVENT = 12 , // event_id 0 0 true if event is active
CONDITION_INSTANCE_DATA = 13 , // entry data 0 true if data is set in current instance
CONDITION_QUEST_NONE = 14 , // quest_id 0 0 true if doesn't have quest saved
CONDITION_CLASS = 15 , // class 0 0 true if player's class is equal to class
CONDITION_RACE = 16 , // race 0 0 true if player's race is equal to race
CONDITION_ACHIEVEMENT = 17 , // achievement_id 0 0 true if achievement is complete
2012-02-10 15:30:33 +01:00
CONDITION_SPELL_SCRIPT_TARGET = 18 , // SpellScriptTargetType, TargetEntry, 0
2012-02-11 15:16:18 +01:00
CONDITION_CREATURE_TARGET = 19 , // creature entry 0 0 true if current target is creature with value1 entry
CONDITION_TARGET_HEALTH_BELOW_PCT = 20 , // 0-100 0 0 true if target's health is below value1 percent, false if over or no target
CONDITION_TARGET_RANGE = 21 , // minDistance maxDist 0 true if target is closer then minDist and further then maxDist or if max is 0 then max dist is infinit
CONDITION_MAPID = 22 , // map_id 0 0 true if in map_id
CONDITION_AREAID = 23 , // area_id 0 0 true if in area_id
CONDITION_ITEM_TARGET = 24 , // ItemRequiredTargetType, TargetEntry, 0
CONDITION_SPELL = 25 , // spell_id 0 0 true if player has learned spell
2012-02-10 16:32:26 +00:00
CONDITION_UNUSED_26 = 26 ,
2012-02-11 15:16:18 +01:00
CONDITION_LEVEL = 27 , // level ComparisonType 0 true if unit's level is equal to param1 (param2 can modify the statement)
CONDITION_QUEST_COMPLETE = 28 , // quest_id 0 0 true if player has quest_id with all objectives complete, but not yet rewarded
CONDITION_NEAR_CREATURE = 29 , // creature entry distance 0 true if there is a creature of entry in range
CONDITION_NEAR_GAMEOBJECT = 30 , // gameobject entry distance 0 true if there is a gameobject of entry in range
CONDITION_OBJECT_ENTRY = 31 , // TypeID entry 0 true if object is type TypeID and the entry is 0 or matches entry of the object
CONDITION_TYPE_MASK = 32 , // TypeMask 0 0 true if object is type object's TypeMask matches provided TypeMask
CONDITION_RELATION_TO = 33 , // ConditionTarget RelationType 0 true if object is in given relation with object specified by ConditionTarget
CONDITION_REACTION_TO = 34 , // ConditionTarget rankMask 0 true if object's reaction matches rankMask object specified by ConditionTarget
CONDITION_DISTANCE_TO = 35 , // ConditionTarget distance ComparisonType true if object and ConditionTarget are within distance given by parameters
CONDITION_ALIVE = 36 , // 0 0 0 true if unit is alive
CONDITION_HP_VAL = 37 , // hpVal ComparisonType 0 true if unit's hp matches given value
CONDITION_HP_PCT = 38 , // hpPct ComparisonType 0 true if unit's hp matches given pct
CONDITION_MAX = 39 // MAX
2010-10-05 18:07:41 +02:00
};
2010-06-04 23:24:48 +02:00
enum ConditionSourceType
{
2012-02-10 16:32:26 +00:00
CONDITION_SOURCE_TYPE_NONE = 0 ,
CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE = 1 ,
CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE = 2 ,
CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE = 3 ,
CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE = 4 ,
CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE = 5 ,
CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE = 6 ,
CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE = 7 ,
CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE = 8 ,
CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE = 9 ,
CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE = 10 ,
CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE = 11 ,
CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE = 12 ,
CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET = 13 ,
CONDITION_SOURCE_TYPE_GOSSIP_MENU = 14 ,
CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION = 15 ,
CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE = 16 ,
CONDITION_SOURCE_TYPE_SPELL = 17 ,
CONDITION_SOURCE_TYPE_ITEM_REQUIRED_TARGET = 18 ,
CONDITION_SOURCE_TYPE_QUEST_ACCEPT = 19 ,
CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK = 20 ,
CONDITION_SOURCE_TYPE_VEHICLE_SPELL = 21 ,
CONDITION_SOURCE_TYPE_SMART_EVENT = 22 ,
2012-01-29 13:49:19 -05:00
CONDITION_SOURCE_TYPE_MAX = 23 //MAX
2010-06-04 23:24:48 +02:00
};
2012-02-11 15:16:18 +01:00
enum ComparisionType
{
COMP_TYPE_EQ = 0 ,
COMP_TYPE_HIGH ,
COMP_TYPE_LOW ,
COMP_TYPE_HIGH_EQ ,
COMP_TYPE_LOW_EQ ,
COMP_TYPE_MAX
};
enum RelationType
{
RELATION_SELF = 0 ,
RELATION_IN_PARTY ,
RELATION_IN_RAID_OR_PARTY ,
RELATION_OWNED_BY ,
RELATION_PASSENGER_OF ,
RELATION_MAX
};
2012-02-10 23:40:38 +01:00
enum
{
MAX_CONDITION_TARGETS = 3 ,
};
struct ConditionSourceInfo
{
2012-02-11 15:16:18 +01:00
WorldObject * mConditionTargets [ MAX_CONDITION_TARGETS ]; // an array of targets available for conditions
2012-02-10 23:40:38 +01:00
Condition * mLastFailedCondition ;
ConditionSourceInfo ( WorldObject * target0 , WorldObject * target1 = NULL , WorldObject * target2 = NULL )
{
mConditionTargets [ 0 ] = target0 ;
mConditionTargets [ 1 ] = target1 ;
mConditionTargets [ 2 ] = target2 ;
mLastFailedCondition = NULL ;
}
};
2010-06-04 23:24:48 +02:00
struct Condition
2010-06-11 01:25:10 +02:00
{
2010-06-04 23:24:48 +02:00
ConditionSourceType mSourceType ; //SourceTypeOrReferenceId
uint32 mSourceGroup ;
2012-01-31 09:50:02 -05:00
int32 mSourceEntry ;
2012-01-29 13:49:19 -05:00
uint32 mSourceId ; // So far, only used in CONDITION_SOURCE_TYPE_SMART_EVENT
2010-06-04 23:24:48 +02:00
uint32 mElseGroup ;
ConditionType mConditionType ; //ConditionTypeOrReference
2012-02-10 23:40:38 +01:00
uint8 mConditionTarget ;
2010-06-04 23:24:48 +02:00
uint32 mConditionValue1 ;
uint32 mConditionValue2 ;
uint32 mConditionValue3 ;
uint32 ErrorTextd ;
uint32 mReferenceId ;
2010-08-06 16:33:31 +02:00
uint32 mScriptId ;
2012-02-10 12:44:07 +01:00
bool mNegativeCondition ;
2010-06-04 23:24:48 +02:00
Condition ()
{
mSourceType = CONDITION_SOURCE_TYPE_NONE ;
mSourceGroup = 0 ;
mSourceEntry = 0 ;
mElseGroup = 0 ;
mConditionType = CONDITION_NONE ;
2012-02-10 23:40:38 +01:00
mConditionTarget = 0 ;
2010-06-04 23:24:48 +02:00
mConditionValue1 = 0 ;
mConditionValue2 = 0 ;
mConditionValue3 = 0 ;
mReferenceId = 0 ;
ErrorTextd = 0 ;
2010-08-06 16:33:31 +02:00
mScriptId = 0 ;
2012-02-10 12:44:07 +01:00
mNegativeCondition = false ;
2010-06-04 23:24:48 +02:00
}
2010-08-06 19:23:43 +02:00
2012-02-10 23:40:38 +01:00
bool Meets ( ConditionSourceInfo & sourceInfo );
2010-12-06 02:07:53 +01:00
bool isLoaded () const { return mConditionType > CONDITION_NONE || mReferenceId ; }
2012-02-11 15:16:18 +01:00
uint32 GetMaxAvailableConditionTargets ();
2010-06-04 23:24:48 +02:00
};
typedef std :: list < Condition *> ConditionList ;
2012-01-29 13:49:19 -05:00
typedef std :: map < uint32 , ConditionList > ConditionTypeContainer ;
typedef std :: map < ConditionSourceType , ConditionTypeContainer > ConditionContainer ;
typedef std :: map < uint32 , ConditionTypeContainer > VehicleSpellConditionContainer ;
2012-01-31 09:50:02 -05:00
typedef std :: map < std :: pair < int32 , uint32 /*SAI source_type*/ > , ConditionTypeContainer > SmartEventConditionContainer ;
2010-06-04 23:24:48 +02:00
2012-01-29 13:49:19 -05:00
typedef std :: map < uint32 , ConditionList > ConditionReferenceContainer ; //only used for references
2010-06-04 23:24:48 +02:00
class ConditionMgr
{
2010-06-25 00:18:01 +02:00
friend class ACE_Singleton < ConditionMgr , ACE_Null_Mutex > ;
2010-08-08 19:45:53 +02:00
2011-08-04 14:27:10 +02:00
private :
ConditionMgr ();
~ ConditionMgr ();
2010-06-04 23:24:48 +02:00
2011-08-04 14:27:10 +02:00
public :
2010-06-04 23:24:48 +02:00
void LoadConditions ( bool isReload = false );
bool isConditionTypeValid ( Condition * cond );
ConditionList GetConditionReferences ( uint32 refId );
2010-06-11 01:25:10 +02:00
2012-02-10 23:40:38 +01:00
bool IsObjectMeetToConditions ( WorldObject * object , ConditionList const & conditions );
bool IsObjectMeetToConditions ( ConditionSourceInfo & sourceInfo , ConditionList const & conditions );
2012-01-29 13:49:19 -05:00
ConditionList GetConditionsForNotGroupedEntry ( ConditionSourceType sourceType , uint32 entry );
2012-01-31 09:50:02 -05:00
ConditionList GetConditionsForSmartEvent ( int32 entryOrGuid , uint32 eventId , uint32 sourceType );
2010-10-22 22:45:11 +02:00
ConditionList GetConditionsForVehicleSpell ( uint32 creatureID , uint32 spellID );
2010-06-04 23:24:48 +02:00
private :
bool isSourceTypeValid ( Condition * cond );
bool addToLootTemplate ( Condition * cond , LootTemplate * loot );
bool addToGossipMenus ( Condition * cond );
bool addToGossipMenuItems ( Condition * cond );
2012-02-10 23:40:38 +01:00
bool IsObjectMeetToConditionList ( ConditionSourceInfo & sourceInfo , ConditionList const & conditions );
2010-06-04 23:24:48 +02:00
2010-12-06 02:07:53 +01:00
bool isGroupable ( ConditionSourceType sourceType ) const
2010-06-04 23:24:48 +02:00
{
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 ||
2010-10-22 22:45:11 +02:00
sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION ||
2012-01-29 13:49:19 -05:00
sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL ||
sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT );
2010-06-04 23:24:48 +02:00
}
2010-06-11 01:25:10 +02:00
void Clean (); // free up resources
2012-01-29 13:49:19 -05:00
std :: list < Condition *> AllocatedMemoryStore ; // some garbage collection :)
2011-08-04 14:27:10 +02:00
2012-01-29 13:49:19 -05:00
ConditionContainer ConditionStore ;
ConditionReferenceContainer ConditionReferenceStore ;
VehicleSpellConditionContainer VehicleSpellConditionStore ;
SmartEventConditionContainer SmartEventConditionStore ;
2010-06-04 23:24:48 +02:00
};
2012-02-11 15:16:18 +01:00
template < class T > bool CompareValues ( ComparisionType type , T val1 , T val2 )
{
switch ( type )
{
case COMP_TYPE_EQ :
return val1 == val2 ;
case COMP_TYPE_HIGH :
return val1 > val2 ;
case COMP_TYPE_LOW :
return val1 < val2 ;
case COMP_TYPE_HIGH_EQ :
return val1 >= val2 ;
case COMP_TYPE_LOW_EQ :
return val1 <= val2 ;
}
// incorrect parameter
ASSERT ( false );
return false ;
}
2010-12-22 21:25:23 +01:00
#define sConditionMgr ACE_Singleton<ConditionMgr, ACE_Null_Mutex>::instance()
2010-06-04 23:24:48 +02:00
#endif