summaryrefslogtreecommitdiff
path: root/src/map/magic-expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/magic-expr.cpp')
-rw-r--r--src/map/magic-expr.cpp270
1 files changed, 118 insertions, 152 deletions
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp
index 5aad257..872ba6f 100644
--- a/src/map/magic-expr.cpp
+++ b/src/map/magic-expr.cpp
@@ -87,12 +87,12 @@ void magic_clear_var(val_t *v)
}
static
-const char *show_entity(dumb_ptr<block_list> entity)
+FString show_entity(dumb_ptr<block_list> entity)
{
switch (entity->bl_type)
{
case BL::PC:
- return entity->as_player()->status.name;
+ return entity->as_player()->status.name.to__actual();
case BL::NPC:
return entity->as_npc()->name;
case BL::MOB:
@@ -104,23 +104,23 @@ const char *show_entity(dumb_ptr<block_list> entity)
// return ((struct item_data *) (&entity->as_item()->item_data))->name;
abort();
case BL::SPELL:
- return "%invocation(ERROR:this-should-not-be-an-entity)";
+ return {"%invocation(ERROR:this-should-not-be-an-entity)"};
default:
- return "%unknown-entity";
+ return {"%unknown-entity"};
}
}
static
void stringify(val_t *v, int within_op)
{
- static const char *dirs[8] =
- {
- "south", "south-west",
- "west", "north-west",
- "north", "north-east",
- "east", "south-east"
- };
- std::string buf;
+ static earray<ZString, DIR, DIR::COUNT> dirs //=
+ {{
+ {"south"}, {"south-west"},
+ {"west"}, {"north-west"},
+ {"north"}, {"north-east"},
+ {"east"}, {"south-east"},
+ }};
+ FString buf;
switch (v->ty)
{
@@ -136,7 +136,7 @@ void stringify(val_t *v, int within_op)
return;
case TYPE::DIR:
- buf = dirs[v->v.v_int];
+ buf = dirs[v->v.v_dir];
break;
case TYPE::ENTITY:
@@ -278,7 +278,10 @@ int fun_add(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
stringify(&args[1], 1);
/* Yes, we could speed this up. */
// ugh
- RESULTSTR = dumb_string::copys(ARGSTR(0).str() + ARGSTR(1).str());
+ MString m;
+ m += ARGSTR(0);
+ m += ARGSTR(1);
+ RESULTSTR = dumb_string::copys(FString(m));
result->ty = TYPE::STRING;
}
return 0;
@@ -351,7 +354,6 @@ int fun_gte(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
stringify(&args[0], 1);
stringify(&args[1], 1);
- using namespace operators;
RESULTINT = ARGSTR(0) >= ARGSTR(1);
}
else
@@ -370,7 +372,6 @@ int fun_gt(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
stringify(&args[0], 1);
stringify(&args[1], 1);
- using namespace operators;
RESULTINT = ARGSTR(0) > ARGSTR(1);
}
else
@@ -389,7 +390,6 @@ int fun_eq(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
stringify(&args[0], 1);
stringify(&args[1], 1);
- using namespace operators;
RESULTINT = ARGSTR(0) == ARGSTR(1);
}
else if (ARG_TYPE(0) == TYPE::DIR && ARG_TYPE(1) == TYPE::DIR)
@@ -652,7 +652,7 @@ int fun_name_of(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
if (ARG_TYPE(0) == TYPE::ENTITY)
{
- RESULTSTR = dumb_string::copy(show_entity(ARGENTITY(0)));
+ RESULTSTR = dumb_string::copys(show_entity(ARGENTITY(0)));
return 0;
}
else if (ARG_TYPE(0) == TYPE::SPELL)
@@ -745,7 +745,7 @@ magic_find_item(const_array<val_t> args, int index, struct item *item_, int *sta
if (ARG_TYPE(index) == TYPE::INT)
item_data = itemdb_exists(ARGINT(index));
else if (ARG_TYPE(index) == TYPE::STRING)
- item_data = itemdb_searchname(ARGSTR(index).c_str());
+ item_data = itemdb_searchname(stringish<ItemName>(ARGSTR(index)));
else
return -1;
@@ -874,14 +874,16 @@ int fun_failed(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
static
int fun_npc(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- RESULTENTITY = npc_name2id(ARGSTR(0).c_str());
+ NpcName name = stringish<NpcName>(ARGSTR(0));
+ RESULTENTITY = npc_name2id(name);
return RESULTENTITY == NULL;
}
static
int fun_pc(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
- RESULTENTITY = map_nick2sd(ARGSTR(0).c_str());
+ CharName name = stringish<CharName>(ARGSTR(0));
+ RESULTENTITY = map_nick2sd(name);
return RESULTENTITY == NULL;
}
@@ -913,7 +915,7 @@ int fun_rdistance(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
static
int fun_anchor(dumb_ptr<env_t> env, val_t *result, const_array<val_t> args)
{
- dumb_ptr<teleport_anchor_t> anchor = magic_find_anchor(ARGSTR(0).str());
+ dumb_ptr<teleport_anchor_t> anchor = magic_find_anchor(ARGSTR(0));
if (!anchor)
return 1;
@@ -997,12 +999,12 @@ static
int fun_read_script_int(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
dumb_ptr<block_list> subject_p = ARGENTITY(0);
- dumb_string var_name = ARGSTR(1);
+ VarName var_name = stringish<VarName>(ARGSTR(1));
if (subject_p->bl_type != BL::PC)
return 1;
- RESULTINT = pc_readglobalreg(subject_p->as_player(), var_name.c_str());
+ RESULTINT = pc_readglobalreg(subject_p->as_player(), var_name);
return 0;
}
@@ -1055,13 +1057,6 @@ int fun_element_level(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
}
static
-int fun_index(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
-{
- RESULTINT = ARGSPELL(0)->index_;
- return 0;
-}
-
-static
int fun_is_exterior(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
#warning "Evil assumptions!"
@@ -1136,7 +1131,7 @@ static
int fun_map_nr(dumb_ptr<env_t>, val_t *result, const_array<val_t> args)
{
#warning "Evil assumptions!"
- const char *mapname = ARGLOCATION(0).m->name_;
+ MapName mapname = ARGLOCATION(0).m->name_;
RESULTINT = ((mapname[0] - '0') * 100)
+ ((mapname[1] - '0') * 10) + ((mapname[2] - '0'));
@@ -1221,123 +1216,93 @@ int fun_extract_healer_xp(dumb_ptr<env_t>, val_t *result, const_array<val_t> arg
return 0;
}
-static
-fun_t functions[] =
-{
- {"+", "..", '.', fun_add},
- {"-", "ii", 'i', fun_sub},
- {"*", "ii", 'i', fun_mul},
- {"/", "ii", 'i', fun_div},
- {"%", "ii", 'i', fun_mod},
- {"||", "ii", 'i', fun_or},
- {"&&", "ii", 'i', fun_and},
- {">", "..", 'i', fun_gt},
- {">=", "..", 'i', fun_gte},
- {"=", "..", 'i', fun_eq},
- {"|", "..", 'i', fun_bitor},
- {"&", "ii", 'i', fun_bitand},
- {"^", "ii", 'i', fun_bitxor},
- {"<<", "ii", 'i', fun_bitshl},
- {">>", "ii", 'i', fun_bitshr},
- {"not", "i", 'i', fun_not},
- {"neg", "i", 'i', fun_neg},
- {"max", "ii", 'i', fun_max},
- {"min", "ii", 'i', fun_min},
- {"is_in", "la", 'i', fun_is_in},
- {"if_then_else", "i__", '_', fun_if_then_else},
- {"skill", "ei", 'i', fun_skill},
- {"str", "e", 'i', fun_get_str},
- {"agi", "e", 'i', fun_get_agi},
- {"vit", "e", 'i', fun_get_vit},
- {"dex", "e", 'i', fun_get_dex},
- {"luk", "e", 'i', fun_get_luk},
- {"int", "e", 'i', fun_get_int},
- {"level", "e", 'i', fun_get_lv},
- {"mdef", "e", 'i', fun_get_mdef},
- {"def", "e", 'i', fun_get_def},
- {"hp", "e", 'i', fun_get_hp},
- {"max_hp", "e", 'i', fun_get_max_hp},
- {"sp", "e", 'i', fun_get_sp},
- {"max_sp", "e", 'i', fun_get_max_sp},
- {"dir", "e", 'd', fun_get_dir},
- {"name_of", ".", 's', fun_name_of},
- {"mob_id", "e", 'i', fun_mob_id},
- {"location", "e", 'l', fun_location},
- {"random", "i", 'i', fun_random},
- {"random_dir", "i", 'd', fun_random_dir},
- {"hash_entity", "e", 'i', fun_hash_entity},
- {"is_married", "e", 'i', fun_is_married},
- {"partner", "e", 'e', fun_partner},
- {"awayfrom", "ldi", 'l', fun_awayfrom},
- {"failed", "_", 'i', fun_failed},
- {"pc", "s", 'e', fun_pc},
- {"npc", "s", 'e', fun_npc},
- {"distance", "ll", 'i', fun_distance},
- {"rdistance", "ll", 'i', fun_rdistance},
- {"anchor", "s", 'a', fun_anchor},
- {"random_location", "a", 'l', fun_pick_location},
- {"script_int", "es", 'i', fun_read_script_int},
- {"rbox", "li", 'a', fun_rbox},
- {"count_item", "e.", 'i', fun_count_item},
- {"line_of_sight", "ll", 'i', fun_line_of_sight},
- {"running_status_update", "ei", 'i', fun_running_status_update},
- {"status_option", "ei", 'i', fun_status_option},
- {"element", "e", 'i', fun_element},
- {"element_level", "e", 'i', fun_element_level},
- {"has_shroud", "e", 'i', fun_has_shroud},
- {"is_equipped", "e.", 'i', fun_is_equipped},
- {"spell_index", "S", 'i', fun_index},
- {"is_exterior", "l", 'i', fun_is_exterior},
- {"contains_string", "ss", 'i', fun_contains_string},
- {"strstr", "ss", 'i', fun_strstr},
- {"strlen", "s", 'i', fun_strlen},
- {"substr", "sii", 's', fun_substr},
- {"sqrt", "i", 'i', fun_sqrt},
- {"map_level", "l", 'i', fun_map_level},
- {"map_nr", "l", 'i', fun_map_nr},
- {"dir_towards", "lli", 'd', fun_dir_towards},
- {"is_dead", "e", 'i', fun_is_dead},
- {"is_pc", "e", 'i', fun_is_pc},
- {"extract_healer_experience", "ei", 'i', fun_extract_healer_xp},
- {NULL, NULL, '.', NULL}
+#define MAGIC_FUNCTION(name, args, ret, impl) {{name}, {{name}, {args}, ret, impl}}
+#define MAGIC_FUNCTION1(name, args, ret) MAGIC_FUNCTION(#name, args, ret, fun_##name)
+static
+std::map<ZString, fun_t> functions =
+{
+ MAGIC_FUNCTION("+", "..", '.', fun_add),
+ MAGIC_FUNCTION("-", "ii", 'i', fun_sub),
+ MAGIC_FUNCTION("*", "ii", 'i', fun_mul),
+ MAGIC_FUNCTION("/", "ii", 'i', fun_div),
+ MAGIC_FUNCTION("%", "ii", 'i', fun_mod),
+ MAGIC_FUNCTION("||", "ii", 'i', fun_or),
+ MAGIC_FUNCTION("&&", "ii", 'i', fun_and),
+ MAGIC_FUNCTION(">", "..", 'i', fun_gt),
+ MAGIC_FUNCTION(">=", "..", 'i', fun_gte),
+ MAGIC_FUNCTION("=", "..", 'i', fun_eq),
+ MAGIC_FUNCTION("|", "..", 'i', fun_bitor),
+ MAGIC_FUNCTION("&", "ii", 'i', fun_bitand),
+ MAGIC_FUNCTION("^", "ii", 'i', fun_bitxor),
+ MAGIC_FUNCTION("<<", "ii", 'i', fun_bitshl),
+ MAGIC_FUNCTION(">>", "ii", 'i', fun_bitshr),
+ MAGIC_FUNCTION1(not, "i", 'i'),
+ MAGIC_FUNCTION1(neg, "i", 'i'),
+ MAGIC_FUNCTION1(max, "ii", 'i'),
+ MAGIC_FUNCTION1(min, "ii", 'i'),
+ MAGIC_FUNCTION1(is_in, "la", 'i'),
+ MAGIC_FUNCTION1(if_then_else, "i__", '_'),
+ MAGIC_FUNCTION1(skill, "ei", 'i'),
+ MAGIC_FUNCTION("str", "e", 'i', fun_get_str),
+ MAGIC_FUNCTION("agi", "e", 'i', fun_get_agi),
+ MAGIC_FUNCTION("vit", "e", 'i', fun_get_vit),
+ MAGIC_FUNCTION("dex", "e", 'i', fun_get_dex),
+ MAGIC_FUNCTION("luk", "e", 'i', fun_get_luk),
+ MAGIC_FUNCTION("int", "e", 'i', fun_get_int),
+ MAGIC_FUNCTION("level", "e", 'i', fun_get_lv),
+ MAGIC_FUNCTION("mdef", "e", 'i', fun_get_mdef),
+ MAGIC_FUNCTION("def", "e", 'i', fun_get_def),
+ MAGIC_FUNCTION("hp", "e", 'i', fun_get_hp),
+ MAGIC_FUNCTION("max_hp", "e", 'i', fun_get_max_hp),
+ MAGIC_FUNCTION("sp", "e", 'i', fun_get_sp),
+ MAGIC_FUNCTION("max_sp", "e", 'i', fun_get_max_sp),
+ MAGIC_FUNCTION("dir", "e", 'd', fun_get_dir),
+ MAGIC_FUNCTION1(name_of, ".", 's'),
+ MAGIC_FUNCTION1(mob_id, "e", 'i'),
+ MAGIC_FUNCTION1(location, "e", 'l'),
+ MAGIC_FUNCTION1(random, "i", 'i'),
+ MAGIC_FUNCTION1(random_dir, "i", 'd'),
+ MAGIC_FUNCTION1(hash_entity, "e", 'i'),
+ MAGIC_FUNCTION1(is_married, "e", 'i'),
+ MAGIC_FUNCTION1(partner, "e", 'e'),
+ MAGIC_FUNCTION1(awayfrom, "ldi", 'l'),
+ MAGIC_FUNCTION1(failed, "_", 'i'),
+ MAGIC_FUNCTION1(pc, "s", 'e'),
+ MAGIC_FUNCTION1(npc, "s", 'e'),
+ MAGIC_FUNCTION1(distance, "ll", 'i'),
+ MAGIC_FUNCTION1(rdistance, "ll", 'i'),
+ MAGIC_FUNCTION1(anchor, "s", 'a'),
+ MAGIC_FUNCTION("random_location", "a", 'l', fun_pick_location),
+ MAGIC_FUNCTION("script_int", "es", 'i', fun_read_script_int),
+ MAGIC_FUNCTION1(rbox, "li", 'a'),
+ MAGIC_FUNCTION1(count_item, "e.", 'i'),
+ MAGIC_FUNCTION1(line_of_sight, "ll", 'i'),
+ MAGIC_FUNCTION1(running_status_update, "ei", 'i'),
+ MAGIC_FUNCTION1(status_option, "ei", 'i'),
+ MAGIC_FUNCTION1(element, "e", 'i'),
+ MAGIC_FUNCTION1(element_level, "e", 'i'),
+ MAGIC_FUNCTION1(has_shroud, "e", 'i'),
+ MAGIC_FUNCTION1(is_equipped, "e.", 'i'),
+ MAGIC_FUNCTION1(is_exterior, "l", 'i'),
+ MAGIC_FUNCTION1(contains_string, "ss", 'i'),
+ MAGIC_FUNCTION1(strstr, "ss", 'i'),
+ MAGIC_FUNCTION1(strlen, "s", 'i'),
+ MAGIC_FUNCTION1(substr, "sii", 's'),
+ MAGIC_FUNCTION1(sqrt, "i", 'i'),
+ MAGIC_FUNCTION1(map_level, "l", 'i'),
+ MAGIC_FUNCTION1(map_nr, "l", 'i'),
+ MAGIC_FUNCTION1(dir_towards, "lli", 'd'),
+ MAGIC_FUNCTION1(is_dead, "e", 'i'),
+ MAGIC_FUNCTION1(is_pc, "e", 'i'),
+ MAGIC_FUNCTION("extract_healer_experience", "ei", 'i', fun_extract_healer_xp),
};
-static
-int functions_are_sorted = 0;
-
-static __attribute__((deprecated))
-int compare_fun(const void *lhs, const void *rhs)
-{
- return strcmp(static_cast<const fun_t *>(lhs)->name, static_cast<const fun_t *>(rhs)->name);
-}
-
-fun_t *magic_get_fun(const std::string& name, int *index)
+fun_t *magic_get_fun(ZString name)
{
- static
- int functions_nr;
- fun_t *result;
- fun_t key;
-
- if (!functions_are_sorted)
- {
- fun_t *it = functions;
-
- while (it->name)
- ++it;
- functions_nr = it - functions;
-
- qsort(functions, functions_nr, sizeof(fun_t), compare_fun);
- functions_are_sorted = 1;
- }
-
- key.name = name.c_str();
- result = static_cast<fun_t *>(bsearch(&key, functions, functions_nr, sizeof(fun_t),
- compare_fun));
-
- if (result && index)
- *index = result - functions;
-
- return result;
+ auto it = functions.find(name);
+ if (it == functions.end())
+ return nullptr;
+ return &it->second;
}
// 1 on failure
@@ -1352,7 +1317,8 @@ int eval_location(dumb_ptr<env_t> env, location_t *dest, e_location_t *expr)
if (CHECK_TYPE(&m, TYPE::STRING)
&& CHECK_TYPE(&x, TYPE::INT) && CHECK_TYPE(&y, TYPE::INT))
{
- map_local *map_id = map_mapname2mapid(m.v.v_string.c_str());
+ MapName name = VString<15>(ZString(m.v.v_string));
+ map_local *map_id = map_mapname2mapid(name);
magic_clear_var(&m);
if (!map_id)
return 1;
@@ -1509,8 +1475,8 @@ TYPE type_key(char ty_key)
}
}
-int magic_signature_check(const char *opname, const char *funname, const char *signature,
- int args_nr, val_t *args, int line, int column)
+int magic_signature_check(ZString opname, ZString funname, ZString signature,
+ int args_nr, val_t *args, int line, int column)
{
int i;
for (i = 0; i < args_nr; i++)
@@ -1620,7 +1586,7 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr)
val_t arguments[MAX_ARGS];
int args_nr = expr->e.e_funapp.args_nr;
int i;
- fun_t *f = functions + expr->e.e_funapp.id;
+ fun_t *f = expr->e.e_funapp.funp;
for (i = 0; i < args_nr; ++i)
magic_eval(env, &arguments[i], expr->e.e_funapp.args[i]);
@@ -1705,13 +1671,13 @@ int magic_eval_int(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr)
return result.v.v_int;
}
-std::string magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr)
+FString magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr)
{
val_t result;
magic_eval(env, &result, expr);
if (result.ty == TYPE::FAIL || result.ty == TYPE::UNDEF)
- return "?";
+ return {"?"};
stringify(&result, 0);