diff --git a/sql/mangos.sql b/sql/mangos.sql index 806559f37..c6dfb86f0 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_11234_01_mangos_command` bit(1) default NULL + `required_11310_01_mangos_mangos_string` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -3867,7 +3867,8 @@ INSERT INTO `mangos_string` VALUES (1206,'dot damage',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1500,'%u - [%s] AutoSpawn: %u MaxLimit: %u Creatures: %u GameObjecs: %u Pools %u Chance: %f %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1501,'%u - |cffffffff|Hpool:%u|h[%s]|h|r AutoSpawn: %u MaxLimit: %u Creatures: %u GameObjecs: %u Pools %u %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(1502,'%u - [%s] AutoSpawn: %u MaxLimit: %u Creatures: %u GameObjecs: %u Pools %u %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +(1502,'%u - [%s] AutoSpawn: %u MaxLimit: %u Creatures: %u GameObjecs: %u Pools %u %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1503,'Can not add spawn because no free guids for static spawn in reserved guids range. Need restart server before command will can used. Also look GuidReserveSize.* config options.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/11310_01_mangos_mangos_string.sql b/sql/updates/11310_01_mangos_mangos_string.sql new file mode 100644 index 000000000..3cf40a9e1 --- /dev/null +++ b/sql/updates/11310_01_mangos_mangos_string.sql @@ -0,0 +1,6 @@ +ALTER TABLE db_version CHANGE COLUMN required_11234_01_mangos_command required_11310_01_mangos_mangos_string bit; + +DELETE FROM mangos_string WHERE entry IN (1503); + +INSERT INTO mangos_string VALUES +(1503,'Can not add spawn because no free guids for static spawn in reserved guids range. Need restart server before command will can used. Also look GuidReserveSize.* config options.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/src/game/Language.h b/src/game/Language.h index b4f6f475b..63406946b 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -935,7 +935,8 @@ enum MangosStrings LANG_POOL_CHANCE_POOL_LIST_CONSOLE = 1500, LANG_POOL_POOL_LIST_CHAT = 1501, LANG_POOL_POOL_LIST_CONSOLE = 1502, - // Room for more Level 2 1503-1599 not used + LANG_NO_FREE_STATIC_GUID_FOR_SPAWN = 1503, + // Room for more Level 2 1504-1599 not used // FREE IDS 1600-9999 diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 04f4d8a4c..28b511892 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1086,7 +1086,15 @@ bool ChatHandler::HandleGameObjectAddCommand(char* args) Map *map = chr->GetMap(); GameObject* pGameObj = new GameObject; - uint32 db_lowGUID = map->GenerateLocalLowGuid(HIGHGUID_GAMEOBJECT); + + // used guids from specially reserved range (can be 0 if no free values) + uint32 db_lowGUID = sObjectMgr.GenerateStaticGameobjectLowGuid(); + if (!db_lowGUID) + { + SendSysMessage(LANG_NO_FREE_STATIC_GUID_FOR_SPAWN); + SetSentErrorMessage(true); + return false; + } if (!pGameObj->Create(db_lowGUID, gInfo->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, GO_ANIMPROGRESS_DEFAULT, GO_STATE_READY)) { @@ -1556,7 +1564,16 @@ bool ChatHandler::HandleNpcAddCommand(char* args) Creature* pCreature = new Creature; - if (!pCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, id)) + // used guids from specially reserved range (can be 0 if no free values) + uint32 lowguid = sObjectMgr.GenerateStaticCreatureLowGuid(); + if (!lowguid) + { + SendSysMessage(LANG_NO_FREE_STATIC_GUID_FOR_SPAWN); + SetSentErrorMessage(true); + return false; + } + + if (!pCreature->Create(lowguid, pos, id)) { delete pCreature; return false; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 9f6315517..b4e4bf5f2 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -77,8 +77,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode) i_gridExpiry(expiry), m_TerrainData(sTerrainMgr.LoadTerrain(id)), i_data(NULL), i_script_id(0) { - m_CreatureGuids.Set(sObjectMgr.GetFirstCreatureLowGuid()); - m_GameObjectGuids.Set(sObjectMgr.GetFirstGameObjectLowGuid()); + m_CreatureGuids.Set(sObjectMgr.GetFirstTemporaryCreatureLowGuid()); + m_GameObjectGuids.Set(sObjectMgr.GetFirstTemporaryGameObjectLowGuid()); for(unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j) { diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 47a9e2950..92049d4e4 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -141,8 +141,8 @@ template uint32 IdGenerator::Generate(); template uint64 IdGenerator::Generate(); ObjectMgr::ObjectMgr() : - m_CreatureFirstGuid(1), - m_GameObjectFirstGuid(1), + m_FirstTemporaryCreatureGuid(1), + m_FirstTemporaryGameObjectGuid(1), m_ArenaTeamIds("Arena team ids"), m_AuctionIds("Auction ids"), @@ -5606,7 +5606,7 @@ void ObjectMgr::SetHighestGuids() result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" ); if( result ) { - m_CreatureFirstGuid = (*result)[0].GetUInt32()+1; + m_FirstTemporaryCreatureGuid = (*result)[0].GetUInt32()+1; delete result; } @@ -5635,7 +5635,7 @@ void ObjectMgr::SetHighestGuids() result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" ); if( result ) { - m_GameObjectFirstGuid = (*result)[0].GetUInt32()+1; + m_FirstTemporaryGameObjectGuid = (*result)[0].GetUInt32()+1; delete result; } @@ -5687,6 +5687,13 @@ void ObjectMgr::SetHighestGuids() m_GroupIds.Set((*result)[0].GetUInt32()+1); delete result; } + + // setup reserved ranges for static guids spawn + m_StaticCreatureGuids.Set(m_FirstTemporaryCreatureGuid); + m_FirstTemporaryCreatureGuid += sWorld.getConfig(CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE); + + m_StaticGamebjectGuids.Set(m_FirstTemporaryGameObjectGuid); + m_FirstTemporaryGameObjectGuid += sWorld.getConfig(CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT); } void ObjectMgr::LoadGameObjectLocales() diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index d0ba3ede9..b4e8f4d9a 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -719,8 +719,12 @@ class ObjectMgr void SetHighestGuids(); // used for set initial guid counter for map local guids - uint32 GetFirstCreatureLowGuid() const { return m_CreatureFirstGuid; } - uint32 GetFirstGameObjectLowGuid() const { return m_GameObjectFirstGuid; } + uint32 GetFirstTemporaryCreatureLowGuid() const { return m_FirstTemporaryCreatureGuid; } + uint32 GetFirstTemporaryGameObjectLowGuid() const { return m_FirstTemporaryGameObjectGuid; } + + // used in .npc add/.gobject add commands for adding static spawns + uint32 GenerateStaticCreatureLowGuid() { if (m_StaticCreatureGuids.GetNextAfterMaxUsed() >= m_FirstTemporaryCreatureGuid) return 0; return m_StaticCreatureGuids.Generate(); } + uint32 GenerateStaticGameobjectLowGuid() { if (m_StaticGamebjectGuids.GetNextAfterMaxUsed() >= m_FirstTemporaryGameObjectGuid) return 0; return m_StaticGamebjectGuids.Generate(); } uint32 GeneratePlayerLowGuid() { return m_CharGuids.Generate(); } uint32 GenerateItemLowGuid() { return m_ItemGuids.Generate(); } @@ -1045,8 +1049,12 @@ class ObjectMgr IdGenerator m_GroupIds; // initial free low guid for selected guid type for map local guids - uint32 m_CreatureFirstGuid; - uint32 m_GameObjectFirstGuid; + uint32 m_FirstTemporaryCreatureGuid; + uint32 m_FirstTemporaryGameObjectGuid; + + // guids from reserved range for use in .npc add/.gobject add commands for adding new static spawns (saved in DB) from client. + ObjectGuidGenerator m_StaticCreatureGuids; + ObjectGuidGenerator m_StaticGamebjectGuids; // first free low guid for selected guid type ObjectGuidGenerator m_CharGuids; diff --git a/src/game/World.cpp b/src/game/World.cpp index 7445c2d20..d3d9e516f 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -837,6 +837,11 @@ void World::LoadConfigSettings(bool reload) setConfigMinMax(CONFIG_UINT32_CHARDELETE_MIN_LEVEL, "CharDelete.MinLevel", 0, 0, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL)); setConfigPos(CONFIG_UINT32_CHARDELETE_KEEP_DAYS, "CharDelete.KeepDays", 30); + if (configNoReload(reload, CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE, "GuidReserveSize.Creature", 100)) + setConfigPos(CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE, "GuidReserveSize.Creature", 100); + if (configNoReload(reload, CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, "GuidReserveSize.Gameobject", 100)) + setConfigPos(CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, "GuidReserveSize.Gameobject", 100); + ///- Read the "Data" directory from the config file std::string dataPath = sConfig.GetStringDefault("DataDir", "./"); diff --git a/src/game/World.h b/src/game/World.h index d38248912..32ef77b79 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -185,6 +185,8 @@ enum eConfigUInt32Values CONFIG_UINT32_CHARDELETE_KEEP_DAYS, CONFIG_UINT32_CHARDELETE_METHOD, CONFIG_UINT32_CHARDELETE_MIN_LEVEL, + CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE, + CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, CONFIG_UINT32_VALUE_COUNT }; diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index 61ffd07a9..d8bc43aaa 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -847,7 +847,7 @@ AllowTwoSide.AddFriend = 0 TalentsInspecting = 1 ################################################################################################################### -# CREATURE SETTINGS +# CREATURE AND GAMEOBJECT SETTINGS # # ThreatRadius # Radius for creature to evade after being pulled away from combat start point @@ -935,6 +935,14 @@ TalentsInspecting = 1 # Distance from player to listen text that creature (or other world object) yell # Default: 300 # +# GuidReserveSize.Creature +# GuidReserveSize.Gameobject +# Amount guids reserved for .npc add/.gobject add directly after last used in DB static spawned creature/gameobject guid +# Commands .npc add/.gobject add can be used only for guids from this reserve and required server restart if all guids +# from reserve used before above commands can be used in like case. Less size increase amount guids for dynamic spawns +# in game from other side +# Default: 100 +# ################################################################################################################### ThreatRadius = 100 @@ -969,6 +977,9 @@ Rate.Creature.Elite.RARE.HP = 1 ListenRange.Say = 40 ListenRange.TextEmote = 40 ListenRange.Yell = 300 +GuidReserveSize.Creature = 100 +GuidReserveSize.Gameobject = 100 + ################################################################################################################### # CHAT SETTINGS diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1fa9d3cb3..b54e95b7c 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 "11309" + #define REVISION_NR "11310" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 60c45bc1a..9d99ff707 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_11299_02_characters_pet_aura" - #define REVISION_DB_MANGOS "required_11234_01_mangos_command" + #define REVISION_DB_MANGOS "required_11310_01_mangos_mangos_string" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__