2010-10-27 21:01:47 +02:00
/*
* Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/>
*
* 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/>.
*/
#ifndef TRINITY_SMARTSCRIPT_H
#define TRINITY_SMARTSCRIPT_H
#include "Common.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "Unit.h"
#include "ConditionMgr.h"
#include "CreatureTextMgr.h"
#include "Spell.h"
#include "GridNotifiers.h"
#include "SmartScriptMgr.h"
//#include "SmartAI.h"
class SmartScript
{
public :
~ SmartScript (){};
SmartScript ();
void OnInitialize ( WorldObject * obj , AreaTriggerEntry const * at = NULL );
void GetScript ();
void FillScript ( SmartAIEventList e , WorldObject * obj , AreaTriggerEntry const * at );
void ProcessEventsFor ( SMART_EVENT e , Unit * unit = NULL , uint32 var0 = 0 , uint32 var1 = 0 , bool bvar = false , const SpellEntry * spell = NULL , GameObject * gob = NULL );
void ProcessEvent ( SmartScriptHolder & e , Unit * unit = NULL , uint32 var0 = 0 , uint32 var1 = 0 , bool bvar = false , const SpellEntry * spell = NULL , GameObject * gob = NULL );
bool CheckTimer ( SmartScriptHolder & e );
void RecalcTimer ( SmartScriptHolder & e , uint32 min , uint32 max );
void UpdateTimer ( SmartScriptHolder & e , const uint32 diff );
void InitTimer ( SmartScriptHolder & e );
void ProcessAction ( SmartScriptHolder & e , Unit * unit = NULL , uint32 var0 = 0 , uint32 var1 = 0 , bool bvar = false , const SpellEntry * spell = NULL , GameObject * gob = NULL );
ObjectList * GetTargets ( SmartScriptHolder e , Unit * invoker = NULL );
ObjectList * GetWorldObjectsInDist ( float dist );
void InstallTemplate ( SmartScriptHolder e );
SmartScriptHolder CreateEvent ( SMART_EVENT e , uint32 event_flags , uint32 event_param1 , uint32 event_param2 , uint32 event_param3 , uint32 event_param4 , SMART_ACTION action , uint32 action_param1 , uint32 action_param2 , uint32 action_param3 , uint32 action_param4 , uint32 action_param5 , uint32 action_param6 , SMARTAI_TARGETS t , uint32 target_param1 , uint32 target_param2 , uint32 target_param3 , uint32 phaseMask = 0 );
void AddEvent ( SMART_EVENT e , uint32 event_flags , uint32 event_param1 , uint32 event_param2 , uint32 event_param3 , uint32 event_param4 , SMART_ACTION action , uint32 action_param1 , uint32 action_param2 , uint32 action_param3 , uint32 action_param4 , uint32 action_param5 , uint32 action_param6 , SMARTAI_TARGETS t , uint32 target_param1 , uint32 target_param2 , uint32 target_param3 , uint32 phaseMask = 0 );
void SetPathId ( uint32 id ) { mPathId = id ; }
uint32 GetPathId () { return mPathId ; }
WorldObject * GetBaseObject ()
{
WorldObject * obj = NULL ;
if ( me )
obj = me ;
else if ( go )
obj = go ;
return obj ;
}
bool IsUnit ( WorldObject * obj )
{
return obj && ( obj -> GetTypeId () == TYPEID_UNIT || obj -> GetTypeId () == TYPEID_PLAYER );
}
bool IsPlayer ( WorldObject * obj )
{
return obj && obj -> GetTypeId () == TYPEID_PLAYER ;
}
bool IsCreature ( WorldObject * obj )
{
return obj && obj -> GetTypeId () == TYPEID_UNIT ;
}
bool IsGameObject ( WorldObject * obj )
{
return obj && obj -> GetTypeId () == TYPEID_GAMEOBJECT ;
}
bool ConditionValid ( Unit * u , int32 c , int32 v1 , int32 v2 , int32 v3 )
{
if ( c == 0 ) return true ;
if ( ! u || ! u -> ToPlayer ()) return false ;
Condition cond ;
cond . mConditionType = ConditionType ( uint32 ( c ));
cond . mConditionValue1 = uint32 ( v1 );
cond . mConditionValue1 = uint32 ( v2 );
cond . mConditionValue1 = uint32 ( v3 );
return cond . Meets ( u -> ToPlayer ());
}
void OnUpdate ( const uint32 diff );
void OnMoveInLineOfSight ( Unit * who );
Unit * DoSelectLowestHpFriendly ( float range , uint32 MinHPDiff );
void DoFindFriendlyCC ( std :: list < Creature *>& _list , float range );
void DoFindFriendlyMissingBuff ( std :: list < Creature *>& _list , float range , uint32 spellid );
void StoreTargetList ( ObjectList * targets , uint32 id )
{
if ( ! targets ) return ;
if ( mTargetStorage -> find ( id ) != mTargetStorage -> end ())
mTargetStorage -> erase ( id );
( * mTargetStorage )[ id ] = targets ;
}
bool IsSmart ( Creature * c = NULL )
{
2010-11-02 13:13:54 +01:00
bool smart = true ;
if ( c && c -> GetAIName () != "SmartAI" ) smart = false ;
if ( ! me || me -> GetAIName () != "SmartAI" ) smart = false ;
if ( ! smart )
sLog . outErrorDb ( "SmartScript: Action target creature(entry: %u) is not using SmartAI, action skipped to prevent crash." , c ? c -> GetEntry () : ( me ? me -> GetEntry () : 0 ));
return smart ;
2010-10-27 21:01:47 +02:00
}
ObjectList * GetTargetList ( uint32 id )
{
ObjectListMap :: iterator itr = mTargetStorage -> find ( id );
if ( itr != mTargetStorage -> end ())
return ( * itr ). second ;
return NULL ;
}
inline GameObject * FindGameObjectNear ( WorldObject * pSearchObject , uint32 guid ) const
{
GameObject * pGameObject = NULL ;
CellPair p ( Trinity :: ComputeCellPair ( pSearchObject -> GetPositionX (), pSearchObject -> GetPositionY ()));
Cell cell ( p );
cell . data . Part . reserved = ALL_DISTRICT ;
Trinity :: GameObjectWithDbGUIDCheck goCheck ( * pSearchObject , guid );
Trinity :: GameObjectSearcher < Trinity :: GameObjectWithDbGUIDCheck > checker ( pSearchObject , pGameObject , goCheck );
TypeContainerVisitor < Trinity :: GameObjectSearcher < Trinity :: GameObjectWithDbGUIDCheck > , GridTypeMapContainer > objectChecker ( checker );
cell . Visit ( p , objectChecker , * pSearchObject -> GetMap ());
return pGameObject ;
}
inline Creature * FindCreatureNear ( WorldObject * pSearchObject , uint32 guid ) const
{
Creature * crea = NULL ;
CellPair p ( Trinity :: ComputeCellPair ( pSearchObject -> GetPositionX (), pSearchObject -> GetPositionY ()));
Cell cell ( p );
cell . data . Part . reserved = ALL_DISTRICT ;
Trinity :: CreatureWithDbGUIDCheck target_check ( pSearchObject , guid );
Trinity :: CreatureSearcher < Trinity :: CreatureWithDbGUIDCheck > checker ( pSearchObject , crea , target_check );
TypeContainerVisitor < Trinity :: CreatureSearcher < Trinity :: CreatureWithDbGUIDCheck > , GridTypeMapContainer > unit_checker ( checker );
cell . Visit ( p , unit_checker , * pSearchObject -> GetMap ());
return crea ;
}
ObjectListMap * mTargetStorage ;
void OnReset ();
void ResetBaseObject ()
{
if ( meOrigGUID )
{
if ( Creature * m = HashMapHolder < Creature >:: Find ( meOrigGUID ))
{
me = m ;
go = NULL ;
}
}
if ( goOrigGUID )
{
if ( GameObject * o = HashMapHolder < GameObject >:: Find ( goOrigGUID ))
{
me = NULL ;
go = o ;
}
}
goOrigGUID = 0 ;
meOrigGUID = 0 ;
}
private :
2010-10-27 23:19:35 +02:00
void IncPhase ( int32 p = 1 ) {
if ( p >= 0 )
mEventPhase += ( uint32 ) p ;
else
DecPhase ( abs ( p ));
}
2010-10-27 21:01:47 +02:00
void DecPhase ( int32 p = 1 ) { mEventPhase -= ( mEventPhase < ( uint32 ) p ? ( uint32 ) p - mEventPhase : ( uint32 ) p ); }
bool IsInPhase ( uint32 p ) { return mEventPhase & p ; }
void SetPhase ( uint32 p = 0 ) { mEventPhase = p ; }
SmartAIEventList mEvents ;
SmartAIEventList mInstallEvents ;
2010-11-03 14:10:16 +01:00
SmartAIEventList mTimedActionList ;
bool mResumeActionList ;
2010-10-27 21:01:47 +02:00
Creature * me ;
uint64 meOrigGUID ;
GameObject * go ;
uint64 goOrigGUID ;
AreaTriggerEntry const * trigger ;
SmartScriptType mScriptType ;
uint32 mEventPhase ;
uint32 mInvinceabilityHpLevel ;
UNORDERED_MAP < int32 , int32 > mStoredDecimals ;
uint32 mPathId ;
SmartAIEventList mStoredEvents ;
std :: list < uint32 > mRemIDs ;
uint32 mTextTimer ;
uint32 mLastTextID ;
uint64 mTextGUID ;
2010-11-01 11:00:53 +01:00
Creature * talker ;
2010-10-27 21:01:47 +02:00
bool mUseTextTimer ;
2010-11-01 11:00:53 +01:00
2010-10-27 21:01:47 +02:00
SMARTAI_TEMPLATE mTemplate ;
void InstallEvents ();
void RemoveStoredEvent ( uint32 id )
{
if ( ! mStoredEvents . empty ())
{
for ( SmartAIEventList :: iterator i = mStoredEvents . begin (); i != mStoredEvents . end (); ++ i )
{
if ( i -> event_id = id )
{
mStoredEvents . erase ( i );
return ;
}
}
}
}
SmartScriptHolder FindLinkedEvent ( uint32 link )
{
if ( ! mEvents . empty ())
{
for ( SmartAIEventList :: iterator i = mEvents . begin (); i != mEvents . end (); ++ i )
{
if ( i -> event_id == link )
{
return ( * i );
}
}
}
SmartScriptHolder s ;
return s ;
}
};
#endif