/* * Copyright (C) 2005-2012 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 "RandomMovementGenerator.h" #include "Map.h" #include "Util.h" #include "movement/MoveSplineInit.h" #include "movement/MoveSpline.h" template<> RandomMovementGenerator::RandomMovementGenerator(const Creature& creature) { float respX, respY, respZ, respO, wander_distance; creature.GetRespawnCoord(respX, respY, respZ, &respO, &wander_distance); i_nextMoveTime = ShortTimeTracker(0); i_x = respX; i_y = respY; i_z = respZ; i_radius = wander_distance; // TODO - add support for flying mobs using some distance i_verticalZ = 0.0f; } template<> void RandomMovementGenerator::_setRandomLocation(Creature& creature) { const float angle = rand_norm_f() * (M_PI_F*2.0f); const float range = rand_norm_f() * i_radius; float destX = i_x + range * cos(angle); float destY = i_y + range * sin(angle); float destZ = i_z + frand(-1,1) * i_verticalZ; creature.UpdateAllowedPositionZ(destX, destY, destZ); creature.addUnitState(UNIT_STAT_ROAMING_MOVE); Movement::MoveSplineInit init(creature); init.MoveTo(destX, destY, destZ, true); init.SetWalk(true); init.Launch(); if (creature.CanFly()) i_nextMoveTime.Reset(0); else i_nextMoveTime.Reset(urand(500, 10000)); } template<> void RandomMovementGenerator::Initialize(Creature& creature) { if (!creature.isAlive()) return; creature.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); _setRandomLocation(creature); } template<> void RandomMovementGenerator::Reset(Creature& creature) { Initialize(creature); } template<> void RandomMovementGenerator::Interrupt(Creature& creature) { creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); creature.SetWalk(false); } template<> void RandomMovementGenerator::Finalize(Creature& creature) { creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE); creature.SetWalk(false); } template<> bool RandomMovementGenerator::Update(Creature& creature, const uint32& diff) { if (creature.hasUnitState(UNIT_STAT_NOT_MOVE)) { i_nextMoveTime.Reset(0); // Expire the timer creature.clearUnitState(UNIT_STAT_ROAMING_MOVE); return true; } if (creature.movespline->Finalized()) { i_nextMoveTime.Update(diff); if (i_nextMoveTime.Passed()) _setRandomLocation(creature); } return true; }