home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume13 / dominion / part26 / user.c < prev    next >
C/C++ Source or Header  |  1992-02-11  |  10KB  |  346 lines

  1. /* user.c -- stuff relating to the "current user" */
  2.  
  3. /*
  4.  * Copyright (C) 1990 Free Software Foundation, Inc.
  5.  * Written by the dominion project.
  6.  *
  7.  * This file is part of dominion.
  8.  *
  9.  * dominion is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License as published
  11.  * by the Free Software Foundation; either version 1, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This software is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this software; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. #include <stdio.h>
  25. #ifdef SYSV
  26. # include <string.h>
  27. #else
  28. # include <strings.h>
  29. #endif /* SYSV */
  30. #include <time.h>
  31.  
  32. #include "dominion.h"
  33. #include "misc.h"
  34.  
  35. extern Suser user;
  36. extern Sworld world;
  37. extern int debug;
  38. extern int (*wrapx)(), (*wrapy)();
  39. extern int viewall;
  40. extern double get_version(),atof();
  41. extern char *update_time, *get_update_time(), *mail_forwarding(),*civ_move[];
  42.  
  43. void usageerr(argc, argv)
  44. int argc;
  45. char *argv[]; 
  46. {
  47.   fprintf(stderr, "usage: %s -[n nation] [-d dir] [-x] [-h] [-p] [-c]\n", argv[0]);
  48. }
  49.  
  50.   /* initializes the user's data structure, and does
  51.      other tasks concerned with loading up the game
  52.    */
  53. init_user(innation, nation)
  54.      int innation;        /* do we have a nation name already? */
  55.      char nation[];        /* pre-entered nation name */
  56. {
  57.   char passwd[NAMELEN];
  58.   char *s, *getpass(), *crypt();
  59.   int c;
  60.   char syscmd[NAMELEN];
  61.   int i;
  62.   Sdiplo **allocate_diplo();
  63.  
  64.   printf("initializing user...\r\n");
  65.   load_army_types();
  66.   load_spirit_types();
  67.     /* in case the master changed your password */
  68.   load_master_execs();
  69.   if (!innation)
  70.     {
  71.       printf("which nation would you like to play? ");
  72.       getline(nation, NAMELEN);
  73.     }
  74.   if ((user.id = get_nation_id(nation)) == -1) {
  75.     printf ("\r\nnation does not exist, sorry\r\n");
  76.     clean_exit ();
  77.     exit (1);
  78.   }
  79.   get_crypt_pass("Your nation's password: ", passwd, NULL, NULL);
  80.   if (strcmp(world.nations[user.id].passwd, passwd)) {
  81.     printf("\r\nTry again\r\n");
  82.     get_crypt_pass("Your nation's password: ", passwd, NULL, NULL);
  83.     user.id = get_nation_id(nation);
  84.     if (strcmp(world.nations[user.id].passwd, passwd)) {
  85.       printf("\r\nwrong password, sorry\r\n");
  86.       clean_exit();
  87.       exit(1);
  88.     }
  89.   }
  90.  
  91.   handle_locks(user.id);
  92.  
  93.   user.np = &world.nations[user.id];
  94.  
  95.     /* now check to see if this nation has been destroyed */
  96.   if (user.np->capital.x == -1 && user.np->capital.y == -1) {
  97.     if (user.np->id == 0) {    /* nation 0 cannot be destroyed!!! */
  98.       user.np->capital.x = 0;
  99.       user.np->capital.y = 0;
  100.     } else {
  101.       printf("\r\nYour nation has been destroyed.\n");
  102.       printf("Ask your Gamemaster for your last mail.\n");
  103.       clean_exit();
  104.       exit(0);
  105.     }
  106.   }
  107.     /* find out which army types are available to the user */
  108.   user.avail_armies = NULL;
  109.   get_avail_armies(&user, user.np->tech_skill);
  110.     /* start the user off with all spells s/he deserves.
  111.        note that, because of spirits, this has to be done
  112.        before load_nation(), since the spirit list is used
  113.        in the exec parsing.
  114.      */
  115.   user.spell_list = NULL;
  116.   user.spirit_list = NULL;
  117.   get_spells(&user, user.np->mag_skill);
  118.   get_spirits(&user, user.np->mag_skill);
  119.     /* fundamental step:  load exec file */
  120.   if (user.id != 0) {        /* gamemaster is already loaded */
  121.     load_nation(user.id, user.np);
  122.   } else {
  123.     load_options(user.np);
  124.   }
  125.     /* now set fields for the ustruct */
  126.   user.cursor = user.center = user.np->capital;
  127.   user.help_char = '?';
  128.   user.map_style = NORMAL_MAP;
  129.   user.display = DESIGNATION;
  130.   if (user.id != 0) {
  131.     user.highlight = H_OWNED;
  132.   } else {            /* for gamemaster, don't highlight */
  133.     user.highlight = H_NONE;
  134.   }
  135.   user.underwater = 0;        /* user is not underwater at start */
  136.   if (user.np->race.pref_alt < 0) {
  137.     user.underwater = 1;    /* merfolk or whatever */
  138.   }
  139.   user.n_execs = 0;
  140.   user.current_army =
  141.     first_sect_army(&world.map[user.cursor.x][user.cursor.y]);
  142.   user.just_moved = 1;
  143.   user.last_n_armies = 0;
  144.     /* super user visibility */
  145.   if (user.id == 0) {
  146.     viewall = 1;
  147.   }
  148.   user.show_sect_win = 1;
  149.     /* load user's diplomacy statuses, for fast access later;
  150.        also remember the initial values, so users cannot change
  151.        their status by more than one step at a time.
  152.      */
  153.   user.diplo_matrix = allocate_diplo(world.n_nations);
  154.   read_in_diplo(user.diplo_matrix, world.n_nations);
  155. /* Load removed spells first */
  156.   load_dead_hspells(&user,0);
  157.  
  158.     /* load hanging spells, and put them in this user's list */
  159.   load_h_spells(&user);
  160.     /* calculate visibility matrix for this user.
  161.        this might depend on spells, so do it after
  162.        loading spells.
  163.      */
  164.   user.visible_sectors = (int **) malloc(world.xmax*sizeof(int *));
  165.   for (i = 0; i < world.xmax; ++i) {
  166.     user.visible_sectors[i] = (int *) malloc(world.ymax*sizeof(int));
  167.   }
  168.   find_visible_sectors(user.visible_sectors);
  169. }
  170.  
  171.   /* for a fixed army, update its visibility range */
  172. army_visibility(visible_sectors, ap)
  173.      int **visible_sectors;
  174.      Sarmy *ap;
  175. {
  176.   int x = ap->pos.x, y = ap->pos.y, i, j;
  177.   Ssector *sp;
  178.  
  179.   sp = &world.map[x][y];
  180.   if (has_hidden(sp) && sp->owner != user.id) {
  181.     visible_sectors[x][y] = SEE_ARMIES;
  182.   } else if (sp->owner != user.id) {
  183.     visible_sectors[x][y] = SEE_ARMIES;
  184.   } else {
  185.     visible_sectors[x][y] = SEE_ALL;
  186.   }
  187.   for (i = x-ARMY_SIGHT; i <= x+ARMY_SIGHT; ++i) {
  188.     for (j = y-ARMY_SIGHT; j <= y+ARMY_SIGHT; ++j) {
  189.       sp = &world.map[(*wrapx)(i,j)][(*wrapy)(i,j)];
  190.       if (has_hidden(sp) && sp->owner != user.id) {
  191.     /* if sect. is hidden, we don't see it */
  192.       } else {
  193.     visible_sectors[(*wrapx)(i,j)][(*wrapy)(i,j)] |=
  194.       (SEE_LAND_WATER | SEE_OWNER | SEE_DESIG |
  195.        SEE_POPULATION | SEE_ARMIES);
  196.       }
  197.       if (world.map[(*wrapx)(i,j)][(*wrapy)(i,j)].owner == 0) {
  198.     visible_sectors[(*wrapx)(i,j)][(*wrapy)(i,j)] |= SEE_RESOURCES;
  199.       }
  200.     }
  201.   }
  202. }
  203.  
  204.   /* this allows a user to set her/his options */
  205. options()
  206. {
  207.   WINDOW *optw;
  208.   char c;
  209.   int done = 0;
  210.   char *forwarding = mail_forwarding(user.id);
  211.  
  212.   optw = newwin(8, 50, 5, 10);
  213.   while (!done) {
  214.     mvwprintw(optw, 1, 2, "[x]: toggle expert mode (%s)",
  215.           user.np->opts->expert_mode ? "on" : "off");
  216.     wclrtoeol(optw);
  217.  
  218.     if (user.np->opts->mail_forward) {
  219.       mvwprintw(optw, 2, 2, "[f]: Change mail forwarding (\"%s\")",
  220.                    user.np->opts->mail_forward);
  221.     } else {
  222.       mvwprintw(optw, 2, 2, "[f]: Change mail forwarding (none)");
  223.     }
  224.     wclrtoeol(optw);
  225.     mvwprintw(optw, 3, 2, "[c]: Toggle civilian movement (%s)",
  226.                      civ_move[user.np->opts->civ_movemode]);
  227.     wclrtoeol(optw);
  228.     if (user.np->opts->mail_reader) {
  229.       mvwprintw(optw, 4, 2, "[m]: Mail Program (%s)",
  230.                                    user.np->opts->mail_reader);
  231.     } else {
  232.       mvwprintw(optw, 4, 2, "[m]: Mail Program (internal)");
  233.     }
  234.     wclrtobot(optw);
  235.     box(optw, '|', '-');
  236.     wrefresh(optw);
  237.     statline("Choose an option, hit space to get back.", "options");
  238.     switch (c = getch()) {
  239.     case 'x':
  240.       user.np->opts->expert_mode = !user.np->opts->expert_mode;
  241.       user.xmode = user.np->opts->expert_mode;
  242.       break;
  243.     case 'f':
  244.       ask_for_forwarding(optw);
  245.       break;
  246.     case 'c':
  247.         /* cycle through the various migration modes */
  248.       user.np->opts->civ_movemode = (user.np->opts->civ_movemode + 1) % 3;
  249.       break;
  250.     case 'm':
  251.       ask_for_mail_reader(optw);
  252.       break;
  253.     case ' ':
  254.       done = 1;
  255.       break;
  256.     default:
  257.       break;
  258.     }
  259.   }
  260.   delwin(optw);
  261.   user.just_moved = 1;
  262.   save_options(user.np);
  263.  
  264.   touch_all_wins();
  265. }
  266.  
  267. static ask_for_forwarding(win)
  268.      WINDOW *win;
  269. {
  270.   char buf[200];
  271.  
  272.   mvwprintw(win, 5, 2, "New mail address? (<return> for no forwarding)");
  273.   mvwprintw(win, 6, 4, "-->");
  274.   wrefresh(win);
  275.  
  276.   if (user.np->opts->mail_forward != NULL) {
  277.     free(user.np->opts->mail_forward);
  278.     user.np->opts->mail_forward = NULL;
  279.   }
  280.   if (wget_string(win, buf,200) != 0) {
  281.     if ((user.np->opts->mail_forward = (char *)malloc ((strlen(buf) + 1) * 
  282.           sizeof (char))) == NULL) { mem_error(); }
  283.     strcpy(user.np->opts->mail_forward, buf);
  284.   } 
  285. }
  286.  
  287. ask_for_mail_reader(win)
  288.      WINDOW *win;
  289. {
  290.   char buf[200];
  291.  
  292.   if (user.np->opts->mail_reader) { free(user.np->opts->mail_reader); }
  293.  
  294.   mvwprintw(win, 5, 2, "New mail reader? (<return> for internal mail)");
  295.   mvwprintw(win, 6, 4, "-->");
  296.   wrefresh(win);
  297.  
  298.   if (wget_string(win, buf, 200))  {
  299.     if ((user.np->opts->mail_reader = (char *)malloc ((strlen(buf) + 1) * 
  300.           sizeof (char))) == NULL) { mem_error(); }
  301.     strcpy(user.np->opts->mail_reader, buf);
  302.   } else {
  303.     user.np->opts->mail_reader = NULL;
  304.   }
  305. }
  306.  
  307.   /* check if there is a lock file, and handle the situation if there is */
  308. handle_locks(id)
  309.      int id;
  310. {
  311.   FILE *lock_fp, *is_locked();
  312.   char *timestr;
  313.   long secs;            /* seconds marked in lock file */
  314.  
  315.     /* check if there is a master lock file */
  316.   if (is_master_lock()) {
  317.     printf("There is a master lock file.  You cannot play right now.\n");
  318.     clean_exit();
  319.     exit(1);
  320.   }
  321.   if (strcmp(update_time,get_update_time()) != 0)
  322.   {
  323.     fprintf(stderr,"Error: Update has occured.  Please restart program \n");
  324.     clean_exit();
  325.     exit(0);
  326.   }
  327.  
  328.     /* see if there is a lock file for this nation */
  329.   if (lock_fp = is_locked(id)) {
  330.     fscanf(lock_fp, "%ld", &secs);
  331.     fclose(lock_fp);
  332.     timestr = ctime(&secs);
  333.     printf("\r\nYour nation is already being played.\n\r");
  334.     printf("That session seems to have been started at %s", timestr);
  335.     printf("If that session is no more and you want to play now, type [y] ");
  336.     if (getchar() != 'y') {
  337.       printf("OK, then you will have to wait until that session is over\n");
  338.       clean_exit();
  339.       exit(1);
  340.     }
  341.   }
  342.     /* set a lock file */
  343.   set_lock(id);
  344. }
  345.  
  346.