applied flame badguy patch from Matze Braun
[supertux.git] / src / badguy.cpp
1 //
2 // C Implementation: badguy
3 //
4 // Description:
5 //
6 //
7 // Author: Tobias Glaesser <tobi.web@gmx.de> & Bill Kendrick, (C) 2004
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12 #include <math.h>
13
14 #include "globals.h"
15 #include "defines.h"
16 #include "badguy.h"
17 #include "scene.h"
18 #include "screen.h"
19
20 texture_type img_bsod_squished_left;
21 texture_type img_bsod_squished_right;
22 texture_type img_bsod_falling_left;
23 texture_type img_bsod_falling_right;
24 texture_type img_laptop_flat_left;
25 texture_type img_laptop_flat_right;
26 texture_type img_laptop_falling_left;
27 texture_type img_laptop_falling_right;
28 texture_type img_bsod_left[4];
29 texture_type img_bsod_right[4];
30 texture_type img_laptop_left[3];
31 texture_type img_laptop_right[3];
32 texture_type img_money_left[2];
33 texture_type img_money_right[2];
34 texture_type img_mrbomb_left[4];
35 texture_type img_mrbomb_right[4];
36 texture_type img_stalactite;
37 texture_type img_stalactite_broken;
38 texture_type img_flame[2];
39
40 BadGuyKind  badguykind_from_string(const std::string& str)
41 {
42   if (str == "money")
43     return BAD_MONEY;
44   else if (str == "laptop")
45     return BAD_LAPTOP;
46   else if (str == "bsod")
47     return BAD_BSOD;
48   else if (str == "mrbomb")
49     return BAD_MRBOMB;
50   else if (str == "stalactite")
51     return BAD_STALACTITE;
52   else if (str == "flame")
53     return BAD_FLAME;
54   else
55     {
56       printf("Couldn't convert badguy: %s\n", str.c_str());
57       return BAD_BSOD;
58     }
59 }
60
61 std::string badguykind_to_string(BadGuyKind kind)
62 {
63   switch(kind)
64     {
65     case BAD_MONEY:
66       return "money";
67       break;
68     case BAD_LAPTOP:
69       return "laptop";
70       break;
71     case BAD_BSOD:
72       return "bsod";
73       break;
74     case BAD_MRBOMB:
75       return "mrbomb";
76       break;
77     case BAD_STALACTITE:
78       return "stalactite";
79       break;
80     case BAD_FLAME:
81       return "flame";
82       break;
83     default:
84       return "bsod";
85     }
86 }
87
88 void
89 BadGuy::init(float x, float y, BadGuyKind kind_)
90 {
91   base.width  = 32;
92   base.height = 32;
93   mode     = NORMAL;
94   dying    = DYING_NOT;
95   kind     = kind_;
96   base.x   = x;
97   base.y   = y;
98   base.xm  = -1.3;
99   base.ym  = 4.8;
100   old_base = base;
101   dir      = LEFT;
102   seen     = false;
103   timer_init(&timer, true);
104   physic_init(&physic);
105
106   if(kind == BAD_BOMB) {
107     timer_start(&timer, 1000);
108     mode = BOMB_TICKING;
109     // hack so that the bomb doesn't hurt until it expldes...
110     dying = DYING_SQUISHED;
111   } else if(kind == BAD_FLAME) {
112     base.ym = 0; // we misuse base.ym as angle for the flame
113   }
114 }
115
116 void BadGuy::action_bsod()
117 {
118   /* --- BLUE SCREEN OF DEATH MONSTER: --- */
119
120   /* Move left/right: */
121   if (dying == DYING_NOT ||
122       dying == DYING_FALLING)
123     {
124       base.x += base.xm * frame_ratio;
125     }
126
127   /* Move vertically: */
128   base.y = base.y + base.ym * frame_ratio;
129
130   if (dying != DYING_FALLING)
131     collision_swept_object_map(&old_base,&base);
132                 
133   if (!dying)
134     check_horizontal_bump();
135
136   fall(true);
137
138   // Handle dying timer:
139   if (dying == DYING_SQUISHED)       
140     {
141       /* Remove it if time's up: */
142       if(!timer_check(&timer)) {
143         remove_me();
144         return;
145       }
146     }
147 }
148
149 void BadGuy::action_laptop()
150 {
151   /* Move left/right: */
152   if (mode == NORMAL || mode == KICK)
153     {
154       if (dying == DYING_NOT ||
155           dying == DYING_FALLING)
156         {
157           base.x += base.xm * frame_ratio;
158         }
159     }
160   else if (mode == HELD)
161     { /* FIXME: The pbad object shouldn't know about pplayer objects. */
162       /* If we're holding the laptop */
163       dir=tux.dir;
164       if(dir==RIGHT)
165         {
166           base.x = tux.base.x + 16;
167           base.y = tux.base.y + tux.base.height/1.5 - base.height;
168         }
169       else /* facing left */
170         {
171           base.x = tux.base.x - 16;
172           base.y = tux.base.y + tux.base.height/1.5 - base.height;
173         }
174       if(collision_object_map(&base))
175         {
176           base.x = tux.base.x;
177           base.y = tux.base.y + tux.base.height/1.5 - base.height;
178         }
179
180       if(tux.input.fire != DOWN) /* SHOOT! */
181         {
182           if(dir == LEFT)
183             base.x -= 24;
184           else
185             base.x += 24;
186
187           mode=KICK;
188           base.xm = 8;
189           base.ym = 8;
190           play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
191         }
192     }
193
194
195   /* Move vertically: */
196   if(mode != HELD)
197     base.y = base.y + base.ym * frame_ratio;
198
199   if (dying != DYING_FALLING)
200     collision_swept_object_map(&old_base,&base);
201   /* Bump into things horizontally: */
202
203   if (!dying)
204     {
205       int changed = dir;
206       check_horizontal_bump();
207       if(mode == KICK && changed != dir)
208         {
209           /* handle stereo sound (number 10 should be tweaked...)*/
210           if (base.x < scroll_x - 10)
211             play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
212           else if (base.x > scroll_x + 10)
213             play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
214           else
215             play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
216         }
217     }
218
219   fall();
220
221   /* Handle mode timer: */
222   if (mode == FLAT && mode != HELD)
223     {
224       if(!timer_check(&timer))
225         {
226           mode = NORMAL;
227           base.xm = 4;
228         }
229     }
230   else if (mode == KICK)
231     {
232       timer_check(&timer);
233     }
234 }
235
236 void BadGuy::check_horizontal_bump(bool checkcliff)
237 {
238     if (dir == LEFT && issolid( base.x, (int) base.y + 16))
239     {
240         dir = RIGHT;
241         base.xm = -base.xm;
242         return;
243     }
244     if (dir == RIGHT && issolid( base.x + base.width, (int) base.y + 16))
245     {
246         dir = LEFT;
247         base.xm = -base.xm;
248         return;
249     }
250
251     // don't check for cliffs when we're falling
252     if(!checkcliff)
253         return;
254     
255     if(dir == LEFT && !issolid(base.x, (int) base.y + base.height + 16))
256     {
257         printf("Cliffcol left\n");
258         dir = RIGHT;
259         base.xm = -base.xm;
260         return;
261     }
262     if(dir == RIGHT && !issolid(base.x + base.width,
263                 (int) base.y + base.height + 16))
264     {
265         printf("Cliffcol right\n");
266         dir = LEFT;
267         base.xm = -base.xm;
268         return;
269     }
270 }
271
272 void BadGuy::fall(bool dojump)
273 {
274   /* Fall if we get off the ground: */
275   if (dying != DYING_FALLING)
276     {
277       if (!issolid(base.x+16, base.y + 32))
278         {
279           if(!physic_is_set(&physic))
280             {
281               physic_set_state(&physic,PH_VT);
282               physic_set_start_vy(&physic, dojump ? 2. : 0.);
283             }
284
285           if(mode != HELD)
286             {
287               base.ym = physic_get_velocity(&physic);
288             }
289         }
290       else
291         {
292           /* Land: */
293
294           if (base.ym > 0)
295             {
296               base.y = (int)(base.y / 32) * 32;
297               base.ym = 0;
298             }
299           physic_init(&physic);
300         }
301     }
302   else
303     {
304       if(!physic_is_set(&physic))
305         {                                                
306           physic_set_state(&physic,PH_VT);
307           physic_set_start_vy(&physic,0.);
308         }
309       base.ym = physic_get_velocity(&physic);
310     }
311
312   // BadGuy fall below the ground
313   if (base.y > screen->h) {
314     remove_me();
315     return;
316   }
317 }
318
319 void BadGuy::remove_me()
320 {
321   std::vector<BadGuy>::iterator i;
322   for(i = bad_guys.begin(); i != bad_guys.end(); ++i) {
323     if( & (*i) == this) {
324       bad_guys.erase(i);
325       return;
326     }
327   }
328 }
329
330 void BadGuy::action_money()
331 {
332   /* Move vertically: */
333   base.y = base.y + base.ym * frame_ratio;
334
335   if (dying != DYING_FALLING)
336     collision_swept_object_map(&old_base,&base);
337
338   if (base.y > screen->h) {
339     remove_me();
340     return;
341   }
342
343   if(physic_get_state(&physic) == -1)
344     {
345       physic_set_state(&physic,PH_VT);
346       physic_set_start_vy(&physic,0.);
347     }
348
349   if (dying != DYING_FALLING)
350     {
351       
352       if(issolid(base.x, base.y + 32))
353         {
354           physic_set_state(&physic,PH_VT);
355           physic_set_start_vy(&physic,6.);
356           base.ym = physic_get_velocity(&physic);
357         }
358       /* // matze: is this code needed?
359       else if(issolid(base.x, base.y))
360         { // This works, but isn't the best solution imagineable 
361           physic_set_state(&physic,PH_VT);
362           physic_set_start_vy(&physic,0.);
363           base.ym = physic_get_velocity(&physic);
364           ++base.y;
365         }*/
366       else
367         {
368           base.ym = physic_get_velocity(&physic);
369         }
370     }
371   else
372     {
373       if(!physic_is_set(&physic))
374         {
375           physic_set_state(&physic,PH_VT);
376           physic_set_start_vy(&physic,0.);
377         }
378       base.ym = physic_get_velocity(&physic);
379     } 
380 }
381
382 void BadGuy::action_mrbomb()
383 {
384   if(mode == NORMAL) {
385     base.x += base.xm * frame_ratio;
386   }
387
388   /* Move vertically: */
389   base.y += base.ym * frame_ratio;
390
391   if (dying != DYING_FALLING)
392     collision_swept_object_map(&old_base,&base);
393
394   check_horizontal_bump(true);
395   fall();
396 }
397
398 void BadGuy::action_bomb()
399 {
400   // eventually fall down
401   base.y += base.ym * frame_ratio;
402   collision_swept_object_map(&old_base,&base);
403   fall();
404
405   if(!timer_check(&timer)) {
406     if(mode == BOMB_TICKING) {
407       mode = BOMB_EXPLODE;
408       dying = DYING_NOT; // now the bomb hurts
409       timer_start(&timer, 1000);
410     } else if(mode == BOMB_EXPLODE) {
411       remove_me();
412       return;
413     }
414   }
415 }
416
417 void BadGuy::action_stalactite()
418 {
419   if(mode == NORMAL) {
420     if(tux.base.x + 32 > base.x - 40 && tux.base.x < base.x + 32 + 40) {
421       timer_start(&timer, 800);
422       mode = STALACTITE_SHAKING;
423     }
424   } if(mode == STALACTITE_SHAKING) {
425     base.x = old_base.x + (rand() % 6) - 3; // TODO this could be done nicer...
426     if(!timer_check(&timer)) {
427       mode = STALACTITE_FALL;
428     }
429   } else if(mode == STALACTITE_FALL) {
430     base.y += base.ym * frame_ratio;   
431     /* Destroy if collides land */
432     if(issolid(base.x+16, base.y+32))
433     {
434       timer_start(&timer, 3000);
435       dying = DYING_SQUISHED;
436       mode = FLAT;
437     }
438   }
439 }
440
441 void
442 BadGuy::action_flame()
443 {
444     static const float radius = 100;
445     static const float speed = 0.02;
446     base.x = old_base.x + cos(base.ym) * radius;
447     base.y = old_base.y + sin(base.ym) * radius;
448
449     base.ym = fmodf(base.ym + frame_ratio * speed, 2*M_PI);
450 }
451
452 void
453 BadGuy::action()
454
455   if (seen)
456     {
457       switch (kind)
458         {
459         case BAD_BSOD:
460           action_bsod();
461           break;
462     
463         case BAD_LAPTOP:
464           action_laptop();
465           break;
466       
467         case BAD_MONEY:
468           action_money();
469           break;
470
471         case BAD_MRBOMB:
472           action_mrbomb();
473           break;
474         
475         case BAD_BOMB:
476           action_bomb();
477           break;
478
479         case BAD_STALACTITE:
480           action_stalactite();
481           break;
482
483         case BAD_FLAME:
484           action_flame();
485           break;
486         }
487     }
488
489   // Remove if it's far off the screen:
490   if (base.x < scroll_x - OFFSCREEN_DISTANCE)
491     {
492       remove_me();
493       return;
494     }
495   else /* !seen */
496     {
497       // Once it's on screen, it's activated!
498       if (base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
499         seen = true;
500     }
501 }
502
503 void
504 BadGuy::draw_bsod()
505 {
506   texture_type* texture = 0;
507   float y = base.y;
508   if(dying == DYING_NOT) {
509     size_t frame = (global_frame_counter / 5) % 4;
510     texture = (dir == LEFT) ? &img_bsod_left[frame] : &img_bsod_right[frame];
511   } else if(dying == DYING_FALLING) {
512     texture = (dir == LEFT) ? &img_bsod_falling_left : &img_bsod_falling_right;
513   } else if(dying == DYING_SQUISHED) {
514     texture = (dir == LEFT) 
515         ? &img_bsod_squished_left : &img_bsod_squished_right;
516     y += 24;
517   }
518   
519   texture_draw(texture, base.x - scroll_x, y);
520 }
521
522 void
523 BadGuy::draw_laptop()
524 {
525   texture_type* texture;
526   size_t frame = (global_frame_counter / 5) % 3;
527   
528   if(dying == DYING_NOT) {
529     if(mode == NORMAL) {
530       if(dir == LEFT)
531         texture = &img_laptop_left[frame];
532       else
533         texture = &img_laptop_right[frame];
534     } else {
535       texture = (dir == LEFT) ? &img_laptop_flat_left : &img_laptop_flat_right;
536     }
537   } else {
538     texture = (dir == LEFT) 
539         ? &img_laptop_falling_left : &img_laptop_falling_right;
540   }
541
542   texture_draw(texture, base.x - scroll_x, base.y);
543 }
544
545 void
546 BadGuy::draw_money()
547 {
548   texture_type* texture;
549   size_t frame = (base.ym != 300) ? 0 : 1;
550
551   if(tux.base.x + tux.base.width < base.x) {
552     texture = &img_money_left[frame];
553   } else {
554     texture = &img_money_right[frame];
555   }
556
557   texture_draw(texture, base.x - scroll_x, base.y);
558 }
559   
560 void
561 BadGuy::draw_mrbomb()
562 {
563   texture_type* texture;
564   size_t frame = (global_frame_counter/5) % 4;
565
566   if(dir == LEFT)
567     texture = &img_mrbomb_left[frame];
568   else
569     texture = &img_mrbomb_right[frame];
570
571   texture_draw(texture, base.x - scroll_x, base.y);
572 }
573
574 void
575 BadGuy::draw_bomb()
576 {
577   texture_type* texture;
578   
579   // TODO add real bomb graphics
580   if(mode == BOMB_TICKING) {
581     texture = &img_bsod_squished_right;
582   } else {
583     texture = &img_bsod_squished_left;
584   }
585   
586   texture_draw(texture, base.x - scroll_x, base.y);
587 }
588
589 void
590 BadGuy::draw_stalactite()
591 {
592   texture_type* texture;
593   if(mode != FLAT)
594     texture = &img_stalactite;
595   else
596     texture = &img_stalactite_broken;
597
598   texture_draw(texture, base.x - scroll_x, base.y);
599 }
600
601 void
602 BadGuy::draw_flame()
603 {
604   size_t frame = (global_frame_counter / 10) % 2;
605   texture_type* texture = &img_flame[frame];
606
607   texture_draw(texture, base.x - scroll_x, base.y);
608 }
609
610 void
611 BadGuy::draw()
612 {
613   // Don't try to draw stuff that is outside of the screen
614   if (base.x > scroll_x - 32 &&
615       base.x < scroll_x + screen->w)
616     {
617       switch (kind)
618         {
619         case BAD_BSOD:
620           draw_bsod();
621           break;
622     
623         case BAD_LAPTOP:
624           draw_laptop();
625           break;
626     
627         case BAD_MONEY:
628           draw_money();
629           break;
630
631         case BAD_MRBOMB:
632           draw_mrbomb();
633           break;
634
635         case BAD_BOMB:
636           draw_bomb();
637           break;
638
639         case BAD_STALACTITE:
640           draw_stalactite();
641           break;
642
643         case BAD_FLAME:
644           draw_flame();
645           break;
646
647         }
648     }
649 }
650
651 void
652 BadGuy::bump()
653 {
654   if(kind == BAD_BSOD || kind == BAD_LAPTOP || kind == BAD_BOMB) {
655     dying = DYING_FALLING;
656     base.ym = -8;
657     play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
658   }
659 }
660
661 void
662 BadGuy::make_player_jump(Player* player)
663 {
664     physic_set_state(&player->vphysic,PH_VT);
665     physic_set_start_vy(&player->vphysic,2.);
666     player->base.y = base.y - player->base.height - 1;
667 }
668
669 void
670 BadGuy::squich(Player* player)
671 {
672   if(kind == BAD_MRBOMB) {
673       // mrbomb transforms into a bomb now
674       add_bad_guy(base.x, base.y, BAD_BOMB);
675       
676       make_player_jump(player);
677       add_score(base.x - scroll_x, base.y, 50 * score_multiplier);
678       play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
679       score_multiplier++;
680       
681       remove_me();
682       return;
683
684   } else if(kind == BAD_BSOD) {
685       dying = DYING_SQUISHED;
686       timer_start(&timer,4000);
687
688       make_player_jump(player);
689
690       add_score(base.x - scroll_x, base.y, 50 * score_multiplier);
691       play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
692       score_multiplier++;
693       return;
694       
695   } else if (kind == BAD_LAPTOP) {
696       if (mode == NORMAL || mode == KICK)
697       {
698           /* Flatten! */
699           play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
700           mode = FLAT;
701           base.xm = 4;
702
703           timer_start(&timer, 4000);
704       } else if (mode == FLAT) {
705           /* Kick! */
706           play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
707
708           if (player->base.x < base.x + (base.width/2))
709               dir = RIGHT;
710           else
711               dir = LEFT;
712
713           base.xm = 5;
714           mode = KICK;
715
716           timer_start(&timer,5000);
717       }
718
719       make_player_jump(player);
720               
721       add_score(base.x - scroll_x,
722               base.y,
723               25 * score_multiplier);
724       score_multiplier++;
725       return;
726   }
727 }
728
729 void
730 BadGuy::collision(void *p_c_object, int c_object, CollisionType type)
731 {
732   BadGuy* pbad_c    = NULL;
733
734   if(type == COLLISION_BUMP) {
735     bump();
736     return;
737   }
738   if(type == COLLISION_SQUICH) {
739     Player* player = static_cast<Player*>(p_c_object);
740     squich(player);
741     return;
742   }
743
744   switch (c_object)
745     {
746     case CO_BULLET:
747       if(kind == BAD_BOMB || kind == BAD_STALACTITE || kind == BAD_FLAME)
748         return;
749
750       dying = DYING_FALLING;
751       base.ym = -8;
752
753       /* Gain some points: */
754       if (kind == BAD_BSOD)
755         add_score(base.x - scroll_x, base.y,
756                   50 * score_multiplier);
757       else if (kind == BAD_LAPTOP)
758         add_score(base.x - scroll_x, base.y,
759                   25 * score_multiplier);
760       else if (kind == BAD_MONEY)
761         add_score(base.x - scroll_x, base.y,
762                   50 * score_multiplier);
763
764       /* Play death sound: */
765       play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
766       break;
767
768     case CO_BADGUY:
769       pbad_c = (BadGuy*) p_c_object;
770       if (mode == NORMAL)
771       {
772       /* do nothing */
773       }
774       else if(mode == KICK)
775         {
776           /* We're in kick mode, kill the other guy
777              and yourself(wuahaha) : */
778
779           pbad_c->dying = DYING_FALLING;
780           pbad_c->base.ym = -8;
781           play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
782
783           add_score(base.x - scroll_x,
784                     base.y, 100);
785                   pbad_c->dying = DYING_FALLING;
786                   
787           dying = DYING_FALLING;
788           base.ym = -8;
789
790           add_score(pbad_c->base.x - scroll_x,
791                     pbad_c->base.y, 100);
792         }
793       break;
794     }
795 }
796
797 //---------------------------------------------------------------------------
798
799 void load_badguy_gfx()
800 {
801   /* (BSOD) */
802   texture_load(&img_bsod_left[0], datadir +
803                "/images/shared/bsod-left-0.png",
804                USE_ALPHA);
805
806   texture_load(&img_bsod_left[1], datadir +
807                "/images/shared/bsod-left-1.png",
808                USE_ALPHA);
809
810   texture_load(&img_bsod_left[2], datadir +
811                "/images/shared/bsod-left-2.png",
812                USE_ALPHA);
813
814   texture_load(&img_bsod_left[3], datadir +
815                "/images/shared/bsod-left-3.png",
816                USE_ALPHA);
817
818   texture_load(&img_bsod_right[0], datadir +
819                "/images/shared/bsod-right-0.png",
820                USE_ALPHA);
821
822   texture_load(&img_bsod_right[1], datadir +
823                "/images/shared/bsod-right-1.png",
824                USE_ALPHA);
825
826   texture_load(&img_bsod_right[2], datadir +
827                "/images/shared/bsod-right-2.png",
828                USE_ALPHA);
829
830   texture_load(&img_bsod_right[3], datadir +
831                "/images/shared/bsod-right-3.png",
832                USE_ALPHA);
833
834   texture_load(&img_bsod_squished_left, datadir +
835                "/images/shared/bsod-squished-left.png",
836                USE_ALPHA);
837
838   texture_load(&img_bsod_squished_right, datadir +
839                "/images/shared/bsod-squished-right.png",
840                USE_ALPHA);
841
842   texture_load(&img_bsod_falling_left, datadir +
843                "/images/shared/bsod-falling-left.png",
844                USE_ALPHA);
845
846   texture_load(&img_bsod_falling_right, datadir +
847                "/images/shared/bsod-falling-right.png",
848                USE_ALPHA);
849
850
851   /* (Laptop) */
852
853   texture_load(&img_laptop_left[0], datadir +
854                "/images/shared/laptop-left-0.png",
855                USE_ALPHA);
856
857   texture_load(&img_laptop_left[1], datadir +
858                "/images/shared/laptop-left-1.png",
859                USE_ALPHA);
860
861   texture_load(&img_laptop_left[2], datadir +
862                "/images/shared/laptop-left-2.png",
863                USE_ALPHA);
864
865   texture_load(&img_laptop_right[0], datadir +
866                "/images/shared/laptop-right-0.png",
867                USE_ALPHA);
868
869   texture_load(&img_laptop_right[1], datadir +
870                "/images/shared/laptop-right-1.png",
871                USE_ALPHA);
872
873   texture_load(&img_laptop_right[2], datadir +
874                "/images/shared/laptop-right-2.png",
875                USE_ALPHA);
876
877   texture_load(&img_laptop_flat_left, datadir +
878                "/images/shared/laptop-flat-left.png",
879                USE_ALPHA);
880
881   texture_load(&img_laptop_flat_right, datadir +
882                "/images/shared/laptop-flat-right.png",
883                USE_ALPHA);
884
885   texture_load(&img_laptop_falling_left, datadir +
886                "/images/shared/laptop-falling-left.png",
887                USE_ALPHA);
888
889   texture_load(&img_laptop_falling_right, datadir +
890                "/images/shared/laptop-falling-right.png",
891                USE_ALPHA);
892
893
894   /* (Money) */
895
896   texture_load(&img_money_left[0], datadir +
897                "/images/shared/bag-left-0.png",
898                USE_ALPHA);
899
900   texture_load(&img_money_left[1], datadir +
901                "/images/shared/bag-left-1.png",
902                USE_ALPHA);
903
904   texture_load(&img_money_right[0], datadir +
905                "/images/shared/bag-right-0.png",
906                USE_ALPHA);
907
908   texture_load(&img_money_right[1], datadir +
909                "/images/shared/bag-right-1.png",
910                USE_ALPHA);
911
912   /* Mr. Bomb */
913   for(int i=0; i<4; ++i) {
914       char num[4];
915       snprintf(num, 4, "%d", i);
916       texture_load(&img_mrbomb_left[i],
917               datadir + "/images/shared/mrbomb-left-" + num + ".png", USE_ALPHA);
918       texture_load(&img_mrbomb_right[i],
919               datadir + "/images/shared/mrbomb-right-" + num + ".png", USE_ALPHA);
920   }
921
922   /* stalactite */
923   texture_load(&img_stalactite, 
924           datadir + "/images/shared/stalactite.png", USE_ALPHA);
925   texture_load(&img_stalactite_broken,
926           datadir + "/images/shared/stalactite-broken.png", USE_ALPHA);
927
928   /* flame */
929   texture_load(&img_flame[0],
930           datadir + "/images/shared/flame-0.png", USE_ALPHA);
931   texture_load(&img_flame[1],
932           datadir + "/images/shared/flame-1.png", USE_ALPHA);  
933 }
934
935 void free_badguy_gfx()
936 {
937   for (int i = 0; i < 4; i++)
938     {
939       texture_free(&img_bsod_left[i]);
940       texture_free(&img_bsod_right[i]);
941     }
942
943   texture_free(&img_bsod_squished_left);
944   texture_free(&img_bsod_squished_right);
945
946   texture_free(&img_bsod_falling_left);
947   texture_free(&img_bsod_falling_right);
948
949   for (int i = 0; i < 3; i++)
950     {
951       texture_free(&img_laptop_left[i]);
952       texture_free(&img_laptop_right[i]);
953     }
954
955   texture_free(&img_laptop_flat_left);
956   texture_free(&img_laptop_flat_right);
957
958   texture_free(&img_laptop_falling_left);
959   texture_free(&img_laptop_falling_right);
960
961   for (int i = 0; i < 2; i++)
962     {
963       texture_free(&img_money_left[i]);
964       texture_free(&img_money_right[i]);
965     }
966
967   for(int i = 0; i < 4; i++) {
968       texture_free(&img_mrbomb_left[i]);
969       texture_free(&img_mrbomb_right[i]);
970   }
971
972   texture_free(&img_stalactite);
973   texture_free(&img_stalactite_broken);
974
975   texture_free(&img_flame[0]);
976   texture_free(&img_flame[1]);
977 }
978
979 // EOF //