CAAD

Comunidad de Aventuras Conversacionales y Relatos Interactivos
Fecha actual 25 Jun 2017 15:10

Todos los horarios son UTC + 1 hora




Nuevo tema Responder al tema  [ 84 mensajes ]  Ir a página Anterior  1, 2, 3, 4, 5, 6  Siguiente
Autor Mensaje
NotaPublicado: 11 Nov 2013 13:08 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5265
Ubicación: Coruña
Ahh, vale. Fallo mío, por sugerirte hacer estas cosas en el método onInit()... cosa que no es la correcta (lo siento, cómo se nota que llevo tiempo sin hacer una aventura en AGE yo mismo).

Al crear relaciones en el método onInit(), efectivamente dependes del orden en que se crean las entidades. Si una entidad A se crea cuando la B todavía no está creada, el onInit() de la entidad A no podrá referirse a la B, porque aún no existe. Por ello, los onInit() de una entidad no deberían referirse a otra, salvo que sea a una entidad que está garantizada que se cree antes (las habitaciones se crean antes que los personajes y las cosas, por ejemplo).

¿Cómo hay que hacer estas cosas entonces? Pues en el método intro(), que está garantizado que se ejecuta cuando todo el mundo está inicializado. Ahí o bien puedes inicializar todas las relaciones, o bien puedes, si quieres mantener la modularidad, llamar a un método de cada entidad que las inicialice(pero que tenga un nombre distinto de onInit).

Lo dicho, siento no habértelo dicho bien antes.

Por cierto que también existe la posibilidad de crear las relaciones en PUCK en lugar de por código, lo que pasa es que eso no te lo he sugerido porque, como entiendo que tienes muchísimas, acabarías con una maraña de flechas.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 11 Nov 2013 13:30 
Desconectado
Implementador
Implementador

Registrado: 13 Feb 2005 18:57
Mensajes: 1853
[Se me adelantó Al-K, pero aquí va la respuesta que estaba escribiendo mientras contestó, porque aporta otra posible solución]

Creo que durante los onInit() no se da por asegurada la existencia de otra entidades, aparte de la que se está inicializando.

Por eso supongo que tienes problemas al hacer referencia a otras: cabe la posibilidad de que AGE todavía no las haya inicializado.

Se me ocurren dos soluciones:
  • Guardar simplemente el nombre único (string) en las relaciones, en vez de las entidades.
  • Crear las relaciones en otra función (en cada entidad, por ejemplo inicializarRelacionesDeConversacion), a la que llamaremos tras todas las inicializaciones (por ejemplo en intro()). Las llamadas se podrían automatizar, pero de momento tendrías que llamar a mano a cada una.

Si quieres podemos entrar en detalles sobre la segunda, pero la primera podría ser suficiente si no te obliga a retocar mucho el código que utiliza las relaciones.

Un par de dudas, de paso:
  • ¿No eran problemáticas las entidades como valores de propiedades o relaciones a la hora de guardar partidas?
  • No existe onInit() en el mundo, que se ejecute como último paso de la inicialización ¿verdad?


Arriba
 Perfil  
 
NotaPublicado: 11 Nov 2013 13:46 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Ok, gracias, ya sabiéndolo perfecto.

En intro he colocado:

Código:
//INICIALIZAMOS LAS RELACIONES ENTRE LOS PERSONAJES Y COSAS
mobile("eugenia").inicializar();
mobile("fede").inicializar();


Y en la función inicializar de cada personaje las relaciones que hemos comentado y va todo bien. Una pregunta, existe una forma de "automatizarlo" con un bucle for.
Es decir, igual que teníamos un for para cada entidad que tienen una relación:

Código:
...
temas = self.getRelatedEntities("hablaDe");
for ( Entity e : temas )
....


Recorrer todas las entidades que son personajes y lanzar la función inicializar() que he creado en cada una de ellas.
Ahora solo tengo dos personajes y en total en la historia habrá unos...10, si no me caliento mucho, y bueno 10 líneas de código para inicializar las relaciones no pasa nada. Pero y si me caliento y pongo 100 personajes... sería 100 líneas de código.


