diff --git a/sql/mangos.sql b/sql/mangos.sql index f861b0df1..496dc9075 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_8917_01_mangos_spell_proc_event` bit(1) default NULL + `required_8923_01_mangos_gossip` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -1899,6 +1899,88 @@ LOCK TABLES `gameobject_template` WRITE; /*!40000 ALTER TABLE `gameobject_template` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `gossip_menu` +-- + +DROP TABLE IF EXISTS gossip_menu; +CREATE TABLE gossip_menu ( + entry smallint(6) unsigned NOT NULL default '0', + text_id mediumint(8) unsigned NOT NULL default '0', + cond_1 tinyint(3) unsigned NOT NULL default '0', + cond_1_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_1_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_2 tinyint(3) unsigned NOT NULL default '0', + cond_2_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_2_val_2 mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (entry, text_id) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `gossip_menu` +-- + +LOCK TABLES `gossip_menu` WRITE; +/*!40000 ALTER TABLE `gossip_menu` DISABLE KEYS */; +/*!40000 ALTER TABLE `gossip_menu` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gossip_menu_option` +-- + +DROP TABLE IF EXISTS gossip_menu_option; +CREATE TABLE gossip_menu_option ( + menu_id smallint(6) unsigned NOT NULL default '0', + id smallint(6) unsigned NOT NULL default '0', + option_icon mediumint(8) unsigned NOT NULL default '0', + option_text text, + option_id tinyint(3) unsigned NOT NULL default '0', + npc_option_npcflag int(10) unsigned NOT NULL default '0', + action_menu_id mediumint(8) unsigned NOT NULL default '0', + action_poi_id mediumint(8) unsigned NOT NULL default '0', + action_script_id mediumint(8) unsigned NOT NULL default '0', + box_coded tinyint(3) unsigned NOT NULL default '0', + box_money int(11) unsigned NOT NULL default '0', + box_text text, + cond_1 tinyint(3) unsigned NOT NULL default '0', + cond_1_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_1_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_2 tinyint(3) unsigned NOT NULL default '0', + cond_2_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_2_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_3 tinyint(3) unsigned NOT NULL default '0', + cond_3_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_3_val_2 mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (menu_id, id) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `gossip_menu_option` +-- + +LOCK TABLES `gossip_menu_option` WRITE; +/*!40000 ALTER TABLE `gossip_menu_option` DISABLE KEYS */; +INSERT INTO gossip_menu_option VALUES +(0,0,0,'GOSSIP_OPTION_QUESTGIVER',2,2,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,1,1,'GOSSIP_OPTION_VENDOR',3,128,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,2,2,'GOSSIP_OPTION_TAXIVENDOR',4,8192,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,3,3,'GOSSIP_OPTION_TRAINER',5,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,4,4,'GOSSIP_OPTION_SPIRITHEALER',6,16384,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,5,4,'GOSSIP_OPTION_SPIRITGUIDE',7,32768,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,6,5,'GOSSIP_OPTION_INNKEEPER',8,65536,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,7,6,'GOSSIP_OPTION_BANKER',9,131072,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,8,7,'GOSSIP_OPTION_PETITIONER',10,262144,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,9,8,'GOSSIP_OPTION_TABARDDESIGNER',11,524288,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,10,9,'GOSSIP_OPTION_BATTLEFIELD',12,1048576,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,11,6,'GOSSIP_OPTION_AUCTIONEER',13,2097152,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,12,0,'GOSSIP_OPTION_STABLEPET',14,4194304,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,13,1,'GOSSIP_OPTION_ARMORER',15,4096,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,14,2,'GOSSIP_OPTION_UNLEARNTALENTS',16,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,15,2,'GOSSIP_OPTION_UNLEARNPETSKILLS',17,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0); +/*!40000 ALTER TABLE `gossip_menu` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `instance_template` -- @@ -2344,6 +2426,42 @@ LOCK TABLES `locales_gameobject` WRITE; /*!40000 ALTER TABLE `locales_gameobject` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `locales_gossip_menu_option` +-- + +DROP TABLE IF EXISTS `locales_gossip_menu_option`; +CREATE TABLE `locales_gossip_menu_option` ( + `menu_id` smallint(6) unsigned NOT NULL default '0', + `id` smallint(6) unsigned NOT NULL default '0', + `option_text_loc1` text, + `option_text_loc2` text, + `option_text_loc3` text, + `option_text_loc4` text, + `option_text_loc5` text, + `option_text_loc6` text, + `option_text_loc7` text, + `option_text_loc8` text, + `box_text_loc1` text, + `box_text_loc2` text, + `box_text_loc3` text, + `box_text_loc4` text, + `box_text_loc5` text, + `box_text_loc6` text, + `box_text_loc7` text, + `box_text_loc8` text, + PRIMARY KEY (`menu_id`, `id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `locales_gossip_menu_option` +-- + +LOCK TABLES `locales_gossip_menu_option` WRITE; +/*!40000 ALTER TABLE `locales_gossip_menu_option` DISABLE KEYS */; +/*!40000 ALTER TABLE `locales_gossip_menu_option` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `locales_item` -- @@ -2379,42 +2497,6 @@ LOCK TABLES `locales_item` WRITE; /*!40000 ALTER TABLE `locales_item` ENABLE KEYS */; UNLOCK TABLES; - --- --- Table structure for table `locales_npc_option` --- - -DROP TABLE IF EXISTS `locales_npc_option`; -CREATE TABLE `locales_npc_option` ( - `entry` mediumint(8) unsigned NOT NULL default '0', - `option_text_loc1` text, - `option_text_loc2` text, - `option_text_loc3` text, - `option_text_loc4` text, - `option_text_loc5` text, - `option_text_loc6` text, - `option_text_loc7` text, - `option_text_loc8` text, - `box_text_loc1` text, - `box_text_loc2` text, - `box_text_loc3` text, - `box_text_loc4` text, - `box_text_loc5` text, - `box_text_loc6` text, - `box_text_loc7` text, - `box_text_loc8` text, - PRIMARY KEY (`entry`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `locales_npc_option` --- - -LOCK TABLES `locales_npc_option` WRITE; -/*!40000 ALTER TABLE `locales_npc_option` DISABLE KEYS */; -/*!40000 ALTER TABLE `locales_npc_option` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `locales_npc_text` -- @@ -3530,54 +3612,6 @@ LOCK TABLES `npc_gossip` WRITE; /*!40000 ALTER TABLE `npc_gossip` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `npc_gossip_textid` --- - -DROP TABLE IF EXISTS `npc_gossip_textid`; -CREATE TABLE `npc_gossip_textid` ( - `zoneid` smallint(5) unsigned NOT NULL default '0', - `action` smallint(5) unsigned NOT NULL default '0', - `textid` mediumint(8) unsigned NOT NULL default '0', - KEY `zoneid` (`zoneid`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `npc_gossip_textid` --- - -LOCK TABLES `npc_gossip_textid` WRITE; -/*!40000 ALTER TABLE `npc_gossip_textid` DISABLE KEYS */; -/*!40000 ALTER TABLE `npc_gossip_textid` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `npc_option` --- - -DROP TABLE IF EXISTS `npc_option`; -CREATE TABLE `npc_option` ( - `id` mediumint(8) unsigned NOT NULL default '0', - `gossip_id` mediumint(8) unsigned NOT NULL default '0', - `npcflag` int(10) unsigned NOT NULL default '0', - `icon` tinyint(3) unsigned NOT NULL default '0', - `action` mediumint(8) unsigned NOT NULL default '0', - `box_money` int(10) unsigned NOT NULL default '0', - `coded` tinyint(3) unsigned NOT NULL default '0', - `option_text` text, - `box_text` text, - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `npc_option` --- - -LOCK TABLES `npc_option` WRITE; -/*!40000 ALTER TABLE `npc_option` DISABLE KEYS */; -/*!40000 ALTER TABLE `npc_option` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `npc_spellclick_spells` -- diff --git a/sql/updates/8923_01_mangos_gossip.sql b/sql/updates/8923_01_mangos_gossip.sql new file mode 100644 index 000000000..896c66def --- /dev/null +++ b/sql/updates/8923_01_mangos_gossip.sql @@ -0,0 +1,72 @@ +ALTER TABLE db_version CHANGE COLUMN required_8917_01_mangos_spell_proc_event required_8923_01_mangos_gossip bit; + +DROP TABLE IF EXISTS gossip_menu; +CREATE TABLE gossip_menu ( + entry smallint(6) unsigned NOT NULL default '0', + text_id mediumint(8) unsigned NOT NULL default '0', + cond_1 tinyint(3) unsigned NOT NULL default '0', + cond_1_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_1_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_2 tinyint(3) unsigned NOT NULL default '0', + cond_2_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_2_val_2 mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (entry, text_id) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS gossip_menu_option; +CREATE TABLE gossip_menu_option ( + menu_id smallint(6) unsigned NOT NULL default '0', + id smallint(6) unsigned NOT NULL default '0', + option_icon mediumint(8) unsigned NOT NULL default '0', + option_text text, + option_id tinyint(3) unsigned NOT NULL default '0', + npc_option_npcflag int(10) unsigned NOT NULL default '0', + action_menu_id mediumint(8) unsigned NOT NULL default '0', + action_poi_id mediumint(8) unsigned NOT NULL default '0', + action_script_id mediumint(8) unsigned NOT NULL default '0', + box_coded tinyint(3) unsigned NOT NULL default '0', + box_money int(11) unsigned NOT NULL default '0', + box_text text, + cond_1 tinyint(3) unsigned NOT NULL default '0', + cond_1_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_1_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_2 tinyint(3) unsigned NOT NULL default '0', + cond_2_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_2_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_3 tinyint(3) unsigned NOT NULL default '0', + cond_3_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_3_val_2 mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (menu_id, id) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DELETE FROM gossip_menu_option WHERE menu_id=0; +INSERT INTO gossip_menu_option VALUES +(0,0,0,'GOSSIP_OPTION_QUESTGIVER',2,2,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,1,1,'GOSSIP_OPTION_VENDOR',3,128,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,2,2,'GOSSIP_OPTION_TAXIVENDOR',4,8192,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,3,3,'GOSSIP_OPTION_TRAINER',5,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,4,4,'GOSSIP_OPTION_SPIRITHEALER',6,16384,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,5,4,'GOSSIP_OPTION_SPIRITGUIDE',7,32768,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,6,5,'GOSSIP_OPTION_INNKEEPER',8,65536,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,7,6,'GOSSIP_OPTION_BANKER',9,131072,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,8,7,'GOSSIP_OPTION_PETITIONER',10,262144,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,9,8,'GOSSIP_OPTION_TABARDDESIGNER',11,524288,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,10,9,'GOSSIP_OPTION_BATTLEFIELD',12,1048576,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,11,6,'GOSSIP_OPTION_AUCTIONEER',13,2097152,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,12,0,'GOSSIP_OPTION_STABLEPET',14,4194304,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,13,1,'GOSSIP_OPTION_ARMORER',15,4096,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,14,2,'GOSSIP_OPTION_UNLEARNTALENTS',16,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,15,2,'GOSSIP_OPTION_UNLEARNPETSKILLS',17,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0); + +ALTER TABLE creature_template ADD gossip_menu_id mediumint(8) unsigned NOT NULL default 0 AFTER IconName; + +ALTER TABLE locales_npc_option CHANGE COLUMN entry id smallint(6) unsigned NOT NULL default '0'; +ALTER TABLE locales_npc_option ADD menu_id smallint(6) unsigned NOT NULL default '0' FIRST; + +ALTER TABLE locales_npc_option DROP PRIMARY KEY; +ALTER TABLE locales_npc_option ADD PRIMARY KEY (menu_id, id); + +RENAME TABLE locales_npc_option TO locales_gossip_menu_option; + +DROP TABLE IF EXISTS npc_option; +DROP TABLE IF EXISTS npc_gossip_textid; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 056287b36..14b603189 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -189,6 +189,7 @@ pkgdata_DATA = \ 8909_01_mangos_spell_proc_event.sql \ 8912_01_mangos_spell_proc_event.sql \ 8917_01_mangos_spell_proc_event.sql \ + 8923_01_mangos_gossip.sql \ README ## Additional files to include when running 'make dist' @@ -358,4 +359,5 @@ EXTRA_DIST = \ 8909_01_mangos_spell_proc_event.sql \ 8912_01_mangos_spell_proc_event.sql \ 8917_01_mangos_spell_proc_event.sql \ + 8923_01_mangos_gossip.sql \ README diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 8cd094a85..06949e94a 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -110,7 +110,7 @@ Unit(), i_AI(NULL), lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), m_lootMoney(0), m_lootRecipient(0), m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f), -m_gossipOptionLoaded(false), m_isPet(false), m_isVehicle(false), m_isTotem(false), +m_isPet(false), m_isVehicle(false), m_isTotem(false), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), @@ -744,21 +744,6 @@ bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const && pPlayer->getClass() == GetCreatureInfo()->trainer_class; } -void Creature::LoadGossipOptions() -{ - if(m_gossipOptionLoaded) - return; - - uint32 npcflags=GetUInt32Value(UNIT_NPC_FLAGS); - - CacheNpcOptionList const& noList = sObjectMgr.GetNpcOptions (); - for (CacheNpcOptionList::const_iterator i = noList.begin (); i != noList.end (); ++i) - if(i->NpcFlag & npcflags) - addGossipOption(*i); - - m_gossipOptionLoaded = true; -} - void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, MonsterMovementFlags flags, uint8 type) { /* uint32 timeElap = getMSTime(); diff --git a/src/game/Creature.h b/src/game/Creature.h index 781acb9ad..e6e46fe79 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -36,102 +36,6 @@ class Quest; class Player; class WorldSession; -enum Gossip_Option -{ - GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE = 0, - GOSSIP_OPTION_GOSSIP = 1, //UNIT_NPC_FLAG_GOSSIP = 1, - GOSSIP_OPTION_QUESTGIVER = 2, //UNIT_NPC_FLAG_QUESTGIVER = 2, - GOSSIP_OPTION_VENDOR = 3, //UNIT_NPC_FLAG_VENDOR = 4, - GOSSIP_OPTION_TAXIVENDOR = 4, //UNIT_NPC_FLAG_TAXIVENDOR = 8, - GOSSIP_OPTION_TRAINER = 5, //UNIT_NPC_FLAG_TRAINER = 16, - GOSSIP_OPTION_SPIRITHEALER = 6, //UNIT_NPC_FLAG_SPIRITHEALER = 32, - GOSSIP_OPTION_SPIRITGUIDE = 7, //UNIT_NPC_FLAG_SPIRITGUIDE = 64, - GOSSIP_OPTION_INNKEEPER = 8, //UNIT_NPC_FLAG_INNKEEPER = 128, - GOSSIP_OPTION_BANKER = 9, //UNIT_NPC_FLAG_BANKER = 256, - GOSSIP_OPTION_PETITIONER = 10, //UNIT_NPC_FLAG_PETITIONER = 512, - GOSSIP_OPTION_TABARDDESIGNER = 11, //UNIT_NPC_FLAG_TABARDDESIGNER = 1024, - GOSSIP_OPTION_BATTLEFIELD = 12, //UNIT_NPC_FLAG_BATTLEFIELDPERSON = 2048, - GOSSIP_OPTION_AUCTIONEER = 13, //UNIT_NPC_FLAG_AUCTIONEER = 4096, - GOSSIP_OPTION_STABLEPET = 14, //UNIT_NPC_FLAG_STABLE = 8192, - GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER = 16384, - GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER) - GOSSIP_OPTION_UNLEARNPETSKILLS = 17 //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER) -}; - -enum Gossip_Guard -{ - GOSSIP_GUARD_BANK = 32, - GOSSIP_GUARD_RIDE = 33, - GOSSIP_GUARD_GUILD = 34, - GOSSIP_GUARD_INN = 35, - GOSSIP_GUARD_MAIL = 36, - GOSSIP_GUARD_AUCTION = 37, - GOSSIP_GUARD_WEAPON = 38, - GOSSIP_GUARD_STABLE = 39, - GOSSIP_GUARD_BATTLE = 40, - GOSSIP_GUARD_SPELLTRAINER = 41, - GOSSIP_GUARD_SKILLTRAINER = 42 -}; - -enum Gossip_Guard_Spell -{ - GOSSIP_GUARD_SPELL_WARRIOR = 64, - GOSSIP_GUARD_SPELL_PALADIN = 65, - GOSSIP_GUARD_SPELL_HUNTER = 66, - GOSSIP_GUARD_SPELL_ROGUE = 67, - GOSSIP_GUARD_SPELL_PRIEST = 68, - GOSSIP_GUARD_SPELL_UNKNOWN1 = 69, - GOSSIP_GUARD_SPELL_SHAMAN = 70, - GOSSIP_GUARD_SPELL_MAGE = 71, - GOSSIP_GUARD_SPELL_WARLOCK = 72, - GOSSIP_GUARD_SPELL_UNKNOWN2 = 73, - GOSSIP_GUARD_SPELL_DRUID = 74 -}; - -enum Gossip_Guard_Skill -{ - GOSSIP_GUARD_SKILL_ALCHEMY = 80, - GOSSIP_GUARD_SKILL_BLACKSMITH = 81, - GOSSIP_GUARD_SKILL_COOKING = 82, - GOSSIP_GUARD_SKILL_ENCHANT = 83, - GOSSIP_GUARD_SKILL_FIRSTAID = 84, - GOSSIP_GUARD_SKILL_FISHING = 85, - GOSSIP_GUARD_SKILL_HERBALISM = 86, - GOSSIP_GUARD_SKILL_LEATHER = 87, - GOSSIP_GUARD_SKILL_MINING = 88, - GOSSIP_GUARD_SKILL_SKINNING = 89, - GOSSIP_GUARD_SKILL_TAILORING = 90, - GOSSIP_GUARD_SKILL_ENGINERING = 91 -}; - -enum GossipOptionIcon -{ - GOSSIP_ICON_CHAT = 0, //white chat bubble - GOSSIP_ICON_VENDOR = 1, //brown bag - GOSSIP_ICON_TAXI = 2, //flight - GOSSIP_ICON_TRAINER = 3, //book - GOSSIP_ICON_INTERACT_1 = 4, //interaction wheel - GOSSIP_ICON_INTERACT_2 = 5, //interaction wheel - GOSSIP_ICON_MONEY_BAG = 6, //brown bag with yellow dot - 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 -}; - -struct GossipOption -{ - uint32 Id; - uint32 GossipId; - uint32 NpcFlag; - uint32 Icon; - uint32 Action; - uint32 BoxMoney; - bool Coded; - std::string OptionText; - std::string BoxText; -}; - enum CreatureFlagsExtra { CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group @@ -165,6 +69,7 @@ struct CreatureInfo char* Name; char* SubName; char* IconName; + uint32 GossipMenuId; uint32 minlevel; uint32 maxlevel; uint32 minhealth; @@ -449,8 +354,6 @@ struct TrainerSpellData void Clear() { spellList.clear(); } }; -typedef std::list GossipOptionList; - typedef std::map CreatureSpellCooldowns; // max different by z coordinate for creature aggro reaction @@ -576,10 +479,6 @@ class MANGOS_DLL_SPEC Creature : public Unit std::string GetScriptName() const; uint32 GetScriptId() const; - void LoadGossipOptions(); - void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); } - GossipOptionList &GetGossipOptionList() { return m_goptions; } - void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); } void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); } void TextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(textId,TargetGuid,IsBossEmote); } @@ -708,9 +607,6 @@ class MANGOS_DLL_SPEC Creature : public Unit uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance float m_respawnradius; - bool m_gossipOptionLoaded; - GossipOptionList m_goptions; - bool m_isPet; // set only in Pet::Pet bool m_isVehicle; // set only in Vehicle::Vehicle bool m_isTotem; // set only in Totem::Totem diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 0aa6f7f99..e8aa32b67 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -872,13 +872,13 @@ void GameObject::Use(Unit* user) case GAMEOBJECT_TYPE_QUESTGIVER: //2 { - if(user->GetTypeId()!=TYPEID_PLAYER) + if (user->GetTypeId() != TYPEID_PLAYER) return; Player* player = (Player*)user; - player->PrepareQuestMenu( GetGUID() ); - player->SendPreparedQuest( GetGUID() ); + player->PrepareGossipMenu(this, GetGOInfo()->questgiver.gossipID); + player->SendPreparedGossip(this); return; } //Sitting: Wooden bench, chairs enzz @@ -952,12 +952,17 @@ void GameObject::Use(Unit* user) Player* player = (Player*)user; // show page - if(info->goober.pageId) + if (info->goober.pageId) { WorldPacket data(SMSG_GAMEOBJECT_PAGETEXT, 8); data << GetGUID(); player->GetSession()->SendPacket(&data); } + else if (info->questgiver.gossipID) + { + player->PrepareGossipMenu(this, info->goober.gossipID); + player->SendPreparedGossip(this); + } // possible quest objective for active quests player->CastedCreatureOrGO(info->id, GetGUID(), 0); diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp index 12fd7846c..5b269da61 100644 --- a/src/game/GossipDef.cpp +++ b/src/game/GossipDef.cpp @@ -27,6 +27,7 @@ GossipMenu::GossipMenu() { m_gItems.reserve(16); // can be set for max from most often sizes to speedup push_back and less memory use + m_gMenuId = 0; } GossipMenu::~GossipMenu() @@ -44,13 +45,24 @@ void GossipMenu::AddMenuItem(uint8 Icon, const std::string& Message, uint32 dtSe gItem.m_gMessage = Message; gItem.m_gCoded = Coded; gItem.m_gSender = dtSender; - gItem.m_gAction = dtAction; + gItem.m_gOptionId = dtAction; gItem.m_gBoxMessage = BoxMessage; gItem.m_gBoxMoney = BoxMoney; m_gItems.push_back(gItem); } +void GossipMenu::AddGossipMenuItemData(uint32 action_menu, uint32 action_poi, uint32 action_script) +{ + GossipMenuItemData pItemData; + + pItemData.m_gAction_menu = action_menu; + pItemData.m_gAction_poi = action_poi; + pItemData.m_gAction_script = action_script; + + m_gItemsData.push_back(pItemData); +} + void GossipMenu::AddMenuItem(uint8 Icon, const std::string& Message, bool Coded) { AddMenuItem( Icon, Message, 0, 0, "", 0, Coded); @@ -77,7 +89,7 @@ uint32 GossipMenu::MenuItemAction( unsigned int ItemId ) { if ( ItemId >= m_gItems.size() ) return 0; - return m_gItems[ ItemId ].m_gAction; + return m_gItems[ ItemId ].m_gOptionId; } bool GossipMenu::MenuItemCoded( unsigned int ItemId ) @@ -90,6 +102,7 @@ bool GossipMenu::MenuItemCoded( unsigned int ItemId ) void GossipMenu::ClearMenu() { m_gItems.clear(); + m_gItemsData.clear(); } PlayerMenu::PlayerMenu( WorldSession *session ) : pSession(session) @@ -122,13 +135,13 @@ bool PlayerMenu::GossipOptionCoded( unsigned int Selection ) return mGossipMenu.MenuItemCoded( Selection ); } -void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID ) +void PlayerMenu::SendGossipMenu(uint32 TitleTextId, uint64 objectGUID) { - WorldPacket data( SMSG_GOSSIP_MESSAGE, (100) ); // guess size - data << uint64(npcGUID); - data << uint32(0); // new 2.4.0 - data << uint32( TitleTextId ); - data << uint32( mGossipMenu.MenuItemCount() ); // max count 0x10 + WorldPacket data(SMSG_GOSSIP_MESSAGE, (100)); // guess size + data << uint64(objectGUID); + data << uint32(mGossipMenu.GetMenuId()); // new 2.4.0 + data << uint32(TitleTextId); + data << uint32(mGossipMenu.MenuItemCount()); // max count 0x10 for (uint32 iI = 0; iI < mGossipMenu.MenuItemCount(); ++iI ) { diff --git a/src/game/GossipDef.h b/src/game/GossipDef.h index ea31b4c15..335b010ca 100644 --- a/src/game/GossipDef.h +++ b/src/game/GossipDef.h @@ -28,6 +28,43 @@ class WorldSession; #define GOSSIP_MAX_MENU_ITEMS 64 // client supported items unknown, but provided number must be enough #define DEFAULT_GOSSIP_MESSAGE 0xffffff +enum Gossip_Option +{ + GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE (0) + GOSSIP_OPTION_GOSSIP = 1, //UNIT_NPC_FLAG_GOSSIP (1) + GOSSIP_OPTION_QUESTGIVER = 2, //UNIT_NPC_FLAG_QUESTGIVER (2) + GOSSIP_OPTION_VENDOR = 3, //UNIT_NPC_FLAG_VENDOR (128) + GOSSIP_OPTION_TAXIVENDOR = 4, //UNIT_NPC_FLAG_TAXIVENDOR (8192) + GOSSIP_OPTION_TRAINER = 5, //UNIT_NPC_FLAG_TRAINER (16) + GOSSIP_OPTION_SPIRITHEALER = 6, //UNIT_NPC_FLAG_SPIRITHEALER (16384) + GOSSIP_OPTION_SPIRITGUIDE = 7, //UNIT_NPC_FLAG_SPIRITGUIDE (32768) + GOSSIP_OPTION_INNKEEPER = 8, //UNIT_NPC_FLAG_INNKEEPER (65536) + GOSSIP_OPTION_BANKER = 9, //UNIT_NPC_FLAG_BANKER (131072) + GOSSIP_OPTION_PETITIONER = 10, //UNIT_NPC_FLAG_PETITIONER (262144) + GOSSIP_OPTION_TABARDDESIGNER = 11, //UNIT_NPC_FLAG_TABARDDESIGNER (524288) + GOSSIP_OPTION_BATTLEFIELD = 12, //UNIT_NPC_FLAG_BATTLEFIELDPERSON (1048576) + GOSSIP_OPTION_AUCTIONEER = 13, //UNIT_NPC_FLAG_AUCTIONEER (2097152) + 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) +}; + +enum GossipOptionIcon +{ + GOSSIP_ICON_CHAT = 0, //white chat bubble + GOSSIP_ICON_VENDOR = 1, //brown bag + GOSSIP_ICON_TAXI = 2, //flight + GOSSIP_ICON_TRAINER = 3, //book + GOSSIP_ICON_INTERACT_1 = 4, //interaction wheel + GOSSIP_ICON_INTERACT_2 = 5, //interaction wheel + GOSSIP_ICON_MONEY_BAG = 6, //brown bag with yellow dot + 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 +}; + //POI icons. Many more exist, list not complete. enum Poi_Icon { @@ -80,13 +117,22 @@ struct GossipMenuItem bool m_gCoded; std::string m_gMessage; uint32 m_gSender; - uint32 m_gAction; + uint32 m_gOptionId; std::string m_gBoxMessage; uint32 m_gBoxMoney; }; typedef std::vector GossipMenuItemList; +struct GossipMenuItemData +{ + uint32 m_gAction_menu; + uint32 m_gAction_poi; + uint32 m_gAction_script; +}; + +typedef std::vector GossipMenuItemDataList; + struct QuestMenuItem { uint32 m_qId; @@ -108,6 +154,11 @@ class MANGOS_DLL_SPEC GossipMenu void AddMenuItem(uint8 Icon, char const* Message, bool Coded = false); void AddMenuItem(uint8 Icon, char const* Message, uint32 dtSender, uint32 dtAction, char const* BoxMessage, uint32 BoxMoney, bool Coded = false); + void SetMenuId(uint32 menu_id) { m_gMenuId = menu_id; } + uint32 GetMenuId() { return m_gMenuId; } + + void AddGossipMenuItemData(uint32 action_menu, uint32 action_poi, uint32 action_script); + unsigned int MenuItemCount() const { return m_gItems.size(); @@ -123,6 +174,11 @@ class MANGOS_DLL_SPEC GossipMenu return m_gItems[ Id ]; } + GossipMenuItemData const& GetItemData(unsigned int indexId) + { + return m_gItemsData[indexId]; + } + uint32 MenuItemSender( unsigned int ItemId ); uint32 MenuItemAction( unsigned int ItemId ); bool MenuItemCoded( unsigned int ItemId ); @@ -130,7 +186,10 @@ class MANGOS_DLL_SPEC GossipMenu void ClearMenu(); protected: - GossipMenuItemList m_gItems; + GossipMenuItemList m_gItems; + GossipMenuItemDataList m_gItemsData; + + uint32 m_gMenuId; }; class QuestMenu diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 94413af32..4320b5ae0 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -407,7 +407,8 @@ bool ChatHandler::HandleReloadMangosStringCommand(const char*) bool ChatHandler::HandleReloadNpcOptionCommand(const char*) { sLog.outString( "Re-Loading `npc_option` Table!" ); - sObjectMgr.LoadNpcOptions(); + //sObjectMgr.LoadGossipMenu(); + //sObjectMgr.LoadGossipMenuItems(); SendGlobalSysMessage("DB table `npc_option` reloaded."); return true; } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index e3101cc1b..6d74f770e 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -277,7 +277,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket & recv_data) if (!Script->GossipHello(_player, pCreature)) { _player->TalkedToCreature(pCreature->GetEntry(), pCreature->GetGUID()); - _player->PrepareGossipMenu(pCreature); + _player->PrepareGossipMenu(pCreature, pCreature->GetCreatureInfo()->GossipMenuId); _player->SendPreparedGossip(pCreature); } } @@ -286,14 +286,14 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) { sLog.outDebug("WORLD: CMSG_GOSSIP_SELECT_OPTION"); - uint32 option; + uint32 gossipListId; uint32 menuId; uint64 guid; std::string code = ""; - recv_data >> guid >> menuId >> option; + recv_data >> guid >> menuId >> gossipListId; - if (_player->PlayerTalkClass->GossipOptionCoded(option)) + if (_player->PlayerTalkClass->GossipOptionCoded(gossipListId)) { sLog.outBasic("reading string"); recv_data >> code; @@ -314,13 +314,13 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) if (!code.empty()) { - if (!Script->GossipSelectWithCode(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(option), _player->PlayerTalkClass->GossipOptionAction(option), code.c_str())) - _player->OnGossipSelect(pCreature, option); + if (!Script->GossipSelectWithCode(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str())) + _player->OnGossipSelect(pCreature, gossipListId, menuId); } else { - if (!Script->GossipSelect(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(option), _player->PlayerTalkClass->GossipOptionAction(option))) - _player->OnGossipSelect(pCreature, option); + if (!Script->GossipSelect(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId))) + _player->OnGossipSelect(pCreature, gossipListId, menuId); } } diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 3407fd9ce..2bacdaa39 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -342,12 +342,12 @@ void ObjectMgr::LoadNpcOptionLocales() { mNpcOptionLocaleMap.clear(); // need for reload case - QueryResult *result = WorldDatabase.Query("SELECT entry," + QueryResult *result = WorldDatabase.Query("SELECT menu_id,id," "option_text_loc1,box_text_loc1,option_text_loc2,box_text_loc2," "option_text_loc3,box_text_loc3,option_text_loc4,box_text_loc4," "option_text_loc5,box_text_loc5,option_text_loc6,box_text_loc6," "option_text_loc7,box_text_loc7,option_text_loc8,box_text_loc8 " - "FROM locales_npc_option"); + "FROM locales_gossip_menu_option"); if(!result) { @@ -356,7 +356,7 @@ void ObjectMgr::LoadNpcOptionLocales() bar.step(); sLog.outString(); - sLog.outString(">> Loaded 0 npc_option locale strings. DB table `locales_npc_option` is empty."); + sLog.outString(">> Loaded 0 gossip_menu_option locale strings. DB table `locales_gossip_menu_option` is empty."); return; } @@ -367,9 +367,10 @@ void ObjectMgr::LoadNpcOptionLocales() Field *fields = result->Fetch(); bar.step(); - uint32 entry = fields[0].GetUInt32(); + uint16 menuId = fields[0].GetUInt16(); + uint16 id = fields[1].GetUInt16(); - NpcOptionLocale& data = mNpcOptionLocaleMap[entry]; + NpcOptionLocale& data = mNpcOptionLocaleMap[MAKE_PAIR32(menuId,id)]; for(int i = 1; i < MAX_LOCALE; ++i) { @@ -403,7 +404,7 @@ void ObjectMgr::LoadNpcOptionLocales() delete result; sLog.outString(); - sLog.outString( ">> Loaded %lu npc_option locale strings", (unsigned long)mNpcOptionLocaleMap.size() ); + sLog.outString( ">> Loaded %lu gossip_menu_option locale strings", (unsigned long)mNpcOptionLocaleMap.size() ); } void ObjectMgr::LoadPointOfInterestLocales() @@ -7825,23 +7826,21 @@ void ObjectMgr::LoadNpcTextId() sLog.outString( ">> Loaded %d NpcTextId ", count ); } -void ObjectMgr::LoadNpcOptions() +void ObjectMgr::LoadGossipMenu() { - m_mCacheNpcOptionList.clear(); // For reload case + m_mGossipMenusMap.clear(); - QueryResult *result = WorldDatabase.Query( - // 0 1 2 3 4 5 6 7 8 - "SELECT id,gossip_id,npcflag,icon,action,box_money,coded,option_text,box_text " - "FROM npc_option"); + QueryResult* result = WorldDatabase.Query("SELECT entry, text_id, " + "cond_1, cond_1_val_1, cond_1_val_2, cond_2, cond_2_val_1, cond_2_val_2 FROM gossip_menu"); - if( !result ) + if (!result) { - barGoLink bar( 1 ); + barGoLink bar(1); bar.step(); sLog.outString(); - sLog.outErrorDb(">> Loaded `npc_option`, table is empty!"); + sLog.outErrorDb(">> Loaded gossip_menu, table is empty!"); return; } @@ -7855,26 +7854,146 @@ void ObjectMgr::LoadNpcOptions() Field* fields = result->Fetch(); - GossipOption go; - go.Id = fields[0].GetUInt32(); - go.GossipId = fields[1].GetUInt32(); - go.NpcFlag = fields[2].GetUInt32(); - go.Icon = fields[3].GetUInt32(); - go.Action = fields[4].GetUInt32(); - go.BoxMoney = fields[5].GetUInt32(); - go.Coded = fields[6].GetUInt8()!=0; - go.OptionText = fields[7].GetCppString(); - go.BoxText = fields[8].GetCppString(); + GossipMenus gMenu; - m_mCacheNpcOptionList.push_back(go); + gMenu.entry = fields[0].GetUInt32(); + gMenu.text_id = fields[1].GetUInt32(); + + ConditionType cond_1 = (ConditionType)fields[2].GetUInt32(); + uint32 cond_1_val_1 = fields[3].GetUInt32(); + uint32 cond_1_val_2 = fields[4].GetUInt32(); + ConditionType cond_2 = (ConditionType)fields[5].GetUInt32(); + uint32 cond_2_val_1 = fields[6].GetUInt32(); + uint32 cond_2_val_2 = fields[7].GetUInt32(); + + if (!GetGossipText(gMenu.text_id)) + { + sLog.outErrorDb("Table gossip_menu entry %u are using non-existing text_id %u", gMenu.entry, gMenu.text_id); + continue; + } + + if (!PlayerCondition::IsValid(cond_1, cond_1_val_1, cond_1_val_2)) + { + sLog.outErrorDb("Table gossip_menu entry %u, invalid condition 1 for id %u", gMenu.entry, gMenu.text_id); + continue; + } + + if (!PlayerCondition::IsValid(cond_2, cond_2_val_1, cond_2_val_2)) + { + sLog.outErrorDb("Table gossip_menu entry %u, invalid condition 2 for id %u", gMenu.entry, gMenu.text_id); + continue; + } + + gMenu.cond_1 = GetConditionId(cond_1, cond_1_val_1, cond_1_val_2); + gMenu.cond_2 = GetConditionId(cond_2, cond_2_val_1, cond_2_val_2); + + m_mGossipMenusMap.insert(GossipMenusMap::value_type(gMenu.entry, gMenu)); ++count; + } + while(result->NextRow()); - } while (result->NextRow()); delete result; sLog.outString(); - sLog.outString( ">> Loaded %d npc_option entries", count ); + sLog.outString( ">> Loaded %u gossip_menu entries", count); +} + +void ObjectMgr::LoadGossipMenuItems() +{ + m_mGossipMenuItemsMap.clear(); + + QueryResult *result = WorldDatabase.Query( + "SELECT menu_id, id, option_icon, option_text, option_id, npc_option_npcflag, " + "action_menu_id, action_poi_id, action_script_id, box_coded, box_money, box_text, " + "cond_1, cond_1_val_1, cond_1_val_2, " + "cond_2, cond_2_val_1, cond_2_val_2, " + "cond_3, cond_3_val_1, cond_3_val_2 " + "FROM gossip_menu_option"); + + if (!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded gossip_menu_items, table is empty!"); + return; + } + + barGoLink bar(result->GetRowCount()); + + uint32 count = 0; + + do + { + bar.step(); + + Field* fields = result->Fetch(); + + GossipMenuItems gMenuItem; + + gMenuItem.menu_id = fields[0].GetUInt32(); + gMenuItem.id = fields[1].GetUInt32(); + gMenuItem.option_icon = fields[2].GetUInt8(); + gMenuItem.option_text = fields[3].GetCppString(); + gMenuItem.option_id = fields[4].GetUInt32(); + gMenuItem.npc_option_npcflag = fields[5].GetUInt32(); + gMenuItem.action_menu_id = fields[6].GetUInt32(); + gMenuItem.action_poi_id = fields[7].GetUInt32(); + gMenuItem.action_script_id = fields[8].GetUInt32(); + gMenuItem.box_coded = fields[9].GetUInt8() != 0; + gMenuItem.box_money = fields[10].GetUInt32(); + gMenuItem.box_text = fields[11].GetCppString(); + + ConditionType cond_1 = (ConditionType)fields[12].GetUInt32(); + uint32 cond_1_val_1 = fields[13].GetUInt32(); + uint32 cond_1_val_2 = fields[14].GetUInt32(); + ConditionType cond_2 = (ConditionType)fields[15].GetUInt32(); + uint32 cond_2_val_1 = fields[16].GetUInt32(); + uint32 cond_2_val_2 = fields[17].GetUInt32(); + ConditionType cond_3 = (ConditionType)fields[18].GetUInt32(); + uint32 cond_3_val_1 = fields[19].GetUInt32(); + uint32 cond_3_val_2 = fields[20].GetUInt32(); + + 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); + 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); + 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); + continue; + } + + 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); + gMenuItem.action_poi_id = 0; + } + + 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); + + m_mGossipMenuItemsMap.insert(GossipMenuItemsMap::value_type(gMenuItem.menu_id, gMenuItem)); + + ++count; + + } + while(result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString(">> Loaded %u gossip_menu_items 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 e4c90aadb..dbb9bed72 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -216,6 +216,38 @@ struct PointOfInterest std::string icon_name; }; +struct GossipMenuItems +{ + uint32 menu_id; + uint32 id; + uint8 option_icon; + std::string option_text; + uint32 option_id; + uint32 npc_option_npcflag; + uint32 action_menu_id; + uint32 action_poi_id; + uint32 action_script_id; + bool box_coded; + uint32 box_money; + std::string box_text; + uint16 cond_1; + uint16 cond_2; + uint16 cond_3; +}; + +struct GossipMenus +{ + uint32 entry; + uint32 text_id; + uint16 cond_1; + uint16 cond_2; +}; + +typedef std::multimap GossipMenusMap; +typedef std::pair GossipMenusMapBounds; +typedef std::multimap GossipMenuItemsMap; +typedef std::pair GossipMenuItemsMapBounds; + #define WEATHER_SEASONS 4 struct WeatherSeasonChances { @@ -275,7 +307,6 @@ struct PlayerCondition // NPC gossip text id typedef UNORDERED_MAP CacheNpcTextIdMap; -typedef std::list CacheNpcOptionList; typedef UNORDERED_MAP CacheVendorItemMap; typedef UNORDERED_MAP CacheTrainerSpellMap; @@ -557,8 +588,11 @@ class ObjectMgr void LoadWeatherZoneChances(); void LoadGameTele(); - void LoadNpcOptions(); void LoadNpcTextId(); + + void LoadGossipMenu(); + void LoadGossipMenuItems(); + void LoadVendors(); void LoadTrainerSpell(); @@ -751,8 +785,6 @@ class ObjectMgr bool AddGameTele(GameTele& data); bool DeleteGameTele(const std::string& name); - CacheNpcOptionList const& GetNpcOptions() const { return m_mCacheNpcOptionList; } - uint32 GetNpcGossip(uint32 entry) const { CacheNpcTextIdMap::const_iterator iter = m_mCacheNpcTextIdMap.find(entry); @@ -800,6 +832,16 @@ class ObjectMgr return ItemRequiredTargetMapBounds(m_ItemRequiredTarget.lower_bound(uiItemEntry),m_ItemRequiredTarget.upper_bound(uiItemEntry)); } + GossipMenusMapBounds GetGossipMenusMapBounds(uint32 uiMenuId) const + { + return GossipMenusMapBounds(m_mGossipMenusMap.lower_bound(uiMenuId),m_mGossipMenusMap.upper_bound(uiMenuId)); + } + + GossipMenuItemsMapBounds GetGossipMenuItemsMapBounds(uint32 uiMenuId) const + { + return GossipMenuItemsMapBounds(m_mGossipMenuItemsMap.lower_bound(uiMenuId),m_mGossipMenuItemsMap.upper_bound(uiMenuId)); + } + protected: // first free id for selected id type @@ -841,7 +883,9 @@ class ObjectMgr RepOnKillMap mRepOnKill; - PointOfInterestMap mPointsOfInterest; + GossipMenusMap m_mGossipMenusMap; + GossipMenuItemsMap m_mGossipMenuItemsMap; + PointOfInterestMap mPointsOfInterest; WeatherZoneMap mWeatherZoneMap; @@ -914,7 +958,6 @@ class ObjectMgr typedef std::vector ConditionStore; ConditionStore mConditions; - CacheNpcOptionList m_mCacheNpcOptionList; CacheNpcTextIdMap m_mCacheNpcTextIdMap; CacheVendorItemMap m_mCacheVendorItemMap; CacheTrainerSpellMap m_mCacheTrainerSpellMap; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 354272a51..4d34ff7f4 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12179,126 +12179,148 @@ void Player::SendNewItem(Item *item, uint32 count, bool received, bool created, /*** GOSSIP SYSTEM ***/ /*********************************************************/ -void Player::PrepareGossipMenu(WorldObject *pSource, uint32 gossipid) +void Player::PrepareGossipMenu(WorldObject *pSource, uint32 menuId) { PlayerMenu* pMenu = PlayerTalkClass; pMenu->ClearMenus(); - if (pSource->GetTypeId() != TYPEID_UNIT) - return; + pMenu->GetGossipMenu().SetMenuId(menuId); - Creature *pCreature = (Creature*)pSource; + GossipMenuItemsMapBounds pMenuItemBounds = sObjectMgr.GetGossipMenuItemsMapBounds(menuId); - // lazy loading single time at use - pCreature->LoadGossipOptions(); - - GossipOptionList &iOptList = pCreature->GetGossipOptionList(); - - for(GossipOptionList::iterator i = iOptList.begin( ); i != iOptList.end( ); ++i) + for(GossipMenuItemsMap::const_iterator itr = pMenuItemBounds.first; itr != pMenuItemBounds.second; ++itr) { - GossipOption* gso = &*i; + bool bCanTalk = true; - if (gso->GossipId == gossipid) + if (itr->second.cond_1 && !sObjectMgr.IsPlayerMeetToCondition(this, itr->second.cond_1)) + continue; + + if (itr->second.cond_2 && !sObjectMgr.IsPlayerMeetToCondition(this, itr->second.cond_2)) + continue; + + if (itr->second.cond_3 && !sObjectMgr.IsPlayerMeetToCondition(this, itr->second.cond_3)) + continue; + + if (pSource->GetTypeId() == TYPEID_UNIT) { - bool cantalking = true; + Creature *pCreature = (Creature*)pSource; - if (gso->Id == 1) + uint32 npcflags = pCreature->GetUInt32Value(UNIT_NPC_FLAGS); + + if (!(itr->second.npc_option_npcflag & npcflags)) + continue; + + switch(itr->second.option_id) { - uint32 textid = GetGossipTextId(pSource); - - GossipText const* gossiptext = sObjectMgr.GetGossipText(textid); - - if (!gossiptext) - cantalking = false; - } - else - { - switch(gso->Action) + case GOSSIP_OPTION_QUESTGIVER: + PrepareQuestMenu(pSource->GetGUID()); + bCanTalk = false; + break; + case GOSSIP_OPTION_ARMORER: + bCanTalk = false; // added in special mode + break; + case GOSSIP_OPTION_SPIRITHEALER: + if (!isDead()) + bCanTalk = false; + break; + case GOSSIP_OPTION_VENDOR: { - case GOSSIP_OPTION_QUESTGIVER: + VendorItemData const* vItems = pCreature->GetVendorItems(); + if (!vItems || vItems->Empty()) + { + sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.", pCreature->GetGUIDLow(), pCreature->GetEntry()); + bCanTalk = false; + } + break; + } + case GOSSIP_OPTION_TRAINER: + if (!pCreature->isCanTrainingOf(this, false)) + bCanTalk = false; + break; + case GOSSIP_OPTION_UNLEARNTALENTS: + if (!pCreature->isCanTrainingAndResetTalentsOf(this)) + bCanTalk = false; + break; + case GOSSIP_OPTION_UNLEARNPETSKILLS: + if (!GetPet() || GetPet()->getPetType() != HUNTER_PET || GetPet()->m_spells.size() <= 1 || pCreature->GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS || pCreature->GetCreatureInfo()->trainer_class != CLASS_HUNTER) + bCanTalk = false; + break; + case GOSSIP_OPTION_TAXIVENDOR: + if (GetSession()->SendLearnNewTaxiNode(pCreature)) + return; + break; + case GOSSIP_OPTION_BATTLEFIELD: + if (!pCreature->isCanInteractWithBattleMaster(this, false)) + bCanTalk = false; + break; + case GOSSIP_OPTION_STABLEPET: + if (!GetPet() || GetPet()->getPetType() != HUNTER_PET) + bCanTalk = false; + break; + case GOSSIP_OPTION_GOSSIP: + case GOSSIP_OPTION_SPIRITGUIDE: + case GOSSIP_OPTION_INNKEEPER: + case GOSSIP_OPTION_BANKER: + case GOSSIP_OPTION_PETITIONER: + case GOSSIP_OPTION_TABARDDESIGNER: + case GOSSIP_OPTION_AUCTIONEER: + break; // no checks + default: + sLog.outErrorDb("Creature entry %u have unknown gossip option %u for menu %u", pCreature->GetEntry(), itr->second.option_id, itr->second.menu_id); + bCanTalk = false; + break; + } + } + else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT) + { + GameObject *pGo = (GameObject*)pSource; + + switch(itr->second.option_id) + { + case GOSSIP_OPTION_QUESTGIVER: + if (pGo->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) PrepareQuestMenu(pSource->GetGUID()); - //if (pm->GetQuestMenu()->MenuItemCount() == 0) - cantalking = false; - //pm->GetQuestMenu()->ClearMenu(); - break; - case GOSSIP_OPTION_ARMORER: - cantalking = false; // added in special mode - break; - case GOSSIP_OPTION_SPIRITHEALER: - if (!isDead()) - cantalking = false; - break; - case GOSSIP_OPTION_VENDOR: - { - VendorItemData const* vItems = pCreature->GetVendorItems(); - if (!vItems || vItems->Empty()) - { - sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.", - pCreature->GetGUIDLow(), pCreature->GetEntry()); - cantalking = false; - } - break; - } - case GOSSIP_OPTION_TRAINER: - if (!pCreature->isCanTrainingOf(this, false)) - cantalking = false; - break; - case GOSSIP_OPTION_UNLEARNTALENTS: - if (!pCreature->isCanTrainingAndResetTalentsOf(this)) - cantalking = false; - break; - case GOSSIP_OPTION_UNLEARNPETSKILLS: - if(!GetPet() || GetPet()->getPetType() != HUNTER_PET || GetPet()->m_spells.size() <= 1 || pCreature->GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS || pCreature->GetCreatureInfo()->trainer_class != CLASS_HUNTER) - cantalking = false; - break; - case GOSSIP_OPTION_TAXIVENDOR: - if (GetSession()->SendLearnNewTaxiNode(pCreature)) - return; - break; - case GOSSIP_OPTION_BATTLEFIELD: - if (!pCreature->isCanInteractWithBattleMaster(this, false)) - cantalking = false; - break; - case GOSSIP_OPTION_SPIRITGUIDE: - case GOSSIP_OPTION_INNKEEPER: - case GOSSIP_OPTION_BANKER: - case GOSSIP_OPTION_PETITIONER: - case GOSSIP_OPTION_STABLEPET: - case GOSSIP_OPTION_TABARDDESIGNER: - case GOSSIP_OPTION_AUCTIONEER: - break; // no checks - default: - sLog.outErrorDb("Creature %u (entry: %u) have unknown gossip option %u", pCreature->GetDBTableGUIDLow(), pCreature->GetEntry(), gso->Action); - break; - } + bCanTalk = false; + break; + case GOSSIP_OPTION_GOSSIP: + if (pGo->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER || pGo->GetGoType() != GAMEOBJECT_TYPE_GOOBER) + bCanTalk = false; + break; + default: + sLog.outErrorDb("GameObject entry %u are using invalid gossip option %u for menu %u", pGo->GetEntry(), itr->second.option_id, itr->second.menu_id); + bCanTalk = false; + break; } + } - //note for future dev: should have database fields for BoxMessage & BoxMoney - if (!gso->OptionText.empty() && cantalking) + if (bCanTalk) + { + std::string strOptionText = itr->second.option_text; + std::string strBoxText = itr->second.box_text; + + int loc_idx = GetSession()->GetSessionDbLocaleIndex(); + + if (loc_idx >= 0) { - std::string OptionText = gso->OptionText; - std::string BoxText = gso->BoxText; - int loc_idx = GetSession()->GetSessionDbLocaleIndex(); + uint32 idxEntry = MAKE_PAIR32(menuId, itr->second.id); - if (loc_idx >= 0) + if (NpcOptionLocale const *no = sObjectMgr.GetNpcOptionLocale(idxEntry)) { - if (NpcOptionLocale const *no = sObjectMgr.GetNpcOptionLocale(gso->Id)) - { - if (no->OptionText.size() > (size_t)loc_idx && !no->OptionText[loc_idx].empty()) - OptionText = no->OptionText[loc_idx]; + if (no->OptionText.size() > (size_t)loc_idx && !no->OptionText[loc_idx].empty()) + strOptionText = no->OptionText[loc_idx]; - if (no->BoxText.size() > (size_t)loc_idx && !no->BoxText[loc_idx].empty()) - BoxText = no->BoxText[loc_idx]; - } + if (no->BoxText.size() > (size_t)loc_idx && !no->BoxText[loc_idx].empty()) + strBoxText = no->BoxText[loc_idx]; } - - pMenu->GetGossipMenu().AddMenuItem((uint8)gso->Icon,OptionText, gossipid,gso->Action,BoxText,gso->BoxMoney,gso->Coded); } + + pMenu->GetGossipMenu().AddMenuItem(itr->second.option_icon, strOptionText, 0, itr->second.option_id, strBoxText, itr->second.box_money, itr->second.box_coded); + pMenu->GetGossipMenu().AddGossipMenuItemData(itr->second.action_menu_id, itr->second.action_poi_id, itr->second.action_script_id); } } - ///some gossips aren't handled in normal way ... so we need to do it this way .. TODO: handle it in normal way ;-) - if (pMenu->Empty()) + // some gossips aren't handled in normal way ... so we need to do it this way .. TODO: handle it in normal way ;-) + /*if (pMenu->Empty()) { if (pCreature->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_TRAINER)) { @@ -12311,59 +12333,86 @@ void Player::PrepareGossipMenu(WorldObject *pSource, uint32 gossipid) // output error message if need pCreature->isCanInteractWithBattleMaster(this, true); } - } + }*/ } void Player::SendPreparedGossip(WorldObject *pSource) { - if (!pSource || pSource->GetTypeId() != TYPEID_UNIT) + if (!pSource) return; - // in case no gossip flag and quest menu not empty, open quest menu (client expect gossip menu with this flag) - if (!((Creature*)pSource)->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_GOSSIP) && !PlayerTalkClass->GetQuestMenu().Empty()) + if (pSource->GetTypeId() == TYPEID_UNIT) { - SendPreparedQuest(pSource->GetGUID()); - return; + // in case no gossip flag and quest menu not empty, open quest menu (client expect gossip menu with this flag) + if (!((Creature*)pSource)->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_GOSSIP) && !PlayerTalkClass->GetQuestMenu().Empty()) + { + SendPreparedQuest(pSource->GetGUID()); + return; + } + } + else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT) + { + // probably need to find a better way here + if (!PlayerTalkClass->GetGossipMenu().GetMenuId() && !PlayerTalkClass->GetQuestMenu().Empty()) + { + SendPreparedQuest(pSource->GetGUID()); + return; + } } // in case non empty gossip menu (that not included quests list size) show it // (quest entries from quest menu will be included in list) - PlayerTalkClass->SendGossipMenu(GetGossipTextId(pSource), pSource->GetGUID()); + + uint32 textId = GetGossipTextId(pSource); + + if (uint32 menuId = PlayerTalkClass->GetGossipMenu().GetMenuId()) + textId = GetGossipTextId(menuId); + + PlayerTalkClass->SendGossipMenu(textId, pSource->GetGUID()); } -void Player::OnGossipSelect(WorldObject* pSource, uint32 option) +void Player::OnGossipSelect(WorldObject* pSource, uint32 gossipListId, uint32 menuId) { GossipMenu& gossipmenu = PlayerTalkClass->GetGossipMenu(); - if (option >= gossipmenu.MenuItemCount()) + if (gossipListId >= gossipmenu.MenuItemCount()) return; - uint32 action = gossipmenu.GetItem(option).m_gAction; - uint32 zoneid = GetZoneId(); + // if not same, then something funky is going on + if (menuId != gossipmenu.GetMenuId()) + return; + + uint32 gossipOptionId = gossipmenu.GetItem(gossipListId).m_gOptionId; uint64 guid = pSource->GetGUID(); - GossipOption const *gossip = GetGossipOption(pSource, action); - - if (!gossip) + if (pSource->GetTypeId() == TYPEID_GAMEOBJECT) { - zoneid = 0; - gossip = GetGossipOption(pSource, action); - - if (!gossip) + if (gossipOptionId > GOSSIP_OPTION_QUESTGIVER) + { + sLog.outError("Player guid %u request invalid gossip option for GameObject entry %u", GetGUIDLow(), pSource->GetEntry()); return; + } } - switch(gossip->Action) + GossipMenuItemData pMenuData = gossipmenu.GetItemData(gossipListId); + + switch(gossipOptionId) { case GOSSIP_OPTION_GOSSIP: { - uint32 textid = GetGossipTextId(action, zoneid); + if (pMenuData.m_gAction_menu) + { + PrepareGossipMenu(pSource, pMenuData.m_gAction_menu); + SendPreparedGossip(pSource); + } + else + { + PlayerTalkClass->CloseGossip(); + } - if (textid == 0) - textid = GetGossipTextId(pSource); + if (pMenuData.m_gAction_poi) + PlayerTalkClass->SendPointOfInterest(pMenuData.m_gAction_poi); - PlayerTalkClass->CloseGossip(); - PlayerTalkClass->SendTalking(textid); break; } case GOSSIP_OPTION_SPIRITHEALER: @@ -12414,9 +12463,7 @@ void Player::OnGossipSelect(WorldObject* pSource, uint32 option) GetSession()->SendAuctionHello(guid, ((Creature*)pSource)); break; case GOSSIP_OPTION_SPIRITGUIDE: - case GOSSIP_GUARD_SPELLTRAINER: - case GOSSIP_GUARD_SKILLTRAINER: - PrepareGossipMenu(pSource, gossip->Id); + PrepareGossipMenu(pSource); SendPreparedGossip(pSource); break; case GOSSIP_OPTION_BATTLEFIELD: @@ -12432,59 +12479,13 @@ void Player::OnGossipSelect(WorldObject* pSource, uint32 option) GetSession()->SendBattlegGroundList(guid, bgTypeId); break; } - default: - OnPoiSelect(pSource, gossip); - break; } } -void Player::OnPoiSelect(WorldObject *pSource, GossipOption const *gossip) -{ - if(gossip->GossipId==GOSSIP_GUARD_SPELLTRAINER || gossip->GossipId==GOSSIP_GUARD_SKILLTRAINER) - { - Poi_Icon icon = ICON_POI_BLANK; - //need add more case. - switch(gossip->Action) - { - case GOSSIP_GUARD_BANK: - icon=ICON_POI_SMALL_HOUSE; - break; - case GOSSIP_GUARD_RIDE: - icon=ICON_POI_RWHORSE; - break; - case GOSSIP_GUARD_GUILD: - icon=ICON_POI_BLUETOWER; - break; - default: - icon=ICON_POI_GREYTOWER; - break; - } - uint32 textid = GetGossipTextId(gossip->Action, GetZoneId()); - PlayerTalkClass->SendTalking(textid); - // std::string areaname= gossip->OptionText; - // how this could worked player->PlayerTalkClass->SendPointOfInterest( x, y, icon, 2, 15, areaname.c_str() ); - } -} - -uint32 Player::GetGossipTextId(uint32 action, uint32 zoneid) -{ - QueryResult *result= WorldDatabase.PQuery("SELECT textid FROM npc_gossip_textid WHERE action = '%u' AND zoneid ='%u'", action, zoneid ); - - if (!result) - return 0; - - Field *fields = result->Fetch(); - uint32 id = fields[0].GetUInt32(); - - delete result; - - return id; -} - uint32 Player::GetGossipTextId(WorldObject *pSource) { if (!pSource || pSource->GetTypeId() != TYPEID_UNIT || !((Creature*)pSource)->GetDBTableGUIDLow()) - return DEFAULT_GOSSIP_MESSAGE; + return 0; if (uint32 pos = sObjectMgr.GetNpcGossip(((Creature*)pSource)->GetDBTableGUIDLow())) return pos; @@ -12492,19 +12493,22 @@ uint32 Player::GetGossipTextId(WorldObject *pSource) return DEFAULT_GOSSIP_MESSAGE; } -GossipOption const* Player::GetGossipOption(WorldObject *pSource, uint32 id) const +uint32 Player::GetGossipTextId(uint32 menuId) { - if (pSource->GetTypeId() == TYPEID_UNIT) - { - GossipOptionList &iOptlist = ((Creature*)pSource)->GetGossipOptionList(); + uint32 textId = DEFAULT_GOSSIP_MESSAGE; - for(GossipOptionList::const_iterator i = iOptlist.begin( ); i != iOptlist.end( ); ++i) - { - if (i->Action == id) - return &*i; - } + if (!menuId) + return textId; + + GossipMenusMapBounds pMenuBounds = sObjectMgr.GetGossipMenusMapBounds(menuId); + + for(GossipMenusMap::const_iterator itr = pMenuBounds.first; itr != pMenuBounds.second; ++itr) + { + if (sObjectMgr.IsPlayerMeetToCondition(this, itr->second.cond_1) && sObjectMgr.IsPlayerMeetToCondition(this, itr->second.cond_2)) + textId = itr->second.text_id; } - return NULL; + + return textId; } /*********************************************************/ diff --git a/src/game/Player.h b/src/game/Player.h index 446b834c5..b7d29cc38 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1299,14 +1299,12 @@ class MANGOS_DLL_SPEC Player : public Unit /*** GOSSIP SYSTEM ***/ /*********************************************************/ - void PrepareGossipMenu(WorldObject *pSource, uint32 gossipid = 0); + void PrepareGossipMenu(WorldObject *pSource, uint32 menuId = 0); void SendPreparedGossip(WorldObject *pSource); - void OnGossipSelect(WorldObject *pSource, uint32 option); - void OnPoiSelect(WorldObject *pSource, GossipOption const *gossip); + void OnGossipSelect(WorldObject *pSource, uint32 gossipListId, uint32 menuId); - uint32 GetGossipTextId(uint32 action, uint32 zoneid); + uint32 GetGossipTextId(uint32 menuId); uint32 GetGossipTextId(WorldObject *pSource); - GossipOption const* GetGossipOption(WorldObject *pSource, uint32 id) const; /*********************************************************/ /*** QUEST SYSTEM ***/ diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 87ef0b093..4d5334ebf 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -102,7 +102,7 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data) if (Script->GossipHello(_player, pCreature)) return; - _player->PrepareGossipMenu(pCreature); + _player->PrepareGossipMenu(pCreature, pCreature->GetCreatureInfo()->GossipMenuId); _player->SendPreparedGossip(pCreature); } diff --git a/src/game/World.cpp b/src/game/World.cpp index ca23473be..d9b966c19 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1402,8 +1402,11 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Npc Text Id..." ); sObjectMgr.LoadNpcTextId(); // must be after load Creature and NpcText - sLog.outString( "Loading Npc Options..." ); - sObjectMgr.LoadNpcOptions(); + sLog.outString( "Loading Gossip menus..." ); + sObjectMgr.LoadGossipMenu(); + + sLog.outString( "Loading Gossip menu options..." ); + sObjectMgr.LoadGossipMenuItems(); sLog.outString( "Loading Vendors..." ); sObjectMgr.LoadVendors(); // must be after load CreatureTemplate and ItemTemplate diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp index 0a16e71e0..513f4b51d 100644 --- a/src/shared/Database/SQLStorage.cpp +++ b/src/shared/Database/SQLStorage.cpp @@ -25,8 +25,8 @@ extern DatabasePostgre WorldDatabase; extern DatabaseMysql WorldDatabase; #endif -const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis"; -const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii"; +const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis"; +const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii"; const char CreatureDataAddonInfofmt[]="iiiiiis"; const char CreatureModelfmt[]="iffbi"; const char CreatureInfoAddonInfofmt[]="iiiiiis"; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e7f5055be..81b2993c1 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 "8922" + #define REVISION_NR "8923" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index e341811f7..a325173b9 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_8917_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_8923_01_mangos_gossip" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__