Added AI by Ricardo Cruz. This also adds mouse controls. master origin release_1_51
authorFlorian Schulze <crow@icculus.org>
Sun, 27 Jun 2004 09:27:36 +0000 (09:27 +0000)
committerFlorian Schulze <crow@icculus.org>
Sun, 27 Jun 2004 09:27:36 +0000 (09:27 +0000)
AUTHORS
ChangeLog
VisualC6/jumpnbump.dsp
globals.pre
jumpnbump.6
main.c
menu.c
sdl/interrpt.c

diff --git a/AUTHORS b/AUTHORS
index f9e2d62..35ea1bb 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -56,3 +56,6 @@ Alessandro Gatti <a.gatti@tiscali.it>
 
 Ulrich Eckhardt <uli@doommachine.dyndns.org>
   Cleanup and small patches for enhanced networking.
+
+Ricardo Cruz <rick2@aeiou.pt>
+  AI functions
index 421d5da..e1c4617 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+27 Jun 2004 - 1.51
+  - refactored code to make it a bit simpler
+  - Added AI by Ricardo Cruz
+
 30 Mar 2004 - 1.42
   - added support for gzip and bzip2 packed levels.
 
index de65599..c6450cb 100644 (file)
@@ -43,7 +43,7 @@ RSC=rc.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "USE_SDL" /D "USE_NET" /D "ZLIB_SUPPORT" /D "BZLIB_SUPPORT" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "USE_SDL" /D "USE_NET" /D "BZLIB_SUPPORT" /YX /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x407 /d "NDEBUG"
index 469576e..f2346da 100644 (file)
@@ -79,7 +79,7 @@ void tellServerPlayerMoved(int playerid, int movement_type, int newval);
 #define MOVEMENT_RIGHT 2
 #define MOVEMENT_UP    3
 
-#define JNB_VERSION "1.42"
+#define JNB_VERSION "1.51"
 
 #define JNB_WIDTH 400
 #define JNB_HEIGHT 256
@@ -89,6 +89,8 @@ extern int screen_height;
 extern int screen_pitch;
 extern int scale_up;
 
+extern int ai[JNB_MAX_PLAYERS];
+
 #ifndef USE_SDL
 #define KEY_PL1_LEFT 0xcb
 #define KEY_PL1_RIGHT  0xcd
@@ -352,6 +354,7 @@ extern char last_keys[50];
 int hook_keyb_handler(void);
 void remove_keyb_handler(void);
 int key_pressed(int key);
+int addkey(unsigned int key);
 
 /* sound-linux.c */
 #ifdef LINUX
index 5acc604..a93092a 100644 (file)
@@ -64,6 +64,15 @@ Left - 4
 Right - 5
 .br
 Jump - 8
+.IP "In the game"
+Turn on/off computer play (AI) of bunny 1 - 1
+.br
+Turn on/off computer play (AI) of bunny 2 - 2
+.br
+Turn on/off computer play (AI) of bunny 3 - 3
+.br
+Turn on/off computer play (AI) of bunny 4 - 4
+.br
 .SH SECRET CODES
 You can type these while in the game
 .br
@@ -112,7 +121,7 @@ packed and are thus very large.
 .PP
 Chuck Mason <cemason@users.sourceforge.net>, Jon Atkins <jcatki@home.com>,
 Philippe Brochard <phil.brochard@wanadoo.fr>, Gürkan Sengün <gurkan@linuks.mine.nu>,
-Florian Schulze <crow@icculus.org> and "timecop" <timecop@japan.co.jp> are
+Florian Schulze <crow@icculus.org>, Ricardo Cruz <rick2@aeiou.pt> and "timecop" <timecop@japan.co.jp> are
 the authors of jump'n'bump.
 .PP
 This program is a UNIX port of the old DOS game by brainchilddesign. 
