]> git.pond.sub.org Git - empserver/blob - src/lib/subs/satmap.c
Indented with src/scripts/indent-emp.
[empserver] / src / lib / subs / satmap.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2000, 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 the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23  *  related information and legal notices. It is expected that any future
24  *  projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  satmap.c: Do a satellite map given an x,y location, effic and other
29  * 
30  *  Known contributors to this file:
31  *     Steve McClure, 2000
32  *     
33  */
34
35 #include "misc.h"
36 #include "player.h"
37 #include "xy.h"
38 #include "sect.h"
39 #include "ship.h"
40 #include "land.h"
41 #include "plane.h"
42 #include "var.h"
43 #include "nsc.h"
44 #include "nat.h"
45 #include "file.h"
46 #include "prototypes.h"
47 #include "optlist.h"
48
49 void satdisp(struct sctstr *sp, int acc, int showstuff);
50
51 static s_char **rad;
52 static s_char *radbuf;
53
54 void
55 satmap(int x, int y, int eff, int range, int flags, int type)
56 {
57     int acc;
58     struct sctstr sect;
59     struct shpstr ship;
60     struct lndstr land;
61     int count;
62     struct nstr_item ni;
63     struct nstr_sect ns;
64     int rx, ry;
65     int row;
66     int n;
67     int changed = 0;
68     long crackle;
69     s_char noise[100];
70     s_char selection[1024];
71
72     if (!eff)
73         return;
74
75     if (!radbuf)
76         radbuf = (s_char *)malloc((WORLD_Y * (WORLD_X + 1)) *
77                                   sizeof(s_char));
78     if (!rad) {
79         rad = (s_char **)malloc(WORLD_Y * sizeof(s_char *));
80         if (rad && radbuf) {
81             for (rx = 0; rx < WORLD_Y; rx++)
82                 rad[rx] = &radbuf[(WORLD_X + 1) * rx];
83         }
84     }
85
86     if (!radbuf || !rad) {
87         pr("Memory error in satmap, tell the deity.\n");
88         return;
89     }
90
91     range = range * (eff / 100.0);
92     pr("%s efficiency %d%%, max range %d\n", xyas(x, y, player->cnum),
93        eff, range);
94     bzero(noise, sizeof(noise));
95     if (eff < 100) {
96         pr("Some noise on the transmission...\n");
97         for (n = 0; n < (100 - eff); ++n)
98             noise[100 * n / (100 - eff)] = 1;
99     }
100
101     /* Have to convert to player coords, since it gets converted
102        back from there */
103     sprintf(selection, "@%s:%d", xyas(x, y, player->cnum), range);
104
105     if (type == EF_BAD || type == EF_SECTOR) {
106         if (type == EF_SECTOR)  /* Use ?conditionals */
107             snxtsct(&ns, selection);
108         else
109             snxtsct_dist(&ns, x, y, range);
110
111         blankfill((s_char *)radbuf, &ns.range, 1);
112         if (flags & P_S) {
113             pr("Satellite sector report\n");
114             prdate();
115             sathead();
116             acc = (flags & P_I) ? 5 : 50;
117         }
118         crackle = count = 0;
119         while (nxtsct(&ns, &sect)) {
120             if (++crackle == 100)
121                 crackle = 0;
122             if (noise[crackle])
123                 continue;
124             if (flags & P_S) {
125                 if (sect.sct_type > SCT_RURAL) {
126                     satdisp(&sect, acc, 0);
127                     ++count;
128                 }
129                 if (opt_HIDDEN) {
130                     setcont(player->cnum, sect.sct_own, FOUND_FLY);
131                 }
132             }
133             if ((flags & P_I) ||
134                 sect.sct_type == SCT_WATER || sect.sct_type == SCT_MOUNT) {
135                 rad[ns.dy][ns.dx] = dchr[sect.sct_type].d_mnem;
136             } else
137                 rad[ns.dy][ns.dx] = '?';
138             changed +=
139                 map_set(player->cnum, ns.x, ns.y, rad[ns.dy][ns.dx], 0);
140         }
141         if (changed)
142             writemap(player->cnum);
143         if (flags & P_S)
144             pr("  %d sectors\n\n", count);
145     }
146
147     if ((type == EF_BAD || type == EF_SHIP) &&
148         (flags & P_S || flags & P_I)) {
149         if (type == EF_SHIP)
150             snxtitem(&ni, EF_SHIP, selection);
151         else
152             snxtitem_dist(&ni, EF_SHIP, x, y, range);
153
154         crackle = count = 0;
155         if (flags & P_S) {
156             pr("Satellite ship report\n");
157             prdate();
158             if (opt_SHIPNAMES) {
159                 pr(" own  shp# ship type                                  sector   eff\n");
160             } else {
161                 pr(" own  shp# ship type         sector   eff\n");
162             }
163         }
164         while (nxtitem(&ni, (caddr_t)&ship)) {
165             if (ship.shp_own == 0)
166                 continue;
167             if ((mchr[(int)ship.shp_type].m_flags & M_SUB) &&
168                 ((flags & (P_S | P_I)) != (P_S | P_I)))
169                 continue;
170             if (++crackle == 100)
171                 crackle = 0;
172             if (noise[crackle])
173                 continue;
174             if (flags & P_S) {
175                 pr("%4d %4d %-16.16s ",
176                    ship.shp_own, ship.shp_uid,
177                    mchr[(int)ship.shp_type].m_name);
178                 if (opt_SHIPNAMES)
179                     pr("%-25.25s ", ship.shp_name);
180                 prxy("%4d,%-4d ", ship.shp_x, ship.shp_y, player->cnum);
181                 pr("%3d%%\n", ship.shp_effic);
182                 ++count;
183                 if (opt_HIDDEN) {
184                     setcont(player->cnum, ship.shp_own, FOUND_FLY);
185                 }
186             }
187             /* If we are imaging *and* drawing the map */
188             if ((flags & P_I) && (type == EF_BAD)) {
189                 /* Figure out where to put the ship */
190                 /* First, figure out the distance from the two */
191                 rx = diffx((int)ship.shp_x, x);
192                 ry = diffy((int)ship.shp_y, y);
193                 /* Next, determine which direction to add it to the center */
194                 /* We can only do this if imaging and we have gotten the center
195                    up above by imaging the sectors. */
196                 rx = deltax(x, ns.range.lx) + rx;
197                 ry = deltay(y, ns.range.ly) + ry;
198                 /* &~0x20 makes it a cap letter */
199                 rad[ry][rx] = (*mchr[(int)ship.shp_type].m_name) & ~0x20;
200             }
201         }
202         if (flags & P_S)
203             pr("  %d ships\n\n", count);
204     }
205
206     if ((type == EF_BAD || type == EF_LAND) &&
207         (flags & P_S || flags & P_I)) {
208         if (type == EF_LAND)
209             snxtitem(&ni, EF_LAND, selection);
210         else
211             snxtitem_dist(&ni, EF_LAND, x, y, range);
212
213         crackle = count = 0;
214         if (flags & P_S) {
215             pr("Satellite unit report\n");
216             prdate();
217             pr(" own  lnd# unit type         sector   eff\n");
218         }
219         while (nxtitem(&ni, (caddr_t)&land)) {
220             if (land.lnd_own == 0)
221                 continue;
222             if (!chance((double)land.lnd_effic / 20.0))
223                 continue;
224             if (++crackle == 100)
225                 crackle = 0;
226             if (noise[crackle])
227                 continue;
228             if (flags & P_S) {
229                 pr("%4d %4d %-16.16s ",
230                    land.lnd_own, land.lnd_uid,
231                    lchr[(int)land.lnd_type].l_name);
232                 prxy("%4d,%-4d", land.lnd_x, land.lnd_y, player->cnum);
233                 pr("%3d%%\n", land.lnd_effic);
234                 ++count;
235             }
236             /* If we are imaging *and* drawing the map */
237             if ((flags & P_I) && (type == EF_BAD)) {
238                 /* Figure out where to put the unit */
239                 /* First, figure out the distance from the two */
240                 rx = diffx((int)land.lnd_x, x);
241                 ry = diffy((int)land.lnd_y, y);
242                 /* Next, determine which direction to add it to the center */
243                 /* We can only do this if imaging and we have gotten the center
244                    up above by imaging the sectors. */
245                 rx = deltax(x, ns.range.lx) + rx;
246                 ry = deltay(y, ns.range.ly) + ry;
247                 /* &~0x20 makes it a cap letter */
248                 rad[ry][rx] = (*lchr[(int)land.lnd_type].l_name) & ~0x20;
249             }
250         }
251         if (flags & P_S)
252             pr("  %d units\n\n", count);
253     }
254
255     /* Ok, have we made the map?  If so, display it */
256     if (type == EF_BAD) {
257         /*
258          * print out the map
259          * We have to make the center a '0' for ve
260          * ve needs a garbage line to terminate the map
261          */
262         rad[deltay(y, ns.range.ly)][deltax(x, ns.range.lx)] = '0';
263
264         pr("Satellite radar report\n");
265 #ifdef HAY
266         /* This is wrong for small, hitech worlds. */
267         n = deltay(ns.range.hy, ns.range.ly);
268 #else
269         /* This is already available, so why not use it. */
270         n = ns.range.height;
271 #endif
272         for (row = 0; row < n; row++)
273             pr("%s\n", rad[row]);
274         pr("\n(c) 1989 Imaginative Images Inc.\n");
275     }
276 }
277
278 void
279 sathead(void)
280 {
281     pr("                    sct rd  rl  def\n");
282     pr("   sect   type own  eff eff eff eff  civ  mil  shl  gun iron  pet  food\n");
283 }
284
285 void
286 satdisp(struct sctstr *sp, int acc, int showstuff)
287 {
288     int vec[I_MAX + 1], first;
289     struct nstr_item ni;
290     struct shpstr ship;
291     struct lndstr land;
292
293     if (getvec(VT_ITEM, vec, (caddr_t)sp, EF_SECTOR) < 0)
294         return;
295     prxy("%4d,%-4d   ", sp->sct_x, sp->sct_y, player->cnum),
296         pr("%c  %3d  %3d %3d %3d %3d %4d %4d %4d %4d %4d %4d %5d\n",
297            dchr[sp->sct_type].d_mnem,
298            sp->sct_own, roundintby((int)sp->sct_effic, acc / 2),
299            roundintby((int)sp->sct_road, acc / 2),
300            roundintby((int)sp->sct_rail, acc / 2),
301            roundintby((int)sp->sct_defense, acc / 2),
302            roundintby(vec[I_CIVIL], acc), roundintby(vec[I_MILIT], acc),
303            roundintby(vec[I_SHELL], acc), roundintby(vec[I_GUN], acc),
304            roundintby(vec[I_IRON], acc), roundintby(vec[I_PETROL], acc),
305            roundintby(vec[I_FOOD], acc));
306     map_set(player->cnum, sp->sct_x, sp->sct_y, dchr[sp->sct_type].d_mnem,
307             0);
308     if (!showstuff)
309         return;
310     snxtitem_xy(&ni, EF_SHIP, sp->sct_x, sp->sct_y);
311     first = 1;
312     while (nxtitem(&ni, (caddr_t)&ship)) {
313         if (ship.shp_own == 0)
314             continue;
315         if (mchr[(int)ship.shp_type].m_flags & M_SUB)
316             continue;
317         if (first) {
318             if (opt_SHIPNAMES) {
319                 pr("\t own  shp# ship type                                  sector   eff\n");
320             } else {
321                 pr("\t own  shp# ship type         sector   eff\n");
322             }
323             first = 0;
324         }
325         pr("\t%4d %4d %-16.16s ", ship.shp_own, ship.shp_uid,
326            mchr[(int)ship.shp_type].m_name);
327         if (opt_SHIPNAMES)
328             pr("%-25.25s ", ship.shp_name);
329         prxy("%4d,%-4d ", ship.shp_x, ship.shp_y, player->cnum);
330         pr("%3d%%\n", ship.shp_effic);
331     }
332
333     if (!first)
334         pr("\n");
335
336     snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y);
337     first = 1;
338
339     while (nxtitem(&ni, (caddr_t)&land)) {
340         if (land.lnd_own == 0)
341             continue;
342         if (!chance((double)land.lnd_effic / 20.0))
343             continue;
344
345         if (first) {
346             pr("\t own  lnd# unit type         sector   eff\n");
347             first = 0;
348         }
349
350         pr("\t%4d %4d %-16.16s ", land.lnd_own, land.lnd_uid,
351            lchr[(int)land.lnd_type].l_name);
352         prxy("%4d,%-4d ", land.lnd_x, land.lnd_y, player->cnum);
353         pr("%3d%%\n", land.lnd_effic);
354     }
355
356     if (!first)
357         pr("\n");
358 }