1 // --------------------------------------------------------
3 // --------------------------------------------------------
4 // Copyright (c) Kronoman
5 // En memoria de mi querido padre
6 // --------------------------------------------------------
7 // Este modulo contiene todo lo relacionado con los enemigos
8 // Tal como movimiento, disparos, etc...
9 // --------------------------------------------------------
19 #include "jugador.h" /* lo preciso para poder verificar
20 los disparos contra el jugador... jeje */
31 ARMA_ENE arma_ene
[MAX_E_CLASS
]; /* armamento enemigo */
32 ENEM_T enem_t
[MAX_E_CLASS
]; /* tipos de enemigos */
33 ENEMIGO
*enemigo_1
= NULL
; /* puntero al 1er enemigo activo */
34 DISP_ENE
*disp_ene_1
= NULL
; /* puntero al 1er disparo activo */
36 /* esta variable NO es necesaria, solo la uso para
37 ver cuantos enemigos hay en memoria, y de esa manera,
38 revisar la performance... */
39 int cant_enemigos_debug
= 0;
41 /* Agrega un enemigo en x, y de tipo 'tipo' */
42 void agregar_enemigo(int x
, int y
, int tipo
)
44 ENEMIGO
*nueva
= malloc(sizeof(ENEMIGO
));
45 nueva
->next
= enemigo_1
;
48 if (nueva
!= NULL
) /* si el malloc funciono, seteo los datos... */
52 nueva
->vida
= enem_t
[tipo
].vida
; /* que corta es la vida de un piloto enemigo... */
53 nueva
->ene_t
= tipo
; /* que somos? yankis gallinas o pilotos de verdad? */
55 nueva
->bytecode_actual
= -1; // aun no ejecute nada, por eso -1
56 nueva
->bytecode_loop
= 0; // empezar con la 1era instruccion
58 nueva
->ia_node
= enem_t
[tipo
].ia_node
;
59 // debo comenzar la IA en un punto al azar?
60 if (enem_t
[tipo
].ia_azar
!= 0) nueva
->bytecode_actual
= rand_ex(-1, nueva
->ia_node
->size
-1);
62 // animaciones, etc...
63 nueva
->spr_actual
= rand()%4;
68 /* Esta funcion altera la IA del enemigo
69 llamar en cada ciclo...
71 void IA_enemigo(ENEMIGO
*ene
)
74 // interpretar bytecodes de la IA
75 if (ene
->ia_node
== NULL
) return; // no tiene IA, descerebrado...
76 if (ene
->ia_node
->size
< 1) return; // IA vacia, que paso?
78 ene
->bytecode_loop
--; // ejecute 1 instruccion
81 if (ene
->bytecode_loop
< 0)
83 // proxima instruccion
84 ene
->bytecode_actual
++;
85 if (ene
->bytecode_actual
> ene
->ia_node
->size
- 1) ene
->bytecode_actual
= 0;
86 if (ene
->bytecode_actual
> ene
->ia_node
->size
-1) return; // seguridad... :)
87 ene
->bytecode_loop
= ene
->ia_node
->code
[ene
->bytecode_actual
].loop
;
89 // copiar bytecode, solo campos importantes... el resto indeterminados... :)
90 ene
->bytecode_exe
.x1
= rand_ex(ene
->ia_node
->code
[ene
->bytecode_actual
].x1
, ene
->ia_node
->code
[ene
->bytecode_actual
].x2
);
91 ene
->bytecode_exe
.y1
= rand_ex(ene
->ia_node
->code
[ene
->bytecode_actual
].y1
, ene
->ia_node
->code
[ene
->bytecode_actual
].y2
);
96 if (ene
->bytecode_actual
> ene
->ia_node
->size
-1) return; // seguridad... :)
99 ene
->x
= fixadd(ene
->x
, itofix(ene
->bytecode_exe
.x1
));
100 ene
->y
= fixadd(ene
->y
, itofix(ene
->bytecode_exe
.y1
));
103 /* debo disparar ? */
104 if (ene
->ia_node
->code
[ene
->bytecode_actual
].weapon
> -1)
106 // cambio de arma del enemigo
107 ene
->arma_actual
= ene
->ia_node
->code
[ene
->bytecode_actual
].weapon
;
109 agregar_disparo_ene(ene
);
117 Esta funcion actualiza los enemigos
118 Verifica colisiones con disparos de jugador y con el jugador mismo
119 Precisa saber el desplazamiento del fondo, 'fy' ya que
120 cuando el enemigo sale de pantalla, se elimina...
122 void mover_enemigos(int fy
)
124 ENEMIGO
**tmp_p
= &enemigo_1
;
125 DISP_JUG
*tmpd
= NULL
;
128 cant_enemigos_debug
= 0; /* DEBUG: innecesario */
132 cant_enemigos_debug
++; /* DEBUG: innecesario */
135 /* hacer IA del enemigo */
138 // animacion del enemigo
140 if (tmp
->spr_delay
< 0)
142 tmp
->spr_delay
= enem_t
[tmp
->ene_t
].spr_delay
; // reiniciar contador
143 tmp
->spr_actual
++; // cambiar sprite
144 if (tmp
->spr_actual
> 3) tmp
->spr_actual
= 0;
148 /* verificar colisiones... */
150 /* colision contra el jugador? */
151 if (check_pmask_collision(enem_t
[tmp
->ene_t
].mask
[tmp
->spr_actual
], jugador
.mask
,
152 fixtoi(tmp
->x
), fixtoi(tmp
->y
),
153 fixtoi(jugador
.x
), fixtoi(jugador
.y
) ) != 0)
155 /* DEBUG: choco al jugador!, falta sonido! */
157 pone_explo_pixel(&ptr_explo_arriba
,
158 fixtoi(tmp
->x
)+rand()%enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
,
159 fixtoi(tmp
->y
)+rand()%enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->h
,
160 rand()%enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
+enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
/3,
164 jugador
.vida
-= enem_t
[tmp
->ene_t
].peso
+ rand()%5; /* restar energia al jugador */
165 tmp
->vida
-= rand()%5 + 5; /* restarme energia tambien */
169 recorrer disparos del jugador
170 DEBUG: esto es muy lento!! */
174 /* chequear colision, solo si el disparo esta activo,
175 de la manera hecha siguiente, si el disparo esta muerto,
176 evito comprobar la mascara, que tarda mas...*/
179 if (check_pmask_collision(enem_t
[tmp
->ene_t
].mask
[tmp
->spr_actual
], arma_tipo
[tmpd
->arma
].mask
,
180 fixtoi(tmp
->x
), fixtoi(tmp
->y
),
181 fixtoi(tmpd
->x
), fixtoi(tmpd
->y
) ) != 0 )
184 /* DEBUG: choco al disparo del jugador, restar energia, etc! */
185 poner_explosion_nave(fixtoi(tmpd
->x
),
187 rand()%20+20, rand()%10+5+arma_tipo
[tmpd
->arma
].punch
*2, 0);
189 /* DEBUG: sonido del arma
190 del jugador pegandole al enemigo */
191 tocar_sonido_paneado(fixtoi(tmpd
->x
),
192 arma_tipo
[tmpd
->arma
].snd
[1],
197 /* Esta comparacion es para NO pagarle mas de una vez al jugador
202 tmp
->vida
-= arma_tipo
[tmpd
->arma
].punch
; /* restar energia al enemigo */
204 /* DEBUG: mato al enemigo */
208 for (ttt
=0; ttt
< rand()%3 + enem_t
[tmp
->ene_t
].peso
/2+1; ttt
++)
210 pone_explo_pixel(&ptr_explo_arriba
,
211 fixtoi(tmp
->x
)+rand()%enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
,
212 fixtoi(tmp
->y
)+rand()%enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->h
,
213 rand()%enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
+enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
/3,
217 // Soltar premio, si lo hubiera... -DEBUG-
218 if ( (enem_t
[tmp
->ene_t
].premio_idx
> -1) && (rand()%100+1 < enem_t
[tmp
->ene_t
].premio_prob
) )
219 agrega_premio(enem_t
[tmp
->ene_t
].premio_idx
, tmp
->x
, tmp
->y
);
222 jugador
.dinero
+= enem_t
[tmp
->ene_t
].dinero
;
224 } /* fin de no pagar 2 veces */
226 tmpd
->vida
= -1; /* eliminar disparo, la memoria
227 se libera en jugador.c */
228 } /* fin chequear colision */
230 tmpd
= tmpd
->next
; /* siguiente */
232 } /* fin loop de verificar disparos */
234 /* Si esta activa la bomba especial, restar energia progresivamente */
235 if (bomba_esta_activa
&& tmp
->vida
> 0)
237 tmp
->vida
-= rand()%10+5;
240 jugador
.dinero
+= enem_t
[tmp
->ene_t
].dinero
; // pagar
241 tmp
->vida
= -1; // fuerzo que se 'combustione' completamente
245 /* Ir combustionando el enemigo cuando muere (energia <= 0) */
248 tmp
->vida
-= rand()%10+10;
251 /* Explosiones peque~as */
252 if (rand()%150 < abs((tmp
->vida
* 100) / ENE_MUERTO
) ) /* incremental al irse combustionando */
257 tocar_sonido_paneado(fixtoi(tmp
->x
),
258 explo_cache_snd
[rand()%3],
263 pone_explo_pixel(&ptr_explo_arriba
,
264 fixtoi(tmp
->x
)+rand()%enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
,
265 fixtoi(tmp
->y
)+rand()%enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->h
,
266 rand()%enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
+enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
/3,
270 /* Descontrolar enemigo */
271 // tmp->dx = (rand()%100 < 50) ? ftofix(MAX_VEL_E_X * (-1.0)) : ftofix(MAX_VEL_E_X);
272 // tmp->dy = (rand()%100 < 50) ? ftofix(MAX_VEL_E_Y * (-1.0)) : ftofix(MAX_VEL_E_Y);
275 /* al aproximarse al final, recontra-explotar... */
276 if (tmp
->vida
< (ENE_MUERTO
/ 10)*9 && nivel_detalle
> 4)
278 pone_explo_pixel(&ptr_explo_arriba
,
279 fixtoi(tmp
->x
)+enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
/2,
280 fixtoi(tmp
->y
)+enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->h
/2,
281 enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
+rand()%10,
285 /* PARTICULAS Y PEDAZOS DE NAVES AL MORIR... */
286 if (tmp
->vida
-10 <= ENE_MUERTO
)
287 poner_explosion_nave(fixtoi(tmp
->x
)+enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
/2,
288 fixtoi(tmp
->y
)+enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->h
/2,
292 } /* fin combustionar */
295 /* verificar limites de pantalla visible */
296 /* nota: la IA rebota en las X, queda cool. */
297 if (tmp
->x
< 0) { tmp
->x
= 0; tmp
->bytecode_exe
.x1
*= -1; }
299 if (fixtoi(tmp
->x
) > ANCHO_FB
- enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
)
301 tmp
->x
= itofix(ANCHO_FB
- enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->w
);
302 tmp
->bytecode_exe
.x1
*= -1;
305 if (fixtoi(tmp
->y
) < fy
- (enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->h
*2)) tmp
->y
= itofix(fy
- (enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->h
*2));
307 if (fixtoi(tmp
->y
) < fy
)
309 tmp
->y
= itofix(fy
+2); /* DEBUG: mejorar esto para que no 'salte' desde arriba de pantalla! */
310 tmp
->bytecode_exe
.y1
*= -1;
313 // es un BOSS, no pasar de 2/3 de pantalla?
314 if (enem_t
[tmp
->ene_t
].ia_boss
)
316 if (fixtoi(tmp
->y
)+enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->h
> (fy
+ALTO_FB
) / 3 * 2 )
318 tmp
->y
= itofix((fy
+ALTO_FB
) / 3 * 2 - enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
]->h
);
319 tmp
->bytecode_exe
.y1
*= -1;
323 { // desaparecer al salir por abajo
324 if (fixtoi(tmp
->y
) > fy
+ ALTO_FB
*1.05) tmp
->vida
= ENE_MUERTO
;
327 /* Verificacion para ir limpiando la lista de enemigos muertos */
328 if (tmp
->vida
<= ENE_MUERTO
) {
329 /* murio, eliminar y pasar al siguiente!!! */
333 tmp_p
= &tmp
->next
; /* nadie murio, siguiente por favor! */
335 } /* fin loop recorrer enemigos */
339 Esta funcion dibuja los enemigos en
340 el bitmap, desplazado x,y,
341 dibuja tambien una sombra que se desplaza
342 en relacion al borde inferior del bitmap y el centro y del mismo
343 de manera de dar un look 3D (como el viejo Rapt*r :^P )
344 TIENE que estar seteado el colormap de transparencia
346 void dibujar_enemigos(BITMAP
*bmp
, int x
, int y
)
348 ENEMIGO
*tmp
= enemigo_1
;
353 /* Colocar enemigo */
354 if (enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
] != NULL
)
356 /* colocar la sombra */
357 colocar_sombra(bmp
, enem_t
[tmp
->ene_t
].spr_shadow
[tmp
->spr_actual
], fixtoi(tmp
->x
)-x
, fixtoi(tmp
->y
)-y
);
358 draw_sprite(bmp
, enem_t
[tmp
->ene_t
].spr
[tmp
->spr_actual
], fixtoi(tmp
->x
)-x
, fixtoi(tmp
->y
)-y
);
363 sprintf(errstr
, "ERROR: dibujar_enemigos, hay un enemigo sin sprite (clase: %d, sprite: %d)!", tmp
->ene_t
, tmp
->spr_actual
);
364 levantar_error(errstr
);
368 /* DEBUG: mostrar energia del enemigo */
369 // if (KRONO_QUIERE_DEBUG)
372 // textprintf(bmp, font, fixtoi(tmp->x)-x, fixtoi(tmp->y)-y, makecol(255,255,255), "%d" , tmp->vida);
380 /* Esta funcion se debe llamar cuando no se precise mas la lista
381 Libera la RAM usada y reinicia la lista
383 void liberar_lista_enemigos() {
384 ENEMIGO
*tmp
= enemigo_1
;
388 ENEMIGO
*next
= tmp
->next
;
394 /* ------- DISPAROS DE LOS ENEMIGOS A PARTIR DE AQUI -------- */
397 Esta funcion agrega un disparo a la lista de disparos
398 Automaticamente lo agrega usando el arma del enemigo, etc
399 Ademas, verifica el timer, y todo lo demas.
400 Pasarle el puntero al enemigo que dispara.
402 void agregar_disparo_ene(ENEMIGO
*ene
)
406 if (ene
->arma_actual
< 0) return; /* enemigo desarmado */
409 EJECUTAR LOS SONIDOS DEL DISPARO */
410 tocar_sonido_paneado(fixtoi(ene
->x
),
411 arma_ene
[ene
->arma_actual
].snd
[0],
416 switch (arma_ene
[ene
->arma_actual
].t
)
460 /* DEBUG, que paso? */
461 c
= -1; /* no agregar nada! */
465 /* Si el tipo de disparo es doble, o triple, realizar el proceso varias veces */
468 DISP_ENE
*nueva
= malloc(sizeof(DISP_ENE
));
469 nueva
->next
= disp_ene_1
;
472 if (nueva
!= NULL
) /* si el malloc funciono, seteo los datos... */
475 /* Para evitar problemas, lleno todos los valores con defaults primero... */
476 /* La 'y' es comun a todos los tipos de disparos */
477 nueva
->x
= fixadd(ene
->x
, itofix(enem_t
[ene
->ene_t
].spr
[ene
->spr_actual
]->w
/2));
478 nueva
->y
= fixadd(ene
->y
, itofix(enem_t
[ene
->ene_t
].spr
[ene
->spr_actual
]->h
/2));
479 nueva
->dx
= arma_ene
[ene
->arma_actual
].vx
;
480 nueva
->dy
= arma_ene
[ene
->arma_actual
].vy
;
481 nueva
->arma
= ene
->arma_actual
;
482 nueva
->vida
= arma_ene
[nueva
->arma
].vida
;
484 /* Dependiendo del tipo de disparo, setear su posicion */
485 switch (arma_ene
[nueva
->arma
].t
)
488 nueva
->x
= fixadd(ene
->x
, itofix(rand() % enem_t
[ene
->ene_t
].spr
[ene
->spr_actual
]->w
));
491 case 1: /* direccion al azar */
494 nueva
->x
= fixadd(ene
->x
, itofix(rand() % enem_t
[ene
->ene_t
].spr
[ene
->spr_actual
]->w
));
495 nueva
->dx
= ftofix((float)rand_ex(-fixtof(arma_ene
[ene
->arma_actual
].vx
)*10.0, fixtof(arma_ene
[ene
->arma_actual
].vx
)*10.0) / 10.0);
496 if (rand()%100 < 10) nueva
->dx
= 0;
498 nueva
->dy
= fmul(arma_ene
[ene
->arma_actual
].vy
, itofix(rand_ex(1, 3)) );
501 case 2: /* abanico triple */
502 nueva
->x
= fixadd(ene
->x
, itofix(rand() % enem_t
[ene
->ene_t
].spr
[ene
->spr_actual
]->w
));
503 if (i
== 0) nueva
->dx
= arma_ene
[ene
->arma_actual
].vx
;
504 if (i
== 1) nueva
->dx
= 0;
505 if (i
== 2) nueva
->dx
= fixmul(arma_ene
[ene
->arma_actual
].vx
, itofix(-1)) ;
506 nueva
->dy
= arma_ene
[ene
->arma_actual
].vy
;
509 case 3: /* doble recto */
510 nueva
->x
= fixadd(ene
->x
, itofix(rand() % enem_t
[ene
->ene_t
].spr
[ene
->spr_actual
]->w
));
511 nueva
->dx
= arma_ene
[ene
->arma_actual
].vx
;
512 nueva
->dy
= arma_ene
[ene
->arma_actual
].vy
;
515 case 4: /* rastreador y en un 10% al azar */
518 nueva
->x
= fixadd(ene
->x
, itofix(rand()% enem_t
[ene
->ene_t
].spr
[ene
->spr_actual
]->w
));
520 if (jugador
.x
< ene
->x
) // rastrear
521 nueva
->dx
= ftofix((float)rand_ex(-150, 0)/10.0);
523 nueva
->dx
= ftofix((float)rand_ex(0, 150)/10.0);
525 nueva
->dy
= arma_ene
[ene
->arma_actual
].vy
;
527 if (rand()%100 < 15) // cada tanto, al azar
529 nueva
->dx
= ftofix((float)rand_ex(-150, 150) / 10.0);
530 nueva
->dy
= fmul(arma_ene
[ene
->arma_actual
].vy
, itofix(rand_ex(1, 3)) );
535 case 9: // en todas direcciones
538 nueva
->x
= fixadd(ene
->x
, itofix(rand() % enem_t
[ene
->ene_t
].spr
[ene
->spr_actual
]->w
));
541 nueva
->dx
= ftofix((float)rand_ex(-fixtoi(arma_ene
[ene
->arma_actual
].vx
)*10, 0)/10.0);
543 nueva
->dx
= ftofix((float)rand_ex(fixtoi(arma_ene
[ene
->arma_actual
].vx
)*10, 0)/10.0);
546 nueva
->dy
= ftofix((float)rand_ex(-fixtoi(arma_ene
[ene
->arma_actual
].vy
)*10, -fixtoi(arma_ene
[ene
->arma_actual
].vy
)*5 )/10.0);
548 nueva
->dy
= ftofix((float)rand_ex(fixtoi(arma_ene
[ene
->arma_actual
].vy
)*10, fixtoi(arma_ene
[ene
->arma_actual
].vy
)*5)/10.0);
551 default: /* que paso? */
552 nueva
->x
= fixadd(ene
->x
, itofix(rand() % enem_t
[ene
->ene_t
].spr
[ene
->spr_actual
]->w
));
553 nueva
->dx
= ftofix((float)rand_ex(-150, 150)/10.0);
554 nueva
->dy
= arma_ene
[ene
->arma_actual
].vy
;
563 Esta funcion actualiza la logica de los disparos
564 y los comprueba contra el jugador
565 ademas de remover los que tienen vida < 0
566 Precisa saber el desplazamiento del mapa (fy)
567 si la bomba especial del jugador esta activa, elimina los disparos!
569 void mover_disparos_ene(int fy
) {
570 DISP_ENE
**tmp_p
= &disp_ene_1
;
571 int i1
; /* auxiliar para agregar estelas a los disparos */
575 DISP_ENE
*tmp
= *tmp_p
;
578 tmp
->x
= fixadd(tmp
->x
, tmp
->dx
);
579 tmp
->y
= fixadd(tmp
->y
, tmp
->dy
);
580 (tmp
->vida
)--; /* DEBUG: esto es correcto?, teoricamente, si... */
582 if (bomba_esta_activa
) tmp
->vida
= -1; // matar disparo si esta la bomba
584 /* verificar si disparo CHOCA CON jugador */
586 if (check_pmask_collision(arma_ene
[tmp
->arma
].mask
, jugador
.mask
,
587 fixtoi(tmp
->x
), fixtoi(tmp
->y
),
588 fixtoi(jugador
.x
), fixtoi(jugador
.y
) ) != 0)
591 /* choco al jugador! SONIDO de colision del arma */
592 tocar_sonido_paneado(fixtoi(tmp
->x
),
593 arma_ene
[tmp
->arma
].snd
[1],
599 jugador
.vida
-= arma_ene
[tmp
->arma
].punch
;
601 if (nivel_detalle
> 0) poner_explosion_nave(fixtoi(tmp
->x
), fixtoi(tmp
->y
), rand()%20+20, rand()%10+5+arma_ene
[tmp
->arma
].punch
*2, 0);
603 else /* si no choco al jugador, agregar estela de particulas - DEBUG */
605 /* DEBUG: agregar estela en particulas, [eliminar en bajos detalles!]
606 esto podria ser una funcion aparte
607 porque es bastante complicada la sintaxis... */
608 if (nivel_detalle
> 7)
610 i1
< rand_ex(arma_ene
[tmp
->arma
].est_cant
[0], arma_ene
[tmp
->arma
].est_cant
[1]);
612 agrega_particula( fixadd(tmp
->x
, itofix(arma_ene
[tmp
->arma
].spr
->w
/2)),
613 fixadd(tmp
->y
, itofix(rand()%arma_ene
[tmp
->arma
].spr
->h
)),
614 ftofix(rand_ex(arma_ene
[tmp
->arma
].est_dx
[0], arma_ene
[tmp
->arma
].est_dx
[1])/100.0),
615 ftofix(rand_ex(arma_ene
[tmp
->arma
].est_dy
[0], arma_ene
[tmp
->arma
].est_dy
[1])/100.0),
616 rand_ex(arma_ene
[tmp
->arma
].est_vida
[0], arma_ene
[tmp
->arma
].est_vida
[1]),
617 makecol(rand_ex(arma_ene
[tmp
->arma
].est_color
[0][0], arma_ene
[tmp
->arma
].est_color
[0][1]),
618 rand_ex(arma_ene
[tmp
->arma
].est_color
[1][0], arma_ene
[tmp
->arma
].est_color
[1][1]),
619 rand_ex(arma_ene
[tmp
->arma
].est_color
[2][0], arma_ene
[tmp
->arma
].est_color
[2][1])),
620 rand_ex(arma_ene
[tmp
->arma
].est_rad
[0], arma_ene
[tmp
->arma
].est_rad
[1]),
621 rand_ex(arma_ene
[tmp
->arma
].est_tipo
[0], arma_ene
[tmp
->arma
].est_tipo
[1]),
622 arma_ene
[tmp
->arma
].est_transp
,0,
626 if (fixtoi(tmp
->y
) > fy
+ ALTO_FB
) tmp
->vida
= -1; /* se fue por abajo... */
627 if (fixtoi(tmp
->y
) < fy
) tmp
->vida
= -1; /* se fue por arriba... */
629 /* Remocion de disparos muertos */
631 /* murio, eliminar!!! */
635 tmp_p
= &tmp
->next
; /* siguiente por favor! */
640 /* Dibuja los disparos, desplazados por x,y
641 sobre el bitmap bmp */
642 void dibujar_disp_ene(BITMAP
*bmp
, int x
, int y
) {
644 DISP_ENE
*tmp
= disp_ene_1
;
647 draw_sprite(bmp
, arma_ene
[tmp
->arma
].spr
, fixtoi(tmp
->x
)-x
, fixtoi(tmp
->y
)-y
);
649 /* DEBUG: mostrar energia */
650 // if (KRONO_QUIERE_DEBUG)
653 // textprintf(bmp, font, fixtoi(tmp->x)-x, fixtoi(tmp->y)-y, makecol(255,255,255), "%d" , tmp->vida);
656 tmp
= tmp
->next
; /* proximo... */
661 /* Esta funcion se debe llamar cuando no se precise mas la lista
662 Libera la RAM usada y reinicia la lista
664 void liberar_lista_disparos_ene() {
665 DISP_ENE
*tmp
= disp_ene_1
;
669 DISP_ENE
*next
= tmp
->next
;