diff options
Diffstat (limited to 'src/map/itemdb.cpp')
-rw-r--r-- | src/map/itemdb.cpp | 173 |
1 files changed, 72 insertions, 101 deletions
diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index 50cc5c4..7dd725e 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -29,20 +29,24 @@ #include "../generic/db.hpp" #include "../io/cxxstdio.hpp" -#include "../io/read.hpp" +#include "../io/extract.hpp" +#include "../io/line.hpp" #include "../mmo/config_parse.hpp" -#include "../mmo/extract.hpp" #include "../mmo/extract_enums.hpp" +#include "../ast/item.hpp" + +#include "globals.hpp" +#include "script-parse.hpp" + #include "../poison.hpp" namespace tmwa { -static -Map<ItemNameId, struct item_data> item_db; - +namespace map +{ // Function declarations /*========================================== @@ -51,24 +55,24 @@ Map<ItemNameId, struct item_data> item_db; */ // name = item alias, so we should find items aliases first. if not found then look for "jname" (full name) static -void itemdb_searchname_sub(struct item_data *item, ItemName str, struct item_data **dst) +void itemdb_searchname_sub(Borrowed<struct item_data> item, ItemName str, Borrowed<Option<Borrowed<struct item_data>>> dst) { if (item->name == str) - *dst = item; + *dst = Some(item); } /*========================================== * 名前で検索 *------------------------------------------ */ -struct item_data *itemdb_searchname(XString str_) +Option<Borrowed<struct item_data>> itemdb_searchname(XString str_) { ItemName str = stringish<ItemName>(str_); if (XString(str) != str_) - return nullptr; - struct item_data *item = nullptr; + return None; + Option<P<struct item_data>> item = None; for (auto& pair : item_db) - itemdb_searchname_sub(&pair.second, str, &item); + itemdb_searchname_sub(borrow(pair.second), str, borrow(item)); return item; } @@ -76,7 +80,7 @@ struct item_data *itemdb_searchname(XString str_) * DBの存在確認 *------------------------------------------ */ -struct item_data *itemdb_exists(ItemNameId nameid) +Option<Borrowed<struct item_data>> itemdb_exists(ItemNameId nameid) { return item_db.search(nameid); } @@ -85,13 +89,16 @@ struct item_data *itemdb_exists(ItemNameId nameid) * DBの検索 *------------------------------------------ */ -struct item_data *itemdb_search(ItemNameId nameid) +Borrowed<struct item_data> itemdb_search(ItemNameId nameid) { - struct item_data *id = item_db.search(nameid); - if (id) + Option<P<struct item_data>> id_ = item_db.search(nameid); + OMATCH_BEGIN_SOME (id, id_) + { return id; + } + OMATCH_END (); - id = item_db.init(nameid); + P<struct item_data> id = item_db.init(nameid); id->nameid = nameid; id->value_buy = 10; @@ -123,10 +130,8 @@ int itemdb_isequip(ItemNameId nameid) * *------------------------------------------ */ -int itemdb_isequip2(struct item_data *data) +bool itemdb_isequip2(Borrowed<struct item_data> data) { - if (!data) - return false; ItemType type = data->type; return !(type == ItemType::USE || type == ItemType::_2 @@ -149,99 +154,64 @@ int itemdb_isequip3(ItemNameId nameid) bool itemdb_readdb(ZString filename) { - bool rv = true; - - int ln = 0, lines = 0; + io::LineCharReader in(filename); + if (!in.is_open()) { - io::ReadFile in(filename); - - if (!in.is_open()) - { - PRINTF("can't read %s\n"_fmt, filename); - return false; - } + PRINTF("can't read %s\n"_fmt, filename); + return false; + } - lines = 0; + int ln = 0; - AString line; - while (in.getline(line)) + while (true) + { + auto res = TRY_UNWRAP(ast::item::parse_item(in), + { + PRINTF("read %s done (count=%d)\n"_fmt, filename, ln); + return true; + }); + if (res.get_failure()) + PRINTF("%s\n"_fmt, res.get_failure()); + ast::item::ItemOrComment ioc = TRY_UNWRAP(std::move(res.get_success()), return false); + + MATCH_BEGIN (ioc) { - lines++; - if (is_comment(line)) - continue; - // a line is 17 normal fields followed by 2 {} fields - // the fields are separated by ", *", but there may be , - // in the {}. - - auto it = std::find(line.begin(), line.end(), '{'); - XString main_part = line.xislice_h(it).rstrip(); - // According to the code, tail_part may be empty. See later. - ZString tail_part = line.xislice_t(it); - - XString unused_slot_count; - item_data idv {}; - if (!extract( - main_part, record<','>( - &idv.nameid, - lstripping(&idv.name), - lstripping(&idv.jname), - lstripping(&idv.type), - lstripping(&idv.value_buy), - lstripping(&idv.value_sell), - lstripping(&idv.weight), - lstripping(&idv.atk), - lstripping(&idv.def), - lstripping(&idv.range), - lstripping(&idv.magic_bonus), - lstripping(&unused_slot_count), - lstripping(&idv.sex), - lstripping(&idv.equip), - lstripping(&idv.wlv), - lstripping(&idv.elv), - lstripping(&idv.look) - ) - ) - ) - { - PRINTF("%s:%d: error: bad item line: %s\n"_fmt, - filename, lines, line); - rv = false; - continue; - } - - ln++; - - struct item_data *id = itemdb_search(idv.nameid); - *id = std::move(idv); - if (id->value_buy == 0 && id->value_sell == 0) + MATCH_CASE (const ast::item::Comment&, c) { + (void)c; } - else if (id->value_buy == 0) + MATCH_CASE (const ast::item::Item&, item) { - id->value_buy = id->value_sell * 2; + ln++; + + item_data idv {}; + idv.nameid = item.id.data; + idv.name = item.name.data; + idv.jname = item.jname.data; + idv.type = item.type.data; + idv.value_buy = item.buy_price.data ?: item.sell_price.data * 2; + idv.value_sell = item.sell_price.data ?: item.buy_price.data / 2; + idv.weight = item.weight.data; + idv.atk = item.atk.data; + idv.def = item.def.data; + idv.range = item.range.data; + idv.magic_bonus = item.magic_bonus.data; + idv.sex = item.gender.data; + idv.equip = item.loc.data; + idv.wlv = item.wlv.data; + idv.elv = item.elv.data; + idv.look = item.view.data; + + idv.use_script = compile_script(STRPRINTF("use script %d"_fmt, idv.nameid), item.use_script, true); + idv.equip_script = compile_script(STRPRINTF("equip script %d"_fmt, idv.nameid), item.equip_script, true); + + Borrowed<struct item_data> id = itemdb_search(idv.nameid); + *id = std::move(idv); } - else if (id->value_sell == 0) - { - id->value_sell = id->value_buy / 2; - } - - id->use_script = nullptr; - id->equip_script = nullptr; - - if (!tail_part) - continue; - id->use_script = parse_script(tail_part, lines, true); - - tail_part = tail_part.xislice_t(std::find(tail_part.begin() + 1, tail_part.end(), '{')); - if (!tail_part) - continue; - id->equip_script = parse_script(tail_part, lines, true); } - PRINTF("read %s done (count=%d)\n"_fmt, filename, ln); + MATCH_END (); } - - return rv; } /*========================================== @@ -265,4 +235,5 @@ void do_final_itemdb(void) itemdb_final(&pair.second); item_db.clear(); } +} // namespace map } // namespace tmwa |