- bugfix: walk ring shouldn't work while swimming

- bugfix: fixed ladders behaviour
- bugfix: dont play splash sound effect for mosnters which start in the water
- added boss music
- top/bottom of screen now wrap around
- bees no longer avoid the top/bottom of the screen
- added new moster: snail/slug
- swimming sprites now create bubblse
This commit is contained in:
Rob Pearce 2008-10-09 03:32:15 +00:00
parent dba3c41970
commit 04a7f02211
15 changed files with 802 additions and 889 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 KiB

After

Width:  |  Height:  |  Size: 354 KiB

16
defs.h
View File

@ -78,6 +78,7 @@
// Game mechanics // Game mechanics
#define INVULNTIME 200 // how long player stays invulnerable for #define INVULNTIME 200 // how long player stays invulnerable for
#define SLUGINVULNTIME 50 // how long a new slug stays invulnerable for
#define SHIELDTIME 500 // how long a shield lasts #define SHIELDTIME 500 // how long a shield lasts
#define FALLSPEED 4 // terminal velocity of falling sprites #define FALLSPEED 4 // terminal velocity of falling sprites
#define NETSPEED 9 // how fast the player's net moves #define NETSPEED 9 // how fast the player's net moves
@ -85,6 +86,8 @@
#define PLAYERFAST 2 // how fast player goes with speed powerup #define PLAYERFAST 2 // how fast player goes with speed powerup
#define BUBBLETIME 200 // how oftem bubbles appear
#define CANNONSIZE 10 #define CANNONSIZE 10
@ -131,7 +134,7 @@
// Limits // Limits
#define MAXLEVELS 100 #define MAXLEVELS 100
#define MAXMAPPINGS 50 #define MAXMAPPINGS 50
#define MAXMONSTERSPERLEVEL 40 #define MAXMONSTERSPERLEVEL 60
#define MAXLETTERHEIGHT 100 #define MAXLETTERHEIGHT 100
#define MAXFRAMES 18 // max number of frames for sprites #define MAXFRAMES 18 // max number of frames for sprites
#define MAXHELP 5 #define MAXHELP 5
@ -164,7 +167,7 @@
/* enums */ /* enums */
/* sounds */ /* sounds */
#define MAXFX 33 #define MAXFX 34
#define FX_SHOOT 0 #define FX_SHOOT 0
#define FX_SLAM 1 #define FX_SLAM 1
#define FX_KILL 2 #define FX_KILL 2
@ -198,6 +201,7 @@
#define FX_BOSSWALL 30 #define FX_BOSSWALL 30
#define FX_SPRAY 31 #define FX_SPRAY 31
#define FX_CANNON 32 #define FX_CANNON 32
#define FX_CRACK 33
// Slope types // Slope types
#define S_NOTSOLID 0 #define S_NOTSOLID 0
@ -205,7 +209,7 @@
#define S_SLOPE 2 #define S_SLOPE 2
// Sprite types // Sprite types
#define MAXPTYPES 49 #define MAXPTYPES 52
#define P_PLAYER 0 #define P_PLAYER 0
#define P_RAT 1 #define P_RAT 1
#define P_CHEESE 2 #define P_CHEESE 2
@ -255,6 +259,9 @@
#define P_SPRAY 46 #define P_SPRAY 46
#define P_CANNONPOWERUP 47 #define P_CANNONPOWERUP 47
#define P_CANNON 48 #define P_CANNON 48
#define P_SNAIL 49
#define P_SLUG 50
#define P_BUBBLE 51
// powerups // powerups
#define PW_NONE 0 #define PW_NONE 0
@ -530,6 +537,7 @@ typedef struct sprite_s {
int timer1; // int timer1; //
int timer2; // int timer2; //
int timer3; // int timer3; //
int watertimer; //
// GAME MECHANICS // GAME MECHANICS
@ -569,7 +577,7 @@ extern int vidargs;
extern int toggletimer; extern int toggletimer;
extern TTF_Font *font[]; extern TTF_Font *font[];
extern int musicplaying; extern int musicplaying;
extern Mix_Music *music, *normalmusic, *fastmusic; extern Mix_Music *music, *normalmusic, *fastmusic, *bossmusic;
extern Mix_Chunk *sfx[]; extern Mix_Chunk *sfx[];
extern int oldexitdir; extern int oldexitdir;
extern int levelcomplete; extern int levelcomplete;

35
edit.c
View File

@ -449,6 +449,12 @@ int main (int argc, char **argv) {
toggletimer = 30; toggletimer = 30;
} }
} }
if (keys[SDLK_f]) {
if (toggletimer == 0) {
filllevel();
toggletimer = 30;
}
}
@ -922,6 +928,27 @@ int savelevel(int wnum, int lnum) {
return 0; return 0;
} }
void filllevel(void) {
int offset,x,y;
if (seltile == NULL) {
setstatustext("No tile selected for fill!",&red);
} else {
/* fill level with current tile*/
for (x = 0; x < LEVELW; x++) {
for (y = 0; y < LEVELH; y++) {
offset = y*LEVELW+x;
curlevel->map[offset] = seltile->uniqid;
curlevel->map2[offset] = T_BLANK;
draweditortile(screen,x,y);
}
}
}
modified = B_TRUE;
}
void clearlevel(void) { void clearlevel(void) {
int offset,x,y; int offset,x,y;
@ -984,6 +1011,14 @@ int isplacablesprite(int sid) {
case P_SPRAY: case P_SPRAY:
case P_CANNONPOWERUP: case P_CANNONPOWERUP:
case P_CANNON: case P_CANNON:
case P_TROPHY:
case P_SNOWMAN:
case P_RINGSILVER:
case P_RINGGOLD:
case P_CLOCK:
case P_BELL:
case P_GEMBOOST:
case P_HELMET:
return B_FALSE; return B_FALSE;
} }
return B_TRUE; return B_TRUE;

1
edit.h
View File

@ -46,6 +46,7 @@ int savelevel(int wnum, int lnum);
void cleanup(void); void cleanup(void);
void usage(void); void usage(void);
void clearlevel(void); void clearlevel(void);
void filllevel(void);
int isplacabletile(int tid); int isplacabletile(int tid);
int isplacablesprite(int sid); int isplacablesprite(int sid);

View File

@ -24,7 +24,7 @@ sprite_t *lastsprite; // tail of sprite linked list
sprite_t *player; // pointer to the player's sprite sprite_t *player; // pointer to the player's sprite
sprite_t *boss; // point to current boss on level (normally NULL) sprite_t *boss; // point to current boss on level (normally NULL)
Mix_Music *music, *fastmusic, *normalmusic; Mix_Music *music, *fastmusic, *normalmusic,*bossmusic;
Mix_Chunk *sfx[MAXFX]; Mix_Chunk *sfx[MAXFX];
text_t *text, *lasttext; text_t *text, *lasttext;

View File

@ -277,3 +277,65 @@ id 1
solid 1 solid 1
file newtiles/landse.png file newtiles/landse.png
end end
tile sand
id 1
solid 1
file newtiles/sand.png
end
tile sandtop
id 1
solid 1
file newtiles/sandtop.png
end
tile sandtopw
id 1
solid 1
file newtiles/sandtopw.png
end
tile sandtope
id 1
solid 1
file newtiles/sandtope.png
end
tile sandslopeup
id 2
solid 2
lowness 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
file newtiles/sandslopeup.png
end
tile sandslopedown
id 3
solid 2
lowness 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
file newtiles/sandslopedown.png
end
tile sandsw
id 1
solid 1
file newtiles/sandsw.png
end
tile sandse
id 1
solid 1
file newtiles/sandse.png
end
tile sandstone
id 1
solid 1
file newtiles/sandstone.png
end
tile sandbg
id 5
solid 0
file newtiles/sandbg.png
end

View File

@ -15,7 +15,12 @@
14,level12.dat,Bee Pods 14,level12.dat,Bee Pods
15,level13.dat,Dual Hives 15,level13.dat,Dual Hives
16,level14.dat,The Chimney 16,level14.dat,The Chimney
19,level21.dat,Island 19,theisland.dat,Island
18,level8.5.dat,Look out above... 18,level8.5.dat,Look out above...
20,level20.dat,King Rat 20,level20.dat,King Rat
21,level21.dat,The Beach
100,level100.dat,Snails and Slugs
22,level22.dat,Platforms in the Sand
23,level23.dat,Twisty Little Passages
101,level101.dat,Sand Castle
99,level99.dat,TEST LEVEL 99,level99.dat,TEST LEVEL

497
rc.c
View File

@ -398,15 +398,21 @@ int main (int argc, char **argv) {
} }
} }
if (keys[SDLK_UP]) { if (keys[SDLK_UP]) {
//if (isonladder(player) || isladderabove(player)) {
if (player->climbing || isladderabove(player)) { if (player->climbing || isladderabove(player)) {
if (!player->netting && !player->slamming) { if (!player->netting && !player->slamming) {
player->y -= getspeed(player); // if tile above is non-solid, or a ladder
player->jumping = 0; if (isladderabove(player) || !isroofabove(player)) {
player->falling = 0; // if not jumping
player->climbing = B_TRUE; if (!player->jumping) {
player->moved = MV_WALK; player->y -= getspeed(player);
player->jumping = 0;
player->falling = 0;
player->climbing = B_TRUE;
player->moved = MV_WALK;
}
}
} }
//}
} }
} }
if (keys[SDLK_DOWN]) { if (keys[SDLK_DOWN]) {
@ -600,6 +606,7 @@ int main (int argc, char **argv) {
if (levelcomplete == LV_INIT) { if (levelcomplete == LV_INIT) {
// only player // only player
dogravity(player); dogravity(player);
checkwrap(player);
dotileeffects(player); dotileeffects(player);
} else { } else {
sprite_t *s; sprite_t *s;
@ -612,6 +619,7 @@ int main (int argc, char **argv) {
/* gravity */ /* gravity */
for (s = sprite ; s ; s = s->next) { for (s = sprite ; s ; s = s->next) {
dogravity(s); dogravity(s);
checkwrap(s);
} }
/* tile effects */ /* tile effects */
@ -696,6 +704,7 @@ int main (int argc, char **argv) {
if (ismonster(s3->id) && !s3->dead) { if (ismonster(s3->id) && !s3->dead) {
if ((yy >= s3->y - s3->img->h) && (yy <= s3->y)) { if ((yy >= s3->y - s3->img->h) && (yy <= s3->y)) {
s3->willbecome = P_DIAMOND; s3->willbecome = P_DIAMOND;
if (s3->id == P_SNAIL) s3->id = P_SLUG;
die(s3); die(s3);
} }
} }
@ -709,6 +718,7 @@ int main (int argc, char **argv) {
if (ismonster(s3->id) && !s3->dead) { if (ismonster(s3->id) && !s3->dead) {
if ((xx >= s3->x - (s3->img->w/2)) && (xx <= s3->x + (s3->img->w/2))) { if ((xx >= s3->x - (s3->img->w/2)) && (xx <= s3->x + (s3->img->w/2))) {
s3->willbecome = P_DIAMOND; s3->willbecome = P_DIAMOND;
if (s3->id == P_SNAIL) s3->id = P_SLUG;
die(s3); die(s3);
} }
} }
@ -1006,10 +1016,21 @@ void nextlevel(void) {
playedbell = BELL_DONEFLASH; playedbell = BELL_DONEFLASH;
} }
// if this is boss level, play music
if (isbosslevel(curlevelnum)) {
stopmusic();
playmusic(bossmusic);
} else {
if (curmusic != normalmusic) {
stopmusic();
playmusic(normalmusic);
}
}
level->iced = ICE_NONE; level->iced = ICE_NONE;
level->icey = -1; level->icey = -1;
sprintf(msg, "Level %d-%d",curworld, curlevelnum); sprintf(msg, "Level %d-%d",getcurworld(), getcurlevel());
addoutlinetext(320,240-18,TEXTSIZE_LEVEL,msg,&white,&black,LEVELDELAY); addoutlinetext(320,240-18,TEXTSIZE_LEVEL,msg,&white,&black,LEVELDELAY);
@ -1028,12 +1049,6 @@ void nextlevel(void) {
cloudp = addsprite(P_PINKCLOUD, player->x,player->y + (imageset[P_PINKCLOUD].img[F_WALK1]->h / 2),"initial_pinkcloud"); cloudp = addsprite(P_PINKCLOUD, player->x,player->y + (imageset[P_PINKCLOUD].img[F_WALK1]->h / 2),"initial_pinkcloud");
cloudp->size = 1.0; cloudp->size = 1.0;
// TODO: add boss every 20 levles
//if (curlevel % 20 == 0) {
//}
if (cheat) { if (cheat) {
player->speed = 2; player->speed = 2;
} }
@ -1055,19 +1070,30 @@ void jump(sprite_t *s, int dir) {
} }
} }
// check for recoiling here, because we always need to be able to
// "jump" backwards, even if already jumping
if (s->recoiling || isonground(s) || isinwater(s) || isonladder(s)) { if (s->recoiling || isonground(s) || isinwater(s) || isonladder(s)) {
if (ismonster(s->id)) { if (ismonster(s->id)) {
s->jumpdir = dir; if (s->recoiling) { // recoiling monsters don't pause before jumping
if (s->jumpdir != 0) { s->jumpspeed = MONJUMPSPEED;
s->dir = s->jumpdir;
}
// special case
if ((s->id == P_KINGRAT) && (s->timer1 == KRS_CHARGEWAIT)) {
s->jumpspeed = MONJUMPSPEED; // will be changed later
s->jumping = 1; s->jumping = 1;
s->jumpdir = dir;
s->dir = -s->jumpdir; // face backwards
} else { } else {
s->jumptimer = 60; s->jumpdir = dir;
s->willjumpspeed = MONJUMPSPEED; if (s->jumpdir != 0) {
s->dir = s->jumpdir;
}
// special case
if ((s->id == P_KINGRAT) && (s->timer1 == KRS_CHARGEWAIT)) {
// jump right away
s->jumpspeed = MONJUMPSPEED; // will be changed later
s->jumping = 1;
} else {
// delay then jump
s->jumptimer = getjumpdelay(s->id);
s->willjumpspeed = getmonjumpspeed(s);
}
} }
} else { } else {
s->jumpdir = dir; s->jumpdir = dir;
@ -1085,14 +1111,17 @@ void jump(sprite_t *s, int dir) {
} }
// stop climbing // stop climbing
s->climbing = B_FALSE; s->climbing = B_FALSE;
// stop recoiling
s->recoiling = B_FALSE;
// play a sound effect if this is the player
if (s == player) { if (s == player) {
if (player->ontramp) { // stop recoiling
playfx(FX_SPRING); if (s->recoiling) {
s->recoiling = B_FALSE;
} else { } else {
playfx(FX_JUMP); // play sound effect
if (player->ontramp) {
playfx(FX_SPRING);
} else {
playfx(FX_JUMP);
}
} }
} }
@ -1160,7 +1189,7 @@ void die(sprite_t *s) {
} }
} }
// un-ice everything // un-ice everything if player dies
if (s == player) { if (s == player) {
for (s2 = sprite->next ; s2 ; s2 = s2->next) { for (s2 = sprite->next ; s2 ; s2 = s2->next) {
if (s2->iced) { if (s2->iced) {
@ -1182,12 +1211,48 @@ void die(sprite_t *s) {
s->timer3 = BOSSDIETIME; s->timer3 = BOSSDIETIME;
} }
/* set death attribute */
s->dead = D_INITIAL; // snails can't die but turn into slugs instead
s->netting = 0; if ((s->id == P_SNAIL) && (s->lives > 0)) {
s->slamming = 0; sprite_t *newsp;
s->iced = 0;
s->angry = 0; // create a slug here
newsp = addsprite(P_SLUG, s->x,s->y, "slug" );
puffin(-1, s->x, s->y, "nothing", 0); // create the illusion of a puff
newsp->dir = player->dir; // facing away from player
// make sure it can't be netted right away!
if (player->powerup != PW_CLOCK) {
newsp->invuln = SLUGINVULNTIME;
}
// recoil (other code will kill us off when this is done
// -become invulnerable temporarily
s->invuln = INVULNTIME*2; // make sure this lasts until we die
// -bounce back
s->recoiling = B_TRUE;
jump(s,player->dir); // ie. away from the player
playfx(FX_CRACK);
// when we hit the ground, later code will check for this.
// if a snail with lives=0 hits the ground, they die (it actually
// looks like a shell)
s->lives = 0;
// attributes
s->angry = 0;
s->iced = 0;
} else {
/* set death attribute */
s->dead = D_INITIAL;
s->netting = 0;
s->slamming = 0;
s->iced = 0;
s->angry = 0;
}
// check for level clear // check for level clear
checklevelend(); checklevelend();
@ -1265,7 +1330,7 @@ void checkcollide(sprite_t *s) {
/* check for colission with our net */ /* check for colission with our net */
if (s->netting ) { if (s->netting ) {
if (isnettable(s2->id)) { if (isnettable(s2->id) && !s2->invuln) {
xdiff = (s->x + s->netlen*s->netdir) - s2->x; xdiff = (s->x + s->netlen*s->netdir) - s2->x;
if (xdiff < 0) xdiff = -xdiff; if (xdiff < 0) xdiff = -xdiff;
ydiff = s->netystart - (s2->y - s2->img->h/2); ydiff = s->netystart - (s2->y - s2->img->h/2);
@ -1309,6 +1374,7 @@ void checkcollide(sprite_t *s) {
} else if (s2->iced) { } else if (s2->iced) {
// it dies // it dies
playfx(FX_ICEBREAK); playfx(FX_ICEBREAK);
if (s2->id == P_SNAIL) s2->id = P_SLUG;
die(s2); die(s2);
} else { } else {
// otherwise we caught it if we have enough nets // otherwise we caught it if we have enough nets
@ -1456,7 +1522,8 @@ if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
/* avoid edges of screen */ /* avoid edges of screen */
if (s->y < s->img->h) { if (s->y < s->img->h) {
if (!s->flies) { // if (!s->flies) {
if (s->dead) {
s->y = s->img->h; s->y = s->img->h;
} }
} }
@ -1522,7 +1589,7 @@ if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
} }
/* if we've fallen off the bottom... */ /* if we've fallen off the bottom... */
if (s->y >= 480) { if (s->y >= (480+s->img->h)) {
/* pause before respawning */ /* pause before respawning */
s->jumpspeed = 0; /* this is now a timer */ s->jumpspeed = 0; /* this is now a timer */
s->dead = D_LASTBOUNCE; s->dead = D_LASTBOUNCE;
@ -1646,7 +1713,9 @@ if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
if (s->jumpdir != 0) s->dir = s->jumpdir; if (s->jumpdir != 0) s->dir = s->jumpdir;
return B_FALSE; return B_FALSE;
} else if (s->jumptimer % 20 == 0) { } else if (s->jumptimer % 20 == 0) {
s->dir = -s->dir; if (s->id != P_SLUG) { // slugs don't turn back and forth before jumping
s->dir = -s->dir;
}
} }
} else if ((s->id == P_PUFF) || (s->id == P_SMASH) || (s->id == P_SPARKLE)) { } else if ((s->id == P_PUFF) || (s->id == P_SMASH) || (s->id == P_SPARKLE)) {
/* SUMMARY: /* SUMMARY:
@ -1686,15 +1755,34 @@ if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
case P_KINGRAT: case P_KINGRAT:
boss = newsp; boss = newsp;
} }
// is it in the water?
if (isinwater(newsp)) {
newsp->swimming = B_TRUE;
newsp->watertimer = rand() % BUBBLETIME;
}
} }
} }
} else if (s->timer1 >= PUFFFRAMES) { } else if (s->timer1 >= PUFFFRAMES) {
s->timer1 = 999; // TODO: REMOVE THIS - debugging! s->timer1 = 999; // for debugging
s->dead = D_FINAL; s->dead = D_FINAL;
} }
} }
} }
} else if (s->id == P_BUBBLE) { // bubble effect
tiletype_t *tt;
// float up, die when we leave the water
tt = gettileat(s->x,s->y, NULL,NULL);
if (tt->water) {
s->y -= 0.5;
// move left/right
s->x += (sin(s->y/5)/5);
} else {
// die
s->dead = D_FINAL;
}
} else if (s->id == P_CANNON) { // cannon effect } else if (s->id == P_CANNON) { // cannon effect
// die if player dies // die if player dies
if (player->dead) { if (player->dead) {
@ -1749,6 +1837,7 @@ if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
if (!s->falling) { if (!s->falling) {
int move = B_FALSE; int move = B_FALSE;
int xdiff, absxdiff; int xdiff, absxdiff;
tiletype_t *tunder;
/* distance to player */ /* distance to player */
@ -1756,21 +1845,29 @@ if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
if (xdiff < 0) absxdiff = -xdiff; if (xdiff < 0) absxdiff = -xdiff;
else absxdiff = xdiff; else absxdiff = xdiff;
tt = gettileat(s->x + s->dir+getspeed(s) + (s->dir * (s->img->w/2)),s->y,NULL,NULL); // tile in front and below
/* if there's a hole in front of us */ tt = gettileat(s->x + s->dir*getspeed(s) + (s->dir * (s->img->w/2)),s->y + (TILEH/2),NULL,NULL);
// tile below
tunder = gettileat(s->x ,s->y + 1,NULL,NULL);
/* if there's a hole in front of us and below*/
if (tt->solid == S_NOTSOLID) { if (tt->solid == S_NOTSOLID) {
if ((player->y > s->y) && (s->angry || boss)) { // we're on a slope
/* if player is below, fall off */ if (tunder->solid == S_SLOPE) {
if (xdiff <= (TILEW*8)) { move = B_TRUE;
move = B_TRUE; } else {
} if (s->angry || boss) {
} else if (player->y == s->y) { if (player->y > s->y) {
if ((s->angry) || boss) { /* if player is below, fall off */
/* if player is at same level and close, jump */ if (xdiff <= (TILEW*8)) {
if ((s->dir == D_RIGHT) && (xdiff > 0) && (xdiff <= (TILEW*7))) { move = B_TRUE;
jump(s,D_RIGHT); }
} else if ((s->dir == D_LEFT) && (xdiff < 0) && (xdiff >= -(TILEW*7))) { } else if (player->y == s->y) {
jump(s,D_LEFT); /* if player is at same level and close, jump */
if ((s->dir == D_RIGHT) && (xdiff > 0) && (xdiff <= (TILEW*7))) {
jump(s,D_RIGHT);
} else if ((s->dir == D_LEFT) && (xdiff < 0) && (xdiff >= -(TILEW*7))) {
jump(s,D_LEFT);
}
} }
} }
} }
@ -1818,6 +1915,128 @@ if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
} }
} }
} }
} else { // falling
tiletype_t *tunder, *t2under;
// tile below
tunder = gettileat(s->x ,s->y,NULL,NULL);
t2under = gettileat(s->x ,s->y+s->img->h,NULL,NULL);
if ((tunder->solid == S_SLOPE) || (t2under->solid == S_SLOPE)) {
movex(s, s->dir*getspeed(s));
}
}
} else if (s->id == P_SNAIL) {
if (!s->falling) {
int move = B_FALSE;
int xdiff, absxdiff;
/* distance to player */
xdiff = player->x - s->x;
if (xdiff < 0) absxdiff = -xdiff;
else absxdiff = xdiff;
tt = gettileat(s->x + s->dir+getspeed(s) + (s->dir * (s->img->w/2)),s->y,NULL,NULL);
/* if there's a hole in front of us */
if (tt->solid == S_NOTSOLID) {
if ((player->y > s->y) && (s->angry || boss)) {
/* if player is below, fall off */
if (xdiff <= (TILEW*8)) {
move = B_TRUE;
}
}
} else {
move = B_TRUE;
}
/* either move or turn around */
if (move) {
rv = movex(s, s->dir*getspeed(s));
if (rv) {
/* if we couldn't move (hit a wall), turn */
s->dir = -s->dir;
}
} else {
s->dir = -s->dir;
}
} else { // falling
if (s->recoiling) {
// fall backwards
rv = movex(s, -s->dir*getspeed(s));
}
}
} else if (s->id == P_SLUG) {
if (!s->falling) {
int move = B_FALSE;
int xdiff, absxdiff;
/* distance to player */
xdiff = player->x - s->x;
if (xdiff < 0) absxdiff = -xdiff;
else absxdiff = xdiff;
tt = gettileat(s->x + s->dir+getspeed(s),s->y,NULL,NULL);
/* if there's a hole in front of us */
if (tt->solid == S_NOTSOLID) {
if (player->y > s->y ) {
/* if player is below and nearby, fall off */
if (xdiff <= (TILEW*16)) {
move = B_TRUE;
}
} else if (player->y == s->y) {
/* if player is at same level and close, try to jump over the gap */
if ((s->dir == D_RIGHT) && (xdiff > 0) && (xdiff <= (TILEW*9))) {
jump(s,D_RIGHT);
} else if ((s->dir == D_LEFT) && (xdiff < 0) && (xdiff >= -(TILEW*9))) {
jump(s,D_LEFT);
}
}
} else {
move = B_TRUE;
}
/* either move or turn around */
if (move) {
rv = movex(s, s->dir*getspeed(s));
if (rv) {
/* if we couldn't move (hit a wall), turn */
s->dir = -s->dir;
}
} else {
s->dir = -s->dir;
}
/* moves like an angry rat all the time */
if ((player->dead == 0) && (!s->jumping) && (!s->jumptimer)) {
/* if player is above us or at same level...*/
if (player->y <= s->y) {
int ydiff = s->y - player->y;
if ((ydiff >= (TILEH*4)) && (ydiff <= (TILEH*8))) { // player between 4 and 8 tiles above
if (xdiff <= (TILEW*16)) { // if closeish horizontally
/* jump up */
jump(s, 0);
}
} else if ((xdiff >= (TILEW*1)) && (xdiff <= (TILEW*9))) { // if 1-9 tiles right
if (s->dir == D_RIGHT) {
/* jump right */
jump(s, D_RIGHT);
}
} else if ((xdiff <= -(TILEW*1)) && (xdiff >= -(TILEW*9))) { // if 1-9 tiles left
if (s->dir == D_LEFT) {
/* jump left */
jump(s, D_LEFT);
}
}
}
}
} else { // falling
int rv;
// move forwards
rv = movex(s, s->dir*getspeed(s));
} }
} else if (s->id == P_KINGRAT) { } else if (s->id == P_KINGRAT) {
/* timer1 is state /* timer1 is state
@ -2175,13 +2394,6 @@ if (s->id == P_PUFF) printf("PUFF WITH DOOMCOUNT!\n");
s->ys = -s->ys; s->ys = -s->ys;
} }
/* check for top of screen */
// TODO: later, remove this when we can wrap around
if ((s->y <= s->img->h) && (s->ys < 0)) {
s->ys = -s->ys;
}
/* move */ /* move */
s->x += s->xs; s->x += s->xs;
s->y += s->ys; s->y += s->ys;
@ -2938,6 +3150,19 @@ double getspeed(sprite_t *s ) {
if (s == player) { if (s == player) {
speed = s->speed; speed = s->speed;
} else if (id == P_SNAIL) {
if (s->recoiling) {
speed = 2;
} else {
if (s->angry) speed = 1;
else speed = 0.5;
}
} else if (id == P_SLUG) {
if (s->angry) speed = 1;
else speed = 0.5;
if (s->jumping) {
speed = 8; // very fast jumping
}
} else if (id == P_RAT) { } else if (id == P_RAT) {
if (s->angry) speed = 1.5; if (s->angry) speed = 1.5;
else speed = 1; else speed = 1;
@ -3101,7 +3326,7 @@ void drawscore(void) {
} }
// level # // level #
sprintf(tempm, "Level %d-%d",curworld, curlevelnum); sprintf(tempm, "Level %d-%d",getcurworld(), getcurlevel());
/* shadow */ /* shadow */
score = TTF_RenderText_Solid(font[TEXTSIZE_SCORE], tempm, black); score = TTF_RenderText_Solid(font[TEXTSIZE_SCORE], tempm, black);
area.x = 320-(score->w/2)-2; area.x = 320-(score->w/2)-2;
@ -3331,13 +3556,19 @@ int isonladder(sprite_t *s) {
return B_TRUE; return B_TRUE;
} }
// if ladder bove and climbing
if (isladderabove(s) && s->climbing) {
return B_TRUE;
}
return B_FALSE; return B_FALSE;
} }
int isladderabove(sprite_t *s) { int isladderabove(sprite_t *s) {
tiletype_t *tthere; tiletype_t *tthere;
tthere = gettileat(s->x,s->y-TILEH, NULL,NULL); //tthere = gettileat(s->x,s->y-TILEH, NULL,NULL);
if (tthere->id == T_LADDER) { tthere = gettileat(s->x,s->y-s->img->h, NULL,NULL);
if (isladder(tthere->id)) {
return B_TRUE; return B_TRUE;
} }
@ -3542,10 +3773,19 @@ void dogravity(sprite_t *s) {
if (isinwater(s)) { if (isinwater(s)) {
if (!s->swimming) { if (!s->swimming) {
s->swimming = B_TRUE; s->swimming = B_TRUE;
s->watertimer = rand() % BUBBLETIME;
playfx(FX_SPLASH); playfx(FX_SPLASH);
if (s == player) adjustx(s, F_SWIM1); if (s == player) adjustx(s, F_SWIM1);
else adjustx(s, F_WALK1); else adjustx(s, F_WALK1);
} }
// generate bubbles
// just use s->x and s->y to add randomness, so that
// all sprites don't make bubbles at the same time
s->watertimer++;
if (s->watertimer >= BUBBLETIME) {
addsprite(P_BUBBLE,s->x + (s->dir*((s->img->w/4)+(rand() % 12 - 6))),s->y-(s->img->h/2),"bubble" );
s->watertimer = 0;
}
} else { } else {
if (s->swimming) { if (s->swimming) {
s->swimming = B_FALSE; s->swimming = B_FALSE;
@ -3565,7 +3805,6 @@ void dogravity(sprite_t *s) {
//if (isonground(s)) { //if (isonground(s)) {
if (isongroundpoint(s, s->x, s->y)) { if (isongroundpoint(s, s->x, s->y)) {
if (!isongroundpoint(s, s->x, s->y-1)) { if (!isongroundpoint(s, s->x, s->y-1)) {
attop = B_TRUE;
attop = B_TRUE; attop = B_TRUE;
} }
} }
@ -3639,6 +3878,9 @@ void dogravity(sprite_t *s) {
s->falling = B_FALSE; s->falling = B_FALSE;
s->climbing = B_FALSE; s->climbing = B_FALSE;
} }
} else if ((s->id == P_SNAIL) && (s->lives == 0) && s->falling) {
// snail dies
s->dead = D_FINAL;
} else { // everyone else } else { // everyone else
s->dropping = B_FALSE; s->dropping = B_FALSE;
s->falling = B_FALSE; s->falling = B_FALSE;
@ -3650,6 +3892,7 @@ void dogravity(sprite_t *s) {
//if ((s->id == P_KINGRAT) && ((s->timer1 == KRS_CHARGE) || (s->timer1 == KRS_WALK))) { //if ((s->id == P_KINGRAT) && ((s->timer1 == KRS_CHARGE) || (s->timer1 == KRS_WALK))) {
// do nothing // do nothing
//} else { //} else {
//if (!s->climbing) {
if (s->falling == B_FALSE) { if (s->falling == B_FALSE) {
s->fallspeed = 1; s->fallspeed = 1;
} }
@ -3663,6 +3906,8 @@ void dogravity(sprite_t *s) {
s->fallspeed++; s->fallspeed++;
} }
//} //}
//}
} }
} }
@ -3787,13 +4032,21 @@ void dogravity(sprite_t *s) {
curfruittype = 0; curfruittype = 0;
} }
} }
if ((player->powerup == PW_MACE) && (s2->id == P_SNAIL)) {
// turn into a slug so that it really dies
s2->id = P_SLUG;
}
die(s2); die(s2);
pointsinc *= 2;
psize += 10; if ((player->powerup == PW_MACE) || (s2->id != P_SNAIL)) {
pointsinc *= 2;
psize += 10;
gotsomething++;
}
xnet = s2->x; xnet = s2->x;
ynet = s2->y - s2->img->h/2; ynet = s2->y - s2->img->h/2;
gotsomething++;
} else { } else {
/* otherwise it gets angry */ /* otherwise it gets angry */
s2->angry = B_TRUE; s2->angry = B_TRUE;
@ -3813,7 +4066,7 @@ void dogravity(sprite_t *s) {
if (gotsomething || (player->powerup == PW_MACE)) { if (gotsomething || (player->powerup == PW_MACE)) {
/* kill anything we hit */ /* kill anything we hit */
for (s2 = sprite; s2 ; s2 = s2->next) { for (s2 = sprite; s2 ; s2 = s2->next) {
if ((s2->caughtby != s) && (!s2->dead) && (ismonster(s2->id))) { if ((s2->caughtby != s) && !s2->dead && !s2->invuln && (ismonster(s2->id))) {
int xthresh,ythresh; int xthresh,ythresh;
xdiff = s2->x - xnet; xdiff = s2->x - xnet;
@ -3880,8 +4133,8 @@ void dogravity(sprite_t *s) {
} }
} else if (s2->id != P_BLACKCLOUD) { // non bosses } else if (s2->id != P_BLACKCLOUD) { // non bosses
/* dies and becomes a powerup */ /* dies and becomes a powerup */
// if we were holding something, we can get a powerup // if we were holding something, we can get a powerup.
// if we used a mace, it becomes a diamon. // if we used a mace, it becomes a diamond.
if (gotsomething) { if (gotsomething) {
if (boss) { // no fruits on boss levels if (boss) { // no fruits on boss levels
s2->willbecome = -1; s2->willbecome = -1;
@ -3908,11 +4161,24 @@ void dogravity(sprite_t *s) {
curfruittype = 0; curfruittype = 0;
} }
} }
die(s2); if ((player->powerup == PW_MACE) && (s2->id == P_SNAIL)) {
pointsinc *= 2; // turn into a slug so that it really dies
psize += 10; s2->id = P_SLUG;
}
gotsomething++; if (s2->id == P_SNAIL) {
// avoid triggering death code twice for caught snails
// since for them s->dead won't be set after we
// slam them.
if (s2->lives != 0) { // ie if we didn't just catch+slam it
die(s2);
}
} else {
die(s2);
pointsinc *= 2;
psize += 10;
gotsomething++;
}
} }
} }
@ -4027,7 +4293,7 @@ int movex(sprite_t *s,double amt) {
// rings // rings
if (s == player) { if (s == player) {
if (player->powerup == PW_RINGWALK) { if (player->powerup == PW_RINGWALK) {
if (isonground(player)) { if (isonground(player) && !player->swimming) {
int xx,yy; int xx,yy;
// add sparkle // add sparkle
xx = player->x + (rand() % player->img->w) - (player->img->w/2); xx = player->x + (rand() % player->img->w) - (player->img->w/2);
@ -4047,8 +4313,10 @@ void adjustheight(sprite_t *s) {
tiletype_t *tt; tiletype_t *tt;
int xoff,groundy; int xoff,groundy;
int tilex,tiley; int tilex,tiley;
double origy;
int totmoved;
if ((s->flies) || isbullet(s->id)) { if ((s->flies) || isbullet(s->id) ) {
return; return;
} }
@ -4059,8 +4327,17 @@ void adjustheight(sprite_t *s) {
groundy = tiley*TILEH + tt->lowness[xoff]; groundy = tiley*TILEH + tt->lowness[xoff];
s->y = groundy; s->y = groundy;
} else if (tt->solid == S_SOLID) { } else if (tt->solid == S_SOLID) {
origy = s->y;
totmoved = 0;
// keep moving up
while (tt->solid == S_SOLID) { while (tt->solid == S_SOLID) {
s->y--; s->y--;
totmoved++;
// don't move more than 1 tile worth!
// don't go off top of screen
if ((totmoved >= TILEH) || (s->y <= TILEH)) {
break;
}
tt = gettileat(s->x,s->y-1,&tilex,&tiley); tt = gettileat(s->x,s->y-1,&tilex,&tiley);
} }
} }
@ -4284,6 +4561,7 @@ int dofruiteffect(sprite_t *s) {
s2->dead = D_FINAL; s2->dead = D_FINAL;
} else if (ismonster(s2->id)) { } else if (ismonster(s2->id)) {
s2->willbecome = P_DIAMOND; s2->willbecome = P_DIAMOND;
s2->lives = 0; // for snails
if (s2->caughtby) { if (s2->caughtby) {
s2->caughtby = NULL; s2->caughtby = NULL;
@ -4445,6 +4723,7 @@ int initsound(void) {
loadfx(FX_BOSSWALL, "bosswall.wav"); loadfx(FX_BOSSWALL, "bosswall.wav");
loadfx(FX_SPRAY, "spray.wav"); loadfx(FX_SPRAY, "spray.wav");
loadfx(FX_CANNON, "fusion.wav"); loadfx(FX_CANNON, "fusion.wav");
loadfx(FX_CRACK, "crack.wav");
// load sound effects // load sound effects
@ -4470,6 +4749,12 @@ int initsound(void) {
return B_TRUE; return B_TRUE;
} }
bossmusic = Mix_LoadMUS("music/boss.mod");
if (!bossmusic) {
printf("can't load music\n");
return B_TRUE;
}
return B_FALSE; return B_FALSE;
} }
@ -4796,3 +5081,59 @@ void drawallsprites(void) {
if (s->id == P_PUFF) drawsprite(s); if (s->id == P_PUFF) drawsprite(s);
} }
} }
// check if sprite has passed off bottom/top of screen
void checkwrap(sprite_t *s) {
if (!s->dead) {
/* if we've fallen off the bottom... */
if (s->y > (480+s->img->h)) {
// move to top
s->y = -s->img->h;
}
/* if we've gone off the top */
if (s->y < -s->img->h) {
// move to bottom
s->y = (480+s->img->h);
}
}
}
int getcurworld(void) {
int wnum;
wnum = ((curlevelnum-1)/20)+1;
return wnum;
}
int getcurlevel(void) {
int wnum;
wnum = (curlevelnum%20);
if (wnum == 0) return 20;
return wnum;
}
// returns how high a given monster will jump
int getmonjumpspeed(sprite_t *s ) {
switch (s->id) {
case P_SLUG:
if (s->jumpdir == 0) { // jumping straight up
return MONJUMPSPEED;
} else { // jumping horizontally
return 3;
}
default:
return MONJUMPSPEED;
}
}
// returns how long to pause before jumping
int getjumpdelay(int mid) {
switch (mid) {
case P_SLUG:
return 30;
default:
return 60;
}
}

5
rc.h
View File

@ -56,4 +56,9 @@ void checksprites(void);
void moveallsprites(void); void moveallsprites(void);
void checkcollideall(void); void checkcollideall(void);
void drawallsprites(void); void drawallsprites(void);
void checkwrap(sprite_t *s);
int getcurworld(void);
int getcurlevel(void);
int getmonjumpspeed(sprite_t *s);
int getjumpdelay(int mid);

329
shared.c
View File

@ -304,6 +304,11 @@ int loadlevel(int wnum, int lnum) {
} }
level->nummonsters++; level->nummonsters++;
if (level->nummonsters >= MAXMONSTERSPERLEVEL) {
printf("ERROR: too many sprites !\n");
fclose(f);
return B_TRUE;
}
} }
@ -400,163 +405,11 @@ int loadlevel(int wnum, int lnum) {
p = strtok(NULL, ","); p = strtok(NULL, ",");
} }
} /*else { // old level data version } else { // old level data version
for (p = buf; *p; p++) { printf("ERROR: old level data!\n");
int n,found = 0; fclose(f);
// search mappings return B_TRUE;
for (n = 0; n < nmappings; n++) { }
if (mapping[n].ch == *p) {
tileid = mapping[n].tnum;
found = B_TRUE;
break;
}
}
if (!found) {
if (*p == '~') {
tileid = T_LAND;
} else if (*p == '=') {
tileid = T_LADDER;
} else if (*p == '-') {
tileid = T_LADDERTOP;
} else if (*p == '{') {
tileid = T_WATERTOP;
} else if (*p == '}') {
tileid = T_WATER;
} else if (*p == '>') {
tileid = T_RIGHT;
} else if (*p == '<') {
tileid = T_LEFT;
} else if (*p == '^') {
tileid = T_SPIKES;
} else if (*p == '|') {
tileid = T_WATERSPIKES;
} else if (*p == 'c') {
tileid = level->bgtileid;
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
level->initm[level->nummonsters].id = P_BLACKCLOUD;
level->nummonsters++;
} else if (*p == 'r') {
// figure out background type
if (lasttile->solid) {
tileid = level->map[(y-1)*LEVELW+x];
} else {
tileid = lasttile->id;
}
// tileid = level->bgtileid;
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
level->initm[level->nummonsters].id = P_RAT;
level->nummonsters++;
} else if (*p == 'S') {
// figure out background type
if (lasttile->solid) {
tileid = level->map[(y-1)*LEVELW+x];
} else {
tileid = lasttile->id;
}
// tileid = level->bgtileid;
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
level->initm[level->nummonsters].id = P_SNAKE;
level->nummonsters++;
} else if (*p == 'a') {
// figure out background type
if (lasttile->solid) {
tileid = level->map[(y-1)*LEVELW+x];
} else {
tileid = lasttile->id;
}
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
level->initm[level->nummonsters].id = P_BEE;
level->nummonsters++;
} else if (*p == 's') {
// figure out background type
if (lasttile->solid) {
tileid = level->map[(y-1)*LEVELW+x];
} else {
tileid = lasttile->id;
}
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
level->initm[level->nummonsters].starty = y*TILEH+TILEH;
level->initm[level->nummonsters].id = P_SPIDER;
level->nummonsters++;
} else if (*p == '?') {
// figure out background type
if (lasttile->solid) {
tileid = level->map[(y-1)*LEVELW+x];
} else {
tileid = lasttile->id;
}
// tileid = level->bgtileid;
level->initm[level->nummonsters].startx = x*TILEW+(TILEW/2);
level->initm[level->nummonsters].starty = y*TILEH+(TILEH-2);
level->initm[level->nummonsters].id = P_HELP;
if (curhelp >= numhelp) {
printf("Error in level - more help icons than help texts.\n");
exit(1);
} else {
level->initm[level->nummonsters].help = strdup(help[curhelp]);
curhelp++;
}
level->nummonsters++;
} else if (*p == '*') {
tileid = T_FULL;
} else if (*p == ';') {
tileid = T_TELEPORT;
} else if (*p == ':') {
tileid = T_TELEPORT2;
} else if (*p == '.') {
tileid = T_TELEPORTDEST;
} else if (*p == '/') {
tileid = T_SLOPEUP;
} else if (*p == '\\') {
tileid = T_SLOPEDOWN;
} else if (*p == '1') {
// figure out background type
if (lasttile->solid) {
tileid = level->map[(y-1)*LEVELW+x];
} else {
tileid = lasttile->id;
}
level->p1x = x;
level->p1y = y;
} else {
tileid = level->bgtileid;
}
}
if (!gettile(tileid)) {
printf("invalid tileid: %d\n",tileid);
fclose(f);
return B_TRUE;
}
if (x > LEVELW) {
printf("Too many tiles on line %d: %d,%d\n",y,x,y);
fclose(f);
return B_TRUE;
}
if (y >= LEVELH) {
printf("Too many lines at line %d: %d,%d\n",y,x,y);
fclose(f);
return B_TRUE;
}
level->map[y*LEVELW+x] = tileid;
lasttile = gettile(tileid);
x++;
}
} // if newversion
*/
/* make sure enough data was found */ /* make sure enough data was found */
if (x < LEVELW+1) { if (x < LEVELW+1) {
@ -656,6 +509,8 @@ int loadlevel(int wnum, int lnum) {
} }
*/ */
/* add monsters */ /* add monsters */
for (i = 0; i < level->nummonsters; i++) { for (i = 0; i < level->nummonsters; i++) {
char name[MIDBUFLEN]; char name[MIDBUFLEN];
@ -676,6 +531,7 @@ int loadlevel(int wnum, int lnum) {
#ifdef __EDITOR #ifdef __EDITOR
addsprite(level->initm[i].id, addsprite(level->initm[i].id,
level->initm[i].startx, level->initm[i].starty, name ); level->initm[i].startx, level->initm[i].starty, name );
#else #else
puffin(level->initm[i].id, level->initm[i].startx, level->initm[i].starty, name, delay ); puffin(level->initm[i].id, level->initm[i].startx, level->initm[i].starty, name, delay );
#endif #endif
@ -708,13 +564,13 @@ void setdefaults(sprite_t *s) {
s->powerup = 0; s->powerup = 0;
s->netbig = 0; s->netbig = 0;
// player-only states // player-only states
s->recoiling = B_FALSE;
s->netting = 0; s->netting = 0;
s->netmax = 1; s->netmax = 1;
s->netcaught = 0; s->netcaught = 0;
s->slamming = 0; s->slamming = 0;
s->invuln = 0; s->invuln = 0;
// states // states
s->recoiling = B_FALSE;
s->teleporting = 0; s->teleporting = 0;
s->climbing = 0; s->climbing = 0;
s->jumping = 0; s->jumping = 0;
@ -743,6 +599,8 @@ void setdefaults(sprite_t *s) {
s->iceimg = NULL; s->iceimg = NULL;
} }
s->watertimer = 0;
s->bullet = NULL; s->bullet = NULL;
s->owner = NULL; s->owner = NULL;
@ -756,6 +614,11 @@ void setdefaults(sprite_t *s) {
s->size = -1; s->size = -1;
} }
// special
if (s->id == P_SNAIL) {
s->lives = 1;
}
// special for bosses // special for bosses
if (s->id == P_KINGRAT) { if (s->id == P_KINGRAT) {
s->timer1 = 0; s->timer1 = 0;
@ -875,6 +738,18 @@ tiletype_t *gettileat(int pixx,int pixy, int *tilex,int *tiley) {
*tiley = ty; *tiley = ty;
} }
if (ty >= LEVELH) {
// if tile is off the bottom of the screen,
// return one from the top row
ty = 0;
}
if (pixy < 0) {
// if tile is off the top of the screen,
// return one from the bottom row
ty = LEVELH-1;
}
// return layer2 if it exists // return layer2 if it exists
tid = curlevel->map2[ty*LEVELW+tx]; tid = curlevel->map2[ty*LEVELW+tx];
if (tid == T_BLANK) { if (tid == T_BLANK) {
@ -1169,6 +1044,22 @@ int loadimagesets(void) {
/* next 3 are auto generated */ /* next 3 are auto generated */
imageset[P_KINGRAT].numimages = 8; imageset[P_KINGRAT].numimages = 8;
loadspriteimage(P_SNAIL,F_WALK1, "sprites/snail.png");
loadspriteimage(P_SNAIL,F_JUMP, "sprites/snailwalk2.png");
loadspriteimage(P_SNAIL,F_FALL, "sprites/snailwalk2.png");
loadspriteimage(P_SNAIL,F_CAUGHT, "sprites/snailcaught.png");
loadspriteimage(P_SNAIL,F_DEAD, "sprites/snaildead.png");
/* next 3 are auto generated */
imageset[P_SNAIL].numimages = 8;
loadspriteimage(P_SLUG,F_WALK1, "sprites/slug.png");
loadspriteimage(P_SLUG,F_JUMP, "sprites/slugwalk.png");
loadspriteimage(P_SLUG,F_FALL, "sprites/slugjump.png");
loadspriteimage(P_SLUG,F_CAUGHT, "sprites/slugcaught.png");
loadspriteimage(P_SLUG,F_DEAD, "sprites/slugdead.png");
/* next 3 are auto generated */
imageset[P_SLUG].numimages = 8;
/* fruits / powerups */ /* fruits / powerups */
loadspriteimage(P_CHEESE,F_WALK1, "sprites/cheese.png"); loadspriteimage(P_CHEESE,F_WALK1, "sprites/cheese.png");
imageset[P_CHEESE].numimages = 1; imageset[P_CHEESE].numimages = 1;
@ -1296,6 +1187,9 @@ int loadimagesets(void) {
} }
imageset[P_SPARKLE].numimages = SPARKLEFRAMES; imageset[P_SPARKLE].numimages = SPARKLEFRAMES;
loadspriteimage(P_BUBBLE,F_WALK1, "sprites/bubble.png");
imageset[P_BUBBLE].numimages = 1;
/* bullets */ /* bullets */
loadspriteimage(P_SPIT,F_WALK1, "sprites/spit.png"); loadspriteimage(P_SPIT,F_WALK1, "sprites/spit.png");
imageset[P_SPIT].numimages = 1; imageset[P_SPIT].numimages = 1;
@ -1451,12 +1345,16 @@ void drawsprite(sprite_t *s) {
frame = F_WALK1; frame = F_WALK1;
} else if (s->id == P_CANNON) { } else if (s->id == P_CANNON) {
frame = F_WALK1; frame = F_WALK1;
} else if (s->id == P_BUBBLE) {
frame = F_WALK1;
} }
} else if (s->dead) { } else if (s->dead) {
if (s == player) { if (s == player) {
frame = F_DEAD; frame = F_DEAD;
} else if (s == boss) { } else if (s == boss) {
frame = F_DEAD; frame = F_DEAD;
} else if (s->id == P_SNAIL) {
frame = F_DEAD;
} else { } else {
frame = F_DEAD + ((timer/2) % 4); frame = F_DEAD + ((timer/2) % 4);
} }
@ -1484,9 +1382,21 @@ void drawsprite(sprite_t *s) {
} else if (s->iced) { } else if (s->iced) {
frame = F_WALK1; frame = F_WALK1;
} else if (s->jumping) { } else if (s->jumping) {
frame = F_JUMP; if ((s->id == P_SNAIL) && (s->recoiling)) {
// when a snail is "jumping" it is actually recoiling
// and should look like a shell
frame = F_DEAD;
} else if (s->id == P_SLUG) {
frame = F_FALL;
} else {
frame = F_JUMP;
}
} else if (s->falling) { } else if (s->falling) {
frame = F_FALL; if ((s->id == P_SNAIL) && (s->recoiling)) {
frame = F_DEAD;
} else {
frame = F_FALL;
}
} else if (s->slamming) { } else if (s->slamming) {
double slamdegs = s->slamangle / (M_PI/180); double slamdegs = s->slamangle / (M_PI/180);
if (slamdegs < 36) { if (slamdegs < 36) {
@ -1554,24 +1464,38 @@ void drawsprite(sprite_t *s) {
} }
// override
if ((s->id == P_SNAIL) && (s->recoiling)) {
frame = F_DEAD;
}
area.x = s->x - (s->img->w/2); area.x = s->x - (s->img->w/2);
area.y = s->y - (s->img->h); area.y = s->y - (s->img->h);
area.w = 0; area.w = 0;
area.h = 0; area.h = 0;
if (area.y < (480-s->img->h)) { //if (area.y < (480-s->img->h)) {
/*
if (s == player) {
printf("player at %0.1f,%0.1f\n",player->x,player->y);
}
*/
if (s->invuln) { if (s->invuln) {
if (timer % 2 == 0) { if (timer % 2 == 0) {
SDL_BlitSurface(s->img, NULL, screen, &area); //SDL_BlitSurface(s->img, NULL, screen, &area);
doblit(s->img, screen, &area);
} }
} else if (s == boss && s->dead) { } else if (s == boss && s->dead) {
if ((timer / 10) % 2 == 0) { if ((timer / 10) % 2 == 0) {
SDL_BlitSurface(s->img, NULL, screen, &area); //SDL_BlitSurface(s->img, NULL, screen, &area);
doblit(s->img, screen, &area);
} }
} else { } else {
// draw the sprite // draw the sprite
SDL_BlitSurface(s->img, NULL, screen, &area); //SDL_BlitSurface(s->img, NULL, screen, &area);
doblit(s->img, screen, &area);
/* for opengl */ /* for opengl */
//SDL_UpdateRect(screen, area.x, area.y, area.w, area.h); //SDL_UpdateRect(screen, area.x, area.y, area.w, area.h);
} }
@ -1586,21 +1510,25 @@ void drawsprite(sprite_t *s) {
s->iceimg = rotozoomSurfaceXY(icecube,0, xmod, ymod ,0); s->iceimg = rotozoomSurfaceXY(icecube,0, xmod, ymod ,0);
} }
// draw it // draw it
SDL_BlitSurface(s->iceimg, NULL, screen, &area); doblit(s->iceimg, screen, &area);
//SDL_BlitSurface(s->iceimg, NULL, screen, &area);
} }
} //}
/* caughtby lines */ /* caughtby lines */
if ((s->caughtby) && (s->caughtstate == 2)){ if ((s->caughtby) && (s->caughtstate == 2)){
drawline16(screen, s->x,s->y - s->img->h, // only if we're on the screen
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white); if ((s->y >= 0) && (s->y <= 480)) {
drawline16(screen, s->x,s->y - (s->img->h/2), drawline16(screen, s->x,s->y - s->img->h,
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white); s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white);
drawline16(screen, s->x,s->y, drawline16(screen, s->x,s->y - (s->img->h/2),
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white); s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white);
drawline16(screen, s->x,s->y,
s->caughtby->x,s->caughtby->y-(s->caughtby->img->h/2), white);
}
} }
@ -1754,14 +1682,18 @@ int isbullet(int id) {
} }
int iseffect(int id) { int iseffect(int id) {
if (id == P_PUFF) return B_TRUE; switch (id) {
if (id == P_SPARKLE) return B_TRUE; case P_PUFF:
if (id == P_SMASH) return B_TRUE; case P_SPARKLE:
if (id == P_POWERUPPOS) return B_TRUE; case P_SMASH:
if (id == P_GLOVE) return B_TRUE; case P_POWERUPPOS:
if (id == P_MACE) return B_TRUE; case P_GLOVE:
if (id == P_PINKCLOUD) return B_TRUE; case P_MACE:
if (id == P_CANNON) return B_TRUE; case P_PINKCLOUD:
case P_CANNON:
case P_BUBBLE:
return B_TRUE;
}
return B_FALSE; return B_FALSE;
} }
@ -2071,6 +2003,8 @@ SDL_Surface *loadspriteimage(int spriteid, int frame, char *filename) {
int candoslopes(int sid) { int candoslopes(int sid) {
switch(sid) { switch(sid) {
case P_SNAKE: case P_SNAKE:
case P_SNAIL:
case P_SLUG:
return B_FALSE; return B_FALSE;
} }
return B_TRUE; return B_TRUE;
@ -2083,6 +2017,8 @@ int ismonster(int id) {
case P_SPIDER: case P_SPIDER:
case P_SNAKE: case P_SNAKE:
case P_COKE: case P_COKE:
case P_SNAIL:
case P_SLUG:
return MT_MONSTER; return MT_MONSTER;
case P_BLACKCLOUD: case P_BLACKCLOUD:
case P_KINGRAT: case P_KINGRAT:
@ -2450,6 +2386,9 @@ void setfruitinfo(void) {
setinfo(P_KINGRAT, "King Rat", "This mighty creature is the ruler of the rats, and impervious to the player's net. It can only be harmed by slamming another monster into it! King Rat will roam the level searching for a player, and upon locating them will charge at high speed.", "kingrat.png"); setinfo(P_KINGRAT, "King Rat", "This mighty creature is the ruler of the rats, and impervious to the player's net. It can only be harmed by slamming another monster into it! King Rat will roam the level searching for a player, and upon locating them will charge at high speed.", "kingrat.png");
setinfo(P_SNAIL, "Snail", "Snails are slow moving but tough - when slammed they will not die, but simply lose their shell and become a slug.", "snail.png");
setinfo(P_SLUG, "Slug", "Slugs are faster moving than snails and capable of launching themselves through the air at their prey!", "slug.png");
} }
void setinfo(int id, char *name, char *desc, char *file) { void setinfo(int id, char *name, char *desc, char *file) {
@ -2512,3 +2451,33 @@ void dumpinfo(void) {
} }
} }
} }
void doblit(SDL_Surface *src, SDL_Surface *dst, SDL_Rect *dstarea) {
SDL_Rect srcarea;
if ((dstarea->y > 0) && (dstarea->y <= (480-src->h))) {
// completely onscreen
SDL_BlitSurface(src, NULL, dst, dstarea);
} else if (dstarea->y > (480-src->h)) {
// off the bottom
srcarea.x = 0;
srcarea.y = 0;
srcarea.w = src->w;
srcarea.h = 480 - dstarea->y;
if (srcarea.h > 0) {
SDL_BlitSurface(src, &srcarea, dst, dstarea);
}
} else if (dstarea->y < 0) {
// off the top
srcarea.x = 0;
srcarea.w = src->w;
srcarea.y = - dstarea->y;
srcarea.h = src->h - srcarea.y;
if (srcarea.y > 0) {
dstarea->y = 0;
dstarea->h = srcarea.h;
dstarea->w = srcarea.w;
SDL_BlitSurface(src, &srcarea, dst, dstarea);
}
}
}

View File

@ -49,6 +49,7 @@ int isnettable(int monid);
int isboss(int monid); int isboss(int monid);
int getbosshealth(int mid); int getbosshealth(int mid);
void getpixelrgb(SDL_Surface *where, int x, int y, SDL_Color *clr); void getpixelrgb(SDL_Surface *where, int x, int y, SDL_Color *clr);
void doblit(SDL_Surface *src, SDL_Surface *dst, SDL_Rect *dstarea);
// for doco // for doco
void setfruitinfo(void); void setfruitinfo(void);
void setinfo(int id, char *name, char *desc, char *file); void setinfo(int id, char *name, char *desc, char *file);

View File

@ -22,7 +22,6 @@ monsters
16 15 28 16 15 28
16 15 28 16 15 28
16 15 28 16 15 28
15 35 5
15 28 5 15 28 5
16 20 2 16 20 2
15 21 2 15 21 2
@ -31,9 +30,6 @@ monsters
15 10 10 15 10 10
1 11 18 1 11 18
18 9 28 18 9 28
12 30 5
12 30 5
12 30 5
17 30 28 17 30 28
17 31 28 17 31 28
16 28 14 16 28 14
@ -49,6 +45,7 @@ monsters
17 8 10 17 8 10
17 12 10 17 12 10
15 14 10 15 14 10
12 30 5
endmonsters endmonsters
exitdir 1 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, 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,
@ -57,9 +54,9 @@ exitdir 1
39,1,40,1,1,40,40,1,3,0,0,0,0,0,0,0,0,2,1,1,1,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, 39,1,40,1,1,40,40,1,3,0,0,0,0,0,0,0,0,2,1,1,1,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,4,4,4,4,4,4,4,37,3,0,0,0,0,0,0,2,36,4,4,4,4,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, 4,4,4,4,4,4,4,4,37,3,0,0,0,0,0,0,2,36,4,4,4,4,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,4,4,4,4,4,4,4,0,37,3,0,0,0,0,2,36,0,4,4,4,4,4,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, 4,4,4,4,4,4,4,4,0,37,3,0,0,0,0,2,36,0,4,4,4,4,4,4,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,4,4,4,4,4,4,43,0,0,37,3,0,0,2,36,0,0,4,4,4,4,4,4,4,1,40,40,40,40,1,1,0,0,0,1,16,16,16,4, 4,4,4,4,4,4,4,43,0,0,37,3,0,0,2,36,0,0,4,4,4,4,4,4,4,1,40,40,40,40,1,1,0,0,0,0,0,0,0,4,
4,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,4,4,4,4,4,4,4,4,19,0,0,0,0,0,0,0,4,15,15,15,4, 4,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,4,4,4,4,4,4,4,4,19,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,42,4,4,4,4,4,4,4,16,16,16,16,16,1,40,40,38,15,15,15,4, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,4,4,4,4,4,4,4,16,16,16,16,16,1,40,40,1,16,16,16,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,4,4,4,4,4,4,15,15,15,15,15,4,4,4,4,15,15,15,4, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,4,4,4,4,4,4,15,15,15,15,15,4,4,4,4,15,15,15,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,4,4,4,4,15,15,15,15,15,4,4,4,4,15,15,15,4, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,4,4,4,4,15,15,15,15,15,4,4,4,4,15,15,15,4,
39,1,1,8,1,1,40,40,1,1,40,40,40,40,40,1,1,16,16,16,16,16,16,4,4,4,4,15,15,15,15,15,4,4,4,4,15,15,15,4, 39,1,1,8,1,1,40,40,1,1,40,40,40,40,40,1,1,16,16,16,16,16,16,4,4,4,4,15,15,15,15,15,4,4,4,4,15,15,15,4,

View File

@ -1,604 +1,87 @@
bgfile bgfile backgrounds/beach1.png
bg 0 bg 0
hurryup 90 hurryup 136
help help
Drop through the bottom of this level
endhelp endhelp
monsters monsters
0 32 7 0 20 17
1 33 23 23 14 20
1 4 23 18 26 4
17 34 23 18 7 4
17 33 23 15 30 10
17 6 23 15 28 10
17 5 23 15 12 10
15 35 23 15 8 10
15 32 23 15 8 23
15 7 23 15 11 23
15 4 23 15 28 23
16 24 18 15 31 23
16 16 18 16 27 20
16 15 18 16 23 20
16 23 18 16 16 20
17 27 16 16 12 20
17 12 16 16 12 14
15 26 17 16 16 14
15 25 17 16 23 14
15 14 17 16 27 14
15 13 17 17 21 17
6 23 17 17 18 17
6 25 14 14 19 17
6 12 15 6 36 22
6 17 13 6 13 23
1 35 28 17 20 27
1 7 28 16 21 27
1 10 7 16 18 27
17 20 6 17 19 27
17 19 6 16 22 27
16 22 6 16 17 27
16 17 6 15 23 27
15 27 7 15 24 27
15 12 7 15 16 27
15 28 7 15 15 27
15 11 7 17 37 27
7 29 22 17 2 27
7 12 22 1 30 23
12 10 20 1 9 23
12 30 20 17 36 1
17 3 1
16 31 4
16 8 4
16 12 4
16 27 4
1 9 10
1 31 10
endmonsters endmonsters
exitdir 1 exitdir 2
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, 44,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,44,
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, 44,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,44,
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, 44,0,0,46,45,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,45,47,0,0,44,
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, 44,0,0,0,44,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,44,0,0,0,44,
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, 44,0,0,0,44,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,44,0,0,0,44,
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, 44,0,0,0,44,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,44,0,0,0,44,
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, 44,0,0,0,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,0,0,0,44,
4,0,0,0,0,0,0,0,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,0,0,0,0,0,0,0,4, 44,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,44,
4,27,27,27,27,27,27,1,1,1,1,1,1,1,1,1,25,25,25,25,25,25,25,25,1,1,1,1,1,1,1,1,1,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,4,4,4,4,4,4,4,4,4,24,26,26,26,26,26,26,24,4,4,4,4,4,4,4,4,4,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,4,4,4,4,4,4,4,4,4,24,26,26,26,26,26,26,24,4,4,4,4,4,4,4,4,4,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,4,4,4,4,4,4,4,24,24,24,26,26,26,26,26,26,24,24,24,4,4,4,4,4,4,4,27,27,27,27,27,27,4, 44,0,0,0,0,0,0,0,46,45,45,45,47,0,0,0,0,46,45,45,45,45,47,0,0,0,0,46,45,45,45,47,0,0,0,0,0,0,0,44,
4,27,27,27,27,27,27,4,4,4,4,4,24,24,24,26,26,26,26,26,26,26,26,26,26,24,24,24,4,4,4,4,4,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,4,24,24,24,24,24,26,26,26,26,26,26,26,26,26,26,26,26,26,26,24,24,24,24,24,4,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,4,24,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,24,4,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,4,24,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,24,4,27,27,27,27,27,27,4, 44,0,0,0,0,0,0,0,0,0,0,0,46,45,45,45,47,0,0,0,0,0,0,46,45,45,45,47,0,0,0,0,0,0,0,0,0,0,0,44,
4,27,27,27,27,27,27,4,24,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,24,4,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,4,24,24,24,24,24,26,26,26,26,26,26,26,26,26,26,26,26,26,26,24,24,24,24,24,4,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,15,4,4,4,4,24,24,24,26,26,26,26,26,26,26,26,26,26,24,24,24,4,4,4,4,15,27,27,27,27,27,27,4, 44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,45,45,47,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,44,
4,27,27,27,27,27,27,27,27,27,27,27,27,4,24,24,24,26,26,26,26,26,26,24,24,24,4,27,27,27,27,27,27,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,27,27,27,27,27,27,4,4,4,4,26,26,26,26,26,26,4,4,4,4,27,27,27,27,27,27,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,27,27,15,1,1,1,4,4,4,4,26,26,26,26,26,26,4,4,4,4,1,1,1,15,27,27,27,27,27,27,27,27,4, 44,0,0,0,0,0,0,0,0,0,0,0,46,45,45,45,47,0,0,0,0,0,0,46,45,45,45,47,0,0,0,0,0,0,0,0,0,0,0,44,
4,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,1,1,1,1,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,1,1,1,1,27,27,27,4, 44,0,0,0,0,0,0,0,46,45,45,47,0,0,0,0,0,46,45,45,45,45,47,0,0,0,0,0,46,45,45,47,0,0,0,0,0,0,0,44,
4,27,27,27,42,4,4,43,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,42,4,4,43,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,4, 44,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,44,
4,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,4, 44,0,0,0,17,30,0,0,0,0,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,0,0,0,0,30,17,0,0,0,44,
4,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,4, 44,45,45,45,45,45,0,0,0,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,0,0,0,0,45,45,45,45,45,44,
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4, 44,44,44,44,44,44,0,0,0,0,44,44,44,44,44,44,44,45,44,44,44,44,44,44,44,44,44,44,44,44,0,0,0,0,44,44,44,44,44,44,
layer2 layer2
15,7,2
16,7,1
17,7,1
18,7,1
19,7,1
20,7,1
21,7,1
22,7,1
23,7,1
24,7,3
1,8,16
2,8,16
3,8,16
4,8,16
5,8,16
6,8,16
9,8,40
10,8,40
11,8,40
13,8,40
15,8,4
16,8,24
17,8,24
18,8,24
19,8,24
20,8,24
21,8,24
22,8,24
23,8,24
24,8,4
27,8,40
28,8,40
29,8,40
31,8,40
33,8,16
34,8,16
35,8,16
36,8,16
37,8,16
38,8,16
1,9,15
2,9,15
3,9,15
4,9,15
5,9,15
6,9,15
33,9,15
34,9,15
35,9,15
36,9,15
37,9,15
38,9,15
1,10,15
2,10,15
3,10,15
4,10,15
5,10,15
6,10,15
33,10,15
34,10,15
35,10,15
36,10,15
37,10,15
38,10,15
1,11,15
2,11,15
3,11,15
4,11,15
5,11,15
6,11,15
33,11,15
34,11,15
35,11,15
36,11,15
37,11,15
38,11,15
1,12,15
2,12,15
3,12,15
4,12,15
5,12,15
6,12,15
33,12,15
34,12,15
35,12,15
36,12,15
37,12,15
38,12,15
1,13,15
2,13,15
3,13,15
4,13,15
5,13,15
6,13,15
33,13,15
34,13,15
35,13,15
36,13,15
37,13,15
38,13,15
1,14,15
2,14,15
3,14,15
4,14,15
5,14,15
6,14,15
33,14,15
34,14,15
35,14,15
36,14,15
37,14,15
38,14,15
1,15,15
2,15,15
3,15,15
4,15,15
5,15,15
6,15,15
33,15,15
34,15,15
35,15,15
36,15,15
37,15,15
38,15,15
1,16,15
2,16,15
3,16,15
4,16,15
5,16,15
6,16,15
33,16,15
34,16,15
35,16,15
36,16,15
37,16,15
38,16,15
1,17,15
2,17,15
3,17,15
4,17,15
5,17,15
6,17,15
33,17,15
34,17,15
35,17,15
36,17,15
37,17,15
38,17,15
1,18,15
2,18,15
3,18,15
4,18,15
5,18,15
6,18,15
7,18,42
32,18,43
33,18,15
34,18,15
35,18,15
36,18,15
37,18,15
38,18,15
1,19,15
2,19,15
3,19,15
4,19,15
5,19,15
6,19,15
7,19,15
8,19,15
9,19,15
10,19,15
11,19,15
12,19,15
17,19,28
18,19,28
19,19,28
20,19,28
21,19,28
22,19,28
27,19,15
28,19,15
29,19,15
30,19,15
31,19,15
32,19,15
33,19,15
34,19,15
35,19,15
36,19,15
37,19,15
38,19,15
1,20,15
2,20,15
3,20,15
4,20,15
5,20,15
6,20,15
7,20,15
8,20,15
9,20,15
10,20,15
11,20,15
12,20,15
17,20,16
18,20,16
19,20,16
20,20,16
21,20,16
22,20,16
27,20,15
28,20,15
29,20,15
30,20,15
31,20,15
32,20,15
33,20,15
34,20,15
35,20,15
36,20,15
37,20,15
38,20,15
1,21,15
2,21,15
3,21,15
4,21,15
5,21,15
6,21,15
7,21,15
8,21,15
9,21,35
17,21,15
18,21,15
19,21,15
20,21,15
21,21,15
22,21,15
30,21,34
31,21,15
32,21,15
33,21,15
34,21,15
35,21,15
36,21,15
37,21,15
38,21,15
1,22,15
2,22,15
3,22,15
4,22,15
5,22,15
6,22,15
7,22,15
8,22,15
9,22,15
10,22,15
11,22,15
12,22,15
13,22,15
14,22,15
15,22,15
16,22,15
17,22,15
18,22,15
19,22,15
20,22,15
21,22,15
22,22,15
23,22,15
24,22,15
25,22,15
26,22,15
27,22,15
28,22,15
29,22,15
30,22,15
31,22,15
32,22,15
33,22,15
34,22,15
35,22,15
36,22,15
37,22,15
38,22,15
1,23,15
2,23,15
3,23,15
4,23,15
5,23,15
6,23,15
7,23,15
8,23,15
9,23,15
10,23,15
11,23,15
12,23,15
13,23,15
14,23,15
15,23,15
16,23,15
17,23,15
18,23,15
19,23,15
20,23,15
21,23,15
22,23,15
23,23,15
24,23,15
25,23,15
26,23,15
27,23,15
28,23,15
29,23,15
30,23,15
31,23,15
32,23,15
33,23,15
34,23,15
35,23,15
36,23,15
37,23,15
38,23,15
1,24,15
2,24,15
3,24,15
8,24,15
9,24,15
10,24,15
11,24,15
12,24,15
13,24,15
14,24,15
15,24,15
16,24,15
17,24,15
18,24,15
19,24,15
20,24,15
21,24,15
22,24,15
23,24,15
24,24,15
25,24,15
26,24,15
27,24,15
28,24,15
29,24,15
30,24,15
31,24,15
36,24,15
37,24,15
38,24,15
1,25,15
2,25,15
3,25,15
4,25,15
5,25,15
6,25,15
7,25,15
8,25,15
9,25,15
10,25,15
11,25,15
12,25,15
13,25,15
14,25,15
15,25,15
16,25,15
17,25,15
18,25,15
19,25,15
20,25,15
21,25,15
22,25,15
23,25,15
24,25,15
25,25,15
26,25,15
27,25,15
28,25,15
29,25,15
30,25,15
31,25,15
32,25,15
33,25,15
34,25,15
35,25,15
36,25,15
37,25,15
38,25,15
1,26,15
2,26,15
3,26,15
4,26,15
5,26,15
6,26,15
7,26,15
8,26,15
9,26,15
10,26,15
11,26,15
12,26,15
13,26,15
14,26,15
15,26,15
16,26,15
17,26,15
18,26,15
19,26,15
20,26,15
21,26,15
22,26,15
23,26,15
24,26,15
25,26,15
26,26,15
27,26,15
28,26,15
29,26,15
30,26,15
31,26,15
32,26,15
33,26,15
34,26,15
35,26,15
36,26,15
37,26,15
38,26,15
1,27,15
2,27,15
3,27,15
4,27,15
5,27,15
6,27,15
7,27,15
8,27,15
9,27,15
10,27,15
11,27,15
12,27,15
13,27,15
14,27,15
15,27,15
16,27,15
17,27,15
18,27,15
19,27,15
20,27,15
21,27,15
22,27,15
23,27,15
24,27,15
25,27,15
26,27,15
27,27,15
28,27,15
29,27,15
30,27,15
31,27,15
32,27,15
33,27,15
34,27,15
35,27,15
36,27,15
37,27,15
38,27,15
1,28,15
2,28,15
3,28,15
4,28,15
5,28,15
6,28,15
7,28,15
8,28,15
9,28,15
10,28,15
11,28,15
12,28,15
13,28,15
14,28,15
15,28,15
16,28,15
17,28,15
18,28,15
19,28,15
20,28,15
21,28,15
22,28,15
23,28,15
24,28,15
25,28,15
26,28,15
27,28,15
28,28,15
29,28,15
30,28,15
31,28,15
32,28,15
33,28,15
34,28,15
35,28,15
36,28,15
37,28,15
38,28,15
3,29,40
4,29,40
5,29,40
6,29,40
7,29,40
13,29,40
14,29,40
15,29,40
16,29,40
17,29,40
18,29,40
19,29,40
24,29,40
25,29,40
26,29,40
28,29,40
29,29,40
30,29,40
31,29,40
36,29,40
37,29,40

View File

@ -43,7 +43,7 @@ exitdir 1
4,1,1,1,40,40,40,40,1,40,1,40,40,40,1,38,43,0,0,0,0,0,0,42,39,1,1,1,40,40,1,1,1,40,40,40,40,1,1,4, 4,1,1,1,40,40,40,40,1,40,1,40,40,40,1,38,43,0,0,0,0,0,0,42,39,1,1,1,40,40,1,1,1,40,40,40,40,1,1,4,
4,7,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,7,4, 4,7,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,7,4,
4,7,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,7,4, 4,7,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,7,4,
4,7,0,0,0,0,0,0,0,0,0,0,0,35,1,1,40,40,40,1,40,40,40,1,1,1,34,0,0,0,0,0,0,0,0,0,0,0,7,4, 4,7,0,0,0,0,0,0,0,0,0,0,0,0,0,35,40,40,40,1,40,40,40,1,34,0,0,0,0,0,0,0,0,0,0,0,0,0,7,4,
4,7,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,7,4, 4,7,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,7,4,
4,7,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,7,4, 4,7,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,7,4,
4,7,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,7,4, 4,7,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,7,4,
@ -51,7 +51,7 @@ exitdir 1
39,1,40,1,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,1,40,1,38, 39,1,40,1,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,1,40,1,38,
4,4,4,4,9,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,10,4,4,4,4, 4,4,4,4,9,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,10,4,4,4,4,
4,4,4,39,34,9,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,10,35,38,4,4,4, 4,4,4,39,34,9,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,10,35,38,4,4,4,
4,4,4,4,39,34,9,9,9,0,0,0,0,0,0,35,1,40,40,1,1,40,40,1,34,0,0,0,0,0,0,10,10,10,35,38,4,4,4,4, 4,4,4,4,39,34,9,9,9,0,0,0,0,35,1,1,1,40,40,1,1,40,40,1,40,1,34,0,0,0,0,10,10,10,35,38,4,4,4,4,
4,4,4,4,4,39,1,40,34,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,10,10,35,40,1,38,4,4,4,4,4, 4,4,4,4,4,39,1,40,34,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,10,10,35,40,1,38,4,4,4,4,4,
4,4,4,4,4,4,4,4,39,1,40,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,40,40,38,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,39,1,40,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,40,40,38,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,9,9,9,9,9,0,0,0,0,0,0,0,0,10,10,10,10,10,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,9,9,9,9,9,0,0,0,0,0,0,0,0,10,10,10,10,10,4,4,4,4,4,4,4,4,4,4,4,

View File

@ -4,30 +4,34 @@ hurryup 30
help help
endhelp endhelp
monsters monsters
0 26 13 0 21 10
23 31 13
17 1 13 17 1 13
17 7 13 17 7 13
1 17 13 1 17 13
1 37 12 1 37 12
1 23 24
1 17 24
1 11 24
23 17 10
49 2 13
endmonsters endmonsters
exitdir 1 exitdir 1
1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4, 4,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4, 4,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4, 4,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,8,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,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,4, 4,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,1,
4,0,0,0,0,0,0,0,0,0,0,10,10,10,10,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,4, 4,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,1,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,4, 4,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,7,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,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,4, 4,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,7,0,1,1,1,1,1,1,1,1,1,1,1,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,4, 4,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,1,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,4, 4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,7,0,0,0,1,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,4, 4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,0,0,7,0,0,0,1,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,4, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,7,1,1,1,7,1,0,0,0,0,0,0,7,0,0,0,1,0,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,4, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,7,0,0,0,0,0,0,0,7,0,0,0,1,1,0,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,4, 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,7,0,0,0,0,0,0,0,7,0,0,0,1,1,1,1,1,4,
4,1,1,1,1,1,1,1,16,16,16,16,16,16,16,1,1,1,1,1,1,16,16,16,16,23,23,23,23,23,23,23,23,23,23,23,0,0,0,4, 4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,16,7,16,16,23,23,23,23,23,23,23,23,23,23,23,0,0,0,4,
4,4,4,4,4,4,4,4,15,15,15,15,15,15,15,15,15,15,15,15,1,15,15,15,15,4,4,0,0,0,0,0,4,4,4,4,0,0,0,4, 4,4,4,4,4,4,4,4,15,15,15,15,15,15,15,15,15,15,15,15,1,15,7,15,15,4,4,0,0,0,0,0,4,4,4,4,0,0,0,4,
4,4,4,4,4,4,4,4,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,4,4,0,0,0,0,0,4,4,4,4,1,1,1,4, 4,4,4,4,4,4,4,4,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,4,4,0,0,0,0,0,4,4,4,4,1,1,1,4,
4,4,4,4,4,4,4,4,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,4,4,0,0,0,0,0,4,4,4,4,0,0,0,4, 4,4,4,4,4,4,4,4,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,4,4,0,0,0,0,0,4,4,4,4,0,0,0,4,
4,4,4,4,4,4,4,4,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,4,4,0,0,0,0,0,4,4,4,4,0,0,0,4, 4,4,4,4,4,4,4,4,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,4,4,0,0,0,0,0,4,4,4,4,0,0,0,4,
@ -43,3 +47,5 @@ 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, 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,
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, 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,
layer2 layer2
22,2,8
30,7,8