Added new powerup - machine gun

This commit is contained in:
Rob Pearce 2008-10-29 23:00:12 +00:00
parent 0efde07a9f
commit feb4ae5615
7 changed files with 262 additions and 102 deletions

BIN
data/sounds/alarm.wav Normal file

Binary file not shown.

BIN
data/sounds/gun.wav Normal file

Binary file not shown.

BIN
data/sprites/gunner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

13
defs.h
View File

@ -227,7 +227,7 @@
/* enums */ /* enums */
/* sounds */ /* sounds */
#define MAXFX 45 #define MAXFX 47
#define FX_SHOOT 0 #define FX_SHOOT 0
#define FX_SLAM 1 #define FX_SLAM 1
#define FX_KILL 2 #define FX_KILL 2
@ -273,6 +273,8 @@
#define FX_SKULL 42 #define FX_SKULL 42
#define FX_1UP 43 #define FX_1UP 43
#define FX_CATCH 44 #define FX_CATCH 44
#define FX_GUN 45
#define FX_ALARM 46
// card suits // card suits
#define CS_HEART 1 #define CS_HEART 1
@ -298,7 +300,7 @@
#define S_SLOPE 2 #define S_SLOPE 2
// Sprite types // Sprite types
#define MAXPTYPES 125 #define MAXPTYPES 126
#define P_PLAYER 0 #define P_PLAYER 0
#define P_RAT 1 #define P_RAT 1
#define P_CHEESE 2 #define P_CHEESE 2
@ -429,6 +431,7 @@
#define P_WINGLEFT 122 #define P_WINGLEFT 122
#define P_WINGRIGHT 123 #define P_WINGRIGHT 123
#define P_PLANT 124 #define P_PLANT 124
#define P_GUN 125
// cards // cards
#define CARDFONTX 4 #define CARDFONTX 4
@ -462,9 +465,13 @@
#define PW_CANNONFIRE 10 // fusion cannon firing #define PW_CANNONFIRE 10 // fusion cannon firing
#define PW_PHONE 11 // skip level #define PW_PHONE 11 // skip level
#define PW_ACCORDION 12 // super long net #define PW_ACCORDION 12 // super long net
#define PW_GUNNER 13 // machine gunner
// "virtual" powerup for bosses // "virtual" powerup for bosses
#define PW_RATSHAKE 20 // shake screen horizontally #define PW_RATSHAKE 20 // shake screen horizontally
#define GUNNERSPEED 2.5 // speed crosshair moves in gunner mode
#define GUNNERDELAY 10 // how fast gunner powerup shoots
// Frame names // Frame names
#define F_WALK1 0 #define F_WALK1 0
#define F_JUMP 1 #define F_JUMP 1
@ -793,7 +800,7 @@ imageset_t imageset[MAXPTYPES];
extern SDL_Color black; extern SDL_Color black;
extern SDL_Surface *screen, *temps, *levelbg, *head, *head5, *icecube; extern SDL_Surface *screen, *temps, *levelbg, *head, *head5, *icecube;
extern SDL_Surface *healthbar[]; extern SDL_Surface *healthbar[];
extern SDL_Surface *greenbox; extern SDL_Surface *greenbox, *redbox;
extern sprite_t *sprite, *lastsprite, *player, *boss, *mask; extern sprite_t *sprite, *lastsprite, *player, *boss, *mask;
extern level_t *curlevel; extern level_t *curlevel;
extern tiletype_t fakeblock; extern tiletype_t fakeblock;

View File

@ -27,6 +27,7 @@ SDL_Surface *screen; // the actual video screen
SDL_Surface *head,*head5; // imgs in corner showing number of lives SDL_Surface *head,*head5; // imgs in corner showing number of lives
SDL_Surface *icecube; // overlaid on frozen monsters SDL_Surface *icecube; // overlaid on frozen monsters
SDL_Surface *greenbox; // for fly spray effect SDL_Surface *greenbox; // for fly spray effect
SDL_Surface *redbox; // for gunner
SDL_Surface *healthbar[HEALTHFRAMES]; // for boss health SDL_Surface *healthbar[HEALTHFRAMES]; // for boss health
sprite_t *sprite; // head of sprite linked list sprite_t *sprite; // head of sprite linked list
sprite_t *lastsprite; // tail of sprite linked list sprite_t *lastsprite; // tail of sprite linked list

