Logo Search packages:      
Sourcecode: gtkatlantic version File versions  Download package

game.c

/*
 *     gtkatlantic - the gtk+ monopd client, enjoy network monopoly games
 *
 *
 *  Copyright (C) 2002-2004 Rochet Sylvain
 *
 *  gtkatlantic is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <sys/time.h>
#include <gtk/gtk.h>

#include <libxml/parser.h>

#include "config.h"

#include "global.h"
#include "game.h"
#include "load.h"
#include "interface.h"
#include "client.h"
#include "trade.h"
#include "engine.h"


/* create home directory (~/.gtkatlantic) *
 * return TRUE if exist/created, return FALSE if cannot be created */
gboolean create_home_directory()  {

      guchar *path;
      struct stat s;

      path = g_strconcat( getenv("HOME"), "/", ".", PACKAGE, "/", NULL);
      global->path_home = g_strdup(path);
      if(stat(path, &s) < 0)  {

            mkdir(path, 0777);
            if(stat(path, &s) < 0)  {

                  g_free(path);
                  return FALSE;
            }
      }
      g_free(path);

      path = g_strconcat( global->path_home, "themes/", NULL);
      if(stat(path, &s) < 0)  {

            mkdir(path, 0777);
            if(stat(path, &s) < 0)  {

                  g_free(path);
                  return FALSE;
            }
      }
      g_free(path);

      return TRUE;
}


/* read config files */
void read_config_files()   {

      guchar *filename;
      struct stat s;

      /* read default config file */
      filename = g_strconcat(PACKAGE_DATA_DIR, "/default.conf", NULL);
      if(! parse_file_config(filename) ) {
            printf("Error opening config file %s\n",filename);
            exit(-1);
      }

      g_free(filename);

      /* read user config file */
      filename = g_strconcat(global->path_home, "gtkatlantic.conf", NULL);
      if(stat(filename, &s) >= 0)
            parse_file_config(filename);

      g_free(filename);
}


/* return a valid slot for a connection     *
 *   else return FALSE                      */
gboolean connect_get_valid_id(guint16 *idconnect)  {

      guint16 i;

      for(i = 1; i < MAX_CONNECTION; i++)
            if(!connection_is_open[i]) {

                  *idconnect = i;
                  return(TRUE);
            }

      return(FALSE);
}


/* this function made a new connection for metaserver (list & games) */
void create_connection_metaserver(guint32 gametype)  {

      guint16 connectid;
      gchar *sendstr;

      if(! client_connect(&connectid, config->metaserver_host, config->metaserver_port) ) return;
      connection[connectid]->type = gametype;

      /* send client version (to retrieve info about release) */
      if(config->metaserver_sendclientversion)  {

            sendstr = g_strconcat("CHECKCLIENT", PACKAGE, VERSION, "\n", NULL);
            client_send(connectid, sendstr, strlen(sendstr));
            g_free(sendstr);
      }

      if(gametype == CONNECT_TYPE_META_GETLIST)  {
            sendstr = g_strdup("SERVERLIST\n");
            client_send(connectid, sendstr, strlen(sendstr));
            g_free(sendstr);
      }
      else  {
            sendstr = g_strdup("GAMELIST\n");
            client_send(connectid, sendstr, strlen(sendstr));
            g_free(sendstr);
      }
}


/* this function made a new connection for get games only */
void create_connection_get_games(guchar *host, guint32 port)  {

      guint16 connectid;
      gchar *sendstr;

      if(! client_connect(&connectid, host, port) ) return;
      connection[connectid]->type = CONNECT_TYPE_MONOPD_GETGAME;

      sendstr = g_strdup(".n_client_\n.gl\n");
      client_send(connectid, sendstr, strlen(sendstr));
      g_free(sendstr);
}


/* insert test in Message Box */
void text_insert_message(gchar* text, guint32 length)  {

      GtkTextBuffer *textbuff;
      GtkTextIter textiter;
      GtkTextMark *textmark;

      guint32 i, len;

      if(global->phase < PHASE_GETGAMES) return;

      textbuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(global->Message));
      gtk_text_buffer_get_end_iter(textbuff, &textiter);
      gtk_text_buffer_insert(textbuff, &textiter, text, length);
      gtk_text_buffer_insert(textbuff, &textiter, "\n", -1);

      /* Scroll the text */
      textmark = gtk_text_buffer_get_mark(textbuff, "endmark");
      gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(global->Message), textmark,
                  0.0, FALSE, 0.0, 0.0);

      global->message_nb_lines++;

