Friday, June 07, 2019

Mientras tanto, en Plutón...

Ya vimos en la entrada anterior cómo se definen los personajes con los que se encontrará el jugador a lo largo de la aventura, así que profundizaremos ahora en lo que le da el nombre a las aventuras conversacionales. Efectivamente, las conversaciones.

Bla bla bla

Para empezar, vamos a echarle un vistazo a la definición de un árbol de conversación -y de los elementos que dependen de él- en el archivo conversation_trees.json. Usaremos uno de los árboles de Pluto Crash como ejemplo.

[
    {
        "id":1,
        "conversationBranches":[
    {
        "id":1,
        "conversationText":"La señal roja de alerta parpadea en la pantalla-cara de K128 mientras aúlla un constante '!ALERTA, PELIGRO!' a través de sus altavoces. Es bastante molesto.",
        "triggers":null,
        "conversationOptions":[
            {
        "id":0,
        "optionText":"Vale, vale, alerta peligro, lo pillo ¿Se puede saber qué ha pasado?",
        "destinationBranch":2,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":null
            }
        ],
        "conversationImage":"k128_dialog_warning.png"
    },
    ...
    {
        "id":8,
        "conversationText":"'Aquí tienes una lista de los daños que he podido comprobar:\n*Comunicaciones externas fuera de línea.\n*Control de soporte vital planta suelo inoperativo.\n*Control de soporte vital plantas -1 y -2 operativo.\n*Ascensor en línea. Inoperativo.\n*Robot de cocina y preparador de alimentos inoperativo.\n*Cubas de reciclaje operativas.\n*Laboratorio hidropónico operativo.\n*Arsenal y control automatizado de seguridad fuera de línea.\n*Enfermería operativa.'",
        "triggers":null,
        "conversationOptions":[
            {
        "id":0,
        "optionText":"¿Qué ocurre con las comunicaciones?",
        "destinationBranch":9,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":null
            },
            {
        "id":1,
        "optionText":"¿Qué hay del soporte vital?",
        "destinationBranch":10,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":null
            },
            {
        "id":2,
        "optionText":"¿Ascensor en línea pero inoperativo? Explícate.",
        "destinationBranch":11,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":null
            },
            {
        "id":3,
        "optionText":"¿Qué ocurre con la cocina?",
        "destinationBranch":12,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":null
            },
            {
        "id":4,
        "optionText":"¿Qué hay de las cubas de reciclaje?",
        "destinationBranch":13,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":null
            },
            {
        "id":5,
        "optionText":"¿Algún problema con el laboratorio hidropónico?",
        "destinationBranch":14,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":null
            },
            {
        "id":6,
        "optionText":"¿Han reventado el arsenal?¡Venga ya!",
        "destinationBranch":15,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":null
            },
            {
        "id":7,
        "optionText":"¿Qué hay de la enfermería?",
        "destinationBranch":16,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":null
            },
            {
        "id":8,
        "optionText":"Supongo que podría haber sido peor.",
        "destinationBranch":17,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":null
            }
        ],
        "conversationImage":"k128_dialog_serious.png"
    },
    ...
   
    {
        "id":18,
        "conversationText":"Giras la cabeza de K128 hasta que ésta se separa de su brazo robótico y la colocas bajo tu brazo.",
        "triggers":null,
        "conversationOptions":[
            {
        "id":0,
        "optionText":"¡La aventura nos aguarda!",
        "destinationBranch":0,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "skillRequirements":null,
        "gameTriggers":[
            {
                "id":1,
                "triggerType":0,
                "triggerSubType":0,
                "beenTriggered":"false",
                "actionId":null,
                "locationId":null,
                "itemId":null,
                "characterId":null,
                "enabled":"true",
                "effects":[
            {
                "id":1,
                "type":110,
                "passiveGameItems":null,
                "passiveGameLocations":null,
                "passiveGameNPCs":[1],
                "passiveGameTriggers":null,
                "passiveGameFlags":null,
                "newIntegerValue":1,
                "newBooleanValue":null,
                "newStringValue":null,
                "message":null
            },{
                "id":2,
                "type":106,
                "passiveGameItems":null,
                "passiveGameLocations":null,
                "passiveGameNPCs":[1],
                "passiveGameTriggers":null,
                "passiveGameFlags":null,
                "newIntegerValue":4,
                "newBooleanValue":null,
                "newStringValue":null,
                "message":null
            },{
                "id":3,
                "type":111,
                "passiveGameItems":null,
                "passiveGameLocations":null,
                "passiveGameNPCs":[1],
                "passiveGameTriggers":null,
                "passiveGameFlags":null,
                "newIntegerValue":null,
                "newBooleanValue":"false",
                "newStringValue":null,
                "message":null
            },{
                "id":4,
                "type":109,
                "passiveGameItems":null,
                "passiveGameLocations":null,
                "passiveGameNPCs":[1],
                "passiveGameTriggers":null,
                "passiveGameFlags":null,
                "newIntegerValue":2,
                "newBooleanValue":null,
                "newStringValue":null,
                "message":null
            },{
                "id":5,
                "type":113,
                "passiveGameItems":null,
                "passiveGameLocations":null,
                "passiveGameNPCs":[1],
                "passiveGameTriggers":null,
                "passiveGameFlags":null,
                "newIntegerValue":null,
                "newBooleanValue":null,
                "newStringValue":"",
                "message":null
            },{
                "id":6,
                "type":401,
                "passiveGameItems":null,
                "passiveGameLocations":null,
                "passiveGameNPCs":null,
                "passiveGameTriggers":null,
                "passiveGameFlags":[8],
                "newIntegerValue":null,
                "newBooleanValue":true,
                "newStringValue":null,
                "message":null
            }
                ]
            }
        ]
            }
        ],
        "conversationImage":"k128_dialog.png"
    }
        ],
        "initialBranch":1,
        "moodRequirements":null,
        "locationRequirements":null,
        "inventoryRequirements":null,
        "defaultImage":"k128_dialog.png",
        "triggers":null
    },
...
]

