Featuring a rewritten waypoint movement with more options, optimised code and revamped ingame waypoint control. To convert entries from the old tables manually, please use the PHP script provided at http://www.trinitycore.org/forum/project.php?issueid=830
--HG-- branch : trunk
This commit is contained in:
+19
-11
@@ -134,15 +134,18 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
|
||||
static ChatCommand wpCommandTable[] =
|
||||
{
|
||||
{ "show", SEC_GAMEMASTER, false, &ChatHandler::HandleWpShowCommand, "", NULL },
|
||||
{ "add", SEC_GAMEMASTER, false, &ChatHandler::HandleWpAddCommand, "", NULL },
|
||||
{ "modify", SEC_GAMEMASTER, false, &ChatHandler::HandleWpModifyCommand, "", NULL },
|
||||
{ "export", SEC_ADMINISTRATOR, false, &ChatHandler::HandleWpExportCommand, "", NULL },
|
||||
{ "import", SEC_ADMINISTRATOR, false, &ChatHandler::HandleWpImportCommand, "", NULL },
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
static ChatCommand wpCommandTable[] =
|
||||
{
|
||||
{ "show", SEC_GAMEMASTER, false, &ChatHandler::HandleWpShowCommand, "", NULL },
|
||||
{ "addwp", SEC_GAMEMASTER, false, &ChatHandler::HandleWpAddCommand, "", NULL },
|
||||
{ "load", SEC_GAMEMASTER, false, &ChatHandler::HandleWpLoadPathCommand, "", NULL },
|
||||
{ "modify", SEC_GAMEMASTER, false, &ChatHandler::HandleWpModifyCommand, "", NULL },
|
||||
{ "event", SEC_GAMEMASTER, false, &ChatHandler::HandleWpEventCommand, "", NULL },
|
||||
{ "unload", SEC_GAMEMASTER, false, &ChatHandler::HandleWpUnLoadPathCommand, "", NULL },
|
||||
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
|
||||
|
||||
static ChatCommand banCommandTable[] =
|
||||
{
|
||||
@@ -293,6 +296,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||
{ "locales_npc_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesNpcTextCommand, "", NULL },
|
||||
{ "locales_page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL },
|
||||
{ "locales_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL },
|
||||
{ "waypoint_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadWpScriptsCommand, "", NULL },
|
||||
|
||||
{ "", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommand, "", NULL },
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
@@ -507,8 +511,12 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||
{ "event", SEC_GAMEMASTER, false, NULL, "", eventCommandTable },
|
||||
{ "gobject", SEC_GAMEMASTER, false, NULL, "", gobjectCommandTable },
|
||||
{ "honor", SEC_GAMEMASTER, false, NULL, "", honorCommandTable },
|
||||
{ "wp", SEC_GAMEMASTER, false, NULL, "", wpCommandTable },
|
||||
{ "quest", SEC_ADMINISTRATOR, false, NULL, "", questCommandTable },
|
||||
|
||||
//wp commands
|
||||
{ "path", SEC_GAMEMASTER, false, NULL, "", wpCommandTable },
|
||||
{ "loadpath", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllPaths, "", NULL },
|
||||
|
||||
{ "quest", SEC_ADMINISTRATOR, false, NULL, "", questCommandTable },
|
||||
{ "reload", SEC_ADMINISTRATOR, true, NULL, "", reloadCommandTable },
|
||||
{ "list", SEC_ADMINISTRATOR, true, NULL, "", listCommandTable },
|
||||
{ "lookup", SEC_ADMINISTRATOR, true, NULL, "", lookupCommandTable },
|
||||
|
||||
+12
-6
@@ -211,7 +211,8 @@ class ChatHandler
|
||||
|
||||
bool HandleReloadConfigCommand(const char* args);
|
||||
|
||||
bool HandleReloadAreaTriggerTavernCommand(const char* args);
|
||||
bool HandleReloadWpScriptsCommand(const char* args);
|
||||
bool HandleReloadAreaTriggerTavernCommand(const char* args);
|
||||
bool HandleReloadAreaTriggerTeleportCommand(const char* args);
|
||||
bool HandleReloadEventScriptsCommand(const char* args);
|
||||
bool HandleReloadCommandCommand(const char* args);
|
||||
@@ -410,11 +411,16 @@ class ChatHandler
|
||||
bool HandlePasswordCommand(const char* args);
|
||||
bool HandleLockAccountCommand(const char* args);
|
||||
bool HandleRespawnCommand(const char* args);
|
||||
bool HandleWpAddCommand(const char* args);
|
||||
bool HandleWpModifyCommand(const char* args);
|
||||
bool HandleWpShowCommand(const char* args);
|
||||
bool HandleWpExportCommand(const char* args);
|
||||
bool HandleWpImportCommand(const char* args);
|
||||
|
||||
//New Wp Commands
|
||||
bool HandleWpAddCommand(const char* args);
|
||||
bool HandleWpLoadPathCommand(const char* args);
|
||||
bool HandleWpUnLoadPathCommand(const char* args);
|
||||
bool HandleWpModifyCommand(const char* args);
|
||||
bool HandleWpEventCommand(const char* args);
|
||||
bool HandleWpShowCommand(const char* args);
|
||||
bool HandleReloadAllPaths(const char *args);
|
||||
|
||||
bool HandleFlyModeCommand(const char* args);
|
||||
bool HandleSendOpcodeCommand(const char* args);
|
||||
bool HandleSellErrorCommand(const char* args);
|
||||
|
||||
@@ -2068,6 +2068,10 @@ bool Creature::LoadCreaturesAddon(bool reload)
|
||||
if (cainfo->move_flags != 0)
|
||||
SetUnitMovementFlags(cainfo->move_flags);
|
||||
|
||||
//Load Path
|
||||
if (cainfo->path_id != 0)
|
||||
m_path_id = cainfo->path_id;
|
||||
|
||||
if(cainfo->auras)
|
||||
{
|
||||
for (CreatureDataAddonAura const* cAura = cainfo->auras; cAura->spell_id; ++cAura)
|
||||
|
||||
+15
-3
@@ -279,7 +279,8 @@ struct CreatureDataAddonAura
|
||||
struct CreatureDataAddon
|
||||
{
|
||||
uint32 guidOrEntry;
|
||||
uint32 mount;
|
||||
uint32 path_id;
|
||||
uint32 mount;
|
||||
uint32 bytes0;
|
||||
uint32 bytes1;
|
||||
uint32 bytes2;
|
||||
@@ -616,7 +617,14 @@ class TRINITY_DLL_SPEC Creature : public Unit
|
||||
void GetCombatStartPosition(float &x, float &y, float &z) { x = CombatStartX; y = CombatStartY; z = CombatStartZ; }
|
||||
|
||||
uint32 GetGlobalCooldown() const { return m_GlobalCooldown; }
|
||||
protected:
|
||||
|
||||
uint32 GetWaypointPath(){return m_path_id;}
|
||||
void LoadPath(uint32 pathid) { m_path_id = pathid; }
|
||||
|
||||
uint32 GetCurrentWaypointID(){return m_waypointID;}
|
||||
void UpdateWaypointID(uint32 wpID){m_waypointID = wpID;}
|
||||
|
||||
protected:
|
||||
bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL);
|
||||
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
|
||||
|
||||
@@ -666,7 +674,11 @@ class TRINITY_DLL_SPEC Creature : public Unit
|
||||
float CombatStartZ;
|
||||
|
||||
private:
|
||||
GridReference<Creature> m_gridRef;
|
||||
//WaypointMovementGenerator vars
|
||||
uint32 m_waypointID;
|
||||
uint32 m_path_id;
|
||||
|
||||
GridReference<Creature> m_gridRef;
|
||||
CreatureInfo const* m_creatureInfo; // in heroic mode can different from ObjMgr::GetCreatureTemplate(GetEntry())
|
||||
};
|
||||
|
||||
|
||||
+1122
-1155
File diff suppressed because it is too large
Load Diff
+24
-3
@@ -136,7 +136,8 @@ bool ChatHandler::HandleReloadAllScriptsCommand(const char*)
|
||||
HandleReloadSpellScriptsCommand("a");
|
||||
SendGlobalSysMessage("DB tables `*_scripts` reloaded.");
|
||||
HandleReloadDbScriptStringCommand("a");
|
||||
return true;
|
||||
HandleReloadWpScriptsCommand("a");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadAllSpellCommand(const char*)
|
||||
@@ -535,8 +536,28 @@ bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
|
||||
sLog.outString( "Re-Loading Scripts from `event_scripts`...");
|
||||
|
||||
objmgr.LoadEventScripts();
|
||||
|
||||
if(*arg!='a')
|
||||
|
||||
if(*arg!='a')
|
||||
SendGlobalSysMessage("DB table `event_scripts` reloaded.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadWpScriptsCommand(const char* arg)
|
||||
{
|
||||
if(sWorld.IsScriptScheduled())
|
||||
{
|
||||
SendSysMessage("DB scripts used currently, please attempt reload later.");
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(*arg!='a')
|
||||
sLog.outString( "Re-Loading Scripts from `event_scripts`...");
|
||||
|
||||
objmgr.LoadWaypointScripts();
|
||||
|
||||
if(*arg!='a')
|
||||
SendGlobalSysMessage("DB table `event_scripts` reloaded.");
|
||||
|
||||
return true;
|
||||
|
||||
@@ -319,6 +319,31 @@ void MotionMaster::Mutate(MovementGenerator *m)
|
||||
push(m);
|
||||
}
|
||||
|
||||
void MotionMaster::MovePath(uint32 path_id, bool repeatable)
|
||||
{
|
||||
if(!path_id)
|
||||
return;
|
||||
//We set waypoint movement as new default movement generator
|
||||
// clear ALL movement generators (including default)
|
||||
while(!empty())
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
if( !isStatic( curr ) )
|
||||
delete curr;
|
||||
}
|
||||
|
||||
sLog.outError("attempting to move");
|
||||
//i_owner->GetTypeId()==TYPEID_PLAYER ?
|
||||
//Mutate(new WaypointMovementGenerator<Player>(path_id, repeatable)):
|
||||
Mutate(new WaypointMovementGenerator<Creature>(path_id, repeatable));
|
||||
|
||||
DEBUG_LOG("%s (GUID: %u) start moving over path(Id:%u, repeatable: %s)",
|
||||
i_owner->GetTypeId()==TYPEID_PLAYER ? "Player" : "Creature",
|
||||
i_owner->GetGUIDLow(), path_id, repeatable ? "YES" : "NO" );
|
||||
}
|
||||
|
||||
void MotionMaster::propagateSpeedChange()
|
||||
{
|
||||
Impl::container_type::iterator it = Impl::c.begin();
|
||||
|
||||
@@ -80,6 +80,7 @@ class TRINITY_DLL_SPEC MotionMaster : private std::stack<MovementGenerator *>
|
||||
void MovePoint(uint32 id, float x,float y,float z);
|
||||
void MoveTaxiFlight(uint32 path, uint32 pathnode);
|
||||
void MoveDistract(uint32 time);
|
||||
void MovePath(uint32 path_id, bool repeatable);
|
||||
|
||||
MovementGeneratorType GetCurrentMovementGeneratorType() const;
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ template<class MOVEMENT_GEN>
|
||||
inline MovementGenerator*
|
||||
MovementGeneratorFactory<MOVEMENT_GEN>::Create(void *data) const
|
||||
{
|
||||
Creature* creature = reinterpret_cast<Creature *>(data);
|
||||
return (new MOVEMENT_GEN(*creature));
|
||||
return (new MOVEMENT_GEN());
|
||||
}
|
||||
#endif
|
||||
|
||||
+15
-1
@@ -54,6 +54,7 @@ ScriptMapMap sQuestStartScripts;
|
||||
ScriptMapMap sSpellScripts;
|
||||
ScriptMapMap sGameObjectScripts;
|
||||
ScriptMapMap sEventScripts;
|
||||
ScriptMapMap sWaypointScripts;
|
||||
|
||||
bool normalizePlayerName(std::string& name)
|
||||
{
|
||||
@@ -4110,6 +4111,19 @@ void ObjectMgr::LoadEventScripts()
|
||||
}
|
||||
}
|
||||
|
||||
//Load WP Scripts
|
||||
void ObjectMgr::LoadWaypointScripts()
|
||||
{
|
||||
LoadScripts(sWaypointScripts, "waypoint_scripts");
|
||||
|
||||
for(ScriptMapMap::const_iterator itr = sWaypointScripts.begin(); itr != sWaypointScripts.end(); ++itr)
|
||||
{
|
||||
QueryResult *query = WorldDatabase.PQuery("SELECT * FROM `waypoint_scripts` WHERE `id` = %u", itr->first);
|
||||
if(!query || !query->GetRowCount())
|
||||
sLog.outErrorDb("There is no waypoint which links to the waypoint script %u", itr->first);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadItemTexts()
|
||||
{
|
||||
QueryResult *result = CharacterDatabase.Query("SELECT id, text FROM item_text");
|
||||
@@ -7481,7 +7495,7 @@ void ObjectMgr::LoadDbScriptStrings()
|
||||
CheckScripts(sGameObjectScripts,ids);
|
||||
CheckScripts(sEventScripts,ids);
|
||||
|
||||
WaypointMgr.CheckTextsExistance(ids);
|
||||
CheckScripts(sWaypointScripts,ids);
|
||||
|
||||
for(std::set<int32>::const_iterator itr = ids.begin(); itr != ids.end(); ++itr)
|
||||
sLog.outErrorDb( "Table `db_script_string` has unused string id %u", *itr);
|
||||
|
||||
@@ -98,6 +98,7 @@ extern ScriptMapMap sQuestStartScripts;
|
||||
extern ScriptMapMap sSpellScripts;
|
||||
extern ScriptMapMap sGameObjectScripts;
|
||||
extern ScriptMapMap sEventScripts;
|
||||
extern ScriptMapMap sWaypointScripts;
|
||||
|
||||
struct AreaTrigger
|
||||
{
|
||||
@@ -531,6 +532,7 @@ class ObjectMgr
|
||||
void LoadQuestStartScripts();
|
||||
void LoadEventScripts();
|
||||
void LoadSpellScripts();
|
||||
void LoadWaypointScripts();
|
||||
|
||||
bool LoadTrinityStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value);
|
||||
bool LoadTrinityStrings() { return LoadTrinityStrings(WorldDatabase,"trinity_string",MIN_TRINITY_STRING_ID,MAX_TRINITY_STRING_ID); }
|
||||
|
||||
@@ -31,7 +31,7 @@ class TRINITY_DLL_SPEC RandomMovementGenerator
|
||||
: public MovementGeneratorMedium< T, RandomMovementGenerator<T> >
|
||||
{
|
||||
public:
|
||||
RandomMovementGenerator(const Unit &) : i_nextMoveTime(0) {}
|
||||
RandomMovementGenerator() : i_nextMoveTime(0) {}
|
||||
|
||||
void _setRandomLocation(T &);
|
||||
void Initialize(T &);
|
||||
|
||||
+152
-342
@@ -1,342 +1,152 @@
|
||||
/*
|
||||
* 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
|
||||
* (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 "Database/DatabaseEnv.h"
|
||||
#include "GridDefines.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "WaypointManager.h"
|
||||
#include "ProgressBar.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectMgr.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(WaypointManager);
|
||||
|
||||
bool WaypointBehavior::isEmpty()
|
||||
{
|
||||
if (emote || spell || model1 || model2)
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
|
||||
if(textid[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
WaypointBehavior::WaypointBehavior(const WaypointBehavior &b)
|
||||
{
|
||||
emote = b.emote;
|
||||
spell = b.spell;
|
||||
model1 = b.model1;
|
||||
model2 = b.model2;
|
||||
for(int i=0; i < MAX_WAYPOINT_TEXT; ++i)
|
||||
textid[i] = b.textid[i];
|
||||
}
|
||||
|
||||
void WaypointManager::Load()
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
uint32 total_paths = 0;
|
||||
uint32 total_nodes = 0;
|
||||
uint32 total_behaviors = 0;
|
||||
|
||||
QueryResult *result = WorldDatabase.Query("SELECT id, COUNT(point) FROM creature_movement GROUP BY id");
|
||||
if(result)
|
||||
{
|
||||
total_paths = result->GetRowCount();
|
||||
barGoLink bar( total_paths );
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
uint32 id = fields[0].GetUInt32();
|
||||
uint32 count = fields[1].GetUInt32();
|
||||
m_pathMap[id].resize(count);
|
||||
|
||||
total_nodes += count;
|
||||
bar.step();
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
}
|
||||
|
||||
result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id, point FROM creature_movement");
|
||||
if(result)
|
||||
{
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
uint32 point = fields[15].GetUInt32();
|
||||
uint32 id = fields[14].GetUInt32();
|
||||
|
||||
WaypointPath &path = m_pathMap[id];
|
||||
// the cleanup queries make sure the following is true
|
||||
assert(point >= 1 && point <= path.size());
|
||||
WaypointNode &node = path[point-1];
|
||||
|
||||
node.x = fields[0].GetFloat();
|
||||
node.y = fields[1].GetFloat();
|
||||
node.z = fields[2].GetFloat();
|
||||
node.orientation = fields[3].GetFloat();
|
||||
node.delay = fields[6].GetUInt16();
|
||||
|
||||
// prevent using invalid coordinates
|
||||
if(!Trinity::IsValidMapCoord(node.x, node.y, node.z, node.orientation))
|
||||
{
|
||||
QueryResult *result1 = WorldDatabase.PQuery("SELECT id, map FROM creature WHERE guid = '%u'", id);
|
||||
if(result1)
|
||||
sLog.outErrorDb("ERROR: Creature (guidlow %d, entry %d) have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
|
||||
id, result1->Fetch()[0].GetUInt32(), point, node.x, node.y);
|
||||
else
|
||||
sLog.outErrorDb("ERROR: Waypoint path %d, have invalid coordinates in his waypoint %d (X: %f, Y: %f).",
|
||||
id, point, node.x, node.y);
|
||||
|
||||
Trinity::NormalizeMapCoord(node.x);
|
||||
Trinity::NormalizeMapCoord(node.y);
|
||||
if(result1)
|
||||
{
|
||||
node.z = MapManager::Instance ().GetBaseMap(result1->Fetch()[1].GetUInt32())->GetHeight(node.x, node.y, node.z);
|
||||
delete result1;
|
||||
}
|
||||
WorldDatabase.PExecute("UPDATE creature_movement SET position_x = '%f', position_y = '%f', position_z = '%f' WHERE id = '%u' AND point = '%u'", node.x, node.y, node.z, id, point);
|
||||
}
|
||||
|
||||
WaypointBehavior be;
|
||||
be.model1 = fields[4].GetUInt32();
|
||||
be.model2 = fields[5].GetUInt32();
|
||||
be.emote = fields[7].GetUInt32();
|
||||
be.spell = fields[8].GetUInt32();
|
||||
|
||||
for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
|
||||
{
|
||||
be.textid[i] = fields[9+i].GetUInt32();
|
||||
if(be.textid[i])
|
||||
{
|
||||
if (be.textid[i] < MIN_DB_SCRIPT_STRING_ID || be.textid[i] >= MAX_DB_SCRIPT_STRING_ID)
|
||||
{
|
||||
sLog.outErrorDb( "Table `db_script_string` not have string id %u", be.textid[i]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save memory by not storing empty behaviors
|
||||
if(!be.isEmpty())
|
||||
{
|
||||
node.behavior = new WaypointBehavior(be);
|
||||
++total_behaviors;
|
||||
}
|
||||
else
|
||||
node.behavior = NULL;
|
||||
bar.step();
|
||||
} while( result->NextRow() );
|
||||
delete result;
|
||||
}
|
||||
sLog.outString( ">> Loaded %u paths, %u nodes and %u behaviors", total_paths, total_nodes, total_behaviors);
|
||||
}
|
||||
|
||||
void WaypointManager::Cleanup()
|
||||
{
|
||||
// check if points need to be renumbered and do it
|
||||
if(QueryResult *result = WorldDatabase.Query("SELECT 1 from creature_movement As T WHERE point <> (SELECT COUNT(*) FROM creature_movement WHERE id = T.id AND point <= T.point) LIMIT 1"))
|
||||
{
|
||||
delete result;
|
||||
WorldDatabase.DirectExecute("CREATE TEMPORARY TABLE temp LIKE creature_movement");
|
||||
WorldDatabase.DirectExecute("INSERT INTO temp SELECT * FROM creature_movement");
|
||||
WorldDatabase.DirectExecute("ALTER TABLE creature_movement DROP PRIMARY KEY");
|
||||
WorldDatabase.DirectExecute("UPDATE creature_movement AS T SET point = (SELECT COUNT(*) FROM temp WHERE id = T.id AND point <= T.point)");
|
||||
WorldDatabase.DirectExecute("ALTER TABLE creature_movement ADD PRIMARY KEY (id, point)");
|
||||
WorldDatabase.DirectExecute("DROP TABLE temp");
|
||||
assert(!(result = WorldDatabase.Query("SELECT 1 from creature_movement As T WHERE point <> (SELECT COUNT(*) FROM creature_movement WHERE id = T.id AND point <= T.point) LIMIT 1")));
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointManager::Unload()
|
||||
{
|
||||
for(WaypointPathMap::iterator itr = m_pathMap.begin(); itr != m_pathMap.end(); ++itr)
|
||||
_clearPath(itr->second);
|
||||
m_pathMap.clear();
|
||||
}
|
||||
|
||||
void WaypointManager::_clearPath(WaypointPath &path)
|
||||
{
|
||||
for(WaypointPath::iterator itr = path.begin(); itr != path.end(); ++itr)
|
||||
if(itr->behavior)
|
||||
delete itr->behavior;
|
||||
path.clear();
|
||||
}
|
||||
|
||||
/// - Insert after the last point
|
||||
void WaypointManager::AddLastNode(uint32 id, float x, float y, float z, float o, uint32 delay, uint32 wpGuid)
|
||||
{
|
||||
_addNode(id, GetLastPoint(id, 0) + 1, x, y, z, o, delay, wpGuid);
|
||||
}
|
||||
|
||||
/// - Insert after a certain point
|
||||
void WaypointManager::AddAfterNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid)
|
||||
{
|
||||
for(uint32 i = GetLastPoint(id, 0); i > point; i--)
|
||||
WorldDatabase.PExecuteLog("UPDATE creature_movement SET point=point+1 WHERE id='%u' AND point='%u'", id, i);
|
||||
|
||||
_addNode(id, point + 1, x, y, z, o, delay, wpGuid);
|
||||
}
|
||||
|
||||
/// - Insert without checking for collision
|
||||
void WaypointManager::_addNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid)
|
||||
{
|
||||
if(point == 0) return; // counted from 1 in the DB
|
||||
WorldDatabase.PExecuteLog("INSERT INTO creature_movement (id,point,position_x,position_y,position_z,orientation,wpguid,waittime) VALUES ('%u','%u','%f', '%f', '%f', '%f', '%d', '%d')", id, point, x, y, z, o, wpGuid, delay);
|
||||
WaypointPathMap::iterator itr = m_pathMap.find(id);
|
||||
if(itr == m_pathMap.end())
|
||||
itr = m_pathMap.insert(WaypointPathMap::value_type(id, WaypointPath())).first;
|
||||
itr->second.insert(itr->second.begin() + (point - 1), WaypointNode(x, y, z, o, delay, NULL));
|
||||
}
|
||||
|
||||
uint32 WaypointManager::GetLastPoint(uint32 id, uint32 default_notfound)
|
||||
{
|
||||
uint32 point = default_notfound;
|
||||
/*QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'", id);
|
||||
if( result )
|
||||
{
|
||||
point = (*result)[0].GetUInt32()+1;
|
||||
delete result;
|
||||
}*/
|
||||
WaypointPathMap::iterator itr = m_pathMap.find(id);
|
||||
if(itr != m_pathMap.end() && itr->second.size() != 0)
|
||||
point = itr->second.size();
|
||||
return point;
|
||||
}
|
||||
|
||||
void WaypointManager::DeleteNode(uint32 id, uint32 point)
|
||||
{
|
||||
if(point == 0) return; // counted from 1 in the DB
|
||||
WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id='%u' AND point='%u'", id, point);
|
||||
WorldDatabase.PExecuteLog("UPDATE creature_movement SET point=point-1 WHERE id='%u' AND point>'%u'", id, point);
|
||||
WaypointPathMap::iterator itr = m_pathMap.find(id);
|
||||
if(itr != m_pathMap.end() && point <= itr->second.size())
|
||||
itr->second.erase(itr->second.begin() + (point-1));
|
||||
}
|
||||
|
||||
void WaypointManager::DeletePath(uint32 id)
|
||||
{
|
||||
WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id='%u'", id);
|
||||
WaypointPathMap::iterator itr = m_pathMap.find(id);
|
||||
if(itr != m_pathMap.end())
|
||||
_clearPath(itr->second);
|
||||
// the path is not removed from the map, just cleared
|
||||
// WMGs have pointers to the path, so deleting them would crash
|
||||
// this wastes some memory, but these functions are
|
||||
// only meant to be called by GM commands
|
||||
}
|
||||
|
||||
void WaypointManager::SetNodePosition(uint32 id, uint32 point, float x, float y, float z)
|
||||
{
|
||||
if(point == 0) return; // counted from 1 in the DB
|
||||
WorldDatabase.PExecuteLog("UPDATE creature_movement SET position_x = '%f',position_y = '%f',position_z = '%f' where id = '%u' AND point='%u'", x, y, z, id, point);
|
||||
WaypointPathMap::iterator itr = m_pathMap.find(id);
|
||||
if(itr != m_pathMap.end() && point <= itr->second.size())
|
||||
{
|
||||
itr->second[point-1].x = x;
|
||||
itr->second[point-1].y = y;
|
||||
itr->second[point-1].z = z;
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointManager::SetNodeText(uint32 id, uint32 point, const char *text_field, const char *text)
|
||||
{
|
||||
if(point == 0) return; // counted from 1 in the DB
|
||||
if(!text_field) return;
|
||||
std::string field = text_field;
|
||||
WorldDatabase.escape_string(field);
|
||||
|
||||
if(!text)
|
||||
{
|
||||
WorldDatabase.PExecuteLog("UPDATE creature_movement SET %s=NULL WHERE id='%u' AND point='%u'", field.c_str(), id, point);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string text2 = text;
|
||||
WorldDatabase.escape_string(text2);
|
||||
WorldDatabase.PExecuteLog("UPDATE creature_movement SET %s='%s' WHERE id='%u' AND point='%u'", field.c_str(), text2.c_str(), id, point);
|
||||
}
|
||||
|
||||
WaypointPathMap::iterator itr = m_pathMap.find(id);
|
||||
if(itr != m_pathMap.end() && point <= itr->second.size())
|
||||
{
|
||||
WaypointNode &node = itr->second[point-1];
|
||||
if(!node.behavior) node.behavior = new WaypointBehavior();
|
||||
|
||||
// if(field == "text1") node.behavior->text[0] = text ? text : "";
|
||||
// if(field == "text2") node.behavior->text[1] = text ? text : "";
|
||||
// if(field == "text3") node.behavior->text[2] = text ? text : "";
|
||||
// if(field == "text4") node.behavior->text[3] = text ? text : "";
|
||||
// if(field == "text5") node.behavior->text[4] = text ? text : "";
|
||||
if(field == "emote") node.behavior->emote = text ? atoi(text) : 0;
|
||||
if(field == "spell") node.behavior->spell = text ? atoi(text) : 0;
|
||||
if(field == "model1") node.behavior->model1 = text ? atoi(text) : 0;
|
||||
if(field == "model2") node.behavior->model2 = text ? atoi(text) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointManager::CheckTextsExistance(std::set<int32>& ids)
|
||||
{
|
||||
WaypointPathMap::iterator pmItr = m_pathMap.begin();
|
||||
for ( ; pmItr != m_pathMap.end(); ++pmItr)
|
||||
{
|
||||
for (int i = 0; i < pmItr->second.size(); ++i)
|
||||
{
|
||||
if (!pmItr->second[i].behavior)
|
||||
continue;
|
||||
|
||||
// Now we check text existence and put all zero texts ids to the end of array
|
||||
|
||||
// Counting leading zeros for futher textid shift
|
||||
int zeroCount = 0;
|
||||
for (int j = 0; j < MAX_WAYPOINT_TEXT; ++j)
|
||||
{
|
||||
if (!pmItr->second[i].behavior->textid[j])
|
||||
{
|
||||
++zeroCount;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!objmgr.GetTrinityStringLocale(pmItr->second[i].behavior->textid[j]))
|
||||
{
|
||||
sLog.outErrorDb("ERROR: Some waypoint has textid%u with not existing %u text.", j, pmItr->second[i].behavior->textid[j]);
|
||||
pmItr->second[i].behavior->textid[j] = 0;
|
||||
++zeroCount;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
ids.erase(pmItr->second[i].behavior->textid[j]);
|
||||
|
||||
// Shifting check
|
||||
if (zeroCount)
|
||||
{
|
||||
// Correct textid but some zeros leading, so move it forward.
|
||||
pmItr->second[i].behavior->textid[j-zeroCount] = pmItr->second[i].behavior->textid[j];
|
||||
pmItr->second[i].behavior->textid[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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
|
||||
* (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 "Database/DatabaseEnv.h"
|
||||
#include "GridDefines.h"
|
||||
#include "WaypointManager.h"
|
||||
#include "ProgressBar.h"
|
||||
#include "MapManager.h"
|
||||
|
||||
UNORDERED_MAP<uint32, WaypointPath*> waypoint_map;
|
||||
WaypointStore WaypointMgr;
|
||||
|
||||
void WaypointStore::Free()
|
||||
{
|
||||
waypoint_map.clear();
|
||||
}
|
||||
|
||||
void WaypointStore::Load()
|
||||
{
|
||||
QueryResult *result = WorldDatabase.PQuery("SELECT MAX(`id`) FROM `waypoint_data");
|
||||
if(!result)
|
||||
{
|
||||
sLog.outError(" an error occured while loading the table `waypoint_data` ( maybe it doesn't exist ?)\n");
|
||||
exit(1); // Stop server at loading non exited table or not accessable table
|
||||
}
|
||||
|
||||
records = (*result)[0].GetUInt32();
|
||||
delete result;
|
||||
|
||||
|
||||
result = WorldDatabase.PQuery("SELECT `id`,`point`,`position_x`,`position_y`,`position_z`,`move_flag`,`delay`,`action`,`action_chance` FROM `waypoint_data` ORDER BY `id`, `point`");
|
||||
if(!result)
|
||||
{
|
||||
sLog.outErrorDb("The table `creature_addon` is empty or corrupted");
|
||||
return;
|
||||
}
|
||||
|
||||
WaypointPath* path_data;
|
||||
uint32 total_records = result->GetRowCount();
|
||||
|
||||
barGoLink bar( total_records);
|
||||
Field *fields;
|
||||
uint32 last_id = 0;
|
||||
|
||||
do
|
||||
{
|
||||
fields = result->Fetch();
|
||||
uint32 id = fields[0].GetUInt32();
|
||||
bar.step();
|
||||
WaypointData *wp = new WaypointData;
|
||||
|
||||
if(last_id != id)
|
||||
path_data = new WaypointPath;
|
||||
|
||||
float x,y,z;
|
||||
x = fields[2].GetFloat();
|
||||
y = fields[3].GetFloat();
|
||||
z = fields[4].GetFloat();
|
||||
|
||||
Trinity::NormalizeMapCoord(x);
|
||||
Trinity::NormalizeMapCoord(y);
|
||||
|
||||
wp->id = fields[1].GetUInt32();
|
||||
wp->x = x;
|
||||
wp->y = y;
|
||||
wp->z = z;
|
||||
wp->run = fields[5].GetBool();
|
||||
wp->delay = fields[6].GetUInt32();
|
||||
wp->event_id = fields[7].GetUInt32();
|
||||
wp->event_chance = fields[8].GetUInt8();
|
||||
|
||||
path_data->push_back(wp);
|
||||
|
||||
if(id != last_id)
|
||||
waypoint_map[id] = path_data;
|
||||
|
||||
last_id = id;
|
||||
|
||||
} while(result->NextRow()) ;
|
||||
|
||||
|
||||
delete result;
|
||||
}
|
||||
|
||||
void WaypointStore::UpdatePath(uint32 id)
|
||||
{
|
||||
|
||||
if(waypoint_map.find(id)!= waypoint_map.end())
|
||||
waypoint_map[id]->clear();
|
||||
|
||||
QueryResult *result;
|
||||
|
||||
result = WorldDatabase.PQuery("SELECT `id`,`point`,`position_x`,`position_y`,`position_z`,`move_flag`,`delay`,`action`,`action_chance` FROM `waypoint_data` WHERE id = %u ORDER BY `point`", id);
|
||||
|
||||
if(!result)
|
||||
return;
|
||||
|
||||
WaypointPath* path_data;
|
||||
|
||||
path_data = new WaypointPath;
|
||||
|
||||
Field *fields;
|
||||
|
||||
do
|
||||
{
|
||||
fields = result->Fetch();
|
||||
uint32 id = fields[0].GetUInt32();
|
||||
|
||||
WaypointData *wp = new WaypointData;
|
||||
|
||||
float x,y,z;
|
||||
x = fields[2].GetFloat();
|
||||
y = fields[3].GetFloat();
|
||||
z = fields[4].GetFloat();
|
||||
|
||||
Trinity::NormalizeMapCoord(x);
|
||||
Trinity::NormalizeMapCoord(y);
|
||||
|
||||
wp->id = fields[1].GetUInt32();
|
||||
wp->x = x;
|
||||
wp->y = y;
|
||||
wp->z = z;
|
||||
wp->run = fields[5].GetBool();
|
||||
wp->delay = fields[6].GetUInt32();
|
||||
wp->event_id = fields[7].GetUInt32();
|
||||
wp->event_chance = fields[8].GetUInt8();
|
||||
|
||||
path_data->push_back(wp);
|
||||
|
||||
}while (result->NextRow());
|
||||
|
||||
waypoint_map[id] = path_data;
|
||||
|
||||
delete result;
|
||||
}
|
||||
|
||||
+61
-93
@@ -1,93 +1,61 @@
|
||||
/*
|
||||
* 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
|
||||
* (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
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_WAYPOINTMANAGER_H
|
||||
#define TRINITY_WAYPOINTMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "Utilities/UnorderedMap.h"
|
||||
|
||||
#define MAX_WAYPOINT_TEXT 5
|
||||
struct WaypointBehavior
|
||||
{
|
||||
uint32 emote;
|
||||
uint32 spell;
|
||||
int32 textid[MAX_WAYPOINT_TEXT];
|
||||
uint32 model1;
|
||||
uint32 model2;
|
||||
|
||||
bool isEmpty();
|
||||
WaypointBehavior() {}
|
||||
WaypointBehavior(const WaypointBehavior &b);
|
||||
};
|
||||
|
||||
struct WaypointNode
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float orientation;
|
||||
uint32 delay;
|
||||
WaypointBehavior * behavior;
|
||||
WaypointNode() {}
|
||||
WaypointNode(float _x, float _y, float _z, float _o, uint32 _delay, WaypointBehavior * _behavior)
|
||||
: x(_x), y(_y), z(_z), orientation(_o), delay(_delay), behavior(_behavior) {}
|
||||
};
|
||||
|
||||
typedef std::vector<WaypointNode> WaypointPath;
|
||||
|
||||
class WaypointManager
|
||||
{
|
||||
public:
|
||||
WaypointManager() {}
|
||||
~WaypointManager() { Unload(); }
|
||||
|
||||
void Load();
|
||||
void Unload();
|
||||
|
||||
void Cleanup();
|
||||
|
||||
WaypointPath *GetPath(uint32 id)
|
||||
{
|
||||
WaypointPathMap::iterator itr = m_pathMap.find(id);
|
||||
return itr != m_pathMap.end() ? &itr->second : NULL;
|
||||
}
|
||||
|
||||
void AddLastNode(uint32 id, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
|
||||
void AddAfterNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
|
||||
uint32 GetLastPoint(uint32 id, uint32 default_notfound);
|
||||
void DeleteNode(uint32 id, uint32 point);
|
||||
void DeletePath(uint32 id);
|
||||
void SetNodePosition(uint32 id, uint32 point, float x, float y, float z);
|
||||
void SetNodeText(uint32 id, uint32 point, const char *text_field, const char *text);
|
||||
void CheckTextsExistance(std::set<int32>& ids);
|
||||
|
||||
private:
|
||||
void _addNode(uint32 id, uint32 point, float x, float y, float z, float o, uint32 delay, uint32 wpGuid);
|
||||
void _clearPath(WaypointPath &path);
|
||||
|
||||
typedef UNORDERED_MAP<uint32, WaypointPath> WaypointPathMap;
|
||||
WaypointPathMap m_pathMap;
|
||||
};
|
||||
|
||||
#define WaypointMgr Trinity::Singleton<WaypointManager>::Instance()
|
||||
|
||||
#endif
|
||||
/*
|
||||
* 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
|
||||
* (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
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_WAYPOINTMANAGER_H
|
||||
#define TRINITY_WAYPOINTMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct WaypointData
|
||||
{
|
||||
uint32 id;
|
||||
float x,y,z;
|
||||
bool run;
|
||||
uint32 delay;
|
||||
uint32 event_id;
|
||||
uint8 event_chance;
|
||||
};
|
||||
|
||||
typedef std::vector<WaypointData*> WaypointPath;
|
||||
extern UNORDERED_MAP<uint32, WaypointPath*> waypoint_map;
|
||||
|
||||
class WaypointStore
|
||||
{
|
||||
private :
|
||||
uint32 records;
|
||||
|
||||
public:
|
||||
void UpdatePath(uint32 id);
|
||||
void Load();
|
||||
void Free();
|
||||
|
||||
WaypointPath* GetPath(uint32 id)
|
||||
{
|
||||
if(waypoint_map.find(id) != waypoint_map.end())
|
||||
return waypoint_map[id];
|
||||
else return 0;
|
||||
}
|
||||
|
||||
inline uint32 GetRecordsCount() { return records; }
|
||||
};
|
||||
|
||||
extern WaypointStore WaypointMgr;
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,140 +1,118 @@
|
||||
/*
|
||||
* 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
|
||||
* (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
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_WAYPOINTMOVEMENTGENERATOR_H
|
||||
#define TRINITY_WAYPOINTMOVEMENTGENERATOR_H
|
||||
|
||||
/** @page PathMovementGenerator is used to generate movements
|
||||
* of waypoints and flight paths. Each serves the purpose
|
||||
* of generate activities so that it generates updated
|
||||
* packets for the players.
|
||||
*/
|
||||
|
||||
#include "MovementGenerator.h"
|
||||
#include "DestinationHolder.h"
|
||||
#include "WaypointManager.h"
|
||||
#include "Path.h"
|
||||
#include "Traveller.h"
|
||||
|
||||
#include "Player.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#define FLIGHT_TRAVEL_UPDATE 100
|
||||
#define STOP_TIME_FOR_PLAYER 3 * 60 * 1000 // 3 Minutes
|
||||
|
||||
template<class T, class P = Path>
|
||||
class TRINITY_DLL_SPEC PathMovementBase
|
||||
{
|
||||
public:
|
||||
PathMovementBase() : i_currentNode(0) {}
|
||||
virtual ~PathMovementBase() {};
|
||||
|
||||
inline bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); }
|
||||
|
||||
// template pattern, not defined .. override required
|
||||
void LoadPath(T &);
|
||||
void ReloadPath(T &);
|
||||
uint32 GetCurrentNode() const { return i_currentNode; }
|
||||
|
||||
protected:
|
||||
uint32 i_currentNode;
|
||||
DestinationHolder< Traveller<T> > i_destinationHolder;
|
||||
P i_path;
|
||||
};
|
||||
|
||||
/** WaypointMovementGenerator loads a series of way points
|
||||
* from the DB and apply it to the creature's movement generator.
|
||||
* Hence, the creature will move according to its predefined way points.
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
class TRINITY_DLL_SPEC WaypointMovementGenerator;
|
||||
|
||||
template<>
|
||||
class TRINITY_DLL_SPEC WaypointMovementGenerator<Creature>
|
||||
: public MovementGeneratorMedium< Creature, WaypointMovementGenerator<Creature> >,
|
||||
public PathMovementBase<Creature, WaypointPath*>
|
||||
{
|
||||
TimeTrackerSmall i_nextMoveTime;
|
||||
std::vector<bool> i_hasDone;
|
||||
public:
|
||||
WaypointMovementGenerator(Creature &) : i_nextMoveTime(0) {}
|
||||
~WaypointMovementGenerator() { ClearWaypoints(); }
|
||||
void Initialize(Creature &u)
|
||||
{
|
||||
i_nextMoveTime.Reset(0); // TODO: check the lower bound (0 is probably too small)
|
||||
u.StopMoving();
|
||||
LoadPath(u);
|
||||
}
|
||||
void Finalize(Creature &) {}
|
||||
void Reset(Creature &u) { ReloadPath(u); }
|
||||
bool Update(Creature &u, const uint32 &diff);
|
||||
|
||||
void MovementInform(Creature &);
|
||||
|
||||
MovementGeneratorType GetMovementGeneratorType() { return WAYPOINT_MOTION_TYPE; }
|
||||
|
||||
// now path movement implmementation
|
||||
void LoadPath(Creature &c);
|
||||
void ReloadPath(Creature &c) { ClearWaypoints(); LoadPath(c); }
|
||||
|
||||
// Player stoping creature
|
||||
bool IsStopedByPlayer() { return b_StopedByPlayer; }
|
||||
void SetStopedByPlayer(bool val) { b_StopedByPlayer = val; }
|
||||
|
||||
// statics
|
||||
static void Initialize(void);
|
||||
|
||||
bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; }
|
||||
private:
|
||||
void ClearWaypoints();
|
||||
bool b_StopedByPlayer;
|
||||
};
|
||||
|
||||
/** FlightPathMovementGenerator generates movement of the player for the paths
|
||||
* and hence generates ground and activities for the player.
|
||||
*/
|
||||
class TRINITY_DLL_SPEC FlightPathMovementGenerator
|
||||
: public MovementGeneratorMedium< Player, FlightPathMovementGenerator >,
|
||||
public PathMovementBase<Player>
|
||||
{
|
||||
uint32 i_pathId;
|
||||
std::vector<uint32> i_mapIds;
|
||||
public:
|
||||
explicit FlightPathMovementGenerator(uint32 id, uint32 startNode = 0) : i_pathId(id) { i_currentNode = startNode; }
|
||||
void Initialize(Player &);
|
||||
void Finalize(Player &);
|
||||
void Reset(Player &) {}
|
||||
bool Update(Player &, const uint32 &);
|
||||
MovementGeneratorType GetMovementGeneratorType() { return FLIGHT_MOTION_TYPE; }
|
||||
|
||||
void LoadPath(Player &);
|
||||
void ReloadPath(Player &) { /* don't reload flight path */ }
|
||||
|
||||
Path& GetPath() { return i_path; }
|
||||
uint32 GetPathAtMapEnd() const;
|
||||
inline bool HasArrived() const { return (i_currentNode >= i_path.Size()); }
|
||||
void SetCurrentNodeAfterTeleport();
|
||||
void SkipCurrentNode() { ++i_currentNode; }
|
||||
bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; }
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* 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
|
||||
* (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
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_WAYPOINTMOVEMENTGENERATOR_H
|
||||
#define TRINITY_WAYPOINTMOVEMENTGENERATOR_H
|
||||
|
||||
/** @page PathMovementGenerator is used to generate movements
|
||||
* of waypoints and flight paths. Each serves the purpose
|
||||
* of generate activities so that it generates updated
|
||||
* packets for the players.
|
||||
*/
|
||||
|
||||
#include "MovementGenerator.h"
|
||||
#include "DestinationHolder.h"
|
||||
#include "WaypointManager.h"
|
||||
#include "Path.h"
|
||||
#include "Traveller.h"
|
||||
|
||||
#include "Player.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#define FLIGHT_TRAVEL_UPDATE 100
|
||||
#define STOP_TIME_FOR_PLAYER 3 * 60 * 1000 // 3 Minutes
|
||||
|
||||
template<class T, class P = Path>
|
||||
class TRINITY_DLL_SPEC PathMovementBase
|
||||
{
|
||||
public:
|
||||
PathMovementBase() : i_currentNode(0) {}
|
||||
virtual ~PathMovementBase() {};
|
||||
|
||||
inline bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); }
|
||||
|
||||
void LoadPath(T &);
|
||||
void ReloadPath(T &);
|
||||
uint32 GetCurrentNode() const { return i_currentNode; }
|
||||
|
||||
protected:
|
||||
uint32 i_currentNode;
|
||||
DestinationHolder< Traveller<T> > i_destinationHolder;
|
||||
P i_path;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
||||
class TRINITY_DLL_SPEC WaypointMovementGenerator
|
||||
: public MovementGeneratorMedium< T, WaypointMovementGenerator<T> >, public PathMovementBase<T>
|
||||
{
|
||||
public:
|
||||
WaypointMovementGenerator(uint32 _path_id = 0, bool _repeating = true) :
|
||||
i_nextMoveTime(0), path_id(_path_id), repeating(_repeating), StopedByPlayer(false){}
|
||||
|
||||
void Initialize(T &);
|
||||
void Finalize(T &);
|
||||
void MovementInform(T &);
|
||||
void InitTraveller(T &, const WaypointData &);
|
||||
void GeneratePathId(T &);
|
||||
void Reset(T &unit);
|
||||
bool Update(T &, const uint32 &);
|
||||
bool GetDestination(float &x, float &y, float &z) const{if(i_destinationHolder.HasArrived())return false; i_destinationHolder.GetDestination(x, y, z); return true;}
|
||||
MovementGeneratorType GetMovementGeneratorType() { return WAYPOINT_MOTION_TYPE; }
|
||||
|
||||
private:
|
||||
WaypointData node;
|
||||
uint32 i_currentNode, path_id;
|
||||
TimeTrackerSmall i_nextMoveTime;
|
||||
WaypointPath *waypoints;
|
||||
bool repeating, custom_path, ExecuteScript, StopedByPlayer;
|
||||
};
|
||||
|
||||
/** FlightPathMovementGenerator generates movement of the player for the paths
|
||||
* and hence generates ground and activities for the player.
|
||||
*/
|
||||
class TRINITY_DLL_SPEC FlightPathMovementGenerator
|
||||
: public MovementGeneratorMedium< Player, FlightPathMovementGenerator >,
|
||||
public PathMovementBase<Player>
|
||||
{
|
||||
uint32 i_pathId;
|
||||
std::vector<uint32> i_mapIds;
|
||||
public:
|
||||
explicit FlightPathMovementGenerator(uint32 id, uint32 startNode = 0) : i_pathId(id) { i_currentNode = startNode; }
|
||||
void Initialize(Player &);
|
||||
void Finalize(Player &);
|
||||
void Reset(Player &) {}
|
||||
bool Update(Player &, const uint32 &);
|
||||
MovementGeneratorType GetMovementGeneratorType() { return FLIGHT_MOTION_TYPE; }
|
||||
|
||||
void LoadPath(Player &);
|
||||
void ReloadPath(Player &) { /* don't reload flight path */ }
|
||||
|
||||
Path& GetPath() { return i_path; }
|
||||
uint32 GetPathAtMapEnd() const;
|
||||
inline bool HasArrived() const { return (i_currentNode >= i_path.Size()); }
|
||||
void SetCurrentNodeAfterTeleport();
|
||||
void SkipCurrentNode() { ++i_currentNode; }
|
||||
bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; }
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
+27
-3
@@ -1271,6 +1271,7 @@ void World::SetInitialWorldSettings()
|
||||
objmgr.LoadSpellScripts(); // must be after load Creature/Gameobject(Template/Data)
|
||||
objmgr.LoadGameObjectScripts(); // must be after load Creature/Gameobject(Template/Data)
|
||||
objmgr.LoadEventScripts(); // must be after load Creature/Gameobject(Template/Data)
|
||||
objmgr.LoadWaypointScripts();
|
||||
|
||||
sLog.outString( "Loading Scripts text locales..." ); // must be after Load*Scripts calls
|
||||
objmgr.LoadDbScriptStrings();
|
||||
@@ -1313,7 +1314,6 @@ void World::SetInitialWorldSettings()
|
||||
|
||||
///- Initilize static helper structures
|
||||
AIRegistry::Initialize();
|
||||
WaypointMovementGenerator<Creature>::Initialize();
|
||||
Player::InitVisibleBits();
|
||||
|
||||
///- Initialize MapManager
|
||||
@@ -2203,8 +2203,32 @@ void World::ScriptsProcess()
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
case SCRIPT_COMMAND_LOAD_PATH:
|
||||
{
|
||||
if(!source)
|
||||
{
|
||||
sLog.outError("SCRIPT_COMMAND_START_MOVE is tried to apply to NON-existing unit.");
|
||||
break;
|
||||
}
|
||||
|
||||
if(!source->isType(TYPEMASK_UNIT))
|
||||
{
|
||||
sLog.outError("SCRIPT_COMMAND_START_MOVE source mover isn't unit (TypeId: %u), skipping.",source->GetTypeId());
|
||||
break;
|
||||
}
|
||||
|
||||
if(!WaypointMgr.GetPath(step.script->datalong))
|
||||
{
|
||||
sLog.outError("SCRIPT_COMMAND_START_MOVE source mover has an invallid path, skipping.", step.script->datalong2);
|
||||
break;
|
||||
}
|
||||
|
||||
dynamic_cast<Unit*>(source)->GetMotionMaster()->MovePath(step.script->datalong, step.script->datalong2);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
sLog.outError("Unknown script command %u called.",step.script->command);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -326,6 +326,7 @@ enum RealmZone
|
||||
#define SCRIPT_COMMAND_ACTIVATE_OBJECT 13 // source = unit, target=GO
|
||||
#define SCRIPT_COMMAND_REMOVE_AURA 14 // source (datalong2!=0) or target (datalong==0) unit, datalong = spell_id
|
||||
#define SCRIPT_COMMAND_CAST_SPELL 15 // source (datalong2!=0) or target (datalong==0) unit, datalong = spell_id
|
||||
#define SCRIPT_COMMAND_LOAD_PATH 16 // source = unit, path = datalong, repeatable datalong2
|
||||
|
||||
/// Storage class for commands issued for delayed execution
|
||||
struct CliCommandHolder
|
||||
|
||||
@@ -29,9 +29,9 @@ extern DatabaseMysql WorldDatabase;
|
||||
|
||||
const char CreatureInfosrcfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiilliiis";
|
||||
const char CreatureInfodstfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiilliiii";
|
||||
const char CreatureDataAddonInfofmt[]="iiiiiiis";
|
||||
const char CreatureDataAddonInfofmt[]="iiiiiiiis";
|
||||
const char CreatureModelfmt[]="iffbi";
|
||||
const char CreatureInfoAddonInfofmt[]="iiiiiiis";
|
||||
const char CreatureInfoAddonInfofmt[]="iiiiiiiis";
|
||||
const char EquipmentInfofmt[]="iiiiiiiiii";
|
||||
const char GameObjectInfosrcfmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiis";
|
||||
const char GameObjectInfodstfmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiii";
|
||||
|
||||
Reference in New Issue
Block a user