Gracias!

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 11 Nov 2013 13:52 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
dddddd escribió:
[Se me adelantó Al-K, pero aquí va la respuesta que estaba escribiendo mientras contestó, porque aporta otra posible solución]

Creo que durante los onInit() no se da por asegurada la existencia de otra entidades, aparte de la que se está inicializando.

Por eso supongo que tienes problemas al hacer referencia a otras: cabe la posibilidad de que AGE todavía no las haya inicializado.

Se me ocurren dos soluciones:
  • Guardar simplemente el nombre único (string) en las relaciones, en vez de las entidades.
  • Crear las relaciones en otra función (en cada entidad, por ejemplo inicializarRelacionesDeConversacion), a la que llamaremos tras todas las inicializaciones (por ejemplo en intro()). Las llamadas se podrían automatizar, pero de momento tendrías que llamar a mano a cada una.

Si quieres podemos entrar en detalles sobre la segunda, pero la primera podría ser suficiente si no te obliga a retocar mucho el código que utiliza las relaciones.

Un par de dudas, de paso:
  • ¿No eran problemáticas las entidades como valores de propiedades o relaciones a la hora de guardar partidas?
  • No existe onInit() en el mundo, que se ejecute como último paso de la inicialización ¿verdad?


He publicado mi respuesta y he visto esta.

Gracias!

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 11 Nov 2013 13:59 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5265
Ubicación: Coruña
Sí, existe una forma de recorrer todos los personajes del mundo.

Código:
world.getAllMobiles()


te da una lista de todos ellos. Así que puedes hacer

Código:
for ( Mobile m : world.getAllMobiles() ) ...


A la pregunta de dddddd, sí, el juego no se puede guardar si las propiedades o relaciones toman valores que no sean tipos básicos o Strings (porque no hay una forma que permita guardar cualquier objeto). Pero no es el caso de lo que está haciendo edlobez, porque en su caso se trata de relaciones entre dos entidades que tienen como valor un String.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 11 Nov 2013 14:10 
Desconectado
Implementador
Implementador

Registrado: 13 Feb 2005 18:57
Mensajes: 1853
Al-Khwarizmi escribió:
Sí, existe una forma de recorrer todos los personajes del mundo.
Código:
world.getAllMobiles()

te da una lista de todos ellos. Así que puedes hacer
Código:
for ( Mobile m : world.getAllMobiles() ) ...

Nótese que si vas a llamar a una función en todos los Mobile, la función tiene que existir en todos. Si no va a existir en todos, tendrías que marcarlos de alguna manera (una propiedad tipo "hay_que_inicializar_conversacion", p.ej.), para discriminar con un if dentro del bucle. O hacer el bucle sobre una lista manual de los Mobile que tienen la función.

Al-Khwarizmi escribió:
Pero no es el caso de lo que está haciendo edlobez, porque en su caso se trata de relaciones entre dos entidades que tienen como valor un String.


Ups, vale, entendí mal. Entonces la primera solución que propuse no tiene sentido, edlobez. Perdona.


Arriba
 Perfil  
 
NotaPublicado: 11 Nov 2013 15:16 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Paso como me ha quedado el código en la función intro del world:

Código:
EntityList gentes= world.getAllMobiles();
    for ( int i=0; i<gentes.size(); i++ ) {
             //si el personaje tiene la propiedad iniciarConversa hay que inicializar la función
             if (get(gentes.get(i), "iniciarConversa")!=null) {
                gentes.get(i).inicializar();
                //aPlayer.waitKeyPress();
             }         
    }


La lista de personajes la he tenido que manejar de la forma que está ya que de la forma

Código:
for ( Mobile m : world.getAllMobiles() ) ...


No me funcionaba, creo que se que le pasa, pero bueno de la forma que lo he puesto me aclaro mejor.

