00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <config.h>
00037
00038 #include "file.h"
00039 #include "nat.h"
00040 #include "news.h"
00041 #include "optlist.h"
00042 #include "prototypes.h"
00043
00044 #define SLOTS 5
00045
00046 struct newscache {
00047 struct nwsstr news;
00048 int id;
00049 };
00050
00051 static struct newscache cache[MAXNOC][SLOTS];
00052 static int news_tail;
00053
00054 static struct newscache *
00055 ncache(int actor, int event, int victim, int times);
00056
00057 void
00058 nreport(natid actor, int event, natid victim, int times)
00059 {
00060 int nice;
00061 struct natstr *natp;
00062 struct newscache *ncp;
00063
00064 if (CANT_HAPPEN((unsigned)event > N_MAX_VERB
00065 || rpt[event].r_newstory[0] == rpt[0].r_newstory[0]))
00066 return;
00067
00068 ncp = ncache(actor, event, victim, times);
00069 putnews(ncp->id, &ncp->news);
00070
00071
00072
00073
00074
00075 if (victim == 0 || (nice = rpt[event].r_good_will) >= 0)
00076 return;
00077
00078
00079
00080
00081 if (actor == victim)
00082 return;
00083 if (!chance((double)-nice * times / 20.0))
00084 return;
00085 if ((natp = getnatp(victim)) == 0)
00086 return;
00087 if (getrel(natp, actor) < HOSTILE)
00088 return;
00089
00090 setrel(victim, actor, HOSTILE);
00091 }
00092
00093
00094
00095
00096 void
00097 delete_old_news(void)
00098 {
00099 time_t expiry_time;
00100 int i, j, k;
00101 struct nwsstr news;
00102
00103
00104 expiry_time = time(NULL) - days(news_keep_days);
00105 for (i = 0; getnews(i, &news); i++) {
00106 if (news.nws_when == 0 || news.nws_when >= expiry_time)
00107 break;
00108 }
00109
00110 CANT_HAPPEN(i > news_tail);
00111
00112 if (i == 0)
00113 return;
00114
00115
00116 for (j = 0; getnews(i + j, &news); j++) {
00117 if (news.nws_when == 0)
00118 break;
00119 putnews(j, &news);
00120 }
00121 CANT_HAPPEN(i + j != news_tail);
00122 news_tail = j;
00123
00124
00125 memset(&news, 0, sizeof(news));
00126 for (k = 0; k < i; k++)
00127 putnews(j + k, &news);
00128
00129
00130 memset(&cache, 0, sizeof(cache));
00131 }
00132
00133
00134
00135
00136
00137 void
00138 init_nreport(void)
00139 {
00140 int newest_item;
00141 struct nwsstr news;
00142
00143 for (newest_item = 0; getnews(newest_item, &news); newest_item++) {
00144 if (news.nws_when == 0)
00145 break;
00146 }
00147 news_tail = newest_item;
00148 }
00149
00150
00151
00152
00153
00154
00155 static struct newscache *
00156 ncache(int actor, int event, int victim, int times)
00157 {
00158 struct newscache *np;
00159 int i;
00160 int oldslot;
00161 time_t oldtime;
00162 time_t now = time(NULL);
00163
00164 oldslot = -1;
00165 oldtime = 0x7fffffff;
00166 for (i = 0; i < SLOTS; i++) {
00167 np = &cache[actor][i];
00168 if (np->news.nws_when < oldtime) {
00169 oldslot = i;
00170 oldtime = np->news.nws_when;
00171 }
00172 if (np->id == 0)
00173 continue;
00174 if ((now - np->news.nws_when) > minutes(5))
00175 continue;
00176 if (np->news.nws_vrb == event && np->news.nws_vno == victim &&
00177 np->news.nws_ntm + times <= 127) {
00178 np->news.nws_ntm += times;
00179 return np;
00180 }
00181 }
00182 if (CANT_HAPPEN(oldslot < 0))
00183 oldslot = 0;
00184 if (CANT_HAPPEN(!strstr(rpt[event].r_newstory[0], "%s") && victim != 0))
00185 victim = 0;
00186 np = &cache[actor][oldslot];
00187 np->news.nws_ano = actor;
00188 np->news.nws_vno = victim;
00189 np->news.nws_when = now;
00190 np->news.nws_vrb = event;
00191 np->news.nws_ntm = times;
00192 ef_ensure_space(EF_NEWS, news_tail, 100);
00193 np->id = news_tail++;
00194 return np;
00195 }