rnd-19981016-1
authorHolger Schemel <info@artsoft.org>
Fri, 16 Oct 1998 00:17:12 +0000 (02:17 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:31:10 +0000 (10:31 +0200)
src/game.c
src/init.c
src/main.h
src/netserv.c
src/network.c

index 622a1857a553a41e70a89b7a00a9c5ff0cc152d4..7e678bfbd4f063ea04e37486abb4c7143f408f2d 100644 (file)
@@ -72,8 +72,13 @@ void InitGame()
 
     player->index_nr = i;
     player->element_nr = EL_SPIELER1 + i;
+
+    player->present = FALSE;
     player->active = FALSE;
+
+    /*
     player->local = FALSE;
+    */
 
     player->score = 0;
     player->gems_still_needed = level.edelsteine;
@@ -129,8 +134,10 @@ void InitGame()
     player->GameOver = FALSE;
   }
 
+  /*
   local_player->active = TRUE;
   local_player->local = TRUE;
+  */
 
   network_player_action_received = FALSE;
 
@@ -181,16 +188,30 @@ void InitGame()
        struct PlayerInfo *player = &stored_player[Feld[x][y] - EL_SPIELER1];
        int jx = player->jx, jy = player->jy;
 
-       /* remove duplicate players */
+       /*
+       player->active = TRUE;
+       */
+
+       player->present = TRUE;
+       if (player->connected)
+       {
+         player->active = TRUE;
+
+         printf("Player %d activated.\n", player->element_nr);
+         printf("[Local player is %d and currently %s.]\n",
+                local_player->element_nr,
+                local_player->active ? "active" : "not active");
+       }
+
+       /* remove potentially duplicate players */
        if (StorePlayer[jx][jy] == Feld[x][y])
          StorePlayer[jx][jy] = 0;
 
-       player->active = TRUE;
-
        StorePlayer[x][y] = Feld[x][y];
        Feld[x][y] = EL_LEERRAUM;
        player->jx = player->last_jx = x;
        player->jy = player->last_jy = y;
+
        break;
       }
       case EL_BADEWANNE:
@@ -268,6 +289,52 @@ void InitGame()
     }
   }
 
+  /* check if any connected player was not found in playfield */
+  for(i=0; i<MAX_PLAYERS; i++)
+  {
+    struct PlayerInfo *player = &stored_player[i];
+
+    if (player->connected && !player->present)
+    {
+      printf("Oops!\n");
+
+
+      for(j=0; j<MAX_PLAYERS; j++)
+      {
+       struct PlayerInfo *some_player = &stored_player[j];
+       int jx = some_player->jx, jy = some_player->jy;
+
+       /* assign first free player found that is present in the playfield */
+       if (some_player->present && !some_player->connected)
+       {
+         player->present = TRUE;
+         player->active = TRUE;
+         some_player->present = FALSE;
+
+         StorePlayer[jx][jy] = player->element_nr;
+         player->jx = player->last_jx = jx;
+         player->jy = player->last_jy = jy;
+
+         break;
+       }
+      }
+    }
+  }
+
+  for(i=0; i<MAX_PLAYERS; i++)
+  {
+    struct PlayerInfo *player = &stored_player[i];
+
+    printf("Player %d: present == %d, connected == %d, active == %d.\n",
+          i+1,
+          player->present,
+          player->connected,
+          player->active);
+    if (local_player == player)
+      printf("Player %d is local player.\n", i+1);
+  }
+
+
   game_emulation = (emulate_bd ? EMU_BOULDERDASH :
                    emulate_sb ? EMU_SOKOBAN : EMU_NONE);
 
@@ -324,6 +391,12 @@ void InitGame()
     PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
 
   XAutoRepeatOff(display);
+
+
+  for (i=0;i<4;i++)
+    printf("Spieler %d %saktiv.\n",
+          i+1, (stored_player[i].active ? "" : "nicht "));
+
 }
 
 void InitMovDir(int x, int y)
index 6931936ee00a902d1aa55ba437dfa8dba5d5fa95..cbfab54b20dae6f0bb8a34c653630f0e075dd0b1 100644 (file)
@@ -92,6 +92,8 @@ void OpenAll(int argc, char *argv[])
 
 void InitLevelAndPlayerInfo()
 {
+  int i;
+
   local_player = &stored_player[0];
 
   if (!LoadLevelInfo())                        /* global level info */
@@ -99,6 +101,14 @@ void InitLevelAndPlayerInfo()
 
   LoadPlayerInfo(PLAYER_SETUP);                /* global setup info */
   LoadPlayerInfo(PLAYER_LEVEL);                /* level specific info */
+
+  for (i=0; i<MAX_PLAYERS; i++)
+  {
+    stored_player[i].connected = FALSE;
+    stored_player[i].local = FALSE;
+  }
+  local_player->connected = TRUE;
+  local_player->local = TRUE;
 }
 
 void InitNetworkServer()
