diff --git a/sql/mangos.sql b/sql/mangos.sql index fc093e0c5..145788a76 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_11169_02_mangos_command` bit(1) default NULL + `required_11190_01_mangos_pool_gameobject_template` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -13787,7 +13787,6 @@ LOCK TABLES `points_of_interest` WRITE; /*!40000 ALTER TABLE `points_of_interest` ENABLE KEYS */; UNLOCK TABLES; - -- -- Table structure for table `pool_creature` -- @@ -13802,7 +13801,6 @@ CREATE TABLE `pool_creature` ( INDEX `pool_idx` (pool_entry) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; - -- -- Dumping data for table `pool_creature` -- @@ -13812,6 +13810,29 @@ LOCK TABLES `pool_creature` WRITE; /*!40000 ALTER TABLE `pool_creature` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `pool_creature_template` +-- + +DROP TABLE IF EXISTS `pool_creature_template`; +CREATE TABLE `pool_creature_template` ( + `id` int(10) unsigned NOT NULL default '0', + `pool_entry` mediumint(8) unsigned NOT NULL default '0', + `chance` float unsigned NOT NULL default '0', + `description` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + INDEX `pool_idx` (pool_entry) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `pool_creature_template` +-- + +LOCK TABLES `pool_creature_template` WRITE; +/*!40000 ALTER TABLE `pool_creature_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `pool_creature_template` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `pool_gameobject` -- @@ -13835,6 +13856,29 @@ LOCK TABLES `pool_gameobject` WRITE; /*!40000 ALTER TABLE `pool_gameobject` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `pool_gameobject_template` +-- + +DROP TABLE IF EXISTS `pool_gameobject_template`; +CREATE TABLE `pool_gameobject_template` ( + `id` int(10) unsigned NOT NULL default '0', + `pool_entry` mediumint(8) unsigned NOT NULL default '0', + `chance` float unsigned NOT NULL default '0', + `description` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + INDEX `pool_idx` (pool_entry) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `pool_gameobject_template` +-- + +LOCK TABLES `pool_gameobject_template` WRITE; +/*!40000 ALTER TABLE `pool_gameobject_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `pool_gameobject_template` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `pool_pool` -- diff --git a/sql/updates/11190_01_mangos_pool_creature_template.sql b/sql/updates/11190_01_mangos_pool_creature_template.sql new file mode 100644 index 000000000..6a0740da2 --- /dev/null +++ b/sql/updates/11190_01_mangos_pool_creature_template.sql @@ -0,0 +1,13 @@ +ALTER TABLE db_version CHANGE COLUMN required_11169_02_mangos_command required_11190_01_mangos_pool_creature_template bit; + +DROP TABLE IF EXISTS `pool_creature_template`; +CREATE TABLE `pool_creature_template` ( + `id` int(10) unsigned NOT NULL default '0', + `pool_entry` mediumint(8) unsigned NOT NULL default '0', + `chance` float unsigned NOT NULL default '0', + `description` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + INDEX `pool_idx` (pool_entry) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + diff --git a/sql/updates/11190_01_mangos_pool_gameobject_template.sql b/sql/updates/11190_01_mangos_pool_gameobject_template.sql new file mode 100644 index 000000000..e305d90a9 --- /dev/null +++ b/sql/updates/11190_01_mangos_pool_gameobject_template.sql @@ -0,0 +1,13 @@ +ALTER TABLE db_version CHANGE COLUMN required_11190_01_mangos_pool_creature_template required_11190_01_mangos_pool_gameobject_template bit; + +DROP TABLE IF EXISTS `pool_gameobject_template`; +CREATE TABLE `pool_gameobject_template` ( + `id` int(10) unsigned NOT NULL default '0', + `pool_entry` mediumint(8) unsigned NOT NULL default '0', + `chance` float unsigned NOT NULL default '0', + `description` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + INDEX `pool_idx` (pool_entry) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + diff --git a/src/game/PoolManager.cpp b/src/game/PoolManager.cpp index 8eef4b023..e12362ca6 100644 --- a/src/game/PoolManager.cpp +++ b/src/game/PoolManager.cpp @@ -618,7 +618,7 @@ void PoolManager::LoadFromDB() PoolMapChecker mapChecker(mPoolTemplate); - // Creatures + // Creatures (guids and entries) mPoolCreatureGroups.resize(max_pool_id + 1); mCreatureSearchMap.clear(); @@ -632,7 +632,7 @@ void PoolManager::LoadFromDB() bar2.step(); sLog.outString(); - sLog.outString(">> Loaded %u creatures in pools", count ); + sLog.outString(">> Loaded %u creatures in pools from `pool_creature`", count ); } else { @@ -681,11 +681,83 @@ void PoolManager::LoadFromDB() } while (result->NextRow()); sLog.outString(); - sLog.outString( ">> Loaded %u creatures in pools", count ); + sLog.outString( ">> Loaded %u creatures in pools from `pool_creature`", count ); delete result; } - // Gameobjects + result = WorldDatabase.Query("SELECT guid, pool_entry, chance, pool_creature_template.id FROM pool_creature_template LEFT JOIN creature ON creature.id = pool_creature_template.id"); + + count = 0; + if (!result) + { + barGoLink bar2(1); + bar2.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u creatures in pools from `pool_creature_template`", count ); + } + else + { + barGoLink bar2((int)result->GetRowCount()); + do + { + Field *fields = result->Fetch(); + + bar2.step(); + + uint32 guid = fields[0].GetUInt32(); + uint16 pool_id = fields[1].GetUInt16(); + float chance = fields[2].GetFloat(); + uint16 entry_id = fields[3].GetUInt32(); // for errors output only + + CreatureData const* data = sObjectMgr.GetCreatureData(guid); + if (!data) + { + sLog.outErrorDb("`pool_creature_template` has a non existing creature spawn (GUID: %u Entry: %u) defined for pool id (%u), skipped.", guid, entry_id, pool_id ); + continue; + } + if (pool_id > max_pool_id) + { + sLog.outErrorDb("`pool_creature_template` pool id (%i) is out of range compared to max pool id in `pool_template`, skipped.",pool_id); + continue; + } + if (chance < 0 || chance > 100) + { + sLog.outErrorDb("`pool_creature_template` has an invalid chance (%f) for creature (Guid %u Entry %u) in pool id (%i), skipped.", chance, guid, entry_id, pool_id); + continue; + } + + // `pool_creature` and `pool_creature_template` can't have guids duplicates (in second case because entries also unique) + // So if guid already listed in pools then this duplicate from alt.table + // Also note: for added guid not important what case we skip from 2 tables + if (uint16 alt_pool_id = IsPartOfAPool(guid)) + { + sLog.outErrorDb("`pool_creature` has guid %u for pool %u that already added to pool %u from `pool_creature_template` for creature entry %u, skipped.", + guid, pool_id, alt_pool_id, entry_id); + continue; + } + + if (!mapChecker.CheckAndRemember(data->mapid, pool_id, "pool_creature_template", "creature guid")) + continue; + + PoolTemplateData *pPoolTemplate = &mPoolTemplate[pool_id]; + + ++count; + + PoolObject plObject = PoolObject(guid, chance); + PoolGroup& cregroup = mPoolCreatureGroups[pool_id]; + cregroup.SetPoolId(pool_id); + cregroup.AddEntry(plObject, pPoolTemplate->MaxLimit); + SearchPair p(guid, pool_id); + mCreatureSearchMap.insert(p); + + } while (result->NextRow()); + sLog.outString(); + sLog.outString(">> Loaded %u creatures in pools from `pool_creature_template`", count ); + delete result; + } + + // Gameobjects (guids and entries) mPoolGameobjectGroups.resize(max_pool_id + 1); mGameobjectSearchMap.clear(); @@ -699,7 +771,7 @@ void PoolManager::LoadFromDB() bar2.step(); sLog.outString(); - sLog.outString(">> Loaded %u gameobject in pools", count ); + sLog.outString(">> Loaded %u gameobject in pools from `pool_gameobject`", count ); } else { @@ -756,7 +828,89 @@ void PoolManager::LoadFromDB() } while( result->NextRow() ); sLog.outString(); - sLog.outString( ">> Loaded %u gameobject in pools", count ); + sLog.outString(">> Loaded %u gameobject in pools from `pool_gameobject`", count ); + delete result; + } + + // 1 2 3 + result = WorldDatabase.Query("SELECT guid, pool_entry, chance, pool_gameobject_template.id FROM pool_gameobject_template LEFT JOIN gameobject ON gameobject.id = pool_gameobject_template.id"); + + count = 0; + if (!result) + { + barGoLink bar2(1); + bar2.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u gameobject in pools from `pool_gameobject_template`", count ); + } + else + { + + barGoLink bar2((int)result->GetRowCount()); + do + { + Field *fields = result->Fetch(); + + bar2.step(); + + uint32 guid = fields[0].GetUInt32(); + uint16 pool_id = fields[1].GetUInt16(); + float chance = fields[2].GetFloat(); + uint16 entry_id = fields[3].GetUInt32(); // for errors output only + + GameObjectData const* data = sObjectMgr.GetGOData(guid); + if (!data) + { + sLog.outErrorDb("`pool_gameobject_template` has a non existing gameobject spawn (GUID: %u Entry %u) defined for pool id (%u), skipped.", guid, entry_id, pool_id); + continue; + } + GameObjectInfo const* goinfo = ObjectMgr::GetGameObjectInfo(data->id); + if (goinfo->type != GAMEOBJECT_TYPE_CHEST && + goinfo->type != GAMEOBJECT_TYPE_GOOBER && + goinfo->type != GAMEOBJECT_TYPE_FISHINGHOLE) + { + sLog.outErrorDb("`pool_gameobject_template` has a not lootable gameobject spawn (GUID: %u Entry % Type: %u) defined for pool id (%u), skipped.", guid, entry_id, goinfo->type, pool_id ); + continue; + } + if (pool_id > max_pool_id) + { + sLog.outErrorDb("`pool_gameobject_template` pool id (%i) is out of range compared to max pool id in `pool_template`, skipped.",pool_id); + continue; + } + if (chance < 0 || chance > 100) + { + sLog.outErrorDb("`pool_gameobject_template` has an invalid chance (%f) for gameobject (Guid %u Entry %u) in pool id (%i), skipped.", chance, guid, entry_id, pool_id); + continue; + } + + // `pool_gameobject` and `pool_gameobject_template` can't have guids duplicates (in second case because entries also unique) + // So if guid already listed in pools then this duplicate from alt.table + // Also note: for added guid not important what case we skip from 2 tables + if (uint16 alt_pool_id = IsPartOfAPool(guid)) + { + sLog.outErrorDb("`pool_gameobject` has guid %u for pool %u that already added to pool %u from `pool_gameobject_template` for gameobject entry %u, skipped.", + guid, pool_id, alt_pool_id, entry_id); + continue; + } + + if (!mapChecker.CheckAndRemember(data->mapid, pool_id, "pool_gameobject_template", "gameobject guid")) + continue; + + PoolTemplateData *pPoolTemplate = &mPoolTemplate[pool_id]; + + ++count; + + PoolObject plObject = PoolObject(guid, chance); + PoolGroup& gogroup = mPoolGameobjectGroups[pool_id]; + gogroup.SetPoolId(pool_id); + gogroup.AddEntry(plObject, pPoolTemplate->MaxLimit); + SearchPair p(guid, pool_id); + mGameobjectSearchMap.insert(p); + + } while( result->NextRow() ); + sLog.outString(); + sLog.outString(">> Loaded %u gameobject in pools from `pool_gameobject_template`", count ); delete result; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f9b082e1b..688addee3 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 "11189" + #define REVISION_NR "11190" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 847223830..826b0adbe 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_11117_02_characters_world" - #define REVISION_DB_MANGOS "required_11169_02_mangos_command" + #define REVISION_DB_MANGOS "required_11190_01_mangos_pool_gameobject_template" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__