New update scheduler:

(schedulefil): New.
(set_dirs, set_paths): Rename.  Initialize schedulfil.
(read_schedule): New.  Can read several updates, which will be used in
later changesets.
(update_time): Change to array.  Will be used in later changesets.
(update_schedule_anchor): New.
(update_init): Initialize it.
(update_get_schedule): New.
(update_init): Call it to initialize update_time[].
(update_sched): Rewrite.
(update_forced, update_wanted): Replace.
(update_reschedule): New.
(main): Call it on SIGHUP to reload the schedule.
(update_trigger, update_force, force, player_coms): Drop force's
capability to schedule updates in the future, because it's not worth
the trouble to implement again.  Deities can simply edit the schedule
file to schedule updates.  Remove update_force() and
update_trigger()'s parameter.
(upda): Update for new scheduler.  Take care to keep output the same
as far as possible, even though it's ugly, to avoid breaking clients.
(update_policy, adj_update, update_times, hourslop, blitz_time):
econfig keys removed.
(update_demand, UPD_DEMAND_NONE, UPD_DEMAND_SCHED, UPD_DEMAND_ASYNC)
(update_demandpolicy, UDP_NORMAL, UDP_TIMES, UDP_NORMAL, UDP_BLITZ)
(UDP_MAX, UDP_DEFAULT, UDDEM_TMCHECK, UDDEM_COMSET, UDDEM_DISABLE)
(UDDEM_MAX, UDDEM_DEFAULT): econfig key and values replaced.  Users
changed.  wantupd.h is now empty, remove.
(demand_check): External linkage.
(update_policy_check): Now pointless, remove.
(is_daytime_near, min_to_next_daytime, regular_update_time)
(scheduled_update_time, next_scheduled_time, updatetime)
(next_update_time, next_update_check_time): Unused, Remove.

(demand_check, demandupdatecheck): Move call of demand_update_time()
from demand_check(), which controls all demand updates, to
demandupdatecheck(), which controls only unscheduled ones.  Fixes
update command not to lie about the next scheduled demand update.

(demandupdatecheck): Check updates_disabled() so that zdone no longer
claims to trigger an update when it can't.
This commit is contained in:
Markus Armbruster 2007-07-11 22:27:29 +00:00
parent 15f8f48353
commit 71320ed67f
20 changed files with 487 additions and 448 deletions

View file

@ -49,12 +49,7 @@ force(void)
pr("Updates are disabled\n");
return RET_FAIL;
}
seconds = onearg(player->argp[1], "Time until update [in seconds]? ");
if (seconds < 0)
return RET_FAIL;
pr("Scheduling update in %d second(s)\n", seconds);
if (update_trigger(seconds) < 0)
if (update_trigger() < 0)
return RET_FAIL;
return RET_OK;
}

View file

