[11117] Allow for non-instancable maps have InstanceData and instance scripts.

* New table added for non-instanced maps (except BG/arena):
    - `mangos`.`world_template` (script mapping to non instanced data)
    - `characters`.`world` (saved script data string storage)

* InstancedData created for any map types including BGs/arenas, that allow have scripts
  state for any maps, but BG/arena instance data not saved.

Note: Possible structures will renamed later for clarify apply to any type maps,
but avoid for now for simplify changes and hard affect to script library sources.
This commit is contained in:
VladimirMangos 2011-02-08 03:54:45 +03:00
parent 332c4174d2
commit f73868a703
23 changed files with 244 additions and 101 deletions

View file

@ -21,7 +21,7 @@
DROP TABLE IF EXISTS `character_db_version`; DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` ( CREATE TABLE `character_db_version` (
`required_10973_01_characters_game_event_status` bit(1) default NULL `required_11117_02_characters_world` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
-- --
@ -1703,6 +1703,25 @@ LOCK TABLES `saved_variables` WRITE;
UNLOCK TABLES; UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
--
-- Table structure for table `world`
--
DROP TABLE IF EXISTS `world`;
CREATE TABLE `world` (
`map` int(11) unsigned NOT NULL default '0',
`data` longtext,
PRIMARY KEY (`map`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `world`
--
LOCK TABLES `world` WRITE;
/*!40000 ALTER TABLE `world` DISABLE KEYS */;
/*!40000 ALTER TABLE `world` ENABLE KEYS */;
UNLOCK TABLES;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0', `cache_id` int(10) default '0',
`required_11115_01_mangos_command` bit(1) default NULL `required_11117_01_mangos_world_template` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -17787,8 +17787,28 @@ LOCK TABLES `transports` WRITE;
/*!40000 ALTER TABLE `transports` DISABLE KEYS */; /*!40000 ALTER TABLE `transports` DISABLE KEYS */;
/*!40000 ALTER TABLE `transports` ENABLE KEYS */; /*!40000 ALTER TABLE `transports` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
--
-- Table structure for table `world_template`
--
DROP TABLE IF EXISTS `world_template`;
CREATE TABLE `world_template` (
`map` smallint(5) unsigned NOT NULL,
`ScriptName` varchar(128) NOT NULL default '',
PRIMARY KEY (`map`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Dumping data for table `world_template`
--
LOCK TABLES `world_template` WRITE;
/*!40000 ALTER TABLE `world_template` DISABLE KEYS */;
/*!40000 ALTER TABLE `world_template` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;

View file

@ -0,0 +1,12 @@
ALTER TABLE db_version CHANGE COLUMN required_11115_01_mangos_command required_11117_01_mangos_world_template bit;
--
-- Table structure for table `world_template`
--
DROP TABLE IF EXISTS `world_template`;
CREATE TABLE `world_template` (
`map` smallint(5) unsigned NOT NULL,
`ScriptName` varchar(128) NOT NULL default '',
PRIMARY KEY (`map`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

View file

@ -0,0 +1,12 @@
ALTER TABLE character_db_version CHANGE COLUMN required_10973_01_characters_game_event_status required_11117_02_characters_world bit;
--
-- Table structure for table `world`
--
DROP TABLE IF EXISTS `world`;
CREATE TABLE `world` (
`map` int(11) unsigned NOT NULL default '0',
`data` longtext,
PRIMARY KEY (`map`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View file

@ -159,6 +159,8 @@ pkgdata_DATA = \
11040_02_mangos_spell_bonus_data.sql \ 11040_02_mangos_spell_bonus_data.sql \
11058_01_mangos_spell_proc_event.sql \ 11058_01_mangos_spell_proc_event.sql \
11115_01_mangos_command.sql \ 11115_01_mangos_command.sql \
11117_01_mangos_world_template.sql \
11117_02_characters_world.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -298,4 +300,6 @@ EXTRA_DIST = \
11040_02_mangos_spell_bonus_data.sql \ 11040_02_mangos_spell_bonus_data.sql \
11058_01_mangos_spell_proc_event.sql \ 11058_01_mangos_spell_proc_event.sql \
11115_01_mangos_command.sql \ 11115_01_mangos_command.sql \
11117_01_mangos_world_template.sql \
11117_02_characters_world.sql \
README README

View file

@ -331,21 +331,11 @@ bool AchievementCriteriaRequirement::Meets(uint32 criteria_id, Player const* sou
{ {
if (!source->IsInWorld()) if (!source->IsInWorld())
return false; return false;
Map* map = source->GetMap(); InstanceData* data = source->GetInstanceData();
// BattleGroundMap-class is instanceable, but no InstanceMap-class
if (map->IsBattleGroundOrArena())
return false;
if (!map->Instanceable())
{
sLog.outErrorDb("Achievement system call ACHIEVEMENT_CRITERIA_REQUIRE_INSTANCE_SCRIPT (%u) for achievement criteria %u for non-instance map %u",
ACHIEVEMENT_CRITERIA_REQUIRE_INSTANCE_SCRIPT, criteria_id, map->GetId());
return false;
}
InstanceData* data = ((InstanceMap*)map)->GetInstanceData();
if (!data) if (!data)
{ {
sLog.outErrorDb("Achievement system call ACHIEVEMENT_CRITERIA_REQUIRE_INSTANCE_SCRIPT (%u) for achievement criteria %u for map %u but map not have instance script", sLog.outErrorDb("Achievement system call ACHIEVEMENT_CRITERIA_REQUIRE_INSTANCE_SCRIPT (%u) for achievement criteria %u for map %u but map not have instance script",
ACHIEVEMENT_CRITERIA_REQUIRE_INSTANCE_SCRIPT, criteria_id, map->GetId()); ACHIEVEMENT_CRITERIA_REQUIRE_INSTANCE_SCRIPT, criteria_id, source->GetMapId());
return false; return false;
} }
return data->CheckAchievementCriteriaMeet(criteria_id, source, target, miscvalue1); return data->CheckAchievementCriteriaMeet(criteria_id, source, target, miscvalue1);

View file

@ -721,8 +721,8 @@ bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry,
//Notify the map's instance data. //Notify the map's instance data.
//Only works if you create the object in it, not if it is moves to that map. //Only works if you create the object in it, not if it is moves to that map.
//Normally non-players do not teleport to other maps. //Normally non-players do not teleport to other maps.
if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData()) if (InstanceData* iData = map->GetInstanceData())
((InstanceMap*)map)->GetInstanceData()->OnCreatureCreate(this); iData->OnCreatureCreate(this);
switch (GetCreatureInfo()->rank) switch (GetCreatureInfo()->rank)
{ {

View file

@ -151,10 +151,8 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
//Notify the map's instance data. //Notify the map's instance data.
//Only works if you create the object in it, not if it is moves to that map. //Only works if you create the object in it, not if it is moves to that map.
//Normally non-players do not teleport to other maps. //Normally non-players do not teleport to other maps.
if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData()) if (InstanceData* iData = map->GetInstanceData())
{ iData->OnObjectCreate(this);
((InstanceMap*)map)->GetInstanceData()->OnObjectCreate(this);
}
return true; return true;
} }

View file

@ -23,10 +23,20 @@
void InstanceData::SaveToDB() void InstanceData::SaveToDB()
{ {
if(!Save()) return; // no reason to save BGs/Arenas
if (instance->IsBattleArena())
return;
if (!Save())
return;
std::string data = Save(); std::string data = Save();
CharacterDatabase.escape_string(data); CharacterDatabase.escape_string(data);
CharacterDatabase.PExecute("UPDATE instance SET data = '%s' WHERE id = '%u'", data.c_str(), instance->GetInstanceId());
if (instance->Instanceable())
CharacterDatabase.PExecute("UPDATE instance SET data = '%s' WHERE id = '%u'", data.c_str(), instance->GetInstanceId());
else
CharacterDatabase.PExecute("UPDATE world SET data = '%s' WHERE map = '%u'", data.c_str(), instance->GetId());
} }
bool InstanceData::CheckAchievementCriteriaMeet( uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/ /*= NULL*/, uint32 /*miscvalue1*/ /*= 0*/ ) bool InstanceData::CheckAchievementCriteriaMeet( uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/ /*= NULL*/, uint32 /*miscvalue1*/ /*= 0*/ )

View file

@ -72,8 +72,7 @@ void InstanceSave::SaveToDB()
Map *map = sMapMgr.FindMap(GetMapId(),m_instanceid); Map *map = sMapMgr.FindMap(GetMapId(),m_instanceid);
if(map) if(map)
{ {
MANGOS_ASSERT(map->IsDungeon()); InstanceData *iData = map->GetInstanceData();
InstanceData *iData = ((InstanceMap *)map)->GetInstanceData();
if(iData && iData->Save()) if(iData && iData->Save())
{ {
data = iData->Save(); data = iData->Save();

View file

@ -6339,21 +6339,16 @@ bool ChatHandler::HandleInstanceSaveDataCommand(char* /*args*/)
Player* pl = m_session->GetPlayer(); Player* pl = m_session->GetPlayer();
Map* map = pl->GetMap(); Map* map = pl->GetMap();
if (!map->IsDungeon())
{
PSendSysMessage("Map is not a dungeon.");
SetSentErrorMessage(true);
return false;
}
if (!((InstanceMap*)map)->GetInstanceData()) InstanceData* iData = map->GetInstanceData();
if (!iData)
{ {
PSendSysMessage("Map has no instance data."); PSendSysMessage("Map has no instance data.");
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
((InstanceMap*)map)->GetInstanceData()->SaveToDB(); iData->SaveToDB();
return true; return true;
} }

View file

@ -49,6 +49,12 @@ Map::~Map()
if (m_instanceSave) if (m_instanceSave)
m_instanceSave->SetUsedByMapState(false); // field pointer can be deleted after this m_instanceSave->SetUsedByMapState(false); // field pointer can be deleted after this
if(i_data)
{
delete i_data;
i_data = NULL;
}
//release reference count //release reference count
if(m_TerrainData->Release()) if(m_TerrainData->Release())
sTerrainMgr.UnloadTerrain(m_TerrainData->GetMapId()); sTerrainMgr.UnloadTerrain(m_TerrainData->GetMapId());
@ -69,7 +75,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0), i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_instanceSave(NULL), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_instanceSave(NULL),
m_activeNonPlayersIter(m_activeNonPlayers.end()), m_activeNonPlayersIter(m_activeNonPlayers.end()),
i_gridExpiry(expiry), m_TerrainData(sTerrainMgr.LoadTerrain(id)) i_gridExpiry(expiry), m_TerrainData(sTerrainMgr.LoadTerrain(id)),
i_data(NULL), i_script_id(0)
{ {
for(unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j) for(unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j)
{ {
@ -307,6 +314,10 @@ bool Map::Add(Player *player)
UpdateObjectVisibility(player,cell,p); UpdateObjectVisibility(player,cell,p);
AddNotifier(player,cell,p); AddNotifier(player,cell,p);
if (i_data)
i_data->OnPlayerEnter(player);
return true; return true;
} }
@ -565,10 +576,16 @@ void Map::Update(const uint32 &t_diff)
///- Process necessary scripts ///- Process necessary scripts
if (!m_scriptSchedule.empty()) if (!m_scriptSchedule.empty())
ScriptsProcess(); ScriptsProcess();
if(i_data)
i_data->Update(t_diff);
} }
void Map::Remove(Player *player, bool remove) void Map::Remove(Player *player, bool remove)
{ {
if (i_data)
i_data->OnPlayerLeave(player);
if(remove) if(remove)
player->CleanupsBeforeDelete(); player->CleanupsBeforeDelete();
else else
@ -1214,6 +1231,58 @@ void Map::RemoveFromActive( WorldObject* obj )
} }
} }
void Map::CreateInstanceData(bool load)
{
if(i_data != NULL)
return;
if (Instanceable())
{
if (InstanceTemplate const* mInstance = ObjectMgr::GetInstanceTemplate(GetId()))
i_script_id = mInstance->script_id;
}
else
{
if (WorldTemplate const* mInstance = ObjectMgr::GetWorldTemplate(GetId()))
i_script_id = mInstance->script_id;
}
if (!i_script_id)
return;
i_data = sScriptMgr.CreateInstanceData(this);
if(!i_data)
return;
if (load)
{
// TODO: make a global storage for this
QueryResult* result;
if (Instanceable())
result = CharacterDatabase.PQuery("SELECT data FROM instance WHERE id = '%u'", i_InstanceId);
else
result = CharacterDatabase.PQuery("SELECT data FROM world WHERE map = '%u'", GetId());
if (result)
{
Field* fields = result->Fetch();
const char* data = fields[0].GetString();
if (data)
{
DEBUG_LOG("Loading instance data for `%s` (Map: %u Instance: %u)", sScriptMgr.GetScriptName(i_script_id), GetId(), i_InstanceId);
i_data->Load(data);
}
delete result;
}
}
else
{
DEBUG_LOG("New instance data, \"%s\" ,initialized!", sScriptMgr.GetScriptName(i_script_id));
i_data->Initialize();
}
}
template void Map::Add(Corpse *); template void Map::Add(Corpse *);
template void Map::Add(Creature *); template void Map::Add(Creature *);
template void Map::Add(GameObject *); template void Map::Add(GameObject *);
@ -1228,8 +1297,7 @@ template void Map::Remove(DynamicObject *, bool);
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode) InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
: Map(id, expiry, InstanceId, SpawnMode), : Map(id, expiry, InstanceId, SpawnMode),
m_resetAfterUnload(false), m_unloadWhenEmpty(false), m_resetAfterUnload(false), m_unloadWhenEmpty(false)
i_data(NULL), i_script_id(0)
{ {
//lets initialize visibility distance for dungeons //lets initialize visibility distance for dungeons
InstanceMap::InitVisibilityDistance(); InstanceMap::InitVisibilityDistance();
@ -1248,11 +1316,6 @@ InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 Spaw
InstanceMap::~InstanceMap() InstanceMap::~InstanceMap()
{ {
if(i_data)
{
delete i_data;
i_data = NULL;
}
} }
void InstanceMap::InitVisibilityDistance() void InstanceMap::InitVisibilityDistance()
@ -1414,18 +1477,12 @@ bool InstanceMap::Add(Player *player)
// this will acquire the same mutex so it cannot be in the previous block // this will acquire the same mutex so it cannot be in the previous block
Map::Add(player); Map::Add(player);
if (i_data)
i_data->OnPlayerEnter(player);
return true; return true;
} }
void InstanceMap::Update(const uint32& t_diff) void InstanceMap::Update(const uint32& t_diff)
{ {
Map::Update(t_diff); Map::Update(t_diff);
if(i_data)
i_data->Update(t_diff);
} }
void BattleGroundMap::Update(const uint32& diff) void BattleGroundMap::Update(const uint32& diff)
@ -1443,53 +1500,12 @@ void InstanceMap::Remove(Player *player, bool remove)
if(!m_unloadTimer && m_mapRefManager.getSize() == 1) if(!m_unloadTimer && m_mapRefManager.getSize() == 1)
m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_UINT32_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_UINT32_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
if (i_data)
i_data->OnPlayerLeave(player);
Map::Remove(player, remove); Map::Remove(player, remove);
// for normal instances schedule the reset after all players have left // for normal instances schedule the reset after all players have left
SetResetSchedule(true); SetResetSchedule(true);
} }
void InstanceMap::CreateInstanceData(bool load)
{
if(i_data != NULL)
return;
InstanceTemplate const* mInstance = ObjectMgr::GetInstanceTemplate(GetId());
if (mInstance)
{
i_script_id = mInstance->script_id;
i_data = sScriptMgr.CreateInstanceData(this);
}
if(!i_data)
return;
if(load)
{
// TODO: make a global storage for this
QueryResult* result = CharacterDatabase.PQuery("SELECT data FROM instance WHERE map = '%u' AND id = '%u'", GetId(), i_InstanceId);
if (result)
{
Field* fields = result->Fetch();
const char* data = fields[0].GetString();
if(data)
{
DEBUG_LOG("Loading instance data for `%s` with id %u", sScriptMgr.GetScriptName(i_script_id), i_InstanceId);
i_data->Load(data);
}
delete result;
}
}
else
{
DEBUG_LOG("New instance data, \"%s\" ,initialized!", sScriptMgr.GetScriptName(i_script_id));
i_data->Initialize();
}
}
/* /*
Returns true if there are no players in the instance Returns true if there are no players in the instance
*/ */

View file

@ -67,6 +67,12 @@ struct InstanceTemplate
uint32 script_id; uint32 script_id;
}; };
struct WorldTemplate
{
uint32 map; // non-instance map
uint32 script_id;
};
enum LevelRequirementVsMode enum LevelRequirementVsMode
{ {
LEVELREQUIREMENT_HEROIC = 70 LEVELREQUIREMENT_HEROIC = 70
@ -238,6 +244,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>
//get corresponding TerrainData object for this particular map //get corresponding TerrainData object for this particular map
const TerrainInfo * GetTerrain() const { return m_TerrainData; } const TerrainInfo * GetTerrain() const { return m_TerrainData; }
void CreateInstanceData(bool load);
InstanceData* GetInstanceData() { return i_data; }
uint32 GetScriptId() const { return i_script_id; }
private: private:
void LoadMapAndVMap(int gx, int gy); void LoadMapAndVMap(int gx, int gy);
@ -308,6 +317,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>
std::set<WorldObject *> i_objectsToRemove; std::set<WorldObject *> i_objectsToRemove;
std::multimap<time_t, ScriptAction> m_scriptSchedule; std::multimap<time_t, ScriptAction> m_scriptSchedule;
InstanceData* i_data;
uint32 i_script_id;
// Map local low guid counters // Map local low guid counters
ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT> m_DynObjectGuids; ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT> m_DynObjectGuids;
ObjectGuidGenerator<HIGHGUID_PET> m_PetGuids; ObjectGuidGenerator<HIGHGUID_PET> m_PetGuids;
@ -332,10 +344,7 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
bool Add(Player *); bool Add(Player *);
void Remove(Player *, bool); void Remove(Player *, bool);
void Update(const uint32&); void Update(const uint32&);
void CreateInstanceData(bool load);
bool Reset(InstanceResetMethod method); bool Reset(InstanceResetMethod method);
uint32 GetScriptId() const { return i_script_id; }
InstanceData* GetInstanceData() { return i_data; }
void PermBindAllPlayers(Player *player); void PermBindAllPlayers(Player *player);
void UnloadAll(bool pForce); void UnloadAll(bool pForce);
bool CanEnter(Player* player); bool CanEnter(Player* player);
@ -346,8 +355,6 @@ class MANGOS_DLL_SPEC InstanceMap : public Map
private: private:
bool m_resetAfterUnload; bool m_resetAfterUnload;
bool m_unloadWhenEmpty; bool m_unloadWhenEmpty;
InstanceData* i_data;
uint32 i_script_id;
}; };
class MANGOS_DLL_SPEC BattleGroundMap : public Map class MANGOS_DLL_SPEC BattleGroundMap : public Map

View file

@ -115,6 +115,9 @@ Map* MapManager::CreateMap(uint32 id, const WorldObject* obj)
m = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); m = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY);
//add map into container //add map into container
i_maps[MapID(id)] = m; i_maps[MapID(id)] = m;
// non-instanceable maps always expected have saved state
m->CreateInstanceData(true);
} }
} }
@ -419,6 +422,7 @@ InstanceMap* MapManager::CreateInstanceMap(uint32 id, uint32 InstanceId, Difficu
InstanceMap *map = new InstanceMap(id, i_gridCleanUpDelay, InstanceId, difficulty); InstanceMap *map = new InstanceMap(id, i_gridCleanUpDelay, InstanceId, difficulty);
MANGOS_ASSERT(map->IsDungeon()); MANGOS_ASSERT(map->IsDungeon());
// Dungeons can have saved instance data
bool load_data = save != NULL; bool load_data = save != NULL;
map->CreateInstanceData(load_data); map->CreateInstanceData(load_data);
@ -441,6 +445,9 @@ BattleGroundMap* MapManager::CreateBattleGroundMap(uint32 id, uint32 InstanceId,
//add map into map container //add map into map container
i_maps[MapID(id, InstanceId)] = map; i_maps[MapID(id, InstanceId)] = map;
// BGs/Arenas not have saved instance data
map->CreateInstanceData(false);
return map; return map;
} }

View file

@ -1099,8 +1099,7 @@ void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const
InstanceData* WorldObject::GetInstanceData() const InstanceData* WorldObject::GetInstanceData() const
{ {
Map *map = GetMap(); return GetMap()->GetInstanceData();
return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceData() : NULL;
} }
//slow //slow

View file

@ -4685,9 +4685,9 @@ void ObjectMgr::LoadInstanceTemplate()
continue; continue;
} }
if (mapEntry->IsContinent()) if (!mapEntry->Instanceable())
{ {
sLog.outErrorDb("ObjectMgr::LoadInstanceTemplate: continent mapid %d for template!", temp->map); sLog.outErrorDb("ObjectMgr::LoadInstanceTemplate: non-instanceable mapid %d for template!", temp->map);
sInstanceTemplate.EraseEntry(i); sInstanceTemplate.EraseEntry(i);
continue; continue;
} }
@ -4718,6 +4718,46 @@ void ObjectMgr::LoadInstanceTemplate()
sLog.outString(); sLog.outString();
} }
struct SQLWorldLoader : public SQLStorageLoaderBase<SQLWorldLoader>
{
template<class D>
void convert_from_str(uint32 /*field_pos*/, char const *src, D &dst)
{
dst = D(sScriptMgr.GetScriptId(src));
}
};
void ObjectMgr::LoadWorldTemplate()
{
SQLWorldLoader loader;
loader.Load(sWorldTemplate);
for(uint32 i = 0; i < sWorldTemplate.MaxEntry; i++)
{
WorldTemplate const* temp = GetWorldTemplate(i);
if (!temp)
continue;
MapEntry const* mapEntry = sMapStore.LookupEntry(temp->map);
if (!mapEntry)
{
sLog.outErrorDb("ObjectMgr::LoadWorldTemplate: bad mapid %d for template!", temp->map);
sWorldTemplate.EraseEntry(i);
continue;
}
if (mapEntry->Instanceable())
{
sLog.outErrorDb("ObjectMgr::LoadWorldTemplate: instanceable mapid %d for template!", temp->map);
sWorldTemplate.EraseEntry(i);
continue;
}
}
sLog.outString( ">> Loaded %u World Template definitions", sWorldTemplate.RecordCount );
sLog.outString();
}
GossipText const *ObjectMgr::GetGossipText(uint32 Text_ID) const GossipText const *ObjectMgr::GetGossipText(uint32 Text_ID) const
{ {
GossipTextMap::const_iterator itr = mGossipText.find(Text_ID); GossipTextMap::const_iterator itr = mGossipText.find(Text_ID);

View file

@ -509,6 +509,11 @@ class ObjectMgr
return sInstanceTemplate.LookupEntry<InstanceTemplate>(map); return sInstanceTemplate.LookupEntry<InstanceTemplate>(map);
} }
static WorldTemplate const* GetWorldTemplate(uint32 map)
{
return sWorldTemplate.LookupEntry<WorldTemplate>(map);
}
PetLevelInfo const* GetPetLevelInfo(uint32 creature_id, uint32 level) const; PetLevelInfo const* GetPetLevelInfo(uint32 creature_id, uint32 level) const;
PlayerClassInfo const* GetPlayerClassInfo(uint32 class_) const PlayerClassInfo const* GetPlayerClassInfo(uint32 class_) const
@ -661,6 +666,7 @@ class ObjectMgr
void LoadGossipMenuItemsLocales(); void LoadGossipMenuItemsLocales();
void LoadPointOfInterestLocales(); void LoadPointOfInterestLocales();
void LoadInstanceTemplate(); void LoadInstanceTemplate();
void LoadWorldTemplate();
void LoadMailLevelRewards(); void LoadMailLevelRewards();
void LoadGossipText(); void LoadGossipText();

View file

@ -34,6 +34,8 @@ const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
const char PageTextfmt[]="isi"; const char PageTextfmt[]="isi";
const char InstanceTemplatesrcfmt[]="iiiis"; const char InstanceTemplatesrcfmt[]="iiiis";
const char InstanceTemplatedstfmt[]="iiiii"; const char InstanceTemplatedstfmt[]="iiiii";
const char WorldTemplatesrcfmt[]="is";
const char WorldTemplatedstfmt[]="ii";
SQLStorage sCreatureStorage(CreatureInfosrcfmt, CreatureInfodstfmt, "entry","creature_template"); SQLStorage sCreatureStorage(CreatureInfosrcfmt, CreatureInfodstfmt, "entry","creature_template");
SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon"); SQLStorage sCreatureDataAddonStorage(CreatureDataAddonInfofmt,"guid","creature_addon");
@ -44,3 +46,4 @@ SQLStorage sGOStorage(GameObjectInfosrcfmt, GameObjectInfodstfmt, "entry","gameo
SQLStorage sItemStorage(ItemPrototypesrcfmt, ItemPrototypedstfmt, "entry","item_template"); SQLStorage sItemStorage(ItemPrototypesrcfmt, ItemPrototypedstfmt, "entry","item_template");
SQLStorage sPageTextStore(PageTextfmt,"entry","page_text"); SQLStorage sPageTextStore(PageTextfmt,"entry","page_text");
SQLStorage sInstanceTemplate(InstanceTemplatesrcfmt, InstanceTemplatedstfmt, "map","instance_template"); SQLStorage sInstanceTemplate(InstanceTemplatesrcfmt, InstanceTemplatedstfmt, "map","instance_template");
SQLStorage sWorldTemplate(WorldTemplatesrcfmt, WorldTemplatedstfmt, "map","world_template");

View file

@ -31,5 +31,6 @@ extern SQLStorage sGOStorage;
extern SQLStorage sPageTextStore; extern SQLStorage sPageTextStore;
extern SQLStorage sItemStorage; extern SQLStorage sItemStorage;
extern SQLStorage sInstanceTemplate; extern SQLStorage sInstanceTemplate;
extern SQLStorage sWorldTemplate;
#endif #endif

View file

@ -850,7 +850,9 @@ void ScriptMgr::LoadScriptNames()
"UNION " "UNION "
"SELECT DISTINCT(ScriptName) FROM scripted_event_id WHERE ScriptName <> '' " "SELECT DISTINCT(ScriptName) FROM scripted_event_id WHERE ScriptName <> '' "
"UNION " "UNION "
"SELECT DISTINCT(ScriptName) FROM instance_template WHERE ScriptName <> ''"); "SELECT DISTINCT(ScriptName) FROM instance_template WHERE ScriptName <> '' "
"UNION "
"SELECT DISTINCT(ScriptName) FROM world_template WHERE ScriptName <> ''");
if (!result) if (!result)
{ {

View file

@ -931,6 +931,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Script Names..."); sLog.outString( "Loading Script Names...");
sScriptMgr.LoadScriptNames(); sScriptMgr.LoadScriptNames();
sLog.outString( "Loading WorldTemplate..." );
sObjectMgr.LoadWorldTemplate();
sLog.outString( "Loading InstanceTemplate..." ); sLog.outString( "Loading InstanceTemplate..." );
sObjectMgr.LoadInstanceTemplate(); sObjectMgr.LoadInstanceTemplate();

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11116" #define REVISION_NR "11117"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__ #ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__ #define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_10973_01_characters_game_event_status" #define REVISION_DB_CHARACTERS "required_11117_02_characters_world"
#define REVISION_DB_MANGOS "required_11115_01_mangos_command" #define REVISION_DB_MANGOS "required_11117_01_mangos_world_template"
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
#endif // __REVISION_SQL_H__ #endif // __REVISION_SQL_H__