Clean up library dependencies

Move stuff to untangle the ugly cyclic dependencies between the
archives built for selected subdirectories of src/lib/:

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

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

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

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

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

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

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

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

Remaining dependencies:

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

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

Link order now: liblwp.a libcommon.a libas.a libgen.a libglobal.a
libw32.a.  The position of libw32.a is not quite right, but works
anyway.
This commit is contained in:
Markus Armbruster 2008-02-02 21:03:12 +01:00
parent 1cbb37d4fb
commit 77e95bd788
20 changed files with 235 additions and 191 deletions

View file

@ -1,175 +0,0 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* bridgefall.c: Knock a bridge down
*
* Known contributors to this file:
* Steve McClure, 1998
*/
#include <config.h>
#include "file.h"
#include "land.h"
#include "lost.h"
#include "misc.h"
#include "nat.h"
#include "nsc.h"
#include "nuke.h"
#include "optlist.h"
#include "path.h"
#include "plague.h"
#include "plane.h"
#include "prototypes.h"
#include "sect.h"
#include "xy.h"
void
bridgefall(struct sctstr *sp, struct emp_qelem *list)
{
int i;
int j;
struct sctstr sect;
struct sctstr bh_sect;
int nx;
int ny;
int nnx;
int nny;
for (i = 1; i <= 6; i++) {
nx = sp->sct_x + diroff[i][0];
ny = sp->sct_y + diroff[i][1];
getsect(nx, ny, &sect);
if (sect.sct_type != SCT_BSPAN)
continue;
for (j = 1; j <= 6; j++) {
nnx = nx + diroff[j][0];
nny = ny + diroff[j][1];
if (nnx == sp->sct_x && nny == sp->sct_y)
continue;
getsect(nnx, nny, &bh_sect);
if (bh_sect.sct_type == SCT_BHEAD &&
bh_sect.sct_newtype == SCT_BHEAD)
break;
if (bh_sect.sct_type == SCT_BTOWER)
break;
/* With EASY_BRIDGES, it just has to be next to any
land */
if (opt_EASY_BRIDGES) {
if (bh_sect.sct_type != SCT_WATER &&
bh_sect.sct_type != SCT_BSPAN)
break;
}
}
if (j > 6) {
knockdown(&sect, list);
putsect(&sect);
}
}
}
/* Knock down a bridge span. Note that this does NOT write the
* sector out to the database, it's up to the caller to do that. */
void
knockdown(struct sctstr *sp, struct emp_qelem *list)
{
struct lndstr land;
struct plnstr plane;
struct nukstr nuke;
struct nstr_item ni;
struct natstr *np;
mpr(sp->sct_own,
"Crumble... SCREEEECH! Splash! Bridge%s falls at %s!\n",
sp->sct_type == SCT_BTOWER ? " tower" : "",
xyas(sp->sct_x, sp->sct_y, sp->sct_own));
sp->sct_type = SCT_WATER;
sp->sct_newtype = SCT_WATER;
makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y);
sp->sct_own = 0;
sp->sct_oldown = 0;
sp->sct_mobil = 0;
sp->sct_effic = 0;
/* Sink all the units */
snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y);
while (nxtitem(&ni, &land)) {
if (land.lnd_own == 0)
continue;
if (land.lnd_ship >= 0)
continue;
np = getnatp(land.lnd_own);
if (np->nat_flags & NF_BEEP)
mpr(land.lnd_own, "\07");
mpr(land.lnd_own, " AARGH! %s tumbles to its doom!\n",
prland(&land));
land.lnd_effic = 0;
putland(land.lnd_uid, &land);
}
/* Sink all the planes */
snxtitem_xy(&ni, EF_PLANE, sp->sct_x, sp->sct_y);
while (nxtitem(&ni, &plane)) {
if (plane.pln_own == 0)
continue;
if (plane.pln_flags & PLN_LAUNCHED)
continue;
if (plane.pln_ship >= 0)
continue;
/* Is this plane flying in this list? */
if (ac_isflying(&plane, list))
continue;
np = getnatp(plane.pln_own);
if (np->nat_flags & NF_BEEP)
mpr(plane.pln_own, "\07");
mpr(plane.pln_own, " AARGH! %s tumbles to its doom!\n",
prplane(&plane));
plane.pln_effic = 0;
putplane(plane.pln_uid, &plane);
}
/* Sink all the nukes */
snxtitem_xy(&ni, EF_NUKE, sp->sct_x, sp->sct_y);
while (nxtitem(&ni, &nuke)) {
if (nuke.nuk_own == 0)
continue;
if (nuke.nuk_plane >= 0)
continue;
np = getnatp(nuke.nuk_own);
if (np->nat_flags & NF_BEEP)
mpr(nuke.nuk_own, "\07");
mpr(nuke.nuk_own, " %s sinks to the bottom of the sea!\n",
prnuke(&nuke));
nuke.nuk_effic = 0;
putnuke(nuke.nuk_uid, &nuke);
}
memset(sp->sct_item, 0, sizeof(sp->sct_item));
memset(sp->sct_del, 0, sizeof(sp->sct_del));
memset(sp->sct_dist, 0, sizeof(sp->sct_dist));
sp->sct_pstage = PLG_HEALTHY;
sp->sct_ptime = 0;
sp->sct_che = 0;
sp->sct_che_target = 0;
}

View file

@ -1,175 +0,0 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* check.c: Check a sector, plane, land unit, ship or nuke
*
* Known contributors to this file:
* Steve McClure, 1998
*/
#include <config.h>
#include "commodity.h"
#include "file.h"
#include "land.h"
#include "loan.h"
#include "misc.h"
#include "nat.h"
#include "nsc.h"
#include "nuke.h"
#include "plane.h"
#include "player.h"
#include "prototypes.h"
#include "sect.h"
#include "ship.h"
#include "trade.h"
#include "xy.h"
/* Note that timestamps make things tricky. And, we don't
* really care about the timestamp, we just care about the rest
* of the structure. So, we make a copy, and zero the timestamps
* in both copies, and then compare. */
int
check_sect_ok(struct sctstr *sectp)
{
struct sctstr chksect;
struct sctstr tsect;
getsect(sectp->sct_x, sectp->sct_y, &chksect);
memcpy(&tsect, sectp, sizeof(struct sctstr));
tsect.sct_timestamp = chksect.sct_timestamp = 0;
if (memcmp(&tsect, &chksect, sizeof(struct sctstr))) {
pr("Sector %s has changed!\n",
xyas(sectp->sct_x, sectp->sct_y, player->cnum));
return 0;
}
return 1;
}
int
check_ship_ok(struct shpstr *shipp)
{
struct shpstr chkship;
struct shpstr tship;
getship(shipp->shp_uid, &chkship);
memcpy(&tship, shipp, sizeof(struct shpstr));
tship.shp_timestamp = chkship.shp_timestamp = 0;
if (memcmp(&tship, &chkship, sizeof(struct shpstr))) {
pr("Ship #%d has changed!\n", shipp->shp_uid);
return 0;
}
return 1;
}
int
check_plane_ok(struct plnstr *planep)
{
struct plnstr chkplane;
struct plnstr tplane;
getplane(planep->pln_uid, &chkplane);
memcpy(&tplane, planep, sizeof(struct plnstr));
tplane.pln_timestamp = chkplane.pln_timestamp = 0;
if (memcmp(&tplane, &chkplane, sizeof(struct plnstr))) {
pr("Plane #%d has changed!\n", planep->pln_uid);
return 0;
}
return 1;
}
int
check_land_ok(struct lndstr *landp)
{
struct lndstr chkland;
struct lndstr tland;
getland(landp->lnd_uid, &chkland);
memcpy(&tland, landp, sizeof(struct lndstr));
tland.lnd_timestamp = chkland.lnd_timestamp = 0;
if (memcmp(&tland, &chkland, sizeof(struct lndstr))) {
pr("Land unit #%d has changed!\n", landp->lnd_uid);
return 0;
}
return 1;
}
int
check_nuke_ok(struct nukstr *nukep)
{
struct nukstr chknuke;
struct nukstr tnuke;
getnuke(nukep->nuk_uid, &chknuke);
memcpy(&tnuke, nukep, sizeof(struct nukstr));
tnuke.nuk_timestamp = chknuke.nuk_timestamp = 0;
if (memcmp(&tnuke, &chknuke, sizeof(struct nukstr))) {
pr("Nuke %d has changed!\n", nukep->nuk_uid);
return 0;
}
return 1;
}
int
check_loan_ok(struct lonstr *loanp)
{
struct lonstr chkloan;
getloan(loanp->l_uid, &chkloan);
if (memcmp(loanp, &chkloan, sizeof(struct lonstr))) {
pr("Loan %d has changed!\n", loanp->l_uid);
return 0;
}
return 1;
}
int
check_comm_ok(struct comstr *commp)
{
struct comstr chkcomm;
getcomm(commp->com_uid, &chkcomm);
if (memcmp(commp, &chkcomm, sizeof(struct comstr))) {
pr("Commodity %d has changed!\n", commp->com_uid);
return 0;
}
return 1;
}
int
check_trade_ok(struct trdstr *tp)
{
struct trdstr chktrade;
gettrade(tp->trd_uid, &chktrade);
if (memcmp(tp, &chktrade, sizeof(struct trdstr))) {
pr("Trade lot #%d has changed!\n", tp->trd_uid);
return 0;
}
return 1;
}

View file

@ -25,56 +25,50 @@
*
* ---
*
* fsize.c: BSD dependant file and block sizing routines
* cnumb.c: Return country number give country name
*
* 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 "file.h"
#include "match.h"
#include "nat.h"
#include "prototypes.h"
/*
* return the size of the file in bytes.
* Search for a country matching CNTRY, return its number.
* Return M_NOTFOUND if no such country exists, M_NOTUNIQUE if there
* are several.
*/
int
fsize(int fd)
cnumb(char *cntry)
{
struct stat statb;
char *ncp;
char *cp;
struct natstr *natp;
int res;
natid cn;
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;
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;
}

View file

@ -1,202 +0,0 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* damage.c: Damage stuff.
*
* Known contributors to this file:
* Dave Pare, 1989
* Steve McClure, 1997
*/
#include <config.h>
#include "damage.h"
#include "land.h"
#include "misc.h"
#include "nsc.h"
#include "nuke.h"
#include "optlist.h"
#include "plane.h"
#include "prototypes.h"
#include "sect.h"
#include "ship.h"
void
item_damage(int pct, short *item)
{
int lose;
i_type i;
for (i = I_NONE + 1; i <= I_MAX; ++i) {
if (opt_SUPER_BARS && i == I_BAR)
continue;
lose = roundavg((double)item[i] * pct * 0.01);
if (i == I_CIVIL || i == I_MILIT || i == I_UW)
lose = ldround(people_damage * lose, 1);
item[i] = item[i] >= lose ? item[i] - lose : 0;
}
}
void
ship_damage(struct shpstr *sp, int dam)
{
if (dam <= 0)
return;
if (dam > 100)
dam = 100;
mpr(sp->shp_own, "\t%s takes %d\n", prship(sp), dam);
sp->shp_effic = damage((int)sp->shp_effic, dam);
if (sp->shp_mobil > 0)
sp->shp_mobil = damage((int)sp->shp_mobil, dam);
if (opt_FUEL && sp->shp_fuel)
sp->shp_fuel = damage((int)sp->shp_fuel, dam);
item_damage(dam, sp->shp_item);
}
void
shipdamage(struct shpstr *sp, int dam)
{
ship_damage(sp, (int)(dam / (1.0 + sp->shp_armor / 100.0)));
}
void
land_damage(struct lndstr *lp, int dam)
{
if (dam <= 0)
return;
if (dam > 100)
dam = 100;
mpr(lp->lnd_own, "\t%s takes %d\n", prland(lp), dam);
if (lchr[(int)lp->lnd_type].l_flags & L_SPY) {
/* Spies die! */
lp->lnd_effic = 0;
} else {
lp->lnd_effic = damage((int)lp->lnd_effic, dam);
if (lp->lnd_mobil > 0)
lp->lnd_mobil = damage((int)lp->lnd_mobil, dam);
if (opt_FUEL && lp->lnd_fuel)
lp->lnd_fuel = damage((int)lp->lnd_fuel, dam);
item_damage(dam, lp->lnd_item);
}
}
void
landdamage(struct lndstr *lp, int dam)
{
double damage_factor, m;
m = land_mob_max;
/* fortification reduces damage */
damage_factor = m / (m + lp->lnd_harden);
/* vulnerable units take more damage */
damage_factor *= lp->lnd_vul / 100.0;
land_damage(lp, ldround(damage_factor * dam, 1));
}
void
planedamage(struct plnstr *pp, int dam)
{
if (dam <= 0)
return;
if (dam > 100)
dam = 100;
mpr(pp->pln_own, "\t%s takes %d\n", prplane(pp), dam);
pp->pln_effic = damage((int)pp->pln_effic, dam);
if (pp->pln_mobil > 0)
pp->pln_mobil = damage((int)pp->pln_mobil, dam);
}
/*
* nukedamage() actually just calculates damage
* rather than inflicting it.
*/
int
nukedamage(struct nchrstr *ncp, int range, int airburst)
{
int dam;
int rad;
rad = ncp->n_blast;
if (airburst)
rad = (int)(rad * 1.5);
if (rad < range)
return 0;
if (airburst) {
/* larger area, less center damage */
dam = (int)((ncp->n_dam * 0.75) - (range * 20));
} else {
/* smaller area, more center damage */
dam = (int)(ncp->n_dam / (range + 1.0));
}
if (dam < 5)
dam = 0;
return dam;
}
int
damage(int amt, int pct)
{
int tmp;
int lost;
if (amt <= 0)
return 0;
tmp = amt * pct;
lost = tmp / 100;
if (random() % 100 < tmp % 100)
lost++;
return amt - lost;
}
/* asymptotic damage to commodities, efficiency, and sectors */
int
effdamage(int amt, int dam)
{
return damage(amt, PERCENT_DAMAGE(dam));
}
int
commdamage(int amt, int dam, i_type vtype)
{
int lost;
if (vtype == I_BAR && opt_SUPER_BARS)
return amt;
lost = amt - effdamage(amt, dam);
if (vtype == I_MILIT || vtype == I_CIVIL || vtype == I_UW)
lost = ldround(people_damage * lost, 1);
return amt - lost;
}

246
src/lib/common/emp_config.c Normal file
View file

@ -0,0 +1,246 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* emp_config.c: Allows config file to control server config. from a file
*
* Known contributors to this file:
* Julian Onions, 1995
* Steve McClure, 1998-2000
*/
/*
* STILL TO DO
*
* Change other constants - such as MAXNOC etc.
* Just requires variables to be assigned, then dynamic allocation in
* a few places. Some checks needed in the server to check the world
* hasn't changed size etc.
*/
#include <config.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "file.h"
#include "misc.h"
#include "optlist.h"
#include "prototypes.h"
/* Dummy one */
static int emp_config_dummy;
/* things that can be changed */
struct keymatch configkeys[] = {
#define EMP_CONFIG_C_OUTPUT
#include "econfig-spec.h"
#undef EMP_CONFIG_C_OUTPUT
};
static struct keymatch *keylookup(char *key, struct keymatch tbl[]);
static void set_paths(char *);
/*
* read in empire configuration
*/
int
emp_config(char *file)
{
FILE *fp;
char scanspace[1024];
char *av[128];
char buf[1024];
struct keymatch *kp;
int lno = 0;
int errors = 0;
int i;
if (!file)
file = dflt_econfig;
errno = 0;
if ((fp = fopen(file, "r")) == NULL) {
if (file == dflt_econfig && errno == ENOENT)
goto done;
fprintf(stderr, "Can't open %s for reading (%s)\n",
file, strerror(errno));
return -1;
}
while (fgets(buf, sizeof(buf), fp) != NULL) {
++lno;
for (i = 0; buf[i] && isspace(buf[i]); ++i) ;
if (!buf[i] || buf[i] == '#')
continue;
if (parse(buf, scanspace, av, NULL, NULL, NULL) < 0) {
fprintf(stderr, "%s:%d: Can't parse line %s", file, lno, buf);
errors = 1;
continue;
}
if ((kp = keylookup(av[0], configkeys)) == NULL) {
fprintf(stderr, "%s:%d: Unknown config key %s\n",
file, lno, av[0]);
errors = 1;
continue;
}
if (av[1] == NULL) {
fprintf(stderr, "%s:%d: Config key %s needs a value\n",
file, lno, av[0]);
errors = 1;
continue;
}
i = 2;
switch (kp->km_type) {
case NSC_INT:
*(int *)kp->km_data = atoi(av[1]);
break;
case NSC_FLOAT:
*(float *)kp->km_data = atof(av[1]);
break;
case NSC_DOUBLE:
*(double *)kp->km_data = atof(av[1]);
break;
case NSC_LONG:
*(long *)kp->km_data = atol(av[1]);
break;
case NSC_STRING:
if (kp->km_flags & KM_ALLOC)
free(*(char **)kp->km_data);
*(char **)kp->km_data = strdup(av[1]);
kp->km_flags |= KM_ALLOC;
break;
default:
assert(0);
}
if (av[i] != NULL) {
fprintf(stderr, "%s:%d: Junk after value of config key %s\n",
file, lno, av[0]);
errors = 1;
}
}
fclose(fp);
done:
WORLD_X &= ~1; /* force even */
set_paths(file);
return -errors;
}
/* find the key in the table */
static struct keymatch *
keylookup(char *command, struct keymatch *tbl)
{
struct keymatch *kp;
if (command == 0 || *command == 0)
return 0;
for (kp = tbl; kp->km_key != 0; kp++) {
if (strcmp(kp->km_key, command) == 0)
return kp;
}
return NULL;
}
static void
set_paths(char *econfig)
{
char *slash;
char *cwd = getcwd(NULL, 0);
#ifdef _WIN32
/* normalize path separator to '\\', for easier searching: */
econfig = _fullpath(NULL, econfig, 0);
slash = strrchr(econfig, '\\');
configdir = malloc(slash - econfig + 1);
memcpy(configdir, econfig, slash - econfig);
configdir[slash - econfig] = 0;
#else
if ((slash = strrchr(econfig, '/'))) {
configdir = malloc(slash - econfig + 1);
memcpy(configdir, econfig, slash - econfig);
configdir[slash - econfig] = 0;
} else
configdir = strdup(cwd);
if (configdir[0] != '/') {
char *tmp = configdir;
size_t len = strlen(cwd);
configdir = malloc(len + 1 + strlen(tmp) + 1);
sprintf(configdir, "%s/%s", cwd, tmp);
free(tmp);
}
#endif /* !_WIN32 */
schedulefil = malloc(strlen(configdir) + 10);
sprintf(schedulefil, "%s/schedule", configdir);
free(cwd);
}
void
print_config(FILE *fp)
{
struct keymatch *kp;
fprintf(fp, "# Empire Configuration File:\n");
for (kp = configkeys; kp->km_key; kp++) {
if (kp->km_comment) {
if (kp->km_comment[0] != '\n' && kp->km_comment[0] != '#')
fprintf(fp, "\n# ");
fprintf(fp, "%s\n", kp->km_comment);
}
if (!kp->km_key[0])
continue;
switch (kp->km_type) {
case NSC_STRING:
fprintf(fp, "%s \"%s\"\n", kp->km_key, *(char **)kp->km_data);
break;
case NSC_INT:
fprintf(fp, "%s %d\n", kp->km_key, *(int *)kp->km_data);
break;
case NSC_FLOAT:
fprintf(fp, "%s %g\n", kp->km_key, *(float *)kp->km_data);
break;
case NSC_DOUBLE:
fprintf(fp, "%s %g\n", kp->km_key, *(double *)kp->km_data);
break;
case NSC_LONG:
fprintf(fp, "%s %ld\n", kp->km_key, *(long *)kp->km_data);
break;
default:
assert(0);
}
}
fprintf(fp, "\n");
}

View file

@ -1,137 +0,0 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* empobj.c: Common functions on struct empobj and
* union empobj_storage
*
* Known contributors to this file:
* Ron Koenderink, 2006
* Markus Armbruster, 2006
*/
#include <config.h>
#include "empobj.h"
#include "file.h"
#include "optlist.h"
#include "prototypes.h"
char *
obj_nameof(struct empobj *gp)
{
switch (gp->ef_type) {
case EF_SHIP:
return prship((struct shpstr *)gp);
case EF_PLANE:
return prplane((struct plnstr *)gp);
case EF_LAND:
return prland((struct lndstr *)gp);
case EF_NUKE:
return prnuke((struct nukstr *)gp);
}
CANT_REACH();
return "The Beast #666";
}
struct empobj *
get_empobjp(int type, int id)
{
if (CANT_HAPPEN(type == EF_SECTOR || type == EF_BAD))
return NULL;
return ef_ptr(type, id);
}
int
put_empobj(struct empobj *gp)
{
switch (gp->ef_type)
{
case EF_SECTOR:
return ef_write(gp->ef_type, sctoff(gp->x, gp->y), gp);
case EF_NATION:
case EF_BMAP:
case EF_MAP:
return ef_write(gp->ef_type, gp->own, gp);
default:
return ef_write(gp->ef_type, gp->uid, gp);
}
}
struct empobj_chr *
get_empobj_chr(struct empobj *gp)
{
switch (gp->ef_type) {
case EF_LAND:
return (struct empobj_chr *)&lchr[(int)gp->type];
case EF_SHIP:
return (struct empobj_chr *)&mchr[(int)gp->type];
case EF_PLANE:
return (struct empobj_chr *)&plchr[(int)gp->type];
case EF_NUKE:
return (struct empobj_chr *)&nchr[(int)gp->type];
case EF_SECTOR:
return (struct empobj_chr *)&dchr[(int)gp->type];
}
CANT_REACH();
return NULL;
}
char *
emp_obj_chr_name(struct empobj *gp)
{
switch (gp->ef_type) {
case EF_LAND:
return lchr[(int)gp->type].l_name;
case EF_SHIP:
return mchr[(int)gp->type].m_name;
case EF_PLANE:
return plchr[(int)gp->type].pl_name;
case EF_NUKE:
return nchr[(int)gp->type].n_name;
case EF_SECTOR:
return dchr[(int)gp->type].d_name;
}
CANT_REACH();
return NULL;
}
int
get_empobj_mob_max(int type)
{
switch (type) {
case EF_SHIP:
return ship_mob_max;
case EF_LAND:
return land_mob_max;
case EF_PLANE:
return plane_mob_max;
case EF_SECTOR:
return sect_mob_max;
}
CANT_REACH();
return -1;
}

View file

@ -1,169 +0,0 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
* related information and legal notices. It is expected that any future
* projects/authors will amend these files as needed.
*
* ---
*
* journal.c: Log a journal of events to a file
*
* Known contributors to this file:
* Markus Armbruster, 2004-2007
*/
/*
* Journal file format: each line logs an event, and looks like this:
*
* TIME THREAD EVENT DATA
*
* Events and their data are:
*
* startup
* shutdown
* login CNUM HOSTADDR USER
* logout CNUM
* input INPUT
* update ETU
*/
#include <config.h>
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include "misc.h"
#include "empthread.h"
#include "journal.h"
#include "optlist.h"
#include "player.h"
#include "prototypes.h"
static char journal_fname[] = "journal.log";
static FILE *journal;
static FILE *
journal_open(void)
{
return fopen(journal_fname, "a+");
}
static void
journal_entry(char *fmt, ...)
{
static char buf[1024];
va_list ap;
time_t now;
unsigned char *p;
if (journal) {
time(&now);
fprintf(journal, "%.24s %p ", ctime(&now), empth_self());
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
va_end(ap);
for (p = (unsigned char *)buf; *p; p++) {
if (isprint(*p))
putc(*p, journal);
else
fprintf(journal, "\\%03o", *p);
}
fputs("\n", journal);
if (debug)
fflush(journal);
if (ferror(journal)) {
logerror("Error writing journal (%s)", strerror(errno));
clearerr(journal);
}
}
}
int
journal_startup(void)
{
if (!keep_journal)
return 0;
journal = journal_open();
if (!journal) {
logerror("Can't open %s (%s)", journal_fname, strerror(errno));
return -1;
}
journal_entry("startup");
return 0;
}
void
journal_shutdown(void)
{
journal_entry("shutdown");
if (journal) {
fclose(journal);
journal = NULL;
}
}
int
journal_reopen(void)
{
FILE *j;
if (!keep_journal)
return 0;
j = journal_open();
if (!j) {
logerror("Can't open %s (%s)", journal_fname, strerror(errno));
return -1;
}
if (journal)
fclose(journal);
journal = j;
return 0;
}
void
journal_login(void)
{
journal_entry("login %d %s %s",
player->cnum, player->hostaddr, player->userid);
}
void
journal_logout(void)
{
journal_entry("logout %d", player->cnum);
}
void
journal_input(char *input)
{
journal_entry("input %s", input);
}
void
journal_update(int etu)
{
journal_entry("update %d", etu);
}

View file

@ -1,150 +0,0 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* log.c: Log an Empire error to a file
*
* Known contributors to this file:
* Dave Pare, 1989
*/
#include <config.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "misc.h"
#include "optlist.h"
#include "player.h"
#include "prototypes.h"
/* Debugging? If yes call abort() on internal error. */
int debug = 0;
static char logfile[32];
static int logfd = -1;
static int logopen(void);
/*
* Points log file at PROGRAM.log
*/
int
loginit(char *program)
{
sprintf(logfile, "%.*s.log", (int)sizeof(logfile) - 5, program);
logfd = logopen();
return logfd;
}
static int
logopen(void)
{
int fd;
fd = open(logfile, O_WRONLY | O_CREAT | O_APPEND, S_IRWUG);
if (fd < 0)
logerror("Can't open %s (%s)", logfile, strerror(errno));
return fd;
}
int
logreopen(void)
{
int newfd, res;
if ((newfd = logopen()) < 0)
return -1;
res = close(logfd);
logfd = newfd;
if (res < 0)
logerror("Can't close %s (%s)", logfile, strerror(errno));
return res;
}
/*
* Write a line to the log file and to stderr.
* Messages are silently truncated after 512 characters or a newline.
*/
void
logerror(char *format, ...)
{
enum {
ctime_len = 24, /* output of ctime() less the newline */
msg_space = 512 /* space for formatted message */
};
va_list list;
time_t now;
char buf[ctime_len + 1 + msg_space + 2];
char *msg, *p;
va_start(list, format);
msg = buf + ctime_len + 1;
vsnprintf(msg, msg_space, format, list);
buf[sizeof(buf)-2] = 0;
p = msg + strlen(msg);
p[0] = '\n';
p[1] = 0;
p = strchr(msg, '\n');
p[1] = 0;
fputs(msg, stderr);
if (logfd >= 0) {
time(&now);
memcpy(buf, ctime(&now), ctime_len);
buf[ctime_len] = ' ';
write(logfd, buf, strlen(buf));
}
va_end(list);
}
/*
* Log internal error MSG occured in FILE:LINE.
* If debugging, call abort(), else return 1.
*/
int
oops(char *msg, char *file, int line)
{
logerror("Oops: %s in %s:%d", msg ? msg : "bug", file, line);
if (debug) abort();
return 1;
}
/*
* Report out-of-memory condition and terminate the program.
* Use this with restraint! Clean error recovery is preferable, but
* not always feasible (e.g. halfway through the update) or worthwhile
* (during server startup).
*/
void
exit_nomem(void)
{
logerror("Memory exhausted");
exit(1);
}

110
src/lib/common/mapdist.c Normal file
View file

@ -0,0 +1,110 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* mapdist.c: Return the distance between two sectors
*
* Known contributors to this file:
*
*/
/*
* mapdist returns (integer) distance between two sectors.
*/
#include <config.h>
#include "misc.h"
#include "optlist.h"
#include "prototypes.h"
int
diffx(int x1, int x2)
{
int dx;
dx = x1 - x2;
dx = dx % WORLD_X;
if (dx > WORLD_X / 2)
dx = dx - WORLD_X;
if (dx < -WORLD_X / 2)
dx = dx + WORLD_X;
return dx;
}
int
diffy(int y1, int y2)
{
int dy;
dy = y1 - y2;
dy = dy % WORLD_Y;
if (dy > WORLD_Y / 2)
dy = dy - WORLD_Y;
if (dy < -WORLD_Y / 2)
dy = dy + WORLD_Y;
return dy;
}
int
deltax(int x1, int x2)
{
int dx;
dx = abs(x1 - x2);
dx = dx % WORLD_X;
if (dx > WORLD_X / 2)
dx = WORLD_X - dx;
return dx;
}
int
deltay(int y1, int y2)
{
int dy;
dy = abs(y1 - y2);
dy = dy % WORLD_Y;
if (dy > WORLD_Y / 2)
dy = WORLD_Y - dy;
return dy;
}
int
mapdist(int x1, int y1, int x2, int y2)
{
int dx, dy;
x1 = x1 % WORLD_X;
y1 = y1 % WORLD_Y;
x2 = x2 % WORLD_X;
y2 = y2 % WORLD_Y;
dx = deltax(x1, x2);
dy = deltay(y1, y2);
if (dx > dy)
return (dx - dy) / 2 + dy;
return dy;
}

View file

@ -1,449 +0,0 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* maps.c: Map routines
*
* Known contributors to this file:
* Ken Stevens, 1995
* Steve McClure, 1998
* Ron Koenderink, 2006
*/
#include <config.h>
#include <ctype.h>
#include "com.h"
#include "empobj.h"
#include "file.h"
#include "land.h"
#include "map.h"
#include "misc.h"
#include "nat.h"
#include "nsc.h"
#include "nuke.h"
#include "optlist.h"
#include "plane.h"
#include "player.h"
#include "prototypes.h"
#include "sect.h"
#include "ship.h"
#include "xy.h"
static int bmnxtsct(struct nstr_sect *);
static char map_char(unsigned char type, natid own, int owner_or_god);
int
do_map(int bmap, int unit_type, char *arg, char *map_flags_arg)
{
struct nstr_sect ns;
char origin = '\0';
char *b;
int map_flags = 0;
if (!snxtsct(&ns, arg)) {
if (unit_map(unit_type, atoi(arg), &ns, &origin))
return RET_FAIL;
}
for (b = map_flags_arg; b && *b; b++) {
switch (*b) {
case 's':
case 'S':
map_flags |= MAP_SHIP;
break;
case 'l':
case 'L':
map_flags |= MAP_LAND;
break;
case 'p':
case 'P':
map_flags |= MAP_PLANE;
break;
case 'n':
case 'N':
map_flags |= MAP_NUKE;
break;
case 'h':
case 'H':
map_flags |= MAP_HIGH;
break;
case '*':
map_flags |= MAP_ALL;
break;
case 't':
if (bmap != 'b')
goto bad_flag;
bmap = 't';
*(b + 1) = 0;
break;
case 'r':
if (bmap != 'b')
goto bad_flag;
bmap = 'r';
*(b + 1) = 0;
break;
default:
bad_flag:
pr("Bad flag %c!\n", *b);
break;
}
}
return draw_map(bmap, origin, map_flags, &ns);
}
int
draw_map(int bmap, char origin, int map_flags, struct nstr_sect *nsp)
{
struct natstr *np;
struct range range;
struct nstr_item ni;
union empobj_storage unit;
coord x, y;
int i;
/* Note this is not re-entrant anyway, so we keep the buffers
around */
static unsigned char *bitmap = NULL;
static char *wmapbuf = NULL;
static char **wmap = NULL;
static int ef_mappable[] = { EF_PLANE, EF_SHIP, EF_LAND, EF_NUKE, EF_BAD };
static int ef_unit_map[] = { MAP_PLANE, MAP_SHIP, MAP_LAND, MAP_NUKE };
char *name;
if (!wmapbuf)
wmapbuf = malloc(WORLD_Y * MAPWIDTH(1));
if (!wmap) {
wmap = malloc(WORLD_Y * sizeof(char *));
if (wmap && wmapbuf) {
for (i = 0; i < WORLD_Y; i++)
wmap[i] = &wmapbuf[MAPWIDTH(1) * i];
} else if (wmap) {
free(wmap);
wmap = NULL;
}
}
if (!bitmap)
bitmap = malloc((WORLD_X * WORLD_Y) / 8);
if (!wmapbuf || !wmap || !bitmap) {
pr("Memory error, tell the deity.\n");
logerror("malloc failed in draw_map\n");
return RET_FAIL;
}
if (bmap == 'r') {
if (!confirm("Are you sure you want to revert your bmap? "))
return RET_OK;
}
if (!(player->command->c_flags & C_MOD)) {
logerror("%s command needs C_MOD flag set",
player->command->c_form);
player->command->c_flags |= C_MOD;
}
np = getnatp(player->cnum);
/* zap any conditionals */
nsp->ncond = 0;
xyrelrange(np, &nsp->range, &range);
border(&range, " ", "");
blankfill(wmapbuf, &nsp->range, 1);
if (bmap) {
int c;
switch (bmap) {
default:
CANT_REACH();
bmap = 'b';
/* fall through */
case 'b':
while (bmnxtsct(nsp) && !player->aborted) {
if (0 != (c = player->bmap[sctoff(nsp->x, nsp->y)]))
wmap[nsp->dy][nsp->dx] = c;
}
break;
case 't':
while (bmnxtsct(nsp) && !player->aborted) {
if (0 != (c = player->map[sctoff(nsp->x, nsp->y)]))
wmap[nsp->dy][nsp->dx] = c;
}
break;
case 'r':
while (bmnxtsct(nsp) && !player->aborted) {
player->bmap[sctoff(nsp->x, nsp->y)] =
player->map[sctoff(nsp->x, nsp->y)];
if (0 != (c = player->bmap[sctoff(nsp->x, nsp->y)]))
wmap[nsp->dy][nsp->dx] = c;
}
ef_write(EF_BMAP, player->cnum, player->bmap);
break;
case 'n':
{
struct sctstr sect;
if (!player->god) {
memset(bitmap, 0, (WORLD_X * WORLD_Y) / 8);
bitinit2(nsp, bitmap, player->cnum);
}
while (nxtsct(nsp, &sect) && !player->aborted) {
if (!player->god && !emp_getbit(nsp->x, nsp->y, bitmap))
continue;
wmap[nsp->dy][nsp->dx]
= map_char(sect.sct_newtype, sect.sct_own,
player->owner);
}
break;
}
}
} else {
struct sctstr sect;
char mapch;
int changed = 0;
if (!player->god) {
memset(bitmap, 0, (WORLD_X * WORLD_Y) / 8);
bitinit2(nsp, bitmap, player->cnum);
}
while (nxtsct(nsp, &sect) && !player->aborted) {
if (!player->god && !emp_getbit(nsp->x, nsp->y, bitmap))
continue;
mapch = map_char(sect.sct_type, sect.sct_own, player->owner);
wmap[nsp->dy][nsp->dx] = mapch;
changed |= map_set(player->cnum, nsp->x, nsp->y, mapch, 0);
}
if (changed)
writemap(player->cnum);
}
if (player->aborted)
return RET_OK;
i = 0;
while (ef_mappable[i] != EF_BAD) {
if (map_flags & ef_unit_map[i]) {
snxtitem_all(&ni, ef_mappable[i]);
while (nxtitem(&ni, &unit)) {
if (unit.gen.own == 0)
continue;
if (unit.gen.own != player->cnum && !player->god)
continue;
if (!xyinrange(unit.gen.x, unit.gen.y, &nsp->range))
continue;
x = xnorm(unit.gen.x - nsp->range.lx);
y = ynorm(unit.gen.y - nsp->range.ly);
if (ef_mappable[i] == EF_NUKE)
wmap[y][x] = 'N';
else {
if ((name = emp_obj_chr_name(&unit.gen)) == NULL)
return RET_FAIL;
wmap[y][x] = *name & ~0x20;
}
}
}
i++;
}
if (map_flags & MAP_HIGH) {
struct sctstr sect;
snxtsct_rewind(nsp);
if (!player->god) {
memset(bitmap, 0, (WORLD_X * WORLD_Y) / 8);
bitinit2(nsp, bitmap, player->cnum);
}
while (nxtsct(nsp, &sect) && !player->aborted) {
if (!player->god && !emp_getbit(nsp->x, nsp->y, bitmap))
continue;
if (sect.sct_own == player->cnum)
wmap[nsp->dy][nsp->dx] |= 0x80;
}
}
if (origin)
wmap[5][10] = origin & ~0x20;
for (y = nsp->range.ly, i = 0; i < nsp->range.height; y++, i++) {
int yval;
yval = yrel(np, y);
wmap[i][nsp->range.width] = '\0';
pr("%4d %s %-4d\n", yval, wmap[i], yval);
if (y >= WORLD_Y)
y -= WORLD_Y;
}
border(&range, " ", "");
return RET_OK;
}
/*
* get the next sector in the range
*/
static int
bmnxtsct(struct nstr_sect *np)
{
while (1) {
np->dx++;
np->x++;
if (np->x >= WORLD_X)
np->x = 0;
if (np->dx >= np->range.width) {
np->dx = 0;
np->x = np->range.lx;
np->dy++;
if (np->dy >= np->range.height)
return 0;
np->y++;
if (np->y >= WORLD_Y)
np->y = 0;
}
if ((np->y + np->x) & 01)
continue;
if (np->type == NS_DIST) {
np->curdist = mapdist(np->x, np->y, np->cx, np->cy);
if (np->curdist > np->dist)
continue;
}
np->id = sctoff(np->x, np->y);
return 1;
}
/*NOTREACHED*/
}
/*
* Return character to use in maps for sector type TYPE owned by OWN.
* If OWNER_OR_GOD, the map is for the sector's owner or a deity.
*/
static char
map_char(unsigned char type, natid own, int owner_or_god)
{
if (CANT_HAPPEN(type > SCT_TYPE_MAX || !dchr[type].d_mnem))
return '?';
if (owner_or_god
|| type == SCT_WATER || type == SCT_MOUNT || type == SCT_WASTE
|| (!own && (type == SCT_RURAL || type == SCT_PLAINS)))
return dchr[type].d_mnem;
return '?';
}
int
unit_map(int unit_type, int uid, struct nstr_sect *nsp, char *originp)
{
struct empobj *gp;
struct range range;
char *name;
gp = get_empobjp(unit_type, uid);
if (!gp || (gp->own != player->cnum && !player->god) || gp->own == 0)
return RET_FAIL;
if (unit_type == EF_NUKE)
*originp = 'n';
else {
if ((name = emp_obj_chr_name(gp)) == NULL)
return RET_FAIL;
*originp = *name;
}
range.lx = xnorm(gp->x - 10);
range.hx = xnorm(gp->x + 11);
range.ly = ynorm(gp->y - 5);
range.hy = ynorm(gp->y + 6);
xysize_range(&range);
snxtsct_area(nsp, &range);
return RET_OK;
}
int
display_region_map(int bmap, int unit_type, coord curx, coord cury,
char *arg)
{
char coordinates[80];
char *map_flag_arg;
if (!arg || !*arg) {
struct natstr *np;
np = getnatp(player->cnum);
sprintf(coordinates, "%d:%d,%d:%d",
xrel(np, curx - 10), xrel(np, curx + 11),
yrel(np, cury - 5), yrel(np, cury + 6));
arg = coordinates;
map_flag_arg = NULL;
} else {
map_flag_arg = strchr(arg, ' ');
if (map_flag_arg != NULL) {
*map_flag_arg++ = '\0';
while (isspace(*map_flag_arg)) map_flag_arg++;
}
}
player->condarg = NULL;
return do_map(bmap, unit_type, arg, map_flag_arg);
}
int
bmaps_intersect(natid a, natid b)
{
char *mapa = ef_ptr(EF_MAP, a);
char *mapb = ef_ptr(EF_MAP, b);
int i;
for (i = 0; i < WORLD_SZ(); i++)
if (mapa[i] && mapa[i] != ' ' && mapb[i] && mapb[i] != ' ')
return 1;
return 0;
}
/* Note that this requires that the BMAP is mapped into memory */
int
share_bmap(natid from, natid to, struct nstr_sect *ns, char des,
char *from_name)
{
char *from_bmap = ef_ptr(EF_BMAP, from);
char *to_bmap = ef_ptr(EF_BMAP, to);
int n = 0;
struct sctstr sect;
char fromdes;
char todes;
char from_des = *from_name;
if (isalpha(from_des))
from_des &= ~0x20;
while (nxtsct(ns, &sect)) {
if (!(fromdes = from_bmap[sctoff(ns->x, ns->y)]))
continue;
todes = to_bmap[sctoff(ns->x, ns->y)];
if (todes &&
todes != '?' &&
todes != '.' && todes != ' ' && todes != from_des)
continue;
if (sect.sct_own == from) {
if (fromdes != '=' && fromdes != 'h' && fromdes != des)
fromdes = from_des;
}
if (todes == fromdes)
continue;
n += map_set(to, ns->x, ns->y, fromdes, 1);
}
if (n)
writebmap(to);
return n;
}

173
src/lib/common/nstreval.c Normal file
View file

@ -0,0 +1,173 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* nstreval.c: evaluate compiled values
*
* Known contributors to this file:
* Dave Pare, 1989
* Steve McClure, 1997
* Markus Armbruster, 2004-2006
*/
#include <config.h>
#include <limits.h>
#include "file.h"
#include "nat.h"
#include "nsc.h"
#include "optlist.h"
/*
* Evaluate VAL.
* If VAL is symbolic, evaluate it into a promoted value type.
* Use coordinate system of country CNUM.
* PTR points to a context object of the type that was used to compile
* the value.
* Unless WANT is NSC_NOTYPE, coerce the value to promoted value type
* WANT. VAL must be coercible. That's the case if a previous
* nstr_coerce_val(VAL, WANT, STR) succeeded.
*/
void
nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
{
char *memb_ptr;
nsc_type valtype;
int idx;
struct natstr *natp;
switch (val->val_cat) {
default:
CANT_REACH();
/* fall through */
case NSC_VAL:
valtype = val->val_type;
break;
case NSC_OFF:
valtype = NSC_LONG;
memb_ptr = ptr;
memb_ptr += val->val_as.sym.off;
idx = val->val_as.sym.idx;
switch (val->val_type) {
case NSC_CHAR:
val->val_as.lng = ((signed char *)memb_ptr)[idx];
break;
case NSC_UCHAR:
val->val_as.lng = ((unsigned char *)memb_ptr)[idx];
break;
case NSC_SHORT:
val->val_as.lng = ((short *)memb_ptr)[idx];
break;
case NSC_USHORT:
val->val_as.lng = ((unsigned short *)memb_ptr)[idx];
break;
case NSC_INT:
val->val_as.lng = ((int *)memb_ptr)[idx];
break;
case NSC_LONG:
val->val_as.lng = ((long *)memb_ptr)[idx];
break;
case NSC_XCOORD:
val->val_as.lng = xrel(getnatp(cnum), ((short *)memb_ptr)[idx]);
break;
case NSC_YCOORD:
val->val_as.lng = yrel(getnatp(cnum), ((short *)memb_ptr)[idx]);
break;
case NSC_HIDDEN:
val->val_as.lng = -1;
if (CANT_HAPPEN(((struct natstr *)ptr)->ef_type != EF_NATION))
break;
natp = getnatp(cnum);
if (!opt_HIDDEN
|| natp->nat_stat == STAT_GOD
|| (getcontact(natp, idx) && getcontact(ptr, idx)))
val->val_as.lng = ((unsigned char *)memb_ptr)[idx];
break;
case NSC_FLOAT:
val->val_as.dbl = ((float *)memb_ptr)[idx];
valtype = NSC_DOUBLE;
break;
case NSC_DOUBLE:
val->val_as.dbl = ((double *)memb_ptr)[idx];
valtype = NSC_DOUBLE;
break;
case NSC_STRINGY:
CANT_HAPPEN(idx);
val->val_as.str.maxsz = val->val_as.sym.len;
val->val_as.str.base = (char *)memb_ptr;
valtype = NSC_STRING;
break;
case NSC_STRING:
val->val_as.str.base = ((char **)memb_ptr)[idx];
val->val_as.str.maxsz = INT_MAX;
valtype = NSC_STRING;
break;
case NSC_TIME:
val->val_as.lng = ((time_t *)memb_ptr)[idx];
break;
default:
CANT_REACH();
val->val_as.lng = 0;
}
val->val_cat = NSC_VAL;
}
if (valtype == want)
;
else if (want == NSC_DOUBLE) {
if (valtype == NSC_LONG) {
valtype = want;
val->val_as.dbl = val->val_as.lng;
}
} else if (want == NSC_STRING)
CANT_REACH(); /* FIXME implement */
if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE)) {
valtype = want;
switch (want) {
case NSC_LONG: val->val_as.lng = 0; break;
case NSC_DOUBLE: val->val_as.dbl = 0.0; break;
case NSC_STRING: val->val_as.str.base = NULL; break;
default:
CANT_REACH();
}
}
val->val_type = valtype;
}
char *
symbol_by_value(int key, struct symbol *table)
{
int i;
for (i = 0; table[i].name; i++)
if (key == table[i].value)
return table[i].name;
return NULL;
}