Gracias

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 11 Nov 2013 18:43 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Por cierto
Al-Khwarizmi escribió:
...cómo se nota que llevo tiempo sin hacer una aventura en AGE yo mismo).
....


a ver cuando nos animamos.

:P

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 19 Nov 2013 16:09 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Una duda, bueno otra...

Tengo un objeto, "llave", que la tiene un personaje, "eugenia". Le tengo que pedir la llave a este personaje, si el objeto lo tiene el personaje, he creado la relación entre el objeto y el personaje de PSI TIENE OBJETO A. No puedo realizar ninguna acción sobre el OBJETO A (no lo tengo al alcance). Para pedirle el objeto al personaje he puesto este código en el personaje:

Código:
void parseCommand( Mobile aCreature , String verb , String args ) {

.....
if (equals(verb, "pedir")) {
        if (item("llave").matchesCommand(args,false) > 0 ) {
            mobile("jugador").write("En el personaje Eugenia, le quieres pedir la llave a eugenia.\n");
            end();}
    }

.....
}


Vale y funciona como quiero.
Luego, en la documentación aparece un método para el análisis sintáctico de la entrada referida a dos cosas, por lo que en el objeto llave puse este código:

Código:
void parseCommandObj1 ( Mobile aCreature , String verb , String args1 , String args2 , Entity obj2  )
{
   
    if (equals(verb, "pedir")) {
        if (equals(obj2, mobile("eugenia"))) {
            mobile("jugador").write("En el objeto LLAVE, le quieres pedir la llave a eugenia.\n");
            end();}       
    }

}


Que no funciona si la llave la tiene el personaje "Eugenia". Para que funcione tengo que poner la llave oculta en la habitación donde está el personaje, y hacerla visible cuando Eugenia me hable de ella. Y además tendría que "capar" verbos como coger, mover.... mientras la llave la tenga el personaje, cosa que debo controlar mediante una propiedad.....

Bueno a simple vista parece mejor el primer método que he usado y funciona bien... entonces que haces aquí preguntando y mareando a la gente edlobez.. que hartible que eres...
pues pregunto porque tendré más personajes en la historia a los cuales habrá que pedirles y darles cosas, no quiero hacer algo de una manera para que más adelante me digan, noooo, si tendrías que haberlo hecho de la otra forma, por que ahora con esta acción y como lo has hecho se descugeringa la junta la trocola.... etc.... (cosa, que he decir, que siempre agradezco, para no ir rompiendo más juntas de trocolas...)

Gracias!!!!
... y perdón por el desvarío mental 8)

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 19 Nov 2013 22:53 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5265
Ubicación: Coruña
No, si siempre está bien que preguntes estas cosas, porque efectivamente, a veces hacemos algo de maneras que no son las mejores.

Pero en este caso, no hay una alternativa claramente mejor. Los parseCommand de dos entidades están pensados para entidades que están presentes. Para las que no están no sirven, y por lo tanto hay que hacer lo que tú has hecho (o eso o, como dices, hacer "chapuzas" para que las entidades sí que estén aunque no se note, pero no creo que merezca la pena).

Para el futuro creo que tendré que plantearme, de alguna manera, que se puedan definir parseCommands que actuén sobre entidades que no están. Inicialmente no pensé en tal cosa, pero parece que hay casos (como el que planteas) en los que puede ser útil. El tema será cómo añadir esa funcionalidad sin crear todavía más parseCommands, que no es que haya pocos ya :D

Pero vamos, que en la actual versión de AGE, la solución que has implementado es (por lo que a mí se me ocurre) la mejor.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 20 Nov 2013 20:26 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Hola de nuevo!

Se puede eliminar el eco del comando "decir". Por ejemplo:

>decir "hola" a manolo
dices "hola" a manolo -----> eliminar este eco
Manolo dice "Hola pesao"


He preparado las conversas de tal forma que el eco resultaría repetitivo en algunas ocasiones, y tendría que eliminarlo; por ejemplo

