Import of Empire 4.2.12
This commit is contained in:
commit
d8b7fdfae1
817 changed files with 126589 additions and 0 deletions
67
src/lib/common/Makefile
Normal file
67
src/lib/common/Makefile
Normal file
|
@ -0,0 +1,67 @@
|
|||
#
|
||||
# Empire - A multi-player, client/server Internet based war game.
|
||||
# Copyright (C) 1986-2000, 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.
|
||||
#
|
||||
# Makefile - Wolfpack, 1996
|
||||
|
||||
# Note that these could have been listed 1 per line, but I chose to just
|
||||
# stick them all together this way to shorten the file.
|
||||
|
||||
include ../../../build.conf
|
||||
include ../../make.src
|
||||
include ../../make.defs
|
||||
|
||||
LIB = $(SRCDIR)/lib/libcommon.a
|
||||
NTLIB = $(SRCDIR)\lib\libcommon.lib
|
||||
|
||||
OBJS = bestpath.o bridgefall.o check.o damage.o file.o fsize.o getvar.o \
|
||||
hap_fact.o hours.o keyword.o land.o log.o mailbox.o maps.o move.o \
|
||||
nat.o nstr_subs.o path.o res_pop.o sectdamage.o snxtit_subs.o \
|
||||
snxtsct_subs.o stmtch.o tfact.o type.o vlist.o wantupd.o xy.o
|
||||
|
||||
NTOBJS = bestpath.obj bridgefall.obj check.obj damage.obj file.obj fsize.obj \
|
||||
getvar.obj hap_fact.obj hours.obj keyword.obj land.obj log.obj \
|
||||
mailbox.obj maps.obj move.obj nat.obj nstr_subs.obj path.obj res_pop.obj \
|
||||
sectdamage.obj snxtit_subs.obj snxtsct_subs.obj stmtch.obj tfact.obj \
|
||||
type.obj vlist.obj wantupd.obj xy.obj
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
nt: $(NTLIB)
|
||||
|
||||
$(NTLIB): $(NTOBJS)
|
||||
-del /q $@
|
||||
lib /OUT:$@ /DEBUGTYPE:CV $(NTOBJS)
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
rm -f $(LIB)
|
||||
ar cq $(LIB) $(OBJS)
|
||||
$(RANLIB) $(LIB)
|
||||
|
||||
clean:
|
||||
-(rm -f $(OBJS))
|
||||
-(del /q $(NTOBJS))
|
||||
|
||||
include ../../make.rules
|
||||
include Makedepend
|
322
src/lib/common/bestpath.c
Normal file
322
src/lib/common/bestpath.c
Normal file
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* bestpath.c: Find the best path between sectors
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Steve McClure, 1998-2000
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: These routines are very selectively used in the server.
|
||||
*
|
||||
* "bestpath" is now obsolete (and removed)
|
||||
* "bestownedpath" is only used to determine paths for ships and planes.
|
||||
*
|
||||
* Callers should not be calling these directly anymore. They should use
|
||||
* the "BestShipPath", "BestAirPath", "BestLandPath" and "BestDistPath"
|
||||
* functions. Note that those last two use the A* algorithms to find
|
||||
* information.
|
||||
*/
|
||||
|
||||
#include "gamesdef.h"
|
||||
#include "misc.h"
|
||||
#include "xy.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "file.h"
|
||||
#include "nat.h"
|
||||
#include "common.h"
|
||||
#include "optlist.h"
|
||||
|
||||
static int owned_and_navigable(s_char * , int , int , s_char * , int );
|
||||
|
||||
#define MAXROUTE 100 /* return '?' if path longer than this */
|
||||
#define valid(x,y) (((x^y)&1)==0)
|
||||
|
||||
/* ________________________________________________________________
|
||||
**
|
||||
** bestpath(x1,y1,x2,y2,(s_char *)terrain);
|
||||
**
|
||||
** Calculate routing string to get from sector [x1,y1] to sector [x2,y2]
|
||||
** via a specified type of terrain.
|
||||
**
|
||||
** Specify:
|
||||
**
|
||||
** x1,y1 starting coordinates
|
||||
**
|
||||
** x2,y2 destination coordinates
|
||||
**
|
||||
** terrain ptr to string showing the types of sectors that
|
||||
** we're allowed to pass through:
|
||||
**
|
||||
** A null string enables routing through any kind of
|
||||
** sector (useful for airplanes).
|
||||
**
|
||||
** A string that begins with an 'R' ensures that
|
||||
** the source and destination sectors also match
|
||||
** the specified type of terrain.
|
||||
**
|
||||
** A string that begins with a '~' (after the 'R',
|
||||
** if necessary) specifies that we can pass through
|
||||
** any kind of sector EXCEPT those in the remainder
|
||||
** of the string.
|
||||
**
|
||||
** Examples:
|
||||
**
|
||||
** "R~.^" all sectors along route must be
|
||||
** non-ocean, non-mountain
|
||||
**
|
||||
** "+" all sectors between start and end
|
||||
** must be highway
|
||||
**
|
||||
** "h. " all sectors along route must be
|
||||
** harbor, water, or unmapped
|
||||
**
|
||||
** 'bestpath' returns a pointer to a route string containing either:
|
||||
**
|
||||
** yugjbn - string of normal routing characters if route possible
|
||||
** ? - if route is longer than MAXROUTE characters
|
||||
** \0 - (null string) if no route possible
|
||||
** h - if start and end points are the same sector
|
||||
** ________________________________________________________________
|
||||
*/
|
||||
|
||||
s_char *dirchar = "juygbn";
|
||||
int dx[6] = { 2, 1,-1,-2,-1, 1 };
|
||||
int dy[6] = { 0,-1,-1, 0, 1, 1 };
|
||||
int tmp;
|
||||
|
||||
/*
|
||||
* Ok, note that here we malloc some buffers. BUT, we never
|
||||
* free them. Why, you may ask? Because we want to allocate
|
||||
* them based on world size which is now (or soon to be) dynamic,
|
||||
* but we don't want to allocate each and every time, since that
|
||||
* would be slow. And, since world size only changes at init
|
||||
* time, we can do this safely.
|
||||
* We also share these buffers between "bestpath" and "bestownedpath"
|
||||
* since you can never be in both functions at the same time. If that
|
||||
* did happen, we'd already be so broken that it won't matter.
|
||||
*/
|
||||
static unsigned int *mapbuf = (unsigned int *)0;
|
||||
static unsigned int **mapindex = (unsigned int **)0;
|
||||
|
||||
s_char *bestownedpath(s_char *bpath,
|
||||
s_char *bigmap,
|
||||
int x,
|
||||
int y,
|
||||
int ex,
|
||||
int ey,
|
||||
s_char *terrain,
|
||||
int own)
|
||||
{
|
||||
int i, j, tx, ty, markedsectors, restr2;
|
||||
int minx, maxx, miny, maxy, scanx, scany;
|
||||
unsigned int routelen;
|
||||
|
||||
if (!mapbuf)
|
||||
mapbuf = (unsigned int *)malloc((WORLD_X * WORLD_Y) *
|
||||
sizeof(unsigned int));
|
||||
if (!mapbuf)
|
||||
return ((s_char *)0);
|
||||
if (!mapindex) {
|
||||
mapindex = (unsigned int **)malloc(WORLD_X * sizeof(unsigned int *));
|
||||
if (mapindex) {
|
||||
/* Setup the map pointers */
|
||||
for (i = 0; i < WORLD_X; i++)
|
||||
mapindex[i] = &mapbuf[WORLD_Y * i];
|
||||
}
|
||||
}
|
||||
if (!mapindex)
|
||||
return ((s_char *)0);
|
||||
|
||||
bpath[0] = 0;
|
||||
if (0 != (restr2 = (*terrain == 'R')))
|
||||
terrain++;
|
||||
|
||||
x = XNORM(x);
|
||||
y = YNORM(y);
|
||||
ex = XNORM(ex);
|
||||
ey = YNORM(ey);
|
||||
|
||||
if (x == ex && y == ey) {
|
||||
bpath[0] = 'h';
|
||||
bpath[1] = 0;
|
||||
return ((s_char *)bpath);
|
||||
}
|
||||
|
||||
if (!valid(x,y) || !valid(ex,ey))
|
||||
return((s_char *)0);
|
||||
|
||||
if (restr2 && (!owned_and_navigable(bigmap, x, y, terrain, own) ||
|
||||
!owned_and_navigable(bigmap, x, y, terrain, own)))
|
||||
return ((s_char *)0);
|
||||
|
||||
for (i = 0; i < WORLD_X; i++)
|
||||
for (j = 0; j < WORLD_Y; j++)
|
||||
mapindex[i][j] = 0xFFFF; /* clear the workspace */
|
||||
|
||||
routelen = 0; /* path length is now 0 */
|
||||
mapindex[x][y] = 0; /* mark starting spot */
|
||||
markedsectors = 1; /* source sector marked */
|
||||
minx = x - 2; /* set X scan bounds */
|
||||
maxx = x + 2;
|
||||
miny = y - 1; /* set Y scan bounds */
|
||||
maxy = y + 1;
|
||||
|
||||
do {
|
||||
if (++routelen == MAXROUTE) {
|
||||
bpath[0] = '?';
|
||||
bpath[1] = 0;
|
||||
return ((s_char *)bpath);
|
||||
}
|
||||
markedsectors = 0;
|
||||
for (scanx = minx; scanx <= maxx; scanx++) {
|
||||
x = XNORM(scanx);
|
||||
for (scany = miny; scany <= maxy; scany++) {
|
||||
y = YNORM(scany);
|
||||
if (valid(x,y)) {
|
||||
if ((((mapindex[x][y]) & 0x1FFF) == (routelen - 1))) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
tx = x + dx[i];
|
||||
ty = y + dy[i];
|
||||
tx = XNORM(tx);
|
||||
ty = YNORM(ty);
|
||||
if (mapindex[tx][ty] == 0xFFFF) {
|
||||
if (owned_and_navigable(bigmap, tx, ty, terrain, own) ||
|
||||
(tx == ex && ty == ey && !restr2) ) {
|
||||
mapindex[tx][ty] = ((i + 1) << 13) + routelen;
|
||||
markedsectors++;
|
||||
}
|
||||
}
|
||||
if (tx == ex && ty == ey) {
|
||||
bpath[routelen] = 0;
|
||||
while (routelen--) {
|
||||
i = ((mapindex[tx][ty]) >> 13) - 1;
|
||||
bpath[routelen] = dirchar[i];
|
||||
tx = tx - dx[i];
|
||||
ty = ty - dy[i];
|
||||
tx = XNORM(tx);
|
||||
ty = YNORM(ty);
|
||||
}
|
||||
return((s_char *)bpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
miny--;
|
||||
maxy++;
|
||||
minx -= 2;
|
||||
maxx += 2;
|
||||
} while (markedsectors);
|
||||
|
||||
bpath[0] = 0;
|
||||
return((s_char *)0); /* no route possible */
|
||||
}
|
||||
|
||||
/* return TRUE if sector is passable */
|
||||
static int
|
||||
owned_and_navigable(s_char *map, int x, int y, s_char *terrain, int own)
|
||||
{
|
||||
s_char c;
|
||||
s_char *t;
|
||||
s_char mapspot; /* What this spot on the bmap is */
|
||||
int negate;
|
||||
struct sctstr *sect;
|
||||
int rel;
|
||||
|
||||
/* No terrain to check? Everything is navigable! (this
|
||||
probably means we are flying) */
|
||||
if (!(*terrain))
|
||||
return (1);
|
||||
|
||||
/* Are we checking this map? */
|
||||
if (map) {
|
||||
/* Do we know what this sector is? If not, we assume it's ok,
|
||||
since otherwise we'll never venture anywhere */
|
||||
mapspot = map[sctoff(x, y)];
|
||||
if (mapspot == ' ' || mapspot == 0)
|
||||
return (1);
|
||||
|
||||
/* Now, is it marked with a 'x' or 'X'? If so, avoid it! */
|
||||
if (mapspot == 'x' || mapspot == 'X')
|
||||
return (0);
|
||||
} else {
|
||||
/* We don't know what it is since we have no map, so return ok! */
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Now, check this bmap entry to see if it is one of the
|
||||
terrain types. */
|
||||
t = terrain;
|
||||
if (*t == '~') {
|
||||
negate = 1;
|
||||
t++;
|
||||
} else
|
||||
negate = 0;
|
||||
|
||||
while (*t) {
|
||||
if (*t == mapspot)
|
||||
break;
|
||||
t++;
|
||||
}
|
||||
if (negate && *t) {
|
||||
/* We found it, so we say it's bad since we are negating */
|
||||
return (0);
|
||||
} else if (!negate && !*t) {
|
||||
/* We didn't find it, so we say it's bad since we aren't negating */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* According to our bmap, this sector is ok so far. */
|
||||
|
||||
/* Ok, we made it this far. Now get the sector */
|
||||
sect = getsectp(x, y);
|
||||
c = dchr[sect->sct_type].d_mnem;
|
||||
/* Ok, now, check the owner if needed */
|
||||
if (own >= 0) {
|
||||
if (sect->sct_own != own) {
|
||||
rel = getrel(getnatp(sect->sct_own), own);
|
||||
/* We can't sail through deity sectors, but we can sail
|
||||
through any ocean */
|
||||
if (rel < FRIENDLY && sect->sct_type != SCT_WATER)
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
/* Ok, now, check these two sector types */
|
||||
/* check for bad harbors. */
|
||||
if (c == 'h' && sect->sct_effic < 2)
|
||||
return (0);
|
||||
/* check for bad bridges */
|
||||
if (c == '=' && sect->sct_effic < 60)
|
||||
return (0);
|
||||
/* Woo-hoo, it's ok! */
|
||||
return (1);
|
||||
}
|
||||
|
167
src/lib/common/bridgefall.c
Normal file
167
src/lib/common/bridgefall.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* bridgefall.c: Knock a bridge down
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Steve McClure, 1998
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "path.h"
|
||||
#include "file.h"
|
||||
#include "xy.h"
|
||||
#include "plane.h"
|
||||
#include "land.h"
|
||||
#include "nsc.h"
|
||||
#include "common.h"
|
||||
#include "subs.h"
|
||||
#include "lost.h"
|
||||
#include "optlist.h"
|
||||
|
||||
void
|
||||
bridgefall(struct sctstr *sp, struct emp_qelem *list)
|
||||
{
|
||||
register int i;
|
||||
register 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 nstr_item ni;
|
||||
int mines;
|
||||
struct natstr *np;
|
||||
|
||||
if (sp->sct_type == SCT_BTOWER)
|
||||
mpr(sp->sct_own, "Crumble... SCREEEECH! Splash! Bridge tower falls at %s!\n",
|
||||
xyas(sp->sct_x, sp->sct_y, sp->sct_own));
|
||||
else
|
||||
mpr(sp->sct_own, "Crumble... SCREEEECH! Splash! Bridge falls at %s!\n",
|
||||
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, (s_char *)&land)){
|
||||
if (land.lnd_own == 0)
|
||||
continue;
|
||||
if(land.lnd_x != sp->sct_x || land.lnd_y != sp->sct_y)
|
||||
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));
|
||||
makelost(EF_LAND, land.lnd_own, land.lnd_uid, land.lnd_x, land.lnd_y);
|
||||
land.lnd_own = 0;
|
||||
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, (s_char *)&plane)){
|
||||
if (plane.pln_own == 0)
|
||||
continue;
|
||||
if(plane.pln_x != sp->sct_x || plane.pln_y != sp->sct_y)
|
||||
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));
|
||||
makelost(EF_PLANE, plane.pln_own, plane.pln_uid, plane.pln_x, plane.pln_y);
|
||||
plane.pln_own = 0;
|
||||
plane.pln_effic = 0;
|
||||
putplane(plane.pln_uid, &plane);
|
||||
}
|
||||
/*
|
||||
* save only the mines; zero the rest of the
|
||||
* commodities.
|
||||
*/
|
||||
mines = getvar(V_MINE, (caddr_t)sp, EF_SECTOR);
|
||||
sp->sct_nv = 0;
|
||||
if (mines > 0)
|
||||
(void) putvar(V_MINE, mines, (caddr_t)sp, EF_SECTOR);
|
||||
}
|
||||
|
165
src/lib/common/check.c
Normal file
165
src/lib/common/check.c
Normal file
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* check.c: Check a sector, plane, land unit, ship or nuke
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Steve McClure, 1998
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "player.h"
|
||||
#include "xy.h"
|
||||
#include "file.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "ship.h"
|
||||
#include "plane.h"
|
||||
#include "nuke.h"
|
||||
#include "land.h"
|
||||
#include "item.h"
|
||||
#include "nsc.h"
|
||||
#include "nat.h"
|
||||
#include "commodity.h"
|
||||
#include "loan.h"
|
||||
#include "optlist.h"
|
||||
#include "commands.h"
|
||||
#include "trade.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("Nuclear stockpile %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;
|
||||
}
|
||||
|
||||
|
199
src/lib/common/damage.c
Normal file
199
src/lib/common/damage.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* damage.c: Damage stuff.
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
* Steve McClure, 1997
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "ship.h"
|
||||
#include "land.h"
|
||||
#include "plane.h"
|
||||
#include "nuke.h"
|
||||
#include "xy.h"
|
||||
#include "nsc.h"
|
||||
#include <fcntl.h>
|
||||
#include "file.h"
|
||||
#include "optlist.h"
|
||||
#include "damage.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
#include "subs.h"
|
||||
|
||||
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);
|
||||
sp->shp_nv = vl_damage(dam, sp->shp_vtype, sp->shp_vamt,
|
||||
(int) sp->shp_nv);
|
||||
}
|
||||
|
||||
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);
|
||||
lp->lnd_nv = vl_damage(dam, lp->lnd_vtype, lp->lnd_vamt,
|
||||
(int) lp->lnd_nv);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
landdamage(struct lndstr *lp, int dam)
|
||||
{
|
||||
double damage_factor, m;
|
||||
extern int land_mob_max;
|
||||
|
||||
m = (double)land_mob_max;
|
||||
|
||||
/* fortification reduces damage */
|
||||
damage_factor = m / (m+((double)lp->lnd_harden));
|
||||
if (damage_factor == 0.0)
|
||||
damage_factor = 1.0;
|
||||
|
||||
/* 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(register int amt, int pct)
|
||||
{
|
||||
register int tmp;
|
||||
register 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(register int amt, int dam)
|
||||
{
|
||||
return damage(amt, PERCENT_DAMAGE(dam));
|
||||
}
|
||||
|
||||
int
|
||||
commdamage(register int amt, int dam, int vtype)
|
||||
{
|
||||
extern double people_damage;
|
||||
int lost;
|
||||
|
||||
if (vtype == V_BAR && opt_SUPER_BARS)
|
||||
return amt;
|
||||
|
||||
lost = amt - effdamage(amt, dam);
|
||||
|
||||
if (vtype == V_MILIT ||
|
||||
vtype == V_CIVIL ||
|
||||
vtype == V_UW)
|
||||
lost = ldround(people_damage * lost, 1);
|
||||
return amt - lost;
|
||||
}
|
494
src/lib/common/file.c
Normal file
494
src/lib/common/file.c
Normal file
|
@ -0,0 +1,494 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* file.c: Misc. operations on files
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
* Steve McClure, 2000
|
||||
*/
|
||||
|
||||
#ifdef Rel4
|
||||
#include <string.h>
|
||||
#endif /* Rel4 */
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "misc.h"
|
||||
#include "xy.h"
|
||||
#include "nsc.h"
|
||||
#include "file.h"
|
||||
#include "match.h"
|
||||
#include "struct.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
|
||||
#ifdef Rel4
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static void fillcache(struct empfile *ep, int start);
|
||||
|
||||
int
|
||||
ef_open(int type, int mode, int how)
|
||||
{
|
||||
register struct empfile *ep;
|
||||
static int block;
|
||||
int size;
|
||||
|
||||
#if defined(_WIN32)
|
||||
mode |= _O_BINARY;
|
||||
#endif
|
||||
if (ef_check(type) < 0)
|
||||
return 0;
|
||||
ep = &empfile[type];
|
||||
if ((ep->fd = open(ep->file, mode, 0660)) < 0) {
|
||||
logerror("%s: open failed", ep->file);
|
||||
return 0;
|
||||
}
|
||||
if (block == 0)
|
||||
block = blksize(ep->fd);
|
||||
ep->baseid = 0;
|
||||
ep->cids = 0;
|
||||
ep->mode = mode;
|
||||
ep->flags |= how;
|
||||
ep->fids = fsize(ep->fd) / ep->size;
|
||||
if (ep->flags & EFF_MEM)
|
||||
ep->csize = ep->fids;
|
||||
else
|
||||
ep->csize = block / ep->size;
|
||||
size = ep->csize * ep->size;
|
||||
ep->cache = (s_char *)malloc(size);
|
||||
if ((ep->cache == 0) && (size !=0)) {
|
||||
logerror("ef_open: %s malloc(%d) failed\n", ep->file, size);
|
||||
return 0;
|
||||
}
|
||||
if (ep->flags & EFF_MEM) {
|
||||
if (read(ep->fd, ep->cache, size) != size) {
|
||||
logerror("ef_open: read(%s) failed\n", ep->file);
|
||||
return 0;
|
||||
}
|
||||
ep->cids = size / ep->size;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ef_close(int type)
|
||||
{
|
||||
register struct empfile *ep;
|
||||
int r;
|
||||
|
||||
if (ef_check(type) < 0)
|
||||
return 0;
|
||||
ep = &empfile[type];
|
||||
if (ep->cache == 0) {
|
||||
/* no cache implies never opened */
|
||||
return 0;
|
||||
}
|
||||
ef_flush(type);
|
||||
ep->flags &= ~EFF_MEM;
|
||||
free(ep->cache);
|
||||
ep->cache = 0;
|
||||
if ((r = close(ep->fd)) < 0) {
|
||||
logerror("ef_close: %s close(%d) -> %d",
|
||||
ep->name, ep->fd, r);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ef_flush(int type)
|
||||
{
|
||||
register struct empfile *ep;
|
||||
int size;
|
||||
int r;
|
||||
|
||||
if (ef_check(type) < 0)
|
||||
return 0;
|
||||
ep = &empfile[type];
|
||||
if (ep->cache == 0) {
|
||||
/* no cache implies never opened */
|
||||
return 0;
|
||||
}
|
||||
size = ep->csize * ep->size;
|
||||
if (ep->mode > 0 && (ep->flags & EFF_MEM)) {
|
||||
if ((r = lseek(ep->fd, 0L, 0)) < 0) {
|
||||
logerror("ef_flush: %s cache lseek(%d, 0L, 0) -> %d",
|
||||
ep->name, ep->fd, r);
|
||||
return 0;
|
||||
}
|
||||
if (write(ep->fd, ep->cache, size) != size) {
|
||||
logerror("ef_flush: %s cache write(%d, %x, %d) -> %d",
|
||||
ep->name, ep->fd, ep->cache, ep->size, r);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*ef_zapcache(type);*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
s_char *
|
||||
ef_ptr(int type, int id)
|
||||
{
|
||||
register struct empfile *ep;
|
||||
|
||||
if (ef_check(type) < 0)
|
||||
return 0;
|
||||
ep = &empfile[type];
|
||||
if (id < 0 || id >= ep->fids)
|
||||
return 0;
|
||||
if ((ep->flags & EFF_MEM) == 0) {
|
||||
logerror("ef_ptr: (%s) only valid for EFF_MEM entries",
|
||||
ep->file);
|
||||
return 0;
|
||||
}
|
||||
return (s_char *) (ep->cache + ep->size * id);
|
||||
}
|
||||
|
||||
/*
|
||||
* buffered read. Tries to read a large number of items.
|
||||
* This system won't work if item size is > sizeof buffer area.
|
||||
*/
|
||||
int
|
||||
ef_read(int type, int id, caddr_t ptr)
|
||||
{
|
||||
register struct empfile *ep;
|
||||
caddr_t from;
|
||||
|
||||
if (ef_check(type) < 0)
|
||||
return 0;
|
||||
ep = &empfile[type];
|
||||
if (id < 0)
|
||||
return 0;
|
||||
if (ep->flags & EFF_MEM) {
|
||||
if (id >= ep->fids)
|
||||
return 0;
|
||||
from = ep->cache + (id * ep->size);
|
||||
} else {
|
||||
if (id >= ep->fids) {
|
||||
ep->fids = fsize(ep->fd) / ep->size;
|
||||
if (id >= ep->fids)
|
||||
return 0;
|
||||
}
|
||||
if (ep->baseid + ep->cids <= id || ep->baseid > id)
|
||||
fillcache(ep, id);
|
||||
from = ep->cache + (id - ep->baseid) * ep->size;
|
||||
}
|
||||
bcopy(from, ptr, ep->size);
|
||||
|
||||
if (ep->postread)
|
||||
ep->postread(id, ptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
fillcache(struct empfile *ep, int start)
|
||||
{
|
||||
int n;
|
||||
|
||||
ep->baseid = start;
|
||||
lseek(ep->fd, start * ep->size, 0);
|
||||
n = read(ep->fd, ep->cache, ep->csize * ep->size);
|
||||
ep->cids = n / ep->size;
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* no-buffered read
|
||||
* zaps read cache
|
||||
*/
|
||||
int
|
||||
ef_nbread(int type, int id, caddr_t ptr)
|
||||
{
|
||||
register struct empfile *ep;
|
||||
int r;
|
||||
|
||||
if (ef_check(type) < 0)
|
||||
return 0;
|
||||
ep = &empfile[type];
|
||||
if (id < 0)
|
||||
return 0;
|
||||
if (id >= ep->fids) {
|
||||
ep->fids = fsize(ep->fd) / ep->size;
|
||||
if (id >= ep->fids)
|
||||
return 0;
|
||||
}
|
||||
if ((r = lseek(ep->fd, id * ep->size, 0)) < 0) {
|
||||
logerror("ef_nbread: %s #%d lseek(%d, %d, 0) -> %d",
|
||||
ep->name, id, ep->fd, id * ep->size, r);
|
||||
return 0;
|
||||
}
|
||||
if ((r = read(ep->fd, ptr, ep->size)) != ep->size) {
|
||||
logerror("ef_nbread: %s #%d read(%d, %x, %d) -> %d",
|
||||
ep->name, id, ep->fd, ptr, ep->size, r);
|
||||
return 0;
|
||||
}
|
||||
ef_zapcache(type);
|
||||
if (ep->postread)
|
||||
ep->postread(id, ptr);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* buffered write. Modifies read cache (if applicable)
|
||||
* and writes through to disk.
|
||||
*/
|
||||
int
|
||||
ef_write(int type, int id, caddr_t ptr)
|
||||
{
|
||||
register int r;
|
||||
register struct empfile *ep;
|
||||
s_char *to;
|
||||
|
||||
if (ef_check(type) < 0)
|
||||
return 0;
|
||||
ep = &empfile[type];
|
||||
if (id > 65536) {
|
||||
/* largest unit id; this may bite us in large games */
|
||||
logerror("ef_write: type %d id %d is too large!\n", type, id);
|
||||
return 0;
|
||||
}
|
||||
if ((r = lseek(ep->fd, id * ep->size, 0)) < 0) {
|
||||
logerror("ef_write: %s #%d lseek(%d, %d, 0) -> %d",
|
||||
ep->name, id, ep->fd, id * ep->size, r);
|
||||
return 0;
|
||||
}
|
||||
if (ep->prewrite)
|
||||
ep->prewrite(id, ptr);
|
||||
if ((r = write(ep->fd, ptr, ep->size)) != ep->size) {
|
||||
logerror("ef_write: %s #%d write(%d, %x, %d) -> %d",
|
||||
ep->name, id, ep->fd, ptr, ep->size, r);
|
||||
return 0;
|
||||
}
|
||||
if (id >= ep->baseid && id < ep->baseid + ep->cids) {
|
||||
/* update the cache if necessary */
|
||||
to = ep->cache + (id - ep->baseid) * ep->size;
|
||||
bcopy(ptr, to, ep->size);
|
||||
}
|
||||
if (id > ep->fids) {
|
||||
logerror("WARNING ef_write: expanded %s by more than one id",
|
||||
ep->name);
|
||||
log_last_commands();
|
||||
}
|
||||
if (id >= ep->fids) {
|
||||
if (ep->flags & EFF_MEM) {
|
||||
logerror("file %s went beyond %d items; won't be able toread item w/o restart", ep->name, ep->fids);
|
||||
} else {
|
||||
/* write expanded file; ep->fids = last id + 1 */
|
||||
ep->fids = id + 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* no-buffered write
|
||||
* zaps read cache
|
||||
*/
|
||||
int
|
||||
ef_nbwrite(int type, int id, caddr_t ptr)
|
||||
{
|
||||
register struct empfile *ep;
|
||||
register int r;
|
||||
|
||||
if (ef_check(type) < 0)
|
||||
return 0;
|
||||
ep = &empfile[type];
|
||||
if (id > 65536) {
|
||||
/* largest unit id; this may bite us in large games */
|
||||
logerror("ef_nbwrite: %s id %d is too large!\n", ep->name, id);
|
||||
return 0;
|
||||
}
|
||||
if ((r = lseek(ep->fd, id * ep->size, 0)) < 0) {
|
||||
logerror("ef_nbwrite: %s #%d lseek(%d, %d, 0) -> %d",
|
||||
ep->name, id, ep->fd, id * ep->size, r);
|
||||
return 0;
|
||||
}
|
||||
if (ep->prewrite)
|
||||
ep->prewrite(id, ptr);
|
||||
if ((r = write(ep->fd, ptr, ep->size)) != ep->size) {
|
||||
logerror("ef_nbwrite: %s #%d write(%d, %x, %d) -> %d",
|
||||
ep->name, id, ep->fd, ptr, ep->size, r);
|
||||
return 0;
|
||||
}
|
||||
ef_zapcache(type);
|
||||
if (id >= ep->fids) {
|
||||
/* write expanded file; ep->fids = last id + 1 */
|
||||
ep->fids = id + 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ef_extend(int type, int count)
|
||||
{
|
||||
register struct empfile *ep;
|
||||
char *ptr;
|
||||
int cur, max;
|
||||
int mode, how;
|
||||
int r;
|
||||
|
||||
if (ef_check(type) < 0)
|
||||
return 0;
|
||||
ep = &empfile[type];
|
||||
max = ep->fids + count;
|
||||
cur = ep->fids;
|
||||
ptr = (s_char *)calloc(1, ep->size);
|
||||
if ((r = lseek(ep->fd, ep->fids * ep->size, 0)) < 0) {
|
||||
logerror("ef_extend: %s +#%d lseek(%d, %d, 0) -> %d",
|
||||
ep->name, count, ep->fd, ep->fids * ep->size, r);
|
||||
return 0;
|
||||
}
|
||||
for (cur = ep->fids; cur < max; cur++) {
|
||||
if (ep->init)
|
||||
ep->init(cur, ptr);
|
||||
if ((r = write(ep->fd, ptr, ep->size)) != ep->size) {
|
||||
logerror("ef_extend: %s +#%d write(%d, %x, %d) -> %d",
|
||||
ep->name, count, ep->fd, ptr, ep->size, r);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
free(ptr);
|
||||
if (ep->flags & EFF_MEM) {
|
||||
/* XXX this will cause problems if there are ef_ptrs (to the
|
||||
* old allocated structure) active when we do the re-open */
|
||||
mode = ep->mode;
|
||||
how = ep->flags;
|
||||
ef_close(type);
|
||||
ef_open(type, mode, how);
|
||||
} else {
|
||||
ep->fids += count;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
ef_zapcache(int type)
|
||||
{
|
||||
register struct empfile *ep = &empfile[type];
|
||||
if ((ep->flags & EFF_MEM) == 0) {
|
||||
ep->cids = 0;
|
||||
ep->baseid = -1;
|
||||
}
|
||||
}
|
||||
|
||||
struct castr *
|
||||
ef_cadef(int type)
|
||||
{
|
||||
return empfile[type].cadef;
|
||||
}
|
||||
|
||||
int
|
||||
ef_nelem(int type)
|
||||
{
|
||||
return empfile[type].fids;
|
||||
}
|
||||
|
||||
int
|
||||
ef_flags(int type)
|
||||
{
|
||||
return empfile[type].flags;
|
||||
}
|
||||
|
||||
int
|
||||
ef_lock(int type)
|
||||
{
|
||||
return file_lock(empfile[type].fd);
|
||||
}
|
||||
|
||||
int
|
||||
ef_unlock(int type)
|
||||
{
|
||||
return file_unlock(empfile[type].fd);
|
||||
}
|
||||
|
||||
time_t
|
||||
ef_mtime(int type)
|
||||
{
|
||||
extern time_t fdate(int fd);
|
||||
|
||||
if (empfile[type].fd <= 0)
|
||||
return 0;
|
||||
return fdate(empfile[type].fd);
|
||||
}
|
||||
|
||||
int
|
||||
ef_vars(int type, register s_char *sp, u_char **nvp, u_char **vp, u_short **ap)
|
||||
{
|
||||
register struct empfile *ef;
|
||||
|
||||
if (ef_check(type) < 0)
|
||||
return 0;
|
||||
ef = &empfile[type];
|
||||
if ((ef->flags & EFF_COM) == 0)
|
||||
return -1;
|
||||
*nvp = (u_char *) (sp + ef->varoffs[0]);
|
||||
*vp = (u_char *) (sp + ef->varoffs[1]);
|
||||
*ap = (u_short *) (sp + ef->varoffs[2]);
|
||||
return ef->maxvars;
|
||||
}
|
||||
|
||||
int
|
||||
ef_byname(s_char *name)
|
||||
{
|
||||
register struct empfile *ef;
|
||||
register int i;
|
||||
int len;
|
||||
|
||||
len = strlen(name);
|
||||
for (i=0; i<EF_MAX; i++) {
|
||||
ef = &empfile[i];
|
||||
if (strncmp(ef->name, name, min(len, strlen(ef->name))) == 0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
s_char *
|
||||
ef_nameof(int type)
|
||||
{
|
||||
if (type < 0 || type >= EF_MAX)
|
||||
return "bad item type";
|
||||
return empfile[type].name;
|
||||
}
|
||||
|
||||
int
|
||||
ef_check(int type)
|
||||
{
|
||||
if (type < 0 || type >= EF_MAX) {
|
||||
logerror("ef_ptr: bad EF_type %d\n", type);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
92
src/lib/common/fsize.c
Normal file
92
src/lib/common/fsize.c
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* fsize.c: BSD dependant file and block sizing routines
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Doug Hay, 1998
|
||||
* Steve McClure, 1998
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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 block size of the filesystem
|
||||
* If it's not a filesystem, return 1024.
|
||||
*/
|
||||
int
|
||||
blksize(int fd)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return 2048;
|
||||
#elif (!defined (aix) && !defined (sgi))
|
||||
struct stat statb;
|
||||
|
||||
if (fstat(fd, &statb) < 0)
|
||||
return 1024;
|
||||
return statb.st_blksize;
|
||||
#else
|
||||
return 1024;
|
||||
#endif
|
||||
}
|
||||
|
||||
time_t
|
||||
fdate(int fd)
|
||||
{
|
||||
struct stat statb;
|
||||
|
||||
if (fstat(fd, &statb) < 0)
|
||||
return 0;
|
||||
return statb.st_mtime;
|
||||
}
|
||||
|
||||
void
|
||||
filetruncate(s_char *name)
|
||||
{
|
||||
close(open(name, O_RDWR|O_TRUNC, 0660));
|
||||
}
|
118
src/lib/common/getvar.c
Normal file
118
src/lib/common/getvar.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* getvar.c: Routines for manipulating variable lists.
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "file.h"
|
||||
#include "common.h"
|
||||
|
||||
int
|
||||
getvar(int vtype, s_char *sp, int ptype)
|
||||
{
|
||||
u_char *vtypep;
|
||||
u_short *vamtp;
|
||||
u_char *nvp;
|
||||
int amt;
|
||||
|
||||
if (ef_vars(ptype, sp, &nvp, &vtypep, &vamtp) < 0) {
|
||||
logerror("getvar: ptype %d has no vars", ptype);
|
||||
return 0;
|
||||
}
|
||||
amt = vl_find(vtype, vtypep, vamtp, (int) *nvp);
|
||||
if (amt < 0) {
|
||||
logerror("getvar: vl_find returns %d, vtype %d",
|
||||
amt, vtype);
|
||||
return 0;
|
||||
}
|
||||
return amt;
|
||||
}
|
||||
|
||||
int
|
||||
getvec(int class, int *vec, s_char *sp, int ptype)
|
||||
{
|
||||
u_char *vtypep;
|
||||
u_short *vamtp;
|
||||
u_char *nvp;
|
||||
int nv;
|
||||
|
||||
if (ef_vars(ptype, sp, &nvp, &vtypep, &vamtp) < 0) {
|
||||
logerror("getvec: ptype %d has no vars", ptype);
|
||||
return 0;
|
||||
}
|
||||
nv = vl_getvec(vtypep, vamtp, (int)*nvp, class, vec);
|
||||
if (nv < 0) {
|
||||
logerror("vl_getvec: returns %d, ptype %d\n",
|
||||
nv, ptype);
|
||||
return 0;
|
||||
}
|
||||
return nv;
|
||||
}
|
||||
|
||||
int
|
||||
putvar(int vtype, int amt, s_char *sp, int ptype)
|
||||
{
|
||||
u_char *vtypep;
|
||||
u_short *vamtp;
|
||||
u_char *nvp;
|
||||
int maxv;
|
||||
|
||||
if (vtype < 0 || vtype > V_MAX) {
|
||||
logerror("putvar: bad vtype %d\n", vtype);
|
||||
return 0;
|
||||
}
|
||||
if ((maxv = ef_vars(ptype, sp, &nvp, &vtypep, &vamtp)) < 0) {
|
||||
logerror("putvar: ptype %d has no vars", ptype);
|
||||
return 0;
|
||||
}
|
||||
if (amt < 0)
|
||||
amt = 0;
|
||||
return vl_set(vtype, (u_int)amt, vtypep, vamtp, nvp, maxv);
|
||||
}
|
||||
|
||||
int
|
||||
putvec(int class, int *vec, s_char *sp, int ptype)
|
||||
{
|
||||
u_char *vtypep;
|
||||
u_short *vamtp;
|
||||
u_char *nvp;
|
||||
int maxv,x;
|
||||
|
||||
if ((maxv = ef_vars(ptype, sp, &nvp, &vtypep, &vamtp)) < 0) {
|
||||
logerror("putvec: ptype %d has no vars", ptype);
|
||||
return 0;
|
||||
}
|
||||
for(x=0;x<I_MAX;x++)
|
||||
if (vec[x] < 0)
|
||||
vec[x] = 0;
|
||||
return vl_setvec(vtypep, vamtp, nvp, maxv, class, vec);
|
||||
}
|
66
src/lib/common/hap_fact.c
Normal file
66
src/lib/common/hap_fact.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* hap_fact.c: Happiness effect on che
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Steve McClure, 1996
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "misc.h"
|
||||
#include "player.h"
|
||||
#include "var.h"
|
||||
#include "xy.h"
|
||||
#include "sect.h"
|
||||
#include "nat.h"
|
||||
#include "news.h"
|
||||
#include "nsc.h"
|
||||
#include "item.h"
|
||||
#include "file.h"
|
||||
#include "common.h"
|
||||
|
||||
double hap_fact(struct natstr *tnat, struct natstr *vnat)
|
||||
{
|
||||
double hap_fact;
|
||||
|
||||
hap_fact = vnat->nat_level[NAT_HLEV];
|
||||
if (hap_fact && tnat->nat_level[NAT_HLEV])
|
||||
hap_fact = tnat->nat_level[NAT_HLEV] / hap_fact;
|
||||
else if (!hap_fact && !tnat->nat_level[NAT_HLEV])
|
||||
hap_fact = 1.0;
|
||||
else if (tnat->nat_level[NAT_HLEV]) /* Target has happy, better fighting */
|
||||
hap_fact = 2.0;
|
||||
else /* Target has no happy, worse fighting */
|
||||
hap_fact = 0.8;
|
||||
if (hap_fact > 2.0)
|
||||
hap_fact = 2.0;
|
||||
if (hap_fact < 0.8)
|
||||
hap_fact = 0.8;
|
||||
return hap_fact;
|
||||
}
|
100
src/lib/common/hours.c
Normal file
100
src/lib/common/hours.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* hours.c: Game hours determination; is it legal to play now?
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
* Doug Hay, 1998
|
||||
* Steve McClure, 1998
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "misc.h"
|
||||
#include "nat.h"
|
||||
#include "tel.h"
|
||||
#include "proto.h"
|
||||
#include "com.h"
|
||||
#include "deity.h"
|
||||
#include "keyword.h"
|
||||
#include "file.h"
|
||||
#include "common.h"
|
||||
|
||||
#if defined(Rel4) || defined(_WIN32)
|
||||
#include <time.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif /* Rel4 */
|
||||
|
||||
/*
|
||||
* returns true if game can be played now.
|
||||
* Sets the number of minutes until the hours
|
||||
* function must be re-called.
|
||||
*/
|
||||
int
|
||||
gamehours(time_t now, int *hour)
|
||||
{
|
||||
extern s_char *game_days,*game_hours;
|
||||
extern int errno;
|
||||
extern struct tm *localtime(const time_t *);
|
||||
register s_char *bp;
|
||||
register struct tm *tm;
|
||||
int day;
|
||||
int curtime;
|
||||
int okday[7];
|
||||
int tomorrow;
|
||||
|
||||
tm = localtime(&now);
|
||||
curtime = tm->tm_min + tm->tm_hour * 60;
|
||||
bp = game_days;
|
||||
if (*bp != 0) {
|
||||
for (day=0; day<7; day++)
|
||||
okday[day] = 0;
|
||||
while (NULL != (bp = kw_parse(CF_WEEKDAY, bp, &day)))
|
||||
okday[day] = 1;
|
||||
} else {
|
||||
for (day=0; day<7; day++)
|
||||
okday[day] = 1;
|
||||
}
|
||||
if (!okday[tm->tm_wday])
|
||||
return 0;
|
||||
bp = game_hours;
|
||||
if (*bp != 0) {
|
||||
while (NULL != (bp = kw_parse(CF_TIMERANGE, bp, hour)))
|
||||
if (curtime >= hour[0] && curtime < hour[1])
|
||||
break;
|
||||
if (bp == 0)
|
||||
return 0;
|
||||
} else {
|
||||
hour[0] = 0;
|
||||
hour[1] = 24*60;
|
||||
}
|
||||
tomorrow = tm->tm_wday + 1;
|
||||
if (tomorrow >= 7)
|
||||
tomorrow = 0;
|
||||
return 1;
|
||||
}
|
199
src/lib/common/keyword.c
Normal file
199
src/lib/common/keyword.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* keyword.c: Find keywords in a file
|
||||
*
|
||||
* Known contributors to this file:
|
||||
*
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "keyword.h"
|
||||
#include "gen.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "common.h"
|
||||
|
||||
struct kwtab {
|
||||
struct kwtab *next;
|
||||
s_char *name;
|
||||
s_char *text;
|
||||
};
|
||||
|
||||
struct kwtab *kw_list;
|
||||
|
||||
int
|
||||
kw_read(FILE *fp)
|
||||
{
|
||||
register struct kwtab *kw;
|
||||
register struct kwtab *next;
|
||||
s_char buf[255];
|
||||
s_char *p;
|
||||
int n;
|
||||
|
||||
for (kw = kw_list; kw != 0; kw = next) {
|
||||
next = kw->next;
|
||||
free(kw->name);
|
||||
free(kw->text);
|
||||
free(kw);
|
||||
}
|
||||
kw_list = 0;
|
||||
for (n=0; fgets(buf, sizeof(buf), fp) != 0; n++) {
|
||||
/* Allow for comments.. any line starting with # */
|
||||
if (buf[0] == '#')
|
||||
continue;
|
||||
p = rindex(buf, '\n');
|
||||
if (p != 0)
|
||||
*p = 0;
|
||||
if ((p = index(buf, ':')) == 0) {
|
||||
logerror("kw_read: Bad keyword line #%d\n", n);
|
||||
return 0;
|
||||
}
|
||||
*p++ = 0;
|
||||
while (*p && isspace(*p))
|
||||
p++;
|
||||
kw = (struct kwtab *) malloc(sizeof(*kw));
|
||||
kw->name = strcpy(malloc(strlen(buf)+1), buf);
|
||||
kw->text = strcpy(malloc(strlen(p)+1), p);
|
||||
kw->next = kw_list;
|
||||
kw_list = kw;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
s_char *
|
||||
kw_find(s_char *name)
|
||||
{
|
||||
register struct kwtab *kw;
|
||||
|
||||
for (kw = kw_list; kw != 0; kw = kw->next) {
|
||||
if (strcmp(kw->name, name) == 0)
|
||||
return kw->text;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CF_VALUE 1
|
||||
#define CF_TIME 2
|
||||
#define CF_TIMERANGE 3
|
||||
#define CF_WEEKDAY 4
|
||||
|
||||
/*
|
||||
* destructive parse
|
||||
*/
|
||||
s_char *
|
||||
kw_parse(int type, s_char *text, int *data)
|
||||
{
|
||||
s_char *get_time(s_char *ptr, int *data);
|
||||
s_char *weekday(s_char *ptr, int *data);
|
||||
s_char *next;
|
||||
|
||||
while (isspace(*text))
|
||||
text++;
|
||||
switch (type) {
|
||||
case CF_VALUE:
|
||||
*data = atoip(&text);
|
||||
break;
|
||||
case CF_TIME:
|
||||
text = get_time(text, &data[0]);
|
||||
break;
|
||||
case CF_TIMERANGE:
|
||||
if ((next = index(text, '-')) == 0)
|
||||
return 0;
|
||||
next++;
|
||||
if ((text = get_time(text, &data[0])) == 0)
|
||||
return 0;
|
||||
text = get_time(next, &data[1]);
|
||||
break;
|
||||
case CF_WEEKDAY:
|
||||
text = weekday(text, &data[0]);
|
||||
break;
|
||||
default:
|
||||
text = 0;
|
||||
break;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
struct day {
|
||||
s_char *string;
|
||||
int day[7];
|
||||
} day[] = {
|
||||
{ "smtwtfs", { -1, 0, -1, 2, -1, 4, -1 } },
|
||||
{ "uouehra", { 0, 1, 2, 3, 4, 5, 6 } }
|
||||
};
|
||||
|
||||
s_char *
|
||||
weekday(s_char *ptr, int *data)
|
||||
{
|
||||
register s_char *string;
|
||||
register int c;
|
||||
register int n;
|
||||
|
||||
c = *ptr++;
|
||||
if (isupper(c))
|
||||
c = tolower(c);
|
||||
string = day[0].string;
|
||||
for (n=0; n<7; n++) {
|
||||
if (string[n] != c)
|
||||
continue;
|
||||
if (day[0].day[n] >= 0)
|
||||
break;
|
||||
if (day[1].string[n] == *ptr)
|
||||
break;
|
||||
}
|
||||
if (n == 7)
|
||||
return 0;
|
||||
*data = day[1].day[n];
|
||||
while (*ptr && !isspace(*ptr))
|
||||
ptr++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
s_char *
|
||||
get_time(s_char *ptr, int *data)
|
||||
{
|
||||
int hour;
|
||||
int minute;
|
||||
|
||||
if (!isdigit(*ptr))
|
||||
return 0;
|
||||
hour = atoip(&ptr);
|
||||
minute = 0;
|
||||
if (*ptr) {
|
||||
if (*ptr != ':')
|
||||
return 0;
|
||||
ptr++;
|
||||
if (!isdigit(*ptr))
|
||||
return 0;
|
||||
minute = atoip(&ptr);
|
||||
}
|
||||
*data = (hour * 60) + minute;
|
||||
return ptr;
|
||||
}
|
98
src/lib/common/land.c
Normal file
98
src/lib/common/land.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* land.c: Misc. land unit routines
|
||||
*
|
||||
* Known contributors to this file:
|
||||
*
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "nat.h"
|
||||
#include "var.h"
|
||||
#include "file.h"
|
||||
#include "path.h"
|
||||
#include "xy.h"
|
||||
#include "land.h"
|
||||
#include "nsc.h"
|
||||
#include "common.h"
|
||||
#include "subs.h"
|
||||
|
||||
int
|
||||
adj_units(coord x, coord y, natid own)
|
||||
{
|
||||
register int i;
|
||||
struct sctstr sect;
|
||||
|
||||
for (i = DIR_FIRST; i <= DIR_LAST; i++) {
|
||||
getsect(x + diroff[i][0], y + diroff[i][1], §);
|
||||
if (has_units(sect.sct_x, sect.sct_y, own, 0))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
has_units(coord x, coord y, natid cn, struct lndstr *lp)
|
||||
{
|
||||
register int n;
|
||||
struct lndstr land;
|
||||
|
||||
for (n=0; ef_read(EF_LAND, n, (s_char *)&land); n++) {
|
||||
if(land.lnd_x != x || land.lnd_y != y)
|
||||
continue;
|
||||
if (lp) {
|
||||
/* Check this unit. If it is this one, we don't want
|
||||
it included in the count. */
|
||||
if (lp->lnd_uid == land.lnd_uid)
|
||||
continue;
|
||||
}
|
||||
if (land.lnd_own == cn)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
has_units_with_mob(coord x, coord y, natid cn)
|
||||
{
|
||||
struct nstr_item ni;
|
||||
struct lndstr land;
|
||||
|
||||
snxtitem_xy(&ni,EF_LAND,x,y);
|
||||
while(nxtitem(&ni,(s_char *)&land)) {
|
||||
if (land.lnd_own != cn)
|
||||
continue;
|
||||
if (land.lnd_mobil > 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
164
src/lib/common/log.c
Normal file
164
src/lib/common/log.c
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* log.c: Log an Empire error to a file
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#ifdef Rel4
|
||||
#include <string.h>
|
||||
#endif /* Rel4 */
|
||||
#include <time.h>
|
||||
#include "deity.h"
|
||||
#include "player.h"
|
||||
#include "common.h"
|
||||
|
||||
static s_char *logfile = 0;
|
||||
|
||||
s_char *
|
||||
getlogfile()
|
||||
{
|
||||
return (s_char *)logfile;
|
||||
}
|
||||
|
||||
/*
|
||||
* Points logfile at datadir/"program".log
|
||||
*/
|
||||
void
|
||||
loginit(void)
|
||||
{
|
||||
extern s_char program[];
|
||||
extern s_char *datadir;
|
||||
s_char buf[1024];
|
||||
|
||||
#if !defined(_WIN32)
|
||||
sprintf(buf, "%s/%s.log", datadir, program);
|
||||
#else
|
||||
sprintf(buf, "%s\\%s.log", datadir, program);
|
||||
#endif
|
||||
logfile = malloc(strlen(buf) + 1);
|
||||
strcpy(logfile, buf);
|
||||
}
|
||||
|
||||
/*VARARGS*/
|
||||
void logerror(s_char *format, ...)
|
||||
{
|
||||
#if !defined(Rel4) && !defined(__linux__) && !defined(__ppc__)
|
||||
extern s_char *sys_errlist[];
|
||||
#endif
|
||||
#ifndef sgi
|
||||
extern int errno;
|
||||
#endif /* sgi */
|
||||
va_list list;
|
||||
time_t now;
|
||||
s_char buf[512];
|
||||
s_char cbuf[512];
|
||||
s_char buf1[512];
|
||||
int logf;
|
||||
/* s_char *error; */
|
||||
s_char *p;
|
||||
|
||||
if (logfile == 0)
|
||||
loginit();
|
||||
va_start(list, format);
|
||||
vsprintf(buf, format, list);
|
||||
if ((p = index(buf, '\n')) != 0)
|
||||
*p = 0;
|
||||
(void) time(&now);
|
||||
/* error = "log";
|
||||
if (errno != 0)
|
||||
error = sys_errlist[errno];
|
||||
(void) sprintf(buf1, "%s; (%s) %s", buf, error, ctime(&now));
|
||||
*/
|
||||
strcpy(cbuf, ctime(&now));
|
||||
if ((p = index(cbuf, '\n')) != 0)
|
||||
*p = 0;
|
||||
(void) sprintf(buf1, "%s %s\n", cbuf, buf);
|
||||
if ((logf = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
|
||||
return;
|
||||
(void) write(logf, buf1, strlen(buf1));
|
||||
(void) close(logf);
|
||||
errno = 0;
|
||||
#ifdef notdef
|
||||
if (player) {
|
||||
pr("A system error has occured; please notify the deity.\n");
|
||||
pr(buf1);
|
||||
}
|
||||
#endif
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
/*VARARGS*/
|
||||
void filelogerror(s_char *format, ...)
|
||||
{
|
||||
#if !defined(Rel4) && !defined(__linux__) && !defined(__ppc__)
|
||||
extern s_char *sys_errlist[];
|
||||
#endif /* Rel4 */
|
||||
#ifndef sgi
|
||||
extern int errno;
|
||||
#endif /* sgi */
|
||||
va_list list;
|
||||
time_t now;
|
||||
s_char buf[512];
|
||||
s_char buf1[512];
|
||||
int logf;
|
||||
s_char *error;
|
||||
s_char *p;
|
||||
|
||||
if (logfile == 0)
|
||||
loginit();
|
||||
va_start(list, format);
|
||||
vsprintf(buf, format, list);
|
||||
if ((p = index(buf, '\n')) != 0)
|
||||
*p = 0;
|
||||
(void) time(&now);
|
||||
error = "log";
|
||||
if (errno != 0)
|
||||
#ifdef Rel4
|
||||
error = strerror (errno);
|
||||
#else
|
||||
error = (s_char *)sys_errlist[errno];
|
||||
#endif /* Rel4 */
|
||||
(void) sprintf(buf1, "%s; (%s) %s", buf, error, ctime(&now));
|
||||
if ((logf = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
|
||||
return;
|
||||
(void) write(logf, buf1, strlen(buf1));
|
||||
(void) close(logf);
|
||||
errno = 0;
|
||||
va_end(list);
|
||||
}
|
45
src/lib/common/mailbox.c
Normal file
45
src/lib/common/mailbox.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* mailbox.c: Return string containing telegram file
|
||||
*
|
||||
* Known contributors to this file:
|
||||
*
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "tel.h"
|
||||
#include <stdio.h>
|
||||
|
||||
s_char *
|
||||
mailbox(s_char *buf, natid cn)
|
||||
{
|
||||
(void) sprintf(buf, "%s%d", telfil, cn);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
420
src/lib/common/maps.c
Normal file
420
src/lib/common/maps.c
Normal file
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* maps.c: Map routines
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Ken Stevens, 1995
|
||||
* Steve McClure, 1998
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "player.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "xy.h"
|
||||
#include "nsc.h"
|
||||
#include "file.h"
|
||||
#include "deity.h"
|
||||
#include "nat.h"
|
||||
#include "map.h"
|
||||
#include "ship.h"
|
||||
#include "land.h"
|
||||
#include "plane.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
#include "subs.h"
|
||||
#include "optlist.h"
|
||||
|
||||
int
|
||||
draw_map(int bmap, s_char origin, int map_flags, struct nstr_sect *nsp, int country)
|
||||
{
|
||||
struct natstr *np;
|
||||
struct range range;
|
||||
struct nstr_item ni;
|
||||
struct shpstr ship;
|
||||
struct lndstr land;
|
||||
struct plnstr plane;
|
||||
coord x,y;
|
||||
int i;
|
||||
/* Note this is not re-entrant anyway, so we keep the buffers
|
||||
around */
|
||||
static u_char *bitmap = (u_char *)0;
|
||||
static s_char *wmapbuf = (s_char *)0;
|
||||
static s_char **wmap = (s_char **)0;
|
||||
|
||||
if (!wmapbuf)
|
||||
wmapbuf = (s_char *)malloc((WORLD_Y * MAPWIDTH(1)) * sizeof(s_char));
|
||||
if (!wmap) {
|
||||
wmap = (s_char **)malloc(WORLD_Y * sizeof(s_char *));
|
||||
if (wmap && wmapbuf) {
|
||||
for (i = 0; i < WORLD_Y; i++)
|
||||
wmap[i] = &wmapbuf[MAPWIDTH(1) * i];
|
||||
} else if (wmap) {
|
||||
free((s_char *)wmap);
|
||||
wmap = (s_char **)0;
|
||||
}
|
||||
}
|
||||
if (!bitmap)
|
||||
bitmap = (u_char *)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 == EF_MAP + EF_BMAP) {
|
||||
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(country);
|
||||
/* zap any conditionals */
|
||||
nsp->ncond = 0;
|
||||
xyrelrange(np, &nsp->range, &range);
|
||||
border(&range, " ", "");
|
||||
blankfill((s_char *)wmapbuf, &nsp->range, 1);
|
||||
if (bmap) {
|
||||
register int c;
|
||||
switch (bmap) {
|
||||
case EF_BMAP:
|
||||
while (bmnxtsct(nsp) && !player->aborted) {
|
||||
if (0 != (c = player->bmap[sctoff(nsp->x, nsp->y)]))
|
||||
wmap[nsp->dy][nsp->dx] = c;
|
||||
}
|
||||
break;
|
||||
case EF_MAP:
|
||||
while (bmnxtsct(nsp) && !player->aborted) {
|
||||
if (0 != (c = player->map[sctoff(nsp->x, nsp->y)]))
|
||||
wmap[nsp->dy][nsp->dx] = c;
|
||||
}
|
||||
break;
|
||||
case (EF_MAP + EF_BMAP):
|
||||
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 EF_NMAP:
|
||||
do {
|
||||
register s_char *ptr;
|
||||
struct sctstr sect;
|
||||
|
||||
if ((!player->god || country)) {
|
||||
bzero((s_char *)bitmap, (WORLD_X * WORLD_Y) / 8);
|
||||
bitinit2(nsp, bitmap, country);
|
||||
}
|
||||
while (nxtsct(nsp, §) && !player->aborted) {
|
||||
if ((!player->god || country) &&
|
||||
!emp_getbit(nsp->x, nsp->y, bitmap)) {
|
||||
if (!player->god)
|
||||
continue;
|
||||
}
|
||||
ptr = &wmap[nsp->dy][nsp->dx];
|
||||
if (sect.sct_newtype > SCT_MAXDEF) {
|
||||
*ptr = '?';
|
||||
} else {
|
||||
*ptr = dchr[sect.sct_newtype].d_mnem;
|
||||
switch (sect.sct_newtype) {
|
||||
case SCT_WATER:
|
||||
case SCT_RURAL:
|
||||
case SCT_MOUNT:
|
||||
case SCT_WASTE:
|
||||
case SCT_PLAINS:
|
||||
break;
|
||||
default:
|
||||
if (sect.sct_own != country &&
|
||||
(!player->god || country)) {
|
||||
if (!player->god)
|
||||
*ptr = '?';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
register s_char *ptr;
|
||||
struct sctstr sect;
|
||||
int changed = 0;
|
||||
|
||||
if ((!player->god || country)) {
|
||||
bzero((s_char *)bitmap, (WORLD_X * WORLD_Y) / 8);
|
||||
bitinit2(nsp, bitmap, country);
|
||||
}
|
||||
while (nxtsct(nsp, §) && !player->aborted) {
|
||||
if ((!player->god || country) && !emp_getbit(nsp->x, nsp->y, bitmap)) {
|
||||
if (!player->god)
|
||||
continue;
|
||||
}
|
||||
ptr = &wmap[nsp->dy][nsp->dx];
|
||||
if (sect.sct_type > SCT_MAXDEF) {
|
||||
*ptr = '?';
|
||||
} else {
|
||||
*ptr = dchr[sect.sct_type].d_mnem;
|
||||
switch (sect.sct_type) {
|
||||
case SCT_WATER:
|
||||
case SCT_RURAL:
|
||||
case SCT_MOUNT:
|
||||
case SCT_WASTE:
|
||||
case SCT_PLAINS:
|
||||
break;
|
||||
default:
|
||||
if (sect.sct_own != country &&
|
||||
(!player->god || country)) {
|
||||
if(!player->god)
|
||||
*ptr = '?';
|
||||
}
|
||||
break;
|
||||
}
|
||||
changed += map_set(player->cnum, nsp->x, nsp->y, *ptr, 0);
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
writemap(player->cnum);
|
||||
}
|
||||
if (player->aborted)
|
||||
return RET_OK;
|
||||
if (map_flags & MAP_PLANE){
|
||||
snxtitem_all(&ni, EF_PLANE);
|
||||
while (nxtitem(&ni, (caddr_t)&plane)) {
|
||||
if (plane.pln_own == 0)
|
||||
continue;
|
||||
if (plane.pln_own != player->cnum && !player->god)
|
||||
continue;
|
||||
if (!xyinrange(plane.pln_x, plane.pln_y, &nsp->range))
|
||||
continue;
|
||||
|
||||
x = xnorm(plane.pln_x-nsp->range.lx);
|
||||
y = ynorm(plane.pln_y-nsp->range.ly);
|
||||
wmap[y][x] = (*plchr[(int)plane.pln_type].pl_name) & ~0x20;
|
||||
}
|
||||
}
|
||||
if (map_flags & MAP_SHIP){
|
||||
snxtitem_all(&ni, EF_SHIP);
|
||||
while (nxtitem(&ni, (caddr_t)&ship)) {
|
||||
if (ship.shp_own == 0)
|
||||
continue;
|
||||
if (ship.shp_own != player->cnum && !player->god)
|
||||
continue;
|
||||
if (!xyinrange(ship.shp_x, ship.shp_y, &nsp->range))
|
||||
continue;
|
||||
|
||||
x = xnorm(ship.shp_x-nsp->range.lx);
|
||||
y = ynorm(ship.shp_y-nsp->range.ly);
|
||||
wmap[y][x] = (*mchr[(int)ship.shp_type].m_name) & ~0x20;
|
||||
}
|
||||
}
|
||||
if (map_flags & MAP_LAND){
|
||||
snxtitem_all(&ni, EF_LAND);
|
||||
while (nxtitem(&ni, (caddr_t)&land)) {
|
||||
if (land.lnd_own == 0)
|
||||
continue;
|
||||
if (land.lnd_own != player->cnum && !player->god)
|
||||
continue;
|
||||
if (!xyinrange(land.lnd_x, land.lnd_y, &nsp->range))
|
||||
continue;
|
||||
|
||||
x = xnorm(land.lnd_x-nsp->range.lx);
|
||||
y = ynorm(land.lnd_y-nsp->range.ly);
|
||||
wmap[y][x] = (*lchr[(int)land.lnd_type].l_name) & ~0x20;
|
||||
}
|
||||
}
|
||||
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
|
||||
*/
|
||||
int
|
||||
bmnxtsct(register 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*/
|
||||
}
|
||||
|
||||
void
|
||||
bitinit2(struct nstr_sect *np, u_char *bitmap, int country)
|
||||
{
|
||||
extern int *bitmaps[];
|
||||
struct sctstr sect;
|
||||
int eff;
|
||||
|
||||
while (nxtsct(np, §)) {
|
||||
if (sect.sct_own != country)
|
||||
continue;
|
||||
eff = sect.sct_effic / 20;
|
||||
if (eff > 4)
|
||||
eff = 4;
|
||||
emp_setbitmap(np->x, np->y, bitmap, bitmaps[eff]);
|
||||
}
|
||||
snxtsct_rewind(np);
|
||||
}
|
||||
|
||||
int
|
||||
unit_map(int unit_type, int i, struct nstr_sect *nsp, s_char *originp)
|
||||
{
|
||||
struct shpstr origs;
|
||||
struct lndstr origl;
|
||||
struct plnstr origp;
|
||||
s_char what[64];
|
||||
struct natstr *np;
|
||||
|
||||
np = getnatp(player->cnum);
|
||||
if (unit_type == EF_LAND){
|
||||
if (!getland(i, &origl) ||
|
||||
(origl.lnd_own != player->cnum && !player->god) ||
|
||||
(origl.lnd_own == 0))
|
||||
return RET_FAIL;
|
||||
sprintf(what, "%d:%d,%d:%d",xrel(np,origl.lnd_x-10),
|
||||
xrel(np,origl.lnd_x+10),
|
||||
yrel(np,origl.lnd_y-5), yrel(np,origl.lnd_y+5));
|
||||
*originp = *lchr[(int)origl.lnd_type].l_name;
|
||||
} else if (unit_type == EF_PLANE){
|
||||
if (!getplane(i, &origp) ||
|
||||
(origp.pln_own != player->cnum && !player->god) ||
|
||||
(origp.pln_own == 0))
|
||||
return RET_FAIL;
|
||||
sprintf(what, "%d:%d,%d:%d",xrel(np,origp.pln_x-10),
|
||||
xrel(np,origp.pln_x+10),
|
||||
yrel(np,origp.pln_y-5), yrel(np,origp.pln_y+5));
|
||||
*originp = *plchr[(int)origp.pln_type].pl_name;
|
||||
} else {
|
||||
if (!getship(i, &origs) ||
|
||||
(origs.shp_own != player->cnum && !player->god) ||
|
||||
(origs.shp_own == 0))
|
||||
return RET_FAIL;
|
||||
sprintf(what, "%d:%d,%d:%d",xrel(np,origs.shp_x-10),
|
||||
xrel(np,origs.shp_x+10),
|
||||
yrel(np,origs.shp_y-5), yrel(np,origs.shp_y+5));
|
||||
unit_type = EF_SHIP;
|
||||
*originp = *mchr[(int)origs.shp_type].m_name;
|
||||
}
|
||||
if (!snxtsct(nsp, what))
|
||||
return RET_FAIL;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int
|
||||
bmaps_intersect(natid a, natid b)
|
||||
{
|
||||
s_char *mapa = ef_ptr(EF_MAP, a);
|
||||
s_char *mapb = ef_ptr(EF_MAP, b);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < WORLD_X*WORLD_Y/2; ++i, ++mapa, ++mapb)
|
||||
if (*mapa && *mapa != ' ' && *mapb && *mapb != ' ')
|
||||
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, s_char des, s_char *from_name)
|
||||
{
|
||||
s_char *from_bmap = ef_ptr(EF_BMAP, from);
|
||||
s_char *to_bmap = ef_ptr(EF_BMAP, to);
|
||||
int n = 0;
|
||||
struct sctstr sect;
|
||||
s_char fromdes;
|
||||
s_char todes;
|
||||
s_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;
|
||||
}
|
||||
|
75
src/lib/common/move.c
Normal file
75
src/lib/common/move.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* move.c: Misc. move routines
|
||||
*
|
||||
* Known contributors to this file:
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gamesdef.h"
|
||||
#include "misc.h"
|
||||
#include "xy.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "file.h"
|
||||
#include "deity.h"
|
||||
#include "path.h"
|
||||
#include "nat.h"
|
||||
#include "common.h"
|
||||
|
||||
double
|
||||
sector_mcost(struct sctstr *sp, int do_bonus)
|
||||
{
|
||||
double d;
|
||||
|
||||
if (!(d = dchr[sp->sct_type].d_mcst))
|
||||
return -1.0;
|
||||
|
||||
/* Note, the best you can get is a 1.0 here. */
|
||||
|
||||
if (do_bonus == MOB_ROAD) {
|
||||
d = d / (1.0 + ((double)sp->sct_road / 122.0));
|
||||
} else if (do_bonus == MOB_RAIL) {
|
||||
d = d / (1.0 + ((double)sp->sct_rail / 100.0));
|
||||
} else {
|
||||
if (d < 2.0)
|
||||
d = 2.0;
|
||||
}
|
||||
if (d < 1.0)
|
||||
d = 1.0;
|
||||
if (dchr[sp->sct_type].d_mcst < 25)
|
||||
d = (d * 100.0 - (double)sp->sct_effic) / 500.0;
|
||||
/* d = (200.0 + (d - 3.0) * (double)sp->sct_effic) / 500.0;*/
|
||||
else
|
||||
d = (d * 10.0 - (double)sp->sct_effic) / 115;
|
||||
|
||||
if (d <= 0.0 || d < MIN_MOBCOST)
|
||||
return MIN_MOBCOST;
|
||||
return d;
|
||||
}
|
||||
|
170
src/lib/common/nat.c
Normal file
170
src/lib/common/nat.c
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* nat.c: Misc. accesses on the nation file
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "optlist.h"
|
||||
|
||||
s_char *
|
||||
cname(natid n)
|
||||
{
|
||||
struct natstr *np;
|
||||
|
||||
if ((np = getnatp(n)) == 0)
|
||||
return 0;
|
||||
return np->nat_cnam;
|
||||
}
|
||||
|
||||
s_char *
|
||||
relatename(struct natstr *np, natid other)
|
||||
{
|
||||
extern s_char *relates[];
|
||||
|
||||
return relates[getrel(np, other)];
|
||||
}
|
||||
|
||||
s_char *
|
||||
rejectname(struct natstr *np, natid other)
|
||||
{
|
||||
extern s_char *rejects[];
|
||||
|
||||
return rejects[getrejects(other, np)];
|
||||
}
|
||||
|
||||
s_char *
|
||||
natstate(struct natstr *np)
|
||||
{
|
||||
if ((np->nat_stat & STAT_INUSE) == 0)
|
||||
return "FREE";
|
||||
if (np->nat_stat & STAT_GOD)
|
||||
return "DEITY";
|
||||
if ((np->nat_stat & STAT_NORM) == 0)
|
||||
return "VISITOR";
|
||||
return "ACTIVE";
|
||||
}
|
||||
|
||||
/* This returns the relations that np has with them */
|
||||
int
|
||||
getrel(struct natstr *np, natid them)
|
||||
{
|
||||
return np->nat_relate[them];
|
||||
}
|
||||
|
||||
int
|
||||
getrejects(natid them, struct natstr *np)
|
||||
{
|
||||
int ind;
|
||||
int shift;
|
||||
int reject;
|
||||
|
||||
ind = them / 4;
|
||||
shift = 12 - ((them - ((them / 4) << 2)) * 4);
|
||||
/* the 07 should *really* be 017 */
|
||||
reject = (np->nat_rejects[ind] >> shift) & 0x0f;
|
||||
return reject;
|
||||
}
|
||||
|
||||
void
|
||||
agecontact(struct natstr *np)
|
||||
{
|
||||
int them;
|
||||
|
||||
if (opt_LOSE_CONTACT) {
|
||||
for (them = 1; them < MAXNOC; ++them) {
|
||||
if (them != np->nat_cnum && np->nat_contact[them]) {
|
||||
--np->nat_contact[them];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getcontact(struct natstr *np, natid them)
|
||||
{
|
||||
int contact;
|
||||
|
||||
if (opt_LOSE_CONTACT) {
|
||||
contact = np->nat_contact[them];
|
||||
} else {
|
||||
int ind = them/16;
|
||||
int shift = (them % 16);
|
||||
|
||||
contact = (np->nat_contact[ind] >> shift) & 1;
|
||||
}
|
||||
return contact;
|
||||
}
|
||||
|
||||
void
|
||||
putrel(struct natstr *np, natid them, int relate)
|
||||
{
|
||||
np->nat_relate[them] = relate;
|
||||
}
|
||||
|
||||
void
|
||||
putreject(struct natstr *np, natid them, int how, int what)
|
||||
{
|
||||
int shift;
|
||||
int newrej;
|
||||
int ind;
|
||||
|
||||
/* This 07 should be changed to 017 after the current game is over */
|
||||
what &= 0x0f;
|
||||
ind = them / 4;
|
||||
shift = 12 - ((them - ((them / 4) << 2)) * 4);
|
||||
newrej = np->nat_rejects[ind];
|
||||
if (how)
|
||||
newrej |= (what << shift);
|
||||
else
|
||||
newrej &= ~(what << shift);
|
||||
np->nat_rejects[ind] = newrej;
|
||||
}
|
||||
|
||||
void
|
||||
putcontact(struct natstr *np, natid them, int contact)
|
||||
{
|
||||
if (opt_LOSE_CONTACT) {
|
||||
if (np->nat_contact[them] > contact)
|
||||
return;
|
||||
np->nat_contact[them] = contact;
|
||||
} else {
|
||||
int ind = them/16;
|
||||
int shift = them%16;
|
||||
int new = np->nat_contact[ind];
|
||||
if (contact)
|
||||
contact = 1;
|
||||
new &= ~(1 << shift);
|
||||
new |= (contact << shift);
|
||||
np->nat_contact[ind] = new;
|
||||
}
|
||||
}
|
159
src/lib/common/nstr_subs.c
Normal file
159
src/lib/common/nstr_subs.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* nstr.c: Compile and execute the item selections on sectors
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "struct.h"
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "xy.h"
|
||||
#include "sect.h"
|
||||
#include "nsc.h"
|
||||
#include "nat.h"
|
||||
#include "match.h"
|
||||
#include "file.h"
|
||||
#include "player.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
|
||||
/*
|
||||
* return true if the conditions on this item
|
||||
* are all true.
|
||||
*/
|
||||
int
|
||||
nstr_exec(struct nscstr *conds, register int ncond, void *ptr, int type)
|
||||
{
|
||||
register struct nscstr *nsc;
|
||||
register int op;
|
||||
register int lhs;
|
||||
register int rhs;
|
||||
register int oper;
|
||||
|
||||
for (nsc=conds; --ncond >= 0; nsc++) {
|
||||
oper = nsc->oper;
|
||||
if (oper > 65535) {
|
||||
oper = oper - 65535;
|
||||
rhs = nsc->fld2;
|
||||
} else
|
||||
rhs = decode(player->cnum, nsc->fld2, ptr, type);
|
||||
|
||||
if (oper > 255) {
|
||||
oper = oper - 255;
|
||||
lhs = nsc->fld1;
|
||||
} else
|
||||
lhs = decode(player->cnum, nsc->fld1, ptr, type);
|
||||
|
||||
op = oper;
|
||||
if ((op == '<' && lhs >= rhs) ||
|
||||
(op == '=' && lhs != rhs) ||
|
||||
(op == '>' && lhs <= rhs) ||
|
||||
(op == '#' && lhs == rhs))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
decode(natid cnum, long int code, void *addr, int type)
|
||||
{
|
||||
register int val;
|
||||
register int nsc_code;
|
||||
struct natstr *np;
|
||||
long code_type = (code & NSC_TMASK);
|
||||
|
||||
val = (code & ~NSC_MASK) & 0xffff;
|
||||
|
||||
/* handle negative numbers properly */
|
||||
/* this assumes a binary two's complement number representation */
|
||||
if (val>=0x8000) val -= 0x10000;
|
||||
|
||||
nsc_code = code & NSC_CMASK;
|
||||
if (nsc_code == NSC_VAR) {
|
||||
val = getvar(val, addr, type);
|
||||
} else if (nsc_code == NSC_OFF) {
|
||||
/*
|
||||
* add offset to value
|
||||
*/
|
||||
addr = (s_char *)addr + val;
|
||||
switch (code_type) {
|
||||
case NSC_TIME:
|
||||
val = *((time_t *)addr);
|
||||
break;
|
||||
case NSC_CHAR:
|
||||
val = *((s_char *) addr);
|
||||
break;
|
||||
case NSC_UCHAR:
|
||||
val = (int) *((unsigned char *) addr);
|
||||
break;
|
||||
case NSC_SHORT:
|
||||
val = *((short *) addr);
|
||||
break;
|
||||
case NSC_USHORT:
|
||||
val = *((u_short *) addr);
|
||||
break;
|
||||
case NSC_INT:
|
||||
val = *((int *) addr);
|
||||
break;
|
||||
case NSC_LONG:
|
||||
val = *((long *) addr);
|
||||
break;
|
||||
case NSC_XCOORD:
|
||||
val = *((short *) addr);
|
||||
np = getnatp(cnum);
|
||||
val = xrel(np, val);
|
||||
break;
|
||||
case NSC_YCOORD:
|
||||
val = *((short *) addr);
|
||||
np = getnatp(cnum);
|
||||
val = yrel(np, val);
|
||||
break;
|
||||
default:
|
||||
logerror("bad type in decode: %x!\n",
|
||||
code & NSC_TMASK);
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (code & NSC_ROUND)
|
||||
val = roundintby(val, 10);
|
||||
return val;
|
||||
}
|
||||
|
||||
s_char *
|
||||
decodep(long int code, void *addr)
|
||||
{
|
||||
addr = (char *)addr + ((code & ~NSC_MASK) & 0xffff);
|
||||
|
||||
if ((code & NSC_TMASK) == NSC_CHARP)
|
||||
return *(s_char **)addr?*((s_char **)addr):(s_char *)"";
|
||||
return addr;
|
||||
}
|
541
src/lib/common/path.c
Normal file
541
src/lib/common/path.c
Normal file
|
@ -0,0 +1,541 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* path.c: Empire/A* Interface code. Provides callbacks for A* code and
|
||||
* a sector cache to speed things up. Define BP_STATS for sector
|
||||
* cache statistics, AS_STATS for A* statistics.
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Phil Lapsley, 1991
|
||||
* Dave Pare, 1991
|
||||
* Thomas Ruschak, 1993
|
||||
* Steve McClure, 1997
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "../as/as.h"
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
#include "xy.h"
|
||||
#include "sect.h"
|
||||
#include "file.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
#include "optlist.h"
|
||||
|
||||
/* STM - The server is now reliant on the sector file being
|
||||
* memory mapped for other things. So, this code has been
|
||||
* setup to have the sector hashing #ifdef'd instead so that
|
||||
* we don't have to do runtime checking. If someone moves
|
||||
* the sector file to me non-memory mapped, they have larger
|
||||
* problems than this, and can just turn this back on. Then
|
||||
* again, their performance will be so bad going to a file
|
||||
* all the time, it won't matter. */
|
||||
|
||||
/*#define DO_EFF_MEM_CHECKING*/
|
||||
|
||||
|
||||
/* XXX won't need sector hash when sect file is memory mapped */
|
||||
|
||||
#define BP_SCTHASHSIZE 128 /* sector cache hash table size */
|
||||
#define BP_ASHASHSIZE 128 /* A* queue hash table size */
|
||||
#define BP_NEIGHBORS 6 /* max number of neighbors */
|
||||
|
||||
struct sctcache {
|
||||
coord x, y;
|
||||
struct sctstr *sp;
|
||||
struct sctcache *next;
|
||||
};
|
||||
|
||||
struct bestp {
|
||||
struct sctcache *sctcachetab[BP_SCTHASHSIZE];
|
||||
int sctcache_hits;
|
||||
int sctcache_misses;
|
||||
int bp_mobtype;
|
||||
struct as_data *adp;
|
||||
};
|
||||
|
||||
#ifdef DO_EFF_MEM_CHECKING
|
||||
|
||||
static struct sctstr *bp_getsect(struct bestp *bp, coord x, coord y);
|
||||
static struct sctstr *bp_sctcache_get(struct bestp *bp, coord x, coord y);
|
||||
static void bp_sctcache_set(struct bestp *bp, coord x, coord y, struct sctstr *sp);
|
||||
static void bp_sctcache_zap(struct bestp *bp);
|
||||
|
||||
#endif /* DO_EFF_MEM_CHECKING */
|
||||
|
||||
static int bp_path(struct as_path *pp, s_char *buf);
|
||||
static int bp_neighbors(struct as_coord c, struct as_coord *cp, s_char *pp);
|
||||
static double bp_lbcost(struct as_coord from, struct as_coord to, s_char *pp);
|
||||
static double bp_realcost(struct as_coord from, struct as_coord to, s_char *pp);
|
||||
static double bp_seccost(struct as_coord from, struct as_coord to, s_char *pp);
|
||||
static int bp_coord_hash(struct as_coord c);
|
||||
|
||||
struct empfile *ep;
|
||||
|
||||
/* We use this for caching neighbors. It never changes except
|
||||
* at reboot time (maybe) so we never need to free it */
|
||||
struct sctstr **neighsects = (struct sctstr **)0;
|
||||
|
||||
s_char *
|
||||
bp_init(void)
|
||||
{
|
||||
struct bestp *bp;
|
||||
|
||||
ep = &empfile[EF_SECTOR];
|
||||
|
||||
bp = (struct bestp *) malloc(sizeof(*bp));
|
||||
bzero((s_char *)bp, sizeof(*bp));
|
||||
bp->adp = as_init(BP_NEIGHBORS, BP_ASHASHSIZE, bp_coord_hash,
|
||||
bp_neighbors, bp_lbcost, bp_realcost,
|
||||
bp_seccost, (s_char *)bp);
|
||||
|
||||
if (bp->adp == NULL)
|
||||
return NULL;
|
||||
|
||||
if (neighsects == (struct sctstr **)0)
|
||||
neighsects = (struct sctstr **)calloc(1, (sizeof(struct sctstr *) *
|
||||
((WORLD_X * WORLD_Y)/2)*6));
|
||||
|
||||
return (s_char *) bp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the best path from sector to to sector, and put the Empire movement
|
||||
* string in path. Return 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
best_path(struct sctstr *from, struct sctstr *to, s_char *path, int mob_type)
|
||||
{
|
||||
static struct bestp *mybestpath;
|
||||
struct as_data *adp;
|
||||
struct as_path *ap;
|
||||
|
||||
if (mybestpath == 0)
|
||||
mybestpath = (struct bestp *)bp_init();
|
||||
adp = mybestpath->adp;
|
||||
#ifdef DO_EFF_MEM_CHECKING
|
||||
bp_sctcache_zap(mybestpath);
|
||||
#endif
|
||||
ap = as_find_cachepath(from->sct_x, from->sct_y, to->sct_x, to->sct_y);
|
||||
if (ap == NULL) {
|
||||
adp->from.x = from->sct_x;
|
||||
adp->from.y = from->sct_y;
|
||||
adp->to.x = to->sct_x;
|
||||
adp->to.y = to->sct_y;
|
||||
mybestpath->bp_mobtype = mob_type;
|
||||
|
||||
if (as_search(adp) < 0)
|
||||
return -1;
|
||||
ap = adp->path;
|
||||
}
|
||||
|
||||
if (bp_path(ap, path) < 0)
|
||||
return -1;
|
||||
|
||||
#ifdef AS_STATS
|
||||
as_stats(adp, stderr);
|
||||
#endif /* AS_STATS */
|
||||
#ifdef BP_STATS
|
||||
fprintf(stderr, "best path %s\n", path);
|
||||
fprintf(stderr, "cache hits/misses: %d/%d\n",
|
||||
bp->sctcache_hits, bp->sctcache_misses);
|
||||
#endif /* BP_STATS */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate an A* path into an empire movement string. Return 0 on
|
||||
* success, -1 on failure.
|
||||
*/
|
||||
static int
|
||||
bp_path(struct as_path *pp, s_char *buf)
|
||||
{
|
||||
struct as_path *np;
|
||||
s_char *cp = buf;
|
||||
int dx, dy;
|
||||
int n;
|
||||
|
||||
np = pp->next;
|
||||
while (np) {
|
||||
dx = np->c.x - pp->c.x;
|
||||
/* deal with wraparound from non-neg coords */
|
||||
if (dx < -2)
|
||||
dx += WORLD_X;
|
||||
else if (dx > 2)
|
||||
dx -= WORLD_X;
|
||||
dy = np->c.y - pp->c.y;
|
||||
if (dy < -1)
|
||||
dy += WORLD_Y;
|
||||
else if (dy > 1)
|
||||
dy -= WORLD_Y;
|
||||
for (n=1;n<=6;n++)
|
||||
if (dx == diroff[n][0] && dy == diroff[n][1])
|
||||
break;
|
||||
if (n > 6)
|
||||
return -1;
|
||||
|
||||
*cp++ = dirch[n];
|
||||
pp = np;
|
||||
np = np->next;
|
||||
}
|
||||
*cp = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find coords neighboring this sector; return number of such
|
||||
* coords, and coordinartes themselves in an array pointed
|
||||
* to by *cpp.
|
||||
* XXX need to check ownership, sector types, etc.
|
||||
*/
|
||||
static int
|
||||
bp_neighbors(struct as_coord c, struct as_coord *cp, s_char *pp)
|
||||
{
|
||||
#ifdef DO_EFF_MEM_CHECKING
|
||||
struct bestp *bp = (struct bestp *) pp;
|
||||
#endif /* DO_EFF_MEM_CHECKING */
|
||||
coord x, y;
|
||||
coord nx, ny;
|
||||
int n = 0, q;
|
||||
struct sctstr *sp, *from, **ssp;
|
||||
/* Six pointers, just in case our cache isn't there */
|
||||
struct sctstr *tsp[] = { 0, 0, 0, 0, 0, 0 };
|
||||
int sx, sy, offset;
|
||||
|
||||
x = c.x;
|
||||
y = c.y;
|
||||
#ifdef DO_EFF_MEM_CHECKING
|
||||
if ((ep->flags & EFF_MEM) == 0) {
|
||||
from = bp_getsect(bp, x, y);
|
||||
} else {
|
||||
#endif /* DO_EFF_MEM_CHECKING */
|
||||
sx = XNORM(x);
|
||||
sy = YNORM(y);
|
||||
offset = (sy * WORLD_X + sx) / 2;
|
||||
from = (struct sctstr *) (ep->cache + ep->size * offset);
|
||||
#ifdef DO_EFF_MEM_CHECKING
|
||||
}
|
||||
#endif /* DO_EFF_MEM_CHECKING */
|
||||
|
||||
if (neighsects == (struct sctstr **)0)
|
||||
ssp = (struct sctstr **)&tsp[0];
|
||||
else
|
||||
ssp = (struct sctstr **)&neighsects[offset * 6];
|
||||
for (q = 1; q <= 6; q++, ssp++) {
|
||||
if (*ssp == (struct sctstr *)0) {
|
||||
/* We haven't cached this neighbor yet */
|
||||
nx = x + diroff[q][0];
|
||||
ny = y + diroff[q][1];
|
||||
sx = XNORM(nx);
|
||||
sy = YNORM(ny);
|
||||
#ifdef DO_EFF_MEM_CHECKING
|
||||
if ((ep->flags & EFF_MEM) == 0) {
|
||||
sp = bp_getsect(bp, nx, ny);
|
||||
} else {
|
||||
#endif /* DO_EFF_MEM_CHECKING */
|
||||
offset = (sy * WORLD_X + sx) / 2;
|
||||
sp = (struct sctstr *) (ep->cache + ep->size * offset);
|
||||
/* We can only save in our neighbor cache if the
|
||||
sector file is in memory */
|
||||
*ssp = sp;
|
||||
#ifdef DO_EFF_MEM_CHECKING
|
||||
}
|
||||
#endif /* DO_EFF_MEM_CHECKING */
|
||||
} else {
|
||||
sp = *ssp;
|
||||
sx = XNORM(sp->sct_x);
|
||||
sy = YNORM(sp->sct_y);
|
||||
}
|
||||
/* No need to calculate cost each time, just make sure we can
|
||||
move through it. We calculate it later. */
|
||||
if (dchr[sp->sct_type].d_mcst == 0)
|
||||
continue;
|
||||
if (sp->sct_own != from->sct_own)
|
||||
continue;
|
||||
cp[n].x = sx;
|
||||
cp[n].y = sy;
|
||||
n++;
|
||||
}
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute a lower-bound on the cost from "from" to "to".
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static double
|
||||
bp_lbcost(struct as_coord from, struct as_coord to, s_char *pp)
|
||||
{
|
||||
struct bestp *bp = (struct bestp *) pp;
|
||||
struct sctstr *ts;
|
||||
float cost;
|
||||
int x, y, sx, sy, offset;
|
||||
|
||||
#ifdef DO_EFF_MEM_CHECKING
|
||||
if ((ep->flags & EFF_MEM) == 0) {
|
||||
ts = bp_getsect(bp, (coord)to.x, (coord)to.y);
|
||||
} else {
|
||||
#endif /* DO_EFF_MEM_CHECKING */
|
||||
x = to.x;
|
||||
y = to.y;
|
||||
sx = XNORM(x);
|
||||
sy = YNORM(y);
|
||||
offset = (sy * WORLD_X + sx) / 2;
|
||||
ts = (struct sctstr *)(ep->cache + ep->size * offset);
|
||||
#ifdef DO_EFF_MEM_CHECKING
|
||||
}
|
||||
#endif /* DO_EFF_MEM_CHECKING */
|
||||
cost = sector_mcost(ts, bp->bp_mobtype);
|
||||
return (cost);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the real cost to move from "from" to "to".
|
||||
*/
|
||||
static double
|
||||
bp_realcost(struct as_coord from, struct as_coord to, s_char *pp)
|
||||
{
|
||||
return (bp_lbcost(from, to, pp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tie breaker secondary metric (only used when lower bound costs
|
||||
* are equal).
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static double
|
||||
bp_seccost(struct as_coord from, struct as_coord to, s_char *pp)
|
||||
{
|
||||
return ((double) mapdist((coord)from.x, (coord)from.y,
|
||||
(coord)to.x, (coord)to.y));
|
||||
}
|
||||
|
||||
#ifdef DO_EFF_MEM_CHECKING
|
||||
|
||||
/*
|
||||
* Get a sector from the cache. If it's not in the cache,
|
||||
* get it from disk and add it to the cache.
|
||||
*/
|
||||
static struct sctstr *
|
||||
bp_getsect(struct bestp *bp, coord x, coord y)
|
||||
{
|
||||
struct sctstr *sp;
|
||||
|
||||
sp = bp_sctcache_get(bp, x, y);
|
||||
if (sp == NULL) {
|
||||
sp = (struct sctstr *) malloc(sizeof(*sp));
|
||||
getsect(x, y, sp);
|
||||
bp_sctcache_set(bp, x, y, sp);
|
||||
bp->sctcache_misses++;
|
||||
} else {
|
||||
bp->sctcache_hits++;
|
||||
}
|
||||
return (sp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a sector from the cache; return NULL if it's not there.
|
||||
*/
|
||||
static struct sctstr *
|
||||
bp_sctcache_get(struct bestp *bp, coord x, coord y)
|
||||
{
|
||||
int hashval;
|
||||
struct as_coord c;
|
||||
struct sctcache *hp;
|
||||
|
||||
c.x = x;
|
||||
c.y = y;
|
||||
hashval = bp_coord_hash(c) % BP_SCTHASHSIZE;
|
||||
for (hp = bp->sctcachetab[hashval]; hp; hp = hp->next) {
|
||||
if (hp->x == x && hp->y == y)
|
||||
return (hp->sp);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a sector in the cache.
|
||||
*/
|
||||
static void
|
||||
bp_sctcache_set(struct bestp *bp, coord x, coord y, struct sctstr *sp)
|
||||
{
|
||||
int hashval;
|
||||
struct as_coord c;
|
||||
struct sctcache *hp;
|
||||
|
||||
hp = (struct sctcache *) calloc(1, sizeof(*hp));
|
||||
hp->x = x;
|
||||
hp->y = y;
|
||||
hp->sp = sp;
|
||||
c.x = x;
|
||||
c.y = y;
|
||||
hashval = bp_coord_hash(c) % BP_SCTHASHSIZE;
|
||||
hp->next = bp->sctcachetab[hashval];
|
||||
bp->sctcachetab[hashval] = hp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zap the cache and reset statistics.
|
||||
*/
|
||||
static void
|
||||
bp_sctcache_zap(struct bestp *bp)
|
||||
{
|
||||
register struct sctcache *hp;
|
||||
register struct sctcache *np;
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < BP_SCTHASHSIZE; i++) {
|
||||
for (hp = bp->sctcachetab[i]; hp; hp = np) {
|
||||
np = hp->next;
|
||||
free(hp->sp);
|
||||
free(hp);
|
||||
}
|
||||
bp->sctcachetab[i] = NULL;
|
||||
}
|
||||
bp->sctcache_hits = 0;
|
||||
bp->sctcache_misses = 0;
|
||||
}
|
||||
|
||||
#endif /* DO_EFF_MEM_CHECKING */
|
||||
|
||||
/*
|
||||
* Hash a coordinate into an integer.
|
||||
*/
|
||||
static int
|
||||
bp_coord_hash(struct as_coord c)
|
||||
{
|
||||
return ((abs(c.x) + 1) << 3) ^ abs(c.y);
|
||||
}
|
||||
|
||||
void
|
||||
bp_enable_cachepath()
|
||||
{
|
||||
as_enable_cachepath();
|
||||
}
|
||||
|
||||
void
|
||||
bp_disable_cachepath()
|
||||
{
|
||||
as_disable_cachepath();
|
||||
}
|
||||
|
||||
void
|
||||
bp_clear_cachepath()
|
||||
{
|
||||
as_clear_cachepath();
|
||||
}
|
||||
|
||||
double
|
||||
pathcost(struct sctstr *start, s_char *path, int mob_type)
|
||||
{
|
||||
register int o;
|
||||
register int cx, cy;
|
||||
double cost = 0.0;
|
||||
struct sctstr *sp;
|
||||
int sx, sy, offset;
|
||||
|
||||
cx = start->sct_x;
|
||||
cy = start->sct_y;
|
||||
|
||||
while (*path) {
|
||||
if (*path == 'h') {
|
||||
path++;
|
||||
continue;
|
||||
}
|
||||
o = dirindex[(int)((*path) - 'a')];
|
||||
cx += diroff[o][0];
|
||||
cy += diroff[o][1];
|
||||
sx = XNORM(cx);
|
||||
sy = YNORM(cy);
|
||||
offset = (sy * WORLD_X + sx) / 2;
|
||||
sp = (struct sctstr *)(ep->cache + ep->size * offset);
|
||||
cost += sector_mcost(sp, mob_type);
|
||||
path++;
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
s_char *
|
||||
BestDistPath(s_char *path,
|
||||
struct sctstr *from,
|
||||
struct sctstr *to,
|
||||
double *cost,
|
||||
int mob_type)
|
||||
{
|
||||
return BestLandPath(path, from, to, cost, mob_type);
|
||||
}
|
||||
|
||||
s_char *
|
||||
BestLandPath(s_char *path,
|
||||
struct sctstr *from,
|
||||
struct sctstr *to,
|
||||
double *cost,
|
||||
int mob_type)
|
||||
{
|
||||
int length;
|
||||
|
||||
*path = 0;
|
||||
*cost = 0.0;
|
||||
if (best_path(from, to, path, mob_type) < 0)
|
||||
return (s_char *)0;
|
||||
*cost = pathcost(from, path, mob_type);
|
||||
length = strlen(path);
|
||||
path[length] = 'h';
|
||||
path[length + 1] = '\0';
|
||||
return path;
|
||||
}
|
||||
|
||||
s_char *
|
||||
BestShipPath(s_char *path,
|
||||
int fx,
|
||||
int fy,
|
||||
int tx,
|
||||
int ty,
|
||||
int owner)
|
||||
{
|
||||
s_char *map;
|
||||
|
||||
/* need to make sector database available to bestpath */
|
||||
map = ef_ptr(EF_BMAP, owner);
|
||||
|
||||
return (bestownedpath(path, map, fx, fy, tx, ty, ".=h", owner));
|
||||
}
|
||||
|
||||
s_char *
|
||||
BestAirPath(s_char *path,
|
||||
int fx,
|
||||
int fy,
|
||||
int tx,
|
||||
int ty)
|
||||
{
|
||||
return (bestownedpath(path, 0, fx, fy, tx, ty, "", -1));
|
||||
/* return (bestpath(path, fx, fy, tx, ty, ""));*/
|
||||
}
|
||||
|
71
src/lib/common/res_pop.c
Normal file
71
src/lib/common/res_pop.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* res_pop.c: Get maximum pop of a sector
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Ken Stevens, 1995
|
||||
* Steve McClure, 1998
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "nat.h"
|
||||
#include "item.h"
|
||||
#include "news.h"
|
||||
#include "file.h"
|
||||
#include "xy.h"
|
||||
#include "optlist.h"
|
||||
#include "common.h"
|
||||
|
||||
int
|
||||
max_pop(float research, struct sctstr *sp)
|
||||
{
|
||||
int maxpop = 999;
|
||||
|
||||
if (opt_RES_POP) {
|
||||
maxpop = (((50.0+4.0*research)/(200.0+3.0*research))*600.0) + 400;
|
||||
if (maxpop > 999)
|
||||
maxpop = 999;
|
||||
}
|
||||
|
||||
if (opt_BIG_CITY) {
|
||||
if (sp && dchr[sp->sct_type].d_pkg == UPKG)
|
||||
maxpop = (int)(maxpop * ((9.0 * sp->sct_effic) / 100 + 1));
|
||||
}
|
||||
|
||||
if (sp) {
|
||||
if (sp->sct_type == SCT_MOUNT)
|
||||
maxpop /= 10;
|
||||
else if (sp->sct_type == SCT_PLAINS)
|
||||
maxpop /= 20;
|
||||
}
|
||||
|
||||
return maxpop;
|
||||
}
|
141
src/lib/common/sectdamage.c
Normal file
141
src/lib/common/sectdamage.c
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* sectdamage.c: Damage a sector
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
* Steve McClure, 1996
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "ship.h"
|
||||
#include "land.h"
|
||||
#include "plane.h"
|
||||
#include "nuke.h"
|
||||
#include "xy.h"
|
||||
#include "nsc.h"
|
||||
#include "file.h"
|
||||
#include "nat.h"
|
||||
#include "optlist.h"
|
||||
#include "damage.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
#include "subs.h"
|
||||
#include "lost.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((int)sp->sct_effic, dam);
|
||||
sp->sct_road = damage((int)sp->sct_road, dam);
|
||||
sp->sct_rail = damage((int)sp->sct_rail, dam);
|
||||
sp->sct_defense = damage((int)sp->sct_defense, dam);
|
||||
if (!opt_DEFENSE_INFRA)
|
||||
sp->sct_defense = sp->sct_effic;
|
||||
|
||||
eff = dam;
|
||||
|
||||
if (sp->sct_mobil > 0)
|
||||
sp->sct_mobil = damage((int)sp->sct_mobil, dam);
|
||||
sp->sct_nv = vl_damage(dam,
|
||||
sp->sct_vtype, sp->sct_vamt,
|
||||
(int)sp->sct_nv);
|
||||
if (opt_EASY_BRIDGES == 0) {
|
||||
if (sp->sct_effic < 20 && sp->sct_type == SCT_BHEAD)
|
||||
bridgefall(sp, list);
|
||||
} else {
|
||||
if (sp->sct_effic < 20 && sp->sct_type == SCT_BSPAN)
|
||||
knockdown(sp, list);
|
||||
}
|
||||
putsect(sp);
|
||||
return eff;
|
||||
}
|
||||
|
||||
int
|
||||
sectdamage(struct sctstr *sp, int dam, struct emp_qelem *list)
|
||||
{
|
||||
extern double unit_damage;
|
||||
struct nstr_item ni;
|
||||
struct lndstr land;
|
||||
struct plnstr plane;
|
||||
double real_dam;
|
||||
int eff;
|
||||
double sector_strength();
|
||||
|
||||
/* Some sectors are harder/easier to kill.. */
|
||||
/* Average sector has a dstr of 1, so adjust */
|
||||
/* the damage accordingly. Makes forts a pain */
|
||||
|
||||
/* real_dam = (double)dam * (1.0/((((double)(dchr[sp->sct_type].d_dstr - 1))*(sp->sct_effic/100.0)) + 1.0));*/
|
||||
real_dam = (double)dam * (1.0/sector_strength(sp));
|
||||
dam = ldround(real_dam,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,(s_char *)&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, (s_char *)&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;
|
||||
}
|
156
src/lib/common/snxtit_subs.c
Normal file
156
src/lib/common/snxtit_subs.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* snxtit_subs.c: arrange item selection using one of many criteria.
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "xy.h"
|
||||
#include "sect.h"
|
||||
#include "nsc.h"
|
||||
#include "file.h"
|
||||
#include "common.h"
|
||||
|
||||
void
|
||||
snxtitem_area(register struct nstr_item *np, int type, struct range *range)
|
||||
{
|
||||
bzero((s_char *)np, sizeof(*np));
|
||||
np->cur = -1;
|
||||
np->type = type;
|
||||
np->sel = NS_AREA;
|
||||
np->index = -1;
|
||||
np->range = *range;
|
||||
np->read = ef_read;
|
||||
np->flags = ef_flags(type);
|
||||
xysize_range(&np->range);
|
||||
ef_zapcache(type);
|
||||
}
|
||||
|
||||
void
|
||||
snxtitem_dist(register struct nstr_item *np, int type, int cx, int cy, int dist)
|
||||
{
|
||||
struct range range;
|
||||
|
||||
bzero((s_char *)np, sizeof(*np));
|
||||
xydist_range(cx, cy, dist, &range);
|
||||
np->cur = -1;
|
||||
np->type = type;
|
||||
np->sel = NS_DIST;
|
||||
np->cx = cx;
|
||||
np->cy = cy;
|
||||
np->index = -1;
|
||||
np->range = range;
|
||||
np->dist = dist;
|
||||
np->read = ef_read;
|
||||
np->flags = ef_flags(type);
|
||||
#if 0
|
||||
/* This is no longer proper. */
|
||||
/* It did the wrong thing for small, hitech worlds. */
|
||||
xysize_range(&np->range);
|
||||
#endif
|
||||
ef_zapcache(type);
|
||||
}
|
||||
|
||||
void
|
||||
snxtitem_xy(register struct nstr_item *np, int type, coord x, coord y)
|
||||
{
|
||||
bzero((s_char *)np, sizeof(*np));
|
||||
np->cur = -1;
|
||||
np->type = type;
|
||||
np->sel = NS_XY;
|
||||
np->cx = xnorm(x);
|
||||
np->cy = ynorm(y);
|
||||
np->index = -1;
|
||||
np->dist = 0;
|
||||
np->read = ef_read;
|
||||
np->flags = ef_flags(type);
|
||||
ef_zapcache(type);
|
||||
}
|
||||
|
||||
void
|
||||
snxtitem_all(register struct nstr_item *np, int type)
|
||||
{
|
||||
bzero((s_char *)np, sizeof(*np));
|
||||
np->cur = -1;
|
||||
np->sel = NS_ALL;
|
||||
np->type = type;
|
||||
np->index = -1;
|
||||
np->read = ef_read;
|
||||
np->flags = ef_flags(type);
|
||||
xysize_range(&np->range);
|
||||
ef_zapcache(type);
|
||||
}
|
||||
|
||||
void
|
||||
snxtitem_group(register struct nstr_item *np, int type, s_char group)
|
||||
{
|
||||
if (group == '~')
|
||||
group = ' ';
|
||||
bzero((s_char *)np, sizeof(*np));
|
||||
np->cur = -1;
|
||||
np->sel = NS_GROUP;
|
||||
np->group = group;
|
||||
np->type = type;
|
||||
np->index = -1;
|
||||
np->read = ef_read;
|
||||
np->flags = ef_flags(type);
|
||||
xysize_range(&np->range);
|
||||
ef_zapcache(type);
|
||||
}
|
||||
|
||||
void
|
||||
snxtitem_rewind(struct nstr_item *np)
|
||||
{
|
||||
np->cur = -1;
|
||||
np->index = -1;
|
||||
ef_zapcache(np->type);
|
||||
}
|
||||
|
||||
int
|
||||
snxtitem_list(register struct nstr_item *np, int type, int *list, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
bzero((s_char *)np, sizeof(*np));
|
||||
np->cur = -1;
|
||||
np->type = type;
|
||||
np->sel = NS_LIST;
|
||||
np->index = -1;
|
||||
np->read = ef_read;
|
||||
np->flags = ef_flags(type);
|
||||
if (len <= 0 || len > NS_LSIZE)
|
||||
return 0;
|
||||
for (i=0; i<len; i++)
|
||||
np->list[i] = list[i];
|
||||
np->size = len;
|
||||
ef_zapcache(type);
|
||||
return 1;
|
||||
}
|
159
src/lib/common/snxtsct_subs.c
Normal file
159
src/lib/common/snxtsct_subs.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* snxtsct_subs.c: arrange sector selection using either distance or area
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
*/
|
||||
/*
|
||||
* XXX we can *almost* treat sectors as items, but not quite.
|
||||
* Items are retrieved using id's, and sectors still use x,y.
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "xy.h"
|
||||
#include "sect.h"
|
||||
#include "nsc.h"
|
||||
#include "file.h"
|
||||
#include "common.h"
|
||||
#include "optlist.h"
|
||||
|
||||
void
|
||||
snxtsct_all(struct nstr_sect *np)
|
||||
{
|
||||
struct range worldrange;
|
||||
|
||||
worldrange.lx = -WORLD_X/2;
|
||||
worldrange.ly = -WORLD_Y/2;
|
||||
worldrange.hx = WORLD_X/2;
|
||||
worldrange.hy = WORLD_Y/2;
|
||||
worldrange.width = worldrange.height = 0;
|
||||
snxtsct_area(np, &worldrange);
|
||||
}
|
||||
|
||||
void
|
||||
snxtsct_area(register struct nstr_sect *np, struct range *range)
|
||||
{
|
||||
bzero((s_char *)np, sizeof(*np));
|
||||
np->range = *range;
|
||||
np->ncond = 0;
|
||||
np->type = NS_AREA;
|
||||
np->read = ef_read;
|
||||
np->x = np->range.lx - 1;
|
||||
np->y = np->range.ly;
|
||||
np->dx = -1;
|
||||
np->dy = 0;
|
||||
xysize_range(&np->range);
|
||||
ef_zapcache(EF_SECTOR);
|
||||
}
|
||||
|
||||
void
|
||||
snxtsct_rewind(struct nstr_sect *np)
|
||||
{
|
||||
np->x = np->range.lx - 1;
|
||||
np->y = np->range.ly;
|
||||
np->dx = -1;
|
||||
np->dy = 0;
|
||||
np->id = -1;
|
||||
ef_zapcache(EF_SECTOR);
|
||||
}
|
||||
|
||||
void
|
||||
snxtsct_dist(register struct nstr_sect *np, coord cx, coord cy, int dist)
|
||||
{
|
||||
bzero((s_char *)np, sizeof(*np));
|
||||
xydist_range(cx, cy, dist, &np->range);
|
||||
np->cx = cx;
|
||||
np->cy = cy;
|
||||
np->ncond = 0;
|
||||
np->dist = dist;
|
||||
np->type = NS_DIST;
|
||||
np->read = ef_read;
|
||||
np->x = np->range.lx - 1;
|
||||
np->y = np->range.ly;
|
||||
np->dx = -1;
|
||||
np->dy = 0;
|
||||
#if 0
|
||||
/* This function is now done elsewhere. */
|
||||
/* It was not doing the right thing when the world was small */
|
||||
xysize_range(&np->range);
|
||||
#endif
|
||||
ef_zapcache(EF_SECTOR);
|
||||
}
|
||||
|
||||
void
|
||||
xysize_range(register struct range *rp)
|
||||
{
|
||||
if (rp->lx >= rp->hx)
|
||||
rp->width = WORLD_X + rp->hx - rp->lx;
|
||||
else
|
||||
rp->width = rp->hx - rp->lx;
|
||||
#ifndef HAY
|
||||
/* This is a necessary check for small, hitech worlds. */
|
||||
if (rp->width > WORLD_X)
|
||||
rp->width = WORLD_X;
|
||||
#endif
|
||||
if (rp->ly >= rp->hy)
|
||||
rp->height = WORLD_Y + rp->hy - rp->ly;
|
||||
else
|
||||
rp->height = rp->hy - rp->ly;
|
||||
#ifndef HAY
|
||||
/* This is a necessary check for small, hitech worlds. */
|
||||
if (rp->height > WORLD_Y)
|
||||
rp->height = WORLD_Y;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This is called also called in snxtitem.c */
|
||||
void
|
||||
xydist_range(coord x, coord y, register int dist, struct range *rp)
|
||||
{
|
||||
if (dist < WORLD_X/4) {
|
||||
rp->lx = xnorm((coord)(x - 2 * dist));
|
||||
rp->hx = xnorm((coord)(x + 2 * dist) + 1);
|
||||
rp->width = 4 * dist + 1;
|
||||
} else {
|
||||
/* Range is larger than the world */
|
||||
/* Make sure we get lx in the right place. */
|
||||
rp->lx = xnorm((coord)(x - WORLD_X/2));
|
||||
rp->hx = xnorm((coord)(rp->lx + WORLD_X - 1));
|
||||
rp->width = WORLD_X;
|
||||
}
|
||||
|
||||
if (dist < WORLD_Y/2) {
|
||||
rp->ly = ynorm((coord)(y - dist));
|
||||
rp->hy = ynorm((coord)(y + dist) + 1);
|
||||
rp->height = 2 * dist + 1;
|
||||
} else {
|
||||
/* Range is larger than the world */
|
||||
rp->ly = ynorm((coord)(y - WORLD_Y/2));
|
||||
rp->hy = ynorm((coord)(rp->ly + WORLD_Y - 1));
|
||||
rp->height = WORLD_Y;
|
||||
}
|
||||
}
|
82
src/lib/common/stmtch.c
Normal file
82
src/lib/common/stmtch.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* stmtch.c: Matching operations on structures and commands
|
||||
*
|
||||
* Known contributors to this file:
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* XXX These routines gamble that structures are all longword-aligned.
|
||||
* If this is not true, they will BREAK!
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "match.h"
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* find a matching string from a member string pointer
|
||||
* in a structure "str". Pointer is incremented by
|
||||
* the (passed) size of the structure.
|
||||
*/
|
||||
int
|
||||
stmtch(register s_char *obj, s_char *base, int off, int size)
|
||||
{
|
||||
register s_char *str;
|
||||
register int stat2;
|
||||
register int i;
|
||||
register int n;
|
||||
|
||||
stat2 = M_NOTFOUND;
|
||||
str = base + off;
|
||||
for (i=0; *(s_char **)str; i++, str += size) {
|
||||
if ((n = mineq(obj, *(s_char **)str)) == ME_MISMATCH)
|
||||
continue;
|
||||
if (n == ME_EXACT)
|
||||
return i;
|
||||
if (stat2 != M_NOTFOUND)
|
||||
return M_NOTUNIQUE;
|
||||
stat2 = i;
|
||||
}
|
||||
return stat2;
|
||||
}
|
||||
|
||||
/*
|
||||
* do partial match comparison.
|
||||
*/
|
||||
int
|
||||
mineq(register s_char *a, register s_char *b)
|
||||
{
|
||||
do {
|
||||
if (*a++ != *b++)
|
||||
return ME_MISMATCH;
|
||||
} while (*b != ' ' && *a != 0);
|
||||
if (*a == 0 && (*b == ' ' || *b == 0))
|
||||
return ME_EXACT;
|
||||
return ME_PARTIAL;
|
||||
}
|
89
src/lib/common/tfact.c
Normal file
89
src/lib/common/tfact.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* tfact.c: return tech fact given multiplier
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Yannick Trembley
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
|
||||
extern float fire_range_factor;
|
||||
|
||||
double
|
||||
tfact(natid cn, double mult)
|
||||
{
|
||||
double tlev;
|
||||
struct natstr *np;
|
||||
|
||||
np = getnatp(cn);
|
||||
tlev = np->nat_level[NAT_TLEV];
|
||||
tlev = (50.0 + tlev) / (200.0 + tlev);
|
||||
return mult * tlev;
|
||||
}
|
||||
|
||||
double
|
||||
tfactfire(natid cn, double mult)
|
||||
{
|
||||
double tlev;
|
||||
struct natstr *np;
|
||||
|
||||
np = getnatp(cn);
|
||||
tlev = np->nat_level[NAT_TLEV];
|
||||
tlev = (50.0 + tlev) / (200.0 + tlev);
|
||||
return mult * tlev * fire_range_factor;
|
||||
}
|
||||
|
||||
double
|
||||
techfact(int level, double mult)
|
||||
{
|
||||
return mult * ((50.0 + level) / (200.0 + level));
|
||||
}
|
||||
|
||||
/*
|
||||
* added so that firing range can be different to other ranges
|
||||
*/
|
||||
double
|
||||
techfactfire(int level, double mult)
|
||||
{
|
||||
return mult * ((50.0 + level) / (200.0 + level)) * fire_range_factor;
|
||||
}
|
||||
|
||||
/*
|
||||
* figure out relative difference between two tech levels
|
||||
*/
|
||||
double
|
||||
reltech(int level1, int level2, double mult)
|
||||
{
|
||||
int diff;
|
||||
|
||||
diff = level1 - level2;
|
||||
return (1.0 + ((diff + 50.0) / (level1 + 50.0))) * mult;
|
||||
}
|
101
src/lib/common/type.c
Normal file
101
src/lib/common/type.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* type.c: typename to array offset translation
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
* Steve McClure, 2000
|
||||
*/
|
||||
|
||||
#ifdef Rel4
|
||||
#include <string.h>
|
||||
#endif /* Rel4 */
|
||||
#include "misc.h"
|
||||
#include "ship.h"
|
||||
#include "land.h"
|
||||
#include "plane.h"
|
||||
#include "sect.h"
|
||||
#include "nuke.h"
|
||||
#include "file.h"
|
||||
#include "common.h"
|
||||
|
||||
int
|
||||
typematch(s_char *buf, int type)
|
||||
{
|
||||
register int n;
|
||||
int len;
|
||||
|
||||
len = strlen(buf);
|
||||
switch (type) {
|
||||
case EF_SECTOR: {
|
||||
register struct dchrstr *dcp;
|
||||
|
||||
if (!buf[0] || buf[1])
|
||||
return -1;
|
||||
for (dcp=dchr,n=0; dcp->d_name; n++,dcp++)
|
||||
if (dcp->d_mnem == *buf)
|
||||
return n;
|
||||
}
|
||||
break;
|
||||
case EF_SHIP: {
|
||||
register struct mchrstr *mcp;
|
||||
|
||||
for (mcp=mchr,n=0; *mcp->m_name; n++,mcp++)
|
||||
if (strncmp(mcp->m_name, buf, len) == 0)
|
||||
return n;
|
||||
}
|
||||
break;
|
||||
case EF_LAND: {
|
||||
register struct lchrstr *lcp;
|
||||
|
||||
for (lcp=lchr,n=0; *lcp->l_name; n++,lcp++)
|
||||
if (strncmp(lcp->l_name, buf, len) == 0)
|
||||
return n;
|
||||
}
|
||||
break;
|
||||
case EF_PLANE: {
|
||||
register struct plchrstr *pcp;
|
||||
|
||||
for (pcp=plchr,n=0; *pcp->pl_name; n++,pcp++)
|
||||
if (strncmp(pcp->pl_name, buf, len) == 0)
|
||||
return n;
|
||||
}
|
||||
break;
|
||||
case EF_NUKE: {
|
||||
register struct nchrstr *ncp;
|
||||
|
||||
for (ncp=nchr,n=0; *ncp->n_name; n++,ncp++)
|
||||
if (strncmp(ncp->n_name, buf, len) == 0)
|
||||
return n;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
284
src/lib/common/vlist.c
Normal file
284
src/lib/common/vlist.c
Normal file
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* vlist.c: manage variable lists
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "ship.h"
|
||||
#include "land.h"
|
||||
#include "product.h"
|
||||
#include "optlist.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
|
||||
static int freeslot(u_char *vec, register u_char *end);
|
||||
|
||||
int
|
||||
vl_find(register int vtype, u_char *typevec, u_short *amtvec, int nelem)
|
||||
{
|
||||
register u_char *vp;
|
||||
register u_short *ap;
|
||||
register u_char *endp;
|
||||
|
||||
if (vtype < 0 || vtype > V_MAX)
|
||||
return -1;
|
||||
vp = typevec;
|
||||
ap = amtvec;
|
||||
endp = vp + nelem;
|
||||
for ( ; vp < endp; vp++, ap++) {
|
||||
if (*vp == vtype)
|
||||
return (int) *ap;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
vl_set(register int vtype, u_int amt, u_char *typevec, u_short *amtvec, u_char *nvp, int max)
|
||||
{
|
||||
register u_char *vp;
|
||||
register u_char *endp;
|
||||
register u_short *ap;
|
||||
int n;
|
||||
|
||||
if (vtype < 0 || vtype > V_MAX)
|
||||
return 0;
|
||||
if (amt > 65536) {
|
||||
logerror("vl_set: bad amt %d (%x), vtype %d\n", (int)amt, amt,
|
||||
vtype);
|
||||
return 0;
|
||||
}
|
||||
vp = typevec;
|
||||
ap = amtvec;
|
||||
endp = vp + *nvp;
|
||||
for ( ; vp < endp; vp++, ap++) {
|
||||
if (*vp == vtype)
|
||||
break;
|
||||
}
|
||||
if (vp == endp) {
|
||||
if (amt == 0) {
|
||||
/* deleting, but not present */
|
||||
return 0;
|
||||
}
|
||||
if (*nvp == max) {
|
||||
if (isdel(vtype) || isdist(vtype))
|
||||
return -1;
|
||||
/* replace any del or dst entries */
|
||||
if ((n = freeslot(typevec, endp)) < 0)
|
||||
return -1;
|
||||
vp = &typevec[n];
|
||||
ap = &amtvec[n];
|
||||
} else {
|
||||
/* add at end */
|
||||
(*nvp)++;
|
||||
}
|
||||
*vp = vtype;
|
||||
*ap = amt;
|
||||
} else {
|
||||
if (amt != 0) {
|
||||
/* altering; just change value */
|
||||
*ap = amt;
|
||||
return 1;
|
||||
}
|
||||
(*nvp)--;
|
||||
if (vp < endp-1) {
|
||||
/* if not last element, copy last to current */
|
||||
*ap = amtvec[*nvp];
|
||||
*vp = typevec[*nvp];
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
vl_damage(register int pct, register u_char *typevec, register u_short *amtvec, register int nelem)
|
||||
{
|
||||
register int i;
|
||||
register int lose;
|
||||
extern double people_damage;
|
||||
|
||||
if (pct >= 100)
|
||||
return 0;
|
||||
if (pct <= 0)
|
||||
return nelem;
|
||||
for (i=0; i<nelem; i++) {
|
||||
if (!isitem(typevec[i]))
|
||||
continue;
|
||||
if (opt_SUPER_BARS && typevec[i] == V_BAR)
|
||||
continue;
|
||||
lose = roundavg((double)amtvec[i] * pct * 0.01);
|
||||
if (typevec[i] == V_CIVIL ||
|
||||
typevec[i] == V_MILIT ||
|
||||
typevec[i] == V_UW)
|
||||
lose = ldround(people_damage * lose, 1);
|
||||
if ((amtvec[i] -= lose) + 1 == 0) {
|
||||
nelem--;
|
||||
if (i == nelem)
|
||||
break;
|
||||
typevec[i] = typevec[nelem];
|
||||
amtvec[i] = amtvec[nelem];
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return nelem;
|
||||
}
|
||||
|
||||
/*
|
||||
* extract all "mask" items from the variable list
|
||||
* caller must pass a pointer to an aray of I_MAX+1,
|
||||
* or else bad things will happen.
|
||||
*/
|
||||
int
|
||||
vl_getvec(register u_char *src_type, register u_short *src_amt, register int src_nv, register int class, register int *dst_amt)
|
||||
{
|
||||
register int n;
|
||||
int count;
|
||||
int item;
|
||||
|
||||
for (n=0; n<I_MAX+1; n++)
|
||||
dst_amt[n] = 0;
|
||||
for (count=0, n=0; n<src_nv; n++) {
|
||||
if ((src_type[n] & VT_TYPE) != class)
|
||||
continue;
|
||||
item = src_type[n] & ~VT_TYPE;
|
||||
if (item > I_MAX) {
|
||||
logerror("vl_getvec: bad I-type %d (vtype %d)\n",
|
||||
item, src_type[n]);
|
||||
continue;
|
||||
}
|
||||
dst_amt[item] = src_amt[n];
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the vec into the variable list. All items zero in
|
||||
* the vec will be deleted from the vlist, and all items
|
||||
* present in the vec will be added to the vlist.
|
||||
*/
|
||||
int
|
||||
vl_setvec(register u_char *type, register u_short *amt, u_char *nvp, int max, register int class, register int *vec)
|
||||
{
|
||||
register int nv;
|
||||
register int n;
|
||||
register int vec_n;
|
||||
|
||||
nv = *nvp;
|
||||
vec_n = 1;
|
||||
n = 0;
|
||||
while (n < nv) {
|
||||
if ((type[n] & VT_TYPE) != class) {
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
/* find non-zero vec entry to overwrite current slot */
|
||||
for ( ; vec_n <= I_MAX; vec_n++)
|
||||
if (vec[vec_n] != 0)
|
||||
break;
|
||||
if (vec_n > I_MAX) {
|
||||
/* no more elements left; delete */
|
||||
nv--;
|
||||
if (n < nv) {
|
||||
/* copy last entry over current entry */
|
||||
type[n] = type[nv];
|
||||
amt[n] = amt[nv];
|
||||
}
|
||||
} else {
|
||||
/* use new (unused) entry */
|
||||
type[n] = vec_n | class;
|
||||
amt[n] = vec[vec_n];
|
||||
vec_n++;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
*nvp = nv;
|
||||
if (n >= nv && vec_n > I_MAX)
|
||||
return 1;
|
||||
/* free slots at end; copy rest of vec into the vlist */
|
||||
for ( ; vec_n <= I_MAX && nv < max; vec_n++) {
|
||||
if (vec[vec_n] == 0)
|
||||
continue;
|
||||
type[nv] = vec_n | class;
|
||||
amt[nv] = vec[vec_n];
|
||||
nv++;
|
||||
}
|
||||
*nvp = nv;
|
||||
if (vec_n <= I_MAX && (class == VT_ITEM || class == VT_COND)) {
|
||||
/*
|
||||
* still stuff left; make free slots out of deliveries
|
||||
* and distributes and stuff 'em in (only for item or cond)
|
||||
*/
|
||||
for ( ; vec_n <= I_MAX; vec_n++) {
|
||||
if (vec[vec_n] == 0)
|
||||
continue;
|
||||
if ((n = freeslot(type, &type[max])) < 0) {
|
||||
logerror("vl_setvec: no free slots left\n");
|
||||
return 0;
|
||||
}
|
||||
logerror("vl_setvec: replacing type %d amt %d\n",
|
||||
type[n], amt[n]);
|
||||
type[n] = vec_n | class;
|
||||
amt[n] = vec[vec_n];
|
||||
}
|
||||
}
|
||||
if (nv == max) {
|
||||
/* checking for overflow */
|
||||
while (vec_n <= I_MAX) {
|
||||
if (vec[vec_n])
|
||||
break;
|
||||
}
|
||||
if (vec_n <= I_MAX) {
|
||||
logerror("vl_setvec: no space for i-type #%d (%d)\n",
|
||||
vec_n, vec[vec_n]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* make a free slot; deliveries and distributions
|
||||
* are fair game for us.
|
||||
*/
|
||||
static
|
||||
int
|
||||
freeslot(u_char *vec, register u_char *end)
|
||||
{
|
||||
register u_char *vp;
|
||||
|
||||
for (vp=vec; vp < end; vp++) {
|
||||
if (isdel(*vp) || isdist(*vp))
|
||||
return vp - vec;
|
||||
}
|
||||
return -1;
|
||||
}
|
399
src/lib/common/wantupd.c
Normal file
399
src/lib/common/wantupd.c
Normal file
|
@ -0,0 +1,399 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* wantupd.c: Check to se if an update is wanted and/or allowed.
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Doug Hay, 1990
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "misc.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "keyword.h"
|
||||
#include "wantupd.h"
|
||||
#include "optlist.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#if defined(Rel4) || defined(_WIN32)
|
||||
#include <time.h>
|
||||
#else /* Rel4 */
|
||||
#include <sys/time.h>
|
||||
#endif /* Rel4 */
|
||||
|
||||
void
|
||||
update_policy_check(void)
|
||||
{
|
||||
extern int update_policy,update_demandpolicy;
|
||||
extern int update_wantmin,blitz_time;
|
||||
|
||||
if (update_policy < 0) update_policy = UDP_DEFAULT;
|
||||
if (update_policy > UDP_MAX) update_policy = UDP_DEFAULT;
|
||||
if (update_demandpolicy < 0) update_demandpolicy = UDDEM_DEFAULT;
|
||||
if (update_demandpolicy > UDDEM_MAX)
|
||||
update_demandpolicy = UDDEM_DEFAULT;
|
||||
if (update_wantmin < 0) update_wantmin = 0;
|
||||
if (update_wantmin > MAXNOC) update_wantmin = MAXNOC;
|
||||
if (blitz_time < 0) blitz_time = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
demand_update_time(time_t *now)
|
||||
{
|
||||
struct tm *tm;
|
||||
s_char *p;
|
||||
int curtime;
|
||||
int hour[2];
|
||||
extern s_char *update_demandtimes;
|
||||
|
||||
tm = localtime(now);
|
||||
curtime = tm->tm_min + tm->tm_hour * 60;
|
||||
p=update_demandtimes;
|
||||
if (*p == 0) return(1);
|
||||
while (NULL != (p = kw_parse(CF_TIMERANGE, p, &hour[0]))) {
|
||||
if (curtime >= hour[0] && curtime < hour[1])
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* When is the next regularly scheduled update from now. */
|
||||
static void
|
||||
regular_update_time(time_t *now, time_t *tim, time_t *delta)
|
||||
{
|
||||
extern int s_p_etu;
|
||||
extern int etu_per_update;
|
||||
extern int adj_update;
|
||||
s_char *p;
|
||||
time_t tw;
|
||||
int secs_per_update;
|
||||
|
||||
tw = *now + adj_update;
|
||||
secs_per_update = etu_per_update * s_p_etu;
|
||||
*delta = secs_per_update - (tw % secs_per_update);
|
||||
*tim = *now + *delta;
|
||||
}
|
||||
|
||||
/* Is this a valid time for a scheduled update. */
|
||||
static int
|
||||
scheduled_update_time(time_t *now, int *which)
|
||||
{
|
||||
struct tm *tm;
|
||||
s_char *p, *p1;
|
||||
int curtime;
|
||||
int hour;
|
||||
extern int hourslop;
|
||||
extern s_char *update_times;
|
||||
|
||||
*which = -1;
|
||||
p=update_times;
|
||||
if (*p == 0) return(0);
|
||||
|
||||
tm = localtime(now);
|
||||
curtime = tm->tm_min + tm->tm_hour * 60;
|
||||
while (NULL != (p = kw_parse(CF_TIME, p, &hour))) {
|
||||
(*which) ++;
|
||||
if (curtime >= hour &&
|
||||
curtime < hour+hourslop)
|
||||
return(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
next_scheduled_time(time_t *now, time_t *tim, time_t *delta)
|
||||
{
|
||||
struct tm *tm;
|
||||
s_char *p;
|
||||
int curtime;
|
||||
int hour;
|
||||
int mintime;
|
||||
extern s_char *update_times;
|
||||
|
||||
p=update_times;
|
||||
if (*p == 0) return(0);
|
||||
|
||||
tm = localtime(now);
|
||||
curtime = tm->tm_min + tm->tm_hour * 60; /* now - in minutes */
|
||||
mintime = curtime + 24*60+1; /* start with now + 1 day */
|
||||
while (NULL != (p = kw_parse(CF_TIME, p, &hour))) {
|
||||
if (hour <= curtime)
|
||||
hour += 24 * 60; /* this must be tomorrow */
|
||||
if (hour < mintime)
|
||||
mintime = hour; /* this is best bet so far */
|
||||
}
|
||||
*delta = 60*(mintime - curtime);
|
||||
*tim = *now + *delta - tm->tm_sec;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
demand_update_want(int *want, int *pop, int which)
|
||||
{
|
||||
natid cn;
|
||||
struct natstr *natp;
|
||||
int totpop;
|
||||
int totwant;
|
||||
int whichwants;
|
||||
|
||||
whichwants = totpop = totwant = 0;
|
||||
for (cn = 1; 0 != (natp = getnatp(cn)); cn++) {
|
||||
/* Only countries which are normal. */
|
||||
/* Should probably include sanctuaries ..... */
|
||||
if (((natp->nat_stat & NORM) == NORM) &&
|
||||
((natp->nat_stat & GOD) != GOD)) {
|
||||
totpop++;
|
||||
if ((natp->nat_update & WUPD_WANT) == WUPD_WANT) {
|
||||
totwant++;
|
||||
if (which == cn)
|
||||
whichwants++;
|
||||
}
|
||||
}
|
||||
}
|
||||
*want = totwant;
|
||||
*pop = totpop;
|
||||
return(whichwants);
|
||||
}
|
||||
|
||||
static int
|
||||
demand_check(void)
|
||||
{
|
||||
extern int update_wantmin,update_missed;
|
||||
struct natstr *natp;
|
||||
int want, pop, cn, veto;
|
||||
time_t now;
|
||||
time_t cur;
|
||||
extern long last_demand_update;
|
||||
|
||||
time(&cur);
|
||||
|
||||
/*
|
||||
if (last_demand_update == 0){
|
||||
natp=getnatp(0);
|
||||
last_demand_update = natp->nat_reserve;
|
||||
}
|
||||
|
||||
logerror("last_demand_update = %d\n",last_demand_update);
|
||||
logerror("update_between = %d\n",update_between());
|
||||
logerror("now = %d\n",cur);
|
||||
diff = (cur-(last_demand_update + update_between()));
|
||||
logerror("diff = %d\n",diff);
|
||||
if (diff >= 0){
|
||||
logerror("Forced update!\n");
|
||||
last_demand_update = cur;
|
||||
for (cn = 1; natp = getnatp(cn); cn++){
|
||||
if (((natp->nat_stat & NORM) == NORM) &&
|
||||
((natp->nat_stat & GOD) != GOD)){
|
||||
natp->nat_missed = 0;
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
logerror("No forced update!\n");
|
||||
*/
|
||||
if (0 == update_wantmin) {
|
||||
logerror("no demand update allowed, wantmin = 0");
|
||||
return(0);
|
||||
}
|
||||
|
||||
demand_update_want(&want, &pop, 0);
|
||||
if (want < update_wantmin) {
|
||||
logerror("no demand update, want = %d, min = %d",
|
||||
want, update_wantmin);
|
||||
return(0);
|
||||
}
|
||||
|
||||
time(&now);
|
||||
if (!demand_update_time(&now)) {
|
||||
logerror("no demand update, not within hours allowed.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
veto=0;
|
||||
for (cn = 1; 0 != (natp = getnatp(cn)); cn++){
|
||||
if (((natp->nat_stat & NORM) == NORM) &&
|
||||
((natp->nat_stat & GOD) != GOD)){
|
||||
if (natp->nat_missed >= update_missed)
|
||||
veto=cn+1;
|
||||
}
|
||||
}
|
||||
|
||||
if (veto){
|
||||
logerror("no demand update, %d has missed more than %d updates",
|
||||
veto-1, update_missed);
|
||||
return(0);
|
||||
}
|
||||
|
||||
last_demand_update = cur;
|
||||
natp=getnatp(0);
|
||||
/* A dumb way to do it, but simple */
|
||||
last_demand_update = natp->nat_reserve;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Check if enough countries want an update,
|
||||
* and if demand updates are allowed now.
|
||||
*/
|
||||
int
|
||||
demandupdatecheck(void)
|
||||
{
|
||||
extern int update_demandpolicy;
|
||||
|
||||
if (UDDEM_COMSET != update_demandpolicy) {
|
||||
logerror("no demand update, not policy.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(demand_check());
|
||||
}
|
||||
|
||||
/* Is it time for a regular or scheduled update?
|
||||
* As well, if none of the above, check to see if
|
||||
* a demand update can occur.
|
||||
*/
|
||||
int
|
||||
updatetime(time_t *now)
|
||||
{
|
||||
extern int update_policy;
|
||||
int which;
|
||||
|
||||
if (opt_BLITZ && update_policy == UDP_BLITZ) {
|
||||
logerror("BLITZ Update.");
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (UDP_NORMAL == update_policy) {
|
||||
logerror("Regular update, etu type.");
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (UDP_TIMES == update_policy) {
|
||||
if (scheduled_update_time(now, &which)) {
|
||||
logerror("Scheduled update, %d.", which);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
if (opt_DEMANDUPDATE) {
|
||||
if (demand_check()) {
|
||||
logerror("Demand update, at check time.");
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Return the time, and delta seconds, of the next update.
|
||||
* If the policy is no regular updates, return the time of
|
||||
* the next possible check.
|
||||
*/
|
||||
void
|
||||
next_update_time(time_t *now, time_t *tim, time_t *delta)
|
||||
/* From when */
|
||||
/* Time of next update */
|
||||
/* Seconds till next update */
|
||||
{
|
||||
extern int update_policy;
|
||||
time_t stim, sdelta;
|
||||
extern int blitz_time;
|
||||
|
||||
switch (update_policy) {
|
||||
case UDP_NORMAL:
|
||||
regular_update_time(now, tim, delta);
|
||||
break;
|
||||
case UDP_TIMES:
|
||||
if (!next_scheduled_time(now, tim, delta))
|
||||
regular_update_time(now, tim, delta);
|
||||
break;
|
||||
case UDP_BLITZ:
|
||||
*delta = (blitz_time * 60) - (*now % (blitz_time * 60));
|
||||
*tim = *now + *delta;
|
||||
break;
|
||||
|
||||
case UDP_NOREG:
|
||||
default:
|
||||
regular_update_time(now, tim, delta);
|
||||
if (next_scheduled_time(now, &stim, &sdelta)) {
|
||||
if (*delta > sdelta) {
|
||||
*delta = sdelta;
|
||||
*tim = stim;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
next_update_check_time(time_t *now, time_t *tim, time_t *delta)
|
||||
/* From when */
|
||||
/* Time of next update */
|
||||
/* Seconds till next update check */
|
||||
{
|
||||
extern int update_policy;
|
||||
time_t stim, sdelta;
|
||||
extern int blitz_time;
|
||||
|
||||
switch (update_policy) {
|
||||
case UDP_NORMAL:
|
||||
regular_update_time(now, tim, delta);
|
||||
break;
|
||||
case UDP_BLITZ:
|
||||
*delta = (blitz_time * 60) - (*now % (blitz_time * 60));
|
||||
*tim = *now + *delta;
|
||||
break;
|
||||
case UDP_TIMES:
|
||||
case UDP_NOREG:
|
||||
default:
|
||||
regular_update_time(now, tim, delta);
|
||||
if (next_scheduled_time(now, &stim, &sdelta)) {
|
||||
if (*delta > sdelta) {
|
||||
*delta = sdelta;
|
||||
*tim = stim;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
updates_disabled(void)
|
||||
{
|
||||
extern s_char *disablefil;
|
||||
int fd;
|
||||
|
||||
if ((fd = open(disablefil, O_RDONLY, 0)) < 0)
|
||||
return 0;
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
212
src/lib/common/xy.c
Normal file
212
src/lib/common/xy.c
Normal file
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* Empire - A multi-player, client/server Internet based war game.
|
||||
* Copyright (C) 1986-2000, 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* xy.c: x-y related conversion routines
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include "misc.h"
|
||||
#include "xy.h"
|
||||
#include "nat.h"
|
||||
#include "sect.h"
|
||||
#include "deity.h"
|
||||
#include "file.h"
|
||||
#include <stdio.h>
|
||||
#include "common.h"
|
||||
#include "optlist.h"
|
||||
|
||||
/*
|
||||
* return pointer to a string containing the x,y
|
||||
* coords as desired by a particular target country.
|
||||
*/
|
||||
s_char *
|
||||
xyas(coord x, coord y, natid country)
|
||||
{
|
||||
struct natstr *np;
|
||||
|
||||
np = getnatp(country);
|
||||
return prbuf("%d,%d", xrel(np, x), yrel(np, y));
|
||||
}
|
||||
|
||||
s_char *
|
||||
ownxy(struct sctstr *sp)
|
||||
{
|
||||
return xyas(sp->sct_x, sp->sct_y, sp->sct_own);
|
||||
}
|
||||
|
||||
coord
|
||||
xrel(struct natstr *np, coord absx)
|
||||
{
|
||||
coord x;
|
||||
|
||||
if ((np->nat_stat & STAT_ABS) == 0) {
|
||||
x = XNORM(absx - np->nat_xorg);
|
||||
} else {
|
||||
x = XNORM(absx);
|
||||
}
|
||||
if (x >= WORLD_X/2)
|
||||
x -= WORLD_X;
|
||||
else if (x < -WORLD_X/2)
|
||||
x += WORLD_X;
|
||||
return x;
|
||||
}
|
||||
|
||||
coord
|
||||
yrel(struct natstr *np, coord absy)
|
||||
{
|
||||
coord y;
|
||||
|
||||
if ((np->nat_stat & STAT_ABS) == 0) {
|
||||
y = YNORM(absy - np->nat_yorg);
|
||||
} else {
|
||||
y = YNORM(absy);
|
||||
}
|
||||
if (y >= WORLD_Y/2)
|
||||
y -= WORLD_Y;
|
||||
else if (y < -WORLD_Y/2)
|
||||
y += WORLD_Y;
|
||||
return y;
|
||||
}
|
||||
|
||||
void
|
||||
xyrelrange(struct natstr *np, struct range *src, struct range *dst)
|
||||
{
|
||||
dst->lx = xrel(np, src->lx);
|
||||
dst->hx = xrel(np, src->hx);
|
||||
dst->ly = yrel(np, src->ly);
|
||||
dst->hy = yrel(np, src->hy);
|
||||
dst->width = src->width;
|
||||
dst->height = src->height;
|
||||
}
|
||||
|
||||
void
|
||||
xyabsrange(struct natstr *np, struct range *src, struct range *dst)
|
||||
{
|
||||
dst->lx = xabs(np, src->lx);
|
||||
dst->hx = xabs(np, src->hx);
|
||||
dst->ly = yabs(np, src->ly);
|
||||
dst->hy = yabs(np, src->hy);
|
||||
dst->width = src->width;
|
||||
dst->height = src->height;
|
||||
}
|
||||
|
||||
void
|
||||
inputxy(coord *xp, coord *yp, natid cn)
|
||||
{
|
||||
struct natstr *np;
|
||||
|
||||
np = getnatp(cn);
|
||||
*xp = xabs(np, *xp);
|
||||
*yp = yabs(np, *yp);
|
||||
}
|
||||
|
||||
coord
|
||||
xabs(struct natstr *np, coord relx)
|
||||
{
|
||||
if ((np->nat_stat & STAT_ABS) == 0)
|
||||
relx += np->nat_xorg;
|
||||
return XNORM(relx);
|
||||
}
|
||||
|
||||
coord
|
||||
yabs(struct natstr *np, coord rely)
|
||||
{
|
||||
if ((np->nat_stat & STAT_ABS) == 0)
|
||||
rely += np->nat_yorg;
|
||||
return YNORM(rely);
|
||||
}
|
||||
|
||||
int
|
||||
sctoff(coord x, coord y)
|
||||
{
|
||||
if ((x + y) & 01) {
|
||||
logerror("%d,%d is an invalid sector specification!\n", x, y);
|
||||
return -1;
|
||||
}
|
||||
return (YNORM(y) * WORLD_X + XNORM(x))/2;
|
||||
}
|
||||
|
||||
coord
|
||||
xnorm(register coord x)
|
||||
{
|
||||
if (x < 0)
|
||||
x = WORLD_X - (-x % WORLD_X);
|
||||
return x % WORLD_X;
|
||||
}
|
||||
|
||||
coord
|
||||
ynorm(register coord y)
|
||||
{
|
||||
if (y < 0)
|
||||
y = WORLD_Y - (-y % WORLD_Y);
|
||||
return y % WORLD_Y;
|
||||
}
|
||||
|
||||
int
|
||||
xyinrange(coord x, coord y, struct range *rp)
|
||||
{
|
||||
if (rp->lx < rp->hx) {
|
||||
/* xrange doesn't wrap */
|
||||
if (x < rp->lx || x > rp->hx)
|
||||
return 0;
|
||||
} else {
|
||||
if (x < rp->lx && x > rp->hx)
|
||||
return 0;
|
||||
}
|
||||
if (rp->ly < rp->hy) {
|
||||
/* yrange doesn't wrap */
|
||||
if (y < rp->ly || y > rp->hy)
|
||||
return 0;
|
||||
} else {
|
||||
if (y < rp->ly && y > rp->hy)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
s_char *
|
||||
prbuf(s_char *format, ...)
|
||||
{
|
||||
static int nbuf = -1;
|
||||
static s_char buf[20][1024];
|
||||
va_list ap;
|
||||
|
||||
if (++nbuf > 19)
|
||||
nbuf = 0;
|
||||
|
||||
va_start(ap, format);
|
||||
(void) vsprintf(buf[nbuf], format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return buf[nbuf];
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue