# 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)
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
# 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
$(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))
*/
/* 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);
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);
/* 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 */
/*
* 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);
/* 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 */
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);
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 *);
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 *);
+++ /dev/null
-/*
- * 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, §);
- 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(§, list);
- putsect(§);
- }
- }
-}
-
-/* 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;
-}
+++ /dev/null
-/*
- * 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;
-}
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-/*
- * 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;
-}
--- /dev/null
+/*
+ * 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");
+}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-/*
- * 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);
-}
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-/*
- * 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, §) && !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, §) && !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, §) && !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, §)) {
- 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;
-}
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-/*
- * 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;
-}
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-/*
- * 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");
-}
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
--- /dev/null
+/*
+ * 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);
+}
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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;
-}
--- /dev/null
+/*
+ * 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, §);
+ 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(§, list);
+ putsect(§);
+ }
+ }
+}
+
+/* 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-/*
- * 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;
-}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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, §) && !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, §) && !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, §) && !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, §)) {
+ 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;
+}
#include <limits.h>
#include "file.h"
#include "match.h"
-#include "nat.h"
-#include "optlist.h"
#include "player.h"
#include "prototypes.h"
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;
-}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}