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

  1.   /* commands.c -- various commands in dominion */
  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 "dominion.h"
  25. #include "misc.h"
  26. #include "army.h"
  27. #include <stdio.h>
  28.     /* many commands are kept in this file, except for those
  29.        that depend on the graphics being used.
  30.      */
  31.  
  32. extern Suser user;
  33. extern Sworld world;
  34. extern struct s_desig_map desig_map[];
  35. extern struct s_altitude_map altitude_map[];
  36. extern struct item_map climates[];
  37. extern struct item_map terrains[];
  38. extern WINDOW *sectw;
  39. extern char help_tag[];
  40. extern int (*wrapx)(), (*wrapy)();
  41. extern char *getenv();
  42. extern char libdir[], *current_dir;
  43.  
  44. quit()                /* cleanup and quit */
  45. {
  46.   clear();
  47.   cleanup();
  48.   clean_exit();
  49.   exit(0);
  50. }
  51.  
  52. help()
  53. {
  54.   start_help_win();
  55.   show_help();
  56.   end_help_win();
  57. }
  58.  
  59.   /* this routine sets certain parameters that must be
  60.      set when the cursor has been moved
  61.    */
  62. just_moved()
  63. {
  64.   user.just_moved = 1;
  65. }
  66.  
  67. up()                /* move the cursor; should look at topology */
  68. {
  69.   --user.cursor.y;
  70.   just_moved();
  71. }
  72. jup()
  73. {
  74.   user.cursor.y -= 8;
  75.   just_moved();
  76. }
  77. down()
  78. {
  79.   ++user.cursor.y;
  80.   just_moved();
  81. }
  82. jdown()
  83. {
  84.   user.cursor.y += 8;
  85.   just_moved();
  86. }
  87. right()
  88. {
  89.   ++user.cursor.x;
  90.   just_moved();
  91. }
  92. jright()
  93. {
  94.   user.cursor.x += 8;
  95.   just_moved();
  96. }
  97. left()
  98. {
  99.   --user.cursor.x;
  100.   just_moved();
  101. }
  102. jleft()
  103. {
  104.   user.cursor.x -= 8;
  105.   just_moved();
  106. }
  107. upright()
  108. {
  109.   up(); right();
  110.   just_moved();
  111. }
  112. upleft()
  113. {
  114.   up(); left();
  115.   just_moved();
  116. }
  117. downright()
  118. {
  119.   down(); right();
  120.   just_moved();
  121. }
  122. downleft()
  123. {
  124.   down(); left();
  125.   just_moved();
  126. }
  127. jhome()
  128. {
  129.   user.cursor.x = user.np->capital.x;
  130.   user.cursor.y = user.np->capital.y;
  131.   user.center = user.cursor;
  132.   just_moved();
  133. }
  134.  
  135. jpos()
  136. {
  137.   char s[100];
  138.   int x,y;
  139.  
  140.   statline2("  x postion to jump to ? : " , "position");
  141.   move (LINES-2, strlen("  x position to jump to ? : "));
  142.   if ( wget_number(stdscr, &x) < 1) {
  143.     statline2("", "");
  144.     return;
  145.   }
  146.   statline2("  y postion to jump to ? : " , "position");
  147.   move (LINES-2, strlen("  y position to jump to ? : "));
  148.   if ( wget_number(stdscr, &y) < 1) {
  149.     statline2("", "");
  150.     return;
  151.   }
  152.   user.cursor.x = (*wrapx)(user.np->capital.x + x,user.np->capital.y + y);
  153.   user.cursor.y = (*wrapy)(user.np->capital.x + x,user.np->capital.y + y);
  154.   user.center = user.cursor;
  155.   just_moved();
  156.   statline2("", "");
  157. }
  158.  
  159. #define ZX 70
  160. #define ZY 18
  161.  
  162.   /* zoom-in on a sector */
  163. zoom_sector()
  164. {
  165.   WINDOW *zoomw = NULL;
  166.   char s[EXECLEN];
  167.   char c;
  168.   int x = user.cursor.x, y = user.cursor.y;
  169.   Ssector *sp = &world.map[x][y];
  170.   Snation *np;
  171.   int done = 0, old_desig = sp->designation;
  172.   int new_desig = sp->designation, quantity, fraction, total;
  173.   int visibility = user.visible_sectors[x][y];
  174.  
  175.   strcpy(help_tag, "Designations");
  176.   if (user.id != 0) {
  177.     np = user.np;
  178.   } else {
  179.     np = &world.nations[sp->owner]; /* for super user */
  180.   }
  181.   if (!user.xmode) {
  182.     zoomw = newwin(ZY, ZX, 4, 5);
  183.   }
  184.   while (!done) {
  185.     if (zoomw) {
  186.       statline("type space when done", "zoom_sector");
  187.  
  188.       if (strlen(sp->name) > 0 && (visibility & SEE_POPULATION)) {
  189.     sprintf(s, "Detailed Evaluation of %s", sp->name);
  190.       } else {
  191.     sprintf(s, "Detailed Evaluation of Sector (%d,%d)",
  192.         xrel(x, y, np->capital), yrel(x, y, np->capital));
  193.       }
  194.       wmove(zoomw, 1, 1);
  195.       wclrtoeol(zoomw);
  196.       wmove(zoomw, 1, (70-strlen(s))/2); /* make the string centered */
  197.       wstandout(zoomw);
  198.       waddstr(zoomw, s);
  199.       wclrtoeol(zoomw);
  200.       wstandend(zoomw);
  201.  
  202.       if (sp->owner != 0 && (visibility & SEE_OWNER)) {
  203.     mvwprintw(zoomw, 2, 2, "     Owner: %s",world.nations[sp->owner].name);
  204.       } else {
  205.     mvwprintw(zoomw, 2, 2, "     Owner: None");
  206.       }
  207.       if (strlen(sp->name) > 0 || !(visibility & SEE_POPULATION)) {
  208.     mvwprintw(zoomw, 2, 1+ZX/2, "Location: (%d,%d)",xrel(x,y,np->capital),
  209.           yrel(x,y,np->capital));
  210.       }
  211.       wclrtoeol(zoomw);
  212.  
  213.       mvwprintw(zoomw, 3, 2, " Geography: ");
  214.       if (visibility & SEE_LAND_WATER) {
  215.     wprintw(zoomw, "%s ", terrains[sp->terrain - MIN_TERRAIN].name);
  216.     if (sp->altitude > SEA_LEVEL) {
  217.       wprintw(zoomw, "%s", altitude_map[map_alt(sp->altitude)].name);
  218.     }
  219.       } else {
  220.     wprintw(zoomw, "Unknown");
  221.       }
  222.       wclrtoeol(zoomw);
  223.  
  224.       mvwprintw(zoomw, 4, 2, "   Climate: ");
  225.       if (visibility & SEE_LAND_WATER) {
  226.     wprintw(zoomw, "%s", climates[sp->climate].name);
  227.       } else {
  228.     wprintw(zoomw, "Unknown");
  229.       }
  230.       wclrtoeol(zoomw);
  231.  
  232.       mvwprintw(zoomw, 5, 2, " Resources: ");
  233.       if (visibility & SEE_RESOURCES) {
  234.     wprintw(zoomw, "soil %d, metal %d, jewels %d", sp->soil, sp->metal,
  235.         sp->jewels);
  236.       } else {
  237.     wprintw(zoomw, "Unknown");
  238.       }
  239.       wclrtoeol(zoomw);
  240.  
  241.       mvwprintw(zoomw, 6, 2, "Population: ");
  242.       if (sp->owner != 0) {
  243.     if (visibility & SEE_POPULATION) {
  244.       wprintw(zoomw, "%d people (%c); %d employed; %d%% unemp.",
  245.           sp->n_people, world.nations[sp->owner].race.mark,
  246.           n_workers(sp), sp->n_people ?
  247.           (100*(sp->n_people - n_workers(sp)))/sp->n_people : 0);
  248.     } else {
  249.       wprintw(zoomw, "Unknown people");
  250.     }
  251.     if ((visibility & SEE_ARMIES) && sp->alist != NULL) {
  252.       wprintw(zoomw, "; %d armies", sect_n_armies(sp));
  253.     }
  254.       } else {
  255.     wprintw(zoomw, "None");
  256.       }
  257.       wclrtoeol(zoomw);
  258.  
  259.       mvwprintw(zoomw, 7, 2, "  Movecost: ");
  260.       if (visibility & SEE_LAND_WATER) {
  261.     wprintw(zoomw, "%d", get_generic_move_cost(np,sp));
  262. /*    wprintw(zoomw, "%d", get_move_cost(np,sp)); */
  263.       } else {
  264.     wprintw(zoomw, "Unknown");
  265.       }
  266.       wclrtoeol(zoomw);
  267.       mvwprintw(zoomw, 7, 1+ZX/4, "Roads: %d", sp->roads);
  268.       mvwprintw(zoomw, 7, 1+2*ZX/4, "Defense: %d", sp->defense);
  269.       mvwprintw(zoomw, 7, 1+3*ZX/4, " %s", has_bubble(sp) ? "Bubble" : "");
  270.  
  271.       if (sp->owner == np->id || user.id == 0) {
  272.     mvwprintw(zoomw, 9, 2, "Sector Economy:");
  273.     wclrtoeol(zoomw);
  274.  
  275.     mvwprintw(zoomw, 10, 2, "       Designation: %s (%c)",
  276.           desig_map[old_desig].name,
  277.           desig_map[old_desig].mark);
  278.     wclrtoeol(zoomw);
  279.  
  280.     mvwprintw(zoomw, 11, 2, " Trial Designation: %s (%c)",
  281.           desig_map[new_desig].name,
  282.           desig_map[new_desig].mark);
  283.     wclrtoeol(zoomw);
  284.  
  285.       /* now tell the user how much revenue this sector generates */
  286.     quantity=(desig_map[new_desig].revenue*np->taxes*n_workers(sp))/100;
  287.     if (calc_revenue(np) > 0) {
  288.       fraction = (100*quantity)/calc_revenue(np);
  289.     } else {
  290.       fraction = 100;
  291.     }
  292.  
  293.     mvwprintw(zoomw, 12, 2, "Per capita revenue: %d    ",
  294.           desig_map[new_desig].revenue);
  295.     mvwprintw(zoomw, 13, 2,
  296.           "   Taxes collected: %d, %d%% of total income (%d)    ",
  297.           quantity, fraction, calc_revenue(np));
  298.     wclrtoeol(zoomw);
  299.  
  300.     switch (desig_map[new_desig].mark) {
  301.     case 'm':
  302.       strcpy(s, "metal");
  303.       total = calc_metal(np);
  304.       quantity = sector_metal(sp);
  305.       break;
  306.     case 'j':
  307.       strcpy(s, "jewels");
  308.       total = calc_jewels(np);
  309.       quantity = sector_jewels(sp);
  310.       break;
  311.     case 'f':
  312.       strcpy(s, "food");
  313.       total = calc_food(np);
  314.       quantity = sector_food(sp);
  315.       break;
  316.     default:
  317.       strcpy(s, "");
  318.       quantity = -1;
  319.       fraction = 0;
  320.       break;
  321.     }
  322.     fraction = (total == 0) ? 100 : ((quantity * 100) / total);
  323.  
  324.     wmove(zoomw, 14, 2);
  325.     if (quantity != -1) {
  326.       /* watch out for division by zero if there are zero workers */
  327.       wprintw(zoomw,
  328.                "Production of %s: %d; %d%% of total (%d); %5.2f per capita   ",
  329.       s, quantity, fraction, total,
  330.       ((double) quantity)/((double) (n_workers(sp) ? n_workers(sp) : 1)));
  331.     }
  332.     wclrtoeol(zoomw);
  333.       }
  334.  
  335.       mvwaddstr(zoomw, 16, 1,
  336.         "Options: [N]ame sector, [t]rial redesignate, [r]edesignate");
  337.       box(zoomw, '|', '-');
  338.       wrefresh(zoomw);
  339.     } else {            /* else we must be in e[x]pert mode */
  340.       if (visibility & SEE_POPULATION) {
  341.     sprintf(s, "[N],[r],pop=%d,emp=%d,roads=%d,defense=%d", sp->n_people,
  342.         n_workers(sp), sp->roads, sp->defense);
  343.       } else {
  344.     sprintf(s, "[N],[r],pop=?,emp=?,roads%d,defense%d",
  345.         sp->roads, sp->defense);
  346.       }
  347.       statline_prompt(s, "sector zoom");
  348.     }
  349.     switch(c = mygetch()) {
  350.     case ' ':
  351.       done = 1;
  352.       break;
  353.     case 'N':
  354.       name_sector(zoomw);
  355.       break;
  356.     case 't':            /* redesignate without paying and saving */
  357.       if (zoomw) {            /* not in expert mode */
  358.     new_desig = redesignate(np, zoomw, 0);
  359.     sp->designation = new_desig;
  360.       }
  361.       break;
  362.     case 'r':            /* make a redesignation for sure, and pay */
  363.       new_desig = redesignate(np, zoomw, 2);
  364.       old_desig = new_desig;    /* permanent change!! */
  365.       sp->designation = new_desig;
  366.       break;
  367.     default:
  368.       break;
  369.     }
  370.   }
  371.   if (zoomw) {
  372.     delwin(zoomw);
  373.     touch_all_wins();
  374.     refresh();
  375.   }
  376.   sp->designation = old_desig;    /* make sure "trial" changes are temporary */
  377. }
  378.  
  379.   /* change the name of a sector */
  380. name_sector(w)
  381.      WINDOW *w;
  382. {
  383.   char name[NAMELEN];
  384.   int x = user.cursor.x, y = user.cursor.y;
  385.   Ssector *sp = &world.map[x][y];
  386.   char s[EXECLEN];
  387.   int ret;            /* for return values */
  388.  
  389.   if (w) {
  390.     statline("name this sector", "name_sector");
  391.   }
  392.   if (sp->owner != user.id && user.id != 0) {
  393.     statline2_err("hit space", "sector not yours");
  394.   } else {
  395.     if (w) {
  396.       mvwaddstr(w, ZY-3, 2, "Enter name for the sector: ");
  397.       wclrtoeol(w);
  398.       wrefresh(w);
  399.     } else {
  400.       statline_prompt("Name this sector: ", "");
  401.     }
  402.     ret = wget_name(w, name);
  403.     if (ret > 0) {
  404.       strcpy(sp->name, name);
  405.         /* now generate the exec instruction */
  406.       sprintf(s, "SNAME:%d:%d:%s\n", x, y, name);
  407.       gen_exec(s);
  408.     }
  409.   }
  410.   if (w) {
  411.     wmove(w, ZY-3, 2);
  412.     wclrtoeol(w);
  413.   }
  414.   user.just_moved = 1;
  415. }
  416.  
  417.   /* menu that allows you to redesignate a sector */
  418. redesignate(np, w, confirm)
  419.      Snation * np;
  420.      WINDOW *w;
  421.      int confirm;
  422. {
  423.   char name[NAMELEN];
  424.   int x = user.cursor.x, y = user.cursor.y;
  425.   Ssector *sp = &world.map[x][y];
  426.   char s[EXECLEN];
  427.   char c;
  428.   int i, new_desig = sp->designation;
  429.  
  430.   if (w) {
  431.     statline("choose a designation", "redesignate");
  432.   }
  433.   if (sp->owner != user.id && user.id != 0) {
  434.     statline2_err("type space to continue", "sector not yours");
  435.       /* a user cannot remove their capital, but Gamemaster can */
  436.   } else if (user.id != 0 && sp->designation == D_CAPITAL) {
  437.     statline2_err("type space to continue", "you cannot be without a capital");
  438.   } else {
  439.     if (w) {
  440.       wmove(w, ZY-5, 1);
  441.       wclrtoeol(w);
  442.       wmove(w, ZY-5, 1);
  443.       for (i = 0; i < D_MAX_DESIG; ++i) {
  444.     if (i % 4 == 0) {
  445.       wmove(w, ZY-5 + i/4, 1);
  446.       wclrtoeol(w);
  447.       wmove(w, ZY-5 + i/4, 1);
  448.     }
  449.     wprintw(w, "[%c]-%s  ", desig_map[i].mark, desig_map[i].name);
  450.       }
  451.       box(w,'|','-');
  452.       wrefresh(w);
  453.     } else {            /* expert mode */
  454.       statline_prompt("Give new designation: ", "");
  455.     }
  456.     c = getch();        /* get the new designation */
  457.  
  458.     for (i = 0; i < D_MAX_DESIG; ++i) {
  459.       if (desig_map[i].mark == c) {
  460.     new_desig = i;
  461.     break;
  462.       }
  463.     }
  464.     /* make sure that user's capital is moved (if it is confirmed) */
  465.     if ((new_desig == D_CAPITAL) && confirm) {
  466.       move_capital(&world.nations[sp->owner], sp);
  467.     }
  468.   }
  469.   if (w) {
  470.     wmove(w, ZY-5, 0);
  471.     wclrtobot(w);
  472.     statline2("", "");
  473.   }
  474.   if (new_desig==D_CITY && sp->n_people < desig_map[new_desig].min_employed) {
  475.     sprintf(s, "need %d people for a city", desig_map[new_desig].min_employed);
  476.     statline2_err("type space to continue", s);
  477.     new_desig = sp->designation;
  478.     confirm = 0;
  479.   }
  480.  
  481.   if (np->money < desig_map [new_desig].price && confirm && !(user.id == 0)) {
  482.     confirm = 0;
  483.     new_desig = sp->designation;
  484.     statline2_err ("space to continue", "not enough money");
  485.   }
  486.  
  487.   /* only make the actual change if the confirm flag is set */
  488.   if ((new_desig != sp->designation) && confirm) {
  489.     sp->designation = new_desig;
  490.       /* now generate the exec instructions */
  491.     sprintf(s, "DESIG_SECTOR:%d:%d:%d\n", x, y, new_desig);
  492.     gen_exec(s);
  493.     user.np->money -= desig_map[i].price;
  494.     cmoney(user.np, -desig_map[new_desig].price);
  495.   }
  496.   user.just_moved = 1;
  497.   return new_desig;
  498. }
  499.  
  500.   /* a couple of little routines that generate simple
  501.      exec lines, and are used all the time
  502.    */
  503. cpeople_sector(sp, p)
  504.      Ssector *sp;
  505.      int p;
  506. {
  507.   char s[EXECLEN];
  508.  
  509.   sprintf(s, "CPEOPLE_SECTOR:%d:%d:%d\n", sp->loc.x, sp->loc.y, p);
  510.   gen_exec(s);
  511. }
  512.  
  513. cmoney(np, m)
  514.      Snation *np;
  515.      int m;
  516. {
  517.   char s[EXECLEN];
  518.   sprintf(s, "CMONEY:%d:%d\n", np->id, m);
  519.   gen_exec(s);
  520. }
  521.  
  522. cmetal(np, m)
  523.      Snation *np;
  524.      int m;
  525. {
  526.   char s[EXECLEN];
  527.   sprintf(s, "CMETAL:%d:%d\n", np->id, m);
  528.   gen_exec(s);
  529. }
  530.  
  531. cjewels(np, j)
  532.      Snation *np;
  533.      int j;
  534. {
  535.   char s[EXECLEN];
  536.   sprintf(s, "CJEWELS:%d:%d\n", np->id, j);
  537.   gen_exec(s);
  538. }
  539.  
  540. cspell_pts(np, pts)
  541.      Snation *np;
  542.      int pts;
  543. {
  544.   char s[EXECLEN];
  545.  
  546.   sprintf(s, "CSPELL_PTS:%d:%d\n", np->id, pts);
  547.   gen_exec(s);
  548. }
  549.  
  550. cfood(np, f)
  551.      Snation *np;
  552.      int f;
  553. {
  554.   char s[EXECLEN];
  555.   sprintf(s, "CFOOD:%d:%d\n", np->id, f);
  556.   gen_exec(s);
  557. }
  558.  
  559. ctech_skill(np, change)
  560.      Snation *np;
  561.      int change;
  562. {
  563.   char s[EXECLEN];
  564.   sprintf(s, "CTECH_SKILL:%d:%d\n", np->id, change);
  565.   gen_exec(s);
  566. }
  567.  
  568. cmag_skill(np, change)
  569.      Snation *np;
  570.      int change;
  571. {
  572.   char s[EXECLEN];
  573.   sprintf(s, "CMAG_SKILL:%d:%d\n", np->id, change);
  574.   gen_exec(s);
  575. }
  576.  
  577.   /* this ensures that the user has only one capital,
  578.      when he moves his over.
  579.    */
  580. move_capital(np, sp)
  581.      Snation *np;
  582.      Ssector *sp;
  583. {
  584.   char s[EXECLEN];
  585.     /* first make the old capital be a simple city */
  586.   if (user.id != 0) {
  587.     world.map[np->capital.x][np->capital.y].designation = D_CITY;
  588.     sprintf(s,"DESIG_SECTOR:%d:%d:%d\n", np->capital.x, np->capital.y, D_CITY);
  589.     gen_exec(s);
  590.       /* now make this sector be the new capital */
  591.   }
  592.   np->capital = sp->loc;
  593. }
  594.  
  595.   /* dumps the map visible on the screen to a file */
  596. dump_map()
  597. {
  598.   char s[80], filename[NAMELEN];
  599.   sprintf(s, "give a file name (default = \"%s\")", "map");
  600.   statline(s, "dump_map");
  601.   move(LINES-2, COLS/3);
  602.   addstr("> ");
  603.   echo();
  604.   if (wget_string(NULL,filename,18) <= 0) {
  605.     strcpy(filename, "map");
  606.   }
  607.   noecho();
  608.   move(LINES-2, COLS/3);
  609.   clrtoeol();
  610.   my_scr_dump(stdscr, filename);
  611. }
  612.  
  613.   /* mail menu */
  614. mail()
  615. {
  616.   char *mail_prog;
  617.  
  618.   statline("do you want to (r)ead mail or (w)rite mail", "mail");
  619.   switch (getch()) {
  620.   case 'r':
  621.     refresh();
  622.     mail_read(user.id);
  623.     clear(); refresh();
  624.     user.just_moved = 1;
  625.     break;
  626.   case 'w':
  627.     mail_write();
  628.     user.just_moved = 1;
  629.     break;
  630.   default:
  631.     break;
  632.   }
  633. }
  634.  
  635. /* This function takes care of players' sending mail to other nations.
  636.  It does all the curses printing and scaning here (That's why it's a bit
  637.  messy) and calls functions from mail for editing and sending and lock foo. */
  638.  
  639. mail_write()
  640. {
  641.   char s[EXECLEN];
  642.   int ret, id, done = 0;
  643.   char r_name[NAMELEN];
  644.   int c;
  645.   char tmp_fname[PATHLEN];
  646.   char subject[100];
  647.   char sender[NAMELEN*2+4],receiver[NAMELEN*2+4];
  648.   
  649.   clear();
  650.   statline("Sending mail","mail_write");
  651.   mvaddstr(1,0,"Enter name of recipient (Nation name) ");
  652.   ret = wget_name(stdscr,r_name);
  653.   if (ret > 0) {
  654.     id=get_nation_id(r_name);
  655.     if (id>=0) {
  656.       if (has_mail_lock(id)) {
  657.     mvaddstr(4,0,"The recipient's mailbox is active right now.");
  658.     mvaddstr(5,0,"Try sending you mail in a moment.");
  659.     refresh();
  660.     statline2_err("Press space to return","write_mail");
  661.     clear();
  662.       } else {
  663.     strcpy(tmp_fname, "/usr/tmp/domedXXXXXX");
  664.     if (mktemp(tmp_fname) == NULL) {
  665.       fprintf(stderr,"Error getting temp file name\n");
  666.       fflush(stderr);
  667.       return;
  668.     }
  669.     mvaddstr(4,0,"Subject: ");
  670.     refresh();
  671.     wget_name(stdscr, subject);
  672.     cleanup();
  673.     chdir("/usr/tmp");
  674.     edit(tmp_fname);
  675.     chdir(current_dir);
  676.     chdir(libdir);
  677.     {
  678.       initscr();
  679.       savetty();
  680.       nonl();
  681.       cbreak();
  682.       noecho();
  683.       clear();
  684.     }
  685.     mvaddstr(2, 0, "Choices: S)end mail or A)bort sending ");
  686.     refresh();
  687.     done = 0;
  688.     while(!done) {
  689.       switch(getch()){
  690.       case 'S':
  691.       case 's':
  692. /*        lock_mail(id); */
  693.         mvaddstr(3, 9, "Sending Mail...");
  694.           /* Check if mail is being used by/for this user right now */
  695.         if (has_mail_lock(id)) {
  696.           printf("Found a lock file for receiver %d\n", id);
  697.           fflush(stdout);
  698.           refresh();
  699.           sleep(2);
  700.           if(has_mail_lock(id)) {
  701.         printf("Found a lock file for receiver %d\n", id);
  702.         fflush(stdout);
  703.         refresh();
  704.         return(1);
  705.           }
  706.         }
  707.         lock_mail(id);
  708.         refresh();
  709.         mail_send(tmp_fname, user.id, id, subject);
  710.         unlock_mail(id);
  711.         mvaddstr(3, LINES, "done.");
  712.         refresh();
  713.         done = 1;
  714.         break;
  715.       case 'A':
  716.         mvaddstr(3, LINES-1, "OK. Aborting...");
  717.         refresh();
  718.         done = 1;
  719.         unlock_mail(id);
  720.         break;
  721.       }
  722.       unlink(tmp_fname);
  723.     }
  724.     cleanup();
  725.     init_screen();
  726.       } /* else */
  727.     } /* id >= 0 */
  728.     else {            /* else we got a bad nation name */
  729.       mvaddstr(7,0,"Invalid Nation Name");
  730.       statline2_err("Press <SPACE> to return", "Bad Nation Name");
  731.       clear();
  732.       refresh();
  733.     } /* else */
  734.   } /* ret > 0 */
  735.   clear(); refresh();
  736. } /* mail_write */
  737.