home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume13 / dominion / part24 < prev    next >
Encoding:
Internet Message Format  |  1992-02-10  |  61.3 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: v13i060:  dominion - a multi-player world simulation game, Part24/28
  5. Message-ID: <2463@masterCNA.TEK.COM>
  6. Date: 11 Feb 92 18:27:31 GMT
  7. Sender: news@masterCNA.TEK.COM
  8. Lines: 2191
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: rosalia@dirac.physics.sunysb.edu (Mark Galassi)
  12. Posting-number: Volume 13, Issue 60
  13. Archive-name: dominion/Part24
  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 24 (of 28)."
  25. # Contents:  dominion.h int_mail.c printmap.c races spelllib.c
  26. # Wrapped by billr@saab on Tue Feb 11 10:14:58 1992
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'dominion.h' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'dominion.h'\"
  30. else
  31. echo shar: Extracting \"'dominion.h'\" \(13830 characters\)
  32. sed "s/^X//" >'dominion.h' <<'END_OF_FILE'
  33. X  /* dominion.h -- general include file for dominion */
  34. X
  35. X/*
  36. X * Copyright (C) 1990 Free Software Foundation, Inc.
  37. X * Written by the dominion project.
  38. X *
  39. X * This file is part of dominion.
  40. X *
  41. X * dominion is free software; you can redistribute it and/or
  42. X * modify it under the terms of the GNU General Public License as published
  43. X * by the Free Software Foundation; either version 1, or (at your option)
  44. X * any later version.
  45. X *
  46. X * This software is distributed in the hope that it will be useful,
  47. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  48. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  49. X * GNU General Public License for more details.
  50. X *
  51. X * You should have received a copy of the GNU General Public License
  52. X * along with this software; see the file COPYING.  If not, write to
  53. X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  54. X */
  55. X
  56. X#include <curses.h>
  57. X
  58. X  /* user-definable params */
  59. X#define WORLD_FILE "world"
  60. X#define REF_CARD_FILE "doc/refcard" /* basic reference card */
  61. X#define INFO_FILE "doc/dominion.info" /* complete documentation */
  62. X#define RACES_FILE "misc/races"
  63. X#define DIPLO_FILE "dom_diplo"    /* diplomacy matrix stored here */
  64. X#define INIT_DIPLO_FILE "init_diplo" /* remember initial diplomacy matrix */
  65. X#define CARGO_FILE "misc/cargo" /* stores cargo exchanges */
  66. X#define HANGING_SPELLS_FILE "hanging_spells" /* currently active spells */
  67. X  /* any file that starts with the MAG_PREFIX is a description
  68. X     of a magical order.  the name of the order follows the prefix.
  69. X     a list of possible magic orders is in mag_orders.
  70. X   */
  71. X#define MAG_ORDERS "magic/mag_orders"
  72. X#define MAG_PREFIX "magic/mag_"
  73. X#define TECHNO_FILE "misc/techno_levels"
  74. X
  75. X#define MAIL_DIR   "mail"    /* Which dir (in lib) to place mail */
  76. X#define NEWS_DIR   "news"       /* Which dir (in lib) to keep news */
  77. X#define NGDB_FILE  "groups"     /* What file in NEWS_DIR to hold the news
  78. X                   groups database */
  79. X#define OPT_DIR    "options"    /* Which dir (in lib) to keep options */
  80. X#define TRADES_FILE "trades"    /* file where trade info is kept */
  81. X#define BIDS_FILE  "bids"    /* file where bids on trades are kept */
  82. X#define ARMY_TYPES_FILE "misc/army_types" /* army type descriptions are here */
  83. X /* spirit type descriptions are here */
  84. X#define SPIRIT_TYPES_FILE "misc/spirit_types"
  85. X#define NPC_FILE   "misc/npcs"    /* file where npc info is kept */
  86. X#define MAXTRADES  100          /* maximum amount of trades on board */
  87. X#define NATIONS 50        /* max # of nations; to be removed some day */
  88. X
  89. X  /* now some defines for how the NPCs move */
  90. X#define NPC_FIGHT TRUE        /* if this is TRUE, NPCs fight each other */
  91. X#define NPC_VIEW 4        /* how far NPC armies look to move */
  92. X#define NPC_SIDE (NPC_VIEW*2+3)    /* length of the side of the "looking" array */
  93. X#define MAX_TYPES 100        /* maximum number of armies NPC considers */
  94. X#define DIP_CHANGE 75        /* Percent chance for npc diplomacy change */
  95. X
  96. X  /* tunable parameters */
  97. X#define OCCUPYING_SOLDIERS 100    /* min. soldiers to occupy a sector */
  98. X/*#define POP_REFINERY 100    /* min. population for a refinery to work */
  99. X#define REFINERY_FACT (12.0/100.0) /* percent added by an active refinery */
  100. X#define FOOD_PROD 4        /* production of food/farmer : tons */
  101. X#define EAT 1.3            /* how much a person eats in 1 thon : tons */
  102. X#define SOLD_EAT_FACTOR 1.2    /* multiplies the eat rate */
  103. X
  104. X#define CARAVAN_CAPACITY 250    /* how many civilians on 1 caravan unit */
  105. X
  106. X#define JEWEL_WEIGHT 0.01    /* the next four are in relation to one */
  107. X#define MONEY_WEIGHT 0.01    /* person's weight (i.e. jewels weigh */
  108. X#define METAL_WEIGHT 0.1    /* 1/100th of a person) */
  109. X#define FOOD_WEIGHT  0.05
  110. X
  111. X#define DISBAND_RETURN (0.5)    /* what fraction metal is returned w/disband */
  112. X
  113. X/* how much do money/metal/jewels affect R&D */
  114. X#define TECH_MONEY_FACTOR 1.0/10.0
  115. X#define TECH_METAL_FACTOR 1.0/40.0
  116. X#define MAG_MONEY_FACTOR 1.0/5.0
  117. X#define MAG_JEWEL_FACTOR 1.0/200.0
  118. X#define SPY_MONEY_FACTOR 1.0/200.0
  119. X#define SPY_SECRECY_FACTOR 1.0/2000.0
  120. X
  121. X  /* these parameters determine how far you can see */
  122. X#define LAND_SIGHT 3        /* how far you see from an owned sector */
  123. X#define WATER_SIGHT 2        /* ...             across water */
  124. X#define ARMY_SIGHT 2        /* ...                  an army */
  125. X
  126. X  /* end of user-defined parameters */
  127. X
  128. X#define NOT_NPC 0        /* values of the Snation.npc_flag */
  129. X#define NPC_NOMAIL 1        /* NPC that does not get mail */
  130. X#define NPC_MAIL 2        /* NPC that gets mail */
  131. X  /* now a macro that allows us to quickly see if an NPC should get mail */
  132. X#define gets_mail(np) ((np)->npc_flag == NOT_NPC || (np)->npc_flag == NPC_MAIL)
  133. X
  134. X#define NAMELEN 20        /* length of most names */
  135. X#define PASSLEN 15
  136. X#define PATHLEN 200        /* length of directory paths */
  137. X
  138. X#ifdef CURSES
  139. X  typedef char Symbol;        /* just a char for curses */
  140. X#endif
  141. X    /* should typedef mark for X and other windows... */
  142. X
  143. Xstruct pt {
  144. X  int x, y;
  145. X};
  146. Xtypedef struct pt Pt;
  147. X
  148. X  /* this structure identifies an army by its owner and id.
  149. X     it is used in the list of armies present in each sector.
  150. X   */
  151. Xstruct armyid {
  152. X  int owner, id;
  153. X  struct armyid *next;
  154. X};
  155. X
  156. X  /* defines a cargo carried by some moving object (caravan or navy) */
  157. Xstruct scargo {
  158. X  int money, metal, jewels, food, people, army;
  159. X  Pt title;
  160. X};
  161. X
  162. Xtypedef struct scargo Scargo;
  163. X
  164. Xstruct sarmy {
  165. X  char type[NAMELEN],        /* string (i.e. "Infantry","ent")   */
  166. X       name[NAMELEN];        /* the army's name */
  167. X  int  n_soldiers,        /* number of soldiers in the army   */
  168. X       status,            /* ATACK|DEFEND|OCCUPY|...          */
  169. X       id,            /* army number                      */
  170. X       owner,            /* nation number of army owner      */
  171. X       mvpts,            /* move points                      */
  172. X       mvratio;            /* fraction of movement used        */
  173. X       long flags;        /* bitmap, fields defined in army.h */
  174. X  Pt   pos;            /* where the army is                */
  175. X  int  sp_bonus;          /* extra bonus, on top of basic nation bonus */
  176. X    /* the maintainance costs are all per-soldier, except the
  177. X       spell points, which apply to the entire army.
  178. X     */
  179. X  int  money_maint, metal_maint, jewel_maint, spell_pts_maint;
  180. X  Scargo cargo;
  181. X  struct sarmy *next;        /* pointer to next army             */
  182. X};
  183. Xtypedef struct sarmy Sarmy;
  184. X
  185. Xstruct pt_list {
  186. X  Pt pt;            /* list of owned sectors */
  187. X  struct pt_list *next;
  188. X};
  189. X
  190. X  /* this contains the basic properties of a race, which are read in
  191. X     from the "races" file.  this does NOT include other attributes
  192. X     gained later by a nation.
  193. X   */
  194. Xstruct srace {
  195. X  char name[NAMELEN];
  196. X  char mark;            /* to represent them on map */
  197. X  int strength, repro, mortality, intel, speed, stealth;
  198. X  int pref_alt, pref_terrain, pref_climate;
  199. X  int mag_apt, farming, mining;
  200. X};
  201. Xtypedef struct srace Srace;
  202. X
  203. Xstruct race_list {
  204. X  Srace race;
  205. X  struct race_list *next;
  206. X};
  207. X
  208. X/* This structures stores a nations options */
  209. Xstruct soptions {
  210. X  int expert_mode;
  211. X  int civ_movemode;
  212. X  char *mail_forward;
  213. X  char *mail_reader;
  214. X};
  215. Xtypedef struct soptions Soptions;
  216. X
  217. Xstruct snation {
  218. X  int id;            /* for quick search */
  219. X  char name[NAMELEN];
  220. X  char leader[NAMELEN];
  221. X  char passwd[PASSLEN];        /* encrypted, of course */
  222. X  Pt capital;            /* coordinates of main city */
  223. X  Srace race;
  224. X  Symbol mark;            /* nation mark */
  225. X    /* parameters that influence the economy */
  226. X  int taxes, taxtype, charity, money, jewels, metal, food, n_sects,
  227. X      tech_r_d, tech_r_d_metal, mag_r_d, mag_r_d_jewels, spy_r_d,
  228. X      npc_flag, npc_agg, npc_exp, npc_iso; /* NPC performance values */
  229. X  
  230. X  char mag_order[NAMELEN];    /* which magical order they belong to */
  231. X  int tech_skill, mag_skill, farm_skill, mine_skill; /* skills */
  232. X  int spell_pts;        /* available spell points */
  233. X    /* military stuff */
  234. X  int attack, defense, spy, secrecy;
  235. X  int n_armies;
  236. X  Sarmy *armies;        /* linked list of armies */
  237. X  struct pt_list *ptlist;    /* list of owned points */
  238. X  int cur_mag_r_d, cur_mag_r_d_jewels;
  239. X  int cur_tech_r_d, cur_tech_r_d_metal;
  240. X  int cur_spy_r_d;
  241. X  Soptions *opts;
  242. X};
  243. Xtypedef struct snation Snation;
  244. X
  245. X#define NORMAL_MAP  0        /* map_style: non-compact map display */
  246. X#define COMPACT_MAP 1        /* map_style: compact map display */
  247. X#define DESIGNATION 0        /* display: show sector designation */
  248. X#define NATION_MARK 1        /* display: show nation mark */
  249. X#define SOIL        2        /* display: show vegetation */
  250. X#define METAL        3        /* etc... */
  251. X#define JEWELS      4
  252. X#define ALTITUDE    5
  253. X#define CLIMATE     6
  254. X#define POPULATION  7
  255. X#define MOVECOST    8
  256. X#define TERRAIN     9
  257. X#define ARMY_MOVECOST 10
  258. X
  259. X#define H_NONE        0        /*            don't highlight */
  260. X#define H_OWNED       1        /* highlight: if you own sector */
  261. X#define H_ARMIES      2        /*            if there are armies */
  262. X#define H_YOUR_ARMIES 3        /*            if they are your armies */
  263. X#define H_OTHER_ARMIES 4    /*            if they are not yours */
  264. X#define H_MOVE_LEFT   5        /*            if armies can move */
  265. X#define H_UNEMP       6        /*            if there are civ's unemployed */
  266. X#define H_HOSTILE     7        /*            if the sector is hostile */
  267. X
  268. X  /* the following prepare the ground for the exec list array */
  269. X#define N_EXEC_ARGS 12        /* for now, exec has 8 args */
  270. X#define N_EXECS     2        /* # of exec commands before we save to file */
  271. X#define EXECLEN     100        /* max length of exec string */
  272. X
  273. X  /* spell structure, used for describing a spell, and also
  274. X     for giving each user a list of available spells
  275. X   */
  276. Xstruct sspell {
  277. X  char name[NAMELEN];        /* name of spell */
  278. X  int cost, duration;
  279. X/*  int (*spell_func)();          /* pointer to function that does the work */
  280. X  struct sspell *next;        /* for a linked list */
  281. X};
  282. Xtypedef struct sspell Sspell;
  283. X
  284. Xstruct sh_spell {
  285. X  int nat_id;
  286. X  char name[NAMELEN];
  287. X  int thons_left;
  288. X  int n_lines;
  289. X  char **lines;
  290. X  struct sh_spell *next;
  291. X};
  292. Xtypedef struct sh_spell Sh_spell;
  293. X
  294. X  /* avail army structure, used for describing available armies */
  295. Xstruct savail_army {
  296. X  char type[NAMELEN];        /* type of army */
  297. X  struct savail_army *next;    /* for a linked list */
  298. X};
  299. Xtypedef struct savail_army Savail_army;
  300. X
  301. X  /* spirit structure, used for describing available spirits */
  302. Xstruct sspirit {
  303. X  char type[NAMELEN];        /* type of spirit */
  304. X    /* cost can be different for different
  305. X       mag orders, even if it is the same
  306. X       spirit
  307. X     */
  308. X  int cost;
  309. X  struct sspirit *next;        /* for a linked list */
  310. X};
  311. Xtypedef struct sspirit Sspirit;
  312. X
  313. X/* the following structure is the matrix used for diplomacy */
  314. X/* for more info, see diplomacy.c */
  315. Xstruct sdiplo {
  316. X  int self_id, neighbor_id;  /* player, and his neighbor */
  317. X  int status;                /* status from player to neighbor */
  318. X};
  319. Xtypedef struct sdiplo Sdiplo;
  320. X
  321. X  /* this structure describes run-time information for the user
  322. X     currently playing.  It is contains their nation struct.
  323. X   */
  324. Xstruct suser {
  325. X  int id;            /* nation id */
  326. X  Snation *np;            /* describe her/his nation */
  327. X  Pt cursor, center;        /* current sector and middle of screen */
  328. X  char help_char;        /* char used to get help */
  329. X    /* display styles */
  330. X  int map_style, display, highlight, underwater;
  331. X  int **visible_sectors;    /* which sectors can the user see? */
  332. X  Sdiplo **diplo_matrix;    /* fast-access diplo matrix */
  333. X  int n_execs;            /* how many exec lines already there */
  334. X  char exec_lines[N_EXECS][EXECLEN];
  335. X  int current_army;        /* army that has been picked */
  336. X  int just_moved;        /* has the user just moved? */
  337. X    /* how much did we have at the start of the turn */
  338. X  int init_money, init_metal, init_jewels, init_food;
  339. X/*should have other run-time info, taken from world parameters, like date*/
  340. X    /* available types armies to that user */
  341. X  Savail_army *avail_armies;
  342. X    /* this is read in at the beginning of a session, and has a
  343. X       list of spells available to this user.  same thing for spirits.
  344. X     */
  345. X  Sspell *spell_list;
  346. X  Sh_spell *h_spells;
  347. X  Sspirit *spirit_list;
  348. X    /* this is a funny global variable, needed for
  349. X       consistency in drawing the army list
  350. X     */
  351. X  int last_n_armies;
  352. X    /* number of army/spirit types there are */
  353. X  int n_army_types, n_spirit_types;
  354. X    /* now some user-configurable options */
  355. X  int xmode, show_sect_win;
  356. X};
  357. Xtypedef struct suser Suser;
  358. X
  359. Xstruct ssector {
  360. X  Pt loc;        /* x, y coords */
  361. X    /* if terrain is water, some of these don't apply */
  362. X        /* a lot must be re-considered here */
  363. X  int terrain, altitude, climate, designation, soil, metal, jewels;
  364. X  int defense;            /* defense bonus in sector */
  365. X  int roads;            /* how easy to travel */
  366. X  int owner;            /* index of sector's owner */
  367. X  int n_people;            /* civilians in that sector */
  368. X  long flags;            /* sector flags */
  369. X  char name[NAMELEN];        /* you can name a sector!!! */
  370. X    /* the sector has a list of army id's, where the owner and army
  371. X       id are stored, so the army can be obtained from the nation's
  372. X       army list.
  373. X     */
  374. X  struct armyid *alist;
  375. X};
  376. Xtypedef struct ssector Ssector;
  377. X
  378. X  /* world topology type */
  379. X#define TORUS 0
  380. X
  381. X/* extern Pt wrap();        /* this func. determines topology */
  382. X
  383. Xstruct sworld {
  384. X  int turn;
  385. X  int xmax, ymax;
  386. X  Ssector **map;
  387. X  struct {
  388. X    int topology;        /* topology type */
  389. X    int pwater;            /* % water in world */
  390. X    double metal_avg, jewel_avg, soil_avg; /* averages for the world */
  391. X  } geo;            /* geography */
  392. X  int n_nations;        /* how many nations are actually there? */
  393. X  Snation nations[NATIONS];
  394. X};
  395. Xtypedef struct sworld Sworld;
  396. X
  397. Xstruct argument {
  398. X  int type;
  399. X  union {
  400. X    int num;
  401. X    char str[20];
  402. X  } data;
  403. X};
  404. X
  405. X#define NUM 0    /* values for -type- field of above structure */
  406. X#define TXT 1
  407. X
  408. X#define NUMCMDS 200
  409. X
  410. X  /* declare malloc() as returning a void *.  Don't even
  411. X     try including malloc.h, since it is not there on very
  412. X     many systems.  If you don't have type "void", then
  413. X     you can make it be "char *malloc()".
  414. X   */
  415. Xvoid *malloc();
  416. X
  417. X#ifndef max
  418. X#define max(a,b) ((a)<(b) ? (b) : (a))
  419. X#endif
  420. X#ifndef min
  421. X#define min(a,b) ((a)>(b) ? (b) : (a))
  422. X#endif
  423. X
  424. X#ifdef PMAX
  425. X#define mvwprintw mymvwprintw
  426. X#endif
  427. END_OF_FILE
  428. if test 13830 -ne `wc -c <'dominion.h'`; then
  429.     echo shar: \"'dominion.h'\" unpacked with wrong size!
  430. fi
  431. # end of 'dominion.h'
  432. fi
  433. if test -f 'int_mail.c' -a "${1}" != "-c" ; then 
  434.   echo shar: Will not clobber existing file \"'int_mail.c'\"
  435. else
  436. echo shar: Extracting \"'int_mail.c'\" \(15808 characters\)
  437. sed "s/^X//" >'int_mail.c' <<'END_OF_FILE'
  438. X  /* mailer.c -- dominion mail reading system by Stephen Underwood */
  439. X  /*                                          and Doug Novellano :) */
  440. X
  441. X/*
  442. X * Copyright (C) 1990 Free Software Foundation, Inc.
  443. X * Written by the dominion project.
  444. X *
  445. X * This file is part of dominion.
  446. X *
  447. X * dominion is free software; you can redistribute it and/or
  448. X * modify it under the terms of the GNU General Public License as published
  449. X * by the Free Software Foundation; either version 1, or (at your option)
  450. X * any later version.
  451. X *
  452. X * This software is distributed in the hope that it will be useful,
  453. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  454. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  455. X * GNU General Public License for more details.
  456. X *
  457. X * You should have received a copy of the GNU General Public License
  458. X * along with this software; see the file COPYING.  If not, write to
  459. X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  460. X */
  461. X
  462. X#include "dominion.h"
  463. X#include <stdio.h>
  464. X#ifdef AMIGA
  465. X# include <exec/types.h>
  466. X# include <string.h>
  467. X#else
  468. X# include <sys/types.h>
  469. X#endif
  470. X
  471. X#include <time.h>
  472. X#ifdef SYSV
  473. X# include <string.h>
  474. X#else
  475. X# include <strings.h>
  476. X#endif
  477. X#include <ctype.h>
  478. X
  479. Xextern Suser user;
  480. Xextern Sworld world;
  481. Xextern char *libdir;
  482. Xextern int ruid, euid;
  483. X
  484. Xstruct message {
  485. X  struct message_body *body;
  486. X  char status;
  487. X  struct message *next;
  488. X};
  489. X  
  490. Xstruct message_body {
  491. X  char *line;
  492. X  struct message_body *next;
  493. X};
  494. X
  495. X/* Read the persons mail. Reader is the name
  496. X   of the nations whose mail is to be read.
  497. X */
  498. Xint mail_read(reader)
  499. X     int reader;
  500. X{
  501. X  FILE *lock_fp;
  502. X  char mail_command[100],mail_file[PATHLEN];
  503. X  char lock_fn[100], *mail_prog, *getenv();
  504. X#ifdef UID_SECURITY
  505. X      int pid;
  506. X#endif
  507. X
  508. X/*
  509. X  if ((mail_prog=getenv("DOMINION_MAIL"))==NULL) {
  510. X    mail_prog=(char *)malloc(sizeof(DEFAULT_MAIL));
  511. X    strcpy(mail_prog, DEFAULT_MAIL);
  512. X  }
  513. X*/
  514. X  mail_prog = world.nations[reader].opts->mail_reader;
  515. X
  516. X/* This is going to be essentially what's in int_mail.c */
  517. X  if (mail_prog == NULL) 
  518. X  {
  519. X    sprintf(mail_file,"%s/mail.%d",MAIL_DIR, reader);
  520. X    printf("\n\n");
  521. X    fflush(stdin);
  522. X    fflush(stdout);
  523. X    mail_reader(mail_file);
  524. X  }
  525. X  else /* We want to use our own mail program */
  526. X  {
  527. X    char tmp_fname[PATHLEN];
  528. X    cleanup(); /* Get ready to leave the system */
  529. X    /* we must make the file read/modify-able.  is this a security prob? */
  530. X/* Yes it was */
  531. X/*      sprintf(mail_command, "chmod 666 \"%s/mail.%d\"", MAIL_DIR, reader);
  532. X      system(mail_command);
  533. X*/
  534. X    strcpy(tmp_fname,"/usr/tmp/dom_XXXXXX");
  535. X    mktemp(tmp_fname);
  536. X    sprintf(mail_command, "cp %s/mail.%d %s", MAIL_DIR, reader,tmp_fname);
  537. X    system(mail_command);
  538. X    sprintf(mail_command, "chmod 666 %s", tmp_fname);
  539. X    system(mail_command);
  540. X
  541. X#ifdef UID_SECURITY
  542. X      /* we must fork, so that in the child we set the
  543. X     real user id, whereas the parent continues with
  544. X     the effective user id.
  545. X     */
  546. X
  547. X      if ((pid=fork()) == 0) {        /* child has fork() == 0 */
  548. X      setuid(getuid());        /* so this user cannot poke around */
  549. X#endif
  550. X    sprintf(mail_command, "%s -f %s", mail_prog, tmp_fname);
  551. X    system(mail_command);
  552. X#ifdef UID_SECURITY
  553. X      exit(0);
  554. X      }
  555. X      else if (pid < 0)
  556. X      perror("Could not fork mailer");
  557. X      else
  558. X      while (wait(0) != pid);
  559. X#endif UID_SEQURITY
  560. X    sprintf(mail_command,"cp %s %s/mail.%d",tmp_fname,MAIL_DIR,reader);
  561. X    system(mail_command);
  562. X    unlink(tmp_fname);
  563. X
  564. X    init_screen(); /* Resetup the screen after coming back */
  565. X  }
  566. X}
  567. X
  568. Xchar *get_line(fp)
  569. X/* Gets a single line from the file fp and returns it, or returns NULL */
  570. XFILE *fp;
  571. X{
  572. X  char *temp;
  573. X
  574. X  if ((temp = (char *)malloc((COLS+1) * sizeof(char))) == NULL) mem_error();
  575. X  if ( (fgets(temp,COLS-1,fp) == NULL))
  576. X  {
  577. X    free(temp);
  578. X    return NULL;
  579. X  } 
  580. X  temp[COLS-1] = '\0';
  581. X  if (temp[strlen(temp) -1] != '\n') strcat(temp,"\n");
  582. X  return temp;
  583. X}    
  584. X
  585. Xis_fromline(s)
  586. X/* Determines if the string passed it is the start of a new message */
  587. Xchar *s;
  588. X{
  589. X  if (s == NULL) return 0;
  590. X  if (strncmp(s,"From ",5) == 0) return 1;
  591. X  return 0;
  592. X}
  593. X
  594. Xadd_line(mbody, text)
  595. X/* Adds a new line onto the end of the message passed to it. */
  596. Xstruct message_body **mbody;
  597. Xchar *text;
  598. X{
  599. X  struct message_body *last_mbody = *mbody, *temp;
  600. X
  601. X  if (*mbody == NULL)
  602. X  {
  603. X    if ((*mbody = (struct message_body *) malloc(sizeof(struct message_body)))
  604. X             == NULL) { 
  605. X      mem_error();
  606. X    }
  607. X    (*mbody)->next = NULL;
  608. X    (*mbody)->line = text;
  609. X  } else
  610. X  {
  611. X    while (last_mbody->next != NULL) last_mbody = last_mbody->next;
  612. X    if ((temp = (struct message_body *) malloc(sizeof(struct message_body)))
  613. X             == NULL) {
  614. X      mem_error();
  615. X    }
  616. X    last_mbody->next = temp;
  617. X    temp->next = NULL;
  618. X    temp->line = text;
  619. X  }
  620. X}
  621. X
  622. Xmail_reader(fname)
  623. X/* 
  624. X  This routine acts like a very simple mail program, in that it allows
  625. X  the user to read their mail, and to delete messages, and even to write
  626. X  the messages to a file.  However you are still required with this program
  627. X  to proceede linearly one message at a time through all your mail.
  628. X*/
  629. Xchar *fname;
  630. X{
  631. X  FILE *fp, *fpout, *fopen(); /* fp is the mailfile fpout is a temp file */
  632. X  char outfname[PATHLEN], cmd[2*PATHLEN];
  633. X  int wrote_to_outfile = 0, num_mess;
  634. X  struct message *first_mesg = NULL;
  635. X
  636. X  if ((fp = fopen(fname,"r")) == NULL) /* Open the mail file */
  637. X  {
  638. X    fprintf(stderr,"No Mail\n");
  639. X    return 0;
  640. X  }
  641. X  sprintf(outfname, "%s.out", fname);
  642. X  if ((fpout = fopen(outfname,"w")) == NULL) /* Open our temp file */
  643. X  {
  644. X    fprintf(stderr,"Error: Can't open Temporary Mailfile\n");
  645. X    return 0;
  646. X  }
  647. X  if ((num_mess = load_messages(fp,&first_mesg)) < 1 )
  648. X  {
  649. X    fprintf(stderr,"No Mail\n");
  650. X    return 0;
  651. X  }
  652. X/*  initscr(); */
  653. X  display_messages(first_mesg,num_mess);
  654. X  if (write_messages(fpout, first_mesg) != 0)
  655. X  {
  656. X    fclose(fpout); /* Close the temporary file */
  657. X    sprintf(cmd,"mv %s %s",outfname,fname);  /* then replace the mailfile */
  658. X  } else
  659. X  {
  660. X    fclose(fpout); /* Close the temporary file */
  661. X    sprintf(cmd,"rm %s",fname); /* Otherwise remove the mailfile */
  662. X    unlink(outfname);
  663. X  }
  664. X#ifdef UID_SECURITY
  665. X  if (fork() == 0) {        /* child has fork() == 0 */
  666. X    setuid(getuid());
  667. X    system(cmd);
  668. X    exit(0);
  669. X  }
  670. X#else
  671. X  system(cmd);
  672. X#endif
  673. X  
  674. X  clear_messages(first_mesg);
  675. X}
  676. X
  677. Xput_mesg_to_file(mbody)
  678. X/*
  679. X   This function is to write the given message out to a file the
  680. X   user specifies
  681. X*/
  682. Xstruct message_body *mbody;
  683. X{
  684. X  FILE *fp, *fopen();
  685. X  char fname[PATHLEN];
  686. X  extern int ruid, euid;
  687. X#ifdef BSD
  688. X extern char current_dir[];
  689. X#else /* BSD */
  690. X extern char *current_dir;
  691. X#endif
  692. X
  693. X  printw("Name of File? ");
  694. X  refresh();
  695. X  wget_string(stdscr,fname,PATHLEN-1);
  696. X  if (fname[strlen(fname)-1] == '\n') fname[strlen(fname)-1] = '\0';
  697. X
  698. X#ifdef UID_SECURITY
  699. X  if (fork() == 0) {        /* child has fork() == 0 */
  700. X      /* first change back to the user's current directory */
  701. X    setuid(ruid);
  702. X    chdir(current_dir);
  703. X    if ((fp = fopen(fname, "w")) == NULL) {
  704. X      fprintf(stderr,"Error: could not write to file %d",fname);
  705. X      exit(0);
  706. X    }
  707. X    put_mesg(fp,mbody);
  708. X    fclose(fp);
  709. X    exit(0);
  710. X  }
  711. X  wait(0);
  712. X#else /* UID_SECURITY */
  713. X  chdir(current_dir);
  714. X  if ((fp = fopen(fname, "w")) == NULL) {
  715. X    fprintf(stderr,"Error: could not write to file %d",fname);
  716. X    return -1;
  717. X  }
  718. X  put_mesg(fp,mbody);
  719. X  fclose(fp);
  720. X  chdir(libdir);
  721. X#endif /* UID_SECURITY */
  722. X
  723. X  return 0;
  724. X}
  725. X
  726. Xput_mesg(fp,mbody)
  727. X/* This function puts the given message into the file passed to it */
  728. XFILE *fp;
  729. Xstruct message_body *mbody;
  730. X{
  731. X  struct message_body *curr = mbody;
  732. X
  733. X  while (curr != NULL)
  734. X  {
  735. X    fprintf(fp,"%s",curr->line);
  736. X    curr = curr->next;
  737. X  }
  738. X}
  739. X
  740. Xclear_mesg(mbody)
  741. X/* Clean up the memory for a given message */
  742. Xstruct message_body **mbody;
  743. X{
  744. X  struct message_body *curr = *mbody, *temp;
  745. X
  746. X  while (curr != NULL)
  747. X  {
  748. X    temp = curr;
  749. X    curr = curr->next;
  750. X    if (temp->line != NULL) free(temp->line);
  751. X    if (temp != NULL) free(temp);
  752. X  }
  753. X  *mbody = NULL;  /* And clean up the beginning */
  754. X}
  755. X
  756. Xadd_rest(fpout, fpin)
  757. X/* Add the rest of the mailfile to the temporary output file */
  758. XFILE *fpout, *fpin;
  759. X{
  760. X  int c;
  761. X
  762. X  while ((c = fgetc(fpin)) != EOF)
  763. X  {
  764. X     fputc(c,fpout);
  765. X  }
  766. X}
  767. X
  768. Xget_message(fp, mbody, first_flag)
  769. Xint first_flag;
  770. Xstruct message_body **mbody;
  771. XFILE *fp;
  772. X{
  773. X  static char *from_line = NULL;
  774. X  char *curr_text;
  775. X  int first_line = first_flag;
  776. X
  777. X  while ((curr_text = get_line(fp)) != NULL) {
  778. X    if ((is_fromline(curr_text)) && (!first_line))
  779. X    { /* If it's the begining of any message but the first */
  780. X      from_line = curr_text; /* save the beginning line of the next message*/
  781. X      return 0;
  782. X    }
  783. X    if (from_line != NULL) /* If we have a leftover first line */
  784. X    {
  785. X      add_line(mbody, from_line);  /* Add it to the message */
  786. X      from_line = NULL;
  787. X    }
  788. X    add_line(mbody, curr_text); /* Add the current line to the mesg */
  789. X    first_line = 0;
  790. X  }
  791. X
  792. X /* If it's the end of the file return 1 */
  793. X  return 1;
  794. X}
  795. X
  796. Xprint_message(mbody)
  797. Xstruct message_body *mbody;
  798. X{
  799. X  int curr_line = 0, i;
  800. X  struct message_body *curr = mbody;
  801. X  char temp[100];
  802. X
  803. X  clear(); refresh();
  804. X  if (curr != NULL) { curr = curr->next; } /* Don't print from line */
  805. X  while (curr != NULL)
  806. X  {
  807. X    printw("%s",curr->line); /* Print out the next line */
  808. X    if ( ++curr_line >= (LINES - 1))
  809. X    { /* break for the end of the scren */
  810. X      printw("---More--- Press return to cont. j to jump to next message : ");
  811. X      refresh();
  812. X      wget_string(stdscr,temp,39);
  813. X      clear();
  814. X      curr_line = 0;
  815. X      if ((temp[0] == 'j') || (temp[0] == 'J')) 
  816. X      {
  817. X        return 0;
  818. X      }
  819. X    }
  820. X    curr = curr->next;
  821. X  }
  822. X  printw("Press return to continue");
  823. X  refresh();
  824. X  wget_string(stdscr,temp,39);
  825. X  curr_line = 0;
  826. X}
  827. X
  828. Xload_messages(fp,first_mesg)
  829. XFILE *fp;
  830. Xstruct message **first_mesg;
  831. X{
  832. X  int file_over = 0, num_mess = 0, first_flag = 1;
  833. X  struct message *curr_mesg = NULL;
  834. X  struct message_body *curr_mbody = NULL;
  835. X
  836. X  do {
  837. X    file_over = get_message(fp, &curr_mbody, first_flag);
  838. X    if ( curr_mbody == NULL ) { break; }
  839. X    num_mess++;
  840. X    if (curr_mesg == NULL)
  841. X    {
  842. X      if ((curr_mesg = (struct message *)malloc(sizeof (struct message)))
  843. X          == NULL) { mem_error(); }
  844. X      *first_mesg = curr_mesg;
  845. X    } else
  846. X    {
  847. X      if ((curr_mesg->next = (struct message *)malloc(sizeof (struct message)))
  848. X          == NULL) { mem_error(); }
  849. X      curr_mesg = curr_mesg->next;
  850. X    }
  851. X    curr_mesg->body = curr_mbody;
  852. X    curr_mbody = NULL;
  853. X    curr_mesg->next = NULL;
  854. X    curr_mesg->status = ' ';
  855. X    first_flag = 0; /* Stop special handling for first message */
  856. X  } while (file_over != 1);
  857. X
  858. X  return num_mess;
  859. X}
  860. X
  861. Xwrite_messages(fp, first_mesg)
  862. XFILE *fp;
  863. Xstruct message *first_mesg;
  864. X{
  865. X  struct message *curr_mesg = first_mesg;
  866. X  int rtvl = 0;
  867. X
  868. X  while ( curr_mesg != NULL )
  869. X  {
  870. X    switch (curr_mesg->status)
  871. X    {
  872. X      case 'd': break;
  873. X      default: {
  874. X    rtvl = 1;
  875. X        put_mesg(fp,curr_mesg->body);
  876. X        break;
  877. X      }
  878. X    }
  879. X    curr_mesg = curr_mesg->next;
  880. X  }
  881. X  return rtvl;
  882. X}
  883. X
  884. Xstruct message *get_mesg_by_number(first, num)
  885. Xstruct message *first;
  886. Xint num;
  887. X{
  888. X  struct message *curr_mesg = first;
  889. X  int i = 0;
  890. X
  891. X  if (num < 0) { return NULL; }
  892. X  while (i < num) {
  893. X    if (curr_mesg == NULL) { return NULL; }
  894. X    curr_mesg = curr_mesg->next;
  895. X    i++;
  896. X  }
  897. X
  898. X  return curr_mesg;
  899. X}
  900. X
  901. Xchar *get_from(mesg)
  902. Xstruct message *mesg;
  903. X{
  904. X  struct message_body *curr_line = mesg->body;
  905. X
  906. X  while (curr_line != NULL) {
  907. X    if (curr_line->line == NULL) { continue; }
  908. X    if (strncmp(curr_line->line, "From: ", strlen("From: ")) == 0) {
  909. X      return &(curr_line->line[6]);
  910. X    }
  911. X    curr_line = curr_line->next;
  912. X  }
  913. X  return NULL;
  914. X}
  915. X
  916. Xchar *get_subject(mesg)
  917. Xstruct message *mesg;
  918. X{
  919. X  struct message_body *curr_line = mesg->body;
  920. X
  921. X  while (curr_line != NULL) {
  922. X    if (curr_line->line == NULL) { continue; }
  923. X    if (strncmp(curr_line->line, "Subject: ", strlen("Subject: ")) == 0) {
  924. X      return &(curr_line->line[9]);
  925. X    }
  926. X    curr_line = curr_line->next;
  927. X  }
  928. X  return NULL;
  929. X}
  930. X
  931. Xdisplay_messages(first_mesg,num_mess)
  932. Xint num_mess;
  933. Xstruct message *first_mesg;
  934. X{
  935. X  struct message *curr_mesg = first_mesg, *temp_mesg;
  936. X  struct message_body *curr_mbody;
  937. X  int user_quit = 0, num_top = 0, num_bottom, num_curr = 0, i, j;
  938. X  int chose_option, do_refresh = 1, x, y, oldx, oldy;
  939. X  char temp[40], *from, *subject;
  940. X#define USED_LINES 8
  941. X
  942. X  while ( user_quit == 0 )
  943. X  {
  944. X    if (do_refresh == 1) {
  945. X      clear(); refresh();
  946. X      num_bottom = num_top + (LINES - USED_LINES);
  947. X      move(1, 0);
  948. X      for (i = num_top;i <= num_bottom; i++)
  949. X      {
  950. X        if ((temp_mesg = get_mesg_by_number(first_mesg, i)) == NULL) {
  951. X          break;
  952. X        }
  953. X        from = get_from(temp_mesg);
  954. X        subject = get_subject(temp_mesg);
  955. X        printw("          %c%.2d %c ",(i == num_curr)?'*' : ' ',i,
  956. X               temp_mesg->status);
  957. X        for(j = 0; (j < 30) && (from[j] != '\0') && (from[j] !='\n') ; j++)
  958. X        {
  959. X          addch(from[j]);
  960. X        }
  961. X        for ( j = j - 1; j < 30  ; j++) { addch(' '); }
  962. X        addch(' ');
  963. X        for(j = 0; (j < 30)&&(subject[j] != '\0')&& (subject[j] !='\n') ; j++)
  964. X        {
  965. X          addch(subject[j]);
  966. X        }
  967. X        for ( j = j - 1; j < 30  ; j++) { addch(' '); }
  968. X        addch('\n');
  969. X      }
  970. X      do_refresh = 0;
  971. X      addch('\n');
  972. X      move(LINES - 4, 0);
  973. X      printw("[R]ead curr [W]rite to file, [D]elete, [U]ndelete, [Q]uit\n");
  974. X      printw("> for next page < for prev page Enter number to change curr\n");
  975. X    } 
  976. X    move(LINES - 2, 0);
  977. X    printw("[RWDQ><#]:                ");
  978. X    move(LINES - 2, 11);
  979. X    refresh();
  980. X    wget_string(stdscr,temp,39);
  981. X    chose_option = 1;
  982. X    if (isupper(temp[0])) { temp[0] = (char)tolower(temp[0]); }
  983. X    switch (temp[0])
  984. X    {
  985. X      case 'w': do_refresh = 1; put_mesg_to_file(curr_mesg->body); break;
  986. X      case 'd': {
  987. X        curr_mesg->status = 'd'; 
  988. X        getyx(stdscr,oldy,oldx);
  989. X        move(num_curr - num_top + 1, 14);
  990. X        addch('d');
  991. X        getyx(stdscr, y, x);
  992. X        mvcur(y, x, oldy, oldx);
  993. X        move(oldy, oldx);
  994. X        refresh();
  995. X        break;
  996. X      }
  997. X      case 'u': {
  998. X        curr_mesg->status = ' '; 
  999. X        getyx(stdscr,oldy,oldx);
  1000. X        move(num_curr - num_top + 1, 14);
  1001. X        addch(' ');
  1002. X        getyx(stdscr, y, x);
  1003. X        mvcur(y, x, oldy, oldx);
  1004. X        move(oldy, oldx);
  1005. X        refresh();
  1006. X        break;
  1007. X      }
  1008. X      case 'r': do_refresh = 1; print_message(curr_mesg->body); break;
  1009. X      case '>': {
  1010. X         if ((num_top += (LINES - USED_LINES)) >= num_mess) { 
  1011. X           num_top -= (LINES - USED_LINES);
  1012. X         }
  1013. X         num_curr = num_top;
  1014. X         curr_mesg = get_mesg_by_number(first_mesg, num_curr);
  1015. X         do_refresh = 1;
  1016. X         break;
  1017. X      }
  1018. X      case '<': {
  1019. X         if ((num_top -= (LINES - USED_LINES)) < 0) { 
  1020. X           num_top = 0;
  1021. X         }
  1022. X         num_curr = num_top;
  1023. X         curr_mesg = get_mesg_by_number(first_mesg, num_curr);
  1024. X         do_refresh = 1;
  1025. X         break;
  1026. X      }
  1027. X      case 'q': user_quit = 1; break;
  1028. X      default: {
  1029. X        getyx(stdscr,oldy,oldx);
  1030. X        move(num_curr - num_top + 1, 10);
  1031. X        addch(' ');
  1032. X        if (isdigit(temp[0])) {
  1033. X          i = atoi(temp);
  1034. X          if ((temp_mesg = get_mesg_by_number(first_mesg, i)) != NULL) {
  1035. X            curr_mesg = temp_mesg;
  1036. X            num_curr = i;
  1037. X            if ((i < num_top) || (i > num_bottom)) {
  1038. X              num_top = i;
  1039. X              do_refresh = 1;
  1040. X        }
  1041. X      }
  1042. X    }
  1043. X        move(num_curr - num_top + 1, 10);
  1044. X        addch('*');
  1045. X        getyx(stdscr, y, x);
  1046. X        mvcur(y, x, oldy, oldx);
  1047. X        move(oldy, oldx);
  1048. X        refresh();
  1049. X      }
  1050. X    }
  1051. X  }
  1052. X}
  1053. X
  1054. Xclear_messages(first_mesg)
  1055. Xstruct message *first_mesg;
  1056. X{
  1057. X  struct message *curr_mesg = first_mesg, *next_mesg;
  1058. X
  1059. X  while (curr_mesg != NULL)
  1060. X  {
  1061. X    next_mesg = curr_mesg->next;
  1062. X    clear_mesg(&(curr_mesg->body));
  1063. X    free(curr_mesg);
  1064. X    curr_mesg = next_mesg;
  1065. X  }
  1066. X}
  1067. X
  1068. X/*#endif*/
  1069. END_OF_FILE
  1070. if test 15808 -ne `wc -c <'int_mail.c'`; then
  1071.     echo shar: \"'int_mail.c'\" unpacked with wrong size!
  1072. fi
  1073. # end of 'int_mail.c'
  1074. fi
  1075. if test -f 'printmap.c' -a "${1}" != "-c" ; then 
  1076.   echo shar: Will not clobber existing file \"'printmap.c'\"
  1077. else
  1078. echo shar: Extracting \"'printmap.c'\" \(13099 characters\)
  1079. sed "s/^X//" >'printmap.c' <<'END_OF_FILE'
  1080. X /* printmap.c -- print the nation */
  1081. X
  1082. X/*
  1083. X * Copyright (C) 1990 Free Software Foundation, Inc.
  1084. X * Written by the dominion project.
  1085. X *
  1086. X * This file is part of dominion.
  1087. X *
  1088. X * dominion is free software; you can redistribute it and/or
  1089. X * modify it under the terms of the GNU General Public License as published
  1090. X * by the Free Software Foundation; either version 1, or (at your option)
  1091. X * any later version.
  1092. X *
  1093. X * This software is distributed in the hope that it will be useful,
  1094. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1095. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1096. X * GNU General Public License for more details.
  1097. X *
  1098. X * You should have received a copy of the GNU General Public License
  1099. X * along with this software; see the file COPYING.  If not, write to
  1100. X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  1101. X */
  1102. X
  1103. X#include "dominion.h"
  1104. X#include "misc.h"
  1105. X#include "army.h"
  1106. X#include <stdio.h>
  1107. X#include <signal.h>
  1108. X#include <math.h>
  1109. X
  1110. Xextern Sworld world;
  1111. Xextern Suser user;
  1112. Xextern int debug;
  1113. Xextern int viewall;
  1114. Xextern char libdir[];
  1115. Xextern int (*wrapx)(), (*wrapy)();
  1116. X#ifdef BSD
  1117. Xextern char current_dir[];
  1118. X#else /* BSD */
  1119. Xextern char *current_dir, *getcwd();
  1120. X#endif
  1121. Xextern int euid, ruid;
  1122. X
  1123. Xint reverse_water=0;
  1124. Xint ascii_map=0;
  1125. Xint dash_sectors=0;
  1126. X#ifdef ANDREW
  1127. Xint beroot = 1;
  1128. X#endif
  1129. X
  1130. XSdiplo **allocate_diplo();
  1131. Xchar *des();
  1132. X
  1133. Xmain(argc, argv)
  1134. X     int argc;
  1135. X     char *argv[];
  1136. X{
  1137. X  char nation[NAMELEN], passwd[NAMELEN];
  1138. X  Snation *np;
  1139. X  Ssector *sp;
  1140. X  int i, j, iw, jw, ii, jj;        /* for loops */
  1141. X  int rel_xcenter, rel_ycenter, abs_xcenter, abs_ycenter;
  1142. X  int map_size, visibility, c, ascii=0;
  1143. X  int type1, type2, mark1, mark2;
  1144. X  extern char *optarg;
  1145. X  extern int optind;
  1146. X
  1147. X  /* rel_center vars are map center coords relative to your capital */
  1148. X  /* abs_center is the map center in absolute coordinates.  Secret! */
  1149. X  /* map_size is the number of sectors to display across the map    */
  1150. X  /* type1 is map shading type, type2 is desig || nation_mark text  */
  1151. X
  1152. X  strcpy(libdir, DEF_LIBDIR);
  1153. X#ifdef ANDREW
  1154. X  while ((c = getopt(argc, argv, "d:uxaWb")) != EOF) {
  1155. X#else
  1156. X  while ((c = getopt(argc, argv, "d:xaWs")) != EOF) {
  1157. X#endif
  1158. X    switch (c) {
  1159. X#ifdef ANDREW
  1160. X     case 'u':
  1161. X       beroot = 0;
  1162. X       break;
  1163. X#endif
  1164. X    case 'a':            /* ascii instead of postscript */
  1165. X      ascii = 1;
  1166. X      break;
  1167. X    case 'x':            /* debug mode */
  1168. X      debug = 1;
  1169. X      break;
  1170. X    case 'd':            /* lib directory */
  1171. X      strcpy(libdir, optarg);
  1172. X      break;
  1173. X    case 'W':            /* reverse above/below water */
  1174. X      reverse_water = 1;
  1175. X      break;
  1176. X    case 's':            /* show invisible sectors dashed */
  1177. X      dash_sectors = 1;
  1178. X      break;
  1179. X    }
  1180. X  }
  1181. X
  1182. X  /* now get some unix system information */
  1183. X#ifdef ANDREW
  1184. X  if (beroot == 1) {
  1185. X    Authenticate();
  1186. X    beGames();
  1187. X  }
  1188. X#else
  1189. X  ruid = getuid();
  1190. X  euid = geteuid();
  1191. X#endif
  1192. X
  1193. X  if (chdir(libdir) == -1) {
  1194. X    fprintf(stderr,"Error: cannot cd to directory %s\n",libdir);
  1195. X    clean_exit();
  1196. X    exit();
  1197. X  }
  1198. X  dom_print_intro();
  1199. X  load_army_types();
  1200. X  load_spirit_types();
  1201. X  get_user();            /* select & load nation */
  1202. X
  1203. X  get_display_type(&type1, &type2); /* display type (nation, desig... */
  1204. X  get_map_info(&rel_xcenter, &rel_ycenter, &map_size);
  1205. X
  1206. X  abs_xcenter = user.np->capital.x + rel_xcenter;
  1207. X  abs_ycenter = user.np->capital.y + rel_ycenter;
  1208. X
  1209. X#ifdef UID_SECURITY
  1210. X  setuid(ruid);
  1211. X#endif
  1212. X#ifdef ANDREW
  1213. X  if (beroot == 1) {
  1214. X    bePlayer();
  1215. X    unAuth();
  1216. X    beroot = 0;
  1217. X  }
  1218. X#endif
  1219. X  
  1220. X  ps_prolog(map_size, type1, type2);
  1221. X
  1222. X  ii = 0;
  1223. X  jj = map_size-1;
  1224. X
  1225. X  for (j = abs_ycenter - map_size/2; j < abs_ycenter + map_size/2; j++) {
  1226. X    for (i = abs_xcenter - map_size/2; i < abs_xcenter + map_size/2; i++) {
  1227. X      iw = (*wrapx)(i,j);
  1228. X      jw = (*wrapy)(i,j);
  1229. X      visibility = user.visible_sectors[iw][jw];
  1230. X      if (type1 != 99) {    /* do some kind of shading */
  1231. X    user.display = type1;
  1232. X    mark1 = which_mark(iw, jw, &user);
  1233. X      }
  1234. X      if (type2 != 99) {    /* do some text in sectors */
  1235. X    user.display = type2;
  1236. X    mark2 = which_mark(iw, jw, &user);
  1237. X      }
  1238. X
  1239. X      if (ascii_map) asc_mark(mark1, mark2, type1, type2, visibility);
  1240. X      else ps_mark(ii, jj, mark1, mark2, type1, type2, visibility);
  1241. X      ii++;
  1242. X    }
  1243. X
  1244. X    jj--; ii = 0;
  1245. X    if (ascii_map) printf("\n");
  1246. X  }
  1247. X  if (!ascii_map) {
  1248. X    draw_axes(map_size, rel_xcenter, rel_ycenter);
  1249. X    if (type1 != 99)
  1250. X      draw_key();
  1251. X    printf("\nshowpage\n\n");
  1252. X  }
  1253. X}
  1254. X
  1255. Xasc_mark(m, v)
  1256. X     int m, v;
  1257. X{
  1258. X}
  1259. X
  1260. X
  1261. Xdraw_key()
  1262. X{
  1263. X  printf("\ngrestore\n");
  1264. X  printf("/Times-Roman findfont 15 scalefont setfont\n");
  1265. X  printf("0 .1 1.01 { /i exch def\n");
  1266. X  printf("  /x 2.1 inch i 300 mul add def\n  /y 2 inch def\n");
  1267. X  printf("  x y moveto 18 0 rlineto 0 18 rlineto 18 neg 0 rlineto\n");
  1268. X  printf("  closepath gsave 1 i sub setgray fill grestore stroke\n");
  1269. X  printf("  x 4 add y .2 inch sub moveto i 10 mul round cvi str cvs show\n");
  1270. X  printf("  } for\n");
  1271. X}
  1272. X
  1273. X
  1274. Xdraw_axes(size, xc, yc)
  1275. X     int size, xc, yc;
  1276. X{
  1277. X  int x, y, step=1;
  1278. X
  1279. X  if (size > 50) step = 5;
  1280. X  else printf("\nsmallfont\n");
  1281. X
  1282. X  printf("\n/str 15 string def   /size %d def\n", size);
  1283. X  printf("/minx %d def  /miny %d def\n", xc-size/2, yc-size/2);
  1284. X  printf("0 %d size 1 sub { /i exch def /i2 i def\n", step);
  1285. X  printf("   i   -0.8    i minx add str cvs 1 letter  /i i2 def\n");
  1286. X  printf("   i   size    i minx add str cvs 1 letter  /i i2 def\n");
  1287. X  printf("  -1   size i sub 1 sub i miny add str cvs 1 letter  /i i2 def\n");
  1288. X  printf("  size size i sub 1 sub i miny add str cvs 1 letter\n");
  1289. X  printf("} for\n");
  1290. X}
  1291. X
  1292. Xps_prolog(size, type1, type2)
  1293. X     int size, type1, type2;
  1294. X{
  1295. X  printf("%%!\n");
  1296. X  printf("/inch { 72 mul } def\n");
  1297. X  printf("/center {dup stringwidth pop 2 div neg 0 rmoveto} bind def\n");
  1298. X  printf("/smallfont { /Courier findfont 25 scalefont setfont } def\n\n");
  1299. X
  1300. X  printf("/xaxis { /t exch def /x exch def gsave smallfont\n");
  1301. X  printf("   x .8 neg t 1 letter   x %d t 1 letter\n", size);
  1302. X  printf("   grestore } def\n");
  1303. X
  1304. X  printf("/yaxis { /t exch def /y exch def gsave smallfont\n");
  1305. X  printf("   1 neg y t 1 letter   %d y t 1 letter\n", size);
  1306. X  printf("   grestore } def\n\n");
  1307. X
  1308. X  printf("/box { newpath 0 0 moveto 0 64 lineto 64 64 lineto 64 0 lineto\n");
  1309. X  printf("     closepath } def\n\n");
  1310. X
  1311. X  printf("/graybox { /g exch def /y exch def /x exch def gsave\n");
  1312. X  printf("     x inch y inch translate box g setgray fill grestore } def\n\n");
  1313. X
  1314. X  printf("/emptybox { /y exch def /x exch def gsave\n");
  1315. X  printf("   x inch y inch translate box 0 setgray stroke grestore } def\n\n");
  1316. X
  1317. X  printf("/dashbox { /y exch def /x exch def gsave\n");
  1318. X  printf("     x inch y inch translate [3 9] 1 setdash box\n");
  1319. X  printf("     0 setgray stroke grestore } def\n");
  1320. X
  1321. X  printf("/waterbox { /y exch def /x exch def gsave\n");
  1322. X  printf("     x inch y inch translate  0 12 64 { /i exch def\n");
  1323. X  printf("       0 i moveto  64 i lineto stroke \n");
  1324. X  printf("     } for  grestore } def\n\n");
  1325. X
  1326. X  printf("/letter { /g exch def /t exch def /y exch def /x exch def\n");
  1327. X  printf("     gsave  x inch 20 add y inch 15 add translate 0 0 moveto\n");
  1328. X  printf("     g 0.5 lt { 1 setgray } { 0 setgray } ifelse\n");
  1329. X  printf("     t show grestore } def\n\n");
  1330. X
  1331. X  printf("/Times-Roman findfont 20 scalefont setfont\n");
  1332. X  printf("4.25 inch 10.5 inch moveto (%s) center show\n", user.np->name);
  1333. X  printf("/Times-Roman findfont 15 scalefont setfont\n");
  1334. X  printf("4.25 inch 10 inch moveto (%s/%s) center show\n", des(type1), des(type2));
  1335. X  printf("/Courier findfont 50 scalefont setfont\n\n");
  1336. X  printf("0.01 setlinewidth  gsave\n");
  1337. X  printf("1 inch 3 inch translate\n");
  1338. X  printf("%f %f scale\n\n", 6.5/size, 6.5/size);
  1339. X}
  1340. X
  1341. Xps_mark(x, y, m1, m2, t1, t2, vis)
  1342. X     int x, y, m1, m2, t1, t2, vis;
  1343. X{
  1344. X  float gray;
  1345. X  int other_char = '~';        /* which char represents 'other' world */
  1346. X
  1347. X  if (debug)
  1348. X    fprintf(stderr, "x=%d y=%d m1=%c m2=%c t1=%d t2=%d vis=%d\n",
  1349. X        x, y, m1, m2, t1, t2, vis);
  1350. X
  1351. X  if (user.underwater)
  1352. X    other_char = '.';
  1353. X
  1354. X  if (vis > SEE_NOTHING) {
  1355. X    if (m1 == other_char || m2 == other_char) {
  1356. X      printf("%d %d waterbox\n", x, y);
  1357. X    } else {
  1358. X      if (t1 != 99) {        /* if we are doing shading */
  1359. X    if (m1 == 'I' || m1 == '+') gray = 0.0;
  1360. X    else gray = 1 - (float)(m1 - '0') / 10.0;
  1361. X    if (gray == 1.0)    /* make blank white box visible */
  1362. X      printf("%d %d emptybox\n", x, y);
  1363. X    else            /* print a box of proper gray shade */
  1364. X      printf("%d %d %3.2f graybox\n", x, y, gray);
  1365. X      }
  1366. X      if (t2 != 99) {        /* do some text */
  1367. X    if (t1 == 99) {        /* haven't done anything yet, make box */
  1368. X      printf("%d %d emptybox\n", x, y);
  1369. X      gray = 1.0;
  1370. X    }
  1371. X    printf("%d %d (%c) %3.2f letter\n", x, y, m2, gray);
  1372. X      }
  1373. X    }
  1374. X  } else {            /* invisible sectors are dashed */
  1375. X    if (dash_sectors)
  1376. X      printf("%d %d dashbox\n", x, y);
  1377. X  }
  1378. X}
  1379. X
  1380. Xcritical()
  1381. X{
  1382. X}
  1383. Xnoncritical()
  1384. X{
  1385. X}
  1386. Xcleanup()
  1387. X{
  1388. X}
  1389. Xclean_exit()
  1390. X{
  1391. X#ifdef ANDREW
  1392. X  if (beroot == 1) {
  1393. X    bePlayer();
  1394. X    unAuth();
  1395. X    beroot = 0;
  1396. X  }
  1397. X#endif
  1398. X}
  1399. X
  1400. X/* GET_MAP_INFO asks the user where to center the map, and what size
  1401. X   it should be */
  1402. Xget_map_info(x, y, size, type1, type2)
  1403. X     int *x, *y, *size, *type1, *type2;
  1404. X{
  1405. X  char buff[NAMELEN];
  1406. X  int temp;
  1407. X
  1408. X  *x = *y = 0;
  1409. X  *size = 30;
  1410. X  fprintf(stderr, "\nCenter the map around what sector?\n");
  1411. X  fprintf(stderr, "       x coordinate [0]: ");
  1412. X  gets(buff);
  1413. X  if (strlen(buff)) {
  1414. X    sscanf(buff, "%d", &temp);
  1415. X    *x = temp;
  1416. X  }
  1417. X  fprintf(stderr, "       y coordinate [0]: ");
  1418. X  gets(buff);
  1419. X  if (strlen(buff)) {
  1420. X    sscanf(buff, "%d", &temp);
  1421. X    *y = temp;
  1422. X  }
  1423. X  fprintf(stderr, "\nHow many sectors across the map [30]: ");
  1424. X  gets(buff);
  1425. X  if (strlen(buff)) {
  1426. X    sscanf(buff, "%d", &temp);
  1427. X    if ( (float)(temp) / 2.0 != (float)(temp / 2) ) /* even number */
  1428. X      temp++;
  1429. X    *size = temp;
  1430. X  }
  1431. X  if (*size < 10) *size = 10;
  1432. X}
  1433. X
  1434. X/* GET_DISPLAY_TYPE get's the user's choice of the display parameter */
  1435. Xget_display_type(t1, t2)
  1436. X     int *t1, *t2;
  1437. X{
  1438. X  char buff[NAMELEN], a;
  1439. X
  1440. X  fprintf(stderr, "\np: population\t A: Altitude\t w: Climate\n");
  1441. X  fprintf(stderr, "t: Terrain\t s: Soil\t m: Metal\n");
  1442. X  fprintf(stderr, "j: Jewels\t M: Movecost\t N: None\n");
  1443. X  fprintf(stderr, "\nSelect sector shading from above list [None]: ");
  1444. X
  1445. X  gets(buff);
  1446. X  a = buff[0];
  1447. X
  1448. X  switch (a) {
  1449. X  case 'p':
  1450. X    *t1 = POPULATION;
  1451. X    break;
  1452. X  case 'A':
  1453. X    *t1 = ALTITUDE;
  1454. X    break;
  1455. X  case 'w':
  1456. X    *t1 = CLIMATE;
  1457. X    break;
  1458. X  case 't':
  1459. X    *t1 = TERRAIN;
  1460. X    break;
  1461. X  case 's':
  1462. X    *t1 = SOIL;
  1463. X    break;
  1464. X  case 'm':
  1465. X    *t1 = METAL;
  1466. X    break;
  1467. X  case 'j':
  1468. X    *t1 = JEWELS;
  1469. X    break;
  1470. X  case 'M':
  1471. X    *t1 = MOVECOST;
  1472. X    break;
  1473. X  default:
  1474. X    *t1 = 99;
  1475. X    break;
  1476. X  }
  1477. X
  1478. X  fprintf(stderr, "\nn: Nation Mark\t d: Designation\t N: None\n");
  1479. X  fprintf(stderr, "\nSelect sector text from above list [designation]: ");
  1480. X
  1481. X  gets(buff);
  1482. X  a = buff[0];
  1483. X
  1484. X  switch (a) {
  1485. X  case 'N':
  1486. X    *t2 = 99;
  1487. X    break;
  1488. X  case 'n':
  1489. X    *t2 = NATION_MARK;
  1490. X    break;
  1491. X  case 'd':
  1492. X  default:
  1493. X    *t2 = DESIGNATION;
  1494. X    break;
  1495. X  }
  1496. X}
  1497. X
  1498. X/* GET_USER actually takes care of reading in the world, selecting and
  1499. X   loading a nation, and setting up data (such as visibility) */
  1500. Xget_user()
  1501. X{
  1502. X  char nation[NAMELEN], passwd[NAMELEN];
  1503. X  int i;
  1504. X
  1505. X  read_world(&world, WORLD_FILE);
  1506. X  fprintf(stderr, "Enter nation name: ");
  1507. X  getline(nation, NAMELEN);
  1508. X  user.id = get_nation_id(nation);
  1509. X  get_crypt_pass("Your password: ", passwd, NULL, NULL);
  1510. X  if (strcmp(world.nations[user.id].passwd, passwd)) {
  1511. X    fprintf(stderr, "\nInvalid password.  AND, *I* only give you one try!\n");
  1512. X    exit(1);
  1513. X  }
  1514. X  user.np = &world.nations[user.id];
  1515. X
  1516. X  user.avail_armies = NULL;
  1517. X  get_avail_armies(&user, user.np->tech_skill);
  1518. X
  1519. X  user.spell_list = NULL;
  1520. X  user.spirit_list = NULL;
  1521. X  get_spells(&user, user.np->mag_skill);
  1522. X  get_spirits(&user, user.np->mag_skill);
  1523. X
  1524. X  if (user.id != 0)        /* Gamemaster is already loaded   */
  1525. X    load_nation(user.id, user.np); /* load their exec file etc    */
  1526. X
  1527. X  user.underwater = 0;
  1528. X  if (user.np->race.pref_alt < 0) /* set underwater preference   */
  1529. X    user.underwater = 1;
  1530. X  if (user.id == 0)        /* give Gamemaster clairvoyance */
  1531. X    viewall = 1;
  1532. X
  1533. X  user.diplo_matrix = allocate_diplo(world.n_nations);
  1534. X  read_in_diplo(user.diplo_matrix, world.n_nations);
  1535. X
  1536. X  user.visible_sectors = (int **) malloc(world.xmax*sizeof(int *));
  1537. X  for (i = 0; i < world.xmax; ++i)
  1538. X    user.visible_sectors[i] = (int *) malloc(world.ymax*sizeof(int));
  1539. X  find_visible_sectors(user.visible_sectors);
  1540. X
  1541. X  chdir("..");
  1542. X}
  1543. X
  1544. X
  1545. Xdom_print_intro()
  1546. X{
  1547. X  fprintf(stderr, "\ndom_print - postscript map printer\n\n");
  1548. X  fprintf(stderr, "Redirect output to file or pipe to printer.\n\n");
  1549. X  fprintf(stderr, " -d dir = set lib directory\n");
  1550. X  fprintf(stderr, " -W = invert above/below water\n");
  1551. X  fprintf(stderr, " -s = show invisible sectors dashed\n\n");
  1552. X}
  1553. X
  1554. X
  1555. Xchar *des(x)
  1556. X     int x;
  1557. X{
  1558. X  switch (x) {
  1559. X  case POPULATION:
  1560. X    return "Population";
  1561. X  case ALTITUDE:
  1562. X    return "Altitude";
  1563. X  case CLIMATE:
  1564. X    return "Climate";
  1565. X  case TERRAIN:
  1566. X    return "Terrain";
  1567. X  case SOIL:
  1568. X    return "Soil";
  1569. X  case METAL:
  1570. X    return "Metal";
  1571. X  case JEWELS:
  1572. X    return "Jewels";
  1573. X  case MOVECOST:
  1574. X    return "Movecost";
  1575. X  case DESIGNATION:
  1576. X    return "Designation";
  1577. X  case NATION_MARK:
  1578. X    return "Nation Mark";
  1579. X  default:
  1580. X    return " ";
  1581. X  }
  1582. X}
  1583. X
  1584. X
  1585. END_OF_FILE
  1586. if test 13099 -ne `wc -c <'printmap.c'`; then
  1587.     echo shar: \"'printmap.c'\" unpacked with wrong size!
  1588. fi
  1589. # end of 'printmap.c'
  1590. fi
  1591. if test -f 'races' -a "${1}" != "-c" ; then 
  1592.   echo shar: Will not clobber existing file \"'races'\"
  1593. else
  1594. echo shar: Extracting \"'races'\" \(1640 characters\)
  1595. sed "s/^X//" >'races' <<'END_OF_FILE'
  1596. X# this is the races file.  the format is:
  1597. X#   - comments at the start (like this one)
  1598. X#   - a line with the number of races defined in here
  1599. X#   - comments about the next race described
  1600. X#   - strings, chars and numbers describing the race, following
  1601. X#     the fields of the structure Srace, defined in dominion.h
  1602. X#   - repeat these last 2 steps, for as many races as prescribed
  1603. X#     at the beginning of this file
  1604. X#   - a section at the end with a list of army types that are
  1605. X#     specific to that race.  these require no technology to
  1606. X#     acquire
  1607. X#
  1608. X# for now I have defined Humans, Elves, Orcs, Dwarves, Hobbits, Merfolk,
  1609. X# Icefolk, Gnomes, Harpies, Ogres, Walruses, Algae, Squid
  1610. X#
  1611. X# DO NOT REMOVE THIS NUMBER!!! IT STATES HOW MANY RACES ARE DEFINED!!!
  1612. X13
  1613. X# Here is a list of the fields in the structure:
  1614. X#name:mark:str.:repro.:mortality:intel.:speed:stealth:pref_alt:pref_terrain:pref_climate:mag_apt:farming:mining
  1615. X#
  1616. XHuman    :H:80:11: 8:50:65:4: 2: 3: 7:30: 0:0
  1617. X#
  1618. XElf    :E:70: 8: 5:70:80:8: 2: 5: 7:55:10:-15
  1619. X#
  1620. XOrc    :O:50:15:10:20:40:3: 4: 4: 4:35: 0:5
  1621. X#
  1622. XDwarf    :D:95: 9: 6:60:40:2: 5: 3: 6:30:-5:20
  1623. X#
  1624. XHobbit    :h:15:10: 7:45:50:9: 3: 4: 7:20: 5:5
  1625. X#
  1626. XMerfolk    :M:30: 7: 4:75:80:7:-2:-1: 4:55:50:-10
  1627. X#
  1628. XIcefolk    :I:90: 9: 7:50:70:4: 3: 0:10:30:50:0
  1629. X#
  1630. XGnome   :G:75:10: 8:95:40:9: 4: 3: 5:10: 0:10
  1631. X#
  1632. XHarpy   :y:40:12:10:25:60:5: 5: 4: 6:30: 0:-5
  1633. X#
  1634. XOgre    :o:95: 5: 3:75:60:5: 4: 3: 6:50: 5:5
  1635. X#
  1636. XWalrus  :W:95: 9: 7:30:80:3:-1:-1: 7:55:50:5
  1637. X#
  1638. XAlgae   :A:15:11: 6:50:60:7:-2:-1: 3:45:80:0
  1639. X#
  1640. XSquid   :S:40: 9: 8:25:110:8:-2:-1:5:40:50:15
  1641. X#
  1642. X# now the race-specific army types
  1643. XOrc_armies:Orcs
  1644. XHarpy_armies:Harpies
  1645. XHobbit_armies:Hobbits
  1646. XOgre_armies:Ogres
  1647. END_OF_FILE
  1648. if test 1640 -ne `wc -c <'races'`; then
  1649.     echo shar: \"'races'\" unpacked with wrong size!
  1650. fi
  1651. # end of 'races'
  1652. fi
  1653. if test -f 'spelllib.c' -a "${1}" != "-c" ; then 
  1654.   echo shar: Will not clobber existing file \"'spelllib.c'\"
  1655. else
  1656. echo shar: Extracting \"'spelllib.c'\" \(12959 characters\)
  1657. sed "s/^X//" >'spelllib.c' <<'END_OF_FILE'
  1658. X  /* spelllib.c -- handls loading spells for a nation, and keeping
  1659. X                   them "hanging" for a certain number of turns.
  1660. X   */
  1661. X
  1662. X/*
  1663. X * Copyright (C) 1990 Free Software Foundation, Inc.
  1664. X * Written by the dominion project.
  1665. X *
  1666. X * This file is part of dominion.
  1667. X *
  1668. X * dominion is free software; you can redistribute it and/or
  1669. X * modify it under the terms of the GNU General Public License as published
  1670. X * by the Free Software Foundation; either version 1, or (at your option)
  1671. X * any later version.
  1672. X *
  1673. X * This software is distributed in the hope that it will be useful,
  1674. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1675. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1676. X * GNU General Public License for more details.
  1677. X *
  1678. X * You should have received a copy of the GNU General Public License
  1679. X * along with this software; see the file COPYING.  If not, write to
  1680. X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  1681. X */
  1682. X
  1683. X#include "dominion.h"
  1684. X#include "misc.h"
  1685. X#include "army.h"
  1686. X
  1687. X#include <stdio.h>
  1688. X
  1689. X  /* army and spirit types */
  1690. Xextern struct army_type *army_types;
  1691. Xextern struct spirit_type *spirit_types;
  1692. X
  1693. Xextern Sworld world;
  1694. Xextern int debug;
  1695. Xextern Sh_spell *hanging_spells;
  1696. X
  1697. Xextern Sh_spell *dead_spells;
  1698. Xextern Suser user;
  1699. X
  1700. X
  1701. X  /* this writes out the hanging spells after the update, decreasing
  1702. X     the thons_left parameter by one, and removing the spell
  1703. X     once the thons_left reaches zero.
  1704. X   */
  1705. Xwrite_h_spells()
  1706. X{
  1707. X  FILE *hang_fp, *fopen();
  1708. X  char line[EXECLEN];
  1709. X  int i;
  1710. X  Sh_spell *h_spells;
  1711. X
  1712. X  if ((hang_fp = fopen(HANGING_SPELLS_FILE, "w")) == NULL) {
  1713. X    printf("cannot write file %s\n", HANGING_SPELLS_FILE);
  1714. X    return -1;
  1715. X  }
  1716. X  for (h_spells=hanging_spells; h_spells != NULL; h_spells = h_spells->next) {
  1717. X      /* only write them out if they have not expired */
  1718. X    if (h_spells->thons_left != -1) {
  1719. X      fprintf(hang_fp, "%s\n", h_spells->name);
  1720. X      fprintf(hang_fp, "%d\n", h_spells->nat_id);
  1721. X      fprintf(hang_fp, "%d\n", h_spells->thons_left);
  1722. X      fprintf(hang_fp, "%d\n", h_spells->n_lines);
  1723. X      for (i = 0; i < h_spells->n_lines; ++i) { /* write out the exec lines */
  1724. X    fprintf(hang_fp, "%s", h_spells->lines[i]);
  1725. X      /* we might need to tack on a newline */
  1726. X    if (h_spells->lines[i][strlen(h_spells->lines[i])-1] != '\n') {
  1727. X      fprintf(hang_fp, "\n");
  1728. X    }
  1729. X      }
  1730. X    }
  1731. X  }
  1732. X  fclose(hang_fp);
  1733. X}
  1734. X
  1735. X  /* we need list as a pointer to pointer, so as to add at
  1736. X     the start of the list (which is easy and fast)
  1737. X   */
  1738. Xadd_h_spell(listp, h_spellp)
  1739. X     Sh_spell **listp, *h_spellp;
  1740. X{
  1741. X  Sh_spell *tmp;
  1742. X
  1743. X  if (listp) {            /* list should not be null in this func. */
  1744. X    tmp = (Sh_spell *)malloc(sizeof(Sh_spell));
  1745. X    *tmp = *h_spellp;
  1746. X    tmp->next = *listp;
  1747. X    *listp = tmp;
  1748. X  }
  1749. X}
  1750. X
  1751. X  /* removes a hanging spell from the list */
  1752. Xdelete_h_spell(listp, h_spellp)
  1753. X     Sh_spell **listp, *h_spellp;
  1754. X{
  1755. X}
  1756. X
  1757. X  /* prepares a new hanging spell structure, to be
  1758. X     filled in with its exec lines
  1759. X   */
  1760. Xprepare_h_spell(h_spellp, name, nat_id, thons_left, n_lines)
  1761. X     Sh_spell *h_spellp;
  1762. X     char name[];
  1763. X     int nat_id, thons_left, n_lines;
  1764. X{
  1765. X  int i;
  1766. X
  1767. X  strcpy(h_spellp->name, name);
  1768. X  h_spellp->next = NULL;
  1769. X  h_spellp->nat_id = nat_id;
  1770. X  h_spellp->thons_left = thons_left;
  1771. X  h_spellp->n_lines = n_lines;
  1772. X  h_spellp->lines = (char **)malloc(h_spellp->n_lines*sizeof(char*));
  1773. X  for (i = 0; i < h_spellp->n_lines; ++i) {
  1774. X    h_spellp->lines[i] = (char *)malloc(EXECLEN*sizeof(char));
  1775. X    strcpy(h_spellp->lines[i], "");
  1776. X  }
  1777. X}
  1778. X
  1779. X/* compares 2 hanging spells and returns 0 if same 1 if not */
  1780. Xh_spell_compare(sp1, sp2)
  1781. XSh_spell *sp1, *sp2;
  1782. X{
  1783. X  int i;
  1784. X
  1785. X  if (sp1->nat_id != sp2->nat_id) return 1;
  1786. X  if (sp1->thons_left != sp2->thons_left) return 1;
  1787. X  if (sp1->n_lines != sp2->n_lines) return 1;
  1788. X  if (strncmp(sp1->name, sp2->name,NAMELEN) != 0) return 1;
  1789. X  for (i = 0 ; i < sp1->n_lines; i++)
  1790. X  {  
  1791. X    if (strcmp(sp1->lines[i], sp2->lines[i]) != 0) return 1;
  1792. X  }
  1793. X  return 0;
  1794. X};
  1795. X
  1796. Xis_dead_spell(sp,flag)
  1797. Xint flag;
  1798. XSh_spell *sp;
  1799. X{
  1800. X  Sh_spell *tmp;
  1801. X
  1802. X  tmp = dead_spells;
  1803. X  while (tmp != NULL)
  1804. X  {
  1805. X    if (h_spell_compare(tmp,sp) == 0)
  1806. X    { 
  1807. X      got_dead_h_spell(tmp);
  1808. X      return 1;
  1809. X    }
  1810. X    tmp = tmp->next;
  1811. X  }
  1812. X  return 0;
  1813. X}
  1814. X
  1815. Xload_dead_hspells(up,flag)
  1816. Xint flag;
  1817. X     Suser *up;            /* up can also be NULL */
  1818. X{
  1819. X  FILE *dead_fp, *fopen();
  1820. X  int done = 0, i;
  1821. X  char line[EXECLEN], filename[PATHLEN];
  1822. X  Sh_spell h_spell;
  1823. X
  1824. X  sprintf(filename,"exec/%s.%d","dead_spells",up->id);
  1825. X  if ((dead_fp = fopen(filename, "r")) == NULL) {
  1826. X    if (debug) printf("no file %s\n", filename);
  1827. X    return -1;
  1828. X  }
  1829. X  while (!done) {
  1830. X    h_spell.next = NULL;
  1831. X    if (fscanf(dead_fp, "%s", h_spell.name) < 0) {
  1832. X      done = 1;            /* useless? */
  1833. X      break;
  1834. X    }
  1835. X    fscanf(dead_fp, "%d", &h_spell.nat_id);
  1836. X    fscanf(dead_fp, "%d", &h_spell.thons_left);
  1837. X    fscanf(dead_fp, "%d", &h_spell.n_lines);
  1838. X    if (debug) {
  1839. X      printf("nation id %d, spell <%s>, time_left = %d, n_lines = %d\n",
  1840. X       h_spell.nat_id, h_spell.name, h_spell.thons_left, h_spell.n_lines);
  1841. X    }
  1842. X    h_spell.lines = (char **)malloc(h_spell.n_lines * sizeof(char *));
  1843. X
  1844. X    for (i = 0; i < h_spell.n_lines; ++i) { /* read in the exec lines */
  1845. X      h_spell.lines[i] = (char *)malloc(EXECLEN*sizeof(char));
  1846. X      fscanf(dead_fp, "%s", h_spell.lines[i]);
  1847. X    }
  1848. X    add_h_spell(&dead_spells, &h_spell);
  1849. X  }
  1850. X  fclose(dead_fp);
  1851. X  if (flag == 1) { unlink(filename); }
  1852. X}
  1853. X
  1854. X  /* this is fundamental:  it loads all spells from the global
  1855. X     "hanging_spells" file and runs the exec lines it finds.
  1856. X     Note:  it must load all the spells, not just those for the
  1857. X     current user, because spells by other users affect the current
  1858. X     user too.  One effect is that spells, like diplomacy, take
  1859. X     immediate effect, rather than waiting for the update.  Hmm,
  1860. X     is that good or bad?
  1861. X
  1862. X     At the same time, the spells of the current user (if we are in
  1863. X     the game rather than the update) are stored into a list for that
  1864. X     user to examine, apart from the global list.
  1865. X   */
  1866. X
  1867. Xload_h_spells(up)
  1868. X     Suser *up;            /* up can also be NULL */
  1869. X{
  1870. X  FILE *hang_fp, *fopen();
  1871. X  int done = 0, i;
  1872. X  char line[EXECLEN];
  1873. X  Sh_spell h_spell;
  1874. X  struct argument exec_args[N_EXEC_ARGS];
  1875. X  Snation *np;
  1876. X
  1877. X    /* start with the global list being NULL */
  1878. X  hanging_spells = NULL;
  1879. X  if (up) {
  1880. X    up->h_spells = NULL;
  1881. X  }
  1882. X  if ((hang_fp = fopen(HANGING_SPELLS_FILE, "r")) == NULL) {
  1883. X    if (debug) printf("no file %s\n", HANGING_SPELLS_FILE);
  1884. X    return -1;
  1885. X  }
  1886. X  while (!done) {
  1887. X    h_spell.next = NULL;
  1888. X    if (fscanf(hang_fp, "%s", h_spell.name) < 0) {
  1889. X      done = 1;            /* useless? */
  1890. X      break;
  1891. X    }
  1892. X    fscanf(hang_fp, "%d", &h_spell.nat_id);
  1893. X    fscanf(hang_fp, "%d", &h_spell.thons_left);
  1894. X    fscanf(hang_fp, "%d", &h_spell.n_lines);
  1895. X    if (debug) {
  1896. X      printf("nation id %d, spell <%s>, time_left = %d, n_lines = %d\n",
  1897. X       h_spell.nat_id, h_spell.name, h_spell.thons_left, h_spell.n_lines);
  1898. X    }
  1899. X    h_spell.lines = (char **)malloc(h_spell.n_lines * sizeof(char *));
  1900. X
  1901. X    for (i = 0; i < h_spell.n_lines; ++i) { /* read in the exec lines */
  1902. X      h_spell.lines[i] = (char *)malloc(EXECLEN*sizeof(char));
  1903. X      fscanf(hang_fp, "%s", h_spell.lines[i]);
  1904. X    }
  1905. X    if (!is_dead_spell(&h_spell,1))
  1906. X    {
  1907. X      for (i = 0 ; i < h_spell.n_lines; ++i)
  1908. X      {
  1909. X        if (i % 2 == 0) {
  1910. X      parse_exec_line(h_spell.lines[i], exec_args);
  1911. X          np = &world.nations[h_spell.nat_id];
  1912. X          run_exec_line(np, exec_args);
  1913. X        }
  1914. X      }
  1915. X      add_h_spell(&hanging_spells, &h_spell);
  1916. X      if (up && (up->id == h_spell.nat_id || up->id == 0)) {
  1917. X    add_h_spell(&up->h_spells, &h_spell);
  1918. X      }
  1919. X    }
  1920. X  }
  1921. X  fclose(hang_fp);
  1922. X}
  1923. X
  1924. Xdelete_hanging_spell(sp1)
  1925. XSh_spell *sp1;
  1926. X{
  1927. X  Sh_spell *prev, *next, *tmp, *tmp2;
  1928. X  struct argument exec_args[N_EXEC_ARGS];
  1929. X  int i;
  1930. X
  1931. X  tmp = user.h_spells; tmp2 = NULL; prev = NULL;
  1932. X  while ((tmp != NULL) && (tmp2 == NULL))
  1933. X  {
  1934. X    if (h_spell_compare(sp1, tmp) == 0)
  1935. X    {
  1936. X      tmp2 = tmp;
  1937. X    } else
  1938. X    {
  1939. X      prev = tmp;
  1940. X      tmp = tmp->next;
  1941. X    }
  1942. X  }
  1943. X  if (prev == NULL)
  1944. X  { 
  1945. X    user.h_spells = tmp2->next;
  1946. X  } else
  1947. X  {
  1948. X    prev->next = tmp2->next;
  1949. X  }
  1950. X  for (i = 0 ; i < tmp2->n_lines; i++)
  1951. X  {
  1952. X    if (i % 2 == 1)
  1953. X    {
  1954. X      parse_exec_line(tmp2->lines[i], exec_args);
  1955. X      run_exec_line(user.np, exec_args);
  1956. X    }
  1957. X  }
  1958. X  write_dead_spell(tmp2);
  1959. X  if (is_army_spell(tmp2)) reset_spelled_flags();
  1960. X  free_h_spell(tmp2);
  1961. X}
  1962. X
  1963. Xgot_dead_h_spell(sp1)
  1964. XSh_spell *sp1;
  1965. X{
  1966. X  Sh_spell *prev, *tmp, *tmp2;
  1967. X
  1968. X  tmp = dead_spells; tmp2 = NULL; prev = NULL;
  1969. X  while ((tmp != NULL) && (tmp2 == NULL))
  1970. X  {
  1971. X    if (sp1 == tmp)
  1972. X    {
  1973. X      tmp2 = tmp;
  1974. X    } else
  1975. X    {
  1976. X      prev = tmp;
  1977. X      tmp = tmp->next;
  1978. X    }
  1979. X  }
  1980. X  if (tmp2 != NULL)
  1981. X  {
  1982. X    if (prev == NULL)
  1983. X    { 
  1984. X      dead_spells = tmp2->next;
  1985. X    } else
  1986. X    {
  1987. X      prev->next = tmp2->next;
  1988. X    }
  1989. X    free_h_spell(tmp2);
  1990. X  }
  1991. X}
  1992. X
  1993. Xfree_h_spell(sp1)
  1994. XSh_spell *sp1;
  1995. X{
  1996. X  int i;  
  1997. X
  1998. X  for (i = 0 ; i < sp1->n_lines ; i++)
  1999. X  {
  2000. X    free(sp1->lines[i]);
  2001. X  }
  2002. X  free(sp1);
  2003. X}
  2004. X
  2005. Xreset_spelled_flags()
  2006. X{
  2007. X  Sh_spell *tmp;
  2008. X  
  2009. X  tmp = user.h_spells;
  2010. X
  2011. X  while (tmp != NULL)
  2012. X  {
  2013. X    reset_one_spell(tmp);
  2014. X    tmp = tmp -> next;
  2015. X  }
  2016. X}
  2017. X
  2018. Xreset_one_spell(sp1)
  2019. XSh_spell *sp1;
  2020. X{
  2021. X  struct argument exec_args[N_EXEC_ARGS];
  2022. X  if (strcmp(sp1->name, "hide_army") == 0)
  2023. X  {
  2024. X    if (sp1->n_lines < 4) return;
  2025. X    parse_exec_line(sp1->lines[2], exec_args);
  2026. X    run_exec_line(user.np, exec_args);
  2027. X  }
  2028. X  else if (strcmp(sp1->name, "fly_army") == 0)
  2029. X  {
  2030. X    if (sp1->n_lines < 4) return;
  2031. X    parse_exec_line(sp1->lines[2], exec_args);
  2032. X    run_exec_line(user.np, exec_args);
  2033. X  }
  2034. X  else if (strcmp(sp1->name, "vampire_army")== 0 )
  2035. X  {
  2036. X    if (sp1->n_lines < 4) return;
  2037. X    parse_exec_line(sp1->lines[2], exec_args);
  2038. X    run_exec_line(user.np, exec_args);
  2039. X  }
  2040. X  else if (strcmp(sp1->name, "burrow_army")== 0 )
  2041. X  {
  2042. X    if (sp1->n_lines < 4) return;
  2043. X    parse_exec_line(sp1->lines[2], exec_args);
  2044. X    run_exec_line(user.np, exec_args);
  2045. X  }
  2046. X  else if (strcmp(sp1->name, "water_walk") == 0)
  2047. X  {
  2048. X    if (sp1->n_lines < 4) return;
  2049. X    parse_exec_line(sp1->lines[2], exec_args);
  2050. X    run_exec_line(user.np, exec_args);
  2051. X  }
  2052. X  else if (strcmp(sp1->name, "mag_bonus") == 0)
  2053. X  {
  2054. X    if (sp1->n_lines < 4) return;
  2055. X    parse_exec_line(sp1->lines[2], exec_args);
  2056. X    run_exec_line(user.np, exec_args);
  2057. X  }
  2058. X}
  2059. X
  2060. Xis_army_spell(sp1)
  2061. XSh_spell *sp1;
  2062. X{
  2063. X  struct argument exec_args[N_EXEC_ARGS];
  2064. X  if (strcmp(sp1->name, "hide_army") == 0)
  2065. X  {
  2066. X    return 1;
  2067. X  }
  2068. X  else if (strcmp(sp1->name, "fly_army") == 0)
  2069. X  {
  2070. X    return 1;
  2071. X  }
  2072. X  else if (strcmp(sp1->name, "vampire_army")== 0 )
  2073. X  {
  2074. X    return 1;
  2075. X  }
  2076. X  else if (strcmp(sp1->name, "burrow_army")== 0 )
  2077. X  {
  2078. X    return 1;
  2079. X  } 
  2080. X  else if (strcmp(sp1->name, "water_walk") == 0)
  2081. X  {
  2082. X    return 1;
  2083. X  }
  2084. X  else if (strcmp(sp1->name, "mag_bonus") == 0)
  2085. X  {
  2086. X    return 1;
  2087. X  }
  2088. X  return 0;
  2089. X}
  2090. X
  2091. Xwrite_dead_spell(sp1)
  2092. XSh_spell *sp1;
  2093. X{
  2094. X  FILE *dead_fp, *fopen();
  2095. X  char line[EXECLEN], filename[PATHLEN];
  2096. X  int i;
  2097. X
  2098. X  sprintf(filename,"exec/%s.%d","dead_spells",user.id);
  2099. X  if ((dead_fp = fopen(filename, "a")) == NULL) {
  2100. X    if (debug) printf("no file %s\n", filename);
  2101. X    return -1;
  2102. X  }
  2103. X  fprintf(dead_fp, "%s\n", sp1->name);
  2104. X  fprintf(dead_fp, "%d\n", sp1->nat_id);
  2105. X  fprintf(dead_fp, "%d\n", sp1->thons_left);
  2106. X  fprintf(dead_fp, "%d\n", sp1->n_lines);
  2107. X  for (i = 0; i < sp1->n_lines; ++i) { /* write out the exec lines */
  2108. X    fprintf(dead_fp, "%s", sp1->lines[i]);
  2109. X     /* we might need to tack on a newline */
  2110. X    if (sp1->lines[i][strlen(sp1->lines[i])-1] != '\n') {
  2111. X    fprintf(dead_fp, "\n");
  2112. X    }
  2113. X  }
  2114. X  fclose(dead_fp);
  2115. X}
  2116. X
  2117. Xclear_dead_hspells()
  2118. X{
  2119. X  Sh_spell *h_spells;
  2120. X  int i,end;
  2121. X  struct argument exec_args[N_EXEC_ARGS];
  2122. X
  2123. X  for (h_spells=hanging_spells; h_spells != NULL; h_spells = h_spells->next)
  2124. X  {
  2125. X    for (i = 0; i < h_spells->n_lines; ++i) { /* check the exec lines */
  2126. X/* Remove that goddman newline */
  2127. X      end = strlen(h_spells->lines[i]);
  2128. X      if (h_spells->lines[i][end-1] == '\n') {
  2129. X        h_spells->lines[i][end - 1] = '\0';
  2130. X      }
  2131. X    }
  2132. X    if (is_dead_spell(h_spells,1))
  2133. X    {
  2134. X      h_spells->thons_left = 0;
  2135. X    }
  2136. X  }
  2137. X}
  2138. X
  2139. X/* This routine checks to see if this army has a spell cast on it by  */
  2140. X/* checking to see if the flags are different from the default.       */
  2141. X/* If new spells are developed that change things besides flags, then */
  2142. X/* other mechanism's will need to be used.                            */
  2143. Xis_spelled(ap)
  2144. XSarmy *ap;
  2145. X{
  2146. X  int i;
  2147. X  int def_flags;
  2148. X  Snation *np = user.np;
  2149. X
  2150. X  i = army_type_index(ap->type);
  2151. X  if (i != -1 ) {
  2152. X    def_flags = army_types[i].flags;
  2153. X    if (def_flags & AF_INVERSE_ALT) {
  2154. X      if (np->race.pref_alt >= SEA_LEVEL) {
  2155. X        def_flags |= AF_WATER;
  2156. X      } else {
  2157. X        def_flags |= AF_LAND;
  2158. X      }
  2159. X    }
  2160. X    if (def_flags != ap->flags) {
  2161. X      return 1;
  2162. X    } else {
  2163. X      return 0;
  2164. X    }
  2165. X  } else {
  2166. X    if ((i = spirit_type_index(ap->type)) < 0) {
  2167. X      return 0;  /* We can't figure out what it is, so it's not spelled */
  2168. X    }
  2169. X    if (spirit_types[i].flags != ap->flags) {
  2170. X      return 1;
  2171. X    } else {
  2172. X      return 0;
  2173. X    }
  2174. X  }
  2175. X}
  2176. END_OF_FILE
  2177. if test 12959 -ne `wc -c <'spelllib.c'`; then
  2178.     echo shar: \"'spelllib.c'\" unpacked with wrong size!
  2179. fi
  2180. # end of 'spelllib.c'
  2181. fi
  2182. echo shar: End of archive 24 \(of 28\).
  2183. cp /dev/null ark24isdone
  2184. MISSING=""
  2185. 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
  2186.     if test ! -f ark${I}isdone ; then
  2187.     MISSING="${MISSING} ${I}"
  2188.     fi
  2189. done
  2190. if test "${MISSING}" = "" ; then
  2191.     echo You have unpacked all 28 archives.
  2192.     echo "Now execute ./do_cat.sh to build doc files"
  2193.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2194. else
  2195.     echo You still need to unpack the following archives:
  2196.     echo "        " ${MISSING}
  2197. fi
  2198. ##  End of shell archive.
  2199. exit 0
  2200.