From 506a41d6926405b2753894f0b40130b4077828b3 Mon Sep 17 00:00:00 2001 From: wushin Date: Tue, 9 Jun 2015 01:06:22 -0500 Subject: Remove old Magic --- src/map/magic-interpreter-base.cpp | 553 ------------------------------------- 1 file changed, 553 deletions(-) delete mode 100644 src/map/magic-interpreter-base.cpp (limited to 'src/map/magic-interpreter-base.cpp') diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp deleted file mode 100644 index c2be363..0000000 --- a/src/map/magic-interpreter-base.cpp +++ /dev/null @@ -1,553 +0,0 @@ -#include "magic-interpreter-base.hpp" -// magic-interpreter-base.cpp - Core of the old magic system. -// -// Copyright © 2004-2011 The Mana World Development Team -// Copyright © 2011-2014 Ben Longbons -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include - -#include "../strings/astring.hpp" -#include "../strings/xstring.hpp" - -#include "../io/cxxstdio.hpp" - -#include "../mmo/cxxstdio_enums.hpp" - -#include "../net/timer.hpp" - -#include "globals.hpp" -#include "magic.hpp" -#include "magic-expr.hpp" -#include "magic-interpreter.hpp" -#include "pc.hpp" - -#include "../poison.hpp" - - -namespace tmwa -{ -namespace map -{ -namespace magic -{ -static -void set_int(val_t *v, int i) -{ - *v = ValInt{i}; -} - -static __attribute__((unused)) -void set_dir(val_t *v, DIR d) -{ - *v = ValDir{d}; -} - - -static -void set_string(val_t *v, RString x) -{ - *v = ValString{x}; -} - -static -void set_entity(val_t *v, dumb_ptr e) -{ - *v = ValEntityInt{e->bl_id}; -} - -static -void set_invocation(val_t *v, dumb_ptr i) -{ - *v = ValInvocationInt{i->bl_id}; -} - -static -void set_spell(val_t *v, dumb_ptr x) -{ - *v = ValSpell{x}; -} - -AString magic_find_invocation(XString spellname) -{ - auto it = magic_conf.spells_by_name.find(spellname); - if (it != magic_conf.spells_by_name.end()) - return it->second->invocation; - - return AString(); -} - -dumb_ptr magic_find_spell(XString invocation) -{ - auto it = magic_conf.spells_by_invocation.find(invocation); - if (it != magic_conf.spells_by_invocation.end()) - return it->second; - - return nullptr; -} - -/* -------------------------------------------------------------------------------- */ -/* Spell anchors */ -/* -------------------------------------------------------------------------------- */ - -AString magic_find_anchor_invocation(XString anchor_name) -{ - auto it = magic_conf.anchors_by_name.find(anchor_name); - - if (it != magic_conf.anchors_by_name.end()) - return it->second->invocation; - - return AString(); -} - -dumb_ptr magic_find_anchor(XString name) -{ - auto it = magic_conf.anchors_by_invocation.find(name); - if (it != magic_conf.anchors_by_invocation.end()) - return it->second; - - return nullptr; -} - -/* -------------------------------------------------------------------------------- */ -/* Spell guard checks */ -/* -------------------------------------------------------------------------------- */ - -static -dumb_ptr alloc_env(magic_conf_t *conf) -{ - auto env = dumb_ptr::make(); - env->varu = make_unique(conf->varv.size()); - env->base_env = conf; - return env; -} - -static -dumb_ptr clone_env(dumb_ptr src) -{ - dumb_ptr retval = alloc_env(src->base_env); - - 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(dumb_ptr 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_(); -} - -dumb_ptr spell_create_env(magic_conf_t *conf, dumb_ptr spell, - dumb_ptr caster, int spellpower, XString param) -{ - dumb_ptr env = alloc_env(conf); - - switch (spell->spellarg_ty) - { - - case SPELLARG::STRING: - set_string(&env->varu[spell->arg], param); - break; - - case SPELLARG::PC: - { - CharName name = stringish(param); - dumb_ptr subject = map_nick2sd(name); - if (!subject) - subject = caster; - set_entity(&env->varu[spell->arg], subject); - break; - } - - case SPELLARG::NONE: - break; - - default: - FPRINTF(stderr, "Unexpected spellarg type %d\n"_fmt, - spell->spellarg_ty); - } - - set_entity(&env->varu[VAR_CASTER], caster); - set_int(&env->varu[VAR_SPELLPOWER], spellpower); - set_spell(&env->varu[VAR_SPELL], spell); - - return env; -} - -static -void free_components(dumb_ptr *component_holder) -{ - if (*component_holder == nullptr) - return; - free_components(&(*component_holder)->next); - (*component_holder).delete_(); - *component_holder = nullptr; -} - -void magic_add_component(dumb_ptr *component_holder, ItemNameId id, int count) -{ - if (count <= 0) - return; - - if (*component_holder == nullptr) - { - auto component = dumb_ptr::make(); - component->next = nullptr; - component->item_id = id; - component->count = count; - *component_holder = component; - } - else - { - dumb_ptr component = *component_holder; - if (component->item_id == id) - { - component->count += count; - return; - } - else - magic_add_component(&component->next, id, count); - /* Tail-recurse; gcc can optimise this. Not that it matters. */ - } -} - -static -void copy_components(dumb_ptr *component_holder, dumb_ptr component) -{ - if (component == nullptr) - return; - - magic_add_component(component_holder, component->item_id, component->count); - copy_components(component_holder, component->next); -} - -typedef struct spellguard_check -{ - dumb_ptr catalysts, components; - int mana; - interval_t casttime; -} spellguard_check_t; - -static -int check_prerequisites(dumb_ptr caster, dumb_ptr component) -{ - while (component) - { - if (pc_count_all_items(caster, component->item_id) < component->count) - return 0; /* insufficient */ - - component = component->next; - } - - return 1; -} - -static -void consume_components(dumb_ptr caster, dumb_ptr component) -{ - while (component) - { - pc_remove_items(caster, component->item_id, component->count); - component = component->next; - } -} - -static -int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr caster, - dumb_ptr env, int *near_miss) -{ - tick_t tick = gettick(); - - 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); - - if (retval) - { - interval_t casttime = check->casttime; - - if (ValInt *v = env->VAR(VAR_MIN_CASTTIME).get_if()) - { - casttime = std::max(casttime, static_cast(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); - } - - return retval; -} - -static -const effect_set_t *spellguard_check_sub(spellguard_check_t *check, - dumb_ptr guard, - dumb_ptr caster, - dumb_ptr env, - int *near_miss) -{ - if (guard == nullptr) - return nullptr; - - MATCH_BEGIN (*guard) - { - MATCH_CASE (const GuardCondition&, s) - { - if (!magic_eval_int(env, s.s_condition)) - return nullptr; - } - MATCH_CASE (const GuardComponents&, s) - { - copy_components(&check->components, s.s_components); - } - MATCH_CASE (const GuardCatalysts&, s) - { - copy_components(&check->catalysts, s.s_catalysts); - } - MATCH_CASE (const GuardChoice&, s) - { - spellguard_check_t altcheck = *check; - const effect_set_t *retval; - - altcheck.components = nullptr; - altcheck.catalysts = nullptr; - - copy_components(&altcheck.catalysts, check->catalysts); - copy_components(&altcheck.components, check->components); - - retval = - spellguard_check_sub(&altcheck, guard->next, caster, env, - near_miss); - free_components(&altcheck.catalysts); - free_components(&altcheck.components); - if (retval) - return retval; - else - return spellguard_check_sub(check, s.s_alt, caster, - env, near_miss); - } - MATCH_CASE (const GuardMana&, s) - { - check->mana += magic_eval_int(env, s.s_mana); - } - MATCH_CASE (const GuardCastTime&, s) - { - check->casttime += static_cast(magic_eval_int(env, s.s_casttime)); - } - MATCH_CASE (const effect_set_t&, s_effect) - { - if (spellguard_can_satisfy(check, caster, env, near_miss)) - return &s_effect; - else - return nullptr; - } - } - MATCH_END (); - - return spellguard_check_sub(check, guard->next, caster, env, near_miss); -} - -static -const effect_set_t *check_spellguard(dumb_ptr guard, - dumb_ptr caster, dumb_ptr env, - int *near_miss) -{ - spellguard_check_t check; - const effect_set_t *retval; - check.catalysts = nullptr; - check.components = nullptr; - check.mana = 0; - check.casttime = interval_t::zero(); - - retval = spellguard_check_sub(&check, guard, caster, env, near_miss); - - free_components(&check.catalysts); - free_components(&check.components); - - return retval; -} - -/* -------------------------------------------------------------------------------- */ -/* Public API */ -/* -------------------------------------------------------------------------------- */ - -const effect_set_t *spell_trigger(dumb_ptr spell, dumb_ptr caster, - dumb_ptr env, int *near_miss) -{ - dumb_ptr guard = spell->spellguard; - - if (near_miss) - *near_miss = 0; - - for (letdef_t& ld : spell->letdefv) - magic_eval(env, &env->varu[ld.id], ld.expr); - - return check_spellguard(guard, caster, env, near_miss); -} - -static -void spell_set_location(dumb_ptr invocation, dumb_ptr entity) -{ - magic_clear_var(&invocation->env->varu[VAR_LOCATION]); - ValLocation v; - v.v_location.m = entity->bl_m; - v.v_location.x = entity->bl_x; - v.v_location.y = entity->bl_y; - invocation->env->varu[VAR_LOCATION] = v; -} - -void spell_update_location(dumb_ptr invocation) -{ - if (bool(invocation->spell->flags & SPELL_FLAG::LOCAL)) - return; - else - { - dumb_ptr owner_bl = map_id2bl(invocation->subject); - if (!owner_bl) - return; - dumb_ptr owner = owner_bl->is_player(); - - spell_set_location(invocation, owner); - } -} - -dumb_ptr spell_instantiate(const effect_set_t *effect_set, dumb_ptr env) -{ - dumb_ptr retval; - retval.new_(); - dumb_ptr caster; - - retval->env = env; - - retval->caster = env->VAR(VAR_CASTER).get_if()->v_eid; - retval->spell = env->VAR(VAR_SPELL).get_if()->v_spell; - 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); - retval->bl_type = BL::SPELL; - retval->bl_m = caster->bl_m; - retval->bl_x = caster->bl_x; - retval->bl_y = caster->bl_y; - - map_addblock(retval); - set_invocation(&env->varu[VAR_INVOCATION], retval); - - return retval; -} - -dumb_ptr spell_clone_effect(dumb_ptr base) -{ - dumb_ptr retval; - retval.new_(); - - // block_list in general is not copyable - // since this is the only call site, it is expanded here - //*retval = *base; - - retval->next_invocation = nullptr; - retval->flags = INVOCATION_FLAG::ZERO; - dumb_ptr env = retval->env = clone_env(base->env); - retval->spell = base->spell; - retval->caster = base->caster; - retval->subject = BlockId(); - // retval->timer = 0; - // retval->stack = undef; - retval->script_pos = 0; - // huh? - retval->current_effect = base->trigger_effect; - retval->trigger_effect = base->trigger_effect; - retval->end_effect = nullptr; - // retval->status_change_refs = nullptr; - - retval->bl_id = BlockId(); - retval->bl_prev = nullptr; - retval->bl_next = nullptr; - retval->bl_m = base->bl_m; - retval->bl_x = base->bl_x; - retval->bl_y = base->bl_y; - retval->bl_type = base->bl_type; - - retval->bl_id = map_addobject(retval); - set_invocation(&env->varu[VAR_INVOCATION], retval); - - return retval; -} - -void spell_bind(dumb_ptr subject, dumb_ptr invocation) -{ - /* Only bind nonlocal spells */ - - if (!bool(invocation->spell->flags & SPELL_FLAG::LOCAL)) - { - if (bool(invocation->flags & INVOCATION_FLAG::BOUND) - || invocation->subject || invocation->next_invocation) - { - int *i = nullptr; - FPRINTF(stderr, - "[magic] INTERNAL ERROR: Attempt to re-bind spell invocation `%s'\n"_fmt, - invocation->spell->name); - *i = 1; - return; - } - - invocation->next_invocation = subject->active_spells; - subject->active_spells = invocation; - invocation->flags |= INVOCATION_FLAG::BOUND; - invocation->subject = subject->bl_id; - } - - spell_set_location(invocation, subject); -} - -int spell_unbind(dumb_ptr subject, dumb_ptr invocation_) -{ - dumb_ptr *seeker = &subject->active_spells; - - while (*seeker) - { - if (*seeker == invocation_) - { - *seeker = invocation_->next_invocation; - - invocation_->flags &= ~INVOCATION_FLAG::BOUND; - invocation_->next_invocation = nullptr; - invocation_->subject = BlockId(); - - return 0; - } - seeker = &((*seeker)->next_invocation); - } - - return 1; -} -} // namespace magic -} // namespace map -} // namespace tmwa -- cgit v1.2.3-70-g09d2