empserver/src/lib/commands/head.c
Markus Armbruster 4ae9c417b3 (bzero, bcopy): Obsolete BSDisms; remove. Remove some calls without
effect.  Replace calls by struct assignment where possible.  Replace
clear buffer, copy string to buffer by strncpy().  Use assignment to
clear when that's clearer.  Replace overlapping copy through bounce
buffer by memmove().  Replace rest by standard memset() and memcpy().
Also use sizeof() instead of literal array sizes for robustness, and
instead of symbolic array sizes for clarity.
2004-01-08 17:54:28 +00:00

261 lines
6.5 KiB
C

/*
* 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.
*
* ---
*
* head.c: Print headlines of the Empire News
*
* Known contributors to this file:
*
*/
#include "misc.h"
#include "player.h"
#include "news.h"
#include "nat.h"
#include "file.h"
#include "xy.h"
#include "nsc.h"
#include "commands.h"
struct histstr {
int h_past;
int h_recent;
};
static s_char *head_meanwhile(int val);
static s_char *head_describe(struct histstr *hp, int what);
static int head_printscoop(struct histstr (*hist)[MAXNOC], natid ano,
natid vno);
static int head_findscoop(struct histstr (*hist)[MAXNOC],
register natid maxcnum, natid *ano, natid *vno);
int
head(void)
{
register int i;
register struct histstr *hp;
register natid maxcnum;
time_t now;
int severity;
int scoop;
time_t news_per;
time_t news_age;
struct histstr hist[MAXNOC][MAXNOC];
struct natstr *natp;
struct nwsstr news;
natid actor;
natid victim;
struct nstr_item nstr;
int n;
(void)time(&now);
natp = getnatp(player->cnum);
if (player->argp[1] != 0 && *player->argp[1] != 0) {
news_per = days(atoi(player->argp[1]));
if (news_per > days(3))
news_per = days(3);
} else
/* replaced the following line with the one under it to
* fix headlines which never change.
* 3/3/90 bailey@math-cs.kent.edu
*/
/* news_per = natp->nat_newstim; */
news_per = now - natp->nat_newstim;
pr("\n -=[ EMPIRE NEWS ]=-\n");
pr("::::::::::::::::::::::::::::::::::::::::::::::::::\n");
pr("! \"All the news that fits, we print.\" !\n");
pr("::::::::::::::::::::::::::::::::::::::::::::::::::\n");
pr(" %s", ctime(&now));
pr("\n");
memset(hist, 0, sizeof(hist));
snxtitem_all(&nstr, EF_NEWS);
maxcnum = 0;
while (nxtitem(&nstr, (s_char *)&news)) {
news_age = now - news.nws_when;
if (news_age > news_per)
continue;
if (news.nws_ano == news.nws_vno)
continue;
if ((i = rpt[(int)news.nws_vrb].r_good_will) == 0)
continue;
if (news_age > (news_per / 2))
hist[news.nws_ano][news.nws_vno].h_past += i;
else
hist[news.nws_ano][news.nws_vno].h_recent += i;
if (maxcnum < news.nws_ano)
maxcnum = news.nws_ano;
if (maxcnum < news.nws_vno)
maxcnum = news.nws_vno;
}
for (n = 0; n < 5; n++) {
if ((scoop = head_findscoop(hist, maxcnum, &actor, &victim)) < 10)
break;
severity = head_printscoop(hist, actor, victim);
hp = &hist[actor][victim];
severity = hp->h_recent - hp->h_past;
if (severity <= -scoop / 2 || severity >= scoop / 2) {
pr("\t%s\n", head_meanwhile(severity));
(void)head_printscoop(hist, victim, actor);
}
}
if (n <= 1)
pr("\nRelative calm prevails.\n");
return RET_OK;
}
static
int
head_printscoop(struct histstr (*hist)[MAXNOC], natid ano, natid vno)
{
register struct histstr *hp;
int severity;
hp = &hist[ano][vno];
severity = abs(hp->h_past) > abs(hp->h_recent) ? 1 : 0;
severity += (hp->h_past >= 0) ? 2 : 0;
severity += (hp->h_recent >= 0) ? 4 : 0;
pr(head_describe(hp, severity), cname(ano), cname(vno));
pr("\n");
hp->h_past = 0;
hp->h_recent = 0;
return severity;
}
static
s_char *
head_meanwhile(int val)
{
switch (val & 03) {
case 0:
return "Meanwhile";
case 1:
return "On the other hand";
case 2:
return "At the same time";
case 3:
return "Although";
}
/*NOTREACHED*/
return "";
}
static
s_char *
head_describe(struct histstr *hp, int what)
{
s_char *cp;
cp = 0;
switch (what) {
case 0:
if (hp->h_recent > hp->h_past / 2)
cp = "Bad relations between %s and %s worsen!";
else
cp = "Carnage wrought by %s on %s continues unabated!";
break;
case 1:
if (hp->h_recent < -16)
cp = "%s agression against %s has lessened slightly";
else
cp = "Peace talks may occur between %s & %s";
break;
case 2:
if (hp->h_recent < -16) {
if (hp->h_past > 0)
cp = " ! WAR ! Reversal of prior %s -- %s relations";
else if (hp->h_recent >= -25)
cp = "VIOLENCE ERUPTS! -- %s wages war on %s";
else
cp = "%s wreaks havoc on %s!";
} else
cp = "Breakdown in communication between %s & %s";
break;
case 3:
cp = "FLASH! %s turns on former ally, %s!";
break;
case 4:
cp = "%s \"makes friends\" with %s";
break;
case 5:
if (hp->h_past >= -25)
cp = "%s seems to have forgotten earlier disagreement with %s";
else
cp = "Tensions ease as %s attacks on %s seem at an end";
break;
case 6:
cp = "%s good deeds further growing alliance with %s";
break;
case 7:
if (hp->h_recent - hp->h_past < 12)
cp = "Honeymoon appears to be over between %s & %s";
else
cp = "Friendly relations between %s & %s have cooled";
break;
}
return cp;
}
/*
* returns 9 if no scoops were found
* Pretty strange.
*/
static
int
head_findscoop(struct histstr (*hist)[MAXNOC], register natid maxcnum,
natid *ano, natid *vno)
{
register struct histstr *hp;
register int i;
register int j;
register int k;
int scoop;
natid actor;
natid victim;
scoop = 9;
actor = 0;
victim = 0;
for (i = 1; i < maxcnum; i++) {
for (j = 1; j < maxcnum; j++) {
hp = &hist[i][j];
k = abs(hp->h_recent / 2);
if (k > scoop) {
scoop = k;
actor = (natid)i;
victim = (natid)j;
}
k = abs(hp->h_recent - hp->h_past);
if (k > scoop) {
scoop = k;
actor = (natid)i;
victim = (natid)j;
}
}
}
*ano = actor;
*vno = victim;
return scoop;
}