Clean up library dependencies
authorMarkus Armbruster <armbru@pond.sub.org>
Sat, 2 Feb 2008 20:03:12 +0000 (21:03 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Sun, 3 Feb 2008 07:11:13 +0000 (08:11 +0100)
Move stuff to untangle the ugly cyclic dependencies between the
archives built for selected subdirectories of src/lib/:

* Move common/io.c to empthread/ because it requires empthread stuff

* Move parts of subs/nstr.c to common/nstreval.c to satisfy
  common/ef_verify.o

* Move getstarg.c getstring.c onearg.c from gen/ to subs/ because they
  require stuff from there

* Move bridgefall.c check.c damage.c empobj.c journal.c maps.c
  sectdamage.c from common/ to subs/ because they require stuff from
  there

* Move cnumb.c from subs/ to common/ to satisfy common/type.o

* Move log.c fsize.c from common/ to gen/ because they really belong
  there

* Move emp_config.c mapdist.c from gen/ to common/ because they really
  belong there, and require stuff from libglobal.a

Also package as/ as libas.a to satisfy common/path.o.

Remaining dependencies:

    lib             needs
    --------------------------------------------
    libas.a         libglobal.a
    libcommon.a     libas.a libglobal.a libgen.a
    libgen.a
    libglobal.a
    liblwp.a        libgen.a
    libw32.a[*]     libgen.a

    [*] Except for service.o, which can only be linked into the server

Link order now: liblwp.a libcommon.a libas.a libgen.a libglobal.a
libw32.a.  The position of libw32.a is not quite right, but works
anyway.

36 files changed:
Make.mk
include/prototypes.h
src/lib/common/bridgefall.c [deleted file]
src/lib/common/check.c [deleted file]
src/lib/common/cnumb.c [new file with mode: 0644]
src/lib/common/damage.c [deleted file]
src/lib/common/emp_config.c [new file with mode: 0644]
src/lib/common/empobj.c [deleted file]
src/lib/common/fsize.c [deleted file]
src/lib/common/journal.c [deleted file]
src/lib/common/log.c [deleted file]
src/lib/common/mapdist.c [new file with mode: 0644]
src/lib/common/maps.c [deleted file]
src/lib/common/nstreval.c [new file with mode: 0644]
src/lib/common/sectdamage.c [deleted file]
src/lib/empthread/io.c [new file with mode: 0644]
src/lib/gen/emp_config.c [deleted file]
src/lib/gen/fsize.c [new file with mode: 0644]
src/lib/gen/getstarg.c [deleted file]
src/lib/gen/getstring.c [deleted file]
src/lib/gen/io.c [deleted file]
src/lib/gen/log.c [new file with mode: 0644]
src/lib/gen/mapdist.c [deleted file]
src/lib/gen/onearg.c [deleted file]
src/lib/subs/bridgefall.c [new file with mode: 0644]
src/lib/subs/check.c [new file with mode: 0644]
src/lib/subs/cnumb.c [deleted file]
src/lib/subs/damage.c [new file with mode: 0644]
src/lib/subs/empobj.c [new file with mode: 0644]
src/lib/subs/getstarg.c [new file with mode: 0644]
src/lib/subs/getstring.c [new file with mode: 0644]
src/lib/subs/journal.c [new file with mode: 0644]
src/lib/subs/maps.c [new file with mode: 0644]
src/lib/subs/nstr.c
src/lib/subs/onearg.c [new file with mode: 0644]
src/lib/subs/sectdamage.c [new file with mode: 0644]

diff --git a/Make.mk b/Make.mk
index 9449545f4a11ef65651d3c245254bf488a2209b7..2508e1b727ce9e30b20051d071de929a382567ec 100644 (file)
--- a/Make.mk
+++ b/Make.mk
@@ -102,7 +102,7 @@ obj := $(csrc:.c=.o) $(filter %.o, $(ac:.c=.o))
 # Dependencies:
 deps := $(obj:.o=.d)
 # Library archives:
-libs := $(addprefix lib/, libcommon.a libgen.a libglobal.a)
+libs := $(addprefix lib/, libcommon.a libas.a libgen.a libglobal.a)
 # Programs:
 util := $(addprefix src/util/, $(addsuffix $(EXEEXT), empsched fairland files pconfig))
 client := src/client/empire$(EXEEXT)
@@ -115,17 +115,17 @@ info.nr := $(addprefix info.nr/, $(info))
 info.html := $(addprefix info.html/, $(addsuffix .html, $(info)))
 
 # Conditionally generated files:
+empth_obj := src/lib/empthread/io.o
+empth_lib :=
 ifeq ($(empthread),LWP)
-empth_obj := src/lib/empthread/lwp.o src/lib/empthread/posix.o
-empth_lib := lib/liblwp.a
+empth_obj += src/lib/empthread/lwp.o src/lib/empthread/posix.o
+empth_lib += lib/liblwp.a
 endif
 ifeq ($(empthread),POSIX)
-empth_obj := src/lib/empthread/pthread.o src/lib/empthread/posix.o
-empth_lib :=
+empth_obj += src/lib/empthread/pthread.o src/lib/empthread/posix.o
 endif
 ifeq ($(empthread),Windows)
-empth_obj := src/lib/empthread/ntthread.o
-empth_lib :=
+empth_obj += src/lib/empthread/ntthread.o
 endif
 
 ifeq ($(empthread),Windows)    # really: W32, regardless of thread package
@@ -262,7 +262,7 @@ info.html/%.html: info/%.t
 
 # Compilation
 
-$(server): $(filter src/server/% src/lib/as/% src/lib/commands/% src/lib/player/% src/lib/subs/% src/lib/update/%, $(obj)) $(empth_obj) $(libs) $(empth_lib)
+$(server): $(filter src/server/% src/lib/commands/% src/lib/player/% src/lib/subs/% src/lib/update/%, $(obj)) $(empth_obj) $(empth_lib) $(libs)
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
 
 $(client): $(filter src/client/%, $(obj)) src/lib/global/version.o
@@ -273,6 +273,7 @@ endif
 
 $(util): $(libs)
 
+lib/libas.a: $(filter src/lib/as/%, $(obj))
 lib/libcommon.a: $(filter src/lib/common/%, $(obj))
 lib/libgen.a: $(filter src/lib/gen/%, $(obj))
 lib/libglobal.a: $(filter src/lib/global/%, $(obj))
index 3ed8becfc0c5fe0fa64fa76c73263ad7715369f6..24d14f3ef48ff28a2da45f37b1f62b37041a0d40 100644 (file)
@@ -259,38 +259,16 @@ int zdon(void);
  */
 /* bestpath.c */
 extern char *bestownedpath(char *, char *, int, int, int, int, int);
-/* bridgefall.c */
-extern void bridgefall(struct sctstr *, struct emp_qelem *);
-extern void knockdown(struct sctstr *, struct emp_qelem *);
-/* damage.c */
-extern void landdamage(struct lndstr *, int);
-extern void ship_damage(struct shpstr *, int);
-extern int damage(int, int);
-extern void shipdamage(struct shpstr *, int);
-extern void land_damage(struct lndstr *, int);
-extern void planedamage(struct plnstr *, int);
-extern int nukedamage(struct nchrstr *, int, int);
-extern int effdamage(int, int);
-extern void item_damage(int, short *);
-extern int commdamage(int, int, i_type);
-/* check.c */
-extern int check_sect_ok(struct sctstr *);
-extern int check_ship_ok(struct shpstr *);
-extern int check_land_ok(struct lndstr *);
-extern int check_nuke_ok(struct nukstr *);
-extern int check_plane_ok(struct plnstr *);
-extern int check_comm_ok(struct comstr *);
-extern int check_loan_ok(struct lonstr *);
-extern int check_trade_ok(struct trdstr *);
 /* conftab.c */
 extern int read_builtin_tables(void);
 extern int read_custom_tables(void);
+/* cnumb.c */
+extern int cnumb(char *);
 /* ef_verify.c */
 /* in file.h */
-/* fsize.c */
-extern int fsize(int);
-extern int blksize(int);
-extern time_t fdate(int);
+/* emp_config.c */
+extern int emp_config(char *file);
+extern void print_config(FILE * fp);
 /* hap_fact.c */
 extern double hap_fact(struct natstr *, struct natstr *);
 extern double hap_req(struct natstr *np);
@@ -303,17 +281,15 @@ extern int loginit(char *);
 extern int logreopen(void);
 extern void logerror(char *, ...) ATTRIBUTE((format (printf, 1, 2)));
 /* more in misc.h */
-/* maps.c */
-extern int do_map(int bmap, int unit_type, char *arg1, char *arg2);
-extern int draw_map(int, char, int, struct nstr_sect *);
-extern int unit_map(int, int, struct nstr_sect *, char *);
-extern int display_region_map(int bmap, int unit_type, coord curx,
-                             coord cury, char *arg);
-extern int bmaps_intersect(natid, natid);
-extern int share_bmap(natid, natid, struct nstr_sect *, char, char *);
+/* mapdist.c */
+extern int diffx(int, int);
+extern int diffy(int, int);
+extern int deltax(int, int);
+extern int deltay(int, int);
+extern int mapdist(int, int, int, int);
 /* move.c */
 /* in path.h */
-/* nstr_subs.c */
+/* nstreval.c */
 /* in nsc.h */
 /* path.c */
 extern void bp_enable_cachepath(void);
@@ -331,9 +307,6 @@ extern int read_schedule(char *, time_t[], int, time_t, time_t);
 /* res_pop.c */
 extern int max_population(float, int, int);
 extern int max_pop(float, struct sctstr *);
-/* sectdamage.c */
-extern int sect_damage(struct sctstr *, int, struct emp_qelem *);
-extern int sectdamage(struct sctstr *, int, struct emp_qelem *);
 /* stmtch.c */
 /* in match.h */
 /* type.c */
@@ -348,21 +321,16 @@ extern int xundump(FILE *, char *, int *, int);
 /*
  * src/lib/gen/ *.c 
  */
-/* emp_config.c */
-extern int emp_config(char *file);
-extern void print_config(FILE * fp);
+/* fsize.c */
+extern int fsize(int);
+extern int blksize(int);
+extern time_t fdate(int);
 
 extern int roll(int);
 extern int roundavg(double);
 extern int chance(double);
 extern int disassoc(void);
-extern int diffx(int, int);
-extern int diffy(int, int);
-extern int deltax(int, int);
-extern int deltay(int, int);
-extern int mapdist(int, int, int, int);
 extern char *effadv(int);
-extern int onearg(char *, char *);
 extern int parse(char *, char *, char **, char **, char **, char **);
 extern int ldround(double, int);
 extern int roundintby(int, int);
@@ -430,19 +398,40 @@ extern void stop_service(void);
 /* askyn.c */
 extern int confirm(char *);
 extern int askyn(char *);
+/* bridgefall.c */
+extern void bridgefall(struct sctstr *, struct emp_qelem *);
+extern void knockdown(struct sctstr *, struct emp_qelem *);
 /* bsanct.c */
 extern void bsanct(void);
 /* caploss.c */
 extern void caploss(struct sctstr *, natid, char *);
+/* check.c */
+extern int check_sect_ok(struct sctstr *);
+extern int check_ship_ok(struct shpstr *);
+extern int check_land_ok(struct lndstr *);
+extern int check_nuke_ok(struct nukstr *);
+extern int check_plane_ok(struct plnstr *);
+extern int check_comm_ok(struct comstr *);
+extern int check_loan_ok(struct lonstr *);
+extern int check_trade_ok(struct trdstr *);
 /* chkmoney.c */
 extern int chkmoney(long, long, char *);
 extern int check_cost(int, int, long, int *, char *);
-/* cnumb.c */
-extern int cnumb(char *);
 /* coastal.c */
 extern void set_coastal(struct sctstr *, int, int);
 /* control.c */
 extern int military_control(struct sctstr *);
+/* damage.c */
+extern void landdamage(struct lndstr *, int);
+extern void ship_damage(struct shpstr *, int);
+extern int damage(int, int);
+extern void shipdamage(struct shpstr *, int);
+extern void land_damage(struct lndstr *, int);
+extern void planedamage(struct plnstr *, int);
+extern int nukedamage(struct nchrstr *, int, int);
+extern int effdamage(int, int);
+extern void item_damage(int, short *);
+extern int commdamage(int, int, i_type);
 /* detonate.c */
 extern int detonate(struct nukstr *, coord, coord, int);
 /* disloan.c */
@@ -486,7 +475,15 @@ extern int num_shipsatxy(coord, coord, int, int);
 extern int has_units(coord, coord, natid, struct lndstr *);
 extern int adj_units(coord, coord, natid);
 extern int islist(char *);
-/* src/lib/subs/mission.c */
+/* maps.c */
+extern int do_map(int bmap, int unit_type, char *arg1, char *arg2);
+extern int draw_map(int, char, int, struct nstr_sect *);
+extern int unit_map(int, int, struct nstr_sect *, char *);
+extern int display_region_map(int bmap, int unit_type, coord curx,
+                             coord cury, char *arg);
+extern int bmaps_intersect(natid, natid);
+extern int share_bmap(natid, natid, struct nstr_sect *, char, char *);
+/* mission.c */
 extern char *mission_name(short);
 extern int collateral_damage(coord, coord, int, struct emp_qelem *);
 extern int mission_pln_equip(struct plist *, struct ichrstr *, int, char);
@@ -536,6 +533,8 @@ extern int nuk_on_plane(struct nukstr *, int);
 extern int nxtitem(struct nstr_item *, void *);
 /* nxtsct.c */
 extern int nxtsct(struct nstr_sect *, struct sctstr *);
+/* onearg.c */
+extern int onearg(char *, char *);
 /* plane.c */
 extern char *prplane(struct plnstr *);
 extern int pln_postread(int, void *);
@@ -631,6 +630,9 @@ extern int sct_postread(int, void *);
 extern int sct_prewrite(int, void *);
 extern void item_prewrite(short *);
 extern int issector(char *);
+/* sectdamage.c */
+extern int sect_damage(struct sctstr *, int, struct emp_qelem *);
+extern int sectdamage(struct sctstr *, int, struct emp_qelem *);
 /* ship.c */
 extern char *prship(struct shpstr *);
 extern int shp_postread(int, void *);
diff --git a/src/lib/common/bridgefall.c b/src/lib/common/bridgefall.c
deleted file mode 100644 (file)
index c11529d..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  bridgefall.c: Knock a bridge down
- * 
- *  Known contributors to this file:
- *     Steve McClure, 1998
- */
-
-#include <config.h>
-
-#include "file.h"
-#include "land.h"
-#include "lost.h"
-#include "misc.h"
-#include "nat.h"
-#include "nsc.h"
-#include "nuke.h"
-#include "optlist.h"
-#include "path.h"
-#include "plague.h"
-#include "plane.h"
-#include "prototypes.h"
-#include "sect.h"
-#include "xy.h"
-
-void
-bridgefall(struct sctstr *sp, struct emp_qelem *list)
-{
-    int i;
-    int j;
-    struct sctstr sect;
-    struct sctstr bh_sect;
-    int nx;
-    int ny;
-    int nnx;
-    int nny;
-
-    for (i = 1; i <= 6; i++) {
-       nx = sp->sct_x + diroff[i][0];
-       ny = sp->sct_y + diroff[i][1];
-       getsect(nx, ny, &sect);
-       if (sect.sct_type != SCT_BSPAN)
-           continue;
-       for (j = 1; j <= 6; j++) {
-           nnx = nx + diroff[j][0];
-           nny = ny + diroff[j][1];
-           if (nnx == sp->sct_x && nny == sp->sct_y)
-               continue;
-           getsect(nnx, nny, &bh_sect);
-           if (bh_sect.sct_type == SCT_BHEAD &&
-               bh_sect.sct_newtype == SCT_BHEAD)
-               break;
-           if (bh_sect.sct_type == SCT_BTOWER)
-               break;
-           /* With EASY_BRIDGES, it just has to be next to any
-              land */
-           if (opt_EASY_BRIDGES) {
-               if (bh_sect.sct_type != SCT_WATER &&
-                   bh_sect.sct_type != SCT_BSPAN)
-                   break;
-           }
-       }
-       if (j > 6) {
-           knockdown(&sect, list);
-           putsect(&sect);
-       }
-    }
-}
-
-/* Knock down a bridge span.  Note that this does NOT write the
- * sector out to the database, it's up to the caller to do that. */
-void
-knockdown(struct sctstr *sp, struct emp_qelem *list)
-{
-    struct lndstr land;
-    struct plnstr plane;
-    struct nukstr nuke;
-    struct nstr_item ni;
-    struct natstr *np;
-
-    mpr(sp->sct_own,
-       "Crumble... SCREEEECH!  Splash! Bridge%s falls at %s!\n",
-       sp->sct_type == SCT_BTOWER ? " tower" : "",
-       xyas(sp->sct_x, sp->sct_y, sp->sct_own));
-    sp->sct_type = SCT_WATER;
-    sp->sct_newtype = SCT_WATER;
-    makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y);
-    sp->sct_own = 0;
-    sp->sct_oldown = 0;
-    sp->sct_mobil = 0;
-    sp->sct_effic = 0;
-
-    /* Sink all the units */
-    snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y);
-    while (nxtitem(&ni, &land)) {
-       if (land.lnd_own == 0)
-           continue;
-       if (land.lnd_ship >= 0)
-           continue;
-       np = getnatp(land.lnd_own);
-       if (np->nat_flags & NF_BEEP)
-           mpr(land.lnd_own, "\07");
-       mpr(land.lnd_own, "     AARGH! %s tumbles to its doom!\n",
-           prland(&land));
-       land.lnd_effic = 0;
-       putland(land.lnd_uid, &land);
-    }
-    /* Sink all the planes */
-    snxtitem_xy(&ni, EF_PLANE, sp->sct_x, sp->sct_y);
-    while (nxtitem(&ni, &plane)) {
-       if (plane.pln_own == 0)
-           continue;
-       if (plane.pln_flags & PLN_LAUNCHED)
-           continue;
-       if (plane.pln_ship >= 0)
-           continue;
-       /* Is this plane flying in this list? */
-       if (ac_isflying(&plane, list))
-           continue;
-       np = getnatp(plane.pln_own);
-       if (np->nat_flags & NF_BEEP)
-           mpr(plane.pln_own, "\07");
-       mpr(plane.pln_own, "     AARGH! %s tumbles to its doom!\n",
-           prplane(&plane));
-       plane.pln_effic = 0;
-       putplane(plane.pln_uid, &plane);
-    }
-    /* Sink all the nukes */
-    snxtitem_xy(&ni, EF_NUKE, sp->sct_x, sp->sct_y);
-    while (nxtitem(&ni, &nuke)) {
-       if (nuke.nuk_own == 0)
-           continue;
-       if (nuke.nuk_plane >= 0)
-           continue;
-       np = getnatp(nuke.nuk_own);
-       if (np->nat_flags & NF_BEEP)
-           mpr(nuke.nuk_own, "\07");
-       mpr(nuke.nuk_own, "     %s sinks to the bottom of the sea!\n",
-           prnuke(&nuke));
-       nuke.nuk_effic = 0;
-       putnuke(nuke.nuk_uid, &nuke);
-    }
-    memset(sp->sct_item, 0, sizeof(sp->sct_item));
-    memset(sp->sct_del, 0, sizeof(sp->sct_del));
-    memset(sp->sct_dist, 0, sizeof(sp->sct_dist));
-    sp->sct_pstage = PLG_HEALTHY;
-    sp->sct_ptime = 0;
-    sp->sct_che = 0;
-    sp->sct_che_target = 0;
-}
diff --git a/src/lib/common/check.c b/src/lib/common/check.c
deleted file mode 100644 (file)
index d8b3150..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  check.c: Check a sector, plane, land unit, ship or nuke
- * 
- *  Known contributors to this file:
- *     Steve McClure, 1998
- */
-
-#include <config.h>
-
-#include "commodity.h"
-#include "file.h"
-#include "land.h"
-#include "loan.h"
-#include "misc.h"
-#include "nat.h"
-#include "nsc.h"
-#include "nuke.h"
-#include "plane.h"
-#include "player.h"
-#include "prototypes.h"
-#include "sect.h"
-#include "ship.h"
-#include "trade.h"
-#include "xy.h"
-
-/* Note that timestamps make things tricky.  And, we don't
- * really care about the timestamp, we just care about the rest
- * of the structure.  So, we make a copy, and zero the timestamps
- * in both copies, and then compare. */
-
-int
-check_sect_ok(struct sctstr *sectp)
-{
-    struct sctstr chksect;
-    struct sctstr tsect;
-
-    getsect(sectp->sct_x, sectp->sct_y, &chksect);
-    memcpy(&tsect, sectp, sizeof(struct sctstr));
-    tsect.sct_timestamp = chksect.sct_timestamp = 0;
-    if (memcmp(&tsect, &chksect, sizeof(struct sctstr))) {
-       pr("Sector %s has changed!\n",
-          xyas(sectp->sct_x, sectp->sct_y, player->cnum));
-       return 0;
-    }
-    return 1;
-}
-
-int
-check_ship_ok(struct shpstr *shipp)
-{
-    struct shpstr chkship;
-    struct shpstr tship;
-
-    getship(shipp->shp_uid, &chkship);
-    memcpy(&tship, shipp, sizeof(struct shpstr));
-    tship.shp_timestamp = chkship.shp_timestamp = 0;
-    if (memcmp(&tship, &chkship, sizeof(struct shpstr))) {
-       pr("Ship #%d has changed!\n", shipp->shp_uid);
-       return 0;
-    }
-    return 1;
-}
-
-int
-check_plane_ok(struct plnstr *planep)
-{
-    struct plnstr chkplane;
-    struct plnstr tplane;
-
-    getplane(planep->pln_uid, &chkplane);
-    memcpy(&tplane, planep, sizeof(struct plnstr));
-    tplane.pln_timestamp = chkplane.pln_timestamp = 0;
-    if (memcmp(&tplane, &chkplane, sizeof(struct plnstr))) {
-       pr("Plane #%d has changed!\n", planep->pln_uid);
-       return 0;
-    }
-    return 1;
-}
-
-int
-check_land_ok(struct lndstr *landp)
-{
-    struct lndstr chkland;
-    struct lndstr tland;
-
-    getland(landp->lnd_uid, &chkland);
-    memcpy(&tland, landp, sizeof(struct lndstr));
-    tland.lnd_timestamp = chkland.lnd_timestamp = 0;
-    if (memcmp(&tland, &chkland, sizeof(struct lndstr))) {
-       pr("Land unit #%d has changed!\n", landp->lnd_uid);
-       return 0;
-    }
-    return 1;
-}
-
-int
-check_nuke_ok(struct nukstr *nukep)
-{
-    struct nukstr chknuke;
-    struct nukstr tnuke;
-
-    getnuke(nukep->nuk_uid, &chknuke);
-    memcpy(&tnuke, nukep, sizeof(struct nukstr));
-    tnuke.nuk_timestamp = chknuke.nuk_timestamp = 0;
-    if (memcmp(&tnuke, &chknuke, sizeof(struct nukstr))) {
-       pr("Nuke %d has changed!\n", nukep->nuk_uid);
-       return 0;
-    }
-    return 1;
-}
-
-int
-check_loan_ok(struct lonstr *loanp)
-{
-    struct lonstr chkloan;
-
-    getloan(loanp->l_uid, &chkloan);
-    if (memcmp(loanp, &chkloan, sizeof(struct lonstr))) {
-       pr("Loan %d has changed!\n", loanp->l_uid);
-       return 0;
-    }
-    return 1;
-}
-
-int
-check_comm_ok(struct comstr *commp)
-{
-    struct comstr chkcomm;
-
-    getcomm(commp->com_uid, &chkcomm);
-    if (memcmp(commp, &chkcomm, sizeof(struct comstr))) {
-       pr("Commodity %d has changed!\n", commp->com_uid);
-       return 0;
-    }
-    return 1;
-}
-
-int
-check_trade_ok(struct trdstr *tp)
-{
-    struct trdstr chktrade;
-
-    gettrade(tp->trd_uid, &chktrade);
-    if (memcmp(tp, &chktrade, sizeof(struct trdstr))) {
-       pr("Trade lot #%d has changed!\n", tp->trd_uid);
-       return 0;
-    }
-    return 1;
-}
diff --git a/src/lib/common/cnumb.c b/src/lib/common/cnumb.c
new file mode 100644 (file)
index 0000000..26a48b1
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  cnumb.c: Return country number give country name
+ * 
+ *  Known contributors to this file:
+ *     
+ */
+
+#include <config.h>
+
+#include "file.h"
+#include "match.h"
+#include "nat.h"
+#include "prototypes.h"
+
+/*
+ * Search for a country matching CNTRY, return its number.
+ * Return M_NOTFOUND if no such country exists, M_NOTUNIQUE if there
+ * are several.
+ */
+int
+cnumb(char *cntry)
+{
+    char *ncp;
+    char *cp;
+    struct natstr *natp;
+    int res;
+    natid cn;
+
+    res = M_NOTFOUND;
+    for (cn = 0; cn < MAXNOC; cn++) {
+       if ((natp = getnatp(cn)) == 0)
+           break;
+       if (natp->nat_stat == STAT_UNUSED)
+           continue;
+       ncp = natp->nat_cnam;
+       for (cp = cntry; *cp == *ncp; cp++, ncp++) {
+           if (*cp == 0)
+               return cn;      /* exact match */
+       }
+       if (*cp == 0) {
+           /* is a prefix */
+           if (res >= 0)
+               return M_NOTUNIQUE;
+           res = cn;
+       }
+    }
+    return res;
+}
diff --git a/src/lib/common/damage.c b/src/lib/common/damage.c
deleted file mode 100644 (file)
index 11684fb..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  damage.c: Damage stuff.
- * 
- *  Known contributors to this file:
- *     Dave Pare, 1989
- *     Steve McClure, 1997
- */
-
-#include <config.h>
-
-#include "damage.h"
-#include "land.h"
-#include "misc.h"
-#include "nsc.h"
-#include "nuke.h"
-#include "optlist.h"
-#include "plane.h"
-#include "prototypes.h"
-#include "sect.h"
-#include "ship.h"
-
-void
-item_damage(int pct, short *item)
-{
-    int lose;
-    i_type i;
-
-    for (i = I_NONE + 1; i <= I_MAX; ++i) {
-       if (opt_SUPER_BARS && i == I_BAR)
-           continue;
-       lose = roundavg((double)item[i] * pct * 0.01);
-       if (i == I_CIVIL || i == I_MILIT || i == I_UW)
-           lose = ldround(people_damage * lose, 1);
-       item[i] = item[i] >= lose ? item[i] - lose : 0;
-    }
-}
-
-void
-ship_damage(struct shpstr *sp, int dam)
-{
-    if (dam <= 0)
-       return;
-    if (dam > 100)
-       dam = 100;
-
-    mpr(sp->shp_own, "\t%s takes %d\n", prship(sp), dam);
-
-    sp->shp_effic = damage((int)sp->shp_effic, dam);
-    if (sp->shp_mobil > 0)
-       sp->shp_mobil = damage((int)sp->shp_mobil, dam);
-    if (opt_FUEL && sp->shp_fuel)
-       sp->shp_fuel = damage((int)sp->shp_fuel, dam);
-    item_damage(dam, sp->shp_item);
-}
-
-void
-shipdamage(struct shpstr *sp, int dam)
-{
-    ship_damage(sp, (int)(dam / (1.0 + sp->shp_armor / 100.0)));
-}
-
-void
-land_damage(struct lndstr *lp, int dam)
-{
-    if (dam <= 0)
-       return;
-    if (dam > 100)
-       dam = 100;
-
-    mpr(lp->lnd_own, "\t%s takes %d\n", prland(lp), dam);
-    if (lchr[(int)lp->lnd_type].l_flags & L_SPY) {
-       /* Spies die! */
-       lp->lnd_effic = 0;
-    } else {
-       lp->lnd_effic = damage((int)lp->lnd_effic, dam);
-       if (lp->lnd_mobil > 0)
-           lp->lnd_mobil = damage((int)lp->lnd_mobil, dam);
-       if (opt_FUEL && lp->lnd_fuel)
-           lp->lnd_fuel = damage((int)lp->lnd_fuel, dam);
-       item_damage(dam, lp->lnd_item);
-    }
-}
-
-void
-landdamage(struct lndstr *lp, int dam)
-{
-    double damage_factor, m;
-
-    m = land_mob_max;
-
-    /* fortification reduces damage */
-    damage_factor = m / (m + lp->lnd_harden);
-
-    /* vulnerable units take more damage */
-    damage_factor *= lp->lnd_vul / 100.0;
-
-    land_damage(lp, ldround(damage_factor * dam, 1));
-}
-
-void
-planedamage(struct plnstr *pp, int dam)
-{
-    if (dam <= 0)
-       return;
-    if (dam > 100)
-       dam = 100;
-
-    mpr(pp->pln_own, "\t%s takes %d\n", prplane(pp), dam);
-    pp->pln_effic = damage((int)pp->pln_effic, dam);
-    if (pp->pln_mobil > 0)
-       pp->pln_mobil = damage((int)pp->pln_mobil, dam);
-}
-
-/*
- * nukedamage() actually just calculates damage
- * rather than inflicting it.
- */
-int
-nukedamage(struct nchrstr *ncp, int range, int airburst)
-{
-    int dam;
-    int rad;
-
-    rad = ncp->n_blast;
-    if (airburst)
-       rad = (int)(rad * 1.5);
-    if (rad < range)
-       return 0;
-    if (airburst) {
-       /* larger area, less center damage */
-       dam = (int)((ncp->n_dam * 0.75) - (range * 20));
-    } else {
-       /* smaller area, more center damage */
-       dam = (int)(ncp->n_dam / (range + 1.0));
-    }
-    if (dam < 5)
-       dam = 0;
-    return dam;
-}
-
-int
-damage(int amt, int pct)
-{
-    int tmp;
-    int lost;
-
-    if (amt <= 0)
-       return 0;
-    tmp = amt * pct;
-    lost = tmp / 100;
-    if (random() % 100 < tmp % 100)
-       lost++;
-    return amt - lost;
-}
-
-/* asymptotic damage to commodities, efficiency, and sectors */
-int
-effdamage(int amt, int dam)
-{
-    return damage(amt, PERCENT_DAMAGE(dam));
-}
-
-int
-commdamage(int amt, int dam, i_type vtype)
-{
-    int lost;
-
-    if (vtype == I_BAR && opt_SUPER_BARS)
-       return amt;
-
-    lost = amt - effdamage(amt, dam);
-
-    if (vtype == I_MILIT || vtype == I_CIVIL || vtype == I_UW)
-       lost = ldround(people_damage * lost, 1);
-    return amt - lost;
-}
diff --git a/src/lib/common/emp_config.c b/src/lib/common/emp_config.c
new file mode 100644 (file)
index 0000000..7997b9a
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  emp_config.c: Allows config file to control server config. from a file
+ * 
+ *  Known contributors to this file:
+ *     Julian Onions, 1995
+ *     Steve McClure, 1998-2000
+ */
+
+/*
+ * STILL TO DO
+ *
+ * Change other constants - such as MAXNOC etc.
+ * Just requires variables to be assigned, then dynamic allocation in
+ * a few places.  Some checks needed in the server to check the world
+ * hasn't changed size etc.
+ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "file.h"
+#include "misc.h"
+#include "optlist.h"
+#include "prototypes.h"
+
+/* Dummy one */
+static int emp_config_dummy;
+
+/* things that can be changed */
+struct keymatch configkeys[] = {
+#define        EMP_CONFIG_C_OUTPUT
+#include "econfig-spec.h"
+#undef EMP_CONFIG_C_OUTPUT
+};
+
+static struct keymatch *keylookup(char *key, struct keymatch tbl[]);
+static void set_paths(char *);
+
+/*
+ * read in empire configuration
+ */
+int
+emp_config(char *file)
+{
+    FILE *fp;
+    char scanspace[1024];
+    char *av[128];
+    char buf[1024];
+    struct keymatch *kp;
+    int lno = 0;
+    int errors = 0;
+    int i;
+
+    if (!file)
+       file = dflt_econfig;
+    errno = 0;
+    if ((fp = fopen(file, "r")) == NULL) {
+       if (file == dflt_econfig && errno == ENOENT)
+           goto done;
+       fprintf(stderr, "Can't open %s for reading (%s)\n",
+               file, strerror(errno));
+       return -1;
+    }
+
+    while (fgets(buf, sizeof(buf), fp) != NULL) {
+       ++lno;
+       for (i = 0; buf[i] && isspace(buf[i]); ++i) ;
+       if (!buf[i] || buf[i] == '#')
+           continue;
+       if (parse(buf, scanspace, av, NULL, NULL, NULL) < 0) {
+           fprintf(stderr, "%s:%d: Can't parse line %s", file, lno, buf);
+           errors = 1;
+           continue;
+       }
+       if ((kp = keylookup(av[0], configkeys)) == NULL) {
+           fprintf(stderr, "%s:%d: Unknown config key %s\n",
+                   file, lno, av[0]);
+           errors = 1;
+           continue;
+       }
+       if (av[1] == NULL) {
+           fprintf(stderr, "%s:%d: Config key %s needs a value\n",
+                   file, lno, av[0]);
+           errors = 1;
+           continue;
+       }
+       i = 2;
+       switch (kp->km_type) {
+       case NSC_INT:
+           *(int *)kp->km_data = atoi(av[1]);
+           break;
+       case NSC_FLOAT:
+           *(float *)kp->km_data = atof(av[1]);
+           break;
+       case NSC_DOUBLE:
+           *(double *)kp->km_data = atof(av[1]);
+           break;
+       case NSC_LONG:
+           *(long *)kp->km_data = atol(av[1]);
+           break;
+       case NSC_STRING:
+           if (kp->km_flags & KM_ALLOC)
+               free(*(char **)kp->km_data);
+           *(char **)kp->km_data = strdup(av[1]);
+           kp->km_flags |= KM_ALLOC;
+           break;
+       default:
+           assert(0);
+       }
+       if (av[i] != NULL) {
+           fprintf(stderr, "%s:%d: Junk after value of config key %s\n",
+                   file, lno, av[0]);
+           errors = 1;
+       }
+    }
+
+    fclose(fp);
+
+done:
+    WORLD_X &= ~1;             /* force even */
+    set_paths(file);
+
+    return -errors;
+}
+
+/* find the key in the table */
+static struct keymatch *
+keylookup(char *command, struct keymatch *tbl)
+{
+    struct keymatch *kp;
+
+    if (command == 0 || *command == 0)
+       return 0;
+    for (kp = tbl; kp->km_key != 0; kp++) {
+       if (strcmp(kp->km_key, command) == 0)
+           return kp;
+    }
+    return NULL;
+}
+
+static void
+set_paths(char *econfig)
+{
+    char *slash;
+    char *cwd = getcwd(NULL, 0);
+
+#ifdef _WIN32
+    /* normalize path separator to '\\', for easier searching: */
+    econfig = _fullpath(NULL, econfig, 0);
+    slash = strrchr(econfig, '\\');
+    configdir = malloc(slash - econfig + 1);
+    memcpy(configdir, econfig, slash - econfig);
+    configdir[slash - econfig] = 0;
+#else
+    if ((slash = strrchr(econfig, '/'))) {
+       configdir = malloc(slash - econfig + 1);
+       memcpy(configdir, econfig, slash - econfig);
+       configdir[slash - econfig] = 0;
+    } else
+       configdir = strdup(cwd);
+
+    if (configdir[0] != '/') {
+       char *tmp = configdir;
+       size_t len = strlen(cwd);
+
+       configdir = malloc(len + 1 + strlen(tmp) + 1);
+       sprintf(configdir, "%s/%s", cwd, tmp);
+       free(tmp);
+    }
+#endif /* !_WIN32 */
+
+    schedulefil = malloc(strlen(configdir) + 10);
+    sprintf(schedulefil, "%s/schedule", configdir);
+
+    free(cwd);
+}
+
+void
+print_config(FILE *fp)
+{
+    struct keymatch *kp;
+
+    fprintf(fp, "# Empire Configuration File:\n");
+    for (kp = configkeys; kp->km_key; kp++) {
+       if (kp->km_comment) {
+           if (kp->km_comment[0] != '\n' && kp->km_comment[0] != '#')
+               fprintf(fp, "\n# ");
+           fprintf(fp, "%s\n", kp->km_comment);
+       }
+       if (!kp->km_key[0])
+           continue;
+       switch (kp->km_type) {
+       case NSC_STRING:
+           fprintf(fp, "%s \"%s\"\n", kp->km_key, *(char **)kp->km_data);
+           break;
+       case NSC_INT:
+           fprintf(fp, "%s %d\n", kp->km_key, *(int *)kp->km_data);
+           break;
+       case NSC_FLOAT:
+           fprintf(fp, "%s %g\n", kp->km_key, *(float *)kp->km_data);
+           break;
+       case NSC_DOUBLE:
+           fprintf(fp, "%s %g\n", kp->km_key, *(double *)kp->km_data);
+           break;
+       case NSC_LONG:
+           fprintf(fp, "%s %ld\n", kp->km_key, *(long *)kp->km_data);
+           break;
+       default:
+           assert(0);
+       }
+    }
+
+    fprintf(fp, "\n");
+}
diff --git a/src/lib/common/empobj.c b/src/lib/common/empobj.c
deleted file mode 100644 (file)
index 35a18d0..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  empobj.c: Common functions on struct empobj and
- *            union empobj_storage
- * 
- *  Known contributors to this file:
- *     Ron Koenderink, 2006
- *     Markus Armbruster, 2006
- */
-
-#include <config.h>
-
-#include "empobj.h"
-#include "file.h"
-#include "optlist.h"
-#include "prototypes.h"
-
-char *
-obj_nameof(struct empobj *gp)
-{
-    switch (gp->ef_type) {
-    case EF_SHIP:
-       return prship((struct shpstr *)gp);
-    case EF_PLANE:
-       return prplane((struct plnstr *)gp);
-    case EF_LAND:
-       return prland((struct lndstr *)gp);
-    case EF_NUKE:
-       return prnuke((struct nukstr *)gp);
-    }
-    CANT_REACH();
-    return "The Beast #666";
-}
-
-struct empobj *
-get_empobjp(int type, int id)
-{
-    if (CANT_HAPPEN(type == EF_SECTOR || type == EF_BAD))
-       return NULL;
-    return ef_ptr(type, id);
-}
-
-int
-put_empobj(struct empobj *gp)
-{
-    switch (gp->ef_type)
-    {
-    case EF_SECTOR:
-        return ef_write(gp->ef_type, sctoff(gp->x, gp->y), gp);
-    case EF_NATION:
-    case EF_BMAP:
-    case EF_MAP:
-       return ef_write(gp->ef_type, gp->own, gp);
-    default:
-       return ef_write(gp->ef_type, gp->uid, gp);
-    }
-}
-
-struct empobj_chr *
-get_empobj_chr(struct empobj *gp)
-{
-    switch (gp->ef_type) {
-    case EF_LAND:
-       return (struct empobj_chr *)&lchr[(int)gp->type];
-    case EF_SHIP:
-       return (struct empobj_chr *)&mchr[(int)gp->type];
-    case EF_PLANE:
-       return (struct empobj_chr *)&plchr[(int)gp->type];
-    case EF_NUKE:
-       return (struct empobj_chr *)&nchr[(int)gp->type];
-    case EF_SECTOR:
-       return (struct empobj_chr *)&dchr[(int)gp->type];
-    }
-    CANT_REACH();
-    return NULL;
-}
-
-char *
-emp_obj_chr_name(struct empobj *gp)
-{
-    switch (gp->ef_type) {
-    case EF_LAND:
-       return lchr[(int)gp->type].l_name;
-    case EF_SHIP:
-       return mchr[(int)gp->type].m_name;
-    case EF_PLANE:
-       return plchr[(int)gp->type].pl_name;
-    case EF_NUKE:
-       return nchr[(int)gp->type].n_name;
-    case EF_SECTOR:
-       return dchr[(int)gp->type].d_name;
-    }
-    CANT_REACH();
-    return NULL;
-}
-
-int
-get_empobj_mob_max(int type)
-{
-    switch (type) {
-    case EF_SHIP:
-       return ship_mob_max;
-    case EF_LAND:
-       return land_mob_max;
-    case EF_PLANE:
-       return plane_mob_max;
-    case EF_SECTOR:
-       return sect_mob_max;
-    }
-    CANT_REACH();
-    return -1;
-}
diff --git a/src/lib/common/fsize.c b/src/lib/common/fsize.c
deleted file mode 100644 (file)
index 36af6d2..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  fsize.c: BSD dependant file and block sizing routines
- * 
- *  Known contributors to this file:
- *     Dave Pare, 1986
- *     Doug Hay, 1998
- *     Steve McClure, 1998
- */
-
-#include <config.h>
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include "prototypes.h"
-
-/*
- * return the size of the file in bytes.
- */
-int
-fsize(int fd)
-{
-    struct stat statb;
-
-    if (fstat(fd, &statb) < 0)
-       return -1;
-    return statb.st_size;
-}
-
-/*
- * Return the preferred block size for I/O on FD.
- */
-int
-blksize(int fd)
-{
-#if defined(_WIN32)
-    return 2048;
-#else  /* !_WIN32 */
-    struct stat statb;
-
-    if (fstat(fd, &statb) < 0)
-       return 1024;
-    return statb.st_blksize;
-#endif /* !_WIN32 */
-}
-
-time_t
-fdate(int fd)
-{
-    struct stat statb;
-
-    if (fstat(fd, &statb) < 0)
-       return 0;
-    return statb.st_mtime;
-}
diff --git a/src/lib/common/journal.c b/src/lib/common/journal.c
deleted file mode 100644 (file)
index ed111a2..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
- *  related information and legal notices. It is expected that any future
- *  projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  journal.c: Log a journal of events to a file
- * 
- *  Known contributors to this file:
- *     Markus Armbruster, 2004-2007
- */
-
-/*
- * Journal file format: each line logs an event, and looks like this:
- *
- *     TIME THREAD EVENT DATA
- *
- * Events and their data are:
- *
- *     startup
- *     shutdown
- *     login CNUM HOSTADDR USER
- *     logout CNUM
- *     input INPUT
- *     update ETU
- */
-
-#include <config.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <time.h>
-#include "misc.h"
-#include "empthread.h"
-#include "journal.h"
-#include "optlist.h"
-#include "player.h"
-#include "prototypes.h"
-
-static char journal_fname[] = "journal.log";
-static FILE *journal;
-
-static FILE *
-journal_open(void)
-{
-    return fopen(journal_fname, "a+");
-}
-
-static void
-journal_entry(char *fmt, ...)
-{
-    static char buf[1024];
-    va_list ap;
-    time_t now;
-    unsigned char *p;
-
-    if (journal) {
-       time(&now);
-       fprintf(journal, "%.24s %p ", ctime(&now), empth_self());
-       
-       va_start(ap, fmt);
-       vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
-       va_end(ap);
-
-       for (p = (unsigned char *)buf; *p; p++) {
-           if (isprint(*p))
-               putc(*p, journal);
-           else
-               fprintf(journal, "\\%03o", *p);
-       }
-       fputs("\n", journal);
-       if (debug)
-           fflush(journal);
-       if (ferror(journal)) {
-           logerror("Error writing journal (%s)", strerror(errno));
-           clearerr(journal);
-       }
-    }
-}
-
-int
-journal_startup(void)
-{
-    if (!keep_journal)
-       return 0;
-    journal = journal_open();
-    if (!journal) {
-       logerror("Can't open %s (%s)", journal_fname, strerror(errno));
-       return -1;
-    }
-    journal_entry("startup");
-    return 0;
-}
-
-void
-journal_shutdown(void)
-{
-    journal_entry("shutdown");
-    if (journal) {
-       fclose(journal);
-       journal = NULL;
-    }
-}
-
-int
-journal_reopen(void)
-{
-    FILE *j;
-
-    if (!keep_journal)
-       return 0;
-    j = journal_open();
-    if (!j) {
-       logerror("Can't open %s (%s)", journal_fname, strerror(errno));
-       return -1;
-    }
-    if (journal)
-       fclose(journal);
-    journal = j;
-    return 0;
-}
-
-void
-journal_login(void)
-{
-    journal_entry("login %d %s %s",
-                 player->cnum, player->hostaddr, player->userid);
-}
-
-void
-journal_logout(void)
-{
-    journal_entry("logout %d", player->cnum);
-}
-
-void
-journal_input(char *input)
-{
-    journal_entry("input %s", input);
-}
-
-void
-journal_update(int etu)
-{
-    journal_entry("update %d", etu);
-}
diff --git a/src/lib/common/log.c b/src/lib/common/log.c
deleted file mode 100644 (file)
index 1a49c0d..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  log.c: Log an Empire error to a file
- * 
- *  Known contributors to this file:
- *     Dave Pare, 1989
- */
-
-#include <config.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <unistd.h>
-#include "misc.h"
-#include "optlist.h"
-#include "player.h"
-#include "prototypes.h"
-
-/* Debugging?  If yes call abort() on internal error.  */
-int debug = 0;
-
-static char logfile[32];
-static int logfd = -1;
-
-static int logopen(void);
-
-/*
- * Points log file at PROGRAM.log
- */
-int
-loginit(char *program)
-{
-    sprintf(logfile, "%.*s.log", (int)sizeof(logfile) - 5, program);
-    logfd = logopen();
-    return logfd;
-}
-
-static int
-logopen(void)
-{
-    int fd;
-
-    fd = open(logfile, O_WRONLY | O_CREAT | O_APPEND, S_IRWUG);
-    if (fd < 0)
-       logerror("Can't open %s (%s)", logfile, strerror(errno));
-    return fd;
-}
-
-int
-logreopen(void)
-{
-    int newfd, res;
-
-    if ((newfd = logopen()) < 0)
-       return -1;
-    res = close(logfd);
-    logfd = newfd;
-    if (res < 0)
-       logerror("Can't close %s (%s)", logfile, strerror(errno));
-    return res;
-}
-
-/*
- * Write a line to the log file and to stderr.
- * Messages are silently truncated after 512 characters or a newline.
- */
-void
-logerror(char *format, ...)
-{
-    enum {
-       ctime_len = 24,         /* output of ctime() less the newline */
-       msg_space = 512         /* space for formatted message */
-    };
-    va_list list;
-    time_t now;
-    char buf[ctime_len + 1 + msg_space + 2];
-    char *msg, *p;
-
-    va_start(list, format);
-    msg = buf + ctime_len + 1;
-    vsnprintf(msg, msg_space, format, list);
-    buf[sizeof(buf)-2] = 0;
-    p = msg + strlen(msg);
-    p[0] = '\n';
-    p[1] = 0;
-    p = strchr(msg, '\n');
-    p[1] = 0;
-    fputs(msg, stderr);
-    if (logfd >= 0) {
-       time(&now);
-       memcpy(buf, ctime(&now), ctime_len);
-       buf[ctime_len] = ' ';
-       write(logfd, buf, strlen(buf));
-    }
-    va_end(list);
-}
-
-/*
- * Log internal error MSG occured in FILE:LINE.
- * If debugging, call abort(), else return 1.
- */
-int
-oops(char *msg, char *file, int line)
-{
-    logerror("Oops: %s in %s:%d", msg ? msg : "bug", file, line);
-    if (debug) abort();
-    return 1;
-}
-
-/*
- * Report out-of-memory condition and terminate the program.
- * Use this with restraint!  Clean error recovery is preferable, but
- * not always feasible (e.g. halfway through the update) or worthwhile
- * (during server startup).
- */
-void
-exit_nomem(void)
-{
-    logerror("Memory exhausted");
-    exit(1);
-}
diff --git a/src/lib/common/mapdist.c b/src/lib/common/mapdist.c
new file mode 100644 (file)
index 0000000..cac702f
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  mapdist.c: Return the distance between two sectors
+ * 
+ *  Known contributors to this file:
+ *     
+ */
+
+/*
+ * mapdist returns (integer) distance between two sectors.
+ */
+
+#include <config.h>
+
+#include "misc.h"
+#include "optlist.h"
+#include "prototypes.h"
+
+int
+diffx(int x1, int x2)
+{
+    int dx;
+
+    dx = x1 - x2;
+    dx = dx % WORLD_X;
+    if (dx > WORLD_X / 2)
+       dx = dx - WORLD_X;
+    if (dx < -WORLD_X / 2)
+       dx = dx + WORLD_X;
+    return dx;
+}
+
+int
+diffy(int y1, int y2)
+{
+    int dy;
+
+    dy = y1 - y2;
+    dy = dy % WORLD_Y;
+    if (dy > WORLD_Y / 2)
+       dy = dy - WORLD_Y;
+    if (dy < -WORLD_Y / 2)
+       dy = dy + WORLD_Y;
+    return dy;
+}
+
+int
+deltax(int x1, int x2)
+{
+    int dx;
+
+    dx = abs(x1 - x2);
+    dx = dx % WORLD_X;
+    if (dx > WORLD_X / 2)
+       dx = WORLD_X - dx;
+    return dx;
+}
+
+int
+deltay(int y1, int y2)
+{
+    int dy;
+
+    dy = abs(y1 - y2);
+    dy = dy % WORLD_Y;
+    if (dy > WORLD_Y / 2)
+       dy = WORLD_Y - dy;
+    return dy;
+}
+
+int
+mapdist(int x1, int y1, int x2, int y2)
+{
+    int dx, dy;
+
+    x1 = x1 % WORLD_X;
+    y1 = y1 % WORLD_Y;
+    x2 = x2 % WORLD_X;
+    y2 = y2 % WORLD_Y;
+    dx = deltax(x1, x2);
+    dy = deltay(y1, y2);
+    if (dx > dy)
+       return (dx - dy) / 2 + dy;
+    return dy;
+}
diff --git a/src/lib/common/maps.c b/src/lib/common/maps.c
deleted file mode 100644 (file)
index b60d5d6..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  maps.c: Map routines
- * 
- *  Known contributors to this file:
- *     Ken Stevens, 1995
- *     Steve McClure, 1998
- *     Ron Koenderink, 2006
- */
-
-#include <config.h>
-
-#include <ctype.h>
-#include "com.h"
-#include "empobj.h"
-#include "file.h"
-#include "land.h"
-#include "map.h"
-#include "misc.h"
-#include "nat.h"
-#include "nsc.h"
-#include "nuke.h"
-#include "optlist.h"
-#include "plane.h"
-#include "player.h"
-#include "prototypes.h"
-#include "sect.h"
-#include "ship.h"
-#include "xy.h"
-
-static int bmnxtsct(struct nstr_sect *);
-static char map_char(unsigned char type, natid own, int owner_or_god);
-
-int
-do_map(int bmap, int unit_type, char *arg, char *map_flags_arg)
-{
-    struct nstr_sect ns;
-    char origin = '\0';
-    char *b;
-    int map_flags = 0;
-
-    if (!snxtsct(&ns, arg)) {
-       if (unit_map(unit_type, atoi(arg), &ns, &origin))
-           return RET_FAIL;
-    }
-    for (b = map_flags_arg; b && *b; b++) {
-       switch (*b) {
-       case 's':
-       case 'S':
-           map_flags |= MAP_SHIP;
-           break;
-       case 'l':
-       case 'L':
-           map_flags |= MAP_LAND;
-           break;
-       case 'p':
-       case 'P':
-           map_flags |= MAP_PLANE;
-           break;
-       case 'n':
-       case 'N':
-           map_flags |= MAP_NUKE;
-           break;
-       case 'h':
-       case 'H':
-           map_flags |= MAP_HIGH;
-           break;
-       case '*':
-           map_flags |= MAP_ALL;
-           break;
-       case 't':
-           if (bmap != 'b')
-               goto bad_flag;
-           bmap = 't';
-           *(b + 1) = 0;
-           break;
-       case 'r':
-           if (bmap != 'b')
-               goto bad_flag;
-           bmap = 'r';
-           *(b + 1) = 0;
-           break;
-       default:
-       bad_flag:
-           pr("Bad flag %c!\n", *b);
-           break;
-       }
-    }
-    return draw_map(bmap, origin, map_flags, &ns);
-}
-
-int
-draw_map(int bmap, char origin, int map_flags, struct nstr_sect *nsp)
-{
-    struct natstr *np;
-    struct range range;
-    struct nstr_item ni;
-    union empobj_storage unit;
-    coord x, y;
-    int i;
-    /* Note this is not re-entrant anyway, so we keep the buffers
-       around */
-    static unsigned char *bitmap = NULL;
-    static char *wmapbuf = NULL;
-    static char **wmap = NULL;
-    static int ef_mappable[] = { EF_PLANE, EF_SHIP, EF_LAND, EF_NUKE, EF_BAD };
-    static int ef_unit_map[] = { MAP_PLANE, MAP_SHIP, MAP_LAND, MAP_NUKE };
-    char *name;
-
-    if (!wmapbuf)
-       wmapbuf = malloc(WORLD_Y * MAPWIDTH(1));
-    if (!wmap) {
-       wmap = malloc(WORLD_Y * sizeof(char *));
-       if (wmap && wmapbuf) {
-           for (i = 0; i < WORLD_Y; i++)
-               wmap[i] = &wmapbuf[MAPWIDTH(1) * i];
-       } else if (wmap) {
-           free(wmap);
-           wmap = NULL;
-       }
-    }
-    if (!bitmap)
-       bitmap = malloc((WORLD_X * WORLD_Y) / 8);
-    if (!wmapbuf || !wmap || !bitmap) {
-       pr("Memory error, tell the deity.\n");
-       logerror("malloc failed in draw_map\n");
-       return RET_FAIL;
-    }
-
-    if (bmap == 'r') {
-       if (!confirm("Are you sure you want to revert your bmap? "))
-           return RET_OK;
-    }
-    if (!(player->command->c_flags & C_MOD)) {
-       logerror("%s command needs C_MOD flag set",
-                player->command->c_form);
-       player->command->c_flags |= C_MOD;
-    }
-    np = getnatp(player->cnum);
-    /* zap any conditionals */
-    nsp->ncond = 0;
-    xyrelrange(np, &nsp->range, &range);
-    border(&range, "     ", "");
-    blankfill(wmapbuf, &nsp->range, 1);
-    if (bmap) {
-       int c;
-       switch (bmap) {
-       default:
-           CANT_REACH();
-           bmap = 'b';
-           /* fall through */
-       case 'b':
-           while (bmnxtsct(nsp) && !player->aborted) {
-               if (0 != (c = player->bmap[sctoff(nsp->x, nsp->y)]))
-                   wmap[nsp->dy][nsp->dx] = c;
-           }
-           break;
-       case 't':
-           while (bmnxtsct(nsp) && !player->aborted) {
-               if (0 != (c = player->map[sctoff(nsp->x, nsp->y)]))
-                   wmap[nsp->dy][nsp->dx] = c;
-           }
-           break;
-       case 'r':
-           while (bmnxtsct(nsp) && !player->aborted) {
-               player->bmap[sctoff(nsp->x, nsp->y)] =
-                   player->map[sctoff(nsp->x, nsp->y)];
-               if (0 != (c = player->bmap[sctoff(nsp->x, nsp->y)]))
-                   wmap[nsp->dy][nsp->dx] = c;
-           }
-           ef_write(EF_BMAP, player->cnum, player->bmap);
-           break;
-       case 'n':
-           {
-               struct sctstr sect;
-
-               if (!player->god) {
-                   memset(bitmap, 0, (WORLD_X * WORLD_Y) / 8);
-                   bitinit2(nsp, bitmap, player->cnum);
-               }
-               while (nxtsct(nsp, &sect) && !player->aborted) {
-                   if (!player->god && !emp_getbit(nsp->x, nsp->y, bitmap))
-                       continue;
-                   wmap[nsp->dy][nsp->dx]
-                       = map_char(sect.sct_newtype, sect.sct_own,
-                                  player->owner);
-               }
-               break;
-           }
-       }
-    } else {
-       struct sctstr sect;
-       char mapch;
-       int changed = 0;
-
-       if (!player->god) {
-           memset(bitmap, 0, (WORLD_X * WORLD_Y) / 8);
-           bitinit2(nsp, bitmap, player->cnum);
-       }
-       while (nxtsct(nsp, &sect) && !player->aborted) {
-           if (!player->god && !emp_getbit(nsp->x, nsp->y, bitmap))
-               continue;
-           mapch = map_char(sect.sct_type, sect.sct_own, player->owner);
-           wmap[nsp->dy][nsp->dx] = mapch;
-           changed |= map_set(player->cnum, nsp->x, nsp->y, mapch, 0);
-       }
-       if (changed)
-           writemap(player->cnum);
-    }
-    if (player->aborted)
-       return RET_OK;
-
-    i = 0;
-    while (ef_mappable[i] != EF_BAD) {
-       if (map_flags & ef_unit_map[i]) {
-           snxtitem_all(&ni, ef_mappable[i]);
-           while (nxtitem(&ni, &unit)) {
-               if (unit.gen.own == 0)
-                   continue;
-               if (unit.gen.own != player->cnum && !player->god)
-                   continue;
-               if (!xyinrange(unit.gen.x, unit.gen.y, &nsp->range))
-                   continue;
-
-               x = xnorm(unit.gen.x - nsp->range.lx);
-               y = ynorm(unit.gen.y - nsp->range.ly);
-
-               if (ef_mappable[i] == EF_NUKE)
-                   wmap[y][x] = 'N';
-               else {
-                   if ((name = emp_obj_chr_name(&unit.gen)) == NULL)
-                       return RET_FAIL;
-                   wmap[y][x] = *name & ~0x20;
-               }
-           }
-       }
-       i++;
-    }
-    if (map_flags & MAP_HIGH) {
-       struct sctstr sect;
-
-       snxtsct_rewind(nsp);
-       if (!player->god) {
-           memset(bitmap, 0, (WORLD_X * WORLD_Y) / 8);
-           bitinit2(nsp, bitmap, player->cnum);
-       }
-       while (nxtsct(nsp, &sect) && !player->aborted) {
-           if (!player->god && !emp_getbit(nsp->x, nsp->y, bitmap))
-               continue;
-           if (sect.sct_own == player->cnum)
-                wmap[nsp->dy][nsp->dx] |= 0x80;
-       }
-    }
-    if (origin)
-       wmap[5][10] = origin & ~0x20;
-    for (y = nsp->range.ly, i = 0; i < nsp->range.height; y++, i++) {
-       int yval;
-
-       yval = yrel(np, y);
-       wmap[i][nsp->range.width] = '\0';
-       pr("%4d %s %-4d\n", yval, wmap[i], yval);
-       if (y >= WORLD_Y)
-           y -= WORLD_Y;
-    }
-    border(&range, "     ", "");
-    return RET_OK;
-}
-
-/*
- * get the next sector in the range
- */
-static int
-bmnxtsct(struct nstr_sect *np)
-{
-    while (1) {
-       np->dx++;
-       np->x++;
-       if (np->x >= WORLD_X)
-           np->x = 0;
-       if (np->dx >= np->range.width) {
-           np->dx = 0;
-           np->x = np->range.lx;
-           np->dy++;
-           if (np->dy >= np->range.height)
-               return 0;
-           np->y++;
-           if (np->y >= WORLD_Y)
-               np->y = 0;
-       }
-       if ((np->y + np->x) & 01)
-           continue;
-       if (np->type == NS_DIST) {
-           np->curdist = mapdist(np->x, np->y, np->cx, np->cy);
-           if (np->curdist > np->dist)
-               continue;
-       }
-       np->id = sctoff(np->x, np->y);
-       return 1;
-    }
-    /*NOTREACHED*/
-}
-
-/*
- * Return character to use in maps for sector type TYPE owned by OWN.
- * If OWNER_OR_GOD, the map is for the sector's owner or a deity.
- */
-static char
-map_char(unsigned char type, natid own, int owner_or_god)
-{
-    if (CANT_HAPPEN(type > SCT_TYPE_MAX || !dchr[type].d_mnem))
-       return '?';
-    if (owner_or_god
-       || type == SCT_WATER || type == SCT_MOUNT || type == SCT_WASTE
-       || (!own && (type == SCT_RURAL || type == SCT_PLAINS)))
-       return dchr[type].d_mnem;
-    return '?';
-}
-
-int
-unit_map(int unit_type, int uid, struct nstr_sect *nsp, char *originp)
-{
-    struct empobj *gp;
-    struct range range;
-    char *name;
-
-    gp = get_empobjp(unit_type, uid);
-    if (!gp || (gp->own != player->cnum && !player->god) || gp->own == 0)
-       return RET_FAIL;
-
-    if (unit_type == EF_NUKE)
-       *originp = 'n';
-    else {
-       if ((name = emp_obj_chr_name(gp)) == NULL)
-           return RET_FAIL;
-       *originp = *name;
-    }
-
-    range.lx = xnorm(gp->x - 10);
-    range.hx = xnorm(gp->x + 11);
-    range.ly = ynorm(gp->y - 5);
-    range.hy = ynorm(gp->y + 6);
-    xysize_range(&range);
-    snxtsct_area(nsp, &range);
-    return RET_OK;
-}
-
-int
-display_region_map(int bmap, int unit_type, coord curx, coord cury,
-                  char *arg)
-{
-    char coordinates[80];
-    char *map_flag_arg;
-
-    if (!arg || !*arg) {
-       struct natstr *np;
-
-       np = getnatp(player->cnum);
-       sprintf(coordinates, "%d:%d,%d:%d",
-           xrel(np, curx - 10), xrel(np, curx + 11),
-           yrel(np, cury - 5), yrel(np, cury + 6));
-       arg = coordinates;
-       map_flag_arg = NULL;
-    } else {
-       map_flag_arg = strchr(arg, ' ');
-       if (map_flag_arg != NULL) {
-           *map_flag_arg++  = '\0';
-           while (isspace(*map_flag_arg)) map_flag_arg++;
-       }
-    }
-    player->condarg = NULL;
-    return do_map(bmap, unit_type, arg, map_flag_arg);
-}
-
-int
-bmaps_intersect(natid a, natid b)
-{
-    char *mapa = ef_ptr(EF_MAP, a);
-    char *mapb = ef_ptr(EF_MAP, b);
-    int i;
-
-    for (i = 0; i < WORLD_SZ(); i++)
-       if (mapa[i] && mapa[i] != ' ' && mapb[i] && mapb[i] != ' ')
-           return 1;
-    return 0;
-}
-
-/* Note that this requires that the BMAP is mapped into memory */
-
-int
-share_bmap(natid from, natid to, struct nstr_sect *ns, char des,
-          char *from_name)
-{
-    char *from_bmap = ef_ptr(EF_BMAP, from);
-    char *to_bmap = ef_ptr(EF_BMAP, to);
-    int n = 0;
-    struct sctstr sect;
-    char fromdes;
-    char todes;
-    char from_des = *from_name;
-
-    if (isalpha(from_des))
-       from_des &= ~0x20;
-
-    while (nxtsct(ns, &sect)) {
-       if (!(fromdes = from_bmap[sctoff(ns->x, ns->y)]))
-           continue;
-       todes = to_bmap[sctoff(ns->x, ns->y)];
-       if (todes &&
-           todes != '?' &&
-           todes != '.' && todes != ' ' && todes != from_des)
-           continue;
-       if (sect.sct_own == from) {
-           if (fromdes != '=' && fromdes != 'h' && fromdes != des)
-               fromdes = from_des;
-       }
-       if (todes == fromdes)
-           continue;
-       n += map_set(to, ns->x, ns->y, fromdes, 1);
-    }
-
-    if (n)
-       writebmap(to);
-    return n;
-}
diff --git a/src/lib/common/nstreval.c b/src/lib/common/nstreval.c
new file mode 100644 (file)
index 0000000..9bb35dc
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  nstreval.c: evaluate compiled values
+ * 
+ *  Known contributors to this file:
+ *     Dave Pare, 1989
+ *     Steve McClure, 1997
+ *     Markus Armbruster, 2004-2006
+ */
+
+#include <config.h>
+
+#include <limits.h>
+#include "file.h"
+#include "nat.h"
+#include "nsc.h"
+#include "optlist.h"
+
+
+/*
+ * Evaluate VAL.
+ * If VAL is symbolic, evaluate it into a promoted value type.
+ * Use coordinate system of country CNUM.
+ * PTR points to a context object of the type that was used to compile
+ * the value.
+ * Unless WANT is NSC_NOTYPE, coerce the value to promoted value type
+ * WANT.  VAL must be coercible.  That's the case if a previous
+ * nstr_coerce_val(VAL, WANT, STR) succeeded.
+ */
+void
+nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
+{
+    char *memb_ptr;
+    nsc_type valtype;
+    int idx;
+    struct natstr *natp;
+
+    switch (val->val_cat) {
+    default:
+       CANT_REACH();
+       /* fall through */
+    case NSC_VAL:
+       valtype = val->val_type;
+       break;
+    case NSC_OFF:
+       valtype = NSC_LONG;
+       memb_ptr = ptr;
+       memb_ptr += val->val_as.sym.off;
+       idx = val->val_as.sym.idx;
+       switch (val->val_type) {
+       case NSC_CHAR:
+           val->val_as.lng = ((signed char *)memb_ptr)[idx];
+           break;
+       case NSC_UCHAR:
+           val->val_as.lng = ((unsigned char *)memb_ptr)[idx];
+           break;
+       case NSC_SHORT:
+           val->val_as.lng = ((short *)memb_ptr)[idx];
+           break;
+       case NSC_USHORT:
+           val->val_as.lng = ((unsigned short *)memb_ptr)[idx];
+           break;
+       case NSC_INT:
+           val->val_as.lng = ((int *)memb_ptr)[idx];
+           break;
+       case NSC_LONG:
+           val->val_as.lng = ((long *)memb_ptr)[idx];
+           break;
+       case NSC_XCOORD:
+           val->val_as.lng = xrel(getnatp(cnum), ((short *)memb_ptr)[idx]);
+           break;
+       case NSC_YCOORD:
+           val->val_as.lng = yrel(getnatp(cnum), ((short *)memb_ptr)[idx]);
+           break;
+       case NSC_HIDDEN:
+           val->val_as.lng = -1;
+           if (CANT_HAPPEN(((struct natstr *)ptr)->ef_type != EF_NATION))
+               break;
+           natp = getnatp(cnum);
+           if (!opt_HIDDEN
+               || natp->nat_stat == STAT_GOD
+               || (getcontact(natp, idx) && getcontact(ptr, idx)))
+               val->val_as.lng = ((unsigned char *)memb_ptr)[idx];
+           break;
+       case NSC_FLOAT:
+           val->val_as.dbl = ((float *)memb_ptr)[idx];
+           valtype = NSC_DOUBLE;
+           break;
+       case NSC_DOUBLE:
+           val->val_as.dbl = ((double *)memb_ptr)[idx];
+           valtype = NSC_DOUBLE;
+           break;
+       case NSC_STRINGY:
+           CANT_HAPPEN(idx);
+           val->val_as.str.maxsz = val->val_as.sym.len;
+           val->val_as.str.base = (char *)memb_ptr;
+           valtype = NSC_STRING;
+           break;
+       case NSC_STRING:
+           val->val_as.str.base = ((char **)memb_ptr)[idx];
+           val->val_as.str.maxsz = INT_MAX;
+           valtype = NSC_STRING;
+           break;
+       case NSC_TIME:
+           val->val_as.lng = ((time_t *)memb_ptr)[idx];
+           break;
+       default:
+           CANT_REACH();
+           val->val_as.lng = 0;
+       }
+       val->val_cat = NSC_VAL;
+    }
+
+    if (valtype == want)
+       ;
+    else if (want == NSC_DOUBLE) {
+       if (valtype == NSC_LONG) {
+           valtype = want;
+           val->val_as.dbl = val->val_as.lng;
+       }
+    } else if (want == NSC_STRING)
+       CANT_REACH();           /* FIXME implement */
+
+    if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE)) {
+       valtype = want;
+       switch (want) {
+       case NSC_LONG: val->val_as.lng = 0; break;
+       case NSC_DOUBLE: val->val_as.dbl = 0.0; break;
+       case NSC_STRING: val->val_as.str.base = NULL; break;
+       default:
+           CANT_REACH();
+       }
+    }
+
+    val->val_type = valtype;
+}
+
+char *
+symbol_by_value(int key, struct symbol *table)
+{
+    int i;
+
+    for (i = 0; table[i].name; i++)
+       if (key == table[i].value)
+           return table[i].name;
+
+    return NULL;
+}
diff --git a/src/lib/common/sectdamage.c b/src/lib/common/sectdamage.c
deleted file mode 100644 (file)
index 6dcacbb..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  sectdamage.c: Damage a sector
- * 
- *  Known contributors to this file:
- *     Dave Pare, 1989
- *     Steve McClure, 1996
- */
-
-#include <config.h>
-
-#include "combat.h"
-#include "damage.h"
-#include "file.h"
-#include "land.h"
-#include "misc.h"
-#include "nat.h"
-#include "nsc.h"
-#include "optlist.h"
-#include "plane.h"
-#include "prototypes.h"
-#include "sect.h"
-#include "ship.h"
-#include "xy.h"
-
-int
-sect_damage(struct sctstr *sp, int dam, struct emp_qelem *list)
-{
-    int eff;
-
-    if (dam <= 0)
-       return 0;
-    if (dam > 100)
-       dam = 100;
-
-    sp->sct_effic = damage(sp->sct_effic, dam);
-    sp->sct_avail = damage(sp->sct_avail, dam);
-    sp->sct_road = damage(sp->sct_road, dam);
-    sp->sct_rail = damage(sp->sct_rail, dam);
-    sp->sct_defense = damage(sp->sct_defense, dam);
-
-    eff = dam;
-
-    if (sp->sct_mobil > 0)
-       sp->sct_mobil = damage(sp->sct_mobil, dam);
-    item_damage(dam, sp->sct_item);
-    if (opt_EASY_BRIDGES == 0) {
-       if (sp->sct_effic < SCT_MINEFF && sp->sct_type == SCT_BHEAD)
-           bridgefall(sp, list);
-    } else {
-       if (sp->sct_effic < SCT_MINEFF && sp->sct_type == SCT_BSPAN)
-           knockdown(sp, list);
-    }
-    putsect(sp);
-    return eff;
-}
-
-int
-sectdamage(struct sctstr *sp, int dam, struct emp_qelem *list)
-{
-    struct nstr_item ni;
-    struct lndstr land;
-    struct plnstr plane;
-    int eff;
-
-    /* Some sectors are harder/easier to kill..   */
-    /* Average sector has a dstr of 1, so adjust  */
-    /* the damage accordingly. Makes forts a pain */
-    dam = ldround(dam / sector_strength(sp), 1);
-
-    eff = sect_damage(sp, PERCENT_DAMAGE(dam), list);
-
-    /* Damage all the land units in the sector */
-    /* Units don't take full damage */
-    dam = ldround(DPERCENT_DAMAGE(dam * unit_damage), 1);
-    if (dam <= 0)
-       return eff;
-
-    snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y);
-    while (nxtitem(&ni, &land)) {
-       if (!land.lnd_own)
-           continue;
-       landdamage(&land, dam);
-       putland(land.lnd_uid, &land);
-    }
-
-    dam = dam / 7;
-    if (dam <= 0)
-       return eff;
-    snxtitem_xy(&ni, EF_PLANE, sp->sct_x, sp->sct_y);
-    while (nxtitem(&ni, &plane)) {
-       if (!plane.pln_own)
-           continue;
-       if (plane.pln_flags & PLN_LAUNCHED)
-           continue;
-       if (plane.pln_ship >= 0)
-           continue;
-       /* Is this plane flying in this list? */
-       if (ac_isflying(&plane, list))
-           continue;
-       planedamage(&plane, dam);
-       putplane(plane.pln_uid, &plane);
-    }
-    return eff;
-}
diff --git a/src/lib/empthread/io.c b/src/lib/empthread/io.c
new file mode 100644 (file)
index 0000000..4c42a55
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  io.c: Arrange for input and output on a file descriptor to be queued.
+ * 
+ *  Known contributors to this file:
+ *      Doug Hay, 1998
+ *      Steve McClure, 1998
+ */
+
+/*
+ * Arrange for input and output on a file descriptor
+ * to be queued.  Provide main loop -- a mechanism for
+ * blocking across all registered file descriptors, and
+ * reading or writing when appropriate.
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include "empio.h"
+#include "empthread.h"
+#include "ioqueue.h"
+#include "misc.h"
+#include "queue.h"
+#include "server.h"
+
+struct iop {
+    int fd;
+    struct ioqueue *input;
+    struct ioqueue *output;
+    int flags;
+    int bufsize;
+};
+
+void
+io_init(void)
+{
+}
+
+struct iop *
+io_open(int fd, int flags, int bufsize)
+{
+    struct iop *iop;
+
+    flags = flags & (IO_READ | IO_WRITE | IO_NBLOCK | IO_NEWSOCK);
+    if ((flags & (IO_READ | IO_WRITE)) == 0)
+       return NULL;
+    iop = malloc(sizeof(struct iop));
+    if (!iop)
+       return NULL;
+    iop->fd = fd;
+    iop->input = 0;
+    iop->output = 0;
+    iop->flags = 0;
+    iop->bufsize = bufsize;
+    if ((flags & IO_READ) && (flags & IO_NEWSOCK) == 0)
+       iop->input = ioq_create(bufsize);
+    if ((flags & IO_WRITE) && (flags & IO_NEWSOCK) == 0)
+       iop->output = ioq_create(bufsize);
+    if (flags & IO_NBLOCK)
+       io_noblocking(iop, 1);  /* FIXME check success */
+    iop->flags = flags;
+    return iop;
+}
+
+void
+io_close(struct iop *iop)
+{
+
+    if (iop->input != 0)
+       ioq_destroy(iop->input);
+    if (iop->output != 0)
+       ioq_destroy(iop->output);
+    (void)close(iop->fd);
+    free(iop);
+}
+
+int
+io_input(struct iop *iop, int waitforinput)
+{
+    char buf[IO_BUFSIZE];
+    int cc;
+
+    /* Not a read IOP */
+    if ((iop->flags & IO_READ) == 0)
+       return -1;
+    /* IOP is markes as in error. */
+    if (iop->flags & IO_ERROR)
+       return -1;
+    /* Wait for the file to have input. */
+    if (waitforinput) {
+       empth_select(iop->fd, EMPTH_FD_READ);
+    }
+    /* Do the actual read. */
+    cc = read(iop->fd, buf, sizeof(buf));
+    if (cc < 0) {
+       /* would block, so nothing to read. */
+       if (errno == EAGAIN || errno == EWOULDBLOCK)
+           return 0;
+
+       /* Some form of file error occurred... */
+       iop->flags |= IO_ERROR;
+       return -1;
+    }
+
+    /* We eof'd */
+    if (cc == 0) {
+       iop->flags |= IO_EOF;
+       return 0;
+    }
+
+    /* Append the input to the IOQ. */
+    ioq_append(iop->input, buf, cc);
+    return cc;
+}
+
+int
+io_inputwaiting(struct iop *iop)
+{
+    return ioq_qsize(iop->input);
+}
+
+int
+io_outputwaiting(struct iop *iop)
+{
+    return ioq_qsize(iop->output);
+}
+
+int
+io_output(struct iop *iop, int waitforoutput)
+{
+    struct iovec iov[16];
+    int cc;
+    int n;
+    int remain;
+
+    /* If there is no output waiting. */
+    if (!io_outputwaiting(iop))
+       return 0;
+
+    /* If the iop is not write enabled. */
+    if ((iop->flags & IO_WRITE) == 0)
+       return -1;
+
+    /* If the io is marked as in error... */
+    if (iop->flags & IO_ERROR)
+       return -1;
+
+    /* make the iov point to the data in the queue. */
+    /* I.E., each of the elements in the queue. */
+    /* returns the number of elements in the iov. */
+    n = ioq_makeiov(iop->output, iov, IO_BUFSIZE);
+
+    if (n <= 0) {
+       return 0;
+    }
+
+    /* wait for the file to be output ready. */
+    if (waitforoutput != IO_NOWAIT) {
+       /* This waits for the file to be ready for writing, */
+       /* and lets other threads run. */
+       empth_select(iop->fd, EMPTH_FD_WRITE);
+    }
+
+    /* Do the actual write. */
+    cc = writev(iop->fd, iov, n);
+
+    /* if it failed.... */
+    if (cc < 0) {
+       /* Hmm, it would block.  file is opened noblock, soooooo.. */
+       if (errno == EAGAIN || errno == EWOULDBLOCK) {
+           /* If there are remaining bytes, set the IO as remaining.. */
+           remain = ioq_qsize(iop->output);
+           return remain;
+       }
+       iop->flags |= IO_ERROR;
+       return -1;
+    }
+
+    /* If no bytes were written, something happened..  Like an EOF. */
+    if (cc == 0) {
+       iop->flags |= IO_EOF;
+       return 0;
+    }
+
+    /* Remove the number of written bytes from the queue. */
+    ioq_dequeue(iop->output, cc);
+
+    return cc;
+}
+
+int
+io_peek(struct iop *iop, char *buf, int nbytes)
+{
+    if ((iop->flags & IO_READ) == 0)
+       return -1;
+    return ioq_peek(iop->input, buf, nbytes);
+}
+
+int
+io_read(struct iop *iop, char *buf, int nbytes)
+{
+    int cc;
+
+    if ((iop->flags & IO_READ) == 0)
+       return -1;
+    cc = ioq_peek(iop->input, buf, nbytes);
+    if (cc > 0)
+       ioq_dequeue(iop->input, cc);
+    return cc;
+}
+
+int
+io_write(struct iop *iop, char *buf, int nbytes, int doWait)
+{
+    int len;
+
+    if ((iop->flags & IO_WRITE) == 0)
+       return -1;
+    ioq_append(iop->output, buf, nbytes);
+    len = ioq_qsize(iop->output);
+    if (len > iop->bufsize) {
+       if (doWait) {
+           io_output_all(iop);
+       } else {
+           /* only try a write every BUFSIZE characters */
+           if (((len - nbytes) % iop->bufsize) < (len % iop->bufsize))
+               io_output(iop, IO_NOWAIT);
+       }
+    }
+    return nbytes;
+}
+
+int
+io_output_all(struct iop *iop)
+{
+    int n;
+
+    /*
+     * Mustn't block a player thread while update is pending, or else
+     * a malicous player could delay the update indefinitely
+     */
+    while ((n = io_output(iop, IO_NOWAIT)) > 0 && !play_wrlock_wanted)
+       empth_select(iop->fd, EMPTH_FD_WRITE);
+
+    return n;
+}
+
+int
+io_gets(struct iop *iop, char *buf, int nbytes)
+{
+    if ((iop->flags & IO_READ) == 0)
+       return -1;
+    return ioq_gets(iop->input, buf, nbytes);
+}
+
+int
+io_puts(struct iop *iop, char *buf)
+{
+    if ((iop->flags & IO_WRITE) == 0)
+       return -1;
+    return ioq_puts(iop->output, buf);
+}
+
+int
+io_shutdown(struct iop *iop, int flags)
+{
+    flags &= (IO_READ | IO_WRITE);
+    if ((iop->flags & flags) != flags)
+       return -1;
+    if (flags & IO_READ) {
+       shutdown(iop->fd, 0);
+       ioq_drain(iop->input);
+    }
+    if (flags & IO_WRITE) {
+       shutdown(iop->fd, 1);
+       ioq_drain(iop->output);
+    }
+    return 0;
+}
+
+int
+io_noblocking(struct iop *iop, int value)
+{
+    int flags;
+
+    flags = fcntl(iop->fd, F_GETFL, 0);
+    if (flags < 0)
+       return -1;
+    if (value == 0)
+       flags &= ~O_NONBLOCK;
+    else
+       flags |= O_NONBLOCK;
+    if (fcntl(iop->fd, F_SETFL, flags) < 0)
+       return -1;
+    if (value == 0)
+       iop->flags &= ~IO_NBLOCK;
+    else
+       iop->flags |= IO_NBLOCK;
+    return 0;
+}
+
+int
+io_error(struct iop *iop)
+{
+    return iop->flags & IO_ERROR;
+}
+
+int
+io_eof(struct iop *iop)
+{
+    return iop->flags & IO_EOF;
+}
+
+int
+io_fileno(struct iop *iop)
+{
+    return iop->fd;
+}
diff --git a/src/lib/gen/emp_config.c b/src/lib/gen/emp_config.c
deleted file mode 100644 (file)
index 7997b9a..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  emp_config.c: Allows config file to control server config. from a file
- * 
- *  Known contributors to this file:
- *     Julian Onions, 1995
- *     Steve McClure, 1998-2000
- */
-
-/*
- * STILL TO DO
- *
- * Change other constants - such as MAXNOC etc.
- * Just requires variables to be assigned, then dynamic allocation in
- * a few places.  Some checks needed in the server to check the world
- * hasn't changed size etc.
- */
-
-#include <config.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "file.h"
-#include "misc.h"
-#include "optlist.h"
-#include "prototypes.h"
-
-/* Dummy one */
-static int emp_config_dummy;
-
-/* things that can be changed */
-struct keymatch configkeys[] = {
-#define        EMP_CONFIG_C_OUTPUT
-#include "econfig-spec.h"
-#undef EMP_CONFIG_C_OUTPUT
-};
-
-static struct keymatch *keylookup(char *key, struct keymatch tbl[]);
-static void set_paths(char *);
-
-/*
- * read in empire configuration
- */
-int
-emp_config(char *file)
-{
-    FILE *fp;
-    char scanspace[1024];
-    char *av[128];
-    char buf[1024];
-    struct keymatch *kp;
-    int lno = 0;
-    int errors = 0;
-    int i;
-
-    if (!file)
-       file = dflt_econfig;
-    errno = 0;
-    if ((fp = fopen(file, "r")) == NULL) {
-       if (file == dflt_econfig && errno == ENOENT)
-           goto done;
-       fprintf(stderr, "Can't open %s for reading (%s)\n",
-               file, strerror(errno));
-       return -1;
-    }
-
-    while (fgets(buf, sizeof(buf), fp) != NULL) {
-       ++lno;
-       for (i = 0; buf[i] && isspace(buf[i]); ++i) ;
-       if (!buf[i] || buf[i] == '#')
-           continue;
-       if (parse(buf, scanspace, av, NULL, NULL, NULL) < 0) {
-           fprintf(stderr, "%s:%d: Can't parse line %s", file, lno, buf);
-           errors = 1;
-           continue;
-       }
-       if ((kp = keylookup(av[0], configkeys)) == NULL) {
-           fprintf(stderr, "%s:%d: Unknown config key %s\n",
-                   file, lno, av[0]);
-           errors = 1;
-           continue;
-       }
-       if (av[1] == NULL) {
-           fprintf(stderr, "%s:%d: Config key %s needs a value\n",
-                   file, lno, av[0]);
-           errors = 1;
-           continue;
-       }
-       i = 2;
-       switch (kp->km_type) {
-       case NSC_INT:
-           *(int *)kp->km_data = atoi(av[1]);
-           break;
-       case NSC_FLOAT:
-           *(float *)kp->km_data = atof(av[1]);
-           break;
-       case NSC_DOUBLE:
-           *(double *)kp->km_data = atof(av[1]);
-           break;
-       case NSC_LONG:
-           *(long *)kp->km_data = atol(av[1]);
-           break;
-       case NSC_STRING:
-           if (kp->km_flags & KM_ALLOC)
-               free(*(char **)kp->km_data);
-           *(char **)kp->km_data = strdup(av[1]);
-           kp->km_flags |= KM_ALLOC;
-           break;
-       default:
-           assert(0);
-       }
-       if (av[i] != NULL) {
-           fprintf(stderr, "%s:%d: Junk after value of config key %s\n",
-                   file, lno, av[0]);
-           errors = 1;
-       }
-    }
-
-    fclose(fp);
-
-done:
-    WORLD_X &= ~1;             /* force even */
-    set_paths(file);
-
-    return -errors;
-}
-
-/* find the key in the table */
-static struct keymatch *
-keylookup(char *command, struct keymatch *tbl)
-{
-    struct keymatch *kp;
-
-    if (command == 0 || *command == 0)
-       return 0;
-    for (kp = tbl; kp->km_key != 0; kp++) {
-       if (strcmp(kp->km_key, command) == 0)
-           return kp;
-    }
-    return NULL;
-}
-
-static void
-set_paths(char *econfig)
-{
-    char *slash;
-    char *cwd = getcwd(NULL, 0);
-
-#ifdef _WIN32
-    /* normalize path separator to '\\', for easier searching: */
-    econfig = _fullpath(NULL, econfig, 0);
-    slash = strrchr(econfig, '\\');
-    configdir = malloc(slash - econfig + 1);
-    memcpy(configdir, econfig, slash - econfig);
-    configdir[slash - econfig] = 0;
-#else
-    if ((slash = strrchr(econfig, '/'))) {
-       configdir = malloc(slash - econfig + 1);
-       memcpy(configdir, econfig, slash - econfig);
-       configdir[slash - econfig] = 0;
-    } else
-       configdir = strdup(cwd);
-
-    if (configdir[0] != '/') {
-       char *tmp = configdir;
-       size_t len = strlen(cwd);
-
-       configdir = malloc(len + 1 + strlen(tmp) + 1);
-       sprintf(configdir, "%s/%s", cwd, tmp);
-       free(tmp);
-    }
-#endif /* !_WIN32 */
-
-    schedulefil = malloc(strlen(configdir) + 10);
-    sprintf(schedulefil, "%s/schedule", configdir);
-
-    free(cwd);
-}
-
-void
-print_config(FILE *fp)
-{
-    struct keymatch *kp;
-
-    fprintf(fp, "# Empire Configuration File:\n");
-    for (kp = configkeys; kp->km_key; kp++) {
-       if (kp->km_comment) {
-           if (kp->km_comment[0] != '\n' && kp->km_comment[0] != '#')
-               fprintf(fp, "\n# ");
-           fprintf(fp, "%s\n", kp->km_comment);
-       }
-       if (!kp->km_key[0])
-           continue;
-       switch (kp->km_type) {
-       case NSC_STRING:
-           fprintf(fp, "%s \"%s\"\n", kp->km_key, *(char **)kp->km_data);
-           break;
-       case NSC_INT:
-           fprintf(fp, "%s %d\n", kp->km_key, *(int *)kp->km_data);
-           break;
-       case NSC_FLOAT:
-           fprintf(fp, "%s %g\n", kp->km_key, *(float *)kp->km_data);
-           break;
-       case NSC_DOUBLE:
-           fprintf(fp, "%s %g\n", kp->km_key, *(double *)kp->km_data);
-           break;
-       case NSC_LONG:
-           fprintf(fp, "%s %ld\n", kp->km_key, *(long *)kp->km_data);
-           break;
-       default:
-           assert(0);
-       }
-    }
-
-    fprintf(fp, "\n");
-}
diff --git a/src/lib/gen/fsize.c b/src/lib/gen/fsize.c
new file mode 100644 (file)
index 0000000..36af6d2
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  fsize.c: BSD dependant file and block sizing routines
+ * 
+ *  Known contributors to this file:
+ *     Dave Pare, 1986
+ *     Doug Hay, 1998
+ *     Steve McClure, 1998
+ */
+
+#include <config.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include "prototypes.h"
+
+/*
+ * return the size of the file in bytes.
+ */
+int
+fsize(int fd)
+{
+    struct stat statb;
+
+    if (fstat(fd, &statb) < 0)
+       return -1;
+    return statb.st_size;
+}
+
+/*
+ * Return the preferred block size for I/O on FD.
+ */
+int
+blksize(int fd)
+{
+#if defined(_WIN32)
+    return 2048;
+#else  /* !_WIN32 */
+    struct stat statb;
+
+    if (fstat(fd, &statb) < 0)
+       return 1024;
+    return statb.st_blksize;
+#endif /* !_WIN32 */
+}
+
+time_t
+fdate(int fd)
+{
+    struct stat statb;
+
+    if (fstat(fd, &statb) < 0)
+       return 0;
+    return statb.st_mtime;
+}
diff --git a/src/lib/gen/getstarg.c b/src/lib/gen/getstarg.c
deleted file mode 100644 (file)
index 62605d7..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  getstarg.c: Get a string argument (ask if not there)
- * 
- *  Known contributors to this file:
- *     
- */
-
-#include <config.h>
-
-#include <string.h>
-#include "misc.h"
-
-/*
- * Get string argument.
- * If INPUT is not empty, use it, else prompt for more input using PROMPT.
- * Copy input to BUF[1024].
- * Return BUF on success, else NULL.
- */
-char *
-getstarg(char *input, char *prompt, char *buf)
-{
-    *buf = '\0';
-    if (input == 0 || *input == 0) {
-       if (getstring(prompt, buf) == 0)
-           return 0;
-    } else {
-       strcpy(buf, input);
-    }
-    return buf;
-}
diff --git a/src/lib/gen/getstring.c b/src/lib/gen/getstring.c
deleted file mode 100644 (file)
index 8f07230..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  getstring.c: get string, printing a prompt if there is one
- * 
- *  Known contributors to this file:
- *     
- */
-
-#include <config.h>
-
-#include "prototypes.h"
-
-/*
- * Print sub-prompt PROMPT, receive a line of input into BUF[1024].
- * Return BUF on success, else NULL.
- */
-char *
-getstring(char *prompt, char *buf)
-{
-    *buf = '\0';
-    if (prmptrd(prompt, buf, 1024) < 0)
-       return NULL;
-    return buf;
-}
-
-/*
- * Print sub-prompt PROMPT, receive a line of UTF-8 input into BUF[1024].
- * Return BUF on success, else NULL.
- */
-char *
-ugetstring(char *prompt, char *buf)
-{
-    *buf = '\0';
-    if (uprmptrd(prompt, buf, 1024) < 0)
-       return NULL;
-    return buf;
-}
diff --git a/src/lib/gen/io.c b/src/lib/gen/io.c
deleted file mode 100644 (file)
index 4c42a55..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  io.c: Arrange for input and output on a file descriptor to be queued.
- * 
- *  Known contributors to this file:
- *      Doug Hay, 1998
- *      Steve McClure, 1998
- */
-
-/*
- * Arrange for input and output on a file descriptor
- * to be queued.  Provide main loop -- a mechanism for
- * blocking across all registered file descriptors, and
- * reading or writing when appropriate.
- */
-
-#include <config.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include "empio.h"
-#include "empthread.h"
-#include "ioqueue.h"
-#include "misc.h"
-#include "queue.h"
-#include "server.h"
-
-struct iop {
-    int fd;
-    struct ioqueue *input;
-    struct ioqueue *output;
-    int flags;
-    int bufsize;
-};
-
-void
-io_init(void)
-{
-}
-
-struct iop *
-io_open(int fd, int flags, int bufsize)
-{
-    struct iop *iop;
-
-    flags = flags & (IO_READ | IO_WRITE | IO_NBLOCK | IO_NEWSOCK);
-    if ((flags & (IO_READ | IO_WRITE)) == 0)
-       return NULL;
-    iop = malloc(sizeof(struct iop));
-    if (!iop)
-       return NULL;
-    iop->fd = fd;
-    iop->input = 0;
-    iop->output = 0;
-    iop->flags = 0;
-    iop->bufsize = bufsize;
-    if ((flags & IO_READ) && (flags & IO_NEWSOCK) == 0)
-       iop->input = ioq_create(bufsize);
-    if ((flags & IO_WRITE) && (flags & IO_NEWSOCK) == 0)
-       iop->output = ioq_create(bufsize);
-    if (flags & IO_NBLOCK)
-       io_noblocking(iop, 1);  /* FIXME check success */
-    iop->flags = flags;
-    return iop;
-}
-
-void
-io_close(struct iop *iop)
-{
-
-    if (iop->input != 0)
-       ioq_destroy(iop->input);
-    if (iop->output != 0)
-       ioq_destroy(iop->output);
-    (void)close(iop->fd);
-    free(iop);
-}
-
-int
-io_input(struct iop *iop, int waitforinput)
-{
-    char buf[IO_BUFSIZE];
-    int cc;
-
-    /* Not a read IOP */
-    if ((iop->flags & IO_READ) == 0)
-       return -1;
-    /* IOP is markes as in error. */
-    if (iop->flags & IO_ERROR)
-       return -1;
-    /* Wait for the file to have input. */
-    if (waitforinput) {
-       empth_select(iop->fd, EMPTH_FD_READ);
-    }
-    /* Do the actual read. */
-    cc = read(iop->fd, buf, sizeof(buf));
-    if (cc < 0) {
-       /* would block, so nothing to read. */
-       if (errno == EAGAIN || errno == EWOULDBLOCK)
-           return 0;
-
-       /* Some form of file error occurred... */
-       iop->flags |= IO_ERROR;
-       return -1;
-    }
-
-    /* We eof'd */
-    if (cc == 0) {
-       iop->flags |= IO_EOF;
-       return 0;
-    }
-
-    /* Append the input to the IOQ. */
-    ioq_append(iop->input, buf, cc);
-    return cc;
-}
-
-int
-io_inputwaiting(struct iop *iop)
-{
-    return ioq_qsize(iop->input);
-}
-
-int
-io_outputwaiting(struct iop *iop)
-{
-    return ioq_qsize(iop->output);
-}
-
-int
-io_output(struct iop *iop, int waitforoutput)
-{
-    struct iovec iov[16];
-    int cc;
-    int n;
-    int remain;
-
-    /* If there is no output waiting. */
-    if (!io_outputwaiting(iop))
-       return 0;
-
-    /* If the iop is not write enabled. */
-    if ((iop->flags & IO_WRITE) == 0)
-       return -1;
-
-    /* If the io is marked as in error... */
-    if (iop->flags & IO_ERROR)
-       return -1;
-
-    /* make the iov point to the data in the queue. */
-    /* I.E., each of the elements in the queue. */
-    /* returns the number of elements in the iov. */
-    n = ioq_makeiov(iop->output, iov, IO_BUFSIZE);
-
-    if (n <= 0) {
-       return 0;
-    }
-
-    /* wait for the file to be output ready. */
-    if (waitforoutput != IO_NOWAIT) {
-       /* This waits for the file to be ready for writing, */
-       /* and lets other threads run. */
-       empth_select(iop->fd, EMPTH_FD_WRITE);
-    }
-
-    /* Do the actual write. */
-    cc = writev(iop->fd, iov, n);
-
-    /* if it failed.... */
-    if (cc < 0) {
-       /* Hmm, it would block.  file is opened noblock, soooooo.. */
-       if (errno == EAGAIN || errno == EWOULDBLOCK) {
-           /* If there are remaining bytes, set the IO as remaining.. */
-           remain = ioq_qsize(iop->output);
-           return remain;
-       }
-       iop->flags |= IO_ERROR;
-       return -1;
-    }
-
-    /* If no bytes were written, something happened..  Like an EOF. */
-    if (cc == 0) {
-       iop->flags |= IO_EOF;
-       return 0;
-    }
-
-    /* Remove the number of written bytes from the queue. */
-    ioq_dequeue(iop->output, cc);
-
-    return cc;
-}
-
-int
-io_peek(struct iop *iop, char *buf, int nbytes)
-{
-    if ((iop->flags & IO_READ) == 0)
-       return -1;
-    return ioq_peek(iop->input, buf, nbytes);
-}
-
-int
-io_read(struct iop *iop, char *buf, int nbytes)
-{
-    int cc;
-
-    if ((iop->flags & IO_READ) == 0)
-       return -1;
-    cc = ioq_peek(iop->input, buf, nbytes);
-    if (cc > 0)
-       ioq_dequeue(iop->input, cc);
-    return cc;
-}
-
-int
-io_write(struct iop *iop, char *buf, int nbytes, int doWait)
-{
-    int len;
-
-    if ((iop->flags & IO_WRITE) == 0)
-       return -1;
-    ioq_append(iop->output, buf, nbytes);
-    len = ioq_qsize(iop->output);
-    if (len > iop->bufsize) {
-       if (doWait) {
-           io_output_all(iop);
-       } else {
-           /* only try a write every BUFSIZE characters */
-           if (((len - nbytes) % iop->bufsize) < (len % iop->bufsize))
-               io_output(iop, IO_NOWAIT);
-       }
-    }
-    return nbytes;
-}
-
-int
-io_output_all(struct iop *iop)
-{
-    int n;
-
-    /*
-     * Mustn't block a player thread while update is pending, or else
-     * a malicous player could delay the update indefinitely
-     */
-    while ((n = io_output(iop, IO_NOWAIT)) > 0 && !play_wrlock_wanted)
-       empth_select(iop->fd, EMPTH_FD_WRITE);
-
-    return n;
-}
-
-int
-io_gets(struct iop *iop, char *buf, int nbytes)
-{
-    if ((iop->flags & IO_READ) == 0)
-       return -1;
-    return ioq_gets(iop->input, buf, nbytes);
-}
-
-int
-io_puts(struct iop *iop, char *buf)
-{
-    if ((iop->flags & IO_WRITE) == 0)
-       return -1;
-    return ioq_puts(iop->output, buf);
-}
-
-int
-io_shutdown(struct iop *iop, int flags)
-{
-    flags &= (IO_READ | IO_WRITE);
-    if ((iop->flags & flags) != flags)
-       return -1;
-    if (flags & IO_READ) {
-       shutdown(iop->fd, 0);
-       ioq_drain(iop->input);
-    }
-    if (flags & IO_WRITE) {
-       shutdown(iop->fd, 1);
-       ioq_drain(iop->output);
-    }
-    return 0;
-}
-
-int
-io_noblocking(struct iop *iop, int value)
-{
-    int flags;
-
-    flags = fcntl(iop->fd, F_GETFL, 0);
-    if (flags < 0)
-       return -1;
-    if (value == 0)
-       flags &= ~O_NONBLOCK;
-    else
-       flags |= O_NONBLOCK;
-    if (fcntl(iop->fd, F_SETFL, flags) < 0)
-       return -1;
-    if (value == 0)
-       iop->flags &= ~IO_NBLOCK;
-    else
-       iop->flags |= IO_NBLOCK;
-    return 0;
-}
-
-int
-io_error(struct iop *iop)
-{
-    return iop->flags & IO_ERROR;
-}
-
-int
-io_eof(struct iop *iop)
-{
-    return iop->flags & IO_EOF;
-}
-
-int
-io_fileno(struct iop *iop)
-{
-    return iop->fd;
-}
diff --git a/src/lib/gen/log.c b/src/lib/gen/log.c
new file mode 100644 (file)
index 0000000..1a49c0d
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  log.c: Log an Empire error to a file
+ * 
+ *  Known contributors to this file:
+ *     Dave Pare, 1989
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+#include "misc.h"
+#include "optlist.h"
+#include "player.h"
+#include "prototypes.h"
+
+/* Debugging?  If yes call abort() on internal error.  */
+int debug = 0;
+
+static char logfile[32];
+static int logfd = -1;
+
+static int logopen(void);
+
+/*
+ * Points log file at PROGRAM.log
+ */
+int
+loginit(char *program)
+{
+    sprintf(logfile, "%.*s.log", (int)sizeof(logfile) - 5, program);
+    logfd = logopen();
+    return logfd;
+}
+
+static int
+logopen(void)
+{
+    int fd;
+
+    fd = open(logfile, O_WRONLY | O_CREAT | O_APPEND, S_IRWUG);
+    if (fd < 0)
+       logerror("Can't open %s (%s)", logfile, strerror(errno));
+    return fd;
+}
+
+int
+logreopen(void)
+{
+    int newfd, res;
+
+    if ((newfd = logopen()) < 0)
+       return -1;
+    res = close(logfd);
+    logfd = newfd;
+    if (res < 0)
+       logerror("Can't close %s (%s)", logfile, strerror(errno));
+    return res;
+}
+
+/*
+ * Write a line to the log file and to stderr.
+ * Messages are silently truncated after 512 characters or a newline.
+ */
+void
+logerror(char *format, ...)
+{
+    enum {
+       ctime_len = 24,         /* output of ctime() less the newline */
+       msg_space = 512         /* space for formatted message */
+    };
+    va_list list;
+    time_t now;
+    char buf[ctime_len + 1 + msg_space + 2];
+    char *msg, *p;
+
+    va_start(list, format);
+    msg = buf + ctime_len + 1;
+    vsnprintf(msg, msg_space, format, list);
+    buf[sizeof(buf)-2] = 0;
+    p = msg + strlen(msg);
+    p[0] = '\n';
+    p[1] = 0;
+    p = strchr(msg, '\n');
+    p[1] = 0;
+    fputs(msg, stderr);
+    if (logfd >= 0) {
+       time(&now);
+       memcpy(buf, ctime(&now), ctime_len);
+       buf[ctime_len] = ' ';
+       write(logfd, buf, strlen(buf));
+    }
+    va_end(list);
+}
+
+/*
+ * Log internal error MSG occured in FILE:LINE.
+ * If debugging, call abort(), else return 1.
+ */
+int
+oops(char *msg, char *file, int line)
+{
+    logerror("Oops: %s in %s:%d", msg ? msg : "bug", file, line);
+    if (debug) abort();
+    return 1;
+}
+
+/*
+ * Report out-of-memory condition and terminate the program.
+ * Use this with restraint!  Clean error recovery is preferable, but
+ * not always feasible (e.g. halfway through the update) or worthwhile
+ * (during server startup).
+ */
+void
+exit_nomem(void)
+{
+    logerror("Memory exhausted");
+    exit(1);
+}
diff --git a/src/lib/gen/mapdist.c b/src/lib/gen/mapdist.c
deleted file mode 100644 (file)
index cac702f..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  mapdist.c: Return the distance between two sectors
- * 
- *  Known contributors to this file:
- *     
- */
-
-/*
- * mapdist returns (integer) distance between two sectors.
- */
-
-#include <config.h>
-
-#include "misc.h"
-#include "optlist.h"
-#include "prototypes.h"
-
-int
-diffx(int x1, int x2)
-{
-    int dx;
-
-    dx = x1 - x2;
-    dx = dx % WORLD_X;
-    if (dx > WORLD_X / 2)
-       dx = dx - WORLD_X;
-    if (dx < -WORLD_X / 2)
-       dx = dx + WORLD_X;
-    return dx;
-}
-
-int
-diffy(int y1, int y2)
-{
-    int dy;
-
-    dy = y1 - y2;
-    dy = dy % WORLD_Y;
-    if (dy > WORLD_Y / 2)
-       dy = dy - WORLD_Y;
-    if (dy < -WORLD_Y / 2)
-       dy = dy + WORLD_Y;
-    return dy;
-}
-
-int
-deltax(int x1, int x2)
-{
-    int dx;
-
-    dx = abs(x1 - x2);
-    dx = dx % WORLD_X;
-    if (dx > WORLD_X / 2)
-       dx = WORLD_X - dx;
-    return dx;
-}
-
-int
-deltay(int y1, int y2)
-{
-    int dy;
-
-    dy = abs(y1 - y2);
-    dy = dy % WORLD_Y;
-    if (dy > WORLD_Y / 2)
-       dy = WORLD_Y - dy;
-    return dy;
-}
-
-int
-mapdist(int x1, int y1, int x2, int y2)
-{
-    int dx, dy;
-
-    x1 = x1 % WORLD_X;
-    y1 = y1 % WORLD_Y;
-    x2 = x2 % WORLD_X;
-    y2 = y2 % WORLD_Y;
-    dx = deltax(x1, x2);
-    dy = deltay(y1, y2);
-    if (dx > dy)
-       return (dx - dy) / 2 + dy;
-    return dy;
-}
diff --git a/src/lib/gen/onearg.c b/src/lib/gen/onearg.c
deleted file mode 100644 (file)
index 79c8e46..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  onearg.c: Get one argument, or ask if not there
- * 
- *  Known contributors to this file:
- *     
- */
-
-#include <config.h>
-
-#include "prototypes.h"
-
-int
-onearg(char *arg, char *prompt)
-{
-    int n;
-    char buf[1024];
-
-    if (arg == 0 || *arg == 0) {
-       if ((arg = getstring(prompt, buf)) == 0)
-           return -1;
-    }
-    n = atoi(arg);
-    if (n < 0)
-       return -1;
-    return n;
-}
diff --git a/src/lib/subs/bridgefall.c b/src/lib/subs/bridgefall.c
new file mode 100644 (file)
index 0000000..c11529d
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  bridgefall.c: Knock a bridge down
+ * 
+ *  Known contributors to this file:
+ *     Steve McClure, 1998
+ */
+
+#include <config.h>
+
+#include "file.h"
+#include "land.h"
+#include "lost.h"
+#include "misc.h"
+#include "nat.h"
+#include "nsc.h"
+#include "nuke.h"
+#include "optlist.h"
+#include "path.h"
+#include "plague.h"
+#include "plane.h"
+#include "prototypes.h"
+#include "sect.h"
+#include "xy.h"
+
+void
+bridgefall(struct sctstr *sp, struct emp_qelem *list)
+{
+    int i;
+    int j;
+    struct sctstr sect;
+    struct sctstr bh_sect;
+    int nx;
+    int ny;
+    int nnx;
+    int nny;
+
+    for (i = 1; i <= 6; i++) {
+       nx = sp->sct_x + diroff[i][0];
+       ny = sp->sct_y + diroff[i][1];
+       getsect(nx, ny, &sect);
+       if (sect.sct_type != SCT_BSPAN)
+           continue;
+       for (j = 1; j <= 6; j++) {
+           nnx = nx + diroff[j][0];
+           nny = ny + diroff[j][1];
+           if (nnx == sp->sct_x && nny == sp->sct_y)
+               continue;
+           getsect(nnx, nny, &bh_sect);
+           if (bh_sect.sct_type == SCT_BHEAD &&
+               bh_sect.sct_newtype == SCT_BHEAD)
+               break;
+           if (bh_sect.sct_type == SCT_BTOWER)
+               break;
+           /* With EASY_BRIDGES, it just has to be next to any
+              land */
+           if (opt_EASY_BRIDGES) {
+               if (bh_sect.sct_type != SCT_WATER &&
+                   bh_sect.sct_type != SCT_BSPAN)
+                   break;
+           }
+       }
+       if (j > 6) {
+           knockdown(&sect, list);
+           putsect(&sect);
+       }
+    }
+}
+
+/* Knock down a bridge span.  Note that this does NOT write the
+ * sector out to the database, it's up to the caller to do that. */
+void
+knockdown(struct sctstr *sp, struct emp_qelem *list)
+{
+    struct lndstr land;
+    struct plnstr plane;
+    struct nukstr nuke;
+    struct nstr_item ni;
+    struct natstr *np;
+
+    mpr(sp->sct_own,
+       "Crumble... SCREEEECH!  Splash! Bridge%s falls at %s!\n",
+       sp->sct_type == SCT_BTOWER ? " tower" : "",
+       xyas(sp->sct_x, sp->sct_y, sp->sct_own));
+    sp->sct_type = SCT_WATER;
+    sp->sct_newtype = SCT_WATER;
+    makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y);
+    sp->sct_own = 0;
+    sp->sct_oldown = 0;
+    sp->sct_mobil = 0;
+    sp->sct_effic = 0;
+
+    /* Sink all the units */
+    snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y);
+    while (nxtitem(&ni, &land)) {
+       if (land.lnd_own == 0)
+           continue;
+       if (land.lnd_ship >= 0)
+           continue;
+       np = getnatp(land.lnd_own);
+       if (np->nat_flags & NF_BEEP)
+           mpr(land.lnd_own, "\07");
+       mpr(land.lnd_own, "     AARGH! %s tumbles to its doom!\n",
+           prland(&land));
+       land.lnd_effic = 0;
+       putland(land.lnd_uid, &land);
+    }
+    /* Sink all the planes */
+    snxtitem_xy(&ni, EF_PLANE, sp->sct_x, sp->sct_y);
+    while (nxtitem(&ni, &plane)) {
+       if (plane.pln_own == 0)
+           continue;
+       if (plane.pln_flags & PLN_LAUNCHED)
+           continue;
+       if (plane.pln_ship >= 0)
+           continue;
+       /* Is this plane flying in this list? */
+       if (ac_isflying(&plane, list))
+           continue;
+       np = getnatp(plane.pln_own);
+       if (np->nat_flags & NF_BEEP)
+           mpr(plane.pln_own, "\07");
+       mpr(plane.pln_own, "     AARGH! %s tumbles to its doom!\n",
+           prplane(&plane));
+       plane.pln_effic = 0;
+       putplane(plane.pln_uid, &plane);
+    }
+    /* Sink all the nukes */
+    snxtitem_xy(&ni, EF_NUKE, sp->sct_x, sp->sct_y);
+    while (nxtitem(&ni, &nuke)) {
+       if (nuke.nuk_own == 0)
+           continue;
+       if (nuke.nuk_plane >= 0)
+           continue;
+       np = getnatp(nuke.nuk_own);
+       if (np->nat_flags & NF_BEEP)
+           mpr(nuke.nuk_own, "\07");
+       mpr(nuke.nuk_own, "     %s sinks to the bottom of the sea!\n",
+           prnuke(&nuke));
+       nuke.nuk_effic = 0;
+       putnuke(nuke.nuk_uid, &nuke);
+    }
+    memset(sp->sct_item, 0, sizeof(sp->sct_item));
+    memset(sp->sct_del, 0, sizeof(sp->sct_del));
+    memset(sp->sct_dist, 0, sizeof(sp->sct_dist));
+    sp->sct_pstage = PLG_HEALTHY;
+    sp->sct_ptime = 0;
+    sp->sct_che = 0;
+    sp->sct_che_target = 0;
+}
diff --git a/src/lib/subs/check.c b/src/lib/subs/check.c
new file mode 100644 (file)
index 0000000..d8b3150
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  check.c: Check a sector, plane, land unit, ship or nuke
+ * 
+ *  Known contributors to this file:
+ *     Steve McClure, 1998
+ */
+
+#include <config.h>
+
+#include "commodity.h"
+#include "file.h"
+#include "land.h"
+#include "loan.h"
+#include "misc.h"
+#include "nat.h"
+#include "nsc.h"
+#include "nuke.h"
+#include "plane.h"
+#include "player.h"
+#include "prototypes.h"
+#include "sect.h"
+#include "ship.h"
+#include "trade.h"
+#include "xy.h"
+
+/* Note that timestamps make things tricky.  And, we don't
+ * really care about the timestamp, we just care about the rest
+ * of the structure.  So, we make a copy, and zero the timestamps
+ * in both copies, and then compare. */
+
+int
+check_sect_ok(struct sctstr *sectp)
+{
+    struct sctstr chksect;
+    struct sctstr tsect;
+
+    getsect(sectp->sct_x, sectp->sct_y, &chksect);
+    memcpy(&tsect, sectp, sizeof(struct sctstr));
+    tsect.sct_timestamp = chksect.sct_timestamp = 0;
+    if (memcmp(&tsect, &chksect, sizeof(struct sctstr))) {
+       pr("Sector %s has changed!\n",
+          xyas(sectp->sct_x, sectp->sct_y, player->cnum));
+       return 0;
+    }
+    return 1;
+}
+
+int
+check_ship_ok(struct shpstr *shipp)
+{
+    struct shpstr chkship;
+    struct shpstr tship;
+
+    getship(shipp->shp_uid, &chkship);
+    memcpy(&tship, shipp, sizeof(struct shpstr));
+    tship.shp_timestamp = chkship.shp_timestamp = 0;
+    if (memcmp(&tship, &chkship, sizeof(struct shpstr))) {
+       pr("Ship #%d has changed!\n", shipp->shp_uid);
+       return 0;
+    }
+    return 1;
+}
+
+int
+check_plane_ok(struct plnstr *planep)
+{
+    struct plnstr chkplane;
+    struct plnstr tplane;
+
+    getplane(planep->pln_uid, &chkplane);
+    memcpy(&tplane, planep, sizeof(struct plnstr));
+    tplane.pln_timestamp = chkplane.pln_timestamp = 0;
+    if (memcmp(&tplane, &chkplane, sizeof(struct plnstr))) {
+       pr("Plane #%d has changed!\n", planep->pln_uid);
+       return 0;
+    }
+    return 1;
+}
+
+int
+check_land_ok(struct lndstr *landp)
+{
+    struct lndstr chkland;
+    struct lndstr tland;
+
+    getland(landp->lnd_uid, &chkland);
+    memcpy(&tland, landp, sizeof(struct lndstr));
+    tland.lnd_timestamp = chkland.lnd_timestamp = 0;
+    if (memcmp(&tland, &chkland, sizeof(struct lndstr))) {
+       pr("Land unit #%d has changed!\n", landp->lnd_uid);
+       return 0;
+    }
+    return 1;
+}
+
+int
+check_nuke_ok(struct nukstr *nukep)
+{
+    struct nukstr chknuke;
+    struct nukstr tnuke;
+
+    getnuke(nukep->nuk_uid, &chknuke);
+    memcpy(&tnuke, nukep, sizeof(struct nukstr));
+    tnuke.nuk_timestamp = chknuke.nuk_timestamp = 0;
+    if (memcmp(&tnuke, &chknuke, sizeof(struct nukstr))) {
+       pr("Nuke %d has changed!\n", nukep->nuk_uid);
+       return 0;
+    }
+    return 1;
+}
+
+int
+check_loan_ok(struct lonstr *loanp)
+{
+    struct lonstr chkloan;
+
+    getloan(loanp->l_uid, &chkloan);
+    if (memcmp(loanp, &chkloan, sizeof(struct lonstr))) {
+       pr("Loan %d has changed!\n", loanp->l_uid);
+       return 0;
+    }
+    return 1;
+}
+
+int
+check_comm_ok(struct comstr *commp)
+{
+    struct comstr chkcomm;
+
+    getcomm(commp->com_uid, &chkcomm);
+    if (memcmp(commp, &chkcomm, sizeof(struct comstr))) {
+       pr("Commodity %d has changed!\n", commp->com_uid);
+       return 0;
+    }
+    return 1;
+}
+
+int
+check_trade_ok(struct trdstr *tp)
+{
+    struct trdstr chktrade;
+
+    gettrade(tp->trd_uid, &chktrade);
+    if (memcmp(tp, &chktrade, sizeof(struct trdstr))) {
+       pr("Trade lot #%d has changed!\n", tp->trd_uid);
+       return 0;
+    }
+    return 1;
+}
diff --git a/src/lib/subs/cnumb.c b/src/lib/subs/cnumb.c
deleted file mode 100644 (file)
index 26a48b1..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  ---
- *
- *  See files README, COPYING and CREDITS in the root of the source
- *  tree for related information and legal notices.  It is expected
- *  that future projects/authors will amend these files as needed.
- *
- *  ---
- *
- *  cnumb.c: Return country number give country name
- * 
- *  Known contributors to this file:
- *     
- */
-
-#include <config.h>
-
-#include "file.h"
-#include "match.h"
-#include "nat.h"
-#include "prototypes.h"
-
-/*
- * Search for a country matching CNTRY, return its number.
- * Return M_NOTFOUND if no such country exists, M_NOTUNIQUE if there
- * are several.
- */
-int
-cnumb(char *cntry)
-{
-    char *ncp;
-    char *cp;
-    struct natstr *natp;
-    int res;
-    natid cn;
-
-    res = M_NOTFOUND;
-    for (cn = 0; cn < MAXNOC; cn++) {
-       if ((natp = getnatp(cn)) == 0)
-           break;
-       if (natp->nat_stat == STAT_UNUSED)
-           continue;
-       ncp = natp->nat_cnam;
-       for (cp = cntry; *cp == *ncp; cp++, ncp++) {
-           if (*cp == 0)
-               return cn;      /* exact match */
-       }
-       if (*cp == 0) {
-           /* is a prefix */
-           if (res >= 0)
-               return M_NOTUNIQUE;
-           res = cn;
-       }
-    }
-    return res;
-}
diff --git a/src/lib/subs/damage.c b/src/lib/subs/damage.c
new file mode 100644 (file)
index 0000000..11684fb
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  damage.c: Damage stuff.
+ * 
+ *  Known contributors to this file:
+ *     Dave Pare, 1989
+ *     Steve McClure, 1997
+ */
+
+#include <config.h>
+
+#include "damage.h"
+#include "land.h"
+#include "misc.h"
+#include "nsc.h"
+#include "nuke.h"
+#include "optlist.h"
+#include "plane.h"
+#include "prototypes.h"
+#include "sect.h"
+#include "ship.h"
+
+void
+item_damage(int pct, short *item)
+{
+    int lose;
+    i_type i;
+
+    for (i = I_NONE + 1; i <= I_MAX; ++i) {
+       if (opt_SUPER_BARS && i == I_BAR)
+           continue;
+       lose = roundavg((double)item[i] * pct * 0.01);
+       if (i == I_CIVIL || i == I_MILIT || i == I_UW)
+           lose = ldround(people_damage * lose, 1);
+       item[i] = item[i] >= lose ? item[i] - lose : 0;
+    }
+}
+
+void
+ship_damage(struct shpstr *sp, int dam)
+{
+    if (dam <= 0)
+       return;
+    if (dam > 100)
+       dam = 100;
+
+    mpr(sp->shp_own, "\t%s takes %d\n", prship(sp), dam);
+
+    sp->shp_effic = damage((int)sp->shp_effic, dam);
+    if (sp->shp_mobil > 0)
+       sp->shp_mobil = damage((int)sp->shp_mobil, dam);
+    if (opt_FUEL && sp->shp_fuel)
+       sp->shp_fuel = damage((int)sp->shp_fuel, dam);
+    item_damage(dam, sp->shp_item);
+}
+
+void
+shipdamage(struct shpstr *sp, int dam)
+{
+    ship_damage(sp, (int)(dam / (1.0 + sp->shp_armor / 100.0)));
+}
+
+void
+land_damage(struct lndstr *lp, int dam)
+{
+    if (dam <= 0)
+       return;
+    if (dam > 100)
+       dam = 100;
+
+    mpr(lp->lnd_own, "\t%s takes %d\n", prland(lp), dam);
+    if (lchr[(int)lp->lnd_type].l_flags & L_SPY) {
+       /* Spies die! */
+       lp->lnd_effic = 0;
+    } else {
+       lp->lnd_effic = damage((int)lp->lnd_effic, dam);
+       if (lp->lnd_mobil > 0)
+           lp->lnd_mobil = damage((int)lp->lnd_mobil, dam);
+       if (opt_FUEL && lp->lnd_fuel)
+           lp->lnd_fuel = damage((int)lp->lnd_fuel, dam);
+       item_damage(dam, lp->lnd_item);
+    }
+}
+
+void
+landdamage(struct lndstr *lp, int dam)
+{
+    double damage_factor, m;
+
+    m = land_mob_max;
+
+    /* fortification reduces damage */
+    damage_factor = m / (m + lp->lnd_harden);
+
+    /* vulnerable units take more damage */
+    damage_factor *= lp->lnd_vul / 100.0;
+
+    land_damage(lp, ldround(damage_factor * dam, 1));
+}
+
+void
+planedamage(struct plnstr *pp, int dam)
+{
+    if (dam <= 0)
+       return;
+    if (dam > 100)
+       dam = 100;
+
+    mpr(pp->pln_own, "\t%s takes %d\n", prplane(pp), dam);
+    pp->pln_effic = damage((int)pp->pln_effic, dam);
+    if (pp->pln_mobil > 0)
+       pp->pln_mobil = damage((int)pp->pln_mobil, dam);
+}
+
+/*
+ * nukedamage() actually just calculates damage
+ * rather than inflicting it.
+ */
+int
+nukedamage(struct nchrstr *ncp, int range, int airburst)
+{
+    int dam;
+    int rad;
+
+    rad = ncp->n_blast;
+    if (airburst)
+       rad = (int)(rad * 1.5);
+    if (rad < range)
+       return 0;
+    if (airburst) {
+       /* larger area, less center damage */
+       dam = (int)((ncp->n_dam * 0.75) - (range * 20));
+    } else {
+       /* smaller area, more center damage */
+       dam = (int)(ncp->n_dam / (range + 1.0));
+    }
+    if (dam < 5)
+       dam = 0;
+    return dam;
+}
+
+int
+damage(int amt, int pct)
+{
+    int tmp;
+    int lost;
+
+    if (amt <= 0)
+       return 0;
+    tmp = amt * pct;
+    lost = tmp / 100;
+    if (random() % 100 < tmp % 100)
+       lost++;
+    return amt - lost;
+}
+
+/* asymptotic damage to commodities, efficiency, and sectors */
+int
+effdamage(int amt, int dam)
+{
+    return damage(amt, PERCENT_DAMAGE(dam));
+}
+
+int
+commdamage(int amt, int dam, i_type vtype)
+{
+    int lost;
+
+    if (vtype == I_BAR && opt_SUPER_BARS)
+       return amt;
+
+    lost = amt - effdamage(amt, dam);
+
+    if (vtype == I_MILIT || vtype == I_CIVIL || vtype == I_UW)
+       lost = ldround(people_damage * lost, 1);
+    return amt - lost;
+}
diff --git a/src/lib/subs/empobj.c b/src/lib/subs/empobj.c
new file mode 100644 (file)
index 0000000..35a18d0
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  empobj.c: Common functions on struct empobj and
+ *            union empobj_storage
+ * 
+ *  Known contributors to this file:
+ *     Ron Koenderink, 2006
+ *     Markus Armbruster, 2006
+ */
+
+#include <config.h>
+
+#include "empobj.h"
+#include "file.h"
+#include "optlist.h"
+#include "prototypes.h"
+
+char *
+obj_nameof(struct empobj *gp)
+{
+    switch (gp->ef_type) {
+    case EF_SHIP:
+       return prship((struct shpstr *)gp);
+    case EF_PLANE:
+       return prplane((struct plnstr *)gp);
+    case EF_LAND:
+       return prland((struct lndstr *)gp);
+    case EF_NUKE:
+       return prnuke((struct nukstr *)gp);
+    }
+    CANT_REACH();
+    return "The Beast #666";
+}
+
+struct empobj *
+get_empobjp(int type, int id)
+{
+    if (CANT_HAPPEN(type == EF_SECTOR || type == EF_BAD))
+       return NULL;
+    return ef_ptr(type, id);
+}
+
+int
+put_empobj(struct empobj *gp)
+{
+    switch (gp->ef_type)
+    {
+    case EF_SECTOR:
+        return ef_write(gp->ef_type, sctoff(gp->x, gp->y), gp);
+    case EF_NATION:
+    case EF_BMAP:
+    case EF_MAP:
+       return ef_write(gp->ef_type, gp->own, gp);
+    default:
+       return ef_write(gp->ef_type, gp->uid, gp);
+    }
+}
+
+struct empobj_chr *
+get_empobj_chr(struct empobj *gp)
+{
+    switch (gp->ef_type) {
+    case EF_LAND:
+       return (struct empobj_chr *)&lchr[(int)gp->type];
+    case EF_SHIP:
+       return (struct empobj_chr *)&mchr[(int)gp->type];
+    case EF_PLANE:
+       return (struct empobj_chr *)&plchr[(int)gp->type];
+    case EF_NUKE:
+       return (struct empobj_chr *)&nchr[(int)gp->type];
+    case EF_SECTOR:
+       return (struct empobj_chr *)&dchr[(int)gp->type];
+    }
+    CANT_REACH();
+    return NULL;
+}
+
+char *
+emp_obj_chr_name(struct empobj *gp)
+{
+    switch (gp->ef_type) {
+    case EF_LAND:
+       return lchr[(int)gp->type].l_name;
+    case EF_SHIP:
+       return mchr[(int)gp->type].m_name;
+    case EF_PLANE:
+       return plchr[(int)gp->type].pl_name;
+    case EF_NUKE:
+       return nchr[(int)gp->type].n_name;
+    case EF_SECTOR:
+       return dchr[(int)gp->type].d_name;
+    }
+    CANT_REACH();
+    return NULL;
+}
+
+int
+get_empobj_mob_max(int type)
+{
+    switch (type) {
+    case EF_SHIP:
+       return ship_mob_max;
+    case EF_LAND:
+       return land_mob_max;
+    case EF_PLANE:
+       return plane_mob_max;
+    case EF_SECTOR:
+       return sect_mob_max;
+    }
+    CANT_REACH();
+    return -1;
+}
diff --git a/src/lib/subs/getstarg.c b/src/lib/subs/getstarg.c
new file mode 100644 (file)
index 0000000..62605d7
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  getstarg.c: Get a string argument (ask if not there)
+ * 
+ *  Known contributors to this file:
+ *     
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include "misc.h"
+
+/*
+ * Get string argument.
+ * If INPUT is not empty, use it, else prompt for more input using PROMPT.
+ * Copy input to BUF[1024].
+ * Return BUF on success, else NULL.
+ */
+char *
+getstarg(char *input, char *prompt, char *buf)
+{
+    *buf = '\0';
+    if (input == 0 || *input == 0) {
+       if (getstring(prompt, buf) == 0)
+           return 0;
+    } else {
+       strcpy(buf, input);
+    }
+    return buf;
+}
diff --git a/src/lib/subs/getstring.c b/src/lib/subs/getstring.c
new file mode 100644 (file)
index 0000000..8f07230
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  getstring.c: get string, printing a prompt if there is one
+ * 
+ *  Known contributors to this file:
+ *     
+ */
+
+#include <config.h>
+
+#include "prototypes.h"
+
+/*
+ * Print sub-prompt PROMPT, receive a line of input into BUF[1024].
+ * Return BUF on success, else NULL.
+ */
+char *
+getstring(char *prompt, char *buf)
+{
+    *buf = '\0';
+    if (prmptrd(prompt, buf, 1024) < 0)
+       return NULL;
+    return buf;
+}
+
+/*
+ * Print sub-prompt PROMPT, receive a line of UTF-8 input into BUF[1024].
+ * Return BUF on success, else NULL.
+ */
+char *
+ugetstring(char *prompt, char *buf)
+{
+    *buf = '\0';
+    if (uprmptrd(prompt, buf, 1024) < 0)
+       return NULL;
+    return buf;
+}
diff --git a/src/lib/subs/journal.c b/src/lib/subs/journal.c
new file mode 100644 (file)
index 0000000..ed111a2
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
+ *  related information and legal notices. It is expected that any future
+ *  projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  journal.c: Log a journal of events to a file
+ * 
+ *  Known contributors to this file:
+ *     Markus Armbruster, 2004-2007
+ */
+
+/*
+ * Journal file format: each line logs an event, and looks like this:
+ *
+ *     TIME THREAD EVENT DATA
+ *
+ * Events and their data are:
+ *
+ *     startup
+ *     shutdown
+ *     login CNUM HOSTADDR USER
+ *     logout CNUM
+ *     input INPUT
+ *     update ETU
+ */
+
+#include <config.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <time.h>
+#include "misc.h"
+#include "empthread.h"
+#include "journal.h"
+#include "optlist.h"
+#include "player.h"
+#include "prototypes.h"
+
+static char journal_fname[] = "journal.log";
+static FILE *journal;
+
+static FILE *
+journal_open(void)
+{
+    return fopen(journal_fname, "a+");
+}
+
+static void
+journal_entry(char *fmt, ...)
+{
+    static char buf[1024];
+    va_list ap;
+    time_t now;
+    unsigned char *p;
+
+    if (journal) {
+       time(&now);
+       fprintf(journal, "%.24s %p ", ctime(&now), empth_self());
+       
+       va_start(ap, fmt);
+       vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
+       va_end(ap);
+
+       for (p = (unsigned char *)buf; *p; p++) {
+           if (isprint(*p))
+               putc(*p, journal);
+           else
+               fprintf(journal, "\\%03o", *p);
+       }
+       fputs("\n", journal);
+       if (debug)
+           fflush(journal);
+       if (ferror(journal)) {
+           logerror("Error writing journal (%s)", strerror(errno));
+           clearerr(journal);
+       }
+    }
+}
+
+int
+journal_startup(void)
+{
+    if (!keep_journal)
+       return 0;
+    journal = journal_open();
+    if (!journal) {
+       logerror("Can't open %s (%s)", journal_fname, strerror(errno));
+       return -1;
+    }
+    journal_entry("startup");
+    return 0;
+}
+
+void
+journal_shutdown(void)
+{
+    journal_entry("shutdown");
+    if (journal) {
+       fclose(journal);
+       journal = NULL;
+    }
+}
+
+int
+journal_reopen(void)
+{
+    FILE *j;
+
+    if (!keep_journal)
+       return 0;
+    j = journal_open();
+    if (!j) {
+       logerror("Can't open %s (%s)", journal_fname, strerror(errno));
+       return -1;
+    }
+    if (journal)
+       fclose(journal);
+    journal = j;
+    return 0;
+}
+
+void
+journal_login(void)
+{
+    journal_entry("login %d %s %s",
+                 player->cnum, player->hostaddr, player->userid);
+}
+
+void
+journal_logout(void)
+{
+    journal_entry("logout %d", player->cnum);
+}
+
+void
+journal_input(char *input)
+{
+    journal_entry("input %s", input);
+}
+
+void
+journal_update(int etu)
+{
+    journal_entry("update %d", etu);
+}
diff --git a/src/lib/subs/maps.c b/src/lib/subs/maps.c
new file mode 100644 (file)
index 0000000..b60d5d6
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  maps.c: Map routines
+ * 
+ *  Known contributors to this file:
+ *     Ken Stevens, 1995
+ *     Steve McClure, 1998
+ *     Ron Koenderink, 2006
+ */
+
+#include <config.h>
+
+#include <ctype.h>
+#include "com.h"
+#include "empobj.h"
+#include "file.h"
+#include "land.h"
+#include "map.h"
+#include "misc.h"
+#include "nat.h"
+#include "nsc.h"
+#include "nuke.h"
+#include "optlist.h"
+#include "plane.h"
+#include "player.h"
+#include "prototypes.h"
+#include "sect.h"
+#include "ship.h"
+#include "xy.h"
+
+static int bmnxtsct(struct nstr_sect *);
+static char map_char(unsigned char type, natid own, int owner_or_god);
+
+int
+do_map(int bmap, int unit_type, char *arg, char *map_flags_arg)
+{
+    struct nstr_sect ns;
+    char origin = '\0';
+    char *b;
+    int map_flags = 0;
+
+    if (!snxtsct(&ns, arg)) {
+       if (unit_map(unit_type, atoi(arg), &ns, &origin))
+           return RET_FAIL;
+    }
+    for (b = map_flags_arg; b && *b; b++) {
+       switch (*b) {
+       case 's':
+       case 'S':
+           map_flags |= MAP_SHIP;
+           break;
+       case 'l':
+       case 'L':
+           map_flags |= MAP_LAND;
+           break;
+       case 'p':
+       case 'P':
+           map_flags |= MAP_PLANE;
+           break;
+       case 'n':
+       case 'N':
+           map_flags |= MAP_NUKE;
+           break;
+       case 'h':
+       case 'H':
+           map_flags |= MAP_HIGH;
+           break;
+       case '*':
+           map_flags |= MAP_ALL;
+           break;
+       case 't':
+           if (bmap != 'b')
+               goto bad_flag;
+           bmap = 't';
+           *(b + 1) = 0;
+           break;
+       case 'r':
+           if (bmap != 'b')
+               goto bad_flag;
+           bmap = 'r';
+           *(b + 1) = 0;
+           break;
+       default:
+       bad_flag:
+           pr("Bad flag %c!\n", *b);
+           break;
+       }
+    }
+    return draw_map(bmap, origin, map_flags, &ns);
+}
+
+int
+draw_map(int bmap, char origin, int map_flags, struct nstr_sect *nsp)
+{
+    struct natstr *np;
+    struct range range;
+    struct nstr_item ni;
+    union empobj_storage unit;
+    coord x, y;
+    int i;
+    /* Note this is not re-entrant anyway, so we keep the buffers
+       around */
+    static unsigned char *bitmap = NULL;
+    static char *wmapbuf = NULL;
+    static char **wmap = NULL;
+    static int ef_mappable[] = { EF_PLANE, EF_SHIP, EF_LAND, EF_NUKE, EF_BAD };
+    static int ef_unit_map[] = { MAP_PLANE, MAP_SHIP, MAP_LAND, MAP_NUKE };
+    char *name;
+
+    if (!wmapbuf)
+       wmapbuf = malloc(WORLD_Y * MAPWIDTH(1));
+    if (!wmap) {
+       wmap = malloc(WORLD_Y * sizeof(char *));
+       if (wmap && wmapbuf) {
+           for (i = 0; i < WORLD_Y; i++)
+               wmap[i] = &wmapbuf[MAPWIDTH(1) * i];
+       } else if (wmap) {
+           free(wmap);
+           wmap = NULL;
+       }
+    }
+    if (!bitmap)
+       bitmap = malloc((WORLD_X * WORLD_Y) / 8);
+    if (!wmapbuf || !wmap || !bitmap) {
+       pr("Memory error, tell the deity.\n");
+       logerror("malloc failed in draw_map\n");
+       return RET_FAIL;
+    }
+
+    if (bmap == 'r') {
+       if (!confirm("Are you sure you want to revert your bmap? "))
+           return RET_OK;
+    }
+    if (!(player->command->c_flags & C_MOD)) {
+       logerror("%s command needs C_MOD flag set",
+                player->command->c_form);
+       player->command->c_flags |= C_MOD;
+    }
+    np = getnatp(player->cnum);
+    /* zap any conditionals */
+    nsp->ncond = 0;
+    xyrelrange(np, &nsp->range, &range);
+    border(&range, "     ", "");
+    blankfill(wmapbuf, &nsp->range, 1);
+    if (bmap) {
+       int c;
+       switch (bmap) {
+       default:
+           CANT_REACH();
+           bmap = 'b';
+           /* fall through */
+       case 'b':
+           while (bmnxtsct(nsp) && !player->aborted) {
+               if (0 != (c = player->bmap[sctoff(nsp->x, nsp->y)]))
+                   wmap[nsp->dy][nsp->dx] = c;
+           }
+           break;
+       case 't':
+           while (bmnxtsct(nsp) && !player->aborted) {
+               if (0 != (c = player->map[sctoff(nsp->x, nsp->y)]))
+                   wmap[nsp->dy][nsp->dx] = c;
+           }
+           break;
+       case 'r':
+           while (bmnxtsct(nsp) && !player->aborted) {
+               player->bmap[sctoff(nsp->x, nsp->y)] =
+                   player->map[sctoff(nsp->x, nsp->y)];
+               if (0 != (c = player->bmap[sctoff(nsp->x, nsp->y)]))
+                   wmap[nsp->dy][nsp->dx] = c;
+           }
+           ef_write(EF_BMAP, player->cnum, player->bmap);
+           break;
+       case 'n':
+           {
+               struct sctstr sect;
+
+               if (!player->god) {
+                   memset(bitmap, 0, (WORLD_X * WORLD_Y) / 8);
+                   bitinit2(nsp, bitmap, player->cnum);
+               }
+               while (nxtsct(nsp, &sect) && !player->aborted) {
+                   if (!player->god && !emp_getbit(nsp->x, nsp->y, bitmap))
+                       continue;
+                   wmap[nsp->dy][nsp->dx]
+                       = map_char(sect.sct_newtype, sect.sct_own,
+                                  player->owner);
+               }
+               break;
+           }
+       }
+    } else {
+       struct sctstr sect;
+       char mapch;
+       int changed = 0;
+
+       if (!player->god) {
+           memset(bitmap, 0, (WORLD_X * WORLD_Y) / 8);
+           bitinit2(nsp, bitmap, player->cnum);
+       }
+       while (nxtsct(nsp, &sect) && !player->aborted) {
+           if (!player->god && !emp_getbit(nsp->x, nsp->y, bitmap))
+               continue;
+           mapch = map_char(sect.sct_type, sect.sct_own, player->owner);
+           wmap[nsp->dy][nsp->dx] = mapch;
+           changed |= map_set(player->cnum, nsp->x, nsp->y, mapch, 0);
+       }
+       if (changed)
+           writemap(player->cnum);
+    }
+    if (player->aborted)
+       return RET_OK;
+
+    i = 0;
+    while (ef_mappable[i] != EF_BAD) {
+       if (map_flags & ef_unit_map[i]) {
+           snxtitem_all(&ni, ef_mappable[i]);
+           while (nxtitem(&ni, &unit)) {
+               if (unit.gen.own == 0)
+                   continue;
+               if (unit.gen.own != player->cnum && !player->god)
+                   continue;
+               if (!xyinrange(unit.gen.x, unit.gen.y, &nsp->range))
+                   continue;
+
+               x = xnorm(unit.gen.x - nsp->range.lx);
+               y = ynorm(unit.gen.y - nsp->range.ly);
+
+               if (ef_mappable[i] == EF_NUKE)
+                   wmap[y][x] = 'N';
+               else {
+                   if ((name = emp_obj_chr_name(&unit.gen)) == NULL)
+                       return RET_FAIL;
+                   wmap[y][x] = *name & ~0x20;
+               }
+           }
+       }
+       i++;
+    }
+    if (map_flags & MAP_HIGH) {
+       struct sctstr sect;
+
+       snxtsct_rewind(nsp);
+       if (!player->god) {
+           memset(bitmap, 0, (WORLD_X * WORLD_Y) / 8);
+           bitinit2(nsp, bitmap, player->cnum);
+       }
+       while (nxtsct(nsp, &sect) && !player->aborted) {
+           if (!player->god && !emp_getbit(nsp->x, nsp->y, bitmap))
+               continue;
+           if (sect.sct_own == player->cnum)
+                wmap[nsp->dy][nsp->dx] |= 0x80;
+       }
+    }
+    if (origin)
+       wmap[5][10] = origin & ~0x20;
+    for (y = nsp->range.ly, i = 0; i < nsp->range.height; y++, i++) {
+       int yval;
+
+       yval = yrel(np, y);
+       wmap[i][nsp->range.width] = '\0';
+       pr("%4d %s %-4d\n", yval, wmap[i], yval);
+       if (y >= WORLD_Y)
+           y -= WORLD_Y;
+    }
+    border(&range, "     ", "");
+    return RET_OK;
+}
+
+/*
+ * get the next sector in the range
+ */
+static int
+bmnxtsct(struct nstr_sect *np)
+{
+    while (1) {
+       np->dx++;
+       np->x++;
+       if (np->x >= WORLD_X)
+           np->x = 0;
+       if (np->dx >= np->range.width) {
+           np->dx = 0;
+           np->x = np->range.lx;
+           np->dy++;
+           if (np->dy >= np->range.height)
+               return 0;
+           np->y++;
+           if (np->y >= WORLD_Y)
+               np->y = 0;
+       }
+       if ((np->y + np->x) & 01)
+           continue;
+       if (np->type == NS_DIST) {
+           np->curdist = mapdist(np->x, np->y, np->cx, np->cy);
+           if (np->curdist > np->dist)
+               continue;
+       }
+       np->id = sctoff(np->x, np->y);
+       return 1;
+    }
+    /*NOTREACHED*/
+}
+
+/*
+ * Return character to use in maps for sector type TYPE owned by OWN.
+ * If OWNER_OR_GOD, the map is for the sector's owner or a deity.
+ */
+static char
+map_char(unsigned char type, natid own, int owner_or_god)
+{
+    if (CANT_HAPPEN(type > SCT_TYPE_MAX || !dchr[type].d_mnem))
+       return '?';
+    if (owner_or_god
+       || type == SCT_WATER || type == SCT_MOUNT || type == SCT_WASTE
+       || (!own && (type == SCT_RURAL || type == SCT_PLAINS)))
+       return dchr[type].d_mnem;
+    return '?';
+}
+
+int
+unit_map(int unit_type, int uid, struct nstr_sect *nsp, char *originp)
+{
+    struct empobj *gp;
+    struct range range;
+    char *name;
+
+    gp = get_empobjp(unit_type, uid);
+    if (!gp || (gp->own != player->cnum && !player->god) || gp->own == 0)
+       return RET_FAIL;
+
+    if (unit_type == EF_NUKE)
+       *originp = 'n';
+    else {
+       if ((name = emp_obj_chr_name(gp)) == NULL)
+           return RET_FAIL;
+       *originp = *name;
+    }
+
+    range.lx = xnorm(gp->x - 10);
+    range.hx = xnorm(gp->x + 11);
+    range.ly = ynorm(gp->y - 5);
+    range.hy = ynorm(gp->y + 6);
+    xysize_range(&range);
+    snxtsct_area(nsp, &range);
+    return RET_OK;
+}
+
+int
+display_region_map(int bmap, int unit_type, coord curx, coord cury,
+                  char *arg)
+{
+    char coordinates[80];
+    char *map_flag_arg;
+
+    if (!arg || !*arg) {
+       struct natstr *np;
+
+       np = getnatp(player->cnum);
+       sprintf(coordinates, "%d:%d,%d:%d",
+           xrel(np, curx - 10), xrel(np, curx + 11),
+           yrel(np, cury - 5), yrel(np, cury + 6));
+       arg = coordinates;
+       map_flag_arg = NULL;
+    } else {
+       map_flag_arg = strchr(arg, ' ');
+       if (map_flag_arg != NULL) {
+           *map_flag_arg++  = '\0';
+           while (isspace(*map_flag_arg)) map_flag_arg++;
+       }
+    }
+    player->condarg = NULL;
+    return do_map(bmap, unit_type, arg, map_flag_arg);
+}
+
+int
+bmaps_intersect(natid a, natid b)
+{
+    char *mapa = ef_ptr(EF_MAP, a);
+    char *mapb = ef_ptr(EF_MAP, b);
+    int i;
+
+    for (i = 0; i < WORLD_SZ(); i++)
+       if (mapa[i] && mapa[i] != ' ' && mapb[i] && mapb[i] != ' ')
+           return 1;
+    return 0;
+}
+
+/* Note that this requires that the BMAP is mapped into memory */
+
+int
+share_bmap(natid from, natid to, struct nstr_sect *ns, char des,
+          char *from_name)
+{
+    char *from_bmap = ef_ptr(EF_BMAP, from);
+    char *to_bmap = ef_ptr(EF_BMAP, to);
+    int n = 0;
+    struct sctstr sect;
+    char fromdes;
+    char todes;
+    char from_des = *from_name;
+
+    if (isalpha(from_des))
+       from_des &= ~0x20;
+
+    while (nxtsct(ns, &sect)) {
+       if (!(fromdes = from_bmap[sctoff(ns->x, ns->y)]))
+           continue;
+       todes = to_bmap[sctoff(ns->x, ns->y)];
+       if (todes &&
+           todes != '?' &&
+           todes != '.' && todes != ' ' && todes != from_des)
+           continue;
+       if (sect.sct_own == from) {
+           if (fromdes != '=' && fromdes != 'h' && fromdes != des)
+               fromdes = from_des;
+       }
+       if (todes == fromdes)
+           continue;
+       n += map_set(to, ns->x, ns->y, fromdes, 1);
+    }
+
+    if (n)
+       writebmap(to);
+    return n;
+}
index 2184646a1041bc2be2e195e7723b9fa9b75699c3..2ce084032998b58ff31c370a0a5e4d4a72cea085 100644 (file)
@@ -39,8 +39,6 @@
 #include <limits.h>
 #include "file.h"
 #include "match.h"
-#include "nat.h"
-#include "optlist.h"
 #include "player.h"
 #include "prototypes.h"
 
@@ -568,133 +566,3 @@ nstr_coerce_val(struct valstr *val, nsc_type to, char *str)
 
     return 0;
 }
-
-/*
- * Evaluate VAL.
- * If VAL is symbolic, evaluate it into a promoted value type.
- * Use coordinate system of country CNUM.
- * PTR points to a context object of the type that was used to compile
- * the value.
- * Unless WANT is NSC_NOTYPE, coerce the value to promoted value type
- * WANT.  VAL must be coercible.  That's the case if a previous
- * nstr_coerce_val(VAL, WANT, STR) succeeded.
- */
-void
-nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
-{
-    char *memb_ptr;
-    nsc_type valtype;
-    int idx;
-    struct natstr *natp;
-
-    switch (val->val_cat) {
-    default:
-       CANT_REACH();
-       /* fall through */
-    case NSC_VAL:
-       valtype = val->val_type;
-       break;
-    case NSC_OFF:
-       valtype = NSC_LONG;
-       memb_ptr = ptr;
-       memb_ptr += val->val_as.sym.off;
-       idx = val->val_as.sym.idx;
-       switch (val->val_type) {
-       case NSC_CHAR:
-           val->val_as.lng = ((signed char *)memb_ptr)[idx];
-           break;
-       case NSC_UCHAR:
-           val->val_as.lng = ((unsigned char *)memb_ptr)[idx];
-           break;
-       case NSC_SHORT:
-           val->val_as.lng = ((short *)memb_ptr)[idx];
-           break;
-       case NSC_USHORT:
-           val->val_as.lng = ((unsigned short *)memb_ptr)[idx];
-           break;
-       case NSC_INT:
-           val->val_as.lng = ((int *)memb_ptr)[idx];
-           break;
-       case NSC_LONG:
-           val->val_as.lng = ((long *)memb_ptr)[idx];
-           break;
-       case NSC_XCOORD:
-           val->val_as.lng = xrel(getnatp(cnum), ((short *)memb_ptr)[idx]);
-           break;
-       case NSC_YCOORD:
-           val->val_as.lng = yrel(getnatp(cnum), ((short *)memb_ptr)[idx]);
-           break;
-       case NSC_HIDDEN:
-           val->val_as.lng = -1;
-           if (CANT_HAPPEN(((struct natstr *)ptr)->ef_type != EF_NATION))
-               break;
-           natp = getnatp(cnum);
-           if (!opt_HIDDEN
-               || natp->nat_stat == STAT_GOD
-               || (getcontact(natp, idx) && getcontact(ptr, idx)))
-               val->val_as.lng = ((unsigned char *)memb_ptr)[idx];
-           break;
-       case NSC_FLOAT:
-           val->val_as.dbl = ((float *)memb_ptr)[idx];
-           valtype = NSC_DOUBLE;
-           break;
-       case NSC_DOUBLE:
-           val->val_as.dbl = ((double *)memb_ptr)[idx];
-           valtype = NSC_DOUBLE;
-           break;
-       case NSC_STRINGY:
-           CANT_HAPPEN(idx);
-           val->val_as.str.maxsz = val->val_as.sym.len;
-           val->val_as.str.base = (char *)memb_ptr;
-           valtype = NSC_STRING;
-           break;
-       case NSC_STRING:
-           val->val_as.str.base = ((char **)memb_ptr)[idx];
-           val->val_as.str.maxsz = INT_MAX;
-           valtype = NSC_STRING;
-           break;
-       case NSC_TIME:
-           val->val_as.lng = ((time_t *)memb_ptr)[idx];
-           break;
-       default:
-           CANT_REACH();
-           val->val_as.lng = 0;
-       }
-       val->val_cat = NSC_VAL;
-    }
-
-    if (valtype == want)
-       ;
-    else if (want == NSC_DOUBLE) {
-       if (valtype == NSC_LONG) {
-           valtype = want;
-           val->val_as.dbl = val->val_as.lng;
-       }
-    } else if (want == NSC_STRING)
-       CANT_REACH();           /* FIXME implement */
-
-    if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE)) {
-       valtype = want;
-       switch (want) {
-       case NSC_LONG: val->val_as.lng = 0; break;
-       case NSC_DOUBLE: val->val_as.dbl = 0.0; break;
-       case NSC_STRING: val->val_as.str.base = NULL; break;
-       default:
-           CANT_REACH();
-       }
-    }
-
-    val->val_type = valtype;
-}
-
-char *
-symbol_by_value(int key, struct symbol *table)
-{
-    int i;
-
-    for (i = 0; table[i].name; i++)
-       if (key == table[i].value)
-           return table[i].name;
-
-    return NULL;
-}
diff --git a/src/lib/subs/onearg.c b/src/lib/subs/onearg.c
new file mode 100644 (file)
index 0000000..79c8e46
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  onearg.c: Get one argument, or ask if not there
+ * 
+ *  Known contributors to this file:
+ *     
+ */
+
+#include <config.h>
+
+#include "prototypes.h"
+
+int
+onearg(char *arg, char *prompt)
+{
+    int n;
+    char buf[1024];
+
+    if (arg == 0 || *arg == 0) {
+       if ((arg = getstring(prompt, buf)) == 0)
+           return -1;
+    }
+    n = atoi(arg);
+    if (n < 0)
+       return -1;
+    return n;
+}
diff --git a/src/lib/subs/sectdamage.c b/src/lib/subs/sectdamage.c
new file mode 100644 (file)
index 0000000..6dcacbb
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ *  Empire - A multi-player, client/server Internet based war game.
+ *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                           Ken Stevens, Steve McClure
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *  ---
+ *
+ *  See files README, COPYING and CREDITS in the root of the source
+ *  tree for related information and legal notices.  It is expected
+ *  that future projects/authors will amend these files as needed.
+ *
+ *  ---
+ *
+ *  sectdamage.c: Damage a sector
+ * 
+ *  Known contributors to this file:
+ *     Dave Pare, 1989
+ *     Steve McClure, 1996
+ */
+
+#include <config.h>
+
+#include "combat.h"
+#include "damage.h"
+#include "file.h"
+#include "land.h"
+#include "misc.h"
+#include "nat.h"
+#include "nsc.h"
+#include "optlist.h"
+#include "plane.h"
+#include "prototypes.h"
+#include "sect.h"
+#include "ship.h"
+#include "xy.h"
+
+int
+sect_damage(struct sctstr *sp, int dam, struct emp_qelem *list)
+{
+    int eff;
+
+    if (dam <= 0)
+       return 0;
+    if (dam > 100)
+       dam = 100;
+
+    sp->sct_effic = damage(sp->sct_effic, dam);
+    sp->sct_avail = damage(sp->sct_avail, dam);
+    sp->sct_road = damage(sp->sct_road, dam);
+    sp->sct_rail = damage(sp->sct_rail, dam);
+    sp->sct_defense = damage(sp->sct_defense, dam);
+
+    eff = dam;
+
+    if (sp->sct_mobil > 0)
+       sp->sct_mobil = damage(sp->sct_mobil, dam);
+    item_damage(dam, sp->sct_item);
+    if (opt_EASY_BRIDGES == 0) {
+       if (sp->sct_effic < SCT_MINEFF && sp->sct_type == SCT_BHEAD)
+           bridgefall(sp, list);
+    } else {
+       if (sp->sct_effic < SCT_MINEFF && sp->sct_type == SCT_BSPAN)
+           knockdown(sp, list);
+    }
+    putsect(sp);
+    return eff;
+}
+
+int
+sectdamage(struct sctstr *sp, int dam, struct emp_qelem *list)
+{
+    struct nstr_item ni;
+    struct lndstr land;
+    struct plnstr plane;
+    int eff;
+
+    /* Some sectors are harder/easier to kill..   */
+    /* Average sector has a dstr of 1, so adjust  */
+    /* the damage accordingly. Makes forts a pain */
+    dam = ldround(dam / sector_strength(sp), 1);
+
+    eff = sect_damage(sp, PERCENT_DAMAGE(dam), list);
+
+    /* Damage all the land units in the sector */
+    /* Units don't take full damage */
+    dam = ldround(DPERCENT_DAMAGE(dam * unit_damage), 1);
+    if (dam <= 0)
+       return eff;
+
+    snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y);
+    while (nxtitem(&ni, &land)) {
+       if (!land.lnd_own)
+           continue;
+       landdamage(&land, dam);
+       putland(land.lnd_uid, &land);
+    }
+
+    dam = dam / 7;
+    if (dam <= 0)
+       return eff;
+    snxtitem_xy(&ni, EF_PLANE, sp->sct_x, sp->sct_y);
+    while (nxtitem(&ni, &plane)) {
+       if (!plane.pln_own)
+           continue;
+       if (plane.pln_flags & PLN_LAUNCHED)
+           continue;
+       if (plane.pln_ship >= 0)
+           continue;
+       /* Is this plane flying in this list? */
+       if (ac_isflying(&plane, list))
+           continue;
+       planedamage(&plane, dam);
+       putplane(plane.pln_uid, &plane);
+    }
+    return eff;
+}