TaxiHandler.cpp
上传用户:jxpjxmjjw
上传日期:2009-12-07
资源大小:5877k
文件大小:9k
源码类别:

模拟服务器

开发平台:

Visual C++

  1. // Copyright (C) 2004 Team Python //   // 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, write to the Free Software  // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "TaxiHandler.h" #include "NetworkInterface.h" #include "Log.h" #include "Opcodes.h" #include "GameClient.h" #include "Character.h" #include "UpdateMask.h" #include "WorldServer.h" #include "Path.h" #include "DatabaseInterface.h" #include "Database.h" #include "math.h" // npcs have a taxi element // how about when the npc is created it uses the database to find the nearest taxi and set it // when the npc is clicked for now we use the database to display available waypoints // when the taxi is started, we know the starting node and the ending node. //   we use the database or a cache to find the path, utilizing two tables. #define world WorldServer::getSingleton( ) TaxiHandler::TaxiHandler( ) { } TaxiHandler::~TaxiHandler( ) { } void TaxiHandler::HandleMsg( wowWData & recv_data, GameClient *pClient ) {     wowWData data;     char f[ 256 ];     sprintf( f, "WORLD: Taxi Opcode 0x%.4X", recv_data.opcode ); int CharZone; CharZone=pClient->getCurrentChar( )->getZone();     Log::getSingleton( ).outString( f );     switch( recv_data.opcode ) {         case CMSG_TAXINODE_STATUS_QUERY:             {                 Log::getSingleton( ).outString( "WORLD: Recieved CMSG_TAXINODE_STATUS_QUERY" );                 uint32 guid1, guid2;                 recv_data >> guid1 >> guid2;                 data.Initialise( 9, SMSG_TAXINODE_STATUS );                 data << guid1 << guid2 << uint8( 0 );                 pClient->SendMsg( &data );                 Log::getSingleton( ).outString( "WORLD: Sent SMSG_TAXINODE_STATUS" );             }break;         case CMSG_TAXIQUERYAVAILABLENODES:             {                 Log::getSingleton( ).outString( "WORLD: Recieved CMSG_TAXIQUERYAVAILABLENODES" );                 uint32 guid1, guid2;                 recv_data >> guid1 >> guid2;                 data.Initialise( 32, SMSG_SHOWTAXINODES );                                  DatabaseInterface *dbi = Database::getSingleton( ).createDatabaseInterface( );                 uint32 curloc = dbi->getNearestTaxiNode(                      pClient->getCurrentChar( )->getPositionX( ),                     pClient->getCurrentChar( )->getPositionY( ),                     pClient->getCurrentChar( )->getPositionZ( ), pClient->getCurrentChar( )->getMapId( ) );                 data << uint32( 1 ) << guid1 << guid2;                 // current location: 0x0c is darkshire... 0x02 is stormwind                 data << uint32( curloc );    uint32 TaxiMask = dbi->getGlobalTaxiNodeMask( curloc );                 //uint32 TaxiMask = dbi->getGlobalTaxiNodeMask(  ); // a uint64 representing places on the map that have prices, same format as next uint64               data << ( TaxiMask | (1<<(curloc-1)) ) << uint32(0);                 // a uint64 representing the map.  Each bit is a visible location -- smallest bit is location #1, etc. data << ( TaxiMask | (1<<(curloc-1)) ) << uint32(0);                 Database::getSingleton( ).removeDatabaseInterface( dbi ); //data << uint32( 0 );                 pClient->SendMsg( &data );                 Log::getSingleton( ).outString( "WORLD: Sent SMSG_SHOWTAXINODES" );             }break;         case CMSG_ACTIVATETAXI:             { uint16 MountId; /* 0.8.0 zones if ((CharZone == 141) || (CharZone == 141) || (CharZone == 331) || (CharZone == 357)) MountId = 479; //Hypogryphon else if ((CharZone == 400) || (CharZone == 17) || (CharZone == 406) || (CharZone == 215) || (CharZone == 14) || (CharZone == 3)) MountId = 295; // Wyvern else if ((CharZone == 85) || (CharZone == 130) || (CharZone == 267) || (CharZone == 40) || (CharZone == 10)) MountId = 1566; // Bat */ //looks like different places has same zoneId (like undercity sometime has 10 and duskwood) that fucks up with mounting system :/ // 0.9.1 zones if ((CharZone == 141) || (CharZone == 148) || (CharZone == 331) || (CharZone == 357)) MountId = 479; //Hypogryphon else if ((CharZone == 45) || (CharZone == 3) || (CharZone == 33) || (CharZone == 14) || (CharZone == 17) || (CharZone == 215) || (CharZone == 1638) || (CharZone == 406) || (CharZone == 400)) MountId = 295; // Wyvern else if ((CharZone == 10) || (CharZone == 267) || (CharZone == 1497) || (CharZone == 12) || (CharZone == 130)) MountId = 1566; // Bat else MountId = 1147; // Gryphon Log::getSingleton( ).outString( "WORLD: Recieved CMSG_ACTIVATETAXI" );                 uint32 guid1, guid2, sourcenode, destinationnode;                 recv_data >> guid1 >> guid2 >> sourcenode >> destinationnode;                 // can't taxi if frozen for now, fixes bug when you double-click a node if( pClient->getCurrentChar( )->getUpdateValue( UNIT_FIELD_FLAGS ) & 0x4 )                     break;                 DatabaseInterface *dbi = Database::getSingleton( ).createDatabaseInterface( );                 uint32 path = dbi->getPath( sourcenode, destinationnode ); uint32 price = dbi->getTaxiPrice( sourcenode, destinationnode );                 Path pathnodes;                 dbi->getPathNodes( path, &pathnodes );                 Database::getSingleton( ).removeDatabaseInterface( dbi ); uint32 player_gold = pClient->getCurrentChar( )->getUpdateValue( PLAYER_FIELD_COINAGE ); if(player_gold >= (uint32)price) { pClient->getCurrentChar( )->setUpdateValue( PLAYER_FIELD_COINAGE, player_gold-price ); data.Initialise( 4, SMSG_ACTIVATETAXIREPLY ); data << uint32( 0 ); pClient->SendMsg( &data ); Log::getSingleton( ).outString( "WORLD: Sent SMSG_ACTIVATETAXIREPLY" ); // first create the mount pClient->getCurrentChar( )->addUnitFlag( 0x001000 ); pClient->getCurrentChar( )->addUnitFlag( 0x000004 ); pClient->getCurrentChar( )->setUpdateValue( UNIT_FIELD_MOUNTDISPLAYID, MountId ); pClient->getCurrentChar( )->UpdateObject( ); // now mount it.  this must be done separately for it to animate while moving for some reason. pClient->getCurrentChar( )->addUnitFlag( 0x002000 ); //                pClient->getCurrentChar( )->UpdateObject( );                 // 0x001000 seems to make a mount visible             // 0x002000 seems to make you sit on the mount, and the mount move with you         // 0x100000 ??      // 0x000004 locks you so you can't move, no msg_move updates are sent to the server // 0x000008 seems to enable detailed collision checking     data.Initialise( /*229*/37 + pathnodes.getLength( ) * 4 * 3, SMSG_MONSTER_MOVE );         data << pClient->getCurrentChar( )->getGUID( ) << uint32( 0 );             //data << (float)-10514.92 << (float)-1260.089 << (float)41.38442; // starting location;                 data << pClient->getCurrentChar( )->getPositionX( )  << pClient->getCurrentChar( )->getPositionY( )      << pClient->getCurrentChar( )->getPositionZ( );     data << pClient->getCurrentChar( )->getOrientation( );         data << uint8( 0 ); // dunno             data << uint32( 0x00000300 ); // flags?                 uint32 traveltime = uint32(pathnodes.getTotalLength( ) * 32); // 36.7407 data << uint32( traveltime ); // total travel time     data << uint32( pathnodes.getLength( ) ); // number of spline points         //pClient->getCurrentChar( )->setPosition( pathnodes.getNodes( )[ pathnodes.getLength( ) - 1 ].x, pathnodes.getNodes( )[ pathnodes.getLength( ) - 1 ].y, pathnodes.getNodes( )[ pathnodes.getLength( ) - 1 ].z, true );             data.writeData( pathnodes.getNodes( ), pathnodes.getLength( ) * 4 * 3 ); //                pClient->getCurrentChar()->SendMessageToSet(&data, true); //                world.SendZoneMessage(&data, pClient, 1);                 world.SendAreaMessage(&data, pClient, 1); pClient->getCurrentChar()->setTaxiTime((uint32)time(NULL)+(traveltime)/1000); pClient->getCurrentChar()->setTaxiNode(destinationnode); } else { ChatHandler pChat;
  2. pChat.FillMessageData(&data, 0x09, pClient, (uint8*)"You don't have enought money to travel");
  3. pClient->SendMsg(&data);
  4. } }break;     } }