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

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

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

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