use new phosg JSON interface

This commit is contained in:
Martin Michelsen
2023-08-28 21:06:03 -07:00
parent a842880123
commit 466eb49c55
17 changed files with 404 additions and 487 deletions
+122 -143
View File
@@ -1083,151 +1083,45 @@ void PlayerConfig::encrypt(uint8_t basis) {
this->basis = basis;
}
HPType hp_type_for_name(const char* name) {
if (!strcmp(name, "DEFEAT_PLAYER")) {
return HPType::DEFEAT_PLAYER;
} else if (!strcmp(name, "DEFEAT_TEAM")) {
return HPType::DEFEAT_TEAM;
} else if (!strcmp(name, "COMMON_HP")) {
return HPType::COMMON_HP;
} else {
throw out_of_range("invalid HP type name");
}
}
const char* name_for_hp_type(HPType hp_type) {
switch (hp_type) {
case HPType::DEFEAT_PLAYER:
return "DEFEAT_PLAYER";
case HPType::DEFEAT_TEAM:
return "DEFEAT_TEAM";
case HPType::COMMON_HP:
return "COMMON_HP";
default:
throw out_of_range("invalid HP type");
}
}
DiceExchangeMode dice_exchange_mode_for_name(const char* name) {
if (!strcmp(name, "HIGH_ATK")) {
return DiceExchangeMode::HIGH_ATK;
} else if (!strcmp(name, "HIGH_DEF")) {
return DiceExchangeMode::HIGH_DEF;
} else if (!strcmp(name, "NONE")) {
return DiceExchangeMode::NONE;
} else {
throw out_of_range("invalid dice exchange mode name");
}
}
const char* name_for_dice_exchange_mode(DiceExchangeMode dice_exchange_mode) {
switch (dice_exchange_mode) {
case DiceExchangeMode::HIGH_ATK:
return "HIGH_ATK";
case DiceExchangeMode::HIGH_DEF:
return "HIGH_DEF";
case DiceExchangeMode::NONE:
return "NONE";
default:
throw out_of_range("invalid dice exchange mode");
}
}
AllowedCards allowed_cards_for_name(const char* name) {
if (!strcmp(name, "ALL")) {
return AllowedCards::ALL;
} else if (!strcmp(name, "N_ONLY")) {
return AllowedCards::N_ONLY;
} else if (!strcmp(name, "N_R_ONLY")) {
return AllowedCards::N_R_ONLY;
} else if (!strcmp(name, "N_R_S_ONLY")) {
return AllowedCards::N_R_S_ONLY;
} else {
throw out_of_range("invalid allowed cards name");
}
}
const char* name_for_allowed_cards(AllowedCards allowed_cards) {
switch (allowed_cards) {
case AllowedCards::ALL:
return "ALL";
case AllowedCards::N_ONLY:
return "N_ONLY";
case AllowedCards::N_R_ONLY:
return "N_R_ONLY";
case AllowedCards::N_R_S_ONLY:
return "N_R_S_ONLY";
default:
throw out_of_range("invalid allowed cards");
}
}
Rules::Rules() {
this->clear();
}
template <typename IntT>
void get_json_optional_int(const JSONObject::dict_type& dict, IntT& result, const char* key) {
try {
auto value_json = dict.at(key);
if (value_json->is_int()) {
result = value_json->as_int();
} else if (value_json->is_bool()) {
result = value_json->as_bool() ? 1 : 0;
} else {
throw runtime_error("int-valued field is not int or bool");
}
} catch (const out_of_range&) {
}
};
template <typename EnumT>
void get_json_optional_enum(const JSONObject::dict_type& dict, EnumT& result, const char* key, EnumT (*parse_str)(const char*)) {
try {
auto value_json = dict.at(key);
if (value_json->is_string()) {
result = parse_str(value_json->as_string().c_str());
} else if (value_json->is_int()) {
result = static_cast<EnumT>(value_json->as_int());
} else {
throw runtime_error("enum-valued field is not int or string");
}
} catch (const out_of_range&) {
}
};
Rules::Rules(shared_ptr<const JSONObject> json) {
Rules::Rules(const JSON& json) {
this->clear();
auto dict = json->as_dict();
get_json_optional_int(dict, this->overall_time_limit, "overall_time_limit");
get_json_optional_int(dict, this->phase_time_limit, "phase_time_limit");
get_json_optional_enum(dict, this->allowed_cards, "allowed_cards", allowed_cards_for_name);
get_json_optional_int(dict, this->min_dice, "min_dice");
get_json_optional_int(dict, this->max_dice, "max_dice");
get_json_optional_int(dict, this->disable_deck_shuffle, "disable_deck_shuffle");
get_json_optional_int(dict, this->disable_deck_loop, "disable_deck_loop");
get_json_optional_int(dict, this->char_hp, "char_hp");
get_json_optional_enum(dict, this->hp_type, "hp_type", hp_type_for_name);
get_json_optional_int(dict, this->no_assist_cards, "no_assist_cards");
get_json_optional_int(dict, this->disable_dialogue, "disable_dialogue");
get_json_optional_enum(dict, this->dice_exchange_mode, "dice_exchange_mode", dice_exchange_mode_for_name);
get_json_optional_int(dict, this->disable_dice_boost, "disable_dice_boost");
auto dict = json.as_dict();
this->overall_time_limit = json.get("overall_time_limit", this->overall_time_limit);
this->phase_time_limit = json.get("phase_time_limit", this->phase_time_limit);
this->allowed_cards = json.get_enum("allowed_cards", this->allowed_cards);
this->min_dice = json.get("min_dice", this->min_dice);
this->max_dice = json.get("max_dice", this->max_dice);
this->disable_deck_shuffle = json.get("disable_deck_shuffle", this->disable_deck_shuffle);
this->disable_deck_loop = json.get("disable_deck_loop", this->disable_deck_loop);
this->char_hp = json.get("char_hp", this->char_hp);
this->hp_type = json.get_enum("hp_type", this->hp_type);
this->no_assist_cards = json.get("no_assist_cards", this->no_assist_cards);
this->disable_dialogue = json.get("disable_dialogue", this->disable_dialogue);
this->dice_exchange_mode = json.get_enum("dice_exchange_mode", this->dice_exchange_mode);
this->disable_dice_boost = json.get("disable_dice_boost", this->disable_dice_boost);
}
shared_ptr<JSONObject> Rules::json() const {
unordered_map<string, shared_ptr<JSONObject>> dict;
dict.emplace("overall_time_limit", make_json_int(this->overall_time_limit));
dict.emplace("phase_time_limit", make_json_int(this->phase_time_limit));
dict.emplace("allowed_cards", make_json_str(name_for_allowed_cards(this->allowed_cards)));
dict.emplace("min_dice", make_json_int(this->min_dice));
dict.emplace("max_dice", make_json_int(this->max_dice));
dict.emplace("disable_deck_shuffle", make_json_bool(this->disable_deck_shuffle));
dict.emplace("disable_deck_loop", make_json_bool(this->disable_deck_loop));
dict.emplace("char_hp", make_json_int(this->char_hp));
dict.emplace("hp_type", make_json_str(name_for_hp_type(this->hp_type)));
dict.emplace("no_assist_cards", make_json_bool(this->no_assist_cards));
dict.emplace("disable_dialogue", make_json_bool(this->disable_dialogue));
dict.emplace("dice_exchange_mode", make_json_str(name_for_dice_exchange_mode(this->dice_exchange_mode)));
dict.emplace("disable_dice_boost", make_json_bool(this->disable_dice_boost));
return shared_ptr<JSONObject>(new JSONObject(std::move(dict)));
JSON Rules::json() const {
unordered_map<string, JSON> dict;
dict.emplace("overall_time_limit", this->overall_time_limit);
dict.emplace("phase_time_limit", this->phase_time_limit);
dict.emplace("allowed_cards", name_for_enum(this->allowed_cards));
dict.emplace("min_dice", this->min_dice);
dict.emplace("max_dice", this->max_dice);
dict.emplace("disable_deck_shuffle", this->disable_deck_shuffle);
dict.emplace("disable_deck_loop", this->disable_deck_loop);
dict.emplace("char_hp", this->char_hp);
dict.emplace("hp_type", name_for_enum(this->hp_type));
dict.emplace("no_assist_cards", this->no_assist_cards);
dict.emplace("disable_dialogue", this->disable_dialogue);
dict.emplace("dice_exchange_mode", name_for_enum(this->dice_exchange_mode));
dict.emplace("disable_dice_boost", this->disable_dice_boost);
return JSON(std::move(dict));
}
void Rules::set_defaults() {
@@ -2106,15 +2000,15 @@ set<uint32_t> MapIndex::all_numbers() const {
COMDeckIndex::COMDeckIndex(const string& filename) {
try {
auto json = JSONObject::parse(load_file(filename));
for (const auto& def_json : json->as_list()) {
auto json = JSON::parse(load_file(filename));
for (const auto& def_json : json.as_list()) {
auto& def = this->decks.emplace_back(new COMDeckDefinition());
def->index = this->decks.size() - 1;
def->player_name = def_json->at(0)->as_string();
def->deck_name = def_json->at(1)->as_string();
auto card_ids_json = def_json->at(2)->as_list();
def->player_name = def_json.at(0).as_string();
def->deck_name = def_json.at(1).as_string();
auto card_ids_json = def_json.at(2);
for (size_t z = 0; z < 0x1F; z++) {
def->card_ids[z] = card_ids_json.at(z)->as_int();
def->card_ids[z] = card_ids_json.at(z).as_int();
}
if (!this->decks_by_name.emplace(def->deck_name, def).second) {
throw runtime_error("duplicate COM deck name: " + def->deck_name);
@@ -2142,3 +2036,88 @@ shared_ptr<const COMDeckDefinition> COMDeckIndex::random_deck() const {
}
} // namespace Episode3
template <>
Episode3::HPType enum_for_name<Episode3::HPType>(const char* name) {
if (!strcmp(name, "DEFEAT_PLAYER")) {
return Episode3::HPType::DEFEAT_PLAYER;
} else if (!strcmp(name, "DEFEAT_TEAM")) {
return Episode3::HPType::DEFEAT_TEAM;
} else if (!strcmp(name, "COMMON_HP")) {
return Episode3::HPType::COMMON_HP;
} else {
throw out_of_range("invalid HP type name");
}
}
template <>
const char* name_for_enum<Episode3::HPType>(Episode3::HPType hp_type) {
switch (hp_type) {
case Episode3::HPType::DEFEAT_PLAYER:
return "DEFEAT_PLAYER";
case Episode3::HPType::DEFEAT_TEAM:
return "DEFEAT_TEAM";
case Episode3::HPType::COMMON_HP:
return "COMMON_HP";
default:
throw out_of_range("invalid HP type");
}
}
template <>
Episode3::DiceExchangeMode enum_for_name<Episode3::DiceExchangeMode>(const char* name) {
if (!strcmp(name, "HIGH_ATK")) {
return Episode3::DiceExchangeMode::HIGH_ATK;
} else if (!strcmp(name, "HIGH_DEF")) {
return Episode3::DiceExchangeMode::HIGH_DEF;
} else if (!strcmp(name, "NONE")) {
return Episode3::DiceExchangeMode::NONE;
} else {
throw out_of_range("invalid dice exchange mode name");
}
}
template <>
const char* name_for_enum<Episode3::DiceExchangeMode>(Episode3::DiceExchangeMode dice_exchange_mode) {
switch (dice_exchange_mode) {
case Episode3::DiceExchangeMode::HIGH_ATK:
return "HIGH_ATK";
case Episode3::DiceExchangeMode::HIGH_DEF:
return "HIGH_DEF";
case Episode3::DiceExchangeMode::NONE:
return "NONE";
default:
throw out_of_range("invalid dice exchange mode");
}
}
template <>
Episode3::AllowedCards enum_for_name<Episode3::AllowedCards>(const char* name) {
if (!strcmp(name, "ALL")) {
return Episode3::AllowedCards::ALL;
} else if (!strcmp(name, "N_ONLY")) {
return Episode3::AllowedCards::N_ONLY;
} else if (!strcmp(name, "N_R_ONLY")) {
return Episode3::AllowedCards::N_R_ONLY;
} else if (!strcmp(name, "N_R_S_ONLY")) {
return Episode3::AllowedCards::N_R_S_ONLY;
} else {
throw out_of_range("invalid allowed cards name");
}
}
template <>
const char* name_for_enum<Episode3::AllowedCards>(Episode3::AllowedCards allowed_cards) {
switch (allowed_cards) {
case Episode3::AllowedCards::ALL:
return "ALL";
case Episode3::AllowedCards::N_ONLY:
return "N_ONLY";
case Episode3::AllowedCards::N_R_ONLY:
return "N_R_ONLY";
case Episode3::AllowedCards::N_R_S_ONLY:
return "N_R_S_ONLY";
default:
throw out_of_range("invalid allowed cards");
}
}