Use an absolute directory under /usr/share/games/ for game data
[kraptor.git] / src / premio.c
blob2b41ab06960aead0cb9d53f65d78c25cce21b75f
1 /*-------------------------------------------------------
2 premio.c
3 --------------------------------------------------------
4 Copyright (c) 2002, Kronoman
5 En memoria de mi querido padre
6 Enero - 2003
7 --------------------------------------------------------
8 Engine de premios
9 usando una lista enlazada muy sencilla
10 --------------------------------------------------------*/
12 #ifndef PREMIO_C
13 #define PREMIO_C
15 #include <stdio.h>
16 #include <allegro.h>
18 #include "jugador.h"
19 #include "premio.h"
20 #include "azar.h"
21 #include "pmask.h"
22 #include "combo.h" // para las particulas
23 #include "global.h" // para chequear el nivel de detalle
24 #include "jugador.h" // para poder darle los premios
25 #include "sonido.h"
27 /* globales exportadas */
28 PREMIO_CLASS premio_class[MAX_PREMIO_CLASS];
30 /* --- globales internas --- */
31 static PREMIO *prt_1er_premio = NULL; /* puntero al comienzo de la lista */
33 /* Esta funcion agrega un nuevo premio
34 Devuelve puntero al creado.
35 Si vida <= 0, NO se crea...
36 Pasarle el indice de la clase de premio a crear y su posicion
37 La direccion es elegida al azar... :)
39 PREMIO *agrega_premio(int premio, fixed x, fixed y)
41 PREMIO *nueva = NULL;
42 if (premio < 0 || premio > MAX_PREMIO_CLASS-1) return NULL; /* fuera de rango */
43 if (premio_class[premio].vida <= 0) return NULL; /* ni pierdo el tiempo... */
46 nueva = (PREMIO *)malloc(sizeof(PREMIO));
47 nueva->next = prt_1er_premio;
48 prt_1er_premio = nueva;
50 if (nueva != NULL) /* si el malloc funciono, seteo los datos... */
52 nueva->x = x;
53 nueva->y = y;
54 nueva->r = itofix(rand()%256);
55 nueva->dx = ftofix((float)rand_ex(-500, 500) / 100.0);
56 nueva->dy = ftofix((float)rand_ex(-500, 500) / 100.0);
57 nueva->dr = ftofix((float)rand_ex(-160, 160) / 10.0);
58 nueva->vida = premio_class[premio].vida;
59 nueva->clase = premio;
62 return nueva;
66 Esta funcion actualiza la logica (mueve) los premios
67 tambien los elimina si vida < 0 o si estan fuera de pantalla
68 Pasar en x, y la posicion de scroll en pantalla
69 en w, h el ancho y alto de la pantalla
70 Comprueba si toca al jugador, para darle el premio tambien...
72 void mover_premio(int x, int y, int w, int h)
74 // int i;
75 PREMIO **tmp_p = &prt_1er_premio;
76 PREMIO *tmp = NULL;
78 while (*tmp_p) {
80 tmp = *tmp_p;
81 tmp->x = fixadd(tmp->x, tmp->dx);
82 tmp->y = fixadd(tmp->y, tmp->dy);
83 tmp->r = fixadd(tmp->r, tmp->dr); // rotar
85 /* debug: comprobar si toco al jugador; bounding box pedorro */
86 if (check_bb_collision_general(fixtoi(tmp->x),fixtoi(tmp->y),
87 premio_class[tmp->clase].sprite->w,
88 premio_class[tmp->clase].sprite->h,
89 fixtoi(jugador.x),fixtoi(jugador.y),
90 jugador.spr[1]->w ,jugador.spr[1]->h) != 0)
92 /* toco al jugador, dar premio! */
94 switch (premio_class[tmp->clase].premiar)
96 case -2: // bombas
97 jugador.bombas += premio_class[tmp->clase].cantidad;
99 if (jugador.bombas > jugador.max_bombas)
100 jugador.bombas = jugador.max_bombas;
102 break;
104 case -1: // energia
105 jugador.vida += premio_class[tmp->clase].cantidad;
106 if (jugador.vida >= MAX_ENERGIA) jugador.vida = MAX_ENERGIA;
107 break;
109 default: // arma
110 jugador.arma[premio_class[tmp->clase].premiar] += premio_class[tmp->clase].cantidad;
112 if (jugador.arma[premio_class[tmp->clase].premiar] > arma_tipo[premio_class[tmp->clase].premiar].cant_ammo_max)
113 jugador.arma[premio_class[tmp->clase].premiar] = arma_tipo[premio_class[tmp->clase].premiar].cant_ammo_max;
115 // seleccionar el arma - DEBUG, no se si es lo mejor...
116 jugador.arma_actual = premio_class[tmp->clase].premiar;
117 break;
120 // tocar el sonido!!
121 if (premio_class[tmp->clase].sonido != NULL)
122 tocar_sonido(premio_class[tmp->clase].sonido, 255, 128, 1000);
124 tmp->vida = 0;
128 tmp->vida--;
130 /* verificar si estan fuera de pantalla y hacerlos rebotar */
132 if (tmp->y < itofix(y))
134 tmp->y = itofix(y);
135 tmp->dy = fixmul(tmp->dy, itofix(-1));
137 if (tmp->x < itofix(x))
139 tmp->x = itofix(x);
140 tmp->dx = fixmul(tmp->dx, itofix(-1));
143 if (tmp->x > itofix(x + w - premio_class[tmp->clase].sprite->w))
145 tmp->x = itofix(x + w - premio_class[tmp->clase].sprite->w);
146 tmp->dx = fixmul(tmp->dx, itofix(-1));
149 if (tmp->y > itofix(y + h - premio_class[tmp->clase].sprite->h))
151 tmp->y = itofix(y + h - premio_class[tmp->clase].sprite->h);
152 tmp->dy = fixmul(tmp->dy, itofix(-1));
155 if (tmp->vida < 0) {
156 /* murio, eliminar!!! */
158 /* explotan con algunas particulas */
159 if (nivel_detalle > 7)
160 poner_muchas_particulas( fixtoi(tmp->x), fixtoi(tmp->y),
161 5,5,
163 -1, 1, 1,
164 NULL,
165 rand()%10+30 );
168 *tmp_p = tmp->next;
170 free(tmp);
172 } else {
173 tmp_p = &tmp->next; /* siguiente por favor! */
178 /* Esta funcion se debe llamar cuando no se precise
179 mas la lista de premios
180 Libera la RAM usada y reinicia la lista
182 void liberar_premio()
184 PREMIO *tmp = prt_1er_premio;
185 prt_1er_premio = NULL;
187 while (tmp) {
188 PREMIO *next = tmp->next;
189 free(tmp);
190 tmp = next;
195 Esta funcion dibuja los premios en el bitmap bmp
196 Las dibuja desplazado x,y
198 void dibujar_premio(BITMAP *bmp, int x, int y)
200 PREMIO *tmp = prt_1er_premio;
202 while (tmp) {
203 /* dibujar */
204 if (premio_class[tmp->clase].sprite != NULL)
205 rotate_sprite(bmp, premio_class[tmp->clase].sprite, fixtoi(tmp->x)-x, fixtoi(tmp->y)-y, tmp->r);
206 else
207 circlefill(bmp, fixtoi(tmp->x)-x, fixtoi(tmp->y)-y, 5, makecol(255,255,255));
209 tmp = tmp->next; /* proximo... */
213 #endif