Tutorial de cobro de Misiones, por Txibi.

   Bién, la idea es organizar una trama secundaria, lo que se da en llamar quest automática. Una misión, que esta atomatizada para que los jugadores la jueguen con sus fichas sin la intervención de un director de juego o dungeon master (DM).

   Lo primero es preparar el editor de diarios (herramientas, editor de diarios). De los 4 botones de la tira vertical de la izquierda, arriba, seleccionamos el primero. Agregar.

   Saldrá una entrada por defecto que será algo así: Categoría000  y abajo a la izquierda eston campos de datos y los siguientes datos por defecto:

   Nombre Categoría000, Etiqueta Categora000, Prioridad El más bajo, PX 0.

   Aquí ya nos da un consejo y una lección. Etiqueta pone Categora000, pero ¿no debería poner por defecto Categoría000? Sí, pero el inglés, y el aurora no cogen acentos ni "símbolos especiales"  Vamos, que no utilicéis eñes, acentos y símbolos. Utilizad letras, números y el guión bajo si tenéis que emular espacios en blanco, por ejemplo etiqueta_1 . Sigamos.

   Vamos a poner un diario más ameno, una misión épica no puede ser Categoría000, Bien rellenamos, por ejemplo así.

   Nombre: Problemas con los Forajidos del Bosque del Roble.
   Etiqueta: mis_1_for_roble  (de misión 1 de los forajidos del roble)
   Prioridad: Intermedio
   PX: 0 (tranquilos, que se da experiencia, pero irá en el script final de testeo de misión).

   Vvamos a agregar dos entradas. Pincha en lo que era Categoría000, ahora
Problemas con los Forajidos del Bosque del Roble y añade estas dos entradas.

   En la 1 entrada pondremos:

   Aparentemente al norte, más alla del Bosque del Roble, debe de haber una gran ciudad en ruinas, numerosos forajidos acechan en el bosque a ingenuos buscadores de tesoros. El encargado de los cazarrecompensas del Enclave, nos ha prometido una bonita suma por reducir la población de bandidos en este bosque. Debemos traer alguna prueba de algún cabecilla o banda.

   Y en la 2 entrada (y última, no nos complicaremos la primera vez) escribermos lo siguiente. Además pincharemos la casilla de verificación de Terminar categoría, abajo a la izquierda.

   Bien, desde luego la batalla fué muy dura, pero hemos vencido, cambiemos la espada de uno de los líderes bandidos caídos por una bonita suma de oro. No está mal.

   Debería quedar así:

imagen del diario, ejemplo

   Aja, ya tenemos el diario. Vamos a colocar al "patrón". Creamos un PNJ (Personaje No Jugador) y lo colocamos en algún lugar de paso de viajeros y aventureros. Yo no pude resistir la nostalgia de los viejos tiempos del Runequest y el patrón... está en una posada.

   He aquí al patrón y la conversación:

ejemplo de conversación de misión.

   Hemos procurado poner una conversación decente.

   Si eres observador verás unas frases grises que ponen lo mismo que otras de arriba. Es que son las de arriba. Para no tener que repetir frases se pueden pegar como vínculo, tu haces botón derecho copiar la frase, y en la parte de la conversación que quieras que salte hacie ahí pone pegar como vínculo.

   He aquí un ejemplo:

ejemplo de pegar como vínculo.

   Con frecuencia haré referencia a dos opciones del editor de conversaciones. El texto aparece cuando... y Acciones emprendidas. En cada una de esas pestañas se pueden seleccionar y colocar un guión de programa, un script.

Ejemplo de uso del editor de texto para los scripts.

    Cuando se deba colocar algún script o guión en alguna frase de la conversación (y habrá que hacerlo) ya lo indicaré.

   Vamos a comenzar a programar la misión o quest, como les gusta de llamar a los angloparlantes. En un principio tendremos tres bloques bien diferenciados.

   No se ha aceptado misión.
   Se ha aceptado la misión pero todavía no se ha finalizado con éxito.
   Se ha aceptado y terminado la misión.

Texto, los 3 bloques de la conversación.

   Empezamos con el primer bloque. A partir de ahora daré por supuesto que se sabe hacer las opciones y utilidades más básicas del editor de conversaciones y del editor de guiones (o scripts). Si es la primera vez que vas a utilizar el editor de conversaciones o es la primera vez que vas a escribir un guión o script, tal vez quieras prácticar un poco creando conversaciones y guiones sencillos. Como todavía no se ha aceptado la misión, la variable
mis_1_for_roble vale 0, (menor de 1).

   Primer Bloque:

Saludos, ¡vaya! tienes pinta de estar interesado en una busqueda y una suculenta recompensa, ¿que me dices?

   En una conversación, de las listas de frases que puede decir el PNJ (las que están en rojo precedido de DUEÑO), tenemos que tener en cuenta que sólo dirá una, la lista de posibles frases a escoger son las respuestas que dará nuestro PJ (Personaje Jugador) controlado directamente.

   En esa lista de 3 frases del PNJ por lo tanto, dirá sólo una de ellas. Si no hemos puesto ninguna condición, por defecto lee la primera que encuentre, empezando por arriba. Si hemos puesto condiciones lee la primera que encuentre empezando por arriba en la que se cumplan las condiciones o en la que no tenga condición.

   Así que en la pestaña del "El texto aparece cuando..." del primer bloque vamos a colocar un script, el script 3_tx_roblefora_1  que su función es que está frase que da acceso al primer bloque, sólo salga si no hemos aceptado la misión.

/*
Script: 3_tx_roblefora_1
0:20 del 15 de Noviembre del 2004.
Scripts de Mision (las misiones empezaran por 3_tx_) de los forajidos del Bosque del Roble.
*/
int StartingConditional()
{
    if(!(GetLocalInt(GetPCSpeaker(),"mis_1_for_roble")<1))
    return FALSE;

    return TRUE;
}

   De este primer bloque las dos primeras respuestas son para las fichas con una inteligencia normal (10 o más) y las dos últimas líneas son para las fichas con poca inteligencia o idiotas (9 o menos).

Ejemplo bloque 1.

   
El guión o script que gestiona las 2 primeras respuestas se coloca en El texto aparace cuando... y está hecho por el motor del never, es este:

   nw_d2_intn

   Y el guión o script que gestiona las 2 ultimas respuestas se coloca en el El texto aparece cuando... y también evidentemente está hecho por el never y es este otro, muy parecido como era de esperar:

   nw_d2_intl

   No os corteis, alguién con inteligencia baja (el motor del juego determina automáticamente quien tiene "una inteligencia baja") no sabe hablar correctamente y no tiene las luces suficientes para llevar una conversación prolongada o usar las habilidades de persuadir. Aunque sea una respuesta trivial, poner las dos, lo que responde una persona de inteligencia normal, que sabe hablar, y lo que responde el que ha puesto a su ficha el mínimo en inteligencia (8) para subir sus atributos físicos y que, evidentemente no sabe hablar bien.

  
Recordemos el primer bloque, el de aceptar la misión, desglosado ahora:

Primer bloque de texto desglosado.

   BLOQUE PARA FICHAS CON INTELIGENCIA NORMAL.

   Un PJ inteligente, intentará negociar el precio, hay que dar salida a esas habilidades de persuasión, en cambio un Paladín, jamás pedirá oro por eliminar el mal, salvo lo justo. (En la captura, la línea del paladín es la que está resaltada).

   Colocando los guiones o scripts, las frases que tengan uno las reproduciré y diré donde van, las que no mencione no tendrán nada. Si el script o guión asociado no es de bioware, lo listaremos inmediatamente después. Vamos alla.

Saludos a ti también, ¿qué tienes que nos pueda interesar?

El texto aparece cuando... tiene el script: nw_d2_intn

<StartAction>[Persuadir]</Start> ¿Bandidos? ¿Y en gran número dices? 300 Doblones de Oro son pocos Doblones, lo haré pero tendrás que mejorar esa oferta.

El texto aparece cuando... tiene el script: tx_no_paladin

/*
Script: tx_no_paladin
Restriccion de clases. mira si NO se es paladin.
Txibi.
*/
int StartingConditional()
{
    //Restriccion basada en la clase de personaje.
    int iPassed = 0;

    if (GetLevelByClass(CLASS_TYPE_PALADIN, GetPCSpeaker()) >= 1)
    iPassed = 1;
    if (iPassed == 0)
    return TRUE;

    return FALSE;
}

<StartCheck>[Éxito]</Start> ¡De acuerdo! Recibirás no menos de 450 Doblones de Oro. Ahora sal y dale una patada en el culo a esos bandidos.

El texto aparece cuando... tiene el script: nw_d2_pershigh
Acciones emprendidas tiene el script: 3_tx_roblefora_8

/*
Script: 3_tx_roblefora_8
0:20 del 15 de Noviembre del 2004.
Scripts de Mision (las misiones empezaran por 3_tx_) de los forajidos del Bosque del Roble.
*/
void main()
{
    //Establecer Variables.
    //Consigue 450 monedas en total por un gran exito en persuadir.
    SetLocalInt(GetPCSpeaker(), "regForaRoble", 1);
    SetLocalInt(GetPCSpeaker(), "mis_1_for_roble", 1);
    AddJournalQuestEntry("mis_1_for_roble", 1, GetPCSpeaker());
}//fin Cuerpo principal.

<StartCheck>[Éxito]</Start> mmm quizá tengas algo de razón, añadiré 60 doblones de oro más a la oferta.

El texto aparece cuando... tiene el script:
nw_d2_persmed
Acciones emprendidas tiene el script: 3_tx_roblefora_7


/*
Script: 3_tx_roblefora_7
0:20 del 15 de Noviembre del 2004.
Scripts de Mision (las misiones empezaran por 3_tx_) de los forajidos del Bosque del Roble.
*/
void main()
{
    //Establecer Variables.
    //Consigue 60 monedas extra por exito en persuadir.
    SetLocalInt(GetPCSpeaker(), "regForaRoble", 2);
    SetLocalInt(GetPCSpeaker(), "mis_1_for_roble", 1);
    AddJournalQuestEntry("mis_1_for_roble", 1, GetPCSpeaker());
}//fin Cuerpo principal.

<StartCheck>[Fracaso]</Start>No, no estoy autorizado a ofrecer más. ¡Nos quedaríamos sin oro rápidamente si todos los cazarecompensas escogieran que quieren cobrar! 300 Doblones.

Acciones emprendidas tiene el script: 3_tx_roblefora_6

/*
Script: 3_tx_roblefora_6
0:20 del 15 de Noviembre del 2004.
Scripts de Mision (las misiones empezaran por 3_tx_) de los forajidos del Bosque del Roble.
*/
void main()
{
    //Establecer Variables.
    SetLocalInt(GetPCSpeaker(), "mis_1_for_roble", 1);
    AddJournalQuestEntry("mis_1_for_roble", 1, GetPCSpeaker());
}//fin Cuerpo principal.

¡Bandidos! ¡Criminales! ¡Guardaos vuestro oro! Será un honor limpiar esta zona de su vil presencia.

El texto aparece cuando... tiene el script: tx_paladin
Acciones emprendidas tiene el script: 3_tx_roblefora_5


/*
Script: tx_paladin
Restriccion de clases. mira si se es paladin.
Txibi.
*/
int StartingConditional()
{
    //Restriccion basada en la clase de personaje.
    int iPassed = 0;

    if (GetLevelByClass(CLASS_TYPE_PALADIN, GetPCSpeaker()) >= 1)
       iPassed = 1;
    if (iPassed == 0)
       return FALSE;

    return TRUE;
}

/*
Script: 3_tx_roblefora_5
0:20 del 15 de Noviembre del 2004.
Scripts de Mision (las misiones empezaran por 3_tx_) de los forajidos del Bosque del Roble.
*/
void main()
{
    //Establecer Variables.
    //Al ser Paladin especifica en 3 el regateo, no tomara oro, salvo unas pocas monedas.
    SetLocalInt(GetPCSpeaker(), "regForaRoble", 3);
    SetLocalInt(GetPCSpeaker(), "mis_1_for_roble", 1);
    AddJournalQuestEntry("mis_1_for_roble", 1, GetPCSpeaker());
}//fin Cuerpo principal.

