fix challenge mode times window

This commit is contained in:
Martin Michelsen
2024-05-01 23:26:08 -07:00
parent 57ea246dd7
commit 4d172fff64
23 changed files with 126 additions and 73 deletions
+24 -7
View File
@@ -2022,8 +2022,19 @@ template <TextEncoding Encoding, size_t ShortDescLength>
struct S_QuestMenuEntryT { struct S_QuestMenuEntryT {
// Note: The game treats menu_id as two 8-bit fields followed by a 16-bit // Note: The game treats menu_id as two 8-bit fields followed by a 16-bit
// field. In most situations, this is opaque to the server, so we treat it as // field. In most situations, this is opaque to the server, so we treat it as
// a single 32-bit field, but in the case of the quest menu, the second byte // a single 32-bit field; however, in the case of the quest menu, the first
// is used to determine the icon that appears to the left of the quest name. // and second bytes have meaning on the client.
//
// The first byte is used as the quest episode number, which is only relevant
// for showing the Challenge Mode times window when a quest is selected.
// This byte must be set correctly on the quest category entry, not the quest
// itself, so the Episode 1 Challenge quests category should have a value of
// 1 in this byte, and the Episode 2 Challenge quests category should have a
// value of 2. (This is not the only condition required for the Challenge
// Mode times window to work; see the description of command A3 also.)
//
// The second byte of the menu ID is used to determine which icon appears to
// the left of the quest name.
// Specifically: // Specifically:
// 0 = online quest icon (green diamond) // 0 = online quest icon (green diamond)
// 1 = download quest icon (green square with outlined diamond) // 1 = download quest icon (green square with outlined diamond)
@@ -2054,7 +2065,13 @@ struct S_QuestMenuEntry_BB_A2_A4 {
} __packed_ws__(S_QuestMenuEntry_BB_A2_A4, 0x13C); } __packed_ws__(S_QuestMenuEntry_BB_A2_A4, 0x13C);
// A3 (S->C): Quest information // A3 (S->C): Quest information
// Same format as 1A/D5 command (plain text) // Same format as 1A/D5 command (plain text). The header.flag field is used to
// inform the client of the Challenge stage number, so it can show the correct
// timing window when the stage is selected. The Episode 1 stage numbers should
// be specified as 51-59 (decimal) in header.flag, and the Episode 2 stage
// numbers should be specified as 61-65 (decimal). If the header.flag value is
// outside this range, it is ignored, and the Challenge Mode times window does
// not update.
// A4 (S->C): Download quest menu // A4 (S->C): Download quest menu
// Internal name: RcvQuestList // Internal name: RcvQuestList
@@ -5220,12 +5237,12 @@ struct G_PlayerKilledByMonster_6x89 {
le_uint16_t unused = 0; le_uint16_t unused = 0;
} __packed_ws__(G_PlayerKilledByMonster_6x89, 8); } __packed_ws__(G_PlayerKilledByMonster_6x89, 8);
// 6x8A: Unknown (not valid on Episode 3) // 6x8A: Show Challenge time records window (not valid on Episode 3)
struct G_Unknown_6x8A { struct G_ShowChallengeTimeRecordsWindow_6x8A {
G_ClientIDHeader header; G_ClientIDHeader header;
le_uint32_t unknown_a1 = 0; // Must be < 0x11 le_uint32_t which = 0; // Must be < 0x11
} __packed_ws__(G_Unknown_6x8A, 8); } __packed_ws__(G_ShowChallengeTimeRecordsWindow_6x8A, 8);
// 6x8B: Unknown (not valid on Episode 3) // 6x8B: Unknown (not valid on Episode 3)
// This command has a handler, but it does nothing. // This command has a handler, but it does nothing.
+2 -1
View File
@@ -20,7 +20,8 @@ constexpr uint32_t LOBBY = 0x33000033;
constexpr uint32_t GAME = 0x44000044; constexpr uint32_t GAME = 0x44000044;
constexpr uint32_t QUEST_EP1 = 0x55010155; constexpr uint32_t QUEST_EP1 = 0x55010155;
constexpr uint32_t QUEST_EP2 = 0x55020255; constexpr uint32_t QUEST_EP2 = 0x55020255;
constexpr uint32_t QUEST_CATEGORIES = 0x66010166; constexpr uint32_t QUEST_CATEGORIES_EP1 = 0x01666601;
constexpr uint32_t QUEST_CATEGORIES_EP2 = 0x02666602;
constexpr uint32_t PROXY_DESTINATIONS = 0x77000077; constexpr uint32_t PROXY_DESTINATIONS = 0x77000077;
constexpr uint32_t PROGRAMS = 0x88000088; constexpr uint32_t PROGRAMS = 0x88000088;
constexpr uint32_t PATCHES = 0x99000099; constexpr uint32_t PATCHES = 0x99000099;
+12
View File
@@ -204,6 +204,7 @@ VersionedQuest::VersionedQuest(
std::shared_ptr<const std::string> pvr_contents, std::shared_ptr<const std::string> pvr_contents,
std::shared_ptr<const BattleRules> battle_rules, std::shared_ptr<const BattleRules> battle_rules,
ssize_t challenge_template_index, ssize_t challenge_template_index,
uint8_t description_flag,
std::shared_ptr<const IntegralExpression> available_expression, std::shared_ptr<const IntegralExpression> available_expression,
std::shared_ptr<const IntegralExpression> enabled_expression, std::shared_ptr<const IntegralExpression> enabled_expression,
bool allow_start_from_chat_command, bool allow_start_from_chat_command,
@@ -223,6 +224,7 @@ VersionedQuest::VersionedQuest(
pvr_contents(pvr_contents), pvr_contents(pvr_contents),
battle_rules(battle_rules), battle_rules(battle_rules),
challenge_template_index(challenge_template_index), challenge_template_index(challenge_template_index),
description_flag(description_flag),
available_expression(available_expression), available_expression(available_expression),
enabled_expression(enabled_expression) { enabled_expression(enabled_expression) {
@@ -392,6 +394,7 @@ Quest::Quest(shared_ptr<const VersionedQuest> initial_version)
name(initial_version->name), name(initial_version->name),
battle_rules(initial_version->battle_rules), battle_rules(initial_version->battle_rules),
challenge_template_index(initial_version->challenge_template_index), challenge_template_index(initial_version->challenge_template_index),
description_flag(initial_version->description_flag),
available_expression(initial_version->available_expression), available_expression(initial_version->available_expression),
enabled_expression(initial_version->enabled_expression) { enabled_expression(initial_version->enabled_expression) {
this->versions.emplace(this->versions_key(initial_version->version, initial_version->language), initial_version); this->versions.emplace(this->versions_key(initial_version->version, initial_version->language), initial_version);
@@ -429,6 +432,9 @@ void Quest::add_version(shared_ptr<const VersionedQuest> vq) {
if (this->challenge_template_index != vq->challenge_template_index) { if (this->challenge_template_index != vq->challenge_template_index) {
throw runtime_error("quest version has different challenge template index"); throw runtime_error("quest version has different challenge template index");
} }
if (this->description_flag != vq->description_flag) {
throw runtime_error("quest version has different description flag");
}
if (!this->available_expression != !vq->available_expression) { if (!this->available_expression != !vq->available_expression) {
throw runtime_error("quest version has available expression but root quest does not, or vice versa"); throw runtime_error("quest version has available expression but root quest does not, or vice versa");
} }
@@ -680,6 +686,7 @@ QuestIndex::QuestIndex(
const FileData* json_filedata = nullptr; const FileData* json_filedata = nullptr;
shared_ptr<BattleRules> battle_rules; shared_ptr<BattleRules> battle_rules;
ssize_t challenge_template_index = -1; ssize_t challenge_template_index = -1;
uint8_t description_flag = 0;
shared_ptr<const IntegralExpression> available_expression; shared_ptr<const IntegralExpression> available_expression;
shared_ptr<const IntegralExpression> enabled_expression; shared_ptr<const IntegralExpression> enabled_expression;
bool allow_start_from_chat_command = false; bool allow_start_from_chat_command = false;
@@ -707,6 +714,10 @@ QuestIndex::QuestIndex(
challenge_template_index = metadata_json.at("ChallengeTemplateIndex").as_int(); challenge_template_index = metadata_json.at("ChallengeTemplateIndex").as_int();
} catch (const out_of_range&) { } catch (const out_of_range&) {
} }
try {
description_flag = metadata_json.at("DescriptionFlag").as_int();
} catch (const out_of_range&) {
}
try { try {
available_expression = make_shared<IntegralExpression>(metadata_json.get_string("AvailableIf")); available_expression = make_shared<IntegralExpression>(metadata_json.get_string("AvailableIf"));
} catch (const out_of_range&) { } catch (const out_of_range&) {
@@ -739,6 +750,7 @@ QuestIndex::QuestIndex(
pvr_filedata ? pvr_filedata->data : nullptr, pvr_filedata ? pvr_filedata->data : nullptr,
battle_rules, battle_rules,
challenge_template_index, challenge_template_index,
description_flag,
available_expression, available_expression,
enabled_expression, enabled_expression,
allow_start_from_chat_command, allow_start_from_chat_command,
+8 -2
View File
@@ -37,7 +37,7 @@ enum class QuestMenuType {
struct QuestCategoryIndex { struct QuestCategoryIndex {
struct Category { struct Category {
uint32_t category_id; uint32_t category_id;
uint8_t enabled_flags; uint16_t enabled_flags;
std::string directory_name; std::string directory_name;
std::string name; std::string name;
std::string description; std::string description;
@@ -48,7 +48,10 @@ struct QuestCategoryIndex {
return this->enabled_flags & (1 << static_cast<uint8_t>(menu_type)); return this->enabled_flags & (1 << static_cast<uint8_t>(menu_type));
} }
[[nodiscard]] inline bool enable_episode_filter() const { [[nodiscard]] inline bool enable_episode_filter() const {
return this->enabled_flags & 0x80; return this->enabled_flags & 0x080;
}
[[nodiscard]] inline bool use_ep2_icon() const {
return this->enabled_flags & 0x100;
} }
}; };
@@ -78,6 +81,7 @@ struct VersionedQuest {
std::shared_ptr<const std::string> pvr_contents; std::shared_ptr<const std::string> pvr_contents;
std::shared_ptr<const BattleRules> battle_rules; std::shared_ptr<const BattleRules> battle_rules;
ssize_t challenge_template_index; ssize_t challenge_template_index;
uint8_t description_flag;
std::shared_ptr<const IntegralExpression> available_expression; std::shared_ptr<const IntegralExpression> available_expression;
std::shared_ptr<const IntegralExpression> enabled_expression; std::shared_ptr<const IntegralExpression> enabled_expression;
@@ -91,6 +95,7 @@ struct VersionedQuest {
std::shared_ptr<const std::string> pvr_contents, std::shared_ptr<const std::string> pvr_contents,
std::shared_ptr<const BattleRules> battle_rules = nullptr, std::shared_ptr<const BattleRules> battle_rules = nullptr,
ssize_t challenge_template_index = -1, ssize_t challenge_template_index = -1,
uint8_t description_flag = 0,
std::shared_ptr<const IntegralExpression> available_expression = nullptr, std::shared_ptr<const IntegralExpression> available_expression = nullptr,
std::shared_ptr<const IntegralExpression> enabled_expression = nullptr, std::shared_ptr<const IntegralExpression> enabled_expression = nullptr,
bool allow_start_from_chat_command = false, bool allow_start_from_chat_command = false,
@@ -131,6 +136,7 @@ public:
std::string name; std::string name;
std::shared_ptr<const BattleRules> battle_rules; std::shared_ptr<const BattleRules> battle_rules;
ssize_t challenge_template_index; ssize_t challenge_template_index;
uint8_t description_flag;
std::shared_ptr<const IntegralExpression> available_expression; std::shared_ptr<const IntegralExpression> available_expression;
std::shared_ptr<const IntegralExpression> enabled_expression; std::shared_ptr<const IntegralExpression> enabled_expression;
std::map<uint32_t, std::shared_ptr<const VersionedQuest>> versions; std::map<uint32_t, std::shared_ptr<const VersionedQuest>> versions;
+8 -6
View File
@@ -1744,7 +1744,8 @@ static void on_09(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
auto s = c->require_server_state(); auto s = c->require_server_state();
switch (cmd.menu_id) { switch (cmd.menu_id) {
case MenuID::QUEST_CATEGORIES: case MenuID::QUEST_CATEGORIES_EP1:
case MenuID::QUEST_CATEGORIES_EP2:
// Don't send anything here. The quest filter menu already has short // Don't send anything here. The quest filter menu already has short
// descriptions included with the entries, which the client shows in the // descriptions included with the entries, which the client shows in the
// usual location on the screen. // usual location on the screen.
@@ -1754,17 +1755,17 @@ static void on_09(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
bool is_download_quest = !c->lobby.lock(); bool is_download_quest = !c->lobby.lock();
auto quest_index = s->quest_index(c->version()); auto quest_index = s->quest_index(c->version());
if (!quest_index) { if (!quest_index) {
send_quest_info(c, "$C7Quests are not available.", is_download_quest); send_quest_info(c, "$C7Quests are not available.", 0x00, is_download_quest);
} else { } else {
auto q = quest_index->get(cmd.item_id); auto q = quest_index->get(cmd.item_id);
if (!q) { if (!q) {
send_quest_info(c, "$C4Quest does not\nexist.", is_download_quest); send_quest_info(c, "$C4Quest does not\nexist.", 0x00, is_download_quest);
} else { } else {
auto vq = q->version(c->version(), c->language()); auto vq = q->version(c->version(), c->language());
if (!vq) { if (!vq) {
send_quest_info(c, "$C4Quest does not\nexist for this game\nversion.", is_download_quest); send_quest_info(c, "$C4Quest does not\nexist for this game\nversion.", 0x00, is_download_quest);
} else { } else {
send_quest_info(c, vq->long_description, is_download_quest); send_quest_info(c, vq->long_description, vq->description_flag, is_download_quest);
} }
} }
} }
@@ -2470,7 +2471,8 @@ static void on_10(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
break; break;
} }
case MenuID::QUEST_CATEGORIES: { case MenuID::QUEST_CATEGORIES_EP1:
case MenuID::QUEST_CATEGORIES_EP2: {
auto s = c->require_server_state(); auto s = c->require_server_state();
auto quest_index = s->quest_index(c->version()); auto quest_index = s->quest_index(c->version());
if (!quest_index) { if (!quest_index) {
+10 -9
View File
@@ -739,6 +739,7 @@ static void send_text(
Channel& ch, Channel& ch,
StringWriter& w, StringWriter& w,
uint16_t command, uint16_t command,
uint32_t flag,
const string& text, const string& text,
ColorMode color_mode) { ColorMode color_mode) {
bool is_w = uses_utf16(ch.version); bool is_w = uses_utf16(ch.version);
@@ -772,18 +773,18 @@ static void send_text(
while (w.str().size() & 3) { while (w.str().size() & 3) {
w.put_u8(0); w.put_u8(0);
} }
ch.send(command, 0x00, w.str()); ch.send(command, flag, w.str());
} }
static void send_text(Channel& ch, uint16_t command, const string& text, ColorMode color_mode) { static void send_text(Channel& ch, uint16_t command, uint32_t flag, const string& text, ColorMode color_mode) {
StringWriter w; StringWriter w;
send_text(ch, w, command, text, color_mode); send_text(ch, w, command, flag, text, color_mode);
} }
static void send_header_text(Channel& ch, uint16_t command, uint32_t guild_card_number, const string& text, ColorMode color_mode) { static void send_header_text(Channel& ch, uint16_t command, uint32_t guild_card_number, const string& text, ColorMode color_mode) {
StringWriter w; StringWriter w;
w.put(SC_TextHeader_01_06_11_B0_EE({0, guild_card_number})); w.put(SC_TextHeader_01_06_11_B0_EE({0, guild_card_number}));
send_text(ch, w, command, text, color_mode); send_text(ch, w, command, 0x00, text, color_mode);
} }
void send_message_box(shared_ptr<Client> c, const string& text) { void send_message_box(shared_ptr<Client> c, const string& text) {
@@ -812,7 +813,7 @@ void send_message_box(shared_ptr<Client> c, const string& text) {
default: default:
throw logic_error("invalid game version"); throw logic_error("invalid game version");
} }
send_text(c->channel, command, text, ColorMode::ADD); send_text(c->channel, command, 0x00, text, ColorMode::ADD);
} }
void send_ep3_timed_message_box(Channel& ch, uint32_t frames, const string& message) { void send_ep3_timed_message_box(Channel& ch, uint32_t frames, const string& message) {
@@ -834,11 +835,11 @@ void send_ep3_timed_message_box(Channel& ch, uint32_t frames, const string& mess
} }
void send_lobby_name(shared_ptr<Client> c, const string& text) { void send_lobby_name(shared_ptr<Client> c, const string& text) {
send_text(c->channel, 0x8A, text, ColorMode::NONE); send_text(c->channel, 0x8A, 0x00, text, ColorMode::NONE);
} }
void send_quest_info(shared_ptr<Client> c, const string& text, bool is_download_quest) { void send_quest_info(shared_ptr<Client> c, const string& text, uint8_t description_flag, bool is_download_quest) {
send_text(c->channel, is_download_quest ? 0xA5 : 0xA3, text, ColorMode::ADD); send_text(c->channel, is_download_quest ? 0xA5 : 0xA3, description_flag, text, ColorMode::ADD);
} }
void send_lobby_message_box(shared_ptr<Client> c, const string& text, bool left_side_on_bb) { void send_lobby_message_box(shared_ptr<Client> c, const string& text, bool left_side_on_bb) {
@@ -1590,7 +1591,7 @@ void send_quest_categories_menu_t(
vector<EntryT> entries; vector<EntryT> entries;
for (const auto& cat : quest_index->categories(menu_type, episode, c->version(), include_condition)) { for (const auto& cat : quest_index->categories(menu_type, episode, c->version(), include_condition)) {
auto& e = entries.emplace_back(); auto& e = entries.emplace_back();
e.menu_id = MenuID::QUEST_CATEGORIES; e.menu_id = cat->use_ep2_icon() ? MenuID::QUEST_CATEGORIES_EP2 : MenuID::QUEST_CATEGORIES_EP1;
e.item_id = cat->category_id; e.item_id = cat->category_id;
e.name.encode(cat->name, c->language()); e.name.encode(cat->name, c->language());
e.short_description.encode(add_color(cat->description), c->language()); e.short_description.encode(add_color(cat->description), c->language());
+1 -2
View File
@@ -200,8 +200,7 @@ void send_complete_player_bb(std::shared_ptr<Client> c);
void send_message_box(std::shared_ptr<Client> c, const std::string& text); void send_message_box(std::shared_ptr<Client> c, const std::string& text);
void send_ep3_timed_message_box(Channel& ch, uint32_t frames, const std::string& text); void send_ep3_timed_message_box(Channel& ch, uint32_t frames, const std::string& text);
void send_lobby_name(std::shared_ptr<Client> c, const std::string& text); void send_lobby_name(std::shared_ptr<Client> c, const std::string& text);
void send_quest_info(std::shared_ptr<Client> c, const std::string& text, void send_quest_info(std::shared_ptr<Client> c, const std::string& text, uint8_t flag, bool is_download_quest);
bool is_download_quest);
void send_lobby_message_box(std::shared_ptr<Client> c, const std::string& text, bool left_side_on_bb = false); void send_lobby_message_box(std::shared_ptr<Client> c, const std::string& text, bool left_side_on_bb = false);
void send_ship_info(std::shared_ptr<Client> c, const std::string& text); void send_ship_info(std::shared_ptr<Client> c, const std::string& text);
void send_ship_info(Channel& ch, const std::string& text); void send_ship_info(Channel& ch, const std::string& text);
+27 -26
View File
@@ -662,37 +662,38 @@
// Each entry is [flags, directory_name, category_name, description]. // Each entry is [flags, directory_name, category_name, description].
// These fields are: // These fields are:
// flags: a bit field containing the following: // flags: a bit field containing the following:
// 0x01 - appears in normal mode // 0x001 - appears in normal mode
// 0x02 - appears in battle mode // 0x002 - appears in battle mode
// 0x04 - appears in challenge mode // 0x004 - appears in challenge mode
// 0x08 - appears in solo mode (BB) // 0x008 - appears in solo mode (BB)
// 0x10 - appears at government counter (BB) // 0x010 - appears at government counter (BB)
// 0x20 - appears in download quest menu // 0x020 - appears in download quest menu
// 0x40 - appears in Episode 3 download quest menu // 0x040 - appears in Episode 3 download quest menu
// 0x80 - hide quests that don't match the game's episode // 0x080 - hide quests that don't match the game's episode
// 0x100 - is Episode 2 Challenge category
// directory_name: the directory inside system/quests that contains quests // directory_name: the directory inside system/quests that contains quests
// for this category. // for this category.
// category_name: what appears in the quest menu on the client. // category_name: what appears in the quest menu on the client.
// description: what appears in the category description window (may // description: what appears in the category description window (may
// contain color escape codes like $C6). // contain color escape codes like $C6).
[0x81, "retrieval", "Retrieval", "$E$C6Quests that involve\nretrieving an object"], [0x081, "retrieval", "Retrieval", "$E$C6Quests that involve\nretrieving an object"],
[0x81, "extermination", "Extermination", "$E$C6Quests that involve\ndestroying all\nmonsters"], [0x081, "extermination", "Extermination", "$E$C6Quests that involve\ndestroying all\nmonsters"],
[0x81, "events", "Events", "$E$C6Quests that are part\nof an event"], [0x081, "events", "Events", "$E$C6Quests that are part\nof an event"],
[0x81, "shops", "Shops", "$E$C6Quests that contain\nshops"], [0x081, "shops", "Shops", "$E$C6Quests that contain\nshops"],
[0x81, "vr", "Virtual Reality", "$E$C6Quests that are\ndone in a simulator"], [0x081, "vr", "Virtual Reality", "$E$C6Quests that are\ndone in a simulator"],
[0x81, "tower", "Control Tower", "$E$C6Quests that take\nplace at the Control\nTower"], [0x081, "tower", "Control Tower", "$E$C6Quests that take\nplace at the Control\nTower"],
[0x81, "team", "Team", "$E$C6Quests for you\nand your team\nmembers."], [0x081, "team", "Team", "$E$C6Quests for you\nand your team\nmembers."],
[0x02, "battle", "Battle", "$E$C6Battle mode rule\nsets"], [0x002, "battle", "Battle", "$E$C6Battle mode rule\nsets"],
[0x04, "challenge-ep1", "Challenge (Episode 1)", "$E$C6Challenge mode\nquests in Episode 1"], [0x004, "challenge-ep1", "Challenge (Episode 1)", "$E$C6Challenge mode\nquests in Episode 1"],
[0x04, "challenge-ep2", "Challenge (Episode 2)", "$E$C6Challenge mode\nquests in Episode 2"], [0x104, "challenge-ep2", "Challenge (Episode 2)", "$E$C6Challenge mode\nquests in Episode 2"],
[0x88, "solo-story", "Story", "$E$C6Quests that follow\nthe story"], [0x088, "solo-story", "Story", "$E$C6Quests that follow\nthe story"],
[0x88, "solo-extra", "Solo", "$E$C6Quests that require\na single player"], [0x088, "solo-extra", "Solo", "$E$C6Quests that require\na single player"],
[0x10, "government-ep1", "Hero in Red", "$E$CG-Red Ring Rico-\n$C6Quests that follow\nthe Episode 1\nstoryline"], [0x010, "government-ep1", "Hero in Red", "$E$CG-Red Ring Rico-\n$C6Quests that follow\nthe Episode 1\nstoryline"],
[0x10, "government-ep2", "The Military's Hero", "$E$CG-Heathcliff Flowen-\n$C6Quests that follow\nthe Episode 2\nstoryline"], [0x010, "government-ep2", "The Military's Hero", "$E$CG-Heathcliff Flowen-\n$C6Quests that follow\nthe Episode 2\nstoryline"],
[0x10, "government-ep4", "The Meteor Impact Incident", "$E$C6Quests that follow\nthe Episode 4\nstoryline"], [0x010, "government-ep4", "The Meteor Impact Incident", "$E$C6Quests that follow\nthe Episode 4\nstoryline"],
[0x20, "download", "Download", "$E$C6Quests to download\nto your Memory Card"], [0x020, "download", "Download", "$E$C6Quests to download\nto your Memory Card"],
[0x40, "download-ep3-trial", "Trial Download", "$E$C6Quests to download\nto your Memory Card\nfrom Episode 3\nTrial Edition"], [0x040, "download-ep3-trial", "Trial Download", "$E$C6Quests to download\nto your Memory Card\nfrom Episode 3\nTrial Edition"],
[0x40, "download-ep3", "Download", "$E$C6Quests to download\nto your Memory Card"], [0x040, "download-ep3", "Download", "$E$C6Quests to download\nto your Memory Card"],
], ],
// Item stack limits. Note that changing these does not affect the client's // Item stack limits. Note that changing these does not affect the client's
+2 -1
View File
@@ -1,3 +1,4 @@
{ {
"ChallengeTemplateIndex": 0 "ChallengeTemplateIndex": 0,
"DescriptionFlag": 51
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 1, "ChallengeTemplateIndex": 1,
"DescriptionFlag": 52,
"AvailableIf": "CC_Ep1_1", "AvailableIf": "CC_Ep1_1",
"EnabledIf": "CC_Ep1_1" "EnabledIf": "CC_Ep1_1"
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 2, "ChallengeTemplateIndex": 2,
"DescriptionFlag": 53,
"AvailableIf": "CC_Ep1_2", "AvailableIf": "CC_Ep1_2",
"EnabledIf": "CC_Ep1_2" "EnabledIf": "CC_Ep1_2"
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 3, "ChallengeTemplateIndex": 3,
"DescriptionFlag": 54,
"AvailableIf": "CC_Ep1_3", "AvailableIf": "CC_Ep1_3",
"EnabledIf": "CC_Ep1_3" "EnabledIf": "CC_Ep1_3"
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 4, "ChallengeTemplateIndex": 4,
"DescriptionFlag": 55,
"AvailableIf": "CC_Ep1_4", "AvailableIf": "CC_Ep1_4",
"EnabledIf": "CC_Ep1_4" "EnabledIf": "CC_Ep1_4"
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 5, "ChallengeTemplateIndex": 5,
"DescriptionFlag": 56,
"AvailableIf": "CC_Ep1_5", "AvailableIf": "CC_Ep1_5",
"EnabledIf": "CC_Ep1_5" "EnabledIf": "CC_Ep1_5"
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 6, "ChallengeTemplateIndex": 6,
"DescriptionFlag": 57,
"AvailableIf": "CC_Ep1_6", "AvailableIf": "CC_Ep1_6",
"EnabledIf": "CC_Ep1_6" "EnabledIf": "CC_Ep1_6"
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 7, "ChallengeTemplateIndex": 7,
"DescriptionFlag": 58,
"AvailableIf": "CC_Ep1_7", "AvailableIf": "CC_Ep1_7",
"EnabledIf": "CC_Ep1_7" "EnabledIf": "CC_Ep1_7"
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 8, "ChallengeTemplateIndex": 8,
"DescriptionFlag": 59,
"AvailableIf": "CC_Ep1_8", "AvailableIf": "CC_Ep1_8",
"EnabledIf": "CC_Ep1_8" "EnabledIf": "CC_Ep1_8"
} }
+2 -1
View File
@@ -1,3 +1,4 @@
{ {
"ChallengeTemplateIndex": 1 "ChallengeTemplateIndex": 1,
"DescriptionFlag": 61,
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 4, "ChallengeTemplateIndex": 4,
"DescriptionFlag": 62,
"AvailableIf": "CC_Ep2_1", "AvailableIf": "CC_Ep2_1",
"EnabledIf": "CC_Ep2_1" "EnabledIf": "CC_Ep2_1"
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 5, "ChallengeTemplateIndex": 5,
"DescriptionFlag": 63,
"AvailableIf": "CC_Ep2_2", "AvailableIf": "CC_Ep2_2",
"EnabledIf": "CC_Ep2_2" "EnabledIf": "CC_Ep2_2"
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 8, "ChallengeTemplateIndex": 8,
"DescriptionFlag": 64,
"AvailableIf": "CC_Ep2_3", "AvailableIf": "CC_Ep2_3",
"EnabledIf": "CC_Ep2_3" "EnabledIf": "CC_Ep2_3"
} }
+1
View File
@@ -1,5 +1,6 @@
{ {
"ChallengeTemplateIndex": 8, "ChallengeTemplateIndex": 8,
"DescriptionFlag": 65,
"AvailableIf": "CC_Ep2_4", "AvailableIf": "CC_Ep2_4",
"EnabledIf": "CC_Ep2_4" "EnabledIf": "CC_Ep2_4"
} }
+18 -18
View File
@@ -190,24 +190,24 @@
}, },
"QuestCategories": [ "QuestCategories": [
[0x81, "retrieval", "Retrieval", "$E$C6Quests that involve\nretrieving an object"], [0x081, "retrieval", "Retrieval", "$E$C6Quests that involve\nretrieving an object"],
[0x81, "extermination", "Extermination", "$E$C6Quests that involve\ndestroying all\nmonsters"], [0x081, "extermination", "Extermination", "$E$C6Quests that involve\ndestroying all\nmonsters"],
[0x81, "events", "Events", "$E$C6Quests that are part\nof an event"], [0x081, "events", "Events", "$E$C6Quests that are part\nof an event"],
[0x81, "shops", "Shops", "$E$C6Quests that contain\nshops"], [0x081, "shops", "Shops", "$E$C6Quests that contain\nshops"],
[0x81, "vr", "Virtual Reality", "$E$C6Quests that are\ndone in a simulator"], [0x081, "vr", "Virtual Reality", "$E$C6Quests that are\ndone in a simulator"],
[0x81, "tower", "Control Tower", "$E$C6Quests that take\nplace at the Control\nTower"], [0x081, "tower", "Control Tower", "$E$C6Quests that take\nplace at the Control\nTower"],
[0x81, "team", "Team", "$E$C6Quests for you\nand your team\nmembers."], [0x081, "team", "Team", "$E$C6Quests for you\nand your team\nmembers."],
[0x02, "battle", "Battle", "$E$C6Battle mode rule\nsets"], [0x002, "battle", "Battle", "$E$C6Battle mode rule\nsets"],
[0x04, "challenge-ep1", "Challenge (Episode 1)", "$E$C6Challenge mode\nquests in Episode 1"], [0x004, "challenge-ep1", "Challenge (Episode 1)", "$E$C6Challenge mode\nquests in Episode 1"],
[0x04, "challenge-ep2", "Challenge (Episode 2)", "$E$C6Challenge mode\nquests in Episode 2"], [0x104, "challenge-ep2", "Challenge (Episode 2)", "$E$C6Challenge mode\nquests in Episode 2"],
[0x88, "solo-story", "Story", "$E$C6Quests that follow\nthe Episode 1 story"], [0x088, "solo-story", "Story", "$E$C6Quests that follow\nthe Episode 1 story"],
[0x88, "solo-extra", "Solo", "$E$C6Quests that require\na single player"], [0x088, "solo-extra", "Solo", "$E$C6Quests that require\na single player"],
[0x10, "government-ep1", "Hero in Red", "$E$CG-Red Ring Rico-\n$C6Quests that follow\nthe Episode 1\nstoryline"], [0x010, "government-ep1", "Hero in Red", "$E$CG-Red Ring Rico-\n$C6Quests that follow\nthe Episode 1\nstoryline"],
[0x10, "government-ep2", "The Military's Hero", "$E$CG-Heathcliff Flowen-\n$C6Quests that follow\nthe Episode 2\nstoryline"], [0x010, "government-ep2", "The Military's Hero", "$E$CG-Heathcliff Flowen-\n$C6Quests that follow\nthe Episode 2\nstoryline"],
[0x10, "government-ep4", "The Meteor Impact Incident", "$E$C6Quests that follow\nthe Episode 4\nstoryline"], [0x010, "government-ep4", "The Meteor Impact Incident", "$E$C6Quests that follow\nthe Episode 4\nstoryline"],
[0x20, "download", "Download", "$E$C6Quests to download\nto your Memory Card"], [0x020, "download", "Download", "$E$C6Quests to download\nto your Memory Card"],
[0x40, "download-ep3-trial", "Trial Download", "$E$C6Quests to download\nto your Memory Card\nfrom Episode 3\nTrial Edition"], [0x040, "download-ep3-trial", "Trial Download", "$E$C6Quests to download\nto your Memory Card\nfrom Episode 3\nTrial Edition"],
[0x40, "download-ep3", "Download", "$E$C6Quests to download\nto your Memory Card"], [0x040, "download-ep3", "Download", "$E$C6Quests to download\nto your Memory Card"],
], ],
"ItemStackLimits": [ "ItemStackLimits": [