aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/444_world.sql36
-rw-r--r--sql/world.sql67
-rw-r--r--src/game/Chat.cpp22
-rw-r--r--src/game/Chat.h18
-rw-r--r--src/game/Creature.cpp4
-rw-r--r--src/game/Creature.h18
-rw-r--r--src/game/Level2.cpp1357
-rw-r--r--src/game/Level3.cpp23
-rw-r--r--src/game/MotionMaster.cpp25
-rw-r--r--src/game/MotionMaster.h1
-rw-r--r--src/game/MovementGeneratorImpl.h3
-rw-r--r--src/game/ObjectMgr.cpp16
-rw-r--r--src/game/ObjectMgr.h2
-rw-r--r--src/game/RandomMovementGenerator.h2
-rw-r--r--src/game/World.cpp28
-rw-r--r--src/game/World.h1
-rw-r--r--src/shared/Database/SQLStorage.cpp4
17 files changed, 886 insertions, 741 deletions
diff --git a/sql/updates/444_world.sql b/sql/updates/444_world.sql
new file mode 100644
index 00000000000..004cf626f88
--- /dev/null
+++ b/sql/updates/444_world.sql
@@ -0,0 +1,36 @@
+DROP TABLE IF EXISTS `waypoint_data`;
+
+CREATE TABLE `waypoint_data` (
+ `id` int(10) unsigned NOT NULL default '0' COMMENT 'Creature GUID',
+ `point` mediumint(8) unsigned NOT NULL default '0',
+ `position_x` float NOT NULL default '0',
+ `position_y` float NOT NULL default '0',
+ `position_z` float NOT NULL default '0',
+ `delay` int(10) unsigned NOT NULL default '0',
+ `move_flag` tinyint(1) NOT NULL default '0',
+ `action` int(11) NOT NULL default '0',
+ `action_chance` smallint(3) NOT NULL default '100',
+ `wpguid` int(11) NOT NULL default '0'
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `waypoint_scripts`;
+
+CREATE TABLE `waypoint_scripts` (
+ `id` int(11) unsigned NOT NULL default '0',
+ `delay` int(11) unsigned NOT NULL default '0',
+ `command` int(11) unsigned NOT NULL default '0',
+ `datalong` int(11) unsigned NOT NULL default '0',
+ `datalong2` int(11) unsigned NOT NULL default '0',
+ `dataint` int(11) unsigned NOT NULL default '0',
+ `x` float NOT NULL default '0',
+ `y` float NOT NULL default '0',
+ `z` float NOT NULL default '0',
+ `o` float NOT NULL default '0',
+ `guid` int(11) NOT NULL default '0',
+ PRIMARY KEY (`guid`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+ALTER TABLE `creature_addon`
+ ADD `path_id` int(11) unsigned NOT NULL default '0' AFTER `guid`;
+ALTER TABLE `creature_template_addon`
+ ADD `path_id` int(11) unsigned NOT NULL default '0' AFTER `entry`;
diff --git a/sql/world.sql b/sql/world.sql
index 01c94db3ce6..ca5af56edd1 100644
--- a/sql/world.sql
+++ b/sql/world.sql
@@ -220,6 +220,7 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `creature_addon`;
CREATE TABLE `creature_addon` (
`guid` int(10) unsigned NOT NULL default '0',
+ `path_id` int(11) unsigned NOT NULL default '0',
`mount` mediumint(8) unsigned NOT NULL default '0',
`bytes0` int(10) unsigned NOT NULL default '0',
`bytes1` int(10) unsigned NOT NULL default '0',
@@ -337,39 +338,62 @@ LOCK TABLES `creature_model_info` WRITE;
/*!40000 ALTER TABLE `creature_model_info` ENABLE KEYS */;
UNLOCK TABLES;
+
--
--- Table structure for table `creature_movement`
+-- Table structure for table `waypoint_data`
--
-DROP TABLE IF EXISTS `creature_movement`;
-CREATE TABLE `creature_movement` (
- `id` int(10) unsigned NOT NULL COMMENT 'Creature GUID',
+DROP TABLE IF EXISTS `waypoint_data`;
+CREATE TABLE `waypoint_data` (
+ `id` int(10) unsigned NOT NULL default '0' COMMENT 'Creature GUID',
`point` mediumint(8) unsigned NOT NULL default '0',
`position_x` float NOT NULL default '0',
`position_y` float NOT NULL default '0',
`position_z` float NOT NULL default '0',
- `waittime` int(10) unsigned NOT NULL default '0',
- `text1` text,
- `text2` text,
- `text3` text,
- `text4` text,
- `text5` text,
- `emote` mediumint(8) unsigned NOT NULL default '0',
- `spell` mediumint(8) unsigned NOT NULL default '0',
- `wpguid` int(11) NOT NULL default '0',
- `orientation` float NOT NULL default '0',
- `model1` mediumint(9) NOT NULL default '0',
- `model2` mediumint(9) NOT NULL default '0',
- PRIMARY KEY (`id`,`point`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Creature System';
+ `delay` int(10) unsigned NOT NULL default '0',
+ `move_flag` tinyint(1) NOT NULL default '0',
+ `action` int(11) NOT NULL default '0',
+ `action_chance` smallint(3) NOT NULL default '100',
+ `wpguid` int(11) NOT NULL default '0'
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+--
+-- Dumping data for table `creature_movement`
+--
+
+LOCK TABLES `waypoint_data` WRITE;
+/*!40000 ALTER TABLE `waypoint_data` DISABLE KEYS */;
+/*!40000 ALTER TABLE `waypoint_data` ENABLE KEYS */;
+UNLOCK TABLES;
+
+
+--
+-- Table structure for table `waypoint_scripts`
+--
+
+DROP TABLE IF EXISTS `waypoint_scripts`;
+CREATE TABLE `waypoint_scripts` (
+ `id` int(11) unsigned NOT NULL default '0',
+ `delay` int(11) unsigned NOT NULL default '0',
+ `command` int(11) unsigned NOT NULL default '0',
+ `datalong` int(11) unsigned NOT NULL default '0',
+ `datalong2` int(11) unsigned NOT NULL default '0',
+ `dataint` int(11) unsigned NOT NULL default '0',
+ `x` float NOT NULL default '0',
+ `y` float NOT NULL default '0',
+ `z` float NOT NULL default '0',
+ `o` float NOT NULL default '0',
+ `guid` int(11) NOT NULL default '0',
+ PRIMARY KEY (`guid`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Dumping data for table `creature_movement`
--
-LOCK TABLES `creature_movement` WRITE;
-/*!40000 ALTER TABLE `creature_movement` DISABLE KEYS */;
-/*!40000 ALTER TABLE `creature_movement` ENABLE KEYS */;
+LOCK TABLES `waypoint_scripts` WRITE;
+/*!40000 ALTER TABLE `waypoint_scripts` DISABLE KEYS */;
+/*!40000 ALTER TABLE `waypoint_scripts` ENABLE KEYS */;
UNLOCK TABLES;
--
@@ -533,6 +557,7 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `creature_template_addon`;
CREATE TABLE `creature_template_addon` (
`entry` mediumint(8) unsigned NOT NULL default '0',
+ `path_id' int(11) unsigned NOT NULL default '0',
`mount` mediumint(8) unsigned NOT NULL default '0',
`bytes0` int(10) unsigned NOT NULL default '0',
`bytes1` int(10) unsigned NOT NULL default '0',
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index 951f443e479..09af5f18c78 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -137,13 +137,16 @@ ChatCommand * ChatHandler::getCommandTable()
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 }
+ { "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[] =
{
{ "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanAccountCommand, "", NULL },
@@ -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 },
diff --git a/src/game/Chat.h b/src/game/Chat.h
index b62bae39d17..57e1b486189 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -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);
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 80eba6fde98..3e2a6e72dfd 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -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)
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 31386d3b180..457e88cc3e3 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -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())
};
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index bb6a4473e0b..89d27582195 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -1371,11 +1371,9 @@ bool ChatHandler::HandleNpcAddMoveCommand(const char* args)
Player* player = m_session->GetPlayer();
- WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), wait, 0);
-
// update movement type
WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
- if(pCreature)
+ if(pCreature && pCreature->GetWaypointPath())
{
pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
pCreature->GetMotionMaster()->Initialize();
@@ -1387,8 +1385,6 @@ bool ChatHandler::HandleNpcAddMoveCommand(const char* args)
pCreature->SaveToDB();
}
- SendSysMessage(LANG_WAYPOINT_ADDED);
-
return true;
}
@@ -1507,13 +1503,13 @@ bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)
else
return false;
- // update movement type
- if(doNotDelete == false)
- WaypointMgr.DeletePath(lowguid);
-
if(pCreature)
{
- pCreature->SetDefaultMovementType(move_type);
+ // update movement type
+ if(doNotDelete == false)
+ pCreature->LoadPath(0);
+
+ pCreature->SetDefaultMovementType(move_type);
pCreature->GetMotionMaster()->Initialize();
if(pCreature->isAlive()) // dead creature will reset movement generator at respawn
{
@@ -2160,190 +2156,414 @@ bool ChatHandler::HandleNpcSpawnTimeCommand(const char* args)
return true;
}
-/**
- * Add a waypoint to a creature.
- *
- * The user can either select an npc or provide its GUID.
- *
- * The user can even select a visual waypoint - then the new waypoint
- * is placed *after* the selected one - this makes insertion of new
- * waypoints possible.
- *
- * eg:
- * .wp add 12345
- * -> adds a waypoint to the npc with the GUID 12345
- *
- * .wp add
- * -> adds a waypoint to the currently selected creature
- *
- *
- * @param args if the user did not provide a GUID, it is NULL
- *
- * @return true - command did succeed, false - something went wrong
- */
+/////WAYPOINT COMMANDS
+
bool ChatHandler::HandleWpAddCommand(const char* args)
{
sLog.outDebug("DEBUG: HandleWpAddCommand");
// optional
- char* guid_str = NULL;
-
+ char* path_number = NULL;
+ uint32 pathid = 0;
+
if(*args)
- {
- guid_str = strtok((char*)args, " ");
- }
-
- uint32 lowguid = 0;
+ path_number = strtok((char*)args, " ");
+
uint32 point = 0;
Creature* target = getSelectedCreature();
- // Did player provide a GUID?
- if (!guid_str)
+
+ if (!path_number)
+ {
+ if(target)
+ pathid = target->GetWaypointPath();
+ else
+ {
+ QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(id) FROM waypoint_data");
+ uint32 maxpathid = result->Fetch()->GetInt32();
+ pathid = maxpathid+1;
+ sLog.outDebug("DEBUG: HandleWpAddCommand - New path started.");
+ PSendSysMessage("%s%s|r", "|cff00ff00", "New path started.");
+
+ }
+ }
+ else
+ pathid = atoi(path_number);
+
+ // path_id -> ID of the Path
+ // point -> number of the waypoint (if not 0)
+
+ if(!pathid)
+ {
+ sLog.outDebug("DEBUG: HandleWpAddCommand - Current creature haven't loaded path.");
+ PSendSysMessage("%s%s|r", "|cffff33ff", "Current creature haven't loaded path.");
+ return true;
+ }
+
+ sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
+
+ QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM waypoint_data WHERE id = '%u'",pathid);
+
+ if( result )
{
- sLog.outDebug("DEBUG: HandleWpAddCommand - No GUID provided");
+ point = (*result)[0].GetUInt32();
+ delete result;
+ }
+
+ Player* player = m_session->GetPlayer();
+ Map *map = player->GetMap();
- // No GUID provided
- // -> Player must have selected a creature
+ WorldDatabase.PExecuteLog("INSERT INTO waypoint_data (id,point,position_x,position_y,position_z) VALUES ('%u','%u','%f', '%f', '%f')",
+ pathid, point+1, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
- if(!target || target->isPet())
- {
- SendSysMessage(LANG_SELECT_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
- if (target->GetEntry() == VISUAL_WAYPOINT )
- {
- sLog.outDebug("DEBUG: HandleWpAddCommand - target->GetEntry() == VISUAL_WAYPOINT (1) ");
+ PSendSysMessage("%s%s%u%s%u%s|r", "|cff00ff00", "PathID: |r|cff00ffff", pathid, "|r|cff00ff00: Waypoint |r|cff00ffff", point,"|r|cff00ff00 created. ");
+
+ return true;
+} // HandleWpAddCommand
- QueryResult *result =
- WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u",
- target->GetGUIDLow() );
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
- // User selected a visual spawnpoint -> get the NPC
- // Select NPC GUID
- // Since we compare float values, we have to deal with
- // some difficulties.
- // Here we search for all waypoints that only differ in one from 1 thousand
- // (0.001) - There is no other way to compare C++ floats with mySQL floats
- // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
- const char* maxDIFF = "0.01";
- result = WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
- target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
- SetSentErrorMessage(true);
- return false;
- }
- }
- do
- {
- Field *fields = result->Fetch();
- lowguid = fields[0].GetUInt32();
- point = fields[1].GetUInt32();
- }while( result->NextRow() );
- delete result;
+bool ChatHandler::HandleWpLoadPathCommand(const char *args)
+{
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
+ if(!*args)
+ return false;
+
+ // optional
+ char* path_number = NULL;
- target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
- if(!target)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- }
- else
- {
- lowguid = target->GetDBTableGUIDLow();
- }
+ if(*args)
+ {
+ path_number = strtok((char*)args, " ");
}
- else
- {
- sLog.outDebug("DEBUG: HandleWpAddCommand - GUID provided");
-
- // GUID provided
- // Warn if player also selected a creature
- // -> Creature selection is ignored <-
- if(target)
- {
- SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
- }
- lowguid = atoi((char*)guid_str);
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ uint32 pathid = 0;
+ uint32 guidlow = 0;
+ Creature* target = getSelectedCreature();
+
+ // Did player provide a path_id?
+ if (!path_number)
+ sLog.outDebug("DEBUG: HandleWpLoadPathCommand - No path number provided");
+
+ if(!target)
+ {
+ SendSysMessage(LANG_SELECT_CREATURE);
SetSentErrorMessage(true);
return false;
}
-
- target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
- if(!target || target->isPet())
+ if(target->GetEntry() == 1)
{
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
+ PSendSysMessage("%s%s|r", "|cffff33ff", "You want to load path to a waypoint? Aren't you?");
SetSentErrorMessage(true);
return false;
}
- }
- // lowguid -> GUID of the NPC
- // point -> number of the waypoint (if not 0)
- sLog.outDebug("DEBUG: HandleWpAddCommand - danach");
- sLog.outDebug("DEBUG: HandleWpAddCommand - point == 0");
+ pathid = atoi(path_number);
+ if(!pathid)
+ {
+ PSendSysMessage("%s%s|r", "|cffff33ff", "No vallid path number provided.");
+ return true;
+ }
+
+ guidlow = target->GetGUIDLow();
+
+ QueryResult *result = WorldDatabase.PQuery( "SELECT guid FROM creature_addon WHERE guid = '%u'",guidlow);
+
+ if( result )
+ {
+ WorldDatabase.PExecute("UPDATE creature_addon SET path_id = '%u' WHERE guid = '%u'", pathid, guidlow);
+ delete result;
+ }
+ else
+ WorldDatabase.PExecute("INSERT INTO creature_addon(guid,path_id) VALUES ('%u','%u')", guidlow, pathid);
+
+ WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE, guidlow);
+
+ target->LoadPath(pathid);
+
+ target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
+
+ target->GetMotionMaster()->Initialize();
+
+ target->Say("Path loaded.",0,0);
+
+ return true;
+}
- Player* player = m_session->GetPlayer();
- WaypointMgr.AddLastNode(lowguid, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0);
- // update movement type
- if(target)
+bool ChatHandler::HandleReloadAllPaths(const char* args)
+{
+if(!*args)
+ return false;
+
+uint32 id = atoi(args);
+
+if(!id)
+ return false;
+
+ PSendSysMessage("%s%s|r|cff00ffff%u|r", "|cff00ff00", "Loading Path: ", id);
+ WaypointMgr.UpdatePath(id);
+ return true;
+}
+
+bool ChatHandler::HandleWpUnLoadPathCommand(const char *args)
+{
+ uint32 guidlow = 0;
+ Creature* target = getSelectedCreature();
+
+ if(!target)
+ {
+ PSendSysMessage("%s%s|r", "|cff33ffff", "You must select target.");
+ return true;
+ }
+
+ if(target->GetCreatureAddon())
+ {
+ if(target->GetCreatureAddon()->path_id != 0)
+ {
+ WorldDatabase.PExecute("DELETE FROM creature_addon WHERE guid = %u", target->GetGUIDLow());
+ target->UpdateWaypointID(0);
+ WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", IDLE_MOTION_TYPE, guidlow);
+ target->LoadPath(0);
+ target->SetDefaultMovementType(IDLE_MOTION_TYPE);
+ target->GetMotionMaster()->MoveTargetedHome();
+ target->GetMotionMaster()->Initialize();
+ target->Say("Path unloaded.",0,0);
+ return true;
+ }
+ PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path.");
+ return true;
+ }
+ PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path.");
+ return true;
+}
+
+bool ChatHandler::HandleWpEventCommand(const char* args)
+{
+if(!*args)
+ return false;
+
+ char* show_str = strtok((char*)args, " ");
+
+ std::string show = show_str;
+
+ // Check
+ if( (show != "add") && (show != "mod") && (show != "del") && (show != "listid")) return false;
+
+
+ if(show == "add")
+ {
+ uint32 id = 0;
+ char* arg_id = strtok(NULL, " ");
+
+ if(arg_id)
+ uint32 id = atoi(arg_id);
+
+ if(id)
+ {
+ QueryResult *result = WorldDatabase.PQuery( "SELECT `id` FROM waypoint_scripts WHERE guid = %u", id);
+
+ if( !result )
+ {
+ WorldDatabase.PExecute("INSERT INTO waypoint_scripts(guid)VALUES(%u)", id);
+ PSendSysMessage("%s%s%u|r", "|cff00ff00", "Wp Event: New waypoint event added: ", id);
+ }
+ else
+ {
+ PSendSysMessage("|cff00ff00Wp Event: You have choosed an existing waypoint script guid: %u|r", id);
+ delete result;
+ }
+ }
+ else
+ {
+ QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(guid) FROM waypoint_scripts");
+ id = result->Fetch()->GetUInt32();
+ WorldDatabase.PExecute("INSERT INTO waypoint_scripts(guid)VALUES(%u)", id+1);
+ PSendSysMessage("%s%s%u|r", "|cff00ff00","Wp Event: New waypoint event added: |r|cff00ffff", id+1);
+ }
+
+ return true;
+ }
+
+
+ if(show == "listid")
+ {
+ uint32 id;
+ char* arg_id = strtok(NULL, " ");
+
+ if(!arg_id)
+ {
+ PSendSysMessage("%s%s|r", "|cff33ffff","Wp Event: You must provide waypoint script id.");
+ return true;
+ }
+
+ id = atoi(arg_id);
+
+ uint32 a2, a3, a4, a5, a6;
+ float a8, a9, a10, a11;
+ char const* a7;
+
+ QueryResult *result = WorldDatabase.PQuery( "SELECT `guid`, `delay`, `command`, `datalong`, `datalong2`, `dataint`, `x`, `y`, `z`, `o` FROM waypoint_scripts WHERE id = %u", id);
+
+ if( !result )
+ {
+ PSendSysMessage("%s%s%u|r", "|cff33ffff", "Wp Event: No waypoint scripts found on id: ", id);
+ return true;
+ }
+
+ Field *fields;
+
+ do
+ {
+ fields = result->Fetch();
+ a2 = fields[0].GetUInt32();
+ a3 = fields[1].GetUInt32();
+ a4 = fields[2].GetUInt32();
+ a5 = fields[3].GetUInt32();
+ a6 = fields[4].GetUInt32();
+ a7 = fields[5].GetString();
+ a8 = fields[6].GetFloat();
+ a9 = fields[7].GetFloat();
+ a10 = fields[8].GetFloat();
+ a11 = fields[9].GetFloat();
+
+ PSendSysMessage("|cffff33ffid:|r|cff00ffff %u|r|cff00ff00, guid: |r|cff00ffff%u|r|cff00ff00, delay: |r|cff00ffff%u|r|cff00ff00, command: |r|cff00ffff%u|r|cff00ff00, datalong: |r|cff00ffff%u|r|cff00ff00, datalong2: |r|cff00ffff%u|r|cff00ff00, datatext: |r|cff00ffff%s|r|cff00ff00, posx: |r|cff00ffff%f|r|cff00ff00, posy: |r|cff00ffff%f|r|cff00ff00, posz: |r|cff00ffff%f|r|cff00ff00, orientation: |r|cff00ffff%f|r", id, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+ }while(result->NextRow());
+
+ delete result;
+ }
+
+ if(show == "del")
+ {
+
+ char* arg_id = strtok(NULL, " ");
+ uint32 id = atoi(arg_id);
+
+ QueryResult *result = WorldDatabase.PQuery( "SELECT `guid` FROM waypoint_scripts WHERE guid = %u", id);
+
+ if( result )
{
- target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
- target->GetMotionMaster()->Initialize();
- if(target->isAlive()) // dead creature will reset movement generator at respawn
- {
- target->setDeathState(JUST_DIED);
- target->Respawn();
- }
- target->SaveToDB();
- }
+
+ WorldDatabase.PExecuteLog("DELETE FROM waypoint_scripts WHERE guid = %u", id);
+ PSendSysMessage("%s%s%u|r","|cff00ff00","Wp Event: Waypoint script removed: ", id);
+ delete result;
+ }
else
- WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
+ PSendSysMessage("|cffff33ffWp Event: ERROR: you have selected a non existing script: %u|r", id);
+
+ return true;
+ }
+
+
+ if(show == "mod")
+ {
+ char* arg_1 = strtok(NULL," ");
+
+ if(!arg_1)
+ {
+ SendSysMessage("|cffff33ffERROR: Waypoint script guid not present.|r");
+ return true;
+ }
+
+ uint32 id = atoi(arg_1);
- PSendSysMessage(LANG_WAYPOINT_ADDED, point, lowguid);
+ if(!id)
+ {
+ SendSysMessage("|cffff33ffERROR: No vallid waypoint script id not present.|r");
+ return true;
+ }
- return true;
-} // HandleWpAddCommand
+ char* arg_2 = strtok(NULL," ");
+
+ if(!arg_2)
+ { SendSysMessage("|cffff33ffERROR: No argument present.|r");
+ return true;}
+
+
+ std::string arg_string = arg_2;
+
+
+if( (arg_string != "setid") && (arg_string != "delay") && (arg_string != "command")
+&& (arg_string != "datalong") && (arg_string != "datalong2") && (arg_string != "dataint") && (arg_string != "posx")
+&& (arg_string != "posy") && (arg_string != "posz") && (arg_string != "orientation")
+) { SendSysMessage("|cffff33ffERROR: No valid argument present.|r");
+ return true;}
+
+
+char* arg_3;
+std::string arg_str_2 = arg_2;
+arg_3 = strtok(NULL," ");
+
+if(!arg_3)
+{SendSysMessage("|cffff33ffERROR: No additional argument present.|r");
+ return true;}
+
+float coord;
+
+ if(arg_str_2 == "setid")
+ {
+ uint32 newid = atoi(arg_3);
+ PSendSysMessage("%s%s|r|cff00ffff%u|r|cff00ff00%s|r|cff00ffff%u|r","|cff00ff00","Wp Event: Wypoint scipt guid: ", newid," id changed: ", id);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET id='%u' WHERE guid='%u'",
+ newid, id); return true;
+ }
+ else
+ {
+
+ QueryResult *result = WorldDatabase.PQuery("SELECT id FROM waypoint_scripts WHERE guid='%u'",id);
+
+ if(!result)
+ {
+ SendSysMessage("|cffff33ffERROR: You have selected an non existing waypoint script guid.|r");
+ return true;
+ }
+
+ delete result;
+
+if(arg_str_2 == "posx")
+{
+ coord = atof(arg_3);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET x='%f' WHERE guid='%u'",
+ coord, id);
+ PSendSysMessage("|cff00ff00Waypoint script:|r|cff00ffff %u|r|cff00ff00 position_x updated.|r", id);
+ return true;
+}else if(arg_str_2 == "posy")
+{
+ coord = atof(arg_3);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET y='%f' WHERE guid='%u'",
+ coord, id);
+ PSendSysMessage("|cff00ff00Waypoint script: %u position_y updated.|r", id);
+ return true;
+} else if(arg_str_2 == "posz")
+{
+ coord = atof(arg_3);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET z='%f' WHERE guid='%u'",
+ coord, id);
+ PSendSysMessage("|cff00ff00Waypoint script: |r|cff00ffff%u|r|cff00ff00 position_z updated.|r", id);
+ return true;
+} else if(arg_str_2 == "orientation")
+{
+ coord = atof(arg_3);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET o='%f' WHERE guid='%u'",
+ coord, id);
+ PSendSysMessage("|cff00ff00Waypoint script: |r|cff00ffff%u|r|cff00ff00 orientation updated.|r", id);
+ return true;
+} else if(arg_str_2 == "dataint")
+{
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET %s='%u' WHERE guid='%u'",
+ arg_2, atoi(arg_3), id);
+ PSendSysMessage("|cff00ff00Waypoint script: |r|cff00ffff%u|r|cff00ff00 dataint updated.|r", id);
+ return true;
+}else
+{
+ std::string arg_str_3 = arg_3;
+ WorldDatabase.escape_string(arg_str_3);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_scripts SET %s='%s' WHERE guid='%u'",
+ arg_2, arg_str_3.c_str(), id);
+}
+}
+ PSendSysMessage("%s%s|r|cff00ffff%u:|r|cff00ff00 %s %s|r","|cff00ff00","Waypoint script:", id, arg_2,"updated.");
+}
+return true;
+}
-/**
- * .wp modify emote | spell | text | del | move | add
- *
- * add -> add a WP after the selected visual waypoint
- * User must select a visual waypoint and then issue ".wp modify add"
- *
- * emote <emoteID>
- * User has selected a visual waypoint before.
- * <emoteID> is added to this waypoint. Everytime the
- * NPC comes to this waypoint, the emote is called.
- *
- * emote <GUID> <WPNUM> <emoteID>
- * User has not selected visual waypoint before.
- * For the waypoint <WPNUM> for the NPC with <GUID>
- * an emote <emoteID> is added.
- * Everytime the NPC comes to this waypoint, the emote is called.
- *
- *
- * info <GUID> <WPNUM> -> User did not select a visual waypoint and
- */
bool ChatHandler::HandleWpModifyCommand(const char* args)
{
sLog.outDebug("DEBUG: HandleWpModifyCommand");
@@ -2361,20 +2581,20 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
std::string show = show_str;
// Check
// Remember: "show" must also be the name of a column!
- if( (show != "emote") && (show != "spell") && (show != "textid1") && (show != "textid2")
- && (show != "textid3") && (show != "textid4") && (show != "textid5")
- && (show != "waittime") && (show != "del") && (show != "move") && (show != "add")
- && (show != "model1") && (show != "model2") && (show != "orientation"))
+ if( (show != "delay") && (show != "event_id") && (show != "event_chance")
+ && (show != "move_flag") && (show != "del") && (show != "move") && (show != "wpadd")
+ )
{
return false;
}
// Next arg is: <GUID> <WPNUM> <ARGUMENT>
+ char* arg_str = NULL;
// Did user provide a GUID
// or did the user select a creature?
// -> variable lowguid is filled with the GUID of the NPC
- uint32 lowguid = 0;
+ uint32 pathid = 0;
uint32 point = 0;
uint32 wpGuid = 0;
Creature* target = getSelectedCreature();
@@ -2383,244 +2603,203 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
{
sLog.outDebug("DEBUG: HandleWpModifyCommand - User did select an NPC");
+ // The visual waypoint
+ Creature* wpCreature = NULL;
+
+ wpGuid = target->GetGUIDLow();
+
// Did the user select a visual spawnpoint?
- if (target->GetEntry() != VISUAL_WAYPOINT )
- {
- PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
- SetSentErrorMessage(true);
- return false;
- }
- wpGuid = target->GetGUIDLow();
+ if(wpGuid)
+ wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
- // The visual waypoint
- QueryResult *result =
- WorldDatabase.PQuery( "SELECT id, point FROM creature_movement WHERE wpguid = %u LIMIT 1",
- target->GetGUIDLow() );
- if(!result)
+ // attempt check creature existence by DB data
+ else
{
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
- SetSentErrorMessage(true);
- return false;
+
+ QueryResult *result = WorldDatabase.PQuery( "SELECT guid FROM creature_addon WHERE path_id = '%u'",wpGuid);
+ if(!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, wpGuid);
+ return true;
+ }
+
}
- sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
+ // User did select a visual waypoint?
+ // Check the creature
+ if (wpCreature->GetEntry() == VISUAL_WAYPOINT )
+ {
+ QueryResult *result =
+ WorldDatabase.PQuery( "SELECT id, point FROM waypoint_data WHERE wpguid = %u",
+ wpGuid);
+ if(!result)
+ {
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - No waypoint found - used 'wpguid'");
- Field *fields = result->Fetch();
- lowguid = fields[0].GetUInt32();
- point = fields[1].GetUInt32();
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow());
+ // Select waypoint number from database
+ // Since we compare float values, we have to deal with
+ // some difficulties.
+ // Here we search for all waypoints that only differ in one from 1 thousand
+ // (0.001) - There is no other way to compare C++ floats with mySQL floats
+ // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
+ const char* maxDIFF = "0.01";
+ result = WorldDatabase.PQuery( "SELECT id, point FROM waypoint_data WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
+ wpCreature->GetPositionX(), maxDIFF, wpCreature->GetPositionY(), maxDIFF, wpCreature->GetPositionZ(), maxDIFF);
+ if(!result)
+ {
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid);
+ return true;
+ }
+ }
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - After getting wpGuid");
- // Cleanup memory
- sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
- delete result;
+ do
+ {
+ Field *fields = result->Fetch();
+ pathid = fields[0].GetUInt32();
+ point = fields[1].GetUInt32();
+ }while( result->NextRow() );
+
+ // Cleanup memory
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - Cleanup memory");
+ delete result;
+ // We have the waypoint number and the GUID of the "master npc"
+ // Text is enclosed in "<>", all other arguments not
+
+ arg_str = strtok((char*)NULL, " ");
+
+ }
}
else
{
// User did provide <GUID> <WPNUM>
-
char* guid_str = strtok((char*)NULL, " ");
- if( !guid_str )
- {
- SendSysMessage(LANG_WAYPOINT_NOGUID);
- return false;
- }
- lowguid = atoi((char*)guid_str);
+ char* point_str = strtok((char*)NULL, " ");
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
+ arg_str = strtok((char*)NULL, " ");
+
+ if( !guid_str )
{
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
+ SendSysMessage(LANG_WAYPOINT_NOGUID);
return false;
}
- PSendSysMessage("DEBUG: GUID provided: %d", lowguid);
-
- char* point_str = strtok((char*)NULL, " ");
if( !point_str )
{
SendSysMessage(LANG_WAYPOINT_NOWAYPOINTGIVEN);
return false;
}
- point = atoi((char*)point_str);
-
- PSendSysMessage("DEBUG: wpNumber provided: %d", point);
-
- // Now we need the GUID of the visual waypoint
- // -> "del", "move", "add" command
-
- QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' AND point = '%u' LIMIT 1", lowguid, point);
- if (!result)
+ if( (show != "del") && (show != "move") )
{
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, lowguid, point);
- SetSentErrorMessage(true);
- return false;
+ if( !arg_str )
+ {
+ PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show.c_str());
+ return false;
+ }
}
- Field *fields = result->Fetch();
- wpGuid = fields[0].GetUInt32();
+ pathid = atoi((char*)guid_str);
+ PSendSysMessage("|cff33ffffDEBUG: GUID provided: %d|r", pathid);
- // Free memory
- delete result;
- }
+ point = atoi((char*)point_str);
+ PSendSysMessage("|cff33ffffDEBUG: wpNumber provided: %d|r", point);
- char* arg_str = NULL;
- // Check for argument
- if( (show.find("text") == std::string::npos ) && (show != "del") && (show != "move") && (show != "add"))
- {
- // Text is enclosed in "<>", all other arguments not
- if( show.find("text") != std::string::npos )
- arg_str = strtok((char*)NULL, "<>");
- else
- arg_str = strtok((char*)NULL, " ");
+ // Now we need the GUID of the visual waypoint
+ // -> "del", "move", "add" command
- if( !arg_str)
+ QueryResult *result = WorldDatabase.PQuery( "SELECT wpguid FROM waypoint_data WHERE id = '%u' AND point = '%u'", pathid, point);
+ if(result)
{
- PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
- return false;
- }
- }
-
- sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
- // wpGuid -> GUID of the waypoint creature
- // lowguid -> GUID of the NPC
- // point -> waypoint number
-
- // Special functions:
- // add - move - del -> no args commands
- // Add a waypoint after the selected visual
- if(show == "add" && target)
- {
- PSendSysMessage("DEBUG: wp modify add, GUID: %u", lowguid);
-
- // Get the creature for which we read the waypoint
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
+ do
+ {
+ Field *fields = result->Fetch();
+ wpGuid = fields[0].GetUInt32();
+ }while( result->NextRow() );
- Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
- if( !npcCreature )
- {
- PSendSysMessage(LANG_WAYPOINT_NPCNOTFOUND);
- SetSentErrorMessage(true);
- return false;
+ // Free memory
+ delete result;
}
-
- sLog.outDebug("DEBUG: HandleWpModifyCommand - add -- npcCreature");
-
- // What to do:
- // Add the visual spawnpoint (DB only)
- // Adjust the waypoints
- // Respawn the owner of the waypoints
- sLog.outDebug("DEBUG: HandleWpModifyCommand - add");
-
- Player* chr = m_session->GetPlayer();
- Map *map = chr->GetMap();
-
- if(npcCreature)
+ else
{
- npcCreature->GetMotionMaster()->Initialize();
- if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, pathid, point);
+ // Select waypoint number from database
+ QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM waypoint_data WHERE point='%d' AND id = '%u'", point, pathid);
+ if(!result)
{
- npcCreature->setDeathState(JUST_DIED);
- npcCreature->Respawn();
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid);
+ return true;
}
- }
- // create the waypoint creature
- wpGuid = 0;
- Creature* wpCreature = new Creature;
- if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map,VISUAL_WAYPOINT,0))
- {
- PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
- delete wpCreature;
- }
- else
- {
- wpCreature->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
+ Field *fields = result->Fetch();
+ float x = fields[0].GetFloat();
+ float y = fields[1].GetFloat();
+ float z = fields[2].GetFloat();
+ // Cleanup memory
+ delete result;
- if(!wpCreature->IsPositionValid())
+ // Select waypoint number from database
+ // Since we compare float values, we have to deal with
+ // some difficulties.
+ // Here we search for all waypoints that only differ in one from 1 thousand
+ // (0.001) - There is no other way to compare C++ floats with mySQL floats
+ // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
+ const char* maxDIFF = "0.01";
+
+ result = WorldDatabase.PQuery( "SELECT guid FROM creature WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s ) and id=%d",
+ x, maxDIFF, y, maxDIFF, z, maxDIFF, VISUAL_WAYPOINT);
+ if(!result)
{
- sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
- delete wpCreature;
- }
- else
+
+ PSendSysMessage(LANG_WAYPOINT_WPCREATNOTFOUND, VISUAL_WAYPOINT);
+ return true;
+ }
+ do
{
- wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
- // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
- wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
- map->Add(wpCreature);
- wpGuid = wpCreature->GetGUIDLow();
- }
- }
+ Field *fields = result->Fetch();
+ wpGuid = fields[0].GetUInt32();
+ }while( result->NextRow() );
- WaypointMgr.AddAfterNode(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), 0, 0, wpGuid);
- if(!wpGuid)
- return false;
+ // Free memory
+ delete result;
- PSendSysMessage(LANG_WAYPOINT_ADDED_NO, point+1);
- return true;
- } // add
+ }
+ }
- if(show == "del" && target)
- {
- PSendSysMessage("DEBUG: wp modify del, GUID: %u", lowguid);
+ sLog.outDebug("DEBUG: HandleWpModifyCommand - Parameters parsed - now execute the command");
- // Get the creature for which we read the waypoint
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
+ // Check for argument
+ if((show != "del") && (show != "move"))
+ {
+ if( arg_str == NULL )
{
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
+ PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str);
return false;
}
+ }
- Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
+ if(show == "del" && target)
+ {
+ PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid);
+
+ // wpCreature
- // wpCreature
Creature* wpCreature = NULL;
if( wpGuid != 0 )
{
wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ wpCreature->CombatStop();
wpCreature->DeleteFromDB();
- wpCreature->CleanupsBeforeDelete();
wpCreature->AddObjectToRemoveList();
}
- // What to do:
- // Remove the visual spawnpoint
- // Adjust the waypoints
- // Respawn the owner of the waypoints
-
- WaypointMgr.DeleteNode(lowguid, point);
-
- if(npcCreature)
- {
- // Any waypoints left?
- QueryResult *result2 = WorldDatabase.PQuery( "SELECT point FROM creature_movement WHERE id = '%u'",lowguid);
- if(!result2)
- {
- npcCreature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
- }
- else
- {
- npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
- delete result2;
- }
- npcCreature->GetMotionMaster()->Initialize();
- if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- npcCreature->setDeathState(JUST_DIED);
- npcCreature->Respawn();
- }
- npcCreature->SaveToDB();
- }
+ WorldDatabase.PExecuteLog("DELETE FROM waypoint_data WHERE id='%u' AND point='%u'",
+ pathid, point);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET point=point-1 WHERE id='%u' AND point>'%u'",
+ pathid, point);
PSendSysMessage(LANG_WAYPOINT_REMOVED);
return true;
@@ -2628,32 +2807,21 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
if(show == "move" && target)
{
- PSendSysMessage("DEBUG: wp move, GUID: %u", lowguid);
+ PSendSysMessage("|cff00ff00DEBUG: wp move, PathID: |r|cff00ffff%u|r", pathid);
Player *chr = m_session->GetPlayer();
Map *map = chr->GetMap();
{
- // Get the creature for which we read the waypoint
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
-
- Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
-
- // wpCreature
- Creature* wpCreature = NULL;
+ // wpCreature
+ Creature* wpCreature = NULL;
// What to do:
// Move the visual spawnpoint
// Respawn the owner of the waypoints
if( wpGuid != 0 )
{
wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ wpCreature->CombatStop();
wpCreature->DeleteFromDB();
- wpCreature->CleanupsBeforeDelete();
wpCreature->AddObjectToRemoveList();
// re-create
Creature* wpCreature2 = new Creature;
@@ -2663,7 +2831,6 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
delete wpCreature2;
return false;
}
-
wpCreature2->Relocate(chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation());
if(!wpCreature2->IsPositionValid())
@@ -2680,81 +2847,38 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
//MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2);
}
- WaypointMgr.SetNodePosition(lowguid, point, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ());
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET position_x = '%f',position_y = '%f',position_z = '%f' where id = '%u' AND point='%u'",
+ chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), pathid, point );
- if(npcCreature)
- {
- npcCreature->GetMotionMaster()->Initialize();
- if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- npcCreature->setDeathState(JUST_DIED);
- npcCreature->Respawn();
- }
- }
PSendSysMessage(LANG_WAYPOINT_CHANGED);
}
return true;
} // move
- // Create creature - npc that has the waypoint
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- // set in game textids not supported
- if( show == "textid1" || show == "textid2" || show == "textid3" ||
- show == "textid4" || show == "textid5" )
+ const char *text = arg_str;
+
+ if( text == 0 )
{
- return false;
+ // show_str check for present in list of correct values, no sql injection possible
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET %s=NULL WHERE id='%u' AND point='%u'",
+ show_str, pathid, point);
}
-
- WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str);
-
- Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT));
- if(npcCreature)
+ else
{
- npcCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
- npcCreature->GetMotionMaster()->Initialize();
- if(npcCreature->isAlive()) // dead creature will reset movement generator at respawn
- {
- npcCreature->setDeathState(JUST_DIED);
- npcCreature->Respawn();
- }
+ // show_str check for present in list of correct values, no sql injection possible
+ std::string text2 = text;
+ WorldDatabase.escape_string(text2);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET %s='%s' WHERE id='%u' AND point='%u'",
+ show_str, text2.c_str(), pathid, point);
}
- PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
+
+ PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str);
return true;
}
-/**
- * .wp show info | on | off
- *
- * info -> User has selected a visual waypoint before
- *
- * info <GUID> <WPNUM> -> User did not select a visual waypoint and
- * provided the GUID of the NPC and the number of
- * the waypoint.
- *
- * on -> User has selected an NPC; all visual waypoints for this
- * NPC are added to the world
- *
- * on <GUID> -> User did not select an NPC - instead the GUID of the
- * NPC is provided. All visual waypoints for this NPC
- * are added from the world.
- *
- * off -> User has selected an NPC; all visual waypoints for this
- * NPC are removed from the world.
- *
- * on <GUID> -> User did not select an NPC - instead the GUID of the
- * NPC is provided. All visual waypoints for this NPC
- * are removed from the world.
- *
- *
- */
+
bool ChatHandler::HandleWpShowCommand(const char* args)
{
sLog.outDebug("DEBUG: HandleWpShowCommand");
@@ -2771,19 +2895,16 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
// second arg: GUID (optional, if a creature is selected)
char* guid_str = strtok((char*)NULL, " ");
sLog.outDebug("DEBUG: HandleWpShowCommand: show_str: %s guid_str: %s", show_str, guid_str);
- //if (!guid_str) {
- // return false;
- //}
+
+ uint32 pathid = 0;
+ Creature* target = getSelectedCreature();
+
+ // Did player provide a PathID?
- // Did user provide a GUID
- // or did the user select a creature?
- // -> variable lowguid is filled with the GUID
- Creature* target = getSelectedCreature();
- // Did player provide a GUID?
if (!guid_str)
{
sLog.outDebug("DEBUG: HandleWpShowCommand: !guid_str");
- // No GUID provided
+ // No PathID provided
// -> Player must have selected a creature
if(!target)
@@ -2792,11 +2913,14 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
SetSentErrorMessage(true);
return false;
}
- }
+
+ pathid = target->GetWaypointPath();
+ }
+
else
{
- sLog.outDebug("DEBUG: HandleWpShowCommand: GUID provided");
- // GUID provided
+ sLog.outDebug("|cff00ff00DEBUG: HandleWpShowCommand: PathID provided|r");
+ // PathID provided
// Warn if player also selected a creature
// -> Creature selection is ignored <-
if(target)
@@ -2804,118 +2928,86 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
SendSysMessage(LANG_WAYPOINT_CREATSELECTED);
}
- uint32 lowguid = atoi((char*)guid_str);
+ pathid = atoi((char*)guid_str);
+ }
- CreatureData const* data = objmgr.GetCreatureData(lowguid);
- if(!data)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- target = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT));
+ sLog.outDebug("DEBUG: HandleWpShowCommand: danach");
- if(!target)
- {
- PSendSysMessage(LANG_WAYPOINT_CREATNOTFOUND, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- }
- uint32 lowguid = target->GetDBTableGUIDLow();
std::string show = show_str;
uint32 Maxpoint;
- sLog.outDebug("DEBUG: HandleWpShowCommand: lowguid: %u show: %s", lowguid, show_str);
+ sLog.outDebug("DEBUG: HandleWpShowCommand: PathID: %u", pathid);
+
+ //PSendSysMessage("wpshow - show: %s", show);
// Show info for the selected waypoint
if(show == "info")
- {
- PSendSysMessage("DEBUG: wp info, GUID: %u", lowguid);
- // Check if the user did specify a visual waypoint
+ {
+
+ // Check if the user did specify a visual waypoint
if( target->GetEntry() != VISUAL_WAYPOINT )
+
{
PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
SetSentErrorMessage(true);
return false;
}
- //PSendSysMessage("wp on, GUID: %u", lowguid);
- //pCreature->GetPositionX();
+ QueryResult *result = WorldDatabase.PQuery( "SELECT id, point, delay, move_flag, action, action_chance FROM waypoint_data WHERE wpguid = %u", target->GetGUIDLow());
+
+ if(!result)
- QueryResult *result =
- WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u",
- target->GetGUIDLow() );
- if(!result)
{
- // Since we compare float values, we have to deal with
- // some difficulties.
- // Here we search for all waypoints that only differ in one from 1 thousand
- // (0.001) - There is no other way to compare C++ floats with mySQL floats
- // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
- const char* maxDIFF = "0.01";
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID());
-
- result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )",
- target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF);
- if(!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, lowguid);
- SetSentErrorMessage(true);
- return false;
- }
- }
- do
+ SendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM);
+ return true;
+ }
+
+ SendSysMessage("|cff00ffffDEBUG: wp show info:|r");
+
+ do
{
Field *fields = result->Fetch();
- uint32 creGUID = fields[0].GetUInt32();
- uint32 point = fields[1].GetUInt32();
- int waittime = fields[2].GetUInt32();
- uint32 emote = fields[3].GetUInt32();
- uint32 spell = fields[4].GetUInt32();
- uint32 textid[MAX_WAYPOINT_TEXT];
- for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
- textid[i] = fields[5+i].GetUInt32();
- uint32 model1 = fields[10].GetUInt32();
- uint32 model2 = fields[11].GetUInt32();
-
- // Get the creature for which we read the waypoint
- Creature* wpCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(creGUID,VISUAL_WAYPOINT,HIGHGUID_UNIT));
-
- PSendSysMessage(LANG_WAYPOINT_INFO_TITLE, point, (wpCreature ? wpCreature->GetName() : "<not found>"), creGUID);
- PSendSysMessage(LANG_WAYPOINT_INFO_WAITTIME, waittime);
- PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 1, model1);
- PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2);
- PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote);
- PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell);
- for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i)
- PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, i+1, textid[i], (textid[i] ? GetTrinityString(textid[i]) : ""));
-
- }while( result->NextRow() );
- // Cleanup memory
+ pathid = fields[0].GetUInt32();
+ uint32 point = fields[1].GetUInt32();
+ uint32 delay = fields[2].GetUInt32();
+ uint32 flag = fields[3].GetUInt32();
+ uint32 ev_id = fields[4].GetUInt32();
+ uint32 ev_chance = fields[5].GetUInt32();
+
+ PSendSysMessage("|cff00ff00Show info: for current point: |r|cff00ffff%u|r|cff00ff00, Path ID: |r|cff00ffff%u|r", point, pathid);
+ PSendSysMessage("|cff00ff00Show info: delay: |r|cff00ffff%u|r", delay);
+ PSendSysMessage("|cff00ff00Show info: Move flag: |r|cff00ffff%u|r", flag);
+ PSendSysMessage("|cff00ff00Show info: Waypoint event: |r|cff00ffff%u|r", ev_id);
+ PSendSysMessage("|cff00ff00Show info: Event chance: |r|cff00ffff%u|r", ev_chance);
+ }while( result->NextRow() );
+
+ // Cleanup memory
delete result;
return true;
}
if(show == "on")
- {
- PSendSysMessage("DEBUG: wp on, GUID: %u", lowguid);
-
- QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM creature_movement WHERE id = '%u'",lowguid);
- if(!result)
+ {
+ QueryResult *result = WorldDatabase.PQuery( "SELECT point, position_x,position_y,position_z FROM waypoint_data WHERE id = '%u'", pathid);
+
+ if(!result)
{
- PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
+ SendSysMessage("|cffff33ffPath no found.|r");
SetSentErrorMessage(true);
return false;
}
- // Delete all visuals for this NPC
- QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM creature_movement WHERE id = '%u' and wpguid <> 0", lowguid);
- if(result2)
+
+ PSendSysMessage("|cff00ff00DEBUG: wp on, PathID: |cff00ffff%u|r", pathid);
+
+ // Delete all visuals for this NPC
+ QueryResult *result2 = WorldDatabase.PQuery( "SELECT wpguid FROM waypoint_data WHERE id = '%u' and wpguid <> 0", pathid);
+
+ if(result2)
{
bool hasError = false;
do
@@ -2932,14 +3024,16 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
}
else
{
+ pCreature->CombatStop();
pCreature->DeleteFromDB();
- pCreature->CleanupsBeforeDelete();
pCreature->AddObjectToRemoveList();
}
}while( result2->NextRow() );
- delete result2;
- if( hasError )
+
+ delete result2;
+
+ if( hasError )
{
PSendSysMessage(LANG_WAYPOINT_TOOFAR1);
PSendSysMessage(LANG_WAYPOINT_TOOFAR2);
@@ -2969,10 +3063,10 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
delete result;
return false;
}
-
- wpCreature->Relocate(x, y, z, o);
-
- if(!wpCreature->IsPositionValid())
+
+ wpCreature->Relocate(x, y, z, o);
+
+ if(!wpCreature->IsPositionValid())
{
sLog.outError("ERROR: Creature (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)",wpCreature->GetGUIDLow(),wpCreature->GetEntry(),wpCreature->GetPositionX(),wpCreature->GetPositionY());
delete wpCreature;
@@ -2980,31 +3074,36 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
return false;
}
- wpCreature->SetVisibility(VISIBILITY_OFF);
- sLog.outDebug("DEBUG: UPDATE creature_movement SET wpguid = '%u");
+ sLog.outDebug("DEBUG: UPDATE waypoint_data SET wpguid = '%u");
// set "wpguid" column to the visual waypoint
- WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), pathid, point);
wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
- // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
map->Add(wpCreature);
- //MapManager::Instance().GetMap(wpCreature->GetMapId())->Add(wpCreature);
- }while( result->NextRow() );
+
+ if(target)
+ {
+ wpCreature->SetDisplayId(target->GetDisplayId());
+ wpCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
+ }
+ }
+ while( result->NextRow() );
- // Cleanup memory
+ SendSysMessage("|cff00ff00Showing the current creature's path.|r");
+ // Cleanup memory
delete result;
return true;
}
if(show == "first")
{
- PSendSysMessage("DEBUG: wp first, GUID: %u", lowguid);
+ PSendSysMessage("|cff00ff00DEBUG: wp first, GUID: %u|r", pathid);
- QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point='1' AND id = '%u'",lowguid);
+ QueryResult *result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM waypoint_data WHERE point='1' AND id = '%u'",pathid);
if(!result)
{
- PSendSysMessage(LANG_WAYPOINT_NOTFOUND, lowguid);
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid);
SetSentErrorMessage(true);
return false;
}
@@ -3037,22 +3136,27 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
delete result;
return false;
}
-
- pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
map->Add(pCreature);
- //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
-
- // Cleanup memory
+
+ if(target)
+ {
+ pCreature->SetDisplayId(target->GetDisplayId());
+ pCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
+ }
+
+ // Cleanup memory
delete result;
return true;
}
if(show == "last")
{
- PSendSysMessage("DEBUG: wp last, GUID: %u", lowguid);
+ PSendSysMessage("|cff00ff00DEBUG: wp last, PathID: |r|cff00ffff%u|r", pathid);
- QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM creature_movement WHERE id = '%u'",lowguid);
+ QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(point) FROM waypoint_data WHERE id = '%u'",pathid);
if( result )
{
Maxpoint = (*result)[0].GetUInt32();
@@ -3062,10 +3166,10 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
else
Maxpoint = 0;
- result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM creature_movement WHERE point ='%u' AND id = '%u'",Maxpoint, lowguid);
+ result = WorldDatabase.PQuery( "SELECT position_x,position_y,position_z FROM waypoint_data WHERE point ='%u' AND id = '%u'",Maxpoint, pathid);
if(!result)
{
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, lowguid);
+ PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, pathid);
SetSentErrorMessage(true);
return false;
}
@@ -3097,19 +3201,25 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
delete result;
return false;
}
-
- pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
+
+ pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
map->Add(pCreature);
- //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
- // Cleanup memory
+
+ if(target)
+ {
+ pCreature->SetDisplayId(target->GetDisplayId());
+ pCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5);
+ }
+
+ // Cleanup memory
delete result;
return true;
}
if(show == "off")
{
- QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%d'", VISUAL_WAYPOINT);
+ QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%u'", 1);
if(!result)
{
SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND);
@@ -3123,8 +3233,6 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
uint32 guid = fields[0].GetUInt32();
Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(),MAKE_NEW_GUID(guid,VISUAL_WAYPOINT,HIGHGUID_UNIT));
- //Creature* pCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), guid);
-
if(!pCreature)
{
PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid);
@@ -3133,13 +3241,15 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
}
else
{
+ pCreature->CombatStop();
+
pCreature->DeleteFromDB();
- pCreature->CleanupsBeforeDelete();
+
pCreature->AddObjectToRemoveList();
}
}while(result->NextRow());
// set "wpguid" column to "empty" - no visual waypoint spawned
- WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0'");
+ WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '0'");
if( hasError )
{
@@ -3155,155 +3265,12 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
return true;
}
- PSendSysMessage("DEBUG: wpshow - no valid command found");
-
- return true;
-} // HandleWpShowCommand
-
-bool ChatHandler::HandleWpExportCommand(const char *args)
-{
- if(!*args)
- return false;
-
- // Next arg is: <GUID> <ARGUMENT>
-
- // Did user provide a GUID
- // or did the user select a creature?
- // -> variable lowguid is filled with the GUID of the NPC
- uint32 lowguid = 0;
- Creature* target = getSelectedCreature();
- char* arg_str = NULL;
- if (target)
- {
- if (target->GetEntry() != VISUAL_WAYPOINT)
- lowguid = target->GetGUIDLow();
- else
- {
- QueryResult *result = WorldDatabase.PQuery( "SELECT id FROM creature_movement WHERE wpguid = %u LIMIT 1", target->GetGUIDLow() );
- if (!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, target->GetGUIDLow());
- return true;
- }
- Field *fields = result->Fetch();
- lowguid = fields[0].GetUInt32();;
- delete result;
- }
-
- arg_str = strtok((char*)args, " ");
- }
- else
- {
- // user provided <GUID>
- char* guid_str = strtok((char*)args, " ");
- if( !guid_str )
- {
- SendSysMessage(LANG_WAYPOINT_NOGUID);
- return false;
- }
- lowguid = atoi((char*)guid_str);
-
- arg_str = strtok((char*)NULL, " ");
- }
-
- if( !arg_str)
- {
- PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, "export");
- return false;
- }
-
- PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid);
-
- QueryResult *result = WorldDatabase.PQuery(
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid );
-
- if (!result)
- {
- PSendSysMessage(LANG_WAYPOINT_NOTHINGTOEXPORT);
- SetSentErrorMessage(true);
- return false;
- }
-
- std::ofstream outfile;
- outfile.open (arg_str);
-
- do
- {
- Field *fields = result->Fetch();
-
- outfile << "INSERT INTO creature_movement ";
- outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES ";
-
- outfile << "( ";
- outfile << fields[15].GetUInt32(); // id
- outfile << ", ";
- outfile << fields[0].GetUInt32(); // point
- outfile << ", ";
- outfile << fields[1].GetFloat(); // position_x
- outfile << ", ";
- outfile << fields[2].GetFloat(); // position_y
- outfile << ", ";
- outfile << fields[3].GetUInt32(); // position_z
- outfile << ", ";
- outfile << fields[4].GetUInt32(); // orientation
- outfile << ", ";
- outfile << fields[5].GetUInt32(); // model1
- outfile << ", ";
- outfile << fields[6].GetUInt32(); // model2
- outfile << ", ";
- outfile << fields[7].GetUInt16(); // waittime
- outfile << ", ";
- outfile << fields[8].GetUInt32(); // emote
- outfile << ", ";
- outfile << fields[9].GetUInt32(); // spell
- outfile << ", ";
- outfile << fields[10].GetUInt32(); // textid1
- outfile << ", ";
- outfile << fields[11].GetUInt32(); // textid2
- outfile << ", ";
- outfile << fields[12].GetUInt32(); // textid3
- outfile << ", ";
- outfile << fields[13].GetUInt32(); // textid4
- outfile << ", ";
- outfile << fields[14].GetUInt32(); // textid5
- outfile << ");\n ";
-
- } while( result->NextRow() );
- delete result;
-
- PSendSysMessage(LANG_WAYPOINT_EXPORTED);
- outfile.close();
+ PSendSysMessage("|cffff33ffDEBUG: wpshow - no valid command found|r");
return true;
}
-bool ChatHandler::HandleWpImportCommand(const char *args)
-{
- if(!*args)
- return false;
-
- char* arg_str = strtok((char*)args, " ");
- if (!arg_str)
- return false;
-
- std::string line;
- std::ifstream infile (arg_str);
- if (infile.is_open())
- {
- while (! infile.eof() )
- {
- getline (infile,line);
- //cout << line << endl;
- QueryResult *result = WorldDatabase.Query(line.c_str());
- delete result;
- }
- infile.close();
- }
- PSendSysMessage(LANG_WAYPOINT_IMPORTED);
-
- return true;
-}
+//////////// WAYPOINT COMMANDS //
//rename characters
bool ChatHandler::HandleRenameCommand(const char* args)
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index 51b9a092ba3..a5c6f54016c 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -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*)
@@ -542,6 +543,26 @@ bool ChatHandler::HandleReloadEventScriptsCommand(const char* arg)
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;
+}
+
bool ChatHandler::HandleReloadQuestEndScriptsCommand(const char* arg)
{
if(sWorld.IsScriptScheduled())
diff --git a/src/game/MotionMaster.cpp b/src/game/MotionMaster.cpp
index d3167e180a0..0195e3ebdf6 100644
--- a/src/game/MotionMaster.cpp
+++ b/src/game/MotionMaster.cpp
@@ -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();
diff --git a/src/game/MotionMaster.h b/src/game/MotionMaster.h
index f6d244db2db..3a17b8e135e 100644
--- a/src/game/MotionMaster.h
+++ b/src/game/MotionMaster.h
@@ -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;
diff --git a/src/game/MovementGeneratorImpl.h b/src/game/MovementGeneratorImpl.h
index c8270094b52..43c18ac6866 100644
--- a/src/game/MovementGeneratorImpl.h
+++ b/src/game/MovementGeneratorImpl.h
@@ -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
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 36d4317b3ec..1d359a2df7c 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -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);
diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
index 8c7f8728b0b..7dc6c1f8a9f 100644
--- a/src/game/ObjectMgr.h
+++ b/src/game/ObjectMgr.h
@@ -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); }
diff --git a/src/game/RandomMovementGenerator.h b/src/game/RandomMovementGenerator.h
index 229761423e6..2825bc306a8 100644
--- a/src/game/RandomMovementGenerator.h
+++ b/src/game/RandomMovementGenerator.h
@@ -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 &);
diff --git a/src/game/World.cpp b/src/game/World.cpp
index 04b3a1004c9..66054d95afb 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -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;
}
+
+ case SCRIPT_COMMAND_LOAD_PATH:
+ {
+ if(!source)
+ {
+ sLog.outError("SCRIPT_COMMAND_START_MOVE is tried to apply to NON-existing unit.");
+ break;
+ }
- default:
+ 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;
}
diff --git a/src/game/World.h b/src/game/World.h
index fc11301f883..885047e6685 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -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
diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp
index 720e6e3e683..4845841b6d6 100644
--- a/src/shared/Database/SQLStorage.cpp
+++ b/src/shared/Database/SQLStorage.cpp
@@ -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";