]> git.pond.sub.org Git - empserver/blob - src/lib/commands/head.c
Fix trailing whitespace
[empserver] / src / lib / commands / head.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See files README, COPYING and CREDITS in the root of the source
23  *  tree for related information and legal notices.  It is expected
24  *  that future projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  head.c: Print headlines of the Empire News
29  *
30  *  Known contributors to this file:
31  *
32  */
33
34 #include <config.h>
35
36 #include "commands.h"
37 #include "news.h"
38
39 struct histstr {
40     int h_past;
41     int h_recent;
42 };
43
44 static char *head_meanwhile(int val);
45 static void head_describe(struct histstr *, int, char *, char *);
46 static int head_printscoop(struct histstr (*hist)[MAXNOC], natid ano,
47                            natid vno);
48 static int head_findscoop(struct histstr (*hist)[MAXNOC],
49                           natid maxcnum, natid *ano, natid *vno);
50
51 int
52 head(void)
53 {
54     struct histstr *hp;
55     natid maxcnum;
56     time_t now;
57     int severity;
58     int scoop;
59     time_t news_per;
60     time_t news_age;
61     struct histstr hist[MAXNOC][MAXNOC];
62     struct natstr *natp;
63     struct nwsstr news;
64     natid actor;
65     natid victim;
66     struct nstr_item nstr;
67     int i, n;
68
69     (void)time(&now);
70     natp = getnatp(player->cnum);
71     if (player->argp[1] != 0 && *player->argp[1] != 0) {
72         news_per = days(atoi(player->argp[1]));
73         if (news_per > days(3))
74             news_per = days(3);
75     } else
76         news_per = now - natp->nat_newstim;
77     pr("\n        -=[  EMPIRE NEWS  ]=-\n");
78     pr("::::::::::::::::::::::::::::::::::::::::::::::::::\n");
79     pr("!       \"All the news that fits, we print.\"      !\n");
80     pr("::::::::::::::::::::::::::::::::::::::::::::::::::\n");
81     pr("       %s", ctime(&now));
82     pr("\n");
83     memset(hist, 0, sizeof(hist));
84     snxtitem_all(&nstr, EF_NEWS);
85     maxcnum = 0;
86     while (nxtitem(&nstr, &news)) {
87         if (!news.nws_vrb || CANT_HAPPEN(news.nws_vrb > N_MAX_VERB))
88             continue;
89         news_age = now - news.nws_when;
90         if (news_age > news_per)
91             continue;
92         if (news.nws_ano == news.nws_vno)
93             continue;
94         if ((i = rpt[(int)news.nws_vrb].r_good_will) == 0)
95             continue;
96         if (news_age > news_per / 2)
97             hist[news.nws_ano][news.nws_vno].h_past += i;
98         else
99             hist[news.nws_ano][news.nws_vno].h_recent += i;
100         if (maxcnum < news.nws_ano)
101             maxcnum = news.nws_ano;
102         if (maxcnum < news.nws_vno)
103             maxcnum = news.nws_vno;
104     }
105     for (n = 0; n < 5; n++) {
106         if ((scoop = head_findscoop(hist, maxcnum, &actor, &victim)) < 10)
107             break;
108         severity = head_printscoop(hist, actor, victim);
109         hp = &hist[actor][victim];
110         severity = hp->h_recent - hp->h_past;
111         if (severity <= -scoop / 2 || severity >= scoop / 2) {
112             pr("\t%s\n", head_meanwhile(severity));
113             (void)head_printscoop(hist, victim, actor);
114         }
115     }
116     if (n <= 1)
117         pr("\nRelative calm prevails.\n");
118     return RET_OK;
119 }
120
121 static int
122 head_printscoop(struct histstr (*hist)[MAXNOC], natid ano, natid vno)
123 {
124     struct histstr *hp;
125     int severity;
126
127     hp = &hist[ano][vno];
128     severity = abs(hp->h_past) > abs(hp->h_recent) ? 1 : 0;
129     severity += (hp->h_past >= 0) ? 2 : 0;
130     severity += (hp->h_recent >= 0) ? 4 : 0;
131     head_describe(hp, severity, cname(ano), cname(vno));
132     pr("\n");
133     hp->h_past = 0;
134     hp->h_recent = 0;
135     return severity;
136 }
137
138 static char *
139 head_meanwhile(int val)
140 {
141     switch (val & 03) {
142     case 0:
143         return "Meanwhile";
144     case 1:
145         return "On the other hand";
146     case 2:
147         return "At the same time";
148     case 3:
149         return "Although";
150     }
151     /*NOTREACHED*/
152     return "";
153 }
154
155 static void
156 head_describe(struct histstr *hp, int what, char *aname, char *vname)
157 {
158     switch (what) {
159     case 0:
160         if (hp->h_recent > hp->h_past / 2)
161             pr("Bad relations between %s and %s worsen!", aname, vname);
162         else
163             pr("Carnage wrought by %s on %s continues unabated!",
164                aname, vname);
165         break;
166     case 1:
167         if (hp->h_recent < -16)
168             pr("%s agression against %s has lessened slightly",
169                aname, vname);
170         else
171             pr("Peace talks may occur between %s & %s", aname, vname);
172         break;
173     case 2:
174         if (hp->h_recent < -16) {
175             if (hp->h_past > 0)
176                 pr(" ! WAR !  Reversal of prior %s -- %s relations",
177                    aname, vname);
178             else if (hp->h_recent >= -25)
179                 pr("VIOLENCE ERUPTS! -- %s wages war on %s", aname, vname);
180             else
181                 pr("%s wreaks havoc on %s!", aname, vname);
182         } else
183             pr("Breakdown in communication between %s & %s", aname, vname);
184         break;
185     case 3:
186         pr("FLASH!    %s turns on former ally, %s!", aname, vname);
187         break;
188     case 4:
189         pr("%s \"makes friends\" with %s", aname, vname);
190         break;
191     case 5:
192         if (hp->h_past >= -25)
193             pr("%s seems to have forgotten earlier disagreement with %s",
194                aname, vname);
195         else
196             pr("Tensions ease as %s attacks on %s seem at an end",
197                aname, vname);
198         break;
199     case 6:
200         pr("%s good deeds further growing alliance with %s", aname, vname);
201         break;
202     case 7:
203         if (hp->h_recent - hp->h_past < 12)
204             pr("Honeymoon appears to be over between %s & %s",
205                aname, vname);
206         else
207             pr("Friendly relations between %s & %s have cooled",
208                aname, vname);
209         break;
210     }
211 }
212
213 /*
214  * returns 9 if no scoops were found
215  * Pretty strange.
216  */
217 static int
218 head_findscoop(struct histstr (*hist)[MAXNOC], natid maxcnum,
219                natid *ano, natid *vno)
220 {
221     struct histstr *hp;
222     int i, j, k, scoop;
223     natid actor, victim;
224
225     scoop = 9;
226     actor = 0;
227     victim = 0;
228     for (i = 1; i < maxcnum; i++) {
229         for (j = 1; j < maxcnum; j++) {
230             hp = &hist[i][j];
231             k = abs(hp->h_recent / 2);
232             if (k > scoop) {
233                 scoop = k;
234                 actor = (natid)i;
235                 victim = (natid)j;
236             }
237             k = abs(hp->h_recent - hp->h_past);
238             if (k > scoop) {
239                 scoop = k;
240                 actor = (natid)i;
241                 victim = (natid)j;
242             }
243         }
244     }
245     *ano = actor;
246     *vno = victim;
247     return scoop;
248 }