[9891] Implement *_scripts for creature_movement

New field script_id in creature_movement can be filled for each waypoint point and run the corresponding script from creature_movement_scripts.
Script_id can be any value and several points/creatures can share the same script (with limits of course, such as script depending on location and other factors).

DB projects are advised to move current text, spells and emotes data in creature_movement fields as these fields are strictly no longer needed and may be fully removed in the future.

Signed-off-by: NoFantasy <nofantasy@nf.no>
This commit is contained in:
NoFantasy 2010-05-14 12:15:50 +02:00
parent 5a72466935
commit 312a076491
12 changed files with 110 additions and 9 deletions

View file

@ -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`
--

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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); }

View file

@ -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<uint32> 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<uint32>::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)

View file

@ -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<WaypointNode> WaypointPath;

View file

@ -171,6 +171,12 @@ bool WaypointMovementGenerator<Creature>::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)

View file

@ -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();

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9890"
#define REVISION_NR "9891"
#endif // __REVISION_NR_H__

View file

@ -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__