@ -28,7 +28,7 @@
* upda.c: Give the time of the next update
*
* Known contributors to this file:
*
* Markus Armbruster, 2007
*/
#include <config.h>
@ -36,7 +36,6 @@
#include "commands.h"
#include "optlist.h"
#include "server.h"
#include "wantupd.h"
/*
* Tell what the update policy is, and when the next update
@ -47,7 +46,7 @@ upda(void)
{
FILE *fp;
struct mob_acc_globals timestamps;
time_t now, next, delta;
time_t now, next, stop;
if (opt_MOB_ACCESS) {
if ((fp = fopen(timestampfil, "rb")) == NULL)
@ -70,66 +69,41 @@ upda(void)
pr("UPDATES ARE DISABLED!\n");
(void)time(&now);
switch (update_policy) {
case UDP_NORMAL:
next_update_time(&now, &next, &delta);
next = update_time[0];
if (next) {
pr("\nUpdates occur at times specified by the ETU rates.\n\n");
pr("The next update is at %19.19s.\n", ctime(&next));
break;
case UDP_TIMES:
next_update_time(&now, &next, &delta);
pr("\nUpdates occur at scheduled times.\n\n");
pr("The next update is at %19.19s.\n", ctime(&next));
break;
case UDP_BLITZ:
next_update_time(&now, &next, &delta);
pr("\nBlitz Updates occur every %d minutes. \n\n", blitz_time);
pr("The next update is at %19.19s.\n", ctime(&next));
break;
case UDP_NOREG:
} else {
pr("There are no regularly scheduled updates.\n");
break;
default:
pr("Update policy is inconsistent.\n");
}
pr("The current time is %19.19s.\n\n", ctime(&now));
if (update_window) {
now = update_time - update_window;
next_update_time(&now, &next, &delta);
if (next && update_window) {
pr("The next update window starts at %19.19s.\n",
ctime(&next));
next += update_window;
pr("The next update window stops at %19.19s.\n", ctime(&next));
stop = next + update_window;
pr("The next update window stops at %19.19s.\n", ctime(&stop));
}
switch (update_demandpolicy) {
case UDDEM_TMCHECK:
next_update_check_time(&now, &next, &delta);
pr("Demand updates occur at update CHECK times.\n");
pr("The next update check is at %19.19s.\n",
ctime(&next));
break;
case UDDEM_COMSET:
pr("Demand updates occur right after the demand is set.\n");
break;
case UDDEM_DISABLE:
break;
switch (update_demand) {
case UPD_DEMAND_NONE:
default:
CANT_REACH();
pr("Update demand policy is inconsistent.\n");
}
if ((update_policy == UDP_TIMES) ||
(update_demandpolicy == UDDEM_TMCHECK)) {
if (*update_times != 0)
pr("The update schedule is: %s\n", update_times);
}
if (update_demandpolicy != UDDEM_DISABLE) {
if (*update_demandtimes != 0)
break;
case UPD_DEMAND_SCHED:
pr("Demand updates occur at update CHECK times.\n");
if (next) {
pr("The next update check is at %19.19s.\n",
ctime(&next));
}
pr("Demand updates require %d country(s) to want one.\n",
update_wantmin);
break;
case UPD_DEMAND_ASYNC:
pr("Demand updates occur right after the demand is set.\n");
if (*update_demandtimes != 0) {
pr("Demand updates are allowed during: %s\n",
update_demandtimes);
}
pr("Demand updates require %d country(s) to want one.\n",
update_wantmin);
}

View file

@ -54,7 +54,6 @@
#include "commands.h"
#include "optlist.h"
#include "server.h"
#include "wantupd.h"
int
zdon(void)
@ -70,7 +69,8 @@ zdon(void)
int dowant;
char buf[1024];
if (update_demandpolicy == UDDEM_DISABLE) {
if (update_demand != UPD_DEMAND_SCHED
&& update_demand != UPD_DEMAND_ASYNC) {
pr("Demand updates are not enabled.\n");
return RET_FAIL;
}
@ -136,7 +136,7 @@ zdon(void)
if (!checking && wantupd && demandupdatecheck()) {
pr("Here goes...\n");
update_trigger(0);
update_trigger();
}
return RET_OK;
}

View file

@ -101,50 +101,6 @@ gamehours(time_t t)
return is_daytime_allowed(60 * tm->tm_hour + tm->tm_min, game_hours);
}
/*
* Is day time DTIME (minutes since midnight) near a time in TIMES?
* TIMES is a list of day times. See daytime() for syntax.
* DTIME is near a listed time T if its within T and T + SLOP minutes.
*/
int
is_daytime_near(int dtime, char *times, int slop)
{
int dt;
if (times)
while (NULL != (times = daytime(times, &dt)))
if (dt <= dtime && dtime < dt + slop)
return 1;
return 0;
}
/*
* Return time in minutes between DTIME and next time in TIMES.
* If TIMES doesn't give a time, return -1.
* DTIME is day time in minutes since midnight.
* TIMES is a list of day times. See daytime() for syntax.
*/
int
min_to_next_daytime(int dtime, char *times)
{
int mindt = INT_MAX;
int dt;
if (times) {
while (NULL != (times = daytime(times, &dt))) {
if (dt <= dtime)
dt += 24 * 60; /* tomorrow */
if (dt < mindt)
mindt = dt;
}
}
if (mindt == INT_MAX)
return -1;
return mindt - dtime;
}
/*
* Parse weekday name in STR.
* On success assign day number (Sunday is 0) to *WDAY and return

320
src/lib/common/rdsched.c Normal file
View file

@ -0,0 +1,320 @@
/*
* Empire - A multi-player, client/server Internet based war game.
* Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---
*
* See files README, COPYING and CREDITS in the root of the source
* tree for related information and legal notices. It is expected
* that future projects/authors will amend these files as needed.
*
* ---
*
* rdsched.c: Read update schedule
*
* Known contributors to this file:
* Markus Armbruster, 2007
*/
#define _XOPEN_SOURCE 500
#include <config.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "prototypes.h"
static int parse_schedule_line(char *, time_t[], int, time_t, time_t *,
char *, int);
static int time_ok(time_t, char *, int);
static char *parse_time(time_t *, char *, time_t *);
static char *parse_every(time_t *, char *);
static char *parse_until(time_t *, char *, time_t *);
static char *parse_skip(time_t *, char *, time_t *);
static int insert_update(time_t, time_t[], int, time_t);
static int delete_update(time_t, time_t[], int);
/*
* Read update schedule from file FNAME.
* Put the first N-1 updates after T0 into SCHED[] in ascending order,
* terminated with a zero.
* Use ANCHOR as initial anchor for anchor-relative times.
* Return 0 on success, -1 on failure.
*/
int
read_schedule(char *fname, time_t sched[], int n, time_t t0, time_t anchor)
{
FILE *fp;
int lno = 0;
char buf[1024];
char *endp;
if (fname) {
fp = fopen(fname, "r");
if (!fp) {
logerror("Can't open %s for reading (%s)\n",
fname, strerror(errno));
return -1;
}
} else {
fp = stdin;
fname = "<stdin>";
}
sched[0] = 0;
while (fgets(buf, sizeof(buf), fp) != NULL) {
++lno;
endp = strchr(buf, '#');
if (endp)
*endp = 0;
if (parse_schedule_line(buf, sched, n, t0, &anchor, fname, lno))
return -1;
}
fclose(fp);
return 0;
}
/*
* Parse an update schedule directive from LINE.
* Update SCHED[] and ANCHOR accordingly.
* SCHED[] holds the first N-1 updates after T0 in ascending order.
* FNAME and LNO file name and line number for reporting errors.
*/
static int
parse_schedule_line(char *line, time_t sched[], int n,
time_t t0, time_t *anchor,
char *fname, int lno)
{
char *endp, *p;
int bol;
time_t t, delta, u;
if ((endp = parse_time(&t, line, anchor))) {
if (!time_ok(t, fname, lno))
return -1;
*anchor = t;
insert_update(t, sched, n, t0);
} else if ((endp = parse_every(&delta, line))) {
if ((p = parse_until(&u, endp, anchor))) {
endp = p;
if (!time_ok(u, fname, lno))
return -1;
} else
u = (time_t)-1;
t = *anchor;
do {
t += delta;
} while ((u == (time_t)-1 || t <= u)
&& insert_update(t, sched, n, t0) < n - 1);
} else if ((endp = parse_skip(&t, line, anchor))) {
if (!time_ok(t, fname, lno))
return -1;
delete_update(t, sched, n);
} else
endp = line;
bol = endp == line;
while (isspace(*endp)) endp++;
if (*endp) {
if (bol)
logerror("%s:%d: unintelligible\n", fname, lno);
else
logerror("%s:%d: trailing junk\n", fname, lno);
return -1;
}
return 0;
}
/*
* Complain and return zero when T is bad, else return non-zero.
* FNAME and LNO file name and line number.
*/
static int
time_ok(time_t t, char *fname, int lno)
{
if (t == (time_t)-1) {
logerror("%s:%d: time weird\n", fname, lno);
return 0;
}
return 1;
}
/*
* Parse a time from S into *T.
* *ANCHOR is the base for anchor-relative time.
* Return pointer to first character not parsed on success,
* null pointer on failure.
*/
static char *
parse_time(time_t *t, char *s, time_t *anchor)
{
static char *fmt[] = {
"%Y-%m-%d %H:%M ", /* ISO 8601 */
"%b %d %H:%M %Y ", /* like ctime(): Dec 22 15:35 2006 */
"%d %b %Y %H:%M ", /* 22 Dec 2006 15:35 */
"next %a %H:%M ", /* next Fri 15:35 */
"next %a ", /* next Fri */
NULL
};
char *p, *endp;
int i;
struct tm tm, nexttm;
for (p = s; isspace(*(unsigned char *)p); ++p) ;
for (i = 0; ; i++) {
if (!fmt[i])
return NULL;
memset(&tm, 0, sizeof(tm));
tm.tm_hour = -1;
endp = strptime(p, fmt[i], &tm);
if (endp)
break;
}
if (tm.tm_mday == 0) {
/* relative to anchor */
nexttm = *localtime(anchor);
if (tm.tm_hour >= 0) {
/* got hour and minute */
nexttm.tm_hour = tm.tm_hour;
nexttm.tm_min = tm.tm_min;
nexttm.tm_sec = 0;
}
nexttm.tm_mday += tm.tm_wday - nexttm.tm_wday;
if (tm.tm_wday <= nexttm.tm_wday)
nexttm.tm_mday += 7;
tm = nexttm;
}
*t = mktime(&tm);
return endp;
}
/*
* Parse an every clause from S into *SECS.
* Return pointer to first character not parsed on success,
* null pointer on failure.
*/
static char *
parse_every(time_t *secs, char *s)
{
int nch, delta;
nch = -1;
sscanf(s, " every %u hours%n", &delta, &nch);
if (nch >= 0)
delta *= 60;
else
sscanf(s, " every %u minutes%n", &delta, &nch);
if (nch < 0)
return NULL; *secs = 60 * delta;
return s + nch;
}
/*
* Parse an until clause from S into *T.
* *ANCHOR is the base for anchor-relative time.
* Return pointer to first character not parsed on success,
* null pointer on failure.
*/
static char *
parse_until(time_t *t, char *s, time_t *anchor)
{
int nch;
nch = -1;
sscanf(s, " until%n", &nch);
if (nch < 0)
return NULL;
return parse_time(t, s + nch, anchor);
}
/*
* Parse an skip clause from S into *T.
* *ANCHOR is the base for anchor-relative time.
* Return pointer to first character not parsed on success,
* null pointer on failure.
*/
static char *
parse_skip(time_t *t, char *s, time_t *anchor)
{
int nch;
nch = -1;
sscanf(s, " skip%n", &nch);
if (nch < 0)
return NULL;
return parse_time(t, s + nch, anchor);
}
/*
* Return the index of the first update at or after T in SCHED[].
*/
static int
find_update(time_t t, time_t sched[])
{
int i;
/* Could use binary search here, but it's hardly worth it */
for (i = 0; sched[i] && t > sched[i]; i++) ;
return i;
}
/*
* Insert update at T into SCHED[].
* SCHED[] holds the first N-1 updates after T0 in ascending order.
* If T is before T0 or outside game_days/game_hours, return -1.
* If there's no space for T in SCHED[], return N-1.
* Else insert T into SCHED[] and return its index in SCHED[].
*/
static int
insert_update(time_t t, time_t sched[], int n, time_t t0)
{
int i;
if (t <= t0 || !gamehours(t))
return -1;
i = find_update(t, sched);
memmove(sched + i + 1, sched + i, (n - 1 - i) * sizeof(*sched));
sched[i] = t;
sched[n - 1] = 0;
return i;
}
/*
* Delete update T from SCHED[].
* SCHED[] holds N-1 updates in ascending order.
* Return the index of the first update after T in SCHED[].
*/
static int
delete_update(time_t t, time_t sched[], int n)
{
int i = find_update(t, sched);
if (t == sched[i])
memmove(sched + i, sched + i + 1,
(n - 1 - i) * sizeof(*sched));
return i;
}

View file

@ -47,26 +47,6 @@
#include "nat.h"
#include "optlist.h"
#include "prototypes.h"
#include "wantupd.h"
void
update_policy_check(void)
{
if (update_policy < 0)
update_policy = UDP_DEFAULT;
if (update_policy > UDP_MAX)
update_policy = UDP_DEFAULT;
if (update_demandpolicy < 0)
update_demandpolicy = UDDEM_DEFAULT;
if (update_demandpolicy > UDDEM_MAX)
update_demandpolicy = UDDEM_DEFAULT;
if (update_wantmin < 1)
update_wantmin = 1;
if (update_wantmin > MAXNOC)
update_wantmin = MAXNOC;
if (blitz_time < 1)
blitz_time = 1;
}
static int
demand_update_time(time_t *now)
@ -78,45 +58,6 @@ demand_update_time(time_t *now)
update_demandtimes);
}
/* When is the next regularly scheduled update from now. */
static void
regular_update_time(time_t *now, time_t *tim, time_t *delta)
{
time_t tw;
int secs_per_update;
tw = *now + adj_update;
secs_per_update = etu_per_update * s_p_etu;
*delta = secs_per_update - (tw % secs_per_update);
*tim = *now + *delta;
}
/* Is this a valid time for a scheduled update. */
static int
scheduled_update_time(time_t *now)
{
struct tm *tm;
tm = localtime(now);
return is_daytime_near(60 * tm->tm_hour + tm->tm_min,
update_times, hourslop);
}
static int
next_scheduled_time(time_t *now, time_t *tim, time_t *delta)
{
struct tm *tm;
int d;
tm = localtime(now);
d = min_to_next_daytime(60 * tm->tm_hour + tm->tm_min, update_times);
if (d < 0)
return 0;
*delta = 60 * d;
*tim = *now + *delta - tm->tm_sec;
return 1;
}
int
demand_update_want(int *want, int *pop, int which)
{
@ -144,12 +85,14 @@ demand_update_want(int *want, int *pop, int which)
return whichwants;
}
static int
/*
* Do we have sufficient votes for a demand update?
*/
int
demand_check(void)
{
struct natstr *natp;
int want, pop, cn, veto;
time_t now;
demand_update_want(&want, &pop, 0);
if (want < update_wantmin) {
@ -158,13 +101,6 @@ demand_check(void)
return 0;
}
time(&now);
if (!demand_update_time(&now)) {
logerror("no demand update, not within hours allowed.");
return 0;
}
veto = 0;
for (cn = 1; 0 != (natp = getnatp(cn)); cn++) {
if (natp->nat_stat == STAT_ACTIVE) {
@ -183,118 +119,17 @@ demand_check(void)
}
/*
* Check if enough countries want an update,
* and if demand updates are allowed now.
* Can we have an unscheduled demand update now?
*/
int
demandupdatecheck(void)
{
if (UDDEM_COMSET != update_demandpolicy) {
logerror("no demand update, not policy.");
return 0;
}
time_t now = time(NULL);
return demand_check();
}
/*
* Is it time for a regular or scheduled update?
* As well, if none of the above, check to see if
* a demand update can occur.
*/
int
updatetime(time_t *now)
{
if (opt_BLITZ && update_policy == UDP_BLITZ) {
logerror("BLITZ Update.");
return 1;
}
if (UDP_NORMAL == update_policy) {
logerror("Regular update, etu type.");
return 1;
}
if (UDP_TIMES == update_policy) {
if (scheduled_update_time(now)) {
logerror("Scheduled update.");
return 1;
}
}
if (UDDEM_DISABLE != update_demandpolicy) {
if (demand_check()) {
logerror("Demand update, at check time.");
return 1;
}
}
return 0;
}
/*
* Return the time, and delta seconds, of the next update.
* If the policy is no regular updates, return the time of
* the next possible check.
*/
void
next_update_time(time_t *now, time_t *tim, time_t *delta)
/* From when */
/* Time of next update */
/* Seconds till next update */
{
time_t stim, sdelta;
switch (update_policy) {
case UDP_NORMAL:
regular_update_time(now, tim, delta);
break;
case UDP_TIMES:
if (!next_scheduled_time(now, tim, delta))
regular_update_time(now, tim, delta);
break;
case UDP_BLITZ:
*delta = (blitz_time * 60) - (*now % (blitz_time * 60));
*tim = *now + *delta;
break;
case UDP_NOREG:
default:
regular_update_time(now, tim, delta);
if (next_scheduled_time(now, &stim, &sdelta)) {
if (*delta > sdelta) {
*delta = sdelta;
*tim = stim;
}
}
break;
}
}
void
next_update_check_time(time_t *now, time_t *tim, time_t *delta)
/* From when */
/* Time of next update */
/* Seconds till next update check */
{
time_t stim, sdelta;
switch (update_policy) {
case UDP_NORMAL:
regular_update_time(now, tim, delta);
break;
case UDP_BLITZ:
*delta = (blitz_time * 60) - (*now % (blitz_time * 60));
*tim = *now + *delta;
break;
case UDP_TIMES:
case UDP_NOREG:
default:
regular_update_time(now, tim, delta);
if (next_scheduled_time(now, &stim, &sdelta)) {
if (*delta > sdelta) {
*delta = sdelta;
*tim = stim;
}
}
}
return update_demand == UPD_DEMAND_ASYNC
&& !updates_disabled()
&& demand_update_time(&now)
&& demand_check();
}
int

View file

@ -70,7 +70,7 @@ struct keymatch configkeys[] = {
};
static struct keymatch *keylookup(char *key, struct keymatch tbl[]);
static void set_dirs(char *);
static void set_paths(char *);
/*
* read in empire configuration
@ -154,7 +154,7 @@ emp_config(char *file)
done:
WORLD_X &= ~1; /* force even */
set_dirs(file);
set_paths(file);
return -errors;
}
@ -175,7 +175,7 @@ keylookup(char *command, struct keymatch *tbl)
}
static void
set_dirs(char *econfig)
set_paths(char *econfig)
{
char *slash;
char *cwd = getcwd(NULL, 0);
@ -204,6 +204,9 @@ set_dirs(char *econfig)
}
#endif /* !_WIN32 */
schedulefil = malloc(strlen(configdir) + 10);
sprintf(schedulefil, "%s/schedule", configdir);
free(cwd);
}

View file

@ -34,7 +34,7 @@
#include <config.h>
#include "wantupd.h"
#include "optlist.h"
/* Name of the deity */
char *privname = "Deity forgot to edit econfig";
@ -56,15 +56,10 @@ int TRADE_DELAY = 7200; /* Seconds to bid on units */
int m_m_p_d = 1440; /* max mins of play per day (per country) */
int s_p_etu = 10; /* seconds per Empire Time Unit */
int etu_per_update = 60; /* # of etu's per update */
int adj_update = 0; /* update time adjustment, in seconds */
int update_window = 0; /* update window adjustment, in seconds */
int hourslop = 5; /* update_times matching fuzz, in minutes */
char *update_times = ""; /* update times for policy UDP_TIMES */
int update_policy = UDP_DEFAULT; /* update policy for regular updates */
int update_demandpolicy = UDDEM_DEFAULT; /* update policy for demand updates */
int update_demand = UPD_DEMAND_NONE;
int update_missed = 999; /* demand updates missed before veto */
int update_wantmin = 1; /* votes required for demand update */
int blitz_time = 10; /* number of minutes between blitz updates */
char *update_demandtimes = ""; /* demand update time ranges */
char *game_days = ""; /* days game is running */
char *game_hours = ""; /* hours game is running */

View file

@ -49,6 +49,9 @@ char *configdir;
/* User configuration tables to load (relative to configdir) */
char *custom_tables = "";
/* Update schedule (absolute file name) */
char *schedulefil;
/* Where to find built-in configuration tables (relative to configdir) */
char *builtindir = "@builtindir@";

View file

@ -111,7 +111,7 @@ struct cmndstr player_coms[] = {
{"fly <cargo-PLANES> <fighter-PLANES> <ap-SECT> <PATH|DESTINATION> <COM>",
2, fly, C_MOD, NORM + MONEY + CAP},
{"follow <leader> <SHIPS>", 1, foll, C_MOD, NORM + CAP},
{"force <delay time>", 0, force, C_MOD, GOD},
{"force", 0, force, C_MOD, GOD},
{"fortify <UNITS> <MOB>", 1, fort, C_MOD, NORM},
{"fuel <s|l> <SHIP/FLEET | UNIT/ARMY> <AMOUNT> [<OILER>]",
1, fuel, C_MOD, NORM},

View file

@ -41,7 +41,6 @@
#include "player.h"
#include "server.h"
#include "update.h"
#include "wantupd.h"
long money[MAXNOC];
long pops[MAXNOC];
@ -159,7 +158,8 @@ update_main(void)
mob_plane(etu);
mob_land(etu);
}
if (update_demandpolicy != UDDEM_DISABLE)
if (update_demand == UPD_DEMAND_SCHED
|| update_demand == UPD_DEMAND_ASYNC)
update_removewants();
/* flush all mem file objects to disk */
ef_flush(EF_NATION);