Como se puede ver -más o menos- la conversaciones se apoyan en tres elementos, los árboles de conversación -implementados en la clase ConversationTree.java-, las ramas de conversación -ConversationBranch.java- y las opciones de conversación -ConversationOption.java-. Un árbol estará compuesto de varias ramas que presentan al jugador la parte del diálogo que corresponde al personaje con el que está hablando. Estas ramas tienen asociadas una serie de opciones que representan las respuestas que dará el jugador y que determinan la navegación a través de las diferentes ramas del árbol.

Orrarrum

Los diferentes atributos asociados a un árbol de conversación son los siguientes.
  • id. El identificador numérico único asociado al árbol de conversación.
  • conversationBranches. Un array de objetos ConversationBranch.java que contiene todas las ramas de conversación asociadas al árbol.
  • initialBranch. La rama inicial del árbol. Al iniciar una conversación, el texto y la imagen asociadas a esta rama, así como sus opciones de ocnversación, serán las que sean presentadas al jugador.
  • moodRequirements, locationRequirements, inventoryRequirements. Pendientes de implementación. En un futuro servirán para hacer que el acceso a un árbol de conversación esté condicionado por la actitud del personaje, la localización en la que se encuentra y los objetos que el jugador lleve en su inventario.
  • defaultImage. Imagen por defecto de la conversación. Será la imagen que se muestre en la pantalla de conversación si la rama actual no define ninguna imagen específica.
  • triggers. Disparadores que se activaran al iniciar o finalizar la conversación. Los disparadores definidos con tipo ON_TALK_TRIGGER se activarán al empezar la conversación mientras los definidos como ON_CONVERSATION_FINISH_TRIGGER se activarán cuando el jugador seleccione una opción de conversación que dé por finalizada la misma.
Por su parte las ramas tienen los siguientes atributos.
  • id. Como siempre, el identificador numérico de la rama.conversationText. El texto que se mostrará en pantalla al entrar en la rama de conversación.
  • triggers. Pendiente de implementación. Contendría los disparadores que se activarían al llegar a la rama; probablemente se elimine este campo debido a que, a efectos prácticos, esto ya se consigue con los disparadores definidos en la clase ConversationOption.java.
  • conversationOptions. Un array de objetos ConversationOption.java con las respuestas disponibles.
  • conversationImage. La imagen que se deberá mostrar en la pantalla del diálogo, en caso de que sea diferente de la imagen por defecto de la conversación.
Al entrar en una rama se mostrará en pantalla el texto indicado en conversationText y un listado con las opciones definidas en conversationOptions. El jugador podrá seleccionar una de estas opciones, lo que hará que se cargue otra rama del árbol o se termine la conversación volviendo a la pantalla de juego normal.

Por su parte, los atributos de las opciones de conversación son los siguientes.
  • id. Sí, el identificador numérico de la opción de conversación.
  • optionText. El texto que se mostrará en la lista de opciones de conversación.
  • destinationBranch. El identificador numérico de la rama de la conversación que se deberá mostrar al seleccionar la opción. Si el valor es 0 se finalizará la conversación.
  • moodRequirements, locationRequirements, inventoryRequirements, skillRequirements. Pendientes de implementación. De manera similar a los campos análogos del árbol de conversación, representan requisitos relativos a la actitud y ubicación del personaje, a objetos del inventario del jugador y a valores en sus habilidades (este último aspecto no está implementado, ya hablaremos de él cuando veamos la definición de los datos del personaje jugador).
  • gameTriggers. Disparadores que se activarán al seleccionar la opción de conversación.
Pues por hoy creo que tienen bastante que masticar. No se preocupen que cada vez queda menos para terminar con los archivos de configuración y entrar a cosas más divertidas. Más o menos.

Ale, a conversar.

No comments: