CAAD

Comunidad de Aventuras Conversacionales y Relatos Interactivos
Fecha actual 23 Sep 2018 10:25

Todos los horarios son UTC + 1 hora




Nuevo tema Responder al tema  [ 23 mensajes ]  Ir a página 1, 2  Siguiente
Autor Mensaje
NotaPublicado: 24 Ene 2011 12:12 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
No sé si es que no termino de entenderlo...

Si hago un forceCommand desde un contenedor a su propio contenido, y el contenido captura la nueva acción, se inicia un bucle en el que la acción se llama a sí misma una y otra vez ¿no?

Es que he comprobado que si saco el contenido del contenedor, todo funciona correctamente, pero si lo meto, los turnos corren hasta que un update lo para.

¿Es el comportamiento normal?


Mi problema es que quiero que "echar contenedor" sea sinónimo de "echar contenido".

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 24 Ene 2011 13:18 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5303
Ubicación: Coruña
El forceCommand con los contenedores no tiene ningún comportamiento especial. El forceCommand no sabe nada ni de contenidos, ni de contenedores, ni de objetos, ni nada. Simplemente lo único que hace es mandarle a un jugador (o criatura) que ejecute una orden, y la orden se ejecutará como si el jugador la hubiese tecleado, sin que haya ninguna distinción especial. Si desde la ejecución de una orden mandas ejecutar ese mismo comando (sea sobre contenedores o cualquier otra cosa), se crea el bucle.

En tu caso, imagino que "echar contenedor" estará forzando "echar contenido", y "echar contenido" forzará a su vez "echar contenido", creando el bucle. O eso, o bien "echar contenedor" está forzando realmente "echar contenedor".

Poniendo un write antes de llamar a los forceCommand puedes saber exactamente cuál es la cadena de comandos que se está forzando:

jugador.write("Estoy forzando " + loquesea);
jugador.forceCommand(loquesea);

_________________
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: 24 Ene 2011 13:24 
Desconectado
Implementador
Implementador

Registrado: 13 Feb 2005 18:57
Mensajes: 1863
jenesis escribió:
Es que he comprobado que si saco el contenido del contenedor, todo funciona correctamente, pero si lo meto, los turnos corren hasta que un update lo para.

¿Es el comportamiento normal?
Mi problema es que quiero que "echar contenedor" sea sinónimo de "echar contenido".


Mmmm... ¿De qué me suena...?

jenesis escribió:
dddddd escribió:
Una locura que se me ocurre es un subsistema en el multiverso que controle, mediante heurística, estas anomalias (y destruya el hilo descontrolado), unido a un sistema de energias que haga que el descontrol desaparezca por agotamiento, para casos no detectables.



Pero a ver...
¿Qué estáis haciendo?
¿Un parser o un arma nuclear? :lol:


¿Se te descontrola la fusión? :P

Perdón por la salida de tema, no he podido resistirlo ;)


Arriba
 Perfil  
 
NotaPublicado: 24 Ene 2011 13:52 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Al-Khwarizmi escribió:
En tu caso, imagino que "echar contenedor" estará forzando "echar contenido", y "echar contenido" forzará a su vez "echar contenido", creando el bucle. O eso, o bien "echar contenedor" está forzando realmente "echar contenedor".


Pero en ese caso daría lo mismo que el contenido estuviera dentro o fuera del contenedor ¿no?
De ambas maneras se ejecutaría el bucle. ¿no?

PD: De todos modos ni dejando el código del contenido en blanco consigo que el bucle no se ejecute. La única manera de que no lo haga es que deje de ser contenido.

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 24 Ene 2011 14:03 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5303
Ubicación: Coruña
jenesis escribió:
Pero en ese caso daría lo mismo que el contenido estuviera dentro o fuera del contenedor ¿no?
De ambas maneras se ejecutaría el bucle. ¿no?

Pues es que a eso no te puedo contestar porque dependerá de cómo sea específicamente tu código... de cuándo fuerzas (sólo si el contenido está dentro, o cómo) y de qué comando fuerzas específicamente...

Como digo, el forceCommand no sabe ni de contenedores, ni de contenidos ni de nada. Es un comando que no trabaja con nada del modelo de mundo. Sólo "teclea" un string, simplemente. Y el string se interpreta como si viniese del teclado. Que el bucle se comporte de una forma o de otra dependiendo de temas de contenedores dependerá de lo que estés haciendo tú según cómo estén los contenedores, el forceCommand no comprueba nada relacionado con eso, lo compruebas tú.

¿No tendrás otra vez el problema de siempre de que tienes un generic y no has puesto la comprobación de que el comando se refiere al contenido y no al contenedor? ¿Ese if que te dije que si ponías siempre, resolverías el 90% de tus problemas con contenedores? :)

_________________
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: 24 Ene 2011 14:10 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
En un mundo básico:

El bote:

Código:
void parseCommandOnContentsGeneric ( Mobile aCreature , String verb , String args1 , String args2 , Vector path1 , Vector path2 , Entity obj1 , Entity obj2 , boolean goesFirst )
{
 
  String args=args1 + args2;

      
  if(equals(verb,"lanzar"))      
   {
    aCreature.write("Estoy forzando lanzar comida " + verb +"\n");
    aCreature.forceCommand("Lanzar comida" + args);
     end(); 
    }        

}


su contenido, La comida:

Código:
void parseCommandOnContentsGeneric ( Mobile aCreature , String verb , String args1 , String args2 , Vector path1 , Vector path2 , Entity obj1 , Entity obj2 , boolean goesFirst )
{

String args= args1+args2;
 
   if(equals(verb,"lanzar"))
   {   
       aCreature.write("Lanzas la comida.\n");
       end();
   }

}


El resultado:
orzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
etc...


Si es normal, no lo entiendo. :(

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 24 Ene 2011 15:04 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
jenesis escribió:
En un mundo básico:

Spoiler: Mostrar
El bote:

Código:
void parseCommandOnContentsGeneric ( Mobile aCreature , String verb , String args1 , String args2 , Vector path1 , Vector path2 , Entity obj1 , Entity obj2 , boolean goesFirst )
{
 
  String args=args1 + args2;

      
  if(equals(verb,"lanzar"))      
   {
    aCreature.write("Estoy forzando lanzar comida " + verb +"\n");
    aCreature.forceCommand("Lanzar comida" + args);
     end(); 
    }        

}


su contenido, La comida:

Código:
void parseCommandOnContentsGeneric ( Mobile aCreature , String verb , String args1 , String args2 , Vector path1 , Vector path2 , Entity obj1 , Entity obj2 , boolean goesFirst )
{

String args= args1+args2;
 
   if(equals(verb,"lanzar"))
   {   
       aCreature.write("Lanzas la comida.\n");
       end();
   }

}


El resultado:
orzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
Estoy forzando lanzar comida Lanzar
etc...

Si es normal, no lo entiendo. :(



He conseguido que funcione haciendo que el verbo capturado en el contenedor, no sea el mismo que se fuerza a ejecutar en el contenido.

Código:
//bote

void parseCommandOnContentsGeneric ( Mobile aCreature , String verb , String args1 , String args2 , Vector path1 , Vector path2 , Entity obj1 , Entity obj2 , boolean goesFirst )
{
 
  String args=args1 + args2;

      
  if(equals(verb,"lanzar"))      
   {
    aCreature.write("Estoy forzando tirar comida " + verb +"\n");
    aCreature.forceCommand("tirar comida" + args);
     end(); 
    }        

}



Código:
//comida

void parseCommandOnContentsGeneric ( Mobile aCreature , String verb , String args1 , String args2 , Vector path1 , Vector path2 , Entity obj1 , Entity obj2 , boolean goesFirst )
{

String args= args1+args2;

 
 
   if(equals(verb,"tirar"))
   {   
       aCreature.write("Tiras la comida.\n");
       end();
   }

}


Si era esto lo que no entendía, la verdad es que sigo sin entenderlo.
Del mismo modo que no entiendo que lo otro funcione correctamente, siempre y cuando la comida no esté dentro del contenedor.
Pero bueno, al menos ya sé cómo arreglarlo.

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 24 Ene 2011 15:06 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5303
Ubicación: Coruña
jenesis escribió:
Si es normal, no lo entiendo. :(


Es totalmente normal... a ver, pusiste un forceCommand un poco raro, porque imprimes al final el verb en vez de los args.

Pero básicamente:

- El jugador pone lanzar bote.
- Fuerzas: "lanzar comida bote" (ahí se muestra lanzar comida lanzar porque has impreso verb en vez de args, pero lo fuerzas con los args).
- Se vuelve a ejecutar el parseCommand del bote.
- Fuerzas "lanzar comida bote"
- Etc.

De hecho, incluso si no forzaras con los args, el bucle seguiría produciéndose igual igual porque no haces el famoso if... el código para el bote va a saltar tanto para el bote como para la comida, ya que en ningún momento compruebas que obj1 sea igual a path1.get(0).

No entiendo por qué piensas que con esos comandos puede pasar otra cosa que un bucle... si con una acción estás forzando la misma...

Ten en cuenta que el método genérico que tú usas se ejecuta tanto si el objeto en el que lo estás definiendo se menciona en la orden (de primero o de segundo), como si el objeto en el que lo estás definiendo contiene al que se menciona en la orden (de primero o de segundo). Tú no estás haciendo ninguna comprobación de en cuál de estos casos encuentras, así que tu forceCommand se ejecuta en todos estos casos. Y uno de ellos es que se ejecute una orden sobre el contenido, pero se ejecute el método del contenedor.

Con que hagas algo así, ya está:

Código:
//bote
 if ( obj1.equals(path1.get(0) )
 {
  if(equals(verb,"lanzar"))       
   {
     aCreature.forceCommand("lanzar comida");
     end(); 
    }         
  }
}


Código:
//comida
if ( obj1.equals(path1.get(0) )
{
   if(equals(verb,"lanzar"))
   {   
       aCreature.write("Tiras la comida.\n");
      end();
   }
}


Lo que has hecho también resuelve el problema "de rebote", porque al forzar verbos distintos el contenedor fuerza un "tirar" (en lugar de "lanzar") que el contenedor no entiende (sólo el contenido) y se rompe el bucle.

Pero la solución para resolver el tema sin usar dos verbos sería ésa.

Y de todas formas, sigues sin hacerme caso cuando te digo que en todos estos parseCommand genéricos deberías estar comprobando que obj1.equals(path1.get(0)), y si usas obj2, que obj2.equals(path2.get(0)). Y esto te puede dar más problemas. No sé si te das cuenta de que ya vamos como por el octavo o noveno fallo causado por esa misma cosa (sin exagerar), y todos se arreglan exactamente igual, comprobando eso...

_________________
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: 24 Ene 2011 15:20 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Si hay un obj2 y no es "éste"

if ( obj2!=null && (equals(obj1,path1.get(0)) && equals(obj2,path2.get(0))) )

¿Es eso lo que significa esa línea?

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 24 Ene 2011 15:33 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5303
Ubicación: Coruña
jenesis escribió:
Si hay un obj2 y no es "éste"

if ( obj2!=null && (equals(obj1,path1.get(0)) && equals(obj2,path2.get(0))) )

¿Es eso lo que significa esa línea?


Significa que exista obj2, y que además obj1 y obj2 sean los objetos a los que se refirió el jugador con su orden. Sería una comprobación para acciones que necesitan que el jugador teclee dos objetos.

Para las de un objeto, podría ser simplemente if ( equals(obj1,path1.get(0)) ) que fue la que te puse antes (ya que para un objeto no nos importa que haya obj2).

_________________
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: 24 Ene 2011 15:44 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Al-Khwarizmi escribió:
jenesis escribió:
Si hay un obj2 y no es "éste"

if ( obj2!=null && (equals(obj1,path1.get(0)) && equals(obj2,path2.get(0))) )

¿Es eso lo que significa esa línea?


Significa que exista obj2, y que además obj1 y obj2 sean los objetos a los que se refirió el jugador con su orden. Sería una comprobación para acciones que necesitan que el jugador teclee dos objetos.

Para las de un objeto, podría ser simplemente if ( equals(obj1,path1.get(0)) ) que fue la que te puse antes (ya que para un objeto no nos importa que haya obj2).



Cualquier contenedor se puede vaciar, echar, volcar, tirar, arrojar, en un lugar determinado, así que realmente necesito hacer ambas comprobaciones.
Lo que ocurre es que es complejo aplicar lo que no se entiende por completo.
La famosa línea, realmente son dos ¿no?

if ( null==obj2 && equals(obj1,path1.get(0) ) )
{
acciones que competen a este único objeto
}

if ( null!=obj2 && (equals(obj2,path2.get(0) ) ) )
{
acciones que competen a este y a otro objeto.
}

Y si poniendo estas dos condiciones en cualquier objeto contenedor y en cualquier objeto capaz de ser contenido, se arreglan todos los problemas que he tenido con contenedores y contenidos ¡alabados sean Santa Tecla y San RAM-on!

PD: Creo que me he hecho un poco de lío con los paréntesis y con un path... xD

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 24 Ene 2011 15:52 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5303
Ubicación: Coruña
En la segunda yo pondría más bien:

Código:
if ( null!=obj2 && equals(obj1,path1.get(0)) && equals(obj2,path1.get(0)))


porque en el caso de dos objetos, así te aseguras que obj1 y obj2 son los objetos a los que se ha referido el jugador.

Y sí, esas comprobaciones arreglan todo este tipo de problemas... pero no es novedad, ya te lo he dicho más veces, lo que pasa es que no me haces caso... :D

A ver, el tema resumido es que ese método tan genérico que usas tiene dos posibles usos:

1. Capturar órdenes sobre uno o dos objetos a los que se refiere el jugador, y que pueden estar contenidos en contenedores.
2. Que desde un objeto contenedor, puedas capturar órdenes sobre objetos que están dentro.

Tú el uso 2 nunca lo estás utilizando. Para tu aventura, estás usando sólo el uso 1. Pero si no haces ninguna comprobación, el método salta en ambos casos, tanto en el 1 como en el 2. Estas comprobaciones lo que hacen es excluir el 2.

_________________
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: 24 Ene 2011 16:00 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Al-Khwarizmi escribió:
En la segunda yo pondría más bien:

Código:
if ( null!=obj2 && equals(obj1,path1.get(0)) && equals(obj2,path1.get(0)))


porque en el caso de dos objetos, así te aseguras que obj1 y obj2 son los objetos a los que se ha referido el jugador.

Y sí, esas comprobaciones arreglan todo este tipo de problemas... pero no es novedad, ya te lo he dicho más veces, lo que pasa es que no me haces caso... :D


Y digo yo, siendo que esto es obligatorio para con todos los parseCommands genéricos. ¿Por qué no lo llevan puesto de fábrica?
Del mismo modo que al elegir el parseCommand se imprime automáticamente:

void parseCommandOnContentsGeneric ( Mobile aCreature , String verb , String args1 , String args2 , Vector path1 , Vector path2 , Entity obj1 , Entity obj2 , boolean goesFirst )
{

}

¿No se podría añadir entre las llaves?

if ( null==obj2 && equals(obj1,path1.get(0) ) )
{
acciones que competen a este único objeto
}

if ( obj2!=null && (equals(obj1,path1.get(0)) && equals(obj2,path2.get(0))) )
{
acciones que competen a este y a otro objeto
}

Es que creo que les ibas a ahorrar muchos dolores de cabeza a futuros usuarios. :lol:
Si te fijas, en el primer caso compruebo que no exista obj2, no sé si es del todo necesario.

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
NotaPublicado: 24 Ene 2011 16:07 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5303
Ubicación: Coruña
jenesis escribió:
Y digo yo, siendo que esto es obligatorio para con todos los parseCommands genéricos. ¿Por qué no lo llevan puesto de fábrica?

Porque es que en realidad no es obligatorio, sólo lo es para el uso que haces tú de esos métodos.

Como dije en el mensaje anterior, estos parseCommand también se pueden utilizar para que un contenedor capture órdenes que se refieren a un objeto contenido en él. En ese caso, no te interesan esas comprobaciones (de hecho, habría que hacer justo las comprobaciones opuestas).

Lo que pasa es que he visto que en tu aventura no tienes ningún puzzle donde un contenedor capture órdenes referidas a objetos contenidos en él, todos los usos que haces de ese método son para capturar órdenes en los objetos a los que se refieren. Por eso digo que para el uso que tú particularmente haces del método, esas comprobaciones resuelven el problema. Pero no son algo universal porque hay usos en los que no hay que poner eso. De hecho, si fuesen algo universal ya habría puesto yo esas comprobaciones en el propio código de AGE, no le pasaría la pelota al usuario sin necesidad; pero es que no es el caso.

Lo que a lo mejor sí tiene sentido hacer en PUCK es que el mismo método tenga varias plantillas: una para el caso 1 que mencionaba antes, otra para el caso 2 y otra para ambos. Aunque habría que pensar si realmente compensa, porque igual ver tantas plantillas abruma al usuario haciéndole pensar cuál elegir, más que ayudarlo.

jenesis escribió:
Si te fijas, en el primer caso compruebo que no exista obj2, no sé si es del todo necesario.

Pues depende de cómo quieras que se analice la entrada.

Si quieres que funcione sólo "verbear X" y no "verbear X Y", sí, es necesario.

Si te da igual, y te sirve que funcionen las dos cosas, no lo es.

_________________
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: 24 Ene 2011 16:17 
Desconectado
xyzzy

Registrado: 09 Mar 2004 22:50
Mensajes: 9150
Al-Khwarizmi escribió:
jenesis escribió:
Si te fijas, en el primer caso compruebo que no exista obj2, no sé si es del todo necesario.

Pues depende de cómo quieras que se analice la entrada.

Si quieres que funcione sólo "verbear X" y no "verbear X Y", sí, es necesario.

Si te da igual, y te sirve que funcionen las dos cosas, no lo es.


Pues es que si no lo compruebo, cualquier acción que competa a ese y otro objeto, no pasa de ahí, es capturada y la segunda comprobación nunca se ejecuta.

>lanza el bote
Lanzas la comida.

>Lanza el bote a los cococrilos.
Lanzas la comida

Cuando debería ser

>Lanza el bote a los cocodrilos.
Las aguas se agitan mientras los cocodrilos luchan por hacerse con el mejor bocado.

Así que debo de estar haciendo alguna otra cosa mal... :\

_________________
Si la mentira tuviera color, todos seríamos daltónicos...


Arriba
 Perfil  
 
Mostrar mensajes previos:  Ordenar por  
Nuevo tema Responder al tema  [ 23 mensajes ]  Ir a página 1, 2  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 1 invitado


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:  
cron
Desarrollado por phpBB® Forum Software © phpBB Group
Traducción al español por Huan Manwë para phpBB-Es.COM