diff --git a/sql/mangos.sql b/sql/mangos.sql index 30c3353e3f2..c561da1d2ab 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_9886_02_mangos_command` bit(1) default NULL + `required_9891_02_mangos_creature_movement_scripts` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -984,6 +984,7 @@ CREATE TABLE `creature_movement` ( `position_y` float NOT NULL default '0', `position_z` float NOT NULL default '0', `waittime` int(10) unsigned NOT NULL default '0', + `script_id` int(10) unsigned NOT NULL default '0', `textid1` int(11) NOT NULL default '0', `textid2` int(11) NOT NULL default '0', `textid3` int(11) NOT NULL default '0', @@ -1007,6 +1008,36 @@ LOCK TABLES `creature_movement` WRITE; /*!40000 ALTER TABLE `creature_movement` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `creature_movement_scripts` +-- + +DROP TABLE IF EXISTS `creature_movement_scripts`; +CREATE TABLE `creature_movement_scripts` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `delay` int(10) unsigned NOT NULL default '0', + `command` mediumint(8) unsigned NOT NULL default '0', + `datalong` mediumint(8) unsigned NOT NULL default '0', + `datalong2` int(10) unsigned NOT NULL default '0', + `datalong3` int(10) unsigned NOT NULL default '0', + `datalong4` int(10) unsigned NOT NULL default '0', + `data_flags` tinyint(3) unsigned NOT NULL default '0', + `dataint` int(11) 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' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `creature_movement_scripts` +-- + +LOCK TABLES `creature_movement_scripts` WRITE; +/*!40000 ALTER TABLE `creature_movement_scripts` DISABLE KEYS */; +/*!40000 ALTER TABLE `creature_movement_scripts` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `creature_onkill_reputation` -- diff --git a/sql/updates/9891_01_mangos_creature_movement.sql b/sql/updates/9891_01_mangos_creature_movement.sql new file mode 100644 index 00000000000..89d38f27093 --- /dev/null +++ b/sql/updates/9891_01_mangos_creature_movement.sql @@ -0,0 +1,3 @@ +ALTER TABLE db_version CHANGE COLUMN required_9886_02_mangos_command required_9891_01_mangos_creature_movement bit; + +ALTER TABLE creature_movement ADD COLUMN script_id MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0' AFTER waittime; diff --git a/sql/updates/9891_02_mangos_creature_movement_scripts.sql b/sql/updates/9891_02_mangos_creature_movement_scripts.sql new file mode 100644 index 00000000000..e37fba3ce25 --- /dev/null +++ b/sql/updates/9891_02_mangos_creature_movement_scripts.sql @@ -0,0 +1,18 @@ +ALTER TABLE db_version CHANGE COLUMN required_9891_01_mangos_creature_movement required_9891_02_mangos_creature_movement_scripts bit; + +DROP TABLE IF EXISTS `creature_movement_scripts`; +CREATE TABLE `creature_movement_scripts` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `delay` int(10) unsigned NOT NULL default '0', + `command` mediumint(8) unsigned NOT NULL default '0', + `datalong` mediumint(8) unsigned NOT NULL default '0', + `datalong2` int(10) unsigned NOT NULL default '0', + `datalong3` int(10) unsigned NOT NULL default '0', + `datalong4` int(10) unsigned NOT NULL default '0', + `data_flags` tinyint(3) unsigned NOT NULL default '0', + `dataint` int(11) 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' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index f55e50d2ad9..431455d8691 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -62,6 +62,8 @@ pkgdata_DATA = \ 9883_01_mangos_scripts.sql \ 9886_01_mangos_mangos_string.sql \ 9886_02_mangos_command.sql \ + 9891_01_mangos_creature_movement.sql \ + 9891_02_mangos_creature_movement_scripts.sql \ README ## Additional files to include when running 'make dist' @@ -104,4 +106,6 @@ EXTRA_DIST = \ 9883_01_mangos_scripts.sql \ 9886_01_mangos_mangos_string.sql \ 9886_02_mangos_command.sql \ + 9891_01_mangos_creature_movement.sql \ + 9891_02_mangos_creature_movement_scripts.sql \ README diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 50c1c84a49f..4626884767d 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -57,6 +57,7 @@ ScriptMapMap sSpellScripts; ScriptMapMap sGameObjectScripts; ScriptMapMap sEventScripts; ScriptMapMap sGossipScripts; +ScriptMapMap sCreatureMovementScripts; bool normalizePlayerName(std::string& name) { @@ -4579,6 +4580,11 @@ void ObjectMgr::LoadGossipScripts() // checks are done in LoadGossipMenuItems } +void ObjectMgr::LoadCreatureMovementScripts() +{ + LoadScripts(sCreatureMovementScripts, "creature_movement_scripts"); +} + void ObjectMgr::LoadPageTexts() { sPageTextStore.Free(); // for reload case @@ -8477,6 +8483,7 @@ void ObjectMgr::LoadDbScriptStrings() CheckScripts(sGameObjectScripts,ids); CheckScripts(sEventScripts,ids); CheckScripts(sGossipScripts,ids); + CheckScripts(sCreatureMovementScripts,ids); sWaypointMgr.CheckTextsExistance(ids); diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 837d7fc45b5..7a60d017a4d 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -93,6 +93,7 @@ extern ScriptMapMap sSpellScripts; extern ScriptMapMap sGameObjectScripts; extern ScriptMapMap sEventScripts; extern ScriptMapMap sGossipScripts; +extern ScriptMapMap sCreatureMovementScripts; struct SpellClickInfo { @@ -595,6 +596,7 @@ class ObjectMgr void LoadEventScripts(); void LoadSpellScripts(); void LoadGossipScripts(); + void LoadCreatureMovementScripts(); bool LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value); bool LoadMangosStrings() { return LoadMangosStrings(WorldDatabase,"mangos_string",MIN_MANGOS_STRING_ID,MAX_MANGOS_STRING_ID); } diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp index 40ec6b8146e..528611dc684 100644 --- a/src/game/WaypointManager.cpp +++ b/src/game/WaypointManager.cpp @@ -85,8 +85,13 @@ void WaypointManager::Load() // 0 1 2 3 4 5 result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2," - // 6 7 8 9 10 11 12 13 14 15 - "waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id, point FROM creature_movement"); + // 6 7 8 9 10 11 12 13 14 15 16 + "waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id, point, script_id FROM creature_movement"); + + std::set movementScriptSet; + + for(ScriptMapMap::const_iterator itr = sCreatureMovementScripts.begin(); itr != sCreatureMovementScripts.end(); ++itr) + movementScriptSet.insert(itr->first); barGoLink bar( (int)result->GetRowCount() ); do @@ -111,6 +116,7 @@ void WaypointManager::Load() node.z = fields[2].GetFloat(); node.orientation = fields[3].GetFloat(); node.delay = fields[6].GetUInt32(); + node.script_id = fields[16].GetUInt32(); // prevent using invalid coordinates if(!MaNGOS::IsValidMapCoord(node.x, node.y, node.z, node.orientation)) @@ -132,6 +138,20 @@ void WaypointManager::Load() } 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); } + + if (node.script_id) + { + if (sCreatureMovementScripts.find(node.script_id) == sCreatureMovementScripts.end()) + { + sLog.outErrorDb("Table creature_movement for id %u, point %u have script_id %u that does not exist in `creature_movement_scripts`, ignoring", id, point, node.script_id); + continue; + } + + movementScriptSet.erase(node.script_id); + } + + // WaypointBehavior can be dropped in time. Script_id added may 2010 and can handle all the below behavior. + WaypointBehavior be; be.model1 = fields[4].GetUInt32(); be.model2 = fields[5].GetUInt32(); @@ -173,6 +193,12 @@ void WaypointManager::Load() } while( result->NextRow() ); delete result; + if (!movementScriptSet.empty()) + { + for(std::set::const_iterator itr = movementScriptSet.begin(); itr != movementScriptSet.end(); ++itr) + sLog.outErrorDb("Table `creature_movement_scripts` contain unused script, id %u.", *itr); + } + sLog.outString(); sLog.outString( ">> Waypoints and behaviors loaded" ); sLog.outString(); @@ -233,7 +259,7 @@ void WaypointManager::_addNode(uint32 id, uint32 point, float x, float y, float 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)); + itr->second.insert(itr->second.begin() + (point - 1), WaypointNode(x, y, z, o, delay, 0, NULL)); } uint32 WaypointManager::GetLastPoint(uint32 id, uint32 default_notfound) diff --git a/src/game/WaypointManager.h b/src/game/WaypointManager.h index ae8375a6b16..e0c0eb4f50d 100644 --- a/src/game/WaypointManager.h +++ b/src/game/WaypointManager.h @@ -45,10 +45,11 @@ struct WaypointNode float z; float orientation; uint32 delay; + uint32 script_id; // Added may 2010. WaypointBehavior w/DB data should in time be removed. WaypointBehavior * behavior; - WaypointNode() : x(0.0f), y(0.0f), z(0.0f), orientation(0.0f), delay(0), behavior(NULL) {} - 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) {} + WaypointNode() : x(0.0f), y(0.0f), z(0.0f), orientation(0.0f), delay(0), script_id(0), behavior(NULL) {} + WaypointNode(float _x, float _y, float _z, float _o, uint32 _delay, uint32 _script_id, WaypointBehavior * _behavior) + : x(_x), y(_y), z(_z), orientation(_o), delay(_delay), script_id(_script_id), behavior(_behavior) {} }; typedef std::vector WaypointPath; diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index 834e11bd435..ba6bd7e6883 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -171,6 +171,12 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 if (i_path->at(idx).orientation != 100) creature.SetOrientation(i_path->at(idx).orientation); + if (i_path->at(idx).script_id) + { + DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "Creature movement start script %u at point %u for creature %u (entry %u).", i_path->at(idx).script_id, idx, creature.GetDBTableGUIDLow(), creature.GetEntry()); + creature.GetMap()->ScriptsStart(sCreatureMovementScripts, i_path->at(idx).script_id, &creature, &creature); + } + if (WaypointBehavior *behavior = i_path->at(idx).behavior) { if (behavior->emote != 0) diff --git a/src/game/World.cpp b/src/game/World.cpp index 87d4a15917a..cffa722e5ad 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1185,6 +1185,9 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Trainers..." ); sObjectMgr.LoadTrainerSpell(); // must be after load CreatureTemplate + sLog.outString( "Loading Waypoint scripts..." ); // before loading from creature_movement + sObjectMgr.LoadCreatureMovementScripts(); + sLog.outString( "Loading Waypoints..." ); sLog.outString(); sWaypointMgr.Load(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 3af863604b0..36daf8dace1 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9890" + #define REVISION_NR "9891" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 49604d255b1..ddeb2745b32 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_9849_01_characters_saved_variables" - #define REVISION_DB_MANGOS "required_9886_02_mangos_command" + #define REVISION_DB_MANGOS "required_9891_02_mangos_creature_movement_scripts" #define REVISION_DB_REALMD "required_9748_01_realmd_realmlist" #endif // __REVISION_SQL_H__