tuts_gba
Thread Id: 25075
Thread Name: GBA | Scripting | People AI System Script by Javi4315
#0
Javi4315♪ 13374
Vaya, Javi, me sorprende un nuevo tutorial tuyo en tan poco tiempo. Pero tengo dos importantes dudas que me corroen ¿Para qué sirve este nuevo manual tan interesante? ¿Y, sobre todo, qué te ha dado ahora para escribir los títulos en ese idioma que invade nuestro amado Gibraltar?

Hola, querido yo mismo. Respondiendo a tus preguntas, esto es un sistema que diseñé para mi hack y que podéis ver si lo jugáis, se trata de un sistema que, dependiendo de la hora que sea, haya una determinada persona en la calle o no, o esté en una posición u otra. Sobre lo segundo, tiene más musicalidad (?) :P


Teoría

Vamos a ver. No podéis negarme que es raro si vais a hablar con una persona aleatoria a las 12:00 y esté en el mismo lugar y en el mismo sitio 10 horas después. Más si insertáis una sistema día/noche. Vas por la mañana y te dice: "¡Cómo brilla el Sol hoy!". Bien, pero es que vas en plena noche y te suelta lo mismo. Es raro. A parte, ¿Qué hace un señor todo el día en la calle? ¿No debería estar en casa a cierta hora? ¿No se ausenta del pueblo en ningún momento? ¿Para ir a la escuela? ¿Para ir a trabajar?

Bueno, pues este sistema pretende que cada persona esté en un lugar determinado dependiendo de la hora. O que dependiendo de la hora diga una cosa u otra (o no).

Un ejemplo de mi hack. En Ciudad Orquídea está el casino. Pero no puedes jugar sin fichas, igual que no puedes tener fichas sin un monedero. Pues el monedero te lo da un hombre. Ese hombre sólo aparece sentado en un banco por las noches (entre las 00:00 y las 4:00). Para conseguir el monedero, tienes que ir a hablar con él a esa hora, porque no aparece en ningún otro momento del día. Bueno, pues de eso se trata.


Para entenderlo mejor

Para el que no se haya enterado muy bien todavía, dejo la imagen de un mapa de mi hack y explico diferentes eventos:



1. El chico con la gorra amarilla que está arriba sólo es visible a primeras horas de la noche. Está escondido, fumando.
2. El hombre gordo aparece 3 veces. Eso se debe a que aparece en 3 periodos del día distintos, en distintas zonas y habla sobre distintas cosas. El resto de las horas está en casa (igual que el de la gorra amarilla).
3. La mujer rubia sólo aparece por la tarde porque "le gusta ver el atardecer".
4. La pokéball que se encuentra detrás de la tienda sólo se puede alcanzar si el tendero se quita. Obviamente en determinados momentos del día, el tendero no estará y podremos acceder a la pokéball.
5. El policía aparece de noche y de madrugada para vigilar la zona de manera más intensa. El resto del día no hay presencia policial.

Eso son algunos ejemplos. Se pueden hacer muchas cosas, a parte de estar hablando de un sistema mucho más realista.


Real Time Clock (RTC)

Para que los eventos funcionen dependiendo de la hora, debemos insertar el RTC al juego. Esto se puede hacer con la herramienta DNS, que también sirve para insertar el sistema día/noche. Se puede insertar el RTC sin necesidad de insertar el sistema día/noche, para el que quiera que siempre sea de día (que nunca lo entenderé xD).

Pues nada, abrís la herramienta, cargáis el rom y le dais a "Insert RTC".


¿Cómo lo hago?

Este es el script que yo uso en mi hack:

#dynamic 0x800000

#org @comienzo
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x7
if 0x1 goto @1
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x8
if 0x1 goto @1
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x9
if 0x1 goto @1
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0xA
if 0x1 goto @1
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0xB
if 0x1 goto @2
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0xC
if 0x1 goto @2
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0xD
if 0x1 goto @2
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0xE
if 0x1 goto @2
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0xF
if 0x1 goto @3
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x10
if 0x1 goto @3
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x11
if 0x1 goto @3
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x12
if 0x1 goto @4
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x13
if 0x1 goto @4
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x14
if 0x1 goto @4
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x15
if 0x1 goto @4
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x16
if 0x1 goto @5
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x17
if 0x1 goto @5
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x0
if 0x1 goto @6
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x1
if 0x1 goto @6
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x2
if 0x1 goto @6
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x3
if 0x1 goto @6
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x4
if 0x1 goto @7
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x5
if 0x1 goto @7
copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x6
if 0x1 goto @7
end

