Ok, el error ocurre porque en los rooms que no tienen objetos Temp_Array nunca se vuelve un array, se puede arreglar declarando Temp_Array como un un array con un elemento vacío desde el inicio.

[gml]var Length = array_length_1d(obj_inventario_room.inv),
    String = "",
    Temp_Array[0] = "",
    c = 0;[/gml]
   
El comando inventario deja de funcionar porque el else de mirar lo esta sobrescribiendo, has que mirar también sea un else de inventario o cámbialo todo a un switch.

Y si, como te dije, las funciones array_push, array_delete y array_find no existen en GMS 1, tienes que crear scripts con los códigos que te pase y darles esos nombres.

#16 Marzo 30, 2022, 09:23:53 PM Ultima modificación: Marzo 30, 2022, 11:01:23 PM por JohnW
Creo que la estoy liando...

Aver primero de todo he declarado la variable en mi objeto control principal del inicio del jueto:
[gml]Temp_Array[0] = "";[/gml]
He intentado convertir el inputbox con switch como me dijiste pero me tira error y ahora no me deja ni escribir se borra todo lo que escribo, no se si lo hize mal:
[gml]if keyboard_check_pressed(vk_enter){
    Unlock = keyboard_string;
    switch (Unlock){
        case 1: if (Unlock) == "inventario"{
                    String = "Tengo " + mirarinventariopj()}; break;
        case 2: if (Unlock) == "mirar"{
                    String = "Veo " + mirarinventarioroom()}; break;
}keyboard_string = "";}else{
String = ">No comprendo";}
draw_text(550,900,String)[/gml]

Los scripts me daba error en esas lineas pero ya arregle lo de los scripts que no me los detectaba y me tiraba error.... reiniciando el programa se arreglo.
Falta arreglar el switch del inputbox.

Siento molestarte tanto... pero ahora mismo estoy muy liado con todos estos cambios y estoy muy perdido.

Muchas gracias por toda la ayuda que me estas ofreciendo.

Temp_Array se declara en el script, no en el objeto, deberia quedar así:

[gml]var Length = array_length_1d(obj_inventario_room.inv),
    String = "",
    Temp_Array[0]="",
    c = 0;

for (var i=0;i<Length;++i){
    if is_string(obj_inventario_room.inv) && obj_inventario_room.inv!="" {
        Temp_Array[c] = obj_inventario_room.inv;
        c++;
    }
}

Length = array_length_1d(Temp_Array);
for(var i = 0; i < Length; ++i){
    String += Temp_Array;
    if i == Length-2 String += " y ";
    else if i < Length-2 String += ", ";
}
return String;[/gml]

La estructura del switch es incorecta, los casos no se definen por numero, sino por el valor que quieres comparar, y los else son exclusivos para if, no puedes usarlos despues de un switch, la versión de else para switch es default, y se utiliza dentro del switch. Aparte en tu código colocaste ese else despues del if para vk_enter, asi que esta constantemente sobrescribiendo el texto a dibujar. Deberia quedar así:

[gml]if keyboard_check_pressed(vk_enter){
    Unlock = keyboard_string;
    switch (Unlock){
        case ("inventario"): String = "Tengo " + mirarinventariopj(); break;
        case ("mirar"): String = "Veo " + mirarinventarioroom(); break;
      default: String = ">No Comprendo"; break;
   }
   keyboard_string = "";
}
draw_text(550,900,String);[/gml]

Finalmente, array_push, array_find y array_delete aparecen como error justamente porque no se han creado scripts con esos nombres.

Crea un script nuevo, nombralo array_push y en su interior pega este código:

[gml]///array_push(array,value)
argument0[array_length_1d(argument0)] = argument1;
return argument0;[/gml]

Crea otro script, nombralo array_delete y en su interior pega este código:

[gml]///array_delete(array,index,number)
var temp_array,
    Length = array_length_1d(argument0)
    c = 0;
for (var i = 0; i<Length;++i){
    if i<argument1 && i > argument1+argument2-1
    temp_array[c] = temp_array;
    c++;
}
return temp_array;[/gml]

Por ultimo, crea otro script, nombralo array_find y en su interior pega este código:

[gml]///array_find(array,value)
var Length = array_length_1d(argument0);
for(var i=0;i<Length;++i){
    if argument0 == argument1 return i;
}
return -1;[/gml]

#18 Marzo 30, 2022, 11:25:16 PM Ultima modificación: Marzo 30, 2022, 11:40:04 PM por JohnW
Lo de los scripts ya lo arregle, me daba error aun creando los scripts pero guarde todo, y reinicie el programa... aveces me pasa no se porque... sera que tengo algo corrupto en la instalacion que a veces me falla.

