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.cpp347
1 files changed, 184 insertions, 163 deletions
diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp
index 0305192..26d75af 100644
--- a/src/map/magic-interpreter-base.cpp
+++ b/src/map/magic-interpreter-base.cpp
@@ -1,34 +1,49 @@
-#include "magic.hpp"
+#include "magic-interpreter-aux.hpp"
#include "magic-interpreter.hpp"
+
+#include "../common/cxxstdio.hpp"
+#include "../common/timer.hpp"
+
#include "magic-expr.hpp"
-#include "magic-interpreter-aux.hpp"
-static void set_int_p (val_t * v, int i, int t)
+#include "pc.hpp"
+
+#include "../poison.hpp"
+
+static
+void set_int_p(val_t *v, int i, TYPE t)
{
v->ty = t;
v->v.v_int = i;
}
-#define set_int(v, i) set_int_p(v, i, TY_INT)
-#define set_dir(v, i) set_int_p(v, i, TY_DIR)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-macros"
+
+#define set_int(v, i) set_int_p(v, i, TYPE::INT)
+#define set_dir(v, i) set_int_p(v, i, TYPE::DIR)
#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 *, TY_STRING, v_string);
+static
+void set_string SETTER(char *, TYPE::STRING, v_string)
-static void set_entity (val_t * v, entity_t * e)
+static
+void set_entity(val_t *v, entity_t *e)
{
- v->ty = TY_ENTITY;
+ v->ty = TYPE::ENTITY;
v->v.v_int = e->id;
}
-static void set_invocation (val_t * v, invocation_t * i)
+static
+void set_invocation(val_t *v, invocation_t *i)
{
- v->ty = TY_INVOCATION;
+ v->ty = TYPE::INVOCATION;
v->v.v_int = i->bl.id;
}
-static void set_spell SETTER (spell_t *, TY_SPELL, v_spell);
+static
+void set_spell SETTER(spell_t *, TYPE::SPELL, v_spell)
#define setenv(f, v, x) f(&(env->vars[v]), x)
@@ -41,29 +56,33 @@ static void set_spell SETTER (spell_t *, TY_SPELL, v_spell);
#define set_env_invocation(v, x) setenv(set_invocation, v, x)
#define set_env_spell(v, x) setenv(set_spell, v, x)
+#pragma GCC diagnostic pop
+
magic_conf_t magic_conf; /* Global magic conf */
env_t magic_default_env = { &magic_conf, NULL };
-static int spells_sorted = 0;
+static
+int spells_sorted = 0;
const char *magic_find_invocation(const char *spellname)
{
- int i;
+ int i;
- for (i = 0; i < abs (magic_conf.spells_nr); i++)
- if (!strcmp (magic_conf.spells[i]->name, spellname))
+ for (i = 0; i < abs(magic_conf.spells_nr); i++)
+ if (!strcmp(magic_conf.spells[i]->name, spellname))
return magic_conf.spells[i]->invocation;
return NULL;
}
-static int spell_compare (const void *lhs, const void *rhs)
+static
+int spell_compare(const void *lhs, const void *rhs)
{
- return strcmp ((*((spell_t **) lhs))->invocation,
- (*((spell_t **) rhs))->invocation);
+ return strcmp((*((const spell_t *const*) lhs))->invocation,
+ (*((const spell_t *const*) rhs))->invocation);
}
-spell_t *magic_find_spell (char *invocation)
+spell_t *magic_find_spell(char *invocation)
{
spell_t key;
spell_t *keyp = &key;
@@ -71,7 +90,7 @@ spell_t *magic_find_spell (char *invocation)
if (!spells_sorted)
{
- qsort (magic_conf.spells, magic_conf.spells_nr, sizeof (spell_t *),
+ qsort(magic_conf.spells, magic_conf.spells_nr, sizeof(spell_t *),
spell_compare);
spells_sorted = 1;
}
@@ -80,8 +99,8 @@ spell_t *magic_find_spell (char *invocation)
retval =
((spell_t **)
- bsearch (&keyp, magic_conf.spells, magic_conf.spells_nr,
- sizeof (spell_t *), spell_compare));
+ bsearch(&keyp, magic_conf.spells, magic_conf.spells_nr,
+ sizeof(spell_t *), spell_compare));
if (!retval)
return NULL;
@@ -93,24 +112,25 @@ spell_t *magic_find_spell (char *invocation)
/* Spell anchors */
/* -------------------------------------------------------------------------------- */
-static int compare_teleport_anchor (const void *lhs, const void *rhs)
+static
+int compare_teleport_anchor(const void *lhs, const void *rhs)
{
- return strcmp ((*((teleport_anchor_t **) lhs))->invocation,
- (*((teleport_anchor_t **) rhs))->invocation);
+ 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)
{
- int i;
+ int i;
- for (i = 0; i < abs (magic_conf.anchors_nr); i++)
- if (!strcmp (magic_conf.anchors[i]->name, 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;
return NULL;
}
-teleport_anchor_t *magic_find_anchor (char *name)
+teleport_anchor_t *magic_find_anchor(char *name)
{
teleport_anchor_t key;
teleport_anchor_t *keyp = &key;
@@ -118,17 +138,17 @@ teleport_anchor_t *magic_find_anchor (char *name)
if (magic_conf.anchors_nr > 0)
{ /* unsorted */
- qsort (magic_conf.anchors, magic_conf.anchors_nr,
- sizeof (teleport_anchor_t *), compare_teleport_anchor);
+ 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,
+ retval = (teleport_anchor_t **) bsearch(&keyp,
magic_conf.anchors,
-magic_conf.anchors_nr,
- sizeof (teleport_anchor_t *),
+ sizeof(teleport_anchor_t *),
compare_teleport_anchor);
if (!retval)
@@ -141,83 +161,86 @@ teleport_anchor_t *magic_find_anchor (char *name)
/* Spell guard checks */
/* -------------------------------------------------------------------------------- */
-static env_t *alloc_env (magic_conf_t * conf)
+static
+env_t *alloc_env(magic_conf_t *conf)
{
env_t *env;
- CREATE (env, env_t, 1);
- CREATE (env->vars, val_t, conf->vars_nr);
+ CREATE(env, env_t, 1);
+ CREATE(env->vars, val_t, conf->vars_nr);
env->base_env = conf;
return env;
}
-static env_t *clone_env (env_t * src)
+static
+env_t *clone_env(env_t *src)
{
- env_t *retval = alloc_env (src->base_env);
- int i;
+ env_t *retval = alloc_env(src->base_env);
+ int i;
for (i = 0; i < src->base_env->vars_nr; i++)
- magic_copy_var (&retval->vars[i], &src->vars[i]);
+ magic_copy_var(&retval->vars[i], &src->vars[i]);
return retval;
}
-void magic_free_env (env_t * env)
+void magic_free_env(env_t *env)
{
- int i;
+ int i;
for (i = 0; i < env->base_env->vars_nr; i++)
- magic_clear_var (&env->vars[i]);
- free (env);
+ magic_clear_var(&env->vars[i]);
+ free(env);
}
-env_t *spell_create_env (magic_conf_t * conf, spell_t * spell,
- character_t * caster, int spellpower, char *param)
+env_t *spell_create_env(magic_conf_t *conf, spell_t *spell,
+ character_t *caster, int spellpower, char *param)
{
- env_t *env = alloc_env (conf);
+ env_t *env = alloc_env(conf);
switch (spell->spellarg_ty)
{
- case SPELLARG_STRING:
- set_env_string (spell->arg, param);
+ case SPELLARG::STRING:
+ set_env_string(spell->arg, param);
break;
- case SPELLARG_PC:
+ case SPELLARG::PC:
{
- character_t *subject = map_nick2sd (param);
+ character_t *subject = map_nick2sd(param);
if (!subject)
subject = caster;
- set_env_entity (spell->arg, &subject->bl);
- free (param);
+ set_env_entity(spell->arg, &subject->bl);
+ free(param);
break;
}
- case SPELLARG_NONE:
- free (param);
+ case SPELLARG::NONE:
+ free(param);
break;
default:
- free (param);
- fprintf (stderr, "Unexpected spellarg type %d\n",
+ free(param);
+ FPRINTF(stderr, "Unexpected spellarg type %d\n",
spell->spellarg_ty);
}
- set_env_entity (VAR_CASTER, &caster->bl);
- set_env_int (VAR_SPELLPOWER, spellpower);
- set_env_spell (VAR_SPELL, spell);
+ set_env_entity(VAR_CASTER, &caster->bl);
+ set_env_int(VAR_SPELLPOWER, spellpower);
+ set_env_spell(VAR_SPELL, spell);
return env;
}
-static void free_components (component_t ** component_holder)
+static
+void free_components(component_t ** component_holder)
{
if (*component_holder == NULL)
return;
- free_components (&(*component_holder)->next);
- free (*component_holder);
+ free_components(&(*component_holder)->next);
+ free(*component_holder);
*component_holder = NULL;
}
-void magic_add_component (component_t ** component_holder, int id, int count)
+void magic_add_component(component_t ** component_holder, int id, int count)
{
if (count <= 0)
return;
@@ -225,7 +248,7 @@ void magic_add_component (component_t ** component_holder, int id, int count)
if (*component_holder == NULL)
{
component_t *component =
- (component_t *) malloc (sizeof (component_t));
+ (component_t *) malloc(sizeof(component_t));
component->next = NULL;
component->item_id = id;
component->count = count;
@@ -240,33 +263,35 @@ void magic_add_component (component_t ** component_holder, int id, int count)
return;
}
else
- magic_add_component (&component->next, id, count);
+ magic_add_component(&component->next, id, count);
/* Tail-recurse; gcc can optimise this. Not that it matters. */
}
}
-static void
-copy_components (component_t ** component_holder, component_t * component)
+static
+void copy_components(component_t ** component_holder, component_t *component)
{
if (component == NULL)
return;
- magic_add_component (component_holder, component->item_id,
+ magic_add_component(component_holder, component->item_id,
component->count);
- copy_components (component_holder, component->next);
+ copy_components(component_holder, component->next);
}
typedef struct spellguard_check
{
component_t *catalysts, *components;
- int mana, casttime;
+ int mana;
+ interval_t casttime;
} spellguard_check_t;
-static int check_prerequisites (character_t * caster, component_t * component)
+static
+int check_prerequisites(character_t *caster, component_t *component)
{
while (component)
{
- if (pc_count_all_items (caster, component->item_id)
+ if (pc_count_all_items(caster, component->item_id)
< component->count)
return 0; /* insufficient */
@@ -276,59 +301,51 @@ static int check_prerequisites (character_t * caster, component_t * component)
return 1;
}
-static void consume_components (character_t * caster, component_t * component)
+static
+void consume_components(character_t *caster, component_t *component)
{
while (component)
{
- pc_remove_items (caster, component->item_id, component->count);
+ pc_remove_items(caster, component->item_id, component->count);
component = component->next;
}
}
-static int
-spellguard_can_satisfy (spellguard_check_t * check, character_t * caster,
- env_t * env, int *near_miss)
+static
+int spellguard_can_satisfy(spellguard_check_t *check, character_t *caster,
+ env_t *env, int *near_miss)
{
- unsigned int tick = gettick ();
-
- int retval = check_prerequisites (caster, check->catalysts);
+ tick_t tick = gettick();
-/*
- fprintf(stderr, "MC(%d/%s)? %d%d%d%d (%u <= %u)\n",
- caster->bl.id, caster->status.name,
- retval,
- caster->cast_tick <= tick,
- check->mana <= caster->status.sp,
- check_prerequisites(caster, check->components),
- caster->cast_tick, tick);
-*/
+ int retval = check_prerequisites(caster, check->catalysts);
if (retval && near_miss)
*near_miss = 1; // close enough!
retval = retval && caster->cast_tick <= tick /* Hasn't cast a spell too recently */
&& check->mana <= caster->status.sp
- && check_prerequisites (caster, check->components);
+ && check_prerequisites(caster, check->components);
if (retval)
{
- unsigned int casttime = (unsigned int) check->casttime;
+ interval_t casttime = check->casttime;
- if (VAR (VAR_MIN_CASTTIME).ty == TY_INT)
- casttime = MAX (casttime, VAR (VAR_MIN_CASTTIME).v.v_int);
+ if (VAR(VAR_MIN_CASTTIME).ty == TYPE::INT)
+ casttime = max(casttime, static_cast<interval_t>(VAR(VAR_MIN_CASTTIME).v.v_int));
caster->cast_tick = tick + casttime; /* Make sure not to cast too frequently */
- consume_components (caster, check->components);
- pc_heal (caster, 0, -check->mana);
+ consume_components(caster, check->components);
+ pc_heal(caster, 0, -check->mana);
}
return retval;
}
-static effect_set_t *spellguard_check_sub (spellguard_check_t * check,
- spellguard_t * guard,
- character_t * caster, env_t * env,
+static
+effect_set_t *spellguard_check_sub(spellguard_check_t *check,
+ spellguard_t *guard,
+ character_t *caster, env_t *env,
int *near_miss)
{
if (guard == NULL)
@@ -336,20 +353,20 @@ static effect_set_t *spellguard_check_sub (spellguard_check_t * check,
switch (guard->ty)
{
- case SPELLGUARD_CONDITION:
- if (!magic_eval_int (env, guard->s.s_condition))
+ case SPELLGUARD::CONDITION:
+ if (!magic_eval_int(env, guard->s.s_condition))
return NULL;
break;
- case SPELLGUARD_COMPONENTS:
- copy_components (&check->components, guard->s.s_components);
+ case SPELLGUARD::COMPONENTS:
+ copy_components(&check->components, guard->s.s_components);
break;
- case SPELLGUARD_CATALYSTS:
- copy_components (&check->catalysts, guard->s.s_catalysts);
+ case SPELLGUARD::CATALYSTS:
+ copy_components(&check->catalysts, guard->s.s_catalysts);
break;
- case SPELLGUARD_CHOICE:
+ case SPELLGUARD::CHOICE:
{
spellguard_check_t altcheck = *check;
effect_set_t *retval;
@@ -357,57 +374,60 @@ static effect_set_t *spellguard_check_sub (spellguard_check_t * check,
altcheck.components = NULL;
altcheck.catalysts = NULL;
- copy_components (&altcheck.catalysts, check->catalysts);
- copy_components (&altcheck.components, check->components);
+ copy_components(&altcheck.catalysts, check->catalysts);
+ copy_components(&altcheck.components, check->components);
retval =
- spellguard_check_sub (&altcheck, guard->next, caster, env,
+ spellguard_check_sub(&altcheck, guard->next, caster, env,
near_miss);
- free_components (&altcheck.catalysts);
- free_components (&altcheck.components);
+ free_components(&altcheck.catalysts);
+ free_components(&altcheck.components);
if (retval)
return retval;
else
- return spellguard_check_sub (check, guard->s.s_alt, caster,
+ return spellguard_check_sub(check, guard->s.s_alt, caster,
env, near_miss);
}
- case SPELLGUARD_MANA:
- check->mana += magic_eval_int (env, guard->s.s_mana);
+ case SPELLGUARD::MANA:
+ check->mana += magic_eval_int(env, guard->s.s_mana);
break;
- case SPELLGUARD_CASTTIME:
- check->casttime += magic_eval_int (env, guard->s.s_mana);
+ case SPELLGUARD::CASTTIME:
+ check->casttime += static_cast<interval_t>(magic_eval_int(env, guard->s.s_mana));
break;
- case SPELLGUARD_EFFECT:
- if (spellguard_can_satisfy (check, caster, env, near_miss))
+ case SPELLGUARD::EFFECT:
+ if (spellguard_can_satisfy(check, caster, env, near_miss))
return &guard->s.s_effect;
else
return NULL;
default:
- fprintf (stderr, "Unexpected spellguard type %d\n", guard->ty);
+ FPRINTF(stderr, "Unexpected spellguard type %d\n",
+ guard->ty);
return NULL;
}
- return spellguard_check_sub (check, guard->next, caster, env, near_miss);
+ return spellguard_check_sub(check, guard->next, caster, env, near_miss);
}
-static effect_set_t *check_spellguard (spellguard_t * guard,
- character_t * caster, env_t * env,
+static
+effect_set_t *check_spellguard(spellguard_t *guard,
+ character_t *caster, env_t *env,
int *near_miss)
{
spellguard_check_t check;
effect_set_t *retval;
check.catalysts = NULL;
check.components = NULL;
- check.mana = check.casttime = 0;
+ check.mana = 0;
+ check.casttime = interval_t::zero();
- retval = spellguard_check_sub (&check, guard, caster, env, near_miss);
+ retval = spellguard_check_sub(&check, guard, caster, env, near_miss);
- free_components (&check.catalysts);
- free_components (&check.components);
+ free_components(&check.catalysts);
+ free_components(&check.components);
return retval;
}
@@ -416,114 +436,115 @@ static effect_set_t *check_spellguard (spellguard_t * guard,
/* Public API */
/* -------------------------------------------------------------------------------- */
-effect_set_t *spell_trigger (spell_t * spell, character_t * caster,
- env_t * env, int *near_miss)
+effect_set_t *spell_trigger(spell_t *spell, character_t *caster,
+ env_t *env, int *near_miss)
{
- int i;
+ int i;
spellguard_t *guard = spell->spellguard;
if (near_miss)
*near_miss = 0;
for (i = 0; i < spell->letdefs_nr; i++)
- magic_eval (env,
+ magic_eval(env,
&env->vars[spell->letdefs[i].id], spell->letdefs[i].expr);
- return check_spellguard (guard, caster, env, near_miss);
+ return check_spellguard(guard, caster, env, near_miss);
}
-static void spell_set_location (invocation_t * invocation, entity_t * entity)
+static
+void spell_set_location(invocation_t *invocation, entity_t *entity)
{
- magic_clear_var (&invocation->env->vars[VAR_LOCATION]);
- invocation->env->vars[VAR_LOCATION].ty = TY_LOCATION;
+ 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->m;
invocation->env->vars[VAR_LOCATION].v.v_location.x = entity->x;
invocation->env->vars[VAR_LOCATION].v.v_location.y = entity->y;
}
-void spell_update_location (invocation_t * invocation)
+void spell_update_location(invocation_t *invocation)
{
- if (invocation->spell->flags & SPELL_FLAG_LOCAL)
+ if (bool(invocation->spell->flags & SPELL_FLAG::LOCAL))
return;
else
{
- character_t *owner = (character_t *) map_id2bl (invocation->subject);
+ character_t *owner = (character_t *) map_id2bl(invocation->subject);
if (!owner)
return;
- spell_set_location (invocation, (entity_t *) owner);
+ spell_set_location(invocation, (entity_t *) owner);
}
}
-invocation_t *spell_instantiate (effect_set_t * effect_set, env_t * env)
+invocation_t *spell_instantiate(effect_set_t *effect_set, env_t *env)
{
invocation_t *retval;
- CREATE (retval, invocation_t, 1);
+ CREATE(retval, invocation_t, 1);
entity_t *caster;
retval->env = env;
- retval->caster = VAR (VAR_CASTER).v.v_int;
- retval->spell = VAR (VAR_SPELL).v.v_spell;
+ retval->caster = VAR(VAR_CASTER).v.v_int;
+ retval->spell = VAR(VAR_SPELL).v.v_spell;
retval->stack_size = 0;
retval->current_effect = effect_set->effect;
retval->trigger_effect = effect_set->at_trigger;
retval->end_effect = effect_set->at_end;
- caster = map_id2bl (retval->caster); // must still exist
- retval->bl.id = map_addobject (&retval->bl);
- retval->bl.type = BL_SPELL;
+ caster = map_id2bl(retval->caster); // must still exist
+ retval->bl.id = map_addobject(&retval->bl);
+ retval->bl.type = BL::SPELL;
retval->bl.m = caster->m;
retval->bl.x = caster->x;
retval->bl.y = caster->y;
- map_addblock (&retval->bl);
- set_env_invocation (VAR_INVOCATION, retval);
+ map_addblock(&retval->bl);
+ set_env_invocation(VAR_INVOCATION, retval);
return retval;
}
-invocation_t *spell_clone_effect (invocation_t * base)
+invocation_t *spell_clone_effect(invocation_t *base)
{
- invocation_t *retval = (invocation_t *) malloc (sizeof (invocation_t));
+ invocation_t *retval = (invocation_t *) calloc(1, sizeof(invocation_t));
env_t *env;
- memcpy (retval, base, sizeof (invocation_t));
+ memcpy(retval, base, sizeof(invocation_t));
- retval->env = clone_env (retval->env);
+ retval->env = clone_env(retval->env);
env = retval->env;
retval->current_effect = retval->trigger_effect;
retval->next_invocation = NULL;
retval->end_effect = NULL;
retval->script_pos = 0;
retval->stack_size = 0;
- retval->timer = 0;
+ // retval->timer = 0;
retval->subject = 0;
retval->status_change_refs_nr = 0;
retval->status_change_refs = NULL;
- retval->flags = 0;
+ retval->flags = INVOCATION_FLAG::ZERO;
retval->bl.id = 0;
retval->bl.prev = NULL;
retval->bl.next = NULL;
- retval->bl.id = map_addobject (&retval->bl);
- set_env_invocation (VAR_INVOCATION, retval);
+ retval->bl.id = map_addobject(&retval->bl);
+ set_env_invocation(VAR_INVOCATION, retval);
return retval;
}
-void spell_bind (character_t * subject, invocation_t * invocation)
+void spell_bind(character_t *subject, invocation_t *invocation)
{
/* Only bind nonlocal spells */
- if (!(invocation->spell->flags & SPELL_FLAG_LOCAL))
+ if (!bool(invocation->spell->flags & SPELL_FLAG::LOCAL))
{
- if (invocation->flags & INVOCATION_FLAG_BOUND
+ if (bool(invocation->flags & INVOCATION_FLAG::BOUND)
|| invocation->subject || invocation->next_invocation)
{
int *i = NULL;
- fprintf (stderr,
+ FPRINTF(stderr,
"[magic] INTERNAL ERROR: Attempt to re-bind spell invocation `%s'\n",
invocation->spell->name);
*i = 1;
@@ -532,14 +553,14 @@ void spell_bind (character_t * subject, invocation_t * invocation)
invocation->next_invocation = subject->active_spells;
subject->active_spells = invocation;
- invocation->flags |= INVOCATION_FLAG_BOUND;
+ invocation->flags |= INVOCATION_FLAG::BOUND;
invocation->subject = subject->bl.id;
}
- spell_set_location (invocation, (entity_t *) subject);
+ spell_set_location(invocation, (entity_t *) subject);
}
-int spell_unbind (character_t * subject, invocation_t * invocation)
+int spell_unbind(character_t *subject, invocation_t *invocation)
{
invocation_t **seeker = &subject->active_spells;
@@ -549,7 +570,7 @@ int spell_unbind (character_t * subject, invocation_t * invocation)
{
*seeker = invocation->next_invocation;
- invocation->flags &= ~INVOCATION_FLAG_BOUND;
+ invocation->flags &= ~INVOCATION_FLAG::BOUND;
invocation->next_invocation = NULL;
invocation->subject = 0;