From 5d2189b7b74eb07e1d1e1af15b4a53ca585be8c9 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Sun, 6 Dec 2009 19:44:44 +0100 Subject: [PATCH] [8929] Implement gossip scripts to be used with gossip_menu_option.action_script_id Note that script is implemented for GOSSIP_OPTION_GOSSIP only (as not expected needed for other gossip options). Also add a few more startup checks for LoadGossipMenuItems with check for basic errors in fields --- sql/mangos.sql | 29 +++++++++- sql/updates/8929_01_mangos_gossip_scripts.sql | 15 +++++ sql/updates/Makefile.am | 2 + src/game/GossipDef.h | 6 +- src/game/ObjectMgr.cpp | 58 +++++++++++++++++-- src/game/ObjectMgr.h | 2 + src/game/Player.cpp | 8 +++ src/game/World.cpp | 3 + src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 10 files changed, 116 insertions(+), 11 deletions(-) create mode 100644 sql/updates/8929_01_mangos_gossip_scripts.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 496dc9075..d782ee46c 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_8923_01_mangos_gossip` bit(1) default NULL + `required_8929_01_mangos_gossip_scripts` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -1981,6 +1981,33 @@ INSERT INTO gossip_menu_option VALUES /*!40000 ALTER TABLE `gossip_menu` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `gossip_scripts` +-- + +DROP TABLE IF EXISTS `gossip_scripts`; +CREATE TABLE `gossip_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', + `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 `gossip_scripts` +-- + +LOCK TABLES `gossip_scripts` WRITE; +/*!40000 ALTER TABLE `gossip_scripts` DISABLE KEYS */; +/*!40000 ALTER TABLE `gossip_scripts` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `instance_template` -- diff --git a/sql/updates/8929_01_mangos_gossip_scripts.sql b/sql/updates/8929_01_mangos_gossip_scripts.sql new file mode 100644 index 000000000..0a52a37da --- /dev/null +++ b/sql/updates/8929_01_mangos_gossip_scripts.sql @@ -0,0 +1,15 @@ +ALTER TABLE db_version CHANGE COLUMN required_8923_01_mangos_gossip required_8929_01_mangos_gossip_scripts bit; + +DROP TABLE IF EXISTS `gossip_scripts`; +CREATE TABLE `gossip_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', + `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 14b603189..a130d0092 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -190,6 +190,7 @@ pkgdata_DATA = \ 8912_01_mangos_spell_proc_event.sql \ 8917_01_mangos_spell_proc_event.sql \ 8923_01_mangos_gossip.sql \ + 8929_01_mangos_gossip_scripts.sql \ README ## Additional files to include when running 'make dist' @@ -360,4 +361,5 @@ EXTRA_DIST = \ 8912_01_mangos_spell_proc_event.sql \ 8917_01_mangos_spell_proc_event.sql \ 8923_01_mangos_gossip.sql \ + 8929_01_mangos_gossip_scripts.sql \ README diff --git a/src/game/GossipDef.h b/src/game/GossipDef.h index 335b010ca..1cb39b7d0 100644 --- a/src/game/GossipDef.h +++ b/src/game/GossipDef.h @@ -47,7 +47,8 @@ enum Gossip_Option GOSSIP_OPTION_STABLEPET = 14, //UNIT_NPC_FLAG_STABLE (4194304) GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER (4096) GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER) - GOSSIP_OPTION_UNLEARNPETSKILLS = 17 //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER) + GOSSIP_OPTION_UNLEARNPETSKILLS = 17, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER) + GOSSIP_OPTION_MAX }; enum GossipOptionIcon @@ -62,7 +63,8 @@ enum GossipOptionIcon GOSSIP_ICON_TALK = 7, //white chat bubble with black dots GOSSIP_ICON_TABARD = 8, //tabard GOSSIP_ICON_BATTLE = 9, //two swords - GOSSIP_ICON_DOT = 10 //yellow dot + GOSSIP_ICON_DOT = 10, //yellow dot + GOSSIP_ICON_MAX }; //POI icons. Many more exist, list not complete. diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 3166d34ed..117cd0867 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -43,6 +43,7 @@ #include "SpellAuras.h" #include "Util.h" #include "WaypointManager.h" +#include "GossipDef.h" INSTANTIATE_SINGLETON_1(ObjectMgr); @@ -51,6 +52,7 @@ ScriptMapMap sQuestStartScripts; ScriptMapMap sSpellScripts; ScriptMapMap sGameObjectScripts; ScriptMapMap sEventScripts; +ScriptMapMap sGossipScripts; bool normalizePlayerName(std::string& name) { @@ -4442,6 +4444,13 @@ void ObjectMgr::LoadEventScripts() } } +void ObjectMgr::LoadGossipScripts() +{ + LoadScripts(sGossipScripts, "gossip_scripts"); + + // checks are done in LoadGossipMenuItems +} + void ObjectMgr::LoadItemTexts() { QueryResult *result = CharacterDatabase.Query("SELECT id, text FROM item_text"); @@ -7918,7 +7927,7 @@ void ObjectMgr::LoadGossipMenuItems() bar.step(); sLog.outString(); - sLog.outErrorDb(">> Loaded gossip_menu_items, table is empty!"); + sLog.outErrorDb(">> Loaded gossip_menu_option, table is empty!"); return; } @@ -7926,6 +7935,11 @@ void ObjectMgr::LoadGossipMenuItems() uint32 count = 0; + std::set gossipScriptSet; + + for(ScriptMapMap::const_iterator itr = sGossipScripts.begin(); itr != sGossipScripts.end(); ++itr) + gossipScriptSet.insert(itr->first); + do { bar.step(); @@ -7959,26 +7973,52 @@ void ObjectMgr::LoadGossipMenuItems() if (!PlayerCondition::IsValid(cond_1, cond_1_val_1, cond_1_val_2)) { - sLog.outErrorDb("Table gossip_menu_items menu %u, invalid condition 1 for id %u", gMenuItem.menu_id, gMenuItem.id); + sLog.outErrorDb("Table gossip_menu_option menu %u, invalid condition 1 for id %u", gMenuItem.menu_id, gMenuItem.id); continue; } if (!PlayerCondition::IsValid(cond_2, cond_2_val_1, cond_2_val_2)) { - sLog.outErrorDb("Table gossip_menu_items menu %u, invalid condition 2 for id %u", gMenuItem.menu_id, gMenuItem.id); + sLog.outErrorDb("Table gossip_menu_option menu %u, invalid condition 2 for id %u", gMenuItem.menu_id, gMenuItem.id); continue; } if (!PlayerCondition::IsValid(cond_3, cond_3_val_1, cond_3_val_2)) { - sLog.outErrorDb("Table gossip_menu_items menu %u, invalid condition 3 for id %u", gMenuItem.menu_id, gMenuItem.id); + sLog.outErrorDb("Table gossip_menu_option menu %u, invalid condition 3 for id %u", gMenuItem.menu_id, gMenuItem.id); continue; } + if (gMenuItem.option_icon >= GOSSIP_ICON_MAX) + { + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u has unknown icon id %u. Replacing with GOSSIP_ICON_CHAT", gMenuItem.menu_id, gMenuItem.id, gMenuItem.option_icon); + gMenuItem.option_icon = GOSSIP_ICON_CHAT; + } + + if (gMenuItem.option_id >= GOSSIP_OPTION_MAX) + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u has unknown option id %u. Option will not be used", gMenuItem.menu_id, gMenuItem.id, gMenuItem.option_id); + if (gMenuItem.action_poi_id && !GetPointOfInterest(gMenuItem.action_poi_id)) { - sLog.outErrorDb("Table gossip_menu_items for menu %u, id %u use non-existing action_poi_id %u, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_poi_id); + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u use non-existing action_poi_id %u, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_poi_id); gMenuItem.action_poi_id = 0; } + if (gMenuItem.action_script_id) + { + if (gMenuItem.option_id != GOSSIP_OPTION_GOSSIP) + { + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u have action_script_id %u but option_id is not GOSSIP_OPTION_GOSSIP, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_script_id); + continue; + } + + if (sGossipScripts.find(gMenuItem.action_script_id) == sGossipScripts.end()) + { + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u have action_script_id %u that does not exist in `gossip_scripts`, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_script_id); + continue; + } + + gossipScriptSet.erase(gMenuItem.action_script_id); + } + gMenuItem.cond_1 = GetConditionId(cond_1, cond_1_val_1, cond_1_val_2); gMenuItem.cond_2 = GetConditionId(cond_2, cond_2_val_1, cond_2_val_2); gMenuItem.cond_3 = GetConditionId(cond_3, cond_3_val_1, cond_3_val_2); @@ -7992,8 +8032,14 @@ void ObjectMgr::LoadGossipMenuItems() delete result; + if (!gossipScriptSet.empty()) + { + for(std::set::const_iterator itr = gossipScriptSet.begin(); itr != gossipScriptSet.end(); ++itr) + sLog.outErrorDb("Table `gossip_scripts` contain unused script, id %u.", *itr); + } + sLog.outString(); - sLog.outString(">> Loaded %u gossip_menu_items entries", count); + sLog.outString(">> Loaded %u gossip_menu_option entries", count); } void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost ) diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 2fc21293e..931a853c1 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -93,6 +93,7 @@ extern ScriptMapMap sQuestStartScripts; extern ScriptMapMap sSpellScripts; extern ScriptMapMap sGameObjectScripts; extern ScriptMapMap sEventScripts; +extern ScriptMapMap sGossipScripts; struct SpellClickInfo { @@ -536,6 +537,7 @@ class ObjectMgr void LoadQuestStartScripts(); void LoadEventScripts(); void LoadSpellScripts(); + void LoadGossipScripts(); 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/Player.cpp b/src/game/Player.cpp index dc8958d58..d44360d5d 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12413,6 +12413,14 @@ void Player::OnGossipSelect(WorldObject* pSource, uint32 gossipListId, uint32 me if (pMenuData.m_gAction_poi) PlayerTalkClass->SendPointOfInterest(pMenuData.m_gAction_poi); + if (pMenuData.m_gAction_script) + { + if (pSource->GetTypeId() == TYPEID_UNIT) + GetMap()->ScriptsStart(sGossipScripts, pMenuData.m_gAction_script, this, pSource); + else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT) + GetMap()->ScriptsStart(sGossipScripts, pMenuData.m_gAction_script, pSource, this); + } + break; } case GOSSIP_OPTION_SPIRITHEALER: diff --git a/src/game/World.cpp b/src/game/World.cpp index c91bba636..ad772bdf7 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1402,6 +1402,9 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Npc Text Id..." ); sObjectMgr.LoadNpcTextId(); // must be after load Creature and NpcText + sLog.outString( "Loading Gossip scripts..." ); + sObjectMgr.LoadGossipScripts(); // must be before gossip menu options + sLog.outString( "Loading Gossip menus..." ); sObjectMgr.LoadGossipMenu(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7883c9cec..27f77340c 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 "8928" + #define REVISION_NR "8929" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index a325173b9..851acb02d 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_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8923_01_mangos_gossip" + #define REVISION_DB_MANGOS "required_8929_01_mangos_gossip_scripts" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__