summaryrefslogtreecommitdiff
path: root/src/map/magic-interpreter-base.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/magic-interpreter-base.cpp')
-rw-r--r--src/map/magic-interpreter-base.cpp217
1 files changed, 77 insertions, 140 deletions
diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp
index 775e7e4..e6c1f37 100644
--- a/src/map/magic-interpreter-base.cpp
+++ b/src/map/magic-interpreter-base.cpp
@@ -17,6 +17,7 @@ void set_int_p(val_t *v, int i, TYPE t)
v->v.v_int = i;
}
+#warning "This code should die"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-macros"
@@ -26,7 +27,7 @@ void set_int_p(val_t *v, int i, TYPE t)
#define SETTER(tty, dyn_ty, field) (val_t *v, tty x) { v->ty = dyn_ty; v->v.field = x; }
static
-void set_string SETTER(char *, TYPE::STRING, v_string)
+void set_string SETTER(dumb_string, TYPE::STRING, v_string)
static
void set_entity(val_t *v, dumb_ptr<block_list> e)
@@ -43,9 +44,9 @@ void set_invocation(val_t *v, dumb_ptr<invocation> i)
}
static
-void set_spell SETTER(spell_t *, TYPE::SPELL, v_spell)
+void set_spell SETTER(dumb_ptr<spell_t>, TYPE::SPELL, v_spell)
-#define setenv(f, v, x) f(&(env->vars[v]), x)
+#define setenv(f, v, x) f(&(env->varu[v]), x)
#define set_env_int(v, x) setenv(set_int, v, x)
#define set_env_dir(v, x) setenv(set_dir, v, x)
@@ -61,100 +62,45 @@ void set_spell SETTER(spell_t *, TYPE::SPELL, v_spell)
magic_conf_t magic_conf; /* Global magic conf */
env_t magic_default_env = { &magic_conf, NULL };
-static
-int spells_sorted = 0;
-
-const char *magic_find_invocation(const char *spellname)
+const char *magic_find_invocation(const std::string& spellname)
{
- int i;
-
- for (i = 0; i < abs(magic_conf.spells_nr); i++)
- if (!strcmp(magic_conf.spells[i]->name, spellname))
- return magic_conf.spells[i]->invocation;
+ auto it = magic_conf.spells_by_name.find(spellname);
+ if (it != magic_conf.spells_by_name.end())
+ return it->second->invocation.c_str();
return NULL;
}
-static
-int spell_compare(const void *lhs, const void *rhs)
-{
- return strcmp((*((const spell_t *const*) lhs))->invocation,
- (*((const spell_t *const*) rhs))->invocation);
-}
-
-spell_t *magic_find_spell(char *invocation)
+dumb_ptr<spell_t> magic_find_spell(const std::string& invocation)
{
- spell_t key;
- spell_t *keyp = &key;
- spell_t **retval;
+ auto it = magic_conf.spells_by_invocation.find(invocation);
+ if (it != magic_conf.spells_by_invocation.end())
+ return it->second;
- if (!spells_sorted)
- {
- qsort(magic_conf.spells, magic_conf.spells_nr, sizeof(spell_t *),
- spell_compare);
- spells_sorted = 1;
- }
-
- key.invocation = invocation;
-
- retval =
- ((spell_t **)
- bsearch(&keyp, magic_conf.spells, magic_conf.spells_nr,
- sizeof(spell_t *), spell_compare));
-
- if (!retval)
- return NULL;
- else
- return *retval;
+ return NULL;
}
/* -------------------------------------------------------------------------------- */
/* Spell anchors */
/* -------------------------------------------------------------------------------- */
-static
-int compare_teleport_anchor(const void *lhs, const void *rhs)
-{
- return strcmp((*((const teleport_anchor_t *const*) lhs))->invocation,
- (*((const teleport_anchor_t *const*) rhs))->invocation);
-}
-
-const char *magic_find_anchor_invocation(const char *anchor_name)
+const char *magic_find_anchor_invocation(const std::string& anchor_name)
{
- int i;
+ auto it = magic_conf.anchors_by_name.find(anchor_name);
- for (i = 0; i < abs(magic_conf.anchors_nr); i++)
- if (!strcmp(magic_conf.anchors[i]->name, anchor_name))
- return magic_conf.anchors[i]->invocation;
+ if (it != magic_conf.anchors_by_name.end())
+ return it->second->invocation.c_str();
return NULL;
}
-teleport_anchor_t *magic_find_anchor(char *name)
+dumb_ptr<teleport_anchor_t> magic_find_anchor(const std::string& name)
{
- teleport_anchor_t key;
- teleport_anchor_t *keyp = &key;
- teleport_anchor_t **retval;
-
- if (magic_conf.anchors_nr > 0)
- { /* unsorted */
- qsort(magic_conf.anchors, magic_conf.anchors_nr,
- sizeof(teleport_anchor_t *), compare_teleport_anchor);
- magic_conf.anchors_nr = -magic_conf.anchors_nr;
- }
-
- key.invocation = name;
-
- retval = (teleport_anchor_t **) bsearch(&keyp,
- magic_conf.anchors,
- -magic_conf.anchors_nr,
- sizeof(teleport_anchor_t *),
- compare_teleport_anchor);
+ auto it = magic_conf.anchors_by_invocation.find(name);
+ if (it != magic_conf.anchors_by_invocation.end())
+ return it->second;
- if (!retval)
- return NULL;
- else
- return *retval;
+ return NULL;
}
/* -------------------------------------------------------------------------------- */
@@ -162,63 +108,59 @@ teleport_anchor_t *magic_find_anchor(char *name)
/* -------------------------------------------------------------------------------- */
static
-env_t *alloc_env(magic_conf_t *conf)
+dumb_ptr<env_t> alloc_env(magic_conf_t *conf)
{
- env_t *env;
- CREATE(env, env_t, 1);
- CREATE(env->vars, val_t, conf->vars_nr);
+ auto env = dumb_ptr<env_t>::make();
+ env->varu = make_unique<val_t[]>(conf->varv.size());
env->base_env = conf;
return env;
}
static
-env_t *clone_env(env_t *src)
+dumb_ptr<env_t> clone_env(dumb_ptr<env_t> src)
{
- env_t *retval = alloc_env(src->base_env);
- int i;
+ dumb_ptr<env_t> retval = alloc_env(src->base_env);
- for (i = 0; i < src->base_env->vars_nr; i++)
- magic_copy_var(&retval->vars[i], &src->vars[i]);
+ for (int i = 0; i < src->base_env->varv.size(); i++)
+ magic_copy_var(&retval->varu[i], &src->varu[i]);
return retval;
}
-void magic_free_env(env_t *env)
+void magic_free_env(dumb_ptr<env_t> env)
{
- int i;
- for (i = 0; i < env->base_env->vars_nr; i++)
- magic_clear_var(&env->vars[i]);
- free(env);
+ for (int i = 0; i < env->base_env->varv.size(); i++)
+ magic_clear_var(&env->varu[i]);
+ // handled by std::unique_ptr now. Was a memory leak before.
+ // delete[] env->vars;
+ env.delete_();
}
-env_t *spell_create_env(magic_conf_t *conf, spell_t *spell,
- dumb_ptr<map_session_data> caster, int spellpower, char *param)
+dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell,
+ dumb_ptr<map_session_data> caster, int spellpower, const_string param)
{
- env_t *env = alloc_env(conf);
+ dumb_ptr<env_t> env = alloc_env(conf);
switch (spell->spellarg_ty)
{
case SPELLARG::STRING:
- set_env_string(spell->arg, param);
+ set_env_string(spell->arg, dumb_string::copyc(param));
break;
case SPELLARG::PC:
{
- dumb_ptr<map_session_data> subject = map_nick2sd(param);
+ dumb_ptr<map_session_data> subject = map_nick2sd(std::string(param.begin(), param.end()).c_str());
if (!subject)
subject = caster;
set_env_entity(spell->arg, subject);
- free(param);
break;
}
case SPELLARG::NONE:
- free(param);
break;
default:
- free(param);
FPRINTF(stderr, "Unexpected spellarg type %d\n",
spell->spellarg_ty);
}
@@ -231,24 +173,23 @@ env_t *spell_create_env(magic_conf_t *conf, spell_t *spell,
}
static
-void free_components(component_t ** component_holder)
+void free_components(dumb_ptr<component_t> *component_holder)
{
if (*component_holder == NULL)
return;
free_components(&(*component_holder)->next);
- free(*component_holder);
+ (*component_holder).delete_();
*component_holder = NULL;
}
-void magic_add_component(component_t ** component_holder, int id, int count)
+void magic_add_component(dumb_ptr<component_t> *component_holder, int id, int count)
{
if (count <= 0)
return;
if (*component_holder == NULL)
{
- component_t *component =
- (component_t *) malloc(sizeof(component_t));
+ auto component = dumb_ptr<component_t>::make();
component->next = NULL;
component->item_id = id;
component->count = count;
@@ -256,7 +197,7 @@ void magic_add_component(component_t ** component_holder, int id, int count)
}
else
{
- component_t *component = *component_holder;
+ dumb_ptr<component_t> component = *component_holder;
if (component->item_id == id)
{
component->count += count;
@@ -269,30 +210,28 @@ void magic_add_component(component_t ** component_holder, int id, int count)
}
static
-void copy_components(component_t ** component_holder, component_t *component)
+void copy_components(dumb_ptr<component_t> *component_holder, dumb_ptr<component_t> component)
{
if (component == NULL)
return;
- magic_add_component(component_holder, component->item_id,
- component->count);
+ magic_add_component(component_holder, component->item_id, component->count);
copy_components(component_holder, component->next);
}
typedef struct spellguard_check
{
- component_t *catalysts, *components;
+ dumb_ptr<component_t> catalysts, components;
int mana;
interval_t casttime;
} spellguard_check_t;
static
-int check_prerequisites(dumb_ptr<map_session_data> caster, component_t *component)
+int check_prerequisites(dumb_ptr<map_session_data> caster, dumb_ptr<component_t> component)
{
while (component)
{
- if (pc_count_all_items(caster, component->item_id)
- < component->count)
+ if (pc_count_all_items(caster, component->item_id) < component->count)
return 0; /* insufficient */
component = component->next;
@@ -302,7 +241,7 @@ int check_prerequisites(dumb_ptr<map_session_data> caster, component_t *componen
}
static
-void consume_components(dumb_ptr<map_session_data> caster, component_t *component)
+void consume_components(dumb_ptr<map_session_data> caster, dumb_ptr<component_t> component)
{
while (component)
{
@@ -313,7 +252,7 @@ void consume_components(dumb_ptr<map_session_data> caster, component_t *componen
static
int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr<map_session_data> caster,
- env_t *env, int *near_miss)
+ dumb_ptr<env_t> env, int *near_miss)
{
tick_t tick = gettick();
@@ -330,8 +269,8 @@ int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr<map_session_data>
{
interval_t casttime = check->casttime;
- if (VAR(VAR_MIN_CASTTIME).ty == TYPE::INT)
- casttime = max(casttime, static_cast<interval_t>(VAR(VAR_MIN_CASTTIME).v.v_int));
+ if (env->VAR(VAR_MIN_CASTTIME).ty == TYPE::INT)
+ casttime = max(casttime, static_cast<interval_t>(env->VAR(VAR_MIN_CASTTIME).v.v_int));
caster->cast_tick = tick + casttime; /* Make sure not to cast too frequently */
@@ -344,9 +283,10 @@ int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr<map_session_data>
static
effect_set_t *spellguard_check_sub(spellguard_check_t *check,
- spellguard_t *guard,
- dumb_ptr<map_session_data> caster, env_t *env,
- int *near_miss)
+ dumb_ptr<spellguard_t> guard,
+ dumb_ptr<map_session_data> caster,
+ dumb_ptr<env_t> env,
+ int *near_miss)
{
if (guard == NULL)
return NULL;
@@ -413,9 +353,9 @@ effect_set_t *spellguard_check_sub(spellguard_check_t *check,
}
static
-effect_set_t *check_spellguard(spellguard_t *guard,
- dumb_ptr<map_session_data> caster, env_t *env,
- int *near_miss)
+effect_set_t *check_spellguard(dumb_ptr<spellguard_t> guard,
+ dumb_ptr<map_session_data> caster, dumb_ptr<env_t> env,
+ int *near_miss)
{
spellguard_check_t check;
effect_set_t *retval;
@@ -436,18 +376,16 @@ effect_set_t *check_spellguard(spellguard_t *guard,
/* Public API */
/* -------------------------------------------------------------------------------- */
-effect_set_t *spell_trigger(spell_t *spell, dumb_ptr<map_session_data> caster,
- env_t *env, int *near_miss)
+effect_set_t *spell_trigger(dumb_ptr<spell_t> spell, dumb_ptr<map_session_data> caster,
+ dumb_ptr<env_t> env, int *near_miss)
{
- int i;
- spellguard_t *guard = spell->spellguard;
+ dumb_ptr<spellguard_t> guard = spell->spellguard;
if (near_miss)
*near_miss = 0;
- for (i = 0; i < spell->letdefs_nr; i++)
- magic_eval(env,
- &env->vars[spell->letdefs[i].id], spell->letdefs[i].expr);
+ for (letdef_t& ld : spell->letdefv)
+ magic_eval(env, &env->varu[ld.id], ld.expr);
return check_spellguard(guard, caster, env, near_miss);
}
@@ -455,11 +393,11 @@ effect_set_t *spell_trigger(spell_t *spell, dumb_ptr<map_session_data> caster,
static
void spell_set_location(dumb_ptr<invocation> invocation, dumb_ptr<block_list> entity)
{
- magic_clear_var(&invocation->env->vars[VAR_LOCATION]);
- invocation->env->vars[VAR_LOCATION].ty = TYPE::LOCATION;
- invocation->env->vars[VAR_LOCATION].v.v_location.m = entity->bl_m;
- invocation->env->vars[VAR_LOCATION].v.v_location.x = entity->bl_x;
- invocation->env->vars[VAR_LOCATION].v.v_location.y = entity->bl_y;
+ magic_clear_var(&invocation->env->varu[VAR_LOCATION]);
+ invocation->env->varu[VAR_LOCATION].ty = TYPE::LOCATION;
+ invocation->env->varu[VAR_LOCATION].v.v_location.m = entity->bl_m;
+ invocation->env->varu[VAR_LOCATION].v.v_location.x = entity->bl_x;
+ invocation->env->varu[VAR_LOCATION].v.v_location.y = entity->bl_y;
}
void spell_update_location(dumb_ptr<invocation> invocation)
@@ -477,7 +415,7 @@ void spell_update_location(dumb_ptr<invocation> invocation)
}
}
-dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, env_t *env)
+dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, dumb_ptr<env_t> env)
{
dumb_ptr<invocation> retval;
retval.new_();
@@ -485,8 +423,8 @@ dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, env_t *env)
retval->env = env;
- retval->caster = VAR(VAR_CASTER).v.v_int;
- retval->spell = VAR(VAR_SPELL).v.v_spell;
+ retval->caster = env->VAR(VAR_CASTER).v.v_int;
+ retval->spell = env->VAR(VAR_SPELL).v.v_spell;
retval->stack_size = 0;
retval->current_effect = effect_set->effect;
retval->trigger_effect = effect_set->at_trigger;
@@ -516,7 +454,7 @@ dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> base)
retval->next_invocation = NULL;
retval->flags = INVOCATION_FLAG::ZERO;
- env_t *env = retval->env = clone_env(base->env);
+ dumb_ptr<env_t> env = retval->env = clone_env(base->env);
retval->spell = base->spell;
retval->caster = base->caster;
retval->subject = 0;
@@ -528,8 +466,7 @@ dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> base)
retval->current_effect = base->trigger_effect;
retval->trigger_effect = base->trigger_effect;
retval->end_effect = NULL;
- retval->status_change_refs_nr = 0;
- retval->status_change_refs = NULL;
+ // retval->status_change_refs = NULL;
retval->bl_id = 0;
retval->bl_prev = NULL;
@@ -568,7 +505,7 @@ void spell_bind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocat
invocation->subject = subject->bl_id;
}
- spell_set_location(invocation, (dumb_ptr<block_list> ) subject);
+ spell_set_location(invocation, subject);
}
int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocation_)