/* * 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" initialiseSingleton( TaxiMgr ); /************************ * TaxiPath * ************************/ void TaxiPath::ComputeLen() { m_length = 0; if (!m_pathNodes.size()) return; std::map::iterator itr; itr = m_pathNodes.begin(); float x = itr->second->x; float y = itr->second->y; float z = itr->second->z; itr++; while (itr != m_pathNodes.end()) { m_length += sqrt((itr->second->x - x)*(itr->second->x - x) + (itr->second->y - y)*(itr->second->y - y) + (itr->second->z - z)*(itr->second->z - z)); x = itr->second->x; y = itr->second->y; z = itr->second->z; itr++; } } void TaxiPath::SetPosForTime(float &x, float &y, float &z, uint32 time, uint32 *last_node) { if (!time) return; float traveled_len = (time/(getLength() * TAXI_TRAVEL_SPEED))*getLength(); uint32 len = 0; x = 0; y = 0; z = 0; if (!m_pathNodes.size()) return; std::map::iterator itr; itr = m_pathNodes.begin(); float nx = itr->second->x; float ny = itr->second->y; float nz = itr->second->z; uint32 nodecounter = 0; while (itr != m_pathNodes.end()) { len = (uint32)sqrt((itr->second->x - nx)*(itr->second->x - nx) + (itr->second->y - ny)*(itr->second->y - ny) + (itr->second->z - nz)*(itr->second->z - nz)); if (len >= traveled_len) { x = (itr->second->x - nx)*(traveled_len/len) + nx; y = (itr->second->y - ny)*(traveled_len/len) + ny; z = (itr->second->z - nz)*(traveled_len/len) + nz; *last_node = nodecounter; return; } else { traveled_len -= len; } nx = itr->second->x; ny = itr->second->y; nz = itr->second->z; itr++; nodecounter++; } x = nx; y = ny; z = nz; } TaxiPathNode* TaxiPath::GetPathNode(uint32 i) { if (m_pathNodes.find(i) == m_pathNodes.end()) return NULL; else return m_pathNodes.find(i)->second; } void TaxiPath::SendMoveForTime(Player *riding, Player *to, uint32 time) { if (!time) return; float traveled_len = (time/(getLength() * TAXI_TRAVEL_SPEED))*getLength();; uint32 len = 0, count = 0; float x = 0,y = 0,z = 0; if (!m_pathNodes.size()) return; std::map::iterator itr; itr = m_pathNodes.begin(); float nx = itr->second->x; float ny = itr->second->y; float nz = itr->second->z; itr++; while (itr != m_pathNodes.end()) { len = (uint32)sqrt((itr->second->x - nx)*(itr->second->x - nx) + (itr->second->y - ny)*(itr->second->y - ny) + (itr->second->z - nz)*(itr->second->z - nz)); if (len > traveled_len) { x = (itr->second->x - nx)*(traveled_len/len) + nx; y = (itr->second->y - ny)*(traveled_len/len) + ny; z = (itr->second->z - nz)*(traveled_len/len) + nz; break; } else { traveled_len -= len; } nx = itr->second->x; ny = itr->second->y; nz = itr->second->z; itr++; count++; } if (itr == m_pathNodes.end()) return; WorldPacket * data = new WorldPacket(SMSG_MONSTER_MOVE, 2000); *data << riding->GetNewGUID(); *data << riding->GetPositionX( ) << riding->GetPositionY( ) << riding->GetPositionZ( ); *data << getMSTime(); *data << uint8( 0 ); *data << uint32( 0x00000300 ); *data << uint32( uint32((getLength() * TAXI_TRAVEL_SPEED) - time)); *data << uint32( GetNodeCount() - count ); *data << nx << ny << nz; while (itr != m_pathNodes.end()) { TaxiPathNode *pn = itr->second; *data << pn->x << pn->y << pn->z; itr++; } //to->GetSession()->SendPacket(&data); to->delayedPackets.add(data); } /*********************** * TaxiMgr * ***********************/ void TaxiMgr::_LoadTaxiNodes() { uint32 i; for(i = 0; i < sTaxiNodeStore.GetNumRows(); i++) { DBCTaxiNode *node = sTaxiNodeStore.LookupEntry(i); if (node) { TaxiNode *n = new TaxiNode; n->id = node->id; n->mapid = node->mapid; n->alliance_mount = node->alliance_mount; n->horde_mount = node->horde_mount; n->x = node->x; n->y = node->y; n->z = node->z; this->m_taxiNodes.insert(std::map::value_type(n->id, n)); } } //todo: load mounts } void TaxiMgr::_LoadTaxiPaths() { uint32 i, j; for(i = 0; i < sTaxiPathStore.GetNumRows(); i++) { DBCTaxiPath *path = sTaxiPathStore.LookupEntry(i); if (path) { TaxiPath *p = new TaxiPath; p->from = path->from; p->to = path->to; p->id = path->id; p->price = path->price; //Load Nodes for(j = 0; j < sTaxiPathNodeStore.GetNumRows(); j++) { DBCTaxiPathNode *pathnode = sTaxiPathNodeStore.LookupEntry(j); if (pathnode) { if (pathnode->path == p->id) { TaxiPathNode *pn = new TaxiPathNode; pn->x = pathnode->x; pn->y = pathnode->y; pn->z = pathnode->z; pn->mapid = pathnode->mapid; p->AddPathNode(pathnode->seq, pn); } } } p->ComputeLen(); this->m_taxiPaths.insert(std::map::value_type(p->id, p)); } } } TaxiPath* TaxiMgr::GetTaxiPath(uint32 path) { HM_NAMESPACE::hash_map::iterator itr; itr = this->m_taxiPaths.find(path); if (itr == m_taxiPaths.end()) return NULL; else return itr->second; } TaxiPath* TaxiMgr::GetTaxiPath(uint32 from, uint32 to) { HM_NAMESPACE::hash_map::iterator itr; for (itr = m_taxiPaths.begin(); itr != m_taxiPaths.end(); itr++) if ((itr->second->to == to) && (itr->second->from == from)) return itr->second; return NULL; } TaxiNode* TaxiMgr::GetTaxiNode(uint32 node) { HM_NAMESPACE::hash_map::iterator itr; itr = this->m_taxiNodes.find(node); if (itr == m_taxiNodes.end()) return NULL; else return itr->second; } uint32 TaxiMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid ) { uint32 nearest = 0; float distance = -1; float nx, ny, nz, nd; HM_NAMESPACE::hash_map::iterator itr; for (itr = m_taxiNodes.begin(); itr != m_taxiNodes.end(); itr++) { if (itr->second->mapid == mapid) { nx = itr->second->x - x; ny = itr->second->y - y; nz = itr->second->z - z; nd = nx * nx + ny * ny + nz * nz; if( nd < distance || distance < 0 ) { distance = nd; nearest = itr->second->id; } } } return nearest; } bool TaxiMgr::GetGlobalTaxiNodeMask( uint32 curloc, uint32 *Mask ) { HM_NAMESPACE::hash_map::iterator itr; uint8 field; for (itr = m_taxiPaths.begin(); itr != m_taxiPaths.end(); itr++) { if( itr->second->from == curloc ) { field = (uint8)((itr->second->to - 1) / 32); Mask[field] |= 1 << ( (itr->second->to - 1 ) % 32 ); } } return true; }