root/trunk/src/game/TaxiHandler.cpp @ 229

Revision 229, 9.0 kB (checked in by yumileroy, 17 years ago)

[svn] *** Source: MaNGOS ***
* Fixed build extractor at Windows Vista. Author: Vladimir
* Fixed comment text and code indentifiers spelling. Author: Vladimir & Paradox.
* Access cached member lists in guild handlers instead of querying the DB. Author: Hunuza
* Small fixes in send/received packet and simple code cleanup also. Author: Vladimir
* Not output error at loading empty character_ticket table. Author: Vladimir
* Not reset display model at shapeshift aura remove if it not set at apply. Author: Arthorius
* Applied props to few files.

Original author: visagalis
Date: 2008-11-14 16:28:45-06:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "Common.h"
22#include "Database/DatabaseEnv.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25#include "Opcodes.h"
26#include "Log.h"
27#include "World.h"
28#include "ObjectMgr.h"
29#include "Player.h"
30#include "UpdateMask.h"
31#include "Path.h"
32#include "WaypointMovementGenerator.h"
33#include "DestinationHolderImp.h"
34
35#include <cassert>
36
37void WorldSession::HandleTaxiNodeStatusQueryOpcode( WorldPacket & recv_data )
38{
39    CHECK_PACKET_SIZE(recv_data,8);
40
41    sLog.outDebug( "WORLD: Received CMSG_TAXINODE_STATUS_QUERY" );
42
43    uint64 guid;
44
45    recv_data >> guid;
46    SendTaxiStatus( guid );
47}
48
49void WorldSession::SendTaxiStatus( uint64 guid )
50{
51    // cheating checks
52    Creature *unit = ObjectAccessor::GetCreature(*_player, guid);
53    if (!unit)
54    {
55        sLog.outDebug( "WorldSession::SendTaxiStatus - Unit (GUID: %u) not found.", uint32(GUID_LOPART(guid)) );
56        return;
57    }
58
59    uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId());
60
61    // not found nearest
62    if(curloc == 0)
63        return;
64
65    sLog.outDebug( "WORLD: current location %u ",curloc);
66
67    WorldPacket data( SMSG_TAXINODE_STATUS, 9 );
68    data << guid;
69    data << uint8( GetPlayer( )->m_taxi.IsTaximaskNodeKnown(curloc) ? 1 : 0 );
70    SendPacket( &data );
71    sLog.outDebug( "WORLD: Sent SMSG_TAXINODE_STATUS" );
72}
73
74void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data )
75{
76    CHECK_PACKET_SIZE(recv_data,8);
77
78    sLog.outDebug( "WORLD: Received CMSG_TAXIQUERYAVAILABLENODES" );
79
80    uint64 guid;
81    recv_data >> guid;
82
83    // cheating checks
84    Creature *unit = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER);
85    if (!unit)
86    {
87        sLog.outDebug( "WORLD: HandleTaxiQueryAvailableNodesOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
88        return;
89    }
90
91    // remove fake death
92    if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
93        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
94
95    // unknown taxi node case
96    if( SendLearnNewTaxiNode(unit) )
97        return;
98
99    // known taxi node case
100    SendTaxiMenu( unit );
101}
102
103void WorldSession::SendTaxiMenu( Creature* unit )
104{
105    // find current node
106    uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId());
107
108    if ( curloc == 0 )
109        return;
110
111    sLog.outDebug( "WORLD: CMSG_TAXINODE_STATUS_QUERY %u ",curloc);
112
113    WorldPacket data( SMSG_SHOWTAXINODES, (4+8+4+8*4) );
114    data << uint32( 1 );
115    data << uint64( unit->GetGUID() );
116    data << uint32( curloc );
117    GetPlayer()->m_taxi.AppendTaximaskTo(data,GetPlayer()->isTaxiCheater());
118    SendPacket( &data );
119
120    sLog.outDebug( "WORLD: Sent SMSG_SHOWTAXINODES" );
121}
122
123void WorldSession::SendDoFlight( uint16 MountId, uint32 path, uint32 pathNode )
124{
125    // remove fake death
126    if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
127        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
128
129    while(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE)
130        GetPlayer()->GetMotionMaster()->MovementExpired(false);
131
132    GetPlayer()->Mount( MountId );
133    GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path,pathNode);
134}
135
136bool WorldSession::SendLearnNewTaxiNode( Creature* unit )
137{
138    // find current node
139    uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId());
140
141    if ( curloc == 0 )
142        return true;                                        // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
143
144    if( GetPlayer()->m_taxi.SetTaximaskNode(curloc) )
145    {
146        WorldPacket msg(SMSG_NEW_TAXI_PATH, 0);
147        SendPacket( &msg );
148
149        WorldPacket update( SMSG_TAXINODE_STATUS, 9 );
150        update << uint64( unit->GetGUID() );
151        update << uint8( 1 );
152        SendPacket( &update );
153
154        return true;
155    }
156    else
157        return false;
158}
159
160void WorldSession::HandleActivateTaxiFarOpcode ( WorldPacket & recv_data )
161{
162    CHECK_PACKET_SIZE(recv_data,8+4+4);
163
164    sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXIEXPRESS" );
165
166    uint64 guid;
167    uint32 node_count, _totalcost;
168
169    recv_data >> guid >> _totalcost >> node_count;
170
171    Creature *npc = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER);
172    if (!npc)
173    {
174        sLog.outDebug( "WORLD: HandleActivateTaxiFarOpcode - Unit (GUID: %u) not found or you can't interact with it.", uint32(GUID_LOPART(guid)) );
175        return;
176    }
177    // recheck
178    CHECK_PACKET_SIZE(recv_data,8+4+4+node_count*4);
179
180    std::vector<uint32> nodes;
181
182    for(uint32 i = 0; i < node_count; ++i)
183    {
184        uint32 node;
185        recv_data >> node;
186        nodes.push_back(node);
187    }
188
189    if(nodes.empty())
190        return;
191
192    sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXIEXPRESS from %d to %d" ,nodes.front(),nodes.back());
193
194    GetPlayer()->ActivateTaxiPathTo(nodes, 0, npc);
195}
196
197void WorldSession::HandleTaxiNextDestinationOpcode(WorldPacket& /*recv_data*/)
198{
199    sLog.outDebug( "WORLD: Received CMSG_MOVE_SPLINE_DONE" );
200
201    // in taxi flight packet received in 2 case:
202    // 1) end taxi path in far (multi-node) flight
203    // 2) switch from one map to other in case multim-map taxi path
204    // we need process only (1)
205    uint32 curDest = GetPlayer()->m_taxi.GetTaxiDestination();
206    if(!curDest)
207        return;
208
209    TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
210
211    // far teleport case
212    if(curDestNode && curDestNode->map_id != GetPlayer()->GetMapId())
213    {
214        if(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE)
215        {
216            // short preparations to continue flight
217            FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top());
218
219            flight->SetCurrentNodeAfterTeleport();
220            Path::PathNode const& node = flight->GetPath()[flight->GetCurrentNode()];
221            flight->SkipCurrentNode();
222
223            GetPlayer()->TeleportTo(curDestNode->map_id,node.x,node.y,node.z,GetPlayer()->GetOrientation());
224        }
225        return;
226    }
227
228    uint32 destinationnode = GetPlayer()->m_taxi.NextTaxiDestination();
229    if ( destinationnode > 0 )                              // if more destinations to go
230    {
231        // current source node for next destination
232        uint32 sourcenode = GetPlayer()->m_taxi.GetTaxiSource();
233
234        // Add to taximask middle hubs in taxicheat mode (to prevent having player with disabled taxicheat and not having back flight path)
235        if (GetPlayer()->isTaxiCheater())
236        {
237            if(GetPlayer()->m_taxi.SetTaximaskNode(sourcenode))
238            {
239                WorldPacket data(SMSG_NEW_TAXI_PATH, 0);
240                _player->GetSession()->SendPacket( &data );
241            }
242        }
243
244        sLog.outDebug( "WORLD: Taxi has to go from %u to %u", sourcenode, destinationnode );
245
246        uint16 MountId = objmgr.GetTaxiMount(sourcenode, GetPlayer()->GetTeam());
247
248        uint32 path, cost;
249        objmgr.GetTaxiPath( sourcenode, destinationnode, path, cost);
250
251        if(path && MountId)
252            SendDoFlight( MountId, path, 1 );               // skip start fly node
253        else
254            GetPlayer()->m_taxi.ClearTaxiDestinations();    // clear problematic path and next
255    }
256    else
257        GetPlayer()->m_taxi.ClearTaxiDestinations();        // not destinations, clear source node
258}
259
260void WorldSession::HandleActivateTaxiOpcode( WorldPacket & recv_data )
261{
262    CHECK_PACKET_SIZE(recv_data,8+4+4);
263
264    sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXI" );
265
266    uint64 guid;
267    std::vector<uint32> nodes;
268    nodes.resize(2);
269
270    recv_data >> guid >> nodes[0] >> nodes[1];
271    sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXI from %d to %d" ,nodes[0],nodes[1]);
272    Creature *npc = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_FLIGHTMASTER);
273    if (!npc)
274    {
275        sLog.outDebug( "WORLD: HandleActivateTaxiOpcode - Unit (GUID: %u) not found or you can't interact with it.", uint32(GUID_LOPART(guid)) );
276        return;
277    }
278
279    GetPlayer()->ActivateTaxiPathTo(nodes, 0, npc);
280}
Note: See TracBrowser for help on using the browser.