#org @1
clearflag 0x500
setflag 0x501
setflag 0x502
setflag 0x503
setflag 0x504
setflag 0x505
setflag 0x506
end

#org @2
setflag 0x500
clearflag 0x501
setflag 0x502
setflag 0x503
setflag 0x504
setflag 0x505
setflag 0x506
end

#org @3
setflag 0x500
setflag 0x501
clearflag 0x502
setflag 0x503
setflag 0x504
setflag 0x505
setflag 0x506
end

#org @4
setflag 0x500
setflag 0x501
setflag 0x502
clearflag 0x503
setflag 0x504
setflag 0x505
setflag 0x506
end

#org @5
setflag 0x500
setflag 0x501
setflag 0x502
setflag 0x503
clearflag 0x504
setflag 0x505
setflag 0x506
end

#org @6
setflag 0x500
setflag 0x501
setflag 0x502
setflag 0x503
setflag 0x504
clearflag 0x505
setflag 0x506
end

#org @7
setflag 0x500
setflag 0x501
setflag 0x502
setflag 0x503
setflag 0x504
setflag 0x505
clearflag 0x506
end

copybyte 0x20370D0 0x3005542
compare LASTRESULT 0x(hora en hex)
if 0x1 goto @(pointer)

Lo que hace esto es copiar el byte de la ram que guarda la hora a otro byte de la ram vacío. De ese modo conseguimos guardarlo en LASTRESULT. Con el compare, comprobamos si es una determinada hora (en hex). Por último, si es esa hora, nos lleva a un pointer que queramos.

Yo he divido el día en 7 partes, cada una representada por una flag. De esta manera, en cada uno de los punteros se activan todas las flags excepto una que se desactiva. Esta flag que se desactiva es la que representa ese periodo del día. Todos los minis que tengamos con otras flags, se supone que aparecen en otro momento, entonces, al estar la flag activada, desaparece. Sólo aparecerán los minis con la flag que desactivamos.

Por supuesto, vosotros podéis partir más el día, o partirlo menos. Eso como queráis.

Si vais a utilizar el script tal como está, estas son las flags y las horas:

500 - 7:00 a 11:00
501 - 11:00 a 15:00
502 - 15:00 a 18:00
503 - 18:00 a 22:00
504 - 22:00 a 0:00
505 - 0:00 a 4:00
506 - 4:00 a 7:00


Por ejemplo, si le asignáis a un mini la flag 0x500, el mini aparecerá entre las 7:00 y las 11:00.

Ahora vamos a implementarlo. Lo único que tenemos que hacer es poner un script de nivel de tipo 05 en todos los mapas que lo necesitemos. En principio, sobra con ponerlo en todos los mapas de pueblos, ciudades y rutas. En las casas y eso no tiene por qué ser necesario, pero también lo podéis poner si queréis, depende de vuestras necesidades. Obviamente, no hace falta que lo compiléis un montón de veces, con compilarlo una vez y poner en todos los mapas el script con el mismo offset es suficiente.

Bueno, pues lo compilamos. Creamos el script de nivel tipo 05 en el mapa. Le asignamos el offset de nuestro script. Ahora guardamos y pulsamos ctrl+H para ver el cabezal en modo profesional. Vamos a "Map Script Offset" y copiamos el offset que nos da. Ahora vamos a XSE, ponemos el offset, marcamos la casilla de script de nivel (el último icono) y decompilamos. Ahora vemos si al principio del script hay algún "#raw 0xFFFF" y si lo hay, lo cambiamos a "#raw 0x0" y compilamos. Esto del "Map Script Offset" es porque a veces se produce ese error y no funcionan bien los scripts de nivel, así que se comprueban y, si todo está bien, hemos acabado.
#1
G0LD_ZTHVARD0X! 27515
Gracias javi gran tuto!!!!
Es curioso saber que en GBC ese sistema viene default, pudiendo configurar desde el editor de mapas la hora de aparicion y que texto mostrar segun la hora.

Este tuto lo usare para mi otro proyecto, sigue asi aportando!!!
#2
Foxz. 16646
Gran tuto Javi, aunque ya lo había implementado en mi hack, seguro que servirá a muchos users, es una manera de hacer el juego más dinámico y con una apariencia más realista.
#3
Tito Sayer301 26309
Gran tuto Javi, el realismo predomina si o si yiah makayinah! Ademas me gusta que el script de nivel sea de tipo 05 porque no lo he usado nunca y significa poder implementarlo en mi hack sin problemas cuando quiera. MUY PRO!

Solo tengo una duda:
Usas esto "copybyte 0x20370D0 0x3005542" para copiar el byte a LASTRESULT y así poder compararlo.
¿Se podría poner "copybyte 0x20370D0 LASTRESULT"?
#4
Javi4315♪ 13374
Iniciado por Sayer Conflow!
Gran tuto Javi, el realismo predomina si o si yiah makayinah! Ademas me gusta que el script de nivel sea de tipo 05 porque no lo he usado nunca y significa poder implementarlo en mi hack sin problemas cuando quiera. MUY PRO!

Solo tengo una duda:
Usas esto "copybyte 0x20370D0 0x3005542" para copiar el byte a LASTRESULT y así poder compararlo.
¿Se podría poner "copybyte 0x20370D0 LASTRESULT"?


El comando funciona al revés, es decir, primero va el offset donde se copiará el byte y después el offset donde se encuentra, es decir, el planteamiento hubiera sido "copybyte LASTRESULT 0x3005542". Y sí se puede hacer, pero no es lo correcto. En realidad no estás guardando el valor del byte en LASTRESULT directamente, sino que el byte se está copiando en la dirección de la ram que representa LASTRESULT, es decir, se guarda en el offset 0x800D, pero eso no quiere decir que se guarde directamente en la variable. Lo que pasa es que da igual dónde pongas el byte porque se va a guardar igualmente en LASTRESULT, pongas una dirección u otra. Lo único es que hay que tratar de hacerlo en una dirección que no cambie ningún dato del juego, es decir, que esté libre.
#5
Loony Boo♪ 12263
Gracias por el tutorial, seguro que a muchos les servirá. Sin embargo, si quisieras ahorrar flags y minis (en el caso del señor gordinflón), ¿no sería más fácil jugar con diversos valores en una variable y, en base al valor que marque, jugar con la posición y el comportamiento de los minis mediante movesprite, movesprite2 y spritebehave? También me consta que existen diversas formas de cambiar la apariencia de los minis, ¿por qué no preparar el script para hacer que ese mini desempeñe una cuantiosa suma de papeles en distintos eventos?

Te dejo esas ideas en el aire, por cierto, me encantó el punto sarcásticamente divertido en tu tutorial.
#6
Javi4315♪ 13374
Iniciado por Loony Boo♪
Gracias por el tutorial, seguro que a muchos les servirá. Sin embargo, si quisieras ahorrar flags y minis (en el caso del señor gordinflón), ¿no sería más fácil jugar con diversos valores en una variable y, en base al valor que marque, jugar con la posición y el comportamiento de los minis mediante movesprite, movesprite2 y spritebehave? También me consta que existen diversas formas de cambiar la apariencia de los minis, ¿por qué no preparar el script para hacer que ese mini desempeñe una cuantiosa suma de papeles en distintos eventos?

Te dejo esas ideas en el aire, por cierto, me encantó el punto sarcásticamente divertido en tu tutorial.


¿En serio quieres cambiar algo tan simple como poner un mini y asignarle la variable que te convenga por un sistema en el que lo tienes que llenar todo variables, comandos raros y muy seguramente tener un script distinto en cada mapa? Yo no lo veo. De todas formas, ni creo que sea necesario ahorrar espacio a la hora de poner más mini y ni mucho menos para ahorrar flags, son 7 de las 992 que puedes usar de forma totalmente segura.

Yo creo que no compensa liarse.
#7
Loony Boo♪ 12263
Iniciado por Javi4315♪
¿En serio quieres cambiar algo tan simple como poner un mini y asignarle la variable que te convenga por un sistema en el que lo tienes que llenar todo variables, comandos raros y muy seguramente tener un script distinto en cada mapa? Yo no lo veo. De todas formas, ni creo que sea necesario ahorrar espacio a la hora de poner más mini y ni mucho menos para ahorrar flags, son 7 de las 992 que puedes usar de forma totalmente segura.

Yo creo que no compensa liarse.


992 flags... si no contamos que muchas de ellas presentan anomalías, tales como estar permanentemente desactivadas o perpetuamente activadas, y en definitiva, supone todo un dolor de cabeza la programación de scripts y otros eventos relacionados empleando flags. Además, el script que propongo sólo presenta unos pocos comandos "raros", en total unos dos, que vienen bien explicados en la propia guía de comandos del XSE y que te muestran una gran serie de ventajas:



Y todo esto sólo programando dos o tres comandos en un script cuyos efectos dependerán del valor de una variable. ¿Que lleva un poco de más tiempo? Sí, pero te permite tener un mayor control, orden y elasticidad sobre tu trabajo (el orden también conlleva ahorro en el tiempo de comprobación, todo va en base a valores de variables, no necesitarás comprobar si funciona la flag X o la Y).
#8
Javi4315♪ 13374
Iniciado por Loony Boo♪
992 flags... si no contamos que muchas de ellas presentan anomalías, tales como estar permanentemente desactivadas o perpetuamente activadas, y en definitiva, supone todo un dolor de cabeza la programación de scripts y otros eventos relacionados empleando flags. Además, el script que propongo sólo presenta unos pocos comandos "raros", en total unos dos, que vienen bien explicados en la propia guía de comandos del XSE y que te muestran una gran serie de ventajas:

  • Una gran programación de múltiples eventos diferentes.
  • Aportar mucho más realismo a los mapeados.
  • Poder cambiar cualquier posición y cualquier comportamiento de los minis ante todo tipo de situaciones: cambio de estaciones, avance en la aventura, franjas horarias, eventos puntuales.


Y todo esto sólo programando dos o tres comandos en un script cuyos efectos dependerán del valor de una variable. ¿Que lleva un poco de más tiempo? Sí, pero te permite tener un mayor control, orden y elasticidad sobre tu trabajo (el orden también conlleva ahorro en el tiempo de comprobación, todo va en base a valores de variables, no necesitarás comprobar si funciona la flag X o la Y).


Venga vale.

Atención usuarios: El que quiera aplicar el sistema del que habla el manual, que siga el propio manual. El que quiera, sin embargo, hacerlo de una forma rápida y sencilla, que siga el método propuesto por Boo. Este fabuloso método no tiene ninguna complicación y además te ahorrarás la impactante cantidad de 7 flags, sí, has oído bien, ¡7 flags!

Y sí, si leyeras detenidamente habrías visto que he dicho "son 7 de las 992 que puedes usar de forma totalmente segura". Es decir, sin ningún tipo de "anomalía".

No sé qué te ha dado por intentar sabotear mis tutoriales. Pero si quieres hacerlo bien, no comentes diciendo que "sería mejor hacerlo así". Haz tú tutoriales, que para ser el mejor administrador que ha conocido WaH, no se te ve mucho movimiento.
#9
Loony Boo♪ 12263
Iniciado por Javi4315♪
No sé qué te ha dado por intentar sabotear mis tutoriales. Pero si quieres hacerlo bien, no comentes diciendo que "sería mejor hacerlo así". Haz tú tutoriales, que para ser el mejor administrador que ha conocido WaH, no se te ve mucho movimiento.


Sólo he comentado por aportar ideas, como aquella rutina para el sistema de banco, no he venido a dejar el típico mensaje que dice algo como "huy, buen tutorial, gracias" (para eso existe el botón "+Gracias" y acabamos antes), he leído a fondo el tutorial y he querido comentar qué ideas podrías agregar (o no). Si no te agradaron mis mensajes pues lo siento, pero no hace falta que mezcles campos ni que me ataques, he captado la idea, ten por seguro que no voy a volver a comentar en tus temas.

Ya está, no voy a decir nada más.
#10
eing 12479
enhorabuena por el tutorial [MENTION=16728]javi[/MENTION]4315, pero no entiendo porque haces esto todo el rato:
copybyte 0x20370D0 0x3005542
Con que lo copies una vez y lo compares continuamente, mejor. Por que si no no ahorras espacio.

De todas formas muy buen tutorial.