diff --git a/main.c b/main.c
index 6bb73e8..7cb4a09 100644 (file)
--- a/main.c
+++ b/main.c
@@ -65,6 +65,8 @@ int flip = 0;
 char pal[768];
 char cur_pal[768];
 
+int ai[JNB_MAX_PLAYERS];
+
 unsigned int ban_map[17][22] = {
        {1, 1, 1, 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, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0},
@@ -1432,6 +1434,11 @@ static int menu_loop(void)
        int c1, c2;
        int s1, s2;
 
+       for(c1 = 0; c1 < JNB_MAX_PLAYERS; c1++)         // reset player values
+        {
+               ai[c1] = 0;
+        }
+
        while (1) {
 
                if (!is_net)
@@ -1718,6 +1725,219 @@ static void player_action_right(int c1)
     }
 }
 
+int map_tile(int pos_x, int pos_y)
+{
+int tile;
+
+pos_x = pos_x >> 4;
+pos_y = pos_y >> 4;
+
+if(pos_x < 0 || pos_x >= 17 || pos_y < 0 || pos_y >= 22)
+  return BAN_VOID;
+
+tile = ban_map[pos_y][pos_x];
+return tile;
+}
+
+void cpu_move(void)
+{
+       int lm, rm, jm;
+       int i, j;
+       int cur_posx, cur_posy, tar_posx, tar_posy;
+       int players_distance;
+       player_t* target = NULL;
+       int nearest_distance = -1;
+
+       for (i = 0; i < JNB_MAX_PLAYERS; i++)
+               {
+         nearest_distance = -1;
+               if(ai[i] && player[i].enabled)          // this player is a computer
+                       {               // get nearest target
+                       for (j = 0; j < JNB_MAX_PLAYERS; j++)
+                               {
+                               int deltax, deltay;
+
+                               if(i == j || !player[j].enabled)
+                                       continue;
+
+                               deltax = player[j].x - player[i].x;
+                               deltay = player[j].y - player[i].y;
+                               players_distance = deltax*deltax + deltay*deltay;
+
+                               if (players_distance < nearest_distance || nearest_distance == -1)
+                                       {
+                                       target = &player[j];
+                                       nearest_distance = players_distance;
+                                       }
+                               }
+
+                       if(target == NULL)
+                               continue;
+
+                       cur_posx = player[i].x >> 16;
+                       cur_posy = player[i].y >> 16;
+                       tar_posx = target->x >> 16;
+                       tar_posy = target->y >> 16;
+
+                       /** nearest player found, get him */
+                       /* here goes the artificial intelligence code */
+
+                       /* X-axis movement */
+                       if(tar_posx > cur_posx)       // if true target is on the right side
+                               {    // go after him
+                               lm=0;
+                               rm=1;
+                               }
+                       else    // target on the left side
+                               {
+                               lm=1;
+                               rm=0;
+                               }
+
+                       if(cur_posy - tar_posy < 32 && cur_posy - tar_posy > 0 &&
+              tar_posx - cur_posx < 32+8 && tar_posx - cur_posx > -32)
+                               {
+                               lm = !lm;
+                               rm = !rm;
+                               }
+                       else if(tar_posx - cur_posx < 4+8 && tar_posx - cur_posx > -4)
+                               {      // makes the bunnies less "nervous"
+                               lm=0;
+                               lm=0;
+                               }
+
+                       /* Y-axis movement */
+                       if(map_tile(cur_posx, cur_posy+16) != BAN_VOID &&
+                               ((i == 0 && key_pressed(KEY_PL1_JUMP)) ||
+                               (i == 1 && key_pressed(KEY_PL2_JUMP)) ||
+                               (i == 2 && key_pressed(KEY_PL3_JUMP)) ||
+                               (i == 3 && key_pressed(KEY_PL4_JUMP))))
+                                       jm=0;   // if we are on ground and jump key is being pressed,
+                                                                       //first we have to release it or else we won't be able to jump more than once
+
+                       else if(map_tile(cur_posx, cur_posy-8) != BAN_VOID &&
+                               map_tile(cur_posx, cur_posy-8) != BAN_WATER)
+                                       jm=0;   // don't jump if there is something over it
+
+                       else if(map_tile(cur_posx-(lm*8)+(rm*16), cur_posy) != BAN_VOID &&
+                               map_tile(cur_posx-(lm*8)+(rm*16), cur_posy) != BAN_WATER &&
+                               cur_posx > 16 && cur_posx < 352-16-8)  // obstacle, jump
+                                       jm=1;   // if there is something on the way, jump over it
+
+                       else if(((i == 0 && key_pressed(KEY_PL1_JUMP)) ||
+                                                       (i == 1 && key_pressed(KEY_PL2_JUMP)) ||
+                                                       (i == 2 && key_pressed(KEY_PL3_JUMP)) ||
+                                                       (i == 3 && key_pressed(KEY_PL4_JUMP))) &&
+                                                       (map_tile(cur_posx-(lm*8)+(rm*16), cur_posy+8) != BAN_VOID &&
+                                                       map_tile(cur_posx-(lm*8)+(rm*16), cur_posy+8) != BAN_WATER))
+                                       jm=1;   // this makes it possible to jump over 2 tiles
+
+                       else if(cur_posy - tar_posy < 32 && cur_posy - tar_posy > 0 &&
+              tar_posx - cur_posx < 32+8 && tar_posx - cur_posx > -32)  // don't jump - running away
+                               jm=0;
+
+                       else if(tar_posy <= cur_posy)   // target on the upper side
+                               jm=1;
+                       else   // target below
+                               jm=0;
+
+                       /** Artificial intelligence done, now apply movements */
+                       if(lm)
+                               {
+                               SDLKey key;
+                               if(i == 0)
+                                       key = KEY_PL1_LEFT;
+                               else if(i == 1)
+                                       key = KEY_PL2_LEFT;
+                               else if(i == 2)
+                                       key = KEY_PL3_LEFT;
+                               else
+                                       key = KEY_PL4_LEFT;
+
+                               key &= 0x7f;
+                               addkey(key);
+                               }
+                       else
+                               {
+                               SDLKey key;
+                               if(i == 0)
+                                       key = KEY_PL1_LEFT;
+                               else if(i == 1)
+                                       key = KEY_PL2_LEFT;
+                               else if(i == 2)
+                                       key = KEY_PL3_LEFT;
+                               else
+                                       key = KEY_PL4_LEFT;
+
+                               key &= 0x7f;
+                               addkey(key | 0x8000);
+                               }
+
+                       if(rm)
+                               {
+                               SDLKey key;
+                               if(i == 0)
+                                       key = KEY_PL1_RIGHT;
+                               else if(i == 1)
+                                       key = KEY_PL2_RIGHT;
+                               else if(i == 2)
+                                       key = KEY_PL3_RIGHT;
+                               else
+                                       key = KEY_PL4_RIGHT;
+
+                               key &= 0x7f;
+                               addkey(key);
+                               }
+                       else
+                               {
+                               SDLKey key;
+                               if(i == 0)
+                                       key = KEY_PL1_RIGHT;
+                               else if(i == 1)
+                                       key = KEY_PL2_RIGHT;
+                               else if(i == 2)
+                                       key = KEY_PL3_RIGHT;
+                               else
+                                       key = KEY_PL4_RIGHT;
+
+                               key &= 0x7f;
+                               addkey(key | 0x8000);
+                               }
+
+                       if(jm)
+                               {
+                               SDLKey key;
+                               if(i == 0)
+                                       key = KEY_PL1_JUMP;
+                               else if(i == 1)
+                                       key = KEY_PL2_JUMP;
+                               else if(i == 2)
+                                       key = KEY_PL3_JUMP;
+                               else
+                                       key = KEY_PL4_JUMP;
+
+                               key &= 0x7f;
+                               addkey(key);
+                               }
+                       else
+                               {
+                               SDLKey key;
+                               if(i == 0)
+                                       key = KEY_PL1_JUMP;
+                               else if(i == 1)
+                                       key = KEY_PL2_JUMP;
+                               else if(i == 2)
+                                       key = KEY_PL3_JUMP;
+                               else
+                                       key = KEY_PL4_JUMP;
+
+                               key &= 0x7f;
+                               addkey(key | 0x8000);
+                               }
+                       }
+               }
+}
+
 
 #define GET_BAN_MAP_IN_WATER(s1, s2) (GET_BAN_MAP_XY((s1), ((s2) + 7)) == BAN_VOID || GET_BAN_MAP_XY(((s1) + 15), ((s2) + 7)) == BAN_VOID) && (GET_BAN_MAP_XY((s1), ((s2) + 8)) == BAN_WATER || GET_BAN_MAP_XY(((s1) + 15), ((s2) + 8)) == BAN_WATER)
 
