diff --git a/data/sprites/bigumbrella.png b/data/sprites/bigumbrella.png new file mode 100644 index 0000000..964704b Binary files /dev/null and b/data/sprites/bigumbrella.png differ diff --git a/data/sprites/umbrella.png b/data/sprites/umbrella.png new file mode 100644 index 0000000..be54a2f Binary files /dev/null and b/data/sprites/umbrella.png differ diff --git a/defs.h b/defs.h index 509a1cb..b2a1c17 100644 --- a/defs.h +++ b/defs.h @@ -160,6 +160,7 @@ #define SLUGINVULNTIME 50 // how long a new slug stays invulnerable for #define SHIELDTIME 600 // how long a shield lasts #define FALLSPEED 4 // terminal velocity of falling sprites +#define UMBFALLSPEED 1 // terminal velocity of falling sprites with umbrella #define SMALLNETSPEED 6 // how fast the player's net moves with skull #define NETSPEED 9 // how fast the player's net moves #define BIGNETSPEED 12 // how fast the player's net moves with bignet @@ -383,7 +384,7 @@ #define S_SLOPE 2 // Sprite types -#define MAXPTYPES 150 +#define MAXPTYPES 152 #define P_PLAYER 0 #define P_RAT 1 #define P_CHEESE 2 @@ -539,6 +540,8 @@ #define P_BADMAGNET 147 #define P_JETPACK 148 #define P_CAMERA 149 +#define P_UMBRELLA 150 +#define P_BIGUMBRELLA 151 #define FLY_FLYTIME 150 @@ -861,6 +864,8 @@ typedef struct sprite_s { int netsticky; // can net pick up powerups? int powerup; // what temp powerup does the player have? + int cancelumb; // cancelled the umbrella? + int oncloud; // on cloud at end of level? int permspeed; // got the permenant speed powerup? @@ -869,6 +874,7 @@ typedef struct sprite_s { int permsticky; // got the permenant sticky net powerup? int permdoublejump;// got the permenant dbljump powerup? int permarmour;// got the permenant armour powerup? + int permumbrella;// got the permenant umbrella powerup? int permmask; // got the permenant scuba mask powerup? int ontramp; // on a trampoline? @@ -878,6 +884,7 @@ typedef struct sprite_s { // player permenant powerups int armour; // does the player have armour? + int umbrella; // does the player have umbrella? int gemboost; // how many extra gems do you get in a bonus int netbig; // have we collected a BIG NET powerup? int hasbell; // got a bell ? @@ -933,7 +940,7 @@ typedef struct sprite_s { int falling; // are we falling? int dropping; // are we purposely dropping through solid ground? int dropx,dropy;// coords of tile we dropped from - int fallspeed; // how fast are we falling? + double fallspeed; // how fast are we falling? int jumping; // are we jumping? double jumpdir; //which way are we jumping? int jumpspeed; // how fast we are moving upwards diff --git a/rc.c b/rc.c index ee941bc..6fb8d74 100644 --- a/rc.c +++ b/rc.c @@ -129,6 +129,7 @@ int poweruptypes[] = { P_NUMNETS, P_GEMBOOST, P_HELMET, + P_UMBRELLA, P_WINGBOOTS, -1 }; @@ -1557,7 +1558,7 @@ void die(sprite_t *s) { Mix_ResumeMusic(); } - // turn off some powerups + // turn off some global powerups switch (globpowerup) { case PW_CLOCK: case PW_SPRAYUP: @@ -1567,6 +1568,10 @@ void die(sprite_t *s) { break; } + // lose normal powerups immediately + s->powerup = PW_NONE; + s->umbrella = B_FALSE; + resethurryup(curlevel); if (curmusic == fastmusic) { playmusic(normalmusic); @@ -6369,6 +6374,10 @@ void dogravity(sprite_t *s) { if (!s->jumptimer) { s->jumpdir = 0; } + // reset umbrella + if (s->umbrella) { + s->cancelumb = B_FALSE; + } if (s->falling && s->iced) { // when an iced monster hits the ground, it smashes @@ -6428,6 +6437,7 @@ void dogravity(sprite_t *s) { // constant speed - we are flying down, not falling s->y += getspeed(s); } else { + double termvel; if (isinwater(s) && !s->iced) { if (s->hasmask) { @@ -6441,9 +6451,17 @@ void dogravity(sprite_t *s) { s->y += s->fallspeed; } + if (s->umbrella && !s->cancelumb) { + termvel = UMBFALLSPEED; + } else { + termvel = FALLSPEED; + } + if ((timer % 10 == 0) && (s->fallspeed < FALLSPEED)) { s->fallspeed++; } + + if (s->fallspeed > termvel) s->fallspeed = termvel; } //} //} @@ -7441,6 +7459,12 @@ int dofruiteffect(sprite_t *pp, sprite_t *s) { addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY, TT_NORM); pp->powerup = PW_JETPACK; return B_TRUE; + } else if (s->id == P_UMBRELLA) { + playfx(FX_POWERUP); + sprintf(tempm, "Umbrella!"); + addoutlinetext(s->x,s->y - s->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY, TT_NORM); + pp->umbrella = B_TRUE; + return B_TRUE; } else if (s->id == P_BADMAGNET) { playfx(FX_SKULL); sprintf(tempm, "Repel fruits!"); @@ -9403,6 +9427,7 @@ if (cheat) { player->netsticky = B_TRUE; player->doublejump = B_TRUE; player->hasbell = B_TRUE; + player->umbrella = B_TRUE; player->hasmask = B_TRUE; addoutlinetext(player->x,player->y - player->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY,TT_NORM); } @@ -9414,6 +9439,7 @@ if (cheat) { player2->doublejump = B_TRUE; player2->hasbell = B_TRUE; player2->hasmask = B_TRUE; + player2->umbrella = B_TRUE; addoutlinetext(player2->x,player2->y - player2->img->h/2, TEXTSIZE_POINTS, tempm,&white,&black,POINTSDELAY,TT_NORM); } toggletimer = 80; @@ -11468,6 +11494,12 @@ void doplayermovement(sprite_t *pl) { pl->x = ladderx; } } + + if (pl->falling && !pl->swimming) { + if (pl->umbrella) { + pl->cancelumb = B_TRUE; + } + } } // Jump if (keydown(pnum,KEY_JUMP)) { diff --git a/shared.c b/shared.c index 811b26c..3d358dd 100644 --- a/shared.c +++ b/shared.c @@ -673,6 +673,19 @@ void setdefaults(sprite_t *s) { } else { s->armour = B_FALSE; } + + if (s->permumbrella) { + s->umbrella = B_TRUE; + if (s == player) { + s->id = P_ARMOUR; + } else { + s->id = P_ARMOUR2; + } + } else { + s->umbrella = B_FALSE; + } + + } else { if (s->id == P_PLATFORM) { s->speed = PLATFORM_MAXSPEED; @@ -684,6 +697,7 @@ void setdefaults(sprite_t *s) { s->armour = B_FALSE; s->netsticky = B_FALSE; s->doublejump = B_FALSE; + s->umbrella = B_FALSE; s->netbig = B_FALSE; s->netmax = 1; } @@ -701,7 +715,7 @@ void setdefaults(sprite_t *s) { s->hasbell = B_FALSE; s->gemboost = 1; - s->powerup = 0; + s->powerup = PW_NONE; // player-only states s->netting = 0; s->netcaught = 0; @@ -716,6 +730,8 @@ void setdefaults(sprite_t *s) { s->jumpspeed = 0; s->jumpdir = 1; s->useddoublejump = B_FALSE; + s->cancelumb = B_FALSE; + if (s->id != P_RANDOM) { // random gets timer1 set during addsprite() s->timer1 = 0; @@ -883,6 +899,7 @@ sprite_t *addsprite(int id, int x, int y, char *name ) { s->permdoublejump = B_FALSE; s->permarmour = B_FALSE; s->permmask = B_FALSE; + s->permumbrella = B_FALSE; s->lostlife = B_FALSE; @@ -1551,6 +1568,7 @@ int loadimagesets(void) { loadspriteimage(P_ANCHOR,F_WALK1, "sprites/anchor.png"); imageset[P_ANCHOR].numimages = 1; + loadspriteimage(P_SMALLANCHOR,F_WALK1, "sprites/smallanchor.png"); imageset[P_SMALLANCHOR].numimages = 1; @@ -1563,6 +1581,12 @@ int loadimagesets(void) { loadspriteimage(P_JETPACK,F_WALK1, "sprites/jetpack.png"); imageset[P_JETPACK].numimages = 1; + loadspriteimage(P_UMBRELLA,F_WALK1, "sprites/umbrella.png"); + imageset[P_UMBRELLA].numimages = 1; + + loadspriteimage(P_BIGUMBRELLA,F_WALK1, "sprites/bigumbrella.png"); + imageset[P_BIGUMBRELLA].numimages = 1; + loadspriteimage(P_CAMERA,F_WALK1, "sprites/camera.png"); imageset[P_CAMERA].numimages = 1; @@ -2429,6 +2453,7 @@ int isfruit(int id) { case P_HELMET: case P_MASKPOWERUP: case P_WINGBOOTS: + case P_UMBRELLA: return FT_PERM; /* one-off level only powerups */ case P_BOXING: @@ -2521,6 +2546,7 @@ int iseffect(int id) { // these last ones aren't REALLY effects since they never have a sprite allocated case P_WINGLEFT: case P_WINGRIGHT: + case P_BIGUMBRELLA: case P_SMALLANCHOR: return B_TRUE; } @@ -3106,7 +3132,7 @@ int loadlevellist(void) { int randompowerup(void) { int num; - num = rand() % 43; + num = rand() % 44; switch (num) { case 0: @@ -3201,6 +3227,8 @@ int randompowerup(void) { return P_JETPACK; case 42: return P_CAMERA; + case 43: + return P_UMBRELLA; } } @@ -3352,6 +3380,7 @@ void setfruitinfo(void) { setinfo(P_MAGNET, "Magnet", "Collecting this powerup will align the magnetic forces of the earth in your favour, attracting all nearby fruits towards you.", "magnet.png"); setinfo(P_BADMAGNET, "Red Skull", "This skull curses you and will repel fruits away from you, denying you access to them!", "badmagnet.png"); setinfo(P_JETPACK, "Jetpack", "For the remainder of the current level, the jetpack's thrust will add to your jumping ability!", "jetpack.png"); + setinfo(P_UMBRELLA, "Umbrella", "Slows your descent giving you more time to contemplate your rat eradication quest.", "umbrella.png"); setinfo(P_CAMERA, "Camera", "Creates a bright flash of light, blinding all enemies.", "camera.png"); setinfo(P_ZAPPOWERUP, "Bug Zapper", "Zaps nearby enemies with miniature bolts of lightning", "zapper.png"); setinfo(P_SKULL, "Green Skull", "Avoid these at all costs! The green skull will shrink your net to miniscule proportions for the remainder of the level.", "skull.png"); @@ -3959,6 +3988,10 @@ void drawplayer(sprite_t *s, SDL_Rect *where) { wingarea.y -= 9; } + if (s == player2) { + wingarea.x -= (4 * s->dir); + } + // when climbing, show "left" wing twice instead // when swimming, only show left wing if (!s->climbing && !s->swimming) { @@ -3968,6 +4001,8 @@ void drawplayer(sprite_t *s, SDL_Rect *where) { } #endif + + if ((levelcomplete == LV_CLOUDLOOP) || (levelcomplete == LV_NEXTLEV)) { s->img = imageset[s->id].img[F_SHOOT]; } @@ -4023,6 +4058,34 @@ void drawplayer(sprite_t *s, SDL_Rect *where) { doblit(imageset[P_WINGLEFT].img[wingframe], screen, &wingarea); } } + + + // draw umbrella + if (s->umbrella && !s->cancelumb) { + if (!s->swimming && !s->climbing) { + SDL_Rect umarea; + if (s->netting) { + if (s->dir == D_RIGHT) { + umarea.x = s->x - 11 - 10; + } else { + umarea.x = s->x - 11 + 10; + } + umarea.y = s->y - s->img->h - 2; + } else if (s->falling) { + if (s->dir == D_RIGHT) { + umarea.x = s->x - 11 - 8; + } else { + umarea.x = s->x - 11 + 8; + } + umarea.y = s->y - s->img->h - 9; + } else { + umarea.x = s->x - 11; + umarea.y = s->y - s->img->h - 2; + } + doblit(imageset[P_BIGUMBRELLA].img[F_WALK1], screen, &umarea); + } + } + #endif } diff --git a/website/img/umbrella.png b/website/img/umbrella.png new file mode 100644 index 0000000..95bc158 Binary files /dev/null and b/website/img/umbrella.png differ diff --git a/website/info.html b/website/info.html index a76cf60..983ac13 100644 --- a/website/info.html +++ b/website/info.html @@ -49,8 +49,9 @@
HoneyCoats your net in a layer of sticky honey, allowing it to pick up fruits from afar.
Scuba MaskAllows you to move fast underwater.
Winged BootsThese magical boots cause you to grow wings, allowing to you jump again while in mid-air! -
CardKeep a look out for these useful items. Collect a full poker hand for a secret bonus! -Temporary Powerups +
UmbrellaSlows your descent giving you more time to contemplate your rat eradication quest. +
CardKeep a look out for these useful items. Collect a full poker hand for a secret bonus! + Temporary Powerups
Boxing GloveYour net will punch monsters, killing them instantly.
Diamond FlowerTransforms all flowers on the level into diamonds.
Rainbow FlowerTransforms all flowers on the level into gems, and turns itself into an extra-long stream of gems.