index ce5d1bb99cc9753a168bea37bfff849d0bf85bae..0e967f3d7ca1256bb3f072263e5466a6a12493bd 100644 (file)
@@ -209,7 +209,11 @@ struct HiScore
 
 struct PlayerInfo
 {
-  int active, local;
+  BOOL present;                        /* player present in level playfield */
+  BOOL connected;              /* player connected locally or via network */
+  BOOL local;                  /* player connected locally */
+  BOOL active;                 /* player (present && connected) */
+
   int index_nr, client_nr, element_nr;
 
   char login_name[MAX_NAMELEN];
@@ -221,13 +225,11 @@ struct PlayerInfo
 
   int jx,jy, last_jx,last_jy;
   int MovDir, MovPos, GfxPos;
-  int Pushing, Frame;
-
-  int gone, LevelSolved, GameOver;
-
-  long actual_frame_counter;
+  int Frame;
 
-  int frame_reset_delay;
+  BOOL Pushing;
+  BOOL gone, LevelSolved, GameOver;
+  BOOL snapped;
 
   long move_delay;
   int last_move_dir;
@@ -235,7 +237,9 @@ struct PlayerInfo
   long push_delay;
   int push_delay_value;
 
-  int snapped;
+  int frame_reset_delay;
+
+  long actual_frame_counter;
 
   int score;
   int gems_still_needed;
index b9dad16248cc83e0dcf4e6cbe2660f10c1a8e82f..aec5d0576d3d147f735e4d03d3b1aa4ceb07d116 100644 (file)
@@ -270,6 +270,7 @@ static void Handle_OP_PROTOCOL_VERSION(struct user *u, unsigned int len)
 static void Handle_OP_NUMBER_WANTED(struct user *u)
 {
   struct user *v;
+  int client_nr = u->number;
   int nr_wanted = buf[2];
   int nr_is_free = 1;
 
@@ -302,11 +303,16 @@ static void Handle_OP_NUMBER_WANTED(struct user *u)
   if (nr_is_free)
     u->number = nr_wanted;
 
-  buf[0] = 0;
+  buf[0] = client_nr;
   buf[1] = OP_NUMBER_WANTED;
   buf[2] = nr_wanted;
   buf[3] = u->number;
+
+  /*
   sendtoone(u, 4);
+  */
+
+  broadcast(NULL, 4, 0);
 }
 
 static void Handle_OP_NICKNAME(struct user *u, unsigned int len)
@@ -455,8 +461,8 @@ static void Handle_OP_STOP_PLAYING(struct user *u)
 static void Handle_OP_MOVE_FIGURE(struct user *u)
 {
   struct user *v;
-  int actions_complete = 1;
   int last_client_nr = 0;
+  int i;
 
   /* store player action */
   for (v=user0; v; v=v->next)
@@ -472,14 +478,15 @@ static void Handle_OP_MOVE_FIGURE(struct user *u)
   for (v=user0; v; v=v->next)
   {
     if (!v->action_received)
-    {
-      actions_complete = 0;
-      break;
-    }
+      return;
+
+    if (v->number > last_client_nr)
+      last_client_nr = v->number;
   }
 
-  if (!actions_complete)
-    return;
+  /* initialize all player actions to zero */
+  for (i=0; i<last_client_nr; i++)
+    buf[6 + i] = 0;
 
   /* broadcast actions of all players to all players */
   for (v=user0; v; v=v->next)
@@ -487,9 +494,6 @@ static void Handle_OP_MOVE_FIGURE(struct user *u)
     buf[6 + v->number-1] = v->action;
     v->action = 0;
     v->action_received = 0;
-
-    if (v->number > last_client_nr)
-      last_client_nr = v->number;
   }
 
   buf[2] = (unsigned char)((frame_counter >> 24) & 0xff);
index 82f406d61382f39df2fa06fc15870d5497a5e989..126eb52351a7c2f916323a237ef9f3129735c0b0 100644 (file)
@@ -314,12 +314,22 @@ static void Handle_OP_YOUR_NUMBER()
 {
   int new_client_nr = buf[2];
   int new_index_nr = new_client_nr - 1;
+  struct PlayerInfo *old_local_player = local_player;
+  struct PlayerInfo *new_local_player = &stored_player[new_index_nr];
 
   printf("OP_YOUR_NUMBER: %d\n", buf[0]);
   me.nr = new_client_nr;
 
-  stored_player[new_index_nr] = *local_player;
-  local_player = &stored_player[new_index_nr];
+  if (old_local_player != new_local_player)
+  {
+    /* copy existing player settings and change to new player */
+
+    *new_local_player = *old_local_player;
+    old_local_player->connected = FALSE;
+    old_local_player->local = FALSE;
+
+    local_player = new_local_player;
+  }
 
   TestPlayer = new_index_nr;
 
@@ -333,38 +343,63 @@ static void Handle_OP_YOUR_NUMBER()
 static void Handle_OP_NUMBER_WANTED()
 {
   int client_nr_wanted = buf[2];
+  int old_client_nr = buf[0];
   int new_client_nr = buf[3];
+  int old_index_nr = old_client_nr - 1;
   int new_index_nr = new_client_nr - 1;
+  int index_nr_wanted = client_nr_wanted - 1;
+  struct PlayerInfo *old_player = &stored_player[old_index_nr];
+  struct PlayerInfo *new_player = &stored_player[new_index_nr];
 
   printf("OP_NUMBER_WANTED: %d\n", buf[0]);
 
-  if (new_client_nr != client_nr_wanted)
+  if (new_client_nr == client_nr_wanted)       /* switching succeeded */
+  {
+    struct user *u;
+
+    if (old_client_nr != client_nr_wanted)     /* client's nr has changed */
+    {
+      sprintf(msgbuf, "client %d switches to # %d",
+             old_client_nr, new_client_nr);
+      sysmsg(msgbuf);
+    }
+    else if (old_client_nr == me.nr)           /* local player keeps his nr */
+    {
+      sprintf(msgbuf, "keeping client # %d", new_client_nr);
+      sysmsg(msgbuf);
+    }
+
+    if (old_client_nr != new_client_nr)
+    {
+      /* copy existing player settings and change to new player */
+
+      *new_player = *old_player;
+      old_player->connected = FALSE;
+      old_player->local = FALSE;
+    }
+
+    u = finduser(old_client_nr);
+    u->nr = new_client_nr;
+
+    if (old_client_nr == local_player->client_nr) /* local player switched */
+      local_player = new_player;
+
+
+
+    TestPlayer = new_index_nr;
+  }
+  else if (old_client_nr == me.nr)             /* failed -- local player? */
   {
     char *color[] = { "yellow", "red", "green", "blue" };
 
-    sprintf(msgbuf, "Sorry ! You are %s player !",
-           color[new_index_nr]);
+    sprintf(msgbuf, "Sorry ! %s player still exists ! You are %s player !",
+           color[index_nr_wanted], color[new_index_nr]);
     Request(msgbuf, REQ_CONFIRM);
 
     sprintf(msgbuf, "cannot switch -- you keep client # %d",
            new_client_nr);
     sysmsg(msgbuf);
   }
-  else
-  {
-    if (me.nr != client_nr_wanted)
-      sprintf(msgbuf, "switching to client # %d", new_client_nr);
-    else
-      sprintf(msgbuf, "keeping client # %d", new_client_nr);
-    sysmsg(msgbuf);
-
-    me.nr = new_client_nr;
-
-    stored_player[new_index_nr] = *local_player;
-    local_player = &stored_player[new_index_nr];
-
-    TestPlayer = new_index_nr;
-  }
 }
 
 static void Handle_OP_NICKNAME(unsigned int len)
@@ -382,23 +417,27 @@ static void Handle_OP_NICKNAME(unsigned int len)
 static void Handle_OP_PLAYER_CONNECTED()
 {
   struct user *u, *v = NULL;
+  int new_client_nr = buf[0];
+  int new_index_nr = new_client_nr - 1;
 
-  printf("OP_PLAYER_CONNECTED: %d\n", buf[0]);
-  sprintf(msgbuf, "new client %d connected", buf[0]);
+  printf("OP_PLAYER_CONNECTED: %d\n", new_client_nr);
+  sprintf(msgbuf, "new client %d connected", new_client_nr);
   sysmsg(msgbuf);
 
   for (u = &me; u; u = u->next)
   {
-    if (u->nr == buf[0])
+    if (u->nr == new_client_nr)
       Error(ERR_EXIT, "multiplayer server sent duplicate player id");
     else
       v = u;
   }
 
   v->next = u = mmalloc(sizeof(struct user));
-  u->nr = buf[0];
+  u->nr = new_client_nr;
   u->name[0] = '\0';
   u->next = NULL;
+
+  stored_player[new_index_nr].connected = TRUE;
 }
 
 static void Handle_OP_PLAYER_DISCONNECTED()
@@ -511,7 +550,7 @@ static void Handle_OP_STOP_PLAYING()
   DrawMainMenu();
 }
 
-static void Handle_OP_MOVE_FIGURE()
+static void Handle_OP_MOVE_FIGURE(unsigned int len)
 {
   int frame_nr;
   int i;
@@ -530,11 +569,10 @@ static void Handle_OP_MOVE_FIGURE()
     Error(ERR_EXIT,   "this should not happen -- please debug");
   }
 
+  /* copy valid player actions */
   for (i=0; i<MAX_PLAYERS; i++)
-  {
-    if (stored_player[i].active)
-      network_player_action[i] = buf[6 + i];
-  }
+    network_player_action[i] =
+      (i < len - 6 && stored_player[i].active ? buf[6 + i] : 0);
 
   network_player_action_received = TRUE;
 
@@ -602,7 +640,7 @@ static void handlemessages()
        break;
 
       case OP_MOVE_FIGURE:
-       Handle_OP_MOVE_FIGURE();
+       Handle_OP_MOVE_FIGURE(len);
        break;
 
       case OP_WON: