From f6d7ccbb69f92031c67aa0e6245852114a1b78ab Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Fri, 13 Feb 2026 00:34:07 +0100 Subject: [PATCH] Quest/Filter * update quest flags to current knowledge base * implemented filter criterium for pvp-enabling quests --- endpoints/quest/quest.php | 4 +- includes/dbtypes/quest.class.php | 97 +++++++++++++---------------- includes/defines.php | 43 ++++++++----- setup/tools/filegen/profiler.ss.php | 2 +- static/js/filters.js | 1 + static/js/locale_dede.js | 1 + static/js/locale_enus.js | 1 + static/js/locale_eses.js | 1 + static/js/locale_frfr.js | 1 + static/js/locale_ruru.js | 1 + static/js/locale_zhcn.js | 1 + 11 files changed, 79 insertions(+), 74 deletions(-) diff --git a/endpoints/quest/quest.php b/endpoints/quest/quest.php index a17b0992..575af6b3 100644 --- a/endpoints/quest/quest.php +++ b/endpoints/quest/quest.php @@ -233,7 +233,7 @@ class QuestBaseResponse extends TemplateResponse implements ICache $infobox[] = implode('[br]', $e); // auto accept - if ($_flags & QUEST_FLAG_AUTO_ACCEPT) + if ($this->subject->isAutoAccept()) $infobox[] = Lang::quest('autoaccept'); // Repeatable @@ -244,7 +244,7 @@ class QuestBaseResponse extends TemplateResponse implements ICache $infobox[] = $_flags & QUEST_FLAG_SHARABLE ? Lang::quest('sharable') : Lang::quest('notSharable'); // Keeps you PvP flagged - if ($this->subject->isPvPEnabled()) + if ($_flags & QUEST_FLAG_FLAGS_PVP) $infobox[] = Lang::quest('keepsPvpFlag'); // difficulty (todo (low): formula unclear. seems to be [minLevel,] -4, -2, (level), +3, +(9 to 15)) diff --git a/includes/dbtypes/quest.class.php b/includes/dbtypes/quest.class.php index e6afef09..7096fbba 100644 --- a/includes/dbtypes/quest.class.php +++ b/includes/dbtypes/quest.class.php @@ -112,7 +112,7 @@ class QuestList extends DBTypeList public function isRepeatable() : bool { - return $this->curTpl['flags'] & QUEST_FLAG_REPEATABLE || $this->curTpl['specialFlags'] & QUEST_FLAG_SPECIAL_REPEATABLE; + return $this->curTpl['specialFlags'] & QUEST_FLAG_SPECIAL_REPEATABLE; } public function isDaily() : int @@ -129,10 +129,9 @@ class QuestList extends DBTypeList return 0; } - // using reqPlayerKills and rewardHonor as a crutch .. has TC this even implemented..? - public function isPvPEnabled() : bool + public function isAutoAccept() : bool { - return $this->curTpl['reqPlayerKills'] || $this->curTpl['rewardHonorPoints'] || $this->curTpl['rewardArenaPoints']; + return $this->curTpl['flags'] & QUEST_FLAG_AUTO_ACCEPT || $this->curTpl['specialFlags'] & QUEST_FLAG_SPECIAL_AUTO_ACCEPT; } // by TC definition @@ -263,14 +262,14 @@ class QuestList extends DBTypeList if ($this->isSeasonal()) $data[$this->id]['wflags'] |= QUEST_CU_SEASONAL; - if ($this->curTpl['flags'] & QUEST_FLAG_AUTO_REWARDED) // not shown in log + if ($this->curTpl['flags'] & QUEST_FLAG_TRACKING) // not shown in log $data[$this->id]['wflags'] |= QUEST_CU_SKIP_LOG; - if ($this->curTpl['flags'] & QUEST_FLAG_AUTO_ACCEPT) // self-explanatory + if ($this->isAutoAccept()) $data[$this->id]['wflags'] |= QUEST_CU_AUTO_ACCEPT; - if ($this->isPvPEnabled()) // not sure why this flag also requires auto-accept to be set - $data[$this->id]['wflags'] |= (QUEST_CU_AUTO_ACCEPT | QUEST_CU_PVP_ENABLED); + if ($this->curTpl['flags'] & QUEST_FLAG_FLAGS_PVP) // this flag is only displayed if auto-accept is also set. not sure why. + $data[$this->id]['wflags'] |= QUEST_CU_PVP_ENABLED; $data[$this->id]['reprewards'] = []; for ($i = 1; $i < 6; $i++) @@ -447,42 +446,43 @@ class QuestListFilter extends Filter ); protected static array $genericFilter = array( - 1 => [parent::CR_CALLBACK, 'cbReputation', '>', null], // increasesrepwith - 2 => [parent::CR_NUMERIC, 'rewardXP', NUM_CAST_INT ], // experiencegained - 3 => [parent::CR_NUMERIC, 'rewardOrReqMoney', NUM_CAST_INT ], // moneyrewarded - 4 => [parent::CR_CALLBACK, 'cbSpellRewards', null, null], // spellrewarded [yn] - 5 => [parent::CR_FLAG, 'flags', QUEST_FLAG_SHARABLE ], // sharable - 6 => [parent::CR_NUMERIC, 'timeLimit', NUM_CAST_INT ], // timer - 7 => [parent::CR_FLAG, 'cuFlags', QUEST_CU_FIRST_SERIES ], // firstquestseries - 9 => [parent::CR_CALLBACK, 'cbEarnReputation', null, null], // objectiveearnrepwith [enum] - 10 => [parent::CR_CALLBACK, 'cbReputation', '<', null], // decreasesrepwith - 11 => [parent::CR_NUMERIC, 'suggestedPlayers', NUM_CAST_INT ], // suggestedplayers - 15 => [parent::CR_FLAG, 'cuFlags', QUEST_CU_LAST_SERIES ], // lastquestseries - 16 => [parent::CR_FLAG, 'cuFlags', QUEST_CU_PART_OF_SERIES ], // partseries - 18 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_SCREENSHOT ], // hasscreenshots - 19 => [parent::CR_CALLBACK, 'cbQuestRelation', 0x1, null], // startsfrom [enum] - 21 => [parent::CR_CALLBACK, 'cbQuestRelation', 0x2, null], // endsat [enum] - 22 => [parent::CR_CALLBACK, 'cbItemRewards', null, null], // itemrewards [op] [int] - 23 => [parent::CR_CALLBACK, 'cbItemChoices', null, null], // itemchoices [op] [int] - 24 => [parent::CR_CALLBACK, 'cbLacksStartEnd', null, null], // lacksstartend [yn] - 25 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments - 27 => [parent::CR_FLAG, 'flags', QUEST_FLAG_DAILY ], // daily - 28 => [parent::CR_FLAG, 'flags', QUEST_FLAG_WEEKLY ], // weekly - 29 => [parent::CR_CALLBACK, 'cbRepeatable', null ], // repeatable - 30 => [parent::CR_NUMERIC, 'id', NUM_CAST_INT, true], // id - 33 => [parent::CR_ENUM, 'e.holidayId', true, true], // relatedevent - 34 => [parent::CR_CALLBACK, 'cbAvailable', null, null], // availabletoplayers [yn] - 36 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_VIDEO ], // hasvideos - 37 => [parent::CR_CALLBACK, 'cbClassSpec', null, null], // classspecific [enum] - 38 => [parent::CR_CALLBACK, 'cbRaceSpec', null, null], // racespecific [enum] - 42 => [parent::CR_STAFFFLAG, 'flags' ], // flags - 43 => [parent::CR_CALLBACK, 'cbCurrencyReward', null, null], // currencyrewarded [enum] - 44 => [parent::CR_CALLBACK, 'cbLoremaster', null, null], // countsforloremaster_stc [yn] - 45 => [parent::CR_BOOLEAN, 'rewardTitleId' ] // titlerewarded + 1 => [parent::CR_CALLBACK, 'cbReputation', '>', null], // increasesrepwith + 2 => [parent::CR_NUMERIC, 'rewardXP', NUM_CAST_INT ], // experiencegained + 3 => [parent::CR_NUMERIC, 'rewardOrReqMoney', NUM_CAST_INT ], // moneyrewarded + 4 => [parent::CR_CALLBACK, 'cbSpellRewards', null, null], // spellrewarded [yn] + 5 => [parent::CR_FLAG, 'flags', QUEST_FLAG_SHARABLE ], // sharable + 6 => [parent::CR_NUMERIC, 'timeLimit', NUM_CAST_INT ], // timer + 7 => [parent::CR_FLAG, 'cuFlags', QUEST_CU_FIRST_SERIES ], // firstquestseries + 9 => [parent::CR_CALLBACK, 'cbEarnReputation', null, null], // objectiveearnrepwith [enum] + 10 => [parent::CR_CALLBACK, 'cbReputation', '<', null], // decreasesrepwith + 11 => [parent::CR_NUMERIC, 'suggestedPlayers', NUM_CAST_INT ], // suggestedplayers + 15 => [parent::CR_FLAG, 'cuFlags', QUEST_CU_LAST_SERIES ], // lastquestseries + 16 => [parent::CR_FLAG, 'cuFlags', QUEST_CU_PART_OF_SERIES ], // partseries + 18 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_SCREENSHOT ], // hasscreenshots + 19 => [parent::CR_CALLBACK, 'cbQuestRelation', 0x1, null], // startsfrom [enum] + 21 => [parent::CR_CALLBACK, 'cbQuestRelation', 0x2, null], // endsat [enum] + 22 => [parent::CR_CALLBACK, 'cbItemRewards', null, null], // itemrewards [op] [int] + 23 => [parent::CR_CALLBACK, 'cbItemChoices', null, null], // itemchoices [op] [int] + 24 => [parent::CR_CALLBACK, 'cbLacksStartEnd', null, null], // lacksstartend [yn] + 25 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments + 27 => [parent::CR_FLAG, 'flags', QUEST_FLAG_DAILY ], // daily + 28 => [parent::CR_FLAG, 'flags', QUEST_FLAG_WEEKLY ], // weekly + 29 => [parent::CR_FLAG, 'specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE], // repeatable + 30 => [parent::CR_NUMERIC, 'id', NUM_CAST_INT, true], // id + 33 => [parent::CR_ENUM, 'e.holidayId', true, true], // relatedevent + 34 => [parent::CR_CALLBACK, 'cbAvailable', null, null], // availabletoplayers [yn] + 36 => [parent::CR_FLAG, 'cuFlags', CUSTOM_HAS_VIDEO ], // hasvideos + 37 => [parent::CR_CALLBACK, 'cbClassSpec', null, null], // classspecific [enum] + 38 => [parent::CR_CALLBACK, 'cbRaceSpec', null, null], // racespecific [enum] + 42 => [parent::CR_STAFFFLAG, 'flags' ], // flags + 43 => [parent::CR_CALLBACK, 'cbCurrencyReward', null, null], // currencyrewarded [enum] + 44 => [parent::CR_CALLBACK, 'cbLoremaster', null, null], // countsforloremaster_stc [yn] + 45 => [parent::CR_BOOLEAN, 'rewardTitleId' ], // titlerewarded + 47 => [parent::CR_FLAG, 'flags', QUEST_FLAG_FLAGS_PVP ] // setspvpflag ); protected static array $inputFields = array( - 'cr' => [parent::V_RANGE, [1, 45], true ], // criteria ids + 'cr' => [parent::V_RANGE, [1, 47], true ], // criteria ids 'crs' => [parent::V_LIST, [parent::ENUM_NONE, parent::ENUM_ANY, [0, 99999]], true ], // criteria operators 'crv' => [parent::V_REGEX, parent::PATTERN_INT, true ], // criteria values - only numerals 'na' => [parent::V_NAME, false, false], // name / text - only printable chars, no delimiter @@ -616,17 +616,6 @@ class QuestListFilter extends Filter return ['cuFlags', CUSTOM_UNAVAILABLE | CUSTOM_DISABLED, '&']; } - protected function cbRepeatable(int $cr, int $crs, string $crv) : ?array - { - if (!$this->int2Bool($crs)) - return null; - - if ($crs) - return ['OR', ['flags', QUEST_FLAG_REPEATABLE, '&'], ['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE, '&']]; - else - return ['AND', [['flags', QUEST_FLAG_REPEATABLE, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE, '&'], 0]]; - } - protected function cbItemChoices(int $cr, int $crs, string $crv) : ?array { if (!Util::checkNumeric($crv, NUM_CAST_INT) || !$this->int2Op($crs)) @@ -653,9 +642,9 @@ class QuestListFilter extends Filter return null; if ($crs) - return ['AND', ['questSortId', 0, '>'], [['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_REPEATABLE, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0]]; + return ['AND', ['questSortId', 0, '>'], [['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0]]; else - return ['OR', ['questSortId', 0, '<'], ['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_REPEATABLE, '&'], ['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&']]; + return ['OR', ['questSortId', 0, '<'], ['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY, '&'], ['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_MONTHLY, '&']]; } protected function cbSpellRewards(int $cr, int $crs, string $crv) : ?array diff --git a/includes/defines.php b/includes/defines.php index 9762fa4b..ea2cf913 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -801,24 +801,33 @@ define('PET_TALENT_TYPE_TENACITY', 1); define('PET_TALENT_TYPE_CUNNING', 2); // quest -define('QUEST_FLAG_STAY_ALIVE', 0x00001); -define('QUEST_FLAG_PARTY_ACCEPT', 0x00002); -define('QUEST_FLAG_EXPLORATION', 0x00004); -define('QUEST_FLAG_SHARABLE', 0x00008); -define('QUEST_FLAG_AUTO_REWARDED', 0x00400); -define('QUEST_FLAG_DAILY', 0x01000); -define('QUEST_FLAG_REPEATABLE', 0x02000); -define('QUEST_FLAG_UNAVAILABLE', 0x04000); -define('QUEST_FLAG_WEEKLY', 0x08000); -define('QUEST_FLAG_AUTO_COMPLETE', 0x10000); -define('QUEST_FLAG_AUTO_ACCEPT', 0x80000); +define('QUEST_FLAG_STAY_ALIVE', 0x00001); +define('QUEST_FLAG_PARTY_ACCEPT', 0x00002); +define('QUEST_FLAG_EXPLORATION', 0x00004); +define('QUEST_FLAG_SHARABLE', 0x00008); +define('QUEST_FLAG_HAS_CONDITION', 0x00010); // TC: Not used currently +define('QUEST_FLAG_HIDE_REWARD_POI', 0x00020); // TC: Not used currently: Unsure of content +define('QUEST_FLAG_RAID', 0x00040); +define('QUEST_FLAG_TBC', 0x00080); +define('QUEST_FLAG_NO_MONEY_FROM_XP', 0x00100); +define('QUEST_FLAG_HIDDEN_REWARDS', 0x00200); +define('QUEST_FLAG_TRACKING', 0x00400); // TC: These quests are automatically rewarded on quest complete and they will never appear in quest log client side. +define('QUEST_FLAG_DEPRECATE_REPUTATION', 0x00800); // TC: Not used currently +define('QUEST_FLAG_DAILY', 0x01000); +define('QUEST_FLAG_FLAGS_PVP', 0x02000); +define('QUEST_FLAG_UNAVAILABLE', 0x04000); +define('QUEST_FLAG_WEEKLY', 0x08000); +define('QUEST_FLAG_AUTO_COMPLETE', 0x10000); +define('QUEST_FLAG_DISPLAY_ITEM_IN_TRACKER', 0x20000); // TC: Displays usable item in quest tracker +define('QUEST_FLAG_OBJ_TEXT', 0x40000); // TC: use Objective text as Complete text +define('QUEST_FLAG_AUTO_ACCEPT', 0x80000); -define('QUEST_FLAG_SPECIAL_REPEATABLE', 0x01); -define('QUEST_FLAG_SPECIAL_EXT_COMPLETE', 0x02); -define('QUEST_FLAG_SPECIAL_AUTO_ACCEPT', 0x04); -define('QUEST_FLAG_SPECIAL_DUNGEON_FINDER', 0x08); -define('QUEST_FLAG_SPECIAL_MONTHLY', 0x10); -define('QUEST_FLAG_SPECIAL_SPELLCAST', 0x20); // not documented in wiki! :[ +define('QUEST_FLAG_SPECIAL_REPEATABLE', 0x01); +define('QUEST_FLAG_SPECIAL_EXT_COMPLETE', 0x02); +define('QUEST_FLAG_SPECIAL_AUTO_ACCEPT', 0x04); +define('QUEST_FLAG_SPECIAL_DUNGEON_FINDER', 0x08); +define('QUEST_FLAG_SPECIAL_MONTHLY', 0x10); +define('QUEST_FLAG_SPECIAL_SPELLCAST', 0x20); // not documented in wiki! :[ // GameObject define('OBJECT_DOOR', 0); diff --git a/setup/tools/filegen/profiler.ss.php b/setup/tools/filegen/profiler.ss.php index 98cfb57f..8a60c3dd 100644 --- a/setup/tools/filegen/profiler.ss.php +++ b/setup/tools/filegen/profiler.ss.php @@ -58,7 +58,7 @@ CLISetup::registerSetup("build", new class extends SetupScript $condition = [ 'AND', [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW | CUSTOM_UNAVAILABLE | CUSTOM_DISABLED, '&'], 0], - [['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_REPEATABLE | QUEST_FLAG_AUTO_REWARDED, '&'], 0], + [['flags', QUEST_FLAG_DAILY | QUEST_FLAG_WEEKLY | QUEST_FLAG_TRACKING, '&'], 0], [['specialFlags', QUEST_FLAG_SPECIAL_REPEATABLE | QUEST_FLAG_SPECIAL_DUNGEON_FINDER | QUEST_FLAG_SPECIAL_MONTHLY, '&'], 0] ]; diff --git a/static/js/filters.js b/static/js/filters.js index 67c6e541..4c6a346a 100644 --- a/static/js/filters.js +++ b/static/js/filters.js @@ -280,6 +280,7 @@ var fi_filters = { { id: 29, name: 'repeatable', type: 'yn' }, { id: 30, name: 'id', type: 'num', before: 'name' }, { id: 44, name: 'countsforloremaster_stc', type: 'yn' }, + { id: 47, name: 'setspvpflag', type: 'yn' }, { id: 9, name: 'objectiveearnrepwith', type: 'faction-any+none' }, { id: 33, name: 'relatedevent', type: 'event-any+none' }, { id: 5, name: 'sharable', type: 'yn' }, diff --git a/static/js/locale_dede.js b/static/js/locale_dede.js index 13149b44..45dff883 100644 --- a/static/js/locale_dede.js +++ b/static/js/locale_dede.js @@ -4167,6 +4167,7 @@ var LANG = { id: "ID", classspecific: "Klassenspezifisch", racespecific: "Volksspezifisch", + setspvpflag: "Hält Euch im PvP", sepgainsrewards: "Belohnungen/Steigerungen", experiencegained: "Erhaltene Erfahrung", diff --git a/static/js/locale_enus.js b/static/js/locale_enus.js index 2886bafa..6dc726c0 100644 --- a/static/js/locale_enus.js +++ b/static/js/locale_enus.js @@ -4211,6 +4211,7 @@ var LANG = { id: "ID", classspecific: "Class-specific", racespecific: "Race-specific", + setspvpflag: "Keeps you PvP flagged", sepgainsrewards: "Gains/rewards", experiencegained: "Experience gained", diff --git a/static/js/locale_eses.js b/static/js/locale_eses.js index 7434c43f..723a7651 100644 --- a/static/js/locale_eses.js +++ b/static/js/locale_eses.js @@ -4167,6 +4167,7 @@ var LANG = { id: "ID", classspecific: "Específico de clase", racespecific: "Específico de raza", + setspvpflag: "Mantiene el JcJ activado", sepgainsrewards: "Ganancias/recompensas", experiencegained: "Experiencia ganada", diff --git a/static/js/locale_frfr.js b/static/js/locale_frfr.js index 205e8371..b46cdd3f 100644 --- a/static/js/locale_frfr.js +++ b/static/js/locale_frfr.js @@ -4167,6 +4167,7 @@ var LANG = { id: "ID", classspecific: "Classe-spécifique", racespecific: "Spécifique à la race", + setspvpflag: "Vous garde en mode JvJ", sepgainsrewards: "Gains/récompenses", experiencegained: "Expérience gagnée", diff --git a/static/js/locale_ruru.js b/static/js/locale_ruru.js index b63439fb..1a2b065f 100644 --- a/static/js/locale_ruru.js +++ b/static/js/locale_ruru.js @@ -4166,6 +4166,7 @@ var LANG = { id: "Номер", classspecific: "Только для класса", racespecific: "Расовый", + setspvpflag: "Включает доступность PvP", sepgainsrewards: "Награда за выполнение", experiencegained: "Получаемый опыт", diff --git a/static/js/locale_zhcn.js b/static/js/locale_zhcn.js index 7447f0a4..09016afa 100644 --- a/static/js/locale_zhcn.js +++ b/static/js/locale_zhcn.js @@ -4208,6 +4208,7 @@ var LANG = { id: "ID", classspecific: "职业专属", racespecific: "种族特定", + setspvpflag: "保持PvP旗帜标记", sepgainsrewards: "收获/奖励", experiencegained: "获得的经验",