View file

@ -1,130 +0,0 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* sectdamage.c: Damage a sector
*
* Known contributors to this file:
* Dave Pare, 1989
* Steve McClure, 1996
*/
#include <config.h>
#include "combat.h"
#include "damage.h"
#include "file.h"
#include "land.h"
#include "misc.h"
#include "nat.h"
#include "nsc.h"
#include "optlist.h"
#include "plane.h"
#include "prototypes.h"
#include "sect.h"
#include "ship.h"
#include "xy.h"
int
sect_damage(struct sctstr *sp, int dam, struct emp_qelem *list)
{
int eff;
if (dam <= 0)
return 0;
if (dam > 100)
dam = 100;
sp->sct_effic = damage(sp->sct_effic, dam);
sp->sct_avail = damage(sp->sct_avail, dam);
sp->sct_road = damage(sp->sct_road, dam);
sp->sct_rail = damage(sp->sct_rail, dam);
sp->sct_defense = damage(sp->sct_defense, dam);
eff = dam;
if (sp->sct_mobil > 0)
sp->sct_mobil = damage(sp->sct_mobil, dam);
item_damage(dam, sp->sct_item);
if (opt_EASY_BRIDGES == 0) {
if (sp->sct_effic < SCT_MINEFF && sp->sct_type == SCT_BHEAD)
bridgefall(sp, list);
} else {
if (sp->sct_effic < SCT_MINEFF && sp->sct_type == SCT_BSPAN)
knockdown(sp, list);
}
putsect(sp);
return eff;
}
int
sectdamage(struct sctstr *sp, int dam, struct emp_qelem *list)
{
struct nstr_item ni;
struct lndstr land;
struct plnstr plane;
int eff;
/* Some sectors are harder/easier to kill.. */
/* Average sector has a dstr of 1, so adjust */
/* the damage accordingly. Makes forts a pain */
dam = ldround(dam / sector_strength(sp), 1);
eff = sect_damage(sp, PERCENT_DAMAGE(dam), list);
/* Damage all the land units in the sector */
/* Units don't take full damage */
dam = ldround(DPERCENT_DAMAGE(dam * unit_damage), 1);
if (dam <= 0)
return eff;
snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y);
while (nxtitem(&ni, &land)) {
if (!land.lnd_own)
continue;
landdamage(&land, dam);
putland(land.lnd_uid, &land);
}
dam = dam / 7;
if (dam <= 0)
return eff;
snxtitem_xy(&ni, EF_PLANE, sp->sct_x, sp->sct_y);
while (nxtitem(&ni, &plane)) {
if (!plane.pln_own)
continue;
if (plane.pln_flags & PLN_LAUNCHED)
continue;
if (plane.pln_ship >= 0)
continue;
/* Is this plane flying in this list? */
if (ac_isflying(&plane, list))
continue;
planedamage(&plane, dam);
putplane(plane.pln_uid, &plane);
}
return eff;
}