diff --git a/data/sprites/net.png b/data/sprites/net.png new file mode 100644 index 0000000..3efba43 Binary files /dev/null and b/data/sprites/net.png differ diff --git a/defs.h b/defs.h index 2255d7a..81e16ac 100644 --- a/defs.h +++ b/defs.h @@ -496,7 +496,7 @@ enum SPELL { #define S_SLOPE 2 // Sprite types -#define MAXPTYPES 179 +#define MAXPTYPES 181 #define P_PLAYER 0 #define P_RAT 1 #define P_CHEESE 2 @@ -681,7 +681,8 @@ enum SPELL { #define P_FALLINGBRICK 176 #define P_BIGCHEST 177 #define P_FIREUP 178 - +#define P_NET 179 +#define P_UPSTAR 180 #define FLY_FLYTIME 150 #define FLY_WALKTIME 300 @@ -759,6 +760,8 @@ enum SPELL { #define PW_ENDGAME 54 +#define MINUPSTARS 50 + #define GUNNERSPEED 2.5 // speed crosshair moves in gunner mode #define GUNNERDELAY 10 // how fast gunner powerup shoots diff --git a/globals.h b/globals.h index 5cf91f4..11ec577 100644 --- a/globals.h +++ b/globals.h @@ -97,9 +97,11 @@ SDL_Color red; SDL_Color black; SDL_Color blue; SDL_Color white; +SDL_Color white2; SDL_Color green; SDL_Color purple; SDL_Color yellow; +SDL_Color orange; #endif diff --git a/rc.c b/rc.c index a5aa1c2..b8740b4 100644 --- a/rc.c +++ b/rc.c @@ -29,8 +29,6 @@ #include "shared.h" #include "rc.h" - - FPSmanager manager; SDL_Surface *temps; SDL_Surface *screen; @@ -190,6 +188,7 @@ SDL_Color purple = {200, 0, 200, 0}; SDL_Color brown = {166, 97, 7, 0}; SDL_Color brown2 = {116, 47, 0, 0}; SDL_Color white = {255, 255, 255, 0}; +SDL_Color white2 = {150, 150, 150, 0}; SDL_Color grey = {210, 210, 210, 0}; SDL_Color grey2 = {90, 90, 90, 0}; SDL_Color green = {0, 255, 0, 0}; @@ -1150,6 +1149,9 @@ printf("timer = %d\n",timer); ss->xs = 0; ss->ys = rand() % 2; } + if (countsprites(P_UPSTAR) < MINUPSTARS) { + addupstar(); + } if (endgame == EG_FADETOBLACK) { int val; @@ -2361,6 +2363,8 @@ void checkcollideplatform(sprite_t *s) { // only monsters and players and fruits can be on platforms if (!ismonster(s2->id) && (!isplayer(s2)) && (!isfruit(s2->id))) { continue; + } else if (s2->id == P_BLACKCLOUD) { + continue; } if (s2->onplatform == s) { @@ -2549,7 +2553,6 @@ void checkcollide(sprite_t *s) { s2->caughtstate = C_NETTING; s->netcaught++; - // special case for whitetail if (s2->id == P_WSPIDER) { s2->timer2 = 0; @@ -2809,7 +2812,6 @@ int movesprite(sprite_t *s) { return B_FALSE; } - if (levelcomplete == LV_INIT) { // most things can't move in this state //if ((s->id != P_PUFF) && (s != player)) { @@ -3489,6 +3491,18 @@ int movesprite(sprite_t *s) { // die s->dead = D_FINAL; } + } else if (s->id == P_UPSTAR) { // star at endgame + double oldy; + + // rise to top of screen then die + oldy = s->y; + s->y = s->y - (s->ys*2); + + // if off screen + if (s->y <= 0) { + // die + s->dead = D_FINAL; + } } else if (s->id == P_BUBBLE) { // bubble effect tiletype_t *tt; // float up, die when we leave the water @@ -5343,7 +5357,7 @@ int movesprite(sprite_t *s) { s2->y += ydiff; // check if s2's head has hit something - if (preroof && isroofabove(s2) && (ydiff < 0)) { + if (preroof && isroofabove(s2) && (ydiff < 0) && (s2->id != P_BLACKCLOUD)) { if (isplayer(s2)) { die(s2); printf("DB: killed by head crush\n"); fflush(stdout); @@ -7934,23 +7948,25 @@ void drawscore(void) { } // level # - sprintf(tempm, "Level %d-%d",getcurworld(), getcurlevel()); - /* shadow */ - score = TTF_RenderText_Solid(font[TEXTSIZE_SCORE], tempm, black); - area.x = 320-(score->w/2)-2; - area.y = 7; - area.w = 0; - area.h = 0; - SDL_BlitSurface(score, NULL, screen, &area); - SDL_FreeSurface(score); - /* text */ - score = TTF_RenderText_Solid(font[TEXTSIZE_SCORE], tempm, white); - area.x = 320-(score->w/2); - area.y = 5; - area.w = 0; - area.h = 0; - SDL_BlitSurface(score, NULL, screen, &area); - SDL_FreeSurface(score); + if (globpowerup != PW_ENDGAME) { + sprintf(tempm, "Level %d-%d",getcurworld(), getcurlevel()); + /* shadow */ + score = TTF_RenderText_Solid(font[TEXTSIZE_SCORE], tempm, black); + area.x = 320-(score->w/2)-2; + area.y = 7; + area.w = 0; + area.h = 0; + SDL_BlitSurface(score, NULL, screen, &area); + SDL_FreeSurface(score); + /* text */ + score = TTF_RenderText_Solid(font[TEXTSIZE_SCORE], tempm, white); + area.x = 320-(score->w/2); + area.y = 5; + area.w = 0; + area.h = 0; + SDL_BlitSurface(score, NULL, screen, &area); + SDL_FreeSurface(score); + } drawcredits(); @@ -8145,6 +8161,8 @@ void drawnetting(sprite_t *s) { s->netystart = s->nety - 3; + + if (s->netdir == 1) { area.x = s->netxstart + TILEW/2; } else { @@ -8161,7 +8179,11 @@ void drawnetting(sprite_t *s) { dis = (int)s->img->h / (int)(netsleft+1) + 1; + for (y = dis; y < s->img->h; y += dis) { + SDL_Rect endarea; + SDL_Surface *netim; + yy = s->y - s->img->h; yy += y; @@ -8169,15 +8191,22 @@ void drawnetting(sprite_t *s) { if (s->netsticky) { drawdotline16(screen,sx,s->nety,xx,yy,orange,yellow); } else { - drawline(screen,sx,s->nety,xx,yy,white); + drawdotline16(screen,sx,s->nety,xx,yy,white,white2); } // add sparkle xx = s->x + s->netdir*s->netlen; if (levelcomplete != LV_HELPFREEZE) { addsprite(P_SPARKLE, xx + (rand() % 14) - 7, yy + (rand() % 8) - 4, "sparkle"); } + + netim = imageset[P_NET].img[(s->netdir == 1) ? 0 : 1]; + endarea.x = xx; + endarea.y = yy - (netim->h/2); + + SDL_BlitSurface(netim, NULL, screen, &endarea); } + //drawline(screen,sx,s->nety,s->x + s->netdir*s->netlen,s->nety-3,white); //drawline(screen,sx,s->nety,s->x + s->netdir*s->netlen,s->nety,white); //drawline(screen,sx,s->nety,s->x + s->netdir*s->netlen,s->nety+3,white); @@ -8200,7 +8229,7 @@ void drawnetting(sprite_t *s) { col2 = &yellow; } else { col1 = &white; - col2 = &white; + col2 = &white2; } /* middle dotline */ @@ -8565,28 +8594,29 @@ void dogravity(sprite_t *s) { } // if we were on a trampoline and are now not, it releases */ - tt = gettileat(s->x,s->y,&tilex,&tiley); - if (s->ontramp) { - if (s->trampy == tiley) { - // you jump automatically! - jump(s, s->xs / getspeed(s)); - } else { - //if (s->trampy != tiley) { - // change tile type - if (s->tramplayer == 1) { - curlevel->map[s->trampy * LEVELW + s->trampx] = getuniq(T_TRAMPUP); + if (s->id != P_BLACKCLOUD) { + tt = gettileat(s->x,s->y,&tilex,&tiley); + if (s->ontramp) { + if (s->trampy == tiley) { + // you jump automatically! + jump(s, s->xs / getspeed(s)); } else { - curlevel->map2[s->trampy * LEVELW + s->trampx] = getuniq(T_TRAMPUP); - } - drawtile(temps, s->trampx, s->trampy); + //if (s->trampy != tiley) { + // change tile type + if (s->tramplayer == 1) { + curlevel->map[s->trampy * LEVELW + s->trampx] = getuniq(T_TRAMPUP); + } else { + curlevel->map2[s->trampy * LEVELW + s->trampx] = getuniq(T_TRAMPUP); + } + drawtile(temps, s->trampx, s->trampy); - // update sprite settings - s->ontramp = B_FALSE; - s->trampx = -1; - s->trampy = -1; + // update sprite settings + s->ontramp = B_FALSE; + s->trampx = -1; + s->trampy = -1; + } } } - if (s->dead) return; @@ -9599,7 +9629,7 @@ int dofruiteffect(sprite_t *pp, sprite_t *s) { } return B_TRUE; } else if (s->id == P_BIGCHEST) { // trigger endgame! - int tx,ty; + int tx,ty,i; sprite_t *s2,*nexts; endgame = EG_FRUITFALL; endtexttimer = 0; @@ -9617,6 +9647,12 @@ int dofruiteffect(sprite_t *pp, sprite_t *s) { } globpowerup = PW_ENDGAME; globtimer = 0; + // add initial stars + for (i = 0; i < MINUPSTARS; i++) { + sprite_t *ss; + ss = addupstar(); + ss->y = (rand() % (480-(TILEH*2))) + TILEH; + } // all tiles become fruit for (ty = 0 ; ty < LEVELH; ty++) { for (tx = 0 ; tx < LEVELW; tx++) { @@ -10772,6 +10808,18 @@ char *addcommas(char *buffer, long num) { return buffer; } +sprite_t *addupstar(void) { + sprite_t *ss; + int x,y; + // spawn a new star + x = (rand() % (640-(TILEW*2))) + TILEW; + y = 480; + ss = addsprite(P_UPSTAR, x, y, "upstar"); + ss->xs = 0; + ss->ys = (rand() % 4)+1; + return ss; +} + int addscore(sprite_t *s, long amt) { int oldscore; oldscore = s->score; @@ -12208,7 +12256,8 @@ if (cheat) { playfx(FX_POWERUP); sprintf(tempm, "Cheat!"); if (player) { - player->powerup = PW_MAGNET; + //player->powerup = PW_MAGNET; + player->powerup = PW_RAYGUN; player->netmax = 4; // all nets player->netbig = B_TRUE; // big net player->speed = 2; // fast @@ -12596,7 +12645,6 @@ void trytoslam(sprite_t *pl) { } void trytoshoot(sprite_t *pl) { - if (pl->caughtby) return; if ((!pl->netting) && (!pl->slamming)) { diff --git a/rc.h b/rc.h index 288bf45..bf16318 100644 --- a/rc.h +++ b/rc.h @@ -55,6 +55,7 @@ int counttextoftype(int wanttype); int getpoints(int id); int isladder(int tid); char *addcommas(char *buffer, long num); +sprite_t *addupstar(void); int addscore(sprite_t *s, long amt); void extralife(sprite_t *s); void doice(void); diff --git a/shared.c b/shared.c index bdad35b..e69777b 100644 --- a/shared.c +++ b/shared.c @@ -1982,13 +1982,15 @@ int loadimagesets(void) { } - // sparkles + // sparkles + endgame stars for (i = 0; i < SPARKLEFRAMES; i++) { char name[SMALLBUFLEN]; sprintf(name, "sprites/sparkle%d.png",i); loadspriteimage(P_SPARKLE,i, name); + loadspriteimage(P_UPSTAR, i, name); } imageset[P_SPARKLE].numimages = SPARKLEFRAMES; + imageset[P_UPSTAR].numimages = SPARKLEFRAMES; loadspriteimage(P_BUBBLE,F_WALK1, "sprites/bubble.png"); imageset[P_BUBBLE].numimages = 1; @@ -2029,6 +2031,11 @@ int loadimagesets(void) { loadspriteimage(P_SONAR,9, "sprites/sonar1.png"); imageset[P_SONAR].numimages = 10; + loadspriteimage(P_NET,0, "sprites/net.png"); + // manually do flipped one + imageset[P_NET].img[1] = rotozoomSurfaceXY(imageset[P_NET].img[0], 0, -1,1,0); + imageset[P_NET].numimages = 2; + // manual angry image for black cloud origi = imageset[P_BLACKCLOUD].img[0]; @@ -2248,6 +2255,9 @@ void drawsprite(sprite_t *s) { frame = F_WALK1; } else if (s->id == P_METEOR) { frame = F_WALK1; + } else if (s->id == P_UPSTAR) { + // frame based on speed + frame = (s->ys - 1); } else if (s->id == P_STAR) { frame = s->timer1; } else if (s->id == P_MASK) { @@ -2664,12 +2674,17 @@ void drawsprite(sprite_t *s) { if ((s->caughtby) && (s->caughtstate == 2)){ // only if we're on the screen if ((s->y >= 0) && (s->y <= 480)) { - drawline(screen, s->x,s->y - s->img->h, - s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white); - drawline(screen, s->x,s->y - (s->img->h/2), - s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white); - drawline(screen, s->x,s->y, - s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white); + SDL_Color *col1 = &white,*col2 = &white2; + if (s->caughtby->netsticky) { + col1 = &orange; + col2 = &yellow; + } + drawdotline16(screen, s->x,s->y - s->img->h, + s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), *col1, *col2); + drawdotline16(screen, s->x,s->y - (s->img->h/2), + s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), *col1,*col2); + drawdotline16(screen, s->x,s->y, + s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), *col1,*col2); } } @@ -2972,6 +2987,7 @@ int isplatform(int id) { int iseffect(int id) { switch (id) { + case P_UPSTAR: case P_PUFF: case P_SPARKLE: case P_SMASH: @@ -2997,6 +3013,7 @@ int iseffect(int id) { case P_WINGRIGHT: case P_BIGUMBRELLA: case P_SMALLANCHOR: + case P_NET: return B_TRUE; } @@ -3827,6 +3844,9 @@ int isnettable(sprite_t *s) { // return starting health for a given boss type int getbosshealth(int mid) { + if (cheat) { + return 1; + } switch (mid) { case P_KINGRAT: return 8;