2012-02-28 13:09:12 +01:00
/*! \file level.c
* \ brief Playable Level code .
*/
2012-03-04 13:32:42 +01:00
/*
* Copyright ( c ) Sebastian Krzyszkowiak < dos @ dosowisko . net >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
2012-02-22 12:43:14 +01:00
# include <stdio.h>
2012-05-20 14:40:49 +02:00
# include <math.h>
2012-05-20 18:07:24 +02:00
# include "levels/actions.h"
2012-04-06 17:28:38 +02:00
# include "moonwalk.h"
2012-04-06 18:25:04 +02:00
# include "config.h"
# include "pause.h"
2012-02-22 12:43:14 +01:00
# include "level.h"
2012-04-06 23:32:15 +02:00
# include "timeline.h"
2012-04-14 22:26:33 +02:00
/* TODO: check if spritesheet speed still depends on FPS */
2012-04-08 23:56:13 +02:00
2012-05-03 19:42:23 +02:00
void SelectDerpySpritesheet ( struct Game * game , char * name ) {
struct Spritesheet * tmp = game - > level . derpy_sheets ;
2012-05-19 21:50:01 +02:00
PrintConsole ( game , " Selecting Derpy spritesheet: %s " , name ) ;
2012-05-03 19:42:23 +02:00
if ( ! tmp ) {
PrintConsole ( game , " ERROR: No spritesheets registered for Derpy! " ) ;
return ;
}
while ( tmp ) {
if ( ! strcmp ( tmp - > name , name ) ) {
game - > level . derpy_sheet = & ( tmp - > bitmap ) ;
game - > level . sheet_rows = tmp - > rows ;
game - > level . sheet_cols = tmp - > cols ;
2012-05-08 13:22:56 +02:00
game - > level . sheet_blanks = tmp - > blanks ;
2012-05-03 19:42:23 +02:00
game - > level . sheet_speed_modifier = tmp - > speed ;
game - > level . sheet_pos = 0 ;
2012-05-10 12:21:53 +02:00
game - > level . sheet_scale = tmp - > scale ;
if ( game - > level . derpy ) al_destroy_bitmap ( game - > level . derpy ) ;
2012-05-19 21:50:01 +02:00
game - > level . derpy = al_create_bitmap ( ( al_get_display_height ( game - > display ) * 0.25 ) * tmp - > aspect * tmp - > scale , ( al_get_display_height ( game - > display ) * 0.25 ) * tmp - > scale ) ;
PrintConsole ( game , " SUCCESS: Derpy spritesheet activated: %s (%dx%d) " , name , al_get_bitmap_width ( game - > level . derpy ) , al_get_bitmap_height ( game - > level . derpy ) ) ;
2012-05-03 19:42:23 +02:00
return ;
}
tmp = tmp - > next ;
}
PrintConsole ( game , " ERROR: No spritesheets registered for Derpy with given name: %s " , name ) ;
return ;
}
void RegisterDerpySpritesheet ( struct Game * game , char * name ) {
char filename [ 255 ] = { } ;
sprintf ( filename , " data/levels/derpy/%s.ini " , name ) ;
ALLEGRO_CONFIG * config = al_load_config_file ( filename ) ;
struct Spritesheet * s = malloc ( sizeof ( struct Spritesheet ) ) ;
s - > name = malloc ( ( strlen ( name ) + 1 ) * sizeof ( char ) ) ;
strcpy ( s - > name , name ) ;
s - > bitmap = NULL ;
s - > cols = atoi ( al_get_config_value ( config , " " , " cols " ) ) ;
s - > rows = atoi ( al_get_config_value ( config , " " , " rows " ) ) ;
2012-05-08 13:22:56 +02:00
s - > blanks = atoi ( al_get_config_value ( config , " " , " blanks " ) ) ;
2012-05-03 19:42:23 +02:00
s - > speed = atof ( al_get_config_value ( config , " " , " speed " ) ) ;
2012-05-08 13:22:56 +02:00
s - > aspect = atof ( al_get_config_value ( config , " " , " aspect " ) ) ;
s - > scale = atof ( al_get_config_value ( config , " " , " scale " ) ) ;
2012-05-03 19:42:23 +02:00
s - > next = game - > level . derpy_sheets ;
game - > level . derpy_sheets = s ;
al_destroy_config ( config ) ;
2012-05-19 21:50:01 +02:00
PrintConsole ( game , " Registering Derpy spritesheet: %s " , name ) ;
2012-05-03 19:42:23 +02:00
}
2012-04-06 18:25:04 +02:00
void Level_Passed ( struct Game * game ) {
if ( game - > level . current_level < 6 ) {
int available = atoi ( GetConfigOptionDefault ( " MuffinAttack " , " level " , " 1 " ) ) ;
available + + ;
if ( ( available < 2 ) | | ( available > 7 ) ) available = 1 ;
if ( available = = ( game - > level . current_level + 1 ) ) {
char * text = malloc ( 2 * sizeof ( char ) ) ;
sprintf ( text , " %d " , available ) ;
SetConfigOption ( " MuffinAttack " , " level " , text ) ;
free ( text ) ;
}
} else {
SetConfigOption ( " MuffinAttack " , " completed " , " 1 " ) ;
}
}
2012-02-22 12:43:14 +01:00
void Level_Draw ( struct Game * game ) {
2012-05-07 20:17:35 +02:00
if ( ! al_get_sample_instance_playing ( game - > level . music ) & & ( game - > loadstate = = GAMESTATE_LEVEL ) ) {
2012-04-09 15:25:56 +02:00
al_set_sample_instance_playing ( game - > level . music , true ) ;
al_set_sample_instance_position ( game - > level . music , game - > level . music_pos ) ;
}
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_Draw ( game ) ;
else {
2012-05-07 20:17:35 +02:00
2012-04-09 15:58:01 +02:00
struct ALLEGRO_KEYBOARD_STATE keyboard ;
al_get_keyboard_state ( & keyboard ) ;
if ( game - > level . handle_input ) {
if ( al_key_down ( & keyboard , ALLEGRO_KEY_UP ) ) {
2012-05-18 13:12:58 +02:00
game - > level . derpy_y - = tps ( game , 60 * 0.0075 ) ;
2012-04-14 22:26:33 +02:00
/*PrintConsole(game, "Derpy Y position: %f", game->level.derpy_y);*/
2012-05-07 20:17:35 +02:00
}
2012-04-09 15:58:01 +02:00
if ( al_key_down ( & keyboard , ALLEGRO_KEY_DOWN ) ) {
2012-05-18 13:12:58 +02:00
game - > level . derpy_y + = tps ( game , 60 * 0.0075 ) ;
2012-04-14 22:26:33 +02:00
/*PrintConsole(game, "Derpy Y position: %f", game->level.derpy_y);*/
2012-04-09 15:58:01 +02:00
}
2012-05-18 13:12:58 +02:00
/*if ((game->level.derpy_y > 0.6) && (game->level.flying)) {
2012-05-08 13:22:56 +02:00
SelectDerpySpritesheet ( game , " run " ) ;
game - > level . flying = false ;
game - > level . sheet_speed = tps ( game , 60 * 0.0020 / game - > level . speed ) ;
}
2012-05-10 12:21:53 +02:00
else if ( ( game - > level . derpy_y < = 0.6 ) & & ( ! game - > level . flying ) ) {
2012-05-08 13:22:56 +02:00
SelectDerpySpritesheet ( game , " fly " ) ;
game - > level . flying = true ;
game - > level . sheet_speed = tps ( game , 60 * 2.4 ) ;
2012-05-19 18:48:29 +02:00
}
if ( ! game - > level . flying ) game - > level . sheet_speed = tps ( game , 60 * 0.0020 / game - > level . speed ) ; */
2012-04-09 16:14:10 +02:00
if ( game - > level . derpy_y < 0 ) game - > level . derpy_y = 0 ;
2012-05-10 12:21:53 +02:00
else if ( game - > level . derpy_y > 0.8 ) game - > level . derpy_y = 0.8 ;
2012-04-09 15:58:01 +02:00
}
2012-05-07 20:17:35 +02:00
2012-04-08 19:01:30 +02:00
al_draw_bitmap ( game - > level . clouds , ( - game - > level . cl_pos ) * al_get_bitmap_width ( game - > level . clouds ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . clouds , ( 1 + ( - game - > level . cl_pos ) ) * al_get_bitmap_width ( game - > level . clouds ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . background , ( - game - > level . bg_pos ) * al_get_bitmap_width ( game - > level . background ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . background , ( 1 + ( - game - > level . bg_pos ) ) * al_get_bitmap_width ( game - > level . background ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . stage , ( - game - > level . st_pos ) * al_get_bitmap_width ( game - > level . stage ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . stage , ( 1 + ( - game - > level . st_pos ) ) * al_get_bitmap_width ( game - > level . stage ) , 0 , 0 ) ;
2012-05-07 20:17:35 +02:00
2012-05-03 02:49:08 +02:00
int derpyx = game - > level . derpy_x * al_get_display_width ( game - > display ) ;
int derpyy = game - > level . derpy_y * al_get_display_height ( game - > display ) ;
int derpyw = al_get_bitmap_width ( game - > level . derpy ) ;
int derpyh = al_get_bitmap_height ( game - > level . derpy ) ;
2012-05-19 18:48:29 +02:00
int derpyo = al_get_display_width ( game - > display ) * 0.1953125 - al_get_bitmap_width ( game - > level . derpy ) ; /* offset */
2012-05-03 02:49:08 +02:00
bool colision = false ;
2012-05-19 15:31:41 +02:00
struct Obstacle * tmp = game - > level . obstacles ;
2012-05-01 22:52:30 +02:00
while ( tmp ) {
/*PrintConsole(game, "DRAWING %f %f", tmp->x, tmp->y);*/
2012-05-20 14:40:49 +02:00
int x = ( tmp - > x / 100.0 ) * al_get_display_width ( game - > display ) ;
int y = ( tmp - > y / 100.0 ) * al_get_display_height ( game - > display ) ;
2012-05-20 20:05:03 +02:00
int w = 0 , h = 0 ;
if ( tmp - > bitmap ) {
w = al_get_bitmap_width ( * ( tmp - > bitmap ) ) / tmp - > cols ;
h = al_get_bitmap_height ( * ( tmp - > bitmap ) ) / tmp - > rows ;
}
2012-05-20 14:40:49 +02:00
if ( x > - w ) {
2012-05-20 18:07:24 +02:00
/*if (!tmp->hit)*/
2012-05-21 21:17:58 +02:00
if ( ( ( ( x > = derpyx + 0.38 * derpyw + derpyo ) & & ( x < = derpyx + 0.94 * derpyw + derpyo ) ) | | ( ( x + w > = derpyx + 0.38 * derpyw + derpyo ) & & ( x + w < = derpyx + 0.94 * derpyw + derpyo ) ) | | ( ( x < = derpyx + 0.38 * derpyw + derpyo ) & & ( x + w > = derpyx + 0.94 * derpyw + derpyo ) ) ) & &
( ( ( y > = derpyy + 0.26 * derpyh ) & & ( y < = derpyy + 0.76 * derpyh ) ) | | ( ( y + h > = derpyy + 0.26 * derpyh ) & & ( y + h < = derpyy + 0.76 * derpyh ) ) | | ( ( y < = derpyy + 0.26 * derpyh ) & & ( y + h > = derpyy + 0.76 * derpyh ) ) ) ) {
2012-05-18 13:12:58 +02:00
tmp - > hit = true ;
}
2012-05-20 14:40:49 +02:00
2012-05-21 14:00:42 +02:00
if ( tmp - > bitmap ) {
ALLEGRO_BITMAP * subbitmap = al_create_sub_bitmap ( * ( tmp - > bitmap ) , w * ( tmp - > pos % tmp - > cols ) , h * ( tmp - > pos / tmp - > cols ) , w , h ) ;
al_draw_rotated_bitmap ( subbitmap , w / 2.0 , h / 2.0 , x + w / 2.0 , y + h / 2.0 , tmp - > angle , 0 ) ;
al_destroy_bitmap ( subbitmap ) ;
}
2012-05-20 14:40:49 +02:00
if ( tmp - > anim_speed ) {
tmp - > tmp_pos + = tps ( game , 60 ) ;
if ( tmp - > tmp_pos > = tmp - > anim_speed ) {
tmp - > pos + + ;
tmp - > tmp_pos = 0 ;
}
if ( tmp - > pos > = tmp - > cols * tmp - > rows - tmp - > blanks ) tmp - > pos = 0 ;
}
/*al_draw_bitmap(*(tmp->bitmap), x, y, 0);*/
2012-05-19 18:48:29 +02:00
if ( game - > level . debug_show_sprite_frames ) al_draw_rectangle ( x , y , x + w , y + h , al_map_rgba ( 255 , 0 , 0 , 255 ) , 3 ) ;
2012-05-20 18:07:24 +02:00
if ( tmp - > hit ) {
2012-05-20 20:05:03 +02:00
if ( tmp - > points < 0 ) colision = true ;
else tmp - > bitmap = NULL ;
2012-05-20 18:07:24 +02:00
game - > level . hp + = tps ( game , 60 * 0.0002 * tmp - > points * ( ( ( 1 - game - > level . speed_modifier ) / 2.0 ) + 1 ) ) ;
2012-05-20 20:05:03 +02:00
if ( game - > level . hp > 1 ) game - > level . hp = 1 ;
2012-05-20 18:07:24 +02:00
PrintConsole ( game , " POINTS: %d, %f " , tmp - > points , tps ( game , 60 * 0.0002 * tmp - > points * game - > level . speed_modifier ) ) ;
if ( ( game - > level . hp < = 0 ) & & ( ! game - > level . failed ) ) {
game - > level . failed = true ;
2012-05-20 20:05:03 +02:00
game - > level . handle_input = false ;
game - > level . speed_modifier = 1 ;
2012-05-20 18:07:24 +02:00
TM_AddBackgroundAction ( & LevelFailed , NULL , 0 , " levelfailed " ) ;
}
}
2012-05-20 23:17:52 +02:00
tmp - > x - = tps ( game , game - > level . speed * game - > level . speed_modifier * 60 * tmp - > speed ) * 100 * al_get_bitmap_width ( game - > level . stage ) / ( float ) al_get_display_width ( game - > display ) ;
2012-05-03 02:19:55 +02:00
if ( tmp - > callback ) tmp - > callback ( game , tmp ) ;
2012-05-03 02:49:08 +02:00
tmp = tmp - > next ;
2012-05-01 22:52:30 +02:00
} else {
2012-05-03 02:49:08 +02:00
if ( tmp - > next )
tmp - > next - > prev = tmp - > prev ;
if ( tmp - > prev )
tmp - > prev - > next = tmp - > next ;
else
2012-05-19 15:31:41 +02:00
game - > level . obstacles = tmp - > next ;
struct Obstacle * t = tmp ;
2012-05-03 02:49:08 +02:00
tmp = tmp - > next ;
free ( t ) ;
2012-05-01 22:52:30 +02:00
}
}
2012-05-20 18:07:24 +02:00
/*if (colision) game->level.hp-=tps(game, 60*0.002);*/
2012-05-07 20:17:35 +02:00
2012-04-08 23:25:14 +02:00
al_set_target_bitmap ( game - > level . derpy ) ;
al_clear_to_color ( al_map_rgba ( 0 , 0 , 0 , 0 ) ) ;
2012-05-03 19:42:23 +02:00
al_draw_bitmap_region ( * ( game - > level . derpy_sheet ) , al_get_bitmap_width ( game - > level . derpy ) * ( game - > level . sheet_pos % game - > level . sheet_cols ) , al_get_bitmap_height ( game - > level . derpy ) * ( game - > level . sheet_pos / game - > level . sheet_cols ) , al_get_bitmap_width ( game - > level . derpy ) , al_get_bitmap_height ( game - > level . derpy ) , 0 , 0 , 0 ) ;
2012-05-03 19:59:53 +02:00
if ( ( game - > level . sheet_speed ) & & ( game - > level . sheet_speed_modifier ) ) {
2012-04-14 22:26:33 +02:00
game - > level . sheet_tmp + = tps ( game , 60 ) ;
2012-05-19 22:38:13 +02:00
if ( game - > level . sheet_tmp > = ( game - > level . sheet_speed / game - > level . speed_modifier ) / game - > level . sheet_speed_modifier ) {
2012-04-14 22:26:33 +02:00
game - > level . sheet_pos + + ;
game - > level . sheet_tmp = 0 ;
}
2012-05-08 13:22:56 +02:00
if ( game - > level . sheet_pos > = game - > level . sheet_cols * game - > level . sheet_rows - game - > level . sheet_blanks ) game - > level . sheet_pos = 0 ;
2012-04-08 23:25:14 +02:00
}
al_set_target_bitmap ( al_get_backbuffer ( game - > display ) ) ;
2012-05-08 13:22:56 +02:00
al_draw_tinted_bitmap ( game - > level . derpy , al_map_rgba ( 255 , 255 - colision * 255 , 255 - colision * 255 , 255 ) , derpyx + al_get_display_width ( game - > display ) * 0.1953125 - al_get_bitmap_width ( game - > level . derpy ) , derpyy , 0 ) ;
2012-05-04 01:12:19 +02:00
2012-05-19 18:48:29 +02:00
/* if ((((x>=derpyx+0.36*derpyw) && (x<=derpyx+0.94*derpyw)) || ((x+w>=derpyx+0.36*derpyw) && (x+w<=derpyx+0.94*derpyw))) &&
( ( ( y > = derpyy + 0.26 * derpyh ) & & ( y < = derpyy + 0.76 * derpyh ) ) | | ( ( y + h > = derpyy + 0.26 * derpyh ) & & ( y + h < = derpyy + 0.76 * derpyh ) ) ) ) {
*/
if ( game - > level . debug_show_sprite_frames ) {
al_draw_rectangle ( derpyx + derpyo , derpyy , derpyx + derpyw + derpyo , derpyy + derpyh , al_map_rgba ( 0 , 255 , 0 , 255 ) , 3 ) ;
al_draw_rectangle ( derpyx + 0.38 * derpyw + derpyo , derpyy + 0.26 * derpyh , derpyx + 0.94 * derpyw + derpyo , derpyy + 0.76 * derpyh , al_map_rgba ( 0 , 0 , 255 , 255 ) , 3 ) ;
}
2012-04-08 19:01:30 +02:00
al_draw_bitmap ( game - > level . foreground , ( - game - > level . fg_pos ) * al_get_bitmap_width ( game - > level . foreground ) , 0 , 0 ) ;
al_draw_bitmap ( game - > level . foreground , ( 1 + ( - game - > level . fg_pos ) ) * al_get_bitmap_width ( game - > level . foreground ) , 0 , 0 ) ;
2012-05-04 01:12:19 +02:00
2012-04-08 19:01:30 +02:00
if ( game - > level . speed > 0 ) {
2012-05-19 22:38:13 +02:00
game - > level . cl_pos + = tps ( game , 60 * game - > level . speed * game - > level . speed_modifier ) * 0.2 ;
game - > level . bg_pos + = tps ( game , 60 * game - > level . speed * game - > level . speed_modifier ) * 0.6 ;
game - > level . st_pos + = tps ( game , 60 * game - > level . speed * game - > level . speed_modifier ) * 1 ;
game - > level . fg_pos + = tps ( game , 60 * game - > level . speed * game - > level . speed_modifier ) * 1.75 ;
2012-04-09 18:11:09 +02:00
if ( game - > level . bg_pos > = 1 ) game - > level . bg_pos = game - > level . bg_pos - 1 ;
if ( game - > level . st_pos > = 1 ) game - > level . st_pos = game - > level . st_pos - 1 ;
if ( game - > level . fg_pos > = 1 ) game - > level . fg_pos = game - > level . fg_pos - 1 ;
2012-04-08 19:01:30 +02:00
}
2012-04-09 18:11:09 +02:00
game - > level . cl_pos + = tps ( game , 60 * 0.00005 ) ;
if ( game - > level . cl_pos > = 1 ) game - > level . cl_pos = game - > level . cl_pos - 1 ;
2012-05-07 20:17:35 +02:00
2012-05-09 10:58:45 +02:00
al_set_target_bitmap ( game - > level . meter_bmp ) ;
2012-05-09 12:40:21 +02:00
al_clear_to_color ( al_map_rgba ( 0 , 0 , 0 , 0 ) ) ;
2012-05-18 22:07:35 +02:00
al_draw_filled_rounded_rectangle ( al_get_bitmap_width ( game - > level . meter_bmp ) * 0.1 , al_get_bitmap_height ( game - > level . meter_bmp ) * 0.34 , al_get_bitmap_width ( game - > level . meter_bmp ) * 0.993 , al_get_bitmap_height ( game - > level . meter_bmp ) * 0.66 ,
6 , 6 , al_map_rgb ( 232 , 234 , 239 ) ) ;
2012-05-17 00:18:19 +02:00
al_draw_horizontal_gradient_rect ( al_get_bitmap_width ( game - > level . meter_bmp ) - al_get_display_width ( game - > display ) * 0.215 , ( al_get_bitmap_height ( game - > level . meter_bmp ) - al_get_display_height ( game - > display ) * 0.025 ) / 2 , al_get_display_width ( game - > display ) * 0.215 * 0.975 , al_get_display_height ( game - > display ) * 0.025 , al_map_rgb ( 150 , 159 , 182 ) , al_map_rgb ( 130 , 139 , 162 ) ) ;
al_draw_filled_rectangle ( al_get_bitmap_width ( game - > level . meter_bmp ) - al_get_display_width ( game - > display ) * 0.215 , ( al_get_bitmap_height ( game - > level . meter_bmp ) - al_get_display_height ( game - > display ) * 0.025 ) / 2 , al_get_bitmap_width ( game - > level . meter_bmp ) - al_get_display_width ( game - > display ) * 0.215 + ( al_get_display_width ( game - > display ) * 0.215 * 0.975 ) * game - > level . hp , ( al_get_bitmap_height ( game - > level . meter_bmp ) - al_get_display_height ( game - > display ) * 0.025 ) / 2 + al_get_display_height ( game - > display ) * 0.025 , al_map_rgb ( 214 , 172 , 55 ) ) ;
2012-05-09 12:40:21 +02:00
al_draw_bitmap ( game - > level . meter_image , 0 , 0 , 0 ) ;
2012-05-09 10:58:45 +02:00
al_set_target_bitmap ( al_get_backbuffer ( game - > display ) ) ;
2012-05-17 00:18:19 +02:00
2012-05-09 12:40:21 +02:00
al_draw_tinted_bitmap ( game - > level . meter_bmp , al_map_rgba ( game - > level . meter_alpha , game - > level . meter_alpha , game - > level . meter_alpha , game - > level . meter_alpha ) , al_get_display_width ( game - > display ) * 0.95 - al_get_bitmap_width ( game - > level . meter_bmp ) , al_get_display_height ( game - > display ) * 0.975 - al_get_bitmap_height ( game - > level . meter_bmp ) , 0 ) ;
2012-05-09 10:58:45 +02:00
2012-04-06 23:32:15 +02:00
TM_Process ( ) ;
2012-04-06 18:25:04 +02:00
}
2012-02-22 12:43:14 +01:00
}
void Level_Load ( struct Game * game ) {
2012-05-19 01:20:52 +02:00
game - > level . failed = false ;
2012-05-17 00:18:19 +02:00
game - > level . hp = 1 ;
2012-04-08 19:01:30 +02:00
game - > level . cl_pos = 0 ;
game - > level . bg_pos = 0 ;
game - > level . fg_pos = 0.2 ;
game - > level . st_pos = 0.1 ;
2012-04-08 23:25:14 +02:00
game - > level . speed = 0 ;
2012-05-19 22:38:13 +02:00
game - > level . speed_modifier = 1 ;
2012-04-08 23:25:14 +02:00
game - > level . derpy_x = - 0.2 ;
game - > level . derpy_y = 0.6 ;
2012-05-08 13:22:56 +02:00
game - > level . sheet_speed = tps ( game , 60 * 2.4 ) ;
2012-04-08 23:25:14 +02:00
game - > level . sheet_tmp = 0 ;
2012-04-08 23:41:22 +02:00
game - > level . handle_input = false ;
2012-05-19 15:31:41 +02:00
game - > level . obstacles = NULL ;
2012-05-09 10:58:45 +02:00
game - > level . meter_alpha = 0 ;
2012-05-19 18:48:29 +02:00
game - > level . debug_show_sprite_frames = false ;
2012-04-06 23:32:15 +02:00
al_clear_to_color ( al_map_rgb ( 0 , 0 , 0 ) ) ;
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_Load ( game ) ;
2012-04-06 23:32:15 +02:00
else {
TM_Init ( game ) ;
2012-04-09 17:17:16 +02:00
TM_AddBackgroundAction ( & FadeIn , NULL , 0 , " fadein " ) ;
2012-04-08 23:25:14 +02:00
TM_AddDelay ( 1000 ) ;
2012-04-09 17:17:16 +02:00
TM_AddQueuedBackgroundAction ( & Welcome , NULL , 0 , " welcome " ) ;
2012-04-09 15:25:56 +02:00
TM_AddDelay ( 1000 ) ;
2012-04-09 17:17:16 +02:00
TM_AddAction ( & Walk , NULL , " walk " ) ;
TM_AddAction ( & Move , NULL , " move " ) ;
TM_AddAction ( & Stop , NULL , " stop " ) ;
2012-04-09 16:21:45 +02:00
TM_AddDelay ( 1000 ) ;
2012-04-09 17:17:16 +02:00
TM_AddAction ( & Letter , NULL , " letter " ) ;
2012-05-18 13:12:58 +02:00
TM_AddDelay ( 200 ) ;
2012-04-09 17:17:16 +02:00
TM_AddQueuedBackgroundAction ( & Accelerate , NULL , 0 , " accelerate " ) ;
TM_AddAction ( & Fly , NULL , " fly " ) ;
2012-05-21 20:56:16 +02:00
TM_AddDelay ( 500 ) ;
2012-04-14 22:26:33 +02:00
/* first part gameplay goes here */
2012-04-30 00:55:27 +02:00
2012-05-19 15:31:41 +02:00
/* actions for generating obstacles should go here
2012-04-30 00:55:27 +02:00
* probably as regular actions . When one ends , harder one
2012-05-21 20:56:16 +02:00
* begins . After last one part with muffins starts . */
2012-05-19 15:31:41 +02:00
TM_AddAction ( & GenerateObstacles , NULL , " obstacles " ) ;
2012-05-21 20:56:16 +02:00
TM_AddDelay ( 3 * 1000 ) ;
/* wings disappear, deccelerate */
TM_AddAction ( & Run , NULL , " run " ) ;
TM_AddDelay ( 3 * 1000 ) ;
/* show Fluttershy's house
2012-05-07 20:17:35 +02:00
2012-04-08 23:25:14 +02:00
// second part gameplay goes here
2012-05-07 20:17:35 +02:00
2012-05-21 20:56:16 +02:00
// cutscene goes here */
2012-04-09 17:17:16 +02:00
TM_AddAction ( & PassLevel , NULL , " passlevel " ) ;
2012-05-20 23:17:52 +02:00
struct Obstacle * obst = malloc ( sizeof ( struct Obstacle ) ) ;
obst - > prev = NULL ;
obst - > next = NULL ;
obst - > x = 83.5 ;
obst - > y = 55 ;
obst - > speed = 1 ;
obst - > points = 0 ;
obst - > hit = false ;
obst - > rows = 1 ;
obst - > cols = 1 ;
obst - > pos = 0 ;
obst - > blanks = 0 ;
obst - > anim_speed = 0 ;
obst - > tmp_pos = 0 ;
obst - > callback = NULL ;
obst - > data = NULL ;
obst - > bitmap = & ( game - > level . owl ) ;
game - > level . obstacles = obst ;
2012-04-06 23:32:15 +02:00
}
2012-02-22 12:43:14 +01:00
}
2012-02-25 22:26:31 +01:00
2012-02-22 12:43:14 +01:00
int Level_Keydown ( struct Game * game , ALLEGRO_EVENT * ev ) {
2012-04-09 15:25:56 +02:00
if ( ev - > keyboard . keycode = = ALLEGRO_KEY_ESCAPE ) {
game - > level . music_pos = al_get_sample_instance_position ( game - > level . music ) ;
al_set_sample_instance_playing ( game - > level . music , false ) ;
2012-05-18 22:07:35 +02:00
} else if ( ( game - > debug ) & & ( ev - > keyboard . keycode = = ALLEGRO_KEY_F2 ) ) {
game - > level . hp - = 0.1 ;
if ( game - > level . hp < = 0 ) game - > level . hp = 0.001 ;
2012-05-19 18:48:29 +02:00
} else if ( ( game - > debug ) & & ( ev - > keyboard . keycode = = ALLEGRO_KEY_F3 ) ) {
2012-05-18 22:07:35 +02:00
game - > level . hp + = 0.1 ;
if ( game - > level . hp > 1 ) game - > level . hp = 1 ;
2012-05-19 18:48:29 +02:00
} else if ( ( game - > debug ) & & ( ev - > keyboard . keycode = = ALLEGRO_KEY_F4 ) ) {
game - > level . debug_show_sprite_frames = ! game - > level . debug_show_sprite_frames ;
2012-04-09 15:25:56 +02:00
}
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_Keydown ( game , ev ) ;
2012-05-19 22:38:13 +02:00
else if ( game - > level . handle_input ) {
if ( ev - > keyboard . keycode = = ALLEGRO_KEY_LEFT ) {
game - > level . speed_modifier = 0.75 ;
} else if ( ev - > keyboard . keycode = = ALLEGRO_KEY_RIGHT ) {
game - > level . speed_modifier = 1.3 ;
}
}
2012-04-06 18:25:04 +02:00
if ( ev - > keyboard . keycode = = ALLEGRO_KEY_ESCAPE ) {
game - > gamestate = GAMESTATE_PAUSE ;
game - > loadstate = GAMESTATE_LEVEL ;
Pause_Load ( game ) ;
}
return 0 ;
2012-03-08 22:21:02 +01:00
}
2012-04-06 23:32:15 +02:00
void Level_ProcessLogic ( struct Game * game , ALLEGRO_EVENT * ev ) {
2012-05-19 22:38:13 +02:00
if ( game - > level . handle_input ) {
if ( ( ev - > type = = ALLEGRO_EVENT_KEY_UP ) & & ( ev - > keyboard . keycode = = ALLEGRO_KEY_LEFT ) ) {
game - > level . speed_modifier = 1 ;
struct ALLEGRO_KEYBOARD_STATE keyboard ;
al_get_keyboard_state ( & keyboard ) ;
if ( al_key_down ( & keyboard , ALLEGRO_KEY_RIGHT ) ) {
game - > level . speed_modifier = 1.3 ;
}
} else if ( ( ev - > type = = ALLEGRO_EVENT_KEY_UP ) & & ( ev - > keyboard . keycode = = ALLEGRO_KEY_RIGHT ) ) {
game - > level . speed_modifier = 1 ;
struct ALLEGRO_KEYBOARD_STATE keyboard ;
al_get_keyboard_state ( & keyboard ) ;
if ( al_key_down ( & keyboard , ALLEGRO_KEY_LEFT ) ) {
game - > level . speed_modifier = 0.75 ;
}
}
}
2012-04-06 23:32:15 +02:00
if ( game - > level . current_level = = 1 ) TM_HandleEvent ( ev ) ;
}
2012-05-18 18:34:07 +02:00
void Level_Preload ( struct Game * game , void ( * progress ) ( struct Game * , float ) ) {
2012-05-03 19:42:23 +02:00
game - > level . derpy_sheets = NULL ;
2012-05-10 12:21:53 +02:00
game - > level . derpy = NULL ;
2012-04-06 18:25:04 +02:00
Pause_Preload ( game ) ;
2012-05-03 19:42:23 +02:00
RegisterDerpySpritesheet ( game , " walk " ) ;
RegisterDerpySpritesheet ( game , " fly " ) ;
RegisterDerpySpritesheet ( game , " run " ) ;
RegisterDerpySpritesheet ( game , " stand " ) ;
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_Preload ( game ) ;
2012-04-09 15:25:56 +02:00
else {
game - > level . sample = al_load_sample ( " data/levels/1/music.flac " ) ;
game - > level . music = al_create_sample_instance ( game - > level . sample ) ;
al_attach_sample_instance_to_mixer ( game - > level . music , game - > audio . music ) ;
al_set_sample_instance_playmode ( game - > level . music , ALLEGRO_PLAYMODE_LOOP ) ;
if ( ! game - > level . sample ) {
fprintf ( stderr , " Audio clip sample not loaded! \n " ) ;
exit ( - 1 ) ;
}
}
2012-05-18 18:34:07 +02:00
Level_PreloadBitmaps ( game , progress ) ;
2012-04-06 17:28:38 +02:00
}
2012-03-08 22:21:02 +01:00
2012-04-06 17:28:38 +02:00
void Level_Unload ( struct Game * game ) {
2012-04-06 18:25:04 +02:00
Pause_Unload_Real ( game ) ;
2012-04-09 15:25:56 +02:00
al_destroy_sample_instance ( game - > level . music ) ;
al_destroy_sample ( game - > level . sample ) ;
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_Unload ( game ) ;
2012-04-06 23:32:15 +02:00
else {
TM_Destroy ( ) ;
}
2012-05-19 15:31:41 +02:00
struct Obstacle * t = game - > level . obstacles ;
2012-05-03 19:42:23 +02:00
if ( t ) {
while ( t - > next ) {
if ( t - > prev ) free ( t - > prev ) ;
t = t - > next ;
}
free ( t ) ;
2012-05-01 22:52:30 +02:00
}
2012-04-08 19:01:30 +02:00
Level_UnloadBitmaps ( game ) ;
2012-05-03 19:42:23 +02:00
struct Spritesheet * tmp , * s = game - > level . derpy_sheets ;
tmp = s ;
while ( s ) {
tmp = s ;
s = s - > next ;
free ( tmp ) ;
}
2012-02-22 12:43:14 +01:00
}
2012-02-25 22:26:31 +01:00
2012-03-08 22:21:02 +01:00
void Level_UnloadBitmaps ( struct Game * game ) {
2012-04-08 23:25:14 +02:00
al_destroy_bitmap ( game - > level . derpy ) ;
2012-05-03 19:42:23 +02:00
struct Spritesheet * tmp = game - > level . derpy_sheets ;
while ( tmp ) {
al_destroy_bitmap ( tmp - > bitmap ) ;
tmp = tmp - > next ;
}
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_UnloadBitmaps ( game ) ;
2012-04-08 19:01:30 +02:00
else {
al_destroy_bitmap ( game - > level . foreground ) ;
al_destroy_bitmap ( game - > level . background ) ;
al_destroy_bitmap ( game - > level . stage ) ;
al_destroy_bitmap ( game - > level . clouds ) ;
2012-04-08 23:25:14 +02:00
al_destroy_bitmap ( game - > level . welcome ) ;
2012-05-22 21:29:55 +02:00
al_destroy_bitmap ( game - > level . letter ) ;
al_destroy_bitmap ( game - > level . owl ) ;
al_destroy_bitmap ( game - > level . obst_bmps . pie1 ) ;
al_destroy_bitmap ( game - > level . obst_bmps . pie2 ) ;
al_destroy_bitmap ( game - > level . obst_bmps . pig ) ;
2012-05-23 10:34:36 +02:00
al_destroy_bitmap ( game - > level . obst_bmps . cherry ) ;
2012-05-22 21:29:55 +02:00
al_destroy_bitmap ( game - > level . obst_bmps . muffin ) ;
al_destroy_bitmap ( game - > level . obst_bmps . badmuffin ) ;
al_destroy_bitmap ( game - > level . obst_bmps . screwball ) ;
2012-05-09 10:58:45 +02:00
al_destroy_bitmap ( game - > level . meter_bmp ) ;
2012-05-09 12:40:21 +02:00
al_destroy_bitmap ( game - > level . meter_image ) ;
2012-04-08 19:01:30 +02:00
}
2012-03-08 22:21:02 +01:00
}
2012-05-18 18:34:07 +02:00
void Level_PreloadBitmaps ( struct Game * game , void ( * progress ) ( struct Game * , float ) ) {
2012-05-23 10:34:36 +02:00
PROGRESS_INIT ( 18 ) ;
2012-05-18 18:34:07 +02:00
int x = 0 ;
2012-05-03 19:42:23 +02:00
struct Spritesheet * tmp = game - > level . derpy_sheets ;
2012-05-18 18:34:07 +02:00
while ( tmp ) {
x + + ;
tmp = tmp - > next ;
}
if ( game - > level . current_level = = 1 ) load_a + = x ;
else load_a = 2 + x ;
tmp = game - > level . derpy_sheets ;
2012-05-03 19:42:23 +02:00
while ( tmp ) {
char filename [ 255 ] = { } ;
sprintf ( filename , " levels/derpy/%s.png " , tmp - > name ) ;
2012-05-19 21:50:01 +02:00
tmp - > bitmap = LoadScaledBitmap ( filename , ( int ) ( al_get_display_height ( game - > display ) * 0.25 * tmp - > aspect * tmp - > scale ) * tmp - > cols , ( int ) ( al_get_display_height ( game - > display ) * 0.25 * tmp - > scale ) * tmp - > rows ) ;
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-05-03 19:42:23 +02:00
tmp = tmp - > next ;
}
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-05-10 12:21:53 +02:00
if ( ! game - > level . derpy ) SelectDerpySpritesheet ( game , " stand " ) ;
game - > level . derpy = al_create_bitmap ( al_get_bitmap_width ( * ( game - > level . derpy_sheet ) ) / game - > level . sheet_cols , al_get_bitmap_height ( * ( game - > level . derpy_sheet ) ) / game - > level . sheet_rows ) ;
2012-04-06 18:25:04 +02:00
if ( game - > level . current_level ! = 1 ) Moonwalk_PreloadBitmaps ( game ) ;
2012-04-08 19:01:30 +02:00
else {
2012-04-14 22:26:33 +02:00
/* TODO: handle strange display aspects */
2012-04-08 19:01:30 +02:00
game - > level . clouds = LoadScaledBitmap ( " levels/1/clouds.png " , al_get_display_height ( game - > display ) * 4.73307291666666666667 , al_get_display_height ( game - > display ) ) ;
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-04-08 19:01:30 +02:00
game - > level . foreground = LoadScaledBitmap ( " levels/1/foreground.png " , al_get_display_height ( game - > display ) * 4.73307291666666666667 , al_get_display_height ( game - > display ) ) ;
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-04-08 19:01:30 +02:00
game - > level . background = LoadScaledBitmap ( " levels/1/background.png " , al_get_display_height ( game - > display ) * 4.73307291666666666667 , al_get_display_height ( game - > display ) ) ;
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-04-08 19:01:30 +02:00
game - > level . stage = LoadScaledBitmap ( " levels/1/stage.png " , al_get_display_height ( game - > display ) * 4.73307291666666666667 , al_get_display_height ( game - > display ) ) ;
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-05-22 21:29:55 +02:00
game - > level . obst_bmps . pie1 = LoadScaledBitmap ( " levels/pie1.png " , al_get_display_width ( game - > display ) * 0.1 , al_get_display_height ( game - > display ) * 0.08 ) ;
PROGRESS ;
game - > level . obst_bmps . pie2 = LoadScaledBitmap ( " levels/pie2.png " , al_get_display_width ( game - > display ) * 0.1 , al_get_display_height ( game - > display ) * 0.08 ) ;
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-05-20 14:41:49 +02:00
game - > level . obst_bmps . pig = LoadScaledBitmap ( " levels/pig.png " , ( int ) ( al_get_display_width ( game - > display ) * 0.15 ) * 3 , ( int ) ( al_get_display_height ( game - > display ) * 0.2 ) * 3 ) ;
2012-05-20 14:40:49 +02:00
PROGRESS ;
2012-05-21 18:47:17 +02:00
game - > level . obst_bmps . screwball = LoadScaledBitmap ( " levels/screwball.png " , ( int ) ( al_get_display_height ( game - > display ) * 0.2 ) * 4 * 1.4 , ( int ) ( al_get_display_height ( game - > display ) * 0.2 ) * 4 ) ;
PROGRESS ;
2012-05-18 23:40:02 +02:00
game - > level . obst_bmps . muffin = LoadScaledBitmap ( " levels/muffin.png " , al_get_display_width ( game - > display ) * 0.07 , al_get_display_height ( game - > display ) * 0.1 ) ;
PROGRESS ;
2012-05-23 10:34:36 +02:00
game - > level . obst_bmps . cherry = LoadScaledBitmap ( " levels/cherry.png " , al_get_display_width ( game - > display ) * 0.03 , al_get_display_height ( game - > display ) * 0.08 ) ;
PROGRESS ;
2012-05-21 18:47:17 +02:00
game - > level . obst_bmps . badmuffin = LoadScaledBitmap ( " levels/badmuffin.png " , al_get_display_width ( game - > display ) * 0.07 , al_get_display_height ( game - > display ) * 0.1 ) ;
PROGRESS ;
2012-05-20 23:17:52 +02:00
game - > level . owl = LoadScaledBitmap ( " levels/owl.png " , al_get_display_width ( game - > display ) * 0.08 , al_get_display_width ( game - > display ) * 0.08 ) ;
PROGRESS ;
2012-05-22 21:29:55 +02:00
game - > level . letter = LoadScaledBitmap ( " levels/letter.png " , al_get_display_height ( game - > display ) , al_get_display_height ( game - > display ) ) ;
2012-05-21 22:27:49 +02:00
al_set_target_bitmap ( game - > level . letter ) ;
2012-05-22 21:46:51 +02:00
al_draw_text ( game - > menu . font , al_map_rgb ( 0 , 0 , 0 ) , al_get_bitmap_width ( game - > level . letter ) * 0.45 , al_get_display_height ( game - > display ) * 0.45 , ALLEGRO_ALIGN_CENTRE , " Letter from Twilight " ) ;
2012-05-21 22:27:49 +02:00
al_set_target_bitmap ( al_get_backbuffer ( game - > display ) ) ;
PROGRESS ;
2012-05-04 02:13:46 +02:00
game - > level . welcome = al_create_bitmap ( al_get_display_width ( game - > display ) , al_get_display_height ( game - > display ) / 2 ) ;
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-04-08 23:25:14 +02:00
al_set_target_bitmap ( game - > level . welcome ) ;
al_clear_to_color ( al_map_rgba ( 0 , 0 , 0 , 0 ) ) ;
al_draw_text_with_shadow ( game - > menu . font_title , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) * 0.5 , al_get_display_height ( game - > display ) * 0.1 , ALLEGRO_ALIGN_CENTRE , " Level 1 " ) ;
al_draw_text_with_shadow ( game - > menu . font_subtitle , al_map_rgb ( 255 , 255 , 255 ) , al_get_display_width ( game - > display ) * 0.5 , al_get_display_height ( game - > display ) * 0.275 , ALLEGRO_ALIGN_CENTRE , " Fluttershy " ) ;
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-05-09 10:58:45 +02:00
2012-05-09 12:40:21 +02:00
game - > level . meter_image = LoadScaledBitmap ( " levels/meter.png " , al_get_display_width ( game - > display ) * 0.075 , al_get_display_width ( game - > display ) * 0.075 * 0.96470588235294117647 ) ;
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-05-09 12:40:21 +02:00
game - > level . meter_bmp = al_create_bitmap ( al_get_display_width ( game - > display ) * 0.2 + al_get_bitmap_width ( game - > level . meter_image ) , al_get_bitmap_height ( game - > level . meter_image ) ) ;
al_set_target_bitmap ( al_get_backbuffer ( game - > display ) ) ;
2012-04-08 19:01:30 +02:00
}
2012-05-18 18:34:07 +02:00
PROGRESS ;
2012-02-22 12:43:14 +01:00
}