El codigo del Temp_Array me da error de escritura la linea.

Unexpected symbol in expression. Como si estuviera mal definida


Los codigos para coger y dejar objetos que me pusiste... los copio en un script y luego en el inputbox los llamo asi?
[gml]case ("coge linterna"):cogeobjeto(); break;
case ("deja linterna"):dejaobjeto(); break;[/gml]

Porque de esa forma me da error:
Function "array_find" expects 2 arguments, 1 provided

El segundo error que te da es porque olvide poner el array en uno de los array_find, simplemente agrégalo como primer argumento.

Y los casos para coje y deja no van a funcionar así, los códigos que deje para coger y dejar eran ejemplos, debes adaptarlos a tus necesidades, específicamente, en el ejemplo uso la cadena "nombre del item" como remplazo para el item que afectar y si tus scripts cogeobjeto y dejaobjeto no toman argumentos no van a saber que con que item están trabajando.

#20 Marzo 31, 2022, 12:11:28 AM Ultima modificación: Marzo 31, 2022, 01:42:16 AM por JohnW
Entonces para que funcione los comandos "coger objeto" y "dejar objeto" he de copiar los scripts de coger y tantas veces como objetos tenga sustituyendo en cada copia el "nombre del item" por el nombre del objeto, no?

Por ejemplo para coger linterna:
[gml]var Pos = array_find(global.invpj,"")
if  Pos != -1 {
obj_inventario_room.inv = array_delete(obj_inventario_room.inv,array_find("Linterna"),1)
global.invpj[Pos] = "Linterna"
String = "Cojo " + "Linterna"
}
else String = "No tengo espacio para coger " + "Linterna"[/gml]
Y ahora justo debajo copio todo ese codigo pero con otro item... asi con todos, y con el script de dejar items lo mismo no?

El error que me daba era que faltaba un "1" al lado de linterna xq pedia 2 argumentos y le estabamos dando 1 quedando asi:
[gml]var Pos = array_find(global.invpj,"")
if  Pos != -1 {
obj_inventario_room.inv = array_delete(obj_inventario_room.inv,array_find("linterna",1),1)
global.invpj[Pos] = "linterna"
String = "Cojo " + "linterna"
}
else String = "No tengo espacio para coger " + "linterna"[/gml]

Ahora me da error al coger un objeto me da error en array_delete:
[gml]Push :: Execution Error - Variable Get -7.temp_array(100008, -2147483648)
at gml_Script_array_delete (line 9) - return temp_array;
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_array_delete (line 9)
called from - gml_Script_cogeobjeto (line 3) - obj_inventario_room.inv = array_delete(obj_inventario_room.inv,array_find("linterna",1),1)
called from - gml_Object_inputBox_DrawEvent_1 (line 10) -         case ("coge linterna"):cogeobjeto(); break;
[/gml]
De momento para que no me diera error he comentado la linea: return del array_delete:
[gml]//return temp_array;[/gml]
con eso no me da error pero supongo que evitar eso me causara problemas futuros.

He intentado copiar los scripts de dejar y coger uno debajo de otro con diferentes items... pero no funciona...

Y he localizado otro fallo... cuando estoy en una room donde hay mas de 1 objeto... por ejemplo room 4 hay linterna y pedernal... si le dijo coge linterna... desaparece la linterna y el pedernal de la room. No se queda el pedernal.

Resumido:
Fallos:
el return temp_array que de momento lo he dejado comentado.
en una room con mas de 1 objeto, coge el primero y los demas que hay en la room los borra.
Al copiar los scripts de coger y dejar uno debajo de otro con mas objetos. No funciona.
Al escribir el comando inventario, con el inventario del PJ vacio salta este error:
[gml]Push :: Execution Error - Variable Get -7.Temp_Array(100005, -2147483648)
at gml_Script_mirarinventariopj (line 13) - Length = array_length_1d(Temp_Array);
[/gml]

Cita de: JohnW en Marzo 31, 2022, 12:11:28 AM
Entonces para que funcione los comandos "coger objeto" y "dejar objeto" he de copiar los scripts de coger y tantas veces como objetos tenga sustituyendo en cada copia el "nombre del item" por el nombre del objeto, no?
No crees un código adicional por item, en su lugar usa un solo script al que se le pueda pasar el nombre del item como argumento.

Cita de: JohnW en Marzo 31, 2022, 12:11:28 AM
El error que me daba era que faltaba un "1" al lado de linterna xq pedia 2 argumentos y le estabamos dando 1 quedando asi:

No, como te dije, lo que le falta es el nombre del array, obj_inventario_room.inv. No pongas argumentos al azar, solo porque deja de tirar error no significa que esta funcionando. Si tienes que adivinar un argumento estudia el código primero para al menos tener alguna idea de lo que pide.

Cita de: JohnW en Marzo 31, 2022, 12:11:28 AM
Ahora me da error al coger un objeto me da error en array_delete:
[gml]Push :: Execution Error - Variable Get -7.temp_array(100008, -2147483648)
at gml_Script_array_delete (line 9) - return temp_array;
[/gml]

El error que te da con array_delete es el mismo de antes, temp_array debe ser inicializado como un array con una cadena vacía, el problema fue que no anticipe que pasaría con arrays que tienen solo un elemento.

Cita de: JohnW en Marzo 31, 2022, 12:11:28 AM
Y he localizado otro fallo... cuando estoy en una room donde hay mas de 1 objeto... por ejemplo room 4 hay linterna y pedernal... si le dijo coge linterna... desaparece la linterna y el pedernal de la room. No se queda el pedernal.
Sin ver el código me imagino que el problema es que, como dijiste al principio, incluiste más código para el resto de los items en el mismo script, y sin nada que lo detenga el código sigue corriendo para todos los items que encuentre en el room.

#22 Marzo 31, 2022, 04:42:04 PM Ultima modificación: Marzo 31, 2022, 04:45:05 PM por JohnW
Cita de: Void en Marzo 31, 2022, 02:39:29 AM
No crees un código adicional por item, en su lugar usa un solo script al que se le pueda pasar el nombre del item como argumento.
No se hacer esto, he intentado hacer un script con switch agregando en cada case un objeto y luego pasarle ese script al codigo de coger y dejar objetos pero no me aclaro.
CitarNo, como te dije, lo que le falta es el nombre del array, obj_inventario_room.inv. No pongas argumentos al azar, solo porque deja de tirar error no significa que esta funcionando. Si tienes que adivinar un argumento estudia el código primero para al menos tener alguna idea de lo que pide.
No se a que te refieres con el array del obj_inventario_room.inv porque ya esta puesto eso.
[gml]var Pos = array_find(global.invpj,"")
if  Pos != -1 {
obj_inventario_room.inv = array_delete(obj_inventario_room.inv,array_find("linterna"),0,1)
global.invpj[Pos] = "linterna"
String = "Cojo " + "linterna"
}
else String = "No tengo espacio para coger " + "linterna"[/gml]

CitarEl error que te da con array_delete es el mismo de antes, temp_array debe ser inicializado como un array con una cadena vacía, el problema fue que no anticipe que pasaría con arrays que tienen solo un elemento.
En un script si me deja inicializar el temp_array como un array vacio pero en otros me da error de escritura y no me deja guardarlo con ese error.
Aporto imagen:
https://ibb.co/rbMQnF8
CitarSin ver el código me imagino que el problema es que, como dijiste al principio, incluiste más código para el resto de los items en el mismo script, y sin nada que lo detenga el código sigue corriendo para todos los items que encuentre en el room.
En el codigo del inputbox cada comando esta cerrado por un break con lo que deberia detenerse ahi.
[gml]if keyboard_check_pressed(vk_enter){
    Unlock = keyboard_string;
    switch (Unlock){
        case ("inventario"): String = "Tengo " + mirarinventariopj(); break;
        case ("mirar"): String = "Veo " + mirarinventarioroom(); break;
        case ("coge linterna"):cogeobjeto(); break;
        case ("deja linterna"):dejaobjeto(); break;
        default: String = ">No Comprendo"; break;
    }
    keyboard_string = "";
}
draw_text(550,900,String);[/gml]
Yo creo que el fallo de que me coja un objeto y los demas los borre de la room esta en este otro codigo:
[gml]var Pos = array_find(global.invpj,"")
if  Pos != -1 {
obj_inventario_room.inv = array_delete(obj_inventario_room.inv,array_find("linterna"),0,1)
global.invpj[Pos] = "linterna"
String = "Cojo " + "linterna"
}
else String = "No tengo espacio para coger " + "linterna"[/gml]

Cita de: JohnW en Marzo 31, 2022, 04:42:04 PM
No se a que te refieres con el array del obj_inventario_room.inv porque ya esta puesto eso.
El primer argumento de array_find deberia ser un array, en array_find("linterna") solo se le esta pasando una cadena, es ahí donde hay que agregar obj_inventario_room.inv como primer argumento. Deberia quedar así:

[gml]var Pos = array_find(global.invpj,"")
if  Pos != -1 {
obj_inventario_room.inv = array_delete(obj_inventario_room.inv,array_find(obj_inventario_room.inv,"linterna"),1)
global.invpj[Pos] = "linterna"
String = "Cojo " + "linterna"
}
else String = "No tengo espacio para coger " + "linterna"[/gml]

Cita de: JohnW en Marzo 31, 2022, 04:42:04 PM
No se hacer esto, he intentado hacer un script con switch agregando en cada case un objeto y luego pasarle ese script al codigo de coger y dejar objetos pero no me aclaro.

Para pasar datos a un script como argumento simplemente se cambia la parte del script que trabaja con ese dato por la variable argument correspondiente, existen argument0, argument1, argument2 hasta llegar a argument15, y reciben los datos según el orden que se pasan cuando se llama el script, el primer argumento sera argument0, el segundo sera argument1 y así.

Si queremos que a un script se le pueda pasar el nombre de objeto entonces cambiamos el código donde se trabaja con dicho nombre de objeto, en este caso quedaría así:

[gml]var Pos = array_find(global.invpj,"")
if  Pos != -1 {
obj_inventario_room.inv = array_delete(obj_inventario_room.inv,array_find(obj_inventario_room.inv,argument0),1)
global.invpj[Pos] = argument0
String = "Cojo " + argument0
}
else String = "No tengo espacio para coger " + argument0[/gml]

Como notaras, cada vez que el script decia "linterna" lo cambiamos a argument0

Para usar el script lo llamamos pasando el nombre del item, por ejemplo:

[gml]cogeobjeto("linterna")[/gml]

Cita de: JohnW en Marzo 31, 2022, 04:42:04 PM
En un script si me deja inicializar el temp_array como un array vacio pero en otros me da error de escritura y no me deja guardarlo con ese error.
Aporto imagen:
https://ibb.co/rbMQnF8
No declares temp_array como array dentro del area var, el GMS no lo acepta ahí. Para que quedemos claros en esto, la palabra clave var hace que las variables declaradas sean locales, es decir variables temporales que se borrarán despues de que termine el bloque de código. Se pueden declarar varias variables con un solo var si se separan con coma, y un punto y coma señala el final del area del var. Deja temp_array dentro del var y luego declaralo como array despues de su punto y coma.

[gml]var Length = array_length_1d(global.invpj),
    String = "",
    Temp_Array,
    c = 0;
   
Temp_Array[0]="";

for (var i=0;i<Length;++i){
    if is_string(global.invpj) && global.invpj!="" {
        Temp_Array[c] = global.invpj;
        c++;
    }
}

Length = array_length_1d(Temp_Array);
for(var i = 0; i < Length; ++i){
    String += Temp_Array;
    if i == Length-2 String += " y ";
    else if i < Length-2 String += ", ";
}
return String;[/gml]

Muchas gracias de nuevo amigo.

Entiendo que lo mismo que has hecho en este codigo:
[gml]var Pos = array_find(global.invpj,"")
if  Pos != -1 {
obj_inventario_room.inv = array_delete(obj_inventario_room.inv,array_find(obj_inventario_room.inv,argument0),1)
global.invpj[Pos] = argument0
String = "Cojo " + argument0
}
else String = "No tengo espacio para coger " + argument0[/gml]
Lo he de hacer igual en el "dejaobjeto" quedando asi:
[gml]var Pos = array_find(global.invpj,argument0)
if  Pos != -1 {
obj_inventario_room.inv = array_push(obj_inventario_room.inv,argument0)
global.invpj[Pos] = ""
String = "Dejo " + argument0
}
else String = "No tengo " + argument0;[/gml]

Ahora parece que no falla, pero sigo teniendo el error de que cuando estoy en una room con varios items... al coger 1 los demas los borra de la room.
¿Es posible que el fallo este aqui?
[gml]var temp_array,
    Length = array_length_1d(argument0)
    c = 0;
    temp_array[0]="";
for (var i = 0; i<Length;++i){
    if i<argument1 && i > argument1+argument2-1
    temp_array[c] = temp_array;
    c++;
}
return temp_array;[/gml]
Que le estemos diciendo argument1 y 2 y por eso coge 2 items?

Ok, ya veo porque ocurre el problema de que borre todos los items. Es en efecto un fallo en ese script, pero no tiene que ver con los argumentos.

