TaxiHandler.cpp
资源名称:wow.rar [点击查看]
上传用户:jxpjxmjjw
上传日期:2009-12-07
资源大小:5877k
文件大小:9k
源码类别:
模拟服务器
开发平台:
Visual C++
- // 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;
- pChat.FillMessageData(&data, 0x09, pClient, (uint8*)"You don't have enought money to travel");
- pClient->SendMsg(&data);
- } }break; } }