1 /*
2 * fireball.c - fire ball
3 * Copyright (C) 2010 Alexandre Martins <alemartf(at)gmail(dot)com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "fireball.h"
21 #include "../../core/util.h"
22 #include "../../core/soundfactory.h"
23 #include "../../scenes/level.h"
24
25 /* fireball class */
26 typedef struct fireball_t fireball_t;
27 struct fireball_t {
28 item_t item; /* base class */
29 void (*run)(item_t*,brick_list_t*);
30 };
31
32 static void fireball_init(item_t *item);
33 static void fireball_release(item_t* item);
34 static void fireball_update(item_t* item, player_t** team, int team_size, brick_list_t* brick_list, item_list_t* item_list, enemy_list_t* enemy_list);
35 static void fireball_render(item_t* item, v2d_t camera_position);
36
37 static void fireball_set_behavior(item_t *fireball, void (*behavior)(item_t*,brick_list_t*));
38
39 static void falling_behavior(item_t *fireball, brick_list_t *brick_list);
40 static void disappearing_behavior(item_t *fireball, brick_list_t *brick_list);
41 static void smallfire_behavior(item_t *fireball, brick_list_t *brick_list);
42
43
44
45 /* public methods */
fireball_create()46 item_t* fireball_create()
47 {
48 item_t *item = mallocx(sizeof(fireball_t));
49
50 item->init = fireball_init;
51 item->release = fireball_release;
52 item->update = fireball_update;
53 item->render = fireball_render;
54
55 return item;
56 }
57
58
59 /* private methods */
fireball_set_behavior(item_t * fireball,void (* behavior)(item_t *,brick_list_t *))60 void fireball_set_behavior(item_t *fireball, void (*behavior)(item_t*,brick_list_t*))
61 {
62 fireball_t *me = (fireball_t*)fireball;
63 me->run = behavior;
64 }
65
fireball_init(item_t * item)66 void fireball_init(item_t *item)
67 {
68 item->obstacle = FALSE;
69 item->bring_to_back = FALSE;
70 item->preserve = FALSE;
71 item->actor = actor_create();
72
73 fireball_set_behavior(item, falling_behavior);
74 actor_change_animation(item->actor, sprite_get_animation("SD_FIREBALL", 0));
75 }
76
77
78
fireball_release(item_t * item)79 void fireball_release(item_t* item)
80 {
81 actor_destroy(item->actor);
82 }
83
84
85
fireball_update(item_t * item,player_t ** team,int team_size,brick_list_t * brick_list,item_list_t * item_list,enemy_list_t * enemy_list)86 void fireball_update(item_t* item, player_t** team, int team_size, brick_list_t* brick_list, item_list_t* item_list, enemy_list_t* enemy_list)
87 {
88 int i;
89 actor_t *act = item->actor;
90 fireball_t *me = (fireball_t*)item;
91
92 /* hit the player */
93 for(i=0; i<team_size; i++) {
94 player_t *player = team[i];
95 if(!player->dying && actor_collision(act, player->actor)) {
96 item->state = IS_DEAD;
97 if(player->shield_type != SH_FIRESHIELD)
98 player_hit(player);
99 }
100 }
101
102 /* my behavior */
103 me->run(item, brick_list);
104 }
105
106
fireball_render(item_t * item,v2d_t camera_position)107 void fireball_render(item_t* item, v2d_t camera_position)
108 {
109 actor_render(item->actor, camera_position);
110 }
111
112
113 /* private behaviors */
falling_behavior(item_t * fireball,brick_list_t * brick_list)114 void falling_behavior(item_t *fireball, brick_list_t *brick_list)
115 {
116 int i, n;
117 float sqrsize = 2, diff = -2;
118 actor_t *act = fireball->actor;
119 brick_t *down;
120
121 /* movement & animation */
122 act->speed.x = 0.0f;
123 act->mirror = (act->speed.y < 0.0f) ? IF_VFLIP : IF_NONE;
124 actor_move(act, actor_particle_movement(act, level_gravity()));
125 actor_change_animation(act, sprite_get_animation("SD_FIREBALL", 0));
126
127 /* collision detection */
128 actor_corners(act, sqrsize, diff, brick_list, NULL, NULL, NULL, NULL, &down, NULL, NULL, NULL);
129 actor_handle_clouds(act, diff, NULL, NULL, NULL, NULL, &down, NULL, NULL, NULL);
130 if(down) {
131 /* I have just touched the ground */
132 fireball_set_behavior(fireball, disappearing_behavior);
133 sound_play( soundfactory_get("fire2") );
134
135 /* create small fire balls */
136 n = 2 + random(3);
137 for(i=0; i<n; i++) {
138 item_t *obj = level_create_item(IT_FIREBALL, act->position);
139 fireball_set_behavior(obj, smallfire_behavior);
140 obj->actor->speed = v2d_new(((float)i/(float)n)*400.0f-200.0f, -120.0f-random(240.0f));
141 }
142 }
143 }
144
disappearing_behavior(item_t * fireball,brick_list_t * brick_list)145 void disappearing_behavior(item_t *fireball, brick_list_t *brick_list)
146 {
147 actor_t *act = fireball->actor;
148
149 actor_change_animation(act, sprite_get_animation("SD_FIREBALL", 1));
150 if(actor_animation_finished(act))
151 fireball->state = IS_DEAD;
152 }
153
smallfire_behavior(item_t * fireball,brick_list_t * brick_list)154 void smallfire_behavior(item_t *fireball, brick_list_t *brick_list)
155 {
156 float sqrsize = 2, diff = -2;
157 actor_t *act = fireball->actor;
158 brick_t *down;
159
160 /* movement & animation */
161 actor_move(act, actor_particle_movement(act, level_gravity()));
162 actor_change_animation(act, sprite_get_animation("SD_FIREBALL", 2));
163
164 /* collision detection */
165 actor_corners(act, sqrsize, diff, brick_list, NULL, NULL, NULL, NULL, &down, NULL, NULL, NULL);
166 actor_handle_clouds(act, diff, NULL, NULL, NULL, NULL, &down, NULL, NULL, NULL);
167 if(down && act->speed.y > 0.0f)
168 fireball->state = IS_DEAD;
169 }
170
171