2010-10-27 21:01:47 +02:00
/*
2011-01-01 15:01:13 +01:00
* Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
2010-10-27 21:01:47 +02:00
*
* 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 ();
2011-03-27 12:54:11 +02:00
~ SmartScript ();
2010-10-27 21:01:47 +02:00
void OnInitialize ( WorldObject * obj , AreaTriggerEntry const * at = NULL );
void GetScript ();
void FillScript ( SmartAIEventList e , WorldObject * obj , AreaTriggerEntry const * at );
2011-07-26 23:09:28 +02:00
void ProcessEventsFor ( SMART_EVENT e , Unit * unit = NULL , uint32 var0 = 0 , uint32 var1 = 0 , bool bvar = false , const SpellInfo * spell = NULL , GameObject * gob = NULL );
void ProcessEvent ( SmartScriptHolder & e , Unit * unit = NULL , uint32 var0 = 0 , uint32 var1 = 0 , bool bvar = false , const SpellInfo * spell = NULL , GameObject * gob = NULL );
2011-03-27 12:54:42 +02:00
bool CheckTimer ( SmartScriptHolder const & e ) const ;
void RecalcTimer ( SmartScriptHolder & e , uint32 min , uint32 max );
void UpdateTimer ( SmartScriptHolder & e , uint32 const diff );
void InitTimer ( SmartScriptHolder & e );
2011-07-26 23:09:28 +02:00
void ProcessAction ( SmartScriptHolder & e , Unit * unit = NULL , uint32 var0 = 0 , uint32 var1 = 0 , bool bvar = false , const SpellInfo * spell = NULL , GameObject * gob = NULL );
2011-05-12 10:42:25 +02:00
ObjectList * GetTargets ( SmartScriptHolder const & e , Unit * invoker = NULL );
2010-10-27 21:01:47 +02:00
ObjectList * GetWorldObjectsInDist ( float dist );
2011-05-12 10:42:25 +02:00
void InstallTemplate ( SmartScriptHolder const & e );
2010-10-27 21:01:47 +02:00
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 ; }
2010-12-06 02:07:53 +01:00
uint32 GetPathId () const { return mPathId ; }
2010-10-27 21:01:47 +02:00
WorldObject * GetBaseObject ()
{
WorldObject * obj = NULL ;
if ( me )
obj = me ;
else if ( go )
obj = go ;
return obj ;
}
2011-03-27 12:54:42 +02:00
2010-10-27 21:01:47 +02:00
bool IsUnit ( WorldObject * obj )
{
return obj && ( obj -> GetTypeId () == TYPEID_UNIT || obj -> GetTypeId () == TYPEID_PLAYER );
}
2011-03-27 12:54:42 +02:00
2010-10-27 21:01:47 +02:00
bool IsPlayer ( WorldObject * obj )
{
return obj && obj -> GetTypeId () == TYPEID_PLAYER ;
}
2011-03-27 12:54:42 +02:00
2010-10-27 21:01:47 +02:00
bool IsCreature ( WorldObject * obj )
{
return obj && obj -> GetTypeId () == TYPEID_UNIT ;
}
2011-03-27 12:54:42 +02:00
2010-10-27 21:01:47 +02:00
bool IsGameObject ( WorldObject * obj )
{
return obj && obj -> GetTypeId () == TYPEID_GAMEOBJECT ;
}
2011-03-27 12:54:42 +02:00
2010-10-27 21:01:47 +02:00
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 );
2011-03-27 12:54:42 +02:00
void OnMoveInLineOfSight ( Unit * who );
2010-10-27 21:01:47 +02:00
Unit * DoSelectLowestHpFriendly ( float range , uint32 MinHPDiff );
void DoFindFriendlyCC ( std :: list < Creature *>& _list , float range );
2011-06-15 17:33:06 +02:00
void DoFindFriendlyMissingBuff ( std :: list < Creature *>& list , float range , uint32 spellid );
2010-10-27 21:01:47 +02:00
void StoreTargetList ( ObjectList * targets , uint32 id )
{
2011-03-26 23:45:23 +01:00
if ( ! targets )
return ;
if ( mTargetStorage -> find ( id ) != mTargetStorage -> end ())
delete ( * mTargetStorage )[ id ];
2010-10-27 21:01:47 +02:00
( * mTargetStorage )[ id ] = targets ;
}
2011-03-26 23:45:23 +01:00
2010-10-27 21:01:47 +02:00
bool IsSmart ( Creature * c = NULL )
{
2010-11-02 13:13:54 +01:00
bool smart = true ;
2011-03-26 23:45:23 +01:00
if ( c && c -> GetAIName () != "SmartAI" )
smart = false ;
if ( ! me || me -> GetAIName () != "SmartAI" )
smart = false ;
2010-11-02 13:13:54 +01:00
if ( ! smart )
2011-06-15 17:33:06 +02:00
sLog -> outErrorDb ( "SmartScript: Action target Creature(entry: %u) is not using SmartAI, action skipped to prevent crash." , c ? c -> GetEntry () : ( me ? me -> GetEntry () : 0 ));
2010-12-07 20:25:45 +01:00
return smart ;
}
2011-03-26 23:45:23 +01:00
2010-12-07 20:25:45 +01:00
bool IsSmartGO ( GameObject * g = NULL )
{
bool smart = true ;
2011-03-26 23:45:23 +01:00
if ( g && g -> GetAIName () != "SmartGameObjectAI" )
smart = false ;
if ( ! go || go -> GetAIName () != "SmartGameObjectAI" )
smart = false ;
2010-12-07 20:25:45 +01:00
if ( ! smart )
2011-06-15 17:33:06 +02:00
sLog -> outErrorDb ( "SmartScript: Action target GameObject(entry: %u) is not using SmartGameObjectAI, action skipped to prevent crash." , g ? g -> GetEntry () : ( go ? go -> GetEntry () : 0 ));
2011-03-26 23:45:23 +01:00
2010-11-02 13:13:54 +01:00
return smart ;
2010-10-27 21:01:47 +02:00
}
2011-03-26 23:45:23 +01:00
2010-10-27 21:01:47 +02:00
ObjectList * GetTargetList ( uint32 id )
{
ObjectListMap :: iterator itr = mTargetStorage -> find ( id );
2011-06-12 02:30:32 +02:00
if ( itr != mTargetStorage -> end ())
2010-10-27 21:01:47 +02:00
return ( * itr ). second ;
return NULL ;
}
2011-08-20 20:31:31 -03:00
GameObject * FindGameObjectNear ( WorldObject * searchObject , uint32 guid ) const
2010-10-27 21:01:47 +02:00
{
2011-08-20 20:31:31 -03:00
GameObject * gameObject = NULL ;
2010-10-27 21:01:47 +02:00
2011-08-20 20:31:31 -03:00
CellPair p ( Trinity :: ComputeCellPair ( searchObject -> GetPositionX (), searchObject -> GetPositionY ()));
2010-10-27 21:01:47 +02:00
Cell cell ( p );
cell . data . Part . reserved = ALL_DISTRICT ;
2011-08-20 20:31:31 -03:00
Trinity :: GameObjectWithDbGUIDCheck goCheck ( * searchObject , guid );
Trinity :: GameObjectSearcher < Trinity :: GameObjectWithDbGUIDCheck > checker ( searchObject , gameObject , goCheck );
2010-10-27 21:01:47 +02:00
TypeContainerVisitor < Trinity :: GameObjectSearcher < Trinity :: GameObjectWithDbGUIDCheck > , GridTypeMapContainer > objectChecker ( checker );
2011-08-20 20:31:31 -03:00
cell . Visit ( p , objectChecker , * searchObject -> GetMap ());
2010-10-27 21:01:47 +02:00
2011-08-20 20:31:31 -03:00
return gameObject ;
2010-10-27 21:01:47 +02:00
}
2011-08-20 20:31:31 -03:00
Creature * FindCreatureNear ( WorldObject * searchObject , uint32 guid ) const
2010-10-27 21:01:47 +02:00
{
2011-03-27 12:54:42 +02:00
Creature * crea = NULL ;
2011-08-20 20:31:31 -03:00
CellPair p ( Trinity :: ComputeCellPair ( searchObject -> GetPositionX (), searchObject -> GetPositionY ()));
2010-10-27 21:01:47 +02:00
Cell cell ( p );
cell . data . Part . reserved = ALL_DISTRICT ;
2011-08-20 20:31:31 -03:00
Trinity :: CreatureWithDbGUIDCheck target_check ( searchObject , guid );
Trinity :: CreatureSearcher < Trinity :: CreatureWithDbGUIDCheck > checker ( searchObject , crea , target_check );
2010-10-27 21:01:47 +02:00
TypeContainerVisitor < Trinity :: CreatureSearcher < Trinity :: CreatureWithDbGUIDCheck > , GridTypeMapContainer > unit_checker ( checker );
2011-08-20 20:31:31 -03:00
cell . Visit ( p , unit_checker , * searchObject -> GetMap ());
2010-10-27 21:01:47 +02:00
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 ;
}
2010-12-07 18:31:34 +01:00
//TIMED_ACTIONLIST (script type 9 aka script9)
2011-03-27 12:54:42 +02:00
void SetScript9 ( SmartScriptHolder & e , uint32 entry );
2011-02-21 22:23:43 +01:00
Unit * GetLastInvoker ();
uint64 mLastInvoker ;
2010-12-07 18:31:34 +01:00
2010-10-27 21:01:47 +02:00
private :
2011-03-27 12:54:42 +02:00
void IncPhase ( int32 p = 1 )
{
2011-06-12 02:30:32 +02:00
if ( p >= 0 )
2010-10-27 23:19:35 +02:00
mEventPhase += ( uint32 ) p ;
else
2010-12-13 22:37:56 +01:00
DecPhase ( abs ( p ));
2010-10-27 23:19:35 +02:00
}
2011-03-27 12:54:42 +02:00
2010-10-27 21:01:47 +02:00
void DecPhase ( int32 p = 1 ) { mEventPhase -= ( mEventPhase < ( uint32 ) p ? ( uint32 ) p - mEventPhase : ( uint32 ) p ); }
2010-12-06 02:07:53 +01:00
bool IsInPhase ( uint32 p ) const { return mEventPhase & p ; }
2010-10-27 21:01:47 +02:00
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 ;
2010-12-13 22:37:56 +01:00
2010-10-27 21:01:47 +02:00
uint32 mInvinceabilityHpLevel ;
UNORDERED_MAP < int32 , int32 > mStoredDecimals ;
uint32 mPathId ;
SmartAIEventList mStoredEvents ;
std :: list < uint32 > mRemIDs ;
uint32 mTextTimer ;
uint32 mLastTextID ;
uint64 mTextGUID ;
2011-09-19 09:24:59 -04:00
uint32 mTalkerEntry ;
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 )
{
2010-11-16 14:08:12 +01:00
if ( i -> event_id == id )
2010-10-27 21:01:47 +02:00
{
mStoredEvents . erase ( i );
return ;
}
2010-12-13 22:37:56 +01:00
2010-10-27 21:01:47 +02:00
}
}
}
SmartScriptHolder FindLinkedEvent ( uint32 link )
{
if ( ! mEvents . empty ())
{
for ( SmartAIEventList :: iterator i = mEvents . begin (); i != mEvents . end (); ++ i )
{
if ( i -> event_id == link )
{
return ( * i );
}
2010-12-13 22:37:56 +01:00
2010-10-27 21:01:47 +02:00
}
}
SmartScriptHolder s ;
return s ;
}
};
#endif