2010-10-07 15:35:36 +02:00
/*
2015-01-01 00:27:46 +01:00
* Copyright (C) 2008-2015 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/>.
2008-10-02 16:23:55 -05:00
*/
2009-10-17 15:51:44 -07:00
2009-05-06 15:36:55 +02:00
#include "Creature.h"
2009-05-16 14:49:30 -05:00
#include "CreatureAI.h"
2012-11-20 12:30:30 +01:00
#include "DatabaseEnv.h"
#include "GameObject.h"
2013-01-09 15:15:42 +01:00
#include "Group.h"
2012-11-20 12:30:30 +01:00
#include "InstanceScript.h"
2011-02-03 22:20:40 +01:00
#include "LFGMgr.h"
2012-11-20 12:30:30 +01:00
#include "Log.h"
#include "Map.h"
#include "Player.h"
#include "Pet.h"
2012-11-20 14:54:33 +01:00
#include "WorldSession.h"
#include "Opcodes.h"
2009-10-17 15:51:44 -07:00
2010-08-08 22:54:58 +06:00
void InstanceScript :: SaveToDB ()
2008-10-02 16:23:55 -05:00
{
2009-05-11 03:17:13 -05:00
std :: string data = GetSaveData ();
2009-11-01 17:53:07 -08:00
if ( data . empty ())
2009-05-11 03:17:13 -05:00
return ;
2011-02-03 22:20:40 +01:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_INSTANCE_DATA );
2011-02-03 22:20:40 +01:00
stmt -> setUInt32 ( 0 , GetCompletedEncounterMask ());
stmt -> setString ( 1 , data );
stmt -> setUInt32 ( 2 , instance -> GetInstanceId ());
CharacterDatabase . Execute ( stmt );
2008-10-02 16:23:55 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-08 22:54:58 +06:00
bool InstanceScript :: IsEncounterInProgress () const
2009-05-01 18:24:12 -05:00
{
2009-10-17 16:20:24 -07:00
for ( std :: vector < BossInfo >:: const_iterator itr = bosses . begin (); itr != bosses . end (); ++ itr )
2009-11-01 17:53:07 -08:00
if ( itr -> state == IN_PROGRESS )
2009-05-01 18:24:12 -05:00
return true ;
2009-10-17 15:51:44 -07:00
2009-05-01 18:24:12 -05:00
return false ;
}
2009-10-17 15:51:44 -07:00
2014-09-18 00:25:05 +02:00
void InstanceScript :: OnCreatureCreate ( Creature * creature )
{
AddObject ( creature , true );
AddMinion ( creature , true );
}
void InstanceScript :: OnCreatureRemove ( Creature * creature )
{
AddObject ( creature , false );
AddMinion ( creature , false );
}
void InstanceScript :: OnGameObjectCreate ( GameObject * go )
{
AddObject ( go , true );
AddDoor ( go , true );
}
void InstanceScript :: OnGameObjectRemove ( GameObject * go )
{
AddObject ( go , false );
AddDoor ( go , false );
}
ObjectGuid InstanceScript :: GetObjectGuid ( uint32 type ) const
{
ObjectGuidMap :: const_iterator i = _objectGuids . find ( type );
if ( i != _objectGuids . end ())
return i -> second ;
return ObjectGuid :: Empty ;
}
ObjectGuid InstanceScript :: GetGuidData ( uint32 type ) const
{
return GetObjectGuid ( type );
}
2014-09-07 00:42:14 +02:00
void InstanceScript :: SetHeaders ( std :: string const & dataHeaders )
{
for ( char header : dataHeaders )
if ( isalpha ( header ))
headers . push_back ( header );
}
2011-09-15 14:08:17 +02:00
void InstanceScript :: LoadMinionData ( const MinionData * data )
2009-05-16 14:49:30 -05:00
{
2010-04-07 19:13:19 +02:00
while ( data -> entry )
2009-05-16 14:49:30 -05:00
{
2009-11-01 17:53:07 -08:00
if ( data -> bossId < bosses . size ())
2009-05-16 14:49:30 -05:00
minions . insert ( std :: make_pair ( data -> entry , MinionInfo ( & bosses [ data -> bossId ])));
2009-10-17 15:51:44 -07:00
2009-05-16 14:49:30 -05:00
++ data ;
}
2013-11-08 10:50:51 +01:00
TC_LOG_DEBUG ( "scripts" , "InstanceScript::LoadMinionData: " UI64FMTD " minions loaded." , uint64 ( minions . size ()));
2009-05-16 14:49:30 -05:00
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
void InstanceScript :: LoadDoorData ( const DoorData * data )
2009-05-01 18:24:12 -05:00
{
2010-04-07 19:13:19 +02:00
while ( data -> entry )
2009-05-01 18:24:12 -05:00
{
2009-11-01 17:53:07 -08:00
if ( data -> bossId < bosses . size ())
2009-05-17 16:37:03 -05:00
doors . insert ( std :: make_pair ( data -> entry , DoorInfo ( & bosses [ data -> bossId ], data -> type , BoundaryType ( data -> boundary ))));
2009-10-17 15:51:44 -07:00
2009-05-09 14:08:42 -05:00
++ data ;
}
2013-11-08 10:50:51 +01:00
TC_LOG_DEBUG ( "scripts" , "InstanceScript::LoadDoorData: " UI64FMTD " doors loaded." , uint64 ( doors . size ()));
2009-05-09 14:08:42 -05:00
}
2009-10-17 15:51:44 -07:00
2014-09-18 00:25:05 +02:00
void InstanceScript :: LoadObjectData ( ObjectData const * creatureData , ObjectData const * gameObjectData )
{
if ( creatureData )
LoadObjectData ( creatureData , _creatureInfo );
if ( gameObjectData )
LoadObjectData ( gameObjectData , _gameObjectInfo );
2014-11-21 01:36:50 +01:00
TC_LOG_DEBUG ( "scripts" , "InstanceScript::LoadObjectData: " SZFMTD " objects loaded." , _creatureInfo . size () + _gameObjectInfo . size ());
2014-09-18 00:25:05 +02:00
}
void InstanceScript :: LoadObjectData ( ObjectData const * data , ObjectInfoMap & objectInfo )
{
while ( data -> entry )
{
ASSERT ( objectInfo . find ( data -> entry ) == objectInfo . end ());
objectInfo [ data -> entry ] = data -> type ;
++ data ;
}
}
2011-09-15 14:08:17 +02:00
void InstanceScript :: UpdateMinionState ( Creature * minion , EncounterState state )
2009-05-16 14:49:30 -05:00
{
2009-11-01 17:53:07 -08:00
switch ( state )
2009-05-16 14:49:30 -05:00
{
case NOT_STARTED :
2013-06-11 19:54:27 -02:30
if ( ! minion -> IsAlive ())
2009-05-16 14:49:30 -05:00
minion -> Respawn ();
2013-06-11 19:54:27 -02:30
else if ( minion -> IsInCombat ())
2009-05-16 14:49:30 -05:00
minion -> AI () -> EnterEvadeMode ();
break ;
case IN_PROGRESS :
2013-06-11 19:54:27 -02:30
if ( ! minion -> IsAlive ())
2009-05-16 14:49:30 -05:00
minion -> Respawn ();
2013-06-11 19:54:27 -02:30
else if ( ! minion -> GetVictim ())
2009-05-16 14:49:30 -05:00
minion -> AI () -> DoZoneInCombat ();
break ;
2010-08-21 20:55:31 +02:00
default :
break ;
2009-05-16 14:49:30 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
void InstanceScript :: UpdateDoorState ( GameObject * door )
2009-05-09 14:08:42 -05:00
{
2013-01-02 09:53:43 +01:00
DoorInfoMapBounds range = doors . equal_range ( door -> GetEntry ());
if ( range . first == range . second )
2009-05-09 14:08:42 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-05-09 14:08:42 -05:00
bool open = true ;
2013-01-02 09:53:43 +01:00
for (; range . first != range . second && open ; ++ range . first )
2009-05-09 14:08:42 -05:00
{
2013-01-02 09:53:43 +01:00
DoorInfo const & info = range . first -> second ;
switch ( info . type )
2009-05-06 00:06:38 -05:00
{
2011-05-16 13:24:08 +02:00
case DOOR_TYPE_ROOM :
2013-01-02 09:53:43 +01:00
open = ( info . bossInfo -> state != IN_PROGRESS );
2009-05-09 14:08:42 -05:00
break ;
2011-05-16 13:24:08 +02:00
case DOOR_TYPE_PASSAGE :
2013-01-02 09:53:43 +01:00
open = ( info . bossInfo -> state == DONE );
2011-05-16 13:24:08 +02:00
break ;
case DOOR_TYPE_SPAWN_HOLE :
2013-01-02 09:53:43 +01:00
open = ( info . bossInfo -> state == IN_PROGRESS );
2011-05-16 13:24:08 +02:00
break ;
default :
2009-05-09 14:08:42 -05:00
break ;
2009-05-06 00:06:38 -05:00
}
2009-05-01 18:24:12 -05:00
}
2009-10-17 15:51:44 -07:00
2009-05-09 14:08:42 -05:00
door -> SetGoState ( open ? GO_STATE_ACTIVE : GO_STATE_READY );
2009-05-01 18:24:12 -05:00
}
2009-10-17 15:51:44 -07:00
2014-09-18 00:25:05 +02:00
void InstanceScript :: AddObject ( Creature * obj , bool add )
{
ObjectInfoMap :: const_iterator j = _creatureInfo . find ( obj -> GetEntry ());
if ( j != _creatureInfo . end ())
AddObject ( obj , j -> second , add );
}
void InstanceScript :: AddObject ( GameObject * obj , bool add )
{
ObjectInfoMap :: const_iterator j = _gameObjectInfo . find ( obj -> GetEntry ());
if ( j != _gameObjectInfo . end ())
AddObject ( obj , j -> second , add );
}
void InstanceScript :: AddObject ( WorldObject * obj , uint32 type , bool add )
{
if ( add )
_objectGuids [ type ] = obj -> GetGUID ();
else
{
ObjectGuidMap :: iterator i = _objectGuids . find ( type );
if ( i != _objectGuids . end () && i -> second == obj -> GetGUID ())
_objectGuids . erase ( i );
}
}
2011-09-15 14:08:17 +02:00
void InstanceScript :: AddDoor ( GameObject * door , bool add )
2009-05-01 18:24:12 -05:00
{
2013-01-02 09:53:43 +01:00
DoorInfoMapBounds range = doors . equal_range ( door -> GetEntry ());
if ( range . first == range . second )
2009-05-09 14:08:42 -05:00
return ;
2009-10-17 15:51:44 -07:00
2013-01-02 09:53:43 +01:00
for (; range . first != range . second ; ++ range . first )
2009-05-01 18:24:12 -05:00
{
2013-01-02 09:53:43 +01:00
DoorInfo const & data = range . first -> second ;
2011-10-18 12:39:01 +02:00
2009-11-01 17:53:07 -08:00
if ( add )
2009-05-17 16:37:03 -05:00
{
2014-07-13 22:43:28 +02:00
data . bossInfo -> door [ data . type ]. insert ( door -> GetGUID ());
2011-10-18 12:39:01 +02:00
switch ( data . boundary )
2009-05-17 16:37:03 -05:00
{
default :
case BOUNDARY_NONE :
break ;
case BOUNDARY_N :
case BOUNDARY_S :
2011-10-18 12:39:01 +02:00
data . bossInfo -> boundary [ data . boundary ] = door -> GetPositionX ();
2009-05-17 16:37:03 -05:00
break ;
case BOUNDARY_E :
case BOUNDARY_W :
2011-10-18 12:39:01 +02:00
data . bossInfo -> boundary [ data . boundary ] = door -> GetPositionY ();
2009-05-17 16:37:03 -05:00
break ;
case BOUNDARY_NW :
case BOUNDARY_SE :
2011-10-18 12:39:01 +02:00
data . bossInfo -> boundary [ data . boundary ] = door -> GetPositionX () + door -> GetPositionY ();
2009-05-17 16:37:03 -05:00
break ;
case BOUNDARY_NE :
case BOUNDARY_SW :
2011-10-18 12:39:01 +02:00
data . bossInfo -> boundary [ data . boundary ] = door -> GetPositionX () - door -> GetPositionY ();
2009-05-17 16:37:03 -05:00
break ;
}
}
2009-05-06 00:06:38 -05:00
else
2014-07-13 22:43:28 +02:00
data . bossInfo -> door [ data . type ]. erase ( door -> GetGUID ());
2009-05-01 18:24:12 -05:00
}
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( add )
2009-05-09 14:08:42 -05:00
UpdateDoorState ( door );
2009-05-01 18:24:12 -05:00
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
void InstanceScript :: AddMinion ( Creature * minion , bool add )
2009-05-16 14:49:30 -05:00
{
MinionInfoMap :: iterator itr = minions . find ( minion -> GetEntry ());
2009-11-01 17:53:07 -08:00
if ( itr == minions . end ())
2009-05-16 14:49:30 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( add )
2014-07-13 22:43:28 +02:00
itr -> second . bossInfo -> minion . insert ( minion -> GetGUID ());
2009-05-16 14:49:30 -05:00
else
2014-07-13 22:43:28 +02:00
itr -> second . bossInfo -> minion . erase ( minion -> GetGUID ());
2009-05-16 14:49:30 -05:00
}
2009-10-17 15:51:44 -07:00
2010-08-08 22:54:58 +06:00
bool InstanceScript :: SetBossState ( uint32 id , EncounterState state )
2009-05-01 18:24:12 -05:00
{
2009-11-01 17:53:07 -08:00
if ( id < bosses . size ())
2009-05-01 18:24:12 -05:00
{
2011-09-15 14:08:17 +02:00
BossInfo * bossInfo = & bosses [ id ];
2009-11-01 17:53:07 -08:00
if ( bossInfo -> state == TO_BE_DECIDED ) // loading
2009-05-20 11:44:38 -05:00
{
2009-05-11 03:17:13 -05:00
bossInfo -> state = state ;
2013-11-08 10:50:51 +01:00
//TC_LOG_ERROR("misc", "Inialize boss %u state as %u.", id, (uint32)state);
2009-05-20 11:44:38 -05:00
return false ;
}
2009-05-11 03:17:13 -05:00
else
{
2009-11-01 17:53:07 -08:00
if ( bossInfo -> state == state )
2009-05-20 11:44:38 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2009-11-01 17:53:07 -08:00
if ( state == DONE )
2014-09-14 16:14:12 +02:00
for ( GuidSet :: iterator i = bossInfo -> minion . begin (); i != bossInfo -> minion . end (); ++ i )
2014-07-13 22:43:28 +02:00
if ( Creature * minion = instance -> GetCreature ( * i ))
if ( minion -> isWorldBoss () && minion -> IsAlive ())
return false ;
2009-10-17 15:51:44 -07:00
2009-05-11 03:17:13 -05:00
bossInfo -> state = state ;
SaveToDB ();
}
2009-10-17 16:20:24 -07:00
for ( uint32 type = 0 ; type < MAX_DOOR_TYPES ; ++ type )
2014-09-14 16:14:12 +02:00
for ( GuidSet :: iterator i = bossInfo -> door [ type ]. begin (); i != bossInfo -> door [ type ]. end (); ++ i )
2014-07-13 22:43:28 +02:00
if ( GameObject * door = instance -> GetGameObject ( * i ))
UpdateDoorState ( door );
2009-10-17 15:51:44 -07:00
2014-09-14 16:14:12 +02:00
for ( GuidSet :: iterator i = bossInfo -> minion . begin (); i != bossInfo -> minion . end (); ++ i )
2014-07-13 22:43:28 +02:00
if ( Creature * minion = instance -> GetCreature ( * i ))
UpdateMinionState ( minion , state );
2009-10-17 15:51:44 -07:00
2009-05-20 11:44:38 -05:00
return true ;
2009-05-01 18:24:12 -05:00
}
2009-05-20 11:44:38 -05:00
return false ;
2009-05-01 18:24:12 -05:00
}
2009-10-17 15:51:44 -07:00
2014-09-07 00:42:14 +02:00
void InstanceScript :: Load ( char const * data )
2009-05-11 03:17:13 -05:00
{
2010-04-07 19:14:10 +02:00
if ( ! data )
2014-09-07 00:42:14 +02:00
{
OUT_LOAD_INST_DATA_FAIL ;
return ;
}
OUT_LOAD_INST_DATA ( data );
2009-05-11 03:17:13 -05:00
std :: istringstream loadStream ( data );
2014-09-07 00:42:14 +02:00
if ( ReadSaveDataHeaders ( loadStream ))
{
ReadSaveDataBossStates ( loadStream );
ReadSaveDataMore ( loadStream );
}
else
OUT_LOAD_INST_DATA_FAIL ;
OUT_LOAD_INST_DATA_COMPLETE ;
}
bool InstanceScript :: ReadSaveDataHeaders ( std :: istringstream & data )
{
for ( char header : headers )
{
char buff ;
data >> buff ;
if ( header != buff )
return false ;
}
return true ;
}
void InstanceScript :: ReadSaveDataBossStates ( std :: istringstream & data )
{
2009-05-11 03:17:13 -05:00
uint32 bossId = 0 ;
2009-10-17 16:20:24 -07:00
for ( std :: vector < BossInfo >:: iterator i = bosses . begin (); i != bosses . end (); ++ i , ++ bossId )
2009-05-11 03:17:13 -05:00
{
2014-09-07 00:42:14 +02:00
uint32 buff ;
data >> buff ;
if ( buff == IN_PROGRESS || buff == SPECIAL )
buff = NOT_STARTED ;
2009-11-01 17:53:07 -08:00
if ( buff < TO_BE_DECIDED )
2014-09-07 00:42:14 +02:00
SetBossState ( bossId , EncounterState ( buff ));
2009-05-11 03:17:13 -05:00
}
}
2009-10-17 15:51:44 -07:00
2014-09-07 00:42:14 +02:00
std :: string InstanceScript :: GetSaveData ()
2009-05-11 03:17:13 -05:00
{
2014-09-07 00:42:14 +02:00
OUT_SAVE_INST_DATA ;
2009-05-11 03:17:13 -05:00
std :: ostringstream saveStream ;
2014-09-07 00:42:14 +02:00
WriteSaveDataHeaders ( saveStream );
WriteSaveDataBossStates ( saveStream );
WriteSaveDataMore ( saveStream );
OUT_SAVE_INST_DATA_COMPLETE ;
2009-05-11 03:17:13 -05:00
return saveStream . str ();
2009-10-17 16:20:24 -07:00
}
2009-10-17 15:51:44 -07:00
2014-09-07 00:42:14 +02:00
void InstanceScript :: WriteSaveDataHeaders ( std :: ostringstream & data )
2009-06-17 07:16:40 +02:00
{
2014-09-07 00:42:14 +02:00
for ( char header : headers )
data << header << ' ' ;
}
2009-10-17 15:51:44 -07:00
2014-09-07 00:42:14 +02:00
void InstanceScript :: WriteSaveDataBossStates ( std :: ostringstream & data )
{
for ( BossInfo const & bossInfo : bosses )
data << uint32 ( bossInfo . state ) << ' ' ;
}
2009-10-17 15:51:44 -07:00
2014-09-14 16:14:12 +02:00
void InstanceScript :: HandleGameObject ( ObjectGuid guid , bool open , GameObject * go /*= nullptr*/ )
2014-09-07 00:42:14 +02:00
{
if ( ! go )
go = instance -> GetGameObject ( guid );
2011-10-07 19:45:43 -05:00
if ( go )
2014-09-07 00:42:14 +02:00
go -> SetGoState ( open ? GO_STATE_ACTIVE : GO_STATE_READY );
else
TC_LOG_DEBUG ( "scripts" , "InstanceScript: HandleGameObject failed" );
}
2014-09-14 16:14:12 +02:00
void InstanceScript :: DoUseDoorOrButton ( ObjectGuid guid , uint32 withRestoreTime /*= 0*/ , bool useAlternativeState /*= false*/ )
2014-09-07 00:42:14 +02:00
{
if ( ! guid )
return ;
if ( GameObject * go = instance -> GetGameObject ( guid ))
2009-06-17 07:16:40 +02:00
{
2011-10-07 19:45:43 -05:00
if ( go -> GetGoType () == GAMEOBJECT_TYPE_DOOR || go -> GetGoType () == GAMEOBJECT_TYPE_BUTTON )
2009-06-17 07:16:40 +02:00
{
2011-10-07 19:45:43 -05:00
if ( go -> getLootState () == GO_READY )
2014-09-07 00:42:14 +02:00
go -> UseDoorOrButton ( withRestoreTime , useAlternativeState );
2011-10-07 19:45:43 -05:00
else if ( go -> getLootState () == GO_ACTIVATED )
go -> ResetDoorOrButton ();
2009-06-17 07:16:40 +02:00
}
else
2014-09-07 00:42:14 +02:00
TC_LOG_ERROR ( "scripts" , "InstanceScript: DoUseDoorOrButton can't use gameobject entry %u, because type is %u." , go -> GetEntry (), go -> GetGoType ());
2009-06-17 07:16:40 +02:00
}
2014-09-07 00:42:14 +02:00
else
TC_LOG_DEBUG ( "scripts" , "InstanceScript: HandleGameObject failed" );
2009-06-17 07:16:40 +02:00
}
2009-10-17 15:51:44 -07:00
2014-09-14 16:14:12 +02:00
void InstanceScript :: DoRespawnGameObject ( ObjectGuid guid , uint32 timeToDespawn /*= MINUTE*/ )
2009-06-17 07:16:40 +02:00
{
2014-09-07 00:42:14 +02:00
if ( GameObject * go = instance -> GetGameObject ( guid ))
2009-06-17 07:16:40 +02:00
{
2014-09-07 00:42:14 +02:00
switch ( go -> GetGoType ())
{
case GAMEOBJECT_TYPE_DOOR :
case GAMEOBJECT_TYPE_BUTTON :
case GAMEOBJECT_TYPE_TRAP :
case GAMEOBJECT_TYPE_FISHINGNODE :
// not expect any of these should ever be handled
TC_LOG_ERROR ( "scripts" , "InstanceScript: DoRespawnGameObject can't respawn gameobject entry %u, because type is %u." , go -> GetEntry (), go -> GetGoType ());
return ;
default :
break ;
}
2009-10-17 15:51:44 -07:00
2011-10-07 19:45:43 -05:00
if ( go -> isSpawned ())
2009-06-17 07:16:40 +02:00
return ;
2009-10-17 15:51:44 -07:00
2014-09-07 00:42:14 +02:00
go -> SetRespawnTime ( timeToDespawn );
2009-06-17 07:16:40 +02:00
}
2014-09-07 00:42:14 +02:00
else
TC_LOG_DEBUG ( "scripts" , "InstanceScript: DoRespawnGameObject failed" );
2009-06-17 07:16:40 +02:00
}
2009-10-17 15:51:44 -07:00
2010-08-08 22:54:58 +06:00
void InstanceScript :: DoUpdateWorldState ( uint32 uiStateId , uint32 uiStateData )
2009-08-14 20:56:01 +02:00
{
Map :: PlayerList const & lPlayers = instance -> GetPlayers ();
2009-10-17 15:51:44 -07:00
2009-08-14 20:56:01 +02:00
if ( ! lPlayers . isEmpty ())
{
2009-10-17 16:20:24 -07:00
for ( Map :: PlayerList :: const_iterator itr = lPlayers . begin (); itr != lPlayers . end (); ++ itr )
2013-06-11 21:25:12 -02:30
if ( Player * player = itr -> GetSource ())
2011-10-07 11:08:09 -05:00
player -> SendUpdateWorldState ( uiStateId , uiStateData );
2009-08-14 20:56:01 +02:00
}
else
2013-11-08 10:50:51 +01:00
TC_LOG_DEBUG ( "scripts" , "DoUpdateWorldState attempt send data but no players in map." );
2009-08-14 20:56:01 +02:00
}
2009-10-17 15:51:44 -07:00
2009-10-16 16:45:01 -07:00
// Send Notify to all players in instance
2012-01-12 22:33:11 +01:00
void InstanceScript :: DoSendNotifyToInstance ( char const * format , ...)
2009-10-16 16:45:01 -07:00
{
2012-01-12 21:14:57 +01:00
InstanceMap :: PlayerList const & players = instance -> GetPlayers ();
2009-10-17 15:51:44 -07:00
2012-01-12 21:14:57 +01:00
if ( ! players . isEmpty ())
2010-08-30 15:25:15 +02:00
{
va_list ap ;
va_start ( ap , format );
2012-01-12 21:14:57 +01:00
char buff [ 1024 ];
vsnprintf ( buff , 1024 , format , ap );
2010-08-30 15:25:15 +02:00
va_end ( ap );
2012-01-12 21:14:57 +01:00
for ( Map :: PlayerList :: const_iterator i = players . begin (); i != players . end (); ++ i )
2013-06-11 21:25:12 -02:30
if ( Player * player = i -> GetSource ())
2012-01-12 21:14:57 +01:00
if ( WorldSession * session = player -> GetSession ())
2012-02-16 13:56:08 +01:00
session -> SendNotification ( "%s" , buff );
2010-08-30 15:25:15 +02:00
}
2009-10-16 16:45:01 -07:00
}
2009-11-01 17:53:07 -08:00
2010-03-23 19:15:17 +01:00
// Update Achievement Criteria for all players in instance
2011-04-21 23:32:45 +02:00
void InstanceScript :: DoUpdateAchievementCriteria ( AchievementCriteriaTypes type , uint32 miscValue1 /*= 0*/ , uint32 miscValue2 /*= 0*/ , Unit * unit /*= NULL*/ )
2010-03-23 19:15:17 +01:00
{
Map :: PlayerList const & PlayerList = instance -> GetPlayers ();
if ( ! PlayerList . isEmpty ())
for ( Map :: PlayerList :: const_iterator i = PlayerList . begin (); i != PlayerList . end (); ++ i )
2013-06-11 21:25:12 -02:30
if ( Player * player = i -> GetSource ())
2012-11-12 14:25:51 +01:00
player -> UpdateAchievementCriteria ( type , miscValue1 , miscValue2 , 0 , unit );
2010-03-23 19:15:17 +01:00
}
2010-04-27 22:26:30 +02:00
// Start timed achievement for all players in instance
2010-08-08 22:54:58 +06:00
void InstanceScript :: DoStartTimedAchievement ( AchievementCriteriaTimedTypes type , uint32 entry )
2010-04-27 22:26:30 +02:00
{
Map :: PlayerList const & PlayerList = instance -> GetPlayers ();
if ( ! PlayerList . isEmpty ())
for ( Map :: PlayerList :: const_iterator i = PlayerList . begin (); i != PlayerList . end (); ++ i )
2013-06-11 21:25:12 -02:30
if ( Player * player = i -> GetSource ())
2012-09-18 14:29:53 +02:00
player -> StartTimedAchievement ( type , entry );
2010-04-27 22:26:30 +02:00
}
// Stop timed achievement for all players in instance
2010-08-08 22:54:58 +06:00
void InstanceScript :: DoStopTimedAchievement ( AchievementCriteriaTimedTypes type , uint32 entry )
2010-04-27 22:26:30 +02:00
{
Map :: PlayerList const & PlayerList = instance -> GetPlayers ();
if ( ! PlayerList . isEmpty ())
for ( Map :: PlayerList :: const_iterator i = PlayerList . begin (); i != PlayerList . end (); ++ i )
2013-06-11 21:25:12 -02:30
if ( Player * player = i -> GetSource ())
2012-09-18 14:29:53 +02:00
player -> RemoveTimedAchievement ( type , entry );
2010-04-27 22:26:30 +02:00
}
2009-10-16 16:45:01 -07:00
// Remove Auras due to Spell on all players in instance
2010-08-08 22:54:58 +06:00
void InstanceScript :: DoRemoveAurasDueToSpellOnPlayers ( uint32 spell )
2009-10-16 16:45:01 -07:00
{
2011-08-19 18:17:04 +02:00
Map :: PlayerList const & PlayerList = instance -> GetPlayers ();
2009-10-16 16:45:01 -07:00
if ( ! PlayerList . isEmpty ())
2011-08-19 18:17:04 +02:00
{
for ( Map :: PlayerList :: const_iterator itr = PlayerList . begin (); itr != PlayerList . end (); ++ itr )
{
2013-06-11 21:25:12 -02:30
if ( Player * player = itr -> GetSource ())
2011-08-19 18:17:04 +02:00
{
player -> RemoveAurasDueToSpell ( spell );
if ( Pet * pet = player -> GetPet ())
pet -> RemoveAurasDueToSpell ( spell );
}
}
}
2009-10-16 16:45:01 -07:00
}
2009-12-25 15:53:37 +01:00
2011-01-01 23:37:35 +01:00
// Cast spell on all players in instance
void InstanceScript :: DoCastSpellOnPlayers ( uint32 spell )
{
Map :: PlayerList const & PlayerList = instance -> GetPlayers ();
if ( ! PlayerList . isEmpty ())
for ( Map :: PlayerList :: const_iterator i = PlayerList . begin (); i != PlayerList . end (); ++ i )
2013-06-11 21:25:12 -02:30
if ( Player * player = i -> GetSource ())
2011-01-01 23:37:35 +01:00
player -> CastSpell ( player , spell , true );
}
2010-08-08 22:54:58 +06:00
bool InstanceScript :: CheckAchievementCriteriaMeet ( uint32 criteria_id , Player const * /*source*/ , Unit const * /*target*/ /*= NULL*/ , uint32 /*miscvalue1*/ /*= 0*/ )
2009-12-25 15:53:37 +01:00
{
2013-11-08 10:50:51 +01:00
TC_LOG_ERROR ( "misc" , "Achievement system call InstanceScript::CheckAchievementCriteriaMeet but instance script for map %u not have implementation for achievement criteria %u" ,
2011-04-29 20:47:02 +02:00
instance -> GetId (), criteria_id );
2009-12-25 15:53:37 +01:00
return false ;
}
2011-01-23 16:59:33 +01:00
2011-01-23 21:42:32 +01:00
void InstanceScript :: SendEncounterUnit ( uint32 type , Unit * unit /*= NULL*/ , uint8 param1 /*= 0*/ , uint8 param2 /*= 0*/ )
2011-01-23 16:59:33 +01:00
{
2011-01-23 21:42:32 +01:00
// size of this packet is at most 15 (usually less)
WorldPacket data ( SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT , 15 );
2011-01-23 16:59:33 +01:00
data << uint32 ( type );
switch ( type )
{
2012-03-30 02:43:17 +02:00
case ENCOUNTER_FRAME_ENGAGE :
case ENCOUNTER_FRAME_DISENGAGE :
case ENCOUNTER_FRAME_UPDATE_PRIORITY :
if ( ! unit )
return ;
2014-09-13 01:07:21 +02:00
data << unit -> GetPackGUID ();
2011-01-23 16:59:33 +01:00
data << uint8 ( param1 );
break ;
2012-03-30 02:43:17 +02:00
case ENCOUNTER_FRAME_ADD_TIMER :
case ENCOUNTER_FRAME_ENABLE_OBJECTIVE :
case ENCOUNTER_FRAME_DISABLE_OBJECTIVE :
2012-03-30 15:13:54 +02:00
case ENCOUNTER_FRAME_SET_COMBAT_RES_LIMIT :
2011-01-23 16:59:33 +01:00
data << uint8 ( param1 );
break ;
2012-03-30 02:43:17 +02:00
case ENCOUNTER_FRAME_UPDATE_OBJECTIVE :
2011-01-23 16:59:33 +01:00
data << uint8 ( param1 );
2012-03-30 02:43:17 +02:00
data << uint8 ( param2 );
2011-01-23 16:59:33 +01:00
break ;
2012-03-30 02:43:17 +02:00
case ENCOUNTER_FRAME_UNK7 :
2012-03-30 15:13:54 +02:00
case ENCOUNTER_FRAME_ADD_COMBAT_RES_LIMIT :
case ENCOUNTER_FRAME_RESET_COMBAT_RES_LIMIT :
2011-01-23 16:59:33 +01:00
default :
break ;
}
instance -> SendToPlayers ( & data );
}
2011-02-03 22:20:40 +01:00
2013-01-09 15:15:42 +01:00
void InstanceScript :: UpdateEncounterState ( EncounterCreditType type , uint32 creditEntry , Unit * /*source*/ )
2011-02-03 22:20:40 +01:00
{
DungeonEncounterList const * encounters = sObjectMgr -> GetDungeonEncounterList ( instance -> GetId (), instance -> GetDifficulty ());
if ( ! encounters )
return ;
2013-01-09 15:15:42 +01:00
uint32 dungeonId = 0 ;
2011-02-03 22:20:40 +01:00
for ( DungeonEncounterList :: const_iterator itr = encounters -> begin (); itr != encounters -> end (); ++ itr )
{
2013-01-09 15:15:42 +01:00
DungeonEncounter const * encounter = * itr ;
if ( encounter -> creditType == type && encounter -> creditEntry == creditEntry )
2011-02-03 22:20:40 +01:00
{
2014-11-08 19:26:20 +02:00
completedEncounters |= 1 << encounter -> dbcEntry -> OrderIndex ;
2013-01-09 15:15:42 +01:00
if ( encounter -> lastEncounterDungeon )
2011-02-03 22:20:40 +01:00
{
2013-01-09 15:15:42 +01:00
dungeonId = encounter -> lastEncounterDungeon ;
2014-11-08 19:26:20 +02:00
TC_LOG_DEBUG ( "lfg" , "UpdateEncounterState: Instance %s (instanceId %u) completed encounter %s. Credit Dungeon: %u" , instance -> GetMapName (), instance -> GetInstanceId (), encounter -> dbcEntry -> Name_lang , dungeonId );
2013-01-09 15:15:42 +01:00
break ;
2011-02-03 22:20:40 +01:00
}
2013-01-09 15:15:42 +01:00
}
}
if ( dungeonId )
{
Map :: PlayerList const & players = instance -> GetPlayers ();
for ( Map :: PlayerList :: const_iterator i = players . begin (); i != players . end (); ++ i )
{
2013-06-11 21:25:12 -02:30
if ( Player * player = i -> GetSource ())
2013-01-09 15:15:42 +01:00
if ( Group * grp = player -> GetGroup ())
if ( grp -> isLFGGroup ())
{
sLFGMgr -> FinishDungeon ( grp -> GetGUID (), dungeonId );
return ;
}
2011-02-03 22:20:40 +01:00
}
}
}
2012-09-26 17:46:00 +02:00
void InstanceScript :: UpdatePhasing ()
{
Map :: PlayerList const & players = instance -> GetPlayers ();
for ( Map :: PlayerList :: const_iterator itr = players . begin (); itr != players . end (); ++ itr )
2013-06-13 19:35:01 +02:00
if ( Player * player = itr -> GetSource ())
2014-06-03 13:08:54 -05:00
player -> UpdatePhasing ();
2012-09-26 17:46:00 +02:00
}