diff --git a/data/levels/level604.dat b/data/levels/level604.dat
index 8d584b7..6d3d4e6 100644
--- a/data/levels/level604.dat
+++ b/data/levels/level604.dat
@@ -10,8 +10,6 @@ monsters
49 26 14
6 35 3
6 8 26
-18 26 24
-18 14 2
1 19 20
1 25 7
49 15 14
@@ -37,6 +35,8 @@ monsters
17 17 2
17 22 2
17 22 14
+171 14 2
+171 22 24
endmonsters
exitdir -2
90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,
diff --git a/data/levels/level99.dat b/data/levels/level99.dat
index afa111e..786927e 100644
--- a/data/levels/level99.dat
+++ b/data/levels/level99.dat
@@ -4,10 +4,9 @@ hurryup 10
help
endhelp
monsters
-0 38 28
134 18 15
-171 3 25
-171 16 20
+0 17 15
+171 4 7
endmonsters
exitdir 1
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
@@ -18,14 +17,14 @@ exitdir 1
4,0,0,0,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,0,0,4,
4,0,0,0,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,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,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,1,0,0,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,4,
-4,0,0,0,0,0,0,0,7,0,0,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,0,0,0,4,
-4,0,0,0,0,0,0,0,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,4,
-4,0,0,0,0,0,0,0,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,4,
-4,0,0,0,0,0,0,0,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,4,
-4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,
-4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,7,0,0,4,
-4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,7,0,0,4,
+4,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,1,0,0,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,4,
+4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,4,
+4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
+4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
+4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
+4,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,7,0,0,4,
+4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,7,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,0,0,0,0,0,1,1,0,0,0,0,7,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,7,0,0,4,
4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,7,0,0,4,
@@ -41,7 +40,6 @@ exitdir 1
4,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,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,4,
layer2
-8,8,8
36,13,8
20,16,8
26,21,8
diff --git a/defs.h b/defs.h
index 749ae87..23bb84f 100644
--- a/defs.h
+++ b/defs.h
@@ -822,6 +822,10 @@
#define HF_RED 2
+// white spider timers
+#define WS_DROPDELAY 40 // how long whitetail pauses before dropping
+
+
/* data structures */
typedef struct mapping_s {
char ch;
diff --git a/rc.c b/rc.c
index 7828cd0..648cd4e 100644
--- a/rc.c
+++ b/rc.c
@@ -2254,6 +2254,12 @@ void checkcollide(sprite_t *s) {
s2->caughtstate = C_NETTING;
s->netcaught++;
+
+ // special case for whitetail
+ if (s2->id == P_WSPIDER) {
+ s2->timer2 = 0;
+ }
+
// special case for bosses
if (isbosslevel(curlevelnum)) {
if (s2->owner) {
@@ -4828,11 +4834,32 @@ printf("setting target to y = %d\n",ss->timer2);
}
} else if (s->id == P_WSPIDER) { // white spider - very intelligent!
// timer3 is climb direction
+ // timer2 is drop countdown
if (!s->falling) {
int move = B_FALSE;
int xdiff, absxdiff;
int ladderx = isladderabove(s);
+ if (s->timer2) {
+ int mod,mod2;
+ mod = (s->timer2 / (WS_DROPDELAY/2));
+ s->timer2--;
+ if (s->timer2 == 0) {
+ // drop!
+
+ /* drop down */
+ s->dropping = B_TRUE;
+ s->dropx = s->x / TILEW;
+ s->dropy = s->y / TILEH;
+ } else {
+ mod2 = (s->timer2 / (WS_DROPDELAY/2));
+ if (mod2 != mod) {
+ // change direction
+ if (s->dir == D_RIGHT) s->dir = D_LEFT;
+ else if (s->dir == D_LEFT) s->dir = D_RIGHT;
+ }
+ }
+ }
/* distance to closest player */
xdiff = getxdisttoplayer(s, NULL);
@@ -4859,6 +4886,10 @@ printf("setting target to y = %d\n",ss->timer2);
s->falling = 0;
s->climbing = B_TRUE;
s->moved = MV_WALK;
+ } else {
+ s->climbing = B_FALSE;
+ // face a player
+ faceplayer(s);
}
} else { // down
if (isonladder(s)) {
@@ -4871,10 +4902,11 @@ printf("setting target to y = %d\n",ss->timer2);
s->moved = MV_WALK;
} else {
s->climbing = B_FALSE;
+ faceplayer(s);
}
}
}
- } else if (ladderx && isplayerabove(s)) { // if we are at the bottom of a ladder
+ } else if (ladderx && isplayerabovedis(s,TILEW)) { // if we are at the bottom of a ladder
// start climbing
s->x = ladderx; // lock to ladder
s->y -= getspeed(s);
@@ -4883,7 +4915,7 @@ printf("setting target to y = %d\n",ss->timer2);
s->climbing = B_TRUE;
s->moved = MV_WALK;
s->timer3 = D_UP;
- } else if (isonladder(s) && isplayerbelow(s)) { // is we are at top of ladder
+ } else if (isonladder(s) && isplayerbelowdis(s,TILEW)) { // are we at top of ladder
int ladderx = isonladder(s);
if (isladderbelow(s)) {
s->y += getspeed(s);
@@ -4897,50 +4929,74 @@ printf("setting target to y = %d\n",ss->timer2);
} else {
s->climbing = B_FALSE;
}
- } else {
+ } else if (!s->dropping && (s->timer2 == 0)) {
+ /// not climbing - walk or drop down
+ int willdrop = B_FALSE;
+
+
s->climbing = B_FALSE;
- // walk
- 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) {
- double ycutoff = s->y + (TILEH/2);
- if ((player && (player->y >= ycutoff)) || (player2 && (player2->y >= ycutoff ))) {
- /* if player is below and nearby, fall off */
- if (xdiff <= (TILEW*16)) {
+
+ // drop down?
+ if (isonbridge(s) && !s->falling) {
+ int dist = 9999;
+ /* player below (get the one with closest x distance)? */
+ if (player && !player->dead && player->y > s->y) dist = abs(player->x - s->x);
+ if (player2 && !player2->dead && player2->y > s->y) {
+ int dist2;
+ dist2 = abs(player2->x - s->x);
+ if (dist2 < dist) dist = dist2;
+ }
+ if (dist <= (TILEW*3)) {
+ willdrop = B_TRUE;
+ }
+ }
+
+ if (willdrop) {
+ s->timer2 = WS_DROPDELAY;
+ } else {
+ // walk
+ 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) {
+ double ycutoff = s->y + (TILEH/2);
+ if ((player && (player->y >= ycutoff)) || (player2 && (player2->y >= ycutoff ))) {
+ /* if player is below and nearby, fall off */
+ if (xdiff <= (TILEW*16)) {
+ move = B_TRUE;
+ }
+ } else if ((player && (player->y == s->y)) || (player2 && (player2->y == s->y ))) {
+ if (globpowerup != PW_CAMERA) {
+ /* 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);
+ }
+ }
+ } else if (level->bottomopen && (s->y >= (480 - 100)) && isplayerabove(s)) {
+ // if near bottom of the screen and can fall through...
move = B_TRUE;
}
- } else if ((player && (player->y == s->y)) || (player2 && (player2->y == s->y ))) {
- if (globpowerup != PW_CAMERA) {
- /* 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);
- }
- }
- } else if (level->bottomopen && (s->y >= (480 - 100)) && isplayerabove(s)) {
- // if near bottom of the screen and can fall through...
+ } else {
move = B_TRUE;
}
- } else {
- move = B_TRUE;
- }
- if (globpowerup == PW_CAMERA) {
- move = B_TRUE;
- }
-
- /* either move or turn around */
- if (move) {
- rv = movex(s, s->dir*getspeed(s), B_TRUE);
- if (rv) {
- /* if we couldn't move (hit a wall), turn */
+ if (globpowerup == PW_CAMERA) {
+ move = B_TRUE;
+ }
+
+ /* either move or turn around */
+ if (move) {
+ rv = movex(s, s->dir*getspeed(s), B_TRUE);
+ if (rv) {
+ /* if we couldn't move (hit a wall), turn */
+ s->dir = -s->dir;
+ }
+ } else {
s->dir = -s->dir;
}
- } else {
- s->dir = -s->dir;
- }
+ }
}
@@ -4971,6 +5027,7 @@ printf("setting target to y = %d\n",ss->timer2);
}
} else { // falling
movex(s, s->jumpdir*getspeed(s), B_TRUE);
+ faceplayer(s);
}
} else if (s->id == P_SNAKE) {
/* timer1 loopsfrom 0 - 19
@@ -13510,6 +13567,16 @@ sprite_t *isplayerbelow(sprite_t *s) {
return NULL;
}
+// is there a player more than "dis" pixels below?
+sprite_t *isplayerbelowdis(sprite_t *s,int dis) {
+ if (globpowerup == PW_CAMERA) return NULL;
+
+ if (player && !player->dead && (player->y - s->y) >= dis ) return player;
+ if (player2 && !player2->dead && (player2->y - s->y) >= dis) return player2;
+
+ return NULL;
+}
+
sprite_t *isplayerabove(sprite_t *s) {
if (globpowerup == PW_CAMERA) return NULL;
@@ -13519,6 +13586,18 @@ sprite_t *isplayerabove(sprite_t *s) {
return NULL;
}
+
+// is there a player more than "dis" pixels above?
+sprite_t *isplayerabovedis(sprite_t *s,int dis) {
+ if (globpowerup == PW_CAMERA) return NULL;
+
+ if (player && !player->dead && (s->y - player->y) >= dis ) return player;
+ if (player2 && !player2->dead && (s->y - player2->y) >= dis) return player2;
+
+ return NULL;
+}
+
+
sprite_t *isplayerright(sprite_t *s) {
if (globpowerup == PW_CAMERA) return NULL;
@@ -13528,6 +13607,15 @@ sprite_t *isplayerright(sprite_t *s) {
return NULL;
}
+sprite_t *isplayerleft(sprite_t *s) {
+
+ if (globpowerup == PW_CAMERA) return NULL;
+
+ if (player && !player->dead && player->x < s->x) return player;
+ if (player2 && !player2->dead && player2->x < s->x) return player2;
+
+ return NULL;
+}
sprite_t *isplayerahead(sprite_t *s) {
sprite_t *seen = NULL;
int ydis;
@@ -13559,6 +13647,16 @@ sprite_t *isplayerahead(sprite_t *s) {
return seen;
}
+// turn to face a player
+void faceplayer(sprite_t *s) {
+ // face a player
+ if ((s->dir == D_RIGHT) && !isplayerright(s) && isplayerleft(s)) {
+ s->dir = D_LEFT;
+ } else if ((s->dir == D_LEFT) && !isplayerleft(s) && isplayerright(s)) {
+ s->dir = D_RIGHT;
+ }
+}
+
SDL_Color *getcolour(int id) {
switch (id) {
diff --git a/rc.h b/rc.h
index 9e95ae6..0d6a060 100644
--- a/rc.h
+++ b/rc.h
@@ -117,9 +117,13 @@ double getxdisttoplayer(sprite_t *s, sprite_t **pl);
double getydisttoplayer(sprite_t *s);
int playersalive(void);
int inintro(void);
+void faceplayer(sprite_t *s);
sprite_t *isplayerbelow(sprite_t *s);
+sprite_t *isplayerbelowdis(sprite_t *s,int dis);
sprite_t *isplayerabove(sprite_t *s);
+sprite_t *isplayerabovedis(sprite_t *s,int dis);
sprite_t *isplayerright(sprite_t *s);
+sprite_t *isplayerleft(sprite_t *s);
sprite_t *isplayerahead(sprite_t *s);
SDL_Color *getcolour(int id);
SDL_Color *getbgcolour(int id);
diff --git a/shared.c b/shared.c
index c9fc4e3..efe7d2d 100644
--- a/shared.c
+++ b/shared.c
@@ -3843,6 +3843,8 @@ void dumpinfo(void) {
printf("");
} else if (i == P_SPIDER) {
printf("");
+ } else if (i == P_WSPIDER) {
+ printf("");
}
printf("
%s