diff options
-rw-r--r-- | sql/base/characters_database.sql | 50 | ||||
-rw-r--r-- | sql/updates/characters/master/2017_08_20_00_characters.sql | 21 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 8 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.h | 8 | ||||
-rw-r--r-- | src/server/game/Achievements/AchievementMgr.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Achievements/CriteriaHandler.cpp | 28 | ||||
-rw-r--r-- | src/server/game/Achievements/CriteriaHandler.h | 17 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 48 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 5 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Quests/QuestDef.h | 6 | ||||
-rw-r--r-- | src/server/game/Quests/QuestObjectiveCriteriaMgr.cpp | 320 | ||||
-rw-r--r-- | src/server/game/Quests/QuestObjectiveCriteriaMgr.h | 64 |
13 files changed, 573 insertions, 14 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 6baffea518e..99558dfd839 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1186,6 +1186,54 @@ LOCK TABLES `character_queststatus_objectives` WRITE; UNLOCK TABLES; -- +-- Table structure for table `character_queststatus_objectives_criteria` +-- + +DROP TABLE IF EXISTS `character_queststatus_objectives_criteria`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `character_queststatus_objectives_criteria` ( + `guid` bigint(20) unsigned NOT NULL, + `questObjectiveId` int(10) unsigned NOT NULL, + PRIMARY KEY (`guid`,`questObjectiveId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `character_queststatus_objectives_criteria` +-- + +LOCK TABLES `character_queststatus_objectives_criteria` WRITE; +/*!40000 ALTER TABLE `character_queststatus_objectives_criteria` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_queststatus_objectives_criteria` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `character_queststatus_objectives_criteria_progress` +-- + +DROP TABLE IF EXISTS `character_queststatus_objectives_criteria_progress`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `character_queststatus_objectives_criteria_progress` ( + `guid` bigint(20) unsigned NOT NULL, + `criteriaId` int(10) unsigned NOT NULL, + `counter` bigint(20) unsigned NOT NULL, + `date` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`guid`,`criteriaId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `character_queststatus_objectives_criteria_progress` +-- + +LOCK TABLES `character_queststatus_objectives_criteria_progress` WRITE; +/*!40000 ALTER TABLE `character_queststatus_objectives_criteria_progress` DISABLE KEYS */; +/*!40000 ALTER TABLE `character_queststatus_objectives_criteria_progress` ENABLE KEYS */; +UNLOCK TABLES; + +-- -- Table structure for table `character_queststatus_rewarded` -- @@ -3260,7 +3308,7 @@ CREATE TABLE `updates` ( LOCK TABLES `updates` WRITE; /*!40000 ALTER TABLE `updates` DISABLE KEYS */; -INSERT INTO `updates` VALUES ('2014_10_20_00_characters.sql','A5882DA0979CF4DAE33DA011EBAA006C24BE7230','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_00_characters.sql','E2AC4758133EE19B7F08464A445802154D1261C8','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_01_characters.sql','20029E6323D9773B32C34D84FFED1711CC60F09F','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_02_characters.sql','8A7A16886EE71E7ACDDB3DDA6D0ECAC2FD2FDCA8','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_24_00_characters.sql','D008FE81AE844FCA686439D6ECC5108FB0DD1EB9','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_25_00_characters.sql','A39C7BE46686B54776BDAB9D7A882D91EDEC51A4','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_26_00_characters.sql','C787954CC35FE34B4101FDE6527F14C027F4947C','ARCHIVED','2015-03-21 15:55:55',0),('2014_11_12_00_characters.sql','B160BB2313F1BD5F3B076A5A9279DC10D4796E34','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_23_00_characters.sql','3D9D648B2387B357F4BD090B33F80682F7924882','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_28_00_characters.sql','5362922FF4483A336311D73082A5727309CD9219','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_31_00_characters.sql','498DDF2DD936CF156D74A8208DC93DCE9FCAB5AA','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_02_00_characters.sql','E5940BE836F253982E07930120422E598D08BDE1','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_10_00_characters.sql','30796056C8623699B2FE1BF626A19D38262E9284','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_16_00_characters.sql','96642760A54C8D799AAFE438049A63AA521656F2','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_27_00_characters.sql','EB710E3EB9F2CAFD84AB62CDC84E898403A80A4F','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_13_00_characters.sql','405BEB4ED207DC6076442A37EE2AFB1F21E274A0','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_13_01_characters.sql','35F582D4F33BF55D1685A1BA89273ED895FD09C5','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_17_00_characters.sql','8D21FC5A55BF8B55D6DCDCE5F02CF2B640230E94','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_10_00_characters.sql','E565B89B145C340067742DFF2DEF1B74F5F1BD4E','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_00_characters.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_01_characters.sql','20BD68468C57FCF7E665B4DA185DCD52FACE8B3F','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_02_characters.sql','0296995DCD3676BA9AE6024CA7C91C5F39D927A3','ARCHIVED','2015-03-21 15:56:46',0),('2015_03_29_00_characters.sql','95D6A46BB746A8BD3EE3FE2086DF1A07F7C33B92','ARCHIVED','2015-05-02 15:43:06',0),('2015_04_21_00_characters.sql','F2032B9BF4EDA7EDE5065554724ED392FD91657D','ARCHIVED','2015-05-02 15:43:06',0),('2015_04_28_00_characters.sql','949F62DB3A3461D420A1230ECF7A6A3ED6435703','ARCHIVED','2015-05-02 15:43:06',0),('2015_05_08_00_characters.sql','0F14B7821618D1C872625B6EDDAA9A667B211167','ARCHIVED','2015-07-10 19:32:17',0),('2015_05_22_00_characters.sql','65B82152413FAB23BE413656E59A486A74447FF7','ARCHIVED','2015-07-10 19:32:17',0),('2015_07_08_00_characters.sql','DAB25360ACB5244C8F8E6214CF6BD97160588A5B','ARCHIVED','2015-07-10 19:32:17',0),('2015_07_11_00_characters.sql','B421B6C0E57BD0FD587071358863D9DABF4BA849','ARCHIVED','2015-07-13 21:50:02',0),('2015_07_12_00_characters.sql','E98E7FD61EF6426E7EDE8ED9AD8C15D8D7132589','ARCHIVED','2015-07-13 21:50:02',0),('2015_07_28_00_characters.sql','0711BC3A658D189EF71B0CB68DCFF2E9B781C4A0','ARCHIVED','2015-07-29 16:23:56',0),('2015_08_08_00_characters.sql','EA12BB2DC24FAF2300A96D0888A45BBEA158D5DC','ARCHIVED','2015-08-08 16:34:07',0),('2015_08_12_00_characters.sql','4FD7F89FE5DA51D4E0C33E520719986AA3EBD31B','ARCHIVED','2015-08-12 12:35:20',0),('2015_09_05_00_characters.sql','4C22BB29365BE4B6B95E64DAD84B63CA002304EA','ARCHIVED','2015-09-05 12:35:20',0),('2015_09_09_00_characters.sql','AFC32E693BC17CFD9A17919FE5317B8FE337ACAD','ARCHIVED','2015-09-09 12:35:20',0),('2015_09_10_00_characters.sql','4555A7F35C107E54C13D74D20F141039ED42943E','ARCHIVED','2015-09-10 22:50:42',0),('2015_10_16_00_characters.sql','E3A3FFF0CB42F04A8DCF0CE4362143C16E2083AF','ARCHIVED','2015-10-15 21:54:11',0),('2015_11_06_00_characters_2015_10_12_00.sql','D6F9927BDED72AD0A81D6EC2C6500CBC34A39FA2','ARCHIVED','2015-11-06 23:43:27',0),('2015_11_08_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2015-11-08 00:51:45',15),('2015_11_23_00_characters.sql','9FC828E9E48E8E2E9B99A5A0073D6614C5BFC6B5','ARCHIVED','2015-11-22 23:27:34',0),('2016_01_05_00_characters.sql','0EAD24977F40DE2476B4567DA2B477867CC0DA1A','ARCHIVED','2016-01-04 23:07:40',0),('2016_04_05_00_characters_2016_02_10_00_characters.sql','F1B4DA202819CABC7319A4470A2D224A34609E97','ARCHIVED','2016-04-05 20:34:41',0),('2016_04_11_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 02:24:14',30),('2016_04_11_01_characters.sql','CA90F6D99C1EEA7B25BD58BC8368A8D78234BBEF','ARCHIVED','2016-04-11 18:14:18',0),('2016_05_07_00_characters.sql','D1DB5557B21A552C935564D829B4E98B98149077','ARCHIVED','2016-05-07 00:00:00',0),('2016_05_26_00_characters.sql','4179ADC32B96FD8D7D4CF5509A470B1ACE00BE85','ARCHIVED','2016-05-26 17:06:16',0),('2016_07_16_00_characters.sql','EF267FCB92B383FFB33C700508EAF3FBC1F8AC23','ARCHIVED','2016-07-16 14:45:12',0),('2016_07_19_00_characters.sql','AA2C516FA81B451071EA82F58F447E9D13E5D1BD','ARCHIVED','2016-07-19 14:36:25',0),('2016_07_19_01_characters.sql','E9AF46AF4C7CC2E2779E44254AEEDF880D020166','ARCHIVED','2016-07-19 14:36:25',0),('2016_07_19_02_characters.sql','5B1B334449996F3639C9226F587129E03DC4BF6D','ARCHIVED','2016-07-19 14:36:26',0),('2016_07_19_03_characters.sql','7787C8A67D720492FED4BF60ADB22D3CDE1C536D','ARCHIVED','2016-07-19 14:36:26',0),('2016_07_19_04_characters.sql','6D4B536094367AC9EF7CDFF41A4F96EB00B25EE5','ARCHIVED','2016-07-19 14:36:26',0),('2016_07_19_05_characters.sql','12639268DC5F78CE900B59D5C646B10D70842928','ARCHIVED','2016-07-19 14:36:27',0),('2016_07_19_06_characters.sql','9F5A4B533E6BFBAA718DE5160E1FDCB8471A88BF','ARCHIVED','2016-07-19 14:36:28',0),('2016_07_19_07_characters.sql','1E8273FFD4340CBD7BB71D2406E23E9EF7230CFA','ARCHIVED','2016-07-19 14:36:29',0),('2016_07_19_08_characters.sql','FB41FD2F8A7114FEE154021A9D47488C4B12E2A9','ARCHIVED','2016-07-19 14:36:29',0),('2016_08_15_00_characters.sql','BF0B5F453384210CD77C54E262A19B888AAA4095','ARCHIVED','2016-08-14 18:14:32',0),('2016_08_25_00_characters.sql','4AD506C3FCE54238EF452AC07EC562BD41A9D50C','ARCHIVED','2016-08-25 22:54:11',0),('2016_10_17_00_characters.sql','A0EF594CD73690D46A46031137DB0E895F079235','ARCHIVED','2016-10-16 16:33:05',25),('2016_10_25_00_characters.sql','CC894484561CE138C10B69D34F7831CEDFAF496B','ARCHIVED','2016-10-25 17:19:35',0),('2016_11_06_00_characters.sql','C7EC8B65C1BE7722C53BAB79C52C1549054178C0','ARCHIVED','2016-11-06 23:05:44',0),('2016_12_09_00_characters.sql','2A68E4187CE7F7294CBC3804AC39F48B2727E64E','ARCHIVED','2016-12-09 18:38:46',0),('2016_12_26_00_characters.sql','D265DE655DDBFC13E2FA1EB021A435A21189B6E4','ARCHIVED','2016-12-26 18:45:15',0),('2017_01_22_00_characters.sql','62B08B5FB1DA7B207C74DC000C42517A2D6F6BCC','ARCHIVED','2017-01-22 02:06:31',0),('2017_01_29_00_characters.sql','E7475DCC13A0910FF23BF0EFB731629950A73A0D','ARCHIVED','2017-01-29 15:00:00',0),('2017_02_26_00_characters_2016_09_13_00_characters.sql','2EF7AD507D097ABC74FF1E98A65BEC03B12E51C6','ARCHIVED','2017-02-26 19:57:47',0),('2017_04_15_00_characters.sql','F118BA33CD7DDF2EE5673C6749C2965EFFF53C23','ARCHIVED','2017-04-15 12:10:50',0),('2017_04_19_00_characters.sql','5A36FD9015ED024BC085F995F72DC81B47CD1093','RELEASED','2017-04-18 23:16:18',30),('2017_05_08_00_characters.sql','86B5603EEBE1DE0EA56DBB264257967CFE583F46','RELEASED','2017-05-08 23:54:40',0),('2017_05_14_00_characters.sql','3452261F366BFE76BB59C0AAA674FA1513042899','RELEASED','2017-05-14 17:29:04',0),('2017_05_24_00_characters.sql','02701BF57589CD41456A748AEF425CBB2D3E6AD7','RELEASED','2017-05-24 22:00:00',0),('2017_06_04_00_characters.sql','BC80D2B7515CC6E01701070D2DA466727F36DB5E','RELEASED','2017-06-04 14:43:26',0); +INSERT INTO `updates` VALUES ('2014_10_20_00_characters.sql','A5882DA0979CF4DAE33DA011EBAA006C24BE7230','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_00_characters.sql','E2AC4758133EE19B7F08464A445802154D1261C8','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_01_characters.sql','20029E6323D9773B32C34D84FFED1711CC60F09F','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_23_02_characters.sql','8A7A16886EE71E7ACDDB3DDA6D0ECAC2FD2FDCA8','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_24_00_characters.sql','D008FE81AE844FCA686439D6ECC5108FB0DD1EB9','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_25_00_characters.sql','A39C7BE46686B54776BDAB9D7A882D91EDEC51A4','ARCHIVED','2015-03-21 15:55:55',0),('2014_10_26_00_characters.sql','C787954CC35FE34B4101FDE6527F14C027F4947C','ARCHIVED','2015-03-21 15:55:55',0),('2014_11_12_00_characters.sql','B160BB2313F1BD5F3B076A5A9279DC10D4796E34','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_23_00_characters.sql','3D9D648B2387B357F4BD090B33F80682F7924882','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_28_00_characters.sql','5362922FF4483A336311D73082A5727309CD9219','ARCHIVED','2015-03-21 15:55:55',0),('2014_12_31_00_characters.sql','498DDF2DD936CF156D74A8208DC93DCE9FCAB5AA','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_02_00_characters.sql','E5940BE836F253982E07930120422E598D08BDE1','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_10_00_characters.sql','30796056C8623699B2FE1BF626A19D38262E9284','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_16_00_characters.sql','96642760A54C8D799AAFE438049A63AA521656F2','ARCHIVED','2015-03-21 15:55:55',0),('2015_01_27_00_characters.sql','EB710E3EB9F2CAFD84AB62CDC84E898403A80A4F','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_13_00_characters.sql','405BEB4ED207DC6076442A37EE2AFB1F21E274A0','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_13_01_characters.sql','35F582D4F33BF55D1685A1BA89273ED895FD09C5','ARCHIVED','2015-03-21 15:55:55',0),('2015_02_17_00_characters.sql','8D21FC5A55BF8B55D6DCDCE5F02CF2B640230E94','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_10_00_characters.sql','E565B89B145C340067742DFF2DEF1B74F5F1BD4E','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_00_characters.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_01_characters.sql','20BD68468C57FCF7E665B4DA185DCD52FACE8B3F','ARCHIVED','2015-03-21 15:55:55',0),('2015_03_20_02_characters.sql','0296995DCD3676BA9AE6024CA7C91C5F39D927A3','ARCHIVED','2015-03-21 15:56:46',0),('2015_03_29_00_characters.sql','95D6A46BB746A8BD3EE3FE2086DF1A07F7C33B92','ARCHIVED','2015-05-02 15:43:06',0),('2015_04_21_00_characters.sql','F2032B9BF4EDA7EDE5065554724ED392FD91657D','ARCHIVED','2015-05-02 15:43:06',0),('2015_04_28_00_characters.sql','949F62DB3A3461D420A1230ECF7A6A3ED6435703','ARCHIVED','2015-05-02 15:43:06',0),('2015_05_08_00_characters.sql','0F14B7821618D1C872625B6EDDAA9A667B211167','ARCHIVED','2015-07-10 19:32:17',0),('2015_05_22_00_characters.sql','65B82152413FAB23BE413656E59A486A74447FF7','ARCHIVED','2015-07-10 19:32:17',0),('2015_07_08_00_characters.sql','DAB25360ACB5244C8F8E6214CF6BD97160588A5B','ARCHIVED','2015-07-10 19:32:17',0),('2015_07_11_00_characters.sql','B421B6C0E57BD0FD587071358863D9DABF4BA849','ARCHIVED','2015-07-13 21:50:02',0),('2015_07_12_00_characters.sql','E98E7FD61EF6426E7EDE8ED9AD8C15D8D7132589','ARCHIVED','2015-07-13 21:50:02',0),('2015_07_28_00_characters.sql','0711BC3A658D189EF71B0CB68DCFF2E9B781C4A0','ARCHIVED','2015-07-29 16:23:56',0),('2015_08_08_00_characters.sql','EA12BB2DC24FAF2300A96D0888A45BBEA158D5DC','ARCHIVED','2015-08-08 16:34:07',0),('2015_08_12_00_characters.sql','4FD7F89FE5DA51D4E0C33E520719986AA3EBD31B','ARCHIVED','2015-08-12 12:35:20',0),('2015_09_05_00_characters.sql','4C22BB29365BE4B6B95E64DAD84B63CA002304EA','ARCHIVED','2015-09-05 12:35:20',0),('2015_09_09_00_characters.sql','AFC32E693BC17CFD9A17919FE5317B8FE337ACAD','ARCHIVED','2015-09-09 12:35:20',0),('2015_09_10_00_characters.sql','4555A7F35C107E54C13D74D20F141039ED42943E','ARCHIVED','2015-09-10 22:50:42',0),('2015_10_16_00_characters.sql','E3A3FFF0CB42F04A8DCF0CE4362143C16E2083AF','ARCHIVED','2015-10-15 21:54:11',0),('2015_11_06_00_characters_2015_10_12_00.sql','D6F9927BDED72AD0A81D6EC2C6500CBC34A39FA2','ARCHIVED','2015-11-06 23:43:27',0),('2015_11_08_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2015-11-08 00:51:45',15),('2015_11_23_00_characters.sql','9FC828E9E48E8E2E9B99A5A0073D6614C5BFC6B5','ARCHIVED','2015-11-22 23:27:34',0),('2016_01_05_00_characters.sql','0EAD24977F40DE2476B4567DA2B477867CC0DA1A','ARCHIVED','2016-01-04 23:07:40',0),('2016_04_05_00_characters_2016_02_10_00_characters.sql','F1B4DA202819CABC7319A4470A2D224A34609E97','ARCHIVED','2016-04-05 20:34:41',0),('2016_04_11_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 02:24:14',30),('2016_04_11_01_characters.sql','CA90F6D99C1EEA7B25BD58BC8368A8D78234BBEF','ARCHIVED','2016-04-11 18:14:18',0),('2016_05_07_00_characters.sql','D1DB5557B21A552C935564D829B4E98B98149077','ARCHIVED','2016-05-07 00:00:00',0),('2016_05_26_00_characters.sql','4179ADC32B96FD8D7D4CF5509A470B1ACE00BE85','ARCHIVED','2016-05-26 17:06:16',0),('2016_07_16_00_characters.sql','EF267FCB92B383FFB33C700508EAF3FBC1F8AC23','ARCHIVED','2016-07-16 14:45:12',0),('2016_07_19_00_characters.sql','AA2C516FA81B451071EA82F58F447E9D13E5D1BD','ARCHIVED','2016-07-19 14:36:25',0),('2016_07_19_01_characters.sql','E9AF46AF4C7CC2E2779E44254AEEDF880D020166','ARCHIVED','2016-07-19 14:36:25',0),('2016_07_19_02_characters.sql','5B1B334449996F3639C9226F587129E03DC4BF6D','ARCHIVED','2016-07-19 14:36:26',0),('2016_07_19_03_characters.sql','7787C8A67D720492FED4BF60ADB22D3CDE1C536D','ARCHIVED','2016-07-19 14:36:26',0),('2016_07_19_04_characters.sql','6D4B536094367AC9EF7CDFF41A4F96EB00B25EE5','ARCHIVED','2016-07-19 14:36:26',0),('2016_07_19_05_characters.sql','12639268DC5F78CE900B59D5C646B10D70842928','ARCHIVED','2016-07-19 14:36:27',0),('2016_07_19_06_characters.sql','9F5A4B533E6BFBAA718DE5160E1FDCB8471A88BF','ARCHIVED','2016-07-19 14:36:28',0),('2016_07_19_07_characters.sql','1E8273FFD4340CBD7BB71D2406E23E9EF7230CFA','ARCHIVED','2016-07-19 14:36:29',0),('2016_07_19_08_characters.sql','FB41FD2F8A7114FEE154021A9D47488C4B12E2A9','ARCHIVED','2016-07-19 14:36:29',0),('2016_08_15_00_characters.sql','BF0B5F453384210CD77C54E262A19B888AAA4095','ARCHIVED','2016-08-14 18:14:32',0),('2016_08_25_00_characters.sql','4AD506C3FCE54238EF452AC07EC562BD41A9D50C','ARCHIVED','2016-08-25 22:54:11',0),('2016_10_17_00_characters.sql','A0EF594CD73690D46A46031137DB0E895F079235','ARCHIVED','2016-10-16 16:33:05',25),('2016_10_25_00_characters.sql','CC894484561CE138C10B69D34F7831CEDFAF496B','ARCHIVED','2016-10-25 17:19:35',0),('2016_11_06_00_characters.sql','C7EC8B65C1BE7722C53BAB79C52C1549054178C0','ARCHIVED','2016-11-06 23:05:44',0),('2016_12_09_00_characters.sql','2A68E4187CE7F7294CBC3804AC39F48B2727E64E','ARCHIVED','2016-12-09 18:38:46',0),('2016_12_26_00_characters.sql','D265DE655DDBFC13E2FA1EB021A435A21189B6E4','ARCHIVED','2016-12-26 18:45:15',0),('2017_01_22_00_characters.sql','62B08B5FB1DA7B207C74DC000C42517A2D6F6BCC','ARCHIVED','2017-01-22 02:06:31',0),('2017_01_29_00_characters.sql','E7475DCC13A0910FF23BF0EFB731629950A73A0D','ARCHIVED','2017-01-29 15:00:00',0),('2017_02_26_00_characters_2016_09_13_00_characters.sql','2EF7AD507D097ABC74FF1E98A65BEC03B12E51C6','ARCHIVED','2017-02-26 19:57:47',0),('2017_04_15_00_characters.sql','F118BA33CD7DDF2EE5673C6749C2965EFFF53C23','ARCHIVED','2017-04-15 12:10:50',0),('2017_04_19_00_characters.sql','5A36FD9015ED024BC085F995F72DC81B47CD1093','RELEASED','2017-04-18 23:16:18',30),('2017_05_08_00_characters.sql','86B5603EEBE1DE0EA56DBB264257967CFE583F46','RELEASED','2017-05-08 23:54:40',0),('2017_05_14_00_characters.sql','3452261F366BFE76BB59C0AAA674FA1513042899','RELEASED','2017-05-14 17:29:04',0),('2017_05_24_00_characters.sql','02701BF57589CD41456A748AEF425CBB2D3E6AD7','RELEASED','2017-05-24 22:00:00',0),('2017_06_04_00_characters.sql','BC80D2B7515CC6E01701070D2DA466727F36DB5E','RELEASED','2017-06-04 14:43:26',0),('2017_08_20_00_characters.sql','8C5BBF6AEAA6C7DE2F40A7D3878C8187A4729F13','RELEASED','2017-08-20 17:00:00',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/characters/master/2017_08_20_00_characters.sql b/sql/updates/characters/master/2017_08_20_00_characters.sql new file mode 100644 index 00000000000..f4d354081bf --- /dev/null +++ b/sql/updates/characters/master/2017_08_20_00_characters.sql @@ -0,0 +1,21 @@ +-- +-- Table structure for table `character_queststatus_objectives_criteria` +-- +DROP TABLE IF EXISTS `character_queststatus_objectives_criteria`; +CREATE TABLE `character_queststatus_objectives_criteria` ( + `guid` bigint(20) unsigned NOT NULL, + `questObjectiveId` int(10) unsigned NOT NULL, + PRIMARY KEY (`guid`,`questObjectiveId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Table structure for table `character_queststatus_objectives_criteria_progress` +-- +DROP TABLE IF EXISTS `character_queststatus_objectives_criteria_progress`; +CREATE TABLE `character_queststatus_objectives_criteria_progress` ( + `guid` bigint(20) unsigned NOT NULL, + `criteriaId` int(10) unsigned NOT NULL, + `counter` bigint(20) unsigned NOT NULL, + `date` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`guid`,`criteriaId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 34bef1ea62a..ad4998b9543 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -94,6 +94,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHARACTER_SPELL, "SELECT spell, active, disabled FROM character_spell WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS, "SELECT quest, status, timer FROM character_queststatus WHERE guid = ? AND status <> 0", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES, "SELECT quest, objective, data FROM character_queststatus_objectives WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES_CRITERIA, "SELECT questObjectiveId FROM character_queststatus_objectives_criteria WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS, "SELECT criteriaId, counter, date FROM character_queststatus_objectives_criteria_progress WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_DAILY, "SELECT quest, time FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_WEEKLY, "SELECT quest FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC); @@ -549,6 +551,9 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_UPD_CHAR_TAXIMASK, "UPDATE characters SET taximask = ? WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS, "DELETE FROM character_queststatus WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES, "DELETE FROM character_queststatus_objectives WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA, "DELETE FROM character_queststatus_objectives_criteria WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS, "DELETE FROM character_queststatus_objectives_criteria_progress WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS_BY_CRITERIA, "DELETE FROM character_queststatus_objectives_criteria_progress WHERE guid = ? AND criteriaId = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_SOCIAL_BY_GUID, "DELETE FROM character_social WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_SOCIAL_BY_FRIEND, "DELETE FROM character_social WHERE friend = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT, "DELETE FROM character_achievement WHERE achievement = ? AND guid = ?", CONNECTION_ASYNC); @@ -596,11 +601,14 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_BY_QUEST, "DELETE FROM character_queststatus WHERE guid = ? AND quest = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_REP_CHAR_QUESTSTATUS_OBJECTIVES, "REPLACE INTO character_queststatus_objectives (guid, quest, objective, data) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_BY_QUEST, "DELETE FROM character_queststatus_objectives WHERE guid = ? AND quest = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA, "INSERT INTO character_queststatus_objectives_criteria (guid, questObjectiveId) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_INS_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS, "INSERT INTO character_queststatus_objectives_criteria_progress (guid, criteriaId, counter, date) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_QUESTSTATUS_REWARDED, "INSERT IGNORE INTO character_queststatus_rewarded (guid, quest, active) VALUES (?, ?, 1)", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, "DELETE FROM character_queststatus_rewarded WHERE guid = ? AND quest = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE, "UPDATE character_queststatus_rewarded SET quest = ? WHERE quest = ? AND guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE, "UPDATE character_queststatus_rewarded SET active = 1 WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, "UPDATE character_queststatus_rewarded SET active = 0 WHERE quest = ? AND guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_INVALID_QUEST_PROGRESS_CRITERIA, "DELETE FROM character_queststatus_objectives_criteria WHERE questObjectiveId = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHAR_SKILL_BY_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_SKILLS, "INSERT INTO character_skills (guid, skill, value, max) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index c2ea5136261..b2acafc2308 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -71,6 +71,8 @@ enum CharacterDatabaseStatements : uint32 CHAR_SEL_CHARACTER_QUESTSTATUS, CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES, + CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES_CRITERIA, + CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS, CHAR_SEL_CHARACTER_QUESTSTATUS_DAILY, CHAR_SEL_CHARACTER_QUESTSTATUS_WEEKLY, CHAR_SEL_CHARACTER_QUESTSTATUS_MONTHLY, @@ -450,6 +452,9 @@ enum CharacterDatabaseStatements : uint32 CHAR_UPD_CHAR_TAXIMASK, CHAR_DEL_CHAR_QUESTSTATUS, CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES, + CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA, + CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS, + CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS_BY_CRITERIA, CHAR_DEL_CHAR_SOCIAL_BY_GUID, CHAR_DEL_CHAR_SOCIAL_BY_FRIEND, CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT, @@ -497,11 +502,14 @@ enum CharacterDatabaseStatements : uint32 CHAR_DEL_CHAR_QUESTSTATUS_BY_QUEST, CHAR_REP_CHAR_QUESTSTATUS_OBJECTIVES, CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_BY_QUEST, + CHAR_INS_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA, + CHAR_INS_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS, CHAR_INS_CHAR_QUESTSTATUS_REWARDED, CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE, CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, + CHAR_DEL_INVALID_QUEST_PROGRESS_CRITERIA, CHAR_DEL_CHAR_SKILL_BY_SKILL, CHAR_INS_CHAR_SKILLS, CHAR_UPD_CHAR_SKILLS, diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index b4d7ad07eb6..6ab15152d75 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -272,7 +272,7 @@ void PlayerAchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, Pre TC_LOG_ERROR("criteria.achievement", "Non-existing achievement criteria %u data has been removed from the table `character_achievement_progress`.", id); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA); - stmt->setUInt32(0, uint16(id)); + stmt->setUInt32(0, id); CharacterDatabase.Execute(stmt); continue; @@ -716,7 +716,7 @@ void GuildAchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, Prep TC_LOG_ERROR("criteria.achievement", "Non-existing achievement criteria %u data removed from table `guild_achievement_progress`.", id); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA_GUILD); - stmt->setUInt32(0, uint16(id)); + stmt->setUInt32(0, id); CharacterDatabase.Execute(stmt); continue; } diff --git a/src/server/game/Achievements/CriteriaHandler.cpp b/src/server/game/Achievements/CriteriaHandler.cpp index cbf296ddb7e..f3bb97ecf4b 100644 --- a/src/server/game/Achievements/CriteriaHandler.cpp +++ b/src/server/game/Achievements/CriteriaHandler.cpp @@ -2227,19 +2227,34 @@ void CriteriaMgr::LoadCriteriaList() if (scenarioStep->CriteriaTreeID) scenarioCriteriaTreeIds[scenarioStep->CriteriaTreeID] = scenarioStep; + std::unordered_map<uint32 /*criteriaTreeID*/, QuestObjective const*> questObjectiveCriteriaTreeIds; + for (std::pair<uint32 /*questID*/, Quest const*> itr : sObjectMgr->GetQuestTemplates()) + { + for (QuestObjective const& objective : itr.second->Objectives) + { + if (objective.Type != QUEST_OBJECTIVE_CRITERIA_TREE) + continue; + + if (objective.ObjectID) + questObjectiveCriteriaTreeIds[objective.ObjectID] = &objective; + } + } + // Load criteria tree nodes for (CriteriaTreeEntry const* tree : sCriteriaTreeStore) { // Find linked achievement AchievementEntry const* achievement = GetEntry(achievementCriteriaTreeIds, tree); ScenarioStepEntry const* scenarioStep = GetEntry(scenarioCriteriaTreeIds, tree); - if (!achievement && !scenarioStep) + QuestObjective const* questObjective = GetEntry(questObjectiveCriteriaTreeIds, tree); + if (!achievement && !scenarioStep && !questObjective) continue; CriteriaTree* criteriaTree = new CriteriaTree(); criteriaTree->ID = tree->ID; criteriaTree->Achievement = achievement; criteriaTree->ScenarioStep = scenarioStep; + criteriaTree->QuestObjective = questObjective; criteriaTree->Entry = tree; _criteriaTrees[criteriaTree->Entry->ID] = criteriaTree; @@ -2274,6 +2289,7 @@ void CriteriaMgr::LoadCriteriaList() uint32 criterias = 0; uint32 guildCriterias = 0; uint32 scenarioCriterias = 0; + uint32 questObjectiveCriterias = 0; for (CriteriaEntry const* criteriaEntry : sCriteriaStore) { ASSERT(criteriaEntry->Type < CRITERIA_TYPE_TOTAL, "CRITERIA_TYPE_TOTAL must be greater than or equal to %u but is currently equal to %u", @@ -2305,6 +2321,8 @@ void CriteriaMgr::LoadCriteriaList() } else if (tree->ScenarioStep) criteria->FlagsCu |= CRITERIA_FLAG_CU_SCENARIO; + else if (tree->QuestObjective) + criteria->FlagsCu |= CRITERIA_FLAG_CU_QUEST_OBJECTIVE; } if (criteria->FlagsCu & (CRITERIA_FLAG_CU_PLAYER | CRITERIA_FLAG_CU_ACCOUNT)) @@ -2325,6 +2343,12 @@ void CriteriaMgr::LoadCriteriaList() _scenarioCriteriasByType[criteriaEntry->Type].push_back(criteria); } + if (criteria->FlagsCu & CRITERIA_FLAG_CU_QUEST_OBJECTIVE) + { + ++questObjectiveCriterias; + _questObjectiveCriteriasByType[criteriaEntry->Type].push_back(criteria); + } + if (criteriaEntry->StartTimer) _criteriasByTimedType[criteriaEntry->StartEvent].push_back(criteria); } @@ -2332,7 +2356,7 @@ void CriteriaMgr::LoadCriteriaList() for (auto& p : _criteriaTrees) const_cast<CriteriaTree*>(p.second)->Criteria = GetCriteria(p.second->Entry->CriteriaID); - TC_LOG_INFO("server.loading", ">> Loaded %u criteria, %u guild criteria and %u scenario criteria in %u ms.", criterias, guildCriterias, scenarioCriterias, GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u criteria, %u guild criteria, %u scenario criteria and %u quest objective criteria in %u ms.", criterias, guildCriterias, scenarioCriterias, questObjectiveCriterias, GetMSTimeDiffToNow(oldMSTime)); } void CriteriaMgr::LoadCriteriaData() diff --git a/src/server/game/Achievements/CriteriaHandler.h b/src/server/game/Achievements/CriteriaHandler.h index c8b96b144cd..7d14df68be1 100644 --- a/src/server/game/Achievements/CriteriaHandler.h +++ b/src/server/game/Achievements/CriteriaHandler.h @@ -34,6 +34,7 @@ struct AchievementEntry; struct CriteriaEntry; struct CriteriaTreeEntry; struct ModifierTreeEntry; +struct QuestObjective; struct ScenarioStepEntry; struct ModifierTreeNode @@ -44,10 +45,11 @@ struct ModifierTreeNode enum CriteriaFlagsCu { - CRITERIA_FLAG_CU_PLAYER = 0x1, - CRITERIA_FLAG_CU_ACCOUNT = 0x2, - CRITERIA_FLAG_CU_GUILD = 0x4, - CRITERIA_FLAG_CU_SCENARIO = 0x8 + CRITERIA_FLAG_CU_PLAYER = 0x1, + CRITERIA_FLAG_CU_ACCOUNT = 0x2, + CRITERIA_FLAG_CU_GUILD = 0x4, + CRITERIA_FLAG_CU_SCENARIO = 0x8, + CRITERIA_FLAG_CU_QUEST_OBJECTIVE = 0x10 }; struct Criteria @@ -66,6 +68,7 @@ struct CriteriaTree CriteriaTreeEntry const* Entry = nullptr; AchievementEntry const* Achievement = nullptr; ScenarioStepEntry const* ScenarioStep = nullptr; + QuestObjective const* QuestObjective = nullptr; struct Criteria const* Criteria = nullptr; std::vector<CriteriaTree const*> Children; }; @@ -331,6 +334,11 @@ public: return _scenarioCriteriasByType[type]; } + CriteriaList const& GetQuestObjectiveCriteriaByType(CriteriaTypes type) const + { + return _questObjectiveCriteriasByType[type]; + } + CriteriaTreeList const* GetCriteriaTreesByCriteria(uint32 criteriaId) const { auto itr = _criteriaTreeByCriteria.find(criteriaId); @@ -395,6 +403,7 @@ private: CriteriaList _criteriasByType[CRITERIA_TYPE_TOTAL]; CriteriaList _guildCriteriasByType[CRITERIA_TYPE_TOTAL]; CriteriaList _scenarioCriteriasByType[CRITERIA_TYPE_TOTAL]; + CriteriaList _questObjectiveCriteriasByType[CRITERIA_TYPE_TOTAL]; CriteriaList _criteriasByTimedType[CRITERIA_TIMED_TYPE_MAX]; }; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9f5a82f96ea..e2611e9c9ac 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -89,6 +89,7 @@ #include "PetPackets.h" #include "QueryHolder.h" #include "QuestDef.h" +#include "QuestObjectiveCriteriaMgr.h" #include "QuestPackets.h" #include "Realm.h" #include "ReputationMgr.h" @@ -346,6 +347,7 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this) m_achievementMgr = new PlayerAchievementMgr(this); m_reputationMgr = new ReputationMgr(this); + m_questObjectiveCriteriaMgr = Trinity::make_unique<QuestObjectiveCriteriaMgr>(this); for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i) _CUFProfiles[i] = nullptr; @@ -14745,6 +14747,11 @@ void Player::AddQuestAndCheckCompletion(Quest const* quest, Object* questGiver) { AddQuest(quest, questGiver); + for (QuestObjective const& obj : quest->GetObjectives()) + if (obj.Type == QUEST_OBJECTIVE_CRITERIA_TREE) + if (m_questObjectiveCriteriaMgr->HasCompletedObjective(&obj)) + KillCreditCriteriaTreeObjective(obj); + if (CanCompleteQuest(quest->GetQuestId())) CompleteQuest(quest->GetQuestId()); @@ -14900,9 +14907,22 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) AdjustQuestReqItemCount(quest); for (QuestObjective const& obj : quest->GetObjectives()) - if (obj.Type == QUEST_OBJECTIVE_MIN_REPUTATION || obj.Type == QUEST_OBJECTIVE_MAX_REPUTATION) - if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(obj.ObjectID)) - GetReputationMgr().SetVisible(factionEntry); + { + switch (obj.Type) + { + case QUEST_OBJECTIVE_MIN_REPUTATION: + case QUEST_OBJECTIVE_MAX_REPUTATION: + if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(obj.ObjectID)) + GetReputationMgr().SetVisible(factionEntry); + break; + case QUEST_OBJECTIVE_CRITERIA_TREE: + if (quest->HasFlagEx(QUEST_FLAGS_EX_CLEAR_PROGRESS_OF_CRITERIA_TREE_OBJECTIVES_ON_ACCEPT)) + m_questObjectiveCriteriaMgr->ResetCriteriaTree(obj.ObjectID); + break; + default: + break; + } + } uint32 qtime = 0; if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED)) @@ -16563,6 +16583,21 @@ void Player::TalkedToCreature(uint32 entry, ObjectGuid guid) } } +void Player::KillCreditCriteriaTreeObjective(QuestObjective const& questObjective) +{ + if (questObjective.Type != QUEST_OBJECTIVE_CRITERIA_TREE) + return; + + if (GetQuestStatus(questObjective.QuestID) == QUEST_STATUS_INCOMPLETE) + { + SetQuestObjectiveData(questObjective, 1); + SendQuestUpdateAddCreditSimple(questObjective); + + if (CanCompleteQuest(questObjective.QuestID)) + CompleteQuest(questObjective.QuestID); + } +} + void Player::MoneyChanged(uint64 value) { for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i) @@ -16813,6 +16848,7 @@ bool Player::IsQuestObjectiveComplete(QuestObjective const& objective) const return false; break; case QUEST_OBJECTIVE_AREATRIGGER: + case QUEST_OBJECTIVE_CRITERIA_TREE: if (!GetQuestObjectiveData(quest, objective.StorageIndex)) return false; break; @@ -17389,6 +17425,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) // load achievements before anything else to prevent multiple gains for the same achievement/criteria on every loading (as loading does call UpdateCriteria) m_achievementMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS)); + m_questObjectiveCriteriaMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES_CRITERIA), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES_CRITERIA_PROGRESS)); uint64 money = fields[8].GetUInt64(); if (money > MAX_MONEY_AMOUNT) @@ -18056,6 +18093,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) } m_achievementMgr->CheckAllAchievementCriteria(this); + m_questObjectiveCriteriaMgr->CheckAllQuestObjectiveCriteria(this); return true; } @@ -19966,6 +20004,7 @@ void Player::SaveToDB(bool create /*=false*/) _SaveSkills(trans); m_achievementMgr->SaveToDB(trans); m_reputationMgr->SaveToDB(trans); + m_questObjectiveCriteriaMgr->SaveToDB(trans); _SaveEquipmentSets(trans); GetSession()->SaveTutorialsData(trans); // changed only while character in game _SaveInstanceTimeRestrictions(trans); @@ -23448,6 +23487,7 @@ void Player::SendInitialPacketsBeforeAddToMap() SendEquipmentSetList(); m_achievementMgr->SendAllData(this); + m_questObjectiveCriteriaMgr->SendAllData(this); /// SMSG_LOGIN_SETTIMESPEED static float const TimeSpeed = 0.01666667f; @@ -25876,11 +25916,13 @@ void Player::RemoveCriteriaTimer(CriteriaTimedTypes type, uint32 entry) void Player::ResetCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, bool evenIfCriteriaComplete /* = false*/) { m_achievementMgr->ResetCriteria(type, miscValue1, miscValue2, evenIfCriteriaComplete); + m_questObjectiveCriteriaMgr->ResetCriteria(type, miscValue1, miscValue2, evenIfCriteriaComplete); } void Player::UpdateCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, Unit* unit /*= NULL*/) { m_achievementMgr->UpdateCriteria(type, miscValue1, miscValue2, miscValue3, unit, this); + m_questObjectiveCriteriaMgr->UpdateCriteria(type, miscValue1, miscValue2, miscValue3, unit, this); // Update only individual achievement criteria here, otherwise we may get multiple updates // from a single boss kill diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 414515b5e36..4f3f270fdc6 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -77,6 +77,7 @@ class PlayerAI; class PlayerAchievementMgr; class PlayerMenu; class PlayerSocial; +class QuestObjectiveCriteriaMgr; class ReputationMgr; class RestMgr; class SpellCastTargets; @@ -785,6 +786,8 @@ enum PlayerLoginQueryIndex PLAYER_LOGIN_QUERY_LOAD_SPELLS, PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS, PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES, + PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES_CRITERIA, + PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES_CRITERIA_PROGRESS, PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS, PLAYER_LOGIN_QUERY_LOAD_REPUTATION, PLAYER_LOGIN_QUERY_LOAD_INVENTORY, @@ -1415,6 +1418,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void KilledPlayerCredit(); void KillCreditGO(uint32 entry, ObjectGuid guid = ObjectGuid::Empty); void TalkedToCreature(uint32 entry, ObjectGuid guid); + void KillCreditCriteriaTreeObjective(QuestObjective const& questObjective); void MoneyChanged(uint64 value); void ReputationChanged(FactionEntry const* factionEntry); void CurrencyChanged(uint32 currencyId, int32 change); @@ -2659,6 +2663,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> PlayerAchievementMgr* m_achievementMgr; ReputationMgr* m_reputationMgr; + std::unique_ptr<QuestObjectiveCriteriaMgr> m_questObjectiveCriteriaMgr; uint32 m_ChampioningFaction; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 17ddf3ed8a6..1ee32b74991 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -113,6 +113,14 @@ bool LoginQueryHolder::Initialize() stmt->setUInt64(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES, stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES_CRITERIA); + stmt->setUInt64(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES_CRITERIA, stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS); + stmt->setUInt64(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES_CRITERIA_PROGRESS, stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_DAILY); stmt->setUInt64(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS, stmt); diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index 49bce2fe583..700216ef7e8 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -132,7 +132,7 @@ enum QuestGiverStatus DIALOG_STATUS_SCRIPTED_NO_STATUS = 0x1000 }; -enum QuestFlags +enum QuestFlags : uint32 { QUEST_FLAGS_NONE = 0x00000000, QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently @@ -164,7 +164,7 @@ enum QuestFlags }; // last checked in 19802 -enum QuestFlagsEx +enum QuestFlagsEx : uint32 { QUEST_FLAGS_EX_NONE = 0x0000000, QUEST_FLAGS_EX_KEEP_ADDITIONAL_ITEMS = 0x0000001, @@ -335,6 +335,8 @@ class TC_GAME_API Quest bool HasSpecialFlag(uint32 flag) const { return (SpecialFlags & flag) != 0; } void SetSpecialFlag(uint32 flag) { SpecialFlags |= flag; } + bool HasFlagEx(QuestFlagsEx flag) const { return (FlagsEx & uint32(flag)) != 0; } + // table data accessors: uint32 GetQuestId() const { return ID; } uint32 GetQuestType() const { return Type; } diff --git a/src/server/game/Quests/QuestObjectiveCriteriaMgr.cpp b/src/server/game/Quests/QuestObjectiveCriteriaMgr.cpp new file mode 100644 index 00000000000..965cbd804d1 --- /dev/null +++ b/src/server/game/Quests/QuestObjectiveCriteriaMgr.cpp @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "QuestObjectiveCriteriaMgr.h" +#include "AchievementPackets.h" +#include "DatabaseEnv.h" +#include "DB2Structure.h" +#include "Log.h" +#include "ObjectMgr.h" +#include "Player.h" + +QuestObjectiveCriteriaMgr::QuestObjectiveCriteriaMgr(Player* owner) : _owner(owner) +{ +} + +QuestObjectiveCriteriaMgr::~QuestObjectiveCriteriaMgr() +{ +} + +void QuestObjectiveCriteriaMgr::CheckAllQuestObjectiveCriteria(Player* referencePlayer) +{ + // suppress sending packets + for (uint32 i = 0; i < CRITERIA_TYPE_TOTAL; ++i) + UpdateCriteria(CriteriaTypes(i), 0, 0, 0, nullptr, referencePlayer); +} + +void QuestObjectiveCriteriaMgr::Reset() +{ + for (auto& criteriaProgres : _criteriaProgress) + SendCriteriaProgressRemoved(criteriaProgres.first); + + _criteriaProgress.clear(); + + DeleteFromDB(_owner->GetGUID()); + + // re-fill data + CheckAllQuestObjectiveCriteria(_owner); +} + +void QuestObjectiveCriteriaMgr::DeleteFromDB(ObjectGuid const& guid) +{ + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA); + stmt->setUInt64(0, guid.GetCounter()); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS); + stmt->setUInt64(0, guid.GetCounter()); + trans->Append(stmt); + + CharacterDatabase.CommitTransaction(trans); +} + +void QuestObjectiveCriteriaMgr::LoadFromDB(PreparedQueryResult objectiveResult, PreparedQueryResult criteriaResult) +{ + if (objectiveResult) + { + do + { + uint32 objectiveId = (*objectiveResult)[0].GetUInt32(); + + QuestObjective const* objective = sObjectMgr->GetQuestObjective(objectiveId); + if (!objective) + continue; + + _completedObjectives.insert(objectiveId); + + } while (objectiveResult->NextRow()); + } + + if (criteriaResult) + { + time_t now = time(nullptr); + do + { + Field* fields = criteriaResult->Fetch(); + uint32 criteriaId = fields[0].GetUInt32(); + uint64 counter = fields[1].GetUInt64(); + time_t date = time_t(fields[2].GetUInt32()); + + Criteria const* criteria = sCriteriaMgr->GetCriteria(criteriaId); + if (!criteria) + { + // Removing non-existing criteria data for all characters + TC_LOG_ERROR("criteria.quest", "Non-existing quest objective criteria %u data has been removed from the table `character_queststatus_objectives_criteria_progress`.", criteriaId); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_QUEST_PROGRESS_CRITERIA); + stmt->setUInt32(0, criteriaId); + CharacterDatabase.Execute(stmt); + + continue; + } + + if (criteria->Entry->StartTimer && time_t(date + criteria->Entry->StartTimer) < now) + continue; + + CriteriaProgress& progress = _criteriaProgress[criteriaId]; + progress.Counter = counter; + progress.Date = date; + progress.Changed = false; + } while (criteriaResult->NextRow()); + } +} + +void QuestObjectiveCriteriaMgr::SaveToDB(SQLTransaction& trans) +{ + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA); + stmt->setUInt64(0, _owner->GetGUID().GetCounter()); + trans->Append(stmt); + + if (!_completedObjectives.empty()) + { + for (uint32 completedObjectiveId : _completedObjectives) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA); + stmt->setUInt64(0, _owner->GetGUID().GetCounter()); + stmt->setUInt32(1, completedObjectiveId); + trans->Append(stmt); + } + } + + if (!_criteriaProgress.empty()) + { + for (auto& criteriaProgres : _criteriaProgress) + { + if (!criteriaProgres.second.Changed) + continue; + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS_BY_CRITERIA); + stmt->setUInt64(0, _owner->GetGUID().GetCounter()); + stmt->setUInt32(1, criteriaProgres.first); + trans->Append(stmt); + + if (criteriaProgres.second.Counter) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_QUESTSTATUS_OBJECTIVES_CRITERIA_PROGRESS); + stmt->setUInt64(0, _owner->GetGUID().GetCounter()); + stmt->setUInt32(1, criteriaProgres.first); + stmt->setUInt64(2, criteriaProgres.second.Counter); + stmt->setUInt32(3, uint32(criteriaProgres.second.Date)); + trans->Append(stmt); + } + + criteriaProgres.second.Changed = false; + } + } +} + +void QuestObjectiveCriteriaMgr::ResetCriteria(CriteriaTypes type, uint64 miscValue1, uint64 miscValue2, bool evenIfCriteriaComplete) +{ + TC_LOG_DEBUG("criteria.quest", "QuestObjectiveCriteriaMgr::ResetCriteria(%u, " UI64FMTD ", " UI64FMTD ")", type, miscValue1, miscValue2); + + // disable for gamemasters with GM-mode enabled + if (_owner->IsGameMaster()) + return; + + CriteriaList const& playerCriteriaList = GetCriteriaByType(type); + for (Criteria const* playerCriteria : playerCriteriaList) + { + if (playerCriteria->Entry->FailEvent != miscValue1 || (playerCriteria->Entry->FailAsset && playerCriteria->Entry->FailAsset != miscValue2)) + continue; + + std::vector<CriteriaTree const*> const* trees = sCriteriaMgr->GetCriteriaTreesByCriteria(playerCriteria->ID); + bool allComplete = true; + for (CriteriaTree const* tree : *trees) + { + // don't update already completed criteria if not forced + if (!(IsCompletedCriteriaTree(tree) && !evenIfCriteriaComplete)) + { + allComplete = false; + break; + } + } + + if (allComplete) + continue; + + RemoveCriteriaProgress(playerCriteria); + } +} + +void QuestObjectiveCriteriaMgr::ResetCriteriaTree(uint32 criteriaTreeId) +{ + CriteriaTree const* tree = sCriteriaMgr->GetCriteriaTree(criteriaTreeId); + if (!tree) + return; + + CriteriaMgr::WalkCriteriaTree(tree, [this](CriteriaTree const* criteriaTree) + { + RemoveCriteriaProgress(criteriaTree->Criteria); + }); +} + +void QuestObjectiveCriteriaMgr::SendAllData(Player const* /*receiver*/) const +{ + for (const auto& criteriaProgres : _criteriaProgress) + { + WorldPackets::Achievement::CriteriaUpdate criteriaUpdate; + + criteriaUpdate.CriteriaID = criteriaProgres.first; + criteriaUpdate.Quantity = criteriaProgres.second.Counter; + criteriaUpdate.PlayerGUID = _owner->GetGUID(); + criteriaUpdate.Flags = 0; + + criteriaUpdate.CurrentTime = criteriaProgres.second.Date; + criteriaUpdate.CreationTime = 0; + + SendPacket(criteriaUpdate.Write()); + } +} + +void QuestObjectiveCriteriaMgr::CompletedObjective(QuestObjective const* questObjective, Player* referencePlayer) +{ + // disable for gamemasters with GM-mode enabled + if (_owner->IsGameMaster()) + return; + + if (HasCompletedObjective(questObjective)) + return; + + referencePlayer->KillCreditCriteriaTreeObjective(*questObjective); + + TC_LOG_INFO("criteria.quest", "QuestObjectiveCriteriaMgr::CompletedObjective(%u). %s", questObjective->ID, GetOwnerInfo().c_str()); + + _completedObjectives.insert(questObjective->ID); +} + +bool QuestObjectiveCriteriaMgr::HasCompletedObjective(QuestObjective const* questObjective) const +{ + return _completedObjectives.find(questObjective->ID) != _completedObjectives.end(); +} + +void QuestObjectiveCriteriaMgr::SendCriteriaUpdate(Criteria const* criteria, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const +{ + WorldPackets::Achievement::CriteriaUpdate criteriaUpdate; + + criteriaUpdate.CriteriaID = criteria->ID; + criteriaUpdate.Quantity = progress->Counter; + criteriaUpdate.PlayerGUID = _owner->GetGUID(); + criteriaUpdate.Flags = 0; + if (criteria->Entry->StartTimer) + criteriaUpdate.Flags = timedCompleted ? 1 : 0; // 1 is for keeping the counter at 0 in client + + criteriaUpdate.CurrentTime = progress->Date; + criteriaUpdate.ElapsedTime = timeElapsed; + criteriaUpdate.CreationTime = 0; + + SendPacket(criteriaUpdate.Write()); +} + +void QuestObjectiveCriteriaMgr::SendCriteriaProgressRemoved(uint32 criteriaId) +{ + WorldPackets::Achievement::CriteriaDeleted criteriaDeleted; + criteriaDeleted.CriteriaID = criteriaId; + SendPacket(criteriaDeleted.Write()); +} + +bool QuestObjectiveCriteriaMgr::CanUpdateCriteriaTree(Criteria const* criteria, CriteriaTree const* tree, Player* referencePlayer) const +{ + QuestObjective const* objective = tree->QuestObjective; + if (!objective) + return false; + + if (HasCompletedObjective(objective)) + { + TC_LOG_TRACE("criteria.quest", "QuestObjectiveCriteriaMgr::CanUpdateCriteriaTree: (Id: %u Type %s Quest Objective %u) Objective already completed", + criteria->ID, CriteriaMgr::GetCriteriaTypeString(criteria->Entry->Type), objective->ID); + return false; + } + + return CriteriaHandler::CanUpdateCriteriaTree(criteria, tree, referencePlayer); +} + +bool QuestObjectiveCriteriaMgr::CanCompleteCriteriaTree(CriteriaTree const* tree) +{ + QuestObjective const* objective = tree->QuestObjective; + if (!objective) + return false; + + return CriteriaHandler::CanCompleteCriteriaTree(tree); +} + +void QuestObjectiveCriteriaMgr::CompletedCriteriaTree(CriteriaTree const* tree, Player* referencePlayer) +{ + QuestObjective const* objective = tree->QuestObjective; + if (!objective) + return; + + CompletedObjective(objective, referencePlayer); +} + +void QuestObjectiveCriteriaMgr::SendPacket(WorldPacket const* data) const +{ + _owner->SendDirectMessage(data); +} + +std::string QuestObjectiveCriteriaMgr::GetOwnerInfo() const +{ + return Trinity::StringFormat("%s %s", _owner->GetGUID().ToString().c_str(), _owner->GetName().c_str()); +} + +CriteriaList const& QuestObjectiveCriteriaMgr::GetCriteriaByType(CriteriaTypes type) const +{ + return sCriteriaMgr->GetQuestObjectiveCriteriaByType(type); +} diff --git a/src/server/game/Quests/QuestObjectiveCriteriaMgr.h b/src/server/game/Quests/QuestObjectiveCriteriaMgr.h new file mode 100644 index 00000000000..76c6bbb8d1d --- /dev/null +++ b/src/server/game/Quests/QuestObjectiveCriteriaMgr.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef QuestObjectiveCriteriaMgr_h__ +#define QuestObjectiveCriteriaMgr_h__ + +#include "CriteriaHandler.h" + +class TC_GAME_API QuestObjectiveCriteriaMgr : public CriteriaHandler +{ +public: + explicit QuestObjectiveCriteriaMgr(Player* owner); + ~QuestObjectiveCriteriaMgr(); + + void CheckAllQuestObjectiveCriteria(Player* referencePlayer); + + void Reset() override; + + static void DeleteFromDB(ObjectGuid const& guid); + void LoadFromDB(PreparedQueryResult objectiveResult, PreparedQueryResult criteriaResult); + void SaveToDB(SQLTransaction& trans); + + void ResetCriteria(CriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, bool evenIfCriteriaComplete = false); + void ResetCriteriaTree(uint32 criteriaTreeId); + + void SendAllData(Player const* receiver) const override; + + void CompletedObjective(QuestObjective const* questObjective, Player* referencePlayer); + bool HasCompletedObjective(QuestObjective const* questObjective) const; + +protected: + void SendCriteriaUpdate(Criteria const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const override; + + void SendCriteriaProgressRemoved(uint32 criteriaId) override; + + bool CanUpdateCriteriaTree(Criteria const* criteria, CriteriaTree const* tree, Player* referencePlayer) const override; + bool CanCompleteCriteriaTree(CriteriaTree const* tree) override; + void CompletedCriteriaTree(CriteriaTree const* tree, Player* referencePlayer) override; + + void SendPacket(WorldPacket const* data) const override; + + std::string GetOwnerInfo() const override; + CriteriaList const& GetCriteriaByType(CriteriaTypes type) const override; + +private: + Player* _owner; + std::unordered_set<uint32> _completedObjectives; +}; + +#endif |