home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!zephyr.ens.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v13i055: dominion - a multi-player world simulation game, Part19/28
- Message-ID: <2458@masterCNA.TEK.COM>
- Date: 11 Feb 92 18:26:24 GMT
- Sender: news@masterCNA.TEK.COM
- Lines: 2091
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: rosalia@dirac.physics.sunysb.edu (Mark Galassi)
- Posting-number: Volume 13, Issue 55
- Archive-name: dominion/Part19
- Environment: Unix, curses
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 19 (of 28)."
- # Contents: ChangeLog battle.c misc.c
- # Wrapped by billr@saab on Tue Feb 11 10:14:56 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'ChangeLog' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ChangeLog'\"
- else
- echo shar: Extracting \"'ChangeLog'\" \(4115 characters\)
- sed "s/^X//" >'ChangeLog' <<'END_OF_FILE'
- XThu Jan 30 16:00:06 1992 Mark Galassi (rosalia at max)
- X
- X * root.c: now root windows are cleared when created on BSD
- X systems.
- X
- X * cur_stuff.c: fixed problem with return value of wget_number()
- X function and friends.
- X
- X * spells.c: fixed a bug with the merge spell which allowed you to
- X steal other nations' population by merging on hostile sectors.
- X
- X * mail.c and commands.c: fixed problem with permissions/uids
- X etc... now sending mail works both when forwarding and when
- X sending locally.
- X
- XTue Jan 28 22:58:44 1992 Douglas J. Novellano (doug at max)
- X
- X * c_news.c: write_newsrc(): Fixed (?) the .tmprc.n error bug.
- X Changed mv system call to cp and rm.
- X
- XMon Jan 27 04:30:09 1992 C. Titus Brown (brown at dirac)
- X
- X * commands.c: Fixed aforementioned bug
- X
- X * c_news.c: Fixed the previously mentioned major bug
- X
- X * mail.c: Fixed the major bug with the init_screen and edit()
- X
- X * int_mail.c: Now, when the mail reader deletes all the messages
- X in the mailbox, the change is kept
- X (formerly, it tried to copy the deleted file)
- X
- X * int_mail.c: Fixed the major bug with the init_screen and
- X edit().
- X
- XSat Jan 25 18:59:55 1992 C. Titus Brown (brown at dirac)
- X
- X * army.c: added routine "statline2_prompt" to all the relevant places
- X
- X * army.c: fixed problem with army status' running over into bonus'
- X in zoom_army.
- X
- X * misc.c: added routine "statline2_prompt"
- X
- XFri Jan 24 02:30:43 1992 C. Titus Brown (brown at dirac)
- X
- X * mktables.c: checked in (not in makefile)
- X
- X * dominion.tex: added in new army_types table (see mktable)
- X
- X * ext.c: changed description for army_examine, spelling, etc.
- X
- XThu Jan 23 23:36:33 1992 C. Titus Brown (brown at dirac)
- X
- X * nation.c: new_army_type now checks to see if the army_type
- X being added already is there.
- X
- X * armylib.c: add_army_type now checks to see if the army_type
- X being added is already there.
- X
- XThu Jan 23 18:03:05 1992 Michael D Fischer (greendog at max)
- X
- X * ext.c: changed some <a>rmy <e>xamine descriptions
- X
- XThu Jan 23 15:46:41 1992 Stephen H. Underwood (heechee at max)
- X
- X * misc.h: removed extern declarations of index/strchr
- X
- X * army.c: added typecast to remove warning.
- X
- XFri Jan 17 13:50:42 1992 Stephen H. Underwood (heechee at max)
- X
- X * army.h, spelllib.c: Fixed the problem with spells & merge
- X so it is not possible to split or merge armies or spritis
- X which are currently being affected by a spell.
- X
- XTue Jan 14 16:40:01 1992 Stephen H. Underwood (heechee at max)
- X
- X * dominion.h, cur_stuff.c, Makefile: Added supporrt for PMAX,
- X fixing bug in the curses desplay for ultrix
- X
- X * dominion.c, printmap.c: Added support for ANDREW style
- X authenticaion (since setuid/setgid doesn't function on AFS)
- X
- X * army.c, ext.c, menus.c, nation.c, addnation.c, file.c,
- X amry.h, update.c, mail.c, user.c, spelllib.c
- X Remove the slew of meaningless comments I left lying around.
- X
- XMon Jan 13 23:04:10 EST 1992 Stephen Underwood (heechee at max)
- X
- X * army.c: removed direct reference to strchr that would not
- X compile under BSD.
- X
- X * misc.h: Made sure that strchr or index were defined correctly
- X as a proper fix to the above problems.
- X
- XFri Jan 10 15:58:17 1992 Michael D Fischer (greendog at max)
- X
- X * printmap.c: Changed scaling from c-code to ps-code, and
- X added axes to borders of map.
- X
- XTue Jan 7 22:36:35 1992 Michael D Fischer (greendog at max)
- X
- X * printmap.c: Changes back to real userid to be able to write
- X to user's directory. Also a few minor changes.
- X
- XTue Jan 7 14:09:51 1992 Mark Galassi (rosalia at max)
- X
- X * Addnation: now doesn't infinite-loop if there is no
- X space of a new nation. Behaves well on this count.
- X
- XFri Dec 13 08:11:54 1991 Mark Galassi (rosalia at max)
- X
- X * Makefile: added the ChangeLog in the distribution
- X
- X * Makefile: now compiling as version 1.06beta
- X
- X * cinfo.c: fixed bug that find_info_file() was not returning
- X the file pointer as it should have been. this caused core
- X dumps on suns, and worked by miracle on MIPS/SGI.
- X
- X * armylib.c: fixed (finally) bug in army_is_in_sector() which
- X caused all sorts of trouble with armies not being properly
- X inserted into sectors.
- END_OF_FILE
- if test 4115 -ne `wc -c <'ChangeLog'`; then
- echo shar: \"'ChangeLog'\" unpacked with wrong size!
- fi
- # end of 'ChangeLog'
- fi
- if test -f 'battle.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'battle.c'\"
- else
- echo shar: Extracting \"'battle.c'\" \(27165 characters\)
- sed "s/^X//" >'battle.c' <<'END_OF_FILE'
- X/* battle.c -- functions relating to resolving battles between nations */
- X
- X/*
- X * Copyright (C) 1990 Free Software Foundation, Inc.
- X * Written by the dominion project.
- X *
- X * This file is part of dominion.
- X *
- X * dominion is free software; you can redistribute it and/or
- X * modify it under the terms of the GNU General Public License as published
- X * by the Free Software Foundation; either version 1, or (at your option)
- X * any later version.
- X *
- X * This software is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this software; see the file COPYING. If not, write to
- X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X */
- X
- X/* against(dm,list,nation) - checks a list of armies (in a sector) for */
- X/* any army which the nation specified is against (at WAR/JIHAD) */
- X/* count_force(np,sp,ap) - calculates the EFFECTIVE force of an army */
- X/* which a unit represents including nation, sector, army bonuses */
- X/* free_list(list) - frees up memory which was used in the list */
- X/* status_check(list,status) - checks a 'sector list' of armies for a */
- X/* particular status and returns one if it occurs, else zero */
- X/* supports(dm,list,nation) - checks a list of armies for any army which */
- X/* the nation specified supports (TREATY) */
- X/**************************************************************************/
- X/* These remaining functions are probably useless for other purposes */
- X/**************************************************************************/
- X/* dobattles() - resolves all battles in the world during an update */
- X/* move_intercepts(dm) - moves each army with INTERCEPT status to */
- X/* bordering hostile armies and sets to ATTACK status. If there */
- X/* is no hostile army locally, keep army in INTERCEPT mode. */
- X/* add_to_list(list,army,mail_list) - adds the army to the list specified */
- X/* and also to the mail list IF it does not already occur there. */
- X/* extract_losses(list,pct_loss,mail_list,type) - Extracts losses from */
- X/* armies in a sector. If type is 3, the army list is of neutrals*/
- X/* total_bonus(np,sp,ap) - gets TOTAL bonus for that army */
- X/* battle_mail(mail_list,s) - adds string s to mail for nations in list */
- X/* intro_battle_mail(mail_list,x,y) - sends intro message with rel coord. */
- X/* intro_battle_news(...) - posts news about the battle */
- X/* single_mail(nation,s) - adds string s to mail for nation #nation */
- X/* is_war(dm,x,y) - sees if any war should happen in this sector */
- X/* battle(dm,x,y,fp) - main routine which deals with all battles in a sector */
- X
- X#include "dominion.h"
- X#include "misc.h"
- X#include "army.h"
- X
- X#include <stdio.h>
- X
- X/* used as type parameter values passed to extract_losses */
- X
- X#define ALLIES 1
- X#define ENEMIES 2
- X#define NEUTRALS 3
- X
- X
- Xextern Sworld world;
- Xint (*wrapx)(), (*wrapy)();
- XFILE *mailfile;
- X
- Xdobattles()
- X{
- X int x,y;
- X Sdiplo **dm, **allocate_diplo();
- X FILE *tmp_fp, *fopen(); /* for the news posting */
- X char tmp_name[100];
- X char subj[100];
- X dm = allocate_diplo(world.n_nations);
- X read_in_diplo(dm,world.n_nations);
- X
- X printf("Doing battles...\n");
- X fflush(stdout);
- X
- X /* a temporary file name for this news posting */
- X/* tmp_name = tmpnam(NULL, "dominion"); */
- X strcpy(tmp_name, "dominionXXXXXX");
- X mktemp(tmp_name);
- X
- X if (strlen(tmp_name) == 0) {
- X fprintf(stderr, "Error getting temp file name\n");
- X return;
- X }
- X if ((tmp_fp = fopen(tmp_name, "w")) == NULL) {
- X fprintf(stderr, "Error opening file %s for writing\n", tmp_name);
- X return;
- X }
- X/* fprintf(tmp_fp, "Date: Thon %d\n", world.turn);
- X fprintf(tmp_fp, "From: Update\n");
- X fprintf(tmp_fp, "Subj: battles from thon %d to thon %d\n", world.turn-1,
- X world.turn);*/
- X sprintf(subj, "battles from thon %d to thon %d",world.turn-1,world.turn);
- X
- X move_intercepts(dm);
- X
- X for (x = 0; x < world.xmax; x++) {
- X for (y = 0; y < world.ymax; y++) {
- X if (world.map[x][y].alist && world.map[x][y].alist->next
- X && is_war(dm, x, y, tmp_fp)) {
- X/* battle(dm, x, y, tmp_fp); */
- X }
- X }
- X }
- X fclose(tmp_fp);
- X post_news_file(tmp_name, NEWS_GROUP,subj,0);
- X printf("just posted file to newsgroup <%s>\n", NEWS_GROUP);
- X}
- X
- X /* takes all armies in intercept mode and sees if
- X it can move them to attack an enemy army.
- X */
- Xmove_intercepts(dm)
- X Sdiplo **dm;
- X{
- X int nation,x,y;
- X Snation *np;
- X Ssector *sp;
- X Sarmy *ap;
- X
- X for (nation = 1; nation < world.n_nations; nation++) {
- X np = &world.nations[nation];
- X ap = np->armies;
- X while (ap != NULL) {
- X if (ap->status == A_INTERCEPT) {
- X for (x = ap->pos.x - 1; x <= ap->pos.x + 1; x++) {
- X for (y = ap->pos.y - 1; y <= ap->pos.y + 1; y++) {
- X sp = &world.map[(*wrapx)(x,y)][(*wrapy)(x,y)];
- X /* army might not be in intercept mode any more,
- X in which case we don't make it move. that way
- X an intercept army will only move once.
- X */
- X if (ap->status == A_INTERCEPT && against(dm, sp->alist, nation)
- X /* be careful about moving into bad altitude */
- X && (good_army_altitude(np, sp, ap) || is_kamikaze(ap))) {
- X printf("%s army %d is intercepting from (%d,%d) to (%d,%d)\n",
- X np->name, ap->id, ap->pos.x, ap->pos.y, x, y);
- X ap->status = A_ATTACK;
- X/* if (sect_n_armies(&world.map[ap->pos.x][ap->pos.y]) > 1) { */
- X delete_army_sector(&world.map[ap->pos.x][ap->pos.y],ap);
- X/* } else {
- X free(sp->alist);
- X sp->alist = NULL;
- X }
- X*/
- X ap->pos.x = (*wrapx)(x,y);
- X ap->pos.y = (*wrapy)(x,y);
- X insert_army_sector(sp, ap);
- X }
- X }
- X }
- X }
- X ap = ap->next;
- X }
- X }
- X}
- X
- X/*
- X against(): searches throught the list of armies
- X and checks for their diplomatic status
- X with 'nation' and vice versa. When
- X the nation status is either WAR or JIHAD
- X then it returns 1 else 0
- X This routine is called from battle()
- X*/
- X
- Xagainst(dm,list,nation)
- X Sdiplo **dm;
- X struct armyid *list;
- X int nation;
- X{
- X struct armyid *tmp;
- X int ds1,ds2;
- X
- X tmp = list;
- X while (tmp != NULL) {
- X ds1 = get_diplo_status(dm,nation,tmp->owner);
- X ds2 = get_diplo_status(dm,tmp->owner,nation);
- X if (ds1 == WAR || ds1 == JIHAD || ds2 == WAR || ds2 == JIHAD) {
- X return 1;
- X }
- X tmp = tmp->next;
- X }
- X return 0;
- X}
- X
- X/* this routine is being called from battle() */
- X
- Xsupports(dm,list,nation)
- X Sdiplo **dm;
- X struct armyid *list;
- X int nation;
- X{
- X struct armyid *tmp;
- X int ds1,ds2;
- X
- X tmp = list;
- X while (tmp != NULL) {
- X if (tmp->owner == nation) { /* a nation is allied with itself */
- X return 1;
- X }
- X ds1 = get_diplo_status(dm,nation,tmp->owner);
- X ds2 = get_diplo_status(dm,tmp->owner,nation);
- X if (ds1 == TREATY && ds2 == TREATY) {
- X return 1;
- X }
- X tmp = tmp->next;
- X }
- X return 0;
- X}
- X
- X/* this routine is being called from battle() as well */
- X/* also being called from battle() */
- X
- Xadd_to_list(list,army,mail_list)
- X struct armyid **list, *army, **mail_list;
- X{
- X struct armyid *tmp;
- X
- X tmp = (struct armyid *) malloc(sizeof(struct armyid));
- X *tmp = *army;
- X tmp->next = (*list);
- X (*list) = tmp;
- X
- X tmp = (*mail_list);
- X while (tmp != NULL) {
- X if (tmp->owner == army->owner) {
- X return;
- X }
- X tmp = tmp->next;
- X }
- X tmp = (struct armyid *) malloc(sizeof(struct armyid));
- X *tmp = *army;
- X tmp->next = (*mail_list);
- X (*mail_list) = tmp;
- X}
- X
- X/***************************************************
- X total_bonus() returns all bonuses of an army
- X if an army is in TREATY with the owner of the
- X sector then they can enjoy sector defense bonuses
- X and have a choice of being in DEFEND, GARRISON,
- X AMBUSH etc.
- X if an army is in garrison mode they get extra 10
- X this function has the flexibility in case we want
- X other modes. For starters I will add some experimental
- X stuff with ALLIED status with sector's owner
- X ALLIED will give 1/2 of sector bonuses and +5 for
- X garrison mode. A nation with very strong
- X sector bonuses will invite more nations to be in
- X treaty with him because any time they fight in a sector
- X owned by this strong nation will enjoy the sector
- X bonuses as well.
- X This routine is called from battle() and from extract_losses
- X*************************************************************/
- X
- Xtotal_bonus(np,sp,ap,dm)
- XSnation *np;
- XSsector *sp;
- XSarmy *ap;
- XSdiplo **dm;
- X
- X{
- X int bonus = 0;
- X int ds1,ds2; /* test to see if army is in trearty with sector owner */
- X /* if they are in treaty with each other then the army can share the*/
- X /* sector's defense bonuses. */
- X
- X if (sp->owner == np->id) {
- X bonus += np->defense;
- X bonus += sp->defense;
- X if (ap->status == A_GARRISON)
- X bonus += 10;
- X } else {
- X ds1 = get_diplo_status(dm,sp->owner,np->id);
- X ds2 = get_diplo_status(dm,np->id,sp->owner);
- X
- X /* count the nation's bonus */
- X if ((ds1 == TREATY || ds1 == ALLIED) && (ds2 == TREATY || ds2 == ALLIED)) {
- X switch(ap->status) {
- X case A_DEFEND: bonus += np->defense;
- X if (ds1 == TREATY)
- X bonus += sp->defense;
- X else /* ALLIED */
- X bonus += (sp->defense)/2;
- X break;
- X case A_ATTACK:
- X { bonus += np->attack;
- X if (ds1 == TREATY)
- X bonus += sp->defense;
- X else /* ALLIED */
- X bonus += (sp->defense)/2;
- X }
- X break;
- X case A_GARRISON:
- X { bonus += np->defense;
- X if (ds1 == TREATY) {
- X bonus += sp->defense;
- X bonus += 10; }
- X else {/* ALLIED */
- X bonus += (sp->defense)/2;
- X bonus += 5; }
- X }
- X break;
- X default: break;
- X } /* end switch */
- X } else
- X bonus += np->attack; /* not allied with owner */
- X /* just attack bonuses */
- X }
- X
- X bonus += ap->sp_bonus; /* army's special bonus */
- X
- X return bonus;
- X}
- X
- X /* returns the force of that army (minimum 1) */
- X /* this is being called by battle() and extract_losses()
- X and makes a call to total bonus. It is important to
- X know that **dm is being passed along and not used
- X until it reaches total_bonus() */
- X
- Xcount_force(np,sp,ap,dm)
- X Snation *np;
- X Ssector *sp;
- X Sarmy *ap;
- X Sdiplo **dm; /* passed along to total bonus */
- X{
- X int force;
- X
- X force = (ap->n_soldiers*(100+total_bonus(np,sp,ap,dm)))/100;
- X if (force < 1) {
- X return 1; /* return at least 1 */
- X }
- X return force;
- X}
- X
- Xcount_men(force_list,flags)
- X/*
- X This counts the nubmer of units in a given force counting only those
- X units without the flags in flags set.
- X*/
- Xstruct armyid *force_list;
- Xint flags;
- X{
- X struct armyid *tmp_alist;
- X Sarmy *ap = NULL, *get_army();
- X Snation *np;
- X int total = 0;
- X
- X for (tmp_alist= force_list; tmp_alist != NULL; tmp_alist = tmp_alist->next) {
- X np = &world.nations[tmp_alist->owner];
- X ap = get_army(np, tmp_alist->id);
- X if ((!(ap->flags & flags)) && !(is_spirit(ap))) {
- X total += ap->n_soldiers;
- X }
- X }
- X return total;
- X}
- X
- Xcount_machine(force_list)
- X/*
- X This counts the nubmer of units in a given force counting only those
- X units without the flags in flags set.
- X*/
- Xstruct armyid *force_list;
- X{
- X struct armyid *tmp_alist;
- X Sarmy *ap = NULL, *get_army();
- X Snation *np;
- X int total = 0;
- X
- X for (tmp_alist= force_list; tmp_alist != NULL; tmp_alist = tmp_alist->next) {
- X np = &world.nations[tmp_alist->owner];
- X ap = get_army(np, tmp_alist->id);
- X if (is_machine(ap)) {
- X total += ap->n_soldiers;
- X }
- X }
- X return total;
- X}
- X
- Xmach_bonus_avg(force_list)
- X/*
- X This computes the average bonus gained from machines.
- X*/
- Xstruct armyid *force_list;
- X{
- X struct armyid *tmp_alist;
- X Sarmy *ap = NULL, *get_army();
- X Snation *np;
- X int tot_mach_bonus = 0, total_units = 0;
- X
- X for (tmp_alist= force_list; tmp_alist != NULL; tmp_alist = tmp_alist->next) {
- X np = &world.nations[tmp_alist->owner];
- X ap = get_army(np, tmp_alist->id);
- X if (is_machine(ap))
- X {
- X tot_mach_bonus += ap->sp_bonus * ap->n_soldiers;
- X total_units += ap->n_soldiers;
- X }
- X }
- X return (tot_mach_bonus / total_units);
- X}
- X
- X/* This function is being called from battle() */
- X
- Xextract_losses(list, pct_loss, mail_list, type, dm)
- X struct armyid *list;
- X float pct_loss;
- X struct armyid *mail_list;
- X int type;
- X Sdiplo **dm;
- X{
- X struct armyid *tmp_aid;
- X Snation *np;
- X Ssector *sp;
- X Sarmy *ap, *get_army();
- X int killed, dead = 0;
- X char s[EXECLEN], name[NAMELEN];
- X
- X tmp_aid = list;
- X if (tmp_aid != NULL) {
- X if (type == NEUTRALS) {
- X sprintf(s, "---<<< NEUTRAL FORCES IN THE REGION >>>---\n");
- X } else {
- X if (type == ALLIES)
- X sprintf(s, "---<<< First force >>>---\n");
- X else
- X sprintf(s, "---<<< Second force >>>---\n");
- X }
- X battle_mail(mail_list,s);
- X }
- X while (tmp_aid != NULL) {
- X np = &world.nations[tmp_aid->owner];
- X ap = get_army(np,tmp_aid->id);
- X sp = &world.map[ap->pos.x][ap->pos.y];
- X /* special case for mages and ships: they
- X only die if more than 80% of supporting armies
- X are killed.
- X */
- X if ((strcmp(ap->type, "Mage") == 0) || is_cargo(ap)) {
- X if (pct_loss > 0.8) {
- X killed = ap->n_soldiers;
- X } else {
- X killed = 0;
- X }
- X } else {
- X killed = (int) (ap->n_soldiers * pct_loss + .5);
- X /* if less than 5 soldiers, or if kamikaze unit, kill them */
- X if ((ap->n_soldiers - killed) < 5 || is_kamikaze(ap)) {
- X killed = ap->n_soldiers;
- X }
- X }
- X
- X if (strlen(ap->name) == 0) {
- X strcpy(ap->name, "(no name)");
- X } else {
- X sprintf(name, " \"%s\" ", ap->name);
- X }
- X sprintf(s,
- X "\t%s: Army %s (%d):\n\t\t%d %s\n",
- X np->name, name, ap->id, ap->n_soldiers, ap->type);
- X battle_mail(mail_list,s);
- X
- X/* AH YOU LITTLE BUGGER, the cause of the segmentation fault mystery
- X I didn't look at this sprintf() funtion and it does in fact call
- X total_bonus() and count_force. So I just added an extra parameter
- X **dm
- X */
- X sprintf(s, "\t\tbonus %d, force %d;\n\t\tloses %d men.\n",
- X total_bonus(np, sp, ap, dm), count_force(np, sp, ap, dm), killed);
- X battle_mail(mail_list,s);
- X
- X ap->n_soldiers -= killed;
- X dead += killed;
- X if (ap->n_soldiers == 0) { /* Army destroyed */
- X delete_army_sector(sp, ap);
- X delete_army_nation(np, ap);
- X }
- X tmp_aid = tmp_aid->next;
- X }
- X /* now that we have the dead count, we can raise some of them
- X to join with the vampire units. this code is primitive:
- X just for example, it does not take into account that more
- X people may rise than actually died (if there are lots of
- X vampire units).
- X */
- X for (tmp_aid = list; tmp_aid != NULL; tmp_aid = tmp_aid->next) {
- X np = &world.nations[tmp_aid->owner];
- X /* only if we *do* get the army can we go on. it might have been killed */
- X if (ap = get_army(np, tmp_aid->id)) {
- X/* sp = &world.map[ap->pos.x][ap->pos.y]; why??? */
- X if (is_vampire(ap)) {
- X /* notice that an army canot grow by more than a certain amount */
- X ap->n_soldiers += min((int) (dead*VAMPIRE_FRACT), 10*ap->n_soldiers);
- X }
- X }
- X }
- X return dead;
- X}
- X
- Xfree_list(list)
- X struct armyid *list;
- X{
- X struct armyid *tmp;
- X
- X while (list != NULL) {
- X tmp = list;
- X list = list->next;
- X free(tmp);
- X }
- X}
- X
- Xstatus_check(list,status)
- X struct armyid *list;
- X int status;
- X{
- X struct armyid *tmp;
- X Sarmy *ap, *get_army();
- X
- X tmp = list;
- X while (tmp != NULL) {
- X ap = get_army(&world.nations[tmp->owner],tmp->id);
- X if (ap->status == status) {
- X return 1;
- X }
- X tmp = tmp->next;
- X }
- X return 0;
- X}
- X
- Xbattle_mail(mail_list,s)
- X struct armyid *mail_list;
- X char s[];
- X{
- X struct armyid *alist;
- X
- X alist = mail_list;
- X while (alist != NULL) {
- X single_mail(alist->owner,s);
- X alist = alist->next;
- X }
- X}
- X
- X /* prints the introductory message, with relative
- X coordinates for each nation.
- X */
- Xintro_battle_mail(mail_list, x, y)
- X struct armyid *mail_list;
- X int x, y;
- X{
- X Snation *np;
- X struct armyid *alist = mail_list;
- X char s[EXECLEN];
- X
- X while (alist) {
- X Snation *sect_owner = &world.nations[world.map[x][y].owner];
- X
- X np = &world.nations[alist->owner];
- X sprintf(s, "\nBattle Reported in Sector (%d, %d) [owner: %s]:\n",
- X xrel(x, y, np->capital), yrel(x, y, np->capital),
- X sect_owner->id == 0 ? "unowned" : sect_owner->name);
- X single_mail(alist->owner, s);
- X alist = alist->next;
- X }
- X}
- X
- X /* prints some stuff to the News about the battle */
- Xintro_battle_news(news_fp, x, y, ally_list, enemy_list, neutral_list)
- X FILE *news_fp;
- X int x, y;
- X struct armyid *ally_list, *enemy_list, *neutral_list;
- X{
- X Snation *np;
- X struct armyid *alist; /* to run through the lists */
- X Sarmy *ap, *get_army();
- X Ssector *sp = &world.map[x][y];
- X char s[EXECLEN];
- X
- X np = &world.nations[world.map[x][y].owner]; /* nation in which it happens */
- X fprintf(news_fp, "\nBattle Reported in %s", np->id ? np->name
- X : "unowned land");
- X if (strlen(sp->name) > 0) {
- X fprintf(news_fp, " (\"%s\")", sp->name);
- X }
- X
- X fprintf(news_fp, ".\nInvolved armies:\n");
- X/* fprintf(news_fp, "**************\n"); */
- X alist = ally_list;
- X while (alist) { /* run through the participants */
- X np = &world.nations[alist->owner];
- X ap = get_army(np, alist->id);
- X if (is_spirit(ap)) {
- X fprintf(news_fp, "\t%s (spirit %s)\n", np->name, ap->name);
- X } else {
- X fprintf(news_fp, "\t%s (army %s)\n", np->name, ap->name);
- X }
- X alist = alist->next;
- X }
- X fprintf(news_fp, "versus\n");
- X alist = enemy_list;
- X while (alist) { /* run through the participants */
- X np = &world.nations[alist->owner];
- X ap = get_army(np, alist->id);
- X if (is_spirit(ap)) {
- X fprintf(news_fp, "\t%s (spirit %s)\n", np->name, ap->name);
- X } else {
- X fprintf(news_fp, "\t%s (army %s)\n", np->name, ap->name);
- X }
- X alist = alist->next;
- X }
- X if (neutral_list) {
- X fprintf(news_fp, "Neutral Armies:\n");
- X fprintf(news_fp, "--------------:\n");
- X }
- X alist = neutral_list;
- X while (alist) { /* run through the participants */
- X np = &world.nations[alist->owner];
- X fprintf(news_fp, "\t%s\n", np->name);
- X alist = alist->next;
- X }
- X}
- X
- Xsingle_mail(nation,s)
- X int nation;
- X char s[];
- X{
- X char mailname[NAMELEN];
- X
- X if (world.nations[nation].npc_flag != 0) return;
- X
- X sprintf(mailname, "mail%d", nation);
- X if ( (mailfile = fopen(mailname, "a") ) == NULL)
- X {
- X fprintf(stderr,"Error: Cannot reopen mail file %s\n",mailname);
- X clean_exit();
- X exit(1);
- X }
- X fprintf(mailfile, s);
- X fclose(mailfile);
- X}
- X
- Xbattle(dm, x, y, news_fp, ally_list, enemy_list, neutral_list, mail_list)
- X Sdiplo **dm;
- X int x,y;
- X FILE *news_fp; /* for reporting to the news */
- X struct armyid *ally_list, *enemy_list, *neutral_list, *mail_list;
- X{
- X Snation *np = NULL;
- X Ssector *sp = &world.map[x][y];
- X Sarmy *ap = NULL, *get_army();
- X/* struct armyid *ally_list, *enemy_list, *neutral_list, *mail_list, *tmp; */
- X struct armyid *tmp_alist;
- X int ally_force, enemy_force, neutral_force;
- X int ally_dead, enemy_dead, neutral_dead;
- X int enemy_act_mach, ally_act_mach, neutral_act_mach, mach_force_fact;
- X double defense_loss = 0.0;
- X
- X float ally_losses, enemy_losses, neutral_losses;
- X int nation;
- X
- X char mailname[NAMELEN], s[EXECLEN];
- X
- X /* Initialize the three lists for armies in the sector's battle */
- X
- X/* ally_list = enemy_list = neutral_list = mail_list = NULL; */
- X ally_force = enemy_force = neutral_force = 0;
- X ally_dead = enemy_dead = neutral_dead = 0;
- X ally_losses = enemy_losses = neutral_losses = 0.0;
- X
- X /* Now begin breaking the armies up by affiliations and sum forces */
- X for (tmp_alist = ally_list; tmp_alist != NULL; tmp_alist = tmp_alist->next) {
- X np = &world.nations[tmp_alist->owner];
- X ap = get_army(np, tmp_alist->id);
- X ally_force += count_force(np,sp,ap,dm);
- X }
- X for(tmp_alist = enemy_list; tmp_alist != NULL; tmp_alist = tmp_alist->next) {
- X np = &world.nations[tmp_alist->owner];
- X ap = get_army(np, tmp_alist->id);
- X enemy_force += count_force(np,sp,ap,dm);
- X }
- X for(tmp_alist=neutral_list; tmp_alist != NULL; tmp_alist = tmp_alist->next){
- X np = &world.nations[tmp_alist->owner];
- X ap = get_army(np, tmp_alist->id);
- X neutral_force += count_force(np,sp,ap,dm);
- X }
- X
- X/* tmp = sp->alist;
- X while (tmp != NULL) {
- X np = &world.nations[tmp->owner];
- X ap = get_army(np,tmp->id);
- X nation = tmp->owner;
- X if (ally_list == NULL
- X || supports(dm,ally_list,nation)
- X || against(dm,enemy_list,nation)) {
- X add_to_list(&ally_list,tmp,&mail_list);
- X ally_force += count_force(np,sp,ap,dm);
- X } else {
- X if (supports(dm,enemy_list,nation)
- X || against(dm,ally_list,nation)) {
- X add_to_list(&enemy_list,tmp,&mail_list);
- X enemy_force += count_force(np,sp,ap,dm);
- X } else {
- X add_to_list(&neutral_list,tmp,&mail_list);
- X neutral_force += count_force(np,sp,ap,dm);
- X }
- X }
- X tmp = tmp->next;
- X }
- X*/
- X/* Now adjust the forces for the presence of macines */
- X if ((ally_act_mach = min(count_machine(ally_list) * MEN_PER_MACHINE,
- X count_men(ally_list,(AF_MACHINE)))) != 0)
- X {
- X ally_force += ally_act_mach * mach_bonus_avg(ally_list) / 100;
- X }
- X if ((enemy_act_mach = min(count_machine(enemy_list) * MEN_PER_MACHINE,
- X count_men(enemy_list,(AF_MACHINE)))) != 0)
- X {
- X enemy_force += enemy_act_mach * mach_bonus_avg(enemy_list) / 100;
- X }
- X if ((neutral_act_mach = min(count_machine(neutral_list) * MEN_PER_MACHINE,
- X count_men(neutral_list,(AF_MACHINE)))) != 0)
- X {
- X neutral_force += neutral_act_mach * mach_bonus_avg(neutral_list) / 100;
- X }
- X /* Now calculate loss percentages for each side */
- X if (ally_force != 0 && enemy_force != 0 &&
- X (status_check(ally_list,A_ATTACK) || status_check(enemy_list,A_ATTACK) ||
- X status_check(ally_list,A_OCCUPY) || status_check(enemy_list,A_OCCUPY))) {
- X
- X /* send an introductory message to all users,
- X giving the relative coords of sector in which
- X battle happens. also send out some news.
- X */
- X intro_battle_mail(mail_list, x, y);
- X intro_battle_news(news_fp, x, y, ally_list, enemy_list, neutral_list);
- X
- X ally_losses = (1.0*enemy_force*enemy_force)
- X /(1.0*(ally_force*ally_force + enemy_force*enemy_force));
- X enemy_losses = (1.0*ally_force*ally_force)
- X /(1.0*(ally_force*ally_force + enemy_force*enemy_force));
- X if (ally_losses < enemy_losses) {
- X neutral_losses = ally_losses/10.0;
- X } else {
- X neutral_losses = enemy_losses/10.0;
- X }
- X/* Now we mess with the fortifications. */
- X np = &world.nations[enemy_list->owner];
- X defense_loss = 0.0;
- X if (sp->owner == np->id)
- X {
- X if (ally_act_mach != 0)
- X {
- X defense_loss = count_men(ally_list,AF_MACHINE);
- X defense_loss = defense_loss/ally_act_mach;
- X defense_loss *= enemy_losses;
- X defense_loss = (int)(sp->defense * defense_loss);
- X sp->defense -= (int)defense_loss;
- X }
- X }
- X np = &world.nations[ally_list->owner];
- X if (sp->owner == np->id)
- X {
- X if (enemy_act_mach != 0)
- X {
- X defense_loss = count_men(enemy_list,AF_MACHINE);
- X defense_loss = defense_loss/enemy_act_mach;
- X defense_loss *= ally_losses;
- X defense_loss = (int)(sp->defense * defense_loss);
- X sp->defense -= (int)defense_loss;
- X }
- X }
- X
- X /* Now extract losses from each group */
- X /* calls to extract_losses() */
- X
- X ally_dead = extract_losses(ally_list,ally_losses,mail_list,ALLIES,dm);
- X enemy_dead = extract_losses(enemy_list,enemy_losses,mail_list,ENEMIES,dm);
- X neutral_dead =
- X extract_losses(neutral_list,neutral_losses,mail_list,NEUTRALS,dm);
- X }
- X if (defense_loss != 0.0)
- X {
- X sprintf(s, "\nSector Defenses reduced by %d to %d\n",
- X (int)defense_loss,sp->defense);
- X battle_mail(mail_list,s);
- X }
- X
- X /* Now free up all the memory we ate with our army lists! */
- X free_list(ally_list);
- X free_list(enemy_list);
- X free_list(neutral_list);
- X free_list(mail_list);
- X}
- X
- X /* this is an ugly routine which goes into great detail
- X to see if a war is actually taking place in a given
- X sector. it is totally inefficient, but until we
- X redo the battle code, it will have to do. the previous
- X code used to not yield battles in some cases.
- X */
- Xis_war(dm, x, y, news_fp)
- X Sdiplo **dm;
- X int x, y;
- X FILE *news_fp;
- X{
- X Ssector *sp = &world.map[x][y];
- X Snation *np, *tmp_np;
- X struct armyid *alist, *tmp_alist;
- X int id1, id2, stat1, stat2;
- X
- X/* printf("**********sector (%d,%d)***************\n", x, y); */
- X alist = sp->alist;
- X while (alist != NULL) {
- X/* printf("alist = (%d,%d)\n", alist->owner, alist->id); */
- X np = &world.nations[alist->owner];
- X id1 = np->id;
- X tmp_alist = sp->alist;
- X while (tmp_alist != NULL) {
- X/* printf("\ttmp_alist = (%d,%d)\n", tmp_alist->owner, tmp_alist->id); */
- X tmp_np = &world.nations[tmp_alist->owner];
- X id2 = tmp_np->id;
- X stat1 = get_diplo_status(dm, id1, id2);
- X/* printf("stat1 = %d\n", stat1); */
- X stat2 = get_diplo_status(dm, id2, id1);
- X/* printf("stat2 = %d\n", stat2); */
- X if (stat1 == WAR || stat1 == JIHAD || stat2 == WAR || stat2 == JIHAD) {
- X struct armyid *other_tmp_alist;
- X struct armyid *ally_list, *enemy_list, *neutral_list, *mail_list;
- X int nation;
- X
- X ally_list = enemy_list = neutral_list = mail_list = NULL;
- X
- X printf("Found battle between %s and %s\n", np->name, tmp_np->name);
- X add_to_list(&ally_list, tmp_alist, &mail_list);
- X other_tmp_alist = sp->alist;
- X /* now we add everything else in this sector to some list */
- X while (other_tmp_alist != NULL) {
- X /* bad kludge */
- X nation = other_tmp_alist->owner;
- X /* remember: we have already added an ally. don't
- X duplicate him.
- X */
- X if (other_tmp_alist->owner != tmp_alist->owner
- X || other_tmp_alist->id != tmp_alist->id) {
- X if (ally_list == NULL
- X || supports(dm,ally_list,nation)
- X || against(dm,enemy_list,nation)) {
- X add_to_list(&ally_list,other_tmp_alist,&mail_list);
- X/* ally_force += count_force(np,sp,ap,dm); */
- X } else {
- X if (supports(dm,enemy_list,nation)
- X || against(dm,ally_list,nation)) {
- X add_to_list(&enemy_list,other_tmp_alist,&mail_list);
- X/* enemy_force += count_force(np,sp,ap,dm); */
- X } else {
- X add_to_list(&neutral_list,other_tmp_alist,&mail_list);
- X/* neutral_force += count_force(np,sp,ap,dm); */
- X }
- X }
- X }
- X other_tmp_alist = other_tmp_alist->next;
- X }
- X battle(dm, x, y, news_fp,
- X ally_list, enemy_list, neutral_list, mail_list);
- X return 1;
- X }
- X tmp_alist = tmp_alist->next;
- X }
- X alist = alist->next;
- X }
- X return 0;
- X}
- END_OF_FILE
- if test 27165 -ne `wc -c <'battle.c'`; then
- echo shar: \"'battle.c'\" unpacked with wrong size!
- fi
- # end of 'battle.c'
- fi
- if test -f 'misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc.c'\"
- else
- echo shar: Extracting \"'misc.c'\" \(25699 characters\)
- sed "s/^X//" >'misc.c' <<'END_OF_FILE'
- X/* misc.c -- routines for which a better place has yet to be found */
- X/* or routines which are needed in many places */
- X
- X/*
- X * Copyright (C) 1990 Free Software Foundation, Inc.
- X * Written by the dominion project.
- X *
- X * This file is part of dominion.
- X *
- X * dominion is free software; you can redistribute it and/or
- X * modify it under the terms of the GNU General Public License as published
- X * by the Free Software Foundation; either version 1, or (at your option)
- X * any later version.
- X *
- X * This software is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this software; see the file COPYING. If not, write to
- X * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X */
- X
- X
- X/* int interrupt() - handles interupts */
- X/* show_nation(np) - displays a nation's characteristics */
- X/* free_nation_mark(wp,c) - tell us if the symbol is available */
- X/* getline(s,n) - read a line from stdin, remove \n */
- X/* get_crypt_pass(prompt,s,w) - get password and encrypt */
- X/* critical() - while writing, don't bug me!! */
- X/* noncritical() - normal operation */
- X/* which_mark(x,y,up) - determine which mark is to be shown for */
- X/* the sector in question based on display modes, etc. */
- X/* addsector(np,x,y) - adds sector x,y to nation's list of owned */
- X/* sectors. Also changes owner of sector to nation->id. */
- X/* subtsector(np,x,y) - deletes sector x,y from nation's list of */
- X/* owned sectors. */
- X/* destroy_nation(np) - frees all memory used by that nation */
- X/* get_n_cities(np) - return number of cities in nation */
- X/* get_n_civil(np) - return number of civilians in nation */
- X/* unique_name(name) - returns true if a nation with this name */
- X/* does not exist yet */
- X/* free_army_id(np) - finds first free army id for a nation */
- X/* get_space() - waits for the user to type a space */
- X/* statline(s,s) - places information on the statline */
- X/* statline2(s,s) - places information on statline 2 */
- X/* get_spirit_from_type(up,type) - returns a spirit pointer, given a type */
- X/* gen_exec(s) - puts the exec line into the exec list (and later file) */
- X/* is_good_order(name) - TRUE if this is a valid name for a magic order */
- X/* find_visible_sectors(visible_sectors) - updates visibility matrix */
- X
- X#include "dominion.h"
- X#include "misc.h"
- X#include "army.h"
- X#include "cur_stuff.h"
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <signal.h>
- X
- Xextern int (*wrapx)(), (*wrapy)();
- X
- Xextern Sworld world;
- Xextern struct s_desig_map desig_map[];
- Xextern struct s_altitude_map altitude_map[];
- Xextern struct item_map terrains[];
- Xextern struct item_map climates[];
- Xextern Suser user;
- Xint viewall;
- Xextern int debug;
- X
- XWINDOW *sectw;
- X
- X/* handles interrupts */
- Xint interrupt()
- X{
- X printf("\r\ngot an interrupt. quitting nicely...\r\n");
- X cleanup(); /* cleanup depends on which program you are in */
- X clean_exit();
- X exit(0);
- X}
- X
- X/* show a nation's characteristics */
- Xshow_nation(np)
- X Snation *np; /* nation pointer */
- X{
- X printf("\n\tname: %s (id = %d)\n", np->name, np->id);
- X printf("\tleader: %s\n", np->leader);
- X printf("\tpasswd: %s\n", np->passwd);
- X printf("\tcapital is at (%d, %d)\n", np->capital.x, np->capital.y);
- X printf("\trace is %s\n", np->race.name);
- X printf("\tnation mark is %c\n", np->mark);
- X printf("\t%d civilians; %d soldiers; %d armies.\n",
- X get_n_civil(np), get_n_soldiers(np), np->n_armies);
- X printf("\tmagical order %s\n", np->mag_order);
- X}
- X
- X
- X /* tell us if the symbol is available */
- Xfree_nation_mark(wp, c)
- X Sworld *wp;
- X Symbol c;
- X{
- X int i;
- X
- X if (!isprint(c)) {
- X return 0;
- X }
- X for (i = 0; i < wp->n_nations; ++i) {
- X if (wp->nations[i].mark == c) {
- X return 0;
- X }
- X }
- X return 1;
- X}
- X
- Xgetline(s, n) /* read a line from stdin, remove \n */
- X char s[];
- X int n;
- X{
- X fgets(s, n, stdin);
- X if (s[strlen(s)-1] == '\n') { /* remove \n if it is there */
- X s[strlen(s)-1] = '\0';
- X }
- X}
- X
- X /* get a password and encrypt it. if the parameter "default"
- X has a string in it, use that instead of getting it from
- X the terminal. if "w" is not NULL, get the string from
- X the window "w".
- X */
- Xget_crypt_pass(prompt, pass, w, def_pass)
- X char prompt[], pass[];
- X WINDOW *w;
- X char def_pass[];
- X{
- X char *s1, s2[PASSLEN], *getpass(), *crypt();
- X
- X /* if there is already a password, it is passed in the string def_pass */
- X if (def_pass != NULL && strlen(def_pass) > 0) {
- X strcpy(s2, def_pass);
- X s1 = crypt(s2, SALT);
- X strcpy(pass, s1+2);
- X return;
- X }
- X /* if no password was given us, get it from input */
- X if (w == NULL) {
- X s1 = getpass(prompt);
- X strcpy(s2, s1);
- X s1 = crypt(s2, SALT);
- X strcpy(pass, s1 + 2); /* final crypted pass. without salt */
- X } else {
- X wprintw(w, "%s", prompt);
- X wrefresh(w);
- X wscanw(w, "%s", s2);
- X s1 = crypt(s2, SALT);
- X strcpy(pass, s1+2);
- X }
- X}
- X
- Xcpass(np, pass)
- X Snation *np;
- X char pass[];
- X{
- X char s[EXECLEN];
- X sprintf(s, "CPASS:%d:%s\n", np->id, pass);
- X gen_exec(s);
- X}
- X
- Xwhich_mark(x, y, up)
- X int x, y;
- X Suser *up;
- X{
- X int highlight = 1; /* should we highlight? 1=no,-1=yes */
- X int owner = world.map[x][y].owner, mark = '\0';
- X Ssector *sectp = &world.map[x][y];
- X int visibility = user.visible_sectors[x][y];
- X int cost;
- X Sarmy *ap, *get_army();
- X struct armyid *alist;
- X
- X /* figure out what to draw */
- X /* should find a clean way of dealing with above/under water */
- X if (!user.underwater && sectp->altitude < SEA_LEVEL) {
- X mark = '~'; /* if not underwater, water looks like ~ */
- X }
- X if (user.underwater && sectp->altitude >= SEA_LEVEL) {
- X mark = '.'; /* if underwater, land looks like # */
- X }
- X
- X if (!mark) { /* only if mark is not yet set */
- X switch (up->display) {
- X case DESIGNATION:
- X if (owner == up->id) {
- X mark = desig_map[sectp->designation].mark;
- X } else {
- X if (world.nations[owner].mark == '-') {
- X mark = altitude_map[map_alt(sectp->altitude)].mark;
- X } else {
- X mark = world.nations[owner].mark;
- X }
- X }
- X break;
- X case NATION_MARK:
- X/* if (world.nations[owner].mark == '-' || !(visibility & SEE_OWNER)) {
- X mark = altitude_map[map_alt(sectp->altitude)].mark;
- X } else {
- X mark = world.nations[owner].mark;
- X }
- X */
- X mark = world.nations[owner].mark;
- X break;
- X case SOIL:
- X if (visibility & SEE_RESOURCES) {
- X mark = (sectp->soil <= 9) ? sectp->soil + '0' : '+';
- X } else {
- X mark = '?';
- X }
- X break;
- X case METAL:
- X if (visibility & SEE_RESOURCES) {
- X mark = (sectp->metal <= 9) ? sectp->metal + '0' : '+';
- X } else {
- X mark = '?';
- X }
- X break;
- X case JEWELS:
- X if (visibility & SEE_RESOURCES) {
- X mark = (sectp->jewels <= 9) ? sectp->jewels + '0' : '+';
- X } else {
- X mark = '?';
- X }
- X break;
- X case ALTITUDE:
- X if (visibility & SEE_LAND_WATER) {
- X/* mark = (sectp->altitude <= 9) ? sectp->altitude + '0' : '+'; */
- X if (sectp->altitude > 9) {
- X mark = '+';
- X } else if (sectp->altitude >= 0) {
- X mark = sectp->altitude + '0';
- X } else {
- X mark = (-1 * sectp->altitude) + '0';
- X }
- X } else {
- X mark = '?';
- X }
- X break;
- X case CLIMATE:
- X if (visibility & SEE_LAND_WATER) {
- X mark = climates[sectp->climate].mark;
- X } else {
- X mark = '?';
- X }
- X break;
- X case POPULATION:
- X if (visibility & SEE_POPULATION) {
- X if (sectp->n_people < 950) {
- X mark =(sectp->n_people < 950) ? (sectp->n_people + 50)/100+'0' : '+';
- X } else {
- X mark = 'I';
- X }
- X } else {
- X mark = '?';
- X }
- X break;
- X case ARMY_MOVECOST:
- X if (visibility & SEE_LAND_WATER) {
- X if ((ap=get_army (&world.nations[up->id], user.current_army))
- X == NULL) {
- X cost = get_generic_move_cost (&world.nations[up->id], sectp);
- X } else {
- X cost = get_army_move_cost (&world.nations[up->id], sectp, ap);
- X }
- X mark = (cost <= 9) ? cost + '0' : '+';
- X } else {
- X mark = '?';
- X }
- X break;
- X case MOVECOST:
- X if (visibility & SEE_LAND_WATER) {
- X cost = get_generic_move_cost(&world.nations[up->id], sectp);
- X mark = (cost <= 9) ? cost + '0' : '+';
- X } else {
- X mark = '?';
- X }
- X break;
- X case TERRAIN:
- X if (visibility & SEE_LAND_WATER) {
- X mark = terrains[sectp->terrain - MIN_TERRAIN].mark;
- X } else {
- X mark = '?';
- X }
- X break;
- X default: /* this should never happen */
- X break;
- X }
- X }
- X
- X /* here set the highlighting; we know user owns sector */
- X switch (up->highlight) {
- X case H_OWNED:
- X if (sectp->owner == up->id) {
- X highlight = -1; /* if user owns, highlight */
- X }
- X break;
- X case H_ARMIES:
- X if ((user.visible_sectors[sectp->loc.x][sectp->loc.y] & SEE_ARMIES)
- X && has_visible_army(sectp, &user)) {
- X highlight = -1;
- X }
- X/* if (sectp->alist != NULL
- X && (user.visible_sectors[sectp->loc.x][sectp->loc.y] & SEE_ARMIES)) {
- X highlight = -1;
- X } else {
- X highlight = 1;
- X }
- X*/
- X break;
- X case H_HOSTILE:
- X if (has_hostile (sectp)) {
- X highlight = -1;
- X }
- X break;
- X case H_YOUR_ARMIES:
- X if (sectp->alist != NULL
- X && (user.visible_sectors[sectp->loc.x][sectp->loc.y] & SEE_ARMIES)) {
- X alist = sectp->alist;
- X while (alist != NULL) {
- X if (alist->owner == user.id) {
- X highlight = -1;
- X break;
- X }
- X alist = alist->next;
- X }
- X }
- X break;
- X case H_OTHER_ARMIES:
- X if (sectp->alist != NULL
- X && (user.visible_sectors[sectp->loc.x][sectp->loc.y] & SEE_ARMIES)) {
- X alist = sectp->alist;
- X ap = get_army(&world.nations[alist->owner], alist->id);
- X while (alist != NULL) {
- X if (alist->owner != user.id && !is_hidden(ap)) {
- X highlight = -1;
- X break;
- X }
- X alist = alist->next;
- X }
- X }
- X break;
- X case H_MOVE_LEFT:
- X if (sectp->alist != NULL
- X && (user.visible_sectors[sectp->loc.x][sectp->loc.y] & SEE_ARMIES)) {
- X highlight = 1;
- X alist = sectp->alist;
- X while (alist != NULL) {
- X if (alist->owner == user.id) {
- X ap = get_army(&world.nations[alist->owner], alist->id);
- X if (ap->mvpts > 0) {
- X highlight = -1;
- X }
- X }
- X alist = alist->next;
- X }
- X } else {
- X highlight = 1;
- X }
- X break;
- X case H_UNEMP:
- X if ((sectp->n_people > n_workers(sectp)) && (sectp->owner == up->id)) {
- X highlight = -1;
- X }
- X break;
- X case H_NONE:
- X highlight = 1;
- X break;
- X default:
- X break;
- X }
- X
- X return highlight*mark; /* highlight can be +- 1 */
- X}
- X
- X/********************************************************************/
- X/* adds sector x,y to nation's list of owned sectors. Also changes */
- X/* owner of sector to nation->id. */
- X/********************************************************************/
- Xaddsector(np, x, y)
- X Snation *np;
- X int x, y;
- X{
- X struct pt_list *sect;
- X
- X sect = (struct pt_list *) malloc(sizeof(struct pt_list));
- X sect->pt.x = x;
- X sect->pt.y = y;
- X sect->next = np->ptlist;
- X np->ptlist = sect;
- X np->n_sects++;
- X world.map[x][y].owner = np->id;
- X}
- X
- X
- Xsubtsector(np, x, y)
- X Snation *np;
- X int x, y;
- X{
- X struct pt_list *sect, *temp;
- X
- X sect = np->ptlist;
- X if (sect->pt.x == x && sect->pt.y == y) {
- X temp = sect;
- X np->ptlist = sect->next;
- X (np->n_sects)--;
- X free(temp);
- X } else {
- X temp = sect;
- X while (sect->pt.x != x || sect->pt.y != y && sect->next != NULL) {
- X temp = sect;
- X sect = sect->next;
- X }
- X if (sect->pt.x == x && sect->pt.y == y) {
- X temp->next = sect->next;
- X free(sect);
- X (np->n_sects)--;
- X } else printf("Error - deleting sector not in list!\n");
- X }
- X if (np->n_sects == 0) {
- X np->ptlist = NULL;
- X }
- X}
- X
- X /* Destroy a nation: these things have to be done:
- X 1. Free up its point list, and return the sectors to owner 0
- X 2. Free up its army list, and also its army entires in the
- X various sector army lists. This can be done by disbanding
- X them all. (?)
- X 3. Set the coordinates of its capital to (-1, -1), which alerts
- X the program that this nation is no more.
- X */
- Xdestroy_nation(id)
- X int id;
- X{
- X struct pt_list *ptlist, *pt_tmp;
- X Sarmy *army_list, *ap_tmp;
- X Snation *np = &world.nations[id];
- X Ssector *sp;
- X struct army_id *sect_alist;
- X char s[EXECLEN];
- X
- X if (np->id == 0) {
- X return; /* don't destroy nation 0, ever */
- X }
- X ptlist = np->ptlist;
- X
- X while (ptlist) {
- X /* return all the sectors */
- X world.map[ptlist->pt.x][ptlist->pt.y].owner = 0;
- X world.map[ptlist->pt.x][ptlist->pt.y].designation = D_NODESIG;
- X world.map[ptlist->pt.x][ptlist->pt.y].n_people = 0;
- X pt_tmp = ptlist->next;
- X free(ptlist);
- X --np->n_sects;
- X ptlist = pt_tmp;
- X }
- X np->ptlist = NULL;
- X
- X army_list = np->armies;
- X /* delete armies while we still have armies in the nation */
- X while (army_list) {
- X ap_tmp = army_list->next;
- X sp = &world.map[army_list->pos.x][army_list->pos.y];
- X delete_army_sector(sp, army_list);
- X delete_army_nation(np, army_list);
- X /* free(army_list); */
- X /* army_list = ap_tmp; */
- X army_list = np->armies;
- X }
- X np->armies = NULL;
- X
- X /* set capital to (-1,-1): this tells dominion that
- X the parrot (i mean, nation) is no more
- X */
- X np->capital.x = -1;
- X np->capital.y = -1;
- X}
- X
- X /* returns the number of cities in this nation */
- Xget_n_cities(np)
- X Snation *np;
- X{
- X Ssector *sp;
- X struct pt_list *ptlist = np->ptlist;
- X int n_cities = 0;
- X
- X while (ptlist != NULL) {
- X sp = &world.map[ptlist->pt.x][ptlist->pt.y];
- X if (sp->designation == D_CITY || sp->designation == D_CAPITAL) {
- X ++n_cities;
- X }
- X ptlist = ptlist->next;
- X }
- X return n_cities;
- X}
- X
- X /* returns the number of civilians in this nation */
- Xget_n_civil(np)
- X Snation *np;
- X{
- X Ssector *sp;
- X struct pt_list *ptlist = np->ptlist;
- X int n_civil = 0;
- X
- X while (ptlist != NULL) {
- X sp = &world.map[ptlist->pt.x][ptlist->pt.y];
- X n_civil += sp->n_people;
- X ptlist = ptlist->next;
- X }
- X return n_civil;
- X}
- X
- X /* returns the number of soldiers in this nation (includes spirits) */
- Xget_n_soldiers(np)
- X Snation *np;
- X{
- X Sarmy *armies = np->armies;
- X int n_sold = 0;
- X
- X while (armies != NULL) {
- X n_sold += armies->n_soldiers;
- X armies = armies->next;
- X }
- X return n_sold;
- X}
- X
- X /* returns true if a nation with this name does not yet exist */
- Xunique_name(name)
- X char name[];
- X{
- X int i;
- X for (i = 0; i < NATIONS; ++i) {
- X if (strcmp(world.nations[i].name, name) == 0) {
- X return 0; /* found a conflicting name */
- X }
- X }
- X return 1; /* didn't find it any conflict */
- X}
- X
- X /* this is for when the user hits a harmless key, don't give error */
- Xnull_key()
- X{
- X}
- X
- X /* returns the first free army id for a nation */
- Xfree_army_id(np)
- X Snation *np;
- X{
- X Sarmy *ap = np->armies, *ap_prev = np->armies;
- X int id;
- X
- X if (ap == NULL) {
- X return 0;
- X }
- X if (ap->id > 0) { /* if first slot is unused */
- X return 0;
- X }
- X if (ap->next == NULL) {
- X return 1;
- X }
- X
- X while (ap != NULL) {
- X if (ap->id > ap_prev->id+1) { /* a space!! */
- X id = ap_prev->id + 1;
- X return id;
- X }
- X ap_prev = ap;
- X ap = ap->next;
- X }
- X /* if we have not yet found it, it must be the last one!! */
- X/* beep(); refresh(); */
- X id = ap_prev->id + 1;
- X return id;
- X}
- X
- X /* this waits for the user to type a space */
- Xget_space()
- X{
- X fflush(stdin);
- X while (getch() != ' ') {
- X }
- X}
- X
- X#ifndef min
- Xmin(a,b)
- X int a,b;
- X{
- X return (a < b) ? a : b;
- X}
- X
- Xmax(a,b)
- X int a,b;
- X{
- X return (a > b) ? a : b;
- X}
- X#endif
- X
- Xstatline(s1, s2) /* print status line with s1 and s2 */
- X char s1[], s2[];
- X{
- X /* the stat line goes at the bottom of the screen */
- X mvaddstr(LINES-1, 0, s1); /* first string at beginning */
- X clrtoeol();
- X /* second string at end of line */
- X standout();
- X mvaddstr(LINES-1, COLS-strlen(s2)-2, s2);
- X standend();
- X refresh();
- X}
- X
- X /* statline2 is like statline, but prints on the second-last line.
- X statline2 should be used for instructions while a command is being run,
- X (like a move_army).
- X */
- Xstatline2(s1, s2)
- X char s1[], s2[];
- X{
- X /* the stat line goes at the bottom of the screen */
- X mvprintw(LINES-2, 0, "%s", s1); /* first string at beginning */
- X clrtoeol();
- X /* second string at end of line */
- X standout();
- X mvprintw(LINES-2, COLS-strlen(s2)-2, "%s", s2);
- X standend();
- X refresh();
- X}
- X
- X /* this runs a statline, and then moves to just
- X after s1, for a prompt. used a lot in xmode
- X */
- Xstatline_prompt(s1, s2)
- X char s1[], s2[];
- X{
- X statline(s1, s2);
- X move(LINES-1, strlen(s1));
- X refresh();
- X}
- X
- X /* this runs a statline2, and then moves to just
- X after s1, for a prompt. used a lot in xmode
- X */
- Xstatline2_prompt(s1, s2)
- X char s1[], s2[];
- X{
- X statline2(s1, s2);
- X move(LINES-2, strlen(s1));
- X refresh();
- X}
- X
- X /* runs a statline2, waits for a space to be typed,
- X then cleans the statline2 and returns
- X */
- Xstatline2_err(s1, s2)
- X char s1[], s2[];
- X{
- X statline2(s1, s2);
- X get_space();
- X statline2("", "");
- X}
- X
- X /* curses interface */
- Xinit_screen()
- X{
- X printf("initializing screen...\r\n");
- X initscr();
- X savetty();
- X/* nonl(); */
- X cbreak();
- X noecho();
- X clear();
- X /* OK, now the stdscr is made, must make a couple other windows */
- X sectw = newwin(SECTW_SIZE_Y, SECTW_SIZE_X, SECTW_Y, SECTW_X);
- X /* armyw = newwin(ARMYW_SIZE_Y, ARMYW_SIZE_X, ARMYW_Y, ARMYW_X); */
- X /* move the point to the user's capital (to start) */
- X if (user.map_style == NORMAL_MAP) {
- X move(user.cursor.y, user.cursor.x);
- X } else {
- X move(2*user.cursor.y, user.cursor.x);
- X }
- X /* refresh(); */
- X}
- X
- X /* returns a pointer to the spirit pointer of that given type */
- Xstruct spirit_type *get_spirit_type(up, type)
- X Suser *up;
- X char type[];
- X{
- X int i;
- X extern struct spirit_type *spirit_types;
- X
- X/* printf("user.n_spirit_types = %d\n", up->n_spirit_types); */
- X for (i = 0; i < up->n_spirit_types; ++i) {
- X/* printf("type=%s, spirit_types[%d].type = %s\n", type, i, spirit_types[i].type); */
- X if (strcmp(type, spirit_types[i].type) == 0) {
- X return &(spirit_types[i]);
- X }
- X }
- X return NULL;
- X}
- X
- X /* add to the user's exec_list; write it to file if full.
- X If passed string is NULL, DON'T generate exec, and
- X write out the whole thing anyway.
- X */
- Xgen_exec(s)
- X char *s;
- X{
- X FILE *fp, *fopen();
- X char exec_file[NAMELEN];
- X int i;
- X
- X sprintf(exec_file, "exec/exec%d", user.id);
- X
- X /* first add the string s to the user's exec_lines;
- X special case if string is empty or NULL:
- X if empty, do nothing;
- X if NULL, write out to file.
- X */
- X if ((s != NULL) && (strlen(s) == 0)) {
- X return;
- X }
- X if (s != NULL) {
- X strcpy(user.exec_lines[user.n_execs], s);
- X ++user.n_execs;
- X }
- X if ((user.n_execs >= N_EXECS) || (s == NULL) ) {
- X if ((fp = fopen(exec_file, "a")) == NULL) {
- X printf("cannot open your exec file, this is serious\n");
- X clean_exit();
- X exit(1);
- X }
- X critical();
- X for (i = 0; i < user.n_execs; ++i) {
- X fprintf(fp, "%s", user.exec_lines[i]);
- X /* printf("debug: writing to exec file: %s", user.exec_lines[i]); */
- X }
- X fclose(fp);
- X noncritical();
- X user.n_execs = 0; /* reset count */
- X }
- X}
- X
- X
- X/* This just displays the title/intro screen */
- Xintro(wp, np)
- X Sworld *wp;
- X Snation *np;
- X{
- X FILE *mail;
- X char txt[200];
- X
- X sprintf(txt, "mail/mail.%d", np->id);
- X mail = fopen(txt, "r");
- X strcpy(txt, "Dominion");
- X mvprintw((LINES-12)/2, (COLS-strlen(txt))/2, txt);
- X sprintf(txt, "Version %s", VERSION);
- X mvprintw((LINES-10)/2, (COLS-strlen(txt))/2, txt);
- X standout();
- X strcpy(txt, "Copyright (c) 1990, Free Software Foundation");
- X mvprintw((LINES-6)/2, (COLS-strlen(txt))/2, txt);
- X standend();
- X sprintf(txt, "Thon %d", wp->turn);
- X mvprintw((LINES-2)/2, (COLS-strlen(txt))/2, txt);
- X sprintf(txt, "%d nations", wp->n_nations);
- X mvprintw(LINES/2, (COLS-strlen(txt))/2, txt);
- X sprintf(txt, "world size is %d across, %d down", wp->xmax, wp->ymax);
- X mvprintw((LINES-2)/2, (COLS-strlen(txt))/2, txt);
- X standout();
- X if (mail) {
- X strcpy(txt, "You have mail!");
- X mvprintw((LINES+6)/2, (COLS-strlen(txt))/2, txt);
- X fclose(mail);
- X }
- X strcpy(txt, "Press any key to begin");
- X mvprintw((LINES+10)/2, (COLS-strlen(txt))/2, txt);
- X standend();
- X refresh();
- X getch();
- X clear();
- X}
- X
- X /* check the mag_Orders file, and see if this is a valid magic order */
- Xis_good_order(name)
- X char name[];
- X{
- X int good = 0;
- X FILE *fp, *fopen();
- X char line[200];
- X int i, n_orders;
- X
- X if ((fp = fopen(MAG_ORDERS, "r")) == NULL) {
- X printf("cannot find file %s. this is bad.\n", MAG_ORDERS);
- X clean_exit();
- X exit(1);
- X }
- X while (fgets(line, 200, fp) != NULL) {
- X /* printf("%s", line); */
- X if (line[0] != '#') {
- X sscanf(line, "%d", &n_orders);
- X break; /* we got the number of orders */
- X }
- X }
- X /* printf("there are %d magical orders\n", n_orders); */
- X for (i = 0; i < n_orders; ) {
- X fgets(line, NAMELEN, fp);
- X if (line[strlen(line)-1] == '\n') {
- X line[strlen(line)-1] = '\0';
- X }
- X if (line[0] != '#') {
- X if (strncmp(line, name, NAMELEN) == 0) {
- X good = 1;
- X }
- X ++i;
- X }
- X }
- X return good;
- X}
- X
- X /* returns true if there is at least one
- X non-hidden army on this sector.
- X */
- Xhas_visible_army(sp, up)
- X Ssector *sp;
- X Suser *up;
- X{
- X struct armyid *alist = sp->alist;
- X Sarmy *ap, *get_army();
- X int found = 0;
- X
- X while (alist) {
- X ap = get_army(&world.nations[alist->owner], alist->id);
- X if (!is_hidden(ap)) {
- X found = 1;
- X break;
- X }
- X alist = alist->next;
- X }
- X return found;
- X}
- X
- X /* this routine goes through the entire map and figures out
- X which sectors are visible by the user.
- X */
- Xfind_visible_sectors(visible_sectors)
- X int **visible_sectors;
- X{
- X int x, y, i, j;
- X struct pt_list *plist;
- X Sarmy *ap;
- X Ssector *sp;
- X
- X for (i = 0; i < world.xmax; ++i) {
- X for (j = 0; j < world.ymax; ++j) {
- X visible_sectors[i][j] = viewall ? SEE_ALL : SEE_NOTHING;
- X }
- X }
- X for (plist = user.np->ptlist; plist != NULL; plist = plist->next) {
- X x = plist->pt.x;
- X y = plist->pt.y;
- X visible_sectors[x][y] = SEE_ALL;
- X for (i = x-LAND_SIGHT; i <= x+LAND_SIGHT; ++i) {
- X for (j = y-LAND_SIGHT; j <= y+LAND_SIGHT; ++j) {
- X sp = &world.map[(*wrapx)(i,j)][(*wrapy)(i,j)];
- X if (has_hidden(sp) && sp->owner != user.id) {
- X visible_sectors[x][y] |= SEE_ARMIES;
- X } else {
- X visible_sectors[(*wrapx)(i,j)][(*wrapy)(i,j)] |=
- X (SEE_LAND_WATER | SEE_OWNER | SEE_DESIG | SEE_POPULATION);
- X }
- X if (world.map[(*wrapx)(i,j)][(*wrapy)(i,j)].owner == 0) {
- X visible_sectors[(*wrapx)(i,j)][(*wrapy)(i,j)] |= SEE_RESOURCES;
- X }
- X }
- X }
- X }
- X for (ap = user.np->armies; ap != NULL; ap = ap->next) {
- X x = ap->pos.x;
- X y = ap->pos.y;
- X sp = &world.map[x][y];
- X if (has_hidden(sp) && sp->owner != user.id) {
- X visible_sectors[x][y] = SEE_ARMIES;
- X } else {
- X visible_sectors[x][y] = SEE_ALL;
- X }
- X for (i = x-ARMY_SIGHT; i <= x+ARMY_SIGHT; ++i) {
- X for (j = y-ARMY_SIGHT; j <= y+ARMY_SIGHT; ++j) {
- X sp = &world.map[(*wrapx)(i,j)][(*wrapy)(i,j)];
- X if (!has_hidden(sp)) {
- X visible_sectors[(*wrapx)(i,j)][(*wrapy)(i,j)] |=
- X (SEE_LAND_WATER | SEE_OWNER | SEE_DESIG |
- X SEE_POPULATION | SEE_ARMIES);
- X }
- X if (world.map[(*wrapx)(i,j)][(*wrapy)(i,j)].owner == 0) {
- X visible_sectors[(*wrapx)(i,j)][(*wrapy)(i,j)] |= SEE_RESOURCES;
- X }
- X }
- X }
- X }
- X}
- X
- X/* Returns a string that formats the arguments */
- X
- Xchar * contents (money, metal, jewels, food, people, army, title, sp)
- X
- Xint money, metal, jewels, food, people, army, sp;
- XPt * title;
- X{
- X char * rcontents;
- X char tmps [60];
- X
- X if ((rcontents = (char *)malloc (sizeof (char) * 100)) == NULL) {
- X clean_exit();
- X exit (-1);
- X }
- X
- X sprintf (rcontents, "");
- X
- X if (money > 0) {
- X sprintf (tmps, "/%d sk.", money);
- X strcat (rcontents, tmps);
- X }
- X if (metal > 0) {
- X sprintf (tmps, "/%d met", metal);
- X strcat (rcontents, tmps);
- X }
- X if (jewels > 0) {
- X sprintf (tmps, "/%d jwl", jewels);
- X strcat (rcontents, tmps);
- X }
- X if (food > 0) {
- X sprintf (tmps, "/%d food", food);
- X strcat (rcontents, tmps);
- X }
- X if (people > 0) {
- X sprintf (tmps, "/%d peop", people);
- X strcat (rcontents, tmps);
- X }
- X if (army >= 0) {
- X sprintf (tmps, "/army %d", army);
- X strcat (rcontents, tmps);
- X }
- X if (title && title->x != -1) {
- X sprintf (tmps, "/sect %d,%d",
- X xrel (title->x, title->y, user.np->capital),
- X yrel (title->x, title->y, user.np->capital));
- X strcat (rcontents, tmps);
- X }
- X if (sp > 0) {
- X sprintf (tmps, "/%d sp", sp);
- X strcat (rcontents, tmps);
- X }
- X
- X if (rcontents [0] == '/') {
- X strcpy (rcontents, rcontents + 1);
- X }
- X
- X return rcontents;
- X}
- X
- Xint univ_intel (np)
- X
- XSnation * np;
- X{
- X double sqrt ();
- X int ret;
- X
- X if (get_n_civil (np)) {
- X ret = (int) (100 * get_n_students (np) / get_n_civil (np));
- X }
- X else { ret = 0; }
- X
- X return ret;
- X}
- X
- X
- X/*
- X if (get_n_civil (np)) {
- X ret = (int) sqrt ((double)(get_n_students (np) / 5));
- X if (ret > 100) {
- X ret = 100;
- X }
- X return ret;
- X }
- X return 0;
- X*/
- X
- Xint priestliness (np)
- X
- XSnation * np;
- X{
- X double sqrt ();
- X int ret;
- X
- X if (get_n_civil (np)) {
- X ret = (int) (100 * get_n_priests (np) / get_n_civil (np));
- X }
- X else { ret = 0; }
- X
- X return ret;
- X}
- X/* if (get_n_civil (np)) {
- X ret = (int) sqrt ((double)(get_n_priests (np) / 5));
- X if (ret > 100) {
- X ret = 100;
- X }
- X return ret;
- X }
- X return 0;
- X*/
- END_OF_FILE
- if test 25699 -ne `wc -c <'misc.c'`; then
- echo shar: \"'misc.c'\" unpacked with wrong size!
- fi
- # end of 'misc.c'
- fi
- echo shar: End of archive 19 \(of 28\).
- cp /dev/null ark19isdone
- MISSING=""
- 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
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 28 archives.
- echo "Now execute ./do_cat.sh to build doc files"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-