Skip to content

Creando acciones nuevas

Baltasar García Perez-Schofield edited this page May 3, 2023 · 3 revisions

Buscando una acción

Quizás lo que se desea es buscar una acción (probablemente para modificarla), se puede hacer mediante actions.getAction(), como se hace a continuación.

const examineAction = actions.getAction( "examine" );

Probablemente, lo más probable es querer darle más sinónimos. En ese caso, lo podemos hacer con:

const examineAction = actions.getAction( "examine" );
examineAction.verbs.push( "contemplar" );

Registrando la acción

La acción debe ser registrada con sus sinónimos en actions. En el siguiente ejemplo, tomando de vampiro.js se crea una nueva acción para poder afilar una estaca.

const sharpenAction = actions.crea(
    "sharpen",
    [ "afila", "afilar", "afilo", "pule", "pulir", "pulo"]
);

Análisis semántico

fi.js rellena una estructura parser.sentence/parser.sentencia con el verbo y la acción correspondiente, los objetos y los términos utilizados. Así, todas las sentencias se reducen a verbo objeto_directo prep objeto_indirecto, por ejemplo "norte" se traduce como ir al norte, de manera que verbo = ir, prep = al, term1 = norte.

const sentence = {
        // Objects (only filled after parsing)
        persona: null,
        act: null,
        obj1: null,
        obj2: null,

        // Terms employed by the user
        verb: null,
        term1: null,
        prep: null,
        term2: null,
        ...
}

Elementos sintácticos:

  • parser.sentence.verb: la palabra que juega el papel del verbo en la instrucción del usuario.
  • parser.sentence.term1: la palabra que juega el papel del objeto directo en la instrucción del usuario.
  • parser.sentence.prep: la palabra que juega el papel de la preposición en la instrucción del usuario.
  • parser.sentence.term2: la palabra que juega el papel del objeto indirecto en la instrucción del usuario.

Objetos obtenidos tras el parsing:

  • parser.sentence.persona: El objeto persona que ha realizado la acción. Normalmente, se trata de ctrl.persona.getPlayer().
  • parser.sentence.act: La acción reconocida tras comparar verb con los sinónimos de las acciones disponibles y hacer las transformaciones necesarias. Por ejemplo, actions.getAction( "examine" ).
  • parser.sentence.obj1: El objeto directo de la acción, como objeto del juego, o null si no se ha detectado alguno.
  • parser.sentence.obj2: El objeto indirecto de la acción, como objeto del juego, o null si no se ha detectado alguno.

Ejemplos:

  • "coge la llave":

    1. verb = "coger", term1 = "llave"
    2. act: actions.getAction( "take" ), obj1 = objLlave
  • "abre la puerta con la llave":

    1. verb = "abrir", term1 = "puerta", prep = "con", term2 = "llave"
    2. act: actions.getAction( "open" ), obj1 = objPuerta, obj2 = objLlave
  • "mata al cajero":

    1. verb = "atacar", prep = "a", term1 = "cajero"
    2. act: actions.getAction( "attack" ), obj1 = pnjCajero
  • "rompe la puerta":

    1. verb = "romper", term1 = "puerta"
    2. act: actions.getAction( "attack" ), obj1 = objPuerta

Por supuesto, en estos ejemplos se asume que se han creado los objetos objPuerta, pnjCajero...

Llevando a cabo acciones

La forma de llevar a cabo las acciones se divide en dos métodos. El primero es Act.doIt(), que hace las comprobaciones mínimas y llama a los métodos pre- y post- de los objetos involucrados. En nuestro ejemplo, si queremos afilar la estaca, el objTrozoDeMadera vé llamado su método preSharpen() cuando el usuario teclea "afila madero". El segundo es Act.exe(), que es el método que realmente se encarga de llevar algo a cabo. De hecho, doIt() llamará a exe(), aunque solo en caso de que el método pre-no exista o no haya devuelto nada. En otro caso, se devuelve lo que el método pre- haya devuelto.

De forma totalmente independiente de invocar al método pre-es decir, independientemente de que haya sido encontrado, o de que haya devuelto algo o no, se ejecuta el método post- correspondiente. Normalmente, el método post- utiliza si acaso ctrl.print() si quiere visualizar algo por pantalla, puesto que lo que devuelva el método post- se ignora totalmente. Normalmente, el programador no quiere cambiar la acción por defecto, sino añadir algo al mensaje de respuesta por defecto, o realizar cualquier tarea "extra" cuando el jugador lleva esto a cabo. Por ejemplo, el objTrozoDeMadera puede tener un método postSharpen() que simplemente añada a lo que devuelva el método preSharpen() un mensaje del estilo "algo de serrín ha caído al suelo, manchando la moqueta".

sharpenAction.doIt = function(s) {
    var toret = "No veo de eso en derredor.";

    if ( s.term1 === null ) {
        toret = "Deberías especificar qué.";
    }
    else
    if ( s.obj1 != null ) {
        if ( typeof( s.obj1.preSharpen ) === "function" ) {
            toret = s.obj1.preSharpen();
        } else {
            toret = this.exe( s );
        }

        if ( typeof( s.obj1.postSharpen ) === "function" ) {
            s.obj1.postSharpen();
        }
    }

    return toret;
};

Es necesario prestar atención al crear el método Act.exe() de la acción, que es la que se ejecuta cuando se ha emparejado nuestra nueva acción dependiendo de la entrada del usuario. Este método toma como parámetro s, que normalmente es exactamente parser.sentence. Hay que tener en cuenta las siguientes posibilidades:

  • term1 == null: El usuario solo ha tecleado el verbo, como en "coger".

  • term1 != null && obj1 == null: El usuario tecleó un objeto, pero no ha sido encontrado, como en "coger chuviflan".

  • term2 == null: El usuario solo ha tecleado un objeto, como en "abrir puerta con".

  • term2 != null && obj2 == null: El usuario tecleó un segundo objeto, pero no ha sido encontrado, como en "abrir puerta con chuviflan".

  • obj1.isReachable() == false: El objeto fue encontrado, pero no es alcanzable. Esto puede ser el sol, una lámpara colgada del techo, etc. Así, puede ser que el usuario pretenda "lamer la lampara", cuando no puede hacerlo porque no le llega.

En el caso de pretender afilar algo, solo tenemos que preocuparnos de afectar a un solo objeto. Nótese que doIt() solo debe realizar las comprobaciones genéricas, y realizar la acción genérica, que en general debe ser negativa, es decir, no hacer nada, devolviendo una respuesta adecuada.

sharpenAction.exe = function(s) {
    var toret = "No veo de eso en derredor.";

    if ( s.term1 === null ) {
        toret = "Deberías especificar qué.";
    }
    else
    if ( s.obj1 !== null ) {
        if ( s.obj1.isReachable() ) {
            toret = "La violencia no es la solución.";
        } else {
            toret = "Demasiado lejos.";
        }
    }

    return toret;
};
Clone this wiki locally