/** * MaNGOS is a full featured server for World of Warcraft, supporting * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 * * Copyright (C) 2005-2014 MaNGOS project * * 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 * * World of Warcraft, and all World of Warcraft or Warcraft art, images, * and lore are copyrighted by Blizzard Entertainment, Inc. */ #include "ConfusedMovementGenerator.h" #include "MapManager.h" #include "Creature.h" #include "Player.h" #include "movement/MoveSplineInit.h" #include "movement/MoveSpline.h" #include "PathFinder.h" template void ConfusedMovementGenerator::Initialize(T& unit) { unit.addUnitState(UNIT_STAT_CONFUSED); // set initial position unit.GetPosition(i_x, i_y, i_z); if (!unit.isAlive() || unit.hasUnitState(UNIT_STAT_NOT_MOVE)) return; unit.StopMoving(); unit.addUnitState(UNIT_STAT_CONFUSED_MOVE); } template void ConfusedMovementGenerator::Interrupt(T& unit) { unit.InterruptMoving(); // confused state still applied while movegen disabled unit.clearUnitState(UNIT_STAT_CONFUSED_MOVE); } template void ConfusedMovementGenerator::Reset(T& unit) { i_nextMoveTime.Reset(0); if (!unit.isAlive() || unit.hasUnitState(UNIT_STAT_NOT_MOVE)) return; unit.StopMoving(); unit.addUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_CONFUSED_MOVE); } template bool ConfusedMovementGenerator::Update(T& unit, const uint32& diff) { // ignore in case other no reaction state if (unit.hasUnitState(UNIT_STAT_CAN_NOT_REACT & ~UNIT_STAT_CONFUSED)) return true; if (i_nextMoveTime.Passed()) { // currently moving, update location unit.addUnitState(UNIT_STAT_CONFUSED_MOVE); if (unit.movespline->Finalized()) i_nextMoveTime.Reset(urand(800, 1500)); } else { // waiting for next move i_nextMoveTime.Update(diff); if (i_nextMoveTime.Passed()) { // start moving unit.addUnitState(UNIT_STAT_CONFUSED_MOVE); float x = i_x + 10.0f * (rand_norm_f() - 0.5f); float y = i_y + 10.0f * (rand_norm_f() - 0.5f); float z = i_z; unit.UpdateAllowedPositionZ(x, y, z); PathFinder path(&unit); path.setPathLengthLimit(30.0f); path.calculate(x, y, z); if (path.getPathType() & PATHFIND_NOPATH) { i_nextMoveTime.Reset(urand(800, 1000)); return true; } Movement::MoveSplineInit init(unit); init.MovebyPath(path.getPath()); init.SetWalk(true); init.Launch(); } } return true; } template<> void ConfusedMovementGenerator::Finalize(Player& unit) { unit.clearUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_CONFUSED_MOVE); unit.StopMoving(); } template<> void ConfusedMovementGenerator::Finalize(Creature& unit) { unit.clearUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_CONFUSED_MOVE); } template void ConfusedMovementGenerator::Initialize(Player& player); template void ConfusedMovementGenerator::Initialize(Creature& creature); template void ConfusedMovementGenerator::Interrupt(Player& player); template void ConfusedMovementGenerator::Interrupt(Creature& creature); template void ConfusedMovementGenerator::Reset(Player& player); template void ConfusedMovementGenerator::Reset(Creature& creature); template bool ConfusedMovementGenerator::Update(Player& player, const uint32& diff); template bool ConfusedMovementGenerator::Update(Creature& creature, const uint32& diff);