add more options in IntegralExpression
This commit is contained in:
+2
-2
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "Client.hh"
|
#include "Client.hh"
|
||||||
|
|
||||||
const std::vector<ChoiceSearchCategory> CHOICE_SEARCH_CATEGORIES({
|
const std::vector<ChoiceSearchCategory> CHOICE_SEARCH_CATEGORIES{
|
||||||
ChoiceSearchCategory{
|
ChoiceSearchCategory{
|
||||||
.id = 0x0001,
|
.id = 0x0001,
|
||||||
.name = "Level",
|
.name = "Level",
|
||||||
@@ -145,4 +145,4 @@ const std::vector<ChoiceSearchCategory> CHOICE_SEARCH_CATEGORIES({
|
|||||||
return (choice_id == 0) || (target_choice_id == 0) || (choice_id == target_choice_id);
|
return (choice_id == 0) || (target_choice_id == 0) || (choice_id == target_choice_id);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
|||||||
+3
-1
@@ -377,7 +377,9 @@ bool Client::evaluate_quest_availability_expression(
|
|||||||
}
|
}
|
||||||
auto p = this->character_file();
|
auto p = this->character_file();
|
||||||
IntegralExpression::Env env = {
|
IntegralExpression::Env env = {
|
||||||
.flags = &p->quest_flags.data.at(static_cast<size_t>(difficulty)),
|
.section_id = p->disp.visual.sh.section_id,
|
||||||
|
.difficulty = difficulty,
|
||||||
|
.flags = &p->quest_flags,
|
||||||
.challenge_records = &p->challenge_records,
|
.challenge_records = &p->challenge_records,
|
||||||
.team = this->team(),
|
.team = this->team(),
|
||||||
.num_players = num_players,
|
.num_players = num_players,
|
||||||
|
|||||||
@@ -811,7 +811,7 @@ void DownloadSession::on_request_complete() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<DownloadSession::GameConfig> DownloadSession::game_configs({
|
const std::vector<DownloadSession::GameConfig> DownloadSession::game_configs{
|
||||||
{.mode = GameMode::NORMAL, .episode = Episode::EP1, .v1 = true, .v2 = true, .v3 = true},
|
{.mode = GameMode::NORMAL, .episode = Episode::EP1, .v1 = true, .v2 = true, .v3 = true},
|
||||||
{.mode = GameMode::NORMAL, .episode = Episode::EP2, .v1 = false, .v2 = false, .v3 = true},
|
{.mode = GameMode::NORMAL, .episode = Episode::EP2, .v1 = false, .v2 = false, .v3 = true},
|
||||||
{.mode = GameMode::NORMAL, .episode = Episode::EP4, .v1 = false, .v2 = false, .v3 = false},
|
{.mode = GameMode::NORMAL, .episode = Episode::EP4, .v1 = false, .v2 = false, .v3 = false},
|
||||||
@@ -821,4 +821,4 @@ const std::vector<DownloadSession::GameConfig> DownloadSession::game_configs({
|
|||||||
{.mode = GameMode::SOLO, .episode = Episode::EP1, .v1 = false, .v2 = false, .v3 = false},
|
{.mode = GameMode::SOLO, .episode = Episode::EP1, .v1 = false, .v2 = false, .v3 = false},
|
||||||
{.mode = GameMode::SOLO, .episode = Episode::EP2, .v1 = false, .v2 = false, .v3 = false},
|
{.mode = GameMode::SOLO, .episode = Episode::EP2, .v1 = false, .v2 = false, .v3 = false},
|
||||||
{.mode = GameMode::SOLO, .episode = Episode::EP4, .v1 = false, .v2 = false, .v3 = false},
|
{.mode = GameMode::SOLO, .episode = Episode::EP4, .v1 = false, .v2 = false, .v3 = false},
|
||||||
});
|
};
|
||||||
|
|||||||
@@ -1738,7 +1738,7 @@ bool Server::update_registration_phase() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::unordered_map<uint8_t, Server::handler_t> Server::subcommand_handlers({
|
const std::unordered_map<uint8_t, Server::handler_t> Server::subcommand_handlers{
|
||||||
{0x0B, &Server::handle_CAx0B_redraw_initial_hand},
|
{0x0B, &Server::handle_CAx0B_redraw_initial_hand},
|
||||||
{0x0C, &Server::handle_CAx0C_end_redraw_initial_hand_phase},
|
{0x0C, &Server::handle_CAx0C_end_redraw_initial_hand_phase},
|
||||||
{0x0D, &Server::handle_CAx0D_end_non_action_phase},
|
{0x0D, &Server::handle_CAx0D_end_non_action_phase},
|
||||||
@@ -1762,7 +1762,7 @@ const std::unordered_map<uint8_t, Server::handler_t> Server::subcommand_handlers
|
|||||||
{0x41, &Server::handle_CAx41_map_request},
|
{0x41, &Server::handle_CAx41_map_request},
|
||||||
{0x48, &Server::handle_CAx48_end_turn},
|
{0x48, &Server::handle_CAx48_end_turn},
|
||||||
{0x49, &Server::handle_CAx49_card_counts},
|
{0x49, &Server::handle_CAx49_card_counts},
|
||||||
});
|
};
|
||||||
|
|
||||||
void Server::on_server_data_input(std::shared_ptr<Client> sender_c, const std::string& data) {
|
void Server::on_server_data_input(std::shared_ptr<Client> sender_c, const std::string& data) {
|
||||||
auto header = check_size_t<G_CardBattleCommandHeader>(data, 0xFFFF);
|
auto header = check_size_t<G_CardBattleCommandHeader>(data, 0xFFFF);
|
||||||
|
|||||||
+39
-10
@@ -158,26 +158,42 @@ std::string IntegralExpression::UnaryOperatorNode::str() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IntegralExpression::FlagLookupNode::FlagLookupNode(uint16_t flag_index) : flag_index(flag_index) {}
|
bool IntegralExpression::SectionIDLookupNode::operator==(const Node& other) const {
|
||||||
|
return (dynamic_cast<const SectionIDLookupNode*>(&other) != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
bool IntegralExpression::FlagLookupNode::operator==(const Node& other) const {
|
int64_t IntegralExpression::SectionIDLookupNode::evaluate(const Env& env) const {
|
||||||
|
return env.section_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string IntegralExpression::SectionIDLookupNode::str() const {
|
||||||
|
return "P_SID";
|
||||||
|
}
|
||||||
|
|
||||||
|
IntegralExpression::QuestFlagLookupNode::QuestFlagLookupNode(Difficulty difficulty, uint16_t flag_index)
|
||||||
|
: difficulty(difficulty), flag_index(flag_index) {}
|
||||||
|
|
||||||
|
bool IntegralExpression::QuestFlagLookupNode::operator==(const Node& other) const {
|
||||||
try {
|
try {
|
||||||
const FlagLookupNode& other_flag = dynamic_cast<const FlagLookupNode&>(other);
|
const QuestFlagLookupNode& other_flag = dynamic_cast<const QuestFlagLookupNode&>(other);
|
||||||
return other_flag.flag_index == this->flag_index;
|
return ((other_flag.difficulty == this->difficulty) && (other_flag.flag_index == this->flag_index));
|
||||||
} catch (const std::bad_cast&) {
|
} catch (const std::bad_cast&) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t IntegralExpression::FlagLookupNode::evaluate(const Env& env) const {
|
int64_t IntegralExpression::QuestFlagLookupNode::evaluate(const Env& env) const {
|
||||||
if (!env.flags) {
|
if (!env.flags) {
|
||||||
throw std::runtime_error("quest flags not available");
|
throw std::runtime_error("quest flags not available");
|
||||||
}
|
}
|
||||||
return env.flags->get(this->flag_index) ? 1 : 0;
|
Difficulty effective_difficulty = (this->difficulty == Difficulty::UNKNOWN) ? env.difficulty : this->difficulty;
|
||||||
|
return env.flags->get(effective_difficulty, this->flag_index) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IntegralExpression::FlagLookupNode::str() const {
|
std::string IntegralExpression::QuestFlagLookupNode::str() const {
|
||||||
return std::format("F_{:04X}", this->flag_index);
|
return (this->difficulty == Difficulty::UNKNOWN)
|
||||||
|
? std::format("F_{:04X}", this->flag_index)
|
||||||
|
: std::format("F_{:c}_{:04X}", abbreviation_for_difficulty(this->difficulty), this->flag_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
IntegralExpression::ChallengeCompletionLookupNode::ChallengeCompletionLookupNode(Episode episode, uint8_t stage_index)
|
IntegralExpression::ChallengeCompletionLookupNode::ChallengeCompletionLookupNode(Episode episode, uint8_t stage_index)
|
||||||
@@ -380,16 +396,29 @@ std::unique_ptr<const IntegralExpression::Node> IntegralExpression::parse_expr(s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for env lookups
|
// Check for env lookups
|
||||||
|
if (text == "P_SID") {
|
||||||
|
return std::make_unique<SectionIDLookupNode>();
|
||||||
|
}
|
||||||
if (text.starts_with("F_")) {
|
if (text.starts_with("F_")) {
|
||||||
|
Difficulty difficulty = Difficulty::UNKNOWN;
|
||||||
|
if (text.starts_with("F_N_")) {
|
||||||
|
difficulty = Difficulty::NORMAL;
|
||||||
|
} else if (text.starts_with("F_H_")) {
|
||||||
|
difficulty = Difficulty::HARD;
|
||||||
|
} else if (text.starts_with("F_V_")) {
|
||||||
|
difficulty = Difficulty::VERY_HARD;
|
||||||
|
} else if (text.starts_with("F_U_")) {
|
||||||
|
difficulty = Difficulty::ULTIMATE;
|
||||||
|
}
|
||||||
char* endptr = nullptr;
|
char* endptr = nullptr;
|
||||||
uint64_t flag = strtoul(text.data() + 2, &endptr, 16);
|
uint64_t flag = strtoul(text.data() + ((difficulty == Difficulty::UNKNOWN) ? 2 : 4), &endptr, 16);
|
||||||
if (endptr != text.data() + text.size()) {
|
if (endptr != text.data() + text.size()) {
|
||||||
throw std::runtime_error("invalid flag lookup token");
|
throw std::runtime_error("invalid flag lookup token");
|
||||||
}
|
}
|
||||||
if (flag >= 0x400) {
|
if (flag >= 0x400) {
|
||||||
throw std::runtime_error("invalid flag index");
|
throw std::runtime_error("invalid flag index");
|
||||||
}
|
}
|
||||||
return std::make_unique<FlagLookupNode>(flag);
|
return std::make_unique<QuestFlagLookupNode>(difficulty, flag);
|
||||||
}
|
}
|
||||||
if (text.starts_with("CC_")) {
|
if (text.starts_with("CC_")) {
|
||||||
Episode episode;
|
Episode episode;
|
||||||
|
|||||||
@@ -15,7 +15,9 @@
|
|||||||
class IntegralExpression {
|
class IntegralExpression {
|
||||||
public:
|
public:
|
||||||
struct Env {
|
struct Env {
|
||||||
const QuestFlagsForDifficulty* flags;
|
uint8_t section_id;
|
||||||
|
Difficulty difficulty;
|
||||||
|
const QuestFlags* flags;
|
||||||
const PlayerRecordsChallengeBB* challenge_records;
|
const PlayerRecordsChallengeBB* challenge_records;
|
||||||
std::shared_ptr<const TeamIndex::Team> team;
|
std::shared_ptr<const TeamIndex::Team> team;
|
||||||
size_t num_players;
|
size_t num_players;
|
||||||
@@ -105,15 +107,25 @@ protected:
|
|||||||
std::unique_ptr<const Node> sub;
|
std::unique_ptr<const Node> sub;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlagLookupNode : public Node {
|
class SectionIDLookupNode : public Node {
|
||||||
public:
|
public:
|
||||||
FlagLookupNode(uint16_t flag_index);
|
SectionIDLookupNode() = default;
|
||||||
virtual ~FlagLookupNode() = default;
|
virtual ~SectionIDLookupNode() = default;
|
||||||
|
virtual bool operator==(const Node& other) const;
|
||||||
|
virtual int64_t evaluate(const Env& env) const;
|
||||||
|
virtual std::string str() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QuestFlagLookupNode : public Node {
|
||||||
|
public:
|
||||||
|
QuestFlagLookupNode(Difficulty difficulty, uint16_t flag_index);
|
||||||
|
virtual ~QuestFlagLookupNode() = default;
|
||||||
virtual bool operator==(const Node& other) const;
|
virtual bool operator==(const Node& other) const;
|
||||||
virtual int64_t evaluate(const Env& env) const;
|
virtual int64_t evaluate(const Env& env) const;
|
||||||
virtual std::string str() const;
|
virtual std::string str() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Difficulty difficulty;
|
||||||
uint16_t flag_index;
|
uint16_t flag_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -6,10 +6,10 @@
|
|||||||
#include "ItemParameterTable.hh"
|
#include "ItemParameterTable.hh"
|
||||||
#include "StaticGameData.hh"
|
#include "StaticGameData.hh"
|
||||||
|
|
||||||
const std::vector<uint8_t> ItemData::StackLimits::DEFAULT_TOOL_LIMITS_DC_NTE({10});
|
const std::vector<uint8_t> ItemData::StackLimits::DEFAULT_TOOL_LIMITS_DC_NTE{10};
|
||||||
const std::vector<uint8_t> ItemData::StackLimits::DEFAULT_TOOL_LIMITS_V1_V2({10, 10, 1, 10, 10, 10, 10, 10, 10, 1});
|
const std::vector<uint8_t> ItemData::StackLimits::DEFAULT_TOOL_LIMITS_V1_V2{10, 10, 1, 10, 10, 10, 10, 10, 10, 1};
|
||||||
const std::vector<uint8_t> ItemData::StackLimits::DEFAULT_TOOL_LIMITS_V3_V4(
|
const std::vector<uint8_t> ItemData::StackLimits::DEFAULT_TOOL_LIMITS_V3_V4{
|
||||||
{10, 10, 1, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 99, 1});
|
10, 10, 1, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 99, 1};
|
||||||
|
|
||||||
const ItemData::StackLimits ItemData::StackLimits::DEFAULT_STACK_LIMITS_DC_NTE(
|
const ItemData::StackLimits ItemData::StackLimits::DEFAULT_STACK_LIMITS_DC_NTE(
|
||||||
Version::DC_NTE, ItemData::StackLimits::DEFAULT_TOOL_LIMITS_DC_NTE, 999999);
|
Version::DC_NTE, ItemData::StackLimits::DEFAULT_TOOL_LIMITS_DC_NTE, 999999);
|
||||||
|
|||||||
@@ -4735,7 +4735,9 @@ std::shared_ptr<Lobby> create_game_generic(
|
|||||||
|
|
||||||
if (quest_flag_rewrites && !quest_flag_rewrites->empty()) {
|
if (quest_flag_rewrites && !quest_flag_rewrites->empty()) {
|
||||||
IntegralExpression::Env env = {
|
IntegralExpression::Env env = {
|
||||||
.flags = &p->quest_flags.array(difficulty),
|
.section_id = game->effective_section_id(),
|
||||||
|
.difficulty = game->difficulty,
|
||||||
|
.flags = &p->quest_flags,
|
||||||
.challenge_records = &p->challenge_records,
|
.challenge_records = &p->challenge_records,
|
||||||
.team = creator_c->team(),
|
.team = creator_c->team(),
|
||||||
.num_players = 1,
|
.num_players = 1,
|
||||||
|
|||||||
+6
-6
@@ -33,7 +33,7 @@ inline uint8_t get_pre_v1_subcommand(Version v, uint8_t nte_subcommand, uint8_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::unordered_set<uint32_t> v2_crypt_initial_client_commands({
|
const std::unordered_set<uint32_t> v2_crypt_initial_client_commands{
|
||||||
0x00260088, // (17) DCNTE license check
|
0x00260088, // (17) DCNTE license check
|
||||||
0x00B0008B, // (02) DCNTE login
|
0x00B0008B, // (02) DCNTE login
|
||||||
0x00B0018B, // (02) DCNTE login (UDP off)
|
0x00B0018B, // (02) DCNTE login (UDP off)
|
||||||
@@ -52,20 +52,20 @@ const std::unordered_set<uint32_t> v2_crypt_initial_client_commands({
|
|||||||
0x0130019D, // (02) DCv2/GCNTE extended login (UDP off)
|
0x0130019D, // (02) DCv2/GCNTE extended login (UDP off)
|
||||||
// Note: PSO PC initial commands are not listed here because we don't use a detector encryption for PSO PC
|
// Note: PSO PC initial commands are not listed here because we don't use a detector encryption for PSO PC
|
||||||
// (instead, we use the split reconnect command to send PC to a different port).
|
// (instead, we use the split reconnect command to send PC to a different port).
|
||||||
});
|
};
|
||||||
const std::unordered_set<uint32_t> v3_crypt_initial_client_commands({
|
const std::unordered_set<uint32_t> v3_crypt_initial_client_commands{
|
||||||
0x00E000DB, // (17) GC/XB license check
|
0x00E000DB, // (17) GC/XB license check
|
||||||
0x00EC009E, // (02) GC login
|
0x00EC009E, // (02) GC login
|
||||||
0x00EC019E, // (02) GC login (UDP off)
|
0x00EC019E, // (02) GC login (UDP off)
|
||||||
0x0150009E, // (02) GC extended login
|
0x0150009E, // (02) GC extended login
|
||||||
0x0150019E, // (02) GC extended login (UDP off)
|
0x0150019E, // (02) GC extended login (UDP off)
|
||||||
});
|
};
|
||||||
|
|
||||||
const std::unordered_set<std::string> bb_crypt_initial_client_commands({
|
const std::unordered_set<std::string> bb_crypt_initial_client_commands{
|
||||||
std::string("\xB4\x00\x93\x00\x00\x00\x00\x00", 8),
|
std::string("\xB4\x00\x93\x00\x00\x00\x00\x00", 8),
|
||||||
std::string("\xAC\x00\x93\x00\x00\x00\x00\x00", 8),
|
std::string("\xAC\x00\x93\x00\x00\x00\x00\x00", 8),
|
||||||
std::string("\xDC\x00\xDB\x00\x00\x00\x00\x00", 8),
|
std::string("\xDC\x00\xDB\x00\x00\x00\x00\x00", 8),
|
||||||
});
|
};
|
||||||
|
|
||||||
void send_command(
|
void send_command(
|
||||||
std::shared_ptr<Client> c,
|
std::shared_ptr<Client> c,
|
||||||
|
|||||||
@@ -515,7 +515,7 @@ struct WeaponRootT {
|
|||||||
U32T<BE> favored_grind_range_table; // {u32 min, u32 max}[6]
|
U32T<BE> favored_grind_range_table; // {u32 min, u32 max}[6]
|
||||||
} __packed_ws_be__(WeaponRootT, 0x20);
|
} __packed_ws_be__(WeaponRootT, 0x20);
|
||||||
|
|
||||||
const std::array<std::pair<uint8_t, uint8_t>, 0x48> WeaponShopRandomSet::type_defs({
|
const std::array<std::pair<uint8_t, uint8_t>, 0x48> WeaponShopRandomSet::type_defs{{
|
||||||
/* 00 */ {0x01, 0x00}, // Saber
|
/* 00 */ {0x01, 0x00}, // Saber
|
||||||
/* 01 */ {0x01, 0x01}, // Brand
|
/* 01 */ {0x01, 0x01}, // Brand
|
||||||
/* 02 */ {0x01, 0x02}, // Buster
|
/* 02 */ {0x01, 0x02}, // Buster
|
||||||
@@ -588,9 +588,9 @@ const std::array<std::pair<uint8_t, uint8_t>, 0x48> WeaponShopRandomSet::type_de
|
|||||||
/* 45 */ {0x0A, 0x05}, // MACE OF ADAMAN
|
/* 45 */ {0x0A, 0x05}, // MACE OF ADAMAN
|
||||||
/* 46 */ {0x0C, 0x05}, // ICE STAFF:DAGON
|
/* 46 */ {0x0C, 0x05}, // ICE STAFF:DAGON
|
||||||
/* 47 */ {0x0B, 0x05}, // BRAVE HAMMER
|
/* 47 */ {0x0B, 0x05}, // BRAVE HAMMER
|
||||||
});
|
}};
|
||||||
|
|
||||||
const std::array<std::pair<uint8_t, uint8_t>, 10> WeaponShopRandomSet::type_defs_39({
|
const std::array<std::pair<uint8_t, uint8_t>, 10> WeaponShopRandomSet::type_defs_39{{
|
||||||
// Indexed by section_id
|
// Indexed by section_id
|
||||||
{0x28, 0x00}, // HARISEN BATTLE FAN
|
{0x28, 0x00}, // HARISEN BATTLE FAN
|
||||||
{0x2A, 0x00}, // AKIKO'S WOK
|
{0x2A, 0x00}, // AKIKO'S WOK
|
||||||
@@ -602,9 +602,9 @@ const std::array<std::pair<uint8_t, uint8_t>, 10> WeaponShopRandomSet::type_defs
|
|||||||
{0x59, 0x00}, // BROOM
|
{0x59, 0x00}, // BROOM
|
||||||
{0x8A, 0x00}, // SANGE
|
{0x8A, 0x00}, // SANGE
|
||||||
{0x99, 0x00}, // ANGEL HARP
|
{0x99, 0x00}, // ANGEL HARP
|
||||||
});
|
}};
|
||||||
|
|
||||||
const std::array<std::pair<uint8_t, uint8_t>, 10> WeaponShopRandomSet::type_defs_3A({
|
const std::array<std::pair<uint8_t, uint8_t>, 10> WeaponShopRandomSet::type_defs_3A{{
|
||||||
// Indexed by section_id
|
// Indexed by section_id
|
||||||
{0x99, 0x00}, // ANGEL HARP
|
{0x99, 0x00}, // ANGEL HARP
|
||||||
{0x64, 0x00}, // CHAMELEON SCYTHE
|
{0x64, 0x00}, // CHAMELEON SCYTHE
|
||||||
@@ -616,7 +616,7 @@ const std::array<std::pair<uint8_t, uint8_t>, 10> WeaponShopRandomSet::type_defs
|
|||||||
{0x2A, 0x00}, // AKIKO'S WOK
|
{0x2A, 0x00}, // AKIKO'S WOK
|
||||||
{0x48, 0x00}, // SAMBA MARACAS
|
{0x48, 0x00}, // SAMBA MARACAS
|
||||||
{0x35, 0x00}, // CRAZY TUNE
|
{0x35, 0x00}, // CRAZY TUNE
|
||||||
});
|
}};
|
||||||
|
|
||||||
const std::array<int8_t, 20> WeaponShopRandomSet::bonus_values{
|
const std::array<int8_t, 20> WeaponShopRandomSet::bonus_values{
|
||||||
-50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50};
|
-50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50};
|
||||||
|
|||||||
@@ -121,13 +121,13 @@ static const std::array<const char*, 10> section_id_to_name = {
|
|||||||
static const std::array<const char*, 10> section_id_to_abbreviation = {
|
static const std::array<const char*, 10> section_id_to_abbreviation = {
|
||||||
"Vir", "Grn", "Sky", "Blu", "Prp", "Pnk", "Red", "Orn", "Ylw", "Wht"};
|
"Vir", "Grn", "Sky", "Blu", "Prp", "Pnk", "Red", "Orn", "Ylw", "Wht"};
|
||||||
|
|
||||||
const std::unordered_map<std::string, uint8_t> name_to_section_id({{"viridia", 0},
|
const std::unordered_map<std::string, uint8_t> name_to_section_id{
|
||||||
// Greennill is spelled Greenill in some places, so we accept both spellings
|
// Greennill is spelled Greenill in some places, so we accept both spellings
|
||||||
{"greennill", 1}, {"greenill", 1}, {"skyly", 2}, {"bluefull", 3}, {"purplenum", 4}, {"pinkal", 5}, {"redria", 6},
|
{"viridia", 0}, {"greennill", 1}, {"greenill", 1}, {"skyly", 2}, {"bluefull", 3}, {"purplenum", 4}, {"pinkal", 5},
|
||||||
{"oran", 7}, {"yellowboze", 8}, {"whitill", 9},
|
{"redria", 6}, {"oran", 7}, {"yellowboze", 8}, {"whitill", 9},
|
||||||
|
|
||||||
// Shortcuts for chat commands
|
// Shortcuts for chat commands
|
||||||
{"b", 3}, {"g", 1}, {"o", 7}, {"pi", 5}, {"pu", 4}, {"r", 6}, {"s", 2}, {"v", 0}, {"w", 9}, {"y", 8}});
|
{"b", 3}, {"g", 1}, {"o", 7}, {"pi", 5}, {"pu", 4}, {"r", 6}, {"s", 2}, {"v", 0}, {"w", 9}, {"y", 8}};
|
||||||
|
|
||||||
const std::vector<std::string> lobby_event_to_name = {
|
const std::vector<std::string> lobby_event_to_name = {
|
||||||
"none", "xmas", "none", "val", "easter", "hallo", "sonic", "newyear",
|
"none", "xmas", "none", "val", "easter", "hallo", "sonic", "newyear",
|
||||||
@@ -673,10 +673,10 @@ char char_for_challenge_rank(uint8_t rank) {
|
|||||||
return "BAS"[rank];
|
return "BAS"[rank];
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::array<size_t, 4> DEFAULT_MIN_LEVELS_V123({0, 19, 39, 79});
|
const std::array<size_t, 4> DEFAULT_MIN_LEVELS_V123{{0, 19, 39, 79}};
|
||||||
const std::array<size_t, 4> DEFAULT_MIN_LEVELS_V4_EP1({0, 19, 39, 79});
|
const std::array<size_t, 4> DEFAULT_MIN_LEVELS_V4_EP1{{0, 19, 39, 79}};
|
||||||
const std::array<size_t, 4> DEFAULT_MIN_LEVELS_V4_EP2({0, 29, 49, 89});
|
const std::array<size_t, 4> DEFAULT_MIN_LEVELS_V4_EP2{{0, 29, 49, 89}};
|
||||||
const std::array<size_t, 4> DEFAULT_MIN_LEVELS_V4_EP4({0, 39, 79, 109});
|
const std::array<size_t, 4> DEFAULT_MIN_LEVELS_V4_EP4{{0, 39, 79, 109}};
|
||||||
|
|
||||||
const std::array<GameMode, 2> ALL_GAME_MODES_V1 = {GameMode::NORMAL, GameMode::BATTLE};
|
const std::array<GameMode, 2> ALL_GAME_MODES_V1 = {GameMode::NORMAL, GameMode::BATTLE};
|
||||||
const std::array<GameMode, 3> ALL_GAME_MODES_V23 = {GameMode::NORMAL, GameMode::BATTLE, GameMode::CHALLENGE};
|
const std::array<GameMode, 3> ALL_GAME_MODES_V23 = {GameMode::NORMAL, GameMode::BATTLE, GameMode::CHALLENGE};
|
||||||
|
|||||||
+22
-22
@@ -1338,35 +1338,35 @@
|
|||||||
// doesn't have direct access to the client's quest flags from their save file.
|
// doesn't have direct access to the client's quest flags from their save file.
|
||||||
// If you use an expression, the format is the same as the AvailableIf and EnabledIf fields in quest JSONs (see
|
// If you use an expression, the format is the same as the AvailableIf and EnabledIf fields in quest JSONs (see
|
||||||
// system/quests/retrieval/q058.json for details). Note that the expression is only evaluated at the time the game is
|
// system/quests/retrieval/q058.json for details). Note that the expression is only evaluated at the time the game is
|
||||||
// created, and the player-specific tokens like C_EpX_YY refer to the player who created the game.
|
// created, and the player-specific tokens like CC_EpX_YY refer to the player who created the game.
|
||||||
// The UnlockAllAreas option is now gone; if you want the same behavior as if it were enabled, uncomment all the
|
// The UnlockAllAreas option is now gone; if you want the same behavior as if it were enabled, uncomment all the
|
||||||
// "area unlocks" lines below. Note that some late PSOBB client versions (for example, the Tethealla client) open all
|
// "area unlock" lines below. Note that some late PSOBB client versions (for example, the Tethealla client) open all
|
||||||
// areas by default, so the area unlock flags have no effect for them.
|
// areas by default, so the area unlock flags have no effect for them.
|
||||||
"QuestFlagRewritesV1V2": {
|
"QuestFlagRewritesV1V2": {
|
||||||
// "F_0017": true, // Ep1 area unlocks
|
// "F_0017": true, // Ep1 area unlock (Caves)
|
||||||
// "F_0020": true, // Ep1 area unlocks
|
// "F_0020": true, // Ep1 area unlock (Mines)
|
||||||
// "F_002A": true, // Ep1 area unlocks
|
// "F_002A": true, // Ep1 area unlock (Ruins)
|
||||||
},
|
},
|
||||||
"QuestFlagRewritesV3": {
|
"QuestFlagRewritesV3": {
|
||||||
// "F_0017": true, // Ep1 area unlocks
|
// "F_0017": true, // Ep1 area unlock (Caves)
|
||||||
// "F_0020": true, // Ep1 area unlocks
|
// "F_0020": true, // Ep1 area unlock (Mines)
|
||||||
// "F_002A": true, // Ep1 area unlocks
|
// "F_002A": true, // Ep1 area unlock (Ruins)
|
||||||
// "F_004C": true, // Ep2 area unlocks
|
// "F_004C": true, // Ep2 area unlock (VR Spaceship)
|
||||||
// "F_004F": true, // Ep2 area unlocks
|
// "F_004F": true, // Ep2 area unlock (CCA)
|
||||||
// "F_0052": true, // Ep2 area unlocks
|
// "F_0052": true, // Ep2 area unlock (Seabed)
|
||||||
},
|
},
|
||||||
"QuestFlagRewritesV4": {
|
"QuestFlagRewritesV4": {
|
||||||
// "F_01F9": true, // Ep1 area unlocks
|
// "F_01F9": true, // Ep1 area unlock (Caves)
|
||||||
// "F_0201": true, // Ep1 area unlocks
|
// "F_0201": true, // Ep1 area unlock (Mines)
|
||||||
// "F_0207": true, // Ep1 area unlocks
|
// "F_0207": true, // Ep1 area unlock (Ruins)
|
||||||
// "F_021B": true, // Ep2 area unlocks
|
// "F_021B": true, // Ep2 area unlock (VR Spaceship)
|
||||||
// "F_0225": true, // Ep2 area unlocks
|
// "F_0225": true, // Ep2 area unlock (CCA)
|
||||||
// "F_022F": true, // Ep2 area unlocks
|
// "F_022F": true, // Ep2 area unlock (Seabed)
|
||||||
// "F_02BD": true, // Ep4 area unlocks
|
// "F_02BD": true, // Ep4 area unlock (Crater West)
|
||||||
// "F_02BE": true, // Ep4 area unlocks
|
// "F_02BE": true, // Ep4 area unlock (Crater South)
|
||||||
// "F_02BF": true, // Ep4 area unlocks
|
// "F_02BF": true, // Ep4 area unlock (Crater North)
|
||||||
// "F_02C0": true, // Ep4 area unlocks
|
// "F_02C0": true, // Ep4 area unlock (Crater Interior)
|
||||||
// "F_02C1": true, // Ep4 area unlocks
|
// "F_02C1": true, // Ep4 area unlock (Desert)
|
||||||
"F_0046": false, // Ep2 CCA door lock fix
|
"F_0046": false, // Ep2 CCA door lock fix
|
||||||
"F_0047": false, // Ep2 CCA door lock fix
|
"F_0047": false, // Ep2 CCA door lock fix
|
||||||
"F_0048": false, // Ep2 CCA door lock fix
|
"F_0048": false, // Ep2 CCA door lock fix
|
||||||
|
|||||||
@@ -5,7 +5,10 @@
|
|||||||
// Quests that are considered unavailable don't appear in the quest menu at all. To set a condition for a quest to be
|
// Quests that are considered unavailable don't appear in the quest menu at all. To set a condition for a quest to be
|
||||||
// available, you can set AvailableIf in the quest's JSON file. The value for AvailableIf should be an expression
|
// available, you can set AvailableIf in the quest's JSON file. The value for AvailableIf should be an expression
|
||||||
// that tests any of the following:
|
// that tests any of the following:
|
||||||
// F_XXXX: Quest flag specified in hex (e.g. F_014D)
|
// P_SID: Current effective section ID for the game; see name_to_section_id in StaticGameData.cc for values
|
||||||
|
// F_XXXX: Quest flag specified in hex (e.g. F_014D) for the difficulty the player is currently playing in
|
||||||
|
// F_N_XXXX, F_H_XXXX, F_V_XXXX, F_U_XXXX: Same as F_XXXX, but read from a specific difficulty regardless of which
|
||||||
|
// difficulty the player is currently playing in
|
||||||
// CC_EpX_Y: Whether or not Challenge stage X in Episode Y is complete (e.g. CC_Ep1_7)
|
// CC_EpX_Y: Whether or not Challenge stage X in Episode Y is complete (e.g. CC_Ep1_7)
|
||||||
// T_ZZZ: Whether or not the player's BB team has reward with key ZZZ (as defined in TeamRewards in config.json)
|
// T_ZZZ: Whether or not the player's BB team has reward with key ZZZ (as defined in TeamRewards in config.json)
|
||||||
// V_NumPlayers: The number of players in the current game
|
// V_NumPlayers: The number of players in the current game
|
||||||
|
|||||||
Reference in New Issue
Block a user