2010-10-07 15:35:36 +02:00
/*
2012-12-31 23:15:50 +01:00
* Copyright (C) 2008-2013 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-09-22 18:13:57 +06:00
*/
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "GossipDef.h"
2012-11-20 12:30:30 +01:00
#include "Map.h"
2010-09-22 18:13:57 +06:00
#include "MapManager.h"
#include "MapRefManager.h"
2012-11-20 12:30:30 +01:00
#include "ObjectMgr.h"
#include "Pet.h"
#include "ScriptedCreature.h"
2011-04-13 12:07:20 +06:00
#include "ScriptMgr.h"
2012-11-20 12:30:30 +01:00
#include "Transport.h"
#include "WaypointManager.h"
#include "World.h"
2010-09-22 18:13:57 +06:00
/// Put scripts in the execution queue
void Map :: ScriptsStart ( ScriptMapMap const & scripts , uint32 id , Object * source , Object * target )
{
///- Find the script map
ScriptMapMap :: const_iterator s = scripts . find ( id );
if ( s == scripts . end ())
return ;
// prepare static data
2012-02-23 13:01:16 +01:00
uint64 sourceGUID = source ? source -> GetGUID () : uint64 ( 0 ); //some script commands doesn't have source
uint64 targetGUID = target ? target -> GetGUID () : uint64 ( 0 );
uint64 ownerGUID = ( source && source -> GetTypeId () == TYPEID_ITEM ) ? (( Item * ) source ) -> GetOwnerGUID () : uint64 ( 0 );
2010-09-22 18:13:57 +06:00
///- Schedule script execution for all scripts in the script map
2011-09-15 14:08:17 +02:00
ScriptMap const * s2 = & ( s -> second );
2010-09-22 18:13:57 +06:00
bool immedScript = false ;
for ( ScriptMap :: const_iterator iter = s2 -> begin (); iter != s2 -> end (); ++ iter )
{
ScriptAction sa ;
sa . sourceGUID = sourceGUID ;
sa . targetGUID = targetGUID ;
sa . ownerGUID = ownerGUID ;
sa . script = & iter -> second ;
2011-04-13 12:07:20 +06:00
m_scriptSchedule . insert ( ScriptScheduleMap :: value_type ( time_t ( sWorld -> GetGameTime () + iter -> first ), sa ));
2010-09-22 18:13:57 +06:00
if ( iter -> first == 0 )
immedScript = true ;
2011-04-13 12:07:20 +06:00
sScriptMgr -> IncreaseScheduledScriptsCount ();
2010-09-22 18:13:57 +06:00
}
///- If one of the effects should be immediate, launch the script execution
if ( /*start &&*/ immedScript && ! i_scriptLock )
{
i_scriptLock = true ;
ScriptsProcess ();
i_scriptLock = false ;
}
}
void Map :: ScriptCommandStart ( ScriptInfo const & script , uint32 delay , Object * source , Object * target )
{
// NOTE: script record _must_ exist until command executed
// prepare static data
2012-02-23 13:01:16 +01:00
uint64 sourceGUID = source ? source -> GetGUID () : uint64 ( 0 );
uint64 targetGUID = target ? target -> GetGUID () : uint64 ( 0 );
uint64 ownerGUID = ( source && source -> GetTypeId () == TYPEID_ITEM ) ? (( Item * ) source ) -> GetOwnerGUID () : uint64 ( 0 );
2010-09-22 18:13:57 +06:00
ScriptAction sa ;
sa . sourceGUID = sourceGUID ;
sa . targetGUID = targetGUID ;
sa . ownerGUID = ownerGUID ;
sa . script = & script ;
2011-04-13 12:07:20 +06:00
m_scriptSchedule . insert ( ScriptScheduleMap :: value_type ( time_t ( sWorld -> GetGameTime () + delay ), sa ));
2010-09-22 18:13:57 +06:00
2011-04-13 12:07:20 +06:00
sScriptMgr -> IncreaseScheduledScriptsCount ();
2010-09-22 18:13:57 +06:00
///- If effects should be immediate, launch the script execution
if ( delay == 0 && ! i_scriptLock )
{
i_scriptLock = true ;
ScriptsProcess ();
i_scriptLock = false ;
}
}
// Helpers for ScriptProcess method.
inline Player * Map :: _GetScriptPlayerSourceOrTarget ( Object * source , Object * target , const ScriptInfo * scriptInfo ) const
{
2011-10-07 11:08:09 -05:00
Player * player = NULL ;
2010-09-22 18:13:57 +06:00
if ( ! source && ! target )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s source and target objects are NULL." , scriptInfo -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
else
{
// Check target first, then source.
if ( target )
2011-10-07 11:08:09 -05:00
player = target -> ToPlayer ();
if ( ! player && source )
player = source -> ToPlayer ();
2010-09-22 18:13:57 +06:00
2011-10-07 11:08:09 -05:00
if ( ! player )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s neither source nor target object is player (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping." ,
2010-09-22 18:13:57 +06:00
scriptInfo -> GetDebugInfo (). c_str (),
source ? source -> GetTypeId () : 0 , source ? source -> GetEntry () : 0 , source ? source -> GetGUIDLow () : 0 ,
target ? target -> GetTypeId () : 0 , target ? target -> GetEntry () : 0 , target ? target -> GetGUIDLow () : 0 );
}
2011-10-07 11:08:09 -05:00
return player ;
2010-09-22 18:13:57 +06:00
}
inline Creature * Map :: _GetScriptCreatureSourceOrTarget ( Object * source , Object * target , const ScriptInfo * scriptInfo , bool bReverse ) const
{
2011-10-07 11:08:09 -05:00
Creature * creature = NULL ;
2010-09-22 18:13:57 +06:00
if ( ! source && ! target )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s source and target objects are NULL." , scriptInfo -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
else
{
if ( bReverse )
{
// Check target first, then source.
if ( target )
2011-10-07 11:08:09 -05:00
creature = target -> ToCreature ();
if ( ! creature && source )
creature = source -> ToCreature ();
2010-09-22 18:13:57 +06:00
}
else
{
// Check source first, then target.
if ( source )
2011-10-07 11:08:09 -05:00
creature = source -> ToCreature ();
if ( ! creature && target )
creature = target -> ToCreature ();
2010-09-22 18:13:57 +06:00
}
2011-10-07 11:08:09 -05:00
if ( ! creature )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s neither source nor target are creatures (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping." ,
2010-09-22 18:13:57 +06:00
scriptInfo -> GetDebugInfo (). c_str (),
source ? source -> GetTypeId () : 0 , source ? source -> GetEntry () : 0 , source ? source -> GetGUIDLow () : 0 ,
target ? target -> GetTypeId () : 0 , target ? target -> GetEntry () : 0 , target ? target -> GetGUIDLow () : 0 );
}
2011-10-07 11:08:09 -05:00
return creature ;
2010-09-22 18:13:57 +06:00
}
inline Unit * Map :: _GetScriptUnit ( Object * obj , bool isSource , const ScriptInfo * scriptInfo ) const
{
2011-10-07 10:48:56 -05:00
Unit * unit = NULL ;
2010-09-22 18:13:57 +06:00
if ( ! obj )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s %s object is NULL." , scriptInfo -> GetDebugInfo (). c_str (), isSource ? "source" : "target" );
2010-09-22 18:13:57 +06:00
else if ( ! obj -> isType ( TYPEMASK_UNIT ))
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s %s object is not unit (TypeId: %u, Entry: %u, GUID: %u), skipping." ,
2010-09-22 18:13:57 +06:00
scriptInfo -> GetDebugInfo (). c_str (), isSource ? "source" : "target" , obj -> GetTypeId (), obj -> GetEntry (), obj -> GetGUIDLow ());
else
{
2011-10-07 10:48:56 -05:00
unit = obj -> ToUnit ();
if ( ! unit )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s %s object could not be casted to unit." ,
2010-09-22 18:13:57 +06:00
scriptInfo -> GetDebugInfo (). c_str (), isSource ? "source" : "target" );
}
2011-10-07 10:48:56 -05:00
return unit ;
2010-09-22 18:13:57 +06:00
}
inline Player * Map :: _GetScriptPlayer ( Object * obj , bool isSource , const ScriptInfo * scriptInfo ) const
{
2011-10-07 11:08:09 -05:00
Player * player = NULL ;
2010-09-22 18:13:57 +06:00
if ( ! obj )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s %s object is NULL." , scriptInfo -> GetDebugInfo (). c_str (), isSource ? "source" : "target" );
2010-09-22 18:13:57 +06:00
else
{
2011-10-07 11:08:09 -05:00
player = obj -> ToPlayer ();
if ( ! player )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s %s object is not a player (TypeId: %u, Entry: %u, GUID: %u)." ,
2010-09-22 18:13:57 +06:00
scriptInfo -> GetDebugInfo (). c_str (), isSource ? "source" : "target" , obj -> GetTypeId (), obj -> GetEntry (), obj -> GetGUIDLow ());
}
2011-10-07 11:08:09 -05:00
return player ;
2010-09-22 18:13:57 +06:00
}
inline Creature * Map :: _GetScriptCreature ( Object * obj , bool isSource , const ScriptInfo * scriptInfo ) const
{
2011-10-07 11:08:09 -05:00
Creature * creature = NULL ;
2010-09-22 18:13:57 +06:00
if ( ! obj )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s %s object is NULL." , scriptInfo -> GetDebugInfo (). c_str (), isSource ? "source" : "target" );
2010-09-22 18:13:57 +06:00
else
{
2011-10-07 11:08:09 -05:00
creature = obj -> ToCreature ();
if ( ! creature )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s %s object is not a creature (TypeId: %u, Entry: %u, GUID: %u)." , scriptInfo -> GetDebugInfo (). c_str (),
2010-09-22 18:13:57 +06:00
isSource ? "source" : "target" , obj -> GetTypeId (), obj -> GetEntry (), obj -> GetGUIDLow ());
}
2011-10-07 11:08:09 -05:00
return creature ;
2010-09-22 18:13:57 +06:00
}
inline WorldObject * Map :: _GetScriptWorldObject ( Object * obj , bool isSource , const ScriptInfo * scriptInfo ) const
{
WorldObject * pWorldObject = NULL ;
if ( ! obj )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s %s object is NULL." ,
2010-09-22 18:13:57 +06:00
scriptInfo -> GetDebugInfo (). c_str (), isSource ? "source" : "target" );
else
{
pWorldObject = dynamic_cast < WorldObject *> ( obj );
if ( ! pWorldObject )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s %s object is not a world object (TypeId: %u, Entry: %u, GUID: %u)." ,
2010-09-22 18:13:57 +06:00
scriptInfo -> GetDebugInfo (). c_str (), isSource ? "source" : "target" , obj -> GetTypeId (), obj -> GetEntry (), obj -> GetGUIDLow ());
}
return pWorldObject ;
}
inline void Map :: _ScriptProcessDoor ( Object * source , Object * target , const ScriptInfo * scriptInfo ) const
{
bool bOpen = false ;
uint32 guid = scriptInfo -> ToggleDoor . GOGuid ;
int32 nTimeToToggle = std :: max ( 15 , int32 ( scriptInfo -> ToggleDoor . ResetDelay ));
switch ( scriptInfo -> command )
{
case SCRIPT_COMMAND_OPEN_DOOR : bOpen = true ; break ;
case SCRIPT_COMMAND_CLOSE_DOOR : break ;
default :
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s unknown command for _ScriptProcessDoor." , scriptInfo -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
return ;
}
if ( ! guid )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s door guid is not specified." , scriptInfo -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
else if ( ! source )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s source object is NULL." , scriptInfo -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
else if ( ! source -> isType ( TYPEMASK_UNIT ))
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s source object is not unit (TypeId: %u, Entry: %u, GUID: %u), skipping." , scriptInfo -> GetDebugInfo (). c_str (),
2010-09-22 18:13:57 +06:00
source -> GetTypeId (), source -> GetEntry (), source -> GetGUIDLow ());
else
{
WorldObject * wSource = dynamic_cast < WorldObject *> ( source );
if ( ! wSource )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s source object could not be casted to world object (TypeId: %u, Entry: %u, GUID: %u), skipping." ,
2010-09-22 18:13:57 +06:00
scriptInfo -> GetDebugInfo (). c_str (), source -> GetTypeId (), source -> GetEntry (), source -> GetGUIDLow ());
else
{
2011-09-15 14:08:17 +02:00
GameObject * pDoor = _FindGameObject ( wSource , guid );
2010-09-22 18:13:57 +06:00
if ( ! pDoor )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s gameobject was not found (guid: %u)." , scriptInfo -> GetDebugInfo (). c_str (), guid );
2010-09-22 18:13:57 +06:00
else if ( pDoor -> GetGoType () != GAMEOBJECT_TYPE_DOOR )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s gameobject is not a door (GoType: %u, Entry: %u, GUID: %u)." ,
2010-09-22 18:13:57 +06:00
scriptInfo -> GetDebugInfo (). c_str (), pDoor -> GetGoType (), pDoor -> GetEntry (), pDoor -> GetGUIDLow ());
else if ( bOpen == ( pDoor -> GetGoState () == GO_STATE_READY ))
{
pDoor -> UseDoorOrButton ( nTimeToToggle );
if ( target && target -> isType ( TYPEMASK_GAMEOBJECT ))
{
2011-07-08 11:12:19 +02:00
GameObject * goTarget = target -> ToGameObject ();
2010-09-22 18:13:57 +06:00
if ( goTarget && goTarget -> GetGoType () == GAMEOBJECT_TYPE_BUTTON )
goTarget -> UseDoorOrButton ( nTimeToToggle );
}
}
}
}
}
2011-10-19 17:40:44 +01:00
inline GameObject * Map :: _FindGameObject ( WorldObject * searchObject , uint32 guid ) const
2010-09-22 18:13:57 +06:00
{
2011-10-19 17:40:44 +01:00
GameObject * gameobject = NULL ;
2010-09-22 18:13:57 +06:00
2011-10-19 17:40:44 +01:00
CellCoord p ( Trinity :: ComputeCellCoord ( searchObject -> GetPositionX (), searchObject -> GetPositionY ()));
2010-09-22 18:13:57 +06:00
Cell cell ( p );
2011-10-19 17:40:44 +01:00
Trinity :: GameObjectWithDbGUIDCheck goCheck ( * searchObject , guid );
Trinity :: GameObjectSearcher < Trinity :: GameObjectWithDbGUIDCheck > checker ( searchObject , gameobject , goCheck );
2010-09-22 18:13:57 +06:00
TypeContainerVisitor < Trinity :: GameObjectSearcher < Trinity :: GameObjectWithDbGUIDCheck > , GridTypeMapContainer > objectChecker ( checker );
2011-10-19 17:40:44 +01:00
cell . Visit ( p , objectChecker , * searchObject -> GetMap (), * searchObject , searchObject -> GetGridActivationRange ());
2010-09-22 18:13:57 +06:00
2011-10-19 17:40:44 +01:00
return gameobject ;
2010-09-22 18:13:57 +06:00
}
/// Process queued scripts
void Map :: ScriptsProcess ()
{
if ( m_scriptSchedule . empty ())
return ;
///- Process overdue queued scripts
2011-04-13 12:07:20 +06:00
ScriptScheduleMap :: iterator iter = m_scriptSchedule . begin ();
2010-09-22 18:13:57 +06:00
// ok as multimap is a *sorted* associative container
2010-12-23 23:25:44 +01:00
while ( ! m_scriptSchedule . empty () && ( iter -> first <= sWorld -> GetGameTime ()))
2010-09-22 18:13:57 +06:00
{
ScriptAction const & step = iter -> second ;
Object * source = NULL ;
if ( step . sourceGUID )
{
switch ( GUID_HIPART ( step . sourceGUID ))
{
2011-01-28 10:52:18 +06:00
case HIGHGUID_ITEM : // as well as HIGHGUID_CONTAINER
if ( Player * player = HashMapHolder < Player >:: Find ( step . ownerGUID ))
2010-09-22 18:13:57 +06:00
source = player -> GetItemByGuid ( step . sourceGUID );
break ;
case HIGHGUID_UNIT :
2011-09-06 10:33:45 +02:00
case HIGHGUID_VEHICLE :
2010-09-22 18:13:57 +06:00
source = HashMapHolder < Creature >:: Find ( step . sourceGUID );
break ;
case HIGHGUID_PET :
source = HashMapHolder < Pet >:: Find ( step . sourceGUID );
break ;
case HIGHGUID_PLAYER :
source = HashMapHolder < Player >:: Find ( step . sourceGUID );
break ;
case HIGHGUID_GAMEOBJECT :
source = HashMapHolder < GameObject >:: Find ( step . sourceGUID );
break ;
case HIGHGUID_CORPSE :
source = HashMapHolder < Corpse >:: Find ( step . sourceGUID );
break ;
case HIGHGUID_MO_TRANSPORT :
2011-11-23 19:17:33 +01:00
for ( MapManager :: TransportSet :: iterator itr2 = sMapMgr -> m_Transports . begin (); itr2 != sMapMgr -> m_Transports . end (); ++ itr2 )
2010-09-22 18:13:57 +06:00
{
2011-11-23 19:17:33 +01:00
if (( * itr2 ) -> GetGUID () == step . sourceGUID )
2010-09-22 18:13:57 +06:00
{
2011-11-23 19:17:33 +01:00
source = * itr2 ;
2010-09-22 18:13:57 +06:00
break ;
}
}
break ;
default :
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s source with unsupported high guid (GUID: " UI64FMTD ", high guid: %u)." ,
2011-01-28 10:52:18 +06:00
step . script -> GetDebugInfo (). c_str (), step . sourceGUID , GUID_HIPART ( step . sourceGUID ));
2010-09-22 18:13:57 +06:00
break ;
}
}
Object * target = NULL ;
if ( step . targetGUID )
{
switch ( GUID_HIPART ( step . targetGUID ))
{
case HIGHGUID_UNIT :
2011-06-28 21:43:06 +02:00
case HIGHGUID_VEHICLE :
2010-09-22 18:13:57 +06:00
target = HashMapHolder < Creature >:: Find ( step . targetGUID );
break ;
case HIGHGUID_PET :
target = HashMapHolder < Pet >:: Find ( step . targetGUID );
break ;
case HIGHGUID_PLAYER : // empty GUID case also
target = HashMapHolder < Player >:: Find ( step . targetGUID );
break ;
case HIGHGUID_GAMEOBJECT :
target = HashMapHolder < GameObject >:: Find ( step . targetGUID );
break ;
case HIGHGUID_CORPSE :
target = HashMapHolder < Corpse >:: Find ( step . targetGUID );
break ;
default :
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s target with unsupported high guid (GUID: " UI64FMTD ", high guid: %u)." ,
2011-01-28 10:52:18 +06:00
step . script -> GetDebugInfo (). c_str (), step . targetGUID , GUID_HIPART ( step . targetGUID ));
2010-09-22 18:13:57 +06:00
break ;
}
}
2011-09-01 22:38:32 +03:00
2010-09-22 18:13:57 +06:00
switch ( step . script -> command )
{
case SCRIPT_COMMAND_TALK :
if ( step . script -> Talk . ChatType > CHAT_TYPE_WHISPER && step . script -> Talk . ChatType != CHAT_MSG_RAID_BOSS_WHISPER )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s invalid chat type (%u) specified, skipping." , step . script -> GetDebugInfo (). c_str (), step . script -> Talk . ChatType );
2010-09-22 18:13:57 +06:00
break ;
}
if ( step . script -> Talk . Flags & SF_TALK_USE_PLAYER )
{
2012-03-07 14:08:30 +01:00
if ( Player * player = _GetScriptPlayerSourceOrTarget ( source , target , step . script ))
2010-09-22 18:13:57 +06:00
{
2012-03-07 14:08:30 +01:00
LocaleConstant loc_idx = player -> GetSession () -> GetSessionDbLocaleIndex ();
2010-12-22 21:25:23 +01:00
std :: string text ( sObjectMgr -> GetTrinityString ( step . script -> Talk . TextID , loc_idx ));
2010-09-22 18:13:57 +06:00
switch ( step . script -> Talk . ChatType )
{
case CHAT_TYPE_SAY :
2012-03-07 14:08:30 +01:00
player -> Say ( text , LANG_UNIVERSAL );
2010-09-22 18:13:57 +06:00
break ;
case CHAT_TYPE_YELL :
2012-03-07 14:08:30 +01:00
player -> Yell ( text , LANG_UNIVERSAL );
2010-09-22 18:13:57 +06:00
break ;
case CHAT_TYPE_TEXT_EMOTE :
case CHAT_TYPE_BOSS_EMOTE :
2012-03-07 14:08:30 +01:00
player -> TextEmote ( text );
2010-09-22 18:13:57 +06:00
break ;
case CHAT_TYPE_WHISPER :
case CHAT_MSG_RAID_BOSS_WHISPER :
2011-01-28 10:52:18 +06:00
{
uint64 targetGUID = target ? target -> GetGUID () : 0 ;
2010-09-22 18:13:57 +06:00
if ( ! targetGUID || ! IS_PLAYER_GUID ( targetGUID ))
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s attempt to whisper to non-player unit, skipping." , step . script -> GetDebugInfo (). c_str ());
2011-01-28 10:52:18 +06:00
else
2012-03-07 14:08:30 +01:00
player -> Whisper ( text , LANG_UNIVERSAL , targetGUID );
2010-09-22 18:13:57 +06:00
break ;
2011-01-28 10:52:18 +06:00
}
2010-09-22 18:13:57 +06:00
default :
break ; // must be already checked at load
}
}
}
else
{
// Source or target must be Creature.
2011-09-15 14:08:17 +02:00
if ( Creature * cSource = _GetScriptCreatureSourceOrTarget ( source , target , step . script ))
2010-09-22 18:13:57 +06:00
{
uint64 targetGUID = target ? target -> GetGUID () : 0 ;
switch ( step . script -> Talk . ChatType )
{
case CHAT_TYPE_SAY :
cSource -> Say ( step . script -> Talk . TextID , LANG_UNIVERSAL , targetGUID );
break ;
case CHAT_TYPE_YELL :
cSource -> Yell ( step . script -> Talk . TextID , LANG_UNIVERSAL , targetGUID );
break ;
case CHAT_TYPE_TEXT_EMOTE :
cSource -> TextEmote ( step . script -> Talk . TextID , targetGUID );
break ;
case CHAT_TYPE_BOSS_EMOTE :
cSource -> MonsterTextEmote ( step . script -> Talk . TextID , targetGUID , true );
break ;
case CHAT_TYPE_WHISPER :
if ( ! targetGUID || ! IS_PLAYER_GUID ( targetGUID ))
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s attempt to whisper to non-player unit, skipping." , step . script -> GetDebugInfo (). c_str ());
2011-01-28 10:52:18 +06:00
else
cSource -> Whisper ( step . script -> Talk . TextID , targetGUID );
2010-09-22 18:13:57 +06:00
break ;
2011-01-28 10:52:18 +06:00
case CHAT_MSG_RAID_BOSS_WHISPER :
2010-09-22 18:13:57 +06:00
if ( ! targetGUID || ! IS_PLAYER_GUID ( targetGUID ))
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s attempt to raidbosswhisper to non-player unit, skipping." , step . script -> GetDebugInfo (). c_str ());
2011-01-28 10:52:18 +06:00
else
cSource -> MonsterWhisper ( step . script -> Talk . TextID , targetGUID , true );
2010-09-22 18:13:57 +06:00
break ;
default :
break ; // must be already checked at load
}
}
}
break ;
case SCRIPT_COMMAND_EMOTE :
// Source or target must be Creature.
2011-09-15 14:08:17 +02:00
if ( Creature * cSource = _GetScriptCreatureSourceOrTarget ( source , target , step . script ))
2010-09-22 18:13:57 +06:00
{
if ( step . script -> Emote . Flags & SF_EMOTE_USE_STATE )
cSource -> SetUInt32Value ( UNIT_NPC_EMOTESTATE , step . script -> Emote . EmoteID );
else
cSource -> HandleEmoteCommand ( step . script -> Emote . EmoteID );
}
break ;
case SCRIPT_COMMAND_FIELD_SET :
// Source or target must be Creature.
2011-09-15 14:08:17 +02:00
if ( Creature * cSource = _GetScriptCreatureSourceOrTarget ( source , target , step . script ))
2010-09-22 18:13:57 +06:00
{
// Validate field number.
if ( step . script -> FieldSet . FieldID <= OBJECT_FIELD_ENTRY || step . script -> FieldSet . FieldID >= cSource -> GetValuesCount ())
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping." ,
2010-09-22 18:13:57 +06:00
step . script -> GetDebugInfo (). c_str (), step . script -> FieldSet . FieldID ,
cSource -> GetValuesCount (), cSource -> GetTypeId (), cSource -> GetEntry (), cSource -> GetGUIDLow ());
else
cSource -> SetUInt32Value ( step . script -> FieldSet . FieldID , step . script -> FieldSet . FieldValue );
}
break ;
case SCRIPT_COMMAND_MOVE_TO :
// Source or target must be Creature.
2011-09-15 14:08:17 +02:00
if ( Creature * cSource = _GetScriptCreatureSourceOrTarget ( source , target , step . script ))
2010-09-22 18:13:57 +06:00
{
2013-01-14 09:50:59 +01:00
Unit * unit = ( Unit * ) cSource ;
2012-01-14 15:34:41 +01:00
if ( step . script -> MoveTo . TravelTime != 0 )
{
float speed = unit -> GetDistance ( step . script -> MoveTo . DestX , step . script -> MoveTo . DestY , step . script -> MoveTo . DestZ ) / (( float ) step . script -> MoveTo . TravelTime * 0.001f );
unit -> MonsterMoveWithSpeed ( step . script -> MoveTo . DestX , step . script -> MoveTo . DestY , step . script -> MoveTo . DestZ , speed );
}
else
unit -> NearTeleportTo ( step . script -> MoveTo . DestX , step . script -> MoveTo . DestY , step . script -> MoveTo . DestZ , unit -> GetOrientation ());
2010-09-22 18:13:57 +06:00
}
break ;
case SCRIPT_COMMAND_FLAG_SET :
// Source or target must be Creature.
2011-09-15 14:08:17 +02:00
if ( Creature * cSource = _GetScriptCreatureSourceOrTarget ( source , target , step . script ))
2010-09-22 18:13:57 +06:00
{
// Validate field number.
if ( step . script -> FlagToggle . FieldID <= OBJECT_FIELD_ENTRY || step . script -> FlagToggle . FieldID >= cSource -> GetValuesCount ())
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping." ,
2010-09-22 18:13:57 +06:00
step . script -> GetDebugInfo (). c_str (), step . script -> FlagToggle . FieldID ,
source -> GetValuesCount (), source -> GetTypeId (), source -> GetEntry (), source -> GetGUIDLow ());
else
cSource -> SetFlag ( step . script -> FlagToggle . FieldID , step . script -> FlagToggle . FieldValue );
}
break ;
case SCRIPT_COMMAND_FLAG_REMOVE :
// Source or target must be Creature.
2011-09-15 14:08:17 +02:00
if ( Creature * cSource = _GetScriptCreatureSourceOrTarget ( source , target , step . script ))
2010-09-22 18:13:57 +06:00
{
// Validate field number.
if ( step . script -> FlagToggle . FieldID <= OBJECT_FIELD_ENTRY || step . script -> FlagToggle . FieldID >= cSource -> GetValuesCount ())
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping." ,
2010-09-22 18:13:57 +06:00
step . script -> GetDebugInfo (). c_str (), step . script -> FlagToggle . FieldID ,
source -> GetValuesCount (), source -> GetTypeId (), source -> GetEntry (), source -> GetGUIDLow ());
else
cSource -> RemoveFlag ( step . script -> FlagToggle . FieldID , step . script -> FlagToggle . FieldValue );
}
break ;
case SCRIPT_COMMAND_TELEPORT_TO :
2011-06-12 02:30:32 +02:00
if ( step . script -> TeleportTo . Flags & SF_TELEPORT_USE_CREATURE )
2010-09-22 18:13:57 +06:00
{
// Source or target must be Creature.
2011-09-15 14:08:17 +02:00
if ( Creature * cSource = _GetScriptCreatureSourceOrTarget ( source , target , step . script , true ))
2010-09-22 18:13:57 +06:00
cSource -> NearTeleportTo ( step . script -> TeleportTo . DestX , step . script -> TeleportTo . DestY , step . script -> TeleportTo . DestZ , step . script -> TeleportTo . Orientation );
}
else
{
// Source or target must be Player.
2012-03-07 14:08:30 +01:00
if ( Player * player = _GetScriptPlayerSourceOrTarget ( source , target , step . script ))
player -> TeleportTo ( step . script -> TeleportTo . MapID , step . script -> TeleportTo . DestX , step . script -> TeleportTo . DestY , step . script -> TeleportTo . DestZ , step . script -> TeleportTo . Orientation );
2010-09-22 18:13:57 +06:00
}
break ;
case SCRIPT_COMMAND_QUEST_EXPLORED :
{
if ( ! source )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s source object is NULL." , step . script -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
break ;
}
if ( ! target )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s target object is NULL." , step . script -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
break ;
}
// when script called for item spell casting then target == (unit or GO) and source is player
WorldObject * worldObject ;
2012-03-07 14:08:30 +01:00
Player * player = target -> ToPlayer ();
if ( player )
2010-09-22 18:13:57 +06:00
{
if ( source -> GetTypeId () != TYPEID_UNIT && source -> GetTypeId () != TYPEID_GAMEOBJECT && source -> GetTypeId () != TYPEID_PLAYER )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s source is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping." ,
2010-09-22 18:13:57 +06:00
step . script -> GetDebugInfo (). c_str (), source -> GetTypeId (), source -> GetEntry (), source -> GetGUIDLow ());
break ;
}
worldObject = dynamic_cast < WorldObject *> ( source );
}
else
{
2012-03-07 14:08:30 +01:00
player = source -> ToPlayer ();
if ( player )
2010-09-22 18:13:57 +06:00
{
if ( target -> GetTypeId () != TYPEID_UNIT && target -> GetTypeId () != TYPEID_GAMEOBJECT && target -> GetTypeId () != TYPEID_PLAYER )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s target is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping." ,
2010-09-22 18:13:57 +06:00
step . script -> GetDebugInfo (). c_str (), target -> GetTypeId (), target -> GetEntry (), target -> GetGUIDLow ());
break ;
}
2012-03-29 13:42:04 +08:00
worldObject = dynamic_cast < WorldObject *> ( target );
2010-09-22 18:13:57 +06:00
}
else
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s neither source nor target is player (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping." ,
2011-10-11 23:40:04 +02:00
step . script -> GetDebugInfo (). c_str (), source -> GetTypeId (), source -> GetEntry (), source -> GetGUIDLow (),
target -> GetTypeId (), target -> GetEntry (), target -> GetGUIDLow ());
2010-09-22 18:13:57 +06:00
break ;
}
}
// quest id and flags checked at script loading
if (( worldObject -> GetTypeId () != TYPEID_UNIT || (( Unit * ) worldObject ) -> isAlive ()) &&
2012-03-07 14:08:30 +01:00
( step . script -> QuestExplored . Distance == 0 || worldObject -> IsWithinDistInMap ( player , float ( step . script -> QuestExplored . Distance ))))
player -> AreaExploredOrEventHappens ( step . script -> QuestExplored . QuestID );
2010-09-22 18:13:57 +06:00
else
2012-03-07 14:08:30 +01:00
player -> FailQuest ( step . script -> QuestExplored . QuestID );
2010-09-22 18:13:57 +06:00
break ;
}
case SCRIPT_COMMAND_KILL_CREDIT :
// Source or target must be Player.
2012-03-07 14:08:30 +01:00
if ( Player * player = _GetScriptPlayerSourceOrTarget ( source , target , step . script ))
2010-09-22 18:13:57 +06:00
{
if ( step . script -> KillCredit . Flags & SF_KILLCREDIT_REWARD_GROUP )
2012-03-07 14:08:30 +01:00
player -> RewardPlayerAndGroupAtEvent ( step . script -> KillCredit . CreatureEntry , player );
2010-09-22 18:13:57 +06:00
else
2012-03-07 14:08:30 +01:00
player -> KilledMonsterCredit ( step . script -> KillCredit . CreatureEntry , 0 );
2010-09-22 18:13:57 +06:00
}
break ;
case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT :
if ( ! step . script -> RespawnGameobject . GOGuid )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s gameobject guid (datalong) is not specified." , step . script -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
break ;
}
// Source or target must be WorldObject.
if ( WorldObject * pSummoner = _GetScriptWorldObject ( source , true , step . script ))
{
2011-09-15 14:08:17 +02:00
GameObject * pGO = _FindGameObject ( pSummoner , step . script -> RespawnGameobject . GOGuid );
2010-09-22 18:13:57 +06:00
if ( ! pGO )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s gameobject was not found (guid: %u)." , step . script -> GetDebugInfo (). c_str (), step . script -> RespawnGameobject . GOGuid );
2010-09-22 18:13:57 +06:00
break ;
}
if ( pGO -> GetGoType () == GAMEOBJECT_TYPE_FISHINGNODE ||
pGO -> GetGoType () == GAMEOBJECT_TYPE_DOOR ||
pGO -> GetGoType () == GAMEOBJECT_TYPE_BUTTON ||
pGO -> GetGoType () == GAMEOBJECT_TYPE_TRAP )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s can not be used with gameobject of type %u (guid: %u)." ,
2010-09-22 18:13:57 +06:00
step . script -> GetDebugInfo (). c_str (), uint32 ( pGO -> GetGoType ()), step . script -> RespawnGameobject . GOGuid );
break ;
}
// Check that GO is not spawned
if ( ! pGO -> isSpawned ())
{
int32 nTimeToDespawn = std :: max ( 5 , int32 ( step . script -> RespawnGameobject . DespawnDelay ));
pGO -> SetLootState ( GO_READY );
pGO -> SetRespawnTime ( nTimeToDespawn );
2011-10-10 17:39:34 -04:00
pGO -> GetMap () -> AddToMap ( pGO );
2010-09-22 18:13:57 +06:00
}
}
break ;
case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE :
{
// Source must be WorldObject.
if ( WorldObject * pSummoner = _GetScriptWorldObject ( source , true , step . script ))
{
if ( ! step . script -> TempSummonCreature . CreatureEntry )
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s creature entry (datalong) is not specified." , step . script -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
else
{
float x = step . script -> TempSummonCreature . PosX ;
float y = step . script -> TempSummonCreature . PosY ;
float z = step . script -> TempSummonCreature . PosZ ;
float o = step . script -> TempSummonCreature . Orientation ;
if ( ! pSummoner -> SummonCreature ( step . script -> TempSummonCreature . CreatureEntry , x , y , z , o , TEMPSUMMON_TIMED_OR_DEAD_DESPAWN , step . script -> TempSummonCreature . DespawnDelay ))
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s creature was not spawned (entry: %u)." , step . script -> GetDebugInfo (). c_str (), step . script -> TempSummonCreature . CreatureEntry );
2010-09-22 18:13:57 +06:00
}
}
break ;
}
case SCRIPT_COMMAND_OPEN_DOOR :
case SCRIPT_COMMAND_CLOSE_DOOR :
_ScriptProcessDoor ( source , target , step . script );
break ;
case SCRIPT_COMMAND_ACTIVATE_OBJECT :
// Source must be Unit.
2012-03-07 14:08:30 +01:00
if ( Unit * unit = _GetScriptUnit ( source , true , step . script ))
2010-09-22 18:13:57 +06:00
{
// Target must be GameObject.
if ( ! target )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s target object is NULL." , step . script -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
break ;
}
if ( target -> GetTypeId () != TYPEID_GAMEOBJECT )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s target object is not gameobject (TypeId: %u, Entry: %u, GUID: %u), skipping." ,
2010-09-22 18:13:57 +06:00
step . script -> GetDebugInfo (). c_str (), target -> GetTypeId (), target -> GetEntry (), target -> GetGUIDLow ());
break ;
}
2011-09-15 14:08:17 +02:00
if ( GameObject * pGO = target -> ToGameObject ())
2012-03-07 14:08:30 +01:00
pGO -> Use ( unit );
2010-09-22 18:13:57 +06:00
}
break ;
case SCRIPT_COMMAND_REMOVE_AURA :
{
// Source (datalong2 != 0) or target (datalong2 == 0) must be Unit.
bool bReverse = step . script -> RemoveAura . Flags & SF_REMOVEAURA_REVERSE ;
2012-03-07 14:08:30 +01:00
if ( Unit * unit = _GetScriptUnit ( bReverse ? source : target , bReverse , step . script ))
unit -> RemoveAurasDueToSpell ( step . script -> RemoveAura . SpellID );
2010-09-22 18:13:57 +06:00
break ;
}
case SCRIPT_COMMAND_CAST_SPELL :
{
2013-03-08 21:41:30 +01:00
/// @todo Allow gameobjects to be targets and casters
2010-09-22 18:13:57 +06:00
if ( ! source && ! target )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s source and target objects are NULL." , step . script -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
break ;
}
Unit * uSource = NULL ;
Unit * uTarget = NULL ;
// source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s
switch ( step . script -> CastSpell . Flags )
{
case SF_CASTSPELL_SOURCE_TO_TARGET : // source -> target
2011-07-08 11:12:19 +02:00
uSource = source ? source -> ToUnit () : NULL ;
uTarget = target ? target -> ToUnit () : NULL ;
2010-09-22 18:13:57 +06:00
break ;
case SF_CASTSPELL_SOURCE_TO_SOURCE : // source -> source
2011-07-08 11:12:19 +02:00
uSource = source ? source -> ToUnit () : NULL ;
2010-09-22 18:13:57 +06:00
uTarget = uSource ;
break ;
case SF_CASTSPELL_TARGET_TO_TARGET : // target -> target
2011-07-08 11:12:19 +02:00
uSource = target ? target -> ToUnit () : NULL ;
2010-09-22 18:13:57 +06:00
uTarget = uSource ;
break ;
case SF_CASTSPELL_TARGET_TO_SOURCE : // target -> source
2011-07-08 11:12:19 +02:00
uSource = target ? target -> ToUnit () : NULL ;
uTarget = source ? source -> ToUnit () : NULL ;
2010-09-22 18:13:57 +06:00
break ;
case SF_CASTSPELL_SEARCH_CREATURE : // source -> creature with entry
2011-07-08 11:12:19 +02:00
uSource = source ? source -> ToUnit () : NULL ;
uTarget = uSource ? GetClosestCreatureWithEntry ( uSource , abs ( step . script -> CastSpell . CreatureEntry ), step . script -> CastSpell . SearchRadius ) : NULL ;
2010-09-22 18:13:57 +06:00
break ;
}
if ( ! uSource || ! uSource -> isType ( TYPEMASK_UNIT ))
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s no source unit found for spell %u" , step . script -> GetDebugInfo (). c_str (), step . script -> CastSpell . SpellID );
2010-09-22 18:13:57 +06:00
break ;
}
if ( ! uTarget || ! uTarget -> isType ( TYPEMASK_UNIT ))
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s no target unit found for spell %u" , step . script -> GetDebugInfo (). c_str (), step . script -> CastSpell . SpellID );
2010-09-22 18:13:57 +06:00
break ;
}
2010-09-25 22:03:57 +02:00
bool triggered = ( step . script -> CastSpell . Flags != 4 ) ?
step . script -> CastSpell . CreatureEntry & SF_CASTSPELL_TRIGGERED :
2010-09-22 18:13:57 +06:00
step . script -> CastSpell . CreatureEntry < 0 ;
uSource -> CastSpell ( uTarget , step . script -> CastSpell . SpellID , triggered );
break ;
}
case SCRIPT_COMMAND_PLAY_SOUND :
// Source must be WorldObject.
2012-03-07 14:08:30 +01:00
if ( WorldObject * object = _GetScriptWorldObject ( source , true , step . script ))
2010-09-22 18:13:57 +06:00
{
// PlaySound.Flags bitmask: 0/1=anyone/target
2012-03-07 14:08:30 +01:00
Player * player = NULL ;
2010-09-22 18:13:57 +06:00
if ( step . script -> PlaySound . Flags & SF_PLAYSOUND_TARGET_PLAYER )
{
// Target must be Player.
2012-03-07 14:08:30 +01:00
player = _GetScriptPlayer ( target , false , step . script );
if ( ! target )
2010-09-22 18:13:57 +06:00
break ;
}
// PlaySound.Flags bitmask: 0/2=without/with distance dependent
if ( step . script -> PlaySound . Flags & SF_PLAYSOUND_DISTANCE_SOUND )
2012-03-07 14:08:30 +01:00
object -> PlayDistanceSound ( step . script -> PlaySound . SoundID , player );
2010-09-22 18:13:57 +06:00
else
2012-03-07 14:08:30 +01:00
object -> PlayDirectSound ( step . script -> PlaySound . SoundID , player );
2010-09-22 18:13:57 +06:00
}
break ;
case SCRIPT_COMMAND_CREATE_ITEM :
// Target or source must be Player.
if ( Player * pReceiver = _GetScriptPlayerSourceOrTarget ( source , target , step . script ))
{
ItemPosCountVec dest ;
2011-04-29 16:48:15 +06:00
InventoryResult msg = pReceiver -> CanStoreNewItem ( NULL_BAG , NULL_SLOT , dest , step . script -> CreateItem . ItemEntry , step . script -> CreateItem . Amount );
2010-09-22 18:13:57 +06:00
if ( msg == EQUIP_ERR_OK )
{
if ( Item * item = pReceiver -> StoreNewItem ( dest , step . script -> CreateItem . ItemEntry , true ))
pReceiver -> SendNewItem ( item , step . script -> CreateItem . Amount , false , true );
}
else
pReceiver -> SendEquipError ( msg , NULL , NULL , step . script -> CreateItem . ItemEntry );
}
break ;
case SCRIPT_COMMAND_DESPAWN_SELF :
// Target or source must be Creature.
if ( Creature * cSource = _GetScriptCreatureSourceOrTarget ( source , target , step . script , true ))
2011-01-02 21:33:37 +01:00
cSource -> DespawnOrUnsummon ( step . script -> DespawnSelf . DespawnDelay );
2010-09-22 18:13:57 +06:00
break ;
case SCRIPT_COMMAND_LOAD_PATH :
// Source must be Unit.
2012-03-07 14:08:30 +01:00
if ( Unit * unit = _GetScriptUnit ( source , true , step . script ))
2010-09-22 18:13:57 +06:00
{
if ( ! sWaypointMgr -> GetPath ( step . script -> LoadPath . PathID ))
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s source object has an invalid path (%u), skipping." , step . script -> GetDebugInfo (). c_str (), step . script -> LoadPath . PathID );
2010-09-22 18:13:57 +06:00
else
2012-03-07 14:08:30 +01:00
unit -> GetMotionMaster () -> MovePath ( step . script -> LoadPath . PathID , step . script -> LoadPath . IsRepeatable );
2010-09-22 18:13:57 +06:00
}
break ;
case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT :
{
if ( ! step . script -> CallScript . CreatureEntry )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s creature entry is not specified, skipping." , step . script -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
break ;
}
if ( ! step . script -> CallScript . ScriptID )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s script id is not specified, skipping." , step . script -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
break ;
}
2010-12-14 15:58:45 +01:00
Creature * cTarget = NULL ;
2010-09-22 18:13:57 +06:00
if ( source ) //using grid searcher
{
WorldObject * wSource = dynamic_cast < WorldObject *> ( source );
2011-10-18 10:53:34 -04:00
CellCoord p ( Trinity :: ComputeCellCoord ( wSource -> GetPositionX (), wSource -> GetPositionY ()));
2010-09-22 18:13:57 +06:00
Cell cell ( p );
Trinity :: CreatureWithDbGUIDCheck target_check ( wSource , step . script -> CallScript . CreatureEntry );
Trinity :: CreatureSearcher < Trinity :: CreatureWithDbGUIDCheck > checker ( wSource , cTarget , target_check );
TypeContainerVisitor < Trinity :: CreatureSearcher < Trinity :: CreatureWithDbGUIDCheck > , GridTypeMapContainer > unit_checker ( checker );
2011-10-19 17:40:44 +01:00
cell . Visit ( p , unit_checker , * wSource -> GetMap (), * wSource , wSource -> GetGridActivationRange ());
2010-09-22 18:13:57 +06:00
}
else //check hashmap holders
{
2010-12-22 21:25:23 +01:00
if ( CreatureData const * data = sObjectMgr -> GetCreatureData ( step . script -> CallScript . CreatureEntry ))
2010-09-22 18:13:57 +06:00
cTarget = ObjectAccessor :: GetObjectInWorld < Creature > ( data -> mapid , data -> posX , data -> posY , MAKE_NEW_GUID ( step . script -> CallScript . CreatureEntry , data -> id , HIGHGUID_UNIT ), cTarget );
}
if ( ! cTarget )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s target was not found (entry: %u)" , step . script -> GetDebugInfo (). c_str (), step . script -> CallScript . CreatureEntry );
2010-09-22 18:13:57 +06:00
break ;
}
//Lets choose our ScriptMap map
2011-09-15 14:08:17 +02:00
ScriptMapMap * datamap = GetScriptsMapByType ( ScriptsType ( step . script -> CallScript . ScriptType ));
2010-09-22 18:13:57 +06:00
//if no scriptmap present...
if ( ! datamap )
{
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s unknown scriptmap (%u) specified, skipping." , step . script -> GetDebugInfo (). c_str (), step . script -> CallScript . ScriptType );
2010-09-22 18:13:57 +06:00
break ;
}
// Insert script into schedule but do not start it
ScriptsStart ( * datamap , step . script -> CallScript . ScriptID , cTarget , NULL );
break ;
}
case SCRIPT_COMMAND_KILL :
// Source or target must be Creature.
2011-09-15 14:08:17 +02:00
if ( Creature * cSource = _GetScriptCreatureSourceOrTarget ( source , target , step . script ))
2010-09-22 18:13:57 +06:00
{
if ( cSource -> isDead ())
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "%s creature is already dead (Entry: %u, GUID: %u)" ,
2010-09-22 18:13:57 +06:00
step . script -> GetDebugInfo (). c_str (), cSource -> GetEntry (), cSource -> GetGUIDLow ());
else
{
cSource -> setDeathState ( JUST_DIED );
if ( step . script -> Kill . RemoveCorpse == 1 )
cSource -> RemoveCorpse ();
}
}
break ;
case SCRIPT_COMMAND_ORIENTATION :
// Source must be Unit.
2012-03-07 14:08:30 +01:00
if ( Unit * sourceUnit = _GetScriptUnit ( source , true , step . script ))
2010-09-22 18:13:57 +06:00
{
2012-03-07 14:08:30 +01:00
if ( step . script -> Orientation . Flags & SF_ORIENTATION_FACE_TARGET )
2010-09-22 18:13:57 +06:00
{
// Target must be Unit.
2012-03-07 14:08:30 +01:00
Unit * targetUnit = _GetScriptUnit ( target , false , step . script );
if ( ! targetUnit )
2010-09-22 18:13:57 +06:00
break ;
2012-03-07 14:08:30 +01:00
sourceUnit -> SetInFront ( targetUnit );
2010-09-22 18:13:57 +06:00
}
else
2012-03-07 14:08:30 +01:00
sourceUnit -> SetOrientation ( step . script -> Orientation . Orientation );
2010-09-22 18:13:57 +06:00
2012-03-07 14:08:30 +01:00
sourceUnit -> SendMovementFlagUpdate ();
2010-09-22 18:13:57 +06:00
}
break ;
case SCRIPT_COMMAND_EQUIP :
// Source must be Creature.
2011-09-15 14:08:17 +02:00
if ( Creature * cSource = _GetScriptCreature ( source , true , step . script ))
2010-09-22 18:13:57 +06:00
cSource -> LoadEquipment ( step . script -> Equip . EquipmentID );
break ;
case SCRIPT_COMMAND_MODEL :
// Source must be Creature.
2011-09-15 14:08:17 +02:00
if ( Creature * cSource = _GetScriptCreature ( source , true , step . script ))
2010-09-22 18:13:57 +06:00
cSource -> SetDisplayId ( step . script -> Model . ModelID );
break ;
case SCRIPT_COMMAND_CLOSE_GOSSIP :
// Source must be Player.
2012-03-07 14:08:30 +01:00
if ( Player * player = _GetScriptPlayer ( source , true , step . script ))
player -> PlayerTalkClass -> SendCloseGossip ();
2010-09-22 18:13:57 +06:00
break ;
case SCRIPT_COMMAND_PLAYMOVIE :
// Source must be Player.
2012-03-07 14:08:30 +01:00
if ( Player * player = _GetScriptPlayer ( source , true , step . script ))
player -> SendMovieStart ( step . script -> PlayMovie . MovieID );
2010-09-22 18:13:57 +06:00
break ;
default :
2013-05-13 15:07:36 +02:00
TC_LOG_ERROR ( LOG_FILTER_TSCR , "Unknown script command %s." , step . script -> GetDebugInfo (). c_str ());
2010-09-22 18:13:57 +06:00
break ;
}
m_scriptSchedule . erase ( iter );
iter = m_scriptSchedule . begin ();
2011-04-13 12:07:20 +06:00
sScriptMgr -> DecreaseScheduledScriptCount ();
2010-09-22 18:13:57 +06:00
}
}