diff options
Diffstat (limited to 'src/map/magic-expr.c')
-rw-r--r-- | src/map/magic-expr.c | 140 |
1 files changed, 117 insertions, 23 deletions
diff --git a/src/map/magic-expr.c b/src/map/magic-expr.c index a300a74..0034441 100644 --- a/src/map/magic-expr.c +++ b/src/map/magic-expr.c @@ -214,6 +214,20 @@ make_location(val_t *v) } } +static void +make_spell(val_t *v) +{ + if (v->ty == TY_INVOCATION) { + invocation_t *invoc = v->v.v_invocation; //(invocation_t *) map_id2bl(v->v.v_int); + if (!invoc) + v->ty = TY_FAIL; + else { + v->ty = TY_SPELL; + v->v.v_spell = invoc->spell; + } + } +} + static int fun_add(env_t *env, int args_nr, val_t *result, val_t *args) { @@ -483,13 +497,13 @@ magic_area_rect(int *m, int *x, int *y, int *width, int *height, area_t *area) } } -static int -location_in_area(int m, int x, int y, area_t *area) +int +magic_location_in_area(int m, int x, int y, area_t *area) { switch (area->ty) { case AREA_UNION: - return location_in_area(m, x, y, area->a.a_union[0]) - || location_in_area(m, x, y, area->a.a_union[1]); + return magic_location_in_area(m, x, y, area->a.a_union[0]) + || magic_location_in_area(m, x, y, area->a.a_union[1]); case AREA_LOCATION: case AREA_RECT: case AREA_BAR: { @@ -510,10 +524,10 @@ location_in_area(int m, int x, int y, area_t *area) static int fun_is_in(env_t *env, int args_nr, val_t *result, val_t *args) { - RESULTINT = location_in_area(ARGLOCATION(0).m, - ARGLOCATION(0).x, - ARGLOCATION(0).y, - ARGAREA(1)); + RESULTINT = magic_location_in_area(ARGLOCATION(0).m, + ARGLOCATION(0).x, + ARGLOCATION(0).y, + ARGAREA(1)); return 0; } @@ -621,31 +635,79 @@ fun_hash_entity(env_t *env, int args_nr, val_t *result, val_t *args) return 0; } +int // ret -1: not a string, ret 1: no such item, ret 0: OK +magic_find_item(val_t *args, int index, struct item *item, int *stackable) +{ + struct item_data *item_data; + int must_add_sequentially; + + if (TY(index) == TY_INT) + item_data = itemdb_exists(ARGINT(index)); + else if (TY(index) == TY_STRING) + item_data = itemdb_searchname(ARGSTR(index)); + else + return -1; + + if (!item_data) + return 1; + + must_add_sequentially = (item_data->type == 4 + || item_data->type == 5 + || item_data->type == 7 + || item_data->type == 8); /* Very elegant. */ + + if (stackable) + *stackable = !must_add_sequentially; + + memset(item, 0, sizeof(struct item)); + item->nameid = item_data->nameid; + item->identify = 1; + + return 0; +} + static int fun_count_item(env_t *env, int args_nr, val_t *result, val_t *args) { character_t *chr = (ETY(0) == BL_PC) ? ARGPC(0) : NULL; - int item_id; - - if (TY(1) == TY_INT) - item_id = ARGINT(1); - else if (TY(1) == TY_STRING) { - struct item_data *bitem = itemdb_searchname(ARGSTR(1)); - if (!bitem) { - fprintf(stderr, "Unknown item `%s' used in spell\n", ARGSTR(1)); - return 1; - } else - item_id = bitem->nameid; - } else - return 0; + int stackable; + struct item item; + + GET_ARG_ITEM(1, item, stackable); if (!chr) return 1; - RESULTINT = pc_count_all_items(chr, item_id); + RESULTINT = pc_count_all_items(chr, item.nameid); return 0; } +static int +fun_is_equipped(env_t *env, int args_nr, val_t *result, val_t *args) +{ + character_t *chr = (ETY(0) == BL_PC) ? ARGPC(0) : NULL; + int stackable; + struct item item; + int i; + int retval = 0; + + GET_ARG_ITEM(1, item, stackable); + + if (!chr) + return 1; + + fprintf(stderr, "Checking for equipped status of item %d\n", item.nameid); + + for (i = 0; i < 11; i++) + if (chr->equip_index[i] >= 0 + && chr->status.inventory[chr->equip_index[i]].nameid == item.nameid) { + retval = i + 1; + break; + } + + RESULTINT = retval; + return 0; +} static int fun_is_married(env_t *env, int args_nr, val_t *result, val_t *args) @@ -885,6 +947,13 @@ fun_element_level(env_t *env, int args_nr, val_t *result, val_t *args) return 0; } +static int +fun_index(env_t *env, int args_nr, val_t *result, val_t *args) +{ + RESULTINT = ARGSPELL(0)->index; + return 0; +} + #define BATTLE_RECORD2(sname, name) { sname, "e", 'i', fun_get_##name } #define BATTLE_RECORD(name) BATTLE_RECORD2(#name, name) static fun_t functions[] = { @@ -944,6 +1013,8 @@ static fun_t functions[] = { { "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 }, { NULL, NULL, '.', NULL } }; @@ -1167,6 +1238,7 @@ magic_signature_check(char *opname, char *funname, char *signature, int args_nr, case TY_STRING: stringify(arg, 1); break; /* 100% success rate */ case TY_AREA: make_area(arg); break; /* Only works for locations */ case TY_LOCATION: make_location(arg); break; /* Only works for some areas */ + case TY_SPELL: make_spell(arg); break; /* Only works for still-active invocatoins */ default: break; /* We'll fail right below */ } @@ -1241,8 +1313,30 @@ magic_eval(env_t *env, val_t *dest, expr_t *expr) break; } + case EXPR_SPELLFIELD: { + val_t v; + int id = expr->e.e_field.id; + magic_eval(env, &v, expr->e.e_field.expr); + + if (v.ty == TY_INVOCATION) { + invocation_t *t = (invocation_t *) map_id2bl(v.v.v_int); + + if (!t) + dest->ty = TY_UNDEF; + else { + env_t *env = t->env; + val_t v = VAR(id); + magic_copy_var(dest, &v); + } + } else { + fprintf(stderr, "[magic] Attempt to access field %s on non-spell\n", env->base_env->var_name[id]); + dest->ty = TY_FAIL; + } + break; + } + default: - fprintf(stderr, "INTERNAL ERROR: Unknown expression type %d\n", expr->ty); + fprintf(stderr, "[magic] INTERNAL ERROR: Unknown expression type %d\n", expr->ty); break; } } |