2008-10-02 16:23:55 -05:00
/*
2009-02-04 12:42:26 +01:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
2008-10-14 11:57:03 -05:00
*
2009-02-04 12:04:12 +01:00
* Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
2008-10-02 16:23:55 -05: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
2008-10-14 11:57:03 -05:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2008-10-02 16:23:55 -05:00
* 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, write to the Free Software
2008-10-14 11:57:03 -05:00
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-10-02 16:23:55 -05:00
*/
#include "Common.h"
#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Opcodes.h"
#include "Log.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "UpdateMask.h"
#include "Path.h"
#include "WaypointMovementGenerator.h"
#include "DestinationHolderImp.h"
void WorldSession :: HandleTaxiNodeStatusQueryOpcode ( WorldPacket & recv_data )
{
sLog . outDebug ( "WORLD: Received CMSG_TAXINODE_STATUS_QUERY" );
uint64 guid ;
recv_data >> guid ;
SendTaxiStatus ( guid );
}
void WorldSession :: SendTaxiStatus ( uint64 guid )
{
// cheating checks
2009-04-20 20:28:19 -05:00
Creature * unit = GetPlayer () -> GetMap () -> GetCreature ( guid );
2008-10-02 16:23:55 -05:00
if ( ! unit )
{
sLog . outDebug ( "WorldSession::SendTaxiStatus - Unit (GUID: %u) not found." , uint32 ( GUID_LOPART ( guid )) );
return ;
}
2009-01-21 16:18:57 -06:00
uint32 curloc = objmgr . GetNearestTaxiNode ( unit -> GetPositionX (), unit -> GetPositionY (), unit -> GetPositionZ (), unit -> GetMapId (), GetPlayer ( ) -> GetTeam ());
2008-10-02 16:23:55 -05:00
// not found nearest
if ( curloc == 0 )
return ;
sLog . outDebug ( "WORLD: current location %u " , curloc );
WorldPacket data ( SMSG_TAXINODE_STATUS , 9 );
data << guid ;
data << uint8 ( GetPlayer ( ) -> m_taxi . IsTaximaskNodeKnown ( curloc ) ? 1 : 0 );
SendPacket ( & data );
sLog . outDebug ( "WORLD: Sent SMSG_TAXINODE_STATUS" );
}
2008-12-24 09:58:26 -06:00
void WorldSession :: HandleTaxiQueryAvailableNodes ( WorldPacket & recv_data )
2008-10-02 16:23:55 -05:00
{
sLog . outDebug ( "WORLD: Received CMSG_TAXIQUERYAVAILABLENODES" );
uint64 guid ;
recv_data >> guid ;
// cheating checks
2009-04-19 18:23:10 -05:00
Creature * unit = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_FLIGHTMASTER );
2008-10-02 16:23:55 -05:00
if ( ! unit )
{
2008-12-12 11:21:28 -06:00
sLog . outDebug ( "WORLD: HandleTaxiQueryAvailableNodes - Unit (GUID: %u) not found or you can't interact with him." , uint32 ( GUID_LOPART ( guid )) );
2008-10-02 16:23:55 -05:00
return ;
}
// remove fake death
if ( GetPlayer () -> hasUnitState ( UNIT_STAT_DIED ))
2009-04-06 13:31:14 +02:00
GetPlayer () -> RemoveAurasByType ( SPELL_AURA_FEIGN_DEATH );
2008-10-02 16:23:55 -05:00
// unknown taxi node case
if ( SendLearnNewTaxiNode ( unit ) )
return ;
// known taxi node case
SendTaxiMenu ( unit );
}
void WorldSession :: SendTaxiMenu ( Creature * unit )
{
// find current node
2009-01-21 16:18:57 -06:00
uint32 curloc = objmgr . GetNearestTaxiNode ( unit -> GetPositionX (), unit -> GetPositionY (), unit -> GetPositionZ (), unit -> GetMapId (), GetPlayer ( ) -> GetTeam ());
2008-10-02 16:23:55 -05:00
if ( curloc == 0 )
return ;
2009-08-31 01:15:09 -07:00
bool lastTaxiCheaterState = GetPlayer () -> isTaxiCheater ();
if ( unit -> GetEntry () == 29480 ) GetPlayer () -> SetTaxiCheater ( true ); // Grimwing in Ebon Hold, special case. NOTE: Not perfect, Zul'Aman should not be included according to WoWhead, and I think taxicheat includes it.
2008-10-02 16:23:55 -05:00
sLog . outDebug ( "WORLD: CMSG_TAXINODE_STATUS_QUERY %u " , curloc );
WorldPacket data ( SMSG_SHOWTAXINODES , ( 4 + 8 + 4 + 8 * 4 ) );
data << uint32 ( 1 );
data << uint64 ( unit -> GetGUID () );
data << uint32 ( curloc );
GetPlayer () -> m_taxi . AppendTaximaskTo ( data , GetPlayer () -> isTaxiCheater ());
SendPacket ( & data );
sLog . outDebug ( "WORLD: Sent SMSG_SHOWTAXINODES" );
2009-08-31 01:15:09 -07:00
GetPlayer () -> SetTaxiCheater ( lastTaxiCheaterState );
2008-10-02 16:23:55 -05:00
}
2009-06-15 18:02:12 -05:00
void WorldSession :: SendDoFlight ( uint32 mountDisplayId , uint32 path , uint32 pathNode )
2008-10-02 16:23:55 -05:00
{
// remove fake death
2009-06-15 18:02:12 -05:00
if ( GetPlayer () -> hasUnitState ( UNIT_STAT_DIED ))
2009-04-06 13:31:14 +02:00
GetPlayer () -> RemoveAurasByType ( SPELL_AURA_FEIGN_DEATH );
2008-10-02 16:23:55 -05:00
while ( GetPlayer () -> GetMotionMaster () -> GetCurrentMovementGeneratorType () == FLIGHT_MOTION_TYPE )
GetPlayer () -> GetMotionMaster () -> MovementExpired ( false );
2009-06-15 18:02:12 -05:00
if ( mountDisplayId )
GetPlayer () -> Mount ( mountDisplayId );
2008-10-02 16:23:55 -05:00
GetPlayer () -> GetMotionMaster () -> MoveTaxiFlight ( path , pathNode );
}
bool WorldSession :: SendLearnNewTaxiNode ( Creature * unit )
{
// find current node
2009-01-21 16:18:57 -06:00
uint32 curloc = objmgr . GetNearestTaxiNode ( unit -> GetPositionX (), unit -> GetPositionY (), unit -> GetPositionZ (), unit -> GetMapId (), GetPlayer ( ) -> GetTeam ());
2008-10-02 16:23:55 -05:00
if ( curloc == 0 )
return true ; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
if ( GetPlayer () -> m_taxi . SetTaximaskNode ( curloc ) )
{
WorldPacket msg ( SMSG_NEW_TAXI_PATH , 0 );
SendPacket ( & msg );
WorldPacket update ( SMSG_TAXINODE_STATUS , 9 );
update << uint64 ( unit -> GetGUID () );
update << uint8 ( 1 );
SendPacket ( & update );
return true ;
}
else
return false ;
}
2009-05-31 15:56:51 -05:00
void WorldSession :: HandleActivateTaxiExpressOpcode ( WorldPacket & recv_data )
2008-10-02 16:23:55 -05:00
{
sLog . outDebug ( "WORLD: Received CMSG_ACTIVATETAXIEXPRESS" );
uint64 guid ;
uint32 node_count , _totalcost ;
recv_data >> guid >> _totalcost >> node_count ;
2009-04-19 18:23:10 -05:00
Creature * npc = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_FLIGHTMASTER );
2008-10-02 16:23:55 -05:00
if ( ! npc )
{
2009-05-31 15:56:51 -05:00
sLog . outDebug ( "WORLD: HandleActivateTaxiExpressOpcode - Unit (GUID: %u) not found or you can't interact with it." , uint32 ( GUID_LOPART ( guid )) );
2008-10-02 16:23:55 -05:00
return ;
}
std :: vector < uint32 > nodes ;
for ( uint32 i = 0 ; i < node_count ; ++ i )
{
uint32 node ;
recv_data >> node ;
nodes . push_back ( node );
}
if ( nodes . empty ())
return ;
sLog . outDebug ( "WORLD: Received CMSG_ACTIVATETAXIEXPRESS from %d to %d" , nodes . front (), nodes . back ());
2009-05-08 18:52:12 -05:00
GetPlayer () -> ActivateTaxiPathTo ( nodes , npc );
2008-10-02 16:23:55 -05:00
}
2009-05-31 15:56:51 -05:00
void WorldSession :: HandleMoveSplineDoneOpcode ( WorldPacket & /*recv_data*/ )
2008-10-02 16:23:55 -05:00
{
sLog . outDebug ( "WORLD: Received CMSG_MOVE_SPLINE_DONE" );
// in taxi flight packet received in 2 case:
// 1) end taxi path in far (multi-node) flight
// 2) switch from one map to other in case multim-map taxi path
2008-11-14 16:28:45 -06:00
// we need process only (1)
2008-10-02 16:23:55 -05:00
uint32 curDest = GetPlayer () -> m_taxi . GetTaxiDestination ();
if ( ! curDest )
return ;
TaxiNodesEntry const * curDestNode = sTaxiNodesStore . LookupEntry ( curDest );
// far teleport case
if ( curDestNode && curDestNode -> map_id != GetPlayer () -> GetMapId ())
{
if ( GetPlayer () -> GetMotionMaster () -> GetCurrentMovementGeneratorType () == FLIGHT_MOTION_TYPE )
{
// short preparations to continue flight
FlightPathMovementGenerator * flight = ( FlightPathMovementGenerator * )( GetPlayer () -> GetMotionMaster () -> top ());
flight -> SetCurrentNodeAfterTeleport ();
Path :: PathNode const & node = flight -> GetPath ()[ flight -> GetCurrentNode ()];
flight -> SkipCurrentNode ();
GetPlayer () -> TeleportTo ( curDestNode -> map_id , node . x , node . y , node . z , GetPlayer () -> GetOrientation ());
}
return ;
}
uint32 destinationnode = GetPlayer () -> m_taxi . NextTaxiDestination ();
if ( destinationnode > 0 ) // if more destinations to go
{
// current source node for next destination
uint32 sourcenode = GetPlayer () -> m_taxi . GetTaxiSource ();
// Add to taximask middle hubs in taxicheat mode (to prevent having player with disabled taxicheat and not having back flight path)
if ( GetPlayer () -> isTaxiCheater ())
{
if ( GetPlayer () -> m_taxi . SetTaximaskNode ( sourcenode ))
{
WorldPacket data ( SMSG_NEW_TAXI_PATH , 0 );
_player -> GetSession () -> SendPacket ( & data );
}
}
sLog . outDebug ( "WORLD: Taxi has to go from %u to %u" , sourcenode , destinationnode );
2009-06-15 18:02:12 -05:00
uint32 mountDisplayId = objmgr . GetTaxiMountDisplayId ( sourcenode , GetPlayer () -> GetTeam ());
2008-10-02 16:23:55 -05:00
uint32 path , cost ;
objmgr . GetTaxiPath ( sourcenode , destinationnode , path , cost );
2009-06-15 18:02:12 -05:00
if ( path && mountDisplayId )
SendDoFlight ( mountDisplayId , path , 1 ); // skip start fly node
else
GetPlayer () -> m_taxi . ClearTaxiDestinations (); // clear problematic path and next
2009-06-24 00:12:09 +02:00
return ;
2008-10-02 16:23:55 -05:00
}
2009-07-01 16:18:37 +02:00
GetPlayer () -> CleanupAfterTaxiFlight ();
2009-05-20 20:39:55 -05:00
GetPlayer () -> SetFallInformation ( 0 , GetPlayer () -> GetPositionZ ());
if ( GetPlayer () -> pvpInfo . inHostileArea )
GetPlayer () -> CastSpell ( GetPlayer (), 2479 , true );
2008-10-02 16:23:55 -05:00
}
void WorldSession :: HandleActivateTaxiOpcode ( WorldPacket & recv_data )
{
sLog . outDebug ( "WORLD: Received CMSG_ACTIVATETAXI" );
uint64 guid ;
std :: vector < uint32 > nodes ;
nodes . resize ( 2 );
recv_data >> guid >> nodes [ 0 ] >> nodes [ 1 ];
sLog . outDebug ( "WORLD: Received CMSG_ACTIVATETAXI from %d to %d" , nodes [ 0 ], nodes [ 1 ]);
2009-04-19 18:23:10 -05:00
Creature * npc = GetPlayer () -> GetNPCIfCanInteractWith ( guid , UNIT_NPC_FLAG_FLIGHTMASTER );
2008-10-02 16:23:55 -05:00
if ( ! npc )
{
sLog . outDebug ( "WORLD: HandleActivateTaxiOpcode - Unit (GUID: %u) not found or you can't interact with it." , uint32 ( GUID_LOPART ( guid )) );
return ;
}
2009-05-08 18:52:12 -05:00
GetPlayer () -> ActivateTaxiPathTo ( nodes , npc );
2008-10-02 16:23:55 -05:00
}
2009-02-17 20:07:49 -06:00