/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
- * Ken Stevens, Steve McClure
+ * Copyright (C) 1986-2017, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Ken Stevens, Steve McClure, Markus Armbruster
*
- * This program is free software; you can redistribute it and/or modify
+ * Empire 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
+ * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* 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
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ---
*
* ---
*
* news.c: Show current Empire news
- *
+ *
* Known contributors to this file:
- *
+ * Markus Armbruster, 2006-2016
*/
#include <config.h>
+#include "chance.h"
#include "commands.h"
#include "news.h"
#include "optlist.h"
static void preport(struct nwsstr *np);
+static int sectwon_cmp(const void *p, const void *q);
+
+struct sectwon {
+ natid ano, vno;
+ unsigned short num;
+};
int
news(void)
{
struct natstr *natp;
time_t now;
- int page;
+ int heading, page;
time_t then;
time_t delta;
struct nwsstr nws;
struct nstr_item nstr;
int page_has_news[N_MAX_PAGE + 1];
- int there_is_news = 0;
- short sectors_taken[MAXNOC][MAXNOC];
- short sectors_delta;
- short max_delta = -1;
- short abs_delta;
- short k;
- int sectors_were_taken = 0;
+ unsigned short sectors_taken[MAXNOC][MAXNOC];
natid i, j;
+ int k, n, diff;
+ struct sectwon *sectwon;
char num[128];
char *verb;
- if (!snxtitem(&nstr, EF_NEWS, "*"))
- return RET_SYN;
- memset(page_has_news, 0, sizeof(page_has_news));
+ if (!snxtitem(&nstr, EF_NEWS, "*", NULL))
+ return RET_SYN;
memset(sectors_taken, 0, sizeof(sectors_taken));
(void)time(&now);
natp = getnatp(player->cnum);
natp->nat_newstim = now;
head();
pr("\nThe details of Empire news since %s", ctime(&then));
- while (nxtitem(&nstr, &nws)) {
- if (nws.nws_when < then)
- continue;
- if (opt_HIDDEN) {
- if (!player->god &&
- !(getcontact(getnatp(player->cnum), nws.nws_ano) &&
- getcontact(getnatp(player->cnum), nws.nws_vno)))
- continue;
- }
- ++page_has_news[rpt[(int)nws.nws_vrb].r_newspage];
- ++there_is_news;
- }
- for (page = 1; page <= N_MAX_PAGE; page++) {
+
+ heading = 0;
+ memset(page_has_news, 0, sizeof(page_has_news));
+ page_has_news[0] = 1;
+
+ for (page = 0; page <= N_MAX_PAGE; page++) {
if (!page_has_news[page])
continue;
- pr("\n\t === %s ===\n", page_headings[page].name);
snxtitem_rewind(&nstr);
while (nxtitem(&nstr, &nws)) {
- if (rpt[(int)nws.nws_vrb].r_newspage != page)
+ if (CANT_HAPPEN(nws.nws_vrb > N_MAX_VERB))
continue;
if (nws.nws_when < then)
continue;
- if (nws.nws_ntm == 0)
+ if (CANT_HAPPEN(nws.nws_ntm <= 0))
nws.nws_ntm = 1;
if (opt_HIDDEN) {
if (!player->god &&
- !(getcontact(getnatp(player->cnum), nws.nws_ano) &&
- getcontact(getnatp(player->cnum), nws.nws_vno)))
+ !(in_contact(player->cnum, nws.nws_ano) &&
+ in_contact(player->cnum, nws.nws_vno)))
continue;
}
- if (page == N_FRONT &&
- (nws.nws_vrb == N_WON_SECT ||
- nws.nws_vrb == N_AWON_SECT ||
- nws.nws_vrb == N_PWON_SECT)) {
- sectors_taken[nws.nws_ano][nws.nws_vno] += nws.nws_ntm;
- sectors_were_taken += nws.nws_ntm;
+ page_has_news[rpt[nws.nws_vrb].r_newspage] = 1;
+ if (rpt[nws.nws_vrb].r_newspage != page)
+ continue;
+ if (heading != page) {
+ pr("\n\t === %s ===\n", page_headings[page].name);
+ heading = page;
}
+ if (nws.nws_vrb == N_WON_SECT ||
+ nws.nws_vrb == N_AWON_SECT ||
+ nws.nws_vrb == N_PWON_SECT)
+ sectors_taken[nws.nws_ano][nws.nws_vno] += nws.nws_ntm;
preport(&nws);
}
}
- if (sectors_were_taken) {
- for (i = 0; i < MAXNOC; ++i) {
- for (j = 0; j < i; ++j) {
- sectors_delta = sectors_taken[i][j] - sectors_taken[j][i];
- if (max_delta < abs(sectors_delta))
- max_delta = abs(sectors_delta);
+
+ if (!heading) {
+ pr("\nNo news at the moment...\n");
+ return RET_OK;
+ }
+
+ n = 0;
+ for (i = 0; i < MAXNOC; ++i) {
+ for (j = 0; j < i; ++j)
+ n += !!(sectors_taken[i][j] - sectors_taken[j][i]);
+ }
+ sectwon = malloc(sizeof(*sectwon) * n);
+
+ n = 0;
+ for (i = 0; i < MAXNOC; ++i) {
+ for (j = 0; j < i; ++j) {
+ diff = sectors_taken[i][j] - sectors_taken[j][i];
+ if (diff > 0) {
+ sectwon[n].ano = i;
+ sectwon[n].vno = j;
+ sectwon[n].num = diff;
+ n++;
+ } else if (diff < 0) {
+ sectwon[n].ano = j;
+ sectwon[n].vno = i;
+ sectwon[n].num = -diff;
+ n++;
}
}
+ }
+
+ qsort(sectwon, n, sizeof(*sectwon), sectwon_cmp);
+
+ if (n) {
pr("\n\t === The Bottom Line ==\n");
- for (k = max_delta; k > 0; --k) {
- for (i = 0; i < MAXNOC; ++i) {
- for (j = 0; j < i; ++j) {
- sectors_delta = sectors_taken[i][j] -
- sectors_taken[j][i];
- abs_delta = abs(sectors_delta);
- if (abs_delta != k)
- continue;
- if (abs_delta == 1)
- verb = "stole";
- else if (abs_delta < 4)
- verb = "took";
- else if (abs_delta < 8)
- verb = "captured";
- else
- verb = "seized";
- if (sectors_delta > 0) {
- numstr(num, abs_delta);
- pr("%s %s %s sector%s from %s\n", cname(i), verb,
- num, splur(sectors_delta), cname(j));
- } else if (sectors_delta < 0) {
- numstr(num, abs_delta);
- pr("%s %s %s sector%s from %s\n", cname(j), verb,
- num, splur(-sectors_delta), cname(i));
- }
- }
- }
+ for (k = 0; k < n; k++) {
+ if (sectwon[k].num == 1)
+ verb = "stole";
+ else if (sectwon[k].num < 4)
+ verb = "took";
+ else if (sectwon[k].num < 8)
+ verb = "captured";
+ else
+ verb = "seized";
+ numstr(num, sectwon[k].num);
+ pr("%s %s %s sector%s from %s\n",
+ cname(sectwon[k].ano), verb, num, splur(sectwon[k].num),
+ cname(sectwon[k].vno));
}
}
- if (!there_is_news)
- pr("\nNo news at the moment...\n");
- return 0;
+
+ free(sectwon);
+ return RET_OK;
}
static void
/*
* vary the order of the printing of "%d times "
*/
- if ((random() & 3) == 0 && np->nws_ntm > 1) {
+ if (roll0(4) == 0 && np->nws_ntm > 1) {
sprintf(cp, "%s times ", ptr);
cp += strlen(cp);
np->nws_ntm = 1;
strcpy(cp, cname(np->nws_ano));
cp += strlen(cp);
*cp++ = ' ';
- if (np->nws_vrb < 1 || np->nws_vrb > N_MAX_VERB)
- np->nws_vrb = 0;
- sprintf(cp, rpt[(int)np->nws_vrb].r_newstory[random() % NUM_RPTS],
+ sprintf(cp, rpt[(int)np->nws_vrb].r_newstory[roll0(NUM_RPTS)],
cname(np->nws_vno));
cp += strlen(cp);
if (np->nws_ntm != 1) {
sprintf(cp, " %s times", ptr);
cp += strlen(cp);
}
- if (*buf >= 'a' && *buf <= 'z')
- *buf += 'A' - 'a';
if (cp - buf > 80) {
for (i = 80; --i > 60;)
if (buf[i] == ' ')
np->nws_ntm = 0;
return;
}
+
+static int
+sectwon_cmp(const void *p, const void *q)
+{
+ const struct sectwon *a = p, *b = q;
+ int cmp;
+
+ cmp = b->num - a->num;
+ if (cmp)
+ return cmp;
+ cmp = b->ano - a->ano;
+ if (cmp)
+ return cmp;
+ return b->vno - a->vno;
+}