>decir "hola" a manolo
dices "hola" a manolo -----> este eco necesitaría eliminarlo, resultaría repetitiva con la siguiente línea.
dices Manolo qué tal buenos días!
Manolo dice "otra vez tu..."

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 21 Nov 2013 00:54 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5265
Ubicación: Coruña
Pues he echado un vistazo y creo que has dado con una de los pocos (sino el único) mensajes que quedan en AGE que no he sacado al fichero de mensajes por defecto... al principio los mensajes no eran configurables, luego los saqué al fichero para que se pudieran configurar, me olvidé alguno, me los fueron diciendo y... bueno, parece que éste se me olvidó y aún está "cableado" en el código ahora mismo.

Para que lo puedas cambiar (o, en tu caso, quitar) tengo por lo tanto que hacer unos cambios en AGE para que ese mensaje sea configurable también. Pero no worries, que lo hago mañana mismo, ya que no es un cambio nada complicado.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 21 Nov 2013 08:27 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Ok muchas gracias!

Por cierto en breve tendré parte de la aventura que estoy escribiendo. La quiero dividir en varios "módulos" unos 3 o 4 he calculado, y buscar voluntario para ir testeándolo módulo a módulo.
Si la entrego para testear al final, sería demasiado complicado y se podría alargar un poco. Si se va probando por módulos, mientras se prueba un módulo voy avanzando con el siguiente y corrigiendo fallos del anterior, e incluso poder modificar el avance de la historia en función de las opiniones...
Esta primera parte que estoy acabando he tardado un poca más ya que he empezado de cero con AGE y voy aprendiendo sobre la marcha, pero ya he cogido buen ritmo.
Bueno por ahora lo dejo dicho como avance, en cuanto tenga casi acabado este primer módulo, abriré hilo nuevo en el foro autores para buscar voluntario.

Gracias de nuevo!

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 21 Nov 2013 17:37 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5265
Ubicación: Coruña
Ya he arreglado la limitación de que ese mensaje no se pudiera configurar como los demás.

Te he puesto una versión de AGE con el problema arreglado en:

https://dl.dropboxusercontent.com/u/194 ... 211729.zip

De momento la versión no es oficial (no está disponible para que el público en general se la baje) pero en cuanto haga falta porque vayas a sacar la aventura, sacaré una oficial con todos los cambios que haya hasta entonces.

Los mensajes por defecto relacionados con decir cosas están al final de los ficheros messages.lan:

Código:
#Alguien dice algo
someone.says.something=$1 dice \"$text\".\n

#Dices algo
you.say.something=Dices \"$text\".\n

#Alguien dice algo a alguien
someone.tells.someone.something=$1 dice \"$text\" a $2.\n

#Alguien te dice algo
someone.tells.you.something=$1 te dice \"$text\".\n

#Dices algo a alguien
you.tell.someone.something=Dices \"$text\" a $2.\n


Y se pueden cambiar con todos los mecanismos habituales para cambiar mensajes por defecto (véase la documentación), para que digan otra cosa o, en tu caso, para que no digan nada:

Código:
Tu orden:  decir hola
Dices "hola".

Tu orden:  eval world.getMessages().setMessage("you.say.something","")
null

Tu orden:  decir hola

Tu orden:  eval world.getMessages().setMessage("you.say.something","En alta y resonante voz, proclamas: \"$text\"")
null

Tu orden:  decir hola
En alta y resonante voz, proclamas: "hola".

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 21 Nov 2013 19:06 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Muchas gracias de nuevo!

Me pongo con ello.

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
Mostrar mensajes previos:  Ordenar por  
Nuevo tema Responder al tema  [ 84 mensajes ]  Ir a página Anterior  1, 2, 3, 4, 5, 6  Siguiente

Todos los horarios son UTC + 1 hora


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados


No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro

Buscar:
Saltar a:  
Desarrollado por phpBB® Forum Software © phpBB Group
Traducción al español por Huan Manwë para phpBB-Es.COM