Hola a todos. Hoy os vengo con un problema cuya resolución se me escapa:
Como muchos sabréis (o deberíais saber) en Abril empecé a hacer un motor RPG por turnos. Ahora estoy con el combate. Mi idea para asignar los turnos es la siguiente:
Cada personaje tiene una iniciativa X que sirve para simular que el personaje y/o enemigo tiene que recargar fuerzas para otro ataque. Lo que voy a hacer es un motor de estados que tenga un estado que sea recargando. este recargando, lo que hará será esperar hasta que el pj/npc esté listo. en ese momento, se inscribirá en una lista y, cuando le toque turno, elegirá la acción a realizar y comenzará a recargar de nuevo. Como la cola de espera de la carnicería.
Para ello he pensado hacerlo con memoria dinámica. Al fin y al cabo, no se cuánta gente habrá en un combate. Y me parece más limpio reservar estructuras de [[id del que le toca],[id del siguiente]] o por el estilo que reservar siempre una tabla de 90 celdas de las cuales igual en un combate uso 2 y en otro 80.
¿Alguien sabe cómo podría hacerlo?
Edit: Vale, esta edición es para aclarar que ya lo he conseguido. El comando alloc es totalmente distinto al new de C++. En serio, hay que pensar distinto.
He hecho lo siguiente:
1º En el fichero globales tengo:
/* Tupla que define un elemento de una lista dinámica */
type _lista
int valor; /* Valor */
_lista* anterior; /* Elemento anterior */
end
global
/* Motor de combate */
_lista* enemigos, turno; //Creo una lista
end
2º En el fichero de las batallas por el momento tengo lo siguiente:
/*
Este archivo contiene las funciones generales del sistema de combates
*/
function iniciar_batalla() /* Esta función inicia el sistema */
private
int i,j;
_lista* actual; /* Guarda el elemento en el que nos situamos */
int cancion_actual; /* Canción que estaba sonando */
end
begin
/* Congelamos todos los procesos */
signal(type gameobject,s_freeze_tree);
signal(personajeid,s_freeze_tree);
/* Almacenamos la canción que sonaba y cambiamos */
cancion_actual=sonando;
sonando=-1;
/* Hacemos un fundido a negro */
fade(0,0,0,120);
while(fading)
frame;
end
/* Llamamos a los enemigos */
i=40; /* Coordenada x del enemigo */
j=modo_y/2; /* Coordenada y del enemigo */
actual=enemigos; /* Recojemos el primer enemigo */
while(actual != NULL)
enemigo(actual.valor,i,j); /* "Instanciamos" el enemigo */
actual=actual.anterior; /* Pasamos al siguiente enemigo */
i+=270; /* Pasamos a la siguiente "celda" del campo de batalla */
if(i>1260) /* Si hemos terminado la fila */
i=40; /* Volvemos al inicio de la fila */
j-=300; /* y nos vamos a la fila superior */
end
end
/* Llamamos a los personajes */
/* Llamamos al gestor de turnos */
/* Preparamos el entorno */
x=modo_x/2;
y=modo_y/2;
z=99;
file=fpgs[1];
graph=200;
/* Fundido desde negro */
cambiar_tono_pantalla(0,0,0,0);
fade(100,100,100,30);
while(fading)
frame;
end
repeat
frame;
until(key(_enter));
/* Hacemos un fundido a negro */
fade(0,0,0,30);
while(fading)
frame;
end
/* Retomamos la canción */
sonando=cancion_actual;
/* Fundido desde negro */
cambiar_tono_pantalla(0,0,0,0);
fade(100,100,100,30);
while(fading)
frame;
end
/* Levantamos los procesos */
signal(type gameobject,s_wakeup_tree);
signal(personajeid,s_wakeup_tree);
end
function cargar_enemigo(int tipo) /* Esta función carga un enemigo en el sistema */
private
_lista* nuevo; /* Guarda el puntero al nuevo elemento que vamos a añadir */
end
begin
nuevo=alloc(sizeof(_lista));/* Reservo la memoria */
nuevo.valor=tipo; /* Asigno el tipo de enemigo que es */
nuevo.anterior=enemigos; /* Asigno el puntero para que apunte al último elemento añadido */
enemigos=nuevo; /* Reasigno el puntero global para que apunte al nuevo */
end
/*
Procesos de los elementos de batalla (enemigos, pj's, etc...)
*/
process enemigo(int id_obj,int x, int y)
private
string nombre;
int pv,iniciativa;
end
begin
z=(modo_y-y)/100;
file=fpgs[6];
graph=buscar("graf",13);
nombre=buscar("nombre",13);
pv=buscar("pv",13);
iniciativa=buscar("iniciativa",13);
repeat
frame;
until(key(_enter));
end
Ahora tengo que hacer la función que descargue las colas de enemigos y turnos.
A mi también me pasó. Acostumbrado al NEW y a ciertas librerías que nos daban hechas para la facultad, usar alloc es raro...
Pero años más tarde te enteras de que es así como se hacía en C, y de que tiene incluso más ventajas, como que puedes usar alloc para reservar 300 BYTES, y tienes un array de tipo byte, que puedes agrandar y reducir cuando quieras, y que en Bennu, si es un INT* pues es un array de INTS, y a las malas hasta del tipo que tu le definas, siempre que no haya otro tipo de datos dinámicos (como Strings)... aunque para esos casos es mejor seguir con las puñeteras listas enlazadas, así te aseguras que están en partes diferentes de la memoria, y que el sistema se va a encargar de que no se pisen los datos de cada nodo si aumentan de tamaño.
Son cosillas que, si sabes cómo funciona la memoria de un ordenador, o la organización de la misma de un SO, pues ayudan mucho a sacar truquillos o a optimizar el programa (aunque al nivel en que nos movemos, es casi irrelevante en este caso).