/*
* Ascent MMORPG Server
* Copyright (C) 2005-2007 Ascent Team
*
* 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 3 of the License, or
* 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 .
*
*/
#include "StdAfx.h"
void WorldSession::HandleTaxiNodeStatusQueryOpcode( WorldPacket & recv_data )
{
if(!_player->IsInWorld()) return;
sLog.outDebug( "WORLD: Received CMSG_TAXINODE_STATUS_QUERY" );
uint64 guid;
uint32 curloc;
uint8 field;
uint32 submask;
recv_data >> guid;
curloc = sTaxiMgr.GetNearestTaxiNode( GetPlayer( )->GetPositionX( ), GetPlayer( )->GetPositionY( ), GetPlayer( )->GetPositionZ( ), GetPlayer( )->GetMapId( ) );
field = (uint8)((curloc - 1) / 32);
submask = 1<<((curloc-1)%32);
WorldPacket data(9);
data.Initialize( SMSG_TAXINODE_STATUS );
data << guid;
// Check for known nodes
if ( (GetPlayer( )->GetTaximask(field) & submask) != submask )
{
data << uint8( 0 );
}
else
{
data << uint8( 1 );
}
SendPacket( &data );
sLog.outDebug( "WORLD: Sent SMSG_TAXINODE_STATUS" );
}
void WorldSession::HandleTaxiQueryAvaibleNodesOpcode( WorldPacket & recv_data )
{
if(!_player->IsInWorld()) return;
sLog.outDebug( "WORLD: Received CMSG_TAXIQUERYAVAILABLENODES" );
uint64 guid;
recv_data >> guid;
Creature *pCreature = _player->GetMapMgr()->GetCreature(guid);
if(!pCreature) return;
SendTaxiList(pCreature);
}
void WorldSession::SendTaxiList(Creature* pCreature)
{
uint32 curloc;
uint8 field;
uint32 TaxiMask[8];
uint32 submask;
uint64 guid = pCreature->GetGUID();
curloc = pCreature->m_TaxiNode;
if (!curloc)
return;
field = (uint8)((curloc - 1) / 32);
submask = 1<<((curloc-1)%32);
// Check for known nodes
if (!(GetPlayer( )->GetTaximask(field) & submask))
{
GetPlayer()->SetTaximask(field, (submask | GetPlayer( )->GetTaximask(field)) );
OutPacket(SMSG_NEW_TAXI_PATH);
//Send packet
WorldPacket update(SMSG_TAXINODE_STATUS, 9);
update << guid << uint8( 1 );
SendPacket( &update );
}
//Set Mask
memset(TaxiMask, 0, sizeof(uint32)*8);
sTaxiMgr.GetGlobalTaxiNodeMask(curloc, TaxiMask);
TaxiMask[field] |= 1 << ((curloc-1)%32);
//Remove nodes unknown to player
for(int i = 0; i < 8; i++)
{
TaxiMask[i] &= GetPlayer( )->GetTaximask(i);
}
WorldPacket data(48);
data.Initialize( SMSG_SHOWTAXINODES );
data << uint32( 1 ) << guid;
data << uint32( curloc );
for(int i = 0; i < 8; i++)
{
data << TaxiMask[i];
}
SendPacket( &data );
sLog.outDebug( "WORLD: Sent SMSG_SHOWTAXINODES" );
}
void WorldSession::HandleActivateTaxiOpcode( WorldPacket & recv_data )
{
if(!_player->IsInWorld()) return;
sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXI" );
uint64 guid;
uint32 sourcenode, destinationnode;
int32 newmoney;
uint32 curloc;
uint8 field;
uint32 submask;
WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
recv_data >> guid >> sourcenode >> destinationnode;
if( GetPlayer( )->GetUInt32Value( UNIT_FIELD_FLAGS ) & U_FIELD_FLAG_LOCK_PLAYER )
return;
TaxiPath* taxipath = sTaxiMgr.GetTaxiPath(sourcenode, destinationnode);
TaxiNode* taxinode = sTaxiMgr.GetTaxiNode(sourcenode);
curloc = taxinode->id;
field = (uint8)((curloc - 1) / 32);
submask = 1<<((curloc-1)%32);
// Check for known nodes
if ( (GetPlayer( )->GetTaximask(field) & submask) != submask )
{
data << uint32( 1 );
SendPacket( &data );
return;
}
// Check for valid node
if (!taxinode)
{
data << uint32( 1 );
SendPacket( &data );
return;
}
if (!taxipath || !taxipath->GetNodeCount())
{
data << uint32( 2 );
SendPacket( &data );
return;
}
// Check for gold
newmoney = ((GetPlayer()->GetUInt32Value(PLAYER_FIELD_COINAGE)) - taxipath->GetPrice());
if(newmoney < 0 )
{
data << uint32( 3 );
SendPacket( &data );
return;
}
// MOUNTDISPLAYID
// bat: 1566
// gryph: 1147
// wyvern: 295
// hippogryph: 479
uint32 modelid =0;
if( _player->GetTeam() )
{
if( taxinode->horde_mount == 2224 )
modelid =295; // In case it's a wyvern
else
modelid =1566; // In case it's a bat or a bad id
}
else
{
if( taxinode->alliance_mount == 3837 )
modelid =479; // In case it's an hippogryph
else
modelid =1147; // In case it's a gryphon or a bad id
}
//GetPlayer( )->setDismountCost( newmoney );
data << uint32( 0 );
// 0 Ok
// 1 Unspecified Server Taxi Error
// 2.There is no direct path to that direction
// 3 Not enough Money
SendPacket( &data );
sLog.outDebug( "WORLD: Sent SMSG_ACTIVATETAXIREPLY" );
// 0x001000 seems to make a mount visible
// 0x002000 seems to make you sit on the mount, and the mount move with you
// 0x000004 locks you so you can't move, no msg_move updates are sent to the server
// 0x000008 seems to enable detailed collision checking
// check for a summon -> if we do, remove.
if(_player->GetSummon() != NULL)
{
if(_player->GetSummon()->GetUInt32Value(UNIT_CREATED_BY_SPELL) > 0)
_player->GetSummon()->Dismiss(false); // warlock summon -> dismiss
else
_player->GetSummon()->Remove(false, true, true); // hunter pet -> just remove for later re-call
}
_player->taxi_model_id = modelid;
GetPlayer()->TaxiStart(taxipath, modelid, 0);
//sLog.outString("TAXI: Starting taxi trip. Next update in %d msec.", first_node_time);
}
void WorldSession::HandleMultipleActivateTaxiOpcode(WorldPacket & recvPacket)
{
if(!_player->IsInWorld()) return;
sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXI" );
uint64 guid;
uint32 moocost;
uint32 nodecount;
vector pathes;
int32 newmoney;
uint32 curloc;
uint8 field;
uint32 submask;
WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
recvPacket >> guid >> moocost >> nodecount;
if(nodecount < 2)
return;
for(uint32 i = 0; i < nodecount; ++i)
pathes.push_back( recvPacket.read() );
if( GetPlayer( )->GetUInt32Value( UNIT_FIELD_FLAGS ) & U_FIELD_FLAG_LOCK_PLAYER )
return;
// get first trip
TaxiPath* taxipath = sTaxiMgr.GetTaxiPath(pathes[0], pathes[1]);
TaxiNode* taxinode = sTaxiMgr.GetTaxiNode(pathes[0]);
curloc = taxinode->id;
field = (uint8)((curloc - 1) / 32);
submask = 1<<((curloc-1)%32);
// Check for known nodes
if ( (GetPlayer( )->GetTaximask(field) & submask) != submask )
{
data << uint32( 1 );
SendPacket( &data );
return;
}
// Check for valid node
if (!taxinode)
{
data << uint32( 1 );
SendPacket( &data );
return;
}
if (!taxipath || !taxipath->GetNodeCount())
{
data << uint32( 2 );
SendPacket( &data );
return;
}
// Check for gold
newmoney = ((GetPlayer()->GetUInt32Value(PLAYER_FIELD_COINAGE)) - taxipath->GetPrice());
if(newmoney < 0 )
{
data << uint32( 3 );
SendPacket( &data );
return;
}
// MOUNTDISPLAYID
// bat: 1566
// gryph: 1147
// wyvern: 295
// hippogryph: 479
uint32 modelid =0;
if( _player->GetTeam() )
{
if( taxinode->horde_mount == 2224 )
modelid =295; // In case it's a wyvern
else
modelid =1566; // In case it's a bat or a bad id
}
else
{
if( taxinode->alliance_mount == 3837 )
modelid =479; // In case it's an hippogryph
else
modelid =1147; // In case it's a gryphon or a bad id
}
//GetPlayer( )->setDismountCost( newmoney );
data << uint32( 0 );
// 0 Ok
// 1 Unspecified Server Taxi Error
// 2.There is no direct path to that direction
// 3 Not enough Money
SendPacket( &data );
sLog.outDebug( "WORLD: Sent SMSG_ACTIVATETAXIREPLY" );
// 0x001000 seems to make a mount visible
// 0x002000 seems to make you sit on the mount, and the mount move with you
// 0x000004 locks you so you can't move, no msg_move updates are sent to the server
// 0x000008 seems to enable detailed collision checking
// check for a summon -> if we do, remove.
if(_player->GetSummon() != NULL)
{
if(_player->GetSummon()->GetUInt32Value(UNIT_CREATED_BY_SPELL) > 0)
_player->GetSummon()->Dismiss(false); // warlock summon -> dismiss
else
_player->GetSummon()->Remove(false, true, true); // hunter pet -> just remove for later re-call
}
_player->taxi_model_id = modelid;
// build the rest of the path list
for(uint32 i = 2; i < nodecount; ++i)
{
TaxiPath * np = sTaxiMgr.GetTaxiPath(pathes[i-1], pathes[i]);
if(!np) return;
// add to the list.. :)
_player->m_taxiPaths.push_back(np);
}
// start the first trip :)
GetPlayer()->TaxiStart(taxipath, modelid, 0);
}