]> git.pond.sub.org Git - empserver/blob - src/lib/subs/satmap.c
Import of Empire 4.2.12
[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 ||
135                             sect.sct_type == SCT_MOUNT) {
136                                 rad[ns.dy][ns.dx] = dchr[sect.sct_type].d_mnem;
137                         } else
138                                 rad[ns.dy][ns.dx] = '?';
139                         changed += 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,
181                                         player->cnum);
182                                 pr("%3d%%\n", ship.shp_effic);
183                                 ++count;
184                                 if (opt_HIDDEN) {
185                                     setcont(player->cnum, ship.shp_own, FOUND_FLY);
186                                 }
187                         }
188                         /* If we are imaging *and* drawing the map */
189                         if ((flags & P_I) && (type == EF_BAD)) {
190                             /* Figure out where to put the ship */
191                             /* First, figure out the distance from the two */
192                             rx = diffx((int)ship.shp_x, x);
193                             ry = diffy((int)ship.shp_y, y);
194                             /* Next, determine which direction to add it to the center */
195                             /* We can only do this if imaging and we have gotten the center
196                                up above by imaging the sectors. */
197                             rx = deltax(x, ns.range.lx) + rx;
198                             ry = deltay(y, ns.range.ly) + ry;
199                             /* &~0x20 makes it a cap letter */
200                             rad[ry][rx] = (*mchr[(int)ship.shp_type].m_name) & ~0x20;
201                         }
202                 }
203                 if (flags & P_S)
204                         pr("  %d ships\n\n", count);
205         }
206
207         if ((type == EF_BAD || type == EF_LAND) &&
208             (flags & P_S || flags & P_I)) {
209                 if (type == EF_LAND)
210                         snxtitem(&ni, EF_LAND, selection);
211                 else
212                         snxtitem_dist(&ni, EF_LAND, x, y, range);
213
214                 crackle = count = 0;
215                 if (flags & P_S) {
216                         pr("Satellite unit report\n");
217                         prdate();
218                         pr(" own  lnd# unit type         sector   eff\n");
219                 }
220                 while (nxtitem(&ni, (caddr_t)&land)) {
221                         if (land.lnd_own == 0)
222                                 continue;
223                         if (!chance((double)land.lnd_effic/20.0))
224                                 continue;
225                         if (++crackle == 100)
226                                 crackle = 0;
227                         if (noise[crackle])
228                                 continue;
229                         if (flags & P_S) {
230                                 pr("%4d %4d %-16.16s ",
231                                        land.lnd_own, land.lnd_uid,
232                                        lchr[(int)land.lnd_type].l_name);
233                                 prxy("%4d,%-4d", land.lnd_x, land.lnd_y,
234                                         player->cnum);
235                                 pr("%3d%%\n", land.lnd_effic);
236                                 ++count;
237                         }
238                         /* If we are imaging *and* drawing the map */
239                         if ((flags & P_I) && (type == EF_BAD)) {
240                             /* Figure out where to put the unit */
241                             /* First, figure out the distance from the two */
242                             rx = diffx((int)land.lnd_x, x);
243                             ry = diffy((int)land.lnd_y, y);
244                             /* Next, determine which direction to add it to the center */
245                             /* We can only do this if imaging and we have gotten the center
246                                up above by imaging the sectors. */
247                             rx = deltax(x, ns.range.lx) + rx;
248                             ry = deltay(y, ns.range.ly) + ry;
249                             /* &~0x20 makes it a cap letter */
250                             rad[ry][rx] = (*lchr[(int)land.lnd_type].l_name) & ~0x20;
251                         }
252                 }
253                 if (flags & P_S)
254                         pr("  %d units\n\n", count);
255         }
256
257         /* Ok, have we made the map?  If so, display it */
258         if (type == EF_BAD) {
259                 /*
260                  * print out the map
261                  * We have to make the center a '0' for ve
262                  * ve needs a garbage line to terminate the map
263                  */
264                 rad[deltay(y, ns.range.ly)][deltax(x, ns.range.lx)] = '0';
265
266                 pr("Satellite radar report\n");
267 #ifdef HAY
268                 /* This is wrong for small, hitech worlds. */
269                 n = deltay(ns.range.hy, ns.range.ly);
270 #else
271                 /* This is already available, so why not use it. */
272                 n = ns.range.height;
273 #endif
274                 for (row=0; row < n; row++)
275                         pr("%s\n", rad[row]);
276                 pr("\n(c) 1989 Imaginative Images Inc.\n");
277         }
278 }
279
280 void
281 sathead(void)
282 {
283 pr("                    sct rd  rl  def\n");
284 pr("   sect   type own  eff eff eff eff  civ  mil  shl  gun iron  pet  food\n");
285 }
286
287 void
288 satdisp(struct sctstr *sp, int acc, int showstuff)
289 {
290         int     vec[I_MAX+1], first;
291         struct  nstr_item ni;
292         struct  shpstr ship;
293         struct  lndstr land;
294
295         if (getvec(VT_ITEM, vec, (caddr_t)sp, EF_SECTOR) < 0)
296                 return;
297         prxy("%4d,%-4d   ", sp->sct_x, sp->sct_y, player->cnum),
298         pr("%c  %3d  %3d %3d %3d %3d %4d %4d %4d %4d %4d %4d %5d\n",
299                dchr[sp->sct_type].d_mnem,
300                sp->sct_own, roundintby((int)sp->sct_effic, acc / 2),
301                roundintby((int)sp->sct_road, acc / 2),
302                roundintby((int)sp->sct_rail, acc / 2),
303                roundintby((int)sp->sct_defense, acc / 2),
304                roundintby(vec[I_CIVIL], acc), roundintby(vec[I_MILIT], acc),
305                roundintby(vec[I_SHELL], acc), roundintby(vec[I_GUN], acc),
306                roundintby(vec[I_IRON], acc), roundintby(vec[I_PETROL], acc),
307                roundintby(vec[I_FOOD], acc));
308         map_set(player->cnum, sp->sct_x, sp->sct_y, dchr[sp->sct_type].d_mnem, 0);
309         if (!showstuff)
310                 return;
311         snxtitem_xy(&ni, EF_SHIP, sp->sct_x, sp->sct_y);
312         first=1;
313         while (nxtitem(&ni, (caddr_t)&ship)) {
314                 if (ship.shp_own == 0)
315                         continue;
316                 if (mchr[(int)ship.shp_type].m_flags & M_SUB)
317                         continue;
318                 if (first){
319                     if (opt_SHIPNAMES) {
320 pr("\t own  shp# ship type                                  sector   eff\n");
321                     } else { 
322 pr("\t own  shp# ship type         sector   eff\n");
323                     }
324                     first=0;
325                 }
326                 pr("\t%4d %4d %-16.16s ", ship.shp_own, ship.shp_uid,
327                        mchr[(int)ship.shp_type].m_name);
328                 if (opt_SHIPNAMES)
329                     pr("%-25.25s ", ship.shp_name);
330                 prxy("%4d,%-4d ", ship.shp_x, ship.shp_y, player->cnum);
331                 pr("%3d%%\n", ship.shp_effic);
332         }
333
334         if (!first)
335                 pr("\n");
336
337         snxtitem_xy(&ni, EF_LAND, sp->sct_x, sp->sct_y);
338         first=1;
339
340         while (nxtitem(&ni, (caddr_t)&land)) {
341                 if (land.lnd_own == 0)
342                         continue;
343                 if (!chance((double)land.lnd_effic/20.0))
344                         continue;
345
346                 if (first){
347                         pr("\t own  lnd# unit type         sector   eff\n");
348                         first=0;
349                 }
350
351                 pr("\t%4d %4d %-16.16s ",land.lnd_own, land.lnd_uid,
352                         lchr[(int)land.lnd_type].l_name);
353                 prxy("%4d,%-4d ",land.lnd_x, land.lnd_y, player->cnum);
354                 pr("%3d%%\n", land.lnd_effic);
355         }
356
357         if (!first)
358                 pr("\n");
359 }
360