diff --git a/data/sprites/clover.png b/data/sprites/clover.png new file mode 100644 index 0000000..5c3e8e3 Binary files /dev/null and b/data/sprites/clover.png differ diff --git a/data/world1/level107.dat b/data/world1/level107.dat index db3186e..4808ac6 100644 --- a/data/world1/level107.dat +++ b/data/world1/level107.dat @@ -2,6 +2,7 @@ bgfile forest.png bg 0 hurryup 30 help +Jump in the direction of the logs... endhelp monsters 0 2 22 @@ -39,6 +40,7 @@ monsters 16 23 4 18 20 8 18 32 8 +14 6 22 endmonsters exitdir 1 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, @@ -55,15 +57,15 @@ exitdir 1 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, 4,1,1,1,1,1,1,1,1,1,1,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,4, -4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,20,20,20,4, +4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,20,20,20,20,4, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,9,9,9,1,0,0,0,0,0,0,0,0,4, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,4, -4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,9,9,9,1,0,0,0,4,4,4,4,4,11,11,11,11,0,0,0,0,4, +4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,9,9,9,1,0,0,0,4,4,4,4,4,11,11,11,11,0,20,20,20,4, 4,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,4, 4,0,0,0,0,0,0,0,0,0,2,9,9,9,1,0,0,0,4,4,4,4,4,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,4, 4,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,4,4,4,4,4,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,4, -4,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,4,4,4,4,4,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,4, +4,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,4,4,4,4,4,0,0,0,4,4,4,4,4,4,4,4,4,0,0,20,20,4, 4,1,1,1,1,1,1,1,1,1,4,4,4,4,4,0,0,0,4,4,4,4,4,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,43,0,0,0,42,4,4,4,43,0,0,0,42,4,4,4,4,4,4,4,43,0,0,0,0,4, 4,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, diff --git a/defs.h b/defs.h index a7aaaa5..3795095 100644 --- a/defs.h +++ b/defs.h @@ -42,6 +42,7 @@ #define TEXTSIZE_SCORE 14 #define TEXTSIZE_BONUS 20 #define TEXTSIZE_HELP 20 +#define TEXTSIZE_CLOVER 20 #define TEXTSIZE_DEATH 20 #define TEXTSIZE_TITLE 20 #define TEXTSIZE_LEVEL2 22 @@ -60,6 +61,9 @@ #define TT_NORM 0 #define TT_HELP 1 #define TT_HELPSHADOW 2 +#define TT_GAMEOVER 3 + +#define GAMEOVERWAIT 5 // # of seconds to wait before going back to title // text delays #define TEXTSPEED 2 // how fast text zooms in @@ -70,6 +74,7 @@ #define MULTIDELAY 50 #define HURRYDELAY 50 #define LIFEDELAY 50 +#define CLOVERDELAY 50 #define POKERMSGDELAY 80 #define LEVELWINDELAY 80 #define DIEDELAY 80 @@ -111,6 +116,8 @@ #define FLOODSPEED 4 // how fast flood effect acts +#define LUCKYFLASH 10 // how fast score flashes during lucky mode + #define MASKOFFSETX 8 #define MASKOFFSETY -12 @@ -276,7 +283,7 @@ #define S_SLOPE 2 // Sprite types -#define MAXPTYPES 118 +#define MAXPTYPES 119 #define P_PLAYER 0 #define P_RAT 1 #define P_CHEESE 2 @@ -400,6 +407,7 @@ #define P_CARDCK 115 #define P_MOVINGCARD 116 #define P_FIVECARDS 117 +#define P_CLOVER 118 // cards #define CARDFONTX 4 diff --git a/rc.c b/rc.c index 79e8c02..d84a417 100644 --- a/rc.c +++ b/rc.c @@ -39,15 +39,17 @@ int watertime; int playedbell; int clocktime; +int gameovertime; + int sprayalpha; // for spray effect +int gameover; + SDL_Surface *pausedtext, *pausedshadow; int paused; -//tiletype_t fakeblock; - -int skiplevels = 0; +int skiplevels; /* the order in which fruit will appear */ @@ -82,23 +84,22 @@ int gtime = 0; int fpsticks = 0; int fpsstart = 0; -int curworld = 1; +int curworld; int curlevelnum; int skipto = -1; // which level to skip to level_t *curlevel; -int levelcompletetime = -1; - -int oldlevelcomplete = -1; +int levelcompletetime; +int oldlevelcomplete; sprite_t *sprite = NULL; /* main sprite list */ -sprite_t *player; +sprite_t *player = NULL; sprite_t *lastsprite; sprite_t *lastmet; -int pokereffect = -1; -int pokerpoints = 0; +int pokereffect; +int pokerpoints; SDL_Color red = {255, 0, 0, 0}; @@ -109,6 +110,7 @@ SDL_Color cyan = {0, 255, 255, 0}; SDL_Color white = {255, 255, 255, 0}; SDL_Color grey = {210, 210, 210, 0}; SDL_Color green = {0, 255, 0, 0}; +SDL_Color green2 = {0, 150, 0, 0}; SDL_Color yellow = {255, 255, 0, 0}; int vidargs = 0; @@ -124,9 +126,6 @@ int main (int argc, char **argv) { int i; int *animtile; - curlevelnum = 1; - musicplaying = B_FALSE; - cheat = B_FALSE; levelbg = NULL; datadir = NULL; @@ -184,14 +183,6 @@ int main (int argc, char **argv) { return 1; } - // is we're skipping to a level, do so now - if (skipto >= 0) { - for (i = 0; i < numlevels; i++) { - if (levelentry[i].id == skipto) { - curlevelnum = i; - } - } - } /* fakeblock.id = T_LAND; @@ -242,409 +233,401 @@ int main (int argc, char **argv) { exit(1); } - shufflecards(); - - - // title screen - dotitlescreen(); - - - // load initial level - playmusic(normalmusic); - - if (loadlevel(curworld,curlevelnum, B_TRUE)) { - return 1; - } - - //levelcomplete = LV_FINAL; - curlevelnum-- ; // since nexlevel() will increment it - nextlevel(); - //drawlevel(); - flip(); - - timer = 0; - - player->invuln = INVULNTIME; - player->score = 0; - player->lives = 3; - forcegoodcard = B_FALSE; - nextforcegoodcard = B_FALSE; - - - /* generate images for "PAUSED" text */ pausedtext = TTF_RenderText_Solid(font[TEXTSIZE_PAUSED], "PAUSED", yellow); pausedshadow = TTF_RenderText_Solid(font[TEXTSIZE_PAUSED], "PAUSED", black); paused = B_FALSE; - // main loop - while (1) { - removeall(); - // check for sprite death and update moevment counters - checksprites(); - - /********************************************** - * check for end of level - */ - if (levelcomplete == LV_CLEAR) { - addoutlinetext(320,240,TEXTSIZE_LEVEL,"Level Complete!",&green,&black,LEVELWINDELAY, TT_NORM); - levelcomplete = LV_WAIT; - playfx(FX_WINLEVEL); - // turn off clock and water powerups - if (player->powerup == PW_CLOCK) { - Mix_ResumeMusic(); - player->powerup = B_FALSE; - } else if ((curlevel->iced == WATER_INPROGRESS) || (curlevel->iced == WATER_COMPLETE)) { - curlevel->iced = B_FALSE; - undoflood(); - } - } else if (levelcomplete == LV_WAIT) { - int mcount = 0; - sprite_t *s2; - - /* when all monsters have become fruits */ - for (s2 = sprite->next ; s2 ; s2 = s2->next) { - if (ismonster(s2->id)) { - if (s2->id != P_BLACKCLOUD) { - mcount++; - break; - } - } - } - if (mcount == 0) { - levelcompletetime = gtime; - levelcomplete = LV_FINAL; - } - } - - /********************************************** - * check for keypress or other input (joystick etc) - */ - handleinput(); + // outside loop + while (1) { + // title screen + if (!skipto) { + dotitlescreen(); + } + + // shuffle cards + shufflecards(); + + startgame(); + + // main loop + while (!gameover) { + removeall(); + + // check for sprite death and update moevment counters + checksprites(); - if (!paused) { /********************************************** - * Special effects #1 - ones which change the level by - * modifiying tiles, etc. + * check for end of level */ - if (player->powerup != PW_CLOCK) { - // for each animated tile on the level... - for (animtile = curlevel->animtiles; animtile && *animtile != -1; animtile++) { - int offset,numframes; - tiletype_t *tt; + if (levelcomplete == LV_CLEAR) { + addoutlinetext(320,240,TEXTSIZE_LEVEL,"Level Complete!",&green,&black,LEVELWINDELAY, TT_NORM); + levelcomplete = LV_WAIT; + playfx(FX_WINLEVEL); + // turn off clock and water powerups + if (player->powerup == PW_CLOCK) { + Mix_ResumeMusic(); + player->powerup = B_FALSE; + } else if ((curlevel->iced == WATER_INPROGRESS) || (curlevel->iced == WATER_COMPLETE)) { + curlevel->iced = B_FALSE; + undoflood(); + } + } else if (levelcomplete == LV_WAIT) { + int mcount = 0; + sprite_t *s2; - offset = *animtile; - - tt = gettile(curlevel->map[offset]); - - numframes = tt->numframes; - - // is it time to change frames? - if ((timer % tt->animspeed) == 0) { - // change its frame - curlevel->tileframe[offset]++; - if (curlevel->tileframe[offset] >= numframes) { - curlevel->tileframe[offset] = 0; + /* when all monsters have become fruits */ + for (s2 = sprite->next ; s2 ; s2 = s2->next) { + if (ismonster(s2->id)) { + if (s2->id != P_BLACKCLOUD) { + mcount++; + break; } - // redraw it - drawtile(temps, offset%LEVELW,offset/LEVELW); + } + } + if (mcount == 0) { + levelcompletetime = gtime; + levelcomplete = LV_FINAL; + } + } + + + /********************************************** + * check for keypress or other input (joystick etc) + */ + handleinput(); + + if (!paused) { + /********************************************** + * Special effects #1 - ones which change the level by + * modifiying tiles, etc. + */ + if (player->powerup != PW_CLOCK) { + // for each animated tile on the level... + for (animtile = curlevel->animtiles; animtile && *animtile != -1; animtile++) { + int offset,numframes; + tiletype_t *tt; + + offset = *animtile; + + tt = gettile(curlevel->map[offset]); + + numframes = tt->numframes; + + // is it time to change frames? + if ((timer % tt->animspeed) == 0) { + // change its frame + curlevel->tileframe[offset]++; + if (curlevel->tileframe[offset] >= numframes) { + curlevel->tileframe[offset] = 0; + } + // redraw it + drawtile(temps, offset%LEVELW,offset/LEVELW); + } + } - } - - // ice effect - if (curlevel->iced == ICE_INPROGRESS) { - doice(); - } - - // water effect - if (timer % FLOODSPEED == 0) { - if (curlevel->iced == WATER_INPROGRESS) { - doflood(); + // ice effect + if (curlevel->iced == ICE_INPROGRESS) { + doice(); } + + // water effect + if (timer % FLOODSPEED == 0) { + if (curlevel->iced == WATER_INPROGRESS) { + doflood(); + } + } + } + + /********************************************** + * Move sprites + */ + if (levelcomplete == LV_DOPOKER) { + // only fivecards sprite can move + sprite_t *this; + for (this = sprite; this ; this = this->next) { + if (this->id == P_FIVECARDS) { + movesprite(this); + } + } + } else { // all other states... + if (levelcomplete != LV_HELPFREEZE) { + // move sprites + moveallsprites(); + } + } + + /********************************************** + * Move onscreen text + */ + if (levelcomplete != LV_HELPFREEZE) { + movetext(); + } + + + /********************************************** + * Gravity + */ + if (levelcomplete == LV_INIT) { + // only player + dogravity(player); + checkwrap(player); + dotileeffects(player); + } else { + sprite_t *s; + switch (levelcomplete) { + case LV_INPROGRESS: + case LV_CLEAR: + case LV_WAIT: + case LV_FINAL: + case LV_CLOUD: + /* gravity */ + for (s = sprite ; s ; s = s->next) { + dogravity(s); + checkwrap(s); + } + + /* tile effects */ + for (s = sprite ; s ; s = s->next) { + dotileeffects(s); + } + break; + case LV_GAMEOVER: // no collision detection or player movement + /* gravity */ + for (s = sprite->next ; s ; s = s->next) { + dogravity(s); + checkwrap(s); + } + break; + case LV_DOPOKER: // do nothing + case LV_HELPFREEZE: // do nothing + break; + } + } + + /********************************************** + * Special effects #2 - ones which need to happen + * after sprite movement + */ + if (player->hasbell) { + /* check for bell sound */ + + /* play a bell sound if the powerup will be a permenant one */ + if (ispermenant(level->poweruptype)) { + // play sound once + if (!playedbell) { + playfx(FX_BELL); + playedbell = BELL_DONESOUND; + } + if (playedbell != BELL_DONEFLASH) { + if (timer >= BELLTIME) { + playedbell = BELL_DONEFLASH; + } else if (timer % 10 == 0) { + SDL_Rect area; + area.x = 0; + area.y = 0; + area.w = 640; + area.h = 480; + SDL_FillRect(screen, &area, SDL_MapRGB(screen->format,white.r,white.g,white.b)); + flip(); + } + } + } + } + + /********************************************** + * Collision detection + */ + if ((levelcomplete != LV_DOPOKER) && (levelcomplete != LV_HELPFREEZE)) { + checkcollideall(); } } + + /********************************************** - * Move sprites + * Drawing routines */ + + // player netting + if ((levelcomplete != LV_DOPOKER) && (levelcomplete != LV_HELPFREEZE)) { + drawnetting(player); + } + + // cannon firing + if ((levelcomplete != LV_DOPOKER) && (levelcomplete != LV_HELPFREEZE) && (player->powerup == PW_CANNONFIRE)) { // cannon firing + docannoneffect(); + } + + + // draw sprites + if ((levelcomplete != LV_DOPOKER) && (levelcomplete != LV_HELPFREEZE)) { + drawallsprites(); + } + + + + // poker effect + // this must come last as it clears the screen and blanks out other sprites if (levelcomplete == LV_DOPOKER) { - // only fivecards sprite can move + SDL_Rect area; sprite_t *this; + + area.x = 0; + area.y = 0; + area.w = 640; + area.h = 480; + // clear screen + SDL_FillRect(screen, &area, SDL_MapRGB(screen->format,black.r,black.g,black.b)); + + // only fivecards sprite is drawn for (this = sprite; this ; this = this->next) { if (this->id == P_FIVECARDS) { - movesprite(this); + drawsprite(this); } } - } else { // all other states... - if (levelcomplete != LV_HELPFREEZE) { - // move sprites - moveallsprites(); - } + } else if (levelcomplete == LV_HELPFREEZE) { + SDL_Rect area; + + area.x = 0; + area.y = 0; + area.w = 640; + area.h = 480; + // clear screen + SDL_FillRect(screen, &area, SDL_MapRGB(screen->format,black.r,black.g,black.b)); + } + + // draw text + drawtext(); + + // draw score + drawscore(); + + // draw boss health + if (boss) { + drawbosshealth(); + } + + + // draw 'PAUSED' text + if (paused) { + SDL_Rect area; + // show that we are paused + area.x = (640/2) - (pausedshadow->w/2) - 2; + area.y = (480/2) - (pausedshadow->h/2) + 2; + area.w = 0; + area.h = 0; + SDL_BlitSurface(pausedshadow, NULL, screen, &area); + area.x = (640/2) - (pausedtext->w/2); + area.y = (480/2) - (pausedtext->h/2); + area.w = 0; + area.h = 0; + SDL_BlitSurface(pausedtext, NULL, screen, &area); } /********************************************** - * Move onscreen text + * Special effects #3 - ones which need to happen + * after graphics drawing */ - if (levelcomplete != LV_HELPFREEZE) { - movetext(); - } + if (!paused) { + /* is screen shaking? */ + if (player->powerup == PW_BOMB) { + if (timer % 5 == 0) { + int amt; + SDL_Rect area; + amt = (rand() % 20)+1; + area.x = 0; + area.y = amt; + area.w = 640; + area.h = 480-amt; - - /********************************************** - * Gravity - */ - if (levelcomplete == LV_INIT) { - // only player - dogravity(player); - checkwrap(player); - dotileeffects(player); - } else { - sprite_t *s; - switch (levelcomplete) { - case LV_INPROGRESS: - case LV_CLEAR: - case LV_WAIT: - case LV_FINAL: - case LV_CLOUD: - /* gravity */ - for (s = sprite ; s ; s = s->next) { - dogravity(s); - checkwrap(s); - } + SDL_BlitSurface(screen, &area, screen, NULL); - /* tile effects */ - for (s = sprite ; s ; s = s->next) { - dotileeffects(s); + area.x = 0; + area.y = 480-amt; + area.w = 640; + area.h = amt; + SDL_FillRect(screen, &area, SDL_MapRGB(screen->format,black.r,black.g,black.b)); + } + + if (--player->timer1 == 0) { + player->powerup = B_FALSE; + } + } else if (player->powerup == PW_SPRAYUP) { // green overlay for fly spray + SDL_SetAlpha(greenbox, SDL_SRCALPHA, sprayalpha); + sprayalpha += 5; + if (sprayalpha >= 100) { + player->powerup = PW_SPRAYDOWN; + } + SDL_BlitSurface(greenbox,NULL,screen,NULL); + } else if (player->powerup == PW_SPRAYDOWN) { // green overlay for fly spray + SDL_SetAlpha(greenbox, SDL_SRCALPHA, sprayalpha); + sprayalpha -= 5; + if (sprayalpha <= 0) { + player->powerup = PW_SPRAYUP; + } + SDL_BlitSurface(greenbox,NULL,screen,NULL); + } else if (player->powerup == PW_RATSHAKE) { // horizontal shake due to rat + // shake screen + if (timer % 5 == 0) { + int amt; + SDL_Rect area; + amt = (rand() % 20)+1; + area.x = amt; + area.y = 0; + area.w = 640-amt; + area.h = 480; + + SDL_BlitSurface(screen, &area, screen, NULL); + + area.x = 640-amt; + area.y = 0; + area.w = amt; + area.h = 480; + SDL_FillRect(screen, &area, SDL_MapRGB(screen->format,black.r,black.g,black.b)); + } + + + // create rat + if (timer % 10 == 0) { + if (countmonsters() < 8) { // max 7 rats + king rat + puffin(P_RAT, rand() % (640-(TILEW*8))+(TILEW*4), TILEH, "gen_rat",0); } - break; - case LV_GAMEOVER: // no collision detection or player movement - /* gravity */ - for (s = sprite->next ; s ; s = s->next) { - dogravity(s); - checkwrap(s); - } - break; - case LV_DOPOKER: // do nothing - case LV_HELPFREEZE: // do nothing - break; + } + + + if (--player->timer1 == 0) { + player->powerup = B_FALSE; + } } + } /********************************************** - * Special effects #2 - ones which need to happen - * after sprite movement + * Update the screen */ - if (player->hasbell) { - /* check for bell sound */ + flip(); - /* play a bell sound if the powerup will be a permenant one */ - if (ispermenant(level->poweruptype)) { - // play sound once - if (!playedbell) { - playfx(FX_BELL); - playedbell = BELL_DONESOUND; - } - if (playedbell != BELL_DONEFLASH) { - if (timer >= BELLTIME) { - playedbell = BELL_DONEFLASH; - } else if (timer % 10 == 0) { - SDL_Rect area; - area.x = 0; - area.y = 0; - area.w = 640; - area.h = 480; - SDL_FillRect(screen, &area, SDL_MapRGB(screen->format,white.r,white.g,white.b)); - flip(); - } - } - } + if (!paused) { + if (++timer == 100) timer = 0; } - /********************************************** - * Collision detection - */ - if ((levelcomplete != LV_DOPOKER) && (levelcomplete != LV_HELPFREEZE)) { - checkcollideall(); - } - } + if (toggletimer > 0) toggletimer--; + tick(); + } // end main loop + // TODO: fade - /********************************************** - * Drawing routines - */ + // TODO: high scores - // player netting - if ((levelcomplete != LV_DOPOKER) && (levelcomplete != LV_HELPFREEZE)) { - drawnetting(player); - } - - // cannon firing - if ((levelcomplete != LV_DOPOKER) && (levelcomplete != LV_HELPFREEZE) && (player->powerup == PW_CANNONFIRE)) { // cannon firing - docannoneffect(); - } - - - // draw sprites - if ((levelcomplete != LV_DOPOKER) && (levelcomplete != LV_HELPFREEZE)) { - drawallsprites(); - } - - - - // poker effect - // this must come last as it clears the screen and blanks out other sprites - if (levelcomplete == LV_DOPOKER) { - SDL_Rect area; - sprite_t *this; - - area.x = 0; - area.y = 0; - area.w = 640; - area.h = 480; - // clear screen - SDL_FillRect(screen, &area, SDL_MapRGB(screen->format,black.r,black.g,black.b)); - - // only fivecards sprite is drawn - for (this = sprite; this ; this = this->next) { - if (this->id == P_FIVECARDS) { - drawsprite(this); - } - } - } else if (levelcomplete == LV_HELPFREEZE) { - SDL_Rect area; - - area.x = 0; - area.y = 0; - area.w = 640; - area.h = 480; - // clear screen - SDL_FillRect(screen, &area, SDL_MapRGB(screen->format,black.r,black.g,black.b)); - } - - // draw text - drawtext(); - - // draw score - drawscore(); - - // draw boss health - if (boss) { - drawbosshealth(); - } - - - // draw 'PAUSED' text - if (paused) { - SDL_Rect area; - // show that we are paused - area.x = (640/2) - (pausedshadow->w/2) - 2; - area.y = (480/2) - (pausedshadow->h/2) + 2; - area.w = 0; - area.h = 0; - SDL_BlitSurface(pausedshadow, NULL, screen, &area); - area.x = (640/2) - (pausedtext->w/2); - area.y = (480/2) - (pausedtext->h/2); - area.w = 0; - area.h = 0; - SDL_BlitSurface(pausedtext, NULL, screen, &area); - } - - /********************************************** - * Special effects #3 - ones which need to happen - * after graphics drawing - */ - if (!paused) { - /* is screen shaking? */ - if (player->powerup == PW_BOMB) { - if (timer % 5 == 0) { - int amt; - SDL_Rect area; - amt = (rand() % 20)+1; - area.x = 0; - area.y = amt; - area.w = 640; - area.h = 480-amt; - - SDL_BlitSurface(screen, &area, screen, NULL); - - area.x = 0; - area.y = 480-amt; - area.w = 640; - area.h = amt; - SDL_FillRect(screen, &area, SDL_MapRGB(screen->format,black.r,black.g,black.b)); - } - - if (--player->timer1 == 0) { - player->powerup = B_FALSE; - } - } else if (player->powerup == PW_SPRAYUP) { // green overlay for fly spray - SDL_SetAlpha(greenbox, SDL_SRCALPHA, sprayalpha); - sprayalpha += 5; - if (sprayalpha >= 100) { - player->powerup = PW_SPRAYDOWN; - } - SDL_BlitSurface(greenbox,NULL,screen,NULL); - } else if (player->powerup == PW_SPRAYDOWN) { // green overlay for fly spray - SDL_SetAlpha(greenbox, SDL_SRCALPHA, sprayalpha); - sprayalpha -= 5; - if (sprayalpha <= 0) { - player->powerup = PW_SPRAYUP; - } - SDL_BlitSurface(greenbox,NULL,screen,NULL); - } else if (player->powerup == PW_RATSHAKE) { // horizontal shake due to rat - // shake screen - if (timer % 5 == 0) { - int amt; - SDL_Rect area; - amt = (rand() % 20)+1; - area.x = amt; - area.y = 0; - area.w = 640-amt; - area.h = 480; - - SDL_BlitSurface(screen, &area, screen, NULL); - - area.x = 640-amt; - area.y = 0; - area.w = amt; - area.h = 480; - SDL_FillRect(screen, &area, SDL_MapRGB(screen->format,black.r,black.g,black.b)); - } - - - // create rat - if (timer % 10 == 0) { - if (countmonsters() < 8) { // max 7 rats + king rat - puffin(P_RAT, rand() % (640-(TILEW*8))+(TILEW*4), TILEH, "gen_rat",0); - } - } - - - if (--player->timer1 == 0) { - player->powerup = B_FALSE; - } - } - - } - - /********************************************** - * Update the screen - */ - flip(); - - if (!paused) { - if (++timer == 100) timer = 0; - } - - if (toggletimer > 0) toggletimer--; - - tick(); - } + // clear screen ready to start again... + SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,black.r,black.g,black.b)); + } // end outside loop return 0; @@ -666,6 +649,13 @@ void tick(void) { if (fpsticks - fpsstart >= 1000) { gtime++; + // check for game over - 5 seocnds after game over text disappears + if (gameovertime > 0) { + if (gtime >= (gameovertime + GAMEOVERWAIT)) { + gameover = B_TRUE; + } + } + // handle clock effect if (levelcomplete == LV_INPROGRESS) { if (player->powerup == PW_CLOCK) { @@ -3427,6 +3417,10 @@ void movetext(void) { } else if (t->state == t->delay) { t->size -= TEXTSPEED; if (t->size <= 3) { + if ((t->type == TT_GAMEOVER) && (levelcomplete == LV_GAMEOVER)) { + // start game over timer + gameovertime = gtime; + } killtext(t); } @@ -3480,8 +3474,19 @@ void drawbosshealth(void) { void drawscore(void) { SDL_Surface *score; SDL_Rect area; + SDL_Color scorecol; int i; + if (forcegoodcard) { + if ((timer / LUCKYFLASH) % 2 == 0) { + scorecol = green; + } else { + scorecol = red; + } + } else { + scorecol = red; + } + addcommas(tempm, player->score); /* shadow */ @@ -3493,7 +3498,7 @@ void drawscore(void) { SDL_BlitSurface(score, NULL, screen, &area); SDL_FreeSurface(score); /* score */ - score = TTF_RenderText_Solid(font[TEXTSIZE_SCORE], tempm, red); + score = TTF_RenderText_Solid(font[TEXTSIZE_SCORE], tempm, scorecol); area.x = 20; area.y = 5; area.w = 0; @@ -4218,6 +4223,7 @@ void dogravity(sprite_t *s) { int pointsinc = 250; int psize = 6; int gotsomething = B_FALSE; + int gotclover = B_FALSE; int hitboss = B_FALSE; int macex,macey; int numcaught = 0; @@ -4304,6 +4310,11 @@ void dogravity(sprite_t *s) { pointsinc *= 2; psize += 10; gotsomething++; + // killing 5 at a time gives us a clover for good luck + if ((!gotclover) && (gotsomething >= 5)) { + puffin(P_CLOVER, s2->x, s2->y, "clover", 0); + gotclover = B_TRUE; + } } xnet = s2->x; ynet = s2->y - s2->img->h/2; @@ -4444,6 +4455,11 @@ void dogravity(sprite_t *s) { pointsinc *= 2; psize += 10; gotsomething++; + // killing 5 at a time gives us a clover for good luck + if ((!gotclover) && (gotsomething >= 5)) { + puffin(P_CLOVER, s2->x, s2->y, "clover", 0); + gotclover = B_TRUE; + } } } } @@ -4462,11 +4478,6 @@ void dogravity(sprite_t *s) { } } - // killing 5 at a time gives us a bonus on the next level... - if (gotsomething >= 5) { - nextforcegoodcard = B_TRUE; - forcegoodcard = B_TRUE; // and on this level if we get one... - } gotsomething = B_FALSE; @@ -4962,10 +4973,15 @@ int dofruiteffect(sprite_t *s) { playfx(FX_POWERUP); sprintf(tempm, "Shield!"); addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY, TT_NORM); - // temp invincibility player->invuln = SHIELDTIME; - + return B_TRUE; + } else if (s->id == P_CLOVER) { + playfx(FX_POWERUP); + sprintf(tempm, "Lucky!"); + addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_CLOVER, tempm,&green2,&black,CLOVERDELAY, TT_NORM); + nextforcegoodcard = B_TRUE; + forcegoodcard = B_TRUE; return B_TRUE; } else if (s->id == P_HELP) { playfx(FX_POWERUP); @@ -5490,12 +5506,9 @@ void checksprites(void) { s->y = (curlevel->p1y * TILEH) + (TILEH/2); s->invuln = INVULNTIME; } else { - if (levelcomplete == LV_GAMEOVER) { - // TODO: Wait until "game over" text is gone, then slowly fade out the screen - // then show hiscores - // then back to title screen - } else { - addoutlinetext(320,240,TEXTSIZE_GAMEOVER,"Game Over",&red,&black,GAMEOVERDELAY,TT_NORM); + if (levelcomplete != LV_GAMEOVER) { + // special type - when it expires, gameover timer will start + addoutlinetext(320,240,TEXTSIZE_GAMEOVER,"Game Over",&red,&black,GAMEOVERDELAY,TT_GAMEOVER); levelcomplete = LV_GAMEOVER; stopmusic(); playfx(FX_GAMEOVER); @@ -6968,3 +6981,77 @@ void dotitlescreen(void) { // clear screen to black //SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); } + +void startgame(void) { + int i; + + // initial variables + curlevelnum = 1; + curworld = 1; // TODO: REMOVE THIS + musicplaying = B_FALSE; + levelcompletetime = -1; + oldlevelcomplete = -1; + pokereffect = -1; + pokerpoints = 0; + skiplevels = 0; + + + curfruittype = 0; + curpoweruptype = 0; + + fpsticks = 0; + fpsstart = 0; + + // init player variables - if player + // hasn't been allocated yet then this will + // be done so in loadlevel(), and the below + // settings done in addsprite() + if (player) { + int c; + setdefaults(player); + player->permspeed = B_FALSE; + player->permbignet = B_FALSE; + player->permnumnets = B_FALSE; + player->permsticky = B_FALSE; + player->numcards = 0; + for (c = 0; c < MAXCARDS; c++) { + player->card[c] = -1; + player->usedcard[c] = 0; + } + } + + // is we're skipping to a level, do so now + if (skipto >= 0) { + for (i = 0; i < numlevels; i++) { + if (levelentry[i].id == skipto) { + curlevelnum = i; + } + } + } + + // pre-load initial level + if (loadlevel(curworld,curlevelnum, B_TRUE)) { + exit(1); + } + + // more initial variables + player->invuln = INVULNTIME; + player->score = 0; + player->lives = 3; + forcegoodcard = B_FALSE; + nextforcegoodcard = B_FALSE; + + gameover = B_FALSE; + gameovertime = -1; + + gtime = 0; + + curlevelnum-- ; // since nexlevel() will increment it + + // start the first level + nextlevel(); + flip(); + + // start timer + timer = 0; +} diff --git a/rc.h b/rc.h index 04da968..29f96a9 100644 --- a/rc.h +++ b/rc.h @@ -80,3 +80,4 @@ void trytojump(sprite_t *pl); void trytoshoot(sprite_t *pl); void docannoneffect(void); void dotitlescreen(void); +void startgame(void); diff --git a/shared.c b/shared.c index 2f23dfe..3596e63 100644 --- a/shared.c +++ b/shared.c @@ -1268,6 +1268,9 @@ int loadimagesets(void) { loadspriteimage(P_CANNON,F_WALK1, "sprites/cannon.png"); imageset[P_CANNON].numimages = 1; + loadspriteimage(P_CLOVER,F_WALK1, "sprites/clover.png"); + imageset[P_CLOVER].numimages = 1; + loadspriteimage(P_BIGSPEED,F_WALK1, "sprites/bigspeed.png"); imageset[P_BIGSPEED].numimages = 1; @@ -1879,6 +1882,7 @@ int isfruit(int id) { case P_TAP: case P_SPRAY: case P_CANNONPOWERUP: + case P_CLOVER: return FT_TEMP; /* flowers */ case P_FLOWERYELLOW: @@ -2488,7 +2492,7 @@ int loadlevellist(void) { int randompowerup(void) { int num; - num = rand() % 27; + num = rand() % 28; switch (num) { case 0: @@ -2546,6 +2550,8 @@ int randompowerup(void) { return P_MASKPOWERUP; case 26: return getrandomcard(); + case 27: + return P_CLOVER; } } @@ -2674,8 +2680,7 @@ void setfruitinfo(void) { setinfo(P_LIFE, "Life", "Awards the player an extra life.", "extralife.png"); setinfo(P_UFO, "UFO", "Calls in a powerful meteor strike!", "ufo.png"); setinfo(P_TAP, "Tap", "The leaky tap will flood the level with water, allowing you to acces hard to reach areas.", "tap.png"); - - // TODO: add cards here! + setinfo(P_CLOVER, "4-Leaf Clover", "Increases your luck...", "clover.png"); setinfo(P_RAT, "Rat", "The weakest of the monsters, the rat will simply walk back and forth waiting to be caught. Beward an angry rat though, as it will try to fall or jump in order to catch you!", "rat.png"); @@ -2859,7 +2864,7 @@ int getrandomcard(void) { } // are we forcing it to be good? - if (forcegoodcard) { + if ((forcegoodcard) && (player->numcards > 0)) { int okay = B_FALSE; int csuit,cval; for (i = 0; i < player->numcards; i++) {