diff options
Diffstat (limited to 'src/map/magic-expr.cpp')
-rw-r--r-- | src/map/magic-expr.cpp | 198 |
1 files changed, 104 insertions, 94 deletions
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp index 674c850..197727e 100644 --- a/src/map/magic-expr.cpp +++ b/src/map/magic-expr.cpp @@ -33,7 +33,8 @@ #include "../generic/random.hpp" #include "../io/cxxstdio.hpp" -#include "../io/cxxstdio_enums.hpp" + +#include "../mmo/cxxstdio_enums.hpp" #include "battle.hpp" #include "itemdb.hpp" @@ -42,12 +43,15 @@ #include "magic-interpreter-base.hpp" #include "npc.hpp" #include "pc.hpp" +#include "script-call.hpp" #include "../poison.hpp" namespace tmwa { +namespace map +{ namespace magic { static @@ -56,14 +60,15 @@ void free_area(dumb_ptr<area_t> area) if (!area) return; - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { free_area(a.a_union[0]); free_area(a.a_union[1]); } } + MATCH_END (); area.delete_(); } @@ -71,109 +76,111 @@ void free_area(dumb_ptr<area_t> area) static dumb_ptr<area_t> dup_area(dumb_ptr<area_t> area) { - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const location_t&, loc) + MATCH_CASE (const location_t&, loc) { return dumb_ptr<area_t>::make(loc); } - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { AreaUnion u; u.a_union[0] = dup_area(a.a_union[0]); u.a_union[1] = dup_area(a.a_union[1]); return dumb_ptr<area_t>::make(u); } - CASE (const AreaRect&, rect) + MATCH_CASE (const AreaRect&, rect) { return dumb_ptr<area_t>::make(rect); } - CASE (const AreaBar&, bar) + MATCH_CASE (const AreaBar&, bar) { return dumb_ptr<area_t>::make(bar); } } + MATCH_END (); abort(); } void magic_copy_var(val_t *dest, const val_t *src) { - MATCH (*src) + MATCH_BEGIN (*src) { - // mumble mumble not a public API ... - default: + MATCH_DEFAULT () { abort(); } - CASE (const ValUndef&, s) + MATCH_CASE (const ValUndef&, s) { *dest = s; } - CASE (const ValInt&, s) + MATCH_CASE (const ValInt&, s) { *dest = s; } - CASE (const ValDir&, s) + MATCH_CASE (const ValDir&, s) { *dest = s; } - CASE (const ValString&, s) + MATCH_CASE (const ValString&, s) { *dest = ValString{s.v_string}; } - CASE (const ValEntityInt&, s) + MATCH_CASE (const ValEntityInt&, s) { *dest = s; } - CASE (const ValEntityPtr&, s) + MATCH_CASE (const ValEntityPtr&, s) { *dest = s; } - CASE (const ValLocation&, s) + MATCH_CASE (const ValLocation&, s) { *dest = s; } - CASE (const ValArea&, s) + MATCH_CASE (const ValArea&, s) { *dest = ValArea{dup_area(s.v_area)}; } - CASE (const ValSpell&, s) + MATCH_CASE (const ValSpell&, s) { *dest = s; } - CASE (const ValInvocationInt&, s) + MATCH_CASE (const ValInvocationInt&, s) { *dest = s; } - CASE (const ValInvocationPtr&, s) + MATCH_CASE (const ValInvocationPtr&, s) { *dest = s; } - CASE (const ValFail&, s) + MATCH_CASE (const ValFail&, s) { *dest = s; } - CASE (const ValNegative1&, s) + MATCH_CASE (const ValNegative1&, s) { *dest = s; } } + MATCH_END (); } void magic_clear_var(val_t *v) { - MATCH (*v) + MATCH_BEGIN (*v) { - CASE (ValString&, s) + MATCH_CASE (ValString&, s) { (void)s; } - CASE (const ValArea&, a) + MATCH_CASE (const ValArea&, a) { free_area(a.v_area); } } + MATCH_END (); } static @@ -212,63 +219,64 @@ void stringify(val_t *v) }}; AString buf; - MATCH (*v) + MATCH_BEGIN (*v) { - default: + MATCH_DEFAULT () { abort(); } - CASE (const ValUndef&, x) + MATCH_CASE (const ValUndef&, x) { (void)x; buf = "UNDEF"_s; } - CASE (const ValInt&, x) + MATCH_CASE (const ValInt&, x) { buf = STRPRINTF("%i"_fmt, x.v_int); } - CASE (const ValString&, x) + MATCH_CASE (const ValString&, x) { (void)x; return; } - CASE (const ValDir&, x) + MATCH_CASE (const ValDir&, x) { buf = dirs[x.v_dir]; } - CASE (const ValEntityPtr&, x) + MATCH_CASE (const ValEntityPtr&, x) { buf = show_entity(x.v_entity); } - CASE (const ValLocation&, x) + MATCH_CASE (const ValLocation&, x) { buf = STRPRINTF("<\"%s\", %d, %d>"_fmt, x.v_location.m->name_, x.v_location.x, x.v_location.y); } - CASE (const ValArea&, x) + MATCH_CASE (const ValArea&, x) { buf = "%area"_s; free_area(x.v_area); } - CASE (const ValSpell&, x) + MATCH_CASE (const ValSpell&, x) { buf = x.v_spell->name; } - CASE (const ValInvocationInt&, x) + MATCH_CASE (const ValInvocationInt&, x) { dumb_ptr<invocation> invocation_ = map_id2bl(x.v_iid)->is_spell(); buf = invocation_->spell->name; } - CASE (const ValInvocationPtr&, x) + MATCH_CASE (const ValInvocationPtr&, x) { dumb_ptr<invocation> invocation_ = x.v_invocation; buf = invocation_->spell->name; } } + MATCH_END (); *v = ValString{buf}; } @@ -310,14 +318,15 @@ void make_location(val_t *v) { if (ValArea *a = v->get_if<ValArea>()) { - MATCH (*a->v_area) + MATCH_BEGIN (*a->v_area) { - CASE (const location_t&, location) + MATCH_CASE (const location_t&, location) { free_area(a->v_area); *v = ValLocation{location}; } } + MATCH_END (); } } @@ -582,39 +591,41 @@ int fun_if_then_else(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) return 0; } -void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height, +Borrowed<map_local> magic_area_rect(int *x, int *y, int *width, int *height, area_t& area_) { - MATCH (area_) + MATCH_BEGIN (area_) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { (void)a; abort(); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { - *m = a_loc.m; + P<map_local> m = a_loc.m; *x = a_loc.x; *y = a_loc.y; *width = 1; *height = 1; + return m; } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { - *m = a_rect.loc.m; + P<map_local> m = a_rect.loc.m; *x = a_rect.loc.x; *y = a_rect.loc.y; *width = a_rect.width; *height = a_rect.height; + return m; } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { int tx = a_bar.loc.x; int ty = a_bar.loc.y; int twidth = a_bar.width; int tdepth = a_bar.width; - *m = a_bar.loc.m; + P<map_local> m = a_bar.loc.m; switch (a_bar.dir) { @@ -653,53 +664,54 @@ void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height, *y = ty; *width = *height = 1; } + return m; } } + MATCH_END (); + abort(); } -int magic_location_in_area(map_local *m, int x, int y, dumb_ptr<area_t> area) +int magic_location_in_area(Borrowed<map_local> m, int x, int y, dumb_ptr<area_t> area) { - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { return magic_location_in_area(m, x, y, a.a_union[0]) || magic_location_in_area(m, x, y, a.a_union[1]); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { (void)a_loc; // TODO this can be simplified - map_local *am; int ax, ay, awidth, aheight; - magic_area_rect(&am, &ax, &ay, &awidth, &aheight, *area); + P<map_local> am = magic_area_rect(&ax, &ay, &awidth, &aheight, *area); return (am == m && (x >= ax) && (y >= ay) && (x < ax + awidth) && (y < ay + aheight)); } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { (void)a_rect; // TODO this is too complicated - map_local *am; int ax, ay, awidth, aheight; - magic_area_rect(&am, &ax, &ay, &awidth, &aheight, *area); + P<map_local> am = magic_area_rect(&ax, &ay, &awidth, &aheight, *area); return (am == m && (x >= ax) && (y >= ay) && (x < ax + awidth) && (y < ay + aheight)); } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { (void)a_bar; // TODO this is wrong - map_local *am; int ax, ay, awidth, aheight; - magic_area_rect(&am, &ax, &ay, &awidth, &aheight, *area); + P<map_local> am = magic_area_rect(&ax, &ay, &awidth, &aheight, *area); return (am == m && (x >= ax) && (y >= ay) && (x < ax + awidth) && (y < ay + aheight)); } } + MATCH_END (); abort(); } @@ -872,18 +884,17 @@ int fun_hash_entity(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) // ret -1: not a string, ret 1: no such item, ret 0: OK int magic_find_item(Slice<val_t> args, int index, Item *item_, int *stackable) { - struct item_data *item_data; + Option<P<struct item_data>> item_data_ = None; int must_add_sequentially; if (args[index].is<ValInt>()) - item_data = itemdb_exists(wrap<ItemNameId>(static_cast<uint16_t>(ARGINT(index)))); + item_data_ = itemdb_exists(wrap<ItemNameId>(static_cast<uint16_t>(ARGINT(index)))); else if (args[index].is<ValString>()) - item_data = itemdb_searchname(ARGSTR(index)); + item_data_ = itemdb_searchname(ARGSTR(index)); else return -1; - if (!item_data) - return 1; + P<struct item_data> item_data = TRY_UNWRAP(item_data_, return 1); // Very elegant. must_add_sequentially = ( @@ -1082,22 +1093,21 @@ int fun_line_of_sight(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) void magic_random_location(location_t *dest, dumb_ptr<area_t> area) { - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { if (random_::chance({a.a_union[0]->size, area->size})) magic_random_location(dest, a.a_union[0]); else magic_random_location(dest, a.a_union[1]); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { (void)a_loc; // TODO this can be simplified - map_local *m; int x, y, w, h; - magic_area_rect(&m, &x, &y, &w, &h, *area); + P<map_local> m = magic_area_rect(&x, &y, &w, &h, *area); if (w <= 1) w = 1; @@ -1113,13 +1123,12 @@ void magic_random_location(location_t *dest, dumb_ptr<area_t> area) dest->x = pair.first; dest->y = pair.second; } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { (void)a_rect; // TODO this can be simplified - map_local *m; int x, y, w, h; - magic_area_rect(&m, &x, &y, &w, &h, *area); + P<map_local> m = magic_area_rect(&x, &y, &w, &h, *area); if (w <= 1) w = 1; @@ -1135,13 +1144,12 @@ void magic_random_location(location_t *dest, dumb_ptr<area_t> area) dest->x = pair.first; dest->y = pair.second; } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { (void)a_bar; // TODO this is wrong - map_local *m; int x, y, w, h; - magic_area_rect(&m, &x, &y, &w, &h, *area); + P<map_local> m = magic_area_rect(&x, &y, &w, &h, *area); if (w <= 1) w = 1; @@ -1158,6 +1166,7 @@ void magic_random_location(location_t *dest, dumb_ptr<area_t> area) dest->y = pair.second; } } + MATCH_END (); } static @@ -1228,7 +1237,7 @@ int fun_running_status_update(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) static int fun_status_option(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) { - *result = ValInt{(bool((ARGPC(0))->status.option & static_cast<Option>(ARGINT(1))))}; + *result = ValInt{(bool((ARGPC(0))->status.option & static_cast<Opt0>(ARGINT(1))))}; return 0; } @@ -1511,10 +1520,8 @@ int eval_location(dumb_ptr<env_t> env, location_t *dest, const e_location_t *exp && x.is<ValInt>() && y.is<ValInt>()) { MapName name = VString<15>(ZString(m.get_if<ValString>()->v_string)); - map_local *map_id = map_mapname2mapid(name); magic_clear_var(&m); - if (!map_id) - return 1; + P<map_local> map_id = TRY_UNWRAP(map_mapname2mapid(name), return 1); dest->m = map_id; dest->x = x.get_if<ValInt>()->v_int; dest->y = y.get_if<ValInt>()->v_int; @@ -1532,9 +1539,9 @@ int eval_location(dumb_ptr<env_t> env, location_t *dest, const e_location_t *exp static dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_) { - MATCH (expr_) + MATCH_BEGIN (expr_) { - CASE (const e_location_t&, a_loc) + MATCH_CASE (const e_location_t&, a_loc) { location_t loc; if (eval_location(env, &loc, &a_loc)) @@ -1546,7 +1553,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_) return dumb_ptr<area_t>::make(loc); } } - CASE (const ExprAreaUnion&, a) + MATCH_CASE (const ExprAreaUnion&, a) { AreaUnion u; bool fail = false; @@ -1568,7 +1575,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_) } return dumb_ptr<area_t>::make(u); } - CASE (const ExprAreaRect&, a_rect) + MATCH_CASE (const ExprAreaRect&, a_rect) { val_t width, height; magic_eval(env, &width, a_rect.width); @@ -1594,7 +1601,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_) return nullptr; } } - CASE (const ExprAreaBar&, a_bar) + MATCH_CASE (const ExprAreaBar&, a_bar) { val_t width, depth, dir; magic_eval(env, &width, a_bar.width); @@ -1626,6 +1633,7 @@ dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_) } } } + MATCH_END (); abort(); } @@ -1744,14 +1752,14 @@ int magic_signature_check(ZString opname, ZString funname, ZString signature, void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) { - MATCH (*expr) + MATCH_BEGIN (*expr) { - CASE (const val_t&, e_val) + MATCH_CASE (const val_t&, e_val) { magic_copy_var(dest, &e_val); } - CASE (const e_location_t&, e_location) + MATCH_CASE (const e_location_t&, e_location) { location_t loc; if (eval_location(env, &loc, &e_location)) @@ -1759,14 +1767,14 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) else *dest = ValLocation{loc}; } - CASE (const e_area_t&, e_area) + MATCH_CASE (const e_area_t&, e_area) { if (dumb_ptr<area_t> area = eval_area(env, e_area)) *dest = ValArea{area}; else *dest = ValFail(); } - CASE (const ExprFunApp&, e_funapp) + MATCH_CASE (const ExprFunApp&, e_funapp) { val_t arguments[MAX_ARGS]; int args_nr = e_funapp.args_nr; @@ -1800,12 +1808,12 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) for (i = 0; i < args_nr; ++i) magic_clear_var(&arguments[i]); } - CASE (const ExprId&, e) + MATCH_CASE (const ExprId&, e) { val_t& v = env->VAR(e.e_id); magic_copy_var(dest, &v); } - CASE (const ExprField&, e_field) + MATCH_CASE (const ExprField&, e_field) { val_t v; int id = e_field.id; @@ -1833,6 +1841,7 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr) } } } + MATCH_END (); } int magic_eval_int(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr) @@ -1861,4 +1870,5 @@ AString magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr) return result.get_if<ValString>()->v_string; } } // namespace magic +} // namespace map } // namespace tmwa |