El fallo esta en las condiciones, cuando escribí el script cometí un error con las condiciones dentro del for. El script debería crear un array nuevo con el contenido del viejo, saltándose las posiciones que se le indican, de esa manera "borra" esas posiciones, pero la condición que escribí es "si la posición actual es menor y mayor a las posiciones dadas" lo cual es imposible, por lo que siempre devuelve un array vacio, la condición debería haber sido "si la posición actual es menor O mayor a las posiciones dadas."

El script corregido quedaría así:

[gml]var temp_array,
    Length = array_length_1d(argument0)
    c = 0;
    temp_array[0]="";
for (var i = 0; i<Length;++i){
    if i < argument1 || i > argument1+argument2-1
    temp_array[c] = temp_array;
    c++;
}
return temp_array;[/gml]

Me habia fijado en eso y probe tambien poner los "||" y tambien probe de poner "or"... pero con esa modificacion me tira este error:

[gml]Push :: Execution Error - Variable Index [0,1] out of range [1,1] - -7.temp_array(100008,1)
at gml_Script_array_delete (line 7) -     temp_array[c] = temp_array;[/gml]

Tambien tengo un error al escribir el comando "coge (objeto)" en una room donde no hay objetos:
[gml]DoSet :: Invalid comparison type
at gml_Script_array_find (line 3) -     if argument0 == argument1 return i;[/gml]
Refiriendose al script array_find:
[gml]var Length = array_length_1d(argument0);
for(var i=0;i<Length;++i){
    if argument0 == argument1 return i;
}
return -1;[/gml]

Cita de: JohnW en Marzo 31, 2022, 09:52:47 PM
Me habia fijado en eso y probe tambien poner los "||" y tambien probe de poner "or"... pero con esa modificacion me tira este error:

[gml]Push :: Execution Error - Variable Index [0,1] out of range [1,1] - -7.temp_array(100008,1)
at gml_Script_array_delete (line 7) -     temp_array[c] = temp_array;[/gml]
Debo estar ciego, es otro error en el script que hasta ahora noto, temp_array se esta igualando a si mismo, cuando deberia ser a argument0:

[gml]var temp_array,
    Length = array_length_1d(argument0)
    c = 0;
    temp_array[0]="";
for (var i = 0; i<Length;++i){
    if i < argument1 || i > argument1+argument2-1
    temp_array[c] = argument0;
    c++;
}
return temp_array;
[/gml]
Cita de: JohnW en Marzo 31, 2022, 09:52:47 PM
Tambien tengo un error al escribir el comando "coge (objeto)" en una room donde no hay objetos:
[gml]DoSet :: Invalid comparison type
at gml_Script_array_find (line 3) -     if argument0 == argument1 return i;[/gml]

Ah, ese es un error de tipos, tambien error mio, no lo preevi, en el evento create del objeto obj_inventario_room cambia inv[0] = 0 por inv[0] = "".


El ciego soy yo... tranquilo... que a estas alturas estoy super perdido y tengo tanto codigo que no se ya ni que tocar... jeje

Ahora hay un fallo en el juego...

Si estas en una room donde no hay objetos... y escribes "coge (objeto)" lo coge y te dice que lo a cojido... aun no habiendo objetos en la room.

En las rooms donde no hay objetos puse este codigo en el creation code:
[gml]var Inst = instance_create(0,0,obj_inventario_room);[/gml]
Y en las rooms que si hay objetos puse este:
[gml]var Inst = instance_create(0,0,obj_inventario_room);
with Inst {
    inv[0] = "linterna";
    inv[1] = "pedernal";
}[/gml]

No entiendo muy bien el porque te coge un objeto de la room 4 estando en la 1

De hecho la respuesta a eso es simple, el script cogeobjeto inmediatamente asume que el objeto existe, no se le a agregado ningún chequeo para ver si el objeto efectivamente existe dentro del room:

[gml]var Pos = array_find(obj_invetario_room.inv,argument0);
if Pos == -1 {
   String = "No hay " + argument0 + " que pueda coger";
   exit;
}
Pos = array_find(global.invpj,"")
if  Pos != -1 {
   obj_inventario_room.inv = array_delete(obj_inventario_room.inv,array_find(argument0),0,1);
   global.invpj[Pos] = argument0;
   String = "Cojo " + argument0;
}
else String = "No tengo espacio para coger " + argument0;[/gml]

Con ese chequeo inicial si el objeto no existe dentro del array de obj_inventario_room pone una string apropiada y termina el código antes de ponerse a modificar el inventario del jugador.