Bien, 300 Doblones de Oro, habéis echo un trato.

El texto aparece cuando... tiene el script: tx_no_paladin
Acciones emprendidas tiene el script: 3_tx_roblefora_6


¡Bandidos...! Quizá en otra ocasión, pero por ahora no me embarcaré en semejante aventura.

El texto aparece cuando... tiene el script: tx_no_paladin

Pués no, te equivocas, sólo estoy dando una vuelta y mirando un rato la taberna. ¡Hasta Luego!

El texto aparece cuando... tiene el script: nw_d2_intn

BLOQUE PARA FICHAS POCO INTELIGENTES.

Ejemplo de texto bloque 1 para fichas poco inteligentes.

¿Ehh? ¿Que querer decir tu?

El texto aparece cuando... tiene el script: nw_d2_intl

Yo querrer, si.


El texto aparece cuando... tiene el script: tx_no_paladin
Acciones emprendidas tiene el script: 3_tx_roblefora_6

No, no estarrr interresado.

El texto aparece cuando... tiene el script: tx_no_paladin

¡Bandidos! Arrancarles la cabeza.

El texto aparece cuando... tiene el script: tx_paladin
Acciones emprendidas tiene el script: 3_tx_roblefora_5


No, no querer saber nada, dejarme en paz.

El texto aparece cuando... tiene el script: nw_d2_intl

   Ya hemos terminado con el primer bloque de la conversación, el más largo. No es complicado, sólo que es trabajoso. En este primer bloque hemos activado las variables de misión, hemos puesto las opciones de regateo y lenguaje o falta de lenguaje. Al mismo tiempo hemos añadido la posibilidad de diferenciar entre paladines, que jamás se negarían a socorrer una aldea acosada por bandidos, de otro tipo de personas, que dependiendo de su alineamiento pueden aceptar, negarse o pedir más oro.

   Segundo Bloque:

   En el segundo bloque ya hemos aceptado la misión con lo cual hemos dicho que la variable mis_1_for_roble vale 1 , la función de la conversación es comunicar que ya hemos terminado el encargo o que todavía estamos en ello.

Segundo bloque de texto de la conversación.

 ¡Ah, hola de nuevo <Sir/Madam>!

El texto aparece cuando... tiene el script: 3_tx_roblefora_2

/*
Script: 3_tx_roblefora_2
0:20 del 15 de Noviembre del 2004.
Scripts de Mision (las misiones empezaran por 3_tx_) de los forajidos del Bosque del Roble.
*/
int StartingConditional()
{
    if(!(GetLocalInt(GetPCSpeaker(),"mis_1_for_roble")==1))
    return FALSE;

    return TRUE;
}

[CONTINUAR]
(El que lleva la parte de la conversación para fichas de inteligencia normal).
El texto aparece cuando... tiene el script: nw_d2_intn

Perfectamente, aquí está el arma de uno de sus cabecillas para demostrar mis palabras.
El texto aparece cuando... tiene el script: 3_tx_roblefora_4

/*
Script: 3_tx_roblefora_4
0:20 del 15 de Noviembre del 2004.
Scripts de Mision (las misiones empezaran por 3_tx_) de los forajidos del Bosque del Roble.
*/
#include "nw_i0_tool"
int StartingConditional()
{
    if(!CheckPartyForItem(GetPCSpeaker(),"mis_1_arma"))
    return FALSE;

    return TRUE;
}

   Si sois vivos habréis visto que hay algo nuevo,
#include "nw_i0_tool", esto gestiona el inventario entre otras cosas, para que mire si el PJ dispone del arma con la etiqueta mis_1_arma que es lo que debe de tener en el inventario para ser una misión exitosa. Podría ser por variable, que en vez de tener un objeto en el inventario guarde una posición de variable para tener la misión hecha. Pero esta vez hemos resuelto con objeto. Sigamos.

¡Perfecto! Toma lo acordado. Yo ahora informaré a mis superiores de tu éxito.
Acciones emprendidas tiene el script: 3_tx_roblefora_f

Este script, 3_tx_roblefora_f, lo comentaremos al final, que es largo.

[CONTINUAR]
(El que lleva la parte de la conversación para fichas de inteligencia baja).

El texto aparece cuando... tiene el script: nw_d2_intl

¡Agg! Si, yo tener arma de jefe, mostar.
El texto aparece cuando... tiene el script: 3_tx_roblefora_4

   Tercer bloque:

Este bloque es pequeño. Una línea. Ya hemos terminado la misión y la variable mis_1_for_roble esta establecida en 2, con lo cual el patrón se limita a saludarnos y agradecernos nuestra gesta.

¡Que ven mis ojos! ¿Que tal lo lleva <Sir/Madam>? Le estamos agradecidos por haber reducido las filas de indeseables.

El texto aparece cuando... tiene el script: 3_tx_roblefora_3

/*
Script: 3_tx_roblefora_3
0:20 del 15 de Noviembre del 2004.
Scripts de Mision (las misiones empezaran por 3_tx_) de los forajidos del Bosque del Roble.
*/
int StartingConditional()
{
    if(!(GetLocalInt(GetPCSpeaker(),"mis_1_for_roble")==2))
    return FALSE;

    return TRUE;
}


   Y ya estaría hecho todo. El script de recompensa lo comentaremos el último. Repasemos. No hay misión, variable mis_1_for_roble vale 0. Aceptamos, vale 1. Completamos la misión, vale 2.
   Añadir entradas al diario. Para añadir al primera entrada sería:
   AddJournalQuestEntry("mis_1_for_roble", 1, GetPCSpeaker());
   Con lo cual la entrada del diario mis_1_for_roble se activa a 1 y es lo que nos pondra en nuestro diario de juego, bajo el título que tenga esa entrada, en este caso: Problemas con los Forajidos del Bosque del Roble.
   Para recordar la persuasión  hemos cogido la variable regForaRoble.

   Y para el final hemos dejado el script o guión más tocho. El que recuerda si hemos hecho o no la misión, establece la experiencia y el oro, según nivel y clase.

   No es tan largo como aparenta.

/*
Script: 3_tx_roblefora_f
0:20 del 15 de Noviembre del 2004.
Scripts de Mision (las misiones empezaran por 3_tx_) de los forajidos del Bosque del Roble.
*/