//    while(global->message_nb_lines > config->message_max_lines) {

            /* if unlimited */
/*          if(config->message_max_lines <= 0)  break;

            len = gtk_text_get_length( GTK_TEXT(global->Message) );

            for(i = 0 ;  GTK_TEXT_INDEX( GTK_TEXT(global->Message), i) != '\n' ; i++)  {

                  if(i >= len)  { /* argl... no CR founded */

/*                      gtk_text_set_point( GTK_TEXT(global->Message), 0);
                        gtk_text_forward_delete( GTK_TEXT(global->Message), len);
                        global->message_nb_lines = 0;
                        break;
                  }
            }

            if(global->message_nb_lines)  {

                  i++;
                  gtk_text_set_point( GTK_TEXT(global->Message), 0);
                  gtk_text_forward_delete( GTK_TEXT(global->Message), i);
                  global->message_nb_lines--;
            }
      }

      len = gtk_text_get_length( GTK_TEXT(global->Message) );
      gtk_text_set_point( GTK_TEXT(global->Message), len);

      gtk_text_thaw( GTK_TEXT(global->Message) );

      gtk_adjustment_set_value( GTK_ADJUSTMENT( GTK_TEXT( global->Message )->vadj ),  GTK_ADJUSTMENT( GTK_TEXT( global->Message )->vadj )->upper );
      */
}


/* insert test in Chat Box */
void text_insert_chat(gchar* text, guint32 length)
{
      GtkTextBuffer *textbuff;
      GtkTextIter textiter;
      GtkTextMark *textmark;

      guint32 i, len;

      if(global->phase < PHASE_GAMECREATE)
            return;

      textbuff = gtk_text_view_get_buffer(GTK_TEXT_VIEW(game->Chat));
      gtk_text_buffer_get_end_iter(textbuff, &textiter);
      gtk_text_buffer_insert(textbuff, &textiter, text, length);
      gtk_text_buffer_insert(textbuff, &textiter, "\n", -1);

      /* Scroll to the end mark */
      textmark = gtk_text_buffer_get_mark(textbuff, "endmark");
      gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(game->Chat), textmark,
                  0.0, FALSE, 0.0, 0.0);

      game->chat_nb_lines++;

/*    while(game->chat_nb_lines > config->chat_max_lines) {

            /* if unlimited */
/*          if(config->chat_max_lines <= 0)  break;

            len = gtk_text_get_length( GTK_TEXT(game->Chat) );

            for(i = 0 ;  GTK_TEXT_INDEX( GTK_TEXT(game->Chat), i) != '\n' ; i++)  {

                  if(i >= len)  { /* argl... no CR founded */

/*                      gtk_text_set_point( GTK_TEXT(game->Chat), 0);
                        gtk_text_forward_delete( GTK_TEXT(game->Chat), len);
                        game->chat_nb_lines = 0;
                        break;
                  }
            }

            if(game->chat_nb_lines)  {

                  i++;
                  gtk_text_set_point( GTK_TEXT(game->Chat), 0);
                  gtk_text_forward_delete( GTK_TEXT(game->Chat), i);
                  game->chat_nb_lines--;
            }
      }

      len = gtk_text_get_length( GTK_TEXT(game->Chat) );
      gtk_text_set_point( GTK_TEXT(game->Chat), len);

      gtk_text_thaw( GTK_TEXT(game->Chat) );

//    gtk_adjustment_set_value( GTK_ADJUSTMENT( GTK_TEXT( game->Chat )->vadj ),  GTK_ADJUSTMENT( GTK_TEXT( game->Chat )->vadj )->upper );

      */
}


/* alloc all memory for a game */
void game_alloc()  {

      game = g_malloc0(sizeof (_game) );
}


/* free entirely a game, return to get games page */
void game_free()  {

      guint32 i;

      client_disconnect(game->connectid);

      interface_destroy_message();
      interface_destroy_chat();
      if(game->WinEstateTree)  gtk_widget_destroy(game->WinEstateTree);

      if(game->timeout_token)  gtk_timeout_remove(game->timeout_token);

      interface_create_getgamespage();

      for(i = 0 ; i < MAX_PLAYERS ; i++)  {

            if(! global->player[i].playerid) continue;

            if(global->player[i].name) g_free(global->player[i].name);
            if(global->player[i].host) g_free(global->player[i].host);
            if(global->player[i].image) g_free(global->player[i].image);

            frame_destroy( global->player[i].playerlist_token_frame );
            frame_destroy( global->player[i].playerlist_cards_frame );
      }

      for(i = 0 ; i < data->number_estates ; i++)  {

            if(game->estate[i].name) g_free(game->estate[i].name);
      }

      for(i = 0 ; i < MAX_GROUPS ; i++)  {

            if(game->group[i].name) g_free(game->group[i].name);
      }

      for(i = 0 ; i < MAX_TRADES ; i++)  {

            trade_destroy_slot(i);
      }

      for(i = 0 ; i < MAX_COMMANDS ; i++)  {

            if(game->command[i].open  &&  game->command[i].command)
                  g_free(game->command[i].command);
      }

      frame_destroy( game->board_frame );

      game_free_pngs();

      g_free(game);
      game = 0;
}


/* return a valid game id */
gboolean game_get_valid_player_slot(guint8 *playerslot)  {

      guint32 i;

      for(i = 0; i < MAX_PLAYERS; i++)
            if(!global->player[i].playerid) {

                  *playerslot = i;
                  return TRUE;
            }

      return FALSE;
}


/* return the player slot of playerid */
gint8 get_player_slot_with_playerid(guint32 playerid)  {

      guint32 i;

      for(i = 0 ; i < MAX_PLAYERS ; i++)  {

            if(global->player[i].playerid == playerid) {

                  return(i);
                  break;
            }
      }

      return(-1);
}


gint8 get_playerlistcard_id_with_estate(guint32 estate)  {

      guint32 i;

      for(i = 0 ; i < data->number_playerlist_card ; i++)  {

            if(data->playerlist_card[i].estateid == estate) {

                  return(i);
                  break;
            }
      }

      return(-1);
}


/* return a valid command slotid */
gboolean game_get_valid_command_slot(guint8 *commandslot)  {

      guint8 i;

      for(i = 0; i < MAX_COMMANDS ; i++)
            if(!game->command[i].open) {

                  *commandslot = i;
                  return TRUE;
            }

      return FALSE;
}


/* return commandslot if button command is displayed
   return <0 if button not is not displayed           */
gint8 get_command_button_slot_with_command(guchar *command) {

      guint32 i;

      for(i = 0 ; i < MAX_COMMANDS ; i ++)  {

            if(game->command[i].open)  {

                  if(! strncmp(command, game->command[i].command, strlen(command)) )
                        return i;
            }
      }

      return -1;
}


/* send specific chat message, like version */
void parse_specific_chat_message(guchar *message)   {

      guchar *msg, *sendstr;
      guint32 pslot;

      struct timeval tv;
      time_t t_now;

      pslot = get_player_slot_with_playerid( game->my_playerid );

      if(message[0] != '!') return;

      msg = message;
      msg++;

      if(! strncmp(msg, "version", 7))  {

            msg += 7;
            while( strlen(msg) )  {

                  if(msg[0] != ' ') break;
                  else  msg++;
            }

            if(strlen(msg) == 0  ||  !strcmp(msg, global->player[pslot].name) )  {

                  sendstr = g_strdup_printf("GtkAtlantic %s\n", VERSION);
                  client_send(game->connectid, sendstr, strlen(sendstr));
                  g_free(sendstr);
            }
      }


      else if(! strncmp(msg, "date", 4))  {

            msg += 4;
            while( strlen(msg) )  {

                  if(msg[0] != ' ') break;
                  else  msg++;
            }

            if(strlen(msg) == 0  ||  !strcmp(msg, global->player[pslot].name) )  {

                  gettimeofday(&tv, NULL);
                  t_now = tv.tv_sec;
                  sendstr = g_strdup_printf("%s", ctime(&t_now) );
                  client_send(game->connectid, sendstr, strlen(sendstr));
                  g_free(sendstr);
            }
      }

      else if(! strncmp(msg, "ping", 4))  {

            msg += 4;
            while( strlen(msg) )  {

                  if(msg[0] != ' ') break;
                  else  msg++;
            }

            if(strlen(msg) == 0  ||  !strcmp(msg, global->player[pslot].name) )  {

                  sendstr = g_strdup_printf("pong\n");
                  client_send(game->connectid, sendstr, strlen(sendstr));
                  g_free(sendstr);
            }
      }
}


/* parse specific send message */
void parse_specific_send_message(guchar *message)   {

      guchar *msg, *tmp;
      guint32 i;
      gint32 playerid, pslot;

      struct timeval tv;
      struct tm *local_tm;
      time_t t_now;

      if(message[0] != '/') return;

      msg = message;
      msg++;

      if(! strncmp(msg, "assets", 6))  {

            msg += 6;
            while( strlen(msg) )  {

                  if(msg[0] != ' ') break;
                  else  msg++;
            }

            if(strlen(msg) == 0)  {

                  for(i = 0 ; i < MAX_PLAYERS ; i++)  {

                        if(! global->player[i].playerid)  continue;
                        if(global->player[i].game != game->gameid)  continue;

                        tmp = g_strdup_printf("<%s> %d", global->player[i].name, game_get_assets_player(global->player[i].playerid) );
                        text_insert_message(tmp, strlen(tmp) );
                        g_free(tmp);
                  }
            }

            if( (playerid = get_playerid_by_playername(msg))  > 0)  {

                  pslot = get_player_slot_with_playerid(playerid);

                  tmp = g_strdup_printf("<%s> %d", global->player[pslot].name, game_get_assets_player(global->player[pslot].playerid) );
                  text_insert_message(tmp, strlen(tmp) );
                  g_free(tmp);
            }
      }


      else if(! strncmp(msg, "nick", 4))  {

            msg += 4;
            while( strlen(msg) )  {

                  if(msg[0] != ' ') break;
                  else  msg++;
            }

            if(strlen(msg) != 0  &&  strcmp(global->player[ get_player_slot_with_playerid(game->my_playerid) ].name, msg) )  {

                  tmp = g_strdup_printf(".n%s\n", msg);
                  client_send(game->connectid, tmp, strlen(tmp));
                  g_free(tmp);
            }
      }


      else if(! strncmp(msg, "date", 4))  {

            gettimeofday(&tv, NULL);
            t_now = tv.tv_sec;

            tmp = g_strdup_printf("%s", ctime(&t_now) );
            for(i = 0 ; i < strlen(tmp) ; i++)  {

                  if(tmp[i] == '\n')  {
                        tmp[i] = '\0';
                        break;
                  }
            }
            text_insert_message(tmp, strlen(tmp) );
            g_free(tmp);
      }


      else if(! strncmp(msg, "elapsed", 7))  {

            if(game->status >= GAME_STATUS_RUN)  {

                  gettimeofday(&tv, NULL);
                  t_now = tv.tv_sec - game->start_time;
            }
            else  t_now = 0;

            local_tm = gmtime(&t_now);

            tmp = g_strdup_printf("%.2d:%.2d:%.2d", local_tm->tm_hour, local_tm->tm_min, local_tm->tm_sec);
            text_insert_message(tmp, strlen(tmp) );
            g_free(tmp);
      }

      else if(! strncmp(msg, "me", 2))  {

            msg += 2;
            while( strlen(msg) )  {

                  if(msg[0] != ' ') break;
                  else  msg++;
            }

            if(strlen(msg) != 0)  {

                  tmp = g_strdup_printf("[ACTION] %s\n", msg);
                  client_send(game->connectid, tmp, strlen(tmp));
                  g_free(tmp);
            }
      }
}


/* sort playerlist by playerid (ascending) */
void game_sort_playerlist_by_playerid()  {

      guint32 i, j;
      _player playertmp;

      for(i = 0 ; i < MAX_PLAYERS ; i++)  {

            if(! global->player[i].playerid) continue;

            for(j = i+1 ; j < MAX_PLAYERS ; j++)  {

                  if(! global->player[j].playerid) continue;

                  if(global->player[j].playerid < global->player[i].playerid)  {

                        memcpy(&playertmp, &global->player[i], sizeof(_player) );
                        memcpy(&global->player[i], &global->player[j], sizeof(_player) );
                        memcpy(&global->player[j], &playertmp, sizeof(_player) );
                  }
            }
      }
}


/* write cookie on disk */
void game_write_cookie(guchar *cookie)  {

      guchar *filename, *errormsg;
      FILE *file;

      filename = g_strconcat(global->path_home, "cookie", NULL);

      file = fopen(filename, "wt");
      if(!file)  {
            errormsg = g_strdup_printf("[ERROR] Can't write cookie file at \"%s\"", filename);
            text_insert_message(errormsg, strlen(errormsg));
            g_free(errormsg);
            g_free(filename);
            return;
      }

      fprintf(file, "%s\n", connection[ game->connectid ]->host );
      fprintf(file, "%d\n", connection[ game->connectid ]->port );
      fprintf(file, "%s\n", cookie);

      g_free(filename);
      fclose(file);
}


/* return a valid card slotid */
gboolean game_get_valid_card_slot(guint8 *cardslot)  {

      guint8 i;

      for(i = 0; i < MAX_CARDS ; i++)
            if(!game->card[i].owner) {

                  *cardslot = i;
                  return TRUE;
            }

      return FALSE;
}


/* return the card slot by cardid */
gint8 get_card_slot_with_cardid(guint32 cardid)  {

      guint32 i;

      for(i = 0 ; i < MAX_CARDS ; i++)  {

            if(game->card[i].cardid == cardid) {

                  return(i);
                  break;
            }
      }

      return(-1);
}


/* return player identifier by name of this player */
gint32 get_playerid_by_playername(guchar *name)  {

      guint32 i;

      if(!name) return(-1);
      if(strlen(name) <= 0) return(-1);

      for(i = 0 ; i < MAX_PLAYERS ; i++)  {

            if(! global->player[i].playerid)  continue;

            if(! strcmp(global->player[i].name, name) )  {

                  return( global->player[i].playerid );
                  break;
            }
      }

      return(-1);
}


/* return a valid trade slotid */
gboolean game_get_valid_trade_slot(guint32 *tradeslot)  {

      guint32 i;

      for(i = 0; i < MAX_TRADES ; i++)
            if(! game->trade[i].open) {

                  *tradeslot = i;
                  return TRUE;
            }

      return FALSE;
}


/* return trade slot by tradeid */
gint32 get_trade_slot_with_tradeid(guint32 tradeid)  {

      guint32 i;

      for(i = 0 ; i < MAX_TRADES ; i++)  {

            if(! game->trade[i].open) continue;

            if(game->trade[i].tradeid == tradeid) {

                  return(i);
                  break;
            }
      }

      return(-1);
}



/* return estate identifier by name of this estate */
gint32 get_estateid_by_estatename(guchar *name)  {

      guint32 i;

      for(i = 0 ; i < data->number_estates ; i++)  {

            if(! strcmp(game->estate[i].name, name) )  {

                  return(i);
                  break;
            }
      }

      return(-1);
}


/* build player list in game config phase */
void game_buildplayerlist()   {

      guint32 i;
      gint32 row;
      gchar *txt[10];

      game_sort_playerlist_by_playerid();

      /* build player list */
      if(global->phase == PHASE_GAMECREATE)  {

            gtk_clist_freeze(GTK_CLIST(game->PlayerCList));
            gtk_clist_clear(GTK_CLIST(game->PlayerCList));

            for(i = 0 ; i < MAX_PLAYERS ; i++)  {

                  if(global->player[i].playerid && global->player[i].game == game->gameid)  {

                        txt[0] = global->player[i].name;
                        txt[1] = global->player[i].host;
                        row = gtk_clist_append(GTK_CLIST(game->PlayerCList), txt);
                        gtk_clist_set_selectable(GTK_CLIST(game->PlayerCList), row ,FALSE);
                  }
            }

            gtk_clist_thaw(GTK_CLIST(game->PlayerCList));
      }
}


/* return assets of a player,
 *   assets is: money + sale price of houses + unmortgaged value of estates
 */
gint32 game_get_assets_player(guint32 playerid)  {

      guint32 i;
      gint32 pslot, assets;

      pslot = get_player_slot_with_playerid( playerid );
      if(pslot < 0)  return 0;

      /* money */
      assets = global->player[pslot].money;

      /* estates + houses */
      for(i = 0 ; i < data->number_estates ; i++)  {

            if(game->estate[i].owner != playerid)  continue;

            /* estates */
            if(! game->estate[i].mortgaged)
                  assets += game->estate[i].mortgageprice;

            /* houses */
            if(game->estate[i].houses <= 0)  continue;

            assets += game->estate[i].houses * game->estate[i].sellhouseprice;
      }

      return assets;
}


/* update token position, handle superposed token */
void game_update_tokens()  {

      gint32 i, j, nb_tokens, x1, y1, x2, y2, xs, ys, xp, yp, pp, k;


      /* === UNJAILED === */

      for(i = 0 ; i < data->number_estates ; i++)  {

            /* search number of unjailed tokens on this estate */
            for(j = 0, nb_tokens = 0 ; j < MAX_PLAYERS ; j++)  {

                  if(! global->player[j].playerid)  continue;
                  if(global->player[j].game != game->gameid)  continue;
                  if(global->player[j].bankrupt)  continue;
                  if(global->player[j].jailed) continue;
                  if(global->player[j].location != i)  continue;

                  nb_tokens++;
            }

            /* move token */
            if(nb_tokens == 0)  continue;

            for(j = 0, k = 0, xp = -1, yp = -1, pp = -1 ; j < MAX_PLAYERS ; j++)  {

                  if(! global->player[j].playerid)  continue;
                  if(global->player[j].game != game->gameid)  continue;
                  if(global->player[j].bankrupt)  continue;
                  if(global->player[j].jailed) continue;
                  if(global->player[j].location != i)  continue;

                  x1 = data->estate[ global->player[j].location ].x1token;
                  x2 = data->estate[ global->player[j].location ].x2token;
                  y1 = data->estate[ global->player[j].location ].y1token;
                  y2 = data->estate[ global->player[j].location ].y2token;

                  if(nb_tokens == 1)  {

                        pic_set_x(game->board_frame, global->player[j].token_pic, x1);
                        pic_set_y(game->board_frame, global->player[j].token_pic, y1);

                        break;
                  }

                  xs = ( ( (x2 - x1) * k) / (nb_tokens -1) ) + x1;
                  if(pp >= 0  &&  abs(xs - xp) > (data->pngfile_token_width[ global->player[pp].buffer_token ] + 2) ) {

                        if(xs - xp > 0)
                              xs = xp + data->pngfile_token_width[ global->player[pp].buffer_token ] + 2;
                        else
                              xs = xp - data->pngfile_token_width[ global->player[pp].buffer_token ] - 2;
                  }

                  ys = ( ( (y2 - y1) * k) / (nb_tokens -1) ) + y1;
                  if(pp >= 0  &&  abs(ys - yp) > (data->pngfile_token_height[ global->player[pp].buffer_token ] + 2) ) {

                        if(ys - yp > 0)
                              ys = yp + data->pngfile_token_height[ global->player[pp].buffer_token ] + 2;
                        else
                              ys = yp - data->pngfile_token_height[ global->player[pp].buffer_token ] - 2;
                  }

                  pic_set_x(game->board_frame, global->player[j].token_pic, xs);
                  pic_set_y(game->board_frame, global->player[j].token_pic, ys);

                  xp = xs;
                  yp = ys;
                  pp = j;

                  k++;
            }
      }


      /* === JAILED === */

      for(i = 0 ; i < data->number_estates ; i++)  {

            /* search number of jailed tokens on this estate */
            for(j = 0, nb_tokens = 0 ; j < MAX_PLAYERS ; j++)  {

                  if(! global->player[j].playerid)  continue;
                  if(global->player[j].game != game->gameid)  continue;
                  if(global->player[j].bankrupt)  continue;
                  if(! global->player[j].jailed) continue;
                  if(global->player[j].location != i)  continue;

                  nb_tokens++;
            }

            /* move token */
            if(nb_tokens == 0)  continue;

            for(j = 0, k = 0, xp = -1, yp = -1, pp = -1 ; j < MAX_PLAYERS ; j++)  {

                  if(! global->player[j].playerid)  continue;
                  if(global->player[j].game != game->gameid)  continue;
                  if(global->player[j].bankrupt)  continue;
                  if(! global->player[j].jailed) continue;
                  if(global->player[j].location != i)  continue;

                  x1 = data->estate[ global->player[j].location ].x1jail;
                  x2 = data->estate[ global->player[j].location ].x2jail;
                  y1 = data->estate[ global->player[j].location ].y1jail;
                  y2 = data->estate[ global->player[j].location ].y2jail;

                  if(nb_tokens == 1)  {

                        pic_set_x(game->board_frame, global->player[j].token_pic, x1);
                        pic_set_y(game->board_frame, global->player[j].token_pic, y1);

                        break;
                  }

                  xs = ( ( (x2 - x1) * k) / (nb_tokens -1) ) + x1;
                  if(pp >= 0  &&  abs(xs - xp) > (data->pngfile_token_width[ global->player[pp].buffer_token ] + 2) ) {

                        if(xs - xp > 0)
                              xs = xp + data->pngfile_token_width[ global->player[pp].buffer_token ] + 2;
                        else
                              xs = xp - data->pngfile_token_width[ global->player[pp].buffer_token ] - 2;
                  }

                  ys = ( ( (y2 - y1) * k) / (nb_tokens -1) ) + y1;
                  if(pp >= 0  &&  abs(ys - yp) > (data->pngfile_token_height[ global->player[pp].buffer_token ] + 2) ) {

                        if(ys - yp > 0)
                              ys = yp + data->pngfile_token_height[ global->player[pp].buffer_token ] + 2;
                        else
                              ys = yp - data->pngfile_token_height[ global->player[pp].buffer_token ] - 2;
                  }

                  pic_set_x(game->board_frame, global->player[j].token_pic, xs);
                  pic_set_y(game->board_frame, global->player[j].token_pic, ys);

                  xp = xs;
                  yp = ys;
                  pp = j;

                  k++;
            }
      }

}


/* start token movement */
void game_start_move_token(guint32 playerid)  {

      guchar *sendstr;
      gint32 pslot;

      pslot = get_player_slot_with_playerid(playerid);
      if(pslot < 0)  return;

      if(global->player[pslot].directmove)  {

            global->player[pslot].location = global->player[pslot].location_to;
            sendstr = g_strdup_printf(".t%d\n", global->player[pslot].location);
            client_send(game->connectid, sendstr, strlen(sendstr));
            g_free(sendstr);
      }

      game_update_tokens();

      return;
}


/* animate move token */
gboolean game_move_tokens()  {

      guint32 i;
      guchar *sendstr;
      gboolean update = 0;

      for(i = 0 ; i < MAX_PLAYERS ; i++)  {

            if(! global->player[i].playerid)  continue;
            if(global->player[i].game != game->gameid)  continue;
            if(global->player[i].location == global->player[i].location_to)  continue;

            global->player[i].location++;
            if(global->player[i].location >= data->number_estates)
                  global->player[i].location = 0;

            sendstr = g_strdup_printf(".t%d\n", global->player[i].location);
            client_send(game->connectid, sendstr, strlen(sendstr));
            g_free(sendstr);

            update = TRUE;
      }

      if(update)  game_update_tokens();

      return TRUE;
}


void game_delete_player(guint32 id)  {

      /* delete a player */
      if(global->player[id].name) g_free(global->player[id].name);
      if(global->player[id].host) g_free(global->player[id].host);
      if(global->player[id].image) g_free(global->player[id].image);
      memset(&global->player[id], 0, sizeof(_player) );
      game->nb_players--;
}

Generated by  Doxygen 1.6.0   Back to index