/* * Copyright (C) 2005,2006,2007 MaNGOS * * 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 "Creature.h" #include "MapManager.h" #include "Opcodes.h" #include "RandomMovementGenerator.h" #include "DestinationHolderImp.h" /* Here interpolation is disabled by default due to it causing crashing in some compile environments. If your server can handle the small amount of lag this may cause and you can build without experiencing a significant increase in crashes then you may uncomment the following line to have correct random motion. */ // uncomment now for wide testing purpose //#define USE_INTERPOLATION, Such complication for in fact wrong base system, GS template<> void RandomMovementGenerator::_setRandomLocation(Creature &creature) { float X,Y,Z,z,nx,ny,nz,wander_distance; creature.GetRespawnDist(wander_distance); if(!wander_distance) //In Fact is that is true we should never Permit that type of MV, GS { i_nextMoveTime.Reset(60000); return; } creature.GetRespawnCoord(X, Y, Z); z = creature.GetPositionZ(); uint32 mapid=creature.GetMapId(); Map const* map = MapManager::Instance().GetBaseMap(mapid); //Both water and fly , will do later... since will be cool to select random Z and will need to check dist into 3d //bool is_water_ok = creature.isCanSwimOrFly(); //bool is_land_ok = creature.isCanWalkOrFly(); const float angle = rand_norm()*(M_PI*2); srand(getMSTime()); const float range = rand_norm()*wander_distance; nx = X + range * cos(angle); ny = Y + range * sin(angle); nz = map->GetHeight(nx,ny,z); Traveller traveller(creature); creature.SetOrientation(creature.GetAngle(nx,ny)); i_destinationHolder.SetDestination(traveller, nx, ny, nz); i_nextMoveTime.Reset(irand(i_destinationHolder.GetTotalTravelTime(),i_destinationHolder.GetTotalTravelTime()*2)); creature.addUnitState(UNIT_STAT_ROAMING); } template<> void RandomMovementGenerator::Initialize(Creature &creature) { if(!&creature) return; if(!creature.IsStopped()) creature.StopMoving(); creature.setMoveRunFlag(irand(0,20) ? false : true); _setRandomLocation(creature); } template<> void RandomMovementGenerator::Reset(Creature &creature) { Initialize(creature); } template<> bool RandomMovementGenerator::Update(Creature &creature, const uint32 &diff) { if(!&creature) return false; i_nextMoveTime.Update(diff); if(i_destinationHolder.HasArrived() && !creature.IsStopped()) creature.clearUnitState(UNIT_STAT_ROAMING); if(!i_destinationHolder.HasArrived() && creature.IsStopped()) creature.addUnitState(UNIT_STAT_ROAMING); CreatureTraveller traveller(creature); if( i_destinationHolder.UpdateTraveller(traveller, diff, false) ) { if(i_nextMoveTime.Passed()) { creature.setMoveRunFlag(irand(0,20) ? false : true); _setRandomLocation(creature); } } return true; }