#include "nw_i0_tool"
//Subprograma PartyHaHechoQuest.
int PartyHaHechoQuest(object oPC)
{
    object oPartyMember = GetFirstFactionMember(oPC, TRUE);
    while (GetIsObjectValid(oPartyMember) == TRUE)
    {
       // Comprobamos que no haya hecho la quest
       if (GetLocalInt(GetModule(),"mis_bandidosroble_hecha_" + GetName(oPartyMember) + GetPCPlayerName(oPartyMember) ) == 1)
       {
          //Ya ha hecho la quest
          return TRUE;
       }
    oPartyMember = GetNextFactionMember(oPartyMember, TRUE);
    }
    return FALSE;
}//fin subprograma PartyHaHechoQuest
//Subprograma MarcarGrupo.
void MarcarGrupo(object oPC)
{
    object oPartyMember = GetFirstFactionMember(oPC, TRUE);
    while (GetIsObjectValid(oPartyMember) == TRUE)
    {
       // Comprobamos que no haya hecho la quest
       SetLocalInt(GetModule(),"mis_bandidosroble_hecha_" + GetName(oPartyMember) + GetPCPlayerName(oPartyMember), 1);
       oPartyMember = GetNextFactionMember(oPartyMember, TRUE);
    }
}//fin subprogrma MarcarGrupo.
//Cuerpo principal del programa.
void main()
{
   object oJugador = GetLastSpeaker();
   object oItemToTake=GetItemPossessedBy(oJugador,"mis_1_arma");
   //If principal.
    if(GetIsObjectValid(oItemToTake)!=0)
    {
       DestroyObject(oItemToTake);
       //Comprobamos si los jugadores han hecho la quest
       if (!PartyHaHechoQuest(oJugador))
       {
          //Damos puntos de xp a todo el grupo y oro al poseedor del arma.
          MarcarGrupo(oJugador);
          //Dar un poco de oro al jugador que habla con el patrón.
          int iOroCarisma = GetAbilityModifier(ABILITY_CHARISMA, GetPCSpeaker());
          //Cogemos el bono del carisma y lo multiplicamos * 10
          iOroCarisma = iOroCarisma * 10;
          //Luego le sumamos la cantida prometida.
          iOroCarisma = iOroCarisma + 300;

          if(GetLocalInt(GetPCSpeaker(), "regForaRoble") == 1)
          {
             //Un buen exito en persuadir.
             iOroCarisma = iOroCarisma + 150;
             GiveGoldToCreature(GetPCSpeaker(), iOroCarisma);
          }
          else if(GetLocalInt(GetPCSpeaker(), "regForaRoble") == 2)
          {
             //Un exito normal en persuadir.
             iOroCarisma = iOroCarisma + 60;
             GiveGoldToCreature(GetPCSpeaker(), iOroCarisma);
           }
          else if(GetLocalInt(GetPCSpeaker(), "regForaRoble") == 3)
          {
             //Es Paladin, de modo que toma el oro justo para pagarse la comida.
             GiveGoldToCreature(GetPCSpeaker(), 10);
             GiveXPToCreature(GetPCSpeaker(), 40);
          }
          else //el pago normal
          {
             GiveGoldToCreature(GetPCSpeaker(), iOroCarisma);
          }
          //Dar un poco de XP
          object oPC=GetLastSpeaker();
          object oPartyMember = GetFirstFactionMember(oPC, TRUE);
          int nNivelPJ = GetHitDice(oPartyMember);
          while (GetIsObjectValid(oPartyMember) == TRUE)
          {
             //Reparto de XP.
             //Comprobamos su inteligencia para dar bono/malus de xp.
             int iEsaINT = GetAbilityModifier(ABILITY_INTELLIGENCE, oPartyMember);
             //Comprobamos su sabidura para dar un bonus o malus de xp.
             int iEsaSAB = GetAbilityModifier(ABILITY_WISDOM, oPartyMember);
             //Se hace la media... de ambas bonus/malus.
             int iBonoXP = ((iEsaINT + iEsaSAB) * 5 );
             //Damos la xp segun nivel y bono/malus
             int iTotal = 0;

             if (nNivelPJ<=4)
             {
                //Antes comprobamos que no de xp negativa... que algunos...
                iTotal = 200 + iBonoXP;
                if (iTotal<0) { iTotal = 0;}
                GiveXPToCreature(oPartyMember, iTotal);
             }
             else if ((nNivelPJ>=5) && (nNivelPJ<=8))
             {
                iTotal = 500 + iBonoXP;
                if (iTotal<0) { iTotal = 0;}
                GiveXPToCreature(oPartyMember, iTotal);
             }
             else if ((nNivelPJ>8) && (nNivelPJ<11))
             {
                iTotal = 650 + iBonoXP;
                if (iTotal<0) { iTotal = 0;}
                GiveXPToCreature(oPartyMember, iTotal);
             }
             else if (nNivelPJ>=11)
             {
                iTotal = 100 + iBonoXP;
                if (iTotal<0) { iTotal = 0;}
                GiveXPToCreature(oPartyMember, iTotal);
             }
             oPartyMember = GetNextFactionMember(oPartyMember, TRUE);
             nNivelPJ = GetHitDice(oPartyMember);
          } //fin while

          //Añadir al diario
          AddJournalQuestEntry("mis_1_for_roble",2,oJugador);
          SetLocalInt(oJugador,"mis_1_for_roble",2);
       }//fin del if de dar cobro de misión.
       else
       {
          SendMessageToPC(oJugador, "DM: No habeis recibido recompensa porque hay jugadores en el grupo que completaron la quest anteriormente");
       }//fin else de aviso DM.
    }//fin del if principal que testea el objeto del inventario y activa la recompensa.
}//fin Cuerpo Principal.

    Y ya estaría hecho, se puede complicar más, y por supuesto, se puede simplificar mucho más. Se ha puesto un ejemplo complejo para que de abanico a un buen número de posibilidades.

   Con sólo algo de lo aquí listado os haya servido, entonces el tiempo invertido en preparar esto ha merecido la pena. A ver si poco a poco encontramos más cosas en castellano.

   Txibi.