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/update/Makefile
Normal file
67
src/lib/update/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/libupdate.a
|
||||
NTLIB = $(SRCDIR)\lib\libupdate.lib
|
||||
|
||||
OBJS = age.o anno.o bp.o deliver.o distribute.o finish.o human.o land.o \
|
||||
main.o material.o mobility.o move_sat.o nat.o nav_ship.o nav_util.o \
|
||||
nxtitemp.o nxtsctp.o plague.o plane.o populace.o prepare.o produce.o \
|
||||
removewants.o revolt.o sail.o sect.o ship.o
|
||||
|
||||
NTOBJS = age.obj anno.obj bp.obj deliver.obj distribute.obj finish.obj \
|
||||
human.obj land.obj main.obj material.obj mobility.obj move_sat.obj \
|
||||
nat.obj nav_ship.obj nav_util.obj nxtitemp.obj nxtsctp.obj plague.obj \
|
||||
plane.obj populace.obj prepare.obj produce.obj removewants.obj \
|
||||
revolt.obj sail.obj sect.obj ship.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
|
102
src/lib/update/age.c
Normal file
102
src/lib/update/age.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* age.c: Age people
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "update.h"
|
||||
#include "gen.h"
|
||||
|
||||
void
|
||||
age_levels(int etu)
|
||||
{
|
||||
extern float level_age_rate;
|
||||
register float best_tech;
|
||||
register float best_res;
|
||||
register struct natstr *np;
|
||||
int i;
|
||||
double level;
|
||||
double delta;
|
||||
int deltares;
|
||||
|
||||
best_tech = 0.0;
|
||||
best_res = 0.0;
|
||||
for (i=0; NULL != (np = getnatp(i)); i++) {
|
||||
if ((np->nat_stat & STAT_NORM) == 0)
|
||||
continue;
|
||||
|
||||
if (np->nat_stat & STAT_GOD)
|
||||
continue;
|
||||
|
||||
if (np->nat_stat == VIS)
|
||||
continue;
|
||||
|
||||
if (best_tech < np->nat_level[NAT_TLEV])
|
||||
best_tech = np->nat_level[NAT_TLEV];
|
||||
if (best_res < np->nat_level[NAT_RLEV])
|
||||
best_res = np->nat_level[NAT_RLEV];
|
||||
if (level_age_rate != 0.0) {
|
||||
delta = np->nat_level[NAT_RLEV] * etu /
|
||||
(100 * level_age_rate);
|
||||
np->nat_level[NAT_RLEV] -= delta;
|
||||
delta = np->nat_level[NAT_TLEV] * etu /
|
||||
(100 * level_age_rate);
|
||||
np->nat_level[NAT_TLEV] -= delta;
|
||||
}
|
||||
/*
|
||||
* age reserves by 1% per every 24 etus
|
||||
*/
|
||||
deltares = -roundavg(np->nat_reserve * etu / 2400.0);
|
||||
if (deltares != 0)
|
||||
np->nat_reserve += deltares;
|
||||
/* Chad Zabel - above number is negative ( was a -= there
|
||||
which was wrong. */
|
||||
}
|
||||
best_tech /= 5;
|
||||
best_res /= 5;
|
||||
for (i=0; NULL != (np = getnatp(i)); i++) {
|
||||
if ((np->nat_stat & STAT_INUSE) == 0)
|
||||
continue;
|
||||
if (np->nat_stat & STAT_GOD)
|
||||
continue;
|
||||
if (np->nat_stat == VIS)
|
||||
continue;
|
||||
level = np->nat_level[NAT_TLEV];
|
||||
if (level < best_tech && chance(0.2))
|
||||
np->nat_level[NAT_TLEV] += (best_tech - level) / 3;
|
||||
level = np->nat_level[NAT_RLEV];
|
||||
if (level < best_res && chance(0.2))
|
||||
np->nat_level[NAT_RLEV] += (best_res - level) / 3;
|
||||
}
|
||||
}
|
||||
|
137
src/lib/update/anno.c
Normal file
137
src/lib/update/anno.c
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* anno.c: Delete announcements older than ANNO_KEEP_DAYS
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Ken Stevens, 1995
|
||||
* Doug Hay, 1998
|
||||
* Steve McClure, 2000
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "tel.h"
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <sys/file.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "update.h"
|
||||
#include "common.h"
|
||||
|
||||
void
|
||||
delete_old_announcements(void)
|
||||
{
|
||||
time_t now;
|
||||
time_t old;
|
||||
struct telstr tgm;
|
||||
FILE *oldfp;
|
||||
int tmpfd;
|
||||
s_char tmp_filename[1024];
|
||||
int writeit;
|
||||
s_char message[MAXTELSIZE];
|
||||
int deleted = 0;
|
||||
int saved = 0;
|
||||
int length;
|
||||
int nbytes;
|
||||
int first = 1;
|
||||
|
||||
time(&now);
|
||||
old = now - days(ANNO_KEEP_DAYS);
|
||||
logerror("Deleting annos older than %s", ctime(&old));
|
||||
|
||||
#if !defined(_WIN32)
|
||||
if ((oldfp = fopen(annfil, "r+")) == 0) {
|
||||
#else
|
||||
if ((oldfp = fopen(annfil, "r+b")) == 0) {
|
||||
#endif
|
||||
logerror("can't read telegram file %s", annfil);
|
||||
return;
|
||||
}
|
||||
sprintf(tmp_filename, "%s.tmp", annfil);
|
||||
#if !defined(_WIN32)
|
||||
if ((tmpfd = open(tmp_filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) {
|
||||
#else
|
||||
if ((tmpfd = open(tmp_filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666)) < 0) {
|
||||
#endif
|
||||
logerror("can't write telegram file %s", tmp_filename);
|
||||
return;
|
||||
}
|
||||
while (fread((s_char *) &tgm, sizeof(tgm), 1, oldfp) == 1) {
|
||||
writeit = 1;
|
||||
if (tgm.tel_length < 0) {
|
||||
logerror("bad telegram file header (length)");
|
||||
return;
|
||||
}
|
||||
if (tgm.tel_type < 0 || tgm.tel_type > TEL_LAST) {
|
||||
logerror("bad telegram file header (type)");
|
||||
writeit = 0;
|
||||
}
|
||||
if (first) {
|
||||
first = 0;
|
||||
if (tgm.tel_date >= old) {
|
||||
fclose(oldfp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (tgm.tel_date < old) {
|
||||
writeit = 0;
|
||||
}
|
||||
|
||||
if (writeit) {
|
||||
if (write(tmpfd, &tgm, sizeof(tgm)) < (int)sizeof(tgm)) {
|
||||
logerror("error writing to ann.tmp");
|
||||
return;
|
||||
}
|
||||
++saved;
|
||||
} else {
|
||||
++deleted;
|
||||
}
|
||||
length = tgm.tel_length;
|
||||
while (length > 0) {
|
||||
nbytes = length;
|
||||
if (nbytes > (int)sizeof(message))
|
||||
nbytes = sizeof(message);
|
||||
(void) fread(message, sizeof(s_char), nbytes, oldfp);
|
||||
if (writeit) {
|
||||
if (write(tmpfd, message, nbytes) < nbytes) {
|
||||
logerror("Error writing to ann.tmp");
|
||||
return;
|
||||
}
|
||||
}
|
||||
length -= nbytes;
|
||||
}
|
||||
}
|
||||
logerror("%d announcements deleted; %d announcements saved",
|
||||
deleted, saved);
|
||||
fclose(oldfp);
|
||||
close(tmpfd);
|
||||
unlink(annfil);
|
||||
rename(tmp_filename, annfil);
|
||||
}
|
97
src/lib/update/bp.c
Normal file
97
src/lib/update/bp.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* bp.c: Functions for build pointer (bp) handling
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Ville Virrankoski, 1996
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "sect.h"
|
||||
#include "var.h"
|
||||
#include "budg.h"
|
||||
#include "update.h"
|
||||
#include "common.h"
|
||||
#include "optlist.h"
|
||||
|
||||
static int bud_key[I_MAX+2] = {0,1,2,3,4,0,0,0,0,0,0,5,6,0,0,7};
|
||||
|
||||
int
|
||||
*get_wp(int *bp, struct sctstr *sp, int cm)
|
||||
{
|
||||
return (bp + (sp->sct_x + (sp->sct_y * WORLD_X)) + WORLD_X * WORLD_Y * (cm - 1));
|
||||
}
|
||||
|
||||
int
|
||||
gt_bg_nmbr(int *bp, struct sctstr *sp, int comm)
|
||||
{
|
||||
int *wp;
|
||||
int cm;
|
||||
int svec[I_MAX+1];
|
||||
|
||||
if ((cm = bud_key[comm]) == 0) {
|
||||
getvec(VT_ITEM, svec, (s_char *)sp, EF_SECTOR);
|
||||
return svec[comm];
|
||||
} else {
|
||||
wp = get_wp(bp, sp, cm);
|
||||
return *wp;
|
||||
}
|
||||
}
|
||||
|
||||
void pt_bg_nmbr(int *bp, struct sctstr *sp, int comm, int amount)
|
||||
{
|
||||
int *wp;
|
||||
int cm;
|
||||
|
||||
if ((cm = bud_key[comm]) != 0) {
|
||||
wp = get_wp(bp, sp, cm);
|
||||
*wp = amount;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fill_update_array(int *bp, struct sctstr *sp)
|
||||
{
|
||||
int vec[I_MAX+1];
|
||||
int i, k;
|
||||
int *wp;
|
||||
|
||||
if (getvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR) <= 0)
|
||||
return;
|
||||
for (i=1;i<=I_MAX;i++)
|
||||
if ((k = bud_key[i]) != 0) {
|
||||
wp = get_wp(bp, sp, k);
|
||||
*wp = vec[i];
|
||||
}
|
||||
wp = get_wp(bp, sp, bud_key[I_MAX+1]);
|
||||
*wp = sp->sct_avail;
|
||||
}
|
||||
|
||||
|
119
src/lib/update/deliver.c
Normal file
119
src/lib/update/deliver.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* deliver.c: Deliver commodities to neighboring sector
|
||||
*
|
||||
* Known contributors to this file:
|
||||
*
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "item.h"
|
||||
#include "path.h"
|
||||
#include "file.h"
|
||||
#include "xy.h"
|
||||
#include "update.h"
|
||||
#include "subs.h"
|
||||
#include "common.h"
|
||||
|
||||
int
|
||||
deliver(register struct sctstr *from, struct ichrstr *ip, int dir, int thresh, int amt_src, int plague)
|
||||
{
|
||||
register struct sctstr *to;
|
||||
int vtype; /* item vartype */
|
||||
int pack_src;
|
||||
int amt_moved;
|
||||
int amt_dst;
|
||||
int mobility;
|
||||
float mcost;
|
||||
struct dchrstr *dp;
|
||||
int n;
|
||||
|
||||
if (dir <= 0 || dir > DIR_UL)
|
||||
return 0;
|
||||
if (amt_src <= 0)
|
||||
return 0;
|
||||
if ((amt_moved = amt_src - thresh) <= 0)
|
||||
return 0;
|
||||
/*
|
||||
* make sure delivery looks ok. Check where its going,
|
||||
* where its coming from, and see if there is more than
|
||||
* the threshold amount
|
||||
*/
|
||||
if (!military_control(from))
|
||||
return 0;
|
||||
to = getsectp(from->sct_x+diroff[dir][0], from->sct_y+diroff[dir][1]);
|
||||
if (to->sct_own != from->sct_own) {
|
||||
wu(0, from->sct_own, "%s delivery walkout at %s\n",
|
||||
ip->i_name, ownxy(from));
|
||||
return 0;
|
||||
}
|
||||
dp = &dchr[from->sct_type];
|
||||
vtype = ip->i_vtype;
|
||||
pack_src = ip->i_pkg[dp->d_pkg];
|
||||
mobility = from->sct_mobil / 2;
|
||||
if (vtype == V_CIVIL && from->sct_own != from->sct_oldown) {
|
||||
wu(0, from->sct_own, "The conquered populace in %s refuses to relocate!\n", ownxy(from));
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* disallow delivery into prohibited sectors.
|
||||
* calculate unit movement cost; decrease amount if
|
||||
* there isn't enough mobility.
|
||||
*/
|
||||
mcost = sector_mcost(to, MOB_ROAD)*ip->i_lbs/pack_src;
|
||||
mcost /= 4.0;
|
||||
|
||||
if (mobility < mcost * amt_moved) {
|
||||
/* XXX can mcost be == 0? */
|
||||
amt_moved = (int) (mobility / mcost);
|
||||
if (amt_moved <= 0)
|
||||
return 0;
|
||||
}
|
||||
amt_dst = getvar(vtype, (caddr_t)to, EF_SECTOR);
|
||||
if (amt_moved + amt_dst > 9990) {
|
||||
/* delivery backlog */
|
||||
if ((amt_moved = 9990 - amt_dst) <= 0)
|
||||
return 0;
|
||||
}
|
||||
if (putvar(vtype, amt_moved + amt_dst, (s_char *)to, EF_SECTOR) < 0) {
|
||||
/* "No room to deliver commodities */
|
||||
wu(0, from->sct_own, "no room for %s in %s\n",
|
||||
ip->i_name, ownxy(to));
|
||||
return 0;
|
||||
}
|
||||
/* deliver the plague too! */
|
||||
if (plague == PLG_INFECT && getvar(V_PSTAGE, (s_char *)to,EF_SECTOR) == 0)
|
||||
putvar(V_PSTAGE, PLG_EXPOSED, (s_char *)to, EF_SECTOR);
|
||||
n = from->sct_mobil - (int) (mcost * amt_moved);
|
||||
if (n < 0)
|
||||
n = 0;
|
||||
from->sct_mobil = n;
|
||||
return amt_moved;
|
||||
}
|
223
src/lib/update/distribute.c
Normal file
223
src/lib/update/distribute.c
Normal file
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* distribute.c: Do distribution to sectors
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Steve McClure, 1998
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "nat.h"
|
||||
#include "sect.h"
|
||||
#include "item.h"
|
||||
#include "xy.h"
|
||||
#include "path.h"
|
||||
#include "file.h"
|
||||
#include "distribute.h"
|
||||
#include "update.h"
|
||||
#include "subs.h"
|
||||
#include "common.h"
|
||||
|
||||
int
|
||||
dodistribute(struct sctstr *sp, int imex, s_char *path, double dist_i_cost, double dist_e_cost)
|
||||
/* import or export? */
|
||||
{
|
||||
struct sctstr *getdistsp();
|
||||
float distpathcost();
|
||||
struct ichrstr *ip;
|
||||
struct sctstr *dist;
|
||||
int amt;
|
||||
int thresh;
|
||||
int amt_dist;
|
||||
int amt_sect;
|
||||
int packing;
|
||||
float imcost;
|
||||
float excost;
|
||||
int dist_packing;
|
||||
int diff;
|
||||
int item;
|
||||
int dists[I_MAX+1];
|
||||
int remote[I_MAX+1];
|
||||
int local[I_MAX+1];
|
||||
int changed;
|
||||
int rplague;
|
||||
int lplague;
|
||||
|
||||
getvec(VT_ITEM, local, (s_char *)sp, EF_SECTOR);
|
||||
if ((sp->sct_dist_x == sp->sct_x) && (sp->sct_dist_y == sp->sct_y))
|
||||
return 0;
|
||||
|
||||
if (getvec(VT_DIST, dists, (s_char *)sp, EF_SECTOR) <= 0)
|
||||
return 0;
|
||||
|
||||
if (path == (s_char *)0){
|
||||
if (sp->sct_own != 0) {
|
||||
if (imex == EXPORT) /* only want this once */
|
||||
wu(0,sp->sct_own,"No path to dist sector for %s\n",
|
||||
ownxy(sp));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
dist = getsectp(sp->sct_dist_x,sp->sct_dist_y);
|
||||
if (dist->sct_effic >= 60)
|
||||
dist_packing = dchr[dist->sct_type].d_pkg;
|
||||
else
|
||||
dist_packing = NPKG; /* No packing */
|
||||
|
||||
if (sp->sct_effic >= 60)
|
||||
packing = dchr[sp->sct_type].d_pkg;
|
||||
else
|
||||
packing = NPKG; /* No packing */
|
||||
|
||||
if ((dist->sct_effic >= 60) && dchr[dist->sct_type].d_pkg == WPKG)
|
||||
packing = dchr[dist->sct_type].d_pkg;
|
||||
|
||||
getvec(VT_ITEM, remote, (s_char *)dist, EF_SECTOR);
|
||||
lplague = rplague = changed = 0;
|
||||
for (item = 1; item < I_MAX+1; item++) {
|
||||
if (dists[item] == 0)
|
||||
continue;
|
||||
ip = &ichr[item];
|
||||
thresh = dists[item];
|
||||
/*
|
||||
* calculate costs for importing and exporting.
|
||||
* the div 10.0 is because delivering straight through
|
||||
* to the dist sect is cheaper than stopping at each
|
||||
* sector along the way (processor-timewise)
|
||||
*/
|
||||
excost = (dist_e_cost/ip->i_pkg[packing] * ip->i_lbs) / 10.0;
|
||||
imcost = (dist_i_cost/ip->i_pkg[dist_packing] *ip->i_lbs)/10.0;
|
||||
amt_sect = local[item];
|
||||
amt_dist = remote[item];
|
||||
diff = amt_sect - thresh;
|
||||
if (item == I_CIVIL)
|
||||
if (sp->sct_own != sp->sct_oldown)
|
||||
continue;
|
||||
if (item == I_CIVIL)
|
||||
if (dist->sct_own != dist->sct_oldown)
|
||||
continue;
|
||||
if (diff < 0){
|
||||
if (imex != IMPORT)
|
||||
continue;
|
||||
|
||||
if (!military_control(dist))
|
||||
continue;
|
||||
|
||||
diff = -diff;
|
||||
/*
|
||||
* import.
|
||||
* don't import if no mobility.
|
||||
* check to make sure have enough mobility in the
|
||||
* dist sector to import what we need.
|
||||
*/
|
||||
if (dist->sct_mobil <= 0) {
|
||||
/*logerror(" dist mobil < 0");*/
|
||||
continue;
|
||||
}
|
||||
amt = diff;
|
||||
if (item == I_CIVIL)
|
||||
amt_dist--; /* Don't send your last civ */
|
||||
|
||||
if (amt_dist < amt) {
|
||||
amt = amt_dist;
|
||||
if (amt_dist == 0)
|
||||
continue;
|
||||
}
|
||||
if (dist->sct_mobil < imcost * amt)
|
||||
amt = dist->sct_mobil / imcost;
|
||||
|
||||
lplague++;
|
||||
/* XXX replace with vector assign and putvec() */
|
||||
remote[item] -= amt;
|
||||
changed++;
|
||||
dist->sct_mobil -= (int) (imcost * amt);
|
||||
local[item] += amt;
|
||||
} else {
|
||||
if (imex != EXPORT)
|
||||
continue;
|
||||
if (!military_control(sp))
|
||||
continue;
|
||||
if ((item == I_CIVIL)&&(sp->sct_work < 100))
|
||||
continue;
|
||||
if ((item == I_CIVIL)&&(sp->sct_own != sp->sct_oldown))
|
||||
continue;
|
||||
/*
|
||||
* export.
|
||||
* don't export if no mobility. check to make sure we
|
||||
* have mobility enough to do the right thing.
|
||||
* also make sure that there's enough space in the
|
||||
* target sector to hold the required amt.
|
||||
*/
|
||||
if (sp->sct_mobil <= 0) {
|
||||
/*logerror(" sp mob is zero");*/
|
||||
continue;
|
||||
}
|
||||
amt = diff;
|
||||
if (amt > amt_sect)
|
||||
amt = amt_sect;
|
||||
if (sp->sct_mobil < excost * amt)
|
||||
amt = sp->sct_mobil / excost;
|
||||
if (amt + amt_dist > 9999)
|
||||
amt = 9999 - amt_dist;
|
||||
if (amt == 0)
|
||||
continue;
|
||||
/* XXX replace with vector assign and putvec() */
|
||||
|
||||
rplague++;
|
||||
local[item] -= amt;
|
||||
changed++;
|
||||
sp->sct_mobil -= (int) (excost * amt);
|
||||
remote[item] += amt;
|
||||
}
|
||||
}
|
||||
putvec(VT_ITEM, remote, (s_char *)dist, EF_SECTOR);
|
||||
putvec(VT_ITEM, local, (s_char *)sp, EF_SECTOR);
|
||||
|
||||
if (lplague) {
|
||||
lplague = getvar(V_PSTAGE, (s_char *)dist, EF_SECTOR);
|
||||
if (lplague == PLG_INFECT &&
|
||||
getvar(V_PSTAGE, (s_char *)sp, EF_SECTOR) == PLG_HEALTHY) {
|
||||
putvar(V_PSTAGE, PLG_EXPOSED, (s_char *)sp, EF_SECTOR);
|
||||
}
|
||||
}
|
||||
|
||||
if (rplague) {
|
||||
rplague = getvar(V_PSTAGE, (s_char *)sp, EF_SECTOR);
|
||||
if (rplague == PLG_INFECT &&
|
||||
getvar(V_PSTAGE, (s_char *)dist, EF_SECTOR) == PLG_HEALTHY) {
|
||||
putvar(V_PSTAGE, PLG_EXPOSED, (s_char *)dist, EF_SECTOR);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
270
src/lib/update/finish.c
Normal file
270
src/lib/update/finish.c
Normal file
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* finish.c: Finish the update
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Thomas Ruschak, 1993
|
||||
* 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 "path.h"
|
||||
#include "distribute.h"
|
||||
#include "update.h"
|
||||
#include "common.h"
|
||||
#include "optlist.h"
|
||||
|
||||
/* Used for building up distribution info */
|
||||
struct distinfo {
|
||||
s_char *path; /* path to take */
|
||||
double imcost; /* import cost */
|
||||
double excost; /* export cost */
|
||||
};
|
||||
|
||||
/* This is our global buffer of distribution pointers. Note that
|
||||
* We only malloc this once, and never again (until reboot time
|
||||
* of course :) ) We do clear it each and every time. */
|
||||
struct distinfo *g_distptrs = (struct distinfo *)0;
|
||||
|
||||
/* Note that even though we malloc and save the path, it is never
|
||||
* used. Thus, this option. If you want to malloc and save every
|
||||
* path and then free when done, just enable this. Or, if the
|
||||
* dodistribute ever uses the path for something other than checking
|
||||
* to see that a path exists, enable this */
|
||||
/* #define SAVE_FINISH_PATHS */
|
||||
|
||||
#ifndef SAVE_FINISH_PATHS
|
||||
static s_char *finish_path = "h"; /* Placeholder indicating path exists */
|
||||
#endif /* SAVE_FINISH_PATHS */
|
||||
|
||||
static void assemble_dist_paths(struct distinfo *distptrs);
|
||||
s_char *BestDistPath();
|
||||
s_char *ReversePath(s_char *path);
|
||||
double pathcost();
|
||||
|
||||
void
|
||||
finish_sects(int etu)
|
||||
{
|
||||
register struct sctstr *sp;
|
||||
struct natstr *np;
|
||||
int n;
|
||||
int vec[I_MAX+1];
|
||||
int changed;
|
||||
struct distinfo *infptr;
|
||||
|
||||
if (g_distptrs == (struct distinfo *)0) {
|
||||
logerror("First update since reboot, allocating buffer\n");
|
||||
/* Allocate the information buffer */
|
||||
g_distptrs = (struct distinfo *)(malloc((WORLD_X * WORLD_Y) *
|
||||
sizeof(struct distinfo)));
|
||||
if (g_distptrs == (struct distinfo *)0) {
|
||||
logerror("malloc failed in finish_sects.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
logerror("Allocated '%d' bytes '%d' indices\n",
|
||||
((WORLD_X * WORLD_Y) * sizeof(struct distinfo)),
|
||||
(WORLD_X * WORLD_Y));
|
||||
|
||||
}
|
||||
|
||||
/* Wipe it clean */
|
||||
bzero((s_char *)g_distptrs, ((WORLD_X * WORLD_Y) *
|
||||
sizeof(struct distinfo)));
|
||||
|
||||
logerror("delivering...\n");
|
||||
/* Do deliveries */
|
||||
for (n=0; NULL != (sp = getsectid(n)); n++) {
|
||||
if (sp->sct_type == SCT_WATER)
|
||||
continue;
|
||||
if (sp->sct_own == 0)
|
||||
continue;
|
||||
np = getnatp(sp->sct_own);
|
||||
if (np->nat_money < 0)
|
||||
continue;
|
||||
changed = 0;
|
||||
if (getvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR) > 0)
|
||||
changed += dodeliver(sp, vec);
|
||||
if (changed)
|
||||
putvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
|
||||
}
|
||||
logerror("done delivering\n");
|
||||
|
||||
logerror("assembling paths...\n");
|
||||
|
||||
/* First, enable the best_path cacheing */
|
||||
bp_enable_cachepath();
|
||||
|
||||
/* Now assemble the paths */
|
||||
assemble_dist_paths(g_distptrs);
|
||||
|
||||
/* Now disable the best_path cacheing */
|
||||
bp_disable_cachepath();
|
||||
|
||||
/* Now, clear the best_path cache that may have been created */
|
||||
bp_clear_cachepath();
|
||||
|
||||
logerror("done assembling paths\n");
|
||||
|
||||
logerror("exporting...");
|
||||
for (n=0; NULL != (sp = getsectid(n)); n++) {
|
||||
if (sp->sct_type == SCT_WATER || sp->sct_own == 0)
|
||||
continue;
|
||||
np = getnatp(sp->sct_own);
|
||||
if (np->nat_money < 0)
|
||||
continue;
|
||||
/* Get the pointer */
|
||||
infptr = &g_distptrs[XYOFFSET(sp->sct_x, sp->sct_y)];
|
||||
dodistribute(sp, EXPORT,
|
||||
infptr->path, infptr->imcost, infptr->excost);
|
||||
}
|
||||
logerror("done exporting\n");
|
||||
|
||||
/* Note that we free the paths (if allocated) as we loop here */
|
||||
logerror("importing...");
|
||||
for (n=0; NULL != (sp = getsectid(n)); n++) {
|
||||
/* Get the pointer (we do it first so we can free if needed) */
|
||||
infptr = &g_distptrs[XYOFFSET(sp->sct_x, sp->sct_y)];
|
||||
if (sp->sct_type == SCT_WATER || sp->sct_own == 0) {
|
||||
#ifdef SAVE_FINISH_PATHS
|
||||
if (infptr->path)
|
||||
free((s_char *)infptr->path);
|
||||
#endif /* SAVE_FINISH_PATHS */
|
||||
continue;
|
||||
}
|
||||
np = getnatp(sp->sct_own);
|
||||
if (np->nat_money < 0) {
|
||||
#ifdef SAVE_FINISH_PATHS
|
||||
if (infptr->path)
|
||||
free((s_char *)infptr->path);
|
||||
#endif /* SAVE_FINISH_PATHS */
|
||||
continue;
|
||||
}
|
||||
dodistribute(sp, IMPORT,
|
||||
infptr->path, infptr->imcost, infptr->excost);
|
||||
#ifdef SAVE_FINISH_PATHS
|
||||
if (infptr->path)
|
||||
free((s_char *)infptr->path);
|
||||
#endif /* SAVE_FINISH_PATHS */
|
||||
}
|
||||
logerror("done importing\n");
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
assemble_dist_paths(struct distinfo *distptrs)
|
||||
{
|
||||
s_char *path, *p;
|
||||
double d;
|
||||
struct sctstr *sp;
|
||||
struct sctstr *dist;
|
||||
struct distinfo *infptr;
|
||||
int n;
|
||||
s_char buf[512];
|
||||
|
||||
for (n=0; NULL != (sp = getsectid(n)); n++) {
|
||||
if ((sp->sct_dist_x == sp->sct_x) && (sp->sct_dist_y == sp->sct_y))
|
||||
continue;
|
||||
/* Set the pointer */
|
||||
infptr = &distptrs[XYOFFSET(sp->sct_x, sp->sct_y)];
|
||||
/* now, get the dist sector */
|
||||
dist = getsectp(sp->sct_dist_x, sp->sct_dist_y);
|
||||
if (dist == (struct sctstr *)0){
|
||||
logerror("Bad dist sect %d,%d for %d,%d !\n",sp->sct_dist_x,
|
||||
sp->sct_dist_y,sp->sct_x,sp->sct_y);
|
||||
continue;
|
||||
}
|
||||
/* Now, get the best distribution path over roads */
|
||||
/* Note we go from the dist center to the sector. This gives
|
||||
us the import path for that sector. */
|
||||
path = BestDistPath(buf, dist, sp, &d, MOB_ROAD);
|
||||
|
||||
/* Now, we have a path */
|
||||
if (path != (s_char *)0) {
|
||||
#ifdef SAVE_FINISH_PATHS
|
||||
int len;
|
||||
/* Here we malloc a buffer and save it */
|
||||
len = strlen(path);
|
||||
infptr->path = (s_char *)malloc(len);
|
||||
if (infptr->path == (s_char *)0) {
|
||||
logerror("malloc failed in assemble_dist_path!\n");
|
||||
return;
|
||||
}
|
||||
#endif /* SAVE_FINISH_PATHS */
|
||||
/* Save the import cost */
|
||||
infptr->imcost = d;
|
||||
/* Now, reverse the path */
|
||||
p = ReversePath(path);
|
||||
/* And walk the path back to the dist center to get the export
|
||||
cost */
|
||||
infptr->excost = pathcost(sp, p, MOB_ROAD);
|
||||
#ifdef SAVE_FINISH_PATHS
|
||||
bcopy(p, infptr->path, len);
|
||||
#else
|
||||
infptr->path = finish_path;
|
||||
#endif /* SAVE_FINISH_PATHS */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s_char
|
||||
*ReversePath(s_char *path)
|
||||
{
|
||||
s_char *patharray = "aucdefjhigklmyopqrstbvwxnz";
|
||||
static s_char new_path[512];
|
||||
int ind;
|
||||
|
||||
if (path == (s_char *)0)
|
||||
return (s_char *)0;
|
||||
|
||||
ind = strlen(path);
|
||||
if (ind == 0)
|
||||
return (s_char *)0;
|
||||
|
||||
if (path[ind - 1] == 'h')
|
||||
ind--;
|
||||
|
||||
new_path[ind--] = '\0';
|
||||
new_path[ind] = '\0';
|
||||
|
||||
while (ind >= 0) {
|
||||
new_path[ind--] = patharray[*(path++) - 'a'];
|
||||
}
|
||||
|
||||
return new_path;
|
||||
}
|
||||
|
326
src/lib/update/human.c
Normal file
326
src/lib/update/human.c
Normal file
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* human.c: Food related functions
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Steve McClure, 1996
|
||||
*/
|
||||
|
||||
#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 "budg.h"
|
||||
#include "player.h"
|
||||
#include "update.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
#include "subs.h"
|
||||
|
||||
/*
|
||||
* feed the individual sector
|
||||
*
|
||||
*/
|
||||
int
|
||||
do_feed(register struct sctstr *sp, register struct natstr *np, int *vec, int *workp, int *bp, int etu)
|
||||
{
|
||||
extern double eatrate;
|
||||
int people;
|
||||
int work_avail;
|
||||
int starved, sctwork;
|
||||
int needed, dummy;
|
||||
int civvies, uws;
|
||||
int mil;
|
||||
int maxpop;
|
||||
|
||||
/* grow people & stuff */
|
||||
sctwork = sp->sct_work;
|
||||
|
||||
maxpop = max_pop(np->nat_level[NAT_RLEV], sp);
|
||||
civvies = (vec[I_CIVIL] > maxpop) ? maxpop : vec[I_CIVIL];
|
||||
uws = (vec[I_UW] > maxpop) ? maxpop : vec[I_UW];
|
||||
mil = (vec[I_MILIT] > maxpop) ? maxpop : vec[I_MILIT];
|
||||
work_avail = total_work(sctwork, etu, civvies, mil, uws);
|
||||
|
||||
people = vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW];
|
||||
if (sp->sct_type != SCT_SANCT) {
|
||||
if (opt_NOFOOD == 0) {
|
||||
if (vec[I_FOOD] < 1 + etu * people * eatrate) {
|
||||
/* need to grow "emergency rations" */
|
||||
work_avail -= (2 *
|
||||
growfood(sp, vec, (int)(work_avail/2), etu));
|
||||
/* It's twice as hard to grow those than norm*/
|
||||
pt_bg_nmbr(bp, sp, I_MAX+1, work_avail);
|
||||
if (!player->simulation)
|
||||
sp->sct_avail = work_avail;
|
||||
}
|
||||
if ((vec[I_FOOD] < 1 + etu * people * eatrate) &&
|
||||
(sp->sct_own == sp->sct_oldown)){
|
||||
|
||||
/* steal food from warehouses, headquarters,
|
||||
supply ships in port, or supply units */
|
||||
int needed;
|
||||
|
||||
needed = ldround((double)(1+etu*people*eatrate),1);
|
||||
|
||||
/* Now, find some food */
|
||||
vec[I_FOOD] = supply_commod(sp->sct_own,sp->sct_x,
|
||||
sp->sct_y,I_FOOD,needed);
|
||||
|
||||
}
|
||||
}
|
||||
starved = feed_people(vec, etu, &needed);
|
||||
if ((starved > 0 && sp->sct_own) && (!player->simulation)) {
|
||||
/* don't report POGO starvation */
|
||||
wu(0, sp->sct_own, "%d starved in %s.\n", starved,
|
||||
xyas(sp->sct_x, sp->sct_y, sp->sct_own));
|
||||
if (starved > 25)
|
||||
nreport(sp->sct_own, N_DIE_FAMINE, 0, 1);
|
||||
}
|
||||
if (starved > 0) {
|
||||
if (!player->simulation)
|
||||
starvation(sp);
|
||||
sctwork = 0;
|
||||
} else {
|
||||
if (sp->sct_work < 100)
|
||||
sctwork = sp->sct_work + 8 + (random() % 15);
|
||||
if (sctwork > 100)
|
||||
sctwork = 100;
|
||||
if (!player->simulation)
|
||||
sp->sct_work = sctwork;
|
||||
dummy = grow_people(sp, etu, np, &work_avail, sctwork, vec);
|
||||
}
|
||||
} else
|
||||
sctwork = sp->sct_work = 100;
|
||||
/* Here is where we truncate extra people, always */
|
||||
trunc_people(sp, np, vec);
|
||||
|
||||
pt_bg_nmbr(bp, sp, I_CIVIL, vec[I_CIVIL]);
|
||||
pt_bg_nmbr(bp, sp, I_UW, vec[I_UW]);
|
||||
pt_bg_nmbr(bp, sp, I_MILIT, vec[I_MILIT]);
|
||||
*workp = work_avail;
|
||||
return sctwork;
|
||||
}
|
||||
|
||||
int
|
||||
growfood(struct sctstr *sp, register int *vec, int work, int etu)
|
||||
{
|
||||
extern double fgrate;
|
||||
extern double fcrate;
|
||||
double food_fertil;
|
||||
double food_workers;
|
||||
double food;
|
||||
int work_used;
|
||||
|
||||
/* I'm being very nice and commenting out this so players
|
||||
* won't whine about starvation
|
||||
if (sp->sct_fertil == 0 || work == 0)
|
||||
return 0;
|
||||
*/
|
||||
food_workers = work * fcrate;
|
||||
food_fertil = etu * sp->sct_fertil * fgrate;
|
||||
food = food_fertil;
|
||||
if (food > food_workers)
|
||||
food = food_workers;
|
||||
/*
|
||||
* be nice; grow minimum one food unit.
|
||||
* This makes life simpler for the player.
|
||||
*/
|
||||
vec[I_FOOD] += (int) food;
|
||||
if (vec[I_FOOD] == 0)
|
||||
vec[I_FOOD] = 1;
|
||||
if (vec[I_FOOD] > 9999)
|
||||
vec[I_FOOD] = 9999;
|
||||
work_used = (int) food / fcrate;
|
||||
return work_used;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the number who starved, if any.
|
||||
*/
|
||||
int
|
||||
feed_people(register int *vec, int etu, int *needed)
|
||||
{
|
||||
extern double eatrate;
|
||||
double food_eaten;
|
||||
double people_left;
|
||||
int can_eat;
|
||||
int total_people;
|
||||
int to_starve;
|
||||
int starved;
|
||||
|
||||
if (opt_NOFOOD)
|
||||
return 0;
|
||||
food_eaten = (double)(((double)etu * (double)eatrate) *
|
||||
(double)(vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW]));
|
||||
if (food_eaten <= 1)
|
||||
return 0;
|
||||
starved = 0;
|
||||
*needed = 0;
|
||||
if (food_eaten > vec[I_FOOD]) {
|
||||
*needed = food_eaten - vec[I_FOOD];
|
||||
if ((double)(*needed) < (double)(food_eaten - (double)vec[I_FOOD]))
|
||||
(*needed)++;
|
||||
if (opt_NEW_STARVE) {
|
||||
can_eat = (vec[I_FOOD] / (etu * eatrate));
|
||||
total_people = vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW];
|
||||
|
||||
/* only want to starve off at most 1/2 the populace. */
|
||||
if (can_eat < (total_people/2))
|
||||
can_eat = total_people/2;
|
||||
|
||||
to_starve = total_people - can_eat;
|
||||
while(to_starve && vec[I_UW]){
|
||||
to_starve--;
|
||||
starved++;
|
||||
vec[I_UW]--;
|
||||
}
|
||||
while(to_starve && vec[I_CIVIL]){
|
||||
to_starve--;
|
||||
starved++;
|
||||
vec[I_CIVIL]--;
|
||||
}
|
||||
while(to_starve && vec[I_MILIT]){
|
||||
to_starve--;
|
||||
starved++;
|
||||
vec[I_MILIT]--;
|
||||
}
|
||||
|
||||
vec[I_FOOD] = 0;
|
||||
}
|
||||
else { /* ! opt_NEW_STARVE */
|
||||
|
||||
people_left = (vec[I_FOOD] + 0.01) / (food_eaten + 0.01);
|
||||
starved = vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW];
|
||||
/* only want to starve off at most 1/2 the populace. */
|
||||
if (people_left < 0.5)
|
||||
people_left = 0.5;
|
||||
vec[I_CIVIL] = (int) (vec[I_CIVIL] * people_left);
|
||||
vec[I_MILIT] = (int) (vec[I_MILIT] * people_left);
|
||||
vec[I_UW] = (int) (vec[I_UW] * people_left);
|
||||
starved -= vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW];
|
||||
vec[I_FOOD] = 0;
|
||||
} /* end opt_NEW_STARVE */
|
||||
} else {
|
||||
vec[I_FOOD] -= roundavg(food_eaten);
|
||||
}
|
||||
return starved;
|
||||
}
|
||||
|
||||
/*
|
||||
* Truncate any extra people that may be around
|
||||
*/
|
||||
void
|
||||
trunc_people(struct sctstr *sp, register struct natstr *np, register int *vec)
|
||||
{
|
||||
int maxpop = max_pop(np->nat_level[NAT_RLEV], sp);
|
||||
|
||||
if (vec[I_CIVIL] > maxpop)
|
||||
vec[I_CIVIL] = maxpop;
|
||||
if (vec[I_UW] > maxpop)
|
||||
vec[I_UW] = maxpop;
|
||||
}
|
||||
|
||||
/*
|
||||
* Grow babies, and add to populace.
|
||||
* XXX Might think about dropping in a birth
|
||||
* rate limitation on countries with high tech
|
||||
* production? Maybe with just high education?
|
||||
*/
|
||||
int grow_people(struct sctstr *sp, register int etu, register struct natstr *np, int *workp, int sctwork, register int *vec)
|
||||
{
|
||||
extern double obrate;
|
||||
extern double uwbrate;
|
||||
extern double babyeat;
|
||||
int newciv;
|
||||
int newuw;
|
||||
int new_birth;
|
||||
int new_food;
|
||||
int maxpop = max_pop(np->nat_level[NAT_RLEV], sp);
|
||||
|
||||
newciv = 0;
|
||||
newuw = 0;
|
||||
if (vec[I_CIVIL] < maxpop) {
|
||||
new_birth = (int) roundavg(obrate * (double)(etu * vec[I_CIVIL]));
|
||||
if (opt_NOFOOD)
|
||||
new_food = (int) (0.5 + maxpop / (2.0 * babyeat));
|
||||
else /* we are using food */
|
||||
new_food = (int) (0.5 + vec[I_FOOD] / (2.0 * babyeat));
|
||||
|
||||
newciv = new_birth;
|
||||
if (newciv > new_food)
|
||||
newciv = new_food;
|
||||
/* Now, check max pops */
|
||||
if ((vec[I_CIVIL] + newciv) > maxpop)
|
||||
newciv = maxpop - vec[I_CIVIL];
|
||||
vec[I_CIVIL] += newciv;
|
||||
}
|
||||
if (vec[I_UW] < maxpop) {
|
||||
/*
|
||||
* now grow uw's
|
||||
*/
|
||||
new_birth = (int) roundavg(uwbrate * (double)(etu * vec[I_UW]));
|
||||
if (opt_NOFOOD)
|
||||
new_food = (int) (0.5 + maxpop / (2.0 * babyeat));
|
||||
else /* food is important */
|
||||
new_food = (int) (0.5 + vec[I_FOOD] / (2.0 * babyeat));
|
||||
|
||||
newuw = new_birth;
|
||||
if (newuw > new_food)
|
||||
newuw = new_food;
|
||||
/* Now, check max pops */
|
||||
if ((vec[I_UW] + newuw) > maxpop)
|
||||
newuw = maxpop - vec[I_UW];
|
||||
vec[I_UW] += newuw;
|
||||
}
|
||||
/*
|
||||
* subtract the baby eat food (if we are using FOOD) and return
|
||||
* # of births.
|
||||
*/
|
||||
if (opt_NOFOOD == 0 && (newciv || newuw))
|
||||
vec[I_FOOD] -= roundavg((newciv + newuw) * babyeat);
|
||||
*workp += total_work(sctwork, etu, newciv, 0, newuw);
|
||||
return newciv + newuw;
|
||||
}
|
||||
|
||||
/*
|
||||
* percentage of people who starved
|
||||
*/
|
||||
void
|
||||
starvation(struct sctstr *sp)
|
||||
{
|
||||
sp->sct_work = 0;
|
||||
sp->sct_loyal += (random() % 8) + 2;
|
||||
}
|
439
src/lib/update/land.c
Normal file
439
src/lib/update/land.c
Normal file
|
@ -0,0 +1,439 @@
|
|||
/*
|
||||
* 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: Do production for land units
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Thomas Ruschak, 1992
|
||||
* Steve McClure, 1996
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "nat.h"
|
||||
#include "land.h"
|
||||
#include "ship.h"
|
||||
#include "var.h"
|
||||
#include "news.h"
|
||||
#include "file.h"
|
||||
#include "product.h"
|
||||
#include "optlist.h"
|
||||
#include "budg.h"
|
||||
#include "player.h"
|
||||
#include "update.h"
|
||||
#include "lost.h"
|
||||
#include "common.h"
|
||||
#include "subs.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
|
||||
int mil_dbl_pay;
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x) > (y) ? (y) : (x))
|
||||
#endif
|
||||
|
||||
void upd_land(register struct lndstr *lp, int landno, register int etus, struct natstr *np, int *bp, int build);
|
||||
|
||||
int
|
||||
prod_land(int etus, int natnum, int *bp, int build)
|
||||
/* build = 1, maintain = 0 */
|
||||
{
|
||||
register struct lndstr *lp;
|
||||
struct sctstr *sp;
|
||||
struct natstr *np;
|
||||
int n, k=0;
|
||||
extern long lnd_money[MAXNOC];
|
||||
int start_money;
|
||||
int lastx = 9999, lasty = 9999;
|
||||
|
||||
bp_enable_cachepath();
|
||||
for (n=0; NULL != (lp = getlandp(n)); n++) {
|
||||
if (lp->lnd_own == 0)
|
||||
continue;
|
||||
if (lp->lnd_own != natnum)
|
||||
continue;
|
||||
|
||||
sp = getsectp(lp->lnd_x,lp->lnd_y);
|
||||
if (sp->sct_type == SCT_SANCT)
|
||||
continue;
|
||||
if (lastx == 9999 || lasty == 9999) {
|
||||
lastx = lp->lnd_x;
|
||||
lasty = lp->lnd_y;
|
||||
}
|
||||
if (lastx != lp->lnd_x || lasty != lp->lnd_y) {
|
||||
/* Reset the cache */
|
||||
bp_disable_cachepath();
|
||||
bp_clear_cachepath();
|
||||
bp_enable_cachepath();
|
||||
}
|
||||
np = getnatp(lp->lnd_own);
|
||||
start_money = np->nat_money;
|
||||
upd_land(lp, n, etus, np, bp, build);
|
||||
lnd_money[lp->lnd_own] += np->nat_money - start_money;
|
||||
if ((build && (np->nat_money != start_money)) || (!build))
|
||||
k++;
|
||||
if (player->simulation)
|
||||
np->nat_money = start_money;
|
||||
}
|
||||
bp_disable_cachepath();
|
||||
bp_clear_cachepath();
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
void
|
||||
upd_land(register struct lndstr *lp, int landno, register int etus, struct natstr *np, int *bp, int build)
|
||||
/* build = 1, maintain = 0 */
|
||||
{
|
||||
extern int morale_base;
|
||||
struct lchrstr *lcp;
|
||||
int vec[I_MAX+1];
|
||||
int cvec[I_MAX+1];
|
||||
int n;
|
||||
double techfact(int, double);
|
||||
int min = morale_base-(int)np->nat_level[NAT_HLEV];
|
||||
int mult;
|
||||
extern double money_land;
|
||||
int needed;
|
||||
int cost;
|
||||
int eff;
|
||||
|
||||
if (!player->simulation)
|
||||
if (lp->lnd_retreat < min)
|
||||
lp->lnd_retreat = min;
|
||||
|
||||
lcp = &lchr[(int)lp->lnd_type];
|
||||
getvec(VT_ITEM, vec, (s_char *)lp, EF_LAND);
|
||||
if (build == 1){
|
||||
if (np->nat_priorities[PRI_LBUILD] == 0 ||
|
||||
np->nat_money < 0)
|
||||
return;
|
||||
if (lp->lnd_effic < LAND_MINEFF ||
|
||||
!(landrepair(lp,vec,np,bp,etus))){
|
||||
makelost(EF_LAND, lp->lnd_own, lp->lnd_uid, lp->lnd_x, lp->lnd_y);
|
||||
lp->lnd_own = 0;
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
mult = 1;
|
||||
if (np->nat_level[NAT_TLEV] < lp->lnd_tech * 0.85)
|
||||
mult = 2;
|
||||
if (lcp->l_flags & L_ENGINEER)
|
||||
mult *= 3;
|
||||
/* cost = -(mult * etus * dmin(0.0, money_land * LND_COST(lcp->l_cost, lp->lnd_tech - lcp->l_tech)));*/
|
||||
cost = -(mult * etus * dmin(0.0, money_land * lcp->l_cost));
|
||||
if ((np->nat_priorities[PRI_LMAINT] == 0 ||
|
||||
np->nat_money < cost) && !player->simulation) {
|
||||
if ((eff = lp->lnd_effic - etus/5) < LAND_MINEFF) {
|
||||
wu(0, lp->lnd_own,
|
||||
"%s lost to lack of maintenance\n",
|
||||
prland(lp));
|
||||
makelost(EF_LAND, lp->lnd_own, lp->lnd_uid, lp->lnd_x, lp->lnd_y);
|
||||
lp->lnd_own = 0;
|
||||
return;
|
||||
}
|
||||
wu(0, lp->lnd_own,
|
||||
"%s lost %d%% to lack of maintenance\n",
|
||||
prland(lp), lp->lnd_effic - eff);
|
||||
lp->lnd_effic = eff;
|
||||
} else {
|
||||
np->nat_money -= cost;
|
||||
}
|
||||
/* Mil costs are now part of regular mil costs, not maint costs */
|
||||
/* np->nat_money += (int) (money_mil * etus * lnd_getmil(lp));*/
|
||||
|
||||
/* Grab more stuff */
|
||||
if ((opt_NOFOOD == 0) && !player->simulation)
|
||||
resupply_commod(lp,I_FOOD);
|
||||
|
||||
getvec(VT_ITEM, vec, (s_char *)lp, EF_LAND);
|
||||
if (!player->simulation) {
|
||||
if ((n = feed_land(lp, vec, etus, &needed, 1)) > 0) {
|
||||
wu(0, lp->lnd_own, "%d starved in %s%s\n",
|
||||
n, prland(lp),
|
||||
(lp->lnd_effic < LAND_MINEFF ?
|
||||
", killing it" : ""));
|
||||
if (n > 10)
|
||||
nreport(lp->lnd_own, N_DIE_FAMINE, 0, 1);
|
||||
}
|
||||
/*
|
||||
* do plague stuff. plague can't break out on land units,
|
||||
* but it can still kill people on them.
|
||||
*/
|
||||
getvec(VT_COND, cvec, (s_char *)lp, EF_LAND);
|
||||
if (cvec[C_PSTAGE] > 0) {
|
||||
n = plague_people(np, vec, cvec, etus);
|
||||
switch (n) {
|
||||
case PLG_DYING:
|
||||
wu(0, lp->lnd_own,
|
||||
"PLAGUE deaths reported on %s\n",
|
||||
prland(lp));
|
||||
nreport(lp->lnd_own, N_DIE_PLAGUE, 0, 1);
|
||||
break;
|
||||
case PLG_INFECT:
|
||||
wu(0, lp->lnd_own, "%s battling PLAGUE\n",
|
||||
prland(lp));
|
||||
break;
|
||||
case PLG_INCUBATE:
|
||||
/* Are we still incubating? */
|
||||
if (n == cvec[C_PSTAGE]) {
|
||||
/* Yes. Will it turn "infectious" next time? */
|
||||
if (cvec[C_PTIME] <= etus) {
|
||||
/* Yes. Report an outbreak. */
|
||||
wu(0, lp->lnd_own,
|
||||
"Outbreak of PLAGUE on %s!\n",
|
||||
prland(lp));
|
||||
nreport(lp->lnd_own, N_OUT_PLAGUE, 0, 1);
|
||||
}
|
||||
} else {
|
||||
/* It has already moved on to "infectious" */
|
||||
wu(0, lp->lnd_own,
|
||||
"%s battling PLAGUE\n", prland(lp));
|
||||
}
|
||||
break;
|
||||
case PLG_EXPOSED:
|
||||
/* Has the plague moved to "incubation" yet? */
|
||||
if (n != cvec[C_PSTAGE]) {
|
||||
/* Yes. Will it turn "infectious" next time? */
|
||||
if (cvec[C_PTIME] <= etus) {
|
||||
/* Yes. Report an outbreak. */
|
||||
wu(0, lp->lnd_own,
|
||||
"Outbreak of PLAGUE on %s!\n",
|
||||
prland(lp));
|
||||
nreport(lp->lnd_own, N_OUT_PLAGUE, 0, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
putvec(VT_COND, cvec, (s_char *)lp, EF_LAND);
|
||||
}
|
||||
putvec(VT_ITEM, vec, (s_char *)lp, EF_LAND);
|
||||
} /* end !player->simulation */
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
landrepair(register struct lndstr *land, int *vec, struct natstr *np, int *bp, int etus)
|
||||
{
|
||||
extern int mil_dbl_pay;
|
||||
extern int land_grow_scale;
|
||||
register int delta;
|
||||
struct sctstr *sp;
|
||||
struct lchrstr *lp;
|
||||
float leftp, buildp;
|
||||
int left, build;
|
||||
int mil_needed, lcm_needed, hcm_needed, gun_needed, shell_needed;
|
||||
int avail;
|
||||
int w_p_eff;
|
||||
int mult;
|
||||
int svec[I_MAX+1];
|
||||
int mvec[I_MAX+1];
|
||||
|
||||
lp = &lchr[(int)land->lnd_type];
|
||||
sp = getsectp(land->lnd_x, land->lnd_y);
|
||||
if (sp->sct_off)
|
||||
return 1;
|
||||
getvec(VT_ITEM, svec, (s_char *)sp, EF_SECTOR);
|
||||
mult = 1;
|
||||
if (np->nat_level[NAT_TLEV] < land->lnd_tech * 0.85)
|
||||
mult = 2;
|
||||
|
||||
if (land->lnd_effic == 100) {
|
||||
/* land is ok; no repairs needed */
|
||||
return 1;
|
||||
}
|
||||
if (sp->sct_own != land->lnd_own)
|
||||
return 1;
|
||||
|
||||
if (!player->simulation)
|
||||
avail = sp->sct_avail * 100;
|
||||
else
|
||||
avail = gt_bg_nmbr(bp, sp, I_MAX+1) * 100;
|
||||
|
||||
w_p_eff = 20 + (lp->l_lcm + 2 * lp->l_hcm);
|
||||
delta = roundavg((double)avail/w_p_eff);
|
||||
if (delta <= 0)
|
||||
return 1;
|
||||
if (delta > etus*land_grow_scale)
|
||||
delta = etus*land_grow_scale;
|
||||
|
||||
/* delta is the max amount we can grow */
|
||||
|
||||
left = 100 - land->lnd_effic;
|
||||
if (left > delta)
|
||||
left = delta;
|
||||
|
||||
leftp = ((float)left/100.0);
|
||||
|
||||
bzero((s_char *)mvec, sizeof(mvec));
|
||||
mvec[I_LCM] = lcm_needed = ldround((double)(lp->l_lcm * leftp),1);
|
||||
mvec[I_HCM] = hcm_needed = ldround((double)(lp->l_hcm * leftp),1);
|
||||
/*
|
||||
mvec[I_GUN] = gun_needed = ldround((double)(lp->l_gun * leftp),1);
|
||||
mvec[I_MILIT] = mil_needed = ldround((double)(lp->l_mil * leftp),1);
|
||||
mvec[I_SHELL] = shell_needed = ldround((double)(lp->l_shell *leftp),1);
|
||||
*/
|
||||
mvec[I_GUN] = gun_needed = 0;
|
||||
mvec[I_MILIT] = mil_needed = 0;
|
||||
mvec[I_SHELL] = shell_needed = 0;
|
||||
|
||||
get_materials(sp, bp, mvec, 0);
|
||||
|
||||
if (mvec[I_MILIT]>=mil_needed)
|
||||
buildp=leftp;
|
||||
else
|
||||
buildp=((float)mvec[I_MILIT]/(float)lp->l_mil);
|
||||
if (mvec[I_LCM] < lcm_needed)
|
||||
buildp = MIN(buildp,((float)mvec[I_LCM]/(float)lp->l_lcm));
|
||||
if (mvec[I_HCM] < hcm_needed)
|
||||
buildp = MIN(buildp,((float)mvec[I_HCM]/(float)lp->l_hcm));
|
||||
if (mvec[I_GUN] < gun_needed)
|
||||
buildp = MIN(buildp,((float)mvec[I_GUN]/(float)lp->l_gun));
|
||||
if (mvec[I_SHELL] < shell_needed)
|
||||
buildp = MIN(buildp,((float)mvec[I_SHELL]/(float)lp->l_shell));
|
||||
|
||||
build=ldround((double)(buildp*100.0),1);
|
||||
|
||||
bzero((s_char *)mvec, sizeof(mvec));
|
||||
mvec[I_LCM] = lcm_needed = roundavg((double)(lp->l_lcm * buildp));
|
||||
mvec[I_HCM] = hcm_needed = roundavg((double)(lp->l_hcm * buildp));
|
||||
/*
|
||||
mvec[I_GUN] = gun_needed = roundavg((double)(lp->l_gun * buildp));
|
||||
mvec[I_MILIT] = mil_needed = roundavg((double)(lp->l_mil * buildp));
|
||||
mvec[I_SHELL] = shell_needed = roundavg((double)(lp->l_shell *buildp));
|
||||
*/
|
||||
mvec[I_GUN] = gun_needed = 0;
|
||||
mvec[I_MILIT] = mil_needed = 0;
|
||||
mvec[I_SHELL] = shell_needed = 0;
|
||||
mil_dbl_pay += mil_needed;
|
||||
|
||||
get_materials(sp, bp, mvec, 1);
|
||||
|
||||
if ((sp->sct_type != SCT_HEADQ) && (sp->sct_type != SCT_FORTR))
|
||||
build /= 3;
|
||||
|
||||
avail -= build * w_p_eff;
|
||||
if (!player->simulation) {
|
||||
sp->sct_avail = avail/100;
|
||||
if (sp->sct_avail < 0)
|
||||
sp->sct_avail = 0;
|
||||
} else {
|
||||
pt_bg_nmbr(bp, sp, I_MAX+1, avail/100);
|
||||
if (gt_bg_nmbr(bp, sp, I_MAX+1) < 0)
|
||||
pt_bg_nmbr(bp, sp, I_MAX+1, 0);
|
||||
}
|
||||
|
||||
if (build<0)
|
||||
logerror("land unit %d building %d ! \n",land->lnd_uid,build);
|
||||
np->nat_money -= mult * lp->l_cost * build / 100.0;
|
||||
if (!player->simulation) {
|
||||
land->lnd_effic += (s_char)build;
|
||||
|
||||
putsect(sp);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the number who starved, if any.
|
||||
*/
|
||||
int
|
||||
feed_land(struct lndstr *lp, register int *vec, int etus, int *needed, int doit)
|
||||
{
|
||||
extern double eatrate;
|
||||
double food_eaten, ship_eaten;
|
||||
double people_left;
|
||||
int can_eat, need, svec[I_MAX+1];
|
||||
int total_people;
|
||||
int starved;
|
||||
struct lchrstr *lcp;
|
||||
struct shpstr *sp;
|
||||
|
||||
if (opt_NOFOOD) return 0; /* no food no work to be done */
|
||||
|
||||
lcp = &lchr[(int)lp->lnd_type];
|
||||
|
||||
food_eaten = (etus * eatrate) * total_mil(lp);
|
||||
starved = 0;
|
||||
*needed = 0;
|
||||
/*
|
||||
* If we're on a ship, and we don't have enough food,
|
||||
* get some food off the carrying ship. (Don't starve
|
||||
* the ship, tho...
|
||||
*/
|
||||
/* doit - Only try to take food off the ship during the update */
|
||||
if ((food_eaten > vec[I_FOOD]) && (lp->lnd_ship >= 0) && doit){
|
||||
need = (int)food_eaten - vec[I_FOOD];
|
||||
sp = getshipp(lp->lnd_ship);
|
||||
getvec(VT_ITEM, svec, (s_char *)sp, EF_SHIP);
|
||||
ship_eaten = (etus * eatrate) *
|
||||
(svec[I_CIVIL]+svec[I_MILIT]+svec[I_UW]);
|
||||
if ((svec[I_FOOD]-need) > ship_eaten){
|
||||
vec[I_FOOD] += need;
|
||||
svec[I_FOOD] -= need;
|
||||
}
|
||||
else if ((svec[I_FOOD]-ship_eaten) > 0){
|
||||
vec[I_FOOD] += (svec[I_FOOD] - ship_eaten);
|
||||
svec[I_FOOD] -= (svec[I_FOOD] - ship_eaten);
|
||||
}
|
||||
putvec(VT_ITEM, svec, (s_char *)sp, EF_SHIP);
|
||||
}
|
||||
|
||||
if (food_eaten > vec[I_FOOD]) {
|
||||
*needed = food_eaten - vec[I_FOOD];
|
||||
if (*needed < (food_eaten - vec[I_FOOD]))
|
||||
(*needed)++;
|
||||
can_eat = (vec[I_FOOD] / (etus * eatrate));
|
||||
total_people = total_mil(lp);
|
||||
/* only want to starve off at most 1/2 the populace. */
|
||||
if (can_eat < (total_people/2))
|
||||
can_eat = total_people/2;
|
||||
|
||||
people_left = (vec[I_FOOD] + 0.01) / (food_eaten + 0.01);
|
||||
/* only want to starve off at most 1/2 the populace. */
|
||||
if (people_left < 0.5)
|
||||
people_left = 0.5;
|
||||
/* lp->lnd_effic *= people_left;*/
|
||||
starved = vec[I_MILIT] - (vec[I_MILIT] * people_left);
|
||||
/* if (!player->simulation)
|
||||
wu(0, lp->lnd_own, "%d mil starved on unit %s.\n",
|
||||
starved,
|
||||
prland(lp));*/
|
||||
vec[I_MILIT] -= starved;
|
||||
vec[I_FOOD] = 0;
|
||||
} else {
|
||||
vec[I_FOOD] -= (int)food_eaten;
|
||||
}
|
||||
return starved;
|
||||
}
|
||||
|
252
src/lib/update/main.c
Normal file
252
src/lib/update/main.c
Normal file
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* main.c: World update main function
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1994
|
||||
* Steve McClure, 1996
|
||||
* Doug Hay, 1998
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "sect.h"
|
||||
#include "player.h"
|
||||
#include "empthread.h"
|
||||
#include "var.h"
|
||||
#include "budg.h"
|
||||
#include "product.h"
|
||||
#include "player.h"
|
||||
#include "update.h"
|
||||
#include "common.h"
|
||||
#include "optlist.h"
|
||||
#include <stdlib.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
long money[MAXNOC];
|
||||
long pops[MAXNOC];
|
||||
long sea_money[MAXNOC];
|
||||
long lnd_money[MAXNOC];
|
||||
long air_money[MAXNOC];
|
||||
long tpops[MAXNOC];
|
||||
|
||||
extern int mil_dbl_pay;
|
||||
int update_pending = 0;
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
update_main(void *argv)
|
||||
{
|
||||
extern int etu_per_update;
|
||||
extern double money_res;
|
||||
int etu = etu_per_update;
|
||||
int n;
|
||||
int x;
|
||||
int *bp;
|
||||
int cn,cn2,rel;
|
||||
struct natstr *cnp;
|
||||
struct natstr *np;
|
||||
|
||||
/* First, make sure all mobility is updated correctly. */
|
||||
if (opt_MOB_ACCESS) {
|
||||
mob_ship(etu);
|
||||
mob_sect(etu);
|
||||
mob_plane(etu);
|
||||
mob_land(etu);
|
||||
}
|
||||
update_pending = 1;
|
||||
player->proc = empth_self();
|
||||
player->cnum = 0;
|
||||
player->god = 1;
|
||||
/*
|
||||
* set up all the variables which get used in the
|
||||
* sector production routine (for producing education,
|
||||
* happiness, and printing out the state of the nation)
|
||||
*/
|
||||
logerror("production update (%d etus)", etu);
|
||||
bzero((s_char *)pops, sizeof(pops));
|
||||
bzero((s_char *)air_money, sizeof(air_money));
|
||||
bzero((s_char *)sea_money, sizeof(sea_money));
|
||||
bzero((s_char *)lnd_money, sizeof(lnd_money));
|
||||
bp = (int *) calloc(WORLD_X * WORLD_Y * 7, sizeof(int));
|
||||
for (n=0; n<MAXNOC; n++) {
|
||||
money[n] = 0;
|
||||
if ((np = getnatp(n)) == (struct natstr *)0)
|
||||
continue;
|
||||
money[n] = np->nat_money;
|
||||
tpops[n] = count_pop(n);
|
||||
}
|
||||
|
||||
logerror("preparing sectors...");
|
||||
prepare_sects(etu, bp);
|
||||
logerror("done preparing sectors.");
|
||||
logerror("producing for countries...");
|
||||
for (x=0; x<MAXNOC; x++){
|
||||
int y,z,sb=0,sm=0,pb=0,pm=0,lm=0,lb=0;
|
||||
long p_sect[SCT_MAXDEF+1][2];
|
||||
|
||||
bzero((s_char *)p_sect, sizeof(p_sect));
|
||||
mil_dbl_pay = 0;
|
||||
if ((np = getnatp(x)) == (struct natstr *)0)
|
||||
continue;
|
||||
if (np->nat_stat & STAT_SANCT ) {
|
||||
#ifdef DEBUG
|
||||
logerror("Country %i is in sanctuary and did not update",x);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
np->nat_money += (int) (np->nat_reserve * money_res * etu);
|
||||
|
||||
for(y=1; y<SCT_MAXDEF+8; y++) {
|
||||
for(z=0; z<SCT_MAXDEF+8; z++) {
|
||||
if (np->nat_priorities[z] == y) {
|
||||
do_prod(z, etu, x, bp, p_sect,
|
||||
&sb, &sm, &pb, &pm, &lb, &lm);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 0 is maintain, 1 is build */
|
||||
if (!sm) prod_ship(etu, x, bp, 0);
|
||||
if (!sb) prod_ship(etu, x, bp, 1);
|
||||
if (!pm) prod_plane(etu, x, bp, 0);
|
||||
if (!pb) prod_plane(etu, x, bp, 1);
|
||||
if (!lm) prod_land(etu, x, bp, 0);
|
||||
if (!lb) prod_land(etu, x, bp, 1);
|
||||
|
||||
/* produce all sects that haven't produced yet */
|
||||
produce_sect(x, etu, bp, p_sect, -1);
|
||||
np->nat_money -= p_sect[SCT_CAPIT][1];
|
||||
}
|
||||
logerror("done producing for countries.");
|
||||
|
||||
finish_sects(etu);
|
||||
prod_nat(etu);
|
||||
age_levels(etu);
|
||||
free(bp);
|
||||
/*flushwu();*/
|
||||
if (opt_SLOW_WAR) {
|
||||
/* Update war declarations */
|
||||
/* MOBILIZATION->SITZKRIEG->AT_WAR */
|
||||
for (cn=1; cn < MAXNOC; cn++) {
|
||||
if ((cnp = getnatp(cn)) == 0)
|
||||
break;
|
||||
for (cn2=1; cn2 < MAXNOC; cn2++) {
|
||||
if (cn2 == cn)
|
||||
continue;
|
||||
rel=getrel(cnp,cn2);
|
||||
if (rel == MOBILIZATION){
|
||||
rel = SITZKRIEG;
|
||||
setrel(cn,cn2,rel);
|
||||
}
|
||||
else if (rel == SITZKRIEG){
|
||||
rel = AT_WAR;
|
||||
setrel(cn,cn2,rel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Age contact */
|
||||
if (opt_LOSE_CONTACT) {
|
||||
for (cn=1; cn<MAXNOC; cn++) {
|
||||
if ((cnp = getnatp(cn)) != NULL) agecontact(cnp);
|
||||
}
|
||||
}
|
||||
/* Only update mobility for non-MOB_ACCESS here, since it doesn't
|
||||
get done for MOB_ACCESS anyway during the update */
|
||||
if (!opt_MOB_ACCESS) {
|
||||
mob_ship(etu);
|
||||
mob_sect(etu);
|
||||
mob_plane(etu);
|
||||
mob_land(etu);
|
||||
}
|
||||
if (opt_DEMANDUPDATE)
|
||||
update_removewants();
|
||||
/* flush all mem file objects to disk */
|
||||
ef_flush(EF_NATION);
|
||||
ef_flush(EF_SECTOR);
|
||||
ef_flush(EF_SHIP);
|
||||
ef_flush(EF_PLANE);
|
||||
ef_flush(EF_LAND);
|
||||
delete_old_announcements();
|
||||
/* Clear all the telegram flags */
|
||||
for (cn = 0; cn < MAXNOC; cn++)
|
||||
clear_telegram_is_new(cn);
|
||||
update_pending = 0;
|
||||
logerror("End update");
|
||||
player_delete(player);
|
||||
empth_exit();
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
void
|
||||
do_prod(int sector_type, int etu, int n, int *bp, long int (*p_sect)[2], int *ship_build, int *ship_maint, int *plane_build, int *plane_maint, int *land_build, int *land_maint)
|
||||
{
|
||||
extern double money_mil;
|
||||
struct natstr *np;
|
||||
|
||||
np = getnatp(n);
|
||||
|
||||
if (sector_type == PRI_SMAINT){
|
||||
prod_ship(etu,n,bp,0);
|
||||
*ship_maint=1;
|
||||
}
|
||||
else
|
||||
if (sector_type == PRI_SBUILD){
|
||||
prod_ship(etu,n,bp,1);
|
||||
*ship_build=1;
|
||||
}
|
||||
else
|
||||
if (sector_type == PRI_PMAINT){
|
||||
prod_plane(etu,n,bp,0);
|
||||
*plane_maint=1;
|
||||
}
|
||||
else
|
||||
if (sector_type == PRI_PBUILD){
|
||||
prod_plane(etu,n,bp,1);
|
||||
*plane_build=1;
|
||||
}
|
||||
else
|
||||
if (sector_type == PRI_LMAINT){
|
||||
if (*land_build)
|
||||
np->nat_money -= (int) (money_mil * etu * mil_dbl_pay);
|
||||
prod_land(etu,n,bp,0);
|
||||
*land_maint=1;
|
||||
}
|
||||
else
|
||||
if (sector_type == PRI_LBUILD){
|
||||
prod_land(etu,n,bp,1);
|
||||
*land_build=1;
|
||||
}
|
||||
else {
|
||||
produce_sect(n,etu,bp,p_sect,sector_type);
|
||||
}
|
||||
}
|
||||
|
93
src/lib/update/material.c
Normal file
93
src/lib/update/material.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* material.c: Tries to find materials for production
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Ville Virrankoski, 1996
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "file.h"
|
||||
#include "optlist.h"
|
||||
#include "budg.h"
|
||||
#include "player.h"
|
||||
#include "update.h"
|
||||
#include "common.h"
|
||||
#include "subs.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x) > (y) ? (y) : (x))
|
||||
#endif
|
||||
|
||||
void
|
||||
get_materials(struct sctstr *sp, int *bp, int *mvec, int check)
|
||||
/* only check if found=0, remove them=1 */
|
||||
{
|
||||
struct sctstr *usp;
|
||||
int i;
|
||||
int used_already;
|
||||
int still_left;
|
||||
int svec[I_MAX+1];
|
||||
|
||||
getvec(VT_ITEM, svec, (s_char *)sp, EF_SECTOR);
|
||||
for(i=1;i<=I_MAX;i++) {
|
||||
if (mvec[i]==0)
|
||||
continue;
|
||||
|
||||
usp = sp;
|
||||
if (check) {
|
||||
still_left = gt_bg_nmbr(bp, sp, i);
|
||||
if ((still_left - mvec[i])<0)
|
||||
still_left = 0;
|
||||
else
|
||||
still_left -= mvec[i];
|
||||
|
||||
if (opt_GRAB_THINGS)
|
||||
mvec[i] = supply_commod(usp->sct_own, usp->sct_x, usp->sct_y,
|
||||
i, mvec[i]);
|
||||
pt_bg_nmbr(bp, sp, i, still_left);
|
||||
svec[i] = still_left;
|
||||
if (!player->simulation)
|
||||
putvec(VT_ITEM, svec, (s_char *)sp, EF_SECTOR);
|
||||
|
||||
} else {
|
||||
|
||||
if (opt_GRAB_THINGS) {
|
||||
used_already = svec[i] - gt_bg_nmbr(bp, sp, i);
|
||||
mvec[i] = try_supply_commod(usp->sct_own, usp->sct_x, usp->sct_y,
|
||||
i, (mvec[i] + used_already));
|
||||
mvec[i] -= used_already;
|
||||
} else { /* ! GRAB_THINGS */
|
||||
still_left = gt_bg_nmbr(bp, sp, i);
|
||||
mvec[i] = MIN(mvec[i], still_left);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
563
src/lib/update/mobility.c
Normal file
563
src/lib/update/mobility.c
Normal file
|
@ -0,0 +1,563 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* mobility.c: Add mobility to each of the items which accumulate mobility.
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Steve McClure, 1998-1999
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "ship.h"
|
||||
#include "land.h"
|
||||
#include "plane.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "optlist.h"
|
||||
#include "mission.h"
|
||||
#include "update.h"
|
||||
#include "gen.h"
|
||||
#include "subs.h"
|
||||
#include "optlist.h"
|
||||
|
||||
extern int timestamp_fixing;
|
||||
extern int update_pending;
|
||||
int do_upd_checking = 0;
|
||||
|
||||
|
||||
int
|
||||
increase_mob(time_t *counter, float mult)
|
||||
{
|
||||
time_t secs;
|
||||
time_t now;
|
||||
time_t left;
|
||||
extern long s_p_etu;
|
||||
extern int updating_mob;
|
||||
int newetus;
|
||||
float newmob;
|
||||
int inewmob;
|
||||
|
||||
time(&now);
|
||||
|
||||
secs = now - *counter;
|
||||
if (secs < 1 || secs < s_p_etu)
|
||||
return 0;
|
||||
newetus = (int)(secs / s_p_etu);
|
||||
if (newetus < 1)
|
||||
return 0;
|
||||
left = (secs % s_p_etu);
|
||||
do {
|
||||
newmob = (float)(newetus * mult);
|
||||
inewmob = (int)(newetus * mult);
|
||||
if (newmob == inewmob || newetus > 7)
|
||||
break;
|
||||
newetus--;
|
||||
left += s_p_etu;
|
||||
} while (newetus > 0);
|
||||
if (newetus <= 0)
|
||||
return 0;
|
||||
|
||||
time(counter);
|
||||
*counter = *counter - left;
|
||||
|
||||
if (updating_mob)
|
||||
return (newetus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
update_timestamps(time_t lastsavedtime)
|
||||
{
|
||||
struct shpstr *shipp;
|
||||
struct sctstr *sectp;
|
||||
struct lndstr *landp;
|
||||
struct plnstr *planep;
|
||||
int n;
|
||||
time_t now;
|
||||
time_t delta;
|
||||
|
||||
timestamp_fixing = 1;
|
||||
time(&now);
|
||||
delta = now - lastsavedtime;
|
||||
for (n = 0; (shipp = getshipp(n)); n++)
|
||||
shipp->shp_access += delta;
|
||||
for (n = 0; (sectp = getsectid(n)); n++)
|
||||
sectp->sct_access += delta;
|
||||
for (n = 0; (landp = getlandp(n)); n++)
|
||||
landp->lnd_access += delta;
|
||||
for (n = 0; (planep = getplanep(n)); n++)
|
||||
planep->pln_access += delta;
|
||||
timestamp_fixing = 0;
|
||||
}
|
||||
|
||||
void
|
||||
update_all_mob(void)
|
||||
{
|
||||
struct shpstr *shipp;
|
||||
struct sctstr *sectp;
|
||||
struct lndstr *landp;
|
||||
struct plnstr *planep;
|
||||
int n;
|
||||
|
||||
n = 0;
|
||||
while (1) {
|
||||
do_upd_checking = 1;
|
||||
shipp = getshipp(n);
|
||||
sectp = getsectid(n);
|
||||
landp = getlandp(n);
|
||||
planep = getplanep(n);
|
||||
do_upd_checking = 0;
|
||||
if (shipp)
|
||||
shp_do_upd_mob(shipp);
|
||||
if (sectp)
|
||||
sct_do_upd_mob(sectp);
|
||||
if (landp)
|
||||
lnd_do_upd_mob(landp);
|
||||
if (planep)
|
||||
pln_do_upd_mob(planep);
|
||||
if (!shipp && !sectp && !landp && !planep)
|
||||
break;
|
||||
n++;
|
||||
}
|
||||
do_upd_checking = 0;
|
||||
}
|
||||
|
||||
void
|
||||
sct_do_upd_mob(register struct sctstr *sp)
|
||||
{
|
||||
extern float sect_mob_scale;
|
||||
int etus;
|
||||
|
||||
if (do_upd_checking || timestamp_fixing || update_pending)
|
||||
return;
|
||||
if (sp->sct_own == 0)
|
||||
return;
|
||||
if (sp->sct_type == SCT_SANCT)
|
||||
return;
|
||||
if ((etus = increase_mob(&sp->sct_access, sect_mob_scale)) == 0)
|
||||
return;
|
||||
do_upd_checking = 1;
|
||||
do_mob_sect(sp, etus);
|
||||
/* putsect(sp);*/
|
||||
do_upd_checking = 0;
|
||||
}
|
||||
|
||||
void
|
||||
shp_do_upd_mob(register struct shpstr *sp)
|
||||
{
|
||||
extern float ship_mob_scale;
|
||||
int etus;
|
||||
|
||||
if (do_upd_checking || timestamp_fixing || update_pending)
|
||||
return;
|
||||
if (sp->shp_own == 0)
|
||||
return;
|
||||
if ((etus = increase_mob(&sp->shp_access, ship_mob_scale)) == 0)
|
||||
return;
|
||||
do_upd_checking = 1;
|
||||
do_mob_ship(sp, etus);
|
||||
do_upd_checking = 0;
|
||||
}
|
||||
|
||||
void
|
||||
lnd_do_upd_mob(register struct lndstr *lp)
|
||||
{
|
||||
extern float land_mob_scale;
|
||||
int etus;
|
||||
|
||||
if (do_upd_checking || timestamp_fixing || update_pending)
|
||||
return;
|
||||
if (lp->lnd_own == 0)
|
||||
return;
|
||||
if ((etus = increase_mob(&lp->lnd_access, land_mob_scale)) == 0)
|
||||
return;
|
||||
|
||||
do_upd_checking = 1;
|
||||
do_mob_land(lp, etus);
|
||||
do_upd_checking = 0;
|
||||
}
|
||||
|
||||
void
|
||||
pln_do_upd_mob(register struct plnstr *pp)
|
||||
{
|
||||
extern float plane_mob_scale;
|
||||
int etus;
|
||||
|
||||
if (do_upd_checking || timestamp_fixing || update_pending)
|
||||
return;
|
||||
if (pp->pln_own == 0)
|
||||
return;
|
||||
if ((etus = increase_mob(&pp->pln_access, plane_mob_scale)) == 0)
|
||||
return;
|
||||
|
||||
do_upd_checking = 1;
|
||||
do_mob_plane(pp, etus);
|
||||
do_upd_checking = 0;
|
||||
}
|
||||
|
||||
void
|
||||
mob_sect(register int etus)
|
||||
{
|
||||
register struct sctstr *sp;
|
||||
register int n;
|
||||
time_t now;
|
||||
|
||||
time(&now);
|
||||
for (n=0; NULL != (sp = getsectid(n)); n++) {
|
||||
sp->sct_timestamp = now;
|
||||
if (opt_MOB_ACCESS)
|
||||
sct_do_upd_mob(sp);
|
||||
else
|
||||
do_mob_sect(sp, etus);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
do_mob_sect(register struct sctstr *sp, register int etus)
|
||||
{
|
||||
extern float sect_mob_scale;
|
||||
extern int sect_mob_max;
|
||||
register int value;
|
||||
|
||||
if (sp->sct_own == 0)
|
||||
return;
|
||||
if (sp->sct_type == SCT_SANCT)
|
||||
return;
|
||||
/* Do we have to even bother? */
|
||||
if (sp->sct_mobil >= sect_mob_max) {
|
||||
/* No, so set just in case and then return */
|
||||
sp->sct_mobil = sect_mob_max;
|
||||
return;
|
||||
}
|
||||
value = sp->sct_mobil + ((float)etus * sect_mob_scale);
|
||||
if (value > sect_mob_max)
|
||||
value = sect_mob_max;
|
||||
sp->sct_mobil = value;
|
||||
}
|
||||
|
||||
void
|
||||
mob_ship(register int etus)
|
||||
{
|
||||
register struct shpstr *sp;
|
||||
register int n;
|
||||
time_t now;
|
||||
|
||||
time(&now);
|
||||
for (n=0; NULL != (sp = getshipp(n)); n++) {
|
||||
sp->shp_timestamp = now;
|
||||
if (opt_MOB_ACCESS)
|
||||
shp_do_upd_mob(sp);
|
||||
else
|
||||
do_mob_ship(sp, etus);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
do_mob_ship(register struct shpstr *sp, register int etus)
|
||||
{
|
||||
extern int ship_mob_max;
|
||||
extern float ship_mob_scale;
|
||||
int newfuel=0;
|
||||
register int value;
|
||||
int can_add,have_fuel_for,total_add;
|
||||
double d;
|
||||
extern int fuel_mult;
|
||||
|
||||
if (sp->shp_own == 0)
|
||||
return;
|
||||
|
||||
/* Do we even have to bother updating this mobility? */
|
||||
if (sp->shp_mobil >= ship_mob_max) {
|
||||
/* No, so don't. Just set it to max (just in case) and
|
||||
return. */
|
||||
sp->shp_mobil = ship_mob_max;
|
||||
return;
|
||||
}
|
||||
|
||||
if (opt_FUEL == 0) { /* only a bit to do ... */
|
||||
value = sp->shp_mobil + ((float)etus * ship_mob_scale);
|
||||
if (value > ship_mob_max)
|
||||
value = ship_mob_max;
|
||||
sp->shp_mobil = value;
|
||||
return; /* so we ship the FUEL stuff */
|
||||
}
|
||||
|
||||
/* opt_FUEL in force */
|
||||
if (mchr[(int)sp->shp_type].m_fuelu == 0) {
|
||||
value = sp->shp_mobil + ((float)etus * ship_mob_scale);
|
||||
if (value > ship_mob_max)
|
||||
value = ship_mob_max;
|
||||
sp->shp_mobil = (s_char)value;
|
||||
} else {
|
||||
can_add = ship_mob_max - sp->shp_mobil;
|
||||
if (can_add > ((float)etus*ship_mob_scale))
|
||||
can_add = ((float)etus*ship_mob_scale);
|
||||
have_fuel_for = ldround((((double)sp->shp_fuel /
|
||||
(double)mchr[(int)sp->shp_type].m_fuelu)*
|
||||
(double)fuel_mult),1);
|
||||
|
||||
if (can_add > have_fuel_for){
|
||||
int need;
|
||||
need = can_add - have_fuel_for;
|
||||
d = (double)need;
|
||||
d *= (double)mchr[(int)sp->shp_type].m_fuelu;
|
||||
d /= (double)fuel_mult;
|
||||
d /= 5.0;
|
||||
if ((d-(int)d) > 0.0)
|
||||
d++;
|
||||
need = (int)d;
|
||||
newfuel = supply_commod(sp->shp_own,sp->shp_x,
|
||||
sp->shp_y,I_PETROL,need);
|
||||
sp->shp_fuel += (u_char)(newfuel * 5);
|
||||
}
|
||||
|
||||
have_fuel_for = ldround((((double)sp->shp_fuel /
|
||||
(double)mchr[(int)sp->shp_type].m_fuelu)*
|
||||
(double)fuel_mult),1);
|
||||
|
||||
if (can_add > have_fuel_for){
|
||||
int need;
|
||||
need = can_add - have_fuel_for;
|
||||
d = (double)need;
|
||||
d *= (double)mchr[(int)sp->shp_type].m_fuelu;
|
||||
d /= (double)fuel_mult;
|
||||
d /= 50.0;
|
||||
if ((d-(int)d) > 0.0)
|
||||
d++;
|
||||
need = (int)d;
|
||||
newfuel = supply_commod(sp->shp_own,sp->shp_x,
|
||||
sp->shp_y,I_OIL,need);
|
||||
sp->shp_fuel += (u_char)(newfuel * 50);
|
||||
}
|
||||
|
||||
have_fuel_for = ldround((((double)sp->shp_fuel /
|
||||
(double)mchr[(int)sp->shp_type].m_fuelu)*
|
||||
(double)fuel_mult),1);
|
||||
|
||||
if (can_add > have_fuel_for)
|
||||
total_add = have_fuel_for;
|
||||
else
|
||||
total_add = can_add;
|
||||
d = (double)total_add;
|
||||
d *= (double)mchr[(int)sp->shp_type].m_fuelu;
|
||||
d /= (double)fuel_mult;
|
||||
sp->shp_fuel -= (u_char)ldround(d,1);
|
||||
sp->shp_fuel = (u_char)min(sp->shp_fuel,
|
||||
mchr[(int)sp->shp_type].m_fuelc);
|
||||
sp->shp_mobil += (s_char)total_add;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mob_land(register int etus)
|
||||
{
|
||||
register struct lndstr *lp;
|
||||
register int n;
|
||||
time_t now;
|
||||
|
||||
time(&now);
|
||||
for (n=0; NULL != (lp = getlandp(n)); n++) {
|
||||
lp->lnd_timestamp = now;
|
||||
if (opt_MOB_ACCESS)
|
||||
lnd_do_upd_mob(lp);
|
||||
else
|
||||
do_mob_land(lp, etus);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
do_mob_land(register struct lndstr *lp, register int etus)
|
||||
{
|
||||
extern int land_mob_max;
|
||||
extern float land_mob_scale;
|
||||
int newfuel=0;
|
||||
register int value;
|
||||
int can_add,have_fuel_for,total_add;
|
||||
double d;
|
||||
extern int fuel_mult;
|
||||
|
||||
if (lp->lnd_own == 0)
|
||||
return;
|
||||
|
||||
if (lp->lnd_mobil >= land_mob_max) {
|
||||
lp->lnd_mobil = land_mob_max;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Give damaged units a break. When at low
|
||||
* efficiency, units can go to -100 mob when
|
||||
* marching 1 step, making them slower than
|
||||
* normal mil. This helps take the curse off.
|
||||
* If MOB_ACCESS is on, we don't do this, as it would
|
||||
* be too much of an advantage. So, we just add double
|
||||
* the small amount of mob if we are < 0 instead.
|
||||
*/
|
||||
|
||||
if (!opt_MOB_ACCESS) {
|
||||
if (lp->lnd_mobil < 0)
|
||||
lp->lnd_mobil /= 2;
|
||||
}
|
||||
|
||||
if (opt_FUEL == 0) { /* just some bits and pieces */
|
||||
if (opt_MOB_ACCESS) {
|
||||
if (lp->lnd_mobil < 0)
|
||||
value = lp->lnd_mobil + (2 * ((float)etus * land_mob_scale));
|
||||
else
|
||||
value = lp->lnd_mobil + ((float)etus * land_mob_scale);
|
||||
} else {
|
||||
value = lp->lnd_mobil + ((float)etus * land_mob_scale);
|
||||
}
|
||||
if (value > land_mob_max)
|
||||
value = land_mob_max;
|
||||
lp->lnd_mobil = value;
|
||||
|
||||
return; /* Done! */
|
||||
}
|
||||
|
||||
/* opt_FUEL in force ... */
|
||||
if (lp->lnd_fuelu == 0){
|
||||
if (opt_MOB_ACCESS) {
|
||||
if (lp->lnd_mobil < 0)
|
||||
value = lp->lnd_mobil + (2 * ((float)etus * land_mob_scale));
|
||||
else
|
||||
value = lp->lnd_mobil + ((float)etus * land_mob_scale);
|
||||
} else {
|
||||
value = lp->lnd_mobil + ((float)etus * land_mob_scale);
|
||||
}
|
||||
if (value > land_mob_max)
|
||||
value = land_mob_max;
|
||||
lp->lnd_mobil = value;
|
||||
|
||||
} else {
|
||||
|
||||
can_add = land_mob_max - lp->lnd_mobil;
|
||||
|
||||
if (can_add > ((float)etus*land_mob_scale))
|
||||
can_add = ((float)etus*land_mob_scale);
|
||||
|
||||
have_fuel_for = (lp->lnd_fuel /
|
||||
lp->lnd_fuelu)*fuel_mult;
|
||||
|
||||
if (can_add > have_fuel_for){
|
||||
int need;
|
||||
need = can_add - have_fuel_for;
|
||||
d = (double)need;
|
||||
d *= (double)lp->lnd_fuelu;
|
||||
d /= (double)fuel_mult;
|
||||
d /= 5.0;
|
||||
if ((d-(int)d) > 0.0)
|
||||
d++;
|
||||
need = (int)d;
|
||||
newfuel = supply_commod(lp->lnd_own,lp->lnd_x,
|
||||
lp->lnd_y,I_PETROL,need);
|
||||
lp->lnd_fuel += (u_char)(newfuel * 5);
|
||||
}
|
||||
|
||||
have_fuel_for = (lp->lnd_fuel /
|
||||
lp->lnd_fuelu)*fuel_mult;
|
||||
|
||||
if (can_add > have_fuel_for){
|
||||
int need;
|
||||
need = can_add - have_fuel_for;
|
||||
d = (double)need;
|
||||
d *= (double)lp->lnd_fuelu;
|
||||
d /= (double)fuel_mult;
|
||||
d /= 50.0;
|
||||
if ((d-(int)d) > 0.0)
|
||||
d++;
|
||||
need = (int)d;
|
||||
newfuel = supply_commod(lp->lnd_own,lp->lnd_x,
|
||||
lp->lnd_y,I_OIL,need);
|
||||
lp->lnd_fuel += (u_char)(newfuel * 50);
|
||||
}
|
||||
|
||||
have_fuel_for = (lp->lnd_fuel /
|
||||
lp->lnd_fuelu)*fuel_mult;
|
||||
|
||||
if (can_add > have_fuel_for){
|
||||
total_add = have_fuel_for;
|
||||
}
|
||||
else
|
||||
total_add = can_add;
|
||||
d = (double)total_add;
|
||||
d *= (double)lp->lnd_fuelu;
|
||||
d /= (double)fuel_mult;
|
||||
lp->lnd_fuel -= (u_char)ldround(d,1);
|
||||
lp->lnd_fuel = (u_char)min(lp->lnd_fuel,
|
||||
lp->lnd_fuelc);
|
||||
if(total_add + lp->lnd_mobil > land_mob_max) {
|
||||
total_add = land_mob_max - lp->lnd_mobil;
|
||||
}
|
||||
|
||||
if (opt_MOB_ACCESS) {
|
||||
if (lp->lnd_mobil < 0)
|
||||
lp->lnd_mobil += (s_char)total_add;
|
||||
}
|
||||
lp->lnd_mobil += (s_char)total_add;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mob_plane(register int etus)
|
||||
{
|
||||
register struct plnstr *pp;
|
||||
register int n;
|
||||
time_t now;
|
||||
|
||||
time(&now);
|
||||
for (n=0; NULL != (pp = getplanep(n)); n++) {
|
||||
pp->pln_timestamp = now;
|
||||
if (opt_MOB_ACCESS)
|
||||
pln_do_upd_mob(pp);
|
||||
else
|
||||
do_mob_plane(pp, etus);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
do_mob_plane(register struct plnstr *pp, register int etus)
|
||||
{
|
||||
extern int plane_mob_max;
|
||||
extern float plane_mob_scale;
|
||||
register int value;
|
||||
|
||||
if (pp->pln_own == 0)
|
||||
return;
|
||||
if (pp->pln_mobil >= plane_mob_max) {
|
||||
pp->pln_mobil = plane_mob_max;
|
||||
return;
|
||||
}
|
||||
|
||||
value = pp->pln_mobil + ((float)etus * plane_mob_scale);
|
||||
if (value > plane_mob_max)
|
||||
value = plane_mob_max;
|
||||
pp->pln_mobil = value;
|
||||
}
|
93
src/lib/update/move_sat.c
Normal file
93
src/lib/update/move_sat.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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_sat.c: Move a satellite to the next point in it's orbit.
|
||||
*
|
||||
* Known contributors to this file:
|
||||
*
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "plane.h"
|
||||
#include "sect.h"
|
||||
#include "xy.h"
|
||||
#include "nsc.h"
|
||||
#include "nat.h"
|
||||
#include "path.h"
|
||||
#include "deity.h"
|
||||
#include "file.h"
|
||||
#include "update.h"
|
||||
#include "subs.h"
|
||||
#include "optlist.h"
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
void
|
||||
move_sat(register struct plnstr *pp)
|
||||
{
|
||||
coord x1,y1,x2,y2;
|
||||
coord dx,dy;
|
||||
float newtheta;
|
||||
struct sctstr sect;
|
||||
|
||||
newtheta = pp->pln_theta + .05;
|
||||
|
||||
if (newtheta >= 1.0)
|
||||
{
|
||||
newtheta -= 1.0;
|
||||
}
|
||||
|
||||
x1 = (coord)(2 * pp->pln_theta * WORLD_X);
|
||||
x1 = xnorm(x1);
|
||||
y1 = (coord)(sin(6 * PI * pp->pln_theta) * (WORLD_Y / 4));
|
||||
x2 = (coord)(2 * newtheta * WORLD_X);
|
||||
x2 = xnorm(x2);
|
||||
y2 = (coord)(sin(6 * PI * newtheta) * (WORLD_Y / 4));
|
||||
dx = x1 - pp->pln_x;
|
||||
dy = y1 - pp->pln_y;
|
||||
x2 -= dx;
|
||||
y2 -= dy;
|
||||
|
||||
if ((x2 + y2) & 1)
|
||||
{
|
||||
x2++;
|
||||
}
|
||||
|
||||
pp->pln_x = xnorm(x2);
|
||||
pp->pln_y = ynorm(y2);
|
||||
pp->pln_theta = newtheta;
|
||||
getsect(pp->pln_x, pp->pln_y, §);
|
||||
if (sect.sct_own)
|
||||
if (pp->pln_own != sect.sct_own)
|
||||
wu(0, sect.sct_own, "%s satellite spotted over %s\n",
|
||||
cname(pp->pln_own), xyas(pp->pln_x, pp->pln_y, sect.sct_own));
|
||||
return;
|
||||
}
|
309
src/lib/update/nat.c
Normal file
309
src/lib/update/nat.c
Normal file
|
@ -0,0 +1,309 @@
|
|||
/*
|
||||
* 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: Accumulate tech, edu, research and happiness.
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
* Steve McClure, 1997
|
||||
*/
|
||||
|
||||
#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 "update.h"
|
||||
#include "subs.h"
|
||||
|
||||
float levels[MAXNOC][4];
|
||||
|
||||
/*
|
||||
* hap and edu avg mean that the weight on current happiness is
|
||||
* (cur_hap * hap_avg + hap_prod * etu) / (hap_avg + etu);
|
||||
* same for education.
|
||||
* right now, happiness has 1 day (48 etu) average, prod of 10 from
|
||||
* initial level of 0 yields (1) 1.42, (6) 6.03, (12) 8.42, (18) 9.37
|
||||
*
|
||||
* education has 4 day (192 etu) average, prod of 10 from initial
|
||||
* level of 0 yields (1) 0.4, (6) 2.2, (12) 3.9, (18) 5.2.
|
||||
*/
|
||||
|
||||
extern float hap_avg;
|
||||
extern float edu_avg;
|
||||
extern float ally_factor;
|
||||
|
||||
/*
|
||||
* for values below the "easy level" values, production is
|
||||
* as normal. For values above "easy", production gets harder
|
||||
* based on an equation in "limit_level()" in update/nat.c.
|
||||
* Basically, the smaller the the values for "level_log", the
|
||||
* smaller return on investment above level_easy[] values.
|
||||
*/
|
||||
/*
|
||||
* Damn! I hate this, but ...
|
||||
* The values here for tech are *not* the real ones.
|
||||
* They are changed later in the limit_level routine.
|
||||
*/
|
||||
/*tech res edu hap */
|
||||
float level_easy[4] = { 0.75, 0.75, 5.00, 5.00 };
|
||||
float level_log[4] = { 1.75, 2.00, 4.00, 6.00 };
|
||||
|
||||
/*
|
||||
* technique to limit the sharpers who turn entire countries
|
||||
* into tech plants overnight...
|
||||
*/
|
||||
|
||||
double
|
||||
logx(double d, double base)
|
||||
{
|
||||
if (base == 1.0)
|
||||
return d;
|
||||
return log10(d) / log10(base);
|
||||
}
|
||||
|
||||
double
|
||||
limit_level(double level, int type, int flag)
|
||||
{
|
||||
double above_easy;
|
||||
double above;
|
||||
double logbase;
|
||||
double easy;
|
||||
|
||||
/*
|
||||
* Begin ugly hack.
|
||||
*/
|
||||
extern float easy_tech, tech_log_base;
|
||||
|
||||
level_easy[0] = easy_tech;
|
||||
level_log[0] = tech_log_base;
|
||||
/*
|
||||
* End ugly hack.
|
||||
*/
|
||||
|
||||
if (level > level_easy[type]) {
|
||||
logbase = level_log[type];
|
||||
easy = level_easy[type];
|
||||
above_easy = level - easy;
|
||||
if (flag)
|
||||
above = above_easy / logx(logbase + above_easy,logbase);
|
||||
else
|
||||
above = logx(above_easy + 1.0, logbase);
|
||||
if (above > 250) above = 250;
|
||||
return ((above) < 0) ? easy : (easy + above);
|
||||
} else
|
||||
return level;
|
||||
}
|
||||
|
||||
void
|
||||
prod_nat(int etu)
|
||||
{
|
||||
extern long money[MAXNOC];
|
||||
extern long pops[MAXNOC];
|
||||
extern double hap_cons, edu_cons;
|
||||
extern long sea_money[MAXNOC];
|
||||
extern long lnd_money[MAXNOC];
|
||||
extern long air_money[MAXNOC];
|
||||
struct natstr *np;
|
||||
float hap;
|
||||
float edu;
|
||||
float hap_edu;
|
||||
long pop;
|
||||
double rlev;
|
||||
double tlev;
|
||||
double tech[MAXNOC];
|
||||
double res[MAXNOC];
|
||||
double newvalue;
|
||||
natid n;
|
||||
int cn,cont;
|
||||
|
||||
for (n=0; NULL != (np = getnatp(n)); n++) {
|
||||
if ((np->nat_stat & STAT_NORM) == 0)
|
||||
continue;
|
||||
/*
|
||||
* hap_edu: the more education people have, the
|
||||
* more happiness they want.
|
||||
*/
|
||||
hap_edu = np->nat_level[NAT_ELEV];
|
||||
hap_edu = 1.5 - ((hap_edu + 10.0) / (hap_edu + 20.0));
|
||||
pop = pops[n] + 1;
|
||||
/*
|
||||
* get per-population happiness and education
|
||||
* see what the total per-civilian production is
|
||||
* for this time period.
|
||||
*/
|
||||
hap = levels[n][NAT_HLEV] * hap_edu * hap_cons /
|
||||
((float)pop * etu);
|
||||
edu = levels[n][NAT_ELEV] * edu_cons /
|
||||
((float)pop * etu);
|
||||
wu((natid)0, n, "%3.0f happiness, %3.0f education produced\n",
|
||||
levels[n][NAT_HLEV], levels[n][NAT_ELEV]);
|
||||
hap = limit_level(hap, NAT_HLEV, 1);
|
||||
edu = limit_level(edu, NAT_ELEV, 1);
|
||||
/*
|
||||
* change the "moving average"...old happiness and
|
||||
* education levels are weighted heavier than current
|
||||
* production.
|
||||
*/
|
||||
newvalue = (np->nat_level[NAT_HLEV] * hap_avg + hap * etu) /
|
||||
(hap_avg + etu);
|
||||
np->nat_level[NAT_HLEV] = newvalue;
|
||||
newvalue = (np->nat_level[NAT_ELEV] * edu_avg + edu * etu) /
|
||||
(edu_avg + etu);
|
||||
np->nat_level[NAT_ELEV] = newvalue;
|
||||
/*
|
||||
* limit tech/research production
|
||||
*/
|
||||
levels[n][NAT_TLEV] =
|
||||
limit_level(levels[n][NAT_TLEV] / 1,
|
||||
NAT_TLEV, 0) * 1;
|
||||
levels[n][NAT_RLEV] =
|
||||
limit_level(levels[n][NAT_RLEV] / 1,
|
||||
NAT_RLEV, 0) * 1;
|
||||
wu((natid)0, n,
|
||||
"total pop is %d, yielding %4.2f hap, %4.2f edu\n",
|
||||
pop - 1, hap, edu);
|
||||
}
|
||||
if (ally_factor > 0.0)
|
||||
share_incr(res, tech);
|
||||
else {
|
||||
bzero((s_char *)res, sizeof(res));
|
||||
bzero((s_char *)tech, sizeof(tech));
|
||||
}
|
||||
for (n=0; NULL != (np = getnatp(n)); n++) {
|
||||
if ((np->nat_stat & STAT_NORM) == 0)
|
||||
continue;
|
||||
tlev = levels[n][NAT_TLEV];
|
||||
rlev = levels[n][NAT_RLEV];
|
||||
if (tech[n] != 0.0 || res[n] != 0.0) {
|
||||
wu((natid)0, n,
|
||||
"%5.4f technology (%5.4f + %5.4f), ",
|
||||
tlev + tech[n], tlev, tech[n]);
|
||||
wu((natid)0, n,
|
||||
"%5.4f research (%5.4f + %5.4f) produced\n",
|
||||
rlev + res[n], rlev, res[n]);
|
||||
} else
|
||||
wu((natid)0, n,
|
||||
"%5.4f tech, %5.4f research produced\n",
|
||||
tlev, rlev);
|
||||
rlev += res[n];
|
||||
tlev += tech[n];
|
||||
if (rlev != 0.0)
|
||||
np->nat_level[NAT_RLEV] += rlev;
|
||||
if (tlev != 0.0)
|
||||
np->nat_level[NAT_TLEV] += tlev;
|
||||
if ((sea_money[n] != 0) || (air_money[n] != 0) ||
|
||||
(lnd_money[n] != 0))
|
||||
wu((natid)0, n,
|
||||
"Army delta $%d, Navy delta $%d, Air force delta $%d\n",
|
||||
lnd_money[n], sea_money[n], air_money[n]);
|
||||
wu((natid)0, n, "money delta was $%d for this update\n",
|
||||
np->nat_money - money[n]);
|
||||
if (opt_LOSE_CONTACT) {
|
||||
for (cn=0; cn <= MAXNOC; cn++) {
|
||||
cont = getcontact(np, cn);
|
||||
if (cont > 0) {
|
||||
logerror ("country %d at level %d with country %d.\n", n, cont, cn);
|
||||
setcont(n, cn, cont-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* find out everyones increment
|
||||
*/
|
||||
void
|
||||
share_incr(register double *res, register double *tech)
|
||||
{
|
||||
register struct natstr *np;
|
||||
register struct natstr *other;
|
||||
register natid i;
|
||||
register natid j;
|
||||
int rnc;
|
||||
int tnc;
|
||||
|
||||
for (i=0; NULL != (np = getnatp(i)); i++) {
|
||||
res[i] = tech[i] = 0.0;
|
||||
if ((np->nat_stat & STAT_INUSE) == 0)
|
||||
continue;
|
||||
if (np->nat_stat & STAT_GOD)
|
||||
continue;
|
||||
if (np->nat_stat == VIS)
|
||||
continue;
|
||||
rnc = tnc = 0;
|
||||
for (j=0; NULL != (other = getnatp(j)); j++) {
|
||||
if (j == i)
|
||||
continue;
|
||||
if (other->nat_stat & STAT_GOD)
|
||||
continue;
|
||||
if (other->nat_stat == VIS)
|
||||
continue;
|
||||
if ((other->nat_stat & STAT_INUSE) == 0)
|
||||
continue;
|
||||
if (opt_HIDDEN) {
|
||||
if (!getcontact(np, j))
|
||||
continue;
|
||||
}
|
||||
if (!opt_ALL_BLEED) {
|
||||
if (getrel(np, j) != ALLIED)
|
||||
continue;
|
||||
if (getrel(other, i) != ALLIED)
|
||||
continue;
|
||||
res[i] += levels[j][NAT_RLEV];
|
||||
tech[i] += levels[j][NAT_TLEV];
|
||||
rnc++;
|
||||
tnc++;
|
||||
} else {
|
||||
if (levels[j][NAT_TLEV] > 0.001) {
|
||||
tech[i] += levels[j][NAT_TLEV];
|
||||
tnc++;
|
||||
}
|
||||
if (levels[j][NAT_RLEV] > 0.001) {
|
||||
res[i] += levels[j][NAT_RLEV];
|
||||
rnc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rnc == 0 && tnc == 0)
|
||||
continue;
|
||||
if (rnc > 0) {
|
||||
res[i] /= rnc * ally_factor;
|
||||
}
|
||||
if (tnc > 0) {
|
||||
tech[i] /= tnc * ally_factor;
|
||||
}
|
||||
/* logerror("Country #%d gets %g res from %d allies, %g tech from %d allies", i, res[i], rnc, tech[i], tnc);*/
|
||||
}
|
||||
}
|
||||
|
373
src/lib/update/nav_ship.c
Normal file
373
src/lib/update/nav_ship.c
Normal file
|
@ -0,0 +1,373 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* nav_ship.c: Navigate ships and such
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Chad Zabel, 1994
|
||||
* Ken Stevens, 1995
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include "var.h"
|
||||
#include "ship.h"
|
||||
#include "sect.h"
|
||||
#include "news.h"
|
||||
#include "xy.h"
|
||||
#include "nsc.h"
|
||||
#include "nat.h"
|
||||
#include "path.h"
|
||||
#include "deity.h"
|
||||
#include "file.h"
|
||||
#include "item.h"
|
||||
#include "optlist.h"
|
||||
#include "player.h"
|
||||
#include "update.h"
|
||||
#include "subs.h"
|
||||
#include "common.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
extern int check_nav(struct sctstr *sect);
|
||||
|
||||
void
|
||||
scuttle_it(register struct shpstr *sp)
|
||||
{
|
||||
struct sctstr *sectp;
|
||||
|
||||
sp->shp_autonav &= ~AN_SCUTTLE;
|
||||
if (!(sectp = getsectp(sp->shp_x,sp->shp_y))) {
|
||||
wu(0, 0, "bad sector (%d,%d) ship %d\n", sp->shp_x, sp->shp_y,
|
||||
sp->shp_uid);
|
||||
return;
|
||||
}
|
||||
if (sectp->sct_type != SCT_HARBR || sectp->sct_effic < 2) {
|
||||
wu(0, sp->shp_own,
|
||||
"%s is not in a harbor at least 2%% eff! Not scuttling.\n",
|
||||
prship(sp));
|
||||
return;
|
||||
}
|
||||
if (opt_TRADESHIPS) {
|
||||
if (!(mchr[(int)sp->shp_type].m_flags & M_TRADE)) {
|
||||
wu(0, sp->shp_own,
|
||||
"You can only autoscuttle trade ships!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
wu(0, sp->shp_own, "Scuttling %s in sector %s\n",
|
||||
prship(sp),
|
||||
xyas(sp->shp_x, sp->shp_y, sp->shp_own));
|
||||
if (opt_TRADESHIPS) {
|
||||
scuttle_tradeship(sp, 0);
|
||||
}
|
||||
scuttle_ship(sp);
|
||||
}
|
||||
|
||||
static void
|
||||
nav_check_atdest(register struct shpstr *sp, struct mchrstr *mcp)
|
||||
{
|
||||
if ((sp->shp_x == sp->shp_destx[0]) &&
|
||||
(sp->shp_y == sp->shp_desty[0])) {
|
||||
if ((sp->shp_destx[0] == sp->shp_destx[1]) &&
|
||||
(sp->shp_desty[0] == sp->shp_desty[1])) {
|
||||
|
||||
/* End of road */
|
||||
|
||||
sp->shp_autonav &= ~AN_AUTONAV;
|
||||
wu(0, sp->shp_own, "%s arrived at %s, finished\n",
|
||||
prship(sp),
|
||||
xyas(sp->shp_x,sp->shp_y,sp->shp_own));
|
||||
if (sp->shp_autonav & AN_SCUTTLE) {
|
||||
scuttle_it(sp);
|
||||
}
|
||||
} else {
|
||||
/* unload all cargo */
|
||||
unload_it(sp);
|
||||
wu(0, sp->shp_own, "%s arrived at %s\n",
|
||||
prship(sp),
|
||||
xyas(sp->shp_x,sp->shp_y,sp->shp_own));
|
||||
/* Swap */
|
||||
swap(sp);
|
||||
}
|
||||
} else
|
||||
sp->shp_autonav &= ~AN_LOADING;
|
||||
}
|
||||
|
||||
/* flip the 2 fields that deal with autonav movement. */
|
||||
/* CZ 6/1/94 */
|
||||
|
||||
void
|
||||
swap(register struct shpstr *sp)
|
||||
{
|
||||
coord tcord;
|
||||
s_char tcomm[TMAX];
|
||||
short lev[TMAX];
|
||||
int i;
|
||||
|
||||
tcord = sp->shp_destx[0];
|
||||
sp->shp_destx[0] = sp->shp_destx[1];
|
||||
sp->shp_destx[1] = tcord;
|
||||
tcord = sp->shp_desty[0];
|
||||
sp->shp_desty[0] = sp->shp_desty[1];
|
||||
sp->shp_desty[1] = tcord;
|
||||
|
||||
for (i=0;i<TMAX;++i){
|
||||
lev[i] = sp->shp_lstart[i];
|
||||
tcomm[i] = sp->shp_tstart[i]; }
|
||||
|
||||
for (i=0;i<TMAX;++i) {
|
||||
sp->shp_lstart[i] = sp->shp_lend[i];
|
||||
sp->shp_tstart[i] = sp->shp_tend[i]; }
|
||||
|
||||
for (i=0;i<TMAX;++i) {
|
||||
sp->shp_lend[i] = lev[i];
|
||||
sp->shp_tend[i] = tcomm[i]; }
|
||||
|
||||
/* set load bit */
|
||||
sp->shp_autonav |= AN_LOADING;
|
||||
}
|
||||
|
||||
/* New Autonav code.
|
||||
* Chad Zabel
|
||||
* 6-1-94
|
||||
*/
|
||||
|
||||
static int
|
||||
nav_loadship(register struct shpstr *sp, natid cnum)
|
||||
{
|
||||
struct sctstr *sectp;
|
||||
s_char item;
|
||||
int i,
|
||||
landown,
|
||||
shipown,
|
||||
level,
|
||||
didsomething[TMAX],
|
||||
rel;
|
||||
|
||||
for (i=0;i<TMAX;i++)
|
||||
didsomething[i]=0;
|
||||
|
||||
/* Turn off the loading flag.
|
||||
* if any of the loads fail on the ship
|
||||
* it will be turned back on.
|
||||
*/
|
||||
|
||||
sp->shp_autonav &= ~AN_LOADING;
|
||||
|
||||
if (!(sectp = getsectp(sp->shp_x,sp->shp_y)))
|
||||
return RET_SYS; /* safety */
|
||||
/* I suspect RET_SYS isn't really what you want here --dfp */
|
||||
|
||||
|
||||
landown = sectp->sct_own;
|
||||
shipown = sp->shp_own;
|
||||
rel = getrel(getnatp(sectp->sct_own),cnum);
|
||||
|
||||
/* loop through each field for that ship */
|
||||
for (i=0;i<TMAX;++i) {
|
||||
item = sp->shp_tend[i]; /* commodity */
|
||||
level = sp->shp_lend[i]; /* amount */
|
||||
|
||||
/* check and see if the data fields have been set. */
|
||||
|
||||
if (item == ' ' || level == 0) {
|
||||
/* nothing to do move on. */
|
||||
didsomething[i] = 1;
|
||||
continue;
|
||||
}
|
||||
if (landown == 0) {
|
||||
/* either sea or deity harbor */
|
||||
didsomething[i] = 1;
|
||||
continue;
|
||||
}
|
||||
if (sectp->sct_type != SCT_HARBR &&
|
||||
(!opt_BIG_CITY || sectp->sct_type != SCT_CAPIT)) {
|
||||
/* we can only load in harbors */
|
||||
didsomething[i] = 1;
|
||||
continue;
|
||||
}
|
||||
if (landown == shipown || rel >= FRIENDLY)
|
||||
didsomething[i] = load_it(sp,sectp,i);
|
||||
}
|
||||
|
||||
/* check for any unsucessful loads */
|
||||
/* if we have any return 0 to stop */
|
||||
/* the nav_ship loop. */
|
||||
|
||||
for (i=0;i<TMAX;i++) {
|
||||
if(didsomething[i] == 0)
|
||||
return 0;
|
||||
}
|
||||
/* All loads were succesful */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* new autonav code.
|
||||
*
|
||||
* 1. Try and move to the next sector/harbor given by the player.
|
||||
* 2. Once we reach a harbor try and load all cargo holds for that ship.
|
||||
* 3. If the ship reaches its max levels set by the player try to use
|
||||
* up all mobility getting to the next harbor.
|
||||
* Continue to loop until the ship runs out of mobility, a load fails,
|
||||
* the ship gets sunk (forts,ect..), the ship hits a mine.
|
||||
*
|
||||
* A check has been added for fuel so ships don't end up running
|
||||
* out of mobility in the ocean.
|
||||
*
|
||||
* Questions, bugs (fixes) , or new ideas should be directed at
|
||||
* Chad Zabel.
|
||||
* 6-1-94
|
||||
* Modified to use shp_nav by Ken Stevens 1995
|
||||
*/
|
||||
int
|
||||
nav_ship(register struct shpstr *sp)
|
||||
{
|
||||
extern double techfact(int, double);
|
||||
struct sctstr *sectp;
|
||||
s_char *cp,item;
|
||||
int stopping;
|
||||
int quit;
|
||||
int didsomething = 0;
|
||||
int max_amt, food_amt, comm;
|
||||
s_char buf[1024];
|
||||
struct emp_qelem ship_list;
|
||||
struct emp_qelem *qp, *newqp;
|
||||
struct mlist *mlp;
|
||||
int dummyint;
|
||||
double dummydouble;
|
||||
int dir;
|
||||
natid cnum;
|
||||
struct mchrstr *mcp, *vship;
|
||||
|
||||
/* just return if no autonaving to do for this ship */
|
||||
if (!(sp->shp_autonav & AN_AUTONAV) || (sp->shp_autonav & AN_STANDBY))
|
||||
return RET_OK;
|
||||
|
||||
cnum = sp->shp_own;
|
||||
vship = mcp = &mchr[(int)sp->shp_type];
|
||||
|
||||
/* Make a list of one ships so we can use the navi.c code */
|
||||
emp_initque(&ship_list);
|
||||
mlp = (struct mlist *) malloc(sizeof(struct mlist));
|
||||
mlp->mcp = mchr + sp->shp_type;
|
||||
bcopy((s_char *)sp, (s_char *)&mlp->ship, sizeof(struct shpstr));
|
||||
mlp->mobil = (double)sp->shp_mobil;
|
||||
emp_insque(&mlp->queue, &ship_list);
|
||||
|
||||
quit = 1; /* setup loop, we want to check it 1 time. */
|
||||
|
||||
do {
|
||||
if ((sp->shp_mobil > 0) && (!(sp->shp_autonav & AN_LOADING)) &&
|
||||
(!(sp->shp_autonav & AN_STANDBY))) {
|
||||
shp_nav(&ship_list, &dummydouble, &dummydouble, &dummyint,
|
||||
sp->shp_own);
|
||||
if (QEMPTY(&ship_list))
|
||||
return RET_OK;
|
||||
/* before we move check to see if ship needs fuel. */
|
||||
sectp = getsectp(sp->shp_x,sp->shp_y);
|
||||
if (opt_FUEL &&
|
||||
sectp->sct_own != 0 &&
|
||||
sp->shp_fuel <= 0 &&
|
||||
mlp->mcp->m_fuelu != 0)
|
||||
auto_fuel_ship(sp);
|
||||
mlp->ship.shp_fuel = sp->shp_fuel;
|
||||
|
||||
cp = BestShipPath(buf, sp->shp_x, sp->shp_y,
|
||||
sp->shp_destx[0], sp->shp_desty[0],
|
||||
sp->shp_own);
|
||||
if (cp == 0 || (*cp == '\0') || (*cp == '?')) {
|
||||
wu(0, cnum,
|
||||
"%s bad path, ship put on standby\n",
|
||||
prship(sp));
|
||||
sp->shp_autonav |= AN_STANDBY;
|
||||
putship(sp->shp_uid, (s_char *)sp);
|
||||
|
||||
/* We need to free the ship list */
|
||||
qp = ship_list.q_forw;
|
||||
while (qp != &(ship_list)) {
|
||||
newqp = qp->q_forw;
|
||||
emp_remque(qp);
|
||||
free((s_char *)qp);
|
||||
qp = newqp;
|
||||
}
|
||||
return RET_SYN;
|
||||
}
|
||||
stopping = 0;
|
||||
|
||||
while (*cp && !stopping && sp->shp_own &&
|
||||
mlp->mobil > 0.0) {
|
||||
dir = chkdir(*cp++, DIR_STOP, DIR_LAST);
|
||||
|
||||
stopping |= shp_nav_one_sector(&ship_list, dir,
|
||||
sp->shp_own, 0);
|
||||
}
|
||||
|
||||
/* sp->shp_mobil = (int) mobil;
|
||||
*/
|
||||
/* Ship not sunk */
|
||||
if (sp->shp_own)
|
||||
nav_check_atdest(sp, mcp);
|
||||
}
|
||||
|
||||
quit = 0; /* stop loop */
|
||||
|
||||
/* Try to load the ship */
|
||||
if (sp->shp_autonav & AN_LOADING) {
|
||||
didsomething = nav_loadship(sp, cnum);
|
||||
if (didsomething)
|
||||
quit = 1;
|
||||
}
|
||||
/* special case for fishing boats */
|
||||
if ((mchr[(int)sp->shp_type].m_flags & M_FOOD) == 1) {
|
||||
item = (s_char)'f';
|
||||
comm = com_num(&item);
|
||||
food_amt=getvar(comm,(s_char *) sp, EF_SHIP);
|
||||
max_amt=(vl_find(comm,vship->m_vtype,
|
||||
vship->m_vamt,
|
||||
(int) vship->m_nv));
|
||||
sectp=getsectp(sp->shp_x,sp->shp_y);
|
||||
|
||||
if (food_amt<max_amt && (sectp->sct_own==0))
|
||||
quit=0;
|
||||
}
|
||||
/* reset flag and check if we can move. */
|
||||
|
||||
} while (quit); /* end loop */
|
||||
|
||||
putship(sp->shp_uid, sp);
|
||||
|
||||
/* We need to free the ship list (just in case) */
|
||||
qp = ship_list.q_forw;
|
||||
while (qp != &(ship_list)) {
|
||||
newqp = qp->q_forw;
|
||||
emp_remque(qp);
|
||||
free((s_char *)qp);
|
||||
qp = newqp;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
310
src/lib/update/nav_util.c
Normal file
310
src/lib/update/nav_util.c
Normal file
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* nav_util.c: Utilities for autonav and sail
|
||||
*
|
||||
* Known contributors to this file:
|
||||
*
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include "var.h"
|
||||
#include "ship.h"
|
||||
#include "plane.h"
|
||||
#include "land.h"
|
||||
#include "nuke.h"
|
||||
#include "sect.h"
|
||||
#include "news.h"
|
||||
#include "xy.h"
|
||||
#include "nsc.h"
|
||||
#include "nat.h"
|
||||
#include "path.h"
|
||||
#include "deity.h"
|
||||
#include "file.h"
|
||||
#include "item.h"
|
||||
#include "optlist.h"
|
||||
#include "player.h"
|
||||
#include "update.h"
|
||||
#include "subs.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
|
||||
/* Format a ship name */
|
||||
int
|
||||
check_nav(struct sctstr *sect)
|
||||
{
|
||||
extern struct dchrstr dchr[];
|
||||
|
||||
switch (dchr[sect->sct_type].d_flg & 03) {
|
||||
case NAVOK:
|
||||
break;
|
||||
|
||||
case NAV_02:
|
||||
if (sect->sct_effic < 2)
|
||||
return CN_CONSTRUCTION;
|
||||
break;
|
||||
case NAV_60:
|
||||
if (sect->sct_effic < 60)
|
||||
return CN_CONSTRUCTION;
|
||||
break;
|
||||
default:
|
||||
return CN_LANDLOCKED;
|
||||
}
|
||||
return CN_NAVIGABLE;
|
||||
}
|
||||
|
||||
/* load a specific ship given its
|
||||
* location and what field to modify.
|
||||
* new autonav code
|
||||
* Chad Zabel 6/1/94
|
||||
*/
|
||||
int
|
||||
load_it(register struct shpstr *sp, register struct sctstr *psect, int i)
|
||||
{
|
||||
int comm, shipown, amount, ship_amt, sect_amt,
|
||||
abs_max, max_amt, transfer;
|
||||
s_char item;
|
||||
struct mchrstr *vship;
|
||||
|
||||
amount = sp->shp_lend[i];
|
||||
shipown = sp->shp_own;
|
||||
item = sp->shp_tend[i]; /* commodity */
|
||||
comm = com_num(&item);
|
||||
|
||||
ship_amt = getvar(comm,(s_char *) sp , EF_SHIP);
|
||||
sect_amt = getvar(comm,(s_char *) psect, EF_SECTOR);
|
||||
|
||||
/* check for disloyal civilians */
|
||||
if (psect->sct_oldown != shipown && comm == V_CIVIL)
|
||||
{ wu(0,shipown,"Ship #%d - unable to load disloyal civilians at %s.",
|
||||
sp->shp_uid, xyas(psect->sct_x,psect->sct_y,psect->sct_own));
|
||||
return 0;
|
||||
}
|
||||
if (comm == V_CIVIL || comm == V_MILIT)
|
||||
sect_amt--; /* leave 1 civ or mil to hold the sector. */
|
||||
vship = &mchr[(int)sp->shp_type];
|
||||
abs_max = max_amt = (vl_find(comm,vship->m_vtype,
|
||||
vship->m_vamt,(int) vship->m_nv));
|
||||
|
||||
if (!abs_max)
|
||||
return 0; /* can't load the ship, skip to the end. */
|
||||
|
||||
max_amt = min (sect_amt, max_amt - ship_amt);
|
||||
if (max_amt <= 0 && (ship_amt != abs_max)) {
|
||||
sp->shp_autonav |= AN_LOADING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
transfer = amount - ship_amt;
|
||||
if (transfer > sect_amt) { /* not enough in the */
|
||||
transfer = sect_amt; /* sector to fill the */
|
||||
sp->shp_autonav |= AN_LOADING; /* ship, set load flag */
|
||||
}
|
||||
if (ship_amt + transfer > abs_max) /* Do not load more */
|
||||
transfer = abs_max-ship_amt; /* then the max alowed */
|
||||
/* on the ship. */
|
||||
|
||||
if (transfer == 0)
|
||||
return 0; /* nothing to move */
|
||||
|
||||
|
||||
putvar(comm, ship_amt + transfer, (s_char *)sp, EF_SHIP);
|
||||
if (comm == V_CIVIL || comm == V_MILIT)
|
||||
sect_amt++; /*adjustment*/
|
||||
putvar(comm, sect_amt - transfer, (s_char *)psect, EF_SECTOR);
|
||||
|
||||
/* deal with the plague */
|
||||
if (getvar(V_PSTAGE, (s_char *)psect, EF_SECTOR) == PLG_INFECT &&
|
||||
getvar(V_PSTAGE, (s_char *)sp , EF_SHIP) == PLG_HEALTHY)
|
||||
putvar(V_PSTAGE, PLG_EXPOSED, (s_char *)sp, EF_SHIP);
|
||||
if (getvar(V_PSTAGE, (s_char *)sp, EF_SHIP) == PLG_INFECT &&
|
||||
getvar(V_PSTAGE, (s_char *)psect, EF_SECTOR) == PLG_HEALTHY)
|
||||
putvar(V_PSTAGE, PLG_EXPOSED, (s_char *)psect, EF_SECTOR);
|
||||
|
||||
return 1; /* we did someloading return 1 to keep */
|
||||
/* our loop happy in nav_ship() */
|
||||
|
||||
}
|
||||
|
||||
/* unload_it
|
||||
* A guess alot of this looks like load_it but because of its location
|
||||
* in the autonav code I had to split the 2 procedures up.
|
||||
* unload_it dumps all the goods from the ship to the harbor.
|
||||
* ONLY goods in the trade fields will be unloaded.
|
||||
* new autonav code
|
||||
* Chad Zabel 6/1/94
|
||||
*/
|
||||
void
|
||||
unload_it(register struct shpstr *sp)
|
||||
{
|
||||
struct sctstr *sectp;
|
||||
s_char item;
|
||||
int i;
|
||||
int landowner;
|
||||
int shipown;
|
||||
int comm;
|
||||
int sect_amt;
|
||||
int ship_amt;
|
||||
int abs_max = 99999; /* max amount a sector can hold. */
|
||||
int max_amt;
|
||||
int level;
|
||||
|
||||
|
||||
sectp = getsectp(sp->shp_x,sp->shp_y);
|
||||
|
||||
landowner = sectp->sct_own;
|
||||
shipown = sp->shp_own;
|
||||
|
||||
for(i=0;i<TMAX;++i) {
|
||||
item = sp->shp_tend[i];
|
||||
level = sp->shp_lend[i];
|
||||
|
||||
if (item == ' ' || level == 0)
|
||||
continue;
|
||||
if (landowner == 0 )
|
||||
continue;
|
||||
if (sectp->sct_type != SCT_HARBR)
|
||||
continue;
|
||||
|
||||
comm = com_num(&item);
|
||||
ship_amt = getvar(comm,(s_char *) sp ,EF_SHIP);
|
||||
sect_amt = getvar(comm,(s_char *) sectp ,EF_SECTOR);
|
||||
|
||||
/* check for disloyal civilians */
|
||||
if (sectp->sct_oldown != shipown && comm == V_CIVIL)
|
||||
{
|
||||
wu(0,sp->shp_own,"Ship #%d - unable to unload civilians into a disloyal sector at %s.",
|
||||
sp->shp_uid, xyas(sectp->sct_x,sectp->sct_y,sectp->sct_own));
|
||||
continue;
|
||||
}
|
||||
if (comm == V_CIVIL)
|
||||
ship_amt--; /* This leaves 1 civs on board the ship */
|
||||
|
||||
if (sect_amt >= abs_max)
|
||||
continue; /* The sector is full. */
|
||||
|
||||
max_amt = min (ship_amt,abs_max - sect_amt);
|
||||
|
||||
if (max_amt <= 0)
|
||||
continue;
|
||||
|
||||
putvar(comm, ship_amt - max_amt, (s_char *) sp ,EF_SHIP);
|
||||
putvar(comm, sect_amt + max_amt, (s_char *) sectp,EF_SECTOR);
|
||||
|
||||
if (getvar(V_PSTAGE, (s_char *)sectp,EF_SECTOR) == PLG_INFECT &&
|
||||
getvar(V_PSTAGE, (s_char *)sp ,EF_SHIP ) == PLG_HEALTHY)
|
||||
putvar(V_PSTAGE, PLG_EXPOSED,(s_char *)sp, EF_SHIP);
|
||||
|
||||
if (getvar(V_PSTAGE, (s_char *)sp ,EF_SHIP ) == PLG_INFECT &&
|
||||
getvar(V_PSTAGE, (s_char *)sectp,EF_SECTOR) == PLG_HEALTHY)
|
||||
putvar(V_PSTAGE, PLG_EXPOSED,(s_char *)sectp, EF_SECTOR);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/* com_num
|
||||
* This small but useful bit of code runs through the list
|
||||
* of commodities and return the integer value of the
|
||||
* commodity it finds if possible. Very handy when using getvar().
|
||||
* Basicly its a hacked version of whatitem.c found in the
|
||||
* /player directory.
|
||||
* new autonav code.
|
||||
* Chad Zabel 6/1/94
|
||||
*/
|
||||
|
||||
int
|
||||
com_num(s_char *ptr)
|
||||
{
|
||||
struct ichrstr *ip;
|
||||
|
||||
for(ip = &ichr[1];ip->i_mnem != 0; ip++) {
|
||||
if (*ptr == ip->i_mnem)
|
||||
return ip->i_vtype;
|
||||
}
|
||||
return 0; /*NOTREACHED*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* auto_fuel_ship
|
||||
* Assume a check for fuel=0 has already been made and passed.
|
||||
* Try to fill a ship using petro. and then oil.
|
||||
* new autonav code.
|
||||
* This should be merged with the fuel command someday.
|
||||
* Chad Zabel 6/1/94
|
||||
*/
|
||||
|
||||
void
|
||||
auto_fuel_ship(register struct shpstr *sp)
|
||||
{
|
||||
double d;
|
||||
int totalfuel = 0;
|
||||
int need;
|
||||
int maxfuel;
|
||||
int newfuel = 0;
|
||||
int add_fuel = 0;
|
||||
|
||||
if (opt_FUEL == 0) return;
|
||||
getship(sp->shp_uid,sp); /* refresh */
|
||||
/* fill with petro */
|
||||
maxfuel = mchr[(int)sp->shp_type].m_fuelc;
|
||||
d = (double) maxfuel / 5.0;
|
||||
if (( d-(int)d > 0.0 ))
|
||||
d++;
|
||||
need = (int)d;
|
||||
|
||||
newfuel = supply_commod(sp->shp_own,sp->shp_x,
|
||||
sp->shp_y,I_PETROL,need);
|
||||
add_fuel += newfuel * 5;
|
||||
if (add_fuel > maxfuel)
|
||||
add_fuel = maxfuel;
|
||||
sp->shp_fuel += add_fuel;
|
||||
totalfuel += add_fuel;
|
||||
|
||||
if (totalfuel == maxfuel) {
|
||||
putship(sp->shp_uid,sp);
|
||||
return; /* the ship is full */
|
||||
}
|
||||
add_fuel = 0;
|
||||
/* fill with oil */
|
||||
d = (double) (maxfuel - totalfuel) / 50.0;
|
||||
if ((d-(int)d > 0.0))
|
||||
d++;
|
||||
need = (int)d;
|
||||
|
||||
newfuel = supply_commod(sp->shp_own,sp->shp_x,
|
||||
sp->shp_y,I_OIL,need);
|
||||
add_fuel = newfuel * 50;
|
||||
if (add_fuel > maxfuel)
|
||||
add_fuel = maxfuel;
|
||||
sp->shp_fuel += add_fuel;
|
||||
putship(sp->shp_uid,sp);
|
||||
}
|
||||
|
119
src/lib/update/nxtitemp.c
Normal file
119
src/lib/update/nxtitemp.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* nxtitemp.c: Get next item from list
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "xy.h"
|
||||
#include "plane.h"
|
||||
#include "ship.h"
|
||||
#include "nuke.h"
|
||||
#include "land.h"
|
||||
#include "nsc.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "genitem.h"
|
||||
#include "player.h"
|
||||
#include "update.h"
|
||||
#include "gen.h"
|
||||
#include "common.h"
|
||||
|
||||
s_char *
|
||||
nxtitemp(struct nstr_item *np, int owner)
|
||||
{
|
||||
struct genitem *gp;
|
||||
int selected;
|
||||
|
||||
if (np->sel == NS_UNDEF)
|
||||
return 0;
|
||||
do {
|
||||
if (np->sel == NS_LIST) {
|
||||
np->index++;
|
||||
if (np->index >= np->size)
|
||||
return 0;
|
||||
np->cur = np->list[np->index];
|
||||
} else {
|
||||
np->cur++;
|
||||
}
|
||||
gp = (struct genitem *)ef_ptr(np->type,np->cur);
|
||||
if (gp == (struct genitem *)0)
|
||||
return 0;
|
||||
|
||||
selected = 1;
|
||||
switch (np->sel) {
|
||||
/*
|
||||
* This one won't work unless you're running in emp_player
|
||||
*
|
||||
*/
|
||||
case NS_LIST:
|
||||
if ((np->flags & EFF_OWNER) && !owner)
|
||||
selected = 0;
|
||||
break;
|
||||
case NS_ALL:
|
||||
/* XXX maybe combine NS_LIST and NS_ALL later */
|
||||
break;
|
||||
case NS_DIST:
|
||||
if (!xyinrange(gp->x, gp->y, &np->range)) {
|
||||
selected = 0;
|
||||
break;
|
||||
}
|
||||
np->curdist = mapdist((int)gp->x, (int)gp->y,
|
||||
(int)np->cx, (int)np->cy);
|
||||
if (np->curdist > np->dist)
|
||||
selected = 0;
|
||||
break;
|
||||
case NS_AREA:
|
||||
if (!xyinrange(gp->x, gp->y, &np->range))
|
||||
selected = 0;
|
||||
if (gp->x == np->range.hx || gp->y == np->range.hy)
|
||||
selected = 0;
|
||||
break;
|
||||
case NS_XY:
|
||||
if (xnorm(gp->x) != np->cx || ynorm(gp->y) != np->cy)
|
||||
selected = 0;
|
||||
break;
|
||||
case NS_GROUP:
|
||||
if (np->group != gp->group)
|
||||
selected = 0;
|
||||
break;
|
||||
default:
|
||||
logerror("nxtitemp: bad selector %d\n", np->sel);
|
||||
return 0;
|
||||
}
|
||||
if (selected && np->ncond) {
|
||||
/* nstr_exec is expensive, so we do it last */
|
||||
if (!nstr_exec(np->cond, np->ncond, (s_char *)gp, np->type))
|
||||
selected = 0;
|
||||
}
|
||||
} while (!selected);
|
||||
return (s_char *)gp;
|
||||
}
|
76
src/lib/update/nxtsctp.c
Normal file
76
src/lib/update/nxtsctp.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* nxtsctp.c: select/get the next sector from a rnage of sectors
|
||||
*
|
||||
* 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 "update.h"
|
||||
#include "gen.h"
|
||||
#include "optlist.h"
|
||||
|
||||
/*
|
||||
* get the next sector in the range
|
||||
* that matches the conditions.
|
||||
*/
|
||||
struct sctstr *
|
||||
nxtsctp(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 (struct sctstr *)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;
|
||||
}
|
||||
return(getsectp(np->x, np->y));
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
200
src/lib/update/plague.c
Normal file
200
src/lib/update/plague.c
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* plague.c: Plague related functions
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Steve McClure, 1998-2000
|
||||
*/
|
||||
|
||||
#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 "update.h"
|
||||
#include "common.h"
|
||||
#include "subs.h"
|
||||
#include "lost.h"
|
||||
#include "gen.h"
|
||||
|
||||
void
|
||||
do_plague(struct sctstr *sp, struct natstr *np, int etu)
|
||||
{
|
||||
int vec[I_MAX+1];
|
||||
int cvec[I_MAX+1];
|
||||
int n;
|
||||
|
||||
if (opt_NO_PLAGUE) /* no plague nothing to do */
|
||||
return;
|
||||
|
||||
if (getvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR) <= 0)
|
||||
return;
|
||||
if (getvec(VT_COND, cvec, (s_char *)sp, EF_SECTOR) <= 0)
|
||||
bzero((s_char *)cvec, sizeof(cvec));
|
||||
|
||||
if (cvec[C_PSTAGE] == 0) {
|
||||
cvec[C_PSTAGE] = infect_people(np, vec, sp->sct_effic,
|
||||
(int)sp->sct_mobil, sp);
|
||||
cvec[C_PTIME] = 0;
|
||||
} else {
|
||||
n = plague_people(np, vec, cvec, etu);
|
||||
switch (n) {
|
||||
case PLG_DYING:
|
||||
wu(0, sp->sct_own, "PLAGUE deaths reported in %s.\n",
|
||||
ownxy(sp));
|
||||
nreport(sp->sct_own, N_DIE_PLAGUE, 0, 1);
|
||||
break;
|
||||
case PLG_INFECT:
|
||||
wu(0, sp->sct_own, "%s battling PLAGUE\n", ownxy(sp));
|
||||
break;
|
||||
case PLG_INCUBATE:
|
||||
/* Are we still incubating? */
|
||||
if (n == cvec[C_PSTAGE]) {
|
||||
/* Yes. Will it turn "infectious" next time? */
|
||||
if (cvec[C_PTIME] <= etu) {
|
||||
/* Yes. Report an outbreak. */
|
||||
wu(0, sp->sct_own,
|
||||
"Outbreak of PLAGUE in %s!\n",
|
||||
ownxy(sp));
|
||||
nreport(sp->sct_own, N_OUT_PLAGUE, 0, 1);
|
||||
}
|
||||
} else {
|
||||
/* It has already moved on to "infectious" */
|
||||
wu(0, sp->sct_own, "%s battling PLAGUE\n", ownxy(sp));
|
||||
}
|
||||
break;
|
||||
case PLG_EXPOSED:
|
||||
/* Has the plague moved to "incubation" yet? */
|
||||
if (n != cvec[C_PSTAGE]) {
|
||||
/* Yes. Will it turn "infectious" next time? */
|
||||
if (cvec[C_PTIME] <= etu) {
|
||||
/* Yes. Report an outbreak. */
|
||||
wu(0, sp->sct_own,
|
||||
"Outbreak of PLAGUE in %s!\n",
|
||||
ownxy(sp));
|
||||
nreport(sp->sct_own, N_OUT_PLAGUE, 0, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vec[I_CIVIL] == 0 && vec[I_MILIT] == 0 &&
|
||||
!has_units(sp->sct_x,sp->sct_y,sp->sct_own,0)) {
|
||||
makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y);
|
||||
sp->sct_own = 0;
|
||||
sp->sct_oldown = 0;
|
||||
}
|
||||
putvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
|
||||
putvec(VT_COND, cvec, (s_char *)sp, EF_SECTOR);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
infect_people(struct natstr *np, register int *vec, u_int eff, int mobil, struct sctstr *sp)
|
||||
{
|
||||
double plg_num;
|
||||
double plg_denom;
|
||||
double plg_chance;
|
||||
double civvies = 999.0;
|
||||
|
||||
if (opt_NO_PLAGUE) /* no plague nothing to do */
|
||||
return PLG_HEALTHY;
|
||||
|
||||
if (np->nat_level[NAT_TLEV] <= 10.0)
|
||||
return PLG_HEALTHY;
|
||||
|
||||
if (opt_BIG_CITY && (sp->sct_type == SCT_CAPIT))
|
||||
civvies = 9999.0;
|
||||
|
||||
/*
|
||||
* make plague where there was none before...
|
||||
*/
|
||||
plg_num = ((vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW]) / civvies) *
|
||||
((vec[I_IRON] + vec[I_OIL] + (vec[I_RAD] * 2)) / 10.0 +
|
||||
np->nat_level[NAT_TLEV] + 100.0);
|
||||
plg_denom = eff + mobil + 100 + np->nat_level[NAT_RLEV];
|
||||
plg_chance = ((plg_num / plg_denom) - 1.0) * 0.01;
|
||||
if (chance(plg_chance))
|
||||
return PLG_EXPOSED;
|
||||
return PLG_HEALTHY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given the fact that plague exists, kill off
|
||||
* people if in plague state DYING. Increment
|
||||
* the plague time. Return "current" plague
|
||||
* stage. No reports generated here anymore.
|
||||
*/
|
||||
int
|
||||
plague_people(struct natstr *np, register int *vec, register int *cvec, int etus)
|
||||
{
|
||||
int stage;
|
||||
double plg_num;
|
||||
double plg_denom;
|
||||
double pct_left;
|
||||
|
||||
if (opt_NO_PLAGUE) /* no plague nothing to do */
|
||||
return PLG_HEALTHY;
|
||||
cvec[C_PTIME] -= etus;
|
||||
stage = cvec[C_PSTAGE];
|
||||
switch (stage) {
|
||||
case PLG_DYING:
|
||||
plg_num = 100.0 * etus;
|
||||
plg_denom = (np->nat_level[NAT_RLEV] + 100.0) *
|
||||
(vec[C_PTIME] + etus + 1.0);
|
||||
pct_left = 1.0 - (double)(plg_num / plg_denom);
|
||||
if (pct_left < 0.2)
|
||||
pct_left = 0.2;
|
||||
vec[I_CIVIL] = vec[I_CIVIL] * pct_left;
|
||||
vec[I_MILIT] = vec[I_MILIT] * pct_left;
|
||||
vec[I_UW] = vec[I_UW] * pct_left;
|
||||
break;
|
||||
case PLG_INFECT:
|
||||
case PLG_INCUBATE:
|
||||
break;
|
||||
case PLG_EXPOSED:
|
||||
cvec[C_PTIME] = 0;
|
||||
break;
|
||||
default:
|
||||
/* bad */
|
||||
cvec[C_PTIME] = 0;
|
||||
break;
|
||||
}
|
||||
if (cvec[C_PTIME] <= 0) {
|
||||
cvec[C_PSTAGE]--;
|
||||
cvec[C_PTIME] = (etus / 2) + (random() % etus);
|
||||
}
|
||||
return stage;
|
||||
}
|
282
src/lib/update/plane.c
Normal file
282
src/lib/update/plane.c
Normal file
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* plane.c: Do production for planes
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Steve McClure, 1998
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "plane.h"
|
||||
#include "ship.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "optlist.h"
|
||||
#include "budg.h"
|
||||
#include "player.h"
|
||||
#include "update.h"
|
||||
#include "lost.h"
|
||||
#include "subs.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x) > (y) ? (y) : (x))
|
||||
#endif
|
||||
|
||||
int
|
||||
prod_plane(int etus, int natnum, int *bp, int buildem)
|
||||
|
||||
|
||||
|
||||
/* Build = 1, maintain =0 */
|
||||
{
|
||||
extern double money_mil;
|
||||
extern double money_plane;
|
||||
extern int plane_grow_scale;
|
||||
extern long air_money[MAXNOC];
|
||||
register struct plnstr *pp;
|
||||
register struct plchrstr *plp;
|
||||
struct natstr *np;
|
||||
float leftp, buildp;
|
||||
int left, build;
|
||||
int lcm_needed,hcm_needed;
|
||||
int mil_needed;
|
||||
int svec[I_MAX+1];
|
||||
int mvec[I_MAX+1];
|
||||
int n, k=0;
|
||||
struct shpstr *shp;
|
||||
struct plchrstr *desc;
|
||||
struct sctstr *sp;
|
||||
int delta;
|
||||
int mult;
|
||||
int cost;
|
||||
int eff;
|
||||
int avail;
|
||||
int w_p_eff;
|
||||
int used;
|
||||
int start_money, onship=0;
|
||||
|
||||
for (n=0; NULL != (pp = getplanep(n)); n++) {
|
||||
if (pp->pln_own == 0)
|
||||
continue;
|
||||
if (pp->pln_own != natnum)
|
||||
continue;
|
||||
if (pp->pln_effic < PLANE_MINEFF) {
|
||||
makelost(EF_PLANE, pp->pln_own, pp->pln_uid,
|
||||
pp->pln_x, pp->pln_y);
|
||||
pp->pln_own = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
plp = &plchr[(int)pp->pln_type];
|
||||
if (pp->pln_flags & PLN_LAUNCHED) {
|
||||
if (opt_ORBIT && (buildem == 0)) {
|
||||
if ((!player->simulation) &&
|
||||
(plp->pl_flags & P_O) &&
|
||||
(pp->pln_flags & PLN_LAUNCHED) &&
|
||||
!(plp->pl_flags & P_M) &&
|
||||
!(pp->pln_flags & PLN_SYNCHRONOUS))
|
||||
move_sat(pp);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
onship = 0;
|
||||
shp = (struct shpstr *)0;
|
||||
if (pp->pln_ship >= 0 && (buildem == 1)) {
|
||||
if (pp->pln_effic >= 80)
|
||||
continue;
|
||||
onship = 1;
|
||||
shp = getshipp(pp->pln_ship);
|
||||
if (shp == 0 || shp->shp_own != pp->pln_own) {
|
||||
/* nplane is unsigned... */
|
||||
if (shp->shp_nplane > 0)
|
||||
shp->shp_nplane --;
|
||||
makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
|
||||
pp->pln_own = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
np = getnatp(pp->pln_own);
|
||||
desc = &plchr[(int)pp->pln_type];
|
||||
sp = getsectp(pp->pln_x, pp->pln_y);
|
||||
getvec(VT_ITEM, svec, (s_char *)sp, EF_SECTOR);
|
||||
mult=1;
|
||||
if (np->nat_level[NAT_TLEV] < pp->pln_tech * 0.85)
|
||||
mult = 2;
|
||||
|
||||
if (buildem == 0) {
|
||||
/* flight pay is 5x the pay received by other military */
|
||||
start_money = np->nat_money;
|
||||
cost = -(mult * etus *
|
||||
dmin(0.0, desc->pl_cost * money_plane));
|
||||
if ((np->nat_priorities[PRI_PMAINT] == 0 ||
|
||||
np->nat_money < cost) && !player->simulation) {
|
||||
if ((eff = pp->pln_effic - etus/5) < PLANE_MINEFF) {
|
||||
wu(0, pp->pln_own,
|
||||
"%s lost to lack of maintenance\n",
|
||||
prplane(pp));
|
||||
makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
|
||||
pp->pln_own = 0;
|
||||
continue;
|
||||
}
|
||||
wu(0, pp->pln_own,
|
||||
"%s lost %d%% to lack of maintenance\n",
|
||||
prplane(pp), pp->pln_effic - eff);
|
||||
pp->pln_effic = eff;
|
||||
} else {
|
||||
np->nat_money -= cost;
|
||||
}
|
||||
|
||||
np->nat_money += (etus * plp->pl_crew * money_mil * 5);
|
||||
|
||||
air_money[pp->pln_own] += np->nat_money - start_money;
|
||||
k++;
|
||||
if (player->simulation)
|
||||
np->nat_money = start_money;
|
||||
if ((pp->pln_flags & PLN_LAUNCHED) == PLN_LAUNCHED)
|
||||
continue;
|
||||
}else{
|
||||
if (sp->sct_off)
|
||||
continue;
|
||||
if (np->nat_priorities[PRI_PBUILD] == 0 ||
|
||||
np->nat_money < 0)
|
||||
continue;
|
||||
|
||||
start_money = np->nat_money;
|
||||
left = 100 - pp->pln_effic;
|
||||
if (left <= 0)
|
||||
continue;
|
||||
|
||||
if (!player->simulation)
|
||||
avail = sp->sct_avail * 100;
|
||||
else
|
||||
avail = gt_bg_nmbr(bp, sp, I_MAX+1) * 100;
|
||||
|
||||
if (pp->pln_ship >= 0) {
|
||||
int vec[I_MAX+1];
|
||||
shp = getshipp(pp->pln_ship);
|
||||
getvec(VT_ITEM, vec, (s_char *)shp, EF_SHIP);
|
||||
avail += (etus * vec[I_MILIT]/2);
|
||||
}
|
||||
w_p_eff = 20 + (desc->pl_lcm + 2 * desc->pl_hcm);
|
||||
delta = roundavg((double)avail/w_p_eff);
|
||||
if (delta <= 0)
|
||||
continue;
|
||||
if (delta > etus*plane_grow_scale)
|
||||
delta = etus*plane_grow_scale;
|
||||
if (delta > left)
|
||||
delta = left;
|
||||
|
||||
/* delta is the max amount we can grow */
|
||||
|
||||
left = 100 - pp->pln_effic;
|
||||
if (left > delta)
|
||||
left = delta;
|
||||
|
||||
leftp = ((float)left/100.0);
|
||||
bzero((s_char *)mvec, sizeof(mvec));
|
||||
mvec[I_MILIT] = mil_needed =
|
||||
ldround((double)(plp->pl_crew * leftp),1);
|
||||
mvec[I_LCM] = lcm_needed =
|
||||
ldround((double)(plp->pl_lcm * leftp),1);
|
||||
mvec[I_HCM] = hcm_needed =
|
||||
ldround((double)(plp->pl_hcm * leftp),1);
|
||||
|
||||
get_materials(sp, bp, mvec, 0);
|
||||
|
||||
if (mvec[I_MILIT]>=mil_needed)
|
||||
buildp=leftp;
|
||||
else
|
||||
buildp=((float)mvec[I_MILIT]/(float)plp->pl_crew);
|
||||
|
||||
if (mvec[I_LCM] < lcm_needed)
|
||||
buildp = MIN(buildp,((float)mvec[I_LCM]/
|
||||
(float)plp->pl_lcm));
|
||||
|
||||
if (mvec[I_HCM] < hcm_needed)
|
||||
buildp = MIN(buildp,((float)mvec[I_HCM]/
|
||||
(float)plp->pl_hcm));
|
||||
|
||||
build=ldround((double)(buildp*100.0),1);
|
||||
bzero((s_char *)mvec, sizeof(mvec));
|
||||
mvec[I_MILIT] = mil_needed =
|
||||
roundavg((double)(plp->pl_crew * buildp));
|
||||
mvec[I_LCM] = lcm_needed =
|
||||
roundavg((double)(plp->pl_lcm * buildp));
|
||||
mvec[I_HCM] = hcm_needed =
|
||||
roundavg((double)(plp->pl_hcm * buildp));
|
||||
|
||||
get_materials(sp, bp, mvec, 1);
|
||||
|
||||
if (onship) build = delta;
|
||||
used = build * w_p_eff;
|
||||
|
||||
/*
|
||||
* I didn't use roundavg here, because I want to
|
||||
* penalize the player with a large number of planes.
|
||||
*/
|
||||
if (!player->simulation)
|
||||
avail = (sp->sct_avail * 100 - used) / 100;
|
||||
else
|
||||
avail = (gt_bg_nmbr(bp,sp,I_MAX+1) *100 -used) / 100;
|
||||
|
||||
if (avail < 0)
|
||||
avail = 0;
|
||||
if (!player->simulation)
|
||||
sp->sct_avail = avail;
|
||||
else
|
||||
pt_bg_nmbr(bp,sp,I_MAX+1,avail);
|
||||
|
||||
if (sp->sct_type != SCT_AIRPT)
|
||||
build /= 3;
|
||||
if (onship){
|
||||
if ((pp->pln_effic + build) > 80)
|
||||
build = 80- pp ->pln_effic;
|
||||
}
|
||||
np->nat_money -= roundavg(mult * build *
|
||||
desc->pl_cost / 100.0);
|
||||
air_money[pp->pln_own] += np->nat_money - start_money;
|
||||
|
||||
if (!player->simulation)
|
||||
pp->pln_effic += (s_char)build;
|
||||
else
|
||||
np->nat_money = start_money;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
141
src/lib/update/populace.c
Normal file
141
src/lib/update/populace.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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* populace.c: Return workforce available
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "nat.h"
|
||||
#include "news.h"
|
||||
#include "var.h"
|
||||
#include "file.h"
|
||||
#include "path.h"
|
||||
#include "xy.h"
|
||||
#include "land.h"
|
||||
#include "budg.h"
|
||||
#include "update.h"
|
||||
#include "subs.h"
|
||||
#include "gen.h"
|
||||
#include "common.h"
|
||||
#include "lost.h"
|
||||
|
||||
void
|
||||
populace(struct natstr *np, register struct sctstr *sp, register int *vec, int etu)
|
||||
{
|
||||
float hap;
|
||||
float tech;
|
||||
float edu;
|
||||
float pct;
|
||||
int n;
|
||||
|
||||
if (vec[I_CIVIL] == 0 && vec[I_MILIT] > 0) {
|
||||
sp->sct_work = 100;
|
||||
sp->sct_loyal = 0;
|
||||
sp->sct_oldown = sp->sct_own;
|
||||
}
|
||||
if (!vec[I_CIVIL] && !vec[I_MILIT] && !vec[I_UW] &&
|
||||
!has_units(sp->sct_x,sp->sct_y,sp->sct_own,0)) {
|
||||
makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y);
|
||||
sp->sct_own = 0;
|
||||
sp->sct_oldown = 0;
|
||||
return;
|
||||
}
|
||||
if (sp->sct_own != sp->sct_oldown && sp->sct_loyal == 0) {
|
||||
sp->sct_oldown = sp->sct_own;
|
||||
}
|
||||
|
||||
hap = np->nat_level[NAT_HLEV];
|
||||
edu = np->nat_level[NAT_ELEV];
|
||||
tech = np->nat_level[NAT_TLEV];
|
||||
pct = (double)((tech - 40) / 40.0 + edu / 3.0);
|
||||
if (sp->sct_own == sp->sct_oldown && hap < pct &&
|
||||
chance((double)(((double)pct-(double)hap)/(double)5.0))) {
|
||||
/*
|
||||
* zap the loyalty of unhappy civilians.
|
||||
* there is a 20% chance per hap point below the
|
||||
* "recommended" amount of this happening.
|
||||
*/
|
||||
n = roundavg(etu * 0.125);
|
||||
if (n == 0) n = 1;
|
||||
n = sp->sct_loyal + (random() % n) + 1;
|
||||
if (n > 127)
|
||||
n = 127;
|
||||
sp->sct_loyal = n;
|
||||
}
|
||||
if (sp->sct_loyal > 65 && vec[I_MILIT] < vec[I_CIVIL]/20) {
|
||||
int work_red;
|
||||
|
||||
work_red = sp->sct_loyal - (50 + (random() % 15));
|
||||
n = sp->sct_work - work_red;
|
||||
if (n < 0)
|
||||
n = 0;
|
||||
sp->sct_work = n;
|
||||
if (chance((double)work_red/1000.0)) {
|
||||
/*
|
||||
* small chance of rebellion...
|
||||
* if work_red is (max) 67,
|
||||
* then revolt chance is 6.7%
|
||||
*/
|
||||
revolt(sp);
|
||||
} else if (chance(.30) && sp->sct_own)
|
||||
wu(0, sp->sct_own, "Civil unrest in %s!\n", ownxy(sp));
|
||||
}
|
||||
if (sp->sct_loyal) {
|
||||
n = sp->sct_loyal;
|
||||
if (chance(0.75))
|
||||
n -= roundavg(etu * 0.25);
|
||||
else
|
||||
n += roundavg(etu * 0.125);
|
||||
if (n < 0)
|
||||
n = 0;
|
||||
else if (n > 127)
|
||||
n = 127;
|
||||
sp->sct_loyal = n;
|
||||
if (sp->sct_loyal == 0) {
|
||||
if (sp->sct_oldown != sp->sct_own) {
|
||||
wu(0, sp->sct_own,
|
||||
"Sector %s is now fully yours\n",
|
||||
ownxy(sp));
|
||||
sp->sct_oldown = sp->sct_own;
|
||||
}
|
||||
sp->sct_loyal = 0;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
total_work(register int sctwork, register int etu, register int civil, register int milit, register int uw)
|
||||
{
|
||||
return ((int)((((civil * sctwork) / 100.0 +
|
||||
(milit * 2 / 5.0) + uw)) * etu) / 100);
|
||||
}
|
187
src/lib/update/prepare.c
Normal file
187
src/lib/update/prepare.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* prepare.c: Perform prelimiary updates of sectors
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Thomas Ruschak, 1992
|
||||
* Steve McClure, 1997
|
||||
*/
|
||||
|
||||
#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 "path.h"
|
||||
#include "optlist.h"
|
||||
#include "budg.h"
|
||||
#include "player.h"
|
||||
#include "ship.h"
|
||||
#include "land.h"
|
||||
#include "update.h"
|
||||
#include "gen.h"
|
||||
#include "common.h"
|
||||
|
||||
extern float levels[MAXNOC][4];
|
||||
|
||||
void
|
||||
prepare_sects(int etu, int *bp)
|
||||
{
|
||||
extern long pops[];
|
||||
register struct sctstr *sp;
|
||||
struct natstr *np;
|
||||
int n, civ_tax, uw_tax, mil_pay;
|
||||
|
||||
bzero((s_char *)levels, sizeof(levels));
|
||||
|
||||
/* Process all the fallout. */
|
||||
if (opt_FALLOUT) {
|
||||
if (!player->simulation) {
|
||||
/* First, we determine which sectors to process fallout in */
|
||||
for (n = 0; NULL != (sp = getsectid(n)); n++) {
|
||||
if (getvar(V_FALLOUT, (s_char *)sp, EF_SECTOR))
|
||||
sp->sct_updated = 1;
|
||||
else
|
||||
sp->sct_updated = 0;
|
||||
}
|
||||
/* Next, we process the fallout there */
|
||||
for (n = 0; NULL != (sp = getsectid(n)); n++)
|
||||
if (sp->sct_updated)
|
||||
do_fallout(sp, etu);
|
||||
/* Next, we spread the fallout */
|
||||
for (n = 0; NULL != (sp = getsectid(n)); n++)
|
||||
if (sp->sct_updated)
|
||||
spread_fallout(sp, etu);
|
||||
/* Next, we decay the fallout */
|
||||
for (n = 0; NULL != (sp = getsectid(n)); n++)
|
||||
if (getvar(V_FALLOUT, (s_char *)sp, EF_SECTOR))
|
||||
decay_fallout(sp, etu);
|
||||
}
|
||||
}
|
||||
for (n=0; NULL != (sp = getsectid(n)); n++) {
|
||||
sp->sct_updated = 0;
|
||||
|
||||
if (sp->sct_type == SCT_WATER)
|
||||
continue;
|
||||
fill_update_array(bp, sp);
|
||||
np = getnatp(sp->sct_own);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (np->nat_stat & STAT_SANCT)
|
||||
logerror("Prepare.c: country in sanctuary skipped production");
|
||||
#endif /* DEBUG */
|
||||
|
||||
if (!(np->nat_stat & STAT_SANCT)){
|
||||
guerrilla(sp);
|
||||
do_plague(sp, np, etu);
|
||||
tax(sp, np, etu, &pops[sp->sct_own], &civ_tax, &uw_tax, &mil_pay);
|
||||
np->nat_money += civ_tax + uw_tax + mil_pay;
|
||||
if (sp->sct_type == SCT_BANK)
|
||||
np->nat_money += bank_income(sp, etu);
|
||||
}
|
||||
}
|
||||
for (n=0; NULL != (np = getnatp(n)); n++) {
|
||||
np->nat_money += upd_slmilcosts(np->nat_cnum, etu);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tax(struct sctstr *sp, struct natstr *np, int etu, long *pop, int *civ_tax, int *uw_tax, int *mil_pay)
|
||||
{
|
||||
int vec[I_MAX+1];
|
||||
extern double money_civ, money_mil, money_uw;
|
||||
|
||||
*civ_tax = 0;
|
||||
*uw_tax = 0;
|
||||
*mil_pay = 0;
|
||||
if (getvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR) <= 0)
|
||||
return;
|
||||
|
||||
if (!player->simulation)
|
||||
populace(np, sp, vec, etu);
|
||||
*civ_tax = (int)(0.5 + vec[I_CIVIL] * sp->sct_effic *
|
||||
etu * money_civ / 100);
|
||||
/*
|
||||
* captured civs only pay 1/4 taxes
|
||||
*/
|
||||
if (sp->sct_own != sp->sct_oldown)
|
||||
*civ_tax = *civ_tax / 4;
|
||||
*uw_tax = (int)(0.5 + vec[I_UW] * sp->sct_effic *
|
||||
etu * money_uw / 100);
|
||||
*mil_pay = vec[I_MILIT] * etu * money_mil;
|
||||
|
||||
/*
|
||||
* only non-captured civs add to census for nation
|
||||
*/
|
||||
if (sp->sct_oldown == sp->sct_own)
|
||||
*pop += vec[I_CIVIL];
|
||||
}
|
||||
|
||||
int
|
||||
upd_slmilcosts(natid n, int etu)
|
||||
{
|
||||
extern double money_mil;
|
||||
struct shpstr *sp;
|
||||
struct lndstr *lp;
|
||||
int mil = 0;
|
||||
int totalmil = 0;
|
||||
int mil_pay = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; NULL != (sp = getshipp(i)); i++) {
|
||||
if (!sp->shp_own || sp->shp_own != n)
|
||||
continue;
|
||||
if ((mil = getvar(V_MILIT, (s_char *)sp, EF_SHIP)) > 0)
|
||||
totalmil += mil;
|
||||
}
|
||||
for (i = 0; NULL != (lp = getlandp(i)); i++) {
|
||||
if (!lp->lnd_own || lp->lnd_own != n)
|
||||
continue;
|
||||
if ((mil = getvar(V_MILIT, (s_char *)lp, EF_LAND)) > 0)
|
||||
totalmil += mil;
|
||||
}
|
||||
mil_pay = totalmil * etu * money_mil;
|
||||
return (mil_pay);
|
||||
}
|
||||
|
||||
int
|
||||
bank_income(struct sctstr *sp, int etu)
|
||||
{
|
||||
extern double bankint;
|
||||
int vec[I_MAX+1];
|
||||
|
||||
if (getvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR) <= 0)
|
||||
return 0;
|
||||
else
|
||||
return (int)(vec[I_BAR] * etu * bankint * sp->sct_effic / 100);
|
||||
}
|
237
src/lib/update/produce.c
Normal file
237
src/lib/update/produce.c
Normal file
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* produce.c: Produce goodies
|
||||
*
|
||||
* Known contributors to this file:
|
||||
*
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "product.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "xy.h"
|
||||
#include "player.h"
|
||||
#include "update.h"
|
||||
#include "gen.h"
|
||||
#include "subs.h"
|
||||
#include "common.h"
|
||||
#include "optlist.h"
|
||||
|
||||
s_char *levelnames[] = { "Technology", "Research", "Education", "Happiness" };
|
||||
|
||||
int
|
||||
produce(struct natstr *np, struct sctstr *sp, int *vec, int work, int sctwork, int desig, int neweff, int *cost, int *amount)
|
||||
{
|
||||
extern float levels[MAXNOC][4];
|
||||
extern long tpops[];
|
||||
register struct pchrstr *product;
|
||||
int vtype;
|
||||
double p_e;
|
||||
double level_p_e;
|
||||
s_char *resource;
|
||||
int output;
|
||||
int actual;
|
||||
int unit_work;
|
||||
double depend;
|
||||
int item;
|
||||
int worker_limit;
|
||||
int material_limit;
|
||||
int material_consume;
|
||||
int val;
|
||||
|
||||
product = &pchr[dchr[desig].d_prd];
|
||||
if (product == &pchr[0])
|
||||
return 0;
|
||||
vtype = product->p_type;
|
||||
item = vtype &~ VT_ITEM;
|
||||
*amount = 0;
|
||||
*cost = 0;
|
||||
|
||||
if ((material_limit = materials_cost(product, vec, &unit_work)) <= 0)
|
||||
return 0;
|
||||
/*
|
||||
* calculate production efficiency.
|
||||
*/
|
||||
p_e = neweff / 100.0;
|
||||
if (product->p_nrndx != 0) {
|
||||
unit_work++;
|
||||
resource = ((s_char *) sp) + product->p_nrndx;
|
||||
p_e = (*resource * p_e) / 100.0;
|
||||
if (product->p_nrdep > 0) {
|
||||
/* XXX this looks way wrong */
|
||||
depend = (*resource * 100.0) / product->p_nrdep;
|
||||
if (p_e > depend)
|
||||
p_e = depend;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* determine number that can be made with
|
||||
* the available workforce
|
||||
*/
|
||||
if (unit_work == 0)
|
||||
unit_work = 1;
|
||||
material_consume = material_limit;
|
||||
worker_limit = roundavg(work * p_e / unit_work);
|
||||
if (material_consume > worker_limit)
|
||||
material_consume = worker_limit;
|
||||
if (material_consume == 0)
|
||||
return 0;
|
||||
level_p_e = 1.0;
|
||||
if (product->p_nlndx >= 0) {
|
||||
level_p_e = np->nat_level[product->p_nlndx] - product->p_nlmin;
|
||||
if ((level_p_e < 0.0) && (!player->simulation)) {
|
||||
wu(0, sp->sct_own,
|
||||
"%s level too low to produce in %s (need %d)\n",
|
||||
levelnames[product->p_nlndx], ownxy(sp),
|
||||
product->p_nlmin);
|
||||
return 0;
|
||||
}
|
||||
level_p_e = level_p_e / (level_p_e + product->p_nllag);
|
||||
}
|
||||
/*
|
||||
* Adjust produced amount by commodity production ratio
|
||||
*/
|
||||
output = roundavg(product->p_effic * 0.01 * material_consume);
|
||||
if ((vtype == 0) && (!player->simulation)) {
|
||||
levels[sp->sct_own][product->p_level] += output * level_p_e;
|
||||
wu((natid)0, sp->sct_own, "%s (%.2f) produced in %s\n",
|
||||
product->p_name, output * level_p_e, ownxy(sp));
|
||||
} else {
|
||||
if ((actual = roundavg(level_p_e * output)) <= 0)
|
||||
return 0;
|
||||
if (product->p_nrdep != 0) {
|
||||
if(*resource*100 < product->p_nrdep*actual)
|
||||
actual = *resource*100/product->p_nrdep;
|
||||
}
|
||||
if (actual > 999) {
|
||||
actual = 999;
|
||||
material_consume = (int)(actual / (product->p_effic * 0.01));
|
||||
}
|
||||
vec[item] += actual;
|
||||
if (vec[item] > 9999) {
|
||||
material_consume =
|
||||
roundavg((9999.0 - vec[item] + actual) *
|
||||
material_consume / actual);
|
||||
if (material_consume < 0)
|
||||
material_consume = 0;
|
||||
vec[item] = 9999;
|
||||
if ((/* vtype != V_FOOD && */ sp->sct_own) &&
|
||||
(!player->simulation))
|
||||
wu(0, sp->sct_own,
|
||||
"%s production backlog in %s\n",
|
||||
product->p_name, ownxy(sp));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Reset produced amount by commodity production ratio
|
||||
*/
|
||||
if (!player->simulation) {
|
||||
materials_charge(product, vec, material_consume);
|
||||
if (product->p_nrdep != 0) {
|
||||
/*
|
||||
* lower natural resource in sector depending on
|
||||
* amount produced
|
||||
*/
|
||||
val = *resource - roundavg(product->p_nrdep *
|
||||
material_consume / 100.0);
|
||||
if (val < 0)
|
||||
val = 0;
|
||||
*resource = val;
|
||||
}
|
||||
}
|
||||
*amount = actual;
|
||||
*cost = product->p_cost * material_consume;
|
||||
|
||||
if (opt_TECH_POP) {
|
||||
if (product->p_level == NAT_TLEV) {
|
||||
if (tpops[sp->sct_own] > 50000)
|
||||
*cost = (double)*cost * (double)tpops[sp->sct_own] / 50000.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The min() here is to take care of integer rounding errors */
|
||||
if (p_e > 0.0) {
|
||||
return min(work, (int)(unit_work * material_consume / p_e));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
materials_cost(struct pchrstr *product, register int *vec, int *costp)
|
||||
{
|
||||
register u_char *vp;
|
||||
register u_short *ap;
|
||||
register int count;
|
||||
register int cost;
|
||||
register int n;
|
||||
register u_char *endp;
|
||||
|
||||
count = 9999;
|
||||
cost = 0;
|
||||
ap = product->p_vamt;
|
||||
endp = product->p_vtype + product->p_nv;
|
||||
for (vp = product->p_vtype; vp < endp; vp++, ap++) {
|
||||
if (!*ap)
|
||||
continue;
|
||||
n = vec[*vp & ~VT_ITEM] / *ap;
|
||||
if (n < count)
|
||||
count = n;
|
||||
cost += *ap;
|
||||
}
|
||||
*costp = cost;
|
||||
return count;
|
||||
}
|
||||
|
||||
void
|
||||
materials_charge(struct pchrstr *product, register int *vec, register int count)
|
||||
{
|
||||
register u_char *vp;
|
||||
register u_short *ap;
|
||||
register u_char *endp;
|
||||
register int item;
|
||||
register int n;
|
||||
|
||||
ap = product->p_vamt;
|
||||
endp = product->p_vtype + product->p_nv;
|
||||
for (vp = product->p_vtype; vp < endp; vp++, ap++) {
|
||||
item = *vp & ~VT_ITEM;
|
||||
if (item < 0 || item > I_MAX) {
|
||||
logerror("materials_charge: bad item %d", item);
|
||||
continue;
|
||||
}
|
||||
if ((n = vec[item] - *ap * count) < 0) {
|
||||
logerror("materials_charge: %d > %d item #%d",
|
||||
n, vec[item], item);
|
||||
n = 0;
|
||||
}
|
||||
vec[item] = n;
|
||||
}
|
||||
}
|
58
src/lib/update/removewants.c
Normal file
58
src/lib/update/removewants.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* removewants.c: Remove the "I want an update" flag.
|
||||
*
|
||||
* Known contributors to this file:
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include "misc.h"
|
||||
#include "nat.h"
|
||||
#include "file.h"
|
||||
#include "update.h"
|
||||
|
||||
int
|
||||
update_removewants(void)
|
||||
{
|
||||
natid cn;
|
||||
struct natstr *natp;
|
||||
|
||||
for (cn = 0; NULL != (natp=getnatp(cn)); cn++) {
|
||||
if ((natp->nat_stat & STAT_INUSE) &&
|
||||
(natp->nat_update & WUPD_WANT) == 0){
|
||||
natp->nat_missed++;
|
||||
}
|
||||
natp->nat_update = natp->nat_stat & ~WUPD_WANT;
|
||||
}
|
||||
return 0;
|
||||
}
|
595
src/lib/update/revolt.c
Normal file
595
src/lib/update/revolt.c
Normal file
|
@ -0,0 +1,595 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* revolt.c: Have disloyal populace revolt!
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Steve McClure, 1997-2000
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "nat.h"
|
||||
#include "news.h"
|
||||
#include "var.h"
|
||||
#include "file.h"
|
||||
#include "path.h"
|
||||
#include "xy.h"
|
||||
#include "land.h"
|
||||
#include "nsc.h"
|
||||
#include "plane.h"
|
||||
#include "update.h"
|
||||
#include "common.h"
|
||||
#include "gen.h"
|
||||
#include "lost.h"
|
||||
#include "subs.h"
|
||||
|
||||
#define get_che_cnum(x) ((x) >> 8)
|
||||
#define set_che_cnum(x, cn) ((x) = ((x) & 0xff) | ((cn) << 8))
|
||||
#define get_che_value(x) ((x) & 0xff)
|
||||
#define set_che_value(x, n) ((x) = ((x) & 0xff00) | (n))
|
||||
|
||||
#define CHE_MAX 255
|
||||
|
||||
void
|
||||
revolt(struct sctstr *sp)
|
||||
{
|
||||
int che_civ;
|
||||
int che_uw;
|
||||
int civ;
|
||||
int uw;
|
||||
u_short che_combo;
|
||||
int che;
|
||||
int n;
|
||||
int target;
|
||||
|
||||
che_combo = getvar(V_CHE, (s_char *)sp, EF_SECTOR);
|
||||
che = get_che_value(che_combo);
|
||||
target = get_che_cnum(che_combo);
|
||||
if (che_combo != 0 && (target != sp->sct_own || che >= CHE_MAX))
|
||||
return;
|
||||
civ = getvar(V_CIVIL, (s_char *)sp, EF_SECTOR);
|
||||
uw = getvar(V_UW, (s_char *)sp, EF_SECTOR);
|
||||
if (che > (civ + uw) * 3)
|
||||
return;
|
||||
che_uw = 0;
|
||||
che_civ = 0;
|
||||
/* che due to civilian unrest */
|
||||
n = 10 - (random() % 20);
|
||||
che_civ = 3 + (civ * n/500);
|
||||
if (che_civ < 0)
|
||||
che_civ = 0;
|
||||
else if (che_civ * 3 > civ)
|
||||
che_civ = civ / 3;
|
||||
if (che + che_civ > CHE_MAX)
|
||||
che_civ = CHE_MAX - che;
|
||||
che += che_civ;
|
||||
if (che < CHE_MAX) {
|
||||
/* che due to uw unrest */
|
||||
n = 10 + (random() % 30);
|
||||
che_uw = 5 + (uw * n/500);
|
||||
if (che_uw > uw)
|
||||
che_uw = uw;
|
||||
if (che + che_uw > CHE_MAX)
|
||||
che_uw = CHE_MAX - che_uw;
|
||||
che += che_uw;
|
||||
}
|
||||
if (che_civ + che_uw > 0) {
|
||||
civ -= che_civ;
|
||||
uw -= che_uw;
|
||||
set_che_cnum(che_combo, sp->sct_own);
|
||||
set_che_value(che_combo, che);
|
||||
putvar(V_CHE, (int)che_combo, (s_char *)sp, EF_SECTOR);
|
||||
if (che_civ > 0)
|
||||
putvar(V_CIVIL, civ, (s_char *)sp, EF_SECTOR);
|
||||
if (che_uw > 0)
|
||||
putvar(V_UW, uw, (s_char *)sp, EF_SECTOR);
|
||||
#ifdef DEBUG
|
||||
logerror("(#%d) %d che fired up in %s",
|
||||
sp->sct_own, che, ownxy(sp));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* summary of effects.
|
||||
* if there are no military in the sector, che recruit from
|
||||
* populace if pop loyalty is > 10. They spread subversion otherwise,
|
||||
* trying to lower pop loyalty.
|
||||
* if che outnumber military, they stay and shoot it out, kill the
|
||||
* military.
|
||||
* if che are outnumbered by less than 5 to 1, they blow up stuff,
|
||||
* killing innocent civilians (never uw's) and damaging commodities.
|
||||
* if che are outnumbered by more than 5 to 1, they try to leave the
|
||||
* sector for a nearby sector with fewer military.
|
||||
*
|
||||
* if the military lose any attacks, the pop loyalty in the sector
|
||||
* gets worse, representing military defeat.
|
||||
* military can "catch" che's after bombing attacks, or after they move.
|
||||
* If military catch them, then they get to shoot it out with a portion
|
||||
* of the che's depending on the # of mil in the sector. Chance to contact
|
||||
* is around 10% per every equal number of mil:che ratio in the sector.
|
||||
* "contact" is by 20% of the military in the sector, and odds are equal.
|
||||
*
|
||||
* Without a doubt this routine should be broken up, if only for readabilty.
|
||||
*/
|
||||
void
|
||||
guerrilla(struct sctstr *sp)
|
||||
{
|
||||
extern s_char *effadv();
|
||||
struct sctstr *nsp;
|
||||
int recruit;
|
||||
int move;
|
||||
int ratio;
|
||||
int che;
|
||||
int mil;
|
||||
int cc, mc;
|
||||
double odds;
|
||||
int civ;
|
||||
int n;
|
||||
int uw;
|
||||
natid target;
|
||||
struct natstr *tnat;
|
||||
int convert;
|
||||
natid actor;
|
||||
natid victim;
|
||||
u_short che_combo;
|
||||
int vec[I_MAX+1];
|
||||
int tmp;
|
||||
int min_mil;
|
||||
int val;
|
||||
int oldmob;
|
||||
struct lndstr *lp;
|
||||
s_char *nxtitemp(struct nstr_item *np, int owner);
|
||||
struct nstr_item ni;
|
||||
extern double hap_fact();
|
||||
|
||||
mc = cc = 0;
|
||||
recruit = 0;
|
||||
convert = 0;
|
||||
move = 0;
|
||||
if ((n = getvar(V_CHE, (s_char *)sp, EF_SECTOR)) <= 0)
|
||||
return;
|
||||
che_combo = n;
|
||||
if (getvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR) <= 0)
|
||||
return;
|
||||
civ = vec[I_CIVIL];
|
||||
|
||||
uw = vec[I_UW];
|
||||
victim = sp->sct_own;
|
||||
actor = sp->sct_oldown;
|
||||
che = get_che_value(che_combo);
|
||||
|
||||
mil = vec[I_MILIT];
|
||||
snxtitem_xy(&ni, EF_LAND, sp->sct_x,sp->sct_y);
|
||||
|
||||
while (NULL != (lp=(struct lndstr *)nxtitemp(&ni, 0))){
|
||||
if (lp->lnd_own != sp->sct_own)
|
||||
continue;
|
||||
|
||||
mil += lnd_getmil(lp);
|
||||
|
||||
/* Security troops can now kill up to 1/2 their complement each
|
||||
update, before doing anything else. */
|
||||
if (lchr[(int)lp->lnd_type].l_flags & L_SECURITY){
|
||||
int che_kill, r;
|
||||
struct lchrstr *lcp;
|
||||
|
||||
lcp = &lchr[(int)lp->lnd_type];
|
||||
mil += lnd_getmil(lp);
|
||||
r = (((float)(lp->lnd_effic / 100) * (float)(lnd_getmil(lp))) / 2);
|
||||
if (r < 2)
|
||||
r = 2;
|
||||
che_kill = (roll(r) - 1);
|
||||
if (che_kill > che)
|
||||
che_kill = che;
|
||||
if (che_kill) {
|
||||
wu(0, sp->sct_own,
|
||||
"%s kills %d guerrilla%s in raid at %s!\n",
|
||||
prland(lp),
|
||||
che_kill, splur(che_kill),
|
||||
ownxy(sp));
|
||||
che -= che_kill;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Security forces killed all the che */
|
||||
if (che <= 0) {
|
||||
putvar(V_CHE, 0, (s_char *)sp, EF_SECTOR);
|
||||
return;
|
||||
}
|
||||
|
||||
target = get_che_cnum(che_combo);
|
||||
if (target == 0) {
|
||||
/* the deity can't be a target! */
|
||||
return;
|
||||
}
|
||||
tnat = getnatp(target);
|
||||
if ((tnat->nat_stat & STAT_INUSE) == 0) {
|
||||
/* target nation has dissolved: che's retire. */
|
||||
logerror("%d Che targeted at country %d retiring", che, target);
|
||||
civ += che;
|
||||
putvar(V_CHE, 0, (s_char *)sp, EF_SECTOR);
|
||||
putvar(V_CIVIL, civ, (s_char *)sp, EF_SECTOR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sp->sct_own != target) {
|
||||
/*logerror("own %d != target %d", sp->sct_own, target);*/
|
||||
move++;
|
||||
goto domove;
|
||||
}
|
||||
|
||||
ratio = mil / che;
|
||||
odds = (double) che / (mil+che);
|
||||
odds /= hap_fact(tnat,getnatp(sp->sct_oldown));
|
||||
if (mil == 0) {
|
||||
wu(0, sp->sct_own, "Revolutionary subversion reported in %s!\n",
|
||||
ownxy(sp));
|
||||
recruit++;
|
||||
convert++;
|
||||
} else if (che > mil && mil > 0) {
|
||||
/*logerror("guerrilla shootout with military");*/
|
||||
/*
|
||||
* shoot it out with the military, and kill them off.
|
||||
* If loyalty bad enough, then take the sector over,
|
||||
* and enlist 5% of civ as military force.
|
||||
*/
|
||||
while (che > 0 && mil > 0) {
|
||||
if (chance(odds)) {
|
||||
mc++;
|
||||
mil--;
|
||||
} else {
|
||||
cc++;
|
||||
che--;
|
||||
}
|
||||
}
|
||||
if (mil > 0) {
|
||||
/* military won. */
|
||||
n = sp->sct_loyal - (random() % 15);
|
||||
if (n < 0)
|
||||
n = 0;
|
||||
sp->sct_loyal = n;
|
||||
/*logerror("(#%d) mil beat che in %s", sp->sct_own,*/
|
||||
/*ownxy(sp));*/
|
||||
} else {
|
||||
convert++;
|
||||
recruit++;
|
||||
/*logerror("(#%d) che beat mil in %s", sp->sct_own,*/
|
||||
/*ownxy(sp));*/
|
||||
}
|
||||
take_casualties(sp,mc);
|
||||
} else if (ratio < 5) {
|
||||
/*
|
||||
* guerrillas have to resort to blowing things up.
|
||||
* Note this disrupts work in the sector.
|
||||
*/
|
||||
n = 0;
|
||||
n = (random() % 10) + (random() % che);
|
||||
if (n > 100)
|
||||
n = 100;
|
||||
tmp = sp->sct_work - n;
|
||||
if (tmp < 0)
|
||||
tmp = 0;
|
||||
sp->sct_work = tmp;
|
||||
wu(0, sp->sct_own,
|
||||
"Production %s disrupted by terrorists in %s\n",
|
||||
effadv(n), ownxy(sp));
|
||||
sect_damage(sp, n/10, 0);
|
||||
/*logerror("(#%d) che blew up %s for %d", sp->sct_own,*/
|
||||
/*ownxy(sp), n);*/
|
||||
recruit++;
|
||||
} else {
|
||||
/* ratio >= 5 */
|
||||
/*logerror("(#%d) %d che fleeing %d mil in %s", sp->sct_own,*/
|
||||
/*che, mil, ownxy(sp));*/
|
||||
move++;
|
||||
}
|
||||
if (mil > 0 && che > 0) {
|
||||
/*
|
||||
* we only get here if we haven't had combat previously.
|
||||
* Chance to catch them.
|
||||
* 20% of mil involved in attacking the che's.
|
||||
*/
|
||||
if (chance(ratio*0.10)) {
|
||||
n = (mil/5) + 1;
|
||||
if ((n+che) == 0){
|
||||
logerror("n=%d che=%d\n",n,che);
|
||||
if (che == 0)
|
||||
return;
|
||||
}
|
||||
odds = (double) che / (n + che);
|
||||
odds /= hap_fact(tnat,getnatp(sp->sct_oldown));
|
||||
while (che > 0 && n > 0) {
|
||||
if (chance(odds)) {
|
||||
mc++;
|
||||
n--;
|
||||
} else {
|
||||
cc++;
|
||||
che--;
|
||||
}
|
||||
}
|
||||
take_casualties(sp,mc);
|
||||
recruit = 0;
|
||||
/*logerror("Caught che; mc: %d, cc: %d", cc, mc);*/
|
||||
}
|
||||
}
|
||||
if (convert && sp->sct_loyal >= 50) {
|
||||
register int n;
|
||||
/* new owner gets to keep the mobility there */
|
||||
oldmob = sp->sct_mobil;
|
||||
/* che won, and sector converts. */
|
||||
if (sp->sct_own == sp->sct_oldown)
|
||||
sp->sct_oldown = 0;
|
||||
else
|
||||
takeover(sp, sp->sct_oldown);
|
||||
sp->sct_mobil = oldmob;
|
||||
civ += uw;
|
||||
uw = 0;
|
||||
/*
|
||||
* so we can't keep losing money by having
|
||||
* our cap retaken
|
||||
*/
|
||||
if (sp->sct_type == SCT_CAPIT &&
|
||||
sp->sct_newtype == SCT_CAPIT)
|
||||
sp->sct_newtype = SCT_AGRI;
|
||||
n = civ / 20;
|
||||
civ -= n;
|
||||
putvar(V_CIVIL, civ, (s_char *)sp, EF_SECTOR);
|
||||
putvar(V_UW, uw, (s_char *)sp, EF_SECTOR);
|
||||
putvar(V_MILIT, n, (s_char *)sp, EF_SECTOR);
|
||||
move++;
|
||||
recruit = 0;
|
||||
if (sp->sct_own)
|
||||
wu(0, sp->sct_own, "Sector %s has been retaken!\n",
|
||||
xyas(sp->sct_x, sp->sct_y, sp->sct_own));
|
||||
}
|
||||
if (recruit && che > 0) {
|
||||
/* loyalty drops during recruitment efforts */
|
||||
n = sp->sct_loyal;
|
||||
if (n < 30)
|
||||
n += (random() % 5) + 1;
|
||||
else if (n < 70)
|
||||
n += (random() % 10) + 4;
|
||||
if (n > 127)
|
||||
n = 127;
|
||||
sp->sct_loyal = n;
|
||||
if (sp->sct_oldown != sp->sct_own || n > 100) {
|
||||
n = civ * (random() % 3) / 200;
|
||||
n /= hap_fact(tnat,getnatp(sp->sct_oldown));
|
||||
if (n + che > CHE_MAX)
|
||||
n = CHE_MAX - che;
|
||||
che += n;
|
||||
civ -= n;
|
||||
putvar(V_CIVIL, civ, (s_char *)sp, EF_SECTOR);
|
||||
}
|
||||
n = uw * (random() % 3) / 200;
|
||||
if (n + che > CHE_MAX)
|
||||
n = CHE_MAX - che;
|
||||
che += n;
|
||||
uw -= n;
|
||||
putvar(V_UW, uw, (s_char *)sp, EF_SECTOR);
|
||||
}
|
||||
domove:
|
||||
if (move && che > 0) {
|
||||
struct sctstr *maybe_sp = 0;
|
||||
if (convert)
|
||||
min_mil = 999;
|
||||
else
|
||||
min_mil = mil;
|
||||
for (n=1; n<=6; n++) {
|
||||
nsp = getsectp(sp->sct_x+diroff[n][0],
|
||||
sp->sct_y+diroff[n][1]);
|
||||
if (dchr[nsp->sct_type].d_mcst == 0)
|
||||
continue;
|
||||
if (nsp->sct_own != target)
|
||||
continue;
|
||||
if ((val = getvar(V_CHE, (s_char *)nsp, EF_SECTOR)) > 0) {
|
||||
che_combo = val;
|
||||
if (get_che_cnum(che_combo) != target)
|
||||
continue;
|
||||
if (get_che_value(che_combo) + che > CHE_MAX)
|
||||
continue;
|
||||
}
|
||||
val = getvar(V_MILIT, (s_char *)nsp, EF_SECTOR);
|
||||
if (val >= min_mil)
|
||||
continue;
|
||||
maybe_sp = nsp;
|
||||
min_mil = val;
|
||||
}
|
||||
/*
|
||||
* if n <= 6, we found a sector owned by TARGET which
|
||||
* is a nice sector. Otherwise, we move to the first
|
||||
* one we find ("maybe_sp").
|
||||
*/
|
||||
if (maybe_sp != 0) {
|
||||
che_combo = getvar(V_CHE, (s_char *)maybe_sp, EF_SECTOR);
|
||||
che += get_che_value(che_combo);
|
||||
set_che_value(che_combo, che);
|
||||
set_che_cnum(che_combo, target);
|
||||
putvar(V_CHE, (int) che_combo, (s_char *)maybe_sp, EF_SECTOR);
|
||||
che = 0;
|
||||
}
|
||||
}
|
||||
if (che > 0) {
|
||||
set_che_value(che_combo, che);
|
||||
set_che_cnum(che_combo, target);
|
||||
putvar(V_CHE, (int) che_combo, (s_char *)sp, EF_SECTOR);
|
||||
} else
|
||||
putvar(V_CHE, 0, (s_char *)sp, EF_SECTOR);
|
||||
if (mc > 0 || cc > 0) {
|
||||
/* don't tell who won just to be mean */
|
||||
wu(0, target,
|
||||
"Guerrilla warfare in %s\n",
|
||||
xyas(sp->sct_x, sp->sct_y, target));
|
||||
wu(0, target, " body count: troops: %d, rebels: %d\n", mc, cc);
|
||||
nreport(actor, N_FREEDOM_FIGHT, victim, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
take_casualties(struct sctstr *sp, int mc)
|
||||
{
|
||||
int orig_mil;
|
||||
int cantake;
|
||||
int nunits=0, each, deq;
|
||||
struct lndstr *lp;
|
||||
s_char *nxtitemp(struct nstr_item *np, int owner);
|
||||
struct nstr_item ni;
|
||||
|
||||
/* casualties come out of mil first */
|
||||
orig_mil = getvar(V_MILIT, (s_char *)sp, EF_SECTOR);
|
||||
|
||||
if (mc <= orig_mil){
|
||||
putvar(V_MILIT, (orig_mil-mc), (s_char *)sp, EF_SECTOR);
|
||||
return;
|
||||
}
|
||||
putvar(V_MILIT, 0, (s_char *)sp, EF_SECTOR);
|
||||
|
||||
/* remaining casualites */
|
||||
mc -= orig_mil;
|
||||
|
||||
/*
|
||||
* Need to take total_casualties and divide
|
||||
* them amongst the land units in the sector
|
||||
* Do security troops first, then others.
|
||||
* Try not to kill any unit.
|
||||
*/
|
||||
snxtitem_xy(&ni, EF_LAND, sp->sct_x,sp->sct_y);
|
||||
while(NULL != (lp=(struct lndstr *)nxtitemp(&ni, 0))){
|
||||
nunits++;
|
||||
if (lchr[(int)lp->lnd_type].l_flags & L_SECURITY)
|
||||
nunits++;
|
||||
}
|
||||
|
||||
if (nunits==0)
|
||||
return;
|
||||
|
||||
each = (mc/nunits)+2;
|
||||
|
||||
/* kill some security troops */
|
||||
snxtitem_xy(&ni, EF_LAND, sp->sct_x,sp->sct_y);
|
||||
while(NULL != (lp=(struct lndstr *)nxtitemp(&ni, 0))){
|
||||
if (!(lchr[(int)lp->lnd_type].l_flags & L_SECURITY))
|
||||
continue;
|
||||
|
||||
cantake = (((float)(lp->lnd_effic-40)/100.0)*
|
||||
(float)lnd_getmil(lp))*2;
|
||||
/* (float)lchr[lp->lnd_type].l_mil)*2;*/
|
||||
|
||||
if (cantake >= each){
|
||||
/* deq = (((float)each/(float)(lchr[lp->lnd_type].l_mil*2))*/
|
||||
deq = (((float)each/(float)(lnd_getmil(lp)*2))
|
||||
*100.0);
|
||||
mc -= each;
|
||||
}else if (cantake > 0){
|
||||
deq = (((float)cantake/
|
||||
(float)(lnd_getmil(lp)*2)) * 100.0);
|
||||
/* (float)(lchr[lp->lnd_type].l_mil*2)) * 100.0);*/
|
||||
mc -= (((float)deq/100.0)*
|
||||
(float)lnd_getmil(lp))*2;
|
||||
/* (float)lchr[lp->lnd_type].l_mil)*2;*/
|
||||
}else
|
||||
deq = 0;
|
||||
|
||||
lp->lnd_effic -= deq;
|
||||
lp->lnd_mobil -= deq/2;
|
||||
deq = (double)lchr[(int)lp->lnd_type].l_mil * (deq / 100.0);
|
||||
lnd_submil(lp, deq);
|
||||
if (mc<=0) return;
|
||||
}
|
||||
|
||||
/* kill some normal troops */
|
||||
snxtitem_xy(&ni, EF_LAND, sp->sct_x,sp->sct_y);
|
||||
while(NULL != (lp=(struct lndstr *)nxtitemp(&ni, 0))){
|
||||
if (lchr[(int)lp->lnd_type].l_flags & L_SECURITY)
|
||||
continue;
|
||||
|
||||
cantake = (((float)(lp->lnd_effic-40)/100.0)*
|
||||
(float)lnd_getmil(lp));
|
||||
|
||||
if (cantake >= each){
|
||||
deq = (((float)each/(float)(lnd_getmil(lp)*2))
|
||||
*100.0);
|
||||
mc -= each;
|
||||
}else if (cantake > 0){
|
||||
deq = (((float)cantake/(float)lnd_getmil(lp))
|
||||
* 100.0);
|
||||
mc -= (((float)deq/100.0)*
|
||||
(float)lnd_getmil(lp));
|
||||
}else
|
||||
deq = 0;
|
||||
lp->lnd_effic -= deq;
|
||||
lp->lnd_mobil -= deq/2;
|
||||
deq = (double)lchr[(int)lp->lnd_type].l_mil * (deq / 100.0);
|
||||
lnd_submil(lp, deq);
|
||||
if (mc<=0) return;
|
||||
}
|
||||
|
||||
/* Hmm.. still some left.. kill off units now */
|
||||
/* kill some normal troops */
|
||||
snxtitem_xy(&ni, EF_LAND, sp->sct_x,sp->sct_y);
|
||||
while(NULL != (lp=(struct lndstr *)nxtitemp(&ni, 0))){
|
||||
if (lchr[(int)lp->lnd_type].l_flags & L_SECURITY)
|
||||
continue;
|
||||
|
||||
mc -= (((float)lp->lnd_effic/100.0) *
|
||||
(float)lnd_getmil(lp));
|
||||
lp->lnd_effic = 0;
|
||||
lnd_submil(lp, 1000); /* Remove 'em all */
|
||||
wu(0,lp->lnd_own,"%s dies fighting guerrillas in %s\n",
|
||||
prland(lp),
|
||||
xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own));
|
||||
makelost(EF_LAND, lp->lnd_own, lp->lnd_uid, lp->lnd_x, lp->lnd_y);
|
||||
lp->lnd_own = 0;
|
||||
if (mc<=0) return;
|
||||
}
|
||||
|
||||
/* Hmm.. still some left.. kill off units now */
|
||||
/* kill some security troops */
|
||||
snxtitem_xy(&ni, EF_LAND, sp->sct_x,sp->sct_y);
|
||||
while(NULL != (lp = (struct lndstr *)nxtitemp(&ni, 0))){
|
||||
if (!(lchr[(int)lp->lnd_type].l_flags & L_SECURITY))
|
||||
continue;
|
||||
|
||||
mc -= (((float)lp->lnd_effic / 100.0) * (float)lnd_getmil(lp)) * 2;
|
||||
lp->lnd_effic = 0;
|
||||
lnd_submil(lp, 1000); /* Kill 'em all */
|
||||
wu(0, lp->lnd_own, "%s dies fighting guerrillas in %s\n",
|
||||
prland(lp),
|
||||
xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own));
|
||||
makelost(EF_LAND, lp->lnd_own, lp->lnd_uid, lp->lnd_x, lp->lnd_y);
|
||||
lp->lnd_own = 0;
|
||||
if (mc <= 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Hmm.. everyone dead.. too bad */
|
||||
}
|
352
src/lib/update/sail.c
Normal file
352
src/lib/update/sail.c
Normal file
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* sail.c: Sail ships during the update
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Doug Hay
|
||||
* Robert Forsman
|
||||
* Ken Stevens, 1995
|
||||
* Steve McClure, 1998-2000
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "path.h"
|
||||
#include "ship.h"
|
||||
#include "var.h"
|
||||
#include "news.h"
|
||||
#include "file.h"
|
||||
#include "nat.h"
|
||||
#include "xy.h"
|
||||
#include "nsc.h"
|
||||
#include "update.h"
|
||||
#include "subs.h"
|
||||
#include "common.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static void
|
||||
cost_ship(struct shpstr *sp, struct fltelemstr *ep, struct fltheadstr *fp)
|
||||
{
|
||||
double mobcost,ceil(double);
|
||||
int howfar;
|
||||
|
||||
mobcost = 0.0;
|
||||
if (sp->shp_effic > 0) {
|
||||
mobcost = sp->shp_effic * sp->shp_speed * 0.01;
|
||||
mobcost = 480.0 / ( mobcost*(1 + (50+sp->shp_tech)/
|
||||
(double)(200+sp->shp_tech)));
|
||||
}
|
||||
/* the next two lines are not necessary since shp_mobquota is unsigned
|
||||
and therefore cannot be less than 0.
|
||||
if (sp->shp_mobquota<0)
|
||||
sp->shp_mobquota=0;
|
||||
*/
|
||||
|
||||
howfar = 0;
|
||||
if (mobcost > 0) {
|
||||
howfar = (int)sp->shp_mobil - (int)sp->shp_mobquota;
|
||||
howfar = ceil((howfar / mobcost));
|
||||
}
|
||||
if (howfar<0)
|
||||
howfar=0;
|
||||
#ifdef SAILDEBUG
|
||||
wu(0,fp->own,
|
||||
"Ship #%d can move %d spaces on mobility %d (cost/sect %f)\n",
|
||||
sp->shp_uid, howfar, sp->shp_mobil, mobcost);
|
||||
#endif
|
||||
if ((unsigned int)howfar < fp->maxmoves)
|
||||
fp->maxmoves = howfar;
|
||||
|
||||
ep->mobil = sp->shp_mobil;
|
||||
ep->mobcost = mobcost;
|
||||
}
|
||||
|
||||
static int
|
||||
sail_find_fleet(struct fltheadstr **head, struct shpstr *sp)
|
||||
{
|
||||
struct fltheadstr *fltp;
|
||||
struct shpstr *ap;
|
||||
struct fltelemstr *this;
|
||||
int len=0;
|
||||
int follow = -1;
|
||||
int stop;
|
||||
s_char *cp;
|
||||
|
||||
if (sp->shp_own==0)
|
||||
return(0);
|
||||
|
||||
|
||||
|
||||
/* If this ship is following, find the head of the follow list. */
|
||||
for (ap=sp; ap; len++, ap=getshipp(follow)) {
|
||||
follow = ap->shp_follow;
|
||||
/* Not same owner */
|
||||
if (ap->shp_own != sp->shp_own) {
|
||||
wu(0, sp->shp_own,
|
||||
"Ship #%d, following #%d, which you don't own.\n",
|
||||
sp->shp_uid, ap->shp_uid);
|
||||
return(0);
|
||||
}
|
||||
/* Not a follower. */
|
||||
if (ap->shp_path[0] != 'f')
|
||||
break;
|
||||
/* Following itself */
|
||||
if (follow==ap->shp_uid ||
|
||||
follow==sp->shp_uid)
|
||||
break;
|
||||
}
|
||||
if (!ap) {
|
||||
wu(0, sp->shp_own,
|
||||
"Ship #%d, following #%d, which you don't own.\n",
|
||||
sp->shp_uid, follow);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* This should prevent infinite loops. */
|
||||
if (len>=10) {
|
||||
wu(0,sp->shp_own,
|
||||
"Ship #%d, too many follows (circular follow?).\n",
|
||||
sp->shp_uid);
|
||||
return(0);
|
||||
}
|
||||
|
||||
for (stop=0,cp=ap->shp_path; (!stop) && (*cp); cp++) {
|
||||
switch (*cp) {
|
||||
case 'y':
|
||||
case 'u':
|
||||
case 'g':
|
||||
case 'j':
|
||||
case 'b':
|
||||
case 'n':
|
||||
case 'h':
|
||||
case 't':
|
||||
break;
|
||||
default:
|
||||
stop=1;
|
||||
}
|
||||
}
|
||||
|
||||
/* we found a non-valid char in the path. */
|
||||
if (*cp) {
|
||||
wu(0,ap->shp_own, "invalid char '\\%03o' in path of ship %d\n",
|
||||
(unsigned char)*cp, ap->shp_uid);
|
||||
*cp=0;
|
||||
}
|
||||
|
||||
/* if this ship is not sailing anywhere then ignore it. */
|
||||
if (!*ap->shp_path)
|
||||
return(0);
|
||||
|
||||
/* Find the fleet structure we belong to. */
|
||||
for (fltp=(*head); (fltp && fltp->leader != follow); fltp = fltp->next)
|
||||
;
|
||||
|
||||
if (!fltp) {
|
||||
fltp = (struct fltheadstr *) malloc(sizeof(*fltp));
|
||||
bzero((s_char *)fltp, sizeof(*fltp));
|
||||
|
||||
/* Fix the links. */
|
||||
fltp->next = (*head);
|
||||
*head = fltp;
|
||||
|
||||
/* Set the leader. */
|
||||
fltp->leader = ap->shp_uid;
|
||||
fltp->real_q = LEADER_REAL;
|
||||
fltp->x = ap->shp_x;
|
||||
fltp->y = ap->shp_y;
|
||||
fltp->own = ap->shp_own;
|
||||
fltp->maxmoves = 500;
|
||||
}
|
||||
|
||||
/* If the fleet is not in the same sector as us, no go. */
|
||||
if ( ( fltp->x!=sp->shp_x ) || ( fltp->y!=sp->shp_y ) ) {
|
||||
wu(0,sp->shp_own,
|
||||
"Ship %d not in same sector as its sailing fleet\n",
|
||||
sp->shp_uid);
|
||||
fltp->real_q = LEADER_WRONGSECT;
|
||||
return(0);
|
||||
}
|
||||
|
||||
this = (struct fltelemstr *) malloc(sizeof(*this));
|
||||
bzero((s_char *)this, sizeof(*this));
|
||||
this->num = sp->shp_uid;
|
||||
this->own = sp->shp_own;
|
||||
this->next = fltp->head;
|
||||
fltp->head = this;
|
||||
cost_ship(sp, this, fltp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
sail_nav_fleet(struct fltheadstr *fltp)
|
||||
{
|
||||
struct fltelemstr *fe;
|
||||
struct shpstr *sp, ship;
|
||||
int vec[I_MAX+1];
|
||||
struct sctstr *sectp;
|
||||
int error=0;
|
||||
s_char *s, *p;
|
||||
natid own;
|
||||
struct emp_qelem ship_list;
|
||||
int dir;
|
||||
|
||||
#ifdef SAILDEBUG
|
||||
switch (fltp->real_q) {
|
||||
case LEADER_VIRTUAL:
|
||||
s = "leaderless";
|
||||
break;
|
||||
case LEADER_REAL:
|
||||
s = "real";
|
||||
break;
|
||||
case LEADER_WRONGSECT:
|
||||
s = "scattered";
|
||||
break;
|
||||
default:
|
||||
s = "inconsistent";
|
||||
}
|
||||
wu(0,fltp->own,
|
||||
"Fleet lead by %d is %s, can go %d spaces\n contains ships:",
|
||||
fltp->leader, s, fltp->maxmoves);
|
||||
for (fe=fltp->head; fe; fe = fe->next)
|
||||
wu(0, fltp->own, " %d", fe->num);
|
||||
wu(0, fltp->own, "\n");
|
||||
#endif
|
||||
sectp = getsectp(fltp->x, fltp->y);
|
||||
switch (check_nav(sectp)) {
|
||||
case CN_NAVIGABLE:
|
||||
break;
|
||||
case CN_CONSTRUCTION:
|
||||
case CN_LANDLOCKED:
|
||||
default:
|
||||
wu(0,fltp->own, "Your fleet lead by %d is trapped by land.\n",
|
||||
fltp->leader);
|
||||
return(0);
|
||||
}
|
||||
for (fe=fltp->head; fe; fe = fe->next) {
|
||||
sp = getshipp(fe->num);
|
||||
getvec(VT_ITEM, vec, (s_char *)sp, EF_SHIP);
|
||||
if (vec[I_MILIT]==0 && vec[I_CIVIL]==0) {
|
||||
wu(0,fltp->own,
|
||||
" ship #%d (%s) is crewless and can't go on\n",
|
||||
fe->num, cname(fe->own));
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
if (error)
|
||||
return(0);
|
||||
sp = getshipp(fltp->leader);
|
||||
own = sp->shp_own;
|
||||
fltp_to_list(fltp, &ship_list); /* hack -KHS 1995 */
|
||||
for (s=sp->shp_path; (*s) && (fltp->maxmoves>0); s++) {
|
||||
dir = chkdir(*s, DIR_STOP, DIR_LAST);
|
||||
if (0 != (error = shp_nav_one_sector(&ship_list, dir, own, 0)))
|
||||
fltp->maxmoves = 1;
|
||||
--(fltp->maxmoves);
|
||||
}
|
||||
shp_put(&ship_list, own);
|
||||
getship(sp->shp_uid, &ship);
|
||||
fltp->x = ship.shp_x;
|
||||
fltp->y = ship.shp_y;
|
||||
for (p=&ship.shp_path[0]; *s; p++,s++)
|
||||
*p = *s;
|
||||
*p = 0;
|
||||
putship(ship.shp_uid, &ship);
|
||||
#ifdef SAILDEBUG
|
||||
if (sp->shp_path[0]) {
|
||||
wu(0,fltp->own,
|
||||
"Fleet lead by #%d nav'd to %s, path left = %s\n",
|
||||
fltp->leader, xyas(fltp->x,fltp->y,fltp->own),
|
||||
&sp->shp_path);
|
||||
} else
|
||||
wu(0,fltp->own,
|
||||
"Fleet lead by #%d nav'd to %s, finished.\n",
|
||||
fltp->leader, xyas(fltp->x,fltp->y,fltp->own));
|
||||
wu(0,sp->shp_own, "Ship #%d has %d mobility now.\n",
|
||||
fe->num, (int)fe->mobil);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
sail_ship(natid cn)
|
||||
{
|
||||
struct shpstr *sp;
|
||||
struct fltheadstr *head=0;
|
||||
struct fltheadstr *fltp;
|
||||
int n;
|
||||
|
||||
|
||||
for (n=0; NULL != (sp = getshipp(n)); n++) if (sp->shp_own==cn) {
|
||||
sail_find_fleet(&head, sp);
|
||||
}
|
||||
|
||||
/* see what the fleets fall out into */
|
||||
for (fltp=head; fltp; fltp = fltp->next) {
|
||||
sail_nav_fleet(fltp);
|
||||
wu(0,fltp->own, "Your fleet lead by ship #%d has reached %s.\n",
|
||||
fltp->leader,xyas(fltp->x,fltp->y,fltp->own));
|
||||
}
|
||||
|
||||
/* Free up the memory, 'cause I want to. */
|
||||
for (fltp=head; fltp!=0; ) {
|
||||
struct fltelemstr *fe;
|
||||
struct fltheadstr *saveh;
|
||||
saveh = fltp->next;
|
||||
for (fe=fltp->head; fe!=0; ) {
|
||||
struct fltelemstr *saveel;
|
||||
saveel = fe->next;
|
||||
free(fe);
|
||||
fe = saveel;
|
||||
}
|
||||
free(fltp);
|
||||
fltp = saveh;
|
||||
}
|
||||
}
|
||||
|
||||
/* The following is a total hack by Ken Stevens to cut down dramatically on repeated code 1995 */
|
||||
|
||||
void
|
||||
fltp_to_list(struct fltheadstr *fltp, struct emp_qelem *list)
|
||||
{
|
||||
struct fltelemstr *fe;
|
||||
struct mlist *mlp;
|
||||
struct shpstr *sp;
|
||||
|
||||
emp_initque(list);
|
||||
for (fe=fltp->head; fe; fe = fe->next) {
|
||||
mlp = (struct mlist *) malloc(sizeof(struct mlist));
|
||||
sp = getshipp(fe->num);
|
||||
mlp->mcp = mchr + sp->shp_type;
|
||||
bcopy((s_char *)sp, (s_char *)&mlp->ship,
|
||||
sizeof(struct shpstr));
|
||||
mlp->mobil = fe->mobil;
|
||||
emp_insque(&mlp->queue, list);
|
||||
}
|
||||
}
|
510
src/lib/update/sect.c
Normal file
510
src/lib/update/sect.c
Normal file
|
@ -0,0 +1,510 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* sect.c: Do production for sectors
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Steve McClure, 1996
|
||||
*/
|
||||
|
||||
#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 "path.h"
|
||||
#include "product.h"
|
||||
#include "distribute.h"
|
||||
#include "optlist.h"
|
||||
#include "budg.h"
|
||||
#include "player.h"
|
||||
#include "land.h"
|
||||
#include "ship.h"
|
||||
#include "update.h"
|
||||
#include "subs.h"
|
||||
#include "common.h"
|
||||
#include "lost.h"
|
||||
#include "gen.h"
|
||||
|
||||
extern float levels[MAXNOC][4];
|
||||
|
||||
int
|
||||
dodeliver(struct sctstr *sp, int *vec)
|
||||
{
|
||||
register int i;
|
||||
int del[I_MAX+1];
|
||||
int thresh;
|
||||
int dir;
|
||||
int plague;
|
||||
int n;
|
||||
int changed;
|
||||
|
||||
if (sp->sct_mobil <= 0)
|
||||
return 0;
|
||||
if (getvec(VT_DEL, del, (s_char *)sp, EF_SECTOR) <= 0)
|
||||
return 0;
|
||||
changed = 0;
|
||||
plague = getvar(V_PSTAGE, (s_char *)sp, EF_SECTOR);
|
||||
for (i=1; i<=I_MAX; i++) {
|
||||
if (del[i] == 0)
|
||||
continue;
|
||||
thresh = del[i] & ~0x7;
|
||||
dir = del[i] & 0x7;
|
||||
n = deliver(sp, &ichr[i], dir, thresh, vec[i], plague);
|
||||
if (n > 0) {
|
||||
vec[i] -= n;
|
||||
changed++;
|
||||
if (sp->sct_mobil <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase sector efficiency if old type == new type.
|
||||
* decrease sector efficiency if old type != new type.
|
||||
* Return amount of work used.
|
||||
*/
|
||||
int
|
||||
upd_buildeff(struct natstr *np, register struct sctstr *sp, int *workp, int *vec, int etu, int *desig, int sctwork, int *cost)
|
||||
{
|
||||
register int work_cost = 0;
|
||||
int buildeff_work = (int)(*workp / 2);
|
||||
int n, hcms, lcms, neweff;
|
||||
u_char old_type = *desig;
|
||||
|
||||
*cost = 0;
|
||||
neweff = sp->sct_effic;
|
||||
|
||||
if (*desig != sp->sct_newtype) {
|
||||
/*
|
||||
* Tear down existing sector.
|
||||
* Easier to destroy than to build.
|
||||
*/
|
||||
work_cost = (sp->sct_effic + 3) / 4;
|
||||
if (work_cost > buildeff_work)
|
||||
work_cost = buildeff_work;
|
||||
buildeff_work -= work_cost;
|
||||
n = sp->sct_effic - work_cost * 4;
|
||||
if (n <= 0) {
|
||||
n = 0;
|
||||
*desig = sp->sct_newtype;
|
||||
}
|
||||
neweff = n;
|
||||
*cost += work_cost;
|
||||
if (opt_BIG_CITY) {
|
||||
if (!n && dchr[old_type].d_pkg == UPKG &&
|
||||
dchr[*desig].d_pkg != UPKG) {
|
||||
int maxpop = max_pop(np->nat_level[NAT_RLEV], sp);
|
||||
if (vec[I_CIVIL] > maxpop)
|
||||
vec[I_CIVIL] = maxpop;
|
||||
if (vec[I_UW] > maxpop)
|
||||
vec[I_UW] = maxpop;
|
||||
*workp = (vec[I_CIVIL] * sctwork) / 100.0
|
||||
+(vec[I_MILIT] * 2 / 5.0) + vec[I_UW];
|
||||
*workp = roundavg((etu * (*workp)) / 100.0);
|
||||
|
||||
buildeff_work = min((int)(*workp / 2), buildeff_work);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (np->nat_priorities[*desig]) {
|
||||
if (*desig == sp->sct_newtype) {
|
||||
work_cost = 100 - neweff;
|
||||
if (work_cost > buildeff_work)
|
||||
work_cost = buildeff_work;
|
||||
|
||||
if (dchr[*desig].d_lcms>0){
|
||||
lcms = vec[I_LCM];
|
||||
lcms /= dchr[*desig].d_lcms;
|
||||
if (work_cost > lcms)
|
||||
work_cost = lcms;
|
||||
}
|
||||
if (dchr[*desig].d_hcms>0){
|
||||
hcms = vec[I_HCM];
|
||||
hcms /= dchr[*desig].d_hcms;
|
||||
if (work_cost > hcms)
|
||||
work_cost = hcms;
|
||||
}
|
||||
|
||||
neweff += work_cost;
|
||||
*cost += work_cost*dchr[*desig].d_build;
|
||||
buildeff_work -= work_cost;
|
||||
|
||||
if ((dchr[*desig].d_lcms>0) ||
|
||||
(dchr[*desig].d_hcms>0)){
|
||||
vec[I_LCM] -= work_cost *
|
||||
dchr[*desig].d_lcms;
|
||||
vec[I_HCM] -= work_cost *
|
||||
dchr[*desig].d_hcms;
|
||||
}
|
||||
}
|
||||
}
|
||||
*workp = *workp/2 + buildeff_work;
|
||||
|
||||
return neweff;
|
||||
}
|
||||
|
||||
/*
|
||||
* enlistment sectors are special; they require military
|
||||
* to convert civ into mil in large numbers.
|
||||
* Conversion will happen much more slowly without
|
||||
* some mil initially.
|
||||
*/
|
||||
int
|
||||
enlist(register int *vec, int etu, int *cost)
|
||||
{
|
||||
int maxmil;
|
||||
int enlisted;
|
||||
|
||||
/* Need to check treaties here */
|
||||
enlisted = 0;
|
||||
maxmil = (vec[I_CIVIL] / 2) - vec[I_MILIT];
|
||||
if (maxmil > 0) {
|
||||
enlisted = (etu * (10 + vec[I_MILIT]) * 0.05);
|
||||
if (enlisted > maxmil)
|
||||
enlisted = maxmil;
|
||||
vec[I_CIVIL] -= enlisted;
|
||||
vec[I_MILIT] += enlisted;
|
||||
}
|
||||
*cost = enlisted * 3;
|
||||
return enlisted;
|
||||
}
|
||||
|
||||
/* Fallout is calculated here. */
|
||||
|
||||
extern int melt_item_denom[];
|
||||
|
||||
void
|
||||
meltitems(int etus, int fallout, int own, int *vec, int type, int x, int y, int uid)
|
||||
{
|
||||
int n;
|
||||
int melt;
|
||||
|
||||
for (n = 1; n <= I_MAX; n++) {
|
||||
melt = roundavg(vec[n] * etus * (long)fallout /
|
||||
(1000.0 * melt_item_denom[n]));
|
||||
if (melt > 5 && own) {
|
||||
if (type == EF_SECTOR)
|
||||
wu(0, own, "Lost %d %s to radiation in %s.\n",
|
||||
(melt < vec[n] ? melt : vec[n]), ichr[n].i_name,
|
||||
xyas(x, y, own));
|
||||
else if (type == EF_LAND)
|
||||
wu(0, own, "Unit #%d lost %d %s to radiation in %s.\n",
|
||||
uid, (melt < vec[n] ? melt : vec[n]), ichr[n].i_name,
|
||||
xyas(x, y, own));
|
||||
else if (type == EF_SHIP)
|
||||
wu(0, own, "Ship #%d lost %d %s to radiation in %s.\n",
|
||||
uid, (melt < vec[n] ? melt : vec[n]), ichr[n].i_name,
|
||||
xyas(x, y, own));
|
||||
}
|
||||
if (melt < vec[n])
|
||||
vec[n] -= melt;
|
||||
else
|
||||
vec[n] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* do_fallout - calculate fallout for sectors.
|
||||
*
|
||||
* This is etu based. But, do limit HUGE kill offs in large ETU
|
||||
* games, the melting etus rate is limited to 24 etus.
|
||||
*/
|
||||
|
||||
void
|
||||
do_fallout(register struct sctstr *sp, register int etus)
|
||||
{
|
||||
int vec[I_MAX+1];
|
||||
int cvec[I_MAX+1];
|
||||
int tvec[I_MAX+1];
|
||||
struct shpstr *spp;
|
||||
struct lndstr *lp;
|
||||
int i;
|
||||
|
||||
getvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
|
||||
getvec(VT_COND, cvec, (s_char *)sp, EF_SECTOR);
|
||||
/* This check shouldn't be needed, but just in case. :) */
|
||||
if (!cvec[C_FALLOUT] || !sp->sct_updated)
|
||||
return;
|
||||
if (etus > 24)
|
||||
etus = 24;
|
||||
#if 0
|
||||
wu(0,0,"Running fallout in %d,%d\n", sp->sct_x, sp->sct_y);
|
||||
#endif
|
||||
meltitems(etus, cvec[C_FALLOUT], sp->sct_own, vec, EF_SECTOR,
|
||||
sp->sct_x, sp->sct_y, 0);
|
||||
putvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
|
||||
for (i = 0; NULL != (lp = getlandp(i)); i++) {
|
||||
if (!lp->lnd_own)
|
||||
continue;
|
||||
if (lp->lnd_x != sp->sct_x || lp->lnd_y != sp->sct_y)
|
||||
continue;
|
||||
getvec(VT_ITEM, tvec, (s_char *)lp, EF_LAND);
|
||||
meltitems(etus, cvec[C_FALLOUT], lp->lnd_own, tvec, EF_LAND,
|
||||
lp->lnd_x, lp->lnd_y, lp->lnd_uid);
|
||||
putvec(VT_ITEM, tvec, (s_char *)lp, EF_LAND);
|
||||
}
|
||||
for (i = 0; NULL != (spp = getshipp(i)); i++) {
|
||||
if (!spp->shp_own)
|
||||
continue;
|
||||
if (spp->shp_x != sp->sct_x || spp->shp_y != sp->sct_y)
|
||||
continue;
|
||||
if (mchr[(int)spp->shp_type].m_flags & M_SUB)
|
||||
continue;
|
||||
getvec(VT_ITEM, tvec, (s_char *)spp, EF_SHIP);
|
||||
meltitems(etus, cvec[C_FALLOUT], spp->shp_own, tvec, EF_SHIP,
|
||||
spp->shp_x, spp->shp_y, spp->shp_uid);
|
||||
putvec(VT_ITEM, tvec, (s_char *)spp, EF_SHIP);
|
||||
}
|
||||
#ifdef GODZILLA
|
||||
if ((cvec[C_FALLOUT] > 20) && chance(100))
|
||||
do_godzilla(sp);
|
||||
#endif /* GODZILLA */
|
||||
}
|
||||
|
||||
void
|
||||
spread_fallout(struct sctstr *sp, int etus)
|
||||
{
|
||||
extern double fallout_spread;
|
||||
struct sctstr *ap;
|
||||
int tvec[I_MAX+1];
|
||||
int cvec[I_MAX+1];
|
||||
int n;
|
||||
register int inc;
|
||||
|
||||
if (etus > 24)
|
||||
etus = 24;
|
||||
getvec(VT_COND, cvec, (s_char *)sp, EF_SECTOR);
|
||||
for (n = DIR_FIRST; n <= DIR_LAST; n++) {
|
||||
ap = getsectp(sp->sct_x+diroff[n][0], sp->sct_y+diroff[n][1]);
|
||||
getvec(VT_COND, tvec, (char *)ap, EF_SECTOR);
|
||||
if (ap->sct_type == SCT_SANCT)
|
||||
continue;
|
||||
inc = roundavg(etus * fallout_spread * (cvec[C_FALLOUT])) - 1;
|
||||
#if 0
|
||||
if (cvec[C_FALLOUT]) {
|
||||
wu(0,0,"Fallout from sector %d,%d to %d,%d is %d=%d*%e*%d\n",
|
||||
sp->sct_x,sp->sct_y,sp->sct_x+diroff[n][0],
|
||||
sp->sct_y+diroff[n][1], inc, etus,
|
||||
fallout_spread, cvec[C_FALLOUT]);
|
||||
}
|
||||
#endif
|
||||
if (inc < 0)
|
||||
inc = 0;
|
||||
tvec[C_FALLOUT] += inc;
|
||||
putvec(VT_COND, tvec, (char *)ap, EF_SECTOR);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
decay_fallout(struct sctstr *sp, int etus)
|
||||
{
|
||||
extern double decay_per_etu;
|
||||
extern double fallout_spread;
|
||||
int cvec[I_MAX+1];
|
||||
int decay;
|
||||
|
||||
if (etus > 24)
|
||||
etus = 24;
|
||||
getvec(VT_COND, cvec, (char *)sp, EF_SECTOR);
|
||||
decay = roundavg(((decay_per_etu + 6.0) * fallout_spread) *
|
||||
(double)etus * (double)cvec[C_FALLOUT]);
|
||||
|
||||
#if 0
|
||||
if (decay || cvec[C_FALLOUT])
|
||||
wu(0,0,"Fallout decay in %d,%d is %d from %d\n", sp->sct_x, sp->sct_y, decay, cvec[C_FALLOUT]);
|
||||
#endif
|
||||
|
||||
cvec[C_FALLOUT] = (decay < cvec[C_FALLOUT]) ? (cvec[C_FALLOUT] - decay) : 0;
|
||||
if (cvec[C_FALLOUT] < 0)
|
||||
cvec[C_FALLOUT] = 0;
|
||||
putvec(VT_COND, cvec, (s_char *)sp, EF_SECTOR);
|
||||
}
|
||||
|
||||
#define SHOULD_PRODUCE(sp,t) (((sp->sct_type == t) || (t == -1)) ? 1 : 0)
|
||||
|
||||
/*
|
||||
* Produce only a set sector type for a specific nation
|
||||
* (or all, if sector_type == -1)
|
||||
*
|
||||
*/
|
||||
void
|
||||
produce_sect(int natnum, int etu, int *bp, long int (*p_sect)[2], int sector_type)
|
||||
{
|
||||
register struct sctstr *sp;
|
||||
register struct natstr *np;
|
||||
int vec[I_MAX+1];
|
||||
int work, cost, ecost, pcost, sctwork;
|
||||
int n, desig, maxpop, neweff, amount;
|
||||
|
||||
for (n=0; NULL != (sp = getsectid(n)); n++) {
|
||||
if (sp->sct_type == SCT_WATER)
|
||||
continue;
|
||||
if (sp->sct_own != natnum)
|
||||
continue;
|
||||
if (sp->sct_updated != 0)
|
||||
continue;
|
||||
if (!SHOULD_PRODUCE(sp,sector_type))
|
||||
continue;
|
||||
|
||||
if ((sp->sct_type == SCT_CAPIT) && (sp->sct_effic > 60)) {
|
||||
p_sect[SCT_CAPIT][0]++;
|
||||
p_sect[SCT_CAPIT][1] += etu;
|
||||
}
|
||||
|
||||
if (getvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR) <= 0)
|
||||
continue;
|
||||
/* If everybody is dead, the sector reverts to unowned.
|
||||
* This is also checked at the end of the production in
|
||||
* they all starved or were plagued off.
|
||||
*/
|
||||
if (vec[I_CIVIL] == 0 && vec[I_MILIT] == 0 &&
|
||||
!has_units(sp->sct_x,sp->sct_y,sp->sct_own,0)) {
|
||||
makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y);
|
||||
sp->sct_own = 0;
|
||||
sp->sct_oldown = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
sp->sct_updated = 1;
|
||||
work = 0;
|
||||
|
||||
np = getnatp(natnum);
|
||||
|
||||
/* do_feed trys to supply. So, we need to enable cacheing
|
||||
here */
|
||||
bp_enable_cachepath();
|
||||
|
||||
sctwork = do_feed(sp, np, vec, &work, bp, etu);
|
||||
|
||||
bp_disable_cachepath();
|
||||
bp_clear_cachepath();
|
||||
|
||||
if (sp->sct_off || np->nat_money < 0) {
|
||||
if (!player->simulation) {
|
||||
putvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
|
||||
sp->sct_off = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ((np->nat_priorities[sp->sct_type] == 0) &&
|
||||
(sp->sct_type == sp->sct_newtype) &&
|
||||
((pchr[dchr[sp->sct_type].d_prd].p_cost != 0) ||
|
||||
(sp->sct_type == SCT_ENLIST))){
|
||||
if (!player->simulation) {
|
||||
putvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
|
||||
logerror("Skipping %s production for country %s\n",
|
||||
dchr[sp->sct_type].d_name,np->nat_cnam);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
neweff = sp->sct_effic;
|
||||
amount = 0;
|
||||
pcost = cost = ecost = 0;
|
||||
|
||||
desig = sp->sct_type;
|
||||
|
||||
if ((sp->sct_effic < 100 || sp->sct_type != sp->sct_newtype) &&
|
||||
np->nat_money > 0) {
|
||||
neweff = upd_buildeff(np, sp, &work, vec, etu, &desig, sctwork, &cost);
|
||||
pt_bg_nmbr(bp, sp, I_LCM, vec[I_LCM]);
|
||||
pt_bg_nmbr(bp, sp, I_HCM, vec[I_HCM]);
|
||||
p_sect[SCT_EFFIC][0]++;
|
||||
p_sect[SCT_EFFIC][1] += cost;
|
||||
if (!player->simulation) {
|
||||
np->nat_money -= cost;
|
||||
/* No longer tear down infrastructure
|
||||
if (sp->sct_type != desig) {
|
||||
sp->sct_road = 0;
|
||||
sp->sct_defense = 0;
|
||||
} else if (neweff < sp->sct_effic) {
|
||||
sp->sct_road -= (sp->sct_road * (sp->sct_effic - neweff) / 100.0);
|
||||
sp->sct_defense -= (sp->sct_defense * (sp->sct_effic - neweff) / 100.0);
|
||||
if (sp->sct_road < 0)
|
||||
sp->sct_road = 0;
|
||||
if (sp->sct_defense < 0)
|
||||
sp->sct_defense = 0;
|
||||
}
|
||||
*/
|
||||
sp->sct_type = desig;
|
||||
sp->sct_effic = neweff;
|
||||
if (!opt_DEFENSE_INFRA)
|
||||
sp->sct_defense = sp->sct_effic;
|
||||
}
|
||||
}
|
||||
|
||||
if ((np->nat_priorities[desig] == 0) &&
|
||||
((pchr[dchr[desig].d_prd].p_cost != 0) ||
|
||||
(desig == SCT_ENLIST))) {
|
||||
if (!player->simulation) {
|
||||
putvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
|
||||
logerror("Skipping %s production for country %s\n",
|
||||
dchr[sp->sct_type].d_name,np->nat_cnam);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (desig == SCT_ENLIST && neweff >= 60 &&
|
||||
sp->sct_own == sp->sct_oldown) {
|
||||
p_sect[desig][0] += enlist(vec, etu, &ecost);
|
||||
p_sect[desig][1] += ecost;
|
||||
if (!player->simulation)
|
||||
np->nat_money -= ecost;
|
||||
}
|
||||
|
||||
/*
|
||||
* now do the production (if sector effic >= 60%)
|
||||
*/
|
||||
|
||||
if (neweff >= 60) {
|
||||
if (np->nat_money > 0 && dchr[desig].d_prd)
|
||||
work -= produce(np, sp, vec, work, sctwork, desig, neweff, &pcost, &amount);
|
||||
}
|
||||
|
||||
pt_bg_nmbr(bp, sp, I_MAX+1, work);
|
||||
p_sect[desig][0] += amount;
|
||||
p_sect[desig][1] += pcost;
|
||||
if (!player->simulation) {
|
||||
maxpop = max_pop(np->nat_level[NAT_RLEV], sp);
|
||||
if (vec[I_CIVIL] > maxpop)
|
||||
vec[I_CIVIL] = maxpop;
|
||||
if (vec[I_UW] > maxpop)
|
||||
vec[I_UW] = maxpop;
|
||||
putvec(VT_ITEM, vec, (s_char *)sp, EF_SECTOR);
|
||||
sp->sct_avail = work;
|
||||
np->nat_money -= pcost;
|
||||
}
|
||||
}
|
||||
}
|
529
src/lib/update/ship.c
Normal file
529
src/lib/update/ship.c
Normal file
|
@ -0,0 +1,529 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* ship.c: Do production for ships
|
||||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Steve McClure, 1996
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "var.h"
|
||||
#include "sect.h"
|
||||
#include "nat.h"
|
||||
#include "ship.h"
|
||||
#include "var.h"
|
||||
#include "news.h"
|
||||
#include "file.h"
|
||||
#include "product.h"
|
||||
#include "land.h"
|
||||
#include "xy.h"
|
||||
#include "nsc.h"
|
||||
#include "optlist.h"
|
||||
#include "player.h"
|
||||
#include "update.h"
|
||||
#include "common.h"
|
||||
#include "subs.h"
|
||||
#include "gen.h"
|
||||
#include "lost.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x) > (y) ? (y) : (x))
|
||||
#endif
|
||||
|
||||
int
|
||||
prod_ship(int etus, int natnum, int *bp, int build)
|
||||
/* build = 1, maintain = 0 */
|
||||
{
|
||||
register struct shpstr *sp;
|
||||
struct natstr *np;
|
||||
int n, k=0;
|
||||
extern long sea_money[MAXNOC];
|
||||
int start_money;
|
||||
int lastx = 9999, lasty = 9999;
|
||||
|
||||
bp_enable_cachepath();
|
||||
for (n=0; NULL != (sp = getshipp(n)); n++) {
|
||||
if (sp->shp_own == 0)
|
||||
continue;
|
||||
if (sp->shp_own != natnum)
|
||||
continue;
|
||||
np = getnatp(sp->shp_own);
|
||||
start_money = np->nat_money;
|
||||
if (lastx == 9999 || lasty == 9999) {
|
||||
lastx = sp->shp_x;
|
||||
lasty = sp->shp_y;
|
||||
}
|
||||
if (lastx != sp->shp_x || lasty != sp->shp_y) {
|
||||
/* Reset the cache */
|
||||
bp_disable_cachepath();
|
||||
bp_clear_cachepath();
|
||||
bp_enable_cachepath();
|
||||
}
|
||||
upd_ship(sp, n, etus, np, bp, build);
|
||||
if (build && !player->simulation) /* make sure to only autonav once */
|
||||
nav_ship(sp); /* autonav the ship */
|
||||
sea_money[sp->shp_own] += np->nat_money - start_money;
|
||||
if ((build && (np->nat_money != start_money)) || (!build))
|
||||
k++;
|
||||
if (player->simulation)
|
||||
np->nat_money = start_money;
|
||||
}
|
||||
bp_disable_cachepath();
|
||||
bp_clear_cachepath();
|
||||
|
||||
if (opt_SAIL) {
|
||||
if (build && !player->simulation) /* make sure to only sail once */
|
||||
sail_ship(natnum);
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
void
|
||||
upd_ship(register struct shpstr *sp, int shipno, register int etus, struct natstr *np, int *bp, int build)
|
||||
/* build = 1, maintain = 0 */
|
||||
{
|
||||
extern long pops[];
|
||||
struct sctstr *sectp;
|
||||
struct mchrstr *mp;
|
||||
int vec[I_MAX+1];
|
||||
int cvec[I_MAX+1];
|
||||
int oil_gained;
|
||||
int max_oil;
|
||||
int max_food;
|
||||
struct pchrstr *product;
|
||||
s_char *resource;
|
||||
int n;
|
||||
int mult;
|
||||
extern double money_ship;
|
||||
int needed;
|
||||
int cost;
|
||||
int eff;
|
||||
|
||||
mp = &mchr[(int)sp->shp_type];
|
||||
getvec(VT_ITEM, vec, (s_char *)sp, EF_SHIP);
|
||||
if (build == 1){
|
||||
if (np->nat_priorities[PRI_SBUILD] == 0 ||
|
||||
np->nat_money < 0)
|
||||
return;
|
||||
if (sp->shp_effic < SHIP_MINEFF ||
|
||||
!shiprepair(sp, vec, np, bp, etus)) {
|
||||
makelost(EF_SHIP, sp->shp_own, sp->shp_uid, sp->shp_x, sp->shp_y);
|
||||
sp->shp_own = 0;
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
mult = 1;
|
||||
if (np->nat_level[NAT_TLEV] < sp->shp_tech * 0.85)
|
||||
mult = 2;
|
||||
cost = -(mult * etus * dmin(0.0, money_ship * mp->m_cost));
|
||||
if ((np->nat_priorities[PRI_SMAINT] == 0 ||
|
||||
np->nat_money < cost) && !player->simulation){
|
||||
if ((eff = sp->shp_effic - etus/5) < SHIP_MINEFF) {
|
||||
wu(0, sp->shp_own,
|
||||
"%s lost to lack of maintenance\n",
|
||||
prship(sp));
|
||||
makelost(EF_SHIP, sp->shp_own, sp->shp_uid, sp->shp_x, sp->shp_y);
|
||||
sp->shp_own = 0;
|
||||
return;
|
||||
}
|
||||
wu(0, sp->shp_own,
|
||||
"%s lost %d%% to lack of maintenance\n",
|
||||
prship(sp), sp->shp_effic - eff);
|
||||
sp->shp_effic = eff;
|
||||
} else {
|
||||
np->nat_money -= cost;
|
||||
}
|
||||
|
||||
sectp = getsectp(sp->shp_x, sp->shp_y);
|
||||
if (((mp->m_flags & M_OIL) && (sectp->sct_type == SCT_WATER))
|
||||
&& !player->simulation){
|
||||
/*
|
||||
* take care of oil production
|
||||
*/
|
||||
oil_gained = roundavg((vec[I_CIVIL] * etus / 10000.0)
|
||||
* sectp->sct_oil);
|
||||
vec[I_OIL] += oil_gained;
|
||||
max_oil = vl_find(V_OIL,mp->m_vtype,mp->m_vamt,mp->m_nv);
|
||||
if (vec[I_OIL] > max_oil)
|
||||
vec[I_OIL] = max_oil;
|
||||
product = &pchr[P_OIL];
|
||||
if (product->p_nrdep != 0 && oil_gained > 0) {
|
||||
resource = ((s_char *)sectp) + product->p_nrndx;
|
||||
*resource -= roundavg(oil_gained *
|
||||
product->p_nrdep / 100.0);
|
||||
}
|
||||
} else if (((mp->m_flags&M_FOOD)&&(sectp->sct_type==SCT_WATER)) && !player->simulation){
|
||||
sectp = getsectp(sp->shp_x, sp->shp_y);
|
||||
vec[I_FOOD] += ((vec[I_CIVIL] * etus) / 1000.0)
|
||||
* sectp->sct_fertil;
|
||||
}
|
||||
/* Military costs are now part of regular military costs, not ship costs */
|
||||
/* np->nat_money += (int) (etus * vec[I_MILIT] * money_mil);*/
|
||||
if (!player->simulation){
|
||||
if ((n = feed_ship(sp,vec,etus, &needed, 1)) > 0) {
|
||||
wu(0, sp->shp_own, "%d starved on %s\n",
|
||||
n, prship(sp));
|
||||
if (n > 10)
|
||||
nreport(sp->shp_own, N_DIE_FAMINE, 0, 1);
|
||||
}
|
||||
max_food = vl_find(V_FOOD, mp->m_vtype, mp->m_vamt, mp->m_nv);
|
||||
if (vec[I_FOOD] > max_food)
|
||||
vec[I_FOOD] = max_food;
|
||||
/*
|
||||
* do plague stuff. plague can't break out on ships,
|
||||
* but it can still kill people.
|
||||
*/
|
||||
getvec(VT_COND, cvec, (s_char *)sp, EF_SHIP);
|
||||
if (cvec[C_PSTAGE] > 0) {
|
||||
n = plague_people(np, vec, cvec, etus);
|
||||
switch (n) {
|
||||
case PLG_DYING:
|
||||
wu(0, sp->shp_own,
|
||||
"PLAGUE deaths reported on %s\n",
|
||||
prship(sp));
|
||||
nreport(sp->shp_own, N_DIE_PLAGUE, 0, 1);
|
||||
break;
|
||||
case PLG_INFECT:
|
||||
wu(0, sp->shp_own, "%s battling PLAGUE\n",
|
||||
prship(sp));
|
||||
break;
|
||||
case PLG_INCUBATE:
|
||||
/* Are we still incubating? */
|
||||
if (n == cvec[C_PSTAGE]) {
|
||||
/* Yes. Will it turn "infectious" next time? */
|
||||
if (cvec[C_PTIME] <= etus) {
|
||||
/* Yes. Report an outbreak. */
|
||||
wu(0, sp->shp_own,
|
||||
"Outbreak of PLAGUE on %s!\n",
|
||||
prship(sp));
|
||||
nreport(sp->shp_own, N_OUT_PLAGUE, 0, 1);
|
||||
}
|
||||
} else {
|
||||
/* It has already moved on to "infectious" */
|
||||
wu(0, sp->shp_own,
|
||||
"%s battling PLAGUE\n", prship(sp));
|
||||
}
|
||||
break;
|
||||
case PLG_EXPOSED:
|
||||
/* Has the plague moved to "incubation" yet? */
|
||||
if (n != cvec[C_PSTAGE]) {
|
||||
/* Yes. Will it turn "infectious" next time? */
|
||||
if (cvec[C_PTIME] <= etus) {
|
||||
/* Yes. Report an outbreak. */
|
||||
wu(0, sp->shp_own,
|
||||
"Outbreak of PLAGUE on %s!\n",
|
||||
prship(sp));
|
||||
nreport(sp->shp_own, N_OUT_PLAGUE, 0, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
putvec(VT_COND, cvec, (s_char *)sp, EF_SHIP);
|
||||
}
|
||||
putvec(VT_ITEM, vec, (s_char *)sp, EF_SHIP);
|
||||
pops[sp->shp_own] += vec[I_CIVIL];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* idea is: a sector full of workers can fix up eight
|
||||
* battleships +8 % eff each etu. This will cost around
|
||||
* 8 * 8 * $40 = $2560!
|
||||
*/
|
||||
int
|
||||
shiprepair(register struct shpstr *ship, int *vec, struct natstr *np, int *bp, int etus)
|
||||
{
|
||||
extern int ship_grow_scale;
|
||||
register int delta;
|
||||
struct sctstr *sp;
|
||||
struct mchrstr *mp;
|
||||
float leftp, buildp;
|
||||
int left, build;
|
||||
int lcm_needed, hcm_needed;
|
||||
int wf;
|
||||
int avail;
|
||||
int w_p_eff;
|
||||
int mult;
|
||||
int svec[I_MAX+1];
|
||||
int mvec[I_MAX+1];
|
||||
int rel;
|
||||
|
||||
mp = &mchr[(int)ship->shp_type];
|
||||
sp = getsectp(ship->shp_x, ship->shp_y);
|
||||
|
||||
if ((sp->sct_own != ship->shp_own) && (sp->sct_own != 0)) {
|
||||
rel=getrel(getnatp(sp->sct_own),ship->shp_own);
|
||||
|
||||
if (rel < FRIENDLY)
|
||||
return 1;
|
||||
}
|
||||
|
||||
wf = 0;
|
||||
/* only military can work on a military boat */
|
||||
if (ship->shp_glim > 0)
|
||||
wf = etus * vec[I_MILIT]/2;
|
||||
else
|
||||
wf = etus * (vec[I_CIVIL]/2 + vec[I_MILIT]/5);
|
||||
|
||||
if (sp->sct_type != SCT_HARBR){
|
||||
wf /= 3;
|
||||
avail = wf;
|
||||
}else{
|
||||
if (!player->simulation)
|
||||
avail = wf + sp->sct_avail * 100;
|
||||
else
|
||||
avail = wf + gt_bg_nmbr(bp, sp, I_MAX+1) * 100;
|
||||
}
|
||||
|
||||
w_p_eff = 20 + (mp->m_lcm + 2 * mp->m_hcm);
|
||||
|
||||
if (sp->sct_type != SCT_HARBR){
|
||||
int abs_max, amt;
|
||||
|
||||
if (ship->shp_glim > 0){
|
||||
abs_max = vl_find(V_MILIT, mp->m_vtype,
|
||||
mp->m_vamt, (int) mp->m_nv);
|
||||
amt = vec[I_MILIT];
|
||||
}else{
|
||||
abs_max = vl_find(V_CIVIL, mp->m_vtype,
|
||||
mp->m_vamt, (int) mp->m_nv);
|
||||
amt = vec[I_CIVIL];
|
||||
if (abs_max==0) {
|
||||
abs_max = vl_find(V_MILIT, mp->m_vtype, mp->m_vamt,
|
||||
(int) mp->m_nv);
|
||||
amt = vec[I_MILIT];
|
||||
}
|
||||
}
|
||||
|
||||
if (abs_max == 0){
|
||||
logerror("Abs max of 0 for ship %d\n",ship->shp_uid);
|
||||
abs_max = 1;
|
||||
}
|
||||
avail -= (etus * (100-((amt*100)/abs_max)))/7;
|
||||
/* think of it as entropy in action */
|
||||
}
|
||||
|
||||
if (avail <= 0){
|
||||
if (!player->simulation) {
|
||||
if (opt_SHIP_DECAY) {
|
||||
ship->shp_effic += avail/w_p_eff;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((sp->sct_off) && (sp->sct_own == ship->shp_own))
|
||||
return 1;
|
||||
|
||||
getvec(VT_ITEM, svec, (s_char *)sp, EF_SECTOR);
|
||||
|
||||
mult = 1;
|
||||
if (np->nat_level[NAT_TLEV] < ship->shp_tech * 0.85)
|
||||
mult = 2;
|
||||
|
||||
if (ship->shp_effic == 100) {
|
||||
/* ship is ok; no repairs needed */
|
||||
return 1;
|
||||
}
|
||||
|
||||
left = 100 - ship->shp_effic;
|
||||
delta = roundavg((double)avail/w_p_eff);
|
||||
if (delta <= 0)
|
||||
return 1;
|
||||
if (delta > etus*ship_grow_scale)
|
||||
delta = etus*ship_grow_scale;
|
||||
if (delta > left)
|
||||
delta = left;
|
||||
|
||||
/* delta is the max amount we can grow */
|
||||
|
||||
left = 100 - ship->shp_effic;
|
||||
if (left > delta)
|
||||
left = delta;
|
||||
|
||||
leftp = ((float)left/100.0);
|
||||
bzero((s_char *)mvec, sizeof(mvec));
|
||||
mvec[I_LCM] = lcm_needed = ldround((double)(mp->m_lcm * leftp),1);
|
||||
mvec[I_HCM] = hcm_needed = ldround((double)(mp->m_hcm * leftp),1);
|
||||
|
||||
get_materials(sp, bp, mvec, 0);
|
||||
|
||||
if (mvec[I_LCM]>=lcm_needed)
|
||||
buildp=leftp;
|
||||
else
|
||||
buildp=((float)mvec[I_LCM]/(float)mp->m_lcm);
|
||||
if (mvec[I_HCM] < hcm_needed)
|
||||
buildp = MIN(buildp,((float)mvec[I_HCM]/(float)mp->m_hcm));
|
||||
|
||||
build=ldround((double)(buildp*100.0),1);
|
||||
bzero((s_char *)mvec, sizeof(mvec));
|
||||
mvec[I_LCM] = lcm_needed = roundavg((double)(mp->m_lcm * buildp));
|
||||
mvec[I_HCM] = hcm_needed = roundavg((double)(mp->m_hcm * buildp));
|
||||
|
||||
get_materials(sp, bp, mvec, 1);
|
||||
|
||||
if (sp->sct_type != SCT_HARBR)
|
||||
build = delta;
|
||||
wf -= build * w_p_eff;
|
||||
if (wf < 0) {
|
||||
/*
|
||||
* I didn't use roundavg here, because I want to penalize
|
||||
* the player with a large number of ships.
|
||||
*/
|
||||
if (!player->simulation)
|
||||
avail = (sp->sct_avail * 100 + wf) / 100;
|
||||
else
|
||||
avail = (gt_bg_nmbr(bp,sp,I_MAX+1) * 100 + wf) / 100;
|
||||
if (avail < 0)
|
||||
avail = 0;
|
||||
if (!player->simulation)
|
||||
sp->sct_avail = avail;
|
||||
else
|
||||
pt_bg_nmbr(bp, sp, I_MAX+1, avail);
|
||||
}
|
||||
if (sp->sct_type != SCT_HARBR)
|
||||
if ((build+ship->shp_effic)>80){
|
||||
build = 80 - ship->shp_effic;
|
||||
if (build < 0)
|
||||
build = 0;
|
||||
}
|
||||
|
||||
np->nat_money -= mult * mp->m_cost * build / 100.0;
|
||||
if (!player->simulation)
|
||||
ship->shp_effic += (s_char)build;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the number who starved, if any.
|
||||
*/
|
||||
int
|
||||
feed_ship(struct shpstr *sp, register int *vec, int etus, int *needed, int doit)
|
||||
{
|
||||
extern double eatrate;
|
||||
double food_eaten, land_eaten;
|
||||
double people_left;
|
||||
int ifood_eaten;
|
||||
int can_eat, need;
|
||||
int total_people;
|
||||
int to_starve;
|
||||
int starved, lvec[I_MAX+1];
|
||||
struct nstr_item ni;
|
||||
struct lndstr *lp;
|
||||
s_char *nxtitemp(struct nstr_item *np, int owner);
|
||||
|
||||
if (opt_NOFOOD) return 0; /* no food no work to do */
|
||||
|
||||
food_eaten = (etus * eatrate) * (vec[I_CIVIL]+vec[I_MILIT]+vec[I_UW]);
|
||||
ifood_eaten = (int)food_eaten;
|
||||
if ((food_eaten-ifood_eaten) > 0)
|
||||
ifood_eaten++;
|
||||
starved = 0;
|
||||
*needed = 0;
|
||||
if (!player->simulation &&
|
||||
food_eaten > vec[I_FOOD])
|
||||
vec[I_FOOD] += supply_commod(sp->shp_own,sp->shp_x,sp->shp_y,
|
||||
I_FOOD,(ifood_eaten-vec[I_FOOD]));
|
||||
|
||||
if (food_eaten > vec[I_FOOD]) {
|
||||
/* doit - only steal food from land units during the update */
|
||||
if (sp->shp_nland > 0 && doit) {
|
||||
snxtitem_all(&ni,EF_LAND);
|
||||
while((lp=(struct lndstr *)nxtitemp(&ni, 0)) &&
|
||||
(food_eaten > vec[I_FOOD])){
|
||||
if (lp->lnd_ship != sp->shp_uid)
|
||||
continue;
|
||||
need = ifood_eaten - vec[I_FOOD];
|
||||
getvec(VT_ITEM, lvec, (s_char *)lp, EF_LAND);
|
||||
land_eaten = (etus * eatrate) *
|
||||
(double)lnd_getmil(lp);
|
||||
if (lvec[I_FOOD]-need > land_eaten){
|
||||
vec[I_FOOD] += need;
|
||||
lvec[I_FOOD] -= need;
|
||||
}else if ((lvec[I_FOOD]-land_eaten) > 0){
|
||||
vec[I_FOOD]+= (lvec[I_FOOD]-land_eaten);
|
||||
lvec[I_FOOD]-=(lvec[I_FOOD]-land_eaten);
|
||||
}
|
||||
putvec(VT_ITEM, lvec, (s_char *)lp, EF_LAND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (food_eaten > vec[I_FOOD]){
|
||||
*needed = food_eaten - vec[I_FOOD];
|
||||
if (*needed < (food_eaten - vec[I_FOOD]))
|
||||
(*needed)++;
|
||||
if (opt_NEW_STARVE) {
|
||||
can_eat = (vec[I_FOOD] / (etus * eatrate));
|
||||
total_people = vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW];
|
||||
|
||||
/* only want to starve off at most 1/2 the populace. */
|
||||
if (can_eat < (total_people/2))
|
||||
can_eat = total_people/2;
|
||||
|
||||
to_starve = total_people - can_eat;
|
||||
while(to_starve && vec[I_UW]){
|
||||
to_starve--;
|
||||
starved++;
|
||||
vec[I_UW]--;
|
||||
}
|
||||
while(to_starve && vec[I_CIVIL]){
|
||||
to_starve--;
|
||||
starved++;
|
||||
vec[I_CIVIL]--;
|
||||
}
|
||||
while(to_starve && vec[I_MILIT]){
|
||||
to_starve--;
|
||||
starved++;
|
||||
vec[I_MILIT]--;
|
||||
}
|
||||
|
||||
vec[I_FOOD] = 0;
|
||||
}
|
||||
else { /* ! opt_NEW_STARVE */
|
||||
people_left = (vec[I_FOOD] + 0.01) / (food_eaten + 0.01);
|
||||
starved = vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW];
|
||||
/* only want to starve off at most 1/2 the populace. */
|
||||
if (people_left < 0.5)
|
||||
people_left = 0.5;
|
||||
vec[I_CIVIL] = (int) (vec[I_CIVIL] * people_left);
|
||||
vec[I_MILIT] = (int) (vec[I_MILIT] * people_left);
|
||||
vec[I_UW] = (int) (vec[I_UW] * people_left);
|
||||
starved -= vec[I_CIVIL] + vec[I_MILIT] + vec[I_UW];
|
||||
vec[I_FOOD] = 0;
|
||||
}
|
||||
} else {
|
||||
vec[I_FOOD] -= (int)food_eaten;
|
||||
}
|
||||
return starved;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue