/********************************************************************/ /* */ /* L I QQ U U I DD W W A RR 555 */ /* L I Q Q U U I D D W W A A R R 5 */ /* L I Q Q U U I D D W W W AAA RR 55 */ /* L I Q Q U U I D D WW WW A A R R 5 */ /* LLL I Q Q U I DD W W A A R R 55 */ /* */ /* b */ /* bb y y */ /* b b yyy */ /* bb y */ /* yy */ /* */ /* U U FFF O O TTT */ /* U U F O O O O T */ /* U U TIRET FF O O O O T */ /* U U F O O O O T */ /* U F O O T */ /* */ /********************************************************************/ /*****************************************************************************/ /* Liquid War is a multiplayer wargame */ /* Copyright (C) 1998-2007 Christian Mauduit */ /* */ /* This program 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* */ /* Liquid War homepage : http://www.ufoot.org/liquidwar/v5 */ /* Contact author : ufoot@ufoot.org */ /*****************************************************************************/ /********************************************************************/ /* name : network.c */ /* content : various network related stuff */ /* last update : may 8th 2001 */ /********************************************************************/ /*==================================================================*/ /* includes */ /*==================================================================*/ #include #include #include "network.h" #include "config.h" /*==================================================================*/ /* constants */ /*==================================================================*/ #define LW_NETWORK_COLOR_NB 12 #define LW_NETWORK_COLOR_DIST_MAXINT 1000000 #define LW_NETWORK_COLOR_DIST_SCALE 1000 /*==================================================================*/ /* globals */ /*==================================================================*/ int LW_NETWORK_ON = 0; LW_WHO LW_NETWORK_INFO[NB_TEAMS]; int LW_NETWORK_ERROR_DETECTED = 0; void *LW_NETWORK_RAW_MAP = NULL; /*==================================================================*/ /* static funcs */ /*==================================================================*/ /*==================================================================*/ /* functions */ /*==================================================================*/ /*------------------------------------------------------------------*/ /* * Returns the "distance" of 2 colors. For 2 adjacent which look * about the sane, it is 1. For radicaly different colors, it is * 6. If the colors are the same, it is 0. */ int distance_between_colors (int col1, int col2) { int dist; if (col1 < 0 || col2 < 0) { /* * Now if one of the member was -1, we * consider the colors are "far" * from each other. */ dist = 6; } else { dist = abs (col1 - col2); } if (dist > LW_NETWORK_COLOR_NB) { /* * Normally we should never get here... */ dist = LW_NETWORK_COLOR_NB / 2; } if (dist > LW_NETWORK_COLOR_NB / 2) { dist = LW_NETWORK_COLOR_NB - dist; } return dist; } /*------------------------------------------------------------------*/ /* * Calculates the "most different color", considering the colors * already chosen in LW_NETWORK_INFO. */ int choose_different_color () { int color; int closeness[LW_NETWORK_COLOR_NB]; int closeness_min; int dist; int i, j; /* * We calculate the "closeness" of each color */ for (i = 0; i < LW_NETWORK_COLOR_NB; ++i) { closeness[i] = 0; for (j = 0; j < NB_TEAMS; ++j) { if (LW_NETWORK_INFO[j].active) { dist = distance_between_colors (LW_NETWORK_INFO[j].color, i); if (dist > 0) { if (LW_NETWORK_INFO[j].network) { /* * We consider network color conflicts * to be less important than conflicts with * local colors, therefore we increase the * distance for network teams. */ dist++; } closeness[i] += LW_NETWORK_COLOR_DIST_SCALE / (dist * dist); } else { closeness[i] = LW_NETWORK_COLOR_DIST_MAXINT; } } } } /* * And now we pick up the one that has the less common points * with existing colors. */ closeness_min = LW_NETWORK_COLOR_DIST_MAXINT; color = 0; for (i = 0; i < LW_NETWORK_COLOR_NB; ++i) { if (closeness[i] < closeness_min) { color = i; closeness_min = closeness[i]; } } return color; } /*------------------------------------------------------------------*/ /* * Associates a color to each team */ void lw_network_attribute_colors () { int i, color; for (i = 0; i < NB_TEAMS; ++i) { if (LW_NETWORK_INFO[i].active) { if (LW_NETWORK_INFO[i].network) { /* * -1 is a temporary value which will be overwritten * by the _real_ value later */ LW_NETWORK_INFO[i].color = -1; } else { LW_NETWORK_INFO[i].color = CONFIG_TEAM_COLOR[i]; } } } for (i = 0; i < NB_TEAMS; ++i) { if (LW_NETWORK_INFO[i].active && LW_NETWORK_INFO[i].network) { color = choose_different_color (); LW_NETWORK_INFO[i].color = color; } } } /*------------------------------------------------------------------*/ /* * Associates a part to each team */ void lw_network_attribute_parts () { int i; static int order[NB_TEAMS] = { 0, 5, 2, 3, 1, 4 }; for (i = 0; i < NB_TEAMS; ++i) { if (LW_NETWORK_INFO[i].active) { LW_NETWORK_INFO[i].part = order[LW_NETWORK_INFO[i].server_id]; } } }