home *** CD-ROM | disk | FTP | other *** search
/ Amiga Times / AmigaTimes.iso / spiele / FreeCiv / src / freeciv-1.7.0 / server / maphand.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-06  |  13.4 KB  |  493 lines

  1. /********************************************************************** 
  2.  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2, or (at your option)
  6.    any later version.
  7.  
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12. ***********************************************************************/
  13. #include <string.h>
  14. #include <map.h>
  15. #include <game.h>
  16. #include <maphand.h>
  17. #include <packets.h>
  18. #include <unitfunc.h>
  19. #include <cityhand.h>
  20. #include <mapgen.h>
  21. #include <stdlib.h>
  22. #include <log.h>
  23. #include <ctype.h>
  24.  
  25. char terrain_chars[]="adfghjm prst";
  26. char dec2hex[]="0123456789abcdef";
  27.  
  28.  
  29. /**************************************************************************
  30. ...
  31. **************************************************************************/
  32. void global_warming(int effect)
  33. {
  34.   int x, y;
  35.   int k=map.xsize*map.ysize;
  36.   while(effect && k--) {
  37.     x=myrand(map.xsize);
  38.     y=myrand(map.ysize);
  39.     if (map_get_terrain(x, y)!=T_OCEAN) {
  40.       if(is_water_adjacent(x, y)) {
  41.     switch (map_get_terrain(x, y)) {
  42.     case T_FOREST:
  43.       effect--;
  44.       map_set_terrain(x, y, T_JUNGLE);
  45.           reset_move_costs(x, y);
  46.           relight_square_if_known(0, x, y);
  47.       break;
  48.     case T_DESERT:
  49.     case T_PLAINS:
  50.     case T_GRASSLAND:
  51.       effect--;
  52.       map_set_terrain(x, y, T_SWAMP);
  53.           reset_move_costs(x, y);
  54.           relight_square_if_known(0, x, y);
  55.       break;
  56.     default:
  57.       break;
  58.     }
  59.       } else {
  60.     switch (map_get_terrain(x, y)) {
  61.     case T_PLAINS:
  62.     case T_GRASSLAND:
  63.     case T_FOREST:
  64.       effect--;
  65.       map_set_terrain(x, y, T_DESERT);
  66.           reset_move_costs(x, y);
  67.           relight_square_if_known(0, x, y);
  68.       break;
  69.     default:
  70.       break;
  71.     }
  72.       }
  73.     }
  74.   }
  75. }
  76.  
  77. /**************************************************************************
  78. ...
  79. **************************************************************************/
  80. void give_map_from_player_to_player(struct player *pfrom, struct player *pdest)
  81. {
  82.   int x, y;
  83.  
  84.   for(y=0; y<map.ysize; y++)
  85.     for(x=0; x<map.xsize; x++)
  86.       if(map_get_known(x, y, pfrom) && !map_get_known(x, y, pdest)) {
  87.     light_square(pdest, x, y, 0);
  88.       }
  89. }
  90.  
  91. /**************************************************************************
  92. ...
  93. **************************************************************************/
  94. void give_seamap_from_player_to_player(struct player *pfrom, struct player *pdest)
  95. {
  96.   int x, y;
  97.  
  98.   for(y=0; y<map.ysize; y++)
  99.     for(x=0; x<map.xsize; x++)
  100.       if(map_get_known(x, y, pfrom) && !map_get_known(x, y, pdest) &&
  101.      map_get_terrain(x, y)==T_OCEAN) {
  102.     light_square(pdest, x, y, 0);
  103.       }
  104. }
  105.  
  106. /**************************************************************************
  107. dest can be NULL meaning all players
  108. **************************************************************************/
  109. void send_all_known_tiles(struct player *dest)
  110. {
  111.   int o;
  112.  
  113.   for(o=0; o<game.nplayers; o++)           /* dests */
  114.     if(!dest || &game.players[o]==dest) {
  115.       int x, y;
  116.       struct player *pplayer=&game.players[o];
  117.       
  118.       connection_do_buffer(pplayer->conn);
  119.       for(y=0; y<map.ysize; y++)
  120.         for(x=0; x<map.xsize; x++)
  121.           if(map_get_known(x, y, pplayer)) {
  122.             map_clear_known(x, y, pplayer);
  123.             light_square(pplayer, x, y, 0);
  124.           }
  125.       connection_do_unbuffer(pplayer->conn);
  126.     }
  127. }
  128.  
  129. /**************************************************************************
  130. dest can be NULL meaning all players
  131. if(dest==NULL) only_send_tile_info_to_client_that_know_the_tile()
  132. else send_tile_info
  133. notice: the tile isn't lighten up on the client by this func
  134. **************************************************************************/
  135. void send_tile_info(struct player *dest, int x, int y, enum known_type type)
  136. {
  137.   int o;
  138.   struct packet_tile_info info;
  139.   struct tile *ptile;
  140.  
  141.   ptile=map_get_tile(x, y);
  142.  
  143.   info.x=x;
  144.   info.y=y;
  145.   info.type=ptile->terrain;
  146.   info.special=ptile->special;
  147.  
  148.   for(o=0; o<game.nplayers; o++)           /* dests */
  149.      if(!dest) {
  150.        if(ptile->known & (1<<o)) {
  151.      info.known=TILE_KNOWN;
  152.      send_packet_tile_info(game.players[o].conn, &info);
  153.        }
  154.      }
  155.      else if(&game.players[o]==dest) {
  156.        info.known=type;
  157.        send_packet_tile_info(game.players[o].conn, &info);
  158.      }
  159. }
  160.  
  161. /**************************************************************************
  162. ...
  163. **************************************************************************/
  164. void relight_square_if_known(struct player *pplayer, int x, int y)
  165. {
  166.   int o;
  167.   for(o=0; o<game.nplayers; o++) {
  168.     struct player *pplayer=&game.players[o];
  169.     if(map_get_known(x, y, pplayer)) {
  170.       connection_do_buffer(pplayer->conn);
  171.       map_clear_known(x, y, pplayer);
  172.       light_square(pplayer, x, y, 0);
  173.       connection_do_unbuffer(pplayer->conn);
  174.     }
  175.   }
  176. }
  177.  
  178. /**************************************************************************
  179. ...
  180. **************************************************************************/
  181. void light_square(struct player *pplayer, int x, int y, int len)
  182. {
  183.   int dx, dy;
  184.   static int known_count=TILE_KNOWN;
  185.   
  186.   known_count++;
  187.   if(known_count>255) known_count=TILE_KNOWN+1;
  188.  
  189.   connection_do_buffer(pplayer->conn);
  190.   for(dy=-len-1; dy<=len+1; ++dy)
  191.     for(dx=-len-1; dx<=len+1; ++dx) {
  192.       int abs_x=map_adjust_x(x+dx);
  193.       int abs_y=map_adjust_y(y+dy);
  194.       if(!map_get_known(abs_x, abs_y, pplayer)) {
  195.     if(dx>=-len && dx<=len && dy>=-len && dy<=len)
  196.       send_tile_info(pplayer, abs_x, abs_y, TILE_KNOWN_NODRAW);
  197.     else
  198.       send_tile_info(pplayer, abs_x, abs_y, TILE_UNKNOWN);
  199.       }
  200.     }
  201.  
  202.   for(dy=-len; dy<=len; ++dy)
  203.     for(dx=-len; dx<=len; ++dx) {
  204.       int abs_x=map_adjust_x(x+dx);
  205.       int abs_y=map_adjust_y(y+dy);
  206.       if(!map_get_known(abs_x, abs_y, pplayer)) {
  207.     unit_list_iterate(map_get_tile(abs_x, abs_y)->units, punit)
  208.       send_unit_info(pplayer, punit, 1);
  209.         unit_list_iterate_end;
  210.       }
  211.     }
  212.     
  213.   
  214.   for(dy=-len; dy<=len; ++dy)
  215.     for(dx=-len; dx<=len; ++dx) {
  216.       int abs_x=map_adjust_x(x+dx);
  217.       int abs_y=map_adjust_y(y+dy);
  218.       if(!map_get_known(abs_x, abs_y, pplayer)) {
  219.     struct city *pcity;
  220.     
  221.     if((pcity=map_get_city(abs_x, abs_y))) {
  222.       send_city_info(pplayer, pcity, 1);
  223.     }
  224.       }
  225.     }
  226.   
  227.   for(dy=-len; dy<=len; ++dy)
  228.     for(dx=-len; dx<=len; ++dx) {
  229.       int abs_x=map_adjust_x(x+dx);
  230.       int abs_y=map_adjust_y(y+dy);
  231.  
  232.       if(!map_get_known(abs_x, abs_y, pplayer)) {
  233.     map_set_known(abs_x, abs_y, pplayer);
  234.     send_tile_info(pplayer, abs_x, abs_y, known_count);
  235.       }
  236.     }
  237.   connection_do_unbuffer(pplayer->conn);
  238. }
  239.  
  240. /**************************************************************************
  241. ...
  242. **************************************************************************/
  243. void lighten_area(struct player *pplayer, int x, int y)
  244. {
  245.   connection_do_buffer(pplayer->conn);
  246.  
  247.   light_square(pplayer, x, y, 1);
  248.   
  249.   connection_do_unbuffer(pplayer->conn);
  250. }
  251.  
  252. /**************************************************************************
  253. ...
  254. **************************************************************************/
  255. void send_map_info(struct player *dest)
  256. {
  257.   int o;
  258.   struct packet_map_info minfo;
  259.  
  260.   minfo.xsize=map.xsize;
  261.   minfo.ysize=map.ysize;
  262.   minfo.is_earth=map.is_earth;
  263.  
  264.   for(o=0; o<game.nplayers; o++)           /* dests */
  265.     if(!dest || &game.players[o]==dest) {
  266.       struct player *pplayer=&game.players[o];
  267.       send_packet_map_info(pplayer->conn, &minfo);
  268.     }
  269. }
  270.  
  271. /***************************************************************
  272. ...
  273. ***************************************************************/
  274. void map_save(struct section_file *file)
  275. {
  276.   int i, x, y;
  277.   char *pbuf=(char *)malloc(map.xsize+1);
  278.  
  279.   secfile_insert_int(file, map.xsize, "map.width");
  280.   secfile_insert_int(file, map.ysize, "map.height");
  281.   secfile_insert_int(file, map.is_earth, "map.is_earth");
  282.  
  283.   for(i=0; i<R_LAST; i++) {
  284.     secfile_insert_int(file, map.start_positions[i].x, "map.r%dsx", i);
  285.     secfile_insert_int(file, map.start_positions[i].y, "map.r%dsy", i);
  286.   }
  287.     
  288.   /* put the terrain type */
  289.   for(y=0; y<map.ysize; y++) {
  290.     for(x=0; x<map.xsize; x++)
  291.       pbuf[x]=terrain_chars[map_get_tile(x, y)->terrain];
  292.     pbuf[x]='\0';
  293.  
  294.     secfile_insert_str(file, pbuf, "map.t%03d", y);
  295.   }
  296.  
  297.   /* get lower 4 bits of special flags */
  298.   for(y=0; y<map.ysize; y++) {
  299.     for(x=0; x<map.xsize; x++)
  300.       pbuf[x]=dec2hex[map_get_tile(x, y)->special&0xf];
  301.     pbuf[x]='\0';
  302.  
  303.     secfile_insert_str(file, pbuf, "map.l%03d", y);
  304.   }
  305.  
  306.  
  307.   /* put upper 4 bits of special flags */
  308.   for(y=0; y<map.ysize; y++) {
  309.     for(x=0; x<map.xsize; x++)
  310.       pbuf[x]=dec2hex[(map_get_tile(x, y)->special&0xf0)>>4];
  311.     pbuf[x]='\0';
  312.  
  313.     secfile_insert_str(file, pbuf, "map.u%03d", y);
  314.   }
  315.  
  316.   /* put bit 0-3 of known bits */
  317.   for(y=0; y<map.ysize; y++) {
  318.     for(x=0; x<map.xsize; x++)
  319.       pbuf[x]=dec2hex[(map_get_tile(x, y)->known&0xf)];
  320.     pbuf[x]='\0';
  321.     secfile_insert_str(file, pbuf, "map.a%03d", y);
  322.   }
  323.  
  324.   /* put bit 4-7 of known bits */
  325.   for(y=0; y<map.ysize; y++) {
  326.     for(x=0; x<map.xsize; x++)
  327.       pbuf[x]=dec2hex[((map_get_tile(x, y)->known&0xf0))>>4];
  328.     pbuf[x]='\0';
  329.     secfile_insert_str(file, pbuf, "map.b%03d", y);
  330.   }
  331.  
  332.   /* put bit 8-11 of known bits */
  333.   for(y=0; y<map.ysize; y++) {
  334.     for(x=0; x<map.xsize; x++)
  335.       pbuf[x]=dec2hex[((map_get_tile(x, y)->known&0xf00))>>8];
  336.     pbuf[x]='\0';
  337.     secfile_insert_str(file, pbuf, "map.c%03d", y);
  338.   }
  339.  
  340.   /* put bit 12-15 of known bits */
  341.   for(y=0; y<map.ysize; y++) {
  342.     for(x=0; x<map.xsize; x++)
  343.       pbuf[x]=dec2hex[((map_get_tile(x, y)->known&0xf000))>>12];
  344.     pbuf[x]='\0';
  345.     secfile_insert_str(file, pbuf, "map.d%03d", y);
  346.   }
  347.   
  348.   free(pbuf);
  349. }
  350.  
  351. /***************************************************************
  352. ...
  353. ***************************************************************/
  354. void map_load(struct section_file *file)
  355. {
  356.   int i, x ,y;
  357.  
  358.   map_init();
  359.  
  360.   map.xsize=secfile_lookup_int(file, "map.width");
  361.   map.ysize=secfile_lookup_int(file, "map.height");
  362.   map.is_earth=secfile_lookup_int(file, "map.is_earth");
  363.  
  364.   for(i=0; i<R_LAST; i++) {
  365.     map.start_positions[i].x=secfile_lookup_int(file, "map.r%dsx", i);
  366.     map.start_positions[i].y=secfile_lookup_int(file, "map.r%dsy", i);
  367.   }
  368.   
  369.   if(!(map.tiles=(struct tile*)malloc(map.xsize*map.ysize*
  370.                      sizeof(struct tile)))) {
  371.     log(LOG_FATAL, "malloc failed in load_map");
  372.     exit(1);
  373.   }
  374.  
  375.   for(y=0; y<map.ysize; y++)
  376.     for(x=0; x<map.xsize; x++)
  377.       tile_init(map_get_tile(x, y));
  378.  
  379.  
  380.   /* get the terrain type */
  381.   for(y=0; y<map.ysize; y++) {
  382.     char *terline=secfile_lookup_str(file, "map.t%03d", y);
  383.     for(x=0; x<map.xsize; x++) {
  384.       char *pch;
  385.       if(!(pch=strchr(terrain_chars, terline[x]))) {
  386.     log(LOG_FATAL, "unknown terrain type in map at position (%d,%d)",
  387.         x, y, terline[x]);
  388.     exit(1);
  389.       }
  390.       map_get_tile(x, y)->terrain=pch-terrain_chars;
  391.     }
  392.   }
  393.  
  394.   /* get lower 4 bits of special flags */
  395.   for(y=0; y<map.ysize; y++) {
  396.     char *terline=secfile_lookup_str(file, "map.l%03d", y);
  397.  
  398.     for(x=0; x<map.xsize; x++) {
  399.       char ch=terline[x];
  400.  
  401.       if(isxdigit(ch))
  402.     map_get_tile(x, y)->special=ch-(isdigit(ch) ? '0' : ('a'-10));
  403.       else if(ch!=' ') {
  404.     log(LOG_FATAL, "unknown special flag(lower) in map at position(%d,%d)",
  405.         x, y, ch);
  406.     exit(1);
  407.       }
  408.       else
  409.     map_get_tile(x, y)->special=S_NONE;
  410.     }
  411.   }
  412.  
  413.   /* get upper 4 bits of special flags */
  414.   for(y=0; y<map.ysize; y++) {
  415.     char *terline=secfile_lookup_str(file, "map.u%03d", y);
  416.  
  417.     for(x=0; x<map.xsize; x++) {
  418.       char ch=terline[x];
  419.  
  420.       if(isxdigit(ch))
  421.     map_get_tile(x, y)->special|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<4;
  422.       else if(ch!=' ') {
  423.     log(LOG_FATAL, "unknown special flag(lower) in map at position(%d,%d)",
  424.         x, y, ch);
  425.     exit(1);
  426.       }
  427.     }
  428.   }
  429.  
  430.   /* get bits 0-3 of known flags */
  431.   for(y=0; y<map.ysize; y++) {
  432.     char *terline=secfile_lookup_str(file, "map.a%03d", y);
  433.     for(x=0; x<map.xsize; x++) {
  434.       char ch=terline[x];
  435.       if(isxdigit(ch))
  436.     map_get_tile(x, y)->known=ch-(isdigit(ch) ? '0' : ('a'-10));
  437.       else if(ch!=' ') {
  438.     log(LOG_FATAL, "unknown known flag(lower) in map at position(%d,%d)",
  439.         x, y, ch);
  440.     exit(1);
  441.       }
  442.       else
  443.     map_get_tile(x, y)->known=0;
  444.     }
  445.   }
  446.  
  447.   /* get bits 4-7 of known flags */
  448.   for(y=0; y<map.ysize; y++) {
  449.     char *terline=secfile_lookup_str(file, "map.b%03d", y);
  450.     for(x=0; x<map.xsize; x++) {
  451.       char ch=terline[x];
  452.       if(isxdigit(ch))
  453.     map_get_tile(x, y)->known|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<4;
  454.       else if(ch!=' ') {
  455.     log(LOG_FATAL, "unknown known flag(lower) in map at position(%d,%d)",
  456.         x, y, ch);
  457.     exit(1);
  458.       }
  459.     }
  460.   }
  461.  
  462.   /* get bits 8-11 of known flags */
  463.   for(y=0; y<map.ysize; y++) {
  464.     char *terline=secfile_lookup_str(file, "map.c%03d", y);
  465.     for(x=0; x<map.xsize; x++) {
  466.       char ch=terline[x];
  467.       if(isxdigit(ch))
  468.     map_get_tile(x, y)->known|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<8;
  469.       else if(ch!=' ') {
  470.     log(LOG_FATAL, "unknown known flag(lower) in map at position(%d,%d)",
  471.         x, y, ch);
  472.     exit(1);
  473.       }
  474.     }
  475.   }
  476.  
  477.   /* get bits 12-15 of known flags */
  478.   for(y=0; y<map.ysize; y++) {
  479.     char *terline=secfile_lookup_str(file, "map.d%03d", y);
  480.     for(x=0; x<map.xsize; x++) {
  481.       char ch=terline[x];
  482.  
  483.       if(isxdigit(ch))
  484.     map_get_tile(x, y)->known|=(ch-(isdigit(ch) ? '0' : 'a'-10))<<12;
  485.       else if(ch!=' ') {
  486.     log(LOG_FATAL, "unknown known flag(lower) in map at position(%d,%d)",
  487.         x, y, ch);
  488.     exit(1);
  489.       }
  490.     }
  491.   }
  492. }
  493.