lo terminé. se me complejizó un poco el sistema de diálogos (ahora llevo un contador de caracteres de la línea filtrada y otro de la línea original. aunque si lo pienso dos veces, hacer eso con el sistema anterior hubiese sido un infierno) pero funciona y funciona bien. | detiene la línea hasta que el jugador presione el botón de hablar y @ detiene la linea por 10 ciclos. @@ lo hace por 20, @@@ por treinta y así.
lo que más me preocupa en éste momento es que para filtrar la línea tuve que llamar funciones dentro de funciones. game maker no tiene una función para reemplazar una lista de caracteres, sólo un caracter por llamada de función. esto es terrible, porque si quiero agregar más marcadores voy a tener que llamar otra función que llame a la misma función que ya llama a la misma función. de todos modos dudo que incluya otro marcador.
lo siguiente es volver a programar el sistema de tipos de líneas y sus correspondientes tipos. voy a empezar con las líneas que entregan objetos con la posibilidad de un trigger global para evitar que te entreguen objetos cada vez que la línea sea ejecutada. como ahora tengo una forma que primero filtra la línea y luego la pasa al string que dibuja la línea caracter por caracter, yo creo que la solución más sensata es usar un switch en la parte que filtra la línea, para que la línea que le pase al string que contiene la línea dibujada se decida ahí, algo así:
switch (tipo de linea){
case 0:
líneas normales
break;
case 1:
si el trigger ya está activado{
"has obtenido un"+nombre del objeto
}
break;
así sucesivamente...
}
se me ocurre que esto se va a poner complicado cuando quiera hacer un tipo de líneas que sólo sean visibles cuando el trigger asociado al objeto esté activado, y voy a tener que modificar el case 0 para que, si el trigger está activado y el objeto tiene la variable de dialogos alternativos activada, use esos diálogos en lugar de los otros. no suena tan complicado, pero eso significa que van a tener que haber dos variables independientes que guarden la cantida de líneas de código, para evitar que haya una restricción que diga que los diálogos alternativos tienen que ser la misma cantidad de los normales, ni uno más ni uno menos. cuando haga eso, probablemente en vez de modificar el case 0 tenga que hacer switches completamente diferentes para dialogos normales y dialogos alternativos. no es tan sencillo como suena.
ahora que lo pienso, puedo ocupar un arreglo unidimensional para la cantidad de líneas, entonces en vez de hacer dos veces el código que implique leer la cantidad de líneas del actor con diálogo, lo hago sólo una vez en un formato variable[trigger asociado al objeto], entonces cuando el trigger esté activado, va a devolver 1 y va a leer el valor del índice 1 en lugar del índice 0 y todo será más sencillo. para recoger el trigger asociado al objeto lo hago del mismo modo en que recojo el resto de las variables.
pero por ahora, lo importante es que tengo el sistema de marcadores de los diálogos funcionando, lo que es importantísimo para darle ritmo a los diálogos y al juego en general.
edit: acabo de terminar el sistema de tipos de texto, tengo diálogos alternativos y una función para definir líneas de texto que dan items. hurra por mi.
y aprendí a hacer anillos de humo con la boca. hip hip.
edit: me di de narices con un problema: quise implementar diferentes velocidades para el diálogo, y me di cuenta que si la cantidad de caracteres por ciclo que dibuja es superior a 1, a veces se salta caracteres, lo que significa que también se salta los efectos de éstas.
se me acaba de ocurrir que la mejor forma de arreglarlo es que la variable dialog_last_char recoja una string con la cantidad de caracteres que está dibujando al mismo tiempo, entonces si dialog_last char contiene, por ejemplo "e|", funcione igual que si devolviese "|" filtrando la variable buscando coincidencias en el switch.
edit: mala idea. el no tener una función para reemplazar más de un tipo de caracter por llamada me juega en contra, y tener que sacarle todas las posibilidades posibles a una string es ridiculo: me deja con algo así como funcion(funcion(funcion(linea,caracter),caracter),caracter); y eso es francamente ilegible y ridículo, además de volverse inmanejable para líneas de tres o más caracteres de largo. imaginense se de el caso "letramarcadorletra", la funcion que uso para quitar las letras me devolvería "letraletra" y dado que no hay ninguna instancia de "letraletra" en mi string el código no quitaría nada y la función que cumple el marcador sería omitida. es demasiado aleatorio. si tan solo hubiese una funcion que devolviese en forma de string las instancias de caracter encontradas...
...por lo que se me ocurre que tendré que programarla yo mismo. va a ser algo así:
return (string_repeat(string(argument0),string_count(string(argument1),string(argument0))));
¿qué haría ésta función? devolver "@@" en caso de "@e@" con argument0 "@e@" y argument1 "@", así puedo darle tiempo de 20 ciclos cuando la línea tenga más de un @ por línea, además de reconocer "|" y cualquier caracter que se me venga en gana.
esto conlleva un cambio que a su vez conlleva un problema. el cambio es que tendré que cambiar el switch por instancias de if/else, y el problema se da cuando en una misma instancia se junten más de dos marcadores. como por ahora tengo dos, no hay problemas, pero si eventualmente incluyo más (algunos para tocar sonidos, por ejemplo) si podría ser un poco problemático, pues agarraría en el mismo ciclo -creo- ambas órdenes. no es problemático si son sonidos, pero ¿qué pasa si se me juntan | y @, por ejemplo? la solución más simple es hacer excepciones. en el condicional que detecte @, que también detecte que no hayan | en el string, así si @ y | se juntan, @ queda inútil. de todos modos, esto es lógico, porque nadie en su sano juicio junta un marcador para detener el texto y uno para pausarlo temporalmente. supongo que nadie nunca lo hará en ningún momento, pero necesito programar la instancia en caso de que el motor caiga en manos torpes y desquiciadas y escriba líneas como "||@|#@|||@|#|@@|||d.@@|@" y le asigne un valor de 50 a la variable de cantidad de caracteres dibujados por ciclo.
también estaba pensando que tengo que programar una función que le de un "tipo de voz" a cada personaje. algo sencillo, un switch que según el valor real dado a arg0 le asigne el índice de un sonido predefinido en la función misma a una variable que va a ser la que lea el sistema de diálogos para llamar al sonido, y poner una condición en la función de líneas que le asigne un valor predeterminado si la variable no está definida, para evitar que haya que llamar a esa función siempre.
todas estas cosas, de cualquier modo, las haré con algo más de paz mental. ahora debo descansar. o trabajar en otra cosa. como sea, debo despejarme un poco. debo estar loco, me despejo de un trabajo haciendo otro.
edit:estaba leyendo lo que escribí y escribí una estupidez. básicamente, si me cambio a condiciones if/else, puedo hacer algo así como:
if string_count(marcador,linea)>0{
ejecutar código correspondiente al marcador acá;
}
y usar la misma función para contar la cantidad de veces que sale el caracter en la línea para asignarle valores que se sumen en caso de que el marcador lo permita o para detectar que el marcador esté o no presente en la línea.
también estaba pensando que si programo esa función puedo conservar el switch, aunque eso sería más arriesgado. básicamente, sería agregar más de una condición para cada estado del switch, sin embargo además de engorroso esto sería limitado y arriesgado. no lo haré por sanidad mental, pero se puede.
edit: arreglado :D. gracias, gracias, no es necesario aplaudir.