@@ -1727,6 +1947,7 @@ void steer_players(void)
        int c1, c2;
        int s1 = 0, s2 = 0;
 
+       cpu_move();
        update_player_actions();
 
        for (c1 = 0; c1 < JNB_MAX_PLAYERS; c1++) {
diff --git a/menu.c b/menu.c
index 2f53113..563c25e 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -77,6 +77,23 @@ int menu(void)
        if (menu_init() != 0)
                return 1;
 
+  /* After a game, we have to release the keys, cause AI player
+     can still be using them */
+       addkey((KEY_PL1_LEFT & 0x7f) | 0x8000);
+       addkey((KEY_PL2_LEFT & 0x7f) | 0x8000);
+       addkey((KEY_PL3_LEFT & 0x7f) | 0x8000);
+       addkey((KEY_PL4_LEFT & 0x7f) | 0x8000);
+
+       addkey((KEY_PL1_RIGHT & 0x7f) | 0x8000);
+       addkey((KEY_PL2_RIGHT & 0x7f) | 0x8000);
+       addkey((KEY_PL3_RIGHT & 0x7f) | 0x8000);
+       addkey((KEY_PL4_RIGHT & 0x7f) | 0x8000);
+
+       addkey((KEY_PL1_JUMP & 0x7f) | 0x8000);
+       addkey((KEY_PL2_JUMP & 0x7f) | 0x8000);
+       addkey((KEY_PL3_JUMP & 0x7f) | 0x8000);
+       addkey((KEY_PL4_JUMP & 0x7f) | 0x8000);
+
        mod_vol = 0;
        mod_fade_direction = 1;
        dj_ready_mod(MOD_MENU);
@@ -106,6 +123,9 @@ int menu(void)
 
                dj_mix();
 
+       for(c1 = 0; c1 < JNB_MAX_PLAYERS; c1++)         // set AI to false
+               ai[c1] = 0;
+
                while (update_count) {
 
                        if (key_pressed(1) == 1 && esc_pressed == 0) {
index 5f72277..91a27ab 100644 (file)
@@ -310,6 +310,49 @@ int intr_sysupdate()
        while (SDL_PollEvent(&e)) {
                switch (e.type) {
                case SDL_MOUSEBUTTONDOWN:
+               case SDL_MOUSEBUTTONUP:
+                       if(e.button.state == SDL_PRESSED &&
+                                       ((key_pressed(KEY_PL3_LEFT) && e.button.button == SDL_BUTTON_RIGHT) ||
+                                       (key_pressed(KEY_PL3_RIGHT) && e.button.button == SDL_BUTTON_LEFT) ||
+                                       (e.button.button == SDL_BUTTON_LEFT && e.button.button == SDL_BUTTON_RIGHT) ||
+          e.button.button == SDL_BUTTON_MIDDLE))
+                               {
+                               addkey(KEY_PL3_JUMP & 0x7f);
+                               }
+                       else if(e.button.state == SDL_RELEASED &&
+                                       ((key_pressed(KEY_PL3_LEFT) && e.button.button == SDL_BUTTON_RIGHT) ||
+                                       (key_pressed(KEY_PL3_RIGHT) && e.button.button == SDL_BUTTON_LEFT) ||
+          e.button.button == SDL_BUTTON_MIDDLE))
+                               {
+                               addkey((KEY_PL3_JUMP & 0x7f) | 0x8000);
+                               }
+
+                       if(e.button.button == SDL_BUTTON_LEFT)
+                               {
+                               SDLKey sym = KEY_PL3_LEFT;
+                               sym &= 0x7f;
+                               if(e.button.state == SDL_RELEASED)
+                                       {
+                                       if(key_pressed(KEY_PL3_JUMP) && (SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(SDL_BUTTON_RIGHT)))
+                                               addkey(KEY_PL3_RIGHT & 0x7f);
+                                       else
+                                               sym |= 0x8000;
+                                       }
+                               addkey(sym);
+                               }
+                       else if(e.button.button == SDL_BUTTON_RIGHT)
+                               {
+                               SDLKey sym = KEY_PL3_RIGHT;
+                               sym &= 0x7f;
+                               if (e.button.state == SDL_RELEASED)
+                                       {
+                                       if(key_pressed(KEY_PL3_JUMP) && (SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(SDL_BUTTON_LEFT)))
+                                               addkey(KEY_PL3_LEFT & 0x7f);
+                                       else
+                                               sym |= 0x8000;
+                                       }
+                               addkey(sym);
+                               }
                        break;
                case SDL_KEYDOWN:
                case SDL_KEYUP:
@@ -325,6 +368,42 @@ int intr_sysupdate()
                                        fs_toggle();
                                }
                                break;
+                       case SDLK_1:
+                               if (e.type == SDL_KEYUP)
+                                       ai[0] = !ai[0];
+
+                               /* Release keys, otherwise it will continue moving that way */
+                               addkey((KEY_PL1_LEFT & 0x7f) | 0x8000);
+                               addkey((KEY_PL1_RIGHT & 0x7f) | 0x8000);
+                               addkey((KEY_PL1_JUMP & 0x7f) | 0x8000);
+                               break;
+                       case SDLK_2:
+                               if (e.type == SDL_KEYUP)
+                                       ai[1] = !ai[1];
+
+                               /* Release keys, otherwise it will continue moving that way */
+                               addkey((KEY_PL2_LEFT & 0x7f) | 0x8000);
+                               addkey((KEY_PL2_RIGHT & 0x7f) | 0x8000);
+                               addkey((KEY_PL2_JUMP & 0x7f) | 0x8000);
+                               break;
+                       case SDLK_3:
+                               if (e.type == SDL_KEYUP)
+                                       ai[2] = !ai[2];
+
+                               /* Release keys, otherwise it will continue moving that way */
+                               addkey((KEY_PL3_LEFT & 0x7f) | 0x8000);
+                               addkey((KEY_PL3_RIGHT & 0x7f) | 0x8000);
+                               addkey((KEY_PL3_JUMP & 0x7f) | 0x8000);
+                               break;
+                       case SDLK_4:
+                               if (e.type == SDL_KEYUP)
+                                       ai[3] = !ai[3];
+
+                               /* Release keys, otherwise it will continue moving that way */
+                               addkey((KEY_PL4_LEFT & 0x7f) | 0x8000);
+                               addkey((KEY_PL4_RIGHT & 0x7f) | 0x8000);
+                               addkey((KEY_PL4_JUMP & 0x7f) | 0x8000);
+                               break;
                        case SDLK_ESCAPE:
                                if (e.type == SDL_KEYUP)
                                        addkey(1 | 0x8000);