2010-10-27 21:01:47 +02:00
/*
2012-01-01 00:32:13 +01:00
* Copyright (C) 2008-2012 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/>.
*/
#include "DatabaseEnv.h"
#include "ObjectMgr.h"
#include "ObjectDefines.h"
#include "GridDefines.h"
#include "GridNotifiers.h"
#include "SpellMgr.h"
#include "GridNotifiersImpl.h"
#include "Cell.h"
#include "CellImpl.h"
#include "InstanceScript.h"
#include "ScriptedCreature.h"
2011-12-11 16:22:18 +01:00
#include "GameEventMgr.h"
2012-03-01 23:45:07 +01:00
#include "CreatureTextMgr.h"
2010-10-27 21:01:47 +02:00
#include "SmartScriptMgr.h"
void SmartWaypointMgr :: LoadFromDB ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2012-03-24 18:42:35 +01:00
for ( UNORDERED_MAP < uint32 , WPPath *>:: iterator itr = waypoint_map . begin (); itr != waypoint_map . end (); ++ itr )
{
for ( WPPath :: iterator pathItr = itr -> second -> begin (); pathItr != itr -> second -> end (); ++ pathItr )
delete pathItr -> second ;
delete itr -> second ;
}
2010-10-27 21:01:47 +02:00
waypoint_map . clear ();
2011-12-31 20:14:38 +01:00
PreparedStatement * stmt = WorldDatabase . GetPreparedStatement ( WORLD_SEL_SMARTAI_WP );
2010-10-27 21:01:47 +02:00
PreparedQueryResult result = WorldDatabase . Query ( stmt );
if ( ! result )
{
2012-08-16 00:23:44 +02:00
sLog -> outInfo ( LOG_FILTER_SERVER_LOADING , ">> Loaded 0 SmartAI Waypoint Paths. DB table `waypoints` is empty." );
2012-08-03 15:54:54 +02:00
2010-10-27 21:01:47 +02:00
return ;
}
uint32 count = 0 ;
uint32 total = 0 ;
2010-12-19 17:06:33 +01:00
uint32 last_entry = 0 ;
uint32 last_id = 1 ;
2010-10-27 21:01:47 +02:00
do
{
2011-03-27 12:54:42 +02:00
Field * fields = result -> Fetch ();
2010-10-27 21:01:47 +02:00
uint32 entry = fields [ 0 ]. GetUInt32 ();
uint32 id = fields [ 1 ]. GetUInt32 ();
2011-04-29 20:47:02 +02:00
float x , y , z ;
2010-10-27 21:01:47 +02:00
x = fields [ 2 ]. GetFloat ();
y = fields [ 3 ]. GetFloat ();
z = fields [ 4 ]. GetFloat ();
2010-12-13 22:37:56 +01:00
2010-10-27 21:01:47 +02:00
if ( last_entry != entry )
{
2012-02-23 13:01:16 +01:00
waypoint_map [ entry ] = new WPPath ();
2010-10-27 21:01:47 +02:00
last_id = 1 ;
2012-02-23 13:01:16 +01:00
count ++ ;
2010-10-27 21:01:47 +02:00
}
2011-11-26 01:53:44 +01:00
2010-10-27 21:01:47 +02:00
if ( last_id != id )
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartWaypointMgr::LoadFromDB: Path entry %u, unexpected point id %u, expected %u." , entry , id , last_id );
2011-11-26 01:53:44 +01:00
2010-10-27 21:01:47 +02:00
last_id ++ ;
2012-02-23 13:01:16 +01:00
( * waypoint_map [ entry ])[ id ] = new WayPoint ( id , x , y , z );
2010-10-27 21:01:47 +02:00
last_entry = entry ;
total ++ ;
2010-12-19 17:06:33 +01:00
}
while ( result -> NextRow ());
2010-10-27 21:01:47 +02:00
2012-08-16 00:23:44 +02:00
sLog -> outInfo ( LOG_FILTER_SERVER_LOADING , ">> Loaded %u SmartAI waypoint paths (total %u waypoints) in %u ms" , count , total , GetMSTimeDiffToNow ( oldMSTime ));
2012-08-03 15:54:54 +02:00
2010-10-27 21:01:47 +02:00
}
2012-03-24 18:42:35 +01:00
SmartWaypointMgr ::~ SmartWaypointMgr ()
{
for ( UNORDERED_MAP < uint32 , WPPath *>:: iterator itr = waypoint_map . begin (); itr != waypoint_map . end (); ++ itr )
{
for ( WPPath :: iterator pathItr = itr -> second -> begin (); pathItr != itr -> second -> end (); ++ pathItr )
delete pathItr -> second ;
delete itr -> second ;
}
waypoint_map . clear ();
}
2010-10-27 21:01:47 +02:00
void SmartAIMgr :: LoadSmartAIFromDB ()
{
2010-12-19 17:06:33 +01:00
uint32 oldMSTime = getMSTime ();
2010-10-27 21:01:47 +02:00
for ( uint8 i = 0 ; i < SMART_SCRIPT_TYPE_MAX ; i ++ )
mEventMap [ i ]. clear (); //Drop Existing SmartAI List
2011-12-31 20:14:38 +01:00
PreparedStatement * stmt = WorldDatabase . GetPreparedStatement ( WORLD_SEL_SMART_SCRIPTS );
2010-10-27 21:01:47 +02:00
PreparedQueryResult result = WorldDatabase . Query ( stmt );
if ( ! result )
{
2012-08-16 00:23:44 +02:00
sLog -> outInfo ( LOG_FILTER_SERVER_LOADING , ">> Loaded 0 SmartAI scripts. DB table `smartai_scripts` is empty." );
2012-08-03 15:54:54 +02:00
2010-10-27 21:01:47 +02:00
return ;
}
2010-12-19 17:06:33 +01:00
uint32 count = 0 ;
2010-10-27 21:01:47 +02:00
do
{
Field * fields = result -> Fetch ();
SmartScriptHolder temp ;
temp . entryOrGuid = fields [ 0 ]. GetInt32 ();
2011-02-20 19:11:42 +00:00
SmartScriptType source_type = ( SmartScriptType ) fields [ 1 ]. GetUInt8 ();
2010-10-27 21:01:47 +02:00
if ( source_type >= SMART_SCRIPT_TYPE_MAX )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr::LoadSmartAIFromDB: invalid source_type (%u), skipped loading." , uint32 ( source_type ));
2010-10-27 21:01:47 +02:00
continue ;
}
if ( temp . entryOrGuid >= 0 )
{
2011-09-29 12:43:05 +02:00
switch ( source_type )
2010-10-27 21:01:47 +02:00
{
case SMART_SCRIPT_TYPE_CREATURE :
{
2011-04-28 22:57:08 +02:00
if ( ! sObjectMgr -> GetCreatureTemplate (( uint32 ) temp . entryOrGuid ))
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) does not exist, skipped loading." , uint32 ( temp . entryOrGuid ));
2010-10-27 21:01:47 +02:00
continue ;
}
break ;
}
case SMART_SCRIPT_TYPE_GAMEOBJECT :
{
2011-04-28 22:54:30 +02:00
if ( ! sObjectMgr -> GetGameObjectTemplate (( uint32 ) temp . entryOrGuid ))
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr::LoadSmartAIFromDB: GameObject entry (%u) does not exist, skipped loading." , uint32 ( temp . entryOrGuid ));
2010-10-27 21:01:47 +02:00
continue ;
}
break ;
}
case SMART_SCRIPT_TYPE_AREATRIGGER :
{
if ( ! sAreaTriggerStore . LookupEntry (( uint32 ) temp . entryOrGuid ))
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr::LoadSmartAIFromDB: AreaTrigger entry (%u) does not exist, skipped loading." , uint32 ( temp . entryOrGuid ));
2010-10-27 21:01:47 +02:00
continue ;
}
break ;
}
2010-11-03 14:10:16 +01:00
case SMART_SCRIPT_TYPE_TIMED_ACTIONLIST :
break ; //nothing to check, really
2010-10-27 21:01:47 +02:00
default :
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr::LoadSmartAIFromDB: not yet implemented source_type %u" , ( uint32 ) source_type );
2010-10-27 21:01:47 +02:00
continue ;
}
2011-10-30 13:12:39 +00:00
}
else
2010-10-27 21:01:47 +02:00
{
2010-12-22 21:25:23 +01:00
if ( ! sObjectMgr -> GetCreatureData ( uint32 ( abs ( temp . entryOrGuid ))))
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading." , uint32 ( abs ( temp . entryOrGuid )));
2010-10-27 21:01:47 +02:00
continue ;
}
}
2011-10-30 13:12:39 +00:00
2010-10-27 21:01:47 +02:00
temp . source_type = source_type ;
2011-02-20 19:11:42 +00:00
temp . event_id = fields [ 2 ]. GetUInt16 ();
temp . link = fields [ 3 ]. GetUInt16 ();
temp . event . type = ( SMART_EVENT ) fields [ 4 ]. GetUInt8 ();
temp . event . event_phase_mask = fields [ 5 ]. GetUInt8 ();
temp . event . event_chance = fields [ 6 ]. GetUInt8 ();
temp . event . event_flags = fields [ 7 ]. GetUInt8 ();
2010-10-27 21:01:47 +02:00
temp . event . raw . param1 = fields [ 8 ]. GetUInt32 ();
temp . event . raw . param2 = fields [ 9 ]. GetUInt32 ();
temp . event . raw . param3 = fields [ 10 ]. GetUInt32 ();
temp . event . raw . param4 = fields [ 11 ]. GetUInt32 ();
2011-02-20 19:11:42 +00:00
temp . action . type = ( SMART_ACTION ) fields [ 12 ]. GetUInt8 ();
2010-10-27 21:01:47 +02:00
temp . action . raw . param1 = fields [ 13 ]. GetUInt32 ();
temp . action . raw . param2 = fields [ 14 ]. GetUInt32 ();
temp . action . raw . param3 = fields [ 15 ]. GetUInt32 ();
temp . action . raw . param4 = fields [ 16 ]. GetUInt32 ();
temp . action . raw . param5 = fields [ 17 ]. GetUInt32 ();
temp . action . raw . param6 = fields [ 18 ]. GetUInt32 ();
2011-02-20 19:11:42 +00:00
temp . target . type = ( SMARTAI_TARGETS ) fields [ 19 ]. GetUInt8 ();
2010-10-27 21:01:47 +02:00
temp . target . raw . param1 = fields [ 20 ]. GetUInt32 ();
temp . target . raw . param2 = fields [ 21 ]. GetUInt32 ();
temp . target . raw . param3 = fields [ 22 ]. GetUInt32 ();
temp . target . x = fields [ 23 ]. GetFloat ();
temp . target . y = fields [ 24 ]. GetFloat ();
temp . target . z = fields [ 25 ]. GetFloat ();
temp . target . o = fields [ 26 ]. GetFloat ();
//check target
if ( ! IsTargetValid ( temp ))
continue ;
// check all event and action params
if ( ! IsEventValid ( temp ))
continue ;
// creature entry / guid not found in storage, create empty event list for it and increase counters
if ( mEventMap [ source_type ]. find ( temp . entryOrGuid ) == mEventMap [ source_type ]. end ())
{
2010-12-19 17:06:33 +01:00
++ count ;
2010-10-27 21:01:47 +02:00
SmartAIEventList eventList ;
mEventMap [ source_type ][ temp . entryOrGuid ] = eventList ;
}
// store the new event
mEventMap [ source_type ][ temp . entryOrGuid ]. push_back ( temp );
2010-12-19 17:06:33 +01:00
}
while ( result -> NextRow ());
2010-10-27 21:01:47 +02:00
2012-08-16 00:23:44 +02:00
sLog -> outInfo ( LOG_FILTER_SERVER_LOADING , ">> Loaded %u SmartAI scripts in %u ms" , count , GetMSTimeDiffToNow ( oldMSTime ));
2012-08-03 14:20:18 +02:00
2010-10-27 21:01:47 +02:00
}
2011-05-12 10:40:53 +02:00
bool SmartAIMgr :: IsTargetValid ( SmartScriptHolder const & e )
2010-10-27 21:01:47 +02:00
{
if ( e . GetActionType () == SMART_ACTION_INSTALL_AI_TEMPLATE )
2011-10-30 13:12:39 +00:00
return true ; // AI template has special handling
2010-10-27 21:01:47 +02:00
switch ( e . GetTargetType ())
{
case SMART_TARGET_CREATURE_DISTANCE :
case SMART_TARGET_CREATURE_RANGE :
2011-10-30 13:12:39 +00:00
{
if ( e . target . unitDistance . creature && ! sObjectMgr -> GetCreatureTemplate ( e . target . unitDistance . creature ))
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Creature entry %u as target_param1, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . target . unitDistance . creature );
2011-10-30 13:12:39 +00:00
return false ;
2010-10-27 21:01:47 +02:00
}
2011-10-30 13:12:39 +00:00
break ;
}
2010-10-27 21:01:47 +02:00
case SMART_TARGET_GAMEOBJECT_DISTANCE :
case SMART_TARGET_GAMEOBJECT_RANGE :
2011-10-30 13:12:39 +00:00
{
if ( e . target . goDistance . entry && ! sObjectMgr -> GetGameObjectTemplate ( e . target . goDistance . entry ))
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent GameObject entry %u as target_param1, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . target . goDistance . entry );
2011-10-30 13:12:39 +00:00
return false ;
2010-10-27 21:01:47 +02:00
}
2011-10-30 13:12:39 +00:00
break ;
}
2010-10-27 21:01:47 +02:00
case SMART_TARGET_CREATURE_GUID :
2011-10-30 13:12:39 +00:00
{
2011-12-27 20:23:55 -05:00
if ( e . target . unitGUID . entry && ! IsCreatureValid ( e , e . target . unitGUID . entry ))
return false ;
2011-10-30 13:12:39 +00:00
break ;
}
2010-10-27 21:01:47 +02:00
case SMART_TARGET_GAMEOBJECT_GUID :
2011-10-30 13:12:39 +00:00
{
2012-02-18 16:52:08 +01:00
if ( e . target . goGUID . entry && ! IsGameObjectValid ( e , e . target . goGUID . entry ))
2011-12-27 20:23:55 -05:00
return false ;
2011-10-30 13:12:39 +00:00
break ;
}
case SMART_TARGET_PLAYER_DISTANCE :
case SMART_TARGET_CLOSEST_PLAYER :
{
if ( e . target . playerDistance . dist == 0 )
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has maxDist 0 as target_param1, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType ());
2011-10-30 13:12:39 +00:00
return false ;
2010-10-27 21:01:47 +02:00
}
2011-10-30 13:12:39 +00:00
break ;
}
2010-10-27 21:01:47 +02:00
case SMART_TARGET_PLAYER_RANGE :
case SMART_TARGET_SELF :
case SMART_TARGET_VICTIM :
case SMART_TARGET_HOSTILE_SECOND_AGGRO :
case SMART_TARGET_HOSTILE_LAST_AGGRO :
case SMART_TARGET_HOSTILE_RANDOM :
case SMART_TARGET_HOSTILE_RANDOM_NOT_TOP :
case SMART_TARGET_ACTION_INVOKER :
2012-01-22 01:49:53 +01:00
case SMART_TARGET_INVOKER_PARTY :
2010-10-27 21:01:47 +02:00
case SMART_TARGET_POSITION :
case SMART_TARGET_NONE :
2010-10-31 14:21:35 +01:00
case SMART_TARGET_ACTION_INVOKER_VEHICLE :
2010-11-07 18:02:33 +01:00
case SMART_TARGET_OWNER_OR_SUMMONER :
2010-11-20 12:42:10 +01:00
case SMART_TARGET_THREAT_LIST :
2011-10-30 13:12:39 +00:00
case SMART_TARGET_CLOSEST_GAMEOBJECT :
case SMART_TARGET_CLOSEST_CREATURE :
2011-12-27 20:23:55 -05:00
case SMART_TARGET_STORED :
2010-10-27 21:01:47 +02:00
break ;
default :
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Not handled target_type(%u), Entry %d SourceType %u Event %u Action %u, skipped." , e . GetTargetType (), e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType ());
2010-10-27 21:01:47 +02:00
return false ;
}
return true ;
}
2011-08-18 14:55:27 -03:00
bool SmartAIMgr :: IsEventValid ( SmartScriptHolder & e )
2010-10-27 21:01:47 +02:00
{
if ( e . event . type >= SMART_EVENT_END )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event type (%u), skipped." , e . entryOrGuid , e . event_id , e . GetEventType ());
2010-10-27 21:01:47 +02:00
return false ;
}
2010-11-03 14:10:16 +01:00
// in SMART_SCRIPT_TYPE_TIMED_ACTIONLIST all event types are overriden by core
if ( e . GetScriptType () != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST && ! ( SmartAIEventMask [ e . event . type ][ 1 ] & SmartAITypeMask [ e . GetScriptType ()][ 1 ]))
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: EntryOrGuid %d, event type %u can not be used for Script type %u" , e . entryOrGuid , e . GetEventType (), e . GetScriptType ());
2010-10-27 21:01:47 +02:00
return false ;
}
2012-05-20 16:13:52 +01:00
if ( e . action . type <= 0 || e . action . type >= SMART_ACTION_END )
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid action type (%u), skipped." , e . entryOrGuid , e . event_id , e . GetActionType ());
2010-10-27 21:01:47 +02:00
return false ;
}
if ( e . event . event_phase_mask > SMART_EVENT_PHASE_ALL )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid phase mask (%u), skipped." , e . entryOrGuid , e . event_id , e . event . event_phase_mask );
2010-10-27 21:01:47 +02:00
return false ;
}
2012-05-20 16:13:52 +01:00
if ( e . event . event_flags > SMART_EVENT_FLAGS_ALL )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event flags (%u), skipped." , e . entryOrGuid , e . event_id , e . event . event_flags );
2012-05-20 16:13:52 +01:00
return false ;
}
2010-11-03 14:10:16 +01:00
if ( e . GetScriptType () == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST )
2010-10-27 21:01:47 +02:00
{
2010-11-03 14:10:16 +01:00
e . event . type = SMART_EVENT_UPDATE_OOC ; //force default OOC, can change when calling the script!
2012-03-28 20:00:29 +08:00
if ( ! IsMinMaxValid ( e , e . event . minMaxRepeat . min , e . event . minMaxRepeat . max ))
return false ;
if ( ! IsMinMaxValid ( e , e . event . minMaxRepeat . repeatMin , e . event . minMaxRepeat . repeatMax ))
return false ;
2010-11-03 14:10:16 +01:00
}
else
{
2011-03-08 19:11:02 +01:00
uint32 type = e . event . type ;
switch ( type )
2010-11-03 14:10:16 +01:00
{
case SMART_EVENT_UPDATE :
case SMART_EVENT_UPDATE_IC :
case SMART_EVENT_UPDATE_OOC :
case SMART_EVENT_HEALT_PCT :
case SMART_EVENT_MANA_PCT :
case SMART_EVENT_TARGET_HEALTH_PCT :
case SMART_EVENT_TARGET_MANA_PCT :
case SMART_EVENT_RANGE :
case SMART_EVENT_DAMAGED :
case SMART_EVENT_DAMAGED_TARGET :
case SMART_EVENT_RECEIVE_HEAL :
2012-03-28 20:00:29 +08:00
if ( ! IsMinMaxValid ( e , e . event . minMaxRepeat . min , e . event . minMaxRepeat . max ))
return false ;
if ( ! IsMinMaxValid ( e , e . event . minMaxRepeat . repeatMin , e . event . minMaxRepeat . repeatMax ))
return false ;
2010-11-03 14:10:16 +01:00
break ;
case SMART_EVENT_SPELLHIT :
case SMART_EVENT_SPELLHIT_TARGET :
if ( e . event . spellHit . spell )
2010-10-27 21:01:47 +02:00
{
2011-08-20 20:31:31 -03:00
SpellInfo const * spellInfo = sSpellMgr -> GetSpellInfo ( e . event . spellHit . spell );
if ( ! spellInfo )
2010-11-03 14:10:16 +01:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Spell entry %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . event . spellHit . spell );
2010-11-03 14:10:16 +01:00
return false ;
}
2011-08-20 20:31:31 -03:00
if ( e . event . spellHit . school && ( e . event . spellHit . school & spellInfo -> SchoolMask ) != spellInfo -> SchoolMask )
2010-11-03 14:10:16 +01:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses Spell entry %u with invalid school mask, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . event . spellHit . spell );
2010-11-03 14:10:16 +01:00
return false ;
}
2010-10-27 21:01:47 +02:00
}
2012-03-28 20:00:29 +08:00
if ( ! IsMinMaxValid ( e , e . event . spellHit . cooldownMin , e . event . spellHit . cooldownMax ))
return false ;
2010-11-03 14:10:16 +01:00
break ;
case SMART_EVENT_OOC_LOS :
case SMART_EVENT_IC_LOS :
2012-03-28 20:00:29 +08:00
if ( ! IsMinMaxValid ( e , e . event . los . cooldownMin , e . event . los . cooldownMax ))
return false ;
2010-11-03 14:10:16 +01:00
break ;
case SMART_EVENT_RESPAWN :
if ( e . event . respawn . type == SMART_SCRIPT_RESPAWN_CONDITION_MAP && ! sMapStore . LookupEntry ( e . event . respawn . map ))
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Map entry %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . event . respawn . map );
2010-10-27 21:01:47 +02:00
return false ;
}
2010-11-03 14:10:16 +01:00
if ( e . event . respawn . type == SMART_SCRIPT_RESPAWN_CONDITION_AREA && ! GetAreaEntryByAreaID ( e . event . respawn . area ))
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Area entry %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . event . respawn . area );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
2010-11-03 14:10:16 +01:00
case SMART_EVENT_FRIENDLY_HEALTH :
2012-03-28 20:00:29 +08:00
if ( ! NotNULL ( e , e . event . friendlyHealt . radius ))
return false ;
if ( ! IsMinMaxValid ( e , e . event . friendlyHealt . repeatMin , e . event . friendlyHealt . repeatMax ))
return false ;
2010-11-03 14:10:16 +01:00
break ;
case SMART_EVENT_FRIENDLY_IS_CC :
2012-03-28 20:00:29 +08:00
if ( ! IsMinMaxValid ( e , e . event . friendlyCC . repeatMin , e . event . friendlyCC . repeatMax ))
return false ;
2010-11-03 14:10:16 +01:00
break ;
case SMART_EVENT_FRIENDLY_MISSING_BUFF :
2010-10-27 21:01:47 +02:00
{
2012-03-28 20:00:29 +08:00
if ( ! IsSpellValid ( e , e . event . missingBuff . spell ))
return false ;
if ( ! NotNULL ( e , e . event . missingBuff . radius ))
return false ;
if ( ! IsMinMaxValid ( e , e . event . missingBuff . repeatMin , e . event . missingBuff . repeatMax ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
}
2010-11-03 14:10:16 +01:00
case SMART_EVENT_KILL :
2012-03-28 20:00:29 +08:00
if ( ! IsMinMaxValid ( e , e . event . kill . cooldownMin , e . event . kill . cooldownMax ))
return false ;
if ( e . event . kill . creature && ! IsCreatureValid ( e , e . event . kill . creature ))
return false ;
2010-11-03 14:10:16 +01:00
break ;
case SMART_EVENT_TARGET_CASTING :
case SMART_EVENT_PASSENGER_BOARDED :
case SMART_EVENT_PASSENGER_REMOVED :
2012-03-28 20:00:29 +08:00
if ( ! IsMinMaxValid ( e , e . event . minMax . repeatMin , e . event . minMax . repeatMax ))
return false ;
2010-11-03 14:10:16 +01:00
break ;
case SMART_EVENT_SUMMON_DESPAWNED :
case SMART_EVENT_SUMMONED_UNIT :
2012-03-28 20:00:29 +08:00
if ( e . event . summoned . creature && ! IsCreatureValid ( e , e . event . summoned . creature ))
return false ;
if ( ! IsMinMaxValid ( e , e . event . summoned . cooldownMin , e . event . summoned . cooldownMax ))
return false ;
2010-11-03 14:10:16 +01:00
break ;
case SMART_EVENT_ACCEPTED_QUEST :
case SMART_EVENT_REWARD_QUEST :
2011-10-24 23:21:34 +01:00
if ( e . event . quest . quest && ! IsQuestValid ( e , e . event . quest . quest ))
return false ;
2010-11-03 14:10:16 +01:00
break ;
case SMART_EVENT_RECEIVE_EMOTE :
2010-10-27 21:01:47 +02:00
{
2012-03-28 20:00:29 +08:00
if ( e . event . emote . emote && ! IsTextEmoteValid ( e , e . event . emote . emote ))
return false ;
if ( ! IsMinMaxValid ( e , e . event . emote . cooldownMin , e . event . emote . cooldownMax ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
}
2010-11-03 14:10:16 +01:00
case SMART_EVENT_HAS_AURA :
case SMART_EVENT_TARGET_BUFFED :
2010-10-27 21:01:47 +02:00
{
2012-03-28 20:00:29 +08:00
if ( ! IsSpellValid ( e , e . event . aura . spell ))
return false ;
if ( ! IsMinMaxValid ( e , e . event . aura . repeatMin , e . event . aura . repeatMax ))
return false ;
2010-11-03 14:10:16 +01:00
break ;
}
case SMART_EVENT_TRANSPORT_ADDCREATURE :
2012-06-17 21:50:01 +01:00
{
if ( e . event . transportAddCreature . creature && ! IsCreatureValid ( e , e . event . transportAddCreature . creature ))
return false ;
break ;
}
2010-11-03 14:10:16 +01:00
case SMART_EVENT_MOVEMENTINFORM :
2012-06-17 21:50:01 +01:00
{
if ( e . event . movementInform . type > NULL_MOTION_TYPE )
2010-11-03 14:10:16 +01:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Motion type %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . event . movementInform . type );
2012-06-17 21:50:01 +01:00
return false ;
2010-10-27 21:01:47 +02:00
}
2012-06-17 21:50:01 +01:00
break ;
}
2010-11-03 14:10:16 +01:00
case SMART_EVENT_DATA_SET :
2012-06-17 21:50:01 +01:00
{
if ( ! IsMinMaxValid ( e , e . event . dataSet . cooldownMin , e . event . dataSet . cooldownMax ))
return false ;
break ;
}
2010-11-03 14:10:16 +01:00
case SMART_EVENT_AREATRIGGER_ONTRIGGER :
2012-06-17 21:50:01 +01:00
{
if ( e . event . areatrigger . id && ! IsAreaTriggerValid ( e , e . event . areatrigger . id ))
return false ;
break ;
}
2010-11-03 14:10:16 +01:00
case SMART_EVENT_TEXT_OVER :
//if (e.event.textOver.textGroupID && !IsTextValid(e, e.event.textOver.textGroupID)) return false;// 0 is a valid text group!
2010-10-27 21:01:47 +02:00
break ;
2010-11-03 14:10:16 +01:00
case SMART_EVENT_LINK :
2012-06-17 21:50:01 +01:00
{
if ( e . link && e . link == e . event_id )
2010-11-03 14:10:16 +01:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id );
2012-06-17 21:50:01 +01:00
return false ;
2010-11-03 14:10:16 +01:00
}
2012-06-17 21:50:01 +01:00
break ;
}
2010-11-17 23:24:21 +01:00
case SMART_EVENT_DUMMY_EFFECT :
2012-06-17 21:50:01 +01:00
{
2012-03-28 20:00:29 +08:00
if ( ! IsSpellValid ( e , e . event . dummy . spell ))
return false ;
if ( e . event . dummy . effIndex > EFFECT_2 )
return false ;
2010-11-17 23:24:21 +01:00
break ;
2012-06-17 21:50:01 +01:00
}
2011-04-14 00:30:32 -03:00
case SMART_EVENT_IS_BEHIND_TARGET :
2012-06-17 21:50:01 +01:00
{
2011-04-14 00:30:32 -03:00
if ( ! IsMinMaxValid ( e , e . event . behindTarget . cooldownMin , e . event . behindTarget . cooldownMax ))
return false ;
break ;
2012-06-17 21:50:01 +01:00
}
2011-12-11 16:22:18 +01:00
case SMART_EVENT_GAME_EVENT_START :
case SMART_EVENT_GAME_EVENT_END :
2012-06-17 21:50:01 +01:00
{
GameEventMgr :: GameEventDataMap const & events = sGameEventMgr -> GetEventMap ();
if ( e . event . gameEvent . gameEventId >= events . size () || ! events [ e . event . gameEvent . gameEventId ]. isValid ())
return false ;
break ;
}
case SMART_EVENT_ACTION_DONE :
{
2012-06-19 00:07:20 +02:00
if ( e . event . doAction . eventId > EVENT_CHARGE )
2011-12-11 16:22:18 +01:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid event id %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . event . doAction . eventId );
2012-06-17 21:50:01 +01:00
return false ;
2011-12-11 16:22:18 +01:00
}
2012-06-17 21:50:01 +01:00
break ;
}
2012-01-06 11:09:01 -05:00
case SMART_EVENT_GO_STATE_CHANGED :
2012-06-11 11:10:46 +02:00
case SMART_EVENT_GO_EVENT_INFORM :
2010-11-03 14:10:16 +01:00
case SMART_EVENT_TIMED_EVENT_TRIGGERED :
case SMART_EVENT_INSTANCE_PLAYER_ENTER :
case SMART_EVENT_TRANSPORT_RELOCATE :
case SMART_EVENT_CHARMED :
case SMART_EVENT_CHARMED_TARGET :
case SMART_EVENT_CORPSE_REMOVED :
case SMART_EVENT_AI_INIT :
case SMART_EVENT_TRANSPORT_ADDPLAYER :
case SMART_EVENT_TRANSPORT_REMOVE_PLAYER :
case SMART_EVENT_AGGRO :
case SMART_EVENT_DEATH :
case SMART_EVENT_EVADE :
case SMART_EVENT_REACHED_HOME :
case SMART_EVENT_RESET :
case SMART_EVENT_QUEST_ACCEPTED :
case SMART_EVENT_QUEST_OBJ_COPLETETION :
case SMART_EVENT_QUEST_COMPLETION :
case SMART_EVENT_QUEST_REWARDED :
case SMART_EVENT_QUEST_FAIL :
case SMART_EVENT_JUST_SUMMONED :
case SMART_EVENT_WAYPOINT_START :
case SMART_EVENT_WAYPOINT_REACHED :
case SMART_EVENT_WAYPOINT_PAUSED :
case SMART_EVENT_WAYPOINT_RESUMED :
case SMART_EVENT_WAYPOINT_STOPPED :
case SMART_EVENT_WAYPOINT_ENDED :
case SMART_EVENT_GOSSIP_SELECT :
case SMART_EVENT_GOSSIP_HELLO :
case SMART_EVENT_JUST_CREATED :
2010-11-17 23:24:21 +01:00
case SMART_EVENT_FOLLOW_COMPLETED :
2012-06-19 00:07:20 +02:00
case SMART_EVENT_ON_SPELLCLICK :
2010-11-03 14:10:16 +01:00
break ;
2010-12-13 22:37:56 +01:00
default :
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Not handled event_type(%u), Entry %d SourceType %u Event %u Action %u, skipped." , e . GetEventType (), e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType ());
2010-11-03 14:10:16 +01:00
return false ;
}
2010-10-27 21:01:47 +02:00
}
2010-11-03 14:10:16 +01:00
2010-10-27 21:01:47 +02:00
switch ( e . GetActionType ())
{
case SMART_ACTION_SET_FACTION :
2011-08-26 05:15:38 +01:00
if ( e . action . faction . factionID && ! sFactionTemplateStore . LookupEntry ( e . action . faction . factionID ))
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Faction %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . faction . factionID );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
case SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL :
case SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL :
if ( e . action . morphOrMount . creature || e . action . morphOrMount . model )
{
2011-04-28 22:57:08 +02:00
if ( e . action . morphOrMount . creature > 0 && ! sObjectMgr -> GetCreatureTemplate ( e . action . morphOrMount . creature ))
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Creature entry %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . morphOrMount . creature );
2010-10-27 21:01:47 +02:00
return false ;
}
if ( e . action . morphOrMount . model )
{
if ( e . action . morphOrMount . creature )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has ModelID set with also set CreatureId, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType ());
2010-10-27 21:01:47 +02:00
return false ;
}
else if ( ! sCreatureDisplayInfoStore . LookupEntry ( e . action . morphOrMount . model ))
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Model id %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . morphOrMount . model );
2010-10-27 21:01:47 +02:00
return false ;
}
}
}
break ;
case SMART_ACTION_SOUND :
2011-10-24 23:21:34 +01:00
if ( ! IsSoundValid ( e , e . action . sound . sound ))
return false ;
2010-10-27 21:01:47 +02:00
if ( e . action . sound . range > TEXT_RANGE_WORLD )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Text Range %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . sound . range );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
case SMART_ACTION_SET_EMOTE_STATE :
case SMART_ACTION_PLAY_EMOTE :
2012-03-28 20:00:29 +08:00
if ( ! IsEmoteValid ( e , e . action . emote . emote ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_FAIL_QUEST :
case SMART_ACTION_ADD_QUEST :
2012-03-28 20:00:29 +08:00
if ( ! e . action . quest . quest || ! IsQuestValid ( e , e . action . quest . quest ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
2010-11-19 20:23:08 +01:00
case SMART_ACTION_ACTIVATE_TAXI :
{
if ( ! sTaxiPathStore . LookupEntry ( e . action . taxi . id ))
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Taxi path ID %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . taxi . id );
2010-11-19 20:23:08 +01:00
return false ;
}
break ;
}
2010-10-27 21:01:47 +02:00
case SMART_ACTION_RANDOM_EMOTE :
2012-03-28 20:00:29 +08:00
if ( e . action . randomEmote . emote1 && ! IsEmoteValid ( e , e . action . randomEmote . emote1 ))
return false ;
if ( e . action . randomEmote . emote2 && ! IsEmoteValid ( e , e . action . randomEmote . emote2 ))
return false ;
if ( e . action . randomEmote . emote3 && ! IsEmoteValid ( e , e . action . randomEmote . emote3 ))
return false ;
if ( e . action . randomEmote . emote4 && ! IsEmoteValid ( e , e . action . randomEmote . emote4 ))
return false ;
if ( e . action . randomEmote . emote5 && ! IsEmoteValid ( e , e . action . randomEmote . emote5 ))
return false ;
if ( e . action . randomEmote . emote6 && ! IsEmoteValid ( e , e . action . randomEmote . emote6 ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_ADD_AURA :
case SMART_ACTION_CAST :
2010-11-06 23:18:04 +01:00
case SMART_ACTION_INVOKER_CAST :
2012-03-28 20:00:29 +08:00
if ( ! IsSpellValid ( e , e . action . cast . spell ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS :
case SMART_ACTION_CALL_GROUPEVENTHAPPENS :
2010-12-22 21:25:23 +01:00
if ( Quest const * qid = sObjectMgr -> GetQuestTemplate ( e . action . quest . quest ))
2010-10-27 21:01:47 +02:00
{
if ( ! qid -> HasFlag ( QUEST_TRINITY_FLAGS_EXPLORATION_OR_EVENT ))
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u SpecialFlags for Quest entry %u does not include FLAGS_EXPLORATION_OR_EVENT(2), skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . quest . quest );
2010-10-27 21:01:47 +02:00
return false ;
}
}
else
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Quest entry %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . quest . quest );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
case SMART_ACTION_SEND_CASTCREATUREORGO :
2012-03-28 20:00:29 +08:00
if ( ! IsQuestValid ( e , e . action . castCreatureOrGO . quest ))
return false ;
if ( ! IsSpellValid ( e , e . action . castCreatureOrGO . spell ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_SET_EVENT_PHASE :
if ( e . action . setEventPhase . phase >= SMART_EVENT_PHASE_MAX )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u attempts to set phase %u. Phase mask cannot be used past phase %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . setEventPhase . phase , SMART_EVENT_PHASE_MAX - 1 );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
case SMART_ACTION_INC_EVENT_PHASE :
if ( ! e . action . incEventPhase . inc && ! e . action . incEventPhase . dec )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u is incrementing phase by 0, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType ());
2010-10-27 21:01:47 +02:00
return false ;
}
else if ( e . action . incEventPhase . inc > SMART_EVENT_PHASE_MAX || e . action . incEventPhase . dec > SMART_EVENT_PHASE_MAX )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u attempts to increment phase by too large value, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType ());
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
case SMART_ACTION_CALL_CASTEDCREATUREORGO :
2012-03-28 20:00:29 +08:00
if ( ! IsCreatureValid ( e , e . action . castedCreatureOrGO . creature ))
return false ;
if ( ! IsSpellValid ( e , e . action . castedCreatureOrGO . spell ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_REMOVEAURASFROMSPELL :
2012-06-02 14:28:24 +01:00
if ( e . action . removeAura . spell != 0 && ! IsSpellValid ( e , e . action . removeAura . spell ))
2012-03-28 20:00:29 +08:00
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_RANDOM_PHASE :
{
if ( e . action . randomPhase . phase1 >= SMART_EVENT_PHASE_MAX ||
e . action . randomPhase . phase2 >= SMART_EVENT_PHASE_MAX ||
e . action . randomPhase . phase3 >= SMART_EVENT_PHASE_MAX ||
e . action . randomPhase . phase4 >= SMART_EVENT_PHASE_MAX ||
e . action . randomPhase . phase5 >= SMART_EVENT_PHASE_MAX ||
e . action . randomPhase . phase6 >= SMART_EVENT_PHASE_MAX )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u attempts to set invalid phase, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType ());
2010-10-27 21:01:47 +02:00
return false ;
}
}
break ;
case SMART_ACTION_RANDOM_PHASE_RANGE : //PhaseMin, PhaseMax
{
if ( e . action . randomPhaseRange . phaseMin >= SMART_EVENT_PHASE_MAX ||
e . action . randomPhaseRange . phaseMax >= SMART_EVENT_PHASE_MAX )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u attempts to set invalid phase, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType ());
2010-10-27 21:01:47 +02:00
return false ;
}
2012-03-28 20:00:29 +08:00
if ( ! IsMinMaxValid ( e , e . action . randomPhaseRange . phaseMin , e . action . randomPhaseRange . phaseMax ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
}
case SMART_ACTION_SUMMON_CREATURE :
2012-03-28 20:00:29 +08:00
if ( ! IsCreatureValid ( e , e . action . summonCreature . creature ))
return false ;
2011-09-19 14:41:21 +02:00
if ( e . action . summonCreature . type < TEMPSUMMON_TIMED_OR_DEAD_DESPAWN || e . action . summonCreature . type > TEMPSUMMON_MANUAL_DESPAWN )
2010-10-27 21:01:47 +02:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses incorrect TempSummonType %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . summonCreature . type );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
case SMART_ACTION_CALL_KILLEDMONSTER :
2012-03-28 20:00:29 +08:00
if ( ! IsCreatureValid ( e , e . action . killedMonster . creature ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_UPDATE_TEMPLATE :
2012-03-28 20:00:29 +08:00
if ( e . action . updateTemplate . creature && ! IsCreatureValid ( e , e . action . updateTemplate . creature ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_SET_SHEATH :
if ( e . action . setSheath . sheath && e . action . setSheath . sheath >= MAX_SHEATH_STATE )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses incorrect Sheath state %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . setSheath . sheath );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
case SMART_ACTION_SET_REACT_STATE :
{
if ( e . action . react . state > REACT_AGGRESSIVE )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Creature %d Event %u Action %u uses invalid React State %u, skipped." , e . entryOrGuid , e . event_id , e . GetActionType (), e . action . react . state );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
}
case SMART_ACTION_SUMMON_GO :
2012-03-28 20:00:29 +08:00
if ( ! IsGameObjectValid ( e , e . action . summonGO . entry ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_ADD_ITEM :
case SMART_ACTION_REMOVE_ITEM :
2012-03-28 20:00:29 +08:00
if ( ! IsItemValid ( e , e . action . item . entry ))
return false ;
if ( ! NotNULL ( e , e . action . item . count ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_TELEPORT :
if ( ! sMapStore . LookupEntry ( e . action . teleport . mapID ))
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Map entry %u, skipped." , e . entryOrGuid , e . GetScriptType (), e . event_id , e . GetActionType (), e . action . teleport . mapID );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
case SMART_ACTION_INSTALL_AI_TEMPLATE :
if ( e . action . installTtemplate . id >= SMARTAI_TEMPLATE_END )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Creature %d Event %u Action %u uses non-existent AI template id %u, skipped." , e . entryOrGuid , e . event_id , e . GetActionType (), e . action . installTtemplate . id );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
case SMART_ACTION_WP_STOP :
2012-03-28 20:00:29 +08:00
if ( e . action . wpStop . quest && ! IsQuestValid ( e , e . action . wpStop . quest ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
case SMART_ACTION_WP_START :
{
2010-12-22 21:25:23 +01:00
if ( ! sSmartWaypointMgr -> GetPath ( e . action . wpStart . pathID ))
2010-11-16 00:13:47 +01:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Creature %d Event %u Action %u uses non-existent WaypointPath id %u, skipped." , e . entryOrGuid , e . event_id , e . GetActionType (), e . action . wpStart . pathID );
2010-11-16 00:13:47 +01:00
return false ;
}
2012-03-28 20:00:29 +08:00
if ( e . action . wpStart . quest && ! IsQuestValid ( e , e . action . wpStart . quest ))
return false ;
2010-10-27 21:01:47 +02:00
if ( e . action . wpStart . reactState > REACT_AGGRESSIVE )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Creature %d Event %u Action %u uses invalid React State %u, skipped." , e . entryOrGuid , e . event_id , e . GetActionType (), e . action . wpStart . reactState );
2010-10-27 21:01:47 +02:00
return false ;
}
break ;
}
case SMART_ACTION_CREATE_TIMED_EVENT :
{
2012-03-28 20:00:29 +08:00
if ( ! IsMinMaxValid ( e , e . action . timeEvent . min , e . action . timeEvent . max ))
return false ;
if ( ! IsMinMaxValid ( e , e . action . timeEvent . repeatMin , e . action . timeEvent . repeatMax ))
return false ;
2010-10-27 21:01:47 +02:00
break ;
}
case SMART_ACTION_FOLLOW :
case SMART_ACTION_SET_ORIENTATION :
case SMART_ACTION_STORE_TARGET_LIST :
case SMART_ACTION_EVADE :
case SMART_ACTION_FLEE_FOR_ASSIST :
case SMART_ACTION_DIE :
case SMART_ACTION_SET_IN_COMBAT_WITH_ZONE :
case SMART_ACTION_SET_ACTIVE :
case SMART_ACTION_STORE_VARIABLE_DECIMAL :
case SMART_ACTION_WP_RESUME :
case SMART_ACTION_KILL_UNIT :
case SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL :
case SMART_ACTION_RESET_GOBJECT :
case SMART_ACTION_ATTACK_START :
case SMART_ACTION_THREAT_ALL_PCT :
case SMART_ACTION_THREAT_SINGLE_PCT :
case SMART_ACTION_SET_INST_DATA :
case SMART_ACTION_SET_INST_DATA64 :
case SMART_ACTION_AUTO_ATTACK :
case SMART_ACTION_ALLOW_COMBAT_MOVEMENT :
case SMART_ACTION_CALL_FOR_HELP :
case SMART_ACTION_SET_DATA :
case SMART_ACTION_MOVE_FORWARD :
case SMART_ACTION_SET_VISIBILITY :
case SMART_ACTION_WP_PAUSE :
case SMART_ACTION_SET_FLY :
case SMART_ACTION_SET_RUN :
2011-08-21 00:07:38 -03:00
case SMART_ACTION_SET_SWIM :
2010-10-27 21:01:47 +02:00
case SMART_ACTION_FORCE_DESPAWN :
case SMART_ACTION_SET_INGAME_PHASE_MASK :
case SMART_ACTION_SET_UNIT_FLAG :
case SMART_ACTION_REMOVE_UNIT_FLAG :
case SMART_ACTION_PLAYMOVIE :
case SMART_ACTION_MOVE_TO_POS :
case SMART_ACTION_RESPAWN_TARGET :
case SMART_ACTION_CLOSE_GOSSIP :
case SMART_ACTION_EQUIP :
case SMART_ACTION_TRIGGER_TIMED_EVENT :
case SMART_ACTION_REMOVE_TIMED_EVENT :
case SMART_ACTION_OVERRIDE_SCRIPT_BASE_OBJECT :
case SMART_ACTION_RESET_SCRIPT_BASE_OBJECT :
case SMART_ACTION_ACTIVATE_GOBJECT :
case SMART_ACTION_CALL_SCRIPT_RESET :
case SMART_ACTION_NONE :
2010-11-03 14:10:16 +01:00
case SMART_ACTION_CALL_TIMED_ACTIONLIST :
case SMART_ACTION_SET_NPC_FLAG :
case SMART_ACTION_ADD_NPC_FLAG :
case SMART_ACTION_REMOVE_NPC_FLAG :
2010-11-05 19:38:43 +01:00
case SMART_ACTION_TALK :
case SMART_ACTION_SIMPLE_TALK :
2010-11-07 18:34:04 +01:00
case SMART_ACTION_CROSS_CAST :
2010-11-07 22:10:11 +01:00
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST :
case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST :
2010-11-20 13:23:29 +01:00
case SMART_ACTION_RANDOM_MOVE :
2011-02-07 09:35:14 -07:00
case SMART_ACTION_SET_UNIT_FIELD_BYTES_1 :
2011-02-07 10:15:54 -07:00
case SMART_ACTION_REMOVE_UNIT_FIELD_BYTES_1 :
2011-02-15 00:29:33 -03:00
case SMART_ACTION_INTERRUPT_SPELL :
2011-03-02 16:50:09 +01:00
case SMART_ACTION_SEND_GO_CUSTOM_ANIM :
2011-06-12 17:50:23 +02:00
case SMART_ACTION_SET_DYNAMIC_FLAG :
case SMART_ACTION_ADD_DYNAMIC_FLAG :
case SMART_ACTION_REMOVE_DYNAMIC_FLAG :
2011-07-02 07:52:03 +02:00
case SMART_ACTION_JUMP_TO_POS :
2011-10-23 12:55:17 +01:00
case SMART_ACTION_SEND_GOSSIP_MENU :
2012-01-22 10:02:31 -05:00
case SMART_ACTION_GO_SET_LOOT_STATE :
case SMART_ACTION_SEND_TARGET_TO_TARGET :
2012-09-08 00:55:47 +01:00
case SMART_ACTION_SET_HOME_POS :
2012-09-17 13:56:12 -04:00
case SMART_ACTION_SET_HEALTH_REGEN :
2012-12-29 15:35:56 -05:00
case SMART_ACTION_SET_RANGED_MOVEMENT :
2010-10-27 21:01:47 +02:00
break ;
default :
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_SQL , "SmartAIMgr: Not handled action_type(%u), event_type(%u), Entry %d SourceType %u Event %u, skipped." , e . GetActionType (), e . GetEventType (), e . entryOrGuid , e . GetScriptType (), e . event_id );
2010-10-27 21:01:47 +02:00
return false ;
}
return true ;
}
2012-08-30 22:44:33 +01:00
/*bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused
2010-10-27 21:01:47 +02:00
{
bool error = false;
uint32 entry = 0;
if (e.entryOrGuid >= 0)
entry = uint32(e.entryOrGuid);
else {
entry = uint32(abs(e.entryOrGuid));
2010-12-22 21:25:23 +01:00
CreatureData const* data = sObjectMgr->GetCreatureData(entry);
2010-10-27 21:01:47 +02:00
if (!data)
{
2012-08-03 14:20:18 +02:00
sLog->outError(LOG_FILTER_SQL, "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
2010-10-27 21:01:47 +02:00
return false;
}
else
entry = data->id;
}
2010-12-22 21:25:23 +01:00
if (!entry || !sCreatureTextMgr->TextExist(entry, uint8(id)))
2010-10-27 21:01:47 +02:00
error = true;
if (error)
{
2012-08-03 14:20:18 +02:00
sLog->outError(LOG_FILTER_SQL, "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.source_type, e.GetActionType(), id);
2010-10-27 21:01:47 +02:00
return false;
}
return true;
2012-08-30 22:44:33 +01:00
}*/