home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume13 / dominion / part26 < prev    next >
Encoding:
Internet Message Format  |  1992-02-10  |  61.0 KB

  1. Path: uunet!zephyr.ens.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v13i062:  dominion - a multi-player world simulation game, Part26/28
  5. Message-ID: <2465@masterCNA.TEK.COM>
  6. Date: 11 Feb 92 18:27:54 GMT
  7. Sender: news@masterCNA.TEK.COM
  8. Lines: 2091
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: rosalia@dirac.physics.sunysb.edu (Mark Galassi)
  12. Posting-number: Volume 13, Issue 62
  13. Archive-name: dominion/Part26
  14. Environment: Unix, curses
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 26 (of 28)."
  25. # Contents:  addnews.sh diplomacy.c mail.c misc.h spy.c user.c world.c
  26. # Wrapped by billr@saab on Tue Feb 11 10:14:59 1992
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'addnews.sh' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'addnews.sh'\"
  30. else
  31. echo shar: Extracting \"'addnews.sh'\" \(1606 characters\)
  32. sed "s/^X//" >'addnews.sh' <<'END_OF_FILE'
  33. X#!/bin/sh
  34. X#
  35. X# Copyright (C) 1990 Free Software Foundation, Inc.
  36. X# Written by the SBW project.
  37. X#
  38. X# This file is part of SBW.
  39. X#
  40. X# SBW is free software; you can redistribute it and/or
  41. X# modify it under the terms of the GNU General Public License as published
  42. X# by the Free Software Foundation; either version 1, or (at your option)
  43. X# any later version.
  44. X#
  45. X# This software is distributed in the hope that it will be useful,
  46. X# but WITHOUT ANY WARRANTY; without even the implied warranty of
  47. X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  48. X# GNU General Public License for more details.
  49. X#
  50. X# You should have received a copy of the GNU General Public License
  51. X# along with this software; see the file COPYING.  If not, write to
  52. X# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  53. X#
  54. X
  55. Xcase $# in 
  56. X2)
  57. X    echo 'Adding  newsgroups' ;;
  58. X*)
  59. X    echo 'Problem in calling addnews' 1>&2 ; exit 2;;
  60. Xesac
  61. X
  62. XDIR=$1
  63. XDB=$2
  64. Xif  test ! -d "$DIR"
  65. Xthen
  66. X    echo 'Problem with news directory argument' 1>&2
  67. X    exit 3
  68. Xfi
  69. Xif test ! -f  "$DIR/$DB"
  70. Xthen
  71. X    touch $DIR/$DB
  72. X    echo 'Creating new database ' $DIR/$DB
  73. Xelse
  74. X    echo 'Adding groups to database ' $DIR/$DB
  75. Xfi
  76. X
  77. Xt="y"
  78. Xwhile test "$t" = "y"
  79. Xdo
  80. X    echo 'Enter the name of the news group: \c'
  81. X    read group
  82. X    echo 'Do you want it human (default) or just game postable (G=game) \c'
  83. X    read postable
  84. X    if test "$postable" = "G"
  85. X    then
  86. X        echo $group ' 1 0 0' >> $DIR/$DB
  87. X    else
  88. X        echo $group ' 1 0 1' >> $DIR/$DB
  89. X    fi
  90. X    if test ! -d "$DIR/$group"
  91. X    then
  92. X        mkdir $DIR/$group
  93. X    fi
  94. X    echo 'Do you want another group? (y/Y=yes) \c'
  95. X    read t
  96. X    if test "$t" = "Y"
  97. X    then
  98. X        t="y"
  99. X    fi
  100. Xdone
  101. X
  102. Xexit 0
  103. END_OF_FILE
  104. if test 1606 -ne `wc -c <'addnews.sh'`; then
  105.     echo shar: \"'addnews.sh'\" unpacked with wrong size!
  106. fi
  107. chmod +x 'addnews.sh'
  108. # end of 'addnews.sh'
  109. fi
  110. if test -f 'diplomacy.c' -a "${1}" != "-c" ; then 
  111.   echo shar: Will not clobber existing file \"'diplomacy.c'\"
  112. else
  113. echo shar: Extracting \"'diplomacy.c'\" \(8211 characters\)
  114. sed "s/^X//" >'diplomacy.c' <<'END_OF_FILE'
  115. X/* diplomacy.c - screen-oriented diplomacy routines */
  116. X
  117. X/*
  118. X * Copyright (C) 1990 Free Software Foundation, Inc.
  119. X * Written by the dominion project.
  120. X *
  121. X * This file is part of dominion.
  122. X *
  123. X * dominion is free software; you can redistribute it and/or
  124. X * modify it under the terms of the GNU General Public License as published
  125. X * by the Free Software Foundation; either version 1, or (at your option)
  126. X * any later version.
  127. X *
  128. X * This software is distributed in the hope that it will be useful,
  129. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  130. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  131. X * GNU General Public License for more details.
  132. X *
  133. X * You should have received a copy of the GNU General Public License
  134. X * along with this software; see the file COPYING.  If not, write to
  135. X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  136. X */
  137. X
  138. X#include "dominion.h"
  139. X#include "misc.h"
  140. X#include <stdio.h>
  141. X#include <ctype.h>
  142. X
  143. Xextern Sworld world;
  144. Xextern Suser user;
  145. Xextern char *dip_status[];
  146. X
  147. Xchar show_to_screen();
  148. X
  149. Xchar diplo_report(nation)
  150. X     Snation *nation;
  151. X{
  152. X  Sdiplo **diplo_matrix, **initial_diplo; /* structure containing all info */
  153. X  Sdiplo **allocate_diplo();
  154. X  FILE   *dfp;           /* file containing all info */
  155. X  int i;
  156. X  char c;
  157. X
  158. X/*  statline2_err("diplo was not locked", "hit space"); */
  159. X    /* read in the current diplomacy matrix, and also the
  160. X       initial state (to see if the user wants to change
  161. X       their status too much)
  162. X     */
  163. X  diplo_matrix = allocate_diplo(world.n_nations);
  164. X  initial_diplo = allocate_diplo(world.n_nations);
  165. X  read_initial_diplo(initial_diplo, world.n_nations);
  166. X    /* if reading in the file fails, we must re-create it */
  167. X  if (read_in_diplo(diplo_matrix, world.n_nations) == -1) {
  168. X    statline2_err("Hit space to go on", "have to re-build diplo file");
  169. X    init_diplo(1);
  170. X    for (i = 2; i <= world.n_nations; ++i) {
  171. X      Sdiplo **dm_old, **dm_new;
  172. X      dm_old = allocate_diplo(i-1);
  173. X      dm_new = allocate_diplo(i);
  174. X      read_in_diplo(dm_old, i-1);
  175. X      increase_diplo(dm_old, dm_new, i-1, &world.nations[i-1]);
  176. X      dump_diplo(nation, dm_new, i);
  177. X      free_diplo(dm_old, i-1);
  178. X      free_diplo(dm_new, i);
  179. X    }
  180. X    update_diplo();        /* update it, since it was reset */
  181. X    read_in_diplo(diplo_matrix, world.n_nations);
  182. X  }
  183. X
  184. X  c = show_to_screen(diplo_matrix, initial_diplo, nation);
  185. X  free_diplo(diplo_matrix, world.n_nations);
  186. X  return c;
  187. X}
  188. X
  189. Xchar show_to_screen(dm, initial_dm, nation)
  190. X  Sdiplo **dm, **initial_dm;
  191. X  Snation *nation;
  192. X{
  193. X/* this function will dynamically keep the window updated with 
  194. X   the diplomacy information.
  195. X */
  196. X
  197. X  WINDOW *dipw;          /* the diplomacy window */
  198. X  int i, j, done=0, neigh_id=0, first_shown, n_shown;
  199. X  char c;
  200. X
  201. X  statline("hit space when done", "diplomacy report");
  202. X
  203. X  dipw = newwin(LINES-2, COLS, 0, 0);  /* full screen window */
  204. X  werase(dipw);
  205. X  touchwin(dipw);
  206. X  first_shown = 1;
  207. X  n_shown = min(world.n_nations, LINES-9);
  208. X  while (!done) {
  209. X    wmove(dipw, 0, COLS/2-13);
  210. X    wstandout(dipw);
  211. X    wprintw(dipw, "Diplomacy for nation %s", nation->name);
  212. X    wstandend(dipw);
  213. X
  214. X  mvwprintw(dipw,1,3,"                                        TO  YOU        TO YOU  ");
  215. X  mvwprintw(dipw,2,3," NATION                   BY YOU         (now)       (at start)");
  216. X  mvwprintw(dipw,3,3," ======                   ======         ======      ==========");
  217. X    wclrtobot(dipw);
  218. X
  219. X    i=0;
  220. X    for (j = 0; j < n_shown &&  j+first_shown < world.n_nations; ++j) {
  221. X        /* j+first_shown is for nation ids, i is for lines printed */
  222. X      wmove(dipw, 4+j, 3);
  223. X      wclrtoeol(dipw);
  224. X      ++i;
  225. X      if (is_active_ntn(&world.nations[j+first_shown])) {
  226. X    mvwprintw(dipw, 4+j, 3, "%2d. %-21s%c%-12s  %c%-12s  %-12s",
  227. X          world.nations[j+first_shown].id,
  228. X          world.nations[j+first_shown].name,
  229. X          dm[nation->id][j+first_shown].status ==
  230. X              initial_dm[nation->id][j+first_shown].status ? ' ' : '*',
  231. X          dip_status[ dm[nation->id][j+first_shown].status ],
  232. X          dm[j+first_shown][nation->id].status ==
  233. X          initial_dm[j+first_shown][nation->id].status ? ' ' : '*',
  234. X          dip_status[dm[j+first_shown][nation->id].status ],
  235. X          dip_status[ initial_dm[j+first_shown][nation->id].status ]);
  236. X      } else {
  237. X    mvwprintw(dipw, 4+j, 3, "%2d. %-21s   ** DESTROYED **",
  238. X          world.nations[j+first_shown].id,
  239. X          world.nations[j+first_shown].name);
  240. X      }
  241. X    }
  242. X    mvwprintw(dipw, LINES-4, 4,
  243. X      "[c]hange diplomacy status, [<]/[,] previous page, [>]/[.] next page");  
  244. X    mvwprintw(dipw, LINES-3, 4,
  245. X      "    Other reports: [i]nfo, [b]udget, [p]roduction, [n]ations ");
  246. X    wrefresh(dipw);    /* update the window, always before input */
  247. X
  248. X    switch (c = getch()) {
  249. X    case ' ':
  250. X    case 'i':
  251. X    case 'b':
  252. X    case 'p':
  253. X    case 'n':
  254. X      done = 1;
  255. X      break;
  256. X    case '.':
  257. X    case '>':
  258. X      if (first_shown + n_shown < world.n_nations) {
  259. X    first_shown += n_shown;
  260. X      }
  261. X      break;
  262. X    case ',':
  263. X    case '<':
  264. X      if (first_shown > 1) {
  265. X    first_shown -= n_shown;
  266. X      }
  267. X      break;
  268. X    case 'c':
  269. X        /* allow to change status */
  270. X      mvwprintw(dipw, LINES-3, 3, "TO WHAT NATION: ");
  271. X      wclrtoeol(dipw);
  272. X      wget_number(dipw, &neigh_id);
  273. X      if (!(have_met(dm, nation->id, neigh_id)) && user.id != 0) {
  274. X    mvwprintw(dipw, LINES-4, 3, "Have not met that nation yet!!!");
  275. X    mvwprintw(dipw, LINES-3, 3, "--- hit space to continue ---");
  276. X    wrefresh(dipw);    /* update the window, always before input */
  277. X    get_space();
  278. X    wrefresh(dipw);    /* update the window, always before input */
  279. X      } else if (diplo_is_locked()) {
  280. X    statline2_err("Sorry, someone writing diplomacy file.", "hit space");
  281. X      } else {
  282. X    change_dip_status(dm, initial_dm, nation->id, neigh_id);
  283. X    dump_diplo(nation, dm, world.n_nations);
  284. X    touchwin(dipw);
  285. X    wrefresh(dipw);    /* update the window, always before input */
  286. X      }
  287. X      break;
  288. X    default:
  289. X      bad_key();
  290. X      break;
  291. X    } /* end of switch (c) statement */
  292. X  }   /* end of while(done ==0) loop */
  293. X  
  294. X  delwin(dipw);
  295. X/*  touch_all_wins();
  296. X  refresh();
  297. X */
  298. X  return c;
  299. X}
  300. X
  301. Xchange_dip_status(dm, initial_dm, n1, n2)
  302. X     Sdiplo **dm, **initial_dm;
  303. X     int n1, n2;
  304. X{
  305. X  char cc;
  306. X  int i,               /* for loops... */
  307. X  New_St,              /* input for new status */
  308. X  ind1=0, ind2=0;      /* indices of nations in array... */
  309. X  WINDOW *chng_dipw;
  310. X  
  311. X  chng_dipw = newwin((LINES-3), (COLS/2), 3, (COLS/2));
  312. X  touchwin(chng_dipw);
  313. X  mvwprintw(chng_dipw, 0,3, "NEW STATUS");
  314. X  mvwprintw(chng_dipw, 1,3, "==========");
  315. X  for (i=JIHAD; i<= TREATY; i++) {
  316. X    mvwprintw(chng_dipw, i,3, "[%c]. %s", dip_status[i][0], dip_status[i] );  
  317. X  }      
  318. X  mvwprintw(chng_dipw, i+1, 3, "Enter new status: ");
  319. X  wrefresh(chng_dipw);    /* update the window, always before input */
  320. X/*  wget_number(chng_dipw, &New_St); */
  321. X
  322. X  cc = getch();            /* we want the first char of a status */
  323. X  if (cc > 'Z') {
  324. X    cc -= ('a'-'A');        /* go to upper case */
  325. X  }
  326. X
  327. X  for (New_St = JIHAD; New_St <= TREATY; New_St++) {
  328. X    if (dip_status[New_St][0] == cc)
  329. X      break;
  330. X  }
  331. X  
  332. X/*  New_St++;   /* to compensate for numbers shown on screen */
  333. X  if ((New_St < JIHAD) || (New_St > TREATY)) {
  334. X    mvwprintw(chng_dipw, i+2, 3, "Illegal Input!");
  335. X    mvwprintw(chng_dipw, i+3, 3,"--- hit space to continue ---");
  336. X    wrefresh(chng_dipw);    /* update the window, always before input */
  337. X    get_space();
  338. X  } else if (user.id != 0 && abs(New_St - initial_dm[n1][n2].status) > 2) {
  339. X    mvwprintw(chng_dipw, i+2, 3, "Can't change so much!!");
  340. X    mvwprintw(chng_dipw, i+3, 3,"--- hit space to continue ---");
  341. X    wrefresh(chng_dipw);    /* update the window, always before input */
  342. X    get_space();
  343. X  } else {
  344. X    /* make the change in status!!! */
  345. X    while(n1 != dm[ind1++][0].self_id)
  346. X      ;
  347. X    ind1--;
  348. X    while(n2 != dm[ind1][ind2++].neighbor_id)
  349. X      ;
  350. X    ind2--;
  351. X    dm[ind1][ind2].status = New_St;
  352. X
  353. X    mvwprintw(chng_dipw, i+2, 3, "The change has been made.");
  354. X    mvwprintw(chng_dipw, i+3, 3,"--- hit space to continue ---");
  355. X    wrefresh(chng_dipw);    /* update the window, always before input */
  356. X    get_space();
  357. X  }
  358. X
  359. X  wrefresh(chng_dipw);     /* update the window, always before input */
  360. X  
  361. X  delwin(chng_dipw);
  362. X/*  touch_all_wins();
  363. X  refresh();
  364. X */
  365. X}
  366. X
  367. END_OF_FILE
  368. if test 8211 -ne `wc -c <'diplomacy.c'`; then
  369.     echo shar: \"'diplomacy.c'\" unpacked with wrong size!
  370. fi
  371. # end of 'diplomacy.c'
  372. fi
  373. if test -f 'mail.c' -a "${1}" != "-c" ; then 
  374.   echo shar: Will not clobber existing file \"'mail.c'\"
  375. else
  376. echo shar: Extracting \"'mail.c'\" \(8487 characters\)
  377. sed "s/^X//" >'mail.c' <<'END_OF_FILE'
  378. X  /* mail.c -- dominion mail system */
  379. X
  380. X/*
  381. X * Copyright (C) 1990 Free Software Foundation, Inc.
  382. X * Written by the dominion project.
  383. X *
  384. X * This file is part of dominion.
  385. X *
  386. X * dominion is free software; you can redistribute it and/or
  387. X * modify it under the terms of the GNU General Public License as published
  388. X * by the Free Software Foundation; either version 1, or (at your option)
  389. X * any later version.
  390. X *
  391. X * This software is distributed in the hope that it will be useful,
  392. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  393. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  394. X * GNU General Public License for more details.
  395. X *
  396. X * You should have received a copy of the GNU General Public License
  397. X * along with this software; see the file COPYING.  If not, write to
  398. X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  399. X */
  400. X
  401. X#include "dominion.h"
  402. X#include <stdio.h>
  403. X#ifdef AMIGA
  404. X# include <exec/types.h>
  405. X# include <string.h>
  406. X#else
  407. X# include <sys/types.h>
  408. X#endif
  409. X
  410. X#include <time.h>
  411. X#ifdef SYSV
  412. X# include <string.h>
  413. X#else
  414. X# include <strings.h>
  415. X#endif
  416. X
  417. Xextern Suser user;
  418. Xextern Sworld world;
  419. Xextern char *libdir;
  420. Xextern int ruid, euid;
  421. Xextern char *get_char_option();
  422. X
  423. Xchar *mail_forwarding(nation)
  424. X     int nation;
  425. X{
  426. X  return get_char_option(nation,"MAIL_FORWARD");
  427. X}
  428. X
  429. X  /* This function checks if mailbox for nation 'id' is locked. */
  430. Xhas_mail_lock(id)
  431. X     int id;
  432. X{
  433. X  FILE *lock_fp;
  434. X  char lock_fn[PATHLEN];
  435. X  int ret;
  436. X
  437. X/*  ruid = getuid();
  438. X  euid = geteuid();
  439. X*/
  440. X  if (mail_forwarding(id))
  441. X      return 0;
  442. X
  443. X  sprintf(lock_fn,"%s/%d.lock", MAIL_DIR, id);
  444. X    /* if it's locked: close and return 1 */
  445. X  if ((lock_fp = fopen(lock_fn, "r")) != NULL) {
  446. X    fclose(lock_fp);
  447. X    ret=1;
  448. X  } else {
  449. X    ret=0;
  450. X  }
  451. X  return(ret);
  452. X} /* has_mail_lock */
  453. X
  454. X  /* This function locks a user's mailbox */
  455. Xlock_mail(nation)
  456. Xint nation;
  457. X{
  458. X  FILE *lock_fp;
  459. X  char lock_fn[100];
  460. X  
  461. X  if (mail_forwarding(nation))
  462. X      return;
  463. X
  464. X  sprintf(lock_fn, "%s/%d.lock", MAIL_DIR, nation);
  465. X  if ((lock_fp = fopen(lock_fn, "w")) != NULL) {
  466. X      fprintf(lock_fp, "%ld; Nation %s\n", time(0L), user.np->name);
  467. X      fclose(lock_fp);
  468. X    }
  469. X}
  470. X
  471. X  /* This unlock's a user's mailbox */
  472. Xunlock_mail(nation)
  473. Xint nation;
  474. X{
  475. X  char lock_fn[100];
  476. X  
  477. X  if (mail_forwarding(nation))
  478. X      return;
  479. X
  480. X  sprintf(lock_fn, "%s/%d.lock", MAIL_DIR, nation);
  481. X  unlink(lock_fn);
  482. X}
  483. X
  484. X  /* This calls the system to edit the given file with the preferred editor */
  485. Xvoid edit(t_fn)
  486. X     char *t_fn;
  487. X{
  488. X  int tmp;
  489. X  char *edit_prog, *getenv();
  490. X  char edit_command[200], command[200];
  491. X
  492. X  if ((edit_prog=getenv("DOMINION_EDITOR"))==NULL
  493. X      && (edit_prog = getenv("VISUAL")) == NULL
  494. X      && (edit_prog = getenv("EDITOR")) == NULL) {
  495. X      edit_prog = DEFAULT_EDITOR;
  496. X    }
  497. X#ifdef UID_SECURITY
  498. X    /* we must fork, so that in the child we set the
  499. X       real user id, whereas the parent continues with
  500. X       the effective user id.
  501. X     */
  502. X  if (fork() == 0) {        /* child has fork() == 0 */
  503. X    setuid(ruid);        /* so this user cannot poke around */
  504. X    close(creat(t_fn, 0600));
  505. X    sprintf(edit_command, "%s %s", edit_prog, t_fn);
  506. X    system(edit_command);
  507. X    /* change owner so that it can be processed once the uid changes back */
  508. X/*
  509. X    sprintf(command, "chown %d %s", euid, t_fn);
  510. X    system(command);
  511. X*/
  512. X    chown(t_fn, euid, getgid()); /* use the system call to chown() */
  513. X/*
  514. X    printf("waiting; type a few returns\n");
  515. X    fflush(stdout);
  516. X    getchar();
  517. X    getchar();
  518. X*/
  519. X    exit(0);
  520. X  }
  521. X  wait(0);
  522. X#else /* UID_SECURITY */
  523. X  creat(t_fn, 0666);
  524. X  sprintf(command, "chmod 666 %s", t_fn);
  525. X  system(command);
  526. X  sprintf(edit_command, "%s %s", edit_prog, t_fn);
  527. X  system(edit_command);
  528. X#endif /* UID_SECURITY */
  529. X}
  530. X
  531. X/* Insert a file (with the name in_name) into the open file stream pointed
  532. X   to by out_pntr */
  533. Xvoid insert(in_name, out_pntr)
  534. X     char *in_name;
  535. X     FILE *out_pntr;
  536. X{
  537. X  FILE *in_pntr;
  538. X  int c;
  539. X
  540. X  if ((in_pntr=fopen(in_name, "r"))!=NULL)
  541. X    {
  542. X      while((c=fgetc(in_pntr))!=EOF)
  543. X    fputc(c, out_pntr);
  544. X      fclose(in_pntr);
  545. X    }
  546. X} /* insert */
  547. X
  548. X
  549. Xchar *fix_name(s,fixed)
  550. X/* Elm and etc. want the name that mail is from to contain no white space */
  551. Xchar *s,*fixed;
  552. X{
  553. X  char *poss = s, *posf = fixed;
  554. X
  555. X  if (s == NULL) { return NULL; }
  556. X  for ( poss = s;(poss != '\0') && (posf - fixed < NAMELEN);  poss++ , posf++)
  557. X  {
  558. X    if ((*poss == ' ') || (*poss == '\t'))
  559. X    {
  560. X      *posf = '_';
  561. X    } else
  562. X    {
  563. X      *posf = *poss;
  564. X    }
  565. X  }
  566. X  if (posf - fixed < NAMELEN) { *posf = '\0' ; }
  567. X  else { *(fixed + NAMELEN - 1) = '\0'; }
  568. X  return fixed;
  569. X}
  570. X/* Send mail from one nation to another. mailfile is the _name_ of the
  571. X   file containing the body of the mail. sender and receiver are the full
  572. X   names of the appropriate nations. Guess what subject is... */
  573. X
  574. Xint mail_send(mailfile, sender, receiver, subject)
  575. X     char mailfile[];
  576. X     int sender, receiver;
  577. X     char subject[];
  578. X{
  579. X  time_t now_secs;
  580. X  char lock_fn[200], dest_fn[200], tmp_fname[PATHLEN], *now_chars;
  581. X  FILE *lock_fp, *dest_fp, *temp_fp;
  582. X  char s_name[NAMELEN], r_name[NAMELEN];
  583. X  int temp;
  584. X  char *forward, fixed_name[NAMELEN];
  585. X
  586. X  if ((forward = get_char_option(receiver,"MAIL_FORWARD")) != NULL) {
  587. X      char command[2048];
  588. X#ifdef UID_SECURITY
  589. X      int pid;
  590. X#endif
  591. X
  592. X      strcpy(tmp_fname, "/usr/tmp/domXXXXXX");
  593. X      mktemp(tmp_fname);
  594. X      temp_fp = fopen(tmp_fname, "w");
  595. X      if (!temp_fp) {
  596. X      perror("Could not open temp file");
  597. X      return 1;
  598. X      }
  599. X      fprintf(temp_fp,"From: %s of %s\n",world.nations[sender].leader,
  600. X          world.nations[sender].name);
  601. X      fprintf(temp_fp,"To: %s of %s\n",world.nations[receiver].leader,
  602. X          world.nations[receiver].name);
  603. X      fprintf(temp_fp,"Subject: %s\n\n",subject);
  604. X      fclose(temp_fp);
  605. X
  606. X#ifdef UID_SECURITY
  607. X      sprintf(command, "chmod +r %s", tmp_fname);
  608. X      system(command);
  609. X#endif
  610. X
  611. X      sprintf(command, "cat %s %s | %s '%s'", tmp_fname, mailfile,
  612. X                          MAILER, forward);
  613. X
  614. X/*
  615. X      printf("\r\n ready to run the cat command; type some returns \r\n");
  616. X      fflush(stdout);
  617. X      getchar();
  618. X      getchar();
  619. X*/
  620. X      system(command);
  621. X#ifdef CONFUSED_UID
  622. X#ifdef UID_SECURITY
  623. X      /* we must fork, so that in the child we set the
  624. X     real user id, whereas the parent continues with
  625. X     the effective user id.
  626. X       */
  627. X
  628. X      if ((pid=fork()) == 0) {        /* child has fork() == 0 */
  629. X      setuid(getuid());        /* so this user cannot poke around */
  630. X#endif
  631. X      system(command);
  632. X#ifdef UID_SECURITY
  633. X      exit(0);
  634. X      }
  635. X/*      else if (pid < 0)
  636. X      perror("Could not fork mailer");
  637. X      else
  638. X      while (wait(0) != pid);
  639. X*/
  640. X      wait(0);
  641. X#endif /* UID_SECURITY */
  642. X#endif /* CONFUSED_UID */
  643. X
  644. X      unlink(tmp_fname);
  645. X      return 0;            /* we've forwarded, so that's all */
  646. X  }
  647. X
  648. X  /* Set the names of the files used in mail */
  649. X  sprintf(dest_fn, "%s/mail.%d", MAIL_DIR, receiver);
  650. X
  651. X/*  sprintf(lock_fn, "%d.lock", receiver); */
  652. X  strcpy(tmp_fname, "dommaXXXXXX");
  653. X  mktemp(tmp_fname);
  654. X
  655. X    /* Get the time right now */
  656. X  now_secs=time(0L);
  657. X  now_chars=ctime(&now_secs);
  658. X
  659. X    /* If not make sure it won't be used */
  660. X/*  lock_fp=fopen(lock_fn, "w");
  661. X  fprintf(lock_fp, "Mail being sent by %s at %s\n", user.np->name, now_chars);
  662. X  fclose(lock_fp);
  663. X*/
  664. X
  665. X    /* Copy the mail that's there right now out */
  666. X  if ((temp_fp = fopen(tmp_fname, "w")) == NULL) { 
  667. X    fprintf(stderr,"Error: Cannot write to mail file %s\n",tmp_fname);
  668. X    clean_exit();
  669. X    exit(1);
  670. X  }
  671. X  insert(dest_fn, temp_fp);
  672. X  fclose(temp_fp);
  673. X    /* Put in the new mail */
  674. X  if ((dest_fp=fopen(dest_fn, "w"))!=NULL) {
  675. X       /* Some header stuff */
  676. X      fix_name(world.nations[sender].leader, fixed_name);
  677. X      fprintf(dest_fp, "From %s %s", fixed_name,now_chars);
  678. X      fprintf(dest_fp, "Date: %s", now_chars);
  679. X      fprintf(dest_fp, "From: %s of %s\n", world.nations[sender].leader,
  680. X          world.nations[sender].name);
  681. X      fprintf(dest_fp, "To: %s of %s\n", world.nations[receiver].leader,
  682. X          world.nations[receiver].name);
  683. X      fprintf(dest_fp, "Subject: %s\n\n", subject);
  684. X
  685. X        /* Now the body of the message */
  686. X      insert(mailfile, dest_fp);
  687. X      fprintf(dest_fp, "\n");
  688. X        /* and now copy the old mail back in */
  689. X      insert(tmp_fname, dest_fp);
  690. X      fclose(dest_fp);
  691. X    } /* if fopen dest_fp */
  692. X  else {
  693. X    if (sender==0) {
  694. X      fprintf(stderr, "Couldn't open dest_fn\n");
  695. X    }
  696. X  }
  697. X    /* Remove the old unnecessary files */
  698. X  unlink(tmp_fname);
  699. X  unlink(mailfile);
  700. X/*  unlink(lock_fn); */
  701. X  unlock_mail(receiver);
  702. X  return(0);
  703. X} /* mail_send */
  704. X
  705. END_OF_FILE
  706. if test 8487 -ne `wc -c <'mail.c'`; then
  707.     echo shar: \"'mail.c'\" unpacked with wrong size!
  708. fi
  709. # end of 'mail.c'
  710. fi
  711. if test -f 'misc.h' -a "${1}" != "-c" ; then 
  712.   echo shar: Will not clobber existing file \"'misc.h'\"
  713. else
  714. echo shar: Extracting \"'misc.h'\" \(8037 characters\)
  715. sed "s/^X//" >'misc.h' <<'END_OF_FILE'
  716. X /* misc.h - various definitions used in dominion */
  717. X
  718. X/*
  719. X * Copyright (C) 1990 Free Software Foundation, Inc.
  720. X * Written by the dominion project.
  721. X *
  722. X * This file is part of dominion.
  723. X *
  724. X * dominion is free software; you can redistribute it and/or
  725. X * modify it under the terms of the GNU General Public License as published
  726. X * by the Free Software Foundation; either version 1, or (at your option)
  727. X * any later version.
  728. X *
  729. X * This software is distributed in the hope that it will be useful,
  730. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  731. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  732. X * GNU General Public License for more details.
  733. X *
  734. X * You should have received a copy of the GNU General Public License
  735. X * along with this software; see the file COPYING.  If not, write to
  736. X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  737. X */
  738. X
  739. X  /* get the control char corresponding to the *upper case*
  740. X     char c.  Note:  will probably only work for ascii.
  741. X   */
  742. X#define CTL(c) (c - 'A' + 1)
  743. X  /* the DELETE key */
  744. X#define DEL ((char) 0x7F)
  745. X
  746. X#ifdef BSD
  747. X# define SRND(x) srandom(x)
  748. X# define RND() random()
  749. X# define strchr(a, b) index(a, b)
  750. X#endif BSD
  751. X
  752. X#ifdef SYSV
  753. X# define SRND(x) srand48(x)
  754. X# define RND() lrand48()
  755. X#endif SYSV
  756. X
  757. X/* Figuring in cur_ stuff. */
  758. X#define cur_expend(np) (((np->cur_tech_r_d + np->cur_mag_r_d + np->cur_spy_r_d) * np->money) / 100)
  759. X#define cur_expend_metal(np) ((np->cur_tech_r_d_metal * np->metal) / 100)
  760. X#define cur_expend_jewels(np) ((np->cur_mag_r_d_jewels * np->jewels) / 100)
  761. X
  762. X#define next_thon_money(np) ((np->money - cur_expend(np)) + (calc_revenue(np) - calc_expend(np)))
  763. X#define next_thon_metal(np) ((np->metal - cur_expend_metal(np)) + (calc_metal (np) - calc_expend_metal(np)))
  764. X#define next_thon_jewels(np) ((np->jewels - cur_expend_jewels(np)) + (calc_jewels (np) - calc_expend_jewels(np)))
  765. X
  766. X  /* the number of good workers in a sector */
  767. X/* #define n_workers(sp) (min(sp->n_people, (world.nations[sp->owner].race.repro*desig_map[sp->designation].max_employed)/10)) */
  768. X
  769. X#define SALT ".."
  770. X
  771. X  /* sector flags */
  772. X#define SF_BUBBLE 0x01        /* a bubble has been built */
  773. X#define SF_QUARANTINE 0x02    /* people cannot migrate */
  774. X#define SF_HIDDEN 0x04        /* sector is cloaked */
  775. X#define SF_TRADED 0x08        /* sector has been traded */
  776. X#define SF_IMPENETRABLE 0x10    /* sector is impenetrable */
  777. X#define SF_HOSTILE 0x20            /* sector is hostile */
  778. X
  779. X  /* routines that check sector flags */
  780. X#define has_bubble(sp) (sp->flags & SF_BUBBLE)
  781. X#define has_quarantine(sp) (sp->flags & SF_QUARANTINE)
  782. X#define has_hidden(sp) (sp->flags & SF_HIDDEN)
  783. X#define has_traded(sp) (sp->flags & SF_TRADED)
  784. X#define has_impenetrable(sp) (sp->flags & SF_IMPENETRABLE)
  785. X#define has_hostile(sp) (sp->flags & SF_HOSTILE)
  786. X
  787. X  /* this is to hide the absolute coordinates from a user */
  788. X/* #define xrel(a) (user.nation.id == 0 ? a : a - user.nation.capital.x)
  789. X#define yrel(b) (user.nation.id == 0 ? b : b - user.nation.capital.y)
  790. X*/
  791. X  /* definitions for sector visibility:  this is a bit-field */
  792. X#define SEE_NOTHING    0x00    /* not on your map at all */
  793. X#define SEE_LAND_WATER 0x01    /* see if it is land or water */
  794. X#define SEE_OWNER      0x02
  795. X#define SEE_DESIG      0x04
  796. X#define SEE_POPULATION 0x08
  797. X#define SEE_RESOURCES  0x10    /* see what metal etc... are there */
  798. X#define SEE_ARMIES     0x20
  799. X#define SEE_ALL        0xff    /* see everything (all bits set) */
  800. X
  801. X                                /* Terrains */
  802. X#define MIN_TERRAIN  -5
  803. X#define JUNGLE        6
  804. X#define FOREST        5         /* Terrain describes how the land looks to */
  805. X#define BRUSH         4         /* the creatures on or around it. */
  806. X#define GRASSLANDS    3
  807. X#define SWAMP         2
  808. X#define BARREN        1
  809. X#define ICE           0
  810. X#define RIVER        -1
  811. X#define LAKE         -2
  812. X#define REEF         -3
  813. X#define BAY          -4
  814. X#define OCEAN        -5
  815. X                                /* Altitudes by */
  816. X#define MOUNTAIN_PEAK 6         
  817. X#define MOUNTAINS     5         /* Altitudes describe the height or depth of */
  818. X#define PLATEAU       4         /* the land on the specified sector. */
  819. X#define HILLS         3         
  820. X#define PLAINS        2         
  821. X#define LOWLANDS      1         
  822. X#define SEA_LEVEL     0         
  823. X#define SHALLOWS     -1
  824. X#define CONT_SHELF   -2
  825. X#define SEA_MOUNT    -3
  826. X#define OCEAN_PLAINS -4
  827. X#define TRENCH       -5
  828. X
  829. X  /* possible sector designations */
  830. X#define D_NODESIG     0        /* designations */
  831. X/*#define D_RUIN        1 */
  832. X#define D_FARM        1
  833. X#define D_METAL_MINE  2
  834. X#define D_JEWEL_MINE  3
  835. X#define D_CITY        4        /* can draft and build; heavy tax */
  836. X#define D_CAPITAL     5        /* nation's capital; even more tax */
  837. X#define D_UNIVERSITY  6        /* increase intelligence (costs to maintain) */
  838. X#define D_TEMPLE      7        /* religion: + morale */
  839. X#define D_STADIUM     8        /* entertainment: + morale */
  840. X#define D_TRADE_POST  9        /* in foreign land: allows trade */
  841. X#define D_EMBASSY    10        /* in foreign land: allows diplo */
  842. X#define D_FORT       11        /* must have a garrison */
  843. X#define D_HOSPITAL   12        /* decrease death rate (costs to maintain) */
  844. X#define D_REFINERY   13        /* put next to a mine, > production */
  845. X#define D_MAX_DESIG  D_REFINERY+1 /* the biggest designation number + 1 */
  846. X/* #define D_MAX_DESIG (sizeof(desig_map)/sizeof(s_desig_map)) */
  847. X#define FORT_BONUS_INCREASE 3    /* how much bonus for passing time in forts */
  848. X
  849. X  /* army_type is used for the general description of
  850. X     armies, and is loaded at the beginning of a session
  851. X     from the file ("army_types")
  852. X   */
  853. Xstruct army_type {
  854. X  char type[NAMELEN];        /* such as "Infantry" */
  855. X  char type_char;        /* could be 'i' for Infantry */
  856. X  float move_factor;        /* multiplies the nation's basic move rate */
  857. X    /* should we have separate attack and defense bonus? */
  858. X  int bonus;            /* added to nation's basic bonus */
  859. X    /* the following describe how much it costs to draft a
  860. X       SINGLE soldier of this type, and maintain it, except in
  861. X       the case of spell points, where it is the price for the
  862. X       ENTIRE army.
  863. X     */
  864. X  int money_draft, metal_draft, jewel_draft;
  865. X  int money_maint, metal_maint, jewel_maint, spell_pts_maint;
  866. X  int flags;            /* permanent flags */
  867. X  char draft_places [NAMELEN];
  868. X};
  869. X
  870. X  /* spirit_type is used for the general description of
  871. X     armies, and is loaded at the beginning of a session
  872. X     from the file ("spirit_types")
  873. X   */
  874. Xstruct spirit_type {
  875. X  char type[NAMELEN];        /* such as "eagle" */
  876. X  char type_char;        /* could be 'E' for eagle */
  877. X  int size;            /* how many "men" */
  878. X  float move_factor;        /* multiplies the nation's basic move rate */
  879. X    /* should we have separate attack and defense bonus? */
  880. X  int bonus;            /* added to nation's basic bonus */
  881. X    /* the following describe how much it costs to draft a
  882. X       SINGLE soldier of this type, and maintain it, except in
  883. X       the case of spell points, where it is the price for the
  884. X       ENTIRE army.  The "flags" field is for permanenty army-type
  885. X       flags.
  886. X     */
  887. X  int spell_pts_draft, jewel_draft, jewel_maint;
  888. X  int flags;
  889. X};
  890. X
  891. X  /* this describes the various types of designation, that their mark
  892. X     is, their name, and how much it costs to redesignate to that.  in
  893. X     future we might put a general description of designations, and
  894. X     also a per-turn cost.
  895. X   */
  896. Xstruct s_desig_map {
  897. X  char mark;
  898. X  char *name;
  899. X  int price;            /* how much it costs to redesignate */
  900. X  int revenue;            /* per capita revenue in sector */
  901. X  int min_employed;        /* how many you need to function */
  902. X  int max_employed;        /* how many can be gainfully employed? */
  903. X};
  904. X
  905. Xstruct s_altitude_map {
  906. X  char mark;
  907. X  char *name;
  908. X  int value;
  909. X};
  910. X
  911. Xstruct army_flags {
  912. X  char flag;
  913. X  char description [EXECLEN];
  914. X};
  915. X
  916. X  /* diplomacy statuses */
  917. X#define SELF          0
  918. X#define UNMET         1
  919. X#define JIHAD         2
  920. X#define WAR           3
  921. X#define HOSTILE       4
  922. X#define UNRECOGNIZED  5
  923. X#define NEUTRAL       6
  924. X#define RECOGNIZED    7
  925. X#define FRIENDLY      8
  926. X#define ALLIED        9
  927. X#define TREATY        10
  928. X
  929. Xstruct item_map { char mark; char *name; }; /* for many things */
  930. END_OF_FILE
  931. if test 8037 -ne `wc -c <'misc.h'`; then
  932.     echo shar: \"'misc.h'\" unpacked with wrong size!
  933. fi
  934. # end of 'misc.h'
  935. fi
  936. if test -f 'spy.c' -a "${1}" != "-c" ; then 
  937.   echo shar: Will not clobber existing file \"'spy.c'\"
  938. else
  939. echo shar: Extracting \"'spy.c'\" \(8899 characters\)
  940. sed "s/^X//" >'spy.c' <<'END_OF_FILE'
  941. X  /* spy.c -- things having to do with "other" nations and espionage */
  942. X
  943. X/*
  944. X * Copyright (C) 1990 Free Software Foundation, Inc.
  945. X * Written by the dominion project.
  946. X *
  947. X * This file is part of dominion.
  948. X *
  949. X * dominion is free software; you can redistribute it and/or
  950. X * modify it under the terms of the GNU General Public License as published
  951. X * by the Free Software Foundation; either version 1, or (at your option)
  952. X * any later version.
  953. X *
  954. X * This software is distributed in the hope that it will be useful,
  955. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  956. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  957. X * GNU General Public License for more details.
  958. X *
  959. X * You should have received a copy of the GNU General Public License
  960. X * along with this software; see the file COPYING.  If not, write to
  961. X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  962. X */
  963. X
  964. X#include "dominion.h"
  965. X#include "misc.h"
  966. X#include <stdio.h>
  967. X#include <ctype.h>
  968. X#include <math.h>
  969. X
  970. X  /* these macros represent the difficulty in gathering
  971. X     inteligence in various areas.
  972. X   */
  973. X#define SPY_POP 1
  974. X#define SPY_ECO 3
  975. X#define SPY_MAG 4
  976. X#define SPY_MIL 5
  977. X#define SPY_TECHNO 5
  978. X#define SPY_CAP 6
  979. X
  980. Xextern Sworld world;
  981. Xextern Suser user;
  982. Xextern char help_tag[];
  983. X
  984. X  /* info on all nations in the world */
  985. Xchar nations_report()
  986. X{
  987. X  WINDOW *w;
  988. X  FILE *diplock;
  989. X  char s[200];
  990. X  Snation *np;
  991. X  char c;
  992. X  int i, done = 0, first_shown, n_shown, id;
  993. X
  994. X  w = newwin(LINES-2, COLS, 0, 0); /* full screen */
  995. X  werase(w);
  996. X  touchwin(w);
  997. X  sprintf(s, "report on all nations");
  998. X  wmove(w, 0, (COLS-strlen(s))/2); /* make the string centered */
  999. X  wstandout(w);
  1000. X  waddstr(w, s);
  1001. X  wclrtoeol(w);
  1002. X  wstandend(w);
  1003. X
  1004. X    /* here go the guts */
  1005. X  sprintf(s,"World size is: %dx%d, there are %d nations",
  1006. X        world.xmax, world.ymax, world.n_nations);
  1007. X  wmove(w, 1, (COLS-strlen(s))/2); /* make the string centered */
  1008. X  waddstr(w, s);
  1009. X  mvwaddstr(w, 3, 0, " id");
  1010. X  mvwaddstr(w, 4, 0, "---");
  1011. X  mvwaddstr(w, 3, 5, "nation");
  1012. X  mvwaddstr(w, 4, 5, "------");
  1013. X  mvwaddstr(w, 3, 25, "mark");
  1014. X  mvwaddstr(w, 4, 25, "----");
  1015. X  mvwaddstr(w, 3, 31, "leader");
  1016. X  mvwaddstr(w, 4, 31, "------");
  1017. X  mvwaddstr(w, 3, 47, "race");
  1018. X  mvwaddstr(w, 4, 47, "----");
  1019. X  if (user.id == 0) {
  1020. X    mvwaddstr(w, 3, 55, "money");
  1021. X    mvwaddstr(w, 4, 55, "-----");
  1022. X    mvwaddstr(w, 3, 65, "civil");
  1023. X    mvwaddstr(w, 4, 65, "-----");
  1024. X  }
  1025. X    /* figure out which nations to show */
  1026. X  first_shown = 1;
  1027. X  n_shown = min(world.n_nations, LINES-10);
  1028. X  while (!done) {
  1029. X    strcpy(help_tag, "Nations Report");
  1030. X    for (i = 0; i < n_shown && i+first_shown < world.n_nations; ++i) {
  1031. X      np = &(world.nations[i+first_shown]);
  1032. X      mvwprintw(w, i+5, 0, "%3d", np->id);
  1033. X      wclrtoeol(w);
  1034. X      mvwaddstr(w, i+5, 5, np->name);
  1035. X      mvwaddch(w, i+5, 26, np->mark);
  1036. X      sprintf(s,"%-12.12s",np->leader);
  1037. X      mvwaddstr(w, i+5, 31, s);
  1038. X
  1039. X      mvwaddstr(w, i+5, 47, np->race.name);
  1040. X
  1041. X      if (!is_active_ntn(np)) {
  1042. X    mvwaddstr(w, i+5, 60, "DESTROYED");
  1043. X      } else if (user.id == 0) {
  1044. X    mvwprintw(w, i+5, 55, "%d", np->money);
  1045. X    mvwprintw(w, i+5, 65, "%d", get_n_civil(np));
  1046. X      }
  1047. X      if (np->npc_flag) {
  1048. X    mvwaddstr(w, i+5, 75, "npc");
  1049. X      }
  1050. X    }
  1051. X    wclrtobot(w);
  1052. X    mvwaddstr(w, LINES-4, 4,
  1053. X   "Options: [s]py on a nation, [<]/[,] previous screen, [>]/[.] next screen");
  1054. X    mvwaddstr(w, LINES-3, 4,
  1055. X          "Reports: [b]udget, [p]roduction, [i]nfo, [d]iplomacy");
  1056. X    wrefresh(w);
  1057. X    statline("type space when done, or F to dump to a file", "nations_report");
  1058. X
  1059. X    switch (c = getch()) {
  1060. X    case '>':
  1061. X    case '.':
  1062. X      if (first_shown+n_shown < world.n_nations) {
  1063. X    first_shown += n_shown;
  1064. X      }
  1065. X      break;
  1066. X    case '<':
  1067. X    case ',':
  1068. X      if (first_shown > 1) {
  1069. X    first_shown -= n_shown;
  1070. X      }
  1071. X      break;
  1072. X    case 's':
  1073. X      mvwaddstr(w, LINES-3, 4, "  Number of nation to spy on? ");
  1074. X      wclrtoeol(w);
  1075. X      if (wget_number(w, &id) > 0 && is_active_ntn(&world.nations[id])
  1076. X      && id != user.np->id) {
  1077. X    if (user.id == 0) {    /* for the game master, give the total info */
  1078. X      (void) info_report(&world.nations[id]);
  1079. X    } else {
  1080. X      spy_report(id);
  1081. X    }
  1082. X    touchwin(w);
  1083. X      }
  1084. X      break;
  1085. X    case 'F':
  1086. X      dump_current_screen(w, "nations_report");
  1087. X      break;
  1088. X    case ' ':
  1089. X    case 'b':
  1090. X    case 'p':
  1091. X    case 'i':
  1092. X    case 'd':
  1093. X      done = 1;
  1094. X      break;
  1095. X    case '?':
  1096. X      online_info();
  1097. X      break;
  1098. X    default:
  1099. X      break;
  1100. X    }
  1101. X  }
  1102. X  delwin(w);
  1103. X  return c;
  1104. X}
  1105. X
  1106. X  /* allow a nation to spy on anther */
  1107. Xspy_report(id)
  1108. X     int id;
  1109. X{
  1110. X  WINDOW *spyw;
  1111. X  Snation *spied_np = &world.nations[id], *spying_np = user.np;
  1112. X  char s[EXECLEN];
  1113. X  char c;
  1114. X  int done = 0, bribe;        /* amount of jewels to get info */
  1115. X  int x, y;            /* for capital locations */
  1116. X
  1117. X  strcpy(help_tag, "Nations Report");
  1118. X  spyw = newwin(18, 60, LINES-22, (COLS-60)/2);
  1119. X  werase(spyw);
  1120. X  touchwin(spyw);
  1121. X  while (!done) {
  1122. X    sprintf(s, "Espionage Report on nation %s", spied_np->name);
  1123. X    wmove(spyw, 1, (60-strlen(s))/2);
  1124. X    wstandout(spyw);
  1125. X    waddstr(spyw, s);
  1126. X    wclrtoeol(spyw);
  1127. X    wstandend(spyw);
  1128. X    /* put the guts between here and the wrefresh() */
  1129. X    mvwaddstr(spyw, 3, 5, "Spy on: [p]opulation, [e]conomy");
  1130. X    mvwaddstr(spyw, 4, 5, "        [m]ilitary, ma[g]ic, [C]apital location");
  1131. X    mvwaddstr(spyw, 5, 5, "        [t]echology, [T]echnology theft");
  1132. X    wclrtobot(spyw);
  1133. X    box(spyw, '|', '-');
  1134. X    wrefresh(spyw);
  1135. X    statline("type space when done, or F to dump to a file", "spy_report");
  1136. X    c = getch();
  1137. X    if (strchr("pemgCt", c) != NULL) {
  1138. X      mvwaddstr(spyw, 10, 1,
  1139. X        "How many jewels do you want to pay in bribes? ");
  1140. X      if (wget_number(spyw, &bribe) < 1 || bribe <= 0) {
  1141. X    continue;
  1142. X      }
  1143. X      if (bribe > spying_np->jewels) {
  1144. X    statline2_err("Hit space", "You don't have enough jewels");
  1145. X    continue;
  1146. X      }
  1147. X    }
  1148. X    switch (c) {
  1149. X    case '?':
  1150. X      online_info();
  1151. X      break;
  1152. X    case ' ':
  1153. X      done = 1;
  1154. X      break;
  1155. X    case 'p':            /* info on their population */
  1156. X      mvwprintw(spyw, 12, 6, "Population is %d",
  1157. X        spy_figure(get_n_civil(spied_np), bribe,
  1158. X        spying_np, spied_np, SPY_POP) );
  1159. X      break;
  1160. X    case 'e':            /* info on their military */
  1161. X      mvwprintw(spyw, 12, 4, "Money: %d",
  1162. X        spy_figure(spied_np->money, bribe,
  1163. X        spying_np, spied_np, SPY_ECO) );
  1164. X      mvwprintw(spyw, 12, 20, "Jewels: %d",
  1165. X        spy_figure(spied_np->jewels, bribe,
  1166. X        spying_np, spied_np, SPY_ECO) );
  1167. X      mvwprintw(spyw, 12, 36, "Metal: %d",
  1168. X        spy_figure(spied_np->metal, bribe,
  1169. X        spying_np, spied_np, SPY_ECO) );
  1170. X      mvwprintw(spyw, 13, 4, "Food: %d",
  1171. X        spy_figure(spied_np->food, bribe,
  1172. X        spying_np, spied_np, SPY_ECO) );
  1173. X      mvwprintw(spyw, 13, 20, "Tax: %d",
  1174. X        spy_figure(spied_np->taxes, bribe,
  1175. X        spying_np, spied_np, SPY_ECO) );
  1176. X      break;
  1177. X    case 'C':
  1178. X      x = spy_figure(spied_np->capital.x, bribe, spying_np, spied_np, SPY_CAP);
  1179. X      y = spy_figure(spied_np->capital.y, bribe, spying_np, spied_np, SPY_CAP);
  1180. X      x = xrel(x, y, spying_np->capital);
  1181. X      y = yrel(x, y, spying_np->capital);
  1182. X      mvwprintw(spyw, 13, 4, "Capital is at (%d, %d) ", x, y);
  1183. X      break;
  1184. X    case 't':            /* info on their technology */
  1185. X      mvwprintw(spyw, 12, 4, "Techno skill: %d",
  1186. X        spy_figure(spied_np->tech_skill, bribe,
  1187. X        spying_np, spied_np, SPY_TECHNO) );
  1188. X      break;
  1189. X    case 'm':            /* info on their military */
  1190. X      mvwprintw(spyw, 12, 4, "Soldiers: %d",
  1191. X        spy_figure(get_n_soldiers(spied_np), bribe,
  1192. X        spying_np, spied_np, SPY_MIL) );
  1193. X      break;
  1194. X    case 'g':            /* info on their magic */
  1195. X      mvwprintw(spyw, 12, 4, "Magic skill: %d",
  1196. X        spy_figure(spied_np->mag_skill, bribe,
  1197. X        spying_np, spied_np, SPY_MAG) );
  1198. X      mvwprintw(spyw, 13, 4, "Spell pts.: %d",
  1199. X        spy_figure(spied_np->spell_pts, bribe,
  1200. X        spying_np, spied_np, SPY_MAG) );
  1201. X      break;
  1202. X    }
  1203. X        /* this section is common to all bribes */
  1204. X    if (strchr("pemgCt", c) != NULL) {
  1205. X      mvwaddstr(spyw, 14, 10, "Hit space");
  1206. X      wrefresh(spyw);
  1207. X      get_space();
  1208. X      spying_np->jewels -= bribe;
  1209. X      cjewels(spying_np, -bribe);
  1210. X    }
  1211. X  }
  1212. X  delwin(spyw);
  1213. X}
  1214. X
  1215. Xspy_figure(n, expend, spying_np, spied_np, cost_fact)
  1216. X     int n,            /* number we modify here */
  1217. X       expend;            /* jewels spent on bribes */
  1218. X     Snation *spying_np, *spied_np; /* nations involved */
  1219. X     int cost_fact;        /* cost factor for type of info */
  1220. X{
  1221. X  double accuracy, error;
  1222. X  int figure;            /* the figure we actually return */
  1223. X  char s[400];
  1224. X
  1225. X  if (spied_np->secrecy == 0) {
  1226. X    spied_np->secrecy = 1;    /* avoid divide-by-zero */
  1227. X  }
  1228. X  accuracy =
  1229. X    ((double) expend*spying_np->spy)/(cost_fact*spied_np->secrecy*100);
  1230. X  
  1231. X    /* now get the percent error */
  1232. X  error = 100*( exp(-sqrt(accuracy)) + 1.0/(5.0+accuracy) );
  1233. X  if (error > 100) {
  1234. X    error = 100;
  1235. X  }
  1236. X/*  sprintf(s, "acc=%f,%%err=%f", accuracy, error); */
  1237. X    /* now get the absolute error */
  1238. X  error = 1 + n*error/100.0;
  1239. X  figure = n + (RND() % ((int) error)) - (int) (error/2);
  1240. X
  1241. X/*  statline2(s, ""); */
  1242. X
  1243. X  return figure;
  1244. X}
  1245. END_OF_FILE
  1246. if test 8899 -ne `wc -c <'spy.c'`; then
  1247.     echo shar: \"'spy.c'\" unpacked with wrong size!
  1248. fi
  1249. # end of 'spy.c'
  1250. fi
  1251. if test -f 'user.c' -a "${1}" != "-c" ; then 
  1252.   echo shar: Will not clobber existing file \"'user.c'\"
  1253. else
  1254. echo shar: Extracting \"'user.c'\" \(10194 characters\)
  1255. sed "s/^X//" >'user.c' <<'END_OF_FILE'
  1256. X/* user.c -- stuff relating to the "current user" */
  1257. X
  1258. X/*
  1259. X * Copyright (C) 1990 Free Software Foundation, Inc.
  1260. X * Written by the dominion project.
  1261. X *
  1262. X * This file is part of dominion.
  1263. X *
  1264. X * dominion is free software; you can redistribute it and/or
  1265. X * modify it under the terms of the GNU General Public License as published
  1266. X * by the Free Software Foundation; either version 1, or (at your option)
  1267. X * any later version.
  1268. X *
  1269. X * This software is distributed in the hope that it will be useful,
  1270. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1271. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1272. X * GNU General Public License for more details.
  1273. X *
  1274. X * You should have received a copy of the GNU General Public License
  1275. X * along with this software; see the file COPYING.  If not, write to
  1276. X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  1277. X */
  1278. X
  1279. X#include <stdio.h>
  1280. X#ifdef SYSV
  1281. X# include <string.h>
  1282. X#else
  1283. X# include <strings.h>
  1284. X#endif /* SYSV */
  1285. X#include <time.h>
  1286. X
  1287. X#include "dominion.h"
  1288. X#include "misc.h"
  1289. X
  1290. Xextern Suser user;
  1291. Xextern Sworld world;
  1292. Xextern int debug;
  1293. Xextern int (*wrapx)(), (*wrapy)();
  1294. Xextern int viewall;
  1295. Xextern double get_version(),atof();
  1296. Xextern char *update_time, *get_update_time(), *mail_forwarding(),*civ_move[];
  1297. X
  1298. Xvoid usageerr(argc, argv)
  1299. Xint argc;
  1300. Xchar *argv[]; 
  1301. X{
  1302. X  fprintf(stderr, "usage: %s -[n nation] [-d dir] [-x] [-h] [-p] [-c]\n", argv[0]);
  1303. X}
  1304. X
  1305. X  /* initializes the user's data structure, and does
  1306. X     other tasks concerned with loading up the game
  1307. X   */
  1308. Xinit_user(innation, nation)
  1309. X     int innation;        /* do we have a nation name already? */
  1310. X     char nation[];        /* pre-entered nation name */
  1311. X{
  1312. X  char passwd[NAMELEN];
  1313. X  char *s, *getpass(), *crypt();
  1314. X  int c;
  1315. X  char syscmd[NAMELEN];
  1316. X  int i;
  1317. X  Sdiplo **allocate_diplo();
  1318. X
  1319. X  printf("initializing user...\r\n");
  1320. X  load_army_types();
  1321. X  load_spirit_types();
  1322. X    /* in case the master changed your password */
  1323. X  load_master_execs();
  1324. X  if (!innation)
  1325. X    {
  1326. X      printf("which nation would you like to play? ");
  1327. X      getline(nation, NAMELEN);
  1328. X    }
  1329. X  if ((user.id = get_nation_id(nation)) == -1) {
  1330. X    printf ("\r\nnation does not exist, sorry\r\n");
  1331. X    clean_exit ();
  1332. X    exit (1);
  1333. X  }
  1334. X  get_crypt_pass("Your nation's password: ", passwd, NULL, NULL);
  1335. X  if (strcmp(world.nations[user.id].passwd, passwd)) {
  1336. X    printf("\r\nTry again\r\n");
  1337. X    get_crypt_pass("Your nation's password: ", passwd, NULL, NULL);
  1338. X    user.id = get_nation_id(nation);
  1339. X    if (strcmp(world.nations[user.id].passwd, passwd)) {
  1340. X      printf("\r\nwrong password, sorry\r\n");
  1341. X      clean_exit();
  1342. X      exit(1);
  1343. X    }
  1344. X  }
  1345. X
  1346. X  handle_locks(user.id);
  1347. X
  1348. X  user.np = &world.nations[user.id];
  1349. X
  1350. X    /* now check to see if this nation has been destroyed */
  1351. X  if (user.np->capital.x == -1 && user.np->capital.y == -1) {
  1352. X    if (user.np->id == 0) {    /* nation 0 cannot be destroyed!!! */
  1353. X      user.np->capital.x = 0;
  1354. X      user.np->capital.y = 0;
  1355. X    } else {
  1356. X      printf("\r\nYour nation has been destroyed.\n");
  1357. X      printf("Ask your Gamemaster for your last mail.\n");
  1358. X      clean_exit();
  1359. X      exit(0);
  1360. X    }
  1361. X  }
  1362. X    /* find out which army types are available to the user */
  1363. X  user.avail_armies = NULL;
  1364. X  get_avail_armies(&user, user.np->tech_skill);
  1365. X    /* start the user off with all spells s/he deserves.
  1366. X       note that, because of spirits, this has to be done
  1367. X       before load_nation(), since the spirit list is used
  1368. X       in the exec parsing.
  1369. X     */
  1370. X  user.spell_list = NULL;
  1371. X  user.spirit_list = NULL;
  1372. X  get_spells(&user, user.np->mag_skill);
  1373. X  get_spirits(&user, user.np->mag_skill);
  1374. X    /* fundamental step:  load exec file */
  1375. X  if (user.id != 0) {        /* gamemaster is already loaded */
  1376. X    load_nation(user.id, user.np);
  1377. X  } else {
  1378. X    load_options(user.np);
  1379. X  }
  1380. X    /* now set fields for the ustruct */
  1381. X  user.cursor = user.center = user.np->capital;
  1382. X  user.help_char = '?';
  1383. X  user.map_style = NORMAL_MAP;
  1384. X  user.display = DESIGNATION;
  1385. X  if (user.id != 0) {
  1386. X    user.highlight = H_OWNED;
  1387. X  } else {            /* for gamemaster, don't highlight */
  1388. X    user.highlight = H_NONE;
  1389. X  }
  1390. X  user.underwater = 0;        /* user is not underwater at start */
  1391. X  if (user.np->race.pref_alt < 0) {
  1392. X    user.underwater = 1;    /* merfolk or whatever */
  1393. X  }
  1394. X  user.n_execs = 0;
  1395. X  user.current_army =
  1396. X    first_sect_army(&world.map[user.cursor.x][user.cursor.y]);
  1397. X  user.just_moved = 1;
  1398. X  user.last_n_armies = 0;
  1399. X    /* super user visibility */
  1400. X  if (user.id == 0) {
  1401. X    viewall = 1;
  1402. X  }
  1403. X  user.show_sect_win = 1;
  1404. X    /* load user's diplomacy statuses, for fast access later;
  1405. X       also remember the initial values, so users cannot change
  1406. X       their status by more than one step at a time.
  1407. X     */
  1408. X  user.diplo_matrix = allocate_diplo(world.n_nations);
  1409. X  read_in_diplo(user.diplo_matrix, world.n_nations);
  1410. X/* Load removed spells first */
  1411. X  load_dead_hspells(&user,0);
  1412. X
  1413. X    /* load hanging spells, and put them in this user's list */
  1414. X  load_h_spells(&user);
  1415. X    /* calculate visibility matrix for this user.
  1416. X       this might depend on spells, so do it after
  1417. X       loading spells.
  1418. X     */
  1419. X  user.visible_sectors = (int **) malloc(world.xmax*sizeof(int *));
  1420. X  for (i = 0; i < world.xmax; ++i) {
  1421. X    user.visible_sectors[i] = (int *) malloc(world.ymax*sizeof(int));
  1422. X  }
  1423. X  find_visible_sectors(user.visible_sectors);
  1424. X}
  1425. X
  1426. X  /* for a fixed army, update its visibility range */
  1427. Xarmy_visibility(visible_sectors, ap)
  1428. X     int **visible_sectors;
  1429. X     Sarmy *ap;
  1430. X{
  1431. X  int x = ap->pos.x, y = ap->pos.y, i, j;
  1432. X  Ssector *sp;
  1433. X
  1434. X  sp = &world.map[x][y];
  1435. X  if (has_hidden(sp) && sp->owner != user.id) {
  1436. X    visible_sectors[x][y] = SEE_ARMIES;
  1437. X  } else if (sp->owner != user.id) {
  1438. X    visible_sectors[x][y] = SEE_ARMIES;
  1439. X  } else {
  1440. X    visible_sectors[x][y] = SEE_ALL;
  1441. X  }
  1442. X  for (i = x-ARMY_SIGHT; i <= x+ARMY_SIGHT; ++i) {
  1443. X    for (j = y-ARMY_SIGHT; j <= y+ARMY_SIGHT; ++j) {
  1444. X      sp = &world.map[(*wrapx)(i,j)][(*wrapy)(i,j)];
  1445. X      if (has_hidden(sp) && sp->owner != user.id) {
  1446. X    /* if sect. is hidden, we don't see it */
  1447. X      } else {
  1448. X    visible_sectors[(*wrapx)(i,j)][(*wrapy)(i,j)] |=
  1449. X      (SEE_LAND_WATER | SEE_OWNER | SEE_DESIG |
  1450. X       SEE_POPULATION | SEE_ARMIES);
  1451. X      }
  1452. X      if (world.map[(*wrapx)(i,j)][(*wrapy)(i,j)].owner == 0) {
  1453. X    visible_sectors[(*wrapx)(i,j)][(*wrapy)(i,j)] |= SEE_RESOURCES;
  1454. X      }
  1455. X    }
  1456. X  }
  1457. X}
  1458. X
  1459. X  /* this allows a user to set her/his options */
  1460. Xoptions()
  1461. X{
  1462. X  WINDOW *optw;
  1463. X  char c;
  1464. X  int done = 0;
  1465. X  char *forwarding = mail_forwarding(user.id);
  1466. X
  1467. X  optw = newwin(8, 50, 5, 10);
  1468. X  while (!done) {
  1469. X    mvwprintw(optw, 1, 2, "[x]: toggle expert mode (%s)",
  1470. X          user.np->opts->expert_mode ? "on" : "off");
  1471. X    wclrtoeol(optw);
  1472. X
  1473. X    if (user.np->opts->mail_forward) {
  1474. X      mvwprintw(optw, 2, 2, "[f]: Change mail forwarding (\"%s\")",
  1475. X                   user.np->opts->mail_forward);
  1476. X    } else {
  1477. X      mvwprintw(optw, 2, 2, "[f]: Change mail forwarding (none)");
  1478. X    }
  1479. X    wclrtoeol(optw);
  1480. X    mvwprintw(optw, 3, 2, "[c]: Toggle civilian movement (%s)",
  1481. X                     civ_move[user.np->opts->civ_movemode]);
  1482. X    wclrtoeol(optw);
  1483. X    if (user.np->opts->mail_reader) {
  1484. X      mvwprintw(optw, 4, 2, "[m]: Mail Program (%s)",
  1485. X                                   user.np->opts->mail_reader);
  1486. X    } else {
  1487. X      mvwprintw(optw, 4, 2, "[m]: Mail Program (internal)");
  1488. X    }
  1489. X    wclrtobot(optw);
  1490. X    box(optw, '|', '-');
  1491. X    wrefresh(optw);
  1492. X    statline("Choose an option, hit space to get back.", "options");
  1493. X    switch (c = getch()) {
  1494. X    case 'x':
  1495. X      user.np->opts->expert_mode = !user.np->opts->expert_mode;
  1496. X      user.xmode = user.np->opts->expert_mode;
  1497. X      break;
  1498. X    case 'f':
  1499. X      ask_for_forwarding(optw);
  1500. X      break;
  1501. X    case 'c':
  1502. X        /* cycle through the various migration modes */
  1503. X      user.np->opts->civ_movemode = (user.np->opts->civ_movemode + 1) % 3;
  1504. X      break;
  1505. X    case 'm':
  1506. X      ask_for_mail_reader(optw);
  1507. X      break;
  1508. X    case ' ':
  1509. X      done = 1;
  1510. X      break;
  1511. X    default:
  1512. X      break;
  1513. X    }
  1514. X  }
  1515. X  delwin(optw);
  1516. X  user.just_moved = 1;
  1517. X  save_options(user.np);
  1518. X
  1519. X  touch_all_wins();
  1520. X}
  1521. X
  1522. Xstatic ask_for_forwarding(win)
  1523. X     WINDOW *win;
  1524. X{
  1525. X  char buf[200];
  1526. X
  1527. X  mvwprintw(win, 5, 2, "New mail address? (<return> for no forwarding)");
  1528. X  mvwprintw(win, 6, 4, "-->");
  1529. X  wrefresh(win);
  1530. X
  1531. X  if (user.np->opts->mail_forward != NULL) {
  1532. X    free(user.np->opts->mail_forward);
  1533. X    user.np->opts->mail_forward = NULL;
  1534. X  }
  1535. X  if (wget_string(win, buf,200) != 0) {
  1536. X    if ((user.np->opts->mail_forward = (char *)malloc ((strlen(buf) + 1) * 
  1537. X          sizeof (char))) == NULL) { mem_error(); }
  1538. X    strcpy(user.np->opts->mail_forward, buf);
  1539. X  } 
  1540. X}
  1541. X
  1542. Xask_for_mail_reader(win)
  1543. X     WINDOW *win;
  1544. X{
  1545. X  char buf[200];
  1546. X
  1547. X  if (user.np->opts->mail_reader) { free(user.np->opts->mail_reader); }
  1548. X
  1549. X  mvwprintw(win, 5, 2, "New mail reader? (<return> for internal mail)");
  1550. X  mvwprintw(win, 6, 4, "-->");
  1551. X  wrefresh(win);
  1552. X
  1553. X  if (wget_string(win, buf, 200))  {
  1554. X    if ((user.np->opts->mail_reader = (char *)malloc ((strlen(buf) + 1) * 
  1555. X          sizeof (char))) == NULL) { mem_error(); }
  1556. X    strcpy(user.np->opts->mail_reader, buf);
  1557. X  } else {
  1558. X    user.np->opts->mail_reader = NULL;
  1559. X  }
  1560. X}
  1561. X
  1562. X  /* check if there is a lock file, and handle the situation if there is */
  1563. Xhandle_locks(id)
  1564. X     int id;
  1565. X{
  1566. X  FILE *lock_fp, *is_locked();
  1567. X  char *timestr;
  1568. X  long secs;            /* seconds marked in lock file */
  1569. X
  1570. X    /* check if there is a master lock file */
  1571. X  if (is_master_lock()) {
  1572. X    printf("There is a master lock file.  You cannot play right now.\n");
  1573. X    clean_exit();
  1574. X    exit(1);
  1575. X  }
  1576. X  if (strcmp(update_time,get_update_time()) != 0)
  1577. X  {
  1578. X    fprintf(stderr,"Error: Update has occured.  Please restart program \n");
  1579. X    clean_exit();
  1580. X    exit(0);
  1581. X  }
  1582. X
  1583. X    /* see if there is a lock file for this nation */
  1584. X  if (lock_fp = is_locked(id)) {
  1585. X    fscanf(lock_fp, "%ld", &secs);
  1586. X    fclose(lock_fp);
  1587. X    timestr = ctime(&secs);
  1588. X    printf("\r\nYour nation is already being played.\n\r");
  1589. X    printf("That session seems to have been started at %s", timestr);
  1590. X    printf("If that session is no more and you want to play now, type [y] ");
  1591. X    if (getchar() != 'y') {
  1592. X      printf("OK, then you will have to wait until that session is over\n");
  1593. X      clean_exit();
  1594. X      exit(1);
  1595. X    }
  1596. X  }
  1597. X    /* set a lock file */
  1598. X  set_lock(id);
  1599. X}
  1600. X
  1601. END_OF_FILE
  1602. if test 10194 -ne `wc -c <'user.c'`; then
  1603.     echo shar: \"'user.c'\" unpacked with wrong size!
  1604. fi
  1605. # end of 'user.c'
  1606. fi
  1607. if test -f 'world.c' -a "${1}" != "-c" ; then 
  1608.   echo shar: Will not clobber existing file \"'world.c'\"
  1609. else
  1610. echo shar: Extracting \"'world.c'\" \(11077 characters\)
  1611. sed "s/^X//" >'world.c' <<'END_OF_FILE'
  1612. X/* world.c -- function dealing with the world; its use and implementation */
  1613. X
  1614. X/*
  1615. X* Copyright (C) 1990 Free Software Foundation, Inc.
  1616. X* Written by the dominion project.
  1617. X*
  1618. X* This file is part of dominion.
  1619. X*
  1620. X* dominion is free software; you can redistribute it and/or
  1621. X* modify it under the terms of the GNU General Public License as published
  1622. X* by the Free Software Foundation; either version 1, or (at your option)
  1623. X* any later version.
  1624. X*
  1625. X* This software is distributed in the hope that it will be useful,
  1626. X* but WITHOUT ANY WARRANTY; without even the implied warranty of
  1627. X* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1628. X* GNU General Public License for more details.
  1629. X*
  1630. X* You should have received a copy of the GNU General Public License
  1631. X* along with this software; see the file COPYING.  If not, write to
  1632. X* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  1633. X*/
  1634. X
  1635. X/* wrap(pp) - wraps a point to its proper location                        */
  1636. X/* latitude(x,y) - returns the latitude of a particular point             */
  1637. X/* map_alt(altitude) - maps the altitude value to the correct data entry  */
  1638. X/* xrel(x,y) - gives the relative x coordinate from nation's capital      */
  1639. X/* yrel(x,y) - gives the relative y coordinate from nation's capital      */
  1640. X/* xdist(x,y,x1,y1) - gives the x distance between (x,y) and (x1,y1)      */
  1641. X/* ydist(x,y,x1,y1) - gives the y distance between (x,y) and (x1,y1)      */
  1642. X/* sect_desire(np,x,y) - gives the desireability value of x,y for nation  */
  1643. X/* is_coastal_sect(np,sp,ap) - is this coast (for given nation and army)? */
  1644. X/* is_active_ntn(np) - returns 1 if the nation has not been destroyed     */
  1645. X/* are_patrols(np, moving_ap, sp) - returns true if moving_ap gets slowed */
  1646. X
  1647. X#include "dominion.h"
  1648. X#include "misc.h"
  1649. X#include "army.h"
  1650. X
  1651. X#include <stdio.h>
  1652. X#include <math.h>
  1653. X
  1654. Xextern Sworld world;
  1655. Xextern Suser user;
  1656. Xextern struct s_altitude_map altitude_map[];
  1657. Xextern struct s_desig_map desig_map[];
  1658. Xextern int (*wrapx)(), (*wrapy)();
  1659. X
  1660. X/* Wrapping functions are the heart and soul of the world's shape */
  1661. X/* these main functions, wrapx and wrapy, choose the proper function for */
  1662. X/* the proper shape of the world in question. */
  1663. X
  1664. X/* This function wraps the entire point */
  1665. X
  1666. Xwrap(pp)
  1667. XPt *pp;
  1668. X{
  1669. Xpp->x = (*wrapx)(pp->x,pp->y);
  1670. Xpp->y = (*wrapy)(pp->x,pp->y);
  1671. X}
  1672. X
  1673. X/* Wrap functions for a TORUS world */
  1674. X
  1675. Xtorus_wrapx(x,y)  /* produce new value of x, if x is too big or negative */
  1676. Xint x,y;
  1677. X{
  1678. Xif (x >= world.xmax) {
  1679. Xreturn x % world.xmax;
  1680. X}
  1681. Xwhile (x < 0) {
  1682. Xx += world.xmax;
  1683. X}
  1684. Xreturn x;
  1685. X}
  1686. X
  1687. Xtorus_wrapy(x,y)  /* produce new value of y, if y is too big or negative*/
  1688. Xint x,y;
  1689. X{
  1690. Xif (y >= world.ymax) {
  1691. Xreturn y % world.ymax;
  1692. X}
  1693. Xwhile (y < 0) {
  1694. Xy += world.ymax;
  1695. X}
  1696. Xreturn y;
  1697. X}
  1698. X
  1699. X/* Wrap function for a pinched cylinder world */
  1700. X
  1701. Xpinch_wrapx(x,y)
  1702. Xint x,y;
  1703. X{
  1704. Xreturn pinch_wrapxy(x,y,1);
  1705. X}
  1706. X
  1707. Xpinch_wrapy(x,y)
  1708. Xint x,y;
  1709. X{
  1710. Xreturn pinch_wrapxy(x,y,2);
  1711. X}
  1712. X
  1713. Xpinch_wrapxy(x,y,which) /* if which=1 then return x */
  1714. Xint x,y,which;
  1715. X{
  1716. Xwhile (y < 0) {
  1717. Xy = -(y + 1);
  1718. Xx = x + (world.xmax / 2);
  1719. X}
  1720. Xwhile (y >= world.ymax) {
  1721. Xy = 2 * world.ymax - (y + 1);
  1722. Xx = x + (world.xmax / 2);
  1723. X}
  1724. Xwhile (x < 0) {
  1725. Xx = x + world.xmax;
  1726. X}
  1727. Xif (x >= world.xmax) {
  1728. Xx = x % world.xmax;
  1729. X}
  1730. Xif (which == 1) {
  1731. Xreturn x;
  1732. X} else {
  1733. Xreturn y;
  1734. X}
  1735. X}
  1736. X
  1737. X/* A latitude function for the world which returns a float angle of the */
  1738. X/* latitude of the y-coordinate given.  Equator is 0 degrees and the poles */
  1739. X/* are 90 degrees (north pole) and negative 90 degrees (south pole) */
  1740. X
  1741. Xlatitude(x,y)
  1742. Xint x,y;
  1743. X{
  1744. Xfloat angle;
  1745. Xswitch(world.geo.topology) {
  1746. Xcase TORUS:
  1747. Xangle = torus_latitude(y); break;
  1748. X}
  1749. Xreturn angle;
  1750. X}
  1751. X
  1752. X/* Returns the latitude of a y-coordinate for a pinched cylinder. */
  1753. X
  1754. Xpinch_latitude(y)
  1755. Xint y;
  1756. X{
  1757. Xfloat eq_dist, angle;
  1758. Xeq_dist = y - (world.ymax / 2.0);
  1759. Xif (eq_dist < 0) {
  1760. Xeq_dist = eq_dist + 1.0;
  1761. X}
  1762. Xangle = 90.0 * (eq_dist / (world.ymax / 2.0));
  1763. Xreturn -(angle);
  1764. X}
  1765. X
  1766. X/* Returns the latitude of a y-coordinate for a torus */
  1767. X
  1768. Xtorus_latitude(y)
  1769. Xint y;
  1770. X{
  1771. Xfloat eq_dist, angle;
  1772. Xeq_dist = y - (world.ymax / 2.0);
  1773. Xangle = 90.0 * (eq_dist / (world.ymax / 2.0));
  1774. Xreturn angle;
  1775. X}
  1776. X
  1777. Xint map_alt(altitude)
  1778. Xint altitude;
  1779. X{
  1780. Xaltitude -= altitude_map[0].value;
  1781. Xreturn altitude;
  1782. X}
  1783. X
  1784. X/* These functions give the coordinates of a sector relative to the user's */
  1785. X/* capital.  They differ depending on which type of world you use! */
  1786. Xint xrel(x, y, cap)
  1787. Xint x, y;
  1788. XPt cap;
  1789. X{
  1790. Xx=xdist(x, y, cap.x, cap.y);
  1791. X/*  if (x < 0) {
  1792. Xreturn(x + world.xmax);
  1793. X} */
  1794. Xreturn(x);
  1795. X}
  1796. X
  1797. Xint yrel(x, y, cap)
  1798. Xint x,y;
  1799. XPt cap;
  1800. X{
  1801. Xy = ydist(x, y, cap.x, cap.y);
  1802. X/*  if (y < 0) {
  1803. Xreturn(y + world.ymax);
  1804. X} */
  1805. Xreturn(y);
  1806. X}
  1807. X
  1808. X/* Functions to return the how far (x,y) is from (x1,y1) */
  1809. Xint xdist(x,y,x1,y1)
  1810. Xint x,y,x1,y1;
  1811. X{
  1812. Xswitch (world.geo.topology) {
  1813. Xcase TORUS:
  1814. Xx = x - x1;
  1815. Xif (x <= (0 - world.xmax / 2)) {
  1816. Xx += world.xmax;
  1817. X}
  1818. Xif (x > world.xmax / 2) {
  1819. Xx = x - world.xmax;
  1820. X}
  1821. Xreturn x;
  1822. Xbreak;    
  1823. X}
  1824. X}
  1825. X
  1826. Xint ydist(x,y,x1,y1)
  1827. Xint x,y,x1,y1;
  1828. X{
  1829. Xswitch (world.geo.topology) {
  1830. Xcase TORUS:
  1831. Xy = y - y1;
  1832. Xif (y <= (0 - world.ymax / 2)) {
  1833. Xy += world.ymax;
  1834. X}
  1835. Xif (y > world.ymax / 2) {
  1836. Xy = y - world.ymax;
  1837. X}
  1838. Xreturn y;
  1839. Xbreak;
  1840. X}
  1841. X}
  1842. X
  1843. Xpinched_dist(x,y,x1,y1,choice)
  1844. Xint x,y,x1,y1,choice;
  1845. X{
  1846. Xint dx,dy,dx2,dy2;
  1847. Xfloat r1,r2;
  1848. Xdx = x - x1;
  1849. Xdy = y - y1;
  1850. Xif (dx > world.xmax / 2) {
  1851. Xdx = dx - world.xmax;
  1852. X}
  1853. Xif (dx <= (0 - world.xmax / 2)) {
  1854. Xdx = dx + world.xmax;
  1855. X}
  1856. X
  1857. Xdy2 = y + y1 + 1;
  1858. Xif (dy2 > world.ymax) {
  1859. Xdy2 = world.ymax * 2 - dy2;
  1860. X} else {
  1861. Xdy2 = -(dy2);
  1862. X}
  1863. Xdx2 = x - x1 + world.xmax / 2;
  1864. Xif (dx2 >= world.xmax / 2) {
  1865. Xdx2 = dx2 - world.xmax;
  1866. X}
  1867. X
  1868. Xr1 = sqrt(dx*dx + dy*dy);
  1869. Xr2 = sqrt(dx2*dx2 + dy2*dy2);
  1870. Xif (r1 <= r2) {
  1871. Xif (choice == 1) {
  1872. Xreturn dx;
  1873. X} else {
  1874. Xreturn dy;
  1875. X}
  1876. X} else {
  1877. Xif (choice == 1) {
  1878. Xreturn dx2;
  1879. X} else {
  1880. Xreturn dy2;
  1881. X}
  1882. X}
  1883. X}
  1884. X
  1885. X/* Old Sector Desire
  1886. Xint sect_desire(np, x, y)
  1887. XSnation *np;
  1888. Xint x, y;
  1889. X{
  1890. Xint terrain_d,climate_d,altitude_d,total_d;
  1891. X
  1892. Xterrain_d = abs(world.map[x][y].terrain - np->race.pref_terrain);
  1893. Xclimate_d = abs(world.map[x][y].climate - np->race.pref_climate);
  1894. Xaltitude_d = abs(world.map[x][y].altitude - np->race.pref_alt);
  1895. Xtotal_d  = max(0,300-(terrain_d*terrain_d)*10);
  1896. Xtotal_d += max(0,50-climate_d*3);
  1897. Xtotal_d += max(0,300-(altitude_d*altitude_d)*8);
  1898. Xtotal_d += world.map[x][y].metal*5;
  1899. Xtotal_d += world.map[x][y].soil*4;
  1900. Xtotal_d += world.map[x][y].jewels*6;
  1901. Xif (world.map[x][y].designation == D_CITY || world.map[x][y].designation == D_CAPITAL) {
  1902. Xtotal_d *= 3;
  1903. X}
  1904. Xreturn total_d;
  1905. X}
  1906. X*/
  1907. X
  1908. Xint sect_desire(np, x, y)
  1909. XSnation *np;
  1910. Xint x, y;
  1911. X{
  1912. X  int terrain_d,climate_d,altitude_d,total_d;
  1913. X
  1914. X  terrain_d = abs(world.map[x][y].terrain - np->race.pref_terrain);
  1915. X  climate_d = abs(world.map[x][y].climate - np->race.pref_climate);
  1916. X  altitude_d = abs(world.map[x][y].altitude - np->race.pref_alt);
  1917. X
  1918. X  total_d  = max(0,230-(terrain_d*terrain_d)*10);
  1919. X  total_d += max(0,250-(climate_d*climate_d)*10);
  1920. X  total_d += max(0,250-(altitude_d*altitude_d)*20);
  1921. X  if (user.id == world.map[x][y].owner)
  1922. X  {
  1923. X    switch (world.map[x][y].designation)
  1924. X    {
  1925. X      case D_FARM: total_d += world.map[x][y].soil * 9; break;
  1926. X      case D_METAL_MINE: total_d += world.map[x][y].metal * 11; break;
  1927. X      case D_JEWEL_MINE: total_d += world.map[x][y].jewels * 13; break;
  1928. X      default:
  1929. X      { 
  1930. X        total_d += 37;
  1931. X        total_d += world.map[x][y].soil;
  1932. X        total_d += world.map[x][y].metal;
  1933. X        total_d += world.map[x][y].jewels;
  1934. X      }
  1935. X    }
  1936. X  } else
  1937. X  {
  1938. X    total_d += world.map[x][y].soil * 7;
  1939. X    total_d += world.map[x][y].metal * 9;
  1940. X    total_d += world.map[x][y].jewels * 11;
  1941. X  }
  1942. X  return total_d;
  1943. X}
  1944. X
  1945. X/* this function returns true if there is a non-treaty army
  1946. X   in patrol/intercept mode in the neighbourhood of the given sector.
  1947. X   if none is found, it returns 0.  If the "moving_ap" is NULL,
  1948. X   then you ignore the issue of whether moving_ap is in flight.
  1949. X */
  1950. Xare_patrols(np, moving_ap, sp)
  1951. X     Snation *np;
  1952. X     Sarmy *moving_ap;
  1953. X     Ssector *sp;
  1954. X{
  1955. X  int found = 0, done = 0, x, y;
  1956. X  Sarmy *ap, *get_army();
  1957. X  struct armyid *alist;
  1958. X
  1959. X  if (moving_ap && is_underground(moving_ap)) {
  1960. X    return 0;            /* underground armies can't be intercepted */
  1961. X  }
  1962. X    /* here we check if there are patrol or intercept units around */
  1963. X  for (x = sp->loc.x - 1; ((x <= sp->loc.x + 1) && (done == 0)); x++) {
  1964. X    for (y = sp->loc.y - 1; ((y <= sp->loc.y + 1) && (done == 0)); y++) {
  1965. X      done = 0;
  1966. X      if (np->npc_flag
  1967. X          || user.visible_sectors[(*wrapx)(x,y)][(*wrapy)(x,y)] & SEE_ARMIES) {
  1968. X    alist = world.map[(*wrapx)(x,y)][(*wrapy)(x,y)].alist;
  1969. X    while (alist != NULL) {
  1970. X      if (alist->owner == sp->owner) {
  1971. X        ap = get_army(&world.nations[alist->owner],alist->id);
  1972. X        if ( (ap->status == A_PATROL || ap->status == A_INTERCEPT) &&
  1973. X            /* OK, we got an army on intercept or patrol.
  1974. X           now check the issue of flight.
  1975. X         */
  1976. X        (!(moving_ap && is_flight(moving_ap)) || is_missiles(ap))
  1977. X        /* make sure that we only slow down armies that are
  1978. X           not our own.  In the future, this should
  1979. X           also let TREATY armies pass...
  1980. X         */
  1981. X        && (moving_ap && (ap->owner != moving_ap->owner))
  1982. X        && (get_diplo_status(user.diplo_matrix,
  1983. X                    ap->owner, moving_ap->owner != TREATY))) {
  1984. X          alist = NULL;
  1985. X          found = 1;
  1986. X          done = 1;
  1987. X        } else {
  1988. X          alist = alist->next;
  1989. X        }
  1990. X      } else {
  1991. X        alist = alist->next;
  1992. X      }
  1993. X    }
  1994. X      }
  1995. X    }
  1996. X  }
  1997. X  return found;
  1998. X}
  1999. X
  2000. Xinit_wrap() 
  2001. X{
  2002. X  int torus_wrapx(), torus_wrapy();
  2003. X  switch(world.geo.topology) {
  2004. X  case TORUS:
  2005. X    wrapx = torus_wrapx;
  2006. X    wrapy = torus_wrapy;
  2007. X    break;
  2008. X  default:
  2009. X    printf("What world is this???\n");
  2010. X    wrapx = torus_wrapx;
  2011. X    wrapy = torus_wrapy;
  2012. X    break;
  2013. X  }
  2014. X}
  2015. X
  2016. X  /* returns 1 if this is a coastal sector (for that race and army),
  2017. X     0 otherwise.  Note that this only applies if the army has the
  2018. X     L or W flag, since other armies don't get any benefit from
  2019. X     coastal sectors:  they should drown anyway.
  2020. X   */
  2021. Xis_coastal_sect(np, sp, ap)
  2022. X     Snation *np;        /* nation that wants to go there */
  2023. X     Ssector *sp;
  2024. X     Sarmy *ap;
  2025. X{
  2026. X  int land, i, j, x, y;
  2027. X
  2028. X  if (is_land(ap) && is_water(ap)) {
  2029. X    return 0;            /* amphibious don't have a coastline */
  2030. X  }
  2031. X  if (is_land(ap)) {
  2032. X    land = 1;
  2033. X  } else if (is_water(ap)) {
  2034. X    land = 0;
  2035. X  } else {            /* coast only applies to L and W flags */
  2036. X    return 0;
  2037. X  }
  2038. X    /* case: we are land army in water; look for land nearby! */
  2039. X  if (land && sp->altitude < SEA_LEVEL) {
  2040. X    for (i = sp->loc.x-1; i <= sp->loc.x+1; ++i) {
  2041. X      for (j = sp->loc.y-1; j <= sp->loc.y+1; ++j) {
  2042. X    x = wrapx(i, j);
  2043. X    y = wrapy(i, j);
  2044. X    if (world.map[x][y].altitude >= SEA_LEVEL) {
  2045. X      return 1;
  2046. X    }
  2047. X      }
  2048. X    }
  2049. X    return 0;            /* no shore nearby */
  2050. X  }
  2051. X    /* case: we are water army on land; look for water nearby! */
  2052. X  if (!land && sp->altitude >= SEA_LEVEL) {
  2053. X    for (i = sp->loc.x-1; i <= sp->loc.x+1; ++i) {
  2054. X      for (j = sp->loc.y-1; j <= sp->loc.y+1; ++j) {
  2055. X    x = wrapx(i, j);
  2056. X    y = wrapy(i, j);
  2057. X    if (world.map[x][y].altitude < SEA_LEVEL) {
  2058. X      return 1;
  2059. X    }
  2060. X      }
  2061. X    }
  2062. X    return 0;            /* no shor nearby */
  2063. X  }
  2064. X}
  2065. X
  2066. X  /* tells you if a nation has not been destroyed */
  2067. Xis_active_ntn(np)
  2068. X     Snation *np;
  2069. X{
  2070. X  if (np->id == 0) {
  2071. X    return 1;
  2072. X  }
  2073. X  if (!(np->capital.x == -1 && np->capital.y == -1)) {
  2074. X    return 1;
  2075. X  }
  2076. X  return 0;
  2077. X}
  2078. END_OF_FILE
  2079. if test 11077 -ne `wc -c <'world.c'`; then
  2080.     echo shar: \"'world.c'\" unpacked with wrong size!
  2081. fi
  2082. # end of 'world.c'
  2083. fi
  2084. echo shar: End of archive 26 \(of 28\).
  2085. cp /dev/null ark26isdone
  2086. MISSING=""
  2087. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ; do
  2088.     if test ! -f ark${I}isdone ; then
  2089.     MISSING="${MISSING} ${I}"
  2090.     fi
  2091. done
  2092. if test "${MISSING}" = "" ; then
  2093.     echo You have unpacked all 28 archives.
  2094.     echo "Now execute ./do_cat.sh to build doc files"
  2095.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2096. else
  2097.     echo You still need to unpack the following archives:
  2098.     echo "        " ${MISSING}
  2099. fi
  2100. ##  End of shell archive.
  2101. exit 0
  2102.