AzerothCore
Pages :
Este artículo fue creado y portado desde la wiki de Trinity core, ya que su sistema es idéntico

Introducción: ¿Cómo funcionan los hechizos en Azerothcore?

Este artículo pretende introducirte al concepto de un lanzamiento de hechizo (spellcast). Es algo importante que todo scripter debe conocer en resumen, porque los hechizos son uno de los principales "canales de interacción" entre objetos del juego. Cada vez que robas el bolsillo de alguien como pícaro (rouge), inicias un intercambio con otro jugador, usas un objeto o simplemente le haces daño a alguien usando magia, hay un hechizo involucrado. Cada hechizo se identifica por su entry spellId en spell.dbc. La clase SpellInfo es una interfaz C++ de esa tabla (entre otras tablas dbc y sql relacionadas). La mayor parte del proceso de lanzamiento se maneja dentro de una clase Spell que representa el estado dinámico de cada lanzamiento. El comportamiento de esa clase puede verse afectado usando objetos de la clase SpellScript. Un mecanismo con un impacto tan grande sobre todo es complejo, así que para simplificar nuestra visión de lo que ocurre, dividámoslo en varias fases. En el juego, ocurren en el mismo orden que en este artículo.

Fase de preparación del hechizo (prepare)

Esta fase es responsable de manejar la "petición" de un lanzador de hechizo: el objeto que ha iniciado el lanzamiento. Una petición puede hacerse desde el cliente de un jugador (ver SpellHandler.cpp), o desde los propios gameobjects. (GameObject::CastSpell, Unit::CastSpell, etc). Aquí, el worldserver valida y prepara un objetivo explícito al que apunta el hechizo.

¿Qué es un objetivo de hechizo explícito?

Dicho de forma simple, un objetivo de hechizo explícito es el objetivo afectado por un hechizo. Por ejemplo, el objetivo de hechizo explícito del Golpe heroico de un Guerrero es la unidad seleccionada actualmente, ya sea un jugador o un personaje no jugable.

El objetivo explícito del lado del servidor se selecciona mediante el primer parámetro de la función Unit::CastSpell.

Sin embargo, ¡no todos los hechizos requieren objetivos explícitos! Un ejemplo puede ser un hechizo de área de efecto, que no importa qué selecciones en el juego, afecta a los objetivos que te rodean. Por tanto, el objetivo de hechizo explícito puede ser null, y eso es natural.

En el caso de muchos otros hechizos, un objetivo explícito puede ser también una posición en el suelo, como es el caso del hechizo de mago blizzard.

¿Qué decide si un hechizo necesita un objetivo explícito?

Como puede que hayas leído en el sistema de hechizos (Spell system), la base de datos decide la mayor parte del comportamiento del hechizo, y así ocurre en este caso. El target, implicitTargetA e implicitTargetB de Spell.dbc deciden eso; brevemente: un flag en el campo target o un implicitTargetX puesto a uno de los modos de objetivo TARGET_XXX_TARGET (TARGET_UNIT_TARGET por ejemplo) significa que el hechizo requiere un objetivo explícito. La consecuencia más importante de esto es que NO PUEDES lanzar lo que quieras sobre lo que desees; todo lo decide con precisión la base de datos del cliente y lo único que puedes hacer es seguir esas reglas. Además de la validación y preparación del objetivo explícito del hechizo, también se hacen algunas comprobaciones prematuras de la corrección de la petición de lanzamiento: se llama a una función Spell::CheckCast (que usa datos de la db para las comprobaciones); también hay algunas comprobaciones hechas en las funciones de petición de lanzamiento, desafortunadamente repartidas por todo el core. En caso de fallo, se envía un error; de lo contrario, el hechizo se encola para ejecutarse en la siguiente actualización del objeto, o se maneja inmediatamente en el caso de los hechizos activados (triggered). Triggered es una especie de lanzamiento de "sistema"; no está definido con precisión qué significa eso exactamente, ya que el término se usa en exceso para tener un significado específico, pero establecer el flag de lanzamiento triggered altera mucho el comportamiento del hechizo y la interpretación de los datos de la db. Por ejemplo, los hechizos lanzados con el flag triggered (un parámetro de CastSpell()) ignorarán los requisitos de objeto establecidos en el dbc, algunos requisitos de estado del lanzador, etc. Después de que el hechizo se prepara con éxito comienza el lanzamiento, ves la barra de lanzamiento en el juego. Puedes seguir el código de esta fase buscando las apariciones de la función Spell::Prepare en el core.

Fase de preparación del hechizo (prepare)

Una vez que la barra de lanzamiento se llena (en el caso de los hechizos instantáneos, inmediatamente) comienza la fase de lanzamiento (cast). Durante esa fase se hacen varias cosas; una de las más importantes es: la selección de objetivos implícitos del hechizo. Los objetivos implícitos del hechizo son los objetos del juego que se verán afectados por tu hechizo. Su selección se basa en las columnas implicitTargetX de Spell.dbc, la tabla conditions y los hooks OnObject(Area)TargetSelect de SpellScript. No se hace nada a los objetivos en este punto (por favor, no rompas esa regla al usar scripts, no es blizzlike), simplemente se seleccionan para su procesamiento futuro. Al comienzo de esta fase se hace otra cosa importante: la segunda llamada a Spell::CheckCast (que puedes afectar usando el hook de spell script OnCheckCast y la tabla db conditions). También, los objetos requeridos y el poder se toman del lanzador en esta fase. Puedes engancharte a esta fase usando los hooks BeforeCast, OnCast, AfterCast. La fase entera se maneja en Spell::cast.

Fase de lanzamiento del hechizo (launch)

El lanzamiento (launch) viene inmediatamente después de que el cast termina; es el momento en que el hechizo "abandona las manos del lanzador", puedes notarlo en los hechizos que están volando durante cierto tiempo antes de alcanzar los objetivos. Algunos efectos de hechizo se manejan durante esta fase; por ejemplo, el daño del lanzador debe calcularse en el momento en que el hechizo se lanza en lugar del momento del impacto, la carga debe comenzar en el launch, etc. Cuando (y si) tu hechizo alcanza su objetivo (inmediatamente para los hechizos sin retardo) comienza la siguiente fase (de impacto). El launch se maneja en Spell::HandleLaunchPhase. Puedes afectar la ejecución de los efectos de hechizo durante esta fase usando los hooks OnEffectLaunch y OnEffectLaunchTarget. La diferencia entre esos dos es que OnEffectLaunch se llama una vez por cada efecto de hechizo que tiene el hechizo, independientemente de sus objetivos; mientras que OnEffectLaunchTarget se llama una vez por cada objetivo implícito disponible del hechizo (seleccionado en la fase de cast anterior).

Fase de impacto del hechizo (hit)

El impacto (hit) es la fase donde se manejan la mayoría de los efectos del hechizo. Los efectos de hechizo son pequeñas operaciones que afectan al lanzador del hechizo o a los objetivos implícitos del hechizo. Cada entry de hechizo tiene columnas EffectX (en el dbc) que contienen el id de los efectos que ese hechizo aplica a su objetivo. Cada efecto tiene su propia lista de objetivos separada, así que un único hechizo puede operar sobre muchos objetos diferentes a la vez. Por ejemplo, un hechizo puede aplicar un efecto de curación a tus amigos y darte a ti un aura de buff a la vez. De forma similar a la fase de launch, puedes sobrescribir el comportamiento de los efectos de hechizo en esta fase mediante los hooks de SpellScript OnEffectHit y OnEffectHitTarget. También puedes usar: los hooks BeforeHit, OnHit y AfterHit. Algo importante durante esta fase es el proc del hechizo: un sistema especial de activación de eventos que hace cosas según qué auras están aplicadas al lanzador y al objetivo implícito del hechizo. Algunas partes del sistema de proc deberían manejarse por el sistema de proc en otras fases del lanzamiento del hechizo, pero eso no está implementado por ahora.

Fase de finalización del hechizo (finish)

La fase de finalización (finish) ocurre después de que se procesan todos los objetivos del hechizo; es solo una limpieza, solo ocurren unos pocos eventos relevantes en esta fase.