aboutsummaryrefslogtreecommitdiff
path: root/src/game/WaypointMovementGenerator.cpp
diff options
context:
space:
mode:
authormegamage <none@none>2008-12-09 23:02:17 -0600
committermegamage <none@none>2008-12-09 23:02:17 -0600
commit36af87fc72594b3b6e3b91e91cd29a00e1a36480 (patch)
treee76372128867cc9ade2b1b343f5fe0f4eef0c05b /src/game/WaypointMovementGenerator.cpp
parentb5d1418b0cdd38980ec1fec3af1ddf031c9cb9e5 (diff)
*Recommit four files because of eol issue.
--HG-- branch : trunk
Diffstat (limited to 'src/game/WaypointMovementGenerator.cpp')
-rw-r--r--src/game/WaypointMovementGenerator.cpp306
1 files changed, 141 insertions, 165 deletions
diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp
index 3dc3ddebf42..84f121eb9b3 100644
--- a/src/game/WaypointMovementGenerator.cpp
+++ b/src/game/WaypointMovementGenerator.cpp
@@ -1,8 +1,6 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
*
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
- *
* 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
@@ -10,209 +8,187 @@
*
* 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
+ * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/*
-creature_movement Table
-
-alter table creature_movement add `textid1` int(11) NOT NULL default '0';
-alter table creature_movement add `textid2` int(11) NOT NULL default '0';
-alter table creature_movement add `textid3` int(11) NOT NULL default '0';
-alter table creature_movement add `textid4` int(11) NOT NULL default '0';
-alter table creature_movement add `textid5` int(11) NOT NULL default '0';
-alter table creature_movement add `emote` int(10) unsigned default '0';
-alter table creature_movement add `spell` int(5) unsigned default '0';
-alter table creature_movement add `wpguid` int(11) default '0';
-
-*/
-
+//Basic header
#include <ctime>
#include "WaypointMovementGenerator.h"
+//Accessors
+#include "Database/DatabaseEnv.h"
#include "ObjectMgr.h"
+#include "World.h"
+//Creature-specific headers
#include "Creature.h"
-#include "DestinationHolderImp.h"
#include "CreatureAI.h"
-#include "WaypointManager.h"
+//Player-Specific
+#include "Player.h"
+//Visual
+#include "ProgressBar.h"
+#include "MapManager.h"
-#include <cassert>
+template<class T>
+void
+WaypointMovementGenerator<T>::Initialize(T &u){}
-//-----------------------------------------------//
+template<>
void
-WaypointMovementGenerator<Creature>::LoadPath(Creature &c)
+WaypointMovementGenerator<Creature>::Initialize(Creature &u)
{
- sLog.outDetail("LoadPath: loading waypoint path for creature %d,%d", c.GetGUIDLow(), c.GetDBTableGUIDLow());
+ i_currentNode = -1;
+ u.StopMoving();
+ if(!path_id)
+ path_id = u.GetWaypointPath();
+ waypoints = WaypointMgr.GetPath(path_id);
+}
- i_path = WaypointMgr.GetPath(c.GetDBTableGUIDLow());
- if(!i_path)
- {
- sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %d) doesn't have waypoint path",
- c.GetName(), c.GetEntry(), c.GetDBTableGUIDLow());
- return;
- }
+template<>
+void
+WaypointMovementGenerator<Creature>::Finalize(Creature &u){}
+
+template<>
+void
+WaypointMovementGenerator<Player>::Finalize(Player &u){}
- uint32 node_count = i_path->size();
- i_hasDone.resize(node_count);
- for(uint32 i = 0; i < node_count-1; i++)
- i_hasDone[i] = false;
+template<class T>
+void
+WaypointMovementGenerator<T>::MovementInform(T &unit){}
- // to prevent a misbehaviour inside "update"
- // update is always called with the next wp - but the wpSys needs the current
- // so when the routine is called the first time, wpSys gets the last waypoint
- // and this prevents the system from performing text/emote, etc
- i_hasDone[node_count - 1] = true;
+template<>
+void WaypointMovementGenerator<Creature>::MovementInform(Creature &unit)
+{
+ unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
}
-void
-WaypointMovementGenerator<Creature>::ClearWaypoints()
+template<>
+void WaypointMovementGenerator<Creature>::Reset(Creature &unit){}
+
+template<>
+void WaypointMovementGenerator<Player>::Reset(Player &unit){}
+
+template<>
+void WaypointMovementGenerator<Creature>::InitTraveller(Creature &unit, const WaypointData &node)
{
- i_path = NULL;
+ node.run ? unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE): unit.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+
+ unit.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
+ unit.SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+
+ if(unit.canFly())
+ unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
+
+ unit.addUnitState(UNIT_STAT_ROAMING);
}
-void
-WaypointMovementGenerator<Creature>::Initialize()
+template<>
+void WaypointMovementGenerator<Player>::InitTraveller(Player &unit, const WaypointData &node){}
+
+template<class T>
+bool
+WaypointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
{
+ return false;
}
+template<>
bool
-WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
+WaypointMovementGenerator<Creature>::Update(Creature &unit, const uint32 &diff)
{
- if(!&creature)
+ if(!&unit)
return true;
- // Waypoint movement can be switched on/off
+ if(!path_id)
+ return false;
+
+ // Waypoint movement can be switched on/off
// This is quite handy for escort quests and other stuff
- if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
- return true;
+ if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
+ return true;
- // prevent a crash at empty waypoint path.
- if(!i_path || i_path->empty())
- return true;
+ // Clear the generator if the path doesn't exist
+ if(!waypoints || !waypoints->size())
+ return false;
- // i_path was modified by chat commands for example
- if(i_path->size() != i_hasDone.size())
- i_hasDone.resize(i_path->size());
- if(i_currentNode >= i_path->size())
- i_currentNode = 0;
+ Traveller<Creature> traveller(unit);
- CreatureTraveller traveller(creature);
-
- i_nextMoveTime.Update(diff);
+ i_nextMoveTime.Update(diff);
i_destinationHolder.UpdateTraveller(traveller, diff, false, true);
- // creature has been stoped in middle of the waypoint segment
- if (!i_destinationHolder.HasArrived() && creature.IsStopped())
- {
- if( i_nextMoveTime.Passed()) // Timer has elapsed, meaning this part controlled it
- {
- SetStopedByPlayer(false);
- // Now we re-set destination to same node and start travel
- creature.addUnitState(UNIT_STAT_ROAMING);
- if (creature.canFly())
- creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
- const WaypointNode &node = i_path->at(i_currentNode);
- i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
- i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
- }
- else // if( !i_nextMoveTime.Passed())
- { // unexpected end of timer && creature stopped && not at end of segment
- if (!IsStopedByPlayer())
- { // Put 30 seconds delay
- i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER);
- i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
- SetStopedByPlayer(true); // Mark we did it
- }
- }
- return true; // Abort here this update
+ if(i_nextMoveTime.Passed())
+ {
+ if(unit.IsStopped())
+ {
+ if(StopedByPlayer)
+ {
+ InitTraveller(unit,node);
+ i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
+ i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
+ StopedByPlayer = false;
+ return true;
+ }
+
+ if(i_currentNode == waypoints->size() - 1) //If that's our last waypoint
+ {
+ if(repeating) //If the movement is repeating
+ i_currentNode = 0; //Start moving all over again
+ else
+ {
+ unit.GetMotionMaster()->Initialize();
+ return false; //Clear the waypoint movement
+ }
+ }
+ else
+ i_currentNode++;
+
+ node = *(waypoints->at(i_currentNode));
+ InitTraveller(unit,node);
+ i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
+ i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
+ }
+ else
+ {
+ //Determine waittime
+ if(node.delay)
+ i_nextMoveTime.Reset(node.delay);
+ else
+ i_nextMoveTime.Reset(100); //Prevents some lag
+
+ if(node.event_id && rand()%100 < node.event_chance && !ExecuteScript)
+ {
+ sWorld.ScriptsStart(sWaypointScripts, node.event_id, &unit, NULL);
+ ExecuteScript = true;
+ }
+
+ MovementInform(unit);
+ unit.UpdateWaypointID(i_currentNode);
+ traveller.Relocation(node.x, node.y, node.z);
+ unit.clearUnitState(UNIT_STAT_MOVING);
+ }
}
-
- if( creature.IsStopped())
- {
- uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1;
-
- if (!i_hasDone[idx])
- {
- if (i_path->at(idx).orientation !=100)
- creature.SetOrientation(i_path->at(idx).orientation);
-
- if(WaypointBehavior *behavior = i_path->at(idx).behavior)
- {
- if(behavior->emote != 0)
- creature.SetUInt32Value(UNIT_NPC_EMOTESTATE,behavior->emote);
- if(behavior->spell != 0)
- creature.CastSpell(&creature,behavior->spell, false);
- if(behavior->model1 != 0)
- creature.SetDisplayId(behavior->model1);
- if(behavior->textid[0])
- {
- // Not only one text is set
- if( behavior->textid[1] )
- {
- // Select one from max 5 texts (0 and 1 already checked)
- int i = 2;
- for( ; i < MAX_WAYPOINT_TEXT; ++i )
- if( !behavior->textid[i] )
- break;
-
- creature.Say(behavior->textid[rand() % i], 0, 0);
- }
- else
- creature.Say(behavior->textid[0], 0, 0);
- }
- } // wpBehaviour found
- i_hasDone[idx] = true;
- MovementInform(creature);
- } // HasDone == false
- } // i_creature.IsStopped()
-
- if( i_nextMoveTime.Passed() ) // This is at the end of waypoint segment or has been stopped by player
- {
- if( creature.IsStopped() ) // If stopped then begin a new move segment
- {
- creature.addUnitState(UNIT_STAT_ROAMING);
- if (creature.canFly())
- creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
- const WaypointNode &node = i_path->at(i_currentNode);
- i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
- i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
- uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1;
-
- if (i_path->at(idx).orientation !=100)
- creature.SetOrientation(i_path->at(idx).orientation);
-
- if(WaypointBehavior *behavior = i_path->at(idx).behavior )
- {
- i_hasDone[idx] = false;
- if(behavior->model2 != 0)
- creature.SetDisplayId(behavior->model2);
-
- creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
- }
- }
- else // If not stopped then stop it and set the reset of TimeTracker to waittime
- {
- creature.StopMoving();
- SetStopedByPlayer(false);
- i_nextMoveTime.Reset(i_path->at(i_currentNode).delay);
- ++i_currentNode;
- if( i_currentNode >= i_path->size() )
- i_currentNode = 0;
- }
- }
- return true;
+ else
+ {
+ if(unit.IsStopped() && !i_destinationHolder.HasArrived())
+ {
+ if(!StopedByPlayer)
+ {
+ i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER);
+ i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
+ StopedByPlayer = true;
+ }
+ }
+ }
+ return true;
}
-void WaypointMovementGenerator<Creature>::MovementInform(Creature &unit)
-{
- if(unit.AI())
- unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
-}
+template void WaypointMovementGenerator<Player>::Initialize(Player &);
+template bool WaypointMovementGenerator<Player>::Update(Player &, const uint32 &);
+template void WaypointMovementGenerator<Player>::MovementInform(Player &);
//----------------------------------------------------//
void