From 8b5370313dcc00a45ea5c3e8b4c497bc00fd8e13 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Tue, 11 Jun 2013 21:55:13 -0700 Subject: Allegedly remove all manual memory management --- src/map/magic-stmt.cpp | 341 ++++++++++++++++++++++--------------------------- 1 file changed, 154 insertions(+), 187 deletions(-) (limited to 'src/map/magic-stmt.cpp') diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp index d7944f1..f24167c 100644 --- a/src/map/magic-stmt.cpp +++ b/src/map/magic-stmt.cpp @@ -71,10 +71,10 @@ void clear_activation_record(cont_activation_record_t *ar) switch (ar->ty) { case CONT_STACK::FOREACH: - free(ar->c.c_foreach.entities); + ar->c.c_foreach.entities_vp.delete_(); break; case CONT_STACK::PROC: - free(ar->c.c_proc.old_actuals); + ar->c.c_proc.old_actualpa.delete_(); break; } } @@ -103,13 +103,7 @@ void clear_stack(dumb_ptr invocation_) void spell_free_invocation(dumb_ptr invocation_) { - if (invocation_->status_change_refs) - { - free(invocation_->status_change_refs); - /* The following cleanup shouldn't be necessary, but I've added it to help tracking a certain bug */ - invocation_->status_change_refs = NULL; - invocation_->status_change_refs_nr = 0; - } + invocation_->status_change_refv.clear(); if (bool(invocation_->flags & INVOCATION_FLAG::BOUND)) { @@ -200,7 +194,7 @@ void magic_stop_completely(dumb_ptr c) static void try_to_finish_invocation(dumb_ptr invocation) { - if (invocation->status_change_refs_nr == 0 && !invocation->current_effect) + if (invocation->status_change_refv.empty() && !invocation->current_effect) { if (invocation->end_effect) { @@ -225,20 +219,20 @@ int trigger_spell(int subject, int spell) invocation_ = spell_clone_effect(invocation_); spell_bind(map_id_as_player(subject), invocation_); - magic_clear_var(&invocation_->env->vars[VAR_CASTER]); - invocation_->env->vars[VAR_CASTER].ty = TYPE::ENTITY; - invocation_->env->vars[VAR_CASTER].v.v_int = subject; + magic_clear_var(&invocation_->env->varu[VAR_CASTER]); + invocation_->env->varu[VAR_CASTER].ty = TYPE::ENTITY; + invocation_->env->varu[VAR_CASTER].v.v_int = subject; return invocation_->bl_id; } static -void entity_warp(dumb_ptr target, int destm, int destx, int desty); +void entity_warp(dumb_ptr target, map_local *destm, int destx, int desty); static void char_update(dumb_ptr character) { - entity_warp((dumb_ptr ) character, character->bl_m, character->bl_x, + entity_warp(character, character->bl_m, character->bl_x, character->bl_y); } @@ -276,7 +270,7 @@ void timer_callback_effect_npc_delete(TimerData *, tick_t, int npc_id) } static -dumb_ptr local_spell_effect(int m, int x, int y, int effect, +dumb_ptr local_spell_effect(map_local *m, int x, int y, int effect, interval_t tdelay) { /* 1 minute should be enough for all interesting spell effects, I hope */ @@ -295,7 +289,7 @@ dumb_ptr local_spell_effect(int m, int x, int y, int effect, } static -int op_sfx(env_t *, int, val_t *args) +int op_sfx(dumb_ptr, const_array args) { interval_t delay = static_cast(ARGINT(2)); @@ -316,10 +310,10 @@ int op_sfx(env_t *, int, val_t *args) } static -int op_instaheal(env_t *env, int, val_t *args) +int op_instaheal(dumb_ptr env, const_array args) { - dumb_ptr caster = (VAR(VAR_CASTER).ty == TYPE::ENTITY) - ? map_id2bl(VAR(VAR_CASTER).v.v_int) : NULL; + dumb_ptr caster = (env->VAR(VAR_CASTER).ty == TYPE::ENTITY) + ? map_id2bl(env->VAR(VAR_CASTER).v.v_int) : NULL; dumb_ptr subject = ARGENTITY(0); if (!caster) caster = subject; @@ -337,7 +331,7 @@ int op_instaheal(env_t *env, int, val_t *args) } static -int op_itemheal(env_t *env, int args_nr, val_t *args) +int op_itemheal(dumb_ptr env, const_array args) { dumb_ptr subject = ARGENTITY(0); if (subject->bl_type == BL::PC) @@ -346,7 +340,7 @@ int op_itemheal(env_t *env, int args_nr, val_t *args) ARGINT(1), ARGINT(2)); } else - return op_instaheal(env, args_nr, args); + return op_instaheal(env, args); return 0; } @@ -367,7 +361,7 @@ using e::Shroud; #define ARGCHAR(n) (ARGENTITY(n)->is_player()) static -int op_shroud(env_t *, int, val_t *args) +int op_shroud(dumb_ptr, const_array args) { dumb_ptr subject = ARGCHAR(0); Shroud arg = static_cast(ARGINT(1)); @@ -386,7 +380,7 @@ int op_shroud(env_t *, int, val_t *args) } static -int op_reveal(env_t *, int, val_t *args) +int op_reveal(dumb_ptr, const_array args) { dumb_ptr subject = ARGCHAR(0); @@ -397,7 +391,7 @@ int op_reveal(env_t *, int, val_t *args) } static -int op_message(env_t *, int, val_t *args) +int op_message(dumb_ptr, const_array args) { dumb_ptr subject = ARGCHAR(0); @@ -416,13 +410,13 @@ void timer_callback_kill_npc(TimerData *, tick_t, int npc_id) } static -int op_messenger_npc(env_t *, int, val_t *args) +int op_messenger_npc(dumb_ptr, const_array args) { dumb_ptr npc; location_t *loc = &ARGLOCATION(0); npc = npc_spawn_text(loc->m, loc->x, loc->y, - ARGINT(1), ARGSTR(2), ARGSTR(3)); + ARGINT(1), ARGSTR(2).c_str(), ARGSTR(3).c_str()); Timer(gettick() + static_cast(ARGINT(4)), std::bind(timer_callback_kill_npc, ph::_1, ph::_2, @@ -433,7 +427,7 @@ int op_messenger_npc(env_t *, int, val_t *args) } static -void entity_warp(dumb_ptr target, int destm, int destx, int desty) +void entity_warp(dumb_ptr target, map_local *destm, int destx, int desty) { if (target->bl_type == BL::PC || target->bl_type == BL::MOB) { @@ -453,7 +447,7 @@ void entity_warp(dumb_ptr target, int destm, int destx, int desty) pc_touch_all_relevant_npcs(character); // Note that touching NPCs may have triggered warping and thereby updated x and y: - map_name = map[character->bl_m].name; + map_name = character->bl_m->name; // Warp part #1: update relevant data, interrupt trading etc.: pc_setpos(character, map_name, character->bl_x, character->bl_y, BeingRemoveWhy::GONE); @@ -473,7 +467,7 @@ void entity_warp(dumb_ptr target, int destm, int destx, int desty) } static -int op_move(env_t *, int, val_t *args) +int op_move(dumb_ptr, const_array args) { dumb_ptr subject = ARGENTITY(0); DIR dir = ARGDIR(1); @@ -488,7 +482,7 @@ int op_move(env_t *, int, val_t *args) } static -int op_warp(env_t *, int, val_t *args) +int op_warp(dumb_ptr, const_array args) { dumb_ptr subject = ARGENTITY(0); location_t *loc = &ARGLOCATION(1); @@ -499,7 +493,7 @@ int op_warp(env_t *, int, val_t *args) } static -int op_banish(env_t *, int, val_t *args) +int op_banish(dumb_ptr, const_array args) { dumb_ptr subject = ARGENTITY(0); @@ -515,26 +509,22 @@ int op_banish(env_t *, int, val_t *args) } static -void record_status_change(dumb_ptr invocation, int bl_id, +void record_status_change(dumb_ptr invocation_, int bl_id, StatusChange sc_id) { - int index = invocation->status_change_refs_nr++; - status_change_ref_t *cr; - - RECREATE(invocation->status_change_refs, status_change_ref_t, invocation->status_change_refs_nr); + status_change_ref_t cr {}; + cr.sc_type = sc_id; + cr.bl_id = bl_id; - cr = &invocation->status_change_refs[index]; - - cr->sc_type = sc_id; - cr->bl_id = bl_id; + invocation_->status_change_refv.push_back(cr); } static -int op_status_change(env_t *env, int, val_t *args) +int op_status_change(dumb_ptr env, const_array args) { dumb_ptr subject = ARGENTITY(0); - int invocation_id = VAR(VAR_INVOCATION).ty == TYPE::INVOCATION - ? VAR(VAR_INVOCATION).v.v_int : 0; + int invocation_id = env->VAR(VAR_INVOCATION).ty == TYPE::INVOCATION + ? env->VAR(VAR_INVOCATION).v.v_int : 0; dumb_ptr invocation_ = map_id_as_spell(invocation_id); assert (!ARGINT(3)); @@ -551,7 +541,7 @@ int op_status_change(env_t *env, int, val_t *args) } static -int op_stop_status_change(env_t *, int, val_t *args) +int op_stop_status_change(dumb_ptr, const_array args) { dumb_ptr subject = ARGENTITY(0); @@ -562,7 +552,7 @@ int op_stop_status_change(env_t *, int, val_t *args) } static -int op_override_attack(env_t *env, int, val_t *args) +int op_override_attack(dumb_ptr env, const_array args) { dumb_ptr psubject = ARGENTITY(0); int charges = ARGINT(1); @@ -586,7 +576,7 @@ int op_override_attack(env_t *env, int, val_t *args) } subject->attack_spell_override = - trigger_spell(subject->bl_id, VAR(VAR_INVOCATION).v.v_int); + trigger_spell(subject->bl_id, env->VAR(VAR_INVOCATION).v.v_int); subject->attack_spell_charges = charges; if (subject->attack_spell_override) @@ -603,7 +593,7 @@ int op_override_attack(env_t *env, int, val_t *args) } static -int op_create_item(env_t *, int, val_t *args) +int op_create_item(dumb_ptr, const_array args) { struct item item; dumb_ptr entity = ARGENTITY(0); @@ -641,7 +631,7 @@ bool AGGRAVATION_MODE_MAKES_AGGRESSIVE(int n) } static -int op_aggravate(env_t *, int, val_t *args) +int op_aggravate(dumb_ptr, const_array args) { dumb_ptr victim = ARGENTITY(2); int mode = ARGINT(1); @@ -676,9 +666,9 @@ enum class MonsterAttitude }; static -int op_spawn(env_t *, int, val_t *args) +int op_spawn(dumb_ptr, const_array args) { - area_t *area = ARGAREA(0); + dumb_ptr area = ARGAREA(0); dumb_ptr owner_e = ARGENTITY(1); int monster_id = ARGINT(2); MonsterAttitude monster_attitude = static_cast(ARGINT(3)); @@ -699,7 +689,7 @@ int op_spawn(env_t *, int, val_t *args) int mob_id; dumb_ptr mob; - mob_id = mob_once_spawn(owner, map[loc.m].name, loc.x, loc.y, "--ja--", // Is that needed? + mob_id = mob_once_spawn(owner, loc.m->name, loc.x, loc.y, "--ja--", // Is that needed? monster_id, 1, ""); mob = map_id_as_mob(mob_id); @@ -752,22 +742,22 @@ int op_spawn(env_t *, int, val_t *args) } static -const char *get_invocation_name(env_t *env) +const char *get_invocation_name(dumb_ptr env) { dumb_ptr invocation_; - if (VAR(VAR_INVOCATION).ty != TYPE::INVOCATION) + if (env->VAR(VAR_INVOCATION).ty != TYPE::INVOCATION) return "?"; - invocation_ = map_id_as_spell(VAR(VAR_INVOCATION).v.v_int); + invocation_ = map_id_as_spell(env->VAR(VAR_INVOCATION).v.v_int); if (invocation_) - return invocation_->spell->name; + return invocation_->spell->name.c_str(); else return "??"; } static -int op_injure(env_t *env, int, val_t *args) +int op_injure(dumb_ptr env, const_array args) { dumb_ptr caster = ARGENTITY(0); dumb_ptr target = ARGENTITY(1); @@ -777,7 +767,7 @@ int op_injure(env_t *env, int, val_t *args) int mdef = battle_get_mdef(target); if (target->bl_type == BL::PC - && !map[target->bl_m].flag.pvp + && !target->bl_m->flag.pvp && !target->as_player()->special_state.killable && (caster->bl_type != BL::PC || !caster->as_player()->special_state.killer)) return 0; /* Cannot damage other players outside of pvp */ @@ -817,7 +807,7 @@ int op_injure(env_t *env, int, val_t *args) } static -int op_emote(env_t *, int, val_t *args) +int op_emote(dumb_ptr, const_array args) { dumb_ptr victim = ARGENTITY(0); int emotion = ARGINT(1); @@ -827,20 +817,20 @@ int op_emote(env_t *, int, val_t *args) } static -int op_set_script_variable(env_t *, int, val_t *args) +int op_set_script_variable(dumb_ptr, const_array args) { dumb_ptr c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; if (!c) return 1; - pc_setglobalreg(c, ARGSTR(1), ARGINT(2)); + pc_setglobalreg(c, ARGSTR(1).c_str(), ARGINT(2)); return 0; } static -int op_set_hair_colour(env_t *, int, val_t *args) +int op_set_hair_colour(dumb_ptr, const_array args) { dumb_ptr c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; @@ -853,7 +843,7 @@ int op_set_hair_colour(env_t *, int, val_t *args) } static -int op_set_hair_style(env_t *, int, val_t *args) +int op_set_hair_style(dumb_ptr, const_array args) { dumb_ptr c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; @@ -866,15 +856,15 @@ int op_set_hair_style(env_t *, int, val_t *args) } static -int op_drop_item_for (env_t *, int args_nr, val_t *args) +int op_drop_item_for (dumb_ptr, const_array args) { struct item item; int stackable; location_t *loc = &ARGLOCATION(0); int count = ARGINT(2); interval_t interval = static_cast(ARGINT(3)); - dumb_ptr c = ((args_nr > 4) && (ENTITY_TYPE(4) == BL::PC)) ? ARGPC(4) : NULL; - interval_t delay = (args_nr > 5) ? static_cast(ARGINT(5)) : interval_t::zero(); + dumb_ptr c = ((args.size() > 4) && (ENTITY_TYPE(4) == BL::PC)) ? ARGPC(4) : NULL; + interval_t delay = (args.size() > 5) ? static_cast(ARGINT(5)) : interval_t::zero(); interval_t delaytime[3] = { delay, delay, delay }; dumb_ptr owners[3] = { c, NULL, NULL }; @@ -892,7 +882,7 @@ int op_drop_item_for (env_t *, int args_nr, val_t *args) } static -int op_gain_exp(env_t *, int, val_t *args) +int op_gain_exp(dumb_ptr, const_array args) { dumb_ptr c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL; @@ -905,7 +895,8 @@ int op_gain_exp(env_t *, int, val_t *args) } static -op_t operations[] = { +op_t operations[] = +{ {"sfx", ".ii", op_sfx}, {"instaheal", "eii", op_instaheal}, {"itemheal", "eii", op_itemheal}, @@ -938,13 +929,13 @@ int operations_sorted = 0; static int operation_count; -static +static __attribute__((deprecated)) int compare_operations(const void *lhs, const void *rhs) { - return strcmp(((const op_t *) lhs)->name, ((const op_t *) rhs)->name); + return strcmp(static_cast(lhs)->name, static_cast(rhs)->name); } -op_t *magic_get_op(char *name, int *index) +op_t *magic_get_op(const std::string& name, int *index) { op_t key; @@ -962,9 +953,9 @@ op_t *magic_get_op(char *name, int *index) operations_sorted = 1; } - key.name = name; - op_t *op = (op_t *)bsearch(&key, operations, operation_count, sizeof(op_t), - compare_operations); + key.name = name.c_str(); + op_t *op = static_cast(bsearch(&key, operations, operation_count, sizeof(op_t), + compare_operations)); if (op && index) *index = op - operations; @@ -975,24 +966,23 @@ op_t *magic_get_op(char *name, int *index) void spell_effect_report_termination(int invocation_id, int bl_id, StatusChange sc_id, int) { - int i; - int index = -1; dumb_ptr invocation_ = map_id_as_spell(invocation_id); if (!invocation_ || invocation_->bl_type != BL::SPELL) return; - for (i = 0; i < invocation_->status_change_refs_nr; i++) + for (status_change_ref_t& cr : invocation_->status_change_refv) { - status_change_ref_t *cr = &invocation_->status_change_refs[i]; - if (cr->sc_type == sc_id && cr->bl_id == bl_id) + if (cr.sc_type == sc_id && cr.bl_id == bl_id) { - index = i; - break; + if (&cr != &invocation_->status_change_refv.back()) + std::swap(cr, invocation_->status_change_refv.back()); + invocation_->status_change_refv.pop_back(); + + try_to_finish_invocation(invocation_); } } - if (index == -1) { dumb_ptr entity = map_id2bl(bl_id); if (entity->bl_type == BL::PC) @@ -1002,17 +992,10 @@ void spell_effect_report_termination(int invocation_id, int bl_id, return; } - if (index == invocation_->status_change_refs_nr - 1) - invocation_->status_change_refs_nr--; - else /* Copy last change ref to the one we are deleting */ - invocation_->status_change_refs[index] = - invocation_->status_change_refs[--invocation_->status_change_refs_nr]; - - try_to_finish_invocation(invocation_); } static -effect_t *return_to_stack(dumb_ptr invocation_) +dumb_ptr return_to_stack(dumb_ptr invocation_) { if (!invocation_->stack_size) return NULL; @@ -1022,20 +1005,18 @@ effect_t *return_to_stack(dumb_ptr invocation_) invocation_->stack + (invocation_->stack_size - 1); switch (ar->ty) { - case CONT_STACK::PROC: { - effect_t *ret = ar->return_location; - int i; - - for (i = 0; i < ar->c.c_proc.args_nr; i++) + dumb_ptr ret = ar->return_location; + for (int i = 0; i < ar->c.c_proc.args_nr; i++) { val_t *var = - &invocation_->env->vars[ar->c.c_proc.formals[i]]; + &invocation_->env->varu[ar->c.c_proc.formalap[i]]; magic_clear_var(var); - *var = ar->c.c_proc.old_actuals[i]; + *var = ar->c.c_proc.old_actualpa[i]; } + // pop the stack clear_activation_record(ar); --invocation_->stack_size; @@ -1045,20 +1026,23 @@ effect_t *return_to_stack(dumb_ptr invocation_) case CONT_STACK::FOREACH: { int entity_id; - val_t *var = &invocation_->env->vars[ar->c.c_foreach.id]; + val_t *var = &invocation_->env->varu[ar->c.c_foreach.id]; do { - if (ar->c.c_foreach.index >= ar->c.c_foreach.entities_nr) + // This >= is really supposed to be a ==, but + // I have no clue if it's actually safe to change it. + if (ar->c.c_foreach.index >= ar->c.c_foreach.entities_vp->size()) { - effect_t *ret = ar->return_location; + // pop the stack + dumb_ptr ret = ar->return_location; clear_activation_record(ar); --invocation_->stack_size; return ret; } entity_id = - ar->c.c_foreach.entities[ar->c.c_foreach.index++]; + (*ar->c.c_foreach.entities_vp)[ar->c.c_foreach.index++]; } while (!entity_id || !map_id2bl(entity_id)); @@ -1072,15 +1056,16 @@ effect_t *return_to_stack(dumb_ptr invocation_) case CONT_STACK::FOR: if (ar->c.c_for.current > ar->c.c_for.stop) { - effect_t *ret = ar->return_location; + dumb_ptr ret = ar->return_location; + // pop the stack clear_activation_record(ar); --invocation_->stack_size; return ret; } - magic_clear_var(&invocation_->env->vars[ar->c.c_for.id]); - invocation_->env->vars[ar->c.c_for.id].ty = TYPE::INT; - invocation_->env->vars[ar->c.c_for.id].v.v_int = + magic_clear_var(&invocation_->env->varu[ar->c.c_for.id]); + invocation_->env->varu[ar->c.c_for.id].ty = TYPE::INT; + invocation_->env->varu[ar->c.c_for.id].v.v_int = ar->c.c_for.current++; return ar->c.c_for.body; @@ -1096,7 +1081,7 @@ effect_t *return_to_stack(dumb_ptr invocation_) static cont_activation_record_t *add_stack_entry(dumb_ptr invocation_, - CONT_STACK ty, effect_t *return_location) + CONT_STACK ty, dumb_ptr return_location) { cont_activation_record_t *ar = invocation_->stack + invocation_->stack_size++; @@ -1116,20 +1101,9 @@ cont_activation_record_t *add_stack_entry(dumb_ptr invocation_, static void find_entities_in_area_c(dumb_ptr target, - int *entities_allocd_p, - int *entities_nr_p, - int **entities_p, + std::vector *entities_vp, FOREACH_FILTER filter) { -/* The following macro adds an entity to the result list: */ -#define ADD_ENTITY(e) \ - if (*entities_nr_p == *entities_allocd_p) { \ - /* Need more space */ \ - (*entities_allocd_p) += 32; \ - RECREATE(*entities_p, int, *entities_allocd_p); \ - } \ - (*entities_p)[(*entities_nr_p)++] = e; - switch (target->bl_type) { @@ -1137,7 +1111,7 @@ void find_entities_in_area_c(dumb_ptr target, if (filter == FOREACH_FILTER::PC || filter == FOREACH_FILTER::ENTITY || (filter == FOREACH_FILTER::TARGET - && map[target->bl_m].flag.pvp)) + && target->bl_m->flag.pvp)) break; else if (filter == FOREACH_FILTER::SPELL) { /* Check all spells bound to the caster */ @@ -1146,7 +1120,7 @@ void find_entities_in_area_c(dumb_ptr target, while (invoc) { - ADD_ENTITY(invoc->bl_id); + entities_vp->push_back(invoc->bl_id); invoc = invoc->next_invocation; } } @@ -1184,42 +1158,45 @@ void find_entities_in_area_c(dumb_ptr target, return; } - ADD_ENTITY(target->bl_id); -#undef ADD_ENTITY + entities_vp->push_back(target->bl_id); } static -void find_entities_in_area(area_t *area, int *entities_allocd_p, - int *entities_nr_p, int **entities_p, FOREACH_FILTER filter) +void find_entities_in_area(area_t& area_, + std::vector *entities_vp, + FOREACH_FILTER filter) { + area_t *area = &area_; // temporary hack to "keep diff small". Heh. switch (area->ty) { case AREA::UNION: - find_entities_in_area(area->a.a_union[0], entities_allocd_p, - entities_nr_p, entities_p, filter); - find_entities_in_area(area->a.a_union[1], entities_allocd_p, - entities_nr_p, entities_p, filter); + find_entities_in_area(*area->a.a_union[0], entities_vp, filter); + find_entities_in_area(*area->a.a_union[1], entities_vp, filter); break; default: { - int m, x, y, width, height; - magic_area_rect(&m, &x, &y, &width, &height, area); - map_foreachinarea(std::bind(find_entities_in_area_c, ph::_1, entities_allocd_p, entities_nr_p, entities_p, filter), - m, x, y, x + width, y + height, - BL::NUL /* filter elsewhere */); + map_local *m; + int x, y, width, height; + magic_area_rect(&m, &x, &y, &width, &height, *area); + map_foreachinarea(std::bind(find_entities_in_area_c, ph::_1, entities_vp, filter), + m, + x, y, + x + width, y + height, + BL::NUL /* filter elsewhere */); } } } static -effect_t *run_foreach(dumb_ptr invocation, effect_t *foreach, - effect_t *return_location) +dumb_ptr run_foreach(dumb_ptr invocation, + dumb_ptr foreach, + dumb_ptr return_location) { val_t area; FOREACH_FILTER filter = foreach->e.e_foreach.filter; int id = foreach->e.e_foreach.id; - effect_t *body = foreach->e.e_foreach.body; + dumb_ptr body = foreach->e.e_foreach.body; magic_eval(invocation->env, &area, foreach->e.e_foreach.area); @@ -1228,32 +1205,28 @@ effect_t *run_foreach(dumb_ptr invocation, effect_t *foreach, magic_clear_var(&area); FPRINTF(stderr, "[magic] Error in spell `%s': FOREACH loop over non-area\n", - invocation->spell->name); + invocation->spell->name.c_str()); return return_location; } else { cont_activation_record_t *ar = add_stack_entry(invocation, CONT_STACK::FOREACH, return_location); - int entities_allocd = 64; - int *entities; - int entities_nr = 0; if (!ar) return return_location; - CREATE(entities, int, entities_allocd); - find_entities_in_area(area.v.v_area, &entities_allocd, &entities_nr, - &entities, filter); - RECREATE(entities, int, entities_nr); + std::vector entities_v; + find_entities_in_area(*area.v.v_area, + &entities_v, filter); + entities_v.shrink_to_fit(); // iterator_pair will go away when this gets properly containerized. - random_::shuffle(iterator_pair(entities, entities + entities_nr)); + random_::shuffle(entities_v); ar->c.c_foreach.id = id; ar->c.c_foreach.body = body; ar->c.c_foreach.index = 0; - ar->c.c_foreach.entities_nr = entities_nr; - ar->c.c_foreach.entities = entities; + ar->c.c_foreach.entities_vp.new_(std::move(entities_v)); ar->c.c_foreach.ty = (filter == FOREACH_FILTER::SPELL) ? TYPE::INVOCATION : TYPE::ENTITY; @@ -1264,8 +1237,9 @@ effect_t *run_foreach(dumb_ptr invocation, effect_t *foreach, } static -effect_t *run_for (dumb_ptr invocation, effect_t *for_, - effect_t *return_location) +dumb_ptr run_for (dumb_ptr invocation, + dumb_ptr for_, + dumb_ptr return_location) { cont_activation_record_t *ar; int id = for_->e.e_for.id; @@ -1299,28 +1273,24 @@ effect_t *run_for (dumb_ptr invocation, effect_t *for_, } static -effect_t *run_call(dumb_ptr invocation, - effect_t *return_location) +dumb_ptr run_call(dumb_ptr invocation, + dumb_ptr return_location) { - effect_t *current = invocation->current_effect; + dumb_ptr current = invocation->current_effect; cont_activation_record_t *ar; - int args_nr = current->e.e_call.args_nr; - int *formals = current->e.e_call.formals; - val_t *old_actuals; - CREATE(old_actuals, val_t, args_nr); - int i; + int args_nr = current->e.e_call.formalv->size(); + int *formals = current->e.e_call.formalv->data(); + auto old_actuals = dumb_ptr::make(args_nr); ar = add_stack_entry(invocation, CONT_STACK::PROC, return_location); ar->c.c_proc.args_nr = args_nr; - ar->c.c_proc.formals = formals; - ar->c.c_proc.old_actuals = old_actuals; - for (i = 0; i < args_nr; i++) + ar->c.c_proc.formalap = formals; + ar->c.c_proc.old_actualpa = old_actuals; + for (int i = 0; i < args_nr; i++) { - val_t *env_val = &invocation->env->vars[formals[i]]; - val_t result; + val_t *env_val = &invocation->env->varu[formals[i]]; magic_copy_var(&old_actuals[i], env_val); - magic_eval(invocation->env, &result, current->e.e_call.actuals[i]); - *env_val = result; + magic_eval(invocation->env, env_val, (*current->e.e_call.actualvp)[i]); } return current->e.e_call.body; @@ -1414,8 +1384,8 @@ interval_t spell_run(dumb_ptr invocation_, int allow_delete) #endif while (invocation_->current_effect) { - effect_t *e = invocation_->current_effect; - effect_t *next = e->next; + dumb_ptr e = invocation_->current_effect; + dumb_ptr next = e->next; int i; #ifdef DEBUG @@ -1439,7 +1409,7 @@ interval_t spell_run(dumb_ptr invocation_, int allow_delete) case EFFECT::ASSIGN: magic_eval(invocation_->env, - &invocation_->env->vars[e->e.e_assign.id], + &invocation_->env->varu[e->e.e_assign.id], e->e.e_assign.expr); break; @@ -1473,19 +1443,16 @@ interval_t spell_run(dumb_ptr invocation_, int allow_delete) dumb_ptr caster = map_id_as_player(invocation_->caster); if (caster) { - env_t *env = invocation_->env; - argrec_t arg[] = { {"@target", - VAR(VAR_TARGET).ty == - TYPE::ENTITY ? 0 : VAR(VAR_TARGET). - v.v_int} - , - {"@caster", invocation_->caster} - , - {"@caster_name$", caster ? caster->status.name : ""} + dumb_ptr env = invocation_->env; + argrec_t arg[] = + { + {"@target", env->VAR(VAR_TARGET).ty == TYPE::ENTITY ? 0 : env->VAR(VAR_TARGET).v.v_int}, + {"@caster", invocation_->caster}, + {"@caster_name$", caster ? caster->status.name : ""}, }; int message_recipient = - VAR(VAR_SCRIPTTARGET).ty == - TYPE::ENTITY ? VAR(VAR_SCRIPTTARGET). + env->VAR(VAR_SCRIPTTARGET).ty == + TYPE::ENTITY ? env->VAR(VAR_SCRIPTTARGET). v.v_int : invocation_->caster; dumb_ptr recipient = map_id_as_player(message_recipient); @@ -1499,11 +1466,11 @@ interval_t spell_run(dumb_ptr invocation_, int allow_delete) // We have to do this or otherwise the client won't think that it's // dealing with an NPC - int newpos = run_script_l(e->e.e_script, - invocation_->script_pos, - message_recipient, - invocation_->bl_id, - 3, arg); + int newpos = run_script_l( + ScriptPointer(&*e->e.e_script, invocation_->script_pos), + message_recipient, + invocation_->bl_id, + 3, arg); /* Returns the new script position, or -1 once the script is finished */ if (newpos != -1) { @@ -1536,7 +1503,7 @@ interval_t spell_run(dumb_ptr invocation_, int allow_delete) e->e.e_op.args_nr, args, e->e.e_op.line_nr, e->e.e_op.column)) - op->op(invocation_->env, e->e.e_op.args_nr, args); + op->op(invocation_->env, const_array(args, e->e.e_op.args_nr)); for (i = 0; i < e->e.e_op.args_nr; i++) magic_clear_var(&args[i]); @@ -1615,9 +1582,9 @@ int spell_attack(int caster_id, int target_id) if (invocation_ && caster->attack_spell_charges > 0) { - magic_clear_var(&invocation_->env->vars[VAR_TARGET]); - invocation_->env->vars[VAR_TARGET].ty = TYPE::ENTITY; - invocation_->env->vars[VAR_TARGET].v.v_int = target_id; + magic_clear_var(&invocation_->env->varu[VAR_TARGET]); + invocation_->env->varu[VAR_TARGET].ty = TYPE::ENTITY; + invocation_->env->varu[VAR_TARGET].v.v_int = target_id; invocation_->current_effect = invocation_->trigger_effect; invocation_->flags &= ~INVOCATION_FLAG::ABORTED; -- cgit v1.2.3-60-g2f50