124
rc.c
View File

@ -56,6 +56,11 @@ char tempm[BUFLEN];
int savemap[LEVELW*LEVELH]; int savemap[LEVELW*LEVELH];
int watertime; int watertime;
double gunorigx;
double gunorigy;
int gundelay;
int guntime;
int playedbell; int playedbell;
int clocktime; int clocktime;
@ -354,13 +359,15 @@ int main (int argc, char **argv) {
addoutlinetext(320,240,TEXTSIZE_LEVEL,"Level Complete!",&green,&black,LEVELWINDELAY, TT_NORM); addoutlinetext(320,240,TEXTSIZE_LEVEL,"Level Complete!",&green,&black,LEVELWINDELAY, TT_NORM);
levelcomplete = LV_WAIT; levelcomplete = LV_WAIT;
playfx(FX_WINLEVEL); playfx(FX_WINLEVEL);
// turn off clock and water powerups // turn off certain powerups
if (player->powerup == PW_CLOCK) { if (player->powerup == PW_CLOCK) {
Mix_ResumeMusic(); Mix_ResumeMusic();
losepowerup(player); losepowerup(player);
} else if ((curlevel->iced == WATER_INPROGRESS) || (curlevel->iced == WATER_COMPLETE)) { } else if ((curlevel->iced == WATER_INPROGRESS) || (curlevel->iced == WATER_COMPLETE)) {
curlevel->iced = B_FALSE; curlevel->iced = B_FALSE;
undoflood(); undoflood();
} else if (player->powerup == PW_GUNNER) {
losepowerup(player);
} }
// kill all cards, so we don't have a pokereffect during endoflevel // kill all cards, so we don't have a pokereffect during endoflevel
@ -442,6 +449,11 @@ int main (int argc, char **argv) {
} }
} }
} }
if (player->powerup == PW_GUNNER) { // red overlay for machine gunner
if (levelcomplete != LV_DOPOKER) {
SDL_BlitSurface(redbox,NULL,screen,NULL);
}
}
/********************************************** /**********************************************
* Move sprites * Move sprites
@ -733,12 +745,23 @@ int main (int argc, char **argv) {
*/ */
flip(); flip();
/**********************************************
* Timers
*/
if (!paused) { if (!paused) {
if (++timer == 100) timer = 0; if (++timer == 100) timer = 0;
} }
if (toggletimer > 0) toggletimer--; if (toggletimer > 0) toggletimer--;
if (player->powerup == PW_GUNNER) {
// delay between shots
if (gundelay > 0) {
gundelay--;
}
}
fpscount++; fpscount++;
tick(); tick();
} // end main loop } // end main loop
@ -796,8 +819,9 @@ void tick(void) {
} }
} }
// handle clock effect // handle visual countdown timers
if (levelcomplete == LV_INPROGRESS) { if (levelcomplete == LV_INPROGRESS) {
// clock
if (player->powerup == PW_CLOCK) { if (player->powerup == PW_CLOCK) {
char tempm[SMALLBUFLEN]; char tempm[SMALLBUFLEN];
// text // text
@ -837,6 +861,24 @@ void tick(void) {
undoflood(); undoflood();
} }
} }
// handle gunner effect
if (player->powerup == PW_GUNNER) {
char tempm[SMALLBUFLEN];
// text
if (guntime > 0) {
sprintf(tempm, "%d",guntime);
addoutlinetext(320,120,TEXTSIZE_LEVEL, tempm, &red,&black,15, TT_NORM);
}
// never reach hurryup time
resethurryup(curlevel);
// decrement counter
guntime--;
if (guntime < 0) {
// finished!
losepowerup(player);
}
}
} }
@ -1595,6 +1637,10 @@ int movesprite(sprite_t *s) {
int rv; int rv;
tiletype_t *tt; tiletype_t *tt;
if ((s == player) && (player->powerup == PW_GUNNER)) {
return B_FALSE;
}
if (levelcomplete == LV_INIT) { if (levelcomplete == LV_INIT) {
// most things can't move in this state // most things can't move in this state
@ -1928,10 +1974,12 @@ if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
// appeared on top of us // appeared on top of us
if ((xdiff <= player->img->w/2 + newsp->img->w/2) && if ((xdiff <= player->img->w/2 + newsp->img->w/2) &&
(ydiff <= player->img->h/2 + newsp->img->h/2)) { (ydiff <= player->img->h/2 + newsp->img->h/2)) {
if ((!player->dead) && (player->powerup != PW_GUNNER)) {
// bonus! // bonus!
getfruit(player, newsp, 4); getfruit(player, newsp, 4);
addoutlinetext(player->x,player->y - (player->img->h*1.5), TEXTSIZE_MULTI, "Nice catch!", &green,&black,MULTIDELAY, TT_NORM); addoutlinetext(player->x,player->y - (player->img->h*1.5), TEXTSIZE_MULTI, "Nice catch!", &green,&black,MULTIDELAY, TT_NORM);
} }
}
} }
@ -3104,6 +3152,13 @@ void dotileeffects(sprite_t *s) {
return; return;
} }
// no tile efffects for machine gun
if (player->powerup == PW_GUNNER) {
if (s == player) {
return;
}
}
/* check where we are */ /* check where we are */
tt = gettileat(s->x,s->y-2,&tilex,&tiley); tt = gettileat(s->x,s->y-2,&tilex,&tiley);
@ -4396,6 +4451,7 @@ void dogravity(sprite_t *s) {
tiletype_t *tt; tiletype_t *tt;
int tilex,tiley; int tilex,tiley;
if (s->id == P_PINKCLOUD) return; if (s->id == P_PINKCLOUD) return;
// only player can move if you have a clock // only player can move if you have a clock
@ -4405,6 +4461,13 @@ void dogravity(sprite_t *s) {
} }
} }
// no gravity for player if you have the machine gun
if (player->powerup == PW_GUNNER) {
if (s == player) {
return;
}
}
// if we were on a trampoline and are now not, it releases */ // if we were on a trampoline and are now not, it releases */
tt = gettileat(s->x,s->y,&tilex,&tiley); tt = gettileat(s->x,s->y,&tilex,&tiley);
if (s->ontramp) { if (s->ontramp) {
@ -5467,6 +5530,15 @@ int dofruiteffect(sprite_t *s) {
addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY, TT_NORM); addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY, TT_NORM);
player->doublejump = B_TRUE; player->doublejump = B_TRUE;
return B_TRUE; return B_TRUE;
} else if (s->id == P_GUN) {
playfx(FX_ALARM);
sprintf(tempm, "Machine gunner!");
gunorigx = player->x;
gunorigy = player->y;
guntime = 10;
gundelay = 0; // used to control shooting speed
player->powerup = PW_GUNNER;
return B_TRUE;
} else if (s->id == P_SKULL) { } else if (s->id == P_SKULL) {
playfx(FX_SKULL); playfx(FX_SKULL);
sprintf(tempm, "Power Down!"); sprintf(tempm, "Power Down!");
@ -5661,6 +5733,8 @@ int initsound(void) {
loadfx(FX_SKULL, "skull.wav"); loadfx(FX_SKULL, "skull.wav");
loadfx(FX_1UP, "1up.wav"); loadfx(FX_1UP, "1up.wav");
loadfx(FX_CATCH, "catch.wav"); loadfx(FX_CATCH, "catch.wav");
loadfx(FX_GUN, "gun.wav");
loadfx(FX_ALARM, "alarm.wav");
// load sound effects // load sound effects
for (i = 0; i < MAXFX; i++) { for (i = 0; i < MAXFX; i++) {
@ -6126,7 +6200,11 @@ void checkcollideall(void) {
/* check collisions for player and effects */ /* check collisions for player and effects */
for (s = sprite ; s ; s = s->next) { for (s = sprite ; s ; s = s->next) {
if ((s == player) || needscollisions(s->id)) { if (s == player) {
if (player->powerup != PW_GUNNER) {
checkcollide(s);
}
} else if (needscollisions(s->id)) {
checkcollide(s); checkcollide(s);
} }
} }
@ -7220,6 +7298,37 @@ if (cheat) {
Player movement Player movement
************************************************************/ ************************************************************/
if ((!paused) && (!levelcomplete != LV_DOPOKER) && (levelcomplete != LV_CLOUDLOOP)) { if ((!paused) && (!levelcomplete != LV_DOPOKER) && (levelcomplete != LV_CLOUDLOOP)) {
if (player->powerup == PW_GUNNER) {
// move crosshairs
if (keydown(SDLK_RIGHT)) {
if (player->x < 640-(TILEW/2)) {
player->x += GUNNERSPEED;
}
}
if (keydown(SDLK_LEFT)) {
if (player->x > (TILEW/2)) {
player->x -= GUNNERSPEED;
}
}
if (keydown(SDLK_DOWN)) {
if (player->y < 480-(TILEH/2)) {
player->y += GUNNERSPEED;
}
}
if (keydown(SDLK_UP)) {
if (player->y > (TILEH/2)) {
player->y -= GUNNERSPEED;
}
}
if (keydown(SDLK_z)) {
// shoot - add explosion
if (gundelay == 0) {
playfx(FX_GUN);
addsprite(P_SMASH, player->x, player->y+(TILEH/2), "gunexplosion");
gundelay = GUNNERDELAY;
}
}
} else {
if ((!player->dead) && (!player->teleporting)) { if ((!player->dead) && (!player->teleporting)) {
int moveok = B_FALSE; int moveok = B_FALSE;
if (player->climbing) { if (player->climbing) {
@ -7323,6 +7432,7 @@ if (cheat) {
} }
} }
} }
}
// ignore other events // ignore other events
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
} }
@ -8635,5 +8745,13 @@ void stopteleporting(sprite_t *s) {
} }
void losepowerup(sprite_t *s) { void losepowerup(sprite_t *s) {
if (s->powerup == PW_GUNNER) {
// go back to original position
player->x = gunorigx;
player->y = gunorigy;
// invulnerable for a little while
player->invuln = INVULNTIME/2;
}
s->powerup = B_FALSE; s->powerup = B_FALSE;
} }

View File

@ -1007,7 +1007,6 @@ int loadimagesets(void) {
healthbar[HF_RED] = IMG_Load(tempfile); healthbar[HF_RED] = IMG_Load(tempfile);
// green square for flyspray effect // green square for flyspray effect
greenbox = SDL_CreateRGBSurface(SDL_SWSURFACE, greenbox = SDL_CreateRGBSurface(SDL_SWSURFACE,
screen->w, screen->w,
screen->h, screen->h,
@ -1016,6 +1015,15 @@ int loadimagesets(void) {
SDL_FillRect(greenbox, NULL, SDL_MapRGB(greenbox->format, 0, 150, 0)); SDL_FillRect(greenbox, NULL, SDL_MapRGB(greenbox->format, 0, 150, 0));
SDL_SetAlpha(greenbox, SDL_SRCALPHA,80); SDL_SetAlpha(greenbox, SDL_SRCALPHA,80);
// red square for gunner effect
redbox = SDL_CreateRGBSurface(SDL_SWSURFACE,
screen->w,
screen->h,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask,screen->format->Bmask, 0);
SDL_FillRect(redbox, NULL, SDL_MapRGB(greenbox->format, 150, 0, 0));
SDL_SetAlpha(redbox, SDL_SRCALPHA,80);
loadspriteimage(P_PLAYER,F_WALK1, "sprites/pdwarf.png"); loadspriteimage(P_PLAYER,F_WALK1, "sprites/pdwarf.png");
loadspriteimage(P_PLAYER,F_JUMP, "sprites/pdwarfjump.png"); loadspriteimage(P_PLAYER,F_JUMP, "sprites/pdwarfjump.png");
@ -1299,6 +1307,9 @@ int loadimagesets(void) {
loadspriteimage(P_WINGBOOTS,F_WALK1, "sprites/wingboots.png"); loadspriteimage(P_WINGBOOTS,F_WALK1, "sprites/wingboots.png");
imageset[P_WINGBOOTS].numimages = 1; imageset[P_WINGBOOTS].numimages = 1;
loadspriteimage(P_GUN,F_WALK1, "sprites/gunner.png");
imageset[P_GUN].numimages = 1;
// wings // wings
loadspriteimage(P_WINGLEFT,0, "sprites/wingleft0.png"); // standing loadspriteimage(P_WINGLEFT,0, "sprites/wingleft0.png"); // standing
loadspriteimage(P_WINGLEFT,1, "sprites/wingleft1.png"); // jumping loadspriteimage(P_WINGLEFT,1, "sprites/wingleft1.png"); // jumping
@ -1532,6 +1543,11 @@ void drawsprite(sprite_t *s) {
SDL_Rect area; SDL_Rect area;
int frame = 0; int frame = 0;
// don't show caught mosnters in gunner mode
if ((s != player) && (s->caughtby == player) && (player->powerup == PW_GUNNER)) {
return;
}
if ((s == player) && (levelcomplete == LV_NEXTLEV)) { if ((s == player) && (levelcomplete == LV_NEXTLEV)) {
frame = F_SHOOT; frame = F_SHOOT;
if (curlevel->exitdir == D_RIGHT) { if (curlevel->exitdir == D_RIGHT) {
@ -1957,6 +1973,7 @@ int isfruit(int id) {
case P_CANNONPOWERUP: case P_CANNONPOWERUP:
case P_CLOVER: case P_CLOVER:
case P_ACCORDION: case P_ACCORDION:
case P_GUN:
case P_SKULL: case P_SKULL:
return FT_TEMP; return FT_TEMP;
/* flowers */ /* flowers */
@ -2571,7 +2588,7 @@ int loadlevellist(void) {
int randompowerup(void) { int randompowerup(void) {
int num; int num;
num = rand() % 31; num = rand() % 32;
switch (num) { switch (num) {
case 0: case 0:
@ -2637,6 +2654,8 @@ int randompowerup(void) {
return P_WINGBOOTS; return P_WINGBOOTS;
case 30: case 30:
return P_SKULL; return P_SKULL;
case 31:
return P_GUN;
} }
} }
@ -2768,6 +2787,7 @@ void setfruitinfo(void) {
setinfo(P_UFO, "UFO", "Calls in a powerful meteor strike!", "ufo.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 for 20 seconds, allowing you to access hard to reach areas.", "tap.png"); setinfo(P_TAP, "Tap", "The leaky tap will flood the level with water for 20 seconds, allowing you to access hard to reach areas.", "tap.png");
setinfo(P_ACCORDION, "Accordion", "Makes your nets enormous", "accordion.png"); setinfo(P_ACCORDION, "Accordion", "Makes your nets enormous", "accordion.png");
setinfo(P_GUN, "Gunner", "Temporarily equips you with a super powerful machine gun!", "gunner.png");
setinfo(P_SKULL, "Skull", "Avoid these at all costs! The skull will cause you to lose all net powerups.", "skull.png"); setinfo(P_SKULL, "Skull", "Avoid these at all costs! The skull will cause you to lose all net powerups.", "skull.png");
setinfo(P_CLOVER, "4-Leaf Clover", "Increases your luck...", "clover.png"); setinfo(P_CLOVER, "4-Leaf Clover", "Increases your luck...", "clover.png");
@ -3173,7 +3193,21 @@ void drawplayer(sprite_t *s, SDL_Rect *where) {
#ifndef __EDITOR #ifndef __EDITOR
// only raw wings in certain states if (player->powerup == PW_GUNNER) {
// just draw crosshairs
// box
drawbox16(screen, s->x-(TILEW/2),s->y-(TILEH/2),s->x+(TILEW/2),s->y+(TILEH/2), &green, NULL);
// littlebox
drawbox16(screen, s->x-1,s->y-1,s->x+1,s->y+1, &green, NULL);
// lines
drawline16(screen, s->x, 0, s->x, s->y-(TILEH/2), green); // top
drawline16(screen, s->x, s->y+(TILEH/2), s->x, 480-1, green); // bottom
drawline16(screen, 0, s->y, s->x-(TILEW/2), s->y, green); // left
drawline16(screen, s->x+(TILEW/2), s->y, 640-1, s->y, green); // right
return;
}
// only draw wings in certain states
switch (levelcomplete) { switch (levelcomplete) {
case LV_NEXTLEV: case LV_NEXTLEV:
case LV_CLOUDLOOP: case LV_CLOUDLOOP: